jinzd-ai-cli 0.4.75 → 0.4.76

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.
@@ -0,0 +1,430 @@
1
+ import {
2
+ detectLanguage,
3
+ emptyIndex,
4
+ loadIndex,
5
+ removeFile,
6
+ saveIndex,
7
+ upsertFileSymbols
8
+ } from "./chunk-BJAT4GNC.js";
9
+
10
+ // src/symbols/indexer.ts
11
+ import fs2 from "fs";
12
+ import path3 from "path";
13
+
14
+ // src/symbols/parser.ts
15
+ import path2 from "path";
16
+
17
+ // src/symbols/loader.ts
18
+ import { Parser, Language } from "web-tree-sitter";
19
+ import { createRequire } from "module";
20
+ import path from "path";
21
+ import fs from "fs";
22
+ import { fileURLToPath } from "url";
23
+ var _metaUrl = import.meta?.url;
24
+ var _cjsFilename = globalThis.__filename;
25
+ var __filename_ = _metaUrl ? fileURLToPath(_metaUrl) : _cjsFilename ?? process.execPath;
26
+ var __dirname_ = path.dirname(__filename_);
27
+ var require_ = _metaUrl ? createRequire(_metaUrl) : createRequire(__filename_);
28
+ var GRAMMAR_FILE = {
29
+ typescript: "tree-sitter-typescript.wasm",
30
+ tsx: "tree-sitter-tsx.wasm",
31
+ javascript: "tree-sitter-javascript.wasm",
32
+ python: "tree-sitter-python.wasm"
33
+ };
34
+ var RUNTIME_WASM = "web-tree-sitter.wasm";
35
+ var parserInitPromise = null;
36
+ var languageCache = /* @__PURE__ */ new Map();
37
+ var parserCache = /* @__PURE__ */ new Map();
38
+ function resolveWasmPath(filename) {
39
+ const candidates = [];
40
+ candidates.push(path.join(__dirname_, "wasm", filename));
41
+ candidates.push(path.join(__dirname_, "..", "wasm", filename));
42
+ candidates.push(path.join(__dirname_, "..", "dist", "wasm", filename));
43
+ if (process.pkg) {
44
+ candidates.push(path.join(path.dirname(process.execPath), "dist", "wasm", filename));
45
+ candidates.push(path.join("/snapshot", "ai-cli", "dist", "wasm", filename));
46
+ candidates.push(path.join("/snapshot", "jinzd-ai-cli", "dist", "wasm", filename));
47
+ }
48
+ const resourcesPath = process.resourcesPath;
49
+ if (resourcesPath) {
50
+ candidates.push(path.join(resourcesPath, "app.asar.unpacked", "dist", "wasm", filename));
51
+ candidates.push(path.join(resourcesPath, "app", "dist", "wasm", filename));
52
+ }
53
+ try {
54
+ if (filename === RUNTIME_WASM) {
55
+ const pkgPath = require_.resolve("web-tree-sitter/package.json");
56
+ candidates.push(path.join(path.dirname(pkgPath), filename));
57
+ } else {
58
+ const grammarPkg = filename.replace(/\.wasm$/, "").replace(/^tree-sitter-tsx$/, "tree-sitter-typescript");
59
+ const pkgPath = require_.resolve(`${grammarPkg}/package.json`);
60
+ candidates.push(path.join(path.dirname(pkgPath), filename));
61
+ }
62
+ } catch {
63
+ }
64
+ candidates.push(path.join(process.cwd(), "dist", "wasm", filename));
65
+ candidates.push(path.join(process.cwd(), "node_modules", "web-tree-sitter", filename));
66
+ for (const p of candidates) {
67
+ try {
68
+ if (fs.existsSync(p)) return p;
69
+ } catch {
70
+ }
71
+ }
72
+ throw new Error(
73
+ `[symbols/loader] Cannot locate ${filename}. Searched:
74
+ ${candidates.join("\n ")}`
75
+ );
76
+ }
77
+ async function initRuntime() {
78
+ if (parserInitPromise) return parserInitPromise;
79
+ parserInitPromise = Parser.init({
80
+ locateFile: (name) => resolveWasmPath(name)
81
+ });
82
+ return parserInitPromise;
83
+ }
84
+ async function loadParser(language) {
85
+ const cached = parserCache.get(language);
86
+ if (cached) return cached;
87
+ await initRuntime();
88
+ let lang = languageCache.get(language);
89
+ if (!lang) {
90
+ const wasmPath = resolveWasmPath(GRAMMAR_FILE[language]);
91
+ lang = await Language.load(wasmPath);
92
+ languageCache.set(language, lang);
93
+ }
94
+ const parser = new Parser();
95
+ parser.setLanguage(lang);
96
+ parserCache.set(language, parser);
97
+ return parser;
98
+ }
99
+
100
+ // src/symbols/parser.ts
101
+ function locationOf(file, node) {
102
+ return {
103
+ file: path2.resolve(file),
104
+ line: node.startPosition.row + 1,
105
+ column: node.startPosition.column,
106
+ endLine: node.endPosition.row + 1,
107
+ endColumn: node.endPosition.column
108
+ };
109
+ }
110
+ function firstLine(text, max = 200) {
111
+ const line = text.split(/\r?\n/)[0] ?? "";
112
+ return line.length > max ? line.slice(0, max) + "\u2026" : line;
113
+ }
114
+ function childByFieldName(node, field) {
115
+ return node.childForFieldName(field) ?? null;
116
+ }
117
+ function nameOf(node) {
118
+ const n = childByFieldName(node, "name") ?? node.children.find((c) => c?.type === "identifier" || c?.type === "property_identifier" || c?.type === "type_identifier");
119
+ return n?.text ?? null;
120
+ }
121
+ function extractTsJs(root, file, language) {
122
+ const out = [];
123
+ const visit = (node, container, exported) => {
124
+ let childrenContainer = container;
125
+ const kindMap = {
126
+ function_declaration: "function",
127
+ generator_function_declaration: "function",
128
+ class_declaration: "class",
129
+ abstract_class_declaration: "class",
130
+ interface_declaration: "interface",
131
+ type_alias_declaration: "type",
132
+ enum_declaration: "enum",
133
+ method_definition: "method",
134
+ method_signature: "method",
135
+ public_field_definition: "property"
136
+ };
137
+ const kind = kindMap[node.type];
138
+ if (kind) {
139
+ const name = nameOf(node);
140
+ if (name) {
141
+ out.push({
142
+ name,
143
+ kind,
144
+ language,
145
+ location: locationOf(file, node),
146
+ signature: firstLine(node.text),
147
+ container,
148
+ exported
149
+ });
150
+ if (kind === "class" || kind === "interface" || kind === "enum") {
151
+ childrenContainer = name;
152
+ }
153
+ }
154
+ } else if (node.type === "lexical_declaration" || node.type === "variable_declaration") {
155
+ for (const decl of node.children) {
156
+ if (decl?.type !== "variable_declarator") continue;
157
+ const nameNode = childByFieldName(decl, "name");
158
+ if (!nameNode || nameNode.type !== "identifier") continue;
159
+ out.push({
160
+ name: nameNode.text,
161
+ kind: "variable",
162
+ language,
163
+ location: locationOf(file, decl),
164
+ signature: firstLine(decl.text),
165
+ container,
166
+ exported
167
+ });
168
+ }
169
+ } else if (node.type === "export_statement") {
170
+ for (const c of node.children) {
171
+ if (c) visit(c, container, true);
172
+ }
173
+ return;
174
+ }
175
+ const descendInto = /* @__PURE__ */ new Set([
176
+ "program",
177
+ "module",
178
+ "class_body",
179
+ "class_declaration",
180
+ "abstract_class_declaration",
181
+ "interface_body",
182
+ "interface_declaration",
183
+ "enum_body",
184
+ "enum_declaration",
185
+ "export_statement",
186
+ "statement_block",
187
+ // for nested class_declaration inside namespace etc.
188
+ "internal_module",
189
+ "namespace_declaration"
190
+ ]);
191
+ if (node === root || descendInto.has(node.type)) {
192
+ for (const c of node.children) {
193
+ if (c) visit(c, childrenContainer, exported);
194
+ }
195
+ }
196
+ };
197
+ visit(root, void 0, false);
198
+ return out;
199
+ }
200
+ function extractPython(root, file) {
201
+ const out = [];
202
+ const visit = (node, container, isModuleLevel) => {
203
+ if (node.type === "decorated_definition") {
204
+ const def = node.children.find(
205
+ (c) => c?.type === "class_definition" || c?.type === "function_definition"
206
+ );
207
+ if (def) visit(def, container, isModuleLevel);
208
+ return;
209
+ }
210
+ if (node.type === "class_definition") {
211
+ const name = nameOf(node);
212
+ if (name) {
213
+ out.push({
214
+ name,
215
+ kind: "class",
216
+ language: "python",
217
+ location: locationOf(file, node),
218
+ signature: firstLine(node.text),
219
+ container,
220
+ exported: isModuleLevel
221
+ });
222
+ const body = childByFieldName(node, "body");
223
+ if (body) {
224
+ for (const c of body.children) {
225
+ if (c) visit(c, name, false);
226
+ }
227
+ }
228
+ }
229
+ return;
230
+ }
231
+ if (node.type === "function_definition") {
232
+ const name = nameOf(node);
233
+ if (name) {
234
+ out.push({
235
+ name,
236
+ kind: container ? "method" : "function",
237
+ language: "python",
238
+ location: locationOf(file, node),
239
+ signature: firstLine(node.text),
240
+ container,
241
+ exported: isModuleLevel && !name.startsWith("_")
242
+ });
243
+ }
244
+ return;
245
+ }
246
+ if (isModuleLevel && node.type === "expression_statement") {
247
+ const assign = node.children.find((c) => c?.type === "assignment");
248
+ if (assign) {
249
+ const left = childByFieldName(assign, "left");
250
+ if (left && left.type === "identifier") {
251
+ out.push({
252
+ name: left.text,
253
+ kind: "variable",
254
+ language: "python",
255
+ location: locationOf(file, assign),
256
+ signature: firstLine(assign.text),
257
+ container,
258
+ exported: !left.text.startsWith("_")
259
+ });
260
+ }
261
+ }
262
+ return;
263
+ }
264
+ if (node === root || node.type === "module") {
265
+ for (const c of node.children) {
266
+ if (c) visit(c, container, true);
267
+ }
268
+ }
269
+ };
270
+ visit(root, void 0, true);
271
+ return out;
272
+ }
273
+ async function parseSource(file, source, language) {
274
+ const lang = language ?? detectLanguage(path2.extname(file).slice(1));
275
+ if (!lang) return [];
276
+ try {
277
+ const parser = await loadParser(lang);
278
+ const tree = parser.parse(source);
279
+ if (!tree) return [];
280
+ const root = tree.rootNode;
281
+ if (lang === "python") return extractPython(root, file);
282
+ return extractTsJs(root, file, lang);
283
+ } catch (err) {
284
+ return [];
285
+ }
286
+ }
287
+
288
+ // src/symbols/indexer.ts
289
+ var SKIP_DIRS = /* @__PURE__ */ new Set([
290
+ "node_modules",
291
+ ".git",
292
+ "dist",
293
+ "dist-cjs",
294
+ "build",
295
+ "out",
296
+ "coverage",
297
+ ".next",
298
+ ".nuxt",
299
+ ".turbo",
300
+ ".cache",
301
+ "__pycache__",
302
+ ".venv",
303
+ "venv",
304
+ ".idea",
305
+ ".vscode",
306
+ "release"
307
+ ]);
308
+ var MAX_FILE_BYTES = 2 * 1024 * 1024;
309
+ function collectFiles(root, maxFiles) {
310
+ const out = [];
311
+ const stack = [root];
312
+ while (stack.length > 0 && out.length < maxFiles) {
313
+ const dir = stack.pop();
314
+ let entries;
315
+ try {
316
+ entries = fs2.readdirSync(dir, { withFileTypes: true });
317
+ } catch {
318
+ continue;
319
+ }
320
+ for (const e of entries) {
321
+ const full = path3.join(dir, e.name);
322
+ if (e.isDirectory()) {
323
+ if (SKIP_DIRS.has(e.name)) continue;
324
+ if (e.name.startsWith(".") && e.name !== ".") {
325
+ continue;
326
+ }
327
+ stack.push(full);
328
+ } else if (e.isFile()) {
329
+ const ext = path3.extname(e.name).slice(1);
330
+ if (detectLanguage(ext)) {
331
+ out.push(full);
332
+ if (out.length >= maxFiles) break;
333
+ }
334
+ }
335
+ }
336
+ }
337
+ return out;
338
+ }
339
+ async function indexProject(root, opts = {}) {
340
+ const start = Date.now();
341
+ const maxFiles = opts.maxFiles ?? 5e3;
342
+ const force = opts.force === true;
343
+ const absRoot = path3.resolve(root);
344
+ let index = force ? emptyIndex(absRoot) : loadIndex(absRoot) ?? emptyIndex(absRoot);
345
+ const files = collectFiles(absRoot, maxFiles);
346
+ const liveSet = new Set(files.map((f) => path3.resolve(f)));
347
+ for (const known of Object.keys(index.files)) {
348
+ if (!liveSet.has(known)) {
349
+ index = removeFile(index, known);
350
+ }
351
+ }
352
+ let parsed = 0;
353
+ let skipped = 0;
354
+ for (let i = 0; i < files.length; i++) {
355
+ const file = path3.resolve(files[i]);
356
+ let stat;
357
+ try {
358
+ stat = fs2.statSync(file);
359
+ } catch {
360
+ skipped++;
361
+ continue;
362
+ }
363
+ if (stat.size > MAX_FILE_BYTES) {
364
+ skipped++;
365
+ continue;
366
+ }
367
+ const prevMtime = index.files[file];
368
+ if (!force && prevMtime !== void 0 && prevMtime === stat.mtimeMs) {
369
+ continue;
370
+ }
371
+ let src;
372
+ try {
373
+ src = fs2.readFileSync(file, "utf-8");
374
+ } catch {
375
+ skipped++;
376
+ continue;
377
+ }
378
+ const symbols = await parseSource(file, src);
379
+ index = upsertFileSymbols(index, file, stat.mtimeMs, symbols);
380
+ parsed++;
381
+ if (opts.onProgress && parsed % 50 === 0) {
382
+ opts.onProgress(i + 1, files.length);
383
+ }
384
+ }
385
+ saveIndex(index);
386
+ return {
387
+ index,
388
+ stats: {
389
+ filesScanned: files.length,
390
+ filesParsed: parsed,
391
+ filesSkipped: skipped,
392
+ symbols: index.symbolCount,
393
+ durationMs: Date.now() - start
394
+ }
395
+ };
396
+ }
397
+ async function updateFile(root, file) {
398
+ const absRoot = path3.resolve(root);
399
+ const absFile = path3.resolve(file);
400
+ let index = loadIndex(absRoot);
401
+ if (!index) return;
402
+ if (!fs2.existsSync(absFile)) {
403
+ index = removeFile(index, absFile);
404
+ saveIndex(index);
405
+ return;
406
+ }
407
+ const ext = path3.extname(absFile).slice(1);
408
+ if (!detectLanguage(ext)) return;
409
+ let stat;
410
+ try {
411
+ stat = fs2.statSync(absFile);
412
+ } catch {
413
+ return;
414
+ }
415
+ if (stat.size > MAX_FILE_BYTES) return;
416
+ let src;
417
+ try {
418
+ src = fs2.readFileSync(absFile, "utf-8");
419
+ } catch {
420
+ return;
421
+ }
422
+ const symbols = await parseSource(absFile, src);
423
+ index = upsertFileSymbols(index, absFile, stat.mtimeMs, symbols);
424
+ saveIndex(index);
425
+ }
426
+
427
+ export {
428
+ indexProject,
429
+ updateFile
430
+ };
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  schemaToJsonSchema,
4
4
  truncateForPersist
