@mariozechner/pi-coding-agent 0.30.2 → 0.31.1
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 +251 -1
- package/README.md +105 -84
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +5 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/file-processor.d.ts +3 -3
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js +7 -10
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +18 -0
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +73 -34
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +464 -210
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +2 -2
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +2 -2
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/bash-executor.d.ts +2 -2
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +2 -2
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts +84 -0
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -0
- package/dist/core/compaction/branch-summarization.js +233 -0
- package/dist/core/compaction/branch-summarization.js.map +1 -0
- package/dist/core/{compaction.d.ts → compaction/compaction.d.ts} +38 -19
- package/dist/core/compaction/compaction.d.ts.map +1 -0
- package/dist/core/compaction/compaction.js +558 -0
- package/dist/core/compaction/compaction.js.map +1 -0
- package/dist/core/compaction/index.d.ts +7 -0
- package/dist/core/compaction/index.d.ts.map +1 -0
- package/dist/core/compaction/index.js +7 -0
- package/dist/core/compaction/index.js.map +1 -0
- package/dist/core/compaction/utils.d.ts +35 -0
- package/dist/core/compaction/utils.d.ts.map +1 -0
- package/dist/core/compaction/utils.js +138 -0
- package/dist/core/compaction/utils.js.map +1 -0
- package/dist/core/custom-tools/index.d.ts +2 -1
- package/dist/core/custom-tools/index.d.ts.map +1 -1
- package/dist/core/custom-tools/index.js +1 -0
- package/dist/core/custom-tools/index.js.map +1 -1
- package/dist/core/custom-tools/loader.d.ts.map +1 -1
- package/dist/core/custom-tools/loader.js +13 -80
- package/dist/core/custom-tools/loader.js.map +1 -1
- package/dist/core/custom-tools/types.d.ts +84 -59
- package/dist/core/custom-tools/types.d.ts.map +1 -1
- package/dist/core/custom-tools/types.js.map +1 -1
- package/dist/core/custom-tools/wrapper.d.ts +15 -0
- package/dist/core/custom-tools/wrapper.d.ts.map +1 -0
- package/dist/core/custom-tools/wrapper.js +23 -0
- package/dist/core/custom-tools/wrapper.js.map +1 -0
- package/dist/core/exec.d.ts +29 -0
- package/dist/core/exec.d.ts.map +1 -0
- package/dist/core/exec.js +71 -0
- package/dist/core/exec.js.map +1 -0
- package/dist/core/export-html/index.d.ts +17 -0
- package/dist/core/export-html/index.d.ts.map +1 -0
- package/dist/core/export-html/index.js +171 -0
- package/dist/core/export-html/index.js.map +1 -0
- package/dist/core/export-html/template.css +781 -0
- package/dist/core/export-html/template.html +54 -0
- package/dist/core/export-html/template.js +1185 -0
- package/dist/core/export-html/vendor/highlight.min.js +1213 -0
- package/dist/core/export-html/vendor/marked.min.js +6 -0
- package/dist/core/hooks/index.d.ts +4 -4
- package/dist/core/hooks/index.d.ts.map +1 -1
- package/dist/core/hooks/index.js +4 -3
- package/dist/core/hooks/index.js.map +1 -1
- package/dist/core/hooks/loader.d.ts +40 -5
- package/dist/core/hooks/loader.d.ts.map +1 -1
- package/dist/core/hooks/loader.js +43 -10
- package/dist/core/hooks/loader.js.map +1 -1
- package/dist/core/hooks/runner.d.ts +94 -18
- package/dist/core/hooks/runner.d.ts.map +1 -1
- package/dist/core/hooks/runner.js +199 -120
- package/dist/core/hooks/runner.js.map +1 -1
- package/dist/core/hooks/tool-wrapper.d.ts +1 -1
- package/dist/core/hooks/tool-wrapper.d.ts.map +1 -1
- package/dist/core/hooks/tool-wrapper.js +36 -19
- package/dist/core/hooks/tool-wrapper.js.map +1 -1
- package/dist/core/hooks/types.d.ts +407 -96
- package/dist/core/hooks/types.d.ts.map +1 -1
- package/dist/core/hooks/types.js.map +1 -1
- package/dist/core/index.d.ts +4 -3
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/messages.d.ts +44 -12
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +82 -34
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-registry.d.ts +5 -5
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +7 -7
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +7 -7
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +45 -14
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/sdk.d.ts +7 -10
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +88 -32
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +202 -36
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +565 -133
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +9 -3
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +13 -12
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +6 -3
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +33 -0
- package/dist/core/tools/edit-diff.d.ts.map +1 -0
- package/dist/core/tools/edit-diff.js +171 -0
- package/dist/core/tools/edit-diff.js.map +1 -0
- package/dist/core/tools/edit.d.ts +7 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +20 -95
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/find.d.ts +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts +1 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.d.ts +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/read.d.ts +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/write.d.ts +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js.map +1 -1
- package/dist/index.d.ts +8 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +22 -21
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +3 -4
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +6 -2
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts +12 -0
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -0
- package/dist/modes/interactive/components/bordered-loader.js +30 -0
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -0
- package/dist/modes/interactive/components/branch-summary-message.d.ts +14 -0
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/branch-summary-message.js +35 -0
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -0
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +14 -0
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/compaction-summary-message.js +36 -0
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -0
- package/dist/modes/interactive/components/dynamic-border.d.ts +5 -1
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.js +5 -1
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +12 -6
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +57 -25
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/hook-editor.d.ts +15 -0
- package/dist/modes/interactive/components/hook-editor.d.ts.map +1 -0
- package/dist/modes/interactive/components/hook-editor.js +95 -0
- package/dist/modes/interactive/components/hook-editor.js.map +1 -0
- package/dist/modes/interactive/components/hook-message.d.ts +18 -0
- package/dist/modes/interactive/components/hook-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/hook-message.js +80 -0
- package/dist/modes/interactive/components/hook-message.js.map +1 -0
- package/dist/modes/interactive/components/model-selector.d.ts +3 -3
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +6 -1
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +15 -2
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +70 -21
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts +52 -0
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/tree-selector.js +745 -0
- package/dist/modes/interactive/components/tree-selector.js.map +1 -0
- package/dist/modes/interactive/components/user-message-selector.d.ts +3 -3
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.js +1 -1
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message.d.ts +1 -1
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js +2 -5
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +29 -12
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +589 -208
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/dark.json +13 -1
- package/dist/modes/interactive/theme/light.json +13 -1
- package/dist/modes/interactive/theme/theme-schema.json +34 -0
- package/dist/modes/interactive/theme/theme.d.ts +20 -2
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +135 -2
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/print-mode.d.ts +3 -3
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +26 -20
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +13 -10
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +11 -10
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +88 -35
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +30 -11
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/utils/shell.d.ts +4 -2
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +36 -7
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/tools-manager.d.ts +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +2 -2
- package/dist/utils/tools-manager.js.map +1 -1
- package/docs/compaction.md +388 -0
- package/docs/custom-tools.md +146 -43
- package/docs/extension-loading.md +1004 -0
- package/docs/hooks.md +562 -596
- package/docs/rpc.md +33 -19
- package/docs/sdk.md +93 -21
- package/docs/session-tree-plan.md +441 -0
- package/docs/session.md +172 -21
- package/docs/skills.md +2 -0
- package/docs/theme.md +31 -2
- package/docs/tree.md +197 -0
- package/docs/tui.md +343 -0
- package/examples/README.md +1 -9
- package/examples/custom-tools/hello/index.ts +4 -3
- package/examples/custom-tools/question/index.ts +4 -4
- package/examples/custom-tools/subagent/index.ts +7 -6
- package/examples/custom-tools/todo/index.ts +11 -5
- package/examples/hooks/README.md +29 -71
- package/examples/hooks/auto-commit-on-exit.ts +8 -9
- package/examples/hooks/confirm-destructive.ts +29 -30
- package/examples/hooks/custom-compaction.ts +20 -21
- package/examples/hooks/dirty-repo-guard.ts +41 -40
- package/examples/hooks/file-trigger.ts +10 -5
- package/examples/hooks/git-checkpoint.ts +16 -12
- package/examples/hooks/handoff.ts +150 -0
- package/examples/hooks/permission-gate.ts +1 -1
- package/examples/hooks/protected-paths.ts +1 -1
- package/examples/hooks/qna.ts +119 -0
- package/examples/hooks/snake.ts +343 -0
- package/examples/hooks/status-line.ts +40 -0
- package/examples/sdk/01-minimal.ts +1 -1
- package/examples/sdk/02-custom-model.ts +1 -1
- package/examples/sdk/03-custom-prompt.ts +1 -1
- package/examples/sdk/04-skills.ts +1 -1
- package/examples/sdk/05-tools.ts +4 -4
- package/examples/sdk/06-hooks.ts +1 -1
- package/examples/sdk/07-context-files.ts +1 -1
- package/examples/sdk/08-slash-commands.ts +6 -1
- package/examples/sdk/09-api-keys-and-oauth.ts +1 -1
- package/examples/sdk/10-settings.ts +1 -1
- package/examples/sdk/11-sessions.ts +1 -1
- package/examples/sdk/12-full-control.ts +4 -7
- package/package.json +6 -6
- package/dist/core/compaction.d.ts.map +0 -1
- package/dist/core/compaction.js +0 -412
- package/dist/core/compaction.js.map +0 -1
- package/dist/core/export-html.d.ts +0 -23
- package/dist/core/export-html.d.ts.map +0 -1
- package/dist/core/export-html.js +0 -1185
- package/dist/core/export-html.js.map +0 -1
- package/dist/modes/interactive/components/compaction.d.ts +0 -15
- package/dist/modes/interactive/components/compaction.d.ts.map +0 -1
- package/dist/modes/interactive/components/compaction.js +0 -41
- package/dist/modes/interactive/components/compaction.js.map +0 -1
- package/docs/hooks-v2.md +0 -385
- package/docs/session-tree.md +0 -452
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-wrapper.js","sourceRoot":"","sources":["../../../src/core/hooks/tool-wrapper.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAI,IAAuB,EAAE,UAAsB,EAAqB;IACxG,OAAO;QACN,GAAG,IAAI;QACP,OAAO,EAAE,KAAK,EACb,UAAkB,EAClB,MAA+B,EAC/B,MAAoB,EACpB,QAAqC,EACpC,EAAE,CAAC;YACJ,mDAAmD;YACnD,yDAAyD;YACzD,IAAI,UAAU,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC;gBACzC,IAAI,CAAC;oBACJ,MAAM,UAAU,GAAG,CAAC,MAAM,UAAU,CAAC,YAAY,CAAC;wBACjD,IAAI,EAAE,WAAW;wBACjB,QAAQ,EAAE,IAAI,CAAC,IAAI;wBACnB,UAAU;wBACV,KAAK,EAAE,MAAM;qBACb,CAAC,CAAoC,CAAC;oBAEvC,IAAI,UAAU,EAAE,KAAK,EAAE,CAAC;wBACvB,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,IAAI,sCAAsC,CAAC;wBAC3E,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;oBACzB,CAAC;gBACF,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACd,+CAA+C;oBAC/C,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;wBAC1B,MAAM,GAAG,CAAC;oBACX,CAAC;oBACD,MAAM,IAAI,KAAK,CAAC,oCAAoC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACpE,CAAC;YACF,CAAC;YAED,sEAAsE;YACtE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"tool-wrapper.js","sourceRoot":"","sources":["../../../src/core/hooks/tool-wrapper.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAI,IAAuB,EAAE,UAAsB,EAAqB;IACxG,OAAO;QACN,GAAG,IAAI;QACP,OAAO,EAAE,KAAK,EACb,UAAkB,EAClB,MAA+B,EAC/B,MAAoB,EACpB,QAAqC,EACpC,EAAE,CAAC;YACJ,mDAAmD;YACnD,yDAAyD;YACzD,IAAI,UAAU,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC;gBACzC,IAAI,CAAC;oBACJ,MAAM,UAAU,GAAG,CAAC,MAAM,UAAU,CAAC,YAAY,CAAC;wBACjD,IAAI,EAAE,WAAW;wBACjB,QAAQ,EAAE,IAAI,CAAC,IAAI;wBACnB,UAAU;wBACV,KAAK,EAAE,MAAM;qBACb,CAAC,CAAoC,CAAC;oBAEvC,IAAI,UAAU,EAAE,KAAK,EAAE,CAAC;wBACvB,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,IAAI,sCAAsC,CAAC;wBAC3E,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;oBACzB,CAAC;gBACF,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACd,+CAA+C;oBAC/C,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;wBAC1B,MAAM,GAAG,CAAC;oBACX,CAAC;oBACD,MAAM,IAAI,KAAK,CAAC,oCAAoC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACpE,CAAC;YACF,CAAC;YAED,sEAAsE;YACtE,IAAI,CAAC;gBACJ,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;gBAExE,uDAAuD;gBACvD,IAAI,UAAU,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE,CAAC;oBAC3C,MAAM,YAAY,GAAG,CAAC,MAAM,UAAU,CAAC,IAAI,CAAC;wBAC3C,IAAI,EAAE,aAAa;wBACnB,QAAQ,EAAE,IAAI,CAAC,IAAI;wBACnB,UAAU;wBACV,KAAK,EAAE,MAAM;wBACb,OAAO,EAAE,MAAM,CAAC,OAAO;wBACvB,OAAO,EAAE,MAAM,CAAC,OAAO;wBACvB,OAAO,EAAE,KAAK;qBACd,CAAC,CAAsC,CAAC;oBAEzC,6BAA6B;oBAC7B,IAAI,YAAY,EAAE,CAAC;wBAClB,OAAO;4BACN,OAAO,EAAE,YAAY,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO;4BAC/C,OAAO,EAAE,CAAC,YAAY,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAM;yBACtD,CAAC;oBACH,CAAC;gBACF,CAAC;gBAED,OAAO,MAAM,CAAC;YACf,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,kEAAkE;gBAClE,IAAI,UAAU,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE,CAAC;oBAC3C,MAAM,UAAU,CAAC,IAAI,CAAC;wBACrB,IAAI,EAAE,aAAa;wBACnB,QAAQ,EAAE,IAAI,CAAC,IAAI;wBACnB,UAAU;wBACV,KAAK,EAAE,MAAM;wBACb,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;wBACnF,OAAO,EAAE,SAAS;wBAClB,OAAO,EAAE,IAAI;qBACb,CAAC,CAAC;gBACJ,CAAC;gBACD,MAAM,GAAG,CAAC,CAAC,yCAAyC;YACrD,CAAC;QAAA,CACD;KACD,CAAC;AAAA,CACF;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAI,KAA0B,EAAE,UAAsB,EAAuB;IAC9G,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;AAAA,CAChE","sourcesContent":["/**\n * Tool wrapper - wraps tools with hook callbacks for interception.\n */\n\nimport type { AgentTool, AgentToolUpdateCallback } from \"@mariozechner/pi-agent-core\";\nimport type { HookRunner } from \"./runner.js\";\nimport type { ToolCallEventResult, ToolResultEventResult } from \"./types.js\";\n\n/**\n * Wrap a tool with hook callbacks.\n * - Emits tool_call event before execution (can block)\n * - Emits tool_result event after execution (can modify result)\n * - Forwards onUpdate callback to wrapped tool for progress streaming\n */\nexport function wrapToolWithHooks<T>(tool: AgentTool<any, T>, hookRunner: HookRunner): AgentTool<any, T> {\n\treturn {\n\t\t...tool,\n\t\texecute: async (\n\t\t\ttoolCallId: string,\n\t\t\tparams: Record<string, unknown>,\n\t\t\tsignal?: AbortSignal,\n\t\t\tonUpdate?: AgentToolUpdateCallback<T>,\n\t\t) => {\n\t\t\t// Emit tool_call event - hooks can block execution\n\t\t\t// If hook errors/times out, block by default (fail-safe)\n\t\t\tif (hookRunner.hasHandlers(\"tool_call\")) {\n\t\t\t\ttry {\n\t\t\t\t\tconst callResult = (await hookRunner.emitToolCall({\n\t\t\t\t\t\ttype: \"tool_call\",\n\t\t\t\t\t\ttoolName: tool.name,\n\t\t\t\t\t\ttoolCallId,\n\t\t\t\t\t\tinput: params,\n\t\t\t\t\t})) as ToolCallEventResult | undefined;\n\n\t\t\t\t\tif (callResult?.block) {\n\t\t\t\t\t\tconst reason = callResult.reason || \"Tool execution was blocked by a hook\";\n\t\t\t\t\t\tthrow new Error(reason);\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\t// Hook error or block - throw to mark as error\n\t\t\t\t\tif (err instanceof Error) {\n\t\t\t\t\t\tthrow err;\n\t\t\t\t\t}\n\t\t\t\t\tthrow new Error(`Hook failed, blocking execution: ${String(err)}`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Execute the actual tool, forwarding onUpdate for progress streaming\n\t\t\ttry {\n\t\t\t\tconst result = await tool.execute(toolCallId, params, signal, onUpdate);\n\n\t\t\t\t// Emit tool_result event - hooks can modify the result\n\t\t\t\tif (hookRunner.hasHandlers(\"tool_result\")) {\n\t\t\t\t\tconst resultResult = (await hookRunner.emit({\n\t\t\t\t\t\ttype: \"tool_result\",\n\t\t\t\t\t\ttoolName: tool.name,\n\t\t\t\t\t\ttoolCallId,\n\t\t\t\t\t\tinput: params,\n\t\t\t\t\t\tcontent: result.content,\n\t\t\t\t\t\tdetails: result.details,\n\t\t\t\t\t\tisError: false,\n\t\t\t\t\t})) as ToolResultEventResult | undefined;\n\n\t\t\t\t\t// Apply modifications if any\n\t\t\t\t\tif (resultResult) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcontent: resultResult.content ?? result.content,\n\t\t\t\t\t\t\tdetails: (resultResult.details ?? result.details) as T,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\t\t\t} catch (err) {\n\t\t\t\t// Emit tool_result event for errors so hooks can observe failures\n\t\t\t\tif (hookRunner.hasHandlers(\"tool_result\")) {\n\t\t\t\t\tawait hookRunner.emit({\n\t\t\t\t\t\ttype: \"tool_result\",\n\t\t\t\t\t\ttoolName: tool.name,\n\t\t\t\t\t\ttoolCallId,\n\t\t\t\t\t\tinput: params,\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: err instanceof Error ? err.message : String(err) }],\n\t\t\t\t\t\tdetails: undefined,\n\t\t\t\t\t\tisError: true,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tthrow err; // Re-throw original error for agent-loop\n\t\t\t}\n\t\t},\n\t};\n}\n\n/**\n * Wrap all tools with hook callbacks.\n */\nexport function wrapToolsWithHooks<T>(tools: AgentTool<any, T>[], hookRunner: HookRunner): AgentTool<any, T>[] {\n\treturn tools.map((tool) => wrapToolWithHooks(tool, hookRunner));\n}\n"]}
|
|
@@ -4,27 +4,18 @@
|
|
|
4
4
|
* Hooks are TypeScript modules that can subscribe to agent lifecycle events
|
|
5
5
|
* and interact with the user via UI primitives.
|
|
6
6
|
*/
|
|
7
|
-
import type {
|
|
8
|
-
import type { ImageContent, Model, TextContent, ToolResultMessage } from "@mariozechner/pi-ai";
|
|
9
|
-
import type {
|
|
10
|
-
import type {
|
|
7
|
+
import type { AgentMessage } from "@mariozechner/pi-agent-core";
|
|
8
|
+
import type { ImageContent, Message, Model, TextContent, ToolResultMessage } from "@mariozechner/pi-ai";
|
|
9
|
+
import type { Component, TUI } from "@mariozechner/pi-tui";
|
|
10
|
+
import type { Theme } from "../../modes/interactive/theme/theme.js";
|
|
11
|
+
import type { CompactionPreparation, CompactionResult } from "../compaction/index.js";
|
|
12
|
+
import type { ExecOptions, ExecResult } from "../exec.js";
|
|
13
|
+
import type { HookMessage } from "../messages.js";
|
|
14
|
+
import type { ModelRegistry } from "../model-registry.js";
|
|
15
|
+
import type { BranchSummaryEntry, CompactionEntry, ReadonlySessionManager, SessionEntry, SessionManager } from "../session-manager.js";
|
|
16
|
+
import type { EditToolDetails } from "../tools/edit.js";
|
|
11
17
|
import type { BashToolDetails, FindToolDetails, GrepToolDetails, LsToolDetails, ReadToolDetails } from "../tools/index.js";
|
|
12
|
-
|
|
13
|
-
* Result of executing a command via ctx.exec()
|
|
14
|
-
*/
|
|
15
|
-
export interface ExecResult {
|
|
16
|
-
stdout: string;
|
|
17
|
-
stderr: string;
|
|
18
|
-
code: number;
|
|
19
|
-
/** True if the process was killed due to signal or timeout */
|
|
20
|
-
killed?: boolean;
|
|
21
|
-
}
|
|
22
|
-
export interface ExecOptions {
|
|
23
|
-
/** AbortSignal to cancel the process */
|
|
24
|
-
signal?: AbortSignal;
|
|
25
|
-
/** Timeout in milliseconds */
|
|
26
|
-
timeout?: number;
|
|
27
|
-
}
|
|
18
|
+
export type { ExecOptions, ExecResult } from "../exec.js";
|
|
28
19
|
/**
|
|
29
20
|
* UI context for hooks to request interactive UI from the harness.
|
|
30
21
|
* Each mode (interactive, RPC, print) provides its own implementation.
|
|
@@ -36,7 +27,7 @@ export interface HookUIContext {
|
|
|
36
27
|
* @param options - Array of string options
|
|
37
28
|
* @returns Selected option string, or null if cancelled
|
|
38
29
|
*/
|
|
39
|
-
select(title: string, options: string[]): Promise<string |
|
|
30
|
+
select(title: string, options: string[]): Promise<string | undefined>;
|
|
40
31
|
/**
|
|
41
32
|
* Show a confirmation dialog.
|
|
42
33
|
* @returns true if confirmed, false if cancelled
|
|
@@ -44,85 +35,271 @@ export interface HookUIContext {
|
|
|
44
35
|
confirm(title: string, message: string): Promise<boolean>;
|
|
45
36
|
/**
|
|
46
37
|
* Show a text input dialog.
|
|
47
|
-
* @returns User input, or
|
|
38
|
+
* @returns User input, or undefined if cancelled
|
|
48
39
|
*/
|
|
49
|
-
input(title: string, placeholder?: string): Promise<string |
|
|
40
|
+
input(title: string, placeholder?: string): Promise<string | undefined>;
|
|
50
41
|
/**
|
|
51
42
|
* Show a notification to the user.
|
|
52
43
|
*/
|
|
53
44
|
notify(message: string, type?: "info" | "warning" | "error"): void;
|
|
45
|
+
/**
|
|
46
|
+
* Set status text in the footer/status bar.
|
|
47
|
+
* Pass undefined as text to clear the status for this key.
|
|
48
|
+
* Text can include ANSI escape codes for styling.
|
|
49
|
+
* Note: Newlines, tabs, and carriage returns are replaced with spaces.
|
|
50
|
+
* The combined status line is truncated to terminal width.
|
|
51
|
+
* @param key - Unique key to identify this status (e.g., hook name)
|
|
52
|
+
* @param text - Status text to display, or undefined to clear
|
|
53
|
+
*/
|
|
54
|
+
setStatus(key: string, text: string | undefined): void;
|
|
55
|
+
/**
|
|
56
|
+
* Show a custom component with keyboard focus.
|
|
57
|
+
* The factory receives TUI, theme, and a done() callback to close the component.
|
|
58
|
+
* Can be async for fire-and-forget work (don't await the work, just start it).
|
|
59
|
+
*
|
|
60
|
+
* @param factory - Function that creates the component. Call done() when finished.
|
|
61
|
+
* @returns Promise that resolves with the value passed to done()
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* // Sync factory
|
|
65
|
+
* const result = await ctx.ui.custom((tui, theme, done) => {
|
|
66
|
+
* const component = new MyComponent(tui, theme);
|
|
67
|
+
* component.onFinish = (value) => done(value);
|
|
68
|
+
* return component;
|
|
69
|
+
* });
|
|
70
|
+
*
|
|
71
|
+
* // Async factory with fire-and-forget work
|
|
72
|
+
* const result = await ctx.ui.custom(async (tui, theme, done) => {
|
|
73
|
+
* const loader = new CancellableLoader(tui, theme.fg("accent"), theme.fg("muted"), "Working...");
|
|
74
|
+
* loader.onAbort = () => done(null);
|
|
75
|
+
* doWork(loader.signal).then(done); // Don't await - fire and forget
|
|
76
|
+
* return loader;
|
|
77
|
+
* });
|
|
78
|
+
*/
|
|
79
|
+
custom<T>(factory: (tui: TUI, theme: Theme, done: (result: T) => void) => (Component & {
|
|
80
|
+
dispose?(): void;
|
|
81
|
+
}) | Promise<Component & {
|
|
82
|
+
dispose?(): void;
|
|
83
|
+
}>): Promise<T>;
|
|
84
|
+
/**
|
|
85
|
+
* Set the text in the core input editor.
|
|
86
|
+
* Use this to pre-fill the input box with generated content (e.g., prompt templates, extracted questions).
|
|
87
|
+
* @param text - Text to set in the editor
|
|
88
|
+
*/
|
|
89
|
+
setEditorText(text: string): void;
|
|
90
|
+
/**
|
|
91
|
+
* Get the current text from the core input editor.
|
|
92
|
+
* @returns Current editor text
|
|
93
|
+
*/
|
|
94
|
+
getEditorText(): string;
|
|
95
|
+
/**
|
|
96
|
+
* Show a multi-line editor for text editing.
|
|
97
|
+
* Supports Ctrl+G to open external editor ($VISUAL or $EDITOR).
|
|
98
|
+
* @param title - Title describing what is being edited
|
|
99
|
+
* @param prefill - Optional initial text
|
|
100
|
+
* @returns Edited text, or undefined if cancelled (Escape)
|
|
101
|
+
*/
|
|
102
|
+
editor(title: string, prefill?: string): Promise<string | undefined>;
|
|
103
|
+
/**
|
|
104
|
+
* Get the current theme for styling text with ANSI codes.
|
|
105
|
+
* Use theme.fg() and theme.bg() to style status text.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* const theme = ctx.ui.theme;
|
|
109
|
+
* ctx.ui.setStatus("my-hook", theme.fg("success", "✓") + " Ready");
|
|
110
|
+
*/
|
|
111
|
+
readonly theme: Theme;
|
|
54
112
|
}
|
|
55
113
|
/**
|
|
56
114
|
* Context passed to hook event handlers.
|
|
115
|
+
* For command handlers, see HookCommandContext which extends this with session control methods.
|
|
57
116
|
*/
|
|
58
|
-
export interface
|
|
59
|
-
/** Execute a command and return stdout/stderr/code */
|
|
60
|
-
exec(command: string, args: string[], options?: ExecOptions): Promise<ExecResult>;
|
|
117
|
+
export interface HookContext {
|
|
61
118
|
/** UI methods for user interaction */
|
|
62
119
|
ui: HookUIContext;
|
|
63
120
|
/** Whether UI is available (false in print mode) */
|
|
64
121
|
hasUI: boolean;
|
|
65
122
|
/** Current working directory */
|
|
66
123
|
cwd: string;
|
|
67
|
-
/**
|
|
68
|
-
|
|
124
|
+
/** Session manager (read-only) - use pi.sendMessage()/pi.appendEntry() for writes */
|
|
125
|
+
sessionManager: ReadonlySessionManager;
|
|
126
|
+
/** Model registry - use for API key resolution and model retrieval */
|
|
127
|
+
modelRegistry: ModelRegistry;
|
|
128
|
+
/** Current model (may be undefined if no model is selected yet) */
|
|
129
|
+
model: Model<any> | undefined;
|
|
130
|
+
/** Whether the agent is idle (not streaming) */
|
|
131
|
+
isIdle(): boolean;
|
|
132
|
+
/** Abort the current agent operation (fire-and-forget, does not wait) */
|
|
133
|
+
abort(): void;
|
|
134
|
+
/** Whether there are queued messages waiting to be processed */
|
|
135
|
+
hasQueuedMessages(): boolean;
|
|
69
136
|
}
|
|
70
137
|
/**
|
|
71
|
-
*
|
|
72
|
-
|
|
73
|
-
interface SessionEventBase {
|
|
74
|
-
type: "session";
|
|
75
|
-
/** All session entries (including pre-compaction history) */
|
|
76
|
-
entries: SessionEntry[];
|
|
77
|
-
/** Current session file path, or null in --no-session mode */
|
|
78
|
-
sessionFile: string | null;
|
|
79
|
-
/** Previous session file path, or null for "start" and "new" */
|
|
80
|
-
previousSessionFile: string | null;
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Event data for session events.
|
|
84
|
-
* Discriminated union based on reason.
|
|
85
|
-
*
|
|
86
|
-
* Lifecycle:
|
|
87
|
-
* - start: Initial session load
|
|
88
|
-
* - before_switch / switch: Session switch (e.g., /resume command)
|
|
89
|
-
* - before_new / new: New session (e.g., /new command)
|
|
90
|
-
* - before_branch / branch: Session branch (e.g., /branch command)
|
|
91
|
-
* - before_compact / compact: Before/after context compaction
|
|
92
|
-
* - shutdown: Process exit (SIGINT/SIGTERM)
|
|
138
|
+
* Extended context for slash command handlers.
|
|
139
|
+
* Includes session control methods that are only safe in user-initiated commands.
|
|
93
140
|
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
141
|
+
* These methods are not available in event handlers because they can cause
|
|
142
|
+
* deadlocks when called from within the agent loop (e.g., tool_call, context events).
|
|
96
143
|
*/
|
|
97
|
-
export
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
144
|
+
export interface HookCommandContext extends HookContext {
|
|
145
|
+
/** Wait for the agent to finish streaming */
|
|
146
|
+
waitForIdle(): Promise<void>;
|
|
147
|
+
/**
|
|
148
|
+
* Start a new session, optionally with a setup callback to initialize it.
|
|
149
|
+
* The setup callback receives a writable SessionManager for the new session.
|
|
150
|
+
*
|
|
151
|
+
* @param options.parentSession - Path to parent session for lineage tracking
|
|
152
|
+
* @param options.setup - Async callback to initialize the new session (e.g., append messages)
|
|
153
|
+
* @returns Object with `cancelled: true` if a hook cancelled the new session
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* // Handoff: summarize current session and start fresh with context
|
|
157
|
+
* await ctx.newSession({
|
|
158
|
+
* parentSession: ctx.sessionManager.getSessionFile(),
|
|
159
|
+
* setup: async (sm) => {
|
|
160
|
+
* sm.appendMessage({ role: "user", content: [{ type: "text", text: summary }] });
|
|
161
|
+
* }
|
|
162
|
+
* });
|
|
163
|
+
*/
|
|
164
|
+
newSession(options?: {
|
|
165
|
+
parentSession?: string;
|
|
166
|
+
setup?: (sessionManager: SessionManager) => Promise<void>;
|
|
167
|
+
}): Promise<{
|
|
168
|
+
cancelled: boolean;
|
|
169
|
+
}>;
|
|
170
|
+
/**
|
|
171
|
+
* Branch from a specific entry, creating a new session file.
|
|
172
|
+
*
|
|
173
|
+
* @param entryId - ID of the entry to branch from
|
|
174
|
+
* @returns Object with `cancelled: true` if a hook cancelled the branch
|
|
175
|
+
*/
|
|
176
|
+
branch(entryId: string): Promise<{
|
|
177
|
+
cancelled: boolean;
|
|
178
|
+
}>;
|
|
179
|
+
/**
|
|
180
|
+
* Navigate to a different point in the session tree (in-place).
|
|
181
|
+
*
|
|
182
|
+
* @param targetId - ID of the entry to navigate to
|
|
183
|
+
* @param options.summarize - Whether to summarize the abandoned branch
|
|
184
|
+
* @returns Object with `cancelled: true` if a hook cancelled the navigation
|
|
185
|
+
*/
|
|
186
|
+
navigateTree(targetId: string, options?: {
|
|
187
|
+
summarize?: boolean;
|
|
188
|
+
}): Promise<{
|
|
189
|
+
cancelled: boolean;
|
|
190
|
+
}>;
|
|
191
|
+
}
|
|
192
|
+
/** Fired on initial session load */
|
|
193
|
+
export interface SessionStartEvent {
|
|
194
|
+
type: "session_start";
|
|
195
|
+
}
|
|
196
|
+
/** Fired before switching to another session (can be cancelled) */
|
|
197
|
+
export interface SessionBeforeSwitchEvent {
|
|
198
|
+
type: "session_before_switch";
|
|
199
|
+
/** Reason for the switch */
|
|
200
|
+
reason: "new" | "resume";
|
|
201
|
+
/** Session file we're switching to (only for "resume") */
|
|
202
|
+
targetSessionFile?: string;
|
|
203
|
+
}
|
|
204
|
+
/** Fired after switching to another session */
|
|
205
|
+
export interface SessionSwitchEvent {
|
|
206
|
+
type: "session_switch";
|
|
207
|
+
/** Reason for the switch */
|
|
208
|
+
reason: "new" | "resume";
|
|
209
|
+
/** Session file we came from */
|
|
210
|
+
previousSessionFile: string | undefined;
|
|
211
|
+
}
|
|
212
|
+
/** Fired before branching a session (can be cancelled) */
|
|
213
|
+
export interface SessionBeforeBranchEvent {
|
|
214
|
+
type: "session_before_branch";
|
|
215
|
+
/** ID of the entry to branch from */
|
|
216
|
+
entryId: string;
|
|
217
|
+
}
|
|
218
|
+
/** Fired after branching a session */
|
|
219
|
+
export interface SessionBranchEvent {
|
|
220
|
+
type: "session_branch";
|
|
221
|
+
previousSessionFile: string | undefined;
|
|
222
|
+
}
|
|
223
|
+
/** Fired before context compaction (can be cancelled or customized) */
|
|
224
|
+
export interface SessionBeforeCompactEvent {
|
|
225
|
+
type: "session_before_compact";
|
|
226
|
+
/** Compaction preparation with messages to summarize, file ops, previous summary, etc. */
|
|
227
|
+
preparation: CompactionPreparation;
|
|
228
|
+
/** Branch entries (root to current leaf). Use to inspect custom state or previous compactions. */
|
|
229
|
+
branchEntries: SessionEntry[];
|
|
230
|
+
/** Optional user-provided instructions for the summary */
|
|
113
231
|
customInstructions?: string;
|
|
114
|
-
model: Model<any>;
|
|
115
|
-
/** Resolve API key for any model (checks settings, OAuth, env vars) */
|
|
116
|
-
resolveApiKey: (model: Model<any>) => Promise<string | undefined>;
|
|
117
232
|
/** Abort signal - hooks should pass this to LLM calls and check it periodically */
|
|
118
233
|
signal: AbortSignal;
|
|
119
|
-
}
|
|
120
|
-
|
|
234
|
+
}
|
|
235
|
+
/** Fired after context compaction */
|
|
236
|
+
export interface SessionCompactEvent {
|
|
237
|
+
type: "session_compact";
|
|
121
238
|
compactionEntry: CompactionEntry;
|
|
122
|
-
tokensBefore: number;
|
|
123
239
|
/** Whether the compaction entry was provided by a hook */
|
|
124
240
|
fromHook: boolean;
|
|
125
|
-
}
|
|
241
|
+
}
|
|
242
|
+
/** Fired on process exit (SIGINT/SIGTERM) */
|
|
243
|
+
export interface SessionShutdownEvent {
|
|
244
|
+
type: "session_shutdown";
|
|
245
|
+
}
|
|
246
|
+
/** Preparation data for tree navigation (used by session_before_tree event) */
|
|
247
|
+
export interface TreePreparation {
|
|
248
|
+
/** Node being switched to */
|
|
249
|
+
targetId: string;
|
|
250
|
+
/** Current active leaf (being abandoned), null if no current position */
|
|
251
|
+
oldLeafId: string | null;
|
|
252
|
+
/** Common ancestor of target and old leaf, null if no common ancestor */
|
|
253
|
+
commonAncestorId: string | null;
|
|
254
|
+
/** Entries to summarize (old leaf back to common ancestor or compaction) */
|
|
255
|
+
entriesToSummarize: SessionEntry[];
|
|
256
|
+
/** Whether user chose to summarize */
|
|
257
|
+
userWantsSummary: boolean;
|
|
258
|
+
}
|
|
259
|
+
/** Fired before navigating to a different node in the session tree (can be cancelled) */
|
|
260
|
+
export interface SessionBeforeTreeEvent {
|
|
261
|
+
type: "session_before_tree";
|
|
262
|
+
/** Preparation data for the navigation */
|
|
263
|
+
preparation: TreePreparation;
|
|
264
|
+
/** Abort signal - honors Escape during summarization (model available via ctx.model) */
|
|
265
|
+
signal: AbortSignal;
|
|
266
|
+
}
|
|
267
|
+
/** Fired after navigating to a different node in the session tree */
|
|
268
|
+
export interface SessionTreeEvent {
|
|
269
|
+
type: "session_tree";
|
|
270
|
+
/** The new active leaf, null if navigated to before first entry */
|
|
271
|
+
newLeafId: string | null;
|
|
272
|
+
/** Previous active leaf, null if there was no position */
|
|
273
|
+
oldLeafId: string | null;
|
|
274
|
+
/** Branch summary entry if one was created */
|
|
275
|
+
summaryEntry?: BranchSummaryEntry;
|
|
276
|
+
/** Whether summary came from hook */
|
|
277
|
+
fromHook?: boolean;
|
|
278
|
+
}
|
|
279
|
+
/** Union of all session event types */
|
|
280
|
+
export type SessionEvent = SessionStartEvent | SessionBeforeSwitchEvent | SessionSwitchEvent | SessionBeforeBranchEvent | SessionBranchEvent | SessionBeforeCompactEvent | SessionCompactEvent | SessionShutdownEvent | SessionBeforeTreeEvent | SessionTreeEvent;
|
|
281
|
+
/**
|
|
282
|
+
* Event data for context event.
|
|
283
|
+
* Fired before each LLM call, allowing hooks to modify context non-destructively.
|
|
284
|
+
* Original session messages are NOT modified - only the messages sent to the LLM are affected.
|
|
285
|
+
*/
|
|
286
|
+
export interface ContextEvent {
|
|
287
|
+
type: "context";
|
|
288
|
+
/** Messages about to be sent to the LLM (deep copy, safe to modify) */
|
|
289
|
+
messages: AgentMessage[];
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Event data for before_agent_start event.
|
|
293
|
+
* Fired after user submits a prompt but before the agent loop starts.
|
|
294
|
+
* Allows hooks to inject context that will be persisted and visible in TUI.
|
|
295
|
+
*/
|
|
296
|
+
export interface BeforeAgentStartEvent {
|
|
297
|
+
type: "before_agent_start";
|
|
298
|
+
/** The user's prompt text */
|
|
299
|
+
prompt: string;
|
|
300
|
+
/** Any images attached to the prompt */
|
|
301
|
+
images?: ImageContent[];
|
|
302
|
+
}
|
|
126
303
|
/**
|
|
127
304
|
* Event data for agent_start event.
|
|
128
305
|
* Fired when an agent loop starts (once per user prompt).
|
|
@@ -135,7 +312,7 @@ export interface AgentStartEvent {
|
|
|
135
312
|
*/
|
|
136
313
|
export interface AgentEndEvent {
|
|
137
314
|
type: "agent_end";
|
|
138
|
-
messages:
|
|
315
|
+
messages: AgentMessage[];
|
|
139
316
|
}
|
|
140
317
|
/**
|
|
141
318
|
* Event data for turn_start event.
|
|
@@ -151,7 +328,7 @@ export interface TurnStartEvent {
|
|
|
151
328
|
export interface TurnEndEvent {
|
|
152
329
|
type: "turn_end";
|
|
153
330
|
turnIndex: number;
|
|
154
|
-
message:
|
|
331
|
+
message: AgentMessage;
|
|
155
332
|
toolResults: ToolResultMessage[];
|
|
156
333
|
}
|
|
157
334
|
/**
|
|
@@ -194,7 +371,7 @@ export interface ReadToolResultEvent extends ToolResultEventBase {
|
|
|
194
371
|
/** Tool result event for edit tool */
|
|
195
372
|
export interface EditToolResultEvent extends ToolResultEventBase {
|
|
196
373
|
toolName: "edit";
|
|
197
|
-
details: undefined;
|
|
374
|
+
details: EditToolDetails | undefined;
|
|
198
375
|
}
|
|
199
376
|
/** Tool result event for write tool */
|
|
200
377
|
export interface WriteToolResultEvent extends ToolResultEventBase {
|
|
@@ -237,7 +414,15 @@ export declare function isLsToolResult(e: ToolResultEvent): e is LsToolResultEve
|
|
|
237
414
|
/**
|
|
238
415
|
* Union of all hook event types.
|
|
239
416
|
*/
|
|
240
|
-
export type HookEvent = SessionEvent | AgentStartEvent | AgentEndEvent | TurnStartEvent | TurnEndEvent | ToolCallEvent | ToolResultEvent;
|
|
417
|
+
export type HookEvent = SessionEvent | ContextEvent | BeforeAgentStartEvent | AgentStartEvent | AgentEndEvent | TurnStartEvent | TurnEndEvent | ToolCallEvent | ToolResultEvent;
|
|
418
|
+
/**
|
|
419
|
+
* Return type for context event handlers.
|
|
420
|
+
* Allows hooks to modify messages before they're sent to the LLM.
|
|
421
|
+
*/
|
|
422
|
+
export interface ContextEventResult {
|
|
423
|
+
/** Modified messages to send instead of the original */
|
|
424
|
+
messages?: Message[];
|
|
425
|
+
}
|
|
241
426
|
/**
|
|
242
427
|
* Return type for tool_call event handlers.
|
|
243
428
|
* Allows hooks to block tool execution.
|
|
@@ -261,39 +446,166 @@ export interface ToolResultEventResult {
|
|
|
261
446
|
isError?: boolean;
|
|
262
447
|
}
|
|
263
448
|
/**
|
|
264
|
-
* Return type for
|
|
265
|
-
* Allows hooks to
|
|
449
|
+
* Return type for before_agent_start event handlers.
|
|
450
|
+
* Allows hooks to inject context before the agent runs.
|
|
266
451
|
*/
|
|
267
|
-
export interface
|
|
268
|
-
/**
|
|
452
|
+
export interface BeforeAgentStartEventResult {
|
|
453
|
+
/** Message to inject into context (persisted to session, visible in TUI) */
|
|
454
|
+
message?: Pick<HookMessage, "customType" | "content" | "display" | "details">;
|
|
455
|
+
}
|
|
456
|
+
/** Return type for session_before_switch handlers */
|
|
457
|
+
export interface SessionBeforeSwitchResult {
|
|
458
|
+
/** If true, cancel the switch */
|
|
459
|
+
cancel?: boolean;
|
|
460
|
+
}
|
|
461
|
+
/** Return type for session_before_branch handlers */
|
|
462
|
+
export interface SessionBeforeBranchResult {
|
|
463
|
+
/**
|
|
464
|
+
* If true, abort the branch entirely. No new session file is created,
|
|
465
|
+
* conversation stays unchanged.
|
|
466
|
+
*/
|
|
269
467
|
cancel?: boolean;
|
|
270
|
-
/**
|
|
468
|
+
/**
|
|
469
|
+
* If true, the branch proceeds (new session file created, session state updated)
|
|
470
|
+
* but the in-memory conversation is NOT rewound to the branch point.
|
|
471
|
+
*
|
|
472
|
+
* Use case: git-checkpoint hook that restores code state separately.
|
|
473
|
+
* The hook handles state restoration itself, so it doesn't want the
|
|
474
|
+
* agent's conversation to be rewound (which would lose recent context).
|
|
475
|
+
*
|
|
476
|
+
* - `cancel: true` → nothing happens, user stays in current session
|
|
477
|
+
* - `skipConversationRestore: true` → branch happens, but messages stay as-is
|
|
478
|
+
* - neither → branch happens AND messages rewind to branch point (default)
|
|
479
|
+
*/
|
|
271
480
|
skipConversationRestore?: boolean;
|
|
272
|
-
|
|
273
|
-
|
|
481
|
+
}
|
|
482
|
+
/** Return type for session_before_compact handlers */
|
|
483
|
+
export interface SessionBeforeCompactResult {
|
|
484
|
+
/** If true, cancel the compaction */
|
|
485
|
+
cancel?: boolean;
|
|
486
|
+
/** Custom compaction result - SessionManager adds id/parentId */
|
|
487
|
+
compaction?: CompactionResult;
|
|
488
|
+
}
|
|
489
|
+
/** Return type for session_before_tree handlers */
|
|
490
|
+
export interface SessionBeforeTreeResult {
|
|
491
|
+
/** If true, cancel the navigation entirely */
|
|
492
|
+
cancel?: boolean;
|
|
493
|
+
/**
|
|
494
|
+
* Custom summary (skips default summarizer).
|
|
495
|
+
* Only used if preparation.userWantsSummary is true.
|
|
496
|
+
*/
|
|
497
|
+
summary?: {
|
|
498
|
+
summary: string;
|
|
499
|
+
details?: unknown;
|
|
500
|
+
};
|
|
274
501
|
}
|
|
275
502
|
/**
|
|
276
503
|
* Handler function type for each event.
|
|
504
|
+
* Handlers can return R, undefined, or void (bare return statements).
|
|
505
|
+
*/
|
|
506
|
+
export type HookHandler<E, R = undefined> = (event: E, ctx: HookContext) => Promise<R | void> | R | void;
|
|
507
|
+
export interface HookMessageRenderOptions {
|
|
508
|
+
/** Whether the view is expanded */
|
|
509
|
+
expanded: boolean;
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Renderer for hook messages.
|
|
513
|
+
* Hooks register these to provide custom TUI rendering for their message types.
|
|
277
514
|
*/
|
|
278
|
-
export type
|
|
515
|
+
export type HookMessageRenderer<T = unknown> = (message: HookMessage<T>, options: HookMessageRenderOptions, theme: Theme) => Component | undefined;
|
|
516
|
+
/**
|
|
517
|
+
* Command registration options.
|
|
518
|
+
*/
|
|
519
|
+
export interface RegisteredCommand {
|
|
520
|
+
name: string;
|
|
521
|
+
description?: string;
|
|
522
|
+
handler: (args: string, ctx: HookCommandContext) => Promise<void>;
|
|
523
|
+
}
|
|
279
524
|
/**
|
|
280
525
|
* HookAPI passed to hook factory functions.
|
|
281
|
-
* Hooks use pi.on() to subscribe to events and pi.
|
|
526
|
+
* Hooks use pi.on() to subscribe to events and pi.sendMessage() to inject messages.
|
|
282
527
|
*/
|
|
283
528
|
export interface HookAPI {
|
|
284
|
-
on(event: "
|
|
529
|
+
on(event: "session_start", handler: HookHandler<SessionStartEvent>): void;
|
|
530
|
+
on(event: "session_before_switch", handler: HookHandler<SessionBeforeSwitchEvent, SessionBeforeSwitchResult>): void;
|
|
531
|
+
on(event: "session_switch", handler: HookHandler<SessionSwitchEvent>): void;
|
|
532
|
+
on(event: "session_before_branch", handler: HookHandler<SessionBeforeBranchEvent, SessionBeforeBranchResult>): void;
|
|
533
|
+
on(event: "session_branch", handler: HookHandler<SessionBranchEvent>): void;
|
|
534
|
+
on(event: "session_before_compact", handler: HookHandler<SessionBeforeCompactEvent, SessionBeforeCompactResult>): void;
|
|
535
|
+
on(event: "session_compact", handler: HookHandler<SessionCompactEvent>): void;
|
|
536
|
+
on(event: "session_shutdown", handler: HookHandler<SessionShutdownEvent>): void;
|
|
537
|
+
on(event: "session_before_tree", handler: HookHandler<SessionBeforeTreeEvent, SessionBeforeTreeResult>): void;
|
|
538
|
+
on(event: "session_tree", handler: HookHandler<SessionTreeEvent>): void;
|
|
539
|
+
on(event: "context", handler: HookHandler<ContextEvent, ContextEventResult>): void;
|
|
540
|
+
on(event: "before_agent_start", handler: HookHandler<BeforeAgentStartEvent, BeforeAgentStartEventResult>): void;
|
|
285
541
|
on(event: "agent_start", handler: HookHandler<AgentStartEvent>): void;
|
|
286
542
|
on(event: "agent_end", handler: HookHandler<AgentEndEvent>): void;
|
|
287
543
|
on(event: "turn_start", handler: HookHandler<TurnStartEvent>): void;
|
|
288
544
|
on(event: "turn_end", handler: HookHandler<TurnEndEvent>): void;
|
|
289
|
-
on(event: "tool_call", handler: HookHandler<ToolCallEvent, ToolCallEventResult
|
|
290
|
-
on(event: "tool_result", handler: HookHandler<ToolResultEvent, ToolResultEventResult
|
|
545
|
+
on(event: "tool_call", handler: HookHandler<ToolCallEvent, ToolCallEventResult>): void;
|
|
546
|
+
on(event: "tool_result", handler: HookHandler<ToolResultEvent, ToolResultEventResult>): void;
|
|
291
547
|
/**
|
|
292
|
-
* Send a message to the
|
|
293
|
-
*
|
|
294
|
-
*
|
|
548
|
+
* Send a custom message to the session. Creates a CustomMessageEntry that
|
|
549
|
+
* participates in LLM context and can be displayed in the TUI.
|
|
550
|
+
*
|
|
551
|
+
* Use this when you want the LLM to see the message content.
|
|
552
|
+
* For hook state that should NOT be sent to the LLM, use appendEntry() instead.
|
|
553
|
+
*
|
|
554
|
+
* @param message - The message to send
|
|
555
|
+
* @param message.customType - Identifier for your hook (used for filtering on reload)
|
|
556
|
+
* @param message.content - Message content (string or TextContent/ImageContent array)
|
|
557
|
+
* @param message.display - Whether to show in TUI (true = styled display, false = hidden)
|
|
558
|
+
* @param message.details - Optional hook-specific metadata (not sent to LLM)
|
|
559
|
+
* @param triggerTurn - If true and agent is idle, triggers a new LLM turn. Default: false.
|
|
560
|
+
* If agent is streaming, message is queued and triggerTurn is ignored.
|
|
295
561
|
*/
|
|
296
|
-
|
|
562
|
+
sendMessage<T = unknown>(message: Pick<HookMessage<T>, "customType" | "content" | "display" | "details">, triggerTurn?: boolean): void;
|
|
563
|
+
/**
|
|
564
|
+
* Append a custom entry to the session for hook state persistence.
|
|
565
|
+
* Creates a CustomEntry that does NOT participate in LLM context.
|
|
566
|
+
*
|
|
567
|
+
* Use this to store hook-specific data that should persist across session reloads
|
|
568
|
+
* but should NOT be sent to the LLM. On reload, scan session entries for your
|
|
569
|
+
* customType to reconstruct hook state.
|
|
570
|
+
*
|
|
571
|
+
* For messages that SHOULD be sent to the LLM, use sendMessage() instead.
|
|
572
|
+
*
|
|
573
|
+
* @param customType - Identifier for your hook (used for filtering on reload)
|
|
574
|
+
* @param data - Hook-specific data to persist (must be JSON-serializable)
|
|
575
|
+
*
|
|
576
|
+
* @example
|
|
577
|
+
* // Store permission state
|
|
578
|
+
* pi.appendEntry("permissions", { level: "full", grantedAt: Date.now() });
|
|
579
|
+
*
|
|
580
|
+
* // On reload, reconstruct state from entries
|
|
581
|
+
* pi.on("session", async (event, ctx) => {
|
|
582
|
+
* if (event.reason === "start") {
|
|
583
|
+
* const entries = event.sessionManager.getEntries();
|
|
584
|
+
* const myEntries = entries.filter(e => e.type === "custom" && e.customType === "permissions");
|
|
585
|
+
* // Reconstruct state from myEntries...
|
|
586
|
+
* }
|
|
587
|
+
* });
|
|
588
|
+
*/
|
|
589
|
+
appendEntry<T = unknown>(customType: string, data?: T): void;
|
|
590
|
+
/**
|
|
591
|
+
* Register a custom renderer for CustomMessageEntry with a specific customType.
|
|
592
|
+
* The renderer is called when rendering the entry in the TUI.
|
|
593
|
+
* Return nothing to use the default renderer.
|
|
594
|
+
*/
|
|
595
|
+
registerMessageRenderer<T = unknown>(customType: string, renderer: HookMessageRenderer<T>): void;
|
|
596
|
+
/**
|
|
597
|
+
* Register a custom slash command.
|
|
598
|
+
* Handler receives HookCommandContext with session control methods.
|
|
599
|
+
*/
|
|
600
|
+
registerCommand(name: string, options: {
|
|
601
|
+
description?: string;
|
|
602
|
+
handler: RegisteredCommand["handler"];
|
|
603
|
+
}): void;
|
|
604
|
+
/**
|
|
605
|
+
* Execute a shell command and return stdout/stderr/code.
|
|
606
|
+
* Supports timeout and abort signal.
|
|
607
|
+
*/
|
|
608
|
+
exec(command: string, args: string[], options?: ExecOptions): Promise<ExecResult>;
|
|
297
609
|
}
|
|
298
610
|
/**
|
|
299
611
|
* Hook factory function type.
|
|
@@ -308,5 +620,4 @@ export interface HookError {
|
|
|
308
620
|
event: string;
|
|
309
621
|
error: string;
|
|
310
622
|
}
|
|
311
|
-
export {};
|
|
312
623
|
//# sourceMappingURL=types.d.ts.map
|