@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/src/cli/onboard.ts
CHANGED
|
@@ -61,8 +61,13 @@ export type OnboardFlags = {
|
|
|
61
61
|
opencode: boolean;
|
|
62
62
|
opencodeOnly: boolean;
|
|
63
63
|
opencodeConfig: string | null;
|
|
64
|
-
opencodeTransport:
|
|
64
|
+
opencodeTransport: AgentMcpTransport;
|
|
65
65
|
opencodeMcpUrl: string;
|
|
66
|
+
mimo: boolean;
|
|
67
|
+
mimoOnly: boolean;
|
|
68
|
+
mimoConfig: string | null;
|
|
69
|
+
mimoTransport: AgentMcpTransport;
|
|
70
|
+
mimoMcpUrl: string;
|
|
66
71
|
uninstall: boolean;
|
|
67
72
|
status: boolean;
|
|
68
73
|
json: boolean;
|
|
@@ -70,29 +75,45 @@ export type OnboardFlags = {
|
|
|
70
75
|
codexSkillDir: string | null;
|
|
71
76
|
};
|
|
72
77
|
|
|
73
|
-
type
|
|
74
|
-
type
|
|
75
|
-
type
|
|
78
|
+
type AgentMcpTransport = "local" | "remote";
|
|
79
|
+
type AgentMcpStatusTransport = AgentMcpTransport | "unknown";
|
|
80
|
+
type AgentMcpConfigState = "missing" | "configured" | "custom" | "disabled" | "invalid";
|
|
76
81
|
|
|
77
|
-
type
|
|
78
|
-
label: "OpenCode
|
|
82
|
+
type AgentMcpConfigTarget = {
|
|
83
|
+
label: "OpenCode" | "MiMo Code";
|
|
84
|
+
configLabel: "OpenCode MCP config" | "MiMo Code MCP config";
|
|
85
|
+
configPath: string;
|
|
86
|
+
transport: AgentMcpTransport;
|
|
87
|
+
endpoint: string;
|
|
88
|
+
setupAction: string;
|
|
89
|
+
forceAction: string;
|
|
90
|
+
verifyCommand: string;
|
|
91
|
+
invalidAction: string;
|
|
92
|
+
configObjectName: string;
|
|
93
|
+
defaultSchema: string;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
type AgentMcpConfigStatus = {
|
|
97
|
+
label: "OpenCode MCP config" | "MiMo Code MCP config";
|
|
79
98
|
path: string;
|
|
80
|
-
state:
|
|
81
|
-
transport:
|
|
99
|
+
state: AgentMcpConfigState;
|
|
100
|
+
transport: AgentMcpStatusTransport;
|
|
82
101
|
endpoint: string;
|
|
83
102
|
action: string;
|
|
103
|
+
forceAction: string;
|
|
104
|
+
verifyCommand: string;
|
|
84
105
|
detail: string;
|
|
85
106
|
};
|
|
86
107
|
|
|
87
|
-
type
|
|
88
|
-
status:
|
|
108
|
+
type AgentMcpConfigPlan = {
|
|
109
|
+
status: AgentMcpConfigStatus;
|
|
89
110
|
body: string | null;
|
|
90
111
|
shouldWrite: boolean;
|
|
91
112
|
shouldRemove: boolean;
|
|
92
113
|
blockedMessage: string | null;
|
|
93
114
|
};
|
|
94
115
|
|
|
95
|
-
type
|
|
116
|
+
type AgentConfigReadResult =
|
|
96
117
|
| {
|
|
97
118
|
ok: true;
|
|
98
119
|
exists: boolean;
|
|
@@ -171,6 +192,11 @@ function parseFlags(argv: readonly string[]): OnboardFlags {
|
|
|
171
192
|
opencodeConfig: null,
|
|
172
193
|
opencodeTransport: "local",
|
|
173
194
|
opencodeMcpUrl: DEFAULT_MCP_URL,
|
|
195
|
+
mimo: false,
|
|
196
|
+
mimoOnly: false,
|
|
197
|
+
mimoConfig: null,
|
|
198
|
+
mimoTransport: "local",
|
|
199
|
+
mimoMcpUrl: DEFAULT_MCP_URL,
|
|
174
200
|
uninstall: false,
|
|
175
201
|
status: false,
|
|
176
202
|
json: false,
|
|
@@ -251,6 +277,53 @@ function parseFlags(argv: readonly string[]): OnboardFlags {
|
|
|
251
277
|
i++;
|
|
252
278
|
break;
|
|
253
279
|
}
|
|
280
|
+
case "--mimo":
|
|
281
|
+
flags.mimo = true;
|
|
282
|
+
break;
|
|
283
|
+
case "--mimo-only":
|
|
284
|
+
flags.mimo = true;
|
|
285
|
+
flags.mimoOnly = true;
|
|
286
|
+
break;
|
|
287
|
+
case "--mimo-config": {
|
|
288
|
+
const next = argv[i + 1];
|
|
289
|
+
if (next === undefined) {
|
|
290
|
+
process.stderr.write("agent-inspector onboard: --mimo-config requires a path argument\n");
|
|
291
|
+
process.exit(2);
|
|
292
|
+
}
|
|
293
|
+
flags.mimoConfig = next;
|
|
294
|
+
i++;
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
case "--mimo-transport": {
|
|
298
|
+
const next = argv[i + 1];
|
|
299
|
+
if (next === undefined) {
|
|
300
|
+
process.stderr.write(
|
|
301
|
+
"agent-inspector onboard: --mimo-transport requires local or remote\n",
|
|
302
|
+
);
|
|
303
|
+
process.exit(2);
|
|
304
|
+
}
|
|
305
|
+
switch (next) {
|
|
306
|
+
case "local":
|
|
307
|
+
case "remote":
|
|
308
|
+
flags.mimoTransport = next;
|
|
309
|
+
break;
|
|
310
|
+
default:
|
|
311
|
+
process.stderr.write(`agent-inspector onboard: invalid --mimo-transport: ${next}\n`);
|
|
312
|
+
process.exit(2);
|
|
313
|
+
}
|
|
314
|
+
i++;
|
|
315
|
+
break;
|
|
316
|
+
}
|
|
317
|
+
case "--mimo-mcp-url": {
|
|
318
|
+
const next = argv[i + 1];
|
|
319
|
+
if (next === undefined) {
|
|
320
|
+
process.stderr.write("agent-inspector onboard: --mimo-mcp-url requires a URL\n");
|
|
321
|
+
process.exit(2);
|
|
322
|
+
}
|
|
323
|
+
flags.mimoMcpUrl = next;
|
|
324
|
+
i++;
|
|
325
|
+
break;
|
|
326
|
+
}
|
|
254
327
|
case "--uninstall":
|
|
255
328
|
flags.uninstall = true;
|
|
256
329
|
break;
|
|
@@ -314,6 +387,12 @@ Options:
|
|
|
314
387
|
--opencode-transport <local|remote>
|
|
315
388
|
OpenCode MCP transport to write (default: local)
|
|
316
389
|
--opencode-mcp-url <url> Agent Inspector MCP endpoint for OpenCode
|
|
390
|
+
--mimo Also configure MiMo Code MCP in mimocode.json/jsonc
|
|
391
|
+
--mimo-only Configure only MiMo Code MCP
|
|
392
|
+
--mimo-config <path> Override MiMo config path (default: ~/.config/mimocode/mimocode.jsonc)
|
|
393
|
+
--mimo-transport <local|remote>
|
|
394
|
+
MiMo Code MCP transport to write (default: local)
|
|
395
|
+
--mimo-mcp-url <url> Agent Inspector MCP endpoint for MiMo Code
|
|
317
396
|
--uninstall Remove generated files whose version matches this package
|
|
318
397
|
--status Show installed onboarding file versions and suggested action
|
|
319
398
|
--json Emit machine-readable JSON with --status
|
|
@@ -349,6 +428,14 @@ function isOpenCodeEnabled(flags: OnboardFlags): boolean {
|
|
|
349
428
|
return flags.opencode || flags.opencodeOnly;
|
|
350
429
|
}
|
|
351
430
|
|
|
431
|
+
function isMiMoEnabled(flags: OnboardFlags): boolean {
|
|
432
|
+
return flags.mimo || flags.mimoOnly;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
function hasOnlyAgentMcpTarget(flags: OnboardFlags): boolean {
|
|
436
|
+
return flags.opencodeOnly || flags.mimoOnly;
|
|
437
|
+
}
|
|
438
|
+
|
|
352
439
|
function resolveOpenCodeConfigPath(flags: OnboardFlags): string {
|
|
353
440
|
if (flags.opencodeConfig !== null) {
|
|
354
441
|
return flags.opencodeConfig;
|
|
@@ -362,6 +449,68 @@ function resolveOpenCodeConfigPath(flags: OnboardFlags): string {
|
|
|
362
449
|
return join(configDir, "opencode.json");
|
|
363
450
|
}
|
|
364
451
|
|
|
452
|
+
function resolveMiMoConfigPath(flags: OnboardFlags): string {
|
|
453
|
+
if (flags.mimoConfig !== null) {
|
|
454
|
+
return flags.mimoConfig;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
const configDir = join(homedir(), ".config", "mimocode");
|
|
458
|
+
const jsoncPath = join(configDir, "mimocode.jsonc");
|
|
459
|
+
if (existsSync(jsoncPath)) {
|
|
460
|
+
return jsoncPath;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
const jsonPath = join(configDir, "mimocode.json");
|
|
464
|
+
if (existsSync(jsonPath)) {
|
|
465
|
+
return jsonPath;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
const legacyDir = join(homedir(), ".mimocode");
|
|
469
|
+
const legacyJsoncPath = join(legacyDir, "config.jsonc");
|
|
470
|
+
if (existsSync(legacyJsoncPath)) {
|
|
471
|
+
return legacyJsoncPath;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
const legacyJsonPath = join(legacyDir, "config.json");
|
|
475
|
+
if (existsSync(legacyJsonPath)) {
|
|
476
|
+
return legacyJsonPath;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
return jsoncPath;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
function openCodeTarget(flags: OnboardFlags): AgentMcpConfigTarget {
|
|
483
|
+
return {
|
|
484
|
+
label: "OpenCode",
|
|
485
|
+
configLabel: "OpenCode MCP config",
|
|
486
|
+
configPath: resolveOpenCodeConfigPath(flags),
|
|
487
|
+
transport: flags.opencodeTransport,
|
|
488
|
+
endpoint: flags.opencodeMcpUrl,
|
|
489
|
+
setupAction: "agent-inspector onboard --opencode-only",
|
|
490
|
+
forceAction: "agent-inspector onboard --opencode-only --force",
|
|
491
|
+
verifyCommand: "opencode mcp list",
|
|
492
|
+
invalidAction: "fix OpenCode JSON/JSONC, then rerun agent-inspector onboard --opencode-only",
|
|
493
|
+
configObjectName: "mcp.agent-inspector",
|
|
494
|
+
defaultSchema: "https://opencode.ai/config.json",
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
function miMoTarget(flags: OnboardFlags): AgentMcpConfigTarget {
|
|
499
|
+
return {
|
|
500
|
+
label: "MiMo Code",
|
|
501
|
+
configLabel: "MiMo Code MCP config",
|
|
502
|
+
configPath: resolveMiMoConfigPath(flags),
|
|
503
|
+
transport: flags.mimoTransport,
|
|
504
|
+
endpoint: flags.mimoMcpUrl,
|
|
505
|
+
setupAction: "agent-inspector onboard --mimo-only",
|
|
506
|
+
forceAction: "agent-inspector onboard --mimo-only --force",
|
|
507
|
+
verifyCommand: "mimo mcp list",
|
|
508
|
+
invalidAction: "fix MiMo Code JSON/JSONC, then rerun agent-inspector onboard --mimo-only",
|
|
509
|
+
configObjectName: "mcp.agent-inspector",
|
|
510
|
+
defaultSchema: "https://mimo.xiaomi.com/mimocode/config.json",
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
|
|
365
514
|
function stripJsoncComments(raw: string): string {
|
|
366
515
|
let result = "";
|
|
367
516
|
let index = 0;
|
|
@@ -418,7 +567,7 @@ function stripJsoncComments(raw: string): string {
|
|
|
418
567
|
return result;
|
|
419
568
|
}
|
|
420
569
|
|
|
421
|
-
function
|
|
570
|
+
function readAgentConfig(path: string, target: AgentMcpConfigTarget): AgentConfigReadResult {
|
|
422
571
|
if (!existsSync(path)) {
|
|
423
572
|
return { ok: true, exists: false, config: {} };
|
|
424
573
|
}
|
|
@@ -435,7 +584,7 @@ function readOpenCodeConfig(path: string): OpenCodeReadResult {
|
|
|
435
584
|
return {
|
|
436
585
|
ok: false,
|
|
437
586
|
exists: true,
|
|
438
|
-
message:
|
|
587
|
+
message: `${target.label} config root must be a JSON object`,
|
|
439
588
|
};
|
|
440
589
|
} catch (err) {
|
|
441
590
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -447,8 +596,8 @@ function readOpenCodeConfig(path: string): OpenCodeReadResult {
|
|
|
447
596
|
}
|
|
448
597
|
}
|
|
449
598
|
|
|
450
|
-
function
|
|
451
|
-
transport:
|
|
599
|
+
function buildAgentMcpEntry(
|
|
600
|
+
transport: AgentMcpTransport,
|
|
452
601
|
endpoint: string,
|
|
453
602
|
): Record<string, unknown> {
|
|
454
603
|
switch (transport) {
|
|
@@ -481,7 +630,7 @@ function stringArrayEquals(value: unknown, expected: readonly string[]): boolean
|
|
|
481
630
|
return value.every((item, index) => item === expected[index]);
|
|
482
631
|
}
|
|
483
632
|
|
|
484
|
-
function
|
|
633
|
+
function isAgentLocalEntry(value: unknown, endpoint: string, ignoreEnabled: boolean): boolean {
|
|
485
634
|
if (!isObject(value)) {
|
|
486
635
|
return false;
|
|
487
636
|
}
|
|
@@ -506,7 +655,7 @@ function isOpenCodeLocalEntry(value: unknown, endpoint: string, ignoreEnabled: b
|
|
|
506
655
|
return value["type"] === "local" && (usesUrlArg || usesEnv);
|
|
507
656
|
}
|
|
508
657
|
|
|
509
|
-
function
|
|
658
|
+
function isAgentRemoteEntry(value: unknown, endpoint: string, ignoreEnabled: boolean): boolean {
|
|
510
659
|
if (!isObject(value)) {
|
|
511
660
|
return false;
|
|
512
661
|
}
|
|
@@ -519,14 +668,14 @@ function isOpenCodeRemoteEntry(value: unknown, endpoint: string, ignoreEnabled:
|
|
|
519
668
|
return value["type"] === "remote" && value["url"] === endpoint;
|
|
520
669
|
}
|
|
521
670
|
|
|
522
|
-
function
|
|
671
|
+
function isKnownAgentEntry(value: unknown, endpoint: string, ignoreEnabled: boolean): boolean {
|
|
523
672
|
return (
|
|
524
|
-
|
|
525
|
-
|
|
673
|
+
isAgentLocalEntry(value, endpoint, ignoreEnabled) ||
|
|
674
|
+
isAgentRemoteEntry(value, endpoint, ignoreEnabled)
|
|
526
675
|
);
|
|
527
676
|
}
|
|
528
677
|
|
|
529
|
-
function
|
|
678
|
+
function detectAgentTransport(value: unknown): AgentMcpStatusTransport {
|
|
530
679
|
if (!isObject(value)) {
|
|
531
680
|
return "unknown";
|
|
532
681
|
}
|
|
@@ -541,46 +690,47 @@ function detectOpenCodeTransport(value: unknown): OpenCodeStatusTransport {
|
|
|
541
690
|
}
|
|
542
691
|
}
|
|
543
692
|
|
|
544
|
-
function
|
|
693
|
+
function agentActionForStatus(target: AgentMcpConfigTarget, status: AgentMcpConfigStatus): string {
|
|
545
694
|
switch (status.state) {
|
|
546
695
|
case "missing":
|
|
547
|
-
return
|
|
696
|
+
return target.setupAction;
|
|
548
697
|
case "configured":
|
|
549
|
-
return
|
|
698
|
+
return target.verifyCommand;
|
|
550
699
|
case "disabled":
|
|
551
700
|
case "custom":
|
|
552
|
-
return
|
|
701
|
+
return target.forceAction;
|
|
553
702
|
case "invalid":
|
|
554
|
-
return
|
|
703
|
+
return target.invalidAction;
|
|
555
704
|
default:
|
|
556
|
-
return
|
|
705
|
+
return target.setupAction;
|
|
557
706
|
}
|
|
558
707
|
}
|
|
559
708
|
|
|
560
|
-
function
|
|
561
|
-
|
|
562
|
-
state:
|
|
563
|
-
transport:
|
|
564
|
-
endpoint: string,
|
|
709
|
+
function makeAgentStatus(
|
|
710
|
+
target: AgentMcpConfigTarget,
|
|
711
|
+
state: AgentMcpConfigState,
|
|
712
|
+
transport: AgentMcpStatusTransport,
|
|
565
713
|
detail: string,
|
|
566
|
-
):
|
|
567
|
-
const status:
|
|
568
|
-
label:
|
|
569
|
-
path,
|
|
714
|
+
): AgentMcpConfigStatus {
|
|
715
|
+
const status: AgentMcpConfigStatus = {
|
|
716
|
+
label: target.configLabel,
|
|
717
|
+
path: target.configPath,
|
|
570
718
|
state,
|
|
571
719
|
transport,
|
|
572
|
-
endpoint,
|
|
573
|
-
action:
|
|
720
|
+
endpoint: target.endpoint,
|
|
721
|
+
action: target.setupAction,
|
|
722
|
+
forceAction: target.forceAction,
|
|
723
|
+
verifyCommand: target.verifyCommand,
|
|
574
724
|
detail,
|
|
575
725
|
};
|
|
576
726
|
|
|
577
727
|
return {
|
|
578
728
|
...status,
|
|
579
|
-
action:
|
|
729
|
+
action: agentActionForStatus(target, status),
|
|
580
730
|
};
|
|
581
731
|
}
|
|
582
732
|
|
|
583
|
-
function
|
|
733
|
+
function getAgentEntry(config: Record<string, unknown>): unknown {
|
|
584
734
|
const mcp = config["mcp"];
|
|
585
735
|
if (!isObject(mcp)) {
|
|
586
736
|
return undefined;
|
|
@@ -588,13 +738,11 @@ function getOpenCodeEntry(config: Record<string, unknown>): unknown {
|
|
|
588
738
|
return mcp["agent-inspector"];
|
|
589
739
|
}
|
|
590
740
|
|
|
591
|
-
function
|
|
741
|
+
function buildAgentConfig(
|
|
592
742
|
config: Record<string, unknown>,
|
|
593
|
-
|
|
594
|
-
endpoint: string,
|
|
743
|
+
target: AgentMcpConfigTarget,
|
|
595
744
|
): Record<string, unknown> {
|
|
596
|
-
const schema =
|
|
597
|
-
typeof config["$schema"] === "string" ? config["$schema"] : "https://opencode.ai/config.json";
|
|
745
|
+
const schema = typeof config["$schema"] === "string" ? config["$schema"] : target.defaultSchema;
|
|
598
746
|
const nextConfig: Record<string, unknown> = {
|
|
599
747
|
$schema: schema,
|
|
600
748
|
};
|
|
@@ -607,16 +755,16 @@ function buildOpenCodeConfig(
|
|
|
607
755
|
|
|
608
756
|
const currentMcp = config["mcp"];
|
|
609
757
|
const nextMcp: Record<string, unknown> = isObject(currentMcp) ? { ...currentMcp } : {};
|
|
610
|
-
nextMcp["agent-inspector"] =
|
|
758
|
+
nextMcp["agent-inspector"] = buildAgentMcpEntry(target.transport, target.endpoint);
|
|
611
759
|
nextConfig["mcp"] = nextMcp;
|
|
612
760
|
return nextConfig;
|
|
613
761
|
}
|
|
614
762
|
|
|
615
|
-
function
|
|
763
|
+
function formatAgentConfig(config: Record<string, unknown>): string {
|
|
616
764
|
return `${JSON.stringify(config, null, 2)}\n`;
|
|
617
765
|
}
|
|
618
766
|
|
|
619
|
-
function
|
|
767
|
+
function removeAgentEntry(config: Record<string, unknown>): Record<string, unknown> {
|
|
620
768
|
const nextConfig: Record<string, unknown> = {};
|
|
621
769
|
for (const [key, value] of Object.entries(config)) {
|
|
622
770
|
if (key !== "mcp") {
|
|
@@ -642,74 +790,70 @@ function removeOpenCodeEntry(config: Record<string, unknown>): Record<string, un
|
|
|
642
790
|
return nextConfig;
|
|
643
791
|
}
|
|
644
792
|
|
|
645
|
-
function
|
|
646
|
-
const
|
|
647
|
-
const read = readOpenCodeConfig(path);
|
|
793
|
+
function readAgentStatus(target: AgentMcpConfigTarget): AgentMcpConfigStatus {
|
|
794
|
+
const read = readAgentConfig(target.configPath, target);
|
|
648
795
|
if (!read.ok) {
|
|
649
|
-
return
|
|
796
|
+
return makeAgentStatus(target, "invalid", "unknown", read.message);
|
|
650
797
|
}
|
|
651
798
|
|
|
652
|
-
const entry =
|
|
799
|
+
const entry = getAgentEntry(read.config);
|
|
653
800
|
if (entry === undefined) {
|
|
654
801
|
const detail = read.exists
|
|
655
|
-
?
|
|
802
|
+
? `${target.label} config has no ${target.configObjectName}`
|
|
656
803
|
: "Missing file";
|
|
657
|
-
return
|
|
804
|
+
return makeAgentStatus(target, "missing", "unknown", detail);
|
|
658
805
|
}
|
|
659
806
|
|
|
660
|
-
const transport =
|
|
807
|
+
const transport = detectAgentTransport(entry);
|
|
661
808
|
if (isObject(entry) && entry["enabled"] === false) {
|
|
662
|
-
return
|
|
663
|
-
|
|
809
|
+
return makeAgentStatus(
|
|
810
|
+
target,
|
|
664
811
|
"disabled",
|
|
665
812
|
transport,
|
|
666
|
-
|
|
667
|
-
"mcp.agent-inspector is present but disabled",
|
|
813
|
+
`${target.configObjectName} is present but disabled`,
|
|
668
814
|
);
|
|
669
815
|
}
|
|
670
816
|
|
|
671
|
-
if (
|
|
672
|
-
return
|
|
673
|
-
|
|
817
|
+
if (isKnownAgentEntry(entry, target.endpoint, false)) {
|
|
818
|
+
return makeAgentStatus(
|
|
819
|
+
target,
|
|
674
820
|
"configured",
|
|
675
821
|
transport,
|
|
676
|
-
|
|
677
|
-
"mcp.agent-inspector points at Agent Inspector MCP",
|
|
822
|
+
`${target.configObjectName} points at Agent Inspector MCP`,
|
|
678
823
|
);
|
|
679
824
|
}
|
|
680
825
|
|
|
681
|
-
return
|
|
682
|
-
|
|
826
|
+
return makeAgentStatus(
|
|
827
|
+
target,
|
|
683
828
|
"custom",
|
|
684
829
|
transport,
|
|
685
|
-
|
|
686
|
-
"mcp.agent-inspector exists but does not match Agent Inspector defaults",
|
|
830
|
+
`${target.configObjectName} exists but does not match Agent Inspector defaults`,
|
|
687
831
|
);
|
|
688
832
|
}
|
|
689
833
|
|
|
690
|
-
function
|
|
691
|
-
|
|
692
|
-
|
|
834
|
+
function buildAgentPlan(
|
|
835
|
+
target: AgentMcpConfigTarget,
|
|
836
|
+
uninstall: boolean,
|
|
837
|
+
force: boolean,
|
|
838
|
+
): AgentMcpConfigPlan {
|
|
839
|
+
const read = readAgentConfig(target.configPath, target);
|
|
693
840
|
if (!read.ok) {
|
|
694
841
|
return {
|
|
695
|
-
status:
|
|
842
|
+
status: makeAgentStatus(target, "invalid", "unknown", read.message),
|
|
696
843
|
body: null,
|
|
697
844
|
shouldWrite: false,
|
|
698
845
|
shouldRemove: false,
|
|
699
|
-
blockedMessage:
|
|
846
|
+
blockedMessage: `${target.label} config is invalid: ${read.message}`,
|
|
700
847
|
};
|
|
701
848
|
}
|
|
702
849
|
|
|
703
|
-
const status =
|
|
704
|
-
const entry =
|
|
705
|
-
const nextBody =
|
|
706
|
-
buildOpenCodeConfig(read.config, flags.opencodeTransport, flags.opencodeMcpUrl),
|
|
707
|
-
);
|
|
850
|
+
const status = readAgentStatus(target);
|
|
851
|
+
const entry = getAgentEntry(read.config);
|
|
852
|
+
const nextBody = formatAgentConfig(buildAgentConfig(read.config, target));
|
|
708
853
|
|
|
709
|
-
if (
|
|
710
|
-
const shouldRemove =
|
|
711
|
-
|
|
712
|
-
const removeBody = shouldRemove ? formatOpenCodeConfig(removeOpenCodeEntry(read.config)) : null;
|
|
854
|
+
if (uninstall) {
|
|
855
|
+
const shouldRemove = entry !== undefined && isKnownAgentEntry(entry, target.endpoint, true);
|
|
856
|
+
const removeBody = shouldRemove ? formatAgentConfig(removeAgentEntry(read.config)) : null;
|
|
713
857
|
return {
|
|
714
858
|
status,
|
|
715
859
|
body: removeBody,
|
|
@@ -717,7 +861,7 @@ function buildOpenCodePlan(flags: OnboardFlags): OpenCodeConfigPlan {
|
|
|
717
861
|
shouldRemove,
|
|
718
862
|
blockedMessage: shouldRemove
|
|
719
863
|
? null
|
|
720
|
-
:
|
|
864
|
+
: `${target.label} ${target.configObjectName} is missing or custom; preserved`,
|
|
721
865
|
};
|
|
722
866
|
}
|
|
723
867
|
|
|
@@ -726,7 +870,7 @@ function buildOpenCodePlan(flags: OnboardFlags): OpenCodeConfigPlan {
|
|
|
726
870
|
return {
|
|
727
871
|
status,
|
|
728
872
|
body: nextBody,
|
|
729
|
-
shouldWrite:
|
|
873
|
+
shouldWrite: force,
|
|
730
874
|
shouldRemove: false,
|
|
731
875
|
blockedMessage: null,
|
|
732
876
|
};
|
|
@@ -743,11 +887,11 @@ function buildOpenCodePlan(flags: OnboardFlags): OpenCodeConfigPlan {
|
|
|
743
887
|
return {
|
|
744
888
|
status,
|
|
745
889
|
body: nextBody,
|
|
746
|
-
shouldWrite:
|
|
890
|
+
shouldWrite: force,
|
|
747
891
|
shouldRemove: false,
|
|
748
|
-
blockedMessage:
|
|
892
|
+
blockedMessage: force
|
|
749
893
|
? null
|
|
750
|
-
:
|
|
894
|
+
: `${target.label} ${target.configObjectName} is custom or disabled; use --force to replace`,
|
|
751
895
|
};
|
|
752
896
|
case "invalid":
|
|
753
897
|
return {
|
|
@@ -755,7 +899,7 @@ function buildOpenCodePlan(flags: OnboardFlags): OpenCodeConfigPlan {
|
|
|
755
899
|
body: null,
|
|
756
900
|
shouldWrite: false,
|
|
757
901
|
shouldRemove: false,
|
|
758
|
-
blockedMessage:
|
|
902
|
+
blockedMessage: `${target.label} config is invalid`,
|
|
759
903
|
};
|
|
760
904
|
default:
|
|
761
905
|
return {
|
|
@@ -763,7 +907,7 @@ function buildOpenCodePlan(flags: OnboardFlags): OpenCodeConfigPlan {
|
|
|
763
907
|
body: null,
|
|
764
908
|
shouldWrite: false,
|
|
765
909
|
shouldRemove: false,
|
|
766
|
-
blockedMessage:
|
|
910
|
+
blockedMessage: `${target.label} config state is unknown`,
|
|
767
911
|
};
|
|
768
912
|
}
|
|
769
913
|
}
|
|
@@ -973,8 +1117,8 @@ function buildPlannedFiles(
|
|
|
973
1117
|
targets: OnboardTargets,
|
|
974
1118
|
version: string,
|
|
975
1119
|
): PlannedFile[] {
|
|
976
|
-
const installClaude = !flags.codexOnly && !flags
|
|
977
|
-
const installCodex = !flags.skipCodexSkill && !flags
|
|
1120
|
+
const installClaude = !flags.codexOnly && !hasOnlyAgentMcpTarget(flags);
|
|
1121
|
+
const installCodex = !flags.skipCodexSkill && !hasOnlyAgentMcpTarget(flags);
|
|
978
1122
|
const detectedSummary = installClaude ? buildDetectedSummary() : "";
|
|
979
1123
|
const claudeSkillBody = installClaude
|
|
980
1124
|
? renderSkillOnboard({
|
|
@@ -1050,7 +1194,7 @@ function runUninstall(
|
|
|
1050
1194
|
plannedFiles: readonly PlannedFile[],
|
|
1051
1195
|
currentVersion: string,
|
|
1052
1196
|
dryRun: boolean,
|
|
1053
|
-
|
|
1197
|
+
agentPlans: readonly AgentMcpConfigPlan[],
|
|
1054
1198
|
): number {
|
|
1055
1199
|
const enabledFiles = plannedFiles.filter((file) => file.enabled);
|
|
1056
1200
|
const filesToRemove = enabledFiles.filter((file) => shouldUninstall(file, currentVersion));
|
|
@@ -1061,26 +1205,26 @@ function runUninstall(
|
|
|
1061
1205
|
const status = shouldUninstall(file, currentVersion) ? "matching" : "skipped";
|
|
1062
1206
|
process.stdout.write(`${file.label}: ${file.path} (${status})\n`);
|
|
1063
1207
|
}
|
|
1064
|
-
|
|
1065
|
-
const status =
|
|
1066
|
-
process.stdout.write(
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
if (openCodePlan.blockedMessage !== null) {
|
|
1070
|
-
process.stdout.write(` ${openCodePlan.blockedMessage}\n`);
|
|
1208
|
+
for (const plan of agentPlans) {
|
|
1209
|
+
const status = plan.shouldRemove ? "matching" : "skipped";
|
|
1210
|
+
process.stdout.write(`${plan.status.label}: ${plan.status.path} (${status})\n`);
|
|
1211
|
+
if (plan.blockedMessage !== null) {
|
|
1212
|
+
process.stdout.write(` ${plan.blockedMessage}\n`);
|
|
1071
1213
|
}
|
|
1072
1214
|
}
|
|
1073
1215
|
process.stdout.write(`\nNo files were removed.\n`);
|
|
1074
1216
|
return 0;
|
|
1075
1217
|
}
|
|
1076
1218
|
|
|
1077
|
-
const
|
|
1078
|
-
if (filesToRemove.length === 0 && !
|
|
1219
|
+
const hasAgentConfigToRemove = agentPlans.some((plan) => plan.shouldRemove);
|
|
1220
|
+
if (filesToRemove.length === 0 && !hasAgentConfigToRemove) {
|
|
1079
1221
|
process.stdout.write(
|
|
1080
1222
|
"agent-inspector onboard: no generated onboarding files match this package version\n",
|
|
1081
1223
|
);
|
|
1082
|
-
|
|
1083
|
-
|
|
1224
|
+
for (const plan of agentPlans) {
|
|
1225
|
+
if (plan.blockedMessage !== null) {
|
|
1226
|
+
process.stdout.write(`${plan.blockedMessage}\n`);
|
|
1227
|
+
}
|
|
1084
1228
|
}
|
|
1085
1229
|
return 0;
|
|
1086
1230
|
}
|
|
@@ -1091,10 +1235,12 @@ function runUninstall(
|
|
|
1091
1235
|
removeEmptyDirectory(dirname(file.path));
|
|
1092
1236
|
process.stdout.write(`Removed ${file.label}: ${file.path}\n`);
|
|
1093
1237
|
}
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1238
|
+
for (const plan of agentPlans) {
|
|
1239
|
+
if (plan.shouldRemove && plan.body !== null) {
|
|
1240
|
+
mkdirSync(dirname(plan.status.path), { recursive: true });
|
|
1241
|
+
writeFileSync(plan.status.path, plan.body, "utf8");
|
|
1242
|
+
process.stdout.write(`Removed ${plan.status.label} entry from: ${plan.status.path}\n`);
|
|
1243
|
+
}
|
|
1098
1244
|
}
|
|
1099
1245
|
} catch (err) {
|
|
1100
1246
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -1111,26 +1257,29 @@ function formatStatusVersion(status: GeneratedFileStatus): string {
|
|
|
1111
1257
|
|
|
1112
1258
|
function summarizeStatusAction(
|
|
1113
1259
|
statuses: readonly GeneratedFileStatus[],
|
|
1114
|
-
|
|
1260
|
+
agentStatuses: readonly AgentMcpConfigStatus[],
|
|
1115
1261
|
): string {
|
|
1116
1262
|
const actionable = statuses.filter(
|
|
1117
1263
|
(status) => status.state === "missing" || status.state === "outdated",
|
|
1118
1264
|
);
|
|
1119
1265
|
const actions = actionable.map((status) => status.action);
|
|
1120
|
-
|
|
1121
|
-
|
|
1266
|
+
for (const agentStatus of agentStatuses) {
|
|
1267
|
+
if (agentStatus.state === "missing") {
|
|
1268
|
+
actions.push(agentStatus.action);
|
|
1269
|
+
}
|
|
1122
1270
|
}
|
|
1123
1271
|
if (actions.length > 0) {
|
|
1124
1272
|
const uniqueActions = Array.from(new Set(actions));
|
|
1125
1273
|
return `Run: ${uniqueActions.join(" && ")}`;
|
|
1126
1274
|
}
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1275
|
+
for (const agentStatus of agentStatuses) {
|
|
1276
|
+
if (
|
|
1277
|
+
agentStatus.state === "custom" ||
|
|
1278
|
+
agentStatus.state === "disabled" ||
|
|
1279
|
+
agentStatus.state === "invalid"
|
|
1280
|
+
) {
|
|
1281
|
+
return `${agentStatus.label} needs review: ${agentStatus.action}`;
|
|
1282
|
+
}
|
|
1134
1283
|
}
|
|
1135
1284
|
if (statuses.some((status) => status.state === "custom")) {
|
|
1136
1285
|
return "Custom files are preserved. Use --force only if you want to replace them.";
|
|
@@ -1145,11 +1294,15 @@ function runStatus(
|
|
|
1145
1294
|
plannedFiles: readonly PlannedFile[],
|
|
1146
1295
|
currentVersion: string,
|
|
1147
1296
|
json: boolean,
|
|
1148
|
-
|
|
1297
|
+
agentStatuses: readonly AgentMcpConfigStatus[],
|
|
1149
1298
|
): number {
|
|
1150
1299
|
const enabledFiles = plannedFiles.filter((file) => file.enabled);
|
|
1151
1300
|
const statuses = enabledFiles.map((file) => readGeneratedFileStatus(file, currentVersion));
|
|
1152
|
-
const summary = summarizeStatusAction(statuses,
|
|
1301
|
+
const summary = summarizeStatusAction(statuses, agentStatuses);
|
|
1302
|
+
const opencodeConfig =
|
|
1303
|
+
agentStatuses.find((status) => status.label === "OpenCode MCP config") ?? null;
|
|
1304
|
+
const mimoConfig =
|
|
1305
|
+
agentStatuses.find((status) => status.label === "MiMo Code MCP config") ?? null;
|
|
1153
1306
|
|
|
1154
1307
|
if (json) {
|
|
1155
1308
|
process.stdout.write(
|
|
@@ -1157,7 +1310,8 @@ function runStatus(
|
|
|
1157
1310
|
{
|
|
1158
1311
|
packageVersion: currentVersion,
|
|
1159
1312
|
files: statuses,
|
|
1160
|
-
opencodeConfig
|
|
1313
|
+
opencodeConfig,
|
|
1314
|
+
mimoConfig,
|
|
1161
1315
|
suggestedAction: summary,
|
|
1162
1316
|
},
|
|
1163
1317
|
null,
|
|
@@ -1177,13 +1331,13 @@ function runStatus(
|
|
|
1177
1331
|
process.stdout.write(` Action: ${status.action}\n`);
|
|
1178
1332
|
}
|
|
1179
1333
|
|
|
1180
|
-
|
|
1181
|
-
process.stdout.write(`${
|
|
1182
|
-
process.stdout.write(`, transport ${
|
|
1183
|
-
process.stdout.write(` ${
|
|
1184
|
-
process.stdout.write(` Endpoint: ${
|
|
1185
|
-
process.stdout.write(` Detail: ${
|
|
1186
|
-
process.stdout.write(` Action: ${
|
|
1334
|
+
for (const agentStatus of agentStatuses) {
|
|
1335
|
+
process.stdout.write(`${agentStatus.label}: ${agentStatus.state}`);
|
|
1336
|
+
process.stdout.write(`, transport ${agentStatus.transport}\n`);
|
|
1337
|
+
process.stdout.write(` ${agentStatus.path}\n`);
|
|
1338
|
+
process.stdout.write(` Endpoint: ${agentStatus.endpoint}\n`);
|
|
1339
|
+
process.stdout.write(` Detail: ${agentStatus.detail}\n`);
|
|
1340
|
+
process.stdout.write(` Action: ${agentStatus.action}\n`);
|
|
1187
1341
|
}
|
|
1188
1342
|
|
|
1189
1343
|
process.stdout.write(`\nSuggested action: ${summary}\n`);
|
|
@@ -1208,25 +1362,31 @@ function runOnboardSync(argv: readonly string[]): number {
|
|
|
1208
1362
|
const version = readPackageVersion();
|
|
1209
1363
|
const plannedFiles = buildPlannedFiles(flags, targets, version);
|
|
1210
1364
|
const enabledFiles = plannedFiles.filter((file) => file.enabled);
|
|
1211
|
-
const
|
|
1212
|
-
|
|
1365
|
+
const agentPlans: AgentMcpConfigPlan[] = [];
|
|
1366
|
+
if (isOpenCodeEnabled(flags)) {
|
|
1367
|
+
agentPlans.push(buildAgentPlan(openCodeTarget(flags), flags.uninstall, flags.force));
|
|
1368
|
+
}
|
|
1369
|
+
if (isMiMoEnabled(flags)) {
|
|
1370
|
+
agentPlans.push(buildAgentPlan(miMoTarget(flags), flags.uninstall, flags.force));
|
|
1371
|
+
}
|
|
1372
|
+
const agentStatuses = agentPlans.map((plan) => plan.status);
|
|
1213
1373
|
|
|
1214
1374
|
if (flags.json && !flags.status) {
|
|
1215
1375
|
process.stderr.write("agent-inspector onboard: --json is only supported with --status\n");
|
|
1216
1376
|
return 2;
|
|
1217
1377
|
}
|
|
1218
1378
|
|
|
1219
|
-
if (enabledFiles.length === 0 &&
|
|
1379
|
+
if (enabledFiles.length === 0 && agentPlans.length === 0) {
|
|
1220
1380
|
process.stderr.write("agent-inspector onboard: no onboarding target selected\n");
|
|
1221
1381
|
return 2;
|
|
1222
1382
|
}
|
|
1223
1383
|
|
|
1224
1384
|
if (flags.status) {
|
|
1225
|
-
return runStatus(plannedFiles, version, flags.json,
|
|
1385
|
+
return runStatus(plannedFiles, version, flags.json, agentStatuses);
|
|
1226
1386
|
}
|
|
1227
1387
|
|
|
1228
1388
|
if (flags.uninstall) {
|
|
1229
|
-
return runUninstall(plannedFiles, version, flags.dryRun,
|
|
1389
|
+
return runUninstall(plannedFiles, version, flags.dryRun, agentPlans);
|
|
1230
1390
|
}
|
|
1231
1391
|
|
|
1232
1392
|
if (flags.dryRun) {
|
|
@@ -1235,19 +1395,17 @@ function runOnboardSync(argv: readonly string[]): number {
|
|
|
1235
1395
|
const status = existsSync(file.path) ? "exists" : "missing";
|
|
1236
1396
|
process.stdout.write(`${file.label}: ${file.path} (${status})\n`);
|
|
1237
1397
|
}
|
|
1238
|
-
|
|
1239
|
-
process.stdout.write(
|
|
1240
|
-
|
|
1241
|
-
);
|
|
1242
|
-
process.stdout.write(`
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
if (openCodePlan.blockedMessage !== null) {
|
|
1246
|
-
process.stdout.write(` ${openCodePlan.blockedMessage}\n`);
|
|
1398
|
+
for (const plan of agentPlans) {
|
|
1399
|
+
process.stdout.write(`${plan.status.label}: ${plan.status.path} (${plan.status.state})\n`);
|
|
1400
|
+
process.stdout.write(` Transport: ${plan.status.transport}\n`);
|
|
1401
|
+
process.stdout.write(` Endpoint: ${plan.status.endpoint}\n`);
|
|
1402
|
+
process.stdout.write(` Action: ${plan.status.action}\n`);
|
|
1403
|
+
if (plan.blockedMessage !== null) {
|
|
1404
|
+
process.stdout.write(` ${plan.blockedMessage}\n`);
|
|
1247
1405
|
}
|
|
1248
1406
|
}
|
|
1249
1407
|
process.stdout.write(`\nClaude skill headings:\n`);
|
|
1250
|
-
if (!flags.codexOnly && !flags
|
|
1408
|
+
if (!flags.codexOnly && !hasOnlyAgentMcpTarget(flags)) {
|
|
1251
1409
|
for (const heading of REQUIRED_PHASE_HEADINGS) {
|
|
1252
1410
|
process.stdout.write(` - ${heading}\n`);
|
|
1253
1411
|
}
|
|
@@ -1255,14 +1413,14 @@ function runOnboardSync(argv: readonly string[]): number {
|
|
|
1255
1413
|
process.stdout.write(` (disabled by selected targets)\n`);
|
|
1256
1414
|
}
|
|
1257
1415
|
process.stdout.write(`\nCodex skill headings:\n`);
|
|
1258
|
-
if (!flags.skipCodexSkill && !flags
|
|
1416
|
+
if (!flags.skipCodexSkill && !hasOnlyAgentMcpTarget(flags)) {
|
|
1259
1417
|
for (const heading of REQUIRED_CODEX_PHASE_HEADINGS) {
|
|
1260
1418
|
process.stdout.write(` - ${heading}\n`);
|
|
1261
1419
|
}
|
|
1262
1420
|
} else {
|
|
1263
1421
|
process.stdout.write(` (disabled by selected targets)\n`);
|
|
1264
1422
|
}
|
|
1265
|
-
if (!flags.codexOnly && !flags
|
|
1423
|
+
if (!flags.codexOnly && !hasOnlyAgentMcpTarget(flags)) {
|
|
1266
1424
|
process.stdout.write(`\nDetected tools:\n${buildDetectedSummary()}\n`);
|
|
1267
1425
|
}
|
|
1268
1426
|
process.stdout.write(`\nNo files were written.\n`);
|
|
@@ -1270,18 +1428,21 @@ function runOnboardSync(argv: readonly string[]): number {
|
|
|
1270
1428
|
}
|
|
1271
1429
|
|
|
1272
1430
|
const filesToWrite = plannedFiles.filter((file) => shouldWrite(file, flags.force, version));
|
|
1273
|
-
const
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1431
|
+
const agentPlansToWrite = agentPlans.filter((plan) => plan.shouldWrite && plan.body !== null);
|
|
1432
|
+
for (const plan of agentPlans) {
|
|
1433
|
+
if (plan.status.state === "invalid") {
|
|
1434
|
+
process.stderr.write(`agent-inspector onboard: ${plan.blockedMessage ?? "invalid"}\n`);
|
|
1435
|
+
return 1;
|
|
1436
|
+
}
|
|
1278
1437
|
}
|
|
1279
|
-
if (filesToWrite.length === 0 &&
|
|
1438
|
+
if (filesToWrite.length === 0 && agentPlansToWrite.length === 0) {
|
|
1280
1439
|
process.stdout.write(
|
|
1281
1440
|
"agent-inspector onboard: all selected onboarding files are already up to date\n",
|
|
1282
1441
|
);
|
|
1283
|
-
|
|
1284
|
-
|
|
1442
|
+
for (const plan of agentPlans) {
|
|
1443
|
+
if (plan.blockedMessage !== null) {
|
|
1444
|
+
process.stdout.write(`${plan.blockedMessage}\n`);
|
|
1445
|
+
}
|
|
1285
1446
|
}
|
|
1286
1447
|
process.stdout.write("Re-run with --force to refresh.\n");
|
|
1287
1448
|
return 0;
|
|
@@ -1292,9 +1453,11 @@ function runOnboardSync(argv: readonly string[]): number {
|
|
|
1292
1453
|
mkdirSync(dirname(file.path), { recursive: true });
|
|
1293
1454
|
writeFileSync(file.path, file.body, "utf8");
|
|
1294
1455
|
}
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1456
|
+
for (const plan of agentPlansToWrite) {
|
|
1457
|
+
if (plan.body !== null) {
|
|
1458
|
+
mkdirSync(dirname(plan.status.path), { recursive: true });
|
|
1459
|
+
writeFileSync(plan.status.path, plan.body, "utf8");
|
|
1460
|
+
}
|
|
1298
1461
|
}
|
|
1299
1462
|
} catch (err) {
|
|
1300
1463
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -1308,23 +1471,27 @@ function runOnboardSync(argv: readonly string[]): number {
|
|
|
1308
1471
|
for (const file of filesToWrite) {
|
|
1309
1472
|
process.stdout.write(`Installed/updated ${file.label} to: ${file.path}\n`);
|
|
1310
1473
|
}
|
|
1311
|
-
|
|
1312
|
-
process.stdout.write(`Installed/updated
|
|
1474
|
+
for (const plan of agentPlansToWrite) {
|
|
1475
|
+
process.stdout.write(`Installed/updated ${plan.status.label}: ${plan.status.path}\n`);
|
|
1313
1476
|
}
|
|
1314
1477
|
process.stdout.write(`\nNext steps:\n`);
|
|
1315
|
-
if (!flags.codexOnly && !flags
|
|
1478
|
+
if (!flags.codexOnly && !hasOnlyAgentMcpTarget(flags)) {
|
|
1316
1479
|
process.stdout.write(` - Open Claude Code and run: /agent-inspector:onboard\n`);
|
|
1317
1480
|
}
|
|
1318
|
-
if (!flags.skipCodexSkill && !flags
|
|
1481
|
+
if (!flags.skipCodexSkill && !hasOnlyAgentMcpTarget(flags)) {
|
|
1319
1482
|
process.stdout.write(` - Open Codex and ask to use the agent-inspector-onboard skill\n`);
|
|
1320
1483
|
}
|
|
1321
|
-
|
|
1322
|
-
process.stdout.write(` - Verify
|
|
1323
|
-
}
|
|
1324
|
-
if (flags
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1484
|
+
for (const plan of agentPlans) {
|
|
1485
|
+
process.stdout.write(` - Verify ${plan.status.label}: ${plan.status.verifyCommand}\n`);
|
|
1486
|
+
}
|
|
1487
|
+
if (hasOnlyAgentMcpTarget(flags)) {
|
|
1488
|
+
const refreshActions = agentPlans.map((plan) => plan.status.forceAction);
|
|
1489
|
+
const uniqueRefreshActions = Array.from(new Set(refreshActions));
|
|
1490
|
+
const refresh =
|
|
1491
|
+
uniqueRefreshActions.length > 0
|
|
1492
|
+
? uniqueRefreshActions.join(" && ")
|
|
1493
|
+
: "agent-inspector onboard --force";
|
|
1494
|
+
process.stdout.write(` - Refresh selected MCP config later: ${refresh}\n`);
|
|
1328
1495
|
} else {
|
|
1329
1496
|
process.stdout.write(` - Refresh later: agent-inspector onboard --force\n`);
|
|
1330
1497
|
process.stdout.write(` - Detected primary tool: ${toolHint}\n`);
|