@astralyn/pi 0.84.5 → 0.84.7
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 +35 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +4 -0
- package/dist/core/agent-session.js.map +1 -1
- 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/runner.d.ts +1 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +6 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +11 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/tools/bash.d.ts +5 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +1 -1
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/extensions/background/index.d.ts +95 -20
- package/dist/extensions/background/index.d.ts.map +1 -1
- package/dist/extensions/background/index.js +470 -136
- package/dist/extensions/background/index.js.map +1 -1
- package/dist/extensions/background/manager.d.ts +14 -0
- package/dist/extensions/background/manager.d.ts.map +1 -1
- package/dist/extensions/background/manager.js +125 -24
- package/dist/extensions/background/manager.js.map +1 -1
- package/dist/extensions/background/registry.d.ts +82 -0
- package/dist/extensions/background/registry.d.ts.map +1 -1
- package/dist/extensions/background/registry.js +237 -6
- package/dist/extensions/background/registry.js.map +1 -1
- package/dist/extensions/background/render.d.ts +35 -11
- package/dist/extensions/background/render.d.ts.map +1 -1
- package/dist/extensions/background/render.js +180 -30
- package/dist/extensions/background/render.js.map +1 -1
- package/dist/extensions/router/dialog-host.d.ts +60 -0
- package/dist/extensions/router/dialog-host.d.ts.map +1 -0
- package/dist/extensions/router/dialog-host.js +196 -0
- package/dist/extensions/router/dialog-host.js.map +1 -0
- package/dist/extensions/router/probe.d.ts.map +1 -1
- package/dist/extensions/router/probe.js +2 -0
- package/dist/extensions/router/probe.js.map +1 -1
- package/dist/extensions/router/ui.d.ts.map +1 -1
- package/dist/extensions/router/ui.js +117 -67
- package/dist/extensions/router/ui.js.map +1 -1
- package/dist/extensions/subagent/activity.d.ts +3 -5
- package/dist/extensions/subagent/activity.d.ts.map +1 -1
- package/dist/extensions/subagent/activity.js +8 -89
- package/dist/extensions/subagent/activity.js.map +1 -1
- package/dist/extensions/subagent/agents-command.d.ts.map +1 -1
- package/dist/extensions/subagent/agents-command.js +391 -161
- package/dist/extensions/subagent/agents-command.js.map +1 -1
- package/dist/extensions/subagent/agents.d.ts +2 -0
- package/dist/extensions/subagent/agents.d.ts.map +1 -1
- package/dist/extensions/subagent/agents.js +7 -1
- package/dist/extensions/subagent/agents.js.map +1 -1
- package/dist/extensions/subagent/budget.d.ts +15 -0
- package/dist/extensions/subagent/budget.d.ts.map +1 -0
- package/dist/extensions/subagent/budget.js +96 -0
- package/dist/extensions/subagent/budget.js.map +1 -0
- package/dist/extensions/subagent/cancellation.d.ts +29 -0
- package/dist/extensions/subagent/cancellation.d.ts.map +1 -0
- package/dist/extensions/subagent/cancellation.js +73 -0
- package/dist/extensions/subagent/cancellation.js.map +1 -0
- package/dist/extensions/subagent/index.d.ts.map +1 -1
- package/dist/extensions/subagent/index.js +5 -22
- package/dist/extensions/subagent/index.js.map +1 -1
- package/dist/extensions/subagent/model-selection.d.ts +16 -0
- package/dist/extensions/subagent/model-selection.d.ts.map +1 -0
- package/dist/extensions/subagent/model-selection.js +51 -0
- package/dist/extensions/subagent/model-selection.js.map +1 -0
- package/dist/extensions/subagent/render.d.ts +6 -1
- package/dist/extensions/subagent/render.d.ts.map +1 -1
- package/dist/extensions/subagent/render.js +23 -12
- package/dist/extensions/subagent/render.js.map +1 -1
- package/dist/extensions/subagent/resolve.d.ts.map +1 -1
- package/dist/extensions/subagent/resolve.js +2 -21
- package/dist/extensions/subagent/resolve.js.map +1 -1
- package/dist/extensions/subagent/runner.d.ts +4 -5
- package/dist/extensions/subagent/runner.d.ts.map +1 -1
- package/dist/extensions/subagent/runner.js +71 -264
- package/dist/extensions/subagent/runner.js.map +1 -1
- package/dist/extensions/subagent/sdk-runner.d.ts +13 -11
- package/dist/extensions/subagent/sdk-runner.d.ts.map +1 -1
- package/dist/extensions/subagent/sdk-runner.js +167 -148
- package/dist/extensions/subagent/sdk-runner.js.map +1 -1
- package/dist/extensions/subagent/settings.d.ts.map +1 -1
- package/dist/extensions/subagent/settings.js +11 -4
- package/dist/extensions/subagent/settings.js.map +1 -1
- package/dist/extensions/subagent/state.d.ts +89 -0
- package/dist/extensions/subagent/state.d.ts.map +1 -0
- package/dist/extensions/subagent/state.js +294 -0
- package/dist/extensions/subagent/state.js.map +1 -0
- package/dist/extensions/subagent/text.d.ts +4 -0
- package/dist/extensions/subagent/text.d.ts.map +1 -1
- package/dist/extensions/subagent/text.js +75 -0
- package/dist/extensions/subagent/text.js.map +1 -1
- package/dist/extensions/subagent/types.d.ts +3 -8
- package/dist/extensions/subagent/types.d.ts.map +1 -1
- package/dist/extensions/subagent/types.js.map +1 -1
- package/dist/extensions/subagent/ui/choices.d.ts +36 -0
- package/dist/extensions/subagent/ui/choices.d.ts.map +1 -0
- package/dist/extensions/subagent/ui/choices.js +54 -0
- package/dist/extensions/subagent/ui/choices.js.map +1 -0
- package/dist/extensions/subagent/ui/model-list.d.ts +1 -0
- package/dist/extensions/subagent/ui/model-list.d.ts.map +1 -1
- package/dist/extensions/subagent/ui/model-list.js +15 -18
- package/dist/extensions/subagent/ui/model-list.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/docs/bundled/README.md +1 -1
- package/docs/bundled/extensions/background.md +55 -20
- package/docs/extensions.md +13 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/dist/extensions/subagent/retry.d.ts +0 -17
- package/dist/extensions/subagent/retry.d.ts.map +0 -1
- package/dist/extensions/subagent/retry.js +0 -41
- package/dist/extensions/subagent/retry.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../src/extensions/background/manager.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * /bg task manager — an inline, /model-style menu that mounts in the editor\n * slot. Two views in one component: a task list, and a live output viewport\n * for the selected task (Enter to open, Esc to go back). The host dependency\n * is narrowed to three callbacks so the component stays testable.\n */\n\nimport { type Component, type Focusable, stripTerminalSequences, truncateToWidth } from \"@earendil-works/pi-tui\";\nimport type { KeybindingsManager } from \"../../core/keybindings.ts\";\nimport { formatSize } from \"../../core/tools/truncate.ts\";\nimport { keyLabel } from \"../../modes/interactive/components/keybinding-hints.ts\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { sanitizeBinaryOutput } from \"../../utils/shell.ts\";\nimport { type BgTask, firstCommandLine, formatDuration, type OutputSlice } from \"./registry.ts\";\nimport { statusColor, statusGlyph } from \"./render.ts\";\n\nconst POLL_INTERVAL_MS = 1000;\nconst VIEW_TAIL_BYTES = 128 * 1024;\nconst MAX_VIEW_LINES = 2000;\nconst LIST_MAX_VISIBLE = 10;\n\nexport interface BackgroundManagerHost {\n\tlistTasks(): BgTask[];\n\tkillTask(id: string): { killed: boolean };\n\treadSlice(filePath: string, options: { mode: \"tail\"; maxBytes: number }): Promise<OutputSlice>;\n}\n\ninterface MenuTui {\n\trequestRender(): void;\n\tterminal: { rows: number; columns: number };\n}\n\nexport interface BackgroundTasksMenuOptions {\n\ttui: MenuTui;\n\ttheme: Theme;\n\tkeybindings: Pick<KeybindingsManager, \"matches\" | \"getKeys\">;\n\thost: BackgroundManagerHost;\n\tonClose: () => void;\n\tpollIntervalMs?: number;\n}\n\ninterface TailCache {\n\ttaskId: string;\n\tlines: string[];\n\ttotalBytes: number;\n\terror?: string;\n}\n\n/** Truncate to an exact visible width, padding short lines with spaces. */\nfunction padLine(line: string, width: number): string {\n\treturn truncateToWidth(line, width, \"…\", true);\n}\n\nexport class BackgroundTasksMenu implements Component, Focusable {\n\tprivate readonly tui: MenuTui;\n\tprivate readonly theme: Theme;\n\tprivate readonly keybindings: Pick<KeybindingsManager, \"matches\" | \"getKeys\">;\n\tprivate readonly host: BackgroundManagerHost;\n\tprivate readonly onClose: () => void;\n\tprivate readonly pollIntervalMs: number;\n\n\tprivate view: \"list\" | \"detail\" = \"list\";\n\tprivate tasks: BgTask[] = [];\n\tprivate selectedTaskId: string | undefined;\n\tprivate listScrollTop = 0;\n\tprivate follow = true;\n\tprivate tailOffsetLines = 0;\n\tprivate tailCache: TailCache | undefined;\n\tprivate killFeedback: string | undefined;\n\tprivate pollTimer: ReturnType<typeof setInterval> | undefined;\n\tprivate readBusy = false;\n\tprivate disposed = false;\n\tprivate _focused = false;\n\n\tconstructor(options: BackgroundTasksMenuOptions) {\n\t\tthis.tui = options.tui;\n\t\tthis.theme = options.theme;\n\t\tthis.keybindings = options.keybindings;\n\t\tthis.host = options.host;\n\t\tthis.onClose = options.onClose;\n\t\tthis.pollIntervalMs = options.pollIntervalMs ?? POLL_INTERVAL_MS;\n\n\t\tthis.tasks = this.host.listTasks();\n\t\tthis.selectedTaskId = this.tasks[0]?.id;\n\t\tvoid this.tick();\n\t\tthis.pollTimer = setInterval(() => void this.tick(), this.pollIntervalMs);\n\t}\n\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t}\n\n\tinvalidate(): void {\n\t\t// No cached render state; the poller drives refresh.\n\t}\n\n\tdispose(): void {\n\t\tthis.disposed = true;\n\t\tif (this.pollTimer !== undefined) {\n\t\t\tclearInterval(this.pollTimer);\n\t\t\tthis.pollTimer = undefined;\n\t\t}\n\t}\n\n\thandleInput(data: string): void {\n\t\tthis.killFeedback = undefined;\n\t\tif (this.keybindings.matches(data, \"tui.select.cancel\")) {\n\t\t\tif (this.view === \"detail\") {\n\t\t\t\tthis.view = \"list\";\n\t\t\t\tthis.tui.requestRender();\n\t\t\t} else {\n\t\t\t\tthis.onClose();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (this.keybindings.matches(data, \"app.backgroundTasks.kill\")) {\n\t\t\tthis.killSelected();\n\t\t\treturn;\n\t\t}\n\t\tif (this.view === \"list\") this.handleListInput(data);\n\t\telse this.handleDetailInput(data);\n\t}\n\n\tprivate handleListInput(data: string): void {\n\t\tif (this.keybindings.matches(data, \"tui.select.up\")) {\n\t\t\tthis.moveSelection(-1);\n\t\t\treturn;\n\t\t}\n\t\tif (this.keybindings.matches(data, \"tui.select.down\")) {\n\t\t\tthis.moveSelection(1);\n\t\t\treturn;\n\t\t}\n\t\tif (this.keybindings.matches(data, \"tui.select.confirm\")) {\n\t\t\tif (!this.selectedTask()) return;\n\t\t\tthis.view = \"detail\";\n\t\t\tthis.resetFollow();\n\t\t\tthis.tui.requestRender();\n\t\t}\n\t}\n\n\tprivate handleDetailInput(data: string): void {\n\t\tif (this.keybindings.matches(data, \"tui.select.pageUp\")) {\n\t\t\tconst max = this.maxTailOffset();\n\t\t\tif (max === 0) return; // Nothing above the viewport to scroll back to.\n\t\t\tconst page = Math.max(1, this.detailBodyHeight());\n\t\t\tthis.follow = false;\n\t\t\tthis.tailOffsetLines = Math.min(max, this.tailOffsetLines + page);\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\t\tif (this.keybindings.matches(data, \"tui.select.pageDown\")) {\n\t\t\tif (this.follow) return;\n\t\t\tconst page = Math.max(1, this.detailBodyHeight());\n\t\t\tthis.tailOffsetLines = Math.max(0, this.tailOffsetLines - page);\n\t\t\tif (this.tailOffsetLines === 0) {\n\t\t\t\tthis.follow = true;\n\t\t\t\tvoid this.refreshViewport();\n\t\t\t}\n\t\t\tthis.tui.requestRender();\n\t\t}\n\t}\n\n\trender(width: number): string[] {\n\t\tconst body = this.view === \"list\" ? this.renderList(width) : this.renderDetail(width);\n\t\tconst border = this.theme.fg(\"border\", \"─\".repeat(Math.max(1, width)));\n\t\treturn [border, ...body, padLine(this.footerLine(), width), border];\n\t}\n\n\t// ── list view ──────────────────────────────────────────────────────────\n\n\tprivate renderList(width: number): string[] {\n\t\tconst lines: string[] = [];\n\t\tconst counts = this.countsLabel();\n\t\tconst title = counts ? `Background tasks — ${counts}` : \"Background tasks\";\n\t\tlines.push(padLine(this.theme.fg(\"accent\", this.theme.bold(title)), width));\n\n\t\tif (this.tasks.length === 0) {\n\t\t\tlines.push(padLine(this.theme.fg(\"muted\", \" (no tasks)\"), width));\n\t\t\treturn lines;\n\t\t}\n\n\t\tconst selected = this.selectedTask();\n\t\tconst visible = this.tasks.slice(this.listScrollTop, this.listScrollTop + LIST_MAX_VISIBLE);\n\t\tfor (const task of visible) {\n\t\t\tlines.push(this.renderTaskRow(task, task === selected, width));\n\t\t}\n\t\tif (this.tasks.length > LIST_MAX_VISIBLE) {\n\t\t\tconst index = this.tasks.findIndex((task) => task.id === this.selectedTaskId);\n\t\t\tlines.push(padLine(this.theme.fg(\"muted\", ` (${index + 1}/${this.tasks.length})`), width));\n\t\t}\n\t\treturn lines;\n\t}\n\n\tprivate renderTaskRow(task: BgTask, isSelected: boolean, width: number): string {\n\t\tconst duration = formatDuration((task.endedAt ?? Date.now()) - task.startedAt);\n\t\tconst command = firstCommandLine(task.command);\n\t\tif (isSelected) {\n\t\t\t// Pad to full width before styling so the selection background spans the row.\n\t\t\tconst plain = padLine(`→ ${statusGlyph(task.status)} ${task.id} ${duration} ${command}`, width);\n\t\t\treturn this.theme.bg(\"selectedBg\", this.theme.fg(\"text\", plain));\n\t\t}\n\t\tconst glyph = this.theme.fg(statusColor(task.status), statusGlyph(task.status));\n\t\tconst id = this.theme.fg(\"accent\", task.id);\n\t\tconst rest = this.theme.fg(\"muted\", `${duration} ${command}`);\n\t\treturn padLine(` ${glyph} ${id} ${rest}`, width);\n\t}\n\n\tprivate countsLabel(): string {\n\t\tlet running = 0;\n\t\tfor (const task of this.tasks) if (task.status === \"running\") running++;\n\t\tconst ended = this.tasks.length - running;\n\t\tconst parts: string[] = [];\n\t\tif (running > 0) parts.push(`${running} running`);\n\t\tif (ended > 0) parts.push(`${ended} done`);\n\t\treturn parts.join(\" · \");\n\t}\n\n\t// ── detail view ────────────────────────────────────────────────────────\n\n\tprivate renderDetail(width: number): string[] {\n\t\tconst task = this.selectedTask();\n\t\tconst lines: string[] = [padLine(this.detailHeader(task), width)];\n\t\tconst height = this.detailBodyHeight();\n\t\tconst cache = task && this.tailCache?.taskId === task.id ? this.tailCache : undefined;\n\t\tif (cache?.error) {\n\t\t\tlines.push(padLine(this.theme.fg(\"error\", `Cannot read output: ${cache.error}`), width));\n\t\t\tfor (let row = 1; row < height; row++) lines.push(padLine(\"\", width));\n\t\t\treturn lines;\n\t\t}\n\t\tconst content = cache?.lines ?? [];\n\t\tconst fromEnd = this.follow ? 0 : this.tailOffsetLines;\n\t\tconst start = content.length - height - fromEnd;\n\t\tfor (let row = 0; row < height; row++) {\n\t\t\tconst line = content[start + row];\n\t\t\tlines.push(line === undefined ? padLine(\"\", width) : padLine(this.theme.fg(\"toolOutput\", line), width));\n\t\t}\n\t\treturn lines;\n\t}\n\n\tprivate detailHeader(task: BgTask | undefined): string {\n\t\tif (!task) return this.theme.fg(\"muted\", \"(no task selected)\");\n\t\tconst duration = formatDuration((task.endedAt ?? Date.now()) - task.startedAt);\n\t\tconst exit = task.exitCode !== undefined && task.exitCode !== null ? ` exit ${task.exitCode}` : \"\";\n\t\tconst paused = this.follow ? \"\" : \" — paused (PgDn to follow)\";\n\t\tconst fileName = task.outputPath.replace(/\\\\/g, \"/\").split(\"/\").at(-1) ?? task.outputPath;\n\t\tconst glyph = this.theme.fg(statusColor(task.status), statusGlyph(task.status));\n\t\tconst header = `${task.id} · ${task.status}${exit} · ${duration} · ${formatSize(task.outputBytes)} · ${fileName}${paused}`;\n\t\treturn `${glyph} ${this.theme.fg(\"muted\", header)}`;\n\t}\n\n\tprivate detailBodyHeight(): number {\n\t\t// Inline component: keep the chat transcript visible above the menu.\n\t\treturn Math.min(20, Math.max(4, this.tui.terminal.rows - 8));\n\t}\n\n\t// ── shared behavior ────────────────────────────────────────────────────\n\n\tprivate footerLine(): string {\n\t\tif (this.killFeedback) return this.theme.fg(\"warning\", this.killFeedback);\n\t\tconst opts = { keybindings: this.keybindings };\n\t\tconst parts =\n\t\t\tthis.view === \"list\"\n\t\t\t\t? [\n\t\t\t\t\t\t`${keyLabel(\"tui.select.up\", opts)}/${keyLabel(\"tui.select.down\", opts)} select`,\n\t\t\t\t\t\t`${keyLabel(\"tui.select.confirm\", opts)} output`,\n\t\t\t\t\t\t`${keyLabel(\"app.backgroundTasks.kill\", opts)} kill`,\n\t\t\t\t\t\t`${keyLabel(\"tui.select.cancel\", opts)} close`,\n\t\t\t\t\t]\n\t\t\t\t: [\n\t\t\t\t\t\t`${keyLabel(\"tui.select.pageUp\", opts)}/${keyLabel(\"tui.select.pageDown\", opts)} scroll`,\n\t\t\t\t\t\t`${keyLabel(\"app.backgroundTasks.kill\", opts)} kill`,\n\t\t\t\t\t\t`${keyLabel(\"tui.select.cancel\", opts)} back`,\n\t\t\t\t\t];\n\t\treturn this.theme.fg(\"dim\", parts.join(\" · \"));\n\t}\n\n\tprivate selectedTask(): BgTask | undefined {\n\t\treturn this.tasks.find((task) => task.id === this.selectedTaskId);\n\t}\n\n\tprivate moveSelection(offset: -1 | 1): void {\n\t\tif (this.tasks.length === 0) return;\n\t\tconst current = this.tasks.findIndex((task) => task.id === this.selectedTaskId);\n\t\tconst next = (current + offset + this.tasks.length) % this.tasks.length;\n\t\tconst task = this.tasks[next];\n\t\tif (!task) return;\n\t\tthis.selectedTaskId = task.id;\n\t\tif (next < this.listScrollTop) this.listScrollTop = next;\n\t\tif (next >= this.listScrollTop + LIST_MAX_VISIBLE) this.listScrollTop = next - LIST_MAX_VISIBLE + 1;\n\t\tthis.resetFollow();\n\t\tthis.tui.requestRender();\n\t}\n\n\tprivate resetFollow(): void {\n\t\tthis.follow = true;\n\t\tthis.tailOffsetLines = 0;\n\t\tthis.tailCache = undefined;\n\t\tvoid this.refreshViewport();\n\t}\n\n\tprivate currentLines(): string[] {\n\t\tconst task = this.selectedTask();\n\t\tconst cache = this.tailCache;\n\t\treturn task && cache && cache.taskId === task.id ? cache.lines : [];\n\t}\n\n\tprivate maxTailOffset(): number {\n\t\treturn Math.max(0, this.currentLines().length - this.detailBodyHeight());\n\t}\n\n\tprivate killSelected(): void {\n\t\tconst task = this.selectedTask();\n\t\tif (!task) return;\n\t\tif (task.status !== \"running\") {\n\t\t\tthis.killFeedback = `${task.id} is not running`;\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\t\tthis.host.killTask(task.id);\n\t\tthis.killFeedback = `killed ${task.id}`;\n\t\tthis.tui.requestRender();\n\t}\n\n\tprivate async tick(): Promise<void> {\n\t\tif (this.disposed) return;\n\t\tthis.tasks = this.host.listTasks();\n\t\tif (!this.selectedTask() && this.tasks[0]) this.selectedTaskId = this.tasks[0].id;\n\t\tif (this.view === \"detail\" && this.follow) await this.refreshViewport();\n\t\tthis.tui.requestRender();\n\t}\n\n\tprivate async refreshViewport(): Promise<void> {\n\t\tif (this.readBusy) return;\n\t\tconst task = this.selectedTask();\n\t\tif (!task) return;\n\t\tthis.readBusy = true;\n\t\ttry {\n\t\t\tconst slice = await this.host.readSlice(task.outputPath, { mode: \"tail\", maxBytes: VIEW_TAIL_BYTES });\n\t\t\tif (this.disposed || this.selectedTaskId !== task.id || !this.follow) return;\n\t\t\tthis.tailCache = { taskId: task.id, lines: toViewLines(slice.text), totalBytes: slice.totalBytes };\n\t\t} catch (error) {\n\t\t\tif (this.disposed || this.selectedTaskId !== task.id) return;\n\t\t\tthis.tailCache = {\n\t\t\t\ttaskId: task.id,\n\t\t\t\tlines: [],\n\t\t\t\ttotalBytes: task.outputBytes,\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t};\n\t\t} finally {\n\t\t\tthis.readBusy = false;\n\t\t}\n\t}\n}\n\nfunction toViewLines(text: string): string[] {\n\t// Strip ANSI first: sanitize would remove the escape bytes alone, leaving\n\t// orphaned \"[31m\" fragments that strip can no longer see.\n\tconst lines = sanitizeBinaryOutput(stripTerminalSequences(text)).split(\"\\n\");\n\t// Drop the trailing empty line produced by a final newline, then bound the\n\t// window: a 128KB slice of one-byte lines must never become 128k rows.\n\twhile (lines.length > 0 && lines[lines.length - 1] === \"\") lines.pop();\n\treturn lines.slice(-MAX_VIEW_LINES);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../src/extensions/background/manager.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * /bg task manager — an inline, /model-style menu that mounts in the editor\n * slot. Two views in one component: a task list, and a live output viewport\n * for the selected task (Enter to open, Esc to go back). The host dependency\n * is narrowed to three callbacks so the component stays testable.\n */\n\nimport { type Component, type Focusable, stripTerminalSequences, truncateToWidth } from \"@earendil-works/pi-tui\";\nimport type { KeybindingsManager } from \"../../core/keybindings.ts\";\nimport { formatSize } from \"../../core/tools/truncate.ts\";\nimport { keyLabel } from \"../../modes/interactive/components/keybinding-hints.ts\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { sanitizeBinaryOutput } from \"../../utils/shell.ts\";\nimport { type BgTask, firstCommandLine, formatDuration, type OutputSlice } from \"./registry.ts\";\nimport { statusColor, statusGlyph } from \"./render.ts\";\n\nconst POLL_INTERVAL_MS = 1000;\nconst VIEW_TAIL_BYTES = 128 * 1024;\nconst MAX_VIEW_LINES = 2000;\nconst LIST_MAX_VISIBLE = 10;\nconst LIST_MIN_VISIBLE = 3;\n/** Rows outside the task list itself (borders, title, counter, footer, padding). */\nconst LIST_RESERVED_ROWS = 14;\n\nexport interface BackgroundManagerHost {\n\tlistTasks(): BgTask[];\n\tkillTask(id: string): { killed: boolean };\n\treadSlice(filePath: string, options: { mode: \"tail\"; maxBytes: number }): Promise<OutputSlice>;\n}\n\ninterface MenuTui {\n\trequestRender(): void;\n\tterminal: { rows: number; columns: number };\n}\n\nexport interface BackgroundTasksMenuOptions {\n\ttui: MenuTui;\n\ttheme: Theme;\n\tkeybindings: Pick<KeybindingsManager, \"matches\" | \"getKeys\">;\n\thost: BackgroundManagerHost;\n\tonClose: () => void;\n\tpollIntervalMs?: number;\n}\n\ninterface TailCache {\n\ttaskId: string;\n\tlines: string[];\n\ttotalBytes: number;\n\t/** True once a terminal task's final output has been read; skips re-reads. */\n\tsettledRead?: boolean;\n\terror?: string;\n}\n\n/** Truncate to an exact visible width, padding short lines with spaces. */\nfunction padLine(line: string, width: number): string {\n\treturn truncateToWidth(line, width, \"…\", true);\n}\n\nexport class BackgroundTasksMenu implements Component, Focusable {\n\tprivate readonly tui: MenuTui;\n\tprivate readonly theme: Theme;\n\tprivate readonly keybindings: Pick<KeybindingsManager, \"matches\" | \"getKeys\">;\n\tprivate readonly host: BackgroundManagerHost;\n\tprivate readonly onClose: () => void;\n\tprivate readonly pollIntervalMs: number;\n\n\tprivate view: \"list\" | \"detail\" = \"list\";\n\tprivate tasks: BgTask[] = [];\n\tprivate selectedTaskId: string | undefined;\n\tprivate listScrollTop = 0;\n\tprivate follow = true;\n\tprivate tailOffsetLines = 0;\n\tprivate tailCache: TailCache | undefined;\n\tprivate killFeedback: string | undefined;\n\t/** Task whose settle expires killFeedback; undefined = persists until the next key. */\n\tprivate killFeedbackTaskId: string | undefined;\n\t/** Last tick's render signature; unchanged means nothing visible moved. */\n\tprivate lastSignature = \"\";\n\tprivate pollTimer: ReturnType<typeof setInterval> | undefined;\n\tprivate readBusy = false;\n\tprivate disposed = false;\n\tprivate _focused = false;\n\n\tconstructor(options: BackgroundTasksMenuOptions) {\n\t\tthis.tui = options.tui;\n\t\tthis.theme = options.theme;\n\t\tthis.keybindings = options.keybindings;\n\t\tthis.host = options.host;\n\t\tthis.onClose = options.onClose;\n\t\tthis.pollIntervalMs = options.pollIntervalMs ?? POLL_INTERVAL_MS;\n\n\t\tthis.tasks = this.host.listTasks();\n\t\tthis.selectedTaskId = this.tasks[0]?.id;\n\t\tvoid this.tick();\n\t\tthis.pollTimer = setInterval(() => void this.tick(), this.pollIntervalMs);\n\t}\n\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t}\n\n\tinvalidate(): void {\n\t\t// No cached render state; the poller drives refresh.\n\t}\n\n\tdispose(): void {\n\t\tthis.disposed = true;\n\t\tif (this.pollTimer !== undefined) {\n\t\t\tclearInterval(this.pollTimer);\n\t\t\tthis.pollTimer = undefined;\n\t\t}\n\t}\n\n\thandleInput(data: string): void {\n\t\tif (this.killFeedback !== undefined) {\n\t\t\tthis.killFeedback = undefined;\n\t\t\tthis.killFeedbackTaskId = undefined;\n\t\t\tthis.tui.requestRender();\n\t\t}\n\t\tif (this.keybindings.matches(data, \"tui.select.cancel\")) {\n\t\t\tif (this.view === \"detail\") {\n\t\t\t\tthis.view = \"list\";\n\t\t\t\tthis.tui.requestRender();\n\t\t\t} else {\n\t\t\t\tthis.onClose();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (this.keybindings.matches(data, \"app.backgroundTasks.kill\")) {\n\t\t\tthis.killSelected();\n\t\t\treturn;\n\t\t}\n\t\tif (this.view === \"list\") this.handleListInput(data);\n\t\telse this.handleDetailInput(data);\n\t}\n\n\tprivate handleListInput(data: string): void {\n\t\tif (this.keybindings.matches(data, \"tui.select.up\")) {\n\t\t\tthis.moveSelection(-1);\n\t\t\treturn;\n\t\t}\n\t\tif (this.keybindings.matches(data, \"tui.select.down\")) {\n\t\t\tthis.moveSelection(1);\n\t\t\treturn;\n\t\t}\n\t\tif (this.keybindings.matches(data, \"tui.select.confirm\")) {\n\t\t\tif (!this.selectedTask()) return;\n\t\t\tthis.view = \"detail\";\n\t\t\tthis.resetFollow();\n\t\t\tthis.tui.requestRender();\n\t\t}\n\t}\n\n\tprivate handleDetailInput(data: string): void {\n\t\tif (this.keybindings.matches(data, \"tui.select.pageUp\")) {\n\t\t\tthis.scrollDetail(Math.max(1, this.detailBodyHeight()));\n\t\t\treturn;\n\t\t}\n\t\tif (this.keybindings.matches(data, \"tui.select.pageDown\")) {\n\t\t\tif (!this.follow) this.scrollDetail(-Math.max(1, this.detailBodyHeight()));\n\t\t\treturn;\n\t\t}\n\t\tif (this.keybindings.matches(data, \"tui.select.up\")) {\n\t\t\tthis.scrollDetail(1);\n\t\t\treturn;\n\t\t}\n\t\tif (this.keybindings.matches(data, \"tui.select.down\")) {\n\t\t\tif (!this.follow) this.scrollDetail(-1);\n\t\t}\n\t}\n\n\t/** Scroll the detail viewport by `lines` (positive = back through history). */\n\tprivate scrollDetail(lines: number): void {\n\t\tif (lines > 0) {\n\t\t\tconst max = this.maxTailOffset();\n\t\t\tif (max === 0) return; // Nothing above the viewport to scroll back to.\n\t\t\tthis.follow = false;\n\t\t\tthis.tailOffsetLines = Math.min(max, this.tailOffsetLines + lines);\n\t\t} else {\n\t\t\tif (this.follow) return;\n\t\t\tthis.tailOffsetLines = Math.max(0, this.tailOffsetLines + lines);\n\t\t\tif (this.tailOffsetLines === 0) {\n\t\t\t\tthis.follow = true;\n\t\t\t\tvoid this.refreshViewport();\n\t\t\t}\n\t\t}\n\t\tthis.tui.requestRender();\n\t}\n\n\trender(width: number): string[] {\n\t\tconst body = this.view === \"list\" ? this.renderList(width) : this.renderDetail(width);\n\t\tconst border = this.theme.fg(\"border\", \"─\".repeat(Math.max(1, width)));\n\t\treturn [border, ...body, padLine(this.footerLine(), width), border];\n\t}\n\n\t// ── list view ──────────────────────────────────────────────────────────\n\n\t/** Task rows the terminal can spare; short windows trade rows for the transcript. */\n\tprivate listMaxVisible(): number {\n\t\treturn Math.min(LIST_MAX_VISIBLE, Math.max(LIST_MIN_VISIBLE, this.tui.terminal.rows - LIST_RESERVED_ROWS));\n\t}\n\n\tprivate renderList(width: number): string[] {\n\t\tconst lines: string[] = [];\n\t\tconst counts = this.countsLabel();\n\t\tconst title = counts ? `Background tasks — ${counts}` : \"Background tasks\";\n\t\tlines.push(padLine(this.theme.fg(\"accent\", this.theme.bold(title)), width));\n\n\t\tif (this.tasks.length === 0) {\n\t\t\tlines.push(padLine(this.theme.fg(\"muted\", \" (no tasks)\"), width));\n\t\t\treturn lines;\n\t\t}\n\n\t\tconst selected = this.selectedTask();\n\t\tconst maxVisible = this.listMaxVisible();\n\t\tconst visible = this.tasks.slice(this.listScrollTop, this.listScrollTop + maxVisible);\n\t\tlet seenRunning = false;\n\t\tfor (const task of visible) {\n\t\t\t// listTasks() orders running first, finished after: one separator at the boundary.\n\t\t\tif (seenRunning && task.status !== \"running\") {\n\t\t\t\tlines.push(padLine(this.theme.fg(\"muted\", \" ── finished ──\"), width));\n\t\t\t\tseenRunning = false;\n\t\t\t}\n\t\t\tif (task.status === \"running\") seenRunning = true;\n\t\t\tlines.push(this.renderTaskRow(task, task === selected, width));\n\t\t}\n\t\tif (this.tasks.length > maxVisible) {\n\t\t\tconst index = this.tasks.findIndex((task) => task.id === this.selectedTaskId);\n\t\t\tlines.push(padLine(this.theme.fg(\"muted\", ` (${index + 1}/${this.tasks.length})`), width));\n\t\t}\n\t\treturn lines;\n\t}\n\n\tprivate renderTaskRow(task: BgTask, isSelected: boolean, width: number): string {\n\t\tconst duration = formatDuration((task.endedAt ?? Date.now()) - task.startedAt);\n\t\tconst label = task.description\n\t\t\t? `${task.description} — ${firstCommandLine(task.command)}`\n\t\t\t: firstCommandLine(task.command);\n\t\tif (isSelected) {\n\t\t\t// Pad to full width before styling so the selection background spans the row.\n\t\t\tconst plain = padLine(`→ ${statusGlyph(task.status, task.stalled)} ${task.id} ${duration} ${label}`, width);\n\t\t\treturn this.theme.bg(\"selectedBg\", this.theme.fg(\"text\", plain));\n\t\t}\n\t\tconst glyph = this.theme.fg(statusColor(task.status, task.stalled), statusGlyph(task.status, task.stalled));\n\t\tconst id = this.theme.fg(\"accent\", task.id);\n\t\tconst rest = this.theme.fg(\"muted\", `${duration} ${label}`);\n\t\treturn padLine(` ${glyph} ${id} ${rest}`, width);\n\t}\n\n\tprivate countsLabel(): string {\n\t\tlet running = 0;\n\t\tfor (const task of this.tasks) if (task.status === \"running\") running++;\n\t\tconst ended = this.tasks.length - running;\n\t\tconst parts: string[] = [];\n\t\tif (running > 0) parts.push(`${running} running`);\n\t\tif (ended > 0) parts.push(`${ended} done`);\n\t\treturn parts.join(\" · \");\n\t}\n\n\t// ── detail view ────────────────────────────────────────────────────────\n\n\tprivate renderDetail(width: number): string[] {\n\t\tconst task = this.selectedTask();\n\t\tconst lines: string[] = [padLine(this.detailHeader(task), width)];\n\t\tconst height = this.detailBodyHeight();\n\t\tconst cache = task && this.tailCache?.taskId === task.id ? this.tailCache : undefined;\n\t\tif (cache?.error) {\n\t\t\tlines.push(padLine(this.theme.fg(\"error\", `Cannot read output: ${cache.error}`), width));\n\t\t\tfor (let row = 1; row < height; row++) lines.push(padLine(\"\", width));\n\t\t\treturn lines;\n\t\t}\n\t\tconst content = cache?.lines ?? [];\n\t\tconst fromEnd = this.follow ? 0 : this.tailOffsetLines;\n\t\tconst start = content.length - height - fromEnd;\n\t\tfor (let row = 0; row < height; row++) {\n\t\t\tconst line = content[start + row];\n\t\t\tlines.push(line === undefined ? padLine(\"\", width) : padLine(this.theme.fg(\"toolOutput\", line), width));\n\t\t}\n\t\treturn lines;\n\t}\n\n\tprivate detailHeader(task: BgTask | undefined): string {\n\t\tif (!task) return this.theme.fg(\"muted\", \"(no task selected)\");\n\t\tconst duration = formatDuration((task.endedAt ?? Date.now()) - task.startedAt);\n\t\tconst exit = task.exitCode !== undefined && task.exitCode !== null ? ` exit ${task.exitCode}` : \"\";\n\t\tconst resumeLabel = keyLabel(\"tui.select.pageDown\", { keybindings: this.keybindings });\n\t\tconst paused = this.follow ? \"\" : resumeLabel ? ` — paused (${resumeLabel} to follow)` : \" — paused\";\n\t\tconst fileName = task.outputPath.replace(/\\\\/g, \"/\").split(\"/\").at(-1) ?? task.outputPath;\n\t\tconst glyph = this.theme.fg(statusColor(task.status, task.stalled), statusGlyph(task.status, task.stalled));\n\t\tconst statusLabel = task.stalled ? \"running, waiting for input\" : task.status;\n\t\tconst header = `${task.id} · ${statusLabel}${exit} · ${duration} · ${formatSize(task.outputBytes)} · ${fileName}${paused}`;\n\t\treturn `${glyph} ${this.theme.fg(\"muted\", header)}`;\n\t}\n\n\tprivate detailBodyHeight(): number {\n\t\t// Inline component: keep the chat transcript visible above the menu.\n\t\treturn Math.min(20, Math.max(4, this.tui.terminal.rows - 8));\n\t}\n\n\t// ── shared behavior ────────────────────────────────────────────────────\n\n\tprivate footerLine(): string {\n\t\tif (this.killFeedback) return this.theme.fg(\"warning\", this.killFeedback);\n\t\tconst opts = { keybindings: this.keybindings };\n\t\tconst parts =\n\t\t\tthis.view === \"list\"\n\t\t\t\t? [\n\t\t\t\t\t\t`${keyLabel(\"tui.select.up\", opts)}/${keyLabel(\"tui.select.down\", opts)} select`,\n\t\t\t\t\t\t`${keyLabel(\"tui.select.confirm\", opts)} output`,\n\t\t\t\t\t\t`${keyLabel(\"app.backgroundTasks.kill\", opts)} kill`,\n\t\t\t\t\t\t`${keyLabel(\"tui.select.cancel\", opts)} close`,\n\t\t\t\t\t]\n\t\t\t\t: [\n\t\t\t\t\t\t`${keyLabel(\"tui.select.up\", opts)}/${keyLabel(\"tui.select.down\", opts)} scroll`,\n\t\t\t\t\t\t`${keyLabel(\"tui.select.pageUp\", opts)}/${keyLabel(\"tui.select.pageDown\", opts)} page`,\n\t\t\t\t\t\t`${keyLabel(\"app.backgroundTasks.kill\", opts)} kill`,\n\t\t\t\t\t\t`${keyLabel(\"tui.select.cancel\", opts)} back`,\n\t\t\t\t\t];\n\t\treturn this.theme.fg(\"dim\", parts.join(\" · \"));\n\t}\n\n\tprivate selectedTask(): BgTask | undefined {\n\t\treturn this.tasks.find((task) => task.id === this.selectedTaskId);\n\t}\n\n\tprivate moveSelection(offset: -1 | 1): void {\n\t\tif (this.tasks.length === 0) return;\n\t\tconst current = this.tasks.findIndex((task) => task.id === this.selectedTaskId);\n\t\tconst next = (current + offset + this.tasks.length) % this.tasks.length;\n\t\tconst task = this.tasks[next];\n\t\tif (!task) return;\n\t\tthis.selectedTaskId = task.id;\n\t\tif (next < this.listScrollTop) this.listScrollTop = next;\n\t\tif (next >= this.listScrollTop + this.listMaxVisible()) {\n\t\t\tthis.listScrollTop = next - this.listMaxVisible() + 1;\n\t\t}\n\t\tthis.resetFollow();\n\t\tthis.tui.requestRender();\n\t}\n\n\tprivate resetFollow(): void {\n\t\tthis.follow = true;\n\t\tthis.tailOffsetLines = 0;\n\t\tthis.tailCache = undefined;\n\t\tvoid this.refreshViewport();\n\t}\n\n\tprivate currentLines(): string[] {\n\t\tconst task = this.selectedTask();\n\t\tconst cache = this.tailCache;\n\t\treturn task && cache && cache.taskId === task.id ? cache.lines : [];\n\t}\n\n\tprivate maxTailOffset(): number {\n\t\treturn Math.max(0, this.currentLines().length - this.detailBodyHeight());\n\t}\n\n\tprivate killSelected(): void {\n\t\tconst task = this.selectedTask();\n\t\tif (!task) return;\n\t\tif (task.status !== \"running\") {\n\t\t\tthis.killFeedback = `${task.id} is not running`;\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\t\tthis.host.killTask(task.id);\n\t\t// Terminal state lands on the next poll; the feedback expires with it (tick).\n\t\tthis.killFeedback = `stopping ${task.id}…`;\n\t\tthis.killFeedbackTaskId = task.id;\n\t\tthis.tui.requestRender();\n\t}\n\n\tprivate async tick(): Promise<void> {\n\t\tif (this.disposed) return;\n\t\tthis.tasks = this.host.listTasks();\n\t\tif (!this.selectedTask() && this.tasks[0]) this.selectedTaskId = this.tasks[0].id;\n\t\tthis.expireKillFeedback();\n\t\tif (this.renderSignature() === this.lastSignature) return; // Nothing visible changed.\n\t\tif (this.view === \"detail\" && this.follow && this.detailOutputChanged()) {\n\t\t\tawait this.refreshViewport();\n\t\t}\n\t\tthis.lastSignature = this.renderSignature();\n\t\tthis.tui.requestRender();\n\t}\n\n\t/** Drop \"stopping\" feedback once its task has settled. */\n\tprivate expireKillFeedback(): void {\n\t\tif (this.killFeedbackTaskId === undefined) return;\n\t\tconst task = this.tasks.find((candidate) => candidate.id === this.killFeedbackTaskId);\n\t\tif (!task || task.status !== \"running\") {\n\t\t\tthis.killFeedback = undefined;\n\t\t\tthis.killFeedbackTaskId = undefined;\n\t\t}\n\t}\n\n\t/** Everything the rendered output depends on; equal signatures need no redraw. */\n\tprivate renderSignature(): string {\n\t\tconst parts = [\n\t\t\tthis.view,\n\t\t\tthis.selectedTaskId ?? \"\",\n\t\t\tString(this.listScrollTop),\n\t\t\tString(this.follow),\n\t\t\tString(this.tailOffsetLines),\n\t\t\tthis.killFeedback ?? \"\",\n\t\t\tthis.tailCache\n\t\t\t\t? `${this.tailCache.taskId}:${this.tailCache.lines.length}:${this.tailCache.totalBytes}:${this.tailCache.error ?? \"\"}:${String(this.tailCache.settledRead ?? false)}`\n\t\t\t\t: \"\",\n\t\t];\n\t\tfor (const task of this.tasks) {\n\t\t\tconst duration = formatDuration((task.endedAt ?? Date.now()) - task.startedAt);\n\t\t\tparts.push(\n\t\t\t\t`${task.id}:${task.status}:${String(task.stalled)}:${task.outputBytes}:${task.exitCode ?? \"\"}:${duration}`,\n\t\t\t);\n\t\t}\n\t\treturn parts.join(\"|\");\n\t}\n\n\t/** True when the detail viewport must re-read the output file this tick. */\n\tprivate detailOutputChanged(): boolean {\n\t\tconst task = this.selectedTask();\n\t\tif (!task) return false;\n\t\tconst cache = this.tailCache;\n\t\tif (!cache || cache.taskId !== task.id) return true;\n\t\tif (cache.error !== undefined) return true; // Keep retrying; failed reads are cheap.\n\t\tif (task.status !== \"running\") {\n\t\t\t// Terminal task: the file is final — read it once, then never again.\n\t\t\treturn cache.settledRead !== true;\n\t\t}\n\t\treturn cache.totalBytes !== task.outputBytes;\n\t}\n\n\tprivate async refreshViewport(): Promise<void> {\n\t\tif (this.readBusy) return;\n\t\tconst task = this.selectedTask();\n\t\tif (!task) return;\n\t\tthis.readBusy = true;\n\t\ttry {\n\t\t\tconst slice = await this.host.readSlice(task.outputPath, { mode: \"tail\", maxBytes: VIEW_TAIL_BYTES });\n\t\t\tif (this.disposed || this.selectedTaskId !== task.id || !this.follow) return;\n\t\t\tthis.tailCache = {\n\t\t\t\ttaskId: task.id,\n\t\t\t\tlines: toViewLines(slice.text),\n\t\t\t\ttotalBytes: slice.totalBytes,\n\t\t\t\tsettledRead: task.status !== \"running\",\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tif (this.disposed || this.selectedTaskId !== task.id) return;\n\t\t\tthis.tailCache = {\n\t\t\t\ttaskId: task.id,\n\t\t\t\tlines: [],\n\t\t\t\ttotalBytes: task.outputBytes,\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t};\n\t\t} finally {\n\t\t\tthis.readBusy = false;\n\t\t}\n\t}\n}\n\nfunction toViewLines(text: string): string[] {\n\t// Strip ANSI first: sanitize would remove the escape bytes alone, leaving\n\t// orphaned \"[31m\" fragments that strip can no longer see.\n\tconst lines = sanitizeBinaryOutput(stripTerminalSequences(text)).split(\"\\n\");\n\t// Drop the trailing empty line produced by a final newline, then bound the\n\t// window: a 128KB slice of one-byte lines must never become 128k rows.\n\twhile (lines.length > 0 && lines[lines.length - 1] === \"\") lines.pop();\n\treturn lines.slice(-MAX_VIEW_LINES);\n}\n"]}
|
|
@@ -14,14 +14,27 @@ import type { BashOperations } from "../../core/tools/bash.ts";
|
|
|
14
14
|
export declare const DEFAULT_MAX_OUTPUT_BYTES: number;
|
|
15
15
|
export declare const DEFAULT_MAX_RUNNING_TASKS = 8;
|
|
16
16
|
export declare const DEFAULT_NOTIFY_TAIL_BYTES: number;
|
|
17
|
+
/** Wait-window bounds shared by execution and the pending-call renderer. */
|
|
18
|
+
export declare const BG_WAIT_DEFAULT_MS = 20000;
|
|
19
|
+
export declare const BG_WAIT_MIN_MS = 1000;
|
|
20
|
+
export declare const BG_WAIT_MAX_MS = 60000;
|
|
21
|
+
/** Stall watchdog defaults, matching Claude Code's CC-1175 tuning. */
|
|
22
|
+
export declare const STALL_POLL_INTERVAL_MS = 5000;
|
|
23
|
+
export declare const STALL_THRESHOLD_MS = 45000;
|
|
24
|
+
export declare const STALL_TAIL_BYTES = 1024;
|
|
25
|
+
export declare function looksLikePrompt(tail: string): boolean;
|
|
17
26
|
export type BgTaskStatus = "running" | "completed" | "failed" | "killed" | "timeout";
|
|
18
27
|
export interface BgTask {
|
|
19
28
|
id: string;
|
|
20
29
|
command: string;
|
|
30
|
+
/** Optional model-provided label (e.g. "dev server") shown in /bg and notifications. */
|
|
31
|
+
description?: string;
|
|
21
32
|
cwd: string;
|
|
22
33
|
status: BgTaskStatus;
|
|
23
34
|
startedAt: number;
|
|
24
35
|
endedAt?: number;
|
|
36
|
+
/** True when the stall watchdog flagged this task as waiting for input. */
|
|
37
|
+
stalled: boolean;
|
|
25
38
|
/** Process exit code; null when reaped by a signal, undefined while running or when spawn failed. */
|
|
26
39
|
exitCode: number | null | undefined;
|
|
27
40
|
outputPath: string;
|
|
@@ -44,6 +57,16 @@ export interface BgTaskNotification {
|
|
|
44
57
|
/** Set when the output file could not be read; the notification still fires. */
|
|
45
58
|
tailError?: string;
|
|
46
59
|
}
|
|
60
|
+
/** One-shot signal that a running task appears blocked on interactive input. */
|
|
61
|
+
export interface BgStallNotification {
|
|
62
|
+
task: BgTask;
|
|
63
|
+
tailText: string;
|
|
64
|
+
tailBytes: number;
|
|
65
|
+
totalBytes: number;
|
|
66
|
+
tailTruncated: boolean;
|
|
67
|
+
tailStartsMidLine: boolean;
|
|
68
|
+
tailError?: string;
|
|
69
|
+
}
|
|
47
70
|
export interface OutputSlice {
|
|
48
71
|
text: string;
|
|
49
72
|
sliceBytes: number;
|
|
@@ -53,6 +76,14 @@ export interface OutputSlice {
|
|
|
53
76
|
/** True in tail mode when the slice starts mid-line. */
|
|
54
77
|
startsMidLine: boolean;
|
|
55
78
|
}
|
|
79
|
+
/** Outcome of a bounded wait: terminal delivery, or the wait window expiring. */
|
|
80
|
+
export type WaitOutcome = {
|
|
81
|
+
outcome: "terminal";
|
|
82
|
+
task: BgTask;
|
|
83
|
+
} | {
|
|
84
|
+
outcome: "timeout";
|
|
85
|
+
task: BgTask;
|
|
86
|
+
};
|
|
56
87
|
/**
|
|
57
88
|
* Read a bounded slice from the head or tail of a file via positioned reads —
|
|
58
89
|
* never the whole file. Tail reads skip UTF-8 continuation bytes so the text
|
|
@@ -62,6 +93,15 @@ export declare function readOutputSlice(filePath: string, options: {
|
|
|
62
93
|
mode: "head" | "tail";
|
|
63
94
|
maxBytes: number;
|
|
64
95
|
}): Promise<OutputSlice>;
|
|
96
|
+
/**
|
|
97
|
+
* Read the last `maxBytes` of a file starting no earlier than `fromByte` — the
|
|
98
|
+
* bounded delta since an offset, tail-aligned so the outcome (at the end of
|
|
99
|
+
* the output) is always included. `fromByte` is clamped into the file; the
|
|
100
|
+
* returned `fromByte` is where the slice actually starts.
|
|
101
|
+
*/
|
|
102
|
+
export declare function readOutputSince(filePath: string, fromByte: number, maxBytes: number): Promise<OutputSlice & {
|
|
103
|
+
fromByte: number;
|
|
104
|
+
}>;
|
|
65
105
|
export interface BackgroundRegistryOptions {
|
|
66
106
|
operations: BashOperations;
|
|
67
107
|
/** Directory for task output files. Defaults to the system temp directory. */
|
|
@@ -71,6 +111,14 @@ export interface BackgroundRegistryOptions {
|
|
|
71
111
|
notifyTailBytes?: number;
|
|
72
112
|
/** Called once per finished task; a synchronous throw rolls back `notified`. */
|
|
73
113
|
onNotify: (notification: BgTaskNotification) => void;
|
|
114
|
+
/** Called at most once per task when its output stalls on an interactive-looking prompt. */
|
|
115
|
+
onStall?: (notification: BgStallNotification) => void;
|
|
116
|
+
/** Stall watchdog tuning (tests inject short windows); defaults follow Claude Code's CC-1175. */
|
|
117
|
+
stall?: {
|
|
118
|
+
pollIntervalMs?: number;
|
|
119
|
+
thresholdMs?: number;
|
|
120
|
+
tailBytes?: number;
|
|
121
|
+
};
|
|
74
122
|
/** Called whenever a task starts or reaches a terminal state. */
|
|
75
123
|
onChange: () => void;
|
|
76
124
|
now?: () => number;
|
|
@@ -90,6 +138,10 @@ export declare class BackgroundTaskRegistry {
|
|
|
90
138
|
private readonly maxRunningTasks;
|
|
91
139
|
private readonly notifyTailBytes;
|
|
92
140
|
private readonly onNotify;
|
|
141
|
+
private readonly onStall;
|
|
142
|
+
private readonly stallPollIntervalMs;
|
|
143
|
+
private readonly stallThresholdMs;
|
|
144
|
+
private readonly stallTailBytes;
|
|
93
145
|
private readonly onChange;
|
|
94
146
|
private readonly now;
|
|
95
147
|
private readonly tasks;
|
|
@@ -100,6 +152,7 @@ export declare class BackgroundTaskRegistry {
|
|
|
100
152
|
startTask(input: {
|
|
101
153
|
command: string;
|
|
102
154
|
cwd: string;
|
|
155
|
+
description?: string;
|
|
103
156
|
timeoutSeconds?: number;
|
|
104
157
|
env?: NodeJS.ProcessEnv;
|
|
105
158
|
}): BgTask;
|
|
@@ -116,14 +169,38 @@ export declare class BackgroundTaskRegistry {
|
|
|
116
169
|
};
|
|
117
170
|
counts(): Record<BgTaskStatus, number> & {
|
|
118
171
|
total: number;
|
|
172
|
+
stalled: number;
|
|
119
173
|
};
|
|
120
174
|
/** Resolves once the task has finalized, including its notification attempt. */
|
|
121
175
|
waitForTask(id: string): Promise<BgTask>;
|
|
176
|
+
/**
|
|
177
|
+
* Bounded model-facing wait with the claim protocol: a waiter registered
|
|
178
|
+
* when the task finalizes takes over delivery — finalize sees waiters > 0
|
|
179
|
+
* and suppresses the followUp notification, so the completion is delivered
|
|
180
|
+
* exactly once, inline here. If the window expires first, the followUp
|
|
181
|
+
* notification is left untouched and fires as usual.
|
|
182
|
+
*
|
|
183
|
+
* All interleavings are deterministic on JS's single thread: a waiter that
|
|
184
|
+
* registers before finalize's synchronous claim check claims delivery; one
|
|
185
|
+
* that arrives after sees a terminal status and returns it immediately
|
|
186
|
+
* (the followUp may also arrive — an idempotent repeat, not a lie).
|
|
187
|
+
*/
|
|
188
|
+
waitForResult(id: string, timeoutMs: number): Promise<WaitOutcome>;
|
|
122
189
|
/**
|
|
123
190
|
* Mute notifications, refuse new tasks, abort every running task, and wait
|
|
124
191
|
* (bounded) for their finalization.
|
|
125
192
|
*/
|
|
126
193
|
shutdown(): Promise<void>;
|
|
194
|
+
/**
|
|
195
|
+
* Stall watchdog (Claude Code CC-1175): poll the output file; when output
|
|
196
|
+
* stops growing past the threshold AND the tail looks like an interactive
|
|
197
|
+
* prompt, flag the task and fire a one-shot notification. Merely-slow tasks
|
|
198
|
+
* never match; recovery clears the flag (the notification never re-fires).
|
|
199
|
+
*/
|
|
200
|
+
private armStallWatchdog;
|
|
201
|
+
private clearStallWatchdog;
|
|
202
|
+
private checkStall;
|
|
203
|
+
private probeStallTail;
|
|
127
204
|
private newTaskId;
|
|
128
205
|
private run;
|
|
129
206
|
private handleData;
|
|
@@ -131,6 +208,11 @@ export declare class BackgroundTaskRegistry {
|
|
|
131
208
|
private classifyOutcome;
|
|
132
209
|
private notifyCompletion;
|
|
133
210
|
}
|
|
211
|
+
/**
|
|
212
|
+
* Create an empty output file exclusively ('wx'): fails on any existing path,
|
|
213
|
+
* including a symlink, so creation can never truncate what the path points at.
|
|
214
|
+
*/
|
|
215
|
+
export declare function createOutputFileExclusively(path: string): void;
|
|
134
216
|
/** First non-empty line of a command, trimmed — for one-line task labels. */
|
|
135
217
|
export declare function firstCommandLine(command: string): string;
|
|
136
218
|
/** Compact duration like Pi's own timers: 12s, 3m05s, 1h02m. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/extensions/background/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAOH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAI/D,eAAO,MAAM,wBAAwB,QAAmB,CAAC;AACzD,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAC3C,eAAO,MAAM,yBAAyB,QAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/extensions/background/registry.ts"],"names":[],"mappings":"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"}
|