@subimpact/e 0.99.2 → 0.99.5
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 +7 -17
- package/dist/bundle/chunks/{chunk-75XIWY7P.js → chunk-34ZJK2EZ.js} +1 -1
- package/dist/bundle/chunks/{chunk-5ZENNE67.js → chunk-YGYY5CGE.js} +6 -6
- package/dist/bundle/chunks/{pi-logo-animation-MA3YLQTM.js → pi-logo-animation-5NR3P2W2.js} +1 -1
- package/dist/bundle/chunks/{virtual-modules-VX2P5PB3.js → virtual-modules-GWKJPH7F.js} +1 -1
- package/dist/bundle/cli-runtime.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/modes/interactive/components/pi-logo-animation.js +2 -2
- package/dist/modes/interactive/components/pi-logo-animation.js.map +1 -1
- package/dist/modes/interactive/components/pi-logo.d.ts +7 -6
- package/dist/modes/interactive/components/pi-logo.d.ts.map +1 -1
- package/dist/modes/interactive/components/pi-logo.js +12 -11
- package/dist/modes/interactive/components/pi-logo.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +1 -1
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/session-share.js +1 -1
- package/dist/modes/interactive/session-share.js.map +1 -1
- package/docs/cli.md +3 -62
- package/docs/configuration.md +0 -2
- package/docs/docs.json +0 -4
- package/docs/extensions.md +5 -25
- package/docs/llama-cpp.md +1 -1
- package/docs/models.md +4 -21
- package/docs/sdk.md +1 -6
- package/docs/security.md +0 -2
- package/docs/settings.md +4 -6
- package/examples/README.md +1 -1
- package/examples/extensions/README.md +1 -1
- package/examples/extensions/overlay-qa-tests.ts +1 -1
- package/package.json +1 -1
- package/docs/mcp.md +0 -248
- package/examples/extensions/subagent/README.md +0 -177
- package/examples/extensions/subagent/agents/planner.md +0 -37
- package/examples/extensions/subagent/agents/reviewer.md +0 -35
- package/examples/extensions/subagent/agents/scout.md +0 -50
- package/examples/extensions/subagent/agents/worker.md +0 -24
- package/examples/extensions/subagent/agents.ts +0 -157
- package/examples/extensions/subagent/index.ts +0 -1038
- package/examples/extensions/subagent/prompts/implement-and-review.md +0 -10
- package/examples/extensions/subagent/prompts/implement.md +0 -10
- package/examples/extensions/subagent/prompts/scout-and-plan.md +0 -9
|
@@ -98,7 +98,7 @@ async function tryShareViaRadius(tmpFile, context) {
|
|
|
98
98
|
const body = fs.readFileSync(tmpFile);
|
|
99
99
|
const url = new URL("/v1/artifacts", DEFAULT_RADIUS_GATEWAY);
|
|
100
100
|
url.searchParams.set("visibility", "organization");
|
|
101
|
-
url.searchParams.set("title", "
|
|
101
|
+
url.searchParams.set("title", "e session");
|
|
102
102
|
const response = await fetch(url, {
|
|
103
103
|
method: "POST",
|
|
104
104
|
headers: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-share.js","sourceRoot":"","sources":["../../../src/modes/interactive/session-share.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,sBAAsB,EAAE,MAAM,+CAA+C,CAAC;AACvF,OAAO,EAAwC,SAAS,EAAY,MAAM,wBAAwB,CAAC;AACnG,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAWzC,oGAAoG;AACpG,MAAM,UAAU,0BAA0B,CACzC,OAAqB,EACrB,QAAuB,EACvB,SAAiB;IAEjB,OAAO;QACN;YACC,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,UAAU;YACtB,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;YACnC,QAAQ;YACR,SAAS;YACT,IAAI,EAAE;gBACL,YAAY,EAAE,OAAO,CAAC,KAAK,CAAC,YAAY;gBACxC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;oBACzC,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,WAAW,EAAE,IAAI,CAAC,WAAW;oBAC7B,UAAU,EAAE,IAAI,CAAC,UAAU;iBAC3B,CAAC,CAAC;aACH;SACD;KACD,CAAC;AACH,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,qBAAqB,CAAC,QAAgB,EAAE,OAAqB;IAC5E,oBAAoB,CAAC,OAAO,CAAC,cAAc,EAAE,QAAQ,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,EAAE,CAC9E,0BAA0B,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC,CACxD,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAA4B;IAC9D,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC;IACpE,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IAEpD,IAAI,CAAC;QACJ,IAAI,CAAC;YACJ,qBAAqB,CAAC,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACzB,OAAO,CAAC,SAAS,CAAC,6BAA6B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC;YAC3G,OAAO;QACR,CAAC;QACD,IAAI,MAAM,iBAAiB,CAAC,SAAS,EAAE,OAAO,CAAC;YAAE,OAAO;QAExD,IAAI,CAAC;YACJ,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;YAC9E,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC7B,OAAO,CAAC,SAAS,CAAC,yDAAyD,CAAC,CAAC;gBAC7E,OAAO;YACR,CAAC;QACF,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,CAAC,SAAS,CAAC,2EAA2E,CAAC,CAAC;YAC/F,OAAO;QACR,CAAC;QAED,IAAI,CAAC;YACJ,MAAM,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACzE,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACzB,OAAO,CAAC,SAAS,CAAC,6BAA6B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC;YAC3G,OAAO;QACR,CAAC;QACD,MAAM,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;YAAS,CAAC;QACV,IAAI,CAAC;YACJ,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,CAAC;QAAC,MAAM,CAAC;YACR,wBAAwB;QACzB,CAAC;IACF,CAAC;AACF,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,OAAe,EAAE,OAA4B;IAC7E,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IACpE,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAE5B,MAAM,KAAK,GAAG,iBAAiB,CAC9B,MAAM,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,kBAAkB,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,CACxF,CAAC;IACF,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IAEzB,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,wBAAwB,CAAC,CAAC;IAC/E,OAAO,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;IAChC,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC5B,OAAO,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC;IAC3B,MAAM,CAAC,OAAO,GAAG,GAAG,EAAE;QACrB,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC/B,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;IACvC,CAAC,CAAC;IAEF,IAAI,CAAC;QACJ,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,eAAe,EAAE,sBAAsB,CAAC,CAAC;QAC7D,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;QACnD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAC5C,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YACjC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACR,aAAa,EAAE,UAAU,KAAK,EAAE;gBAChC,cAAc,EAAE,sBAAsB;gBACtC,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC;aACzC;YACD,IAAI;YACJ,MAAM,EAAE,MAAM,CAAC,MAAM;SACrB,CAAC,CAAC;QACH,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QACvC,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAG7C,CAAC;QACT,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QACvC,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC/B,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC;YACrC,OAAO,CAAC,SAAS,CAChB,qCAAqC,IAAI,EAAE,KAAK,IAAI,QAAQ,CAAC,UAAU,IAAI,QAAQ,CAAC,MAAM,EAAE,CAC5F,CAAC;YACF,OAAO,IAAI,CAAC;QACb,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC;QAC7C,OAAO,CAAC,UAAU,CAAC,cAAc,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;QAClE,OAAO,IAAI,CAAC;IACb,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACzB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAC5B,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC/B,OAAO,CAAC,SAAS,CAChB,qCAAqC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CAC/F,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,OAAe,EAAE,OAA4B;IACxE,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,kBAAkB,CAAC,CAAC;IACzE,OAAO,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;IAChC,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC5B,OAAO,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC;IAE3B,IAAI,IAAI,GAAoC,IAAI,CAAC;IACjD,MAAM,CAAC,OAAO,GAAG,GAAG,EAAE;QACrB,IAAI,EAAE,IAAI,EAAE,CAAC;QACb,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC/B,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;IACvC,CAAC,CAAC;IAEF,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,MAAM,IAAI,OAAO,CAA0D,CAAC,OAAO,EAAE,EAAE;YACrG,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,OAAO,CAAC,CAAC,CAAC;YAClE,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;gBAChC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC3B,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;gBAChC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC3B,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO;YAAE,OAAO;QAClC,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAE/B,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,SAAS,CAAC,0BAA0B,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,eAAe,EAAE,CAAC,CAAC;YACxF,OAAO;QACR,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QACzC,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,OAAO,CAAC,SAAS,CAAC,wCAAwC,CAAC,CAAC;YAC5D,OAAO;QACR,CAAC;QAED,MAAM,UAAU,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC7C,OAAO,CAAC,UAAU,CAAC,cAAc,SAAS,CAAC,UAAU,EAAE,UAAU,CAAC,WAAW,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IAC7G,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACzB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAC5B,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC/B,OAAO,CAAC,SAAS,CAAC,0BAA0B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC;QACzG,CAAC;IACF,CAAC;AACF,CAAC;AAED,SAAS,aAAa,CAAC,MAAsB,EAAE,OAA4B;IAC1E,MAAM,CAAC,OAAO,EAAE,CAAC;IACjB,OAAO,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;IAChC,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjD,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AACrC,CAAC","sourcesContent":["import { spawn, spawnSync } from \"node:child_process\";\nimport * as crypto from \"node:crypto\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { DEFAULT_RADIUS_GATEWAY } from \"@earendil-works/pi-ai/providers/radius-config\";\nimport { type Container, type EditorComponent, hyperlink, type TUI } from \"@earendil-works/pi-tui\";\nimport { getAuthCredential } from \"../../cli/auth-command.ts\";\nimport { getShareViewerUrl } from \"../../config.ts\";\nimport type { AgentSession } from \"../../core/agent-session.ts\";\nimport { exportSessionToJsonl } from \"../../core/session-export.ts\";\nimport { BorderedLoader } from \"./components/bordered-loader.ts\";\nimport { theme } from \"./theme/theme.ts\";\n\ninterface SessionShareContext {\n\tsession: AgentSession;\n\tui: TUI;\n\teditorContainer: Container;\n\teditor: EditorComponent;\n\tshowStatus: (message: string) => void;\n\tshowError: (message: string) => void;\n}\n\n/** Trailing `pi.share` entry carrying the system prompt and tool schemas for the session viewer. */\nexport function createShareTrailingEntries(\n\tsession: AgentSession,\n\tparentId: string | null,\n\ttimestamp: string,\n): object[] {\n\treturn [\n\t\t{\n\t\t\ttype: \"custom\",\n\t\t\tcustomType: \"pi.share\",\n\t\t\tid: crypto.randomUUID().slice(0, 8),\n\t\t\tparentId,\n\t\t\ttimestamp,\n\t\t\tdata: {\n\t\t\t\tsystemPrompt: session.state.systemPrompt,\n\t\t\t\ttools: session.state.tools.map((tool) => ({\n\t\t\t\t\tname: tool.name,\n\t\t\t\t\tdescription: tool.description,\n\t\t\t\t\tparameters: tool.parameters,\n\t\t\t\t})),\n\t\t\t},\n\t\t},\n\t];\n}\n\n/** Export the current branch with presentation metadata for Radius. */\nexport function exportSessionForShare(filePath: string, session: AgentSession): void {\n\texportSessionToJsonl(session.sessionManager, filePath, (parentId, timestamp) =>\n\t\tcreateShareTrailingEntries(session, parentId, timestamp),\n\t);\n}\n\n/** Share the current session through Radius, falling back to a private gist. */\nexport async function shareSession(context: SessionShareContext): Promise<void> {\n\tconst tempDir = fs.mkdtempSync(path.join(os.tmpdir(), \"pi-share-\"));\n\tconst jsonlFile = path.join(tempDir, \"session.jsonl\");\n\tconst htmlFile = path.join(tempDir, \"session.html\");\n\n\ttry {\n\t\ttry {\n\t\t\texportSessionForShare(jsonlFile, context.session);\n\t\t} catch (error: unknown) {\n\t\t\tcontext.showError(`Failed to export session: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n\t\t\treturn;\n\t\t}\n\t\tif (await tryShareViaRadius(jsonlFile, context)) return;\n\n\t\ttry {\n\t\t\tconst authResult = spawnSync(\"gh\", [\"auth\", \"status\"], { encoding: \"utf-8\" });\n\t\t\tif (authResult.status !== 0) {\n\t\t\t\tcontext.showError(\"GitHub CLI is not logged in. Run 'gh auth login' first.\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t} catch {\n\t\t\tcontext.showError(\"GitHub CLI (gh) is not installed. Install it from https://cli.github.com/\");\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tawait context.session.exportToHtml(htmlFile, { themeName: theme.name });\n\t\t} catch (error: unknown) {\n\t\t\tcontext.showError(`Failed to export session: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n\t\t\treturn;\n\t\t}\n\t\tawait shareViaGist(htmlFile, context);\n\t} finally {\n\t\ttry {\n\t\t\tfs.rmSync(tempDir, { recursive: true, force: true });\n\t\t} catch {\n\t\t\t// Ignore cleanup errors\n\t\t}\n\t}\n}\n\nasync function tryShareViaRadius(tmpFile: string, context: SessionShareContext): Promise<boolean> {\n\tconst provider = context.session.modelRuntime.getProvider(\"radius\");\n\tif (!provider) return false;\n\n\tconst token = getAuthCredential(\n\t\tawait context.session.modelRuntime.getAuth(\"radius\", { minOAuthValidityMs: 5 * 60_000 }),\n\t);\n\tif (!token) return false;\n\n\tconst loader = new BorderedLoader(context.ui, theme, \"Uploading to Radius...\");\n\tcontext.editorContainer.clear();\n\tcontext.editorContainer.addChild(loader);\n\tcontext.ui.setFocus(loader);\n\tcontext.ui.requestRender();\n\tloader.onAbort = () => {\n\t\trestoreEditor(loader, context);\n\t\tcontext.showStatus(\"Share cancelled\");\n\t};\n\n\ttry {\n\t\tconst body = fs.readFileSync(tmpFile);\n\t\tconst url = new URL(\"/v1/artifacts\", DEFAULT_RADIUS_GATEWAY);\n\t\turl.searchParams.set(\"visibility\", \"organization\");\n\t\turl.searchParams.set(\"title\", \"Pi session\");\n\t\tconst response = await fetch(url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t\t\"Content-Type\": \"application/x-ndjson\",\n\t\t\t\t\"Content-Length\": String(body.byteLength),\n\t\t\t},\n\t\t\tbody,\n\t\t\tsignal: loader.signal,\n\t\t});\n\t\tif (loader.signal.aborted) return true;\n\t\tconst json = (await response.json().catch(() => null)) as {\n\t\t\tartifact?: { canonical_url: string };\n\t\t\terror?: string;\n\t\t} | null;\n\t\tif (loader.signal.aborted) return true;\n\t\trestoreEditor(loader, context);\n\t\tif (!response.ok || !json?.artifact) {\n\t\t\tcontext.showError(\n\t\t\t\t`Failed to upload Radius artifact: ${json?.error || response.statusText || response.status}`,\n\t\t\t);\n\t\t\treturn true;\n\t\t}\n\t\tconst shareUrl = json.artifact.canonical_url;\n\t\tcontext.showStatus(`Share URL: ${hyperlink(shareUrl, shareUrl)}`);\n\t\treturn true;\n\t} catch (error: unknown) {\n\t\tif (!loader.signal.aborted) {\n\t\t\trestoreEditor(loader, context);\n\t\t\tcontext.showError(\n\t\t\t\t`Failed to upload Radius artifact: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n\t\t\t);\n\t\t}\n\t\treturn true;\n\t}\n}\n\nasync function shareViaGist(tmpFile: string, context: SessionShareContext): Promise<void> {\n\tconst loader = new BorderedLoader(context.ui, theme, \"Creating gist...\");\n\tcontext.editorContainer.clear();\n\tcontext.editorContainer.addChild(loader);\n\tcontext.ui.setFocus(loader);\n\tcontext.ui.requestRender();\n\n\tlet proc: ReturnType<typeof spawn> | null = null;\n\tloader.onAbort = () => {\n\t\tproc?.kill();\n\t\trestoreEditor(loader, context);\n\t\tcontext.showStatus(\"Share cancelled\");\n\t};\n\n\ttry {\n\t\tconst result = await new Promise<{ stdout: string; stderr: string; code: number | null }>((resolve) => {\n\t\t\tproc = spawn(\"gh\", [\"gist\", \"create\", \"--public=false\", tmpFile]);\n\t\t\tlet stdout = \"\";\n\t\t\tlet stderr = \"\";\n\t\t\tproc.stdout?.on(\"data\", (data) => {\n\t\t\t\tstdout += data.toString();\n\t\t\t});\n\t\t\tproc.stderr?.on(\"data\", (data) => {\n\t\t\t\tstderr += data.toString();\n\t\t\t});\n\t\t\tproc.on(\"close\", (code) => resolve({ stdout, stderr, code }));\n\t\t});\n\n\t\tif (loader.signal.aborted) return;\n\t\trestoreEditor(loader, context);\n\n\t\tif (result.code !== 0) {\n\t\t\tcontext.showError(`Failed to create gist: ${result.stderr?.trim() || \"Unknown error\"}`);\n\t\t\treturn;\n\t\t}\n\n\t\tconst gistUrl = result.stdout?.trim();\n\t\tconst gistId = gistUrl?.split(\"/\").pop();\n\t\tif (!gistId) {\n\t\t\tcontext.showError(\"Failed to parse gist ID from gh output\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst previewUrl = getShareViewerUrl(gistId);\n\t\tcontext.showStatus(`Share URL: ${hyperlink(previewUrl, previewUrl)}\\nGist: ${hyperlink(gistUrl, gistUrl)}`);\n\t} catch (error: unknown) {\n\t\tif (!loader.signal.aborted) {\n\t\t\trestoreEditor(loader, context);\n\t\t\tcontext.showError(`Failed to create gist: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n\t\t}\n\t}\n}\n\nfunction restoreEditor(loader: BorderedLoader, context: SessionShareContext): void {\n\tloader.dispose();\n\tcontext.editorContainer.clear();\n\tcontext.editorContainer.addChild(context.editor);\n\tcontext.ui.setFocus(context.editor);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"session-share.js","sourceRoot":"","sources":["../../../src/modes/interactive/session-share.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn, spawnSync } from \"node:child_process\";\nimport * as crypto from \"node:crypto\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { DEFAULT_RADIUS_GATEWAY } from \"@earendil-works/pi-ai/providers/radius-config\";\nimport { type Container, type EditorComponent, hyperlink, type TUI } from \"@earendil-works/pi-tui\";\nimport { getAuthCredential } from \"../../cli/auth-command.ts\";\nimport { getShareViewerUrl } from \"../../config.ts\";\nimport type { AgentSession } from \"../../core/agent-session.ts\";\nimport { exportSessionToJsonl } from \"../../core/session-export.ts\";\nimport { BorderedLoader } from \"./components/bordered-loader.ts\";\nimport { theme } from \"./theme/theme.ts\";\n\ninterface SessionShareContext {\n\tsession: AgentSession;\n\tui: TUI;\n\teditorContainer: Container;\n\teditor: EditorComponent;\n\tshowStatus: (message: string) => void;\n\tshowError: (message: string) => void;\n}\n\n/** Trailing `pi.share` entry carrying the system prompt and tool schemas for the session viewer. */\nexport function createShareTrailingEntries(\n\tsession: AgentSession,\n\tparentId: string | null,\n\ttimestamp: string,\n): object[] {\n\treturn [\n\t\t{\n\t\t\ttype: \"custom\",\n\t\t\tcustomType: \"pi.share\",\n\t\t\tid: crypto.randomUUID().slice(0, 8),\n\t\t\tparentId,\n\t\t\ttimestamp,\n\t\t\tdata: {\n\t\t\t\tsystemPrompt: session.state.systemPrompt,\n\t\t\t\ttools: session.state.tools.map((tool) => ({\n\t\t\t\t\tname: tool.name,\n\t\t\t\t\tdescription: tool.description,\n\t\t\t\t\tparameters: tool.parameters,\n\t\t\t\t})),\n\t\t\t},\n\t\t},\n\t];\n}\n\n/** Export the current branch with presentation metadata for Radius. */\nexport function exportSessionForShare(filePath: string, session: AgentSession): void {\n\texportSessionToJsonl(session.sessionManager, filePath, (parentId, timestamp) =>\n\t\tcreateShareTrailingEntries(session, parentId, timestamp),\n\t);\n}\n\n/** Share the current session through Radius, falling back to a private gist. */\nexport async function shareSession(context: SessionShareContext): Promise<void> {\n\tconst tempDir = fs.mkdtempSync(path.join(os.tmpdir(), \"pi-share-\"));\n\tconst jsonlFile = path.join(tempDir, \"session.jsonl\");\n\tconst htmlFile = path.join(tempDir, \"session.html\");\n\n\ttry {\n\t\ttry {\n\t\t\texportSessionForShare(jsonlFile, context.session);\n\t\t} catch (error: unknown) {\n\t\t\tcontext.showError(`Failed to export session: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n\t\t\treturn;\n\t\t}\n\t\tif (await tryShareViaRadius(jsonlFile, context)) return;\n\n\t\ttry {\n\t\t\tconst authResult = spawnSync(\"gh\", [\"auth\", \"status\"], { encoding: \"utf-8\" });\n\t\t\tif (authResult.status !== 0) {\n\t\t\t\tcontext.showError(\"GitHub CLI is not logged in. Run 'gh auth login' first.\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t} catch {\n\t\t\tcontext.showError(\"GitHub CLI (gh) is not installed. Install it from https://cli.github.com/\");\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tawait context.session.exportToHtml(htmlFile, { themeName: theme.name });\n\t\t} catch (error: unknown) {\n\t\t\tcontext.showError(`Failed to export session: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n\t\t\treturn;\n\t\t}\n\t\tawait shareViaGist(htmlFile, context);\n\t} finally {\n\t\ttry {\n\t\t\tfs.rmSync(tempDir, { recursive: true, force: true });\n\t\t} catch {\n\t\t\t// Ignore cleanup errors\n\t\t}\n\t}\n}\n\nasync function tryShareViaRadius(tmpFile: string, context: SessionShareContext): Promise<boolean> {\n\tconst provider = context.session.modelRuntime.getProvider(\"radius\");\n\tif (!provider) return false;\n\n\tconst token = getAuthCredential(\n\t\tawait context.session.modelRuntime.getAuth(\"radius\", { minOAuthValidityMs: 5 * 60_000 }),\n\t);\n\tif (!token) return false;\n\n\tconst loader = new BorderedLoader(context.ui, theme, \"Uploading to Radius...\");\n\tcontext.editorContainer.clear();\n\tcontext.editorContainer.addChild(loader);\n\tcontext.ui.setFocus(loader);\n\tcontext.ui.requestRender();\n\tloader.onAbort = () => {\n\t\trestoreEditor(loader, context);\n\t\tcontext.showStatus(\"Share cancelled\");\n\t};\n\n\ttry {\n\t\tconst body = fs.readFileSync(tmpFile);\n\t\tconst url = new URL(\"/v1/artifacts\", DEFAULT_RADIUS_GATEWAY);\n\t\turl.searchParams.set(\"visibility\", \"organization\");\n\t\turl.searchParams.set(\"title\", \"e session\");\n\t\tconst response = await fetch(url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t\t\"Content-Type\": \"application/x-ndjson\",\n\t\t\t\t\"Content-Length\": String(body.byteLength),\n\t\t\t},\n\t\t\tbody,\n\t\t\tsignal: loader.signal,\n\t\t});\n\t\tif (loader.signal.aborted) return true;\n\t\tconst json = (await response.json().catch(() => null)) as {\n\t\t\tartifact?: { canonical_url: string };\n\t\t\terror?: string;\n\t\t} | null;\n\t\tif (loader.signal.aborted) return true;\n\t\trestoreEditor(loader, context);\n\t\tif (!response.ok || !json?.artifact) {\n\t\t\tcontext.showError(\n\t\t\t\t`Failed to upload Radius artifact: ${json?.error || response.statusText || response.status}`,\n\t\t\t);\n\t\t\treturn true;\n\t\t}\n\t\tconst shareUrl = json.artifact.canonical_url;\n\t\tcontext.showStatus(`Share URL: ${hyperlink(shareUrl, shareUrl)}`);\n\t\treturn true;\n\t} catch (error: unknown) {\n\t\tif (!loader.signal.aborted) {\n\t\t\trestoreEditor(loader, context);\n\t\t\tcontext.showError(\n\t\t\t\t`Failed to upload Radius artifact: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n\t\t\t);\n\t\t}\n\t\treturn true;\n\t}\n}\n\nasync function shareViaGist(tmpFile: string, context: SessionShareContext): Promise<void> {\n\tconst loader = new BorderedLoader(context.ui, theme, \"Creating gist...\");\n\tcontext.editorContainer.clear();\n\tcontext.editorContainer.addChild(loader);\n\tcontext.ui.setFocus(loader);\n\tcontext.ui.requestRender();\n\n\tlet proc: ReturnType<typeof spawn> | null = null;\n\tloader.onAbort = () => {\n\t\tproc?.kill();\n\t\trestoreEditor(loader, context);\n\t\tcontext.showStatus(\"Share cancelled\");\n\t};\n\n\ttry {\n\t\tconst result = await new Promise<{ stdout: string; stderr: string; code: number | null }>((resolve) => {\n\t\t\tproc = spawn(\"gh\", [\"gist\", \"create\", \"--public=false\", tmpFile]);\n\t\t\tlet stdout = \"\";\n\t\t\tlet stderr = \"\";\n\t\t\tproc.stdout?.on(\"data\", (data) => {\n\t\t\t\tstdout += data.toString();\n\t\t\t});\n\t\t\tproc.stderr?.on(\"data\", (data) => {\n\t\t\t\tstderr += data.toString();\n\t\t\t});\n\t\t\tproc.on(\"close\", (code) => resolve({ stdout, stderr, code }));\n\t\t});\n\n\t\tif (loader.signal.aborted) return;\n\t\trestoreEditor(loader, context);\n\n\t\tif (result.code !== 0) {\n\t\t\tcontext.showError(`Failed to create gist: ${result.stderr?.trim() || \"Unknown error\"}`);\n\t\t\treturn;\n\t\t}\n\n\t\tconst gistUrl = result.stdout?.trim();\n\t\tconst gistId = gistUrl?.split(\"/\").pop();\n\t\tif (!gistId) {\n\t\t\tcontext.showError(\"Failed to parse gist ID from gh output\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst previewUrl = getShareViewerUrl(gistId);\n\t\tcontext.showStatus(`Share URL: ${hyperlink(previewUrl, previewUrl)}\\nGist: ${hyperlink(gistUrl, gistUrl)}`);\n\t} catch (error: unknown) {\n\t\tif (!loader.signal.aborted) {\n\t\t\trestoreEditor(loader, context);\n\t\t\tcontext.showError(`Failed to create gist: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n\t\t}\n\t}\n}\n\nfunction restoreEditor(loader: BorderedLoader, context: SessionShareContext): void {\n\tloader.dispose();\n\tcontext.editorContainer.clear();\n\tcontext.editorContainer.addChild(context.editor);\n\tcontext.ui.setFocus(context.editor);\n}\n"]}
|
package/docs/cli.md
CHANGED
|
@@ -13,7 +13,6 @@ pi update [target] [options]
|
|
|
13
13
|
pi list
|
|
14
14
|
pi config [options]
|
|
15
15
|
pi auth <check|print-api-key|print-bearer-token> [options]
|
|
16
|
-
pi mcp <list|login|logout> [options]
|
|
17
16
|
```
|
|
18
17
|
|
|
19
18
|
<a id="modes"></a>
|
|
@@ -138,48 +137,7 @@ Default enabled tools are `read`, `bash`, `edit`, and `write`, unless `defaultTo
|
|
|
138
137
|
| `find` | Find paths using glob patterns |
|
|
139
138
|
| `ls` | List directory contents |
|
|
140
139
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
| Built-in extension | Purpose |
|
|
144
|
-
|---|---|
|
|
145
|
-
| `codemode` | Run JavaScript that calls the other tools, for example in parallel with `Promise.allSettled`; only the script's output reaches the model |
|
|
146
|
-
| `tool_search` | Search tools that are not declared to the model (`codemode` and `deferred` exposure, such as MCP tools) and declare the matches for the next call |
|
|
147
|
-
|
|
148
|
-
### Enable codemode
|
|
149
|
-
|
|
150
|
-
To turn on `codemode` for every session, add it to the default tools in `~/.pi/agent/settings.json` or a project's `.pi/settings.json`:
|
|
151
|
-
|
|
152
|
-
```json
|
|
153
|
-
{
|
|
154
|
-
"defaultTools": ["+codemode"]
|
|
155
|
-
}
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
This keeps `read`, `bash`, `edit`, and `write` and adds `codemode`. For one invocation, list every tool, since `--tools` replaces the selection:
|
|
159
|
-
|
|
160
|
-
```sh
|
|
161
|
-
pi --tools read,bash,edit,write,codemode
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
Codemode is useful without MCP: scripts can run several tool calls in parallel, filter large output before it reaches the model, and call classifier models such as TypeSafe's Jev through `models.classify()` (see [Classifier models](models.md#use-classifier-models)).
|
|
165
|
-
|
|
166
|
-
### How codemode works
|
|
167
|
-
|
|
168
|
-
Codemode scripts run in a QuickJS sandbox that can only reach the other tools, through `tools.<name>(args)`; `ALL_TOOLS` lists them. Output comes from `text(value)`, `image(dataUrlOrImageContent)`, `console.*`, and a top-level `return value`; `exit()` ends the script early. The result starts with `Script completed` or `Script failed`, the wall time, and the output; a failed script keeps its partial output, followed by `Script error:` and the error.
|
|
169
|
-
|
|
170
|
-
A script may start with an options line such as `// @options: {"max_output_tokens": 2000, "timeout_ms": 60000}`. `max_output_tokens` (default 10000) limits the output: longer output keeps its start and end, and the full text is written to a temp file whose path is included in the result. `timeout_ms` is a hard deadline, unset by default.
|
|
171
|
-
|
|
172
|
-
While `codemode` is active, `codemode.mode` in [settings](settings.md#tools) decides how the other tools are presented. With `on` (default) declared tools keep being declared and their descriptions show how to call them from scripts. With `only` they are hidden from the model and listed in the `codemode` description instead, so the model calls them through scripts.
|
|
173
|
-
|
|
174
|
-
The `codemode` description lists the callable tools with their TypeScript declarations, grouped by namespace (for example one MCP server). Tools with `deferred` exposure, which includes MCP tools with the default `codemode` exposure, are not listed and do not affect the description, so it stays the same while MCP servers connect. Declarations share a budget of 3000 estimated tokens (`codemode.inlineBudget` in [settings](settings.md#tools)). Scripts find the rest with `await searchTools(query, { limit, namespace })`, which ranks tools with BM25, and `await describeTool(name)`, or by filtering `ALL_TOOLS`. `await describeNamespace(name)` returns a namespace's description, its instructions (for MCP servers, the server instructions), and the names of its tools.
|
|
175
|
-
|
|
176
|
-
Tools with an output schema resolve to structured values: `bash` to `{ output, truncated, full_output_path?, exit_code, wall_time_seconds }`, also for non-zero exit codes, and MCP tools to their `CallToolResult`. Other tools resolve to their text output. The `output` of `bash` is not limited to the 2000 lines or 50KB the model sees: it holds up to 1 MiB, and longer output keeps its first and last 512 KiB around an omission marker, with `truncated` set and the full output in `full_output_path`.
|
|
177
|
-
|
|
178
|
-
`store(key, value)` and `load(key)` keep JSON values across `codemode` calls: each successful script that stores values appends a `codemode-store` custom entry to the session, so resumed sessions keep the values and each branch sees only the values written on its path. Scripts can also use `models`: `getModelsOfType`, `getAvailableOfType`, and `getModelOfType` list the model catalog, and `classify(model, context)` runs a classifier model with the session's credentials, at most four at a time per script.
|
|
179
|
-
|
|
180
|
-
### Tool search
|
|
181
|
-
|
|
182
|
-
`tool_search` is off by default; enable it with `"defaultTools": ["+tool_search"]` or `--tools`. It uses the same ranking as `searchTools()` over tools that are not declared yet and declares the matches for the next model call. Loaded tools are recorded in the session like other tool changes, so they stay declared on that branch.
|
|
140
|
+
No built-in extension adds tools. The only built-in extension is `builtin:llama.cpp`, which is on by default and registers local models and the `/llama` command, but no tools.
|
|
183
141
|
|
|
184
142
|
<a id="resource-options"></a>
|
|
185
143
|
|
|
@@ -192,9 +150,9 @@ pi --extension ./review.ts
|
|
|
192
150
|
See [Configuration](configuration.md) for conventional directories and project trust, [Settings](settings.md#resources) for configured paths, and [Pi Packages](packages.md) for package sources.
|
|
193
151
|
|
|
194
152
|
- `-e`, `--extension <path>`<br>
|
|
195
|
-
Loads an extension file or directory, or a built-in extension such as `builtin:
|
|
153
|
+
Loads an extension file or directory, or a built-in extension such as `builtin:llama.cpp`, and is repeatable.
|
|
196
154
|
- `-ne`, `--no-extensions`<br>
|
|
197
|
-
Disables discovered, configured, and built-in extensions. Explicit `-e` paths still load, so `pi -ne -e builtin:
|
|
155
|
+
Disables discovered, configured, and built-in extensions. Explicit `-e` paths still load, so `pi -ne -e builtin:llama.cpp` loads only the built-in llama.cpp extension.
|
|
198
156
|
- `--skill <path>`<br>
|
|
199
157
|
Loads a skill file or directory and is repeatable.
|
|
200
158
|
- `-ns`, `--no-skills`<br>
|
|
@@ -310,20 +268,3 @@ Authentication commands require `--provider <provider>` or `--model <model>`. Se
|
|
|
310
268
|
| `--min-expiry <duration>` | `print-bearer-token` | Require remaining token lifetime using `ms`, `s`, `m`, or `h`, such as `30m` |
|
|
311
269
|
|
|
312
270
|
Credential-printing commands write secrets to stdout.
|
|
313
|
-
|
|
314
|
-
## MCP commands
|
|
315
|
-
|
|
316
|
-
These commands work outside a session, so agents can run them through `bash`. See [MCP Servers](mcp.md).
|
|
317
|
-
|
|
318
|
-
| Command | Description |
|
|
319
|
-
|---|---|
|
|
320
|
-
| `pi mcp add <server> [options] -- <command> [args...]` | Add or replace a stdio server in `mcp.json`; `--env KEY=VALUE` (repeatable) and `--cwd <dir>` set its environment and working directory. Arguments after the command are passed to it |
|
|
321
|
-
| `pi mcp add <server> [options] --url <url>` | Add or replace a streamable HTTP server; `--header KEY=VALUE` (repeatable), `--bearer-token-env-var <NAME>` (sends `Authorization: Bearer ${NAME}`), `--oauth-client-id`, `--oauth-client-secret`, `--oauth-callback-port`, and `--oauth-client-name` configure authentication |
|
|
322
|
-
| `pi mcp remove <server>` | Remove a server from `mcp.json`; stored OAuth credentials are kept |
|
|
323
|
-
| `pi mcp list [--json]` | Connect to every enabled server and print its state, tools, and errors; exit with `1` when a config entry is invalid or an enabled server is not connected |
|
|
324
|
-
| `pi mcp login <server> [--timeout <seconds>]` | Sign in to an OAuth server: open the authorization page and wait for the browser (default 300 seconds); a terminal also accepts the pasted redirect URL |
|
|
325
|
-
| `pi mcp logout <server>` | Delete the stored OAuth credentials of a server |
|
|
326
|
-
|
|
327
|
-
`add` and `remove` change `~/.pi/agent/mcp.json`, or `.pi/mcp.json` in the current directory with `--local` (`-l`). `add` also takes `--exposure <mode>` (see [Exposure](mcp.md#exposure)) and `--description <text>` and does not connect; run `pi mcp list` to check the server.
|
|
328
|
-
|
|
329
|
-
Project `.pi/mcp.json` files are only read for projects that are already trusted.
|
package/docs/configuration.md
CHANGED
|
@@ -12,7 +12,6 @@ The agent directory is shown as `<agent-dir>` below. Set its location with the `
|
|
|
12
12
|
|---|---|
|
|
13
13
|
| `<agent-dir>/settings.json` | User-level [settings](settings.md), including preferences, defaults, resource paths, and Pi package declarations. |
|
|
14
14
|
| `<agent-dir>/keybindings.json` | Custom terminal UI and application [keybindings](keybindings.md). |
|
|
15
|
-
| `<agent-dir>/mcp.json` | [MCP servers](mcp.md) available in every project. |
|
|
16
15
|
| `<agent-dir>/models.json` | [Compatible endpoints, models, and model overrides](models.md#configure-a-compatible-endpoint). |
|
|
17
16
|
| `<agent-dir>/auth.json` | Saved API keys and OAuth credentials. |
|
|
18
17
|
| `<agent-dir>/AGENTS.override.md`, `AGENTS.md`, `AGENTS.MD`, `CLAUDE.md`, or `CLAUDE.MD` | User instructions applied across working directories. |
|
|
@@ -28,7 +27,6 @@ The agent directory is shown as `<agent-dir>` below. Set its location with the `
|
|
|
28
27
|
| Path | Responsibility |
|
|
29
28
|
|---|---|
|
|
30
29
|
| `.pi/settings.json` | Project-level [settings](settings.md), resource paths, and Pi package declarations. |
|
|
31
|
-
| `.pi/mcp.json` | Project [MCP servers](mcp.md). |
|
|
32
30
|
| `.pi/SYSTEM.md` | Replaces the system prompt for the project. |
|
|
33
31
|
| `.pi/APPEND_SYSTEM.md` | Adds project-specific instructions to the system prompt. |
|
|
34
32
|
| `.pi/extensions/` | Project extensions. |
|
package/docs/docs.json
CHANGED
package/docs/extensions.md
CHANGED
|
@@ -80,7 +80,6 @@ Automatic retries, recovery, compaction, or queued work can continue afterward.
|
|
|
80
80
|
| Persist non-context session data | `pi.appendEntry()` |
|
|
81
81
|
| Change active tools, model, or thinking level | Session control methods on `pi` |
|
|
82
82
|
| Add a model provider | `pi.registerProvider()` |
|
|
83
|
-
| Add an MCP server | `pi.registerMcpServer()` |
|
|
84
83
|
| Route each request to a model | [`pi.registerVirtualModel()`](virtual-models.md) |
|
|
85
84
|
| Add terminal rendering | Renderer registration and `ctx.ui` |
|
|
86
85
|
| Communicate with another extension | `pi.events` |
|
|
@@ -143,7 +142,7 @@ Use sequential execution when tools share mutable in-memory state.
|
|
|
143
142
|
File-mutating tools should wrap the complete read-modify-write operation with `withFileMutationQueue()`.
|
|
144
143
|
Truncate large model-facing results and tell the model where to read the complete output.
|
|
145
144
|
|
|
146
|
-
Declare `outputSchema` and return a matching `structuredContent` when the result is data. The model still receives `content`; programmatic callers
|
|
145
|
+
Declare `outputSchema` and return a matching `structuredContent` when the result is data. The model still receives `content`; programmatic callers receive `structuredContent` instead of the text. Tools without `outputSchema` are passed to programmatic callers as their text content. To report a failure that still carries data, return the result with `isError: true` instead of throwing: the model sees an error, and programmatic callers still receive `structuredContent`.
|
|
147
146
|
|
|
148
147
|
A tool can run other tools with `ctx.executeTool(name, args, { signal, onUpdate })`. Nested calls go through argument validation and the `tool_call` and `tool_result` handlers like model-issued calls, and emit `tool_execution_start`, `tool_execution_update`, and `tool_execution_end`; all of these events carry `parentToolCallId`, and their `toolCallId` is assigned by pi as `<parent id>/<n>`. These ids do not appear as tool calls or tool results in the transcript. Nested calls do not add transcript entries: their results only reach the calling tool, which reports them itself, for example through `onUpdate` and `details`. The session keeps a bounded record of them (name, arguments, status, duration, error; never results) as `nestedCalls` on the calling tool's result message. It is used for compaction file lists and shown in HTML exports. Arguments over 8 KiB per call or 32 KiB per tool result are omitted, at most 256 calls are kept, and `complete: false` marks a record that lost anything. The `usage` of nested results, at every depth, is added to the calling tool's result `usage`, so a tool reports only its own usage, not that of the tools it called. `ctx.tools` lists the tools `ctx.executeTool()` can call. `tool_result` handlers that redact `content` should also replace `structuredContent`; replacing only `content` drops it.
|
|
149
148
|
|
|
@@ -151,19 +150,17 @@ See [`hello.ts`](../examples/extensions/hello.ts), [`todo.ts`](../examples/exten
|
|
|
151
150
|
|
|
152
151
|
### Tool exposure
|
|
153
152
|
|
|
154
|
-
`exposure` controls how the model reaches a tool. "Callable" means callable from other tools through `ctx.executeTool()` (`ctx.tools`)
|
|
153
|
+
`exposure` controls how the model reaches a tool. "Callable" means callable from other tools through `ctx.executeTool()` (`ctx.tools`):
|
|
155
154
|
|
|
156
155
|
- `direct` (default): declared to the model while active, and callable while active.
|
|
157
156
|
- `model-only`: declared to the model while active, never callable. Use it for tools that orchestrate other tools or ask the user.
|
|
158
|
-
- `codemode`: callable whenever registered, and listed by the `codemode` tool. Not declared to the model unless activated explicitly.
|
|
159
|
-
- `deferred`: like `codemode`, but codemode tools do not list it; `tool_search` can find and activate it.
|
|
160
157
|
- `hidden`: registered but unreachable. Re-register a tool with `exposure: "hidden"` to withdraw it, since tools cannot be unregistered.
|
|
161
158
|
|
|
162
|
-
`namespace: { name, description, instructions }` groups related tools
|
|
159
|
+
`namespace: { name, description, instructions }` groups related tools. `description` summarizes the group; `instructions` holds longer usage guidance and is not listed.
|
|
163
160
|
|
|
164
161
|
Registering a `direct` or `model-only` tool activates it; the other exposures are not activated on registration. The active set (`pi.getActiveTools()`, `pi.setActiveTools()`) is the set of tools declared to the model. `pi.getAllTools()` reports each tool's `exposure`, `namespace`, and `annotations`.
|
|
165
162
|
|
|
166
|
-
`annotations` are hints about what a tool does
|
|
163
|
+
`annotations` are hints about what a tool does: `readOnlyHint`, `destructiveHint`, `idempotentHint`, and `openWorldHint`. Missing hints take the defaults: a tool is not read-only, and may be destructive and reach an open world. The hints are not verified, but a permission extension can use them to decide which calls to confirm. This confirms the calls Codex asks approval for:
|
|
167
164
|
|
|
168
165
|
```typescript
|
|
169
166
|
pi.on("tool_call", async (event, ctx) => {
|
|
@@ -177,7 +174,7 @@ pi.on("tool_call", async (event, ctx) => {
|
|
|
177
174
|
});
|
|
178
175
|
```
|
|
179
176
|
|
|
180
|
-
A tool that orchestrates other tools can adjust what the model sees while it is active with `prepareLoadout(loadout)`. It runs whenever the active tools change and receives the declared tools, the callable tools, and every registered tool with its exposure and namespace. It returns replacement `descriptions` for declared tools (including its own) and `hiddenDeclarations`: active tools whose declarations requests leave out while they stay active and callable.
|
|
177
|
+
A tool that orchestrates other tools can adjust what the model sees while it is active with `prepareLoadout(loadout)`. It runs whenever the active tools change and receives the declared tools, the callable tools, and every registered tool with its exposure and namespace. It returns replacement `descriptions` for declared tools (including its own) and `hiddenDeclarations`: active tools whose declarations requests leave out while they stay active and callable. A tool can implement the same behavior under a different name using only this hook, `exposure`, and `ctx.executeTool()`.
|
|
181
178
|
|
|
182
179
|
### Activate tools dynamically
|
|
183
180
|
|
|
@@ -185,23 +182,6 @@ Register every tool first, keep optional tools inactive, and use `pi.setActiveTo
|
|
|
185
182
|
|
|
186
183
|
Pi records the initial prompt and tool set in the transcript's first system message, then appends tool and prompt changes before the next model request. Providers that cannot represent the transition receive a complete transcript checkpoint, which can invalidate the cached prefix.
|
|
187
184
|
|
|
188
|
-
### MCP servers
|
|
189
|
-
|
|
190
|
-
`pi.registerMcpServer(name, config)` adds an MCP server for the current session. `config` has the shape of an `mcpServers` entry in [`mcp.json`](mcp.md): `command`, `args`, `env`, and `cwd` for stdio servers, `url`, `headers`, and `oauth` for HTTP servers, plus `exposure`, `toolExposure`, `description`, `enabled`, and `timeout`.
|
|
191
|
-
|
|
192
|
-
```typescript
|
|
193
|
-
pi.registerMcpServer("jira", { url: "https://mcp.example.com/jira", exposure: "codemode" });
|
|
194
|
-
pi.unregisterMcpServer("jira");
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
Servers registered while the extension loads connect when the session starts, together with the `mcp.json` servers; servers registered later connect right away, and `pi.unregisterMcpServer()` closes the connection and makes the server's tools unreachable. Registrations are not saved: register again on every load, for example based on the extension's own settings. A server in `mcp.json` with the same name takes precedence, and `/mcp` shows the override. Registering the same name again replaces the extension's earlier registration; names registered by another extension, invalid names, and invalid configs throw.
|
|
198
|
-
|
|
199
|
-
The built-in MCP support connects registered servers. When nothing does, because another extension replaced it (see [MCP](mcp.md#other-mcp-extensions)), each registration is reported as an extension error. Other MCP extensions can connect registered servers too: read them with `pi.getMcpServers()` on `session_start` and handle the `mcp_servers_change` event for later changes.
|
|
200
|
-
|
|
201
|
-
<a id="extensioncontext"></a>
|
|
202
|
-
<a id="extensioncommandcontext"></a>
|
|
203
|
-
<a id="use-extension-context"></a>
|
|
204
|
-
|
|
205
185
|
### Context and session changes
|
|
206
186
|
|
|
207
187
|
`ExtensionContext` provides the working directory, mode, UI, session manager, model runtime, abort signal, context usage, and controls for compaction and shutdown.
|
package/docs/llama-cpp.md
CHANGED
|
@@ -88,7 +88,7 @@ If the router disconnects, `/llama` shows **Retry** and **Close**. Retry reconne
|
|
|
88
88
|
|
|
89
89
|
## Classification
|
|
90
90
|
|
|
91
|
-
Every model listed for chat is also listed as a classifier model with the same ID and the `llama-cpp-classify` API. Classifier models answer typed `choice`, `bool`, and `score` questions about JSON state, like TypeSafe's Jev models.
|
|
91
|
+
Every model listed for chat is also listed as a classifier model with the same ID and the `llama-cpp-classify` API. Classifier models answer typed `choice`, `bool`, and `score` questions about JSON state, like TypeSafe's Jev models. Both are inert catalog entries in Pi: Pi cannot invoke them; scripts that need `classify()` do not run in Pi. See [Classifier models](models.md#use-classifier-models).
|
|
92
92
|
|
|
93
93
|
The model does not generate an answer. Each question becomes one chat prompt: the state, every question of the request, the state again, and then the question with its answers under single-token labels. Labels are letters for a choice (up to 62 options), `Yes`/`No` for a bool, and digits for a score (up to 10 levels). The second copy of the state is read with the questions in view, which improved accuracy on JevBench with small models. Pi reads the probabilities of the labels as the next token and normalizes them. A choice returns every option's probability and a confidence of `(n * peak - 1) / (n - 1)`; a score returns the expected level.
|
|
94
94
|
|
package/docs/models.md
CHANGED
|
@@ -100,7 +100,9 @@ Choose the conservative end of any published range. A model without a lifetime f
|
|
|
100
100
|
|
|
101
101
|
Compatibility settings should describe verified differences in the endpoint's request or response behavior. Do not enable them based only on an endpoint advertising OpenAI or Anthropic compatibility.
|
|
102
102
|
|
|
103
|
-
|
|
103
|
+
<a id="use-classifier-models"></a>
|
|
104
|
+
|
|
105
|
+
## Classifier models
|
|
104
106
|
|
|
105
107
|
Classifier models do not chat. They answer typed questions about JSON state: pick one of several choices, answer yes or no, or give a score, each with probabilities. Pi includes TypeSafe's Jev model from these providers:
|
|
106
108
|
|
|
@@ -114,26 +116,7 @@ Classifier models do not chat. They answer typed questions about JSON state: pic
|
|
|
114
116
|
|
|
115
117
|
Chat models on a [llama.cpp router](llama-cpp.md#classification) are also listed as classifier models.
|
|
116
118
|
|
|
117
|
-
Classifier models
|
|
118
|
-
|
|
119
|
-
```js
|
|
120
|
-
const jev = await models.getModelOfType("classifier", "typesafe", "jev-latest");
|
|
121
|
-
const result = await models.classify(jev, {
|
|
122
|
-
state: { message: "The change works, thanks." },
|
|
123
|
-
questions: {
|
|
124
|
-
approved: {
|
|
125
|
-
type: "bool",
|
|
126
|
-
instructions: "Does the user approve of the result?",
|
|
127
|
-
criteria: { true: "Approval", false: "No approval" },
|
|
128
|
-
},
|
|
129
|
-
},
|
|
130
|
-
});
|
|
131
|
-
return result.answers;
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
When the service reports token counts, as all System One services do, `result.usage` carries them with their cost. Pi adds the usage of a script's classifier calls to the `codemode` tool result, so it counts toward the session cost in the footer and `/session`. The cost uses the model's catalog price; models without one, such as TypeSafe's direct `jev-latest`, report tokens at no cost.
|
|
135
|
-
|
|
136
|
-
Extensions call classifiers through `ctx.modelRegistry.classify()`, without codemode. [Virtual models](virtual-models.md#route-requests) can use them to route requests; see the `jev-router.ts` example.
|
|
119
|
+
Classifier models remain catalog entries but Pi cannot invoke them: there is no classifier tool and no `classify()` in the extension API. They do not appear in `/model`. Scripts that need `classify()` do not run in Pi.
|
|
137
120
|
|
|
138
121
|
## Add a custom provider
|
|
139
122
|
|
package/docs/sdk.md
CHANGED
|
@@ -109,11 +109,7 @@ Use `DefaultResourceLoader` when you want standard discovery with selected overr
|
|
|
109
109
|
|
|
110
110
|
<a id="inlineextension"></a>
|
|
111
111
|
|
|
112
|
-
Inline extension factories can be supplied through `DefaultResourceLoader`. Give one an `InlineExtension` name only when it needs a stable name in diagnostics and startup output. A named inline extension with `replaceable: true` is left out when another extension registers a tool, command, or flag with a name it registers during loading, instead of both loading with a conflict. The CLI's built-in
|
|
113
|
-
|
|
114
|
-
<a id="codemode-mcp"></a>
|
|
115
|
-
|
|
116
|
-
The CLI loads `codemode`, `tool_search`, and MCP as built-in extensions. SDK sessions do not; add `createCodemodeExtension()`, `createToolSearchExtension()`, and `createMcpExtension()` to the `extensionFactories` of `DefaultResourceLoader`. `codemode` and `tool_search` are registered inactive: enable them through the `defaultTools` setting (`["+codemode", "+tool_search"]` keeps the other default tools), or let the MCP extension activate them: `codemode` for servers with `codemode` exposure, `tool_search` for servers with `deferred` exposure. The MCP extension connects its servers on `session_start`, so call `session.bindExtensions()`. See [Codemode and MCP](../examples/sdk/14-codemode-mcp.ts).
|
|
112
|
+
Inline extension factories can be supplied through `DefaultResourceLoader`. Give one an `InlineExtension` name only when it needs a stable name in diagnostics and startup output. A named inline extension with `replaceable: true` is left out when another extension registers a tool, command, or flag with a name it registers during loading, instead of both loading with a conflict. The CLI's built-in llama.cpp extension is replaceable. A named entry with `builtin: true` is not an inline extension: it supplies the code of the `builtin:<name>` extension, which loads like a configured extension file. It loads by default, is listed in `pi config`, and is disabled by `-builtin:<name>` in the `extensions` setting or by `noExtensions`; `additionalExtensionPaths: ["builtin:<name>"]` loads it explicitly. It loads after project trust is resolved, so it cannot handle `project_trust`. The CLI's built-in extensions use it.
|
|
117
113
|
|
|
118
114
|
See the focused examples for [models](../examples/sdk/02-custom-model.ts), [tools](../examples/sdk/05-tools.ts), [extensions](../examples/sdk/06-extensions.ts), and [full control](../examples/sdk/12-full-control.ts).
|
|
119
115
|
|
|
@@ -134,7 +130,6 @@ See the focused examples for [models](../examples/sdk/02-custom-model.ts), [tool
|
|
|
134
130
|
| [Sessions](../examples/sdk/11-sessions.ts) | Control session persistence and restoration |
|
|
135
131
|
| [Full control](../examples/sdk/12-full-control.ts) | Replace default discovery and state services |
|
|
136
132
|
| [Session runtime](../examples/sdk/13-session-runtime.ts) | Replace the active session safely |
|
|
137
|
-
| [Codemode and MCP](../examples/sdk/14-codemode-mcp.ts) | Add the `codemode`, `tool_search`, and MCP extensions |
|
|
138
133
|
|
|
139
134
|
<a id="exports"></a>
|
|
140
135
|
|
package/docs/security.md
CHANGED
|
@@ -37,7 +37,6 @@ Project trust does not limit what tool calls can access or affect. After Pi star
|
|
|
37
37
|
Pi requires a project-trust decision when it finds any of these resources from the current working directory:
|
|
38
38
|
|
|
39
39
|
- `.pi/settings.json`
|
|
40
|
-
- `.pi/mcp.json`
|
|
41
40
|
- `.pi/extensions`, `.pi/skills`, `.pi/prompts`, or `.pi/themes`
|
|
42
41
|
- `.pi/SYSTEM.md` or `.pi/APPEND_SYSTEM.md`
|
|
43
42
|
- project `.agents/skills` in the current directory or an ancestor directory
|
|
@@ -47,7 +46,6 @@ A bare `.pi` directory does not require project trust.
|
|
|
47
46
|
Granting project trust allows Pi to load:
|
|
48
47
|
|
|
49
48
|
- project settings
|
|
50
|
-
- project MCP servers from `.pi/mcp.json`
|
|
51
49
|
- extensions, skills, prompt templates, themes, and system-prompt files under `.pi`
|
|
52
50
|
- missing packages configured through project settings
|
|
53
51
|
- project-local and project-package extensions
|
package/docs/settings.md
CHANGED
|
@@ -38,16 +38,14 @@ See [Choose a Model](models.md) for model selection and thinking controls.
|
|
|
38
38
|
| Setting | Type | Default | Description |
|
|
39
39
|
|---|---|---|---|
|
|
40
40
|
| `defaultTools` | `string[]` | `read`, `bash`, `edit`, `write` | Tools enabled at startup. Plain names replace the defaults; `+name` adds a tool and `-name` removes one. An empty array disables all built-in tools but not extension or SDK tools. |
|
|
41
|
-
| `codemode.mode` | `"on"` \| `"only"` | `"on"` | How the `codemode` tool presents tools while it is active. `on`: declared tools get their `codemode` declaration appended to their description, and `codemode` lists only tools that are not declared. `only`: `codemode` lists every tool scripts can call, and active built-in and extension tools are hidden from the model, so it reaches them through `codemode`. |
|
|
42
|
-
| `codemode.inlineBudget` | number | `3000` | Estimated tokens (characters / 4) the `codemode` tool's description may spend on tool declarations. Tools that do not fit are left out and found with `searchTools()`. `0` lists only namespaces. |
|
|
43
41
|
|
|
44
|
-
Available built-in tools are `read`, `bash`, `powershell`, `edit`, `write`, `grep`, `find`, and `ls`. `defaultTools` can also name
|
|
42
|
+
Available built-in tools are `read`, `bash`, `powershell`, `edit`, `write`, `grep`, `find`, and `ls`. `defaultTools` can also name extension tools registered inactive.
|
|
45
43
|
|
|
46
|
-
A list of only `+name` and `-name` entries changes the inherited selection instead of replacing it. For example, this enables `
|
|
44
|
+
A list of only `+name` and `-name` entries changes the inherited selection instead of replacing it. For example, this enables `grep` next to the default tools:
|
|
47
45
|
|
|
48
46
|
```json
|
|
49
47
|
{
|
|
50
|
-
"defaultTools": ["+
|
|
48
|
+
"defaultTools": ["+grep"]
|
|
51
49
|
}
|
|
52
50
|
```
|
|
53
51
|
|
|
@@ -157,7 +155,7 @@ Resource paths in user settings resolve from the agent directory. Paths in proje
|
|
|
157
155
|
|
|
158
156
|
Resource arrays support glob exclusions with `!pattern`, exact inclusion with `+path`, and exact exclusion with `-path`. Pi loads resources listed in both user-level and project settings.
|
|
159
157
|
|
|
160
|
-
The built-in
|
|
158
|
+
The built-in extension is named `builtin:llama.cpp` in `extensions`. It loads by default; `-builtin:llama.cpp` disables it. A `+builtin:<name>` or `-builtin:<name>` entry in project settings overrides the user setting. `pi config` lists it under Built-in. `--no-extensions` disables it too, and `-e builtin:<name>` loads it explicitly.
|
|
161
159
|
|
|
162
160
|
## Updates, telemetry, and warnings
|
|
163
161
|
|
package/examples/README.md
CHANGED
|
@@ -20,7 +20,7 @@ Programmatic usage via `createAgentSession()`. Shows how to customize models, pr
|
|
|
20
20
|
### [extensions/](extensions/)
|
|
21
21
|
Example extensions demonstrating:
|
|
22
22
|
- Lifecycle event handlers (tool interception, safety gates, context modifications)
|
|
23
|
-
- Custom tools (todo lists, questions,
|
|
23
|
+
- Custom tools (todo lists, questions, background tasks, output truncation)
|
|
24
24
|
- Commands and keyboard shortcuts
|
|
25
25
|
- Custom UI (footers, headers, editors, overlays)
|
|
26
26
|
- Git integration (checkpoints, auto-commit)
|
|
@@ -41,7 +41,7 @@ cp permission-gate.ts ~/.pi/agent/extensions/
|
|
|
41
41
|
| `minimal-mode.ts` | Override built-in tool rendering for minimal display (only tool calls, no output in collapsed mode) |
|
|
42
42
|
| `truncated-tool.ts` | Wraps ripgrep with proper output truncation (50KB/2000 lines) |
|
|
43
43
|
| `ssh.ts` | Delegate all tools to a remote machine via SSH using pluggable operations |
|
|
44
|
-
|
|
44
|
+
|
|
45
45
|
|
|
46
46
|
### Commands & UI
|
|
47
47
|
|
|
@@ -481,7 +481,7 @@ class StreamingOverflowComponent extends BaseOverlay {
|
|
|
481
481
|
"-c",
|
|
482
482
|
`
|
|
483
483
|
echo "Starting streaming overflow test (30+ seconds)..."
|
|
484
|
-
echo "This
|
|
484
|
+
echo "This simulated background-task output with colors, hyperlinks, and long paths"
|
|
485
485
|
echo ""
|
|
486
486
|
for i in $(seq 1 100); do
|
|
487
487
|
# Simulate long file paths with OSC 8 hyperlinks (clickable) - tests width overflow
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@subimpact/e",
|
|
3
|
-
"version": "0.99.
|
|
3
|
+
"version": "0.99.5",
|
|
4
4
|
"description": "Minimal terminal coding harness. Fork of earendil-works/pi (MIT) with the MCP, codemode, and tool-search built-ins removed; compatibility with the classical pi extension/package ecosystem.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"piConfig": {
|