mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-09-30 12:39:42 +02:00
Review follow-ups on #282. All four are the same failure shape: a list that enumerates run modes, missed by the sweep that added 'pi'. 1. Cron ignored pi's project-trust clamp. The PR widened CronJobBaseSchema's agentType to accept 'pi' but not the matching clamp beside gemini's, so a non-granted multi-user owner's cron pi job spawned bare `pi` (pi's own defaultProjectTrust, an interactive prompt they can answer "yes" to, which loads and EXECUTES repo-local .pi/extensions TypeScript) while the same user's UI/API launch was forced to --no-approve. The clamp is now a pure exported helper, clampCronExternalCliConfigs(), so both it and gemini's previously untested materialization are pinned. 2. POST /api/sessions/:id/interactive auto-enabled the Ralph tracker for pi: its denylist covered opencode/codex/gemini/antigravity only. The tracker is never fed for an external CLI (_processExpensiveParsers returns early), so a pi session reported ralphEnabled and Ralph UI state no sibling backend shows. 3. REMOTE_CLI_BIN had no pi entry, so buildRemoteCliVersionProbeCommand() returned null and Session.cliVersion stayed blank for every remote-SSH pi session, even though the PR wired the remote launch command and the per-mode override schema field. 4. The desktop home rail's badge map had no pi entry, and its lookup falls back to '', which is what claude renders. A pi session read as Claude there while the tab strip and phone overview badged it correctly. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
3.6 KiB
3.6 KiB
aicodeman
| aicodeman |
|---|
| minor |
Add Pi (pi.dev) as a sixth CLI run mode (#206).
SessionMode gains 'pi', a first-class backend alongside Claude Code, OpenCode, Codex, Gemini and Antigravity: its own PTY, tmux session, rose tab identity, welcome button, run-mode entry, cron agentType, Docker and remote-SSH command defaults, and clone-repo Brain option.
- New resolver
src/utils/pi-cli-resolver.ts. Unlike the sibling resolvers it sanity-probespi --versionand requires semver-shaped output, becausepiis a short generic name that a stray binary on$PATHcan shadow; the rejected path is logged.GET /api/pi/statusreturns{ available, path, version }so a misresolution is diagnosable. PiConfigmaps to--model(acceptsprovider/idand a:thinkingsuffix),--provider,--thinking,--session/-c, and the tri-state--approve/--no-approve. Every value is regex-allowlisted and dropped on failure.--api-keyis deliberately never wired: it would put a provider secret on the spawn command line.- No bypass flag. Pi has no permission prompts and no sandbox, so there is no
--dangerously-skip-permissionsanalog. Its privilege-shaped knob isapproveProjectTrust, which makes pi load and execute repo-local.pi/extensionsTypeScript and install missing project packages.clampExternalCliBypassForOwner()therefore puts pi in the materialize branch: a non-granted multi-user owner gets--no-approveeven when no config was sent, because pi's own default is an interactive prompt the session user could answer themselves. The same materialization applies to cron-fired jobs (clampCronExternalCliConfigs), which carry no per-CLI config and would otherwise launch on pi's own default. Both helpers had no test coverage at all; they now do, for every CLI. - Env allowlist gains only the
PI_*prefix. Pi's ~34 provider key vars share no prefix andALLOWED_ENV_PREFIXESis one global list with no mode context, so admitting them would widen the allowlist for every mode at once. Users authenticate via pi's/loginor the server process's own environment. - Pi stays out of
isAltScreenStripMode(). Its default TUI renders into the main screen with terminal-owned scrollback, and since 0.84.0 the user can flip to a fullscreen TUI at runtime via/settings— verified to switch the pane into the alt screen, which the strip would have corrupted. - Docker: pi installs in its own
--ignore-scriptsstep so that flag cannot affect the other four CLIs, and its credentials are seeded per-file (auth.json,settings.json,trust.json,models.json,models-store.json) rather than whole-dir, since~/.pi/agentalso holds sessions, extensions and installed package trees. - Local echo: pi lands on the buffer overlay. Verified that codex's per-keystroke starvation does not reproduce — pi's slash picker re-filters on the whole composer content, so a one-shot flush behaves identically to per-keystroke typing.
- Mode-list parity: pi is excluded from the Ralph tracker auto-enable on
POST /api/sessions/:id/interactive(like every other external CLI, whose output the tracker never parses), carries aREMOTE_CLI_BINentry so a remote-SSH pi session reports its CLI version, and gets its own badge in the desktop home rail instead of rendering like Claude. - Installer detection, docs (
docs/pi-integration.md), READMEs, and the architecture invariants are updated. Tests:test/pi-mode.test.tsandtest/routes/external-cli-bypass-clamp.test.ts, plus extensions to the run-mode, mobile-overview, render-index-html, system-routes and local-echo suites.