@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.
- package/dist/SKILL.md +67 -0
- package/dist/cli/init.d.ts +9 -0
- package/dist/cli/init.js +54 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/guard/caps.d.ts +7 -0
- package/dist/guard/caps.js +22 -0
- package/dist/guard/caps.js.map +1 -0
- package/dist/guard/readonly.d.ts +4 -0
- package/dist/guard/readonly.js +91 -0
- package/dist/guard/readonly.js.map +1 -0
- package/dist/guard/summaryValidation.d.ts +18 -0
- package/dist/guard/summaryValidation.js +44 -0
- package/dist/guard/summaryValidation.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +143 -0
- package/dist/index.js.map +1 -0
- package/dist/indexer/fetchBinary.d.ts +24 -0
- package/dist/indexer/fetchBinary.js +109 -0
- package/dist/indexer/fetchBinary.js.map +1 -0
- package/dist/indexer/runIndexer.d.ts +26 -0
- package/dist/indexer/runIndexer.js +42 -0
- package/dist/indexer/runIndexer.js.map +1 -0
- package/dist/profile/assemble.d.ts +5 -0
- package/dist/profile/assemble.js +90 -0
- package/dist/profile/assemble.js.map +1 -0
- package/dist/profile/inline.d.ts +4 -0
- package/dist/profile/inline.js +32 -0
- package/dist/profile/inline.js.map +1 -0
- package/dist/profile/resolve.d.ts +10 -0
- package/dist/profile/resolve.js +24 -0
- package/dist/profile/resolve.js.map +1 -0
- package/dist/profile/summary.d.ts +13 -0
- package/dist/profile/summary.js +12 -0
- package/dist/profile/summary.js.map +1 -0
- package/dist/profile/types.d.ts +55 -0
- package/dist/profile/types.js +2 -0
- package/dist/profile/types.js.map +1 -0
- package/dist/store/GraphStore.d.ts +62 -0
- package/dist/store/GraphStore.js +9 -0
- package/dist/store/GraphStore.js.map +1 -0
- package/dist/store/JsonlGraphStore.d.ts +37 -0
- package/dist/store/JsonlGraphStore.js +275 -0
- package/dist/store/JsonlGraphStore.js.map +1 -0
- package/dist/store/Neo4jGraphStore.d.ts +27 -0
- package/dist/store/Neo4jGraphStore.js +148 -0
- package/dist/store/Neo4jGraphStore.js.map +1 -0
- package/dist/store/UnconfiguredStore.d.ts +16 -0
- package/dist/store/UnconfiguredStore.js +36 -0
- package/dist/store/UnconfiguredStore.js.map +1 -0
- package/dist/store/federation.d.ts +9 -0
- package/dist/store/federation.js +29 -0
- package/dist/store/federation.js.map +1 -0
- package/dist/store/jsonlGraph.d.ts +43 -0
- package/dist/store/jsonlGraph.js +176 -0
- package/dist/store/jsonlGraph.js.map +1 -0
- package/dist/store/repoId.d.ts +3 -0
- package/dist/store/repoId.js +18 -0
- package/dist/store/repoId.js.map +1 -0
- package/dist/store/sidecar.d.ts +16 -0
- package/dist/store/sidecar.js +65 -0
- package/dist/store/sidecar.js.map +1 -0
- package/dist/tools/getContextProfile.d.ts +10 -0
- package/dist/tools/getContextProfile.js +44 -0
- package/dist/tools/getContextProfile.js.map +1 -0
- package/dist/tools/indexerTools.d.ts +27 -0
- package/dist/tools/indexerTools.js +89 -0
- package/dist/tools/indexerTools.js.map +1 -0
- package/dist/tools/readCypher.d.ts +16 -0
- package/dist/tools/readCypher.js +40 -0
- package/dist/tools/readCypher.js.map +1 -0
- package/dist/tools/writeSemanticSummary.d.ts +8 -0
- package/dist/tools/writeSemanticSummary.js +40 -0
- package/dist/tools/writeSemanticSummary.js.map +1 -0
- package/package.json +35 -0
- package/scripts/bundle-skill.mjs +19 -0
- package/scripts/postinstall.mjs +19 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/** Parses committed RepoSkein JSONL into in-memory records + lookup indices.
|
|
2
|
+
* Pure (no I/O) so it is trivially testable. Committed JSONL has no repo_id
|
|
3
|
+
* property — the repo is supplied by the caller (which .reposkein/ was loaded). */
|
|
4
|
+
function parseNodeLine(line, repoId) {
|
|
5
|
+
const obj = JSON.parse(line);
|
|
6
|
+
const id = obj.id;
|
|
7
|
+
const labels = obj.labels;
|
|
8
|
+
if (typeof id !== "string" || !Array.isArray(labels))
|
|
9
|
+
return null;
|
|
10
|
+
const props = { ...obj };
|
|
11
|
+
delete props.id;
|
|
12
|
+
delete props.labels;
|
|
13
|
+
return { id, repoId, labels: labels.filter((l) => typeof l === "string"), props };
|
|
14
|
+
}
|
|
15
|
+
function parseEdgeLine(line) {
|
|
16
|
+
const obj = JSON.parse(line);
|
|
17
|
+
const from = obj.from;
|
|
18
|
+
const type = obj.type;
|
|
19
|
+
const to = obj.to;
|
|
20
|
+
if (typeof from !== "string" || typeof type !== "string" || typeof to !== "string")
|
|
21
|
+
return null;
|
|
22
|
+
const props = { ...obj };
|
|
23
|
+
delete props.from;
|
|
24
|
+
delete props.type;
|
|
25
|
+
delete props.to;
|
|
26
|
+
return { from, type, to, props };
|
|
27
|
+
}
|
|
28
|
+
export function parseNodes(text, repoId) {
|
|
29
|
+
const out = [];
|
|
30
|
+
for (const line of text.split("\n")) {
|
|
31
|
+
if (line.trim() === "")
|
|
32
|
+
continue;
|
|
33
|
+
const n = parseNodeLine(line, repoId);
|
|
34
|
+
if (n)
|
|
35
|
+
out.push(n);
|
|
36
|
+
}
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
39
|
+
export function parseEdges(text) {
|
|
40
|
+
const out = [];
|
|
41
|
+
for (const line of text.split("\n")) {
|
|
42
|
+
if (line.trim() === "")
|
|
43
|
+
continue;
|
|
44
|
+
const e = parseEdgeLine(line);
|
|
45
|
+
if (e)
|
|
46
|
+
out.push(e);
|
|
47
|
+
}
|
|
48
|
+
return out;
|
|
49
|
+
}
|
|
50
|
+
/** Builds lookup indices from parsed node/edge text. */
|
|
51
|
+
export function buildGraph(nodesText, edgesText, repoId) {
|
|
52
|
+
const nodes = parseNodes(nodesText, repoId);
|
|
53
|
+
const edges = parseEdges(edgesText);
|
|
54
|
+
const byId = new Map();
|
|
55
|
+
for (const n of nodes)
|
|
56
|
+
byId.set(n.id, n);
|
|
57
|
+
const callsFrom = new Map();
|
|
58
|
+
const callsTo = new Map();
|
|
59
|
+
for (const e of edges) {
|
|
60
|
+
if (e.type !== "CALLS")
|
|
61
|
+
continue;
|
|
62
|
+
(callsFrom.get(e.from) ?? callsFrom.set(e.from, []).get(e.from)).push(e);
|
|
63
|
+
(callsTo.get(e.to) ?? callsTo.set(e.to, []).get(e.to)).push(e);
|
|
64
|
+
}
|
|
65
|
+
return { byId, callsFrom, callsTo, nodes, edges };
|
|
66
|
+
}
|
|
67
|
+
/** An empty graph (used when .reposkein files are missing). */
|
|
68
|
+
export function emptyGraph() {
|
|
69
|
+
return { byId: new Map(), callsFrom: new Map(), callsTo: new Map(), nodes: [], edges: [] };
|
|
70
|
+
}
|
|
71
|
+
const isFunction = (n) => n.labels.includes("Function");
|
|
72
|
+
/** Builds one merged graph from several repos' committed JSONL, then injects
|
|
73
|
+
* DB-only-style cross-repo edges (M3 + M4):
|
|
74
|
+
* - IMPORTS edges (File→File) from external_import_targets (parity with Neo4j
|
|
75
|
+
* stitch_cross_repo_imports).
|
|
76
|
+
* - CALLS edges (Function→Function) from external_calls, import-scoped first
|
|
77
|
+
* (confidence 0.6) with federation-wide unique fallback (0.5); ambiguous
|
|
78
|
+
* skipped. Per-name (mirrors Neo4j stitch_cross_repo_calls). */
|
|
79
|
+
export function buildFederatedGraph(repos) {
|
|
80
|
+
const byId = new Map();
|
|
81
|
+
const callsFrom = new Map();
|
|
82
|
+
const callsTo = new Map();
|
|
83
|
+
const nodes = [];
|
|
84
|
+
const edges = [];
|
|
85
|
+
const pushCall = (e) => {
|
|
86
|
+
(callsFrom.get(e.from) ?? callsFrom.set(e.from, []).get(e.from)).push(e);
|
|
87
|
+
(callsTo.get(e.to) ?? callsTo.set(e.to, []).get(e.to)).push(e);
|
|
88
|
+
};
|
|
89
|
+
// 1) Parse + merge every repo.
|
|
90
|
+
for (const r of repos) {
|
|
91
|
+
const g = buildGraph(r.nodesText, r.edgesText, r.repoId);
|
|
92
|
+
for (const n of g.nodes) {
|
|
93
|
+
if (!byId.has(n.id)) {
|
|
94
|
+
byId.set(n.id, n);
|
|
95
|
+
nodes.push(n);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
for (const e of g.edges)
|
|
99
|
+
edges.push(e);
|
|
100
|
+
for (const [, list] of g.callsFrom)
|
|
101
|
+
for (const e of list)
|
|
102
|
+
pushCall(e);
|
|
103
|
+
}
|
|
104
|
+
// 2) Cross-repo name index: function name -> [{id, repoId, fileId}] (sorted by id).
|
|
105
|
+
const byName = new Map();
|
|
106
|
+
for (const n of nodes) {
|
|
107
|
+
if (!isFunction(n))
|
|
108
|
+
continue;
|
|
109
|
+
const nm = typeof n.props.name === "string" ? n.props.name : null;
|
|
110
|
+
if (!nm)
|
|
111
|
+
continue;
|
|
112
|
+
const fp = typeof n.props.file_path === "string" ? n.props.file_path : "";
|
|
113
|
+
const fileId = `rs1:${n.repoId}:file:${fp}`;
|
|
114
|
+
(byName.get(nm) ?? byName.set(nm, []).get(nm)).push({ id: n.id, repoId: n.repoId, fileId });
|
|
115
|
+
}
|
|
116
|
+
for (const arr of byName.values())
|
|
117
|
+
arr.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
|
|
118
|
+
// File id -> set of external_import_targets (the child Files it imports from).
|
|
119
|
+
const importTargets = new Map();
|
|
120
|
+
for (const n of nodes) {
|
|
121
|
+
const t = n.props.external_import_targets;
|
|
122
|
+
if (Array.isArray(t)) {
|
|
123
|
+
importTargets.set(n.id, new Set(t.filter((x) => typeof x === "string")));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// M3: cross-repo IMPORTS edges (File -> child File) from external_import_targets,
|
|
127
|
+
// for backend parity with Neo4j's stitch_cross_repo_imports. Added to `edges`
|
|
128
|
+
// (no dedicated reader yet — the committed property already carries the data).
|
|
129
|
+
for (const n of nodes) {
|
|
130
|
+
const targets = n.props.external_import_targets;
|
|
131
|
+
if (!Array.isArray(targets))
|
|
132
|
+
continue;
|
|
133
|
+
for (const t of targets) {
|
|
134
|
+
if (typeof t === "string" && byId.has(t)) {
|
|
135
|
+
edges.push({ from: n.id, type: "IMPORTS", to: t, props: { cross_repo: true, stitched: true } });
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// 3) Inject cross-repo CALLS. Prefer an import-scoped match (the called name
|
|
140
|
+
// in a file the caller's file imports from — precise); fall back to a
|
|
141
|
+
// federation-wide unique match. Per name; ambiguous skipped.
|
|
142
|
+
for (const n of nodes) {
|
|
143
|
+
const ext = n.props.external_calls;
|
|
144
|
+
if (!Array.isArray(ext))
|
|
145
|
+
continue;
|
|
146
|
+
const callerFp = typeof n.props.file_path === "string" ? n.props.file_path : "";
|
|
147
|
+
const callerFileId = `rs1:${n.repoId}:file:${callerFp}`;
|
|
148
|
+
const targets = importTargets.get(callerFileId);
|
|
149
|
+
const names = [...new Set(ext.filter((x) => typeof x === "string"))].sort();
|
|
150
|
+
for (const name of names) {
|
|
151
|
+
const all = (byName.get(name) ?? []).filter((m) => m.repoId !== n.repoId);
|
|
152
|
+
let chosen;
|
|
153
|
+
let confidence = 0.5;
|
|
154
|
+
if (targets) {
|
|
155
|
+
const scoped = all.filter((m) => targets.has(m.fileId));
|
|
156
|
+
if (scoped.length === 1) {
|
|
157
|
+
chosen = scoped[0];
|
|
158
|
+
confidence = 0.6; // import-scoped → more precise
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (!chosen && all.length === 1) {
|
|
162
|
+
chosen = all[0]; // federation-wide fallback
|
|
163
|
+
}
|
|
164
|
+
if (!chosen)
|
|
165
|
+
continue; // ambiguous / unresolved
|
|
166
|
+
pushCall({
|
|
167
|
+
from: n.id,
|
|
168
|
+
type: "CALLS",
|
|
169
|
+
to: chosen.id,
|
|
170
|
+
props: { resolution: "name_match", confidence, cross_repo: true, stitched: true, call_sites: 1 },
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return { byId, callsFrom, callsTo, nodes, edges };
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=jsonlGraph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonlGraph.js","sourceRoot":"","sources":["../../src/store/jsonlGraph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
/** repo_id resolution: REPOSKEIN_REPO_ID env override, else
|
|
4
|
+
* <repoPath>/.reposkein/meta.json's repo_id. Returns undefined if neither. */
|
|
5
|
+
export function resolveRepoId(repoPath, envRepoId) {
|
|
6
|
+
if (envRepoId)
|
|
7
|
+
return envRepoId;
|
|
8
|
+
if (!repoPath)
|
|
9
|
+
return undefined;
|
|
10
|
+
try {
|
|
11
|
+
const meta = JSON.parse(readFileSync(join(repoPath, ".reposkein", "meta.json"), "utf8"));
|
|
12
|
+
return typeof meta.repo_id === "string" ? meta.repo_id : undefined;
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=repoId.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repoId.js","sourceRoot":"","sources":["../../src/store/repoId.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;+EAC+E;AAC/E,MAAM,UAAU,aAAa,CAAC,QAA4B,EAAE,SAA6B;IACvF,IAAI,SAAS;QAAE,OAAO,SAAS,CAAC;IAChC,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IAChC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QACzF,OAAO,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** A persisted summary record (git-ignored .reposkein/local/summaries.jsonl). */
|
|
2
|
+
export interface SidecarSummary {
|
|
3
|
+
id: string;
|
|
4
|
+
semantic_summary: string;
|
|
5
|
+
summary_of_hash: string;
|
|
6
|
+
summary_model: string;
|
|
7
|
+
summary_at: string;
|
|
8
|
+
summary_by: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function sidecarPath(repoPath: string): string;
|
|
11
|
+
/** Reads the sidecar into a map keyed by node id. Missing file → empty map.
|
|
12
|
+
* Best-effort: malformed lines / read errors are skipped. */
|
|
13
|
+
export declare function readSidecar(path: string): Map<string, SidecarSummary>;
|
|
14
|
+
/** Upserts one record and rewrites the sidecar sorted by id (deterministic, no
|
|
15
|
+
* duplicate lines). Creates the local/ dir if needed. Best-effort. */
|
|
16
|
+
export declare function upsertSidecar(path: string, rec: SidecarSummary): void;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
export function sidecarPath(repoPath) {
|
|
4
|
+
return join(repoPath, ".reposkein", "local", "summaries.jsonl");
|
|
5
|
+
}
|
|
6
|
+
/** Reads the sidecar into a map keyed by node id. Missing file → empty map.
|
|
7
|
+
* Best-effort: malformed lines / read errors are skipped. */
|
|
8
|
+
export function readSidecar(path) {
|
|
9
|
+
const map = new Map();
|
|
10
|
+
if (!existsSync(path))
|
|
11
|
+
return map;
|
|
12
|
+
let text;
|
|
13
|
+
try {
|
|
14
|
+
text = readFileSync(path, "utf8");
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return map;
|
|
18
|
+
}
|
|
19
|
+
for (const line of text.split("\n")) {
|
|
20
|
+
if (line.trim() === "")
|
|
21
|
+
continue;
|
|
22
|
+
try {
|
|
23
|
+
const o = JSON.parse(line);
|
|
24
|
+
if (typeof o.id === "string" && typeof o.semantic_summary === "string") {
|
|
25
|
+
map.set(o.id, {
|
|
26
|
+
id: o.id,
|
|
27
|
+
semantic_summary: o.semantic_summary,
|
|
28
|
+
summary_of_hash: typeof o.summary_of_hash === "string" ? o.summary_of_hash : "",
|
|
29
|
+
summary_model: typeof o.summary_model === "string" ? o.summary_model : "",
|
|
30
|
+
summary_at: typeof o.summary_at === "string" ? o.summary_at : "",
|
|
31
|
+
summary_by: typeof o.summary_by === "string" ? o.summary_by : "",
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// skip malformed line
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return map;
|
|
40
|
+
}
|
|
41
|
+
/** Upserts one record and rewrites the sidecar sorted by id (deterministic, no
|
|
42
|
+
* duplicate lines). Creates the local/ dir if needed. Best-effort. */
|
|
43
|
+
export function upsertSidecar(path, rec) {
|
|
44
|
+
const map = readSidecar(path);
|
|
45
|
+
map.set(rec.id, rec);
|
|
46
|
+
const lines = [...map.keys()].sort().map((id) => {
|
|
47
|
+
const r = map.get(id);
|
|
48
|
+
return JSON.stringify({
|
|
49
|
+
id: r.id,
|
|
50
|
+
semantic_summary: r.semantic_summary,
|
|
51
|
+
summary_at: r.summary_at,
|
|
52
|
+
summary_by: r.summary_by,
|
|
53
|
+
summary_model: r.summary_model,
|
|
54
|
+
summary_of_hash: r.summary_of_hash,
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
try {
|
|
58
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
59
|
+
writeFileSync(path, lines.length ? lines.join("\n") + "\n" : "");
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
// best-effort; a write failure must not break the tool call
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=sidecar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sidecar.js","sourceRoot":"","sources":["../../src/store/sidecar.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { GraphStore } from "../store/GraphStore.js";
|
|
2
|
+
import type { ToolResult } from "./readCypher.js";
|
|
3
|
+
export interface GetContextProfileArgs {
|
|
4
|
+
node_id?: string;
|
|
5
|
+
file_path?: string;
|
|
6
|
+
name?: string;
|
|
7
|
+
hops?: number;
|
|
8
|
+
federated?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function makeGetContextProfile(store: GraphStore, repoId: string): (args: GetContextProfileArgs) => Promise<ToolResult>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { resolveTarget } from "../profile/resolve.js";
|
|
2
|
+
import { assembleProfile } from "../profile/assemble.js";
|
|
3
|
+
import { federationIds } from "../store/federation.js";
|
|
4
|
+
export function makeGetContextProfile(store, repoId) {
|
|
5
|
+
return async (args) => {
|
|
6
|
+
const sel = { node_id: args.node_id, file_path: args.file_path, name: args.name };
|
|
7
|
+
if (!sel.node_id && !sel.name && !sel.file_path) {
|
|
8
|
+
return {
|
|
9
|
+
content: [{ type: "text", text: "provide one of: node_id, file_path+name, or name" }],
|
|
10
|
+
isError: true,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
const hops = args.hops === 2 ? 2 : 1;
|
|
14
|
+
try {
|
|
15
|
+
const repoIds = args.federated ? await federationIds(store, repoId) : [repoId];
|
|
16
|
+
const resolved = await resolveTarget(store, repoIds, sel);
|
|
17
|
+
if (resolved.kind === "not_found") {
|
|
18
|
+
return { content: [{ type: "text", text: JSON.stringify({ error: "target not found" }) }], isError: true };
|
|
19
|
+
}
|
|
20
|
+
if (resolved.kind === "candidates") {
|
|
21
|
+
return {
|
|
22
|
+
content: [{
|
|
23
|
+
type: "text",
|
|
24
|
+
text: JSON.stringify({
|
|
25
|
+
ambiguous: true,
|
|
26
|
+
candidates: resolved.candidates.map((c) => ({
|
|
27
|
+
id: c.id,
|
|
28
|
+
name: c.qualified_name,
|
|
29
|
+
file_path: c.file_path,
|
|
30
|
+
repo_id: c.repo_id,
|
|
31
|
+
})),
|
|
32
|
+
}),
|
|
33
|
+
}],
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
const profile = await assembleProfile(store, repoIds, resolved.target, hops);
|
|
37
|
+
return { content: [{ type: "text", text: JSON.stringify(profile) }] };
|
|
38
|
+
}
|
|
39
|
+
catch (e) {
|
|
40
|
+
return { content: [{ type: "text", text: e.message }], isError: true };
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=getContextProfile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getContextProfile.js","sourceRoot":"","sources":["../../src/tools/getContextProfile.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAiB,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAWvD,MAAM,UAAU,qBAAqB,CAAC,KAAiB,EAAE,MAAc;IACrE,OAAO,KAAK,EAAE,IAA2B,EAAuB,EAAE;QAChE,MAAM,GAAG,GAAa,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5F,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;YAChD,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,kDAAkD,EAAE,CAAC;gBACrF,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,GAAU,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5C,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAC/E,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;YAC1D,IAAI,QAAQ,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;gBAClC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YAC7G,CAAC;YACD,IAAI,QAAQ,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBACnC,OAAO;oBACL,OAAO,EAAE,CAAC;4BACR,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gCACnB,SAAS,EAAE,IAAI;gCACf,UAAU,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oCAC1C,EAAE,EAAE,CAAC,CAAC,EAAE;oCACR,IAAI,EAAE,CAAC,CAAC,cAAc;oCACtB,SAAS,EAAE,CAAC,CAAC,SAAS;oCACtB,OAAO,EAAE,CAAC,CAAC,OAAO;iCACnB,CAAC,CAAC;6BACJ,CAAC;yBACH,CAAC;iBACH,CAAC;YACJ,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAC7E,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;QACxE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAG,CAAW,CAAC,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QACpF,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ToolResult } from "./readCypher.js";
|
|
2
|
+
export type RunResult = {
|
|
3
|
+
ok: true;
|
|
4
|
+
nodes: number;
|
|
5
|
+
edges: number;
|
|
6
|
+
files: number;
|
|
7
|
+
warnings: string[];
|
|
8
|
+
} | {
|
|
9
|
+
ok: false;
|
|
10
|
+
error: string;
|
|
11
|
+
};
|
|
12
|
+
export interface RunOpts {
|
|
13
|
+
verb?: "index" | "reindex";
|
|
14
|
+
file?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface IndexerDeps {
|
|
17
|
+
run: (repoId: string, path: string, opts?: RunOpts) => Promise<RunResult>;
|
|
18
|
+
}
|
|
19
|
+
export interface InitArgs {
|
|
20
|
+
path?: string;
|
|
21
|
+
full?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export declare function makeInitCpgSkeleton(repoId: string, deps?: Partial<IndexerDeps>): (args: InitArgs) => Promise<ToolResult>;
|
|
24
|
+
export interface ReindexArgs {
|
|
25
|
+
path: string;
|
|
26
|
+
}
|
|
27
|
+
export declare function makeReindexFile(repoId: string, deps?: Partial<IndexerDeps>): (args: ReindexArgs) => Promise<ToolResult>;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { spawnIndexer, parseJsonStats, repoPath, shouldLoadNeo4j, } from "../indexer/runIndexer.js";
|
|
2
|
+
import { ensureIndexerBinary } from "../indexer/fetchBinary.js";
|
|
3
|
+
/** Default runner: run the index/reindex verb with --json, then load into Neo4j
|
|
4
|
+
* unless we're in JSONL mode (shouldLoadNeo4j() === false). */
|
|
5
|
+
function defaultRun(repoId, indexPath, opts) {
|
|
6
|
+
const verb = opts?.verb ?? "index";
|
|
7
|
+
return (async () => {
|
|
8
|
+
const bin = await ensureIndexerBinary();
|
|
9
|
+
const verbArgs = verb === "reindex"
|
|
10
|
+
? ["reindex", "--json", "--repo-id", repoId, indexPath, ...(opts?.file ? ["--file", opts.file] : [])]
|
|
11
|
+
: ["index", "--json", "--repo-id", repoId, indexPath];
|
|
12
|
+
const idx = await spawnIndexer(bin, verbArgs);
|
|
13
|
+
if (idx.code !== 0)
|
|
14
|
+
return { ok: false, error: `${verb} failed: ${idx.stderr || idx.stdout}` };
|
|
15
|
+
const stats = parseJsonStats(idx.stdout);
|
|
16
|
+
if (!stats)
|
|
17
|
+
return { ok: false, error: `${verb} --json returned unparseable output: ${idx.stdout}` };
|
|
18
|
+
if (shouldLoadNeo4j()) {
|
|
19
|
+
const load = await spawnIndexer(bin, ["load", "--repo-id", repoId, indexPath]);
|
|
20
|
+
if (load.code !== 0)
|
|
21
|
+
return { ok: false, error: `load failed: ${load.stderr || load.stdout}` };
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
ok: true,
|
|
25
|
+
nodes: stats.nodes,
|
|
26
|
+
edges: stats.edges,
|
|
27
|
+
files: stats.files,
|
|
28
|
+
warnings: stats.warnings ?? [],
|
|
29
|
+
};
|
|
30
|
+
})();
|
|
31
|
+
}
|
|
32
|
+
function makeRunner(repoId, deps) {
|
|
33
|
+
const run = deps?.run ?? ((id, path, opts) => defaultRun(id, path, opts));
|
|
34
|
+
return run;
|
|
35
|
+
}
|
|
36
|
+
export function makeInitCpgSkeleton(repoId, deps) {
|
|
37
|
+
const run = makeRunner(repoId, deps);
|
|
38
|
+
return async (args) => {
|
|
39
|
+
const indexPath = args?.path ?? repoPath();
|
|
40
|
+
const start = Date.now();
|
|
41
|
+
const r = await run(repoId, indexPath);
|
|
42
|
+
if (!r.ok) {
|
|
43
|
+
return { content: [{ type: "text", text: r.error }], isError: true };
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
content: [{
|
|
47
|
+
type: "text",
|
|
48
|
+
text: JSON.stringify({
|
|
49
|
+
ok: true,
|
|
50
|
+
nodes: r.nodes,
|
|
51
|
+
edges: r.edges,
|
|
52
|
+
files: r.files,
|
|
53
|
+
duration_ms: Date.now() - start,
|
|
54
|
+
warnings: r.warnings,
|
|
55
|
+
}),
|
|
56
|
+
}],
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
export function makeReindexFile(repoId, deps) {
|
|
61
|
+
const run = makeRunner(repoId, deps);
|
|
62
|
+
return async (args) => {
|
|
63
|
+
if (!args || !args.path) {
|
|
64
|
+
return { content: [{ type: "text", text: "reindex_file requires a 'path'" }], isError: true };
|
|
65
|
+
}
|
|
66
|
+
const indexPath = repoPath();
|
|
67
|
+
const start = Date.now();
|
|
68
|
+
const r = await run(repoId, indexPath, { verb: "reindex", file: args.path });
|
|
69
|
+
if (!r.ok) {
|
|
70
|
+
return { content: [{ type: "text", text: r.error }], isError: true };
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
content: [{
|
|
74
|
+
type: "text",
|
|
75
|
+
text: JSON.stringify({
|
|
76
|
+
ok: true,
|
|
77
|
+
reindexed: args.path,
|
|
78
|
+
nodes: r.nodes,
|
|
79
|
+
edges: r.edges,
|
|
80
|
+
files: r.files,
|
|
81
|
+
duration_ms: Date.now() - start,
|
|
82
|
+
loaded: shouldLoadNeo4j(),
|
|
83
|
+
warnings: r.warnings,
|
|
84
|
+
}),
|
|
85
|
+
}],
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=indexerTools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexerTools.js","sourceRoot":"","sources":["../../src/tools/indexerTools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { GraphStore } from "../store/GraphStore.js";
|
|
2
|
+
export interface ReadCypherArgs {
|
|
3
|
+
query: string;
|
|
4
|
+
params?: Record<string, unknown>;
|
|
5
|
+
federated?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface ToolResult {
|
|
8
|
+
[key: string]: unknown;
|
|
9
|
+
content: {
|
|
10
|
+
type: "text";
|
|
11
|
+
text: string;
|
|
12
|
+
}[];
|
|
13
|
+
isError?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/** Builds the read_cypher handler bound to a store and (optional) repo scope. */
|
|
16
|
+
export declare function makeReadCypher(store: GraphStore, repoId?: string): (args: ReadCypherArgs) => Promise<ToolResult>;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { assertReadOnly } from "../guard/readonly.js";
|
|
2
|
+
import { applyCaps } from "../guard/caps.js";
|
|
3
|
+
import { federationIds } from "../store/federation.js";
|
|
4
|
+
/** Builds the read_cypher handler bound to a store and (optional) repo scope. */
|
|
5
|
+
export function makeReadCypher(store, repoId) {
|
|
6
|
+
return async (args) => {
|
|
7
|
+
const { query, params } = args;
|
|
8
|
+
try {
|
|
9
|
+
assertReadOnly(query);
|
|
10
|
+
}
|
|
11
|
+
catch (e) {
|
|
12
|
+
return {
|
|
13
|
+
content: [{ type: "text", text: e.message }],
|
|
14
|
+
isError: true,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
const merged = { ...(params ?? {}) };
|
|
18
|
+
if (repoId !== undefined) {
|
|
19
|
+
merged.repo_id = repoId;
|
|
20
|
+
merged.repo_ids = args.federated ? await federationIds(store, repoId) : [repoId];
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
const rows = await store.runRead(query, merged, { timeoutMs: 10_000 });
|
|
24
|
+
const { rows: capped, truncated } = applyCaps(rows);
|
|
25
|
+
return {
|
|
26
|
+
content: [
|
|
27
|
+
{ type: "text", text: JSON.stringify({ rows: capped, truncated }) },
|
|
28
|
+
],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
catch (e) {
|
|
32
|
+
// Verbatim Neo4j message so the agent can self-correct (PRD §7.2).
|
|
33
|
+
return {
|
|
34
|
+
content: [{ type: "text", text: e.message }],
|
|
35
|
+
isError: true,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=readCypher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readCypher.js","sourceRoot":"","sources":["../../src/tools/readCypher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAcvD,iFAAiF;AACjF,MAAM,UAAU,cAAc,CAAC,KAAiB,EAAE,MAAe;IAC/D,OAAO,KAAK,EAAE,IAAoB,EAAuB,EAAE;QACzD,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QAC/B,IAAI,CAAC;YACH,cAAc,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAG,CAAW,CAAC,OAAO,EAAE,CAAC;gBACvD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAA4B,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC;QAC9D,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC;YACxB,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACnF,CAAC;QACD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;YACvE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;YACpD,OAAO;gBACL,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE;iBACpE;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,mEAAmE;YACnE,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAG,CAAW,CAAC,OAAO,EAAE,CAAC;gBACvD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { GraphStore } from "../store/GraphStore.js";
|
|
2
|
+
import type { ToolResult } from "./readCypher.js";
|
|
3
|
+
export interface WriteSummaryArgs {
|
|
4
|
+
node_id: string;
|
|
5
|
+
summary: string;
|
|
6
|
+
model?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function makeWriteSemanticSummary(store: GraphStore, repoId: string): (args: WriteSummaryArgs) => Promise<ToolResult>;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { sanitizeSummary } from "../guard/summaryValidation.js";
|
|
2
|
+
function today() {
|
|
3
|
+
// Day-precision ISO date (PRD §6.2.5: no wall-clock timestamps in output).
|
|
4
|
+
return new Date().toISOString().slice(0, 10);
|
|
5
|
+
}
|
|
6
|
+
export function makeWriteSemanticSummary(store, repoId) {
|
|
7
|
+
return async (args) => {
|
|
8
|
+
const v = sanitizeSummary(args.summary);
|
|
9
|
+
if (!v.ok) {
|
|
10
|
+
return { content: [{ type: "text", text: v.error }], isError: true };
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
const res = await store.writeSummary(repoId, args.node_id, {
|
|
14
|
+
summary: v.value,
|
|
15
|
+
model: args.model ?? "unknown",
|
|
16
|
+
at: today(),
|
|
17
|
+
by: process.env.REPOSKEIN_AGENT ?? "agent",
|
|
18
|
+
});
|
|
19
|
+
if (res.kind === "not_found") {
|
|
20
|
+
return {
|
|
21
|
+
content: [{ type: "text", text: JSON.stringify({ error: "node not found" }) }],
|
|
22
|
+
isError: true,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
if (res.kind === "no_content_hash") {
|
|
26
|
+
return {
|
|
27
|
+
content: [{ type: "text", text: JSON.stringify({ error: "node has no content_hash; not summarizable" }) }],
|
|
28
|
+
isError: true,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
content: [{ type: "text", text: JSON.stringify({ ok: true, stale_replaced: res.stale_replaced }) }],
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
return { content: [{ type: "text", text: e.message }], isError: true };
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=writeSemanticSummary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writeSemanticSummary.js","sourceRoot":"","sources":["../../src/tools/writeSemanticSummary.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAShE,SAAS,KAAK;IACZ,2EAA2E;IAC3E,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAiB,EAAE,MAAc;IACxE,OAAO,KAAK,EAAE,IAAsB,EAAuB,EAAE;QAC3D,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YACV,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QACvE,CAAC;QACD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE;gBACzD,OAAO,EAAE,CAAC,CAAC,KAAK;gBAChB,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,SAAS;gBAC9B,EAAE,EAAE,KAAK,EAAE;gBACX,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,OAAO;aAC3C,CAAC,CAAC;YACH,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;gBAC7B,OAAO;oBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC;oBAC9E,OAAO,EAAE,IAAI;iBACd,CAAC;YACJ,CAAC;YACD,IAAI,GAAG,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;gBACnC,OAAO;oBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,4CAA4C,EAAE,CAAC,EAAE,CAAC;oBAC1G,OAAO,EAAE,IAAI;iBACd,CAAC;YACJ,CAAC;YACD,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC;aACpG,CAAC;QACJ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAG,CAAW,CAAC,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QACpF,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|