5
- } from "./chunk-MPIUYP6Q.js";
5
+ } from "./chunk-KR4FTJWB.js";
6
6
  import {
7
7
  AuthError,
8
8
  ProviderError,
@@ -18,7 +18,7 @@ import {
18
18
  MCP_PROTOCOL_VERSION,
19
19
  MCP_TOOL_PREFIX,
20
20
  VERSION
21
- } from "./chunk-5P4QTZBI.js";
21
+ } from "./chunk-2Q77FT3F.js";
22
22
 
23
23
  // src/providers/claude.ts
24
24
  import Anthropic from "@anthropic-ai/sdk";
@@ -385,7 +385,7 @@ ${content}`);
385
385
  }
386
386
  }
387
387
  async function runTaskMode(config, providers, configManager, topic) {
388
- const { TaskOrchestrator } = await import("./task-orchestrator-277NWVSE.js");
388
+ const { TaskOrchestrator } = await import("./task-orchestrator-I5HPXTJY.js");
389
389
  const orchestrator = new TaskOrchestrator(config, providers, configManager);
390
390
  let interrupted = false;
391
391
  const onSigint = () => {
package/dist/index.js CHANGED
@@ -30,10 +30,7 @@ import {
30
30
  saveDevState,
31
31
  sessionHasMeaningfulContent,
32
32
  setupProxy
33
- } from "./chunk-C4MGON2N.js";
34
- import {
35
- ConfigManager
36
- } from "./chunk-ASNDBI5R.js";
33
+ } from "./chunk-XTH7S3AM.js";
37
34
  import {
38
35
  ToolExecutor,
39
36
  ToolRegistry,
@@ -49,11 +46,16 @@ import {
49
46
  spawnAgentContext,
50
47
  theme,
51
48
  undoStack
52
- } from "./chunk-MPIUYP6Q.js";
49
+ } from "./chunk-KR4FTJWB.js";
53
50
  import {
54
51
  fileCheckpoints
55
52
  } from "./chunk-4BKXL7SM.js";
56
- import "./chunk-3BHGEPIT.js";
53
+ import "./chunk-NHNWUBXB.js";
54
+ import "./chunk-6VRJGH25.js";
55
+ import "./chunk-K3JJX2Z5.js";
56
+ import {
57
+ ConfigManager
58
+ } from "./chunk-H4DQNZZ6.js";
57
59
  import "./chunk-2ZD3YTVM.js";
58
60
  import {
59
61
  AGENTIC_BEHAVIOR_GUIDELINE,
@@ -76,7 +78,7 @@ import {
76
78
  SKILLS_DIR_NAME,
77
79
  VERSION,
78
80
  buildUserIdentityPrompt
79
- } from "./chunk-5P4QTZBI.js";
81
+ } from "./chunk-2Q77FT3F.js";
80
82
 
81
83
  // src/index.ts
82
84
  import { program } from "commander";
@@ -214,7 +216,7 @@ var Renderer = class {
214
216
  console.log(theme.dim(" Gemini (Google) \xB7 Zhipu (GLM) \xB7 OpenRouter \xB7 Ollama (Local, no API key)"));
215
217
  console.log(HR);
216
218
  const mcpToolCount = mcpInfo?.tools ?? 0;
217
- const toolTotal = 24 + pluginCount + mcpToolCount;
219
+ const toolTotal = 27 + pluginCount + mcpToolCount;
218
220
  const extras = [];
219
221
  if (pluginCount > 0) extras.push(`${pluginCount} plugin(s)`);
220
222
  if (mcpToolCount > 0) extras.push(`${mcpToolCount} MCP`);
@@ -244,14 +246,17 @@ var Renderer = class {
244
246
  console.log(tool("git_log", "Show commit history (oneline/full, filter by file/author)"));
245
247
  console.log(tool("git_commit", "Create a git commit (stage files, message, stage_all)"));
246
248
  console.log(tool("notebook_edit", "Edit Jupyter notebook cells (add/edit/delete/move)"));
249
+ console.log(tool("find_symbol", "Locate symbol definitions via persistent tree-sitter index (TS/JS/TSX/Python)"));
250
+ console.log(tool("get_outline", "Enumerate all top-level declarations in one source file"));
251
+ console.log(tool("find_references", "Search indexed files for references to a symbol name"));
247
252
  console.log(HR);
248
- console.log(theme.dim(" REPL Commands (40):"));
253
+ console.log(theme.dim(" REPL Commands (42):"));
249
254
  console.log(theme.dim(" /help /about /provider /model /clear /compact /plan /session"));
250
255
  console.log(theme.dim(" /system /context /status /search /undo /export /copy /paste"));
251
256
  console.log(theme.dim(" /cost /init /skill /tools /plugins /mcp /config /checkpoint"));
252
257
  console.log(theme.dim(" /review /security-review /rewind /commands /test /scaffold"));
253
258
  console.log(theme.dim(" /add-dir /memory /profile /doctor /bug /think /diff /fork"));
254
- console.log(theme.dim(" /yolo /exit"));
259
+ console.log(theme.dim(" /branch /index /yolo /exit"));
255
260
  console.log(HR);
256
261
  console.log(theme.dim(" Key Features:"));
257
262
  console.log(feat("Agentic loop (up to 200 tool-call rounds, configurable via config/CLI, final answer streamed)"));
@@ -970,6 +975,8 @@ function createDefaultCommands() {
970
975
  " /bug [--copy] - Generate bug report template (--copy to clipboard)",
971
976
  " /diff [--stats] - Show all file modifications in this session",
972
977
  " /fork [checkpoint] - Fork session from checkpoint or current position",
978
+ " /branch [list|new|switch|delete|rename] - Manage conversation branches (fork tree)",
979
+ " /index [status|rebuild|clear] - Symbol index for find_symbol / get_outline / find_references",
973
980
  " /yolo [on|off] - Toggle session auto-approve (skip confirmations)",
974
981
  " /exit - Exit"
975
982
  ] : [];
@@ -2356,6 +2363,57 @@ ${hint}` : "")
2356
2363
  ctx.renderer.renderError(`Unknown subcommand: ${sub}. Use list/new/switch/delete/rename.`);
