@proletariat/cli 0.3.109 → 0.3.110

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,308 @@
1
+ /**
2
+ * walkPromptChain — drive prlt CLI commands non-interactively by walking JSON prompts.
3
+ *
4
+ * Background (PRLT-1268):
5
+ * Action handlers used to hardcode flag combinations like
6
+ * `prlt work start <ticket> --yes --display background`
7
+ * which broke as soon as a command emitted a JSON prompt that wasn't covered
8
+ * by those flags (e.g. environment selection). `--yes` does not bypass JSON
9
+ * prompts.
10
+ *
11
+ * The right approach is to walk the JSON prompt chain. Every prlt command in
12
+ * JSON mode emits one of:
13
+ * - { type: 'prompt', prompt: { name, choices: [{ value, command, ... }, ...] } }
14
+ * - { type: 'success', ... }
15
+ * - { type: 'execution_result', ... }
16
+ * - { type: 'error', ... }
17
+ *
18
+ * For prompt responses, each choice already carries a fully constructed
19
+ * follow-up `command` field. The walker:
20
+ * 1. Runs the current command with --json
21
+ * 2. If response is type=prompt, picks a default choice by name from the
22
+ * defaults map, then runs choice.command
23
+ * 3. Repeats until success/error/iteration cap
24
+ *
25
+ * Per-action default choices live in the action handler and may be overridden
26
+ * by hook config so users can customize behavior without code changes.
27
+ */
28
+ import { spawnSync } from 'node:child_process';
29
+ /**
30
+ * Default executor — runs the command via spawnSync with a shell.
31
+ */
32
+ export const defaultChainExecutor = (command, timeoutMs) => {
33
+ const result = spawnSync(command, {
34
+ shell: true,
35
+ encoding: 'utf8',
36
+ timeout: timeoutMs,
37
+ // Capture both pipes; prompts emit JSON to stdout even at exit code 2
38
+ stdio: ['ignore', 'pipe', 'pipe'],
39
+ });
40
+ return {
41
+ stdout: result.stdout || '',
42
+ stderr: result.stderr || '',
43
+ status: result.status ?? -1,
44
+ error: result.error ? result.error.message : undefined,
45
+ };
46
+ };
47
+ /**
48
+ * Ensure the command has --json appended (avoid duplicates).
49
+ */
50
+ function ensureJsonFlag(command) {
51
+ // Match --json as a whole token (avoid matching --jsonish)
52
+ if (/(^|\s)--json(\s|$)/.test(command)) {
53
+ return command;
54
+ }
55
+ return `${command} --json`;
56
+ }
57
+ /**
58
+ * Try to parse a JSON envelope out of stdout. Some commands print log lines
59
+ * before the JSON; we look for the largest balanced JSON object.
60
+ */
61
+ function parseJsonEnvelope(stdout) {
62
+ const trimmed = stdout.trim();
63
+ if (!trimmed)
64
+ return null;
65
+ // Fast path: stdout is pure JSON
66
+ try {
67
+ return JSON.parse(trimmed);
68
+ }
69
+ catch {
70
+ // fall through to slow path
71
+ }
72
+ // Slow path: find the last JSON object in stdout. JSON envelopes are
73
+ // pretty-printed with newlines, so look for the last line starting with '}'
74
+ // and walk backwards to a matching '{' at the start of a line.
75
+ const firstBrace = trimmed.indexOf('{');
76
+ const lastBrace = trimmed.lastIndexOf('}');
77
+ if (firstBrace < 0 || lastBrace <= firstBrace)
78
+ return null;
79
+ try {
80
+ return JSON.parse(trimmed.slice(firstBrace, lastBrace + 1));
81
+ }
82
+ catch {
83
+ return null;
84
+ }
85
+ }
86
+ /**
87
+ * Walk a JSON prompt chain to completion.
88
+ *
89
+ * Each iteration runs the current command, parses its JSON envelope, and:
90
+ * - On terminal success/execution_result, returns success.
91
+ * - On error, returns failure with the error code/message.
92
+ * - On prompt, picks the default for that prompt's name and runs the
93
+ * corresponding choice's `command`.
94
+ *
95
+ * If a prompt's name has no entry in `defaults`, the walk fails — this is a
96
+ * configuration bug, not something to silently swallow.
97
+ */
98
+ export function walkPromptChain(opts) {
99
+ const { baseCommand, defaults, timeoutMs = 180_000, maxIterations = 12, executor = defaultChainExecutor, } = opts;
100
+ let currentCommand = ensureJsonFlag(baseCommand);
101
+ const commandTrail = [];
102
+ for (let i = 1; i <= maxIterations; i++) {
103
+ commandTrail.push(currentCommand);
104
+ const exec = executor(currentCommand, timeoutMs);
105
+ // Spawn-level failure (timeout, command not found, etc.)
106
+ if (exec.error && !exec.stdout) {
107
+ return {
108
+ success: false,
109
+ iterations: i,
110
+ finalCommand: currentCommand,
111
+ commandTrail,
112
+ error: `Failed to run \`${currentCommand}\`: ${exec.error}`,
113
+ };
114
+ }
115
+ const parsed = parseJsonEnvelope(exec.stdout);
116
+ if (!parsed) {
117
+ return {
118
+ success: false,
119
+ iterations: i,
120
+ finalCommand: currentCommand,
121
+ commandTrail,
122
+ error: `\`${currentCommand}\` did not emit a JSON envelope ` +
123
+ `(exit ${exec.status}).` +
124
+ (exec.stderr ? ` stderr: ${exec.stderr.trim().slice(0, 500)}` : ''),
125
+ };
126
+ }
127
+ if (parsed.type === 'success' || parsed.type === 'execution_result') {
128
+ return {
129
+ success: true,
130
+ iterations: i,
131
+ finalCommand: currentCommand,
132
+ commandTrail,
133
+ result: parsed.result,
134
+ };
135
+ }
136
+ if (parsed.type === 'error') {
137
+ const code = parsed.error?.code || 'ERROR';
138
+ const message = parsed.error?.message || 'unknown error';
139
+ return {
140
+ success: false,
141
+ iterations: i,
142
+ finalCommand: currentCommand,
143
+ commandTrail,
144
+ error: `${code}: ${message}`,
145
+ };
146
+ }
147
+ if (parsed.type === 'confirmation_needed') {
148
+ // confirmation_needed is structurally different from a prompt — it
149
+ // contains a single `confirm_command` to re-run. We don't try to be
150
+ // clever; treat it as an explicit step the operator must wire up.
151
+ return {
152
+ success: false,
153
+ iterations: i,
154
+ finalCommand: currentCommand,
155
+ commandTrail,
156
+ error: `\`${currentCommand}\` returned confirmation_needed; action handler must opt into confirmation flow`,
157
+ };
158
+ }
159
+ if (parsed.type !== 'prompt') {
160
+ return {
161
+ success: false,
162
+ iterations: i,
163
+ finalCommand: currentCommand,
164
+ commandTrail,
165
+ error: `Unsupported envelope type "${parsed.type}" from \`${currentCommand}\``,
166
+ };
167
+ }
168
+ // type === 'prompt' — pick a default and chain
169
+ const promptBody = parsed.prompt;
170
+ if (!promptBody) {
171
+ return {
172
+ success: false,
173
+ iterations: i,
174
+ finalCommand: currentCommand,
175
+ commandTrail,
176
+ error: `\`${currentCommand}\` returned prompt envelope with empty body`,
177
+ };
178
+ }
179
+ const promptName = promptBody.name;
180
+ if (!promptName) {
181
+ return {
182
+ success: false,
183
+ iterations: i,
184
+ finalCommand: currentCommand,
185
+ commandTrail,
186
+ error: `\`${currentCommand}\` returned prompt with no name; cannot map to defaults`,
187
+ };
188
+ }
189
+ const defaultValue = defaults[promptName];
190
+ if (defaultValue === undefined) {
191
+ const available = Object.keys(defaults).join(', ') || '(none)';
192
+ return {
193
+ success: false,
194
+ iterations: i,
195
+ finalCommand: currentCommand,
196
+ commandTrail,
197
+ error: `No default configured for prompt "${promptName}" ` +
198
+ `(have defaults for: ${available}). ` +
199
+ `Add it via the hook's args.defaults config.`,
200
+ };
201
+ }
202
+ const choices = promptBody.choices || [];
203
+ const chosen = choices.find((c) => c.value === defaultValue);
204
+ if (!chosen) {
205
+ const offered = choices.map((c) => c.value).join(', ') || '(none)';
206
+ return {
207
+ success: false,
208
+ iterations: i,
209
+ finalCommand: currentCommand,
210
+ commandTrail,
211
+ error: `Prompt "${promptName}" has no choice with value "${defaultValue}". ` +
212
+ `Available: ${offered}`,
213
+ };
214
+ }
215
+ if (!chosen.command) {
216
+ return {
217
+ success: false,
218
+ iterations: i,
219
+ finalCommand: currentCommand,
220
+ commandTrail,
221
+ error: `Choice "${defaultValue}" for prompt "${promptName}" has no \`command\` field; ` +
222
+ `cannot continue chain. The command emitting this prompt must populate choice.command.`,
223
+ };
224
+ }
225
+ currentCommand = ensureJsonFlag(chosen.command);
226
+ }
227
+ return {
228
+ success: false,
229
+ iterations: maxIterations,
230
+ finalCommand: currentCommand,
231
+ commandTrail,
232
+ error: `Exceeded max iterations (${maxIterations}) walking prompt chain`,
233
+ };
234
+ }
235
+ /**
236
+ * Built-in default choice maps per action. Hook config can shallow-merge
237
+ * over these to override individual prompt defaults.
238
+ *
239
+ * Keys are prompt names (FlagResolver flagName). Values are the choice value
240
+ * to pick. See `apps/cli/src/commands/work/start.ts` for the prompts a
241
+ * `prlt work start` chain may emit.
242
+ */
243
+ export const DEFAULT_PROMPT_CHOICES = {
244
+ 'spawn-agent': {
245
+ environment: 'devcontainer',
246
+ display: 'background',
247
+ selectedDisplay: 'background',
248
+ 'permission-mode': 'danger',
249
+ tokenAction: 'continue',
250
+ dockerAction: 'host',
251
+ prChoice: 'create',
252
+ saveDefault: 'true',
253
+ authAction: 'oauth',
254
+ },
255
+ 'spawn-review-agent': {
256
+ // Review agents are read-only and faster on host
257
+ environment: 'host',
258
+ display: 'background',
259
+ selectedDisplay: 'background',
260
+ 'permission-mode': 'safe',
261
+ prChoice: 'no-pr',
262
+ saveDefault: 'true',
263
+ },
264
+ 'spawn-fix-agent': {
265
+ environment: 'devcontainer',
266
+ display: 'background',
267
+ selectedDisplay: 'background',
268
+ 'permission-mode': 'danger',
269
+ tokenAction: 'continue',
270
+ dockerAction: 'host',
271
+ prChoice: 'create',
272
+ saveDefault: 'true',
273
+ authAction: 'oauth',
274
+ },
275
+ 'resolve-conflict': {
276
+ environment: 'devcontainer',
277
+ display: 'background',
278
+ selectedDisplay: 'background',
279
+ 'permission-mode': 'danger',
280
+ tokenAction: 'continue',
281
+ dockerAction: 'host',
282
+ prChoice: 'create',
283
+ saveDefault: 'true',
284
+ authAction: 'oauth',
285
+ },
286
+ 'merge-pr': {
287
+ method: 'squash',
288
+ 'delete-branch': 'true',
289
+ },
290
+ 'move-ticket': {
291
+ target: 'done',
292
+ },
293
+ };
294
+ /**
295
+ * Resolve effective defaults for an action by overlaying hook config on top
296
+ * of the built-in defaults. Hook config shape:
297
+ *
298
+ * { defaults: { promptName: 'value', ... } }
299
+ *
300
+ * Unknown keys in hook config are passed through verbatim — there is no
301
+ * allow-list because new prlt prompts get added all the time.
302
+ */
303
+ export function resolveActionDefaults(action, config) {
304
+ const builtIn = DEFAULT_PROMPT_CHOICES[action];
305
+ const overrides = config?.defaults || {};
306
+ return { ...builtIn, ...overrides };
307
+ }
308
+ //# sourceMappingURL=prompt-chain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-chain.js","sourceRoot":"","sources":["../../../src/lib/orchestrate/prompt-chain.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { Command } from '@oclif/core';
2
- import { type JsonFlags } from './prompt-json.js';
2
+ import { type FlagSchemaEntry, type JsonFlags } from './prompt-json.js';
3
3
  /**
4
4
  * Lightweight base command with prompt() method for JSON mode support.
5
5
  *
@@ -110,4 +110,64 @@ export declare abstract class PromptCommand extends Command {
110
110
  flags: JsonFlags & Record<string, unknown>;
111
111
  commandName: string;
112
112
  } | null): Promise<T>;
113
+ /**
114
+ * oclif catch hook — validation-first JSON error layer.
115
+ *
116
+ * Intercepts oclif parse errors (missing required flag/arg, invalid choice,
117
+ * nonexistent flag) and reformats them as a structured validation_error
118
+ * envelope when the command is running in machine/agent mode. This makes
119
+ * every command agent-friendly automatically, with no per-command code.
120
+ *
121
+ * In interactive mode, falls through to the default oclif catch behavior
122
+ * (re-throws the error so the user sees the human-readable message).
123
+ *
124
+ * Subclasses that override catch() should call `await super.catch(err)`.
125
+ */
126
+ protected catch(err: Error & {
127
+ exitCode?: number;
128
+ }): Promise<void>;
129
+ /**
130
+ * Heuristic detector for oclif parse errors.
131
+ *
132
+ * oclif's parser throws subclasses of `CLIParseError` (RequiredArgsError,
133
+ * FailedFlagValidationError, FlagInvalidOptionError, NonExistentFlagsError,
134
+ * UnexpectedArgsError, ArgInvalidOptionError, InvalidArgsSpecError). They
135
+ * are not exported from the public oclif module surface, so we identify
136
+ * them by constructor name plus the presence of the `parse` property that
137
+ * `CLIParseError` adds (the parse context is unique to parse errors).
138
+ */
139
+ protected isOclifParseError(err: unknown): boolean;
140
+ /**
141
+ * Extract a structured (reason, missing[]) tuple from an oclif parse error.
142
+ *
143
+ * - RequiredArgsError → reason="missing_required_args", missing=[arg names]
144
+ * - FailedFlagValidationError → reason="missing_required_flags", missing=[flag names]
145
+ * - FlagInvalidOptionError → reason="invalid_flag_value", missing=[flag name]
146
+ * - ArgInvalidOptionError → reason="invalid_arg_value", missing=[arg name]
147
+ * - NonExistentFlagsError → reason="nonexistent_flags", missing=[flag names]
148
+ * - UnexpectedArgsError → reason="unexpected_args", missing=[]
149
+ *
150
+ * Falls back to parsing the error message when the typed args aren't
151
+ * available (e.g., raw CLIParseError).
152
+ */
153
+ protected classifyParseError(err: Error): {
154
+ reason: string;
155
+ missing: string[];
156
+ };
157
+ /**
158
+ * Build the schema dictionary from this command's static `flags` and
159
+ * `args` definitions, optionally restricted to a subset of names.
160
+ *
161
+ * Combines `flags` and `baseFlags` so flags inherited from a base class
162
+ * (e.g. `pmoBaseFlags`) are still introspectable.
163
+ */
164
+ protected buildSchemaForCommand(restrictTo?: string[]): Record<string, FlagSchemaEntry>;
165
+ /**
166
+ * Emit a validation_error JSON envelope and exit.
167
+ *
168
+ * This is the terminal step of the validation-first error layer.
169
+ * It uses the catch handler context to derive command name, missing
170
+ * flags, and the schema, then writes a structured envelope.
171
+ */
172
+ protected emitValidationErrorJson(err: Error): never;
113
173
  }
@@ -1,6 +1,6 @@
1
1
  import { Command } from '@oclif/core';
2
2
  import inquirer from 'inquirer';
3
- import { isAgentMode, isNonTTY, outputPromptAsJson, createMetadata, normalizeChoices, } from './prompt-json.js';
3
+ import { buildArgSchemaEntry, buildFlagSchemaFromOclif, createMetadata, isAgentMode, isMachineModeFromArgv, isNonTTY, outputPromptAsJson, outputValidationErrorAsJson, normalizeChoices, } from './prompt-json.js';
4
4
  import { isPlainOutput, plainText } from './styles.js';
5
5
  import { withSignalSafePrompt } from './signal-handler.js';
6
6
  /**
@@ -136,5 +136,171 @@ export class PromptCommand extends Command {
136
136
  // Interactive mode: call inquirer with signal-safe wrapper
137
137
  return withSignalSafePrompt(() => inquirer.prompt(questions));
138
138
  }
139
+ // ──────────────────────────────────────────────────────────────────────
140
+ // Validation-first JSON error layer (PRLT-1269)
141
+ // ──────────────────────────────────────────────────────────────────────
142
+ /**
143
+ * oclif catch hook — validation-first JSON error layer.
144
+ *
145
+ * Intercepts oclif parse errors (missing required flag/arg, invalid choice,
146
+ * nonexistent flag) and reformats them as a structured validation_error
147
+ * envelope when the command is running in machine/agent mode. This makes
148
+ * every command agent-friendly automatically, with no per-command code.
149
+ *
150
+ * In interactive mode, falls through to the default oclif catch behavior
151
+ * (re-throws the error so the user sees the human-readable message).
152
+ *
153
+ * Subclasses that override catch() should call `await super.catch(err)`.
154
+ */
155
+ async catch(err) {
156
+ if (this.isOclifParseError(err) && isMachineModeFromArgv(this.argv)) {
157
+ this.emitValidationErrorJson(err);
158
+ }
159
+ return super.catch(err);
160
+ }
161
+ /**
162
+ * Heuristic detector for oclif parse errors.
163
+ *
164
+ * oclif's parser throws subclasses of `CLIParseError` (RequiredArgsError,
165
+ * FailedFlagValidationError, FlagInvalidOptionError, NonExistentFlagsError,
166
+ * UnexpectedArgsError, ArgInvalidOptionError, InvalidArgsSpecError). They
167
+ * are not exported from the public oclif module surface, so we identify
168
+ * them by constructor name plus the presence of the `parse` property that
169
+ * `CLIParseError` adds (the parse context is unique to parse errors).
170
+ */
171
+ isOclifParseError(err) {
172
+ if (!err || typeof err !== 'object')
173
+ return false;
174
+ const name = err.constructor?.name ?? '';
175
+ const PARSE_ERROR_NAMES = new Set([
176
+ 'CLIParseError',
177
+ 'RequiredArgsError',
178
+ 'FailedFlagValidationError',
179
+ 'FlagInvalidOptionError',
180
+ 'NonExistentFlagsError',
181
+ 'UnexpectedArgsError',
182
+ 'ArgInvalidOptionError',
183
+ 'InvalidArgsSpecError',
184
+ ]);
185
+ if (PARSE_ERROR_NAMES.has(name))
186
+ return true;
187
+ // Defensive: any error with a `.parse` context object that has input.flags
188
+ // is almost certainly a CLIParseError subclass.
189
+ const parse = err.parse;
190
+ return Boolean(parse && typeof parse === 'object' && parse.input && 'flags' in parse.input);
191
+ }
192
+ /**
193
+ * Extract a structured (reason, missing[]) tuple from an oclif parse error.
194
+ *
195
+ * - RequiredArgsError → reason="missing_required_args", missing=[arg names]
196
+ * - FailedFlagValidationError → reason="missing_required_flags", missing=[flag names]
197
+ * - FlagInvalidOptionError → reason="invalid_flag_value", missing=[flag name]
198
+ * - ArgInvalidOptionError → reason="invalid_arg_value", missing=[arg name]
199
+ * - NonExistentFlagsError → reason="nonexistent_flags", missing=[flag names]
200
+ * - UnexpectedArgsError → reason="unexpected_args", missing=[]
201
+ *
202
+ * Falls back to parsing the error message when the typed args aren't
203
+ * available (e.g., raw CLIParseError).
204
+ */
205
+ classifyParseError(err) {
206
+ const name = err.constructor?.name ?? '';
207
+ const anyErr = err;
208
+ if (name === 'RequiredArgsError') {
209
+ const missing = (anyErr.args ?? [])
210
+ .map((a) => a?.name)
211
+ .filter((n) => typeof n === 'string' && n.length > 0);
212
+ return { reason: 'missing_required_args', missing };
213
+ }
214
+ if (name === 'NonExistentFlagsError') {
215
+ return { reason: 'nonexistent_flags', missing: anyErr.flags ?? [] };
216
+ }
217
+ if (name === 'UnexpectedArgsError') {
218
+ return { reason: 'unexpected_args', missing: [] };
219
+ }
220
+ if (name === 'FailedFlagValidationError') {
221
+ // The failed validations are not stored on the error object, so derive
222
+ // missing flag names from the message: `Missing required flag <name>`.
223
+ const missing = [];
224
+ const msg = anyErr.message ?? '';
225
+ const re = /Missing required flag\s+(\S+)/g;
226
+ let match;
227
+ while ((match = re.exec(msg)) !== null) {
228
+ missing.push(match[1]);
229
+ }
230
+ return { reason: 'missing_required_flags', missing };
231
+ }
232
+ if (name === 'FlagInvalidOptionError') {
233
+ // Message format: `Expected --<flag>=<value> to be one of: ...`
234
+ const msg = anyErr.message ?? '';
235
+ const match = /Expected --(\S+?)=/.exec(msg);
236
+ return {
237
+ reason: 'invalid_flag_value',
238
+ missing: match ? [match[1]] : [],
239
+ };
240
+ }
241
+ if (name === 'ArgInvalidOptionError') {
242
+ return { reason: 'invalid_arg_value', missing: [] };
243
+ }
244
+ return { reason: 'parse_error', missing: [] };
245
+ }
246
+ /**
247
+ * Build the schema dictionary from this command's static `flags` and
248
+ * `args` definitions, optionally restricted to a subset of names.
249
+ *
250
+ * Combines `flags` and `baseFlags` so flags inherited from a base class
251
+ * (e.g. `pmoBaseFlags`) are still introspectable.
252
+ */
253
+ buildSchemaForCommand(restrictTo) {
254
+ const ctor = this.ctor;
255
+ const allFlags = {
256
+ ...(ctor.baseFlags ?? {}),
257
+ ...(ctor.flags ?? {}),
258
+ };
259
+ const schema = buildFlagSchemaFromOclif(allFlags);
260
+ // Add arg entries (args are keyed by name, treated like input prompts).
261
+ const args = ctor.args ?? {};
262
+ for (const [name, arg] of Object.entries(args)) {
263
+ if (!arg)
264
+ continue;
265
+ schema[name] = buildArgSchemaEntry(arg);
266
+ }
267
+ if (!restrictTo || restrictTo.length === 0) {
268
+ return schema;
269
+ }
270
+ // Restrict to requested names, but always include any arg/flag that exists
271
+ // in the full definition. Unknown names get a placeholder so agents at least
272
+ // see them listed.
273
+ const restricted = {};
274
+ for (const name of restrictTo) {
275
+ if (schema[name]) {
276
+ restricted[name] = schema[name];
277
+ }
278
+ else {
279
+ restricted[name] = { type: 'input' };
280
+ }
281
+ }
282
+ return restricted;
283
+ }
284
+ /**
285
+ * Emit a validation_error JSON envelope and exit.
286
+ *
287
+ * This is the terminal step of the validation-first error layer.
288
+ * It uses the catch handler context to derive command name, missing
289
+ * flags, and the schema, then writes a structured envelope.
290
+ */
291
+ emitValidationErrorJson(err) {
292
+ const { reason, missing } = this.classifyParseError(err);
293
+ const commandName = (this.id ?? 'unknown').replace(/:/g, ' ');
294
+ // Restrict the schema to only the relevant flags/args when we have a list,
295
+ // otherwise emit the full schema so agents see the complete contract.
296
+ const schema = this.buildSchemaForCommand(missing.length > 0 ? missing : undefined);
297
+ outputValidationErrorAsJson({
298
+ command: commandName,
299
+ reason,
300
+ message: err.message ?? 'Validation failed',
301
+ missing,
302
+ schema,
303
+ }, createMetadata(commandName, { json: true }));
304
+ }
139
305
  }
140
306
  //# sourceMappingURL=prompt-command.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompt-command.js","sourceRoot":"","sources":["../../src/lib/prompt-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,EACL,WAAW,EACX,QAAQ,EACR,kBAAkB,EAClB,cAAc,EACd,gBAAgB,GAEjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,OAAgB,aAAc,SAAQ,OAAO;IACjD;;;;;;;;OAQG;IACO,QAAQ,CAAC,OAAgB,EAAE,GAAG,IAAc;QACpD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,IAAI,CAAC,GAAG,EAAE,CAAC;YACX,OAAO;QACT,CAAC;QACD,IAAI,aAAa,EAAE,EAAE,CAAC;YACpB,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;QACxC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,IAAc,OAAO;QACnB,OAAO,aAAa,EAAE,CAAC;IACzB,CAAC;IAED;;;OAGG;IACH,IAAc,QAAQ;QACpB,OAAO,QAAQ,EAAE,CAAC;IACpB,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAuCG;IACO,KAAK,CAAC,MAAM,CACpB,SAeE,EACF,cAGQ;QAER,+DAA+D;QAC/D,IAAI,CAAC,cAAc,IAAI,QAAQ,EAAE,EAAE,CAAC;YAClC,cAAc,GAAG,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,IAAI,SAAS,EAAE,CAAC;QAChF,CAAC;QAED,4BAA4B;QAC5B,IAAI,cAAc,IAAI,WAAW,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YACxD,0EAA0E;YAC1E,MAAM,aAAa,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YACnC,IAAI,aAAa,EAAE,CAAC;gBAClB,6CAA6C;gBAC7C,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO;oBACnC,CAAC,CAAC,gBAAgB,CAAC,aAAa,CAAC,OAAO,CAAC;oBACzC,CAAC,CAAC,SAAS,CAAC;gBAEd,kBAAkB,CAChB;oBACE,IAAI,EAAE,aAAa,CAAC,IAA4D;oBAChF,IAAI,EAAE,aAAa,CAAC,IAAI;oBACxB,OAAO,EAAE,aAAa,CAAC,OAAO;oBAC9B,OAAO;oBACP,OAAO,EAAE,aAAa,CAAC,OAAkD;iBAC1E,EACD,cAAc,CAAC,cAAc,CAAC,WAAW,EAAE,cAAc,CAAC,KAAK,CAAC,CACjE,CAAC;gBACF,OAAO,EAAO,CAAA;YAChB,CAAC;YACD,OAAO,EAAO,CAAC;QACjB,CAAC;QAED,2DAA2D;QAC3D,OAAO,oBAAoB,CAAC,GAAG,EAAE,CAC/B,QAAQ,CAAC,MAAM,CAAC,SAAkD,CAAe,CAClF,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"prompt-command.js","sourceRoot":"","sources":["../../src/lib/prompt-command.ts"],"names":[],"mappings":"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"}