@code-yeongyu/senpi 2026.7.3 → 2026.7.5-2
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 +37 -1
- package/dist/cli/config-selector.d.ts.map +1 -1
- package/dist/cli/config-selector.js +2 -1
- package/dist/cli/config-selector.js.map +1 -1
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +2 -1
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/dispatcher.d.ts +2 -0
- package/dist/core/extensions/builtin/hooks/dispatcher.d.ts.map +1 -1
- package/dist/core/extensions/builtin/hooks/dispatcher.js +50 -17
- package/dist/core/extensions/builtin/hooks/dispatcher.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/hooks/index.js +11 -1
- package/dist/core/extensions/builtin/hooks/index.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/output-bounds.d.ts.map +1 -1
- package/dist/core/extensions/builtin/hooks/output-bounds.js +3 -7
- package/dist/core/extensions/builtin/hooks/output-bounds.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +3 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +65 -57
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +7 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/hidden-stdout-log.d.ts +2 -0
- package/dist/core/hidden-stdout-log.d.ts.map +1 -0
- package/dist/core/hidden-stdout-log.js +17 -0
- package/dist/core/hidden-stdout-log.js.map +1 -0
- package/dist/core/output-guard.d.ts +2 -0
- package/dist/core/output-guard.d.ts.map +1 -1
- package/dist/core/output-guard.js +63 -0
- package/dist/core/output-guard.js.map +1 -1
- package/dist/core/provider-attribution.d.ts.map +1 -1
- package/dist/core/provider-attribution.js +0 -10
- package/dist/core/provider-attribution.js.map +1 -1
- package/dist/core/sensitive-output.d.ts +3 -0
- package/dist/core/sensitive-output.d.ts.map +1 -0
- package/dist/core/sensitive-output.js +12 -0
- package/dist/core/sensitive-output.js.map +1 -0
- package/dist/core/tools/edit.js +2 -2
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +40 -4
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/interactive-stderr-guard.d.ts +3 -0
- package/dist/modes/interactive/interactive-stderr-guard.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-stderr-guard.js +24 -0
- package/dist/modes/interactive/interactive-stderr-guard.js.map +1 -0
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +7 -0
- package/dist/package-manager-cli.js.map +1 -1
- package/docs/extensions.md +14 -1
- package/examples/sdk/12-full-control.ts +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +115 -19
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +10 -2
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +29 -171
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.models.d.ts +0 -170
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.models.js +3 -173
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/mistral.models.d.ts +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/mistral.models.js +4 -4
- package/node_modules/@earendil-works/pi-ai/dist/providers/mistral.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/nvidia.models.d.ts +28 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/nvidia.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/nvidia.models.js +19 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/nvidia.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js +13 -13
- package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/device-code.d.ts +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/device-code.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/device-code.js +9 -2
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/device-code.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/github-copilot.js +2 -2
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts +17 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js +75 -22
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +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 +4 -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
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [
|
|
3
|
+
## [2026.7.5-2] - 2026-07-05
|
|
4
4
|
|
|
5
5
|
### Added
|
|
6
6
|
|
|
@@ -8,6 +8,42 @@
|
|
|
8
8
|
|
|
9
9
|
### Fixed
|
|
10
10
|
|
|
11
|
+
### Removed
|
|
12
|
+
|
|
13
|
+
## [2026.7.5] - 2026-07-05
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
### Removed
|
|
22
|
+
|
|
23
|
+
## [2026.7.4] - 2026-07-04
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- Added `ctx.updateToolHookStatus()` so `tool_call`/`tool_result` extension handlers can report what they are doing in the live "Running PreToolUse/PostToolUse hook" TUI status row
|
|
28
|
+
- Added inherited generated model catalog refreshes from models.dev, including newly listed models such as Kimi K2.7 Code for GitHub Copilot and Fable 5 providers ([#6256](https://github.com/earendil-works/pi/issues/6256)).
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
|
|
34
|
+
- Fixed TUI screen corruption from external stdout writes: `console.log` from libraries or extensions while a TUI owns the terminal (interactive mode, startup dialogs, config selector) is now hidden from the screen and appended, redacted, to the debug log — matching the existing stderr guard.
|
|
35
|
+
- Fixed the live tool hook status row showing a generic `running builtin:hooks` label instead of the running command hook's configured `statusMessage` (falling back to its sanitized command text)
|
|
36
|
+
- Fixed startup model resolution to await available-model lookups before selecting defaults.
|
|
37
|
+
- Fixed pnpm self-update failures to show a prune hint when package-manager metadata blocks a self-update ([#6279](https://github.com/earendil-works/pi/pull/6279) by [@rajp152k](https://github.com/rajp152k)).
|
|
38
|
+
- Fixed the edit tool schema to allow model-invented extra replacement fields instead of rejecting otherwise valid edits ([#6278](https://github.com/earendil-works/pi/issues/6278)).
|
|
39
|
+
- Fixed inherited OAuth device-code polling to honor the server-provided `slow_down` interval so GitHub Copilot login recovers instead of appearing to hang when polls arrive early ([#6187](https://github.com/earendil-works/pi/issues/6187)).
|
|
40
|
+
- Fixed inherited OpenAI Codex WebSocket sessions to rotate cached connections before the backend's 60-minute limit, avoiding connection-limit failures on long sessions ([#6268](https://github.com/earendil-works/pi/issues/6268)).
|
|
41
|
+
- Fixed inherited retry classification for Cloudflare 524 timeout responses ([#6239](https://github.com/earendil-works/pi/issues/6239)).
|
|
42
|
+
|
|
43
|
+
### Removed
|
|
44
|
+
|
|
45
|
+
- Removed default attribution headers from Vercel AI Gateway requests.
|
|
46
|
+
|
|
11
47
|
## [2026.7.3] - 2026-07-03
|
|
12
48
|
|
|
13
49
|
### Added
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-selector.d.ts","sourceRoot":"","sources":["../../src/cli/config-selector.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"config-selector.d.ts","sourceRoot":"","sources":["../../src/cli/config-selector.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAInE,MAAM,WAAW,qBAAqB;IACrC,aAAa,EAAE,aAAa,CAAC;IAC7B,eAAe,EAAE,eAAe,CAAC;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,sDAAsD;AACtD,wBAAsB,YAAY,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkChF"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* TUI config selector for `pi config` command
|
|
3
3
|
*/
|
|
4
4
|
import { ProcessTerminal, TUI } from "@earendil-works/pi-tui";
|
|
5
|
+
import { appendHiddenTuiStdout } from "../core/hidden-stdout-log.js";
|
|
5
6
|
import { ConfigSelectorComponent } from "../modes/interactive/components/config-selector.js";
|
|
6
7
|
import { initTheme, stopThemeWatcher } from "../modes/interactive/theme/theme.js";
|
|
7
8
|
/** Show TUI config selector and return when closed */
|
|
@@ -9,7 +10,7 @@ export async function selectConfig(options) {
|
|
|
9
10
|
// Initialize theme before showing TUI
|
|
10
11
|
initTheme(options.settingsManager.getTheme(), true);
|
|
11
12
|
return new Promise((resolve) => {
|
|
12
|
-
const ui = new TUI(new ProcessTerminal());
|
|
13
|
+
const ui = new TUI(new ProcessTerminal({ onExternalStdoutWrite: appendHiddenTuiStdout }));
|
|
13
14
|
let resolved = false;
|
|
14
15
|
const selector = new ConfigSelectorComponent(options.resolvedPaths, options.settingsManager, options.cwd, options.agentDir, () => {
|
|
15
16
|
if (!resolved) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-selector.js","sourceRoot":"","sources":["../../src/cli/config-selector.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"config-selector.js","sourceRoot":"","sources":["../../src/cli/config-selector.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAGrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,oDAAoD,CAAC;AAC7F,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AASlF,sDAAsD;AACtD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAA8B;IAChE,sCAAsC;IACtC,SAAS,CAAC,OAAO,CAAC,eAAe,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,CAAC;IAEpD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC9B,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,IAAI,eAAe,CAAC,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,CAAC,CAAC,CAAC;QAC1F,IAAI,QAAQ,GAAG,KAAK,CAAC;QAErB,MAAM,QAAQ,GAAG,IAAI,uBAAuB,CAC3C,OAAO,CAAC,aAAa,EACrB,OAAO,CAAC,eAAe,EACvB,OAAO,CAAC,GAAG,EACX,OAAO,CAAC,QAAQ,EAChB,GAAG,EAAE;YACJ,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACf,QAAQ,GAAG,IAAI,CAAC;gBAChB,EAAE,CAAC,IAAI,EAAE,CAAC;gBACV,gBAAgB,EAAE,CAAC;gBACnB,OAAO,EAAE,CAAC;YACX,CAAC;QACF,CAAC,EACD,GAAG,EAAE;YACJ,EAAE,CAAC,IAAI,EAAE,CAAC;YACV,gBAAgB,EAAE,CAAC;YACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC,EACD,GAAG,EAAE,CAAC,EAAE,CAAC,aAAa,EAAE,EACxB,EAAE,CAAC,QAAQ,CAAC,IAAI,CAChB,CAAC;QAEF,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACtB,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,eAAe,EAAE,CAAC,CAAC;QACxC,EAAE,CAAC,KAAK,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;AACJ,CAAC","sourcesContent":["/**\n * TUI config selector for `pi config` command\n */\n\nimport { ProcessTerminal, TUI } from \"@earendil-works/pi-tui\";\nimport { appendHiddenTuiStdout } from \"../core/hidden-stdout-log.ts\";\nimport type { ResolvedPaths } from \"../core/package-manager.ts\";\nimport type { SettingsManager } from \"../core/settings-manager.ts\";\nimport { ConfigSelectorComponent } from \"../modes/interactive/components/config-selector.ts\";\nimport { initTheme, stopThemeWatcher } from \"../modes/interactive/theme/theme.ts\";\n\nexport interface ConfigSelectorOptions {\n\tresolvedPaths: ResolvedPaths;\n\tsettingsManager: SettingsManager;\n\tcwd: string;\n\tagentDir: string;\n}\n\n/** Show TUI config selector and return when closed */\nexport async function selectConfig(options: ConfigSelectorOptions): Promise<void> {\n\t// Initialize theme before showing TUI\n\tinitTheme(options.settingsManager.getTheme(), true);\n\n\treturn new Promise((resolve) => {\n\t\tconst ui = new TUI(new ProcessTerminal({ onExternalStdoutWrite: appendHiddenTuiStdout }));\n\t\tlet resolved = false;\n\n\t\tconst selector = new ConfigSelectorComponent(\n\t\t\toptions.resolvedPaths,\n\t\t\toptions.settingsManager,\n\t\t\toptions.cwd,\n\t\t\toptions.agentDir,\n\t\t\t() => {\n\t\t\t\tif (!resolved) {\n\t\t\t\t\tresolved = true;\n\t\t\t\t\tui.stop();\n\t\t\t\t\tstopThemeWatcher();\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tui.stop();\n\t\t\t\tstopThemeWatcher();\n\t\t\t\tprocess.exit(0);\n\t\t\t},\n\t\t\t() => ui.requestRender(),\n\t\t\tui.terminal.rows,\n\t\t);\n\n\t\tui.addChild(selector);\n\t\tui.setFocus(selector.getResourceList());\n\t\tui.start();\n\t});\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startup-ui.d.ts","sourceRoot":"","sources":["../../src/cli/startup-ui.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmC,GAAG,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"startup-ui.d.ts","sourceRoot":"","sources":["../../src/cli/startup-ui.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmC,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAO9E,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAsE9D,wBAAsB,gBAAgB,CAAC,eAAe,EAAE,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,CAWrF;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,GAAG,EAAE,eAAe,EAAE,eAAe,GAAG,IAAI,CAG/E;AAkBD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,YAAY,GAAE,MAA0B,GAAG,OAAO,CAiBzF;AAED,wBAAsB,mBAAmB,CAAC,CAAC,EAC1C,eAAe,EAAE,eAAe,EAChC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,CAAC,GACzC,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAyBxB;AAED,8DAA8D;AAC9D,wBAAsB,kBAAkB,CAAC,eAAe,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAuCxF;AAED,wBAAsB,gBAAgB,CACrC,eAAe,EAAE,eAAe,EAChC,KAAK,EAAE,MAAM,EACb,WAAW,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA4B7B"}
|
package/dist/cli/startup-ui.js
CHANGED
|
@@ -2,6 +2,7 @@ import { ProcessTerminal, setKeybindings, TUI } from "@earendil-works/pi-tui";
|
|
|
2
2
|
import { existsSync } from "fs";
|
|
3
3
|
import { APP_NAME, CONFIG_DIR_NAME, ENV_AGENT_DIR, getAgentDir, getSettingsPath, PACKAGE_NAME } from "../config.js";
|
|
4
4
|
import { areExperimentalFeaturesEnabled } from "../core/experimental.js";
|
|
5
|
+
import { appendHiddenTuiStdout } from "../core/hidden-stdout-log.js";
|
|
5
6
|
import { KeybindingsManager } from "../core/keybindings.js";
|
|
6
7
|
import { DefaultPackageManager } from "../core/package-manager.js";
|
|
7
8
|
import { SettingsManager } from "../core/settings-manager.js";
|
|
@@ -56,7 +57,7 @@ export async function createStartupTui(settingsManager) {
|
|
|
56
57
|
const terminalTheme = detectTerminalBackgroundFromEnv().theme;
|
|
57
58
|
initTheme(resolveThemeSetting(settingsManager.getThemeSetting(), terminalTheme) ?? terminalTheme);
|
|
58
59
|
setKeybindings(KeybindingsManager.create());
|
|
59
|
-
const ui = new TUI(new ProcessTerminal(), settingsManager.getShowHardwareCursor());
|
|
60
|
+
const ui = new TUI(new ProcessTerminal({ onExternalStdoutWrite: appendHiddenTuiStdout }), settingsManager.getShowHardwareCursor());
|
|
60
61
|
ui.setClearOnShrink(settingsManager.getClearOnShrink());
|
|
61
62
|
return ui;
|
|
62
63
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startup-ui.js","sourceRoot":"","sources":["../../src/cli/startup-ui.ts"],"names":[],"mappings":"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","sourcesContent":["import { ProcessTerminal, setKeybindings, TUI } from \"@earendil-works/pi-tui\";\nimport { existsSync } from \"fs\";\nimport { APP_NAME, CONFIG_DIR_NAME, ENV_AGENT_DIR, getAgentDir, getSettingsPath, PACKAGE_NAME } from \"../config.ts\";\nimport { areExperimentalFeaturesEnabled } from \"../core/experimental.ts\";\nimport { KeybindingsManager } from \"../core/keybindings.ts\";\nimport { DefaultPackageManager, type ResolvedResource } from \"../core/package-manager.ts\";\nimport { SettingsManager } from \"../core/settings-manager.ts\";\nimport { ExtensionInputComponent } from \"../modes/interactive/components/extension-input.ts\";\nimport { ExtensionSelectorComponent } from \"../modes/interactive/components/extension-selector.ts\";\nimport {\n\tFirstTimeSetupComponent,\n\ttype FirstTimeSetupResult,\n} from \"../modes/interactive/components/first-time-setup.ts\";\nimport {\n\tdetectTerminalBackgroundFromEnv,\n\tdetectTerminalThemeForAuto,\n\tinitTheme,\n\tloadThemeFromPath,\n\tparseAutoThemeSetting,\n\tresolveThemeSetting,\n\tsetRegisteredThemes,\n\tsetTheme,\n\ttype Theme,\n} from \"../modes/interactive/theme/theme.ts\";\n\nconst OFFICIAL_PACKAGE_NAME = \"@earendil-works/pi-coding-agent\";\nconst OFFICIAL_APP_NAME = \"pi\";\nconst OFFICIAL_CONFIG_DIR_NAME = \".pi\";\n\ninterface DistributionMetadata {\n\tpackageName: string;\n\tappName: string;\n\tconfigDirName: string;\n}\n\nfunction isOfficialDistribution({ packageName, appName, configDirName }: DistributionMetadata): boolean {\n\treturn (\n\t\tpackageName === OFFICIAL_PACKAGE_NAME &&\n\t\tappName === OFFICIAL_APP_NAME &&\n\t\tconfigDirName === OFFICIAL_CONFIG_DIR_NAME\n\t);\n}\n\nfunction loadThemes(resources: ResolvedResource[]): Theme[] {\n\tconst themes: Theme[] = [];\n\tconst seen = new Set<string>();\n\tfor (const resource of resources) {\n\t\tif (!resource.enabled) continue;\n\t\ttry {\n\t\t\tconst loadedTheme = loadThemeFromPath(resource.path);\n\t\t\tif (loadedTheme.name) {\n\t\t\t\tif (seen.has(loadedTheme.name)) continue;\n\t\t\t\tseen.add(loadedTheme.name);\n\t\t\t}\n\t\t\tthemes.push(loadedTheme);\n\t\t} catch {\n\t\t\t// Startup prompts should not fail because a theme is broken. The normal\n\t\t\t// resource loader reports theme diagnostics later in startup.\n\t\t}\n\t}\n\treturn themes;\n}\n\nasync function loadStartupThemes(settingsManager: SettingsManager): Promise<Theme[]> {\n\tconst globalSettingsManager = SettingsManager.inMemory(settingsManager.getGlobalSettings(), {\n\t\tprojectTrusted: false,\n\t});\n\tconst packageManager = new DefaultPackageManager({\n\t\tcwd: process.cwd(),\n\t\tagentDir: getAgentDir(),\n\t\tsettingsManager: globalSettingsManager,\n\t});\n\tconst resolvedPaths = await packageManager.resolve(async () => \"skip\");\n\treturn loadThemes(resolvedPaths.themes);\n}\n\nexport async function createStartupTui(settingsManager: SettingsManager): Promise<TUI> {\n\tsetRegisteredThemes(await loadStartupThemes(settingsManager));\n\tconst terminalTheme = detectTerminalBackgroundFromEnv().theme;\n\tinitTheme(resolveThemeSetting(settingsManager.getThemeSetting(), terminalTheme) ?? terminalTheme);\n\tsetKeybindings(KeybindingsManager.create());\n\tconst ui = new TUI(new ProcessTerminal(), settingsManager.getShowHardwareCursor());\n\tui.setClearOnShrink(settingsManager.getClearOnShrink());\n\treturn ui;\n}\n\nexport function startStartupTui(ui: TUI, settingsManager: SettingsManager): void {\n\tui.start();\n\tvoid applyDetectedStartupTheme(ui, settingsManager);\n}\n\nasync function applyDetectedStartupTheme(ui: TUI, settingsManager: SettingsManager): Promise<void> {\n\tconst themeSetting = settingsManager.getThemeSetting();\n\tif (themeSetting && !parseAutoThemeSetting(themeSetting)) return;\n\n\tconst terminalTheme = await detectTerminalThemeForAuto({ ui, timeoutMs: 100 });\n\tsetTheme(resolveThemeSetting(themeSetting, terminalTheme) ?? terminalTheme);\n\tui.invalidate();\n\tui.requestRender();\n}\n\nasync function clearStartupTui(ui: TUI): Promise<void> {\n\tui.clear();\n\tui.requestRender();\n\tawait new Promise((resolve) => setTimeout(resolve, 25));\n}\n\n/**\n * First-time setup runs when all of these hold:\n * - this is the official Pi distribution (not a fork/rebrand)\n * - experimental features are enabled (PI_EXPERIMENTAL=1)\n * - the default agent directory is used (no custom agent dir override)\n * - setup was not completed before (settings.json does not exist)\n */\nexport function shouldRunFirstTimeSetup(settingsPath: string = getSettingsPath()): boolean {\n\tif (\n\t\t!isOfficialDistribution({\n\t\t\tpackageName: PACKAGE_NAME,\n\t\t\tappName: APP_NAME,\n\t\t\tconfigDirName: CONFIG_DIR_NAME,\n\t\t})\n\t) {\n\t\treturn false;\n\t}\n\tif (!areExperimentalFeaturesEnabled()) {\n\t\treturn false;\n\t}\n\tif (process.env[ENV_AGENT_DIR]) {\n\t\treturn false;\n\t}\n\treturn !existsSync(settingsPath);\n}\n\nexport async function showStartupSelector<T>(\n\tsettingsManager: SettingsManager,\n\ttitle: string,\n\toptions: Array<{ label: string; value: T }>,\n): Promise<T | undefined> {\n\tconst ui = await createStartupTui(settingsManager);\n\treturn new Promise((resolve) => {\n\t\tlet settled = false;\n\t\tconst finish = async (result: T | undefined) => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\tawait clearStartupTui(ui);\n\t\t\tui.stop();\n\t\t\tresolve(result);\n\t\t};\n\n\t\tconst selector = new ExtensionSelectorComponent(\n\t\t\ttitle,\n\t\t\toptions.map((option) => option.label),\n\t\t\t(option) => void finish(options.find((entry) => entry.label === option)?.value),\n\t\t\t() => void finish(undefined),\n\t\t\t{ tui: ui },\n\t\t);\n\t\tui.addChild(selector);\n\t\tui.setFocus(selector);\n\t\tstartStartupTui(ui, settingsManager);\n\t});\n}\n\n/** Show the first-time setup dialog and persist the result */\nexport async function showFirstTimeSetup(settingsManager: SettingsManager): Promise<void> {\n\tconst ui = await createStartupTui(settingsManager);\n\treturn new Promise((resolve) => {\n\t\tlet settled = false;\n\t\tconst finish = async (result: FirstTimeSetupResult | undefined) => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\tif (result) {\n\t\t\t\tsettingsManager.setTheme(result.theme);\n\t\t\t\tsettingsManager.setEnableAnalytics(result.shareAnalytics);\n\t\t\t\tawait settingsManager.flush();\n\t\t\t}\n\t\t\tawait clearStartupTui(ui);\n\t\t\tui.stop();\n\t\t\tresolve();\n\t\t};\n\n\t\tconst showSetup = async () => {\n\t\t\tui.start();\n\t\t\tconst detectedTheme = await detectTerminalThemeForAuto({ ui, timeoutMs: 100 });\n\t\t\tsetTheme(detectedTheme);\n\t\t\tconst component = new FirstTimeSetupComponent({\n\t\t\t\tdetectedTheme,\n\t\t\t\tonThemePreview: (themeName) => {\n\t\t\t\t\tsetTheme(themeName);\n\t\t\t\t\tui.requestRender();\n\t\t\t\t},\n\t\t\t\tonSubmit: (result) => void finish(result),\n\t\t\t\tonCancel: () => void finish(undefined),\n\t\t\t});\n\t\t\tui.addChild(component);\n\t\t\tui.setFocus(component);\n\t\t\tui.requestRender();\n\t\t};\n\n\t\tvoid showSetup();\n\t});\n}\n\nexport async function showStartupInput(\n\tsettingsManager: SettingsManager,\n\ttitle: string,\n\tplaceholder?: string,\n): Promise<string | undefined> {\n\tconst ui = await createStartupTui(settingsManager);\n\treturn new Promise((resolve) => {\n\t\tlet settled = false;\n\t\tconst finish = async (result: string | undefined) => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\tinput.dispose();\n\t\t\tawait clearStartupTui(ui);\n\t\t\tui.stop();\n\t\t\tresolve(result);\n\t\t};\n\n\t\tconst input = new ExtensionInputComponent(\n\t\t\ttitle,\n\t\t\tplaceholder,\n\t\t\t(value) => void finish(value),\n\t\t\t() => void finish(undefined),\n\t\t\t{\n\t\t\t\ttui: ui,\n\t\t\t},\n\t\t);\n\t\tui.addChild(input);\n\t\tui.setFocus(input);\n\t\tstartStartupTui(ui, settingsManager);\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"startup-ui.js","sourceRoot":"","sources":["../../src/cli/startup-ui.ts"],"names":[],"mappings":"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","sourcesContent":["import { ProcessTerminal, setKeybindings, TUI } from \"@earendil-works/pi-tui\";\nimport { existsSync } from \"fs\";\nimport { APP_NAME, CONFIG_DIR_NAME, ENV_AGENT_DIR, getAgentDir, getSettingsPath, PACKAGE_NAME } from \"../config.ts\";\nimport { areExperimentalFeaturesEnabled } from \"../core/experimental.ts\";\nimport { appendHiddenTuiStdout } from \"../core/hidden-stdout-log.ts\";\nimport { KeybindingsManager } from \"../core/keybindings.ts\";\nimport { DefaultPackageManager, type ResolvedResource } from \"../core/package-manager.ts\";\nimport { SettingsManager } from \"../core/settings-manager.ts\";\nimport { ExtensionInputComponent } from \"../modes/interactive/components/extension-input.ts\";\nimport { ExtensionSelectorComponent } from \"../modes/interactive/components/extension-selector.ts\";\nimport {\n\tFirstTimeSetupComponent,\n\ttype FirstTimeSetupResult,\n} from \"../modes/interactive/components/first-time-setup.ts\";\nimport {\n\tdetectTerminalBackgroundFromEnv,\n\tdetectTerminalThemeForAuto,\n\tinitTheme,\n\tloadThemeFromPath,\n\tparseAutoThemeSetting,\n\tresolveThemeSetting,\n\tsetRegisteredThemes,\n\tsetTheme,\n\ttype Theme,\n} from \"../modes/interactive/theme/theme.ts\";\n\nconst OFFICIAL_PACKAGE_NAME = \"@earendil-works/pi-coding-agent\";\nconst OFFICIAL_APP_NAME = \"pi\";\nconst OFFICIAL_CONFIG_DIR_NAME = \".pi\";\n\ninterface DistributionMetadata {\n\tpackageName: string;\n\tappName: string;\n\tconfigDirName: string;\n}\n\nfunction isOfficialDistribution({ packageName, appName, configDirName }: DistributionMetadata): boolean {\n\treturn (\n\t\tpackageName === OFFICIAL_PACKAGE_NAME &&\n\t\tappName === OFFICIAL_APP_NAME &&\n\t\tconfigDirName === OFFICIAL_CONFIG_DIR_NAME\n\t);\n}\n\nfunction loadThemes(resources: ResolvedResource[]): Theme[] {\n\tconst themes: Theme[] = [];\n\tconst seen = new Set<string>();\n\tfor (const resource of resources) {\n\t\tif (!resource.enabled) continue;\n\t\ttry {\n\t\t\tconst loadedTheme = loadThemeFromPath(resource.path);\n\t\t\tif (loadedTheme.name) {\n\t\t\t\tif (seen.has(loadedTheme.name)) continue;\n\t\t\t\tseen.add(loadedTheme.name);\n\t\t\t}\n\t\t\tthemes.push(loadedTheme);\n\t\t} catch {\n\t\t\t// Startup prompts should not fail because a theme is broken. The normal\n\t\t\t// resource loader reports theme diagnostics later in startup.\n\t\t}\n\t}\n\treturn themes;\n}\n\nasync function loadStartupThemes(settingsManager: SettingsManager): Promise<Theme[]> {\n\tconst globalSettingsManager = SettingsManager.inMemory(settingsManager.getGlobalSettings(), {\n\t\tprojectTrusted: false,\n\t});\n\tconst packageManager = new DefaultPackageManager({\n\t\tcwd: process.cwd(),\n\t\tagentDir: getAgentDir(),\n\t\tsettingsManager: globalSettingsManager,\n\t});\n\tconst resolvedPaths = await packageManager.resolve(async () => \"skip\");\n\treturn loadThemes(resolvedPaths.themes);\n}\n\nexport async function createStartupTui(settingsManager: SettingsManager): Promise<TUI> {\n\tsetRegisteredThemes(await loadStartupThemes(settingsManager));\n\tconst terminalTheme = detectTerminalBackgroundFromEnv().theme;\n\tinitTheme(resolveThemeSetting(settingsManager.getThemeSetting(), terminalTheme) ?? terminalTheme);\n\tsetKeybindings(KeybindingsManager.create());\n\tconst ui = new TUI(\n\t\tnew ProcessTerminal({ onExternalStdoutWrite: appendHiddenTuiStdout }),\n\t\tsettingsManager.getShowHardwareCursor(),\n\t);\n\tui.setClearOnShrink(settingsManager.getClearOnShrink());\n\treturn ui;\n}\n\nexport function startStartupTui(ui: TUI, settingsManager: SettingsManager): void {\n\tui.start();\n\tvoid applyDetectedStartupTheme(ui, settingsManager);\n}\n\nasync function applyDetectedStartupTheme(ui: TUI, settingsManager: SettingsManager): Promise<void> {\n\tconst themeSetting = settingsManager.getThemeSetting();\n\tif (themeSetting && !parseAutoThemeSetting(themeSetting)) return;\n\n\tconst terminalTheme = await detectTerminalThemeForAuto({ ui, timeoutMs: 100 });\n\tsetTheme(resolveThemeSetting(themeSetting, terminalTheme) ?? terminalTheme);\n\tui.invalidate();\n\tui.requestRender();\n}\n\nasync function clearStartupTui(ui: TUI): Promise<void> {\n\tui.clear();\n\tui.requestRender();\n\tawait new Promise((resolve) => setTimeout(resolve, 25));\n}\n\n/**\n * First-time setup runs when all of these hold:\n * - this is the official Pi distribution (not a fork/rebrand)\n * - experimental features are enabled (PI_EXPERIMENTAL=1)\n * - the default agent directory is used (no custom agent dir override)\n * - setup was not completed before (settings.json does not exist)\n */\nexport function shouldRunFirstTimeSetup(settingsPath: string = getSettingsPath()): boolean {\n\tif (\n\t\t!isOfficialDistribution({\n\t\t\tpackageName: PACKAGE_NAME,\n\t\t\tappName: APP_NAME,\n\t\t\tconfigDirName: CONFIG_DIR_NAME,\n\t\t})\n\t) {\n\t\treturn false;\n\t}\n\tif (!areExperimentalFeaturesEnabled()) {\n\t\treturn false;\n\t}\n\tif (process.env[ENV_AGENT_DIR]) {\n\t\treturn false;\n\t}\n\treturn !existsSync(settingsPath);\n}\n\nexport async function showStartupSelector<T>(\n\tsettingsManager: SettingsManager,\n\ttitle: string,\n\toptions: Array<{ label: string; value: T }>,\n): Promise<T | undefined> {\n\tconst ui = await createStartupTui(settingsManager);\n\treturn new Promise((resolve) => {\n\t\tlet settled = false;\n\t\tconst finish = async (result: T | undefined) => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\tawait clearStartupTui(ui);\n\t\t\tui.stop();\n\t\t\tresolve(result);\n\t\t};\n\n\t\tconst selector = new ExtensionSelectorComponent(\n\t\t\ttitle,\n\t\t\toptions.map((option) => option.label),\n\t\t\t(option) => void finish(options.find((entry) => entry.label === option)?.value),\n\t\t\t() => void finish(undefined),\n\t\t\t{ tui: ui },\n\t\t);\n\t\tui.addChild(selector);\n\t\tui.setFocus(selector);\n\t\tstartStartupTui(ui, settingsManager);\n\t});\n}\n\n/** Show the first-time setup dialog and persist the result */\nexport async function showFirstTimeSetup(settingsManager: SettingsManager): Promise<void> {\n\tconst ui = await createStartupTui(settingsManager);\n\treturn new Promise((resolve) => {\n\t\tlet settled = false;\n\t\tconst finish = async (result: FirstTimeSetupResult | undefined) => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\tif (result) {\n\t\t\t\tsettingsManager.setTheme(result.theme);\n\t\t\t\tsettingsManager.setEnableAnalytics(result.shareAnalytics);\n\t\t\t\tawait settingsManager.flush();\n\t\t\t}\n\t\t\tawait clearStartupTui(ui);\n\t\t\tui.stop();\n\t\t\tresolve();\n\t\t};\n\n\t\tconst showSetup = async () => {\n\t\t\tui.start();\n\t\t\tconst detectedTheme = await detectTerminalThemeForAuto({ ui, timeoutMs: 100 });\n\t\t\tsetTheme(detectedTheme);\n\t\t\tconst component = new FirstTimeSetupComponent({\n\t\t\t\tdetectedTheme,\n\t\t\t\tonThemePreview: (themeName) => {\n\t\t\t\t\tsetTheme(themeName);\n\t\t\t\t\tui.requestRender();\n\t\t\t\t},\n\t\t\t\tonSubmit: (result) => void finish(result),\n\t\t\t\tonCancel: () => void finish(undefined),\n\t\t\t});\n\t\t\tui.addChild(component);\n\t\t\tui.setFocus(component);\n\t\t\tui.requestRender();\n\t\t};\n\n\t\tvoid showSetup();\n\t});\n}\n\nexport async function showStartupInput(\n\tsettingsManager: SettingsManager,\n\ttitle: string,\n\tplaceholder?: string,\n): Promise<string | undefined> {\n\tconst ui = await createStartupTui(settingsManager);\n\treturn new Promise((resolve) => {\n\t\tlet settled = false;\n\t\tconst finish = async (result: string | undefined) => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\tinput.dispose();\n\t\t\tawait clearStartupTui(ui);\n\t\t\tui.stop();\n\t\t\tresolve(result);\n\t\t};\n\n\t\tconst input = new ExtensionInputComponent(\n\t\t\ttitle,\n\t\t\tplaceholder,\n\t\t\t(value) => void finish(value),\n\t\t\t() => void finish(undefined),\n\t\t\t{\n\t\t\t\ttui: ui,\n\t\t\t},\n\t\t);\n\t\tui.addChild(input);\n\t\tui.setFocus(input);\n\t\tstartStartupTui(ui, settingsManager);\n\t});\n}\n"]}
|
|
@@ -49,6 +49,7 @@ export type HookDispatchOptions = {
|
|
|
49
49
|
readonly envPassthrough?: readonly string[];
|
|
50
50
|
readonly handlers: readonly ExecutableHookHandler[];
|
|
51
51
|
readonly input: HookInputWire;
|
|
52
|
+
readonly onRunningHandlersChange?: (running: readonly ExecutableHookHandler[]) => void;
|
|
52
53
|
readonly outputPolicy?: HookOutputPolicy;
|
|
53
54
|
readonly runCommand?: HookCommandRunner;
|
|
54
55
|
readonly signal?: AbortSignal;
|
|
@@ -57,4 +58,5 @@ export type HookDispatchOptions = {
|
|
|
57
58
|
readonly trustState: HookTrustState;
|
|
58
59
|
};
|
|
59
60
|
export declare function dispatchHookEvent(options: HookDispatchOptions): Promise<HookDispatchResult>;
|
|
61
|
+
export declare function runningHookHandlersStatusLabel(handlers: readonly ExecutableHookHandler[], platform?: NodeJS.Platform): string;
|
|
60
62
|
//# sourceMappingURL=dispatcher.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/dispatcher.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/dispatcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { stripAnsi } from "../../../../utils/ansi.js";
|
|
1
2
|
import { runCommandHook } from "./command-runner.js";
|
|
2
3
|
import { matchingHookHandlers } from "./matcher.js";
|
|
3
4
|
import { parseHookOutput } from "./output-parser.js";
|
|
@@ -9,24 +10,41 @@ export async function dispatchHookEvent(options) {
|
|
|
9
10
|
const selected = selectExecutableHandlers(ordered, options.trustState, options.trustOptions);
|
|
10
11
|
let nextCompletionIndex = 0;
|
|
11
12
|
const runner = options.runCommand ?? runCommandHook;
|
|
13
|
+
const notifyRunningChange = options.onRunningHandlersChange;
|
|
14
|
+
const runningHandlers = [];
|
|
12
15
|
const completed = await Promise.all(selected.runnable.map(async ({ handler, declarationIndex }) => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
...
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
16
|
+
if (notifyRunningChange !== undefined) {
|
|
17
|
+
runningHandlers.push(handler);
|
|
18
|
+
notifyRunningChange([...runningHandlers]);
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
const run = await runner(handler, options.input, {
|
|
22
|
+
cwd: options.cwd,
|
|
23
|
+
...(options.envPassthrough === undefined ? {} : { envPassthrough: options.envPassthrough }),
|
|
24
|
+
...(options.outputPolicy === undefined ? {} : { outputPolicy: options.outputPolicy }),
|
|
25
|
+
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
26
|
+
...(options.sourceEnv === undefined ? {} : { sourceEnv: options.sourceEnv }),
|
|
27
|
+
});
|
|
28
|
+
const parsed = parseHookOutput({
|
|
29
|
+
event: options.input.event,
|
|
30
|
+
exitCode: run.exitCode ?? 1,
|
|
31
|
+
source: handler.source,
|
|
32
|
+
stderr: run.stderr,
|
|
33
|
+
stdout: run.stdout,
|
|
34
|
+
});
|
|
35
|
+
const completionIndex = nextCompletionIndex;
|
|
36
|
+
nextCompletionIndex += 1;
|
|
37
|
+
return { completionIndex, declarationIndex, handler, parsed, run };
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
if (notifyRunningChange !== undefined) {
|
|
41
|
+
const runningIndex = runningHandlers.indexOf(handler);
|
|
42
|
+
if (runningIndex !== -1) {
|
|
43
|
+
runningHandlers.splice(runningIndex, 1);
|
|
44
|
+
}
|
|
45
|
+
notifyRunningChange([...runningHandlers]);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
30
48
|
}));
|
|
31
49
|
const declarationSummaries = completed
|
|
32
50
|
.toSorted((left, right) => left.declarationIndex - right.declarationIndex)
|
|
@@ -51,6 +69,21 @@ export async function dispatchHookEvent(options) {
|
|
|
51
69
|
summaries: declarationSummaries,
|
|
52
70
|
};
|
|
53
71
|
}
|
|
72
|
+
export function runningHookHandlersStatusLabel(handlers, platform = process.platform) {
|
|
73
|
+
const label = handlers.map((handler) => hookHandlerStatusLabel(handler, platform)).join(" · ");
|
|
74
|
+
return label.length <= 79 ? label : `${label.slice(0, 76)}...`;
|
|
75
|
+
}
|
|
76
|
+
function hookHandlerStatusLabel(handler, platform) {
|
|
77
|
+
const raw = handler.config.statusMessage ??
|
|
78
|
+
(platform === "win32" && handler.config.commandWindows !== undefined
|
|
79
|
+
? handler.config.commandWindows
|
|
80
|
+
: handler.config.command);
|
|
81
|
+
return stripAnsi(raw)
|
|
82
|
+
.replace(/[\r\n\t]+/g, " ")
|
|
83
|
+
.replace(/[\u0000-\u001f\u007f]+/g, "")
|
|
84
|
+
.replace(/\s+/g, " ")
|
|
85
|
+
.trim();
|
|
86
|
+
}
|
|
54
87
|
function declarationOrdered(handlers) {
|
|
55
88
|
return handlers
|
|
56
89
|
.map((handler, index) => ({ declarationIndex: index, handler }))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/dispatcher.ts"],"names":[],"mappings":"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","sourcesContent":["import { type CommandHookRunOptions, type CommandHookRunResult, runCommandHook } from \"./command-runner.ts\";\nimport { matchingHookHandlers } from \"./matcher.ts\";\nimport { type ParsedHookOutput, parseHookOutput } from \"./output-parser.ts\";\nimport { type HookOutputPolicy, validateHookHandlerSafety } from \"./safety.ts\";\nimport { type HookTrustOptions, type HookTrustRecord, listHookTrustRecords } from \"./trust.ts\";\nimport type {\n\tExecutableHookHandler,\n\tHookDiagnostic,\n\tHookInputWire,\n\tHookSourceMetadata,\n\tHookTrustState,\n} from \"./types.ts\";\n\nexport type HookCommandRunner = (\n\thandler: ExecutableHookHandler,\n\tinput: HookInputWire,\n\toptions: CommandHookRunOptions,\n) => Promise<CommandHookRunResult>;\n\nexport type HookDispatchDecision =\n\t| { readonly kind: \"none\" }\n\t| {\n\t\t\treadonly kind: \"allow\" | \"block\";\n\t\t\treadonly reason?: string;\n\t\t\treadonly source: HookSourceMetadata;\n\t\t\treadonly sourceCommand: string;\n\t\t\treadonly updatedInput?: unknown;\n\t }\n\t| {\n\t\t\treadonly fallback: { readonly kind: \"block\"; readonly reason: string };\n\t\t\treadonly kind: \"ask\";\n\t\t\treadonly nativeRepresentable: false;\n\t\t\treadonly reason?: string;\n\t\t\treadonly source: HookSourceMetadata;\n\t\t\treadonly sourceCommand: string;\n\t };\n\nexport type HookDispatchSkipped = {\n\treadonly diagnostics: readonly HookDiagnostic[];\n\treadonly handler: ExecutableHookHandler;\n\treadonly reason: \"disabled\" | \"untrusted\" | \"unsafe\";\n\treadonly record: HookTrustRecord;\n};\n\nexport type HookDispatchSummary = {\n\treadonly completionIndex: number;\n\treadonly diagnostics: readonly HookDiagnostic[];\n\treadonly handler: ExecutableHookHandler;\n\treadonly output: ParsedHookOutput[\"output\"];\n\treadonly run: CommandHookRunResult;\n};\n\nexport type HookDispatchResult = {\n\treadonly decision: HookDispatchDecision;\n\treadonly diagnostics: readonly HookDiagnostic[];\n\treadonly executableHandlers: readonly ExecutableHookHandler[];\n\treadonly matchedHandlers: readonly ExecutableHookHandler[];\n\treadonly skipped: readonly HookDispatchSkipped[];\n\treadonly summaries: readonly HookDispatchSummary[];\n};\n\nexport type HookDispatchOptions = {\n\treadonly cwd: string;\n\treadonly envPassthrough?: readonly string[];\n\treadonly handlers: readonly ExecutableHookHandler[];\n\treadonly input: HookInputWire;\n\treadonly outputPolicy?: HookOutputPolicy;\n\treadonly runCommand?: HookCommandRunner;\n\treadonly signal?: AbortSignal;\n\treadonly sourceEnv?: NodeJS.ProcessEnv;\n\treadonly trustOptions?: HookTrustOptions;\n\treadonly trustState: HookTrustState;\n};\n\ntype OrderedHandler = {\n\treadonly declarationIndex: number;\n\treadonly handler: ExecutableHookHandler;\n};\n\ntype RunnableHandler = OrderedHandler & {\n\treadonly record: HookTrustRecord;\n};\n\nexport async function dispatchHookEvent(options: HookDispatchOptions): Promise<HookDispatchResult> {\n\tconst match = matchingHookHandlers(options.input, options.handlers);\n\tconst ordered = declarationOrdered(match.handlers);\n\tconst selected = selectExecutableHandlers(ordered, options.trustState, options.trustOptions);\n\tlet nextCompletionIndex = 0;\n\tconst runner = options.runCommand ?? runCommandHook;\n\tconst completed = await Promise.all(\n\t\tselected.runnable.map(async ({ handler, declarationIndex }) => {\n\t\t\tconst run = await runner(handler, options.input, {\n\t\t\t\tcwd: options.cwd,\n\t\t\t\t...(options.envPassthrough === undefined ? {} : { envPassthrough: options.envPassthrough }),\n\t\t\t\t...(options.outputPolicy === undefined ? {} : { outputPolicy: options.outputPolicy }),\n\t\t\t\t...(options.signal === undefined ? {} : { signal: options.signal }),\n\t\t\t\t...(options.sourceEnv === undefined ? {} : { sourceEnv: options.sourceEnv }),\n\t\t\t});\n\t\t\tconst parsed = parseHookOutput({\n\t\t\t\tevent: options.input.event,\n\t\t\t\texitCode: run.exitCode ?? 1,\n\t\t\t\tsource: handler.source,\n\t\t\t\tstderr: run.stderr,\n\t\t\t\tstdout: run.stdout,\n\t\t\t});\n\t\t\tconst completionIndex = nextCompletionIndex;\n\t\t\tnextCompletionIndex += 1;\n\t\t\treturn { completionIndex, declarationIndex, handler, parsed, run };\n\t\t}),\n\t);\n\tconst declarationSummaries = completed\n\t\t.toSorted((left, right) => left.declarationIndex - right.declarationIndex)\n\t\t.map((run) => ({\n\t\t\tcompletionIndex: run.completionIndex,\n\t\t\tdiagnostics: run.parsed.diagnostics,\n\t\t\thandler: run.handler,\n\t\t\toutput: run.parsed.output,\n\t\t\trun: run.run,\n\t\t}));\n\tconst diagnostics = [\n\t\t...match.diagnostics,\n\t\t...selected.skipped.flatMap((skip) => skip.diagnostics),\n\t\t...declarationSummaries.flatMap((summary) => summary.diagnostics),\n\t];\n\treturn {\n\t\tdecision: aggregateDecision(options.input.event, declarationSummaries),\n\t\tdiagnostics,\n\t\texecutableHandlers: selected.runnable.map((item) => item.handler),\n\t\tmatchedHandlers: ordered.map((item) => item.handler),\n\t\tskipped: selected.skipped,\n\t\tsummaries: declarationSummaries,\n\t};\n}\n\nfunction declarationOrdered(handlers: readonly ExecutableHookHandler[]): readonly OrderedHandler[] {\n\treturn handlers\n\t\t.map((handler, index) => ({ declarationIndex: index, handler }))\n\t\t.toSorted(\n\t\t\t(left, right) =>\n\t\t\t\tcompareHandlers(left.handler, right.handler) || left.declarationIndex - right.declarationIndex,\n\t\t);\n}\n\nfunction compareHandlers(left: ExecutableHookHandler, right: ExecutableHookHandler): number {\n\treturn (\n\t\tleft.source.displayOrder - right.source.displayOrder ||\n\t\tleft.groupIndex - right.groupIndex ||\n\t\tleft.handlerIndex - right.handlerIndex\n\t);\n}\n\nfunction selectExecutableHandlers(\n\thandlers: readonly OrderedHandler[],\n\ttrustState: HookTrustState,\n\ttrustOptions: HookTrustOptions | undefined,\n): { readonly runnable: readonly RunnableHandler[]; readonly skipped: readonly HookDispatchSkipped[] } {\n\tconst records = listHookTrustRecords(\n\t\thandlers.map((item) => item.handler),\n\t\ttrustState,\n\t\ttrustOptions,\n\t);\n\tconst runnable: RunnableHandler[] = [];\n\tconst skipped: HookDispatchSkipped[] = [];\n\tfor (const [index, item] of handlers.entries()) {\n\t\tconst record = records[index];\n\t\tif (record === undefined) continue;\n\t\tconst safetyDiagnostics = validateHookHandlerSafety(item.handler);\n\t\tconst unsafe = safetyDiagnostics.some((diagnostic) => diagnostic.severity === \"error\");\n\t\tif (unsafe) {\n\t\t\tskipped.push({ diagnostics: safetyDiagnostics, handler: item.handler, reason: \"unsafe\", record });\n\t\t\tcontinue;\n\t\t}\n\t\tif (!record.enabled) {\n\t\t\tskipped.push({ diagnostics: [], handler: item.handler, reason: \"disabled\", record });\n\t\t\tcontinue;\n\t\t}\n\t\tif (!record.trusted) {\n\t\t\tskipped.push({ diagnostics: [], handler: item.handler, reason: \"untrusted\", record });\n\t\t\tcontinue;\n\t\t}\n\t\trunnable.push({ ...item, record });\n\t}\n\treturn { runnable, skipped };\n}\n\nfunction aggregateDecision(\n\tevent: HookInputWire[\"event\"],\n\tsummaries: readonly HookDispatchSummary[],\n): HookDispatchDecision {\n\tswitch (event) {\n\t\tcase \"PreToolUse\":\n\t\t\treturn aggregatePreToolUseDecision(summaries);\n\t\tcase \"PostToolUse\":\n\t\tcase \"UserPromptSubmit\":\n\t\tcase \"SessionStart\":\n\t\tcase \"PreCompact\":\n\t\tcase \"PostCompact\":\n\t\tcase \"Stop\":\n\t\t\treturn aggregateBlockingDecision(summaries);\n\t}\n}\n\nfunction aggregatePreToolUseDecision(summaries: readonly HookDispatchSummary[]): HookDispatchDecision {\n\tconst blocker = summaries.find(hasBlockingDecision);\n\tif (blocker !== undefined) {\n\t\treturn decisionWithSource(\"block\", blocker, blocker.output.reason);\n\t}\n\tconst ask = summaries.find((summary) => summary.output.decision === \"ask\");\n\tif (ask !== undefined) {\n\t\tconst reason = ask.output.reason ?? \"Hook requested manual approval.\";\n\t\treturn {\n\t\t\tfallback: { kind: \"block\", reason },\n\t\t\tkind: \"ask\",\n\t\t\tnativeRepresentable: false,\n\t\t\t...reasonField(ask.output.reason),\n\t\t\tsource: ask.handler.source,\n\t\t\tsourceCommand: ask.handler.config.command,\n\t\t};\n\t}\n\tlet allowSummary: HookDispatchSummary | undefined;\n\tfor (const summary of summaries) {\n\t\tif (summary.output.decision === \"allow\" || summary.output.decision === \"approve\") allowSummary = summary;\n\t}\n\tif (allowSummary !== undefined) {\n\t\treturn decisionWithSource(\"allow\", allowSummary, undefined, allowSummary.output.updatedInput);\n\t}\n\treturn { kind: \"none\" };\n}\n\nfunction aggregateBlockingDecision(summaries: readonly HookDispatchSummary[]): HookDispatchDecision {\n\tconst blocker = summaries.find(hasBlockingDecision);\n\tif (blocker !== undefined) {\n\t\treturn decisionWithSource(\"block\", blocker, blocker.output.reason ?? blocker.output.stopReason);\n\t}\n\treturn { kind: \"none\" };\n}\n\nfunction hasBlockingDecision(summary: HookDispatchSummary): boolean {\n\treturn summary.output.decision === \"block\" || summary.output.decision === \"deny\";\n}\n\nfunction decisionWithSource(\n\tkind: \"allow\" | \"block\",\n\tsummary: HookDispatchSummary,\n\treason: string | undefined,\n\tupdatedInput?: unknown,\n): HookDispatchDecision {\n\treturn {\n\t\tkind,\n\t\t...reasonField(reason),\n\t\tsource: summary.handler.source,\n\t\tsourceCommand: summary.handler.config.command,\n\t\t...updatedInputField(updatedInput),\n\t};\n}\n\nfunction reasonField(reason: string | undefined): { readonly reason?: string } {\n\tif (reason === undefined) {\n\t\treturn {};\n\t}\n\treturn { reason };\n}\n\nfunction updatedInputField(updatedInput: unknown): { readonly updatedInput?: unknown } {\n\tif (updatedInput === undefined) {\n\t\treturn {};\n\t}\n\treturn { updatedInput };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/dispatcher.ts"],"names":[],"mappings":"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","sourcesContent":["import { stripAnsi } from \"../../../../utils/ansi.ts\";\nimport { type CommandHookRunOptions, type CommandHookRunResult, runCommandHook } from \"./command-runner.ts\";\nimport { matchingHookHandlers } from \"./matcher.ts\";\nimport { type ParsedHookOutput, parseHookOutput } from \"./output-parser.ts\";\nimport { type HookOutputPolicy, validateHookHandlerSafety } from \"./safety.ts\";\nimport { type HookTrustOptions, type HookTrustRecord, listHookTrustRecords } from \"./trust.ts\";\nimport type {\n\tExecutableHookHandler,\n\tHookDiagnostic,\n\tHookInputWire,\n\tHookSourceMetadata,\n\tHookTrustState,\n} from \"./types.ts\";\n\nexport type HookCommandRunner = (\n\thandler: ExecutableHookHandler,\n\tinput: HookInputWire,\n\toptions: CommandHookRunOptions,\n) => Promise<CommandHookRunResult>;\n\nexport type HookDispatchDecision =\n\t| { readonly kind: \"none\" }\n\t| {\n\t\t\treadonly kind: \"allow\" | \"block\";\n\t\t\treadonly reason?: string;\n\t\t\treadonly source: HookSourceMetadata;\n\t\t\treadonly sourceCommand: string;\n\t\t\treadonly updatedInput?: unknown;\n\t }\n\t| {\n\t\t\treadonly fallback: { readonly kind: \"block\"; readonly reason: string };\n\t\t\treadonly kind: \"ask\";\n\t\t\treadonly nativeRepresentable: false;\n\t\t\treadonly reason?: string;\n\t\t\treadonly source: HookSourceMetadata;\n\t\t\treadonly sourceCommand: string;\n\t };\n\nexport type HookDispatchSkipped = {\n\treadonly diagnostics: readonly HookDiagnostic[];\n\treadonly handler: ExecutableHookHandler;\n\treadonly reason: \"disabled\" | \"untrusted\" | \"unsafe\";\n\treadonly record: HookTrustRecord;\n};\n\nexport type HookDispatchSummary = {\n\treadonly completionIndex: number;\n\treadonly diagnostics: readonly HookDiagnostic[];\n\treadonly handler: ExecutableHookHandler;\n\treadonly output: ParsedHookOutput[\"output\"];\n\treadonly run: CommandHookRunResult;\n};\n\nexport type HookDispatchResult = {\n\treadonly decision: HookDispatchDecision;\n\treadonly diagnostics: readonly HookDiagnostic[];\n\treadonly executableHandlers: readonly ExecutableHookHandler[];\n\treadonly matchedHandlers: readonly ExecutableHookHandler[];\n\treadonly skipped: readonly HookDispatchSkipped[];\n\treadonly summaries: readonly HookDispatchSummary[];\n};\n\nexport type HookDispatchOptions = {\n\treadonly cwd: string;\n\treadonly envPassthrough?: readonly string[];\n\treadonly handlers: readonly ExecutableHookHandler[];\n\treadonly input: HookInputWire;\n\treadonly onRunningHandlersChange?: (running: readonly ExecutableHookHandler[]) => void;\n\treadonly outputPolicy?: HookOutputPolicy;\n\treadonly runCommand?: HookCommandRunner;\n\treadonly signal?: AbortSignal;\n\treadonly sourceEnv?: NodeJS.ProcessEnv;\n\treadonly trustOptions?: HookTrustOptions;\n\treadonly trustState: HookTrustState;\n};\n\ntype OrderedHandler = {\n\treadonly declarationIndex: number;\n\treadonly handler: ExecutableHookHandler;\n};\n\ntype RunnableHandler = OrderedHandler & {\n\treadonly record: HookTrustRecord;\n};\n\nexport async function dispatchHookEvent(options: HookDispatchOptions): Promise<HookDispatchResult> {\n\tconst match = matchingHookHandlers(options.input, options.handlers);\n\tconst ordered = declarationOrdered(match.handlers);\n\tconst selected = selectExecutableHandlers(ordered, options.trustState, options.trustOptions);\n\tlet nextCompletionIndex = 0;\n\tconst runner = options.runCommand ?? runCommandHook;\n\tconst notifyRunningChange = options.onRunningHandlersChange;\n\tconst runningHandlers: ExecutableHookHandler[] = [];\n\tconst completed = await Promise.all(\n\t\tselected.runnable.map(async ({ handler, declarationIndex }) => {\n\t\t\tif (notifyRunningChange !== undefined) {\n\t\t\t\trunningHandlers.push(handler);\n\t\t\t\tnotifyRunningChange([...runningHandlers]);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst run = await runner(handler, options.input, {\n\t\t\t\t\tcwd: options.cwd,\n\t\t\t\t\t...(options.envPassthrough === undefined ? {} : { envPassthrough: options.envPassthrough }),\n\t\t\t\t\t...(options.outputPolicy === undefined ? {} : { outputPolicy: options.outputPolicy }),\n\t\t\t\t\t...(options.signal === undefined ? {} : { signal: options.signal }),\n\t\t\t\t\t...(options.sourceEnv === undefined ? {} : { sourceEnv: options.sourceEnv }),\n\t\t\t\t});\n\t\t\t\tconst parsed = parseHookOutput({\n\t\t\t\t\tevent: options.input.event,\n\t\t\t\t\texitCode: run.exitCode ?? 1,\n\t\t\t\t\tsource: handler.source,\n\t\t\t\t\tstderr: run.stderr,\n\t\t\t\t\tstdout: run.stdout,\n\t\t\t\t});\n\t\t\t\tconst completionIndex = nextCompletionIndex;\n\t\t\t\tnextCompletionIndex += 1;\n\t\t\t\treturn { completionIndex, declarationIndex, handler, parsed, run };\n\t\t\t} finally {\n\t\t\t\tif (notifyRunningChange !== undefined) {\n\t\t\t\t\tconst runningIndex = runningHandlers.indexOf(handler);\n\t\t\t\t\tif (runningIndex !== -1) {\n\t\t\t\t\t\trunningHandlers.splice(runningIndex, 1);\n\t\t\t\t\t}\n\t\t\t\t\tnotifyRunningChange([...runningHandlers]);\n\t\t\t\t}\n\t\t\t}\n\t\t}),\n\t);\n\tconst declarationSummaries = completed\n\t\t.toSorted((left, right) => left.declarationIndex - right.declarationIndex)\n\t\t.map((run) => ({\n\t\t\tcompletionIndex: run.completionIndex,\n\t\t\tdiagnostics: run.parsed.diagnostics,\n\t\t\thandler: run.handler,\n\t\t\toutput: run.parsed.output,\n\t\t\trun: run.run,\n\t\t}));\n\tconst diagnostics = [\n\t\t...match.diagnostics,\n\t\t...selected.skipped.flatMap((skip) => skip.diagnostics),\n\t\t...declarationSummaries.flatMap((summary) => summary.diagnostics),\n\t];\n\treturn {\n\t\tdecision: aggregateDecision(options.input.event, declarationSummaries),\n\t\tdiagnostics,\n\t\texecutableHandlers: selected.runnable.map((item) => item.handler),\n\t\tmatchedHandlers: ordered.map((item) => item.handler),\n\t\tskipped: selected.skipped,\n\t\tsummaries: declarationSummaries,\n\t};\n}\n\nexport function runningHookHandlersStatusLabel(\n\thandlers: readonly ExecutableHookHandler[],\n\tplatform: NodeJS.Platform = process.platform,\n): string {\n\tconst label = handlers.map((handler) => hookHandlerStatusLabel(handler, platform)).join(\" · \");\n\treturn label.length <= 79 ? label : `${label.slice(0, 76)}...`;\n}\n\nfunction hookHandlerStatusLabel(handler: ExecutableHookHandler, platform: NodeJS.Platform): string {\n\tconst raw =\n\t\thandler.config.statusMessage ??\n\t\t(platform === \"win32\" && handler.config.commandWindows !== undefined\n\t\t\t? handler.config.commandWindows\n\t\t\t: handler.config.command);\n\treturn stripAnsi(raw)\n\t\t.replace(/[\\r\\n\\t]+/g, \" \")\n\t\t.replace(/[\\u0000-\\u001f\\u007f]+/g, \"\")\n\t\t.replace(/\\s+/g, \" \")\n\t\t.trim();\n}\n\nfunction declarationOrdered(handlers: readonly ExecutableHookHandler[]): readonly OrderedHandler[] {\n\treturn handlers\n\t\t.map((handler, index) => ({ declarationIndex: index, handler }))\n\t\t.toSorted(\n\t\t\t(left, right) =>\n\t\t\t\tcompareHandlers(left.handler, right.handler) || left.declarationIndex - right.declarationIndex,\n\t\t);\n}\n\nfunction compareHandlers(left: ExecutableHookHandler, right: ExecutableHookHandler): number {\n\treturn (\n\t\tleft.source.displayOrder - right.source.displayOrder ||\n\t\tleft.groupIndex - right.groupIndex ||\n\t\tleft.handlerIndex - right.handlerIndex\n\t);\n}\n\nfunction selectExecutableHandlers(\n\thandlers: readonly OrderedHandler[],\n\ttrustState: HookTrustState,\n\ttrustOptions: HookTrustOptions | undefined,\n): { readonly runnable: readonly RunnableHandler[]; readonly skipped: readonly HookDispatchSkipped[] } {\n\tconst records = listHookTrustRecords(\n\t\thandlers.map((item) => item.handler),\n\t\ttrustState,\n\t\ttrustOptions,\n\t);\n\tconst runnable: RunnableHandler[] = [];\n\tconst skipped: HookDispatchSkipped[] = [];\n\tfor (const [index, item] of handlers.entries()) {\n\t\tconst record = records[index];\n\t\tif (record === undefined) continue;\n\t\tconst safetyDiagnostics = validateHookHandlerSafety(item.handler);\n\t\tconst unsafe = safetyDiagnostics.some((diagnostic) => diagnostic.severity === \"error\");\n\t\tif (unsafe) {\n\t\t\tskipped.push({ diagnostics: safetyDiagnostics, handler: item.handler, reason: \"unsafe\", record });\n\t\t\tcontinue;\n\t\t}\n\t\tif (!record.enabled) {\n\t\t\tskipped.push({ diagnostics: [], handler: item.handler, reason: \"disabled\", record });\n\t\t\tcontinue;\n\t\t}\n\t\tif (!record.trusted) {\n\t\t\tskipped.push({ diagnostics: [], handler: item.handler, reason: \"untrusted\", record });\n\t\t\tcontinue;\n\t\t}\n\t\trunnable.push({ ...item, record });\n\t}\n\treturn { runnable, skipped };\n}\n\nfunction aggregateDecision(\n\tevent: HookInputWire[\"event\"],\n\tsummaries: readonly HookDispatchSummary[],\n): HookDispatchDecision {\n\tswitch (event) {\n\t\tcase \"PreToolUse\":\n\t\t\treturn aggregatePreToolUseDecision(summaries);\n\t\tcase \"PostToolUse\":\n\t\tcase \"UserPromptSubmit\":\n\t\tcase \"SessionStart\":\n\t\tcase \"PreCompact\":\n\t\tcase \"PostCompact\":\n\t\tcase \"Stop\":\n\t\t\treturn aggregateBlockingDecision(summaries);\n\t}\n}\n\nfunction aggregatePreToolUseDecision(summaries: readonly HookDispatchSummary[]): HookDispatchDecision {\n\tconst blocker = summaries.find(hasBlockingDecision);\n\tif (blocker !== undefined) {\n\t\treturn decisionWithSource(\"block\", blocker, blocker.output.reason);\n\t}\n\tconst ask = summaries.find((summary) => summary.output.decision === \"ask\");\n\tif (ask !== undefined) {\n\t\tconst reason = ask.output.reason ?? \"Hook requested manual approval.\";\n\t\treturn {\n\t\t\tfallback: { kind: \"block\", reason },\n\t\t\tkind: \"ask\",\n\t\t\tnativeRepresentable: false,\n\t\t\t...reasonField(ask.output.reason),\n\t\t\tsource: ask.handler.source,\n\t\t\tsourceCommand: ask.handler.config.command,\n\t\t};\n\t}\n\tlet allowSummary: HookDispatchSummary | undefined;\n\tfor (const summary of summaries) {\n\t\tif (summary.output.decision === \"allow\" || summary.output.decision === \"approve\") allowSummary = summary;\n\t}\n\tif (allowSummary !== undefined) {\n\t\treturn decisionWithSource(\"allow\", allowSummary, undefined, allowSummary.output.updatedInput);\n\t}\n\treturn { kind: \"none\" };\n}\n\nfunction aggregateBlockingDecision(summaries: readonly HookDispatchSummary[]): HookDispatchDecision {\n\tconst blocker = summaries.find(hasBlockingDecision);\n\tif (blocker !== undefined) {\n\t\treturn decisionWithSource(\"block\", blocker, blocker.output.reason ?? blocker.output.stopReason);\n\t}\n\treturn { kind: \"none\" };\n}\n\nfunction hasBlockingDecision(summary: HookDispatchSummary): boolean {\n\treturn summary.output.decision === \"block\" || summary.output.decision === \"deny\";\n}\n\nfunction decisionWithSource(\n\tkind: \"allow\" | \"block\",\n\tsummary: HookDispatchSummary,\n\treason: string | undefined,\n\tupdatedInput?: unknown,\n): HookDispatchDecision {\n\treturn {\n\t\tkind,\n\t\t...reasonField(reason),\n\t\tsource: summary.handler.source,\n\t\tsourceCommand: summary.handler.config.command,\n\t\t...updatedInputField(updatedInput),\n\t};\n}\n\nfunction reasonField(reason: string | undefined): { readonly reason?: string } {\n\tif (reason === undefined) {\n\t\treturn {};\n\t}\n\treturn { reason };\n}\n\nfunction updatedInputField(updatedInput: unknown): { readonly updatedInput?: unknown } {\n\tif (updatedInput === undefined) {\n\t\treturn {};\n\t}\n\treturn { updatedInput };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAA+B,YAAY,EAAuC,MAAM,gBAAgB,CAAC;AAqCrH,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EACX,iBAAiB,EACjB,qBAAqB,EACrB,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,yBAAyB,GACzB,MAAM,YAAY,CAAC;AAEpB,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAA+B,YAAY,EAAuC,MAAM,gBAAgB,CAAC;AAqCrH,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EACX,iBAAiB,EACjB,qBAAqB,EACrB,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,yBAAyB,GACzB,MAAM,YAAY,CAAC;AAEpB,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAiN7D;AAmBD,OAAO,EACN,qBAAqB,EACrB,yBAAyB,EACzB,6BAA6B,GAC7B,MAAM,YAAY,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { registerHooksCommand } from "./command.js";
|
|
3
3
|
import { loadHookConfigSources } from "./config-loader.js";
|
|
4
|
-
import { dispatchHookEvent } from "./dispatcher.js";
|
|
4
|
+
import { dispatchHookEvent, runningHookHandlersStatusLabel } from "./dispatcher.js";
|
|
5
5
|
import { buildPostCompactHookInput, buildPreCompactHookInput, buildSessionStartHookInput, dispatchLifecycleHookEvent, postCompactResultDetails, preCompactResultDetails, recordLifecycleHookResult, sessionBeforeCompactResult, sessionStartResultDetails, } from "./lifecycle-adapter.js";
|
|
6
6
|
import { appendSystemMessages, buildUserPromptHookInput, formatPromptContextMessage, HOOK_CUSTOM_MESSAGE_TYPE, promptBlockReasonFromResult, promptContextFromResult, safeDiagnosticDetails, } from "./prompt-adapter.js";
|
|
7
7
|
import { applyStopHookResult, buildStopHookInput, createStopTurnTracker } from "./stop-adapter.js";
|
|
@@ -125,6 +125,11 @@ export default function hooksExtension(pi) {
|
|
|
125
125
|
cwd: ctx.cwd,
|
|
126
126
|
handlers: state.parsed.executableHandlers,
|
|
127
127
|
input: buildPreToolUseHookInput(event, ctx),
|
|
128
|
+
onRunningHandlersChange: (running) => {
|
|
129
|
+
if (running.length === 0)
|
|
130
|
+
return;
|
|
131
|
+
ctx.updateToolHookStatus?.(runningHookHandlersStatusLabel(running));
|
|
132
|
+
},
|
|
128
133
|
signal: ctx.signal,
|
|
129
134
|
trustOptions: { platform: process.platform },
|
|
130
135
|
trustState: state.trust,
|
|
@@ -148,6 +153,11 @@ export default function hooksExtension(pi) {
|
|
|
148
153
|
cwd: ctx.cwd,
|
|
149
154
|
handlers: state.parsed.executableHandlers,
|
|
150
155
|
input: buildPostToolUseHookInput(event, ctx),
|
|
156
|
+
onRunningHandlersChange: (running) => {
|
|
157
|
+
if (running.length === 0)
|
|
158
|
+
return;
|
|
159
|
+
ctx.updateToolHookStatus?.(runningHookHandlersStatusLabel(running));
|
|
160
|
+
},
|
|
151
161
|
signal: ctx.signal,
|
|
152
162
|
trustOptions: { platform: process.platform },
|
|
153
163
|
trustState: state.trust,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport type { BeforeAgentStartEventResult, ExtensionAPI, ExtensionContext, LoadedHookSources } from \"../../types.ts\";\nimport { registerHooksCommand } from \"./command.ts\";\nimport { loadHookConfigSources } from \"./config-loader.ts\";\nimport { dispatchHookEvent } from \"./dispatcher.ts\";\nimport {\n\tbuildPostCompactHookInput,\n\tbuildPreCompactHookInput,\n\tbuildSessionStartHookInput,\n\tdispatchLifecycleHookEvent,\n\tpostCompactResultDetails,\n\tpreCompactResultDetails,\n\trecordLifecycleHookResult,\n\tsessionBeforeCompactResult,\n\tsessionStartResultDetails,\n} from \"./lifecycle-adapter.ts\";\nimport {\n\tappendSystemMessages,\n\tbuildUserPromptHookInput,\n\tformatPromptContextMessage,\n\tHOOK_CUSTOM_MESSAGE_TYPE,\n\ttype PendingPromptHookContext,\n\tpromptBlockReasonFromResult,\n\tpromptContextFromResult,\n\tsafeDiagnosticDetails,\n} from \"./prompt-adapter.ts\";\nimport { applyStopHookResult, buildStopHookInput, createStopTurnTracker } from \"./stop-adapter.ts\";\nimport {\n\tapplyPostToolUseResult,\n\tapplyPreToolUseResult,\n\tbuildPostToolUseHookInput,\n\tbuildPreToolUseHookInput,\n\ttoolContextsFromResult,\n} from \"./tool-adapter.ts\";\nimport { emptyHookTrustState } from \"./trust.ts\";\nimport { FileHookStateStorage } from \"./trust-storage.ts\";\nimport type { HookTrustState } from \"./types.ts\";\n\nexport { parseHookConfig } from \"./schema.ts\";\nexport type {\n\tCommandHookConfig,\n\tExecutableHookHandler,\n\tHookDiagnostic,\n\tHookDiagnosticCode,\n\tHookInputWire,\n\tHookOutputWire,\n\tHookRuntimeState,\n\tHookSourceMetadata,\n\tHookTrustEntry,\n\tHookTrustState,\n\tParsedHookConfig,\n\tSupportedHookEvent,\n\tUnsupportedKnownHookEvent,\n} from \"./types.ts\";\n\nexport default function hooksExtension(pi: ExtensionAPI): void {\n\tconst pendingPromptContexts: PendingPromptHookContext[] = [];\n\tconst pendingPreToolContexts = new Map<string, readonly string[]>();\n\tconst stopTurnTracker = createStopTurnTracker();\n\n\tconst refreshState = (ctx: ExtensionContext) => {\n\t\tconst sources = ctx.getLoadedHookSources?.() ?? fallbackHookSources(ctx.cwd);\n\t\tconst parsed = loadHookConfigSources({\n\t\t\tagentDir: sources.agentDir,\n\t\t\tcwd: sources.cwd,\n\t\t\tfileSystem: {\n\t\t\t\treadTextFile(path) {\n\t\t\t\t\treturn existsSync(path) ? readFileSync(path, \"utf-8\") : undefined;\n\t\t\t\t},\n\t\t\t},\n\t\t\tglobalHookSourcePaths: sources.globalHookSourcePaths,\n\t\t\tglobalHooksPath: sources.globalHooksPath,\n\t\t\tglobalSettingsHooks: sources.globalSettingsHooks,\n\t\t\tpreSessionHookSourcePaths: sources.preSessionHookSourcePaths,\n\t\t\tprojectHookSourcePaths: sources.projectHookSourcePaths,\n\t\t\tprojectHooksPath: sources.projectHooksPath,\n\t\t\tprojectSettingsHooks: sources.projectSettingsHooks,\n\t\t\truntimeHookSourcePaths: sources.runtimeHookSourcePaths,\n\t\t});\n\t\tconst storage = new FileHookStateStorage({ agentDir: sources.agentDir, cwd: sources.cwd });\n\t\tconst trust = mergeTrustStates(\n\t\t\tstorage.read(\"global\"),\n\t\t\tctx.isProjectTrusted() ? storage.read(\"project\") : emptyHookTrustState(),\n\t\t);\n\t\treturn { parsed, trust, storage };\n\t};\n\n\tpi.on(\"session_start\", async (event, ctx) => {\n\t\tconst state = refreshState(ctx);\n\t\tconst input = buildSessionStartHookInput(event, ctx);\n\t\tconst result = await dispatchLifecycleHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput,\n\t\t\tmatcherInputs: [\"SessionStart\", event.reason],\n\t\t\t...(ctx.signal === undefined ? {} : { signal: ctx.signal }),\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\trecordLifecycleHookResult(pi, \"SessionStart\", sessionStartResultDetails(result));\n\t});\n\n\tpi.on(\"input\", async (event, ctx) => {\n\t\tif (event.source === \"extension\") return undefined;\n\t\tstopTurnTracker.reset();\n\t\tpendingPromptContexts.splice(0);\n\t\tconst state = refreshState(ctx);\n\t\tconst input = buildUserPromptHookInput({\n\t\t\tcwd: ctx.cwd,\n\t\t\tpermissionMode: \"default\",\n\t\t\tprompt: event.text,\n\t\t\tsessionId: ctx.sessionManager.getSessionId(),\n\t\t\ttranscriptPath: ctx.sessionManager.getSessionFile(),\n\t\t});\n\t\tconst result = await dispatchHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput,\n\t\t\tsignal: ctx.signal,\n\t\t\ttrustOptions: { platform: process.platform },\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\tif (result.decision.kind === \"block\") {\n\t\t\tconst reason = promptBlockReasonFromResult(result);\n\t\t\tctx.ui.notify(reason, \"warning\");\n\t\t\tpi.sendMessage(\n\t\t\t\t{\n\t\t\t\t\tcustomType: HOOK_CUSTOM_MESSAGE_TYPE,\n\t\t\t\t\tcontent: reason,\n\t\t\t\t\tdisplay: false,\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\tdecision: \"block\",\n\t\t\t\t\t\tevent: \"UserPromptSubmit\",\n\t\t\t\t\t\tsourcePath: result.decision.source.sourcePath,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{ triggerTurn: false },\n\t\t\t);\n\t\t\treturn { action: \"handled\" };\n\t\t}\n\t\tif (ctx.isIdle()) {\n\t\t\tconst pending = promptContextFromResult(result);\n\t\t\tif (pending !== undefined) {\n\t\t\t\tpendingPromptContexts.push(pending);\n\t\t\t}\n\t\t}\n\t\treturn { action: \"continue\" };\n\t});\n\n\tpi.on(\"before_agent_start\", async (event) => {\n\t\tconst pending = pendingPromptContexts.shift();\n\t\tif (pending === undefined) return undefined;\n\n\t\tconst messageContent = formatPromptContextMessage(pending);\n\t\tconst systemPrompt = appendSystemMessages(event.systemPrompt, pending.systemMessages);\n\t\tif (messageContent === undefined && systemPrompt === event.systemPrompt) return undefined;\n\n\t\tconst result: BeforeAgentStartEventResult = {};\n\t\tif (messageContent !== undefined) {\n\t\t\tresult.message = {\n\t\t\t\tcustomType: HOOK_CUSTOM_MESSAGE_TYPE,\n\t\t\t\tcontent: messageContent,\n\t\t\t\tdisplay: false,\n\t\t\t\tdetails: {\n\t\t\t\t\tevent: \"UserPromptSubmit\",\n\t\t\t\t\tdiagnostics: pending.diagnostics.map(safeDiagnosticDetails),\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tif (systemPrompt !== event.systemPrompt) {\n\t\t\tresult.systemPrompt = systemPrompt;\n\t\t}\n\t\treturn result;\n\t});\n\n\tpi.on(\"tool_call\", async (event, ctx) => {\n\t\tpendingPreToolContexts.delete(event.toolCallId);\n\t\tconst state = refreshState(ctx);\n\t\tconst result = await dispatchHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput: buildPreToolUseHookInput(event, ctx),\n\t\t\tsignal: ctx.signal,\n\t\t\ttrustOptions: { platform: process.platform },\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\tconst toolResult = applyPreToolUseResult(event, result);\n\t\tif (toolResult?.block) {\n\t\t\tpendingPreToolContexts.delete(event.toolCallId);\n\t\t\treturn toolResult;\n\t\t}\n\t\tconst contexts = toolContextsFromResult(result);\n\t\tif (contexts.length > 0) {\n\t\t\tpendingPreToolContexts.set(event.toolCallId, contexts);\n\t\t}\n\t\treturn toolResult;\n\t});\n\n\tpi.on(\"tool_result\", async (event, ctx) => {\n\t\tconst preToolContexts = pendingPreToolContexts.get(event.toolCallId) ?? [];\n\t\tpendingPreToolContexts.delete(event.toolCallId);\n\t\tconst state = refreshState(ctx);\n\t\tconst result = await dispatchHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput: buildPostToolUseHookInput(event, ctx),\n\t\t\tsignal: ctx.signal,\n\t\t\ttrustOptions: { platform: process.platform },\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\treturn applyPostToolUseResult(event, result, preToolContexts);\n\t});\n\n\tpi.on(\"session_before_compact\", async (event, ctx) => {\n\t\tconst state = refreshState(ctx);\n\t\tconst result = await dispatchLifecycleHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput: buildPreCompactHookInput(event, ctx),\n\t\t\tmatcherInputs: [\"PreCompact\", event.reason],\n\t\t\tsignal: event.signal,\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\tconst details = preCompactResultDetails(result);\n\t\trecordLifecycleHookResult(pi, \"PreCompact\", details);\n\t\treturn sessionBeforeCompactResult(details);\n\t});\n\n\tpi.on(\"session_compact\", async (event, ctx) => {\n\t\tif (!event.accepted) return undefined;\n\t\tconst state = refreshState(ctx);\n\t\tconst result = await dispatchLifecycleHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput: buildPostCompactHookInput(event, ctx),\n\t\t\tmatcherInputs: [\"PostCompact\", event.reason],\n\t\t\t...(ctx.signal === undefined ? {} : { signal: ctx.signal }),\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\trecordLifecycleHookResult(pi, \"PostCompact\", postCompactResultDetails(result));\n\t\treturn undefined;\n\t});\n\n\tpi.on(\"agent_end\", async (event, ctx) => {\n\t\tconst state = refreshState(ctx);\n\t\tconst result = await dispatchHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput: buildStopHookInput(event, ctx),\n\t\t\tsignal: ctx.signal,\n\t\t\ttrustOptions: { platform: process.platform },\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\tawait applyStopHookResult(pi, ctx, result, stopTurnTracker.turnKey(ctx));\n\t});\n\n\tregisterHooksCommand(pi, refreshState);\n}\n\nfunction mergeTrustStates(globalState: HookTrustState, projectState: HookTrustState): HookTrustState {\n\treturn { version: 1, hooks: { ...globalState.hooks, ...projectState.hooks } };\n}\n\nfunction fallbackHookSources(cwd: string): LoadedHookSources {\n\treturn {\n\t\tagentDir: cwd,\n\t\tcwd,\n\t\tglobalHookSourcePaths: [],\n\t\tglobalHooksPath: `${cwd}/hooks.json`,\n\t\tpreSessionHookSourcePaths: [],\n\t\tprojectHookSourcePaths: [],\n\t\tprojectHooksPath: `${cwd}/.senpi/hooks.json`,\n\t\truntimeHookSourcePaths: [],\n\t};\n}\n\nexport {\n\tSUPPORTED_HOOK_EVENTS,\n\tUNSUPPORTED_HANDLER_TYPES,\n\tUNSUPPORTED_KNOWN_HOOK_EVENTS,\n} from \"./types.ts\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport type { BeforeAgentStartEventResult, ExtensionAPI, ExtensionContext, LoadedHookSources } from \"../../types.ts\";\nimport { registerHooksCommand } from \"./command.ts\";\nimport { loadHookConfigSources } from \"./config-loader.ts\";\nimport { dispatchHookEvent, runningHookHandlersStatusLabel } from \"./dispatcher.ts\";\nimport {\n\tbuildPostCompactHookInput,\n\tbuildPreCompactHookInput,\n\tbuildSessionStartHookInput,\n\tdispatchLifecycleHookEvent,\n\tpostCompactResultDetails,\n\tpreCompactResultDetails,\n\trecordLifecycleHookResult,\n\tsessionBeforeCompactResult,\n\tsessionStartResultDetails,\n} from \"./lifecycle-adapter.ts\";\nimport {\n\tappendSystemMessages,\n\tbuildUserPromptHookInput,\n\tformatPromptContextMessage,\n\tHOOK_CUSTOM_MESSAGE_TYPE,\n\ttype PendingPromptHookContext,\n\tpromptBlockReasonFromResult,\n\tpromptContextFromResult,\n\tsafeDiagnosticDetails,\n} from \"./prompt-adapter.ts\";\nimport { applyStopHookResult, buildStopHookInput, createStopTurnTracker } from \"./stop-adapter.ts\";\nimport {\n\tapplyPostToolUseResult,\n\tapplyPreToolUseResult,\n\tbuildPostToolUseHookInput,\n\tbuildPreToolUseHookInput,\n\ttoolContextsFromResult,\n} from \"./tool-adapter.ts\";\nimport { emptyHookTrustState } from \"./trust.ts\";\nimport { FileHookStateStorage } from \"./trust-storage.ts\";\nimport type { HookTrustState } from \"./types.ts\";\n\nexport { parseHookConfig } from \"./schema.ts\";\nexport type {\n\tCommandHookConfig,\n\tExecutableHookHandler,\n\tHookDiagnostic,\n\tHookDiagnosticCode,\n\tHookInputWire,\n\tHookOutputWire,\n\tHookRuntimeState,\n\tHookSourceMetadata,\n\tHookTrustEntry,\n\tHookTrustState,\n\tParsedHookConfig,\n\tSupportedHookEvent,\n\tUnsupportedKnownHookEvent,\n} from \"./types.ts\";\n\nexport default function hooksExtension(pi: ExtensionAPI): void {\n\tconst pendingPromptContexts: PendingPromptHookContext[] = [];\n\tconst pendingPreToolContexts = new Map<string, readonly string[]>();\n\tconst stopTurnTracker = createStopTurnTracker();\n\n\tconst refreshState = (ctx: ExtensionContext) => {\n\t\tconst sources = ctx.getLoadedHookSources?.() ?? fallbackHookSources(ctx.cwd);\n\t\tconst parsed = loadHookConfigSources({\n\t\t\tagentDir: sources.agentDir,\n\t\t\tcwd: sources.cwd,\n\t\t\tfileSystem: {\n\t\t\t\treadTextFile(path) {\n\t\t\t\t\treturn existsSync(path) ? readFileSync(path, \"utf-8\") : undefined;\n\t\t\t\t},\n\t\t\t},\n\t\t\tglobalHookSourcePaths: sources.globalHookSourcePaths,\n\t\t\tglobalHooksPath: sources.globalHooksPath,\n\t\t\tglobalSettingsHooks: sources.globalSettingsHooks,\n\t\t\tpreSessionHookSourcePaths: sources.preSessionHookSourcePaths,\n\t\t\tprojectHookSourcePaths: sources.projectHookSourcePaths,\n\t\t\tprojectHooksPath: sources.projectHooksPath,\n\t\t\tprojectSettingsHooks: sources.projectSettingsHooks,\n\t\t\truntimeHookSourcePaths: sources.runtimeHookSourcePaths,\n\t\t});\n\t\tconst storage = new FileHookStateStorage({ agentDir: sources.agentDir, cwd: sources.cwd });\n\t\tconst trust = mergeTrustStates(\n\t\t\tstorage.read(\"global\"),\n\t\t\tctx.isProjectTrusted() ? storage.read(\"project\") : emptyHookTrustState(),\n\t\t);\n\t\treturn { parsed, trust, storage };\n\t};\n\n\tpi.on(\"session_start\", async (event, ctx) => {\n\t\tconst state = refreshState(ctx);\n\t\tconst input = buildSessionStartHookInput(event, ctx);\n\t\tconst result = await dispatchLifecycleHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput,\n\t\t\tmatcherInputs: [\"SessionStart\", event.reason],\n\t\t\t...(ctx.signal === undefined ? {} : { signal: ctx.signal }),\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\trecordLifecycleHookResult(pi, \"SessionStart\", sessionStartResultDetails(result));\n\t});\n\n\tpi.on(\"input\", async (event, ctx) => {\n\t\tif (event.source === \"extension\") return undefined;\n\t\tstopTurnTracker.reset();\n\t\tpendingPromptContexts.splice(0);\n\t\tconst state = refreshState(ctx);\n\t\tconst input = buildUserPromptHookInput({\n\t\t\tcwd: ctx.cwd,\n\t\t\tpermissionMode: \"default\",\n\t\t\tprompt: event.text,\n\t\t\tsessionId: ctx.sessionManager.getSessionId(),\n\t\t\ttranscriptPath: ctx.sessionManager.getSessionFile(),\n\t\t});\n\t\tconst result = await dispatchHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput,\n\t\t\tsignal: ctx.signal,\n\t\t\ttrustOptions: { platform: process.platform },\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\tif (result.decision.kind === \"block\") {\n\t\t\tconst reason = promptBlockReasonFromResult(result);\n\t\t\tctx.ui.notify(reason, \"warning\");\n\t\t\tpi.sendMessage(\n\t\t\t\t{\n\t\t\t\t\tcustomType: HOOK_CUSTOM_MESSAGE_TYPE,\n\t\t\t\t\tcontent: reason,\n\t\t\t\t\tdisplay: false,\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\tdecision: \"block\",\n\t\t\t\t\t\tevent: \"UserPromptSubmit\",\n\t\t\t\t\t\tsourcePath: result.decision.source.sourcePath,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{ triggerTurn: false },\n\t\t\t);\n\t\t\treturn { action: \"handled\" };\n\t\t}\n\t\tif (ctx.isIdle()) {\n\t\t\tconst pending = promptContextFromResult(result);\n\t\t\tif (pending !== undefined) {\n\t\t\t\tpendingPromptContexts.push(pending);\n\t\t\t}\n\t\t}\n\t\treturn { action: \"continue\" };\n\t});\n\n\tpi.on(\"before_agent_start\", async (event) => {\n\t\tconst pending = pendingPromptContexts.shift();\n\t\tif (pending === undefined) return undefined;\n\n\t\tconst messageContent = formatPromptContextMessage(pending);\n\t\tconst systemPrompt = appendSystemMessages(event.systemPrompt, pending.systemMessages);\n\t\tif (messageContent === undefined && systemPrompt === event.systemPrompt) return undefined;\n\n\t\tconst result: BeforeAgentStartEventResult = {};\n\t\tif (messageContent !== undefined) {\n\t\t\tresult.message = {\n\t\t\t\tcustomType: HOOK_CUSTOM_MESSAGE_TYPE,\n\t\t\t\tcontent: messageContent,\n\t\t\t\tdisplay: false,\n\t\t\t\tdetails: {\n\t\t\t\t\tevent: \"UserPromptSubmit\",\n\t\t\t\t\tdiagnostics: pending.diagnostics.map(safeDiagnosticDetails),\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tif (systemPrompt !== event.systemPrompt) {\n\t\t\tresult.systemPrompt = systemPrompt;\n\t\t}\n\t\treturn result;\n\t});\n\n\tpi.on(\"tool_call\", async (event, ctx) => {\n\t\tpendingPreToolContexts.delete(event.toolCallId);\n\t\tconst state = refreshState(ctx);\n\t\tconst result = await dispatchHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput: buildPreToolUseHookInput(event, ctx),\n\t\t\tonRunningHandlersChange: (running) => {\n\t\t\t\tif (running.length === 0) return;\n\t\t\t\tctx.updateToolHookStatus?.(runningHookHandlersStatusLabel(running));\n\t\t\t},\n\t\t\tsignal: ctx.signal,\n\t\t\ttrustOptions: { platform: process.platform },\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\tconst toolResult = applyPreToolUseResult(event, result);\n\t\tif (toolResult?.block) {\n\t\t\tpendingPreToolContexts.delete(event.toolCallId);\n\t\t\treturn toolResult;\n\t\t}\n\t\tconst contexts = toolContextsFromResult(result);\n\t\tif (contexts.length > 0) {\n\t\t\tpendingPreToolContexts.set(event.toolCallId, contexts);\n\t\t}\n\t\treturn toolResult;\n\t});\n\n\tpi.on(\"tool_result\", async (event, ctx) => {\n\t\tconst preToolContexts = pendingPreToolContexts.get(event.toolCallId) ?? [];\n\t\tpendingPreToolContexts.delete(event.toolCallId);\n\t\tconst state = refreshState(ctx);\n\t\tconst result = await dispatchHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput: buildPostToolUseHookInput(event, ctx),\n\t\t\tonRunningHandlersChange: (running) => {\n\t\t\t\tif (running.length === 0) return;\n\t\t\t\tctx.updateToolHookStatus?.(runningHookHandlersStatusLabel(running));\n\t\t\t},\n\t\t\tsignal: ctx.signal,\n\t\t\ttrustOptions: { platform: process.platform },\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\treturn applyPostToolUseResult(event, result, preToolContexts);\n\t});\n\n\tpi.on(\"session_before_compact\", async (event, ctx) => {\n\t\tconst state = refreshState(ctx);\n\t\tconst result = await dispatchLifecycleHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput: buildPreCompactHookInput(event, ctx),\n\t\t\tmatcherInputs: [\"PreCompact\", event.reason],\n\t\t\tsignal: event.signal,\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\tconst details = preCompactResultDetails(result);\n\t\trecordLifecycleHookResult(pi, \"PreCompact\", details);\n\t\treturn sessionBeforeCompactResult(details);\n\t});\n\n\tpi.on(\"session_compact\", async (event, ctx) => {\n\t\tif (!event.accepted) return undefined;\n\t\tconst state = refreshState(ctx);\n\t\tconst result = await dispatchLifecycleHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput: buildPostCompactHookInput(event, ctx),\n\t\t\tmatcherInputs: [\"PostCompact\", event.reason],\n\t\t\t...(ctx.signal === undefined ? {} : { signal: ctx.signal }),\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\trecordLifecycleHookResult(pi, \"PostCompact\", postCompactResultDetails(result));\n\t\treturn undefined;\n\t});\n\n\tpi.on(\"agent_end\", async (event, ctx) => {\n\t\tconst state = refreshState(ctx);\n\t\tconst result = await dispatchHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput: buildStopHookInput(event, ctx),\n\t\t\tsignal: ctx.signal,\n\t\t\ttrustOptions: { platform: process.platform },\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\tawait applyStopHookResult(pi, ctx, result, stopTurnTracker.turnKey(ctx));\n\t});\n\n\tregisterHooksCommand(pi, refreshState);\n}\n\nfunction mergeTrustStates(globalState: HookTrustState, projectState: HookTrustState): HookTrustState {\n\treturn { version: 1, hooks: { ...globalState.hooks, ...projectState.hooks } };\n}\n\nfunction fallbackHookSources(cwd: string): LoadedHookSources {\n\treturn {\n\t\tagentDir: cwd,\n\t\tcwd,\n\t\tglobalHookSourcePaths: [],\n\t\tglobalHooksPath: `${cwd}/hooks.json`,\n\t\tpreSessionHookSourcePaths: [],\n\t\tprojectHookSourcePaths: [],\n\t\tprojectHooksPath: `${cwd}/.senpi/hooks.json`,\n\t\truntimeHookSourcePaths: [],\n\t};\n}\n\nexport {\n\tSUPPORTED_HOOK_EVENTS,\n\tUNSUPPORTED_HANDLER_TYPES,\n\tUNSUPPORTED_KNOWN_HOOK_EVENTS,\n} from \"./types.ts\";\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output-bounds.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/output-bounds.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"output-bounds.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/output-bounds.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,0BAA0B,QAAY,CAAC;AACpD,eAAO,MAAM,0BAA0B,QAAY,CAAC;AAEpD,MAAM,MAAM,gBAAgB,GAAG;IAC9B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACtC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACtC,QAAQ,CAAC,MAAM,EAAE,wBAAwB,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,wBAAwB,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,wBAAwB,CAAC;CAC1C,CAAC;AAEF,wBAAgB,qBAAqB,CACpC,MAAM,EAAE,QAAQ,GAAG,QAAQ,EAC3B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,gBAAgB,GAAG,SAAS,EACpC,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GACvE,cAAc,CAqBhB;AAMD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,SAAe,GAAG,MAAM,CAEtF"}
|
|
@@ -2,6 +2,7 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
|
+
import { redactSensitiveOutput, redactSensitiveTokenValues } from "../../../sensitive-output.js";
|
|
5
6
|
export const DEFAULT_STDOUT_LIMIT_BYTES = 64 * 1024;
|
|
6
7
|
export const DEFAULT_STDERR_LIMIT_BYTES = 64 * 1024;
|
|
7
8
|
export function applyHookOutputSafety(stream, text, policy, capture) {
|
|
@@ -27,15 +28,10 @@ export function applyHookOutputSafety(stream, text, policy, capture) {
|
|
|
27
28
|
};
|
|
28
29
|
}
|
|
29
30
|
function redactHookOutput(text) {
|
|
30
|
-
return
|
|
31
|
-
.replace(/\b([A-Z][A-Z0-9_]*(?:API_KEY|SECRET|TOKEN|PASSWORD|AUTH)[A-Z0-9_]*)=([^\s'"]+)/g, "$1=[REDACTED]")
|
|
32
|
-
.replace(/\b(Authorization:\s*Bearer\s+)([^\s'"]+)/gi, "$1[REDACTED]")
|
|
33
|
-
.replace(/\b(Bearer\s+)(sk-[A-Za-z0-9._-]+)/g, "$1[REDACTED]"));
|
|
31
|
+
return redactSensitiveOutput(text);
|
|
34
32
|
}
|
|
35
33
|
export function redactHookTokenValues(text, replacement = "[REDACTED]") {
|
|
36
|
-
return text
|
|
37
|
-
.replace(/\bghp_[A-Za-z0-9]{20,}\b/g, replacement)
|
|
38
|
-
.replace(/\bgithub_pat_[A-Za-z0-9_]{20,}\b/g, replacement);
|
|
34
|
+
return redactSensitiveTokenValues(text, replacement);
|
|
39
35
|
}
|
|
40
36
|
function spillRedactedOutput(stream, text, policy) {
|
|
41
37
|
const spillDir = policy?.spillDir ?? join(tmpdir(), "senpi-hook-output");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output-bounds.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/output-bounds.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"output-bounds.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/output-bounds.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAEjG,MAAM,CAAC,MAAM,0BAA0B,GAAG,EAAE,GAAG,IAAI,CAAC;AACpD,MAAM,CAAC,MAAM,0BAA0B,GAAG,EAAE,GAAG,IAAI,CAAC;AA2BpD,MAAM,UAAU,qBAAqB,CACpC,MAA2B,EAC3B,IAAY,EACZ,MAAoC,EACpC,OAAyE;IAEzE,MAAM,aAAa,GAAG,OAAO,EAAE,aAAa,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACxE,MAAM,YAAY,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAG,YAAY,KAAK,IAAI,CAAC;IACvC,MAAM,KAAK,GAAG,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC;IACpF,MAAM,QAAQ,GAAG,KAAK,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC;IAC1G,MAAM,aAAa,GAAG,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;IACtD,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,KAAK,IAAI,IAAI,aAAa,GAAG,QAAQ,CAAC;IAC1E,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,mBAAmB,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5F,MAAM,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;IACjH,OAAO;QACN,MAAM,EAAE;YACP,aAAa;YACb,QAAQ;YACR,aAAa,EAAE,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC;YAC9C,OAAO,EAAE,SAAS,KAAK,SAAS;YAChC,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC;YACjD,SAAS;SACT;QACD,IAAI,EAAE,YAAY;KAClB,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAY;IACrC,OAAO,qBAAqB,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,IAAY,EAAE,WAAW,GAAG,YAAY;IAC7E,OAAO,0BAA0B,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;AACtD,CAAC;AAED,SAAS,mBAAmB,CAAC,MAA2B,EAAE,IAAY,EAAE,MAAoC;IAC3G,MAAM,QAAQ,GAAG,MAAM,EAAE,QAAQ,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,mBAAmB,CAAC,CAAC;IACzE,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,QAAQ,MAAM,IAAI,OAAO,CAAC,GAAG,IAAI,UAAU,EAAE,MAAM,CAAC,CAAC;IACjF,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC1B,OAAO,IAAI,CAAC;AACb,CAAC","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { mkdirSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { redactSensitiveOutput, redactSensitiveTokenValues } from \"../../../sensitive-output.ts\";\n\nexport const DEFAULT_STDOUT_LIMIT_BYTES = 64 * 1024;\nexport const DEFAULT_STDERR_LIMIT_BYTES = 64 * 1024;\n\nexport type HookOutputPolicy = {\n\treadonly maxStdoutBytes?: number;\n\treadonly maxStderrBytes?: number;\n\treadonly spillDir?: string;\n};\n\nexport type HookStreamSafetyMetadata = {\n\treadonly originalBytes: number;\n\treadonly returnedBytes: number;\n\treadonly redacted: boolean;\n\treadonly spilled: boolean;\n\treadonly truncated: boolean;\n\treadonly spillPath?: string;\n};\n\nexport type HookOutputSafetyMetadata = {\n\treadonly stdout: HookStreamSafetyMetadata;\n\treadonly stderr: HookStreamSafetyMetadata;\n};\n\nexport type HookSafeOutput = {\n\treadonly text: string;\n\treadonly safety: HookStreamSafetyMetadata;\n};\n\nexport function applyHookOutputSafety(\n\tstream: \"stderr\" | \"stdout\",\n\ttext: string,\n\tpolicy: HookOutputPolicy | undefined,\n\tcapture?: { readonly originalBytes: number; readonly truncated: boolean },\n): HookSafeOutput {\n\tconst originalBytes = capture?.originalBytes ?? Buffer.byteLength(text);\n\tconst redactedText = redactHookOutput(text);\n\tconst redacted = redactedText !== text;\n\tconst limit = stream === \"stdout\" ? policy?.maxStdoutBytes : policy?.maxStderrBytes;\n\tconst maxBytes = limit ?? (stream === \"stdout\" ? DEFAULT_STDOUT_LIMIT_BYTES : DEFAULT_STDERR_LIMIT_BYTES);\n\tconst redactedBytes = Buffer.byteLength(redactedText);\n\tconst truncated = capture?.truncated === true || redactedBytes > maxBytes;\n\tconst spillPath = truncated ? spillRedactedOutput(stream, redactedText, policy) : undefined;\n\tconst returnedText = truncated ? Buffer.from(redactedText).subarray(0, maxBytes).toString(\"utf8\") : redactedText;\n\treturn {\n\t\tsafety: {\n\t\t\toriginalBytes,\n\t\t\tredacted,\n\t\t\treturnedBytes: Buffer.byteLength(returnedText),\n\t\t\tspilled: spillPath !== undefined,\n\t\t\t...(spillPath === undefined ? {} : { spillPath }),\n\t\t\ttruncated,\n\t\t},\n\t\ttext: returnedText,\n\t};\n}\n\nfunction redactHookOutput(text: string): string {\n\treturn redactSensitiveOutput(text);\n}\n\nexport function redactHookTokenValues(text: string, replacement = \"[REDACTED]\"): string {\n\treturn redactSensitiveTokenValues(text, replacement);\n}\n\nfunction spillRedactedOutput(stream: \"stderr\" | \"stdout\", text: string, policy: HookOutputPolicy | undefined): string {\n\tconst spillDir = policy?.spillDir ?? join(tmpdir(), \"senpi-hook-output\");\n\tmkdirSync(spillDir, { recursive: true });\n\tconst path = join(spillDir, `hook-${stream}-${process.pid}-${randomUUID()}.txt`);\n\twriteFileSync(path, text);\n\treturn path;\n}\n"]}
|