Files
waggle-os/docs/audits/2026-07-08-ai-tool-hook-t16-analysis.md
Oleg Maslov 0c3e2ead3b
Some checks failed
Installer Smoke / installer-smoke (push) Has been cancelled
moving
2026-09-02 10:10:29 +02:00

114 lines
35 KiB
Markdown

# T16 AI-Tool Hook Lifecycle UX Analysis
Date: 2026-07-08
Scope: Launcher AI-tool detection, launch, hook install, hook verify, hook uninstall, live output, and the `packages/hive-mind-hooks-*` package set.
Mode: analysis plus focused package-runtime evidence.
## Bottom Line
T16 is functional at the unit, package, manifest, backend-route, component-test, package-runtime, real safe-launch, and rendered-Launcher transition layers, but it is not ready for a 9/10 UX claim.
The strongest evidence is the hook package test suite, shared manifest contract, backend route tests, official package typechecks, compiled bin help smokes, package-local hook/shim test scripts, a fresh package-pack lifecycle lane that runs `npx @waggle/hive-mind-hooks-<id> install/verify/uninstall` for all six hook-capable packages, a real detected-CLI observed launch smoke, a real isolated `/api/tools/hooks` install/verify/uninstall route smoke for all six hook-capable tools, a rendered Launcher smoke with a mock local API, codified all-six rendered hook install/verify/uninstall transitions, focused regressions for observed tool output after exit plus hook result stdout/stderr/structured-failure visibility, focused rendered install/offline/long-output/adapter Playwright coverage, focused third-party adapter launch coverage, and Codex WindowsApps recovery coverage. The hook-result regressions include Backup/Recovery result labels, Verify check failed/manual-approval rows, uninstall restore/cleanup rows, long-output summary rows, empty-output Verify recovery copy, and Claude Desktop launch-only copy. The remaining blockers are user-facing: packaged desktop integration and noisy-but-passing hook output.
## User Jobs
- Detect installed AI tools.
- Launch a detected tool in the current workspace.
- Optionally pass a prompt when the tool supports inline prompt args.
- See whether the tool is already running and inspect live output for observed launches.
- Install hooks without corrupting an existing tool configuration.
- Verify hooks and understand failures or manual trust steps.
- Uninstall hooks byte-identically, or remove only Waggle-managed files when Waggle created the config.
- Understand that Claude Desktop is launchable but not hook-capable.
- Recover when the sidecar, hive-mind CLI, or target AI tool is unavailable.
- For advanced users, add a third-party adapter and expect detected tools to behave coherently.
## Source Model
- Built-in tool manifests live in `packages/shared/src/tool-detection.ts`.
- The canonical built-ins are `claude-code`, `claude-desktop`, `cursor`, `codex`, `codex-desktop`, `hermes`, and `openclaw`.
- All seven built-ins are launchable.
- Six built-ins are hook-capable: all except `claude-desktop`.
- `packages/hive-mind-hooks-claude-desktop` is an intentional stub with no `bin`.
- `packages/hive-mind-hooks-codex-desktop` is a thin wrapper around the Codex hook package and writes to the shared `~/.codex` hook config.
- Detection uses `getToolRegistry()`, which merges built-ins plus validated third-party manifests from `~/.waggle/adapters/*.json`.
- `/api/tools/launch` now validates IDs against the runtime registry, so launchable third-party adapters can launch through the sidecar route and can receive server-applied `promptArgTemplate` prompts.
- `/api/tools/hooks` remains intentionally limited to the known hook-capable built-ins; third-party hook management needs a separate safe hook command/package policy before it should be exposed.
- On Windows, PATH detection now prefers spawnable `where.exe` hits such as `.exe`, `.cmd`, `.bat`, or `.com` over extensionless POSIX npm shims. Standard npm `.cmd` shims are resolved to their `node <module>` target so prompts/args stay literal; unknown `.cmd`/`.bat` files fall back to a quoted `cmd.exe call`. Codex found only through the restricted WindowsApps app alias is reported as installed but not launchable, with recovery copy instead of a failing Launch button.
## Command Evidence
| Check | Result | Notes |
|---|---:|---|
| `npx vitest run packages/shared/tests/tool-manifests.test.ts packages/agent/tests/tool-manifest-loader.test.ts packages/agent/tests/phase4-hooks-cohort.test.ts packages/agent/tests/tool-launcher.test.ts packages/agent/tests/hook-packages-runtime.test.ts packages/server/tests/tools-routes-launch.test.ts packages/server/tests/tools-routes.test.ts --reporter=dot` | Pass, 7 files / 96 tests | Proves manifest, loader, cohort, backend route, process, launch, hook route contracts, and package-packed installed hook lifecycle. Output includes expected mock embedding warning noise from server setup. |
| `npm run test -w apps/web -- src/components/os/apps/LauncherApp.test.tsx src/lib/launcher-prompt-args.test.ts src/lib/adapter.launcher.test.ts --reporter=dot` | Pass, 3 files / 28 tests | Proves Launcher A/B toggle, one hook-capable non-Claude example, live-output pane wiring, prompt arg helpers, and adapter launcher methods. Emits Node `punycode` deprecation warnings. |
| `npm run build` + in-app Browser rendered smoke on `/launcher?watch=1&skipOnboarding=true&skipBoot=true&skipBriefing=true` | Pass, partial state matrix | Fresh production web build passed. Browser DOM snapshot API failed with `TypeError: o.incrementalAriaSnapshot is not a function`, so evidence used the supported in-app Browser screenshot and targeted DOM-evaluate APIs. Artifacts: `output/playwright/launcher-t16-54147/launcher-t16-rendered-summary.json` plus five screenshots for mixed state, prompt summary, install success, verify failure, and running output. |
| `npx vitest run packages/hive-mind-hooks-core/tests --reporter=dot` | Pass, 5 files / 82 tests | Proves shared hook core handlers, install primitives, JSON register merge, path helpers, and fail-open signal behavior. |
| `npx vitest run packages/hive-mind-hooks-codex/tests packages/hive-mind-hooks-codex-desktop/tests packages/hive-mind-hooks-cursor/tests packages/hive-mind-hooks-hermes/tests packages/hive-mind-hooks-openclaw/tests packages/hive-mind-hooks-claude-code/tests packages/hive-mind-shim-core/tests --reporter=dot` | Pass, 55 files / 491 tests, 1 skipped | Proves package-level install/verify/uninstall, lifecycle handlers, Codex Desktop parity, shim core, fail-open behavior, and temp-config reversibility. Output is noisy with expected logs and warnings. |
| Official package typechecks for `hive-mind-shim-core`, `hive-mind-hooks-core`, `claude-code`, `codex`, `codex-desktop`, `cursor`, `hermes`, and `openclaw` | Pass, 8/8 | Each package script runs `tsc --build && tsc --noEmit -p tsconfig.test.json`. |
| `npm run build --workspace @waggle/hive-mind-hooks-claude-desktop` | Pass | Confirms the intentional no-bin Claude Desktop stub still builds. |
| Compiled bin help smokes for `claude-code-hooks`, `codex-hooks`, `codex-desktop-hooks`, `cursor-hooks`, `hermes-hooks`, and `openclaw-hooks` | Pass, 6/6 | Local compiled bin entrypoints boot and show usage. |
| `npx vitest run packages/agent/tests/hook-packages-runtime.test.ts --reporter=verbose` | Pass, 1 file / 1 test | Builds and packs `@waggle/hive-mind-shim-core`, `@waggle/hive-mind-hooks-core`, and all six hook-capable packages into tarballs, installs the local package closure into a clean temp project, then runs production-like `npx --yes @waggle/hive-mind-hooks-<id> install/verify/uninstall` for `claude-code`, `codex`, `codex-desktop`, `cursor`, `hermes`, and `openclaw`. Each install pins a fake `hive-mind-cli --help` target, verify passes, uninstall removes the pointer, and the config is restored or removed as expected. |
| `npm run test --workspace @waggle/hive-mind-hooks-core -- --reporter=dot` | Pass, 5 files / 82 tests | Package-local script now delegates to the root Vitest config with a package-specific path. |
| Package-local `npm run test` for `hive-mind-hooks-claude-code`, `codex`, `codex-desktop`, `cursor`, `hermes`, `openclaw`, and `hive-mind-shim-core` | Pass, 55 files / 492 tests | Package-local scripts now run the intended root-config lanes. The shim script builds the in-monorepo CLI first, then its integration test verifies the CLI ESM resolver fix: `hive-mind-cli mcp call` now resolves the ESM-only MCP server via `import.meta.resolve`. |
| `npx vitest run packages/agent/tests/tool-launcher.test.ts packages/agent/tests/tool-detection.test.ts packages/agent/tests/tool-registry.test.ts packages/server/tests/tools-routes-launch.test.ts packages/server/tests/launch-args.test.ts --reporter=dot` | Pass, 5 files / 108 tests | Proves registry-aware detection metadata, launchable third-party adapter launch, prompt template application through `/api/tools/launch`, built-in launch/hook contracts, and route/process persistence behavior. Output includes expected mock embedding warning noise from server setup. |
| `npx vitest run packages/agent/tests/tool-launcher.test.ts packages/agent/tests/tool-detection.test.ts --reporter=dot` | Pass, 2 files / 73 tests | Adds Windows real-world launcher guardrails: `where.exe` now prefers spawnable `.cmd`/`.exe` hits over extensionless npm shims, standard npm `.cmd` shims resolve to their Node module target instead of raw `cmd.exe`, unknown `.cmd`/`.bat` files use a quoted fallback, and async child-spawn failures no longer become unhandled sidecar crashes. |
| `npx vitest run packages/agent/tests/tool-launcher.test.ts packages/agent/tests/tool-detection.test.ts --reporter=dot` | Pass, 2 files / 76 tests | Adds hook-management command guardrails: Windows hook commands resolve the Node-installed `npx.cmd` instead of `execFile('npx')` or a broken local shim, and default exec capture now uses the shared `.cmd` resolver. |
| `npx vitest run packages/server/tests/tools-routes-launch.test.ts packages/agent/tests/tool-process-tracker.test.ts packages/agent/tests/tool-launcher.test.ts --reporter=dot` | Pass, 3 files / 98 tests | Revalidates launch route, process tracker, observed launch, hook route, persistence/reconcile, registry-aware launch, and Windows command invocation behavior after the real-tool fix. Output still includes expected mock embedding warning noise. |
| `npm run build:packages` | Pass | Rebuilt shared/core/agent/server package output so the sidecar imports the updated `@waggle/agent` dist for real-tool Playwright evidence. |
| Built package detection probe via `node -e "import('./packages/agent/dist/tool-detection.js')..."` | Pass | On this Windows host, Codex resolves to `C:\Program Files\WindowsApps\OpenAI.Codex_26.623.19656.0_x64__2p2nqsd0c76g0\app\resources\codex.exe` and is now reported as `installed: true`, `launchable: false`, `version: null`, with the WindowsApps recovery diagnostic. OpenClaw still resolves through the spawnable npm `.cmd` path in the broader package probe. |
| `npx vitest run packages/agent/tests/tool-detection.test.ts --reporter=dot`; `npx vitest run src/components/os/apps/LauncherApp.test.tsx --reporter=dot` from `apps/web` | Pass, 30 agent tests + 15 Launcher tests | Adds focused Codex WindowsApps regressions: the detector reports the restricted app alias as installed but not launchable, and the Launcher hides the Launch button while showing recovery copy instead of generic adapter-not-configured text. Web test output includes the expected Node `punycode` deprecation warning. |
| `node -e "import('./packages/agent/dist/tool-command.js')..."` | Pass | Built helper resolves the real OpenClaw npm `.cmd` shim to `node C:\Users\MarkoMarkovic\AppData\Roaming\npm\node_modules\openclaw\openclaw.mjs` and preserves metacharacter args such as `foo&echoBAD` and `100%` without `cmd.exe`. |
| `WAGGLE_E2E_REAL_TOOLS=1 WAGGLE_E2E_PORT=34242 WAGGLE_E2E_BASE_URL=http://127.0.0.1:34242 npx playwright test tests/e2e/launcher-real-tool-lifecycle.spec.ts --project=chromium --reporter=list` | Pass, 1 file / 1 test | Fresh production build plus clean sidecar rendered Launcher, detected a real safe CLI (`OpenClaw` on this host), launched it through `/api/tools/launch` with safe `--version` args in observed mode, streamed real output, observed exit code 0, and verified `/api/tools/processes` cleared the pid. |
| `WAGGLE_E2E_REAL_HOOKS=1 WAGGLE_E2E_HOOK_HOME=<temp> USERPROFILE=<temp> HOME=<temp> WAGGLE_E2E_PORT=34247 WAGGLE_E2E_BASE_URL=http://127.0.0.1:34247 npx playwright test tests/e2e/launcher-real-hook-lifecycle.spec.ts --project=chromium --reporter=list` | Pass, 1 file / 1 test | Fresh production build plus clean sidecar drove `/api/tools/hooks` through real `install`, `verify`, and `uninstall` for all six hook-capable tools: `claude-code`, `codex`, `codex-desktop`, `cursor`, `hermes`, and `openclaw`. Each case ran against a throwaway `HOME`/`USERPROFILE`, asserted config and pointer creation, Verify returned `All checks passed.`, uninstall removed the pointer and restored or removed config as appropriate, and OpenClaw's managed hook dir was removed. The first broadened run timed out at the default 30s Playwright test limit; the spec now uses a 180s timeout for the 18 synchronous route calls. |
| `npm run test -w apps/web -- src/lib/adapter.authgate.test.ts src/lib/adapter.sse.test.ts src/lib/adapter.launcher.test.ts src/components/os/apps/launcher/ToolOutputPane.test.tsx src/components/os/apps/LauncherApp.test.tsx --reporter=dot` | Pass, 5 files / 72 tests | Adds and verifies the observed-output regression: after an `exit` event, `streamToolOutput()` closes the EventSource and does not reconnect/replay old buffered output. Also protects hook result visibility: install success is summarized with `Backup` and `Recovery` labels instead of a raw `stdout:` row, verify failure preserves stderr even when `error` is generic, Verify `[FAIL]` output is summarized as `Check failed` with the manual approval detail and no raw `[FAIL]`, uninstall output labels restore/cleanup rows as `Changed file`, `Restored from`, `Created file removed`, `Backup removed`, and `Pointer removed` without implying an install pointer, long hook output is capped behind a `More output` summary while keeping recovery guidance, a structured hook failure with no stderr/error is not replaced by raw `HTTP 400`, an empty-output Verify failure shows retry/uninstall/reinstall recovery copy, installed Claude Desktop is explicitly labeled as launch-only with no hook actions, and a detected launchable third-party adapter gets a Launch action and sends its raw prompt. Output includes expected Node `punycode` deprecation warnings. |
| `npx playwright test tests/e2e/launcher-rendered-states.spec.ts --project=chromium --reporter=list` | Pass, 1 file / 5 tests | Production-build rendered Launcher proof now covers sidecar-offline recovery with an inline `Retry tool detection` action, long hook stderr summarization with `More output`, hidden-line count, and recovery guidance, standard install output with `Changed file`, `Install pointer`, `Backup`, and `Recovery` labels without raw hook command chatter, all six hook-capable tools rendering install/verify/uninstall state transitions with `Hooks active` refreshes, and a non-built-in launchable adapter state with Launch-only/no-hook copy, prompt routing, and launch payload assertion. |
| `npm run test -w apps/web -- src/test/motion-class-hygiene.test.ts src/test/wave-u-chat-action-row.test.tsx --reporter=dot`; `npm run test -w apps/web -- src/test/build-warning-hygiene.test.ts src/test/motion-class-hygiene.test.ts --reporter=dot`; `npm run build` | Pass, 3 focused web test files + production build | Adds source hygiene guards that ban Tailwind-ambiguous `duration-[var(--mo-*)]` / `ease-[var(--mo-*)]` class tokens, require named motion utilities, and prevent the adapter from dynamically importing `shape-selection.ts`. The production build no longer emits the prior Tailwind ambiguity warnings or the `shape-selection.ts` dynamic/static import warning. Remaining build/playwright noise includes `NO_COLOR`/`FORCE_COLOR`, mock embedding banners, and expected hook negative-path logs. |
| `npm run test -w apps/web -- src/test/build-warning-hygiene.test.ts --reporter=dot`; `npm run typecheck:web`; `npm run build`; `WAGGLE_E2E_PORT=4320 WAGGLE_E2E_BASE_URL=http://localhost:4320 npx playwright test tests/e2e/user-journeys.spec.ts --project=chromium --grep "J3:|J5:|J6:|J-mobile: Command Center|J-mobile: first-run onboarding|J-route-coverage|J10:|J11:" --reporter=list` | Pass, 4 build-hygiene tests, web typecheck, production build, focused rendered smoke 8 passed / 1 skipped | Route surfaces, closed shell overlays, ChatHost, and PostHog analytics are lazy-loaded and guarded. Current production build no longer emits the Vite large-chunk warning; startup JS is 421.96 kB minified / 114.08 kB gzip, and PostHog is split into a separate 208.95 kB chunk. Focused Chromium smoke covers Workspace Switcher, keyboard shortcuts, Command Center mobile, first-run onboarding mobile, route shells, Home, and keyboard-help overlay. |
| `npx tsc --noEmit --project packages/shared/tsconfig.json`; `npx tsc --noEmit --project packages/agent/tsconfig.json`; `npx tsc --noEmit --project packages/server/tsconfig.json`; `npm run typecheck:web` | Pass, 4/4 | Proves the shared detection metadata, agent launch/process contracts, server route, and web UI stay type-consistent after the adapter launch fix. |
| Fresh in-app Browser route smoke on `http://127.0.0.1:8096/launcher` with sidecar `3336` | Pass for HTTP 400 symptom and empty-output recovery; T16 still partial | The real route rendered Tool Launcher, detected installed tools, and exposed hook actions. Clicking read-only `Verify` on the first hook-capable tool now renders `verify failed (exit 1)`, `No hook output was returned`, and retry/uninstall/reinstall guidance; it does not render `HTTP 400`, and console errors/warnings for the interaction were empty. The real hook command produced no stdout/stderr detail in that run, so real installed target-app install/verify/uninstall states still need proof. |
| In-app Browser mocked Verify check failure on `http://127.0.0.1:8104/launcher` | Pass for visible check/manual-trust copy; console not clean evidence | A browser-scoped API mock rendered installed Codex, clicked the single Verify action, and fulfilled the hook route with `[PASS]` and `[FAIL]` Verify stdout. The visible panel showed `CHECK FAILED`, `hook command trusted: manual approval required in Codex settings`, and `RECOVERY`, while raw `[FAIL]` was absent. The Browser DOM snapshot API again hit the known `incrementalAriaSnapshot` issue, so proof used targeted DOM evaluation and screenshot evidence. Console logs were contaminated by earlier failed mock attempts and background polling timeouts, so component tests remain the clean console owner. |
| In-app Browser rendered Claude Desktop mock state on `/launcher` | Pass for visible state; console not used as clean evidence | A browser-scoped API mock rendered installed Claude Desktop with one Launch button, no Install hooks or Verify buttons, a `Launch only` badge, and `Hooks are not supported for Claude Desktop yet.` copy. The Browser DOM snapshot API hit the known `incrementalAriaSnapshot` issue, so proof used targeted locators and screenshot evidence. Failed earlier mock attempts left stale console log entries in Browser's collector, so the component regression is the clean console owner for this state. |
| In-app Browser mocked Codex uninstall cleanup on `http://127.0.0.1:8105/launcher` | Pass for visible restore/cleanup copy; console not clean evidence | A browser-scoped API mock rendered installed Codex, clicked the single Uninstall hooks action, and fulfilled the hook route with standard uninstall stdout. The visible panel showed `Codex: uninstall OK`, `CHANGED FILE`, `RESTORED FROM`, `CREATED FILE REMOVED`, `BACKUP REMOVED`, and `POINTER REMOVED`; `Install pointer` and raw `- backup removed` text were absent. The test tab completed onboarding via the visible `Skip setup` control first; sidecar-off shell polling still produced background console errors, so component tests remain the clean console owner. |
## UX Findings
| ID | Severity | Finding | Evidence | Correction Needed |
|---|---:|---|---|---|
| T16-1 | Rendered fixed; packaged residual | Rendered Launcher hook states are now codified across all six hook-capable tools, but packaged desktop hook-status transitions are not yet proven. | The in-app Browser smokes render installed, not installed, hooks-active, running, Phase 4/unsupported, prompt summary, install success, verify failure, mocked uninstall cleanup, and live-output states. A codified Playwright spec now proves sidecar-offline retry, long stderr summarization, standard install changed-file/pointer/backup/recovery labels, all six hook-capable tools rendering install/verify/uninstall state transitions with `Hooks active` refreshes, and rendered non-built-in adapter launch-only/prompt behavior. A gated real-tool Playwright smoke now renders Launcher with a real detected CLI and proves observed safe launch/output/exit/process-clear through the sidecar. A gated route-level smoke now proves real hook install/verify/uninstall for all six hook-capable tools against an isolated profile. | Add packaged desktop hook-status evidence, or explicitly defer packaged hook management from final scoring. |
| T16-2 | Route + rendered fixed; packaged residual | Real detected-CLI launch, the full hook-capable route lifecycle, and the full rendered installed-app hook matrix are proven; packaged desktop integration is not. | The packed package command lifecycle is proven hermetically for all six hook-capable packages. A gated Playwright smoke drove real OpenClaw detection and safe observed `--version` launch through the production sidecar route, streamed output, saw exit 0, and verified process tracking cleared the pid. The route lifecycle smoke now drives `/api/tools/hooks` through real `install`, `verify`, and `uninstall` for `claude-code`, `codex`, `codex-desktop`, `cursor`, `hermes`, and `openclaw` against an isolated `USERPROFILE/HOME`, proving config/pointer creation and cleanup without touching the user's real profile. The rendered state spec mocks the local API adapter but covers every supported hook-capable card's install, verify, uninstall, and refreshed hooks-active UI transitions. No packaged-desktop hook-status transition has been proved. | Add packaged desktop state evidence, or document approved deferrals for installed-app config-editing UI flows. |
| T16-3 | Local fixed | Package-pack `npx @waggle/hive-mind-hooks-<id>` resolution is now proven for all Launcher hook targets. | `hook-packages-runtime.test.ts` installs the packed local package closure into a temp project and invokes every hook-capable package with the same package-name shape Launcher uses: `npx --yes @waggle/hive-mind-hooks-<id> install/verify/uninstall`. | Keep this in the release lane; registry-only proof after actual publication remains launch/deploy evidence rather than a local code blocker. |
| T16-4 | Rendered fixed; release residual | Hook result copy now has a compact structured panel for focused install/verify/uninstall results: backup paths are labeled, raw `stdout:` is hidden, Verify check failures become `Check failed` rows with manual approval details, uninstall restore/cleanup rows do not imply install state, long output is capped behind a count summary, structured live failures are not masked as `HTTP 400`, empty-output Verify failures show recovery copy, offline detection has an inline Retry action, route-level lifecycle is real-proved for all six hook-capable tools, and rendered all-tool install/verify/uninstall transitions are codified. | Red component tests reproduced install success hiding a stdout backup path, verify failure dropping stderr when `error` was generic, empty-output Verify showing only an exit code, Verify `[FAIL]` output showing as generic raw output, uninstall cleanup rows appearing as generic Backup/Install pointer state, and long stderr flooding the result panel. A red adapter test reproduced the live shape `{ ok:false, code:1, stdout:'', stderr:'' }` being overwritten as `HTTP 400`; the adapter now preserves that hook envelope. The focused Launcher/web suite now proves `Backup` and `Recovery` labels for install output, stderr preservation, no raw `stdout:` row for the covered install case, `Check failed` manual-approval output without raw `[FAIL]`, uninstall restore/cleanup labels, `More output` summarization for long hook output, and empty-output recovery copy. Browser evidence on mocked Verify and Uninstall states renders the manual approval detail, `RECOVERY`, and restore/cleanup labels. A fresh real Browser smoke renders `verify failed (exit 1)` plus retry/uninstall/reinstall guidance instead of `HTTP 400`. A codified rendered Playwright spec proves standard install changed-file/pointer/backup/recovery labels, offline retry, long-output summarization, and all-six hook-card install/verify/uninstall transitions. A gated route Playwright smoke proves real install/verify/uninstall for all six hook-capable tools succeeds through `/api/tools/hooks` after Windows `npx` command resolution was fixed. | Keep the lifecycle panel regression green; finish packaged desktop status proof and warning hygiene. |
| T16-5 | Focused fixed | Claude Desktop's unsupported-hook state is explicit in the UI. | Manifest marks it non-hook-capable and its package is a no-bin stub. A red component test reproduced the old state where installed Claude Desktop had only Launch and no explanation. The Launcher now shows a `Launch only` badge, `Hooks are not supported for Claude Desktop yet.` copy, one Launch button, and no Install hooks or Verify actions; a Browser-rendered mocked state confirmed the visible layout. | Keep this focused regression in the T16 lane. |
| T16-6 | Focused fixed | Launchable third-party adapters can be detected and launched through the route/UI contract; hook management remains intentionally built-in-only. | Red tests reproduced the gap: `launchTool()` rejected a registered `foo-cli`, `/api/tools/launch` rejected the adapter id before applying its prompt template, detection omitted launch/prompt metadata, and Launcher rendered the adapter as a non-actionable Phase 4 item. The current contract uses registry metadata for detection, validates launch IDs against `getToolRegistry()`, applies `promptArgTemplate` server-side, tracks adapter process IDs as strings, and shows a Launch action plus prompt routing for launchable detected adapters. Focused backend/agent tests pass 108/108, tracker/route regression tests pass 96/96, the focused web Launcher suite passes 72/72, shared/agent/server/web typechecks pass, and rendered Playwright coverage proves a non-built-in adapter shows launch-only/no-hook copy, routes the prompt, and sends the expected launch payload. | Keep third-party hook management disabled until a safe hook command/package policy exists. |
| T16-7 | Local fixed | Hook package-local test scripts now run their intended lanes. | Package-local `npm run test --workspace ...` now passes for hook core, all six hook-capable packages, and shim core. The fix also replaced the CLI's CommonJS-only `createRequire().resolve()` path with ESM-compatible `import.meta.resolve` for the MCP server entry. | Keep these package-local scripts in the release lane; remaining package-local command-shape gaps are tracked under T17. |
| T16-8 | Partially fixed | Standard hook/test output is still too noisy, but the Tailwind motion-token ambiguity warnings, `shape-selection.ts` dynamic/static import warning, and Vite large-chunk warning are fixed. | Passing root-run hook tests still emit install logs, fail-open warnings, sidecar-unreachable drops, and server embedding degradation banners. Playwright output still includes `NO_COLOR`/`FORCE_COLOR` and mock-embedding noise. The old Tailwind ambiguity warnings from `duration-[var(--mo-base)]`, `duration-[var(--mo-fast)]`, and `ease-[var(--mo-ease)]` no longer appear after replacing them with named motion utilities guarded by `motion-class-hygiene.test.ts`; the defeated `shape-selection.ts` dynamic import no longer appears after promoting the adapter dependency to a static import guarded by `build-warning-hygiene.test.ts`; the oversized startup chunk no longer appears after lazy-loading routes, closed shell overlays, ChatHost, and PostHog analytics behind `build-warning-hygiene.test.ts`. | Quieten or isolate the remaining expected warnings in the standard release lane so real hook failures stand out. |
| T16-9 | Partially fixed | Launcher prompt metadata is fixed, including third-party prompt-template metadata, but prompt-support transparency still needs a focused pass. | Current Launcher source gives the optional prompt textarea `id`, `name`, `aria-label`, `autocomplete`, and a visible label. The accepts/ignores summary now includes adapters whose manifests have `promptArgTemplate`, but it still appears only after text exists. | Make prompt support obvious per tool before launch. This can be bundled with T10 form/focus work. |
| T16-10 | Focused fixed | Observed live output no longer reconnects and replays duplicate terminal output after process exit. | The red regression in `adapter.sse.test.ts` reproduced the issue: after `line` and `exit`, the EventSource stayed open and could reconnect. `streamToolOutput()` now closes its EventSource on a valid `exit` event; the current focused Launcher/web suite passes 5 files / 72 tests. | Keep this regression in the T16 lane; rendered no-duplicate screenshot evidence can be refreshed when the broader Launcher state matrix is rerun. |
| T16-11 | Focused fixed | Windows npm shim launch/version behavior is now safer, failed child spawns no longer crash the sidecar, and restricted Codex WindowsApps aliases no longer show a failing Launch path. | Real evidence found `where.exe openclaw` returning an extensionless POSIX shim before `openclaw.cmd`, which made Node spawn fail. Detection now prefers spawnable Windows hits, standard npm `.cmd` shims resolve to their Node module target, unknown `.cmd`/`.bat` files use a quoted fallback, and `defaultSpawnDetached`/`defaultSpawnObserved` guard async child `error` events. The first real Playwright smoke reproduced the old behavior as a sidecar crash; the final smoke passed. On this Windows host, Codex detects only through a WindowsApps app alias that refuses command-line exec; detection now marks that install `launchable: false`, and Launcher shows recovery copy instead of a Launch button. | Keep the Codex WindowsApps regression. A future direct-launch path should require a supported PATH CLI or a proven desktop-specific launch bridge. |
| T16-12 | Focused fixed | Windows hook-management command execution now resolves `npx` correctly. | A gated route smoke first failed because `/api/tools/hooks` returned HTTP 400 with empty stdout/stderr: `execFile('npx')` on Windows cannot resolve the npm shim, and a bare `npx.cmd` can pick the wrong shim under npm-started PATHs. `runHookCommand()` now prefers the `npx.cmd` beside `process.execPath`, and default exec capture uses the shared `.cmd` resolver. The broadened route smoke passes real install/verify/uninstall for all six hook-capable tools in an isolated profile. | Keep the gated route smoke in the release lane. |
## Persona Impact
| Persona | Current T16 cap | Why |
|---|---:|---|
| Engineer / power user | 8/10 | They can now trust packed-package command lifecycle, focused/rendered third-party launch behavior, Windows npm-shim launch handling, one real observed CLI launch, all six real hook route lifecycles, and the all-six rendered hook matrix. Packaged desktop status evidence and warning hygiene still cap trust. |
| Solo founder | 8/10 | Hook setup edits personal AI-tool configs; packed lifecycle evidence plus Backup/Recovery, install pointer, manual-approval, uninstall cleanup, long-output, offline retry copy, one real safe launch, all six isolated route lifecycles, and all-six rendered transitions improve confidence. Remaining concern is packaged desktop status transitions. |
| Team admin | 7/10 | Unsupported Claude Desktop messaging is now explicit, one real launch path is proven, all six hook-capable route lifecycles are proven, and all-six rendered state transitions are covered, but team rollout still needs packaged desktop evidence and quieter release output. |
| Researcher | 8/10 | Less central, but memory capture trust depends on hooks failing open and reporting status clearly. |
| Mobile executive | 8/10 | Less central, but launch/hook management still needs clear compact states if surfaced on smaller screens. |
## Acceptance For Closing T16
- Rendered Launcher evidence covers detected, not detected, installing, hooks active, verify success, verify failure, uninstall, all six hook-capable install/verify/uninstall transitions, sidecar offline, running observed output without duplicate replay, and unsupported Claude Desktop.
- Command lifecycle evidence covers install, verify, and uninstall for all six hook-capable packages using the production-like invocation path.
- `npx`/package-pack resolution is verified for every hook package that Launcher can invoke; registry-only proof is captured after actual publication.
- Hook result UI exposes backup/pointer paths and manual trust steps without dumping raw logs as the primary UX.
- Third-party adapter launch behavior has focused route/UI coverage and rendered non-built-in adapter proof.
- Real detected CLI launch behavior has at least one safe observed smoke, and hook install/verify/uninstall has isolated route lifecycle evidence for all six hook-capable tools.
- Hook/shim package-local test commands pass; any broader package-local command-shape gaps are tracked under T17.
## Packet Decision
Keep T16 as `Phase 2 Pending`. The rendered Launcher proof now includes all six hook-capable install/verify/uninstall transitions, packed-package `npx` lifecycle is locally proven, hook/shim package-local scripts now pass, observed output no longer reconnects after exit, component tests prove hook stdout/stderr details are not dropped, covered install output now renders Backup/Recovery labels instead of raw stdout, rendered standard install output shows changed-file and install-pointer labels, Verify `[FAIL]` output now renders as `Check failed` with manual-approval detail, uninstall output now renders restore/cleanup labels without implying install state, long hook output is summarized behind `More output`, offline detection now has rendered Retry recovery, Claude Desktop is explicitly launch-only, launchable third-party adapters are covered through detection/route/UI/rendered tests, the live Verify path no longer renders generic `HTTP 400` or bare empty-output exit codes, Windows npm shims are launchable/version-probed, Codex WindowsApps installs are blocked with recovery copy instead of a failing Launch button, one real detected CLI launch/output/exit/process-clear lifecycle is proven, all six real `/api/tools/hooks` install/verify/uninstall route lifecycles are proven in an isolated profile, the Tailwind motion-token ambiguity warnings are gone, and the `shape-selection.ts` dynamic/static import warning is gone. Packaged desktop hook-status transitions and remaining warning hygiene still block the final "complete UX, all parts functional" claim unless the user explicitly defers AI-tool hook lifecycle from the five-persona score.