2357
2364
  }
2358
2365
  },
2366
+ // ── /index ────────────────────────────────────────────────────
2367
+ {
2368
+ name: "index",
2369
+ description: "Manage symbol index (status/rebuild/clear) \u2014 used by find_symbol / get_outline / find_references",
2370
+ usage: "/index [status | rebuild | clear]",
2371
+ async execute(args, ctx) {
2372
+ const sub = (args[0] ?? "status").toLowerCase();
2373
+ const root = process.cwd();
2374
+ const { loadIndex, clearIndex } = await import("./store-S24SPPDZ.js");
2375
+ const { indexProject } = await import("./indexer-C7QYYHSZ.js");
2376
+ if (sub === "status") {
2377
+ const idx = loadIndex(root);
2378
+ if (!idx) {
2379
+ console.log(theme.dim(` No index for ${root}.`));
2380
+ console.log(theme.dim(" Run `/index rebuild` to build one."));
2381
+ return;
2382
+ }
2383
+ console.log(theme.heading("\n Symbol index:\n"));
2384
+ console.log(` Root: ${idx.root}`);
2385
+ console.log(` Generated: ${idx.generated}`);
2386
+ console.log(` Files: ${idx.fileCount}`);
2387
+ console.log(` Symbols: ${idx.symbolCount}`);
2388
+ console.log();
2389
+ return;
2390
+ }
2391
+ if (sub === "rebuild") {
2392
+ console.log(theme.dim(` Indexing ${root}\u2026`));
2393
+ const start = Date.now();
2394
+ const { stats } = await indexProject(root, {
2395
+ force: true,
2396
+ onProgress: (done, total) => {
2397
+ process.stdout.write(theme.dim(`\r ${done}/${total} files\u2026`));
2398
+ }
2399
+ });
2400
+ process.stdout.write("\r\x1B[K");
2401
+ console.log(theme.success(
2402
+ ` \u2713 Indexed ${stats.filesParsed} files (${stats.symbols} symbols) in ${stats.durationMs}ms`
2403
+ ));
2404
+ if (stats.filesSkipped > 0) {
2405
+ console.log(theme.dim(` (${stats.filesSkipped} skipped: oversized or unreadable)`));
2406
+ }
2407
+ return;
2408
+ }
2409
+ if (sub === "clear") {
2410
+ clearIndex(root);
2411
+ console.log(theme.success(` \u2713 Cleared symbol index for ${root}`));
2412
+ return;
2413
+ }
2414
+ ctx.renderer.renderError(`Unknown subcommand: ${sub}. Use status/rebuild/clear.`);
2415
+ }
2416
+ },
2359
2417
  // ── /commands ─────────────────────────────────────────────────
