Skip to content

feat(native): run SumoCode's Pi in T3 Code via sumocode-pi-cli, on Pi 1.1.0 - #618

Merged
dhruvkelawala merged 9 commits into
mainfrom
sumo/sumocode-pi-cli
Oct 12, 2026
Merged

dhruvkelawala merged 9 commits into
mainfrom
sumo/sumocode-pi-cli

Conversation

@dhruvkelawala

@dhruvkelawala dhruvkelawala commented Oct 9, 2026 •

Copy link
Copy Markdown
Owner

Summary

T3 Code, and other apps that launch pi themselves, can now run SumoCode's bundled Pi. Pi under T3 sees T3's own tools plus the SumoCode tools that work there. The SumoCode shell and its Herdr integration are unchanged.

T3 Code ── spawns ──▶ ~/.local/bin/sumocode-pi-cli        (install.sh link → archive bin/)
                        ├─ --version        → bin/sumocode-pi --version   (Pi 0.99.1, the version T3 checks)
                        ├─ --no-extensions  → bin/sumocode-pi "$@"         (T3's commit-message / title runs)
                        └─ otherwise        → SUMOCODE_APP_HOST=1 bin/sumocode --no-sumo-tui "$@"
 sumocode(pi)                          # src/extension.ts
   SUMOCODE_RPC_CHILD=1  → installRpcChildProfile   # SumoCode shell + Herdr bridge, unchanged
+  SUMOCODE_APP_HOST=1   → installAppHostProfile
+    question, terminal_*, Slate tools · memory · skill expansion
+    /slate /sumo:ship /sumo:memory /sumo:sync /sumo:bootstrap /fast /answer
+    T3 bridge present (T3_MCP_URL + token)?
+      yes → no subagent_*; prompt maps each role → delegate_task(target: pi, role model, role instructions)
+      no  → SumoCode subagents as before
   otherwise             → classic profile          # unchanged

The profile keys off the wrapper's marker, not T3's variables. T3 lists slash commands from a discovery process that has none of them, so keying on T3's env would show the composer a different command list than the chat session.

Pi 0.99.1 to 1.1.0 (5a2c780f), in the same PR as asked:

  • No contract changes: rpc-types.d.ts is byte-identical, and the compile-exhaustive RPC classification typechecks unchanged.
  • One new flag: args.js adds the boolean --no-mcp. Both launcher tables list it, so it never consumes the prompt, and a new PTY row covers that.
  • Native build unchanged: the bun/ entry files and Bedrock strip points are the same, and both binaries report 1.1.0.
  • RPC output stays clean: OSC 7501 program status is interactive-only, so the JSONL that T3 and the shell read is unaffected.
  • One limitation: Pi 1.0 opens plain interactive sessions fullscreen, and there SumoCode's classic footer does not draw. The package-entry boot test pins --tui-mode regular, and the changelog says how to keep regular mode.

Evidence

  • Before: T3's Pi provider found only the stale global pi 0.87.1. Pointing it at sumocode failed because sumocode --version prints sumocode 0.7.6, which T3 reads as Pi 0.7.6. With SumoCode's Pi, T3's composer listed 53 commands, including /reload, /exit, /login, /sumo:theme, /sumo:tabs, and /sumo:worktree. The prompt told the model to delegate with visible subagent_spawn, which fails under T3 with "visible subagents require a running terminal host".
    After: checked in T3 Code nightly 0.0.46-nightly.20261009, with the Pi provider pointed at this branch's archive:
    • T3's probe reports Pi 0.99.1 ready. The composer lists 39 commands, and SumoCode's are exactly answer fast slate sumo:bootstrap sumo:memory sumo:ship sumo:sync.
    • The captured provider request (a temporary before_provider_request probe) has no subagent_* tools. It has question, terminal_*, slate_*, and mcp__t3-code__{orchestrator_capabilities,delegate_task,task_status}. The prompt has ## SumoCode roles in T3 Code followed by T3's orchestration block.
    • Asked to delegate with the research role, Pi called mcp__t3-code__delegate_task. T3 shows a child thread on provider pi with model deepseek/deepseek-flash, the role's model from roles.json.
    • terminal_start with completion: wake ended the turn. T3 opened run 2, "Background activity updated", and Pi replied WOKE TERMINAL-WAKE-OK.
    • Cancelling a T3 Pi turn reaps the launcher, the Pi child, and the tool processes (one process group) within 2 s.
  • Commands at 5a2c780f, on Pi 1.1.0 (CI=1):
    • pnpm exec tsc --noEmit ✅ · node scripts/check-tsc-budget.mjs ✅ · pnpm lint ✅ · node scripts/check-dependency-audit.mjs ✅
    • Focused vitest (app-host, extension, interaction-registry, build-native, dependency-audit, rpc response anchors): 130/130 ✅
    • pnpm test:native: 109/109 ✅, 0 orphans. sumocode-pi --version and sumocode-pi-cli --version both print 1.1.0, and codesign --verify --strict passes on both binaries.
    • pnpm test:integration: 45 files, 349 passed and 110 skipped ✅, 0 survivors across 175 process groups.
    • scripts/smoke-pi-versions.sh --supported-matrix (pnpm 10.29.2, as CI): Pi compatibility contract 1.1.0: PASS, sumocode Pi compatibility 1.1.0: PASS ✅
    • pnpm test: the same 8 failing files and 29 tests as main on this machine (git-worktree fixtures and timeouts).
  • Autoreview: autoreview --mode local --engine codex --model gpt-6.1-sol --thinking xhigh --max-priority P1 came back clean on every round: the feature (0.84), each review repair (0.9, 0.9, 0.99), and the Pi bump (0.87). Every OpenCodeReview and pullfrog thread is answered and resolved.

Merge Danger

Door: two-way

Nothing changes unless SUMOCODE_APP_HOST=1 is set, and only sumocode-pi-cli sets it. Reverting removes the wrapper and the profile.

Blast Radius: contained, plus a Pi major

  • sumocode, sc, the RPC host, the rpc-child profile, and the Herdr bridge take the same paths as before. The integration suite is green.
  • install.sh now requires bin/sumocode-pi-cli. The installer ships inside the same archive, so the two always match.
  • Inside T3 Code, the model loses subagent_* in favor of delegate_task. If T3's MCP bridge is off, SumoCode subagents stay.
  • Pi 1.1.0 is a major bump, but the RPC contract is unchanged and the full integration suite passes. Plain interactive Pi with the extension now opens fullscreen without the classic footer (see the changelog).
  • Not in scope: SumoCode outside Herdr still advertises visible subagents in its prompt.

install.sh links ~/.local/bin/sumocode-pi-cli, a Pi CLI entry for apps
that launch pi themselves. It reports the bundled Pi version, runs bare
Pi for --no-extensions helper runs, and otherwise runs
`sumocode --no-sumo-tui` with SUMOCODE_APP_HOST=1.

That marker selects a new app-host extension profile: no chrome, no
Herdr bridge, the question/terminal/Slate tools, memory, and seven
commands that work through Pi's RPC dialogs. Inside T3 Code, T3's
delegate_task replaces the subagent tools and the system prompt maps
each SumoCode role to a delegate_task call. The rpc-child profile and
the classic profile are unchanged.
@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

🔍 OpenCodeReview found 3 issue(s) in this PR.

  • ✅ Successfully posted inline: 2 comment(s)
  • ⏭️ Skipped (overlap with history): 1 comment(s)

Comment thread src/extension-core.ts Outdated
Comment thread src/extension-core.ts Outdated
Comment thread src/native/sumocode-pi-cli.sh
Comment thread src/native/sumocode-pi-cli.sh Outdated
@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Here's a visual recap of what changed:

Visual recap

Open the full interactive recap

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

Reviewed the complete 13-file diff at dd89fab and traced each new path through its consumers.

  • App-host profile dispatch (src/app-host.ts, src/extension.ts, src/extension-core.ts): SUMOCODE_APP_HOST=1 selects installAppHostProfile after the helper-subprocess guard, the duplicate-install guard, the process latch, and the SUMOCODE_RPC_CHILD check — so SumoCode's own child and the Herdr bridge keep the full rpc-child profile, and the marker (not T3's variables) drives selection.
  • T3 orchestration gate (hasT3Orchestration requires both T3_MCP_URL and T3_MCP_BEARER_TOKEN): with the bridge, subagent_* tools are replaced by buildT3RoleGuidance appended in before_agent_start; without it, installSubagents runs unchanged. Pi's emitBeforeAgentStart chains handler results (dist/core/extensions/runner.js), so the append composes with other handlers.
  • Command allowlist (installAppHostInteractions + answer/fast): I checked each of the seven handlers takes an RPC-safe path — showDivineQuery and showMemoryEditor both branch on ctx.mode === "rpc", as does /answer, and /fast, /sumo:sync, /sumo:bootstrap only notify.
  • Wrapper and packaging (src/native/sumocode-pi-cli.sh, install.sh, scripts/build-native.mjs): version fast-path, bare-Pi --no-extensions passthrough, -- termination, and symlink-to-archive resolution are consistent with the existing launcher; the installer requires, checks, and links bin/sumocode-pi-cli, and the archive build copies it 0755.
  • Tests and docs: unit coverage asserts the exact 7-command list, the subagent swap, no chrome on session_start, and rpc-child precedence; native cases cover install/version/dry-run and get_commands through the wrapper, including empty output under --no-extensions.

