@inkeep/agents-cli 0.59.3 → 0.59.4

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 (88) hide show
  1. package/dist/agents-cli/package.js +1 -1
  2. package/dist/commands/pull-v4/collector-common.js +128 -0
  3. package/dist/commands/pull-v4/collector-common.js.map +1 -0
  4. package/dist/commands/pull-v4/collector-reference-helpers.js +323 -0
  5. package/dist/commands/pull-v4/collector-reference-helpers.js.map +1 -0
  6. package/dist/commands/pull-v4/component-parser.js +2 -1
  7. package/dist/commands/pull-v4/component-parser.js.map +1 -1
  8. package/dist/commands/pull-v4/file-scope.js +43 -0
  9. package/dist/commands/pull-v4/file-scope.js.map +1 -0
  10. package/dist/commands/pull-v4/generation-resolver.js +305 -0
  11. package/dist/commands/pull-v4/generation-resolver.js.map +1 -0
  12. package/dist/commands/pull-v4/generation-types.js +56 -0
  13. package/dist/commands/pull-v4/generation-types.js.map +1 -0
  14. package/dist/commands/pull-v4/generators/agent-generator.helpers.js +4 -10
  15. package/dist/commands/pull-v4/generators/agent-generator.helpers.js.map +1 -1
  16. package/dist/commands/pull-v4/generators/agent-generator.js +154 -81
  17. package/dist/commands/pull-v4/generators/agent-generator.js.map +1 -1
  18. package/dist/commands/pull-v4/generators/artifact-component-generator.js +48 -27
  19. package/dist/commands/pull-v4/generators/artifact-component-generator.js.map +1 -1
  20. package/dist/commands/pull-v4/generators/context-config-generator.js +147 -129
  21. package/dist/commands/pull-v4/generators/context-config-generator.js.map +1 -1
  22. package/dist/commands/pull-v4/generators/credential-generator.js +36 -14
  23. package/dist/commands/pull-v4/generators/credential-generator.js.map +1 -1
  24. package/dist/commands/pull-v4/generators/data-component-generator.js +55 -19
  25. package/dist/commands/pull-v4/generators/data-component-generator.js.map +1 -1
  26. package/dist/commands/pull-v4/generators/environment-generator.js +29 -33
  27. package/dist/commands/pull-v4/generators/environment-generator.js.map +1 -1
  28. package/dist/commands/pull-v4/generators/environment-settings-generator.js +57 -0
  29. package/dist/commands/pull-v4/generators/environment-settings-generator.js.map +1 -0
  30. package/dist/commands/pull-v4/generators/external-agent-generator.js +51 -23
  31. package/dist/commands/pull-v4/generators/external-agent-generator.js.map +1 -1
  32. package/dist/commands/pull-v4/generators/function-tool-generator.js +50 -14
  33. package/dist/commands/pull-v4/generators/function-tool-generator.js.map +1 -1
  34. package/dist/commands/pull-v4/generators/helpers/agent.js +129 -0
  35. package/dist/commands/pull-v4/generators/helpers/agent.js.map +1 -0
  36. package/dist/commands/pull-v4/generators/helpers/sub-agent.js +65 -0
  37. package/dist/commands/pull-v4/generators/helpers/sub-agent.js.map +1 -0
  38. package/dist/commands/pull-v4/generators/index.js +38 -0
  39. package/dist/commands/pull-v4/generators/index.js.map +1 -0
  40. package/dist/commands/pull-v4/generators/mcp-tool-generator.js +48 -27
  41. package/dist/commands/pull-v4/generators/mcp-tool-generator.js.map +1 -1
  42. package/dist/commands/pull-v4/generators/project-generator.js +144 -110
  43. package/dist/commands/pull-v4/generators/project-generator.js.map +1 -1
  44. package/dist/commands/pull-v4/generators/scheduled-trigger-generator.js +66 -0
  45. package/dist/commands/pull-v4/generators/scheduled-trigger-generator.js.map +1 -0
  46. package/dist/commands/pull-v4/generators/status-component-generator.js +55 -20
  47. package/dist/commands/pull-v4/generators/status-component-generator.js.map +1 -1
  48. package/dist/commands/pull-v4/generators/sub-agent-generator.helpers.js +4 -1
  49. package/dist/commands/pull-v4/generators/sub-agent-generator.helpers.js.map +1 -1
  50. package/dist/commands/pull-v4/generators/sub-agent-generator.js +282 -166
  51. package/dist/commands/pull-v4/generators/sub-agent-generator.js.map +1 -1
  52. package/dist/commands/pull-v4/generators/trigger-generator.js +62 -27
  53. package/dist/commands/pull-v4/generators/trigger-generator.js.map +1 -1
  54. package/dist/commands/pull-v4/import-plan.js +40 -0
  55. package/dist/commands/pull-v4/import-plan.js.map +1 -0
  56. package/dist/commands/pull-v4/introspect/index.js +11 -7
  57. package/dist/commands/pull-v4/introspect/index.js.map +1 -1
  58. package/dist/commands/pull-v4/introspect-generator.js +15 -1218
  59. package/dist/commands/pull-v4/introspect-generator.js.map +1 -1
  60. package/dist/commands/pull-v4/module-merge.js +14 -5
  61. package/dist/commands/pull-v4/module-merge.js.map +1 -1
  62. package/dist/commands/pull-v4/reference-resolution.js +111 -0
  63. package/dist/commands/pull-v4/reference-resolution.js.map +1 -0
  64. package/dist/commands/pull-v4/simple-factory-generator.js +54 -0
  65. package/dist/commands/pull-v4/simple-factory-generator.js.map +1 -0
  66. package/dist/commands/pull-v4/{generators/skill-generator.js → skill.js} +18 -6
  67. package/dist/commands/pull-v4/skill.js.map +1 -0
  68. package/dist/commands/pull-v4/typescript-file-writer.js +78 -0
  69. package/dist/commands/pull-v4/typescript-file-writer.js.map +1 -0
  70. package/dist/commands/pull-v4/utils/code-values.js +64 -0
  71. package/dist/commands/pull-v4/utils/code-values.js.map +1 -0
  72. package/dist/commands/pull-v4/utils/factory-writer.js +128 -0
  73. package/dist/commands/pull-v4/utils/factory-writer.js.map +1 -0
  74. package/dist/commands/pull-v4/utils/index.js +8 -0
  75. package/dist/commands/pull-v4/utils/naming.js +74 -0
  76. package/dist/commands/pull-v4/utils/naming.js.map +1 -0
  77. package/dist/commands/pull-v4/utils/schema-rendering.js +20 -0
  78. package/dist/commands/pull-v4/utils/schema-rendering.js.map +1 -0
  79. package/dist/commands/pull-v4/utils/shared.js +18 -0
  80. package/dist/commands/pull-v4/utils/shared.js.map +1 -0
  81. package/dist/commands/pull-v4/utils/templates.js +58 -0
  82. package/dist/commands/pull-v4/utils/templates.js.map +1 -0
  83. package/package.json +4 -4
  84. package/dist/commands/pull-v4/generators/skill-generator.js.map +0 -1
  85. package/dist/commands/pull-v4/scheduled-trigger-generator.js +0 -38
  86. package/dist/commands/pull-v4/scheduled-trigger-generator.js.map +0 -1
  87. package/dist/commands/pull-v4/utils.js +0 -320
  88. package/dist/commands/pull-v4/utils.js.map +0 -1
