codeimpact 0.4.1 → 0.4.3
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/index.js +127 -12
- package/dist/index.js.map +3 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -28332,15 +28332,16 @@ var EXCLUDED_PATH_PATTERNS = [
|
|
|
28332
28332
|
"knowledge/"
|
|
28333
28333
|
];
|
|
28334
28334
|
function PATH_EXCLUSION_SQL(col = "path") {
|
|
28335
|
-
return `${col} NOT LIKE '%node_modules
|
|
28336
|
-
AND ${col} NOT LIKE '%.git
|
|
28335
|
+
return `${col} NOT LIKE '%node_modules/%'
|
|
28336
|
+
AND ${col} NOT LIKE '%.git/%'
|
|
28337
28337
|
AND ${col} NOT LIKE '%/dist/%'
|
|
28338
28338
|
AND ${col} NOT LIKE '%/build/%'
|
|
28339
28339
|
AND ${col} NOT LIKE '%/venv/%'
|
|
28340
28340
|
AND ${col} NOT LIKE '%/.venv/%'
|
|
28341
28341
|
AND ${col} NOT LIKE '%/env/%'
|
|
28342
28342
|
AND ${col} NOT LIKE '%__pycache__%'
|
|
28343
|
-
AND ${col} NOT LIKE '%/knowledge/%'
|
|
28343
|
+
AND ${col} NOT LIKE '%/knowledge/%'
|
|
28344
|
+
AND ${col} NOT LIKE 'knowledge/%'`;
|
|
28344
28345
|
}
|
|
28345
28346
|
var Tier2Storage = class {
|
|
28346
28347
|
db;
|
|
@@ -28392,6 +28393,33 @@ var Tier2Storage = class {
|
|
|
28392
28393
|
const stmt = this.db.prepare("DELETE FROM files WHERE path = ?");
|
|
28393
28394
|
stmt.run(path);
|
|
28394
28395
|
}
|
|
28396
|
+
/**
|
|
28397
|
+
* Bulk-delete files whose paths match excluded patterns (node_modules, venv, etc.).
|
|
28398
|
+
* Call this during initialization to clean up stale data from previous indexing runs.
|
|
28399
|
+
* Returns the number of rows deleted.
|
|
28400
|
+
*/
|
|
28401
|
+
purgeExcludedFiles() {
|
|
28402
|
+
const excludedIds = this.db.prepare(`
|
|
28403
|
+
SELECT id FROM files
|
|
28404
|
+
WHERE NOT (${PATH_EXCLUSION_SQL("path")})
|
|
28405
|
+
`).all();
|
|
28406
|
+
if (excludedIds.length === 0) return 0;
|
|
28407
|
+
const ids = excludedIds.map((r) => r.id);
|
|
28408
|
+
const chunkSize = 500;
|
|
28409
|
+
let deleted = 0;
|
|
28410
|
+
for (let i = 0; i < ids.length; i += chunkSize) {
|
|
28411
|
+
const chunk = ids.slice(i, i + chunkSize);
|
|
28412
|
+
const placeholders = chunk.map(() => "?").join(",");
|
|
28413
|
+
this.db.prepare(`DELETE FROM embeddings WHERE file_id IN (${placeholders})`).run(...chunk);
|
|
28414
|
+
this.db.prepare(`DELETE FROM symbols WHERE file_id IN (${placeholders})`).run(...chunk);
|
|
28415
|
+
this.db.prepare(`DELETE FROM imports WHERE file_id IN (${placeholders})`).run(...chunk);
|
|
28416
|
+
this.db.prepare(`DELETE FROM exports WHERE file_id IN (${placeholders})`).run(...chunk);
|
|
28417
|
+
this.db.prepare(`DELETE FROM dependencies WHERE source_file_id IN (${placeholders}) OR target_file_id IN (${placeholders})`).run(...chunk, ...chunk);
|
|
28418
|
+
const result = this.db.prepare(`DELETE FROM files WHERE id IN (${placeholders})`).run(...chunk);
|
|
28419
|
+
deleted += result.changes;
|
|
28420
|
+
}
|
|
28421
|
+
return deleted;
|
|
28422
|
+
}
|
|
28395
28423
|
getAllFiles() {
|
|
28396
28424
|
const stmt = this.db.prepare(`
|
|
28397
28425
|
SELECT id, path, content_hash as contentHash, preview, language,
|
|
@@ -28671,6 +28699,10 @@ var Tier2Storage = class {
|
|
|
28671
28699
|
const stmt = this.db.prepare("DELETE FROM dependencies WHERE source_file_id = ?");
|
|
28672
28700
|
stmt.run(fileId);
|
|
28673
28701
|
}
|
|
28702
|
+
/** Remove ALL dependency edges. Used before a full rebuild pass. */
|
|
28703
|
+
clearAllDependencies() {
|
|
28704
|
+
this.db.prepare("DELETE FROM dependencies").run();
|
|
28705
|
+
}
|
|
28674
28706
|
// Project summary
|
|
28675
28707
|
updateProjectSummary(name, description, languages, keyDirectories, architectureNotes) {
|
|
28676
28708
|
const stmt = this.db.prepare(`
|
|
@@ -30294,6 +30326,28 @@ var ASTParser = class {
|
|
|
30294
30326
|
import chokidar from "chokidar";
|
|
30295
30327
|
import { EventEmitter } from "events";
|
|
30296
30328
|
import { relative } from "path";
|
|
30329
|
+
function buildIgnoreMatcher(patterns) {
|
|
30330
|
+
const segments = /* @__PURE__ */ new Set();
|
|
30331
|
+
for (const p of patterns) {
|
|
30332
|
+
const m = p.match(/^\*\*\/([^/*]+)\/\*\*?$/);
|
|
30333
|
+
if (m && m[1]) {
|
|
30334
|
+
segments.add(m[1]);
|
|
30335
|
+
}
|
|
30336
|
+
}
|
|
30337
|
+
for (const s of ["node_modules", ".git", "venv", ".venv", "env", "__pycache__", "vendor", "knowledge", ".next", ".nuxt"]) {
|
|
30338
|
+
segments.add(s);
|
|
30339
|
+
}
|
|
30340
|
+
const segmentArray = [...segments];
|
|
30341
|
+
return (testPath) => {
|
|
30342
|
+
const normalised = testPath.replace(/\\/g, "/");
|
|
30343
|
+
for (const seg of segmentArray) {
|
|
30344
|
+
if (normalised.includes("/" + seg + "/") || normalised.endsWith("/" + seg) || normalised === seg) {
|
|
30345
|
+
return true;
|
|
30346
|
+
}
|
|
30347
|
+
}
|
|
30348
|
+
return false;
|
|
30349
|
+
};
|
|
30350
|
+
}
|
|
30297
30351
|
var FileWatcher = class extends EventEmitter {
|
|
30298
30352
|
watcher = null;
|
|
30299
30353
|
projectPath;
|
|
@@ -30307,15 +30361,16 @@ var FileWatcher = class extends EventEmitter {
|
|
|
30307
30361
|
if (this.watcher) {
|
|
30308
30362
|
return;
|
|
30309
30363
|
}
|
|
30364
|
+
const ignoreFn = buildIgnoreMatcher(this.ignorePatterns);
|
|
30310
30365
|
this.watcher = chokidar.watch(this.projectPath, {
|
|
30311
30366
|
ignored: [
|
|
30312
30367
|
/(^|[\/\\])\../,
|
|
30313
30368
|
// dotfiles
|
|
30314
|
-
|
|
30369
|
+
ignoreFn
|
|
30315
30370
|
],
|
|
30316
30371
|
persistent: true,
|
|
30317
|
-
ignoreInitial:
|
|
30318
|
-
//
|
|
30372
|
+
ignoreInitial: true,
|
|
30373
|
+
// Don't emit 'add' for existing files — initial index uses glob
|
|
30319
30374
|
awaitWriteFinish: {
|
|
30320
30375
|
stabilityThreshold: 300,
|
|
30321
30376
|
pollInterval: 100
|
|
@@ -30334,7 +30389,7 @@ var FileWatcher = class extends EventEmitter {
|
|
|
30334
30389
|
});
|
|
30335
30390
|
}
|
|
30336
30391
|
handleEvent(type, path) {
|
|
30337
|
-
const relativePath = relative(this.projectPath, path);
|
|
30392
|
+
const relativePath = relative(this.projectPath, path).replace(/\\/g, "/");
|
|
30338
30393
|
const event = {
|
|
30339
30394
|
type,
|
|
30340
30395
|
path,
|
|
@@ -30460,6 +30515,31 @@ function countLines(content) {
|
|
|
30460
30515
|
}
|
|
30461
30516
|
|
|
30462
30517
|
// src/indexing/indexer.ts
|
|
30518
|
+
var EXCLUDED_PATH_SEGMENTS = [
|
|
30519
|
+
"node_modules",
|
|
30520
|
+
".git",
|
|
30521
|
+
"venv",
|
|
30522
|
+
".venv",
|
|
30523
|
+
"env",
|
|
30524
|
+
"__pycache__",
|
|
30525
|
+
".pytest_cache",
|
|
30526
|
+
".mypy_cache",
|
|
30527
|
+
".ruff_cache",
|
|
30528
|
+
".tox",
|
|
30529
|
+
".nox",
|
|
30530
|
+
"vendor",
|
|
30531
|
+
".gradle",
|
|
30532
|
+
"Pods",
|
|
30533
|
+
"DerivedData",
|
|
30534
|
+
".next",
|
|
30535
|
+
".nuxt",
|
|
30536
|
+
".svelte-kit",
|
|
30537
|
+
"knowledge"
|
|
30538
|
+
];
|
|
30539
|
+
function isExcludedPath(relPath) {
|
|
30540
|
+
const segments = relPath.replace(/\\/g, "/").split("/");
|
|
30541
|
+
return segments.some((seg) => EXCLUDED_PATH_SEGMENTS.includes(seg));
|
|
30542
|
+
}
|
|
30463
30543
|
var Indexer = class extends EventEmitter2 {
|
|
30464
30544
|
config;
|
|
30465
30545
|
embeddingGenerator;
|
|
@@ -30525,9 +30605,12 @@ var Indexer = class extends EventEmitter2 {
|
|
|
30525
30605
|
}
|
|
30526
30606
|
async indexFile(absolutePath) {
|
|
30527
30607
|
try {
|
|
30608
|
+
const relativePath = relative2(this.config.projectPath, absolutePath).replace(/\\/g, "/");
|
|
30609
|
+
if (isExcludedPath(relativePath)) {
|
|
30610
|
+
return false;
|
|
30611
|
+
}
|
|
30528
30612
|
const content = readFileSync3(absolutePath, "utf-8");
|
|
30529
30613
|
const stats = statSync(absolutePath);
|
|
30530
|
-
const relativePath = relative2(this.config.projectPath, absolutePath);
|
|
30531
30614
|
const contentHash = hashContent(content);
|
|
30532
30615
|
const existingFile = this.tier2.getFile(relativePath);
|
|
30533
30616
|
if (existingFile && existingFile.contentHash === contentHash) {
|
|
@@ -30604,6 +30687,10 @@ var Indexer = class extends EventEmitter2 {
|
|
|
30604
30687
|
this.isIndexing = true;
|
|
30605
30688
|
this.emit("indexingStarted");
|
|
30606
30689
|
try {
|
|
30690
|
+
const purged = this.tier2.purgeExcludedFiles();
|
|
30691
|
+
if (purged > 0) {
|
|
30692
|
+
console.error(`[Index] Purged ${purged} excluded files from database`);
|
|
30693
|
+
}
|
|
30607
30694
|
const patterns = [
|
|
30608
30695
|
"**/*.ts",
|
|
30609
30696
|
"**/*.tsx",
|
|
@@ -30662,6 +30749,10 @@ var Indexer = class extends EventEmitter2 {
|
|
|
30662
30749
|
console.error(`Error indexing ${file2}:`, error2);
|
|
30663
30750
|
}
|
|
30664
30751
|
}
|
|
30752
|
+
const depCount = this.rebuildDependencies();
|
|
30753
|
+
if (depCount > 0) {
|
|
30754
|
+
console.error(`[Index] Built ${depCount} dependency edges`);
|
|
30755
|
+
}
|
|
30665
30756
|
this.emit("indexingComplete", {
|
|
30666
30757
|
total: checked,
|
|
30667
30758
|
indexed,
|
|
@@ -30671,6 +30762,23 @@ var Indexer = class extends EventEmitter2 {
|
|
|
30671
30762
|
this.isIndexing = false;
|
|
30672
30763
|
}
|
|
30673
30764
|
}
|
|
30765
|
+
/**
|
|
30766
|
+
* Rebuild all dependency edges from stored imports.
|
|
30767
|
+
* Run after initial indexing so all target files are in the DB.
|
|
30768
|
+
*/
|
|
30769
|
+
rebuildDependencies() {
|
|
30770
|
+
this.tier2.clearAllDependencies();
|
|
30771
|
+
const allImports = this.tier2.getAllImports();
|
|
30772
|
+
let count = 0;
|
|
30773
|
+
for (const imp of allImports) {
|
|
30774
|
+
const targetFile = this.tier2.resolveImportToFile(imp.filePath, imp.importedFrom, this.config.projectPath);
|
|
30775
|
+
if (targetFile) {
|
|
30776
|
+
this.tier2.addDependency(imp.fileId, targetFile.id, "imports");
|
|
30777
|
+
count++;
|
|
30778
|
+
}
|
|
30779
|
+
}
|
|
30780
|
+
return count;
|
|
30781
|
+
}
|
|
30674
30782
|
startWatching() {
|
|
30675
30783
|
this.watcher.start();
|
|
30676
30784
|
}
|
|
@@ -30885,7 +30993,7 @@ ${result.preview}
|
|
|
30885
30993
|
if (currentFile && dirname3(r.file) === dirname3(currentFile)) {
|
|
30886
30994
|
score *= 1.5;
|
|
30887
30995
|
}
|
|
30888
|
-
const hoursSinceModified = (Date.now() - r.lastModified) / 36e5;
|
|
30996
|
+
const hoursSinceModified = (Date.now() - r.lastModified * 1e3) / 36e5;
|
|
30889
30997
|
if (hoursSinceModified < 24) {
|
|
30890
30998
|
score *= 1 + 0.3 * (24 - hoursSinceModified) / 24;
|
|
30891
30999
|
}
|
|
@@ -35630,7 +35738,7 @@ ${code}` : code;
|
|
|
35630
35738
|
file: result.path,
|
|
35631
35739
|
similarity,
|
|
35632
35740
|
snippet: result.preview,
|
|
35633
|
-
lastModified: file2 ? new Date(file2.lastModified) : void 0,
|
|
35741
|
+
lastModified: file2 ? new Date(file2.lastModified * 1e3) : void 0,
|
|
35634
35742
|
usageCount: dependents.length + 1,
|
|
35635
35743
|
function: symbols.length > 0 ? symbols[0].name : void 0
|
|
35636
35744
|
});
|
|
@@ -44395,7 +44503,6 @@ var PlatformRuleSync = class {
|
|
|
44395
44503
|
results.push(writeManagedFile(join17(this.projectPath, ".cursor", "rules", "codeimpact.mdc"), cursorSection, options));
|
|
44396
44504
|
const claudeSection = renderPlatformSection("claude", paths, skillIndex, guidance);
|
|
44397
44505
|
results.push(writeManagedFile(join17(this.projectPath, "CLAUDE.md"), claudeSection, options));
|
|
44398
|
-
results.push(writeManagedFile(join17(this.projectPath, "Cloud.md"), claudeSection, options));
|
|
44399
44506
|
const codexSection = renderPlatformSection("codex", paths, skillIndex, guidance);
|
|
44400
44507
|
results.push(writeManagedFile(join17(this.projectPath, "AGENTS.md"), codexSection, options));
|
|
44401
44508
|
results.push(writeManagedFile(join17(this.projectPath, "CODEX.md"), codexSection, options));
|
|
@@ -45197,7 +45304,10 @@ var CodeImpactEngine = class {
|
|
|
45197
45304
|
this.featureContextManager.onFileOpened(path);
|
|
45198
45305
|
this.summarizer.invalidateSummaryByPath(path);
|
|
45199
45306
|
this.knowledgeOrchestrator.schedule("file_indexed", [path]);
|
|
45200
|
-
|
|
45307
|
+
const normalizedPath = path.replace(/\\/g, "/");
|
|
45308
|
+
if (!normalizedPath.includes("knowledge/") && !normalizedPath.includes(".code-impact/")) {
|
|
45309
|
+
this.pendingComponentDocPaths.add(path);
|
|
45310
|
+
}
|
|
45201
45311
|
if (this.componentDocTimer) clearTimeout(this.componentDocTimer);
|
|
45202
45312
|
this.componentDocTimer = setTimeout(() => {
|
|
45203
45313
|
this.batchGenerateComponentDocs(Array.from(this.pendingComponentDocPaths)).catch((err) => {
|
|
@@ -45368,6 +45478,11 @@ var CodeImpactEngine = class {
|
|
|
45368
45478
|
FROM files f
|
|
45369
45479
|
LEFT JOIN dependencies d ON d.target_file_id = f.id
|
|
45370
45480
|
WHERE f.language IS NOT NULL
|
|
45481
|
+
AND f.path NOT LIKE '%node_modules%'
|
|
45482
|
+
AND f.path NOT LIKE '%knowledge/%'
|
|
45483
|
+
AND f.path NOT LIKE '%.code-impact/%'
|
|
45484
|
+
AND f.path NOT LIKE '%/venv/%'
|
|
45485
|
+
AND f.path NOT LIKE '%/.venv/%'
|
|
45371
45486
|
GROUP BY f.id
|
|
45372
45487
|
ORDER BY dep_count DESC
|
|
45373
45488
|
LIMIT 20
|