@clien-ai/mcp 0.2.1 → 0.3.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.
@@ -17,6 +17,11 @@
17
17
  * enforced in the handler, not via `.superRefine` (which would yield a
18
18
  * `ZodEffects`, not a `ZodObject`).
19
19
  *
20
+ * Params are snake_case (`project_id`, `persona_id`, `interview_id`) — matching
21
+ * every other tool — and translated to the camelCase the REST API expects at the
22
+ * call site. FUL-233: the pre-migration camelCase spellings stay accepted as
23
+ * deprecated aliases (see `INTERVIEW_PERSONA_ALIASES` and `param-aliases.ts`).
24
+ *
20
25
  * Contract (all bearer-authenticated, ownership derived from the parent project):
21
26
  * - start → POST /api/interviews { projectId, personaId, withFirstMessage:true, ephemeral } → { interview, personaName, firstMessageContent }
22
27
  * - turn → POST /api/interviews/{id}/turn { content } → { reply, message, userMessage, messageCount }
@@ -34,10 +39,17 @@
34
39
  */
35
40
  import { z } from 'zod';
36
41
  import { ToolError } from './errors.js';
42
+ import { deprecatedAlias } from './param-aliases.js';
37
43
  import { apiCall, categorizeFetchError, truncate, } from './research.js';
38
44
  const INTERVIEW_FETCH_TIMEOUT_MS = 60_000;
39
45
  /** Upper bound on a turn's question — matches the server's `MESSAGE_CONTENT_MAX`. */
40
46
  const CONTENT_MAX = 10_000;
47
+ /** FUL-233: legacy camelCase spellings `interview_persona` still accepts. */
48
+ export const INTERVIEW_PERSONA_ALIASES = {
49
+ projectId: 'project_id',
50
+ personaId: 'persona_id',
51
+ interviewId: 'interview_id',
52
+ };
41
53
  export const InterviewPersonaInputSchema = z.object({
42
54
  action: z
43
55
  .enum(['start', 'turn', 'transcript', 'complete', 'reopen'])
@@ -46,24 +58,24 @@ export const InterviewPersonaInputSchema = z.object({
46
58
  'read the persona\'s full reply, decide the next question. `transcript` re-reads the ' +
47
59
  'whole conversation. `complete` closes the interview when you\'ve learned enough ' +
48
60
  '(5-12 turns is typical); `reopen` resumes a completed one.'),
49
- projectId: z
61
+ project_id: z
50
62
  .string()
51
63
  .uuid()
52
64
  .optional()
53
- .describe('action=start: UUID of the project the interview belongs to. Get it from `list_projects` ' +
54
- 'or `create_project`. You are 404\'d if you do not own it.'),
55
- personaId: z
65
+ .describe('action=start (REQUIRED there): UUID of the project the interview belongs to. Get it from ' +
66
+ '`list_projects` or `create_project`. You are 404\'d if you do not own it.'),
67
+ persona_id: z
56
68
  .string()
57
69
  .uuid()
58
70
  .optional()
59
- .describe('action=start: UUID of the persona to interview (must belong to `projectId`). Get it from ' +
60
- '`create_persona` (`_meta.persona.id`).'),
61
- interviewId: z
71
+ .describe('action=start (REQUIRED there): UUID of the persona to interview (must belong to ' +
72
+ '`project_id`). Get it from `list_personas` or `create_persona` (`_meta.persona.id`).'),
73
+ interview_id: z
62
74
  .string()
63
75
  .uuid()
64
76
  .optional()
65
- .describe('action=turn/transcript/complete/reopen: UUID of the interview to act on. Returned by ' +
66
- '`start` in `_meta.interview.id`.'),
77
+ .describe('action=turn/transcript/complete/reopen (REQUIRED there): UUID of the interview to act on. ' +
78
+ 'Returned by `start` in `_meta.interview.id`, or discoverable via `list_interviews`.'),
67
79
  content: z
68
80
  .string()
69
81
  .trim()
@@ -79,6 +91,10 @@ export const InterviewPersonaInputSchema = z.object({
79
91
  .describe('action=start: set true for a scratch/throwaway interview that should NOT count toward the ' +
80
92
  'project\'s aggregate insights (sets include_in_insights=false). Leave false (the default) ' +
81
93
  'for a real interview you want reflected in project-level analysis.'),
94
+ // --- Deprecated camelCase aliases (FUL-233) — rewritten before parse. ---
95
+ projectId: deprecatedAlias('project_id', z.string().uuid()),
96
+ personaId: deprecatedAlias('persona_id', z.string().uuid()),
97
+ interviewId: deprecatedAlias('interview_id', z.string().uuid()),
82
98
  });
83
99
  export class InterviewToolError extends ToolError {
84
100
  }
@@ -94,7 +110,7 @@ function makeCtx(deps) {
94
110
  * 404 means the interview/project isn't owned by the caller; 400 surfaces the
95
111
  * server's validation detail; everything else surfaces a generic HTTP error.
96
112
  */
97
- async function throwForResponse(response, deps, action) {
113
+ async function throwForResponse(response, deps, action, options) {
98
114
  const category = categorizeFetchError(response.status);
99
115
  if (category === 'auth') {
100
116
  if (response.refreshError?.kind !== 'transient')
@@ -102,8 +118,9 @@ async function throwForResponse(response, deps, action) {
102
118
  throw new InterviewToolError('Session expired. Re-run any Clien.ai tool to re-authenticate, then try again.');
103
119
  }
104
120
  if (response.status === 404) {
105
- throw new InterviewToolError(`Could not ${action} — interview or project not found, or you don't own it. ` +
106
- 'Confirm the ids (list_projects / the id from `start`).');
121
+ throw new InterviewToolError(options?.notFound ??
122
+ `Could not ${action} — interview or project not found, or you don't own it. ` +
123
+ 'Confirm the ids (list_projects / the id from `start`).');
107
124
  }
108
125
  const text = await response.text().catch(() => '');
109
126
  let detail = truncate(text, 200);
@@ -151,12 +168,12 @@ function formatTranscript(interview) {
151
168
  return lines.length > 0 ? `${header}\n\n${lines.join('\n\n')}` : header;
152
169
  }
153
170
  async function startInterview(input, ctx, deps) {
154
- if (!input.projectId || !input.personaId) {
155
- throw new InterviewToolError("action 'start' requires projectId and personaId.");
171
+ if (!input.project_id || !input.persona_id) {
172
+ throw new InterviewToolError("action 'start' requires project_id and persona_id.");
156
173
  }
157
174
  const response = await call(ctx, 'POST', '/api/interviews', 'start interview', {
158
- projectId: input.projectId,
159
- personaId: input.personaId,
175
+ projectId: input.project_id,
176
+ personaId: input.persona_id,
160
177
  withFirstMessage: true,
161
178
  ephemeral: input.ephemeral,
162
179
  });
@@ -184,10 +201,10 @@ async function startInterview(input, ctx, deps) {
184
201
  };
185
202
  }
186
203
  async function sendTurn(input, ctx, deps) {
187
- if (!input.interviewId || !input.content) {
188
- throw new InterviewToolError("action 'turn' requires interviewId and content.");
204
+ if (!input.interview_id || !input.content) {
205
+ throw new InterviewToolError("action 'turn' requires interview_id and content.");
189
206
  }
190
- const response = await call(ctx, 'POST', `/api/interviews/${input.interviewId}/turn`, 'send interview turn', { content: input.content });
207
+ const response = await call(ctx, 'POST', `/api/interviews/${input.interview_id}/turn`, 'send interview turn', { content: input.content });
191
208
  if (!response.ok)
192
209
  await throwForResponse(response, deps, 'send interview turn');
193
210
  const json = await readJson(response);
@@ -206,10 +223,10 @@ async function sendTurn(input, ctx, deps) {
206
223
  };
207
224
  }
208
225
  async function fetchTranscript(input, ctx, deps) {
209
- if (!input.interviewId) {
210
- throw new InterviewToolError("action 'transcript' requires interviewId.");
226
+ if (!input.interview_id) {
227
+ throw new InterviewToolError("action 'transcript' requires interview_id.");
211
228
  }
212
- const response = await call(ctx, 'GET', `/api/interviews/${input.interviewId}`, 'fetch transcript');
229
+ const response = await call(ctx, 'GET', `/api/interviews/${input.interview_id}`, 'fetch transcript');
213
230
  if (!response.ok)
214
231
  await throwForResponse(response, deps, 'fetch transcript');
215
232
  const json = await readJson(response);
@@ -224,10 +241,10 @@ async function fetchTranscript(input, ctx, deps) {
224
241
  }
225
242
  async function setStatus(input, ctx, deps, status) {
226
243
  const action = status === 'completed' ? 'complete' : 'reopen';
227
- if (!input.interviewId) {
228
- throw new InterviewToolError(`action '${action}' requires interviewId.`);
244
+ if (!input.interview_id) {
245
+ throw new InterviewToolError(`action '${action}' requires interview_id.`);
229
246
  }
230
- const response = await call(ctx, 'PATCH', `/api/interviews/${input.interviewId}`, `${action} interview`, { status });
247
+ const response = await call(ctx, 'PATCH', `/api/interviews/${input.interview_id}`, `${action} interview`, { status });
231
248
  if (!response.ok)
232
249
  await throwForResponse(response, deps, `${action} interview`);
233
250
  const json = await readJson(response);
@@ -261,4 +278,152 @@ export async function interviewPersona(input, deps) {
261
278
  return setStatus(data, ctx, deps, 'active');
262
279
  }
263
280
  }
281
+ // ---------------------------------------------------------------------------
282
+ // list_interviews + get_interview (FUL-209 / §U3) — read-only transcript recall
283
+ // ---------------------------------------------------------------------------
284
+ //
285
+ // `list_interviews` discovers past interviews in a project (get IDs, previously
286
+ // unrecoverable — `interview_persona action:transcript` needs an interviewId
287
+ // only obtainable from `action:start`); `get_interview` re-reads one full
288
+ // transcript. Both are read-only over the existing bearer endpoints — zero
289
+ // credit cost, zero side effects — mirroring `list_reports`/`get_report` and the
290
+ // `list_personas`/`get_persona` reads.
291
+ //
292
+ // Params are snake_case (`project_id`, `interview_id`) — matching the other read
293
+ // tools (`get_report`→`job_id`, `get_persona`→`persona_id`) — validated as UUIDs
294
+ // before the HTTP call, then mapped to the camelCase (`projectId`) the REST API
295
+ // expects. There is NO server-side `persona_id` filter, so v1 omits one rather
296
+ // than fake a client-side filter that would under-fill a page.
297
+ const LIST_INTERVIEWS_TIMEOUT_MS = 30_000;
298
+ const LIST_LIMIT_MAX = 100;
299
+ const LIST_LIMIT_DEFAULT = 20;
300
+ export const ListInterviewsInputSchema = z.object({
301
+ project_id: z
302
+ .string()
303
+ .uuid()
304
+ .describe('UUID of the project whose interviews to list. Get it from `list_projects` ' +
305
+ '(or `create_project`). Rejected with a 404 if you do not own the project. ' +
306
+ 'Lists interviews started from the web app too, so you can discover an ' +
307
+ 'interview id to re-read with `get_interview`.'),
308
+ limit: z
309
+ .number()
310
+ .int()
311
+ .min(1)
312
+ .max(LIST_LIMIT_MAX)
313
+ .optional()
314
+ .default(LIST_LIMIT_DEFAULT)
315
+ .describe(`Maximum number of interviews to return (1-${LIST_LIMIT_MAX}, default ${LIST_LIMIT_DEFAULT}). ` +
316
+ 'Newest interviews come first.'),
317
+ offset: z
318
+ .number()
319
+ .int()
320
+ .min(0)
321
+ .optional()
322
+ .default(0)
323
+ .describe('Number of interviews to skip before returning results (default 0). ' +
324
+ 'Combine with `limit` to page through a large interview list; the total ' +
325
+ 'count is returned in `_meta.pagination.total`.'),
326
+ });
327
+ export const GetInterviewInputSchema = z.object({
328
+ interview_id: z
329
+ .string()
330
+ .uuid()
331
+ .describe('UUID of the interview to fetch. Get it from a `list_interviews` entry (or ' +
332
+ 'an interview\'s `_meta.interview.id` from `interview_persona`). Rejected ' +
333
+ 'with a 404 if you do not own it. Returns the full message transcript.'),
334
+ });
335
+ export async function listInterviews(input, deps) {
336
+ const parsed = ListInterviewsInputSchema.safeParse(input);
337
+ if (!parsed.success) {
338
+ throw new InterviewToolError(`Invalid input — ${formatZodError(parsed.error)}`);
339
+ }
340
+ const { project_id: projectId, limit, offset } = parsed.data;
341
+ const ctx = makeCtx(deps);
342
+ const query = new URLSearchParams({
343
+ projectId,
344
+ limit: String(limit),
345
+ offset: String(offset),
346
+ });
347
+ let response;
348
+ try {
349
+ response = await apiCall(ctx, 'GET', `/api/interviews?${query.toString()}`, {
350
+ timeoutMs: LIST_INTERVIEWS_TIMEOUT_MS,
351
+ });
352
+ }
353
+ catch (err) {
354
+ const e = err;
355
+ if (e.name === 'AbortError' || e.name === 'TimeoutError') {
356
+ throw new InterviewToolError(`Listing interviews timed out after ${LIST_INTERVIEWS_TIMEOUT_MS / 1000}s. Try again in a moment.`);
357
+ }
358
+ throw err;
359
+ }
360
+ if (!response.ok) {
361
+ await throwForResponse(response, deps, 'list interviews', {
362
+ notFound: 'Could not list interviews — project not found, or you don\'t own it. ' +
363
+ 'Call list_projects to confirm the project_id.',
364
+ });
365
+ }
366
+ const json = await readJson(response);
367
+ const interviews = json?.interviews ?? [];
368
+ const total = json?.pagination?.total ?? interviews.length;
369
+ let text;
370
+ if (interviews.length === 0) {
371
+ text =
372
+ offset > 0
373
+ ? `No interviews at offset ${offset} in project ${projectId} (total: ${total}).`
374
+ : `No interviews in project ${projectId}. Start one with interview_persona (action:start).`;
375
+ }
376
+ else {
377
+ const lines = interviews.map((iv) => {
378
+ const count = iv.messages?.length ?? 0;
379
+ const persona = iv.personaId ? ` with persona ${iv.personaId}` : '';
380
+ return `- ${iv.status ?? 'unknown'} interview${persona} — ${count} message${count === 1 ? '' : 's'} (id: ${iv.id ?? 'unknown'})`;
381
+ });
382
+ const shown = offset + interviews.length;
383
+ const more = shown < total ? `\n\n${total - shown} more not shown — page with offset=${shown}.` : '';
384
+ text =
385
+ `Found ${total} interview${total === 1 ? '' : 's'} in project ${projectId}:\n${lines.join('\n')}${more}\n\n` +
386
+ 'Use get_interview with an id to re-read a full transcript.';
387
+ }
388
+ return {
389
+ content: [{ type: 'text', text }],
390
+ _meta: { interviews, pagination: json?.pagination ?? { limit, offset, total } },
391
+ };
392
+ }
393
+ export async function getInterview(input, deps) {
394
+ const parsed = GetInterviewInputSchema.safeParse(input);
395
+ if (!parsed.success) {
396
+ throw new InterviewToolError(`Invalid input — ${formatZodError(parsed.error)}`);
397
+ }
398
+ const { interview_id: interviewId } = parsed.data;
399
+ const ctx = makeCtx(deps);
400
+ let response;
401
+ try {
402
+ response = await apiCall(ctx, 'GET', `/api/interviews/${interviewId}`, {
403
+ timeoutMs: INTERVIEW_FETCH_TIMEOUT_MS,
404
+ });
405
+ }
406
+ catch (err) {
407
+ const e = err;
408
+ if (e.name === 'AbortError' || e.name === 'TimeoutError') {
409
+ throw new InterviewToolError(`Fetching the interview timed out after ${INTERVIEW_FETCH_TIMEOUT_MS / 1000}s. Try again in a moment.`);
410
+ }
411
+ throw err;
412
+ }
413
+ if (!response.ok) {
414
+ await throwForResponse(response, deps, 'get interview', {
415
+ notFound: 'Could not get interview — interview not found, or you don\'t own it. ' +
416
+ 'Confirm the interview_id (e.g. from list_interviews).',
417
+ });
418
+ }
419
+ const json = await readJson(response);
420
+ const interview = json?.interview;
421
+ if (!interview?.id) {
422
+ throw new InterviewToolError('Interview fetch returned no interview; the operation may not have succeeded.');
423
+ }
424
+ return {
425
+ content: [{ type: 'text', text: formatTranscript(interview) }],
426
+ _meta: { interview },
427
+ };
428
+ }
264
429
  //# sourceMappingURL=interview.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"interview.js","sourceRoot":"","sources":["../../src/tools/interview.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"interview.js","sourceRoot":"","sources":["../../src/tools/interview.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Backward-compatible camelCase → snake_case parameter aliasing (FUL-233).
3
+ *
4
+ * The tool surface settled on snake_case params (`project_id`, `persona_id`,
5
+ * `job_id`, …) as every read tool landed, but five older write tools still
6
+ * advertised camelCase (`projectId`, `companySize`, `groundInEvidence`, …).
7
+ * A public API cannot simply rename those: `@clien-ai/mcp` is published to npm
8
+ * and existing callers pass the old spellings. So each legacy name survives as
9
+ * a DEPRECATED ALIAS while snake_case becomes the documented form.
10
+ *
11
+ * How it fits together — three pieces, one source of truth per tool:
12
+ *
13
+ * 1. The tool's Zod schema declares the canonical snake_case field normally,
14
+ * plus the camelCase alias via `deprecatedAlias()`. Declaring the alias is
15
+ * load-bearing, not cosmetic: `zodToInputSchema` stamps
16
+ * `additionalProperties: false` on every advert, so an UNDECLARED alias
17
+ * would be a field the schema publicly disowns while the server quietly
18
+ * honours it — and strict MCP clients would drop it before it ever reached
19
+ * us. Declared, the advert and the runtime tell the same story.
20
+ * 2. The registry entry carries the matching `paramAliases` map, and
21
+ * `defineTool` wraps the handler with `normalizeParamAliases` — so a tool
22
+ * cannot forget to call it, and handlers only ever see canonical keys.
23
+ * 3. `__tests__/param-aliases.test.ts` binds (1) to (2): every camelCase
24
+ * property advertised by any registry tool must appear in that tool's
25
+ * alias map, and vice versa. Adding one without the other fails there
26
+ * rather than silently advertising a param nothing honours.
27
+ *
28
+ * Normalization runs BEFORE `safeParse`, which is why the alias's declared Zod
29
+ * type never actually validates anything — by parse time the key is gone,
30
+ * rewritten onto its canonical name. It exists purely so the advert is
31
+ * truthful. It still mirrors the canonical validator so a client reading the
32
+ * advert is not misled about what the alias accepts.
33
+ *
34
+ * Deliberately NOT a Zod `.refine()`/`.transform()`: those produce a
35
+ * `ZodEffects`, which has no `.shape`, and both `zodToInputSchema` and
36
+ * `__tests__/schema-contract.test.ts` depend on `.shape` (see the same note in
37
+ * `interview.ts` and `personas.ts`). Cross-field rules live in plain code.
38
+ *
39
+ * ── SCOPE OF THE COMPATIBILITY GUARANTEE ────────────────────────────────────
40
+ * An alias is honoured at `tools/call`, AND an alias-only payload is valid
41
+ * against the advertised schema. `required` no longer excludes alias-only calls.
42
+ *
43
+ * That second half was not free (FUL-238). An alias is a SEPARATE optional
44
+ * property, so it can never satisfy a `required` entry naming the canonical
45
+ * field — the two are different keys. The only way to make the advert accept
46
+ * what the runtime accepts was to drop the canonical id from `required`
47
+ * entirely: the three aliased ids (`create_persona` / `generate_persona`
48
+ * `project_id`, `enrich_persona` `persona_id`) are declared `.optional()` and
49
+ * their presence is enforced in the handler by `requireId` in `personas.ts` —
50
+ * the convention `interview_persona` (per-action ids) and `update_persona`
51
+ * (at-least-one-field) already use. `interview_persona`'s three ids were always
52
+ * this way, so they never had the gap.
53
+ *
54
+ * The trade, taken deliberately: every caller loses the advert's machine-readable
55
+ * "this field is mandatory" signal for those ids, so each one says REQUIRED in
56
+ * its `.describe()` prose and a missing id fails with a clear handler error
57
+ * naming the canonical param — before any HTTP call. In exchange, no client can
58
+ * refuse a legacy caller's payload before sending it.
59
+ *
60
+ * `__tests__/param-aliases.test.ts` pins BOTH halves — the advert no longer
61
+ * listing those ids in `required`, and an alias-only call still reaching the
62
+ * real request — so neither can drift silently.
63
+ */
64
+ import { ToolError } from './errors.js';
65
+ /**
66
+ * Declare a deprecated camelCase alias property for a tool's Zod schema.
67
+ *
68
+ * Pass the canonical field's BASE validator (before `.optional()`): the alias
69
+ * is always optional regardless of whether the canonical field is required, so
70
+ * a caller may supply either one.
71
+ */
72
+ export function deprecatedAlias(canonical, schema) {
73
+ return schema
74
+ .optional()
75
+ .describe(`DEPRECATED alias for \`${canonical}\` — pass \`${canonical}\` instead. ` +
76
+ 'Still accepted for backward compatibility. Passing both this and ' +
77
+ `\`${canonical}\` with DIFFERENT values is rejected.`);
78
+ }
79
+ /** A key counts as supplied when present and not `undefined` (explicit `null` counts). */
80
+ function isSupplied(source, key) {
81
+ return key in source && source[key] !== undefined;
82
+ }
83
+ /**
84
+ * Whether two supplied values are interchangeable. Aliased params are strings
85
+ * and booleans today; the JSON fallback keeps the check correct if one ever
86
+ * becomes structured, and never throws (both values came off a JSON payload).
87
+ */
88
+ function sameValue(a, b) {
89
+ if (Object.is(a, b))
90
+ return true;
91
+ if (typeof a !== typeof b)
92
+ return false;
93
+ if (typeof a !== 'object')
94
+ return false;
95
+ return JSON.stringify(a) === JSON.stringify(b);
96
+ }
97
+ /**
98
+ * Rewrite any supplied camelCase aliases onto their canonical snake_case names.
99
+ *
100
+ * Returns the input untouched (same reference) when no alias is present, so the
101
+ * overwhelmingly common modern call path allocates nothing. Non-object input is
102
+ * passed straight through — the tool's own `safeParse` owns that error message.
103
+ *
104
+ * Supplying BOTH spellings of one field is only an error when the values
105
+ * DIFFER: a caller that sends the same value twice is unambiguous, and failing
106
+ * it would break a belt-and-braces caller for no safety gain. Differing values
107
+ * are genuinely ambiguous, so we refuse rather than pick a winner — silently
108
+ * preferring one would send a persona edit to whichever project the caller
109
+ * did NOT mean.
110
+ *
111
+ * @throws {ToolError} when one field is supplied under both names with
112
+ * different values.
113
+ */
114
+ export function normalizeParamAliases(input, aliases) {
115
+ if (input === null || typeof input !== 'object' || Array.isArray(input))
116
+ return input;
117
+ const source = input;
118
+ const supplied = Object.keys(aliases).filter((alias) => isSupplied(source, alias));
119
+ if (supplied.length === 0)
120
+ return input;
121
+ const out = { ...source };
122
+ for (const alias of supplied) {
123
+ const canonical = aliases[alias];
124
+ const aliasValue = source[alias];
125
+ const canonicalSupplied = isSupplied(source, canonical);
126
+ // A `null` alias alongside a real canonical value is a JSON-shaped "unset",
127
+ // not a competing answer — dropping it is unambiguous, so refusing the call
128
+ // would fail a caller who is not actually contradicting themselves. Left
129
+ // alone when the alias is the ONLY spelling supplied, so the canonical
130
+ // field's own Zod error ("expected string, received null") still surfaces.
131
+ if (aliasValue === null && canonicalSupplied && source[canonical] !== null) {
132
+ delete out[alias];
133
+ continue;
134
+ }
135
+ if (canonicalSupplied && !sameValue(source[canonical], aliasValue)) {
136
+ throw new ToolError(`Invalid input — \`${canonical}\` and its deprecated alias \`${alias}\` were both ` +
137
+ `provided with different values. Pass only \`${canonical}\`.`);
138
+ }
139
+ out[canonical] = aliasValue;
140
+ delete out[alias];
141
+ }
142
+ return out;
143
+ }
144
+ //# sourceMappingURL=param-aliases.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"param-aliases.js","sourceRoot":"","sources":["../../src/tools/param-aliases.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAKvC;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,SAAiB,EACjB,MAAoB;IAEpB,OAAO,MAAM;SACV,QAAQ,EAAE;SACV,QAAQ,CACP,0BAA0B,SAAS,eAAe,SAAS,cAAc;QACvE,mEAAmE;QACnE,KAAK,SAAS,uCAAuC,CACxD,CAAA;AACL,CAAC;AAED,0FAA0F;AAC1F,SAAS,UAAU,CAAC,MAA+B,EAAE,GAAW;IAC9D,OAAO,GAAG,IAAI,MAAM,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,SAAS,CAAA;AACnD,CAAC;AAED;;;;GAIG;AACH,SAAS,SAAS,CAAC,CAAU,EAAE,CAAU;IACvC,IAAI,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QAAE,OAAO,IAAI,CAAA;IAChC,IAAI,OAAO,CAAC,KAAK,OAAO,CAAC;QAAE,OAAO,KAAK,CAAA;IACvC,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IACvC,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;AAChD,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAc,EAAE,OAAiB;IACrE,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IAErF,MAAM,MAAM,GAAG,KAAgC,CAAA;IAC/C,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAA;IAClF,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IAEvC,MAAM,GAAG,GAAG,EAAE,GAAG,MAAM,EAAE,CAAA;IACzB,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAE,CAAA;QACjC,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;QAChC,MAAM,iBAAiB,GAAG,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;QAEvD,4EAA4E;QAC5E,4EAA4E;QAC5E,yEAAyE;QACzE,uEAAuE;QACvE,2EAA2E;QAC3E,IAAI,UAAU,KAAK,IAAI,IAAI,iBAAiB,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE,CAAC;YAC3E,OAAO,GAAG,CAAC,KAAK,CAAC,CAAA;YACjB,SAAQ;QACV,CAAC;QAED,IAAI,iBAAiB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC,EAAE,CAAC;YACnE,MAAM,IAAI,SAAS,CACjB,qBAAqB,SAAS,iCAAiC,KAAK,eAAe;gBACjF,+CAA+C,SAAS,KAAK,CAChE,CAAA;QACH,CAAC;QACD,GAAG,CAAC,SAAS,CAAC,GAAG,UAAU,CAAA;QAC3B,OAAO,GAAG,CAAC,KAAK,CAAC,CAAA;IACnB,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC"}