Skip to content

fix: ada command hints follow PATH, escape paths, and fall back to t3 - #241

Merged
jayleaton merged 2 commits into
mainfrom
fix/ada-command-fallbacks
Nov 14, 2026
Merged

jayleaton merged 2 commits into
mainfrom
fix/ada-command-fallbacks

Conversation

@jayleaton

Copy link
Copy Markdown
Owner

Problem

Four defects from Randy's re-review of #234/#235 that merged to main:

  1. ada update chose ada because this install owned an ada launcher file, not because PATH runs it. With another program's ada earlier on PATH, following the hint ran that program.
  2. The fallback runtime path was double-quoted, so $workspace expanded, and quotes or backticks in the path broke the command.
  3. Boot recovery (ada triage) and the desktop state-directory dialog (ada update, ada service …) fail on installs that have only t3, or run a foreign ada. The in-app triage fallback toast and the WSL dialog had the same hint.
  4. The usage-data notice promised opt-in on every server, but servers from before feat: Pip is Ada's logo across every surface #235 still send by default.

Change

Defect Fix
1 ownedCommandOnPath resolves ada, then t3, through PATH, and names one only when the file PATH runs is this home's launcher (after an install: one that starts the new runtime). Otherwise the next name, then the runtime path.
2 New shellCommandPath in @t3tools/shared/shell: bare when plainly safe, else a POSIX single-quoted literal, or PowerShell & '…' with '' (and doubled typographic quotes) on Windows.
3 Desktop: runnableCliCommand(state) uses the command its CLI state says PATH runs, else the escaped bundled launcher, else t3. DesktopCliCommand now builds with the backend layer so the pool's dialog can read it. Web boot error, in-app triage fallback and the WSL dialog have no such state and say t3.
4 AnalyticsService.enabled reports the effective telemetry state, and the server sends it as ServerConfig.telemetryEnabled. The notice promises opt-in only when the server reports false, says so when it reports true, and for an older server that omits it says it may send data.

Not changed: the telemetry default and the privacy-policy link (product decision).

Verification

  • A regression test per defect, each failing on main (source files reverted to origin/main with the new tests kept):
    • update.test.ts: rows for a foreign ada first on PATH, launchers off PATH, no launcher. The temp home contains $workspace, ", a backtick and spaces, and the fallback must be the single-quoted literal.
    • shell.test.ts: shellCommandPath table ($, quotes, backticks, spaces, Windows ' and ’), plus a round-trip through /bin/sh.
    • bootError.test.ts and DesktopCliCommand.test.ts (runnableCliCommand): the t3 fallback and owned-command rows.
    • managedPolicy.test.ts (usageDataNotice) and AnalyticsService.test.ts (enabled across shell discovery).
  • vp run check:changed: format, lint, knip, typecheck (37 packages), tests (15 files), react compiler all pass.

🤖 Generated with Claude Code — Claude Opus 5.5 in T3 Code (Claude Code harness)

`ada update` recommended `ada` whenever this install owned an `ada` launcher,
even when PATH runs another program's `ada` first, and double-quoted the
runtime path, so `$workspace`, quotes and backticks in it broke the command.
Boot recovery and the desktop's state-directory dialog said `ada triage` and
`ada update`, which fail on installs that have only `t3`. The usage-data
notice promised opt-in on every server, though older servers send by default.

The update resolves `ada`, then `t3`, through PATH and names one only when
the file PATH runs is this home's launcher (after an install, one that starts
the new runtime); otherwise it prints the runtime path as a POSIX or
PowerShell literal (`shellCommandPath` in @t3tools/shared/shell). Desktop
recovery copy names the command its CLI state says runs, else the launcher,
else `t3`; web and WSL copy without that state says `t3`. Servers now report
`telemetryEnabled` in their config, and the notice promises opt-in only when
the server says it is off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L labels Nov 13, 2026
@github-actions

