@dot-ai/cli 0.5.2 → 0.7.0
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/dist/__tests__/cli.test.js +21 -219
- package/dist/__tests__/cli.test.js.map +1 -1
- package/dist/index.js +319 -117
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/cli.test.ts +21 -272
- package/src/index.ts +340 -133
- package/tsconfig.tsbuildinfo +1 -1
package/src/index.ts
CHANGED
|
@@ -1,17 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { argv, cwd, exit } from 'node:process';
|
|
3
|
-
import { mkdir, writeFile, access } from 'node:fs/promises';
|
|
4
|
-
import { join } from 'node:path';
|
|
3
|
+
import { mkdir, writeFile, access, stat } from 'node:fs/promises';
|
|
4
|
+
import { join, resolve } from 'node:path';
|
|
5
5
|
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
injectRoot,
|
|
9
|
-
registerDefaults,
|
|
10
|
-
clearProviders,
|
|
11
|
-
createProviders,
|
|
12
|
-
boot,
|
|
13
|
-
enrich,
|
|
14
|
-
formatContext,
|
|
6
|
+
DotAiRuntime,
|
|
7
|
+
clearBootCache,
|
|
15
8
|
} from '@dot-ai/core';
|
|
16
9
|
|
|
17
10
|
const args = argv.slice(2);
|
|
@@ -28,23 +21,282 @@ async function main(): Promise<void> {
|
|
|
28
21
|
case 'trace':
|
|
29
22
|
await cmdTrace(args.slice(1));
|
|
30
23
|
break;
|
|
24
|
+
case 'cache':
|
|
25
|
+
await cmdCache(args.slice(1));
|
|
26
|
+
break;
|
|
27
|
+
case 'tools':
|
|
28
|
+
await cmdTools(args.slice(1));
|
|
29
|
+
break;
|
|
30
|
+
case 'commands':
|
|
31
|
+
await cmdCommands();
|
|
32
|
+
break;
|
|
33
|
+
case 'migrate':
|
|
34
|
+
await cmdMigrate();
|
|
35
|
+
break;
|
|
36
|
+
case '--version':
|
|
37
|
+
case '-v':
|
|
38
|
+
console.log('dot-ai v0.6.0');
|
|
39
|
+
break;
|
|
40
|
+
default:
|
|
41
|
+
// Try to execute as a tool: dot-ai <domain> <action> [args...]
|
|
42
|
+
if (command && !command.startsWith('-')) {
|
|
43
|
+
await cmdExecTool(args);
|
|
44
|
+
} else {
|
|
45
|
+
printHelp();
|
|
46
|
+
exit(command ? 1 : 0);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function printHelp(): void {
|
|
52
|
+
console.log('dot-ai v0.6.0\n');
|
|
53
|
+
console.log('Commands:');
|
|
54
|
+
console.log(' init Create .ai/ directory with defaults');
|
|
55
|
+
console.log(' boot Run boot and show workspace info');
|
|
56
|
+
console.log(' trace "<prompt>" Dry-run enrich pipeline with token estimates');
|
|
57
|
+
console.log(' tools [--json] List registered tools from extensions');
|
|
58
|
+
console.log(' commands List registered commands from extensions');
|
|
59
|
+
console.log(' cache clear Clear boot cache');
|
|
60
|
+
console.log(' cache status Show cache status');
|
|
61
|
+
console.log(' migrate Migrate dot-ai.yml to settings.json');
|
|
62
|
+
console.log('');
|
|
63
|
+
console.log('Tool execution:');
|
|
64
|
+
console.log(' dot-ai <domain> <action> [args...]');
|
|
65
|
+
console.log(' dot-ai memory recall "query" Execute memory_recall tool');
|
|
66
|
+
console.log(' dot-ai tasks list Execute task_list tool');
|
|
67
|
+
console.log('');
|
|
68
|
+
console.log('Flags:');
|
|
69
|
+
console.log(' --json Output as JSON');
|
|
70
|
+
console.log(' --workspace <path> Override workspace root');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ── Workspace Detection ──
|
|
74
|
+
|
|
75
|
+
async function resolveWorkspace(): Promise<string> {
|
|
76
|
+
const wsIdx = args.indexOf('--workspace');
|
|
77
|
+
if (wsIdx !== -1 && args[wsIdx + 1]) {
|
|
78
|
+
return resolve(args[wsIdx + 1]);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
let dir = cwd();
|
|
82
|
+
const root = resolve('/');
|
|
83
|
+
|
|
84
|
+
while (dir !== root) {
|
|
85
|
+
try {
|
|
86
|
+
await access(join(dir, '.ai'));
|
|
87
|
+
return dir;
|
|
88
|
+
} catch {
|
|
89
|
+
dir = resolve(dir, '..');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return cwd();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// ── Boot Runtime ──
|
|
97
|
+
|
|
98
|
+
async function bootRuntime(workspaceRoot?: string): Promise<DotAiRuntime> {
|
|
99
|
+
const ws = workspaceRoot ?? await resolveWorkspace();
|
|
100
|
+
const runtime = new DotAiRuntime({ workspaceRoot: ws });
|
|
101
|
+
await runtime.boot();
|
|
102
|
+
return runtime;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// ── Tool Execution ──
|
|
106
|
+
|
|
107
|
+
async function cmdExecTool(rawArgs: string[]): Promise<void> {
|
|
108
|
+
const jsonMode = rawArgs.includes('--json');
|
|
109
|
+
const cleanArgs = rawArgs.filter(a => a !== '--json' && a !== '--workspace').filter((_, i, arr) => {
|
|
110
|
+
if (i > 0 && arr[i - 1] === '--workspace') return false;
|
|
111
|
+
return true;
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const domain = cleanArgs[0];
|
|
115
|
+
const action = cleanArgs[1];
|
|
116
|
+
|
|
117
|
+
if (!domain || !action) {
|
|
118
|
+
console.error(`Unknown command: ${domain ?? ''}`);
|
|
119
|
+
console.error('Run "dot-ai" for help.');
|
|
120
|
+
exit(1);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const toolName = `${domain}_${action}`;
|
|
124
|
+
const toolArgs = cleanArgs.slice(2);
|
|
125
|
+
|
|
126
|
+
const runtime = await bootRuntime();
|
|
127
|
+
const tools = runtime.capabilities;
|
|
128
|
+
|
|
129
|
+
const tool = tools.find(t => t.name === toolName);
|
|
130
|
+
if (!tool) {
|
|
131
|
+
console.error(`Unknown tool: ${toolName}`);
|
|
132
|
+
console.error('Available tools:');
|
|
133
|
+
for (const t of tools) {
|
|
134
|
+
console.error(` ${t.name} — ${t.description}`);
|
|
135
|
+
}
|
|
136
|
+
exit(1);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const input = parseToolArgs(toolArgs, tool.parameters);
|
|
140
|
+
|
|
141
|
+
try {
|
|
142
|
+
const result = await tool.execute(input);
|
|
143
|
+
if (jsonMode) {
|
|
144
|
+
console.log(JSON.stringify({ content: result.text, details: result.details }, null, 2));
|
|
145
|
+
} else {
|
|
146
|
+
console.log(result.text);
|
|
147
|
+
}
|
|
148
|
+
} catch (err) {
|
|
149
|
+
console.error(`Tool execution error: ${err instanceof Error ? err.message : err}`);
|
|
150
|
+
exit(1);
|
|
151
|
+
} finally {
|
|
152
|
+
await runtime.flush();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function parseToolArgs(rawArgs: string[], schema: Record<string, unknown>): Record<string, unknown> {
|
|
157
|
+
const input: Record<string, unknown> = {};
|
|
158
|
+
const props = (schema as { properties?: Record<string, { type?: string }> }).properties ?? {};
|
|
159
|
+
const required = (schema as { required?: string[] }).required ?? [];
|
|
160
|
+
const propNames = Object.keys(props);
|
|
161
|
+
|
|
162
|
+
let positionalIdx = 0;
|
|
163
|
+
let i = 0;
|
|
164
|
+
|
|
165
|
+
while (i < rawArgs.length) {
|
|
166
|
+
const arg = rawArgs[i];
|
|
167
|
+
|
|
168
|
+
if (arg.startsWith('--')) {
|
|
169
|
+
const eqIdx = arg.indexOf('=');
|
|
170
|
+
if (eqIdx !== -1) {
|
|
171
|
+
const key = arg.slice(2, eqIdx);
|
|
172
|
+
const value = arg.slice(eqIdx + 1);
|
|
173
|
+
input[key] = coerceValue(value, props[key]?.type);
|
|
174
|
+
} else {
|
|
175
|
+
const key = arg.slice(2);
|
|
176
|
+
const nextArg = rawArgs[i + 1];
|
|
177
|
+
if (nextArg && !nextArg.startsWith('--')) {
|
|
178
|
+
input[key] = coerceValue(nextArg, props[key]?.type);
|
|
179
|
+
i++;
|
|
180
|
+
} else {
|
|
181
|
+
input[key] = true;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
} else {
|
|
185
|
+
const targetKey = required[positionalIdx] ?? propNames.find(p => !(p in input));
|
|
186
|
+
if (targetKey) {
|
|
187
|
+
input[targetKey] = coerceValue(arg, props[targetKey]?.type);
|
|
188
|
+
}
|
|
189
|
+
positionalIdx++;
|
|
190
|
+
}
|
|
191
|
+
i++;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return input;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function coerceValue(value: string, type?: string): unknown {
|
|
198
|
+
if (type === 'number') return Number(value);
|
|
199
|
+
if (type === 'boolean') return value === 'true';
|
|
200
|
+
if (type === 'array') {
|
|
201
|
+
try { return JSON.parse(value); } catch { return value.split(','); }
|
|
202
|
+
}
|
|
203
|
+
return value;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// ── Tools List ──
|
|
207
|
+
|
|
208
|
+
async function cmdTools(rawArgs: string[]): Promise<void> {
|
|
209
|
+
const jsonMode = rawArgs.includes('--json');
|
|
210
|
+
const runtime = await bootRuntime();
|
|
211
|
+
const tools = runtime.capabilities;
|
|
212
|
+
|
|
213
|
+
if (jsonMode) {
|
|
214
|
+
const output = tools.map(t => ({
|
|
215
|
+
name: t.name,
|
|
216
|
+
description: t.description,
|
|
217
|
+
category: t.category,
|
|
218
|
+
readOnly: t.readOnly,
|
|
219
|
+
}));
|
|
220
|
+
console.log(JSON.stringify(output, null, 2));
|
|
221
|
+
} else {
|
|
222
|
+
if (tools.length === 0) {
|
|
223
|
+
console.log('No tools registered.');
|
|
224
|
+
} else {
|
|
225
|
+
console.log(`${tools.length} tool(s) registered:\n`);
|
|
226
|
+
for (const t of tools) {
|
|
227
|
+
const cat = t.category ? ` [${t.category}]` : '';
|
|
228
|
+
const ro = t.readOnly ? ' (read-only)' : '';
|
|
229
|
+
console.log(` ${t.name}${cat}${ro}`);
|
|
230
|
+
console.log(` ${t.description}`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
await runtime.flush();
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// ── Commands List ──
|
|
239
|
+
|
|
240
|
+
async function cmdCommands(): Promise<void> {
|
|
241
|
+
const runtime = await bootRuntime();
|
|
242
|
+
const runner = runtime.runner;
|
|
243
|
+
const commands = runner?.commands ?? [];
|
|
244
|
+
|
|
245
|
+
if (commands.length === 0) {
|
|
246
|
+
console.log('No commands registered.');
|
|
247
|
+
} else {
|
|
248
|
+
console.log(`${commands.length} command(s) registered:\n`);
|
|
249
|
+
for (const cmd of commands) {
|
|
250
|
+
const params = cmd.parameters?.map((p: { name: string; required?: boolean }) =>
|
|
251
|
+
p.required ? `<${p.name}>` : `[${p.name}]`
|
|
252
|
+
).join(' ') ?? '';
|
|
253
|
+
console.log(` /${cmd.name} ${params}`);
|
|
254
|
+
console.log(` ${cmd.description}`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
await runtime.flush();
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// ── Cache Management ──
|
|
262
|
+
|
|
263
|
+
async function cmdCache(rawArgs: string[]): Promise<void> {
|
|
264
|
+
const subcommand = rawArgs[0];
|
|
265
|
+
const ws = await resolveWorkspace();
|
|
266
|
+
const cacheDir = join(ws, '.ai', '.cache');
|
|
267
|
+
|
|
268
|
+
switch (subcommand) {
|
|
269
|
+
case 'clear': {
|
|
270
|
+
await clearBootCache(ws);
|
|
271
|
+
console.log('Cache cleared.');
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
case 'status': {
|
|
275
|
+
try {
|
|
276
|
+
const bootJson = join(cacheDir, 'boot.json');
|
|
277
|
+
const s = await stat(bootJson);
|
|
278
|
+
console.log(`Cache: ${cacheDir}`);
|
|
279
|
+
console.log(` boot.json: ${s.size} bytes, modified ${s.mtime.toISOString()}`);
|
|
280
|
+
} catch {
|
|
281
|
+
console.log('No cache found.');
|
|
282
|
+
}
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
31
285
|
default:
|
|
32
|
-
console.log('dot-ai
|
|
33
|
-
|
|
34
|
-
console.log(' init Create .ai/ directory with defaults');
|
|
35
|
-
console.log(' boot Run boot and show workspace info');
|
|
36
|
-
console.log(' trace "<prompt>" Dry-run enrich pipeline with token estimates');
|
|
37
|
-
exit(command ? 1 : 0);
|
|
286
|
+
console.log('Usage: dot-ai cache <clear|status>');
|
|
287
|
+
exit(1);
|
|
38
288
|
}
|
|
39
289
|
}
|
|
40
290
|
|
|
291
|
+
// ── Init ──
|
|
292
|
+
|
|
41
293
|
async function cmdInit(): Promise<void> {
|
|
42
294
|
const root = cwd();
|
|
43
295
|
const aiDir = join(root, '.ai');
|
|
44
296
|
|
|
45
297
|
try {
|
|
46
|
-
await access(join(aiDir, '
|
|
47
|
-
console.log('.ai/
|
|
298
|
+
await access(join(aiDir, 'settings.json'));
|
|
299
|
+
console.log('.ai/settings.json already exists. Nothing to do.');
|
|
48
300
|
return;
|
|
49
301
|
} catch {
|
|
50
302
|
// Doesn't exist, create it
|
|
@@ -52,21 +304,10 @@ async function cmdInit(): Promise<void> {
|
|
|
52
304
|
|
|
53
305
|
await mkdir(aiDir, { recursive: true });
|
|
54
306
|
|
|
55
|
-
await writeFile(join(aiDir, '
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
'#',
|
|
60
|
-
'# memory:',
|
|
61
|
-
'# use: "@dot-ai/provider-file-memory"',
|
|
62
|
-
'#',
|
|
63
|
-
'# skills:',
|
|
64
|
-
'# use: "@dot-ai/provider-file-skills"',
|
|
65
|
-
'#',
|
|
66
|
-
'# routing:',
|
|
67
|
-
'# use: "@dot-ai/provider-rules-routing"',
|
|
68
|
-
'',
|
|
69
|
-
].join('\n'));
|
|
307
|
+
await writeFile(join(aiDir, 'settings.json'), JSON.stringify({
|
|
308
|
+
extensions: [],
|
|
309
|
+
packages: [],
|
|
310
|
+
}, null, 2) + '\n');
|
|
70
311
|
|
|
71
312
|
await writeFile(join(aiDir, 'AGENTS.md'), [
|
|
72
313
|
'# AGENTS.md',
|
|
@@ -80,32 +321,34 @@ async function cmdInit(): Promise<void> {
|
|
|
80
321
|
].join('\n'));
|
|
81
322
|
|
|
82
323
|
console.log('Created:');
|
|
83
|
-
console.log(' .ai/
|
|
84
|
-
console.log(' .ai/AGENTS.md
|
|
85
|
-
console.log('\nNext: add SOUL.md, USER.md, skills/,
|
|
324
|
+
console.log(' .ai/settings.json (config)');
|
|
325
|
+
console.log(' .ai/AGENTS.md (template)');
|
|
326
|
+
console.log('\nNext: add SOUL.md, USER.md, skills/, extensions/ as needed.');
|
|
86
327
|
}
|
|
87
328
|
|
|
329
|
+
// ── Boot ──
|
|
330
|
+
|
|
88
331
|
async function cmdBoot(): Promise<void> {
|
|
89
|
-
const root =
|
|
332
|
+
const root = await resolveWorkspace();
|
|
90
333
|
const start = performance.now();
|
|
91
334
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const rawConfig = await loadConfig(root);
|
|
96
|
-
const config = injectRoot(rawConfig, root);
|
|
97
|
-
const providers = await createProviders(config);
|
|
98
|
-
const cache = await boot(providers);
|
|
99
|
-
|
|
335
|
+
const runtime = new DotAiRuntime({ workspaceRoot: root });
|
|
336
|
+
await runtime.boot();
|
|
100
337
|
const duration = Math.round(performance.now() - start);
|
|
338
|
+
const diag = runtime.diagnostics;
|
|
101
339
|
|
|
102
340
|
console.log(`dot-ai boot — ${root}\n`);
|
|
103
|
-
console.log(`
|
|
104
|
-
console.log(`
|
|
105
|
-
console.log(`
|
|
341
|
+
console.log(`Extensions: ${diag.extensions.length}`);
|
|
342
|
+
console.log(`Vocabulary: ${diag.vocabularySize} labels`);
|
|
343
|
+
console.log(`Tools: ${diag.capabilityCount}`);
|
|
344
|
+
console.log(`Tiers: ${diag.usedTiers.join(', ') || 'none'}`);
|
|
106
345
|
console.log(`\nBoot complete in ${duration}ms`);
|
|
346
|
+
|
|
347
|
+
await runtime.flush();
|
|
107
348
|
}
|
|
108
349
|
|
|
350
|
+
// ── Trace ──
|
|
351
|
+
|
|
109
352
|
async function cmdTrace(rawArgs: string[]): Promise<void> {
|
|
110
353
|
const flags = new Set(rawArgs.filter(a => a.startsWith('--')));
|
|
111
354
|
const prompt = rawArgs.filter(a => !a.startsWith('--')).join(' ');
|
|
@@ -117,109 +360,73 @@ async function cmdTrace(rawArgs: string[]): Promise<void> {
|
|
|
117
360
|
exit(1);
|
|
118
361
|
}
|
|
119
362
|
|
|
120
|
-
const root =
|
|
363
|
+
const root = await resolveWorkspace();
|
|
121
364
|
const start = performance.now();
|
|
122
365
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
const rawConfig = await loadConfig(root);
|
|
127
|
-
const config = injectRoot(rawConfig, root);
|
|
128
|
-
const resolved = resolveConfig(rawConfig);
|
|
129
|
-
const providers = await createProviders(config);
|
|
130
|
-
const cache = await boot(providers);
|
|
131
|
-
const ctx = await enrich(prompt, providers, cache);
|
|
132
|
-
|
|
133
|
-
// Load skill content for matched skills
|
|
134
|
-
for (const skill of ctx.skills) {
|
|
135
|
-
if (!skill.content && skill.name) {
|
|
136
|
-
skill.content = await providers.skills.load(skill.name) ?? undefined;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
366
|
+
const runtime = new DotAiRuntime({ workspaceRoot: root });
|
|
367
|
+
await runtime.boot();
|
|
368
|
+
const result = await runtime.processPrompt(prompt);
|
|
140
369
|
const duration = Math.round(performance.now() - start);
|
|
141
370
|
|
|
142
|
-
// Compute token estimates
|
|
143
|
-
const identityChars = cache.identities.reduce((sum, i) => sum + (i.content?.length ?? 0), 0);
|
|
144
|
-
const skillChars = ctx.skills.reduce((sum, s) => sum + (s.content?.length ?? 0), 0);
|
|
145
|
-
const memoryChars = ctx.memories.reduce((sum, m) => sum + m.content.length, 0);
|
|
146
|
-
const totalChars = skillChars + memoryChars;
|
|
147
|
-
|
|
148
|
-
// Check for disabled skills
|
|
149
|
-
const disabledList = typeof resolved.skills?.with?.disabled === 'string'
|
|
150
|
-
? resolved.skills.with.disabled.split(',').map((s: string) => s.trim()).filter(Boolean)
|
|
151
|
-
: [];
|
|
152
|
-
|
|
153
371
|
if (jsonMode) {
|
|
154
372
|
const output = {
|
|
155
373
|
prompt,
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
memoryChars,
|
|
169
|
-
toolCount: ctx.tools.length,
|
|
170
|
-
routing: ctx.routing,
|
|
171
|
-
totalChars,
|
|
172
|
-
estimatedTokens: Math.round(totalChars / 4),
|
|
173
|
-
},
|
|
174
|
-
disabled: disabledList,
|
|
175
|
-
vocabularySize: cache.vocabulary.length,
|
|
374
|
+
labels: result.labels?.map(l => l.name),
|
|
375
|
+
routing: result.routing,
|
|
376
|
+
sections: result.sections?.map(s => ({
|
|
377
|
+
id: s.id,
|
|
378
|
+
title: s.title,
|
|
379
|
+
priority: s.priority,
|
|
380
|
+
source: s.source,
|
|
381
|
+
chars: s.content.length,
|
|
382
|
+
})),
|
|
383
|
+
totalChars: result.formatted.length,
|
|
384
|
+
estimatedTokens: Math.round(result.formatted.length / 4),
|
|
385
|
+
toolCount: result.capabilities.length,
|
|
176
386
|
durationMs: duration,
|
|
177
387
|
};
|
|
178
388
|
console.log(JSON.stringify(output, null, 2));
|
|
179
|
-
|
|
180
|
-
|
|
389
|
+
} else {
|
|
390
|
+
console.log(`dot-ai trace — "${prompt}"\n`);
|
|
181
391
|
|
|
182
|
-
|
|
183
|
-
|
|
392
|
+
const labels = result.labels ?? result.enriched.labels;
|
|
393
|
+
console.log(`Labels: [${labels.map(l => l.name).join(', ')}]`);
|
|
184
394
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
395
|
+
if (result.sections && result.sections.length > 0) {
|
|
396
|
+
console.log(`\nSections (${result.sections.length}):`);
|
|
397
|
+
for (const s of result.sections) {
|
|
398
|
+
console.log(` [${s.priority}] ${s.title} (${s.source}, ${s.content.length} chars)`);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
188
401
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
402
|
+
const routing = result.routing ?? result.enriched.routing;
|
|
403
|
+
console.log(`\nRouting: ${routing?.model ?? 'default'} (${routing?.reason ?? 'none'})`);
|
|
404
|
+
console.log(`Total: ${result.formatted.length.toLocaleString()} chars (~${Math.round(result.formatted.length / 4).toLocaleString()} tokens)`);
|
|
405
|
+
console.log(`Tools: ${result.capabilities.length}`);
|
|
192
406
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
407
|
+
if (verbose) {
|
|
408
|
+
console.log(`\n── Injected markdown (${result.formatted.length.toLocaleString()} chars) ──`);
|
|
409
|
+
console.log(result.formatted);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
console.log(`\nTrace complete in ${duration}ms`);
|
|
198
413
|
}
|
|
199
414
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
console.log(` Routing: ${ctx.routing.model} (${ctx.routing.reason})`);
|
|
203
|
-
console.log(` Total: ${totalChars.toLocaleString()} chars (~${Math.round(totalChars / 4).toLocaleString()} tokens)`);
|
|
415
|
+
await runtime.flush();
|
|
416
|
+
}
|
|
204
417
|
|
|
205
|
-
|
|
206
|
-
if (disabledList.length > 0) {
|
|
207
|
-
console.log(`\n── Disabled skills ──`);
|
|
208
|
-
console.log(` ${disabledList.join(', ')} (via config)`);
|
|
209
|
-
}
|
|
418
|
+
// ── Migrate ──
|
|
210
419
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
console.log(
|
|
420
|
+
async function cmdMigrate(): Promise<void> {
|
|
421
|
+
const ws = await resolveWorkspace();
|
|
422
|
+
const { migrateConfig } = await import('@dot-ai/core');
|
|
423
|
+
const result = await migrateConfig(ws);
|
|
424
|
+
if (result) {
|
|
425
|
+
console.log(`Migrated config to ${result}`);
|
|
426
|
+
console.log('You can now delete .ai/dot-ai.yml');
|
|
427
|
+
} else {
|
|
428
|
+
console.log('No dot-ai.yml found to migrate.');
|
|
220
429
|
}
|
|
221
|
-
|
|
222
|
-
console.log(`\nTrace complete in ${duration}ms`);
|
|
223
430
|
}
|
|
224
431
|
|
|
225
432
|
main().catch((err) => {
|