codecortex-ai 0.1.0 → 0.2.1

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/cli/index.js CHANGED
@@ -7,21 +7,27 @@ import {
7
7
  enrichCouplingWithImports,
8
8
  ensureDir,
9
9
  getLatestSession,
10
+ getModuleDependencies,
10
11
  listDecisions,
11
12
  listModuleDocs,
12
13
  listSessions,
13
14
  readFile,
15
+ readGraph,
14
16
  readManifest,
17
+ readModuleDoc,
18
+ searchKnowledge,
15
19
  startServer,
16
20
  updateManifest,
17
21
  writeFile,
18
22
  writeGraph,
19
23
  writeJsonStream,
20
24
  writeManifest,
25
+ writeModuleDoc,
21
26
  writeSession
22
- } from "../chunk-F4WTE7R3.js";
27
+ } from "../chunk-DWUIP3WA.js";
23
28
 
24
29
  // src/cli/index.ts
30
+ import { createRequire as createRequire2 } from "module";
25
31
  import { Command } from "commander";
26
32
 
27
33
  // src/cli/commands/init.ts
@@ -74,9 +80,11 @@ var LANGUAGE_LOADERS = {
74
80
  ocaml: () => require2("tree-sitter-ocaml").ocaml,
75
81
  elm: () => require2("tree-sitter-elm"),
76
82
  elisp: () => require2("tree-sitter-elisp"),
83
+ // Web / Templating
84
+ vue: () => require2("tree-sitter-vue"),
85
+ liquid: () => require2("tree-sitter-liquid"),
77
86
  // Web3 / Other
78
87
  solidity: () => require2("tree-sitter-solidity"),
79
- vue: () => require2("tree-sitter-vue"),
80
88
  ql: () => require2("tree-sitter-ql")
81
89
  };
