@cortexkit/opencode-magic-context 0.2.5 → 0.2.6
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 +3 -3
- package/dist/cli/config-paths.d.ts.map +1 -1
- package/dist/cli/opencode-helpers.d.ts.map +1 -1
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli.js +96 -42
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -99,9 +99,9 @@ Create `magic-context.jsonc` in your project root, `.opencode/`, or `~/.config/o
|
|
|
99
99
|
|
|
100
100
|
That's it. Everything else has sensible defaults. Project config merges on top of user-wide settings.
|
|
101
101
|
|
|
102
|
-
### Oh-My-OpenCode Users
|
|
102
|
+
### Oh-My-OpenCode / Oh-My-OpenAgent Users
|
|
103
103
|
|
|
104
|
-
If you use [oh-my-
|
|
104
|
+
If you use [oh-my-openagent](https://github.com/code-yeongyu/oh-my-openagent) (formerly oh-my-opencode), disable the hooks that conflict with Magic Context in your `oh-my-openagent.json`:
|
|
105
105
|
|
|
106
106
|
```json
|
|
107
107
|
{
|
|
@@ -113,7 +113,7 @@ If you use [oh-my-opencode](https://github.com/code-yeongyu/oh-my-opencode), dis
|
|
|
113
113
|
}
|
|
114
114
|
```
|
|
115
115
|
|
|
116
|
-
The setup wizard handles this automatically if it detects an oh-my-opencode config.
|
|
116
|
+
The setup wizard handles this automatically if it detects an oh-my-openagent or oh-my-opencode config.
|
|
117
117
|
|
|
118
118
|
---
|
|
119
119
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-paths.d.ts","sourceRoot":"","sources":["../../src/cli/config-paths.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IAChD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;
|
|
1
|
+
{"version":3,"file":"config-paths.d.ts","sourceRoot":"","sources":["../../src/cli/config-paths.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IAChD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAmCD,wBAAgB,iBAAiB,IAAI,WAAW,CA2B/C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opencode-helpers.d.ts","sourceRoot":"","sources":["../../src/cli/opencode-helpers.ts"],"names":[],"mappings":"AAEA,wBAAgB,mBAAmB,IAAI,OAAO,CAO7C;AAED,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAMlD;AAED,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CAU7C;AAED,2CAA2C;AAC3C,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAU7E;AAED,2CAA2C;AAC3C,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CASvD;AAED,uDAAuD;AACvD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAE3E;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAC/B,SAAS,EAAE,MAAM,EAAE,EACnB,IAAI,EAAE,WAAW,GAAG,SAAS,GAAG,UAAU,GAC3C;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,EAAE,
|
|
1
|
+
{"version":3,"file":"opencode-helpers.d.ts","sourceRoot":"","sources":["../../src/cli/opencode-helpers.ts"],"names":[],"mappings":"AAEA,wBAAgB,mBAAmB,IAAI,OAAO,CAO7C;AAED,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAMlD;AAED,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CAU7C;AAED,2CAA2C;AAC3C,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAU7E;AAED,2CAA2C;AAC3C,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CASvD;AAED,uDAAuD;AACvD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAE3E;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAC/B,SAAS,EAAE,MAAM,EAAE,EACnB,IAAI,EAAE,WAAW,GAAG,SAAS,GAAG,UAAU,GAC3C;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,EAAE,CA0D3D"}
|
package/dist/cli/setup.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/cli/setup.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/cli/setup.ts"],"names":[],"mappings":"AAgMA,wBAAsB,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,CAmKhD"}
|
package/dist/cli.js
CHANGED
|
@@ -116,6 +116,8 @@ function getConfigDir() {
|
|
|
116
116
|
}
|
|
117
117
|
function findOmoConfig(configDir) {
|
|
118
118
|
const locations = [
|
|
119
|
+
join(configDir, "oh-my-openagent.jsonc"),
|
|
120
|
+
join(configDir, "oh-my-openagent.json"),
|
|
119
121
|
join(configDir, "oh-my-opencode.jsonc"),
|
|
120
122
|
join(configDir, "oh-my-opencode.json")
|
|
121
123
|
];
|
|
@@ -179,64 +181,49 @@ function getAvailableModels() {
|
|
|
179
181
|
function buildModelSelection(allModels, role) {
|
|
180
182
|
const result = [];
|
|
181
183
|
const added = new Set;
|
|
182
|
-
const addIfAvailable = (pattern,
|
|
184
|
+
const addIfAvailable = (pattern, hint) => {
|
|
183
185
|
const matches = allModels.filter((m) => m === pattern || m.endsWith(`/${pattern}`));
|
|
184
186
|
for (const m of matches) {
|
|
185
187
|
if (!added.has(m)) {
|
|
186
188
|
added.add(m);
|
|
187
189
|
result.push({
|
|
188
|
-
label: m,
|
|
190
|
+
label: hint ? `${m} — ${hint}` : m,
|
|
189
191
|
value: m,
|
|
190
|
-
recommended:
|
|
192
|
+
recommended: result.length === 0
|
|
191
193
|
});
|
|
192
194
|
}
|
|
193
195
|
}
|
|
194
196
|
};
|
|
195
197
|
if (role === "historian") {
|
|
196
|
-
addIfAvailable("claude-sonnet-4
|
|
197
|
-
addIfAvailable("claude-sonnet-4-
|
|
198
|
-
addIfAvailable("
|
|
199
|
-
addIfAvailable("gpt-5.4");
|
|
200
|
-
addIfAvailable("
|
|
201
|
-
addIfAvailable("minimax-m2.7");
|
|
202
|
-
|
|
203
|
-
if (!added.has(m)) {
|
|
204
|
-
added.add(m);
|
|
205
|
-
result.push({ label: `${m} (free with Copilot)`, value: m });
|
|
206
|
-
}
|
|
207
|
-
}
|
|
198
|
+
addIfAvailable("github-copilot/claude-sonnet-4.6", "per-request billing");
|
|
199
|
+
addIfAvailable("anthropic/claude-sonnet-4-6");
|
|
200
|
+
addIfAvailable("github-copilot/gpt-5.4", "per-request billing");
|
|
201
|
+
addIfAvailable("openai/gpt-5.4");
|
|
202
|
+
addIfAvailable("github-copilot/gemini-3.1-pro-preview", "per-request billing");
|
|
203
|
+
addIfAvailable("opencode-go/minimax-m2.7");
|
|
204
|
+
addIfAvailable("opencode-go/glm-5");
|
|
208
205
|
} else if (role === "dreamer") {
|
|
209
206
|
for (const m of allModels.filter((m2) => m2.startsWith("ollama/"))) {
|
|
210
207
|
if (!added.has(m)) {
|
|
211
208
|
added.add(m);
|
|
212
|
-
result.push({ label: `${m}
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
addIfAvailable("claude-sonnet-4-6", result.length === 0);
|
|
216
|
-
addIfAvailable("gemini-3-flash");
|
|
217
|
-
addIfAvailable("glm-5");
|
|
218
|
-
addIfAvailable("minimax-m2.7");
|
|
219
|
-
addIfAvailable("gpt-5.4-mini");
|
|
220
|
-
for (const m of allModels.filter((m2) => m2.startsWith("github-copilot/"))) {
|
|
221
|
-
if (!added.has(m)) {
|
|
222
|
-
added.add(m);
|
|
223
|
-
result.push({ label: `${m} (free with Copilot)`, value: m });
|
|
209
|
+
result.push({ label: `${m} — local`, value: m, recommended: result.length === 0 });
|
|
224
210
|
}
|
|
225
211
|
}
|
|
212
|
+
addIfAvailable("github-copilot/claude-sonnet-4.6", "per-request billing");
|
|
213
|
+
addIfAvailable("anthropic/claude-sonnet-4-6");
|
|
214
|
+
addIfAvailable("github-copilot/gemini-3-flash-preview", "per-request billing");
|
|
215
|
+
addIfAvailable("opencode-go/glm-5");
|
|
216
|
+
addIfAvailable("opencode-go/minimax-m2.7");
|
|
226
217
|
} else if (role === "sidekick") {
|
|
227
218
|
for (const m of allModels.filter((m2) => m2.startsWith("cerebras/"))) {
|
|
228
219
|
if (!added.has(m)) {
|
|
229
220
|
added.add(m);
|
|
230
|
-
result.push({
|
|
231
|
-
label: `${m} (fastest)`,
|
|
232
|
-
value: m,
|
|
233
|
-
recommended: result.length === 0
|
|
234
|
-
});
|
|
221
|
+
result.push({ label: m, value: m, recommended: result.length === 0 });
|
|
235
222
|
}
|
|
236
223
|
}
|
|
237
|
-
addIfAvailable("gpt-5-nano");
|
|
238
|
-
addIfAvailable("gemini-3-flash");
|
|
239
|
-
addIfAvailable("gpt-5
|
|
224
|
+
addIfAvailable("opencode/gpt-5-nano");
|
|
225
|
+
addIfAvailable("github-copilot/gemini-3-flash-preview");
|
|
226
|
+
addIfAvailable("github-copilot/gpt-5-mini");
|
|
240
227
|
}
|
|
241
228
|
return result;
|
|
242
229
|
}
|
|
@@ -1293,15 +1280,55 @@ function ensureDir(dir) {
|
|
|
1293
1280
|
mkdirSync(dir, { recursive: true });
|
|
1294
1281
|
}
|
|
1295
1282
|
}
|
|
1296
|
-
function
|
|
1297
|
-
|
|
1283
|
+
function stripJsoncToJson(text) {
|
|
1284
|
+
let result = "";
|
|
1285
|
+
let i = 0;
|
|
1286
|
+
let inString = false;
|
|
1287
|
+
let escaped = false;
|
|
1288
|
+
while (i < text.length) {
|
|
1289
|
+
const ch = text[i];
|
|
1290
|
+
if (escaped) {
|
|
1291
|
+
result += ch;
|
|
1292
|
+
escaped = false;
|
|
1293
|
+
i++;
|
|
1294
|
+
continue;
|
|
1295
|
+
}
|
|
1296
|
+
if (inString) {
|
|
1297
|
+
if (ch === "\\")
|
|
1298
|
+
escaped = true;
|
|
1299
|
+
else if (ch === '"')
|
|
1300
|
+
inString = false;
|
|
1301
|
+
result += ch;
|
|
1302
|
+
i++;
|
|
1303
|
+
continue;
|
|
1304
|
+
}
|
|
1305
|
+
if (ch === "/" && text[i + 1] === "/") {
|
|
1306
|
+
while (i < text.length && text[i] !== `
|
|
1307
|
+
`)
|
|
1308
|
+
i++;
|
|
1309
|
+
continue;
|
|
1310
|
+
}
|
|
1311
|
+
if (ch === "/" && text[i + 1] === "*") {
|
|
1312
|
+
i += 2;
|
|
1313
|
+
while (i < text.length && !(text[i] === "*" && text[i + 1] === "/"))
|
|
1314
|
+
i++;
|
|
1315
|
+
i += 2;
|
|
1316
|
+
continue;
|
|
1317
|
+
}
|
|
1318
|
+
if (ch === '"')
|
|
1319
|
+
inString = true;
|
|
1320
|
+
result += ch;
|
|
1321
|
+
i++;
|
|
1322
|
+
}
|
|
1323
|
+
return result.replace(/,(\s*[}\]])/g, "$1");
|
|
1298
1324
|
}
|
|
1299
1325
|
function readJsonc(path) {
|
|
1300
1326
|
const content = readFileSync(path, "utf-8");
|
|
1301
1327
|
try {
|
|
1302
|
-
return JSON.parse(
|
|
1303
|
-
} catch {
|
|
1304
|
-
|
|
1328
|
+
return JSON.parse(stripJsoncToJson(content));
|
|
1329
|
+
} catch (err) {
|
|
1330
|
+
console.error(` ⚠ Failed to parse ${path}: ${err instanceof Error ? err.message : err}`);
|
|
1331
|
+
return null;
|
|
1305
1332
|
}
|
|
1306
1333
|
}
|
|
1307
1334
|
function addPluginToOpenCodeConfig(configPath, format) {
|
|
@@ -1316,6 +1343,10 @@ function addPluginToOpenCodeConfig(configPath, format) {
|
|
|
1316
1343
|
return;
|
|
1317
1344
|
}
|
|
1318
1345
|
const existing = readJsonc(configPath);
|
|
1346
|
+
if (!existing) {
|
|
1347
|
+
R2.warn(`Could not parse ${configPath} — skipping to avoid data loss`);
|
|
1348
|
+
return;
|
|
1349
|
+
}
|
|
1319
1350
|
const plugins = existing.plugin ?? [];
|
|
1320
1351
|
const hasPlugin = plugins.some((p) => p === PLUGIN_NAME || p.startsWith(`${PLUGIN_NAME}@`));
|
|
1321
1352
|
if (!hasPlugin) {
|
|
@@ -1330,7 +1361,7 @@ function addPluginToOpenCodeConfig(configPath, format) {
|
|
|
1330
1361
|
`);
|
|
1331
1362
|
}
|
|
1332
1363
|
function writeMagicContextConfig(configPath, options) {
|
|
1333
|
-
const config = existsSync2(configPath) ? readJsonc(configPath) : {};
|
|
1364
|
+
const config = (existsSync2(configPath) ? readJsonc(configPath) : null) ?? {};
|
|
1334
1365
|
if (options.historianModel) {
|
|
1335
1366
|
const historian = config.historian ?? {};
|
|
1336
1367
|
historian.model = options.historianModel;
|
|
@@ -1356,11 +1387,23 @@ function writeMagicContextConfig(configPath, options) {
|
|
|
1356
1387
|
}
|
|
1357
1388
|
config.sidekick = sidekick;
|
|
1358
1389
|
}
|
|
1390
|
+
if (options.claudeMax) {
|
|
1391
|
+
const cacheTtl = config.cache_ttl ?? {};
|
|
1392
|
+
if (!cacheTtl.default)
|
|
1393
|
+
cacheTtl.default = "5m";
|
|
1394
|
+
cacheTtl["anthropic/claude-sonnet-4-6"] = "59m";
|
|
1395
|
+
cacheTtl["anthropic/claude-opus-4-6"] = "59m";
|
|
1396
|
+
config.cache_ttl = cacheTtl;
|
|
1397
|
+
}
|
|
1359
1398
|
writeFileSync(configPath, `${JSON.stringify(config, null, 2)}
|
|
1360
1399
|
`);
|
|
1361
1400
|
}
|
|
1362
1401
|
function disableOmoHooks(omoConfigPath) {
|
|
1363
1402
|
const config = readJsonc(omoConfigPath);
|
|
1403
|
+
if (!config) {
|
|
1404
|
+
R2.warn(`Could not parse ${omoConfigPath} — skipping to avoid data loss`);
|
|
1405
|
+
return;
|
|
1406
|
+
}
|
|
1364
1407
|
const disabledHooks = config.disabled_hooks ?? [];
|
|
1365
1408
|
const hooksToDisable = [
|
|
1366
1409
|
"context-window-monitor",
|
|
@@ -1446,12 +1489,23 @@ async function runSetup() {
|
|
|
1446
1489
|
} else if (sidekickEnabled) {
|
|
1447
1490
|
R2.info("Using built-in fallback chain for sidekick");
|
|
1448
1491
|
}
|
|
1492
|
+
const hasAnthropic = allModels.some((m) => m.startsWith("anthropic/"));
|
|
1493
|
+
let claudeMax = false;
|
|
1494
|
+
if (hasAnthropic) {
|
|
1495
|
+
R2.message(`Claude Max/Pro subscribers get extended prompt caching (up to 1 hour).
|
|
1496
|
+
` + "This lets Magic Context defer context operations much longer, saving money.");
|
|
1497
|
+
claudeMax = await confirm("Do you have a Claude Max or Pro subscription?", false);
|
|
1498
|
+
if (claudeMax) {
|
|
1499
|
+
R2.success("Cache TTL set to 59m for Anthropic models");
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1449
1502
|
writeMagicContextConfig(paths.magicContextConfig, {
|
|
1450
1503
|
historianModel,
|
|
1451
1504
|
dreamerEnabled,
|
|
1452
1505
|
dreamerModel,
|
|
1453
1506
|
sidekickEnabled,
|
|
1454
|
-
sidekickModel
|
|
1507
|
+
sidekickModel,
|
|
1508
|
+
claudeMax
|
|
1455
1509
|
});
|
|
1456
1510
|
R2.success(`Config written to ${paths.magicContextConfig}`);
|
|
1457
1511
|
if (paths.omoConfig) {
|
package/package.json
CHANGED