mirror of
https://github.com/Egonex-AI/Understand-Anything.git
synced 2026-06-22 10:58:03 +08:00
fix: address remaining Copilot review findings
- SKILL.md Phase 7: use core buildFingerprintStore instead of ad-hoc regex script - change-classifier: accurate FULL_UPDATE reason message (count vs percentage) - persistence: add saveConfig/loadConfig tests (round-trip, missing, corrupted) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -43,13 +43,21 @@ export function classifyUpdate(
|
||||
}
|
||||
|
||||
// Too many structural changes — suggest full rebuild
|
||||
if (structuralCount > 30 || (totalFilesInGraph > 0 && structuralCount / totalFilesInGraph > 0.5)) {
|
||||
const triggeredByCount = structuralCount > 30;
|
||||
const triggeredByPercentage = totalFilesInGraph > 0 && structuralCount / totalFilesInGraph > 0.5;
|
||||
if (triggeredByCount || triggeredByPercentage) {
|
||||
const thresholdReason =
|
||||
triggeredByCount && triggeredByPercentage
|
||||
? ">30 files and >50% of project"
|
||||
: triggeredByCount
|
||||
? ">30 files"
|
||||
: ">50% of project";
|
||||
return {
|
||||
action: "FULL_UPDATE",
|
||||
filesToReanalyze: [...structurallyChangedFiles, ...newFiles],
|
||||
rerunArchitecture: true,
|
||||
rerunTour: true,
|
||||
reason: `${structuralCount} files have structural changes (>${totalFilesInGraph > 0 ? "50% of project" : "30 files"}) — full rebuild recommended`,
|
||||
reason: `${structuralCount} files have structural changes (${thresholdReason}) — full rebuild recommended`,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { mkdtempSync, rmSync, existsSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { tmpdir } from "node:os";
|
||||
import { writeFileSync } from "node:fs";
|
||||
import { saveGraph, loadGraph, saveMeta, loadMeta, saveFingerprints, loadFingerprints } from "./index.js";
|
||||
import { saveGraph, loadGraph, saveMeta, loadMeta, saveFingerprints, loadFingerprints, saveConfig, loadConfig } from "./index.js";
|
||||
import type { KnowledgeGraph, AnalysisMeta } from "../types.js";
|
||||
import type { FingerprintStore } from "../fingerprint.js";
|
||||
|
||||
@@ -159,4 +159,28 @@ describe("persistence", () => {
|
||||
expect(loaded).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("saveConfig / loadConfig", () => {
|
||||
it("should round-trip config correctly", () => {
|
||||
saveConfig(tempDir, { autoUpdate: true });
|
||||
const loaded = loadConfig(tempDir);
|
||||
|
||||
expect(loaded).toEqual({ autoUpdate: true });
|
||||
});
|
||||
|
||||
it("should return default config when no file exists", () => {
|
||||
const loaded = loadConfig(tempDir);
|
||||
|
||||
expect(loaded).toEqual({ autoUpdate: false });
|
||||
});
|
||||
|
||||
it("should return default config when config.json is corrupted", () => {
|
||||
saveConfig(tempDir, { autoUpdate: true });
|
||||
const dir = join(tempDir, ".understand-anything");
|
||||
writeFileSync(join(dir, "config.json"), "not json!!", "utf-8");
|
||||
|
||||
const loaded = loadConfig(tempDir);
|
||||
expect(loaded).toEqual({ autoUpdate: false });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -482,34 +482,15 @@ Pass these parameters in the dispatch prompt:
|
||||
|
||||
2.5. **Generate structural fingerprints** for all analyzed files and save to `$PROJECT_ROOT/.understand-anything/fingerprints.json`. This creates the baseline for future automatic incremental updates.
|
||||
|
||||
Write and execute a Node.js script that:
|
||||
1. Reads each source file path from the scan results (Phase 1)
|
||||
2. For each file: computes a SHA-256 content hash, then extracts function/class/import/export declarations via regex matching:
|
||||
- Functions: `function NAME(`, `const NAME = (`, `export function NAME(`, arrow functions assigned to const/let
|
||||
- Classes: `class NAME`, `export class NAME`
|
||||
- Imports: `import ... from '...'`, `import '...'`
|
||||
- Exports: `export { ... }`, `export default`, `export function`, `export class`, `export const`
|
||||
3. For each function: record name, parameter names, whether exported, and line count
|
||||
4. For each class: record name, method names, property names, whether exported
|
||||
5. Writes the fingerprint store JSON to `$PROJECT_ROOT/.understand-anything/fingerprints.json`:
|
||||
```json
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"gitCommitHash": "<commit hash>",
|
||||
"generatedAt": "<ISO timestamp>",
|
||||
"files": {
|
||||
"<filePath>": {
|
||||
"filePath": "<filePath>",
|
||||
"contentHash": "<sha256>",
|
||||
"functions": [{ "name": "...", "params": ["..."], "exported": true, "lineCount": 35 }],
|
||||
"classes": [{ "name": "...", "methods": ["..."], "properties": ["..."], "exported": true, "lineCount": 50 }],
|
||||
"imports": [{ "source": "...", "specifiers": ["..."] }],
|
||||
"exports": ["name1", "name2"],
|
||||
"totalLines": 120
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
Write and execute a Node.js script that uses the core fingerprint module (tree-sitter-based, not regex):
|
||||
```javascript
|
||||
import { buildFingerprintStore } from '@understand-anything/core';
|
||||
import { saveFingerprints } from '@understand-anything/core';
|
||||
|
||||
const store = await buildFingerprintStore('<PROJECT_ROOT>', sourceFilePaths);
|
||||
saveFingerprints('<PROJECT_ROOT>', store);
|
||||
```
|
||||
Where `sourceFilePaths` is the list of all analyzed source file paths from Phase 1. This uses the same tree-sitter analysis pipeline as the main fingerprint engine, ensuring the baseline matches the comparison logic used during auto-updates.
|
||||
|
||||
3. Clean up intermediate files:
|
||||
```bash
|
||||
|
||||
Reference in New Issue
Block a user