ocx 1.0.5 → 1.0.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/dist/index.js +769 -153
- package/dist/index.js.map +9 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -13082,7 +13082,8 @@ var componentManifestSchema = exports_external.object({
|
|
|
13082
13082
|
npmDependencies: exports_external.array(exports_external.string()).optional(),
|
|
13083
13083
|
npmDevDependencies: exports_external.array(exports_external.string()).optional(),
|
|
13084
13084
|
mcpServers: exports_external.record(mcpServerSchema).optional(),
|
|
13085
|
-
mcpScope: exports_external.enum(["agent", "global"]).default("agent")
|
|
13085
|
+
mcpScope: exports_external.enum(["agent", "global"]).default("agent"),
|
|
13086
|
+
disabledTools: exports_external.array(exports_external.string()).optional()
|
|
13086
13087
|
});
|
|
13087
13088
|
var semverRegex = /^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$/;
|
|
13088
13089
|
var registrySchema = exports_external.object({
|
|
@@ -13251,6 +13252,93 @@ async function fetchFileContent(baseUrl, componentName, filePath) {
|
|
|
13251
13252
|
return response.text();
|
|
13252
13253
|
}
|
|
13253
13254
|
|
|
13255
|
+
// src/registry/resolver.ts
|
|
13256
|
+
async function resolveDependencies(registries, componentNames) {
|
|
13257
|
+
const resolved = new Map;
|
|
13258
|
+
const visiting = new Set;
|
|
13259
|
+
const mcpServers = {};
|
|
13260
|
+
const agentMcpBindings = [];
|
|
13261
|
+
const npmDeps = new Set;
|
|
13262
|
+
const npmDevDeps = new Set;
|
|
13263
|
+
const disabledTools = new Set;
|
|
13264
|
+
async function resolve2(name, path3 = []) {
|
|
13265
|
+
if (resolved.has(name)) {
|
|
13266
|
+
return;
|
|
13267
|
+
}
|
|
13268
|
+
if (visiting.has(name)) {
|
|
13269
|
+
const cycle = [...path3, name].join(" \u2192 ");
|
|
13270
|
+
throw new ValidationError(`Circular dependency detected: ${cycle}`);
|
|
13271
|
+
}
|
|
13272
|
+
visiting.add(name);
|
|
13273
|
+
let component = null;
|
|
13274
|
+
let foundRegistry = null;
|
|
13275
|
+
const registryEntries = Object.entries(registries);
|
|
13276
|
+
for (const [regName, regConfig] of registryEntries) {
|
|
13277
|
+
try {
|
|
13278
|
+
const manifest = await fetchComponent(regConfig.url, name);
|
|
13279
|
+
component = manifest;
|
|
13280
|
+
foundRegistry = { name: regName, url: regConfig.url };
|
|
13281
|
+
break;
|
|
13282
|
+
} catch (_err) {}
|
|
13283
|
+
}
|
|
13284
|
+
if (!component || !foundRegistry) {
|
|
13285
|
+
throw new OCXError(`Component '${name}' not found in any configured registry.`, "NOT_FOUND");
|
|
13286
|
+
}
|
|
13287
|
+
for (const dep of component.dependencies) {
|
|
13288
|
+
await resolve2(dep, [...path3, name]);
|
|
13289
|
+
}
|
|
13290
|
+
resolved.set(name, {
|
|
13291
|
+
...component,
|
|
13292
|
+
registryName: foundRegistry.name,
|
|
13293
|
+
baseUrl: foundRegistry.url
|
|
13294
|
+
});
|
|
13295
|
+
visiting.delete(name);
|
|
13296
|
+
if (component.mcpServers) {
|
|
13297
|
+
const serverNames = [];
|
|
13298
|
+
for (const [serverName, config2] of Object.entries(component.mcpServers)) {
|
|
13299
|
+
mcpServers[serverName] = config2;
|
|
13300
|
+
serverNames.push(serverName);
|
|
13301
|
+
}
|
|
13302
|
+
const scope = component.mcpScope ?? "agent";
|
|
13303
|
+
if (component.type === "ocx:agent" && scope === "agent" && serverNames.length > 0) {
|
|
13304
|
+
agentMcpBindings.push({
|
|
13305
|
+
agentName: component.name,
|
|
13306
|
+
serverNames
|
|
13307
|
+
});
|
|
13308
|
+
}
|
|
13309
|
+
}
|
|
13310
|
+
if (component.npmDependencies) {
|
|
13311
|
+
for (const dep of component.npmDependencies) {
|
|
13312
|
+
npmDeps.add(dep);
|
|
13313
|
+
}
|
|
13314
|
+
}
|
|
13315
|
+
if (component.npmDevDependencies) {
|
|
13316
|
+
for (const dep of component.npmDevDependencies) {
|
|
13317
|
+
npmDevDeps.add(dep);
|
|
13318
|
+
}
|
|
13319
|
+
}
|
|
13320
|
+
if (component.disabledTools) {
|
|
13321
|
+
for (const tool of component.disabledTools) {
|
|
13322
|
+
disabledTools.add(tool);
|
|
13323
|
+
}
|
|
13324
|
+
}
|
|
13325
|
+
}
|
|
13326
|
+
for (const name of componentNames) {
|
|
13327
|
+
await resolve2(name);
|
|
13328
|
+
}
|
|
13329
|
+
const components = Array.from(resolved.values());
|
|
13330
|
+
const installOrder = Array.from(resolved.keys());
|
|
13331
|
+
return {
|
|
13332
|
+
components,
|
|
13333
|
+
installOrder,
|
|
13334
|
+
mcpServers,
|
|
13335
|
+
agentMcpBindings,
|
|
13336
|
+
npmDependencies: Array.from(npmDeps),
|
|
13337
|
+
npmDevDependencies: Array.from(npmDevDeps),
|
|
13338
|
+
disabledTools: Array.from(disabledTools)
|
|
13339
|
+
};
|
|
13340
|
+
}
|
|
13341
|
+
|
|
13254
13342
|
// ../../node_modules/.bun/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/scanner.js
|
|
13255
13343
|
function createScanner(text2, ignoreTrivia = false) {
|
|
13256
13344
|
const len = text2.length;
|
|
@@ -13699,6 +13787,249 @@ var cachedBreakLinesWithSpaces = {
|
|
|
13699
13787
|
})
|
|
13700
13788
|
}
|
|
13701
13789
|
};
|
|
13790
|
+
var supportedEols = [`
|
|
13791
|
+
`, "\r", `\r
|
|
13792
|
+
`];
|
|
13793
|
+
|
|
13794
|
+
// ../../node_modules/.bun/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/format.js
|
|
13795
|
+
function format(documentText, range, options2) {
|
|
13796
|
+
let initialIndentLevel;
|
|
13797
|
+
let formatText;
|
|
13798
|
+
let formatTextStart;
|
|
13799
|
+
let rangeStart;
|
|
13800
|
+
let rangeEnd;
|
|
13801
|
+
if (range) {
|
|
13802
|
+
rangeStart = range.offset;
|
|
13803
|
+
rangeEnd = rangeStart + range.length;
|
|
13804
|
+
formatTextStart = rangeStart;
|
|
13805
|
+
while (formatTextStart > 0 && !isEOL(documentText, formatTextStart - 1)) {
|
|
13806
|
+
formatTextStart--;
|
|
13807
|
+
}
|
|
13808
|
+
let endOffset = rangeEnd;
|
|
13809
|
+
while (endOffset < documentText.length && !isEOL(documentText, endOffset)) {
|
|
13810
|
+
endOffset++;
|
|
13811
|
+
}
|
|
13812
|
+
formatText = documentText.substring(formatTextStart, endOffset);
|
|
13813
|
+
initialIndentLevel = computeIndentLevel(formatText, options2);
|
|
13814
|
+
} else {
|
|
13815
|
+
formatText = documentText;
|
|
13816
|
+
initialIndentLevel = 0;
|
|
13817
|
+
formatTextStart = 0;
|
|
13818
|
+
rangeStart = 0;
|
|
13819
|
+
rangeEnd = documentText.length;
|
|
13820
|
+
}
|
|
13821
|
+
const eol = getEOL(options2, documentText);
|
|
13822
|
+
const eolFastPathSupported = supportedEols.includes(eol);
|
|
13823
|
+
let numberLineBreaks = 0;
|
|
13824
|
+
let indentLevel = 0;
|
|
13825
|
+
let indentValue;
|
|
13826
|
+
if (options2.insertSpaces) {
|
|
13827
|
+
indentValue = cachedSpaces[options2.tabSize || 4] ?? repeat(cachedSpaces[1], options2.tabSize || 4);
|
|
13828
|
+
} else {
|
|
13829
|
+
indentValue = "\t";
|
|
13830
|
+
}
|
|
13831
|
+
const indentType = indentValue === "\t" ? "\t" : " ";
|
|
13832
|
+
let scanner = createScanner(formatText, false);
|
|
13833
|
+
let hasError = false;
|
|
13834
|
+
function newLinesAndIndent() {
|
|
13835
|
+
if (numberLineBreaks > 1) {
|
|
13836
|
+
return repeat(eol, numberLineBreaks) + repeat(indentValue, initialIndentLevel + indentLevel);
|
|
13837
|
+
}
|
|
13838
|
+
const amountOfSpaces = indentValue.length * (initialIndentLevel + indentLevel);
|
|
13839
|
+
if (!eolFastPathSupported || amountOfSpaces > cachedBreakLinesWithSpaces[indentType][eol].length) {
|
|
13840
|
+
return eol + repeat(indentValue, initialIndentLevel + indentLevel);
|
|
13841
|
+
}
|
|
13842
|
+
if (amountOfSpaces <= 0) {
|
|
13843
|
+
return eol;
|
|
13844
|
+
}
|
|
13845
|
+
return cachedBreakLinesWithSpaces[indentType][eol][amountOfSpaces];
|
|
13846
|
+
}
|
|
13847
|
+
function scanNext() {
|
|
13848
|
+
let token = scanner.scan();
|
|
13849
|
+
numberLineBreaks = 0;
|
|
13850
|
+
while (token === 15 || token === 14) {
|
|
13851
|
+
if (token === 14 && options2.keepLines) {
|
|
13852
|
+
numberLineBreaks += 1;
|
|
13853
|
+
} else if (token === 14) {
|
|
13854
|
+
numberLineBreaks = 1;
|
|
13855
|
+
}
|
|
13856
|
+
token = scanner.scan();
|
|
13857
|
+
}
|
|
13858
|
+
hasError = token === 16 || scanner.getTokenError() !== 0;
|
|
13859
|
+
return token;
|
|
13860
|
+
}
|
|
13861
|
+
const editOperations = [];
|
|
13862
|
+
function addEdit(text2, startOffset, endOffset) {
|
|
13863
|
+
if (!hasError && (!range || startOffset < rangeEnd && endOffset > rangeStart) && documentText.substring(startOffset, endOffset) !== text2) {
|
|
13864
|
+
editOperations.push({ offset: startOffset, length: endOffset - startOffset, content: text2 });
|
|
13865
|
+
}
|
|
13866
|
+
}
|
|
13867
|
+
let firstToken = scanNext();
|
|
13868
|
+
if (options2.keepLines && numberLineBreaks > 0) {
|
|
13869
|
+
addEdit(repeat(eol, numberLineBreaks), 0, 0);
|
|
13870
|
+
}
|
|
13871
|
+
if (firstToken !== 17) {
|
|
13872
|
+
let firstTokenStart = scanner.getTokenOffset() + formatTextStart;
|
|
13873
|
+
let initialIndent = indentValue.length * initialIndentLevel < 20 && options2.insertSpaces ? cachedSpaces[indentValue.length * initialIndentLevel] : repeat(indentValue, initialIndentLevel);
|
|
13874
|
+
addEdit(initialIndent, formatTextStart, firstTokenStart);
|
|
13875
|
+
}
|
|
13876
|
+
while (firstToken !== 17) {
|
|
13877
|
+
let firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart;
|
|
13878
|
+
let secondToken = scanNext();
|
|
13879
|
+
let replaceContent = "";
|
|
13880
|
+
let needsLineBreak = false;
|
|
13881
|
+
while (numberLineBreaks === 0 && (secondToken === 12 || secondToken === 13)) {
|
|
13882
|
+
let commentTokenStart = scanner.getTokenOffset() + formatTextStart;
|
|
13883
|
+
addEdit(cachedSpaces[1], firstTokenEnd, commentTokenStart);
|
|
13884
|
+
firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart;
|
|
13885
|
+
needsLineBreak = secondToken === 12;
|
|
13886
|
+
replaceContent = needsLineBreak ? newLinesAndIndent() : "";
|
|
13887
|
+
secondToken = scanNext();
|
|
13888
|
+
}
|
|
13889
|
+
if (secondToken === 2) {
|
|
13890
|
+
if (firstToken !== 1) {
|
|
13891
|
+
indentLevel--;
|
|
13892
|
+
}
|
|
13893
|
+
if (options2.keepLines && numberLineBreaks > 0 || !options2.keepLines && firstToken !== 1) {
|
|
13894
|
+
replaceContent = newLinesAndIndent();
|
|
13895
|
+
} else if (options2.keepLines) {
|
|
13896
|
+
replaceContent = cachedSpaces[1];
|
|
13897
|
+
}
|
|
13898
|
+
} else if (secondToken === 4) {
|
|
13899
|
+
if (firstToken !== 3) {
|
|
13900
|
+
indentLevel--;
|
|
13901
|
+
}
|
|
13902
|
+
if (options2.keepLines && numberLineBreaks > 0 || !options2.keepLines && firstToken !== 3) {
|
|
13903
|
+
replaceContent = newLinesAndIndent();
|
|
13904
|
+
} else if (options2.keepLines) {
|
|
13905
|
+
replaceContent = cachedSpaces[1];
|
|
13906
|
+
}
|
|
13907
|
+
} else {
|
|
13908
|
+
switch (firstToken) {
|
|
13909
|
+
case 3:
|
|
13910
|
+
case 1:
|
|
13911
|
+
indentLevel++;
|
|
13912
|
+
if (options2.keepLines && numberLineBreaks > 0 || !options2.keepLines) {
|
|
13913
|
+
replaceContent = newLinesAndIndent();
|
|
13914
|
+
} else {
|
|
13915
|
+
replaceContent = cachedSpaces[1];
|
|
13916
|
+
}
|
|
13917
|
+
break;
|
|
13918
|
+
case 5:
|
|
13919
|
+
if (options2.keepLines && numberLineBreaks > 0 || !options2.keepLines) {
|
|
13920
|
+
replaceContent = newLinesAndIndent();
|
|
13921
|
+
} else {
|
|
13922
|
+
replaceContent = cachedSpaces[1];
|
|
13923
|
+
}
|
|
13924
|
+
break;
|
|
13925
|
+
case 12:
|
|
13926
|
+
replaceContent = newLinesAndIndent();
|
|
13927
|
+
break;
|
|
13928
|
+
case 13:
|
|
13929
|
+
if (numberLineBreaks > 0) {
|
|
13930
|
+
replaceContent = newLinesAndIndent();
|
|
13931
|
+
} else if (!needsLineBreak) {
|
|
13932
|
+
replaceContent = cachedSpaces[1];
|
|
13933
|
+
}
|
|
13934
|
+
break;
|
|
13935
|
+
case 6:
|
|
13936
|
+
if (options2.keepLines && numberLineBreaks > 0) {
|
|
13937
|
+
replaceContent = newLinesAndIndent();
|
|
13938
|
+
} else if (!needsLineBreak) {
|
|
13939
|
+
replaceContent = cachedSpaces[1];
|
|
13940
|
+
}
|
|
13941
|
+
break;
|
|
13942
|
+
case 10:
|
|
13943
|
+
if (options2.keepLines && numberLineBreaks > 0) {
|
|
13944
|
+
replaceContent = newLinesAndIndent();
|
|
13945
|
+
} else if (secondToken === 6 && !needsLineBreak) {
|
|
13946
|
+
replaceContent = "";
|
|
13947
|
+
}
|
|
13948
|
+
break;
|
|
13949
|
+
case 7:
|
|
13950
|
+
case 8:
|
|
13951
|
+
case 9:
|
|
13952
|
+
case 11:
|
|
13953
|
+
case 2:
|
|
13954
|
+
case 4:
|
|
13955
|
+
if (options2.keepLines && numberLineBreaks > 0) {
|
|
13956
|
+
replaceContent = newLinesAndIndent();
|
|
13957
|
+
} else {
|
|
13958
|
+
if ((secondToken === 12 || secondToken === 13) && !needsLineBreak) {
|
|
13959
|
+
replaceContent = cachedSpaces[1];
|
|
13960
|
+
} else if (secondToken !== 5 && secondToken !== 17) {
|
|
13961
|
+
hasError = true;
|
|
13962
|
+
}
|
|
13963
|
+
}
|
|
13964
|
+
break;
|
|
13965
|
+
case 16:
|
|
13966
|
+
hasError = true;
|
|
13967
|
+
break;
|
|
13968
|
+
}
|
|
13969
|
+
if (numberLineBreaks > 0 && (secondToken === 12 || secondToken === 13)) {
|
|
13970
|
+
replaceContent = newLinesAndIndent();
|
|
13971
|
+
}
|
|
13972
|
+
}
|
|
13973
|
+
if (secondToken === 17) {
|
|
13974
|
+
if (options2.keepLines && numberLineBreaks > 0) {
|
|
13975
|
+
replaceContent = newLinesAndIndent();
|
|
13976
|
+
} else {
|
|
13977
|
+
replaceContent = options2.insertFinalNewline ? eol : "";
|
|
13978
|
+
}
|
|
13979
|
+
}
|
|
13980
|
+
const secondTokenStart = scanner.getTokenOffset() + formatTextStart;
|
|
13981
|
+
addEdit(replaceContent, firstTokenEnd, secondTokenStart);
|
|
13982
|
+
firstToken = secondToken;
|
|
13983
|
+
}
|
|
13984
|
+
return editOperations;
|
|
13985
|
+
}
|
|
13986
|
+
function repeat(s2, count) {
|
|
13987
|
+
let result = "";
|
|
13988
|
+
for (let i2 = 0;i2 < count; i2++) {
|
|
13989
|
+
result += s2;
|
|
13990
|
+
}
|
|
13991
|
+
return result;
|
|
13992
|
+
}
|
|
13993
|
+
function computeIndentLevel(content, options2) {
|
|
13994
|
+
let i2 = 0;
|
|
13995
|
+
let nChars = 0;
|
|
13996
|
+
const tabSize = options2.tabSize || 4;
|
|
13997
|
+
while (i2 < content.length) {
|
|
13998
|
+
let ch = content.charAt(i2);
|
|
13999
|
+
if (ch === cachedSpaces[1]) {
|
|
14000
|
+
nChars++;
|
|
14001
|
+
} else if (ch === "\t") {
|
|
14002
|
+
nChars += tabSize;
|
|
14003
|
+
} else {
|
|
14004
|
+
break;
|
|
14005
|
+
}
|
|
14006
|
+
i2++;
|
|
14007
|
+
}
|
|
14008
|
+
return Math.floor(nChars / tabSize);
|
|
14009
|
+
}
|
|
14010
|
+
function getEOL(options2, text2) {
|
|
14011
|
+
for (let i2 = 0;i2 < text2.length; i2++) {
|
|
14012
|
+
const ch = text2.charAt(i2);
|
|
14013
|
+
if (ch === "\r") {
|
|
14014
|
+
if (i2 + 1 < text2.length && text2.charAt(i2 + 1) === `
|
|
14015
|
+
`) {
|
|
14016
|
+
return `\r
|
|
14017
|
+
`;
|
|
14018
|
+
}
|
|
14019
|
+
return "\r";
|
|
14020
|
+
} else if (ch === `
|
|
14021
|
+
`) {
|
|
14022
|
+
return `
|
|
14023
|
+
`;
|
|
14024
|
+
}
|
|
14025
|
+
}
|
|
14026
|
+
return options2 && options2.eol || `
|
|
14027
|
+
`;
|
|
14028
|
+
}
|
|
14029
|
+
function isEOL(text2, offset) {
|
|
14030
|
+
return `\r
|
|
14031
|
+
`.indexOf(text2.charAt(offset)) !== -1;
|
|
14032
|
+
}
|
|
13702
14033
|
|
|
13703
14034
|
// ../../node_modules/.bun/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/parser.js
|
|
13704
14035
|
var ParseOptions;
|
|
@@ -13750,6 +14081,95 @@ function parse(text2, errors2 = [], options2 = ParseOptions.DEFAULT) {
|
|
|
13750
14081
|
visit(text2, visitor, options2);
|
|
13751
14082
|
return currentParent[0];
|
|
13752
14083
|
}
|
|
14084
|
+
function parseTree(text2, errors2 = [], options2 = ParseOptions.DEFAULT) {
|
|
14085
|
+
let currentParent = { type: "array", offset: -1, length: -1, children: [], parent: undefined };
|
|
14086
|
+
function ensurePropertyComplete(endOffset) {
|
|
14087
|
+
if (currentParent.type === "property") {
|
|
14088
|
+
currentParent.length = endOffset - currentParent.offset;
|
|
14089
|
+
currentParent = currentParent.parent;
|
|
14090
|
+
}
|
|
14091
|
+
}
|
|
14092
|
+
function onValue(valueNode) {
|
|
14093
|
+
currentParent.children.push(valueNode);
|
|
14094
|
+
return valueNode;
|
|
14095
|
+
}
|
|
14096
|
+
const visitor = {
|
|
14097
|
+
onObjectBegin: (offset) => {
|
|
14098
|
+
currentParent = onValue({ type: "object", offset, length: -1, parent: currentParent, children: [] });
|
|
14099
|
+
},
|
|
14100
|
+
onObjectProperty: (name, offset, length) => {
|
|
14101
|
+
currentParent = onValue({ type: "property", offset, length: -1, parent: currentParent, children: [] });
|
|
14102
|
+
currentParent.children.push({ type: "string", value: name, offset, length, parent: currentParent });
|
|
14103
|
+
},
|
|
14104
|
+
onObjectEnd: (offset, length) => {
|
|
14105
|
+
ensurePropertyComplete(offset + length);
|
|
14106
|
+
currentParent.length = offset + length - currentParent.offset;
|
|
14107
|
+
currentParent = currentParent.parent;
|
|
14108
|
+
ensurePropertyComplete(offset + length);
|
|
14109
|
+
},
|
|
14110
|
+
onArrayBegin: (offset, length) => {
|
|
14111
|
+
currentParent = onValue({ type: "array", offset, length: -1, parent: currentParent, children: [] });
|
|
14112
|
+
},
|
|
14113
|
+
onArrayEnd: (offset, length) => {
|
|
14114
|
+
currentParent.length = offset + length - currentParent.offset;
|
|
14115
|
+
currentParent = currentParent.parent;
|
|
14116
|
+
ensurePropertyComplete(offset + length);
|
|
14117
|
+
},
|
|
14118
|
+
onLiteralValue: (value, offset, length) => {
|
|
14119
|
+
onValue({ type: getNodeType(value), offset, length, parent: currentParent, value });
|
|
14120
|
+
ensurePropertyComplete(offset + length);
|
|
14121
|
+
},
|
|
14122
|
+
onSeparator: (sep, offset, length) => {
|
|
14123
|
+
if (currentParent.type === "property") {
|
|
14124
|
+
if (sep === ":") {
|
|
14125
|
+
currentParent.colonOffset = offset;
|
|
14126
|
+
} else if (sep === ",") {
|
|
14127
|
+
ensurePropertyComplete(offset);
|
|
14128
|
+
}
|
|
14129
|
+
}
|
|
14130
|
+
},
|
|
14131
|
+
onError: (error, offset, length) => {
|
|
14132
|
+
errors2.push({ error, offset, length });
|
|
14133
|
+
}
|
|
14134
|
+
};
|
|
14135
|
+
visit(text2, visitor, options2);
|
|
14136
|
+
const result = currentParent.children[0];
|
|
14137
|
+
if (result) {
|
|
14138
|
+
delete result.parent;
|
|
14139
|
+
}
|
|
14140
|
+
return result;
|
|
14141
|
+
}
|
|
14142
|
+
function findNodeAtLocation(root, path3) {
|
|
14143
|
+
if (!root) {
|
|
14144
|
+
return;
|
|
14145
|
+
}
|
|
14146
|
+
let node = root;
|
|
14147
|
+
for (let segment of path3) {
|
|
14148
|
+
if (typeof segment === "string") {
|
|
14149
|
+
if (node.type !== "object" || !Array.isArray(node.children)) {
|
|
14150
|
+
return;
|
|
14151
|
+
}
|
|
14152
|
+
let found = false;
|
|
14153
|
+
for (const propertyNode of node.children) {
|
|
14154
|
+
if (Array.isArray(propertyNode.children) && propertyNode.children[0].value === segment && propertyNode.children.length === 2) {
|
|
14155
|
+
node = propertyNode.children[1];
|
|
14156
|
+
found = true;
|
|
14157
|
+
break;
|
|
14158
|
+
}
|
|
14159
|
+
}
|
|
14160
|
+
if (!found) {
|
|
14161
|
+
return;
|
|
14162
|
+
}
|
|
14163
|
+
} else {
|
|
14164
|
+
const index = segment;
|
|
14165
|
+
if (node.type !== "array" || index < 0 || !Array.isArray(node.children) || index >= node.children.length) {
|
|
14166
|
+
return;
|
|
14167
|
+
}
|
|
14168
|
+
node = node.children[index];
|
|
14169
|
+
}
|
|
14170
|
+
}
|
|
14171
|
+
return node;
|
|
14172
|
+
}
|
|
13753
14173
|
function visit(text2, visitor, options2 = ParseOptions.DEFAULT) {
|
|
13754
14174
|
const _scanner = createScanner(text2, false);
|
|
13755
14175
|
const _jsonPath = [];
|
|
@@ -14002,6 +14422,170 @@ function visit(text2, visitor, options2 = ParseOptions.DEFAULT) {
|
|
|
14002
14422
|
}
|
|
14003
14423
|
return true;
|
|
14004
14424
|
}
|
|
14425
|
+
function getNodeType(value) {
|
|
14426
|
+
switch (typeof value) {
|
|
14427
|
+
case "boolean":
|
|
14428
|
+
return "boolean";
|
|
14429
|
+
case "number":
|
|
14430
|
+
return "number";
|
|
14431
|
+
case "string":
|
|
14432
|
+
return "string";
|
|
14433
|
+
case "object": {
|
|
14434
|
+
if (!value) {
|
|
14435
|
+
return "null";
|
|
14436
|
+
} else if (Array.isArray(value)) {
|
|
14437
|
+
return "array";
|
|
14438
|
+
}
|
|
14439
|
+
return "object";
|
|
14440
|
+
}
|
|
14441
|
+
default:
|
|
14442
|
+
return "null";
|
|
14443
|
+
}
|
|
14444
|
+
}
|
|
14445
|
+
|
|
14446
|
+
// ../../node_modules/.bun/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/edit.js
|
|
14447
|
+
function setProperty(text2, originalPath, value, options2) {
|
|
14448
|
+
const path3 = originalPath.slice();
|
|
14449
|
+
const errors2 = [];
|
|
14450
|
+
const root = parseTree(text2, errors2);
|
|
14451
|
+
let parent = undefined;
|
|
14452
|
+
let lastSegment = undefined;
|
|
14453
|
+
while (path3.length > 0) {
|
|
14454
|
+
lastSegment = path3.pop();
|
|
14455
|
+
parent = findNodeAtLocation(root, path3);
|
|
14456
|
+
if (parent === undefined && value !== undefined) {
|
|
14457
|
+
if (typeof lastSegment === "string") {
|
|
14458
|
+
value = { [lastSegment]: value };
|
|
14459
|
+
} else {
|
|
14460
|
+
value = [value];
|
|
14461
|
+
}
|
|
14462
|
+
} else {
|
|
14463
|
+
break;
|
|
14464
|
+
}
|
|
14465
|
+
}
|
|
14466
|
+
if (!parent) {
|
|
14467
|
+
if (value === undefined) {
|
|
14468
|
+
throw new Error("Can not delete in empty document");
|
|
14469
|
+
}
|
|
14470
|
+
return withFormatting(text2, { offset: root ? root.offset : 0, length: root ? root.length : 0, content: JSON.stringify(value) }, options2);
|
|
14471
|
+
} else if (parent.type === "object" && typeof lastSegment === "string" && Array.isArray(parent.children)) {
|
|
14472
|
+
const existing = findNodeAtLocation(parent, [lastSegment]);
|
|
14473
|
+
if (existing !== undefined) {
|
|
14474
|
+
if (value === undefined) {
|
|
14475
|
+
if (!existing.parent) {
|
|
14476
|
+
throw new Error("Malformed AST");
|
|
14477
|
+
}
|
|
14478
|
+
const propertyIndex = parent.children.indexOf(existing.parent);
|
|
14479
|
+
let removeBegin;
|
|
14480
|
+
let removeEnd = existing.parent.offset + existing.parent.length;
|
|
14481
|
+
if (propertyIndex > 0) {
|
|
14482
|
+
let previous = parent.children[propertyIndex - 1];
|
|
14483
|
+
removeBegin = previous.offset + previous.length;
|
|
14484
|
+
} else {
|
|
14485
|
+
removeBegin = parent.offset + 1;
|
|
14486
|
+
if (parent.children.length > 1) {
|
|
14487
|
+
let next = parent.children[1];
|
|
14488
|
+
removeEnd = next.offset;
|
|
14489
|
+
}
|
|
14490
|
+
}
|
|
14491
|
+
return withFormatting(text2, { offset: removeBegin, length: removeEnd - removeBegin, content: "" }, options2);
|
|
14492
|
+
} else {
|
|
14493
|
+
return withFormatting(text2, { offset: existing.offset, length: existing.length, content: JSON.stringify(value) }, options2);
|
|
14494
|
+
}
|
|
14495
|
+
} else {
|
|
14496
|
+
if (value === undefined) {
|
|
14497
|
+
return [];
|
|
14498
|
+
}
|
|
14499
|
+
const newProperty = `${JSON.stringify(lastSegment)}: ${JSON.stringify(value)}`;
|
|
14500
|
+
const index = options2.getInsertionIndex ? options2.getInsertionIndex(parent.children.map((p2) => p2.children[0].value)) : parent.children.length;
|
|
14501
|
+
let edit;
|
|
14502
|
+
if (index > 0) {
|
|
14503
|
+
let previous = parent.children[index - 1];
|
|
14504
|
+
edit = { offset: previous.offset + previous.length, length: 0, content: "," + newProperty };
|
|
14505
|
+
} else if (parent.children.length === 0) {
|
|
14506
|
+
edit = { offset: parent.offset + 1, length: 0, content: newProperty };
|
|
14507
|
+
} else {
|
|
14508
|
+
edit = { offset: parent.offset + 1, length: 0, content: newProperty + "," };
|
|
14509
|
+
}
|
|
14510
|
+
return withFormatting(text2, edit, options2);
|
|
14511
|
+
}
|
|
14512
|
+
} else if (parent.type === "array" && typeof lastSegment === "number" && Array.isArray(parent.children)) {
|
|
14513
|
+
const insertIndex = lastSegment;
|
|
14514
|
+
if (insertIndex === -1) {
|
|
14515
|
+
const newProperty = `${JSON.stringify(value)}`;
|
|
14516
|
+
let edit;
|
|
14517
|
+
if (parent.children.length === 0) {
|
|
14518
|
+
edit = { offset: parent.offset + 1, length: 0, content: newProperty };
|
|
14519
|
+
} else {
|
|
14520
|
+
const previous = parent.children[parent.children.length - 1];
|
|
14521
|
+
edit = { offset: previous.offset + previous.length, length: 0, content: "," + newProperty };
|
|
14522
|
+
}
|
|
14523
|
+
return withFormatting(text2, edit, options2);
|
|
14524
|
+
} else if (value === undefined && parent.children.length >= 0) {
|
|
14525
|
+
const removalIndex = lastSegment;
|
|
14526
|
+
const toRemove = parent.children[removalIndex];
|
|
14527
|
+
let edit;
|
|
14528
|
+
if (parent.children.length === 1) {
|
|
14529
|
+
edit = { offset: parent.offset + 1, length: parent.length - 2, content: "" };
|
|
14530
|
+
} else if (parent.children.length - 1 === removalIndex) {
|
|
14531
|
+
let previous = parent.children[removalIndex - 1];
|
|
14532
|
+
let offset = previous.offset + previous.length;
|
|
14533
|
+
let parentEndOffset = parent.offset + parent.length;
|
|
14534
|
+
edit = { offset, length: parentEndOffset - 2 - offset, content: "" };
|
|
14535
|
+
} else {
|
|
14536
|
+
edit = { offset: toRemove.offset, length: parent.children[removalIndex + 1].offset - toRemove.offset, content: "" };
|
|
14537
|
+
}
|
|
14538
|
+
return withFormatting(text2, edit, options2);
|
|
14539
|
+
} else if (value !== undefined) {
|
|
14540
|
+
let edit;
|
|
14541
|
+
const newProperty = `${JSON.stringify(value)}`;
|
|
14542
|
+
if (!options2.isArrayInsertion && parent.children.length > lastSegment) {
|
|
14543
|
+
const toModify = parent.children[lastSegment];
|
|
14544
|
+
edit = { offset: toModify.offset, length: toModify.length, content: newProperty };
|
|
14545
|
+
} else if (parent.children.length === 0 || lastSegment === 0) {
|
|
14546
|
+
edit = { offset: parent.offset + 1, length: 0, content: parent.children.length === 0 ? newProperty : newProperty + "," };
|
|
14547
|
+
} else {
|
|
14548
|
+
const index = lastSegment > parent.children.length ? parent.children.length : lastSegment;
|
|
14549
|
+
const previous = parent.children[index - 1];
|
|
14550
|
+
edit = { offset: previous.offset + previous.length, length: 0, content: "," + newProperty };
|
|
14551
|
+
}
|
|
14552
|
+
return withFormatting(text2, edit, options2);
|
|
14553
|
+
} else {
|
|
14554
|
+
throw new Error(`Can not ${value === undefined ? "remove" : options2.isArrayInsertion ? "insert" : "modify"} Array index ${insertIndex} as length is not sufficient`);
|
|
14555
|
+
}
|
|
14556
|
+
} else {
|
|
14557
|
+
throw new Error(`Can not add ${typeof lastSegment !== "number" ? "index" : "property"} to parent of type ${parent.type}`);
|
|
14558
|
+
}
|
|
14559
|
+
}
|
|
14560
|
+
function withFormatting(text2, edit, options2) {
|
|
14561
|
+
if (!options2.formattingOptions) {
|
|
14562
|
+
return [edit];
|
|
14563
|
+
}
|
|
14564
|
+
let newText = applyEdit(text2, edit);
|
|
14565
|
+
let begin = edit.offset;
|
|
14566
|
+
let end = edit.offset + edit.content.length;
|
|
14567
|
+
if (edit.length === 0 || edit.content.length === 0) {
|
|
14568
|
+
while (begin > 0 && !isEOL(newText, begin - 1)) {
|
|
14569
|
+
begin--;
|
|
14570
|
+
}
|
|
14571
|
+
while (end < newText.length && !isEOL(newText, end)) {
|
|
14572
|
+
end++;
|
|
14573
|
+
}
|
|
14574
|
+
}
|
|
14575
|
+
const edits = format(newText, { offset: begin, length: end - begin }, { ...options2.formattingOptions, keepLines: false });
|
|
14576
|
+
for (let i2 = edits.length - 1;i2 >= 0; i2--) {
|
|
14577
|
+
const edit2 = edits[i2];
|
|
14578
|
+
newText = applyEdit(newText, edit2);
|
|
14579
|
+
begin = Math.min(begin, edit2.offset);
|
|
14580
|
+
end = Math.max(end, edit2.offset + edit2.length);
|
|
14581
|
+
end += edit2.content.length - edit2.length;
|
|
14582
|
+
}
|
|
14583
|
+
const editLength = text2.length - (newText.length - end) - begin;
|
|
14584
|
+
return [{ offset: begin, length: editLength, content: newText.substring(begin, end) }];
|
|
14585
|
+
}
|
|
14586
|
+
function applyEdit(text2, edit) {
|
|
14587
|
+
return text2.substring(0, edit.offset) + edit.content + text2.substring(edit.offset + edit.length);
|
|
14588
|
+
}
|
|
14005
14589
|
|
|
14006
14590
|
// ../../node_modules/.bun/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/main.js
|
|
14007
14591
|
var ScanError;
|
|
@@ -14054,158 +14638,28 @@ var ParseErrorCode;
|
|
|
14054
14638
|
ParseErrorCode2[ParseErrorCode2["InvalidEscapeCharacter"] = 15] = "InvalidEscapeCharacter";
|
|
14055
14639
|
ParseErrorCode2[ParseErrorCode2["InvalidCharacter"] = 16] = "InvalidCharacter";
|
|
14056
14640
|
})(ParseErrorCode || (ParseErrorCode = {}));
|
|
14057
|
-
|
|
14058
|
-
|
|
14059
|
-
async function readOpencodeConfig(cwd) {
|
|
14060
|
-
const jsonPath = `${cwd}/opencode.json`;
|
|
14061
|
-
const jsoncPath = `${cwd}/opencode.jsonc`;
|
|
14062
|
-
for (const configPath of [jsoncPath, jsonPath]) {
|
|
14063
|
-
const file = Bun.file(configPath);
|
|
14064
|
-
if (await file.exists()) {
|
|
14065
|
-
const content = await file.text();
|
|
14066
|
-
return {
|
|
14067
|
-
config: parse2(content, [], { allowTrailingComma: true }),
|
|
14068
|
-
path: configPath
|
|
14069
|
-
};
|
|
14070
|
-
}
|
|
14071
|
-
}
|
|
14072
|
-
return null;
|
|
14073
|
-
}
|
|
14074
|
-
async function writeOpencodeConfig(path3, config2) {
|
|
14075
|
-
const content = JSON.stringify(config2, null, 2);
|
|
14076
|
-
await Bun.write(path3, content);
|
|
14077
|
-
}
|
|
14078
|
-
function applyMcpServers(config2, mcpServers) {
|
|
14079
|
-
const added = [];
|
|
14080
|
-
const skipped = [];
|
|
14081
|
-
if (!config2.mcp) {
|
|
14082
|
-
config2.mcp = {};
|
|
14083
|
-
}
|
|
14084
|
-
for (const [name, server] of Object.entries(mcpServers)) {
|
|
14085
|
-
if (config2.mcp[name]) {
|
|
14086
|
-
skipped.push(name);
|
|
14087
|
-
} else {
|
|
14088
|
-
const serverConfig = {
|
|
14089
|
-
type: server.type,
|
|
14090
|
-
enabled: server.enabled
|
|
14091
|
-
};
|
|
14092
|
-
if (server.type === "remote" && server.url) {
|
|
14093
|
-
serverConfig.url = server.url;
|
|
14094
|
-
}
|
|
14095
|
-
if (server.type === "local" && server.command) {
|
|
14096
|
-
serverConfig.command = server.command;
|
|
14097
|
-
}
|
|
14098
|
-
if (server.headers) {
|
|
14099
|
-
serverConfig.headers = server.headers;
|
|
14100
|
-
}
|
|
14101
|
-
config2.mcp[name] = serverConfig;
|
|
14102
|
-
added.push(name);
|
|
14103
|
-
}
|
|
14104
|
-
}
|
|
14105
|
-
return { config: config2, added, skipped };
|
|
14106
|
-
}
|
|
14107
|
-
async function updateOpencodeConfig(cwd, options2) {
|
|
14108
|
-
const existing = await readOpencodeConfig(cwd);
|
|
14109
|
-
let config2;
|
|
14110
|
-
let configPath;
|
|
14111
|
-
let created = false;
|
|
14112
|
-
if (existing) {
|
|
14113
|
-
config2 = existing.config;
|
|
14114
|
-
configPath = existing.path;
|
|
14115
|
-
} else {
|
|
14116
|
-
config2 = {
|
|
14117
|
-
$schema: "https://opencode.ai/config.json"
|
|
14118
|
-
};
|
|
14119
|
-
configPath = `${cwd}/opencode.json`;
|
|
14120
|
-
created = true;
|
|
14121
|
-
}
|
|
14122
|
-
let mcpAdded = [];
|
|
14123
|
-
let mcpSkipped = [];
|
|
14124
|
-
if (options2.mcpServers && Object.keys(options2.mcpServers).length > 0) {
|
|
14125
|
-
const result = applyMcpServers(config2, options2.mcpServers);
|
|
14126
|
-
config2 = result.config;
|
|
14127
|
-
mcpAdded = result.added;
|
|
14128
|
-
mcpSkipped = result.skipped;
|
|
14129
|
-
}
|
|
14130
|
-
if (options2.defaultAgent && !config2.default_agent) {
|
|
14131
|
-
config2.default_agent = options2.defaultAgent;
|
|
14132
|
-
}
|
|
14133
|
-
await writeOpencodeConfig(configPath, config2);
|
|
14134
|
-
return {
|
|
14135
|
-
path: configPath,
|
|
14136
|
-
created,
|
|
14137
|
-
mcpAdded,
|
|
14138
|
-
mcpSkipped
|
|
14139
|
-
};
|
|
14641
|
+
function modify(text2, path3, value, options2) {
|
|
14642
|
+
return setProperty(text2, path3, value, options2);
|
|
14140
14643
|
}
|
|
14141
|
-
|
|
14142
|
-
|
|
14143
|
-
|
|
14144
|
-
|
|
14145
|
-
|
|
14146
|
-
const mcpServers = {};
|
|
14147
|
-
const npmDeps = new Set;
|
|
14148
|
-
const npmDevDeps = new Set;
|
|
14149
|
-
async function resolve2(name, path3 = []) {
|
|
14150
|
-
if (resolved.has(name)) {
|
|
14151
|
-
return;
|
|
14644
|
+
function applyEdits(text2, edits) {
|
|
14645
|
+
let sortedEdits = edits.slice(0).sort((a3, b2) => {
|
|
14646
|
+
const diff = a3.offset - b2.offset;
|
|
14647
|
+
if (diff === 0) {
|
|
14648
|
+
return a3.length - b2.length;
|
|
14152
14649
|
}
|
|
14153
|
-
|
|
14154
|
-
|
|
14155
|
-
|
|
14156
|
-
|
|
14157
|
-
|
|
14158
|
-
|
|
14159
|
-
|
|
14160
|
-
|
|
14161
|
-
|
|
14162
|
-
try {
|
|
14163
|
-
const manifest = await fetchComponent(regConfig.url, name);
|
|
14164
|
-
component = manifest;
|
|
14165
|
-
foundRegistry = { name: regName, url: regConfig.url };
|
|
14166
|
-
break;
|
|
14167
|
-
} catch (_err) {}
|
|
14168
|
-
}
|
|
14169
|
-
if (!component || !foundRegistry) {
|
|
14170
|
-
throw new OCXError(`Component '${name}' not found in any configured registry.`, "NOT_FOUND");
|
|
14171
|
-
}
|
|
14172
|
-
for (const dep of component.dependencies) {
|
|
14173
|
-
await resolve2(dep, [...path3, name]);
|
|
14174
|
-
}
|
|
14175
|
-
resolved.set(name, {
|
|
14176
|
-
...component,
|
|
14177
|
-
registryName: foundRegistry.name,
|
|
14178
|
-
baseUrl: foundRegistry.url
|
|
14179
|
-
});
|
|
14180
|
-
visiting.delete(name);
|
|
14181
|
-
if (component.mcpServers) {
|
|
14182
|
-
for (const [serverName, config2] of Object.entries(component.mcpServers)) {
|
|
14183
|
-
mcpServers[serverName] = config2;
|
|
14184
|
-
}
|
|
14185
|
-
}
|
|
14186
|
-
if (component.npmDependencies) {
|
|
14187
|
-
for (const dep of component.npmDependencies) {
|
|
14188
|
-
npmDeps.add(dep);
|
|
14189
|
-
}
|
|
14190
|
-
}
|
|
14191
|
-
if (component.npmDevDependencies) {
|
|
14192
|
-
for (const dep of component.npmDevDependencies) {
|
|
14193
|
-
npmDevDeps.add(dep);
|
|
14194
|
-
}
|
|
14650
|
+
return diff;
|
|
14651
|
+
});
|
|
14652
|
+
let lastModifiedOffset = text2.length;
|
|
14653
|
+
for (let i2 = sortedEdits.length - 1;i2 >= 0; i2--) {
|
|
14654
|
+
let e2 = sortedEdits[i2];
|
|
14655
|
+
if (e2.offset + e2.length <= lastModifiedOffset) {
|
|
14656
|
+
text2 = applyEdit(text2, e2);
|
|
14657
|
+
} else {
|
|
14658
|
+
throw new Error("Overlapping edit");
|
|
14195
14659
|
}
|
|
14660
|
+
lastModifiedOffset = e2.offset;
|
|
14196
14661
|
}
|
|
14197
|
-
|
|
14198
|
-
await resolve2(name);
|
|
14199
|
-
}
|
|
14200
|
-
const components = Array.from(resolved.values());
|
|
14201
|
-
const installOrder = Array.from(resolved.keys());
|
|
14202
|
-
return {
|
|
14203
|
-
components,
|
|
14204
|
-
installOrder,
|
|
14205
|
-
mcpServers,
|
|
14206
|
-
npmDependencies: Array.from(npmDeps),
|
|
14207
|
-
npmDevDependencies: Array.from(npmDevDeps)
|
|
14208
|
-
};
|
|
14662
|
+
return text2;
|
|
14209
14663
|
}
|
|
14210
14664
|
|
|
14211
14665
|
// src/schemas/config.ts
|
|
@@ -14274,6 +14728,158 @@ async function readOcxLock(cwd) {
|
|
|
14274
14728
|
return ocxLockSchema.parse(json);
|
|
14275
14729
|
}
|
|
14276
14730
|
|
|
14731
|
+
// src/updaters/update-opencode-config.ts
|
|
14732
|
+
var JSONC_OPTIONS = {
|
|
14733
|
+
formattingOptions: {
|
|
14734
|
+
tabSize: 2,
|
|
14735
|
+
insertSpaces: false,
|
|
14736
|
+
eol: `
|
|
14737
|
+
`
|
|
14738
|
+
}
|
|
14739
|
+
};
|
|
14740
|
+
async function readOpencodeConfig(cwd) {
|
|
14741
|
+
const jsonPath = `${cwd}/opencode.json`;
|
|
14742
|
+
const jsoncPath = `${cwd}/opencode.jsonc`;
|
|
14743
|
+
for (const configPath of [jsoncPath, jsonPath]) {
|
|
14744
|
+
const file = Bun.file(configPath);
|
|
14745
|
+
if (await file.exists()) {
|
|
14746
|
+
const content = await file.text();
|
|
14747
|
+
return {
|
|
14748
|
+
config: parse2(content, [], { allowTrailingComma: true }),
|
|
14749
|
+
content,
|
|
14750
|
+
path: configPath
|
|
14751
|
+
};
|
|
14752
|
+
}
|
|
14753
|
+
}
|
|
14754
|
+
return null;
|
|
14755
|
+
}
|
|
14756
|
+
async function writeOpencodeConfig(path3, content) {
|
|
14757
|
+
await Bun.write(path3, content);
|
|
14758
|
+
}
|
|
14759
|
+
function applyMcpServers(content, config2, mcpServers) {
|
|
14760
|
+
const added = [];
|
|
14761
|
+
const skipped = [];
|
|
14762
|
+
let updatedContent = content;
|
|
14763
|
+
const existingMcp = config2.mcp ?? {};
|
|
14764
|
+
for (const [name, server] of Object.entries(mcpServers)) {
|
|
14765
|
+
if (existingMcp[name]) {
|
|
14766
|
+
skipped.push(name);
|
|
14767
|
+
continue;
|
|
14768
|
+
}
|
|
14769
|
+
const serverConfig = {
|
|
14770
|
+
type: server.type
|
|
14771
|
+
};
|
|
14772
|
+
if (server.type === "remote" && server.url) {
|
|
14773
|
+
serverConfig.url = server.url;
|
|
14774
|
+
}
|
|
14775
|
+
if (server.type === "local" && server.command) {
|
|
14776
|
+
serverConfig.command = server.command;
|
|
14777
|
+
}
|
|
14778
|
+
if (server.headers) {
|
|
14779
|
+
serverConfig.headers = server.headers;
|
|
14780
|
+
}
|
|
14781
|
+
if (server.enabled !== undefined) {
|
|
14782
|
+
serverConfig.enabled = server.enabled;
|
|
14783
|
+
}
|
|
14784
|
+
const edits = modify(updatedContent, ["mcp", name], serverConfig, JSONC_OPTIONS);
|
|
14785
|
+
updatedContent = applyEdits(updatedContent, edits);
|
|
14786
|
+
added.push(name);
|
|
14787
|
+
}
|
|
14788
|
+
return { content: updatedContent, added, skipped };
|
|
14789
|
+
}
|
|
14790
|
+
function applyGlobalToolDisables(content, serverNames) {
|
|
14791
|
+
let updatedContent = content;
|
|
14792
|
+
for (const name of serverNames) {
|
|
14793
|
+
const toolPattern = `${name}_*`;
|
|
14794
|
+
const edits = modify(updatedContent, ["tools", toolPattern], false, JSONC_OPTIONS);
|
|
14795
|
+
updatedContent = applyEdits(updatedContent, edits);
|
|
14796
|
+
}
|
|
14797
|
+
return updatedContent;
|
|
14798
|
+
}
|
|
14799
|
+
function applyDisabledTools(content, toolNames) {
|
|
14800
|
+
let updatedContent = content;
|
|
14801
|
+
for (const name of toolNames) {
|
|
14802
|
+
const edits = modify(updatedContent, ["tools", name], false, JSONC_OPTIONS);
|
|
14803
|
+
updatedContent = applyEdits(updatedContent, edits);
|
|
14804
|
+
}
|
|
14805
|
+
return updatedContent;
|
|
14806
|
+
}
|
|
14807
|
+
function applyAgentToolEnables(content, bindings) {
|
|
14808
|
+
let updatedContent = content;
|
|
14809
|
+
const agentsConfigured = [];
|
|
14810
|
+
for (const binding of bindings) {
|
|
14811
|
+
for (const serverName of binding.serverNames) {
|
|
14812
|
+
const toolPattern = `${serverName}_*`;
|
|
14813
|
+
const edits = modify(updatedContent, ["agent", binding.agentName, "tools", toolPattern], true, JSONC_OPTIONS);
|
|
14814
|
+
updatedContent = applyEdits(updatedContent, edits);
|
|
14815
|
+
}
|
|
14816
|
+
if (binding.serverNames.length > 0) {
|
|
14817
|
+
agentsConfigured.push(binding.agentName);
|
|
14818
|
+
}
|
|
14819
|
+
}
|
|
14820
|
+
return { content: updatedContent, agentsConfigured: [...new Set(agentsConfigured)] };
|
|
14821
|
+
}
|
|
14822
|
+
function applyDefaultAgent(content, config2, defaultAgent) {
|
|
14823
|
+
if (config2.default_agent) {
|
|
14824
|
+
return content;
|
|
14825
|
+
}
|
|
14826
|
+
const edits = modify(content, ["default_agent"], defaultAgent, JSONC_OPTIONS);
|
|
14827
|
+
return applyEdits(content, edits);
|
|
14828
|
+
}
|
|
14829
|
+
async function updateOpencodeConfig(cwd, options2) {
|
|
14830
|
+
const existing = await readOpencodeConfig(cwd);
|
|
14831
|
+
let content;
|
|
14832
|
+
let config2;
|
|
14833
|
+
let configPath;
|
|
14834
|
+
let created = false;
|
|
14835
|
+
if (existing) {
|
|
14836
|
+
content = existing.content;
|
|
14837
|
+
config2 = existing.config;
|
|
14838
|
+
configPath = existing.path;
|
|
14839
|
+
} else {
|
|
14840
|
+
config2 = { $schema: "https://opencode.ai/config.json" };
|
|
14841
|
+
content = JSON.stringify(config2, null, "\t");
|
|
14842
|
+
configPath = `${cwd}/opencode.json`;
|
|
14843
|
+
created = true;
|
|
14844
|
+
}
|
|
14845
|
+
let mcpAdded = [];
|
|
14846
|
+
let mcpSkipped = [];
|
|
14847
|
+
let agentsConfigured = [];
|
|
14848
|
+
let toolsDisabled = [];
|
|
14849
|
+
if (options2.mcpServers && Object.keys(options2.mcpServers).length > 0) {
|
|
14850
|
+
const result = applyMcpServers(content, config2, options2.mcpServers);
|
|
14851
|
+
content = result.content;
|
|
14852
|
+
mcpAdded = result.added;
|
|
14853
|
+
mcpSkipped = result.skipped;
|
|
14854
|
+
}
|
|
14855
|
+
if (options2.agentMcpBindings && options2.agentMcpBindings.length > 0) {
|
|
14856
|
+
const allScopedServers = [...new Set(options2.agentMcpBindings.flatMap((b2) => b2.serverNames))];
|
|
14857
|
+
if (allScopedServers.length > 0) {
|
|
14858
|
+
content = applyGlobalToolDisables(content, allScopedServers);
|
|
14859
|
+
const agentResult = applyAgentToolEnables(content, options2.agentMcpBindings);
|
|
14860
|
+
content = agentResult.content;
|
|
14861
|
+
agentsConfigured = agentResult.agentsConfigured;
|
|
14862
|
+
}
|
|
14863
|
+
}
|
|
14864
|
+
if (options2.defaultAgent) {
|
|
14865
|
+
const updatedConfig = parse2(content, [], { allowTrailingComma: true });
|
|
14866
|
+
content = applyDefaultAgent(content, updatedConfig, options2.defaultAgent);
|
|
14867
|
+
}
|
|
14868
|
+
if (options2.disabledTools && options2.disabledTools.length > 0) {
|
|
14869
|
+
content = applyDisabledTools(content, options2.disabledTools);
|
|
14870
|
+
toolsDisabled = options2.disabledTools;
|
|
14871
|
+
}
|
|
14872
|
+
await writeOpencodeConfig(configPath, content);
|
|
14873
|
+
return {
|
|
14874
|
+
path: configPath,
|
|
14875
|
+
created,
|
|
14876
|
+
mcpAdded,
|
|
14877
|
+
mcpSkipped,
|
|
14878
|
+
agentsConfigured,
|
|
14879
|
+
toolsDisabled
|
|
14880
|
+
};
|
|
14881
|
+
}
|
|
14882
|
+
|
|
14277
14883
|
// src/utils/env.ts
|
|
14278
14884
|
var isCI = Boolean(process.env.CI || process.env.GITHUB_ACTIONS || process.env.GITLAB_CI || process.env.CIRCLECI || process.env.JENKINS_URL || process.env.BUILDKITE);
|
|
14279
14885
|
var isTTY = Boolean(process.stdout.isTTY && !isCI);
|
|
@@ -15863,9 +16469,13 @@ async function runAdd(componentNames, options3) {
|
|
|
15863
16469
|
};
|
|
15864
16470
|
}
|
|
15865
16471
|
installSpin?.succeed(`Installed ${resolved.components.length} components`);
|
|
15866
|
-
|
|
16472
|
+
const hasMcpChanges = Object.keys(resolved.mcpServers).length > 0 || resolved.agentMcpBindings.length > 0;
|
|
16473
|
+
const hasDisabledTools = resolved.disabledTools.length > 0;
|
|
16474
|
+
if (hasMcpChanges || hasDisabledTools) {
|
|
15867
16475
|
const result = await updateOpencodeConfig(cwd, {
|
|
15868
|
-
mcpServers: resolved.mcpServers
|
|
16476
|
+
mcpServers: resolved.mcpServers,
|
|
16477
|
+
agentMcpBindings: resolved.agentMcpBindings,
|
|
16478
|
+
disabledTools: resolved.disabledTools
|
|
15869
16479
|
});
|
|
15870
16480
|
if (result.mcpSkipped.length > 0 && !options3.quiet) {
|
|
15871
16481
|
for (const name of result.mcpSkipped) {
|
|
@@ -15874,6 +16484,12 @@ async function runAdd(componentNames, options3) {
|
|
|
15874
16484
|
}
|
|
15875
16485
|
if (!options3.quiet && result.mcpAdded.length > 0) {
|
|
15876
16486
|
logger.info(`Configured ${result.mcpAdded.length} MCP servers`);
|
|
16487
|
+
for (const binding of resolved.agentMcpBindings) {
|
|
16488
|
+
logger.info(` Scoped to agent "${binding.agentName}": ${binding.serverNames.join(", ")}`);
|
|
16489
|
+
}
|
|
16490
|
+
}
|
|
16491
|
+
if (!options3.quiet && result.toolsDisabled.length > 0) {
|
|
16492
|
+
logger.info(`Disabled ${result.toolsDisabled.length} tools: ${result.toolsDisabled.join(", ")}`);
|
|
15877
16493
|
}
|
|
15878
16494
|
}
|
|
15879
16495
|
const hasNpmDeps = resolved.npmDependencies.length > 0;
|
|
@@ -17229,7 +17845,7 @@ function registerSearchCommand(program2) {
|
|
|
17229
17845
|
}
|
|
17230
17846
|
|
|
17231
17847
|
// src/index.ts
|
|
17232
|
-
var version2 = "1.0.
|
|
17848
|
+
var version2 = "1.0.6";
|
|
17233
17849
|
async function main2() {
|
|
17234
17850
|
const program2 = new Command().name("ocx").description("OpenCode Extensions - Install agents, skills, plugins, and commands").version(version2);
|
|
17235
17851
|
registerInitCommand(program2);
|
|
@@ -17244,4 +17860,4 @@ main2().catch((err) => {
|
|
|
17244
17860
|
handleError(err);
|
|
17245
17861
|
});
|
|
17246
17862
|
|
|
17247
|
-
//# debugId=
|
|
17863
|
+
//# debugId=1145245802C7C7C964756E2164756E21
|