toolcraft 0.0.233 → 0.0.235
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/composition.json +2 -2
- package/dist/composition.json +2 -2
- package/node_modules/tiny-stdio-mcp-server/dist/composition.json +1 -1
- package/node_modules/toolcraft-design/dist/dashboard/components/context-pane.d.ts +4 -0
- package/node_modules/toolcraft-design/dist/dashboard/components/context-pane.js +22 -0
- package/node_modules/toolcraft-design/dist/dashboard/components/stats-pane.js +12 -6
- package/node_modules/toolcraft-design/dist/dashboard/dashboard.js +22 -0
- package/node_modules/toolcraft-design/dist/dashboard/testing/pipeline-scenario.js +7 -5
- package/node_modules/toolcraft-design/dist/dashboard/types.d.ts +2 -0
- package/node_modules/toolcraft-schema/package.json +1 -1
- package/package.json +2 -2
package/composition.json
CHANGED
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
},
|
|
114
114
|
{
|
|
115
115
|
"name": "toolcraft",
|
|
116
|
-
"version": "0.0.
|
|
116
|
+
"version": "0.0.235",
|
|
117
117
|
"license": "MIT"
|
|
118
118
|
},
|
|
119
119
|
{
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
},
|
|
124
124
|
{
|
|
125
125
|
"name": "toolcraft-schema",
|
|
126
|
-
"version": "0.0.
|
|
126
|
+
"version": "0.0.235",
|
|
127
127
|
"license": "MIT"
|
|
128
128
|
},
|
|
129
129
|
{
|
package/dist/composition.json
CHANGED
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
},
|
|
114
114
|
{
|
|
115
115
|
"name": "toolcraft",
|
|
116
|
-
"version": "0.0.
|
|
116
|
+
"version": "0.0.235",
|
|
117
117
|
"license": "MIT"
|
|
118
118
|
},
|
|
119
119
|
{
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
},
|
|
124
124
|
{
|
|
125
125
|
"name": "toolcraft-schema",
|
|
126
|
-
"version": "0.0.
|
|
126
|
+
"version": "0.0.235",
|
|
127
127
|
"license": "MIT"
|
|
128
128
|
},
|
|
129
129
|
{
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { plainTerminalText } from "../ansi.js";
|
|
2
|
+
import { computeVisualLines } from "./output-pane.js";
|
|
3
|
+
import { truncateToWidth } from "../terminal-width.js";
|
|
4
|
+
/** Reserve fixed plan context while keeping room for the live output. */
|
|
5
|
+
export function renderContextPane(buffer, rect, context) {
|
|
6
|
+
if (context.length === 0 || rect.width <= 0 || rect.height <= 1)
|
|
7
|
+
return rect;
|
|
8
|
+
const available = Math.max(1, Math.floor(rect.height / 2));
|
|
9
|
+
const entries = context.map(text => computeVisualLines([{ kind: "info", text, ts: 0 }], rect.width + 3));
|
|
10
|
+
const lines = entries.flat();
|
|
11
|
+
const visible = lines.slice(0, available);
|
|
12
|
+
if (lines.length > available) {
|
|
13
|
+
const last = visible[available - 1];
|
|
14
|
+
const text = entries[0].length >= available
|
|
15
|
+
? truncateToWidth(`${available === 1 ? plainTerminalText(context[0]) : last.text}…`, rect.width)
|
|
16
|
+
: truncateToWidth(`… more plans (${context.length - 1} queued)`, rect.width);
|
|
17
|
+
visible[available - 1] = { ...last, text };
|
|
18
|
+
}
|
|
19
|
+
buffer.clearRect({ ...rect, height: visible.length });
|
|
20
|
+
visible.forEach((line, row) => buffer.putInRect(rect, row, line.text, { dim: row > 0 }));
|
|
21
|
+
return { ...rect, y: rect.y + visible.length, height: rect.height - visible.length };
|
|
22
|
+
}
|
|
@@ -7,8 +7,10 @@ export function renderCompactStatsPane(buffer, rect, stats) {
|
|
|
7
7
|
if (rect.width <= 0 || rect.height <= 0)
|
|
8
8
|
return;
|
|
9
9
|
const status = formatStatus(stats.status);
|
|
10
|
-
const
|
|
11
|
-
const
|
|
10
|
+
const progress = `${stats.iterationsLabel ?? "Iteration"} ${formatNumber(stats.iterations)}${stats.iterationsTotal === undefined ? "" : `/${formatNumber(stats.iterationsTotal)}`}`;
|
|
11
|
+
const primary = stats.iterationsTotal === undefined ? `${status} · ${progress}` : `${progress} · ${status}`;
|
|
12
|
+
const metrics = `${primary} · ${formatElapsed(stats.elapsedMs)} · ${formatNumber(stats.tokensIn + stats.tokensOut)} tokens`;
|
|
13
|
+
const firstLine = rect.height === 1 && stats.iterationsTotal === undefined && stats.currentAction ? `${status} · ${stats.currentAction}` : metrics;
|
|
12
14
|
const messages = [firstLine, stats.currentAction ?? ""].map(plainTerminalText);
|
|
13
15
|
buffer.putInRect(rect, 0, truncateToWidth(messages[0], rect.width), getStatusStyle(stats.status));
|
|
14
16
|
if (rect.height > 1 && stats.currentAction !== undefined) {
|
|
@@ -23,7 +25,8 @@ export function renderStatsPane(buffer, rect, stats) {
|
|
|
23
25
|
let lines = statsToLines(stats, rect.width);
|
|
24
26
|
if (lines.length > rect.height) {
|
|
25
27
|
const actions = stats.currentAction === undefined ? [] : lines.slice(9);
|
|
26
|
-
const
|
|
28
|
+
const progressLines = stats.iterationsTotal === undefined ? [] : [lines[1]];
|
|
29
|
+
const visibleActions = actions.slice(0, Math.max(0, rect.height - 1 - progressLines.length));
|
|
27
30
|
if (visibleActions.length > 0 && visibleActions.length < actions.length) {
|
|
28
31
|
const last = visibleActions[visibleActions.length - 1];
|
|
29
32
|
visibleActions[visibleActions.length - 1] = {
|
|
@@ -32,9 +35,12 @@ export function renderStatsPane(buffer, rect, stats) {
|
|
|
32
35
|
};
|
|
33
36
|
}
|
|
34
37
|
lines = [
|
|
35
|
-
|
|
38
|
+
stats.iterationsTotal !== undefined && rect.height === 1
|
|
39
|
+
? createKeyValueLine(formatStatus(stats.status), `${stats.iterations}/${stats.iterationsTotal}`, rect.width, getStatusStyle(stats.status))
|
|
40
|
+
: lines[0],
|
|
41
|
+
...progressLines,
|
|
36
42
|
...visibleActions,
|
|
37
|
-
...lines.slice(1, 7).filter((line) => line.prefix.length > 0 || line.text.length > 0)
|
|
43
|
+
...lines.slice(stats.iterationsTotal === undefined ? 1 : 2, 7).filter((line) => line.prefix.length > 0 || line.text.length > 0)
|
|
38
44
|
];
|
|
39
45
|
}
|
|
40
46
|
for (let row = 0; row < rect.height; row += 1) {
|
|
@@ -72,7 +78,7 @@ export function statsToLines(stats, width) {
|
|
|
72
78
|
const iterationsLabel = plainTerminalText(stats.iterationsLabel ?? "Iteration");
|
|
73
79
|
const lines = [
|
|
74
80
|
createKeyValueLine("Status", formatStatus(stats.status), width, getStatusStyle(stats.status)),
|
|
75
|
-
createKeyValueLine(iterationsLabel, formatNumber(stats.iterations), width),
|
|
81
|
+
createKeyValueLine(iterationsLabel, formatNumber(stats.iterations) + (stats.iterationsTotal === undefined ? "" : `/${formatNumber(stats.iterationsTotal)}`), width),
|
|
76
82
|
createKeyValueLine("Elapsed", formatElapsed(stats.elapsedMs), width),
|
|
77
83
|
createBlankLine(),
|
|
78
84
|
createKeyValueLine("Tokens In", formatNumber(stats.tokensIn), width),
|
|
@@ -2,6 +2,7 @@ import { createRenderPerformanceMonitor, formatRenderPerformance } from "../rend
|
|
|
2
2
|
import { createLogger } from "../components/logger.js";
|
|
3
3
|
import { resolveOutputFormat } from "../internal/output-format.js";
|
|
4
4
|
import { ScreenBuffer, diff } from "./buffer.js";
|
|
5
|
+
import { renderContextPane } from "./components/context-pane.js";
|
|
5
6
|
import { renderBorder } from "./components/border.js";
|
|
6
7
|
import { defaultHints, renderFooter } from "./components/footer.js";
|
|
7
8
|
import { renderOutputPane } from "./components/output-pane.js";
|
|
@@ -189,6 +190,27 @@ export function createDashboard(opts = {}) {
|
|
|
189
190
|
rightTitle: statsTitle,
|
|
190
191
|
style: { dim: true }
|
|
191
192
|
});
|
|
193
|
+
if (state.stats.context?.length) {
|
|
194
|
+
const contextRect = layout.summary ?? layout.leftPane;
|
|
195
|
+
// Context spans both panes on wide terminals.
|
|
196
|
+
const remaining = renderContextPane(nextBuffer, {
|
|
197
|
+
x: contextRect.x, y: contextRect.y, width: Math.max(0, cols - 2),
|
|
198
|
+
height: layout.summary ? layout.summary.height + layout.leftPane.height : layout.leftPane.height
|
|
199
|
+
}, state.stats.context);
|
|
200
|
+
const height = remaining.y - contextRect.y;
|
|
201
|
+
if (layout.summary) {
|
|
202
|
+
layout.summary.y = remaining.y;
|
|
203
|
+
layout.summary.height = Math.min(layout.summary.height, remaining.height);
|
|
204
|
+
layout.leftPane.y = layout.summary.y + layout.summary.height;
|
|
205
|
+
layout.leftPane.height = Math.max(0, remaining.height - layout.summary.height);
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
layout.leftPane.y += height;
|
|
209
|
+
layout.leftPane.height -= height;
|
|
210
|
+
layout.rightPane.y += height;
|
|
211
|
+
layout.rightPane.height -= height;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
192
214
|
scrollOffset = renderOutputPane(nextBuffer, { ...layout.leftPane, height: Math.max(0, layout.leftPane.height - (showPerformance ? 1 : 0)) }, heldOutput ?? state.output, scrollOffset);
|
|
193
215
|
if (scrollOffset === 0)
|
|
194
216
|
heldOutput = undefined;
|
|
@@ -6,7 +6,7 @@ const labelControl = scenario === "label-controls" ? "\u001b]52;c;" + "HIDDEN_".
|
|
|
6
6
|
const dashboard = createDashboard({
|
|
7
7
|
title: scenario === "unicode-title" ? "Pipeline · 界界 · 👩💻 · é · ".repeat(3) : `Pipeline · ${scenario}${labelControl}`,
|
|
8
8
|
statsTitle: scenario === "unicode-title" ? "Run · 界界 · 👩💻 · é" : `Run${labelControl}`,
|
|
9
|
-
rightPaneWidth:
|
|
9
|
+
rightPaneWidth: 44,
|
|
10
10
|
hints: [
|
|
11
11
|
{ key: "q", label: `Quit${labelControl}` },
|
|
12
12
|
{ key: "↑↓", label: "Scroll" },
|
|
@@ -33,15 +33,17 @@ if (scenario !== "empty")
|
|
|
33
33
|
dashboard.updateStats({
|
|
34
34
|
status: "running",
|
|
35
35
|
iterationsLabel: `Tasks${labelControl}`,
|
|
36
|
-
iterations: 1,
|
|
36
|
+
iterations: scenario === "resumed" || scenario === "queue" ? 68 : 1,
|
|
37
|
+
iterationsTotal: scenario === "resumed" || scenario === "queue" ? 90 : 8,
|
|
38
|
+
context: scenario === "queue" ? ["Plan 1/3: docs/plans/improve-pipeline-task-counts-and-restart-progress.md", "Next 2/3: docs/plans/agent-conversation-recovery.md", "Next 3/3: docs/plans/界界-unicode-long-plan-title.md"] : ["Plan 1/1: docs/plans/improve-pipeline-task-counts-and-restart-progress.md"],
|
|
37
39
|
tokensIn: 24000,
|
|
38
40
|
tokensOut: 7000,
|
|
39
41
|
elapsedMs: 65000,
|
|
40
|
-
currentAction: "Improve streaming output (implement)"
|
|
42
|
+
currentAction: scenario === "resumed" || scenario === "queue" ? "Task 69/90 · Improve persisted pipeline progress · implement · step 1/2" : "Improve streaming output (implement)"
|
|
41
43
|
});
|
|
42
44
|
append("info", "Config · codex · model-example · docs/plans/fake-pipeline.md");
|
|
43
45
|
if (scenario !== "empty")
|
|
44
|
-
append("status", "Task 2/8 · Improve streaming output (implement)");
|
|
46
|
+
append("status", scenario === "resumed" || scenario === "queue" ? "Task 69/90 · Improve persisted pipeline progress (implement)" : "Task 2/8 · Improve streaming output (implement)");
|
|
45
47
|
if (scenario === "empty") {
|
|
46
48
|
dashboard.updateStats({
|
|
47
49
|
status: "done",
|
|
@@ -118,7 +120,7 @@ else {
|
|
|
118
120
|
}, 100);
|
|
119
121
|
}
|
|
120
122
|
else {
|
|
121
|
-
timer = setInterval(() => append("info", `Streaming response ${count} · working on task
|
|
123
|
+
timer = setInterval(() => append("info", `Streaming response ${count} · working on the current task`), 500);
|
|
122
124
|
}
|
|
123
125
|
}
|
|
124
126
|
// Keep terminal state visible until QA sends q, including completed/error scenarios.
|
|
@@ -10,6 +10,8 @@ export type DashboardStats = {
|
|
|
10
10
|
status: "idle" | "running" | "paused" | "done" | "error";
|
|
11
11
|
iterations: number;
|
|
12
12
|
iterationsLabel?: string;
|
|
13
|
+
iterationsTotal?: number;
|
|
14
|
+
context?: string[];
|
|
13
15
|
tokensIn: number;
|
|
14
16
|
tokensOut: number;
|
|
15
17
|
elapsedMs: number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toolcraft",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.235",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -158,7 +158,7 @@
|
|
|
158
158
|
"yaml"
|
|
159
159
|
],
|
|
160
160
|
"optionalDependencies": {
|
|
161
|
-
"toolcraft-schema": "0.0.
|
|
161
|
+
"toolcraft-schema": "0.0.235",
|
|
162
162
|
"toolcraft-design": "*",
|
|
163
163
|
"@poe-code/frontmatter": "*",
|
|
164
164
|
"@poe-code/agent-mcp-config": "*",
|