github-actions Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 5.0 KiB 5.0 KiB 0 B (0.0%) 6.8 KiB ✅
Codex Thread snapshot wire 3.8 KiB 3.8 KiB 0 B (0.0%) 4.9 KiB ✅
Codex Live turn WebSocket wire 1.2 KiB 1.2 KiB 0 B (0.0%) 2.0 KiB ✅
Codex Live turn WebSocket decoded 21.5 KiB 21.5 KiB 0 B (0.0%) 24.4 KiB ✅
Codex Live turn messages 1 1 0 (0.0%) 8 ✅
Claude Total thread wire 5.0 KiB 5.0 KiB 0 B (0.0%) 6.8 KiB ✅
Claude Thread snapshot wire 3.8 KiB 3.8 KiB 0 B (0.0%) 4.9 KiB ✅
Claude Live turn WebSocket wire 1.2 KiB 1.2 KiB 0 B (0.0%) 2.0 KiB ✅
Claude Live turn WebSocket decoded 21.9 KiB 21.9 KiB 0 B (0.0%) 24.4 KiB ✅
Claude Live turn messages 1 1 0 (0.0%) 8 ✅

Baseline: 57ef5ff · PR result: c4607b2 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@jayleaton

Copy link
Copy Markdown
Owner Author

Review of 73a4769: CI is green and the four original defects are fixed. 245 tests pass, ordinary foreign-ada precedence now works, POSIX quoting holds for newlines, ', unicode, $, backticks and ", telemetry decodes in both compatibility directions, and the layer move introduces no lifecycle regression. Three gaps remain and block merging:

  1. apps/server/src/cli/update.ts:175: empty PATH entries are dropped. With PATH=:<owned-bin> and an executable foreign ./ada, the hint recommends ada, but the shell runs the foreign program (reproduced). Treat an empty POSIX entry as the current directory, and only count executable files.
  2. apps/server/src/cli/update.ts:177: Windows resolution ignores PATHEXT. A foreign ada.bat in an earlier directory is skipped, so a later owned ada.cmd gets recommended. Honor PATHEXT's extensions and its order.
  3. apps/web/src/lib/bootError.ts:7, plus the WSL recovery text and the triage toast: the no-state fallback can still name a foreign program. When install.sh keeps a foreign t3 and installs only ada, the hint says t3 triage and runs the foreign t3 (reproduced). Where there's no desktop state, use neutral guidance such as "Run triage with your installed Ada CLI (ada, or legacy t3)" rather than a copyable command that hasn't been verified.

Nit: packages/shared/src/shell.ts:1113. The quoted Windows form & '…' only works in PowerShell, not cmd.exe. Label those hints "Run in PowerShell", or pick the syntax for the invoking shell.

…ied commands

Review of #241 found three gaps. The PATH search dropped empty POSIX entries,
which a shell searches as the working directory, and counted files it cannot
execute. On Windows it tried only .exe and .cmd, so another program's ada.bat
earlier on PATH was skipped. Where no desktop state verifies a command, the
hints still named `t3`, which install.sh can leave to another program.

The search now treats an empty POSIX entry as the working directory, counts
only executable files, and follows PATHEXT's extensions in order. Boot
recovery, the triage toast and draft hero, the WSL dialog, and the desktop
dialog without a verified command say to run the subcommand with the Ada CLI
(`ada`, or legacy `t3`) and offer nothing to copy. The quoted Windows path
form is labelled "in PowerShell", since cmd.exe cannot run it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jayleaton

Copy link
Copy Markdown
Owner Author

Fixed in c4607b2: the PATH search treats an empty POSIX entry as the working directory, counts only executable files, and follows PATHEXT order on Windows. Where no command is verified (boot error, triage toast and hero, WSL dialog, desktop dialog without CLI state), the hints say to run the subcommand with the Ada CLI (ada, or legacy t3) and offer nothing to copy. The quoted Windows path is labelled "in PowerShell". Each fix has a regression test that fails on 73a4769.

@jayleaton
jayleaton merged commit 1d94b77 into main Nov 14, 2026
29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant