raga-cli 0.0.0-stage → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +103 -0
- package/LICENSE +21 -0
- package/README.md +139 -2
- package/bundled-skills/AGENTS.md +5 -0
- package/bundled-skills/README.md +25 -0
- package/bundled-skills/agents/comment-sicko.json +9 -0
- package/bundled-skills/agents/comment-sicko.md +28 -0
- package/bundled-skills/agents/model-roles.json +41 -0
- package/bundled-skills/agents/poteto-agent.json +9 -0
- package/bundled-skills/agents/poteto-agent.md +4 -0
- package/bundled-skills/agents/worker.json +8 -0
- package/bundled-skills/agents/worker.md +1 -0
- package/bundled-skills/bundle.json +1448 -0
- package/bundled-skills/dependencies.json +40 -0
- package/bundled-skills/docs/guide/01-setup.md +3 -0
- package/bundled-skills/docs/guide/02-peak.md +135 -0
- package/bundled-skills/docs/guide/03-understand.md +79 -0
- package/bundled-skills/docs/guide/04-design.md +133 -0
- package/bundled-skills/docs/guide/05-build-and-clean.md +83 -0
- package/bundled-skills/docs/guide/06-verify-and-ship.md +166 -0
- package/bundled-skills/docs/guide/07-overnight.md +118 -0
- package/bundled-skills/docs/guide/08-principles.md +72 -0
- package/bundled-skills/docs/guide/09-make-it-yours.md +96 -0
- package/bundled-skills/docs/guide/10-recipes-and-pitfalls.md +180 -0
- package/bundled-skills/docs/guide/README.md +38 -0
- package/bundled-skills/docs/guide/images/design.jpg +0 -0
- package/bundled-skills/docs/guide/images/overnight.jpg +0 -0
- package/bundled-skills/docs/guide/images/recipes.jpg +0 -0
- package/bundled-skills/docs/guide/images/router.jpg +0 -0
- package/bundled-skills/docs/guide/images/understanding.jpg +0 -0
- package/bundled-skills/docs/guide/images/verification.jpg +0 -0
- package/bundled-skills/licenses/commander +22 -0
- package/bundled-skills/licenses/cursor-team-kit +21 -0
- package/bundled-skills/licenses/no-mistakes +21 -0
- package/bundled-skills/licenses/pstack +21 -0
- package/bundled-skills/skills/peak/SKILL.md +184 -0
- package/bundled-skills/skills/peak/playbooks/authoring-a-skill.md +12 -0
- package/bundled-skills/skills/peak/playbooks/autonomous-run.md +13 -0
- package/bundled-skills/skills/peak/playbooks/autopilot-full.md +25 -0
- package/bundled-skills/skills/peak/playbooks/autopilot-stack.md +12 -0
- package/bundled-skills/skills/peak/playbooks/babysit.md +18 -0
- package/bundled-skills/skills/peak/playbooks/bug-fix.md +15 -0
- package/bundled-skills/skills/peak/playbooks/eval.md +25 -0
- package/bundled-skills/skills/peak/playbooks/feature.md +21 -0
- package/bundled-skills/skills/peak/playbooks/hillclimb.md +21 -0
- package/bundled-skills/skills/peak/playbooks/investigation.md +14 -0
- package/bundled-skills/skills/peak/playbooks/multi-phase-plan.md +155 -0
- package/bundled-skills/skills/peak/playbooks/opening-a-pr.md +34 -0
- package/bundled-skills/skills/peak/playbooks/orchestrate.md +112 -0
- package/bundled-skills/skills/peak/playbooks/pause-safely.md +10 -0
- package/bundled-skills/skills/peak/playbooks/perf-issue.md +25 -0
- package/bundled-skills/skills/peak/playbooks/prototype.md +14 -0
- package/bundled-skills/skills/peak/playbooks/refactoring.md +16 -0
- package/bundled-skills/skills/peak/playbooks/runtime-forensics.md +11 -0
- package/bundled-skills/skills/peak/playbooks/session-pickup.md +11 -0
- package/bundled-skills/skills/peak/playbooks/shipping.md +12 -0
- package/bundled-skills/skills/peak/playbooks/trace-forensics.md +14 -0
- package/bundled-skills/skills/peak/playbooks/visual-parity.md +11 -0
- package/bundled-skills/skills/peak/playbooks/worktree-cleanup.md +6 -0
- package/bundled-skills/skills/peak/references/architect/SKILL.md +81 -0
- package/bundled-skills/skills/peak/references/architect/references/design-red-flags.md +57 -0
- package/bundled-skills/skills/peak/references/architect/references/rationale-template.md +35 -0
- package/bundled-skills/skills/peak/references/architect/references/runner-prompt.md +20 -0
- package/bundled-skills/skills/peak/references/arena/SKILL.md +50 -0
- package/bundled-skills/skills/peak/references/automate-me/SKILL.md +106 -0
- package/bundled-skills/skills/peak/references/benchmark-checklist/SKILL.md +41 -0
- package/bundled-skills/skills/peak/references/blast-radius/SKILL.md +52 -0
- package/bundled-skills/skills/peak/references/bro/SKILL.md +9 -0
- package/bundled-skills/skills/peak/references/control-cli/SKILL.md +111 -0
- package/bundled-skills/skills/peak/references/control-ui/SKILL.md +111 -0
- package/bundled-skills/skills/peak/references/correct/SKILL.md +34 -0
- package/bundled-skills/skills/peak/references/create-formal-verification-skill/SKILL.md +43 -0
- package/bundled-skills/skills/peak/references/create-skill/SKILL.md +14 -0
- package/bundled-skills/skills/peak/references/create-verification-skill/SKILL.md +46 -0
- package/bundled-skills/skills/peak/references/create-verification-skill/references/feature-map-example/README.md +47 -0
- package/bundled-skills/skills/peak/references/create-verification-skill/references/feature-map-example/create-note.md +39 -0
- package/bundled-skills/skills/peak/references/create-verification-skill/references/feature-map-example/search.md +45 -0
- package/bundled-skills/skills/peak/references/deslop/SKILL.md +24 -0
- package/bundled-skills/skills/peak/references/figure-it-out/SKILL.md +54 -0
- package/bundled-skills/skills/peak/references/how/SKILL.md +38 -0
- package/bundled-skills/skills/peak/references/how/references/explainer-prompt.md +55 -0
- package/bundled-skills/skills/peak/references/how/references/explorer-prompt.md +35 -0
- package/bundled-skills/skills/peak/references/in-your-own-words/SKILL.md +9 -0
- package/bundled-skills/skills/peak/references/interrogate/SKILL.md +76 -0
- package/bundled-skills/skills/peak/references/interrogate/references/code-quality-review.md +47 -0
- package/bundled-skills/skills/peak/references/interrogate/references/lead-judgment.md +39 -0
- package/bundled-skills/skills/peak/references/interrogate/references/reviewer-prompt.md +62 -0
- package/bundled-skills/skills/peak/references/interrogate/references/rubric.md +77 -0
- package/bundled-skills/skills/peak/references/ketchup/SKILL.md +45 -0
- package/bundled-skills/skills/peak/references/maintain-formal-verification-skill/SKILL.md +60 -0
- package/bundled-skills/skills/peak/references/maintain-verification-skill/SKILL.md +41 -0
- package/bundled-skills/skills/peak/references/no-comments/SKILL.md +26 -0
- package/bundled-skills/skills/peak/references/no-mistakes/SKILL.md +20 -0
- package/bundled-skills/skills/peak/references/no-mistakes/upstream/SKILL.md +394 -0
- package/bundled-skills/skills/peak/references/peak-setup/SKILL.md +18 -0
- package/bundled-skills/skills/peak/references/poteto-help/SKILL.md +16 -0
- package/bundled-skills/skills/peak/references/poteto-help/references/prompting.md +51 -0
- package/bundled-skills/skills/peak/references/poteto-help/references/recipes.md +51 -0
- package/bundled-skills/skills/peak/references/principle-attack-the-premise/SKILL.md +23 -0
- package/bundled-skills/skills/peak/references/principle-boundary-discipline/SKILL.md +36 -0
- package/bundled-skills/skills/peak/references/principle-build-the-lever/SKILL.md +25 -0
- package/bundled-skills/skills/peak/references/principle-encode-lessons-in-structure/SKILL.md +13 -0
- package/bundled-skills/skills/peak/references/principle-exhaust-the-design-space/SKILL.md +11 -0
- package/bundled-skills/skills/peak/references/principle-experience-first/SKILL.md +21 -0
- package/bundled-skills/skills/peak/references/principle-explain-the-number/SKILL.md +19 -0
- package/bundled-skills/skills/peak/references/principle-fix-root-causes/SKILL.md +23 -0
- package/bundled-skills/skills/peak/references/principle-foundational-thinking/SKILL.md +23 -0
- package/bundled-skills/skills/peak/references/principle-guard-the-context-window/SKILL.md +14 -0
- package/bundled-skills/skills/peak/references/principle-laziness-protocol/SKILL.md +12 -0
- package/bundled-skills/skills/peak/references/principle-make-operations-idempotent/SKILL.md +24 -0
- package/bundled-skills/skills/peak/references/principle-migrate-callers-then-delete-legacy-apis/SKILL.md +16 -0
- package/bundled-skills/skills/peak/references/principle-minimize-reader-load/SKILL.md +20 -0
- package/bundled-skills/skills/peak/references/principle-model-the-domain/SKILL.md +26 -0
- package/bundled-skills/skills/peak/references/principle-never-block-on-the-human/SKILL.md +17 -0
- package/bundled-skills/skills/peak/references/principle-outcome-oriented-execution/SKILL.md +23 -0
- package/bundled-skills/skills/peak/references/principle-prove-it-works/SKILL.md +24 -0
- package/bundled-skills/skills/peak/references/principle-redesign-from-first-principles/SKILL.md +18 -0
- package/bundled-skills/skills/peak/references/principle-separate-before-serializing-shared-state/SKILL.md +18 -0
- package/bundled-skills/skills/peak/references/principle-sequence-verifiable-units/SKILL.md +19 -0
- package/bundled-skills/skills/peak/references/principle-subtract-before-you-add/SKILL.md +20 -0
- package/bundled-skills/skills/peak/references/principle-test-behavior-not-implementation/SKILL.md +22 -0
- package/bundled-skills/skills/peak/references/principle-type-system-discipline/SKILL.md +15 -0
- package/bundled-skills/skills/peak/references/raga-runtime/SKILL.md +37 -0
- package/bundled-skills/skills/peak/references/raga-runtime/managed-tools.mjs +34 -0
- package/bundled-skills/skills/peak/references/raga-runtime/raga_runtime.py +44 -0
- package/bundled-skills/skills/peak/references/recall/SKILL.md +37 -0
- package/bundled-skills/skills/peak/references/reflect/SKILL.md +63 -0
- package/bundled-skills/skills/peak/references/reflect/references/divergent-reviewer.md +38 -0
- package/bundled-skills/skills/peak/references/reflect/references/judgment-reviewer.md +37 -0
- package/bundled-skills/skills/peak/references/reflect/references/synthesizer.md +56 -0
- package/bundled-skills/skills/peak/references/reflect/references/tooling-reviewer.md +48 -0
- package/bundled-skills/skills/peak/references/reviewer-triage.md +142 -0
- package/bundled-skills/skills/peak/references/sharpen/SKILL.md +18 -0
- package/bundled-skills/skills/peak/references/show-me-your-work/SKILL.md +84 -0
- package/bundled-skills/skills/peak/references/show-me-your-work/references/decision-log-template.tsv +1 -0
- package/bundled-skills/skills/peak/references/show-me-your-work/scripts/log.sh +42 -0
- package/bundled-skills/skills/peak/references/statechart/SKILL.md +38 -0
- package/bundled-skills/skills/peak/references/statechart/scripts/chart-to-tla.mjs +236 -0
- package/bundled-skills/skills/peak/references/statechart/scripts/compare-charts.mjs +104 -0
- package/bundled-skills/skills/peak/references/statechart/scripts/lib.mjs +725 -0
- package/bundled-skills/skills/peak/references/statechart/scripts/model/OutputFolder.cfg +6 -0
- package/bundled-skills/skills/peak/references/statechart/scripts/model/OutputFolder.map.mjs +106 -0
- package/bundled-skills/skills/peak/references/statechart/scripts/model/OutputFolder.tla +176 -0
- package/bundled-skills/skills/peak/references/statechart/scripts/statechart.mjs +749 -0
- package/bundled-skills/skills/peak/references/statechart/scripts/test/statechart.test.mjs +2790 -0
- package/bundled-skills/skills/peak/references/statechart/scripts/test/sync.mmd +19 -0
- package/bundled-skills/skills/peak/references/statechart/scripts/test/upload.mmd +16 -0
- package/bundled-skills/skills/peak/references/statechart/scripts/tlc-to-chart.mjs +1347 -0
- package/bundled-skills/skills/peak/references/swarm/SKILL.md +43 -0
- package/bundled-skills/skills/peak/references/tdd/SKILL.md +44 -0
- package/bundled-skills/skills/peak/references/teach/SKILL.md +23 -0
- package/bundled-skills/skills/peak/references/technical-writing/SKILL.md +108 -0
- package/bundled-skills/skills/peak/references/typescript-best-practices/SKILL.md +33 -0
- package/bundled-skills/skills/peak/references/typescript-best-practices/references/patterns.md +328 -0
- package/bundled-skills/skills/peak/references/unslop/SKILL.md +64 -0
- package/bundled-skills/skills/peak/references/verify-this/SKILL.md +76 -0
- package/bundled-skills/skills/peak/references/why/SKILL.md +100 -0
- package/bundled-skills/skills/peak/references/why/references/epistemics.md +71 -0
- package/bundled-skills/skills/peak/references/why/references/investigator-prompt.md +84 -0
- package/bundled-skills/skills/peak/references/why/references/source-playbook.md +17 -0
- package/bundled-skills/skills/peak/references/why/references/sources/code-archaeology.md +51 -0
- package/bundled-skills/skills/peak/references/why/references/sources/databricks.md +70 -0
- package/bundled-skills/skills/peak/references/why/references/sources/datadog.md +97 -0
- package/bundled-skills/skills/peak/references/why/references/sources/incident-postmortem.md +5 -0
- package/bundled-skills/skills/peak/references/why/references/sources/linear.md +48 -0
- package/bundled-skills/skills/peak/references/why/references/sources/notion.md +55 -0
- package/bundled-skills/skills/peak/references/why/references/sources/sentry.md +66 -0
- package/bundled-skills/skills/peak/references/why/references/sources/slack.md +17 -0
- package/bundled-skills/skills/peak/references/why/references/synthesizer-prompt.md +129 -0
- package/bundled-skills/skills/peak/scripts/check-plan.mjs +205 -0
- package/bundled-skills/skills/peak/scripts/check-plan.test.ts +96 -0
- package/bundled-skills/skills/peak/scripts/orch/orch.test.ts +761 -0
- package/bundled-skills/skills/peak/scripts/orch/orch.ts +588 -0
- package/bundled-skills/skills/peak/scripts/orch/store.ts +1676 -0
- package/bundled-skills/skills/peak/scripts/vendor/commander/LICENSE +22 -0
- package/bundled-skills/skills/peak/scripts/vendor/commander/esm.mjs +16 -0
- package/bundled-skills/skills/peak/scripts/vendor/commander/index.js +24 -0
- package/bundled-skills/skills/peak/scripts/vendor/commander/lib/argument.js +149 -0
- package/bundled-skills/skills/peak/scripts/vendor/commander/lib/command.js +2778 -0
- package/bundled-skills/skills/peak/scripts/vendor/commander/lib/error.js +39 -0
- package/bundled-skills/skills/peak/scripts/vendor/commander/lib/help.js +747 -0
- package/bundled-skills/skills/peak/scripts/vendor/commander/lib/option.js +379 -0
- package/bundled-skills/skills/peak/scripts/vendor/commander/lib/suggestSimilar.js +101 -0
- package/bundled-skills/skills/peak/scripts/vendor/commander/package.json +1 -0
- package/bundled-skills/skills/peak/scripts/vendor/commander/typings/esm.d.mts +3 -0
- package/bundled-skills/skills/peak/scripts/vendor/commander/typings/index.d.ts +1113 -0
- package/bundled-skills/skills/peak/scripts/watch-pr/cli.test.ts +224 -0
- package/bundled-skills/skills/peak/scripts/watch-pr/cli.ts +223 -0
- package/bundled-skills/skills/peak/scripts/watch-pr/fakes.test-helper.ts +129 -0
- package/bundled-skills/skills/peak/scripts/watch-pr/github.test.ts +436 -0
- package/bundled-skills/skills/peak/scripts/watch-pr/github.ts +718 -0
- package/bundled-skills/skills/peak/scripts/watch-pr/policy.test.ts +420 -0
- package/bundled-skills/skills/peak/scripts/watch-pr/policy.ts +836 -0
- package/bundled-skills/skills/peak/scripts/watch-pr/render.ts +169 -0
- package/bundled-skills/skills/peak/scripts/watch-pr/tsconfig.json +13 -0
- package/bundled-skills/skills/peak/scripts/watch-pr/types.compile.ts +93 -0
- package/bundled-skills/skills/peak/scripts/watch-pr/types.ts +413 -0
- package/bundled-skills/skills/peak/scripts/watch-pr/watch-pr +4 -0
- package/bundled-skills/skills/peak/scripts/worktree-audit.sh +4 -0
- package/dist/bundle/chunks/anthropic-messages-BMDYDGHW.js +6 -0
- package/dist/bundle/chunks/anthropic.js +75 -0
- package/dist/bundle/chunks/azure-openai-responses-Q7EZTEHK.js +2 -0
- package/dist/bundle/chunks/bedrock-converse-stream.js +86 -0
- package/dist/bundle/chunks/chunk-3EGDWOKT.js +2 -0
- package/dist/bundle/chunks/chunk-3V45WARH.js +7 -0
- package/dist/bundle/chunks/chunk-5AGIVGSV.js +6 -0
- package/dist/bundle/chunks/chunk-6QGV3IWD.js +6 -0
- package/dist/bundle/chunks/chunk-7CBJINYJ.js +20 -0
- package/dist/bundle/chunks/chunk-7DDKXS2Q.js +2 -0
- package/dist/bundle/chunks/chunk-7ZC4UXSL.js +2 -0
- package/dist/bundle/chunks/chunk-AI2NMHE7.js +1567 -0
- package/dist/bundle/chunks/chunk-C4IJNE7U.js +2 -0
- package/dist/bundle/chunks/chunk-CF5GWZHW.js +31 -0
- package/dist/bundle/chunks/chunk-G54UBZTF.js +44 -0
- package/dist/bundle/chunks/chunk-H76KZMOI.js +2 -0
- package/dist/bundle/chunks/chunk-IOPE2TJ4.js +131 -0
- package/dist/bundle/chunks/chunk-IXDQLPKS.js +11 -0
- package/dist/bundle/chunks/chunk-J22MF7YW.js +64 -0
- package/dist/bundle/chunks/chunk-JLV25LHE.js +2 -0
- package/dist/bundle/chunks/chunk-JXWJOIH4.js +2 -0
- package/dist/bundle/chunks/chunk-KNY3PXQI.js +2 -0
- package/dist/bundle/chunks/chunk-L2ZPNLYD.js +2 -0
- package/dist/bundle/chunks/chunk-LPXNMA2W.js +2 -0
- package/dist/bundle/chunks/chunk-LVVZS2NO.js +12 -0
- package/dist/bundle/chunks/chunk-LX24DVQ5.js +2 -0
- package/dist/bundle/chunks/chunk-P2QCWBFM.js +9 -0
- package/dist/bundle/chunks/chunk-P7FPUEYA.js +2 -0
- package/dist/bundle/chunks/chunk-PGXDEOVV.js +2 -0
- package/dist/bundle/chunks/chunk-PJACZCIR.js +2 -0
- package/dist/bundle/chunks/chunk-PMRZO46Y.js +2 -0
- package/dist/bundle/chunks/chunk-PRRNXB7S.js +2 -0
- package/dist/bundle/chunks/chunk-Q4U25BSY.js +2 -0
- package/dist/bundle/chunks/chunk-RDZVAGPR.js +2 -0
- package/dist/bundle/chunks/chunk-RFPFZTK2.js +7 -0
- package/dist/bundle/chunks/chunk-RP2WKNT7.js +4 -0
- package/dist/bundle/chunks/chunk-TEPMHNKQ.js +2 -0
- package/dist/bundle/chunks/chunk-TMTOQ7H7.js +2 -0
- package/dist/bundle/chunks/chunk-UDT647VB.js +82 -0
- package/dist/bundle/chunks/chunk-UKVNB6C4.js +2 -0
- package/dist/bundle/chunks/chunk-USJZMAIR.js +2 -0
- package/dist/bundle/chunks/chunk-UTB4DTYQ.js +2 -0
- package/dist/bundle/chunks/chunk-WJGLPWUE.js +16 -0
- package/dist/bundle/chunks/chunk-YMZUNB25.js +2 -0
- package/dist/bundle/chunks/cli-4P6FVVLT.js +51 -0
- package/dist/bundle/chunks/cloudflare-workers-ai-system-one-S6CT2FXS.js +2 -0
- package/dist/bundle/chunks/codemode-worker.js +478 -0
- package/dist/bundle/chunks/easter-egg-3d-65VIC4G2.js +2 -0
- package/dist/bundle/chunks/execute-3H5WKMA3.js +505 -0
- package/dist/bundle/chunks/github-copilot.js +2 -0
- package/dist/bundle/chunks/google-generative-ai-35NZKG6S.js +2 -0
- package/dist/bundle/chunks/google-vertex-P33AHYYX.js +2 -0
- package/dist/bundle/chunks/https-proxy-agent-LVOO5TPL.js +13 -0
- package/dist/bundle/chunks/image-resize-worker.js +2 -0
- package/dist/bundle/chunks/jiti-loader-GL4HJFAD.js +21 -0
- package/dist/bundle/chunks/jiti-static-loader-2RCDI6B4.js +2 -0
- package/dist/bundle/chunks/kimi-coding.js +2 -0
- package/dist/bundle/chunks/lib-4AVRLBHM.js +9 -0
- package/dist/bundle/chunks/llama-cpp-classify-U4EH6TAM.js +22 -0
- package/dist/bundle/chunks/meta.js +2 -0
- package/dist/bundle/chunks/mistral-conversations-J62DPS2P.js +5 -0
- package/dist/bundle/chunks/multipart-parser-FMGQ7342.js +3 -0
- package/dist/bundle/chunks/node-AUOGOBCN.js +2 -0
- package/dist/bundle/chunks/node-KCMANYC2.js +16 -0
- package/dist/bundle/chunks/openai-chatgpt.js +75 -0
- package/dist/bundle/chunks/openai-codex-responses-4HXATL2M.js +10 -0
- package/dist/bundle/chunks/openai-codex.js +75 -0
- package/dist/bundle/chunks/openai-completions-75YYY35N.js +7 -0
- package/dist/bundle/chunks/openai-decisions-HEBEVGA2.js +5 -0
- package/dist/bundle/chunks/openai-responses-UWNAKTBV.js +4 -0
- package/dist/bundle/chunks/openrouter-images-HVOPXKHS.js +2 -0
- package/dist/bundle/chunks/openrouter.js +75 -0
- package/dist/bundle/chunks/pi-messages-DG7CALOV.js +8 -0
- package/dist/bundle/chunks/radius.js +75 -0
- package/dist/bundle/chunks/runtime-435R6IKY.js +2 -0
- package/dist/bundle/chunks/src-QKGKDFSU.js +4 -0
- package/dist/bundle/chunks/typesafe-system-one-24HEGHNN.js +2 -0
- package/dist/bundle/chunks/virtual-modules-U3JBUDP7.js +2 -0
- package/dist/bundle/chunks/xai.js +2 -0
- package/dist/bundle/cli-runtime.js +3 -0
- package/dist/bundle/cli.js +5 -0
- package/dist/bundle/index.js +2 -0
- package/dist/bundle/raga-runtime.js +3 -0
- package/dist/bundle/raga.js +5 -0
- package/dist/bundle/rpc-entry.js +3 -0
- package/dist/core/export-html/template.css +1085 -0
- package/dist/core/export-html/template.html +56 -0
- package/dist/core/export-html/template.js +2044 -0
- package/dist/core/export-html/vendor/highlight.min.js +1213 -0
- package/dist/core/export-html/vendor/marked-cjk-friendly.min.js +6 -0
- package/dist/core/export-html/vendor/marked.min.js +79 -0
- package/dist/modes/interactive/assets/clankolas.png +0 -0
- package/dist/modes/interactive/theme/dark.json +78 -0
- package/dist/modes/interactive/theme/light.json +78 -0
- package/docs/cli-integration.md +106 -0
- package/docs/cli.md +337 -0
- package/docs/codemode.md +230 -0
- package/docs/compaction.md +463 -0
- package/docs/configuration.md +62 -0
- package/docs/containerization.md +183 -0
- package/docs/custom-provider.md +227 -0
- package/docs/docs.json +220 -0
- package/docs/environment-variables.md +101 -0
- package/docs/extensions.md +400 -0
- package/docs/how-pi-works.md +49 -0
- package/docs/images/doom-extension.png +0 -0
- package/docs/images/exy.png +0 -0
- package/docs/images/interactive-mode.png +0 -0
- package/docs/images/tree-view.png +0 -0
- package/docs/index.md +39 -0
- package/docs/json.md +226 -0
- package/docs/keybindings.md +195 -0
- package/docs/llama-cpp.md +121 -0
- package/docs/mcp.md +272 -0
- package/docs/message-types.md +279 -0
- package/docs/models-configuration.md +196 -0
- package/docs/models.md +225 -0
- package/docs/nvidia-rtx-llama-cpp.md +96 -0
- package/docs/packages.md +129 -0
- package/docs/prompt-templates.md +59 -0
- package/docs/providers.md +247 -0
- package/docs/quickstart.md +136 -0
- package/docs/rpc-commands.md +860 -0
- package/docs/rpc-extension-ui.md +200 -0
- package/docs/rpc.md +193 -0
- package/docs/sdk.md +148 -0
- package/docs/security.md +99 -0
- package/docs/session-format.md +293 -0
- package/docs/sessions.md +66 -0
- package/docs/settings.md +184 -0
- package/docs/shell-aliases.md +93 -0
- package/docs/skills.md +93 -0
- package/docs/slash-commands.md +61 -0
- package/docs/terminal-setup.md +233 -0
- package/docs/termux.md +117 -0
- package/docs/themes.md +138 -0
- package/docs/tmux.md +55 -0
- package/docs/tui.md +195 -0
- package/docs/usage.md +94 -0
- package/docs/virtual-models.md +114 -0
- package/docs/windows.md +81 -0
- package/examples/README.md +36 -0
- package/examples/extensions/README.md +214 -0
- package/examples/extensions/auto-commit-on-exit.ts +49 -0
- package/examples/extensions/bash-spawn-hook.ts +30 -0
- package/examples/extensions/bookmark.ts +50 -0
- package/examples/extensions/border-status-editor.ts +150 -0
- package/examples/extensions/built-in-tool-renderer.ts +225 -0
- package/examples/extensions/claude-rules.ts +86 -0
- package/examples/extensions/commands.ts +72 -0
- package/examples/extensions/confirm-destructive.ts +59 -0
- package/examples/extensions/custom-compaction.ts +117 -0
- package/examples/extensions/custom-footer.ts +64 -0
- package/examples/extensions/custom-header.ts +73 -0
- package/examples/extensions/custom-provider-anthropic/index.ts +617 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
- package/examples/extensions/custom-provider-anthropic/package.json +19 -0
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +405 -0
- package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
- package/examples/extensions/custom-provider-gitlab-duo/test.ts +82 -0
- package/examples/extensions/debug-provider.ts +90 -0
- package/examples/extensions/dirty-repo-guard.ts +56 -0
- package/examples/extensions/doom-overlay/README.md +46 -0
- package/examples/extensions/doom-overlay/doom/build/doom.js +21 -0
- package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
- package/examples/extensions/doom-overlay/doom/build.sh +152 -0
- package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
- package/examples/extensions/doom-overlay/doom-component.ts +132 -0
- package/examples/extensions/doom-overlay/doom-engine.ts +173 -0
- package/examples/extensions/doom-overlay/doom-keys.ts +104 -0
- package/examples/extensions/doom-overlay/index.ts +74 -0
- package/examples/extensions/doom-overlay/wad-finder.ts +55 -0
- package/examples/extensions/dynamic-resources/SKILL.md +8 -0
- package/examples/extensions/dynamic-resources/dynamic.json +81 -0
- package/examples/extensions/dynamic-resources/dynamic.md +5 -0
- package/examples/extensions/dynamic-resources/index.ts +15 -0
- package/examples/extensions/dynamic-tools.ts +74 -0
- package/examples/extensions/entry-renderer.ts +41 -0
- package/examples/extensions/event-bus.ts +43 -0
- package/examples/extensions/file-trigger.ts +41 -0
- package/examples/extensions/git-checkpoint.ts +53 -0
- package/examples/extensions/git-merge-and-resolve.ts +115 -0
- package/examples/extensions/github-issue-autocomplete.ts +185 -0
- package/examples/extensions/gondolin/index.ts +531 -0
- package/examples/extensions/gondolin/package-lock.json +175 -0
- package/examples/extensions/gondolin/package.json +19 -0
- package/examples/extensions/handoff.ts +190 -0
- package/examples/extensions/hello.ts +26 -0
- package/examples/extensions/hidden-thinking-label.ts +53 -0
- package/examples/extensions/inline-bash.ts +94 -0
- package/examples/extensions/input-transform-streaming.ts +39 -0
- package/examples/extensions/input-transform.ts +43 -0
- package/examples/extensions/interactive-shell.ts +196 -0
- package/examples/extensions/jev-router.ts +113 -0
- package/examples/extensions/mac-system-theme.ts +47 -0
- package/examples/extensions/message-renderer.ts +59 -0
- package/examples/extensions/minimal-mode.ts +353 -0
- package/examples/extensions/modal-editor.ts +85 -0
- package/examples/extensions/model-status.ts +31 -0
- package/examples/extensions/notify.ts +57 -0
- package/examples/extensions/overlay-qa-tests.ts +1450 -0
- package/examples/extensions/overlay-test.ts +153 -0
- package/examples/extensions/permission-gate.ts +34 -0
- package/examples/extensions/pirate.ts +47 -0
- package/examples/extensions/plan-mode/README.md +66 -0
- package/examples/extensions/plan-mode/index.ts +394 -0
- package/examples/extensions/plan-mode/utils.ts +168 -0
- package/examples/extensions/preset.ts +436 -0
- package/examples/extensions/project-trust.ts +64 -0
- package/examples/extensions/prompt-customizer.ts +49 -0
- package/examples/extensions/protected-paths.ts +30 -0
- package/examples/extensions/provider-payload.ts +18 -0
- package/examples/extensions/qna.ts +118 -0
- package/examples/extensions/question.ts +286 -0
- package/examples/extensions/questionnaire.ts +448 -0
- package/examples/extensions/rainbow-editor.ts +88 -0
- package/examples/extensions/reload-runtime.ts +37 -0
- package/examples/extensions/rpc-demo.ts +118 -0
- package/examples/extensions/sandbox/index.ts +326 -0
- package/examples/extensions/sandbox/package-lock.json +92 -0
- package/examples/extensions/sandbox/package.json +19 -0
- package/examples/extensions/send-user-message.ts +97 -0
- package/examples/extensions/session-name.ts +27 -0
- package/examples/extensions/shutdown-command.ts +63 -0
- package/examples/extensions/snake.ts +343 -0
- package/examples/extensions/space-invaders.ts +560 -0
- package/examples/extensions/ssh.ts +220 -0
- package/examples/extensions/status-line.ts +32 -0
- package/examples/extensions/structured-output.ts +65 -0
- package/examples/extensions/subagent/README.md +177 -0
- package/examples/extensions/subagent/agents/planner.md +37 -0
- package/examples/extensions/subagent/agents/reviewer.md +35 -0
- package/examples/extensions/subagent/agents/scout.md +50 -0
- package/examples/extensions/subagent/agents/worker.md +24 -0
- package/examples/extensions/subagent/agents.ts +157 -0
- package/examples/extensions/subagent/index.ts +1038 -0
- package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
- package/examples/extensions/subagent/prompts/implement.md +10 -0
- package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
- package/examples/extensions/summarize.ts +199 -0
- package/examples/extensions/system-prompt-header.ts +17 -0
- package/examples/extensions/tic-tac-toe.ts +1008 -0
- package/examples/extensions/timed-confirm.ts +70 -0
- package/examples/extensions/titlebar-spinner.ts +58 -0
- package/examples/extensions/todo.ts +297 -0
- package/examples/extensions/tool-override.ts +144 -0
- package/examples/extensions/tools.ts +146 -0
- package/examples/extensions/trigger-compact.ts +50 -0
- package/examples/extensions/truncated-tool.ts +195 -0
- package/examples/extensions/widget-placement.ts +9 -0
- package/examples/extensions/with-deps/index.ts +32 -0
- package/examples/extensions/with-deps/package-lock.json +31 -0
- package/examples/extensions/with-deps/package.json +22 -0
- package/examples/extensions/working-indicator.ts +123 -0
- package/examples/extensions/working-message-test.ts +25 -0
- package/examples/rpc-client.ts +35 -0
- package/examples/rpc-extension-ui.ts +661 -0
- package/examples/sdk/01-minimal.ts +26 -0
- package/examples/sdk/02-custom-model.ts +49 -0
- package/examples/sdk/03-custom-prompt.ts +75 -0
- package/examples/sdk/04-skills.ts +55 -0
- package/examples/sdk/05-tools.ts +48 -0
- package/examples/sdk/06-extensions.ts +99 -0
- package/examples/sdk/07-context-files.ts +47 -0
- package/examples/sdk/08-prompt-templates.ts +51 -0
- package/examples/sdk/09-api-keys-and-oauth.ts +34 -0
- package/examples/sdk/10-settings.ts +53 -0
- package/examples/sdk/11-sessions.ts +52 -0
- package/examples/sdk/12-full-control.ts +74 -0
- package/examples/sdk/13-session-runtime.ts +67 -0
- package/examples/sdk/14-codemode-mcp.ts +61 -0
- package/examples/sdk/README.md +141 -0
- package/package.json +21 -5
- package/python/raga_rlm/__init__.py +336 -0
- package/python/raga_rlm/repl.py +920 -0
- package/schemas/keybindings.schema.json +393 -0
- package/schemas/models.schema.json +1211 -0
- package/schemas/settings.schema.json +815 -0
- package/schemas/theme.schema.json +365 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jev router - a virtual model that plans on a strong model and implements on a cheap one.
|
|
3
|
+
*
|
|
4
|
+
* Registers `jev/auto`, which routes between three OpenAI Codex models:
|
|
5
|
+
*
|
|
6
|
+
* - Planning: GPT-5.6 Sol for complex work, GPT-5.6 Terra otherwise. The Jev classifier rates the
|
|
7
|
+
* first user message; planning stays on the chosen model.
|
|
8
|
+
* - Implementation: GPT-5.6 Luna.
|
|
9
|
+
*
|
|
10
|
+
* The planning model explores, plans, and makes the first edit. After the first successful `edit`
|
|
11
|
+
* or `write` tool call, the next request of the same turn goes to Luna, and the session stays
|
|
12
|
+
* there. A session therefore switches models once and accepts a single prompt-cache miss.
|
|
13
|
+
*
|
|
14
|
+
* The phase is router state: Pi stores it on the session branch, so it follows the session tree
|
|
15
|
+
* and survives compaction. The selected thinking level passes through as the reasoning effort of
|
|
16
|
+
* the chosen model. Requests outside the agent loop, such as compaction summaries, go to Luna.
|
|
17
|
+
*
|
|
18
|
+
* Requires TypeSafe credentials (TYPESAFE_API_KEY) and an OpenAI Codex login.
|
|
19
|
+
* Usage: pi -e ./jev-router.ts --model jev/auto
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import type { Message } from "@earendil-works/pi-ai";
|
|
23
|
+
import type { ExtensionAPI, ExtensionContext, ModelRoute, ModelRouteRequest } from "@earendil-works/pi-coding-agent";
|
|
24
|
+
|
|
25
|
+
const PROVIDER = "openai-codex";
|
|
26
|
+
const SOL = "gpt-5.6-sol";
|
|
27
|
+
const TERRA = "gpt-5.6-terra";
|
|
28
|
+
const LUNA = "gpt-5.6-luna";
|
|
29
|
+
|
|
30
|
+
/** Tools whose successful result means implementation has started. */
|
|
31
|
+
const EDIT_TOOLS = new Set(["edit", "write"]);
|
|
32
|
+
|
|
33
|
+
interface JevState {
|
|
34
|
+
phase: "planning" | "implementation";
|
|
35
|
+
/** OpenAI Codex model for this phase. */
|
|
36
|
+
model: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
type JevRequest = ModelRouteRequest<JevState>;
|
|
40
|
+
|
|
41
|
+
function routeTo(request: JevRequest, ctx: ExtensionContext, id: string, state?: JevState): ModelRoute<JevState> {
|
|
42
|
+
const model = ctx.modelRegistry.find(PROVIDER, id);
|
|
43
|
+
if (!model) throw new Error(`Model ${PROVIDER}/${id} is not in the catalog`);
|
|
44
|
+
return { model, thinkingLevel: request.thinkingLevel, state };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function lastUserText(messages: readonly Message[]): string {
|
|
48
|
+
const content = messages.filter((message) => message.role === "user").at(-1)?.content ?? "";
|
|
49
|
+
if (typeof content === "string") return content;
|
|
50
|
+
return content.flatMap((block) => (block.type === "text" ? [block.text] : [])).join("\n");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Whether a tool call since the last user message edited a file successfully. */
|
|
54
|
+
function editedThisTurn(messages: readonly Message[]): boolean {
|
|
55
|
+
const lastUser = messages.findLastIndex((message) => message.role === "user");
|
|
56
|
+
return messages
|
|
57
|
+
.slice(lastUser + 1)
|
|
58
|
+
.some((message) => message.role === "toolResult" && EDIT_TOOLS.has(message.toolName) && !message.isError);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Planning model for a new session: Sol for complex work, Terra otherwise or when Jev is unavailable. */
|
|
62
|
+
async function choosePlanningModel(request: JevRequest, ctx: ExtensionContext): Promise<string> {
|
|
63
|
+
// Keep a planning model the session already uses, so switching to jev/auto costs no cache miss.
|
|
64
|
+
const previous = request.previous?.model;
|
|
65
|
+
if (previous?.provider === PROVIDER && (previous.id === SOL || previous.id === TERRA)) return previous.id;
|
|
66
|
+
|
|
67
|
+
const jev = ctx.modelRegistry.findOfType("classifier", "typesafe", "jev-latest");
|
|
68
|
+
if (!jev) return TERRA;
|
|
69
|
+
const result = await ctx.modelRegistry.classify(
|
|
70
|
+
jev,
|
|
71
|
+
{
|
|
72
|
+
state: { prompt: lastUserText(request.messages).slice(0, 16_000) },
|
|
73
|
+
questions: {
|
|
74
|
+
complexity: {
|
|
75
|
+
type: "choice",
|
|
76
|
+
instructions: "How demanding is the software engineering work requested in `prompt`?",
|
|
77
|
+
criteria: {
|
|
78
|
+
standard: "Ordinary features, fixes, reviews, or questions",
|
|
79
|
+
complex: "Subtle design, cross-cutting changes, or hard debugging",
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
{ signal: request.signal },
|
|
85
|
+
);
|
|
86
|
+
const answer = result.stopReason === "stop" ? result.answers.complexity : undefined;
|
|
87
|
+
return answer?.type === "choice" && (answer.probabilities.complex ?? 0) >= 0.5 ? SOL : TERRA;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export default function (pi: ExtensionAPI) {
|
|
91
|
+
pi.registerVirtualModel<JevState>({
|
|
92
|
+
provider: "jev",
|
|
93
|
+
id: "auto",
|
|
94
|
+
name: "Auto (Jev)",
|
|
95
|
+
thinkingLevels: ["low", "medium", "high", "xhigh"],
|
|
96
|
+
// Shared by all three models; shown before the first response.
|
|
97
|
+
contextWindow: 272_000,
|
|
98
|
+
maxTokens: 128_000,
|
|
99
|
+
async route(request, ctx) {
|
|
100
|
+
if (request.reason === "direct") return routeTo(request, ctx, LUNA);
|
|
101
|
+
const state = request.state;
|
|
102
|
+
if (!state) {
|
|
103
|
+
const model = await choosePlanningModel(request, ctx);
|
|
104
|
+
return routeTo(request, ctx, model, { phase: "planning", model });
|
|
105
|
+
}
|
|
106
|
+
// The planning model made the first edit: hand the rest of the work to Luna.
|
|
107
|
+
if (state.phase === "planning" && editedThisTurn(request.messages)) {
|
|
108
|
+
return routeTo(request, ctx, LUNA, { phase: "implementation", model: LUNA });
|
|
109
|
+
}
|
|
110
|
+
return routeTo(request, ctx, state.model);
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Syncs pi theme with macOS system appearance (dark/light mode).
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* pi -e examples/extensions/mac-system-theme.ts
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { exec } from "node:child_process";
|
|
9
|
+
import { promisify } from "node:util";
|
|
10
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
11
|
+
|
|
12
|
+
const execAsync = promisify(exec);
|
|
13
|
+
|
|
14
|
+
async function isDarkMode(): Promise<boolean> {
|
|
15
|
+
try {
|
|
16
|
+
const { stdout } = await execAsync(
|
|
17
|
+
"osascript -e 'tell application \"System Events\" to tell appearance preferences to return dark mode'",
|
|
18
|
+
);
|
|
19
|
+
return stdout.trim() === "true";
|
|
20
|
+
} catch {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export default function (pi: ExtensionAPI) {
|
|
26
|
+
let intervalId: ReturnType<typeof setInterval> | null = null;
|
|
27
|
+
|
|
28
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
29
|
+
let currentTheme = (await isDarkMode()) ? "dark" : "light";
|
|
30
|
+
ctx.ui.setTheme(currentTheme);
|
|
31
|
+
|
|
32
|
+
intervalId = setInterval(async () => {
|
|
33
|
+
const newTheme = (await isDarkMode()) ? "dark" : "light";
|
|
34
|
+
if (newTheme !== currentTheme) {
|
|
35
|
+
currentTheme = newTheme;
|
|
36
|
+
ctx.ui.setTheme(currentTheme);
|
|
37
|
+
}
|
|
38
|
+
}, 2000);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
pi.on("session_shutdown", () => {
|
|
42
|
+
if (intervalId) {
|
|
43
|
+
clearInterval(intervalId);
|
|
44
|
+
intervalId = null;
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom message rendering example.
|
|
3
|
+
*
|
|
4
|
+
* Shows how to use registerMessageRenderer to control how custom messages
|
|
5
|
+
* appear in the TUI, with colors, formatting, and expandable details.
|
|
6
|
+
*
|
|
7
|
+
* Usage: /status [message] - sends a status message with custom rendering
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
11
|
+
import { Box, Text } from "@earendil-works/pi-tui";
|
|
12
|
+
|
|
13
|
+
export default function (pi: ExtensionAPI) {
|
|
14
|
+
// Register custom renderer for "status-update" messages
|
|
15
|
+
pi.registerMessageRenderer("status-update", (message, { expanded, outputPad }, theme) => {
|
|
16
|
+
const details = message.details as { level: string; timestamp: number } | undefined;
|
|
17
|
+
const level = details?.level ?? "info";
|
|
18
|
+
|
|
19
|
+
// Color based on level
|
|
20
|
+
const color = level === "error" ? "error" : level === "warn" ? "warning" : "success";
|
|
21
|
+
const prefix = theme.fg(color, `[${level.toUpperCase()}]`);
|
|
22
|
+
|
|
23
|
+
let text = `${prefix} ${message.content}`;
|
|
24
|
+
|
|
25
|
+
// Show timestamp when expanded
|
|
26
|
+
if (expanded && details?.timestamp) {
|
|
27
|
+
const time = new Date(details.timestamp).toLocaleTimeString();
|
|
28
|
+
text += `\n${theme.fg("dim", ` at ${time}`)}`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Use Box with customMessageBg for consistent styling
|
|
32
|
+
const box = new Box(outputPad, 1, (t) => theme.bg("customMessageBg", t));
|
|
33
|
+
box.addChild(new Text(text, 0, 0));
|
|
34
|
+
return box;
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// Command to send status messages
|
|
38
|
+
pi.registerCommand("status", {
|
|
39
|
+
description: "Send a status message (usage: /status [warn|error] message)",
|
|
40
|
+
handler: async (args, _ctx) => {
|
|
41
|
+
const parts = args.trim().split(/\s+/);
|
|
42
|
+
let level = "info";
|
|
43
|
+
let content = args.trim();
|
|
44
|
+
|
|
45
|
+
// Check for level prefix
|
|
46
|
+
if (parts[0] === "warn" || parts[0] === "error") {
|
|
47
|
+
level = parts[0];
|
|
48
|
+
content = parts.slice(1).join(" ") || "Status update";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
pi.sendMessage({
|
|
52
|
+
customType: "status-update",
|
|
53
|
+
content,
|
|
54
|
+
display: true,
|
|
55
|
+
details: { level, timestamp: Date.now() },
|
|
56
|
+
});
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
}
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal Mode Example - Demonstrates a "minimal" tool display mode
|
|
3
|
+
*
|
|
4
|
+
* This extension overrides built-in tools to provide custom rendering:
|
|
5
|
+
* - Collapsed mode: Only shows the tool call (command/path), no output
|
|
6
|
+
* - Expanded mode: Shows full output like the built-in renderers
|
|
7
|
+
*
|
|
8
|
+
* This demonstrates how a "minimal mode" could work, where ctrl+o cycles through:
|
|
9
|
+
* - Standard: Shows truncated output (current default)
|
|
10
|
+
* - Expanded: Shows full output (current expanded)
|
|
11
|
+
* - Minimal: Shows only tool call, no output (this extension's collapsed mode)
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* pi -e ./minimal-mode.ts
|
|
15
|
+
*
|
|
16
|
+
* Then use ctrl+o to toggle between minimal (collapsed) and full (expanded) views.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
20
|
+
import {
|
|
21
|
+
createBashToolDefinition,
|
|
22
|
+
createEditToolDefinition,
|
|
23
|
+
createFindToolDefinition,
|
|
24
|
+
createGrepToolDefinition,
|
|
25
|
+
createLsToolDefinition,
|
|
26
|
+
createReadToolDefinition,
|
|
27
|
+
createWriteToolDefinition,
|
|
28
|
+
formatReadLineRange,
|
|
29
|
+
} from "@earendil-works/pi-coding-agent";
|
|
30
|
+
import { Text } from "@earendil-works/pi-tui";
|
|
31
|
+
import { homedir } from "os";
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Shorten a path by replacing home directory with ~
|
|
35
|
+
*/
|
|
36
|
+
function shortenPath(path: string): string {
|
|
37
|
+
const home = homedir();
|
|
38
|
+
if (path.startsWith(home)) {
|
|
39
|
+
return `~${path.slice(home.length)}`;
|
|
40
|
+
}
|
|
41
|
+
return path;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function createBuiltInTools(cwd: string) {
|
|
45
|
+
return {
|
|
46
|
+
read: createReadToolDefinition(cwd),
|
|
47
|
+
bash: createBashToolDefinition(cwd),
|
|
48
|
+
edit: createEditToolDefinition(cwd),
|
|
49
|
+
write: createWriteToolDefinition(cwd),
|
|
50
|
+
find: createFindToolDefinition(cwd),
|
|
51
|
+
grep: createGrepToolDefinition(cwd),
|
|
52
|
+
ls: createLsToolDefinition(cwd),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export default function (pi: ExtensionAPI) {
|
|
57
|
+
const tools = createBuiltInTools(process.cwd());
|
|
58
|
+
|
|
59
|
+
// =========================================================================
|
|
60
|
+
// Read Tool
|
|
61
|
+
// =========================================================================
|
|
62
|
+
pi.registerTool({
|
|
63
|
+
...tools.read,
|
|
64
|
+
|
|
65
|
+
renderCall(args, theme, _context) {
|
|
66
|
+
const path = shortenPath(args.path || "");
|
|
67
|
+
let pathDisplay = path ? theme.fg("accent", path) : theme.fg("toolOutput", "...");
|
|
68
|
+
|
|
69
|
+
const lineRange = formatReadLineRange(args.offset, args.limit);
|
|
70
|
+
if (lineRange) {
|
|
71
|
+
pathDisplay += theme.fg("warning", lineRange);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return new Text(`${theme.fg("toolTitle", theme.bold("read"))} ${pathDisplay}`, 0, 0);
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
renderResult(result, { expanded }, theme, _context) {
|
|
78
|
+
// Minimal mode: show nothing in collapsed state
|
|
79
|
+
if (!expanded) {
|
|
80
|
+
return new Text("", 0, 0);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Expanded mode: show full output
|
|
84
|
+
const textContent = result.content.find((c) => c.type === "text");
|
|
85
|
+
if (!textContent || textContent.type !== "text") {
|
|
86
|
+
return new Text("", 0, 0);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const lines = textContent.text.split("\n");
|
|
90
|
+
const output = lines.map((line) => theme.fg("toolOutput", line)).join("\n");
|
|
91
|
+
return new Text(`\n${output}`, 0, 0);
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// =========================================================================
|
|
96
|
+
// Bash Tool
|
|
97
|
+
// =========================================================================
|
|
98
|
+
pi.registerTool({
|
|
99
|
+
...tools.bash,
|
|
100
|
+
|
|
101
|
+
renderCall(args, theme, _context) {
|
|
102
|
+
const command = args.command || "...";
|
|
103
|
+
const timeout = args.timeout as number | undefined;
|
|
104
|
+
const timeoutSuffix = timeout ? theme.fg("muted", ` (timeout ${timeout}s)`) : "";
|
|
105
|
+
|
|
106
|
+
return new Text(theme.fg("toolTitle", theme.bold(`$ ${command}`)) + timeoutSuffix, 0, 0);
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
renderResult(result, { expanded }, theme, _context) {
|
|
110
|
+
// Minimal mode: show nothing in collapsed state
|
|
111
|
+
if (!expanded) {
|
|
112
|
+
return new Text("", 0, 0);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Expanded mode: show full output
|
|
116
|
+
const textContent = result.content.find((c) => c.type === "text");
|
|
117
|
+
if (!textContent || textContent.type !== "text") {
|
|
118
|
+
return new Text("", 0, 0);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const output = textContent.text
|
|
122
|
+
.trim()
|
|
123
|
+
.split("\n")
|
|
124
|
+
.map((line) => theme.fg("toolOutput", line))
|
|
125
|
+
.join("\n");
|
|
126
|
+
|
|
127
|
+
if (!output) {
|
|
128
|
+
return new Text("", 0, 0);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return new Text(`\n${output}`, 0, 0);
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// =========================================================================
|
|
136
|
+
// Write Tool
|
|
137
|
+
// =========================================================================
|
|
138
|
+
pi.registerTool({
|
|
139
|
+
...tools.write,
|
|
140
|
+
|
|
141
|
+
renderCall(args, theme, _context) {
|
|
142
|
+
const path = shortenPath(args.path || "");
|
|
143
|
+
const pathDisplay = path ? theme.fg("accent", path) : theme.fg("toolOutput", "...");
|
|
144
|
+
const lineCount = args.content ? args.content.split("\n").length : 0;
|
|
145
|
+
const lineInfo = lineCount > 0 ? theme.fg("muted", ` (${lineCount} lines)`) : "";
|
|
146
|
+
|
|
147
|
+
return new Text(`${theme.fg("toolTitle", theme.bold("write"))} ${pathDisplay}${lineInfo}`, 0, 0);
|
|
148
|
+
},
|
|
149
|
+
|
|
150
|
+
renderResult(result, { expanded }, theme, _context) {
|
|
151
|
+
// Minimal mode: show nothing (file was written)
|
|
152
|
+
if (!expanded) {
|
|
153
|
+
return new Text("", 0, 0);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Expanded mode: show error if any
|
|
157
|
+
if (result.content.some((c) => c.type === "text" && c.text)) {
|
|
158
|
+
const textContent = result.content.find((c) => c.type === "text");
|
|
159
|
+
if (textContent?.type === "text" && textContent.text) {
|
|
160
|
+
return new Text(`\n${theme.fg("error", textContent.text)}`, 0, 0);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return new Text("", 0, 0);
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
// =========================================================================
|
|
169
|
+
// Edit Tool
|
|
170
|
+
// =========================================================================
|
|
171
|
+
pi.registerTool({
|
|
172
|
+
...tools.edit,
|
|
173
|
+
renderShell: "default",
|
|
174
|
+
|
|
175
|
+
renderCall(args, theme, _context) {
|
|
176
|
+
const path = shortenPath(args.path || "");
|
|
177
|
+
const pathDisplay = path ? theme.fg("accent", path) : theme.fg("toolOutput", "...");
|
|
178
|
+
|
|
179
|
+
return new Text(`${theme.fg("toolTitle", theme.bold("edit"))} ${pathDisplay}`, 0, 0);
|
|
180
|
+
},
|
|
181
|
+
|
|
182
|
+
renderResult(result, { expanded }, theme, _context) {
|
|
183
|
+
// Minimal mode: show nothing in collapsed state
|
|
184
|
+
if (!expanded) {
|
|
185
|
+
return new Text("", 0, 0);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Expanded mode: show diff or error
|
|
189
|
+
const textContent = result.content.find((c) => c.type === "text");
|
|
190
|
+
if (!textContent || textContent.type !== "text") {
|
|
191
|
+
return new Text("", 0, 0);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// For errors, show the error message
|
|
195
|
+
const text = textContent.text;
|
|
196
|
+
if (text.includes("Error") || text.includes("error")) {
|
|
197
|
+
return new Text(`\n${theme.fg("error", text)}`, 0, 0);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Otherwise show the text (would be nice to show actual diff here)
|
|
201
|
+
return new Text(`\n${theme.fg("toolOutput", text)}`, 0, 0);
|
|
202
|
+
},
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
// =========================================================================
|
|
206
|
+
// Find Tool
|
|
207
|
+
// =========================================================================
|
|
208
|
+
pi.registerTool({
|
|
209
|
+
...tools.find,
|
|
210
|
+
|
|
211
|
+
renderCall(args, theme, _context) {
|
|
212
|
+
const pattern = args.pattern || "";
|
|
213
|
+
const path = shortenPath(args.path || ".");
|
|
214
|
+
const limit = args.limit;
|
|
215
|
+
|
|
216
|
+
let text = `${theme.fg("toolTitle", theme.bold("find"))} ${theme.fg("accent", pattern)}`;
|
|
217
|
+
text += theme.fg("toolOutput", ` in ${path}`);
|
|
218
|
+
if (limit !== undefined) {
|
|
219
|
+
text += theme.fg("toolOutput", ` (limit ${limit})`);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return new Text(text, 0, 0);
|
|
223
|
+
},
|
|
224
|
+
|
|
225
|
+
renderResult(result, { expanded }, theme, _context) {
|
|
226
|
+
if (!expanded) {
|
|
227
|
+
// Minimal: just show count
|
|
228
|
+
const textContent = result.content.find((c) => c.type === "text");
|
|
229
|
+
if (textContent?.type === "text") {
|
|
230
|
+
const count = textContent.text.trim().split("\n").filter(Boolean).length;
|
|
231
|
+
if (count > 0) {
|
|
232
|
+
return new Text(theme.fg("muted", ` → ${count} files`), 0, 0);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return new Text("", 0, 0);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Expanded: show full results
|
|
239
|
+
const textContent = result.content.find((c) => c.type === "text");
|
|
240
|
+
if (!textContent || textContent.type !== "text") {
|
|
241
|
+
return new Text("", 0, 0);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const output = textContent.text
|
|
245
|
+
.trim()
|
|
246
|
+
.split("\n")
|
|
247
|
+
.map((line) => theme.fg("toolOutput", line))
|
|
248
|
+
.join("\n");
|
|
249
|
+
|
|
250
|
+
return new Text(`\n${output}`, 0, 0);
|
|
251
|
+
},
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
// =========================================================================
|
|
255
|
+
// Grep Tool
|
|
256
|
+
// =========================================================================
|
|
257
|
+
pi.registerTool({
|
|
258
|
+
...tools.grep,
|
|
259
|
+
|
|
260
|
+
renderCall(args, theme, _context) {
|
|
261
|
+
const pattern = args.pattern || "";
|
|
262
|
+
const path = shortenPath(args.path || ".");
|
|
263
|
+
const glob = args.glob;
|
|
264
|
+
const limit = args.limit;
|
|
265
|
+
|
|
266
|
+
let text = `${theme.fg("toolTitle", theme.bold("grep"))} ${theme.fg("accent", `/${pattern}/`)}`;
|
|
267
|
+
text += theme.fg("toolOutput", ` in ${path}`);
|
|
268
|
+
if (glob) {
|
|
269
|
+
text += theme.fg("toolOutput", ` (${glob})`);
|
|
270
|
+
}
|
|
271
|
+
if (limit !== undefined) {
|
|
272
|
+
text += theme.fg("toolOutput", ` limit ${limit}`);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return new Text(text, 0, 0);
|
|
276
|
+
},
|
|
277
|
+
|
|
278
|
+
renderResult(result, { expanded }, theme, _context) {
|
|
279
|
+
if (!expanded) {
|
|
280
|
+
// Minimal: just show match count
|
|
281
|
+
const textContent = result.content.find((c) => c.type === "text");
|
|
282
|
+
if (textContent?.type === "text") {
|
|
283
|
+
const count = textContent.text.trim().split("\n").filter(Boolean).length;
|
|
284
|
+
if (count > 0) {
|
|
285
|
+
return new Text(theme.fg("muted", ` → ${count} matches`), 0, 0);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return new Text("", 0, 0);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Expanded: show full results
|
|
292
|
+
const textContent = result.content.find((c) => c.type === "text");
|
|
293
|
+
if (!textContent || textContent.type !== "text") {
|
|
294
|
+
return new Text("", 0, 0);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
const output = textContent.text
|
|
298
|
+
.trim()
|
|
299
|
+
.split("\n")
|
|
300
|
+
.map((line) => theme.fg("toolOutput", line))
|
|
301
|
+
.join("\n");
|
|
302
|
+
|
|
303
|
+
return new Text(`\n${output}`, 0, 0);
|
|
304
|
+
},
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
// =========================================================================
|
|
308
|
+
// Ls Tool
|
|
309
|
+
// =========================================================================
|
|
310
|
+
pi.registerTool({
|
|
311
|
+
...tools.ls,
|
|
312
|
+
|
|
313
|
+
renderCall(args, theme, _context) {
|
|
314
|
+
const path = shortenPath(args.path || ".");
|
|
315
|
+
const limit = args.limit;
|
|
316
|
+
|
|
317
|
+
let text = `${theme.fg("toolTitle", theme.bold("ls"))} ${theme.fg("accent", path)}`;
|
|
318
|
+
if (limit !== undefined) {
|
|
319
|
+
text += theme.fg("toolOutput", ` (limit ${limit})`);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
return new Text(text, 0, 0);
|
|
323
|
+
},
|
|
324
|
+
|
|
325
|
+
renderResult(result, { expanded }, theme, _context) {
|
|
326
|
+
if (!expanded) {
|
|
327
|
+
// Minimal: just show entry count
|
|
328
|
+
const textContent = result.content.find((c) => c.type === "text");
|
|
329
|
+
if (textContent?.type === "text") {
|
|
330
|
+
const count = textContent.text.trim().split("\n").filter(Boolean).length;
|
|
331
|
+
if (count > 0) {
|
|
332
|
+
return new Text(theme.fg("muted", ` → ${count} entries`), 0, 0);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return new Text("", 0, 0);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Expanded: show full listing
|
|
339
|
+
const textContent = result.content.find((c) => c.type === "text");
|
|
340
|
+
if (!textContent || textContent.type !== "text") {
|
|
341
|
+
return new Text("", 0, 0);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const output = textContent.text
|
|
345
|
+
.trim()
|
|
346
|
+
.split("\n")
|
|
347
|
+
.map((line) => theme.fg("toolOutput", line))
|
|
348
|
+
.join("\n");
|
|
349
|
+
|
|
350
|
+
return new Text(`\n${output}`, 0, 0);
|
|
351
|
+
},
|
|
352
|
+
});
|
|
353
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Modal Editor - vim-like modal editing example
|
|
3
|
+
*
|
|
4
|
+
* Usage: pi --extension ./examples/extensions/modal-editor.ts
|
|
5
|
+
*
|
|
6
|
+
* - Escape: insert → normal mode (in normal mode, aborts agent)
|
|
7
|
+
* - i: normal → insert mode
|
|
8
|
+
* - hjkl: navigation in normal mode
|
|
9
|
+
* - ctrl+c, ctrl+d, etc. work in both modes
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { CustomEditor, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
13
|
+
import { matchesKey, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
14
|
+
|
|
15
|
+
// Normal mode key mappings: key -> escape sequence (or null for mode switch)
|
|
16
|
+
const NORMAL_KEYS: Record<string, string | null> = {
|
|
17
|
+
h: "\x1b[D", // left
|
|
18
|
+
j: "\x1b[B", // down
|
|
19
|
+
k: "\x1b[A", // up
|
|
20
|
+
l: "\x1b[C", // right
|
|
21
|
+
"0": "\x01", // line start
|
|
22
|
+
$: "\x05", // line end
|
|
23
|
+
x: "\x1b[3~", // delete char
|
|
24
|
+
i: null, // insert mode
|
|
25
|
+
a: null, // append (insert + right)
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
class ModalEditor extends CustomEditor {
|
|
29
|
+
private mode: "normal" | "insert" = "insert";
|
|
30
|
+
|
|
31
|
+
handleInput(data: string): void {
|
|
32
|
+
// Escape toggles to normal mode, or passes through for app handling
|
|
33
|
+
if (matchesKey(data, "escape")) {
|
|
34
|
+
if (this.mode === "insert") {
|
|
35
|
+
this.mode = "normal";
|
|
36
|
+
} else {
|
|
37
|
+
super.handleInput(data); // abort agent, etc.
|
|
38
|
+
}
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Insert mode: pass everything through
|
|
43
|
+
if (this.mode === "insert") {
|
|
44
|
+
super.handleInput(data);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Normal mode: check mapped keys
|
|
49
|
+
if (data in NORMAL_KEYS) {
|
|
50
|
+
const seq = NORMAL_KEYS[data];
|
|
51
|
+
if (data === "i") {
|
|
52
|
+
this.mode = "insert";
|
|
53
|
+
} else if (data === "a") {
|
|
54
|
+
this.mode = "insert";
|
|
55
|
+
super.handleInput("\x1b[C"); // move right first
|
|
56
|
+
} else if (seq) {
|
|
57
|
+
super.handleInput(seq);
|
|
58
|
+
}
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Pass control sequences (ctrl+c, etc.) to super, ignore printable chars
|
|
63
|
+
if (data.length === 1 && data.charCodeAt(0) >= 32) return;
|
|
64
|
+
super.handleInput(data);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
render(width: number): string[] {
|
|
68
|
+
const lines = super.render(width);
|
|
69
|
+
if (lines.length === 0) return lines;
|
|
70
|
+
|
|
71
|
+
// Add mode indicator to bottom border
|
|
72
|
+
const label = this.mode === "normal" ? " NORMAL " : " INSERT ";
|
|
73
|
+
const last = lines.length - 1;
|
|
74
|
+
if (visibleWidth(lines[last]!) >= label.length) {
|
|
75
|
+
lines[last] = truncateToWidth(lines[last]!, width - label.length, "") + label;
|
|
76
|
+
}
|
|
77
|
+
return lines;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export default function (pi: ExtensionAPI) {
|
|
82
|
+
pi.on("session_start", (_event, ctx) => {
|
|
83
|
+
ctx.ui.setEditorComponent((tui, theme, kb) => new ModalEditor(tui, theme, kb));
|
|
84
|
+
});
|
|
85
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model status extension - shows model changes in the status bar.
|
|
3
|
+
*
|
|
4
|
+
* Demonstrates the `model_select` hook which fires when the model changes
|
|
5
|
+
* via /model command, Ctrl+P cycling, or session restore.
|
|
6
|
+
*
|
|
7
|
+
* Usage: pi -e ./model-status.ts
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
11
|
+
|
|
12
|
+
export default function (pi: ExtensionAPI) {
|
|
13
|
+
pi.on("model_select", async (event, ctx) => {
|
|
14
|
+
const { model, previousModel, source } = event;
|
|
15
|
+
|
|
16
|
+
// Format model identifiers
|
|
17
|
+
const next = `${model.provider}/${model.id}`;
|
|
18
|
+
const prev = previousModel ? `${previousModel.provider}/${previousModel.id}` : "none";
|
|
19
|
+
|
|
20
|
+
// Show notification on change
|
|
21
|
+
if (source !== "restore") {
|
|
22
|
+
ctx.ui.notify(`Model: ${next}`, "info");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Update status bar with current model
|
|
26
|
+
ctx.ui.setStatus("model", `🤖 ${model.id}`);
|
|
27
|
+
|
|
28
|
+
// Log change details (visible in debug output)
|
|
29
|
+
console.log(`[model_select] ${prev} → ${next} (${source})`);
|
|
30
|
+
});
|
|
31
|
+
}
|