@orchagent/cli 0.3.91 → 0.3.93

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,300 @@
1
+ "use strict";
2
+ /**
3
+ * Formatting and colorized output for `orch diff`.
4
+ *
5
+ * Git-style red/green coloring: removed lines are red, added lines are green,
6
+ * changed fields show old in red and new in green. Structured fields
7
+ * (arrays, dependencies, custom_tools, schemas, models) get item-level diffs.
8
+ */
9
+ var __importDefault = (this && this.__importDefault) || function (mod) {
10
+ return (mod && mod.__esModule) ? mod : { "default": mod };
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.formatValuePlain = formatValuePlain;
14
+ exports.formatPromptDiff = formatPromptDiff;
15
+ exports.formatSchemaDiff = formatSchemaDiff;
16
+ exports.formatStringArrayDiff = formatStringArrayDiff;
17
+ exports.formatDependencyDiff = formatDependencyDiff;
18
+ exports.formatCustomToolDiff = formatCustomToolDiff;
19
+ exports.formatModelsDiff = formatModelsDiff;
20
+ exports.printDiffs = printDiffs;
21
+ const chalk_1 = __importDefault(require("chalk"));
22
+ // ── Plain value formatting ────────────────────────────────────
23
+ /** Format a value as plain text (no ANSI colors). */
24
+ function formatValuePlain(val) {
25
+ if (val === undefined || val === null)
26
+ return '(none)';
27
+ if (typeof val === 'boolean')
28
+ return String(val);
29
+ if (typeof val === 'string') {
30
+ if (val.length > 120)
31
+ return val.slice(0, 117) + '...';
32
+ return val;
33
+ }
34
+ if (Array.isArray(val)) {
35
+ if (val.length === 0)
36
+ return '[]';
37
+ if (typeof val[0] === 'string')
38
+ return val.join(', ');
39
+ return JSON.stringify(val, null, 2);
40
+ }
41
+ if (typeof val === 'object')
42
+ return JSON.stringify(val, null, 2);
43
+ return String(val);
44
+ }
45
+ /** Apply a chalk color function to every line of a string. */
46
+ function colorLines(text, colorFn) {
47
+ return text.split('\n').map(colorFn).join('\n');
48
+ }
49
+ // ── Prompt diff ───────────────────────────────────────────────
50
+ function formatPromptDiff(oldPrompt, newPrompt) {
51
+ const oldLines = (oldPrompt || '').split('\n');
52
+ const newLines = (newPrompt || '').split('\n');
53
+ const lines = [];
54
+ const oldSet = new Set(oldLines);
55
+ const newSet = new Set(newLines);
56
+ for (const line of oldLines) {
57
+ if (!newSet.has(line)) {
58
+ lines.push(chalk_1.default.red(` - ${line}`));
59
+ }
60
+ }
61
+ for (const line of newLines) {
62
+ if (!oldSet.has(line)) {
63
+ lines.push(chalk_1.default.green(` + ${line}`));
64
+ }
65
+ }
66
+ if (lines.length === 0) {
67
+ lines.push(chalk_1.default.yellow(' (line order changed)'));
68
+ }
69
+ if (lines.length > 40) {
70
+ const shown = lines.slice(0, 40);
71
+ shown.push(chalk_1.default.dim(` ... and ${lines.length - 40} more lines`));
72
+ return shown.join('\n');
73
+ }
74
+ return lines.join('\n');
75
+ }
76
+ // ── Schema diff ───────────────────────────────────────────────
77
+ function formatSchemaDiff(_field, oldSchema, newSchema) {
78
+ const lines = [];
79
+ const oldProps = oldSchema?.properties || {};
80
+ const newProps = newSchema?.properties || {};
81
+ const oldRequired = new Set(oldSchema?.required || []);
82
+ const newRequired = new Set(newSchema?.required || []);
83
+ const allKeys = new Set([...Object.keys(oldProps), ...Object.keys(newProps)]);
84
+ for (const key of allKeys) {
85
+ const inOld = key in oldProps;
86
+ const inNew = key in newProps;
87
+ if (!inOld && inNew) {
88
+ const reqMark = newRequired.has(key) ? '' : '?';
89
+ lines.push(chalk_1.default.green(` + ${key}${reqMark}: ${newProps[key].type || 'any'}`));
90
+ }
91
+ else if (inOld && !inNew) {
92
+ const reqMark = oldRequired.has(key) ? '' : '?';
93
+ lines.push(chalk_1.default.red(` - ${key}${reqMark}: ${oldProps[key].type || 'any'}`));
94
+ }
95
+ else if (inOld && inNew) {
96
+ const oldType = oldProps[key].type || 'any';
97
+ const newType = newProps[key].type || 'any';
98
+ const wasReq = oldRequired.has(key);
99
+ const isReq = newRequired.has(key);
100
+ if (oldType !== newType || wasReq !== isReq) {
101
+ const oldMark = wasReq ? '' : '?';
102
+ const newMark = isReq ? '' : '?';
103
+ lines.push(chalk_1.default.red(` - ${key}${oldMark}: ${oldType}`));
104
+ lines.push(chalk_1.default.green(` + ${key}${newMark}: ${newType}`));
105
+ }
106
+ }
107
+ }
108
+ return lines.join('\n');
109
+ }
110
+ // ── String array diff ─────────────────────────────────────────
111
+ /** Item-level diff for simple string arrays (tags, providers, secrets, skills). */
112
+ function formatStringArrayDiff(oldArr, newArr) {
113
+ const oldSet = new Set(oldArr);
114
+ const newSet = new Set(newArr);
115
+ const lines = [];
116
+ for (const item of oldArr) {
117
+ if (!newSet.has(item)) {
118
+ lines.push(chalk_1.default.red(` - ${item}`));
119
+ }
120
+ }
121
+ for (const item of newArr) {
122
+ if (!oldSet.has(item)) {
123
+ lines.push(chalk_1.default.green(` + ${item}`));
124
+ }
125
+ }
126
+ // Show items present in both (unchanged) for context
127
+ for (const item of newArr) {
128
+ if (oldSet.has(item)) {
129
+ lines.push(chalk_1.default.dim(` ${item}`));
130
+ }
131
+ }
132
+ return lines.join('\n');
133
+ }
134
+ // ── Dependency diff ───────────────────────────────────────────
135
+ /** Item-level diff for ManifestDependency arrays. Shows version changes. */
136
+ function formatDependencyDiff(oldDeps, newDeps) {
137
+ const oldMap = new Map(oldDeps.map(d => [d.id, d.version]));
138
+ const newMap = new Map(newDeps.map(d => [d.id, d.version]));
139
+ const allIds = new Set([...oldMap.keys(), ...newMap.keys()]);
140
+ const lines = [];
141
+ for (const id of allIds) {
142
+ const oldV = oldMap.get(id);
143
+ const newV = newMap.get(id);
144
+ if (oldV && !newV) {
145
+ lines.push(chalk_1.default.red(` - ${id}@${oldV}`));
146
+ }
147
+ else if (!oldV && newV) {
148
+ lines.push(chalk_1.default.green(` + ${id}@${newV}`));
149
+ }
150
+ else if (oldV && newV && oldV !== newV) {
151
+ lines.push(` ${id}: ${chalk_1.default.red(oldV)} ${chalk_1.default.yellow('\u2192')} ${chalk_1.default.green(newV)}`);
152
+ }
153
+ else {
154
+ lines.push(chalk_1.default.dim(` ${id}@${oldV}`));
155
+ }
156
+ }
157
+ return lines.join('\n');
158
+ }
159
+ // ── Custom tool diff ──────────────────────────────────────────
160
+ /** Item-level diff for CustomTool arrays. */
161
+ function formatCustomToolDiff(oldTools, newTools) {
162
+ const oldMap = new Map(oldTools.map(t => [t.name, t]));
163
+ const newMap = new Map(newTools.map(t => [t.name, t]));
164
+ const allNames = new Set([...oldMap.keys(), ...newMap.keys()]);
165
+ const lines = [];
166
+ for (const name of allNames) {
167
+ const oldT = oldMap.get(name);
168
+ const newT = newMap.get(name);
169
+ if (oldT && !newT) {
170
+ lines.push(chalk_1.default.red(` - ${name}`));
171
+ }
172
+ else if (!oldT && newT) {
173
+ lines.push(chalk_1.default.green(` + ${name}`));
174
+ if (newT.description)
175
+ lines.push(chalk_1.default.green(` ${newT.description}`));
176
+ }
177
+ else if (oldT && newT && JSON.stringify(oldT) !== JSON.stringify(newT)) {
178
+ lines.push(` ~ ${chalk_1.default.bold(name)}`);
179
+ if (oldT.description !== newT.description) {
180
+ lines.push(` desc: ${chalk_1.default.red(oldT.description || '(none)')} ${chalk_1.default.yellow('\u2192')} ${chalk_1.default.green(newT.description || '(none)')}`);
181
+ }
182
+ if (oldT.command !== newT.command) {
183
+ lines.push(` cmd: ${chalk_1.default.red(oldT.command || '(none)')} ${chalk_1.default.yellow('\u2192')} ${chalk_1.default.green(newT.command || '(none)')}`);
184
+ }
185
+ }
186
+ else {
187
+ lines.push(chalk_1.default.dim(` ${name}`));
188
+ }
189
+ }
190
+ return lines.join('\n');
191
+ }
192
+ // ── Models (key-value object) diff ────────────────────────────
193
+ /** Key-level diff for Record<string, string> objects like default_models. */
194
+ function formatModelsDiff(oldObj, newObj) {
195
+ const old = oldObj || {};
196
+ const nw = newObj || {};
197
+ const allKeys = new Set([...Object.keys(old), ...Object.keys(nw)]);
198
+ const lines = [];
199
+ for (const key of allKeys) {
200
+ if (key in old && !(key in nw)) {
201
+ lines.push(chalk_1.default.red(` - ${key}: ${old[key]}`));
202
+ }
203
+ else if (!(key in old) && key in nw) {
204
+ lines.push(chalk_1.default.green(` + ${key}: ${nw[key]}`));
205
+ }
206
+ else if (old[key] !== nw[key]) {
207
+ lines.push(` ${key}: ${chalk_1.default.red(old[key])} ${chalk_1.default.yellow('\u2192')} ${chalk_1.default.green(nw[key])}`);
208
+ }
209
+ }
210
+ return lines.join('\n');
211
+ }
212
+ // ── Main printer ──────────────────────────────────────────────
213
+ /** Render a colorized diff to stdout. */
214
+ function printDiffs(refA, refB, diffs) {
215
+ process.stdout.write('\n');
216
+ process.stdout.write(chalk_1.default.bold(`${refA} ${chalk_1.default.yellow('\u2192')} ${refB}`) + '\n');
217
+ process.stdout.write(chalk_1.default.dim('\u2500'.repeat(50)) + '\n\n');
218
+ if (diffs.length === 0) {
219
+ process.stdout.write(chalk_1.default.green('No differences found.') + '\n');
220
+ return;
221
+ }
222
+ process.stdout.write(`${chalk_1.default.bold(String(diffs.length))} ${diffs.length === 1 ? 'change' : 'changes'}:\n\n`);
223
+ // Fields that get item-level diff when changed
224
+ const stringArrayFields = new Set([
225
+ 'supported_providers', 'tags', 'default_skills', 'required_secrets',
226
+ ]);
227
+ for (const diff of diffs) {
228
+ // ── Schema fields: property-level diff ──
229
+ if ((diff.field === 'input_schema' || diff.field === 'output_schema') &&
230
+ diff.kind === 'changed') {
231
+ process.stdout.write(chalk_1.default.cyan(`~ ${diff.field}:`) + '\n');
232
+ process.stdout.write(formatSchemaDiff(diff.field, diff.old, diff.new) + '\n\n');
233
+ continue;
234
+ }
235
+ // ── Prompt: line-level diff ──
236
+ if (diff.field === 'prompt' && diff.kind === 'changed') {
237
+ process.stdout.write(chalk_1.default.cyan(`~ prompt:`) + '\n');
238
+ process.stdout.write(formatPromptDiff(diff.old, diff.new) + '\n\n');
239
+ continue;
240
+ }
241
+ // ── String arrays: item-level diff ──
242
+ if (stringArrayFields.has(diff.field) && diff.kind === 'changed') {
243
+ process.stdout.write(chalk_1.default.cyan(`~ ${diff.field}:`) + '\n');
244
+ process.stdout.write(formatStringArrayDiff(diff.old, diff.new) + '\n\n');
245
+ continue;
246
+ }
247
+ // ── Dependencies: item-level diff ──
248
+ if (diff.field === 'dependencies' && diff.kind === 'changed') {
249
+ process.stdout.write(chalk_1.default.cyan(`~ dependencies:`) + '\n');
250
+ process.stdout.write(formatDependencyDiff(diff.old, diff.new) + '\n\n');
251
+ continue;
252
+ }
253
+ // ── Custom tools: item-level diff ──
254
+ if (diff.field === 'custom_tools' && diff.kind === 'changed') {
255
+ process.stdout.write(chalk_1.default.cyan(`~ custom_tools:`) + '\n');
256
+ process.stdout.write(formatCustomToolDiff(diff.old, diff.new) + '\n\n');
257
+ continue;
258
+ }
259
+ // ── Default models: key-level diff ──
260
+ if (diff.field === 'default_models' && diff.kind === 'changed') {
261
+ process.stdout.write(chalk_1.default.cyan(`~ default_models:`) + '\n');
262
+ process.stdout.write(formatModelsDiff(diff.old, diff.new) + '\n\n');
263
+ continue;
264
+ }
265
+ // ── Standard scalar fields ──
266
+ if (diff.kind === 'added') {
267
+ const formatted = formatValuePlain(diff.new);
268
+ if (formatted.includes('\n')) {
269
+ process.stdout.write(chalk_1.default.green(`+ ${diff.field}:`) + '\n');
270
+ process.stdout.write(colorLines(formatted, l => chalk_1.default.green(` ${l}`)) + '\n\n');
271
+ }
272
+ else {
273
+ process.stdout.write(chalk_1.default.green(`+ ${diff.field}: ${formatted}`) + '\n');
274
+ }
275
+ }
276
+ else if (diff.kind === 'removed') {
277
+ const formatted = formatValuePlain(diff.old);
278
+ if (formatted.includes('\n')) {
279
+ process.stdout.write(chalk_1.default.red(`- ${diff.field}:`) + '\n');
280
+ process.stdout.write(colorLines(formatted, l => chalk_1.default.red(` ${l}`)) + '\n\n');
281
+ }
282
+ else {
283
+ process.stdout.write(chalk_1.default.red(`- ${diff.field}: ${formatted}`) + '\n');
284
+ }
285
+ }
286
+ else {
287
+ // changed — old in red, new in green
288
+ const oldFmt = formatValuePlain(diff.old);
289
+ const newFmt = formatValuePlain(diff.new);
290
+ if (!oldFmt.includes('\n') && !newFmt.includes('\n')) {
291
+ process.stdout.write(`${chalk_1.default.cyan('~')} ${chalk_1.default.bold(diff.field)}: ${chalk_1.default.red(oldFmt)} ${chalk_1.default.yellow('\u2192')} ${chalk_1.default.green(newFmt)}\n`);
292
+ }
293
+ else {
294
+ process.stdout.write(chalk_1.default.cyan(`~ ${diff.field}:`) + '\n');
295
+ process.stdout.write(colorLines(oldFmt, l => chalk_1.default.red(` - ${l}`)) + '\n');
296
+ process.stdout.write(colorLines(newFmt, l => chalk_1.default.green(` + ${l}`)) + '\n\n');
297
+ }
298
+ }
299
+ }
300
+ }
@@ -1,16 +1,13 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.computeDiffs = computeDiffs;
7
4
  exports.registerDiffCommand = registerDiffCommand;
8
- const chalk_1 = __importDefault(require("chalk"));
9
5
  const config_1 = require("../lib/config");
10
6
  const api_1 = require("../lib/api");
11
7
  const agent_ref_1 = require("../lib/agent-ref");
12
8
  const errors_1 = require("../lib/errors");
13
9
  const spinner_1 = require("../lib/spinner");
10
+ const diff_format_1 = require("./diff-format");
14
11
  // ── Helpers ────────────────────────────────────────────────────
15
12
  function extractDependencies(manifest) {
16
13
  if (!manifest)
@@ -237,130 +234,6 @@ function computeDiffs(a, b) {
237
234
  }
238
235
  return diffs;
239
236
  }
240
- // ── Formatting ─────────────────────────────────────────────────
241
- function formatValue(val) {
242
- if (val === undefined || val === null)
243
- return chalk_1.default.gray('(none)');
244
- if (typeof val === 'boolean')
245
- return val ? chalk_1.default.green('true') : chalk_1.default.red('false');
246
- if (typeof val === 'string') {
247
- if (val.length > 120)
248
- return val.slice(0, 117) + '...';
249
- return val;
250
- }
251
- if (Array.isArray(val)) {
252
- if (val.length === 0)
253
- return chalk_1.default.gray('[]');
254
- // Array of strings
255
- if (typeof val[0] === 'string')
256
- return val.join(', ');
257
- // Array of objects — compact JSON
258
- return JSON.stringify(val, null, 2);
259
- }
260
- if (typeof val === 'object')
261
- return JSON.stringify(val, null, 2);
262
- return String(val);
263
- }
264
- function formatPromptDiff(oldPrompt, newPrompt) {
265
- const oldLines = (oldPrompt || '').split('\n');
266
- const newLines = (newPrompt || '').split('\n');
267
- const lines = [];
268
- // Simple line-by-line diff (not LCS — good enough for prompt comparison)
269
- const maxLines = Math.max(oldLines.length, newLines.length);
270
- const oldSet = new Set(oldLines);
271
- const newSet = new Set(newLines);
272
- for (const line of oldLines) {
273
- if (!newSet.has(line)) {
274
- lines.push(chalk_1.default.red(` - ${line}`));
275
- }
276
- }
277
- for (const line of newLines) {
278
- if (!oldSet.has(line)) {
279
- lines.push(chalk_1.default.green(` + ${line}`));
280
- }
281
- }
282
- if (lines.length === 0) {
283
- // Lines are the same but order changed
284
- lines.push(chalk_1.default.yellow(' (line order changed)'));
285
- }
286
- // Truncate if very large
287
- if (lines.length > 40) {
288
- const shown = lines.slice(0, 40);
289
- shown.push(chalk_1.default.gray(` ... and ${lines.length - 40} more lines`));
290
- return shown.join('\n');
291
- }
292
- return lines.join('\n');
293
- }
294
- function formatSchemaDiff(field, oldSchema, newSchema) {
295
- const lines = [];
296
- const oldProps = oldSchema?.properties || {};
297
- const newProps = newSchema?.properties || {};
298
- const oldRequired = new Set(oldSchema?.required || []);
299
- const newRequired = new Set(newSchema?.required || []);
300
- const allKeys = new Set([...Object.keys(oldProps), ...Object.keys(newProps)]);
301
- for (const key of allKeys) {
302
- const inOld = key in oldProps;
303
- const inNew = key in newProps;
304
- if (!inOld && inNew) {
305
- const reqMark = newRequired.has(key) ? '' : '?';
306
- lines.push(chalk_1.default.green(` + ${key}${reqMark}: ${newProps[key].type || 'any'}`));
307
- }
308
- else if (inOld && !inNew) {
309
- const reqMark = oldRequired.has(key) ? '' : '?';
310
- lines.push(chalk_1.default.red(` - ${key}${reqMark}: ${oldProps[key].type || 'any'}`));
311
- }
312
- else if (inOld && inNew) {
313
- const oldType = oldProps[key].type || 'any';
314
- const newType = newProps[key].type || 'any';
315
- const wasReq = oldRequired.has(key);
316
- const isReq = newRequired.has(key);
317
- if (oldType !== newType || wasReq !== isReq) {
318
- const oldMark = wasReq ? '' : '?';
319
- const newMark = isReq ? '' : '?';
320
- lines.push(chalk_1.default.red(` - ${key}${oldMark}: ${oldType}`));
321
- lines.push(chalk_1.default.green(` + ${key}${newMark}: ${newType}`));
322
- }
323
- }
324
- }
325
- return lines.join('\n');
326
- }
327
- function printDiffs(refA, refB, diffs) {
328
- process.stdout.write('\n');
329
- process.stdout.write(chalk_1.default.bold(`${refA} ${chalk_1.default.yellow('→')} ${refB}`) + '\n');
330
- process.stdout.write('='.repeat(50) + '\n\n');
331
- if (diffs.length === 0) {
332
- process.stdout.write(chalk_1.default.green('No differences found.') + '\n');
333
- return;
334
- }
335
- process.stdout.write(`${chalk_1.default.bold(String(diffs.length))} ${diffs.length === 1 ? 'change' : 'changes'}:\n\n`);
336
- for (const diff of diffs) {
337
- // Schema fields get special formatting
338
- if ((diff.field === 'input_schema' || diff.field === 'output_schema') && diff.kind === 'changed') {
339
- process.stdout.write(chalk_1.default.cyan(`~ ${diff.field}:`) + '\n');
340
- process.stdout.write(formatSchemaDiff(diff.field, diff.old, diff.new) + '\n\n');
341
- continue;
342
- }
343
- // Prompt gets special formatting
344
- if (diff.field === 'prompt' && diff.kind === 'changed') {
345
- process.stdout.write(chalk_1.default.cyan(`~ prompt:`) + '\n');
346
- process.stdout.write(formatPromptDiff(diff.old, diff.new) + '\n\n');
347
- continue;
348
- }
349
- // Standard fields
350
- const prefix = diff.kind === 'added' ? chalk_1.default.green('+')
351
- : diff.kind === 'removed' ? chalk_1.default.red('-')
352
- : chalk_1.default.cyan('~');
353
- if (diff.kind === 'added') {
354
- process.stdout.write(`${prefix} ${chalk_1.default.bold(diff.field)}: ${formatValue(diff.new)}\n`);
355
- }
356
- else if (diff.kind === 'removed') {
357
- process.stdout.write(`${prefix} ${chalk_1.default.bold(diff.field)}: ${formatValue(diff.old)}\n`);
358
- }
359
- else {
360
- process.stdout.write(`${prefix} ${chalk_1.default.bold(diff.field)}: ${formatValue(diff.old)} ${chalk_1.default.yellow('→')} ${formatValue(diff.new)}\n`);
361
- }
362
- }
363
- }
364
237
  // ── Ref parsing ────────────────────────────────────────────────
365
238
  /**
366
239
  * Parse second ref which can be:
@@ -421,6 +294,6 @@ function registerDiffCommand(program) {
421
294
  }, null, 2) + '\n');
422
295
  return;
423
296
  }
424
- printDiffs(refALabel, refBLabel, diffs);
297
+ (0, diff_format_1.printDiffs)(refALabel, refBLabel, diffs);
425
298
  });
426
299
  }
@@ -14,7 +14,8 @@ const output_1 = require("../lib/output");
14
14
  const package_json_1 = __importDefault(require("../../package.json"));
15
15
  /**
16
16
  * Generate a minimal sample input from an agent's input schema.
17
- * Produces just enough to satisfy required fields.
17
+ * Produces just enough to satisfy required fields, using schema hints
18
+ * (format, examples, field name conventions) to create realistic values.
18
19
  */
19
20
  function generateSampleInput(schema) {
20
21
  if (!schema?.properties)
@@ -24,28 +25,110 @@ function generateSampleInput(schema) {
24
25
  for (const [key, prop] of Object.entries(schema.properties)) {
25
26
  if (!required.has(key))
26
27
  continue;
27
- result[key] = sampleValue(prop);
28
+ result[key] = sampleValue(prop, key);
28
29
  }
29
30
  // If no required fields, fill one optional field so the request isn't empty
30
31
  if (Object.keys(result).length === 0) {
31
32
  const firstKey = Object.keys(schema.properties)[0];
32
33
  if (firstKey) {
33
- result[firstKey] = sampleValue(schema.properties[firstKey]);
34
+ result[firstKey] = sampleValue(schema.properties[firstKey], firstKey);
34
35
  }
35
36
  }
36
37
  return Object.keys(result).length > 0 ? result : undefined;
37
38
  }
38
- function sampleValue(prop) {
39
+ /** Well-known JSON Schema string formats → realistic sample values. */
40
+ const FORMAT_SAMPLES = {
41
+ uri: 'https://example.com',
42
+ url: 'https://example.com',
43
+ iri: 'https://example.com',
44
+ 'uri-reference': '/test',
45
+ 'iri-reference': '/test',
46
+ email: 'test@example.com',
47
+ 'idn-email': 'test@example.com',
48
+ date: '2026-01-01',
49
+ 'date-time': '2026-01-01T00:00:00Z',
50
+ time: '12:00:00',
51
+ uuid: '00000000-0000-0000-0000-000000000000',
52
+ hostname: 'example.com',
53
+ 'idn-hostname': 'example.com',
54
+ ipv4: '192.0.2.1',
55
+ ipv6: '::1',
56
+ 'json-pointer': '/test',
57
+ 'relative-json-pointer': '0/test',
58
+ regex: '.*',
59
+ };
60
+ /**
61
+ * Field name segments that suggest a specific value type.
62
+ * Checked after format (format takes priority).
63
+ */
64
+ const NAME_HINT_SAMPLES = [
65
+ { segments: new Set(['url', 'uri', 'href', 'link', 'endpoint', 'webhook']), value: 'https://example.com' },
66
+ { segments: new Set(['email']), value: 'test@example.com' },
67
+ { segments: new Set(['path', 'file', 'filename', 'filepath']), value: '/tmp/test' },
68
+ { segments: new Set(['date', 'timestamp']), value: '2026-01-01' },
69
+ { segments: new Set(['phone', 'tel', 'telephone']), value: '+12025551234' },
70
+ { segments: new Set(['ip', 'ipaddr', 'ipaddress']), value: '192.0.2.1' },
71
+ { segments: new Set(['host', 'hostname', 'domain']), value: 'example.com' },
72
+ { segments: new Set(['uuid', 'guid']), value: '00000000-0000-0000-0000-000000000000' },
73
+ ];
74
+ function sampleString(prop, fieldName) {
75
+ // 1. Schema format (highest priority after default/enum)
76
+ if (prop.format && FORMAT_SAMPLES[prop.format]) {
77
+ return FORMAT_SAMPLES[prop.format];
78
+ }
79
+ // 2. Field name heuristics — split on _ and - to get semantic segments
80
+ if (fieldName) {
81
+ const segments = new Set(fieldName.toLowerCase().split(/[_-]/));
82
+ for (const hint of NAME_HINT_SAMPLES) {
83
+ for (const seg of segments) {
84
+ if (hint.segments.has(seg))
85
+ return hint.value;
86
+ }
87
+ }
88
+ }
89
+ // 3. Respect minLength
90
+ const base = 'test';
91
+ if (prop.minLength && prop.minLength > base.length) {
92
+ return base + 'x'.repeat(prop.minLength - base.length);
93
+ }
94
+ return base;
95
+ }
96
+ function sampleNumber(prop) {
97
+ const min = prop.exclusiveMinimum !== undefined
98
+ ? prop.exclusiveMinimum + 1
99
+ : prop.minimum;
100
+ const max = prop.exclusiveMaximum !== undefined
101
+ ? prop.exclusiveMaximum - 1
102
+ : prop.maximum;
103
+ if (min !== undefined && max !== undefined) {
104
+ return prop.type === 'integer' ? Math.ceil((min + max) / 2) : (min + max) / 2;
105
+ }
106
+ if (min !== undefined)
107
+ return min;
108
+ if (max !== undefined)
109
+ return max;
110
+ return 1;
111
+ }
112
+ function sampleArray(prop) {
113
+ const count = prop.minItems || 0;
114
+ if (count === 0)
115
+ return [];
116
+ const itemProp = prop.items || { type: 'string' };
117
+ return Array.from({ length: count }, () => sampleValue(itemProp));
118
+ }
119
+ function sampleValue(prop, fieldName) {
39
120
  if (prop.default !== undefined)
40
121
  return prop.default;
122
+ if (prop.examples?.length)
123
+ return prop.examples[0];
41
124
  if (prop.enum?.length)
42
125
  return prop.enum[0];
43
126
  switch (prop.type) {
44
- case 'string': return 'test';
127
+ case 'string': return sampleString(prop, fieldName);
45
128
  case 'number':
46
- case 'integer': return 1;
129
+ case 'integer': return sampleNumber(prop);
47
130
  case 'boolean': return true;
48
- case 'array': return [];
131
+ case 'array': return sampleArray(prop);
49
132
  case 'object': return {};
50
133
  default: return 'test';
51
134
  }
@@ -5,6 +5,7 @@ const login_1 = require("./login");
5
5
  const logout_1 = require("./logout");
6
6
  const agents_1 = require("./agents");
7
7
  const init_1 = require("./init");
8
+ const scaffold_1 = require("./scaffold");
8
9
  const publish_1 = require("./publish");
9
10
  const whoami_1 = require("./whoami");
10
11
  const run_1 = require("./run");
@@ -43,11 +44,13 @@ const trace_1 = require("./trace");
43
44
  const metrics_1 = require("./metrics");
44
45
  const dag_1 = require("./dag");
45
46
  const completion_1 = require("./completion");
47
+ const validate_1 = require("./validate");
46
48
  function registerCommands(program) {
47
49
  (0, login_1.registerLoginCommand)(program);
48
50
  (0, logout_1.registerLogoutCommand)(program);
49
51
  (0, whoami_1.registerWhoamiCommand)(program);
50
52
  (0, init_1.registerInitCommand)(program);
53
+ (0, scaffold_1.registerScaffoldCommand)(program);
51
54
  (0, publish_1.registerPublishCommand)(program);
52
55
  (0, run_1.registerRunCommand)(program);
53
56
  (0, info_1.registerInfoCommand)(program);
@@ -86,4 +89,5 @@ function registerCommands(program) {
86
89
  (0, metrics_1.registerMetricsCommand)(program);
87
90
  (0, dag_1.registerDagCommand)(program);
88
91
  (0, completion_1.registerCompletionCommand)(program);
92
+ (0, validate_1.registerValidateCommand)(program);
89
93
  }