@constructive-io/graphql-codegen 4.7.2 → 4.8.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.
@@ -5,7 +5,7 @@ export type { GeneratedDocFile, McpTool } from '../docs-utils';
5
5
  export declare function generateReadme(tables: CleanTable[], customOperations: CleanOperation[], toolName: string): GeneratedDocFile;
6
6
  export declare function generateAgentsDocs(tables: CleanTable[], customOperations: CleanOperation[], toolName: string): GeneratedDocFile;
7
7
  export declare function getCliMcpTools(tables: CleanTable[], customOperations: CleanOperation[], toolName: string): McpTool[];
8
- export declare function generateSkills(tables: CleanTable[], customOperations: CleanOperation[], toolName: string): GeneratedDocFile[];
8
+ export declare function generateSkills(tables: CleanTable[], customOperations: CleanOperation[], toolName: string, targetName: string): GeneratedDocFile[];
9
9
  export interface MultiTargetDocsInput {
10
10
  toolName: string;
11
11
  builtinNames: {
@@ -525,12 +525,16 @@ function getCliMcpTools(tables, customOperations, toolName) {
525
525
  }
526
526
  return tools;
527
527
  }
528
- function generateSkills(tables, customOperations, toolName) {
528
+ function generateSkills(tables, customOperations, toolName, targetName) {
529
529
  const files = [];
530
+ const skillName = `cli-${targetName}`;
531
+ const referenceNames = [];
532
+ // Context reference
533
+ referenceNames.push('context');
530
534
  files.push({
531
- fileName: 'skills/context.md',
532
- content: (0, docs_utils_1.buildSkillFile)({
533
- name: `${toolName}-context`,
535
+ fileName: `${skillName}/references/context.md`,
536
+ content: (0, docs_utils_1.buildSkillReference)({
537
+ title: 'Context Management',
534
538
  description: `Manage API endpoint contexts for ${toolName}`,
535
539
  usage: [
536
540
  `${toolName} context create <name> --endpoint <url>`,
@@ -554,10 +558,12 @@ function generateSkills(tables, customOperations, toolName) {
554
558
  ],
555
559
  }),
556
560
  });
561
+ // Auth reference
562
+ referenceNames.push('auth');
557
563
  files.push({
558
- fileName: 'skills/auth.md',
559
- content: (0, docs_utils_1.buildSkillFile)({
560
- name: `${toolName}-auth`,
564
+ fileName: `${skillName}/references/auth.md`,
565
+ content: (0, docs_utils_1.buildSkillReference)({
566
+ title: 'Authentication',
561
567
  description: `Manage authentication tokens for ${toolName}`,
562
568
  usage: [
563
569
  `${toolName} auth set-token <token>`,
@@ -576,15 +582,17 @@ function generateSkills(tables, customOperations, toolName) {
576
582
  ],
577
583
  }),
578
584
  });
585
+ // Table references
579
586
  for (const table of tables) {
580
587
  const { singularName } = (0, utils_1.getTableNames)(table);
581
588
  const kebab = (0, komoji_1.toKebabCase)(singularName);
582
589
  const pk = (0, utils_1.getPrimaryKeyInfo)(table)[0];
583
590
  const editableFields = (0, docs_utils_1.getEditableFields)(table);
591
+ referenceNames.push(kebab);
584
592
  files.push({
585
- fileName: `skills/${kebab}.md`,
586
- content: (0, docs_utils_1.buildSkillFile)({
587
- name: `${toolName}-${kebab}`,
593
+ fileName: `${skillName}/references/${kebab}.md`,
594
+ content: (0, docs_utils_1.buildSkillReference)({
595
+ title: singularName,
588
596
  description: `CRUD operations for ${table.name} records via ${toolName} CLI`,
589
597
  usage: [
590
598
  `${toolName} ${kebab} list`,
@@ -608,29 +616,21 @@ function generateSkills(tables, customOperations, toolName) {
608
616
  description: `Get a ${singularName} by ${pk.name}`,
609
617
  code: [`${toolName} ${kebab} get --${pk.name} <value>`],
610
618
  },
611
- {
612
- description: `Update a ${singularName}`,
613
- code: [
614
- `${toolName} ${kebab} update --${pk.name} <value> --${editableFields[0]?.name || 'field'} "new-value"`,
615
- ],
616
- },
617
- {
618
- description: `Delete a ${singularName}`,
619
- code: [`${toolName} ${kebab} delete --${pk.name} <value>`],
620
- },
621
619
  ],
622
620
  }),
623
621
  });
624
622
  }
623
+ // Custom operation references
625
624
  for (const op of customOperations) {
626
625
  const kebab = (0, komoji_1.toKebabCase)(op.name);
627
626
  const usage = op.args.length > 0
628
627
  ? `${toolName} ${kebab} ${op.args.map((a) => `--${a.name} <value>`).join(' ')}`
629
628
  : `${toolName} ${kebab}`;
629
+ referenceNames.push(kebab);
630
630
  files.push({
631
- fileName: `skills/${kebab}.md`,
632
- content: (0, docs_utils_1.buildSkillFile)({
633
- name: `${toolName}-${kebab}`,
631
+ fileName: `${skillName}/references/${kebab}.md`,
632
+ content: (0, docs_utils_1.buildSkillReference)({
633
+ title: op.name,
634
634
  description: op.description || `Execute the ${op.name} ${op.kind}`,
635
635
  usage: [usage],
636
636
  examples: [
@@ -642,6 +642,39 @@ function generateSkills(tables, customOperations, toolName) {
642
642
  }),
643
643
  });
644
644
  }
645
+ // Overview SKILL.md
646
+ const tableKebabs = tables.slice(0, 5).map((t) => (0, komoji_1.toKebabCase)((0, utils_1.getTableNames)(t).singularName));
647
+ files.push({
648
+ fileName: `${skillName}/SKILL.md`,
649
+ content: (0, docs_utils_1.buildSkillFile)({
650
+ name: skillName,
651
+ description: `CLI tool (${toolName}) for the ${targetName} API — provides CRUD commands for ${tables.length} tables and ${customOperations.length} custom operations`,
652
+ usage: [
653
+ `# Context management`,
654
+ `${toolName} context create <name> --endpoint <url>`,
655
+ `${toolName} context use <name>`,
656
+ '',
657
+ `# Authentication`,
658
+ `${toolName} auth set-token <token>`,
659
+ '',
660
+ `# CRUD for any table (e.g. ${tableKebabs[0] || 'model'})`,
661
+ `${toolName} ${tableKebabs[0] || 'model'} list`,
662
+ `${toolName} ${tableKebabs[0] || 'model'} get --id <value>`,
663
+ `${toolName} ${tableKebabs[0] || 'model'} create --<field> <value>`,
664
+ ],
665
+ examples: [
666
+ {
667
+ description: 'Set up and query',
668
+ code: [
669
+ `${toolName} context create local --endpoint http://localhost:5000/graphql`,
670
+ `${toolName} context use local`,
671
+ `${toolName} auth set-token <token>`,
672
+ `${toolName} ${tableKebabs[0] || 'model'} list`,
673
+ ],
674
+ },
675
+ ],
676
+ }, referenceNames),
677
+ });
645
678
  return files;
646
679
  }
647
680
  function generateMultiTargetReadme(input) {
@@ -1268,22 +1301,26 @@ function getMultiTargetCliMcpTools(input) {
1268
1301
  function generateMultiTargetSkills(input) {
1269
1302
  const { toolName, builtinNames, targets } = input;
1270
1303
  const files = [];
1271
- const contextUsage = [
1272
- `${toolName} ${builtinNames.context} create <name>`,
1273
- `${toolName} ${builtinNames.context} list`,
1274
- `${toolName} ${builtinNames.context} use <name>`,
1275
- `${toolName} ${builtinNames.context} current`,
1276
- `${toolName} ${builtinNames.context} delete <name>`,
1277
- ];
1304
+ // Generate one skill per target, plus a shared cli-common skill for context/auth
1305
+ const commonSkillName = 'cli-common';
1306
+ const commonReferenceNames = [];
1278
1307
  const contextCreateFlags = targets
1279
1308
  .map((t) => `--${t.name}-endpoint <url>`)
1280
1309
  .join(' ');
1310
+ // Context reference
1311
+ commonReferenceNames.push('context');
1281
1312
  files.push({
1282
- fileName: `skills/${builtinNames.context}.md`,
1283
- content: (0, docs_utils_1.buildSkillFile)({
1284
- name: `${toolName}-${builtinNames.context}`,
1313
+ fileName: `${commonSkillName}/references/context.md`,
1314
+ content: (0, docs_utils_1.buildSkillReference)({
1315
+ title: 'Context Management',
1285
1316
  description: `Manage API endpoint contexts for ${toolName} (multi-target: ${targets.map((t) => t.name).join(', ')})`,
1286
- usage: contextUsage,
1317
+ usage: [
1318
+ `${toolName} ${builtinNames.context} create <name>`,
1319
+ `${toolName} ${builtinNames.context} list`,
1320
+ `${toolName} ${builtinNames.context} use <name>`,
1321
+ `${toolName} ${builtinNames.context} current`,
1322
+ `${toolName} ${builtinNames.context} delete <name>`,
1323
+ ],
1287
1324
  examples: [
1288
1325
  {
1289
1326
  description: 'Create a context for local development (accept all defaults)',
@@ -1299,20 +1336,15 @@ function generateMultiTargetSkills(input) {
1299
1336
  `${toolName} ${builtinNames.context} use production`,
1300
1337
  ],
1301
1338
  },
1302
- {
1303
- description: 'List and switch contexts',
1304
- code: [
1305
- `${toolName} ${builtinNames.context} list`,
1306
- `${toolName} ${builtinNames.context} use staging`,
1307
- ],
1308
- },
1309
1339
  ],
1310
1340
  }),
1311
1341
  });
1342
+ // Auth reference
1343
+ commonReferenceNames.push('auth');
1312
1344
  files.push({
1313
- fileName: `skills/${builtinNames.auth}.md`,
1314
- content: (0, docs_utils_1.buildSkillFile)({
1315
- name: `${toolName}-${builtinNames.auth}`,
1345
+ fileName: `${commonSkillName}/references/auth.md`,
1346
+ content: (0, docs_utils_1.buildSkillReference)({
1347
+ title: 'Authentication',
1316
1348
  description: `Manage authentication tokens for ${toolName} (shared across all targets)`,
1317
1349
  usage: [
1318
1350
  `${toolName} ${builtinNames.auth} set-token <token>`,
@@ -1331,17 +1363,48 @@ function generateMultiTargetSkills(input) {
1331
1363
  ],
1332
1364
  }),
1333
1365
  });
1366
+ // Common SKILL.md
1367
+ files.push({
1368
+ fileName: `${commonSkillName}/SKILL.md`,
1369
+ content: (0, docs_utils_1.buildSkillFile)({
1370
+ name: commonSkillName,
1371
+ description: `Shared CLI utilities for ${toolName} — context management and authentication across targets: ${targets.map((t) => t.name).join(', ')}`,
1372
+ usage: [
1373
+ `# Context management`,
1374
+ `${toolName} ${builtinNames.context} create <name>`,
1375
+ `${toolName} ${builtinNames.context} use <name>`,
1376
+ '',
1377
+ `# Authentication`,
1378
+ `${toolName} ${builtinNames.auth} set-token <token>`,
1379
+ `${toolName} ${builtinNames.auth} status`,
1380
+ ],
1381
+ examples: [
1382
+ {
1383
+ description: 'Set up and authenticate',
1384
+ code: [
1385
+ `${toolName} ${builtinNames.context} create local`,
1386
+ `${toolName} ${builtinNames.context} use local`,
1387
+ `${toolName} ${builtinNames.auth} set-token <token>`,
1388
+ ],
1389
+ },
1390
+ ],
1391
+ }, commonReferenceNames),
1392
+ });
1393
+ // Generate one skill per target with table/op references
1334
1394
  for (const tgt of targets) {
1395
+ const tgtSkillName = `cli-${tgt.name}`;
1396
+ const tgtReferenceNames = [];
1335
1397
  for (const table of tgt.tables) {
1336
1398
  const { singularName } = (0, utils_1.getTableNames)(table);
1337
1399
  const kebab = (0, komoji_1.toKebabCase)(singularName);
1338
1400
  const pk = (0, utils_1.getPrimaryKeyInfo)(table)[0];
1339
1401
  const editableFields = (0, docs_utils_1.getEditableFields)(table);
1340
1402
  const cmd = `${tgt.name}:${kebab}`;
1403
+ tgtReferenceNames.push(kebab);
1341
1404
  files.push({
1342
- fileName: `skills/${tgt.name}-${kebab}.md`,
1343
- content: (0, docs_utils_1.buildSkillFile)({
1344
- name: `${toolName}-${cmd}`,
1405
+ fileName: `${tgtSkillName}/references/${kebab}.md`,
1406
+ content: (0, docs_utils_1.buildSkillReference)({
1407
+ title: singularName,
1345
1408
  description: `CRUD operations for ${table.name} records via ${toolName} CLI (${tgt.name} target)`,
1346
1409
  usage: [
1347
1410
  `${toolName} ${cmd} list`,
@@ -1361,10 +1424,6 @@ function generateMultiTargetSkills(input) {
1361
1424
  `${toolName} ${cmd} create ${editableFields.map((f) => `--${f.name} "value"`).join(' ')}`,
1362
1425
  ],
1363
1426
  },
1364
- {
1365
- description: `Get a ${singularName} by ${pk.name}`,
1366
- code: [`${toolName} ${cmd} get --${pk.name} <value>`],
1367
- },
1368
1427
  ],
1369
1428
  }),
1370
1429
  });
@@ -1379,10 +1438,11 @@ function generateMultiTargetSkills(input) {
1379
1438
  if (tgt.isAuthTarget && op.kind === 'mutation') {
1380
1439
  usageLines.push(`${baseUsage} --save-token`);
1381
1440
  }
1441
+ tgtReferenceNames.push(kebab);
1382
1442
  files.push({
1383
- fileName: `skills/${tgt.name}-${kebab}.md`,
1384
- content: (0, docs_utils_1.buildSkillFile)({
1385
- name: `${toolName}-${cmd}`,
1443
+ fileName: `${tgtSkillName}/references/${kebab}.md`,
1444
+ content: (0, docs_utils_1.buildSkillReference)({
1445
+ title: op.name,
1386
1446
  description: `${op.description || `Execute the ${op.name} ${op.kind}`} (${tgt.name} target)`,
1387
1447
  usage: usageLines,
1388
1448
  examples: [
@@ -1394,6 +1454,29 @@ function generateMultiTargetSkills(input) {
1394
1454
  }),
1395
1455
  });
1396
1456
  }
1457
+ // Target SKILL.md
1458
+ const firstKebab = tgt.tables.length > 0
1459
+ ? (0, komoji_1.toKebabCase)((0, utils_1.getTableNames)(tgt.tables[0]).singularName)
1460
+ : 'model';
1461
+ files.push({
1462
+ fileName: `${tgtSkillName}/SKILL.md`,
1463
+ content: (0, docs_utils_1.buildSkillFile)({
1464
+ name: tgtSkillName,
1465
+ description: `CLI commands for the ${tgt.name} API target — ${tgt.tables.length} tables and ${tgt.customOperations.length} custom operations via ${toolName}`,
1466
+ usage: [
1467
+ `# CRUD for ${tgt.name} tables (e.g. ${firstKebab})`,
1468
+ `${toolName} ${tgt.name}:${firstKebab} list`,
1469
+ `${toolName} ${tgt.name}:${firstKebab} get --id <value>`,
1470
+ `${toolName} ${tgt.name}:${firstKebab} create --<field> <value>`,
1471
+ ],
1472
+ examples: [
1473
+ {
1474
+ description: `Query ${tgt.name} records`,
1475
+ code: [`${toolName} ${tgt.name}:${firstKebab} list`],
1476
+ },
1477
+ ],
1478
+ }, tgtReferenceNames),
1479
+ });
1397
1480
  }
1398
1481
  return files;
1399
1482
  }
@@ -20,6 +20,16 @@ export interface SkillDefinition {
20
20
  }[];
21
21
  language?: string;
22
22
  }
23
+ export interface SkillReferenceDefinition {
24
+ title: string;
25
+ description: string;
26
+ usage: string[];
27
+ examples: {
28
+ description: string;
29
+ code: string[];
30
+ }[];
31
+ language?: string;
32
+ }
23
33
  export declare function getReadmeHeader(title: string): string[];
24
34
  export declare function getReadmeFooter(): string[];
25
35
  export declare function resolveDocsConfig(docs: DocsConfig | boolean | undefined): DocsConfig;
@@ -27,4 +37,5 @@ export declare function formatArgType(arg: CleanOperation['args'][number]): stri
27
37
  export declare function formatTypeRef(t: CleanOperation['args'][number]['type']): string;
28
38
  export declare function getEditableFields(table: CleanTable): CleanField[];
29
39
  export declare function gqlTypeToJsonSchemaType(gqlType: string): string;
30
- export declare function buildSkillFile(skill: SkillDefinition): string;
40
+ export declare function buildSkillFile(skill: SkillDefinition, referenceNames?: string[]): string;
41
+ export declare function buildSkillReference(ref: SkillReferenceDefinition): string;
@@ -8,6 +8,7 @@ exports.formatTypeRef = formatTypeRef;
8
8
  exports.getEditableFields = getEditableFields;
9
9
  exports.gqlTypeToJsonSchemaType = gqlTypeToJsonSchemaType;
10
10
  exports.buildSkillFile = buildSkillFile;
11
+ exports.buildSkillReference = buildSkillReference;
11
12
  const utils_1 = require("./utils");
12
13
  const CONSTRUCTIVE_LOGO_URL = 'https://raw.githubusercontent.com/constructive-io/constructive/refs/heads/main/assets/outline-logo.svg';
13
14
  const CONSTRUCTIVE_REPO = 'https://github.com/constructive-io/constructive';
@@ -89,9 +90,15 @@ function gqlTypeToJsonSchemaType(gqlType) {
89
90
  return 'string';
90
91
  }
91
92
  }
92
- function buildSkillFile(skill) {
93
+ function buildSkillFile(skill, referenceNames) {
93
94
  const lang = skill.language ?? 'bash';
94
95
  const lines = [];
96
+ // YAML frontmatter (Agent Skills format)
97
+ lines.push('---');
98
+ lines.push(`name: ${skill.name}`);
99
+ lines.push(`description: ${skill.description}`);
100
+ lines.push('---');
101
+ lines.push('');
95
102
  lines.push(`# ${skill.name}`);
96
103
  lines.push('');
97
104
  lines.push('<!-- @constructive-io/graphql-codegen - DO NOT EDIT -->');
@@ -118,5 +125,46 @@ function buildSkillFile(skill) {
118
125
  lines.push('```');
119
126
  lines.push('');
120
127
  }
128
+ if (referenceNames && referenceNames.length > 0) {
129
+ lines.push('## References');
130
+ lines.push('');
131
+ lines.push('See the `references/` directory for detailed per-entity API documentation:');
132
+ lines.push('');
133
+ for (const name of referenceNames) {
134
+ lines.push(`- [${name}](references/${name}.md)`);
135
+ }
136
+ lines.push('');
137
+ }
138
+ return lines.join('\n');
139
+ }
140
+ function buildSkillReference(ref) {
141
+ const lang = ref.language ?? 'bash';
142
+ const lines = [];
143
+ lines.push(`# ${ref.title}`);
144
+ lines.push('');
145
+ lines.push('<!-- @constructive-io/graphql-codegen - DO NOT EDIT -->');
146
+ lines.push('');
147
+ lines.push(ref.description);
148
+ lines.push('');
149
+ lines.push('## Usage');
150
+ lines.push('');
151
+ lines.push(`\`\`\`${lang}`);
152
+ for (const u of ref.usage) {
153
+ lines.push(u);
154
+ }
155
+ lines.push('```');
156
+ lines.push('');
157
+ lines.push('## Examples');
158
+ lines.push('');
159
+ for (const ex of ref.examples) {
160
+ lines.push(`### ${ex.description}`);
161
+ lines.push('');
162
+ lines.push(`\`\`\`${lang}`);
163
+ for (const cmd of ex.code) {
164
+ lines.push(cmd);
165
+ }
166
+ lines.push('```');
167
+ lines.push('');
168
+ }
121
169
  return lines.join('\n');
122
170
  }
@@ -3,4 +3,4 @@ import type { GeneratedDocFile, McpTool } from './docs-utils';
3
3
  export declare function generateHooksReadme(tables: CleanTable[], customOperations: CleanOperation[]): GeneratedDocFile;
4
4
  export declare function generateHooksAgentsDocs(tables: CleanTable[], customOperations: CleanOperation[]): GeneratedDocFile;
5
5
  export declare function getHooksMcpTools(tables: CleanTable[], customOperations: CleanOperation[]): McpTool[];
6
- export declare function generateHooksSkills(tables: CleanTable[], customOperations: CleanOperation[]): GeneratedDocFile[];
6
+ export declare function generateHooksSkills(tables: CleanTable[], customOperations: CleanOperation[], targetName: string): GeneratedDocFile[];
@@ -4,6 +4,7 @@ exports.generateHooksReadme = generateHooksReadme;
4
4
  exports.generateHooksAgentsDocs = generateHooksAgentsDocs;
5
5
  exports.getHooksMcpTools = getHooksMcpTools;
6
6
  exports.generateHooksSkills = generateHooksSkills;
7
+ const komoji_1 = require("komoji");
7
8
  const docs_utils_1 = require("./docs-utils");
8
9
  const utils_1 = require("./utils");
9
10
  function getCustomHookName(op) {
@@ -377,8 +378,11 @@ function getHooksMcpTools(tables, customOperations) {
377
378
  }
378
379
  return tools;
379
380
  }
380
- function generateHooksSkills(tables, customOperations) {
381
+ function generateHooksSkills(tables, customOperations, targetName) {
381
382
  const files = [];
383
+ const skillName = `hooks-${targetName}`;
384
+ const referenceNames = [];
385
+ // Generate reference files for each table
382
386
  for (const table of tables) {
383
387
  const { singularName, pluralName } = (0, utils_1.getTableNames)(table);
384
388
  const pk = (0, utils_1.getPrimaryKeyInfo)(table)[0];
@@ -386,10 +390,12 @@ function generateHooksSkills(tables, customOperations) {
386
390
  const selectFields = scalarFields
387
391
  .map((f) => `${f.name}: true`)
388
392
  .join(', ');
393
+ const refName = (0, komoji_1.toKebabCase)(singularName);
394
+ referenceNames.push(refName);
389
395
  files.push({
390
- fileName: `skills/${(0, utils_1.lcFirst)(singularName)}.md`,
391
- content: (0, docs_utils_1.buildSkillFile)({
392
- name: `hooks-${(0, utils_1.lcFirst)(singularName)}`,
396
+ fileName: `${skillName}/references/${refName}.md`,
397
+ content: (0, docs_utils_1.buildSkillReference)({
398
+ title: singularName,
393
399
  description: table.description || `React Query hooks for ${table.name} data operations`,
394
400
  language: 'typescript',
395
401
  usage: [
@@ -429,15 +435,18 @@ function generateHooksSkills(tables, customOperations) {
429
435
  }),
430
436
  });
431
437
  }
438
+ // Generate reference files for custom operations
432
439
  for (const op of customOperations) {
433
440
  const hookName = getCustomHookName(op);
434
441
  const callArgs = op.args.length > 0
435
442
  ? `{ ${op.args.map((a) => `${a.name}: '<value>'`).join(', ')} }`
436
443
  : '';
444
+ const refName = (0, komoji_1.toKebabCase)(op.name);
445
+ referenceNames.push(refName);
437
446
  files.push({
438
- fileName: `skills/${op.name}.md`,
439
- content: (0, docs_utils_1.buildSkillFile)({
440
- name: `hooks-${op.name}`,
447
+ fileName: `${skillName}/references/${refName}.md`,
448
+ content: (0, docs_utils_1.buildSkillReference)({
449
+ title: op.name,
441
450
  description: op.description ||
442
451
  `React Query ${op.kind} hook for ${op.name}`,
443
452
  language: 'typescript',
@@ -464,5 +473,36 @@ function generateHooksSkills(tables, customOperations) {
464
473
  }),
465
474
  });
466
475
  }
476
+ // Generate the overview SKILL.md
477
+ const hookExamples = tables.slice(0, 3).map((t) => (0, utils_1.getListQueryHookName)(t));
478
+ files.push({
479
+ fileName: `${skillName}/SKILL.md`,
480
+ content: (0, docs_utils_1.buildSkillFile)({
481
+ name: skillName,
482
+ description: `React Query hooks for the ${targetName} API — provides typed query and mutation hooks for ${tables.length} tables and ${customOperations.length} custom operations`,
483
+ language: 'typescript',
484
+ usage: [
485
+ `// Import hooks`,
486
+ `import { ${hookExamples[0] || 'useModelQuery'} } from './hooks';`,
487
+ '',
488
+ `// Query hooks: use<Model>Query, use<Model>sQuery`,
489
+ `// Mutation hooks: useCreate<Model>Mutation, useUpdate<Model>Mutation, useDelete<Model>Mutation`,
490
+ '',
491
+ `const { data, isLoading } = ${hookExamples[0] || 'useModelQuery'}({`,
492
+ ` selection: { fields: { id: true } },`,
493
+ `});`,
494
+ ],
495
+ examples: [
496
+ {
497
+ description: 'Query records',
498
+ code: [
499
+ `const { data, isLoading } = ${hookExamples[0] || 'useModelQuery'}({`,
500
+ ' selection: { fields: { id: true } },',
501
+ '});',
502
+ ],
503
+ },
504
+ ],
505
+ }, referenceNames),
506
+ });
467
507
  return files;
468
508
  }
@@ -3,4 +3,4 @@ import type { GeneratedDocFile, McpTool } from '../docs-utils';
3
3
  export declare function generateOrmReadme(tables: CleanTable[], customOperations: CleanOperation[]): GeneratedDocFile;
4
4
  export declare function generateOrmAgentsDocs(tables: CleanTable[], customOperations: CleanOperation[]): GeneratedDocFile;
5
5
  export declare function getOrmMcpTools(tables: CleanTable[], customOperations: CleanOperation[]): McpTool[];
6
- export declare function generateOrmSkills(tables: CleanTable[], customOperations: CleanOperation[]): GeneratedDocFile[];
6
+ export declare function generateOrmSkills(tables: CleanTable[], customOperations: CleanOperation[], targetName: string): GeneratedDocFile[];
@@ -4,6 +4,7 @@ exports.generateOrmReadme = generateOrmReadme;
4
4
  exports.generateOrmAgentsDocs = generateOrmAgentsDocs;
5
5
  exports.getOrmMcpTools = getOrmMcpTools;
6
6
  exports.generateOrmSkills = generateOrmSkills;
7
+ const komoji_1 = require("komoji");
7
8
  const docs_utils_1 = require("../docs-utils");
8
9
  const utils_1 = require("../utils");
9
10
  function generateOrmReadme(tables, customOperations) {
@@ -346,30 +347,36 @@ function getOrmMcpTools(tables, customOperations) {
346
347
  }
347
348
  return tools;
348
349
  }
349
- function generateOrmSkills(tables, customOperations) {
350
+ function generateOrmSkills(tables, customOperations, targetName) {
350
351
  const files = [];
352
+ const skillName = `orm-${targetName}`;
353
+ const referenceNames = [];
354
+ // Generate reference files for each table
351
355
  for (const table of tables) {
352
356
  const { singularName } = (0, utils_1.getTableNames)(table);
353
357
  const pk = (0, utils_1.getPrimaryKeyInfo)(table)[0];
354
358
  const editableFields = (0, docs_utils_1.getEditableFields)(table);
359
+ const modelName = (0, utils_1.lcFirst)(singularName);
360
+ const refName = (0, komoji_1.toKebabCase)(singularName);
361
+ referenceNames.push(refName);
355
362
  files.push({
356
- fileName: `skills/${(0, utils_1.lcFirst)(singularName)}.md`,
357
- content: (0, docs_utils_1.buildSkillFile)({
358
- name: `orm-${(0, utils_1.lcFirst)(singularName)}`,
363
+ fileName: `${skillName}/references/${refName}.md`,
364
+ content: (0, docs_utils_1.buildSkillReference)({
365
+ title: singularName,
359
366
  description: table.description || `ORM operations for ${table.name} records`,
360
367
  language: 'typescript',
361
368
  usage: [
362
- `db.${(0, utils_1.lcFirst)(singularName)}.findMany({ select: { id: true } }).execute()`,
363
- `db.${(0, utils_1.lcFirst)(singularName)}.findOne({ ${pk.name}: '<value>', select: { id: true } }).execute()`,
364
- `db.${(0, utils_1.lcFirst)(singularName)}.create({ data: { ${editableFields.map((f) => `${f.name}: '<value>'`).join(', ')} }, select: { id: true } }).execute()`,
365
- `db.${(0, utils_1.lcFirst)(singularName)}.update({ where: { ${pk.name}: '<value>' }, data: { ${editableFields[0]?.name || 'field'}: '<new>' }, select: { id: true } }).execute()`,
366
- `db.${(0, utils_1.lcFirst)(singularName)}.delete({ where: { ${pk.name}: '<value>' } }).execute()`,
369
+ `db.${modelName}.findMany({ select: { id: true } }).execute()`,
370
+ `db.${modelName}.findOne({ ${pk.name}: '<value>', select: { id: true } }).execute()`,
371
+ `db.${modelName}.create({ data: { ${editableFields.map((f) => `${f.name}: '<value>'`).join(', ')} }, select: { id: true } }).execute()`,
372
+ `db.${modelName}.update({ where: { ${pk.name}: '<value>' }, data: { ${editableFields[0]?.name || 'field'}: '<new>' }, select: { id: true } }).execute()`,
373
+ `db.${modelName}.delete({ where: { ${pk.name}: '<value>' } }).execute()`,
367
374
  ],
368
375
  examples: [
369
376
  {
370
377
  description: `List all ${singularName} records`,
371
378
  code: [
372
- `const items = await db.${(0, utils_1.lcFirst)(singularName)}.findMany({`,
379
+ `const items = await db.${modelName}.findMany({`,
373
380
  ` select: { ${pk.name}: true, ${editableFields[0]?.name || 'name'}: true }`,
374
381
  '}).execute();',
375
382
  ],
@@ -377,7 +384,7 @@ function generateOrmSkills(tables, customOperations) {
377
384
  {
378
385
  description: `Create a ${singularName}`,
379
386
  code: [
380
- `const item = await db.${(0, utils_1.lcFirst)(singularName)}.create({`,
387
+ `const item = await db.${modelName}.create({`,
381
388
  ` data: { ${editableFields.map((f) => `${f.name}: 'value'`).join(', ')} },`,
382
389
  ` select: { ${pk.name}: true }`,
383
390
  '}).execute();',
@@ -387,30 +394,60 @@ function generateOrmSkills(tables, customOperations) {
387
394
  }),
388
395
  });
389
396
  }
397
+ // Generate reference files for custom operations
390
398
  for (const op of customOperations) {
391
399
  const accessor = op.kind === 'query' ? 'query' : 'mutation';
392
400
  const callArgs = op.args.length > 0
393
401
  ? `{ ${op.args.map((a) => `${a.name}: '<value>'`).join(', ')} }`
394
402
  : '';
403
+ const refName = (0, komoji_1.toKebabCase)(op.name);
404
+ referenceNames.push(refName);
395
405
  files.push({
396
- fileName: `skills/${op.name}.md`,
397
- content: (0, docs_utils_1.buildSkillFile)({
398
- name: `orm-${op.name}`,
406
+ fileName: `${skillName}/references/${refName}.md`,
407
+ content: (0, docs_utils_1.buildSkillReference)({
408
+ title: op.name,
399
409
  description: op.description || `Execute the ${op.name} ${op.kind}`,
400
410
  language: 'typescript',
401
- usage: [
402
- `db.${accessor}.${op.name}(${callArgs}).execute()`,
403
- ],
411
+ usage: [`db.${accessor}.${op.name}(${callArgs}).execute()`],
404
412
  examples: [
405
413
  {
406
414
  description: `Run ${op.name}`,
407
- code: [
408
- `const result = await db.${accessor}.${op.name}(${callArgs}).execute();`,
409
- ],
415
+ code: [`const result = await db.${accessor}.${op.name}(${callArgs}).execute();`],
410
416
  },
411
417
  ],
412
418
  }),
413
419
  });
414
420
  }
421
+ // Generate the overview SKILL.md
422
+ const tableNames = tables.map((t) => (0, utils_1.lcFirst)((0, utils_1.getTableNames)(t).singularName));
423
+ files.push({
424
+ fileName: `${skillName}/SKILL.md`,
425
+ content: (0, docs_utils_1.buildSkillFile)({
426
+ name: skillName,
427
+ description: `ORM client for the ${targetName} API — provides typed CRUD operations for ${tables.length} tables and ${customOperations.length} custom operations`,
428
+ language: 'typescript',
429
+ usage: [
430
+ `// Import the ORM client`,
431
+ `import { db } from './orm';`,
432
+ '',
433
+ `// Available models: ${tableNames.slice(0, 8).join(', ')}${tableNames.length > 8 ? ', ...' : ''}`,
434
+ `db.<model>.findMany({ select: { id: true } }).execute()`,
435
+ `db.<model>.findOne({ id: '<value>', select: { id: true } }).execute()`,
436
+ `db.<model>.create({ data: { ... }, select: { id: true } }).execute()`,
437
+ `db.<model>.update({ where: { id: '<value>' }, data: { ... }, select: { id: true } }).execute()`,
438
+ `db.<model>.delete({ where: { id: '<value>' } }).execute()`,
439
+ ],
440
+ examples: [
441
+ {
442
+ description: 'Query records',
443
+ code: [
444
+ `const items = await db.${tableNames[0] || 'model'}.findMany({`,
445
+ ' select: { id: true }',
446
+ '}).execute();',
447
+ ],
448
+ },
449
+ ],
450
+ }, referenceNames),
451
+ });
415
452
  return files;
416
453
  }
@@ -33,6 +33,11 @@ export interface GenerateResult {
33
33
  */
34
34
  export interface GenerateInternalOptions {
35
35
  skipCli?: boolean;
36
+ /**
37
+ * Internal-only name for the target when generating skills.
38
+ * Used by generateMulti() so skill names are stable and composable.
39
+ */
40
+ targetName?: string;
36
41
  }
37
42
  export declare function generate(options?: GenerateOptions, internalOptions?: GenerateInternalOptions): Promise<GenerateResult>;
38
43
  export declare function expandApiNamesToMultiTarget(config: GraphQLSDKConfigTarget): Record<string, GraphQLSDKConfigTarget> | null;