@inkeep/agents-cli 0.41.2 → 0.43.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.
Files changed (41) hide show
  1. package/README.md +13 -20
  2. package/dist/api.js +8 -8
  3. package/dist/commands/init.js +19 -39
  4. package/dist/commands/list-agents.js +1 -1
  5. package/dist/commands/login.js +4 -4
  6. package/dist/commands/profile.js +7 -26
  7. package/dist/commands/pull-v3/component-parser.js +0 -2
  8. package/dist/commands/pull-v3/component-updater.js +122 -64
  9. package/dist/commands/pull-v3/components/agent-generator.js +17 -3
  10. package/dist/commands/pull-v3/components/artifact-component-generator.js +7 -7
  11. package/dist/commands/pull-v3/components/context-config-generator.js +6 -6
  12. package/dist/commands/pull-v3/components/credential-generator.js +4 -4
  13. package/dist/commands/pull-v3/components/data-component-generator.js +4 -4
  14. package/dist/commands/pull-v3/components/environment-generator.js +10 -7
  15. package/dist/commands/pull-v3/components/function-tool-generator.js +5 -7
  16. package/dist/commands/pull-v3/components/mcp-tool-generator.js +5 -5
  17. package/dist/commands/pull-v3/components/project-generator.js +4 -4
  18. package/dist/commands/pull-v3/components/status-component-generator.js +6 -6
  19. package/dist/commands/pull-v3/components/trigger-generator.js +185 -0
  20. package/dist/commands/pull-v3/index.js +25 -30
  21. package/dist/commands/pull-v3/introspect-generator.js +15 -7
  22. package/dist/commands/pull-v3/llm-content-merger.js +1 -1
  23. package/dist/commands/pull-v3/new-component-generator.js +5 -16
  24. package/dist/commands/pull-v3/project-comparator.js +49 -49
  25. package/dist/commands/pull-v3/project-validator.js +5 -4
  26. package/dist/commands/pull-v3/targeted-typescript-placeholders.js +2 -2
  27. package/dist/commands/pull-v3/utils/component-registry.js +9 -7
  28. package/dist/commands/pull-v3/utils/component-tracker.js +1 -1
  29. package/dist/commands/pull-v3/utils/generator-utils.js +2 -2
  30. package/dist/commands/push.js +9 -9
  31. package/dist/commands/status.js +4 -8
  32. package/dist/index.js +2 -2
  33. package/dist/utils/ci-environment.js +4 -6
  34. package/dist/utils/cli-pipeline.js +8 -12
  35. package/dist/utils/config.js +17 -25
  36. package/dist/utils/json-comparison.js +3 -3
  37. package/dist/utils/profile-config.js +4 -6
  38. package/dist/utils/profiles/profile-manager.js +1 -1
  39. package/dist/utils/profiles/types.js +6 -9
  40. package/dist/utils/templates.js +3 -5
  41. package/package.json +7 -8
@@ -4,10 +4,13 @@ const DEFAULT_STYLE = {
4
4
  semicolons: true,
5
5
  indentation: " "
6
6
  };
7
+ /**
8
+ * Utility functions
9
+ */
7
10
  function formatString(str, quote = "'", multiline = false) {
8
11
  if (!str) return `${quote}${quote}`;
9
12
  if (multiline && (str.includes("\n") || str.length > 80)) return `\`${str.replace(/`/g, "\\`")}\``;
10
- return `${quote}${str.replace(new RegExp(quote, "g"), "\\" + quote)}${quote}`;
13
+ return `${quote}${str.replace(new RegExp(quote, "g"), `\\${quote}`)}${quote}`;
11
14
  }
12
15
  /**
13
16
  * Format credentials object for environment settings
@@ -55,7 +58,7 @@ function formatCredentialsObject(credentials, style, indentLevel) {
55
58
  function generateEnvironmentSettingsDefinition(environmentName, environmentData, style = DEFAULT_STYLE) {
56
59
  if (!environmentName || typeof environmentName !== "string") throw new Error("environmentName is required and must be a string");
57
60
  if (!environmentData || typeof environmentData !== "object") throw new Error(`environmentData is required for environment '${environmentName}'`);
58
- const { quotes, semicolons, indentation } = style;
61
+ const { semicolons, indentation } = style;
59
62
  const semi = semicolons ? ";" : "";
60
63
  const lines = [];
61
64
  lines.push(`export const ${environmentName} = registerEnvironmentSettings({`);
@@ -71,7 +74,7 @@ function generateEnvironmentSettingsDefinition(environmentName, environmentData,
71
74
  * Generate Main Environment Settings Index (index.ts)
72
75
  */
73
76
  function generateEnvironmentIndexDefinition(environments, style = DEFAULT_STYLE) {
74
- const { quotes, semicolons, indentation } = style;
77
+ const { semicolons, indentation } = style;
75
78
  const semi = semicolons ? ";" : "";
76
79
  const lines = [];
77
80
  lines.push(`export const envSettings = createEnvironmentSettings({`);
@@ -83,7 +86,7 @@ function generateEnvironmentIndexDefinition(environments, style = DEFAULT_STYLE)
83
86
  /**
84
87
  * Generate imports for individual environment settings file
85
88
  */
86
- function generateEnvironmentSettingsImports(environmentName, environmentData, style = DEFAULT_STYLE) {
89
+ function generateEnvironmentSettingsImports(environmentData, style = DEFAULT_STYLE) {
87
90
  const { quotes, semicolons } = style;
88
91
  const q = quotes === "single" ? "'" : "\"";
89
92
  const semi = semicolons ? ";" : "";
@@ -112,9 +115,9 @@ function generateEnvironmentIndexImports(environments, style = DEFAULT_STYLE) {
112
115
  * Generate complete environment settings file
113
116
  */
114
117
  function generateEnvironmentSettingsFile(environmentName, environmentData, style = DEFAULT_STYLE) {
115
- const imports = generateEnvironmentSettingsImports(environmentName, environmentData, style);
118
+ const imports = generateEnvironmentSettingsImports(environmentData, style);
116
119
  const definition = generateEnvironmentSettingsDefinition(environmentName, environmentData, style);
117
- return imports.join("\n") + "\n\n" + definition + "\n";
120
+ return `${imports.join("\n")}\n\n${definition}\n`;
118
121
  }
119
122
  /**
120
123
  * Generate complete environment index file
@@ -122,7 +125,7 @@ function generateEnvironmentSettingsFile(environmentName, environmentData, style
122
125
  function generateEnvironmentIndexFile(environments, style = DEFAULT_STYLE) {
123
126
  const imports = generateEnvironmentIndexImports(environments, style);
124
127
  const definition = generateEnvironmentIndexDefinition(environments, style);
125
- return imports.join("\n") + "\n\n" + definition + "\n";
128
+ return `${imports.join("\n")}\n\n${definition}\n`;
126
129
  }
127
130
  /**
128
131
  * Generate environment file (alias for generateEnvironmentSettingsFile)
@@ -1,5 +1,3 @@
1
- import { jsonSchemaToZod } from "json-schema-to-zod";
2
-
3
1
  //#region src/commands/pull-v3/components/function-tool-generator.ts
4
2
  const DEFAULT_STYLE = {
5
3
  quotes: "single",
@@ -15,7 +13,7 @@ function toCamelCase(str) {
15
13
  function formatString(str, quote = "'", multiline = false) {
16
14
  if (!str) return `${quote}${quote}`;
17
15
  if (multiline && (str.includes("\n") || str.length > 80)) return `\`${str.replace(/`/g, "\\`")}\``;
18
- return `${quote}${str.replace(new RegExp(quote, "g"), "\\" + quote)}${quote}`;
16
+ return `${quote}${str.replace(new RegExp(quote, "g"), `\\${quote}`)}${quote}`;
19
17
  }
20
18
  /**
21
19
  * Format JavaScript function code with proper indentation
@@ -54,7 +52,7 @@ function generateFunctionToolDefinition(toolId, toolData, style = DEFAULT_STYLE)
54
52
  if (index === 0) return `${indentation}inputSchema: ${line}`;
55
53
  return `${indentation}${line}`;
56
54
  }).join("\n");
57
- lines.push(formattedSchema + ",");
55
+ lines.push(`${formattedSchema},`);
58
56
  }
59
57
  const executeCode = toolData.executeCode || toolData.execute;
60
58
  if (executeCode) {
@@ -73,7 +71,7 @@ function generateFunctionToolDefinition(toolId, toolData, style = DEFAULT_STYLE)
73
71
  /**
74
72
  * Generate imports needed for a function tool file
75
73
  */
76
- function generateFunctionToolImports(toolId, toolData, style = DEFAULT_STYLE) {
74
+ function generateFunctionToolImports(style = DEFAULT_STYLE) {
77
75
  const { quotes, semicolons } = style;
78
76
  const q = quotes === "single" ? "'" : "\"";
79
77
  const semi = semicolons ? ";" : "";
@@ -85,9 +83,9 @@ function generateFunctionToolImports(toolId, toolData, style = DEFAULT_STYLE) {
85
83
  * Generate complete function tool file (imports + definition)
86
84
  */
87
85
  function generateFunctionToolFile(toolId, toolData, style = DEFAULT_STYLE) {
88
- const imports = generateFunctionToolImports(toolId, toolData, style);
86
+ const imports = generateFunctionToolImports(style);
89
87
  const definition = generateFunctionToolDefinition(toolId, toolData, style);
90
- return imports.join("\n") + "\n\n" + definition + "\n";
88
+ return `${imports.join("\n")}\n\n${definition}\n`;
91
89
  }
92
90
 
93
91
  //#endregion
@@ -13,7 +13,7 @@ function toCamelCase(str) {
13
13
  function formatString(str, quote = "'", multiline = false) {
14
14
  if (!str) return `${quote}${quote}`;
15
15
  if (multiline && (str.includes("\n") || str.length > 80)) return `\`${str.replace(/`/g, "\\`")}\``;
16
- return `${quote}${str.replace(new RegExp(quote, "g"), "\\" + quote)}${quote}`;
16
+ return `${quote}${str.replace(new RegExp(quote, "g"), `\\${quote}`)}${quote}`;
17
17
  }
18
18
  /**
19
19
  * Generate MCP Tool Definition using mcpTool() builder function
@@ -47,7 +47,7 @@ function generateMcpToolDefinition(toolId, toolData, style = DEFAULT_STYLE, regi
47
47
  if (index === 0) return `${indentation}headers: ${line}`;
48
48
  return `${indentation}${line}`;
49
49
  }).join("\n");
50
- lines.push(formattedHeaders + ",");
50
+ lines.push(`${formattedHeaders},`);
51
51
  }
52
52
  if (toolData.credential) if (typeof toolData.credential === "object") {
53
53
  const credentialStr = JSON.stringify(toolData.credential);
@@ -64,7 +64,7 @@ function generateMcpToolDefinition(toolId, toolData, style = DEFAULT_STYLE, regi
64
64
  /**
65
65
  * Generate imports needed for an MCP tool file
66
66
  */
67
- function generateMcpToolImports(toolId, toolData, style = DEFAULT_STYLE) {
67
+ function generateMcpToolImports(toolData, style = DEFAULT_STYLE) {
68
68
  const { quotes, semicolons } = style;
69
69
  const q = quotes === "single" ? "'" : "\"";
70
70
  const semi = semicolons ? ";" : "";
@@ -77,9 +77,9 @@ function generateMcpToolImports(toolId, toolData, style = DEFAULT_STYLE) {
77
77
  * Generate complete MCP tool file (imports + definition)
78
78
  */
79
79
  function generateMcpToolFile(toolId, toolData, style = DEFAULT_STYLE, registry) {
80
- const imports = generateMcpToolImports(toolId, toolData, style);
80
+ const imports = generateMcpToolImports(toolData, style);
81
81
  const definition = generateMcpToolDefinition(toolId, toolData, style, registry);
82
- return imports.join("\n") + "\n\n" + definition + "\n";
82
+ return `${imports.join("\n")}\n\n${definition}\n`;
83
83
  }
84
84
 
85
85
  //#endregion
@@ -62,7 +62,7 @@ function generateProjectDefinition(projectId, projectData, style = DEFAULT_STYLE
62
62
  /**
63
63
  * Generate imports needed for a project file
64
64
  */
65
- function generateProjectImports(projectId, projectData, style = DEFAULT_STYLE, registry) {
65
+ function generateProjectImports(projectData, style = DEFAULT_STYLE, registry) {
66
66
  const imports = [];
67
67
  imports.push(generateImport(["project"], "@inkeep/agents-sdk", style));
68
68
  if (registry) {
@@ -83,8 +83,8 @@ function generateProjectImports(projectId, projectData, style = DEFAULT_STYLE, r
83
83
  else if (typeof projectData.tools === "object") toolIds = Object.keys(projectData.tools);
84
84
  for (const toolId of toolIds) {
85
85
  let componentType = "tools";
86
- if (registry && registry.get(toolId, "functionTools")) componentType = "functionTools";
87
- else if (registry && registry.get(toolId, "tools")) componentType = "tools";
86
+ if (registry?.get(toolId, "functionTools")) componentType = "functionTools";
87
+ else if (registry?.get(toolId, "tools")) componentType = "tools";
88
88
  referencedComponents.push({
89
89
  id: toolId,
90
90
  type: componentType
@@ -138,7 +138,7 @@ function generateProjectImports(projectId, projectData, style = DEFAULT_STYLE, r
138
138
  * Generate complete project file (imports + definition)
139
139
  */
140
140
  function generateProjectFile(projectId, projectData, style = DEFAULT_STYLE, registry) {
141
- return generateFileContent(generateProjectImports(projectId, projectData, style, registry), [generateProjectDefinition(projectId, projectData, style, registry)]);
141
+ return generateFileContent(generateProjectImports(projectData, style, registry), [generateProjectDefinition(projectId, projectData, style, registry)]);
142
142
  }
143
143
 
144
144
  //#endregion
@@ -21,7 +21,7 @@ function toCamelCase(str) {
21
21
  function formatString(str, quote = "'", multiline = false) {
22
22
  if (!str) return `${quote}${quote}`;
23
23
  if (multiline && (str.includes("\n") || str.length > 80)) return `\`${str.replace(/`/g, "\\`")}\``;
24
- return `${quote}${str.replace(new RegExp(quote, "g"), "\\" + quote)}${quote}`;
24
+ return `${quote}${str.replace(new RegExp(quote, "g"), `\\${quote}`)}${quote}`;
25
25
  }
26
26
  /**
27
27
  * Convert JSON Schema to Zod schema using existing utility
@@ -58,9 +58,9 @@ function generateStatusComponentDefinition(componentId, componentData, style = D
58
58
  const schemaLines = zodSchema.split("\n");
59
59
  lines.push(`${indentation}detailsSchema: ${schemaLines[0]}`);
60
60
  schemaLines.slice(1, -1).forEach((line) => {
61
- lines[lines.length - 1] += "\n" + indentation + line;
61
+ lines[lines.length - 1] += `\n${indentation}${line}`;
62
62
  });
63
- lines[lines.length - 1] += "\n" + indentation + schemaLines[schemaLines.length - 1] + ",";
63
+ lines[lines.length - 1] += `\n${indentation}${schemaLines[schemaLines.length - 1]},`;
64
64
  } else lines.push(`${indentation}detailsSchema: ${zodSchema},`);
65
65
  }
66
66
  if (lines.length > 0 && lines[lines.length - 1].endsWith(",")) lines[lines.length - 1] = lines[lines.length - 1].slice(0, -1);
@@ -70,7 +70,7 @@ function generateStatusComponentDefinition(componentId, componentData, style = D
70
70
  /**
71
71
  * Generate imports needed for a status component file
72
72
  */
73
- function generateStatusComponentImports(componentId, componentData, style = DEFAULT_STYLE) {
73
+ function generateStatusComponentImports(componentData, style = DEFAULT_STYLE) {
74
74
  const { quotes, semicolons } = style;
75
75
  const q = quotes === "single" ? "'" : "\"";
76
76
  const semi = semicolons ? ";" : "";
@@ -83,9 +83,9 @@ function generateStatusComponentImports(componentId, componentData, style = DEFA
83
83
  * Generate complete status component file (imports + definition)
84
84
  */
85
85
  function generateStatusComponentFile(componentId, componentData, style = DEFAULT_STYLE) {
86
- const imports = generateStatusComponentImports(componentId, componentData, style);
86
+ const imports = generateStatusComponentImports(componentData, style);
87
87
  const definition = generateStatusComponentDefinition(componentId, componentData, style);
88
- return imports.join("\n") + "\n\n" + definition + "\n";
88
+ return `${imports.join("\n")}\n\n${definition}\n`;
89
89
  }
90
90
 
91
91
  //#endregion
@@ -0,0 +1,185 @@
1
+ import { DEFAULT_STYLE, formatString, generateFileContent, generateImport, toCamelCase } from "../utils/generator-utils.js";
2
+
3
+ //#region src/commands/pull-v3/components/trigger-generator.ts
4
+ /**
5
+ * Trigger Generator - Generate trigger definitions
6
+ *
7
+ * Generates triggers using the Trigger class from @inkeep/agents-sdk
8
+ * Triggers are webhooks that can invoke agent conversations
9
+ */
10
+ /**
11
+ * Format authentication configuration
12
+ * New format uses headers array: { headers: [{ name, valueHash, valuePrefix }] }
13
+ * We generate code that uses environment variables for the secret values
14
+ */
15
+ function formatAuthentication(auth, style, indentLevel) {
16
+ if (!auth) return "";
17
+ const { indentation, quotes } = style;
18
+ const q = quotes === "single" ? "'" : "\"";
19
+ const indent = indentation.repeat(indentLevel);
20
+ const innerIndent = indentation.repeat(indentLevel + 1);
21
+ const headerIndent = indentation.repeat(indentLevel + 2);
22
+ const lines = [];
23
+ if (auth.headers && Array.isArray(auth.headers) && auth.headers.length > 0) {
24
+ lines.push(`${indent}authentication: {`);
25
+ lines.push(`${innerIndent}headers: [`);
26
+ for (const header of auth.headers) {
27
+ const envVarName = `TRIGGER_AUTH_${header.name.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`;
28
+ lines.push(`${headerIndent}{`);
29
+ lines.push(`${headerIndent}${indentation}name: ${q}${header.name}${q},`);
30
+ lines.push(`${headerIndent}${indentation}value: process.env.${envVarName} || ${q}${q},`);
31
+ lines.push(`${headerIndent}},`);
32
+ }
33
+ lines.push(`${innerIndent}],`);
34
+ lines.push(`${indent}},`);
35
+ }
36
+ return lines.join("\n");
37
+ }
38
+ /**
39
+ * Format output transform configuration
40
+ */
41
+ function formatOutputTransform(transform, style, indentLevel) {
42
+ if (!transform) return "";
43
+ const { indentation } = style;
44
+ const indent = indentation.repeat(indentLevel);
45
+ const innerIndent = indentation.repeat(indentLevel + 1);
46
+ const lines = [];
47
+ lines.push(`${indent}outputTransform: {`);
48
+ if (transform.jmespath) lines.push(`${innerIndent}jmespath: '${transform.jmespath}',`);
49
+ if (transform.objectTransformation) {
50
+ const formattedTransform = JSON.stringify(transform.objectTransformation, null, 2).split("\n").map((line, index) => {
51
+ if (index === 0) return `${innerIndent}objectTransformation: ${line}`;
52
+ return `${innerIndent}${line}`;
53
+ }).join("\n");
54
+ lines.push(`${formattedTransform},`);
55
+ }
56
+ if (lines.length > 1 && lines[lines.length - 1].endsWith(",")) lines[lines.length - 1] = lines[lines.length - 1].slice(0, -1);
57
+ lines.push(`${indent}},`);
58
+ return lines.join("\n");
59
+ }
60
+ /**
61
+ * Format signature verification configuration
62
+ * Generates code for signatureVerification object with all nested structures
63
+ */
64
+ function formatSignatureVerification(config, style, indentLevel) {
65
+ if (!config) return "";
66
+ const { indentation, quotes } = style;
67
+ const q = quotes === "single" ? "'" : "\"";
68
+ const indent = indentation.repeat(indentLevel);
69
+ const lines = [];
70
+ lines.push(`${indent}signatureVerification: {`);
71
+ const algorithmIndent = indentation.repeat(indentLevel + 1);
72
+ lines.push(`${algorithmIndent}algorithm: ${formatString(config.algorithm, q)},`);
73
+ lines.push(`${algorithmIndent}encoding: ${formatString(config.encoding, q)},`);
74
+ lines.push(`${algorithmIndent}signature: {`);
75
+ const sigIndent = indentation.repeat(indentLevel + 2);
76
+ lines.push(`${sigIndent}source: ${formatString(config.signature.source, q)},`);
77
+ lines.push(`${sigIndent}key: ${formatString(config.signature.key, q)},`);
78
+ if (config.signature.prefix !== void 0 && config.signature.prefix !== null) lines.push(`${sigIndent}prefix: ${formatString(config.signature.prefix, q)},`);
79
+ if (config.signature.regex !== void 0 && config.signature.regex !== null) lines.push(`${sigIndent}regex: ${formatString(config.signature.regex, q)},`);
80
+ if (lines[lines.length - 1].endsWith(",")) lines[lines.length - 1] = lines[lines.length - 1].slice(0, -1);
81
+ lines.push(`${algorithmIndent}},`);
82
+ lines.push(`${algorithmIndent}signedComponents: [`);
83
+ for (const component of config.signedComponents) {
84
+ lines.push(`${sigIndent}{`);
85
+ const compIndent = indentation.repeat(indentLevel + 3);
86
+ lines.push(`${compIndent}source: ${formatString(component.source, q)},`);
87
+ if (component.key !== void 0 && component.key !== null) lines.push(`${compIndent}key: ${formatString(component.key, q)},`);
88
+ if (component.value !== void 0 && component.value !== null) lines.push(`${compIndent}value: ${formatString(component.value, q)},`);
89
+ if (component.regex !== void 0 && component.regex !== null) lines.push(`${compIndent}regex: ${formatString(component.regex, q)},`);
90
+ if (component.required !== void 0 && component.required !== null) lines.push(`${compIndent}required: ${component.required},`);
91
+ if (lines[lines.length - 1].endsWith(",")) lines[lines.length - 1] = lines[lines.length - 1].slice(0, -1);
92
+ lines.push(`${sigIndent}},`);
93
+ }
94
+ lines.push(`${algorithmIndent}],`);
95
+ lines.push(`${algorithmIndent}componentJoin: {`);
96
+ lines.push(`${sigIndent}strategy: ${formatString(config.componentJoin.strategy, q)},`);
97
+ lines.push(`${sigIndent}separator: ${formatString(config.componentJoin.separator, q)}`);
98
+ lines.push(`${algorithmIndent}},`);
99
+ if (config.validation) {
100
+ lines.push(`${algorithmIndent}validation: {`);
101
+ if (config.validation.headerCaseSensitive !== void 0) lines.push(`${sigIndent}headerCaseSensitive: ${config.validation.headerCaseSensitive},`);
102
+ if (config.validation.allowEmptyBody !== void 0) lines.push(`${sigIndent}allowEmptyBody: ${config.validation.allowEmptyBody},`);
103
+ if (config.validation.normalizeUnicode !== void 0) lines.push(`${sigIndent}normalizeUnicode: ${config.validation.normalizeUnicode},`);
104
+ if (lines[lines.length - 1].endsWith(",")) lines[lines.length - 1] = lines[lines.length - 1].slice(0, -1);
105
+ lines.push(`${algorithmIndent}},`);
106
+ }
107
+ if (lines[lines.length - 1].endsWith(",")) lines[lines.length - 1] = lines[lines.length - 1].slice(0, -1);
108
+ lines.push(`${indent}},`);
109
+ return lines.join("\n");
110
+ }
111
+ /**
112
+ * Generate Trigger Definition using Trigger class
113
+ */
114
+ function generateTriggerDefinition(triggerId, triggerData, style = DEFAULT_STYLE, registry) {
115
+ if (!triggerId || typeof triggerId !== "string") throw new Error("triggerId is required and must be a string");
116
+ if (!triggerData || typeof triggerData !== "object") throw new Error(`triggerData is required for trigger '${triggerId}'`);
117
+ const missingFields = ["name", "messageTemplate"].filter((field) => !triggerData[field] || triggerData[field] === null || triggerData[field] === void 0);
118
+ if (missingFields.length > 0) throw new Error(`Missing required fields for trigger '${triggerId}': ${missingFields.join(", ")}`);
119
+ const { quotes, semicolons, indentation } = style;
120
+ const q = quotes === "single" ? "'" : "\"";
121
+ const semi = semicolons ? ";" : "";
122
+ const triggerVarName = toCamelCase(triggerId);
123
+ const lines = [];
124
+ lines.push(`export const ${triggerVarName} = new Trigger({`);
125
+ lines.push(`${indentation}id: ${formatString(triggerId, q)},`);
126
+ lines.push(`${indentation}name: ${formatString(triggerData.name, q)},`);
127
+ if (triggerData.description) lines.push(`${indentation}description: ${formatString(triggerData.description, q, true)},`);
128
+ if (triggerData.enabled !== void 0 && triggerData.enabled !== null) lines.push(`${indentation}enabled: ${triggerData.enabled},`);
129
+ lines.push(`${indentation}messageTemplate: ${formatString(triggerData.messageTemplate, q, true)},`);
130
+ if (triggerData.inputSchema) {
131
+ const formattedSchema = JSON.stringify(triggerData.inputSchema, null, 2).split("\n").map((line, index) => {
132
+ if (index === 0) return `${indentation}inputSchema: ${line}`;
133
+ return `${indentation}${line}`;
134
+ }).join("\n");
135
+ lines.push(`${formattedSchema},`);
136
+ }
137
+ if (triggerData.outputTransform) {
138
+ const outputTransformFormatted = formatOutputTransform(triggerData.outputTransform, style, 1);
139
+ if (outputTransformFormatted) lines.push(outputTransformFormatted);
140
+ }
141
+ if (triggerData.authentication) {
142
+ const authFormatted = formatAuthentication(triggerData.authentication, style, 1);
143
+ if (authFormatted) lines.push(authFormatted);
144
+ }
145
+ if (triggerData.signatureVerification) {
146
+ const sigVerificationFormatted = formatSignatureVerification(triggerData.signatureVerification, style, 1);
147
+ if (sigVerificationFormatted) lines.push(sigVerificationFormatted);
148
+ }
149
+ if (triggerData.signingSecretCredentialReferenceId) {
150
+ if (!registry) throw new Error("Registry is required for signingSecretCredentialReferenceId generation");
151
+ const credentialVar = registry.getVariableName(triggerData.signingSecretCredentialReferenceId, "credentials");
152
+ if (!credentialVar) throw new Error(`Failed to resolve variable name for credential reference: ${triggerData.signingSecretCredentialReferenceId}`);
153
+ lines.push(`${indentation}signingSecretCredentialReference: ${credentialVar},`);
154
+ }
155
+ if (lines.length > 0 && lines[lines.length - 1].endsWith(",")) lines[lines.length - 1] = lines[lines.length - 1].slice(0, -1);
156
+ lines.push(`})${semi}`);
157
+ return lines.join("\n");
158
+ }
159
+ /**
160
+ * Generate imports needed for a trigger file
161
+ */
162
+ function generateTriggerImports(triggerId, triggerData, style = DEFAULT_STYLE, registry) {
163
+ const imports = [];
164
+ imports.push(generateImport(["Trigger"], "@inkeep/agents-sdk", style));
165
+ if (triggerData.signingSecretCredentialReferenceId && typeof triggerData.signingSecretCredentialReferenceId === "string") {
166
+ if (!registry) throw new Error("Registry is required for credential reference imports");
167
+ const currentFilePath = `agents/triggers/${triggerId}.ts`;
168
+ const credentialRefs = [{
169
+ id: triggerData.signingSecretCredentialReferenceId,
170
+ type: "credentials"
171
+ }];
172
+ const componentImports = registry.getImportsForFile(currentFilePath, credentialRefs);
173
+ imports.push(...componentImports);
174
+ }
175
+ return imports;
176
+ }
177
+ /**
178
+ * Generate complete trigger file (imports + definition)
179
+ */
180
+ function generateTriggerFile(triggerId, triggerData, style = DEFAULT_STYLE, registry) {
181
+ return generateFileContent(generateTriggerImports(triggerId, triggerData, style, registry), [generateTriggerDefinition(triggerId, triggerData, style, registry)]);
182
+ }
183
+
184
+ //#endregion
185
+ export { generateTriggerDefinition, generateTriggerFile, generateTriggerImports };
@@ -1,15 +1,13 @@
1
1
  import { ManagementApiClient } from "../../api.js";
2
- import "../../utils/config.js";
3
2
  import { initializeCommand } from "../../utils/cli-pipeline.js";
4
3
  import { performBackgroundVersionCheck } from "../../utils/background-version-check.js";
5
- import "../../utils/json-comparison.js";
6
4
  import { loadProject } from "../../utils/project-loader.js";
7
5
  import { extractSubAgents } from "./utils/component-registry.js";
8
- import { compareProjects } from "./project-comparator.js";
9
6
  import { checkAndPromptForStaleComponentCleanup, cleanupStaleComponents, copyProjectToTemp } from "./component-updater.js";
10
7
  import { introspectGenerate } from "./introspect-generator.js";
8
+ import { compareProjects } from "./project-comparator.js";
11
9
  import { existsSync, mkdirSync } from "node:fs";
12
- import { basename, dirname, join, resolve } from "node:path";
10
+ import { join, resolve } from "node:path";
13
11
  import * as p from "@clack/prompts";
14
12
  import chalk from "chalk";
15
13
  import { EventEmitter } from "node:events";
@@ -38,7 +36,7 @@ function resetStdinState() {
38
36
  /**
39
37
  * Create project directory structure
40
38
  */
41
- function createProjectStructure(projectDir, projectId) {
39
+ function createProjectStructure(projectDir) {
42
40
  const projectRoot = projectDir;
43
41
  const paths = {
44
42
  projectRoot,
@@ -60,11 +58,11 @@ function createProjectStructure(projectDir, projectId) {
60
58
  /**
61
59
  * Enrich canDelegateTo references with component type information
62
60
  */
63
- function enrichCanDelegateToWithTypes(project, debug = false) {
61
+ function enrichCanDelegateToWithTypes(project) {
64
62
  const agentIds = new Set(project.agents ? Object.keys(project.agents) : []);
65
63
  const subAgentIds = new Set(Object.keys(extractSubAgents(project)));
66
64
  const externalAgentIds = new Set(project.externalAgents ? Object.keys(project.externalAgents) : []);
67
- const enrichCanDelegateToArray = (canDelegateTo, context) => {
65
+ const enrichCanDelegateToArray = (canDelegateTo) => {
68
66
  if (!Array.isArray(canDelegateTo)) return;
69
67
  for (let i = 0; i < canDelegateTo.length; i++) {
70
68
  const item = canDelegateTo[i];
@@ -79,15 +77,15 @@ function enrichCanDelegateToWithTypes(project, debug = false) {
79
77
  }
80
78
  };
81
79
  if (project.agents) {
82
- for (const [_, agentData] of Object.entries(project.agents)) if (agentData.subAgents) {
83
- for (const [subAgentId, subAgentData] of Object.entries(agentData.subAgents)) if (subAgentData.canDelegateTo) enrichCanDelegateToArray(subAgentData.canDelegateTo, `subAgent:${subAgentId}`);
80
+ for (const agentData of Object.values(project.agents)) if (agentData.subAgents) {
81
+ for (const subAgentData of Object.values(agentData.subAgents)) if (subAgentData.canDelegateTo) enrichCanDelegateToArray(subAgentData.canDelegateTo);
84
82
  }
85
83
  }
86
84
  }
87
85
  /**
88
86
  * Read existing project from filesystem if it exists
89
87
  */
90
- async function readExistingProject(projectRoot, debug = false) {
88
+ async function readExistingProject(projectRoot) {
91
89
  if (!existsSync(join(projectRoot, "index.ts"))) return null;
92
90
  try {
93
91
  const { loadProject: loadProject$1 } = await import("../../utils/project-loader.js");
@@ -97,9 +95,7 @@ async function readExistingProject(projectRoot, debug = false) {
97
95
  reject(/* @__PURE__ */ new Error("getFullDefinition() timed out after 30 seconds - likely circular reference or infinite loop in local project"));
98
96
  }, 3e4);
99
97
  })]);
100
- } catch (error) {
101
- const errorMessage = error instanceof Error ? error.message : String(error);
102
- errorMessage.includes("Credential") && errorMessage.includes("not found");
98
+ } catch {
103
99
  return null;
104
100
  }
105
101
  }
@@ -125,7 +121,7 @@ async function pullV3Command(options) {
125
121
  else console.log(chalk.gray(" Smart comparison • Detect all changes • Targeted updates"));
126
122
  const s = p.spinner();
127
123
  try {
128
- const { config, profile, isCI } = await initializeCommand({
124
+ const { config, isCI } = await initializeCommand({
129
125
  configPath: options.config,
130
126
  profileName: options.profile,
131
127
  tag: options.tag,
@@ -192,7 +188,7 @@ async function pullV3Command(options) {
192
188
  }
193
189
  }
194
190
  s.start(`Fetching project: ${projectId}`);
195
- const remoteProject = await (await ManagementApiClient.create(config.agentsManageApiUrl, options.config, config.tenantId, projectId, isCI, config.agentsManageApiKey)).getFullProject(projectId);
191
+ const remoteProject = await (await ManagementApiClient.create(config.agentsApiUrl, options.config, config.tenantId, projectId, isCI, config.agentsApiKey)).getFullProject(projectId);
196
192
  if (options.debug && remoteProject.functions) {
197
193
  console.log(chalk.gray(" 📋 Project-level functions from API:"), Object.keys(remoteProject.functions));
198
194
  Object.entries(remoteProject.functions).forEach(([id, data]) => {
@@ -219,21 +215,20 @@ async function pullV3Command(options) {
219
215
  }
220
216
  if (remoteProject.agents && remoteProject.tools) {
221
217
  const projectToolIds = Object.keys(remoteProject.tools);
222
- for (const [agentId, agentData] of Object.entries(remoteProject.agents)) if (agentData.tools) {
223
- Object.keys(agentData.tools).length;
218
+ for (const agentData of Object.values(remoteProject.agents)) if (agentData.tools) {
224
219
  const agentSpecificTools = Object.fromEntries(Object.entries(agentData.tools).filter(([toolId]) => !projectToolIds.includes(toolId)));
225
220
  if (Object.keys(agentSpecificTools).length > 0) agentData.tools = agentSpecificTools;
226
221
  else delete agentData.tools;
227
222
  }
228
223
  }
229
- enrichCanDelegateToWithTypes(remoteProject, options.debug);
224
+ enrichCanDelegateToWithTypes(remoteProject);
230
225
  s.message("Project data fetched");
231
226
  if (options.json) {
232
227
  console.log(JSON.stringify(remoteProject, null, 2));
233
228
  restoreLogLevel();
234
229
  return;
235
230
  }
236
- const paths = createProjectStructure(projectDir, projectId);
231
+ const paths = createProjectStructure(projectDir);
237
232
  if (options.introspect) {
238
233
  console.log(chalk.yellow("\n🔍 Introspect mode: Regenerating all files from scratch"));
239
234
  s.start("Generating all files deterministically...");
@@ -247,7 +242,7 @@ async function pullV3Command(options) {
247
242
  if (batchMode) return { success: true };
248
243
  process.exit(0);
249
244
  }
250
- const localProject = await readExistingProject(paths.projectRoot, options.debug);
245
+ const localProject = await readExistingProject(paths.projectRoot);
251
246
  if (!localProject) s.message("No existing project found - treating as new project");
252
247
  else s.message("Existing project loaded");
253
248
  s.start("Building component registry from local files...");
@@ -261,7 +256,7 @@ async function pullV3Command(options) {
261
256
  const nameGroups = /* @__PURE__ */ new Map();
262
257
  for (const comp of allComponents) {
263
258
  if (!nameGroups.has(comp.name)) nameGroups.set(comp.name, []);
264
- nameGroups.get(comp.name).push(comp);
259
+ nameGroups.get(comp.name)?.push(comp);
265
260
  }
266
261
  for (const [varName, components] of nameGroups.entries()) if (components.length > 1) {
267
262
  console.log(chalk.red(` ❌ Variable name conflict: "${varName}"`));
@@ -269,7 +264,7 @@ async function pullV3Command(options) {
269
264
  } else console.log(chalk.gray(` ✅ ${varName} (${components[0].type}:${components[0].id})`));
270
265
  }
271
266
  s.start("Comparing projects for changes...");
272
- const comparison = await compareProjects(localProject, remoteProject, localRegistry, options.debug);
267
+ const comparison = await compareProjects(localProject, remoteProject, options.debug);
273
268
  if (!comparison.hasChanges && !options.force) {
274
269
  s.stop();
275
270
  console.log(chalk.green("✅ Project is already up to date"));
@@ -289,7 +284,7 @@ async function pullV3Command(options) {
289
284
  copyProjectToTemp(paths.projectRoot, tempDirName);
290
285
  console.log(chalk.green(`✅ Existing project copied to temp directory`));
291
286
  s.start("Checking for stale components...");
292
- const shouldCleanupStale = await checkAndPromptForStaleComponentCleanup(paths.projectRoot, remoteProject, localRegistry);
287
+ const shouldCleanupStale = await checkAndPromptForStaleComponentCleanup(remoteProject, localRegistry);
293
288
  resetStdinState();
294
289
  if (shouldCleanupStale) {
295
290
  s.start("Cleaning up stale components from temp directory...");
@@ -315,7 +310,7 @@ async function pullV3Command(options) {
315
310
  const nameGroups = /* @__PURE__ */ new Map();
316
311
  for (const comp of allComponents) {
317
312
  if (!nameGroups.has(comp.name)) nameGroups.set(comp.name, []);
318
- nameGroups.get(comp.name).push(comp);
313
+ nameGroups.get(comp.name)?.push(comp);
319
314
  }
320
315
  for (const [varName, components] of nameGroups.entries()) if (components.length > 1) {
321
316
  console.log(chalk.red(` ❌ Variable name conflict: "${varName}"`));
@@ -333,9 +328,9 @@ async function pullV3Command(options) {
333
328
  const newComponentsForContext = newComponentResults && newComponentResults.length > 0 ? newComponentResults.filter((result) => result.success).map((result) => ({
334
329
  componentId: result.componentId,
335
330
  componentType: result.componentType,
336
- filePath: result.filePath.replace(paths.projectRoot + "/", "")
331
+ filePath: result.filePath.replace(`${paths.projectRoot}/`, "")
337
332
  })) : void 0;
338
- await updateModifiedComponents(comparison, remoteProject, localRegistry, paths.projectRoot, options.env || "development", options.debug, tempDirName, newComponentsForContext);
333
+ await updateModifiedComponents(comparison, remoteProject, localRegistry, paths.projectRoot, options.debug, tempDirName, newComponentsForContext);
339
334
  }
340
335
  s.start("Generating project index file in temp directory...");
341
336
  const { generateProjectIndex } = await import("./project-index-generator.js");
@@ -380,7 +375,7 @@ async function pullAllProjects(options) {
380
375
  console.log(chalk.gray(" • Existing projects: Smart comparison + LLM merging + confirmation prompts"));
381
376
  console.log(chalk.gray(" • New projects: Fresh generation with introspect mode\n"));
382
377
  performBackgroundVersionCheck();
383
- const { config, profile, isCI } = await initializeCommand({
378
+ const { config, isCI } = await initializeCommand({
384
379
  configPath: options.config,
385
380
  profileName: options.profile,
386
381
  tag: options.tag,
@@ -392,7 +387,7 @@ async function pullAllProjects(options) {
392
387
  const s = p.spinner();
393
388
  try {
394
389
  s.start("Fetching project list from API...");
395
- const projects = await (await ManagementApiClient.create(config.agentsManageApiUrl, options.config, config.tenantId, void 0, isCI, config.agentsManageApiKey)).listAllProjects();
390
+ const projects = await (await ManagementApiClient.create(config.agentsApiUrl, options.config, config.tenantId, void 0, isCI, config.agentsApiKey)).listAllProjects();
396
391
  s.stop(`Found ${projects.length} project(s)`);
397
392
  if (projects.length === 0) {
398
393
  console.log(chalk.yellow("No projects found for this tenant."));
@@ -486,8 +481,8 @@ async function pullSingleProject(projectId, projectName, options, config, isCI)
486
481
  if (originalLogLevel !== void 0) process.env.LOG_LEVEL = originalLogLevel;
487
482
  else delete process.env.LOG_LEVEL;
488
483
  };
489
- const remoteProject = await (await ManagementApiClient.create(config.agentsManageApiUrl, options.config, config.tenantId, projectId, isCI, config.agentsManageApiKey)).getFullProject(projectId);
490
- await introspectGenerate(remoteProject, createProjectStructure(targetDir, projectId), options.env || "development", false);
484
+ const remoteProject = await (await ManagementApiClient.create(config.agentsApiUrl, options.config, config.tenantId, projectId, isCI, config.agentsApiKey)).getFullProject(projectId);
485
+ await introspectGenerate(remoteProject, createProjectStructure(targetDir), options.env || "development", false);
491
486
  restoreLogLevel();
492
487
  return {
493
488
  projectId,