archmantic 1.0.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/LICENSE +202 -0
- package/README.md +172 -0
- package/dist/agent.d.ts +20 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +239 -0
- package/dist/agent.js.map +1 -0
- package/dist/analyze/datamodel.d.ts +9 -0
- package/dist/analyze/datamodel.d.ts.map +1 -0
- package/dist/analyze/datamodel.js +19 -0
- package/dist/analyze/datamodel.js.map +1 -0
- package/dist/analyze/derive.d.ts +21 -0
- package/dist/analyze/derive.d.ts.map +1 -0
- package/dist/analyze/derive.js +211 -0
- package/dist/analyze/derive.js.map +1 -0
- package/dist/analyze/drizzle.d.ts +3 -0
- package/dist/analyze/drizzle.d.ts.map +1 -0
- package/dist/analyze/drizzle.js +83 -0
- package/dist/analyze/drizzle.js.map +1 -0
- package/dist/analyze/endpoints.d.ts +3 -0
- package/dist/analyze/endpoints.d.ts.map +1 -0
- package/dist/analyze/endpoints.js +167 -0
- package/dist/analyze/endpoints.js.map +1 -0
- package/dist/analyze/fs-util.d.ts +3 -0
- package/dist/analyze/fs-util.d.ts.map +1 -0
- package/dist/analyze/fs-util.js +44 -0
- package/dist/analyze/fs-util.js.map +1 -0
- package/dist/analyze/incremental.d.ts +12 -0
- package/dist/analyze/incremental.d.ts.map +1 -0
- package/dist/analyze/incremental.js +102 -0
- package/dist/analyze/incremental.js.map +1 -0
- package/dist/analyze/index.d.ts +5 -0
- package/dist/analyze/index.d.ts.map +1 -0
- package/dist/analyze/index.js +49 -0
- package/dist/analyze/index.js.map +1 -0
- package/dist/analyze/parse-util.d.ts +10 -0
- package/dist/analyze/parse-util.d.ts.map +1 -0
- package/dist/analyze/parse-util.js +47 -0
- package/dist/analyze/parse-util.js.map +1 -0
- package/dist/analyze/prisma.d.ts +4 -0
- package/dist/analyze/prisma.d.ts.map +1 -0
- package/dist/analyze/prisma.js +97 -0
- package/dist/analyze/prisma.js.map +1 -0
- package/dist/analyze/sql.d.ts +3 -0
- package/dist/analyze/sql.d.ts.map +1 -0
- package/dist/analyze/sql.js +110 -0
- package/dist/analyze/sql.js.map +1 -0
- package/dist/analyze/stack.d.ts +4 -0
- package/dist/analyze/stack.d.ts.map +1 -0
- package/dist/analyze/stack.js +94 -0
- package/dist/analyze/stack.js.map +1 -0
- package/dist/analyze/tier0.d.ts +7 -0
- package/dist/analyze/tier0.d.ts.map +1 -0
- package/dist/analyze/tier0.js +57 -0
- package/dist/analyze/tier0.js.map +1 -0
- package/dist/analyze/tier1.d.ts +13 -0
- package/dist/analyze/tier1.d.ts.map +1 -0
- package/dist/analyze/tier1.js +144 -0
- package/dist/analyze/tier1.js.map +1 -0
- package/dist/analyze/tier2.d.ts +14 -0
- package/dist/analyze/tier2.d.ts.map +1 -0
- package/dist/analyze/tier2.js +231 -0
- package/dist/analyze/tier2.js.map +1 -0
- package/dist/analyze/walk.d.ts +3 -0
- package/dist/analyze/walk.d.ts.map +1 -0
- package/dist/analyze/walk.js +50 -0
- package/dist/analyze/walk.js.map +1 -0
- package/dist/auth.d.ts +12 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +61 -0
- package/dist/auth.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +787 -0
- package/dist/cli.js.map +1 -0
- package/dist/cloud/api.d.ts +20 -0
- package/dist/cloud/api.d.ts.map +1 -0
- package/dist/cloud/api.js +81 -0
- package/dist/cloud/api.js.map +1 -0
- package/dist/cloud/index.d.ts +4 -0
- package/dist/cloud/index.d.ts.map +1 -0
- package/dist/cloud/index.js +20 -0
- package/dist/cloud/index.js.map +1 -0
- package/dist/cloud/store.d.ts +34 -0
- package/dist/cloud/store.d.ts.map +1 -0
- package/dist/cloud/store.js +137 -0
- package/dist/cloud/store.js.map +1 -0
- package/dist/diff/history.d.ts +9 -0
- package/dist/diff/history.d.ts.map +1 -0
- package/dist/diff/history.js +44 -0
- package/dist/diff/history.js.map +1 -0
- package/dist/diff/index.d.ts +5 -0
- package/dist/diff/index.d.ts.map +1 -0
- package/dist/diff/index.js +26 -0
- package/dist/diff/index.js.map +1 -0
- package/dist/diff/model-diff.d.ts +44 -0
- package/dist/diff/model-diff.d.ts.map +1 -0
- package/dist/diff/model-diff.js +153 -0
- package/dist/diff/model-diff.js.map +1 -0
- package/dist/diff/snapshot.d.ts +8 -0
- package/dist/diff/snapshot.d.ts.map +1 -0
- package/dist/diff/snapshot.js +50 -0
- package/dist/diff/snapshot.js.map +1 -0
- package/dist/env.d.ts +2 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +44 -0
- package/dist/env.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/ir/naming.d.ts +12 -0
- package/dist/ir/naming.d.ts.map +1 -0
- package/dist/ir/naming.js +31 -0
- package/dist/ir/naming.js.map +1 -0
- package/dist/ir/types.d.ts +149 -0
- package/dist/ir/types.d.ts.map +1 -0
- package/dist/ir/types.js +72 -0
- package/dist/ir/types.js.map +1 -0
- package/dist/mcp/bench.d.ts +25 -0
- package/dist/mcp/bench.d.ts.map +1 -0
- package/dist/mcp/bench.js +115 -0
- package/dist/mcp/bench.js.map +1 -0
- package/dist/mcp/queries.d.ts +22 -0
- package/dist/mcp/queries.d.ts.map +1 -0
- package/dist/mcp/queries.js +147 -0
- package/dist/mcp/queries.js.map +1 -0
- package/dist/mcp/server.d.ts +2 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +147 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/usage.d.ts +23 -0
- package/dist/mcp/usage.d.ts.map +1 -0
- package/dist/mcp/usage.js +125 -0
- package/dist/mcp/usage.js.map +1 -0
- package/dist/project/bpmn-parse.d.ts +17 -0
- package/dist/project/bpmn-parse.d.ts.map +1 -0
- package/dist/project/bpmn-parse.js +60 -0
- package/dist/project/bpmn-parse.js.map +1 -0
- package/dist/project/bpmn.d.ts +11 -0
- package/dist/project/bpmn.d.ts.map +1 -0
- package/dist/project/bpmn.js +89 -0
- package/dist/project/bpmn.js.map +1 -0
- package/dist/project/capability.d.ts +16 -0
- package/dist/project/capability.d.ts.map +1 -0
- package/dist/project/capability.js +38 -0
- package/dist/project/capability.js.map +1 -0
- package/dist/project/erd.d.ts +17 -0
- package/dist/project/erd.d.ts.map +1 -0
- package/dist/project/erd.js +0 -0
- package/dist/project/erd.js.map +1 -0
- package/dist/project/html.d.ts +12 -0
- package/dist/project/html.d.ts.map +1 -0
- package/dist/project/html.js +166 -0
- package/dist/project/html.js.map +1 -0
- package/dist/project/index.d.ts +19 -0
- package/dist/project/index.d.ts.map +1 -0
- package/dist/project/index.js +113 -0
- package/dist/project/index.js.map +1 -0
- package/dist/project/mermaid.d.ts +20 -0
- package/dist/project/mermaid.d.ts.map +1 -0
- package/dist/project/mermaid.js +89 -0
- package/dist/project/mermaid.js.map +1 -0
- package/dist/project/spec.d.ts +69 -0
- package/dist/project/spec.d.ts.map +1 -0
- package/dist/project/spec.js +164 -0
- package/dist/project/spec.js.map +1 -0
- package/dist/project/trust.d.ts +35 -0
- package/dist/project/trust.d.ts.map +1 -0
- package/dist/project/trust.js +48 -0
- package/dist/project/trust.js.map +1 -0
- package/dist/system.d.ts +61 -0
- package/dist/system.d.ts.map +1 -0
- package/dist/system.js +161 -0
- package/dist/system.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type ArchitectureModel } from "../ir/types.js";
|
|
2
|
+
export interface BenchTask {
|
|
3
|
+
question: string;
|
|
4
|
+
mcpTool: string;
|
|
5
|
+
mcpAnswer: string;
|
|
6
|
+
rawFiles: string[];
|
|
7
|
+
}
|
|
8
|
+
export interface BenchRow extends BenchTask {
|
|
9
|
+
mcpTokens: number;
|
|
10
|
+
rawTokens: number;
|
|
11
|
+
savedPct: number;
|
|
12
|
+
}
|
|
13
|
+
export interface BenchReport {
|
|
14
|
+
rows: BenchRow[];
|
|
15
|
+
totalMcp: number;
|
|
16
|
+
totalRaw: number;
|
|
17
|
+
savedPct: number;
|
|
18
|
+
mode: "estimate" | "exact";
|
|
19
|
+
}
|
|
20
|
+
export type TokenCounter = (text: string) => Promise<number>;
|
|
21
|
+
/** Offline heuristic — clearly labeled as an estimate (≈ chars/4). */
|
|
22
|
+
export declare const estimateCounter: TokenCounter;
|
|
23
|
+
export declare function runBenchmark(root: string, model: ArchitectureModel, count: TokenCounter, mode: "estimate" | "exact"): Promise<BenchReport>;
|
|
24
|
+
export declare function renderBench(report: BenchReport): string;
|
|
25
|
+
//# sourceMappingURL=bench.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bench.d.ts","sourceRoot":"","sources":["../../src/mcp/bench.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAIxD,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,QAAS,SAAQ,SAAS;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC;CAC5B;AAED,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAE7D,sEAAsE;AACtE,eAAO,MAAM,eAAe,EAAE,YAAmD,CAAC;AA0DlF,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,iBAAiB,EACxB,KAAK,EAAE,YAAY,EACnB,IAAI,EAAE,UAAU,GAAG,OAAO,GACzB,OAAO,CAAC,WAAW,CAAC,CAatB;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAyBvD"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.estimateCounter = void 0;
|
|
4
|
+
exports.runBenchmark = runBenchmark;
|
|
5
|
+
exports.renderBench = renderBench;
|
|
6
|
+
/**
|
|
7
|
+
* Token-savings benchmark (the *second* proof). For a set of realistic
|
|
8
|
+
* architecture questions, compare the tokens an agent consumes answering via the
|
|
9
|
+
* Archmantic MCP tools vs. reading the raw source files it would otherwise need.
|
|
10
|
+
*
|
|
11
|
+
* Graph questions (dependencies, dependents, "what can this do?") are the win:
|
|
12
|
+
* the MCP answer is a few hundred tokens; the file-reading baseline is the whole
|
|
13
|
+
* subtree. Default counting is an offline estimate (chars/4); `--exact` uses the
|
|
14
|
+
* Anthropic token-counting endpoint (BYOK) for a precise number.
|
|
15
|
+
*/
|
|
16
|
+
const node_fs_1 = require("node:fs");
|
|
17
|
+
const node_path_1 = require("node:path");
|
|
18
|
+
const walk_js_1 = require("../analyze/walk.js");
|
|
19
|
+
const queries_js_1 = require("./queries.js");
|
|
20
|
+
/** Offline heuristic — clearly labeled as an estimate (≈ chars/4). */
|
|
21
|
+
const estimateCounter = async (t) => Math.ceil(t.length / 4);
|
|
22
|
+
exports.estimateCounter = estimateCounter;
|
|
23
|
+
function buildTasks(root, model) {
|
|
24
|
+
const src = (0, walk_js_1.walkSourceFiles)(root).filter((f) => f.startsWith("src/"));
|
|
25
|
+
return [
|
|
26
|
+
{
|
|
27
|
+
question: "What can this system do?",
|
|
28
|
+
mcpTool: "search_capabilities",
|
|
29
|
+
mcpAnswer: (0, queries_js_1.searchCapabilities)(model, ""),
|
|
30
|
+
rawFiles: src, // an agent would read the whole codebase to enumerate capabilities
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
question: "What is the overall architecture context?",
|
|
34
|
+
mcpTool: "get_context",
|
|
35
|
+
mcpAnswer: (0, queries_js_1.getContext)(model),
|
|
36
|
+
rawFiles: ["package.json", ...src],
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
question: "What does the analysis pipeline depend on and do?",
|
|
40
|
+
mcpTool: "get_component(analyze)",
|
|
41
|
+
mcpAnswer: (0, queries_js_1.getComponent)(model, "analyze/index.ts"),
|
|
42
|
+
rawFiles: [
|
|
43
|
+
"src/analyze/index.ts",
|
|
44
|
+
"src/analyze/walk.ts",
|
|
45
|
+
"src/analyze/tier0.ts",
|
|
46
|
+
"src/analyze/tier1.ts",
|
|
47
|
+
"src/analyze/derive.ts",
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
question: "What business process does the CLI implement?",
|
|
52
|
+
mcpTool: "get_process",
|
|
53
|
+
mcpAnswer: (0, queries_js_1.getProcess)(model),
|
|
54
|
+
rawFiles: ["src/cli.ts", "src/analyze/index.ts", "src/analyze/derive.ts"],
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
question: "What depends on the IR types module?",
|
|
58
|
+
mcpTool: "whats_related(ir/types)",
|
|
59
|
+
mcpAnswer: (0, queries_js_1.whatsRelated)(model, "ir/types.ts"),
|
|
60
|
+
rawFiles: src, // finding dependents without the model means scanning everything
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
function readFiles(root, files) {
|
|
65
|
+
const parts = [];
|
|
66
|
+
for (const f of files) {
|
|
67
|
+
const p = (0, node_path_1.join)(root, f);
|
|
68
|
+
if (!(0, node_fs_1.existsSync)(p))
|
|
69
|
+
continue;
|
|
70
|
+
try {
|
|
71
|
+
parts.push((0, node_fs_1.readFileSync)(p, "utf8"));
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
/* skip */
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return parts.join("\n");
|
|
78
|
+
}
|
|
79
|
+
async function runBenchmark(root, model, count, mode) {
|
|
80
|
+
const tasks = buildTasks(root, model);
|
|
81
|
+
const rows = [];
|
|
82
|
+
for (const t of tasks) {
|
|
83
|
+
const mcpTokens = await count(t.mcpAnswer);
|
|
84
|
+
const rawTokens = await count(readFiles(root, t.rawFiles));
|
|
85
|
+
const savedPct = rawTokens === 0 ? 0 : Math.round(((rawTokens - mcpTokens) / rawTokens) * 1000) / 10;
|
|
86
|
+
rows.push({ ...t, mcpTokens, rawTokens, savedPct });
|
|
87
|
+
}
|
|
88
|
+
const totalMcp = rows.reduce((n, r) => n + r.mcpTokens, 0);
|
|
89
|
+
const totalRaw = rows.reduce((n, r) => n + r.rawTokens, 0);
|
|
90
|
+
const savedPct = totalRaw === 0 ? 0 : Math.round(((totalRaw - totalMcp) / totalRaw) * 1000) / 10;
|
|
91
|
+
return { rows, totalMcp, totalRaw, savedPct, mode };
|
|
92
|
+
}
|
|
93
|
+
function renderBench(report) {
|
|
94
|
+
const BOLD = "\x1b[1m";
|
|
95
|
+
const DIM = "\x1b[2m";
|
|
96
|
+
const GREEN = "\x1b[32m";
|
|
97
|
+
const RESET = "\x1b[0m";
|
|
98
|
+
const out = [];
|
|
99
|
+
out.push(`${BOLD}Token-savings benchmark${RESET} ${DIM}(MCP query vs. raw file reads · ${report.mode} counts)${RESET}`);
|
|
100
|
+
out.push("");
|
|
101
|
+
for (const r of report.rows) {
|
|
102
|
+
out.push(`${BOLD}${r.question}${RESET}`);
|
|
103
|
+
out.push(` via MCP ${DIM}(${r.mcpTool})${RESET}: ${r.mcpTokens} tok ` +
|
|
104
|
+
`via files ${DIM}(${r.rawFiles.length} files)${RESET}: ${r.rawTokens} tok ` +
|
|
105
|
+
`${GREEN}−${r.savedPct}%${RESET}`);
|
|
106
|
+
}
|
|
107
|
+
out.push("");
|
|
108
|
+
out.push(`${BOLD}Total:${RESET} ${report.totalMcp} tok via MCP vs ${report.totalRaw} tok via files → ` +
|
|
109
|
+
`${GREEN}${BOLD}${report.savedPct}% fewer tokens${RESET}`);
|
|
110
|
+
if (report.mode === "estimate") {
|
|
111
|
+
out.push(`${DIM}Estimated (≈ chars/4). Run \`archmantic bench --exact\` (needs ANTHROPIC_API_KEY) for precise counts.${RESET}`);
|
|
112
|
+
}
|
|
113
|
+
return out.join("\n");
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=bench.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bench.js","sourceRoot":"","sources":["../../src/mcp/bench.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read queries over the IR — the data plane behind both the MCP server and the
|
|
3
|
+
* token-savings benchmark. Pure functions: model in, compact grounded text out.
|
|
4
|
+
*
|
|
5
|
+
* The whole MCP value prop is that an agent gets exactly the architectural slice
|
|
6
|
+
* it needs (a few hundred tokens) instead of reading whole source files. Keep
|
|
7
|
+
* every answer tight and always carry the `file:line` grounding so the agent can
|
|
8
|
+
* cite/verify.
|
|
9
|
+
*/
|
|
10
|
+
import { type ArchitectureModel, type Component } from "../ir/types.js";
|
|
11
|
+
/** Resolve a loose name (id, path, basename, suffix) to a component. */
|
|
12
|
+
export declare function findComponent(model: ArchitectureModel, name: string): Component | undefined;
|
|
13
|
+
export declare function getContext(model: ArchitectureModel): string;
|
|
14
|
+
export declare function listComponents(model: ArchitectureModel, filter?: string): string;
|
|
15
|
+
export declare function getComponent(model: ArchitectureModel, name: string): string;
|
|
16
|
+
export declare function searchCapabilities(model: ArchitectureModel, query: string): string;
|
|
17
|
+
export declare function getProcess(model: ArchitectureModel): string;
|
|
18
|
+
export declare function getSequence(model: ArchitectureModel): string;
|
|
19
|
+
export declare function getDataModel(model: ArchitectureModel): string;
|
|
20
|
+
export declare function getApiSurface(model: ArchitectureModel): string;
|
|
21
|
+
export declare function whatsRelated(model: ArchitectureModel, name: string): string;
|
|
22
|
+
//# sourceMappingURL=queries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../src/mcp/queries.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAiBxE,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAU3F;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAa3D;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAMhF;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAgB3E;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CASlF;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAO3D;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAM5D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAqB7D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAW9D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAM3E"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.findComponent = findComponent;
|
|
4
|
+
exports.getContext = getContext;
|
|
5
|
+
exports.listComponents = listComponents;
|
|
6
|
+
exports.getComponent = getComponent;
|
|
7
|
+
exports.searchCapabilities = searchCapabilities;
|
|
8
|
+
exports.getProcess = getProcess;
|
|
9
|
+
exports.getSequence = getSequence;
|
|
10
|
+
exports.getDataModel = getDataModel;
|
|
11
|
+
exports.getApiSurface = getApiSurface;
|
|
12
|
+
exports.whatsRelated = whatsRelated;
|
|
13
|
+
const naming_js_1 = require("../ir/naming.js");
|
|
14
|
+
const rel = (id) => id.slice(id.indexOf(":") + 1);
|
|
15
|
+
/** Short display name: folder-aware component label, or external system name. */
|
|
16
|
+
const shortName = (id) => id.startsWith("comp:")
|
|
17
|
+
? (0, naming_js_1.componentLabel)(id)
|
|
18
|
+
: id.startsWith("sys:ext:")
|
|
19
|
+
? id.slice("sys:ext:".length)
|
|
20
|
+
: id;
|
|
21
|
+
function refOf(el) {
|
|
22
|
+
return el.provenance[0]?.ref ?? "?";
|
|
23
|
+
}
|
|
24
|
+
/** Resolve a loose name (id, path, basename, suffix) to a component. */
|
|
25
|
+
function findComponent(model, name) {
|
|
26
|
+
const n = name.trim();
|
|
27
|
+
const r = n.startsWith("comp:") ? n.slice("comp:".length) : n;
|
|
28
|
+
return (model.components.find((c) => c.id === n) ??
|
|
29
|
+
model.components.find((c) => rel(c.id) === r) ??
|
|
30
|
+
model.components.find((c) => rel(c.id).endsWith("/" + r)) ??
|
|
31
|
+
model.components.find((c) => (0, naming_js_1.componentLabel)(c.id).toLowerCase() === r.toLowerCase()) ??
|
|
32
|
+
model.components.find((c) => rel(c.id).split("/").pop() === r));
|
|
33
|
+
}
|
|
34
|
+
function getContext(model) {
|
|
35
|
+
const internal = model.systems.find((s) => s.kind === "internal");
|
|
36
|
+
const externals = model.systems.filter((s) => s.kind === "external");
|
|
37
|
+
const internalDeps = model.relations.filter((r) => r.to.startsWith("comp:")).length;
|
|
38
|
+
const lines = [
|
|
39
|
+
`Project: ${model.project}`,
|
|
40
|
+
internal ? `System: ${internal.name} — ${internal.description ?? "internal system"}` : "",
|
|
41
|
+
`Components: ${model.components.length} · internal dependencies: ${internalDeps}`,
|
|
42
|
+
`External systems (${externals.length}): ${externals.map((s) => s.name).join(", ") || "none"}`,
|
|
43
|
+
`Capabilities: ${model.capabilities.length} · processes: ${model.processes.length} · flows: ${model.flows.length}`,
|
|
44
|
+
];
|
|
45
|
+
if (model.processes[0])
|
|
46
|
+
lines.push(`Primary process: ${model.processes[0].name}`);
|
|
47
|
+
return lines.filter(Boolean).join("\n");
|
|
48
|
+
}
|
|
49
|
+
function listComponents(model, filter) {
|
|
50
|
+
const f = filter?.trim().toLowerCase();
|
|
51
|
+
const rows = model.components
|
|
52
|
+
.filter((c) => !f || rel(c.id).toLowerCase().includes(f) || c.name.toLowerCase().includes(f))
|
|
53
|
+
.map((c) => `- ${(0, naming_js_1.componentLabel)(c.id)} (${rel(c.id)})${c.responsibility ? ` — ${c.responsibility}` : ""}`);
|
|
54
|
+
return rows.length ? rows.join("\n") : "(no matching components)";
|
|
55
|
+
}
|
|
56
|
+
function getComponent(model, name) {
|
|
57
|
+
const c = findComponent(model, name);
|
|
58
|
+
if (!c)
|
|
59
|
+
return `No component matches "${name}". Try \`list_components\`.`;
|
|
60
|
+
const out = model.relations.filter((r) => r.from === c.id).map((r) => `${shortName(r.to)} (${refOf(r)})`);
|
|
61
|
+
const inc = model.relations.filter((r) => r.to === c.id).map((r) => (0, naming_js_1.componentLabel)(r.from));
|
|
62
|
+
const caps = model.capabilities.filter((cap) => cap.componentIds.includes(c.id)).map((cap) => cap.name);
|
|
63
|
+
return [
|
|
64
|
+
`${(0, naming_js_1.componentLabel)(c.id)} [${rel(c.id)}]`,
|
|
65
|
+
c.responsibility ? `Responsibility: ${c.responsibility}` : "",
|
|
66
|
+
`Confidence: ${c.confidence} · grounded: ${refOf(c)}`,
|
|
67
|
+
`Depends on (${out.length}): ${out.join(", ") || "—"}`,
|
|
68
|
+
`Used by (${inc.length}): ${inc.join(", ") || "—"}`,
|
|
69
|
+
caps.length ? `Capabilities: ${caps.join(", ")}` : "",
|
|
70
|
+
]
|
|
71
|
+
.filter(Boolean)
|
|
72
|
+
.join("\n");
|
|
73
|
+
}
|
|
74
|
+
function searchCapabilities(model, query) {
|
|
75
|
+
const q = query.trim().toLowerCase();
|
|
76
|
+
const hits = model.capabilities.filter((cap) => !q || cap.name.toLowerCase().includes(q) || (cap.description ?? "").toLowerCase().includes(q));
|
|
77
|
+
if (!hits.length)
|
|
78
|
+
return `No capabilities match "${query}".`;
|
|
79
|
+
return hits
|
|
80
|
+
.map((cap) => `- ${cap.name}: ${cap.description ?? "(no description)"} [${refOf(cap)}]`)
|
|
81
|
+
.join("\n");
|
|
82
|
+
}
|
|
83
|
+
function getProcess(model) {
|
|
84
|
+
const p = model.processes[0];
|
|
85
|
+
if (!p)
|
|
86
|
+
return "No process derived.";
|
|
87
|
+
const steps = p.tasks.map((t, i) => `${i + 1}. ${t.name}`).join("\n");
|
|
88
|
+
return [`Process: ${p.name}`, p.description ?? "", `Steps:`, steps, `(grounded: ${refOf(p)}, confidence ${p.confidence})`]
|
|
89
|
+
.filter(Boolean)
|
|
90
|
+
.join("\n");
|
|
91
|
+
}
|
|
92
|
+
function getSequence(model) {
|
|
93
|
+
const f = model.flows[0];
|
|
94
|
+
if (!f)
|
|
95
|
+
return "No flow derived.";
|
|
96
|
+
const nameFor = (id) => (id.startsWith("comp:") ? (0, naming_js_1.componentLabel)(id) : id);
|
|
97
|
+
const steps = f.steps.map((s) => `${nameFor(s.participant)} ${s.action} ${nameFor(s.to ?? s.participant)}`);
|
|
98
|
+
return [`Sequence: ${f.name}`, ...steps].join("\n");
|
|
99
|
+
}
|
|
100
|
+
function getDataModel(model) {
|
|
101
|
+
const entities = model.dataEntities ?? [];
|
|
102
|
+
if (!entities.length)
|
|
103
|
+
return "No data model detected (no Prisma schema found).";
|
|
104
|
+
const out = [`Data model: ${entities.length} entities`];
|
|
105
|
+
for (const e of entities) {
|
|
106
|
+
const cols = e.fields
|
|
107
|
+
.filter((f) => !(f.relationTo && !f.isForeignKey))
|
|
108
|
+
.map((f) => {
|
|
109
|
+
const tags = [f.isId ? "PK" : "", f.isForeignKey ? "FK" : "", f.isUnique && !f.isId ? "unique" : ""]
|
|
110
|
+
.filter(Boolean)
|
|
111
|
+
.join(" ");
|
|
112
|
+
return `${f.name}: ${f.type}${f.list ? "[]" : ""}${f.optional ? "?" : ""}${tags ? ` (${tags})` : ""}`;
|
|
113
|
+
});
|
|
114
|
+
const rels = e.fields
|
|
115
|
+
.filter((f) => f.relationTo)
|
|
116
|
+
.map((f) => `${f.name} → ${f.type}${f.list ? "[]" : ""}`);
|
|
117
|
+
out.push(`\n${e.name} [${refOf(e)}]`);
|
|
118
|
+
out.push(` fields: ${cols.join(", ") || "—"}`);
|
|
119
|
+
if (rels.length)
|
|
120
|
+
out.push(` relations: ${rels.join(", ")}`);
|
|
121
|
+
}
|
|
122
|
+
return out.join("\n");
|
|
123
|
+
}
|
|
124
|
+
function getApiSurface(model) {
|
|
125
|
+
const eps = model.endpoints ?? [];
|
|
126
|
+
if (!eps.length)
|
|
127
|
+
return "No API endpoints detected (no routes/procedures/GraphQL schema found).";
|
|
128
|
+
const byProto = new Map();
|
|
129
|
+
for (const e of eps)
|
|
130
|
+
(byProto.get(e.protocol) ?? byProto.set(e.protocol, []).get(e.protocol)).push(e);
|
|
131
|
+
const out = [`API surface: ${eps.length} endpoints`];
|
|
132
|
+
for (const [proto, list] of [...byProto.entries()].sort()) {
|
|
133
|
+
out.push(`\n${proto.toUpperCase()} (${list.length})`);
|
|
134
|
+
for (const e of list)
|
|
135
|
+
out.push(` ${e.method} ${e.path} [${refOf(e)}]`);
|
|
136
|
+
}
|
|
137
|
+
return out.join("\n");
|
|
138
|
+
}
|
|
139
|
+
function whatsRelated(model, name) {
|
|
140
|
+
const c = findComponent(model, name);
|
|
141
|
+
if (!c)
|
|
142
|
+
return `No component matches "${name}".`;
|
|
143
|
+
const out = model.relations.filter((r) => r.from === c.id).map((r) => `→ ${shortName(r.to)}`);
|
|
144
|
+
const inc = model.relations.filter((r) => r.to === c.id).map((r) => `← ${(0, naming_js_1.componentLabel)(r.from)}`);
|
|
145
|
+
return [`Related to ${(0, naming_js_1.componentLabel)(c.id)}:`, ...out, ...inc].join("\n") || "(no relations)";
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=queries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queries.js","sourceRoot":"","sources":["../../src/mcp/queries.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAmEA,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiKhE"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.startMcpServer = startMcpServer;
|
|
4
|
+
/**
|
|
5
|
+
* MCP server (USP 7: the diagram you edit *is* the context your agent queries).
|
|
6
|
+
* Exposes read tools over the committed IR so an agent (Claude Code, Cursor, …)
|
|
7
|
+
* gets exactly the architectural slice it needs instead of reading whole files.
|
|
8
|
+
*
|
|
9
|
+
* stdio transport: protocol travels on stdout, so all human logging goes to
|
|
10
|
+
* stderr. Built on the official @modelcontextprotocol/sdk.
|
|
11
|
+
*/
|
|
12
|
+
const node_fs_1 = require("node:fs");
|
|
13
|
+
const node_child_process_1 = require("node:child_process");
|
|
14
|
+
const node_path_1 = require("node:path");
|
|
15
|
+
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
16
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
17
|
+
const zod_1 = require("zod");
|
|
18
|
+
const types_js_1 = require("../ir/types.js");
|
|
19
|
+
const index_js_1 = require("../analyze/index.js");
|
|
20
|
+
const index_js_2 = require("../diff/index.js");
|
|
21
|
+
const index_js_3 = require("../cloud/index.js");
|
|
22
|
+
const usage_js_1 = require("./usage.js");
|
|
23
|
+
const queries_js_1 = require("./queries.js");
|
|
24
|
+
const MODEL_PATH = (0, node_path_1.join)(".archmantic", "model.json");
|
|
25
|
+
function loadModel(root) {
|
|
26
|
+
const file = (0, node_path_1.join)(root, MODEL_PATH);
|
|
27
|
+
if (!(0, node_fs_1.existsSync)(file)) {
|
|
28
|
+
throw new Error(`No model at ${MODEL_PATH}. Run \`archmantic analyze\` first.`);
|
|
29
|
+
}
|
|
30
|
+
return JSON.parse((0, node_fs_1.readFileSync)(file, "utf8"));
|
|
31
|
+
}
|
|
32
|
+
function currentCommit(root) {
|
|
33
|
+
try {
|
|
34
|
+
return (0, node_child_process_1.execFileSync)("git", ["-C", root, "rev-parse", "HEAD"], { encoding: "utf8" }).trim();
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return "working-tree";
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/** Re-analyze the repo from disk, persist canonically, and return the fresh model. */
|
|
41
|
+
function reanalyze(root) {
|
|
42
|
+
const model = { ...(0, index_js_1.analyzeRepo)(root), generatedAt: new Date().toISOString() };
|
|
43
|
+
const dir = (0, node_path_1.join)(root, ".archmantic");
|
|
44
|
+
(0, node_fs_1.mkdirSync)(dir, { recursive: true });
|
|
45
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(dir, "model.json"), (0, types_js_1.serializeModel)(model), "utf8");
|
|
46
|
+
return model;
|
|
47
|
+
}
|
|
48
|
+
const text = (s) => ({ content: [{ type: "text", text: s }] });
|
|
49
|
+
async function startMcpServer(root) {
|
|
50
|
+
// Mutable so `refresh`/`sync` update what the read tools serve.
|
|
51
|
+
let model = loadModel(root);
|
|
52
|
+
const server = new mcp_js_1.McpServer({ name: "archmantic", version: "1.0.0" });
|
|
53
|
+
// Usage stats: record each read tool, best-effort flush to the cloud (API if a
|
|
54
|
+
// token is set, else direct DB, else local-log only). Never breaks the agent.
|
|
55
|
+
const flushUsage = async (events) => {
|
|
56
|
+
if ((0, index_js_3.hasApiToken)())
|
|
57
|
+
await (0, index_js_3.recordUsageApi)(events);
|
|
58
|
+
else if (process.env.DATABASE_URL)
|
|
59
|
+
await (0, index_js_3.recordUsage)(events);
|
|
60
|
+
// no creds → local log only (still queryable via `archmantic usage`)
|
|
61
|
+
};
|
|
62
|
+
const usage = new usage_js_1.UsageRecorder(root, () => model.project, flushUsage);
|
|
63
|
+
usage.start();
|
|
64
|
+
/** Record the read, then return it as an MCP text result. */
|
|
65
|
+
const served = (tool, answer) => {
|
|
66
|
+
usage.record(tool, answer, new Date().toISOString());
|
|
67
|
+
return text(answer);
|
|
68
|
+
};
|
|
69
|
+
server.registerTool("get_context", {
|
|
70
|
+
title: "Get architecture context",
|
|
71
|
+
description: "High-level architecture context: project, systems, external dependencies, counts, primary process.",
|
|
72
|
+
}, async () => served("get_context", (0, queries_js_1.getContext)(model)));
|
|
73
|
+
server.registerTool("list_components", {
|
|
74
|
+
title: "List components",
|
|
75
|
+
description: "List components (optionally filtered by a substring) with their responsibilities.",
|
|
76
|
+
inputSchema: { filter: zod_1.z.string().optional().describe("optional substring to filter by path/name") },
|
|
77
|
+
}, async ({ filter }) => served("list_components", (0, queries_js_1.listComponents)(model, filter)));
|
|
78
|
+
server.registerTool("get_component", {
|
|
79
|
+
title: "Get component detail",
|
|
80
|
+
description: "Responsibility, dependencies, dependents, and capabilities for one component (by name or path).",
|
|
81
|
+
inputSchema: { name: zod_1.z.string().describe("component name, basename, or repo path") },
|
|
82
|
+
}, async ({ name }) => served("get_component", (0, queries_js_1.getComponent)(model, name)));
|
|
83
|
+
server.registerTool("search_capabilities", {
|
|
84
|
+
title: "Search capabilities",
|
|
85
|
+
description: "Plain-English 'what can this system do?' capabilities matching a query (empty = all).",
|
|
86
|
+
inputSchema: { query: zod_1.z.string().default("").describe("search text; empty returns all capabilities") },
|
|
87
|
+
}, async ({ query }) => served("search_capabilities", (0, queries_js_1.searchCapabilities)(model, query)));
|
|
88
|
+
server.registerTool("get_process", {
|
|
89
|
+
title: "Get business process",
|
|
90
|
+
description: "The primary business process (BPMN) as an ordered list of steps.",
|
|
91
|
+
}, async () => served("get_process", (0, queries_js_1.getProcess)(model)));
|
|
92
|
+
server.registerTool("get_sequence", {
|
|
93
|
+
title: "Get sequence",
|
|
94
|
+
description: "The primary call/dependency sequence (sequence diagram) as ordered messages.",
|
|
95
|
+
}, async () => served("get_sequence", (0, queries_js_1.getSequence)(model)));
|
|
96
|
+
server.registerTool("get_data_model", {
|
|
97
|
+
title: "Get data model",
|
|
98
|
+
description: "The persisted data model (DB entities/tables): each entity's fields with PK/FK/unique markers and its relations. Grounded in the schema file.",
|
|
99
|
+
}, async () => served("get_data_model", (0, queries_js_1.getDataModel)(model)));
|
|
100
|
+
server.registerTool("get_api_surface", {
|
|
101
|
+
title: "Get API surface",
|
|
102
|
+
description: "The API contract: REST routes, tRPC procedures, and GraphQL operations with HTTP methods/paths, grouped by protocol. Grounded in code.",
|
|
103
|
+
}, async () => served("get_api_surface", (0, queries_js_1.getApiSurface)(model)));
|
|
104
|
+
server.registerTool("whats_related", {
|
|
105
|
+
title: "What's related",
|
|
106
|
+
description: "Immediate architectural neighbors (depends-on / used-by) of a component.",
|
|
107
|
+
inputSchema: { name: zod_1.z.string().describe("component name, basename, or repo path") },
|
|
108
|
+
}, async ({ name }) => served("whats_related", (0, queries_js_1.whatsRelated)(model, name)));
|
|
109
|
+
// ── Write tools: the agent keeps the living model current ──────────────────
|
|
110
|
+
server.registerTool("refresh", {
|
|
111
|
+
title: "Refresh the model",
|
|
112
|
+
description: "Re-analyze the repository from disk and update the served model (and .archmantic/model.json). Call this after changing code so subsequent reads reflect reality.",
|
|
113
|
+
}, async () => {
|
|
114
|
+
model = reanalyze(root);
|
|
115
|
+
return text(`Refreshed — ${model.components.length} components, ${model.capabilities.length} capabilities.`);
|
|
116
|
+
});
|
|
117
|
+
server.registerTool("sync", {
|
|
118
|
+
title: "Sync the model to the cloud",
|
|
119
|
+
description: "Re-analyze the repo and push the updated architecture model to the team cloud (org-scoped via your token; direct via DATABASE_URL otherwise). Returns what changed. Call this after making architectural changes.",
|
|
120
|
+
}, async () => {
|
|
121
|
+
const before = model;
|
|
122
|
+
model = reanalyze(root);
|
|
123
|
+
const diff = (0, index_js_2.diffModels)(before, model, "previous", "updated");
|
|
124
|
+
const commit = currentCommit(root);
|
|
125
|
+
const viaApi = (0, index_js_3.hasApiToken)();
|
|
126
|
+
try {
|
|
127
|
+
if (viaApi)
|
|
128
|
+
await (0, index_js_3.pushModelApi)(model, commit);
|
|
129
|
+
else
|
|
130
|
+
await (0, index_js_3.pushModel)(model, commit);
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
return text(`Model refreshed locally, but cloud push failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
134
|
+
}
|
|
135
|
+
return text(`Synced "${model.project}" @ ${commit.slice(0, 7)} ${viaApi ? "(org-scoped API)" : "(direct)"}.\nChanges: ${(0, index_js_2.summarizeChange)(diff)}`);
|
|
136
|
+
});
|
|
137
|
+
// Flush buffered usage on shutdown so short sessions still report.
|
|
138
|
+
for (const sig of ["SIGINT", "SIGTERM"]) {
|
|
139
|
+
process.on(sig, () => {
|
|
140
|
+
void usage.stop().finally(() => process.exit(0));
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
process.on("beforeExit", () => void usage.stop());
|
|
144
|
+
process.stderr.write(`archmantic MCP server: serving "${model.project}" (${model.components.length} components, ${model.capabilities.length} capabilities) over stdio — read + sync tools, usage stats on\n`);
|
|
145
|
+
await server.connect(new stdio_js_1.StdioServerTransport());
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type UsageEvent } from "../cloud/store.js";
|
|
2
|
+
export declare const USAGE_LOG: string;
|
|
3
|
+
export declare class UsageRecorder {
|
|
4
|
+
private root;
|
|
5
|
+
private getProject;
|
|
6
|
+
private flush;
|
|
7
|
+
private buffer;
|
|
8
|
+
private srcTokensCache;
|
|
9
|
+
private timer;
|
|
10
|
+
constructor(root: string, getProject: () => string, flush: (events: UsageEvent[]) => Promise<void>);
|
|
11
|
+
/** Approx tokens an agent would read to answer broad questions (cached). */
|
|
12
|
+
private srcTokens;
|
|
13
|
+
/** Record one tool call. `answer` is the text returned to the agent. */
|
|
14
|
+
record(tool: string, answer: string, now: string): void;
|
|
15
|
+
private appendLocal;
|
|
16
|
+
/** Flush the buffer to the cloud; on failure, retry next time (id makes it idempotent). */
|
|
17
|
+
private drain;
|
|
18
|
+
start(): void;
|
|
19
|
+
stop(): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
/** Parse the local usage log into events (for `archmantic usage`). */
|
|
22
|
+
export declare function readUsageLog(root: string): UsageEvent[];
|
|
23
|
+
//# sourceMappingURL=usage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../../src/mcp/usage.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAgBpD,eAAO,MAAM,SAAS,QAAqC,CAAC;AAI5D,qBAAa,aAAa;IAMtB,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,KAAK;IAPf,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,cAAc,CAAM;IAC5B,OAAO,CAAC,KAAK,CAA6C;gBAGhD,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,MAAM,EACxB,KAAK,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC;IAGxD,4EAA4E;IAC5E,OAAO,CAAC,SAAS;IAcjB,wEAAwE;IACxE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAgBvD,OAAO,CAAC,WAAW;IASnB,2FAA2F;YAC7E,KAAK;IAWnB,KAAK,IAAI,IAAI;IAKP,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAI5B;AAED,sEAAsE;AACtE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,CASvD"}
|