codemini-cli 0.3.0 → 0.3.2
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 +2 -1
- package/souls/anime.md +13 -2
- package/souls/caveman.md +12 -2
- package/souls/ceo.md +14 -3
- package/souls/default.md +10 -2
- package/souls/pirate.md +13 -3
- package/souls/playful.md +13 -3
- package/souls/professional.md +13 -3
- package/src/cli.js +2 -1
- package/src/commands/chat.js +3 -0
- package/src/commands/run.js +6 -2
- package/src/core/agent-loop.js +13 -9
- package/src/core/ast.js +2 -55
- package/src/core/bounded-cache.js +121 -0
- package/src/core/chat-runtime.js +552 -143
- package/src/core/config-store.js +30 -0
- package/src/core/constants.js +171 -0
- package/src/core/crypto-utils.js +18 -0
- package/src/core/memory-policy.js +27 -0
- package/src/core/memory-prompt.js +45 -0
- package/src/core/memory-store.js +181 -0
- package/src/core/paths.js +8 -0
- package/src/core/project-index.js +6 -34
- package/src/core/provider/anthropic.js +388 -0
- package/src/core/provider/index.js +37 -0
- package/src/core/soul.js +3 -2
- package/src/core/tools.js +175 -71
- package/src/tui/chat-app.js +291 -38
- package/src/tui/tool-activity/presenters/command.js +14 -1
- package/src/tui/tool-activity/presenters/files.js +23 -1
- package/src/tui/tool-activity/presenters/system.js +1 -1
- package/src/tui/tool-narration/presenters/glob.js +2 -2
- package/src/tui/tool-narration/presenters/grep.js +2 -2
- package/src/tui/tool-narration/presenters/list.js +2 -2
- package/src/tui/tool-narration/presenters/run.js +2 -2
package/src/core/tools.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import crypto from 'node:crypto';
|
|
4
3
|
import { spawn } from 'node:child_process';
|
|
5
4
|
import net from 'node:net';
|
|
6
5
|
import {
|
|
@@ -16,68 +15,9 @@ import { evaluateCommandPolicy } from './command-policy.js';
|
|
|
16
15
|
import { queryAst, readAstNode, resolveAstTarget } from './ast.js';
|
|
17
16
|
import { initializeProjectIndex, queryProjectIndex, refreshIndexedFile } from './project-index.js';
|
|
18
17
|
import { checkReadDedup } from './agent-loop.js';
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
'.js',
|
|
23
|
-
'.jsx',
|
|
24
|
-
'.ts',
|
|
25
|
-
'.tsx',
|
|
26
|
-
'.json',
|
|
27
|
-
'.md',
|
|
28
|
-
'.mjs',
|
|
29
|
-
'.cjs',
|
|
30
|
-
'.py',
|
|
31
|
-
'.rb',
|
|
32
|
-
'.go',
|
|
33
|
-
'.rs',
|
|
34
|
-
'.java',
|
|
35
|
-
'.cs',
|
|
36
|
-
'.css',
|
|
37
|
-
'.scss',
|
|
38
|
-
'.html',
|
|
39
|
-
'.yml',
|
|
40
|
-
'.yaml',
|
|
41
|
-
'.sh',
|
|
42
|
-
'.ps1'
|
|
43
|
-
]);
|
|
44
|
-
const CODE_WRITE_GUARD_EXTENSIONS = new Set([
|
|
45
|
-
'.js',
|
|
46
|
-
'.jsx',
|
|
47
|
-
'.ts',
|
|
48
|
-
'.tsx',
|
|
49
|
-
'.mjs',
|
|
50
|
-
'.cjs',
|
|
51
|
-
'.py',
|
|
52
|
-
'.rb',
|
|
53
|
-
'.go',
|
|
54
|
-
'.rs',
|
|
55
|
-
'.java',
|
|
56
|
-
'.cs',
|
|
57
|
-
'.css',
|
|
58
|
-
'.scss',
|
|
59
|
-
'.html',
|
|
60
|
-
'.sh',
|
|
61
|
-
'.ps1'
|
|
62
|
-
]);
|
|
63
|
-
const LANGUAGE_FILE_TYPES = {
|
|
64
|
-
js: ['js', 'jsx', 'mjs', 'cjs'],
|
|
65
|
-
ts: ['ts', 'tsx'],
|
|
66
|
-
py: ['py'],
|
|
67
|
-
python: ['py'],
|
|
68
|
-
md: ['md'],
|
|
69
|
-
json: ['json'],
|
|
70
|
-
css: ['css', 'scss'],
|
|
71
|
-
html: ['html'],
|
|
72
|
-
java: ['java'],
|
|
73
|
-
csharp: ['cs'],
|
|
74
|
-
cs: ['cs'],
|
|
75
|
-
go: ['go'],
|
|
76
|
-
rust: ['rs'],
|
|
77
|
-
ruby: ['rb'],
|
|
78
|
-
shell: ['sh', 'ps1'],
|
|
79
|
-
yaml: ['yml', 'yaml']
|
|
80
|
-
};
|
|
18
|
+
import { TOOL_SKIP_DIRS as SKIP_DIRS, TEXT_EXTENSIONS, CODE_WRITE_GUARD_EXTENSIONS, LANGUAGE_FILE_TYPES } from './constants.js';
|
|
19
|
+
import { sha256Prefixed as sha256, sha1 } from './crypto-utils.js';
|
|
20
|
+
import { forgetMemory, listMemories, rememberMemory, searchMemories } from './memory-store.js';
|
|
81
21
|
const SERVICE_RECENT_LOG_LIMIT = 80;
|
|
82
22
|
const SERVICE_STARTUP_POLL_MS = 150;
|
|
83
23
|
const serviceRegistry = new Map();
|
|
@@ -97,14 +37,6 @@ function toWorkspaceRelative(root, absPath) {
|
|
|
97
37
|
return path.relative(path.resolve(root), absPath).replace(/\\/g, '/');
|
|
98
38
|
}
|
|
99
39
|
|
|
100
|
-
function sha256(input) {
|
|
101
|
-
return `sha256:${crypto.createHash('sha256').update(String(input || '')).digest('hex')}`;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function sha1(input) {
|
|
105
|
-
return crypto.createHash('sha1').update(String(input || '')).digest('hex');
|
|
106
|
-
}
|
|
107
|
-
|
|
108
40
|
function trimLinePreview(line, maxLen = 180) {
|
|
109
41
|
const text = String(line || '').replace(/\t/g, ' ').trim();
|
|
110
42
|
if (text.length <= maxLen) return text;
|
|
@@ -2029,6 +1961,101 @@ export function getBuiltinTools({ workspaceRoot = process.cwd(), config, onSyste
|
|
|
2029
1961
|
required: ['query']
|
|
2030
1962
|
}
|
|
2031
1963
|
}
|
|
1964
|
+
},
|
|
1965
|
+
{
|
|
1966
|
+
type: 'function',
|
|
1967
|
+
function: {
|
|
1968
|
+
name: 'remember_user',
|
|
1969
|
+
description: 'Store a durable user preference, communication habit, or long-term instruction for future sessions. Use this for things like reply style, language, explanation depth, or stable guardrails. Never store secrets, tokens, passwords, or one-off task details.',
|
|
1970
|
+
parameters: {
|
|
1971
|
+
type: 'object',
|
|
1972
|
+
properties: {
|
|
1973
|
+
content: { type: 'string', description: 'Stable preference or instruction to remember' },
|
|
1974
|
+
kind: { type: 'string', description: 'preference, workflow, constraint, or warning' },
|
|
1975
|
+
summary: { type: 'string', description: 'Short summary for the memory index' },
|
|
1976
|
+
replace_similar: { type: 'boolean', description: 'Replace an existing similar memory when true' }
|
|
1977
|
+
},
|
|
1978
|
+
required: ['content']
|
|
1979
|
+
}
|
|
1980
|
+
}
|
|
1981
|
+
},
|
|
1982
|
+
{
|
|
1983
|
+
type: 'function',
|
|
1984
|
+
function: {
|
|
1985
|
+
name: 'remember_global',
|
|
1986
|
+
description: 'Store a durable cross-project workflow, environment fact, or generally reusable lesson that can help across many repositories. Use this for stable habits like preferred search tools or repeatable debugging workflow. Never store secrets.',
|
|
1987
|
+
parameters: {
|
|
1988
|
+
type: 'object',
|
|
1989
|
+
properties: {
|
|
1990
|
+
content: { type: 'string' },
|
|
1991
|
+
kind: { type: 'string' },
|
|
1992
|
+
summary: { type: 'string' },
|
|
1993
|
+
replace_similar: { type: 'boolean' }
|
|
1994
|
+
},
|
|
1995
|
+
required: ['content']
|
|
1996
|
+
}
|
|
1997
|
+
}
|
|
1998
|
+
},
|
|
1999
|
+
{
|
|
2000
|
+
type: 'function',
|
|
2001
|
+
function: {
|
|
2002
|
+
name: 'remember_project',
|
|
2003
|
+
description: 'Store a durable project-specific convention, architecture note, key module warning, or local workflow expectation. Use this for repository-specific rules, important files, testing conventions, or architectural boundaries. Never store secrets or transient task state.',
|
|
2004
|
+
parameters: {
|
|
2005
|
+
type: 'object',
|
|
2006
|
+
properties: {
|
|
2007
|
+
content: { type: 'string' },
|
|
2008
|
+
kind: { type: 'string' },
|
|
2009
|
+
summary: { type: 'string' },
|
|
2010
|
+
replace_similar: { type: 'boolean' }
|
|
2011
|
+
},
|
|
2012
|
+
required: ['content']
|
|
2013
|
+
}
|
|
2014
|
+
}
|
|
2015
|
+
},
|
|
2016
|
+
{
|
|
2017
|
+
type: 'function',
|
|
2018
|
+
function: {
|
|
2019
|
+
name: 'list_memory',
|
|
2020
|
+
description: 'List stored persistent memories for one scope.',
|
|
2021
|
+
parameters: {
|
|
2022
|
+
type: 'object',
|
|
2023
|
+
properties: {
|
|
2024
|
+
scope: { type: 'string', description: 'user, global, or project' }
|
|
2025
|
+
},
|
|
2026
|
+
required: ['scope']
|
|
2027
|
+
}
|
|
2028
|
+
}
|
|
2029
|
+
},
|
|
2030
|
+
{
|
|
2031
|
+
type: 'function',
|
|
2032
|
+
function: {
|
|
2033
|
+
name: 'search_memory',
|
|
2034
|
+
description: 'Search stored persistent memories for one scope.',
|
|
2035
|
+
parameters: {
|
|
2036
|
+
type: 'object',
|
|
2037
|
+
properties: {
|
|
2038
|
+
scope: { type: 'string', description: 'user, global, or project' },
|
|
2039
|
+
query: { type: 'string', description: 'Search phrase' }
|
|
2040
|
+
},
|
|
2041
|
+
required: ['scope', 'query']
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
},
|
|
2045
|
+
{
|
|
2046
|
+
type: 'function',
|
|
2047
|
+
function: {
|
|
2048
|
+
name: 'forget_memory',
|
|
2049
|
+
description: 'Delete a stored persistent memory by id.',
|
|
2050
|
+
parameters: {
|
|
2051
|
+
type: 'object',
|
|
2052
|
+
properties: {
|
|
2053
|
+
scope: { type: 'string', description: 'user, global, or project' },
|
|
2054
|
+
id: { type: 'string', description: 'Memory id to delete' }
|
|
2055
|
+
},
|
|
2056
|
+
required: ['scope', 'id']
|
|
2057
|
+
}
|
|
2058
|
+
}
|
|
2032
2059
|
}
|
|
2033
2060
|
];
|
|
2034
2061
|
|
|
@@ -2249,6 +2276,55 @@ export function getBuiltinTools({ workspaceRoot = process.cwd(), config, onSyste
|
|
|
2249
2276
|
return result;
|
|
2250
2277
|
},
|
|
2251
2278
|
run: (args) => runCommand(workspaceRoot, config, args),
|
|
2279
|
+
remember_user: async (args = {}) => {
|
|
2280
|
+
const saved = await rememberMemory({
|
|
2281
|
+
scope: 'user',
|
|
2282
|
+
content: args.content,
|
|
2283
|
+
kind: args.kind,
|
|
2284
|
+
summary: args.summary,
|
|
2285
|
+
replaceSimilar: args.replace_similar !== false,
|
|
2286
|
+
workspaceRoot,
|
|
2287
|
+
config
|
|
2288
|
+
});
|
|
2289
|
+
return { ok: true, scope: 'user', memory: saved };
|
|
2290
|
+
},
|
|
2291
|
+
remember_global: async (args = {}) => {
|
|
2292
|
+
const saved = await rememberMemory({
|
|
2293
|
+
scope: 'global',
|
|
2294
|
+
content: args.content,
|
|
2295
|
+
kind: args.kind,
|
|
2296
|
+
summary: args.summary,
|
|
2297
|
+
replaceSimilar: args.replace_similar !== false,
|
|
2298
|
+
workspaceRoot,
|
|
2299
|
+
config
|
|
2300
|
+
});
|
|
2301
|
+
return { ok: true, scope: 'global', memory: saved };
|
|
2302
|
+
},
|
|
2303
|
+
remember_project: async (args = {}) => {
|
|
2304
|
+
const saved = await rememberMemory({
|
|
2305
|
+
scope: 'project',
|
|
2306
|
+
content: args.content,
|
|
2307
|
+
kind: args.kind,
|
|
2308
|
+
summary: args.summary,
|
|
2309
|
+
replaceSimilar: args.replace_similar !== false,
|
|
2310
|
+
workspaceRoot,
|
|
2311
|
+
config
|
|
2312
|
+
});
|
|
2313
|
+
return { ok: true, scope: 'project', memory: saved };
|
|
2314
|
+
},
|
|
2315
|
+
list_memory: async (args = {}) => ({
|
|
2316
|
+
scope: String(args.scope || ''),
|
|
2317
|
+
items: await listMemories({ scope: args.scope, workspaceRoot })
|
|
2318
|
+
}),
|
|
2319
|
+
search_memory: async (args = {}) => ({
|
|
2320
|
+
scope: String(args.scope || ''),
|
|
2321
|
+
query: String(args.query || ''),
|
|
2322
|
+
items: await searchMemories({ scope: args.scope, query: args.query, workspaceRoot })
|
|
2323
|
+
}),
|
|
2324
|
+
forget_memory: async (args = {}) => ({
|
|
2325
|
+
ok: true,
|
|
2326
|
+
...(await forgetMemory({ scope: args.scope, id: args.id, workspaceRoot }))
|
|
2327
|
+
}),
|
|
2252
2328
|
start_service: (args) => startService(workspaceRoot, config, args),
|
|
2253
2329
|
list_services: () => listServices(workspaceRoot),
|
|
2254
2330
|
get_service_status: (args) => getServiceStatus(workspaceRoot, args),
|
|
@@ -2401,6 +2477,34 @@ export function getBuiltinTools({ workspaceRoot = process.cwd(), config, onSyste
|
|
|
2401
2477
|
return parts.join('\n');
|
|
2402
2478
|
},
|
|
2403
2479
|
|
|
2480
|
+
remember_user(result) {
|
|
2481
|
+
return result?.memory?.content ? `stored user memory: ${result.memory.content}` : JSON.stringify(result);
|
|
2482
|
+
},
|
|
2483
|
+
|
|
2484
|
+
remember_global(result) {
|
|
2485
|
+
return result?.memory?.content ? `stored global memory: ${result.memory.content}` : JSON.stringify(result);
|
|
2486
|
+
},
|
|
2487
|
+
|
|
2488
|
+
remember_project(result) {
|
|
2489
|
+
return result?.memory?.content ? `stored project memory: ${result.memory.content}` : JSON.stringify(result);
|
|
2490
|
+
},
|
|
2491
|
+
|
|
2492
|
+
list_memory(result) {
|
|
2493
|
+
if (!result || typeof result !== 'object' || !Array.isArray(result.items)) return JSON.stringify(result);
|
|
2494
|
+
if (result.items.length === 0) return `No ${result.scope || ''} memories found.`;
|
|
2495
|
+
return result.items.map((item) => `${item.id} [${item.kind}] ${item.content}`).join('\n');
|
|
2496
|
+
},
|
|
2497
|
+
|
|
2498
|
+
search_memory(result) {
|
|
2499
|
+
if (!result || typeof result !== 'object' || !Array.isArray(result.items)) return JSON.stringify(result);
|
|
2500
|
+
if (result.items.length === 0) return `No ${result.scope || ''} memories matched "${result.query || ''}".`;
|
|
2501
|
+
return result.items.map((item) => `${item.id} [${item.kind}] ${item.content}`).join('\n');
|
|
2502
|
+
},
|
|
2503
|
+
|
|
2504
|
+
forget_memory(result) {
|
|
2505
|
+
return `removed ${Number(result?.removed || 0)} memory item(s)`;
|
|
2506
|
+
},
|
|
2507
|
+
|
|
2404
2508
|
generate_diff(result) {
|
|
2405
2509
|
if (!result || typeof result !== 'object') return String(result);
|
|
2406
2510
|
const p = result.path || '';
|