@astralyn/pi 0.87.1 → 0.87.3
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 +24 -0
- package/dist/bundle/chunks/{chunk-CDMUKIXY.js → chunk-MJ45I4SM.js} +1 -1
- package/dist/bundle/chunks/{chunk-772GXEFD.js → chunk-TYOQD6VQ.js} +97 -84
- package/dist/bundle/chunks/{virtual-modules-LQO2MG3T.js → virtual-modules-NDGCHNG7.js} +1 -1
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts +9 -0
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +158 -157
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session.d.ts +14 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +437 -434
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/background/types.d.ts +2 -0
- package/dist/core/background/types.d.ts.map +1 -1
- package/dist/core/background/types.js.map +1 -1
- package/dist/core/extensions/distribution-api.d.ts +41 -0
- package/dist/core/extensions/distribution-api.d.ts.map +1 -0
- package/dist/core/extensions/distribution-api.js +12 -0
- package/dist/core/extensions/distribution-api.js.map +1 -0
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +1 -0
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +0 -2
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +15 -45
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js +1 -11
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/extensions/virtual-modules.d.ts.map +1 -1
- package/dist/core/extensions/virtual-modules.js +2 -1
- package/dist/core/extensions/virtual-modules.js.map +1 -1
- package/dist/core/keybinding-registry.d.ts +11 -0
- package/dist/core/keybinding-registry.d.ts.map +1 -0
- package/dist/core/keybinding-registry.js +24 -0
- package/dist/core/keybinding-registry.js.map +1 -0
- package/dist/core/keybindings.d.ts +4 -64
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +2 -41
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/model-config.d.ts +70 -2
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +2 -26
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +5 -11
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +2 -2
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/shell-execution.d.ts +1 -0
- package/dist/core/tools/shell-execution.d.ts.map +1 -1
- package/dist/core/tools/shell-execution.js +21 -0
- package/dist/core/tools/shell-execution.js.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.js +114 -1
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +11 -48
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/extensions/background/actions.d.ts.map +1 -1
- package/dist/extensions/background/actions.js +107 -55
- package/dist/extensions/background/actions.js.map +1 -1
- package/dist/extensions/background/index.d.ts +2 -0
- package/dist/extensions/background/index.d.ts.map +1 -1
- package/dist/extensions/background/index.js +20 -3
- package/dist/extensions/background/index.js.map +1 -1
- package/dist/extensions/background/keybindings.d.ts +10 -0
- package/dist/extensions/background/keybindings.d.ts.map +1 -0
- package/dist/extensions/background/keybindings.js +14 -0
- package/dist/extensions/background/keybindings.js.map +1 -0
- package/dist/extensions/background/manager.d.ts +2 -0
- package/dist/extensions/background/manager.d.ts.map +1 -1
- package/dist/extensions/background/manager.js +1 -0
- package/dist/extensions/background/manager.js.map +1 -1
- package/dist/extensions/btw/controller.d.ts +1 -0
- package/dist/extensions/btw/controller.d.ts.map +1 -1
- package/dist/extensions/btw/controller.js +5 -5
- package/dist/extensions/btw/controller.js.map +1 -1
- package/dist/extensions/btw/index.js +1 -2
- package/dist/extensions/btw/index.js.map +1 -1
- package/dist/extensions/btw/keybindings.d.ts +10 -0
- package/dist/extensions/btw/keybindings.d.ts.map +1 -0
- package/dist/extensions/btw/keybindings.js +8 -0
- package/dist/extensions/btw/keybindings.js.map +1 -0
- package/dist/extensions/btw/panel.d.ts +1 -0
- package/dist/extensions/btw/panel.d.ts.map +1 -1
- package/dist/extensions/btw/panel.js +1 -0
- package/dist/extensions/btw/panel.js.map +1 -1
- package/dist/extensions/list-keybindings.d.ts +8 -0
- package/dist/extensions/list-keybindings.d.ts.map +1 -0
- package/dist/extensions/list-keybindings.js +8 -0
- package/dist/extensions/list-keybindings.js.map +1 -0
- package/dist/extensions/provider/compat-fields.d.ts.map +1 -1
- package/dist/extensions/provider/compat-fields.js +23 -3
- package/dist/extensions/provider/compat-fields.js.map +1 -1
- package/dist/extensions/provider/connection.d.ts.map +1 -1
- package/dist/extensions/provider/connection.js +1 -1
- package/dist/extensions/provider/connection.js.map +1 -1
- package/dist/extensions/provider/constants.d.ts +2 -0
- package/dist/extensions/provider/constants.d.ts.map +1 -1
- package/dist/extensions/provider/constants.js +2 -0
- package/dist/extensions/provider/constants.js.map +1 -1
- package/dist/extensions/provider/keybindings.d.ts +9 -0
- package/dist/extensions/provider/keybindings.d.ts.map +1 -0
- package/dist/extensions/provider/keybindings.js +12 -0
- package/dist/extensions/provider/keybindings.js.map +1 -0
- package/dist/extensions/provider/probe.d.ts +8 -4
- package/dist/extensions/provider/probe.d.ts.map +1 -1
- package/dist/extensions/provider/probe.js +169 -11
- package/dist/extensions/provider/probe.js.map +1 -1
- package/dist/extensions/provider/ui/builtin-data.d.ts +1 -0
- package/dist/extensions/provider/ui/builtin-data.d.ts.map +1 -1
- package/dist/extensions/provider/ui/builtin-data.js +1 -0
- package/dist/extensions/provider/ui/builtin-data.js.map +1 -1
- package/dist/extensions/provider/ui/compat.d.ts +1 -0
- package/dist/extensions/provider/ui/compat.d.ts.map +1 -1
- package/dist/extensions/provider/ui/compat.js +1 -0
- package/dist/extensions/provider/ui/compat.js.map +1 -1
- package/dist/extensions/provider/ui/dictionary.d.ts +1 -0
- package/dist/extensions/provider/ui/dictionary.d.ts.map +1 -1
- package/dist/extensions/provider/ui/dictionary.js +1 -0
- package/dist/extensions/provider/ui/dictionary.js.map +1 -1
- package/dist/extensions/provider/ui/editor.d.ts +1 -0
- package/dist/extensions/provider/ui/editor.d.ts.map +1 -1
- package/dist/extensions/provider/ui/editor.js +1 -0
- package/dist/extensions/provider/ui/editor.js.map +1 -1
- package/dist/extensions/provider/ui/fetch-models.d.ts +5 -3
- package/dist/extensions/provider/ui/fetch-models.d.ts.map +1 -1
- package/dist/extensions/provider/ui/fetch-models.js +28 -3
- package/dist/extensions/provider/ui/fetch-models.js.map +1 -1
- package/dist/extensions/provider/ui/model-fields.d.ts +1 -0
- package/dist/extensions/provider/ui/model-fields.d.ts.map +1 -1
- package/dist/extensions/provider/ui/model-fields.js +1 -0
- package/dist/extensions/provider/ui/model-fields.js.map +1 -1
- package/dist/extensions/provider/ui/model-options.d.ts +1 -0
- package/dist/extensions/provider/ui/model-options.d.ts.map +1 -1
- package/dist/extensions/provider/ui/model-options.js +1 -0
- package/dist/extensions/provider/ui/model-options.js.map +1 -1
- package/dist/extensions/provider/ui/provider-fields.d.ts +1 -0
- package/dist/extensions/provider/ui/provider-fields.d.ts.map +1 -1
- package/dist/extensions/provider/ui/provider-fields.js +1 -0
- package/dist/extensions/provider/ui/provider-fields.js.map +1 -1
- package/dist/extensions/question/dialog.d.ts +1 -0
- package/dist/extensions/question/dialog.d.ts.map +1 -1
- package/dist/extensions/question/dialog.js +1 -0
- package/dist/extensions/question/dialog.js.map +1 -1
- package/dist/extensions/question/index.d.ts.map +1 -1
- package/dist/extensions/question/index.js +3 -1
- package/dist/extensions/question/index.js.map +1 -1
- package/dist/extensions/question/keybindings.d.ts +2 -0
- package/dist/extensions/question/keybindings.d.ts.map +1 -0
- package/dist/extensions/question/keybindings.js +3 -0
- package/dist/extensions/question/keybindings.js.map +1 -0
- package/dist/extensions/question/schema.d.ts +18 -0
- package/dist/extensions/question/schema.d.ts.map +1 -1
- package/dist/extensions/question/schema.js +52 -0
- package/dist/extensions/question/schema.js.map +1 -1
- package/dist/extensions/subagent/index.d.ts.map +1 -1
- package/dist/extensions/subagent/index.js +3 -1
- package/dist/extensions/subagent/index.js.map +1 -1
- package/dist/extensions/subagent/resolve.d.ts +14 -1
- package/dist/extensions/subagent/resolve.d.ts.map +1 -1
- package/dist/extensions/subagent/resolve.js +32 -18
- package/dist/extensions/subagent/resolve.js.map +1 -1
- package/dist/extensions/subagent/runner.d.ts.map +1 -1
- package/dist/extensions/subagent/runner.js +4 -1
- package/dist/extensions/subagent/runner.js.map +1 -1
- package/dist/extensions/subagent/schema.d.ts +9 -0
- package/dist/extensions/subagent/schema.d.ts.map +1 -1
- package/dist/extensions/subagent/schema.js +30 -1
- package/dist/extensions/subagent/schema.js.map +1 -1
- package/dist/extensions/subagent/types.d.ts +2 -0
- package/dist/extensions/subagent/types.d.ts.map +1 -1
- package/dist/extensions/subagent/types.js.map +1 -1
- package/dist/extensions/todo/constants.d.ts +1 -1
- package/dist/extensions/todo/constants.d.ts.map +1 -1
- package/dist/extensions/todo/constants.js +8 -8
- package/dist/extensions/todo/constants.js.map +1 -1
- package/dist/extensions/todo/index.d.ts.map +1 -1
- package/dist/extensions/todo/index.js +1 -0
- package/dist/extensions/todo/index.js.map +1 -1
- package/dist/extensions/todo/schema.d.ts +30 -25
- package/dist/extensions/todo/schema.d.ts.map +1 -1
- package/dist/extensions/todo/schema.js +26 -20
- package/dist/extensions/todo/schema.js.map +1 -1
- package/dist/extensions/todo/state.d.ts +12 -8
- package/dist/extensions/todo/state.d.ts.map +1 -1
- package/dist/extensions/todo/state.js +255 -171
- package/dist/extensions/todo/state.js.map +1 -1
- package/dist/extensions/todo/view.d.ts +6 -2
- package/dist/extensions/todo/view.d.ts.map +1 -1
- package/dist/extensions/todo/view.js +234 -144
- package/dist/extensions/todo/view.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modes/interactive/editor-host.d.ts +43 -0
- package/dist/modes/interactive/editor-host.d.ts.map +1 -0
- package/dist/modes/interactive/editor-host.js +83 -0
- package/dist/modes/interactive/editor-host.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +1 -11
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +300 -360
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/tool-chat.d.ts +21 -0
- package/dist/modes/interactive/tool-chat.d.ts.map +1 -0
- package/dist/modes/interactive/tool-chat.js +58 -0
- package/dist/modes/interactive/tool-chat.js.map +1 -0
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +0 -2
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/utils/path-identity.d.ts +12 -0
- package/dist/utils/path-identity.d.ts.map +1 -0
- package/dist/utils/path-identity.js +63 -0
- package/dist/utils/path-identity.js.map +1 -0
- package/dist/utils/shell.d.ts +0 -1
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +0 -21
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/syntax-highlight.d.ts +2 -0
- package/dist/utils/syntax-highlight.d.ts.map +1 -1
- package/dist/utils/syntax-highlight.js +2 -0
- package/dist/utils/syntax-highlight.js.map +1 -1
- package/docs/bundled/extensions/background.md +1 -1
- package/docs/bundled/extensions/provider.md +7 -3
- package/docs/bundled/extensions/question.md +1 -0
- package/docs/bundled/extensions/subagent.md +3 -1
- package/docs/bundled/extensions/todo.md +35 -23
- package/docs/extensions.md +17 -5
- package/examples/extensions/README.md +34 -14
- package/examples/extensions/auto-commit-on-exit.ts +1 -1
- package/examples/extensions/bash-spawn-hook.ts +2 -2
- package/examples/extensions/bookmark.ts +1 -1
- package/examples/extensions/border-status-editor.ts +6 -1
- package/examples/extensions/built-in-tool-renderer.ts +2 -2
- package/examples/extensions/claude-rules.ts +1 -1
- package/examples/extensions/commands.ts +1 -1
- package/examples/extensions/confirm-destructive.ts +1 -1
- package/examples/extensions/custom-compaction.ts +2 -2
- package/examples/extensions/custom-footer.ts +1 -1
- package/examples/extensions/custom-header.ts +2 -2
- package/examples/extensions/custom-provider-anthropic/index.ts +6 -6
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +3 -3
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/dirty-repo-guard.ts +1 -1
- package/examples/extensions/doom-overlay/index.ts +1 -1
- package/examples/extensions/dynamic-resources/dynamic.json +3 -1
- package/examples/extensions/dynamic-resources/index.ts +1 -1
- package/examples/extensions/dynamic-tools.ts +1 -1
- package/examples/extensions/entry-renderer.ts +1 -1
- package/examples/extensions/event-bus.ts +1 -1
- package/examples/extensions/file-trigger.ts +1 -1
- package/examples/extensions/git-checkpoint.ts +1 -1
- package/examples/extensions/git-merge-and-resolve.ts +1 -1
- package/examples/extensions/github-issue-autocomplete.ts +1 -1
- package/examples/extensions/gondolin/index.ts +9 -7
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/handoff.ts +2 -2
- package/examples/extensions/hello.ts +1 -1
- package/examples/extensions/hidden-thinking-label.ts +1 -1
- package/examples/extensions/inline-bash.ts +1 -1
- package/examples/extensions/input-transform-streaming.ts +1 -1
- package/examples/extensions/input-transform.ts +1 -1
- package/examples/extensions/interactive-shell.ts +1 -1
- package/examples/extensions/mac-system-theme.ts +1 -1
- package/examples/extensions/message-renderer.ts +1 -1
- package/examples/extensions/minimal-mode.ts +2 -2
- package/examples/extensions/modal-editor.ts +1 -1
- package/examples/extensions/model-status.ts +1 -1
- package/examples/extensions/notify.ts +1 -1
- package/examples/extensions/overlay-qa-tests.ts +3 -3
- package/examples/extensions/overlay-test.ts +1 -1
- package/examples/extensions/permission-gate.ts +1 -1
- package/examples/extensions/pirate.ts +1 -1
- package/examples/extensions/plan-mode/index.ts +1 -1
- package/examples/extensions/preset.ts +2 -2
- package/examples/extensions/project-trust.ts +3 -3
- package/examples/extensions/prompt-customizer.ts +1 -1
- package/examples/extensions/protected-paths.ts +1 -1
- package/examples/extensions/provider-payload.ts +1 -1
- package/examples/extensions/qna.ts +2 -2
- package/examples/extensions/question.ts +1 -1
- package/examples/extensions/questionnaire.ts +1 -1
- package/examples/extensions/rainbow-editor.ts +1 -1
- package/examples/extensions/reload-runtime.ts +1 -1
- package/examples/extensions/rpc-demo.ts +1 -1
- package/examples/extensions/sandbox/index.ts +2 -2
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/send-user-message.ts +1 -1
- package/examples/extensions/session-name.ts +1 -1
- package/examples/extensions/shutdown-command.ts +1 -1
- package/examples/extensions/snake.ts +1 -1
- package/examples/extensions/space-invaders.ts +1 -1
- package/examples/extensions/ssh.ts +2 -2
- package/examples/extensions/status-line.ts +1 -1
- package/examples/extensions/structured-output.ts +1 -1
- package/examples/extensions/summarize.ts +2 -3
- package/examples/extensions/system-prompt-header.ts +1 -1
- package/examples/extensions/tic-tac-toe.ts +1 -1
- package/examples/extensions/timed-confirm.ts +1 -1
- package/examples/extensions/titlebar-spinner.ts +1 -1
- package/examples/extensions/todo.ts +1 -1
- package/examples/extensions/tool-override.ts +1 -1
- package/examples/extensions/tools.ts +2 -2
- package/examples/extensions/trigger-compact.ts +1 -1
- package/examples/extensions/truncated-tool.ts +4 -4
- package/examples/extensions/widget-placement.ts +1 -1
- package/examples/extensions/with-deps/index.ts +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/extensions/working-indicator.ts +1 -1
- package/examples/extensions/working-message-test.ts +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
|
@@ -15,6 +15,41 @@ function result(text, details) {
|
|
|
15
15
|
export function describeTaskLine(task, now = Date.now()) {
|
|
16
16
|
return `${task.id} ${task.kind} ${task.status} (${task.mode}) ${runtimeLabel(task, now)} ${task.title.slice(0, 200)}`;
|
|
17
17
|
}
|
|
18
|
+
const UNKNOWN_ID_MESSAGE = "Unknown background task ID";
|
|
19
|
+
const AMBIGUOUS_ID_MESSAGE = "Ambiguous background task ID";
|
|
20
|
+
const LOOKUP_LIST_LIMIT = 10;
|
|
21
|
+
/** Task ids a lookup prefix can match: the full id or its kind-stripped suffix. */
|
|
22
|
+
function matchesLookupPrefix(task, id) {
|
|
23
|
+
return task.id.startsWith(id) || task.id.slice(task.kind.length + 1).startsWith(id);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Rewrite the service's bare lookup failure into an actionable one: an
|
|
27
|
+
* unknown id gets the session's current tasks (active first, then recent
|
|
28
|
+
* finishes) so the next call can use a real id without a separate list call,
|
|
29
|
+
* and an ambiguous prefix gets exactly the tasks it matched. A missing id
|
|
30
|
+
* stays an error — it is likely a mistyped id of a task still running.
|
|
31
|
+
*/
|
|
32
|
+
function lookupFailure(background, id, error) {
|
|
33
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
34
|
+
const ambiguous = message.includes(AMBIGUOUS_ID_MESSAGE);
|
|
35
|
+
if (!ambiguous && !message.includes(UNKNOWN_ID_MESSAGE)) {
|
|
36
|
+
return error instanceof Error ? error : new Error(message);
|
|
37
|
+
}
|
|
38
|
+
if (ambiguous) {
|
|
39
|
+
const matches = background.list().filter((task) => matchesLookupPrefix(task, id));
|
|
40
|
+
const lines = matches.map((task) => describeTaskLine(task)).join("\n");
|
|
41
|
+
return new Error(`Ambiguous background task ID "${id}" matches ${matches.length} tasks:\n${lines}`);
|
|
42
|
+
}
|
|
43
|
+
const tasks = background.list();
|
|
44
|
+
const active = tasks.filter((task) => !isBackgroundTerminal(task.status));
|
|
45
|
+
const finished = tasks.filter((task) => isBackgroundTerminal(task.status));
|
|
46
|
+
const shown = [...active, ...finished].slice(0, LOOKUP_LIST_LIMIT);
|
|
47
|
+
if (shown.length === 0) {
|
|
48
|
+
return new Error(`No background task "${id}" in this session. No background tasks in this session.`);
|
|
49
|
+
}
|
|
50
|
+
const lines = shown.map((task) => describeTaskLine(task)).join("\n");
|
|
51
|
+
return new Error(`No background task "${id}" in this session. IDs from other sessions are not valid here.\nCurrent tasks:\n${lines}`);
|
|
52
|
+
}
|
|
18
53
|
/** Reserve space for each independent diagnostic before allowing raw output to fill the budget. */
|
|
19
54
|
function readText(header, slice) {
|
|
20
55
|
const boundedField = (text, maxBytes) => truncateHead(boundText(sanitizeBinaryOutput(text), maxBytes), { maxBytes, maxLines: 100 }).content;
|
|
@@ -29,69 +64,86 @@ function readText(header, slice) {
|
|
|
29
64
|
.join("\n");
|
|
30
65
|
}
|
|
31
66
|
export async function runRead(background, input) {
|
|
32
|
-
const mode = input.mode ?? "tail";
|
|
33
|
-
const slice = await background.read(requireTaskId(input), { mode, bytes: clampReadBytes(input.bytes) });
|
|
34
|
-
return result(readText(`[${describeTaskLine(slice.task)} · ${slice.totalBytes} bytes${slice.truncated ? " · truncated" : ""}]`, slice), {
|
|
35
|
-
action: "read",
|
|
36
|
-
taskId: slice.task.id,
|
|
37
|
-
mode,
|
|
38
|
-
sliceBytes: Buffer.byteLength(slice.text),
|
|
39
|
-
totalBytes: slice.totalBytes,
|
|
40
|
-
outputPath: slice.task.outputPath ?? "",
|
|
41
|
-
kind: slice.task.kind,
|
|
42
|
-
status: slice.task.status,
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
export async function runWait(background, input, signal) {
|
|
46
67
|
const id = requireTaskId(input);
|
|
47
|
-
const release = background.pin(id);
|
|
48
68
|
try {
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
: timedOut
|
|
57
|
-
? " · wait window expired; execution continues"
|
|
58
|
-
: "";
|
|
59
|
-
const slice = await background.read(id, {
|
|
60
|
-
bytes: BG_WAIT_DELTA_BYTES,
|
|
61
|
-
sinceBytes: clampSinceBytes(input.sinceBytes),
|
|
62
|
-
});
|
|
63
|
-
signal?.throwIfAborted();
|
|
64
|
-
return result(readText(`[${describeTaskLine(task)}${windowNote}]`, slice), {
|
|
65
|
-
action: "wait",
|
|
66
|
-
taskId: task.id,
|
|
67
|
-
...(!timedOut ? { backgroundTaskId: task.id } : {}),
|
|
68
|
-
status: task.status,
|
|
69
|
-
kind: task.kind,
|
|
70
|
-
timedOut,
|
|
71
|
-
exitCode: undefined,
|
|
72
|
-
waitedMs: Date.now() - start,
|
|
73
|
-
deltaBytes: Buffer.byteLength(slice.text),
|
|
69
|
+
const mode = input.mode ?? "tail";
|
|
70
|
+
const slice = await background.read(id, { mode, bytes: clampReadBytes(input.bytes) });
|
|
71
|
+
return result(readText(`[${describeTaskLine(slice.task)} · ${slice.totalBytes} bytes${slice.truncated ? " · truncated" : ""}]`, slice), {
|
|
72
|
+
action: "read",
|
|
73
|
+
taskId: slice.task.id,
|
|
74
|
+
mode,
|
|
75
|
+
sliceBytes: Buffer.byteLength(slice.text),
|
|
74
76
|
totalBytes: slice.totalBytes,
|
|
75
|
-
|
|
76
|
-
|
|
77
|
+
outputPath: slice.task.outputPath ?? "",
|
|
78
|
+
kind: slice.task.kind,
|
|
79
|
+
status: slice.task.status,
|
|
77
80
|
});
|
|
78
81
|
}
|
|
79
|
-
|
|
80
|
-
|
|
82
|
+
catch (error) {
|
|
83
|
+
throw lookupFailure(background, id, error);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export async function runWait(background, input, signal) {
|
|
87
|
+
const id = requireTaskId(input);
|
|
88
|
+
try {
|
|
89
|
+
const release = background.pin(id);
|
|
90
|
+
try {
|
|
91
|
+
const start = Date.now();
|
|
92
|
+
const task = await background.wait(id, clampWaitMs(input.waitMs), signal);
|
|
93
|
+
const timedOut = !isBackgroundTerminal(task.status);
|
|
94
|
+
// A closed host resolves waits early without settling anything; do not claim
|
|
95
|
+
// the execution merely outlived the wait window.
|
|
96
|
+
const windowNote = background.closed
|
|
97
|
+
? " · host closed; execution state unconfirmed"
|
|
98
|
+
: timedOut
|
|
99
|
+
? " · wait window expired; execution continues"
|
|
100
|
+
: "";
|
|
101
|
+
const slice = await background.read(id, {
|
|
102
|
+
bytes: BG_WAIT_DELTA_BYTES,
|
|
103
|
+
sinceBytes: clampSinceBytes(input.sinceBytes),
|
|
104
|
+
});
|
|
105
|
+
signal?.throwIfAborted();
|
|
106
|
+
return result(readText(`[${describeTaskLine(task)}${windowNote}]`, slice), {
|
|
107
|
+
action: "wait",
|
|
108
|
+
taskId: task.id,
|
|
109
|
+
...(!timedOut ? { backgroundTaskId: task.id } : {}),
|
|
110
|
+
status: task.status,
|
|
111
|
+
kind: task.kind,
|
|
112
|
+
timedOut,
|
|
113
|
+
exitCode: undefined,
|
|
114
|
+
waitedMs: Date.now() - start,
|
|
115
|
+
deltaBytes: Buffer.byteLength(slice.text),
|
|
116
|
+
totalBytes: slice.totalBytes,
|
|
117
|
+
deltaTruncated: slice.truncated,
|
|
118
|
+
outputPath: task.outputPath ?? "",
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
finally {
|
|
122
|
+
release();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
throw lookupFailure(background, id, error);
|
|
81
127
|
}
|
|
82
128
|
}
|
|
83
129
|
export function runKill(background, input) {
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
130
|
+
const id = requireTaskId(input);
|
|
131
|
+
try {
|
|
132
|
+
const task = background.get(id);
|
|
133
|
+
const requested = background.kill(task.id);
|
|
134
|
+
return result(requested
|
|
135
|
+
? `Cancellation requested for ${task.id}. The task or whole group is stopping; cleanup may still be in progress.`
|
|
136
|
+
: `No new cancellation requested for ${task.id} (${background.get(task.id).status}).`, {
|
|
137
|
+
action: "kill",
|
|
138
|
+
taskId: task.id,
|
|
139
|
+
command: task.command ?? task.title,
|
|
140
|
+
requested,
|
|
141
|
+
status: background.get(task.id).status,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
throw lookupFailure(background, id, error);
|
|
146
|
+
}
|
|
95
147
|
}
|
|
96
148
|
export function runList(background) {
|
|
97
149
|
// Listings cover backgrounded work only; foreground executions deliver
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../../../src/extensions/background/actions.ts"],"names":[],"mappings":"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","sourcesContent":["/** Management only: execution and delivery belong to the session Background service. */\nimport { boundText } from \"../../core/background/output.ts\";\nimport {\n\ttype BackgroundContext,\n\ttype BackgroundRead,\n\ttype BackgroundTask,\n\tisBackgroundTerminal,\n} from \"../../core/background/types.ts\";\nimport type { AgentToolResult } from \"../../core/extensions/types.ts\";\nimport { truncateHead } from \"../../core/tools/truncate.ts\";\nimport { sanitizeBinaryOutput } from \"../../utils/shell.ts\";\nimport { BG_LIST_FINISHED_SHOWN, BG_WAIT_DELTA_BYTES } from \"./constants.ts\";\nimport { type BgInput, clampReadBytes, clampSinceBytes, clampWaitMs, requireTaskId } from \"./schema.ts\";\nimport { runtimeLabel } from \"./task-view.ts\";\nimport type { BgDetails, BgKillDetails, BgListDetails, BgReadDetails, BgWaitDetails } from \"./types.ts\";\n\nexport function boundedText(text: string): string {\n\treturn truncateHead(sanitizeBinaryOutput(text), { maxBytes: 50 * 1024, maxLines: 2000 }).content;\n}\nfunction result<T extends BgDetails>(text: string, details: T): AgentToolResult<T> {\n\treturn { content: [{ type: \"text\", text: boundedText(text) }], details };\n}\nexport function describeTaskLine(task: BackgroundTask, now = Date.now()): string {\n\treturn `${task.id} ${task.kind} ${task.status} (${task.mode}) ${runtimeLabel(task, now)} ${task.title.slice(0, 200)}`;\n}\n/** Reserve space for each independent diagnostic before allowing raw output to fill the budget. */\nfunction readText(header: string, slice: BackgroundRead): string {\n\tconst boundedField = (text: string, maxBytes: number) =>\n\t\ttruncateHead(boundText(sanitizeBinaryOutput(text), maxBytes), { maxBytes, maxLines: 100 }).content;\n\treturn [\n\t\tboundedField(header, 4096),\n\t\tslice.task.error ? `Task error: ${boundedField(slice.task.error, 4096)}` : \"\",\n\t\tslice.readError ? `Output read error: ${boundedField(slice.readError, 4096)}` : \"\",\n\t\tboundedField(slice.task.outputPath ?? \"\", 8192),\n\t\tslice.text || \"(no output yet)\",\n\t]\n\t\t.filter(Boolean)\n\t\t.join(\"\\n\");\n}\nexport async function runRead(background: BackgroundContext, input: BgInput): Promise<AgentToolResult<BgReadDetails>> {\n\tconst mode = input.mode ?? \"tail\";\n\tconst slice = await background.read(requireTaskId(input), { mode, bytes: clampReadBytes(input.bytes) });\n\treturn result(\n\t\treadText(\n\t\t\t`[${describeTaskLine(slice.task)} · ${slice.totalBytes} bytes${slice.truncated ? \" · truncated\" : \"\"}]`,\n\t\t\tslice,\n\t\t),\n\t\t{\n\t\t\taction: \"read\",\n\t\t\ttaskId: slice.task.id,\n\t\t\tmode,\n\t\t\tsliceBytes: Buffer.byteLength(slice.text),\n\t\t\ttotalBytes: slice.totalBytes,\n\t\t\toutputPath: slice.task.outputPath ?? \"\",\n\t\t\tkind: slice.task.kind,\n\t\t\tstatus: slice.task.status,\n\t\t},\n\t);\n}\nexport async function runWait(\n\tbackground: BackgroundContext,\n\tinput: BgInput,\n\tsignal?: AbortSignal,\n): Promise<AgentToolResult<BgWaitDetails>> {\n\tconst id = requireTaskId(input);\n\tconst release = background.pin(id);\n\ttry {\n\t\tconst start = Date.now();\n\t\tconst task = await background.wait(id, clampWaitMs(input.waitMs), signal);\n\t\tconst timedOut = !isBackgroundTerminal(task.status);\n\t\t// A closed host resolves waits early without settling anything; do not claim\n\t\t// the execution merely outlived the wait window.\n\t\tconst windowNote = background.closed\n\t\t\t? \" · host closed; execution state unconfirmed\"\n\t\t\t: timedOut\n\t\t\t\t? \" · wait window expired; execution continues\"\n\t\t\t\t: \"\";\n\t\tconst slice = await background.read(id, {\n\t\t\tbytes: BG_WAIT_DELTA_BYTES,\n\t\t\tsinceBytes: clampSinceBytes(input.sinceBytes),\n\t\t});\n\t\tsignal?.throwIfAborted();\n\t\treturn result(readText(`[${describeTaskLine(task)}${windowNote}]`, slice), {\n\t\t\taction: \"wait\",\n\t\t\ttaskId: task.id,\n\t\t\t...(!timedOut ? { backgroundTaskId: task.id } : {}),\n\t\t\tstatus: task.status,\n\t\t\tkind: task.kind,\n\t\t\ttimedOut,\n\t\t\texitCode: undefined,\n\t\t\twaitedMs: Date.now() - start,\n\t\t\tdeltaBytes: Buffer.byteLength(slice.text),\n\t\t\ttotalBytes: slice.totalBytes,\n\t\t\tdeltaTruncated: slice.truncated,\n\t\t\toutputPath: task.outputPath ?? \"\",\n\t\t});\n\t} finally {\n\t\trelease();\n\t}\n}\nexport function runKill(background: BackgroundContext, input: BgInput): AgentToolResult<BgKillDetails> {\n\tconst task = background.get(requireTaskId(input));\n\tconst requested = background.kill(task.id);\n\treturn result(\n\t\trequested\n\t\t\t? `Cancellation requested for ${task.id}. The task or whole group is stopping; cleanup may still be in progress.`\n\t\t\t: `No new cancellation requested for ${task.id} (${background.get(task.id).status}).`,\n\t\t{\n\t\t\taction: \"kill\",\n\t\t\ttaskId: task.id,\n\t\t\tcommand: task.command ?? task.title,\n\t\t\trequested,\n\t\t\tstatus: background.get(task.id).status,\n\t\t},\n\t);\n}\nexport function runList(background: BackgroundContext): AgentToolResult<BgListDetails> {\n\t// Listings cover backgrounded work only; foreground executions deliver\n\t// inline in the transcript, so they are counted here rather than shown.\n\tconst all = background.list();\n\tconst tasks = all.filter((task) => task.mode === \"background\");\n\tconst foregroundOmitted = all.length - tasks.length;\n\tconst active = tasks.filter((task) => !isBackgroundTerminal(task.status));\n\tconst finished = tasks.filter((task) => isBackgroundTerminal(task.status));\n\tconst shown = [...active, ...finished.slice(0, BG_LIST_FINISHED_SHOWN)].slice(0, 100);\n\tconst hidden = tasks.length - shown.length;\n\tconst foregroundNote =\n\t\tforegroundOmitted > 0\n\t\t\t? `\\n${foregroundOmitted} foreground ${foregroundOmitted === 1 ? \"execution\" : \"executions\"} omitted — foreground work is delivered inline in the transcript.`\n\t\t\t: \"\";\n\treturn result(\n\t\tshown.length\n\t\t\t? `${shown.map((task) => describeTaskLine(task)).join(\"\\n\")}${hidden > 0 ? `\\n${hidden} more records not shown.` : \"\"}${foregroundNote}`\n\t\t\t: `No background tasks. Start work through bash or subagent with background: true.${foregroundNote}`,\n\t\t{\n\t\t\taction: \"list\",\n\t\t\trunning: active.length,\n\t\t\tfinished: finished.length,\n\t\t\tshown: shown.length,\n\t\t\thidden,\n\t\t\t...(foregroundOmitted > 0 ? { foregroundOmitted } : {}),\n\t\t},\n\t);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../../../src/extensions/background/actions.ts"],"names":[],"mappings":"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","sourcesContent":["/** Management only: execution and delivery belong to the session Background service. */\nimport { boundText } from \"../../core/background/output.ts\";\nimport {\n\ttype BackgroundContext,\n\ttype BackgroundRead,\n\ttype BackgroundTask,\n\tisBackgroundTerminal,\n} from \"../../core/background/types.ts\";\nimport type { AgentToolResult } from \"../../core/extensions/types.ts\";\nimport { truncateHead } from \"../../core/tools/truncate.ts\";\nimport { sanitizeBinaryOutput } from \"../../utils/shell.ts\";\nimport { BG_LIST_FINISHED_SHOWN, BG_WAIT_DELTA_BYTES } from \"./constants.ts\";\nimport { type BgInput, clampReadBytes, clampSinceBytes, clampWaitMs, requireTaskId } from \"./schema.ts\";\nimport { runtimeLabel } from \"./task-view.ts\";\nimport type { BgDetails, BgKillDetails, BgListDetails, BgReadDetails, BgWaitDetails } from \"./types.ts\";\n\nexport function boundedText(text: string): string {\n\treturn truncateHead(sanitizeBinaryOutput(text), { maxBytes: 50 * 1024, maxLines: 2000 }).content;\n}\nfunction result<T extends BgDetails>(text: string, details: T): AgentToolResult<T> {\n\treturn { content: [{ type: \"text\", text: boundedText(text) }], details };\n}\nexport function describeTaskLine(task: BackgroundTask, now = Date.now()): string {\n\treturn `${task.id} ${task.kind} ${task.status} (${task.mode}) ${runtimeLabel(task, now)} ${task.title.slice(0, 200)}`;\n}\n\nconst UNKNOWN_ID_MESSAGE = \"Unknown background task ID\";\nconst AMBIGUOUS_ID_MESSAGE = \"Ambiguous background task ID\";\nconst LOOKUP_LIST_LIMIT = 10;\n\n/** Task ids a lookup prefix can match: the full id or its kind-stripped suffix. */\nfunction matchesLookupPrefix(task: BackgroundTask, id: string): boolean {\n\treturn task.id.startsWith(id) || task.id.slice(task.kind.length + 1).startsWith(id);\n}\n\n/**\n * Rewrite the service's bare lookup failure into an actionable one: an\n * unknown id gets the session's current tasks (active first, then recent\n * finishes) so the next call can use a real id without a separate list call,\n * and an ambiguous prefix gets exactly the tasks it matched. A missing id\n * stays an error — it is likely a mistyped id of a task still running.\n */\nfunction lookupFailure(background: BackgroundContext, id: string, error: unknown): Error {\n\tconst message = error instanceof Error ? error.message : String(error);\n\tconst ambiguous = message.includes(AMBIGUOUS_ID_MESSAGE);\n\tif (!ambiguous && !message.includes(UNKNOWN_ID_MESSAGE)) {\n\t\treturn error instanceof Error ? error : new Error(message);\n\t}\n\tif (ambiguous) {\n\t\tconst matches = background.list().filter((task) => matchesLookupPrefix(task, id));\n\t\tconst lines = matches.map((task) => describeTaskLine(task)).join(\"\\n\");\n\t\treturn new Error(`Ambiguous background task ID \"${id}\" matches ${matches.length} tasks:\\n${lines}`);\n\t}\n\tconst tasks = background.list();\n\tconst active = tasks.filter((task) => !isBackgroundTerminal(task.status));\n\tconst finished = tasks.filter((task) => isBackgroundTerminal(task.status));\n\tconst shown = [...active, ...finished].slice(0, LOOKUP_LIST_LIMIT);\n\tif (shown.length === 0) {\n\t\treturn new Error(`No background task \"${id}\" in this session. No background tasks in this session.`);\n\t}\n\tconst lines = shown.map((task) => describeTaskLine(task)).join(\"\\n\");\n\treturn new Error(\n\t\t`No background task \"${id}\" in this session. IDs from other sessions are not valid here.\\nCurrent tasks:\\n${lines}`,\n\t);\n}\n/** Reserve space for each independent diagnostic before allowing raw output to fill the budget. */\nfunction readText(header: string, slice: BackgroundRead): string {\n\tconst boundedField = (text: string, maxBytes: number) =>\n\t\ttruncateHead(boundText(sanitizeBinaryOutput(text), maxBytes), { maxBytes, maxLines: 100 }).content;\n\treturn [\n\t\tboundedField(header, 4096),\n\t\tslice.task.error ? `Task error: ${boundedField(slice.task.error, 4096)}` : \"\",\n\t\tslice.readError ? `Output read error: ${boundedField(slice.readError, 4096)}` : \"\",\n\t\tboundedField(slice.task.outputPath ?? \"\", 8192),\n\t\tslice.text || \"(no output yet)\",\n\t]\n\t\t.filter(Boolean)\n\t\t.join(\"\\n\");\n}\nexport async function runRead(background: BackgroundContext, input: BgInput): Promise<AgentToolResult<BgReadDetails>> {\n\tconst id = requireTaskId(input);\n\ttry {\n\t\tconst mode = input.mode ?? \"tail\";\n\t\tconst slice = await background.read(id, { mode, bytes: clampReadBytes(input.bytes) });\n\t\treturn result(\n\t\t\treadText(\n\t\t\t\t`[${describeTaskLine(slice.task)} · ${slice.totalBytes} bytes${slice.truncated ? \" · truncated\" : \"\"}]`,\n\t\t\t\tslice,\n\t\t\t),\n\t\t\t{\n\t\t\t\taction: \"read\",\n\t\t\t\ttaskId: slice.task.id,\n\t\t\t\tmode,\n\t\t\t\tsliceBytes: Buffer.byteLength(slice.text),\n\t\t\t\ttotalBytes: slice.totalBytes,\n\t\t\t\toutputPath: slice.task.outputPath ?? \"\",\n\t\t\t\tkind: slice.task.kind,\n\t\t\t\tstatus: slice.task.status,\n\t\t\t},\n\t\t);\n\t} catch (error) {\n\t\tthrow lookupFailure(background, id, error);\n\t}\n}\nexport async function runWait(\n\tbackground: BackgroundContext,\n\tinput: BgInput,\n\tsignal?: AbortSignal,\n): Promise<AgentToolResult<BgWaitDetails>> {\n\tconst id = requireTaskId(input);\n\ttry {\n\t\tconst release = background.pin(id);\n\t\ttry {\n\t\t\tconst start = Date.now();\n\t\t\tconst task = await background.wait(id, clampWaitMs(input.waitMs), signal);\n\t\t\tconst timedOut = !isBackgroundTerminal(task.status);\n\t\t\t// A closed host resolves waits early without settling anything; do not claim\n\t\t\t// the execution merely outlived the wait window.\n\t\t\tconst windowNote = background.closed\n\t\t\t\t? \" · host closed; execution state unconfirmed\"\n\t\t\t\t: timedOut\n\t\t\t\t\t? \" · wait window expired; execution continues\"\n\t\t\t\t\t: \"\";\n\t\t\tconst slice = await background.read(id, {\n\t\t\t\tbytes: BG_WAIT_DELTA_BYTES,\n\t\t\t\tsinceBytes: clampSinceBytes(input.sinceBytes),\n\t\t\t});\n\t\t\tsignal?.throwIfAborted();\n\t\t\treturn result(readText(`[${describeTaskLine(task)}${windowNote}]`, slice), {\n\t\t\t\taction: \"wait\",\n\t\t\t\ttaskId: task.id,\n\t\t\t\t...(!timedOut ? { backgroundTaskId: task.id } : {}),\n\t\t\t\tstatus: task.status,\n\t\t\t\tkind: task.kind,\n\t\t\t\ttimedOut,\n\t\t\t\texitCode: undefined,\n\t\t\t\twaitedMs: Date.now() - start,\n\t\t\t\tdeltaBytes: Buffer.byteLength(slice.text),\n\t\t\t\ttotalBytes: slice.totalBytes,\n\t\t\t\tdeltaTruncated: slice.truncated,\n\t\t\t\toutputPath: task.outputPath ?? \"\",\n\t\t\t});\n\t\t} finally {\n\t\t\trelease();\n\t\t}\n\t} catch (error) {\n\t\tthrow lookupFailure(background, id, error);\n\t}\n}\nexport function runKill(background: BackgroundContext, input: BgInput): AgentToolResult<BgKillDetails> {\n\tconst id = requireTaskId(input);\n\ttry {\n\t\tconst task = background.get(id);\n\t\tconst requested = background.kill(task.id);\n\t\treturn result(\n\t\t\trequested\n\t\t\t\t? `Cancellation requested for ${task.id}. The task or whole group is stopping; cleanup may still be in progress.`\n\t\t\t\t: `No new cancellation requested for ${task.id} (${background.get(task.id).status}).`,\n\t\t\t{\n\t\t\t\taction: \"kill\",\n\t\t\t\ttaskId: task.id,\n\t\t\t\tcommand: task.command ?? task.title,\n\t\t\t\trequested,\n\t\t\t\tstatus: background.get(task.id).status,\n\t\t\t},\n\t\t);\n\t} catch (error) {\n\t\tthrow lookupFailure(background, id, error);\n\t}\n}\nexport function runList(background: BackgroundContext): AgentToolResult<BgListDetails> {\n\t// Listings cover backgrounded work only; foreground executions deliver\n\t// inline in the transcript, so they are counted here rather than shown.\n\tconst all = background.list();\n\tconst tasks = all.filter((task) => task.mode === \"background\");\n\tconst foregroundOmitted = all.length - tasks.length;\n\tconst active = tasks.filter((task) => !isBackgroundTerminal(task.status));\n\tconst finished = tasks.filter((task) => isBackgroundTerminal(task.status));\n\tconst shown = [...active, ...finished.slice(0, BG_LIST_FINISHED_SHOWN)].slice(0, 100);\n\tconst hidden = tasks.length - shown.length;\n\tconst foregroundNote =\n\t\tforegroundOmitted > 0\n\t\t\t? `\\n${foregroundOmitted} foreground ${foregroundOmitted === 1 ? \"execution\" : \"executions\"} omitted — foreground work is delivered inline in the transcript.`\n\t\t\t: \"\";\n\treturn result(\n\t\tshown.length\n\t\t\t? `${shown.map((task) => describeTaskLine(task)).join(\"\\n\")}${hidden > 0 ? `\\n${hidden} more records not shown.` : \"\"}${foregroundNote}`\n\t\t\t: `No background tasks. Start work through bash or subagent with background: true.${foregroundNote}`,\n\t\t{\n\t\t\taction: \"list\",\n\t\t\trunning: active.length,\n\t\t\tfinished: finished.length,\n\t\t\tshown: shown.length,\n\t\t\thidden,\n\t\t\t...(foregroundOmitted > 0 ? { foregroundOmitted } : {}),\n\t\t},\n\t);\n}\n"]}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/** bg is an observer/controller of the public session-owned Background capability. */
|
|
2
|
+
import "./keybindings.ts";
|
|
1
3
|
import type { ExtensionAPI } from "../../core/extensions/types.ts";
|
|
2
4
|
export declare function createBackgroundExtension(): (pi: ExtensionAPI) => void;
|
|
3
5
|
declare const _default: (pi: ExtensionAPI) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/extensions/background/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/extensions/background/index.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,OAAO,kBAAkB,CAAC;AAG1B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AASnE,wBAAgB,yBAAyB,IAAI,CAAC,EAAE,EAAE,YAAY,KAAK,IAAI,CAyGtE;6BAzGiD,YAAY,KAAK,IAAI;AA0GvE,wBAA2C"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
/** bg is an observer/controller of the public session-owned Background capability. */
|
|
2
|
+
import "./keybindings.js";
|
|
3
|
+
import { getKeybindings } from "@earendil-works/pi-tui";
|
|
2
4
|
import { isBackgroundTerminal } from "../../core/background/types.js";
|
|
3
5
|
import { boundedText, describeTaskLine, runKill, runList, runRead, runWait } from "./actions.js";
|
|
4
6
|
import { renderBackgroundCompletion } from "./completion-render.js";
|
|
@@ -9,9 +11,11 @@ import { BG_PROMPT_GUIDELINES, BG_PROMPT_SNIPPET, BG_TOOL_DESCRIPTION, bgSchema
|
|
|
9
11
|
export function createBackgroundExtension() {
|
|
10
12
|
return (pi) => {
|
|
11
13
|
let unsubscribe;
|
|
14
|
+
let unsubscribeDetachKey;
|
|
12
15
|
let closeMenu;
|
|
13
16
|
pi.on("session_start", (_event, ctx) => {
|
|
14
17
|
unsubscribe?.();
|
|
18
|
+
unsubscribeDetachKey?.();
|
|
15
19
|
const update = () => {
|
|
16
20
|
// The status counts backgrounded work only; foreground executions
|
|
17
21
|
// are already visible as ordinary tool rows in the transcript.
|
|
@@ -20,11 +24,24 @@ export function createBackgroundExtension() {
|
|
|
20
24
|
ctx.ui.setStatus("background", tasks.length ? `bg ${running} active · ${tasks.length - running} finished` : undefined);
|
|
21
25
|
};
|
|
22
26
|
unsubscribe = ctx.background.subscribe(update);
|
|
27
|
+
unsubscribeDetachKey = ctx.ui.onTerminalInput((data) => {
|
|
28
|
+
if (!getKeybindings().matches(data, "app.backgroundTasks.detach"))
|
|
29
|
+
return undefined;
|
|
30
|
+
const count = ctx.background.detachForeground();
|
|
31
|
+
// Nothing can move: let the key fall through to editor bindings instead of
|
|
32
|
+
// spending it on a "nothing happened" status line.
|
|
33
|
+
if (count === 0)
|
|
34
|
+
return undefined;
|
|
35
|
+
ctx.ui.notify(`Moved ${count} execution${count === 1 ? "" : "s"} to the background. Use /bg to manage tasks.`);
|
|
36
|
+
return { consume: true };
|
|
37
|
+
});
|
|
23
38
|
update();
|
|
24
39
|
});
|
|
25
40
|
pi.on("session_shutdown", (_event, ctx) => {
|
|
26
41
|
unsubscribe?.();
|
|
27
42
|
unsubscribe = undefined;
|
|
43
|
+
unsubscribeDetachKey?.();
|
|
44
|
+
unsubscribeDetachKey = undefined;
|
|
28
45
|
closeMenu?.();
|
|
29
46
|
closeMenu = undefined;
|
|
30
47
|
ctx.ui.setStatus("background", undefined);
|
|
@@ -36,6 +53,7 @@ export function createBackgroundExtension() {
|
|
|
36
53
|
promptSnippet: BG_PROMPT_SNIPPET,
|
|
37
54
|
promptGuidelines: BG_PROMPT_GUIDELINES,
|
|
38
55
|
parameters: bgSchema,
|
|
56
|
+
constrainedSampling: { type: "json_schema", strict: "prefer" },
|
|
39
57
|
async execute(_id, params, signal, _onUpdate, ctx) {
|
|
40
58
|
try {
|
|
41
59
|
switch (params.action) {
|
|
@@ -50,10 +68,9 @@ export function createBackgroundExtension() {
|
|
|
50
68
|
}
|
|
51
69
|
}
|
|
52
70
|
catch (error) {
|
|
71
|
+
// Lookup failures already carry the current task list from actions.ts.
|
|
53
72
|
const message = error instanceof Error ? error.message : String(error);
|
|
54
|
-
|
|
55
|
-
const hint = message.includes("background task ID") ? " Use action list to find the execution id." : "";
|
|
56
|
-
throw new Error(boundedText(`${message}${hint}`));
|
|
73
|
+
throw new Error(boundedText(message));
|
|
57
74
|
}
|
|
58
75
|
},
|
|
59
76
|
renderCall: renderBgCall,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/extensions/background/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/extensions/background/index.ts"],"names":[],"mappings":"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","sourcesContent":["/** bg is an observer/controller of the public session-owned Background capability. */\nimport \"./keybindings.ts\";\nimport { getKeybindings } from \"@earendil-works/pi-tui\";\nimport { isBackgroundTerminal } from \"../../core/background/types.ts\";\nimport type { ExtensionAPI } from \"../../core/extensions/types.ts\";\nimport { boundedText, describeTaskLine, runKill, runList, runRead, runWait } from \"./actions.ts\";\nimport { renderBackgroundCompletion } from \"./completion-render.ts\";\nimport { BG_COMPLETION_TYPE, BG_NOTIFICATION_TYPE } from \"./constants.ts\";\nimport { BackgroundTasksMenu } from \"./manager.ts\";\nimport { type BgRenderState, renderBackgroundNotification, renderBgCall, renderBgResult } from \"./render.ts\";\nimport { BG_PROMPT_GUIDELINES, BG_PROMPT_SNIPPET, BG_TOOL_DESCRIPTION, bgSchema } from \"./schema.ts\";\nimport type { BgDetails, BgNotificationDetails } from \"./types.ts\";\n\nexport function createBackgroundExtension(): (pi: ExtensionAPI) => void {\n\treturn (pi) => {\n\t\tlet unsubscribe: (() => void) | undefined;\n\t\tlet unsubscribeDetachKey: (() => void) | undefined;\n\t\tlet closeMenu: (() => void) | undefined;\n\t\tpi.on(\"session_start\", (_event, ctx) => {\n\t\t\tunsubscribe?.();\n\t\t\tunsubscribeDetachKey?.();\n\t\t\tconst update = () => {\n\t\t\t\t// The status counts backgrounded work only; foreground executions\n\t\t\t\t// are already visible as ordinary tool rows in the transcript.\n\t\t\t\tconst tasks = ctx.background.list().filter((task) => task.mode === \"background\");\n\t\t\t\tconst running = tasks.filter((task) => !isBackgroundTerminal(task.status)).length;\n\t\t\t\tctx.ui.setStatus(\n\t\t\t\t\t\"background\",\n\t\t\t\t\ttasks.length ? `bg ${running} active · ${tasks.length - running} finished` : undefined,\n\t\t\t\t);\n\t\t\t};\n\t\t\tunsubscribe = ctx.background.subscribe(update);\n\t\t\tunsubscribeDetachKey = ctx.ui.onTerminalInput((data) => {\n\t\t\t\tif (!getKeybindings().matches(data, \"app.backgroundTasks.detach\")) return undefined;\n\t\t\t\tconst count = ctx.background.detachForeground();\n\t\t\t\t// Nothing can move: let the key fall through to editor bindings instead of\n\t\t\t\t// spending it on a \"nothing happened\" status line.\n\t\t\t\tif (count === 0) return undefined;\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\t`Moved ${count} execution${count === 1 ? \"\" : \"s\"} to the background. Use /bg to manage tasks.`,\n\t\t\t\t);\n\t\t\t\treturn { consume: true };\n\t\t\t});\n\t\t\tupdate();\n\t\t});\n\t\tpi.on(\"session_shutdown\", (_event, ctx) => {\n\t\t\tunsubscribe?.();\n\t\t\tunsubscribe = undefined;\n\t\t\tunsubscribeDetachKey?.();\n\t\t\tunsubscribeDetachKey = undefined;\n\t\t\tcloseMenu?.();\n\t\t\tcloseMenu = undefined;\n\t\t\tctx.ui.setStatus(\"background\", undefined);\n\t\t});\n\t\tpi.registerTool<typeof bgSchema, BgDetails, BgRenderState>({\n\t\t\tname: \"bg\",\n\t\t\tlabel: \"bg\",\n\t\t\tdescription: BG_TOOL_DESCRIPTION,\n\t\t\tpromptSnippet: BG_PROMPT_SNIPPET,\n\t\t\tpromptGuidelines: BG_PROMPT_GUIDELINES,\n\t\t\tparameters: bgSchema,\n\t\t\tconstrainedSampling: { type: \"json_schema\", strict: \"prefer\" },\n\t\t\tasync execute(_id, params, signal, _onUpdate, ctx) {\n\t\t\t\ttry {\n\t\t\t\t\tswitch (params.action) {\n\t\t\t\t\t\tcase \"read\":\n\t\t\t\t\t\t\treturn await runRead(ctx.background, params);\n\t\t\t\t\t\tcase \"wait\":\n\t\t\t\t\t\t\treturn await runWait(ctx.background, params, signal);\n\t\t\t\t\t\tcase \"kill\":\n\t\t\t\t\t\t\treturn runKill(ctx.background, params);\n\t\t\t\t\t\tcase \"list\":\n\t\t\t\t\t\t\treturn runList(ctx.background);\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// Lookup failures already carry the current task list from actions.ts.\n\t\t\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\t\t\tthrow new Error(boundedText(message));\n\t\t\t\t}\n\t\t\t},\n\t\t\trenderCall: renderBgCall,\n\t\t\trenderResult: renderBgResult,\n\t\t});\n\t\t// Stored legacy create results and notification details remain renderable.\n\t\tpi.registerMessageRenderer<BgNotificationDetails>(BG_NOTIFICATION_TYPE, renderBackgroundNotification);\n\t\tpi.registerMessageRenderer(BG_COMPLETION_TYPE, renderBackgroundCompletion);\n\t\tpi.registerCommand(\"bg\", {\n\t\t\tdescription: \"View and manage Bash tasks and Subagent groups\",\n\t\t\thandler: async (_args, ctx) => {\n\t\t\t\tif (ctx.mode !== \"tui\") {\n\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\tboundedText(\n\t\t\t\t\t\t\tctx.background\n\t\t\t\t\t\t\t\t.list()\n\t\t\t\t\t\t\t\t.filter((task) => task.mode === \"background\")\n\t\t\t\t\t\t\t\t.slice(0, 10)\n\t\t\t\t\t\t\t\t.map((task) => describeTaskLine(task))\n\t\t\t\t\t\t\t\t.join(\"\\n\"),\n\t\t\t\t\t\t) || \"No background tasks.\",\n\t\t\t\t\t\t\"info\",\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tcloseMenu?.();\n\t\t\t\tawait ctx.ui.custom<void>(\n\t\t\t\t\t(tui, theme, keybindings, done) => {\n\t\t\t\t\t\tconst close = () => {\n\t\t\t\t\t\t\tif (closeMenu === close) closeMenu = undefined;\n\t\t\t\t\t\t\tdone();\n\t\t\t\t\t\t};\n\t\t\t\t\t\tcloseMenu = close;\n\t\t\t\t\t\treturn new BackgroundTasksMenu({ tui, theme, keybindings, host: ctx.background, onClose: close });\n\t\t\t\t\t},\n\t\t\t\t\t{ overlay: true, overlayOptions: { anchor: \"center\", width: \"100%\", maxHeight: \"100%\" } },\n\t\t\t\t);\n\t\t\t},\n\t\t});\n\t};\n}\nexport default createBackgroundExtension();\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
declare module "../../core/keybindings.ts" {
|
|
2
|
+
interface AppKeybindings {
|
|
3
|
+
"app.backgroundTasks.detach": true;
|
|
4
|
+
"app.backgroundTasks.focusList": true;
|
|
5
|
+
"app.backgroundTasks.focusPreview": true;
|
|
6
|
+
"app.backgroundTasks.kill": true;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=keybindings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keybindings.d.ts","sourceRoot":"","sources":["../../../src/extensions/background/keybindings.ts"],"names":[],"mappings":"AAGA,OAAO,QAAQ,2BAA2B,CAAC;IAC1C,UAAU,cAAc;QACvB,4BAA4B,EAAE,IAAI,CAAC;QACnC,+BAA+B,EAAE,IAAI,CAAC;QACtC,kCAAkC,EAAE,IAAI,CAAC;QACzC,0BAA0B,EAAE,IAAI,CAAC;KACjC;CACD"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { TUI_KEYBINDINGS } from "@earendil-works/pi-tui";
|
|
2
|
+
import { registerKeybindings } from "../../core/keybinding-registry.js";
|
|
3
|
+
registerKeybindings({
|
|
4
|
+
"app.backgroundTasks.detach": {
|
|
5
|
+
defaultKeys: "ctrl+b",
|
|
6
|
+
description: "Move foreground Bash and Subagent executions to the background",
|
|
7
|
+
},
|
|
8
|
+
"app.backgroundTasks.focusList": { defaultKeys: "left", description: "Focus the background task list" },
|
|
9
|
+
"app.backgroundTasks.focusPreview": { defaultKeys: "right", description: "Focus the background task preview" },
|
|
10
|
+
"app.backgroundTasks.kill": { defaultKeys: "k", description: "Kill selected background task" },
|
|
11
|
+
// Detach takes ctrl+b, which the editor otherwise binds as a second cursor-left key.
|
|
12
|
+
"tui.editor.cursorLeft": { ...TUI_KEYBINDINGS["tui.editor.cursorLeft"], defaultKeys: "left" },
|
|
13
|
+
});
|
|
14
|
+
//# sourceMappingURL=keybindings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keybindings.js","sourceRoot":"","sources":["../../../src/extensions/background/keybindings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAWxE,mBAAmB,CAAC;IACnB,4BAA4B,EAAE;QAC7B,WAAW,EAAE,QAAQ;QACrB,WAAW,EAAE,gEAAgE;KAC7E;IACD,+BAA+B,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,gCAAgC,EAAE;IACvG,kCAAkC,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,mCAAmC,EAAE;IAC9G,0BAA0B,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,EAAE,+BAA+B,EAAE;IAC9F,qFAAqF;IACrF,uBAAuB,EAAE,EAAE,GAAG,eAAe,CAAC,uBAAuB,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE;CAC7F,CAAC,CAAC","sourcesContent":["import { TUI_KEYBINDINGS } from \"@earendil-works/pi-tui\";\nimport { registerKeybindings } from \"../../core/keybinding-registry.ts\";\n\ndeclare module \"../../core/keybindings.ts\" {\n\tinterface AppKeybindings {\n\t\t\"app.backgroundTasks.detach\": true;\n\t\t\"app.backgroundTasks.focusList\": true;\n\t\t\"app.backgroundTasks.focusPreview\": true;\n\t\t\"app.backgroundTasks.kill\": true;\n\t}\n}\n\nregisterKeybindings({\n\t\"app.backgroundTasks.detach\": {\n\t\tdefaultKeys: \"ctrl+b\",\n\t\tdescription: \"Move foreground Bash and Subagent executions to the background\",\n\t},\n\t\"app.backgroundTasks.focusList\": { defaultKeys: \"left\", description: \"Focus the background task list\" },\n\t\"app.backgroundTasks.focusPreview\": { defaultKeys: \"right\", description: \"Focus the background task preview\" },\n\t\"app.backgroundTasks.kill\": { defaultKeys: \"k\", description: \"Kill selected background task\" },\n\t// Detach takes ctrl+b, which the editor otherwise binds as a second cursor-left key.\n\t\"tui.editor.cursorLeft\": { ...TUI_KEYBINDINGS[\"tui.editor.cursorLeft\"], defaultKeys: \"left\" },\n});\n"]}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/** Inline observer: selecting or closing a view never changes execution ownership. */
|
|
2
|
+
import "./keybindings.ts";
|
|
1
3
|
import { type Component, type Focusable } from "@earendil-works/pi-tui";
|
|
2
4
|
import { type BackgroundContext } from "../../core/background/types.ts";
|
|
3
5
|
import type { KeybindingsManager } from "../../core/keybindings.ts";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../src/extensions/background/manager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../src/extensions/background/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/** Inline observer: selecting or closing a view never changes execution ownership. */
|
|
2
|
+
import "./keybindings.js";
|
|
2
3
|
import { homedir } from "node:os";
|
|
3
4
|
import { Markdown, stripTerminalSequences, truncateToWidth, visibleWidth, wrapTextWithAnsi, } from "@earendil-works/pi-tui";
|
|
4
5
|
import { isBackgroundTerminal, isForegroundShellTask, } from "../../core/background/types.js";
|