toolcraft 0.0.1
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 +91 -0
- package/dist/cli.compile-check.d.ts +1 -0
- package/dist/cli.compile-check.js +26 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.js +1312 -0
- package/dist/index.compile-check.d.ts +1 -0
- package/dist/index.compile-check.js +50 -0
- package/dist/index.d.ts +164 -0
- package/dist/index.js +366 -0
- package/dist/mcp.compile-check.d.ts +1 -0
- package/dist/mcp.compile-check.js +26 -0
- package/dist/mcp.d.ts +31 -0
- package/dist/mcp.js +354 -0
- package/dist/number-schema.d.ts +3 -0
- package/dist/number-schema.js +8 -0
- package/dist/renderer.d.ts +5 -0
- package/dist/renderer.js +148 -0
- package/dist/schema-scope.d.ts +4 -0
- package/dist/schema-scope.js +34 -0
- package/dist/sdk.compile-check.d.ts +1 -0
- package/dist/sdk.compile-check.js +79 -0
- package/dist/sdk.d.ts +63 -0
- package/dist/sdk.js +218 -0
- package/node_modules/@poe-code/design-system/dist/acp/components.d.ts +11 -0
- package/node_modules/@poe-code/design-system/dist/acp/components.js +121 -0
- package/node_modules/@poe-code/design-system/dist/acp/index.d.ts +3 -0
- package/node_modules/@poe-code/design-system/dist/acp/index.js +2 -0
- package/node_modules/@poe-code/design-system/dist/acp/writer.d.ts +13 -0
- package/node_modules/@poe-code/design-system/dist/acp/writer.js +21 -0
- package/node_modules/@poe-code/design-system/dist/components/command-errors.d.ts +16 -0
- package/node_modules/@poe-code/design-system/dist/components/command-errors.js +22 -0
- package/node_modules/@poe-code/design-system/dist/components/help-formatter.d.ts +20 -0
- package/node_modules/@poe-code/design-system/dist/components/help-formatter.js +27 -0
- package/node_modules/@poe-code/design-system/dist/components/index.d.ts +10 -0
- package/node_modules/@poe-code/design-system/dist/components/index.js +7 -0
- package/node_modules/@poe-code/design-system/dist/components/logger.d.ts +11 -0
- package/node_modules/@poe-code/design-system/dist/components/logger.js +60 -0
- package/node_modules/@poe-code/design-system/dist/components/symbols.d.ts +12 -0
- package/node_modules/@poe-code/design-system/dist/components/symbols.js +71 -0
- package/node_modules/@poe-code/design-system/dist/components/table.d.ts +13 -0
- package/node_modules/@poe-code/design-system/dist/components/table.js +74 -0
- package/node_modules/@poe-code/design-system/dist/components/text.d.ts +14 -0
- package/node_modules/@poe-code/design-system/dist/components/text.js +104 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/ansi.d.ts +18 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/ansi.js +298 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/buffer.d.ts +25 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/buffer.js +189 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/components/border.d.ts +9 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/components/border.js +123 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/components/footer.d.ts +8 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/components/footer.js +57 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/components/output-pane.d.ts +12 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/components/output-pane.js +254 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/components/stats-pane.d.ts +7 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/components/stats-pane.js +121 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/dashboard.d.ts +20 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/dashboard.js +167 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/demo.d.ts +13 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/demo.js +145 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/index.d.ts +8 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/index.js +4 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/keymap.d.ts +3 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/keymap.js +99 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/layout.d.ts +25 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/layout.js +79 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/should-use-dashboard.d.ts +10 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/should-use-dashboard.js +7 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/snapshot.d.ts +10 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/snapshot.js +68 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/store.d.ts +8 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/store.js +51 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/terminal.d.ts +37 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/terminal.js +233 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/types.d.ts +36 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/types.js +1 -0
- package/node_modules/@poe-code/design-system/dist/index.d.ts +33 -0
- package/node_modules/@poe-code/design-system/dist/index.js +31 -0
- package/node_modules/@poe-code/design-system/dist/internal/output-format.d.ts +6 -0
- package/node_modules/@poe-code/design-system/dist/internal/output-format.js +22 -0
- package/node_modules/@poe-code/design-system/dist/internal/strip-ansi.d.ts +1 -0
- package/node_modules/@poe-code/design-system/dist/internal/strip-ansi.js +3 -0
- package/node_modules/@poe-code/design-system/dist/internal/theme-detect.d.ts +11 -0
- package/node_modules/@poe-code/design-system/dist/internal/theme-detect.js +49 -0
- package/node_modules/@poe-code/design-system/dist/prompts/index.d.ts +66 -0
- package/node_modules/@poe-code/design-system/dist/prompts/index.js +132 -0
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/cancel.d.ts +2 -0
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/cancel.js +9 -0
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/intro.d.ts +1 -0
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/intro.js +15 -0
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/log.d.ts +18 -0
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/log.js +101 -0
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/note.d.ts +1 -0
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/note.js +39 -0
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/outro.d.ts +1 -0
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/outro.js +16 -0
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/spinner.d.ts +6 -0
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/spinner.js +74 -0
- package/node_modules/@poe-code/design-system/dist/prompts/theme.d.ts +11 -0
- package/node_modules/@poe-code/design-system/dist/prompts/theme.js +12 -0
- package/node_modules/@poe-code/design-system/dist/static/index.d.ts +4 -0
- package/node_modules/@poe-code/design-system/dist/static/index.js +2 -0
- package/node_modules/@poe-code/design-system/dist/static/menu.d.ts +11 -0
- package/node_modules/@poe-code/design-system/dist/static/menu.js +36 -0
- package/node_modules/@poe-code/design-system/dist/static/spinner.d.ts +14 -0
- package/node_modules/@poe-code/design-system/dist/static/spinner.js +46 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/ast.d.ts +92 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/ast.js +1 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/demo-content.d.ts +2 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/demo-content.js +139 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/index.d.ts +6 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/index.js +8 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/parser/block.d.ts +7 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/parser/block.js +1495 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/parser/frontmatter.d.ts +8 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/parser/frontmatter.js +412 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/parser/inline.d.ts +10 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/parser/inline.js +1166 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/parser.d.ts +5 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/parser.js +42 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/renderer.d.ts +6 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/renderer.js +572 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/testing/theme-render-fixture.d.ts +1 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/testing/theme-render-fixture.js +27 -0
- package/node_modules/@poe-code/design-system/dist/tokens/colors.d.ts +35 -0
- package/node_modules/@poe-code/design-system/dist/tokens/colors.js +34 -0
- package/node_modules/@poe-code/design-system/dist/tokens/index.d.ts +4 -0
- package/node_modules/@poe-code/design-system/dist/tokens/index.js +4 -0
- package/node_modules/@poe-code/design-system/dist/tokens/spacing.d.ts +6 -0
- package/node_modules/@poe-code/design-system/dist/tokens/spacing.js +6 -0
- package/node_modules/@poe-code/design-system/dist/tokens/typography.d.ts +7 -0
- package/node_modules/@poe-code/design-system/dist/tokens/typography.js +8 -0
- package/node_modules/@poe-code/design-system/dist/tokens/widths.d.ts +5 -0
- package/node_modules/@poe-code/design-system/dist/tokens/widths.js +5 -0
- package/node_modules/@poe-code/design-system/package.json +25 -0
- package/package.json +57 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { resolveOutputFormat } from "../internal/output-format.js";
|
|
2
|
+
export function shouldUseInteractiveDashboard(enabled, io = process) {
|
|
3
|
+
return enabled === true
|
|
4
|
+
&& resolveOutputFormat() === "terminal"
|
|
5
|
+
&& Boolean(io.stdin.isTTY)
|
|
6
|
+
&& Boolean(io.stdout.isTTY);
|
|
7
|
+
}
|
|
@@ -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,68 @@
|
|
|
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, items);
|
|
29
|
+
renderStatsPane(buffer, layout.rightPane, stats);
|
|
30
|
+
renderFooter(buffer, layout.footer, defaultHints());
|
|
31
|
+
return bufferToAnsi(buffer);
|
|
32
|
+
}
|
|
33
|
+
function bufferToAnsi(buffer) {
|
|
34
|
+
const lines = [];
|
|
35
|
+
for (let y = 0; y < buffer.height; y += 1) {
|
|
36
|
+
let line = "";
|
|
37
|
+
for (let x = 0; x < buffer.width; x += 1) {
|
|
38
|
+
line += cellToAnsi(buffer.get(x, y));
|
|
39
|
+
}
|
|
40
|
+
lines.push(line);
|
|
41
|
+
}
|
|
42
|
+
return lines.join("\n");
|
|
43
|
+
}
|
|
44
|
+
function defaultItems() {
|
|
45
|
+
const now = Date.now();
|
|
46
|
+
return [
|
|
47
|
+
{ kind: "info", text: "Analyzing repository state", ts: now },
|
|
48
|
+
{ kind: "tool", text: "Running npm test -- --runInBand", ts: now + 500 },
|
|
49
|
+
{ kind: "success", text: "Generated provider config", ts: now + 1000 },
|
|
50
|
+
{ kind: "status", text: "Streaming model response", ts: now + 1500 },
|
|
51
|
+
{ kind: "info", text: "Inspecting agent configuration", ts: now + 2000 },
|
|
52
|
+
{ kind: "tool", text: "Executing npm run lint:types", ts: now + 2500 },
|
|
53
|
+
{ kind: "error", text: "Retrying transient network request", ts: now + 3000 },
|
|
54
|
+
{ kind: "success", text: "Updated dashboard layout", ts: now + 3500 },
|
|
55
|
+
{ kind: "info", text: "Collecting recent command output", ts: now + 4000 },
|
|
56
|
+
{ kind: "status", text: "Waiting for follow-up task", ts: now + 4500 }
|
|
57
|
+
];
|
|
58
|
+
}
|
|
59
|
+
function defaultStats() {
|
|
60
|
+
return {
|
|
61
|
+
status: "running",
|
|
62
|
+
iterations: 5,
|
|
63
|
+
tokensIn: 685,
|
|
64
|
+
tokensOut: 445,
|
|
65
|
+
elapsedMs: 5000,
|
|
66
|
+
currentAction: "Executing tool call"
|
|
67
|
+
};
|
|
68
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { 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
|
+
onChange(handler: () => void): () => void;
|
|
7
|
+
};
|
|
8
|
+
export declare function createStore(): DashboardStore;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const MAX_RETAINED_OUTPUT = 256;
|
|
2
|
+
export function createStore() {
|
|
3
|
+
let state = {
|
|
4
|
+
output: [],
|
|
5
|
+
stats: {
|
|
6
|
+
status: "idle",
|
|
7
|
+
iterations: 0,
|
|
8
|
+
tokensIn: 0,
|
|
9
|
+
tokensOut: 0,
|
|
10
|
+
elapsedMs: 0
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
const listeners = new Set();
|
|
14
|
+
function notify() {
|
|
15
|
+
for (const listener of listeners) {
|
|
16
|
+
listener();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function getState() {
|
|
20
|
+
return state;
|
|
21
|
+
}
|
|
22
|
+
function appendOutput(item) {
|
|
23
|
+
const next = state.output.length >= MAX_RETAINED_OUTPUT
|
|
24
|
+
? [...state.output.slice(state.output.length - MAX_RETAINED_OUTPUT + 1), item]
|
|
25
|
+
: [...state.output, item];
|
|
26
|
+
state = { ...state, output: next };
|
|
27
|
+
notify();
|
|
28
|
+
}
|
|
29
|
+
function updateStats(partial) {
|
|
30
|
+
state = {
|
|
31
|
+
...state,
|
|
32
|
+
stats: {
|
|
33
|
+
...state.stats,
|
|
34
|
+
...partial
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
notify();
|
|
38
|
+
}
|
|
39
|
+
function onChange(handler) {
|
|
40
|
+
listeners.add(handler);
|
|
41
|
+
return () => {
|
|
42
|
+
listeners.delete(handler);
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
getState,
|
|
47
|
+
appendOutput,
|
|
48
|
+
updateStats,
|
|
49
|
+
onChange
|
|
50
|
+
};
|
|
51
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Cell } from "./types.js";
|
|
2
|
+
export type KeypressEvent = {
|
|
3
|
+
name?: string;
|
|
4
|
+
ch?: string;
|
|
5
|
+
ctrl: boolean;
|
|
6
|
+
meta: boolean;
|
|
7
|
+
shift: boolean;
|
|
8
|
+
};
|
|
9
|
+
export type TerminalDriver = {
|
|
10
|
+
enterRawMode(): void;
|
|
11
|
+
exitRawMode(): void;
|
|
12
|
+
enterAltScreen(): void;
|
|
13
|
+
exitAltScreen(): void;
|
|
14
|
+
disableLineWrap(): void;
|
|
15
|
+
enableLineWrap(): void;
|
|
16
|
+
hideCursor(): void;
|
|
17
|
+
showCursor(): void;
|
|
18
|
+
moveTo(x: number, y: number): void;
|
|
19
|
+
write(text: string): void;
|
|
20
|
+
flush(changes: Array<{
|
|
21
|
+
x: number;
|
|
22
|
+
y: number;
|
|
23
|
+
cell: Cell;
|
|
24
|
+
}>): void;
|
|
25
|
+
getSize(): {
|
|
26
|
+
cols: number;
|
|
27
|
+
rows: number;
|
|
28
|
+
};
|
|
29
|
+
onResize(handler: () => void): () => void;
|
|
30
|
+
onKeypress(handler: (key: KeypressEvent) => void): () => void;
|
|
31
|
+
destroy(): void;
|
|
32
|
+
};
|
|
33
|
+
export declare function createTerminalDriver(opts?: {
|
|
34
|
+
stdin?: NodeJS.ReadStream;
|
|
35
|
+
stdout?: NodeJS.WriteStream;
|
|
36
|
+
}): TerminalDriver;
|
|
37
|
+
export declare function parseKeypress(data: Buffer): KeypressEvent | undefined;
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import readline from "node:readline";
|
|
2
|
+
import { PassThrough } from "node:stream";
|
|
3
|
+
import { cellToAnsi } from "./buffer.js";
|
|
4
|
+
export function createTerminalDriver(opts) {
|
|
5
|
+
const stdin = (opts?.stdin ?? process.stdin);
|
|
6
|
+
const stdout = (opts?.stdout ?? process.stdout);
|
|
7
|
+
const resizeListeners = new Set();
|
|
8
|
+
const keypressListeners = new Set();
|
|
9
|
+
let rawMode = false;
|
|
10
|
+
let altScreen = false;
|
|
11
|
+
let lineWrapEnabled = true;
|
|
12
|
+
let cursorHidden = false;
|
|
13
|
+
let destroyed = false;
|
|
14
|
+
readline.emitKeypressEvents(stdin);
|
|
15
|
+
function enterRawMode() {
|
|
16
|
+
if (destroyed || rawMode) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
stdin.setRawMode?.(true);
|
|
20
|
+
stdin.resume();
|
|
21
|
+
rawMode = true;
|
|
22
|
+
}
|
|
23
|
+
function exitRawMode() {
|
|
24
|
+
if (destroyed || !rawMode) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
stdin.setRawMode?.(false);
|
|
28
|
+
stdin.pause();
|
|
29
|
+
rawMode = false;
|
|
30
|
+
}
|
|
31
|
+
function enterAltScreen() {
|
|
32
|
+
if (destroyed || altScreen) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
write("\u001b[?1049h");
|
|
36
|
+
altScreen = true;
|
|
37
|
+
}
|
|
38
|
+
function exitAltScreen() {
|
|
39
|
+
if (destroyed || !altScreen) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
write("\u001b[?1049l");
|
|
43
|
+
altScreen = false;
|
|
44
|
+
}
|
|
45
|
+
function disableLineWrap() {
|
|
46
|
+
if (destroyed || !lineWrapEnabled) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
write("\u001b[?7l");
|
|
50
|
+
lineWrapEnabled = false;
|
|
51
|
+
}
|
|
52
|
+
function enableLineWrap() {
|
|
53
|
+
if (destroyed || lineWrapEnabled) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
write("\u001b[?7h");
|
|
57
|
+
lineWrapEnabled = true;
|
|
58
|
+
}
|
|
59
|
+
function hideCursor() {
|
|
60
|
+
if (destroyed || cursorHidden) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
write("\u001b[?25l");
|
|
64
|
+
cursorHidden = true;
|
|
65
|
+
}
|
|
66
|
+
function showCursor() {
|
|
67
|
+
if (destroyed || !cursorHidden) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
write("\u001b[?25h");
|
|
71
|
+
cursorHidden = false;
|
|
72
|
+
}
|
|
73
|
+
function moveTo(x, y) {
|
|
74
|
+
if (destroyed) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
write(cursorPositionAnsi(x, y));
|
|
78
|
+
}
|
|
79
|
+
function write(text) {
|
|
80
|
+
if (destroyed || text.length === 0) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
stdout.write(text);
|
|
84
|
+
}
|
|
85
|
+
function flush(changes) {
|
|
86
|
+
if (destroyed || changes.length === 0) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
let output = "";
|
|
90
|
+
for (const change of changes) {
|
|
91
|
+
output += `${cursorPositionAnsi(change.x, change.y)}${cellToAnsi(change.cell)}`;
|
|
92
|
+
}
|
|
93
|
+
write(output);
|
|
94
|
+
}
|
|
95
|
+
function getSize() {
|
|
96
|
+
return {
|
|
97
|
+
cols: normalizeSize(stdout.columns),
|
|
98
|
+
rows: normalizeSize(stdout.rows)
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function onResize(handler) {
|
|
102
|
+
if (destroyed) {
|
|
103
|
+
return () => { };
|
|
104
|
+
}
|
|
105
|
+
const listener = () => {
|
|
106
|
+
handler();
|
|
107
|
+
};
|
|
108
|
+
resizeListeners.add(listener);
|
|
109
|
+
stdout.on("resize", listener);
|
|
110
|
+
return () => {
|
|
111
|
+
if (!resizeListeners.delete(listener)) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
stdout.off("resize", listener);
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function onKeypress(handler) {
|
|
118
|
+
if (destroyed) {
|
|
119
|
+
return () => { };
|
|
120
|
+
}
|
|
121
|
+
const listener = (str, key) => {
|
|
122
|
+
const event = toKeypressEvent(str, key);
|
|
123
|
+
if (event !== undefined) {
|
|
124
|
+
handler(event);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
keypressListeners.add(listener);
|
|
128
|
+
stdin.on("keypress", listener);
|
|
129
|
+
return () => {
|
|
130
|
+
if (!keypressListeners.delete(listener)) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
stdin.off("keypress", listener);
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
function destroy() {
|
|
137
|
+
if (destroyed) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
for (const listener of keypressListeners) {
|
|
141
|
+
stdin.off("keypress", listener);
|
|
142
|
+
}
|
|
143
|
+
keypressListeners.clear();
|
|
144
|
+
for (const listener of resizeListeners) {
|
|
145
|
+
stdout.off("resize", listener);
|
|
146
|
+
}
|
|
147
|
+
resizeListeners.clear();
|
|
148
|
+
exitRawMode();
|
|
149
|
+
enableLineWrap();
|
|
150
|
+
exitAltScreen();
|
|
151
|
+
showCursor();
|
|
152
|
+
destroyed = true;
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
enterRawMode,
|
|
156
|
+
exitRawMode,
|
|
157
|
+
enterAltScreen,
|
|
158
|
+
exitAltScreen,
|
|
159
|
+
disableLineWrap,
|
|
160
|
+
enableLineWrap,
|
|
161
|
+
hideCursor,
|
|
162
|
+
showCursor,
|
|
163
|
+
moveTo,
|
|
164
|
+
write,
|
|
165
|
+
flush,
|
|
166
|
+
getSize,
|
|
167
|
+
onResize,
|
|
168
|
+
onKeypress,
|
|
169
|
+
destroy
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
export function parseKeypress(data) {
|
|
173
|
+
if (data.length === 0) {
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
176
|
+
const stream = new PassThrough();
|
|
177
|
+
const stdin = stream;
|
|
178
|
+
let event;
|
|
179
|
+
readline.emitKeypressEvents(stdin);
|
|
180
|
+
stdin.on("keypress", (str, key) => {
|
|
181
|
+
event = toKeypressEvent(str, key);
|
|
182
|
+
});
|
|
183
|
+
stream.emit("data", data);
|
|
184
|
+
stream.destroy();
|
|
185
|
+
return event;
|
|
186
|
+
}
|
|
187
|
+
function toKeypressEvent(str, key) {
|
|
188
|
+
const ctrl = key?.ctrl ?? false;
|
|
189
|
+
const meta = key?.meta ?? false;
|
|
190
|
+
const shift = key?.shift ?? false;
|
|
191
|
+
const ch = extractPrintableCharacter(str, key?.sequence);
|
|
192
|
+
if (ch !== undefined) {
|
|
193
|
+
return { ch, ctrl, meta, shift };
|
|
194
|
+
}
|
|
195
|
+
if (key?.name === undefined) {
|
|
196
|
+
return undefined;
|
|
197
|
+
}
|
|
198
|
+
return {
|
|
199
|
+
name: key.name,
|
|
200
|
+
ctrl,
|
|
201
|
+
meta,
|
|
202
|
+
shift
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
function extractPrintableCharacter(str, sequence) {
|
|
206
|
+
if (isPrintableCharacter(str)) {
|
|
207
|
+
return str;
|
|
208
|
+
}
|
|
209
|
+
if (sequence === undefined || sequence.length <= 1 || sequence[0] !== "\u001b") {
|
|
210
|
+
return undefined;
|
|
211
|
+
}
|
|
212
|
+
const candidate = sequence.slice(1);
|
|
213
|
+
return isPrintableCharacter(candidate) ? candidate : undefined;
|
|
214
|
+
}
|
|
215
|
+
function isPrintableCharacter(value) {
|
|
216
|
+
if (value === undefined || Array.from(value).length !== 1) {
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
const codePoint = value.codePointAt(0);
|
|
220
|
+
return codePoint !== undefined && codePoint >= 0x20 && codePoint !== 0x7f;
|
|
221
|
+
}
|
|
222
|
+
function cursorPositionAnsi(x, y) {
|
|
223
|
+
return `\u001b[${normalizeCoordinate(y) + 1};${normalizeCoordinate(x) + 1}H`;
|
|
224
|
+
}
|
|
225
|
+
function normalizeCoordinate(value) {
|
|
226
|
+
return Math.max(0, Math.floor(value));
|
|
227
|
+
}
|
|
228
|
+
function normalizeSize(value) {
|
|
229
|
+
if (value === undefined || !Number.isFinite(value)) {
|
|
230
|
+
return 0;
|
|
231
|
+
}
|
|
232
|
+
return Math.max(0, Math.floor(value));
|
|
233
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export type OutputItemKind = "info" | "success" | "error" | "tool" | "status";
|
|
2
|
+
export type OutputItem = {
|
|
3
|
+
kind: OutputItemKind;
|
|
4
|
+
text: string;
|
|
5
|
+
ts: number;
|
|
6
|
+
};
|
|
7
|
+
export type DashboardStats = {
|
|
8
|
+
status: "idle" | "running" | "paused" | "done" | "error";
|
|
9
|
+
iterations: number;
|
|
10
|
+
iterationsLabel?: string;
|
|
11
|
+
tokensIn: number;
|
|
12
|
+
tokensOut: number;
|
|
13
|
+
elapsedMs: number;
|
|
14
|
+
currentAction?: string;
|
|
15
|
+
};
|
|
16
|
+
export type Command = "quit" | "forceQuit" | "edit" | "pause" | "retry" | "view-log";
|
|
17
|
+
export type DashboardState = {
|
|
18
|
+
output: OutputItem[];
|
|
19
|
+
stats: DashboardStats;
|
|
20
|
+
};
|
|
21
|
+
export type CellStyle = {
|
|
22
|
+
fg?: string;
|
|
23
|
+
bg?: string;
|
|
24
|
+
bold?: boolean;
|
|
25
|
+
dim?: boolean;
|
|
26
|
+
};
|
|
27
|
+
export type Cell = {
|
|
28
|
+
ch: string;
|
|
29
|
+
style: CellStyle;
|
|
30
|
+
};
|
|
31
|
+
export type Rect = {
|
|
32
|
+
x: number;
|
|
33
|
+
y: number;
|
|
34
|
+
width: number;
|
|
35
|
+
height: number;
|
|
36
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export * as tokens from "./tokens/index.js";
|
|
2
|
+
export { brand, dark, light } from "./tokens/colors.js";
|
|
3
|
+
export type { ThemeName, ThemePalette } from "./tokens/colors.js";
|
|
4
|
+
export { spacing } from "./tokens/spacing.js";
|
|
5
|
+
export { typography } from "./tokens/typography.js";
|
|
6
|
+
export { widths } from "./tokens/widths.js";
|
|
7
|
+
export { text } from "./components/text.js";
|
|
8
|
+
export { symbols } from "./components/symbols.js";
|
|
9
|
+
export { createLogger, logger } from "./components/logger.js";
|
|
10
|
+
export type { LoggerOutput } from "./components/logger.js";
|
|
11
|
+
export { helpFormatter, formatCommand, formatUsage, formatOption, formatCommandList, formatOptionList } from "./components/help-formatter.js";
|
|
12
|
+
export type { CommandInfo, OptionInfo } from "./components/help-formatter.js";
|
|
13
|
+
export { formatCommandNotFound } from "./components/command-errors.js";
|
|
14
|
+
export { formatCommandNotFoundPanel } from "./components/command-errors.js";
|
|
15
|
+
export { renderTable } from "./components/table.js";
|
|
16
|
+
export type { TableColumn, RenderTableOptions } from "./components/table.js";
|
|
17
|
+
export * as acp from "./acp/index.js";
|
|
18
|
+
export * as dashboard from "./dashboard/index.js";
|
|
19
|
+
export { createDashboard, shouldUseInteractiveDashboard } from "./dashboard/index.js";
|
|
20
|
+
export type { Dashboard, DashboardOptions } from "./dashboard/index.js";
|
|
21
|
+
export * as prompts from "./prompts/index.js";
|
|
22
|
+
export { intro, introPlain, outro, note, select, multiselect, text as promptText, confirm, confirmOrCancel, password, spinner, withSpinner, isCancel, cancel, log, PromptCancelledError } from "./prompts/index.js";
|
|
23
|
+
export type { SelectOptions, MultiselectOptions, TextOptions, ConfirmOptions, PasswordOptions, SpinnerOptions, WithSpinnerOptions } from "./prompts/index.js";
|
|
24
|
+
export { promptTheme } from "./prompts/theme.js";
|
|
25
|
+
export * as staticRender from "./static/index.js";
|
|
26
|
+
export { SPINNER_FRAMES, renderSpinnerFrame, renderSpinnerStopped, renderMenu } from "./static/index.js";
|
|
27
|
+
export type { SpinnerFrameOptions, SpinnerStoppedOptions, MenuOption, RenderMenuOptions } from "./static/index.js";
|
|
28
|
+
export { parse, render, renderMarkdown } from "./terminal-markdown/index.js";
|
|
29
|
+
export type { MdNode, RenderOptions } from "./terminal-markdown/index.js";
|
|
30
|
+
export { getTheme, resolveThemeName, resetThemeCache } from "./internal/theme-detect.js";
|
|
31
|
+
export type { ThemeEnv } from "./internal/theme-detect.js";
|
|
32
|
+
export { resolveOutputFormat, resetOutputFormatCache, withOutputFormat } from "./internal/output-format.js";
|
|
33
|
+
export type { OutputFormat } from "./internal/output-format.js";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Tokens
|
|
2
|
+
export * as tokens from "./tokens/index.js";
|
|
3
|
+
export { brand, dark, light } from "./tokens/colors.js";
|
|
4
|
+
export { spacing } from "./tokens/spacing.js";
|
|
5
|
+
export { typography } from "./tokens/typography.js";
|
|
6
|
+
export { widths } from "./tokens/widths.js";
|
|
7
|
+
// Components
|
|
8
|
+
export { text } from "./components/text.js";
|
|
9
|
+
export { symbols } from "./components/symbols.js";
|
|
10
|
+
export { createLogger, logger } from "./components/logger.js";
|
|
11
|
+
export { helpFormatter, formatCommand, formatUsage, formatOption, formatCommandList, formatOptionList } from "./components/help-formatter.js";
|
|
12
|
+
export { formatCommandNotFound } from "./components/command-errors.js";
|
|
13
|
+
export { formatCommandNotFoundPanel } from "./components/command-errors.js";
|
|
14
|
+
export { renderTable } from "./components/table.js";
|
|
15
|
+
// ACP rendering
|
|
16
|
+
export * as acp from "./acp/index.js";
|
|
17
|
+
// Dashboard
|
|
18
|
+
export * as dashboard from "./dashboard/index.js";
|
|
19
|
+
export { createDashboard, shouldUseInteractiveDashboard } from "./dashboard/index.js";
|
|
20
|
+
// Prompts
|
|
21
|
+
export * as prompts from "./prompts/index.js";
|
|
22
|
+
export { intro, introPlain, outro, note, select, multiselect, text as promptText, confirm, confirmOrCancel, password, spinner, withSpinner, isCancel, cancel, log, PromptCancelledError } from "./prompts/index.js";
|
|
23
|
+
export { promptTheme } from "./prompts/theme.js";
|
|
24
|
+
// Static rendering
|
|
25
|
+
export * as staticRender from "./static/index.js";
|
|
26
|
+
export { SPINNER_FRAMES, renderSpinnerFrame, renderSpinnerStopped, renderMenu } from "./static/index.js";
|
|
27
|
+
// Terminal markdown
|
|
28
|
+
export { parse, render, renderMarkdown } from "./terminal-markdown/index.js";
|
|
29
|
+
// Internal utilities (for advanced use)
|
|
30
|
+
export { getTheme, resolveThemeName, resetThemeCache } from "./internal/theme-detect.js";
|
|
31
|
+
export { resolveOutputFormat, resetOutputFormatCache, withOutputFormat } from "./internal/output-format.js";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type OutputFormat = "terminal" | "markdown" | "json";
|
|
2
|
+
export declare function resolveOutputFormat(env?: {
|
|
3
|
+
OUTPUT_FORMAT?: string;
|
|
4
|
+
}): OutputFormat;
|
|
5
|
+
export declare function withOutputFormat<T>(format: OutputFormat, fn: () => T): T;
|
|
6
|
+
export declare function resetOutputFormatCache(): void;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
const VALID_FORMATS = new Set(["terminal", "markdown", "json"]);
|
|
3
|
+
const formatStorage = new AsyncLocalStorage();
|
|
4
|
+
let cached;
|
|
5
|
+
export function resolveOutputFormat(env = process.env) {
|
|
6
|
+
const scoped = formatStorage.getStore();
|
|
7
|
+
if (scoped) {
|
|
8
|
+
return scoped;
|
|
9
|
+
}
|
|
10
|
+
if (cached) {
|
|
11
|
+
return cached;
|
|
12
|
+
}
|
|
13
|
+
const raw = env.OUTPUT_FORMAT?.toLowerCase();
|
|
14
|
+
cached = VALID_FORMATS.has(raw) ? raw : "terminal";
|
|
15
|
+
return cached;
|
|
16
|
+
}
|
|
17
|
+
export function withOutputFormat(format, fn) {
|
|
18
|
+
return formatStorage.run(format, fn);
|
|
19
|
+
}
|
|
20
|
+
export function resetOutputFormatCache() {
|
|
21
|
+
cached = undefined;
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function stripAnsi(value: string): string;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type ThemeName, type ThemePalette } from "../tokens/colors.js";
|
|
2
|
+
export interface ThemeEnv {
|
|
3
|
+
POE_CODE_THEME?: string;
|
|
4
|
+
POE_THEME?: string;
|
|
5
|
+
APPLE_INTERFACE_STYLE?: string;
|
|
6
|
+
VSCODE_COLOR_THEME_KIND?: string;
|
|
7
|
+
COLORFGBG?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function resolveThemeName(env?: ThemeEnv): ThemeName;
|
|
10
|
+
export declare function getTheme(env?: ThemeEnv): ThemePalette;
|
|
11
|
+
export declare function resetThemeCache(): void;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { dark, light } from "../tokens/colors.js";
|
|
2
|
+
function detectThemeFromEnv(env) {
|
|
3
|
+
const apple = env.APPLE_INTERFACE_STYLE;
|
|
4
|
+
if (typeof apple === "string") {
|
|
5
|
+
return apple.toLowerCase() === "dark" ? "dark" : "light";
|
|
6
|
+
}
|
|
7
|
+
const vscodeKind = env.VSCODE_COLOR_THEME_KIND;
|
|
8
|
+
if (typeof vscodeKind === "string") {
|
|
9
|
+
const normalized = vscodeKind.toLowerCase();
|
|
10
|
+
if (normalized.includes("light")) {
|
|
11
|
+
return "light";
|
|
12
|
+
}
|
|
13
|
+
if (normalized.includes("dark")) {
|
|
14
|
+
return "dark";
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const colorFGBG = env.COLORFGBG;
|
|
18
|
+
if (typeof colorFGBG === "string") {
|
|
19
|
+
const parts = colorFGBG.split(";").map((part) => Number.parseInt(part, 10));
|
|
20
|
+
const background = parts.at(-1);
|
|
21
|
+
if (Number.isFinite(background)) {
|
|
22
|
+
return background >= 8 ? "light" : "dark";
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
export function resolveThemeName(env = process.env) {
|
|
28
|
+
const raw = (env.POE_CODE_THEME ?? env.POE_THEME)?.toLowerCase();
|
|
29
|
+
if (raw === "light" || raw === "dark") {
|
|
30
|
+
return raw;
|
|
31
|
+
}
|
|
32
|
+
const detected = detectThemeFromEnv(env);
|
|
33
|
+
if (detected) {
|
|
34
|
+
return detected;
|
|
35
|
+
}
|
|
36
|
+
return "dark";
|
|
37
|
+
}
|
|
38
|
+
let cachedTheme;
|
|
39
|
+
export function getTheme(env) {
|
|
40
|
+
if (cachedTheme) {
|
|
41
|
+
return cachedTheme;
|
|
42
|
+
}
|
|
43
|
+
const themeName = resolveThemeName(env);
|
|
44
|
+
cachedTheme = themeName === "light" ? light : dark;
|
|
45
|
+
return cachedTheme;
|
|
46
|
+
}
|
|
47
|
+
export function resetThemeCache() {
|
|
48
|
+
cachedTheme = undefined;
|
|
49
|
+
}
|