mini-coder 0.5.11 → 0.5.13
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/BENCHMARK.md +107 -0
- package/PROGRESS.md +4 -0
- package/README.md +66 -21
- package/assets/mc-claude-smart.png +0 -0
- package/assets/mc-gpt-smart.png +0 -0
- package/benchmark-baseline.sh +15 -0
- package/benchmark-loop.sh +19 -0
- package/bun.lock +265 -90
- package/package.json +8 -7
- package/skills-lock.json +15 -0
- package/src/agent.ts +20 -0
- package/src/cli.ts +2 -1
- package/src/headless.ts +152 -38
- package/src/index.ts +107 -143
- package/src/input.ts +13 -1
- package/src/mcp.ts +609 -0
- package/src/prompt.ts +10 -12
- package/src/session-message.ts +393 -0
- package/src/session.ts +102 -396
- package/src/settings.ts +218 -22
- package/src/shared.ts +39 -0
- package/src/skills.ts +12 -3
- package/src/submit.ts +20 -25
- package/src/text.ts +71 -0
- package/src/theme.ts +186 -3
- package/src/tool-common.ts +93 -0
- package/src/tool-grep.ts +606 -0
- package/src/tool-read.ts +313 -0
- package/src/tool-shell.ts +1001 -0
- package/src/tools.ts +190 -995
- package/src/ui/agent.ts +206 -110
- package/src/ui/commands.test.ts +489 -17
- package/src/ui/commands.ts +231 -55
- package/src/ui/conversation.test.ts +585 -0
- package/src/ui/conversation.ts +878 -455
- package/src/ui/help.ts +27 -11
- package/src/ui/input.test.ts +1 -43
- package/src/ui/runtime.ts +69 -0
- package/src/ui.ts +422 -185
- package/src/plugins.ts +0 -183
package/src/theme.ts
CHANGED
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
* UI theme definition and default colors.
|
|
3
3
|
*
|
|
4
4
|
* All UI colors are read from the active {@link Theme} object — the UI
|
|
5
|
-
* never hardcodes colors.
|
|
6
|
-
* result to override any color. Multiple overrides are merged left-to-right.
|
|
5
|
+
* never hardcodes colors. Theme overrides are merged left-to-right.
|
|
7
6
|
*
|
|
8
7
|
* Theme values are cel-tui {@link Color} palette references. The default
|
|
9
8
|
* theme prefers ANSI 16-color palette entries so it adapts cleanly to the
|
|
@@ -12,11 +11,47 @@
|
|
|
12
11
|
* @module
|
|
13
12
|
*/
|
|
14
13
|
|
|
14
|
+
import type { SyntaxHighlightTheme } from "@cel-tui/components";
|
|
15
15
|
import type { Color } from "@cel-tui/types";
|
|
16
16
|
|
|
17
17
|
/** A cel-tui palette color or the terminal default when undefined. */
|
|
18
18
|
type ThemeColor = Color | undefined;
|
|
19
19
|
|
|
20
|
+
type SyntaxThemeRegistration = Exclude<SyntaxHighlightTheme, string>;
|
|
21
|
+
type SyntaxThemeTokenColor = NonNullable<
|
|
22
|
+
SyntaxThemeRegistration["tokenColors"]
|
|
23
|
+
>[number];
|
|
24
|
+
type SyntaxThemeVariant = "markdown" | "code" | "shell";
|
|
25
|
+
|
|
26
|
+
/** ANSI16 fallback hex values for syntax-highlighter theme overrides. */
|
|
27
|
+
const ANSI_COLOR_HEX: Readonly<Record<Color, string>> = {
|
|
28
|
+
color00: "#000000",
|
|
29
|
+
color01: "#cd3131",
|
|
30
|
+
color02: "#0dbc79",
|
|
31
|
+
color03: "#e5e510",
|
|
32
|
+
color04: "#2472c8",
|
|
33
|
+
color05: "#bc3fbc",
|
|
34
|
+
color06: "#11a8cd",
|
|
35
|
+
color07: "#e5e5e5",
|
|
36
|
+
color08: "#666666",
|
|
37
|
+
color09: "#f14c4c",
|
|
38
|
+
color10: "#23d18b",
|
|
39
|
+
color11: "#f5f543",
|
|
40
|
+
color12: "#3b8eea",
|
|
41
|
+
color13: "#d670d6",
|
|
42
|
+
color14: "#29b8db",
|
|
43
|
+
color15: "#ffffff",
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const syntaxThemeCache: Record<
|
|
47
|
+
SyntaxThemeVariant,
|
|
48
|
+
WeakMap<Theme, SyntaxThemeRegistration>
|
|
49
|
+
> = {
|
|
50
|
+
markdown: new WeakMap(),
|
|
51
|
+
code: new WeakMap(),
|
|
52
|
+
shell: new WeakMap(),
|
|
53
|
+
};
|
|
54
|
+
|
|
20
55
|
// ---------------------------------------------------------------------------
|
|
21
56
|
// Types
|
|
22
57
|
// ---------------------------------------------------------------------------
|
|
@@ -132,7 +167,7 @@ export const DEFAULT_THEME: Theme = {
|
|
|
132
167
|
* mutated.
|
|
133
168
|
*
|
|
134
169
|
* @param base - The base theme to start from.
|
|
135
|
-
* @param overrides - Partial theme objects to merge
|
|
170
|
+
* @param overrides - Partial theme objects to merge.
|
|
136
171
|
* @returns A complete {@link Theme} with all overrides applied.
|
|
137
172
|
*/
|
|
138
173
|
export function mergeThemes(
|
|
@@ -145,3 +180,151 @@ export function mergeThemes(
|
|
|
145
180
|
}
|
|
146
181
|
return merged;
|
|
147
182
|
}
|
|
183
|
+
|
|
184
|
+
function colorToHex(color: ThemeColor): string | undefined {
|
|
185
|
+
return color ? ANSI_COLOR_HEX[color] : undefined;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function pushSyntaxTokenColor(
|
|
189
|
+
tokenColors: SyntaxThemeTokenColor[],
|
|
190
|
+
scope: string | readonly string[],
|
|
191
|
+
foreground: ThemeColor,
|
|
192
|
+
fontStyle?: string,
|
|
193
|
+
): void {
|
|
194
|
+
const foregroundHex = colorToHex(foreground);
|
|
195
|
+
if (!foregroundHex && !fontStyle) {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
tokenColors.push({
|
|
200
|
+
scope,
|
|
201
|
+
settings: {
|
|
202
|
+
...(foregroundHex ? { foreground: foregroundHex } : {}),
|
|
203
|
+
...(fontStyle ? { fontStyle } : {}),
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function pushCodeSyntaxTokenColors(
|
|
209
|
+
tokenColors: SyntaxThemeTokenColor[],
|
|
210
|
+
theme: Theme,
|
|
211
|
+
): void {
|
|
212
|
+
pushSyntaxTokenColor(
|
|
213
|
+
tokenColors,
|
|
214
|
+
["comment", "quote", "doctag", "markup.quote"],
|
|
215
|
+
theme.mutedText,
|
|
216
|
+
"italic",
|
|
217
|
+
);
|
|
218
|
+
pushSyntaxTokenColor(
|
|
219
|
+
tokenColors,
|
|
220
|
+
["keyword", "operator"],
|
|
221
|
+
theme.secondaryAccentText,
|
|
222
|
+
);
|
|
223
|
+
pushSyntaxTokenColor(
|
|
224
|
+
tokenColors,
|
|
225
|
+
["command", "function_", "function", "title"],
|
|
226
|
+
theme.accentText,
|
|
227
|
+
);
|
|
228
|
+
pushSyntaxTokenColor(
|
|
229
|
+
tokenColors,
|
|
230
|
+
["builtin", "built_in", "class_", "class", "inherited__", "type"],
|
|
231
|
+
theme.accentText,
|
|
232
|
+
);
|
|
233
|
+
pushSyntaxTokenColor(
|
|
234
|
+
tokenColors,
|
|
235
|
+
["escape", "literal", "number", "symbol"],
|
|
236
|
+
theme.secondaryAccentText ?? theme.accentText,
|
|
237
|
+
);
|
|
238
|
+
pushSyntaxTokenColor(
|
|
239
|
+
tokenColors,
|
|
240
|
+
["code", "string", "markup.code"],
|
|
241
|
+
theme.diffAdded,
|
|
242
|
+
);
|
|
243
|
+
pushSyntaxTokenColor(tokenColors, "regexp", theme.diffRemoved);
|
|
244
|
+
pushSyntaxTokenColor(
|
|
245
|
+
tokenColors,
|
|
246
|
+
["attr", "attribute", "params", "property", "selector-attr"],
|
|
247
|
+
theme.accentText,
|
|
248
|
+
);
|
|
249
|
+
pushSyntaxTokenColor(
|
|
250
|
+
tokenColors,
|
|
251
|
+
[
|
|
252
|
+
"name",
|
|
253
|
+
"tag",
|
|
254
|
+
"selector-class",
|
|
255
|
+
"selector-id",
|
|
256
|
+
"selector-pseudo",
|
|
257
|
+
"selector-tag",
|
|
258
|
+
],
|
|
259
|
+
theme.accentText,
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function pushMarkdownSyntaxTokenColors(
|
|
264
|
+
tokenColors: SyntaxThemeTokenColor[],
|
|
265
|
+
theme: Theme,
|
|
266
|
+
): void {
|
|
267
|
+
pushSyntaxTokenColor(
|
|
268
|
+
tokenColors,
|
|
269
|
+
["quote", "markup.quote"],
|
|
270
|
+
theme.mutedText,
|
|
271
|
+
"italic",
|
|
272
|
+
);
|
|
273
|
+
pushSyntaxTokenColor(
|
|
274
|
+
tokenColors,
|
|
275
|
+
["section", "markup.heading"],
|
|
276
|
+
theme.accentText,
|
|
277
|
+
"bold",
|
|
278
|
+
);
|
|
279
|
+
pushSyntaxTokenColor(
|
|
280
|
+
tokenColors,
|
|
281
|
+
["bullet", "markup.list"],
|
|
282
|
+
theme.secondaryAccentText,
|
|
283
|
+
"bold",
|
|
284
|
+
);
|
|
285
|
+
pushSyntaxTokenColor(
|
|
286
|
+
tokenColors,
|
|
287
|
+
["code", "string", "markup.code"],
|
|
288
|
+
theme.diffAdded,
|
|
289
|
+
);
|
|
290
|
+
pushSyntaxTokenColor(tokenColors, "link", theme.accentText, "underline");
|
|
291
|
+
pushSyntaxTokenColor(tokenColors, "strong", undefined, "bold");
|
|
292
|
+
pushSyntaxTokenColor(tokenColors, "emphasis", undefined, "italic");
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Build the shared syntax-highlight theme registration for a UI theme variant.
|
|
297
|
+
*
|
|
298
|
+
* Markdown, read/code blocks, and shell/tool previews all flow through this
|
|
299
|
+
* helper so active-theme overrides stay consistent in one place. Variant names
|
|
300
|
+
* are included in the registration so cel-tui's internal SyntaxHighlight cache
|
|
301
|
+
* does not collapse code and shell renders onto the same custom-theme key.
|
|
302
|
+
*
|
|
303
|
+
* @param theme - Active UI theme.
|
|
304
|
+
* @param variant - Semantic highlighting variant for the rendered content.
|
|
305
|
+
* @returns A cached cel-tui syntax-highlight theme registration.
|
|
306
|
+
*/
|
|
307
|
+
export function getSyntaxHighlightTheme(
|
|
308
|
+
theme: Theme,
|
|
309
|
+
variant: SyntaxThemeVariant,
|
|
310
|
+
): SyntaxThemeRegistration {
|
|
311
|
+
const cache = syntaxThemeCache[variant];
|
|
312
|
+
const cached = cache.get(theme);
|
|
313
|
+
if (cached) {
|
|
314
|
+
return cached;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const tokenColors: SyntaxThemeTokenColor[] = [];
|
|
318
|
+
if (variant === "markdown") {
|
|
319
|
+
pushMarkdownSyntaxTokenColors(tokenColors, theme);
|
|
320
|
+
} else {
|
|
321
|
+
pushCodeSyntaxTokenColors(tokenColors, theme);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
const syntaxTheme: SyntaxThemeRegistration = {
|
|
325
|
+
name: `mini-coder-${variant}`,
|
|
326
|
+
tokenColors,
|
|
327
|
+
};
|
|
328
|
+
cache.set(theme, syntaxTheme);
|
|
329
|
+
return syntaxTheme;
|
|
330
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helpers for built-in tool implementations.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type {
|
|
8
|
+
ImageContent,
|
|
9
|
+
Static,
|
|
10
|
+
TextContent,
|
|
11
|
+
Tool,
|
|
12
|
+
ToolCall,
|
|
13
|
+
TSchema,
|
|
14
|
+
} from "@mariozechner/pi-ai";
|
|
15
|
+
import { validateToolArguments } from "@mariozechner/pi-ai";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Result from executing a tool.
|
|
19
|
+
*
|
|
20
|
+
* Content blocks carry either text or image data. The agent loop maps these
|
|
21
|
+
* directly into pi-ai tool-result content.
|
|
22
|
+
*/
|
|
23
|
+
export interface ToolExecResult {
|
|
24
|
+
/** Content blocks for the tool result. */
|
|
25
|
+
content: (TextContent | ImageContent)[];
|
|
26
|
+
/** Optional structured metadata preserved on the tool-result message. */
|
|
27
|
+
details?: unknown;
|
|
28
|
+
/** Whether the execution encountered an error. */
|
|
29
|
+
isError: boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Build a text-only tool result.
|
|
34
|
+
*
|
|
35
|
+
* @param text - Message text to return in the tool result.
|
|
36
|
+
* @param isError - Whether the result represents a tool error.
|
|
37
|
+
* @returns Text-only tool result content.
|
|
38
|
+
*/
|
|
39
|
+
export function textResult(text: string, isError: boolean): ToolExecResult {
|
|
40
|
+
return { content: [{ type: "text", text }], isError };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Detect which line ending a text blob uses.
|
|
45
|
+
*
|
|
46
|
+
* @param content - Text to inspect.
|
|
47
|
+
* @returns The first detected line ending, or `null` when the text is single-line.
|
|
48
|
+
*/
|
|
49
|
+
export function detectLineEnding(content: string): "\n" | "\r\n" | null {
|
|
50
|
+
if (content.includes("\r\n")) {
|
|
51
|
+
return "\r\n";
|
|
52
|
+
}
|
|
53
|
+
if (content.includes("\n")) {
|
|
54
|
+
return "\n";
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Normalize line endings to a specific style.
|
|
61
|
+
*
|
|
62
|
+
* @param content - Text to normalize.
|
|
63
|
+
* @param lineEnding - Target line ending sequence.
|
|
64
|
+
* @returns Text using only the requested line ending style.
|
|
65
|
+
*/
|
|
66
|
+
export function normalizeLineEndings(
|
|
67
|
+
content: string,
|
|
68
|
+
lineEnding: "\n" | "\r\n",
|
|
69
|
+
): string {
|
|
70
|
+
if (lineEnding === "\r\n") {
|
|
71
|
+
return content.replace(/\r?\n/g, "\r\n");
|
|
72
|
+
}
|
|
73
|
+
return content.replace(/\r\n/g, "\n");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Validate and coerce built-in tool arguments against a typed TypeBox schema.
|
|
78
|
+
*
|
|
79
|
+
* @param tool - Built-in tool definition.
|
|
80
|
+
* @param args - Raw parsed tool-call arguments from the model.
|
|
81
|
+
* @returns Validated arguments typed from the tool schema.
|
|
82
|
+
*/
|
|
83
|
+
export function validateBuiltinToolArgs<TParameters extends TSchema>(
|
|
84
|
+
tool: Tool<TParameters>,
|
|
85
|
+
args: Record<string, unknown>,
|
|
86
|
+
): Static<TParameters> {
|
|
87
|
+
return validateToolArguments(tool, {
|
|
88
|
+
type: "toolCall",
|
|
89
|
+
id: tool.name,
|
|
90
|
+
name: tool.name,
|
|
91
|
+
arguments: args,
|
|
92
|
+
} satisfies ToolCall) as Static<TParameters>;
|
|
93
|
+
}
|