@vibgrate/cli 2026.702.2 → 2026.703.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/DOCS.md +521 -146
- package/LICENSE +202 -0
- package/NOTICE +40 -0
- package/README.md +232 -250
- package/dist/baseline-D2T3V76P.js +6 -0
- package/dist/baseline-D2T3V76P.js.map +1 -0
- package/dist/chunk-4M2MUQRO.js +800 -0
- package/dist/chunk-4M2MUQRO.js.map +1 -0
- package/dist/chunk-E7Q3P6V7.js +6267 -0
- package/dist/chunk-E7Q3P6V7.js.map +1 -0
- package/dist/chunk-ROWQLHEX.js +31 -0
- package/dist/chunk-ROWQLHEX.js.map +1 -0
- package/dist/chunk-RXP66R2E.js +39 -0
- package/dist/chunk-RXP66R2E.js.map +1 -0
- package/dist/chunk-TVPE5CA2.js +11389 -0
- package/dist/chunk-TVPE5CA2.js.map +1 -0
- package/dist/chunk-X5YT263H.js +912 -0
- package/dist/chunk-X5YT263H.js.map +1 -0
- package/dist/cli.d.ts +44 -1
- package/dist/cli.js +3816 -165
- package/dist/cli.js.map +1 -0
- package/dist/fs-7KZ4F3SB.js +3 -0
- package/dist/fs-7KZ4F3SB.js.map +1 -0
- package/dist/index.d.ts +1010 -1
- package/dist/index.js +42 -1
- package/dist/index.js.map +1 -0
- package/dist/parse-worker.d.ts +23 -0
- package/dist/parse-worker.js +32 -0
- package/dist/parse-worker.js.map +1 -0
- package/dist/types-C6ZyQpa9.d.ts +168 -0
- package/grammars/tree-sitter-bash.wasm +0 -0
- package/grammars/tree-sitter-c.wasm +0 -0
- package/grammars/tree-sitter-c_sharp.wasm +0 -0
- package/grammars/tree-sitter-cpp.wasm +0 -0
- package/grammars/tree-sitter-dart.wasm +0 -0
- package/grammars/tree-sitter-elixir.wasm +0 -0
- package/grammars/tree-sitter-go.wasm +0 -0
- package/grammars/tree-sitter-java.wasm +0 -0
- package/grammars/tree-sitter-javascript.wasm +0 -0
- package/grammars/tree-sitter-kotlin.wasm +0 -0
- package/grammars/tree-sitter-lua.wasm +0 -0
- package/grammars/tree-sitter-php.wasm +0 -0
- package/grammars/tree-sitter-python.wasm +0 -0
- package/grammars/tree-sitter-ruby.wasm +0 -0
- package/grammars/tree-sitter-rust.wasm +0 -0
- package/grammars/tree-sitter-scala.wasm +0 -0
- package/grammars/tree-sitter-swift.wasm +0 -0
- package/grammars/tree-sitter-tsx.wasm +0 -0
- package/grammars/tree-sitter-typescript.wasm +0 -0
- package/grammars/tree-sitter-zig.wasm +0 -0
- package/package.json +68 -33
- package/scripts/postinstall.mjs +84 -0
- package/skills/README.md +58 -0
- package/skills/vg/SKILL.md +42 -0
- package/HCS-RUNTIME-SETUP.md +0 -73
- package/LICENSE.md +0 -45
- package/dist/baseline-TJDKYSFL.js +0 -1
- package/dist/chunk-EK7ODJWE.js +0 -1
- package/dist/chunk-GGDB72YE.js +0 -323
- package/dist/chunk-MKDRULJ6.js +0 -1
- package/dist/chunk-NGFYX3CW.js +0 -2
- package/dist/chunk-OQSVJXWJ.js +0 -143
- package/dist/chunk-XTHPCEME.js +0 -2
- package/dist/dist-5D3BKCOR.js +0 -1
- package/dist/fs-PXXYZATK-ZP2RBR47.js +0 -1
- package/dist/hcs-wasm/package.json +0 -3
- package/dist/hcs-wasm/vibgrate_hcs_wasm.js +0 -450
- package/dist/hcs-wasm/vibgrate_hcs_wasm_bg.wasm +0 -0
- package/dist/hcs-worker.js +0 -374406
- package/dist/semver-TPPMM2NV.js +0 -1
package/dist/index.js
CHANGED
|
@@ -1 +1,42 @@
|
|
|
1
|
-
export{
|
|
1
|
+
export { ASSISTANTS, FREE_PACK, GraphIndex, GraphSource, SCHEMA_VERSION, SKIP_DIRS, TOOLS, UsageError, addLibrary, analyze, applyCoverage, applyStaticTestLinkage, assistantById, buildFacts, buildGraph, buildModuleResolver, cosine, coveringTests, createServer, decodeScipIndex, defaultGraphPath, inventory as dependencyInventory, detectRunner, discover, discoverModels, driftCount, driftFor, enrichOnline, exportGraph, findNodes, formatForExt, getNodeEmbeddings, groundGraph, hasDrift, identifierParts, impactOf, installAssistant, isTestFile, libId, loadCatalog, loadCoverage, loadEmbedder, loadGraph, loadSnapshot, nodeById, nodeEmbedText, parseGraph, parseJsonc, probeFreshness, queryGraph, queryGraphSemantic, readDoc, readSavings, recordSaving, refreshIfStale, relativeResolver, renderHtml, renderReport, resolveLib, resolveOne, saveCatalog, savingsRecorded, scipEdges, serializeGraph, serveStdio, shortestPath, stableStringify, testsToRun, uninstallAssistant, verifyDeterminism, vibgrateDir, writeArtifacts, writeSnapshot } from './chunk-E7Q3P6V7.js';
|
|
2
|
+
export { LANGUAGES, allLanguageIds, grammarsSourceDir, langById, langForExtension, parseSource } from './chunk-X5YT263H.js';
|
|
3
|
+
export { VERSION } from './chunk-TVPE5CA2.js';
|
|
4
|
+
import { redactUrlCredentials, redactSecrets } from './chunk-RXP66R2E.js';
|
|
5
|
+
import './chunk-4M2MUQRO.js';
|
|
6
|
+
import { execFileSync } from 'child_process';
|
|
7
|
+
|
|
8
|
+
function buildEnvelope(root, graph, scanIngestId) {
|
|
9
|
+
const sha = git(root, ["rev-parse", "HEAD"]) ?? "0000000000000000000000000000000000000000";
|
|
10
|
+
const branch = git(root, ["rev-parse", "--abbrev-ref", "HEAD"]) ?? "HEAD";
|
|
11
|
+
const remoteUrl = git(root, ["config", "--get", "remote.origin.url"]) ?? void 0;
|
|
12
|
+
return {
|
|
13
|
+
schemaVersion: "vg-graph/1.0",
|
|
14
|
+
artifactType: "graph",
|
|
15
|
+
scanIngestId,
|
|
16
|
+
vcs: { sha, shortSha: sha.slice(0, 12), branch },
|
|
17
|
+
repository: remoteUrl ? { remoteUrl: redactUrlCredentials(remoteUrl) } : void 0,
|
|
18
|
+
generatedAt: graph.generatedAt,
|
|
19
|
+
graph: redactGraph(graph)
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function redactGraph(graph) {
|
|
23
|
+
return {
|
|
24
|
+
...graph,
|
|
25
|
+
nodes: graph.nodes.map((n) => {
|
|
26
|
+
const signature = n.signature ? redactSecrets(n.signature) : n.signature;
|
|
27
|
+
const doc = n.doc ? redactSecrets(n.doc) : n.doc;
|
|
28
|
+
return signature !== n.signature || doc !== n.doc ? { ...n, signature, doc } : n;
|
|
29
|
+
})
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function git(root, args) {
|
|
33
|
+
try {
|
|
34
|
+
return execFileSync("git", args, { cwd: root, encoding: "utf8" }).trim() || null;
|
|
35
|
+
} catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { buildEnvelope, redactGraph };
|
|
41
|
+
//# sourceMappingURL=index.js.map
|
|
42
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/engine/push.ts"],"names":[],"mappings":";;;;;;;AAsBO,SAAS,aAAA,CAAc,IAAA,EAAc,KAAA,EAAgB,YAAA,EAA4C;AACtG,EAAA,MAAM,MAAM,GAAA,CAAI,IAAA,EAAM,CAAC,WAAA,EAAa,MAAM,CAAC,CAAA,IAAK,0CAAA;AAChD,EAAA,MAAM,MAAA,GAAS,IAAI,IAAA,EAAM,CAAC,aAAa,cAAA,EAAgB,MAAM,CAAC,CAAA,IAAK,MAAA;AACnE,EAAA,MAAM,SAAA,GAAY,IAAI,IAAA,EAAM,CAAC,UAAU,OAAA,EAAS,mBAAmB,CAAC,CAAA,IAAK,MAAA;AACzE,EAAA,OAAO;AAAA,IACL,aAAA,EAAe,cAAA;AAAA,IACf,YAAA,EAAc,OAAA;AAAA,IACd,YAAA;AAAA,IACA,GAAA,EAAK,EAAE,GAAA,EAAK,QAAA,EAAU,IAAI,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,EAAG,MAAA,EAAO;AAAA,IAC/C,YAAY,SAAA,GAAY,EAAE,WAAW,oBAAA,CAAqB,SAAS,GAAE,GAAI,MAAA;AAAA,IACzE,aAAa,KAAA,CAAM,WAAA;AAAA,IACnB,KAAA,EAAO,YAAY,KAAK;AAAA,GAC1B;AACF;AAOO,SAAS,YAAY,KAAA,EAAyB;AACnD,EAAA,OAAO;AAAA,IACL,GAAG,KAAA;AAAA,IACH,KAAA,EAAO,KAAA,CAAM,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM;AAC5B,MAAA,MAAM,YAAY,CAAA,CAAE,SAAA,GAAY,cAAc,CAAA,CAAE,SAAS,IAAI,CAAA,CAAE,SAAA;AAC/D,MAAA,MAAM,MAAM,CAAA,CAAE,GAAA,GAAM,cAAc,CAAA,CAAE,GAAG,IAAI,CAAA,CAAE,GAAA;AAC7C,MAAA,OAAO,SAAA,KAAc,CAAA,CAAE,SAAA,IAAa,GAAA,KAAQ,CAAA,CAAE,GAAA,GAAM,EAAE,GAAG,CAAA,EAAG,SAAA,EAAW,GAAA,EAAI,GAAI,CAAA;AAAA,IACjF,CAAC;AAAA,GACH;AACF;AAEA,SAAS,GAAA,CAAI,MAAc,IAAA,EAA+B;AACxD,EAAA,IAAI;AACF,IAAA,OAAO,YAAA,CAAa,KAAA,EAAO,IAAA,EAAM,EAAE,GAAA,EAAK,IAAA,EAAM,QAAA,EAAU,MAAA,EAAQ,CAAA,CAAE,IAAA,EAAK,IAAK,IAAA;AAAA,EAC9E,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF","file":"index.js","sourcesContent":["import { execFileSync } from 'node:child_process';\nimport { redactSecrets, redactUrlCredentials } from '../core-open/utils/redact.js';\nimport type { VgGraph } from '../schema.js';\n\n/**\n * The deferred, decoupled push envelope (VG-PACKAGE-AND-SCHEMA §7). In the open\n * CLI `vg push` is **specified but not built**: it assembles and redacts the\n * envelope and prints a notice, but performs **no network upload**. Nothing in\n * the free path depends on it. Drift-over-time/governance is the separate\n * commercial product.\n */\n\nexport interface GraphUploadEnvelope {\n schemaVersion: 'vg-graph/1.0';\n artifactType: 'graph';\n scanIngestId?: string;\n vcs: { sha: string; shortSha: string; branch: string };\n repository?: { name?: string; remoteUrl?: string };\n generatedAt: string;\n graph: VgGraph;\n}\n\nexport function buildEnvelope(root: string, graph: VgGraph, scanIngestId?: string): GraphUploadEnvelope {\n const sha = git(root, ['rev-parse', 'HEAD']) ?? '0000000000000000000000000000000000000000';\n const branch = git(root, ['rev-parse', '--abbrev-ref', 'HEAD']) ?? 'HEAD';\n const remoteUrl = git(root, ['config', '--get', 'remote.origin.url']) ?? undefined;\n return {\n schemaVersion: 'vg-graph/1.0',\n artifactType: 'graph',\n scanIngestId,\n vcs: { sha, shortSha: sha.slice(0, 12), branch },\n repository: remoteUrl ? { remoteUrl: redactUrlCredentials(remoteUrl) } : undefined,\n generatedAt: graph.generatedAt,\n graph: redactGraph(graph),\n };\n}\n\n/**\n * Redaction pass (GUARDRAILS §1: redact before storage). The graph is structure,\n * not content, but we defensively scrub any signature/name that matches a\n * credential-shaped pattern, and strip credentials from the remote URL.\n */\nexport function redactGraph(graph: VgGraph): VgGraph {\n return {\n ...graph,\n nodes: graph.nodes.map((n) => {\n const signature = n.signature ? redactSecrets(n.signature) : n.signature;\n const doc = n.doc ? redactSecrets(n.doc) : n.doc;\n return signature !== n.signature || doc !== n.doc ? { ...n, signature, doc } : n;\n }),\n };\n}\n\nfunction git(root: string, args: string[]): string | null {\n try {\n return execFileSync('git', args, { cwd: root, encoding: 'utf8' }).trim() || null;\n } catch {\n return null;\n }\n}\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { F as FileParse } from './types-C6ZyQpa9.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* tinypool worker entry. Receives a chunk of files, reads and parses each, and
|
|
5
|
+
* returns the FileParse table. Each worker owns its own web-tree-sitter instance
|
|
6
|
+
* (initialized lazily inside parseSource/grammars). Results are plain data, so
|
|
7
|
+
* they serialize cleanly back to the main thread.
|
|
8
|
+
*
|
|
9
|
+
* The `--grammars <dir>` override is passed in the payload (env vars don't cross
|
|
10
|
+
* into worker threads in a controlled way) and applied per worker before parsing.
|
|
11
|
+
*/
|
|
12
|
+
interface ParseTask {
|
|
13
|
+
rel: string;
|
|
14
|
+
abs: string;
|
|
15
|
+
lang: string;
|
|
16
|
+
}
|
|
17
|
+
interface ParsePayload {
|
|
18
|
+
tasks: ParseTask[];
|
|
19
|
+
grammarsDir?: string;
|
|
20
|
+
}
|
|
21
|
+
declare function run(payload: ParsePayload): Promise<FileParse[]>;
|
|
22
|
+
|
|
23
|
+
export { type ParsePayload, type ParseTask, run as default };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { setGrammarsOverride, parseSource } from './chunk-X5YT263H.js';
|
|
2
|
+
import './chunk-RXP66R2E.js';
|
|
3
|
+
import * as fs from 'fs';
|
|
4
|
+
|
|
5
|
+
async function run(payload) {
|
|
6
|
+
setGrammarsOverride(payload.grammarsDir);
|
|
7
|
+
const out = [];
|
|
8
|
+
for (const task of payload.tasks) {
|
|
9
|
+
try {
|
|
10
|
+
const source = fs.readFileSync(task.abs, "utf8");
|
|
11
|
+
out.push(await parseSource(task.rel, task.lang, source));
|
|
12
|
+
} catch (err) {
|
|
13
|
+
out.push({
|
|
14
|
+
rel: task.rel,
|
|
15
|
+
lang: task.lang,
|
|
16
|
+
hash: "",
|
|
17
|
+
bytes: 0,
|
|
18
|
+
defs: [],
|
|
19
|
+
calls: [],
|
|
20
|
+
imports: [],
|
|
21
|
+
heritage: [],
|
|
22
|
+
guards: [],
|
|
23
|
+
warnings: [`parse failed: ${err.message}`]
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return out;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { run as default };
|
|
31
|
+
//# sourceMappingURL=parse-worker.js.map
|
|
32
|
+
//# sourceMappingURL=parse-worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/engine/parse-worker.ts"],"names":[],"mappings":";;;;AA0BA,eAAO,IAA2B,OAAA,EAA6C;AAC7E,EAAA,mBAAA,CAAoB,QAAQ,WAAW,CAAA;AACvC,EAAA,MAAM,MAAmB,EAAC;AAC1B,EAAA,KAAA,MAAW,IAAA,IAAQ,QAAQ,KAAA,EAAO;AAChC,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAY,EAAA,CAAA,YAAA,CAAa,IAAA,CAAK,GAAA,EAAK,MAAM,CAAA;AAC/C,MAAA,GAAA,CAAI,IAAA,CAAK,MAAM,WAAA,CAAY,IAAA,CAAK,KAAK,IAAA,CAAK,IAAA,EAAM,MAAM,CAAC,CAAA;AAAA,IACzD,SAAS,GAAA,EAAK;AACZ,MAAA,GAAA,CAAI,IAAA,CAAK;AAAA,QACP,KAAK,IAAA,CAAK,GAAA;AAAA,QACV,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,IAAA,EAAM,EAAA;AAAA,QACN,KAAA,EAAO,CAAA;AAAA,QACP,MAAM,EAAC;AAAA,QACP,OAAO,EAAC;AAAA,QACR,SAAS,EAAC;AAAA,QACV,UAAU,EAAC;AAAA,QACX,QAAQ,EAAC;AAAA,QACT,QAAA,EAAU,CAAC,CAAA,cAAA,EAAkB,GAAA,CAAc,OAAO,CAAA,CAAE;AAAA,OACrD,CAAA;AAAA,IACH;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT","file":"parse-worker.js","sourcesContent":["import * as fs from 'node:fs';\nimport { parseSource } from './parse.js';\nimport { setGrammarsOverride } from './grammars.js';\nimport type { FileParse } from './types.js';\n\n/**\n * tinypool worker entry. Receives a chunk of files, reads and parses each, and\n * returns the FileParse table. Each worker owns its own web-tree-sitter instance\n * (initialized lazily inside parseSource/grammars). Results are plain data, so\n * they serialize cleanly back to the main thread.\n *\n * The `--grammars <dir>` override is passed in the payload (env vars don't cross\n * into worker threads in a controlled way) and applied per worker before parsing.\n */\n\nexport interface ParseTask {\n rel: string;\n abs: string;\n lang: string;\n}\n\nexport interface ParsePayload {\n tasks: ParseTask[];\n grammarsDir?: string;\n}\n\nexport default async function run(payload: ParsePayload): Promise<FileParse[]> {\n setGrammarsOverride(payload.grammarsDir);\n const out: FileParse[] = [];\n for (const task of payload.tasks) {\n try {\n const source = fs.readFileSync(task.abs, 'utf8');\n out.push(await parseSource(task.rel, task.lang, source));\n } catch (err) {\n out.push({\n rel: task.rel,\n lang: task.lang,\n hash: '',\n bytes: 0,\n defs: [],\n calls: [],\n imports: [],\n heritage: [],\n guards: [],\n warnings: [`parse failed: ${(err as Error).message}`],\n });\n }\n }\n return out;\n}\n"]}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `vg-graph/1.0` on-disk schema.
|
|
3
|
+
*
|
|
4
|
+
* This is vg's own open schema (VG-PACKAGE-AND-SCHEMA.md §4) — informed by good
|
|
5
|
+
* ideas (content-hashed ids, epistemic typing of facts) but standalone and
|
|
6
|
+
* self-contained. Every collection is deterministically serialized
|
|
7
|
+
* (sorted keys, stable element order). These TypeScript shapes are normative.
|
|
8
|
+
*/
|
|
9
|
+
declare const SCHEMA_VERSION: "vg-graph/1.0";
|
|
10
|
+
type ResolverKind = 'scip' | 'stackgraph' | 'tsc' | 'heuristic';
|
|
11
|
+
interface Provenance {
|
|
12
|
+
tool: 'vg';
|
|
13
|
+
version: string;
|
|
14
|
+
grammars: Record<string, string>;
|
|
15
|
+
resolver: ResolverKind[];
|
|
16
|
+
deep: boolean;
|
|
17
|
+
semanticModel?: string;
|
|
18
|
+
corpusHash: string;
|
|
19
|
+
}
|
|
20
|
+
interface GraphMeta {
|
|
21
|
+
root: string;
|
|
22
|
+
languages: string[];
|
|
23
|
+
counts: {
|
|
24
|
+
nodes: number;
|
|
25
|
+
edges: number;
|
|
26
|
+
areas: number;
|
|
27
|
+
tests: number;
|
|
28
|
+
untested: number;
|
|
29
|
+
};
|
|
30
|
+
cluster: 'leiden' | 'louvain' | 'none';
|
|
31
|
+
edgeKinds: EdgeKind[];
|
|
32
|
+
}
|
|
33
|
+
type NodeKind = 'file' | 'module' | 'package' | 'class' | 'interface' | 'function' | 'method' | 'property' | 'test' | 'route' | 'component' | 'external';
|
|
34
|
+
interface Span {
|
|
35
|
+
start: number;
|
|
36
|
+
end: number;
|
|
37
|
+
}
|
|
38
|
+
interface Centrality {
|
|
39
|
+
degree: number;
|
|
40
|
+
pagerank: number;
|
|
41
|
+
betweenness: number;
|
|
42
|
+
eigenvector: number;
|
|
43
|
+
}
|
|
44
|
+
interface GraphNode {
|
|
45
|
+
id: string;
|
|
46
|
+
kind: NodeKind;
|
|
47
|
+
name: string;
|
|
48
|
+
qualifiedName: string;
|
|
49
|
+
file: string;
|
|
50
|
+
span: Span;
|
|
51
|
+
lang: string;
|
|
52
|
+
visibility?: 'public' | 'private' | 'protected' | 'internal';
|
|
53
|
+
signature?: string;
|
|
54
|
+
doc?: string;
|
|
55
|
+
importance: number;
|
|
56
|
+
centrality: Centrality;
|
|
57
|
+
area: number;
|
|
58
|
+
isHub: boolean;
|
|
59
|
+
tested: boolean | null;
|
|
60
|
+
coverage?: number;
|
|
61
|
+
changeCoupling?: string[];
|
|
62
|
+
}
|
|
63
|
+
type EdgeKind = 'call' | 'import' | 'contains' | 'extends' | 'implements' | 'references' | 'test' | 'coverage';
|
|
64
|
+
interface GraphEdge {
|
|
65
|
+
id: string;
|
|
66
|
+
kind: EdgeKind;
|
|
67
|
+
src: string;
|
|
68
|
+
dst: string;
|
|
69
|
+
resolution: ResolverKind;
|
|
70
|
+
confidence: number;
|
|
71
|
+
surprise?: number;
|
|
72
|
+
count?: number;
|
|
73
|
+
}
|
|
74
|
+
interface Area {
|
|
75
|
+
id: number;
|
|
76
|
+
label: string;
|
|
77
|
+
size: number;
|
|
78
|
+
members: string[];
|
|
79
|
+
cohesion: number;
|
|
80
|
+
externalEdges: number;
|
|
81
|
+
}
|
|
82
|
+
type FactKind = 'contract' | 'invariant' | 'characterization';
|
|
83
|
+
type DerivedBy = 'declared' | 'static';
|
|
84
|
+
type FactConfidence = 'Observed' | 'Derived';
|
|
85
|
+
interface Fact {
|
|
86
|
+
id: string;
|
|
87
|
+
kind: FactKind;
|
|
88
|
+
subjectIds: string[];
|
|
89
|
+
predicate: unknown;
|
|
90
|
+
derivedBy: DerivedBy;
|
|
91
|
+
confidence: FactConfidence;
|
|
92
|
+
evidence: {
|
|
93
|
+
file: string;
|
|
94
|
+
span: Span;
|
|
95
|
+
}[];
|
|
96
|
+
}
|
|
97
|
+
type GroundingKind = 'should_follow' | 'smells_like' | 'relevant_to';
|
|
98
|
+
interface GroundingEdge {
|
|
99
|
+
src: string;
|
|
100
|
+
packEntryId: string;
|
|
101
|
+
kind: GroundingKind;
|
|
102
|
+
confidence: number;
|
|
103
|
+
rationale: 'recommended' | 'conjectured';
|
|
104
|
+
citation: {
|
|
105
|
+
title: string;
|
|
106
|
+
url: string;
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
interface VgGraph {
|
|
110
|
+
schemaVersion: typeof SCHEMA_VERSION;
|
|
111
|
+
generatedAt: string;
|
|
112
|
+
provenance: Provenance;
|
|
113
|
+
meta: GraphMeta;
|
|
114
|
+
nodes: GraphNode[];
|
|
115
|
+
edges: GraphEdge[];
|
|
116
|
+
areas: Area[];
|
|
117
|
+
facts?: Fact[];
|
|
118
|
+
grounding?: GroundingEdge[];
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** A definition extracted from one file (pre-resolution, pre-id). */
|
|
122
|
+
interface RawDef {
|
|
123
|
+
kind: NodeKind;
|
|
124
|
+
name: string;
|
|
125
|
+
qualifiedName: string;
|
|
126
|
+
startLine: number;
|
|
127
|
+
endLine: number;
|
|
128
|
+
startByte: number;
|
|
129
|
+
endByte: number;
|
|
130
|
+
signature?: string;
|
|
131
|
+
doc?: string;
|
|
132
|
+
visibility?: 'public' | 'private' | 'protected' | 'internal';
|
|
133
|
+
}
|
|
134
|
+
interface RawCall {
|
|
135
|
+
callee: string;
|
|
136
|
+
byte: number;
|
|
137
|
+
line: number;
|
|
138
|
+
/** True when the call site had a receiver/qualifier (`obj.foo()`, `pkg::foo()`); the receiver itself is not captured. */
|
|
139
|
+
qualified?: boolean;
|
|
140
|
+
}
|
|
141
|
+
interface RawImport {
|
|
142
|
+
source: string;
|
|
143
|
+
}
|
|
144
|
+
interface RawHeritage {
|
|
145
|
+
superName: string;
|
|
146
|
+
byte: number;
|
|
147
|
+
kind: 'extends' | 'implements';
|
|
148
|
+
}
|
|
149
|
+
interface RawGuard {
|
|
150
|
+
expr: string;
|
|
151
|
+
line: number;
|
|
152
|
+
}
|
|
153
|
+
/** The full result of parsing a single file. */
|
|
154
|
+
interface FileParse {
|
|
155
|
+
rel: string;
|
|
156
|
+
lang: string;
|
|
157
|
+
hash: string;
|
|
158
|
+
bytes: number;
|
|
159
|
+
defs: RawDef[];
|
|
160
|
+
calls: RawCall[];
|
|
161
|
+
imports: RawImport[];
|
|
162
|
+
heritage: RawHeritage[];
|
|
163
|
+
guards: RawGuard[];
|
|
164
|
+
/** Non-fatal issues (e.g. a query that failed to compile for this grammar). */
|
|
165
|
+
warnings?: string[];
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export { type Area as A, type Centrality as C, type DerivedBy as D, type EdgeKind as E, type FileParse as F, type GraphNode as G, type NodeKind as N, type Provenance as P, type ResolverKind as R, SCHEMA_VERSION as S, type VgGraph as V, type GraphEdge as a, type Fact as b, type GroundingKind as c, type GroundingEdge as d, type FactConfidence as e, type FactKind as f, type GraphMeta as g, type Span as h };
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,9 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibgrate/cli",
|
|
3
|
-
"version": "2026.
|
|
4
|
-
"description": "CLI for
|
|
3
|
+
"version": "2026.703.1",
|
|
4
|
+
"description": "vg — local codebase intelligence CLI + MCP server for AI coding agents: deterministic code graph, drift reporting, and version-correct library docs (Apache-2.0)",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"packageManager": "pnpm@9.0.0",
|
|
8
|
+
"author": "Vibgrate",
|
|
9
|
+
"homepage": "https://vibgrate.com",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/vibgrate/cli.git"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/vibgrate/cli/issues"
|
|
16
|
+
},
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public"
|
|
19
|
+
},
|
|
6
20
|
"bin": {
|
|
21
|
+
"vg": "dist/cli.js",
|
|
7
22
|
"vibgrate": "dist/cli.js"
|
|
8
23
|
},
|
|
9
24
|
"main": "./dist/index.js",
|
|
@@ -16,52 +31,72 @@
|
|
|
16
31
|
},
|
|
17
32
|
"files": [
|
|
18
33
|
"dist",
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
34
|
+
"grammars",
|
|
35
|
+
"skills",
|
|
36
|
+
"scripts/postinstall.mjs",
|
|
37
|
+
"LICENSE",
|
|
38
|
+
"NOTICE",
|
|
39
|
+
"README.md",
|
|
40
|
+
"DOCS.md"
|
|
22
41
|
],
|
|
23
42
|
"scripts": {
|
|
24
|
-
"build": "pnpm run
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
43
|
+
"build": "pnpm run bundle:grammars && tsup",
|
|
44
|
+
"bundle:grammars": "node scripts/bundle-grammars.mjs",
|
|
45
|
+
"stamp:pins": "node scripts/stamp-release-pins.mjs",
|
|
46
|
+
"check:pins": "node scripts/stamp-release-pins.mjs --check",
|
|
47
|
+
"demo:svg": "node scripts/gen-demo-svg.mjs",
|
|
48
|
+
"postinstall": "node scripts/postinstall.mjs",
|
|
28
49
|
"dev": "tsx src/cli.ts",
|
|
29
50
|
"lint": "eslint src",
|
|
30
51
|
"typecheck": "tsc --noEmit",
|
|
31
|
-
"test": "vitest run"
|
|
32
|
-
"test:solutions": "tsx test-solutions/test-runner.ts",
|
|
33
|
-
"test:hcs": "tsx test-hcs/test-runner.ts",
|
|
34
|
-
"test:fixtures": "tsx test-fixtures/run-tests.ts test",
|
|
35
|
-
"test:all": "vitest run && pnpm test:solutions && pnpm test:hcs && pnpm test:fixtures"
|
|
52
|
+
"test": "vitest run"
|
|
36
53
|
},
|
|
37
54
|
"keywords": [
|
|
38
|
-
"
|
|
55
|
+
"code-graph",
|
|
56
|
+
"codebase-intelligence",
|
|
57
|
+
"ast",
|
|
58
|
+
"tree-sitter",
|
|
59
|
+
"mcp",
|
|
60
|
+
"ai-agents",
|
|
39
61
|
"drift",
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"dotnet",
|
|
44
|
-
"sarif"
|
|
62
|
+
"deterministic",
|
|
63
|
+
"impact-analysis",
|
|
64
|
+
"cli"
|
|
45
65
|
],
|
|
46
|
-
"
|
|
47
|
-
|
|
48
|
-
|
|
66
|
+
"dependencies": {
|
|
67
|
+
"@modelcontextprotocol/sdk": "^1.19.0",
|
|
68
|
+
"@noble/hashes": "^2.2.0",
|
|
69
|
+
"chalk": "^5.3.0",
|
|
70
|
+
"commander": "^15.0.0",
|
|
71
|
+
"fast-xml-parser": "^5.0.0",
|
|
72
|
+
"gpt-tokenizer": "^3.0.0",
|
|
73
|
+
"graphology": "^0.26.0",
|
|
74
|
+
"graphology-communities-louvain": "^2.0.2",
|
|
75
|
+
"graphology-metrics": "^2.4.0",
|
|
76
|
+
"graphology-shortest-path": "^2.1.0",
|
|
77
|
+
"graphology-traversal": "^0.3.1",
|
|
78
|
+
"ignore": "^7.0.0",
|
|
79
|
+
"semver": "^7.8.5",
|
|
80
|
+
"smol-toml": "^1.7.0",
|
|
81
|
+
"tinypool": "^2.1.0",
|
|
82
|
+
"tree-sitter-wasms": "^0.1.13",
|
|
83
|
+
"typescript": "^6.0.0",
|
|
84
|
+
"web-tree-sitter": "0.25.10",
|
|
85
|
+
"yaml": "^2.6.1"
|
|
86
|
+
},
|
|
87
|
+
"optionalDependencies": {
|
|
88
|
+
"fastembed": "^2.1.0"
|
|
89
|
+
},
|
|
49
90
|
"devDependencies": {
|
|
50
91
|
"@types/node": "^26.1.0",
|
|
51
92
|
"@types/semver": "^7.5.0",
|
|
93
|
+
"@typescript-eslint/eslint-plugin": "^8.61.0",
|
|
94
|
+
"@typescript-eslint/parser": "^8.62.1",
|
|
52
95
|
"eslint": "^10.6.0",
|
|
53
|
-
"
|
|
54
|
-
"semver": "^7.8.5",
|
|
96
|
+
"graphology-types": "^0.24.8",
|
|
55
97
|
"tsup": "^8.0.0",
|
|
56
98
|
"tsx": "^4.22.4",
|
|
57
|
-
"vitest": "^
|
|
58
|
-
},
|
|
59
|
-
"dependencies": {
|
|
60
|
-
"chalk": "^5.3.0",
|
|
61
|
-
"commander": "^15.0.0",
|
|
62
|
-
"typescript": "^5.4.0",
|
|
63
|
-
"zod": "^4.4.3",
|
|
64
|
-
"yaml": "^2.6.1"
|
|
99
|
+
"vitest": "^4.0.0"
|
|
65
100
|
},
|
|
66
101
|
"engines": {
|
|
67
102
|
"node": ">=20.0.0"
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Checks whether `vg` is already occupied by another tool on PATH.
|
|
3
|
+
// If it is, prints a one-time notice that `vibgrate` is an identical alias.
|
|
4
|
+
// Exits 0 regardless — a conflict is not an install failure.
|
|
5
|
+
|
|
6
|
+
import { execFileSync } from 'node:child_process';
|
|
7
|
+
import { realpathSync } from 'node:fs';
|
|
8
|
+
import { fileURLToPath } from 'node:url';
|
|
9
|
+
import * as path from 'node:path';
|
|
10
|
+
|
|
11
|
+
const isWindows = process.platform === 'win32';
|
|
12
|
+
|
|
13
|
+
// Resolve the directory this package installed its own bin links into.
|
|
14
|
+
// __filename → scripts/postinstall.mjs → ../../dist/cli.js (the actual binary)
|
|
15
|
+
const pkgRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
16
|
+
const ownBin = path.join(pkgRoot, 'dist', 'cli.js');
|
|
17
|
+
|
|
18
|
+
function which(cmd) {
|
|
19
|
+
try {
|
|
20
|
+
const out = execFileSync(
|
|
21
|
+
isWindows ? 'where' : 'which',
|
|
22
|
+
[cmd],
|
|
23
|
+
{ encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] },
|
|
24
|
+
).trim().split(/\r?\n/)[0];
|
|
25
|
+
return out || null;
|
|
26
|
+
} catch {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function realpath(p) {
|
|
32
|
+
try { return realpathSync(p); } catch { return p; }
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const vgOnPath = which('vg');
|
|
36
|
+
|
|
37
|
+
if (!vgOnPath) {
|
|
38
|
+
// `vg` not on PATH yet (e.g. local install, PATH not updated) — nothing to warn about.
|
|
39
|
+
process.exit(0);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Resolve symlinks so we compare actual files, not wrapper scripts.
|
|
43
|
+
const resolvedVg = realpath(vgOnPath);
|
|
44
|
+
const resolvedOwn = realpath(ownBin);
|
|
45
|
+
|
|
46
|
+
if (resolvedVg === resolvedOwn) {
|
|
47
|
+
// Our binary is the one that wins — no conflict.
|
|
48
|
+
process.exit(0);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Not a symlink to us — but pnpm/bun/yarn (and every Windows install) generate
|
|
52
|
+
// script *shims*, not symlinks. Treat a shim as ours when its resolved path
|
|
53
|
+
// lives in our package directory or its first bytes reference the package;
|
|
54
|
+
// otherwise every Windows/pnpm user gets a false "vg is taken" warning.
|
|
55
|
+
if (/[\\/]@vibgrate[\\/]cli[\\/]/.test(resolvedVg)) process.exit(0);
|
|
56
|
+
try {
|
|
57
|
+
const { readFileSync } = await import('node:fs');
|
|
58
|
+
const head = readFileSync(resolvedVg, 'utf8').slice(0, 2048);
|
|
59
|
+
if (head.includes('@vibgrate/cli')) process.exit(0);
|
|
60
|
+
} catch {
|
|
61
|
+
// Unreadable → cannot verify; keep the (possibly false) warning below rather
|
|
62
|
+
// than staying silent about a real conflict.
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Something else owns `vg` on this machine.
|
|
66
|
+
console.log('');
|
|
67
|
+
console.log(
|
|
68
|
+
'\x1b[33m⚠\x1b[0m \x1b[1m@vibgrate/cli:\x1b[0m \x1b[33mThe `vg` command is already used by another tool on this system.\x1b[0m',
|
|
69
|
+
);
|
|
70
|
+
console.log(
|
|
71
|
+
' Use \x1b[1mvibgrate\x1b[0m instead — it is installed alongside `vg` and is identical in every way.',
|
|
72
|
+
);
|
|
73
|
+
console.log('');
|
|
74
|
+
console.log(' Examples:');
|
|
75
|
+
console.log(' vibgrate scan');
|
|
76
|
+
console.log(' vibgrate build');
|
|
77
|
+
console.log(' vibgrate serve');
|
|
78
|
+
console.log('');
|
|
79
|
+
console.log(
|
|
80
|
+
' See https://vibgrate.com/cli for full documentation.',
|
|
81
|
+
);
|
|
82
|
+
console.log('');
|
|
83
|
+
|
|
84
|
+
process.exit(0);
|
package/skills/README.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Vibgrate CLI skills for AI agents
|
|
2
|
+
|
|
3
|
+
A **skill** is a ready-made instruction file (plus local MCP wiring) that teaches
|
|
4
|
+
an AI coding assistant to use the `vg` code graph instead of grepping or reading
|
|
5
|
+
many files — cheaper, more relevant context.
|
|
6
|
+
|
|
7
|
+
You don't write these by hand. One command installs them:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
vg install --all # every supported assistant
|
|
11
|
+
vg install claude # or one at a time
|
|
12
|
+
vg install --list # show the support matrix
|
|
13
|
+
vg uninstall claude # remove (add --purge to delete the skill file)
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Each install is idempotent and repo-local (team-shareable). It writes:
|
|
17
|
+
|
|
18
|
+
1. A **skill file** (`SKILL.md`) — see [`vg/SKILL.md`](./vg/SKILL.md) for the
|
|
19
|
+
canonical content.
|
|
20
|
+
2. A **local MCP server** registration (`vg serve`) where the assistant supports
|
|
21
|
+
it — read-only, auto-approvable tools.
|
|
22
|
+
3. An **advisory nudge** in the assistant's instructions file (opt-out, never
|
|
23
|
+
"mandatory").
|
|
24
|
+
|
|
25
|
+
## Supported assistants
|
|
26
|
+
|
|
27
|
+
| id | Assistant | Skill | MCP | Nudge |
|
|
28
|
+
| --- | --- | :---: | :---: | :---: |
|
|
29
|
+
| `claude` | Claude Code | ✓ | ✓ | ✓ |
|
|
30
|
+
| `cursor` | Cursor | — | ✓ | ✓ |
|
|
31
|
+
| `windsurf` | Windsurf | — | ✓ | ✓ |
|
|
32
|
+
| `vscode` | VS Code (Copilot Chat) | — | ✓ | ✓ |
|
|
33
|
+
| `codex` | Codex | ✓ | — | ✓ |
|
|
34
|
+
| `gemini` | Gemini CLI | ✓ | — | ✓ |
|
|
35
|
+
| `opencode` | OpenCode | ✓ | — | ✓ |
|
|
36
|
+
| `kilo` | Kilo Code | ✓ | — | ✓ |
|
|
37
|
+
| `aider` | Aider | ✓ | — | ✓ |
|
|
38
|
+
| `factory` | Factory Droid | ✓ | — | ✓ |
|
|
39
|
+
| `trae` | Trae | ✓ | — | ✓ |
|
|
40
|
+
| `kiro` | Kiro | ✓ | — | ✓ |
|
|
41
|
+
| `amp` | Amp | ✓ | — | ✓ |
|
|
42
|
+
| `kimi` | Kimi Code | ✓ | — | ✓ |
|
|
43
|
+
| `codebuddy` | CodeBuddy | ✓ | — | ✓ |
|
|
44
|
+
| `copilot-cli` | GitHub Copilot CLI | ✓ | — | ✓ |
|
|
45
|
+
| `pi` | Pi | ✓ | — | ✓ |
|
|
46
|
+
| `devin` | Devin CLI | ✓ | — | ✓ |
|
|
47
|
+
| `hermes` | Hermes | ✓ | — | ✓ |
|
|
48
|
+
| `openclaw` | OpenClaw | ✓ | — | ✓ |
|
|
49
|
+
| `agents` | Agent-Skills (generic) | ✓ | — | ✓ |
|
|
50
|
+
|
|
51
|
+
MCP registration for the skill-only assistants is added as their formats
|
|
52
|
+
stabilise; the skill + nudge work today. Run `vg install --list` for the live
|
|
53
|
+
matrix.
|
|
54
|
+
|
|
55
|
+
The canonical skill content is generated from
|
|
56
|
+
[`src/install/content.ts`](../src/install/content.ts) so the published file and
|
|
57
|
+
the installed file never drift. See also the
|
|
58
|
+
[skills page](https://vibgrate.com/skills).
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vg
|
|
3
|
+
description: Query the local code graph (vg) for structure, impact, and navigation instead of grepping/reading many files.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# vg — the code map
|
|
7
|
+
|
|
8
|
+
This repo has a deterministic code graph built by `vg`. Prefer it over reading or
|
|
9
|
+
grepping many files — it is smaller, more relevant context, and free.
|
|
10
|
+
|
|
11
|
+
## When to use it
|
|
12
|
+
|
|
13
|
+
- **Understand code:** `vg "<question>"` returns a budget-bounded, fact-annotated
|
|
14
|
+
context block. Start here instead of opening files blindly.
|
|
15
|
+
- **Find a symbol:** `vg show <name>` — what it is, what it calls, what calls it.
|
|
16
|
+
- **Before changing something:** `vg impact <name>` — what breaks if you change it.
|
|
17
|
+
- **Navigate:** `vg path <A> <B>`, `vg tree <name>`, `vg hubs`, `vg areas`.
|
|
18
|
+
|
|
19
|
+
## Dependencies & library docs
|
|
20
|
+
|
|
21
|
+
- **Upgrade drift:** `vg drift` lists what is outdated across dependencies
|
|
22
|
+
(offline; `--online` for currency). `vg scan` scores upgrade drift and
|
|
23
|
+
`vg report` renders it (text | json | sarif | md).
|
|
24
|
+
- **Version-correct docs:** `vg lib <name>` returns drift-annotated, version-
|
|
25
|
+
specific usage docs for a library — inject these instead of guessing an API.
|
|
26
|
+
|
|
27
|
+
## Via MCP
|
|
28
|
+
|
|
29
|
+
If the `vg` MCP server is registered, call its read-only tools directly:
|
|
30
|
+
`query_graph`, `get_node`, `impact_of`, `find_path`, `list_hubs`, `list_areas`,
|
|
31
|
+
`get_graph_summary`. They are side-effect-free and auto-approvable.
|
|
32
|
+
|
|
33
|
+
## Keep it fresh
|
|
34
|
+
|
|
35
|
+
Run `vg` after pulling or making structural changes. The map lives at
|
|
36
|
+
`.vibgrate/graph.json` and is deterministic (byte-identical across machines).
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
> This is the canonical reference copy. `vg install <assistant>` writes this skill
|
|
41
|
+
> into each assistant's expected location and registers the local MCP server. The
|
|
42
|
+
> source of truth is `src/install/content.ts`.
|