@constructive-io/graphql-codegen 4.9.0 → 4.12.2

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.
Files changed (33) hide show
  1. package/core/codegen/cli/arg-mapper.d.ts +1 -1
  2. package/core/codegen/cli/arg-mapper.js +15 -11
  3. package/core/codegen/cli/custom-command-generator.js +4 -3
  4. package/core/codegen/cli/docs-generator.d.ts +6 -5
  5. package/core/codegen/cli/docs-generator.js +167 -64
  6. package/core/codegen/cli/table-command-generator.d.ts +15 -0
  7. package/core/codegen/cli/table-command-generator.js +20 -1
  8. package/core/codegen/docs-utils.d.ts +26 -1
  9. package/core/codegen/docs-utils.js +105 -0
  10. package/core/codegen/orm/input-types-generator.js +112 -14
  11. package/core/codegen/orm/model-generator.js +8 -0
  12. package/core/codegen/orm/select-types.d.ts +4 -2
  13. package/core/codegen/scalars.js +8 -0
  14. package/core/codegen/templates/cli-entry.ts +2 -2
  15. package/core/codegen/templates/cli-utils.ts +28 -0
  16. package/core/codegen/templates/query-builder.ts +28 -5
  17. package/core/codegen/templates/select-types.ts +4 -2
  18. package/core/generate.js +14 -4
  19. package/esm/core/codegen/cli/arg-mapper.d.ts +1 -1
  20. package/esm/core/codegen/cli/arg-mapper.js +15 -11
  21. package/esm/core/codegen/cli/custom-command-generator.js +4 -3
  22. package/esm/core/codegen/cli/docs-generator.d.ts +6 -5
  23. package/esm/core/codegen/cli/docs-generator.js +168 -65
  24. package/esm/core/codegen/cli/table-command-generator.d.ts +15 -0
  25. package/esm/core/codegen/cli/table-command-generator.js +20 -3
  26. package/esm/core/codegen/docs-utils.d.ts +26 -1
  27. package/esm/core/codegen/docs-utils.js +102 -0
  28. package/esm/core/codegen/orm/input-types-generator.js +112 -14
  29. package/esm/core/codegen/orm/model-generator.js +8 -0
  30. package/esm/core/codegen/orm/select-types.d.ts +4 -2
  31. package/esm/core/codegen/scalars.js +8 -0
  32. package/esm/core/generate.js +14 -4
  33. package/package.json +11 -11
@@ -12,9 +12,10 @@ exports.generateMultiTargetSkills = generateMultiTargetSkills;
12
12
  const komoji_1 = require("komoji");
13
13
  const docs_utils_1 = require("../docs-utils");
14
14
  const utils_1 = require("../utils");
15
+ const table_command_generator_1 = require("./table-command-generator");
15
16
  var docs_utils_2 = require("../docs-utils");
16
17
  Object.defineProperty(exports, "resolveDocsConfig", { enumerable: true, get: function () { return docs_utils_2.resolveDocsConfig; } });
17
- function generateReadme(tables, customOperations, toolName) {
18
+ function generateReadme(tables, customOperations, toolName, registry) {
18
19
  const lines = [];
19
20
  lines.push(...(0, docs_utils_1.getReadmeHeader)(`${toolName} CLI`));
20
21
  lines.push('## Setup');
@@ -98,10 +99,21 @@ function generateReadme(tables, customOperations, toolName) {
98
99
  lines.push('| Field | Type |');
99
100
  lines.push('|-------|------|');
100
101
  for (const f of scalarFields) {
101
- lines.push(`| \`${f.name}\` | ${f.type.gqlType} |`);
102
+ lines.push(`| \`${f.name}\` | ${(0, docs_utils_1.cleanTypeName)(f.type.gqlType)} |`);
102
103
  }
103
104
  lines.push('');
104
- lines.push(`**Create fields:** ${editableFields.map((f) => `\`${f.name}\``).join(', ')}`);
105
+ const defaultFields = (0, table_command_generator_1.getFieldsWithDefaults)(table, registry);
106
+ const requiredCreate = editableFields.filter((f) => !defaultFields.has(f.name));
107
+ const optionalCreate = editableFields.filter((f) => defaultFields.has(f.name));
108
+ if (requiredCreate.length > 0) {
109
+ lines.push(`**Required create fields:** ${requiredCreate.map((f) => `\`${f.name}\``).join(', ')}`);
110
+ }
111
+ if (optionalCreate.length > 0) {
112
+ lines.push(`**Optional create fields (backend defaults):** ${optionalCreate.map((f) => `\`${f.name}\``).join(', ')}`);
113
+ }
114
+ if (requiredCreate.length === 0 && optionalCreate.length === 0) {
115
+ lines.push(`**Create fields:** ${editableFields.map((f) => `\`${f.name}\``).join(', ')}`);
116
+ }
105
117
  lines.push('');
106
118
  }
107
119
  }
@@ -110,18 +122,20 @@ function generateReadme(tables, customOperations, toolName) {
110
122
  lines.push('');
111
123
  for (const op of customOperations) {
112
124
  const kebab = (0, komoji_1.toKebabCase)(op.name);
125
+ const flat = (0, docs_utils_1.flattenArgs)(op.args, registry);
113
126
  lines.push(`### \`${kebab}\``);
114
127
  lines.push('');
115
128
  lines.push(op.description || op.name);
116
129
  lines.push('');
117
130
  lines.push(`- **Type:** ${op.kind}`);
118
- if (op.args.length > 0) {
131
+ if (flat.length > 0) {
119
132
  lines.push('- **Arguments:**');
120
133
  lines.push('');
121
134
  lines.push(' | Argument | Type |');
122
135
  lines.push(' |----------|------|');
123
- for (const arg of op.args) {
124
- lines.push(` | \`${arg.name}\` | ${(0, docs_utils_1.formatArgType)(arg)} |`);
136
+ for (const a of flat) {
137
+ const reqLabel = a.required ? ' (required)' : '';
138
+ lines.push(` | \`--${a.flag}\` | ${a.type}${reqLabel} |`);
125
139
  }
126
140
  }
127
141
  else {
@@ -139,13 +153,21 @@ function generateReadme(tables, customOperations, toolName) {
139
153
  lines.push(`${toolName} car get --id <uuid> | jq '.'`);
140
154
  lines.push('```');
141
155
  lines.push('');
156
+ lines.push('## Non-Interactive Mode');
157
+ lines.push('');
158
+ lines.push('Use `--no-tty` to skip all interactive prompts (useful for scripts and CI):');
159
+ lines.push('');
160
+ lines.push('```bash');
161
+ lines.push(`${toolName} --no-tty car create --name "Sedan" --year 2024`);
162
+ lines.push('```');
163
+ lines.push('');
142
164
  lines.push(...(0, docs_utils_1.getReadmeFooter)());
143
165
  return {
144
166
  fileName: 'README.md',
145
167
  content: lines.join('\n'),
146
168
  };
147
169
  }
148
- function generateAgentsDocs(tables, customOperations, toolName) {
170
+ function generateAgentsDocs(tables, customOperations, toolName, registry) {
149
171
  const lines = [];
150
172
  lines.push(`# ${toolName} CLI - Agent Reference`);
151
173
  lines.push('');
@@ -217,6 +239,13 @@ function generateAgentsDocs(tables, customOperations, toolName) {
217
239
  const pk = (0, utils_1.getPrimaryKeyInfo)(table)[0];
218
240
  const scalarFields = (0, utils_1.getScalarFields)(table);
219
241
  const editableFields = (0, docs_utils_1.getEditableFields)(table);
242
+ const defaultFields = (0, table_command_generator_1.getFieldsWithDefaults)(table, registry);
243
+ const requiredCreateFields = editableFields.filter((f) => !defaultFields.has(f.name));
244
+ const optionalCreateFields = editableFields.filter((f) => defaultFields.has(f.name));
245
+ const createFlags = [
246
+ ...requiredCreateFields.map((f) => `--${f.name} <value>`),
247
+ ...optionalCreateFields.map((f) => `[--${f.name} <value>]`),
248
+ ].join(' ');
220
249
  lines.push(`### TOOL: ${kebab}`);
221
250
  lines.push('');
222
251
  lines.push(`CRUD operations for ${table.name} records.`);
@@ -225,19 +254,20 @@ function generateAgentsDocs(tables, customOperations, toolName) {
225
254
  lines.push('SUBCOMMANDS:');
226
255
  lines.push(` ${toolName} ${kebab} list List all records`);
227
256
  lines.push(` ${toolName} ${kebab} get --${pk.name} <value> Get one record`);
228
- lines.push(` ${toolName} ${kebab} create ${editableFields.map((f) => `--${f.name} <value>`).join(' ')}`);
257
+ lines.push(` ${toolName} ${kebab} create ${createFlags}`);
229
258
  lines.push(` ${toolName} ${kebab} update --${pk.name} <value> ${editableFields.map((f) => `[--${f.name} <value>]`).join(' ')}`);
230
259
  lines.push(` ${toolName} ${kebab} delete --${pk.name} <value> Delete one record`);
231
260
  lines.push('');
232
261
  lines.push('INPUT FIELDS:');
233
262
  for (const f of scalarFields) {
234
263
  const isPk = f.name === pk.name;
235
- lines.push(` ${f.name}: ${f.type.gqlType}${isPk ? ' (primary key)' : ''}`);
264
+ lines.push(` ${f.name}: ${(0, docs_utils_1.cleanTypeName)(f.type.gqlType)}${isPk ? ' (primary key)' : ''}`);
236
265
  }
237
266
  lines.push('');
238
267
  lines.push('EDITABLE FIELDS (for create/update):');
239
268
  for (const f of editableFields) {
240
- lines.push(` ${f.name}: ${f.type.gqlType}`);
269
+ const optLabel = defaultFields.has(f.name) ? ' (optional, has backend default)' : '';
270
+ lines.push(` ${f.name}: ${(0, docs_utils_1.cleanTypeName)(f.type.gqlType)}${optLabel}`);
241
271
  }
242
272
  lines.push('');
243
273
  lines.push('OUTPUT: JSON');
@@ -251,19 +281,21 @@ function generateAgentsDocs(tables, customOperations, toolName) {
251
281
  }
252
282
  for (const op of customOperations) {
253
283
  const kebab = (0, komoji_1.toKebabCase)(op.name);
284
+ const flat = (0, docs_utils_1.flattenArgs)(op.args, registry);
254
285
  lines.push(`### TOOL: ${kebab}`);
255
286
  lines.push('');
256
287
  lines.push(op.description || op.name);
257
288
  lines.push('');
258
289
  lines.push('```');
259
290
  lines.push(`TYPE: ${op.kind}`);
260
- if (op.args.length > 0) {
261
- const flags = op.args.map((a) => `--${a.name} <value>`).join(' ');
291
+ if (flat.length > 0) {
292
+ const flags = (0, docs_utils_1.flattenedArgsToFlags)(flat);
262
293
  lines.push(`USAGE: ${toolName} ${kebab} ${flags}`);
263
294
  lines.push('');
264
295
  lines.push('INPUT:');
265
- for (const arg of op.args) {
266
- lines.push(` ${arg.name}: ${(0, docs_utils_1.formatArgType)(arg)}`);
296
+ for (const a of flat) {
297
+ const reqLabel = a.required ? ' (required)' : '';
298
+ lines.push(` ${a.flag}: ${a.type}${reqLabel}`);
267
299
  }
268
300
  }
269
301
  else {
@@ -341,7 +373,7 @@ function generateAgentsDocs(tables, customOperations, toolName) {
341
373
  content: lines.join('\n'),
342
374
  };
343
375
  }
344
- function getCliMcpTools(tables, customOperations, toolName) {
376
+ function getCliMcpTools(tables, customOperations, toolName, registry) {
345
377
  const tools = [];
346
378
  tools.push({
347
379
  name: `${toolName}_context_create`,
@@ -414,6 +446,10 @@ function getCliMcpTools(tables, customOperations, toolName) {
414
446
  const pk = (0, utils_1.getPrimaryKeyInfo)(table)[0];
415
447
  const scalarFields = (0, utils_1.getScalarFields)(table);
416
448
  const editableFields = (0, docs_utils_1.getEditableFields)(table);
449
+ const defaultFields = (0, table_command_generator_1.getFieldsWithDefaults)(table, registry);
450
+ const requiredCreateFieldNames = editableFields
451
+ .filter((f) => !defaultFields.has(f.name))
452
+ .map((f) => f.name);
417
453
  tools.push({
418
454
  name: `${toolName}_${kebab}_list`,
419
455
  description: `List all ${table.name} records`,
@@ -436,7 +472,7 @@ function getCliMcpTools(tables, customOperations, toolName) {
436
472
  const createProps = {};
437
473
  for (const f of editableFields) {
438
474
  createProps[f.name] = {
439
- type: (0, docs_utils_1.gqlTypeToJsonSchemaType)(f.type.gqlType),
475
+ type: (0, docs_utils_1.gqlTypeToJsonSchemaType)((0, docs_utils_1.cleanTypeName)(f.type.gqlType)),
440
476
  description: `${table.name} ${f.name}`,
441
477
  };
442
478
  }
@@ -446,7 +482,7 @@ function getCliMcpTools(tables, customOperations, toolName) {
446
482
  inputSchema: {
447
483
  type: 'object',
448
484
  properties: createProps,
449
- required: editableFields.map((f) => f.name),
485
+ ...(requiredCreateFieldNames.length > 0 ? { required: requiredCreateFieldNames } : {}),
450
486
  },
451
487
  });
452
488
  const updateProps = {
@@ -457,7 +493,7 @@ function getCliMcpTools(tables, customOperations, toolName) {
457
493
  };
458
494
  for (const f of editableFields) {
459
495
  updateProps[f.name] = {
460
- type: (0, docs_utils_1.gqlTypeToJsonSchemaType)(f.type.gqlType),
496
+ type: (0, docs_utils_1.gqlTypeToJsonSchemaType)((0, docs_utils_1.cleanTypeName)(f.type.gqlType)),
461
497
  description: `${table.name} ${f.name}`,
462
498
  };
463
499
  }
@@ -491,7 +527,7 @@ function getCliMcpTools(tables, customOperations, toolName) {
491
527
  _meta: {
492
528
  fields: scalarFields.map((f) => ({
493
529
  name: f.name,
494
- type: f.type.gqlType,
530
+ type: (0, docs_utils_1.cleanTypeName)(f.type.gqlType),
495
531
  editable: editableFields.some((ef) => ef.name === f.name),
496
532
  primaryKey: f.name === pk.name,
497
533
  })),
@@ -500,17 +536,16 @@ function getCliMcpTools(tables, customOperations, toolName) {
500
536
  }
501
537
  for (const op of customOperations) {
502
538
  const kebab = (0, komoji_1.toKebabCase)(op.name);
539
+ const flat = (0, docs_utils_1.flattenArgs)(op.args, registry);
503
540
  const props = {};
504
541
  const required = [];
505
- for (const arg of op.args) {
506
- const isRequired = arg.type.kind === 'NON_NULL';
507
- const baseType = isRequired && arg.type.ofType ? arg.type.ofType : arg.type;
508
- props[arg.name] = {
509
- type: (0, docs_utils_1.gqlTypeToJsonSchemaType)(baseType.name ?? 'String'),
510
- description: arg.description || arg.name,
542
+ for (const a of flat) {
543
+ props[a.flag] = {
544
+ type: (0, docs_utils_1.gqlTypeToJsonSchemaType)(a.type),
545
+ description: a.description || a.flag,
511
546
  };
512
- if (isRequired) {
513
- required.push(arg.name);
547
+ if (a.required) {
548
+ required.push(a.flag);
514
549
  }
515
550
  }
516
551
  tools.push({
@@ -525,7 +560,7 @@ function getCliMcpTools(tables, customOperations, toolName) {
525
560
  }
526
561
  return tools;
527
562
  }
528
- function generateSkills(tables, customOperations, toolName, targetName) {
563
+ function generateSkills(tables, customOperations, toolName, targetName, registry) {
529
564
  const files = [];
530
565
  const skillName = `cli-${targetName}`;
531
566
  const referenceNames = [];
@@ -588,6 +623,11 @@ function generateSkills(tables, customOperations, toolName, targetName) {
588
623
  const kebab = (0, komoji_1.toKebabCase)(singularName);
589
624
  const pk = (0, utils_1.getPrimaryKeyInfo)(table)[0];
590
625
  const editableFields = (0, docs_utils_1.getEditableFields)(table);
626
+ const defaultFields = (0, table_command_generator_1.getFieldsWithDefaults)(table, registry);
627
+ const createFlags = [
628
+ ...editableFields.filter((f) => !defaultFields.has(f.name)).map((f) => `--${f.name} <value>`),
629
+ ...editableFields.filter((f) => defaultFields.has(f.name)).map((f) => `[--${f.name} <value>]`),
630
+ ].join(' ');
591
631
  referenceNames.push(kebab);
592
632
  files.push({
593
633
  fileName: `${skillName}/references/${kebab}.md`,
@@ -597,7 +637,7 @@ function generateSkills(tables, customOperations, toolName, targetName) {
597
637
  usage: [
598
638
  `${toolName} ${kebab} list`,
599
639
  `${toolName} ${kebab} get --${pk.name} <value>`,
600
- `${toolName} ${kebab} create ${editableFields.map((f) => `--${f.name} <value>`).join(' ')}`,
640
+ `${toolName} ${kebab} create ${createFlags}`,
601
641
  `${toolName} ${kebab} update --${pk.name} <value> ${editableFields.map((f) => `[--${f.name} <value>]`).join(' ')}`,
602
642
  `${toolName} ${kebab} delete --${pk.name} <value>`,
603
643
  ],
@@ -609,7 +649,7 @@ function generateSkills(tables, customOperations, toolName, targetName) {
609
649
  {
610
650
  description: `Create a ${singularName}`,
611
651
  code: [
612
- `${toolName} ${kebab} create ${editableFields.map((f) => `--${f.name} "value"`).join(' ')}`,
652
+ `${toolName} ${kebab} create ${createFlags}`,
613
653
  ],
614
654
  },
615
655
  {
@@ -623,8 +663,9 @@ function generateSkills(tables, customOperations, toolName, targetName) {
623
663
  // Custom operation references
624
664
  for (const op of customOperations) {
625
665
  const kebab = (0, komoji_1.toKebabCase)(op.name);
626
- const usage = op.args.length > 0
627
- ? `${toolName} ${kebab} ${op.args.map((a) => `--${a.name} <value>`).join(' ')}`
666
+ const flat = (0, docs_utils_1.flattenArgs)(op.args, registry);
667
+ const usage = flat.length > 0
668
+ ? `${toolName} ${kebab} ${(0, docs_utils_1.flattenedArgsToFlags)(flat)}`
628
669
  : `${toolName} ${kebab}`;
629
670
  referenceNames.push(kebab);
630
671
  files.push({
@@ -661,6 +702,9 @@ function generateSkills(tables, customOperations, toolName, targetName) {
661
702
  `${toolName} ${tableKebabs[0] || 'model'} list`,
662
703
  `${toolName} ${tableKebabs[0] || 'model'} get --id <value>`,
663
704
  `${toolName} ${tableKebabs[0] || 'model'} create --<field> <value>`,
705
+ '',
706
+ `# Non-interactive mode (skip all prompts, use flags only)`,
707
+ `${toolName} --no-tty ${tableKebabs[0] || 'model'} list`,
664
708
  ],
665
709
  examples: [
666
710
  {
@@ -672,13 +716,19 @@ function generateSkills(tables, customOperations, toolName, targetName) {
672
716
  `${toolName} ${tableKebabs[0] || 'model'} list`,
673
717
  ],
674
718
  },
719
+ {
720
+ description: 'Non-interactive mode (for scripts and CI)',
721
+ code: [
722
+ `${toolName} --no-tty ${tableKebabs[0] || 'model'} create --<field> <value>`,
723
+ ],
724
+ },
675
725
  ],
676
726
  }, referenceNames),
677
727
  });
678
728
  return files;
679
729
  }
680
730
  function generateMultiTargetReadme(input) {
681
- const { toolName, builtinNames, targets } = input;
731
+ const { toolName, builtinNames, targets, registry } = input;
682
732
  const lines = [];
683
733
  lines.push(...(0, docs_utils_1.getReadmeHeader)(`${toolName} CLI`));
684
734
  lines.push('## Setup');
@@ -803,6 +853,7 @@ function generateMultiTargetReadme(input) {
803
853
  const pk = (0, utils_1.getPrimaryKeyInfo)(table)[0];
804
854
  const scalarFields = (0, utils_1.getScalarFields)(table);
805
855
  const editableFields = (0, docs_utils_1.getEditableFields)(table);
856
+ const defaultFields = (0, table_command_generator_1.getFieldsWithDefaults)(table, registry);
806
857
  lines.push(`### \`${tgt.name}:${kebab}\``);
807
858
  lines.push('');
808
859
  lines.push(`CRUD operations for ${table.name} records.`);
@@ -820,26 +871,38 @@ function generateMultiTargetReadme(input) {
820
871
  lines.push('| Field | Type |');
821
872
  lines.push('|-------|------|');
822
873
  for (const f of scalarFields) {
823
- lines.push(`| \`${f.name}\` | ${f.type.gqlType} |`);
874
+ lines.push(`| \`${f.name}\` | ${(0, docs_utils_1.cleanTypeName)(f.type.gqlType)} |`);
824
875
  }
825
876
  lines.push('');
826
- lines.push(`**Create fields:** ${editableFields.map((f) => `\`${f.name}\``).join(', ')}`);
877
+ const requiredCreate = editableFields.filter((f) => !defaultFields.has(f.name));
878
+ const optionalCreate = editableFields.filter((f) => defaultFields.has(f.name));
879
+ if (requiredCreate.length > 0) {
880
+ lines.push(`**Required create fields:** ${requiredCreate.map((f) => `\`${f.name}\``).join(', ')}`);
881
+ }
882
+ if (optionalCreate.length > 0) {
883
+ lines.push(`**Optional create fields (backend defaults):** ${optionalCreate.map((f) => `\`${f.name}\``).join(', ')}`);
884
+ }
885
+ if (requiredCreate.length === 0 && optionalCreate.length === 0) {
886
+ lines.push(`**Create fields:** ${editableFields.map((f) => `\`${f.name}\``).join(', ')}`);
887
+ }
827
888
  lines.push('');
828
889
  }
829
890
  for (const op of tgt.customOperations) {
830
891
  const kebab = (0, komoji_1.toKebabCase)(op.name);
892
+ const flat = (0, docs_utils_1.flattenArgs)(op.args, registry);
831
893
  lines.push(`### \`${tgt.name}:${kebab}\``);
832
894
  lines.push('');
833
895
  lines.push(op.description || op.name);
834
896
  lines.push('');
835
897
  lines.push(`- **Type:** ${op.kind}`);
836
- if (op.args.length > 0) {
898
+ if (flat.length > 0) {
837
899
  lines.push('- **Arguments:**');
838
900
  lines.push('');
839
901
  lines.push(' | Argument | Type |');
840
902
  lines.push(' |----------|------|');
841
- for (const arg of op.args) {
842
- lines.push(` | \`${arg.name}\` | ${(0, docs_utils_1.formatArgType)(arg)} |`);
903
+ for (const a of flat) {
904
+ const reqLabel = a.required ? ' (required)' : '';
905
+ lines.push(` | \`--${a.flag}\` | ${a.type}${reqLabel} |`);
843
906
  }
844
907
  }
845
908
  else {
@@ -864,6 +927,18 @@ function generateMultiTargetReadme(input) {
864
927
  }
865
928
  lines.push('```');
866
929
  lines.push('');
930
+ lines.push('## Non-Interactive Mode');
931
+ lines.push('');
932
+ lines.push('Use `--no-tty` to skip all interactive prompts (useful for scripts and CI):');
933
+ lines.push('');
934
+ lines.push('```bash');
935
+ if (targets.length > 0 && targets[0].tables.length > 0) {
936
+ const tgt = targets[0];
937
+ const kebab = (0, komoji_1.toKebabCase)((0, utils_1.getTableNames)(tgt.tables[0]).singularName);
938
+ lines.push(`${toolName} --no-tty ${tgt.name}:${kebab} create --name "Example"`);
939
+ }
940
+ lines.push('```');
941
+ lines.push('');
867
942
  lines.push(...(0, docs_utils_1.getReadmeFooter)());
868
943
  return {
869
944
  fileName: 'README.md',
@@ -871,7 +946,7 @@ function generateMultiTargetReadme(input) {
871
946
  };
872
947
  }
873
948
  function generateMultiTargetAgentsDocs(input) {
874
- const { toolName, builtinNames, targets } = input;
949
+ const { toolName, builtinNames, targets, registry } = input;
875
950
  const lines = [];
876
951
  lines.push(`# ${toolName} CLI - Agent Reference`);
877
952
  lines.push('');
@@ -964,6 +1039,13 @@ function generateMultiTargetAgentsDocs(input) {
964
1039
  const pk = (0, utils_1.getPrimaryKeyInfo)(table)[0];
965
1040
  const scalarFields = (0, utils_1.getScalarFields)(table);
966
1041
  const editableFields = (0, docs_utils_1.getEditableFields)(table);
1042
+ const defaultFields = (0, table_command_generator_1.getFieldsWithDefaults)(table, registry);
1043
+ const requiredCreateFields = editableFields.filter((f) => !defaultFields.has(f.name));
1044
+ const optionalCreateFields = editableFields.filter((f) => defaultFields.has(f.name));
1045
+ const createFlags = [
1046
+ ...requiredCreateFields.map((f) => `--${f.name} <value>`),
1047
+ ...optionalCreateFields.map((f) => `[--${f.name} <value>]`),
1048
+ ].join(' ');
967
1049
  lines.push(`### TOOL: ${tgt.name}:${kebab}`);
968
1050
  lines.push('');
969
1051
  lines.push(`CRUD operations for ${table.name} records (${tgt.name} target).`);
@@ -972,19 +1054,20 @@ function generateMultiTargetAgentsDocs(input) {
972
1054
  lines.push('SUBCOMMANDS:');
973
1055
  lines.push(` ${toolName} ${tgt.name}:${kebab} list List all records`);
974
1056
  lines.push(` ${toolName} ${tgt.name}:${kebab} get --${pk.name} <value> Get one record`);
975
- lines.push(` ${toolName} ${tgt.name}:${kebab} create ${editableFields.map((f) => `--${f.name} <value>`).join(' ')}`);
1057
+ lines.push(` ${toolName} ${tgt.name}:${kebab} create ${createFlags}`);
976
1058
  lines.push(` ${toolName} ${tgt.name}:${kebab} update --${pk.name} <value> ${editableFields.map((f) => `[--${f.name} <value>]`).join(' ')}`);
977
1059
  lines.push(` ${toolName} ${tgt.name}:${kebab} delete --${pk.name} <value> Delete one record`);
978
1060
  lines.push('');
979
1061
  lines.push('INPUT FIELDS:');
980
1062
  for (const f of scalarFields) {
981
1063
  const isPk = f.name === pk.name;
982
- lines.push(` ${f.name}: ${f.type.gqlType}${isPk ? ' (primary key)' : ''}`);
1064
+ lines.push(` ${f.name}: ${(0, docs_utils_1.cleanTypeName)(f.type.gqlType)}${isPk ? ' (primary key)' : ''}`);
983
1065
  }
984
1066
  lines.push('');
985
1067
  lines.push('EDITABLE FIELDS (for create/update):');
986
1068
  for (const f of editableFields) {
987
- lines.push(` ${f.name}: ${f.type.gqlType}`);
1069
+ const optLabel = defaultFields.has(f.name) ? ' (optional, has backend default)' : '';
1070
+ lines.push(` ${f.name}: ${(0, docs_utils_1.cleanTypeName)(f.type.gqlType)}${optLabel}`);
988
1071
  }
989
1072
  lines.push('');
990
1073
  lines.push('OUTPUT: JSON');
@@ -998,19 +1081,21 @@ function generateMultiTargetAgentsDocs(input) {
998
1081
  }
999
1082
  for (const op of tgt.customOperations) {
1000
1083
  const kebab = (0, komoji_1.toKebabCase)(op.name);
1084
+ const flat = (0, docs_utils_1.flattenArgs)(op.args, registry);
1001
1085
  lines.push(`### TOOL: ${tgt.name}:${kebab}`);
1002
1086
  lines.push('');
1003
1087
  lines.push(op.description || op.name);
1004
1088
  lines.push('');
1005
1089
  lines.push('```');
1006
1090
  lines.push(`TYPE: ${op.kind}`);
1007
- if (op.args.length > 0) {
1008
- const flags = op.args.map((a) => `--${a.name} <value>`).join(' ');
1091
+ if (flat.length > 0) {
1092
+ const flags = (0, docs_utils_1.flattenedArgsToFlags)(flat);
1009
1093
  lines.push(`USAGE: ${toolName} ${tgt.name}:${kebab} ${flags}`);
1010
1094
  lines.push('');
1011
1095
  lines.push('INPUT:');
1012
- for (const arg of op.args) {
1013
- lines.push(` ${arg.name}: ${(0, docs_utils_1.formatArgType)(arg)}`);
1096
+ for (const a of flat) {
1097
+ const reqLabel = a.required ? ' (required)' : '';
1098
+ lines.push(` ${a.flag}: ${a.type}${reqLabel}`);
1014
1099
  }
1015
1100
  }
1016
1101
  else {
@@ -1099,7 +1184,7 @@ function generateMultiTargetAgentsDocs(input) {
1099
1184
  };
1100
1185
  }
1101
1186
  function getMultiTargetCliMcpTools(input) {
1102
- const { toolName, builtinNames, targets } = input;
1187
+ const { toolName, builtinNames, targets, registry } = input;
1103
1188
  const tools = [];
1104
1189
  const contextEndpointProps = {
1105
1190
  name: { type: 'string', description: 'Context name' },
@@ -1179,6 +1264,10 @@ function getMultiTargetCliMcpTools(input) {
1179
1264
  const pk = (0, utils_1.getPrimaryKeyInfo)(table)[0];
1180
1265
  const scalarFields = (0, utils_1.getScalarFields)(table);
1181
1266
  const editableFields = (0, docs_utils_1.getEditableFields)(table);
1267
+ const defaultFields = (0, table_command_generator_1.getFieldsWithDefaults)(table, registry);
1268
+ const requiredCreateFieldNames = editableFields
1269
+ .filter((f) => !defaultFields.has(f.name))
1270
+ .map((f) => f.name);
1182
1271
  const prefix = `${toolName}_${tgt.name}_${kebab}`;
1183
1272
  tools.push({
1184
1273
  name: `${prefix}_list`,
@@ -1202,7 +1291,7 @@ function getMultiTargetCliMcpTools(input) {
1202
1291
  const createProps = {};
1203
1292
  for (const f of editableFields) {
1204
1293
  createProps[f.name] = {
1205
- type: (0, docs_utils_1.gqlTypeToJsonSchemaType)(f.type.gqlType),
1294
+ type: (0, docs_utils_1.gqlTypeToJsonSchemaType)((0, docs_utils_1.cleanTypeName)(f.type.gqlType)),
1206
1295
  description: `${table.name} ${f.name}`,
1207
1296
  };
1208
1297
  }
@@ -1212,7 +1301,7 @@ function getMultiTargetCliMcpTools(input) {
1212
1301
  inputSchema: {
1213
1302
  type: 'object',
1214
1303
  properties: createProps,
1215
- required: editableFields.map((f) => f.name),
1304
+ ...(requiredCreateFieldNames.length > 0 ? { required: requiredCreateFieldNames } : {}),
1216
1305
  },
1217
1306
  });
1218
1307
  const updateProps = {
@@ -1223,7 +1312,7 @@ function getMultiTargetCliMcpTools(input) {
1223
1312
  };
1224
1313
  for (const f of editableFields) {
1225
1314
  updateProps[f.name] = {
1226
- type: (0, docs_utils_1.gqlTypeToJsonSchemaType)(f.type.gqlType),
1315
+ type: (0, docs_utils_1.gqlTypeToJsonSchemaType)((0, docs_utils_1.cleanTypeName)(f.type.gqlType)),
1227
1316
  description: `${table.name} ${f.name}`,
1228
1317
  };
1229
1318
  }
@@ -1257,7 +1346,7 @@ function getMultiTargetCliMcpTools(input) {
1257
1346
  _meta: {
1258
1347
  fields: scalarFields.map((f) => ({
1259
1348
  name: f.name,
1260
- type: f.type.gqlType,
1349
+ type: (0, docs_utils_1.cleanTypeName)(f.type.gqlType),
1261
1350
  editable: editableFields.some((ef) => ef.name === f.name),
1262
1351
  primaryKey: f.name === pk.name,
1263
1352
  })),
@@ -1266,17 +1355,16 @@ function getMultiTargetCliMcpTools(input) {
1266
1355
  }
1267
1356
  for (const op of tgt.customOperations) {
1268
1357
  const kebab = (0, komoji_1.toKebabCase)(op.name);
1358
+ const flat = (0, docs_utils_1.flattenArgs)(op.args, registry);
1269
1359
  const props = {};
1270
1360
  const required = [];
1271
- for (const arg of op.args) {
1272
- const isRequired = arg.type.kind === 'NON_NULL';
1273
- const baseType = isRequired && arg.type.ofType ? arg.type.ofType : arg.type;
1274
- props[arg.name] = {
1275
- type: (0, docs_utils_1.gqlTypeToJsonSchemaType)(baseType.name ?? 'String'),
1276
- description: arg.description || arg.name,
1361
+ for (const a of flat) {
1362
+ props[a.flag] = {
1363
+ type: (0, docs_utils_1.gqlTypeToJsonSchemaType)(a.type),
1364
+ description: a.description || a.flag,
1277
1365
  };
1278
- if (isRequired) {
1279
- required.push(arg.name);
1366
+ if (a.required) {
1367
+ required.push(a.flag);
1280
1368
  }
1281
1369
  }
1282
1370
  if (tgt.isAuthTarget && op.kind === 'mutation') {
@@ -1299,7 +1387,7 @@ function getMultiTargetCliMcpTools(input) {
1299
1387
  return tools;
1300
1388
  }
1301
1389
  function generateMultiTargetSkills(input) {
1302
- const { toolName, builtinNames, targets } = input;
1390
+ const { toolName, builtinNames, targets, registry } = input;
1303
1391
  const files = [];
1304
1392
  // Generate one skill per target, plus a shared cli-common skill for context/auth
1305
1393
  const commonSkillName = 'cli-common';
@@ -1399,6 +1487,11 @@ function generateMultiTargetSkills(input) {
1399
1487
  const kebab = (0, komoji_1.toKebabCase)(singularName);
1400
1488
  const pk = (0, utils_1.getPrimaryKeyInfo)(table)[0];
1401
1489
  const editableFields = (0, docs_utils_1.getEditableFields)(table);
1490
+ const defaultFields = (0, table_command_generator_1.getFieldsWithDefaults)(table, registry);
1491
+ const createFlags = [
1492
+ ...editableFields.filter((f) => !defaultFields.has(f.name)).map((f) => `--${f.name} <value>`),
1493
+ ...editableFields.filter((f) => defaultFields.has(f.name)).map((f) => `[--${f.name} <value>]`),
1494
+ ].join(' ');
1402
1495
  const cmd = `${tgt.name}:${kebab}`;
1403
1496
  tgtReferenceNames.push(kebab);
1404
1497
  files.push({
@@ -1409,7 +1502,7 @@ function generateMultiTargetSkills(input) {
1409
1502
  usage: [
1410
1503
  `${toolName} ${cmd} list`,
1411
1504
  `${toolName} ${cmd} get --${pk.name} <value>`,
1412
- `${toolName} ${cmd} create ${editableFields.map((f) => `--${f.name} <value>`).join(' ')}`,
1505
+ `${toolName} ${cmd} create ${createFlags}`,
1413
1506
  `${toolName} ${cmd} update --${pk.name} <value> ${editableFields.map((f) => `[--${f.name} <value>]`).join(' ')}`,
1414
1507
  `${toolName} ${cmd} delete --${pk.name} <value>`,
1415
1508
  ],
@@ -1421,7 +1514,7 @@ function generateMultiTargetSkills(input) {
1421
1514
  {
1422
1515
  description: `Create a ${singularName}`,
1423
1516
  code: [
1424
- `${toolName} ${cmd} create ${editableFields.map((f) => `--${f.name} "value"`).join(' ')}`,
1517
+ `${toolName} ${cmd} create ${createFlags}`,
1425
1518
  ],
1426
1519
  },
1427
1520
  ],
@@ -1431,8 +1524,9 @@ function generateMultiTargetSkills(input) {
1431
1524
  for (const op of tgt.customOperations) {
1432
1525
  const kebab = (0, komoji_1.toKebabCase)(op.name);
1433
1526
  const cmd = `${tgt.name}:${kebab}`;
1434
- const baseUsage = op.args.length > 0
1435
- ? `${toolName} ${cmd} ${op.args.map((a) => `--${a.name} <value>`).join(' ')}`
1527
+ const flat = (0, docs_utils_1.flattenArgs)(op.args, registry);
1528
+ const baseUsage = flat.length > 0
1529
+ ? `${toolName} ${cmd} ${(0, docs_utils_1.flattenedArgsToFlags)(flat)}`
1436
1530
  : `${toolName} ${cmd}`;
1437
1531
  const usageLines = [baseUsage];
1438
1532
  if (tgt.isAuthTarget && op.kind === 'mutation') {
@@ -1468,12 +1562,21 @@ function generateMultiTargetSkills(input) {
1468
1562
  `${toolName} ${tgt.name}:${firstKebab} list`,
1469
1563
  `${toolName} ${tgt.name}:${firstKebab} get --id <value>`,
1470
1564
  `${toolName} ${tgt.name}:${firstKebab} create --<field> <value>`,
1565
+ '',
1566
+ `# Non-interactive mode (skip all prompts, use flags only)`,
1567
+ `${toolName} --no-tty ${tgt.name}:${firstKebab} list`,
1471
1568
  ],
1472
1569
  examples: [
1473
1570
  {
1474
1571
  description: `Query ${tgt.name} records`,
1475
1572
  code: [`${toolName} ${tgt.name}:${firstKebab} list`],
1476
1573
  },
1574
+ {
1575
+ description: 'Non-interactive mode (for scripts and CI)',
1576
+ code: [
1577
+ `${toolName} --no-tty ${tgt.name}:${firstKebab} create --<field> <value>`,
1578
+ ],
1579
+ },
1477
1580
  ],
1478
1581
  }, tgtReferenceNames),
1479
1582
  });
@@ -1,5 +1,20 @@
1
1
  import type { CleanTable, TypeRegistry } from '../../../types/schema';
2
2
  import type { GeneratedFile } from './executor-generator';
3
+ /**
4
+ * Get the set of field names that have defaults in the create input type.
5
+ * Looks up the CreateXInput -> inner input type (e.g. DatabaseInput) in the
6
+ * TypeRegistry and checks each field's defaultValue from introspection.
7
+ */
8
+ /**
9
+ * Resolve the inner input type from a CreateXInput or UpdateXInput type.
10
+ * The CreateXInput has an inner field (e.g. "database" of type DatabaseInput)
11
+ * that contains the actual field definitions.
12
+ */
13
+ export declare function resolveInnerInputType(inputTypeName: string, typeRegistry: TypeRegistry): {
14
+ name: string;
15
+ fields: Set<string>;
16
+ } | null;
17
+ export declare function getFieldsWithDefaults(table: CleanTable, typeRegistry?: TypeRegistry): Set<string>;
3
18
  export interface TableCommandOptions {
4
19
  targetName?: string;
5
20
  executorImportPath?: string;
@@ -33,6 +33,8 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.resolveInnerInputType = resolveInnerInputType;
37
+ exports.getFieldsWithDefaults = getFieldsWithDefaults;
36
38
  exports.generateTableCommand = generateTableCommand;
37
39
  const t = __importStar(require("@babel/types"));
38
40
  const komoji_1 = require("komoji");
@@ -103,6 +105,22 @@ function getTsTypeForField(field) {
103
105
  return t.tsStringKeyword();
104
106
  }
105
107
  }
108
+ /**
109
+ * Maps a GraphQL scalar type to the appropriate inquirerer question type.
110
+ * Used by table CRUD commands to generate semantic prompts.
111
+ */
112
+ function getQuestionTypeForField(field) {
113
+ const gqlType = field.type.gqlType.replace(/!/g, '');
114
+ switch (gqlType) {
115
+ case 'Boolean':
116
+ return 'boolean';
117
+ case 'JSON':
118
+ case 'GeoJSON':
119
+ return 'json';
120
+ default:
121
+ return 'text';
122
+ }
123
+ }
106
124
  function buildFieldSchemaObject(table) {
107
125
  const fields = (0, utils_1.getScalarFields)(table);
108
126
  return t.objectExpression(fields.map((f) => {
@@ -342,8 +360,9 @@ function buildMutationHandler(table, operation, targetName, typeRegistry, ormTyp
342
360
  // For update: all fields are optional (user only updates what they want)
343
361
  const isRequired = operation === 'create' && !fieldsWithDefaults.has(field.name);
344
362
  const hasDefault = fieldsWithDefaults.has(field.name);
363
+ const questionType = getQuestionTypeForField(field);
345
364
  const questionProps = [
346
- t.objectProperty(t.identifier('type'), t.stringLiteral('text')),
365
+ t.objectProperty(t.identifier('type'), t.stringLiteral(questionType)),
347
366
  t.objectProperty(t.identifier('name'), t.stringLiteral(field.name)),
348
367
  t.objectProperty(t.identifier('message'), t.stringLiteral(field.name)),
349
368
  t.objectProperty(t.identifier('required'), t.booleanLiteral(isRequired)),