@colbymchenry/codegraph 0.7.4 → 0.7.9
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/README.md +35 -10
- package/dist/bin/codegraph.js +72 -4
- package/dist/bin/codegraph.js.map +1 -1
- package/dist/bin/uninstall.d.ts +7 -7
- package/dist/bin/uninstall.d.ts.map +1 -1
- package/dist/bin/uninstall.js +23 -135
- package/dist/bin/uninstall.js.map +1 -1
- package/dist/installer/claude-md-template.d.ts +10 -6
- package/dist/installer/claude-md-template.d.ts.map +1 -1
- package/dist/installer/claude-md-template.js +15 -40
- package/dist/installer/claude-md-template.js.map +1 -1
- package/dist/installer/config-writer.d.ts +17 -24
- package/dist/installer/config-writer.d.ts.map +1 -1
- package/dist/installer/config-writer.js +44 -239
- package/dist/installer/config-writer.js.map +1 -1
- package/dist/installer/index.d.ts +45 -4
- package/dist/installer/index.d.ts.map +1 -1
- package/dist/installer/index.js +214 -78
- package/dist/installer/index.js.map +1 -1
- package/dist/installer/instructions-template.d.ts +28 -0
- package/dist/installer/instructions-template.d.ts.map +1 -0
- package/dist/installer/instructions-template.js +63 -0
- package/dist/installer/instructions-template.js.map +1 -0
- package/dist/installer/targets/claude.d.ts +27 -0
- package/dist/installer/targets/claude.d.ts.map +1 -0
- package/dist/installer/targets/claude.js +246 -0
- package/dist/installer/targets/claude.js.map +1 -0
- package/dist/installer/targets/codex.d.ts +18 -0
- package/dist/installer/targets/codex.d.ts.map +1 -0
- package/dist/installer/targets/codex.js +185 -0
- package/dist/installer/targets/codex.js.map +1 -0
- package/dist/installer/targets/cursor.d.ts +35 -0
- package/dist/installer/targets/cursor.d.ts.map +1 -0
- package/dist/installer/targets/cursor.js +229 -0
- package/dist/installer/targets/cursor.js.map +1 -0
- package/dist/installer/targets/opencode.d.ts +30 -0
- package/dist/installer/targets/opencode.d.ts.map +1 -0
- package/dist/installer/targets/opencode.js +235 -0
- package/dist/installer/targets/opencode.js.map +1 -0
- package/dist/installer/targets/registry.d.ts +35 -0
- package/dist/installer/targets/registry.d.ts.map +1 -0
- package/dist/installer/targets/registry.js +83 -0
- package/dist/installer/targets/registry.js.map +1 -0
- package/dist/installer/targets/shared.d.ts +77 -0
- package/dist/installer/targets/shared.d.ts.map +1 -0
- package/dist/installer/targets/shared.js +246 -0
- package/dist/installer/targets/shared.js.map +1 -0
- package/dist/installer/targets/toml.d.ts +52 -0
- package/dist/installer/targets/toml.d.ts.map +1 -0
- package/dist/installer/targets/toml.js +147 -0
- package/dist/installer/targets/toml.js.map +1 -0
- package/dist/installer/targets/types.d.ts +116 -0
- package/dist/installer/targets/types.d.ts.map +1 -0
- package/dist/installer/targets/types.js +16 -0
- package/dist/installer/targets/types.js.map +1 -0
- package/dist/resolution/frameworks/cargo-workspace.d.ts +18 -0
- package/dist/resolution/frameworks/cargo-workspace.d.ts.map +1 -0
- package/dist/resolution/frameworks/cargo-workspace.js +225 -0
- package/dist/resolution/frameworks/cargo-workspace.js.map +1 -0
- package/dist/resolution/frameworks/rust.d.ts.map +1 -1
- package/dist/resolution/frameworks/rust.js +35 -17
- package/dist/resolution/frameworks/rust.js.map +1 -1
- package/dist/resolution/index.d.ts.map +1 -1
- package/dist/resolution/index.js +18 -0
- package/dist/resolution/index.js.map +1 -1
- package/dist/resolution/types.d.ts +9 -0
- package/dist/resolution/types.d.ts.map +1 -1
- package/package.json +3 -2
- package/scripts/local-install.sh +41 -0
- package/scripts/release.sh +70 -0
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Cursor target.
|
|
4
|
+
*
|
|
5
|
+
* - MCP server entry to `~/.cursor/mcp.json` (global) or
|
|
6
|
+
* `./.cursor/mcp.json` (local). Same `{mcpServers: {...}}` shape
|
|
7
|
+
* as Claude.
|
|
8
|
+
* - Instructions to `./.cursor/rules/codegraph.mdc` (project-local
|
|
9
|
+
* ONLY). Cursor's rules system is a project-scoped surface;
|
|
10
|
+
* global cursor rules aren't a stable convention as of 2026-05.
|
|
11
|
+
* For `--location=global`, only mcp.json is written.
|
|
12
|
+
*
|
|
13
|
+
* ## Why we hardcode `--path` for Cursor
|
|
14
|
+
*
|
|
15
|
+
* Cursor launches MCP-server subprocesses with a working directory
|
|
16
|
+
* that ISN'T the workspace root AND doesn't pass `rootUri` /
|
|
17
|
+
* `workspaceFolders` in the MCP initialize call. The codegraph MCP
|
|
18
|
+
* server's `process.cwd()` fallback therefore misses the workspace's
|
|
19
|
+
* `.codegraph/` and reports "not initialized" on every tool call.
|
|
20
|
+
*
|
|
21
|
+
* So we inject `--path` into the args ourselves:
|
|
22
|
+
*
|
|
23
|
+
* - `local` install: absolute path (we know it at install time).
|
|
24
|
+
* - `global` install: `${workspaceFolder}` — Cursor expands this to
|
|
25
|
+
* the open workspace's root, giving us per-workspace behavior
|
|
26
|
+
* from a single global config.
|
|
27
|
+
*
|
|
28
|
+
* Codex and Claude do not need this — they launch MCP servers with
|
|
29
|
+
* `cwd = workspace` and pass `rootUri`, respectively.
|
|
30
|
+
*
|
|
31
|
+
* No permissions concept — Cursor doesn't have an auto-allow list
|
|
32
|
+
* the installer can populate. `autoAllow` is silently ignored.
|
|
33
|
+
*/
|
|
34
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
35
|
+
if (k2 === undefined) k2 = k;
|
|
36
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
37
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
38
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
39
|
+
}
|
|
40
|
+
Object.defineProperty(o, k2, desc);
|
|
41
|
+
}) : (function(o, m, k, k2) {
|
|
42
|
+
if (k2 === undefined) k2 = k;
|
|
43
|
+
o[k2] = m[k];
|
|
44
|
+
}));
|
|
45
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
46
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
47
|
+
}) : function(o, v) {
|
|
48
|
+
o["default"] = v;
|
|
49
|
+
});
|
|
50
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
51
|
+
var ownKeys = function(o) {
|
|
52
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
53
|
+
var ar = [];
|
|
54
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
55
|
+
return ar;
|
|
56
|
+
};
|
|
57
|
+
return ownKeys(o);
|
|
58
|
+
};
|
|
59
|
+
return function (mod) {
|
|
60
|
+
if (mod && mod.__esModule) return mod;
|
|
61
|
+
var result = {};
|
|
62
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
63
|
+
__setModuleDefault(result, mod);
|
|
64
|
+
return result;
|
|
65
|
+
};
|
|
66
|
+
})();
|
|
67
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
68
|
+
exports.cursorTarget = void 0;
|
|
69
|
+
const fs = __importStar(require("fs"));
|
|
70
|
+
const path = __importStar(require("path"));
|
|
71
|
+
const os = __importStar(require("os"));
|
|
72
|
+
const shared_1 = require("./shared");
|
|
73
|
+
const instructions_template_1 = require("../instructions-template");
|
|
74
|
+
function mcpJsonPath(loc) {
|
|
75
|
+
return loc === 'global'
|
|
76
|
+
? path.join(os.homedir(), '.cursor', 'mcp.json')
|
|
77
|
+
: path.join(process.cwd(), '.cursor', 'mcp.json');
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Cursor "rules" file. Only meaningful for the project-local
|
|
81
|
+
* location — Cursor reads `.cursor/rules/*.mdc` from the workspace
|
|
82
|
+
* root. There is no global equivalent.
|
|
83
|
+
*/
|
|
84
|
+
function rulesPath() {
|
|
85
|
+
return path.join(process.cwd(), '.cursor', 'rules', 'codegraph.mdc');
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Cursor `.mdc` rules use YAML-ish frontmatter. `alwaysApply: true`
|
|
89
|
+
* makes the rule load on every conversation regardless of file
|
|
90
|
+
* patterns — appropriate for a tool-usage guide that's relevant
|
|
91
|
+
* whenever the user is asking the agent to navigate code.
|
|
92
|
+
*/
|
|
93
|
+
const MDC_FRONTMATTER = [
|
|
94
|
+
'---',
|
|
95
|
+
'description: CodeGraph MCP usage guide — when to use which tool',
|
|
96
|
+
'alwaysApply: true',
|
|
97
|
+
'---',
|
|
98
|
+
'',
|
|
99
|
+
].join('\n');
|
|
100
|
+
class CursorTarget {
|
|
101
|
+
id = 'cursor';
|
|
102
|
+
displayName = 'Cursor';
|
|
103
|
+
docsUrl = 'https://docs.cursor.com/context/model-context-protocol';
|
|
104
|
+
supportsLocation(_loc) {
|
|
105
|
+
// Both supported, but `local` writes more files (mcp.json + rules);
|
|
106
|
+
// `global` writes only mcp.json. The orchestrator surfaces the
|
|
107
|
+
// difference via describePaths.
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
detect(loc) {
|
|
111
|
+
const mcpPath = mcpJsonPath(loc);
|
|
112
|
+
const config = (0, shared_1.readJsonFile)(mcpPath);
|
|
113
|
+
const alreadyConfigured = !!config.mcpServers?.codegraph;
|
|
114
|
+
// "Installed" heuristic: does ~/.cursor exist (global) or has the
|
|
115
|
+
// user opted into a project-local cursor config dir?
|
|
116
|
+
const installed = loc === 'global'
|
|
117
|
+
? fs.existsSync(path.join(os.homedir(), '.cursor'))
|
|
118
|
+
: fs.existsSync(path.join(process.cwd(), '.cursor'));
|
|
119
|
+
return { installed, alreadyConfigured, configPath: mcpPath };
|
|
120
|
+
}
|
|
121
|
+
install(loc, _opts) {
|
|
122
|
+
const files = [];
|
|
123
|
+
files.push(writeMcpEntry(loc));
|
|
124
|
+
if (loc === 'local') {
|
|
125
|
+
files.push(writeRulesEntry());
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
files,
|
|
129
|
+
notes: ['Restart Cursor for MCP changes to take effect.'],
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
uninstall(loc) {
|
|
133
|
+
const files = [];
|
|
134
|
+
const mcpPath = mcpJsonPath(loc);
|
|
135
|
+
const config = (0, shared_1.readJsonFile)(mcpPath);
|
|
136
|
+
if (config.mcpServers?.codegraph) {
|
|
137
|
+
delete config.mcpServers.codegraph;
|
|
138
|
+
if (Object.keys(config.mcpServers).length === 0) {
|
|
139
|
+
delete config.mcpServers;
|
|
140
|
+
}
|
|
141
|
+
(0, shared_1.writeJsonFile)(mcpPath, config);
|
|
142
|
+
files.push({ path: mcpPath, action: 'removed' });
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
files.push({ path: mcpPath, action: 'not-found' });
|
|
146
|
+
}
|
|
147
|
+
if (loc === 'local') {
|
|
148
|
+
const rules = rulesPath();
|
|
149
|
+
const action = (0, shared_1.removeMarkedSection)(rules, instructions_template_1.CODEGRAPH_SECTION_START, instructions_template_1.CODEGRAPH_SECTION_END);
|
|
150
|
+
files.push({ path: rules, action });
|
|
151
|
+
}
|
|
152
|
+
return { files };
|
|
153
|
+
}
|
|
154
|
+
printConfig(loc) {
|
|
155
|
+
const target = mcpJsonPath(loc);
|
|
156
|
+
const snippet = JSON.stringify({ mcpServers: { codegraph: buildCursorMcpConfig(loc) } }, null, 2);
|
|
157
|
+
return `# Add to ${target}\n\n${snippet}\n`;
|
|
158
|
+
}
|
|
159
|
+
describePaths(loc) {
|
|
160
|
+
return loc === 'local'
|
|
161
|
+
? [mcpJsonPath(loc), rulesPath()]
|
|
162
|
+
: [mcpJsonPath(loc)];
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Write the project-local `.cursor/rules/codegraph.mdc` file. Used
|
|
166
|
+
* by `codegraph init` to bootstrap projects that have only the
|
|
167
|
+
* global `~/.cursor/mcp.json` — without the rules file, the Cursor
|
|
168
|
+
* agent has no signal to prefer codegraph over native grep.
|
|
169
|
+
*/
|
|
170
|
+
wireProjectSurfaces() {
|
|
171
|
+
return { files: [writeRulesEntry()] };
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Build the codegraph MCP-server config for Cursor at the given
|
|
176
|
+
* location. Inherits the shared shape ({type, command, args}) and
|
|
177
|
+
* appends `--path` so the spawned MCP server resolves the workspace
|
|
178
|
+
* correctly regardless of Cursor's launch cwd. See file header for
|
|
179
|
+
* the full rationale.
|
|
180
|
+
*/
|
|
181
|
+
function buildCursorMcpConfig(loc) {
|
|
182
|
+
const base = (0, shared_1.getMcpServerConfig)();
|
|
183
|
+
const pathArg = loc === 'local' ? process.cwd() : '${workspaceFolder}';
|
|
184
|
+
return { ...base, args: [...base.args, '--path', pathArg] };
|
|
185
|
+
}
|
|
186
|
+
function writeMcpEntry(loc) {
|
|
187
|
+
const file = mcpJsonPath(loc);
|
|
188
|
+
const existing = (0, shared_1.readJsonFile)(file);
|
|
189
|
+
const before = existing.mcpServers?.codegraph;
|
|
190
|
+
const after = buildCursorMcpConfig(loc);
|
|
191
|
+
if ((0, shared_1.jsonDeepEqual)(before, after)) {
|
|
192
|
+
return { path: file, action: 'unchanged' };
|
|
193
|
+
}
|
|
194
|
+
const action = before ? 'updated' : (fs.existsSync(file) ? 'updated' : 'created');
|
|
195
|
+
if (!existing.mcpServers)
|
|
196
|
+
existing.mcpServers = {};
|
|
197
|
+
existing.mcpServers.codegraph = after;
|
|
198
|
+
(0, shared_1.writeJsonFile)(file, existing);
|
|
199
|
+
return { path: file, action };
|
|
200
|
+
}
|
|
201
|
+
function writeRulesEntry() {
|
|
202
|
+
const file = rulesPath();
|
|
203
|
+
const dir = path.dirname(file);
|
|
204
|
+
if (!fs.existsSync(dir))
|
|
205
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
206
|
+
// Body is frontmatter + the shared instructions block. The
|
|
207
|
+
// marker-based replacement targets only the marker block, so the
|
|
208
|
+
// frontmatter is preserved across re-runs.
|
|
209
|
+
const body = MDC_FRONTMATTER + instructions_template_1.INSTRUCTIONS_TEMPLATE;
|
|
210
|
+
if (!fs.existsSync(file)) {
|
|
211
|
+
(0, shared_1.atomicWriteFileSync)(file, body + '\n');
|
|
212
|
+
return { path: file, action: 'created' };
|
|
213
|
+
}
|
|
214
|
+
// For .mdc files we own outright, do byte-equality first.
|
|
215
|
+
const existing = fs.readFileSync(file, 'utf-8');
|
|
216
|
+
const wantWithNL = body + '\n';
|
|
217
|
+
if (existing === wantWithNL) {
|
|
218
|
+
return { path: file, action: 'unchanged' };
|
|
219
|
+
}
|
|
220
|
+
// Otherwise, marker-based section swap (preserves any user-added
|
|
221
|
+
// content outside the markers).
|
|
222
|
+
const action = (0, shared_1.replaceOrAppendMarkedSection)(file, instructions_template_1.INSTRUCTIONS_TEMPLATE, instructions_template_1.CODEGRAPH_SECTION_START, instructions_template_1.CODEGRAPH_SECTION_END);
|
|
223
|
+
const mapped = action === 'created' ? 'created'
|
|
224
|
+
: action === 'unchanged' ? 'unchanged'
|
|
225
|
+
: 'updated';
|
|
226
|
+
return { path: file, action: mapped };
|
|
227
|
+
}
|
|
228
|
+
exports.cursorTarget = new CursorTarget();
|
|
229
|
+
//# sourceMappingURL=cursor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../../src/installer/targets/cursor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* opencode target.
|
|
3
|
+
*
|
|
4
|
+
* - MCP server entry to `~/.config/opencode/opencode.jsonc` (global,
|
|
5
|
+
* XDG-style; `%APPDATA%/opencode/opencode.jsonc` on Windows) or
|
|
6
|
+
* `./opencode.jsonc` (local). Falls back to `opencode.json` when a
|
|
7
|
+
* `.json` file already exists; defaults new installs to `.jsonc`
|
|
8
|
+
* because that's what opencode itself creates on first run.
|
|
9
|
+
* - Instructions to `~/.config/opencode/AGENTS.md` (global) or
|
|
10
|
+
* `./AGENTS.md` (local). opencode reads AGENTS.md for agent
|
|
11
|
+
* instructions — same convention Codex CLI uses.
|
|
12
|
+
* - No permissions concept.
|
|
13
|
+
*
|
|
14
|
+
* Config shape uses opencode's wrapper:
|
|
15
|
+
* {
|
|
16
|
+
* "$schema": "https://opencode.ai/config.json",
|
|
17
|
+
* "mcp": { "codegraph": { "type": "local", "command": [...], "enabled": true } }
|
|
18
|
+
* }
|
|
19
|
+
*
|
|
20
|
+
* The shape differs from Claude/Cursor — opencode uses `mcp.<name>`
|
|
21
|
+
* (not `mcpServers`), takes `command` as a string array combining
|
|
22
|
+
* binary + args, and includes an explicit `enabled` flag.
|
|
23
|
+
*
|
|
24
|
+
* Reads + writes go through `jsonc-parser` so any `//` and `/* *\/`
|
|
25
|
+
* comments the user has added to their `.jsonc` survive idempotent
|
|
26
|
+
* re-runs.
|
|
27
|
+
*/
|
|
28
|
+
import { AgentTarget } from './types';
|
|
29
|
+
export declare const opencodeTarget: AgentTarget;
|
|
30
|
+
//# sourceMappingURL=opencode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode.d.ts","sourceRoot":"","sources":["../../../src/installer/targets/opencode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAMH,OAAO,EACL,WAAW,EAKZ,MAAM,SAAS,CAAC;AA6MjB,eAAO,MAAM,cAAc,EAAE,WAAkC,CAAC"}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* opencode target.
|
|
4
|
+
*
|
|
5
|
+
* - MCP server entry to `~/.config/opencode/opencode.jsonc` (global,
|
|
6
|
+
* XDG-style; `%APPDATA%/opencode/opencode.jsonc` on Windows) or
|
|
7
|
+
* `./opencode.jsonc` (local). Falls back to `opencode.json` when a
|
|
8
|
+
* `.json` file already exists; defaults new installs to `.jsonc`
|
|
9
|
+
* because that's what opencode itself creates on first run.
|
|
10
|
+
* - Instructions to `~/.config/opencode/AGENTS.md` (global) or
|
|
11
|
+
* `./AGENTS.md` (local). opencode reads AGENTS.md for agent
|
|
12
|
+
* instructions — same convention Codex CLI uses.
|
|
13
|
+
* - No permissions concept.
|
|
14
|
+
*
|
|
15
|
+
* Config shape uses opencode's wrapper:
|
|
16
|
+
* {
|
|
17
|
+
* "$schema": "https://opencode.ai/config.json",
|
|
18
|
+
* "mcp": { "codegraph": { "type": "local", "command": [...], "enabled": true } }
|
|
19
|
+
* }
|
|
20
|
+
*
|
|
21
|
+
* The shape differs from Claude/Cursor — opencode uses `mcp.<name>`
|
|
22
|
+
* (not `mcpServers`), takes `command` as a string array combining
|
|
23
|
+
* binary + args, and includes an explicit `enabled` flag.
|
|
24
|
+
*
|
|
25
|
+
* Reads + writes go through `jsonc-parser` so any `//` and `/* *\/`
|
|
26
|
+
* comments the user has added to their `.jsonc` survive idempotent
|
|
27
|
+
* re-runs.
|
|
28
|
+
*/
|
|
29
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
30
|
+
if (k2 === undefined) k2 = k;
|
|
31
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
32
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
33
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
34
|
+
}
|
|
35
|
+
Object.defineProperty(o, k2, desc);
|
|
36
|
+
}) : (function(o, m, k, k2) {
|
|
37
|
+
if (k2 === undefined) k2 = k;
|
|
38
|
+
o[k2] = m[k];
|
|
39
|
+
}));
|
|
40
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
41
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
42
|
+
}) : function(o, v) {
|
|
43
|
+
o["default"] = v;
|
|
44
|
+
});
|
|
45
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
46
|
+
var ownKeys = function(o) {
|
|
47
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
48
|
+
var ar = [];
|
|
49
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
50
|
+
return ar;
|
|
51
|
+
};
|
|
52
|
+
return ownKeys(o);
|
|
53
|
+
};
|
|
54
|
+
return function (mod) {
|
|
55
|
+
if (mod && mod.__esModule) return mod;
|
|
56
|
+
var result = {};
|
|
57
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
58
|
+
__setModuleDefault(result, mod);
|
|
59
|
+
return result;
|
|
60
|
+
};
|
|
61
|
+
})();
|
|
62
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
63
|
+
exports.opencodeTarget = void 0;
|
|
64
|
+
const fs = __importStar(require("fs"));
|
|
65
|
+
const path = __importStar(require("path"));
|
|
66
|
+
const os = __importStar(require("os"));
|
|
67
|
+
const jsonc_parser_1 = require("jsonc-parser");
|
|
68
|
+
const shared_1 = require("./shared");
|
|
69
|
+
const instructions_template_1 = require("../instructions-template");
|
|
70
|
+
function globalConfigDir() {
|
|
71
|
+
if (process.platform === 'win32') {
|
|
72
|
+
const appData = process.env.APPDATA ?? path.join(os.homedir(), 'AppData', 'Roaming');
|
|
73
|
+
return path.join(appData, 'opencode');
|
|
74
|
+
}
|
|
75
|
+
// XDG_CONFIG_HOME if set, else ~/.config — matches opencode's docs.
|
|
76
|
+
const xdg = process.env.XDG_CONFIG_HOME && process.env.XDG_CONFIG_HOME.trim().length > 0
|
|
77
|
+
? process.env.XDG_CONFIG_HOME
|
|
78
|
+
: path.join(os.homedir(), '.config');
|
|
79
|
+
return path.join(xdg, 'opencode');
|
|
80
|
+
}
|
|
81
|
+
function configBaseDir(loc) {
|
|
82
|
+
return loc === 'global' ? globalConfigDir() : process.cwd();
|
|
83
|
+
}
|
|
84
|
+
// Pick existing .jsonc, then .json, default to .jsonc for new files.
|
|
85
|
+
// opencode auto-creates .jsonc on first run, so that's the dominant
|
|
86
|
+
// real-world case and the sensible default for greenfield installs.
|
|
87
|
+
function configPath(loc) {
|
|
88
|
+
const dir = configBaseDir(loc);
|
|
89
|
+
const jsonc = path.join(dir, 'opencode.jsonc');
|
|
90
|
+
const json = path.join(dir, 'opencode.json');
|
|
91
|
+
if (fs.existsSync(jsonc))
|
|
92
|
+
return jsonc;
|
|
93
|
+
if (fs.existsSync(json))
|
|
94
|
+
return json;
|
|
95
|
+
return jsonc;
|
|
96
|
+
}
|
|
97
|
+
function instructionsPath(loc) {
|
|
98
|
+
return path.join(configBaseDir(loc), 'AGENTS.md');
|
|
99
|
+
}
|
|
100
|
+
function readConfigText(file) {
|
|
101
|
+
if (!fs.existsSync(file))
|
|
102
|
+
return '';
|
|
103
|
+
return fs.readFileSync(file, 'utf-8');
|
|
104
|
+
}
|
|
105
|
+
function parseConfig(text) {
|
|
106
|
+
if (!text.trim())
|
|
107
|
+
return {};
|
|
108
|
+
const errors = [];
|
|
109
|
+
const result = (0, jsonc_parser_1.parse)(text, errors, { allowTrailingComma: true });
|
|
110
|
+
if (result == null || typeof result !== 'object' || Array.isArray(result)) {
|
|
111
|
+
return {};
|
|
112
|
+
}
|
|
113
|
+
return result;
|
|
114
|
+
}
|
|
115
|
+
function getOpencodeServerEntry() {
|
|
116
|
+
return {
|
|
117
|
+
type: 'local',
|
|
118
|
+
command: ['codegraph', 'serve', '--mcp'],
|
|
119
|
+
enabled: true,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
const FORMATTING = { tabSize: 2, insertSpaces: true, eol: '\n' };
|
|
123
|
+
class OpencodeTarget {
|
|
124
|
+
id = 'opencode';
|
|
125
|
+
displayName = 'opencode';
|
|
126
|
+
docsUrl = 'https://opencode.ai/docs/config';
|
|
127
|
+
supportsLocation(_loc) {
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
detect(loc) {
|
|
131
|
+
const file = configPath(loc);
|
|
132
|
+
const config = parseConfig(readConfigText(file));
|
|
133
|
+
const alreadyConfigured = !!config.mcp?.codegraph;
|
|
134
|
+
const installed = loc === 'global'
|
|
135
|
+
? fs.existsSync(globalConfigDir())
|
|
136
|
+
: fs.existsSync(file);
|
|
137
|
+
return { installed, alreadyConfigured, configPath: file };
|
|
138
|
+
}
|
|
139
|
+
install(loc, _opts) {
|
|
140
|
+
const files = [];
|
|
141
|
+
files.push(writeMcpEntry(loc));
|
|
142
|
+
files.push(writeInstructionsEntry(loc));
|
|
143
|
+
return { files };
|
|
144
|
+
}
|
|
145
|
+
uninstall(loc) {
|
|
146
|
+
const files = [];
|
|
147
|
+
const file = configPath(loc);
|
|
148
|
+
if (!fs.existsSync(file)) {
|
|
149
|
+
files.push({ path: file, action: 'not-found' });
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
const text = readConfigText(file);
|
|
153
|
+
const config = parseConfig(text);
|
|
154
|
+
if (!config.mcp?.codegraph) {
|
|
155
|
+
files.push({ path: file, action: 'not-found' });
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
// Drop our key surgically. Leaves siblings + comments untouched.
|
|
159
|
+
let edits = (0, jsonc_parser_1.modify)(text, ['mcp', 'codegraph'], undefined, {
|
|
160
|
+
formattingOptions: FORMATTING,
|
|
161
|
+
});
|
|
162
|
+
let updated = (0, jsonc_parser_1.applyEdits)(text, edits);
|
|
163
|
+
// If `mcp` is now an empty object, drop the wrapper too.
|
|
164
|
+
const afterParsed = parseConfig(updated);
|
|
165
|
+
if (afterParsed.mcp && typeof afterParsed.mcp === 'object' &&
|
|
166
|
+
Object.keys(afterParsed.mcp).length === 0) {
|
|
167
|
+
edits = (0, jsonc_parser_1.modify)(updated, ['mcp'], undefined, { formattingOptions: FORMATTING });
|
|
168
|
+
updated = (0, jsonc_parser_1.applyEdits)(updated, edits);
|
|
169
|
+
}
|
|
170
|
+
(0, shared_1.atomicWriteFileSync)(file, updated);
|
|
171
|
+
files.push({ path: file, action: 'removed' });
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
const instr = instructionsPath(loc);
|
|
175
|
+
const instrAction = (0, shared_1.removeMarkedSection)(instr, instructions_template_1.CODEGRAPH_SECTION_START, instructions_template_1.CODEGRAPH_SECTION_END);
|
|
176
|
+
files.push({ path: instr, action: instrAction });
|
|
177
|
+
return { files };
|
|
178
|
+
}
|
|
179
|
+
printConfig(loc) {
|
|
180
|
+
const target = configPath(loc);
|
|
181
|
+
const snippet = JSON.stringify({
|
|
182
|
+
$schema: 'https://opencode.ai/config.json',
|
|
183
|
+
mcp: { codegraph: getOpencodeServerEntry() },
|
|
184
|
+
}, null, 2);
|
|
185
|
+
return `# Add to ${target}\n\n${snippet}\n`;
|
|
186
|
+
}
|
|
187
|
+
describePaths(loc) {
|
|
188
|
+
return [configPath(loc), instructionsPath(loc)];
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
function writeMcpEntry(loc) {
|
|
192
|
+
const file = configPath(loc);
|
|
193
|
+
const existed = fs.existsSync(file);
|
|
194
|
+
let text = readConfigText(file);
|
|
195
|
+
// Seed a minimal opencode config when the file is brand-new so
|
|
196
|
+
// the result is a complete, schema-tagged file (not just a bare
|
|
197
|
+
// `{ "mcp": {...} }`).
|
|
198
|
+
if (!text.trim()) {
|
|
199
|
+
text = '{\n "$schema": "https://opencode.ai/config.json"\n}\n';
|
|
200
|
+
}
|
|
201
|
+
const config = parseConfig(text);
|
|
202
|
+
const before = config.mcp?.codegraph;
|
|
203
|
+
const after = getOpencodeServerEntry();
|
|
204
|
+
if ((0, shared_1.jsonDeepEqual)(before, after)) {
|
|
205
|
+
return { path: file, action: 'unchanged' };
|
|
206
|
+
}
|
|
207
|
+
// Add $schema if the user's existing file is missing it.
|
|
208
|
+
if (!config.$schema) {
|
|
209
|
+
const schemaEdits = (0, jsonc_parser_1.modify)(text, ['$schema'], 'https://opencode.ai/config.json', {
|
|
210
|
+
formattingOptions: FORMATTING,
|
|
211
|
+
});
|
|
212
|
+
text = (0, jsonc_parser_1.applyEdits)(text, schemaEdits);
|
|
213
|
+
}
|
|
214
|
+
// Surgical edit — preserves comments, formatting, and order of
|
|
215
|
+
// every key we don't touch.
|
|
216
|
+
const edits = (0, jsonc_parser_1.modify)(text, ['mcp', 'codegraph'], after, {
|
|
217
|
+
formattingOptions: FORMATTING,
|
|
218
|
+
});
|
|
219
|
+
const updated = (0, jsonc_parser_1.applyEdits)(text, edits);
|
|
220
|
+
(0, shared_1.atomicWriteFileSync)(file, updated);
|
|
221
|
+
return { path: file, action: existed ? 'updated' : 'created' };
|
|
222
|
+
}
|
|
223
|
+
function writeInstructionsEntry(loc) {
|
|
224
|
+
const file = instructionsPath(loc);
|
|
225
|
+
const dir = path.dirname(file);
|
|
226
|
+
if (!fs.existsSync(dir))
|
|
227
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
228
|
+
const action = (0, shared_1.replaceOrAppendMarkedSection)(file, instructions_template_1.INSTRUCTIONS_TEMPLATE, instructions_template_1.CODEGRAPH_SECTION_START, instructions_template_1.CODEGRAPH_SECTION_END);
|
|
229
|
+
const mapped = action === 'created' ? 'created'
|
|
230
|
+
: action === 'unchanged' ? 'unchanged'
|
|
231
|
+
: 'updated';
|
|
232
|
+
return { path: file, action: mapped };
|
|
233
|
+
}
|
|
234
|
+
exports.opencodeTarget = new OpencodeTarget();
|
|
235
|
+
//# sourceMappingURL=opencode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode.js","sourceRoot":"","sources":["../../../src/installer/targets/opencode.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry of all known agent targets.
|
|
3
|
+
*
|
|
4
|
+
* Adding a new target = create `targets/<id>.ts` exporting an
|
|
5
|
+
* `AgentTarget`, then add it to the array below. Order here is the
|
|
6
|
+
* order they appear in the multiselect prompt, in `--target=all`,
|
|
7
|
+
* and in `--print-config`'s help listing — keep it stable.
|
|
8
|
+
*/
|
|
9
|
+
import { AgentTarget, Location, TargetId } from './types';
|
|
10
|
+
export declare const ALL_TARGETS: readonly AgentTarget[];
|
|
11
|
+
export declare function getTarget(id: string): AgentTarget | undefined;
|
|
12
|
+
export declare function listTargetIds(): TargetId[];
|
|
13
|
+
/**
|
|
14
|
+
* Run `detect()` for every target at the given location. Returns the
|
|
15
|
+
* full registry zipped with detection results — orchestrator uses
|
|
16
|
+
* this to seed the multiselect prompt with installed agents
|
|
17
|
+
* pre-checked.
|
|
18
|
+
*/
|
|
19
|
+
export declare function detectAll(loc: Location): Array<{
|
|
20
|
+
target: AgentTarget;
|
|
21
|
+
detection: ReturnType<AgentTarget['detect']>;
|
|
22
|
+
}>;
|
|
23
|
+
/**
|
|
24
|
+
* Resolve a `--target=` flag value to a list of `AgentTarget`
|
|
25
|
+
* instances. Accepts:
|
|
26
|
+
*
|
|
27
|
+
* - `auto` — return all targets whose `detect().installed` is true,
|
|
28
|
+
* or `['claude']` as a fallback if none detected (least-surprise
|
|
29
|
+
* for existing users).
|
|
30
|
+
* - `all` — every target in the registry.
|
|
31
|
+
* - `none` — empty list (caller skips agent writes entirely).
|
|
32
|
+
* - csv list — `'claude,cursor'` etc. Unknown ids throw.
|
|
33
|
+
*/
|
|
34
|
+
export declare function resolveTargetFlag(value: string, loc: Location): AgentTarget[];
|
|
35
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/installer/targets/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAM1D,eAAO,MAAM,WAAW,EAAE,SAAS,WAAW,EAK5C,CAAC;AAEH,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAE7D;AAED,wBAAgB,aAAa,IAAI,QAAQ,EAAE,CAE1C;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,QAAQ,GAAG,KAAK,CAAC;IAC9C,MAAM,EAAE,WAAW,CAAC;IACpB,SAAS,EAAE,UAAU,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC;CAC9C,CAAC,CAKD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,GAAG,WAAW,EAAE,CAyB7E"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Registry of all known agent targets.
|
|
4
|
+
*
|
|
5
|
+
* Adding a new target = create `targets/<id>.ts` exporting an
|
|
6
|
+
* `AgentTarget`, then add it to the array below. Order here is the
|
|
7
|
+
* order they appear in the multiselect prompt, in `--target=all`,
|
|
8
|
+
* and in `--print-config`'s help listing — keep it stable.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.ALL_TARGETS = void 0;
|
|
12
|
+
exports.getTarget = getTarget;
|
|
13
|
+
exports.listTargetIds = listTargetIds;
|
|
14
|
+
exports.detectAll = detectAll;
|
|
15
|
+
exports.resolveTargetFlag = resolveTargetFlag;
|
|
16
|
+
const claude_1 = require("./claude");
|
|
17
|
+
const cursor_1 = require("./cursor");
|
|
18
|
+
const codex_1 = require("./codex");
|
|
19
|
+
const opencode_1 = require("./opencode");
|
|
20
|
+
exports.ALL_TARGETS = Object.freeze([
|
|
21
|
+
claude_1.claudeTarget,
|
|
22
|
+
cursor_1.cursorTarget,
|
|
23
|
+
codex_1.codexTarget,
|
|
24
|
+
opencode_1.opencodeTarget,
|
|
25
|
+
]);
|
|
26
|
+
function getTarget(id) {
|
|
27
|
+
return exports.ALL_TARGETS.find((t) => t.id === id);
|
|
28
|
+
}
|
|
29
|
+
function listTargetIds() {
|
|
30
|
+
return exports.ALL_TARGETS.map((t) => t.id);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Run `detect()` for every target at the given location. Returns the
|
|
34
|
+
* full registry zipped with detection results — orchestrator uses
|
|
35
|
+
* this to seed the multiselect prompt with installed agents
|
|
36
|
+
* pre-checked.
|
|
37
|
+
*/
|
|
38
|
+
function detectAll(loc) {
|
|
39
|
+
return exports.ALL_TARGETS.map((target) => ({
|
|
40
|
+
target,
|
|
41
|
+
detection: target.detect(loc),
|
|
42
|
+
}));
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Resolve a `--target=` flag value to a list of `AgentTarget`
|
|
46
|
+
* instances. Accepts:
|
|
47
|
+
*
|
|
48
|
+
* - `auto` — return all targets whose `detect().installed` is true,
|
|
49
|
+
* or `['claude']` as a fallback if none detected (least-surprise
|
|
50
|
+
* for existing users).
|
|
51
|
+
* - `all` — every target in the registry.
|
|
52
|
+
* - `none` — empty list (caller skips agent writes entirely).
|
|
53
|
+
* - csv list — `'claude,cursor'` etc. Unknown ids throw.
|
|
54
|
+
*/
|
|
55
|
+
function resolveTargetFlag(value, loc) {
|
|
56
|
+
if (value === 'none')
|
|
57
|
+
return [];
|
|
58
|
+
if (value === 'all')
|
|
59
|
+
return [...exports.ALL_TARGETS];
|
|
60
|
+
if (value === 'auto') {
|
|
61
|
+
const detected = detectAll(loc).filter(({ detection }) => detection.installed);
|
|
62
|
+
if (detected.length > 0)
|
|
63
|
+
return detected.map(({ target }) => target);
|
|
64
|
+
const fallback = getTarget('claude');
|
|
65
|
+
return fallback ? [fallback] : [];
|
|
66
|
+
}
|
|
67
|
+
const ids = value.split(',').map((s) => s.trim()).filter(Boolean);
|
|
68
|
+
const resolved = [];
|
|
69
|
+
const unknown = [];
|
|
70
|
+
for (const id of ids) {
|
|
71
|
+
const t = getTarget(id);
|
|
72
|
+
if (t)
|
|
73
|
+
resolved.push(t);
|
|
74
|
+
else
|
|
75
|
+
unknown.push(id);
|
|
76
|
+
}
|
|
77
|
+
if (unknown.length > 0) {
|
|
78
|
+
const known = listTargetIds().join(', ');
|
|
79
|
+
throw new Error(`Unknown --target id(s): ${unknown.join(', ')}. Known: ${known}, plus 'auto' / 'all' / 'none'.`);
|
|
80
|
+
}
|
|
81
|
+
return resolved;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/installer/targets/registry.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAeH,8BAEC;AAED,sCAEC;AAQD,8BAQC;AAaD,8CAyBC;AAxED,qCAAwC;AACxC,qCAAwC;AACxC,mCAAsC;AACtC,yCAA4C;AAE/B,QAAA,WAAW,GAA2B,MAAM,CAAC,MAAM,CAAC;IAC/D,qBAAY;IACZ,qBAAY;IACZ,mBAAW;IACX,yBAAc;CACf,CAAC,CAAC;AAEH,SAAgB,SAAS,CAAC,EAAU;IAClC,OAAO,mBAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AAC9C,CAAC;AAED,SAAgB,aAAa;IAC3B,OAAO,mBAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AACtC,CAAC;AAED;;;;;GAKG;AACH,SAAgB,SAAS,CAAC,GAAa;IAIrC,OAAO,mBAAW,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAClC,MAAM;QACN,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;KAC9B,CAAC,CAAC,CAAC;AACN,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,iBAAiB,CAAC,KAAa,EAAE,GAAa;IAC5D,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,EAAE,CAAC;IAChC,IAAI,KAAK,KAAK,KAAK;QAAE,OAAO,CAAC,GAAG,mBAAW,CAAC,CAAC;IAC7C,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACrB,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAC/E,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;QACrE,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;QACrC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACpC,CAAC;IAED,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAClE,MAAM,QAAQ,GAAkB,EAAE,CAAC;IACnC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;QACrB,MAAM,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC;QACxB,IAAI,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;;YACnB,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,aAAa,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,IAAI,KAAK,CACb,2BAA2B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,KAAK,iCAAiC,CAChG,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|