codemini-cli 0.3.3 → 0.3.5
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/package.json +1 -3
- package/souls/anime.md +9 -9
- package/souls/caveman.md +6 -6
- package/souls/ceo.md +10 -9
- package/souls/default.md +1 -1
- package/souls/pirate.md +6 -6
- package/souls/playful.md +7 -7
- package/souls/professional.md +1 -1
- package/src/core/agent-loop.js +8 -2
- package/src/core/chat-runtime.js +8 -0
- package/src/core/provider/anthropic.sdk-backup.js +439 -0
- package/src/core/provider/openai-compatible.js +132 -18
- package/src/core/provider/openai-compatible.sdk-backup.js +412 -0
- package/src/core/session-store.js +8 -0
- package/src/core/shell-profile.js +9 -5
- package/src/core/tools.js +64 -12
- package/src/tui/chat-app.js +40 -21
package/src/core/tools.js
CHANGED
|
@@ -1843,7 +1843,7 @@ export function getBuiltinTools({ workspaceRoot = process.cwd(), config, onSyste
|
|
|
1843
1843
|
function: {
|
|
1844
1844
|
name: 'read',
|
|
1845
1845
|
description:
|
|
1846
|
-
'Inspect
|
|
1846
|
+
'Inspect code or text files. Use read(path) for normal file or line-window reads, read(ast_target=...) for a node-scoped AST read, and read(path, query=..., capture_name=...) to run an inline Tree-sitter query before returning the first matched node. Prefer the AST forms when targeting a function, class, or method and you want tighter context. Demo-style aliases like file_path, offset, and limit are accepted. Use metadata_only=true only when you want file metadata without content. Do not use run with cat, head, or tail for file reads.',
|
|
1847
1847
|
parameters: {
|
|
1848
1848
|
type: 'object',
|
|
1849
1849
|
properties: {
|
|
@@ -1856,7 +1856,11 @@ export function getBuiltinTools({ workspaceRoot = process.cwd(), config, onSyste
|
|
|
1856
1856
|
max_chars: { type: 'number', description: 'Max chars to return' },
|
|
1857
1857
|
include_content: { type: 'boolean', description: 'Legacy compatibility flag. Content is returned by default.' },
|
|
1858
1858
|
read_token: { type: 'string', description: 'Legacy compatibility token. No longer required for content reads.' },
|
|
1859
|
-
metadata_only: { type: 'boolean', description: 'Set true to return metadata without content.' }
|
|
1859
|
+
metadata_only: { type: 'boolean', description: 'Set true to return metadata without content.' },
|
|
1860
|
+
ast_target: { type: 'object', description: 'AST target from ast_query or a prior AST selection. When provided, read returns that node instead of a line window.' },
|
|
1861
|
+
query: { type: 'string', description: 'Optional Tree-sitter query to run inline before reading the first matched AST node. Use with path for one-shot function/class/method reads.' },
|
|
1862
|
+
capture_name: { type: 'string', description: 'Optional capture name to select when query is provided.' },
|
|
1863
|
+
language: { type: 'string', description: 'Optional Tree-sitter language override for AST reads or inline queries.' }
|
|
1860
1864
|
},
|
|
1861
1865
|
required: []
|
|
1862
1866
|
}
|
|
@@ -1923,7 +1927,7 @@ export function getBuiltinTools({ workspaceRoot = process.cwd(), config, onSyste
|
|
|
1923
1927
|
function: {
|
|
1924
1928
|
name: 'edit',
|
|
1925
1929
|
description:
|
|
1926
|
-
'Edit existing files. Prefer one of these shapes: 1) {file, old_text, new_text} for exact text replacement, 2) {file, symbol, edit:{kind:"replace_block", new_content:"..."}} for block replacement, 3) {file, anchor_text, position:"before"|"after", content:"..."} for inserts. Demo-style aliases {file_path, old_string, new_string} are also accepted. Read first unless the exact target is already known. Prefer this over write for existing code changes.',
|
|
1930
|
+
'Edit existing files. Prefer one of these shapes: 1) {file, old_text, new_text} for exact text replacement, 2) {file, symbol, edit:{kind:"replace_block", new_content:"..."}} for block replacement, 3) {file, anchor_text, position:"before"|"after", content:"..."} for inserts. Demo-style aliases {file_path, old_string, new_string} are also accepted. Read first unless the exact target is already known, and prefer read(ast_target=...) or read(path, query=...) before symbol- or block-level edits when you want tighter context. Prefer this over write for existing code changes.',
|
|
1927
1931
|
parameters: {
|
|
1928
1932
|
type: 'object',
|
|
1929
1933
|
properties: {
|
|
@@ -2053,7 +2057,7 @@ export function getBuiltinTools({ workspaceRoot = process.cwd(), config, onSyste
|
|
|
2053
2057
|
function: {
|
|
2054
2058
|
name: 'ast_query',
|
|
2055
2059
|
description:
|
|
2056
|
-
'Run a Tree-sitter query on a code file and return ast_target objects. Use this when you
|
|
2060
|
+
'Run a Tree-sitter query on a code file and return ast_target objects. Use this for advanced AST workflows such as multi-match selection, explicit node caching, or when you plan to reuse ast_target across follow-up reads or edits. For a common one-shot function, class, or method read, prefer read(path, query=...) or read(ast_target=...).',
|
|
2057
2061
|
parameters: {
|
|
2058
2062
|
type: 'object',
|
|
2059
2063
|
properties: {
|
|
@@ -2092,7 +2096,7 @@ export function getBuiltinTools({ workspaceRoot = process.cwd(), config, onSyste
|
|
|
2092
2096
|
function: {
|
|
2093
2097
|
name: 'read_ast_node',
|
|
2094
2098
|
description:
|
|
2095
|
-
'Read a previously selected AST node with compact structural context. Use this after ast_query before a scoped structural edit.',
|
|
2099
|
+
'Read a previously selected AST node with compact structural context. Use this after ast_query when you want an explicit follow-up read of a cached node before a scoped structural edit. For common one-shot AST reads, prefer read(ast_target=...) or read(path, query=...).',
|
|
2096
2100
|
parameters: {
|
|
2097
2101
|
type: 'object',
|
|
2098
2102
|
properties: {
|
|
@@ -2274,19 +2278,63 @@ export function getBuiltinTools({ workspaceRoot = process.cwd(), config, onSyste
|
|
|
2274
2278
|
const definitions = [...primaryDefinitions];
|
|
2275
2279
|
|
|
2276
2280
|
const handlers = {
|
|
2277
|
-
read: (args) =>
|
|
2278
|
-
|
|
2281
|
+
read: async (args) => {
|
|
2282
|
+
const inlineQuery = String(args?.query || '').trim();
|
|
2283
|
+
const directAstTarget = args?.ast_target;
|
|
2284
|
+
|
|
2285
|
+
if (directAstTarget) {
|
|
2286
|
+
const result = await readAstNode(workspaceRoot, {
|
|
2287
|
+
...args,
|
|
2288
|
+
path: args?.path || directAstTarget?.path,
|
|
2289
|
+
ast_target: directAstTarget
|
|
2290
|
+
});
|
|
2291
|
+
if (directAstTarget?.path) rememberAstSelection(directAstTarget.path, directAstTarget);
|
|
2292
|
+
const readPath = String(result?.path || directAstTarget?.path || '').trim();
|
|
2293
|
+
if (readPath) lastReadPath = readPath;
|
|
2294
|
+
return result;
|
|
2295
|
+
}
|
|
2296
|
+
|
|
2297
|
+
if (inlineQuery) {
|
|
2298
|
+
const queryResult = await queryAst(workspaceRoot, args);
|
|
2299
|
+
const firstTarget = queryResult?.matches?.[0]?.ast_target;
|
|
2300
|
+
if (!firstTarget) {
|
|
2301
|
+
return {
|
|
2302
|
+
path: String(args?.path || '').trim(),
|
|
2303
|
+
language: queryResult?.language,
|
|
2304
|
+
query: inlineQuery,
|
|
2305
|
+
capture_name: String(args?.capture_name || '').trim() || undefined,
|
|
2306
|
+
matches: 0,
|
|
2307
|
+
content: ''
|
|
2308
|
+
};
|
|
2309
|
+
}
|
|
2310
|
+
rememberAstSelection(firstTarget.path, firstTarget);
|
|
2311
|
+
const result = await readAstNode(workspaceRoot, {
|
|
2312
|
+
...args,
|
|
2313
|
+
path: firstTarget.path,
|
|
2314
|
+
ast_target: firstTarget
|
|
2315
|
+
});
|
|
2316
|
+
const readPath = String(result?.path || firstTarget?.path || '').trim();
|
|
2317
|
+
if (readPath) lastReadPath = readPath;
|
|
2318
|
+
return {
|
|
2319
|
+
...result,
|
|
2320
|
+
query: inlineQuery,
|
|
2321
|
+
capture_name: String(args?.capture_name || '').trim() || undefined,
|
|
2322
|
+
matches: queryResult.matches.length
|
|
2323
|
+
};
|
|
2324
|
+
}
|
|
2325
|
+
|
|
2326
|
+
const result = await readFile(workspaceRoot, {
|
|
2279
2327
|
...args,
|
|
2280
2328
|
default_lines: config.context?.read_file_default_lines ?? 220,
|
|
2281
2329
|
max_chars:
|
|
2282
2330
|
typeof args?.max_chars === 'number'
|
|
2283
2331
|
? args.max_chars
|
|
2284
2332
|
: config.context?.read_file_max_chars ?? 24000
|
|
2285
|
-
})
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2333
|
+
});
|
|
2334
|
+
const readPath = String(result?.path || args?.path || '').trim();
|
|
2335
|
+
if (readPath) lastReadPath = readPath;
|
|
2336
|
+
return result;
|
|
2337
|
+
},
|
|
2290
2338
|
query_project_index: async (args) => {
|
|
2291
2339
|
await ensureProjectIndex();
|
|
2292
2340
|
return queryProjectIndex(workspaceRoot, args);
|
|
@@ -2427,6 +2475,10 @@ export function getBuiltinTools({ workspaceRoot = process.cwd(), config, onSyste
|
|
|
2427
2475
|
read(result) {
|
|
2428
2476
|
if (typeof result === 'string') return result;
|
|
2429
2477
|
if (!result || typeof result !== 'object') return String(result);
|
|
2478
|
+
if (result.node && typeof result.content === 'string') {
|
|
2479
|
+
const header = `[AST: ${result.path || '?'} ${result.node.node_type || 'node'} ${result.node.start_line || '?'}-${result.node.end_line || '?'}${result.matches ? `, matches ${result.matches}` : ''}]`;
|
|
2480
|
+
return `${header}\n${result.content}`;
|
|
2481
|
+
}
|
|
2430
2482
|
// Phase 1 metadata: small, return as-is
|
|
2431
2483
|
if (result.phase === 'metadata') {
|
|
2432
2484
|
return JSON.stringify(result);
|
package/src/tui/chat-app.js
CHANGED
|
@@ -961,6 +961,17 @@ function normalizeRuntimeStatus(status, copy) {
|
|
|
961
961
|
};
|
|
962
962
|
}
|
|
963
963
|
|
|
964
|
+
export function shouldRefreshRuntimeStateForEvent(event) {
|
|
965
|
+
const type = String(event?.type || '');
|
|
966
|
+
return (
|
|
967
|
+
type === 'assistant:start' ||
|
|
968
|
+
type === 'assistant:delta' ||
|
|
969
|
+
type === 'assistant:response' ||
|
|
970
|
+
type === 'tool:result' ||
|
|
971
|
+
type === 'compact:auto'
|
|
972
|
+
);
|
|
973
|
+
}
|
|
974
|
+
|
|
964
975
|
function stageDescriptor(inputStage, busy, runtimeStatus, copy) {
|
|
965
976
|
const normalized = normalizeRuntimeStatus(runtimeStatus, copy);
|
|
966
977
|
const tag =
|
|
@@ -1829,6 +1840,10 @@ export function normalizeActivitySpacingRows(inputRows) {
|
|
|
1829
1840
|
}
|
|
1830
1841
|
}
|
|
1831
1842
|
|
|
1843
|
+
if (isTodoRow(row) && !isTodoRow(next) && next && !isBlankTextRow(next) && next.kind !== 'status') {
|
|
1844
|
+
normalized.push({ kind: 'todo-gap' });
|
|
1845
|
+
}
|
|
1846
|
+
|
|
1832
1847
|
if (isBlankTextRow(row) && isBlankTextRow(prev)) {
|
|
1833
1848
|
normalized.pop();
|
|
1834
1849
|
}
|
|
@@ -1954,7 +1969,7 @@ export function collapseActivityChainRows(inputRows, showToolDetails, copy, maxV
|
|
|
1954
1969
|
return collapsed;
|
|
1955
1970
|
}
|
|
1956
1971
|
|
|
1957
|
-
function buildMessageRows(msg, showToolDetails, contentWidth = 72, copy) {
|
|
1972
|
+
export function buildMessageRows(msg, showToolDetails, contentWidth = 72, copy) {
|
|
1958
1973
|
const rows = [];
|
|
1959
1974
|
const pushTextRows = (text) => {
|
|
1960
1975
|
const lines = String(text || '').split('\n');
|
|
@@ -2071,26 +2086,26 @@ function buildMessageRows(msg, showToolDetails, contentWidth = 72, copy) {
|
|
|
2071
2086
|
|
|
2072
2087
|
const codeGenerationRows = getCodeGenerationActivityRows(msg);
|
|
2073
2088
|
const generatingCodeRows = getGeneratingCodePlaceholderRows(msg, copy, contentWidth);
|
|
2074
|
-
const
|
|
2089
|
+
const trailingRows = [];
|
|
2075
2090
|
if (msg?.loading && (msg?.liveStatus || msg?.phase)) {
|
|
2076
|
-
const statusRows = [];
|
|
2077
2091
|
pushWrappedRow(
|
|
2078
|
-
|
|
2092
|
+
trailingRows,
|
|
2079
2093
|
{
|
|
2080
2094
|
kind: 'status',
|
|
2081
2095
|
text: trimText(msg.liveStatus || msg.phase, 144)
|
|
2082
2096
|
},
|
|
2083
2097
|
Math.max(8, contentWidth - 2)
|
|
2084
2098
|
);
|
|
2085
|
-
syntheticRows.push(...statusRows);
|
|
2086
2099
|
}
|
|
2087
2100
|
|
|
2088
|
-
|
|
2089
|
-
|
|
2101
|
+
const rowsWithCodePreview = insertRowsAfterLastCodeRow(
|
|
2102
|
+
collapseActivityChainRows(rows, showToolDetails, copy),
|
|
2103
|
+
[...codeGenerationRows, ...generatingCodeRows]
|
|
2090
2104
|
);
|
|
2105
|
+
return normalizeActivitySpacingRows([...rowsWithCodePreview, ...trailingRows]);
|
|
2091
2106
|
}
|
|
2092
2107
|
|
|
2093
|
-
function renderMessageRow(msg, row, idx, loaderTick) {
|
|
2108
|
+
export function renderMessageRow(msg, row, idx, loaderTick) {
|
|
2094
2109
|
if (row.kind === 'activity') {
|
|
2095
2110
|
const activity = { type: row.activityType, name: row.name, status: row.status };
|
|
2096
2111
|
const display = getActivityDisplayParts(activity);
|
|
@@ -2139,13 +2154,16 @@ function renderMessageRow(msg, row, idx, loaderTick) {
|
|
|
2139
2154
|
const dimColor = row.status === 'completed';
|
|
2140
2155
|
return h(
|
|
2141
2156
|
Box,
|
|
2142
|
-
{ key: `row-todo-${msg.id}-${idx}`, marginLeft: 2
|
|
2157
|
+
{ key: `row-todo-${msg.id}-${idx}`, marginLeft: 2 },
|
|
2143
2158
|
h(Text, { color: 'gray' }, ' '),
|
|
2144
2159
|
h(Text, { color }, marker),
|
|
2145
2160
|
h(Text, { color: 'gray' }, ' '),
|
|
2146
2161
|
h(Text, { color, dimColor }, row.text || row.activeForm || ' ')
|
|
2147
2162
|
);
|
|
2148
2163
|
}
|
|
2164
|
+
if (row.kind === 'todo-gap') {
|
|
2165
|
+
return h(Box, { key: `row-todo-gap-${msg.id}-${idx}`, marginTop: 1 }, h(Text, { color: 'gray' }, ' '));
|
|
2166
|
+
}
|
|
2149
2167
|
if (row.kind === 'table') {
|
|
2150
2168
|
return h(
|
|
2151
2169
|
Box,
|
|
@@ -2203,22 +2221,11 @@ function renderMessageRow(msg, row, idx, loaderTick) {
|
|
|
2203
2221
|
}
|
|
2204
2222
|
if (row.kind === 'status') {
|
|
2205
2223
|
const dots = '.'.repeat((loaderTick % 3) + 1);
|
|
2206
|
-
const phase = msg.phase;
|
|
2207
|
-
const color =
|
|
2208
|
-
phase === 'sending'
|
|
2209
|
-
? 'yellowBright'
|
|
2210
|
-
: phase === 'queued'
|
|
2211
|
-
? 'cyanBright'
|
|
2212
|
-
: phase === 'tooling'
|
|
2213
|
-
? 'magentaBright'
|
|
2214
|
-
: phase === 'generating'
|
|
2215
|
-
? 'greenBright'
|
|
2216
|
-
: 'cyanBright';
|
|
2217
2224
|
return h(
|
|
2218
2225
|
Box,
|
|
2219
2226
|
{ key: `row-status-${msg.id}-${idx}`, marginTop: 1 },
|
|
2220
2227
|
h(Text, { color: 'gray' }, ' '),
|
|
2221
|
-
h(Text, { color }, `${row.text}${dots}`)
|
|
2228
|
+
h(Text, { color: 'gray', dimColor: true }, `${row.text}${dots}`)
|
|
2222
2229
|
);
|
|
2223
2230
|
}
|
|
2224
2231
|
if (row.kind === 'quote') {
|
|
@@ -2762,6 +2769,15 @@ export function ChatApp({ runtime, sessionId, model, sdkProvider = 'openai-compa
|
|
|
2762
2769
|
setRuntimeStatus(makeIdleStatus(copy, snapshot, variant));
|
|
2763
2770
|
};
|
|
2764
2771
|
|
|
2772
|
+
const refreshRuntimeSnapshot = () => {
|
|
2773
|
+
const snapshot = runtime.getRuntimeState?.();
|
|
2774
|
+
if (!snapshot) return;
|
|
2775
|
+
setDisplaySessionId(snapshot.sessionId || sessionId);
|
|
2776
|
+
setDisplayModel(snapshot.model || model);
|
|
2777
|
+
setDisplaySdkProvider(snapshot.sdkProvider || sdkProvider);
|
|
2778
|
+
setRuntimeState(snapshot);
|
|
2779
|
+
};
|
|
2780
|
+
|
|
2765
2781
|
useEffect(() => {
|
|
2766
2782
|
syncRuntimeVisualState('ready');
|
|
2767
2783
|
}, []);
|
|
@@ -3137,6 +3153,9 @@ export function ChatApp({ runtime, sessionId, model, sdkProvider = 'openai-compa
|
|
|
3137
3153
|
|
|
3138
3154
|
runtime
|
|
3139
3155
|
.submit(line, (event) => {
|
|
3156
|
+
if (shouldRefreshRuntimeStateForEvent(event)) {
|
|
3157
|
+
refreshRuntimeSnapshot();
|
|
3158
|
+
}
|
|
3140
3159
|
if (event?.type === 'assistant:start') {
|
|
3141
3160
|
streamedAssistantHandledRef.current = true;
|
|
3142
3161
|
setRuntimeStatus(makeStatus(copy.runtime.modelThinking, copy.runtime.requestDelivered, 'cyanBright'));
|