@tonyclaw/agent-inspector 2.1.7 → 2.1.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/.output/cli.js +274 -140
- package/.output/nitro.json +1 -1
- package/.output/public/assets/{CompareDrawer-BLS7CVvA.js → CompareDrawer-Dv423tJJ.js} +1 -1
- package/.output/public/assets/{ProxyViewerContainer-BFZ1WG07.js → ProxyViewerContainer-6mRRv0F1.js} +35 -35
- package/.output/public/assets/{ReplayDialog-DIGF807X.js → ReplayDialog-Bury80WZ.js} +1 -1
- package/.output/public/assets/{RequestAnatomy-C3Nlvp9P.js → RequestAnatomy-Bh07p6Yj.js} +1 -1
- package/.output/public/assets/{ResponseView-BbZywqHe.js → ResponseView-C8_ZLXNd.js} +1 -1
- package/.output/public/assets/{StreamingChunkSequence-Dk27PfPn.js → StreamingChunkSequence-BKvT1lyU.js} +1 -1
- package/.output/public/assets/_sessionId-DnxfC3cB.js +1 -0
- package/.output/public/assets/index-B1naZUTb.js +1 -0
- package/.output/public/assets/index-CmtfjQPv.css +1 -0
- package/.output/public/assets/{main-BxHXMs6B.js → main-D9YPHKL0.js} +2 -2
- package/.output/server/{_sessionId-D5HNwb9A.mjs → _sessionId-D2z4VD7h.mjs} +3 -3
- package/.output/server/_ssr/{CompareDrawer-QNk1twf8.mjs → CompareDrawer-DNDkVh7T.mjs} +3 -3
- package/.output/server/_ssr/{ProxyViewerContainer-DGhc2le_.mjs → ProxyViewerContainer-CI-fjnaf.mjs} +284 -217
- package/.output/server/_ssr/{ReplayDialog-D8wg4VNL.mjs → ReplayDialog-Dx4um0uS.mjs} +4 -4
- package/.output/server/_ssr/{RequestAnatomy-BtJHKVl2.mjs → RequestAnatomy-CKPBN_PB.mjs} +3 -3
- package/.output/server/_ssr/{ResponseView-CndDItiU.mjs → ResponseView-3wkt24-z.mjs} +3 -3
- package/.output/server/_ssr/{StreamingChunkSequence-D5Ywpbr7.mjs → StreamingChunkSequence-CSK53g5a.mjs} +3 -3
- package/.output/server/_ssr/{index-DtcUTHAX.mjs → index-1uaJ_KuG.mjs} +3 -3
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{router-C0apgqfC.mjs → router-KEX70DxH.mjs} +17 -8
- package/.output/server/{_tanstack-start-manifest_v-BoTPaB-V.mjs → _tanstack-start-manifest_v-VhueDt-w.mjs} +1 -1
- package/.output/server/index.mjs +63 -63
- package/README.md +10 -6
- package/package.json +1 -1
- package/src/cli/detect-tools.ts +2 -1
- package/src/cli/onboard.ts +334 -167
- package/src/components/providers/SettingsDialog.tsx +47 -0
- package/src/components/proxy-viewer/ConversationGroup.tsx +31 -9
- package/src/components/proxy-viewer/ConversationHeader.tsx +97 -37
- package/src/components/proxy-viewer/LogEntryHeader.tsx +3 -12
- package/src/mcp/server.ts +18 -4
- package/.output/public/assets/_sessionId-BHpX8AVf.js +0 -1
- package/.output/public/assets/index-BXHM9OMb.js +0 -1
- package/.output/public/assets/index-DP4NzCZ5.css +0 -1
package/.output/cli.js
CHANGED
|
@@ -52,7 +52,7 @@ function detectOpenCode() {
|
|
|
52
52
|
return { found: true, path: configDir ?? bin ?? "" };
|
|
53
53
|
}
|
|
54
54
|
function detectMiMo() {
|
|
55
|
-
const configDir = tryDir(join(homedir(), ".
|
|
55
|
+
const configDir = tryDir(join(homedir(), ".config", "mimocode")) ?? tryDir(join(homedir(), ".mimocode"));
|
|
56
56
|
const bin = which("mimo");
|
|
57
57
|
if (configDir === null && bin === null) return { found: false };
|
|
58
58
|
return { found: true, path: configDir ?? bin ?? "" };
|
|
@@ -943,6 +943,11 @@ function parseFlags(argv) {
|
|
|
943
943
|
opencodeConfig: null,
|
|
944
944
|
opencodeTransport: "local",
|
|
945
945
|
opencodeMcpUrl: DEFAULT_MCP_URL,
|
|
946
|
+
mimo: false,
|
|
947
|
+
mimoOnly: false,
|
|
948
|
+
mimoConfig: null,
|
|
949
|
+
mimoTransport: "local",
|
|
950
|
+
mimoMcpUrl: DEFAULT_MCP_URL,
|
|
946
951
|
uninstall: false,
|
|
947
952
|
status: false,
|
|
948
953
|
json: false,
|
|
@@ -1024,6 +1029,54 @@ function parseFlags(argv) {
|
|
|
1024
1029
|
i++;
|
|
1025
1030
|
break;
|
|
1026
1031
|
}
|
|
1032
|
+
case "--mimo":
|
|
1033
|
+
flags.mimo = true;
|
|
1034
|
+
break;
|
|
1035
|
+
case "--mimo-only":
|
|
1036
|
+
flags.mimo = true;
|
|
1037
|
+
flags.mimoOnly = true;
|
|
1038
|
+
break;
|
|
1039
|
+
case "--mimo-config": {
|
|
1040
|
+
const next = argv[i + 1];
|
|
1041
|
+
if (next === void 0) {
|
|
1042
|
+
process.stderr.write("agent-inspector onboard: --mimo-config requires a path argument\n");
|
|
1043
|
+
process.exit(2);
|
|
1044
|
+
}
|
|
1045
|
+
flags.mimoConfig = next;
|
|
1046
|
+
i++;
|
|
1047
|
+
break;
|
|
1048
|
+
}
|
|
1049
|
+
case "--mimo-transport": {
|
|
1050
|
+
const next = argv[i + 1];
|
|
1051
|
+
if (next === void 0) {
|
|
1052
|
+
process.stderr.write(
|
|
1053
|
+
"agent-inspector onboard: --mimo-transport requires local or remote\n"
|
|
1054
|
+
);
|
|
1055
|
+
process.exit(2);
|
|
1056
|
+
}
|
|
1057
|
+
switch (next) {
|
|
1058
|
+
case "local":
|
|
1059
|
+
case "remote":
|
|
1060
|
+
flags.mimoTransport = next;
|
|
1061
|
+
break;
|
|
1062
|
+
default:
|
|
1063
|
+
process.stderr.write(`agent-inspector onboard: invalid --mimo-transport: ${next}
|
|
1064
|
+
`);
|
|
1065
|
+
process.exit(2);
|
|
1066
|
+
}
|
|
1067
|
+
i++;
|
|
1068
|
+
break;
|
|
1069
|
+
}
|
|
1070
|
+
case "--mimo-mcp-url": {
|
|
1071
|
+
const next = argv[i + 1];
|
|
1072
|
+
if (next === void 0) {
|
|
1073
|
+
process.stderr.write("agent-inspector onboard: --mimo-mcp-url requires a URL\n");
|
|
1074
|
+
process.exit(2);
|
|
1075
|
+
}
|
|
1076
|
+
flags.mimoMcpUrl = next;
|
|
1077
|
+
i++;
|
|
1078
|
+
break;
|
|
1079
|
+
}
|
|
1027
1080
|
case "--uninstall":
|
|
1028
1081
|
flags.uninstall = true;
|
|
1029
1082
|
break;
|
|
@@ -1087,6 +1140,12 @@ Options:
|
|
|
1087
1140
|
--opencode-transport <local|remote>
|
|
1088
1141
|
OpenCode MCP transport to write (default: local)
|
|
1089
1142
|
--opencode-mcp-url <url> Agent Inspector MCP endpoint for OpenCode
|
|
1143
|
+
--mimo Also configure MiMo Code MCP in mimocode.json/jsonc
|
|
1144
|
+
--mimo-only Configure only MiMo Code MCP
|
|
1145
|
+
--mimo-config <path> Override MiMo config path (default: ~/.config/mimocode/mimocode.jsonc)
|
|
1146
|
+
--mimo-transport <local|remote>
|
|
1147
|
+
MiMo Code MCP transport to write (default: local)
|
|
1148
|
+
--mimo-mcp-url <url> Agent Inspector MCP endpoint for MiMo Code
|
|
1090
1149
|
--uninstall Remove generated files whose version matches this package
|
|
1091
1150
|
--status Show installed onboarding file versions and suggested action
|
|
1092
1151
|
--json Emit machine-readable JSON with --status
|
|
@@ -1118,6 +1177,12 @@ function isObject(value) {
|
|
|
1118
1177
|
function isOpenCodeEnabled(flags) {
|
|
1119
1178
|
return flags.opencode || flags.opencodeOnly;
|
|
1120
1179
|
}
|
|
1180
|
+
function isMiMoEnabled(flags) {
|
|
1181
|
+
return flags.mimo || flags.mimoOnly;
|
|
1182
|
+
}
|
|
1183
|
+
function hasOnlyAgentMcpTarget(flags) {
|
|
1184
|
+
return flags.opencodeOnly || flags.mimoOnly;
|
|
1185
|
+
}
|
|
1121
1186
|
function resolveOpenCodeConfigPath(flags) {
|
|
1122
1187
|
if (flags.opencodeConfig !== null) {
|
|
1123
1188
|
return flags.opencodeConfig;
|
|
@@ -1129,6 +1194,60 @@ function resolveOpenCodeConfigPath(flags) {
|
|
|
1129
1194
|
}
|
|
1130
1195
|
return join2(configDir, "opencode.json");
|
|
1131
1196
|
}
|
|
1197
|
+
function resolveMiMoConfigPath(flags) {
|
|
1198
|
+
if (flags.mimoConfig !== null) {
|
|
1199
|
+
return flags.mimoConfig;
|
|
1200
|
+
}
|
|
1201
|
+
const configDir = join2(homedir2(), ".config", "mimocode");
|
|
1202
|
+
const jsoncPath = join2(configDir, "mimocode.jsonc");
|
|
1203
|
+
if (existsSync2(jsoncPath)) {
|
|
1204
|
+
return jsoncPath;
|
|
1205
|
+
}
|
|
1206
|
+
const jsonPath = join2(configDir, "mimocode.json");
|
|
1207
|
+
if (existsSync2(jsonPath)) {
|
|
1208
|
+
return jsonPath;
|
|
1209
|
+
}
|
|
1210
|
+
const legacyDir = join2(homedir2(), ".mimocode");
|
|
1211
|
+
const legacyJsoncPath = join2(legacyDir, "config.jsonc");
|
|
1212
|
+
if (existsSync2(legacyJsoncPath)) {
|
|
1213
|
+
return legacyJsoncPath;
|
|
1214
|
+
}
|
|
1215
|
+
const legacyJsonPath = join2(legacyDir, "config.json");
|
|
1216
|
+
if (existsSync2(legacyJsonPath)) {
|
|
1217
|
+
return legacyJsonPath;
|
|
1218
|
+
}
|
|
1219
|
+
return jsoncPath;
|
|
1220
|
+
}
|
|
1221
|
+
function openCodeTarget(flags) {
|
|
1222
|
+
return {
|
|
1223
|
+
label: "OpenCode",
|
|
1224
|
+
configLabel: "OpenCode MCP config",
|
|
1225
|
+
configPath: resolveOpenCodeConfigPath(flags),
|
|
1226
|
+
transport: flags.opencodeTransport,
|
|
1227
|
+
endpoint: flags.opencodeMcpUrl,
|
|
1228
|
+
setupAction: "agent-inspector onboard --opencode-only",
|
|
1229
|
+
forceAction: "agent-inspector onboard --opencode-only --force",
|
|
1230
|
+
verifyCommand: "opencode mcp list",
|
|
1231
|
+
invalidAction: "fix OpenCode JSON/JSONC, then rerun agent-inspector onboard --opencode-only",
|
|
1232
|
+
configObjectName: "mcp.agent-inspector",
|
|
1233
|
+
defaultSchema: "https://opencode.ai/config.json"
|
|
1234
|
+
};
|
|
1235
|
+
}
|
|
1236
|
+
function miMoTarget(flags) {
|
|
1237
|
+
return {
|
|
1238
|
+
label: "MiMo Code",
|
|
1239
|
+
configLabel: "MiMo Code MCP config",
|
|
1240
|
+
configPath: resolveMiMoConfigPath(flags),
|
|
1241
|
+
transport: flags.mimoTransport,
|
|
1242
|
+
endpoint: flags.mimoMcpUrl,
|
|
1243
|
+
setupAction: "agent-inspector onboard --mimo-only",
|
|
1244
|
+
forceAction: "agent-inspector onboard --mimo-only --force",
|
|
1245
|
+
verifyCommand: "mimo mcp list",
|
|
1246
|
+
invalidAction: "fix MiMo Code JSON/JSONC, then rerun agent-inspector onboard --mimo-only",
|
|
1247
|
+
configObjectName: "mcp.agent-inspector",
|
|
1248
|
+
defaultSchema: "https://mimo.xiaomi.com/mimocode/config.json"
|
|
1249
|
+
};
|
|
1250
|
+
}
|
|
1132
1251
|
function stripJsoncComments(raw) {
|
|
1133
1252
|
let result = "";
|
|
1134
1253
|
let index = 0;
|
|
@@ -1177,7 +1296,7 @@ function stripJsoncComments(raw) {
|
|
|
1177
1296
|
}
|
|
1178
1297
|
return result;
|
|
1179
1298
|
}
|
|
1180
|
-
function
|
|
1299
|
+
function readAgentConfig(path, target) {
|
|
1181
1300
|
if (!existsSync2(path)) {
|
|
1182
1301
|
return { ok: true, exists: false, config: {} };
|
|
1183
1302
|
}
|
|
@@ -1193,7 +1312,7 @@ function readOpenCodeConfig(path) {
|
|
|
1193
1312
|
return {
|
|
1194
1313
|
ok: false,
|
|
1195
1314
|
exists: true,
|
|
1196
|
-
message:
|
|
1315
|
+
message: `${target.label} config root must be a JSON object`
|
|
1197
1316
|
};
|
|
1198
1317
|
} catch (err) {
|
|
1199
1318
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -1204,7 +1323,7 @@ function readOpenCodeConfig(path) {
|
|
|
1204
1323
|
};
|
|
1205
1324
|
}
|
|
1206
1325
|
}
|
|
1207
|
-
function
|
|
1326
|
+
function buildAgentMcpEntry(transport, endpoint) {
|
|
1208
1327
|
switch (transport) {
|
|
1209
1328
|
case "local":
|
|
1210
1329
|
return {
|
|
@@ -1232,7 +1351,7 @@ function stringArrayEquals(value, expected) {
|
|
|
1232
1351
|
}
|
|
1233
1352
|
return value.every((item, index) => item === expected[index]);
|
|
1234
1353
|
}
|
|
1235
|
-
function
|
|
1354
|
+
function isAgentLocalEntry(value, endpoint, ignoreEnabled) {
|
|
1236
1355
|
if (!isObject(value)) {
|
|
1237
1356
|
return false;
|
|
1238
1357
|
}
|
|
@@ -1250,7 +1369,7 @@ function isOpenCodeLocalEntry(value, endpoint, ignoreEnabled) {
|
|
|
1250
1369
|
const usesEnv = stringArrayEquals(value["command"], ["agent-inspector-mcp", "stdio"]) && isObject(env) && env["AGENT_INSPECTOR_MCP_URL"] === endpoint;
|
|
1251
1370
|
return value["type"] === "local" && (usesUrlArg || usesEnv);
|
|
1252
1371
|
}
|
|
1253
|
-
function
|
|
1372
|
+
function isAgentRemoteEntry(value, endpoint, ignoreEnabled) {
|
|
1254
1373
|
if (!isObject(value)) {
|
|
1255
1374
|
return false;
|
|
1256
1375
|
}
|
|
@@ -1260,10 +1379,10 @@ function isOpenCodeRemoteEntry(value, endpoint, ignoreEnabled) {
|
|
|
1260
1379
|
}
|
|
1261
1380
|
return value["type"] === "remote" && value["url"] === endpoint;
|
|
1262
1381
|
}
|
|
1263
|
-
function
|
|
1264
|
-
return
|
|
1382
|
+
function isKnownAgentEntry(value, endpoint, ignoreEnabled) {
|
|
1383
|
+
return isAgentLocalEntry(value, endpoint, ignoreEnabled) || isAgentRemoteEntry(value, endpoint, ignoreEnabled);
|
|
1265
1384
|
}
|
|
1266
|
-
function
|
|
1385
|
+
function detectAgentTransport(value) {
|
|
1267
1386
|
if (!isObject(value)) {
|
|
1268
1387
|
return "unknown";
|
|
1269
1388
|
}
|
|
@@ -1276,45 +1395,47 @@ function detectOpenCodeTransport(value) {
|
|
|
1276
1395
|
return "unknown";
|
|
1277
1396
|
}
|
|
1278
1397
|
}
|
|
1279
|
-
function
|
|
1398
|
+
function agentActionForStatus(target, status) {
|
|
1280
1399
|
switch (status.state) {
|
|
1281
1400
|
case "missing":
|
|
1282
|
-
return
|
|
1401
|
+
return target.setupAction;
|
|
1283
1402
|
case "configured":
|
|
1284
|
-
return
|
|
1403
|
+
return target.verifyCommand;
|
|
1285
1404
|
case "disabled":
|
|
1286
1405
|
case "custom":
|
|
1287
|
-
return
|
|
1406
|
+
return target.forceAction;
|
|
1288
1407
|
case "invalid":
|
|
1289
|
-
return
|
|
1408
|
+
return target.invalidAction;
|
|
1290
1409
|
default:
|
|
1291
|
-
return
|
|
1410
|
+
return target.setupAction;
|
|
1292
1411
|
}
|
|
1293
1412
|
}
|
|
1294
|
-
function
|
|
1413
|
+
function makeAgentStatus(target, state, transport, detail) {
|
|
1295
1414
|
const status = {
|
|
1296
|
-
label:
|
|
1297
|
-
path,
|
|
1415
|
+
label: target.configLabel,
|
|
1416
|
+
path: target.configPath,
|
|
1298
1417
|
state,
|
|
1299
1418
|
transport,
|
|
1300
|
-
endpoint,
|
|
1301
|
-
action:
|
|
1419
|
+
endpoint: target.endpoint,
|
|
1420
|
+
action: target.setupAction,
|
|
1421
|
+
forceAction: target.forceAction,
|
|
1422
|
+
verifyCommand: target.verifyCommand,
|
|
1302
1423
|
detail
|
|
1303
1424
|
};
|
|
1304
1425
|
return {
|
|
1305
1426
|
...status,
|
|
1306
|
-
action:
|
|
1427
|
+
action: agentActionForStatus(target, status)
|
|
1307
1428
|
};
|
|
1308
1429
|
}
|
|
1309
|
-
function
|
|
1430
|
+
function getAgentEntry(config) {
|
|
1310
1431
|
const mcp = config["mcp"];
|
|
1311
1432
|
if (!isObject(mcp)) {
|
|
1312
1433
|
return void 0;
|
|
1313
1434
|
}
|
|
1314
1435
|
return mcp["agent-inspector"];
|
|
1315
1436
|
}
|
|
1316
|
-
function
|
|
1317
|
-
const schema = typeof config["$schema"] === "string" ? config["$schema"] :
|
|
1437
|
+
function buildAgentConfig(config, target) {
|
|
1438
|
+
const schema = typeof config["$schema"] === "string" ? config["$schema"] : target.defaultSchema;
|
|
1318
1439
|
const nextConfig = {
|
|
1319
1440
|
$schema: schema
|
|
1320
1441
|
};
|
|
@@ -1325,15 +1446,15 @@ function buildOpenCodeConfig(config, transport, endpoint) {
|
|
|
1325
1446
|
}
|
|
1326
1447
|
const currentMcp = config["mcp"];
|
|
1327
1448
|
const nextMcp = isObject(currentMcp) ? { ...currentMcp } : {};
|
|
1328
|
-
nextMcp["agent-inspector"] =
|
|
1449
|
+
nextMcp["agent-inspector"] = buildAgentMcpEntry(target.transport, target.endpoint);
|
|
1329
1450
|
nextConfig["mcp"] = nextMcp;
|
|
1330
1451
|
return nextConfig;
|
|
1331
1452
|
}
|
|
1332
|
-
function
|
|
1453
|
+
function formatAgentConfig(config) {
|
|
1333
1454
|
return `${JSON.stringify(config, null, 2)}
|
|
1334
1455
|
`;
|
|
1335
1456
|
}
|
|
1336
|
-
function
|
|
1457
|
+
function removeAgentEntry(config) {
|
|
1337
1458
|
const nextConfig = {};
|
|
1338
1459
|
for (const [key, value] of Object.entries(config)) {
|
|
1339
1460
|
if (key !== "mcp") {
|
|
@@ -1355,70 +1476,63 @@ function removeOpenCodeEntry(config) {
|
|
|
1355
1476
|
}
|
|
1356
1477
|
return nextConfig;
|
|
1357
1478
|
}
|
|
1358
|
-
function
|
|
1359
|
-
const
|
|
1360
|
-
const read = readOpenCodeConfig(path);
|
|
1479
|
+
function readAgentStatus(target) {
|
|
1480
|
+
const read = readAgentConfig(target.configPath, target);
|
|
1361
1481
|
if (!read.ok) {
|
|
1362
|
-
return
|
|
1482
|
+
return makeAgentStatus(target, "invalid", "unknown", read.message);
|
|
1363
1483
|
}
|
|
1364
|
-
const entry =
|
|
1484
|
+
const entry = getAgentEntry(read.config);
|
|
1365
1485
|
if (entry === void 0) {
|
|
1366
|
-
const detail = read.exists ?
|
|
1367
|
-
return
|
|
1486
|
+
const detail = read.exists ? `${target.label} config has no ${target.configObjectName}` : "Missing file";
|
|
1487
|
+
return makeAgentStatus(target, "missing", "unknown", detail);
|
|
1368
1488
|
}
|
|
1369
|
-
const transport =
|
|
1489
|
+
const transport = detectAgentTransport(entry);
|
|
1370
1490
|
if (isObject(entry) && entry["enabled"] === false) {
|
|
1371
|
-
return
|
|
1372
|
-
|
|
1491
|
+
return makeAgentStatus(
|
|
1492
|
+
target,
|
|
1373
1493
|
"disabled",
|
|
1374
1494
|
transport,
|
|
1375
|
-
|
|
1376
|
-
"mcp.agent-inspector is present but disabled"
|
|
1495
|
+
`${target.configObjectName} is present but disabled`
|
|
1377
1496
|
);
|
|
1378
1497
|
}
|
|
1379
|
-
if (
|
|
1380
|
-
return
|
|
1381
|
-
|
|
1498
|
+
if (isKnownAgentEntry(entry, target.endpoint, false)) {
|
|
1499
|
+
return makeAgentStatus(
|
|
1500
|
+
target,
|
|
1382
1501
|
"configured",
|
|
1383
1502
|
transport,
|
|
1384
|
-
|
|
1385
|
-
"mcp.agent-inspector points at Agent Inspector MCP"
|
|
1503
|
+
`${target.configObjectName} points at Agent Inspector MCP`
|
|
1386
1504
|
);
|
|
1387
1505
|
}
|
|
1388
|
-
return
|
|
1389
|
-
|
|
1506
|
+
return makeAgentStatus(
|
|
1507
|
+
target,
|
|
1390
1508
|
"custom",
|
|
1391
1509
|
transport,
|
|
1392
|
-
|
|
1393
|
-
"mcp.agent-inspector exists but does not match Agent Inspector defaults"
|
|
1510
|
+
`${target.configObjectName} exists but does not match Agent Inspector defaults`
|
|
1394
1511
|
);
|
|
1395
1512
|
}
|
|
1396
|
-
function
|
|
1397
|
-
const
|
|
1398
|
-
const read = readOpenCodeConfig(path);
|
|
1513
|
+
function buildAgentPlan(target, uninstall, force) {
|
|
1514
|
+
const read = readAgentConfig(target.configPath, target);
|
|
1399
1515
|
if (!read.ok) {
|
|
1400
1516
|
return {
|
|
1401
|
-
status:
|
|
1517
|
+
status: makeAgentStatus(target, "invalid", "unknown", read.message),
|
|
1402
1518
|
body: null,
|
|
1403
1519
|
shouldWrite: false,
|
|
1404
1520
|
shouldRemove: false,
|
|
1405
|
-
blockedMessage:
|
|
1521
|
+
blockedMessage: `${target.label} config is invalid: ${read.message}`
|
|
1406
1522
|
};
|
|
1407
1523
|
}
|
|
1408
|
-
const status =
|
|
1409
|
-
const entry =
|
|
1410
|
-
const nextBody =
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
const shouldRemove = entry !== void 0 && isKnownOpenCodeEntry(entry, flags.opencodeMcpUrl, true);
|
|
1415
|
-
const removeBody = shouldRemove ? formatOpenCodeConfig(removeOpenCodeEntry(read.config)) : null;
|
|
1524
|
+
const status = readAgentStatus(target);
|
|
1525
|
+
const entry = getAgentEntry(read.config);
|
|
1526
|
+
const nextBody = formatAgentConfig(buildAgentConfig(read.config, target));
|
|
1527
|
+
if (uninstall) {
|
|
1528
|
+
const shouldRemove = entry !== void 0 && isKnownAgentEntry(entry, target.endpoint, true);
|
|
1529
|
+
const removeBody = shouldRemove ? formatAgentConfig(removeAgentEntry(read.config)) : null;
|
|
1416
1530
|
return {
|
|
1417
1531
|
status,
|
|
1418
1532
|
body: removeBody,
|
|
1419
1533
|
shouldWrite: false,
|
|
1420
1534
|
shouldRemove,
|
|
1421
|
-
blockedMessage: shouldRemove ? null :
|
|
1535
|
+
blockedMessage: shouldRemove ? null : `${target.label} ${target.configObjectName} is missing or custom; preserved`
|
|
1422
1536
|
};
|
|
1423
1537
|
}
|
|
1424
1538
|
switch (status.state) {
|
|
@@ -1426,7 +1540,7 @@ function buildOpenCodePlan(flags) {
|
|
|
1426
1540
|
return {
|
|
1427
1541
|
status,
|
|
1428
1542
|
body: nextBody,
|
|
1429
|
-
shouldWrite:
|
|
1543
|
+
shouldWrite: force,
|
|
1430
1544
|
shouldRemove: false,
|
|
1431
1545
|
blockedMessage: null
|
|
1432
1546
|
};
|
|
@@ -1443,9 +1557,9 @@ function buildOpenCodePlan(flags) {
|
|
|
1443
1557
|
return {
|
|
1444
1558
|
status,
|
|
1445
1559
|
body: nextBody,
|
|
1446
|
-
shouldWrite:
|
|
1560
|
+
shouldWrite: force,
|
|
1447
1561
|
shouldRemove: false,
|
|
1448
|
-
blockedMessage:
|
|
1562
|
+
blockedMessage: force ? null : `${target.label} ${target.configObjectName} is custom or disabled; use --force to replace`
|
|
1449
1563
|
};
|
|
1450
1564
|
case "invalid":
|
|
1451
1565
|
return {
|
|
@@ -1453,7 +1567,7 @@ function buildOpenCodePlan(flags) {
|
|
|
1453
1567
|
body: null,
|
|
1454
1568
|
shouldWrite: false,
|
|
1455
1569
|
shouldRemove: false,
|
|
1456
|
-
blockedMessage:
|
|
1570
|
+
blockedMessage: `${target.label} config is invalid`
|
|
1457
1571
|
};
|
|
1458
1572
|
default:
|
|
1459
1573
|
return {
|
|
@@ -1461,7 +1575,7 @@ function buildOpenCodePlan(flags) {
|
|
|
1461
1575
|
body: null,
|
|
1462
1576
|
shouldWrite: false,
|
|
1463
1577
|
shouldRemove: false,
|
|
1464
|
-
blockedMessage:
|
|
1578
|
+
blockedMessage: `${target.label} config state is unknown`
|
|
1465
1579
|
};
|
|
1466
1580
|
}
|
|
1467
1581
|
}
|
|
@@ -1643,8 +1757,8 @@ function readGeneratedFileStatus(file, currentVersion) {
|
|
|
1643
1757
|
}
|
|
1644
1758
|
}
|
|
1645
1759
|
function buildPlannedFiles(flags, targets, version) {
|
|
1646
|
-
const installClaude = !flags.codexOnly && !flags
|
|
1647
|
-
const installCodex = !flags.skipCodexSkill && !flags
|
|
1760
|
+
const installClaude = !flags.codexOnly && !hasOnlyAgentMcpTarget(flags);
|
|
1761
|
+
const installCodex = !flags.skipCodexSkill && !hasOnlyAgentMcpTarget(flags);
|
|
1648
1762
|
const detectedSummary = installClaude ? buildDetectedSummary() : "";
|
|
1649
1763
|
const claudeSkillBody = installClaude ? renderSkillOnboard({
|
|
1650
1764
|
version,
|
|
@@ -1702,7 +1816,7 @@ function removeEmptyDirectory(path) {
|
|
|
1702
1816
|
} catch {
|
|
1703
1817
|
}
|
|
1704
1818
|
}
|
|
1705
|
-
function runUninstall(plannedFiles, currentVersion, dryRun,
|
|
1819
|
+
function runUninstall(plannedFiles, currentVersion, dryRun, agentPlans) {
|
|
1706
1820
|
const enabledFiles = plannedFiles.filter((file) => file.enabled);
|
|
1707
1821
|
const filesToRemove = enabledFiles.filter((file) => shouldUninstall(file, currentVersion));
|
|
1708
1822
|
if (dryRun) {
|
|
@@ -1714,14 +1828,12 @@ function runUninstall(plannedFiles, currentVersion, dryRun, openCodePlan) {
|
|
|
1714
1828
|
process.stdout.write(`${file.label}: ${file.path} (${status})
|
|
1715
1829
|
`);
|
|
1716
1830
|
}
|
|
1717
|
-
|
|
1718
|
-
const status =
|
|
1719
|
-
process.stdout.write(
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
if (openCodePlan.blockedMessage !== null) {
|
|
1724
|
-
process.stdout.write(` ${openCodePlan.blockedMessage}
|
|
1831
|
+
for (const plan of agentPlans) {
|
|
1832
|
+
const status = plan.shouldRemove ? "matching" : "skipped";
|
|
1833
|
+
process.stdout.write(`${plan.status.label}: ${plan.status.path} (${status})
|
|
1834
|
+
`);
|
|
1835
|
+
if (plan.blockedMessage !== null) {
|
|
1836
|
+
process.stdout.write(` ${plan.blockedMessage}
|
|
1725
1837
|
`);
|
|
1726
1838
|
}
|
|
1727
1839
|
}
|
|
@@ -1730,14 +1842,16 @@ No files were removed.
|
|
|
1730
1842
|
`);
|
|
1731
1843
|
return 0;
|
|
1732
1844
|
}
|
|
1733
|
-
const
|
|
1734
|
-
if (filesToRemove.length === 0 && !
|
|
1845
|
+
const hasAgentConfigToRemove = agentPlans.some((plan) => plan.shouldRemove);
|
|
1846
|
+
if (filesToRemove.length === 0 && !hasAgentConfigToRemove) {
|
|
1735
1847
|
process.stdout.write(
|
|
1736
1848
|
"agent-inspector onboard: no generated onboarding files match this package version\n"
|
|
1737
1849
|
);
|
|
1738
|
-
|
|
1739
|
-
|
|
1850
|
+
for (const plan of agentPlans) {
|
|
1851
|
+
if (plan.blockedMessage !== null) {
|
|
1852
|
+
process.stdout.write(`${plan.blockedMessage}
|
|
1740
1853
|
`);
|
|
1854
|
+
}
|
|
1741
1855
|
}
|
|
1742
1856
|
return 0;
|
|
1743
1857
|
}
|
|
@@ -1748,11 +1862,13 @@ No files were removed.
|
|
|
1748
1862
|
process.stdout.write(`Removed ${file.label}: ${file.path}
|
|
1749
1863
|
`);
|
|
1750
1864
|
}
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1865
|
+
for (const plan of agentPlans) {
|
|
1866
|
+
if (plan.shouldRemove && plan.body !== null) {
|
|
1867
|
+
mkdirSync(dirname(plan.status.path), { recursive: true });
|
|
1868
|
+
writeFileSync(plan.status.path, plan.body, "utf8");
|
|
1869
|
+
process.stdout.write(`Removed ${plan.status.label} entry from: ${plan.status.path}
|
|
1755
1870
|
`);
|
|
1871
|
+
}
|
|
1756
1872
|
}
|
|
1757
1873
|
} catch (err) {
|
|
1758
1874
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -1765,20 +1881,24 @@ No files were removed.
|
|
|
1765
1881
|
function formatStatusVersion(status) {
|
|
1766
1882
|
return status.version ?? "-";
|
|
1767
1883
|
}
|
|
1768
|
-
function summarizeStatusAction(statuses,
|
|
1884
|
+
function summarizeStatusAction(statuses, agentStatuses) {
|
|
1769
1885
|
const actionable = statuses.filter(
|
|
1770
1886
|
(status) => status.state === "missing" || status.state === "outdated"
|
|
1771
1887
|
);
|
|
1772
1888
|
const actions = actionable.map((status) => status.action);
|
|
1773
|
-
|
|
1774
|
-
|
|
1889
|
+
for (const agentStatus of agentStatuses) {
|
|
1890
|
+
if (agentStatus.state === "missing") {
|
|
1891
|
+
actions.push(agentStatus.action);
|
|
1892
|
+
}
|
|
1775
1893
|
}
|
|
1776
1894
|
if (actions.length > 0) {
|
|
1777
1895
|
const uniqueActions = Array.from(new Set(actions));
|
|
1778
1896
|
return `Run: ${uniqueActions.join(" && ")}`;
|
|
1779
1897
|
}
|
|
1780
|
-
|
|
1781
|
-
|
|
1898
|
+
for (const agentStatus of agentStatuses) {
|
|
1899
|
+
if (agentStatus.state === "custom" || agentStatus.state === "disabled" || agentStatus.state === "invalid") {
|
|
1900
|
+
return `${agentStatus.label} needs review: ${agentStatus.action}`;
|
|
1901
|
+
}
|
|
1782
1902
|
}
|
|
1783
1903
|
if (statuses.some((status) => status.state === "custom")) {
|
|
1784
1904
|
return "Custom files are preserved. Use --force only if you want to replace them.";
|
|
@@ -1788,17 +1908,20 @@ function summarizeStatusAction(statuses, openCodeStatus) {
|
|
|
1788
1908
|
}
|
|
1789
1909
|
return "All selected onboarding files are current.";
|
|
1790
1910
|
}
|
|
1791
|
-
function runStatus(plannedFiles, currentVersion, json,
|
|
1911
|
+
function runStatus(plannedFiles, currentVersion, json, agentStatuses) {
|
|
1792
1912
|
const enabledFiles = plannedFiles.filter((file) => file.enabled);
|
|
1793
1913
|
const statuses = enabledFiles.map((file) => readGeneratedFileStatus(file, currentVersion));
|
|
1794
|
-
const summary = summarizeStatusAction(statuses,
|
|
1914
|
+
const summary = summarizeStatusAction(statuses, agentStatuses);
|
|
1915
|
+
const opencodeConfig = agentStatuses.find((status) => status.label === "OpenCode MCP config") ?? null;
|
|
1916
|
+
const mimoConfig = agentStatuses.find((status) => status.label === "MiMo Code MCP config") ?? null;
|
|
1795
1917
|
if (json) {
|
|
1796
1918
|
process.stdout.write(
|
|
1797
1919
|
`${JSON.stringify(
|
|
1798
1920
|
{
|
|
1799
1921
|
packageVersion: currentVersion,
|
|
1800
1922
|
files: statuses,
|
|
1801
|
-
opencodeConfig
|
|
1923
|
+
opencodeConfig,
|
|
1924
|
+
mimoConfig,
|
|
1802
1925
|
suggestedAction: summary
|
|
1803
1926
|
},
|
|
1804
1927
|
null,
|
|
@@ -1822,17 +1945,17 @@ function runStatus(plannedFiles, currentVersion, json, openCodeStatus) {
|
|
|
1822
1945
|
process.stdout.write(` Action: ${status.action}
|
|
1823
1946
|
`);
|
|
1824
1947
|
}
|
|
1825
|
-
|
|
1826
|
-
process.stdout.write(`${
|
|
1827
|
-
process.stdout.write(`, transport ${
|
|
1948
|
+
for (const agentStatus of agentStatuses) {
|
|
1949
|
+
process.stdout.write(`${agentStatus.label}: ${agentStatus.state}`);
|
|
1950
|
+
process.stdout.write(`, transport ${agentStatus.transport}
|
|
1828
1951
|
`);
|
|
1829
|
-
process.stdout.write(` ${
|
|
1952
|
+
process.stdout.write(` ${agentStatus.path}
|
|
1830
1953
|
`);
|
|
1831
|
-
process.stdout.write(` Endpoint: ${
|
|
1954
|
+
process.stdout.write(` Endpoint: ${agentStatus.endpoint}
|
|
1832
1955
|
`);
|
|
1833
|
-
process.stdout.write(` Detail: ${
|
|
1956
|
+
process.stdout.write(` Detail: ${agentStatus.detail}
|
|
1834
1957
|
`);
|
|
1835
|
-
process.stdout.write(` Action: ${
|
|
1958
|
+
process.stdout.write(` Action: ${agentStatus.action}
|
|
1836
1959
|
`);
|
|
1837
1960
|
}
|
|
1838
1961
|
process.stdout.write(`
|
|
@@ -1857,21 +1980,27 @@ function runOnboardSync(argv) {
|
|
|
1857
1980
|
const version = readPackageVersion();
|
|
1858
1981
|
const plannedFiles = buildPlannedFiles(flags, targets, version);
|
|
1859
1982
|
const enabledFiles = plannedFiles.filter((file) => file.enabled);
|
|
1860
|
-
const
|
|
1861
|
-
|
|
1983
|
+
const agentPlans = [];
|
|
1984
|
+
if (isOpenCodeEnabled(flags)) {
|
|
1985
|
+
agentPlans.push(buildAgentPlan(openCodeTarget(flags), flags.uninstall, flags.force));
|
|
1986
|
+
}
|
|
1987
|
+
if (isMiMoEnabled(flags)) {
|
|
1988
|
+
agentPlans.push(buildAgentPlan(miMoTarget(flags), flags.uninstall, flags.force));
|
|
1989
|
+
}
|
|
1990
|
+
const agentStatuses = agentPlans.map((plan) => plan.status);
|
|
1862
1991
|
if (flags.json && !flags.status) {
|
|
1863
1992
|
process.stderr.write("agent-inspector onboard: --json is only supported with --status\n");
|
|
1864
1993
|
return 2;
|
|
1865
1994
|
}
|
|
1866
|
-
if (enabledFiles.length === 0 &&
|
|
1995
|
+
if (enabledFiles.length === 0 && agentPlans.length === 0) {
|
|
1867
1996
|
process.stderr.write("agent-inspector onboard: no onboarding target selected\n");
|
|
1868
1997
|
return 2;
|
|
1869
1998
|
}
|
|
1870
1999
|
if (flags.status) {
|
|
1871
|
-
return runStatus(plannedFiles, version, flags.json,
|
|
2000
|
+
return runStatus(plannedFiles, version, flags.json, agentStatuses);
|
|
1872
2001
|
}
|
|
1873
2002
|
if (flags.uninstall) {
|
|
1874
|
-
return runUninstall(plannedFiles, version, flags.dryRun,
|
|
2003
|
+
return runUninstall(plannedFiles, version, flags.dryRun, agentPlans);
|
|
1875
2004
|
}
|
|
1876
2005
|
if (flags.dryRun) {
|
|
1877
2006
|
process.stdout.write(`agent-inspector onboard --dry-run
|
|
@@ -1882,26 +2011,24 @@ function runOnboardSync(argv) {
|
|
|
1882
2011
|
process.stdout.write(`${file.label}: ${file.path} (${status})
|
|
1883
2012
|
`);
|
|
1884
2013
|
}
|
|
1885
|
-
|
|
1886
|
-
process.stdout.write(
|
|
1887
|
-
|
|
1888
|
-
`
|
|
1889
|
-
);
|
|
1890
|
-
process.stdout.write(` Transport: ${flags.opencodeTransport}
|
|
2014
|
+
for (const plan of agentPlans) {
|
|
2015
|
+
process.stdout.write(`${plan.status.label}: ${plan.status.path} (${plan.status.state})
|
|
2016
|
+
`);
|
|
2017
|
+
process.stdout.write(` Transport: ${plan.status.transport}
|
|
1891
2018
|
`);
|
|
1892
|
-
process.stdout.write(` Endpoint: ${
|
|
2019
|
+
process.stdout.write(` Endpoint: ${plan.status.endpoint}
|
|
1893
2020
|
`);
|
|
1894
|
-
process.stdout.write(` Action: ${
|
|
2021
|
+
process.stdout.write(` Action: ${plan.status.action}
|
|
1895
2022
|
`);
|
|
1896
|
-
if (
|
|
1897
|
-
process.stdout.write(` ${
|
|
2023
|
+
if (plan.blockedMessage !== null) {
|
|
2024
|
+
process.stdout.write(` ${plan.blockedMessage}
|
|
1898
2025
|
`);
|
|
1899
2026
|
}
|
|
1900
2027
|
}
|
|
1901
2028
|
process.stdout.write(`
|
|
1902
2029
|
Claude skill headings:
|
|
1903
2030
|
`);
|
|
1904
|
-
if (!flags.codexOnly && !flags
|
|
2031
|
+
if (!flags.codexOnly && !hasOnlyAgentMcpTarget(flags)) {
|
|
1905
2032
|
for (const heading of REQUIRED_PHASE_HEADINGS) {
|
|
1906
2033
|
process.stdout.write(` - ${heading}
|
|
1907
2034
|
`);
|
|
@@ -1913,7 +2040,7 @@ Claude skill headings:
|
|
|
1913
2040
|
process.stdout.write(`
|
|
1914
2041
|
Codex skill headings:
|
|
1915
2042
|
`);
|
|
1916
|
-
if (!flags.skipCodexSkill && !flags
|
|
2043
|
+
if (!flags.skipCodexSkill && !hasOnlyAgentMcpTarget(flags)) {
|
|
1917
2044
|
for (const heading of REQUIRED_CODEX_PHASE_HEADINGS) {
|
|
1918
2045
|
process.stdout.write(` - ${heading}
|
|
1919
2046
|
`);
|
|
@@ -1922,7 +2049,7 @@ Codex skill headings:
|
|
|
1922
2049
|
process.stdout.write(` (disabled by selected targets)
|
|
1923
2050
|
`);
|
|
1924
2051
|
}
|
|
1925
|
-
if (!flags.codexOnly && !flags
|
|
2052
|
+
if (!flags.codexOnly && !hasOnlyAgentMcpTarget(flags)) {
|
|
1926
2053
|
process.stdout.write(`
|
|
1927
2054
|
Detected tools:
|
|
1928
2055
|
${buildDetectedSummary()}
|
|
@@ -1934,19 +2061,23 @@ No files were written.
|
|
|
1934
2061
|
return 0;
|
|
1935
2062
|
}
|
|
1936
2063
|
const filesToWrite = plannedFiles.filter((file) => shouldWrite(file, flags.force, version));
|
|
1937
|
-
const
|
|
1938
|
-
|
|
1939
|
-
|
|
2064
|
+
const agentPlansToWrite = agentPlans.filter((plan) => plan.shouldWrite && plan.body !== null);
|
|
2065
|
+
for (const plan of agentPlans) {
|
|
2066
|
+
if (plan.status.state === "invalid") {
|
|
2067
|
+
process.stderr.write(`agent-inspector onboard: ${plan.blockedMessage ?? "invalid"}
|
|
1940
2068
|
`);
|
|
1941
|
-
|
|
2069
|
+
return 1;
|
|
2070
|
+
}
|
|
1942
2071
|
}
|
|
1943
|
-
if (filesToWrite.length === 0 &&
|
|
2072
|
+
if (filesToWrite.length === 0 && agentPlansToWrite.length === 0) {
|
|
1944
2073
|
process.stdout.write(
|
|
1945
2074
|
"agent-inspector onboard: all selected onboarding files are already up to date\n"
|
|
1946
2075
|
);
|
|
1947
|
-
|
|
1948
|
-
|
|
2076
|
+
for (const plan of agentPlans) {
|
|
2077
|
+
if (plan.blockedMessage !== null) {
|
|
2078
|
+
process.stdout.write(`${plan.blockedMessage}
|
|
1949
2079
|
`);
|
|
2080
|
+
}
|
|
1950
2081
|
}
|
|
1951
2082
|
process.stdout.write("Re-run with --force to refresh.\n");
|
|
1952
2083
|
return 0;
|
|
@@ -1956,9 +2087,11 @@ No files were written.
|
|
|
1956
2087
|
mkdirSync(dirname(file.path), { recursive: true });
|
|
1957
2088
|
writeFileSync(file.path, file.body, "utf8");
|
|
1958
2089
|
}
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
2090
|
+
for (const plan of agentPlansToWrite) {
|
|
2091
|
+
if (plan.body !== null) {
|
|
2092
|
+
mkdirSync(dirname(plan.status.path), { recursive: true });
|
|
2093
|
+
writeFileSync(plan.status.path, plan.body, "utf8");
|
|
2094
|
+
}
|
|
1962
2095
|
}
|
|
1963
2096
|
} catch (err) {
|
|
1964
2097
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -1972,30 +2105,31 @@ No files were written.
|
|
|
1972
2105
|
process.stdout.write(`Installed/updated ${file.label} to: ${file.path}
|
|
1973
2106
|
`);
|
|
1974
2107
|
}
|
|
1975
|
-
|
|
1976
|
-
process.stdout.write(`Installed/updated
|
|
2108
|
+
for (const plan of agentPlansToWrite) {
|
|
2109
|
+
process.stdout.write(`Installed/updated ${plan.status.label}: ${plan.status.path}
|
|
1977
2110
|
`);
|
|
1978
2111
|
}
|
|
1979
2112
|
process.stdout.write(`
|
|
1980
2113
|
Next steps:
|
|
1981
2114
|
`);
|
|
1982
|
-
if (!flags.codexOnly && !flags
|
|
2115
|
+
if (!flags.codexOnly && !hasOnlyAgentMcpTarget(flags)) {
|
|
1983
2116
|
process.stdout.write(` - Open Claude Code and run: /agent-inspector:onboard
|
|
1984
2117
|
`);
|
|
1985
2118
|
}
|
|
1986
|
-
if (!flags.skipCodexSkill && !flags
|
|
2119
|
+
if (!flags.skipCodexSkill && !hasOnlyAgentMcpTarget(flags)) {
|
|
1987
2120
|
process.stdout.write(` - Open Codex and ask to use the agent-inspector-onboard skill
|
|
1988
2121
|
`);
|
|
1989
2122
|
}
|
|
1990
|
-
|
|
1991
|
-
process.stdout.write(` - Verify
|
|
2123
|
+
for (const plan of agentPlans) {
|
|
2124
|
+
process.stdout.write(` - Verify ${plan.status.label}: ${plan.status.verifyCommand}
|
|
1992
2125
|
`);
|
|
1993
2126
|
}
|
|
1994
|
-
if (flags
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
2127
|
+
if (hasOnlyAgentMcpTarget(flags)) {
|
|
2128
|
+
const refreshActions = agentPlans.map((plan) => plan.status.forceAction);
|
|
2129
|
+
const uniqueRefreshActions = Array.from(new Set(refreshActions));
|
|
2130
|
+
const refresh = uniqueRefreshActions.length > 0 ? uniqueRefreshActions.join(" && ") : "agent-inspector onboard --force";
|
|
2131
|
+
process.stdout.write(` - Refresh selected MCP config later: ${refresh}
|
|
2132
|
+
`);
|
|
1999
2133
|
} else {
|
|
2000
2134
|
process.stdout.write(` - Refresh later: agent-inspector onboard --force
|
|
2001
2135
|
`);
|