Verification at this head: tsc --noEmit clean, oxlint clean on the touched files, and vitest for src/app-host.test.ts + src/extension.test.ts + src/interaction-registry.test.ts passes 46/46. CI's typecheck + unit tests job is red before those steps run — its Dependency audit policy step reports unclassified high advisory 1240992, advisory data unrelated to this diff (no dependency files changed). The four OpenCodeReview inline notes were assessed and are non-blocking: the unbounded symlink loop mirrors bin/sumocode.sh's existing resolution, and the per-turn loadRoles read matches subagent_spawn's per-call pattern.

Pullfrog  | View workflow run | Using deepseek-flash | 𝕏

…on probe

- Load roles.json once when the app-host profile installs, like the
  subagent tools do, and log its warnings, since no spawn step checks
  them under T3.
- sumocode-pi-cli answers -v/--version only as the sole argument, the
  form apps probe with, so a -v that is another flag's value is not
  misread.
Comment thread src/app-host.ts
Comment thread src/app-host.ts Outdated
Comment thread src/extension-core.ts
Comment thread src/extension-core.ts Outdated
Comment thread src/extension-core.ts Outdated
Comment thread src/native/sumocode-pi-cli.sh

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

Reviewed the incremental delta from dd89fab to 3a034a3 and re-read the full 13-file diff for context.

  • Load T3 role guidance once (src/extension-core.ts): loadRoles({ env }) now runs at profile install instead of inside before_agent_start, matching how registerSubagentTools builds its prompt guidelines once; discarded warnings are surfaced through logDiagnostic("app_host_roles_warnings", …). warning.message matches RoleWarning, and the handler only appends the prebuilt string, so no filesystem read happens per turn.
  • Override regression test (src/extension.test.ts): writes a research model override into the per-test temp PI_CODING_AGENT_DIR and asserts the T3 guidance carries - research (model deepseek/deepseek-flash): …; the file lives in the temp dir afterEach removes.
  • Bare version probe (src/native/sumocode-pi-cli.sh): --version/-v route to sumocode-pi only as the sole argument, while --no-extensions keeps its pre--- scan, so helper runs are unchanged.

