zidane 7.2.4 → 8.0.4
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/LICENSE +21 -0
- package/README.md +34 -6
- package/dist/{acp-D-tVyUjw.js → acp-DQDhi2dj.js} +230 -77
- package/dist/acp-DQDhi2dj.js.map +1 -0
- package/dist/acp-cli.d.ts +1 -1
- package/dist/acp-cli.js +9 -66
- package/dist/acp-cli.js.map +1 -1
- package/dist/acp.d.ts +10 -590
- package/dist/acp.d.ts.map +1 -1
- package/dist/acp.js +3 -3
- package/dist/{agent-D0zZnGbt.js → agent-DSLNmBp0.js} +14401 -13214
- package/dist/agent-DSLNmBp0.js.map +1 -0
- package/dist/agent.d.ts +1 -1
- package/dist/agent.js +3 -2
- package/dist/aliasing-lVFbm81n.js +217 -0
- package/dist/aliasing-lVFbm81n.js.map +1 -0
- package/dist/{anthropic-C2aole0G.js → anthropic-CD00LhUP.js} +1442 -1264
- package/dist/anthropic-CD00LhUP.js.map +1 -0
- package/dist/artifacts-CV2hUKnL.js.map +1 -1
- package/dist/{atomic-write-B7zr1ddF.js → atomic-write-Ijgf2Mhc.js} +13 -3
- package/dist/atomic-write-Ijgf2Mhc.js.map +1 -0
- package/dist/call-tool-dHlbGOIY.js +70 -0
- package/dist/call-tool-dHlbGOIY.js.map +1 -0
- package/dist/chat/pure.d.ts +372 -6
- package/dist/chat/pure.d.ts.map +1 -1
- package/dist/chat/pure.js +35 -244
- package/dist/chat/pure.js.map +1 -1
- package/dist/{approvals-DKaJZYlm.js → chat-JPJJ8uu5.js} +15879 -14631
- package/dist/chat-JPJJ8uu5.js.map +1 -0
- package/dist/chat.d.ts +4 -6
- package/dist/chat.js +23 -12
- package/dist/cli-shared-C-YCaglL.js +159 -0
- package/dist/cli-shared-C-YCaglL.js.map +1 -0
- package/dist/client-core-BQSyDALT.d.ts +2115 -0
- package/dist/client-core-BQSyDALT.d.ts.map +1 -0
- package/dist/codemode-worker.d.ts +1 -0
- package/dist/codemode-worker.js +155 -0
- package/dist/codemode-worker.js.map +1 -0
- package/dist/codemode.d.ts +352 -0
- package/dist/codemode.d.ts.map +1 -0
- package/dist/codemode.js +5 -0
- package/dist/connection-Dr-Js4yZ.d.ts +28 -0
- package/dist/connection-Dr-Js4yZ.d.ts.map +1 -0
- package/dist/connection-loop-gdh22LTI.js +112 -0
- package/dist/connection-loop-gdh22LTI.js.map +1 -0
- package/dist/context-segments-BHKlagL6.js +1016 -0
- package/dist/context-segments-BHKlagL6.js.map +1 -0
- package/dist/{context-transport-T_6AYIvy.js → context-transport-DSMTUsK1.js} +3 -3
- package/dist/{context-transport-T_6AYIvy.js.map → context-transport-DSMTUsK1.js.map} +1 -1
- package/dist/contexts/daytona.d.ts +19 -8
- package/dist/contexts/daytona.d.ts.map +1 -1
- package/dist/contexts/daytona.js +1 -440
- package/dist/contexts/docker.d.ts +36 -7
- package/dist/contexts/docker.d.ts.map +1 -1
- package/dist/contexts/docker.js +1 -456
- package/dist/contexts/e2b.d.ts +68 -13
- package/dist/contexts/e2b.d.ts.map +1 -1
- package/dist/contexts/e2b.js +1 -382
- package/dist/contexts/sandbox.d.ts +1 -1
- package/dist/contexts/sandbox.js +5 -0
- package/dist/contexts/sandbox.js.map +1 -1
- package/dist/{contexts-CRE9pw07.js → contexts-d7UolYot.js} +1059 -524
- package/dist/contexts-d7UolYot.js.map +1 -0
- package/dist/contexts.d.ts +3 -3
- package/dist/contexts.js +1 -1
- package/dist/cred-keys-GpBg71cP.js +105 -0
- package/dist/cred-keys-GpBg71cP.js.map +1 -0
- package/dist/{auth-BG2rVKSt.js → credentials-JttEuRON.js} +55 -206
- package/dist/credentials-JttEuRON.js.map +1 -0
- package/dist/{cursor-iojRXHF9.js → cursor-CdjaQTBW.js} +3 -3
- package/dist/{cursor-iojRXHF9.js.map → cursor-CdjaQTBW.js.map} +1 -1
- package/dist/daemon-cli.d.ts +1 -1
- package/dist/daemon-cli.js +3 -2
- package/dist/daemon-cli.js.map +1 -1
- package/dist/daytona-DG3omipZ.js +513 -0
- package/dist/daytona-DG3omipZ.js.map +1 -0
- package/dist/defaults-Cx3zvDOV.js +23 -0
- package/dist/defaults-Cx3zvDOV.js.map +1 -0
- package/dist/dispatcher-BMlu2BmZ.js +4941 -0
- package/dist/dispatcher-BMlu2BmZ.js.map +1 -0
- package/dist/docker-BZhMMJUp.js +727 -0
- package/dist/docker-BZhMMJUp.js.map +1 -0
- package/dist/e2b-CEVOdRib.js +480 -0
- package/dist/e2b-CEVOdRib.js.map +1 -0
- package/dist/edit-utils-EGosADZq.js +234 -0
- package/dist/edit-utils-EGosADZq.js.map +1 -0
- package/dist/environment-8wsKE2Ln.js +214 -0
- package/dist/environment-8wsKE2Ln.js.map +1 -0
- package/dist/eval-BNcvle_J.js +1595 -0
- package/dist/eval-BNcvle_J.js.map +1 -0
- package/dist/eval.d.ts +2 -2
- package/dist/eval.js +1 -1489
- package/dist/executor-Cx5-8yqi.js +621 -0
- package/dist/executor-Cx5-8yqi.js.map +1 -0
- package/dist/extension-authoring-DyGGmq9V.js +385 -0
- package/dist/extension-authoring-DyGGmq9V.js.map +1 -0
- package/dist/extensions.d.ts +2 -2
- package/dist/extensions.js +3 -3
- package/dist/{fetch-url-DX75gpL0.js → fetch-url-Ct2TjDWt.js} +4 -4
- package/dist/{fetch-url-DX75gpL0.js.map → fetch-url-Ct2TjDWt.js.map} +1 -1
- package/dist/{format-BF745pLL.js → format-C2NQEVUH.js} +39 -2
- package/dist/format-C2NQEVUH.js.map +1 -0
- package/dist/format-bytes-C7tfc3Zm.js +55 -0
- package/dist/format-bytes-C7tfc3Zm.js.map +1 -0
- package/dist/headless-C_rNUuYC.js +960 -0
- package/dist/headless-C_rNUuYC.js.map +1 -0
- package/dist/headless.d.ts +1 -1
- package/dist/headless.js +1 -413
- package/dist/{history-search-C4bk1Wz_.js → history-search-CcYzF8-0.js} +7 -3
- package/dist/history-search-CcYzF8-0.js.map +1 -0
- package/dist/history-search-worker.d.ts +1 -1
- package/dist/history-search-worker.js +1 -1
- package/dist/host-D7NrI03V.js +378 -0
- package/dist/host-D7NrI03V.js.map +1 -0
- package/dist/host-signals-BcP5QKUD.js +118 -0
- package/dist/host-signals-BcP5QKUD.js.map +1 -0
- package/dist/identity-CwfO8K-t.js +26 -0
- package/dist/identity-CwfO8K-t.js.map +1 -0
- package/dist/{index-BgN1T3lk.d.ts → index-BGe1fQT7.d.ts} +10987 -9320
- package/dist/index-BGe1fQT7.d.ts.map +1 -0
- package/dist/index-BVQsIKGn.d.ts +448 -0
- package/dist/index-BVQsIKGn.d.ts.map +1 -0
- package/dist/{index-C6NEd5y_.d.ts → index-CHABJd-L.d.ts} +3386 -502
- package/dist/index-CHABJd-L.d.ts.map +1 -0
- package/dist/{index-C37_ppWv.d.ts → index-D6a7qXpg.d.ts} +2 -3
- package/dist/index-D6a7qXpg.d.ts.map +1 -0
- package/dist/index.d.ts +6 -6
- package/dist/index.js +27 -23
- package/dist/{completion-core-BRo86R_L.js → inline-ghost-BVRQeGoL.js} +50 -2
- package/dist/inline-ghost-BVRQeGoL.js.map +1 -0
- package/dist/ipc/remote.d.ts +313 -0
- package/dist/ipc/remote.d.ts.map +1 -0
- package/dist/ipc/remote.js +4 -0
- package/dist/ipc.d.ts +6 -964
- package/dist/ipc.js +403 -4
- package/dist/ipc.js.map +1 -0
- package/dist/{isolation-Kfoof0MM.d.ts → isolation-D9L650W5.d.ts} +100 -15
- package/dist/isolation-D9L650W5.d.ts.map +1 -0
- package/dist/json-rpc--HXQti1E.js +350 -0
- package/dist/json-rpc--HXQti1E.js.map +1 -0
- package/dist/links-j8rED1sR.js +603 -0
- package/dist/links-j8rED1sR.js.map +1 -0
- package/dist/local-terminal-D8QThwo_.js +252 -0
- package/dist/local-terminal-D8QThwo_.js.map +1 -0
- package/dist/{logger--C1VQjwJ.js → logger-Gtqlayx8.js} +199 -173
- package/dist/logger-Gtqlayx8.js.map +1 -0
- package/dist/logs-view-CWG8aUAG.js.map +1 -1
- package/dist/{mcp-CgNd-f3F.js → mcp-_wecH9Qe.js} +608 -562
- package/dist/mcp-_wecH9Qe.js.map +1 -0
- package/dist/mcp.d.ts +2 -2
- package/dist/mcp.js +2 -2
- package/dist/media-sniff-UKijEaiQ.js.map +1 -1
- package/dist/{messages-2jcOA_5R.js → messages-BqiwcD2Q.js} +1017 -1014
- package/dist/messages-BqiwcD2Q.js.map +1 -0
- package/dist/{oauth-DxHO17JE.js → oauth-Px_pBB9W.js} +5 -5
- package/dist/{oauth-DxHO17JE.js.map → oauth-Px_pBB9W.js.map} +1 -1
- package/dist/{openai-compat-Dy56weK8.js → openai-compat-CFrpH7uq.js} +432 -589
- package/dist/openai-compat-CFrpH7uq.js.map +1 -0
- package/dist/orchestration-BCGmB8Ps.js +511 -0
- package/dist/orchestration-BCGmB8Ps.js.map +1 -0
- package/dist/output/stream-json.d.ts +1 -2
- package/dist/output/stream-json.d.ts.map +1 -1
- package/dist/output/stream-json.js +1 -1
- package/dist/output/terminal.d.ts +1 -2
- package/dist/output/terminal.d.ts.map +1 -1
- package/dist/output/terminal.js +13 -7
- package/dist/output/terminal.js.map +1 -1
- package/dist/{plugins-gbI7SBA6.js → plugins-DS7mahzZ.js} +20 -101
- package/dist/plugins-DS7mahzZ.js.map +1 -0
- package/dist/plugins.d.ts +1 -1
- package/dist/plugins.js +1 -2
- package/dist/prelude-Cxo4t74B.js +517 -0
- package/dist/prelude-Cxo4t74B.js.map +1 -0
- package/dist/presets.d.ts +1 -1
- package/dist/presets.js +1 -2
- package/dist/project-root-B8zADr4o.js +167 -0
- package/dist/project-root-B8zADr4o.js.map +1 -0
- package/dist/project-user-paths-BSgtrRxl.js +58 -0
- package/dist/project-user-paths-BSgtrRxl.js.map +1 -0
- package/dist/{prompts-Pqc3JdW_.d.ts → prompts-DYcvqShf.d.ts} +14 -11
- package/dist/prompts-DYcvqShf.d.ts.map +1 -0
- package/dist/protocol-DnhqqSmE.js +13 -0
- package/dist/protocol-DnhqqSmE.js.map +1 -0
- package/dist/providers/anthropic.d.ts +2 -2
- package/dist/providers/anthropic.js +1 -2
- package/dist/providers/arcee.d.ts +1 -1
- package/dist/providers/arcee.js +1 -1
- package/dist/providers/baseten.d.ts +1 -1
- package/dist/providers/baseten.js +1 -1
- package/dist/providers/cerebras.d.ts +1 -1
- package/dist/providers/cerebras.js +3 -2
- package/dist/providers/cerebras.js.map +1 -1
- package/dist/providers/local.d.ts +1 -1
- package/dist/providers/local.js +1 -1
- package/dist/providers/openai-compat.d.ts +1 -1
- package/dist/providers/openai-compat.js +1 -2
- package/dist/providers/openai.d.ts +1 -1
- package/dist/providers/openai.js +15 -12
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/openrouter.d.ts +1 -1
- package/dist/providers/openrouter.js +3 -2
- package/dist/providers/openrouter.js.map +1 -1
- package/dist/providers/xai.d.ts +1 -1
- package/dist/providers/xai.js +3 -3
- package/dist/{providers-BVhnFyiY.js → providers-XUR7F4Hi.js} +4 -4
- package/dist/{providers-BVhnFyiY.js.map → providers-XUR7F4Hi.js.map} +1 -1
- package/dist/providers.d.ts +1 -1
- package/dist/providers.js +4 -4
- package/dist/registry-D6ShBWJU.js +5234 -0
- package/dist/registry-D6ShBWJU.js.map +1 -0
- package/dist/remote-hosts-BtA_9ZGp.js +97 -0
- package/dist/remote-hosts-BtA_9ZGp.js.map +1 -0
- package/dist/restate.d.ts +2 -3
- package/dist/restate.d.ts.map +1 -1
- package/dist/restate.js +631 -572
- package/dist/restate.js.map +1 -1
- package/dist/run-summary-CklLiZ4y.js +288 -0
- package/dist/run-summary-CklLiZ4y.js.map +1 -0
- package/dist/{sandbox-BH0WQkXn.d.ts → sandbox-C5dR5DwQ.d.ts} +6 -3
- package/dist/sandbox-C5dR5DwQ.d.ts.map +1 -0
- package/dist/session/sqlite.d.ts +1 -2
- package/dist/session/sqlite.d.ts.map +1 -1
- package/dist/session/sqlite.js +1 -616
- package/dist/session-factory-BUGY5P40.js +1576 -0
- package/dist/session-factory-BUGY5P40.js.map +1 -0
- package/dist/{session-BqRP1hS7.js → session-xh9JXu6i.js} +94 -52
- package/dist/session-xh9JXu6i.js.map +1 -0
- package/dist/session.d.ts +1 -1
- package/dist/session.js +2 -2
- package/dist/settings-keys-Ckf29NeM.js +677 -0
- package/dist/settings-keys-Ckf29NeM.js.map +1 -0
- package/dist/shell-path-Dqaoow2J.js +412 -0
- package/dist/shell-path-Dqaoow2J.js.map +1 -0
- package/dist/{skills-BC3dodWp.js → skills-DKqZJm4X.js} +430 -470
- package/dist/skills-DKqZJm4X.js.map +1 -0
- package/dist/skills.d.ts +2 -2
- package/dist/skills.js +1 -2
- package/dist/source-mPExaUm8.js +381 -0
- package/dist/source-mPExaUm8.js.map +1 -0
- package/dist/sqlite-DV1DQzN2.js +698 -0
- package/dist/sqlite-DV1DQzN2.js.map +1 -0
- package/dist/{src-CkNQKFKr.js → src-BRMYRJib.js} +903 -1121
- package/dist/src-BRMYRJib.js.map +1 -0
- package/dist/{stdio-DPpBDPx5.js → stdio-C6YyoW3I.js} +4 -4
- package/dist/{stdio-DPpBDPx5.js.map → stdio-C6YyoW3I.js.map} +1 -1
- package/dist/{stdio-loader-Bbx19dMZ.js → stdio-loader-C830Vg-Z.js} +4 -4
- package/dist/{stdio-loader-Bbx19dMZ.js.map → stdio-loader-C830Vg-Z.js.map} +1 -1
- package/dist/system-prompt-MNVHatSD.d.ts.map +1 -1
- package/dist/timeout-DEaqslLO.d.ts.map +1 -1
- package/dist/todo-edits-Dn251YUP.js +1790 -0
- package/dist/todo-edits-Dn251YUP.js.map +1 -0
- package/dist/{turn-operations-DrbJlpq9.js → tool-formatters-IQFDrdrs.js} +1456 -2120
- package/dist/tool-formatters-IQFDrdrs.js.map +1 -0
- package/dist/tool-state-Dku6YqAB.js +989 -0
- package/dist/tool-state-Dku6YqAB.js.map +1 -0
- package/dist/tools/fetch-url.d.ts +1 -2
- package/dist/tools/fetch-url.d.ts.map +1 -1
- package/dist/tools/fetch-url.js +1 -2
- package/dist/tools/prompts.d.ts +1 -1
- package/dist/tools/prompts.js +7 -7
- package/dist/tools/prompts.js.map +1 -1
- package/dist/tools/web-search.d.ts +1 -2
- package/dist/tools/web-search.d.ts.map +1 -1
- package/dist/tools/web-search.js +2 -2
- package/dist/tools/web-search.js.map +1 -1
- package/dist/tools-_DnT3AGM.js +578 -0
- package/dist/tools-_DnT3AGM.js.map +1 -0
- package/dist/tools.d.ts +3 -3
- package/dist/tools.js +4 -2
- package/dist/tui.d.ts +534 -517
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +34933 -27242
- package/dist/tui.js.map +1 -1
- package/dist/turn-operations-B8sokwi5.js +333 -0
- package/dist/turn-operations-B8sokwi5.js.map +1 -0
- package/dist/turn-operations-DQX5ZZni.d.ts +3089 -0
- package/dist/turn-operations-DQX5ZZni.d.ts.map +1 -0
- package/dist/types-C7ZFOztE.d.ts +132 -0
- package/dist/types-C7ZFOztE.d.ts.map +1 -0
- package/dist/types-CH5XpIHw.js +114 -0
- package/dist/types-CH5XpIHw.js.map +1 -0
- package/dist/{types-CWgENVLY.js → types-Cu0ZGDu9.js} +10 -6
- package/dist/types-Cu0ZGDu9.js.map +1 -0
- package/dist/types-IqegbJEE.d.ts +624 -0
- package/dist/types-IqegbJEE.d.ts.map +1 -0
- package/dist/types.d.ts +4 -4
- package/dist/types.js +1 -1
- package/dist/url-D8HCl65b.js +1259 -0
- package/dist/url-D8HCl65b.js.map +1 -0
- package/dist/wasm-BVT-j5cl.js +33 -0
- package/dist/wasm-BVT-j5cl.js.map +1 -0
- package/dist/workspace-exec-stream-SV2R9d5S.js +355 -0
- package/dist/workspace-exec-stream-SV2R9d5S.js.map +1 -0
- package/dist/ws-CIHMvlSh.js +952 -0
- package/dist/ws-CIHMvlSh.js.map +1 -0
- package/dist/ws-client-N7NxzvQp.js +230 -0
- package/dist/ws-client-N7NxzvQp.js.map +1 -0
- package/dist/{xai-CazjStOK.js → xai-CvJTeLrI.js} +165 -5
- package/dist/xai-CvJTeLrI.js.map +1 -0
- package/dist/xdg-zweed0-t.js +117 -0
- package/dist/xdg-zweed0-t.js.map +1 -0
- package/docs/ACP.md +52 -0
- package/docs/ARCHITECTURE.md +103 -6
- package/docs/ARTIFACTS.md +8 -4
- package/docs/CHAT.md +165 -14
- package/docs/EXECUTION_CONTEXT.md +8 -0
- package/docs/EXTENSIONS.md +123 -2
- package/docs/HEADLESS.md +2 -0
- package/docs/IPC.md +775 -64
- package/docs/MACHINES.md +456 -0
- package/docs/PANELS.md +3 -0
- package/docs/README.md +4 -0
- package/docs/RESTATE.md +3 -2
- package/docs/RUN_IN_BACKGROUND.md +10 -2
- package/docs/SERVER.md +1085 -0
- package/docs/SKILL.md +6 -1
- package/docs/TERMINAL.md +75 -0
- package/docs/TUI.md +65 -14
- package/package.json +58 -26
- package/scripts/eval.ts +4 -0
- package/dist/acp-D-tVyUjw.js.map +0 -1
- package/dist/agent-D0zZnGbt.js.map +0 -1
- package/dist/anthropic-C2aole0G.js.map +0 -1
- package/dist/approvals-DKaJZYlm.js.map +0 -1
- package/dist/atomic-write-B7zr1ddF.js.map +0 -1
- package/dist/auth-BG2rVKSt.js.map +0 -1
- package/dist/completion-core-BRo86R_L.js.map +0 -1
- package/dist/contexts/daytona.js.map +0 -1
- package/dist/contexts/docker.js.map +0 -1
- package/dist/contexts/e2b.js.map +0 -1
- package/dist/contexts-CRE9pw07.js.map +0 -1
- package/dist/eval.js.map +0 -1
- package/dist/format-BF745pLL.js.map +0 -1
- package/dist/glob-DluQFSw1.js +0 -270
- package/dist/glob-DluQFSw1.js.map +0 -1
- package/dist/headless.js.map +0 -1
- package/dist/history-search-C4bk1Wz_.js.map +0 -1
- package/dist/index-BgN1T3lk.d.ts.map +0 -1
- package/dist/index-C37_ppWv.d.ts.map +0 -1
- package/dist/index-C6NEd5y_.d.ts.map +0 -1
- package/dist/ipc-zVSyo6K1.js +0 -331
- package/dist/ipc-zVSyo6K1.js.map +0 -1
- package/dist/ipc.d.ts.map +0 -1
- package/dist/isolation-Kfoof0MM.d.ts.map +0 -1
- package/dist/json-rpc-rSWMUh9b.js +0 -192
- package/dist/json-rpc-rSWMUh9b.js.map +0 -1
- package/dist/logger--C1VQjwJ.js.map +0 -1
- package/dist/mcp-CgNd-f3F.js.map +0 -1
- package/dist/messages-2jcOA_5R.js.map +0 -1
- package/dist/openai-compat-Dy56weK8.js.map +0 -1
- package/dist/output-cap-C9zukcCj.js +0 -100
- package/dist/output-cap-C9zukcCj.js.map +0 -1
- package/dist/panels-B6gRk4bf.js +0 -789
- package/dist/panels-B6gRk4bf.js.map +0 -1
- package/dist/plugins-gbI7SBA6.js.map +0 -1
- package/dist/prompts-Pqc3JdW_.d.ts.map +0 -1
- package/dist/run-summary-BU_NgwUT.js +0 -269
- package/dist/run-summary-BU_NgwUT.js.map +0 -1
- package/dist/sandbox-BH0WQkXn.d.ts.map +0 -1
- package/dist/session/sqlite.js.map +0 -1
- package/dist/session-BqRP1hS7.js.map +0 -1
- package/dist/shell-path-h5czzllR.js +0 -1549
- package/dist/shell-path-h5czzllR.js.map +0 -1
- package/dist/skills-BC3dodWp.js.map +0 -1
- package/dist/src-CkNQKFKr.js.map +0 -1
- package/dist/todo-edits-UOwgxGKu.js +0 -528
- package/dist/todo-edits-UOwgxGKu.js.map +0 -1
- package/dist/tool-formatters-DoRLnfuD.d.ts +0 -759
- package/dist/tool-formatters-DoRLnfuD.d.ts.map +0 -1
- package/dist/transcript-anchors-BeudMbXx.d.ts +0 -1762
- package/dist/transcript-anchors-BeudMbXx.d.ts.map +0 -1
- package/dist/turn-operations-C8bMBDl_.d.ts +0 -1258
- package/dist/turn-operations-C8bMBDl_.d.ts.map +0 -1
- package/dist/turn-operations-DrbJlpq9.js.map +0 -1
- package/dist/types-CWgENVLY.js.map +0 -1
- package/dist/xai-CazjStOK.js.map +0 -1
package/dist/output/terminal.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { d as previewLine } from "../format-C2NQEVUH.js";
|
|
2
2
|
import { i as statsByModel } from "../stats-DAKBEKjc.js";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
//#region src/output/terminal.ts
|
|
@@ -136,15 +136,15 @@ async function setupTerminalOutput(agent, model, prompt, preset, options = {}) {
|
|
|
136
136
|
if (!canPrint()) return;
|
|
137
137
|
console.log(chalk.cyan(`System: ${chalk.yellow(ctx.system)}`));
|
|
138
138
|
});
|
|
139
|
-
|
|
139
|
+
const onSpawnBefore = ({ id, task, depth }) => {
|
|
140
140
|
if (!canPrint()) return;
|
|
141
141
|
const d = depth ?? 1;
|
|
142
142
|
if (activeEmitter !== PARENT_KEY) process.stdout.write("\n");
|
|
143
143
|
const taskPreview = previewLine(task, 80);
|
|
144
144
|
console.log(`${indent(d)}${chalk.dim("🌱")} ${chalk.bold(dye(d, `[${id}]`))} ${chalk.dim("depth=")}${chalk.dim(String(d))} ${dye(d, taskPreview)}`);
|
|
145
145
|
activeEmitter = PARENT_KEY;
|
|
146
|
-
}
|
|
147
|
-
|
|
146
|
+
};
|
|
147
|
+
const onSpawnComplete = (ctx) => {
|
|
148
148
|
if (!canPrint()) return;
|
|
149
149
|
const d = ctx.depth ?? 1;
|
|
150
150
|
const stats = ctx.stats;
|
|
@@ -156,15 +156,21 @@ async function setupTerminalOutput(agent, model, prompt, preset, options = {}) {
|
|
|
156
156
|
console.log(summary);
|
|
157
157
|
cursors.delete(ctx.id);
|
|
158
158
|
activeEmitter = PARENT_KEY;
|
|
159
|
-
}
|
|
160
|
-
|
|
159
|
+
};
|
|
160
|
+
const onSpawnError = ({ id, depth, error }) => {
|
|
161
161
|
if (!canPrint()) return;
|
|
162
162
|
const d = depth ?? 1;
|
|
163
163
|
if (activeEmitter !== PARENT_KEY) process.stdout.write("\n");
|
|
164
164
|
console.log(`${indent(d)}${chalk.red("✗")} ${chalk.bold(dye(d, `[${id}]`))} ${chalk.red(`error: ${error.message}`)}`);
|
|
165
165
|
cursors.delete(id);
|
|
166
166
|
activeEmitter = PARENT_KEY;
|
|
167
|
-
}
|
|
167
|
+
};
|
|
168
|
+
hook("spawn:before", onSpawnBefore);
|
|
169
|
+
hook("spawn:complete", onSpawnComplete);
|
|
170
|
+
hook("spawn:error", onSpawnError);
|
|
171
|
+
hook("child:spawn:before", onSpawnBefore);
|
|
172
|
+
hook("child:spawn:complete", onSpawnComplete);
|
|
173
|
+
hook("child:spawn:error", onSpawnError);
|
|
168
174
|
hook("child:turn:after", ({ childId }) => {
|
|
169
175
|
const c = cursors.get(childId);
|
|
170
176
|
if (c) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal.js","names":[],"sources":["../../src/output/terminal.ts"],"sourcesContent":["import type { Agent, AgentHooks } from '../agent'\nimport type { Preset } from '../presets'\nimport chalk from 'chalk'\nimport { previewLine } from '../chat/format'\nimport { statsByModel } from '../stats'\n\n// ---------------------------------------------------------------------------\n// Depth-aware streaming output\n//\n// The renderer interleaves three streams onto stdout:\n//\n// - parent agent (depth 0) — full color\n// - direct subagents (depth 1) — dim, indented one level\n// - grandchildren (depth ≥ 2) — dim italic, indented per depth\n//\n// Child events arrive on the parent's hook bus as `child:*` carrying `childId`\n// and `depth`. We bucket per-emitter cursor state so a child's text doesn't\n// glue onto the parent's line and vice-versa: when the active emitter changes\n// mid-stream, we emit a newline + indent prefix so the next chunk lands on a\n// fresh line.\n// ---------------------------------------------------------------------------\n\n/** Cursor state per emitter (parent or specific child). */\ninterface EmitterCursor {\n /** Indent depth — 0 = parent, ≥ 1 = subagent. */\n depth: number\n /** Have we written any text in the *current* turn yet? */\n isFirstDelta: boolean\n /** Have we just printed one or more tool-call lines (need a newline before text)? */\n hadToolCalls: boolean\n /** Are we currently inside a thinking block? */\n isThinking: boolean\n}\n\nconst PARENT_KEY = '__parent__'\n\nfunction indent(depth: number): string {\n return ' '.repeat(depth)\n}\n\n/** Style child output dim so the visual hierarchy is obvious at a glance. */\nfunction dye(depth: number, s: string): string {\n if (depth === 0)\n return s\n return chalk.dim(s)\n}\n\nexport interface TerminalOutputOptions {\n printHeader?: boolean\n title?: string\n shouldPrint?: () => boolean\n shouldPrintToolCall?: (ctx: Parameters<AgentHooks['tool:before']>[0]) => boolean\n shouldPrintSummary?: (stats: Parameters<AgentHooks['agent:done']>[0]) => boolean\n}\n\nexport function printTerminalHeader(agent: Agent, model: string, prompt: string, preset: Preset, title = '⚽ Zizou') {\n console.log(`\\n${title}`)\n console.log(`${chalk.bold('🤖 Model:')} ${chalk.green(model)} (${agent.meta.isOAuth ? chalk.green('oauth') : chalk.red('key')})`)\n console.log(`${chalk.bold('📝 Prompt:')} ${chalk.yellow(prompt)}`)\n if (preset.name)\n console.log(`${chalk.bold('🔧 Preset:')} ${chalk.cyan(preset.name)}`)\n if (preset.tools) {\n const names = Object.values(preset.tools).map(t => t.spec.name).join(', ')\n if (names)\n console.log(`${chalk.bold('🔧 Tools:')} ${chalk.cyan(names)}`)\n }\n console.log()\n}\n\n/**\n * Wire the depth-aware terminal renderer onto an agent's hook bus.\n *\n * Returns a disposer that unregisters every hook this function installed —\n * hosts reusing one agent across phases can detach the renderer without\n * tearing the agent down. Callers that ignore the return value keep the old\n * fire-and-forget behavior.\n */\nexport async function setupTerminalOutput(agent: Agent, model: string, prompt: string, preset: Preset, options: TerminalOutputOptions = {}): Promise<() => void> {\n if (options.printHeader !== false)\n printTerminalHeader(agent, model, prompt, preset, options.title)\n\n const unregisters: Array<() => void> = []\n const hook: typeof agent.hooks.hook = (name, fn) => {\n const unregister = agent.hooks.hook(name, fn)\n unregisters.push(unregister)\n return unregister\n }\n\n // Per-emitter cursor map. Parent always exists; child entries appear lazily\n // on first event and disappear on `spawn:complete`/`spawn:error`.\n const cursors = new Map<string, EmitterCursor>()\n cursors.set(PARENT_KEY, { depth: 0, isFirstDelta: true, hadToolCalls: false, isThinking: false })\n\n /** Last emitter that wrote to stdout. Drives newline-on-switch behavior. */\n let activeEmitter: string = PARENT_KEY\n let needsSummaryNewline = false\n\n function noteStreamWrite(text: string): void {\n needsSummaryNewline = !text.endsWith('\\n')\n }\n\n function ensureSummaryLineStart(): void {\n process.stdout.write('\\n\\n')\n needsSummaryNewline = false\n activeEmitter = PARENT_KEY\n }\n\n function canPrint(): boolean {\n return options.shouldPrint?.() ?? true\n }\n\n function getCursor(key: string, depth: number): EmitterCursor {\n let c = cursors.get(key)\n if (!c) {\n c = { depth, isFirstDelta: true, hadToolCalls: false, isThinking: false }\n cursors.set(key, c)\n }\n return c\n }\n\n /**\n * Switch the active emitter; when it changes mid-stream, drop a newline +\n * indent prefix so the next write lands cleanly on its own line.\n */\n function switchTo(key: string, depth: number): EmitterCursor {\n const cursor = getCursor(key, depth)\n if (activeEmitter !== key) {\n // Close out previous emitter's line and indent for the new one.\n process.stdout.write(`\\n${indent(depth)}`)\n activeEmitter = key\n cursor.isFirstDelta = false\n }\n return cursor\n }\n\n // ---------------------------------------------------------------------------\n // Parent loop\n // ---------------------------------------------------------------------------\n\n hook('turn:before', () => {\n const c = cursors.get(PARENT_KEY)!\n c.isFirstDelta = true\n c.isThinking = false\n })\n\n hook('stream:thinking', ({ delta }) => {\n if (!canPrint())\n return\n const c = switchTo(PARENT_KEY, 0)\n if (!c.isThinking) {\n if (c.hadToolCalls)\n process.stdout.write('\\n')\n process.stdout.write(chalk.dim.italic('🧠 '))\n noteStreamWrite('🧠 ')\n c.isThinking = true\n c.hadToolCalls = false\n }\n process.stdout.write(chalk.dim.italic(delta))\n noteStreamWrite(delta)\n })\n\n hook('stream:text', ({ delta }) => {\n if (!canPrint())\n return\n const c = switchTo(PARENT_KEY, 0)\n if (c.isFirstDelta) {\n if (c.isThinking) {\n process.stdout.write('\\n')\n c.isThinking = false\n }\n if (c.hadToolCalls)\n process.stdout.write('\\n')\n c.isFirstDelta = false\n c.hadToolCalls = false\n }\n process.stdout.write(delta)\n noteStreamWrite(delta)\n })\n\n hook('stream:end', () => {\n needsSummaryNewline = false\n })\n\n hook('tool:before', (ctx) => {\n if (!canPrint())\n return\n if (options.shouldPrintToolCall && !options.shouldPrintToolCall(ctx))\n return\n\n const c = switchTo(PARENT_KEY, 0)\n if (c.isThinking) {\n process.stdout.write('\\n')\n c.isThinking = false\n }\n if (!c.hadToolCalls)\n process.stdout.write('\\n')\n c.hadToolCalls = true\n const stringified = JSON.stringify(ctx.input)\n const args = stringified && stringified.trim() !== '{}' ? ` (${chalk.yellow(stringified)})` : ''\n console.log(` ↳ ${chalk.cyan(ctx.name)}${args}`)\n activeEmitter = PARENT_KEY\n })\n\n hook('system:before', (ctx) => {\n if (!canPrint())\n return\n console.log(chalk.cyan(`System: ${chalk.yellow(ctx.system)}`))\n })\n\n // ---------------------------------------------------------------------------\n // Spawn lifecycle — print boundary lines so the user can see when a\n // subagent starts and finishes, with cumulative usage at completion.\n // ---------------------------------------------------------------------------\n\n hook('spawn:before', ({ id, task, depth }) => {\n if (!canPrint())\n return\n const d = depth ?? 1\n // Always start a fresh line for spawn announcements.\n if (activeEmitter !== PARENT_KEY)\n process.stdout.write('\\n')\n const taskPreview = previewLine(task, 80)\n console.log(`${indent(d)}${chalk.dim('🌱')} ${chalk.bold(dye(d, `[${id}]`))} ${chalk.dim('depth=')}${chalk.dim(String(d))} ${dye(d, taskPreview)}`)\n activeEmitter = PARENT_KEY\n })\n\n hook('spawn:complete', (ctx) => {\n if (!canPrint())\n return\n const d = ctx.depth ?? 1\n const stats = ctx.stats\n if (activeEmitter !== PARENT_KEY)\n process.stdout.write('\\n')\n const status = ctx.status === 'completed'\n ? chalk.green('✓')\n : ctx.status === 'aborted'\n ? chalk.yellow('⚠')\n : chalk.red('✗')\n let summary = `${indent(d)}${status} ${chalk.bold(dye(d, `[${ctx.id}]`))} ${chalk.dim(`${ctx.status ?? 'completed'} ·`)} ${chalk.yellow(stats.totalIn)} in / ${chalk.green(stats.totalOut)} out`\n if (typeof stats.cost === 'number' && stats.cost > 0)\n summary += chalk.dim(` · $${stats.cost.toFixed(6)}`)\n if (stats.children && stats.children.length > 0)\n summary += chalk.dim(` · ${stats.children.length} sub-spawn${stats.children.length === 1 ? '' : 's'}`)\n console.log(summary)\n cursors.delete(ctx.id)\n activeEmitter = PARENT_KEY\n })\n\n hook('spawn:error', ({ id, depth, error }) => {\n if (!canPrint())\n return\n const d = depth ?? 1\n if (activeEmitter !== PARENT_KEY)\n process.stdout.write('\\n')\n console.log(`${indent(d)}${chalk.red('✗')} ${chalk.bold(dye(d, `[${id}]`))} ${chalk.red(`error: ${error.message}`)}`)\n cursors.delete(id)\n activeEmitter = PARENT_KEY\n })\n\n // ---------------------------------------------------------------------------\n // Child streaming — re-fired child events with `childId` + `depth`. Render\n // them with the matching depth indent so the user can see subagent output\n // happen live without losing track of the parent's stream.\n // ---------------------------------------------------------------------------\n\n hook('child:turn:after', ({ childId }) => {\n // New child turn boundary — reset its first-delta state so the next\n // text/thinking chunk starts a fresh line under the indent.\n const c = cursors.get(childId)\n if (c) {\n c.isFirstDelta = true\n c.isThinking = false\n }\n })\n\n hook('child:stream:thinking', ({ delta, childId, depth }) => {\n if (!canPrint())\n return\n const c = switchTo(childId, depth)\n if (!c.isThinking) {\n if (c.hadToolCalls)\n process.stdout.write(`\\n${indent(depth)}`)\n process.stdout.write(chalk.dim.italic('🧠 '))\n noteStreamWrite('🧠 ')\n c.isThinking = true\n c.hadToolCalls = false\n }\n process.stdout.write(chalk.dim.italic(delta))\n noteStreamWrite(delta)\n })\n\n hook('child:stream:text', ({ delta, childId, depth }) => {\n if (!canPrint())\n return\n const c = switchTo(childId, depth)\n if (c.isFirstDelta) {\n if (c.isThinking) {\n process.stdout.write(`\\n${indent(depth)}`)\n c.isThinking = false\n }\n if (c.hadToolCalls)\n process.stdout.write(`\\n${indent(depth)}`)\n c.isFirstDelta = false\n c.hadToolCalls = false\n }\n // Wrap each delta in dim so multi-line child output stays visually nested.\n // We don't re-indent on \\n inside a delta — providers chunk text in small\n // pieces, so cross-line indentation would feel jittery; the depth prefix\n // on emitter switch is enough.\n process.stdout.write(dye(depth, delta))\n noteStreamWrite(delta)\n })\n\n hook('child:stream:end', ({ childId }) => {\n if (activeEmitter === childId)\n activeEmitter = PARENT_KEY\n needsSummaryNewline = false\n })\n\n hook('child:tool:before', ({ name, input, childId, depth }) => {\n if (!canPrint())\n return\n const c = switchTo(childId, depth)\n if (c.isThinking) {\n process.stdout.write('\\n')\n c.isThinking = false\n }\n if (!c.hadToolCalls)\n process.stdout.write('\\n')\n c.hadToolCalls = true\n const stringified = JSON.stringify(input)\n const args = stringified && stringified.trim() !== '{}' ? ` (${chalk.yellow(stringified)})` : ''\n console.log(`${indent(depth)} ↳ ${chalk.cyan(name)}${args}`)\n activeEmitter = childId\n })\n\n hook('child:tool:error', ({ name, error, depth }) => {\n if (!canPrint())\n return\n if (activeEmitter !== PARENT_KEY)\n process.stdout.write('\\n')\n console.log(`${indent(depth)} ${chalk.red('✗')} ${chalk.cyan(name)}: ${chalk.red(error.message)}`)\n activeEmitter = PARENT_KEY\n })\n\n // ---------------------------------------------------------------------------\n // Final summary\n // ---------------------------------------------------------------------------\n\n hook('agent:done', (stats) => {\n if (!canPrint())\n return\n if (options.shouldPrintSummary && !options.shouldPrintSummary(stats))\n return\n const { totalIn, totalOut, totalCacheRead, totalCacheCreation, turns, elapsed, cost, children } = stats\n\n // Make sure we're not gluing onto an unfinished stream line.\n ensureSummaryLineStart()\n\n const seconds = Math.floor(elapsed / 1000)\n const minutes = Math.floor(seconds / 60)\n const remainingSeconds = seconds % 60\n const timeStr = minutes > 0 ? `${minutes}m ${remainingSeconds}s` : `${remainingSeconds}s`\n\n let line = `🧮 Tokens: ${chalk.yellow(totalIn)} in / ${chalk.green(totalOut)} out`\n line += ` (${chalk.magenta(turns)} parent turn${turns !== 1 ? 's' : ''})`\n line += ` in ${chalk.green(timeStr)}`\n\n if (totalCacheCreation || totalCacheRead)\n line += `\\n Cache: ${chalk.blue(totalCacheCreation)} created / ${chalk.blue(totalCacheRead)} read`\n\n if (cost)\n line += `\\n💸 Cost: ${chalk.yellow(`$${cost.toFixed(6)}`)}`\n\n if (agent.execution.type === 'sandbox' && agent.handle?.id)\n line += `\\n📦 Sandbox: ${chalk.cyan(agent.handle.id)}`\n\n // Per-child breakdown — one line per direct child with its cumulative\n // tokens. Useful for spotting \"which subagent burned all the tokens\".\n if (children && children.length > 0) {\n line += `\\n Children: ${chalk.magenta(children.length)}`\n for (const child of children) {\n line += `\\n · [${chalk.bold(child.id)}] ${chalk.yellow(child.stats.totalIn)} in / ${chalk.green(child.stats.totalOut)} out`\n line += chalk.dim(` (${child.stats.turns} turn${child.stats.turns === 1 ? '' : 's'}, ${child.status ?? 'completed'})`)\n }\n }\n\n // Per-model breakdown — only worth showing when the run touched more\n // than one model id (cross-model spawn, vision-fallback, etc.). Skipping\n // the single-model case keeps the happy-path summary compact.\n const byModel = statsByModel(stats)\n if (byModel.size > 1) {\n line += `\\n By model:`\n for (const [modelId, usage] of byModel) {\n line += `\\n · ${chalk.cyan(modelId)} ${chalk.yellow(usage.input)} in / ${chalk.green(usage.output)} out (${usage.turns} turn${usage.turns === 1 ? '' : 's'})`\n if (usage.cost > 0)\n line += chalk.dim(` · $${usage.cost.toFixed(6)}`)\n }\n }\n\n console.log(chalk.cyan(line))\n\n // Session summary — sums what's actually in the session's run ledger.\n // Each `SessionRun.tokensIn` records parent-loop tokens for that run only\n // (children persisted via `createSpawnTool({ persist: true })` get their\n // own SessionRun entries — summing then matches `stats.totalIn`). When\n // children ran in-memory (the default), the recorded total is parent-\n // only and is intentionally lower than the cumulative figure above.\n if (agent.session) {\n const session = agent.session\n const totalRuns = session.runs.length\n const recordedIn = session.runs.reduce((sum, r) => sum + (r.tokensIn ?? 0), 0)\n const recordedOut = session.runs.reduce((sum, r) => sum + (r.tokensOut ?? 0), 0)\n const recordedCost = session.runs.reduce((sum, r) => sum + (r.cost ?? 0), 0)\n\n let sessionLine = `📋 Session ${chalk.dim(session.id)}: ${chalk.bold(String(totalRuns))} run${totalRuns === 1 ? '' : 's'} recorded`\n sessionLine += `, ${chalk.yellow(recordedIn)} in / ${chalk.green(recordedOut)} out`\n if (recordedCost)\n sessionLine += `, ${chalk.yellow(`$${recordedCost.toFixed(6)}`)}`\n console.log(chalk.dim(sessionLine))\n\n // When the run consumed more than what's recorded (children ran in\n // memory), surface the gap so the difference between the two lines\n // doesn't look like a bug. Compares cumulative `totalIn` against the\n // session ledger; non-zero only with non-persistent spawns.\n const offLedgerIn = totalIn - recordedIn\n const offLedgerOut = totalOut - recordedOut\n const childCount = countDescendants(children)\n if ((offLedgerIn > 0 || offLedgerOut > 0) && childCount > 0) {\n const note = ` ↳ ${chalk.magenta(childCount)} subagent${childCount === 1 ? '' : 's'} ran in-memory (+${chalk.yellow(offLedgerIn)} in / +${chalk.green(offLedgerOut)} out, not persisted)`\n console.log(chalk.dim(note))\n }\n }\n })\n\n return () => {\n for (const unregister of unregisters)\n unregister()\n }\n}\n\n/** Recursively count every descendant in the children tree. */\nfunction countDescendants(children: import('../types').ChildRunStats[] | undefined): number {\n if (!children)\n return 0\n let n = 0\n for (const child of children)\n n += 1 + countDescendants(child.stats.children)\n return n\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"terminal.js","names":[],"sources":["../../src/output/terminal.ts"],"sourcesContent":["import type { Agent, AgentHooks } from '../agent'\nimport type { Preset } from '../presets'\nimport chalk from 'chalk'\nimport { previewLine } from '../chat/format'\nimport { statsByModel } from '../stats'\n\n// ---------------------------------------------------------------------------\n// Depth-aware streaming output\n//\n// The renderer interleaves three streams onto stdout:\n//\n// - parent agent (depth 0) — full color\n// - direct subagents (depth 1) — dim, indented one level\n// - grandchildren (depth ≥ 2) — dim italic, indented per depth\n//\n// Child events arrive on the parent's hook bus as `child:*` carrying `childId`\n// and `depth`. We bucket per-emitter cursor state so a child's text doesn't\n// glue onto the parent's line and vice-versa: when the active emitter changes\n// mid-stream, we emit a newline + indent prefix so the next chunk lands on a\n// fresh line.\n// ---------------------------------------------------------------------------\n\n/** Cursor state per emitter (parent or specific child). */\ninterface EmitterCursor {\n /** Indent depth — 0 = parent, ≥ 1 = subagent. */\n depth: number\n /** Have we written any text in the *current* turn yet? */\n isFirstDelta: boolean\n /** Have we just printed one or more tool-call lines (need a newline before text)? */\n hadToolCalls: boolean\n /** Are we currently inside a thinking block? */\n isThinking: boolean\n}\n\nconst PARENT_KEY = '__parent__'\n\nfunction indent(depth: number): string {\n return ' '.repeat(depth)\n}\n\n/** Style child output dim so the visual hierarchy is obvious at a glance. */\nfunction dye(depth: number, s: string): string {\n if (depth === 0)\n return s\n return chalk.dim(s)\n}\n\nexport interface TerminalOutputOptions {\n printHeader?: boolean\n title?: string\n shouldPrint?: () => boolean\n shouldPrintToolCall?: (ctx: Parameters<AgentHooks['tool:before']>[0]) => boolean\n shouldPrintSummary?: (stats: Parameters<AgentHooks['agent:done']>[0]) => boolean\n}\n\nexport function printTerminalHeader(agent: Agent, model: string, prompt: string, preset: Preset, title = '⚽ Zizou') {\n console.log(`\\n${title}`)\n console.log(`${chalk.bold('🤖 Model:')} ${chalk.green(model)} (${agent.meta.isOAuth ? chalk.green('oauth') : chalk.red('key')})`)\n console.log(`${chalk.bold('📝 Prompt:')} ${chalk.yellow(prompt)}`)\n if (preset.name)\n console.log(`${chalk.bold('🔧 Preset:')} ${chalk.cyan(preset.name)}`)\n if (preset.tools) {\n const names = Object.values(preset.tools).map(t => t.spec.name).join(', ')\n if (names)\n console.log(`${chalk.bold('🔧 Tools:')} ${chalk.cyan(names)}`)\n }\n console.log()\n}\n\n/**\n * Wire the depth-aware terminal renderer onto an agent's hook bus.\n *\n * Returns a disposer that unregisters every hook this function installed —\n * hosts reusing one agent across phases can detach the renderer without\n * tearing the agent down. Callers that ignore the return value keep the old\n * fire-and-forget behavior.\n */\nexport async function setupTerminalOutput(agent: Agent, model: string, prompt: string, preset: Preset, options: TerminalOutputOptions = {}): Promise<() => void> {\n if (options.printHeader !== false)\n printTerminalHeader(agent, model, prompt, preset, options.title)\n\n const unregisters: Array<() => void> = []\n const hook: typeof agent.hooks.hook = (name, fn) => {\n const unregister = agent.hooks.hook(name, fn)\n unregisters.push(unregister)\n return unregister\n }\n\n // Per-emitter cursor map. Parent always exists; child entries appear lazily\n // on first event and disappear on `spawn:complete`/`spawn:error`.\n const cursors = new Map<string, EmitterCursor>()\n cursors.set(PARENT_KEY, { depth: 0, isFirstDelta: true, hadToolCalls: false, isThinking: false })\n\n /** Last emitter that wrote to stdout. Drives newline-on-switch behavior. */\n let activeEmitter: string = PARENT_KEY\n let needsSummaryNewline = false\n\n function noteStreamWrite(text: string): void {\n needsSummaryNewline = !text.endsWith('\\n')\n }\n\n function ensureSummaryLineStart(): void {\n process.stdout.write('\\n\\n')\n needsSummaryNewline = false\n activeEmitter = PARENT_KEY\n }\n\n function canPrint(): boolean {\n return options.shouldPrint?.() ?? true\n }\n\n function getCursor(key: string, depth: number): EmitterCursor {\n let c = cursors.get(key)\n if (!c) {\n c = { depth, isFirstDelta: true, hadToolCalls: false, isThinking: false }\n cursors.set(key, c)\n }\n return c\n }\n\n /**\n * Switch the active emitter; when it changes mid-stream, drop a newline +\n * indent prefix so the next write lands cleanly on its own line.\n */\n function switchTo(key: string, depth: number): EmitterCursor {\n const cursor = getCursor(key, depth)\n if (activeEmitter !== key) {\n // Close out previous emitter's line and indent for the new one.\n process.stdout.write(`\\n${indent(depth)}`)\n activeEmitter = key\n cursor.isFirstDelta = false\n }\n return cursor\n }\n\n // ---------------------------------------------------------------------------\n // Parent loop\n // ---------------------------------------------------------------------------\n\n hook('turn:before', () => {\n const c = cursors.get(PARENT_KEY)!\n c.isFirstDelta = true\n c.isThinking = false\n })\n\n hook('stream:thinking', ({ delta }) => {\n if (!canPrint())\n return\n const c = switchTo(PARENT_KEY, 0)\n if (!c.isThinking) {\n if (c.hadToolCalls)\n process.stdout.write('\\n')\n process.stdout.write(chalk.dim.italic('🧠 '))\n noteStreamWrite('🧠 ')\n c.isThinking = true\n c.hadToolCalls = false\n }\n process.stdout.write(chalk.dim.italic(delta))\n noteStreamWrite(delta)\n })\n\n hook('stream:text', ({ delta }) => {\n if (!canPrint())\n return\n const c = switchTo(PARENT_KEY, 0)\n if (c.isFirstDelta) {\n if (c.isThinking) {\n process.stdout.write('\\n')\n c.isThinking = false\n }\n if (c.hadToolCalls)\n process.stdout.write('\\n')\n c.isFirstDelta = false\n c.hadToolCalls = false\n }\n process.stdout.write(delta)\n noteStreamWrite(delta)\n })\n\n hook('stream:end', () => {\n needsSummaryNewline = false\n })\n\n hook('tool:before', (ctx) => {\n if (!canPrint())\n return\n if (options.shouldPrintToolCall && !options.shouldPrintToolCall(ctx))\n return\n\n const c = switchTo(PARENT_KEY, 0)\n if (c.isThinking) {\n process.stdout.write('\\n')\n c.isThinking = false\n }\n if (!c.hadToolCalls)\n process.stdout.write('\\n')\n c.hadToolCalls = true\n const stringified = JSON.stringify(ctx.input)\n const args = stringified && stringified.trim() !== '{}' ? ` (${chalk.yellow(stringified)})` : ''\n console.log(` ↳ ${chalk.cyan(ctx.name)}${args}`)\n activeEmitter = PARENT_KEY\n })\n\n hook('system:before', (ctx) => {\n if (!canPrint())\n return\n console.log(chalk.cyan(`System: ${chalk.yellow(ctx.system)}`))\n })\n\n // ---------------------------------------------------------------------------\n // Spawn lifecycle — print boundary lines so the user can see when a\n // subagent starts and finishes, with cumulative usage at completion. Nested\n // spawns (run BY a subagent, `child:spawn:*`) print the same lines at their\n // own depth's indent.\n // ---------------------------------------------------------------------------\n\n const onSpawnBefore = ({ id, task, depth }: { id: string, task: string, depth?: number }): void => {\n if (!canPrint())\n return\n const d = depth ?? 1\n // Always start a fresh line for spawn announcements.\n if (activeEmitter !== PARENT_KEY)\n process.stdout.write('\\n')\n const taskPreview = previewLine(task, 80)\n console.log(`${indent(d)}${chalk.dim('🌱')} ${chalk.bold(dye(d, `[${id}]`))} ${chalk.dim('depth=')}${chalk.dim(String(d))} ${dye(d, taskPreview)}`)\n activeEmitter = PARENT_KEY\n }\n\n const onSpawnComplete = (ctx: Parameters<AgentHooks['spawn:complete']>[0]): void => {\n if (!canPrint())\n return\n const d = ctx.depth ?? 1\n const stats = ctx.stats\n if (activeEmitter !== PARENT_KEY)\n process.stdout.write('\\n')\n const status = ctx.status === 'completed'\n ? chalk.green('✓')\n : ctx.status === 'aborted'\n ? chalk.yellow('⚠')\n : chalk.red('✗')\n let summary = `${indent(d)}${status} ${chalk.bold(dye(d, `[${ctx.id}]`))} ${chalk.dim(`${ctx.status ?? 'completed'} ·`)} ${chalk.yellow(stats.totalIn)} in / ${chalk.green(stats.totalOut)} out`\n if (typeof stats.cost === 'number' && stats.cost > 0)\n summary += chalk.dim(` · $${stats.cost.toFixed(6)}`)\n if (stats.children && stats.children.length > 0)\n summary += chalk.dim(` · ${stats.children.length} sub-spawn${stats.children.length === 1 ? '' : 's'}`)\n console.log(summary)\n cursors.delete(ctx.id)\n activeEmitter = PARENT_KEY\n }\n\n const onSpawnError = ({ id, depth, error }: { id: string, depth?: number, error: Error }): void => {\n if (!canPrint())\n return\n const d = depth ?? 1\n if (activeEmitter !== PARENT_KEY)\n process.stdout.write('\\n')\n console.log(`${indent(d)}${chalk.red('✗')} ${chalk.bold(dye(d, `[${id}]`))} ${chalk.red(`error: ${error.message}`)}`)\n cursors.delete(id)\n activeEmitter = PARENT_KEY\n }\n\n hook('spawn:before', onSpawnBefore)\n hook('spawn:complete', onSpawnComplete)\n hook('spawn:error', onSpawnError)\n hook('child:spawn:before', onSpawnBefore)\n hook('child:spawn:complete', onSpawnComplete)\n hook('child:spawn:error', onSpawnError)\n\n // ---------------------------------------------------------------------------\n // Child streaming — re-fired child events with `childId` + `depth`. Render\n // them with the matching depth indent so the user can see subagent output\n // happen live without losing track of the parent's stream.\n // ---------------------------------------------------------------------------\n\n hook('child:turn:after', ({ childId }) => {\n // New child turn boundary — reset its first-delta state so the next\n // text/thinking chunk starts a fresh line under the indent.\n const c = cursors.get(childId)\n if (c) {\n c.isFirstDelta = true\n c.isThinking = false\n }\n })\n\n hook('child:stream:thinking', ({ delta, childId, depth }) => {\n if (!canPrint())\n return\n const c = switchTo(childId, depth)\n if (!c.isThinking) {\n if (c.hadToolCalls)\n process.stdout.write(`\\n${indent(depth)}`)\n process.stdout.write(chalk.dim.italic('🧠 '))\n noteStreamWrite('🧠 ')\n c.isThinking = true\n c.hadToolCalls = false\n }\n process.stdout.write(chalk.dim.italic(delta))\n noteStreamWrite(delta)\n })\n\n hook('child:stream:text', ({ delta, childId, depth }) => {\n if (!canPrint())\n return\n const c = switchTo(childId, depth)\n if (c.isFirstDelta) {\n if (c.isThinking) {\n process.stdout.write(`\\n${indent(depth)}`)\n c.isThinking = false\n }\n if (c.hadToolCalls)\n process.stdout.write(`\\n${indent(depth)}`)\n c.isFirstDelta = false\n c.hadToolCalls = false\n }\n // Wrap each delta in dim so multi-line child output stays visually nested.\n // We don't re-indent on \\n inside a delta — providers chunk text in small\n // pieces, so cross-line indentation would feel jittery; the depth prefix\n // on emitter switch is enough.\n process.stdout.write(dye(depth, delta))\n noteStreamWrite(delta)\n })\n\n hook('child:stream:end', ({ childId }) => {\n if (activeEmitter === childId)\n activeEmitter = PARENT_KEY\n needsSummaryNewline = false\n })\n\n hook('child:tool:before', ({ name, input, childId, depth }) => {\n if (!canPrint())\n return\n const c = switchTo(childId, depth)\n if (c.isThinking) {\n process.stdout.write('\\n')\n c.isThinking = false\n }\n if (!c.hadToolCalls)\n process.stdout.write('\\n')\n c.hadToolCalls = true\n const stringified = JSON.stringify(input)\n const args = stringified && stringified.trim() !== '{}' ? ` (${chalk.yellow(stringified)})` : ''\n console.log(`${indent(depth)} ↳ ${chalk.cyan(name)}${args}`)\n activeEmitter = childId\n })\n\n hook('child:tool:error', ({ name, error, depth }) => {\n if (!canPrint())\n return\n if (activeEmitter !== PARENT_KEY)\n process.stdout.write('\\n')\n console.log(`${indent(depth)} ${chalk.red('✗')} ${chalk.cyan(name)}: ${chalk.red(error.message)}`)\n activeEmitter = PARENT_KEY\n })\n\n // ---------------------------------------------------------------------------\n // Final summary\n // ---------------------------------------------------------------------------\n\n hook('agent:done', (stats) => {\n if (!canPrint())\n return\n if (options.shouldPrintSummary && !options.shouldPrintSummary(stats))\n return\n const { totalIn, totalOut, totalCacheRead, totalCacheCreation, turns, elapsed, cost, children } = stats\n\n // Make sure we're not gluing onto an unfinished stream line.\n ensureSummaryLineStart()\n\n const seconds = Math.floor(elapsed / 1000)\n const minutes = Math.floor(seconds / 60)\n const remainingSeconds = seconds % 60\n const timeStr = minutes > 0 ? `${minutes}m ${remainingSeconds}s` : `${remainingSeconds}s`\n\n let line = `🧮 Tokens: ${chalk.yellow(totalIn)} in / ${chalk.green(totalOut)} out`\n line += ` (${chalk.magenta(turns)} parent turn${turns !== 1 ? 's' : ''})`\n line += ` in ${chalk.green(timeStr)}`\n\n if (totalCacheCreation || totalCacheRead)\n line += `\\n Cache: ${chalk.blue(totalCacheCreation)} created / ${chalk.blue(totalCacheRead)} read`\n\n if (cost)\n line += `\\n💸 Cost: ${chalk.yellow(`$${cost.toFixed(6)}`)}`\n\n if (agent.execution.type === 'sandbox' && agent.handle?.id)\n line += `\\n📦 Sandbox: ${chalk.cyan(agent.handle.id)}`\n\n // Per-child breakdown — one line per direct child with its cumulative\n // tokens. Useful for spotting \"which subagent burned all the tokens\".\n if (children && children.length > 0) {\n line += `\\n Children: ${chalk.magenta(children.length)}`\n for (const child of children) {\n line += `\\n · [${chalk.bold(child.id)}] ${chalk.yellow(child.stats.totalIn)} in / ${chalk.green(child.stats.totalOut)} out`\n line += chalk.dim(` (${child.stats.turns} turn${child.stats.turns === 1 ? '' : 's'}, ${child.status ?? 'completed'})`)\n }\n }\n\n // Per-model breakdown — only worth showing when the run touched more\n // than one model id (cross-model spawn, vision-fallback, etc.). Skipping\n // the single-model case keeps the happy-path summary compact.\n const byModel = statsByModel(stats)\n if (byModel.size > 1) {\n line += `\\n By model:`\n for (const [modelId, usage] of byModel) {\n line += `\\n · ${chalk.cyan(modelId)} ${chalk.yellow(usage.input)} in / ${chalk.green(usage.output)} out (${usage.turns} turn${usage.turns === 1 ? '' : 's'})`\n if (usage.cost > 0)\n line += chalk.dim(` · $${usage.cost.toFixed(6)}`)\n }\n }\n\n console.log(chalk.cyan(line))\n\n // Session summary — sums what's actually in the session's run ledger.\n // Each `SessionRun.tokensIn` records parent-loop tokens for that run only\n // (children persisted via `createSpawnTool({ persist: true })` get their\n // own SessionRun entries — summing then matches `stats.totalIn`). When\n // children ran in-memory (the default), the recorded total is parent-\n // only and is intentionally lower than the cumulative figure above.\n if (agent.session) {\n const session = agent.session\n const totalRuns = session.runs.length\n const recordedIn = session.runs.reduce((sum, r) => sum + (r.tokensIn ?? 0), 0)\n const recordedOut = session.runs.reduce((sum, r) => sum + (r.tokensOut ?? 0), 0)\n const recordedCost = session.runs.reduce((sum, r) => sum + (r.cost ?? 0), 0)\n\n let sessionLine = `📋 Session ${chalk.dim(session.id)}: ${chalk.bold(String(totalRuns))} run${totalRuns === 1 ? '' : 's'} recorded`\n sessionLine += `, ${chalk.yellow(recordedIn)} in / ${chalk.green(recordedOut)} out`\n if (recordedCost)\n sessionLine += `, ${chalk.yellow(`$${recordedCost.toFixed(6)}`)}`\n console.log(chalk.dim(sessionLine))\n\n // When the run consumed more than what's recorded (children ran in\n // memory), surface the gap so the difference between the two lines\n // doesn't look like a bug. Compares cumulative `totalIn` against the\n // session ledger; non-zero only with non-persistent spawns.\n const offLedgerIn = totalIn - recordedIn\n const offLedgerOut = totalOut - recordedOut\n const childCount = countDescendants(children)\n if ((offLedgerIn > 0 || offLedgerOut > 0) && childCount > 0) {\n const note = ` ↳ ${chalk.magenta(childCount)} subagent${childCount === 1 ? '' : 's'} ran in-memory (+${chalk.yellow(offLedgerIn)} in / +${chalk.green(offLedgerOut)} out, not persisted)`\n console.log(chalk.dim(note))\n }\n }\n })\n\n return () => {\n for (const unregister of unregisters)\n unregister()\n }\n}\n\n/** Recursively count every descendant in the children tree. */\nfunction countDescendants(children: import('../types').ChildRunStats[] | undefined): number {\n if (!children)\n return 0\n let n = 0\n for (const child of children)\n n += 1 + countDescendants(child.stats.children)\n return n\n}\n"],"mappings":"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"}
|
|
@@ -1,89 +1,8 @@
|
|
|
1
|
-
import { T as parseSkillFile } from "./skills-BC3dodWp.js";
|
|
2
1
|
import { t as isAllowedRemoteUrl } from "./origin-pinned-fetch-CqG8VZIq.js";
|
|
2
|
+
import { A as parseSkillFile } from "./skills-DKqZJm4X.js";
|
|
3
|
+
import { t as resolveStorageDirs } from "./xdg-zweed0-t.js";
|
|
3
4
|
import { isAbsolute, join, relative, resolve } from "node:path";
|
|
4
|
-
import { existsSync } from "node:fs";
|
|
5
|
-
import { homedir } from "node:os";
|
|
6
5
|
import { readFile, readdir, realpath, stat } from "node:fs/promises";
|
|
7
|
-
//#region src/chat/xdg.ts
|
|
8
|
-
/**
|
|
9
|
-
* XDG Base Directory resolution for zidane.
|
|
10
|
-
*
|
|
11
|
-
* The user's storage spreads across four logical slots:
|
|
12
|
-
*
|
|
13
|
-
* - **config** — credentials, mcp-credentials, keybindings, config.json,
|
|
14
|
-
* mcps.json, skills (user-editable surface).
|
|
15
|
-
* - **data** — sessions.db (long-lived chat history).
|
|
16
|
-
* - **state** — state.json (per-machine UI bookkeeping: last provider,
|
|
17
|
-
* last model, last agent, settings).
|
|
18
|
-
* - **cache** — persisted tool results, background-task logs,
|
|
19
|
-
* auto-update registry cache (regenerable, safe to wipe).
|
|
20
|
-
*
|
|
21
|
-
* Historically all four collapsed to `~/.zidane/`. This module adds
|
|
22
|
-
* XDG-Base-Directory-aware defaults so a Linux user with no existing
|
|
23
|
-
* `~/.zidane/` lands in the conventional `~/.config/zidane/`,
|
|
24
|
-
* `~/.local/share/zidane/`, `~/.local/state/zidane/`, `~/.cache/zidane/`
|
|
25
|
-
* trio. Existing setups (anyone with a `~/.zidane/` directory or
|
|
26
|
-
* `ZIDANE_STORAGE_DIR` set) keep the single-dir layout unchanged.
|
|
27
|
-
*
|
|
28
|
-
* Resolution flow — applied in this order:
|
|
29
|
-
*
|
|
30
|
-
* 1. Caller passed an explicit `storageDir` (`ChatOptions.storageDir`)
|
|
31
|
-
* OR `ZIDANE_STORAGE_DIR` is set → **legacy-explicit** single-dir
|
|
32
|
-
* layout under `<storageDir>/<prefix>`. The four slots collapse to
|
|
33
|
-
* the same directory.
|
|
34
|
-
* 2. `~/<prefix>/` already exists on disk → **legacy-existing**
|
|
35
|
-
* single-dir layout under that directory. Upgrades never silently
|
|
36
|
-
* shift files around.
|
|
37
|
-
* 3. Any `XDG_*_HOME` env var is set OR `process.platform === 'linux'`
|
|
38
|
-
* → **XDG split**. Each slot lands in its own dir. Per-slot
|
|
39
|
-
* `ZIDANE_{CONFIG,DATA,CACHE,STATE}_DIR` overrides beat the XDG
|
|
40
|
-
* vars for surgical tweaks.
|
|
41
|
-
* 4. Otherwise (macOS/Windows, no XDG signal, no existing dir) →
|
|
42
|
-
* **default** single-dir layout at `~/<prefix>/`. Day-one behavior
|
|
43
|
-
* on these platforms is unchanged.
|
|
44
|
-
*
|
|
45
|
-
* The `userDir` legacy alias always equals `configDir` so existing code
|
|
46
|
-
* that still references `paths.userDir` keeps reading credentials, mcps,
|
|
47
|
-
* etc. from the right place.
|
|
48
|
-
*/
|
|
49
|
-
/**
|
|
50
|
-
* Resolve the four storage slots according to the precedence above.
|
|
51
|
-
*
|
|
52
|
-
* Pure aside from one filesystem probe (`existsSync(home/<prefix>)`)
|
|
53
|
-
* — the same probe `resolveStoragePaths` would do anyway when
|
|
54
|
-
* computing `paths.userDir`. No directories are created here; the
|
|
55
|
-
* relevant write paths (state store, credentials writer, persist
|
|
56
|
-
* dir) handle their own lazy `mkdirSync` already.
|
|
57
|
-
*/
|
|
58
|
-
function resolveStorageDirs(opts = {}) {
|
|
59
|
-
const env = opts.env ?? process.env;
|
|
60
|
-
const home = opts.home ?? homedir();
|
|
61
|
-
const platform = opts.platform ?? process.platform;
|
|
62
|
-
const rawPrefix = opts.prefix ?? ".zidane";
|
|
63
|
-
const prefixBare = rawPrefix.replace(/^\./, "");
|
|
64
|
-
const explicitStorageDir = opts.storageDir ?? env.ZIDANE_STORAGE_DIR;
|
|
65
|
-
if (explicitStorageDir) return single(resolve(explicitStorageDir, rawPrefix), "legacy-explicit");
|
|
66
|
-
const legacyHomeDir = resolve(home, rawPrefix);
|
|
67
|
-
if (existsSync(legacyHomeDir)) return single(legacyHomeDir, "legacy-existing");
|
|
68
|
-
if (platform === "linux" || !!env.XDG_CONFIG_HOME || !!env.XDG_DATA_HOME || !!env.XDG_CACHE_HOME || !!env.XDG_STATE_HOME || !!env.ZIDANE_CONFIG_DIR || !!env.ZIDANE_DATA_DIR || !!env.ZIDANE_STATE_DIR || !!env.ZIDANE_CACHE_DIR) return {
|
|
69
|
-
configDir: env.ZIDANE_CONFIG_DIR ?? resolve(env.XDG_CONFIG_HOME || resolve(home, ".config"), prefixBare),
|
|
70
|
-
dataDir: env.ZIDANE_DATA_DIR ?? resolve(env.XDG_DATA_HOME || resolve(home, ".local", "share"), prefixBare),
|
|
71
|
-
stateDir: env.ZIDANE_STATE_DIR ?? resolve(env.XDG_STATE_HOME || resolve(home, ".local", "state"), prefixBare),
|
|
72
|
-
cacheDir: env.ZIDANE_CACHE_DIR ?? resolve(env.XDG_CACHE_HOME || resolve(home, ".cache"), prefixBare),
|
|
73
|
-
mode: "xdg"
|
|
74
|
-
};
|
|
75
|
-
return single(legacyHomeDir, "default");
|
|
76
|
-
}
|
|
77
|
-
function single(base, mode) {
|
|
78
|
-
return {
|
|
79
|
-
configDir: base,
|
|
80
|
-
dataDir: base,
|
|
81
|
-
stateDir: base,
|
|
82
|
-
cacheDir: base,
|
|
83
|
-
mode
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
//#endregion
|
|
87
6
|
//#region src/plugins/boundary.ts
|
|
88
7
|
/**
|
|
89
8
|
* The Agent Plugins package boundary.
|
|
@@ -358,7 +277,7 @@ function validatePluginManifest(raw) {
|
|
|
358
277
|
});
|
|
359
278
|
if (!PLUGIN_NAME_RE.test(name)) return fatal(diagnostics, {
|
|
360
279
|
code: "manifest-name-invalid",
|
|
361
|
-
message: `Plugin name "${name}" is invalid
|
|
280
|
+
message: `Plugin name "${name}" is invalid. Use lowercase letters, digits, hyphens and periods, starting and ending alphanumeric, with no "--" or "..".`,
|
|
362
281
|
field: "name"
|
|
363
282
|
});
|
|
364
283
|
const manifest = {
|
|
@@ -417,7 +336,7 @@ function validatePluginManifest(raw) {
|
|
|
417
336
|
if (typeof ext !== "object" || ext === null || Array.isArray(ext)) diagnostics.push({
|
|
418
337
|
severity: "warning",
|
|
419
338
|
code: "manifest-extensions-not-object",
|
|
420
|
-
message: `plugin.json "extensions" must be an object (got ${describeJsonType(ext)})
|
|
339
|
+
message: `plugin.json "extensions" must be an object (got ${describeJsonType(ext)}), ignoring it.`,
|
|
421
340
|
field: "extensions"
|
|
422
341
|
});
|
|
423
342
|
else manifest.extensions = { ...ext };
|
|
@@ -427,7 +346,7 @@ function validatePluginManifest(raw) {
|
|
|
427
346
|
diagnostics.push({
|
|
428
347
|
severity: "warning",
|
|
429
348
|
code: "manifest-unknown-field",
|
|
430
|
-
message: `plugin.json has unknown top-level field "${key}"
|
|
349
|
+
message: `plugin.json has unknown top-level field "${key}", ignoring it. Client-specific data belongs under "extensions".`,
|
|
431
350
|
field: key
|
|
432
351
|
});
|
|
433
352
|
}
|
|
@@ -503,7 +422,7 @@ const SERVER_NAME_RE = /^[a-z0-9][\w-]{0,63}$/i;
|
|
|
503
422
|
/**
|
|
504
423
|
* Keys that hit a prototype setter instead of creating an own property.
|
|
505
424
|
* Same guard the extension registration paths apply to untrusted keys — see
|
|
506
|
-
* `isSafeRecordKey` in `../extensions/register.ts`. Assigning `__proto__` on
|
|
425
|
+
* `isSafeRecordKey` in `../extensions/register-context-shared.ts`. Assigning `__proto__` on
|
|
507
426
|
* an object literal silently DISCARDS the value, so without this an env var
|
|
508
427
|
* would just never reach the child process with nothing explaining why.
|
|
509
428
|
*/
|
|
@@ -534,7 +453,7 @@ async function loadPluginMcp(opts) {
|
|
|
534
453
|
diagnostics.push({
|
|
535
454
|
severity: "error",
|
|
536
455
|
code: "mcp-file-escapes-root",
|
|
537
|
-
message: `"${PLUGIN_MCP_FILE}"
|
|
456
|
+
message: `"${PLUGIN_MCP_FILE}" points outside the plugin root, so the plugin's MCP servers are off.`,
|
|
538
457
|
path
|
|
539
458
|
});
|
|
540
459
|
return {
|
|
@@ -629,7 +548,7 @@ function validateDocument(raw, specVersion) {
|
|
|
629
548
|
ok: false,
|
|
630
549
|
diagnostic: {
|
|
631
550
|
code: "mcp-schema-version-mismatch",
|
|
632
|
-
message: `"${PLUGIN_MCP_FILE}" targets Agent Plugins ${parsed.version} but plugin.json targets ${specVersion}
|
|
551
|
+
message: `"${PLUGIN_MCP_FILE}" targets Agent Plugins ${parsed.version} but plugin.json targets ${specVersion}. The versions must match.`,
|
|
633
552
|
field: "$schema"
|
|
634
553
|
}
|
|
635
554
|
};
|
|
@@ -661,11 +580,11 @@ async function buildServer(opts) {
|
|
|
661
580
|
ok: false,
|
|
662
581
|
diagnostic: {
|
|
663
582
|
code,
|
|
664
|
-
message: `Skipped MCP server "${name}"
|
|
583
|
+
message: `Skipped MCP server "${name}": ${message}`
|
|
665
584
|
}
|
|
666
585
|
});
|
|
667
586
|
const serverName = namePrefix ? `${namePrefix}-${name}` : name;
|
|
668
|
-
if (!SERVER_NAME_RE.test(serverName)) return reject("mcp-entry-name-invalid", namePrefix ? `its namespaced name "${serverName}"
|
|
587
|
+
if (!SERVER_NAME_RE.test(serverName)) return reject("mcp-entry-name-invalid", namePrefix ? `its namespaced name "${serverName}" can't be a tool prefix. The "${namePrefix}" namePrefix must be letters, digits, underscores or hyphens, and the two together at most 64 characters.` : "its name must be 1-64 characters of letters, digits, underscores or hyphens, starting alphanumeric.");
|
|
669
588
|
if (typeof entry !== "object" || entry === null || Array.isArray(entry)) return reject("mcp-entry-not-object", `its value must be an object (got ${describeJsonType(entry)}).`);
|
|
670
589
|
const obj = entry;
|
|
671
590
|
const type = typeof obj.type === "string" ? obj.type : void 0;
|
|
@@ -681,7 +600,7 @@ async function buildServer(opts) {
|
|
|
681
600
|
if (typeof command !== "string" || command.length === 0) return reject("mcp-entry-command-invalid", "a stdio server needs a non-empty \"command\".");
|
|
682
601
|
if (PLUGIN_VAR_RE.test(command)) {
|
|
683
602
|
PLUGIN_VAR_RE.lastIndex = 0;
|
|
684
|
-
return reject("mcp-entry-command-invalid", "placeholders are not expanded in \"command\"
|
|
603
|
+
return reject("mcp-entry-command-invalid", "placeholders are not expanded in \"command\". Use a \"./\"-relative path or a bare executable name.");
|
|
685
604
|
}
|
|
686
605
|
if (/\s/.test(command)) return reject("mcp-entry-command-invalid", `"command" must be a single executable token, not a command line ("${command}").`);
|
|
687
606
|
const resolvedCommand = await resolveCommand(command, boundary);
|
|
@@ -912,7 +831,7 @@ async function loadPluginSkills(opts) {
|
|
|
912
831
|
diagnostics.push({
|
|
913
832
|
severity: "error",
|
|
914
833
|
code: located.reason === "escaped" ? "skills-dir-escapes-root" : "skills-dir-wrong-kind",
|
|
915
|
-
message: located.reason === "escaped" ? `"${PLUGIN_SKILLS_DIR}/"
|
|
834
|
+
message: located.reason === "escaped" ? `"${PLUGIN_SKILLS_DIR}/" points outside the plugin root, so the plugin's skills are off.` : `"${PLUGIN_SKILLS_DIR}" is not a folder, so the plugin's skills are off.`,
|
|
916
835
|
path: dir
|
|
917
836
|
});
|
|
918
837
|
return {
|
|
@@ -945,7 +864,7 @@ async function loadPluginSkills(opts) {
|
|
|
945
864
|
if (childDir.reason === "escaped") diagnostics.push({
|
|
946
865
|
severity: "warning",
|
|
947
866
|
code: "skill-dir-escapes-root",
|
|
948
|
-
message: `Skipped "${PLUGIN_SKILLS_DIR}/${entry}"
|
|
867
|
+
message: `Skipped "${PLUGIN_SKILLS_DIR}/${entry}": it points outside the plugin root.`,
|
|
949
868
|
path: child
|
|
950
869
|
});
|
|
951
870
|
continue;
|
|
@@ -956,13 +875,13 @@ async function loadPluginSkills(opts) {
|
|
|
956
875
|
if (located2.reason === "escaped") diagnostics.push({
|
|
957
876
|
severity: "error",
|
|
958
877
|
code: "skill-escapes-root",
|
|
959
|
-
message: `Skipped skill "${entry}"
|
|
878
|
+
message: `Skipped skill "${entry}": its SKILL.md points outside the plugin root.`,
|
|
960
879
|
path: skillFile
|
|
961
880
|
});
|
|
962
881
|
else if (located2.reason === "wrong-kind") diagnostics.push({
|
|
963
882
|
severity: "warning",
|
|
964
883
|
code: "skill-file-wrong-kind",
|
|
965
|
-
message: `Skipped "${PLUGIN_SKILLS_DIR}/${entry}"
|
|
884
|
+
message: `Skipped "${PLUGIN_SKILLS_DIR}/${entry}": its SKILL.md is not a regular file.`,
|
|
966
885
|
path: skillFile
|
|
967
886
|
});
|
|
968
887
|
continue;
|
|
@@ -974,7 +893,7 @@ async function loadPluginSkills(opts) {
|
|
|
974
893
|
diagnostics.push({
|
|
975
894
|
severity: "error",
|
|
976
895
|
code: "skill-unreadable",
|
|
977
|
-
message: `Skipped skill "${entry}"
|
|
896
|
+
message: `Skipped skill "${entry}": can't read its SKILL.md: ${err instanceof Error ? err.message : String(err)}`,
|
|
978
897
|
path: located2.real
|
|
979
898
|
});
|
|
980
899
|
continue;
|
|
@@ -983,7 +902,7 @@ async function loadPluginSkills(opts) {
|
|
|
983
902
|
diagnostics.push({
|
|
984
903
|
severity: "error",
|
|
985
904
|
code: "skill-invalid",
|
|
986
|
-
message: `Skipped skill "${entry}"
|
|
905
|
+
message: `Skipped skill "${entry}": its SKILL.md is not a valid Agent Skill (missing description, or unparseable frontmatter).`,
|
|
987
906
|
path: located2.real
|
|
988
907
|
});
|
|
989
908
|
continue;
|
|
@@ -1070,7 +989,7 @@ async function loadAgentPlugin(dir, opts = {}) {
|
|
|
1070
989
|
if (!located.ok) return rejected(boundary.dir, boundary.root, [{
|
|
1071
990
|
severity: "error",
|
|
1072
991
|
code: located.reason === "escaped" ? "manifest-escapes-root" : "manifest-missing",
|
|
1073
|
-
message: located.reason === "escaped" ? `${PLUGIN_MANIFEST_FILE} resolves outside the plugin root.` : located.reason === "wrong-kind" ? `${PLUGIN_MANIFEST_FILE} exists but is not a regular file.` : `No ${PLUGIN_MANIFEST_FILE} at the plugin root
|
|
992
|
+
message: located.reason === "escaped" ? `${PLUGIN_MANIFEST_FILE} resolves outside the plugin root.` : located.reason === "wrong-kind" ? `${PLUGIN_MANIFEST_FILE} exists but is not a regular file.` : `No ${PLUGIN_MANIFEST_FILE} at the plugin root, so it isn't an Agent Plugin.`,
|
|
1074
993
|
path: manifestPath
|
|
1075
994
|
}]);
|
|
1076
995
|
let text;
|
|
@@ -1169,6 +1088,6 @@ function rejected(dir, root, diagnostics) {
|
|
|
1169
1088
|
};
|
|
1170
1089
|
}
|
|
1171
1090
|
//#endregion
|
|
1172
|
-
export { PLUGIN_MCP_FILE as a, validatePluginManifest as c, isSupportedAgentPluginsVersion as d, parseSchemaId as f, PLUGIN_SKILLS_DIR as i, SUPPORTED_AGENT_PLUGINS_VERSIONS as l, defaultPluginDataRoot as n, expandPluginVars as o,
|
|
1091
|
+
export { PLUGIN_MCP_FILE as a, validatePluginManifest as c, isSupportedAgentPluginsVersion as d, parseSchemaId as f, PLUGIN_SKILLS_DIR as i, SUPPORTED_AGENT_PLUGINS_VERSIONS as l, defaultPluginDataRoot as n, expandPluginVars as o, loadAgentPlugin as r, parsePluginManifest as s, PLUGIN_MANIFEST_FILE as t, agentPluginsSchemaId as u };
|
|
1173
1092
|
|
|
1174
|
-
//# sourceMappingURL=plugins-
|
|
1093
|
+
//# sourceMappingURL=plugins-DS7mahzZ.js.map
|