82
90
  var EXTENSION_MAP = {
@@ -147,6 +155,8 @@ var EXTENSION_MAP = {
147
155
  ".sol": "solidity",
148
156
  // Vue
149
157
  ".vue": "vue",
158
+ // Liquid
159
+ ".liquid": "liquid",
150
160
  // CodeQL
151
161
  ".ql": "ql"
152
162
  };
@@ -1492,6 +1502,75 @@ function extractGenericCalls(tree, file) {
1492
1502
 
1493
1503
  // src/cli/commands/init.ts
1494
1504
  import { readFile as readFile2 } from "fs/promises";
1505
+
1506
+ // src/core/module-gen.ts
1507
+ import { existsSync as existsSync3 } from "fs";
1508
+ async function generateStructuralModuleDocs(projectRoot, data) {
1509
+ let generated = 0;
1510
+ for (const mod of data.graph.modules) {
1511
+ const docPath = cortexPath(projectRoot, "modules", `${mod.name}.md`);
1512
+ if (existsSync3(docPath)) continue;
1513
+ const moduleFiles = new Set(mod.files);
1514
+ const exported = data.symbols.filter((s) => moduleFiles.has(s.file) && s.exported).map((s) => {
1515
+ const loc = s.endLine > s.startLine ? `${s.file}:${s.startLine}-${s.endLine}` : `${s.file}:${s.startLine}`;
1516
+ return `${s.name} (${s.kind}, ${loc})`;
1517
+ });
1518
+ const deps = getModuleDependencies(data.graph, mod.name);
1519
+ const importsFromModules = /* @__PURE__ */ new Set();
1520
+ const importedByModules = /* @__PURE__ */ new Set();
1521
+ for (const edge of deps.imports) {
1522
+ for (const other of data.graph.modules) {
1523
+ if (other.name !== mod.name && other.files.includes(edge.target)) {
1524
+ importsFromModules.add(other.name);
1525
+ }
1526
+ }
1527
+ }
1528
+ for (const edge of deps.importedBy) {
1529
+ for (const other of data.graph.modules) {
1530
+ if (other.name !== mod.name && other.files.includes(edge.source)) {
1531
+ importedByModules.add(other.name);
1532
+ }
1533
+ }
1534
+ }
1535
+ const depLines = [];
1536
+ if (importsFromModules.size > 0) depLines.push(`Imports from: ${[...importsFromModules].join(", ")}`);
1537
+ if (importedByModules.size > 0) depLines.push(`Imported by: ${[...importedByModules].join(", ")}`);
1538
+ let temporalSignals;
1539
+ if (data.temporal) {
1540
+ const hotspots = data.temporal.hotspots.filter((h) => moduleFiles.has(h.file));
1541
+ const topHotspot = hotspots[0];
1542
+ const couplings = data.temporal.coupling.filter(
1543
+ (c) => moduleFiles.has(c.fileA) || moduleFiles.has(c.fileB)
1544
+ );
1545
+ const coupledWith = couplings.map((c) => {
1546
+ const other = moduleFiles.has(c.fileA) ? c.fileB : c.fileA;
1547
+ return `${other} (${c.cochanges} co-changes, ${Math.round(c.strength * 100)}%)`;
1548
+ });
1549
+ const bugs = data.temporal.bugHistory.filter((b) => moduleFiles.has(b.file));
1550
+ temporalSignals = {
1551
+ churn: topHotspot ? `${topHotspot.changes} changes (${topHotspot.stability})` : "no hotspot data",
1552
+ coupledWith,
1553
+ stability: topHotspot?.stability ?? "unknown",
1554
+ bugHistory: bugs.flatMap((b) => b.lessons),
1555
+ lastChanged: topHotspot?.lastChanged ?? "unknown"
1556
+ };
1557
+ }
1558
+ const analysis = {
1559
+ name: mod.name,
1560
+ purpose: `${mod.files.length} files, ${mod.lines} lines (${mod.language}). Auto-generated from code structure \u2014 use \`analyze_module\` MCP tool for semantic analysis.`,
1561
+ dataFlow: `Files: ${mod.files.join(", ")}`,
1562
+ publicApi: exported,
1563
+ gotchas: [],
1564
+ dependencies: depLines,
1565
+ temporalSignals
1566
+ };
1567
+ await writeModuleDoc(projectRoot, analysis);
1568
+ generated++;
1569
+ }
1570
+ return generated;
1571
+ }
1572
+
1573
+ // src/cli/commands/init.ts
1495
1574
  async function initCommand(opts) {
1496
1575
  const root = resolve(opts.root);
1497
1576
  const days = parseInt(opts.days, 10);
@@ -1619,7 +1698,12 @@ async function initCommand(opts) {
1619
1698
  });
1620
1699
  await writeManifest(root, manifest);
1621
1700
  await writeFile(cortexPath(root, "patterns.md"), "# Coding Patterns\n\nNo patterns recorded yet. Use `update_patterns` to add patterns.\n");
1622
- console.log(" Written: cortex.yaml, symbols.json, graph.json, temporal.json, overview.md, patterns.md");
1701
+ const moduleDocsGenerated = await generateStructuralModuleDocs(root, {
1702
+ graph,
1703
+ symbols: allSymbols,
1704
+ temporal: temporalData
1705
+ });
1706
+ console.log(` Written: cortex.yaml, symbols.json, graph.json, temporal.json, overview.md, patterns.md, ${moduleDocsGenerated} module docs`);
1623
1707
  console.log("");
1624
1708
  console.log("Step 6/6: Generating constitution...");
1625
1709
  await generateConstitution(root, {
@@ -1689,10 +1773,10 @@ function generateOverview(project) {
1689
1773
 
1690
1774
  // src/cli/commands/serve.ts
1691
1775
  import { resolve as resolve2 } from "path";
1692
- import { existsSync as existsSync3 } from "fs";
1776
+ import { existsSync as existsSync4 } from "fs";
1693
1777
  async function serveCommand(opts) {
1694
1778
  const root = resolve2(opts.root);
1695
- if (!existsSync3(cortexPath(root, "cortex.yaml"))) {
1779
+ if (!existsSync4(cortexPath(root, "cortex.yaml"))) {
1696
1780
  console.error("Error: No CodeCortex knowledge found.");
1697
1781
  console.error(`Run 'codecortex init' first to analyze the codebase.`);
1698
1782
  console.error(`Expected: ${cortexPath(root, "cortex.yaml")}`);
@@ -1703,7 +1787,7 @@ async function serveCommand(opts) {
1703
1787
 
1704
1788
  // src/cli/commands/update.ts
1705
1789
  import { resolve as resolve3 } from "path";
1706
- import { existsSync as existsSync4 } from "fs";
1790
+ import { existsSync as existsSync5 } from "fs";
1707
1791
 
1708
1792
  // src/git/diff.ts
1709
1793
  import simpleGit2 from "simple-git";
@@ -1739,7 +1823,7 @@ import { readFile as fsRead3 } from "fs/promises";
1739
1823
  async function updateCommand(opts) {
1740
1824
  const root = resolve3(opts.root);
1741
1825
  const days = parseInt(opts.days, 10);
1742
- if (!existsSync4(cortexPath(root, "cortex.yaml"))) {
1826
+ if (!existsSync5(cortexPath(root, "cortex.yaml"))) {
1743
1827
  console.error("Error: No CodeCortex knowledge found. Run `codecortex init` first.");
1744
1828
  process.exit(1);
1745
1829
  }
@@ -1821,6 +1905,11 @@ async function updateCommand(opts) {
1821
1905
  if (temporalData) {
1822
1906
  await writeFile(cortexPath(root, "temporal.json"), JSON.stringify(temporalData, null, 2));
1823
1907
  }
1908
+ await generateStructuralModuleDocs(root, {
1909
+ graph,
1910
+ symbols: allSymbols,
1911
+ temporal: temporalData
1912
+ });
1824
1913
  await updateManifest(root, {
1825
1914
  totalFiles: project.files.length,
1826
1915
  totalSymbols: allSymbols.length,
@@ -1856,10 +1945,10 @@ async function updateCommand(opts) {
1856
1945
 
1857
1946
  // src/cli/commands/status.ts
1858
1947
  import { resolve as resolve4 } from "path";
1859
- import { existsSync as existsSync5 } from "fs";
1948
+ import { existsSync as existsSync6 } from "fs";
1860
1949
  async function statusCommand(opts) {
1861
1950
  const root = resolve4(opts.root);
1862
- if (!existsSync5(cortexPath(root, "cortex.yaml"))) {
1951
+ if (!existsSync6(cortexPath(root, "cortex.yaml"))) {
1863
1952
  console.log("No CodeCortex knowledge found.");
1864
1953
  console.log(`Run 'codecortex init' to analyze this codebase.`);
1865
1954
  return;
@@ -1946,12 +2035,300 @@ async function statusCommand(opts) {
1946
2035
  }
1947
2036
  }
1948
2037
 
2038
+ // src/cli/commands/symbols.ts
2039
+ import { resolve as resolve5 } from "path";
2040
+ import { existsSync as existsSync7 } from "fs";
2041
+ async function symbolsCommand(query, opts) {
2042
+ const root = resolve5(opts.root);
2043
+ if (!existsSync7(cortexPath(root, "cortex.yaml"))) {
2044
+ console.log("No CodeCortex knowledge found.");
2045
+ console.log(`Run 'codecortex init' to analyze this codebase.`);
2046
+ return;
2047
+ }
2048
+ const content = await readFile(cortexPath(root, "symbols.json"));
2049
+ if (!content) {
2050
+ console.log("No symbol index found. Run `codecortex init` first.");
2051
+ return;
2052
+ }
2053
+ const index = JSON.parse(content);
2054
+ if (!query && !opts.kind && !opts.file && !opts.exported) {
2055
+ printSummary(index);
2056
+ return;
2057
+ }
2058
+ let matches = index.symbols;
2059
+ if (query) {
2060
+ const q = query.toLowerCase();
2061
+ matches = matches.filter((s) => s.name.toLowerCase().includes(q));
2062
+ }
2063
+ if (opts.kind) {
2064
+ matches = matches.filter((s) => s.kind === opts.kind);
2065
+ }
2066
+ if (opts.file) {
2067
+ matches = matches.filter((s) => s.file.includes(opts.file));
2068
+ }
2069
+ if (opts.exported) {
2070
+ matches = matches.filter((s) => s.exported);
2071
+ }
2072
+ const limit = parseInt(opts.limit ?? "30", 10);
2073
+ const display = matches.slice(0, limit);
2074
+ if (display.length === 0) {
2075
+ console.log(`No symbols found${query ? ` matching "${query}"` : ""}.`);
2076
+ return;
2077
+ }
2078
+ console.log("");
2079
+ for (const s of display) {
2080
+ const lines = s.endLine > s.startLine ? `${s.startLine}-${s.endLine}` : `${s.startLine}`;
2081
+ const exp = s.exported ? "exported" : "local";
2082
+ console.log(` ${pad(s.kind, 12)} ${pad(s.name, 30)} ${pad(s.file, 40)} ${pad(lines, 10)} ${exp}`);
2083
+ if (s.signature) {
2084
+ console.log(`${" ".repeat(14)}${s.signature}`);
2085
+ }
2086
+ }
2087
+ console.log("");
2088
+ if (matches.length > limit) {
2089
+ console.log(`Showing ${limit} of ${matches.length} matches. Use -l to show more.`);
2090
+ } else {
2091
+ console.log(`${matches.length} symbol${matches.length === 1 ? "" : "s"} found.`);
2092
+ }
2093
+ }
2094
+ function printSummary(index) {
2095
+ console.log("");
2096
+ console.log(`Symbol Index: ${index.total} symbols`);
2097
+ console.log("\u2500".repeat(50));
2098
+ const byKind = /* @__PURE__ */ new Map();
2099
+ for (const s of index.symbols) {
2100
+ byKind.set(s.kind, (byKind.get(s.kind) ?? 0) + 1);
2101
+ }
2102
+ console.log("");
2103
+ console.log("By Kind:");
2104
+ for (const [kind, count] of [...byKind.entries()].sort((a, b) => b[1] - a[1])) {
2105
+ console.log(` ${pad(kind, 14)} ${count}`);
2106
+ }
2107
+ const byFile = /* @__PURE__ */ new Map();
2108
+ for (const s of index.symbols) {
2109
+ byFile.set(s.file, (byFile.get(s.file) ?? 0) + 1);
2110
+ }
2111
+ console.log("");
2112
+ console.log("Top Files:");
2113
+ for (const [file, count] of [...byFile.entries()].sort((a, b) => b[1] - a[1]).slice(0, 10)) {
2114
+ console.log(` ${pad(file, 45)} ${count} symbols`);
2115
+ }
2116
+ const exported = index.symbols.filter((s) => s.exported).length;
2117
+ console.log("");
2118
+ console.log(`Exported: ${exported}/${index.total}`);
2119
+ console.log("");
2120
+ console.log("Run `codecortex symbols <query>` to search.");
2121
+ }
2122
+ function pad(str, len) {
2123
+ return str.length >= len ? str : str + " ".repeat(len - str.length);
2124
+ }
2125
+
2126
+ // src/cli/commands/search.ts
2127
+ import { resolve as resolve6 } from "path";
2128
+ import { existsSync as existsSync8 } from "fs";
2129
+ async function searchCommand(query, opts) {
2130
+ const root = resolve6(opts.root);
2131
+ if (!existsSync8(cortexPath(root, "cortex.yaml"))) {
2132
+ console.log("No CodeCortex knowledge found.");
2133
+ console.log(`Run 'codecortex init' to analyze this codebase.`);
2134
+ return;
2135
+ }
2136
+ const results = await searchKnowledge(root, query);
2137
+ const limit = parseInt(opts.limit ?? "20", 10);
2138
+ const display = results.slice(0, limit);
2139
+ if (display.length === 0) {
2140
+ console.log(`No results for "${query}".`);
2141
+ return;
2142
+ }
2143
+ console.log("");
2144
+ console.log(`Search: "${query}"`);
2145
+ console.log("\u2500".repeat(50));
2146
+ for (let i = 0; i < display.length; i++) {
2147
+ const r = display[i];
2148
+ console.log("");
2149
+ console.log(` [${i + 1}] ${r.file}:${r.line}`);
2150
+ const ctxLines = r.context.split("\n");
2151
+ for (const line of ctxLines) {
2152
+ const trimmed = line.trim();
2153
+ if (!trimmed) continue;
2154
+ if (trimmed.toLowerCase().includes(query.toLowerCase())) {
2155
+ console.log(` > ${trimmed}`);
2156
+ } else {
2157
+ console.log(` ${trimmed}`);
2158
+ }
2159
+ }
2160
+ }
2161
+ console.log("");
2162
+ if (results.length > limit) {
2163
+ console.log(`Showing ${limit} of ${results.length} results. Use -l to show more.`);
2164
+ } else {
2165
+ console.log(`${results.length} result${results.length === 1 ? "" : "s"} found.`);
2166
+ }
2167
+ }
2168
+
2169
+ // src/cli/commands/modules.ts
2170
+ import { resolve as resolve7 } from "path";
2171
+ import { existsSync as existsSync9 } from "fs";
2172
+ async function modulesCommand(name, opts) {
2173
+ const root = resolve7(opts.root);
2174
+ if (!existsSync9(cortexPath(root, "cortex.yaml"))) {
2175
+ console.log("No CodeCortex knowledge found.");
2176
+ console.log(`Run 'codecortex init' to analyze this codebase.`);
2177
+ return;
2178
+ }
2179
+ const graph = await readGraph(root);
2180
+ if (!graph) {
2181
+ console.log("No dependency graph found. Run `codecortex init` first.");
2182
+ return;
2183
+ }
2184
+ if (!name) {
2185
+ await printModuleList(root, graph);
2186
+ return;
2187
+ }
2188
+ await printModuleDetail(root, name, graph);
2189
+ }
2190
+ async function printModuleList(root, graph) {
2191
+ const docsAvailable = new Set(await listModuleDocs(root));
2192
+ console.log("");
2193
+ console.log(`Modules: ${graph.modules.length}`);
2194
+ console.log("\u2500".repeat(70));
2195
+ console.log("");
2196
+ console.log(` ${pad2("MODULE", 18)} ${pad2("FILES", 6)} ${pad2("LINES", 7)} ${pad2("SYMBOLS", 8)} ${pad2("LANG", 14)} DOC`);
2197
+ for (const mod of [...graph.modules].sort((a, b) => a.name.localeCompare(b.name))) {
2198
+ const hasDoc = docsAvailable.has(mod.name) ? "yes" : "--";
2199
+ console.log(` ${pad2(mod.name, 18)} ${pad2(String(mod.files.length), 6)} ${pad2(String(mod.lines), 7)} ${pad2(String(mod.symbols), 8)} ${pad2(mod.language, 14)} ${hasDoc}`);
2200
+ }
2201
+ const withDocs = graph.modules.filter((m) => docsAvailable.has(m.name)).length;
2202
+ console.log("");
2203
+ console.log(`${graph.modules.length} modules, ${withDocs} with docs.`);
2204
+ console.log("");
2205
+ console.log("Run `codecortex modules <name>` to deep-dive into a module.");
2206
+ }
2207
+ async function printModuleDetail(root, name, graph) {
2208
+ const mod = graph.modules.find((m) => m.name === name);
2209
+ if (!mod) {
2210
+ const available = graph.modules.map((m) => m.name).join(", ");
2211
+ console.log(`Module "${name}" not found. Available: ${available}`);
2212
+ return;
2213
+ }
2214
+ console.log("");
2215
+ console.log(`Module: ${name}`);
2216
+ console.log("\u2550".repeat(50));
2217
+ const doc = await readModuleDoc(root, name);
2218
+ if (doc) {
2219
+ console.log("");
2220
+ console.log(doc);
2221
+ } else {
2222
+ console.log("");
2223
+ console.log(`No module doc for "${name}".`);
2224
+ console.log(`Run \`codecortex init\` to generate structural docs.`);
2225
+ }
2226
+ const deps = getModuleDependencies(graph, name);
2227
+ if (deps.imports.length > 0) {
2228
+ console.log("");
2229
+ console.log("Imports:");
2230
+ const seen = /* @__PURE__ */ new Set();
2231
+ for (const edge of deps.imports) {
2232
+ const key = `${edge.source} -> ${edge.target}`;
2233
+ if (seen.has(key)) continue;
2234
+ seen.add(key);
2235
+ const specifiers = edge.specifiers.length > 0 ? ` [${edge.specifiers.join(", ")}]` : "";
2236
+ console.log(` ${edge.source} -> ${edge.target}${specifiers}`);
2237
+ }
2238
+ }
2239
+ if (deps.importedBy.length > 0) {
2240
+ console.log("");
2241
+ console.log("Imported By:");
2242
+ const seen = /* @__PURE__ */ new Set();
2243
+ for (const edge of deps.importedBy) {
2244
+ const key = `${edge.source} -> ${edge.target}`;
2245
+ if (seen.has(key)) continue;
2246
+ seen.add(key);
2247
+ const specifiers = edge.specifiers.length > 0 ? ` [${edge.specifiers.join(", ")}]` : "";
2248
+ console.log(` ${edge.source} -> ${edge.target}${specifiers}`);
2249
+ }
2250
+ }
2251
+ console.log("");
2252
+ console.log(`Stats: ${mod.files.length} files, ${mod.lines} lines, ${mod.symbols} symbols (${mod.language})`);
2253
+ }
2254
+ function pad2(str, len) {
2255
+ return str.length >= len ? str : str + " ".repeat(len - str.length);
2256
+ }
2257
+
2258
+ // src/cli/commands/hotspots.ts
2259
+ import { resolve as resolve8 } from "path";
2260
+ import { existsSync as existsSync10 } from "fs";
2261
+ async function hotspotsCommand(opts) {
2262
+ const root = resolve8(opts.root);
2263
+ if (!existsSync10(cortexPath(root, "cortex.yaml"))) {
2264
+ console.log("No CodeCortex knowledge found.");
2265
+ console.log(`Run 'codecortex init' to analyze this codebase.`);
2266
+ return;
2267
+ }
2268
+ const content = await readFile(cortexPath(root, "temporal.json"));
2269
+ if (!content) {
2270
+ console.log("No temporal data found. Run `codecortex init` in a git repository.");
2271
+ return;
2272
+ }
2273
+ const temporal = JSON.parse(content);
2274
+ const limit = parseInt(opts.limit ?? "15", 10);
2275
+ const riskMap = /* @__PURE__ */ new Map();
2276
+ for (const h of temporal.hotspots) {
2277
+ riskMap.set(h.file, { churn: h.changes, couplings: 0, bugs: 0, risk: h.changes });
2278
+ }
2279
+ for (const c of temporal.coupling) {
2280
+ for (const f of [c.fileA, c.fileB]) {
2281
+ const entry = riskMap.get(f) ?? { churn: 0, couplings: 0, bugs: 0, risk: 0 };
2282
+ entry.couplings++;
2283
+ entry.risk += c.strength * 2;
2284
+ riskMap.set(f, entry);
2285
+ }
2286
+ }
2287
+ for (const b of temporal.bugHistory) {
2288
+ const entry = riskMap.get(b.file) ?? { churn: 0, couplings: 0, bugs: 0, risk: 0 };
2289
+ entry.bugs = b.fixCommits;
2290
+ entry.risk += b.fixCommits * 3;
2291
+ riskMap.set(b.file, entry);
2292
+ }
2293
+ const ranked = [...riskMap.entries()].sort((a, b) => b[1].risk - a[1].risk).slice(0, limit).map(([file, data]) => ({ file, ...data, risk: Math.round(data.risk * 100) / 100 }));
2294
+ console.log("");
2295
+ console.log(`Hotspots \u2014 ${temporal.periodDays} days, ${temporal.totalCommits} commits`);
2296
+ console.log("\u2500".repeat(70));
2297
+ console.log("");
2298
+ console.log(` ${pad3("#", 4)} ${pad3("FILE", 42)} ${pad3("CHURN", 6)} ${pad3("CPLS", 5)} ${pad3("BUGS", 5)} RISK`);
2299
+ for (let i = 0; i < ranked.length; i++) {
2300
+ const r = ranked[i];
2301
+ console.log(` ${pad3(String(i + 1), 4)} ${pad3(r.file, 42)} ${pad3(String(r.churn), 6)} ${pad3(String(r.couplings), 5)} ${pad3(String(r.bugs), 5)} ${r.risk.toFixed(2)}`);
2302
+ }
2303
+ const hidden = temporal.coupling.filter((c) => !c.hasImport && c.strength >= 0.3);
2304
+ if (hidden.length > 0) {
2305
+ console.log("");
2306
+ console.log("Hidden Dependencies (co-change but no import):");
2307
+ for (const h of hidden.slice(0, 10)) {
2308
+ console.log(` ${h.fileA} <-> ${h.fileB} (${h.cochanges} co-changes, ${Math.round(h.strength * 100)}%)`);
2309
+ }
2310
+ if (hidden.length > 10) {
2311
+ console.log(` ... and ${hidden.length - 10} more`);
2312
+ }
2313
+ }
2314
+ console.log("");
2315
+ }
2316
+ function pad3(str, len) {
2317
+ return str.length >= len ? str : str + " ".repeat(len - str.length);
2318
+ }
2319
+
1949
2320
  // src/cli/index.ts
2321
+ var require3 = createRequire2(import.meta.url);
2322
+ var { version } = require3("../../package.json");
1950
2323
  var program = new Command();
1951
- program.name("codecortex").description("Persistent, AI-powered codebase knowledge layer").version("0.1.0");
2324
+ program.name("codecortex").description("Persistent, AI-powered codebase knowledge layer").version(version);
1952
2325
  program.command("init").description("Initialize codebase knowledge: discover files, extract symbols, analyze git history").option("-r, --root <path>", "Project root directory", process.cwd()).option("-d, --days <number>", "Days of git history to analyze", "90").action(initCommand);
1953
2326
  program.command("serve").description("Start MCP server (stdio transport) for AI agent access").option("-r, --root <path>", "Project root directory", process.cwd()).action(serveCommand);
1954
2327
  program.command("update").description("Update knowledge for changed files since last session").option("-r, --root <path>", "Project root directory", process.cwd()).option("-d, --days <number>", "Days of git history to re-analyze", "90").action(updateCommand);
1955
2328
  program.command("status").description("Show knowledge freshness, stale modules, and symbol counts").option("-r, --root <path>", "Project root directory", process.cwd()).action(statusCommand);
2329
+ program.command("symbols [query]").description("Browse and filter the symbol index").option("-r, --root <path>", "Project root directory", process.cwd()).option("-k, --kind <kind>", "Filter by kind: function, class, interface, type, const, enum, method, property, variable").option("-f, --file <path>", "Filter by file path (partial match)").option("-e, --exported", "Show only exported symbols").option("-l, --limit <number>", "Max results", "30").action((query, opts) => symbolsCommand(query, opts));
2330
+ program.command("search <query>").description("Search across all CodeCortex knowledge files").option("-r, --root <path>", "Project root directory", process.cwd()).option("-l, --limit <number>", "Max results", "20").action((query, opts) => searchCommand(query, opts));
2331
+ program.command("modules [name]").description("List modules or deep-dive into a specific module").option("-r, --root <path>", "Project root directory", process.cwd()).action((name, opts) => modulesCommand(name, opts));
2332
+ program.command("hotspots").description("Show files ranked by risk: churn + coupling + bug history").option("-r, --root <path>", "Project root directory", process.cwd()).option("-l, --limit <number>", "Number of files to show", "15").action(hotspotsCommand);
1956
2333
  program.parse();
1957
2334
  //# sourceMappingURL=index.js.map