@constructive-io/graphql-codegen 4.13.0 → 4.13.1

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.
@@ -11,6 +11,7 @@ export interface MultiTargetDocsInput {
11
11
  builtinNames: {
12
12
  auth: string;
13
13
  context: string;
14
+ config: string;
14
15
  };
15
16
  registry?: TypeRegistry;
16
17
  targets: Array<{
@@ -37,6 +37,7 @@ function generateReadme(tables, customOperations, toolName, registry) {
37
37
  lines.push('|---------|-------------|');
38
38
  lines.push('| `context` | Manage API contexts (endpoints) |');
39
39
  lines.push('| `auth` | Manage authentication tokens |');
40
+ lines.push('| `config` | Manage config key-value store (per-context) |');
40
41
  for (const table of tables) {
41
42
  const { singularName } = (0, utils_1.getTableNames)(table);
42
43
  const kebab = (0, komoji_1.toKebabCase)(singularName);
@@ -73,6 +74,19 @@ function generateReadme(tables, customOperations, toolName, registry) {
73
74
  lines.push('| `status` | Show auth status across all contexts |');
74
75
  lines.push('| `logout` | Remove credentials for current context |');
75
76
  lines.push('');
77
+ lines.push('### `config`');
78
+ lines.push('');
79
+ lines.push('Manage per-context key-value configuration variables.');
80
+ lines.push('');
81
+ lines.push('| Subcommand | Description |');
82
+ lines.push('|------------|-------------|');
83
+ lines.push('| `get <key>` | Get a config value |');
84
+ lines.push('| `set <key> <value>` | Set a config value |');
85
+ lines.push('| `list` | List all config values |');
86
+ lines.push('| `delete <key>` | Delete a config value |');
87
+ lines.push('');
88
+ lines.push(`Variables are scoped to the active context and stored at \`~/.${toolName}/config/\`.`);
89
+ lines.push('');
76
90
  if (tables.length > 0) {
77
91
  lines.push('## Table Commands');
78
92
  lines.push('');
@@ -233,6 +247,28 @@ function generateAgentsDocs(tables, customOperations, toolName, registry) {
233
247
  lines.push(' logout: { context, status: "logged out" }');
234
248
  lines.push('```');
235
249
  lines.push('');
250
+ lines.push('### TOOL: config');
251
+ lines.push('');
252
+ lines.push('Manage per-context key-value configuration variables.');
253
+ lines.push('');
254
+ lines.push('```');
255
+ lines.push('SUBCOMMANDS:');
256
+ lines.push(` ${toolName} config get <key> Get a config value`);
257
+ lines.push(` ${toolName} config set <key> <value> Set a config value`);
258
+ lines.push(` ${toolName} config list List all config values`);
259
+ lines.push(` ${toolName} config delete <key> Delete a config value`);
260
+ lines.push('');
261
+ lines.push('INPUT:');
262
+ lines.push(' key: string (required for get/set/delete) - Variable name');
263
+ lines.push(' value: string (required for set) - Variable value');
264
+ lines.push('');
265
+ lines.push('OUTPUT: JSON');
266
+ lines.push(' get: { key, value }');
267
+ lines.push(' set: { key, value }');
268
+ lines.push(' list: { vars: { key: value, ... } }');
269
+ lines.push(' delete: { deleted: key }');
270
+ lines.push('```');
271
+ lines.push('');
236
272
  for (const table of tables) {
237
273
  const { singularName } = (0, utils_1.getTableNames)(table);
238
274
  const kebab = (0, komoji_1.toKebabCase)(singularName);
@@ -440,6 +476,45 @@ function getCliMcpTools(tables, customOperations, toolName, registry) {
440
476
  description: 'Remove credentials for the current context',
441
477
  inputSchema: { type: 'object', properties: {} },
442
478
  });
479
+ tools.push({
480
+ name: `${toolName}_config_get`,
481
+ description: 'Get a config variable value for the current context',
482
+ inputSchema: {
483
+ type: 'object',
484
+ properties: {
485
+ key: { type: 'string', description: 'Variable name' },
486
+ },
487
+ required: ['key'],
488
+ },
489
+ });
490
+ tools.push({
491
+ name: `${toolName}_config_set`,
492
+ description: 'Set a config variable value for the current context',
493
+ inputSchema: {
494
+ type: 'object',
495
+ properties: {
496
+ key: { type: 'string', description: 'Variable name' },
497
+ value: { type: 'string', description: 'Variable value' },
498
+ },
499
+ required: ['key', 'value'],
500
+ },
501
+ });
502
+ tools.push({
503
+ name: `${toolName}_config_list`,
504
+ description: 'List all config variables for the current context',
505
+ inputSchema: { type: 'object', properties: {} },
506
+ });
507
+ tools.push({
508
+ name: `${toolName}_config_delete`,
509
+ description: 'Delete a config variable for the current context',
510
+ inputSchema: {
511
+ type: 'object',
512
+ properties: {
513
+ key: { type: 'string', description: 'Variable name to delete' },
514
+ },
515
+ required: ['key'],
516
+ },
517
+ });
443
518
  for (const table of tables) {
444
519
  const { singularName } = (0, utils_1.getTableNames)(table);
445
520
  const kebab = (0, komoji_1.toKebabCase)(singularName);
@@ -617,6 +692,34 @@ function generateSkills(tables, customOperations, toolName, targetName, registry
617
692
  ],
618
693
  }),
619
694
  });
695
+ // Config reference
696
+ referenceNames.push('config');
697
+ files.push({
698
+ fileName: `${skillName}/references/config.md`,
699
+ content: (0, docs_utils_1.buildSkillReference)({
700
+ title: 'Config Variables',
701
+ description: `Manage per-context key-value configuration variables for ${toolName}`,
702
+ usage: [
703
+ `${toolName} config get <key>`,
704
+ `${toolName} config set <key> <value>`,
705
+ `${toolName} config list`,
706
+ `${toolName} config delete <key>`,
707
+ ],
708
+ examples: [
709
+ {
710
+ description: 'Store and retrieve a config variable',
711
+ code: [
712
+ `${toolName} config set orgId abc-123`,
713
+ `${toolName} config get orgId`,
714
+ ],
715
+ },
716
+ {
717
+ description: 'List all config variables',
718
+ code: [`${toolName} config list`],
719
+ },
720
+ ],
721
+ }),
722
+ });
620
723
  // Table references
621
724
  for (const table of tables) {
622
725
  const { singularName } = (0, utils_1.getTableNames)(table);
@@ -698,6 +801,10 @@ function generateSkills(tables, customOperations, toolName, targetName, registry
698
801
  `# Authentication`,
699
802
  `${toolName} auth set-token <token>`,
700
803
  '',
804
+ `# Config variables`,
805
+ `${toolName} config set <key> <value>`,
806
+ `${toolName} config get <key>`,
807
+ '',
701
808
  `# CRUD for any table (e.g. ${tableKebabs[0] || 'model'})`,
702
809
  `${toolName} ${tableKebabs[0] || 'model'} list`,
703
810
  `${toolName} ${tableKebabs[0] || 'model'} get --id <value>`,
@@ -793,6 +900,7 @@ function generateMultiTargetReadme(input) {
793
900
  lines.push('|---------|-------------|');
794
901
  lines.push(`| \`${builtinNames.context}\` | Manage API contexts (per-target endpoints) |`);
795
902
  lines.push(`| \`${builtinNames.auth}\` | Manage authentication tokens |`);
903
+ lines.push(`| \`${builtinNames.config}\` | Manage config key-value store (per-context) |`);
796
904
  lines.push('');
797
905
  for (const tgt of targets) {
798
906
  lines.push(`### ${tgt.name}`);
@@ -842,6 +950,40 @@ function generateMultiTargetReadme(input) {
842
950
  lines.push('| `status` | Show auth status across all contexts |');
843
951
  lines.push('| `logout` | Remove credentials for current context |');
844
952
  lines.push('');
953
+ lines.push(`### \`${builtinNames.config}\``);
954
+ lines.push('');
955
+ lines.push('Manage per-context key-value configuration variables.');
956
+ lines.push('');
957
+ lines.push('| Subcommand | Description |');
958
+ lines.push('|------------|-------------|');
959
+ lines.push('| `get <key>` | Get a config value |');
960
+ lines.push('| `set <key> <value>` | Set a config value |');
961
+ lines.push('| `list` | List all config values |');
962
+ lines.push('| `delete <key>` | Delete a config value |');
963
+ lines.push('');
964
+ lines.push(`Variables are scoped to the active context and stored at \`~/.${toolName}/config/\`.`);
965
+ lines.push('');
966
+ lines.push('## SDK Helpers');
967
+ lines.push('');
968
+ lines.push('The generated `helpers.ts` provides typed client factories for use in scripts and services:');
969
+ lines.push('');
970
+ lines.push('```typescript');
971
+ for (const tgt of targets) {
972
+ const pascalName = tgt.name.charAt(0).toUpperCase() + tgt.name.slice(1);
973
+ lines.push(`import { create${pascalName}Client } from './helpers';`);
974
+ }
975
+ lines.push('');
976
+ for (const tgt of targets) {
977
+ const pascalName = tgt.name.charAt(0).toUpperCase() + tgt.name.slice(1);
978
+ lines.push(`const ${tgt.name} = create${pascalName}Client();`);
979
+ }
980
+ lines.push('```');
981
+ lines.push('');
982
+ lines.push('Credential resolution order:');
983
+ lines.push(`1. appstash store (\`~/.${toolName}/config/\`)`);
984
+ lines.push(`2. Environment variables (\`${toolName.toUpperCase().replace(/-/g, '_')}_TOKEN\`, \`${toolName.toUpperCase().replace(/-/g, '_')}_<TARGET>_ENDPOINT\`)`);
985
+ lines.push('3. Throws with actionable error message');
986
+ lines.push('');
845
987
  for (const tgt of targets) {
846
988
  if (tgt.tables.length === 0 && tgt.customOperations.length === 0)
847
989
  continue;
@@ -968,6 +1110,7 @@ function generateMultiTargetAgentsDocs(input) {
968
1110
  lines.push(` ${toolName} <target>:<command> <subcommand> [flags] Target-specific commands`);
969
1111
  lines.push(` ${toolName} ${builtinNames.context} <subcommand> [flags] Context management`);
970
1112
  lines.push(` ${toolName} ${builtinNames.auth} <subcommand> [flags] Authentication`);
1113
+ lines.push(` ${toolName} ${builtinNames.config} <subcommand> [flags] Config key-value store`);
971
1114
  lines.push('');
972
1115
  lines.push('## PREREQUISITES');
973
1116
  lines.push('');
@@ -1032,6 +1175,51 @@ function generateMultiTargetAgentsDocs(input) {
1032
1175
  lines.push(' logout: { context, status: "logged out" }');
1033
1176
  lines.push('```');
1034
1177
  lines.push('');
1178
+ lines.push(`### TOOL: ${builtinNames.config}`);
1179
+ lines.push('');
1180
+ lines.push('Manage per-context key-value configuration variables.');
1181
+ lines.push('');
1182
+ lines.push('```');
1183
+ lines.push('SUBCOMMANDS:');
1184
+ lines.push(` ${toolName} ${builtinNames.config} get <key> Get a config value`);
1185
+ lines.push(` ${toolName} ${builtinNames.config} set <key> <value> Set a config value`);
1186
+ lines.push(` ${toolName} ${builtinNames.config} list List all config values`);
1187
+ lines.push(` ${toolName} ${builtinNames.config} delete <key> Delete a config value`);
1188
+ lines.push('');
1189
+ lines.push('INPUT:');
1190
+ lines.push(' key: string (required for get/set/delete) - Variable name');
1191
+ lines.push(' value: string (required for set) - Variable value');
1192
+ lines.push('');
1193
+ lines.push('OUTPUT: JSON');
1194
+ lines.push(' get: { key, value }');
1195
+ lines.push(' set: { key, value }');
1196
+ lines.push(' list: { vars: { key: value, ... } }');
1197
+ lines.push(' delete: { deleted: key }');
1198
+ lines.push('```');
1199
+ lines.push('');
1200
+ lines.push('### TOOL: helpers (SDK)');
1201
+ lines.push('');
1202
+ lines.push('Typed client factories for use in scripts and services (generated helpers.ts).');
1203
+ lines.push('Resolves credentials via: appstash store -> env vars -> throw.');
1204
+ lines.push('');
1205
+ lines.push('```');
1206
+ lines.push('FACTORIES:');
1207
+ for (const tgt of targets) {
1208
+ const pascalName = tgt.name.charAt(0).toUpperCase() + tgt.name.slice(1);
1209
+ lines.push(` create${pascalName}Client(contextName?) Create a configured ${tgt.name} ORM client`);
1210
+ }
1211
+ lines.push('');
1212
+ lines.push('USAGE:');
1213
+ lines.push(` import { create${targets[0] ? targets[0].name.charAt(0).toUpperCase() + targets[0].name.slice(1) : 'Target'}Client } from './helpers';`);
1214
+ lines.push(` const client = create${targets[0] ? targets[0].name.charAt(0).toUpperCase() + targets[0].name.slice(1) : 'Target'}Client();`);
1215
+ lines.push('');
1216
+ lines.push('CREDENTIAL RESOLUTION:');
1217
+ lines.push(` 1. appstash store (~/.${toolName}/config/)`);
1218
+ const envPrefix = toolName.toUpperCase().replace(/-/g, '_');
1219
+ lines.push(` 2. env vars (${envPrefix}_TOKEN, ${envPrefix}_<TARGET>_ENDPOINT)`);
1220
+ lines.push(' 3. throws with actionable error message');
1221
+ lines.push('```');
1222
+ lines.push('');
1035
1223
  for (const tgt of targets) {
1036
1224
  for (const table of tgt.tables) {
1037
1225
  const { singularName } = (0, utils_1.getTableNames)(table);
@@ -1257,6 +1445,45 @@ function getMultiTargetCliMcpTools(input) {
1257
1445
  description: 'Remove credentials for the current context',
1258
1446
  inputSchema: { type: 'object', properties: {} },
1259
1447
  });
1448
+ tools.push({
1449
+ name: `${toolName}_${builtinNames.config}_get`,
1450
+ description: 'Get a config variable value for the current context',
1451
+ inputSchema: {
1452
+ type: 'object',
1453
+ properties: {
1454
+ key: { type: 'string', description: 'Variable name' },
1455
+ },
1456
+ required: ['key'],
1457
+ },
1458
+ });
1459
+ tools.push({
1460
+ name: `${toolName}_${builtinNames.config}_set`,
1461
+ description: 'Set a config variable value for the current context',
1462
+ inputSchema: {
1463
+ type: 'object',
1464
+ properties: {
1465
+ key: { type: 'string', description: 'Variable name' },
1466
+ value: { type: 'string', description: 'Variable value' },
1467
+ },
1468
+ required: ['key', 'value'],
1469
+ },
1470
+ });
1471
+ tools.push({
1472
+ name: `${toolName}_${builtinNames.config}_list`,
1473
+ description: 'List all config variables for the current context',
1474
+ inputSchema: { type: 'object', properties: {} },
1475
+ });
1476
+ tools.push({
1477
+ name: `${toolName}_${builtinNames.config}_delete`,
1478
+ description: 'Delete a config variable for the current context',
1479
+ inputSchema: {
1480
+ type: 'object',
1481
+ properties: {
1482
+ key: { type: 'string', description: 'Variable name to delete' },
1483
+ },
1484
+ required: ['key'],
1485
+ },
1486
+ });
1260
1487
  for (const tgt of targets) {
1261
1488
  for (const table of tgt.tables) {
1262
1489
  const { singularName } = (0, utils_1.getTableNames)(table);
@@ -1451,12 +1678,40 @@ function generateMultiTargetSkills(input) {
1451
1678
  ],
1452
1679
  }),
1453
1680
  });
1681
+ // Config reference
1682
+ commonReferenceNames.push('config');
1683
+ files.push({
1684
+ fileName: `${commonSkillName}/references/config.md`,
1685
+ content: (0, docs_utils_1.buildSkillReference)({
1686
+ title: 'Config Variables',
1687
+ description: `Manage per-context key-value configuration variables for ${toolName}`,
1688
+ usage: [
1689
+ `${toolName} ${builtinNames.config} get <key>`,
1690
+ `${toolName} ${builtinNames.config} set <key> <value>`,
1691
+ `${toolName} ${builtinNames.config} list`,
1692
+ `${toolName} ${builtinNames.config} delete <key>`,
1693
+ ],
1694
+ examples: [
1695
+ {
1696
+ description: 'Store and retrieve a config variable',
1697
+ code: [
1698
+ `${toolName} ${builtinNames.config} set orgId abc-123`,
1699
+ `${toolName} ${builtinNames.config} get orgId`,
1700
+ ],
1701
+ },
1702
+ {
1703
+ description: 'List all config variables',
1704
+ code: [`${toolName} ${builtinNames.config} list`],
1705
+ },
1706
+ ],
1707
+ }),
1708
+ });
1454
1709
  // Common SKILL.md
1455
1710
  files.push({
1456
1711
  fileName: `${commonSkillName}/SKILL.md`,
1457
1712
  content: (0, docs_utils_1.buildSkillFile)({
1458
1713
  name: commonSkillName,
1459
- description: `Shared CLI utilities for ${toolName} — context management and authentication across targets: ${targets.map((t) => t.name).join(', ')}`,
1714
+ description: `Shared CLI utilities for ${toolName} — context management, authentication, and config across targets: ${targets.map((t) => t.name).join(', ')}`,
1460
1715
  usage: [
1461
1716
  `# Context management`,
1462
1717
  `${toolName} ${builtinNames.context} create <name>`,
@@ -1465,6 +1720,11 @@ function generateMultiTargetSkills(input) {
1465
1720
  `# Authentication`,
1466
1721
  `${toolName} ${builtinNames.auth} set-token <token>`,
1467
1722
  `${toolName} ${builtinNames.auth} status`,
1723
+ '',
1724
+ `# Config variables`,
1725
+ `${toolName} ${builtinNames.config} set <key> <value>`,
1726
+ `${toolName} ${builtinNames.config} get <key>`,
1727
+ `${toolName} ${builtinNames.config} list`,
1468
1728
  ],
1469
1729
  examples: [
1470
1730
  {
@@ -1475,6 +1735,12 @@ function generateMultiTargetSkills(input) {
1475
1735
  `${toolName} ${builtinNames.auth} set-token <token>`,
1476
1736
  ],
1477
1737
  },
1738
+ {
1739
+ description: 'Store a config variable',
1740
+ code: [
1741
+ `${toolName} ${builtinNames.config} set orgId abc-123`,
1742
+ ],
1743
+ },
1478
1744
  ],
1479
1745
  }, commonReferenceNames),
1480
1746
  });
@@ -11,6 +11,7 @@ export interface MultiTargetDocsInput {
11
11
  builtinNames: {
12
12
  auth: string;
13
13
  context: string;
14
+ config: string;
14
15
  };
15
16
  registry?: TypeRegistry;
16
17
  targets: Array<{
@@ -25,6 +25,7 @@ export function generateReadme(tables, customOperations, toolName, registry) {
25
25
  lines.push('|---------|-------------|');
26
26
  lines.push('| `context` | Manage API contexts (endpoints) |');
27
27
  lines.push('| `auth` | Manage authentication tokens |');
28
+ lines.push('| `config` | Manage config key-value store (per-context) |');
28
29
  for (const table of tables) {
29
30
  const { singularName } = getTableNames(table);
30
31
  const kebab = toKebabCase(singularName);
@@ -61,6 +62,19 @@ export function generateReadme(tables, customOperations, toolName, registry) {
61
62
  lines.push('| `status` | Show auth status across all contexts |');
62
63
  lines.push('| `logout` | Remove credentials for current context |');
63
64
  lines.push('');
65
+ lines.push('### `config`');
66
+ lines.push('');
67
+ lines.push('Manage per-context key-value configuration variables.');
68
+ lines.push('');
69
+ lines.push('| Subcommand | Description |');
70
+ lines.push('|------------|-------------|');
71
+ lines.push('| `get <key>` | Get a config value |');
72
+ lines.push('| `set <key> <value>` | Set a config value |');
73
+ lines.push('| `list` | List all config values |');
74
+ lines.push('| `delete <key>` | Delete a config value |');
75
+ lines.push('');
76
+ lines.push(`Variables are scoped to the active context and stored at \`~/.${toolName}/config/\`.`);
77
+ lines.push('');
64
78
  if (tables.length > 0) {
65
79
  lines.push('## Table Commands');
66
80
  lines.push('');
@@ -221,6 +235,28 @@ export function generateAgentsDocs(tables, customOperations, toolName, registry)
221
235
  lines.push(' logout: { context, status: "logged out" }');
222
236
  lines.push('```');
223
237
  lines.push('');
238
+ lines.push('### TOOL: config');
239
+ lines.push('');
240
+ lines.push('Manage per-context key-value configuration variables.');
241
+ lines.push('');
242
+ lines.push('```');
243
+ lines.push('SUBCOMMANDS:');
244
+ lines.push(` ${toolName} config get <key> Get a config value`);
245
+ lines.push(` ${toolName} config set <key> <value> Set a config value`);
246
+ lines.push(` ${toolName} config list List all config values`);
247
+ lines.push(` ${toolName} config delete <key> Delete a config value`);
248
+ lines.push('');
249
+ lines.push('INPUT:');
250
+ lines.push(' key: string (required for get/set/delete) - Variable name');
251
+ lines.push(' value: string (required for set) - Variable value');
252
+ lines.push('');
253
+ lines.push('OUTPUT: JSON');
254
+ lines.push(' get: { key, value }');
255
+ lines.push(' set: { key, value }');
256
+ lines.push(' list: { vars: { key: value, ... } }');
257
+ lines.push(' delete: { deleted: key }');
258
+ lines.push('```');
259
+ lines.push('');
224
260
  for (const table of tables) {
225
261
  const { singularName } = getTableNames(table);
226
262
  const kebab = toKebabCase(singularName);
@@ -428,6 +464,45 @@ export function getCliMcpTools(tables, customOperations, toolName, registry) {
428
464
  description: 'Remove credentials for the current context',
429
465
  inputSchema: { type: 'object', properties: {} },
430
466
  });
467
+ tools.push({
468
+ name: `${toolName}_config_get`,
469
+ description: 'Get a config variable value for the current context',
470
+ inputSchema: {
471
+ type: 'object',
472
+ properties: {
473
+ key: { type: 'string', description: 'Variable name' },
474
+ },
475
+ required: ['key'],
476
+ },
477
+ });
478
+ tools.push({
479
+ name: `${toolName}_config_set`,
480
+ description: 'Set a config variable value for the current context',
481
+ inputSchema: {
482
+ type: 'object',
483
+ properties: {
484
+ key: { type: 'string', description: 'Variable name' },
485
+ value: { type: 'string', description: 'Variable value' },
486
+ },
487
+ required: ['key', 'value'],
488
+ },
489
+ });
490
+ tools.push({
491
+ name: `${toolName}_config_list`,
492
+ description: 'List all config variables for the current context',
493
+ inputSchema: { type: 'object', properties: {} },
494
+ });
495
+ tools.push({
496
+ name: `${toolName}_config_delete`,
497
+ description: 'Delete a config variable for the current context',
498
+ inputSchema: {
499
+ type: 'object',
500
+ properties: {
501
+ key: { type: 'string', description: 'Variable name to delete' },
502
+ },
503
+ required: ['key'],
504
+ },
505
+ });
431
506
  for (const table of tables) {
432
507
  const { singularName } = getTableNames(table);
433
508
  const kebab = toKebabCase(singularName);
@@ -605,6 +680,34 @@ export function generateSkills(tables, customOperations, toolName, targetName, r
605
680
  ],
606
681
  }),
607
682
  });
683
+ // Config reference
684
+ referenceNames.push('config');
685
+ files.push({
686
+ fileName: `${skillName}/references/config.md`,
687
+ content: buildSkillReference({
688
+ title: 'Config Variables',
689
+ description: `Manage per-context key-value configuration variables for ${toolName}`,
690
+ usage: [
691
+ `${toolName} config get <key>`,
692
+ `${toolName} config set <key> <value>`,
693
+ `${toolName} config list`,
694
+ `${toolName} config delete <key>`,
695
+ ],
696
+ examples: [
697
+ {
698
+ description: 'Store and retrieve a config variable',
699
+ code: [
700
+ `${toolName} config set orgId abc-123`,
701
+ `${toolName} config get orgId`,
702
+ ],
703
+ },
704
+ {
705
+ description: 'List all config variables',
706
+ code: [`${toolName} config list`],
707
+ },
708
+ ],
709
+ }),
710
+ });
608
711
  // Table references
609
712
  for (const table of tables) {
610
713
  const { singularName } = getTableNames(table);
@@ -686,6 +789,10 @@ export function generateSkills(tables, customOperations, toolName, targetName, r
686
789
  `# Authentication`,
687
790
  `${toolName} auth set-token <token>`,
688
791
  '',
792
+ `# Config variables`,
793
+ `${toolName} config set <key> <value>`,
794
+ `${toolName} config get <key>`,
795
+ '',
689
796
  `# CRUD for any table (e.g. ${tableKebabs[0] || 'model'})`,
690
797
  `${toolName} ${tableKebabs[0] || 'model'} list`,
691
798
  `${toolName} ${tableKebabs[0] || 'model'} get --id <value>`,
@@ -781,6 +888,7 @@ export function generateMultiTargetReadme(input) {
781
888
  lines.push('|---------|-------------|');
782
889
  lines.push(`| \`${builtinNames.context}\` | Manage API contexts (per-target endpoints) |`);
783
890
  lines.push(`| \`${builtinNames.auth}\` | Manage authentication tokens |`);
891
+ lines.push(`| \`${builtinNames.config}\` | Manage config key-value store (per-context) |`);
784
892
  lines.push('');
785
893
  for (const tgt of targets) {
786
894
  lines.push(`### ${tgt.name}`);
@@ -830,6 +938,40 @@ export function generateMultiTargetReadme(input) {
830
938
  lines.push('| `status` | Show auth status across all contexts |');
831
939
  lines.push('| `logout` | Remove credentials for current context |');
832
940
  lines.push('');
941
+ lines.push(`### \`${builtinNames.config}\``);
942
+ lines.push('');
943
+ lines.push('Manage per-context key-value configuration variables.');
944
+ lines.push('');
945
+ lines.push('| Subcommand | Description |');
946
+ lines.push('|------------|-------------|');
947
+ lines.push('| `get <key>` | Get a config value |');
948
+ lines.push('| `set <key> <value>` | Set a config value |');
949
+ lines.push('| `list` | List all config values |');
950
+ lines.push('| `delete <key>` | Delete a config value |');
951
+ lines.push('');
952
+ lines.push(`Variables are scoped to the active context and stored at \`~/.${toolName}/config/\`.`);
953
+ lines.push('');
954
+ lines.push('## SDK Helpers');
955
+ lines.push('');
956
+ lines.push('The generated `helpers.ts` provides typed client factories for use in scripts and services:');
957
+ lines.push('');
958
+ lines.push('```typescript');
959
+ for (const tgt of targets) {
960
+ const pascalName = tgt.name.charAt(0).toUpperCase() + tgt.name.slice(1);
961
+ lines.push(`import { create${pascalName}Client } from './helpers';`);
962
+ }
963
+ lines.push('');
964
+ for (const tgt of targets) {
965
+ const pascalName = tgt.name.charAt(0).toUpperCase() + tgt.name.slice(1);
966
+ lines.push(`const ${tgt.name} = create${pascalName}Client();`);
967
+ }
968
+ lines.push('```');
969
+ lines.push('');
970
+ lines.push('Credential resolution order:');
971
+ lines.push(`1. appstash store (\`~/.${toolName}/config/\`)`);
972
+ lines.push(`2. Environment variables (\`${toolName.toUpperCase().replace(/-/g, '_')}_TOKEN\`, \`${toolName.toUpperCase().replace(/-/g, '_')}_<TARGET>_ENDPOINT\`)`);
973
+ lines.push('3. Throws with actionable error message');
974
+ lines.push('');
833
975
  for (const tgt of targets) {
834
976
  if (tgt.tables.length === 0 && tgt.customOperations.length === 0)
835
977
  continue;
@@ -956,6 +1098,7 @@ export function generateMultiTargetAgentsDocs(input) {
956
1098
  lines.push(` ${toolName} <target>:<command> <subcommand> [flags] Target-specific commands`);
957
1099
  lines.push(` ${toolName} ${builtinNames.context} <subcommand> [flags] Context management`);
958
1100
  lines.push(` ${toolName} ${builtinNames.auth} <subcommand> [flags] Authentication`);
1101
+ lines.push(` ${toolName} ${builtinNames.config} <subcommand> [flags] Config key-value store`);
959
1102
  lines.push('');
960
1103
  lines.push('## PREREQUISITES');
961
1104
  lines.push('');
@@ -1020,6 +1163,51 @@ export function generateMultiTargetAgentsDocs(input) {
1020
1163
  lines.push(' logout: { context, status: "logged out" }');
1021
1164
  lines.push('```');
1022
1165
  lines.push('');
1166
+ lines.push(`### TOOL: ${builtinNames.config}`);
1167
+ lines.push('');
1168
+ lines.push('Manage per-context key-value configuration variables.');
1169
+ lines.push('');
1170
+ lines.push('```');
1171
+ lines.push('SUBCOMMANDS:');
1172
+ lines.push(` ${toolName} ${builtinNames.config} get <key> Get a config value`);
1173
+ lines.push(` ${toolName} ${builtinNames.config} set <key> <value> Set a config value`);
1174
+ lines.push(` ${toolName} ${builtinNames.config} list List all config values`);
1175
+ lines.push(` ${toolName} ${builtinNames.config} delete <key> Delete a config value`);
1176
+ lines.push('');
1177
+ lines.push('INPUT:');
1178
+ lines.push(' key: string (required for get/set/delete) - Variable name');
1179
+ lines.push(' value: string (required for set) - Variable value');
1180
+ lines.push('');
1181
+ lines.push('OUTPUT: JSON');
1182
+ lines.push(' get: { key, value }');
1183
+ lines.push(' set: { key, value }');
1184
+ lines.push(' list: { vars: { key: value, ... } }');
1185
+ lines.push(' delete: { deleted: key }');
1186
+ lines.push('```');
1187
+ lines.push('');
1188
+ lines.push('### TOOL: helpers (SDK)');
1189
+ lines.push('');
1190
+ lines.push('Typed client factories for use in scripts and services (generated helpers.ts).');
1191
+ lines.push('Resolves credentials via: appstash store -> env vars -> throw.');
1192
+ lines.push('');
1193
+ lines.push('```');
1194
+ lines.push('FACTORIES:');
1195
+ for (const tgt of targets) {
1196
+ const pascalName = tgt.name.charAt(0).toUpperCase() + tgt.name.slice(1);
1197
+ lines.push(` create${pascalName}Client(contextName?) Create a configured ${tgt.name} ORM client`);
1198
+ }
1199
+ lines.push('');
1200
+ lines.push('USAGE:');
1201
+ lines.push(` import { create${targets[0] ? targets[0].name.charAt(0).toUpperCase() + targets[0].name.slice(1) : 'Target'}Client } from './helpers';`);
1202
+ lines.push(` const client = create${targets[0] ? targets[0].name.charAt(0).toUpperCase() + targets[0].name.slice(1) : 'Target'}Client();`);
1203
+ lines.push('');
1204
+ lines.push('CREDENTIAL RESOLUTION:');
1205
+ lines.push(` 1. appstash store (~/.${toolName}/config/)`);
1206
+ const envPrefix = toolName.toUpperCase().replace(/-/g, '_');
1207
+ lines.push(` 2. env vars (${envPrefix}_TOKEN, ${envPrefix}_<TARGET>_ENDPOINT)`);
1208
+ lines.push(' 3. throws with actionable error message');
1209
+ lines.push('```');
1210
+ lines.push('');
1023
1211
  for (const tgt of targets) {
1024
1212
  for (const table of tgt.tables) {
1025
1213
  const { singularName } = getTableNames(table);
@@ -1245,6 +1433,45 @@ export function getMultiTargetCliMcpTools(input) {
1245
1433
  description: 'Remove credentials for the current context',
1246
1434
  inputSchema: { type: 'object', properties: {} },
1247
1435
  });
1436
+ tools.push({
1437
+ name: `${toolName}_${builtinNames.config}_get`,
1438
+ description: 'Get a config variable value for the current context',
1439
+ inputSchema: {
1440
+ type: 'object',
1441
+ properties: {
1442
+ key: { type: 'string', description: 'Variable name' },
1443
+ },
1444
+ required: ['key'],
1445
+ },
1446
+ });
1447
+ tools.push({
1448
+ name: `${toolName}_${builtinNames.config}_set`,
1449
+ description: 'Set a config variable value for the current context',
1450
+ inputSchema: {
1451
+ type: 'object',
1452
+ properties: {
1453
+ key: { type: 'string', description: 'Variable name' },
1454
+ value: { type: 'string', description: 'Variable value' },
1455
+ },
1456
+ required: ['key', 'value'],
1457
+ },
1458
+ });
1459
+ tools.push({
1460
+ name: `${toolName}_${builtinNames.config}_list`,
1461
+ description: 'List all config variables for the current context',
1462
+ inputSchema: { type: 'object', properties: {} },
1463
+ });
1464
+ tools.push({
1465
+ name: `${toolName}_${builtinNames.config}_delete`,
1466
+ description: 'Delete a config variable for the current context',
1467
+ inputSchema: {
1468
+ type: 'object',
1469
+ properties: {
1470
+ key: { type: 'string', description: 'Variable name to delete' },
1471
+ },
1472
+ required: ['key'],
1473
+ },
1474
+ });
1248
1475
  for (const tgt of targets) {
1249
1476
  for (const table of tgt.tables) {
1250
1477
  const { singularName } = getTableNames(table);
@@ -1439,12 +1666,40 @@ export function generateMultiTargetSkills(input) {
1439
1666
  ],
1440
1667
  }),
1441
1668
  });
1669
+ // Config reference
1670
+ commonReferenceNames.push('config');
1671
+ files.push({
1672
+ fileName: `${commonSkillName}/references/config.md`,
1673
+ content: buildSkillReference({
1674
+ title: 'Config Variables',
1675
+ description: `Manage per-context key-value configuration variables for ${toolName}`,
1676
+ usage: [
1677
+ `${toolName} ${builtinNames.config} get <key>`,
1678
+ `${toolName} ${builtinNames.config} set <key> <value>`,
1679
+ `${toolName} ${builtinNames.config} list`,
1680
+ `${toolName} ${builtinNames.config} delete <key>`,
1681
+ ],
1682
+ examples: [
1683
+ {
1684
+ description: 'Store and retrieve a config variable',
1685
+ code: [
1686
+ `${toolName} ${builtinNames.config} set orgId abc-123`,
1687
+ `${toolName} ${builtinNames.config} get orgId`,
1688
+ ],
1689
+ },
1690
+ {
1691
+ description: 'List all config variables',
1692
+ code: [`${toolName} ${builtinNames.config} list`],
1693
+ },
1694
+ ],
1695
+ }),
1696
+ });
1442
1697
  // Common SKILL.md
1443
1698
  files.push({
1444
1699
  fileName: `${commonSkillName}/SKILL.md`,
1445
1700
  content: buildSkillFile({
1446
1701
  name: commonSkillName,
1447
- description: `Shared CLI utilities for ${toolName} — context management and authentication across targets: ${targets.map((t) => t.name).join(', ')}`,
1702
+ description: `Shared CLI utilities for ${toolName} — context management, authentication, and config across targets: ${targets.map((t) => t.name).join(', ')}`,
1448
1703
  usage: [
1449
1704
  `# Context management`,
1450
1705
  `${toolName} ${builtinNames.context} create <name>`,
@@ -1453,6 +1708,11 @@ export function generateMultiTargetSkills(input) {
1453
1708
  `# Authentication`,
1454
1709
  `${toolName} ${builtinNames.auth} set-token <token>`,
1455
1710
  `${toolName} ${builtinNames.auth} status`,
1711
+ '',
1712
+ `# Config variables`,
1713
+ `${toolName} ${builtinNames.config} set <key> <value>`,
1714
+ `${toolName} ${builtinNames.config} get <key>`,
1715
+ `${toolName} ${builtinNames.config} list`,
1456
1716
  ],
1457
1717
  examples: [
1458
1718
  {
@@ -1463,6 +1723,12 @@ export function generateMultiTargetSkills(input) {
1463
1723
  `${toolName} ${builtinNames.auth} set-token <token>`,
1464
1724
  ],
1465
1725
  },
1726
+ {
1727
+ description: 'Store a config variable',
1728
+ code: [
1729
+ `${toolName} ${builtinNames.config} set orgId abc-123`,
1730
+ ],
1731
+ },
1466
1732
  ],
1467
1733
  }, commonReferenceNames),
1468
1734
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constructive-io/graphql-codegen",
3
- "version": "4.13.0",
3
+ "version": "4.13.1",
4
4
  "description": "GraphQL SDK generator for Constructive databases with React Query hooks",
5
5
  "keywords": [
6
6
  "graphql",
@@ -56,7 +56,7 @@
56
56
  "@0no-co/graphql.web": "^1.1.2",
57
57
  "@babel/generator": "^7.29.1",
58
58
  "@babel/types": "^7.29.0",
59
- "@constructive-io/graphql-query": "^3.5.3",
59
+ "@constructive-io/graphql-query": "^3.5.4",
60
60
  "@constructive-io/graphql-types": "^3.3.2",
61
61
  "@inquirerer/utils": "^3.3.1",
62
62
  "@pgpmjs/core": "^6.6.2",
@@ -64,7 +64,7 @@
64
64
  "deepmerge": "^4.3.1",
65
65
  "find-and-require-package-json": "^0.9.1",
66
66
  "gql-ast": "^3.3.2",
67
- "graphile-schema": "^1.5.3",
67
+ "graphile-schema": "^1.5.4",
68
68
  "graphql": "^16.13.0",
69
69
  "inflekt": "^0.3.3",
70
70
  "inquirerer": "^4.5.2",
@@ -101,5 +101,5 @@
101
101
  "tsx": "^4.21.0",
102
102
  "typescript": "^5.9.3"
103
103
  },
104
- "gitHead": "67218366027bc6370e07a1b96d8bf25adba18f42"
104
+ "gitHead": "d0b204889409aa5ad8c11053c4c7f26611d7c99a"
105
105
  }