Verification at this head: pnpm exec tsc --noEmit clean and pnpm vitest run src/app-host.test.ts src/extension.test.ts 43/43 pass.

Pullfrog  | View workflow run | Using deepseek-flash | 𝕏

…ance

- Each role line now lists its tools and MCP limits, and the guidance
  says delegate_task cannot fence them, so the task must state them.
- roles.json is read on every turn: under T3 the guidance is the role
  config, and no spawn step re-reads it the way subagent_spawn does.
- roles.json problems go into the guidance, the one channel that reaches
  the model and user here, as well as the diagnostics log.
- The app-host activation diagnostic records whether T3 orchestration
  was found, so the fallback to SumoCode subagents is observable.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ No critical issues — one minor rendering suggestion inline.

Reviewed changes

Reviewed the delta from 3a034a3 to 1a0c1e91 (plus the full 13-file diff for context).

  • Role guidance rebuilt per turn again (src/extension-core.ts): loadRoles moved back inside before_agent_start, so roles.json edits take effect mid-session; warnings are re-read, logged each turn, and passed into the guidance. This deliberately reverses the install-time load from 3a034a3 and matches the author's reply on the round-2 OCR thread.
  • Role limits and warnings in the prompt (src/app-host.ts): each role line now carries its tools/mcpServers limits, and a new sentence tells the model that delegate_task cannot fence a child's tools so the task must state them. roles.json warnings are appended to the guidance itself.
  • Fallback observability (src/extension.ts): the app-host extension_activate_end diagnostic records t3Orchestration, so subagents-vs-delegate_task selection is visible in logs.
  • Tests: new cases for role limits and warnings; the roles.json override test now edits the file between turns and asserts the guidance follows, including the broken-file fallback.

