@code-yeongyu/senpi 2026.6.28-4 → 2026.6.30
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 +15 -0
- package/README.md +2 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +17 -4
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/command-runner.d.ts +25 -0
- package/dist/core/extensions/builtin/hooks/command-runner.d.ts.map +1 -0
- package/dist/core/extensions/builtin/hooks/command-runner.js +152 -0
- package/dist/core/extensions/builtin/hooks/command-runner.js.map +1 -0
- package/dist/core/extensions/builtin/hooks/command.d.ts +11 -0
- package/dist/core/extensions/builtin/hooks/command.d.ts.map +1 -0
- package/dist/core/extensions/builtin/hooks/command.js +180 -0
- package/dist/core/extensions/builtin/hooks/command.js.map +1 -0
- package/dist/core/extensions/builtin/hooks/config-loader.d.ts +19 -0
- package/dist/core/extensions/builtin/hooks/config-loader.d.ts.map +1 -0
- package/dist/core/extensions/builtin/hooks/config-loader.js +125 -0
- package/dist/core/extensions/builtin/hooks/config-loader.js.map +1 -0
- package/dist/core/extensions/builtin/hooks/diagnostics.d.ts +10 -0
- package/dist/core/extensions/builtin/hooks/diagnostics.d.ts.map +1 -0
- package/dist/core/extensions/builtin/hooks/diagnostics.js +14 -0
- package/dist/core/extensions/builtin/hooks/diagnostics.js.map +1 -0
- package/dist/core/extensions/builtin/hooks/dispatcher.d.ts +60 -0
- package/dist/core/extensions/builtin/hooks/dispatcher.d.ts.map +1 -0
- package/dist/core/extensions/builtin/hooks/dispatcher.js +161 -0
- package/dist/core/extensions/builtin/hooks/dispatcher.js.map +1 -0
- package/dist/core/extensions/builtin/hooks/handler.d.ts +12 -0
- package/dist/core/extensions/builtin/hooks/handler.d.ts.map +1 -0
- package/dist/core/extensions/builtin/hooks/handler.js +128 -0
- package/dist/core/extensions/builtin/hooks/handler.js.map +1 -0
- package/dist/core/extensions/builtin/hooks/index.d.ts +6 -0
- package/dist/core/extensions/builtin/hooks/index.d.ts.map +1 -0
- package/dist/core/extensions/builtin/hooks/index.js +216 -0
- package/dist/core/extensions/builtin/hooks/index.js.map +1 -0
- package/dist/core/extensions/builtin/hooks/lifecycle-adapter.d.ts +29 -0
- package/dist/core/extensions/builtin/hooks/lifecycle-adapter.d.ts.map +1 -0
- package/dist/core/extensions/builtin/hooks/lifecycle-adapter.js +276 -0
- package/dist/core/extensions/builtin/hooks/lifecycle-adapter.js.map +1 -0
- package/dist/core/extensions/builtin/hooks/matcher.d.ts +7 -0
- package/dist/core/extensions/builtin/hooks/matcher.d.ts.map +1 -0
- package/dist/core/extensions/builtin/hooks/matcher.js +109 -0
- package/dist/core/extensions/builtin/hooks/matcher.js.map +1 -0
- package/dist/core/extensions/builtin/hooks/output-bounds.d.ts +29 -0
- package/dist/core/extensions/builtin/hooks/output-bounds.d.ts.map +1 -0
- package/dist/core/extensions/builtin/hooks/output-bounds.js +47 -0
- package/dist/core/extensions/builtin/hooks/output-bounds.js.map +1 -0
- package/dist/core/extensions/builtin/hooks/output-parser.d.ts +27 -0
- package/dist/core/extensions/builtin/hooks/output-parser.d.ts.map +1 -0
- package/dist/core/extensions/builtin/hooks/output-parser.js +168 -0
- package/dist/core/extensions/builtin/hooks/output-parser.js.map +1 -0
- package/dist/core/extensions/builtin/hooks/plugin-loader.d.ts +11 -0
- package/dist/core/extensions/builtin/hooks/plugin-loader.d.ts.map +1 -0
- package/dist/core/extensions/builtin/hooks/plugin-loader.js +138 -0
- package/dist/core/extensions/builtin/hooks/plugin-loader.js.map +1 -0
- package/dist/core/extensions/builtin/hooks/plugin-manifest.d.ts +47 -0
- package/dist/core/extensions/builtin/hooks/plugin-manifest.d.ts.map +1 -0
- package/dist/core/extensions/builtin/hooks/plugin-manifest.js +86 -0
- package/dist/core/extensions/builtin/hooks/plugin-manifest.js.map +1 -0
- package/dist/core/extensions/builtin/hooks/prompt-adapter.d.ts +30 -0
- package/dist/core/extensions/builtin/hooks/prompt-adapter.d.ts.map +1 -0
- package/dist/core/extensions/builtin/hooks/prompt-adapter.js +59 -0
- package/dist/core/extensions/builtin/hooks/prompt-adapter.js.map +1 -0
- package/dist/core/extensions/builtin/hooks/safety.d.ts +14 -0
- package/dist/core/extensions/builtin/hooks/safety.d.ts.map +1 -0
- package/dist/core/extensions/builtin/hooks/safety.js +179 -0
- package/dist/core/extensions/builtin/hooks/safety.js.map +1 -0
- package/dist/core/extensions/builtin/hooks/schema.d.ts +3 -0
- package/dist/core/extensions/builtin/hooks/schema.d.ts.map +1 -0
- package/dist/core/extensions/builtin/hooks/schema.js +94 -0
- package/dist/core/extensions/builtin/hooks/schema.js.map +1 -0
- package/dist/core/extensions/builtin/hooks/stop-adapter.d.ts +18 -0
- package/dist/core/extensions/builtin/hooks/stop-adapter.d.ts.map +1 -0
- package/dist/core/extensions/builtin/hooks/stop-adapter.js +282 -0
- package/dist/core/extensions/builtin/hooks/stop-adapter.js.map +1 -0
- package/dist/core/extensions/builtin/hooks/tool-adapter.d.ts +11 -0
- package/dist/core/extensions/builtin/hooks/tool-adapter.d.ts.map +1 -0
- package/dist/core/extensions/builtin/hooks/tool-adapter.js +158 -0
- package/dist/core/extensions/builtin/hooks/tool-adapter.js.map +1 -0
- package/dist/core/extensions/builtin/hooks/trust-storage.d.ts +24 -0
- package/dist/core/extensions/builtin/hooks/trust-storage.d.ts.map +1 -0
- package/dist/core/extensions/builtin/hooks/trust-storage.js +102 -0
- package/dist/core/extensions/builtin/hooks/trust-storage.js.map +1 -0
- package/dist/core/extensions/builtin/hooks/trust.d.ts +34 -0
- package/dist/core/extensions/builtin/hooks/trust.d.ts.map +1 -0
- package/dist/core/extensions/builtin/hooks/trust.js +194 -0
- package/dist/core/extensions/builtin/hooks/trust.js.map +1 -0
- package/dist/core/extensions/builtin/hooks/types.d.ts +134 -0
- package/dist/core/extensions/builtin/hooks/types.d.ts.map +1 -0
- package/dist/core/extensions/builtin/hooks/types.js +36 -0
- package/dist/core/extensions/builtin/hooks/types.js.map +1 -0
- package/dist/core/extensions/builtin/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/index.js +2 -0
- package/dist/core/extensions/builtin/index.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +5 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +20 -1
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +17 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/package-manager.d.ts +1 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +14 -1
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/resource-loader.d.ts +14 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +38 -0
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/settings-manager.d.ts +2 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +2 -2
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/utils/version-check.d.ts +1 -0
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +7 -0
- package/dist/utils/version-check.js.map +1 -1
- package/docs/extensions.md +450 -0
- package/docs/index.md +1 -1
- package/docs/packages.md +9 -6
- package/examples/extensions/README.md +1 -0
- package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +17 -24
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.d.ts +17 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.js +17 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/groq.models.js +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/groq.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.d.ts +0 -24
- package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js +16 -35
- package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-ams.models.js +12 -12
- package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-ams.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-cn.models.js +12 -12
- package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-cn.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-sgp.models.js +12 -12
- package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-sgp.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi.models.js +15 -15
- package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui.js +3 -0
- package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/npm-shrinkwrap.json +9 -9
- package/package.json +4 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAQ5C,OAAO,EAAE,qBAAqB,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAC;AAElF,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAS,qBAAqB,CAAC,CAAC;AACnE,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAS,6BAA6B,CAAC,CAAC;AAE7E,MAAM,UAAU,eAAe,CAAC,KAAc,EAAE,MAA0B;IACzE,MAAM,WAAW,GAAqB,EAAE,CAAC;IACzC,MAAM,kBAAkB,GAA4B,EAAE,CAAC;IAEvD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACtB,WAAW,CAAC,IAAI,CACf,UAAU,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,gCAAgC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,MAAM,CAAC,CAClG,CAAC;QACF,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,CAAC;IAC5C,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAC1B,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACtB,WAAW,CAAC,IAAI,CACf,UAAU,CACT,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,iDAAiD,EAAE,IAAI,EAAE,OAAO,EAAE,EACpG,MAAM,CACN,CACD,CAAC;QACF,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,CAAC;IAC5C,CAAC;IAED,KAAK,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzD,IAAI,oBAAoB,CAAC,SAAS,CAAC,EAAE,CAAC;YACrC,kBAAkB,CAAC,IAAI,CAAC,GAAG,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;YACxF,SAAS;QACV,CAAC;QACD,WAAW,CAAC,IAAI,CACf,UAAU,CACT;YACC,IAAI,EAAE,2BAA2B,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,eAAe;YACpF,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,cAAc,SAAS,yCAAyC;YACzE,IAAI,EAAE,SAAS,SAAS,EAAE;YAC1B,QAAQ,EAAE,SAAS;SACnB,EACD,MAAM,CACN,CACD,CAAC;IACH,CAAC;IAED,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,CAAC;AAC5C,CAAC;AAED,SAAS,mBAAmB,CAC3B,KAAyB,EACzB,MAAe,EACf,MAA0B,EAC1B,WAA6B;IAE7B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5B,WAAW,CAAC,IAAI,CACf,UAAU,CACT;YACC,IAAI,EAAE,sBAAsB;YAC5B,KAAK;YACL,OAAO,EAAE,sCAAsC;YAC/C,IAAI,EAAE,SAAS,KAAK,EAAE;SACtB,EACD,MAAM,CACN,CACD,CAAC;QACF,OAAO,EAAE,CAAC;IACX,CAAC;IAED,MAAM,QAAQ,GAA4B,EAAE,CAAC;IAC7C,KAAK,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;QACpD,MAAM,SAAS,GAAG,SAAS,KAAK,IAAI,UAAU,GAAG,CAAC;QAClD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACtB,WAAW,CAAC,IAAI,CACf,UAAU,CACT;gBACC,IAAI,EAAE,uBAAuB;gBAC7B,KAAK;gBACL,OAAO,EAAE,uCAAuC;gBAChD,IAAI,EAAE,SAAS;aACf,EACD,MAAM,CACN,CACD,CAAC;YACF,SAAS;QACV,CAAC;QAED,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;QACnF,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC;QAC7B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9B,WAAW,CAAC,IAAI,CACf,UAAU,CACT;gBACC,IAAI,EAAE,sBAAsB;gBAC5B,KAAK;gBACL,OAAO,EAAE,4CAA4C;gBACrD,IAAI,EAAE,GAAG,SAAS,QAAQ;aAC1B,EACD,MAAM,CACN,CACD,CAAC;YACF,SAAS;QACV,CAAC;QAED,KAAK,MAAM,CAAC,YAAY,EAAE,OAAO,CAAC,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;YAC1D,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;YACxG,IAAI,MAAM,EAAE,CAAC;gBACZ,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACvB,CAAC;QACF,CAAC;IACF,CAAC;IACD,OAAO,QAAQ,CAAC;AACjB,CAAC;AAED,SAAS,YAAY,CACpB,KAAc,EACd,SAAiB,EACjB,KAAyB,EACzB,MAA0B,EAC1B,WAA6B;IAE7B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACd,CAAC;IACD,WAAW,CAAC,IAAI,CACf,UAAU,CACT,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,OAAO,EAAE,gCAAgC,EAAE,IAAI,EAAE,GAAG,SAAS,UAAU,EAAE,EAC3G,MAAM,CACN,CACD,CAAC;IACF,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC/B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC7E,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAa;IAC1C,OAAO,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,2BAA2B,CAAC,KAAa;IACjD,OAAO,qBAAqB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC","sourcesContent":["import { diagnostic } from \"./diagnostics.ts\";\nimport { parseHandler } from \"./handler.ts\";\nimport type {\n\tExecutableHookHandler,\n\tHookDiagnostic,\n\tHookSourceMetadata,\n\tParsedHookConfig,\n\tSupportedHookEvent,\n} from \"./types.ts\";\nimport { SUPPORTED_HOOK_EVENTS, UNSUPPORTED_KNOWN_HOOK_EVENTS } from \"./types.ts\";\n\nconst SUPPORTED_EVENT_SET = new Set<string>(SUPPORTED_HOOK_EVENTS);\nconst UNSUPPORTED_EVENT_SET = new Set<string>(UNSUPPORTED_KNOWN_HOOK_EVENTS);\n\nexport function parseHookConfig(input: unknown, source: HookSourceMetadata): ParsedHookConfig {\n\tconst diagnostics: HookDiagnostic[] = [];\n\tconst executableHandlers: ExecutableHookHandler[] = [];\n\n\tif (!isRecord(input)) {\n\t\tdiagnostics.push(\n\t\t\tdiagnostic({ code: \"invalid_root\", message: \"Hook config must be an object.\", path: \"$\" }, source),\n\t\t);\n\t\treturn { executableHandlers, diagnostics };\n\t}\n\n\tconst hooks = input.hooks;\n\tif (!isRecord(hooks)) {\n\t\tdiagnostics.push(\n\t\t\tdiagnostic(\n\t\t\t\t{ code: \"invalid_hooks\", message: \"Hook config must contain an object hooks field.\", path: \"hooks\" },\n\t\t\t\tsource,\n\t\t\t),\n\t\t);\n\t\treturn { executableHandlers, diagnostics };\n\t}\n\n\tfor (const [eventName, groups] of Object.entries(hooks)) {\n\t\tif (isSupportedHookEvent(eventName)) {\n\t\t\texecutableHandlers.push(...parseSupportedEvent(eventName, groups, source, diagnostics));\n\t\t\tcontinue;\n\t\t}\n\t\tdiagnostics.push(\n\t\t\tdiagnostic(\n\t\t\t\t{\n\t\t\t\t\tcode: isUnsupportedKnownHookEvent(eventName) ? \"unsupported_event\" : \"unknown_event\",\n\t\t\t\t\tevent: eventName,\n\t\t\t\t\tmessage: `Hook event ${eventName} is not executable in builtin hooks v1.`,\n\t\t\t\t\tpath: `hooks.${eventName}`,\n\t\t\t\t\tseverity: \"warning\",\n\t\t\t\t},\n\t\t\t\tsource,\n\t\t\t),\n\t\t);\n\t}\n\n\treturn { executableHandlers, diagnostics };\n}\n\nfunction parseSupportedEvent(\n\tevent: SupportedHookEvent,\n\tgroups: unknown,\n\tsource: HookSourceMetadata,\n\tdiagnostics: HookDiagnostic[],\n): ExecutableHookHandler[] {\n\tif (!Array.isArray(groups)) {\n\t\tdiagnostics.push(\n\t\t\tdiagnostic(\n\t\t\t\t{\n\t\t\t\t\tcode: \"invalid_event_config\",\n\t\t\t\t\tevent,\n\t\t\t\t\tmessage: \"Hook event entries must be an array.\",\n\t\t\t\t\tpath: `hooks.${event}`,\n\t\t\t\t},\n\t\t\t\tsource,\n\t\t\t),\n\t\t);\n\t\treturn [];\n\t}\n\n\tconst handlers: ExecutableHookHandler[] = [];\n\tfor (const [groupIndex, group] of groups.entries()) {\n\t\tconst groupPath = `hooks.${event}[${groupIndex}]`;\n\t\tif (!isRecord(group)) {\n\t\t\tdiagnostics.push(\n\t\t\t\tdiagnostic(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"invalid_handler_group\",\n\t\t\t\t\t\tevent,\n\t\t\t\t\t\tmessage: \"Hook matcher group must be an object.\",\n\t\t\t\t\t\tpath: groupPath,\n\t\t\t\t\t},\n\t\t\t\t\tsource,\n\t\t\t\t),\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst matcher = parseMatcher(group.matcher, groupPath, event, source, diagnostics);\n\t\tconst hookList = group.hooks;\n\t\tif (!Array.isArray(hookList)) {\n\t\t\tdiagnostics.push(\n\t\t\t\tdiagnostic(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"invalid_handler_list\",\n\t\t\t\t\t\tevent,\n\t\t\t\t\t\tmessage: \"Hook matcher group hooks must be an array.\",\n\t\t\t\t\t\tpath: `${groupPath}.hooks`,\n\t\t\t\t\t},\n\t\t\t\t\tsource,\n\t\t\t\t),\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\n\t\tfor (const [handlerIndex, handler] of hookList.entries()) {\n\t\t\tconst parsed = parseHandler(handler, { event, matcher, groupIndex, handlerIndex, source, diagnostics });\n\t\t\tif (parsed) {\n\t\t\t\thandlers.push(parsed);\n\t\t\t}\n\t\t}\n\t}\n\treturn handlers;\n}\n\nfunction parseMatcher(\n\tvalue: unknown,\n\tgroupPath: string,\n\tevent: SupportedHookEvent,\n\tsource: HookSourceMetadata,\n\tdiagnostics: HookDiagnostic[],\n): string | undefined {\n\tif (value === undefined) {\n\t\treturn undefined;\n\t}\n\tif (typeof value === \"string\") {\n\t\treturn value;\n\t}\n\tdiagnostics.push(\n\t\tdiagnostic(\n\t\t\t{ code: \"invalid_matcher\", event, message: \"Hook matcher must be a string.\", path: `${groupPath}.matcher` },\n\t\t\tsource,\n\t\t),\n\t);\n\treturn undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isSupportedHookEvent(value: string): value is SupportedHookEvent {\n\treturn SUPPORTED_EVENT_SET.has(value);\n}\n\nfunction isUnsupportedKnownHookEvent(value: string): boolean {\n\treturn UNSUPPORTED_EVENT_SET.has(value);\n}\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { AgentMessage } from "@earendil-works/pi-agent-core";
|
|
2
|
+
import type { ExtensionAPI, ExtensionContext } from "../../types.ts";
|
|
3
|
+
import type { HookDispatchResult } from "./dispatcher.ts";
|
|
4
|
+
import type { HookInputWire } from "./types.ts";
|
|
5
|
+
export declare const STOP_STATE_CUSTOM_TYPE = "senpi.hooks.stop-state";
|
|
6
|
+
export declare const STOP_DIAGNOSTICS_CUSTOM_TYPE = "senpi.hooks.stop-diagnostics";
|
|
7
|
+
export declare const STOP_OUTPUT_CUSTOM_TYPE = "senpi.hooks.stop-output";
|
|
8
|
+
type StopRuntime = Pick<ExtensionAPI, "appendEntry" | "sendUserMessage">;
|
|
9
|
+
export declare function buildStopHookInput(event: {
|
|
10
|
+
readonly messages: readonly AgentMessage[];
|
|
11
|
+
}, ctx: ExtensionContext): HookInputWire;
|
|
12
|
+
export declare function createStopTurnTracker(): {
|
|
13
|
+
readonly reset: () => void;
|
|
14
|
+
readonly turnKey: (ctx: ExtensionContext) => string;
|
|
15
|
+
};
|
|
16
|
+
export declare function applyStopHookResult(pi: StopRuntime, ctx: ExtensionContext, result: HookDispatchResult, turnKey: string): Promise<void>;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=stop-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop-adapter.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/stop-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAErE,OAAO,KAAK,EAAE,kBAAkB,EAAuB,MAAM,iBAAiB,CAAC;AAE/E,OAAO,KAAK,EAAkB,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhE,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAC/D,eAAO,MAAM,4BAA4B,iCAAiC,CAAC;AAC3E,eAAO,MAAM,uBAAuB,4BAA4B,CAAC;AAiBjE,KAAK,WAAW,GAAG,IAAI,CAAC,YAAY,EAAE,aAAa,GAAG,iBAAiB,CAAC,CAAC;AAEzE,wBAAgB,kBAAkB,CACjC,KAAK,EAAE;IAAE,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAA;CAAE,EACrD,GAAG,EAAE,gBAAgB,GACnB,aAAa,CAWf;AAED,wBAAgB,qBAAqB,IAAI;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,MAAM,CAAC;CACpD,CAeA;AAED,wBAAgB,mBAAmB,CAClC,EAAE,EAAE,WAAW,EACf,GAAG,EAAE,gBAAgB,EACrB,MAAM,EAAE,kBAAkB,EAC1B,OAAO,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAmDf"}
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import { diagnostic } from "./diagnostics.js";
|
|
2
|
+
import { safeDiagnosticDetails } from "./prompt-adapter.js";
|
|
3
|
+
export const STOP_STATE_CUSTOM_TYPE = "senpi.hooks.stop-state";
|
|
4
|
+
export const STOP_DIAGNOSTICS_CUSTOM_TYPE = "senpi.hooks.stop-diagnostics";
|
|
5
|
+
export const STOP_OUTPUT_CUSTOM_TYPE = "senpi.hooks.stop-output";
|
|
6
|
+
const STOP_REENTRY_LIMIT = 8;
|
|
7
|
+
export function buildStopHookInput(event, ctx) {
|
|
8
|
+
const transcriptPath = ctx.sessionManager.getSessionFile();
|
|
9
|
+
const stopReason = findLastAssistantStopReason(event.messages);
|
|
10
|
+
return {
|
|
11
|
+
cwd: ctx.cwd,
|
|
12
|
+
event: "Stop",
|
|
13
|
+
hook_event_name: "Stop",
|
|
14
|
+
session_id: ctx.sessionManager.getSessionId(),
|
|
15
|
+
...(stopReason === undefined ? {} : { stopReason }),
|
|
16
|
+
...(transcriptPath === undefined ? {} : { transcript_path: transcriptPath }),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export function createStopTurnTracker() {
|
|
20
|
+
let activeTurnKey;
|
|
21
|
+
let turnIndex = 0;
|
|
22
|
+
return {
|
|
23
|
+
reset() {
|
|
24
|
+
turnIndex += 1;
|
|
25
|
+
activeTurnKey = undefined;
|
|
26
|
+
},
|
|
27
|
+
turnKey(ctx) {
|
|
28
|
+
if (activeTurnKey !== undefined)
|
|
29
|
+
return activeTurnKey;
|
|
30
|
+
const leafId = ctx.sessionManager.getLeafId() ?? ctx.sessionManager.getSessionId();
|
|
31
|
+
activeTurnKey = `${turnIndex}:${leafId}`;
|
|
32
|
+
return activeTurnKey;
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export function applyStopHookResult(pi, ctx, result, turnKey) {
|
|
37
|
+
const sessionId = ctx.sessionManager.getSessionId();
|
|
38
|
+
const previous = latestStopState(ctx, sessionId, turnKey);
|
|
39
|
+
if (previous.count >= STOP_REENTRY_LIMIT) {
|
|
40
|
+
appendStopState(pi, { count: previous.count, sessionId, turnKey });
|
|
41
|
+
appendStopDiagnostics(pi, [
|
|
42
|
+
diagnostic({
|
|
43
|
+
code: "unsupported_event",
|
|
44
|
+
event: "Stop",
|
|
45
|
+
message: "Stop hook reentry limit reached.",
|
|
46
|
+
path: "hooks.Stop",
|
|
47
|
+
severity: "warning",
|
|
48
|
+
}, limitDiagnosticSource(result)),
|
|
49
|
+
]);
|
|
50
|
+
return Promise.resolve();
|
|
51
|
+
}
|
|
52
|
+
const unsupportedDiagnostics = unsupportedStopOutputDiagnostics(result);
|
|
53
|
+
if (unsupportedDiagnostics.length > 0 || result.diagnostics.length > 0) {
|
|
54
|
+
appendStopDiagnostics(pi, [...result.diagnostics, ...unsupportedDiagnostics]);
|
|
55
|
+
}
|
|
56
|
+
appendStopOutputs(pi, stopOutputRecords(result));
|
|
57
|
+
if (result.decision.kind !== "block") {
|
|
58
|
+
appendStopState(pi, { count: previous.count, sessionId, turnKey });
|
|
59
|
+
return Promise.resolve();
|
|
60
|
+
}
|
|
61
|
+
const count = previous.count + 1;
|
|
62
|
+
appendStopState(pi, { count, sessionId, turnKey });
|
|
63
|
+
const followUp = stopFollowUpText(result);
|
|
64
|
+
if (followUp === undefined) {
|
|
65
|
+
appendStopDiagnostics(pi, [
|
|
66
|
+
diagnostic({
|
|
67
|
+
code: "unsupported_field",
|
|
68
|
+
event: "Stop",
|
|
69
|
+
message: "Stop hook blocked without follow-up context.",
|
|
70
|
+
path: "stdout.reason",
|
|
71
|
+
severity: "warning",
|
|
72
|
+
}, result.decision.source),
|
|
73
|
+
]);
|
|
74
|
+
return Promise.resolve();
|
|
75
|
+
}
|
|
76
|
+
pi.sendUserMessage(followUp, { deliverAs: "followUp" });
|
|
77
|
+
return waitForFollowUpQueue(ctx);
|
|
78
|
+
}
|
|
79
|
+
async function waitForFollowUpQueue(ctx) {
|
|
80
|
+
for (let attempt = 0; attempt < 64; attempt += 1) {
|
|
81
|
+
await Promise.resolve();
|
|
82
|
+
if (ctx.hasPendingMessages())
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function latestStopState(ctx, sessionId, turnKey) {
|
|
87
|
+
const entries = ctx.sessionManager.getEntries();
|
|
88
|
+
for (let index = entries.length - 1; index >= 0; index -= 1) {
|
|
89
|
+
const entry = entries[index];
|
|
90
|
+
if (entry?.type !== "custom" || entry.customType !== STOP_STATE_CUSTOM_TYPE)
|
|
91
|
+
continue;
|
|
92
|
+
if (!isStopState(entry.data))
|
|
93
|
+
continue;
|
|
94
|
+
if (entry.data.sessionId === sessionId && entry.data.turnKey === turnKey)
|
|
95
|
+
return entry.data;
|
|
96
|
+
}
|
|
97
|
+
return { count: 0, sessionId, turnKey };
|
|
98
|
+
}
|
|
99
|
+
function appendStopState(pi, state) {
|
|
100
|
+
pi.appendEntry(STOP_STATE_CUSTOM_TYPE, state);
|
|
101
|
+
}
|
|
102
|
+
function appendStopDiagnostics(pi, diagnostics) {
|
|
103
|
+
if (diagnostics.length === 0)
|
|
104
|
+
return;
|
|
105
|
+
pi.appendEntry(STOP_DIAGNOSTICS_CUSTOM_TYPE, diagnostics.map(safeStopDiagnosticDetails));
|
|
106
|
+
}
|
|
107
|
+
function safeStopDiagnosticDetails(diagnostic) {
|
|
108
|
+
if (diagnostic.code === "invalid_event_config" &&
|
|
109
|
+
diagnostic.event === "Stop" &&
|
|
110
|
+
diagnostic.path === "stdout.hookSpecificOutput.hookEventName") {
|
|
111
|
+
return {
|
|
112
|
+
...safeDiagnosticDetails(diagnostic),
|
|
113
|
+
message: "Hook output event does not match Stop.",
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
return safeDiagnosticDetails(diagnostic);
|
|
117
|
+
}
|
|
118
|
+
function appendStopOutputs(pi, records) {
|
|
119
|
+
if (records.length === 0)
|
|
120
|
+
return;
|
|
121
|
+
pi.appendEntry(STOP_OUTPUT_CUSTOM_TYPE, records);
|
|
122
|
+
}
|
|
123
|
+
function stopOutputRecords(result) {
|
|
124
|
+
return result.summaries.flatMap((summary) => {
|
|
125
|
+
const fields = stopOutputFieldPaths(summary);
|
|
126
|
+
if (fields.length === 0)
|
|
127
|
+
return [];
|
|
128
|
+
return [
|
|
129
|
+
{
|
|
130
|
+
event: "Stop",
|
|
131
|
+
exitCode: summary.run.exitCode,
|
|
132
|
+
fields,
|
|
133
|
+
sourcePath: summary.handler.source.sourcePath,
|
|
134
|
+
},
|
|
135
|
+
];
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
function unsupportedStopOutputDiagnostics(result) {
|
|
139
|
+
const diagnostics = [];
|
|
140
|
+
for (const summary of result.summaries) {
|
|
141
|
+
diagnostics.push(...unsupportedSummaryDiagnostics(summary));
|
|
142
|
+
}
|
|
143
|
+
return diagnostics;
|
|
144
|
+
}
|
|
145
|
+
function unsupportedSummaryDiagnostics(summary) {
|
|
146
|
+
const diagnostics = [];
|
|
147
|
+
if (summary.output.systemMessage !== undefined) {
|
|
148
|
+
diagnostics.push(unsupportedField(summary, "stdout.systemMessage", "Stop does not support systemMessage."));
|
|
149
|
+
}
|
|
150
|
+
if (summary.output.suppressOutput !== undefined) {
|
|
151
|
+
diagnostics.push(unsupportedField(summary, "stdout.suppressOutput", "Stop does not support suppressOutput."));
|
|
152
|
+
}
|
|
153
|
+
if (summary.output.stopReason !== undefined) {
|
|
154
|
+
diagnostics.push(unsupportedField(summary, "stdout.stopReason", "Stop output stopReason is diagnostic-only."));
|
|
155
|
+
}
|
|
156
|
+
if (summary.output.updatedInput !== undefined) {
|
|
157
|
+
diagnostics.push(unsupportedField(summary, "stdout.updatedInput", "Stop does not support updatedInput."));
|
|
158
|
+
}
|
|
159
|
+
if (summary.output.updatedToolOutput !== undefined) {
|
|
160
|
+
diagnostics.push(unsupportedField(summary, "stdout.updatedToolOutput", "Stop does not support updatedToolOutput."));
|
|
161
|
+
}
|
|
162
|
+
for (const path of rawUnsupportedStopFieldPaths(summary)) {
|
|
163
|
+
diagnostics.push(unsupportedField(summary, path, `Stop does not support ${path.replace("stdout.", "")}.`));
|
|
164
|
+
}
|
|
165
|
+
return diagnostics;
|
|
166
|
+
}
|
|
167
|
+
function stopOutputFieldPaths(summary) {
|
|
168
|
+
const fields = [];
|
|
169
|
+
if (summary.output.decision !== undefined)
|
|
170
|
+
fields.push("stdout.decision");
|
|
171
|
+
if (summary.output.reason !== undefined)
|
|
172
|
+
fields.push("stdout.reason");
|
|
173
|
+
if (summary.output.additionalContext !== undefined) {
|
|
174
|
+
const raw = rawStdoutObject(summary.run.stdout);
|
|
175
|
+
const specific = raw === undefined ? undefined : rawHookSpecificOutput(raw);
|
|
176
|
+
fields.push(specific !== undefined && Object.hasOwn(specific, "additionalContext")
|
|
177
|
+
? "stdout.hookSpecificOutput.additionalContext"
|
|
178
|
+
: "stdout.additionalContext");
|
|
179
|
+
}
|
|
180
|
+
if (summary.output.continue !== undefined)
|
|
181
|
+
fields.push("stdout.continue");
|
|
182
|
+
if (summary.output.stopReason !== undefined)
|
|
183
|
+
fields.push("stdout.stopReason");
|
|
184
|
+
if (summary.output.suppressOutput !== undefined)
|
|
185
|
+
fields.push("stdout.suppressOutput");
|
|
186
|
+
if (summary.output.systemMessage !== undefined)
|
|
187
|
+
fields.push("stdout.systemMessage");
|
|
188
|
+
fields.push(...rawUnsupportedStopFieldPaths(summary));
|
|
189
|
+
return fields;
|
|
190
|
+
}
|
|
191
|
+
function rawUnsupportedStopFieldPaths(summary) {
|
|
192
|
+
const raw = rawStdoutObject(summary.run.stdout);
|
|
193
|
+
if (raw === undefined)
|
|
194
|
+
return [];
|
|
195
|
+
const fields = [];
|
|
196
|
+
pushFieldIfPresent(fields, raw, "updatedInput", "stdout.updatedInput");
|
|
197
|
+
pushFieldIfPresent(fields, raw, "updatedToolOutput", "stdout.updatedToolOutput");
|
|
198
|
+
const specific = rawHookSpecificOutput(raw);
|
|
199
|
+
if (specific !== undefined) {
|
|
200
|
+
pushFieldIfPresent(fields, specific, "updatedInput", "stdout.hookSpecificOutput.updatedInput");
|
|
201
|
+
pushFieldIfPresent(fields, specific, "updatedToolOutput", "stdout.hookSpecificOutput.updatedToolOutput");
|
|
202
|
+
}
|
|
203
|
+
return fields;
|
|
204
|
+
}
|
|
205
|
+
function pushFieldIfPresent(fields, record, key, path) {
|
|
206
|
+
if (Object.hasOwn(record, key))
|
|
207
|
+
fields.push(path);
|
|
208
|
+
}
|
|
209
|
+
function rawStdoutObject(stdout) {
|
|
210
|
+
const trimmed = stdout.trim();
|
|
211
|
+
if (trimmed.length === 0)
|
|
212
|
+
return undefined;
|
|
213
|
+
try {
|
|
214
|
+
const parsed = JSON.parse(trimmed);
|
|
215
|
+
return isRecord(parsed) ? parsed : undefined;
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
if (error instanceof SyntaxError)
|
|
219
|
+
return undefined;
|
|
220
|
+
throw error;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
function rawHookSpecificOutput(raw) {
|
|
224
|
+
const value = raw.hookSpecificOutput;
|
|
225
|
+
return isRecord(value) ? value : undefined;
|
|
226
|
+
}
|
|
227
|
+
function unsupportedField(summary, path, message) {
|
|
228
|
+
return diagnostic({
|
|
229
|
+
code: "unsupported_field",
|
|
230
|
+
event: "Stop",
|
|
231
|
+
message,
|
|
232
|
+
path,
|
|
233
|
+
severity: "warning",
|
|
234
|
+
}, summary.handler.source);
|
|
235
|
+
}
|
|
236
|
+
function stopFollowUpText(result) {
|
|
237
|
+
if (result.decision.kind !== "block")
|
|
238
|
+
return undefined;
|
|
239
|
+
const blocker = blockingSummary(result);
|
|
240
|
+
if (blocker === undefined || blocker.run.exitCode === 2)
|
|
241
|
+
return undefined;
|
|
242
|
+
return blocker.output.additionalContext ?? result.decision.reason;
|
|
243
|
+
}
|
|
244
|
+
function blockingSummary(result) {
|
|
245
|
+
if (result.decision.kind !== "block")
|
|
246
|
+
return undefined;
|
|
247
|
+
const sourcePath = result.decision.source.sourcePath;
|
|
248
|
+
return result.summaries.find((summary) => summary.handler.source.sourcePath === sourcePath &&
|
|
249
|
+
(summary.output.decision === "block" || summary.output.decision === "deny"));
|
|
250
|
+
}
|
|
251
|
+
function limitDiagnosticSource(result) {
|
|
252
|
+
return (result.matchedHandlers[0]?.source ??
|
|
253
|
+
result.executableHandlers[0]?.source ?? {
|
|
254
|
+
discoveredAt: "runtime",
|
|
255
|
+
displayOrder: 0,
|
|
256
|
+
scope: "managed",
|
|
257
|
+
sourcePath: "<builtin:hooks>",
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
function isStopState(value) {
|
|
261
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
262
|
+
return false;
|
|
263
|
+
if (!("sessionId" in value) || !("turnKey" in value) || !("count" in value))
|
|
264
|
+
return false;
|
|
265
|
+
return (typeof value.sessionId === "string" &&
|
|
266
|
+
typeof value.turnKey === "string" &&
|
|
267
|
+
typeof value.count === "number" &&
|
|
268
|
+
Number.isInteger(value.count) &&
|
|
269
|
+
value.count >= 0);
|
|
270
|
+
}
|
|
271
|
+
function isRecord(value) {
|
|
272
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
273
|
+
}
|
|
274
|
+
function findLastAssistantStopReason(messages) {
|
|
275
|
+
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
276
|
+
const message = messages[index];
|
|
277
|
+
if (message?.role === "assistant")
|
|
278
|
+
return message.stopReason;
|
|
279
|
+
}
|
|
280
|
+
return undefined;
|
|
281
|
+
}
|
|
282
|
+
//# sourceMappingURL=stop-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop-adapter.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/stop-adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport type { ExtensionAPI, ExtensionContext } from \"../../types.ts\";\nimport { diagnostic } from \"./diagnostics.ts\";\nimport type { HookDispatchResult, HookDispatchSummary } from \"./dispatcher.ts\";\nimport { safeDiagnosticDetails } from \"./prompt-adapter.ts\";\nimport type { HookDiagnostic, HookInputWire } from \"./types.ts\";\n\nexport const STOP_STATE_CUSTOM_TYPE = \"senpi.hooks.stop-state\";\nexport const STOP_DIAGNOSTICS_CUSTOM_TYPE = \"senpi.hooks.stop-diagnostics\";\nexport const STOP_OUTPUT_CUSTOM_TYPE = \"senpi.hooks.stop-output\";\n\nconst STOP_REENTRY_LIMIT = 8;\n\ntype StopState = {\n\treadonly sessionId: string;\n\treadonly turnKey: string;\n\treadonly count: number;\n};\n\ntype StopOutputRecord = {\n\treadonly event: \"Stop\";\n\treadonly exitCode: number | null;\n\treadonly fields: readonly string[];\n\treadonly sourcePath: string;\n};\n\ntype StopRuntime = Pick<ExtensionAPI, \"appendEntry\" | \"sendUserMessage\">;\n\nexport function buildStopHookInput(\n\tevent: { readonly messages: readonly AgentMessage[] },\n\tctx: ExtensionContext,\n): HookInputWire {\n\tconst transcriptPath = ctx.sessionManager.getSessionFile();\n\tconst stopReason = findLastAssistantStopReason(event.messages);\n\treturn {\n\t\tcwd: ctx.cwd,\n\t\tevent: \"Stop\",\n\t\thook_event_name: \"Stop\",\n\t\tsession_id: ctx.sessionManager.getSessionId(),\n\t\t...(stopReason === undefined ? {} : { stopReason }),\n\t\t...(transcriptPath === undefined ? {} : { transcript_path: transcriptPath }),\n\t};\n}\n\nexport function createStopTurnTracker(): {\n\treadonly reset: () => void;\n\treadonly turnKey: (ctx: ExtensionContext) => string;\n} {\n\tlet activeTurnKey: string | undefined;\n\tlet turnIndex = 0;\n\treturn {\n\t\treset() {\n\t\t\tturnIndex += 1;\n\t\t\tactiveTurnKey = undefined;\n\t\t},\n\t\tturnKey(ctx) {\n\t\t\tif (activeTurnKey !== undefined) return activeTurnKey;\n\t\t\tconst leafId = ctx.sessionManager.getLeafId() ?? ctx.sessionManager.getSessionId();\n\t\t\tactiveTurnKey = `${turnIndex}:${leafId}`;\n\t\t\treturn activeTurnKey;\n\t\t},\n\t};\n}\n\nexport function applyStopHookResult(\n\tpi: StopRuntime,\n\tctx: ExtensionContext,\n\tresult: HookDispatchResult,\n\tturnKey: string,\n): Promise<void> {\n\tconst sessionId = ctx.sessionManager.getSessionId();\n\tconst previous = latestStopState(ctx, sessionId, turnKey);\n\tif (previous.count >= STOP_REENTRY_LIMIT) {\n\t\tappendStopState(pi, { count: previous.count, sessionId, turnKey });\n\t\tappendStopDiagnostics(pi, [\n\t\t\tdiagnostic(\n\t\t\t\t{\n\t\t\t\t\tcode: \"unsupported_event\",\n\t\t\t\t\tevent: \"Stop\",\n\t\t\t\t\tmessage: \"Stop hook reentry limit reached.\",\n\t\t\t\t\tpath: \"hooks.Stop\",\n\t\t\t\t\tseverity: \"warning\",\n\t\t\t\t},\n\t\t\t\tlimitDiagnosticSource(result),\n\t\t\t),\n\t\t]);\n\t\treturn Promise.resolve();\n\t}\n\n\tconst unsupportedDiagnostics = unsupportedStopOutputDiagnostics(result);\n\tif (unsupportedDiagnostics.length > 0 || result.diagnostics.length > 0) {\n\t\tappendStopDiagnostics(pi, [...result.diagnostics, ...unsupportedDiagnostics]);\n\t}\n\tappendStopOutputs(pi, stopOutputRecords(result));\n\n\tif (result.decision.kind !== \"block\") {\n\t\tappendStopState(pi, { count: previous.count, sessionId, turnKey });\n\t\treturn Promise.resolve();\n\t}\n\n\tconst count = previous.count + 1;\n\tappendStopState(pi, { count, sessionId, turnKey });\n\tconst followUp = stopFollowUpText(result);\n\tif (followUp === undefined) {\n\t\tappendStopDiagnostics(pi, [\n\t\t\tdiagnostic(\n\t\t\t\t{\n\t\t\t\t\tcode: \"unsupported_field\",\n\t\t\t\t\tevent: \"Stop\",\n\t\t\t\t\tmessage: \"Stop hook blocked without follow-up context.\",\n\t\t\t\t\tpath: \"stdout.reason\",\n\t\t\t\t\tseverity: \"warning\",\n\t\t\t\t},\n\t\t\t\tresult.decision.source,\n\t\t\t),\n\t\t]);\n\t\treturn Promise.resolve();\n\t}\n\tpi.sendUserMessage(followUp, { deliverAs: \"followUp\" });\n\treturn waitForFollowUpQueue(ctx);\n}\n\nasync function waitForFollowUpQueue(ctx: ExtensionContext): Promise<void> {\n\tfor (let attempt = 0; attempt < 64; attempt += 1) {\n\t\tawait Promise.resolve();\n\t\tif (ctx.hasPendingMessages()) return;\n\t}\n}\n\nfunction latestStopState(ctx: ExtensionContext, sessionId: string, turnKey: string): StopState {\n\tconst entries = ctx.sessionManager.getEntries();\n\tfor (let index = entries.length - 1; index >= 0; index -= 1) {\n\t\tconst entry = entries[index];\n\t\tif (entry?.type !== \"custom\" || entry.customType !== STOP_STATE_CUSTOM_TYPE) continue;\n\t\tif (!isStopState(entry.data)) continue;\n\t\tif (entry.data.sessionId === sessionId && entry.data.turnKey === turnKey) return entry.data;\n\t}\n\treturn { count: 0, sessionId, turnKey };\n}\n\nfunction appendStopState(pi: StopRuntime, state: StopState): void {\n\tpi.appendEntry(STOP_STATE_CUSTOM_TYPE, state);\n}\n\nfunction appendStopDiagnostics(pi: StopRuntime, diagnostics: readonly HookDiagnostic[]): void {\n\tif (diagnostics.length === 0) return;\n\tpi.appendEntry(STOP_DIAGNOSTICS_CUSTOM_TYPE, diagnostics.map(safeStopDiagnosticDetails));\n}\n\nfunction safeStopDiagnosticDetails(diagnostic: HookDiagnostic): ReturnType<typeof safeDiagnosticDetails> {\n\tif (\n\t\tdiagnostic.code === \"invalid_event_config\" &&\n\t\tdiagnostic.event === \"Stop\" &&\n\t\tdiagnostic.path === \"stdout.hookSpecificOutput.hookEventName\"\n\t) {\n\t\treturn {\n\t\t\t...safeDiagnosticDetails(diagnostic),\n\t\t\tmessage: \"Hook output event does not match Stop.\",\n\t\t};\n\t}\n\treturn safeDiagnosticDetails(diagnostic);\n}\n\nfunction appendStopOutputs(pi: StopRuntime, records: readonly StopOutputRecord[]): void {\n\tif (records.length === 0) return;\n\tpi.appendEntry(STOP_OUTPUT_CUSTOM_TYPE, records);\n}\n\nfunction stopOutputRecords(result: HookDispatchResult): readonly StopOutputRecord[] {\n\treturn result.summaries.flatMap((summary) => {\n\t\tconst fields = stopOutputFieldPaths(summary);\n\t\tif (fields.length === 0) return [];\n\t\treturn [\n\t\t\t{\n\t\t\t\tevent: \"Stop\",\n\t\t\t\texitCode: summary.run.exitCode,\n\t\t\t\tfields,\n\t\t\t\tsourcePath: summary.handler.source.sourcePath,\n\t\t\t},\n\t\t];\n\t});\n}\n\nfunction unsupportedStopOutputDiagnostics(result: HookDispatchResult): readonly HookDiagnostic[] {\n\tconst diagnostics: HookDiagnostic[] = [];\n\tfor (const summary of result.summaries) {\n\t\tdiagnostics.push(...unsupportedSummaryDiagnostics(summary));\n\t}\n\treturn diagnostics;\n}\n\nfunction unsupportedSummaryDiagnostics(summary: HookDispatchSummary): readonly HookDiagnostic[] {\n\tconst diagnostics: HookDiagnostic[] = [];\n\tif (summary.output.systemMessage !== undefined) {\n\t\tdiagnostics.push(unsupportedField(summary, \"stdout.systemMessage\", \"Stop does not support systemMessage.\"));\n\t}\n\tif (summary.output.suppressOutput !== undefined) {\n\t\tdiagnostics.push(unsupportedField(summary, \"stdout.suppressOutput\", \"Stop does not support suppressOutput.\"));\n\t}\n\tif (summary.output.stopReason !== undefined) {\n\t\tdiagnostics.push(unsupportedField(summary, \"stdout.stopReason\", \"Stop output stopReason is diagnostic-only.\"));\n\t}\n\tif (summary.output.updatedInput !== undefined) {\n\t\tdiagnostics.push(unsupportedField(summary, \"stdout.updatedInput\", \"Stop does not support updatedInput.\"));\n\t}\n\tif (summary.output.updatedToolOutput !== undefined) {\n\t\tdiagnostics.push(\n\t\t\tunsupportedField(summary, \"stdout.updatedToolOutput\", \"Stop does not support updatedToolOutput.\"),\n\t\t);\n\t}\n\tfor (const path of rawUnsupportedStopFieldPaths(summary)) {\n\t\tdiagnostics.push(unsupportedField(summary, path, `Stop does not support ${path.replace(\"stdout.\", \"\")}.`));\n\t}\n\treturn diagnostics;\n}\n\nfunction stopOutputFieldPaths(summary: HookDispatchSummary): readonly string[] {\n\tconst fields: string[] = [];\n\tif (summary.output.decision !== undefined) fields.push(\"stdout.decision\");\n\tif (summary.output.reason !== undefined) fields.push(\"stdout.reason\");\n\tif (summary.output.additionalContext !== undefined) {\n\t\tconst raw = rawStdoutObject(summary.run.stdout);\n\t\tconst specific = raw === undefined ? undefined : rawHookSpecificOutput(raw);\n\t\tfields.push(\n\t\t\tspecific !== undefined && Object.hasOwn(specific, \"additionalContext\")\n\t\t\t\t? \"stdout.hookSpecificOutput.additionalContext\"\n\t\t\t\t: \"stdout.additionalContext\",\n\t\t);\n\t}\n\tif (summary.output.continue !== undefined) fields.push(\"stdout.continue\");\n\tif (summary.output.stopReason !== undefined) fields.push(\"stdout.stopReason\");\n\tif (summary.output.suppressOutput !== undefined) fields.push(\"stdout.suppressOutput\");\n\tif (summary.output.systemMessage !== undefined) fields.push(\"stdout.systemMessage\");\n\tfields.push(...rawUnsupportedStopFieldPaths(summary));\n\treturn fields;\n}\n\nfunction rawUnsupportedStopFieldPaths(summary: HookDispatchSummary): readonly string[] {\n\tconst raw = rawStdoutObject(summary.run.stdout);\n\tif (raw === undefined) return [];\n\tconst fields: string[] = [];\n\tpushFieldIfPresent(fields, raw, \"updatedInput\", \"stdout.updatedInput\");\n\tpushFieldIfPresent(fields, raw, \"updatedToolOutput\", \"stdout.updatedToolOutput\");\n\tconst specific = rawHookSpecificOutput(raw);\n\tif (specific !== undefined) {\n\t\tpushFieldIfPresent(fields, specific, \"updatedInput\", \"stdout.hookSpecificOutput.updatedInput\");\n\t\tpushFieldIfPresent(fields, specific, \"updatedToolOutput\", \"stdout.hookSpecificOutput.updatedToolOutput\");\n\t}\n\treturn fields;\n}\n\nfunction pushFieldIfPresent(\n\tfields: string[],\n\trecord: Readonly<Record<string, unknown>>,\n\tkey: string,\n\tpath: string,\n): void {\n\tif (Object.hasOwn(record, key)) fields.push(path);\n}\n\nfunction rawStdoutObject(stdout: string): Readonly<Record<string, unknown>> | undefined {\n\tconst trimmed = stdout.trim();\n\tif (trimmed.length === 0) return undefined;\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(trimmed);\n\t\treturn isRecord(parsed) ? parsed : undefined;\n\t} catch (error) {\n\t\tif (error instanceof SyntaxError) return undefined;\n\t\tthrow error;\n\t}\n}\n\nfunction rawHookSpecificOutput(raw: Readonly<Record<string, unknown>>): Readonly<Record<string, unknown>> | undefined {\n\tconst value = raw.hookSpecificOutput;\n\treturn isRecord(value) ? value : undefined;\n}\n\nfunction unsupportedField(summary: HookDispatchSummary, path: string, message: string): HookDiagnostic {\n\treturn diagnostic(\n\t\t{\n\t\t\tcode: \"unsupported_field\",\n\t\t\tevent: \"Stop\",\n\t\t\tmessage,\n\t\t\tpath,\n\t\t\tseverity: \"warning\",\n\t\t},\n\t\tsummary.handler.source,\n\t);\n}\n\nfunction stopFollowUpText(result: HookDispatchResult): string | undefined {\n\tif (result.decision.kind !== \"block\") return undefined;\n\tconst blocker = blockingSummary(result);\n\tif (blocker === undefined || blocker.run.exitCode === 2) return undefined;\n\treturn blocker.output.additionalContext ?? result.decision.reason;\n}\n\nfunction blockingSummary(result: HookDispatchResult): HookDispatchSummary | undefined {\n\tif (result.decision.kind !== \"block\") return undefined;\n\tconst sourcePath = result.decision.source.sourcePath;\n\treturn result.summaries.find(\n\t\t(summary) =>\n\t\t\tsummary.handler.source.sourcePath === sourcePath &&\n\t\t\t(summary.output.decision === \"block\" || summary.output.decision === \"deny\"),\n\t);\n}\n\nfunction limitDiagnosticSource(result: HookDispatchResult): HookDiagnostic[\"source\"] {\n\treturn (\n\t\tresult.matchedHandlers[0]?.source ??\n\t\tresult.executableHandlers[0]?.source ?? {\n\t\t\tdiscoveredAt: \"runtime\",\n\t\t\tdisplayOrder: 0,\n\t\t\tscope: \"managed\",\n\t\t\tsourcePath: \"<builtin:hooks>\",\n\t\t}\n\t);\n}\n\nfunction isStopState(value: unknown): value is StopState {\n\tif (typeof value !== \"object\" || value === null || Array.isArray(value)) return false;\n\tif (!(\"sessionId\" in value) || !(\"turnKey\" in value) || !(\"count\" in value)) return false;\n\treturn (\n\t\ttypeof value.sessionId === \"string\" &&\n\t\ttypeof value.turnKey === \"string\" &&\n\t\ttypeof value.count === \"number\" &&\n\t\tNumber.isInteger(value.count) &&\n\t\tvalue.count >= 0\n\t);\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction findLastAssistantStopReason(messages: readonly AgentMessage[]): string | undefined {\n\tfor (let index = messages.length - 1; index >= 0; index -= 1) {\n\t\tconst message = messages[index];\n\t\tif (message?.role === \"assistant\") return message.stopReason;\n\t}\n\treturn undefined;\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ExtensionContext, ToolCallEvent, ToolCallEventResult, ToolResultEvent, ToolResultEventResult } from "../../types.ts";
|
|
2
|
+
import type { HookDispatchResult } from "./dispatcher.ts";
|
|
3
|
+
import type { HookInputWire } from "./types.ts";
|
|
4
|
+
export declare const PRE_TOOL_BLOCK_REASON = "PreToolUse hook blocked the tool call.";
|
|
5
|
+
export declare const POST_TOOL_BLOCK_REASON = "PostToolUse hook flagged the tool result.";
|
|
6
|
+
export declare function buildPreToolUseHookInput(event: ToolCallEvent, ctx: ExtensionContext): HookInputWire;
|
|
7
|
+
export declare function buildPostToolUseHookInput(event: ToolResultEvent, ctx: ExtensionContext): HookInputWire;
|
|
8
|
+
export declare function applyPreToolUseResult(event: ToolCallEvent, result: HookDispatchResult): ToolCallEventResult | undefined;
|
|
9
|
+
export declare function applyPostToolUseResult(event: ToolResultEvent, result: HookDispatchResult, preToolContexts?: readonly string[]): ToolResultEventResult | undefined;
|
|
10
|
+
export declare function toolContextsFromResult(result: HookDispatchResult): readonly string[];
|
|
11
|
+
//# sourceMappingURL=tool-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-adapter.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/tool-adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACX,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,eAAe,EACf,qBAAqB,EACrB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,eAAO,MAAM,qBAAqB,2CAA2C,CAAC;AAC9E,eAAO,MAAM,sBAAsB,8CAA8C,CAAC;AAElF,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,gBAAgB,GAAG,aAAa,CAYnG;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,EAAE,gBAAgB,GAAG,aAAa,CAsBtG;AAED,wBAAgB,qBAAqB,CACpC,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,kBAAkB,GACxB,mBAAmB,GAAG,SAAS,CAWjC;AAED,wBAAgB,sBAAsB,CACrC,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,kBAAkB,EAC1B,eAAe,GAAE,SAAS,MAAM,EAAO,GACrC,qBAAqB,GAAG,SAAS,CAcnC;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,kBAAkB,GAAG,SAAS,MAAM,EAAE,CAIpF"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
export const PRE_TOOL_BLOCK_REASON = "PreToolUse hook blocked the tool call.";
|
|
2
|
+
export const POST_TOOL_BLOCK_REASON = "PostToolUse hook flagged the tool result.";
|
|
3
|
+
export function buildPreToolUseHookInput(event, ctx) {
|
|
4
|
+
return {
|
|
5
|
+
event: "PreToolUse",
|
|
6
|
+
toolName: event.toolName,
|
|
7
|
+
toolInput: event.input,
|
|
8
|
+
cwd: ctx.cwd,
|
|
9
|
+
session_id: ctx.sessionManager.getSessionId(),
|
|
10
|
+
hook_event_name: "PreToolUse",
|
|
11
|
+
tool_name: event.toolName,
|
|
12
|
+
tool_input: event.input,
|
|
13
|
+
tool_use_id: event.toolCallId,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export function buildPostToolUseHookInput(event, ctx) {
|
|
17
|
+
return {
|
|
18
|
+
event: "PostToolUse",
|
|
19
|
+
toolName: event.toolName,
|
|
20
|
+
toolInput: event.input,
|
|
21
|
+
toolOutput: {
|
|
22
|
+
content: event.content,
|
|
23
|
+
details: event.details,
|
|
24
|
+
is_error: event.isError,
|
|
25
|
+
},
|
|
26
|
+
cwd: ctx.cwd,
|
|
27
|
+
session_id: ctx.sessionManager.getSessionId(),
|
|
28
|
+
hook_event_name: "PostToolUse",
|
|
29
|
+
tool_name: event.toolName,
|
|
30
|
+
tool_input: event.input,
|
|
31
|
+
tool_response: {
|
|
32
|
+
content: event.content,
|
|
33
|
+
details: event.details,
|
|
34
|
+
is_error: event.isError,
|
|
35
|
+
},
|
|
36
|
+
tool_use_id: event.toolCallId,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export function applyPreToolUseResult(event, result) {
|
|
40
|
+
if (result.decision.kind === "block") {
|
|
41
|
+
return { block: true, reason: preToolBlockReasonFromResult(result) };
|
|
42
|
+
}
|
|
43
|
+
if (result.decision.kind === "ask") {
|
|
44
|
+
return { block: true, reason: result.decision.fallback.reason };
|
|
45
|
+
}
|
|
46
|
+
if (result.decision.kind === "allow" && isRecord(result.decision.updatedInput)) {
|
|
47
|
+
replaceToolInput(event.input, result.decision.updatedInput);
|
|
48
|
+
}
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
export function applyPostToolUseResult(event, result, preToolContexts = []) {
|
|
52
|
+
if (result.decision.kind === "block") {
|
|
53
|
+
return {
|
|
54
|
+
content: [
|
|
55
|
+
{ type: "text", text: postToolBlockReasonFromResult(result) },
|
|
56
|
+
...preToolContexts.map(contextTextPart),
|
|
57
|
+
...toolContextsFromResult(result).map(contextTextPart),
|
|
58
|
+
],
|
|
59
|
+
details: event.details,
|
|
60
|
+
isError: true,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
const replacement = collectPostToolUseReplacement(event, result, preToolContexts);
|
|
64
|
+
return replacement;
|
|
65
|
+
}
|
|
66
|
+
export function toolContextsFromResult(result) {
|
|
67
|
+
return result.summaries.flatMap((summary) => summary.output.additionalContext === undefined ? [] : [summary.output.additionalContext]);
|
|
68
|
+
}
|
|
69
|
+
function preToolBlockReasonFromResult(result) {
|
|
70
|
+
if (result.decision.kind !== "block")
|
|
71
|
+
return PRE_TOOL_BLOCK_REASON;
|
|
72
|
+
const sourcePath = result.decision.source.sourcePath;
|
|
73
|
+
const blocker = result.summaries.find((summary) => (summary.handler.source.sourcePath === sourcePath &&
|
|
74
|
+
(summary.output.decision === "block" || summary.output.decision === "deny")) ||
|
|
75
|
+
false);
|
|
76
|
+
if (blocker?.run.exitCode === 2)
|
|
77
|
+
return PRE_TOOL_BLOCK_REASON;
|
|
78
|
+
return result.decision.reason ?? PRE_TOOL_BLOCK_REASON;
|
|
79
|
+
}
|
|
80
|
+
function postToolBlockReasonFromResult(result) {
|
|
81
|
+
if (result.decision.kind !== "block")
|
|
82
|
+
return POST_TOOL_BLOCK_REASON;
|
|
83
|
+
const sourcePath = result.decision.source.sourcePath;
|
|
84
|
+
const blocker = result.summaries.find((summary) => (summary.handler.source.sourcePath === sourcePath &&
|
|
85
|
+
(summary.output.decision === "block" || summary.output.decision === "deny")) ||
|
|
86
|
+
false);
|
|
87
|
+
if (blocker?.run.exitCode === 2)
|
|
88
|
+
return POST_TOOL_BLOCK_REASON;
|
|
89
|
+
return result.decision.reason ?? POST_TOOL_BLOCK_REASON;
|
|
90
|
+
}
|
|
91
|
+
function collectPostToolUseReplacement(event, result, preToolContexts) {
|
|
92
|
+
let content = [...event.content];
|
|
93
|
+
let details = event.details;
|
|
94
|
+
let replaced = false;
|
|
95
|
+
const postToolContexts = [];
|
|
96
|
+
for (const summary of result.summaries) {
|
|
97
|
+
const updated = normalizeUpdatedToolOutput(summary.output.updatedToolOutput);
|
|
98
|
+
if (updated !== undefined) {
|
|
99
|
+
content = [...updated.content];
|
|
100
|
+
details = updated.details;
|
|
101
|
+
replaced = true;
|
|
102
|
+
}
|
|
103
|
+
const context = summary.output.additionalContext;
|
|
104
|
+
if (context !== undefined) {
|
|
105
|
+
postToolContexts.push(context);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
for (const context of postToolContexts) {
|
|
109
|
+
content.push(contextTextPart(context));
|
|
110
|
+
}
|
|
111
|
+
for (const context of preToolContexts) {
|
|
112
|
+
content.push(contextTextPart(context));
|
|
113
|
+
}
|
|
114
|
+
if (!replaced && postToolContexts.length === 0 && preToolContexts.length === 0)
|
|
115
|
+
return undefined;
|
|
116
|
+
return { content, ...(details === undefined ? {} : { details }) };
|
|
117
|
+
}
|
|
118
|
+
function normalizeUpdatedToolOutput(value) {
|
|
119
|
+
if (typeof value === "string") {
|
|
120
|
+
return { content: [{ type: "text", text: value }] };
|
|
121
|
+
}
|
|
122
|
+
if (isContentArray(value)) {
|
|
123
|
+
return { content: value };
|
|
124
|
+
}
|
|
125
|
+
if (!isRecord(value))
|
|
126
|
+
return undefined;
|
|
127
|
+
const content = value.content;
|
|
128
|
+
if (typeof content === "string") {
|
|
129
|
+
return { content: [{ type: "text", text: content }], details: value.details };
|
|
130
|
+
}
|
|
131
|
+
if (isContentArray(content)) {
|
|
132
|
+
return { content, details: value.details };
|
|
133
|
+
}
|
|
134
|
+
return undefined;
|
|
135
|
+
}
|
|
136
|
+
function replaceToolInput(target, replacement) {
|
|
137
|
+
for (const key of Object.keys(target)) {
|
|
138
|
+
delete target[key];
|
|
139
|
+
}
|
|
140
|
+
Object.assign(target, replacement);
|
|
141
|
+
}
|
|
142
|
+
function contextTextPart(text) {
|
|
143
|
+
return { type: "text", text };
|
|
144
|
+
}
|
|
145
|
+
function isContentArray(value) {
|
|
146
|
+
return Array.isArray(value) && value.every(isContentPart);
|
|
147
|
+
}
|
|
148
|
+
function isContentPart(value) {
|
|
149
|
+
if (!isRecord(value))
|
|
150
|
+
return false;
|
|
151
|
+
if (value.type === "text")
|
|
152
|
+
return typeof value.text === "string";
|
|
153
|
+
return value.type === "image" && typeof value.mimeType === "string" && typeof value.data === "string";
|
|
154
|
+
}
|
|
155
|
+
function isRecord(value) {
|
|
156
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=tool-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-adapter.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/tool-adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ImageContent, TextContent } from \"@earendil-works/pi-ai\";\nimport type {\n\tExtensionContext,\n\tToolCallEvent,\n\tToolCallEventResult,\n\tToolResultEvent,\n\tToolResultEventResult,\n} from \"../../types.ts\";\nimport type { HookDispatchResult } from \"./dispatcher.ts\";\nimport type { HookInputWire } from \"./types.ts\";\n\nexport const PRE_TOOL_BLOCK_REASON = \"PreToolUse hook blocked the tool call.\";\nexport const POST_TOOL_BLOCK_REASON = \"PostToolUse hook flagged the tool result.\";\n\nexport function buildPreToolUseHookInput(event: ToolCallEvent, ctx: ExtensionContext): HookInputWire {\n\treturn {\n\t\tevent: \"PreToolUse\",\n\t\ttoolName: event.toolName,\n\t\ttoolInput: event.input,\n\t\tcwd: ctx.cwd,\n\t\tsession_id: ctx.sessionManager.getSessionId(),\n\t\thook_event_name: \"PreToolUse\",\n\t\ttool_name: event.toolName,\n\t\ttool_input: event.input,\n\t\ttool_use_id: event.toolCallId,\n\t};\n}\n\nexport function buildPostToolUseHookInput(event: ToolResultEvent, ctx: ExtensionContext): HookInputWire {\n\treturn {\n\t\tevent: \"PostToolUse\",\n\t\ttoolName: event.toolName,\n\t\ttoolInput: event.input,\n\t\ttoolOutput: {\n\t\t\tcontent: event.content,\n\t\t\tdetails: event.details,\n\t\t\tis_error: event.isError,\n\t\t},\n\t\tcwd: ctx.cwd,\n\t\tsession_id: ctx.sessionManager.getSessionId(),\n\t\thook_event_name: \"PostToolUse\",\n\t\ttool_name: event.toolName,\n\t\ttool_input: event.input,\n\t\ttool_response: {\n\t\t\tcontent: event.content,\n\t\t\tdetails: event.details,\n\t\t\tis_error: event.isError,\n\t\t},\n\t\ttool_use_id: event.toolCallId,\n\t};\n}\n\nexport function applyPreToolUseResult(\n\tevent: ToolCallEvent,\n\tresult: HookDispatchResult,\n): ToolCallEventResult | undefined {\n\tif (result.decision.kind === \"block\") {\n\t\treturn { block: true, reason: preToolBlockReasonFromResult(result) };\n\t}\n\tif (result.decision.kind === \"ask\") {\n\t\treturn { block: true, reason: result.decision.fallback.reason };\n\t}\n\tif (result.decision.kind === \"allow\" && isRecord(result.decision.updatedInput)) {\n\t\treplaceToolInput(event.input, result.decision.updatedInput);\n\t}\n\treturn undefined;\n}\n\nexport function applyPostToolUseResult(\n\tevent: ToolResultEvent,\n\tresult: HookDispatchResult,\n\tpreToolContexts: readonly string[] = [],\n): ToolResultEventResult | undefined {\n\tif (result.decision.kind === \"block\") {\n\t\treturn {\n\t\t\tcontent: [\n\t\t\t\t{ type: \"text\", text: postToolBlockReasonFromResult(result) },\n\t\t\t\t...preToolContexts.map(contextTextPart),\n\t\t\t\t...toolContextsFromResult(result).map(contextTextPart),\n\t\t\t],\n\t\t\tdetails: event.details,\n\t\t\tisError: true,\n\t\t};\n\t}\n\tconst replacement = collectPostToolUseReplacement(event, result, preToolContexts);\n\treturn replacement;\n}\n\nexport function toolContextsFromResult(result: HookDispatchResult): readonly string[] {\n\treturn result.summaries.flatMap((summary) =>\n\t\tsummary.output.additionalContext === undefined ? [] : [summary.output.additionalContext],\n\t);\n}\n\nfunction preToolBlockReasonFromResult(result: HookDispatchResult): string {\n\tif (result.decision.kind !== \"block\") return PRE_TOOL_BLOCK_REASON;\n\tconst sourcePath = result.decision.source.sourcePath;\n\tconst blocker = result.summaries.find(\n\t\t(summary) =>\n\t\t\t(summary.handler.source.sourcePath === sourcePath &&\n\t\t\t\t(summary.output.decision === \"block\" || summary.output.decision === \"deny\")) ||\n\t\t\tfalse,\n\t);\n\tif (blocker?.run.exitCode === 2) return PRE_TOOL_BLOCK_REASON;\n\treturn result.decision.reason ?? PRE_TOOL_BLOCK_REASON;\n}\n\nfunction postToolBlockReasonFromResult(result: HookDispatchResult): string {\n\tif (result.decision.kind !== \"block\") return POST_TOOL_BLOCK_REASON;\n\tconst sourcePath = result.decision.source.sourcePath;\n\tconst blocker = result.summaries.find(\n\t\t(summary) =>\n\t\t\t(summary.handler.source.sourcePath === sourcePath &&\n\t\t\t\t(summary.output.decision === \"block\" || summary.output.decision === \"deny\")) ||\n\t\t\tfalse,\n\t);\n\tif (blocker?.run.exitCode === 2) return POST_TOOL_BLOCK_REASON;\n\treturn result.decision.reason ?? POST_TOOL_BLOCK_REASON;\n}\n\nfunction collectPostToolUseReplacement(\n\tevent: ToolResultEvent,\n\tresult: HookDispatchResult,\n\tpreToolContexts: readonly string[],\n): { readonly content: (TextContent | ImageContent)[]; readonly details?: unknown } | undefined {\n\tlet content: (TextContent | ImageContent)[] = [...event.content];\n\tlet details: unknown = event.details;\n\tlet replaced = false;\n\tconst postToolContexts: string[] = [];\n\tfor (const summary of result.summaries) {\n\t\tconst updated = normalizeUpdatedToolOutput(summary.output.updatedToolOutput);\n\t\tif (updated !== undefined) {\n\t\t\tcontent = [...updated.content];\n\t\t\tdetails = updated.details;\n\t\t\treplaced = true;\n\t\t}\n\t\tconst context = summary.output.additionalContext;\n\t\tif (context !== undefined) {\n\t\t\tpostToolContexts.push(context);\n\t\t}\n\t}\n\tfor (const context of postToolContexts) {\n\t\tcontent.push(contextTextPart(context));\n\t}\n\tfor (const context of preToolContexts) {\n\t\tcontent.push(contextTextPart(context));\n\t}\n\tif (!replaced && postToolContexts.length === 0 && preToolContexts.length === 0) return undefined;\n\treturn { content, ...(details === undefined ? {} : { details }) };\n}\n\nfunction normalizeUpdatedToolOutput(\n\tvalue: unknown,\n): { readonly content: (TextContent | ImageContent)[]; readonly details?: unknown } | undefined {\n\tif (typeof value === \"string\") {\n\t\treturn { content: [{ type: \"text\", text: value }] };\n\t}\n\tif (isContentArray(value)) {\n\t\treturn { content: value };\n\t}\n\tif (!isRecord(value)) return undefined;\n\tconst content = value.content;\n\tif (typeof content === \"string\") {\n\t\treturn { content: [{ type: \"text\", text: content }], details: value.details };\n\t}\n\tif (isContentArray(content)) {\n\t\treturn { content, details: value.details };\n\t}\n\treturn undefined;\n}\n\nfunction replaceToolInput(target: Record<string, unknown>, replacement: Record<string, unknown>): void {\n\tfor (const key of Object.keys(target)) {\n\t\tdelete target[key];\n\t}\n\tObject.assign(target, replacement);\n}\n\nfunction contextTextPart(text: string): TextContent {\n\treturn { type: \"text\", text };\n}\n\nfunction isContentArray(value: unknown): value is (TextContent | ImageContent)[] {\n\treturn Array.isArray(value) && value.every(isContentPart);\n}\n\nfunction isContentPart(value: unknown): value is TextContent | ImageContent {\n\tif (!isRecord(value)) return false;\n\tif (value.type === \"text\") return typeof value.text === \"string\";\n\treturn value.type === \"image\" && typeof value.mimeType === \"string\" && typeof value.data === \"string\";\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type HookTrustStorageScope } from "./trust.ts";
|
|
2
|
+
import type { HookTrustState } from "./types.ts";
|
|
3
|
+
export interface HookStateStorage {
|
|
4
|
+
read(scope: HookTrustStorageScope): HookTrustState;
|
|
5
|
+
update(scope: HookTrustStorageScope, updater: (current: HookTrustState) => HookTrustState): HookTrustState;
|
|
6
|
+
}
|
|
7
|
+
export type FileHookStateStorageOptions = {
|
|
8
|
+
readonly agentDir?: string;
|
|
9
|
+
readonly cwd: string;
|
|
10
|
+
};
|
|
11
|
+
export declare class FileHookStateStorage implements HookStateStorage {
|
|
12
|
+
private readonly globalStatePath;
|
|
13
|
+
private readonly projectStatePath;
|
|
14
|
+
constructor(options: FileHookStateStorageOptions);
|
|
15
|
+
read(scope: HookTrustStorageScope): HookTrustState;
|
|
16
|
+
update(scope: HookTrustStorageScope, updater: (current: HookTrustState) => HookTrustState): HookTrustState;
|
|
17
|
+
}
|
|
18
|
+
export declare class InMemoryHookStateStorage implements HookStateStorage {
|
|
19
|
+
private globalState;
|
|
20
|
+
private projectState;
|
|
21
|
+
read(scope: HookTrustStorageScope): HookTrustState;
|
|
22
|
+
update(scope: HookTrustStorageScope, updater: (current: HookTrustState) => HookTrustState): HookTrustState;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=trust-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust-storage.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/trust-storage.ts"],"names":[],"mappings":"AAIA,OAAO,EAAuB,KAAK,qBAAqB,EAA0B,MAAM,YAAY,CAAC;AACrG,OAAO,KAAK,EAAkB,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjE,MAAM,WAAW,gBAAgB;IAChC,IAAI,CAAC,KAAK,EAAE,qBAAqB,GAAG,cAAc,CAAC;IACnD,MAAM,CAAC,KAAK,EAAE,qBAAqB,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,cAAc,GAAG,cAAc,CAAC;CAC3G;AAED,MAAM,MAAM,2BAA2B,GAAG;IACzC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,qBAAa,oBAAqB,YAAW,gBAAgB;IAC5D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAE1C,YAAY,OAAO,EAAE,2BAA2B,EAI/C;IAED,IAAI,CAAC,KAAK,EAAE,qBAAqB,GAAG,cAAc,CAIjD;IAED,MAAM,CAAC,KAAK,EAAE,qBAAqB,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,cAAc,GAAG,cAAc,CAOzG;CACD;AAED,qBAAa,wBAAyB,YAAW,gBAAgB;IAChE,OAAO,CAAC,WAAW,CAAyC;IAC5D,OAAO,CAAC,YAAY,CAAyC;IAE7D,IAAI,CAAC,KAAK,EAAE,qBAAqB,GAAG,cAAc,CAEjD;IAED,MAAM,CAAC,KAAK,EAAE,qBAAqB,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,cAAc,GAAG,cAAc,CAQzG;CACD"}
|