@bastani/atomic 0.8.4 → 0.8.5-0
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 +6 -0
- package/README.md +24 -23
- package/dist/builtin/intercom/README.md +5 -5
- package/dist/builtin/intercom/index.ts +1 -1
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/intercom/ui/compose.ts +19 -1
- package/dist/builtin/intercom/ui/session-list.ts +19 -1
- package/dist/builtin/mcp/README.md +3 -3
- package/dist/builtin/mcp/commands.ts +1 -1
- package/dist/builtin/mcp/host-html-template.ts +1 -1
- package/dist/builtin/mcp/mcp-panel.ts +14 -14
- package/dist/builtin/mcp/mcp-setup-panel.ts +4 -4
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/mcp/tool-result-renderer.ts +1 -1
- package/dist/builtin/subagents/README.md +3 -3
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/src/tui/render.ts +1844 -1062
- package/dist/builtin/web-access/README.md +1 -1
- package/dist/builtin/web-access/curator-page.ts +2 -2
- package/dist/builtin/web-access/index.ts +1 -1
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/README.md +34 -7
- package/dist/builtin/workflows/builtin/deep-research-codebase.ts +23 -4
- package/dist/builtin/workflows/builtin/ralph.ts +1 -1
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/skills/workflow/SKILL.md +75 -16
- package/dist/builtin/workflows/skills/workflow/references/running-workflows.md +34 -11
- package/dist/builtin/workflows/skills/workflow/references/sdk-authoring.md +111 -20
- package/dist/builtin/workflows/src/extension/discovery.ts +32 -4
- package/dist/builtin/workflows/src/extension/index.ts +347 -63
- package/dist/builtin/workflows/src/extension/render-call.ts +3 -1
- package/dist/builtin/workflows/src/extension/render-result.ts +7 -0
- package/dist/builtin/workflows/src/extension/runtime.ts +4 -2
- package/dist/builtin/workflows/src/extension/wiring.ts +32 -8
- package/dist/builtin/workflows/src/extension/workflow-schema.ts +36 -14
- package/dist/builtin/workflows/src/runs/background/runner.ts +2 -2
- package/dist/builtin/workflows/src/runs/background/status.ts +89 -0
- package/dist/builtin/workflows/src/runs/foreground/executor.ts +338 -78
- package/dist/builtin/workflows/src/runs/foreground/stage-control-registry.ts +2 -0
- package/dist/builtin/workflows/src/runs/foreground/stage-runner.ts +55 -7
- package/dist/builtin/workflows/src/runs/shared/workflow-runner.ts +146 -10
- package/dist/builtin/workflows/src/shared/store.ts +29 -0
- package/dist/builtin/workflows/src/shared/types.ts +25 -4
- package/dist/builtin/workflows/src/tui/graph-canvas.ts +69 -2
- package/dist/builtin/workflows/src/tui/graph-view.ts +97 -182
- package/dist/builtin/workflows/src/tui/header.ts +36 -20
- package/dist/builtin/workflows/src/tui/inline-form-card.ts +129 -46
- package/dist/builtin/workflows/src/tui/inline-form-editor.ts +111 -36
- package/dist/builtin/workflows/src/tui/inputs-picker.ts +311 -91
- package/dist/builtin/workflows/src/tui/layout.ts +1 -1
- package/dist/builtin/workflows/src/tui/node-card.ts +66 -37
- package/dist/builtin/workflows/src/tui/overlay-adapter.ts +20 -6
- package/dist/builtin/workflows/src/tui/prompt-card.ts +262 -85
- package/dist/builtin/workflows/src/tui/run-detail.ts +50 -31
- package/dist/builtin/workflows/src/tui/session-confirm.ts +21 -14
- package/dist/builtin/workflows/src/tui/session-picker.ts +35 -26
- package/dist/builtin/workflows/src/tui/stage-chat-view.ts +531 -960
- package/dist/builtin/workflows/src/tui/status-helpers.ts +6 -0
- package/dist/builtin/workflows/src/tui/status-list.ts +8 -4
- package/dist/builtin/workflows/src/tui/store-widget-installer.ts +7 -2
- package/dist/builtin/workflows/src/tui/switcher.ts +55 -25
- package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +33 -1
- package/dist/builtin/workflows/src/tui/workflow-list.ts +10 -6
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +1 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +20 -6
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +3 -3
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +7 -7
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts +2 -2
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +3 -3
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
- package/dist/core/export-html/tool-renderer.js.map +1 -1
- package/dist/core/extensions/loader.d.ts +3 -2
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +24 -12
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +6 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +28 -17
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/package-manager.d.ts +1 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +65 -28
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +13 -5
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts +3 -3
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +1 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +2 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +1 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +5 -3
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/ask-user-question/view/components/preview/preview-block-renderer.d.ts +1 -1
- package/dist/core/tools/ask-user-question/view/components/preview/preview-block-renderer.d.ts.map +1 -1
- package/dist/core/tools/ask-user-question/view/components/preview/preview-block-renderer.js +1 -1
- package/dist/core/tools/ask-user-question/view/components/preview/preview-block-renderer.js.map +1 -1
- package/dist/core/tools/ask-user-question/view/dialog-builder.d.ts +8 -8
- package/dist/core/tools/ask-user-question/view/dialog-builder.d.ts.map +1 -1
- package/dist/core/tools/ask-user-question/view/dialog-builder.js +6 -6
- package/dist/core/tools/ask-user-question/view/dialog-builder.js.map +1 -1
- 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/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +1 -1
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +7 -4
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts +3 -2
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +3 -2
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +2 -2
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts +2 -1
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/todos.d.ts.map +1 -1
- package/dist/core/tools/todos.js +1 -1
- package/dist/core/tools/todos.js.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts +4 -3
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +1 -1
- package/dist/core/tools/write.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +2 -2
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +3 -3
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +3 -3
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/chat-message-renderer.d.ts +2 -1
- package/dist/modes/interactive/components/chat-message-renderer.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-message-renderer.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +1 -1
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +3 -0
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +13 -3
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +1 -1
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +2 -1
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +2 -1
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts +1 -0
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js +47 -5
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +5 -5
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +3 -3
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts +2 -2
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +7 -7
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +8 -8
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +3 -3
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js +2 -2
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +10 -12
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +3 -3
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/working-status.d.ts +25 -0
- package/dist/modes/interactive/components/working-status.d.ts.map +1 -0
- package/dist/modes/interactive/components/working-status.js +28 -0
- package/dist/modes/interactive/components/working-status.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +8 -7
- 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 +8 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +5 -5
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js.map +1 -1
- package/docs/development.md +2 -2
- package/docs/extensions.md +7 -7
- package/docs/packages.md +11 -8
- package/docs/quickstart.md +2 -2
- package/docs/rpc.md +1 -1
- package/docs/sdk.md +14 -11
- package/docs/session-format.md +1 -1
- package/docs/sessions.md +10 -10
- package/docs/settings.md +1 -1
- package/docs/terminal-setup.md +9 -9
- package/docs/tmux.md +10 -10
- package/docs/tui.md +2 -2
- package/docs/usage.md +9 -9
- package/package.json +6 -1
|
@@ -4,14 +4,13 @@
|
|
|
4
4
|
* Visual contract (DESIGN.md §5):
|
|
5
5
|
* - Rounded border `╭╮╰╯` only. No square or ASCII art.
|
|
6
6
|
* - Border colour carries status. `running` pulses via sine lerp
|
|
7
|
-
* against the dim border (focus locks the pulse). `
|
|
8
|
-
* `failed` stay status-coloured regardless of focus.
|
|
9
|
-
* sits on `borderDim` and lifts to `borderActive` when focused.
|
|
7
|
+
* against the dim border (focus locks the pulse). `paused`,
|
|
8
|
+
* `completed` / `failed` stay status-coloured regardless of focus.
|
|
9
|
+
* `pending` sits on `borderDim` and lifts to `borderActive` when focused.
|
|
10
10
|
* - When focused, the centred title segment becomes a compact accent
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* no resize.
|
|
11
|
+
* tab painted with `theme.accent` bg + `theme.surface` fg + bold.
|
|
12
|
+
* The tab is the only focus signal — the surrounding border is
|
|
13
|
+
* reserved for status. No `[focused]` text, no glow, no resize.
|
|
15
14
|
* - Single centred duration line in the body, coloured by status.
|
|
16
15
|
*
|
|
17
16
|
* Reuses the existing `paint(...)` color-utils helper (a thin wrapper
|
|
@@ -28,8 +27,9 @@
|
|
|
28
27
|
|
|
29
28
|
import type { StageSnapshot, StageStatus } from "../shared/store-types.js";
|
|
30
29
|
import type { GraphTheme } from "./graph-theme.js";
|
|
31
|
-
import { fmtDuration } from "./status-helpers.js";
|
|
30
|
+
import { fmtDuration, statusIcon } from "./status-helpers.js";
|
|
32
31
|
import { lerpColor, hexToAnsi, hexBg, paint, RESET, BOLD } from "./color-utils.js";
|
|
32
|
+
import { truncateToWidth, visibleWidth } from "./text-helpers.js";
|
|
33
33
|
import { NODE_W, NODE_H } from "./layout.js";
|
|
34
34
|
|
|
35
35
|
export interface NodeCardOpts {
|
|
@@ -43,11 +43,6 @@ export interface NodeCardOpts {
|
|
|
43
43
|
stages?: readonly StageSnapshot[];
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
/** Glyph that prefixes the focused-tab title; matches the compact
|
|
47
|
-
* cursor `❯` vocabulary used elsewhere but rotated to fit inline
|
|
48
|
-
* inside the top border (`▸` reads as a small wedge in the slot). */
|
|
49
|
-
const FOCUS_TAB_GLYPH = "▸";
|
|
50
|
-
|
|
51
46
|
/** Sine-eased pulse `t ∈ [0, 1]`. Phase 0 ≈ quiet, 0.5 ≈ peak. */
|
|
52
47
|
function pulseT(phase: number): number {
|
|
53
48
|
return (Math.sin(phase * Math.PI * 2 - Math.PI / 2) + 1) / 2;
|
|
@@ -64,6 +59,8 @@ function pickBorder(
|
|
|
64
59
|
// Focus locks the pulse at peak. Status colour wins either way.
|
|
65
60
|
if (focused) return theme.warning;
|
|
66
61
|
return lerpColor(theme.borderDim, theme.warning, pulseT(phase));
|
|
62
|
+
case "paused":
|
|
63
|
+
return theme.warning;
|
|
67
64
|
case "awaiting_input":
|
|
68
65
|
if (focused) return theme.info;
|
|
69
66
|
return lerpColor(theme.borderDim, theme.info, pulseT(phase));
|
|
@@ -85,6 +82,8 @@ function durationColor(status: StageStatus, theme: GraphTheme): string {
|
|
|
85
82
|
switch (status) {
|
|
86
83
|
case "running":
|
|
87
84
|
return theme.warning;
|
|
85
|
+
case "paused":
|
|
86
|
+
return theme.warning;
|
|
88
87
|
case "awaiting_input":
|
|
89
88
|
return theme.info;
|
|
90
89
|
case "completed":
|
|
@@ -107,7 +106,7 @@ function blockedBadgeText(
|
|
|
107
106
|
|
|
108
107
|
const upstream = stages?.find((s) => s.id === blockedBy)?.name ?? blockedBy;
|
|
109
108
|
const withUpstream = `${base} by ${upstream}`;
|
|
110
|
-
if (withUpstream
|
|
109
|
+
if (visibleWidth(withUpstream) <= width) return withUpstream;
|
|
111
110
|
return base;
|
|
112
111
|
}
|
|
113
112
|
|
|
@@ -117,10 +116,28 @@ function durationText(stage: StageSnapshot): string {
|
|
|
117
116
|
return "—";
|
|
118
117
|
}
|
|
119
118
|
|
|
120
|
-
function
|
|
121
|
-
if (
|
|
122
|
-
|
|
123
|
-
|
|
119
|
+
function metaText(stage: StageSnapshot): string {
|
|
120
|
+
if (stage.model) return stage.model;
|
|
121
|
+
const deps = stage.parentIds.length;
|
|
122
|
+
if (deps === 0) return "root";
|
|
123
|
+
return deps === 1 ? "1 dep" : `${deps} deps`;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function statusLabel(status: StageStatus): string {
|
|
127
|
+
switch (status) {
|
|
128
|
+
case "awaiting_input":
|
|
129
|
+
return "awaiting input";
|
|
130
|
+
case "completed":
|
|
131
|
+
return "complete";
|
|
132
|
+
default:
|
|
133
|
+
return status.replace(/_/g, " ");
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function truncate(s: string, maxWidth: number): string {
|
|
138
|
+
if (maxWidth <= 0) return "";
|
|
139
|
+
if (visibleWidth(s) <= maxWidth) return s;
|
|
140
|
+
return truncateToWidth(s, maxWidth, "…");
|
|
124
141
|
}
|
|
125
142
|
|
|
126
143
|
/**
|
|
@@ -138,7 +155,8 @@ function centreColored(
|
|
|
138
155
|
opts: { bold?: boolean } = {},
|
|
139
156
|
): string {
|
|
140
157
|
const safe = truncate(content, width);
|
|
141
|
-
const
|
|
158
|
+
const safeWidth = visibleWidth(safe);
|
|
159
|
+
const pad = Math.max(0, width - safeWidth);
|
|
142
160
|
const left = Math.max(0, Math.floor(pad / 2));
|
|
143
161
|
const right = Math.max(0, pad - left);
|
|
144
162
|
const bold = opts.bold ? BOLD : "";
|
|
@@ -155,7 +173,7 @@ function centreColored(
|
|
|
155
173
|
* width so the caller can pad the surrounding dashes correctly.
|
|
156
174
|
*
|
|
157
175
|
* When `focused`, the slot reads as a small accent-coloured tab:
|
|
158
|
-
* `╭──
|
|
176
|
+
* `╭── stage ──╮`
|
|
159
177
|
* Otherwise it falls back to the historical bold-title shape:
|
|
160
178
|
* `╭── stage ──╮`
|
|
161
179
|
*
|
|
@@ -171,25 +189,23 @@ function buildTitleSlot(
|
|
|
171
189
|
theme: GraphTheme,
|
|
172
190
|
cardBg: string,
|
|
173
191
|
): { slot: string; visibleWidth: number } {
|
|
174
|
-
const
|
|
175
|
-
const maxName = Math.max(2, innerWidth - 4 - overhead);
|
|
192
|
+
const maxName = Math.max(2, innerWidth - 4);
|
|
176
193
|
const safeName = truncate(name, maxName);
|
|
177
194
|
if (focused) {
|
|
178
|
-
//
|
|
179
|
-
//
|
|
180
|
-
//
|
|
181
|
-
//
|
|
182
|
-
|
|
183
|
-
const tabText = ` ${FOCUS_TAB_GLYPH} ${safeName} `;
|
|
195
|
+
// Flanking spaces sit on the accent tab so the pill reads as a
|
|
196
|
+
// single coloured run. Use `paint` to combine bg + fg + bold +
|
|
197
|
+
// RESET in one ANSI sequence, then re-prime the card stratum so
|
|
198
|
+
// the dashes outside the slot stay on the body bg.
|
|
199
|
+
const tabText = ` ${safeName} `;
|
|
184
200
|
const styled = `${paint(tabText, theme.surface, {
|
|
185
201
|
bg: theme.accent,
|
|
186
202
|
bold: true,
|
|
187
203
|
})}${cardBg}`;
|
|
188
|
-
return { slot: styled, visibleWidth: tabText
|
|
204
|
+
return { slot: styled, visibleWidth: visibleWidth(tabText) };
|
|
189
205
|
}
|
|
190
206
|
const titleRaw = ` ${safeName} `;
|
|
191
207
|
const styled = `${BOLD}${titleRaw}${RESET}${cardBg}`;
|
|
192
|
-
return { slot: styled, visibleWidth: titleRaw
|
|
208
|
+
return { slot: styled, visibleWidth: visibleWidth(titleRaw) };
|
|
193
209
|
}
|
|
194
210
|
|
|
195
211
|
/**
|
|
@@ -213,8 +229,8 @@ export function renderNodeCard(stage: StageSnapshot, opts: NodeCardOpts): string
|
|
|
213
229
|
const bg = hexBg(theme.bg);
|
|
214
230
|
const innerWidth = Math.max(2, width - 2);
|
|
215
231
|
|
|
216
|
-
// Title sits inside the top border
|
|
217
|
-
//
|
|
232
|
+
// Title sits inside the top border. Focus adds an accent-coloured
|
|
233
|
+
// pill to the name slot without adding an extra glyph.
|
|
218
234
|
const { slot: titleSlot, visibleWidth: titleVisibleWidth } = buildTitleSlot(
|
|
219
235
|
stage.name,
|
|
220
236
|
innerWidth,
|
|
@@ -231,25 +247,38 @@ export function renderNodeCard(stage: StageSnapshot, opts: NodeCardOpts): string
|
|
|
231
247
|
const top = `${bg}${bc}╭${topMiddle}╮${RESET}`;
|
|
232
248
|
const bottom = `${bg}${bc}╰${"─".repeat(innerWidth)}╯${RESET}`;
|
|
233
249
|
|
|
234
|
-
// Interior —
|
|
235
|
-
//
|
|
236
|
-
// the
|
|
250
|
+
// Interior — compact status + duration. Each `│` border is followed
|
|
251
|
+
// by a `bg`-primed centred run so the inner cells stay on the card
|
|
252
|
+
// stratum without leaving the cards visually hollow.
|
|
237
253
|
const bodyText =
|
|
238
254
|
stage.status === "blocked"
|
|
239
255
|
? blockedBadgeText(stage, opts.stages, innerWidth)
|
|
256
|
+
: stage.status === "paused"
|
|
257
|
+
? "❚❚ paused"
|
|
240
258
|
: durationText(stage);
|
|
241
259
|
const bodyHex = durationColor(stage.status, theme);
|
|
260
|
+
const statusText = `${statusIcon(stage.status)} ${statusLabel(stage.status)}`;
|
|
261
|
+
const statusLine =
|
|
262
|
+
`${bg}${bc}│${RESET}` +
|
|
263
|
+
centreColored(statusText, innerWidth, bodyHex, bg, {
|
|
264
|
+
bold: stage.status === "running" || stage.status === "awaiting_input",
|
|
265
|
+
}) +
|
|
266
|
+
`${bg}${bc}│${RESET}`;
|
|
242
267
|
const durLine =
|
|
243
268
|
`${bg}${bc}│${RESET}` +
|
|
244
269
|
centreColored(bodyText, innerWidth, bodyHex, bg, {
|
|
245
270
|
bold: stage.status === "blocked",
|
|
246
271
|
}) +
|
|
247
272
|
`${bg}${bc}│${RESET}`;
|
|
273
|
+
const metaLine =
|
|
274
|
+
`${bg}${bc}│${RESET}` +
|
|
275
|
+
centreColored(metaText(stage), innerWidth, theme.dim, bg) +
|
|
276
|
+
`${bg}${bc}│${RESET}`;
|
|
248
277
|
|
|
249
278
|
const interior: string[] =
|
|
250
279
|
stage.status === "awaiting_input"
|
|
251
280
|
? [
|
|
252
|
-
|
|
281
|
+
statusLine,
|
|
253
282
|
`${bg}${bc}│${RESET}` +
|
|
254
283
|
centreColored("waiting for response", innerWidth, theme.info, bg) +
|
|
255
284
|
`${bg}${bc}│${RESET}`,
|
|
@@ -257,7 +286,7 @@ export function renderNodeCard(stage: StageSnapshot, opts: NodeCardOpts): string
|
|
|
257
286
|
centreColored("↵ enter to respond", innerWidth, theme.dim, bg) +
|
|
258
287
|
`${bg}${bc}│${RESET}`,
|
|
259
288
|
]
|
|
260
|
-
: [durLine];
|
|
289
|
+
: [durLine, statusLine, metaLine];
|
|
261
290
|
|
|
262
291
|
// Pad / clip to exactly `height` lines.
|
|
263
292
|
const contentRows = Math.max(0, height - 2);
|
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import type { Store } from "../shared/store.js";
|
|
19
|
-
import type { ChatMessageRenderOptions } from "@bastani/atomic";
|
|
19
|
+
import type { ChatMessageRenderOptions, ReadonlyFooterDataProvider } from "@bastani/atomic";
|
|
20
20
|
import { WorkflowAttachPane } from "./workflow-attach-pane.js";
|
|
21
21
|
import { deriveGraphThemeFromPiTheme } from "./graph-theme.js";
|
|
22
|
-
import {
|
|
22
|
+
import { destroyRun } from "../runs/background/status.js";
|
|
23
23
|
import { cancellationRegistry } from "../runs/background/cancellation-registry.js";
|
|
24
24
|
import { stageControlRegistry as defaultStageControlRegistry } from "../runs/foreground/stage-control-registry.js";
|
|
25
25
|
import type { StageControlRegistry } from "../runs/foreground/stage-control-registry.js";
|
|
@@ -41,6 +41,7 @@ export interface OverlayUISurface {
|
|
|
41
41
|
custom?: PiCustomOverlayFunction;
|
|
42
42
|
getEditorComponent?: () => PiEditorFactory | undefined;
|
|
43
43
|
getChatRenderSettings?: () => OverlayChatRenderSettings | undefined;
|
|
44
|
+
getFooterDataProvider?: () => ReadonlyFooterDataProvider;
|
|
44
45
|
}
|
|
45
46
|
|
|
46
47
|
export interface OverlayPiSurface {
|
|
@@ -104,6 +105,12 @@ export interface BuildGraphOverlayAdapterOpts {
|
|
|
104
105
|
* Defaults to the singleton registry registered alongside the store.
|
|
105
106
|
*/
|
|
106
107
|
stageControlRegistry?: StageControlRegistry;
|
|
108
|
+
/**
|
|
109
|
+
* Destructive kill hook used by graph-mode `q`. The extension factory
|
|
110
|
+
* supplies this so persistence can record a terminal event before the run is
|
|
111
|
+
* removed from live history/status.
|
|
112
|
+
*/
|
|
113
|
+
onKillRun?: (runId: string) => void;
|
|
107
114
|
}
|
|
108
115
|
|
|
109
116
|
export function buildGraphOverlayAdapter(
|
|
@@ -112,6 +119,9 @@ export function buildGraphOverlayAdapter(
|
|
|
112
119
|
buildOpts: BuildGraphOverlayAdapterOpts = {},
|
|
113
120
|
): GraphOverlayPort {
|
|
114
121
|
const registry = buildOpts.stageControlRegistry ?? defaultStageControlRegistry;
|
|
122
|
+
const killRun = buildOpts.onKillRun ?? ((id: string): void => {
|
|
123
|
+
destroyRun(id, { store, cancellation: cancellationRegistry });
|
|
124
|
+
});
|
|
115
125
|
let currentView: WorkflowAttachPane | null = null;
|
|
116
126
|
// pi-tui returns an OverlayHandle via `options.onHandle`. We hold onto
|
|
117
127
|
// it so toggle() can flip `setHidden` rather than remounting the
|
|
@@ -192,12 +202,17 @@ export function buildGraphOverlayAdapter(
|
|
|
192
202
|
): void {
|
|
193
203
|
// Already mounted but hidden — flip visibility without remounting.
|
|
194
204
|
if (mounted && currentHandle?.isHidden()) {
|
|
205
|
+
currentView?.retarget(runId, stageId);
|
|
195
206
|
setMouseScrollTracking(currentView?.wantsMouseScrollTracking() ?? true);
|
|
196
207
|
currentHandle.setHidden(false);
|
|
197
208
|
currentHandle.focus();
|
|
198
209
|
return;
|
|
199
210
|
}
|
|
200
|
-
if (mounted)
|
|
211
|
+
if (mounted) {
|
|
212
|
+
currentView?.retarget(runId, stageId);
|
|
213
|
+
setMouseScrollTracking(currentView?.wantsMouseScrollTracking() ?? true);
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
201
216
|
|
|
202
217
|
const ui = surface?.ui ?? pi.ui;
|
|
203
218
|
const custom = ui?.custom;
|
|
@@ -230,15 +245,14 @@ export function buildGraphOverlayAdapter(
|
|
|
230
245
|
uiStatus,
|
|
231
246
|
onClose: finish,
|
|
232
247
|
onHide: hideMounted,
|
|
233
|
-
onKill:
|
|
234
|
-
killRun(id, { store, cancellation: cancellationRegistry });
|
|
235
|
-
},
|
|
248
|
+
onKill: killRun,
|
|
236
249
|
initialAttachStageId: stageId,
|
|
237
250
|
piTui: tui,
|
|
238
251
|
piTheme: theme,
|
|
239
252
|
piKeybindings: keybindings,
|
|
240
253
|
piEditorFactory: ui?.getEditorComponent?.(),
|
|
241
254
|
getChatRenderSettings: ui?.getChatRenderSettings,
|
|
255
|
+
footerData: ui?.getFooterDataProvider?.(),
|
|
242
256
|
// Pi-tui owns terminal dimensions; thread its row count down
|
|
243
257
|
// so the overlay frame fills the actual viewport rather than
|
|
244
258
|
// a hard-coded 32-row rectangle. Returning `undefined` keeps
|