@@ -0,0 +1,74 @@
1
+ //#region src/commands/pull-v4/utils/naming.ts
2
+ const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
3
+ const CUID_RE = /^c[a-z0-9]{24,}$/;
4
+ const NANOID_RE = /^[a-z0-9]{16,}$/;
5
+ const ID_SUFFIX_LENGTH = 8;
6
+ function resolveNonCollidingName(baseName, reservedNames, startIndex = 1) {
7
+ if (!reservedNames.has(baseName)) {
8
+ reservedNames.add(baseName);
9
+ return baseName;
10
+ }
11
+ let index = startIndex;
12
+ while (reservedNames.has(`${baseName}${index}`)) index += 1;
13
+ const uniqueName = `${baseName}${index}`;
14
+ reservedNames.add(uniqueName);
15
+ return uniqueName;
16
+ }
17
+ function toCamelCase(input) {
18
+ const result = input.toLowerCase().replaceAll(/\W/g, " ").trim().replaceAll(/[\s_]+(.)/g, (_, char) => char.toUpperCase()).replace(/^[0-9]/, "_$&");
19
+ return result.charAt(0).toLowerCase() + result.slice(1);
20
+ }
21
+ function toToolReferenceName(input) {
22
+ const base = toCamelCase(input);
23
+ return base.endsWith("Tool") ? base : `${base}Tool`;
24
+ }
25
+ function toCredentialReferenceName(input) {
26
+ const base = toCamelCase(input);
27
+ return base.endsWith("Credential") ? base : `${base}Credential`;
28
+ }
29
+ function toTriggerReferenceName(input) {
30
+ const base = toCamelCase(input);
31
+ return base.endsWith("Trigger") ? base : `${base}Trigger`;
32
+ }
33
+ function toKebabCase(input) {
34
+ return input.trim().replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").toLowerCase();
35
+ }
36
+ function isHumanReadableId(id) {
37
+ if (UUID_RE.test(id) || CUID_RE.test(id) || NANOID_RE.test(id)) return false;
38
+ const segments = id.split(/[-_]/);
39
+ if (segments.length === 1 && id.length > 8) {
40
+ const hasLetters = /[a-zA-Z]/.test(id);
41
+ const hasDigits = /[0-9]/.test(id);
42
+ if (hasLetters && hasDigits) return false;
43
+ }
44
+ return segments.filter((s) => /^[a-zA-Z]+\d{0,2}$/.test(s)).length / segments.length >= .5;
45
+ }
46
+ function buildComponentFileName(id, name) {
47
+ if (!name || isHumanReadableId(id)) return `${id}.ts`;
48
+ const kebabName = toKebabCase(name);
49
+ if (!kebabName || kebabName === id) return `${id}.ts`;
50
+ return `${kebabName}-${id.slice(-ID_SUFFIX_LENGTH)}.ts`;
51
+ }
52
+ function createUniqueReferenceName(baseName, reservedNames, conflictSuffix) {
53
+ if (!reservedNames.has(baseName)) {
54
+ reservedNames.add(baseName);
55
+ return baseName;
56
+ }
57
+ const baseCandidate = `${baseName}${conflictSuffix}`;
58
+ if (!reservedNames.has(baseCandidate)) {
59
+ reservedNames.add(baseCandidate);
60
+ return baseCandidate;
61
+ }
62
+ return resolveNonCollidingName(baseCandidate, reservedNames, 2);
63
+ }
64
+ function resolveReferenceName(referenceId, referenceOverrides) {
65
+ for (const overrideMap of referenceOverrides) {
66
+ const overrideName = overrideMap?.[referenceId];
67
+ if (overrideName) return overrideName;
68
+ }
69
+ return toCamelCase(referenceId);
70
+ }
71
+
72
+ //#endregion
73
+ export { buildComponentFileName, createUniqueReferenceName, isHumanReadableId, resolveNonCollidingName, resolveReferenceName, toCamelCase, toCredentialReferenceName, toKebabCase, toToolReferenceName, toTriggerReferenceName };
74
+ //# sourceMappingURL=naming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming.js","names":[],"sources":["../../../../src/commands/pull-v4/utils/naming.ts"],"sourcesContent":["const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nconst CUID_RE = /^c[a-z0-9]{24,}$/;\nconst NANOID_RE = /^[a-z0-9]{16,}$/;\nconst ID_SUFFIX_LENGTH = 8;\ntype ReferenceOverrideMap = Record<string, string>;\n\nexport function resolveNonCollidingName(\n baseName: string,\n reservedNames: Set<string>,\n startIndex = 1\n): string {\n if (!reservedNames.has(baseName)) {\n reservedNames.add(baseName);\n return baseName;\n }\n\n let index = startIndex;\n while (reservedNames.has(`${baseName}${index}`)) {\n index += 1;\n }\n\n const uniqueName = `${baseName}${index}`;\n reservedNames.add(uniqueName);\n return uniqueName;\n}\n\nexport function toCamelCase(input: string): string {\n const result = input\n .toLowerCase()\n .replaceAll(/\\W/g, ' ')\n .trim()\n .replaceAll(/[\\s_]+(.)/g, (_, char: string) => char.toUpperCase())\n .replace(/^[0-9]/, '_$&');\n\n return result.charAt(0).toLowerCase() + result.slice(1);\n}\n\nexport function toToolReferenceName(input: string): string {\n const base = toCamelCase(input);\n return base.endsWith('Tool') ? base : `${base}Tool`;\n}\n\nexport function toCredentialReferenceName(input: string): string {\n const base = toCamelCase(input);\n return base.endsWith('Credential') ? base : `${base}Credential`;\n}\n\nexport function toTriggerReferenceName(input: string): string {\n const base = toCamelCase(input);\n return base.endsWith('Trigger') ? base : `${base}Trigger`;\n}\n\nexport function toKebabCase(input: string): string {\n return input\n .trim()\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[^a-zA-Z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .toLowerCase();\n}\n\nexport function isHumanReadableId(id: string): boolean {\n if (UUID_RE.test(id) || CUID_RE.test(id) || NANOID_RE.test(id)) {\n return false;\n }\n\n const segments = id.split(/[-_]/);\n if (segments.length === 1 && id.length > 8) {\n const hasLetters = /[a-zA-Z]/.test(id);\n const hasDigits = /[0-9]/.test(id);\n if (hasLetters && hasDigits) {\n return false;\n }\n }\n\n const wordLikeSegments = segments.filter((s) => /^[a-zA-Z]+\\d{0,2}$/.test(s));\n return wordLikeSegments.length / segments.length >= 0.5;\n}\n\nexport function buildComponentFileName(id: string, name?: string): string {\n if (!name || isHumanReadableId(id)) {\n return `${id}.ts`;\n }\n\n const kebabName = toKebabCase(name);\n if (!kebabName || kebabName === id) {\n return `${id}.ts`;\n }\n\n const shortId = id.slice(-ID_SUFFIX_LENGTH);\n return `${kebabName}-${shortId}.ts`;\n}\n\nexport function createUniqueReferenceName(\n baseName: string,\n reservedNames: Set<string>,\n conflictSuffix: string\n): string {\n if (!reservedNames.has(baseName)) {\n reservedNames.add(baseName);\n return baseName;\n }\n\n const baseCandidate = `${baseName}${conflictSuffix}`;\n if (!reservedNames.has(baseCandidate)) {\n reservedNames.add(baseCandidate);\n return baseCandidate;\n }\n\n return resolveNonCollidingName(baseCandidate, reservedNames, 2);\n}\n\nexport function resolveReferenceName(\n referenceId: string,\n referenceOverrides: Array<ReferenceOverrideMap | undefined>\n): string {\n for (const overrideMap of referenceOverrides) {\n const overrideName = overrideMap?.[referenceId];\n if (overrideName) {\n return overrideName;\n }\n }\n\n return toCamelCase(referenceId);\n}\n"],"mappings":";AAAA,MAAM,UAAU;AAChB,MAAM,UAAU;AAChB,MAAM,YAAY;AAClB,MAAM,mBAAmB;AAGzB,SAAgB,wBACd,UACA,eACA,aAAa,GACL;AACR,KAAI,CAAC,cAAc,IAAI,SAAS,EAAE;AAChC,gBAAc,IAAI,SAAS;AAC3B,SAAO;;CAGT,IAAI,QAAQ;AACZ,QAAO,cAAc,IAAI,GAAG,WAAW,QAAQ,CAC7C,UAAS;CAGX,MAAM,aAAa,GAAG,WAAW;AACjC,eAAc,IAAI,WAAW;AAC7B,QAAO;;AAGT,SAAgB,YAAY,OAAuB;CACjD,MAAM,SAAS,MACZ,aAAa,CACb,WAAW,OAAO,IAAI,CACtB,MAAM,CACN,WAAW,eAAe,GAAG,SAAiB,KAAK,aAAa,CAAC,CACjE,QAAQ,UAAU,MAAM;AAE3B,QAAO,OAAO,OAAO,EAAE,CAAC,aAAa,GAAG,OAAO,MAAM,EAAE;;AAGzD,SAAgB,oBAAoB,OAAuB;CACzD,MAAM,OAAO,YAAY,MAAM;AAC/B,QAAO,KAAK,SAAS,OAAO,GAAG,OAAO,GAAG,KAAK;;AAGhD,SAAgB,0BAA0B,OAAuB;CAC/D,MAAM,OAAO,YAAY,MAAM;AAC/B,QAAO,KAAK,SAAS,aAAa,GAAG,OAAO,GAAG,KAAK;;AAGtD,SAAgB,uBAAuB,OAAuB;CAC5D,MAAM,OAAO,YAAY,MAAM;AAC/B,QAAO,KAAK,SAAS,UAAU,GAAG,OAAO,GAAG,KAAK;;AAGnD,SAAgB,YAAY,OAAuB;AACjD,QAAO,MACJ,MAAM,CACN,QAAQ,mBAAmB,QAAQ,CACnC,QAAQ,kBAAkB,IAAI,CAC9B,QAAQ,YAAY,GAAG,CACvB,aAAa;;AAGlB,SAAgB,kBAAkB,IAAqB;AACrD,KAAI,QAAQ,KAAK,GAAG,IAAI,QAAQ,KAAK,GAAG,IAAI,UAAU,KAAK,GAAG,CAC5D,QAAO;CAGT,MAAM,WAAW,GAAG,MAAM,OAAO;AACjC,KAAI,SAAS,WAAW,KAAK,GAAG,SAAS,GAAG;EAC1C,MAAM,aAAa,WAAW,KAAK,GAAG;EACtC,MAAM,YAAY,QAAQ,KAAK,GAAG;AAClC,MAAI,cAAc,UAChB,QAAO;;AAKX,QADyB,SAAS,QAAQ,MAAM,qBAAqB,KAAK,EAAE,CAAC,CACrD,SAAS,SAAS,UAAU;;AAGtD,SAAgB,uBAAuB,IAAY,MAAuB;AACxE,KAAI,CAAC,QAAQ,kBAAkB,GAAG,CAChC,QAAO,GAAG,GAAG;CAGf,MAAM,YAAY,YAAY,KAAK;AACnC,KAAI,CAAC,aAAa,cAAc,GAC9B,QAAO,GAAG,GAAG;AAIf,QAAO,GAAG,UAAU,GADJ,GAAG,MAAM,CAAC,iBAAiB,CACZ;;AAGjC,SAAgB,0BACd,UACA,eACA,gBACQ;AACR,KAAI,CAAC,cAAc,IAAI,SAAS,EAAE;AAChC,gBAAc,IAAI,SAAS;AAC3B,SAAO;;CAGT,MAAM,gBAAgB,GAAG,WAAW;AACpC,KAAI,CAAC,cAAc,IAAI,cAAc,EAAE;AACrC,gBAAc,IAAI,cAAc;AAChC,SAAO;;AAGT,QAAO,wBAAwB,eAAe,eAAe,EAAE;;AAGjE,SAAgB,qBACd,aACA,oBACQ;AACR,MAAK,MAAM,eAAe,oBAAoB;EAC5C,MAAM,eAAe,cAAc;AACnC,MAAI,aACF,QAAO;;AAIX,QAAO,YAAY,YAAY"}
@@ -0,0 +1,20 @@
1
+ import { isPlainObject } from "./shared.js";
2
+ import { jsonSchemaToZod } from "json-schema-to-zod";
3
+
4
+ //#region src/commands/pull-v4/utils/schema-rendering.ts
5
+ function convertJsonSchemaToZodSafe(schema, options) {
6
+ if (!isPlainObject(schema)) {
7
+ console.warn("Schema conversion skipped: non-object schema provided, using z.any()");
8
+ return "z.any()";
9
+ }
10
+ try {
11
+ return jsonSchemaToZod(schema, options?.conversionOptions);
12
+ } catch (error) {
13
+ console.warn(`Schema conversion failed: ${error instanceof Error ? error.message : String(error)}. Falling back to z.any()`);
14
+ return "z.any()";
15
+ }
16
+ }
17
+
18
+ //#endregion
19
+ export { convertJsonSchemaToZodSafe };
20
+ //# sourceMappingURL=schema-rendering.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-rendering.js","names":[],"sources":["../../../../src/commands/pull-v4/utils/schema-rendering.ts"],"sourcesContent":["import { jsonSchemaToZod } from 'json-schema-to-zod';\nimport { isPlainObject } from './shared';\n\nexport function convertJsonSchemaToZodSafe(\n schema: unknown,\n options?: { conversionOptions?: Parameters<typeof jsonSchemaToZod>[1] }\n): string {\n if (!isPlainObject(schema)) {\n console.warn('Schema conversion skipped: non-object schema provided, using z.any()');\n return 'z.any()';\n }\n try {\n return jsonSchemaToZod(schema, options?.conversionOptions);\n } catch (error) {\n console.warn(\n `Schema conversion failed: ${error instanceof Error ? error.message : String(error)}. Falling back to z.any()`\n );\n return 'z.any()';\n }\n}\n"],"mappings":";;;;AAGA,SAAgB,2BACd,QACA,SACQ;AACR,KAAI,CAAC,cAAc,OAAO,EAAE;AAC1B,UAAQ,KAAK,uEAAuE;AACpF,SAAO;;AAET,KAAI;AACF,SAAO,gBAAgB,QAAQ,SAAS,kBAAkB;UACnD,OAAO;AACd,UAAQ,KACN,6BAA6B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,CAAC,2BACrF;AACD,SAAO"}
@@ -0,0 +1,18 @@
1
+ import path from "node:path";
2
+
3
+ //#region src/commands/pull-v4/utils/shared.ts
4
+ function isPlainObject(value) {
5
+ return typeof value === "object" && value !== null && !Array.isArray(value);
6
+ }
7
+ async function expectSnapshots(definitionV4) {
8
+ const { currentTestName, snapshotState } = expect.getState();
9
+ const snapshotDir = path.basename(snapshotState.testFilePath).replace("-generator.test.ts", "");
10
+ await expect(definitionV4).toMatchFileSnapshot(`__snapshots__/${snapshotDir}/${currentTestName}-v4.txt`);
11
+ }
12
+ function hasReferences(references) {
13
+ return Array.isArray(references) && references.length > 0;
14
+ }
15
+
16
+ //#endregion
17
+ export { expectSnapshots, hasReferences, isPlainObject };
18
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.js","names":[],"sources":["../../../../src/commands/pull-v4/utils/shared.ts"],"sourcesContent":["import path from 'node:path';\n\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport async function expectSnapshots(definitionV4: string): Promise<void> {\n const { currentTestName, snapshotState } = expect.getState();\n\n const snapshotDir = path.basename(snapshotState.testFilePath).replace('-generator.test.ts', '');\n await expect(definitionV4).toMatchFileSnapshot(\n `__snapshots__/${snapshotDir}/${currentTestName}-v4.txt`\n );\n}\n\nexport function hasReferences<T>(references?: T[]): references is T[] {\n return Array.isArray(references) && references.length > 0;\n}\n"],"mappings":";;;AAEA,SAAgB,cAAc,OAAkD;AAC9E,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM;;AAG7E,eAAsB,gBAAgB,cAAqC;CACzE,MAAM,EAAE,iBAAiB,kBAAkB,OAAO,UAAU;CAE5D,MAAM,cAAc,KAAK,SAAS,cAAc,aAAa,CAAC,QAAQ,sBAAsB,GAAG;AAC/F,OAAM,OAAO,aAAa,CAAC,oBACzB,iBAAiB,YAAY,GAAG,gBAAgB,SACjD;;AAGH,SAAgB,cAAiB,YAAqC;AACpE,QAAO,MAAM,QAAQ,WAAW,IAAI,WAAW,SAAS"}
@@ -0,0 +1,58 @@
1
+ import { isPlainObject } from "./shared.js";
2
+
3
+ //#region src/commands/pull-v4/utils/templates.ts
4
+ const QUOTE = Object.freeze({
5
+ single: "'",
6
+ double: "\"",
7
+ template: "`"
8
+ });
9
+ const TEMPLATE_VARIABLE_REGEX = /\{\{(?!\{)(?<variableName>[^{}]+)}}/g;
10
+ function formatStringLiteral(value) {
11
+ const hasSingleQuote = value.includes(QUOTE.single);
12
+ const hasDoubleQuote = value.includes(QUOTE.double);
13
+ const quote = value.includes("\n") || value.includes("${") || hasSingleQuote && hasDoubleQuote ? QUOTE.template : hasSingleQuote ? QUOTE.double : QUOTE.single;
14
+ if (quote === QUOTE.template) {}
15
+ return escapeStringLiteral(value, quote);
16
+ }
17
+ function collectTemplateVariableNames(value) {
18
+ const variables = [];
19
+ for (const match of value.matchAll(TEMPLATE_VARIABLE_REGEX)) {
20
+ const variableName = match.groups?.variableName?.trim();
21
+ if (variableName) variables.push(variableName);
22
+ }
23
+ return variables;
24
+ }
25
+ function formatTemplate(value, references) {
26
+ if (!value.length) return value;
27
+ let didReplace = false;
28
+ const rewrittenValue = value.replace(TEMPLATE_VARIABLE_REGEX, (match, ...args) => {
29
+ const maybeGroups = args.at(-1);
30
+ const variableName = isPlainObject(maybeGroups) && typeof maybeGroups.variableName === "string" ? maybeGroups.variableName.trim() : void 0;
31
+ if (!variableName) return match;
32
+ if (variableName.startsWith("headers.")) {
33
+ const headerPath = variableName.slice(8);
34
+ if (!headerPath || !references.headersReference) return match;
35
+ didReplace = true;
36
+ return `\${${references.headersReference}.toTemplate(${JSON.stringify(headerPath)})}`;
37
+ }
38
+ if (!references.contextReference) return match;
39
+ didReplace = true;
40
+ return `\${${references.contextReference}.toTemplate(${JSON.stringify(variableName)})}`;
41
+ });
42
+ return didReplace ? rewrittenValue : value;
43
+ }
44
+ function formatPropertyName(key) {
45
+ if (/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key)) return key;
46
+ return formatStringLiteral(key);
47
+ }
48
+ function escapeStringLiteral(value, quote) {
49
+ return [
50
+ quote,
51
+ value.replaceAll("\\", "\\\\").replaceAll(quote, `\\${quote}`),
52
+ quote
53
+ ].join("");
54
+ }
55
+
56
+ //#endregion
57
+ export { TEMPLATE_VARIABLE_REGEX, collectTemplateVariableNames, formatPropertyName, formatStringLiteral, formatTemplate };
58
+ //# sourceMappingURL=templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.js","names":[],"sources":["../../../../src/commands/pull-v4/utils/templates.ts"],"sourcesContent":["import { isPlainObject } from './shared';\n\nconst QUOTE = Object.freeze({\n single: \"'\",\n double: '\"',\n template: '`',\n});\n\ntype Quote = (typeof QUOTE)[keyof typeof QUOTE];\n\nexport const TEMPLATE_VARIABLE_REGEX = /\\{\\{(?!\\{)(?<variableName>[^{}]+)}}/g;\n\ninterface TemplateReplacementReferences {\n contextReference?: string;\n headersReference?: string;\n}\n\nexport function formatStringLiteral(value: string): string {\n const hasSingleQuote = value.includes(QUOTE.single);\n const hasDoubleQuote = value.includes(QUOTE.double);\n const quote =\n value.includes('\\n') || value.includes('${') || (hasSingleQuote && hasDoubleQuote)\n ? QUOTE.template\n : hasSingleQuote\n ? QUOTE.double\n : QUOTE.single;\n if (quote === QUOTE.template) {\n // TODO: should escape variables except when we inject context variables and headers\n // value = value.replaceAll('${', '\\\\${');\n }\n return escapeStringLiteral(value, quote);\n}\n\nexport function collectTemplateVariableNames(value: string): string[] {\n const variables: string[] = [];\n for (const match of value.matchAll(TEMPLATE_VARIABLE_REGEX)) {\n const variableName = match.groups?.variableName?.trim();\n if (variableName) {\n variables.push(variableName);\n }\n }\n return variables;\n}\n\nexport function formatTemplate(value: string, references: TemplateReplacementReferences): string {\n if (!value.length) {\n return value;\n }\n\n let didReplace = false;\n const rewrittenValue = value.replace(\n TEMPLATE_VARIABLE_REGEX,\n (match: string, ...args: unknown[]): string => {\n const maybeGroups = args.at(-1);\n const variableName =\n isPlainObject(maybeGroups) && typeof maybeGroups.variableName === 'string'\n ? maybeGroups.variableName.trim()\n : undefined;\n\n if (!variableName) {\n return match;\n }\n\n if (variableName.startsWith('headers.')) {\n const headerPath = variableName.slice('headers.'.length);\n if (!headerPath || !references.headersReference) {\n return match;\n }\n didReplace = true;\n return `\\${${references.headersReference}.toTemplate(${JSON.stringify(headerPath)})}`;\n }\n\n if (!references.contextReference) {\n return match;\n }\n\n didReplace = true;\n return `\\${${references.contextReference}.toTemplate(${JSON.stringify(variableName)})}`;\n }\n );\n\n return didReplace ? rewrittenValue : value;\n}\n\nexport function formatPropertyName(key: string): string {\n if (/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key)) {\n return key;\n }\n return formatStringLiteral(key);\n}\n\nfunction escapeStringLiteral(value: string, quote: Quote): string {\n return [quote, value.replaceAll('\\\\', '\\\\\\\\').replaceAll(quote, `\\\\${quote}`), quote].join('');\n}\n"],"mappings":";;;AAEA,MAAM,QAAQ,OAAO,OAAO;CAC1B,QAAQ;CACR,QAAQ;CACR,UAAU;CACX,CAAC;AAIF,MAAa,0BAA0B;AAOvC,SAAgB,oBAAoB,OAAuB;CACzD,MAAM,iBAAiB,MAAM,SAAS,MAAM,OAAO;CACnD,MAAM,iBAAiB,MAAM,SAAS,MAAM,OAAO;CACnD,MAAM,QACJ,MAAM,SAAS,KAAK,IAAI,MAAM,SAAS,KAAK,IAAK,kBAAkB,iBAC/D,MAAM,WACN,iBACE,MAAM,SACN,MAAM;AACd,KAAI,UAAU,MAAM,UAAU;AAI9B,QAAO,oBAAoB,OAAO,MAAM;;AAG1C,SAAgB,6BAA6B,OAAyB;CACpE,MAAM,YAAsB,EAAE;AAC9B,MAAK,MAAM,SAAS,MAAM,SAAS,wBAAwB,EAAE;EAC3D,MAAM,eAAe,MAAM,QAAQ,cAAc,MAAM;AACvD,MAAI,aACF,WAAU,KAAK,aAAa;;AAGhC,QAAO;;AAGT,SAAgB,eAAe,OAAe,YAAmD;AAC/F,KAAI,CAAC,MAAM,OACT,QAAO;CAGT,IAAI,aAAa;CACjB,MAAM,iBAAiB,MAAM,QAC3B,0BACC,OAAe,GAAG,SAA4B;EAC7C,MAAM,cAAc,KAAK,GAAG,GAAG;EAC/B,MAAM,eACJ,cAAc,YAAY,IAAI,OAAO,YAAY,iBAAiB,WAC9D,YAAY,aAAa,MAAM,GAC/B;AAEN,MAAI,CAAC,aACH,QAAO;AAGT,MAAI,aAAa,WAAW,WAAW,EAAE;GACvC,MAAM,aAAa,aAAa,MAAM,EAAkB;AACxD,OAAI,CAAC,cAAc,CAAC,WAAW,iBAC7B,QAAO;AAET,gBAAa;AACb,UAAO,MAAM,WAAW,iBAAiB,cAAc,KAAK,UAAU,WAAW,CAAC;;AAGpF,MAAI,CAAC,WAAW,iBACd,QAAO;AAGT,eAAa;AACb,SAAO,MAAM,WAAW,iBAAiB,cAAc,KAAK,UAAU,aAAa,CAAC;GAEvF;AAED,QAAO,aAAa,iBAAiB;;AAGvC,SAAgB,mBAAmB,KAAqB;AACtD,KAAI,6BAA6B,KAAK,IAAI,CACxC,QAAO;AAET,QAAO,oBAAoB,IAAI;;AAGjC,SAAS,oBAAoB,OAAe,OAAsB;AAChE,QAAO;EAAC;EAAO,MAAM,WAAW,MAAM,OAAO,CAAC,WAAW,OAAO,KAAK,QAAQ;EAAE;EAAM,CAAC,KAAK,GAAG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inkeep/agents-cli",
3
- "version": "0.59.3",
3
+ "version": "0.59.4",
4
4
  "description": "Inkeep CLI tool",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -37,8 +37,8 @@
37
37
  "tsx": "^4.20.5",
38
38
  "yaml": "^2.7.0",
39
39
  "zod": "^4.3.6",
40
- "@inkeep/agents-core": "^0.59.3",
41
- "@inkeep/agents-sdk": "^0.59.3"
40
+ "@inkeep/agents-core": "^0.59.4",
41
+ "@inkeep/agents-sdk": "^0.59.4"
42
42
  },
43
43
  "devDependencies": {
44
44
  "diff": "^8.0.3",
@@ -46,7 +46,7 @@
46
46
  "@types/fs-extra": "^11.0.4",
47
47
  "@types/node": "^22",
48
48
  "@vitest/coverage-v8": "^3.2.4",
49
- "typescript": "^5.9.2",
49
+ "typescript": "^6.0.2",
50
50
  "vitest": "^3.2.4"
51
51
  },
52
52
  "peerDependencies": {
@@ -1 +0,0 @@
1
- {"version":3,"file":"skill-generator.js","names":[],"sources":["../../../../src/commands/pull-v4/generators/skill-generator.ts"],"sourcesContent":["import { mkdir, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { FullProjectDefinitionSchema } from '@inkeep/agents-core';\nimport { stringify } from 'yaml';\nimport type { z } from 'zod';\n\nconst MySchema = FullProjectDefinitionSchema.shape.skills.unwrap().valueType;\n\ntype SkillInput = z.input<typeof MySchema>;\n\ntype SkillMap = Record<string, SkillInput>;\n\nfunction formatMetadata(metadata: NonNullable<SkillInput['metadata']>): string {\n const yaml = stringify(metadata);\n const indented = yaml\n .split('\\n')\n .filter((line) => line.trim() !== '')\n .map((line) => ` ${line}`)\n .join('\\n');\n return `metadata:\\n${indented}`;\n}\n\nexport async function generateSkills(skills: SkillMap, skillsDir: string): Promise<void> {\n await mkdir(skillsDir, { recursive: true });\n\n for (const [skillId, skill] of Object.entries(skills)) {\n const parts: string[] = ['---', `name: ${JSON.stringify(skill.name)}`];\n parts.push(`description: ${JSON.stringify(skill.description ?? '')}`);\n\n if (skill.metadata && Object.keys(skill.metadata).length > 0) {\n parts.push(formatMetadata(skill.metadata));\n }\n\n parts.push('---', '', skill.content || '');\n\n const skillDir = join(skillsDir, skillId);\n await mkdir(skillDir, { recursive: true });\n\n const filePath = join(skillDir, 'SKILL.md');\n await writeFile(filePath, parts.join('\\n'), 'utf8');\n }\n}\n"],"mappings":";;;;;;AAMiB,4BAA4B,MAAM,OAAO,QAAQ,CAAC;AAMnE,SAAS,eAAe,UAAuD;AAO7E,QAAO,cANM,UAAU,SAAS,CAE7B,MAAM,KAAK,CACX,QAAQ,SAAS,KAAK,MAAM,KAAK,GAAG,CACpC,KAAK,SAAS,KAAK,OAAO,CAC1B,KAAK,KAAK;;AAIf,eAAsB,eAAe,QAAkB,WAAkC;AACvF,OAAM,MAAM,WAAW,EAAE,WAAW,MAAM,CAAC;AAE3C,MAAK,MAAM,CAAC,SAAS,UAAU,OAAO,QAAQ,OAAO,EAAE;EACrD,MAAM,QAAkB,CAAC,OAAO,SAAS,KAAK,UAAU,MAAM,KAAK,GAAG;AACtE,QAAM,KAAK,gBAAgB,KAAK,UAAU,MAAM,eAAe,GAAG,GAAG;AAErE,MAAI,MAAM,YAAY,OAAO,KAAK,MAAM,SAAS,CAAC,SAAS,EACzD,OAAM,KAAK,eAAe,MAAM,SAAS,CAAC;AAG5C,QAAM,KAAK,OAAO,IAAI,MAAM,WAAW,GAAG;EAE1C,MAAM,WAAW,KAAK,WAAW,QAAQ;AACzC,QAAM,MAAM,UAAU,EAAE,WAAW,MAAM,CAAC;AAG1C,QAAM,UADW,KAAK,UAAU,WAAW,EACjB,MAAM,KAAK,KAAK,EAAE,OAAO"}
@@ -1,38 +0,0 @@
1
- import { addValueToObject, createFactoryDefinition, toTriggerReferenceName } from "./utils.js";
2
- import { FullProjectDefinitionSchema } from "@inkeep/agents-core";
3
- import { z } from "zod";
4
- import { SyntaxKind } from "ts-morph";
5
-
6
- //#region src/commands/pull-v4/scheduled-trigger-generator.ts
7
- const MySchema = FullProjectDefinitionSchema.shape.agents.valueType.shape.scheduledTriggers.unwrap().valueType.omit({
8
- id: true,
9
- runAsUserId: true,
10
- createdBy: true
11
- });
12
- const ScheduledTriggerSchema = z.strictObject({
13
- scheduledTriggerId: z.string().nonempty(),
14
- ...MySchema.shape,
15
- description: z.preprocess((v) => v ?? void 0, MySchema.shape.description),
16
- runAt: z.preprocess((v) => v ?? void 0, MySchema.shape.runAt),
17
- payload: z.preprocess((v) => v ?? void 0, MySchema.shape.payload)
18
- });
19
- function generateScheduledTriggerDefinition({ id, runAsUserId, createdBy, ...data }) {
20
- const result = ScheduledTriggerSchema.safeParse(data);
21
- if (!result.success) throw new Error(`Validation failed for scheduled trigger:\n${z.prettifyError(result.error)}`);
22
- const parsed = result.data;
23
- const { sourceFile, configObject } = createFactoryDefinition({
24
- importName: "ScheduledTrigger",
25
- variableName: toTriggerReferenceName(parsed.name),
26
- syntaxKind: SyntaxKind.NewExpression
27
- });
28
- const { scheduledTriggerId, ...rest } = parsed;
29
- for (const [key, value] of Object.entries({
30
- id: scheduledTriggerId,
31
- ...rest
32
- })) addValueToObject(configObject, key, value);
33
- return sourceFile;
34
- }
35
-
36
- //#endregion
37
- export { generateScheduledTriggerDefinition };
38
- //# sourceMappingURL=scheduled-trigger-generator.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scheduled-trigger-generator.js","names":[],"sources":["../../../src/commands/pull-v4/scheduled-trigger-generator.ts"],"sourcesContent":["import { FullProjectDefinitionSchema } from '@inkeep/agents-core';\nimport { type SourceFile, SyntaxKind } from 'ts-morph';\nimport { z } from 'zod';\nimport { addValueToObject, createFactoryDefinition, toTriggerReferenceName } from './utils';\n\nconst MySchema = FullProjectDefinitionSchema.shape.agents.valueType.shape.scheduledTriggers\n .unwrap()\n .valueType.omit({\n id: true,\n runAsUserId: true,\n createdBy: true,\n });\n\nconst ScheduledTriggerSchema = z.strictObject({\n scheduledTriggerId: z.string().nonempty(),\n ...MySchema.shape,\n description: z.preprocess((v) => v ?? undefined, MySchema.shape.description),\n runAt: z.preprocess((v) => v ?? undefined, MySchema.shape.runAt),\n payload: z.preprocess((v) => v ?? undefined, MySchema.shape.payload),\n});\n\ntype ScheduledTriggerInput = z.input<typeof ScheduledTriggerSchema>;\n\nexport function generateScheduledTriggerDefinition({\n id,\n runAsUserId,\n createdBy,\n ...data\n}: ScheduledTriggerInput & Record<string, unknown>): SourceFile {\n const result = ScheduledTriggerSchema.safeParse(data);\n if (!result.success) {\n throw new Error(`Validation failed for scheduled trigger:\\n${z.prettifyError(result.error)}`);\n }\n\n const parsed = result.data;\n const { sourceFile, configObject } = createFactoryDefinition({\n importName: 'ScheduledTrigger',\n variableName: toTriggerReferenceName(parsed.name),\n syntaxKind: SyntaxKind.NewExpression,\n });\n\n const { scheduledTriggerId, ...rest } = parsed;\n\n for (const [key, value] of Object.entries({\n id: scheduledTriggerId,\n ...rest,\n })) {\n addValueToObject(configObject, key, value);\n }\n\n return sourceFile;\n}\n"],"mappings":";;;;;;AAKA,MAAM,WAAW,4BAA4B,MAAM,OAAO,UAAU,MAAM,kBACvE,QAAQ,CACR,UAAU,KAAK;CACd,IAAI;CACJ,aAAa;CACb,WAAW;CACZ,CAAC;AAEJ,MAAM,yBAAyB,EAAE,aAAa;CAC5C,oBAAoB,EAAE,QAAQ,CAAC,UAAU;CACzC,GAAG,SAAS;CACZ,aAAa,EAAE,YAAY,MAAM,KAAK,QAAW,SAAS,MAAM,YAAY;CAC5E,OAAO,EAAE,YAAY,MAAM,KAAK,QAAW,SAAS,MAAM,MAAM;CAChE,SAAS,EAAE,YAAY,MAAM,KAAK,QAAW,SAAS,MAAM,QAAQ;CACrE,CAAC;AAIF,SAAgB,mCAAmC,EACjD,IACA,aACA,WACA,GAAG,QAC2D;CAC9D,MAAM,SAAS,uBAAuB,UAAU,KAAK;AACrD,KAAI,CAAC,OAAO,QACV,OAAM,IAAI,MAAM,6CAA6C,EAAE,cAAc,OAAO,MAAM,GAAG;CAG/F,MAAM,SAAS,OAAO;CACtB,MAAM,EAAE,YAAY,iBAAiB,wBAAwB;EAC3D,YAAY;EACZ,cAAc,uBAAuB,OAAO,KAAK;EACjD,YAAY,WAAW;EACxB,CAAC;CAEF,MAAM,EAAE,oBAAoB,GAAG,SAAS;AAExC,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ;EACxC,IAAI;EACJ,GAAG;EACJ,CAAC,CACA,kBAAiB,cAAc,KAAK,MAAM;AAG5C,QAAO"}
@@ -1,320 +0,0 @@
1
- import path from "node:path";
2
- import { IndentationText, NewLineKind, Project, QuoteKind, SyntaxKind, VariableDeclarationKind } from "ts-morph";
3
- import { jsonSchemaToZod } from "json-schema-to-zod";
4
-
5
- //#region src/commands/pull-v4/utils.ts
6
- function createInMemoryProject() {
7
- return new Project({
8
- useInMemoryFileSystem: true,
9
- skipLoadingLibFiles: true,
10
- manipulationSettings: {
11
- indentationText: IndentationText.TwoSpaces,
12
- quoteKind: QuoteKind.Single,
13
- newLineKind: NewLineKind.LineFeed,
14
- useTrailingCommas: true
15
- }
16
- });
17
- }
18
- /**
19
- * Create variable in following pattern
20
- *
21
- * (export)? const VARIABLE_NAME = (new)?IMPORT_NAME({})
22
- */
23
- function addFactoryConfigVariable({ sourceFile, importName, variableName, isExported, syntaxKind = SyntaxKind.CallExpression }) {
24
- const initializer = `${syntaxKind === SyntaxKind.NewExpression ? "new " : ""}${importName}({})`;
25
- const [declaration] = sourceFile.addVariableStatement({
26
- declarationKind: VariableDeclarationKind.Const,
27
- isExported,
28
- declarations: [{
29
- name: variableName,
30
- initializer
31
- }]
32
- }).getDeclarations();
33
- const [configArg] = declaration.getInitializerIfKindOrThrow(syntaxKind).getArguments();
34
- return { configObject: configArg.asKindOrThrow(SyntaxKind.ObjectLiteralExpression) };
35
- }
36
- function createFactoryDefinition({ importName, variableName: name, fileName = "definition.ts", moduleSpecifier = "@inkeep/agents-sdk", syntaxKind }) {
37
- const sourceFile = createInMemoryProject().createSourceFile(fileName, "", { overwrite: true });
38
- sourceFile.addImportDeclaration({
39
- namedImports: [importName],
40
- moduleSpecifier
41
- });
42
- const localVariableName = resolveNonCollidingName(name, collectTakenNames(sourceFile));
43
- const shouldAliasExport = localVariableName !== name;
44
- const { configObject } = addFactoryConfigVariable({
45
- sourceFile,
46
- importName,
47
- variableName: localVariableName,
48
- isExported: !shouldAliasExport,
49
- syntaxKind
50
- });
51
- if (shouldAliasExport) sourceFile.addExportDeclaration({ namedExports: [{
52
- name: localVariableName,
53
- alias: name
54
- }] });
55
- return {
56
- sourceFile,
57
- configObject
58
- };
59
- }
60
- function collectTakenNames(sourceFile) {
61
- const takenNames = /* @__PURE__ */ new Set();
62
- for (const importDeclaration of sourceFile.getImportDeclarations()) {
63
- const defaultImport = importDeclaration.getDefaultImport()?.getText();
64
- if (defaultImport) takenNames.add(defaultImport);
65
- const namespaceImport = importDeclaration.getNamespaceImport()?.getText();
66
- if (namespaceImport) takenNames.add(namespaceImport);
67
- for (const namedImport of importDeclaration.getNamedImports()) {
68
- const localName = namedImport.getAliasNode()?.getText() ?? namedImport.getName();
69
- takenNames.add(localName);
70
- }
71
- }
72
- for (const variableDeclaration of sourceFile.getVariableDeclarations()) takenNames.add(variableDeclaration.getName());
73
- return takenNames;
74
- }
75
- function resolveNonCollidingName(baseName, reservedNames, startIndex = 1) {
76
- if (!reservedNames.has(baseName)) {
77
- reservedNames.add(baseName);
78
- return baseName;
79
- }
80
- let index = startIndex;
81
- while (reservedNames.has(`${baseName}${index}`)) index += 1;
82
- const uniqueName = `${baseName}${index}`;
83
- reservedNames.add(uniqueName);
84
- return uniqueName;
85
- }
86
- function toCamelCase(input) {
87
- const result = input.toLowerCase().replaceAll(/\W/g, " ").trim().replaceAll(/[\s_]+(.)/g, (_, char) => char.toUpperCase()).replace(/^[0-9]/, "_$&");
88
- return result.charAt(0).toLowerCase() + result.slice(1);
89
- }
90
- function toToolReferenceName(input) {
91
- const base = toCamelCase(input);
92
- return base.endsWith("Tool") ? base : `${base}Tool`;
93
- }
94
- function toCredentialReferenceName(input) {
95
- const base = toCamelCase(input);
96
- return base.endsWith("Credential") ? base : `${base}Credential`;
97
- }
98
- function toTriggerReferenceName(input) {
99
- const base = toCamelCase(input);
100
- return base.endsWith("Trigger") ? base : `${base}Trigger`;
101
- }
102
- function toKebabCase(input) {
103
- return input.trim().replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").toLowerCase();
104
- }
105
- const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
106
- const CUID_RE = /^c[a-z0-9]{24,}$/;
107
- const NANOID_RE = /^[a-z0-9]{16,}$/;
108
- function isHumanReadableId(id) {
109
- if (UUID_RE.test(id) || CUID_RE.test(id) || NANOID_RE.test(id)) return false;
110
- const segments = id.split(/[-_]/);
111
- if (segments.length === 1 && id.length > 8) {
112
- const hasLetters = /[a-zA-Z]/.test(id);
113
- const hasDigits = /[0-9]/.test(id);
114
- if (hasLetters && hasDigits) return false;
115
- }
116
- return segments.filter((s) => /^[a-zA-Z]+\d{0,2}$/.test(s)).length / segments.length >= .5;
117
- }
118
- const ID_SUFFIX_LENGTH = 8;
119
- function buildComponentFileName(id, name) {
120
- if (!name || isHumanReadableId(id)) return `${id}.ts`;
121
- const kebabName = toKebabCase(name);
122
- if (!kebabName || kebabName === id) return `${id}.ts`;
123
- return `${kebabName}-${id.slice(-ID_SUFFIX_LENGTH)}.ts`;
124
- }
125
- function createUniqueReferenceName(baseName, reservedNames, conflictSuffix) {
126
- if (!reservedNames.has(baseName)) {
127
- reservedNames.add(baseName);
128
- return baseName;
129
- }
130
- const baseCandidate = `${baseName}${conflictSuffix}`;
131
- if (!reservedNames.has(baseCandidate)) {
132
- reservedNames.add(baseCandidate);
133
- return baseCandidate;
134
- }
135
- return resolveNonCollidingName(baseCandidate, reservedNames, 2);
136
- }
137
- function resolveImportedReference(importName, reservedNames, conflictSuffix, isLocal = false) {
138
- if (isLocal) {
139
- reservedNames.add(importName);
140
- return { referenceName: importName };
141
- }
142
- const referenceName = createUniqueReferenceName(importName, reservedNames, conflictSuffix);
143
- return {
144
- referenceName,
145
- namedImport: importName === referenceName ? importName : {
146
- name: importName,
147
- alias: referenceName
148
- }
149
- };
150
- }
151
- function resolveContextTemplateImports(options) {
152
- const namedImports = [];
153
- let contextReferenceName;
154
- let headersReferenceName;
155
- if (options.shouldResolveContextReference) {
156
- const contextImportName = options.contextConfigReference?.name ?? options.defaultContextImportName;
157
- if (contextImportName) {
158
- const contextImportRef = resolveImportedReference(contextImportName, options.reservedNames, "ContextConfig", options.contextConfigReference?.local === true);
159
- contextReferenceName = contextImportRef.referenceName;
160
- if (contextImportRef.namedImport) namedImports.push(contextImportRef.namedImport);
161
- }
162
- }
163
- if (options.shouldResolveHeadersReference) {
164
- const headersImportName = options.contextConfigHeadersReference?.name ?? options.defaultHeadersImportName;
165
- if (headersImportName) {
166
- const headersImportRef = resolveImportedReference(headersImportName, options.reservedNames, "Headers", options.contextConfigHeadersReference?.local === true);
167
- headersReferenceName = headersImportRef.referenceName;
168
- if (headersImportRef.namedImport) namedImports.push(headersImportRef.namedImport);
169
- }
170
- }
171
- return {
172
- contextReferenceName,
173
- headersReferenceName,
174
- namedImports
175
- };
176
- }
177
- function resolveReferenceName(referenceId, referenceOverrides) {
178
- for (const overrideMap of referenceOverrides) {
179
- const overrideName = overrideMap?.[referenceId];
180
- if (overrideName) return overrideName;
181
- }
182
- return toCamelCase(referenceId);
183
- }
184
- function convertJsonSchemaToZodSafe(schema, options) {
185
- if (!isPlainObject(schema)) {
186
- console.warn("Schema conversion skipped: non-object schema provided, using z.any()");
187
- return "z.any()";
188
- }
189
- try {
190
- return jsonSchemaToZod(schema, options?.conversionOptions);
191
- } catch (error) {
192
- console.warn(`Schema conversion failed: ${error instanceof Error ? error.message : String(error)}. Falling back to z.any()`);
193
- return "z.any()";
194
- }
195
- }
196
- function isPlainObject(value) {
197
- return typeof value === "object" && value !== null && !Array.isArray(value);
198
- }
199
- const QUOTE = Object.freeze({
200
- single: "'",
201
- double: "\"",
202
- template: "`"
203
- });
204
- const TEMPLATE_VARIABLE_REGEX = /\{\{(?!\{)(?<variableName>[^{}]+)}}/g;
205
- function formatStringLiteral(value) {
206
- const hasSingleQuote = value.includes(QUOTE.single);
207
- const hasDoubleQuote = value.includes(QUOTE.double);
208
- return escapeStringLiteral(value, value.includes("\n") || value.includes("${") || hasSingleQuote && hasDoubleQuote ? QUOTE.template : hasSingleQuote ? QUOTE.double : QUOTE.single);
209
- }
210
- function collectTemplateVariableNames(value) {
211
- const variables = [];
212
- for (const match of value.matchAll(TEMPLATE_VARIABLE_REGEX)) {
213
- const variableName = match.groups?.variableName?.trim();
214
- if (variableName) variables.push(variableName);
215
- }
216
- return variables;
217
- }
218
- function formatTemplate(value, references) {
219
- if (!value.length) return value;
220
- let didReplace = false;
221
- const rewrittenValue = value.replace(TEMPLATE_VARIABLE_REGEX, (match, ...args) => {
222
- const maybeGroups = args.at(-1);
223
- const variableName = isPlainObject(maybeGroups) && typeof maybeGroups.variableName === "string" ? maybeGroups.variableName.trim() : void 0;
224
- if (!variableName) return match;
225
- if (variableName.startsWith("headers.")) {
226
- const headerPath = variableName.slice(8);
227
- if (!headerPath || !references.headersReference) return match;
228
- didReplace = true;
229
- return `\${${references.headersReference}.toTemplate(${JSON.stringify(headerPath)})}`;
230
- }
231
- if (!references.contextReference) return match;
232
- didReplace = true;
233
- return `\${${references.contextReference}.toTemplate(${JSON.stringify(variableName)})}`;
234
- });
235
- return didReplace ? rewrittenValue : value;
236
- }
237
- function escapeStringLiteral(value, quote) {
238
- return [
239
- quote,
240
- value.replaceAll("\\", "\\\\").replaceAll(quote, `\\${quote}`),
241
- quote
242
- ].join("");
243
- }
244
- function formatPropertyName(key) {
245
- if (/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key)) return key;
246
- return formatStringLiteral(key);
247
- }
248
- function formatInlineLiteral(value) {
249
- if (typeof value === "string") return formatStringLiteral(value);
250
- if (typeof value === "number" || typeof value === "bigint") return String(value);
251
- if (typeof value === "boolean") return value ? "true" : "false";
252
- if (value === null) return "null";
253
- if (Array.isArray(value)) return `[${value.map((item) => formatInlineLiteral(item)).join(", ")}]`;
254
- if (isPlainObject(value)) {
255
- const entries = Object.entries(value).filter(([, entryValue]) => entryValue !== void 0);
256
- if (!entries.length) return "{}";
257
- return `{ ${entries.map(([key, entryValue]) => `${formatPropertyName(key)}: ${formatInlineLiteral(entryValue)}`).join(", ")} }`;
258
- }
259
- return "undefined";
260
- }
261
- function addReferenceGetterProperty(configObject, key, refs) {
262
- configObject.addPropertyAssignment({
263
- name: key,
264
- initializer: "() => []"
265
- }).getInitializerIfKindOrThrow(SyntaxKind.ArrowFunction).getBody().asKindOrThrow(SyntaxKind.ArrayLiteralExpression).addElements(refs);
266
- }
267
- function addStringProperty(configObject, key, value) {
268
- configObject.addPropertyAssignment({
269
- name: key,
270
- initializer: formatStringLiteral(value)
271
- });
272
- }
273
- function addValueToObject(obj, key, value) {
274
- if (value === void 0) return;
275
- if (isPlainObject(value)) {
276
- const child = obj.addPropertyAssignment({
277
- name: formatPropertyName(key),
278
- initializer: "{}"
279
- }).getInitializerIfKindOrThrow(SyntaxKind.ObjectLiteralExpression);
280
- for (const [k, v] of Object.entries(value)) addValueToObject(child, k, v);
281
- return;
282
- }
283
- if (Array.isArray(value)) {
284
- const arr = obj.addPropertyAssignment({
285
- name: formatPropertyName(key),
286
- initializer: "[]"
287
- }).getInitializerIfKindOrThrow(SyntaxKind.ArrayLiteralExpression);
288
- for (const item of value) addValueToArray(arr, item);
289
- return;
290
- }
291
- obj.addPropertyAssignment({
292
- name: formatPropertyName(key),
293
- initializer: formatInlineLiteral(value)
294
- });
295
- }
296
- function addValueToArray(arr, value) {
297
- if (isPlainObject(value)) {
298
- const child = arr.addElement("{}").asKindOrThrow(SyntaxKind.ObjectLiteralExpression);
299
- for (const [k, v] of Object.entries(value)) addValueToObject(child, k, v);
300
- return;
301
- }
302
- if (Array.isArray(value)) {
303
- const child = arr.addElement("[]").asKindOrThrow(SyntaxKind.ArrayLiteralExpression);
304
- for (const item of value) addValueToArray(child, item);
305
- return;
306
- }
307
- arr.addElement(formatInlineLiteral(value));
308
- }
309
- async function expectSnapshots(definitionV4) {
310
- const { currentTestName, snapshotState } = expect.getState();
311
- const snapshotDir = path.basename(snapshotState.testFilePath).replace("-generator.test.ts", "");
312
- await expect(definitionV4).toMatchFileSnapshot(`__snapshots__/${snapshotDir}/${currentTestName}-v4.txt`);
313
- }
314
- function hasReferences(references) {
315
- return Array.isArray(references) && references.length > 0;
316
- }
317
-
318
- //#endregion
319
- export { TEMPLATE_VARIABLE_REGEX, addFactoryConfigVariable, addReferenceGetterProperty, addStringProperty, addValueToObject, buildComponentFileName, collectTemplateVariableNames, convertJsonSchemaToZodSafe, createFactoryDefinition, createInMemoryProject, createUniqueReferenceName, expectSnapshots, formatInlineLiteral, formatPropertyName, formatStringLiteral, formatTemplate, hasReferences, isHumanReadableId, isPlainObject, resolveContextTemplateImports, resolveImportedReference, resolveNonCollidingName, resolveReferenceName, toCamelCase, toCredentialReferenceName, toKebabCase, toToolReferenceName, toTriggerReferenceName };
320
- //# sourceMappingURL=utils.js.map