poe-code 3.0.178 → 3.0.180
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/dist/index.js +6 -2
- package/dist/index.js.map +2 -2
- package/dist/prompts/github-issue-opened.md +7 -1
- package/dist/prompts/github-pull-request-opened.md +4 -0
- package/dist/prompts/github-pull-request-synchronized.md +4 -0
- package/dist/variables.yaml +46 -1
- package/dist/workflow-templates/github-issue-opened.caller.yml +1 -0
- package/dist/workflow-templates/github-issue-opened.ejected.yml +52 -0
- package/dist/workflow-templates/github-pull-request-opened.caller.yml +1 -0
- package/dist/workflow-templates/github-pull-request-opened.ejected.yml +52 -0
- package/dist/workflow-templates/github-pull-request-synchronized.caller.yml +1 -0
- package/dist/workflow-templates/github-pull-request-synchronized.ejected.yml +52 -0
- package/package.json +6 -2
- package/packages/cmdkit/dist/cli.compile-check.d.ts +1 -0
- package/packages/cmdkit/dist/cli.compile-check.js +26 -0
- package/packages/cmdkit/dist/cli.d.ts +12 -0
- package/packages/cmdkit/dist/cli.js +2306 -0
- package/packages/cmdkit/dist/cli.js.map +7 -0
- package/packages/cmdkit/dist/index.compile-check.d.ts +1 -0
- package/packages/cmdkit/dist/index.compile-check.js +50 -0
- package/packages/cmdkit/dist/index.d.ts +164 -0
- package/packages/cmdkit/dist/index.js +518 -0
- package/packages/cmdkit/dist/index.js.map +7 -0
- package/packages/cmdkit/dist/mcp.compile-check.d.ts +1 -0
- package/packages/cmdkit/dist/mcp.compile-check.js +26 -0
- package/packages/cmdkit/dist/mcp.d.ts +16 -0
- package/packages/cmdkit/dist/mcp.js +1153 -0
- package/packages/cmdkit/dist/mcp.js.map +7 -0
- package/packages/cmdkit/dist/renderer.d.ts +5 -0
- package/packages/cmdkit/dist/renderer.js +164 -0
- package/packages/cmdkit/dist/renderer.js.map +7 -0
- package/packages/cmdkit/dist/sdk.compile-check.d.ts +1 -0
- package/packages/cmdkit/dist/sdk.compile-check.js +79 -0
- package/packages/cmdkit/dist/sdk.d.ts +63 -0
- package/packages/cmdkit/dist/sdk.js +314 -0
- package/packages/cmdkit/dist/sdk.js.map +7 -0
- package/packages/cmdkit-schema/dist/index.compile-check.d.ts +1 -0
- package/packages/cmdkit-schema/dist/index.compile-check.js +11 -0
- package/packages/cmdkit-schema/dist/index.d.ts +81 -0
- package/packages/cmdkit-schema/dist/index.js +130 -0
- package/packages/design-system/dist/acp/components.d.ts +11 -0
- package/packages/design-system/dist/acp/components.js +121 -0
- package/packages/design-system/dist/acp/index.d.ts +3 -0
- package/packages/design-system/dist/acp/index.js +2 -0
- package/packages/design-system/dist/acp/writer.d.ts +13 -0
- package/packages/design-system/dist/acp/writer.js +21 -0
- package/packages/design-system/dist/components/command-errors.d.ts +16 -0
- package/packages/design-system/dist/components/command-errors.js +22 -0
- package/packages/design-system/dist/components/help-formatter.d.ts +20 -0
- package/packages/design-system/dist/components/help-formatter.js +27 -0
- package/packages/design-system/dist/components/index.d.ts +10 -0
- package/packages/design-system/dist/components/index.js +7 -0
- package/packages/design-system/dist/components/logger.d.ts +11 -0
- package/packages/design-system/dist/components/logger.js +60 -0
- package/packages/design-system/dist/components/symbols.d.ts +12 -0
- package/packages/design-system/dist/components/symbols.js +71 -0
- package/packages/design-system/dist/components/table.d.ts +13 -0
- package/packages/design-system/dist/components/table.js +74 -0
- package/packages/design-system/dist/components/text.d.ts +14 -0
- package/packages/design-system/dist/components/text.js +104 -0
- package/packages/design-system/dist/dashboard/ansi.d.ts +18 -0
- package/packages/design-system/dist/dashboard/ansi.js +298 -0
- package/packages/design-system/dist/dashboard/buffer.d.ts +25 -0
- package/packages/design-system/dist/dashboard/buffer.js +189 -0
- package/packages/design-system/dist/dashboard/components/border.d.ts +9 -0
- package/packages/design-system/dist/dashboard/components/border.js +123 -0
- package/packages/design-system/dist/dashboard/components/footer.d.ts +8 -0
- package/packages/design-system/dist/dashboard/components/footer.js +58 -0
- package/packages/design-system/dist/dashboard/components/output-pane.d.ts +21 -0
- package/packages/design-system/dist/dashboard/components/output-pane.js +323 -0
- package/packages/design-system/dist/dashboard/components/stats-pane.d.ts +7 -0
- package/packages/design-system/dist/dashboard/components/stats-pane.js +120 -0
- package/packages/design-system/dist/dashboard/dashboard.d.ts +20 -0
- package/packages/design-system/dist/dashboard/dashboard.js +187 -0
- package/packages/design-system/dist/dashboard/demo.d.ts +13 -0
- package/packages/design-system/dist/dashboard/demo.js +145 -0
- package/packages/design-system/dist/dashboard/index.d.ts +7 -0
- package/packages/design-system/dist/dashboard/index.js +3 -0
- package/packages/design-system/dist/dashboard/keymap.d.ts +3 -0
- package/packages/design-system/dist/dashboard/keymap.js +114 -0
- package/packages/design-system/dist/dashboard/layout.d.ts +25 -0
- package/packages/design-system/dist/dashboard/layout.js +79 -0
- package/packages/design-system/dist/dashboard/snapshot.d.ts +10 -0
- package/packages/design-system/dist/dashboard/snapshot.js +72 -0
- package/packages/design-system/dist/dashboard/store.d.ts +9 -0
- package/packages/design-system/dist/dashboard/store.js +107 -0
- package/packages/design-system/dist/dashboard/terminal.d.ts +35 -0
- package/packages/design-system/dist/dashboard/terminal.js +215 -0
- package/packages/design-system/dist/dashboard/types.d.ts +45 -0
- package/packages/design-system/dist/dashboard/types.js +1 -0
- package/packages/design-system/dist/index.d.ts +33 -0
- package/packages/design-system/dist/index.js +31 -0
- package/packages/design-system/dist/internal/output-format.d.ts +6 -0
- package/packages/design-system/dist/internal/output-format.js +22 -0
- package/packages/design-system/dist/internal/strip-ansi.d.ts +1 -0
- package/packages/design-system/dist/internal/strip-ansi.js +3 -0
- package/packages/design-system/dist/internal/theme-detect.d.ts +11 -0
- package/packages/design-system/dist/internal/theme-detect.js +49 -0
- package/packages/design-system/dist/prompts/index.d.ts +66 -0
- package/packages/design-system/dist/prompts/index.js +132 -0
- package/packages/design-system/dist/prompts/primitives/cancel.d.ts +2 -0
- package/packages/design-system/dist/prompts/primitives/cancel.js +9 -0
- package/packages/design-system/dist/prompts/primitives/intro.d.ts +1 -0
- package/packages/design-system/dist/prompts/primitives/intro.js +15 -0
- package/packages/design-system/dist/prompts/primitives/log.d.ts +18 -0
- package/packages/design-system/dist/prompts/primitives/log.js +101 -0
- package/packages/design-system/dist/prompts/primitives/note.d.ts +1 -0
- package/packages/design-system/dist/prompts/primitives/note.js +39 -0
- package/packages/design-system/dist/prompts/primitives/outro.d.ts +1 -0
- package/packages/design-system/dist/prompts/primitives/outro.js +16 -0
- package/packages/design-system/dist/prompts/primitives/spinner.d.ts +6 -0
- package/packages/design-system/dist/prompts/primitives/spinner.js +74 -0
- package/packages/design-system/dist/prompts/theme.d.ts +11 -0
- package/packages/design-system/dist/prompts/theme.js +12 -0
- package/packages/design-system/dist/static/index.d.ts +4 -0
- package/packages/design-system/dist/static/index.js +2 -0
- package/packages/design-system/dist/static/menu.d.ts +11 -0
- package/packages/design-system/dist/static/menu.js +36 -0
- package/packages/design-system/dist/static/spinner.d.ts +14 -0
- package/packages/design-system/dist/static/spinner.js +46 -0
- package/packages/design-system/dist/terminal-markdown/ast.d.ts +84 -0
- package/packages/design-system/dist/terminal-markdown/ast.js +1 -0
- package/packages/design-system/dist/terminal-markdown/demo-content.d.ts +2 -0
- package/packages/design-system/dist/terminal-markdown/demo-content.js +139 -0
- package/packages/design-system/dist/terminal-markdown/index.d.ts +6 -0
- package/packages/design-system/dist/terminal-markdown/index.js +8 -0
- package/packages/design-system/dist/terminal-markdown/parser/block.d.ts +6 -0
- package/packages/design-system/dist/terminal-markdown/parser/block.js +1205 -0
- package/packages/design-system/dist/terminal-markdown/parser/frontmatter.d.ts +6 -0
- package/packages/design-system/dist/terminal-markdown/parser/frontmatter.js +395 -0
- package/packages/design-system/dist/terminal-markdown/parser/inline.d.ts +6 -0
- package/packages/design-system/dist/terminal-markdown/parser/inline.js +1087 -0
- package/packages/design-system/dist/terminal-markdown/parser.d.ts +5 -0
- package/packages/design-system/dist/terminal-markdown/parser.js +13 -0
- package/packages/design-system/dist/terminal-markdown/renderer.d.ts +6 -0
- package/packages/design-system/dist/terminal-markdown/renderer.js +572 -0
- package/packages/design-system/dist/terminal-markdown/testing/theme-render-fixture.d.ts +1 -0
- package/packages/design-system/dist/terminal-markdown/testing/theme-render-fixture.js +27 -0
- package/packages/design-system/dist/tokens/colors.d.ts +35 -0
- package/packages/design-system/dist/tokens/colors.js +34 -0
- package/packages/design-system/dist/tokens/index.d.ts +4 -0
- package/packages/design-system/dist/tokens/index.js +4 -0
- package/packages/design-system/dist/tokens/spacing.d.ts +6 -0
- package/packages/design-system/dist/tokens/spacing.js +6 -0
- package/packages/design-system/dist/tokens/typography.d.ts +7 -0
- package/packages/design-system/dist/tokens/typography.js +8 -0
- package/packages/design-system/dist/tokens/widths.d.ts +5 -0
- package/packages/design-system/dist/tokens/widths.js +5 -0
- package/packages/tiny-stdio-mcp-server/dist/content/audio.d.ts +14 -0
- package/packages/tiny-stdio-mcp-server/dist/content/audio.js +76 -0
- package/packages/tiny-stdio-mcp-server/dist/content/convert.d.ts +16 -0
- package/packages/tiny-stdio-mcp-server/dist/content/convert.js +42 -0
- package/packages/tiny-stdio-mcp-server/dist/content/file-type.d.ts +11 -0
- package/packages/tiny-stdio-mcp-server/dist/content/file-type.js +93 -0
- package/packages/tiny-stdio-mcp-server/dist/content/file.d.ts +26 -0
- package/packages/tiny-stdio-mcp-server/dist/content/file.js +94 -0
- package/packages/tiny-stdio-mcp-server/dist/content/image.d.ts +14 -0
- package/packages/tiny-stdio-mcp-server/dist/content/image.js +64 -0
- package/packages/tiny-stdio-mcp-server/dist/content/index.d.ts +5 -0
- package/packages/tiny-stdio-mcp-server/dist/content/index.js +8 -0
- package/packages/tiny-stdio-mcp-server/dist/content/mime.d.ts +1 -0
- package/packages/tiny-stdio-mcp-server/dist/content/mime.js +1 -0
- package/packages/tiny-stdio-mcp-server/dist/index.d.ts +9 -0
- package/packages/tiny-stdio-mcp-server/dist/index.js +7 -0
- package/packages/tiny-stdio-mcp-server/dist/jsonrpc.d.ts +14 -0
- package/packages/tiny-stdio-mcp-server/dist/jsonrpc.js +99 -0
- package/packages/tiny-stdio-mcp-server/dist/schema.d.ts +19 -0
- package/packages/tiny-stdio-mcp-server/dist/schema.js +18 -0
- package/packages/tiny-stdio-mcp-server/dist/server.d.ts +13 -0
- package/packages/tiny-stdio-mcp-server/dist/server.js +226 -0
- package/packages/tiny-stdio-mcp-server/dist/testing.d.ts +7 -0
- package/packages/tiny-stdio-mcp-server/dist/testing.js +20 -0
- package/packages/tiny-stdio-mcp-server/dist/types.d.ts +119 -0
- package/packages/tiny-stdio-mcp-server/dist/types.js +16 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { createLogger } from "../components/logger.js";
|
|
2
|
+
import { resolveOutputFormat } from "../internal/output-format.js";
|
|
3
|
+
import { ScreenBuffer, diff } from "./buffer.js";
|
|
4
|
+
import { renderBorder } from "./components/border.js";
|
|
5
|
+
import { defaultHints, renderFooter } from "./components/footer.js";
|
|
6
|
+
import { renderOutputPane } from "./components/output-pane.js";
|
|
7
|
+
import { renderStatsPane } from "./components/stats-pane.js";
|
|
8
|
+
import { createKeymap } from "./keymap.js";
|
|
9
|
+
import { computeDashboardLayout } from "./layout.js";
|
|
10
|
+
import { createStore } from "./store.js";
|
|
11
|
+
import { createTerminalDriver } from "./terminal.js";
|
|
12
|
+
const DEFAULT_TITLE = "Output";
|
|
13
|
+
const DEFAULT_STATS_TITLE = "Stats";
|
|
14
|
+
const DEFAULT_RIGHT_PANE_WIDTH = 25;
|
|
15
|
+
export function createDashboard(opts = {}) {
|
|
16
|
+
const stdin = opts.stdin ?? process.stdin;
|
|
17
|
+
const stdout = opts.stdout ?? process.stdout;
|
|
18
|
+
const resolveCommand = createKeymap(opts.keymap);
|
|
19
|
+
const footerHints = opts.hints ?? defaultHints();
|
|
20
|
+
const title = opts.title ?? DEFAULT_TITLE;
|
|
21
|
+
const statsTitle = opts.statsTitle ?? DEFAULT_STATS_TITLE;
|
|
22
|
+
const rightPaneWidth = opts.rightPaneWidth ?? DEFAULT_RIGHT_PANE_WIDTH;
|
|
23
|
+
const commandHandlers = new Set();
|
|
24
|
+
const fallbackLogger = createLogger((message) => {
|
|
25
|
+
stdout.write(`${message}\n`);
|
|
26
|
+
});
|
|
27
|
+
let driver;
|
|
28
|
+
let store;
|
|
29
|
+
let currentLayout = computeDashboardLayout({
|
|
30
|
+
totalWidth: 0,
|
|
31
|
+
totalHeight: 0,
|
|
32
|
+
rightPaneWidth
|
|
33
|
+
});
|
|
34
|
+
let previousBuffer = new ScreenBuffer(0, 0);
|
|
35
|
+
let unsubscribeStore;
|
|
36
|
+
let unsubscribeKeypress;
|
|
37
|
+
let unsubscribeResize;
|
|
38
|
+
let started = false;
|
|
39
|
+
let destroyed = false;
|
|
40
|
+
function appendOutput(item) {
|
|
41
|
+
if (destroyed) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (!isTerminalMode()) {
|
|
45
|
+
writeFallbackOutput(item);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
getStore().appendOutput(item);
|
|
49
|
+
}
|
|
50
|
+
function updateStats(stats) {
|
|
51
|
+
if (destroyed || !isTerminalMode()) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
getStore().updateStats(stats);
|
|
55
|
+
}
|
|
56
|
+
function start() {
|
|
57
|
+
if (destroyed || started || !isTerminalMode()) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
driver = createTerminalDriver({ stdin, stdout });
|
|
61
|
+
started = true;
|
|
62
|
+
previousBuffer = new ScreenBuffer(0, 0);
|
|
63
|
+
driver.enterRawMode();
|
|
64
|
+
driver.enterAltScreen();
|
|
65
|
+
driver.hideCursor();
|
|
66
|
+
render();
|
|
67
|
+
const activeStore = getStore();
|
|
68
|
+
unsubscribeStore = activeStore.onChange(() => {
|
|
69
|
+
render();
|
|
70
|
+
});
|
|
71
|
+
unsubscribeKeypress = driver.onKeypress((event) => {
|
|
72
|
+
const command = resolveCommand(event);
|
|
73
|
+
if (command === undefined) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (isScrollCommand(command)) {
|
|
77
|
+
activeStore.dispatch(command, currentLayout.leftPane.height);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
emitCommand(command);
|
|
81
|
+
});
|
|
82
|
+
unsubscribeResize = driver.onResize(() => {
|
|
83
|
+
render();
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
function stop() {
|
|
87
|
+
unsubscribeStore?.();
|
|
88
|
+
unsubscribeKeypress?.();
|
|
89
|
+
unsubscribeResize?.();
|
|
90
|
+
unsubscribeStore = undefined;
|
|
91
|
+
unsubscribeKeypress = undefined;
|
|
92
|
+
unsubscribeResize = undefined;
|
|
93
|
+
if (driver === undefined) {
|
|
94
|
+
started = false;
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
driver.destroy();
|
|
98
|
+
driver = undefined;
|
|
99
|
+
previousBuffer = new ScreenBuffer(0, 0);
|
|
100
|
+
started = false;
|
|
101
|
+
}
|
|
102
|
+
function onCommand(handler) {
|
|
103
|
+
if (destroyed) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
commandHandlers.add(handler);
|
|
107
|
+
}
|
|
108
|
+
function destroy() {
|
|
109
|
+
if (destroyed) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
stop();
|
|
113
|
+
commandHandlers.clear();
|
|
114
|
+
store = undefined;
|
|
115
|
+
destroyed = true;
|
|
116
|
+
}
|
|
117
|
+
function getStore() {
|
|
118
|
+
store ??= createStore();
|
|
119
|
+
return store;
|
|
120
|
+
}
|
|
121
|
+
function render() {
|
|
122
|
+
if (driver === undefined) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const { cols, rows } = driver.getSize();
|
|
126
|
+
currentLayout = computeDashboardLayout({
|
|
127
|
+
totalWidth: cols,
|
|
128
|
+
totalHeight: rows,
|
|
129
|
+
rightPaneWidth
|
|
130
|
+
});
|
|
131
|
+
const nextBuffer = new ScreenBuffer(cols, rows);
|
|
132
|
+
const state = getStore().getState();
|
|
133
|
+
renderBorder(nextBuffer, currentLayout, {
|
|
134
|
+
leftTitle: title,
|
|
135
|
+
rightTitle: statsTitle,
|
|
136
|
+
style: { dim: true }
|
|
137
|
+
});
|
|
138
|
+
renderOutputPane(nextBuffer, currentLayout.leftPane, {
|
|
139
|
+
items: state.output,
|
|
140
|
+
scrollOffset: state.outputScroll,
|
|
141
|
+
autoFollow: state.autoFollow
|
|
142
|
+
});
|
|
143
|
+
renderStatsPane(nextBuffer, currentLayout.rightPane, state.stats);
|
|
144
|
+
renderFooter(nextBuffer, currentLayout.footer, footerHints);
|
|
145
|
+
driver.flush(diff(previousBuffer, nextBuffer));
|
|
146
|
+
previousBuffer = nextBuffer;
|
|
147
|
+
}
|
|
148
|
+
function emitCommand(command) {
|
|
149
|
+
for (const handler of commandHandlers) {
|
|
150
|
+
handler(command);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
function writeFallbackOutput(item) {
|
|
154
|
+
if (item.kind === "success") {
|
|
155
|
+
fallbackLogger.success(item.text);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
if (item.kind === "error") {
|
|
159
|
+
fallbackLogger.error(item.text);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (item.kind === "tool") {
|
|
163
|
+
fallbackLogger.message(item.text);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
fallbackLogger.info(item.text);
|
|
167
|
+
}
|
|
168
|
+
return {
|
|
169
|
+
start,
|
|
170
|
+
stop,
|
|
171
|
+
appendOutput,
|
|
172
|
+
updateStats,
|
|
173
|
+
onCommand,
|
|
174
|
+
destroy
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
function isTerminalMode() {
|
|
178
|
+
return resolveOutputFormat() === "terminal";
|
|
179
|
+
}
|
|
180
|
+
function isScrollCommand(command) {
|
|
181
|
+
return command === "scrollUp"
|
|
182
|
+
|| command === "scrollDown"
|
|
183
|
+
|| command === "pageUp"
|
|
184
|
+
|| command === "pageDown"
|
|
185
|
+
|| command === "scrollToTop"
|
|
186
|
+
|| command === "scrollToBottom";
|
|
187
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Dashboard } from "./dashboard.js";
|
|
2
|
+
type DemoDashboard = Pick<Dashboard, "appendOutput" | "updateStats">;
|
|
3
|
+
type DemoRuntime = {
|
|
4
|
+
setInterval: typeof globalThis.setInterval;
|
|
5
|
+
clearInterval: typeof globalThis.clearInterval;
|
|
6
|
+
setTimeout: typeof globalThis.setTimeout;
|
|
7
|
+
clearTimeout: typeof globalThis.clearTimeout;
|
|
8
|
+
now: () => number;
|
|
9
|
+
random: () => number;
|
|
10
|
+
};
|
|
11
|
+
export declare function startDashboardDemo(dashboard: DemoDashboard, runtime?: Partial<DemoRuntime>): () => void;
|
|
12
|
+
export declare function main(): Promise<void>;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { createDashboard } from "./dashboard.js";
|
|
5
|
+
const OUTPUT_INTERVAL_MS = 500;
|
|
6
|
+
const STATS_INTERVAL_MS = 1_000;
|
|
7
|
+
const DEMO_DURATION_MS = 30_000;
|
|
8
|
+
const TOKENS_IN_PER_ITERATION = 137;
|
|
9
|
+
const TOKENS_OUT_PER_ITERATION = 89;
|
|
10
|
+
const OUTPUT_KINDS = ["info", "success", "error", "tool", "status"];
|
|
11
|
+
const OUTPUT_MESSAGES = {
|
|
12
|
+
info: [
|
|
13
|
+
"Analyzing repository state",
|
|
14
|
+
"Inspecting agent configuration",
|
|
15
|
+
"Collecting recent command output"
|
|
16
|
+
],
|
|
17
|
+
success: [
|
|
18
|
+
"Generated provider config",
|
|
19
|
+
"Updated dashboard layout",
|
|
20
|
+
"Saved session checkpoint"
|
|
21
|
+
],
|
|
22
|
+
error: [
|
|
23
|
+
"Retrying transient network request",
|
|
24
|
+
"Tool execution returned a non-zero exit code",
|
|
25
|
+
"Encountered a recoverable validation error"
|
|
26
|
+
],
|
|
27
|
+
tool: [
|
|
28
|
+
"Running npm test -- --runInBand",
|
|
29
|
+
"Executing npm run lint:types",
|
|
30
|
+
"Opening task plan documentation"
|
|
31
|
+
],
|
|
32
|
+
status: [
|
|
33
|
+
"Waiting for follow-up task",
|
|
34
|
+
"Streaming model response",
|
|
35
|
+
"Syncing derived metrics"
|
|
36
|
+
]
|
|
37
|
+
};
|
|
38
|
+
const RUNNING_ACTIONS = [
|
|
39
|
+
"Planning next step",
|
|
40
|
+
"Executing tool call",
|
|
41
|
+
"Reviewing tool results",
|
|
42
|
+
"Updating working memory",
|
|
43
|
+
"Preparing final response"
|
|
44
|
+
];
|
|
45
|
+
const INITIAL_ACTION = "Connecting to provider";
|
|
46
|
+
const COMPLETED_ACTION = "Completed";
|
|
47
|
+
export function startDashboardDemo(dashboard, runtime = {}) {
|
|
48
|
+
const setIntervalFn = runtime.setInterval ?? globalThis.setInterval.bind(globalThis);
|
|
49
|
+
const clearIntervalFn = runtime.clearInterval ?? globalThis.clearInterval.bind(globalThis);
|
|
50
|
+
const setTimeoutFn = runtime.setTimeout ?? globalThis.setTimeout.bind(globalThis);
|
|
51
|
+
const clearTimeoutFn = runtime.clearTimeout ?? globalThis.clearTimeout.bind(globalThis);
|
|
52
|
+
const now = runtime.now ?? Date.now;
|
|
53
|
+
const random = runtime.random ?? Math.random;
|
|
54
|
+
let outputCount = 0;
|
|
55
|
+
let iterations = 0;
|
|
56
|
+
let cleanedUp = false;
|
|
57
|
+
dashboard.updateStats({
|
|
58
|
+
status: "running",
|
|
59
|
+
currentAction: INITIAL_ACTION
|
|
60
|
+
});
|
|
61
|
+
const outputTimer = setIntervalFn(() => {
|
|
62
|
+
const kind = OUTPUT_KINDS[outputCount % OUTPUT_KINDS.length] ?? "info";
|
|
63
|
+
dashboard.appendOutput({
|
|
64
|
+
kind,
|
|
65
|
+
text: pickOutputMessage(kind, random),
|
|
66
|
+
ts: now()
|
|
67
|
+
});
|
|
68
|
+
outputCount += 1;
|
|
69
|
+
}, OUTPUT_INTERVAL_MS);
|
|
70
|
+
const statsTimer = setIntervalFn(() => {
|
|
71
|
+
iterations += 1;
|
|
72
|
+
dashboard.updateStats({
|
|
73
|
+
status: "running",
|
|
74
|
+
iterations,
|
|
75
|
+
tokensIn: iterations * TOKENS_IN_PER_ITERATION,
|
|
76
|
+
tokensOut: iterations * TOKENS_OUT_PER_ITERATION,
|
|
77
|
+
elapsedMs: iterations * STATS_INTERVAL_MS,
|
|
78
|
+
currentAction: RUNNING_ACTIONS[(iterations - 1) % RUNNING_ACTIONS.length] ?? INITIAL_ACTION
|
|
79
|
+
});
|
|
80
|
+
}, STATS_INTERVAL_MS);
|
|
81
|
+
const finishTimeout = setTimeoutFn(() => {
|
|
82
|
+
cleanup();
|
|
83
|
+
dashboard.updateStats({
|
|
84
|
+
status: "done",
|
|
85
|
+
iterations,
|
|
86
|
+
tokensIn: iterations * TOKENS_IN_PER_ITERATION,
|
|
87
|
+
tokensOut: iterations * TOKENS_OUT_PER_ITERATION,
|
|
88
|
+
elapsedMs: DEMO_DURATION_MS,
|
|
89
|
+
currentAction: COMPLETED_ACTION
|
|
90
|
+
});
|
|
91
|
+
}, DEMO_DURATION_MS);
|
|
92
|
+
function cleanup() {
|
|
93
|
+
if (cleanedUp) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
cleanedUp = true;
|
|
97
|
+
clearTimeoutFn(finishTimeout);
|
|
98
|
+
clearIntervalFn(outputTimer);
|
|
99
|
+
clearIntervalFn(statsTimer);
|
|
100
|
+
}
|
|
101
|
+
return cleanup;
|
|
102
|
+
}
|
|
103
|
+
function pickOutputMessage(kind, random) {
|
|
104
|
+
const options = OUTPUT_MESSAGES[kind];
|
|
105
|
+
const cappedRandom = Math.max(0, Math.min(0.999_999, random()));
|
|
106
|
+
const index = Math.floor(cappedRandom * options.length);
|
|
107
|
+
return options[index] ?? options[0] ?? kind;
|
|
108
|
+
}
|
|
109
|
+
export async function main() {
|
|
110
|
+
const dashboard = createDashboard({ title: "Agent Output", statsTitle: "Stats" });
|
|
111
|
+
const stopDemo = startDashboardDemo(dashboard);
|
|
112
|
+
let shutDown = false;
|
|
113
|
+
const shutdown = (exitCode) => {
|
|
114
|
+
if (shutDown) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
shutDown = true;
|
|
118
|
+
stopDemo();
|
|
119
|
+
dashboard.destroy();
|
|
120
|
+
if (exitCode !== undefined) {
|
|
121
|
+
process.exit(exitCode);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
dashboard.onCommand((command) => {
|
|
125
|
+
if (command === "quit") {
|
|
126
|
+
shutdown(0);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
process.once("SIGINT", () => {
|
|
130
|
+
shutdown(0);
|
|
131
|
+
});
|
|
132
|
+
process.once("SIGTERM", () => {
|
|
133
|
+
shutdown(0);
|
|
134
|
+
});
|
|
135
|
+
dashboard.start();
|
|
136
|
+
}
|
|
137
|
+
const entry = process.argv[1];
|
|
138
|
+
const isMain = typeof entry === "string" && path.resolve(entry) === fileURLToPath(import.meta.url);
|
|
139
|
+
if (isMain) {
|
|
140
|
+
main().catch((error) => {
|
|
141
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
142
|
+
process.stderr.write(`${message}\n`);
|
|
143
|
+
process.exitCode = 1;
|
|
144
|
+
});
|
|
145
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { createDashboard } from "./dashboard.js";
|
|
2
|
+
export type { Dashboard, DashboardOptions } from "./dashboard.js";
|
|
3
|
+
export { renderDashboardSnapshot } from "./snapshot.js";
|
|
4
|
+
export type { SnapshotOptions } from "./snapshot.js";
|
|
5
|
+
export type { OutputItem, OutputItemKind, DashboardStats, Command, DashboardState } from "./types.js";
|
|
6
|
+
export { defaultHints } from "./components/footer.js";
|
|
7
|
+
export type { FooterHint } from "./components/footer.js";
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
const commands = [
|
|
2
|
+
"quit",
|
|
3
|
+
"edit",
|
|
4
|
+
"pause",
|
|
5
|
+
"retry",
|
|
6
|
+
"scrollUp",
|
|
7
|
+
"scrollDown",
|
|
8
|
+
"pageUp",
|
|
9
|
+
"pageDown",
|
|
10
|
+
"scrollToTop",
|
|
11
|
+
"scrollToBottom"
|
|
12
|
+
];
|
|
13
|
+
const defaultBindings = {
|
|
14
|
+
quit: ["q", "Ctrl+C"],
|
|
15
|
+
edit: ["e"],
|
|
16
|
+
pause: ["p"],
|
|
17
|
+
retry: ["r"],
|
|
18
|
+
scrollUp: ["up", "k"],
|
|
19
|
+
scrollDown: ["down", "j"],
|
|
20
|
+
pageUp: ["pageup"],
|
|
21
|
+
pageDown: ["pagedown"],
|
|
22
|
+
scrollToTop: ["home", "g"],
|
|
23
|
+
scrollToBottom: ["end", "G", "f", "F"]
|
|
24
|
+
};
|
|
25
|
+
export function createKeymap(overrides) {
|
|
26
|
+
const bindings = new Map();
|
|
27
|
+
for (const command of commands) {
|
|
28
|
+
const keys = overrides?.[command] ?? defaultBindings[command];
|
|
29
|
+
bindings.set(command, keys
|
|
30
|
+
.map(parseBinding)
|
|
31
|
+
.filter((binding) => binding !== undefined));
|
|
32
|
+
}
|
|
33
|
+
return (event) => {
|
|
34
|
+
for (const command of commands) {
|
|
35
|
+
const commandBindings = bindings.get(command);
|
|
36
|
+
if (commandBindings?.some((binding) => matches(binding, event))) {
|
|
37
|
+
return command;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function parseBinding(binding) {
|
|
44
|
+
const value = binding.trim();
|
|
45
|
+
if (value.length === 0) {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
const parts = value.split("+").map((part) => part.trim()).filter(Boolean);
|
|
49
|
+
if (parts.length === 0) {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
let ctrl = false;
|
|
53
|
+
let meta = false;
|
|
54
|
+
let shift = false;
|
|
55
|
+
const key = parts.at(-1);
|
|
56
|
+
if (key === undefined) {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
for (const modifier of parts.slice(0, -1)) {
|
|
60
|
+
const normalized = modifier.toLowerCase();
|
|
61
|
+
if (normalized === "ctrl" || normalized === "control") {
|
|
62
|
+
ctrl = true;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (normalized === "meta" || normalized === "alt") {
|
|
66
|
+
meta = true;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (normalized === "shift") {
|
|
70
|
+
shift = true;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (parts.length === 1 && isShiftedCharacter(key)) {
|
|
75
|
+
shift = true;
|
|
76
|
+
}
|
|
77
|
+
if (key.length === 1) {
|
|
78
|
+
return {
|
|
79
|
+
ch: normalizeBindingCharacter(key, shift),
|
|
80
|
+
ctrl,
|
|
81
|
+
meta,
|
|
82
|
+
shift
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
name: key.toLowerCase(),
|
|
87
|
+
ctrl,
|
|
88
|
+
meta,
|
|
89
|
+
shift
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function matches(binding, event) {
|
|
93
|
+
if (binding.ctrl !== event.ctrl ||
|
|
94
|
+
binding.meta !== event.meta ||
|
|
95
|
+
binding.shift !== event.shift) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
if (binding.ch !== undefined) {
|
|
99
|
+
return event.ch === binding.ch || event.name === binding.ch.toLowerCase();
|
|
100
|
+
}
|
|
101
|
+
if (binding.name !== undefined) {
|
|
102
|
+
return event.name === binding.name;
|
|
103
|
+
}
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
function isShiftedCharacter(value) {
|
|
107
|
+
return value.length === 1 && value.toLowerCase() !== value && value.toUpperCase() === value;
|
|
108
|
+
}
|
|
109
|
+
function normalizeBindingCharacter(value, shift) {
|
|
110
|
+
if (!shift || value.toLowerCase() === value.toUpperCase()) {
|
|
111
|
+
return value;
|
|
112
|
+
}
|
|
113
|
+
return value.toUpperCase();
|
|
114
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Rect } from "./types.js";
|
|
2
|
+
export type LayoutOptions = {
|
|
3
|
+
totalWidth: number;
|
|
4
|
+
totalHeight: number;
|
|
5
|
+
rightPaneWidth?: number;
|
|
6
|
+
footerHeight?: number;
|
|
7
|
+
borderWidth?: number;
|
|
8
|
+
};
|
|
9
|
+
export type DashboardLayout = {
|
|
10
|
+
outerBorder: Rect;
|
|
11
|
+
leftPane: Rect;
|
|
12
|
+
rightPane: Rect;
|
|
13
|
+
divider: {
|
|
14
|
+
x: number;
|
|
15
|
+
top: number;
|
|
16
|
+
bottom: number;
|
|
17
|
+
};
|
|
18
|
+
footer: Rect;
|
|
19
|
+
footerDivider: {
|
|
20
|
+
y: number;
|
|
21
|
+
left: number;
|
|
22
|
+
right: number;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
export declare function computeDashboardLayout(opts: LayoutOptions): DashboardLayout;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const DEFAULT_RIGHT_PANE_WIDTH = 25;
|
|
2
|
+
const DEFAULT_FOOTER_HEIGHT = 1;
|
|
3
|
+
const DEFAULT_BORDER_WIDTH = 1;
|
|
4
|
+
const MIN_LEFT_PANE_WIDTH = 20;
|
|
5
|
+
export function computeDashboardLayout(opts) {
|
|
6
|
+
const totalWidth = normalizeSize(opts.totalWidth);
|
|
7
|
+
const totalHeight = normalizeSize(opts.totalHeight);
|
|
8
|
+
const borderWidth = normalizeSize(opts.borderWidth ?? DEFAULT_BORDER_WIDTH);
|
|
9
|
+
const footerHeight = normalizeSize(opts.footerHeight ?? DEFAULT_FOOTER_HEIGHT);
|
|
10
|
+
const requestedRightPaneWidth = normalizeSize(opts.rightPaneWidth ?? DEFAULT_RIGHT_PANE_WIDTH);
|
|
11
|
+
const maxX = Math.max(0, totalWidth - 1);
|
|
12
|
+
const maxY = Math.max(0, totalHeight - 1);
|
|
13
|
+
const outerBorder = { x: 0, y: 0, width: totalWidth, height: totalHeight };
|
|
14
|
+
const innerWidth = Math.max(0, totalWidth - (borderWidth * 2));
|
|
15
|
+
const innerHeight = Math.max(0, totalHeight - (borderWidth * 2));
|
|
16
|
+
const innerX = clampCoordinate(borderWidth, maxX);
|
|
17
|
+
const innerY = clampCoordinate(borderWidth, maxY);
|
|
18
|
+
const dividerWidth = innerWidth > 0 ? 1 : 0;
|
|
19
|
+
const availablePaneWidth = Math.max(0, innerWidth - dividerWidth);
|
|
20
|
+
const leftPaneWidth = computeLeftPaneWidth(availablePaneWidth, requestedRightPaneWidth);
|
|
21
|
+
const rightPaneWidth = Math.max(0, availablePaneWidth - leftPaneWidth);
|
|
22
|
+
const actualFooterHeight = Math.min(footerHeight, innerHeight);
|
|
23
|
+
const footerDividerHeight = innerHeight > actualFooterHeight ? 1 : 0;
|
|
24
|
+
const contentHeight = Math.max(0, innerHeight - actualFooterHeight - footerDividerHeight);
|
|
25
|
+
const leftPane = {
|
|
26
|
+
x: innerX,
|
|
27
|
+
y: innerY,
|
|
28
|
+
width: leftPaneWidth,
|
|
29
|
+
height: contentHeight
|
|
30
|
+
};
|
|
31
|
+
const dividerX = clampCoordinate(leftPane.x + leftPane.width, maxX);
|
|
32
|
+
const rightPane = {
|
|
33
|
+
x: clampCoordinate(dividerX + dividerWidth, maxX),
|
|
34
|
+
y: innerY,
|
|
35
|
+
width: rightPaneWidth,
|
|
36
|
+
height: contentHeight
|
|
37
|
+
};
|
|
38
|
+
const dividerTop = innerY;
|
|
39
|
+
const dividerBottom = clampCoordinate(dividerTop + Math.max(contentHeight - 1, 0), maxY);
|
|
40
|
+
const footerDividerY = clampCoordinate(innerY + contentHeight, maxY);
|
|
41
|
+
const footerY = clampCoordinate(footerDividerY + footerDividerHeight, maxY);
|
|
42
|
+
const footerDividerLeft = innerX;
|
|
43
|
+
const footerDividerRight = clampCoordinate(Math.max(innerX, totalWidth - borderWidth - 1), maxX);
|
|
44
|
+
return {
|
|
45
|
+
outerBorder,
|
|
46
|
+
leftPane,
|
|
47
|
+
rightPane,
|
|
48
|
+
divider: {
|
|
49
|
+
x: dividerX,
|
|
50
|
+
top: dividerTop,
|
|
51
|
+
bottom: dividerBottom
|
|
52
|
+
},
|
|
53
|
+
footer: {
|
|
54
|
+
x: innerX,
|
|
55
|
+
y: footerY,
|
|
56
|
+
width: innerWidth,
|
|
57
|
+
height: actualFooterHeight
|
|
58
|
+
},
|
|
59
|
+
footerDivider: {
|
|
60
|
+
y: footerDividerY,
|
|
61
|
+
left: footerDividerLeft,
|
|
62
|
+
right: footerDividerRight
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function computeLeftPaneWidth(availablePaneWidth, requestedRightPaneWidth) {
|
|
67
|
+
if (availablePaneWidth <= 0) {
|
|
68
|
+
return 0;
|
|
69
|
+
}
|
|
70
|
+
const maxRightPaneWidth = Math.max(0, availablePaneWidth - MIN_LEFT_PANE_WIDTH);
|
|
71
|
+
const rightPaneWidth = Math.min(requestedRightPaneWidth, maxRightPaneWidth);
|
|
72
|
+
return Math.max(0, availablePaneWidth - rightPaneWidth);
|
|
73
|
+
}
|
|
74
|
+
function normalizeSize(value) {
|
|
75
|
+
return Math.max(0, Math.floor(value));
|
|
76
|
+
}
|
|
77
|
+
function clampCoordinate(value, max) {
|
|
78
|
+
return Math.max(0, Math.min(value, max));
|
|
79
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { DashboardStats, OutputItem } from "./types.js";
|
|
2
|
+
export type SnapshotOptions = {
|
|
3
|
+
width?: number;
|
|
4
|
+
height?: number;
|
|
5
|
+
title?: string;
|
|
6
|
+
statsTitle?: string;
|
|
7
|
+
items?: OutputItem[];
|
|
8
|
+
stats?: DashboardStats;
|
|
9
|
+
};
|
|
10
|
+
export declare function renderDashboardSnapshot(opts?: SnapshotOptions): string;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { ScreenBuffer, cellToAnsi } from "./buffer.js";
|
|
2
|
+
import { renderBorder } from "./components/border.js";
|
|
3
|
+
import { defaultHints, renderFooter } from "./components/footer.js";
|
|
4
|
+
import { renderOutputPane } from "./components/output-pane.js";
|
|
5
|
+
import { renderStatsPane } from "./components/stats-pane.js";
|
|
6
|
+
import { computeDashboardLayout } from "./layout.js";
|
|
7
|
+
const SNAPSHOT_WIDTH = 80;
|
|
8
|
+
const SNAPSHOT_HEIGHT = 20;
|
|
9
|
+
const RIGHT_PANE_WIDTH = 25;
|
|
10
|
+
export function renderDashboardSnapshot(opts = {}) {
|
|
11
|
+
const width = opts.width ?? SNAPSHOT_WIDTH;
|
|
12
|
+
const height = opts.height ?? SNAPSHOT_HEIGHT;
|
|
13
|
+
const title = opts.title ?? "Agent Output";
|
|
14
|
+
const statsTitle = opts.statsTitle ?? "Stats";
|
|
15
|
+
const items = opts.items ?? defaultItems();
|
|
16
|
+
const stats = opts.stats ?? defaultStats();
|
|
17
|
+
const layout = computeDashboardLayout({
|
|
18
|
+
totalWidth: width,
|
|
19
|
+
totalHeight: height,
|
|
20
|
+
rightPaneWidth: RIGHT_PANE_WIDTH
|
|
21
|
+
});
|
|
22
|
+
const buffer = new ScreenBuffer(width, height);
|
|
23
|
+
renderBorder(buffer, layout, {
|
|
24
|
+
leftTitle: title,
|
|
25
|
+
rightTitle: statsTitle,
|
|
26
|
+
style: { dim: true }
|
|
27
|
+
});
|
|
28
|
+
renderOutputPane(buffer, layout.leftPane, {
|
|
29
|
+
items,
|
|
30
|
+
scrollOffset: 0,
|
|
31
|
+
autoFollow: true
|
|
32
|
+
});
|
|
33
|
+
renderStatsPane(buffer, layout.rightPane, stats);
|
|
34
|
+
renderFooter(buffer, layout.footer, defaultHints());
|
|
35
|
+
return bufferToAnsi(buffer);
|
|
36
|
+
}
|
|
37
|
+
function bufferToAnsi(buffer) {
|
|
38
|
+
const lines = [];
|
|
39
|
+
for (let y = 0; y < buffer.height; y += 1) {
|
|
40
|
+
let line = "";
|
|
41
|
+
for (let x = 0; x < buffer.width; x += 1) {
|
|
42
|
+
line += cellToAnsi(buffer.get(x, y));
|
|
43
|
+
}
|
|
44
|
+
lines.push(line);
|
|
45
|
+
}
|
|
46
|
+
return lines.join("\n");
|
|
47
|
+
}
|
|
48
|
+
function defaultItems() {
|
|
49
|
+
const now = Date.now();
|
|
50
|
+
return [
|
|
51
|
+
{ kind: "info", text: "Analyzing repository state", ts: now },
|
|
52
|
+
{ kind: "tool", text: "Running npm test -- --runInBand", ts: now + 500 },
|
|
53
|
+
{ kind: "success", text: "Generated provider config", ts: now + 1000 },
|
|
54
|
+
{ kind: "status", text: "Streaming model response", ts: now + 1500 },
|
|
55
|
+
{ kind: "info", text: "Inspecting agent configuration", ts: now + 2000 },
|
|
56
|
+
{ kind: "tool", text: "Executing npm run lint:types", ts: now + 2500 },
|
|
57
|
+
{ kind: "error", text: "Retrying transient network request", ts: now + 3000 },
|
|
58
|
+
{ kind: "success", text: "Updated dashboard layout", ts: now + 3500 },
|
|
59
|
+
{ kind: "info", text: "Collecting recent command output", ts: now + 4000 },
|
|
60
|
+
{ kind: "status", text: "Waiting for follow-up task", ts: now + 4500 }
|
|
61
|
+
];
|
|
62
|
+
}
|
|
63
|
+
function defaultStats() {
|
|
64
|
+
return {
|
|
65
|
+
status: "running",
|
|
66
|
+
iterations: 5,
|
|
67
|
+
tokensIn: 685,
|
|
68
|
+
tokensOut: 445,
|
|
69
|
+
elapsedMs: 5000,
|
|
70
|
+
currentAction: "Executing tool call"
|
|
71
|
+
};
|
|
72
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Command, DashboardState, DashboardStats, OutputItem } from "./types.js";
|
|
2
|
+
export type DashboardStore = {
|
|
3
|
+
getState(): DashboardState;
|
|
4
|
+
appendOutput(item: OutputItem): void;
|
|
5
|
+
updateStats(partial: Partial<DashboardStats>): void;
|
|
6
|
+
dispatch(command: Command, paneHeight: number): void;
|
|
7
|
+
onChange(handler: () => void): () => void;
|
|
8
|
+
};
|
|
9
|
+
export declare function createStore(): DashboardStore;
|