grepmax 0.7.21 → 0.7.22
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/commands/project.js +175 -0
- package/dist/commands/recent.js +131 -0
- package/dist/commands/related.js +170 -0
- package/dist/index.js +6 -0
- package/package.json +1 -1
- package/plugins/grepmax/.claude-plugin/plugin.json +1 -1
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.project = void 0;
|
|
46
|
+
const path = __importStar(require("node:path"));
|
|
47
|
+
const commander_1 = require("commander");
|
|
48
|
+
const vector_db_1 = require("../lib/store/vector-db");
|
|
49
|
+
const filter_builder_1 = require("../lib/utils/filter-builder");
|
|
50
|
+
const exit_1 = require("../lib/utils/exit");
|
|
51
|
+
const project_registry_1 = require("../lib/utils/project-registry");
|
|
52
|
+
const project_root_1 = require("../lib/utils/project-root");
|
|
53
|
+
function toArr(val) {
|
|
54
|
+
if (val && typeof val.toArray === "function") {
|
|
55
|
+
return val.toArray();
|
|
56
|
+
}
|
|
57
|
+
return Array.isArray(val) ? val : [];
|
|
58
|
+
}
|
|
59
|
+
exports.project = new commander_1.Command("project")
|
|
60
|
+
.description("Show project overview — languages, structure, key symbols")
|
|
61
|
+
.option("--root <dir>", "Project root (defaults to current directory)")
|
|
62
|
+
.action((opts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
63
|
+
var _a, _b, _c;
|
|
64
|
+
let vectorDb = null;
|
|
65
|
+
try {
|
|
66
|
+
const root = opts.root
|
|
67
|
+
? (_a = (0, project_root_1.findProjectRoot)(path.resolve(opts.root))) !== null && _a !== void 0 ? _a : path.resolve(opts.root)
|
|
68
|
+
: (_b = (0, project_root_1.findProjectRoot)(process.cwd())) !== null && _b !== void 0 ? _b : process.cwd();
|
|
69
|
+
const prefix = root.endsWith("/") ? root : `${root}/`;
|
|
70
|
+
const projectName = path.basename(root);
|
|
71
|
+
const paths = (0, project_root_1.ensureProjectPaths)(root);
|
|
72
|
+
vectorDb = new vector_db_1.VectorDB(paths.lancedbDir);
|
|
73
|
+
const table = yield vectorDb.ensureTable();
|
|
74
|
+
const rows = yield table
|
|
75
|
+
.query()
|
|
76
|
+
.select([
|
|
77
|
+
"path",
|
|
78
|
+
"role",
|
|
79
|
+
"is_exported",
|
|
80
|
+
"complexity",
|
|
81
|
+
"defined_symbols",
|
|
82
|
+
"referenced_symbols",
|
|
83
|
+
])
|
|
84
|
+
.where(`path LIKE '${(0, filter_builder_1.escapeSqlString)(prefix)}%'`)
|
|
85
|
+
.limit(200000)
|
|
86
|
+
.toArray();
|
|
87
|
+
if (rows.length === 0) {
|
|
88
|
+
console.log(`No indexed data found for ${root}. Run: gmax index --path ${root}`);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const files = new Set();
|
|
92
|
+
const extCounts = new Map();
|
|
93
|
+
const dirCounts = new Map();
|
|
94
|
+
const roleCounts = new Map();
|
|
95
|
+
const symbolRefs = new Map();
|
|
96
|
+
const entryPoints = [];
|
|
97
|
+
for (const row of rows) {
|
|
98
|
+
const p = String(row.path || "");
|
|
99
|
+
const role = String(row.role || "IMPLEMENTATION");
|
|
100
|
+
const exported = Boolean(row.is_exported);
|
|
101
|
+
const complexity = Number(row.complexity || 0);
|
|
102
|
+
const defs = toArr(row.defined_symbols);
|
|
103
|
+
const refs = toArr(row.referenced_symbols);
|
|
104
|
+
files.add(p);
|
|
105
|
+
const ext = path.extname(p).toLowerCase() || path.basename(p);
|
|
106
|
+
extCounts.set(ext, (extCounts.get(ext) || 0) + 1);
|
|
107
|
+
const rel = p.startsWith(prefix) ? p.slice(prefix.length) : p;
|
|
108
|
+
const parts = rel.split("/");
|
|
109
|
+
const dir = parts.length > 2
|
|
110
|
+
? `${parts.slice(0, 2).join("/")}/`
|
|
111
|
+
: parts.length > 1
|
|
112
|
+
? `${parts[0]}/`
|
|
113
|
+
: "(root)";
|
|
114
|
+
if (!dirCounts.has(dir))
|
|
115
|
+
dirCounts.set(dir, { files: new Set(), chunks: 0 });
|
|
116
|
+
const dc = dirCounts.get(dir);
|
|
117
|
+
dc.files.add(p);
|
|
118
|
+
dc.chunks++;
|
|
119
|
+
roleCounts.set(role, (roleCounts.get(role) || 0) + 1);
|
|
120
|
+
for (const ref of refs)
|
|
121
|
+
symbolRefs.set(ref, (symbolRefs.get(ref) || 0) + 1);
|
|
122
|
+
if (exported && role === "ORCHESTRATION" && complexity >= 5 && defs.length > 0) {
|
|
123
|
+
entryPoints.push({
|
|
124
|
+
symbol: defs[0],
|
|
125
|
+
path: p.startsWith(prefix) ? p.slice(prefix.length) : p,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const projects = (0, project_registry_1.listProjects)();
|
|
130
|
+
const proj = projects.find((p) => p.root === root);
|
|
131
|
+
console.log(`Project: ${projectName} (${root})`);
|
|
132
|
+
console.log(`Last indexed: ${(_c = proj === null || proj === void 0 ? void 0 : proj.lastIndexed) !== null && _c !== void 0 ? _c : "unknown"} • ${rows.length} chunks • ${files.size} files\n`);
|
|
133
|
+
const extEntries = Array.from(extCounts.entries())
|
|
134
|
+
.sort((a, b) => b[1] - a[1])
|
|
135
|
+
.slice(0, 8);
|
|
136
|
+
console.log(`Languages: ${extEntries.map(([ext, count]) => `${ext} (${Math.round((count / rows.length) * 100)}%)`).join(", ")}\n`);
|
|
137
|
+
console.log("Directory structure:");
|
|
138
|
+
for (const [dir, data] of Array.from(dirCounts.entries())
|
|
139
|
+
.sort((a, b) => b[1].chunks - a[1].chunks)
|
|
140
|
+
.slice(0, 12)) {
|
|
141
|
+
console.log(` ${dir.padEnd(25)} (${data.files.size} files, ${data.chunks} chunks)`);
|
|
142
|
+
}
|
|
143
|
+
const roleEntries = Array.from(roleCounts.entries()).sort((a, b) => b[1] - a[1]);
|
|
144
|
+
console.log(`\nRoles: ${roleEntries.map(([r, c]) => `${Math.round((c / rows.length) * 100)}% ${r}`).join(", ")}\n`);
|
|
145
|
+
const topSymbols = Array.from(symbolRefs.entries())
|
|
146
|
+
.sort((a, b) => b[1] - a[1])
|
|
147
|
+
.slice(0, 8);
|
|
148
|
+
if (topSymbols.length > 0) {
|
|
149
|
+
console.log("Key symbols (by reference count):");
|
|
150
|
+
for (const [sym, count] of topSymbols) {
|
|
151
|
+
console.log(` ${sym.padEnd(25)} (referenced ${count}x)`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (entryPoints.length > 0) {
|
|
155
|
+
console.log("\nEntry points (exported orchestration):");
|
|
156
|
+
for (const ep of entryPoints.slice(0, 10)) {
|
|
157
|
+
console.log(` ${ep.symbol.padEnd(25)} ${ep.path}`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
const msg = error instanceof Error ? error.message : "Unknown error";
|
|
163
|
+
console.error("Project summary failed:", msg);
|
|
164
|
+
process.exitCode = 1;
|
|
165
|
+
}
|
|
166
|
+
finally {
|
|
167
|
+
if (vectorDb) {
|
|
168
|
+
try {
|
|
169
|
+
yield vectorDb.close();
|
|
170
|
+
}
|
|
171
|
+
catch (_d) { }
|
|
172
|
+
}
|
|
173
|
+
yield (0, exit_1.gracefulExit)();
|
|
174
|
+
}
|
|
175
|
+
}));
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
45
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
46
|
+
var m = o[Symbol.asyncIterator], i;
|
|
47
|
+
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
48
|
+
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
49
|
+
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
50
|
+
};
|
|
51
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
52
|
+
exports.recent = void 0;
|
|
53
|
+
const path = __importStar(require("node:path"));
|
|
54
|
+
const commander_1 = require("commander");
|
|
55
|
+
const config_1 = require("../config");
|
|
56
|
+
const meta_cache_1 = require("../lib/store/meta-cache");
|
|
57
|
+
const exit_1 = require("../lib/utils/exit");
|
|
58
|
+
const project_root_1 = require("../lib/utils/project-root");
|
|
59
|
+
function formatTimeAgo(ms) {
|
|
60
|
+
const sec = Math.floor(ms / 1000);
|
|
61
|
+
if (sec < 60)
|
|
62
|
+
return `${sec}s ago`;
|
|
63
|
+
const min = Math.floor(sec / 60);
|
|
64
|
+
if (min < 60)
|
|
65
|
+
return `${min}m ago`;
|
|
66
|
+
const hr = Math.floor(min / 60);
|
|
67
|
+
if (hr < 24)
|
|
68
|
+
return `${hr}h ago`;
|
|
69
|
+
const days = Math.floor(hr / 24);
|
|
70
|
+
return `${days}d ago`;
|
|
71
|
+
}
|
|
72
|
+
exports.recent = new commander_1.Command("recent")
|
|
73
|
+
.description("Show recently modified indexed files")
|
|
74
|
+
.option("-l, --limit <n>", "Max files (default 20)", "20")
|
|
75
|
+
.option("--root <dir>", "Project root (defaults to current directory)")
|
|
76
|
+
.action((opts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
77
|
+
var _a, e_1, _b, _c;
|
|
78
|
+
var _d, _e;
|
|
79
|
+
const limit = Math.min(Math.max(Number.parseInt(opts.limit || "20", 10), 1), 50);
|
|
80
|
+
try {
|
|
81
|
+
const root = opts.root
|
|
82
|
+
? (_d = (0, project_root_1.findProjectRoot)(path.resolve(opts.root))) !== null && _d !== void 0 ? _d : path.resolve(opts.root)
|
|
83
|
+
: (_e = (0, project_root_1.findProjectRoot)(process.cwd())) !== null && _e !== void 0 ? _e : process.cwd();
|
|
84
|
+
const prefix = root.endsWith("/") ? root : `${root}/`;
|
|
85
|
+
const metaCache = new meta_cache_1.MetaCache(config_1.PATHS.lmdbPath);
|
|
86
|
+
try {
|
|
87
|
+
const files = [];
|
|
88
|
+
try {
|
|
89
|
+
for (var _f = true, _g = __asyncValues(metaCache.entries()), _h; _h = yield _g.next(), _a = _h.done, !_a; _f = true) {
|
|
90
|
+
_c = _h.value;
|
|
91
|
+
_f = false;
|
|
92
|
+
const { path: p, entry } = _c;
|
|
93
|
+
if (p.startsWith(prefix)) {
|
|
94
|
+
files.push({ path: p, mtimeMs: entry.mtimeMs });
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
99
|
+
finally {
|
|
100
|
+
try {
|
|
101
|
+
if (!_f && !_a && (_b = _g.return)) yield _b.call(_g);
|
|
102
|
+
}
|
|
103
|
+
finally { if (e_1) throw e_1.error; }
|
|
104
|
+
}
|
|
105
|
+
files.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
106
|
+
const top = files.slice(0, limit);
|
|
107
|
+
if (top.length === 0) {
|
|
108
|
+
console.log(`No indexed files found for ${root}`);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const now = Date.now();
|
|
112
|
+
console.log(`Recent changes in ${path.basename(root)} (${top.length} most recent):\n`);
|
|
113
|
+
for (const f of top) {
|
|
114
|
+
const rel = f.path.startsWith(prefix)
|
|
115
|
+
? f.path.slice(prefix.length)
|
|
116
|
+
: f.path;
|
|
117
|
+
const ago = formatTimeAgo(now - f.mtimeMs);
|
|
118
|
+
console.log(` ${ago.padEnd(10)} ${rel}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
finally {
|
|
122
|
+
yield metaCache.close();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
const msg = error instanceof Error ? error.message : "Unknown error";
|
|
127
|
+
console.error("Recent changes failed:", msg);
|
|
128
|
+
process.exitCode = 1;
|
|
129
|
+
}
|
|
130
|
+
yield (0, exit_1.gracefulExit)();
|
|
131
|
+
}));
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.related = void 0;
|
|
46
|
+
const path = __importStar(require("node:path"));
|
|
47
|
+
const commander_1 = require("commander");
|
|
48
|
+
const vector_db_1 = require("../lib/store/vector-db");
|
|
49
|
+
const filter_builder_1 = require("../lib/utils/filter-builder");
|
|
50
|
+
const exit_1 = require("../lib/utils/exit");
|
|
51
|
+
const project_root_1 = require("../lib/utils/project-root");
|
|
52
|
+
function toArr(val) {
|
|
53
|
+
if (val && typeof val.toArray === "function") {
|
|
54
|
+
return val.toArray();
|
|
55
|
+
}
|
|
56
|
+
return Array.isArray(val) ? val : [];
|
|
57
|
+
}
|
|
58
|
+
exports.related = new commander_1.Command("related")
|
|
59
|
+
.description("Find files related by shared symbol references")
|
|
60
|
+
.argument("<file>", "File path relative to project root")
|
|
61
|
+
.option("-l, --limit <n>", "Max results per direction (default 10)", "10")
|
|
62
|
+
.action((file, opts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
63
|
+
var _a;
|
|
64
|
+
const limit = Math.min(Math.max(Number.parseInt(opts.limit || "10", 10), 1), 25);
|
|
65
|
+
let vectorDb = null;
|
|
66
|
+
try {
|
|
67
|
+
const projectRoot = (_a = (0, project_root_1.findProjectRoot)(process.cwd())) !== null && _a !== void 0 ? _a : process.cwd();
|
|
68
|
+
const paths = (0, project_root_1.ensureProjectPaths)(projectRoot);
|
|
69
|
+
vectorDb = new vector_db_1.VectorDB(paths.lancedbDir);
|
|
70
|
+
const absPath = path.resolve(projectRoot, file);
|
|
71
|
+
const table = yield vectorDb.ensureTable();
|
|
72
|
+
const fileChunks = yield table
|
|
73
|
+
.query()
|
|
74
|
+
.select(["defined_symbols", "referenced_symbols"])
|
|
75
|
+
.where(`path = '${(0, filter_builder_1.escapeSqlString)(absPath)}'`)
|
|
76
|
+
.toArray();
|
|
77
|
+
if (fileChunks.length === 0) {
|
|
78
|
+
console.log(`File not found in index: ${file}`);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const definedHere = new Set();
|
|
82
|
+
const referencedHere = new Set();
|
|
83
|
+
for (const chunk of fileChunks) {
|
|
84
|
+
for (const s of toArr(chunk.defined_symbols))
|
|
85
|
+
definedHere.add(s);
|
|
86
|
+
for (const s of toArr(chunk.referenced_symbols))
|
|
87
|
+
referencedHere.add(s);
|
|
88
|
+
}
|
|
89
|
+
// Dependencies
|
|
90
|
+
const depCounts = new Map();
|
|
91
|
+
for (const sym of referencedHere) {
|
|
92
|
+
if (definedHere.has(sym))
|
|
93
|
+
continue;
|
|
94
|
+
const rows = yield table
|
|
95
|
+
.query()
|
|
96
|
+
.select(["path"])
|
|
97
|
+
.where(`array_contains(defined_symbols, '${(0, filter_builder_1.escapeSqlString)(sym)}')`)
|
|
98
|
+
.limit(3)
|
|
99
|
+
.toArray();
|
|
100
|
+
for (const row of rows) {
|
|
101
|
+
const p = String(row.path || "");
|
|
102
|
+
if (p === absPath)
|
|
103
|
+
continue;
|
|
104
|
+
depCounts.set(p, (depCounts.get(p) || 0) + 1);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// Dependents
|
|
108
|
+
const revCounts = new Map();
|
|
109
|
+
for (const sym of definedHere) {
|
|
110
|
+
const rows = yield table
|
|
111
|
+
.query()
|
|
112
|
+
.select(["path"])
|
|
113
|
+
.where(`array_contains(referenced_symbols, '${(0, filter_builder_1.escapeSqlString)(sym)}')`)
|
|
114
|
+
.limit(20)
|
|
115
|
+
.toArray();
|
|
116
|
+
for (const row of rows) {
|
|
117
|
+
const p = String(row.path || "");
|
|
118
|
+
if (p === absPath)
|
|
119
|
+
continue;
|
|
120
|
+
revCounts.set(p, (revCounts.get(p) || 0) + 1);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
console.log(`Related files for ${file}:\n`);
|
|
124
|
+
const topDeps = Array.from(depCounts.entries())
|
|
125
|
+
.sort((a, b) => b[1] - a[1])
|
|
126
|
+
.slice(0, limit);
|
|
127
|
+
if (topDeps.length > 0) {
|
|
128
|
+
console.log("Dependencies (files this imports/calls):");
|
|
129
|
+
for (const [p, count] of topDeps) {
|
|
130
|
+
const rel = p.startsWith(`${projectRoot}/`)
|
|
131
|
+
? p.slice(projectRoot.length + 1)
|
|
132
|
+
: p;
|
|
133
|
+
console.log(` ${rel.padEnd(40)} (${count} shared symbol${count > 1 ? "s" : ""})`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
console.log("Dependencies: none found");
|
|
138
|
+
}
|
|
139
|
+
console.log("");
|
|
140
|
+
const topRevs = Array.from(revCounts.entries())
|
|
141
|
+
.sort((a, b) => b[1] - a[1])
|
|
142
|
+
.slice(0, limit);
|
|
143
|
+
if (topRevs.length > 0) {
|
|
144
|
+
console.log("Dependents (files that call this):");
|
|
145
|
+
for (const [p, count] of topRevs) {
|
|
146
|
+
const rel = p.startsWith(`${projectRoot}/`)
|
|
147
|
+
? p.slice(projectRoot.length + 1)
|
|
148
|
+
: p;
|
|
149
|
+
console.log(` ${rel.padEnd(40)} (${count} shared symbol${count > 1 ? "s" : ""})`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
console.log("Dependents: none found");
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
const msg = error instanceof Error ? error.message : "Unknown error";
|
|
158
|
+
console.error("Related files failed:", msg);
|
|
159
|
+
process.exitCode = 1;
|
|
160
|
+
}
|
|
161
|
+
finally {
|
|
162
|
+
if (vectorDb) {
|
|
163
|
+
try {
|
|
164
|
+
yield vectorDb.close();
|
|
165
|
+
}
|
|
166
|
+
catch (_b) { }
|
|
167
|
+
}
|
|
168
|
+
yield (0, exit_1.gracefulExit)();
|
|
169
|
+
}
|
|
170
|
+
}));
|
package/dist/index.js
CHANGED
|
@@ -45,6 +45,9 @@ const droid_1 = require("./commands/droid");
|
|
|
45
45
|
const index_1 = require("./commands/index");
|
|
46
46
|
const list_1 = require("./commands/list");
|
|
47
47
|
const mcp_1 = require("./commands/mcp");
|
|
48
|
+
const project_1 = require("./commands/project");
|
|
49
|
+
const recent_1 = require("./commands/recent");
|
|
50
|
+
const related_1 = require("./commands/related");
|
|
48
51
|
const opencode_1 = require("./commands/opencode");
|
|
49
52
|
const search_1 = require("./commands/search");
|
|
50
53
|
const serve_1 = require("./commands/serve");
|
|
@@ -77,6 +80,9 @@ commander_1.program.addCommand(list_1.list);
|
|
|
77
80
|
commander_1.program.addCommand(skeleton_1.skeleton);
|
|
78
81
|
commander_1.program.addCommand(symbols_1.symbols);
|
|
79
82
|
commander_1.program.addCommand(trace_1.trace);
|
|
83
|
+
commander_1.program.addCommand(project_1.project);
|
|
84
|
+
commander_1.program.addCommand(related_1.related);
|
|
85
|
+
commander_1.program.addCommand(recent_1.recent);
|
|
80
86
|
// Services
|
|
81
87
|
commander_1.program.addCommand(serve_1.serve);
|
|
82
88
|
commander_1.program.addCommand(watch_1.watch);
|
package/package.json
CHANGED