@code-yeongyu/senpi 2026.9.12-3 → 2026.9.13-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 +63 -0
- package/README.md +3 -1
- package/dist/bun/cli.js +2 -3
- package/dist/bun/cli.js.map +1 -1
- package/dist/bun/runtime-modules.d.ts +3 -0
- package/dist/bun/runtime-modules.d.ts.map +1 -0
- package/dist/bun/runtime-modules.js +17 -0
- package/dist/bun/runtime-modules.js.map +1 -0
- package/dist/bun/runtime-setup.js +2 -5
- package/dist/bun/runtime-setup.js.map +1 -1
- package/dist/core/agent-session.d.ts +2 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +38 -30
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/discovered-resource-scope.d.ts +23 -0
- package/dist/core/discovered-resource-scope.d.ts.map +1 -0
- package/dist/core/discovered-resource-scope.js +44 -0
- package/dist/core/discovered-resource-scope.js.map +1 -0
- package/dist/core/extensions/builtin/ask-user/notify.d.ts +24 -0
- package/dist/core/extensions/builtin/ask-user/notify.d.ts.map +1 -0
- package/dist/core/extensions/builtin/ask-user/notify.js +11 -0
- package/dist/core/extensions/builtin/ask-user/notify.js.map +1 -0
- package/dist/core/extensions/builtin/ask-user/registry.d.ts +2 -0
- package/dist/core/extensions/builtin/ask-user/registry.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ask-user/registry.js.map +1 -1
- package/dist/core/extensions/builtin/ask-user/resume.d.ts +1 -1
- package/dist/core/extensions/builtin/ask-user/resume.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ask-user/resume.js +10 -20
- package/dist/core/extensions/builtin/ask-user/resume.js.map +1 -1
- package/dist/core/extensions/builtin/ask-user/tool.d.ts +5 -2
- package/dist/core/extensions/builtin/ask-user/tool.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ask-user/tool.js +41 -6
- package/dist/core/extensions/builtin/ask-user/tool.js.map +1 -1
- package/dist/core/extensions/builtin/goal/channel-state-subscriptions.d.ts +2 -1
- package/dist/core/extensions/builtin/goal/channel-state-subscriptions.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/channel-state-subscriptions.js +1 -1
- package/dist/core/extensions/builtin/goal/channel-state-subscriptions.js.map +1 -1
- package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/monitor-continuation.js +27 -13
- package/dist/core/extensions/builtin/goal/monitor-continuation.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/config-loader.d.ts +2 -0
- package/dist/core/extensions/builtin/hooks/config-loader.d.ts.map +1 -1
- package/dist/core/extensions/builtin/hooks/config-loader.js +27 -0
- package/dist/core/extensions/builtin/hooks/config-loader.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/dispatcher.js +1 -0
- 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 +51 -2
- package/dist/core/extensions/builtin/hooks/index.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/lifecycle-adapter.d.ts +18 -1
- package/dist/core/extensions/builtin/hooks/lifecycle-adapter.d.ts.map +1 -1
- package/dist/core/extensions/builtin/hooks/lifecycle-adapter.js +36 -1
- package/dist/core/extensions/builtin/hooks/lifecycle-adapter.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/matcher.js +1 -0
- package/dist/core/extensions/builtin/hooks/matcher.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/output-parser.js +6 -0
- package/dist/core/extensions/builtin/hooks/output-parser.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/trust-storage.d.ts +2 -0
- package/dist/core/extensions/builtin/hooks/trust-storage.d.ts.map +1 -1
- package/dist/core/extensions/builtin/hooks/trust-storage.js +13 -0
- package/dist/core/extensions/builtin/hooks/trust-storage.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/types.d.ts +14 -2
- package/dist/core/extensions/builtin/hooks/types.d.ts.map +1 -1
- package/dist/core/extensions/builtin/hooks/types.js +1 -1
- package/dist/core/extensions/builtin/hooks/types.js.map +1 -1
- package/dist/core/extensions/builtin/monitor-state-event.d.ts +1 -0
- package/dist/core/extensions/builtin/monitor-state-event.d.ts.map +1 -1
- package/dist/core/extensions/builtin/monitor-state-event.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/bash.d.ts +1 -0
- package/dist/core/extensions/builtin/terminal/tools/bash.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/bash.js +13 -2
- package/dist/core/extensions/builtin/terminal/tools/bash.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +5 -1
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +5 -16
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +16 -5
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +28 -5
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/extensions/wrapper.d.ts +8 -3
- package/dist/core/extensions/wrapper.d.ts.map +1 -1
- package/dist/core/extensions/wrapper.js +12 -6
- package/dist/core/extensions/wrapper.js.map +1 -1
- package/dist/core/keybindings.d.ts +8 -1
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +7 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/package-manager.d.ts +4 -2
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +7 -2
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/pi-manifest.d.ts +2 -0
- package/dist/core/pi-manifest.d.ts.map +1 -1
- package/dist/core/pi-manifest.js +3 -0
- package/dist/core/pi-manifest.js.map +1 -1
- package/dist/core/resource-loader.d.ts +9 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +69 -21
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/settings-manager.d.ts +1 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +1 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/settings-shapes.d.ts +1 -0
- package/dist/core/settings-shapes.d.ts.map +1 -1
- package/dist/core/settings-shapes.js.map +1 -1
- package/dist/core/source-info.d.ts +5 -1
- package/dist/core/source-info.d.ts.map +1 -1
- package/dist/core/source-info.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +5 -0
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/modes/app-server/server/skills.d.ts.map +1 -1
- package/dist/modes/app-server/server/skills.js +1 -0
- package/dist/modes/app-server/server/skills.js.map +1 -1
- package/dist/modes/interactive/components/ask-user-answer-chip.d.ts +17 -0
- package/dist/modes/interactive/components/ask-user-answer-chip.d.ts.map +1 -0
- package/dist/modes/interactive/components/ask-user-answer-chip.js +86 -0
- package/dist/modes/interactive/components/ask-user-answer-chip.js.map +1 -0
- package/dist/modes/interactive/components/ask-user-answer-key.d.ts +3 -1
- package/dist/modes/interactive/components/ask-user-answer-key.d.ts.map +1 -1
- package/dist/modes/interactive/components/ask-user-answer-key.js +11 -1
- package/dist/modes/interactive/components/ask-user-answer-key.js.map +1 -1
- package/dist/modes/interactive/components/ask-user-async-widget.d.ts +5 -2
- package/dist/modes/interactive/components/ask-user-async-widget.d.ts.map +1 -1
- package/dist/modes/interactive/components/ask-user-async-widget.js +18 -12
- package/dist/modes/interactive/components/ask-user-async-widget.js.map +1 -1
- package/dist/modes/interactive/components/ask-user-countdown.d.ts +8 -0
- package/dist/modes/interactive/components/ask-user-countdown.d.ts.map +1 -0
- package/dist/modes/interactive/components/ask-user-countdown.js +23 -0
- package/dist/modes/interactive/components/ask-user-countdown.js.map +1 -0
- package/dist/modes/interactive/components/ask-user-question-keys.d.ts.map +1 -1
- package/dist/modes/interactive/components/ask-user-question-keys.js +85 -17
- package/dist/modes/interactive/components/ask-user-question-keys.js.map +1 -1
- package/dist/modes/interactive/components/ask-user-question-render.d.ts.map +1 -1
- package/dist/modes/interactive/components/ask-user-question-render.js +22 -7
- package/dist/modes/interactive/components/ask-user-question-render.js.map +1 -1
- package/dist/modes/interactive/components/ask-user-question-state.d.ts +15 -0
- package/dist/modes/interactive/components/ask-user-question-state.d.ts.map +1 -1
- package/dist/modes/interactive/components/ask-user-question-state.js +57 -13
- package/dist/modes/interactive/components/ask-user-question-state.js.map +1 -1
- package/dist/modes/interactive/components/ask-user-question.d.ts +8 -2
- package/dist/modes/interactive/components/ask-user-question.d.ts.map +1 -1
- package/dist/modes/interactive/components/ask-user-question.js +16 -8
- package/dist/modes/interactive/components/ask-user-question.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts +2 -1
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +2 -0
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +10 -1
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/loaded-resource-section.d.ts +14 -0
- package/dist/modes/interactive/components/loaded-resource-section.d.ts.map +1 -0
- package/dist/modes/interactive/components/loaded-resource-section.js +25 -0
- package/dist/modes/interactive/components/loaded-resource-section.js.map +1 -0
- package/dist/modes/interactive/components/user-message.d.ts +2 -1
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js +12 -2
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +14 -11
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +263 -165
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/loaded-resource-scopes.d.ts +28 -0
- package/dist/modes/interactive/loaded-resource-scopes.d.ts.map +1 -0
- package/dist/modes/interactive/loaded-resource-scopes.js +107 -0
- package/dist/modes/interactive/loaded-resource-scopes.js.map +1 -0
- package/dist/modes/interactive/tips/catalog/input-tips.d.ts +1 -1
- package/dist/modes/interactive/tips/catalog/input-tips.js +2 -2
- package/dist/modes/interactive/tips/catalog/input-tips.js.map +1 -1
- package/dist/modes/rpc/host-lifecycle.d.ts.map +1 -1
- package/dist/modes/rpc/host-lifecycle.js +7 -0
- package/dist/modes/rpc/host-lifecycle.js.map +1 -1
- package/dist/modes/rpc/session-worker.js +5 -0
- package/dist/modes/rpc/session-worker.js.map +1 -1
- package/docs/environment-variables.md +5 -1
- package/docs/extensions.md +43 -5
- package/docs/keybindings.md +5 -2
- package/docs/packages.md +17 -0
- package/docs/rpc.md +6 -3
- package/docs/settings.md +5 -1
- package/docs/tui.md +15 -3
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +28 -0
- package/node_modules/@code-yeongyu/senpi-codemode/README.md +16 -4
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-core.js +2 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/session-env.ts +6 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-manager.ts +6 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/run-eval-cell.ts +31 -12
- package/node_modules/@earendil-works/chord/package.json +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/messages.d.ts +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/messages.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/messages.js +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/messages.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +4 -4
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.lazy.d.ts +2 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.lazy.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.lazy.js +6 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.lazy.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 +55 -17
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +9 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/responses-completion-grace.d.ts +30 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/responses-completion-grace.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/responses-completion-grace.js +94 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/responses-completion-grace.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/websocket-liveness.d.ts +48 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/websocket-liveness.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/websocket-liveness.js +104 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/websocket-liveness.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/devin-provider.d.ts +6 -0
- package/node_modules/@earendil-works/pi-ai/dist/devin-provider.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/devin-provider.js +4 -0
- package/node_modules/@earendil-works/pi-ai/dist/devin-provider.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/together.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +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 +7 -3
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +10 -2
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/README.md +11 -3
- package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +2 -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 +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/mouse-input.d.ts +37 -0
- package/node_modules/@earendil-works/pi-tui/dist/mouse-input.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/mouse-input.js +97 -0
- package/node_modules/@earendil-works/pi-tui/dist/mouse-input.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts +2 -0
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js +38 -0
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts +25 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js +110 -4
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui-alt-screen.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui-alt-screen.js +5 -50
- package/node_modules/@earendil-works/pi-tui/dist/tui-alt-screen.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui-main-screen.d.ts +12 -0
- package/node_modules/@earendil-works/pi-tui/dist/tui-main-screen.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui-main-screen.js +129 -3
- package/node_modules/@earendil-works/pi-tui/dist/tui-main-screen.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts +28 -0
- package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui.js +160 -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/package.json +13 -9
- package/dist/bun/register-cursor-agent.d.ts +0 -2
- package/dist/bun/register-cursor-agent.d.ts.map +0 -1
- package/dist/bun/register-cursor-agent.js +0 -4
- package/dist/bun/register-cursor-agent.js.map +0 -1
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Extension } from "./extensions/types.ts";
|
|
2
|
+
import type { PathMetadata } from "./package-manager.ts";
|
|
3
|
+
import type { SourceScope } from "./source-info.ts";
|
|
4
|
+
export interface DiscoveredResourceEntry {
|
|
5
|
+
readonly path: string;
|
|
6
|
+
readonly extensionPath: string;
|
|
7
|
+
/** Scope the handler pinned explicitly; an entry without one inherits it from the contributor. */
|
|
8
|
+
readonly scope?: SourceScope;
|
|
9
|
+
}
|
|
10
|
+
export interface DiscoveredResourcePath {
|
|
11
|
+
readonly path: string;
|
|
12
|
+
readonly metadata: PathMetadata;
|
|
13
|
+
}
|
|
14
|
+
type ContributingExtension = Pick<Extension, "path" | "sourceInfo">;
|
|
15
|
+
export declare function getExtensionSourceLabel(extensionPath: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Turn discover results into loader metadata. A contributed path is `system` when the handler said so,
|
|
18
|
+
* or when it comes from a builtin extension, or when a system package contributes a path inside its
|
|
19
|
+
* own payload; everything else keeps the `temporary` scope contributed paths always had.
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveDiscoveredResourcePaths(entries: readonly DiscoveredResourceEntry[], extensions: readonly ContributingExtension[]): DiscoveredResourcePath[];
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=discovered-resource-scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovered-resource-scope.d.ts","sourceRoot":"","sources":["../../src/core/discovered-resource-scope.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,WAAW,uBAAuB;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,kGAAkG;IAClG,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC;CAC7B;AAED,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;CAChC;AAED,KAAK,qBAAqB,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,CAAC,CAAC;AAEpE,wBAAgB,uBAAuB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAKrE;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,CAC7C,OAAO,EAAE,SAAS,uBAAuB,EAAE,EAC3C,UAAU,EAAE,SAAS,qBAAqB,EAAE,GAC1C,sBAAsB,EAAE,CAiB1B"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { basename, dirname, resolve, sep } from "node:path";
|
|
2
|
+
export function getExtensionSourceLabel(extensionPath) {
|
|
3
|
+
if (extensionPath.startsWith("<")) {
|
|
4
|
+
return `extension:${extensionPath.replace(/[<>]/g, "")}`;
|
|
5
|
+
}
|
|
6
|
+
return `extension:${basename(extensionPath).replace(/\.(ts|js)$/, "")}`;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Turn discover results into loader metadata. A contributed path is `system` when the handler said so,
|
|
10
|
+
* or when it comes from a builtin extension, or when a system package contributes a path inside its
|
|
11
|
+
* own payload; everything else keeps the `temporary` scope contributed paths always had.
|
|
12
|
+
*/
|
|
13
|
+
export function resolveDiscoveredResourcePaths(entries, extensions) {
|
|
14
|
+
const contributors = new Map(extensions.map((extension) => [extension.path, extension]));
|
|
15
|
+
return entries.map((entry) => {
|
|
16
|
+
const contributor = contributors.get(entry.extensionPath);
|
|
17
|
+
const scope = entry.scope ??
|
|
18
|
+
(contributor !== undefined && inheritsSystemScope(contributor, entry.path) ? "system" : "temporary");
|
|
19
|
+
return {
|
|
20
|
+
path: entry.path,
|
|
21
|
+
metadata: {
|
|
22
|
+
source: getExtensionSourceLabel(entry.extensionPath),
|
|
23
|
+
scope,
|
|
24
|
+
origin: "top-level",
|
|
25
|
+
baseDir: entry.extensionPath.startsWith("<") ? undefined : dirname(entry.extensionPath),
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
function inheritsSystemScope(contributor, resourcePath) {
|
|
31
|
+
if (contributor.sourceInfo.scope !== "system")
|
|
32
|
+
return false;
|
|
33
|
+
if (contributor.path.startsWith("<builtin:"))
|
|
34
|
+
return true;
|
|
35
|
+
const packageRoot = contributor.sourceInfo.baseDir;
|
|
36
|
+
return packageRoot !== undefined && isUnderPath(resolve(resourcePath), resolve(packageRoot));
|
|
37
|
+
}
|
|
38
|
+
function isUnderPath(target, root) {
|
|
39
|
+
if (target === root)
|
|
40
|
+
return true;
|
|
41
|
+
const prefix = root.endsWith(sep) ? root : `${root}${sep}`;
|
|
42
|
+
return target.startsWith(prefix);
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=discovered-resource-scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovered-resource-scope.js","sourceRoot":"","sources":["../../src/core/discovered-resource-scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAmB5D,MAAM,UAAU,uBAAuB,CAAC,aAAqB;IAC5D,IAAI,aAAa,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,OAAO,aAAa,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC;IAC1D,CAAC;IACD,OAAO,aAAa,QAAQ,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC;AACzE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,8BAA8B,CAC7C,OAA2C,EAC3C,UAA4C;IAE5C,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IACzF,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QAC5B,MAAM,WAAW,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAC1D,MAAM,KAAK,GACV,KAAK,CAAC,KAAK;YACX,CAAC,WAAW,KAAK,SAAS,IAAI,mBAAmB,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;QACtG,OAAO;YACN,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,QAAQ,EAAE;gBACT,MAAM,EAAE,uBAAuB,CAAC,KAAK,CAAC,aAAa,CAAC;gBACpD,KAAK;gBACL,MAAM,EAAE,WAAW;gBACnB,OAAO,EAAE,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC;aACvF;SACD,CAAC;IACH,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAAC,WAAkC,EAAE,YAAoB;IACpF,IAAI,WAAW,CAAC,UAAU,CAAC,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5D,IAAI,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1D,MAAM,WAAW,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC;IACnD,OAAO,WAAW,KAAK,SAAS,IAAI,WAAW,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;AAC9F,CAAC;AAED,SAAS,WAAW,CAAC,MAAc,EAAE,IAAY;IAChD,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACjC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,GAAG,EAAE,CAAC;IAC3D,OAAO,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;AAClC,CAAC","sourcesContent":["import { basename, dirname, resolve, sep } from \"node:path\";\nimport type { Extension } from \"./extensions/types.ts\";\nimport type { PathMetadata } from \"./package-manager.ts\";\nimport type { SourceScope } from \"./source-info.ts\";\n\nexport interface DiscoveredResourceEntry {\n\treadonly path: string;\n\treadonly extensionPath: string;\n\t/** Scope the handler pinned explicitly; an entry without one inherits it from the contributor. */\n\treadonly scope?: SourceScope;\n}\n\nexport interface DiscoveredResourcePath {\n\treadonly path: string;\n\treadonly metadata: PathMetadata;\n}\n\ntype ContributingExtension = Pick<Extension, \"path\" | \"sourceInfo\">;\n\nexport function getExtensionSourceLabel(extensionPath: string): string {\n\tif (extensionPath.startsWith(\"<\")) {\n\t\treturn `extension:${extensionPath.replace(/[<>]/g, \"\")}`;\n\t}\n\treturn `extension:${basename(extensionPath).replace(/\\.(ts|js)$/, \"\")}`;\n}\n\n/**\n * Turn discover results into loader metadata. A contributed path is `system` when the handler said so,\n * or when it comes from a builtin extension, or when a system package contributes a path inside its\n * own payload; everything else keeps the `temporary` scope contributed paths always had.\n */\nexport function resolveDiscoveredResourcePaths(\n\tentries: readonly DiscoveredResourceEntry[],\n\textensions: readonly ContributingExtension[],\n): DiscoveredResourcePath[] {\n\tconst contributors = new Map(extensions.map((extension) => [extension.path, extension]));\n\treturn entries.map((entry) => {\n\t\tconst contributor = contributors.get(entry.extensionPath);\n\t\tconst scope =\n\t\t\tentry.scope ??\n\t\t\t(contributor !== undefined && inheritsSystemScope(contributor, entry.path) ? \"system\" : \"temporary\");\n\t\treturn {\n\t\t\tpath: entry.path,\n\t\t\tmetadata: {\n\t\t\t\tsource: getExtensionSourceLabel(entry.extensionPath),\n\t\t\t\tscope,\n\t\t\t\torigin: \"top-level\",\n\t\t\t\tbaseDir: entry.extensionPath.startsWith(\"<\") ? undefined : dirname(entry.extensionPath),\n\t\t\t},\n\t\t};\n\t});\n}\n\nfunction inheritsSystemScope(contributor: ContributingExtension, resourcePath: string): boolean {\n\tif (contributor.sourceInfo.scope !== \"system\") return false;\n\tif (contributor.path.startsWith(\"<builtin:\")) return true;\n\tconst packageRoot = contributor.sourceInfo.baseDir;\n\treturn packageRoot !== undefined && isUnderPath(resolve(resourcePath), resolve(packageRoot));\n}\n\nfunction isUnderPath(target: string, root: string): boolean {\n\tif (target === root) return true;\n\tconst prefix = root.endsWith(sep) ? root : `${root}${sep}`;\n\treturn target.startsWith(prefix);\n}\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ExtensionAPI, ExtensionContext } from "../../types.ts";
|
|
2
|
+
import type { AskUserVariant, QuestionRequest, QuestionResponse } from "./schema.ts";
|
|
3
|
+
export declare const ASK_USER_SETTLED_EVENT = "ask-user:settled";
|
|
4
|
+
export declare const ASK_USER_ASKED_EVENT = "ask-user:asked";
|
|
5
|
+
/** UI-only session metadata; never included in the model-facing answer frame. */
|
|
6
|
+
export declare const ASK_USER_QUESTION_ENTRY = "ask-user:question";
|
|
7
|
+
export interface AskUserQuestionEntry {
|
|
8
|
+
readonly requestId: string;
|
|
9
|
+
readonly headers: readonly string[];
|
|
10
|
+
}
|
|
11
|
+
export type AskUserAskedEvent = {
|
|
12
|
+
readonly ctx: ExtensionContext;
|
|
13
|
+
readonly request: QuestionRequest;
|
|
14
|
+
readonly variant: AskUserVariant;
|
|
15
|
+
};
|
|
16
|
+
export type AskUserSettledEvent = {
|
|
17
|
+
readonly ctx: ExtensionContext;
|
|
18
|
+
readonly request: QuestionRequest;
|
|
19
|
+
readonly response: QuestionResponse;
|
|
20
|
+
readonly variant: AskUserVariant;
|
|
21
|
+
};
|
|
22
|
+
/** Publish only; the active hooks builtin owns preparation and command execution. */
|
|
23
|
+
export declare function emitAskUserNotification(pi: Pick<ExtensionAPI, "events">, ctx: ExtensionContext, request: QuestionRequest, response: QuestionResponse, variant: AskUserVariant): void;
|
|
24
|
+
//# sourceMappingURL=notify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notify.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ask-user/notify.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAErF,eAAO,MAAM,sBAAsB,qBAAqB,CAAC;AACzD,eAAO,MAAM,oBAAoB,mBAAmB,CAAC;AACrD,iFAAiF;AACjF,eAAO,MAAM,uBAAuB,sBAAsB,CAAC;AAC3D,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC/B,QAAQ,CAAC,GAAG,EAAE,gBAAgB,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IACjC,QAAQ,CAAC,GAAG,EAAE,gBAAgB,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;CACjC,CAAC;AAEF,qFAAqF;AACrF,wBAAgB,uBAAuB,CACtC,EAAE,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,EAChC,GAAG,EAAE,gBAAgB,EACrB,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,cAAc,GACrB,IAAI,CAGN"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export const ASK_USER_SETTLED_EVENT = "ask-user:settled";
|
|
2
|
+
export const ASK_USER_ASKED_EVENT = "ask-user:asked";
|
|
3
|
+
/** UI-only session metadata; never included in the model-facing answer frame. */
|
|
4
|
+
export const ASK_USER_QUESTION_ENTRY = "ask-user:question";
|
|
5
|
+
/** Publish only; the active hooks builtin owns preparation and command execution. */
|
|
6
|
+
export function emitAskUserNotification(pi, ctx, request, response, variant) {
|
|
7
|
+
if (response.status === "cancelled")
|
|
8
|
+
return;
|
|
9
|
+
pi.events.emit(ASK_USER_SETTLED_EVENT, { ctx, request, response, variant });
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=notify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notify.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ask-user/notify.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,sBAAsB,GAAG,kBAAkB,CAAC;AACzD,MAAM,CAAC,MAAM,oBAAoB,GAAG,gBAAgB,CAAC;AACrD,iFAAiF;AACjF,MAAM,CAAC,MAAM,uBAAuB,GAAG,mBAAmB,CAAC;AAmB3D,qFAAqF;AACrF,MAAM,UAAU,uBAAuB,CACtC,EAAgC,EAChC,GAAqB,EACrB,OAAwB,EACxB,QAA0B,EAC1B,OAAuB;IAEvB,IAAI,QAAQ,CAAC,MAAM,KAAK,WAAW;QAAE,OAAO;IAC5C,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,sBAAsB,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAgC,CAAC,CAAC;AAC3G,CAAC","sourcesContent":["import type { ExtensionAPI, ExtensionContext } from \"../../types.ts\";\nimport type { AskUserVariant, QuestionRequest, QuestionResponse } from \"./schema.ts\";\n\nexport const ASK_USER_SETTLED_EVENT = \"ask-user:settled\";\nexport const ASK_USER_ASKED_EVENT = \"ask-user:asked\";\n/** UI-only session metadata; never included in the model-facing answer frame. */\nexport const ASK_USER_QUESTION_ENTRY = \"ask-user:question\";\nexport interface AskUserQuestionEntry {\n\treadonly requestId: string;\n\treadonly headers: readonly string[];\n}\n\nexport type AskUserAskedEvent = {\n\treadonly ctx: ExtensionContext;\n\treadonly request: QuestionRequest;\n\treadonly variant: AskUserVariant;\n};\n\nexport type AskUserSettledEvent = {\n\treadonly ctx: ExtensionContext;\n\treadonly request: QuestionRequest;\n\treadonly response: QuestionResponse;\n\treadonly variant: AskUserVariant;\n};\n\n/** Publish only; the active hooks builtin owns preparation and command execution. */\nexport function emitAskUserNotification(\n\tpi: Pick<ExtensionAPI, \"events\">,\n\tctx: ExtensionContext,\n\trequest: QuestionRequest,\n\tresponse: QuestionResponse,\n\tvariant: AskUserVariant,\n): void {\n\tif (response.status === \"cancelled\") return;\n\tpi.events.emit(ASK_USER_SETTLED_EVENT, { ctx, request, response, variant } satisfies AskUserSettledEvent);\n}\n"]}
|
|
@@ -5,6 +5,8 @@ import type { QuestionRequest, QuestionResponse } from "./schema.ts";
|
|
|
5
5
|
export interface QuestionDialogOptions extends ExtensionUIDialogOptions {
|
|
6
6
|
deliver: "tool-result" | "user-message";
|
|
7
7
|
hardDeadlineAtMs: number;
|
|
8
|
+
/** Live absolute idle deadline; question UI countdowns are display-only when supplied. */
|
|
9
|
+
getDeadlineAtMs?: () => number;
|
|
8
10
|
onProgress: (draft: {
|
|
9
11
|
answers?: QuestionResponse["answers"];
|
|
10
12
|
comment?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ask-user/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAErE,4FAA4F;AAC5F,MAAM,WAAW,qBAAsB,SAAQ,wBAAwB;IACtE,OAAO,EAAE,aAAa,GAAG,cAAc,CAAC;IACxC,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,CAAC,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CACzF;AACD,MAAM,WAAW,oBAAoB;IACpC,OAAO,EAAE,eAAe,CAAC;IACzB,OAAO,EAAE,eAAe,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACtC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,oBAAoB,EAAE,CAEtF;AACD,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,oBAAoB,GAAG,MAAM,IAAI,CAYlG"}
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ask-user/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAErE,4FAA4F;AAC5F,MAAM,WAAW,qBAAsB,SAAQ,wBAAwB;IACtE,OAAO,EAAE,aAAa,GAAG,cAAc,CAAC;IACxC,gBAAgB,EAAE,MAAM,CAAC;IACzB,0FAA0F;IAC1F,eAAe,CAAC,EAAE,MAAM,MAAM,CAAC;IAC/B,UAAU,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,CAAC,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CACzF;AACD,MAAM,WAAW,oBAAoB;IACpC,OAAO,EAAE,eAAe,CAAC;IACzB,OAAO,EAAE,eAAe,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACtC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,oBAAoB,EAAE,CAEtF;AACD,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,oBAAoB,GAAG,MAAM,IAAI,CAYlG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ask-user/registry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ask-user/registry.ts"],"names":[],"mappings":"AAkBA,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA6C,CAAC;AACtE,MAAM,UAAU,mBAAmB,CAAC,SAAiB;IACpD,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACvD,CAAC;AACD,MAAM,UAAU,uBAAuB,CAAC,SAAiB,EAAE,KAA2B;IACrF,IAAI,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACtC,IAAI,CAAC,OAAO,EAAE,CAAC;QACd,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;QACpB,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAC5C,OAAO,GAAG,EAAE;QACX,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,KAAK;YAAE,OAAO;QAC3D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACxC,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC;YAAE,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC,CAAC;AACH,CAAC","sourcesContent":["import type { ExtensionUIDialogOptions } from \"../../types.ts\";\nimport type { PendingQuestion } from \"./pending.ts\";\nimport type { QuestionRequest, QuestionResponse } from \"./schema.ts\";\n\n/** Additive options consumed by question-capable UI bridges. Delivery belongs to the UI. */\nexport interface QuestionDialogOptions extends ExtensionUIDialogOptions {\n\tdeliver: \"tool-result\" | \"user-message\";\n\thardDeadlineAtMs: number;\n\t/** Live absolute idle deadline; question UI countdowns are display-only when supplied. */\n\tgetDeadlineAtMs?: () => number;\n\tonProgress: (draft: { answers?: QuestionResponse[\"answers\"]; comment?: string }) => void;\n}\nexport interface PendingQuestionEntry {\n\trequest: QuestionRequest;\n\tpending: PendingQuestion;\n\tcompletion: Promise<QuestionResponse>;\n\tcancel(message?: string): void;\n}\nconst sessions = new Map<string, Map<string, PendingQuestionEntry>>();\nexport function getPendingQuestions(sessionId: string): readonly PendingQuestionEntry[] {\n\treturn [...(sessions.get(sessionId)?.values() ?? [])];\n}\nexport function registerPendingQuestion(sessionId: string, entry: PendingQuestionEntry): () => void {\n\tlet entries = sessions.get(sessionId);\n\tif (!entries) {\n\t\tentries = new Map();\n\t\tsessions.set(sessionId, entries);\n\t}\n\tentries.set(entry.request.requestId, entry);\n\treturn () => {\n\t\tif (entries.get(entry.request.requestId) !== entry) return;\n\t\tentries.delete(entry.request.requestId);\n\t\tif (entries.size === 0) sessions.delete(sessionId);\n\t};\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { ExtensionAPI, ExtensionContext, SessionStartEvent } from "../../types.ts";
|
|
2
2
|
export declare const ASK_USER_RESUMED_ENTRY = "ask-user:resumed";
|
|
3
|
-
export declare function resumeDanglingQuestion(pi: Pick<ExtensionAPI, "appendEntry" | "sendUserMessage">, event: Pick<SessionStartEvent, "reason">, ctx:
|
|
3
|
+
export declare function resumeDanglingQuestion(pi: Pick<ExtensionAPI, "appendEntry" | "sendUserMessage" | "events">, event: Pick<SessionStartEvent, "reason">, ctx: ExtensionContext): Promise<void>;
|
|
4
4
|
//# sourceMappingURL=resume.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resume.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ask-user/resume.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"resume.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ask-user/resume.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAaxF,eAAO,MAAM,sBAAsB,qBAAqB,CAAC;AAiEzD,wBAAsB,sBAAsB,CAC3C,EAAE,EAAE,IAAI,CAAC,YAAY,EAAE,aAAa,GAAG,iBAAiB,GAAG,QAAQ,CAAC,EACpE,KAAK,EAAE,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC,EACxC,GAAG,EAAE,gBAAgB,GACnB,OAAO,CAAC,IAAI,CAAC,CAmBf"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { TOOL_NAMES } from "./family.js";
|
|
2
2
|
import { formatUserMessage } from "./format.js";
|
|
3
|
+
import { emitAskUserNotification } from "./notify.js";
|
|
3
4
|
import { DEFAULT_ASK_USER_TIMEOUT_MS, toCanonical, } from "./schema.js";
|
|
5
|
+
import { startQuestion } from "./tool.js";
|
|
4
6
|
export const ASK_USER_RESUMED_ENTRY = "ask-user:resumed";
|
|
5
7
|
function isRecord(value) {
|
|
6
8
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -50,15 +52,11 @@ function requestFromCall(dangling, timeoutMs) {
|
|
|
50
52
|
return { requestId: dangling.toolCallId, questions: [], waitForAnswer: false, timeoutMs };
|
|
51
53
|
}
|
|
52
54
|
}
|
|
53
|
-
function
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
answers: {},
|
|
57
|
-
unanswered: request.questions.map((question) => question.id),
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
function deliver(pi, request, response) {
|
|
55
|
+
function deliver(pi, ctx, request, response, variant) {
|
|
56
|
+
if (response.status === "cancelled")
|
|
57
|
+
return;
|
|
61
58
|
pi.sendUserMessage(formatUserMessage(response, request.requestId, request.questions));
|
|
59
|
+
emitAskUserNotification(pi, ctx, request, response, variant);
|
|
62
60
|
}
|
|
63
61
|
export async function resumeDanglingQuestion(pi, event, ctx) {
|
|
64
62
|
if (event.reason !== "resume" && event.reason !== "reload")
|
|
@@ -69,17 +67,9 @@ export async function resumeDanglingQuestion(pi, event, ctx) {
|
|
|
69
67
|
pi.appendEntry(ASK_USER_RESUMED_ENTRY, { toolCallId: dangling.toolCallId });
|
|
70
68
|
const timeoutMs = (ctx.getAskUserSettings?.().timeoutMinutes ?? DEFAULT_ASK_USER_TIMEOUT_MS / 60_000) * 60_000;
|
|
71
69
|
const request = requestFromCall(dangling, timeoutMs);
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
try {
|
|
78
|
-
const response = await question.call(ctx.ui, request, { timeout: request.timeoutMs });
|
|
79
|
-
deliver(pi, request, response);
|
|
80
|
-
}
|
|
81
|
-
catch {
|
|
82
|
-
deliver(pi, request, orphaned(request));
|
|
83
|
-
}
|
|
70
|
+
// A dangling disk record creates a new runtime registration. Transport/UI
|
|
71
|
+
// hydration reuses that registration and never re-enters this lifecycle.
|
|
72
|
+
const response = await startQuestion(pi, ctx, request, ctx.signal, { timedOut: false, unavailable: false }, dangling.variant, { resuming: true });
|
|
73
|
+
deliver(pi, ctx, request, response, dangling.variant);
|
|
84
74
|
}
|
|
85
75
|
//# sourceMappingURL=resume.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resume.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ask-user/resume.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAEN,2BAA2B,EAG3B,WAAW,GACX,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"resume.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ask-user/resume.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SessionEntry } from \"../../../session-manager.ts\";\nimport type { ExtensionAPI, ExtensionContext, SessionStartEvent } from \"../../types.ts\";\nimport { TOOL_NAMES } from \"./family.ts\";\nimport { formatUserMessage } from \"./format.ts\";\nimport { emitAskUserNotification } from \"./notify.ts\";\nimport {\n\ttype AskUserVariant,\n\tDEFAULT_ASK_USER_TIMEOUT_MS,\n\ttype QuestionRequest,\n\ttype QuestionResponse,\n\ttoCanonical,\n} from \"./schema.ts\";\nimport { startQuestion } from \"./tool.ts\";\n\nexport const ASK_USER_RESUMED_ENTRY = \"ask-user:resumed\";\n\ntype DanglingQuestion = {\n\ttoolCallId: string;\n\tvariant: AskUserVariant;\n\targs: unknown;\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction variantFor(name: string): AskUserVariant | undefined {\n\tif (name === TOOL_NAMES.claude) return \"claude\";\n\tif (name === TOOL_NAMES.codex) return \"codex\";\n\treturn undefined;\n}\n\nfunction findDanglingQuestion(entries: readonly SessionEntry[]): DanglingQuestion | undefined {\n\tconst results = new Set<string>();\n\tconst resumed = new Set<string>();\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"custom\" && entry.customType === ASK_USER_RESUMED_ENTRY && isRecord(entry.data)) {\n\t\t\tconst toolCallId = entry.data.toolCallId;\n\t\t\tif (typeof toolCallId === \"string\") resumed.add(toolCallId);\n\t\t}\n\t\tif (entry.type === \"message\" && entry.message.role === \"toolResult\") {\n\t\t\tresults.add(entry.message.toolCallId);\n\t\t}\n\t}\n\tfor (let index = entries.length - 1; index >= 0; index--) {\n\t\tconst entry = entries[index];\n\t\tif (entry?.type !== \"message\" || entry.message.role !== \"assistant\") continue;\n\t\tconst content = entry.message.content;\n\t\tfor (let blockIndex = content.length - 1; blockIndex >= 0; blockIndex--) {\n\t\t\tconst block = content[blockIndex];\n\t\t\tif (block?.type !== \"toolCall\" || block.incomplete === true) continue;\n\t\t\tconst variant = variantFor(block.name);\n\t\t\tif (!variant || results.has(block.id) || resumed.has(block.id)) continue;\n\t\t\treturn { toolCallId: block.id, variant, args: block.arguments };\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction requestFromCall(dangling: DanglingQuestion, timeoutMs: number): QuestionRequest {\n\ttry {\n\t\treturn toCanonical(dangling.variant, dangling.args, { requestId: dangling.toolCallId, timeoutMs });\n\t} catch {\n\t\treturn { requestId: dangling.toolCallId, questions: [], waitForAnswer: false, timeoutMs };\n\t}\n}\n\nfunction deliver(\n\tpi: Pick<ExtensionAPI, \"sendUserMessage\" | \"events\">,\n\tctx: ExtensionContext,\n\trequest: QuestionRequest,\n\tresponse: QuestionResponse,\n\tvariant: AskUserVariant,\n): void {\n\tif (response.status === \"cancelled\") return;\n\tpi.sendUserMessage(formatUserMessage(response, request.requestId, request.questions));\n\temitAskUserNotification(pi, ctx, request, response, variant);\n}\n\nexport async function resumeDanglingQuestion(\n\tpi: Pick<ExtensionAPI, \"appendEntry\" | \"sendUserMessage\" | \"events\">,\n\tevent: Pick<SessionStartEvent, \"reason\">,\n\tctx: ExtensionContext,\n): Promise<void> {\n\tif (event.reason !== \"resume\" && event.reason !== \"reload\") return;\n\tconst dangling = findDanglingQuestion(ctx.sessionManager.getBranch());\n\tif (!dangling) return;\n\tpi.appendEntry(ASK_USER_RESUMED_ENTRY, { toolCallId: dangling.toolCallId });\n\tconst timeoutMs = (ctx.getAskUserSettings?.().timeoutMinutes ?? DEFAULT_ASK_USER_TIMEOUT_MS / 60_000) * 60_000;\n\tconst request = requestFromCall(dangling, timeoutMs);\n\t// A dangling disk record creates a new runtime registration. Transport/UI\n\t// hydration reuses that registration and never re-enters this lifecycle.\n\tconst response = await startQuestion(\n\t\tpi,\n\t\tctx,\n\t\trequest,\n\t\tctx.signal,\n\t\t{ timedOut: false, unavailable: false },\n\t\tdangling.variant,\n\t\t{ resuming: true },\n\t);\n\tdeliver(pi, ctx, request, response, dangling.variant);\n}\n"]}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import type { ExtensionAPI, ToolDefinition } from "../../types.ts";
|
|
2
|
-
import { type AskUserVariant } from "./schema.ts";
|
|
1
|
+
import type { ExtensionAPI, ExtensionContext, ToolDefinition } from "../../types.ts";
|
|
2
|
+
import { type AskUserVariant, type QuestionRequest, type QuestionResponse } from "./schema.ts";
|
|
3
3
|
export interface AskUserState {
|
|
4
4
|
timedOut: boolean;
|
|
5
5
|
unavailable: boolean;
|
|
6
6
|
}
|
|
7
|
+
export declare function startQuestion(pi: Pick<ExtensionAPI, "sendUserMessage" | "events" | "appendEntry">, ctx: ExtensionContext, request: QuestionRequest, signal: AbortSignal | undefined, state: AskUserState, variant: "codex" | "claude", { resuming }?: {
|
|
8
|
+
resuming?: boolean;
|
|
9
|
+
}): Promise<QuestionResponse>;
|
|
7
10
|
export declare function createAskUserTool(variant: AskUserVariant, pi: ExtensionAPI, state: AskUserState): ToolDefinition;
|
|
8
11
|
//# sourceMappingURL=tool.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ask-user/tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ask-user/tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAcrF,OAAO,EAEN,KAAK,cAAc,EAGnB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EAErB,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,YAAY;IAC5B,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;CACrB;AA+CD,wBAAgB,aAAa,CAC5B,EAAE,EAAE,IAAI,CAAC,YAAY,EAAE,iBAAiB,GAAG,QAAQ,GAAG,aAAa,CAAC,EACpE,GAAG,EAAE,gBAAgB,EACrB,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,OAAO,GAAG,QAAQ,EAC3B,EAAE,QAAgB,EAAE,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,6BA2GjD;AACD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,cAAc,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,GAAG,cAAc,CAmEhH"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { WAKE_SOURCE_STATE_EVENT } from "../monitor-state-event.js";
|
|
2
2
|
import { TOOL_NAMES } from "./family.js";
|
|
3
3
|
import { formatResultDetails, formatResultText, formatUserMessage } from "./format.js";
|
|
4
|
+
import { ASK_USER_ASKED_EVENT, ASK_USER_QUESTION_ENTRY, emitAskUserNotification, } from "./notify.js";
|
|
4
5
|
import { createPendingQuestion } from "./pending.js";
|
|
5
6
|
import { getPendingQuestions, registerPendingQuestion } from "./registry.js";
|
|
6
7
|
import { renderCall, renderResult } from "./render.js";
|
|
@@ -20,12 +21,13 @@ function result(variant, response, request, text) {
|
|
|
20
21
|
* triggers a turn, which is what wakes the model after a timeout. A cancelled
|
|
21
22
|
* question stays silent: it was dismissed, superseded, or aborted.
|
|
22
23
|
*/
|
|
23
|
-
function deliverAnswer(pi, ctx, request, response) {
|
|
24
|
+
function deliverAnswer(pi, ctx, request, response, variant) {
|
|
24
25
|
if (response.status === "cancelled")
|
|
25
26
|
return;
|
|
26
27
|
pi.sendUserMessage(formatUserMessage(response, request.requestId, request.questions), {
|
|
27
28
|
deliverAs: ctx.isIdle() ? "followUp" : "steer",
|
|
28
29
|
});
|
|
30
|
+
void emitAskUserNotification(pi, ctx, request, response, variant);
|
|
29
31
|
}
|
|
30
32
|
function emitWake(pi, sessionId) {
|
|
31
33
|
const entries = getPendingQuestions(sessionId).filter((e) => !e.request.waitForAnswer);
|
|
@@ -34,16 +36,25 @@ function emitWake(pi, sessionId) {
|
|
|
34
36
|
activeCount: entries.length,
|
|
35
37
|
items: entries.map((e) => ({
|
|
36
38
|
id: e.request.requestId,
|
|
39
|
+
deadlineAtMs: e.pending.deadlineAtMs,
|
|
37
40
|
description: e.request.questions.map((q) => q.header).join(", "),
|
|
38
41
|
})),
|
|
39
42
|
};
|
|
40
43
|
pi.events.emit(WAKE_SOURCE_STATE_EVENT, event);
|
|
41
44
|
}
|
|
42
|
-
function startQuestion(pi, ctx, request, signal, state) {
|
|
45
|
+
export function startQuestion(pi, ctx, request, signal, state, variant, { resuming = false } = {}) {
|
|
43
46
|
const question = ctx.ui.question;
|
|
44
|
-
if (!question)
|
|
47
|
+
if (!question && !resuming)
|
|
45
48
|
throw new Error("Question UI is unavailable");
|
|
46
49
|
const sessionId = ctx.sessionManager.getSessionId();
|
|
50
|
+
const existing = getPendingQuestions(sessionId).find((entry) => entry.request.requestId === request.requestId);
|
|
51
|
+
if (existing)
|
|
52
|
+
return existing.completion;
|
|
53
|
+
const orphaned = () => ({
|
|
54
|
+
status: "orphaned-after-restart",
|
|
55
|
+
answers: {},
|
|
56
|
+
unanswered: request.questions.map((question) => question.id),
|
|
57
|
+
});
|
|
47
58
|
const controller = new AbortController();
|
|
48
59
|
const completion = Promise.withResolvers();
|
|
49
60
|
let settled = false;
|
|
@@ -58,6 +69,7 @@ function startQuestion(pi, ctx, request, signal, state) {
|
|
|
58
69
|
signal?.removeEventListener("abort", abort);
|
|
59
70
|
if (!request.waitForAnswer)
|
|
60
71
|
emitWake(pi, sessionId);
|
|
72
|
+
pi.events.emit("herdr:blocked", { active: false, id: request.requestId });
|
|
61
73
|
completion.resolve(response);
|
|
62
74
|
// This extension owns the authoritative idle timer (pending.ts), so a UI
|
|
63
75
|
// bridge that is still waiting learns the outcome only from this abort.
|
|
@@ -78,8 +90,19 @@ function startQuestion(pi, ctx, request, signal, state) {
|
|
|
78
90
|
};
|
|
79
91
|
const abort = () => cancel();
|
|
80
92
|
unregister = registerPendingQuestion(sessionId, { request, pending, completion: completion.promise, cancel });
|
|
93
|
+
pi.appendEntry(ASK_USER_QUESTION_ENTRY, {
|
|
94
|
+
requestId: request.requestId,
|
|
95
|
+
headers: request.questions.map((question) => question.header),
|
|
96
|
+
});
|
|
81
97
|
if (!request.waitForAnswer)
|
|
82
98
|
emitWake(pi, sessionId);
|
|
99
|
+
pi.events.emit(ASK_USER_ASKED_EVENT, { ctx, request, variant });
|
|
100
|
+
const first = request.questions[0];
|
|
101
|
+
pi.events.emit("herdr:blocked", {
|
|
102
|
+
active: true,
|
|
103
|
+
label: first ? `${first.header} — ${first.question}` : "Question",
|
|
104
|
+
id: request.requestId,
|
|
105
|
+
});
|
|
83
106
|
signal?.addEventListener("abort", abort, { once: true });
|
|
84
107
|
let draft = { answers: {} };
|
|
85
108
|
const opts = {
|
|
@@ -87,9 +110,12 @@ function startQuestion(pi, ctx, request, signal, state) {
|
|
|
87
110
|
signal: controller.signal,
|
|
88
111
|
deliver: request.waitForAnswer ? "tool-result" : "user-message",
|
|
89
112
|
hardDeadlineAtMs: Date.now() + 7_200_000,
|
|
113
|
+
getDeadlineAtMs: () => pending.deadlineAtMs,
|
|
90
114
|
onProgress: (progress) => {
|
|
91
115
|
draft = { ...draft, ...progress, answers: progress.answers ?? draft.answers };
|
|
92
116
|
pending.touch(draft);
|
|
117
|
+
if (!request.waitForAnswer)
|
|
118
|
+
emitWake(pi, sessionId);
|
|
93
119
|
},
|
|
94
120
|
};
|
|
95
121
|
const accept = (response) => {
|
|
@@ -115,11 +141,17 @@ function startQuestion(pi, ctx, request, signal, state) {
|
|
|
115
141
|
if (settled)
|
|
116
142
|
return;
|
|
117
143
|
const message = `Question UI failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
144
|
+
if (resuming) {
|
|
145
|
+
accept({ ...orphaned(), comment: message });
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
118
148
|
cancel(message);
|
|
119
149
|
ctx.ui.notify(message, "error");
|
|
120
150
|
};
|
|
121
151
|
if (signal?.aborted)
|
|
122
152
|
abort();
|
|
153
|
+
else if (!question)
|
|
154
|
+
accept(orphaned());
|
|
123
155
|
else {
|
|
124
156
|
try {
|
|
125
157
|
question.call(ctx.ui, request, opts).then(accept, fail);
|
|
@@ -128,8 +160,8 @@ function startQuestion(pi, ctx, request, signal, state) {
|
|
|
128
160
|
fail(error);
|
|
129
161
|
}
|
|
130
162
|
}
|
|
131
|
-
if (!request.waitForAnswer)
|
|
132
|
-
void completion.promise.then((response) => deliverAnswer(pi, ctx, request, response));
|
|
163
|
+
if (!request.waitForAnswer && !resuming)
|
|
164
|
+
void completion.promise.then((response) => deliverAnswer(pi, ctx, request, response, variant));
|
|
133
165
|
return completion.promise;
|
|
134
166
|
}
|
|
135
167
|
export function createAskUserTool(variant, pi, state) {
|
|
@@ -179,13 +211,16 @@ export function createAskUserTool(variant, pi, state) {
|
|
|
179
211
|
pi.setActiveTools(pi.getActiveTools().filter((name) => !Object.values(TOOL_NAMES).includes(name)));
|
|
180
212
|
return result(variant, unavailable, request);
|
|
181
213
|
}
|
|
182
|
-
const completion = startQuestion(pi, ctx, request, signal, state);
|
|
214
|
+
const completion = startQuestion(pi, ctx, request, signal, state, variant);
|
|
183
215
|
if (!request.waitForAnswer)
|
|
184
216
|
return {
|
|
185
217
|
content: [{ type: "text", text: "Question accepted; the answer will arrive as a user message." }],
|
|
186
218
|
details: { accepted: true, requestId: request.requestId, status: "pending" },
|
|
187
219
|
};
|
|
188
220
|
const response = await completion;
|
|
221
|
+
if (response.status !== "cancelled") {
|
|
222
|
+
void emitAskUserNotification(pi, ctx, request, response, variant);
|
|
223
|
+
}
|
|
189
224
|
return result(variant, response, request, response.status === "cancelled" && response.comment ? response.comment : undefined);
|
|
190
225
|
},
|
|
191
226
|
renderCall,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ask-user/tool.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExtensionAPI, ExtensionContext, ToolDefinition } from \"../../types.ts\";\nimport { WAKE_SOURCE_STATE_EVENT, type WakeSourceStateEvent } from \"../monitor-state-event.ts\";\nimport { TOOL_NAMES } from \"./family.ts\";\nimport { formatResultDetails, formatResultText, formatUserMessage } from \"./format.ts\";\nimport { createPendingQuestion } from \"./pending.ts\";\nimport { getPendingQuestions, type QuestionDialogOptions, registerPendingQuestion } from \"./registry.ts\";\nimport { renderCall, renderResult } from \"./render.ts\";\nimport {\n\tAskUserSchemaError,\n\ttype AskUserVariant,\n\tCLAUDE_PARAMS,\n\tCODEX_PARAMS,\n\ttype QuestionRequest,\n\ttype QuestionResponse,\n\ttoCanonical,\n} from \"./schema.ts\";\n\nexport interface AskUserState {\n\ttimedOut: boolean;\n\tunavailable: boolean;\n}\nconst REASK = \"The user did not answer the previous question this turn; continue without asking again.\";\nfunction result(\n\tvariant: AskUserVariant,\n\tresponse: QuestionResponse,\n\trequest: QuestionRequest,\n\ttext?: string,\n): Awaited<ReturnType<ToolDefinition[\"execute\"]>> {\n\treturn {\n\t\tcontent: [{ type: \"text\", text: text ?? formatResultText(variant, response, request.questions) }],\n\t\tdetails: formatResultDetails(variant, response, request.questions),\n\t};\n}\n/**\n * Deliver a settled async answer as one framed user message. The extension owns\n * this so every surface (interactive TUI, RPC, app-server) only has to RESOLVE\n * the question; a surface that delivered on its own would send it twice. It\n * steers into a running turn and follows up when idle - a follow-up always\n * triggers a turn, which is what wakes the model after a timeout. A cancelled\n * question stays silent: it was dismissed, superseded, or aborted.\n */\nfunction deliverAnswer(\n\tpi: ExtensionAPI,\n\tctx: ExtensionContext,\n\trequest: QuestionRequest,\n\tresponse: QuestionResponse,\n): void {\n\tif (response.status === \"cancelled\") return;\n\tpi.sendUserMessage(formatUserMessage(response, request.requestId, request.questions), {\n\t\tdeliverAs: ctx.isIdle() ? \"followUp\" : \"steer\",\n\t});\n}\nfunction emitWake(pi: ExtensionAPI, sessionId: string) {\n\tconst entries = getPendingQuestions(sessionId).filter((e) => !e.request.waitForAnswer);\n\tconst event: WakeSourceStateEvent = {\n\t\tsource: \"ask-user\",\n\t\tactiveCount: entries.length,\n\t\titems: entries.map((e) => ({\n\t\t\tid: e.request.requestId,\n\t\t\tdescription: e.request.questions.map((q) => q.header).join(\", \"),\n\t\t})),\n\t};\n\tpi.events.emit(WAKE_SOURCE_STATE_EVENT, event);\n}\nfunction startQuestion(\n\tpi: ExtensionAPI,\n\tctx: ExtensionContext,\n\trequest: QuestionRequest,\n\tsignal: AbortSignal | undefined,\n\tstate: AskUserState,\n) {\n\tconst question = ctx.ui.question;\n\tif (!question) throw new Error(\"Question UI is unavailable\");\n\tconst sessionId = ctx.sessionManager.getSessionId();\n\tconst controller = new AbortController();\n\tconst completion = Promise.withResolvers<QuestionResponse>();\n\tlet settled = false;\n\tlet unregister = () => {};\n\tconst finish = (response: QuestionResponse) => {\n\t\tif (settled) return;\n\t\tsettled = true;\n\t\tif (response.status === \"timed_out\") state.timedOut = true;\n\t\tunregister();\n\t\tsignal?.removeEventListener(\"abort\", abort);\n\t\tif (!request.waitForAnswer) emitWake(pi, sessionId);\n\t\tcompletion.resolve(response);\n\t\t// This extension owns the authoritative idle timer (pending.ts), so a UI\n\t\t// bridge that is still waiting learns the outcome only from this abort.\n\t\t// Carry the resolved status as the abort reason: a bare abort reads as a\n\t\t// dismissal, and the RPC bridge would broadcast a timeout as \"cancelled\".\n\t\tconst abortReason: QuestionResponse[\"status\"] = response.status;\n\t\tcontroller.abort(abortReason);\n\t};\n\tconst pending = createPendingQuestion({\n\t\trequest,\n\t\tnow: Date.now,\n\t\tidleTimeoutMs: request.timeoutMs,\n\t\tonTimeout: finish,\n\t});\n\tconst cancel = (message?: string) => {\n\t\tconst response = pending.cancel();\n\t\tfinish(message ? { ...response, comment: message } : response);\n\t};\n\tconst abort = () => cancel();\n\tunregister = registerPendingQuestion(sessionId, { request, pending, completion: completion.promise, cancel });\n\tif (!request.waitForAnswer) emitWake(pi, sessionId);\n\tsignal?.addEventListener(\"abort\", abort, { once: true });\n\tlet draft: { answers: QuestionResponse[\"answers\"]; comment?: string } = { answers: {} };\n\tconst opts: QuestionDialogOptions = {\n\t\ttimeout: request.timeoutMs,\n\t\tsignal: controller.signal,\n\t\tdeliver: request.waitForAnswer ? \"tool-result\" : \"user-message\",\n\t\thardDeadlineAtMs: Date.now() + 7_200_000,\n\t\tonProgress: (progress) => {\n\t\t\tdraft = { ...draft, ...progress, answers: progress.answers ?? draft.answers };\n\t\t\tpending.touch(draft);\n\t\t},\n\t};\n\tconst accept = (response: QuestionResponse) => {\n\t\tif (settled) return;\n\t\tpending.touch({ answers: response.answers, comment: response.comment });\n\t\tif (response.status === \"timed_out\") {\n\t\t\tfinish(response);\n\t\t\tpending.timeout();\n\t\t\treturn;\n\t\t}\n\t\tif (response.status === \"answered\" || response.status === \"comment-submitted\") {\n\t\t\t// The UI owns partial submission validation; retain its response verbatim.\n\t\t\tpending.submit(response.answers, response.comment);\n\t\t\tif (pending.state === \"pending\") pending.cancel();\n\t\t} else pending.cancel(response.status);\n\t\tfinish(response);\n\t};\n\tconst fail = (error: unknown) => {\n\t\tif (settled) return;\n\t\tconst message = `Question UI failed: ${error instanceof Error ? error.message : String(error)}`;\n\t\tcancel(message);\n\t\tctx.ui.notify(message, \"error\");\n\t};\n\tif (signal?.aborted) abort();\n\telse {\n\t\ttry {\n\t\t\tquestion.call(ctx.ui, request, opts).then(accept, fail);\n\t\t} catch (error: unknown) {\n\t\t\tfail(error);\n\t\t}\n\t}\n\tif (!request.waitForAnswer) void completion.promise.then((response) => deliverAnswer(pi, ctx, request, response));\n\treturn completion.promise;\n}\nexport function createAskUserTool(variant: AskUserVariant, pi: ExtensionAPI, state: AskUserState): ToolDefinition {\n\tconst flag = variant === \"codex\" ? \"wait_for_answer\" : \"waitForAnswer\";\n\tconst opener =\n\t\tvariant === \"codex\"\n\t\t\t? \"Request user input for one to three short questions.\"\n\t\t\t: \"Ask the user one to four concise questions.\";\n\treturn {\n\t\tname: TOOL_NAMES[variant],\n\t\tlabel: \"Ask user\",\n\t\texposure: \"direct\",\n\t\tallowLazyActivation: false,\n\t\tparameters: variant === \"codex\" ? CODEX_PARAMS : CLAUDE_PARAMS,\n\t\tpromptSnippet: \"Ask a material question, explicitly choosing whether to wait or receive the answer later.\",\n\t\tdescription: `${opener} Set ${flag} true to pause here until the user answers (the answer returns as this tool's result, or a timeout result after 30 idle minutes); set ${flag} false to keep working while the question stays open (the answer arrives later as a user message). Use it only when the answer materially changes the work; if it returns no answers, continue with best judgment instead of asking again. Never use it for permission requests; ask those directly in your message. Unavailable to subagents.${variant === \"claude\" ? \" Users will always be able to type a free-text answer or one comment covering everything; do not add an Other option.\" : \"\"} Call this tool directly, never from inside an eval cell (a cell that waits on the user would hold the kernel).`,\n\t\tprepareArguments(args) {\n\t\t\ttoCanonical(variant, args);\n\t\t\treturn args;\n\t\t},\n\t\tasync execute(toolCallId, params, signal, _onUpdate, ctx) {\n\t\t\tlet request: QuestionRequest;\n\t\t\ttry {\n\t\t\t\trequest = toCanonical(variant, params, {\n\t\t\t\t\trequestId: toolCallId,\n\t\t\t\t\ttimeoutMs: (ctx.getAskUserSettings?.().timeoutMinutes ?? 30) * 60_000,\n\t\t\t\t});\n\t\t\t} catch (error: unknown) {\n\t\t\t\tif (!(error instanceof AskUserSchemaError)) throw error;\n\t\t\t\treturn { content: [{ type: \"text\", text: error.message }], details: { status: \"unavailable\" } };\n\t\t\t}\n\t\t\tconst unavailable: QuestionResponse = {\n\t\t\t\tstatus: \"unavailable\",\n\t\t\t\tanswers: {},\n\t\t\t\tunanswered: request.questions.map((q) => q.id),\n\t\t\t};\n\t\t\tif (state.timedOut) return result(variant, unavailable, request, REASK);\n\t\t\tif (\n\t\t\t\tstate.unavailable ||\n\t\t\t\tctx.getAskUserSettings?.().enabled === false ||\n\t\t\t\tpi.getFlag(\"no-ask-user\") === true ||\n\t\t\t\tctx.mode === \"print\" ||\n\t\t\t\tctx.mode === \"json\" ||\n\t\t\t\t!ctx.ui.question\n\t\t\t) {\n\t\t\t\tstate.unavailable = true;\n\t\t\t\tpi.setActiveTools(pi.getActiveTools().filter((name) => !Object.values(TOOL_NAMES).includes(name)));\n\t\t\t\treturn result(variant, unavailable, request);\n\t\t\t}\n\t\t\tconst completion = startQuestion(pi, ctx, request, signal, state);\n\t\t\tif (!request.waitForAnswer)\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\", text: \"Question accepted; the answer will arrive as a user message.\" }],\n\t\t\t\t\tdetails: { accepted: true, requestId: request.requestId, status: \"pending\" },\n\t\t\t\t};\n\t\t\tconst response = await completion;\n\t\t\treturn result(\n\t\t\t\tvariant,\n\t\t\t\tresponse,\n\t\t\t\trequest,\n\t\t\t\tresponse.status === \"cancelled\" && response.comment ? response.comment : undefined,\n\t\t\t);\n\t\t},\n\t\trenderCall,\n\t\trenderResult,\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tool.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ask-user/tool.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExtensionAPI, ExtensionContext, ToolDefinition } from \"../../types.ts\";\nimport { WAKE_SOURCE_STATE_EVENT, type WakeSourceStateEvent } from \"../monitor-state-event.ts\";\nimport { TOOL_NAMES } from \"./family.ts\";\nimport { formatResultDetails, formatResultText, formatUserMessage } from \"./format.ts\";\nimport {\n\tASK_USER_ASKED_EVENT,\n\tASK_USER_QUESTION_ENTRY,\n\ttype AskUserAskedEvent,\n\ttype AskUserQuestionEntry,\n\temitAskUserNotification,\n} from \"./notify.ts\";\nimport { createPendingQuestion } from \"./pending.ts\";\nimport { getPendingQuestions, type QuestionDialogOptions, registerPendingQuestion } from \"./registry.ts\";\nimport { renderCall, renderResult } from \"./render.ts\";\nimport {\n\tAskUserSchemaError,\n\ttype AskUserVariant,\n\tCLAUDE_PARAMS,\n\tCODEX_PARAMS,\n\ttype QuestionRequest,\n\ttype QuestionResponse,\n\ttoCanonical,\n} from \"./schema.ts\";\n\nexport interface AskUserState {\n\ttimedOut: boolean;\n\tunavailable: boolean;\n}\nconst REASK = \"The user did not answer the previous question this turn; continue without asking again.\";\nfunction result(\n\tvariant: AskUserVariant,\n\tresponse: QuestionResponse,\n\trequest: QuestionRequest,\n\ttext?: string,\n): Awaited<ReturnType<ToolDefinition[\"execute\"]>> {\n\treturn {\n\t\tcontent: [{ type: \"text\", text: text ?? formatResultText(variant, response, request.questions) }],\n\t\tdetails: formatResultDetails(variant, response, request.questions),\n\t};\n}\n/**\n * Deliver a settled async answer as one framed user message. The extension owns\n * this so every surface (interactive TUI, RPC, app-server) only has to RESOLVE\n * the question; a surface that delivered on its own would send it twice. It\n * steers into a running turn and follows up when idle - a follow-up always\n * triggers a turn, which is what wakes the model after a timeout. A cancelled\n * question stays silent: it was dismissed, superseded, or aborted.\n */\nfunction deliverAnswer(\n\tpi: Pick<ExtensionAPI, \"sendUserMessage\" | \"events\">,\n\tctx: ExtensionContext,\n\trequest: QuestionRequest,\n\tresponse: QuestionResponse,\n\tvariant: \"codex\" | \"claude\",\n): void {\n\tif (response.status === \"cancelled\") return;\n\tpi.sendUserMessage(formatUserMessage(response, request.requestId, request.questions), {\n\t\tdeliverAs: ctx.isIdle() ? \"followUp\" : \"steer\",\n\t});\n\tvoid emitAskUserNotification(pi, ctx, request, response, variant);\n}\nfunction emitWake(pi: Pick<ExtensionAPI, \"events\">, sessionId: string) {\n\tconst entries = getPendingQuestions(sessionId).filter((e) => !e.request.waitForAnswer);\n\tconst event: WakeSourceStateEvent = {\n\t\tsource: \"ask-user\",\n\t\tactiveCount: entries.length,\n\t\titems: entries.map((e) => ({\n\t\t\tid: e.request.requestId,\n\t\t\tdeadlineAtMs: e.pending.deadlineAtMs,\n\t\t\tdescription: e.request.questions.map((q) => q.header).join(\", \"),\n\t\t})),\n\t};\n\tpi.events.emit(WAKE_SOURCE_STATE_EVENT, event);\n}\nexport function startQuestion(\n\tpi: Pick<ExtensionAPI, \"sendUserMessage\" | \"events\" | \"appendEntry\">,\n\tctx: ExtensionContext,\n\trequest: QuestionRequest,\n\tsignal: AbortSignal | undefined,\n\tstate: AskUserState,\n\tvariant: \"codex\" | \"claude\",\n\t{ resuming = false }: { resuming?: boolean } = {},\n) {\n\tconst question = ctx.ui.question;\n\tif (!question && !resuming) throw new Error(\"Question UI is unavailable\");\n\tconst sessionId = ctx.sessionManager.getSessionId();\n\tconst existing = getPendingQuestions(sessionId).find((entry) => entry.request.requestId === request.requestId);\n\tif (existing) return existing.completion;\n\tconst orphaned = (): QuestionResponse => ({\n\t\tstatus: \"orphaned-after-restart\",\n\t\tanswers: {},\n\t\tunanswered: request.questions.map((question) => question.id),\n\t});\n\tconst controller = new AbortController();\n\tconst completion = Promise.withResolvers<QuestionResponse>();\n\tlet settled = false;\n\tlet unregister = () => {};\n\tconst finish = (response: QuestionResponse) => {\n\t\tif (settled) return;\n\t\tsettled = true;\n\t\tif (response.status === \"timed_out\") state.timedOut = true;\n\t\tunregister();\n\t\tsignal?.removeEventListener(\"abort\", abort);\n\t\tif (!request.waitForAnswer) emitWake(pi, sessionId);\n\t\tpi.events.emit(\"herdr:blocked\", { active: false, id: request.requestId });\n\t\tcompletion.resolve(response);\n\t\t// This extension owns the authoritative idle timer (pending.ts), so a UI\n\t\t// bridge that is still waiting learns the outcome only from this abort.\n\t\t// Carry the resolved status as the abort reason: a bare abort reads as a\n\t\t// dismissal, and the RPC bridge would broadcast a timeout as \"cancelled\".\n\t\tconst abortReason: QuestionResponse[\"status\"] = response.status;\n\t\tcontroller.abort(abortReason);\n\t};\n\tconst pending = createPendingQuestion({\n\t\trequest,\n\t\tnow: Date.now,\n\t\tidleTimeoutMs: request.timeoutMs,\n\t\tonTimeout: finish,\n\t});\n\tconst cancel = (message?: string) => {\n\t\tconst response = pending.cancel();\n\t\tfinish(message ? { ...response, comment: message } : response);\n\t};\n\tconst abort = () => cancel();\n\tunregister = registerPendingQuestion(sessionId, { request, pending, completion: completion.promise, cancel });\n\tpi.appendEntry<AskUserQuestionEntry>(ASK_USER_QUESTION_ENTRY, {\n\t\trequestId: request.requestId,\n\t\theaders: request.questions.map((question) => question.header),\n\t});\n\tif (!request.waitForAnswer) emitWake(pi, sessionId);\n\tpi.events.emit(ASK_USER_ASKED_EVENT, { ctx, request, variant } satisfies AskUserAskedEvent);\n\tconst first = request.questions[0];\n\tpi.events.emit(\"herdr:blocked\", {\n\t\tactive: true,\n\t\tlabel: first ? `${first.header} — ${first.question}` : \"Question\",\n\t\tid: request.requestId,\n\t});\n\tsignal?.addEventListener(\"abort\", abort, { once: true });\n\tlet draft: { answers: QuestionResponse[\"answers\"]; comment?: string } = { answers: {} };\n\tconst opts: QuestionDialogOptions = {\n\t\ttimeout: request.timeoutMs,\n\t\tsignal: controller.signal,\n\t\tdeliver: request.waitForAnswer ? \"tool-result\" : \"user-message\",\n\t\thardDeadlineAtMs: Date.now() + 7_200_000,\n\t\tgetDeadlineAtMs: () => pending.deadlineAtMs,\n\t\tonProgress: (progress) => {\n\t\t\tdraft = { ...draft, ...progress, answers: progress.answers ?? draft.answers };\n\t\t\tpending.touch(draft);\n\t\t\tif (!request.waitForAnswer) emitWake(pi, sessionId);\n\t\t},\n\t};\n\tconst accept = (response: QuestionResponse) => {\n\t\tif (settled) return;\n\t\tpending.touch({ answers: response.answers, comment: response.comment });\n\t\tif (response.status === \"timed_out\") {\n\t\t\tfinish(response);\n\t\t\tpending.timeout();\n\t\t\treturn;\n\t\t}\n\t\tif (response.status === \"answered\" || response.status === \"comment-submitted\") {\n\t\t\t// The UI owns partial submission validation; retain its response verbatim.\n\t\t\tpending.submit(response.answers, response.comment);\n\t\t\tif (pending.state === \"pending\") pending.cancel();\n\t\t} else pending.cancel(response.status);\n\t\tfinish(response);\n\t};\n\tconst fail = (error: unknown) => {\n\t\tif (settled) return;\n\t\tconst message = `Question UI failed: ${error instanceof Error ? error.message : String(error)}`;\n\t\tif (resuming) {\n\t\t\taccept({ ...orphaned(), comment: message });\n\t\t\treturn;\n\t\t}\n\t\tcancel(message);\n\t\tctx.ui.notify(message, \"error\");\n\t};\n\tif (signal?.aborted) abort();\n\telse if (!question) accept(orphaned());\n\telse {\n\t\ttry {\n\t\t\tquestion.call(ctx.ui, request, opts).then(accept, fail);\n\t\t} catch (error: unknown) {\n\t\t\tfail(error);\n\t\t}\n\t}\n\tif (!request.waitForAnswer && !resuming)\n\t\tvoid completion.promise.then((response) => deliverAnswer(pi, ctx, request, response, variant));\n\treturn completion.promise;\n}\nexport function createAskUserTool(variant: AskUserVariant, pi: ExtensionAPI, state: AskUserState): ToolDefinition {\n\tconst flag = variant === \"codex\" ? \"wait_for_answer\" : \"waitForAnswer\";\n\tconst opener =\n\t\tvariant === \"codex\"\n\t\t\t? \"Request user input for one to three short questions.\"\n\t\t\t: \"Ask the user one to four concise questions.\";\n\treturn {\n\t\tname: TOOL_NAMES[variant],\n\t\tlabel: \"Ask user\",\n\t\texposure: \"direct\",\n\t\tallowLazyActivation: false,\n\t\tparameters: variant === \"codex\" ? CODEX_PARAMS : CLAUDE_PARAMS,\n\t\tpromptSnippet: \"Ask a material question, explicitly choosing whether to wait or receive the answer later.\",\n\t\tdescription: `${opener} Set ${flag} true to pause here until the user answers (the answer returns as this tool's result, or a timeout result after 30 idle minutes); set ${flag} false to keep working while the question stays open (the answer arrives later as a user message). Use it only when the answer materially changes the work; if it returns no answers, continue with best judgment instead of asking again. Never use it for permission requests; ask those directly in your message. Unavailable to subagents.${variant === \"claude\" ? \" Users will always be able to type a free-text answer or one comment covering everything; do not add an Other option.\" : \"\"} Call this tool directly, never from inside an eval cell (a cell that waits on the user would hold the kernel).`,\n\t\tprepareArguments(args) {\n\t\t\ttoCanonical(variant, args);\n\t\t\treturn args;\n\t\t},\n\t\tasync execute(toolCallId, params, signal, _onUpdate, ctx) {\n\t\t\tlet request: QuestionRequest;\n\t\t\ttry {\n\t\t\t\trequest = toCanonical(variant, params, {\n\t\t\t\t\trequestId: toolCallId,\n\t\t\t\t\ttimeoutMs: (ctx.getAskUserSettings?.().timeoutMinutes ?? 30) * 60_000,\n\t\t\t\t});\n\t\t\t} catch (error: unknown) {\n\t\t\t\tif (!(error instanceof AskUserSchemaError)) throw error;\n\t\t\t\treturn { content: [{ type: \"text\", text: error.message }], details: { status: \"unavailable\" } };\n\t\t\t}\n\t\t\tconst unavailable: QuestionResponse = {\n\t\t\t\tstatus: \"unavailable\",\n\t\t\t\tanswers: {},\n\t\t\t\tunanswered: request.questions.map((q) => q.id),\n\t\t\t};\n\t\t\tif (state.timedOut) return result(variant, unavailable, request, REASK);\n\t\t\tif (\n\t\t\t\tstate.unavailable ||\n\t\t\t\tctx.getAskUserSettings?.().enabled === false ||\n\t\t\t\tpi.getFlag(\"no-ask-user\") === true ||\n\t\t\t\tctx.mode === \"print\" ||\n\t\t\t\tctx.mode === \"json\" ||\n\t\t\t\t!ctx.ui.question\n\t\t\t) {\n\t\t\t\tstate.unavailable = true;\n\t\t\t\tpi.setActiveTools(pi.getActiveTools().filter((name) => !Object.values(TOOL_NAMES).includes(name)));\n\t\t\t\treturn result(variant, unavailable, request);\n\t\t\t}\n\t\t\tconst completion = startQuestion(pi, ctx, request, signal, state, variant);\n\t\t\tif (!request.waitForAnswer)\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\", text: \"Question accepted; the answer will arrive as a user message.\" }],\n\t\t\t\t\tdetails: { accepted: true, requestId: request.requestId, status: \"pending\" },\n\t\t\t\t};\n\t\t\tconst response = await completion;\n\t\t\tif (response.status !== \"cancelled\") {\n\t\t\t\tvoid emitAskUserNotification(pi, ctx, request, response, variant);\n\t\t\t}\n\t\t\treturn result(\n\t\t\t\tvariant,\n\t\t\t\tresponse,\n\t\t\t\trequest,\n\t\t\t\tresponse.status === \"cancelled\" && response.comment ? response.comment : undefined,\n\t\t\t);\n\t\t},\n\t\trenderCall,\n\t\trenderResult,\n\t};\n}\n"]}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { ExtensionAPI } from "../../types.ts";
|
|
2
|
+
import { type WakeSourceStateEvent } from "../monitor-state-event.ts";
|
|
2
3
|
type GoalChannelEvents = NonNullable<ExtensionAPI["events"]>;
|
|
3
4
|
interface GoalChannelCallbacks {
|
|
4
|
-
readonly onWakeSource: (source: string, activeCount: number) => void;
|
|
5
|
+
readonly onWakeSource: (source: string, activeCount: number, event?: WakeSourceStateEvent) => void;
|
|
5
6
|
readonly onContinuationHold: (source: string, active: boolean) => void;
|
|
6
7
|
}
|
|
7
8
|
export declare function subscribeGoalChannelState(events: GoalChannelEvents, callbacks: GoalChannelCallbacks): Array<() => void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channel-state-subscriptions.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/channel-state-subscriptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"channel-state-subscriptions.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/channel-state-subscriptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAON,KAAK,oBAAoB,EACzB,MAAM,2BAA2B,CAAC;AAEnC,KAAK,iBAAiB,GAAG,WAAW,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;AAE7D,UAAU,oBAAoB;IAC7B,QAAQ,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACnG,QAAQ,CAAC,kBAAkB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;CACvE;AAED,wBAAgB,yBAAyB,CACxC,MAAM,EAAE,iBAAiB,EACzB,SAAS,EAAE,oBAAoB,GAC7B,KAAK,CAAC,MAAM,IAAI,CAAC,CAYnB"}
|
|
@@ -7,7 +7,7 @@ export function subscribeGoalChannelState(events, callbacks) {
|
|
|
7
7
|
}),
|
|
8
8
|
events.on(WAKE_SOURCE_STATE_EVENT, (data) => {
|
|
9
9
|
if (isWakeSourceStateEvent(data))
|
|
10
|
-
callbacks.onWakeSource(data.source, data.activeCount);
|
|
10
|
+
callbacks.onWakeSource(data.source, data.activeCount, data);
|
|
11
11
|
}),
|
|
12
12
|
events.on(CONTINUATION_HOLD_STATE_EVENT, (data) => {
|
|
13
13
|
if (isContinuationHoldStateEvent(data))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channel-state-subscriptions.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/channel-state-subscriptions.ts"],"names":[],"mappings":"AACA,OAAO,EACN,6BAA6B,EAC7B,4BAA4B,EAC5B,2BAA2B,EAC3B,sBAAsB,EACtB,4BAA4B,EAC5B,uBAAuB,
|
|
1
|
+
{"version":3,"file":"channel-state-subscriptions.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/channel-state-subscriptions.ts"],"names":[],"mappings":"AACA,OAAO,EACN,6BAA6B,EAC7B,4BAA4B,EAC5B,2BAA2B,EAC3B,sBAAsB,EACtB,4BAA4B,EAC5B,uBAAuB,GAEvB,MAAM,2BAA2B,CAAC;AASnC,MAAM,UAAU,yBAAyB,CACxC,MAAyB,EACzB,SAA+B;IAE/B,OAAO;QACN,MAAM,CAAC,EAAE,CAAC,4BAA4B,EAAE,CAAC,IAAI,EAAE,EAAE;YAChD,IAAI,2BAA2B,CAAC,IAAI,CAAC;gBAAE,SAAS,CAAC,YAAY,CAAC,mBAAmB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QACtG,CAAC,CAAC;QACF,MAAM,CAAC,EAAE,CAAC,uBAAuB,EAAE,CAAC,IAAI,EAAE,EAAE;YAC3C,IAAI,sBAAsB,CAAC,IAAI,CAAC;gBAAE,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QAC/F,CAAC,CAAC;QACF,MAAM,CAAC,EAAE,CAAC,6BAA6B,EAAE,CAAC,IAAI,EAAE,EAAE;YACjD,IAAI,4BAA4B,CAAC,IAAI,CAAC;gBAAE,SAAS,CAAC,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAChG,CAAC,CAAC;KACF,CAAC;AACH,CAAC","sourcesContent":["import type { ExtensionAPI } from \"../../types.ts\";\nimport {\n\tCONTINUATION_HOLD_STATE_EVENT,\n\tisContinuationHoldStateEvent,\n\tisTerminalMonitorStateEvent,\n\tisWakeSourceStateEvent,\n\tTERMINAL_MONITOR_STATE_EVENT,\n\tWAKE_SOURCE_STATE_EVENT,\n\ttype WakeSourceStateEvent,\n} from \"../monitor-state-event.ts\";\n\ntype GoalChannelEvents = NonNullable<ExtensionAPI[\"events\"]>;\n\ninterface GoalChannelCallbacks {\n\treadonly onWakeSource: (source: string, activeCount: number, event?: WakeSourceStateEvent) => void;\n\treadonly onContinuationHold: (source: string, active: boolean) => void;\n}\n\nexport function subscribeGoalChannelState(\n\tevents: GoalChannelEvents,\n\tcallbacks: GoalChannelCallbacks,\n): Array<() => void> {\n\treturn [\n\t\tevents.on(TERMINAL_MONITOR_STATE_EVENT, (data) => {\n\t\t\tif (isTerminalMonitorStateEvent(data)) callbacks.onWakeSource(\"terminal-monitors\", data.activeCount);\n\t\t}),\n\t\tevents.on(WAKE_SOURCE_STATE_EVENT, (data) => {\n\t\t\tif (isWakeSourceStateEvent(data)) callbacks.onWakeSource(data.source, data.activeCount, data);\n\t\t}),\n\t\tevents.on(CONTINUATION_HOLD_STATE_EVENT, (data) => {\n\t\t\tif (isContinuationHoldStateEvent(data)) callbacks.onContinuationHold(data.source, data.active);\n\t\t}),\n\t];\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"monitor-continuation.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/monitor-continuation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"monitor-continuation.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/monitor-continuation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAcrE,OAAO,EACN,sCAAsC,EACtC,2CAA2C,GAC3C,MAAM,iBAAiB,CAAC;AAoBzB,OAAO,KAAK,EACX,eAAe,EAIf,uBAAuB,EAEvB,kBAAkB,EAClB,MAAM,iCAAiC,CAAC;AAMzC,OAAO,KAAK,EAAE,IAAI,EAAsB,MAAM,YAAY,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAOvD,eAAO,MAAM,iCAAiC,gCAAgC,CAAC;AAC/E,eAAO,MAAM,+BAA+B,8BAA8B,CAAC;AAC3E,eAAO,MAAM,mCAAmC,kCAAkC,CAAC;AACnF,eAAO,MAAM,wBAAwB,oCAAoC,CAAC;AAE1E,qBAAa,4BAA4B;;IAiCxC,YACC,EAAE,EAAE,YAAY,EAChB,qBAAqB,GAAE,MAAM,OAAqB,EAClD,uBAAuB,GAAE,MAAM,IAAe,EAC9C,UAAU,CAAC,EAAE,cAAc,EAO3B;IAED,KAAK,CAAC,GAAG,EAAE,gBAAgB,GAAG,IAAI,CASjC;IAEK,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAwDlE;IAEK,gBAAgB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAkBxE;IAEK,oBAAoB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAcjF;IAEK,iBAAiB,IAAI,OAAO,CAAC,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC,CAyB1D;IAED,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAOhC;IAED,sGAAsG;IACtG,oBAAoB,IAAI,OAAO,CAE9B;IAED;;;;;OAKG;IACH,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAIrC;IAED,mGAAmG;IACnG,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAsBrC;IAED,6FAA6F;IAC7F,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI,CAY3D;IAED,sEAAsE;IACtE,cAAc,IAAI,IAAI,CAKrB;IAED,mGAAmG;IACnG,uBAAuB,IAAI,IAAI,CAE9B;IAED,OAAO,IAAI,IAAI,CAUd;CA2ZD"}
|