MCPcopy
hub / github.com/colbymchenry/codegraph / OpencodeTarget

Class OpencodeTarget

src/installer/targets/opencode.ts:128–187  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

126const FORMATTING = { tabSize: 2, insertSpaces: true, eol: '\n' };
127
128class OpencodeTarget implements AgentTarget {
129 readonly id = 'opencode' as const;
130 readonly displayName = 'opencode';
131 readonly docsUrl = 'https://opencode.ai/docs/config';
132
133 supportsLocation(_loc: Location): boolean {
134 return true;
135 }
136
137 detect(loc: Location): DetectionResult {
138 const file = configPath(loc);
139 const config = parseConfig(readConfigText(file));
140 const alreadyConfigured = !!config.mcp?.codegraph;
141 // Global: the XDG dir is what current opencode creates on first run; the
142 // legacy %APPDATA% dir still counts as "opencode present" so a re-install
143 // can sweep the stale pre-#535 entry out of it.
144 const legacy = legacyWindowsConfigDir();
145 const installed = loc === 'global'
146 ? fs.existsSync(globalConfigDir()) || (!!legacy && fs.existsSync(legacy))
147 : fs.existsSync(file);
148 return { installed, alreadyConfigured, configPath: file };
149 }
150
151 install(loc: Location, _opts: InstallOptions): WriteResult {
152 const files: WriteResult['files'] = [];
153 files.push(writeMcpEntry(loc));
154
155 // AGENTS.md gets the short marker-fenced CodeGraph block (#704):
156 // subagents and non-MCP harnesses read AGENTS.md but never the MCP
157 // initialize instructions. Upsert self-heals a stale pre-#529 block.
158 files.push(upsertInstructionsEntry(instructionsPath(loc)));
159
160 // Self-heal a pre-#535 install that wrote to %APPDATA%/opencode —
161 // opencode never reads it, so anything of ours there is stale.
162 if (loc === 'global') files.push(...cleanupLegacyWindowsState());
163
164 return { files };
165 }
166
167 uninstall(loc: Location): WriteResult {
168 const files: WriteResult['files'] = [];
169 files.push(removeMcpEntryAt(configPath(loc)));
170 files.push(removeInstructionsEntry(loc));
171 if (loc === 'global') files.push(...cleanupLegacyWindowsState());
172 return { files };
173 }
174
175 printConfig(loc: Location): string {
176 const target = configPath(loc);
177 const snippet = JSON.stringify({
178 $schema: 'https://opencode.ai/config.json',
179 mcp: { codegraph: getOpencodeServerEntry() },
180 }, null, 2);
181 return `# Add to ${target}\n\n${snippet}\n`;
182 }
183
184 describePaths(loc: Location): string[] {
185 return [configPath(loc), instructionsPath(loc)];

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected