@inspectr/mcplab 0.2.0 → 0.4.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.
@@ -0,0 +1,140 @@
1
+ import { existsSync, readdirSync } from 'node:fs';
2
+ import { join, resolve } from 'node:path';
3
+ import { createInterface } from 'node:readline/promises';
4
+ import kleur from 'kleur';
5
+ import { parseNumberSelection, INTERACTIVE_ABORT_ERROR } from './run-interactive.js';
6
+ export function ensureInteractiveTty() {
7
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
8
+ throw new Error('--interactive requires a TTY terminal.');
9
+ }
10
+ }
11
+ export async function selectRunDirInteractive(options) {
12
+ ensureInteractiveTty();
13
+ const cwd = options.cwd ?? process.cwd();
14
+ const runsDir = resolve(cwd, options.runsDir);
15
+ const candidates = getRunDirectoryCandidates(runsDir);
16
+ if (candidates.length === 0) {
17
+ throw new Error(`No run directories with results.json found in ${runsDir}`);
18
+ }
19
+ const ask = createAsker();
20
+ try {
21
+ console.log(kleur.cyan('\nSelect a run directory:'));
22
+ candidates.forEach((candidate, index) => {
23
+ console.log(`${index + 1}. ${candidate.id}`);
24
+ });
25
+ while (true) {
26
+ const input = (await ask.question('Run number or path: ')).trim();
27
+ if (!input) {
28
+ console.log(kleur.yellow('Please enter a selection.'));
29
+ continue;
30
+ }
31
+ if (/^\d+$/.test(input)) {
32
+ const selections = parseNumberSelection(input, candidates.length);
33
+ if (selections.length !== 1) {
34
+ console.log(kleur.yellow('Choose exactly one run.'));
35
+ continue;
36
+ }
37
+ return candidates[selections[0]].path;
38
+ }
39
+ return resolve(cwd, input);
40
+ }
41
+ }
42
+ finally {
43
+ ask.close();
44
+ }
45
+ }
46
+ export async function promptAppOptionsInteractive(current) {
47
+ ensureInteractiveTty();
48
+ const ask = createAsker();
49
+ try {
50
+ console.log(kleur.cyan('\nConfigure MCPLab app startup:'));
51
+ const host = await askWithDefault(ask.question, 'Host', current.host);
52
+ const port = await askValidPort(ask.question, current.port);
53
+ const evalsDir = await askWithDefault(ask.question, 'Evals dir', current.evalsDir);
54
+ const runsDir = await askWithDefault(ask.question, 'Runs dir', current.runsDir);
55
+ const snapshotsDir = await askWithDefault(ask.question, 'Snapshots dir', current.snapshotsDir);
56
+ const toolAnalysisResultsDir = await askWithDefault(ask.question, 'Tool analysis dir', current.toolAnalysisResultsDir);
57
+ const librariesDir = await askWithDefault(ask.question, 'Libraries dir', current.librariesDir);
58
+ console.log(kleur.cyan('\nApp launch summary:'));
59
+ console.log(`host: ${host}`);
60
+ console.log(`port: ${port}`);
61
+ console.log(`evals-dir: ${evalsDir}`);
62
+ console.log(`runs-dir: ${runsDir}`);
63
+ console.log(`snapshots-dir: ${snapshotsDir}`);
64
+ console.log(`tool-analysis-results-dir: ${toolAnalysisResultsDir}`);
65
+ console.log(`libraries-dir: ${librariesDir}`);
66
+ const confirm = (await ask.question('Start app with these settings? [Y/n]: ')).trim().toLowerCase();
67
+ if (confirm === 'n' || confirm === 'no') {
68
+ throw new Error(INTERACTIVE_ABORT_ERROR);
69
+ }
70
+ return {
71
+ host,
72
+ port,
73
+ evalsDir,
74
+ runsDir,
75
+ snapshotsDir,
76
+ toolAnalysisResultsDir,
77
+ librariesDir
78
+ };
79
+ }
80
+ finally {
81
+ ask.close();
82
+ }
83
+ }
84
+ function getRunDirectoryCandidates(runsDir) {
85
+ if (!existsSync(runsDir)) {
86
+ return [];
87
+ }
88
+ return readdirSync(runsDir)
89
+ .map((entry) => ({
90
+ id: entry,
91
+ path: join(runsDir, entry)
92
+ }))
93
+ .filter((entry) => existsSync(join(entry.path, 'results.json')))
94
+ .sort((a, b) => b.id.localeCompare(a.id));
95
+ }
96
+ async function askWithDefault(question, label, defaultValue) {
97
+ const answer = (await question(`${label} [${defaultValue}]: `)).trim();
98
+ return answer || defaultValue;
99
+ }
100
+ async function askValidPort(question, defaultPort) {
101
+ while (true) {
102
+ const value = await askWithDefault(question, 'Port', defaultPort);
103
+ const parsed = Number(value);
104
+ if (!Number.isNaN(parsed) && parsed > 0) {
105
+ return String(parsed);
106
+ }
107
+ console.log(kleur.yellow('Port must be a positive number.'));
108
+ }
109
+ }
110
+ function createAsker() {
111
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
112
+ let interrupted = false;
113
+ const onSigint = () => {
114
+ interrupted = true;
115
+ rl.close();
116
+ };
117
+ process.once('SIGINT', onSigint);
118
+ return {
119
+ question: async (prompt) => {
120
+ try {
121
+ return await rl.question(prompt);
122
+ }
123
+ catch (error) {
124
+ if (interrupted) {
125
+ throw new Error(INTERACTIVE_ABORT_ERROR);
126
+ }
127
+ const message = error instanceof Error ? error.message : String(error);
128
+ if (message.toLowerCase().includes('closed')) {
129
+ throw new Error(INTERACTIVE_ABORT_ERROR);
130
+ }
131
+ throw error;
132
+ }
133
+ },
134
+ close: () => {
135
+ process.off('SIGINT', onSigint);
136
+ rl.close();
137
+ }
138
+ };
139
+ }
140
+ //# sourceMappingURL=interactive-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive-helpers.js","sourceRoot":"","sources":["../src/interactive-helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { SourceEvalConfig } from '@inspectr/mcplab-core';
2
+ /** Pure transformation: migrates a single source config to the canonical format.
3
+ * Moves top-level inline server definitions into scenario-owned mcp_servers entries
4
+ * so that refs point to library servers and inline entries remain inline.
5
+ * Does not read or write files. */
6
+ export declare function migrateSourceConfig(sourceConfig: SourceEvalConfig): SourceEvalConfig;
7
+ //# sourceMappingURL=migrate-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate-utils.d.ts","sourceRoot":"","sources":["../src/migrate-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D;;;oCAGoC;AACpC,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,gBAAgB,GAAG,gBAAgB,CAoCpF"}
@@ -0,0 +1,40 @@
1
+ /** Pure transformation: migrates a single source config to the canonical format.
2
+ * Moves top-level inline server definitions into scenario-owned mcp_servers entries
3
+ * so that refs point to library servers and inline entries remain inline.
4
+ * Does not read or write files. */
5
+ export function migrateSourceConfig(sourceConfig) {
6
+ // Build lookup from top-level servers so inline definitions survive the move
7
+ // to scenario-owned mcp_servers entries instead of becoming broken refs.
8
+ const serverEntryById = new Map();
9
+ for (const entry of (sourceConfig.servers ?? [])) {
10
+ if ('ref' in entry && entry.ref) {
11
+ serverEntryById.set(String(entry.ref), { ref: entry.ref });
12
+ }
13
+ else if (entry.id) {
14
+ serverEntryById.set(String(entry.id), entry);
15
+ }
16
+ }
17
+ return {
18
+ ...sourceConfig,
19
+ servers: [],
20
+ scenarios: sourceConfig.scenarios.map((s) => {
21
+ if ('ref' in s)
22
+ return s;
23
+ const scenario = s;
24
+ if (Array.isArray(scenario.servers) &&
25
+ scenario.servers.length > 0 &&
26
+ typeof scenario.servers[0] === 'string' &&
27
+ !scenario.mcp_servers) {
28
+ const { servers: _legacyServers, ...rest } = scenario;
29
+ return {
30
+ ...rest,
31
+ mcp_servers: _legacyServers.map((id) =>
32
+ // Use the original entry (inline or ref) — fall back to ref only if unknown
33
+ serverEntryById.get(id) ?? { ref: id })
34
+ };
35
+ }
36
+ return s;
37
+ })
38
+ };
39
+ }
40
+ //# sourceMappingURL=migrate-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate-utils.js","sourceRoot":"","sources":["../src/migrate-utils.ts"],"names":[],"mappings":"AAEA;;;oCAGoC;AACpC,MAAM,UAAU,mBAAmB,CAAC,YAA8B;IAChE,6EAA6E;IAC7E,yEAAyE;IACzE,MAAM,eAAe,GAAG,IAAI,GAAG,EAAmC,CAAC;IACnE,KAAK,MAAM,KAAK,IAAI,CAAC,YAAY,CAAC,OAAO,IAAI,EAAE,CAAU,EAAE,CAAC;QAC1D,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;YAChC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QAC7D,CAAC;aAAM,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC;YACpB,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAED,OAAO;QACL,GAAG,YAAY;QACf,OAAO,EAAE,EAAE;QACX,SAAS,EAAE,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YAC1C,IAAI,KAAK,IAAI,CAAC;gBAAE,OAAO,CAAC,CAAC;YACzB,MAAM,QAAQ,GAAG,CAAQ,CAAC;YAC1B,IACE,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAC/B,QAAQ,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;gBAC3B,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,QAAQ;gBACvC,CAAC,QAAQ,CAAC,WAAW,EACrB,CAAC;gBACD,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,IAAI,EAAE,GAAG,QAAQ,CAAC;gBACtD,OAAO;oBACL,GAAG,IAAI;oBACP,WAAW,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC,EAAU,EAAE,EAAE;oBAC7C,4EAA4E;oBAC5E,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,CACvC;iBACF,CAAC;YACJ,CAAC;YACD,OAAO,CAAC,CAAC;QACX,CAAC,CAAC;KACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,33 @@
1
+ import type { EvalConfig } from '@inspectr/mcplab-core';
2
+ export declare const INTERACTIVE_ABORT_ERROR = "Interactive input cancelled.";
3
+ export type InteractiveAgentMode = 'all' | 'defaults' | 'specific';
4
+ export interface InteractiveSelectionResult {
5
+ configPath: string;
6
+ agentMode: InteractiveAgentMode;
7
+ agents?: string[];
8
+ }
9
+ export interface ResolveRunOptionsInput {
10
+ interactive: boolean;
11
+ config?: string;
12
+ agents?: string;
13
+ agentsAll?: boolean;
14
+ interactiveSelection?: InteractiveSelectionResult;
15
+ }
16
+ export interface ResolveRunOptionsResult {
17
+ config: string;
18
+ agents?: string;
19
+ agentsAll: boolean;
20
+ }
21
+ export interface RunInteractiveSelectionOptions {
22
+ initialConfigPath?: string;
23
+ defaultEvalsDir?: string;
24
+ cwd?: string;
25
+ promptAgentSelection?: boolean;
26
+ loadConfigForValidation: (path: string) => {
27
+ config: EvalConfig;
28
+ };
29
+ }
30
+ export declare function parseNumberSelection(input: string, max: number): number[];
31
+ export declare function resolveRunOptions(input: ResolveRunOptionsInput): ResolveRunOptionsResult;
32
+ export declare function runInteractiveSelection(opts: RunInteractiveSelectionOptions): Promise<InteractiveSelectionResult>;
33
+ //# sourceMappingURL=run-interactive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-interactive.d.ts","sourceRoot":"","sources":["../src/run-interactive.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGxD,eAAO,MAAM,uBAAuB,iCAAiC,CAAC;AAEtE,MAAM,MAAM,oBAAoB,GAAG,KAAK,GAAG,UAAU,GAAG,UAAU,CAAC;AAEnE,MAAM,WAAW,0BAA0B;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,oBAAoB,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oBAAoB,CAAC,EAAE,0BAA0B,CAAC;CACnD;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,8BAA8B;IAC7C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,uBAAuB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,MAAM,EAAE,UAAU,CAAA;KAAE,CAAC;CACnE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CA0BzE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,uBAAuB,CA8DxF;AAED,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,8BAA8B,GACnC,OAAO,CAAC,0BAA0B,CAAC,CAuDrC"}
@@ -0,0 +1,256 @@
1
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ import { createInterface } from 'node:readline/promises';
4
+ import kleur from 'kleur';
5
+ import { parse } from 'yaml';
6
+ export const INTERACTIVE_ABORT_ERROR = 'Interactive input cancelled.';
7
+ export function parseNumberSelection(input, max) {
8
+ const parts = input
9
+ .split(',')
10
+ .map((part) => part.trim())
11
+ .filter(Boolean);
12
+ if (parts.length === 0) {
13
+ throw new Error('Please provide at least one number.');
14
+ }
15
+ const indices = [];
16
+ const seen = new Set();
17
+ for (const part of parts) {
18
+ if (!/^\d+$/.test(part)) {
19
+ throw new Error(`Invalid selection "${part}". Expected numeric values.`);
20
+ }
21
+ const oneBased = Number(part);
22
+ if (!Number.isInteger(oneBased) || oneBased < 1 || oneBased > max) {
23
+ throw new Error(`Selection "${part}" is out of range (1-${max}).`);
24
+ }
25
+ const zeroBased = oneBased - 1;
26
+ if (!seen.has(zeroBased)) {
27
+ seen.add(zeroBased);
28
+ indices.push(zeroBased);
29
+ }
30
+ }
31
+ return indices;
32
+ }
33
+ export function resolveRunOptions(input) {
34
+ const agentsCsv = input.agents?.trim();
35
+ const agentsAll = Boolean(input.agentsAll);
36
+ if (agentsAll && agentsCsv) {
37
+ throw new Error('Use either --agents or --agents-all, not both.');
38
+ }
39
+ if (!input.interactive) {
40
+ if (!input.config?.trim()) {
41
+ throw new Error('config is required');
42
+ }
43
+ return {
44
+ config: input.config.trim(),
45
+ agents: agentsCsv || undefined,
46
+ agentsAll
47
+ };
48
+ }
49
+ const selection = input.interactiveSelection;
50
+ const resolvedConfig = input.config?.trim() || selection?.configPath;
51
+ if (!resolvedConfig) {
52
+ throw new Error('config is required');
53
+ }
54
+ if (agentsAll || agentsCsv) {
55
+ return {
56
+ config: resolvedConfig,
57
+ agents: agentsCsv || undefined,
58
+ agentsAll
59
+ };
60
+ }
61
+ if (!selection) {
62
+ return {
63
+ config: resolvedConfig,
64
+ agentsAll: false
65
+ };
66
+ }
67
+ if (selection.agentMode === 'all') {
68
+ return {
69
+ config: resolvedConfig,
70
+ agentsAll: true
71
+ };
72
+ }
73
+ if (selection.agentMode === 'specific') {
74
+ if (!selection.agents || selection.agents.length === 0) {
75
+ throw new Error('Interactive specific agent selection cannot be empty.');
76
+ }
77
+ return {
78
+ config: resolvedConfig,
79
+ agents: selection.agents.join(','),
80
+ agentsAll: false
81
+ };
82
+ }
83
+ return {
84
+ config: resolvedConfig,
85
+ agentsAll: false
86
+ };
87
+ }
88
+ export async function runInteractiveSelection(opts) {
89
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
90
+ throw new Error('--interactive requires a TTY terminal.');
91
+ }
92
+ const cwd = opts.cwd ?? process.cwd();
93
+ const evalsDir = resolve(cwd, opts.defaultEvalsDir ?? 'mcplab/evals');
94
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
95
+ let interrupted = false;
96
+ const onSigint = () => {
97
+ interrupted = true;
98
+ rl.close();
99
+ };
100
+ process.once('SIGINT', onSigint);
101
+ const ask = async (question) => {
102
+ try {
103
+ return await rl.question(question);
104
+ }
105
+ catch (error) {
106
+ if (interrupted) {
107
+ throw new Error(INTERACTIVE_ABORT_ERROR);
108
+ }
109
+ const message = error instanceof Error ? error.message : String(error);
110
+ if (message.toLowerCase().includes('closed')) {
111
+ throw new Error(INTERACTIVE_ABORT_ERROR);
112
+ }
113
+ throw error;
114
+ }
115
+ };
116
+ try {
117
+ const configPath = opts.initialConfigPath
118
+ ? resolve(cwd, opts.initialConfigPath)
119
+ : await promptForConfigPath(ask, evalsDir, cwd, opts.loadConfigForValidation);
120
+ const shouldPromptAgentSelection = opts.promptAgentSelection ?? true;
121
+ if (!shouldPromptAgentSelection) {
122
+ return { configPath, agentMode: 'defaults' };
123
+ }
124
+ const loaded = opts.loadConfigForValidation(configPath);
125
+ const agentIds = Object.keys(loaded.config.agents);
126
+ const defaults = loaded.config.run_defaults?.selected_agents ?? [];
127
+ const agentMode = await promptForAgentMode(ask, agentIds, defaults);
128
+ if (agentMode === 'specific') {
129
+ const agents = await promptForSpecificAgents(ask, agentIds);
130
+ return { configPath, agentMode, agents };
131
+ }
132
+ return { configPath, agentMode };
133
+ }
134
+ finally {
135
+ process.off('SIGINT', onSigint);
136
+ rl.close();
137
+ }
138
+ }
139
+ async function promptForConfigPath(ask, evalsDir, cwd, loadConfigForValidation) {
140
+ const files = existsSync(evalsDir)
141
+ ? readdirSync(evalsDir)
142
+ .filter((name) => name.endsWith('.yaml') || name.endsWith('.yml'))
143
+ .sort((a, b) => a.localeCompare(b))
144
+ : [];
145
+ const choices = files.map((fileName) => {
146
+ const path = resolve(evalsDir, fileName);
147
+ return {
148
+ path,
149
+ fileName,
150
+ label: readConfigName(path) ?? fileName
151
+ };
152
+ });
153
+ if (choices.length > 0) {
154
+ console.log(kleur.cyan('\nSelect an evaluation config:'));
155
+ choices.forEach((choice, index) => {
156
+ const suffix = choice.label === choice.fileName ? '' : ` ${kleur.gray(`(${choice.fileName})`)}`;
157
+ console.log(`${index + 1}. ${choice.label}${suffix}`);
158
+ });
159
+ }
160
+ else {
161
+ console.log(kleur.yellow(`\nNo configs found in ${evalsDir}. Enter a path manually.`));
162
+ }
163
+ while (true) {
164
+ const prompt = choices.length > 0
165
+ ? 'Config number or path: '
166
+ : 'Config path: ';
167
+ const input = (await ask(prompt)).trim();
168
+ if (!input) {
169
+ console.log(kleur.yellow('Please enter a selection.'));
170
+ continue;
171
+ }
172
+ let candidatePath = input;
173
+ if (choices.length > 0 && /^\d+$/.test(input)) {
174
+ const selected = Number(input);
175
+ if (selected < 1 || selected > choices.length) {
176
+ console.log(kleur.yellow(`Selection out of range (1-${choices.length}).`));
177
+ continue;
178
+ }
179
+ candidatePath = choices[selected - 1].path;
180
+ }
181
+ else {
182
+ candidatePath = resolve(cwd, input);
183
+ }
184
+ try {
185
+ loadConfigForValidation(candidatePath);
186
+ return candidatePath;
187
+ }
188
+ catch (error) {
189
+ const message = error instanceof Error ? error.message : String(error);
190
+ console.log(kleur.yellow(`Invalid config: ${message}`));
191
+ }
192
+ }
193
+ }
194
+ function readConfigName(configPath) {
195
+ try {
196
+ const raw = readFileSync(configPath, 'utf8');
197
+ const parsed = parse(raw);
198
+ const name = typeof parsed?.name === 'string' ? parsed.name.trim() : '';
199
+ return name || undefined;
200
+ }
201
+ catch {
202
+ return undefined;
203
+ }
204
+ }
205
+ async function promptForAgentMode(ask, agentIds, defaults) {
206
+ if (agentIds.length === 0) {
207
+ throw new Error('Config has no resolved agents.');
208
+ }
209
+ console.log(kleur.cyan('\nSelect agent mode:'));
210
+ console.log('1. All configured agents');
211
+ if (defaults.length > 0) {
212
+ console.log(`2. Run defaults from config (${defaults.join(', ')})`);
213
+ }
214
+ console.log(defaults.length > 0 ? '3. Choose specific agents' : '2. Choose specific agents');
215
+ const max = defaults.length > 0 ? 3 : 2;
216
+ while (true) {
217
+ const input = (await ask('Choice: ')).trim();
218
+ try {
219
+ const selections = parseNumberSelection(input, max);
220
+ if (selections.length !== 1) {
221
+ throw new Error('Choose exactly one option.');
222
+ }
223
+ const selected = selections[0];
224
+ if (selected === 0)
225
+ return 'all';
226
+ if (defaults.length > 0 && selected === 1)
227
+ return 'defaults';
228
+ return 'specific';
229
+ }
230
+ catch (error) {
231
+ const message = error instanceof Error ? error.message : String(error);
232
+ console.log(kleur.yellow(message));
233
+ }
234
+ }
235
+ }
236
+ async function promptForSpecificAgents(ask, agentIds) {
237
+ console.log(kleur.cyan('\nSelect specific agents (comma-separated numbers):'));
238
+ agentIds.forEach((agentId, index) => {
239
+ console.log(`${index + 1}. ${agentId}`);
240
+ });
241
+ while (true) {
242
+ const input = (await ask('Agent numbers: ')).trim();
243
+ try {
244
+ const selectedIndices = parseNumberSelection(input, agentIds.length);
245
+ if (selectedIndices.length === 0) {
246
+ throw new Error('Select at least one agent.');
247
+ }
248
+ return selectedIndices.map((index) => agentIds[index]);
249
+ }
250
+ catch (error) {
251
+ const message = error instanceof Error ? error.message : String(error);
252
+ console.log(kleur.yellow(message));
253
+ }
254
+ }
255
+ }
256
+ //# sourceMappingURL=run-interactive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-interactive.js","sourceRoot":"","sources":["../src/run-interactive.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inspectr/mcplab",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "MCPLab - Test and evaluate MCP servers with LLMs — run evals, compare agents and launch the MCPLab web app",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -43,9 +43,9 @@
43
43
  "vitest": "^3.2.4"
44
44
  },
45
45
  "dependencies": {
46
- "@inspectr/mcplab-core": "0.2.0",
47
- "@inspectr/mcplab-mcp-server": "0.2.0",
48
- "@inspectr/mcplab-reporting": "0.2.0",
46
+ "@inspectr/mcplab-core": "0.4.0",
47
+ "@inspectr/mcplab-mcp-server": "0.3.0",
48
+ "@inspectr/mcplab-reporting": "0.3.0",
49
49
  "commander": "^12.1.0",
50
50
  "dotenv": "^16.4.5",
51
51
  "kleur": "^4.1.5",