atom-lite 0.1.0 → 0.5.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/CHANGELOG.md +57 -0
- package/README.md +58 -10
- package/dist/agent/loop.d.ts +11 -0
- package/dist/agent/loop.js +238 -47
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/model-turn.d.ts +37 -0
- package/dist/agent/model-turn.js +53 -0
- package/dist/agent/model-turn.js.map +1 -0
- package/dist/agent/turn-recorder.d.ts +33 -0
- package/dist/agent/turn-recorder.js +74 -0
- package/dist/agent/turn-recorder.js.map +1 -0
- package/dist/agent/types.d.ts +4 -0
- package/dist/cli/activity.d.ts +45 -0
- package/dist/cli/activity.js +141 -0
- package/dist/cli/activity.js.map +1 -0
- package/dist/cli/app.js +1234 -378
- package/dist/cli/app.js.map +1 -1
- package/dist/cli/approval-prompt.d.ts +24 -0
- package/dist/cli/approval-prompt.js +82 -0
- package/dist/cli/approval-prompt.js.map +1 -0
- package/dist/cli/banner.d.ts +5 -1
- package/dist/cli/banner.js +10 -4
- package/dist/cli/banner.js.map +1 -1
- package/dist/cli/commands.d.ts +92 -14
- package/dist/cli/commands.js +330 -52
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/diff.d.ts +1 -0
- package/dist/cli/diff.js +28 -0
- package/dist/cli/diff.js.map +1 -0
- package/dist/cli/input.d.ts +2 -0
- package/dist/cli/input.js +10 -0
- package/dist/cli/input.js.map +1 -0
- package/dist/cli/main.js +2 -2
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/mouse.d.ts +54 -0
- package/dist/cli/mouse.js +86 -0
- package/dist/cli/mouse.js.map +1 -0
- package/dist/cli/palette.d.ts +41 -0
- package/dist/cli/palette.js +212 -0
- package/dist/cli/palette.js.map +1 -0
- package/dist/cli/panel.d.ts +29 -0
- package/dist/cli/panel.js +48 -0
- package/dist/cli/panel.js.map +1 -0
- package/dist/cli/picker.d.ts +8 -0
- package/dist/cli/picker.js +26 -28
- package/dist/cli/picker.js.map +1 -1
- package/dist/cli/status-line.d.ts +6 -0
- package/dist/cli/status-line.js +21 -7
- package/dist/cli/status-line.js.map +1 -1
- package/dist/cli/stream-text.d.ts +4 -8
- package/dist/cli/stream-text.js +26 -12
- package/dist/cli/stream-text.js.map +1 -1
- package/dist/cli/theme.d.ts +48 -0
- package/dist/cli/theme.js +160 -0
- package/dist/cli/theme.js.map +1 -0
- package/dist/cli/tool-box.d.ts +41 -0
- package/dist/cli/tool-box.js +177 -0
- package/dist/cli/tool-box.js.map +1 -0
- package/dist/cli/transcript.d.ts +24 -1
- package/dist/cli/transcript.js +65 -2
- package/dist/cli/transcript.js.map +1 -1
- package/dist/cli/trust-prompt.d.ts +24 -0
- package/dist/cli/trust-prompt.js +89 -0
- package/dist/cli/trust-prompt.js.map +1 -0
- package/dist/config/defaults.d.ts +12 -0
- package/dist/config/defaults.js +12 -0
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/load.d.ts +2 -0
- package/dist/config/load.js +36 -0
- package/dist/config/load.js.map +1 -1
- package/dist/config/paths.d.ts +2 -0
- package/dist/config/paths.js +12 -1
- package/dist/config/paths.js.map +1 -1
- package/dist/config/schema.d.ts +53 -0
- package/dist/config/schema.js +33 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/config/write.d.ts +2 -0
- package/dist/config/write.js +9 -0
- package/dist/config/write.js.map +1 -1
- package/dist/context/builder.d.ts +7 -0
- package/dist/context/builder.js +11 -0
- package/dist/context/builder.js.map +1 -0
- package/dist/context/manager.d.ts +17 -3
- package/dist/context/manager.js +129 -41
- package/dist/context/manager.js.map +1 -1
- package/dist/extensions/api.d.ts +101 -0
- package/dist/extensions/api.js +219 -0
- package/dist/extensions/api.js.map +1 -0
- package/dist/extensions/discovery.d.ts +42 -0
- package/dist/extensions/discovery.js +326 -0
- package/dist/extensions/discovery.js.map +1 -0
- package/dist/extensions/loader.d.ts +68 -0
- package/dist/extensions/loader.js +353 -0
- package/dist/extensions/loader.js.map +1 -0
- package/dist/extensions/session-manager.d.ts +44 -0
- package/dist/extensions/session-manager.js +137 -0
- package/dist/extensions/session-manager.js.map +1 -0
- package/dist/extensions/tool-adapter.d.ts +12 -0
- package/dist/extensions/tool-adapter.js +157 -0
- package/dist/extensions/tool-adapter.js.map +1 -0
- package/dist/extensions/trust.d.ts +6 -0
- package/dist/extensions/trust.js +55 -0
- package/dist/extensions/trust.js.map +1 -0
- package/dist/extensions/types.d.ts +94 -0
- package/dist/extensions/types.js +2 -0
- package/dist/extensions/types.js.map +1 -0
- package/dist/extensions/ui.d.ts +21 -0
- package/dist/extensions/ui.js +75 -0
- package/dist/extensions/ui.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/client.d.ts +73 -0
- package/dist/mcp/client.js +363 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/mcp/format.d.ts +3 -0
- package/dist/mcp/format.js +37 -0
- package/dist/mcp/format.js.map +1 -0
- package/dist/mcp/index.d.ts +6 -0
- package/dist/mcp/index.js +7 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/manager.d.ts +53 -0
- package/dist/mcp/manager.js +349 -0
- package/dist/mcp/manager.js.map +1 -0
- package/dist/mcp/stdio-transport.d.ts +26 -0
- package/dist/mcp/stdio-transport.js +174 -0
- package/dist/mcp/stdio-transport.js.map +1 -0
- package/dist/mcp/tools.d.ts +22 -0
- package/dist/mcp/tools.js +162 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/mcp/types.d.ts +92 -0
- package/dist/mcp/types.js +2 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/providers/factory.js +1 -0
- package/dist/providers/factory.js.map +1 -1
- package/dist/runtime/executor.d.ts +2 -0
- package/dist/runtime/executor.js +4 -0
- package/dist/runtime/executor.js.map +1 -0
- package/dist/runtime/scheduler.d.ts +4 -3
- package/dist/runtime/scheduler.js +7 -98
- package/dist/runtime/scheduler.js.map +1 -1
- package/dist/runtime/tool-executor.d.ts +18 -0
- package/dist/runtime/tool-executor.js +126 -0
- package/dist/runtime/tool-executor.js.map +1 -0
- package/dist/security/process.d.ts +10 -0
- package/dist/security/process.js +36 -0
- package/dist/security/process.js.map +1 -1
- package/dist/sessions/events.d.ts +9 -0
- package/dist/sessions/events.js +11 -6
- package/dist/sessions/events.js.map +1 -1
- package/dist/sessions/history.d.ts +18 -0
- package/dist/sessions/history.js +76 -0
- package/dist/sessions/history.js.map +1 -0
- package/dist/sessions/index.d.ts +2 -0
- package/dist/sessions/index.js +2 -0
- package/dist/sessions/index.js.map +1 -1
- package/dist/sessions/search.d.ts +16 -0
- package/dist/sessions/search.js +136 -0
- package/dist/sessions/search.js.map +1 -0
- package/dist/sessions/store.js +7 -4
- package/dist/sessions/store.js.map +1 -1
- package/dist/tools/bash.js +6 -3
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/edit.js +2 -1
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/types.d.ts +6 -0
- package/dist/types.d.ts +2 -1
- package/dist/types.js.map +1 -1
- package/package.json +3 -1
package/dist/cli/stream-text.js
CHANGED
|
@@ -1,24 +1,37 @@
|
|
|
1
|
-
import {
|
|
2
|
-
/** Lines kept live while streaming; older lines are sealed into cached
|
|
1
|
+
import { Markdown } from "@earendil-works/pi-tui";
|
|
2
|
+
/** Lines kept live while streaming; older lines are sealed into cached Markdown. */
|
|
3
3
|
export const STREAM_LIVE_LINES = 200;
|
|
4
4
|
/** Extra live lines tolerated before a batch is sealed. */
|
|
5
5
|
export const STREAM_SEAL_BATCH = 200;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
const DEFAULT_MARKDOWN_THEME = {
|
|
7
|
+
heading: (t) => t,
|
|
8
|
+
link: (t) => t,
|
|
9
|
+
linkUrl: (t) => t,
|
|
10
|
+
code: (t) => t,
|
|
11
|
+
codeBlock: (t) => t,
|
|
12
|
+
codeBlockBorder: (t) => t,
|
|
13
|
+
quote: (t) => t,
|
|
14
|
+
quoteBorder: (t) => t,
|
|
15
|
+
hr: (t) => t,
|
|
16
|
+
listBullet: (t) => t,
|
|
17
|
+
bold: (t) => t,
|
|
18
|
+
italic: (t) => t,
|
|
19
|
+
strikethrough: (t) => t,
|
|
20
|
+
underline: (t) => t,
|
|
21
|
+
codeBlockIndent: " ",
|
|
22
|
+
};
|
|
12
23
|
export class StreamText {
|
|
13
24
|
transcript;
|
|
14
25
|
maxLines;
|
|
15
26
|
sealBatch;
|
|
16
27
|
buffer = "";
|
|
17
28
|
live = null;
|
|
18
|
-
|
|
29
|
+
markdownTheme;
|
|
30
|
+
constructor(transcript, maxLines = STREAM_LIVE_LINES, sealBatch = STREAM_SEAL_BATCH, markdownTheme) {
|
|
19
31
|
this.transcript = transcript;
|
|
20
32
|
this.maxLines = maxLines;
|
|
21
33
|
this.sealBatch = sealBatch;
|
|
34
|
+
this.markdownTheme = markdownTheme ?? DEFAULT_MARKDOWN_THEME;
|
|
22
35
|
}
|
|
23
36
|
append(delta) {
|
|
24
37
|
this.buffer += delta;
|
|
@@ -29,16 +42,17 @@ export class StreamText {
|
|
|
29
42
|
this.buffer = lines.slice(-keepCount).join("\n");
|
|
30
43
|
if (this.live)
|
|
31
44
|
this.transcript.container.removeChild(this.live);
|
|
32
|
-
this.transcript.add(new
|
|
33
|
-
this.live = new
|
|
45
|
+
this.transcript.add(new Markdown(sealed, 0, 0, this.markdownTheme));
|
|
46
|
+
this.live = new Markdown(this.buffer, 0, 0, this.markdownTheme);
|
|
34
47
|
this.transcript.add(this.live);
|
|
35
48
|
}
|
|
36
49
|
else {
|
|
37
50
|
if (!this.live) {
|
|
38
|
-
this.live = new
|
|
51
|
+
this.live = new Markdown("", 0, 0, this.markdownTheme);
|
|
39
52
|
this.transcript.add(this.live);
|
|
40
53
|
}
|
|
41
54
|
this.live.setText(this.buffer);
|
|
55
|
+
this.transcript.invalidate();
|
|
42
56
|
}
|
|
43
57
|
}
|
|
44
58
|
/** Stop this message; its rendered text stays in the transcript. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream-text.js","sourceRoot":"","sources":["../../src/cli/stream-text.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"stream-text.js","sourceRoot":"","sources":["../../src/cli/stream-text.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Semantic theme tokens for the TUI.
|
|
3
|
+
*
|
|
4
|
+
* Components ask for a token (for example `theme.dim`) instead of hardcoding
|
|
5
|
+
* ANSI escapes. That keeps the light, dark, and no-colour variants consistent
|
|
6
|
+
* and makes the choice testable without asserting on raw escape sequences.
|
|
7
|
+
*/
|
|
8
|
+
export type ThemeMode = "dark" | "light" | "ansi";
|
|
9
|
+
export type ThemeToken = "text" | "user" | "dim" | "accent" | "success" | "warning" | "error" | "border" | "selection" | "status" | "banner" | "heading" | "link" | "code" | "quote" | "diffAdded" | "diffRemoved" | "diffContext" | "approval";
|
|
10
|
+
export type ThemeStyle = (text: string) => string;
|
|
11
|
+
export interface Theme {
|
|
12
|
+
/** Name recorded in config (never "auto"; auto resolves to dark/light). */
|
|
13
|
+
readonly name: ThemeMode;
|
|
14
|
+
readonly mode: ThemeMode;
|
|
15
|
+
readonly tokens: Record<ThemeToken, ThemeStyle>;
|
|
16
|
+
}
|
|
17
|
+
export interface ThemeOptions {
|
|
18
|
+
/** CLI --no-color or a caller-forced no-colour session. */
|
|
19
|
+
noColor?: boolean;
|
|
20
|
+
/** Environment to inspect for NO_COLOR and COLORFGBG. */
|
|
21
|
+
env?: NodeJS.ProcessEnv;
|
|
22
|
+
/** A colour-scheme report from the terminal, when available. */
|
|
23
|
+
scheme?: "dark" | "light";
|
|
24
|
+
}
|
|
25
|
+
export declare const darkTheme: Theme;
|
|
26
|
+
/**
|
|
27
|
+
* Dark variants for foreground colours. Standard-bright colours wash out on a
|
|
28
|
+
* light background, so this theme deliberately sticks to the 30-37/90 range.
|
|
29
|
+
*/
|
|
30
|
+
export declare const lightTheme: Theme;
|
|
31
|
+
/** Terminal-palette/no-colour theme: every token is the identity function. */
|
|
32
|
+
import type { MarkdownTheme } from "@earendil-works/pi-tui";
|
|
33
|
+
export declare function markdownThemeFor(theme: Theme): MarkdownTheme;
|
|
34
|
+
export declare const ansiTheme: Theme;
|
|
35
|
+
/** Names shown in the /theme picker, including the auto sentinel. */
|
|
36
|
+
export declare function themeNames(): string[];
|
|
37
|
+
/** NO_COLOR is honoured when it is present and non-empty (per no-color.org). */
|
|
38
|
+
export declare function isNoColorEnabled(env?: NodeJS.ProcessEnv): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Best-effort background detection from COLORFGBG. The final field is the
|
|
41
|
+
* background palette index: 7 (white) and 9-15 (bright) are light, the rest
|
|
42
|
+
* are dark.
|
|
43
|
+
*/
|
|
44
|
+
export declare function detectColorScheme(env?: NodeJS.ProcessEnv): "dark" | "light" | undefined;
|
|
45
|
+
export declare function resolveThemeName(name: string, options?: ThemeOptions): "dark" | "light" | "ansi";
|
|
46
|
+
export declare function resolveTheme(name: string, options?: ThemeOptions): Theme;
|
|
47
|
+
/** Human-readable label for a configured theme name. */
|
|
48
|
+
export declare function themeLabel(name: string): string;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Semantic theme tokens for the TUI.
|
|
3
|
+
*
|
|
4
|
+
* Components ask for a token (for example `theme.dim`) instead of hardcoding
|
|
5
|
+
* ANSI escapes. That keeps the light, dark, and no-colour variants consistent
|
|
6
|
+
* and makes the choice testable without asserting on raw escape sequences.
|
|
7
|
+
*/
|
|
8
|
+
const RESET = "\x1b[0m";
|
|
9
|
+
function sgr(params) {
|
|
10
|
+
return (text) => (text ? `\x1b[${params}m${text}${RESET}` : text);
|
|
11
|
+
}
|
|
12
|
+
const identity = (text) => text;
|
|
13
|
+
function tokens(overrides) {
|
|
14
|
+
const base = {
|
|
15
|
+
text: identity,
|
|
16
|
+
user: sgr("34"),
|
|
17
|
+
dim: sgr("2"),
|
|
18
|
+
accent: sgr("36"),
|
|
19
|
+
success: sgr("32"),
|
|
20
|
+
warning: sgr("33"),
|
|
21
|
+
error: sgr("31"),
|
|
22
|
+
border: sgr("90"),
|
|
23
|
+
selection: sgr("7"),
|
|
24
|
+
status: sgr("2"),
|
|
25
|
+
banner: sgr("1;31"),
|
|
26
|
+
heading: sgr("1"),
|
|
27
|
+
link: sgr("4;36"),
|
|
28
|
+
code: sgr("36"),
|
|
29
|
+
quote: sgr("2;3"),
|
|
30
|
+
diffAdded: sgr("32"),
|
|
31
|
+
diffRemoved: sgr("31"),
|
|
32
|
+
diffContext: sgr("90"),
|
|
33
|
+
approval: sgr("33"),
|
|
34
|
+
};
|
|
35
|
+
return { ...base, ...overrides };
|
|
36
|
+
}
|
|
37
|
+
export const darkTheme = {
|
|
38
|
+
name: "dark",
|
|
39
|
+
mode: "dark",
|
|
40
|
+
tokens: tokens({}),
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Dark variants for foreground colours. Standard-bright colours wash out on a
|
|
44
|
+
* light background, so this theme deliberately sticks to the 30-37/90 range.
|
|
45
|
+
*/
|
|
46
|
+
export const lightTheme = {
|
|
47
|
+
name: "light",
|
|
48
|
+
mode: "light",
|
|
49
|
+
tokens: tokens({
|
|
50
|
+
accent: sgr("34"),
|
|
51
|
+
border: sgr("90"),
|
|
52
|
+
status: sgr("90"),
|
|
53
|
+
banner: sgr("1;35"),
|
|
54
|
+
link: sgr("4;34"),
|
|
55
|
+
code: sgr("34"),
|
|
56
|
+
quote: sgr("3"),
|
|
57
|
+
}),
|
|
58
|
+
};
|
|
59
|
+
export function markdownThemeFor(theme) {
|
|
60
|
+
const bold = (text) => `\x1b[1m${text}\x1b[0m`;
|
|
61
|
+
const italic = (text) => `\x1b[3m${text}\x1b[0m`;
|
|
62
|
+
const underline = (text) => `\x1b[4m${text}\x1b[0m`;
|
|
63
|
+
const strikethrough = (text) => `\x1b[9m${text}\x1b[0m`;
|
|
64
|
+
return {
|
|
65
|
+
heading: theme.tokens.heading,
|
|
66
|
+
link: theme.tokens.link,
|
|
67
|
+
linkUrl: theme.tokens.dim,
|
|
68
|
+
code: theme.tokens.code,
|
|
69
|
+
codeBlock: theme.tokens.code,
|
|
70
|
+
codeBlockBorder: theme.tokens.border,
|
|
71
|
+
quote: theme.tokens.quote,
|
|
72
|
+
quoteBorder: theme.tokens.border,
|
|
73
|
+
hr: theme.tokens.dim,
|
|
74
|
+
listBullet: theme.tokens.accent,
|
|
75
|
+
bold,
|
|
76
|
+
italic,
|
|
77
|
+
strikethrough,
|
|
78
|
+
underline,
|
|
79
|
+
codeBlockIndent: " ",
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
export const ansiTheme = {
|
|
83
|
+
name: "ansi",
|
|
84
|
+
mode: "ansi",
|
|
85
|
+
tokens: tokens({
|
|
86
|
+
text: identity,
|
|
87
|
+
user: identity,
|
|
88
|
+
dim: identity,
|
|
89
|
+
accent: identity,
|
|
90
|
+
success: identity,
|
|
91
|
+
warning: identity,
|
|
92
|
+
error: identity,
|
|
93
|
+
border: identity,
|
|
94
|
+
selection: identity,
|
|
95
|
+
status: identity,
|
|
96
|
+
banner: identity,
|
|
97
|
+
heading: identity,
|
|
98
|
+
link: identity,
|
|
99
|
+
code: identity,
|
|
100
|
+
quote: identity,
|
|
101
|
+
diffAdded: identity,
|
|
102
|
+
diffRemoved: identity,
|
|
103
|
+
diffContext: identity,
|
|
104
|
+
approval: identity,
|
|
105
|
+
}),
|
|
106
|
+
};
|
|
107
|
+
/** Names shown in the /theme picker, including the auto sentinel. */
|
|
108
|
+
export function themeNames() {
|
|
109
|
+
return ["auto", "dark", "light", "ansi"];
|
|
110
|
+
}
|
|
111
|
+
/** NO_COLOR is honoured when it is present and non-empty (per no-color.org). */
|
|
112
|
+
export function isNoColorEnabled(env = process.env) {
|
|
113
|
+
return typeof env.NO_COLOR === "string" && env.NO_COLOR.length > 0;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Best-effort background detection from COLORFGBG. The final field is the
|
|
117
|
+
* background palette index: 7 (white) and 9-15 (bright) are light, the rest
|
|
118
|
+
* are dark.
|
|
119
|
+
*/
|
|
120
|
+
export function detectColorScheme(env = process.env) {
|
|
121
|
+
const raw = env.COLORFGBG;
|
|
122
|
+
if (!raw)
|
|
123
|
+
return undefined;
|
|
124
|
+
const fields = raw.split(";").filter((part) => part.length > 0);
|
|
125
|
+
const background = Number.parseInt(fields[fields.length - 1] ?? "", 10);
|
|
126
|
+
if (!Number.isFinite(background))
|
|
127
|
+
return undefined;
|
|
128
|
+
return background === 7 || background >= 9 ? "light" : "dark";
|
|
129
|
+
}
|
|
130
|
+
export function resolveThemeName(name, options = {}) {
|
|
131
|
+
if (options.noColor || isNoColorEnabled(options.env))
|
|
132
|
+
return "ansi";
|
|
133
|
+
if (name === "ansi")
|
|
134
|
+
return "ansi";
|
|
135
|
+
if (name === "light")
|
|
136
|
+
return "light";
|
|
137
|
+
if (name === "dark")
|
|
138
|
+
return "dark";
|
|
139
|
+
// Unknown custom names are not loadable yet; keep the safe default.
|
|
140
|
+
if (name !== "auto")
|
|
141
|
+
return "dark";
|
|
142
|
+
return options.scheme ?? detectColorScheme(options.env) ?? "dark";
|
|
143
|
+
}
|
|
144
|
+
export function resolveTheme(name, options = {}) {
|
|
145
|
+
const resolved = resolveThemeName(name, options);
|
|
146
|
+
if (resolved === "light")
|
|
147
|
+
return lightTheme;
|
|
148
|
+
if (resolved === "ansi")
|
|
149
|
+
return ansiTheme;
|
|
150
|
+
return darkTheme;
|
|
151
|
+
}
|
|
152
|
+
/** Human-readable label for a configured theme name. */
|
|
153
|
+
export function themeLabel(name) {
|
|
154
|
+
if (name === "auto")
|
|
155
|
+
return "auto (detect)";
|
|
156
|
+
if (name === "ansi")
|
|
157
|
+
return "ansi (no colour)";
|
|
158
|
+
return name;
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=theme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.js","sourceRoot":"","sources":["../../src/cli/theme.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Component } from "@earendil-works/pi-tui";
|
|
2
|
+
export type ToolStatus = "running" | "done" | "error";
|
|
3
|
+
export interface ToolBoxOptions {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
args?: Record<string, unknown>;
|
|
7
|
+
}
|
|
8
|
+
export interface ToolResultOptions {
|
|
9
|
+
isError?: boolean;
|
|
10
|
+
diff?: string[];
|
|
11
|
+
}
|
|
12
|
+
/** A short, human-friendly summary of a tool call's arguments. */
|
|
13
|
+
export declare function formatToolArgs(name: string, args: Record<string, unknown> | undefined): string;
|
|
14
|
+
/**
|
|
15
|
+
* A boxed tool call: a cyan call panel followed by a separate output panel whose
|
|
16
|
+
* colour reflects the result (yellow while running, green on success, red on
|
|
17
|
+
* error). Keeping them distinct makes calls and results easy to scan.
|
|
18
|
+
*/
|
|
19
|
+
export declare class ToolBox implements Component {
|
|
20
|
+
readonly id: string;
|
|
21
|
+
readonly name: string;
|
|
22
|
+
readonly args: Record<string, unknown> | undefined;
|
|
23
|
+
status: ToolStatus;
|
|
24
|
+
private expanded;
|
|
25
|
+
private outputLines;
|
|
26
|
+
private outputIsDiff;
|
|
27
|
+
private liveBuffer;
|
|
28
|
+
private startedAt;
|
|
29
|
+
private finishedAt;
|
|
30
|
+
constructor(options: ToolBoxOptions);
|
|
31
|
+
setExpanded(expanded: boolean): void;
|
|
32
|
+
toggleExpanded(): boolean;
|
|
33
|
+
get isExpanded(): boolean;
|
|
34
|
+
setResult(content: string, options?: ToolResultOptions): void;
|
|
35
|
+
appendLive(text: string): void;
|
|
36
|
+
invalidate(): void;
|
|
37
|
+
render(width: number): string[];
|
|
38
|
+
private title;
|
|
39
|
+
private renderedOutput;
|
|
40
|
+
private renderOutput;
|
|
41
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { cyan, dim, green, panelBottom, panelRow, panelTop, red, yellow, wrapPanelText, } from "./panel.js";
|
|
2
|
+
const LIVE_TAIL_LINES = 8;
|
|
3
|
+
const EXPANDED_LINE_LIMIT = 600;
|
|
4
|
+
function singleLine(text) {
|
|
5
|
+
return text.replace(/\s+/g, " ").trim();
|
|
6
|
+
}
|
|
7
|
+
/** A short, human-friendly summary of a tool call's arguments. */
|
|
8
|
+
export function formatToolArgs(name, args) {
|
|
9
|
+
const a = args ?? {};
|
|
10
|
+
if (name === "bash" && typeof a.command === "string") {
|
|
11
|
+
return `$ ${singleLine(a.command)}`;
|
|
12
|
+
}
|
|
13
|
+
for (const key of ["path", "file", "file_path", "url", "query", "pattern"]) {
|
|
14
|
+
const value = a[key];
|
|
15
|
+
if (typeof value === "string" && value.trim()) {
|
|
16
|
+
return `${key}: ${singleLine(value)}`;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const json = singleLine(JSON.stringify(a));
|
|
20
|
+
return json === "{}" ? "" : json;
|
|
21
|
+
}
|
|
22
|
+
function formatDuration(ms) {
|
|
23
|
+
if (ms < 1000)
|
|
24
|
+
return `${Math.max(1, Math.round(ms))}ms`;
|
|
25
|
+
if (ms < 60_000)
|
|
26
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
27
|
+
const minutes = Math.floor(ms / 60_000);
|
|
28
|
+
const seconds = Math.floor((ms % 60_000) / 1000);
|
|
29
|
+
return `${minutes}m ${String(seconds).padStart(2, "0")}s`;
|
|
30
|
+
}
|
|
31
|
+
function colorizeDiff(line) {
|
|
32
|
+
if (line.startsWith("+++") || line.startsWith("---"))
|
|
33
|
+
return dim(line);
|
|
34
|
+
if (line.startsWith("+"))
|
|
35
|
+
return green(line);
|
|
36
|
+
if (line.startsWith("-"))
|
|
37
|
+
return red(line);
|
|
38
|
+
if (line.startsWith("@@"))
|
|
39
|
+
return cyan(line);
|
|
40
|
+
return line;
|
|
41
|
+
}
|
|
42
|
+
function tail(items, count) {
|
|
43
|
+
return items.length <= count ? items : items.slice(items.length - count);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* A boxed tool call: a cyan call panel followed by a separate output panel whose
|
|
47
|
+
* colour reflects the result (yellow while running, green on success, red on
|
|
48
|
+
* error). Keeping them distinct makes calls and results easy to scan.
|
|
49
|
+
*/
|
|
50
|
+
export class ToolBox {
|
|
51
|
+
id;
|
|
52
|
+
name;
|
|
53
|
+
args;
|
|
54
|
+
status = "running";
|
|
55
|
+
expanded = false;
|
|
56
|
+
outputLines = [];
|
|
57
|
+
outputIsDiff = false;
|
|
58
|
+
liveBuffer = "";
|
|
59
|
+
startedAt = Date.now();
|
|
60
|
+
finishedAt;
|
|
61
|
+
constructor(options) {
|
|
62
|
+
this.id = options.id;
|
|
63
|
+
this.name = options.name;
|
|
64
|
+
this.args = options.args;
|
|
65
|
+
}
|
|
66
|
+
setExpanded(expanded) {
|
|
67
|
+
this.expanded = expanded;
|
|
68
|
+
}
|
|
69
|
+
toggleExpanded() {
|
|
70
|
+
this.expanded = !this.expanded;
|
|
71
|
+
return this.expanded;
|
|
72
|
+
}
|
|
73
|
+
get isExpanded() {
|
|
74
|
+
return this.expanded;
|
|
75
|
+
}
|
|
76
|
+
setResult(content, options = {}) {
|
|
77
|
+
this.status = options.isError ? "error" : "done";
|
|
78
|
+
this.finishedAt = Date.now();
|
|
79
|
+
this.liveBuffer = "";
|
|
80
|
+
this.outputIsDiff = Array.isArray(options.diff);
|
|
81
|
+
this.outputLines = options.diff ?? content.split("\n");
|
|
82
|
+
}
|
|
83
|
+
appendLive(text) {
|
|
84
|
+
this.liveBuffer += text;
|
|
85
|
+
// The completed result carries the full, capped output. Keep the live view
|
|
86
|
+
// bounded so a chatty command cannot pin arbitrarily much text in memory.
|
|
87
|
+
if (this.liveBuffer.length > 60_000) {
|
|
88
|
+
this.liveBuffer = this.liveBuffer.slice(-60_000);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
invalidate() {
|
|
92
|
+
// No cached render state.
|
|
93
|
+
}
|
|
94
|
+
render(width) {
|
|
95
|
+
const panelWidth = Math.max(8, Math.floor(width));
|
|
96
|
+
const lines = [];
|
|
97
|
+
const callColor = this.status === "error" ? red : cyan;
|
|
98
|
+
const title = this.title();
|
|
99
|
+
lines.push(panelTop(title, panelWidth, callColor));
|
|
100
|
+
const preview = formatToolArgs(this.name, this.args);
|
|
101
|
+
if (preview) {
|
|
102
|
+
for (const line of wrapPanelText(preview, panelWidth)) {
|
|
103
|
+
lines.push(panelRow(` ${dim(line)}`, panelWidth, callColor));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (this.status === "running" && !this.liveBuffer) {
|
|
107
|
+
lines.push(panelRow(` ${dim("waiting for output…")}`, panelWidth, callColor));
|
|
108
|
+
}
|
|
109
|
+
lines.push(panelBottom(panelWidth, callColor));
|
|
110
|
+
const output = this.renderedOutput();
|
|
111
|
+
if (output.length > 0) {
|
|
112
|
+
lines.push(...this.renderOutput(output, width));
|
|
113
|
+
}
|
|
114
|
+
return lines;
|
|
115
|
+
}
|
|
116
|
+
title() {
|
|
117
|
+
if (this.status === "running") {
|
|
118
|
+
return `◌ ${this.name} · running`;
|
|
119
|
+
}
|
|
120
|
+
const elapsed = formatDuration((this.finishedAt ?? Date.now()) - this.startedAt);
|
|
121
|
+
return `${this.status === "error" ? "✗" : "✓"} ${this.name} · ${elapsed}`;
|
|
122
|
+
}
|
|
123
|
+
renderedOutput() {
|
|
124
|
+
if (this.status === "running") {
|
|
125
|
+
if (!this.liveBuffer)
|
|
126
|
+
return [];
|
|
127
|
+
const live = this.liveBuffer.replace(/\r/g, "").split("\n");
|
|
128
|
+
const visible = tail(live, LIVE_TAIL_LINES);
|
|
129
|
+
if (live.length > visible.length) {
|
|
130
|
+
return [
|
|
131
|
+
dim(`… ${live.length - visible.length} earlier lines`),
|
|
132
|
+
...visible,
|
|
133
|
+
];
|
|
134
|
+
}
|
|
135
|
+
return visible;
|
|
136
|
+
}
|
|
137
|
+
if (this.outputIsDiff) {
|
|
138
|
+
const added = this.outputLines.filter((line) => line.startsWith("+") && !line.startsWith("+++")).length;
|
|
139
|
+
const removed = this.outputLines.filter((line) => line.startsWith("-") && !line.startsWith("---")).length;
|
|
140
|
+
if (!this.expanded) {
|
|
141
|
+
return [dim(`+${added} -${removed} · ctrl+o to expand`)];
|
|
142
|
+
}
|
|
143
|
+
return this.outputLines.map(colorizeDiff);
|
|
144
|
+
}
|
|
145
|
+
if (!this.expanded) {
|
|
146
|
+
return [dim(`(${this.outputLines.length} lines · ctrl+o to expand)`)];
|
|
147
|
+
}
|
|
148
|
+
if (this.outputLines.length > EXPANDED_LINE_LIMIT) {
|
|
149
|
+
const shown = this.outputLines.slice(0, EXPANDED_LINE_LIMIT);
|
|
150
|
+
return [
|
|
151
|
+
...shown,
|
|
152
|
+
dim(`… ${this.outputLines.length - EXPANDED_LINE_LIMIT} more lines hidden`),
|
|
153
|
+
];
|
|
154
|
+
}
|
|
155
|
+
return this.outputLines;
|
|
156
|
+
}
|
|
157
|
+
renderOutput(output, width) {
|
|
158
|
+
const indent = width > 10 ? " " : "";
|
|
159
|
+
const outputWidth = Math.max(6, Math.floor(width) - indent.length);
|
|
160
|
+
const color = this.status === "error"
|
|
161
|
+
? red
|
|
162
|
+
: this.status === "running"
|
|
163
|
+
? yellow
|
|
164
|
+
: green;
|
|
165
|
+
const label = this.status === "running" ? "output · live" : "output";
|
|
166
|
+
const lines = [indent + panelTop(label, outputWidth, color)];
|
|
167
|
+
for (const raw of output) {
|
|
168
|
+
const content = raw.length === 0 ? "" : raw;
|
|
169
|
+
for (const line of wrapPanelText(content, outputWidth)) {
|
|
170
|
+
lines.push(indent + panelRow(` ${line}`, outputWidth, color));
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
lines.push(indent + panelBottom(outputWidth, color));
|
|
174
|
+
return lines;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=tool-box.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-box.js","sourceRoot":"","sources":["../../src/cli/tool-box.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/transcript.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Container, type Component } from "@earendil-works/pi-tui";
|
|
2
|
+
import { type Theme } from "./theme.js";
|
|
2
3
|
/** Soft cap on rendered transcript children before the oldest are collapsed. */
|
|
3
4
|
export declare const TRANSCRIPT_MAX_CHILDREN = 1500;
|
|
4
5
|
/** How many children to collapse when the cap is exceeded. */
|
|
@@ -7,11 +8,33 @@ export declare const TRANSCRIPT_PRUNE_COUNT = 500;
|
|
|
7
8
|
* Append-only transcript with bounded rendering work. The session store keeps
|
|
8
9
|
* the full history; this only limits what the TUI keeps as live components.
|
|
9
10
|
*/
|
|
11
|
+
declare class TranscriptContainer extends Container {
|
|
12
|
+
version: number;
|
|
13
|
+
private cachedVersion;
|
|
14
|
+
private cachedWidth;
|
|
15
|
+
private cachedLines;
|
|
16
|
+
bump(): void;
|
|
17
|
+
addChild(component: Component): void;
|
|
18
|
+
removeChild(component: Component): void;
|
|
19
|
+
clear(): void;
|
|
20
|
+
render(width: number): string[];
|
|
21
|
+
}
|
|
10
22
|
export declare class Transcript {
|
|
11
|
-
readonly container:
|
|
23
|
+
readonly container: TranscriptContainer;
|
|
12
24
|
private hidden;
|
|
13
25
|
private marker;
|
|
26
|
+
private theme;
|
|
27
|
+
constructor(theme?: Theme);
|
|
28
|
+
setTheme(theme: Theme): void;
|
|
29
|
+
/** Invalidate the rendered-line cache after a child mutates in place. */
|
|
30
|
+
invalidate(): void;
|
|
31
|
+
/** Clear all history and pruning state, e.g. when resuming a session. */
|
|
32
|
+
reset(): void;
|
|
14
33
|
get hiddenCount(): number;
|
|
15
34
|
add(child: Component): void;
|
|
35
|
+
/** Add a plain transcript line using the theme's text token. */
|
|
36
|
+
addLine(text: string): void;
|
|
37
|
+
private markerLabel;
|
|
16
38
|
private pruneIfNeeded;
|
|
17
39
|
}
|
|
40
|
+
export {};
|