2360
2418
  {
2361
2419
  name: "commands",
@@ -2392,7 +2450,7 @@ ${hint}` : "")
2392
2450
  usage: "/test [command|filter]",
2393
2451
  async execute(args, ctx) {
2394
2452
  try {
2395
- const { executeTests } = await import("./run-tests-V2JJADIU.js");
2453
+ const { executeTests } = await import("./run-tests-MKKCDUUV.js");
2396
2454
  const argStr = args.join(" ").trim();
2397
2455
  let testArgs = {};
2398
2456
  if (argStr) {
@@ -4601,6 +4659,27 @@ Session '${this.resumeSessionId}' not found.
4601
4659
  process.stdout.write(theme.dim(` \u{1F4CB} Custom commands: ${customCmdCount} loaded (use /commands to list)
4602
4660
  `));
4603
4661
  }
4662
+ void (async () => {
4663
+ try {
4664
+ const { indexProject } = await import("./indexer-C7QYYHSZ.js");
4665
+ const { loadIndex } = await import("./store-S24SPPDZ.js");
4666
+ const root = process.cwd();
4667
+ const existed = loadIndex(root);
4668
+ const { stats } = await indexProject(root);
4669
+ if (!existed) {
4670
+ process.stdout.write(
4671
+ theme.dim(` \u{1F50E} Symbol index built: ${stats.symbols} symbols across ${stats.filesParsed} files
4672
+ `)
4673
+ );
4674
+ } else if (stats.filesParsed > 0) {
4675
+ process.stdout.write(
4676
+ theme.dim(` \u{1F50E} Symbol index refreshed: ${stats.filesParsed} file(s) updated
4677
+ `)
4678
+ );
4679
+ }
4680
+ } catch {
4681
+ }
4682
+ })();
4604
4683
  const globalMcpServers = this.config.get("mcpServers") ?? {};
4605
4684
  const projectMcpResult = this.loadProjectMcpConfig();
4606
4685
  const projectMcpServers = projectMcpResult?.servers ?? {};
@@ -6264,7 +6343,7 @@ program.command("web").description("Start Web UI server with browser-based chat
6264
6343
  console.error("Error: Invalid port number. Must be between 1 and 65535.");
6265
6344
  process.exit(1);
6266
6345
  }
6267
- const { startWebServer } = await import("./server-2XO72FRP.js");
6346
+ const { startWebServer } = await import("./server-6MPBAH4K.js");
6268
6347
  await startWebServer({ port, host: options.host });
6269
6348
  });
6270
6349
  program.command("user [action] [username]").description("Manage Web UI users (list | create <name> | delete <name> | reset-password <name> | migrate <name>)").action(async (action, username) => {
@@ -6387,7 +6466,7 @@ program.command("sessions").description("List recent conversation sessions").act
6387
6466
  });
6388
6467
  program.command("batch <action> [arg] [arg2]").description("Anthropic Message Batches: submit | list | status <id> | results <id> [out] | cancel <id>").option("--dry-run", "Parse and validate input without submitting (submit only)").action(async (action, arg, arg2, options) => {
6389
6468
  try {
6390
- const batch = await import("./batch-2RTTAHBL.js");
6469
+ const batch = await import("./batch-5HJGW6NA.js");
6391
6470
  switch (action) {
6392
6471
  case "submit":
6393
6472
  if (!arg) {
@@ -6547,7 +6626,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
6547
6626
  }),
6548
6627
  config.get("customProviders")
6549
6628
  );
6550
- const { startHub } = await import("./hub-W3BF22UV.js");
6629
+ const { startHub } = await import("./hub-YPNEYO3Z.js");
6551
6630
  await startHub(
6552
6631
  {
6553
6632
  topic: topic ?? "",
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  executeTests,
3
3
  runTestsTool
4
- } from "./chunk-E6RP5DBU.js";
4
+ } from "./chunk-34NJTPWZ.js";
5
5
  export {
6
6
  executeTests,
7
7
  runTestsTool
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  executeTests,
4
4
  runTestsTool
5
- } from "./chunk-3BHGEPIT.js";
6
- import "./chunk-5P4QTZBI.js";
5
+ } from "./chunk-K3JJX2Z5.js";
6
+ import "./chunk-2Q77FT3F.js";
7
7
  export {
8
8
  executeTests,
9
9
  runTestsTool