zenox 1.0.5 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/constants.d.ts +8 -0
- package/dist/cli/index.js +242 -31
- package/dist/cli/mcp-picker.d.ts +4 -0
- package/dist/cli/mcp.d.ts +1 -0
- package/dist/cli/model-picker.d.ts +4 -4
- package/dist/cli/types.d.ts +20 -0
- package/dist/cli/zenox-config.d.ts +4 -2
- package/package.json +1 -1
package/dist/cli/constants.d.ts
CHANGED
|
@@ -8,3 +8,11 @@ export interface AgentInfo {
|
|
|
8
8
|
}
|
|
9
9
|
export declare const AGENTS: AgentInfo[];
|
|
10
10
|
export declare const DEFAULT_MODELS: Record<AgentName, string>;
|
|
11
|
+
export type McpName = "exa" | "grep_app" | "sequential-thinking";
|
|
12
|
+
export interface McpInfo {
|
|
13
|
+
name: McpName;
|
|
14
|
+
displayName: string;
|
|
15
|
+
description: string;
|
|
16
|
+
recommended: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare const MCP_SERVERS: McpInfo[];
|
package/dist/cli/index.js
CHANGED
|
@@ -2256,6 +2256,9 @@ var {
|
|
|
2256
2256
|
Help
|
|
2257
2257
|
} = import__.default;
|
|
2258
2258
|
|
|
2259
|
+
// node_modules/@clack/prompts/dist/index.mjs
|
|
2260
|
+
import { stripVTControlCharacters as S2 } from "node:util";
|
|
2261
|
+
|
|
2259
2262
|
// node_modules/@clack/core/dist/index.mjs
|
|
2260
2263
|
var import_sisteransi = __toESM(require_src(), 1);
|
|
2261
2264
|
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
@@ -2880,6 +2883,21 @@ ${import_picocolors2.default.cyan(d2)}
|
|
|
2880
2883
|
}
|
|
2881
2884
|
} }).prompt();
|
|
2882
2885
|
};
|
|
2886
|
+
var Me = (t = "", n = "") => {
|
|
2887
|
+
const r2 = `
|
|
2888
|
+
${t}
|
|
2889
|
+
`.split(`
|
|
2890
|
+
`), i = S2(n).length, s = Math.max(r2.reduce((a, l2) => {
|
|
2891
|
+
const $2 = S2(l2);
|
|
2892
|
+
return $2.length > a ? $2.length : a;
|
|
2893
|
+
}, 0), i) + 2, c = r2.map((a) => `${import_picocolors2.default.gray(o)} ${import_picocolors2.default.dim(a)}${" ".repeat(s - S2(a).length)}${import_picocolors2.default.gray(o)}`).join(`
|
|
2894
|
+
`);
|
|
2895
|
+
process.stdout.write(`${import_picocolors2.default.gray(o)}
|
|
2896
|
+
${import_picocolors2.default.green(C)} ${import_picocolors2.default.reset(n)} ${import_picocolors2.default.gray(_2.repeat(Math.max(s - i - 1, 1)) + me)}
|
|
2897
|
+
${c}
|
|
2898
|
+
${import_picocolors2.default.gray(de + _2.repeat(s + 2) + pe)}
|
|
2899
|
+
`);
|
|
2900
|
+
};
|
|
2883
2901
|
var xe = (t = "") => {
|
|
2884
2902
|
process.stdout.write(`${import_picocolors2.default.gray(d2)} ${import_picocolors2.default.red(t)}
|
|
2885
2903
|
|
|
@@ -2972,7 +2990,7 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
|
2972
2990
|
};
|
|
2973
2991
|
|
|
2974
2992
|
// src/cli/install.ts
|
|
2975
|
-
var
|
|
2993
|
+
var import_picocolors5 = __toESM(require_picocolors(), 1);
|
|
2976
2994
|
|
|
2977
2995
|
// src/cli/config-manager.ts
|
|
2978
2996
|
import { existsSync } from "node:fs";
|
|
@@ -3106,6 +3124,26 @@ var DEFAULT_MODELS = {
|
|
|
3106
3124
|
oracle: "openai/gpt-5.2",
|
|
3107
3125
|
"ui-planner": "google/gemini-3-pro-high"
|
|
3108
3126
|
};
|
|
3127
|
+
var MCP_SERVERS = [
|
|
3128
|
+
{
|
|
3129
|
+
name: "exa",
|
|
3130
|
+
displayName: "Exa",
|
|
3131
|
+
description: "Web search & code context via Exa AI",
|
|
3132
|
+
recommended: true
|
|
3133
|
+
},
|
|
3134
|
+
{
|
|
3135
|
+
name: "grep_app",
|
|
3136
|
+
displayName: "grep.app",
|
|
3137
|
+
description: "GitHub code search - find real-world examples",
|
|
3138
|
+
recommended: true
|
|
3139
|
+
},
|
|
3140
|
+
{
|
|
3141
|
+
name: "sequential-thinking",
|
|
3142
|
+
displayName: "Sequential Thinking",
|
|
3143
|
+
description: "Structured reasoning for complex problems",
|
|
3144
|
+
recommended: true
|
|
3145
|
+
}
|
|
3146
|
+
];
|
|
3109
3147
|
|
|
3110
3148
|
// src/cli/config-manager.ts
|
|
3111
3149
|
var CONFIG_FILENAMES = ["opencode.json", "opencode.jsonc"];
|
|
@@ -3172,17 +3210,17 @@ function addPluginToJsonc(content) {
|
|
|
3172
3210
|
const afterTrimmed = afterBrace.trimStart();
|
|
3173
3211
|
if (afterTrimmed.startsWith("}")) {
|
|
3174
3212
|
return `${beforeBrace}
|
|
3175
|
-
"
|
|
3213
|
+
"plugin": ["${PACKAGE_NAME}"]
|
|
3176
3214
|
}`;
|
|
3177
3215
|
} else {
|
|
3178
3216
|
return `${beforeBrace}
|
|
3179
|
-
"
|
|
3217
|
+
"plugin": ["${PACKAGE_NAME}"],
|
|
3180
3218
|
${afterBrace.trimStart()}`;
|
|
3181
3219
|
}
|
|
3182
3220
|
}
|
|
3183
3221
|
}
|
|
3184
3222
|
function addPluginToJson(config) {
|
|
3185
|
-
const existingKey = config.plugins ? "plugins" : config.plugin ? "plugin" : "
|
|
3223
|
+
const existingKey = config.plugins ? "plugins" : config.plugin ? "plugin" : "plugin";
|
|
3186
3224
|
const existingPlugins = config.plugins ?? config.plugin ?? [];
|
|
3187
3225
|
const newConfig = {
|
|
3188
3226
|
[existingKey]: [PACKAGE_NAME, ...existingPlugins],
|
|
@@ -3209,7 +3247,7 @@ function getDefaultConfigPath(directory) {
|
|
|
3209
3247
|
}
|
|
3210
3248
|
async function createDefaultConfig(configPath) {
|
|
3211
3249
|
const defaultConfig = {
|
|
3212
|
-
|
|
3250
|
+
plugin: [PACKAGE_NAME]
|
|
3213
3251
|
};
|
|
3214
3252
|
await writeFile(configPath, JSON.stringify(defaultConfig, null, 2) + `
|
|
3215
3253
|
`, "utf-8");
|
|
@@ -3267,28 +3305,77 @@ function getCurrentModels(config) {
|
|
|
3267
3305
|
}
|
|
3268
3306
|
return result;
|
|
3269
3307
|
}
|
|
3308
|
+
function getDisabledMcps(config) {
|
|
3309
|
+
return config?.disabled_mcps ?? [];
|
|
3310
|
+
}
|
|
3311
|
+
async function updateDisabledMcps(disabledMcps) {
|
|
3312
|
+
const existing = await readZenoxConfig() ?? {};
|
|
3313
|
+
if (disabledMcps.length === 0) {
|
|
3314
|
+
const { disabled_mcps: _3, ...rest } = existing;
|
|
3315
|
+
if (Object.keys(rest).length === 0) {
|
|
3316
|
+
return;
|
|
3317
|
+
}
|
|
3318
|
+
await writeZenoxConfig(rest);
|
|
3319
|
+
} else {
|
|
3320
|
+
await writeZenoxConfig({
|
|
3321
|
+
...existing,
|
|
3322
|
+
disabled_mcps: disabledMcps
|
|
3323
|
+
});
|
|
3324
|
+
}
|
|
3325
|
+
}
|
|
3270
3326
|
|
|
3271
3327
|
// src/cli/model-picker.ts
|
|
3328
|
+
var import_picocolors3 = __toESM(require_picocolors(), 1);
|
|
3272
3329
|
var CUSTOM_MODEL_OPTION = "__custom__";
|
|
3330
|
+
function formatModelName(modelId) {
|
|
3331
|
+
return modelId.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
3332
|
+
}
|
|
3273
3333
|
function extractUserModels(config) {
|
|
3274
|
-
const models = new
|
|
3334
|
+
const models = new Map;
|
|
3275
3335
|
const provider = config.provider;
|
|
3276
|
-
if (
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3336
|
+
if (provider) {
|
|
3337
|
+
for (const [providerName, providerConfig] of Object.entries(provider)) {
|
|
3338
|
+
if (!providerConfig || typeof providerConfig !== "object")
|
|
3339
|
+
continue;
|
|
3340
|
+
const providerModels = providerConfig.models;
|
|
3341
|
+
if (!providerModels)
|
|
3342
|
+
continue;
|
|
3343
|
+
for (const [modelId, modelConfig] of Object.entries(providerModels)) {
|
|
3344
|
+
const fullId = `${providerName}/${modelId}`;
|
|
3345
|
+
const cfg = modelConfig;
|
|
3346
|
+
models.set(fullId, {
|
|
3347
|
+
id: fullId,
|
|
3348
|
+
displayName: cfg?.name ?? formatModelName(modelId),
|
|
3349
|
+
provider: providerName
|
|
3350
|
+
});
|
|
3351
|
+
}
|
|
3286
3352
|
}
|
|
3287
3353
|
}
|
|
3288
|
-
|
|
3354
|
+
if (config.model && typeof config.model === "string" && config.model.includes("/")) {
|
|
3355
|
+
const [providerName, modelId] = config.model.split("/");
|
|
3356
|
+
if (!models.has(config.model)) {
|
|
3357
|
+
models.set(config.model, {
|
|
3358
|
+
id: config.model,
|
|
3359
|
+
displayName: formatModelName(modelId),
|
|
3360
|
+
provider: providerName
|
|
3361
|
+
});
|
|
3362
|
+
}
|
|
3363
|
+
}
|
|
3364
|
+
if (config.small_model && typeof config.small_model === "string" && config.small_model.includes("/")) {
|
|
3365
|
+
const [providerName, modelId] = config.small_model.split("/");
|
|
3366
|
+
if (!models.has(config.small_model)) {
|
|
3367
|
+
models.set(config.small_model, {
|
|
3368
|
+
id: config.small_model,
|
|
3369
|
+
displayName: formatModelName(modelId),
|
|
3370
|
+
provider: providerName
|
|
3371
|
+
});
|
|
3372
|
+
}
|
|
3373
|
+
}
|
|
3374
|
+
return Array.from(models.values()).sort((a, b3) => a.id.localeCompare(b3.id));
|
|
3289
3375
|
}
|
|
3290
3376
|
function buildModelOptions(agent, userModels, currentModel) {
|
|
3291
3377
|
const options = [];
|
|
3378
|
+
const userModelIds = userModels.map((m2) => m2.id);
|
|
3292
3379
|
const isDefault = !currentModel || currentModel === agent.defaultModel;
|
|
3293
3380
|
options.push({
|
|
3294
3381
|
value: agent.defaultModel,
|
|
@@ -3296,16 +3383,16 @@ function buildModelOptions(agent, userModels, currentModel) {
|
|
|
3296
3383
|
hint: "Recommended - Default"
|
|
3297
3384
|
});
|
|
3298
3385
|
for (const model of userModels) {
|
|
3299
|
-
if (model === agent.defaultModel)
|
|
3386
|
+
if (model.id === agent.defaultModel)
|
|
3300
3387
|
continue;
|
|
3301
|
-
const isCurrent = currentModel === model;
|
|
3388
|
+
const isCurrent = currentModel === model.id;
|
|
3302
3389
|
options.push({
|
|
3303
|
-
value: model,
|
|
3304
|
-
label: `${model}${isCurrent ? " (Current)" : ""}`,
|
|
3305
|
-
hint:
|
|
3390
|
+
value: model.id,
|
|
3391
|
+
label: `${model.id}${isCurrent ? " (Current)" : ""}`,
|
|
3392
|
+
hint: `${model.displayName} • Your config`
|
|
3306
3393
|
});
|
|
3307
3394
|
}
|
|
3308
|
-
if (currentModel && currentModel !== agent.defaultModel && !
|
|
3395
|
+
if (currentModel && currentModel !== agent.defaultModel && !userModelIds.includes(currentModel)) {
|
|
3309
3396
|
options.push({
|
|
3310
3397
|
value: currentModel,
|
|
3311
3398
|
label: `${currentModel} (Current)`,
|
|
@@ -3320,9 +3407,11 @@ function buildModelOptions(agent, userModels, currentModel) {
|
|
|
3320
3407
|
return options;
|
|
3321
3408
|
}
|
|
3322
3409
|
async function pickModelForAgent(agent, userModels, currentModel) {
|
|
3410
|
+
Me(`${import_picocolors3.default.bold(agent.description)}
|
|
3411
|
+
${import_picocolors3.default.dim(`Default: ${agent.defaultModel}`)}`, agent.displayName);
|
|
3323
3412
|
const options = buildModelOptions(agent, userModels, currentModel);
|
|
3324
3413
|
const selected = await ve({
|
|
3325
|
-
message:
|
|
3414
|
+
message: "Select model:",
|
|
3326
3415
|
options
|
|
3327
3416
|
});
|
|
3328
3417
|
if (pD(selected))
|
|
@@ -3397,6 +3486,59 @@ async function selectAgentsToReconfigure(currentModels) {
|
|
|
3397
3486
|
return selected;
|
|
3398
3487
|
}
|
|
3399
3488
|
|
|
3489
|
+
// src/cli/mcp-picker.ts
|
|
3490
|
+
var import_picocolors4 = __toESM(require_picocolors(), 1);
|
|
3491
|
+
async function askConfigureMcps() {
|
|
3492
|
+
const result = await ve({
|
|
3493
|
+
message: "Configure MCP servers?",
|
|
3494
|
+
options: [
|
|
3495
|
+
{
|
|
3496
|
+
value: "keep_all",
|
|
3497
|
+
label: "Keep all enabled (Recommended)",
|
|
3498
|
+
hint: "All MCPs are free & enhance capabilities"
|
|
3499
|
+
},
|
|
3500
|
+
{
|
|
3501
|
+
value: "customize",
|
|
3502
|
+
label: "Customize",
|
|
3503
|
+
hint: "Disable specific MCPs"
|
|
3504
|
+
}
|
|
3505
|
+
]
|
|
3506
|
+
});
|
|
3507
|
+
if (pD(result))
|
|
3508
|
+
return null;
|
|
3509
|
+
return result;
|
|
3510
|
+
}
|
|
3511
|
+
async function pickMcpsToDisable(currentDisabled) {
|
|
3512
|
+
Me(`${import_picocolors4.default.dim("All MCPs are free and recommended for best experience.")}
|
|
3513
|
+
${import_picocolors4.default.dim("Only disable if you have specific conflicts.")}`, "MCP Servers");
|
|
3514
|
+
const options = MCP_SERVERS.map((mcp) => {
|
|
3515
|
+
const isDisabled = currentDisabled.includes(mcp.name);
|
|
3516
|
+
const hint = mcp.recommended ? `${mcp.description} ${import_picocolors4.default.green("• Recommended")}` : mcp.description;
|
|
3517
|
+
return {
|
|
3518
|
+
value: mcp.name,
|
|
3519
|
+
label: `${mcp.displayName}${isDisabled ? import_picocolors4.default.yellow(" (Currently disabled)") : ""}`,
|
|
3520
|
+
hint
|
|
3521
|
+
};
|
|
3522
|
+
});
|
|
3523
|
+
const selected = await fe({
|
|
3524
|
+
message: "Select MCPs to DISABLE:",
|
|
3525
|
+
options,
|
|
3526
|
+
required: false
|
|
3527
|
+
});
|
|
3528
|
+
if (pD(selected))
|
|
3529
|
+
return null;
|
|
3530
|
+
return selected;
|
|
3531
|
+
}
|
|
3532
|
+
function showMcpStatus(disabledMcps) {
|
|
3533
|
+
M2.info("MCP Server Status:");
|
|
3534
|
+
for (const mcp of MCP_SERVERS) {
|
|
3535
|
+
const isDisabled = disabledMcps.includes(mcp.name);
|
|
3536
|
+
const status = isDisabled ? import_picocolors4.default.red("✗ Disabled") : import_picocolors4.default.green("✓ Enabled");
|
|
3537
|
+
const rec = mcp.recommended ? import_picocolors4.default.dim(" (Recommended)") : "";
|
|
3538
|
+
M2.message(` ${mcp.displayName}: ${status}${rec}`);
|
|
3539
|
+
}
|
|
3540
|
+
}
|
|
3541
|
+
|
|
3400
3542
|
// src/cli/install.ts
|
|
3401
3543
|
async function runInstall(options = {}) {
|
|
3402
3544
|
const { noTui = false, configPath: customConfigPath } = options;
|
|
@@ -3408,7 +3550,7 @@ async function runInstall(options = {}) {
|
|
|
3408
3550
|
await runInteractive(cwd, customConfigPath);
|
|
3409
3551
|
}
|
|
3410
3552
|
async function runInteractive(cwd, customConfigPath) {
|
|
3411
|
-
Ie(
|
|
3553
|
+
Ie(import_picocolors5.default.cyan(`${PACKAGE_NAME} installer`));
|
|
3412
3554
|
const configFile = customConfigPath ? { path: customConfigPath, format: "json" } : findConfigFile(cwd);
|
|
3413
3555
|
let opencodeConfig = null;
|
|
3414
3556
|
if (!configFile) {
|
|
@@ -3491,7 +3633,33 @@ async function runInteractive(cwd, customConfigPath) {
|
|
|
3491
3633
|
M2.info("Using default models - no zenox.json needed");
|
|
3492
3634
|
}
|
|
3493
3635
|
}
|
|
3494
|
-
|
|
3636
|
+
const mcpChoice = await askConfigureMcps();
|
|
3637
|
+
if (mcpChoice === null) {
|
|
3638
|
+
xe("Installation cancelled");
|
|
3639
|
+
process.exit(0);
|
|
3640
|
+
}
|
|
3641
|
+
if (mcpChoice === "customize") {
|
|
3642
|
+
const zenoxConfig = await readZenoxConfig();
|
|
3643
|
+
const currentDisabled = getDisabledMcps(zenoxConfig);
|
|
3644
|
+
const disabledMcps = await pickMcpsToDisable(currentDisabled);
|
|
3645
|
+
if (disabledMcps === null) {
|
|
3646
|
+
xe("Installation cancelled");
|
|
3647
|
+
process.exit(0);
|
|
3648
|
+
}
|
|
3649
|
+
if (disabledMcps.length > 0) {
|
|
3650
|
+
const spinner = Y2();
|
|
3651
|
+
spinner.start("Saving MCP configuration");
|
|
3652
|
+
try {
|
|
3653
|
+
await updateDisabledMcps(disabledMcps);
|
|
3654
|
+
spinner.stop(`Disabled ${disabledMcps.length} MCP(s)`);
|
|
3655
|
+
} catch (err) {
|
|
3656
|
+
spinner.stop("Failed to save MCP config");
|
|
3657
|
+
M2.error(err instanceof Error ? err.message : "Unknown error");
|
|
3658
|
+
process.exit(1);
|
|
3659
|
+
}
|
|
3660
|
+
}
|
|
3661
|
+
}
|
|
3662
|
+
Se(import_picocolors5.default.green(`${PACKAGE_NAME} installed successfully!`));
|
|
3495
3663
|
}
|
|
3496
3664
|
async function runNonInteractive(cwd, customConfigPath) {
|
|
3497
3665
|
const configFile = customConfigPath ? { path: customConfigPath, format: "json" } : findConfigFile(cwd);
|
|
@@ -3515,9 +3683,9 @@ async function runNonInteractive(cwd, customConfigPath) {
|
|
|
3515
3683
|
}
|
|
3516
3684
|
|
|
3517
3685
|
// src/cli/config.ts
|
|
3518
|
-
var
|
|
3686
|
+
var import_picocolors6 = __toESM(require_picocolors(), 1);
|
|
3519
3687
|
async function runConfig() {
|
|
3520
|
-
Ie(
|
|
3688
|
+
Ie(import_picocolors6.default.cyan(`${PACKAGE_NAME} model configurator`));
|
|
3521
3689
|
const cwd = process.cwd();
|
|
3522
3690
|
let userModels = [];
|
|
3523
3691
|
const configFile = findConfigFile(cwd);
|
|
@@ -3533,7 +3701,7 @@ async function runConfig() {
|
|
|
3533
3701
|
for (const agent of AGENTS) {
|
|
3534
3702
|
const model = currentModels[agent.name] ?? agent.defaultModel;
|
|
3535
3703
|
const isCustom = currentModels[agent.name] !== undefined;
|
|
3536
|
-
const suffix = isCustom ?
|
|
3704
|
+
const suffix = isCustom ? import_picocolors6.default.yellow(" (custom)") : import_picocolors6.default.dim(" (default)");
|
|
3537
3705
|
M2.message(` ${agent.displayName}: ${model}${suffix}`);
|
|
3538
3706
|
}
|
|
3539
3707
|
const selectedAgents = await selectAgentsToReconfigure(currentModels);
|
|
@@ -3543,7 +3711,7 @@ async function runConfig() {
|
|
|
3543
3711
|
}
|
|
3544
3712
|
if (selectedAgents.length === 0) {
|
|
3545
3713
|
M2.warn("No agents selected");
|
|
3546
|
-
Se(
|
|
3714
|
+
Se(import_picocolors6.default.yellow("No changes made"));
|
|
3547
3715
|
return;
|
|
3548
3716
|
}
|
|
3549
3717
|
const newModels = {};
|
|
@@ -3586,7 +3754,42 @@ async function runConfig() {
|
|
|
3586
3754
|
} else {
|
|
3587
3755
|
M2.info("All agents using default models - zenox.json not needed");
|
|
3588
3756
|
}
|
|
3589
|
-
Se(
|
|
3757
|
+
Se(import_picocolors6.default.green("Configuration updated!"));
|
|
3758
|
+
}
|
|
3759
|
+
|
|
3760
|
+
// src/cli/mcp.ts
|
|
3761
|
+
var import_picocolors7 = __toESM(require_picocolors(), 1);
|
|
3762
|
+
async function runMcp() {
|
|
3763
|
+
Ie(import_picocolors7.default.cyan(`${PACKAGE_NAME} MCP configurator`));
|
|
3764
|
+
const zenoxConfig = await readZenoxConfig();
|
|
3765
|
+
const currentDisabled = getDisabledMcps(zenoxConfig);
|
|
3766
|
+
showMcpStatus(currentDisabled);
|
|
3767
|
+
const newDisabled = await pickMcpsToDisable(currentDisabled);
|
|
3768
|
+
if (newDisabled === null) {
|
|
3769
|
+
xe("Configuration cancelled");
|
|
3770
|
+
process.exit(0);
|
|
3771
|
+
}
|
|
3772
|
+
const hasChanges = newDisabled.length !== currentDisabled.length || newDisabled.some((m2) => !currentDisabled.includes(m2));
|
|
3773
|
+
if (!hasChanges) {
|
|
3774
|
+
Se(import_picocolors7.default.yellow("No changes made"));
|
|
3775
|
+
return;
|
|
3776
|
+
}
|
|
3777
|
+
const spinner = Y2();
|
|
3778
|
+
spinner.start("Saving MCP configuration");
|
|
3779
|
+
try {
|
|
3780
|
+
await updateDisabledMcps(newDisabled);
|
|
3781
|
+
if (newDisabled.length === 0) {
|
|
3782
|
+
spinner.stop("All MCPs enabled");
|
|
3783
|
+
} else {
|
|
3784
|
+
spinner.stop(`Updated ${getZenoxConfigPath()}`);
|
|
3785
|
+
}
|
|
3786
|
+
} catch (err) {
|
|
3787
|
+
spinner.stop("Failed to save config");
|
|
3788
|
+
M2.error(err instanceof Error ? err.message : "Unknown error");
|
|
3789
|
+
process.exit(1);
|
|
3790
|
+
}
|
|
3791
|
+
showMcpStatus(newDisabled);
|
|
3792
|
+
Se(import_picocolors7.default.green("MCP configuration updated!"));
|
|
3590
3793
|
}
|
|
3591
3794
|
|
|
3592
3795
|
// src/cli/index.ts
|
|
@@ -3611,4 +3814,12 @@ program2.command("config").alias("models").description("Reconfigure sub-agent mo
|
|
|
3611
3814
|
process.exit(1);
|
|
3612
3815
|
}
|
|
3613
3816
|
});
|
|
3817
|
+
program2.command("mcp").description("Configure MCP servers (enable/disable)").action(async () => {
|
|
3818
|
+
try {
|
|
3819
|
+
await runMcp();
|
|
3820
|
+
} catch (err) {
|
|
3821
|
+
console.error(err instanceof Error ? err.message : "Unknown error");
|
|
3822
|
+
process.exit(1);
|
|
3823
|
+
}
|
|
3824
|
+
});
|
|
3614
3825
|
program2.parse();
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type McpName } from "./constants";
|
|
2
|
+
export declare function askConfigureMcps(): Promise<"keep_all" | "customize" | null>;
|
|
3
|
+
export declare function pickMcpsToDisable(currentDisabled: McpName[]): Promise<McpName[] | null>;
|
|
4
|
+
export declare function showMcpStatus(disabledMcps: McpName[]): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runMcp(): Promise<void>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { OpencodeConfig } from "./types";
|
|
1
|
+
import type { OpencodeConfig, UserModelInfo } from "./types";
|
|
2
2
|
import type { AgentName, AgentInfo } from "./constants";
|
|
3
|
-
export declare function extractUserModels(config: OpencodeConfig):
|
|
4
|
-
export declare function pickModelForAgent(agent: AgentInfo, userModels:
|
|
5
|
-
export declare function pickModelsForAllAgents(userModels:
|
|
3
|
+
export declare function extractUserModels(config: OpencodeConfig): UserModelInfo[];
|
|
4
|
+
export declare function pickModelForAgent(agent: AgentInfo, userModels: UserModelInfo[], currentModel?: string): Promise<string | null>;
|
|
5
|
+
export declare function pickModelsForAllAgents(userModels: UserModelInfo[], currentModels: Partial<Record<AgentName, string>>): Promise<Partial<Record<AgentName, string>> | null>;
|
|
6
6
|
export declare function askConfigureModels(): Promise<"defaults" | "customize" | null>;
|
|
7
7
|
export declare function selectAgentsToReconfigure(currentModels: Partial<Record<AgentName, string>>): Promise<AgentName[] | null>;
|
package/dist/cli/types.d.ts
CHANGED
|
@@ -1,8 +1,28 @@
|
|
|
1
|
+
export interface ModelConfig {
|
|
2
|
+
id?: string;
|
|
3
|
+
name?: string;
|
|
4
|
+
options?: Record<string, unknown>;
|
|
5
|
+
variants?: Record<string, unknown>;
|
|
6
|
+
}
|
|
7
|
+
export interface ProviderConfig {
|
|
8
|
+
npm?: string;
|
|
9
|
+
name?: string;
|
|
10
|
+
options?: Record<string, unknown>;
|
|
11
|
+
models?: Record<string, ModelConfig>;
|
|
12
|
+
}
|
|
1
13
|
export interface OpencodeConfig {
|
|
2
14
|
plugins?: string[];
|
|
3
15
|
plugin?: string[];
|
|
16
|
+
model?: string;
|
|
17
|
+
small_model?: string;
|
|
18
|
+
provider?: Record<string, ProviderConfig>;
|
|
4
19
|
[key: string]: unknown;
|
|
5
20
|
}
|
|
21
|
+
export interface UserModelInfo {
|
|
22
|
+
id: string;
|
|
23
|
+
displayName: string;
|
|
24
|
+
provider: string;
|
|
25
|
+
}
|
|
6
26
|
export interface InstallOptions {
|
|
7
27
|
noTui?: boolean;
|
|
8
28
|
configPath?: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentName } from "./constants";
|
|
1
|
+
import type { AgentName, McpName } from "./constants";
|
|
2
2
|
export interface ZenoxConfigAgents {
|
|
3
3
|
[key: string]: {
|
|
4
4
|
model: string;
|
|
@@ -7,10 +7,12 @@ export interface ZenoxConfigAgents {
|
|
|
7
7
|
export interface ZenoxConfig {
|
|
8
8
|
agents?: ZenoxConfigAgents;
|
|
9
9
|
disabled_agents?: string[];
|
|
10
|
-
disabled_mcps?:
|
|
10
|
+
disabled_mcps?: McpName[];
|
|
11
11
|
}
|
|
12
12
|
export declare function getZenoxConfigPath(): string;
|
|
13
13
|
export declare function readZenoxConfig(): Promise<ZenoxConfig | null>;
|
|
14
14
|
export declare function writeZenoxConfig(config: ZenoxConfig): Promise<void>;
|
|
15
15
|
export declare function updateAgentModels(models: Partial<Record<AgentName, string>>): Promise<void>;
|
|
16
16
|
export declare function getCurrentModels(config: ZenoxConfig | null): Partial<Record<AgentName, string>>;
|
|
17
|
+
export declare function getDisabledMcps(config: ZenoxConfig | null): McpName[];
|
|
18
|
+
export declare function updateDisabledMcps(disabledMcps: McpName[]): Promise<void>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zenox",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "OpenCode plugin with specialized agents (explorer, librarian, oracle, ui-planner), background tasks for parallel execution, and smart orchestration",
|
|
5
5
|
"author": "Ayush",
|
|
6
6
|
"license": "MIT",
|