From 5677a51da83e5d88cc89c16abc58f0685dcef33c Mon Sep 17 00:00:00 2001 From: KooshaPari Date: Sun, 31 May 2026 03:42:37 -0700 Subject: [PATCH 1/2] =?UTF-8?q?feat(tools):=20Start-Menu=20launcher=20regi?= =?UTF-8?q?strar=20=E2=80=94=20HMR/dev=20Electrobun=20shortcuts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds Tools/Register-StartMenuApps.ps1: a data-driven, idempotent registrar that creates a searchable Start-Menu folder "Phenotype Apps" and, per app in Tools/apps.json, refreshes a stable .lnk launching the app in DEV/HMR mode. The generated per-app launcher .cmd boots backend services, starts the Vite dev server if its port is free, and opens the latest Electrobun launcher.exe with RENDERER_URL pointed at the live dev server (hot reload, never a frozen bundle). -App does one app; no-arg does all. Default fallback icon when the app .ico is absent. Wires a `just register-startmenu [app]` target documented as the post-build hook to run at the end of each `electrobun build`. Piloted on AgilePlus. Co-Authored-By: Claude Opus 4.8 --- Tools/README.md | 58 +++++++++ Tools/Register-StartMenuApps.ps1 | 211 +++++++++++++++++++++++++++++++ Tools/apps.json | 25 ++++ justfile | 9 ++ 4 files changed, 303 insertions(+) create mode 100644 Tools/README.md create mode 100644 Tools/Register-StartMenuApps.ps1 create mode 100644 Tools/apps.json diff --git a/Tools/README.md b/Tools/README.md new file mode 100644 index 00000000..9d7e9b8a --- /dev/null +++ b/Tools/README.md @@ -0,0 +1,58 @@ +# Phenotype Tools + +Shared cross-repo tooling scripts (per Phenotype scripting hierarchy: `Tools/*.ps1` +for scripts >20 lines). + +## `Register-StartMenuApps.ps1` — Start-Menu launcher registrar + +Registers each Phenotype web app's Electrobun desktop build as a **searchable, +browsable** Windows Start-Menu shortcut that launches the app in **DEV / HMR mode** +(live hot-reload — never a frozen production bundle). + +### What it does + +1. Ensures the searchable Start-Menu folder + `%APPDATA%\Microsoft\Windows\Start Menu\Programs\Phenotype Apps\`. +2. Reads the data-driven manifest [`apps.json`](./apps.json) (one entry per app: + name, repo, dev-server command + port, optional backend, electrobun build dir, + `.ico`). Extensible to all ~38 apps by appending entries. +3. Per app, generates a stable launcher at + `%LOCALAPPDATA%\PhenotypeApps\launchers\-dev.cmd` that: + - boots backend services (e.g. `cargo run -p agileplus-api`, or process-compose), + - starts the Vite / react-router dev server **only if its port is free** (no dupes), + - launches the latest Electrobun `launcher.exe` with `RENDERER_URL` set to the + **live dev-server URL** → hot reload. Falls back to opening the dev URL in a + browser if the build hasn't been produced yet. +4. Creates/**refreshes** a single stable-named `.lnk` (overwrites, never duplicates): + `TargetPath = cmd.exe /c .cmd`, `IconLocation = app.ico` (default + fallback icon if absent), `WorkingDirectory = repo`. + +### Why it's always latest-build + HMR + +The launcher `.cmd` resolves `launcher.exe` under `/` **at +launch time** and points the webview at the running dev server, so the window renders +the latest source with hot reload — there is no frozen `index.html` or bundled +snapshot in the target chain. + +### Usage + +```powershell +pwsh Tools/Register-StartMenuApps.ps1 # all apps in apps.json +pwsh Tools/Register-StartMenuApps.ps1 -App AgilePlus # one app +# or via just: +just register-startmenu +just register-startmenu AgilePlus +``` + +Idempotent and re-runnable. + +### Build-completion hook + +Call the registrar at the **end of each app's `electrobun build`** so a completed +build re-registers its shortcut at the latest output: + +```bash +electrobun build && just register-startmenu +``` + +For lefthook-driven repos, add a `post-build`/local hook that runs the same line. diff --git a/Tools/Register-StartMenuApps.ps1 b/Tools/Register-StartMenuApps.ps1 new file mode 100644 index 00000000..03f0c7db --- /dev/null +++ b/Tools/Register-StartMenuApps.ps1 @@ -0,0 +1,211 @@ +#requires -Version 5.1 +<# +.SYNOPSIS + Registers Phenotype web apps' Electrobun desktop builds as searchable Windows + Start-Menu shortcuts that launch each app in DEV/HMR (live hot-reload) mode. + +.DESCRIPTION + Creates/ensures a searchable Start-Menu folder: + %APPDATA%\Microsoft\Windows\Start Menu\Programs\Phenotype Apps\ + + Reads a data-driven manifest (apps.json) listing per-app config (name, repo, + dev-server command + port, electrobun build dir, .ico). For each app it: + + 1. Generates a stable launcher .cmd at: + %LOCALAPPDATA%\PhenotypeApps\launchers\-dev.cmd + The launcher (HMR-first, NOT a frozen prod bundle): + a. Boots backend services if configured (process-compose / cargo run). + b. Starts the app's Vite/react-router dev server if its port is free. + c. Launches the LATEST Electrobun build's launcher.exe with + RENDERER_URL pointed at the live dev-server URL -> hot reload. + 2. Creates/REFRESHES a single stable-named .lnk in the Start-Menu folder + (overwrite — never duplicates on rebuild). TargetPath = launcher .cmd, + IconLocation = app.ico (falls back to a default if absent), + WorkingDirectory = repo. + + Idempotent and re-runnable. Designed to be invoked at the end of each app's + `electrobun build` step so a completed build always re-points its shortcut at + the latest output. + +.PARAMETER Manifest + Path to apps.json. Defaults to apps.json next to this script. + +.PARAMETER App + Register only the named app from the manifest. Omit to register all apps. + +.EXAMPLE + pwsh Tools/Register-StartMenuApps.ps1 + pwsh Tools/Register-StartMenuApps.ps1 -App AgilePlus + +.NOTES + HMR guarantee: the shortcut never targets a static index.html or a frozen + bundle. It always (re)resolves launcher.exe under / + at launch time and sets RENDERER_URL to the live dev-server URL, so the window + renders the latest source with hot reload. +#> +[CmdletBinding()] +param( + [string]$Manifest = (Join-Path $PSScriptRoot 'apps.json'), + [string]$App +) + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +function Write-Info($msg) { Write-Host "[Register-StartMenuApps] $msg" } +function Write-Warn($msg) { Write-Warning "[Register-StartMenuApps] $msg" } + +# ── Resolve well-known locations ─────────────────────────────────────────────── +$StartMenuRoot = Join-Path $env:APPDATA 'Microsoft\Windows\Start Menu\Programs' +$LauncherRoot = Join-Path $env:LOCALAPPDATA 'PhenotypeApps\launchers' +$AssetRoot = Join-Path $env:LOCALAPPDATA 'PhenotypeApps\assets' + +if (-not (Test-Path $Manifest)) { + throw "Manifest not found: $Manifest" +} +$cfg = Get-Content -Raw -LiteralPath $Manifest | ConvertFrom-Json + +$folderName = if ($cfg.PSObject.Properties.Name -contains 'startMenuFolder' -and $cfg.startMenuFolder) { + $cfg.startMenuFolder +} else { 'Phenotype Apps' } + +$StartMenuFolder = Join-Path $StartMenuRoot $folderName + +# Ensure folders exist (searchable/browsable in Start Menu). +foreach ($dir in @($StartMenuFolder, $LauncherRoot, $AssetRoot)) { + if (-not (Test-Path $dir)) { + New-Item -ItemType Directory -Force -Path $dir | Out-Null + } +} +Write-Info "Start-Menu folder: $StartMenuFolder" + +# ── Default fallback icon ────────────────────────────────────────────────────── +function Get-DefaultIcon { + # Use a stable system icon as the fallback so shortcuts always render. + $candidates = @( + (Join-Path $env:SystemRoot 'System32\SHELL32.dll'), # generic app glyph (index 2) + (Join-Path $env:SystemRoot 'System32\imageres.dll') + ) + foreach ($c in $candidates) { if (Test-Path $c) { return "$c,2" } } + return $null +} + +# ── Launcher .cmd generation ─────────────────────────────────────────────────── +function New-LauncherCmd { + param([pscustomobject]$AppCfg) + + $repo = ($AppCfg.repoPath -replace '/', '\') + $name = $AppCfg.name + $dev = $AppCfg.devServer + $devCwd = if ($dev.PSObject.Properties.Name -contains 'cwd' -and $dev.cwd) { $dev.cwd } else { '.' } + $devCmd = $dev.command + $devUrl = $dev.url + $devPort = $dev.port + $buildDir = $AppCfg.electrobunBuildDir + + $hasBackend = ($AppCfg.PSObject.Properties.Name -contains 'backend') -and $AppCfg.backend + $beCwd = ''; $beCmd = '' + if ($hasBackend) { + $beCwd = if ($AppCfg.backend.PSObject.Properties.Name -contains 'cwd' -and $AppCfg.backend.cwd) { $AppCfg.backend.cwd } else { '.' } + $beCmd = $AppCfg.backend.command + } + + $cmdPath = Join-Path $LauncherRoot ("{0}-dev.cmd" -f $name) + + $lines = @() + $lines += '@echo off' + $lines += 'rem ====================================================================' + $lines += "rem $name — DEV / HMR launcher (generated by Register-StartMenuApps.ps1)" + $lines += 'rem Boots services -> dev server (if down) -> Electrobun @ live URL.' + $lines += 'rem Never targets a frozen bundle: RENDERER_URL = live dev server.' + $lines += 'rem ====================================================================' + $lines += "set ""REPO=$repo""" + if ($hasBackend) { + $lines += 'rem --- backend services ---' + $lines += "start ""$name backend"" /D ""%REPO%\$beCwd"" cmd /c $beCmd" + } + $lines += 'rem --- dev server: only start if port is free (avoid duplicate) ---' + $lines += "set DEVPORT=$devPort" + $lines += 'set DEVUP=' + $lines += 'for /f "tokens=*" %%A in (''netstat -ano -p tcp ^| findstr ":%DEVPORT% " ^| findstr LISTENING'') do set DEVUP=1' + $lines += 'if not defined DEVUP (' + $lines += " start ""$name dev server"" /D ""%REPO%\$devCwd"" cmd /c $devCmd" + $lines += " rem give the dev server a moment to bind the port" + $lines += ' ping -n 4 127.0.0.1 >nul' + $lines += ') else (' + $lines += " echo [$name] dev server already listening on %DEVPORT%" + $lines += ')' + $lines += 'rem --- Electrobun window pointed at live dev server (HMR) ---' + $lines += "set ""RENDERER_URL=$devUrl""" + $lines += "set ""APP_NAME=$name""" + $lines += "set ""LAUNCHER=%REPO%\$buildDir\launcher.exe""" + $lines += 'if exist "%LAUNCHER%" (' + $lines += ' start "" "%LAUNCHER%"' + $lines += ') else (' + $lines += " echo [$name] Electrobun build not found at ""%LAUNCHER%"". Run: electrobun build" + $lines += " echo Opening dev server in browser as fallback..." + $lines += " start """" ""$devUrl""" + $lines += ')' + + Set-Content -LiteralPath $cmdPath -Value ($lines -join "`r`n") -Encoding ASCII + return $cmdPath +} + +# ── Shortcut (.lnk) creation/refresh ─────────────────────────────────────────── +function Set-AppShortcut { + param([pscustomobject]$AppCfg) + + $name = $AppCfg.name + $repo = $AppCfg.repoPath + if (-not (Test-Path $repo)) { + Write-Warn "Repo path missing for '$name': $repo — skipping." + return + } + + $launcher = New-LauncherCmd -AppCfg $AppCfg + + # Resolve icon: app-provided .ico, else fallback (and note it). + $iconLocation = $null + if ($AppCfg.PSObject.Properties.Name -contains 'ico' -and $AppCfg.ico) { + $icoPath = if ([System.IO.Path]::IsPathRooted($AppCfg.ico)) { $AppCfg.ico } else { Join-Path $repo $AppCfg.ico } + if (Test-Path $icoPath) { + $iconLocation = "$icoPath,0" + } else { + Write-Warn "Icon for '$name' not found at '$icoPath' — using default fallback icon." + } + } + if (-not $iconLocation) { $iconLocation = Get-DefaultIcon } + + $lnkPath = Join-Path $StartMenuFolder ("{0}.lnk" -f $name) + + $shell = New-Object -ComObject WScript.Shell + try { + $sc = $shell.CreateShortcut($lnkPath) # CreateShortcut overwrites if it exists + $sc.TargetPath = "$env:SystemRoot\System32\cmd.exe" + $sc.Arguments = "/c `"$launcher`"" + $sc.WorkingDirectory = $repo + $sc.WindowStyle = 7 # minimized console + $sc.Description = "$name — Phenotype desktop (DEV/HMR, live reload)" + if ($iconLocation) { $sc.IconLocation = $iconLocation } + $sc.Save() + } finally { + [System.Runtime.InteropServices.Marshal]::ReleaseComObject($shell) | Out-Null + } + + Write-Info "Registered shortcut: $lnkPath -> $launcher" +} + +# ── Main ─────────────────────────────────────────────────────────────────────── +$apps = $cfg.apps +if ($App) { + $apps = @($apps | Where-Object { $_.name -eq $App }) + if (-not $apps -or $apps.Count -eq 0) { + throw "App '$App' not found in manifest $Manifest" + } +} + +foreach ($a in $apps) { + Set-AppShortcut -AppCfg $a +} + +Write-Info ("Done. {0} app(s) registered in '{1}'." -f @($apps).Count, $StartMenuFolder) diff --git a/Tools/apps.json b/Tools/apps.json new file mode 100644 index 00000000..eef3c15c --- /dev/null +++ b/Tools/apps.json @@ -0,0 +1,25 @@ +{ + "$schema": "./apps.schema.json", + "_comment": "Data-driven manifest for Register-StartMenuApps.ps1. One entry per Phenotype web app. Each shortcut launches the app in DEV/HMR mode (live reload), pointing the Electrobun shell at the running dev server, NOT a frozen production bundle. Extend this list to cover all ~38 apps.", + "startMenuFolder": "Phenotype Apps", + "apps": [ + { + "name": "AgilePlus", + "appId": "com.phenotype.agileplus", + "repoPath": "C:/Users/koosh/Dev/AgilePlus", + "devServer": { + "cwd": "crates/agileplus-dashboard/web", + "command": "bun run dev", + "url": "http://localhost:5173", + "port": 5173 + }, + "backend": { + "cwd": ".", + "command": "cargo run -p agileplus-api", + "port": 4000 + }, + "electrobunBuildDir": "build/dev-win-x64/AgilePlus", + "ico": "assets/brand/app.ico" + } + ] +} diff --git a/justfile b/justfile index e126b36d..3a8e95bc 100644 --- a/justfile +++ b/justfile @@ -35,3 +35,12 @@ ci: lint test audit unused # Generate docs docs: cargo doc --no-deps --workspace + +# Register/refresh Windows Start-Menu shortcuts for Electrobun desktop apps. +# Each shortcut launches the app in DEV/HMR mode pointed at the live dev server. +# no-arg = all apps in Tools/apps.json; `just register-startmenu AgilePlus` = one. +# BUILD HOOK: call this at the END of each `electrobun build` step so a completed +# build always re-points its shortcut at the latest output, e.g.: +# electrobun build && just register-startmenu {{app}} +register-startmenu app="": + pwsh -NoProfile -File Tools/Register-StartMenuApps.ps1 {{ if app == "" { "" } else { "-App " + app } }} From e0a8f34f9ab92cf755144dac1cc88b0e20b4ad22 Mon Sep 17 00:00:00 2001 From: KooshaPari Date: Sun, 31 May 2026 04:56:39 -0700 Subject: [PATCH 2/2] docs+tools: full app inventory + launcher manifest Classify 136 active KooshaPari repos (excl. archived + blocklist). Real runnable apps = 13: AgilePlus + 12 discovered (10 WEB-APP, 2 DESKTOP-APP: HeliosLab, slickport). Merge the 12 into Tools/apps.json (extends PR #85 manifest) and add docs/app-inventory.md with the per-repo probe results and class summary. Co-Authored-By: Claude Opus 4.8 --- Tools/apps.json | 184 +++++++++++++++++++++++++++++++++++++++++- docs/app-inventory.md | 41 ++++++++++ 2 files changed, 223 insertions(+), 2 deletions(-) create mode 100644 docs/app-inventory.md diff --git a/Tools/apps.json b/Tools/apps.json index eef3c15c..4e808a66 100644 --- a/Tools/apps.json +++ b/Tools/apps.json @@ -1,6 +1,6 @@ { "$schema": "./apps.schema.json", - "_comment": "Data-driven manifest for Register-StartMenuApps.ps1. One entry per Phenotype web app. Each shortcut launches the app in DEV/HMR mode (live reload), pointing the Electrobun shell at the running dev server, NOT a frozen production bundle. Extend this list to cover all ~38 apps.", + "_comment": "Data-driven manifest for Register-StartMenuApps.ps1. One entry per Phenotype web app. Each shortcut launches the app in DEV/HMR mode (live reload), pointing the Electrobun shell at the running dev server, NOT a frozen production bundle. Extend this list to cover all 13 known runnable apps: AgilePlus + 12 discovered (10 WEB-APP, 2 DESKTOP-APP). See docs/app-inventory.md.", "startMenuFolder": "Phenotype Apps", "apps": [ { @@ -20,6 +20,186 @@ }, "electrobunBuildDir": "build/dev-win-x64/AgilePlus", "ico": "assets/brand/app.ico" + }, + { + "name": "phenodocs", + "appId": "com.phenotype.phenodocs", + "repoPath": "https://github.com/KooshaPari/phenodocs", + "devServer": { + "cwd": ".", + "command": "npm run dev", + "url": null, + "port": null + }, + "class": "WEB-APP", + "hasDesktopShell": false, + "ico": null, + "_needsIco": true + }, + { + "name": "Planify", + "appId": "com.phenotype.planify", + "repoPath": "https://github.com/KooshaPari/Planify", + "devServer": { + "cwd": ".", + "command": "npm run dev", + "url": null, + "port": null + }, + "class": "WEB-APP", + "hasDesktopShell": false, + "ico": null, + "_needsIco": true + }, + { + "name": "OmniRoute", + "appId": "com.phenotype.omniroute", + "repoPath": "https://github.com/KooshaPari/OmniRoute", + "devServer": { + "cwd": ".", + "command": "npm run dev", + "url": null, + "port": null + }, + "class": "WEB-APP", + "hasDesktopShell": false, + "ico": null, + "_needsIco": true + }, + { + "name": "phenoRouterMonitor", + "appId": "com.phenotype.phenoroutermonitor", + "repoPath": "https://github.com/KooshaPari/phenoRouterMonitor", + "devServer": { + "cwd": ".", + "command": "npm run dev", + "url": null, + "port": null + }, + "class": "WEB-APP", + "hasDesktopShell": false, + "ico": null, + "_needsIco": true + }, + { + "name": "AtomsBot", + "appId": "com.phenotype.atomsbot", + "repoPath": "https://github.com/KooshaPari/AtomsBot", + "devServer": { + "cwd": ".", + "command": "npm run dev", + "url": null, + "port": null + }, + "class": "WEB-APP", + "hasDesktopShell": false, + "ico": null, + "_needsIco": true + }, + { + "name": "HeliosLab", + "appId": "com.phenotype.helioslab", + "repoPath": "https://github.com/KooshaPari/HeliosLab", + "devServer": { + "cwd": ".", + "command": "npm run dev", + "url": null, + "port": null + }, + "class": "DESKTOP-APP", + "hasDesktopShell": true, + "ico": null, + "_needsIco": true + }, + { + "name": "AppGen", + "appId": "com.phenotype.appgen", + "repoPath": "https://github.com/KooshaPari/AppGen", + "devServer": { + "cwd": ".", + "command": "npm start", + "url": null, + "port": null + }, + "class": "WEB-APP", + "hasDesktopShell": false, + "ico": null, + "_needsIco": true + }, + { + "name": "phenotype-auth-ts", + "appId": "com.phenotype.phenotypeauthts", + "repoPath": "https://github.com/KooshaPari/phenotype-auth-ts", + "devServer": { + "cwd": ".", + "command": "npm run dev", + "url": null, + "port": null + }, + "class": "WEB-APP", + "hasDesktopShell": false, + "ico": null, + "_needsIco": true + }, + { + "name": "helios-router", + "appId": "com.phenotype.heliosrouter", + "repoPath": "https://github.com/KooshaPari/helios-router", + "devServer": { + "cwd": ".", + "command": "npm run dev", + "url": null, + "port": null + }, + "class": "WEB-APP", + "hasDesktopShell": false, + "ico": null, + "_needsIco": true + }, + { + "name": "chatta", + "appId": "com.phenotype.chatta", + "repoPath": "https://github.com/KooshaPari/chatta", + "devServer": { + "cwd": ".", + "command": "npm run dev", + "url": null, + "port": null + }, + "class": "WEB-APP", + "hasDesktopShell": false, + "ico": null, + "_needsIco": true + }, + { + "name": "phenotype-org-governance", + "appId": "com.phenotype.phenotypeorggovernance", + "repoPath": "https://github.com/KooshaPari/phenotype-org-governance", + "devServer": { + "cwd": ".", + "command": "npm run dev", + "url": null, + "port": null + }, + "class": "WEB-APP", + "hasDesktopShell": false, + "ico": null, + "_needsIco": true + }, + { + "name": "slickport", + "appId": "com.phenotype.slickport", + "repoPath": "https://github.com/KooshaPari/slickport", + "devServer": { + "cwd": ".", + "command": "npm run dev", + "url": null, + "port": null + }, + "class": "DESKTOP-APP", + "hasDesktopShell": true, + "ico": null, + "_needsIco": true } ] -} +} \ No newline at end of file diff --git a/docs/app-inventory.md b/docs/app-inventory.md new file mode 100644 index 00000000..bf3d5847 --- /dev/null +++ b/docs/app-inventory.md @@ -0,0 +1,41 @@ +# KooshaPari App Inventory + +Generated 2026-05-31. Source: `gh repo list` (136 active repos, excludes archived + blocklist P2/472-P2/KVirtualStage/KlipDot/KodeVibeGo/kwality). + +## Summary by class +| Class | Count | +|---|---| +| OTHER | 66 | +| LIBRARY-SDK | 26 | +| CLI | 17 | +| SERVICE | 10 | +| WEB-APP | 10 | +| DESKTOP-APP | 2 | +| DOCS | 2 | + +**Runnable apps = 12** (10 WEB-APP + 2 DESKTOP-APP). Desktop shells: HeliosLab, slickport. None ship a branding `.ico` yet (all 12 need one). AgilePlus is a Rust workspace (crates/pheno-cli/agileplus-mcp) — CLI/SDK, not a web shell. + +## Per-repo probe results + +- phenotype-tooling: LIBRARY-SDK | dev=None | ico=False | desktop=False | files=.devcontainer,.editorconfig,.gitattributes,.github,.gitignore,.pre-commit-config.yaml,AGENTS.md,CHANGELOG.md +- phenotype-registry: LIBRARY-SDK | dev=None | ico=False | desktop=False | files=.github,.gitignore,.pre-commit-config.yaml,AGENTS.md,CHANGELOG.md,CLAUDE.md,CONTRIBUTING.md,ECOSYSTEM_MAP.md +- PhenoProject: OTHER | dev=None | ico=False | desktop=False | files=.editorconfig,.github,.pre-commit-config.yaml,AGENTS.md,CHANGELOG.md,CITATION.cff,CLAUDE.md,CODEOWNERS +- phenodocs: WEB-APP | dev=npm run dev | ico=False | desktop=False | files=.agents,.airlock,.broken_md_refs.txt,.coderabbit.yaml,.devcontainer,.env.example,.gitattributes,.github +- Planify: WEB-APP | dev=npm run dev | ico=False | desktop=False | files=.codespellrc,.dockerignore,.editorconfig,.env.example,.gitattributes,.github,.gitignore,.husky +- OmniRoute: WEB-APP | dev=npm run dev | ico=False | desktop=False | files=.agents,.claude,.codegraph,.dockerignore,.editorconfig,.env.example,.gitattributes,.github +- PhenoHandbook: LIBRARY-SDK | dev=None | ico=False | desktop=False | files=.editorconfig,.gitattributes,.github,.gitignore,.pre-commit-config.yaml,ADR.md,AGENTS.md,CHANGELOG.md +- phenoRouterMonitor: WEB-APP | dev=None | ico=False | desktop=False | files=.airlock,.cliff.toml,.coderabbit.yaml,.commit-template,.commitlintrc.yml,.devcontainer,.env.development.example,.env.example +- AtomsBot: WEB-APP | dev=npm run dev | ico=False | desktop=False | files=.data,.dockerignore,.editorconfig,.env.example,.eslintignore,.eslintrc.json,.gitattributes,.github +- HeliosLab: DESKTOP-APP | dev=npm run dev | ico=False | desktop=True | files=.agileplus,.archive,.biomeignore,.coderabbit.yaml,.colab.json,.config,.devcontainer,.editorconfig +- AppGen: WEB-APP | dev=npm start | ico=False | desktop=False | files=.github,AGENTS.md,CHANGELOG.md,FUNCTIONAL_REQUIREMENTS.md,LICENSE,README.md,SECURITY.md,docs +- phenotype-auth-ts: WEB-APP | dev=None | ico=False | desktop=False | files=.editorconfig,.gitattributes,.github,.gitignore,.nvmrc,.pre-commit-config.yaml,ADR.md,AGENTS.md +- helios-router: WEB-APP | dev=None | ico=False | desktop=False | files=.cargo,.coderabbit.yaml,.config,.coverage,.devcontainer,.editorconfig,.gemini,.gitattributes +- phenotype-hub: OTHER | dev=None | ico=False | desktop=False | files=.github,.gitignore,.pre-commit-config.yaml,.vitepress,AGENTS.md,CHANGELOG.md,CLAUDE.md,CODEOWNERS +- Tracely: OTHER | dev=None | ico=False | desktop=False | files=.devcontainer,.editorconfig,.gitattributes,.github,.gitignore,.pre-commit-config.yaml,ADR.md,AGENTS.md +- Conft: OTHER | dev=None | ico=False | desktop=False | files=.agileplus,.editorconfig,.gitattributes,.github,.gitignore,.nvmrc,AGENTS.md,CHANGELOG.md +- Parpoura: LIBRARY-SDK | dev=None | ico=False | desktop=False | files=.airlock,.coderabbit.yaml,.devcontainer,.editorconfig,.env.example,.gemini,.github,.gitignore +- chatta: WEB-APP | dev=None | ico=False | desktop=False | files=.github,.gitignore,.history,.idea,ADR.md,AGENTS.md,CHANGELOG.md,CHARTER.md +- localbase3: OTHER | dev=None | ico=False | desktop=False | files=.github,.gitignore,.history,.vscode,AGENTS.md,CHANGELOG.md,CLAUDE.md,FUNDING.yml +- phenotype-org-governance: WEB-APP | dev=None | ico=False | desktop=False | files=.github,.pre-commit-config.yaml,AGENTS.md,CHANGELOG.md,CITATION.cff,CLAUDE.md,CODEOWNERS,CONTRIBUTING.md +- slickport: DESKTOP-APP | dev=npm run dev | ico=False | desktop=True | files=.github,.gitignore,.history,.npmrc,.prettierignore,.prettierrc,ADR.md,AGENTS.md +- netweave-final2: OTHER | dev=None | ico=False | desktop=False | files=.DS_Store,.github,.gitignore,AGENTS.md,CHANGELOG.md,CLAUDE.md,FUNCTIONAL_REQUIREMENTS.md,FUNDING.yml \ No newline at end of file