Verification at this head: pnpm exec tsc --noEmit clean, pnpm lint clean, and vitest run src/app-host.test.ts src/extension.test.ts passes 45/45.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using deepseek-flash | 𝕏

Comment thread src/app-host.ts Outdated
roles.json "tools": [] launches a SumoCode child with --no-tools, so the T3 guidance says "no tools" instead of a blank list, matching "no MCP". Per pullfrog's review on #618.
Comment thread src/native/sumocode-pi-cli.sh
Comment thread src/native/sumocode-pi-cli.sh

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

Reviewed the delta from 1a0c1e9 to 09a0f75 (plus the full 13-file diff for context).

  • Empty role tool lists render meaningfully (src/app-host.ts): roleLimits now renders tools: [] as no tools instead of a bare tools: , matching the existing no MCP handling for mcpServers: [] and the --no-tools launch SumoCode gives a child with an empty tool surface (src/subagents/task-config.ts:105).
  • Test coverage (src/app-host.test.ts): the role-limits case adds a tools: [] role and asserts - think (inherits your model; no tools): think.

The prior review's inline suggestion is applied and its thread is resolved. Verification at this head: pnpm exec tsc --noEmit clean, pnpm lint clean (4 pre-existing scratch warnings), CI=1 vitest run src/app-host.test.ts src/extension.test.ts 45/45 pass.

Pullfrog  | View workflow run | Using deepseek-flash | 𝕏

Move the Pi peer range, dev pin, native PI_PIN, supported-matrix
default, and every pin anchor from 0.99.1 to 1.1.0.

Upgrade review (0.99.1 -> 1.1.0):
- RPC types (rpc-types.d.ts) are byte-identical, and the compile-exhaustive
  contract classification typechecks unchanged.
- args.js adds one boolean, --no-mcp. The launcher tables in
  bin/sumocode.sh and src/native/main.ts now list it, with a PTY row.
- The bun/ entry files and Bedrock strip points are unchanged; the native
  build still excludes Bedrock and both binaries report 1.1.0.
- OSC 7501 program status lives only in interactive mode, so RPC stdout
  stays clean JSONL for the shell and T3.
- Pi 1.0 opens interactive sessions fullscreen, where the classic footer
  does not draw. The package-entry boot test pins --tui-mode regular, and
  the changelog notes the limitation.
@dhruvkelawala dhruvkelawala changed the title feat(native): run SumoCode's Pi in T3 Code via sumocode-pi-cli feat(native): run SumoCode's Pi in T3 Code via sumocode-pi-cli, on Pi 1.1.0 Oct 12, 2026
Comment thread src/native/sumocode-pi-cli.sh Outdated
The bare-Pi --no-extensions path loads no SumoCode extension, so the marker now applies only to the final sumocode --no-sumo-tui exec. Per OpenCodeReview on #618.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

Reviewed the delta from 09a0f75 to 5a2c780 — the Pi 0.99.1 → 1.1.0 bump with its pin updates, plus the origin/main merge that landed alongside it — against the full 27-file diff.

  • Pi bumped to 1.1.0 (package.json, pnpm-lock.yaml, scripts/build-native.mjs, scripts/smoke-pi-versions.sh, scripts/check-dependency-audit.test.mjs): peer ranges and dev pins move to ~1.1.0, the native PI_PIN and the smoke matrix default follow, and the lockfile resolves the 1.1.0 dependency chain.
  • --no-mcp handled as a boolean (bin/sumocode.sh, src/native/main.ts, test/integration/spawn-pi-pty.test.ts): both launcher option-consumption mirrors list Pi 1.1.0's only new CLI flag — the sole change to the args.js parse loop — so it can never consume the prompt; a PTY row covers the extraction.
  • Fullscreen default documented (CHANGELOG.md, test/integration/rpc-host-shell.test.ts): Pi 1.x opens interactive sessions fullscreen, where the classic footer no longer draws; the changelog points at --tui-mode regular / "tuiMode": "regular" and the classic-footer boot test pins regular mode.
  • Version anchors refreshed (README.md, DEV_LOOP.md, RPC contract comments, integration expectations): pin text moves to 1.1.0 with no behavioral change.

