@reposkein/mcp 0.1.0

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.
Files changed (76) hide show
  1. package/dist/SKILL.md +67 -0
  2. package/dist/cli/init.d.ts +9 -0
  3. package/dist/cli/init.js +54 -0
  4. package/dist/cli/init.js.map +1 -0
  5. package/dist/guard/caps.d.ts +7 -0
  6. package/dist/guard/caps.js +22 -0
  7. package/dist/guard/caps.js.map +1 -0
  8. package/dist/guard/readonly.d.ts +4 -0
  9. package/dist/guard/readonly.js +91 -0
  10. package/dist/guard/readonly.js.map +1 -0
  11. package/dist/guard/summaryValidation.d.ts +18 -0
  12. package/dist/guard/summaryValidation.js +44 -0
  13. package/dist/guard/summaryValidation.js.map +1 -0
  14. package/dist/index.d.ts +1 -0
  15. package/dist/index.js +143 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/indexer/fetchBinary.d.ts +24 -0
  18. package/dist/indexer/fetchBinary.js +109 -0
  19. package/dist/indexer/fetchBinary.js.map +1 -0
  20. package/dist/indexer/runIndexer.d.ts +26 -0
  21. package/dist/indexer/runIndexer.js +42 -0
  22. package/dist/indexer/runIndexer.js.map +1 -0
  23. package/dist/profile/assemble.d.ts +5 -0
  24. package/dist/profile/assemble.js +90 -0
  25. package/dist/profile/assemble.js.map +1 -0
  26. package/dist/profile/inline.d.ts +4 -0
  27. package/dist/profile/inline.js +32 -0
  28. package/dist/profile/inline.js.map +1 -0
  29. package/dist/profile/resolve.d.ts +10 -0
  30. package/dist/profile/resolve.js +24 -0
  31. package/dist/profile/resolve.js.map +1 -0
  32. package/dist/profile/summary.d.ts +13 -0
  33. package/dist/profile/summary.js +12 -0
  34. package/dist/profile/summary.js.map +1 -0
  35. package/dist/profile/types.d.ts +55 -0
  36. package/dist/profile/types.js +2 -0
  37. package/dist/profile/types.js.map +1 -0
  38. package/dist/store/GraphStore.d.ts +62 -0
  39. package/dist/store/GraphStore.js +9 -0
  40. package/dist/store/GraphStore.js.map +1 -0
  41. package/dist/store/JsonlGraphStore.d.ts +37 -0
  42. package/dist/store/JsonlGraphStore.js +275 -0
  43. package/dist/store/JsonlGraphStore.js.map +1 -0
  44. package/dist/store/Neo4jGraphStore.d.ts +27 -0
  45. package/dist/store/Neo4jGraphStore.js +148 -0
  46. package/dist/store/Neo4jGraphStore.js.map +1 -0
  47. package/dist/store/UnconfiguredStore.d.ts +16 -0
  48. package/dist/store/UnconfiguredStore.js +36 -0
  49. package/dist/store/UnconfiguredStore.js.map +1 -0
  50. package/dist/store/federation.d.ts +9 -0
  51. package/dist/store/federation.js +29 -0
  52. package/dist/store/federation.js.map +1 -0
  53. package/dist/store/jsonlGraph.d.ts +43 -0
  54. package/dist/store/jsonlGraph.js +176 -0
  55. package/dist/store/jsonlGraph.js.map +1 -0
  56. package/dist/store/repoId.d.ts +3 -0
  57. package/dist/store/repoId.js +18 -0
  58. package/dist/store/repoId.js.map +1 -0
  59. package/dist/store/sidecar.d.ts +16 -0
  60. package/dist/store/sidecar.js +65 -0
  61. package/dist/store/sidecar.js.map +1 -0
  62. package/dist/tools/getContextProfile.d.ts +10 -0
  63. package/dist/tools/getContextProfile.js +44 -0
  64. package/dist/tools/getContextProfile.js.map +1 -0
  65. package/dist/tools/indexerTools.d.ts +27 -0
  66. package/dist/tools/indexerTools.js +89 -0
  67. package/dist/tools/indexerTools.js.map +1 -0
  68. package/dist/tools/readCypher.d.ts +16 -0
  69. package/dist/tools/readCypher.js +40 -0
  70. package/dist/tools/readCypher.js.map +1 -0
  71. package/dist/tools/writeSemanticSummary.d.ts +8 -0
  72. package/dist/tools/writeSemanticSummary.js +40 -0
  73. package/dist/tools/writeSemanticSummary.js.map +1 -0
  74. package/package.json +35 -0
  75. package/scripts/bundle-skill.mjs +19 -0
  76. package/scripts/postinstall.mjs +19 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetchBinary.js","sourceRoot":"","sources":["../../src/indexer/fetchBinary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ export interface SpawnResult {
2
+ code: number;
3
+ stdout: string;
4
+ stderr: string;
5
+ }
6
+ /** Path to the indexer binary: REPOSKEIN_INDEXER_BIN or `reposkein-indexer`.
7
+ * @deprecated Superseded by ensureIndexerBinary() in fetchBinary.ts (M4-D1).
8
+ * Kept for back-compat; prefer ensureIndexerBinary() in new code. */
9
+ export declare function indexerBinPath(): string;
10
+ /** Repo root the indexer operates on: REPOSKEIN_REPO_PATH or cwd. */
11
+ export declare function repoPath(): string;
12
+ export declare function spawnIndexer(bin: string, args: string[]): Promise<SpawnResult>;
13
+ export interface IndexJsonStats {
14
+ repo_id: string;
15
+ files: number;
16
+ nodes: number;
17
+ edges: number;
18
+ children: number;
19
+ warnings: string[];
20
+ }
21
+ /** Parse the JSON object emitted by `index --json`. Returns null on parse failure. */
22
+ export declare function parseJsonStats(stdout: string): IndexJsonStats | null;
23
+ /** Whether to load the indexed graph into Neo4j after (re)indexing.
24
+ * False in explicit jsonl mode, or in auto mode without NEO4J_PASSWORD
25
+ * (zero-infra). True for neo4j mode or auto-with-DB. */
26
+ export declare function shouldLoadNeo4j(): boolean;
@@ -0,0 +1,42 @@
1
+ import { spawn } from "node:child_process";
2
+ /** Path to the indexer binary: REPOSKEIN_INDEXER_BIN or `reposkein-indexer`.
3
+ * @deprecated Superseded by ensureIndexerBinary() in fetchBinary.ts (M4-D1).
4
+ * Kept for back-compat; prefer ensureIndexerBinary() in new code. */
5
+ export function indexerBinPath() {
6
+ return process.env.REPOSKEIN_INDEXER_BIN ?? "reposkein-indexer";
7
+ }
8
+ /** Repo root the indexer operates on: REPOSKEIN_REPO_PATH or cwd. */
9
+ export function repoPath() {
10
+ return process.env.REPOSKEIN_REPO_PATH ?? process.cwd();
11
+ }
12
+ export function spawnIndexer(bin, args) {
13
+ return new Promise((resolve, reject) => {
14
+ const child = spawn(bin, args, { env: process.env });
15
+ let stdout = "";
16
+ let stderr = "";
17
+ child.stdout.on("data", (d) => (stdout += d.toString()));
18
+ child.stderr.on("data", (d) => (stderr += d.toString()));
19
+ child.on("error", reject);
20
+ child.on("close", (code) => resolve({ code: code ?? -1, stdout, stderr }));
21
+ });
22
+ }
23
+ /** Parse the JSON object emitted by `index --json`. Returns null on parse failure. */
24
+ export function parseJsonStats(stdout) {
25
+ try {
26
+ const parsed = JSON.parse(stdout.trim());
27
+ return parsed;
28
+ }
29
+ catch {
30
+ return null;
31
+ }
32
+ }
33
+ /** Whether to load the indexed graph into Neo4j after (re)indexing.
34
+ * False in explicit jsonl mode, or in auto mode without NEO4J_PASSWORD
35
+ * (zero-infra). True for neo4j mode or auto-with-DB. */
36
+ export function shouldLoadNeo4j() {
37
+ const mode = (process.env.REPOSKEIN_STORE ?? "auto").toLowerCase();
38
+ if (mode === "jsonl")
39
+ return false;
40
+ return !!process.env.NEO4J_PASSWORD;
41
+ }
42
+ //# sourceMappingURL=runIndexer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runIndexer.js","sourceRoot":"","sources":["../../src/indexer/runIndexer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAQ3C;;iFAEiF;AACjF,MAAM,UAAU,cAAc;IAC5B,OAAO,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,mBAAmB,CAAC;AAClE,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,QAAQ;IACtB,OAAO,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,IAAc;IACtD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACrD,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QACzD,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QACzD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1B,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;AACL,CAAC;AAWD,sFAAsF;AACtF,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACzC,OAAO,MAAwB,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;yDAEyD;AACzD,MAAM,UAAU,eAAe;IAC7B,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;IACnE,IAAI,IAAI,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IACnC,OAAO,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;AACtC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { GraphStore } from "../store/GraphStore.js";
2
+ import type { ContextProfile, TargetRow } from "./types.js";
3
+ /** Builds the full context profile for an already-resolved target. Hops is
4
+ * hard-capped at 2 (PRD §10.1). */
5
+ export declare function assembleProfile(store: GraphStore, repos: string | string[], target: TargetRow, hops: 1 | 2): Promise<ContextProfile>;
@@ -0,0 +1,90 @@
1
+ import { summaryState } from "./summary.js";
2
+ import { buildInlinedContext } from "./inline.js";
3
+ function neighborFromRow(r, distance) {
4
+ const st = summaryState({
5
+ semantic_summary: r.semantic_summary,
6
+ summary_of_hash: r.summary_of_hash,
7
+ content_hash: r.content_hash,
8
+ });
9
+ const entry = {
10
+ id: r.id,
11
+ name: r.name ?? "",
12
+ summary: st.summary,
13
+ stale: st.stale,
14
+ needs_enrichment: st.needsEnrichment,
15
+ distance,
16
+ };
17
+ if (r.resolution !== undefined)
18
+ entry.resolution = r.resolution;
19
+ if (r.confidence !== undefined)
20
+ entry.confidence = r.confidence;
21
+ if (r.repo_id !== undefined)
22
+ entry.repo_id = r.repo_id;
23
+ if (r.cross_repo)
24
+ entry.cross_repo = true;
25
+ return entry;
26
+ }
27
+ const MAX_NEIGHBORS = 25;
28
+ /** Builds the full context profile for an already-resolved target. Hops is
29
+ * hard-capped at 2 (PRD §10.1). */
30
+ export async function assembleProfile(store, repos, target, hops) {
31
+ const repoIds = Array.isArray(repos) ? repos : [repos];
32
+ const id = target.id;
33
+ // Upstream: direct callers — fetch one extra to detect truncation.
34
+ const upRows = await store.callers(repoIds, id, MAX_NEIGHBORS + 1);
35
+ const upstreamRaw = upRows.map((r) => neighborFromRow(r, 1));
36
+ const upstreamTruncated = upstreamRaw.length > MAX_NEIGHBORS;
37
+ const upstream = upstreamRaw.slice(0, MAX_NEIGHBORS);
38
+ // Downstream: direct callees (distance 1, with edge props).
39
+ const downRows = await store.callees(repoIds, id, MAX_NEIGHBORS + 1);
40
+ const downstreamRaw = downRows.map((r) => neighborFromRow(r, 1));
41
+ let downstreamTruncated = downstreamRaw.length > MAX_NEIGHBORS;
42
+ const downstream = downstreamRaw.slice(0, MAX_NEIGHBORS);
43
+ if (hops === 2) {
44
+ const seen = new Set(downstream.map((d) => d.id));
45
+ seen.add(id);
46
+ const d2 = await store.calleesAt2Hops(repoIds, id, MAX_NEIGHBORS + 1);
47
+ for (const r of d2) {
48
+ const e = neighborFromRow(r, 2);
49
+ if (!seen.has(e.id)) {
50
+ if (downstream.length >= MAX_NEIGHBORS) {
51
+ downstreamTruncated = true;
52
+ break;
53
+ }
54
+ downstream.push(e);
55
+ seen.add(e.id);
56
+ }
57
+ }
58
+ }
59
+ const tState = summaryState(target);
60
+ const profTarget = {
61
+ id: target.id,
62
+ name: target.qualified_name,
63
+ file_path: target.file_path,
64
+ lines: [target.start_line, target.end_line],
65
+ summary: tState.summary,
66
+ stale: tState.stale,
67
+ repo_id: target.repo_id,
68
+ };
69
+ const enrichment_needed = [
70
+ ...(tState.needsEnrichment ? [target.id] : []),
71
+ ...downstream.filter((d) => d.needs_enrichment).map((d) => d.id),
72
+ ];
73
+ let inlined = buildInlinedContext(profTarget, upstream, downstream);
74
+ if (upstreamTruncated) {
75
+ const extra = upstreamRaw.length - MAX_NEIGHBORS;
76
+ inlined += ` (+${extra} more callers not shown — query read_cypher for the full set.)`;
77
+ }
78
+ if (downstreamTruncated) {
79
+ inlined += ` (downstream list truncated — query read_cypher for the full set.)`;
80
+ }
81
+ return {
82
+ target: profTarget,
83
+ upstream,
84
+ downstream,
85
+ inlined_context: inlined,
86
+ enrichment_needed,
87
+ truncated: { upstream: upstreamTruncated, downstream: downstreamTruncated },
88
+ };
89
+ }
90
+ //# sourceMappingURL=assemble.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assemble.js","sourceRoot":"","sources":["../../src/profile/assemble.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGlD,SAAS,eAAe,CAAC,CAAc,EAAE,QAAgB;IACvD,MAAM,EAAE,GAAG,YAAY,CAAC;QACtB,gBAAgB,EAAE,CAAC,CAAC,gBAAgB;QACpC,eAAe,EAAE,CAAC,CAAC,eAAe;QAClC,YAAY,EAAE,CAAC,CAAC,YAAY;KAC7B,CAAC,CAAC;IACH,MAAM,KAAK,GAAkB;QAC3B,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE;QAClB,OAAO,EAAE,EAAE,CAAC,OAAO;QACnB,KAAK,EAAE,EAAE,CAAC,KAAK;QACf,gBAAgB,EAAE,EAAE,CAAC,eAAe;QACpC,QAAQ;KACT,CAAC;IACF,IAAI,CAAC,CAAC,UAAU,KAAK,SAAS;QAAE,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC;IAChE,IAAI,CAAC,CAAC,UAAU,KAAK,SAAS;QAAE,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC;IAChE,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS;QAAE,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC;IACvD,IAAI,CAAC,CAAC,UAAU;QAAE,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC;IAC1C,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,aAAa,GAAG,EAAE,CAAC;AAEzB;oCACoC;AACpC,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,KAAiB,EACjB,KAAwB,EACxB,MAAiB,EACjB,IAAW;IAEX,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACvD,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC;IAErB,mEAAmE;IACnE,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,EAAE,aAAa,GAAG,CAAC,CAAC,CAAC;IACnE,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7D,MAAM,iBAAiB,GAAG,WAAW,CAAC,MAAM,GAAG,aAAa,CAAC;IAC7D,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;IAErD,4DAA4D;IAC5D,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,EAAE,aAAa,GAAG,CAAC,CAAC,CAAC;IACrE,MAAM,aAAa,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACjE,IAAI,mBAAmB,GAAG,aAAa,CAAC,MAAM,GAAG,aAAa,CAAC;IAC/D,MAAM,UAAU,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;IAEzD,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;QACf,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAClD,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,EAAE,aAAa,GAAG,CAAC,CAAC,CAAC;QACtE,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;YACnB,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAChC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;gBACpB,IAAI,UAAU,CAAC,MAAM,IAAI,aAAa,EAAE,CAAC;oBACvC,mBAAmB,GAAG,IAAI,CAAC;oBAC3B,MAAM;gBACR,CAAC;gBACD,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACnB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,UAAU,GAAG;QACjB,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,IAAI,EAAE,MAAM,CAAC,cAAc;QAC3B,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,KAAK,EAAE,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAqB;QAC/D,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,OAAO,EAAE,MAAM,CAAC,OAAO;KACxB,CAAC;IAEF,MAAM,iBAAiB,GAAG;QACxB,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9C,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACjE,CAAC;IAEF,IAAI,OAAO,GAAG,mBAAmB,CAAC,UAAU,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;IACpE,IAAI,iBAAiB,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,GAAG,aAAa,CAAC;QACjD,OAAO,IAAI,MAAM,KAAK,gEAAgE,CAAC;IACzF,CAAC;IACD,IAAI,mBAAmB,EAAE,CAAC;QACxB,OAAO,IAAI,oEAAoE,CAAC;IAClF,CAAC;IAED,OAAO;QACL,MAAM,EAAE,UAAU;QAClB,QAAQ;QACR,UAAU;QACV,eAAe,EAAE,OAAO;QACxB,iBAAiB;QACjB,SAAS,EAAE,EAAE,QAAQ,EAAE,iBAAiB,EAAE,UAAU,EAAE,mBAAmB,EAAE;KAC5E,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { NeighborEntry, ProfileTarget } from "./types.js";
2
+ /** Assembles the prose `inlined_context` an agent pastes into its reasoning
3
+ * (PRD §7.4 / §10.3) so it doesn't burn turns reassembling the neighborhood. */
4
+ export declare function buildInlinedContext(target: ProfileTarget, upstream: NeighborEntry[], downstream: NeighborEntry[]): string;
@@ -0,0 +1,32 @@
1
+ function neighborPhrase(n, withCaveat, homeRepo) {
2
+ let s = n.name;
3
+ if (n.summary) {
4
+ s += ` (${n.summary})`;
5
+ }
6
+ else {
7
+ s += " (no summary yet — read and enrich)";
8
+ }
9
+ if (homeRepo && n.repo_id && n.repo_id !== homeRepo) {
10
+ s += ` [repo: ${n.repo_id}]`;
11
+ }
12
+ if (withCaveat && n.resolution && n.resolution !== "exact") {
13
+ const conf = n.confidence != null ? `, confidence ${n.confidence}` : "";
14
+ s += ` [${n.resolution}${conf} — verify]`;
15
+ }
16
+ return s;
17
+ }
18
+ /** Assembles the prose `inlined_context` an agent pastes into its reasoning
19
+ * (PRD §7.4 / §10.3) so it doesn't burn turns reassembling the neighborhood. */
20
+ export function buildInlinedContext(target, upstream, downstream) {
21
+ const head = `${target.name} (${target.file_path}:${target.lines[0]}-${target.lines[1]})`;
22
+ const parts = [];
23
+ parts.push(target.summary ? `${head}: ${target.summary}.` : `${head} — no summary yet (read and enrich).`);
24
+ if (upstream.length > 0) {
25
+ parts.push("Called by " + upstream.map((u) => neighborPhrase(u, false, target.repo_id)).join(", ") + ".");
26
+ }
27
+ if (downstream.length > 0) {
28
+ parts.push("Calls " + downstream.map((d) => neighborPhrase(d, true, target.repo_id)).join("; ") + ".");
29
+ }
30
+ return parts.join(" ");
31
+ }
32
+ //# sourceMappingURL=inline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inline.js","sourceRoot":"","sources":["../../src/profile/inline.ts"],"names":[],"mappings":"AAEA,SAAS,cAAc,CAAC,CAAgB,EAAE,UAAmB,EAAE,QAAiB;IAC9E,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;IACf,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;QACd,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,GAAG,CAAC;IACzB,CAAC;SAAM,CAAC;QACN,CAAC,IAAI,qCAAqC,CAAC;IAC7C,CAAC;IACD,IAAI,QAAQ,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QACpD,CAAC,IAAI,WAAW,CAAC,CAAC,OAAO,GAAG,CAAC;IAC/B,CAAC;IACD,IAAI,UAAU,IAAI,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,UAAU,KAAK,OAAO,EAAE,CAAC;QAC3D,MAAM,IAAI,GAAG,CAAC,CAAC,UAAU,IAAI,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxE,CAAC,IAAI,KAAK,CAAC,CAAC,UAAU,GAAG,IAAI,YAAY,CAAC;IAC5C,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED;iFACiF;AACjF,MAAM,UAAU,mBAAmB,CACjC,MAAqB,EACrB,QAAyB,EACzB,UAA2B;IAE3B,MAAM,IAAI,GAAG,GAAG,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC;IAC1F,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,sCAAsC,CAAC,CAAC;IAC3G,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;IAC5G,CAAC;IACD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,KAAK,CAAC,IAAI,CAAC,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;IACzG,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { GraphStore } from "../store/GraphStore.js";
2
+ import type { ResolveResult } from "./types.js";
3
+ export interface Selector {
4
+ node_id?: string;
5
+ file_path?: string;
6
+ name?: string;
7
+ }
8
+ /** Resolves a target across one or more repos: id → exact path#name → fuzzy
9
+ * name. Returns candidates (never guesses) when a name is ambiguous (§7.4). */
10
+ export declare function resolveTarget(store: GraphStore, repos: string | string[], sel: Selector): Promise<ResolveResult>;
@@ -0,0 +1,24 @@
1
+ function fromRows(rows) {
2
+ if (rows.length === 1)
3
+ return { kind: "found", target: rows[0] };
4
+ if (rows.length > 1)
5
+ return { kind: "candidates", candidates: rows };
6
+ return { kind: "not_found" };
7
+ }
8
+ /** Resolves a target across one or more repos: id → exact path#name → fuzzy
9
+ * name. Returns candidates (never guesses) when a name is ambiguous (§7.4). */
10
+ export async function resolveTarget(store, repos, sel) {
11
+ const repoIds = Array.isArray(repos) ? repos : [repos];
12
+ if (sel.node_id) {
13
+ const node = await store.getNode(repoIds, sel.node_id);
14
+ return node ? { kind: "found", target: node } : { kind: "not_found" };
15
+ }
16
+ if (sel.file_path && sel.name) {
17
+ return fromRows(await store.resolveByPathAndName(repoIds, sel.file_path, sel.name));
18
+ }
19
+ if (sel.name) {
20
+ return fromRows(await store.resolveByName(repoIds, sel.name));
21
+ }
22
+ return { kind: "not_found" };
23
+ }
24
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/profile/resolve.ts"],"names":[],"mappings":"AASA,SAAS,QAAQ,CAAC,IAAiB;IACjC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAE,EAAE,CAAC;IAClE,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;IACrE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;AAC/B,CAAC;AAED;gFACgF;AAChF,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,KAAiB,EACjB,KAAwB,EACxB,GAAa;IAEb,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACvD,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QAChB,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QACvD,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IACxE,CAAC;IACD,IAAI,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,OAAO,QAAQ,CAAC,MAAM,KAAK,CAAC,oBAAoB,CAAC,OAAO,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IACtF,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;QACb,OAAO,QAAQ,CAAC,MAAM,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,13 @@
1
+ export interface SummaryInput {
2
+ semantic_summary: string | null;
3
+ summary_of_hash: string | null;
4
+ content_hash: string | null;
5
+ }
6
+ export interface SummaryState {
7
+ summary: string | null;
8
+ stale: boolean;
9
+ needsEnrichment: boolean;
10
+ }
11
+ /** Derives summary freshness (PRD §3.6): a summary is stale when the hash it
12
+ * was written against no longer matches the node's current content_hash. */
13
+ export declare function summaryState(props: SummaryInput): SummaryState;
@@ -0,0 +1,12 @@
1
+ import { neutralizeSummary } from "../guard/summaryValidation.js";
2
+ /** Derives summary freshness (PRD §3.6): a summary is stale when the hash it
3
+ * was written against no longer matches the node's current content_hash. */
4
+ export function summaryState(props) {
5
+ const summary = neutralizeSummary(props.semantic_summary ?? null);
6
+ if (!summary) {
7
+ return { summary: null, stale: false, needsEnrichment: true };
8
+ }
9
+ const stale = props.summary_of_hash !== props.content_hash;
10
+ return { summary, stale, needsEnrichment: stale };
11
+ }
12
+ //# sourceMappingURL=summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary.js","sourceRoot":"","sources":["../../src/profile/summary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAclE;6EAC6E;AAC7E,MAAM,UAAU,YAAY,CAAC,KAAmB;IAC9C,MAAM,OAAO,GAAG,iBAAiB,CAAC,KAAK,CAAC,gBAAgB,IAAI,IAAI,CAAC,CAAC;IAClE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;IAChE,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,eAAe,KAAK,KAAK,CAAC,YAAY,CAAC;IAC3D,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;AACpD,CAAC"}
@@ -0,0 +1,55 @@
1
+ export interface TargetRow {
2
+ id: string;
3
+ repo_id: string;
4
+ name: string;
5
+ qualified_name: string;
6
+ file_path: string;
7
+ start_line: number;
8
+ end_line: number;
9
+ semantic_summary: string | null;
10
+ summary_of_hash: string | null;
11
+ content_hash: string | null;
12
+ labels: string[];
13
+ }
14
+ export interface NeighborEntry {
15
+ id: string;
16
+ name: string;
17
+ summary: string | null;
18
+ stale: boolean;
19
+ needs_enrichment: boolean;
20
+ resolution?: string;
21
+ confidence?: number;
22
+ distance?: number;
23
+ repo_id?: string;
24
+ /** True for a cross-repo (federation-stitched) neighbor. */
25
+ cross_repo?: boolean;
26
+ }
27
+ export interface ProfileTarget {
28
+ id: string;
29
+ name: string;
30
+ file_path: string;
31
+ lines: [number, number];
32
+ summary: string | null;
33
+ stale: boolean;
34
+ repo_id?: string;
35
+ }
36
+ export interface ContextProfile {
37
+ target: ProfileTarget;
38
+ upstream: NeighborEntry[];
39
+ downstream: NeighborEntry[];
40
+ inlined_context: string;
41
+ enrichment_needed: string[];
42
+ truncated?: {
43
+ upstream: boolean;
44
+ downstream: boolean;
45
+ };
46
+ }
47
+ export type ResolveResult = {
48
+ kind: "found";
49
+ target: TargetRow;
50
+ } | {
51
+ kind: "candidates";
52
+ candidates: TargetRow[];
53
+ } | {
54
+ kind: "not_found";
55
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/profile/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,62 @@
1
+ import type { TargetRow } from "../profile/types.js";
2
+ /** Thrown by stores that cannot execute raw Cypher (e.g. the JSONL store).
3
+ * read_cypher surfaces the message to the agent. */
4
+ export declare class CypherUnsupportedError extends Error {
5
+ constructor(message?: string);
6
+ }
7
+ /** A single caller/callee row. resolution/confidence are present only for the
8
+ * direct (1-hop) CALLS edges; absent for 2-hop callees. */
9
+ export interface NeighborRow {
10
+ id: string;
11
+ repo_id?: string;
12
+ name: string;
13
+ semantic_summary: string | null;
14
+ summary_of_hash: string | null;
15
+ content_hash: string | null;
16
+ resolution?: string;
17
+ confidence?: number;
18
+ /** True for a federation-stitched cross-repo CALLS edge. */
19
+ cross_repo?: boolean;
20
+ }
21
+ /** Fields the caller computes (date/agent) and hands to the store to persist. */
22
+ export interface SummaryFields {
23
+ summary: string;
24
+ model: string;
25
+ at: string;
26
+ by: string;
27
+ }
28
+ export type WriteSummaryResult = {
29
+ kind: "ok";
30
+ stale_replaced: boolean;
31
+ } | {
32
+ kind: "not_found";
33
+ } | {
34
+ kind: "no_content_hash";
35
+ };
36
+ /** Storage abstraction (PRD §4.2). All MCP read/write goes through these
37
+ * semantic methods so the backend (Neo4j or JSONL) is swappable. Raw Cypher
38
+ * is exposed only via runRead, used by the read_cypher tool. */
39
+ export interface GraphStore {
40
+ /** Exact node by id within the given repos. null if not found. */
41
+ getNode(repoIds: string[], id: string): Promise<TargetRow | null>;
42
+ /** Function/Class nodes in a file matching name OR qualified_name, within the given repos. */
43
+ resolveByPathAndName(repoIds: string[], filePath: string, name: string): Promise<TargetRow[]>;
44
+ /** Function nodes anywhere in the given repos matching name. */
45
+ resolveByName(repoIds: string[], name: string): Promise<TargetRow[]>;
46
+ /** Direct callers of id whose repo_id is in repoIds, ordered by id, capped at limit. */
47
+ callers(repoIds: string[], id: string, limit: number): Promise<NeighborRow[]>;
48
+ /** Direct callees of id whose repo_id is in repoIds, ordered by id, capped at limit. */
49
+ callees(repoIds: string[], id: string, limit: number): Promise<NeighborRow[]>;
50
+ /** Callees exactly 2 hops out whose repo_id is in repoIds, distinct, ordered by id, capped at limit. */
51
+ calleesAt2Hops(repoIds: string[], id: string, limit: number): Promise<NeighborRow[]>;
52
+ /** Attach/refresh a summary; returns whether a stale one was replaced. */
53
+ writeSummary(repoId: string, id: string, fields: SummaryFields): Promise<WriteSummaryResult>;
54
+ /** Transitively federated repo_ids (NOT including repoId itself). */
55
+ federatedRepoIds(repoId: string): Promise<string[]>;
56
+ /** Raw read-only Cypher (read_cypher tool only). Stores without a Cypher
57
+ * engine throw CypherUnsupportedError. */
58
+ runRead(query: string, params?: Record<string, unknown>, opts?: {
59
+ timeoutMs?: number;
60
+ }): Promise<Record<string, unknown>[]>;
61
+ close(): Promise<void>;
62
+ }
@@ -0,0 +1,9 @@
1
+ /** Thrown by stores that cannot execute raw Cypher (e.g. the JSONL store).
2
+ * read_cypher surfaces the message to the agent. */
3
+ export class CypherUnsupportedError extends Error {
4
+ constructor(message = "read_cypher is not supported by this store (no Cypher engine). Use get_context_profile.") {
5
+ super(message);
6
+ this.name = "CypherUnsupportedError";
7
+ }
8
+ }
9
+ //# sourceMappingURL=GraphStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GraphStore.js","sourceRoot":"","sources":["../../src/store/GraphStore.ts"],"names":[],"mappings":"AAEA;qDACqD;AACrD,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC/C,YACE,OAAO,GAAG,yFAAyF;QAEnG,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF"}
@@ -0,0 +1,37 @@
1
+ import { type GraphStore, type NeighborRow, type SummaryFields, type WriteSummaryResult } from "./GraphStore.js";
2
+ import type { TargetRow } from "../profile/types.js";
3
+ /** A GraphStore over a repo's committed .reposkein JSONL. In single-repo mode
4
+ * it loads only the root; in federated mode it also loads nested children
5
+ * (guarded, cycle-safe) and merges them into one graph. All read methods
6
+ * scope per-node by repoIds — so non-federated reads (repoIds=[root]) see
7
+ * exactly the root (children invisible).
8
+ *
9
+ * Reloads when either ROOT JSONL file's mtime changes (v1: a child-only
10
+ * change without a root change won't trigger reload — acceptable).
11
+ * writeSummary persists to the durable sidecar (.reposkein/local/summaries.jsonl). */
12
+ export declare class JsonlGraphStore implements GraphStore {
13
+ private readonly repoId;
14
+ private graph;
15
+ private mtime;
16
+ private readonly repoPath;
17
+ private readonly nodesPath;
18
+ private readonly edgesPath;
19
+ private readonly sidecarFile;
20
+ constructor(repoPath: string, repoId: string);
21
+ /** Gathers committed JSONL for the root + all transitively federated
22
+ * children (guarded, cycle-safe). Each child's repo_id comes from the proxy
23
+ * Repository node's federated_repo_id in the parent's nodes.jsonl. */
24
+ private collectRepos;
25
+ /** Reloads the graph if either ROOT file's mtime changed since last load. */
26
+ private ensureFresh;
27
+ getNode(repoIds: string[], id: string): Promise<TargetRow | null>;
28
+ resolveByPathAndName(repoIds: string[], filePath: string, name: string): Promise<TargetRow[]>;
29
+ resolveByName(repoIds: string[], name: string): Promise<TargetRow[]>;
30
+ callers(repoIds: string[], id: string, limit: number): Promise<NeighborRow[]>;
31
+ callees(repoIds: string[], id: string, limit: number): Promise<NeighborRow[]>;
32
+ calleesAt2Hops(repoIds: string[], id: string, limit: number): Promise<NeighborRow[]>;
33
+ writeSummary(repoId: string, id: string, fields: SummaryFields): Promise<WriteSummaryResult>;
34
+ federatedRepoIds(repoId: string): Promise<string[]>;
35
+ runRead(): Promise<Record<string, unknown>[]>;
36
+ close(): Promise<void>;
37
+ }