Skip to content

feat(pi): ctx setup pi - Pi coding-agent CLI integration - #161

Open
bilersan wants to merge 8 commits into
ActiveMemory:mainfrom
bilersan:feat/pi-cli-integration
Open

feat(pi): ctx setup pi - Pi coding-agent CLI integration#161
bilersan wants to merge 8 commits into
ActiveMemory:mainfrom
bilersan:feat/pi-cli-integration

Conversation

@bilersan

Copy link
Copy Markdown
Contributor

feat(pi): ctx setup pi — Pi coding-agent CLI integration

New AI-tool integration: ctx setup pi [--write] for the Pi coding-agent CLI
(earendil-works/pi, pi.dev). Pi has no built-in MCP by design, so the
integration is a thin TypeScript extension + Agent-Skills-standard skills +
AGENTS.md; all logic stays in the ctx binary via ctx system subcommands.

Spec: specs/pi-cli-integration.md (committed on-branch).

What ships

  • Embedded extensioninternal/assets/integrations/pi/extension/ctx.ts:
    flat .pi/extensions/ctx.ts shim wiring Pi lifecycle events to ctx system:
    • session_start: warm-up ctx agent --budget 4000 off the prompt path
    • before_agent_start: injects the packet as a persistent
      customType: "ctx-context" message (display: true) only when no ctx
      message exists in the live context — compaction-aware scan of
      sessionManager.buildContextEntries() (summary + kept tail +
      post-compaction entries), so kept-tail packets suppress re-injection and
      folded-away packets trigger it; fail-safe across /new /resume /fork
      /reload
    • tool_result (bash, git commit regex, !isError): ctx system post-commit
      with the hook-JSON envelope on piped+closed stdin (node:child_process
      is mandatory — Pi's exec helper hardcodes stdio: ["ignore","pipe","pipe"])
    • tool_result (edit/write, !isError): check-task-completion;
      agent_settled: check-persistence; session_compact: cache drop
  • ctx setup pi — deploy core (internal/cli/setup/core/pi/) mirroring
    the OpenCode integration: extension fatal, AGENTS.md + 10 bundled skills
    warn; refresh-in-place, symlink/non-regular refusal; dry-run prints the
    hook.pi blueprint; case cfgHook.ToolPi in setup root (no new
    subcommand, no new Use* constant)
  • CI gatetools/typecheck/pi/ (strict tsc --noEmit against
    @earendil-works/pi-coding-agent@0.84.2 types, committed lockfile) +
    typecheck-pi-extension job in .github/workflows/ci.yml
  • Docs — Pi entry in supported-tools reference, docs/home/pi.md
    quickstart, multi-tool recipe, zensical nav

Validation

  • go build ./..., golangci-lint (0 issues), targeted go test green
  • Full-suite delta vs clean main: zero new failures (all failing packages
    pre-exist on this Windows machine: CRLF render drift, .exe exec, audit
    path exemptions)
  • Scratch project: init + dry-run + --write + idempotent re-run +
    tamper-refresh (byte-identical to embedded)
  • Live pi: extension loads clean (A/B run with/without .pi identical);
    full LLM round-trip blocked by local pi provider config — left for a
    working-provider machine
  • tsc --noEmit passes against pi-coding-agent 0.84.2 types

Reviews

  • Independent sub-agent review: approve-with-nits — all nits addressed
    (32c55041: docstring, frontmatter coverage, spec naming)
  • claude -p fable-5 effort-max branch audit: ship-ready after one
    decision
    — the one decision (kept-tail duplicate-injection gap, MAJOR 1)
    resolved by switching the predicate to a buildContextEntries() scan
    (694f6d37, with a one-line stdin stream hardening)

Notes / follow-ups

  • site/ HTML rebuild deferred: this machine's zensical toolchain renders
    entity-escape drift vs the committed artifacts; rebuild on the canonical
    build machine (documented in PI.5 / commit 03a7e776)
  • TASKS.md PI.8 tracks the remaining low-priority audit follow-ups
    (post-compaction re-warm location, embedded-asset EOL pinning, unused
    tool_result nudge channel, tsconfig paths hardening)

PI.1 of specs/pi-cli-integration.md: the thin shim extension (the
.pi/extensions/ctx.ts deploy source) wiring Pi lifecycle events to
ctx system subcommands - hook-JSON envelope on piped stdin, isError
gating, session_start warm-up cache, branch-scan context re-injection
after compaction - plus the 10-skill bundled set copied from the
OpenCode integration (frontmatter conforms to the Agent Skills
standard; no harness-specific content inside the skills).

Spec: specs/pi-cli-integration.md

Signed-off-by: Ersan Bilik <ersanbilik@gmail.com>
PI.2-PI.4 of specs/pi-cli-integration.md: the ctx setup pi surface.
internal/cli/setup/core/pi implements the deploy contract mirroring
the OpenCode integration (extension fatal, AGENTS.md + skills warn;
validateManagedTarget refuses symlink and non-regular targets; refresh-
in-place on drift):

- PI.2: PiExtension/PiSkills accessors (internal/assets/read/agent/pi.go),
  config/hook pi path constants (.pi/extensions/ctx.ts, .pi/skills),
  asset.go directory constants, embed.go directives.
- PI.3: core/pi package - pi.go Deploy (extension, AGENTS.md, skills,
  summary), extension.go, skill.go, validate.go, plus the deploy test
  suite (refresh, symlink refusal, non-regular target refusal;
  windows-skipped where needed).
- PI.4: case cfgHook.ToolPi in setup root Run() - dry-run prints the
  hook.pi blueprint, --write deploys; hooks.yaml hook.pi + supported-tools
  entry, write.yaml write.hook-pi-created/skipped/summary, config/embed/text
  DescKeys, write/setup InfoPi* (TestDescKeyYAMLLinkage green; no new Use*
  constant, no new subcommand).

Spec: specs/pi-cli-integration.md

Signed-off-by: Ersan Bilik <ersanbilik@gmail.com>
PI.5 of specs/pi-cli-integration.md: pi entries in the supported-tools
reference (operations/integrations.md + cli/setup.md), a pi quickstart
(docs/home/pi.md, registered in zensical.toml nav), and the
multi-tool-setup recipe.

site/ HTML rebuild is deferred: this machine's zensical 0.0.51 venv renders
entity-escape drift (120 files, &ActiveMemory#39; vs literal ') against the committed
artifacts - unpinned zensical transitive deps make the build
non-reproducible off the canonical toolchain. Rebuild on the canonical
machine and stage site/ with a follow-up commit.

Spec: specs/pi-cli-integration.md

Signed-off-by: Ersan Bilik <ersanbilik@gmail.com>
PI.7 of specs/pi-cli-integration.md: tools/typecheck/pi/ (tsconfig strict
noEmit over the embedded ctx.ts, devDeps on @earendil-works/pi-coding-agent
types + @types/node + typescript, committed lockfile, README) and the
typecheck-pi-extension CI job mirroring typecheck-opencode-plugin.
Verified locally: tsc --noEmit passes against pi-coding-agent 0.84.2.

Spec: specs/pi-cli-integration.md

Signed-off-by: Ersan Bilik <ersanbilik@gmail.com>
Validation summary: go build + golangci-lint clean; full-suite delta vs
clean main shows zero new failures (all failing packages pre-exist on
this Windows machine: CRLF render drift, .exe exec, audit path
exemptions). Scratch project verified: init, dry-run, --write,
idempotent re-run, tamper refresh (byte-identical to embedded source),
unknown-tool listing. Live pi: extension loads clean (A/B run with and
without .pi identical); LLM round-trip blocked by local pi provider
config - left for a working-provider machine.

Spec: specs/pi-cli-integration.md

Signed-off-by: Ersan Bilik <ersanbilik@gmail.com>
… rebuild drift)

Both surfaced during the pi integration: the Windows schannel/openssl
git TLS quirk and the non-reproducible zensical site rebuild (escape-
churn detection procedure).

Spec: specs/pi-cli-integration.md

Signed-off-by: Ersan Bilik <ersanbilik@gmail.com>
…naming

Independent review (approve-with-nits) follow-ups:
- setup root package doc: add opencode + pi to the tool list
  (spec 'Files to create' required the docstring update)
- TestSkillFrontmatter: add the pi skill tree so the Agent Skills
  frontmatter contract is validated for the pi set
- new deploy tests: fresh-project full deploy (all 12 files,
  byte-identical to embedded; AGENTS.md marker) and deterministic
  skill ordering (deploy output sequence must be lexicographic)
- spec: FilePiExtension -> FilePiExtensionDeploy (matches the shipped
  constant; the FileOpenCodePluginDeploy convention)
- read/agent/pi.go: document the deliberate file-split deviation from
  agent.go's layout

Spec: specs/pi-cli-integration.md

Signed-off-by: Ersan Bilik <ersanbilik@gmail.com>
fable-5 effort-max branch audit (0 blocker, 1 major, 4 minor, 3 nit):

- MAJOR 1: needsContextInjection scanned only branch entries after the last
  compaction, missing ctx packets that survive into the kept tail (a
  custom_message is a valid cut point, kept within keepRecentTokens) and
  causing the duplicate injection the spec explicitly rules out. Now scans
  sessionManager.buildContextEntries() - the compaction-aware live context
  (summary + kept tail + post-compaction entries); strictly smaller function,
  delivers the spec's no-duplicate guarantee. Spec updated to match (event
  map row, compaction interop paragraph, files-to-create comment).
- MINOR 2: child.stdin now swallows async 'error' emissions (EPIPE when the
  child exits before the write flushes, destroyed-stream writes on a failed
  spawn) so they cannot escape Pi's handler stack; spawn/exec failures still
  surface via the execFile callback.
- TASKS.md PI.8: follow-up for the remaining minor/nit findings (post-
  compaction inline re-warm, EOL pinning for embedded assets, unused
  tool_result nudge channel, tsconfig paths hardening). Audit NIT 6 (summary
  omits persistence behavior) was a false positive - all five behaviors are
  listed in write.hook-pi-summary.

Verified: tsc --noEmit (strict, pi-coding-agent 0.84.2 types), go build,
pi deploy suite + assets/read/skill green; remaining suite failures are
pre-existing on clean main.

Spec: specs/pi-cli-integration.md

Signed-off-by: Ersan Bilik <ersanbilik@gmail.com>
@bilersan
bilersan requested a review from josealekhine as a code owner August 23, 2026 19:31
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