gsd-pi 2.26.0 → 2.27.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/README.md +43 -6
- package/dist/cli.js +4 -2
- package/dist/headless.d.ts +3 -0
- package/dist/headless.js +136 -8
- package/dist/help-text.js +3 -0
- package/dist/loader.js +33 -4
- package/dist/resources/extensions/bg-shell/index.ts +19 -2
- package/dist/resources/extensions/bg-shell/process-manager.ts +45 -0
- package/dist/resources/extensions/bg-shell/types.ts +21 -1
- package/dist/resources/extensions/gsd/auto/session.ts +224 -0
- package/dist/resources/extensions/gsd/auto-budget.ts +32 -0
- package/dist/resources/extensions/gsd/auto-dashboard.ts +63 -10
- package/dist/resources/extensions/gsd/auto-direct-dispatch.ts +229 -0
- package/dist/resources/extensions/gsd/auto-dispatch.ts +23 -10
- package/dist/resources/extensions/gsd/auto-model-selection.ts +179 -0
- package/dist/resources/extensions/gsd/auto-observability.ts +74 -0
- package/dist/resources/extensions/gsd/auto-prompts.ts +0 -1
- package/dist/resources/extensions/gsd/auto-timeout-recovery.ts +262 -0
- package/dist/resources/extensions/gsd/auto-tool-tracking.ts +54 -0
- package/dist/resources/extensions/gsd/auto-unit-closeout.ts +46 -0
- package/dist/resources/extensions/gsd/auto-worktree-sync.ts +207 -0
- package/dist/resources/extensions/gsd/auto.ts +977 -1551
- package/dist/resources/extensions/gsd/commands.ts +3 -3
- package/dist/resources/extensions/gsd/dashboard-overlay.ts +47 -72
- package/dist/resources/extensions/gsd/doctor-proactive.ts +9 -4
- package/dist/resources/extensions/gsd/export-html.ts +1001 -0
- package/dist/resources/extensions/gsd/export.ts +49 -1
- package/dist/resources/extensions/gsd/git-service.ts +6 -0
- package/dist/resources/extensions/gsd/gitignore.ts +4 -1
- package/dist/resources/extensions/gsd/guided-flow.ts +24 -5
- package/dist/resources/extensions/gsd/index.ts +54 -1
- package/dist/resources/extensions/gsd/native-git-bridge.ts +30 -2
- package/dist/resources/extensions/gsd/observability-validator.ts +21 -0
- package/dist/resources/extensions/gsd/parallel-orchestrator.ts +231 -20
- package/dist/resources/extensions/gsd/preferences.ts +62 -1
- package/dist/resources/extensions/gsd/prompts/execute-task.md +4 -3
- package/dist/resources/extensions/gsd/prompts/system.md +1 -1
- package/dist/resources/extensions/gsd/reports.ts +510 -0
- package/dist/resources/extensions/gsd/roadmap-slices.ts +1 -1
- package/dist/resources/extensions/gsd/skills/gsd-headless/SKILL.md +178 -0
- package/dist/resources/extensions/gsd/skills/gsd-headless/references/answer-injection.md +54 -0
- package/dist/resources/extensions/gsd/skills/gsd-headless/references/commands.md +59 -0
- package/dist/resources/extensions/gsd/skills/gsd-headless/references/multi-session.md +185 -0
- package/dist/resources/extensions/gsd/state.ts +30 -0
- package/dist/resources/extensions/gsd/templates/task-summary.md +9 -0
- package/dist/resources/extensions/gsd/tests/auto-dashboard.test.ts +13 -0
- package/dist/resources/extensions/gsd/tests/continue-here.test.ts +81 -0
- package/dist/resources/extensions/gsd/tests/derive-state-db.test.ts +5 -0
- package/dist/resources/extensions/gsd/tests/derive-state-deps.test.ts +1 -0
- package/dist/resources/extensions/gsd/tests/derive-state-draft.test.ts +1 -0
- package/dist/resources/extensions/gsd/tests/derive-state.test.ts +10 -1
- package/dist/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +132 -0
- package/dist/resources/extensions/gsd/tests/doctor-proactive.test.ts +14 -0
- package/dist/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +1 -0
- package/dist/resources/extensions/gsd/tests/milestone-transition-worktree.test.ts +1 -1
- package/dist/resources/extensions/gsd/tests/native-has-changes-cache.test.ts +61 -0
- package/dist/resources/extensions/gsd/tests/network-error-fallback.test.ts +51 -1
- package/dist/resources/extensions/gsd/tests/parallel-budget-atomicity.test.ts +331 -0
- package/dist/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +298 -0
- package/dist/resources/extensions/gsd/tests/parallel-merge.test.ts +465 -0
- package/dist/resources/extensions/gsd/tests/parallel-orchestration.test.ts +39 -10
- package/dist/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +71 -0
- package/dist/resources/extensions/gsd/tests/replan-slice.test.ts +42 -0
- package/dist/resources/extensions/gsd/tests/triage-dispatch.test.ts +9 -9
- package/dist/resources/extensions/gsd/tests/verification-evidence.test.ts +743 -0
- package/dist/resources/extensions/gsd/tests/verification-gate.test.ts +965 -0
- package/dist/resources/extensions/gsd/tests/visualizer-data.test.ts +1 -1
- package/dist/resources/extensions/gsd/tests/visualizer-overlay.test.ts +44 -10
- package/dist/resources/extensions/gsd/tests/worktree.test.ts +3 -1
- package/dist/resources/extensions/gsd/types.ts +38 -0
- package/dist/resources/extensions/gsd/verification-evidence.ts +183 -0
- package/dist/resources/extensions/gsd/verification-gate.ts +567 -0
- package/dist/resources/extensions/gsd/visualizer-data.ts +25 -3
- package/dist/resources/extensions/gsd/visualizer-overlay.ts +31 -21
- package/dist/resources/extensions/gsd/visualizer-views.ts +15 -66
- package/dist/resources/extensions/search-the-web/tool-search.ts +26 -0
- package/dist/resources/extensions/shared/format-utils.ts +85 -0
- package/dist/resources/extensions/shared/tests/format-utils.test.ts +153 -0
- package/dist/resources/extensions/subagent/index.ts +46 -1
- package/dist/resources/extensions/subagent/isolation.ts +9 -6
- package/package.json +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.js +7 -4
- package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/packages/pi-ai/src/providers/openai-completions.ts +7 -4
- package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/client.js +7 -0
- package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/config.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/config.js +9 -2
- package/packages/pi-coding-agent/dist/core/lsp/config.js.map +1 -1
- package/packages/pi-coding-agent/src/core/lsp/client.ts +8 -0
- package/packages/pi-coding-agent/src/core/lsp/config.ts +9 -2
- package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/editor.js +1 -1
- package/packages/pi-tui/dist/components/editor.js.map +1 -1
- package/packages/pi-tui/src/components/editor.ts +3 -1
- package/scripts/link-workspace-packages.cjs +22 -6
- package/src/resources/extensions/bg-shell/index.ts +19 -2
- package/src/resources/extensions/bg-shell/process-manager.ts +45 -0
- package/src/resources/extensions/bg-shell/types.ts +21 -1
- package/src/resources/extensions/gsd/auto/session.ts +224 -0
- package/src/resources/extensions/gsd/auto-budget.ts +32 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +63 -10
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +229 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +23 -10
- package/src/resources/extensions/gsd/auto-model-selection.ts +179 -0
- package/src/resources/extensions/gsd/auto-observability.ts +74 -0
- package/src/resources/extensions/gsd/auto-prompts.ts +0 -1
- package/src/resources/extensions/gsd/auto-timeout-recovery.ts +262 -0
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +54 -0
- package/src/resources/extensions/gsd/auto-unit-closeout.ts +46 -0
- package/src/resources/extensions/gsd/auto-worktree-sync.ts +207 -0
- package/src/resources/extensions/gsd/auto.ts +977 -1551
- package/src/resources/extensions/gsd/commands.ts +3 -3
- package/src/resources/extensions/gsd/dashboard-overlay.ts +47 -72
- package/src/resources/extensions/gsd/doctor-proactive.ts +9 -4
- package/src/resources/extensions/gsd/export-html.ts +1001 -0
- package/src/resources/extensions/gsd/export.ts +49 -1
- package/src/resources/extensions/gsd/git-service.ts +6 -0
- package/src/resources/extensions/gsd/gitignore.ts +4 -1
- package/src/resources/extensions/gsd/guided-flow.ts +24 -5
- package/src/resources/extensions/gsd/index.ts +54 -1
- package/src/resources/extensions/gsd/native-git-bridge.ts +30 -2
- package/src/resources/extensions/gsd/observability-validator.ts +21 -0
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +231 -20
- package/src/resources/extensions/gsd/preferences.ts +62 -1
- package/src/resources/extensions/gsd/prompts/execute-task.md +4 -3
- package/src/resources/extensions/gsd/prompts/system.md +1 -1
- package/src/resources/extensions/gsd/reports.ts +510 -0
- package/src/resources/extensions/gsd/roadmap-slices.ts +1 -1
- package/src/resources/extensions/gsd/skills/gsd-headless/SKILL.md +178 -0
- package/src/resources/extensions/gsd/skills/gsd-headless/references/answer-injection.md +54 -0
- package/src/resources/extensions/gsd/skills/gsd-headless/references/commands.md +59 -0
- package/src/resources/extensions/gsd/skills/gsd-headless/references/multi-session.md +185 -0
- package/src/resources/extensions/gsd/state.ts +30 -0
- package/src/resources/extensions/gsd/templates/task-summary.md +9 -0
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +13 -0
- package/src/resources/extensions/gsd/tests/continue-here.test.ts +81 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +5 -0
- package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/derive-state-draft.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +10 -1
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +132 -0
- package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/milestone-transition-worktree.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/native-has-changes-cache.test.ts +61 -0
- package/src/resources/extensions/gsd/tests/network-error-fallback.test.ts +51 -1
- package/src/resources/extensions/gsd/tests/parallel-budget-atomicity.test.ts +331 -0
- package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +298 -0
- package/src/resources/extensions/gsd/tests/parallel-merge.test.ts +465 -0
- package/src/resources/extensions/gsd/tests/parallel-orchestration.test.ts +39 -10
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +71 -0
- package/src/resources/extensions/gsd/tests/replan-slice.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +9 -9
- package/src/resources/extensions/gsd/tests/verification-evidence.test.ts +743 -0
- package/src/resources/extensions/gsd/tests/verification-gate.test.ts +965 -0
- package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +44 -10
- package/src/resources/extensions/gsd/tests/worktree.test.ts +3 -1
- package/src/resources/extensions/gsd/types.ts +38 -0
- package/src/resources/extensions/gsd/verification-evidence.ts +183 -0
- package/src/resources/extensions/gsd/verification-gate.ts +567 -0
- package/src/resources/extensions/gsd/visualizer-data.ts +25 -3
- package/src/resources/extensions/gsd/visualizer-overlay.ts +31 -21
- package/src/resources/extensions/gsd/visualizer-views.ts +15 -66
- package/src/resources/extensions/search-the-web/tool-search.ts +26 -0
- package/src/resources/extensions/shared/format-utils.ts +85 -0
- package/src/resources/extensions/shared/tests/format-utils.test.ts +153 -0
- package/src/resources/extensions/subagent/index.ts +46 -1
- package/src/resources/extensions/subagent/isolation.ts +9 -6
|
@@ -86,7 +86,7 @@ export function registerGSDCommand(pi: ExtensionAPI): void {
|
|
|
86
86
|
{ cmd: "stop", desc: "Stop auto mode gracefully" },
|
|
87
87
|
{ cmd: "pause", desc: "Pause auto-mode (preserves state, /gsd auto to resume)" },
|
|
88
88
|
{ cmd: "status", desc: "Progress dashboard" },
|
|
89
|
-
{ cmd: "visualize", desc: "Open workflow visualizer (progress, deps, metrics,
|
|
89
|
+
{ cmd: "visualize", desc: "Open 10-tab workflow visualizer (progress, timeline, deps, metrics, health, agent, changes, knowledge, captures, export)" },
|
|
90
90
|
{ cmd: "queue", desc: "Queue and reorder future milestones" },
|
|
91
91
|
{ cmd: "quick", desc: "Execute a quick task without full planning overhead" },
|
|
92
92
|
{ cmd: "discuss", desc: "Discuss architecture and decisions" },
|
|
@@ -603,7 +603,7 @@ function showHelp(ctx: ExtensionCommandContext): void {
|
|
|
603
603
|
"",
|
|
604
604
|
"VISIBILITY",
|
|
605
605
|
" /gsd status Show progress dashboard (Ctrl+Alt+G)",
|
|
606
|
-
" /gsd visualize Interactive
|
|
606
|
+
" /gsd visualize Interactive 10-tab TUI (progress, timeline, deps, metrics, health, agent, changes, knowledge, captures, export)",
|
|
607
607
|
" /gsd queue Show queued/dispatched units and execution order",
|
|
608
608
|
" /gsd history View execution history [--cost] [--phase] [--model] [N]",
|
|
609
609
|
"",
|
|
@@ -625,7 +625,7 @@ function showHelp(ctx: ExtensionCommandContext): void {
|
|
|
625
625
|
"",
|
|
626
626
|
"MAINTENANCE",
|
|
627
627
|
" /gsd doctor Diagnose and repair .gsd/ state [audit|fix|heal] [scope]",
|
|
628
|
-
" /gsd export Export milestone/slice results [--json|--markdown]",
|
|
628
|
+
" /gsd export Export milestone/slice results [--json|--markdown|--html]",
|
|
629
629
|
" /gsd cleanup Remove merged branches or snapshots [branches|snapshots]",
|
|
630
630
|
" /gsd migrate Upgrade .gsd/ structures to new format",
|
|
631
631
|
" /gsd remote Control remote auto-mode [slack|discord|status|disconnect]",
|
|
@@ -20,17 +20,9 @@ import {
|
|
|
20
20
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
21
21
|
import { getActiveWorktreeName } from "./worktree-command.js";
|
|
22
22
|
import { getWorkerBatches, hasActiveWorkers, type WorkerEntry } from "../subagent/worker-registry.js";
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (s < 60) return `${s}s`;
|
|
27
|
-
const m = Math.floor(s / 60);
|
|
28
|
-
const rs = s % 60;
|
|
29
|
-
if (m < 60) return `${m}m ${rs}s`;
|
|
30
|
-
const h = Math.floor(m / 60);
|
|
31
|
-
const rm = m % 60;
|
|
32
|
-
return `${h}h ${rm}m`;
|
|
33
|
-
}
|
|
23
|
+
import { formatDuration, padRight, joinColumns, centerLine, fitColumns } from "../shared/format-utils.js";
|
|
24
|
+
import { STATUS_GLYPH, STATUS_COLOR } from "../shared/ui.js";
|
|
25
|
+
import { estimateTimeRemaining } from "./auto-dashboard.js";
|
|
34
26
|
|
|
35
27
|
function unitLabel(type: string): string {
|
|
36
28
|
switch (type) {
|
|
@@ -48,38 +40,6 @@ function unitLabel(type: string): string {
|
|
|
48
40
|
}
|
|
49
41
|
}
|
|
50
42
|
|
|
51
|
-
function centerLine(content: string, width: number): string {
|
|
52
|
-
const vis = visibleWidth(content);
|
|
53
|
-
if (vis >= width) return truncateToWidth(content, width);
|
|
54
|
-
const leftPad = Math.floor((width - vis) / 2);
|
|
55
|
-
return " ".repeat(leftPad) + content;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function padRight(content: string, width: number): string {
|
|
59
|
-
const vis = visibleWidth(content);
|
|
60
|
-
return content + " ".repeat(Math.max(0, width - vis));
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function joinColumns(left: string, right: string, width: number): string {
|
|
64
|
-
const leftW = visibleWidth(left);
|
|
65
|
-
const rightW = visibleWidth(right);
|
|
66
|
-
if (leftW + rightW + 2 > width) {
|
|
67
|
-
return truncateToWidth(`${left} ${right}`, width);
|
|
68
|
-
}
|
|
69
|
-
return left + " ".repeat(width - leftW - rightW) + right;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function fitColumns(parts: string[], width: number, separator = " "): string {
|
|
73
|
-
const filtered = parts.filter(Boolean);
|
|
74
|
-
if (filtered.length === 0) return "";
|
|
75
|
-
let result = filtered[0];
|
|
76
|
-
for (let i = 1; i < filtered.length; i++) {
|
|
77
|
-
const candidate = `${result}${separator}${filtered[i]}`;
|
|
78
|
-
if (visibleWidth(candidate) > width) break;
|
|
79
|
-
result = candidate;
|
|
80
|
-
}
|
|
81
|
-
return truncateToWidth(result, width);
|
|
82
|
-
}
|
|
83
43
|
|
|
84
44
|
export class GSDDashboardOverlay {
|
|
85
45
|
private tui: { requestRender: () => void };
|
|
@@ -95,6 +55,7 @@ export class GSDDashboardOverlay {
|
|
|
95
55
|
private loadedDashboardIdentity?: string;
|
|
96
56
|
private refreshInFlight: Promise<void> | null = null;
|
|
97
57
|
private disposed = false;
|
|
58
|
+
private resizeHandler: (() => void) | null = null;
|
|
98
59
|
|
|
99
60
|
constructor(
|
|
100
61
|
tui: { requestRender: () => void },
|
|
@@ -106,6 +67,14 @@ export class GSDDashboardOverlay {
|
|
|
106
67
|
this.onClose = onClose;
|
|
107
68
|
this.dashData = getAutoDashboardData();
|
|
108
69
|
|
|
70
|
+
// Invalidate cache on terminal resize
|
|
71
|
+
this.resizeHandler = () => {
|
|
72
|
+
if (this.disposed) return;
|
|
73
|
+
this.invalidate();
|
|
74
|
+
this.tui.requestRender();
|
|
75
|
+
};
|
|
76
|
+
process.stdout.on("resize", this.resizeHandler);
|
|
77
|
+
|
|
109
78
|
this.scheduleRefresh(true);
|
|
110
79
|
|
|
111
80
|
this.refreshTimer = setInterval(() => {
|
|
@@ -233,7 +202,7 @@ export class GSDDashboardOverlay {
|
|
|
233
202
|
|
|
234
203
|
handleInput(data: string): void {
|
|
235
204
|
if (matchesKey(data, Key.escape) || matchesKey(data, Key.ctrl("c")) || matchesKey(data, Key.ctrlAlt("g"))) {
|
|
236
|
-
|
|
205
|
+
this.dispose();
|
|
237
206
|
this.onClose();
|
|
238
207
|
return;
|
|
239
208
|
}
|
|
@@ -332,12 +301,15 @@ export class GSDDashboardOverlay {
|
|
|
332
301
|
const worktreeTag = worktreeName
|
|
333
302
|
? ` ${th.fg("warning", `⎇ ${worktreeName}`)}`
|
|
334
303
|
: "";
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
304
|
+
let elapsedParts = "";
|
|
305
|
+
if (this.dashData.active || this.dashData.paused) {
|
|
306
|
+
elapsedParts = th.fg("dim", formatDuration(this.dashData.elapsed));
|
|
307
|
+
const eta = estimateTimeRemaining();
|
|
308
|
+
if (eta) elapsedParts += th.fg("dim", ` · ${eta}`);
|
|
309
|
+
} else if (isRemote) {
|
|
310
|
+
elapsedParts = th.fg("dim", `since ${this.dashData.remoteSession!.startedAt.replace("T", " ").slice(0, 19)}`);
|
|
311
|
+
}
|
|
312
|
+
lines.push(row(joinColumns(`${title} ${status}${worktreeTag}`, elapsedParts, contentWidth)));
|
|
341
313
|
lines.push(blank());
|
|
342
314
|
|
|
343
315
|
if (this.dashData.currentUnit) {
|
|
@@ -435,23 +407,19 @@ export class GSDDashboardOverlay {
|
|
|
435
407
|
lines.push(blank());
|
|
436
408
|
|
|
437
409
|
for (const s of mv.slices) {
|
|
438
|
-
const
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
const titleText =
|
|
442
|
-
: s.done ? th.fg("muted", `${s.id}: ${s.title}`)
|
|
443
|
-
: th.fg("dim", `${s.id}: ${s.title}`);
|
|
410
|
+
const sliceStatus = s.done ? "done" : s.active ? "active" : "pending";
|
|
411
|
+
const icon = th.fg(STATUS_COLOR[sliceStatus], STATUS_GLYPH[sliceStatus]);
|
|
412
|
+
const titleColor = s.active ? "accent" : s.done ? "muted" : "dim";
|
|
413
|
+
const titleText = th.fg(titleColor, `${s.id}: ${s.title}`);
|
|
444
414
|
const risk = th.fg("dim", s.risk);
|
|
445
415
|
lines.push(row(joinColumns(` ${icon} ${titleText}`, risk, contentWidth)));
|
|
446
416
|
|
|
447
417
|
if (s.active && s.tasks.length > 0) {
|
|
448
418
|
for (const t of s.tasks) {
|
|
449
|
-
const
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
const tTitle =
|
|
453
|
-
: t.done ? th.fg("muted", `${t.id}: ${t.title}`)
|
|
454
|
-
: th.fg("dim", `${t.id}: ${t.title}`);
|
|
419
|
+
const taskStatus = t.done ? "done" : t.active ? "active" : "pending";
|
|
420
|
+
const tIcon = th.fg(STATUS_COLOR[taskStatus], STATUS_GLYPH[taskStatus]);
|
|
421
|
+
const tColor = t.active ? "warning" : t.done ? "muted" : "dim";
|
|
422
|
+
const tTitle = th.fg(tColor, `${t.id}: ${t.title}`);
|
|
455
423
|
lines.push(row(` ${tIcon} ${truncateToWidth(tTitle, contentWidth - 6)}`));
|
|
456
424
|
}
|
|
457
425
|
}
|
|
@@ -477,18 +445,21 @@ export class GSDDashboardOverlay {
|
|
|
477
445
|
|
|
478
446
|
const recent = [...this.dashData.completedUnits].reverse().slice(0, 10);
|
|
479
447
|
for (const u of recent) {
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
// Budget indicators from ledger
|
|
448
|
+
// Budget indicators from ledger — use warning glyph for pressured units
|
|
483
449
|
const ledgerEntry = ledgerLookup.get(`${u.type}:${u.id}`);
|
|
450
|
+
const hadPressure = ledgerEntry?.continueHereFired === true;
|
|
451
|
+
const hadTruncation = (ledgerEntry?.truncationSections ?? 0) > 0;
|
|
452
|
+
const unitGlyph = hadPressure
|
|
453
|
+
? th.fg(STATUS_COLOR.warning, STATUS_GLYPH.warning)
|
|
454
|
+
: th.fg(STATUS_COLOR.done, STATUS_GLYPH.done);
|
|
455
|
+
const left = ` ${unitGlyph} ${th.fg("muted", unitLabel(u.type))} ${th.fg("muted", u.id)}`;
|
|
456
|
+
|
|
484
457
|
let budgetMarkers = "";
|
|
485
|
-
if (
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
budgetMarkers += th.fg("error", " → wrap-up");
|
|
491
|
-
}
|
|
458
|
+
if (hadTruncation) {
|
|
459
|
+
budgetMarkers += th.fg("warning", ` ▼${ledgerEntry!.truncationSections}`);
|
|
460
|
+
}
|
|
461
|
+
if (hadPressure) {
|
|
462
|
+
budgetMarkers += th.fg("error", " → wrap-up");
|
|
492
463
|
}
|
|
493
464
|
|
|
494
465
|
const right = th.fg("dim", formatDuration(u.finishedAt - u.startedAt));
|
|
@@ -634,6 +605,10 @@ export class GSDDashboardOverlay {
|
|
|
634
605
|
dispose(): void {
|
|
635
606
|
this.disposed = true;
|
|
636
607
|
clearInterval(this.refreshTimer);
|
|
608
|
+
if (this.resizeHandler) {
|
|
609
|
+
process.stdout.removeListener("resize", this.resizeHandler);
|
|
610
|
+
this.resizeHandler = null;
|
|
611
|
+
}
|
|
637
612
|
}
|
|
638
613
|
}
|
|
639
614
|
|
|
@@ -173,14 +173,19 @@ export async function preDispatchHealthGate(basePath: string): Promise<PreDispat
|
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
// ── STATE.md existence check ──
|
|
176
|
-
// If STATE.md is missing, rebuild it
|
|
177
|
-
//
|
|
176
|
+
// If STATE.md is missing, attempt to rebuild it for the next unit's context.
|
|
177
|
+
// Non-blocking — fresh worktrees won't have it until the first unit completes (#889).
|
|
178
178
|
try {
|
|
179
179
|
const stateFile = resolveGsdRootFile(basePath, "STATE");
|
|
180
180
|
const milestonesDir = join(gsdRoot(basePath), "milestones");
|
|
181
181
|
if (existsSync(milestonesDir) && !existsSync(stateFile)) {
|
|
182
|
-
|
|
183
|
-
|
|
182
|
+
try {
|
|
183
|
+
await rebuildState(basePath);
|
|
184
|
+
fixesApplied.push("rebuilt missing STATE.md before dispatch");
|
|
185
|
+
} catch {
|
|
186
|
+
// Rebuild failed — non-blocking, dispatch continues
|
|
187
|
+
fixesApplied.push("STATE.md missing — will rebuild after first unit completes");
|
|
188
|
+
}
|
|
184
189
|
}
|
|
185
190
|
} catch {
|
|
186
191
|
// Non-fatal — dispatch continues without STATE.md if rebuild fails
|