I verified the load-bearing bump claims against the published packages rather than taking them on faith: dist/modes/rpc (including rpc-types.d.ts) is byte-identical between 0.99.1 and 1.1.0, dist/bun is identical with the Bedrock patch needle still matching exactly once, args.js adds only the boolean --no-mcp, tuiMode is the correct settings key, before_agent_start still chains result.systemPrompt, and the OSC 7501 reporter is imported only by interactive-mode.js so RPC stdout stays clean. CI at this head is green across typecheck + unit tests, pi-compat (supported matrix), integration tests (node-pty), and code-review. All prior review feedback is applied and resolved.

Pullfrog  | View workflow run | Using deepseek-flash | 𝕏

Comment thread install.sh Outdated
sumocode-pi-cli execs bin/sumocode-pi directly for --version and --no-extensions, so the installer checks it like the other two entry points. Per OpenCodeReview on #618.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

Reviewed the delta from 5a2c780 to 4baed371 — one new commit, fix(native): set SUMOCODE_APP_HOST only for the app-host exec — against the full 27-file diff.

  • App-host marker scoped to the app-host exec (src/native/sumocode-pi-cli.sh): export SUMOCODE_APP_HOST=1 moved from the top of the wrapper to immediately above the sumocode --no-sumo-tui exec, so the bare-Pi --version/-v and --no-extensions/-ne branches no longer carry a marker that nothing in those processes reads. This addresses the OCR maintainability note from the prior round; the new inline comment states the invariant.

I re-ran the wrapper against a stub archive to confirm the routing: --version/-v and --no-extensions exec sumocode-pi with SUMOCODE_APP_HOST unset, and every other argv reaches sumocode --no-sumo-tui with SUMOCODE_APP_HOST=1. sh -n is clean, and no consumer of APP_HOST_ENV changed.

Pullfrog  | View workflow run | Using deepseek-flash | 𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

Reviewed the delta from 4baed371 to bcca51e8 — one commit, fix(install): require an executable bin/sumocode-pi — against the full 27-file diff.

  • bin/sumocode-pi joins the installer's executability check (install.sh): the loop now covers all three shipped binaries, matching the -f required-file list, so a release where sumocode-pi exists but lost its exec bit fails at install with exit 65 instead of at the first --version/--no-extensions run. The earlier single bin/sumocode check is already gone, and no caller depended on the two-entry loop.

Pullfrog  | View workflow run | Using deepseek-flash | 𝕏

Comment thread src/app-host.ts Outdated
Comment thread src/extension-core.ts
roles.json prompts may span lines; continuation lines are now indented under their role bullet in the T3 guidance. Per OpenCodeReview on #618.
Comment thread src/interaction-registry.ts
Comment thread src/native/sumocode-pi-cli.sh

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

Reviewed the delta from bcca51e8 to 9b7763d2 — one commit, fix(app-host): keep multi-line role prompts inside their bullet — against the full 27-file diff.

  • Multi-line role prompts stay inside their bullet (src/app-host.ts): buildT3RoleGuidance now trims role.systemPrompt and re-indents every continuation line two spaces (replace(/\r?\n/g, "\n ")), so an operator prompt authored across multiple lines no longer lets the following role bullets visually merge into the previous prompt's text. Two spaces matches the - content column, and both \n and \r\n are covered.
  • Test coverage (src/app-host.test.ts): a new case feeds both line endings through one prompt and asserts the exact indented rendering, including that the bullet structure is preserved.

This addresses the OpenCodeReview maintainability note on src/app-host.ts:39; the author replied on that thread and it is resolved. CI=1 pnpm vitest run src/app-host.test.ts passes 7/7 locally, no prior pullfrog thread remains open, and the completed CI jobs at this head are green (typecheck + unit tests, pi-compat, resume p95 budget, visual-bible), with integration tests (node-pty) still running.

Pullfrog  | View workflow run | Using deepseek-flash | 𝕏

@dhruvkelawala
dhruvkelawala merged commit f14ddd3 into main Oct 12, 2026
10 of 12 checks passed
@dhruvkelawala
dhruvkelawala deleted the sumo/sumocode-pi-cli branch October 12, 2026 13:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant