@astralyn/pi 1.4.2 → 1.4.4
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 +18 -0
- package/dist/bundle/chunks/{chunk-FGPSYHTQ.js → chunk-SBVVM3NV.js} +117 -117
- package/dist/bundle/chunks/{chunk-HXKY52DF.js → chunk-VGSZTBVJ.js} +1 -1
- package/dist/bundle/chunks/{virtual-modules-5NSVVTKO.js → virtual-modules-ETYFHSUG.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/core/agent-session.d.ts +15 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +1 -8
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/extensions/distribution-api.d.ts +1 -1
- package/dist/core/extensions/distribution-api.d.ts.map +1 -1
- package/dist/core/extensions/distribution-api.js.map +1 -1
- package/dist/core/extensions/index.d.ts +2 -2
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +4 -2
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +14 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/keybinding-registry.d.ts +16 -1
- package/dist/core/keybinding-registry.d.ts.map +1 -1
- package/dist/core/keybinding-registry.js +20 -0
- package/dist/core/keybinding-registry.js.map +1 -1
- package/dist/core/keybindings-schema.d.ts.map +1 -1
- package/dist/core/keybindings-schema.js +2 -1
- package/dist/core/keybindings-schema.js.map +1 -1
- package/dist/core/keybindings.d.ts +4 -106
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +0 -13
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +0 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/tasks/format.d.ts.map +1 -1
- package/dist/core/tasks/format.js +10 -4
- package/dist/core/tasks/format.js.map +1 -1
- package/dist/core/tasks/limits.d.ts +5 -0
- package/dist/core/tasks/limits.d.ts.map +1 -0
- package/dist/core/tasks/limits.js +5 -0
- package/dist/core/tasks/limits.js.map +1 -0
- package/dist/core/tasks/runtime.d.ts +1 -0
- package/dist/core/tasks/runtime.d.ts.map +1 -1
- package/dist/core/tasks/runtime.js +7 -3
- package/dist/core/tasks/runtime.js.map +1 -1
- package/dist/core/tasks/session.d.ts +1 -1
- package/dist/core/tasks/session.d.ts.map +1 -1
- package/dist/core/tasks/session.js +10 -2
- package/dist/core/tasks/session.js.map +1 -1
- package/dist/core/tasks/types.d.ts +13 -0
- package/dist/core/tasks/types.d.ts.map +1 -1
- package/dist/core/tasks/types.js.map +1 -1
- package/dist/core/tools/bash.d.ts +98 -9
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +308 -11
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/index.d.ts +5 -4
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +3 -11
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/powershell.d.ts +2 -1
- package/dist/core/tools/powershell.d.ts.map +1 -1
- package/dist/core/tools/powershell.js +2 -1
- package/dist/core/tools/powershell.js.map +1 -1
- package/dist/core/tools/renderers/bash.d.ts +1 -1
- package/dist/core/tools/renderers/bash.d.ts.map +1 -1
- package/dist/core/tools/renderers/bash.js.map +1 -1
- package/dist/core/tools/renderers/index.d.ts.map +1 -1
- package/dist/core/tools/renderers/index.js +7 -5
- package/dist/core/tools/renderers/index.js.map +1 -1
- package/dist/core/tools/shell-execution.d.ts +2 -2
- package/dist/core/tools/shell-execution.d.ts.map +1 -1
- package/dist/core/tools/shell-execution.js +0 -21
- package/dist/core/tools/shell-execution.js.map +1 -1
- package/dist/core/tools/shell-operations.d.ts +12 -0
- package/dist/core/tools/shell-operations.d.ts.map +1 -0
- package/dist/core/tools/shell-operations.js +38 -0
- package/dist/core/tools/shell-operations.js.map +1 -0
- package/dist/core/tools/shell-tool.d.ts +8 -64
- package/dist/core/tools/shell-tool.d.ts.map +1 -1
- package/dist/core/tools/shell-tool.js +27 -125
- package/dist/core/tools/shell-tool.js.map +1 -1
- package/dist/extensions/index.d.ts +1 -0
- package/dist/extensions/index.d.ts.map +1 -1
- package/dist/extensions/index.js +5 -0
- package/dist/extensions/index.js.map +1 -1
- package/dist/extensions/keybindings.d.ts +6 -0
- package/dist/extensions/keybindings.d.ts.map +1 -0
- package/dist/extensions/keybindings.js +6 -0
- package/dist/extensions/keybindings.js.map +1 -0
- package/dist/extensions/provider/store.d.ts +2 -0
- package/dist/extensions/provider/store.d.ts.map +1 -1
- package/dist/extensions/provider/store.js +4 -0
- package/dist/extensions/provider/store.js.map +1 -1
- package/dist/extensions/provider/ui/editor.d.ts +7 -9
- package/dist/extensions/provider/ui/editor.d.ts.map +1 -1
- package/dist/extensions/provider/ui/editor.js +103 -48
- package/dist/extensions/provider/ui/editor.js.map +1 -1
- package/dist/extensions/provider/ui/provider-list.d.ts.map +1 -1
- package/dist/extensions/provider/ui/provider-list.js +13 -19
- package/dist/extensions/provider/ui/provider-list.js.map +1 -1
- package/dist/extensions/run-summary/format.d.ts +2 -0
- package/dist/extensions/run-summary/format.d.ts.map +1 -0
- package/dist/extensions/run-summary/format.js +11 -0
- package/dist/extensions/run-summary/format.js.map +1 -0
- package/dist/extensions/run-summary/index.d.ts +4 -0
- package/dist/extensions/run-summary/index.d.ts.map +1 -0
- package/dist/extensions/run-summary/index.js +48 -0
- package/dist/extensions/run-summary/index.js.map +1 -0
- package/dist/extensions/run-summary/record.d.ts +11 -0
- package/dist/extensions/run-summary/record.d.ts.map +1 -0
- package/dist/extensions/run-summary/record.js +29 -0
- package/dist/extensions/run-summary/record.js.map +1 -0
- package/dist/extensions/tasks/index.d.ts +5 -0
- package/dist/extensions/tasks/index.d.ts.map +1 -0
- package/dist/extensions/tasks/index.js +42 -0
- package/dist/extensions/tasks/index.js.map +1 -0
- package/dist/extensions/tasks/keybindings.d.ts +19 -0
- package/dist/extensions/tasks/keybindings.d.ts.map +1 -0
- package/dist/extensions/tasks/keybindings.js +30 -0
- package/dist/extensions/tasks/keybindings.js.map +1 -0
- package/dist/{core/tools/tasks → extensions/tasks/tool}/actions.d.ts +2 -2
- package/dist/extensions/tasks/tool/actions.d.ts.map +1 -0
- package/dist/{core/tools/tasks → extensions/tasks/tool}/actions.js +4 -4
- package/dist/extensions/tasks/tool/actions.js.map +1 -0
- package/dist/{core/tools/tasks → extensions/tasks/tool}/constants.d.ts +1 -3
- package/dist/extensions/tasks/tool/constants.d.ts.map +1 -0
- package/dist/{core/tools/tasks → extensions/tasks/tool}/constants.js +1 -3
- package/dist/extensions/tasks/tool/constants.js.map +1 -0
- package/dist/extensions/tasks/tool/schema.d.ts.map +1 -0
- package/dist/{core/tools/tasks → extensions/tasks/tool}/schema.js +5 -4
- package/dist/extensions/tasks/tool/schema.js.map +1 -0
- package/dist/{core/tools/tasks → extensions/tasks/tool}/types.d.ts +1 -1
- package/dist/extensions/tasks/tool/types.d.ts.map +1 -0
- package/dist/extensions/tasks/tool/types.js.map +1 -0
- package/dist/extensions/tasks/tool.d.ts +6 -0
- package/dist/extensions/tasks/tool.d.ts.map +1 -0
- package/dist/{core/tools/tasks.js → extensions/tasks/tool.js} +6 -10
- package/dist/extensions/tasks/tool.js.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/completion-render.d.ts +1 -1
- package/dist/extensions/tasks/ui/completion-render.d.ts.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/completion-render.js +2 -2
- package/dist/extensions/tasks/ui/completion-render.js.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/index.d.ts +1 -1
- package/dist/extensions/tasks/ui/index.d.ts.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/index.js +4 -4
- package/dist/extensions/tasks/ui/index.js.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/inspector.d.ts +1 -1
- package/dist/extensions/tasks/ui/inspector.d.ts.map +1 -0
- package/dist/extensions/tasks/ui/inspector.js.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/layout.d.ts +1 -1
- package/dist/extensions/tasks/ui/layout.d.ts.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/layout.js +1 -1
- package/dist/extensions/tasks/ui/layout.js.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/list.d.ts +1 -1
- package/dist/extensions/tasks/ui/list.d.ts.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/list.js +1 -1
- package/dist/extensions/tasks/ui/list.js.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/manager.d.ts +2 -1
- package/dist/extensions/tasks/ui/manager.d.ts.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/manager.js +2 -1
- package/dist/extensions/tasks/ui/manager.js.map +1 -0
- package/dist/extensions/tasks/ui/model.d.ts.map +1 -0
- package/dist/extensions/tasks/ui/model.js.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/render.d.ts +3 -3
- package/dist/extensions/tasks/ui/render.d.ts.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/render.js +2 -2
- package/dist/extensions/tasks/ui/render.js.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/task-view.d.ts +1 -1
- package/dist/extensions/tasks/ui/task-view.d.ts.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/task-view.js +1 -1
- package/dist/extensions/tasks/ui/task-view.js.map +1 -0
- package/dist/extensions/tasks/ui/text.d.ts.map +1 -0
- package/dist/extensions/tasks/ui/text.js.map +1 -0
- package/dist/extensions/tasks/ui/tree.d.ts +7 -0
- package/dist/extensions/tasks/ui/tree.d.ts.map +1 -0
- package/dist/{modes/interactive/tasks/host-hooks.js → extensions/tasks/ui/tree.js} +1 -18
- package/dist/extensions/tasks/ui/tree.js.map +1 -0
- package/dist/extensions/tasks/ui/viewport.d.ts.map +1 -0
- package/dist/extensions/tasks/ui/viewport.js.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/views.d.ts +1 -1
- package/dist/extensions/tasks/ui/views.d.ts.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/views.js +1 -1
- package/dist/extensions/tasks/ui/views.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +3 -2
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +65 -18
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js +1 -3
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +16 -4
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +73 -33
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +3 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/docs/bundled/README.md +2 -4
- package/docs/bundled/extensions/provider.md +9 -7
- package/docs/bundled/extensions/run-summary.md +17 -0
- package/docs/bundled/tasks.md +3 -3
- package/docs/docs.json +4 -0
- package/docs/extensions.md +10 -3
- package/docs/settings.md +1 -1
- package/docs/tui.md +13 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/schemas/keybindings.schema.json +84 -52
- package/dist/core/tools/tasks/actions.d.ts.map +0 -1
- package/dist/core/tools/tasks/actions.js.map +0 -1
- package/dist/core/tools/tasks/constants.d.ts.map +0 -1
- package/dist/core/tools/tasks/constants.js.map +0 -1
- package/dist/core/tools/tasks/schema.d.ts.map +0 -1
- package/dist/core/tools/tasks/schema.js.map +0 -1
- package/dist/core/tools/tasks/types.d.ts.map +0 -1
- package/dist/core/tools/tasks/types.js.map +0 -1
- package/dist/core/tools/tasks.d.ts +0 -14
- package/dist/core/tools/tasks.d.ts.map +0 -1
- package/dist/core/tools/tasks.js.map +0 -1
- package/dist/modes/interactive/tasks/completion-render.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/completion-render.js.map +0 -1
- package/dist/modes/interactive/tasks/host-hooks.d.ts +0 -14
- package/dist/modes/interactive/tasks/host-hooks.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/host-hooks.js.map +0 -1
- package/dist/modes/interactive/tasks/index.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/index.js.map +0 -1
- package/dist/modes/interactive/tasks/inspector.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/inspector.js.map +0 -1
- package/dist/modes/interactive/tasks/layout.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/layout.js.map +0 -1
- package/dist/modes/interactive/tasks/list.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/list.js.map +0 -1
- package/dist/modes/interactive/tasks/manager.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/manager.js.map +0 -1
- package/dist/modes/interactive/tasks/model.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/model.js.map +0 -1
- package/dist/modes/interactive/tasks/render.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/render.js.map +0 -1
- package/dist/modes/interactive/tasks/task-view.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/task-view.js.map +0 -1
- package/dist/modes/interactive/tasks/text.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/text.js.map +0 -1
- package/dist/modes/interactive/tasks/viewport.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/viewport.js.map +0 -1
- package/dist/modes/interactive/tasks/views.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/views.js.map +0 -1
- /package/dist/{core/tools/tasks → extensions/tasks/tool}/schema.d.ts +0 -0
- /package/dist/{core/tools/tasks → extensions/tasks/tool}/types.js +0 -0
- /package/dist/{modes/interactive/tasks → extensions/tasks/ui}/inspector.js +0 -0
- /package/dist/{modes/interactive/tasks → extensions/tasks/ui}/model.d.ts +0 -0
- /package/dist/{modes/interactive/tasks → extensions/tasks/ui}/model.js +0 -0
- /package/dist/{modes/interactive/tasks → extensions/tasks/ui}/text.d.ts +0 -0
- /package/dist/{modes/interactive/tasks → extensions/tasks/ui}/text.js +0 -0
- /package/dist/{modes/interactive/tasks → extensions/tasks/ui}/viewport.d.ts +0 -0
- /package/dist/{modes/interactive/tasks → extensions/tasks/ui}/viewport.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider-list.js","sourceRoot":"","sources":["../../../../src/extensions/provider/ui/provider-list.ts"],"names":[],"mappings":"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","sourcesContent":["/** Searchable provider list and new-provider id entry. */\n\nimport { type Component, type Focusable, fuzzyFilter, type TUI, truncateToWidth } from \"@earendil-works/pi-tui\";\nimport type { KeybindingsManager } from \"../../../core/keybindings.ts\";\nimport { DynamicBorder } from \"../../../modes/interactive/components/dynamic-border.ts\";\nimport { keyHint, rawKeyHint } from \"../../../modes/interactive/components/keybinding-hints.ts\";\nimport type { Theme } from \"../../../modes/interactive/theme/theme.ts\";\nimport { plural } from \"../constants.ts\";\nimport type { ModelsJsonStore } from \"../store.ts\";\nimport { renderInfoLine, renderKeyValueLine, renderPlainLine, ValueEditor, windowLines } from \"./value-row.ts\";\n\n/** Fixed list-area height: the screen frame matches the provider editor's. */\nconst LIST_ROWS = 12;\nexport type ProviderListResult = { kind: \"open\"; providerId: string } | { kind: \"close\" };\n\nexport class ProviderListScreen implements Component, Focusable {\n\tprivate readonly input: ValueEditor;\n\tprivate readonly store: ModelsJsonStore;\n\tprivate readonly tui: TUI;\n\tprivate readonly theme: Theme;\n\tprivate readonly keybindings: KeybindingsManager;\n\tprivate readonly done: (result: ProviderListResult) => void;\n\tprivate mode: \"list\" | \"newProvider\" = \"list\";\n\tprivate query = \"\";\n\tprivate index = 0;\n\tprivate error: string | undefined;\n\tprivate active = false;\n\n\tconstructor(\n\t\ttui: TUI,\n\t\ttheme: Theme,\n\t\tkeybindings: KeybindingsManager,\n\t\tdone: (result: ProviderListResult) => void,\n\t\tstore: ModelsJsonStore,\n\t) {\n\t\tthis.tui = tui;\n\t\tthis.theme = theme;\n\t\tthis.keybindings = keybindings;\n\t\tthis.done = done;\n\t\tthis.store = store;\n\t\tthis.input = new ValueEditor({ onCommit: () => this.confirm(), onCancel: () => this.cancel() });\n\t}\n\n\tget focused(): boolean {\n\t\treturn this.active;\n\t}\n\tset focused(value: boolean) {\n\t\tthis.active = value;\n\t\tthis.input.focused = value;\n\t}\n\tinvalidate(): void {}\n\n\tprivate filtered(): string[] {\n\t\tconst ids = this.store.getProviderIds();\n\t\treturn this.query.trim() ? fuzzyFilter(ids, this.query, (id) => id) : ids;\n\t}\n\n\trender(width: number): string[] {\n\t\tconst theme = this.theme;\n\t\tconst border = new DynamicBorder((text) => theme.fg(\"border\", text)).render(width)[0] ?? \"\";\n\t\tconst lines = [\n\t\t\tborder,\n\t\t\ttruncateToWidth(theme.fg(\"accent\", theme.bold(\" /provider — models.json providers\")), width),\n\t\t\tborder,\n\t\t\trenderKeyValueLine(theme, {\n\t\t\t\tkeyLabel: this.mode === \"list\" ? \"Search\" : \"Provider id\",\n\t\t\t\tactive: false,\n\t\t\t\tpaneFocused: this.active,\n\t\t\t\tediting: this.input,\n\t\t\t\twidth,\n\t\t\t}),\n\t\t\t\"\",\n\t\t];\n\t\t// The list area is a fixed window: overlong lists scroll with a (n/N)\n\t\t// indicator (the /model selector convention) instead of resizing.\n\t\tconst area: string[] = [];\n\t\tif (this.mode === \"list\") {\n\t\t\tconst entries = this.filtered();\n\t\t\tconst total = entries.length + 1;\n\t\t\tthis.index = Math.min(this.index, total - 1);\n\t\t\tconst rows: string[] = [];\n\t\t\tfor (let row = 0; row < total; row++) {\n\t\t\t\tconst id = entries[row - 1];\n\t\t\t\tconst provider = id === undefined ? undefined : this.store.getProvider(id);\n\t\t\t\tconst note =\n\t\t\t\t\tid === undefined\n\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t: provider\n\t\t\t\t\t\t\t? [\n\t\t\t\t\t\t\t\t\t`${String(provider.models?.length ?? 0)} ${plural(provider.models?.length ?? 0, \"model\")}`,\n\t\t\t\t\t\t\t\t\tprovider.api,\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t.filter(Boolean)\n\t\t\t\t\t\t\t\t\t.join(\" · \")\n\t\t\t\t\t\t\t: \"pending deletion\";\n\t\t\t\trows.push(\n\t\t\t\t\trenderPlainLine(theme, row === 0 ? \"+ Add Provider\" : id!, {\n\t\t\t\t\t\tactive: row === this.index,\n\t\t\t\t\t\tpaneFocused: this.active,\n\t\t\t\t\t\tnote,\n\t\t\t\t\t\twidth,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (entries.length === 0)\n\t\t\t\trows.push(renderInfoLine(theme, this.query ? \"No matching providers.\" : \"No providers yet.\", width));\n\t\t\tarea.push(...windowLines(theme, rows, LIST_ROWS, { cursor: this.index }));\n\t\t} else if (this.error) {\n\t\t\tarea.push(truncateToWidth(theme.fg(\"error\", this.error), width));\n\t\t}\n\t\twhile (area.length < LIST_ROWS) area.push(\"\");\n\t\tconst hints =\n\t\t\tthis.mode === \"newProvider\"\n\t\t\t\t? [keyHint(\"tui.input.submit\", \"create\"), keyHint(\"tui.select.cancel\", \"cancel\")]\n\t\t\t\t: [\n\t\t\t\t\t\trawKeyHint(\"type\", \"filter\"),\n\t\t\t\t\t\trawKeyHint(\"↑↓\", \"move\"),\n\t\t\t\t\t\tkeyHint(\"tui.select.confirm\", \"open\"),\n\t\t\t\t\t\tkeyHint(\"tui.select.cancel\", \"close\"),\n\t\t\t\t\t];\n\t\treturn [...lines, ...area, border, truncateToWidth(hints.join(\" \"), width), border];\n\t}\n\n\thandleInput(data: string): void {\n\t\tconst kb = this.keybindings;\n\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\tthis.cancel();\n\t\t\treturn;\n\t\t}\n\t\tif (this.mode === \"list\") {\n\t\t\tconst total = this.filtered().length + 1;\n\t\t\tif (kb.matches(data, \"tui.select.up\")) this.index = (this.index + total - 1) % total;\n\t\t\telse if (kb.matches(data, \"tui.select.down\")) this.index = (this.index + 1) % total;\n\t\t\telse if (kb.matches(data, \"tui.select.confirm\")) {\n\t\t\t\tthis.confirm();\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\tconst previous = this.query;\n\t\t\t\tthis.input.handleInput(data);\n\t\t\t\tthis.query = this.input.value;\n\t\t\t\tif (this.query !== previous) this.index = this.query && this.filtered().length > 0 ? 1 : 0;\n\t\t\t}\n\t\t} else this.input.handleInput(data);\n\t\tthis.tui.requestRender();\n\t}\n\n\tprivate confirm(): void {\n\t\tif (this.mode === \"newProvider\") {\n\t\t\tconst id = this.input.value.trim();\n\t\t\tif (!id) this.error = \"Provider id must be non-empty.\";\n\t\t\telse if (this.store.getProviderIds().includes(id)) this.error = \"This provider id already exists.\";\n\t\t\telse {\n\t\t\t\tthis.store.ensureProviderView(id);\n\t\t\t\tthis.done({ kind: \"open\", providerId: id });\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else if (this.index === 0) {\n\t\t\tthis.mode = \"newProvider\";\n\t\t\tthis.error = undefined;\n\t\t\t// A fruitless search becomes the new id — type once, create once.\n\t\t\tthis.input.reset(this.query);\n\t\t} else {\n\t\t\tconst id = this.filtered()[this.index - 1];\n\t\t\tif (id) this.done({ kind: \"open\", providerId: id });\n\t\t}\n\t\tthis.tui.requestRender();\n\t}\n\n\tprivate cancel(): void {\n\t\tif (this.mode === \"list\") {\n\t\t\tthis.done({ kind: \"close\" });\n\t\t\treturn;\n\t\t}\n\t\tthis.mode = \"list\";\n\t\tthis.error = undefined;\n\t\tthis.input.reset(this.query);\n\t\tthis.tui.requestRender();\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"provider-list.js","sourceRoot":"","sources":["../../../../src/extensions/provider/ui/provider-list.ts"],"names":[],"mappings":"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","sourcesContent":["/** Searchable provider list and new-provider id entry. */\n\nimport { type Component, type Focusable, fuzzyFilter, type TUI, truncateToWidth } from \"@earendil-works/pi-tui\";\nimport type { KeybindingsManager } from \"../../../core/keybindings.ts\";\nimport { DynamicBorder } from \"../../../modes/interactive/components/dynamic-border.ts\";\nimport { keyHint, rawKeyHint } from \"../../../modes/interactive/components/keybinding-hints.ts\";\nimport type { Theme } from \"../../../modes/interactive/theme/theme.ts\";\nimport type { ModelsJsonStore } from \"../store.ts\";\nimport { renderInfoLine, renderKeyValueLine, renderPlainLine, ValueEditor, windowLines } from \"./value-row.ts\";\n\n/** Fixed list-area height: the screen frame matches the provider editor's. */\nconst LIST_ROWS = 12;\nexport type ProviderListResult = { kind: \"open\"; providerId: string } | { kind: \"close\" };\n\nexport class ProviderListScreen implements Component, Focusable {\n\tprivate readonly input: ValueEditor;\n\tprivate readonly store: ModelsJsonStore;\n\tprivate readonly tui: TUI;\n\tprivate readonly theme: Theme;\n\tprivate readonly keybindings: KeybindingsManager;\n\tprivate readonly done: (result: ProviderListResult) => void;\n\tprivate mode: \"list\" | \"newProvider\" = \"list\";\n\tprivate query = \"\";\n\tprivate index = 0;\n\tprivate error: string | undefined;\n\tprivate active = false;\n\n\tconstructor(\n\t\ttui: TUI,\n\t\ttheme: Theme,\n\t\tkeybindings: KeybindingsManager,\n\t\tdone: (result: ProviderListResult) => void,\n\t\tstore: ModelsJsonStore,\n\t) {\n\t\tthis.tui = tui;\n\t\tthis.theme = theme;\n\t\tthis.keybindings = keybindings;\n\t\tthis.done = done;\n\t\tthis.store = store;\n\t\tthis.input = new ValueEditor({ onCommit: () => this.confirm(), onCancel: () => this.cancel() });\n\t}\n\n\tget focused(): boolean {\n\t\treturn this.active;\n\t}\n\tset focused(value: boolean) {\n\t\tthis.active = value;\n\t\tthis.input.focused = value;\n\t}\n\tinvalidate(): void {}\n\n\tprivate filtered(): string[] {\n\t\tconst ids = this.store.getProviderIds();\n\t\treturn this.query.trim() ? fuzzyFilter(ids, this.query, (id) => id) : ids;\n\t}\n\n\trender(width: number): string[] {\n\t\tconst theme = this.theme;\n\t\tconst border = new DynamicBorder((text) => theme.fg(\"border\", text)).render(width)[0] ?? \"\";\n\t\tconst title = this.mode === \"list\" ? \" Providers\" : \" New provider\";\n\t\tconst lines = [\n\t\t\tborder,\n\t\t\ttruncateToWidth(theme.fg(\"accent\", theme.bold(title)), width),\n\t\t\tborder,\n\t\t\trenderKeyValueLine(theme, {\n\t\t\t\tkeyLabel: this.mode === \"list\" ? \"Search\" : \"Provider id\",\n\t\t\t\tactive: false,\n\t\t\t\tpaneFocused: this.active,\n\t\t\t\tediting: this.input,\n\t\t\t\twidth,\n\t\t\t}),\n\t\t\t\"\",\n\t\t];\n\t\t// The list area is a fixed window: overlong lists scroll with a (n/N)\n\t\t// indicator (the /model selector convention) instead of resizing.\n\t\tconst area: string[] = [];\n\t\tif (this.mode === \"list\") {\n\t\t\tconst entries = this.filtered();\n\t\t\tconst total = entries.length + 1;\n\t\t\tthis.index = Math.min(this.index, total - 1);\n\t\t\tconst rows: string[] = [];\n\t\t\tfor (let row = 0; row < total; row++) {\n\t\t\t\tconst id = entries[row - 1];\n\t\t\t\trows.push(\n\t\t\t\t\trenderPlainLine(theme, row === 0 ? \"+ Add provider\" : id!, {\n\t\t\t\t\t\tactive: row === this.index,\n\t\t\t\t\t\tpaneFocused: this.active,\n\t\t\t\t\t\twidth,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (entries.length === 0) {\n\t\t\t\tconst query = this.query.trim();\n\t\t\t\trows.push(\n\t\t\t\t\trenderInfoLine(theme, query ? `No providers match “${query}”.` : \"No providers configured.\", width),\n\t\t\t\t);\n\t\t\t\trows.push(\n\t\t\t\t\trenderInfoLine(\n\t\t\t\t\t\ttheme,\n\t\t\t\t\t\tquery ? `Enter will create provider “${query}”.` : \"Enter starts a new provider.\",\n\t\t\t\t\t\twidth,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\tarea.push(...windowLines(theme, rows, LIST_ROWS, { cursor: this.index }));\n\t\t} else {\n\t\t\tconst id = this.input.value.trim();\n\t\t\tarea.push(\n\t\t\t\trenderInfoLine(\n\t\t\t\t\ttheme,\n\t\t\t\t\tid ? `This becomes the providers.${id} key in models.json.` : \"Choose a unique provider id.\",\n\t\t\t\t\twidth,\n\t\t\t\t),\n\t\t\t);\n\t\t\tif (this.error) area.push(truncateToWidth(theme.fg(\"error\", this.error), width));\n\t\t}\n\t\twhile (area.length < LIST_ROWS) area.push(\"\");\n\t\tconst hints =\n\t\t\tthis.mode === \"newProvider\"\n\t\t\t\t? [keyHint(\"tui.input.submit\", \"create\"), keyHint(\"tui.select.cancel\", \"cancel\")]\n\t\t\t\t: [\n\t\t\t\t\t\trawKeyHint(\"type\", \"filter\"),\n\t\t\t\t\t\trawKeyHint(\"↑↓\", \"move\"),\n\t\t\t\t\t\tkeyHint(\"tui.select.confirm\", \"open\"),\n\t\t\t\t\t\tkeyHint(\"tui.select.cancel\", \"close\"),\n\t\t\t\t\t];\n\t\treturn [...lines, ...area, border, truncateToWidth(hints.join(\" \"), width), border];\n\t}\n\n\thandleInput(data: string): void {\n\t\tconst kb = this.keybindings;\n\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\tthis.cancel();\n\t\t\treturn;\n\t\t}\n\t\tif (this.mode === \"list\") {\n\t\t\tconst total = this.filtered().length + 1;\n\t\t\tif (kb.matches(data, \"tui.select.up\")) this.index = (this.index + total - 1) % total;\n\t\t\telse if (kb.matches(data, \"tui.select.down\")) this.index = (this.index + 1) % total;\n\t\t\telse if (kb.matches(data, \"tui.select.confirm\")) {\n\t\t\t\tthis.confirm();\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\tconst previous = this.query;\n\t\t\t\tthis.input.handleInput(data);\n\t\t\t\tthis.query = this.input.value;\n\t\t\t\tif (this.query !== previous) this.index = this.query && this.filtered().length > 0 ? 1 : 0;\n\t\t\t}\n\t\t} else this.input.handleInput(data);\n\t\tthis.tui.requestRender();\n\t}\n\n\tprivate confirm(): void {\n\t\tif (this.mode === \"newProvider\") {\n\t\t\tconst id = this.input.value.trim();\n\t\t\tif (!id) this.error = \"Provider id must be non-empty.\";\n\t\t\telse if (this.store.getProviderIds().includes(id)) this.error = \"This provider id already exists.\";\n\t\t\telse {\n\t\t\t\tthis.store.ensureProviderView(id);\n\t\t\t\tthis.done({ kind: \"open\", providerId: id });\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else if (this.index === 0) {\n\t\t\tthis.mode = \"newProvider\";\n\t\t\tthis.error = undefined;\n\t\t\t// A fruitless search becomes the new id — type once, create once.\n\t\t\tthis.input.reset(this.query);\n\t\t} else {\n\t\t\tconst id = this.filtered()[this.index - 1];\n\t\t\tif (id) this.done({ kind: \"open\", providerId: id });\n\t\t}\n\t\tthis.tui.requestRender();\n\t}\n\n\tprivate cancel(): void {\n\t\tif (this.mode === \"list\") {\n\t\t\tthis.done({ kind: \"close\" });\n\t\t\treturn;\n\t\t}\n\t\tthis.mode = \"list\";\n\t\tthis.error = undefined;\n\t\tthis.input.reset(this.query);\n\t\tthis.tui.requestRender();\n\t}\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/extensions/run-summary/format.ts"],"names":[],"mappings":"AAMA,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,GAAG,SAAkB,GAAG,MAAM,CAKpH"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { formatDuration } from "../../core/tasks/format.js";
|
|
2
|
+
function pad(value) {
|
|
3
|
+
return String(value).padStart(2, "0");
|
|
4
|
+
}
|
|
5
|
+
export function formatRunSummary(startedAt, finishedAt, outcome = "done") {
|
|
6
|
+
const done = new Date(finishedAt);
|
|
7
|
+
const timestamp = `${done.getFullYear()}/${pad(done.getMonth() + 1)}/${pad(done.getDate())} ${pad(done.getHours())}:${pad(done.getMinutes())}`;
|
|
8
|
+
const label = outcome === "done" ? "Done" : "Stopped";
|
|
9
|
+
return `Worked for ${formatDuration(finishedAt - startedAt)} · ${label} ${timestamp}`;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/extensions/run-summary/format.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,SAAS,GAAG,CAAC,KAAa;IACzB,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,SAAiB,EAAE,UAAkB,EAAE,UAA8B,MAAM;IAC3G,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC;IAClC,MAAM,SAAS,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC;IAC/I,MAAM,KAAK,GAAG,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IACtD,OAAO,cAAc,cAAc,CAAC,UAAU,GAAG,SAAS,CAAC,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;AACvF,CAAC","sourcesContent":["import { formatDuration } from \"../../core/tasks/format.ts\";\n\nfunction pad(value: number): string {\n\treturn String(value).padStart(2, \"0\");\n}\n\nexport function formatRunSummary(startedAt: number, finishedAt: number, outcome: \"done\" | \"stopped\" = \"done\"): string {\n\tconst done = new Date(finishedAt);\n\tconst timestamp = `${done.getFullYear()}/${pad(done.getMonth() + 1)}/${pad(done.getDate())} ${pad(done.getHours())}:${pad(done.getMinutes())}`;\n\tconst label = outcome === \"done\" ? \"Done\" : \"Stopped\";\n\treturn `Worked for ${formatDuration(finishedAt - startedAt)} · ${label} ${timestamp}`;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/extensions/run-summary/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,gCAAgC,CAAC;AAiBrF,yFAAyF;AACzF,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAoCzD"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { formatRunSummary } from "./format.js";
|
|
2
|
+
import { RUN_SUMMARY_ENTRY_TYPE, readRunSummaryRecord } from "./record.js";
|
|
3
|
+
function restoreRunSummaries(ctx) {
|
|
4
|
+
if (ctx.mode !== "tui")
|
|
5
|
+
return;
|
|
6
|
+
for (const entry of ctx.sessionManager.getBranch()) {
|
|
7
|
+
const record = readRunSummaryRecord(entry);
|
|
8
|
+
if (!record)
|
|
9
|
+
continue;
|
|
10
|
+
ctx.ui.addTranscriptNote(`run-summary:${record.afterEntryId}`, formatRunSummary(record.startedAt, record.finishedAt, record.outcome), { afterEntryId: record.afterEntryId });
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/** Persist run boundaries and project them as timing notes after each continuous run. */
|
|
14
|
+
export default function runSummary(pi) {
|
|
15
|
+
let startedAt;
|
|
16
|
+
pi.on("session_start", (_event, ctx) => {
|
|
17
|
+
startedAt = undefined;
|
|
18
|
+
restoreRunSummaries(ctx);
|
|
19
|
+
});
|
|
20
|
+
pi.on("session_tree", (_event, ctx) => {
|
|
21
|
+
restoreRunSummaries(ctx);
|
|
22
|
+
});
|
|
23
|
+
pi.on("before_agent_start", () => {
|
|
24
|
+
startedAt = Date.now();
|
|
25
|
+
});
|
|
26
|
+
pi.on("agent_settled", (event, ctx) => {
|
|
27
|
+
const runStartedAt = startedAt;
|
|
28
|
+
startedAt = undefined;
|
|
29
|
+
if (runStartedAt === undefined || ctx.mode !== "tui")
|
|
30
|
+
return;
|
|
31
|
+
const afterEntryId = ctx.sessionManager.getLeafId();
|
|
32
|
+
if (!afterEntryId)
|
|
33
|
+
return;
|
|
34
|
+
const finishedAt = Date.now();
|
|
35
|
+
const outcome = event.aborted ? "stopped" : "done";
|
|
36
|
+
ctx.ui.addTranscriptNote(`run-summary:${afterEntryId}`, formatRunSummary(runStartedAt, finishedAt, outcome), {
|
|
37
|
+
afterEntryId,
|
|
38
|
+
});
|
|
39
|
+
pi.appendEntry(RUN_SUMMARY_ENTRY_TYPE, {
|
|
40
|
+
version: 1,
|
|
41
|
+
afterEntryId,
|
|
42
|
+
startedAt: runStartedAt,
|
|
43
|
+
finishedAt,
|
|
44
|
+
outcome,
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/extensions/run-summary/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAE3E,SAAS,mBAAmB,CAAC,GAAqB;IACjD,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK;QAAE,OAAO;IAC/B,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,cAAc,CAAC,SAAS,EAAE,EAAE,CAAC;QACpD,MAAM,MAAM,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,GAAG,CAAC,EAAE,CAAC,iBAAiB,CACvB,eAAe,MAAM,CAAC,YAAY,EAAE,EACpC,gBAAgB,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,EACrE,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,CACrC,CAAC;IACH,CAAC;AACF,CAAC;AAED,yFAAyF;AACzF,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EAAgB;IAClD,IAAI,SAA6B,CAAC;IAElC,EAAE,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;QACtC,SAAS,GAAG,SAAS,CAAC;QACtB,mBAAmB,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;QACrC,mBAAmB,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAChC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACrC,MAAM,YAAY,GAAG,SAAS,CAAC;QAC/B,SAAS,GAAG,SAAS,CAAC;QACtB,IAAI,YAAY,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK;YAAE,OAAO;QAC7D,MAAM,YAAY,GAAG,GAAG,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC;QACpD,IAAI,CAAC,YAAY;YAAE,OAAO;QAE1B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;QACnD,GAAG,CAAC,EAAE,CAAC,iBAAiB,CAAC,eAAe,YAAY,EAAE,EAAE,gBAAgB,CAAC,YAAY,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE;YAC5G,YAAY;SACZ,CAAC,CAAC;QACH,EAAE,CAAC,WAAW,CAAC,sBAAsB,EAAE;YACtC,OAAO,EAAE,CAAC;YACV,YAAY;YACZ,SAAS,EAAE,YAAY;YACvB,UAAU;YACV,OAAO;SACP,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { ExtensionAPI, ExtensionContext } from \"../../core/extensions/types.ts\";\nimport { formatRunSummary } from \"./format.ts\";\nimport { RUN_SUMMARY_ENTRY_TYPE, readRunSummaryRecord } from \"./record.ts\";\n\nfunction restoreRunSummaries(ctx: ExtensionContext): void {\n\tif (ctx.mode !== \"tui\") return;\n\tfor (const entry of ctx.sessionManager.getBranch()) {\n\t\tconst record = readRunSummaryRecord(entry);\n\t\tif (!record) continue;\n\t\tctx.ui.addTranscriptNote(\n\t\t\t`run-summary:${record.afterEntryId}`,\n\t\t\tformatRunSummary(record.startedAt, record.finishedAt, record.outcome),\n\t\t\t{ afterEntryId: record.afterEntryId },\n\t\t);\n\t}\n}\n\n/** Persist run boundaries and project them as timing notes after each continuous run. */\nexport default function runSummary(pi: ExtensionAPI): void {\n\tlet startedAt: number | undefined;\n\n\tpi.on(\"session_start\", (_event, ctx) => {\n\t\tstartedAt = undefined;\n\t\trestoreRunSummaries(ctx);\n\t});\n\n\tpi.on(\"session_tree\", (_event, ctx) => {\n\t\trestoreRunSummaries(ctx);\n\t});\n\n\tpi.on(\"before_agent_start\", () => {\n\t\tstartedAt = Date.now();\n\t});\n\n\tpi.on(\"agent_settled\", (event, ctx) => {\n\t\tconst runStartedAt = startedAt;\n\t\tstartedAt = undefined;\n\t\tif (runStartedAt === undefined || ctx.mode !== \"tui\") return;\n\t\tconst afterEntryId = ctx.sessionManager.getLeafId();\n\t\tif (!afterEntryId) return;\n\n\t\tconst finishedAt = Date.now();\n\t\tconst outcome = event.aborted ? \"stopped\" : \"done\";\n\t\tctx.ui.addTranscriptNote(`run-summary:${afterEntryId}`, formatRunSummary(runStartedAt, finishedAt, outcome), {\n\t\t\tafterEntryId,\n\t\t});\n\t\tpi.appendEntry(RUN_SUMMARY_ENTRY_TYPE, {\n\t\t\tversion: 1,\n\t\t\tafterEntryId,\n\t\t\tstartedAt: runStartedAt,\n\t\t\tfinishedAt,\n\t\t\toutcome,\n\t\t});\n\t});\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SessionEntry } from "../../core/session-manager.ts";
|
|
2
|
+
export declare const RUN_SUMMARY_ENTRY_TYPE = "run-summary";
|
|
3
|
+
export interface RunSummaryRecord {
|
|
4
|
+
version: 1;
|
|
5
|
+
afterEntryId: string;
|
|
6
|
+
startedAt: number;
|
|
7
|
+
finishedAt: number;
|
|
8
|
+
outcome: "done" | "stopped";
|
|
9
|
+
}
|
|
10
|
+
export declare function readRunSummaryRecord(entry: SessionEntry): RunSummaryRecord | undefined;
|
|
11
|
+
//# sourceMappingURL=record.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record.d.ts","sourceRoot":"","sources":["../../../src/extensions/run-summary/record.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAElE,eAAO,MAAM,sBAAsB,gBAAgB,CAAC;AAEpD,MAAM,WAAW,gBAAgB;IAChC,OAAO,EAAE,CAAC,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,YAAY,GAAG,gBAAgB,GAAG,SAAS,CA0BtF"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export const RUN_SUMMARY_ENTRY_TYPE = "run-summary";
|
|
2
|
+
export function readRunSummaryRecord(entry) {
|
|
3
|
+
if (entry.type !== "custom" || entry.customType !== RUN_SUMMARY_ENTRY_TYPE)
|
|
4
|
+
return undefined;
|
|
5
|
+
const data = entry.data;
|
|
6
|
+
if (!data || typeof data !== "object")
|
|
7
|
+
return undefined;
|
|
8
|
+
const record = data;
|
|
9
|
+
if (record.version !== 1 ||
|
|
10
|
+
typeof record.afterEntryId !== "string" ||
|
|
11
|
+
record.afterEntryId.length === 0 ||
|
|
12
|
+
typeof record.startedAt !== "number" ||
|
|
13
|
+
!Number.isFinite(record.startedAt) ||
|
|
14
|
+
record.startedAt < 0 ||
|
|
15
|
+
typeof record.finishedAt !== "number" ||
|
|
16
|
+
!Number.isFinite(record.finishedAt) ||
|
|
17
|
+
record.finishedAt < record.startedAt ||
|
|
18
|
+
(record.outcome !== "done" && record.outcome !== "stopped")) {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
version: 1,
|
|
23
|
+
afterEntryId: record.afterEntryId,
|
|
24
|
+
startedAt: record.startedAt,
|
|
25
|
+
finishedAt: record.finishedAt,
|
|
26
|
+
outcome: record.outcome,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=record.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record.js","sourceRoot":"","sources":["../../../src/extensions/run-summary/record.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,sBAAsB,GAAG,aAAa,CAAC;AAUpD,MAAM,UAAU,oBAAoB,CAAC,KAAmB;IACvD,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,KAAK,sBAAsB;QAAE,OAAO,SAAS,CAAC;IAC7F,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;IACxB,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IACxD,MAAM,MAAM,GAAG,IAA+B,CAAC;IAC/C,IACC,MAAM,CAAC,OAAO,KAAK,CAAC;QACpB,OAAO,MAAM,CAAC,YAAY,KAAK,QAAQ;QACvC,MAAM,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC;QAChC,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ;QACpC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC;QAClC,MAAM,CAAC,SAAS,GAAG,CAAC;QACpB,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ;QACrC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC;QACnC,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,SAAS;QACpC,CAAC,MAAM,CAAC,OAAO,KAAK,MAAM,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,EAC1D,CAAC;QACF,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,OAAO;QACN,OAAO,EAAE,CAAC;QACV,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,OAAO,EAAE,MAAM,CAAC,OAAO;KACvB,CAAC;AACH,CAAC","sourcesContent":["import type { SessionEntry } from \"../../core/session-manager.ts\";\n\nexport const RUN_SUMMARY_ENTRY_TYPE = \"run-summary\";\n\nexport interface RunSummaryRecord {\n\tversion: 1;\n\tafterEntryId: string;\n\tstartedAt: number;\n\tfinishedAt: number;\n\toutcome: \"done\" | \"stopped\";\n}\n\nexport function readRunSummaryRecord(entry: SessionEntry): RunSummaryRecord | undefined {\n\tif (entry.type !== \"custom\" || entry.customType !== RUN_SUMMARY_ENTRY_TYPE) return undefined;\n\tconst data = entry.data;\n\tif (!data || typeof data !== \"object\") return undefined;\n\tconst record = data as Record<string, unknown>;\n\tif (\n\t\trecord.version !== 1 ||\n\t\ttypeof record.afterEntryId !== \"string\" ||\n\t\trecord.afterEntryId.length === 0 ||\n\t\ttypeof record.startedAt !== \"number\" ||\n\t\t!Number.isFinite(record.startedAt) ||\n\t\trecord.startedAt < 0 ||\n\t\ttypeof record.finishedAt !== \"number\" ||\n\t\t!Number.isFinite(record.finishedAt) ||\n\t\trecord.finishedAt < record.startedAt ||\n\t\t(record.outcome !== \"done\" && record.outcome !== \"stopped\")\n\t) {\n\t\treturn undefined;\n\t}\n\treturn {\n\t\tversion: 1,\n\t\tafterEntryId: record.afterEntryId,\n\t\tstartedAt: record.startedAt,\n\t\tfinishedAt: record.finishedAt,\n\t\toutcome: record.outcome,\n\t};\n}\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import "./keybindings.ts";
|
|
2
|
+
import type { ExtensionAPI } from "../../core/extensions/types.ts";
|
|
3
|
+
/** User-facing Tasks management; execution and durable delivery remain session-owned. */
|
|
4
|
+
export default function tasksExtension(pi: ExtensionAPI): void;
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/extensions/tasks/index.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,gCAAgC,CAAC;AAOrF,yFAAyF;AACzF,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAoC7D"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import "./keybindings.js";
|
|
2
|
+
import { boundedText, describeTaskLine } from "./tool/actions.js";
|
|
3
|
+
import { createTasksToolDefinition } from "./tool.js";
|
|
4
|
+
import { renderTaskCompletion } from "./ui/completion-render.js";
|
|
5
|
+
import { bindTasksUI } from "./ui/index.js";
|
|
6
|
+
import { confirmStopBranchTasks } from "./ui/tree.js";
|
|
7
|
+
/** User-facing Tasks management; execution and durable delivery remain session-owned. */
|
|
8
|
+
export default function tasksExtension(pi) {
|
|
9
|
+
let ui;
|
|
10
|
+
const bind = (ctx) => {
|
|
11
|
+
ui?.dispose();
|
|
12
|
+
ui = bindTasksUI(ctx);
|
|
13
|
+
};
|
|
14
|
+
pi.on("session_start", (_event, ctx) => bind(ctx));
|
|
15
|
+
pi.on("session_shutdown", () => {
|
|
16
|
+
ui?.dispose();
|
|
17
|
+
ui = undefined;
|
|
18
|
+
});
|
|
19
|
+
pi.on("session_before_tree", async (event, ctx) => {
|
|
20
|
+
if (!ctx.hasUI)
|
|
21
|
+
return;
|
|
22
|
+
const stopped = ctx.tasks.session?.stoppedByTreeNavigation(event.preparation.targetId) ?? [];
|
|
23
|
+
if (!(await confirmStopBranchTasks(stopped, (title, message) => ctx.ui.confirm(title, message))))
|
|
24
|
+
return { cancel: true };
|
|
25
|
+
});
|
|
26
|
+
pi.registerTool(createTasksToolDefinition());
|
|
27
|
+
pi.registerMessageRenderer("task-completion", renderTaskCompletion);
|
|
28
|
+
pi.registerCommand("tasks", {
|
|
29
|
+
description: "View and manage session tasks",
|
|
30
|
+
handler: async (_args, ctx) => {
|
|
31
|
+
if (ctx.mode !== "tui") {
|
|
32
|
+
const tasks = ctx.tasks.list().filter((task) => task.mode === "background");
|
|
33
|
+
ctx.ui.notify(boundedText(tasks.slice(0, 10).map(describeTaskLine).join("\n")) || "No background tasks.", "info");
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (!ui)
|
|
37
|
+
bind(ctx);
|
|
38
|
+
await ui.open();
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/extensions/tasks/index.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAE1B,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,WAAW,EAAgB,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAEtD,yFAAyF;AACzF,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EAAgB;IACtD,IAAI,EAAuB,CAAC;IAC5B,MAAM,IAAI,GAAG,CAAC,GAAqB,EAAE,EAAE;QACtC,EAAE,EAAE,OAAO,EAAE,CAAC;QACd,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC,CAAC;IAEF,EAAE,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACnD,EAAE,CAAC,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAC9B,EAAE,EAAE,OAAO,EAAE,CAAC;QACd,EAAE,GAAG,SAAS,CAAC;IAChB,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,EAAE,CAAC,qBAAqB,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QACjD,IAAI,CAAC,GAAG,CAAC,KAAK;YAAE,OAAO;QACvB,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,uBAAuB,CAAC,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC7F,IAAI,CAAC,CAAC,MAAM,sBAAsB,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;YAC/F,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,YAAY,CAAC,yBAAyB,EAAE,CAAC,CAAC;IAC7C,EAAE,CAAC,uBAAuB,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,CAAC;IACpE,EAAE,CAAC,eAAe,CAAC,OAAO,EAAE;QAC3B,WAAW,EAAE,+BAA+B;QAC5C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YAC7B,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;gBACxB,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;gBAC5E,GAAG,CAAC,EAAE,CAAC,MAAM,CACZ,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,sBAAsB,EAC1F,MAAM,CACN,CAAC;gBACF,OAAO;YACR,CAAC;YACD,IAAI,CAAC,EAAE;gBAAE,IAAI,CAAC,GAAG,CAAC,CAAC;YACnB,MAAM,EAAG,CAAC,IAAI,EAAE,CAAC;QAClB,CAAC;KACD,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import \"./keybindings.ts\";\nimport type { ExtensionAPI, ExtensionContext } from \"../../core/extensions/types.ts\";\nimport { boundedText, describeTaskLine } from \"./tool/actions.ts\";\nimport { createTasksToolDefinition } from \"./tool.ts\";\nimport { renderTaskCompletion } from \"./ui/completion-render.ts\";\nimport { bindTasksUI, type TasksUI } from \"./ui/index.ts\";\nimport { confirmStopBranchTasks } from \"./ui/tree.ts\";\n\n/** User-facing Tasks management; execution and durable delivery remain session-owned. */\nexport default function tasksExtension(pi: ExtensionAPI): void {\n\tlet ui: TasksUI | undefined;\n\tconst bind = (ctx: ExtensionContext) => {\n\t\tui?.dispose();\n\t\tui = bindTasksUI(ctx);\n\t};\n\n\tpi.on(\"session_start\", (_event, ctx) => bind(ctx));\n\tpi.on(\"session_shutdown\", () => {\n\t\tui?.dispose();\n\t\tui = undefined;\n\t});\n\tpi.on(\"session_before_tree\", async (event, ctx) => {\n\t\tif (!ctx.hasUI) return;\n\t\tconst stopped = ctx.tasks.session?.stoppedByTreeNavigation(event.preparation.targetId) ?? [];\n\t\tif (!(await confirmStopBranchTasks(stopped, (title, message) => ctx.ui.confirm(title, message))))\n\t\t\treturn { cancel: true };\n\t});\n\n\tpi.registerTool(createTasksToolDefinition());\n\tpi.registerMessageRenderer(\"task-completion\", renderTaskCompletion);\n\tpi.registerCommand(\"tasks\", {\n\t\tdescription: \"View and manage session tasks\",\n\t\thandler: async (_args, ctx) => {\n\t\t\tif (ctx.mode !== \"tui\") {\n\t\t\t\tconst tasks = ctx.tasks.list().filter((task) => task.mode === \"background\");\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\tboundedText(tasks.slice(0, 10).map(describeTaskLine).join(\"\\n\")) || \"No background tasks.\",\n\t\t\t\t\t\"info\",\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!ui) bind(ctx);\n\t\t\tawait ui!.open();\n\t\t},\n\t});\n}\n"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
declare module "@earendil-works/pi-tui" {
|
|
2
|
+
interface Keybindings {
|
|
3
|
+
"app.tasks.detach": true;
|
|
4
|
+
"app.tasks.previousTab": true;
|
|
5
|
+
"app.tasks.nextTab": true;
|
|
6
|
+
"app.tasks.kill": true;
|
|
7
|
+
"app.tasks.confirmStop": true;
|
|
8
|
+
"app.tasks.detachSelected": true;
|
|
9
|
+
"app.tasks.search": true;
|
|
10
|
+
"app.tasks.follow": true;
|
|
11
|
+
"app.tasks.top": true;
|
|
12
|
+
"app.tasks.bottom": true;
|
|
13
|
+
"app.tasks.nextFocus": true;
|
|
14
|
+
"app.tasks.previousFocus": true;
|
|
15
|
+
"app.tasks.help": true;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=keybindings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keybindings.d.ts","sourceRoot":"","sources":["../../../src/extensions/tasks/keybindings.ts"],"names":[],"mappings":"AAMA,OAAO,QAAQ,wBAAwB,CAAC;IACvC,UAAU,WAAW;QACpB,kBAAkB,EAAE,IAAI,CAAC;QACzB,uBAAuB,EAAE,IAAI,CAAC;QAC9B,mBAAmB,EAAE,IAAI,CAAC;QAC1B,gBAAgB,EAAE,IAAI,CAAC;QACvB,uBAAuB,EAAE,IAAI,CAAC;QAC9B,0BAA0B,EAAE,IAAI,CAAC;QACjC,kBAAkB,EAAE,IAAI,CAAC;QACzB,kBAAkB,EAAE,IAAI,CAAC;QACzB,eAAe,EAAE,IAAI,CAAC;QACtB,kBAAkB,EAAE,IAAI,CAAC;QACzB,qBAAqB,EAAE,IAAI,CAAC;QAC5B,yBAAyB,EAAE,IAAI,CAAC;QAChC,gBAAgB,EAAE,IAAI,CAAC;KACvB;CACD"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { registerKeybindingHelpSection, registerKeybindings, registerReservedKeybindings, } from "../../core/keybinding-registry.js";
|
|
2
|
+
const TASK_KEYBINDINGS = {
|
|
3
|
+
"app.tasks.detach": { defaultKeys: "ctrl+b", description: "Move foreground tasks to the background" },
|
|
4
|
+
"app.tasks.previousTab": { defaultKeys: "left", description: "Show Output in the focused task inspector" },
|
|
5
|
+
"app.tasks.nextTab": { defaultKeys: "right", description: "Show Details in the focused task inspector" },
|
|
6
|
+
"app.tasks.kill": { defaultKeys: "k", description: "Stop the selected task" },
|
|
7
|
+
"app.tasks.confirmStop": { defaultKeys: "enter", description: "Confirm stopping the selected task" },
|
|
8
|
+
"app.tasks.detachSelected": { defaultKeys: "b", description: "Move the selected task to the background" },
|
|
9
|
+
"app.tasks.search": { defaultKeys: "/", description: "Search retained task identities and labels" },
|
|
10
|
+
"app.tasks.follow": { defaultKeys: "f", description: "Follow the selected task's output" },
|
|
11
|
+
"app.tasks.top": { defaultKeys: "home", description: "Go to the top of the task list or preview" },
|
|
12
|
+
"app.tasks.bottom": { defaultKeys: "end", description: "Go to the bottom of the task list or preview" },
|
|
13
|
+
"app.tasks.nextFocus": { defaultKeys: "tab", description: "Switch between task list and inspector" },
|
|
14
|
+
"app.tasks.previousFocus": { defaultKeys: "shift+tab", description: "Switch between task inspector and list" },
|
|
15
|
+
"app.tasks.help": { defaultKeys: "?", description: "Show task controls" },
|
|
16
|
+
};
|
|
17
|
+
registerKeybindings(TASK_KEYBINDINGS);
|
|
18
|
+
registerReservedKeybindings("app.tasks.detach");
|
|
19
|
+
registerKeybindingHelpSection({
|
|
20
|
+
id: "tasks",
|
|
21
|
+
title: "Tasks",
|
|
22
|
+
rows: [
|
|
23
|
+
{ action: "app.tasks.detach", description: TASK_KEYBINDINGS["app.tasks.detach"].description },
|
|
24
|
+
{
|
|
25
|
+
action: "app.tasks.detachSelected",
|
|
26
|
+
description: `${TASK_KEYBINDINGS["app.tasks.detachSelected"].description} (while /tasks is open)`,
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
});
|
|
30
|
+
//# sourceMappingURL=keybindings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keybindings.js","sourceRoot":"","sources":["../../../src/extensions/tasks/keybindings.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,6BAA6B,EAC7B,mBAAmB,EACnB,2BAA2B,GAC3B,MAAM,mCAAmC,CAAC;AAoB3C,MAAM,gBAAgB,GAAG;IACxB,kBAAkB,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,yCAAyC,EAAE;IACrG,uBAAuB,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,2CAA2C,EAAE;IAC1G,mBAAmB,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,4CAA4C,EAAE;IACxG,gBAAgB,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,EAAE,wBAAwB,EAAE;IAC7E,uBAAuB,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,oCAAoC,EAAE;IACpG,0BAA0B,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,EAAE,0CAA0C,EAAE;IACzG,kBAAkB,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,EAAE,4CAA4C,EAAE;IACnG,kBAAkB,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,EAAE,mCAAmC,EAAE;IAC1F,eAAe,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,2CAA2C,EAAE;IAClG,kBAAkB,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,8CAA8C,EAAE;IACvG,qBAAqB,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,wCAAwC,EAAE;IACpG,yBAAyB,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,wCAAwC,EAAE;IAC9G,gBAAgB,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,EAAE,oBAAoB,EAAE;CAChE,CAAC;AAEX,mBAAmB,CAAC,gBAAgB,CAAC,CAAC;AAEtC,2BAA2B,CAAC,kBAAkB,CAAC,CAAC;AAEhD,6BAA6B,CAAC;IAC7B,EAAE,EAAE,OAAO;IACX,KAAK,EAAE,OAAO;IACd,IAAI,EAAE;QACL,EAAE,MAAM,EAAE,kBAAkB,EAAE,WAAW,EAAE,gBAAgB,CAAC,kBAAkB,CAAC,CAAC,WAAW,EAAE;QAC7F;YACC,MAAM,EAAE,0BAA0B;YAClC,WAAW,EAAE,GAAG,gBAAgB,CAAC,0BAA0B,CAAC,CAAC,WAAW,yBAAyB;SACjG;KACD;CACD,CAAC,CAAC","sourcesContent":["import {\n\tregisterKeybindingHelpSection,\n\tregisterKeybindings,\n\tregisterReservedKeybindings,\n} from \"../../core/keybinding-registry.ts\";\n\ndeclare module \"@earendil-works/pi-tui\" {\n\tinterface Keybindings {\n\t\t\"app.tasks.detach\": true;\n\t\t\"app.tasks.previousTab\": true;\n\t\t\"app.tasks.nextTab\": true;\n\t\t\"app.tasks.kill\": true;\n\t\t\"app.tasks.confirmStop\": true;\n\t\t\"app.tasks.detachSelected\": true;\n\t\t\"app.tasks.search\": true;\n\t\t\"app.tasks.follow\": true;\n\t\t\"app.tasks.top\": true;\n\t\t\"app.tasks.bottom\": true;\n\t\t\"app.tasks.nextFocus\": true;\n\t\t\"app.tasks.previousFocus\": true;\n\t\t\"app.tasks.help\": true;\n\t}\n}\n\nconst TASK_KEYBINDINGS = {\n\t\"app.tasks.detach\": { defaultKeys: \"ctrl+b\", description: \"Move foreground tasks to the background\" },\n\t\"app.tasks.previousTab\": { defaultKeys: \"left\", description: \"Show Output in the focused task inspector\" },\n\t\"app.tasks.nextTab\": { defaultKeys: \"right\", description: \"Show Details in the focused task inspector\" },\n\t\"app.tasks.kill\": { defaultKeys: \"k\", description: \"Stop the selected task\" },\n\t\"app.tasks.confirmStop\": { defaultKeys: \"enter\", description: \"Confirm stopping the selected task\" },\n\t\"app.tasks.detachSelected\": { defaultKeys: \"b\", description: \"Move the selected task to the background\" },\n\t\"app.tasks.search\": { defaultKeys: \"/\", description: \"Search retained task identities and labels\" },\n\t\"app.tasks.follow\": { defaultKeys: \"f\", description: \"Follow the selected task's output\" },\n\t\"app.tasks.top\": { defaultKeys: \"home\", description: \"Go to the top of the task list or preview\" },\n\t\"app.tasks.bottom\": { defaultKeys: \"end\", description: \"Go to the bottom of the task list or preview\" },\n\t\"app.tasks.nextFocus\": { defaultKeys: \"tab\", description: \"Switch between task list and inspector\" },\n\t\"app.tasks.previousFocus\": { defaultKeys: \"shift+tab\", description: \"Switch between task inspector and list\" },\n\t\"app.tasks.help\": { defaultKeys: \"?\", description: \"Show task controls\" },\n} as const;\n\nregisterKeybindings(TASK_KEYBINDINGS);\n\nregisterReservedKeybindings(\"app.tasks.detach\");\n\nregisterKeybindingHelpSection({\n\tid: \"tasks\",\n\ttitle: \"Tasks\",\n\trows: [\n\t\t{ action: \"app.tasks.detach\", description: TASK_KEYBINDINGS[\"app.tasks.detach\"].description },\n\t\t{\n\t\t\taction: \"app.tasks.detachSelected\",\n\t\t\tdescription: `${TASK_KEYBINDINGS[\"app.tasks.detachSelected\"].description} (while /tasks is open)`,\n\t\t},\n\t],\n});\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Management only: execution and delivery belong to the session task runtime. */
|
|
2
|
-
import type { AgentToolResult } from "
|
|
3
|
-
import { type TaskSnapshot, type TasksContext } from "
|
|
2
|
+
import type { AgentToolResult } from "../../../core/extensions/types.ts";
|
|
3
|
+
import { type TaskSnapshot, type TasksContext } from "../../../core/tasks/types.ts";
|
|
4
4
|
import { type TasksInput } from "./schema.ts";
|
|
5
5
|
import type { TasksKillDetails, TasksListDetails, TasksReadDetails, TasksWaitDetails } from "./types.ts";
|
|
6
6
|
export declare function boundedText(text: string): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../../../src/extensions/tasks/tool/actions.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAElF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAGzE,OAAO,EAIN,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,MAAM,8BAA8B,CAAC;AAItC,OAAO,EAA+D,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAC3G,OAAO,KAAK,EAAgB,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEvH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAID,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,SAAa,GAAG,MAAM,CAE7E;AAwFD,wBAAsB,OAAO,CAAC,UAAU,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,eAAe,CAAC,gBAAgB,CAAC,CAAC,CAkBrH;AAyFD,wBAAsB,OAAO,CAC5B,UAAU,EAAE,YAAY,EACxB,KAAK,EAAE,UAAU,EACjB,MAAM,CAAC,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,EAClC,eAAe,CAAC,EAAE,WAAW,GAC3B,OAAO,CAAC,eAAe,CAAC,gBAAgB,CAAC,CAAC,CAmE5C;AACD,wBAAgB,OAAO,CAAC,UAAU,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,GAAG,eAAe,CAAC,gBAAgB,CAAC,CAoBtG;AACD,wBAAgB,OAAO,CAAC,UAAU,EAAE,YAAY,GAAG,eAAe,CAAC,gBAAgB,CAAC,CAmBnF"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/** Management only: execution and delivery belong to the session task runtime. */
|
|
2
|
+
import { runtimeLabel } from "../../../core/tasks/format.js";
|
|
3
|
+
import { boundText } from "../../../core/tasks/output.js";
|
|
4
|
+
import { isTaskTerminal, TaskLookupError, } from "../../../core/tasks/types.js";
|
|
5
|
+
import { truncateHead } from "../../../core/tools/truncate.js";
|
|
2
6
|
import { sanitizeBinaryOutput } from "../../../utils/shell.js";
|
|
3
|
-
import { runtimeLabel } from "../../tasks/format.js";
|
|
4
|
-
import { boundText } from "../../tasks/output.js";
|
|
5
|
-
import { isTaskTerminal, TaskLookupError, } from "../../tasks/types.js";
|
|
6
|
-
import { truncateHead } from "../truncate.js";
|
|
7
7
|
import { TASKS_LIST_FINISHED_SHOWN, TASKS_WAIT_DELTA_BYTES } from "./constants.js";
|
|
8
8
|
import { clampReadBytes, clampSinceBytes, clampWaitMs, requireTaskId } from "./schema.js";
|
|
9
9
|
export function boundedText(text) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../../../../src/extensions/tasks/tool/actions.ts"],"names":[],"mappings":"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","sourcesContent":["/** Management only: execution and delivery belong to the session task runtime. */\n\nimport type { AgentToolResult } from \"../../../core/extensions/types.ts\";\nimport { runtimeLabel } from \"../../../core/tasks/format.ts\";\nimport { boundText } from \"../../../core/tasks/output.ts\";\nimport {\n\tisTaskTerminal,\n\tTaskLookupError,\n\ttype TaskRead,\n\ttype TaskSnapshot,\n\ttype TasksContext,\n} from \"../../../core/tasks/types.ts\";\nimport { truncateHead } from \"../../../core/tools/truncate.ts\";\nimport { sanitizeBinaryOutput } from \"../../../utils/shell.ts\";\nimport { TASKS_LIST_FINISHED_SHOWN, TASKS_WAIT_DELTA_BYTES } from \"./constants.ts\";\nimport { clampReadBytes, clampSinceBytes, clampWaitMs, requireTaskId, type TasksInput } from \"./schema.ts\";\nimport type { TasksDetails, TasksKillDetails, TasksListDetails, TasksReadDetails, TasksWaitDetails } 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 TasksDetails>(text: string, details: T): AgentToolResult<T> {\n\treturn { content: [{ type: \"text\", text: boundedText(text) }], details };\n}\nexport function describeTaskLine(task: TaskSnapshot, 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 LOOKUP_LIST_LIMIT = 10;\n\n/**\n * Finished rows sort most-recent first. list() is creation-ordered, so an\n * unsorted slice would surface the oldest completions rather than the recent\n * finishes a caller is most likely looking for.\n */\nfunction recentFinishedFirst(tasks: TaskSnapshot[]): TaskSnapshot[] {\n\treturn tasks.sort((left, right) => (right.endedAt ?? 0) - (left.endedAt ?? 0));\n}\n\n/**\n * Listings cover backgrounded work only; foreground executions deliver inline\n * in the transcript, so they are counted rather than shown. Every listing\n * (tasks list output and lookup-failure messages) shares this scope.\n */\nfunction listedTasks(background: TasksContext): { tasks: TaskSnapshot[]; foregroundOmitted: number } {\n\tconst all = background.list();\n\tconst tasks = all.filter((task) => task.mode === \"background\");\n\treturn { tasks, foregroundOmitted: all.length - tasks.length };\n}\n\nfunction foregroundOmissionNote(omitted: number): string {\n\treturn omitted > 0\n\t\t? `\\n${omitted} foreground ${omitted === 1 ? \"execution\" : \"executions\"} omitted — foreground work is delivered inline in the transcript.`\n\t\t: \"\";\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 — including\n * records outside the current branch, which listings hide but the prefix\n * still collides with.\n */\nfunction lookupFailure(background: TasksContext, id: string, error: unknown): Error {\n\tif (!(error instanceof TaskLookupError)) return error instanceof Error ? error : new Error(String(error));\n\tif (error.kind === \"ambiguous\") {\n\t\tconst lines = error.matches.map((task) => describeTaskLine(task)).join(\"\\n\");\n\t\treturn new Error(`Ambiguous task ID \"${id}\" matches ${error.matches.length} tasks:\\n${lines}`);\n\t}\n\tconst { tasks, foregroundOmitted } = listedTasks(background);\n\tconst active = tasks.filter((task) => !isTaskTerminal(task.status));\n\tconst finished = recentFinishedFirst(tasks.filter((task) => isTaskTerminal(task.status)));\n\tconst shown = [...active, ...finished].slice(0, LOOKUP_LIST_LIMIT);\n\tif (shown.length === 0) {\n\t\treturn new Error(`No 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 task \"${id}\" in this session. IDs from other sessions are not valid here.\\nCurrent background tasks:\\n${lines}${foregroundOmissionNote(foregroundOmitted)}`,\n\t);\n}\n\n/**\n * Where this slice sits in the output, so the next wait can continue from it.\n * A wait whose new output exceeds its budget returns the newest bytes and says what it skipped.\n */\nfunction rangeText(slice: TaskRead, sinceBytes?: number): string {\n\tconst from = slice.fromByte ?? 0;\n\tconst to = from + Buffer.byteLength(slice.text);\n\tconst floor = sinceBytes === undefined || sinceBytes > slice.totalBytes ? 0 : sinceBytes;\n\treturn [\n\t\t`bytes ${from}–${to} of ${slice.totalBytes}`,\n\t\tsinceBytes !== undefined && from > floor ? `skipped ${from - floor} bytes after sinceBytes ${floor}` : \"\",\n\t\t`next sinceBytes ${to}`,\n\t]\n\t\t.filter(Boolean)\n\t\t.join(\" · \");\n}\n\n/** Reserve space for each independent diagnostic before allowing raw output to fill the budget. */\nfunction readText(header: string, slice: TaskRead): 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: TasksContext, input: TasksInput): Promise<AgentToolResult<TasksReadDetails>> {\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(readText(`[${describeTaskLine(slice.task)} · ${rangeText(slice)}]`, slice), {\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} catch (error) {\n\t\tthrow lookupFailure(background, id, error);\n\t}\n}\nfunction activeBackgroundTasks(background: TasksContext): TaskSnapshot[] {\n\treturn background.list().filter((task) => task.mode === \"background\" && !isTaskTerminal(task.status));\n}\n\nfunction stillRunningText(tasks: TaskSnapshot[]): string {\n\treturn tasks.length > 0 ? `\\n\\n[still_running]\\n${tasks.map((task) => describeTaskLine(task)).join(\"\\n\")}` : \"\";\n}\n\nfunction emptyWaitDetails(\n\toutcome: \"interrupted\" | \"timed_out\" | \"no_tasks\",\n\twaitedMs: number,\n\trunning: number,\n): TasksWaitDetails {\n\treturn {\n\t\taction: \"wait\",\n\t\toutcome,\n\t\ttimedOut: outcome === \"timed_out\",\n\t\texitCode: undefined,\n\t\twaitedMs,\n\t\tdeltaBytes: 0,\n\t\ttotalBytes: 0,\n\t\tdeltaTruncated: false,\n\t\toutputPath: \"\",\n\t\trunning,\n\t};\n}\n\nasync function runWaitAny(\n\tbackground: TasksContext,\n\tinput: TasksInput,\n\tsignal?: AbortSignal,\n\tonReady?: (taskId: string) => void,\n\tinterruptSignal?: AbortSignal,\n): Promise<AgentToolResult<TasksWaitDetails>> {\n\tconst candidates = activeBackgroundTasks(background);\n\tif (candidates.length === 0) {\n\t\treturn result(\n\t\t\t\"No background tasks are running, so there is nothing to wait for. Finished tasks report back via automatic notification.\",\n\t\t\temptyWaitDetails(\"no_tasks\", 0, 0),\n\t\t);\n\t}\n\t// Holds cover the whole initial cohort until the winning result is ready for\n\t// persistence. Other completed tasks resume ordinary notification delivery on release.\n\tconst releases = candidates.map((task) => background.holdDelivery(task.id));\n\tconst start = Date.now();\n\ttry {\n\t\tconst task = await background.waitAny(clampWaitMs(input.waitMs), signal, interruptSignal);\n\t\tconst ids = new Set(candidates.map((candidate) => candidate.id));\n\t\tconst running = activeBackgroundTasks(background).filter((candidate) => ids.has(candidate.id));\n\t\tif (!task) {\n\t\t\tconst interrupted = !background.closed && interruptSignal?.aborted === true;\n\t\t\tconst outcome = interrupted ? \"interrupted\" : \"timed_out\";\n\t\t\tconst note = background.closed\n\t\t\t\t? \"The host closed; execution state is unconfirmed.\"\n\t\t\t\t: interrupted\n\t\t\t\t\t? \"New steering input ended this wait early. Read the new input before deciding what to do next; no task was stopped.\"\n\t\t\t\t\t: \"The wait window expired; running tasks continue. Prefer other work over waiting again.\";\n\t\t\treturn result(\n\t\t\t\t`${note}${stillRunningText(running)}`,\n\t\t\t\temptyWaitDetails(outcome, Date.now() - start, running.length),\n\t\t\t);\n\t\t}\n\t\tconst slice = await background.read(task.id, { bytes: TASKS_WAIT_DELTA_BYTES });\n\t\tsignal?.throwIfAborted();\n\t\tonReady?.(task.id);\n\t\treturn result(\n\t\t\t`${readText(`[${describeTaskLine(task)} · waitAny settled · ${rangeText(slice)}]`, slice)}${stillRunningText(running)}`,\n\t\t\t{\n\t\t\t\taction: \"wait\",\n\t\t\t\toutcome: \"settled\",\n\t\t\t\ttaskId: task.id,\n\t\t\t\tstatus: task.status,\n\t\t\t\tkind: task.kind,\n\t\t\t\ttimedOut: false,\n\t\t\t\texitCode: task.exitCode,\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\trunning: running.length,\n\t\t\t},\n\t\t);\n\t} finally {\n\t\tfor (const release of releases) release();\n\t}\n}\n\nexport async function runWait(\n\tbackground: TasksContext,\n\tinput: TasksInput,\n\tsignal?: AbortSignal,\n\tonReady?: (taskId: string) => void,\n\tinterruptSignal?: AbortSignal,\n): Promise<AgentToolResult<TasksWaitDetails>> {\n\tif (!input.taskId?.trim()) {\n\t\tif (input.sinceBytes !== undefined)\n\t\t\tthrow new Error(\"action 'wait' without 'taskId' does not accept 'sinceBytes'; offsets belong to one task.\");\n\t\treturn runWaitAny(background, input, signal, onReady, interruptSignal);\n\t}\n\tconst id = requireTaskId(input);\n\ttry {\n\t\tconst release = background.holdDelivery(id);\n\t\ttry {\n\t\t\tconst start = Date.now();\n\t\t\tconst task = await background.wait(id, clampWaitMs(input.waitMs), signal, interruptSignal);\n\t\t\tconst settled = isTaskTerminal(task.status);\n\t\t\tconst interrupted = !settled && !background.closed && interruptSignal?.aborted === true;\n\t\t\tconst timedOut = !settled && !interrupted;\n\t\t\tconst outcome = settled ? \"settled\" : interrupted ? \"interrupted\" : \"timed_out\";\n\t\t\tconst waitedMs = Date.now() - start;\n\t\t\tif (interrupted) {\n\t\t\t\treturn result(\n\t\t\t\t\t`[${describeTaskLine(task)} · interrupted by steering; execution continues]\\nRead the new input before deciding whether to wait again; the task was not stopped.`,\n\t\t\t\t\t{\n\t\t\t\t\t\taction: \"wait\",\n\t\t\t\t\t\toutcome,\n\t\t\t\t\t\ttaskId: task.id,\n\t\t\t\t\t\tstatus: task.status,\n\t\t\t\t\t\tkind: task.kind,\n\t\t\t\t\t\ttimedOut: false,\n\t\t\t\t\t\texitCode: task.exitCode,\n\t\t\t\t\t\twaitedMs,\n\t\t\t\t\t\tdeltaBytes: 0,\n\t\t\t\t\t\ttotalBytes: 0,\n\t\t\t\t\t\tdeltaTruncated: false,\n\t\t\t\t\t\toutputPath: task.outputPath ?? \"\",\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\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 sinceBytes = clampSinceBytes(input.sinceBytes);\n\t\t\tconst slice = await background.read(id, { bytes: TASKS_WAIT_DELTA_BYTES, sinceBytes });\n\t\t\tsignal?.throwIfAborted();\n\t\t\tif (settled) onReady?.(task.id);\n\t\t\treturn result(readText(`[${describeTaskLine(task)}${windowNote} · ${rangeText(slice, sinceBytes)}]`, slice), {\n\t\t\t\taction: \"wait\",\n\t\t\t\toutcome,\n\t\t\t\ttaskId: 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: task.exitCode,\n\t\t\t\twaitedMs,\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: TasksContext, input: TasksInput): AgentToolResult<TasksKillDetails> {\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: TasksContext): AgentToolResult<TasksListDetails> {\n\tconst { tasks, foregroundOmitted } = listedTasks(background);\n\tconst active = tasks.filter((task) => !isTaskTerminal(task.status));\n\tconst finished = recentFinishedFirst(tasks.filter((task) => isTaskTerminal(task.status)));\n\tconst shown = [...active, ...finished.slice(0, TASKS_LIST_FINISHED_SHOWN)].slice(0, 100);\n\tconst hidden = tasks.length - shown.length;\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.` : \"\"}${foregroundOmissionNote(foregroundOmitted)}`\n\t\t\t: `No background tasks. Start work through its owning tool with background: true.${foregroundOmissionNote(foregroundOmitted)}`,\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"]}
|
|
@@ -12,9 +12,7 @@ export declare const TASKS_LIST_FINISHED_SHOWN = 5;
|
|
|
12
12
|
/** Bounded output delta returned by a successful wait. */
|
|
13
13
|
export declare const TASKS_WAIT_DELTA_BYTES: number;
|
|
14
14
|
/** Wait-window bounds shared by execution and the pending-call renderer. */
|
|
15
|
-
export
|
|
16
|
-
export declare const TASKS_WAIT_MIN_MS = 1000;
|
|
17
|
-
export declare const TASKS_WAIT_MAX_MS = 60000;
|
|
15
|
+
export { TASKS_WAIT_DEFAULT_MS, TASKS_WAIT_MAX_MS, TASKS_WAIT_MIN_MS } from "../../../core/tasks/limits.ts";
|
|
18
16
|
/** How long a foreground execution runs before the statusline advertises the detach key. */
|
|
19
17
|
export declare const TASKS_DETACH_HINT_DELAY_MS = 10000;
|
|
20
18
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/extensions/tasks/tool/constants.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,yFAAyF;AACzF,eAAO,MAAM,wBAAwB,QAAW,CAAC;AACjD,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC,wEAAwE;AACxE,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAE3C,0DAA0D;AAC1D,eAAO,MAAM,sBAAsB,QAAY,CAAC;AAEhD,4EAA4E;AAC5E,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAE5G,4FAA4F;AAC5F,eAAO,MAAM,0BAA0B,QAAS,CAAC"}
|
|
@@ -12,9 +12,7 @@ export const TASKS_LIST_FINISHED_SHOWN = 5;
|
|
|
12
12
|
/** Bounded output delta returned by a successful wait. */
|
|
13
13
|
export const TASKS_WAIT_DELTA_BYTES = 32 * 1024;
|
|
14
14
|
/** Wait-window bounds shared by execution and the pending-call renderer. */
|
|
15
|
-
export
|
|
16
|
-
export const TASKS_WAIT_MIN_MS = 1_000;
|
|
17
|
-
export const TASKS_WAIT_MAX_MS = 60_000;
|
|
15
|
+
export { TASKS_WAIT_DEFAULT_MS, TASKS_WAIT_MAX_MS, TASKS_WAIT_MIN_MS } from "../../../core/tasks/limits.js";
|
|
18
16
|
/** How long a foreground execution runs before the statusline advertises the detach key. */
|
|
19
17
|
export const TASKS_DETACH_HINT_DELAY_MS = 10_000;
|
|
20
18
|
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../src/extensions/tasks/tool/constants.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,yFAAyF;AACzF,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,GAAG,IAAI,CAAC;AACjD,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,CAAC;AAExC,wEAAwE;AACxE,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC;AAE3C,0DAA0D;AAC1D,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,GAAG,IAAI,CAAC;AAEhD,4EAA4E;AAC5E,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAE5G,4FAA4F;AAC5F,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC","sourcesContent":["/**\n * Shared limits of the `tasks` tool.\n *\n * Numbers that more than one module needs live here so a change lands in one\n * place; execution and retention limits belong to the core service.\n */\n\n/** Default and floor for a `read` slice; the ceiling is the core's TASK_RESULT_BYTES. */\nexport const TASKS_LOGS_DEFAULT_BYTES = 8 * 1024;\nexport const TASKS_LOGS_MIN_BYTES = 256;\n\n/** Finished tasks shown by `list` before the rest fold into a count. */\nexport const TASKS_LIST_FINISHED_SHOWN = 5;\n\n/** Bounded output delta returned by a successful wait. */\nexport const TASKS_WAIT_DELTA_BYTES = 32 * 1024;\n\n/** Wait-window bounds shared by execution and the pending-call renderer. */\nexport { TASKS_WAIT_DEFAULT_MS, TASKS_WAIT_MAX_MS, TASKS_WAIT_MIN_MS } from \"../../../core/tasks/limits.ts\";\n\n/** How long a foreground execution runs before the statusline advertises the detach key. */\nexport const TASKS_DETACH_HINT_DELAY_MS = 10_000;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../src/extensions/tasks/tool/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAY5C,eAAO,MAAM,WAAW;;;;;;;EAiCtB,CAAC;AAEH,uFAAuF;AACvF,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,WAAW,CAAC,CAAC;AAOpD,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAMvD;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGhE;AAED,yFAAyF;AACzF,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAG9D;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAElF;AAED,eAAO,MAAM,sBAAsB,QAOmS,CAAC;AACvU,eAAO,MAAM,oBAAoB,0EAA0E,CAAC;AAC5G,eAAO,MAAM,uBAAuB,UAInC,CAAC"}
|
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { StringEnum } from "@earendil-works/pi-ai";
|
|
10
10
|
import { Type } from "typebox";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
11
|
+
import { formatDuration } from "../../../core/tasks/format.js";
|
|
12
|
+
import { TASK_RESULT_BYTES } from "../../../core/tasks/output.js";
|
|
13
|
+
import { formatSize } from "../../../core/tools/truncate.js";
|
|
13
14
|
import { TASKS_LOGS_DEFAULT_BYTES, TASKS_LOGS_MIN_BYTES, TASKS_WAIT_DEFAULT_MS, TASKS_WAIT_MAX_MS, TASKS_WAIT_MIN_MS, } from "./constants.js";
|
|
14
15
|
export const tasksSchema = Type.Object({
|
|
15
16
|
action: StringEnum(["read", "wait", "kill", "list"], {
|
|
@@ -28,7 +29,7 @@ export const tasksSchema = Type.Object({
|
|
|
28
29
|
})),
|
|
29
30
|
// — wait —
|
|
30
31
|
waitMs: Type.Optional(Type.Number({
|
|
31
|
-
description: `
|
|
32
|
+
description: `Maximum wait window in ms (default ${formatDuration(TASKS_WAIT_DEFAULT_MS)}, max ${formatDuration(TASKS_WAIT_MAX_MS)}). Only the wait ends on timeout; execution continues.`,
|
|
32
33
|
})),
|
|
33
34
|
sinceBytes: Type.Optional(Type.Number({
|
|
34
35
|
description: "Only return output written after this byte offset — use the 'next sinceBytes' value from a previous read or wait (wait with taskId only)",
|
|
@@ -61,7 +62,7 @@ export const TASKS_TOOL_DESCRIPTION = "Inspect and control background tasks star
|
|
|
61
62
|
"Completion is delivered to you automatically as a notification — never poll. " +
|
|
62
63
|
"list: bounded activity/history listing; find task IDs here. " +
|
|
63
64
|
"read: bounded output or report slice (head/tail). " +
|
|
64
|
-
"wait:
|
|
65
|
+
"wait: observe one task, or any task running at call time, for up to waitMs; no running tasks returns immediately. New steering input ends only the wait with outcome interrupted; it never stops the task. " +
|
|
65
66
|
"kill: request cancellation of a whole task. " +
|
|
66
67
|
"tasks cannot start work; submit background work through its owning tool. A wait ends as settled, interrupted, timed_out, or no_tasks. Timeout or cancellation ends only the wait, never execution. Reads and settled waits report byte ranges; use next sinceBytes only with that task's ID. Output is capped at 50KB per response.";
|
|
67
68
|
export const TASKS_PROMPT_SNIPPET = "Manage background tasks; wait for a specific task or any running task";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../../src/extensions/tasks/tool/schema.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The `tasks` tool's wire contract: one flat schema whose `action`\n * selects which of the remaining fields apply, plus the model-facing copy.\n *\n * The schema stays flat deliberately: a single tool keeps the model's tool list\n * short. Execution creation belongs to the native tools. Narrowing happens\n * inside actions.ts, not here.\n */\n\nimport { StringEnum } from \"@earendil-works/pi-ai\";\nimport { type Static, Type } from \"typebox\";\nimport { formatDuration } from \"../../../core/tasks/format.ts\";\nimport { TASK_RESULT_BYTES } from \"../../../core/tasks/output.ts\";\nimport { formatSize } from \"../../../core/tools/truncate.ts\";\nimport {\n\tTASKS_LOGS_DEFAULT_BYTES,\n\tTASKS_LOGS_MIN_BYTES,\n\tTASKS_WAIT_DEFAULT_MS,\n\tTASKS_WAIT_MAX_MS,\n\tTASKS_WAIT_MIN_MS,\n} from \"./constants.ts\";\n\nexport const tasksSchema = Type.Object({\n\taction: StringEnum([\"read\", \"wait\", \"kill\", \"list\"] as const, {\n\t\tdescription: \"Which task operation to perform\",\n\t}),\n\t// — read / wait / kill —\n\ttaskId: Type.Optional(\n\t\tType.String({\n\t\t\tdescription: \"Task execution id (read/wait/kill). Omit for wait to wait for any task running at call time.\",\n\t\t}),\n\t),\n\t// — read —\n\tmode: Type.Optional(\n\t\tStringEnum([\"tail\", \"head\"] as const, {\n\t\t\tdescription: \"Read from the end (default) or the start of the output (read)\",\n\t\t}),\n\t),\n\tbytes: Type.Optional(\n\t\tType.Number({\n\t\t\tdescription: `Max bytes to return (read, default ${formatSize(TASKS_LOGS_DEFAULT_BYTES)}, max ${formatSize(TASK_RESULT_BYTES)})`,\n\t\t}),\n\t),\n\t// — wait —\n\twaitMs: Type.Optional(\n\t\tType.Number({\n\t\t\tdescription: `Maximum wait window in ms (default ${formatDuration(TASKS_WAIT_DEFAULT_MS)}, max ${formatDuration(TASKS_WAIT_MAX_MS)}). Only the wait ends on timeout; execution continues.`,\n\t\t}),\n\t),\n\tsinceBytes: Type.Optional(\n\t\tType.Number({\n\t\t\tdescription:\n\t\t\t\t\"Only return output written after this byte offset — use the 'next sinceBytes' value from a previous read or wait (wait with taskId only)\",\n\t\t}),\n\t),\n});\n\n/** Raw tool arguments. Every per-action field is optional here; actions.ts narrows. */\nexport type TasksInput = Static<typeof tasksSchema>;\n\n// ── reading the contract ──────────────────────────────────────────────────\n// One place per field: required fields throw a message that names the next\n// step, optional ones clamp to their documented range. Callers get plain\n// values, so no action handler needs a cast.\n\nexport function requireTaskId(input: TasksInput): string {\n\tconst taskId = input.taskId;\n\tif (!taskId || taskId.trim().length === 0) {\n\t\tthrow new Error(`action '${input.action}' requires 'taskId' — use action list to find the execution id.`);\n\t}\n\treturn taskId;\n}\n\nexport function clampReadBytes(bytes: number | undefined): number {\n\tconst value = bytes !== undefined && Number.isFinite(bytes) ? bytes : TASKS_LOGS_DEFAULT_BYTES;\n\treturn Math.min(TASK_RESULT_BYTES, Math.max(TASKS_LOGS_MIN_BYTES, Math.floor(value)));\n}\n\n/** Shared with the pending-call renderer so the window it shows is the one that runs. */\nexport function clampWaitMs(waitMs: number | undefined): number {\n\tconst value = waitMs !== undefined && Number.isFinite(waitMs) ? waitMs : TASKS_WAIT_DEFAULT_MS;\n\treturn Math.min(TASKS_WAIT_MAX_MS, Math.max(TASKS_WAIT_MIN_MS, Math.floor(value)));\n}\n\nexport function clampSinceBytes(sinceBytes: number | undefined): number | undefined {\n\treturn sinceBytes === undefined || !Number.isFinite(sinceBytes) ? undefined : Math.max(0, Math.floor(sinceBytes));\n}\n\nexport const TASKS_TOOL_DESCRIPTION =\n\t\"Inspect and control background tasks started by native tools or extensions. \" +\n\t\"Completion is delivered to you automatically as a notification — never poll. \" +\n\t\"list: bounded activity/history listing; find task IDs here. \" +\n\t\"read: bounded output or report slice (head/tail). \" +\n\t\"wait: observe one task, or any task running at call time, for up to waitMs; no running tasks returns immediately. New steering input ends only the wait with outcome interrupted; it never stops the task. \" +\n\t\"kill: request cancellation of a whole task. \" +\n\t\"tasks cannot start work; submit background work through its owning tool. A wait ends as settled, interrupted, timed_out, or no_tasks. Timeout or cancellation ends only the wait, never execution. Reads and settled waits report byte ranges; use next sinceBytes only with that task's ID. Output is capped at 50KB per response.\";\nexport const TASKS_PROMPT_SNIPPET = \"Manage background tasks; wait for a specific task or any running task\";\nexport const TASKS_PROMPT_GUIDELINES = [\n\t\"Start background work through its owning tool with background: true; continue independent work while it runs.\",\n\t\"A finished background task delivers its result automatically as a notification. Use tasks wait only when your next step is blocked: provide taskId for one task or omit it for any task running at call time; never sleep-poll with repeated reads.\",\n\t\"A new steering message interrupts only an active tasks wait so you can read the new input; it does not cancel execution. A wait timeout is not a task failure.\",\n];\n"]}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* `exitCode` is three-state: `null` for signal-reaped tasks.
|
|
10
10
|
*/
|
|
11
|
-
import type { TaskKind, TaskStatus } from "
|
|
11
|
+
import type { TaskKind, TaskStatus } from "../../../core/tasks/types.ts";
|
|
12
12
|
export interface TasksReadDetails {
|
|
13
13
|
kind?: TaskKind;
|
|
14
14
|
status?: TaskStatus;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/extensions/tasks/tool/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAEzE,MAAM,WAAW,gBAAgB;IAChC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,GAAG,UAAU,CAAC;AAEpF,MAAM,WAAW,gBAAgB;IAChC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,4FAA4F;IAC5F,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8FAA8F;IAC9F,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAChC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,6FAA6F;IAC7F,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,MAAM,YAAY,GAAG,gBAAgB,GAAG,gBAAgB,GAAG,gBAAgB,GAAG,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/extensions/tasks/tool/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG","sourcesContent":["/**\n * The `tasks` tool's structured `details` payloads.\n *\n * Every shape here is JSON-serialized verbatim into the session file and read back\n * by the renderers on `/reload`, `/tree`, and session resume. Adding an optional\n * field is free; renaming or repurposing an existing one degrades historical\n * transcripts.\n *\n * `exitCode` is three-state: `null` for signal-reaped tasks.\n */\n\nimport type { TaskKind, TaskStatus } from \"../../../core/tasks/types.ts\";\n\nexport interface TasksReadDetails {\n\tkind?: TaskKind;\n\tstatus?: TaskStatus;\n\taction: \"read\";\n\ttaskId: string;\n\tmode: \"head\" | \"tail\";\n\tsliceBytes: number;\n\ttotalBytes: number;\n\toutputPath: string;\n}\n\nexport type TasksWaitOutcome = \"settled\" | \"interrupted\" | \"timed_out\" | \"no_tasks\";\n\nexport interface TasksWaitDetails {\n\tkind?: TaskKind;\n\taction: \"wait\";\n\t/** Absent only in historical results; new calls always record the reason the wait ended. */\n\toutcome?: TasksWaitOutcome;\n\t/** Undefined for waitAny with no selected task, or when no tasks were running. */\n\ttaskId?: string;\n\t/** Retained for compatibility with historical details; true only for a wait-window expiry. */\n\ttimedOut: boolean;\n\tstatus?: TaskStatus;\n\texitCode: number | null | undefined;\n\twaitedMs: number;\n\tdeltaBytes: number;\n\ttotalBytes: number;\n\tdeltaTruncated: boolean;\n\toutputPath: string;\n\t/** Initial waitAny cohort members still running when the wait ended. */\n\trunning?: number;\n}\n\nexport interface TasksKillDetails {\n\trequested?: boolean;\n\tstatus?: TaskStatus;\n\taction: \"kill\";\n\ttaskId: string;\n\tcommand: string;\n}\n\nexport interface TasksListDetails {\n\taction: \"list\";\n\trunning: number;\n\tfinished: number;\n\tshown: number;\n\thidden: number;\n\t/** Foreground executions omitted from the listing; they deliver inline in the transcript. */\n\tforegroundOmitted?: number;\n}\n\nexport type TasksDetails = TasksReadDetails | TasksKillDetails | TasksListDetails | TasksWaitDetails;\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ToolDefinition } from "../../core/extensions/types.ts";
|
|
2
|
+
import { tasksSchema } from "./tool/schema.ts";
|
|
3
|
+
import type { TasksDetails } from "./tool/types.ts";
|
|
4
|
+
import { type TasksRenderState } from "./ui/render.ts";
|
|
5
|
+
export declare function createTasksToolDefinition(): ToolDefinition<typeof tasksSchema, TasksDetails, TasksRenderState>;
|
|
6
|
+
//# sourceMappingURL=tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../../src/extensions/tasks/tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAErE,OAAO,EAAyE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACtH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAsC,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAE3F,wBAAgB,yBAAyB,IAAI,cAAc,CAAC,OAAO,WAAW,EAAE,YAAY,EAAE,gBAAgB,CAAC,CAoC9G"}
|