autojanet/skills/understand/build-fingerprints.mjs
Zoë cc74ad0bd0
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
fix: use library/ Harbor project, add skills, fix pipeline secrets
- .woodpecker.yaml: image paths -> library/autojanet-{agent,dispatcher}
- .woodpecker.yaml: secret names RS_HARBOR_USER / RS_HARBOR_PASS (global)
- container/Dockerfile: restore COPY skills/, skills/ populated from opencode config
- skills/: 84 opencode skills bundled into image
- k8s/manifests: update image refs to library/
2026-05-30 15:43:14 -07:00

90 lines
3.2 KiB
JavaScript

#!/usr/bin/env node
/**
* build-fingerprints.mjs
*
* Builds the structural-fingerprint baseline used by auto-update's
* incremental change detection. Runs once per /understand full rebuild
* (Phase 7 step 2.5), generating .understand-anything/fingerprints.json.
*
* Replaces the LLM-written fingerprint script that previously sat in
* SKILL.md as a code example — that example had the wrong signature
* for buildFingerprintStore() and never successfully produced a baseline,
* which silently broke auto-update for every install (see issue #152).
*
* Usage:
* node build-fingerprints.mjs <input.json>
*
* Input JSON:
* { projectRoot: string, sourceFilePaths: string[], gitCommitHash: string }
*
* Writes: <projectRoot>/.understand-anything/fingerprints.json
* Exit code: 0 on success (including 0 files analyzed); non-zero on error.
*/
import { createRequire } from 'node:module';
import { dirname, resolve } from 'node:path';
import { fileURLToPath, pathToFileURL } from 'node:url';
import { readFileSync } from 'node:fs';
const __dirname = dirname(fileURLToPath(import.meta.url));
// skills/understand/ -> plugin root is two dirs up
const pluginRoot = resolve(__dirname, '../..');
const require = createRequire(resolve(pluginRoot, 'package.json'));
// ---------------------------------------------------------------------------
// Resolve @understand-anything/core (matches extract-structure.mjs).
// pathToFileURL() is required for Windows: dynamic import() of a raw
// "C:\..." path throws ERR_UNSUPPORTED_ESM_URL_SCHEME.
// ---------------------------------------------------------------------------
let core;
try {
core = await import(pathToFileURL(require.resolve('@understand-anything/core')).href);
} catch {
core = await import(pathToFileURL(resolve(pluginRoot, 'packages/core/dist/index.js')).href);
}
const {
TreeSitterPlugin,
PluginRegistry,
builtinLanguageConfigs,
registerAllParsers,
buildFingerprintStore,
saveFingerprints,
} = core;
async function main() {
const [, , inputPath] = process.argv;
if (!inputPath) {
process.stderr.write('Usage: node build-fingerprints.mjs <input.json>\n');
process.exit(1);
}
const { projectRoot, sourceFilePaths, gitCommitHash } = JSON.parse(
readFileSync(inputPath, 'utf-8'),
);
if (!projectRoot || !Array.isArray(sourceFilePaths) || typeof gitCommitHash !== 'string') {
throw new Error(
'Invalid input: requires { projectRoot: string, sourceFilePaths: string[], gitCommitHash: string }',
);
}
// Create tree-sitter plugin with all configs that have WASM grammars,
// mirroring extract-structure.mjs so the baseline matches the comparison
// logic used during auto-updates.
const tsConfigs = builtinLanguageConfigs.filter((c) => c.treeSitter);
const tsPlugin = new TreeSitterPlugin(tsConfigs);
await tsPlugin.init();
const registry = new PluginRegistry();
registry.register(tsPlugin);
registerAllParsers(registry);
const store = buildFingerprintStore(projectRoot, sourceFilePaths, registry, gitCommitHash);
saveFingerprints(projectRoot, store);
const fileCount = Object.keys(store.files).length;
process.stdout.write(`Fingerprints baseline: ${fileCount} files\n`);
}
await main();