@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
@@ -13,9 +13,8 @@ import { generateSubAgentFile } from "./components/sub-agent-generator.js";
13
13
  import { getAvailableModel } from "./utils/model-provider-detector.js";
14
14
  import { mergeComponentsWithLLM } from "./llm-content-merger.js";
15
15
  import { findSubAgentWithParent } from "./utils/component-registry.js";
16
- import "./project-validator.js";
17
16
  import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, statSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
18
- import { basename, dirname, extname, join, relative, resolve } from "node:path";
17
+ import { dirname, extname, join, relative, resolve } from "node:path";
19
18
  import chalk from "chalk";
20
19
  import { spawn } from "node:child_process";
21
20
  import { generateText } from "ai";
@@ -90,7 +89,7 @@ function findParentImports(dir) {
90
89
  const resolvedImport = join(relative(dir, dirname(fullPath)), importPath);
91
90
  if (resolvedImport.startsWith("..")) {
92
91
  parentImports.add(resolvedImport);
93
- if (!resolvedImport.endsWith(".ts") && !resolvedImport.endsWith(".js")) parentImports.add(resolvedImport + ".ts");
92
+ if (!resolvedImport.endsWith(".ts") && !resolvedImport.endsWith(".js")) parentImports.add(`${resolvedImport}.ts`);
94
93
  }
95
94
  }
96
95
  }
@@ -103,34 +102,62 @@ function findParentImports(dir) {
103
102
  /**
104
103
  * Check for stale components and prompt user for cleanup permission
105
104
  */
106
- async function checkAndPromptForStaleComponentCleanup(projectRoot, remoteProject, localRegistry) {
105
+ async function checkAndPromptForStaleComponentCleanup(remoteProject, localRegistry) {
107
106
  const remoteComponentIds = /* @__PURE__ */ new Set();
108
- if (remoteProject.agents) Object.keys(remoteProject.agents).forEach((id) => remoteComponentIds.add(id));
109
- if (remoteProject.tools) Object.keys(remoteProject.tools).forEach((id) => remoteComponentIds.add(id));
110
- if (remoteProject.functionTools) Object.keys(remoteProject.functionTools).forEach((id) => remoteComponentIds.add(id));
111
- if (remoteProject.functions) Object.keys(remoteProject.functions).forEach((id) => remoteComponentIds.add(id));
112
- if (remoteProject.dataComponents) Object.keys(remoteProject.dataComponents).forEach((id) => remoteComponentIds.add(id));
113
- if (remoteProject.artifactComponents) Object.keys(remoteProject.artifactComponents).forEach((id) => remoteComponentIds.add(id));
114
- if (remoteProject.credentialReferences) Object.keys(remoteProject.credentialReferences).forEach((id) => remoteComponentIds.add(id));
115
- if (remoteProject.externalAgents) Object.keys(remoteProject.externalAgents).forEach((id) => remoteComponentIds.add(id));
116
- if (remoteProject.environments) Object.keys(remoteProject.environments).forEach((id) => remoteComponentIds.add(id));
117
- if (remoteProject.headers) Object.keys(remoteProject.headers).forEach((id) => remoteComponentIds.add(id));
107
+ if (remoteProject.agents) Object.keys(remoteProject.agents).forEach((id) => {
108
+ remoteComponentIds.add(id);
109
+ });
110
+ if (remoteProject.tools) Object.keys(remoteProject.tools).forEach((id) => {
111
+ remoteComponentIds.add(id);
112
+ });
113
+ if (remoteProject.functionTools) Object.keys(remoteProject.functionTools).forEach((id) => {
114
+ remoteComponentIds.add(id);
115
+ });
116
+ if (remoteProject.functions) Object.keys(remoteProject.functions).forEach((id) => {
117
+ remoteComponentIds.add(id);
118
+ });
119
+ if (remoteProject.dataComponents) Object.keys(remoteProject.dataComponents).forEach((id) => {
120
+ remoteComponentIds.add(id);
121
+ });
122
+ if (remoteProject.artifactComponents) Object.keys(remoteProject.artifactComponents).forEach((id) => {
123
+ remoteComponentIds.add(id);
124
+ });
125
+ if (remoteProject.credentialReferences) Object.keys(remoteProject.credentialReferences).forEach((id) => {
126
+ remoteComponentIds.add(id);
127
+ });
128
+ if (remoteProject.externalAgents) Object.keys(remoteProject.externalAgents).forEach((id) => {
129
+ remoteComponentIds.add(id);
130
+ });
131
+ if (remoteProject.environments) Object.keys(remoteProject.environments).forEach((id) => {
132
+ remoteComponentIds.add(id);
133
+ });
134
+ if (remoteProject.headers) Object.keys(remoteProject.headers).forEach((id) => {
135
+ remoteComponentIds.add(id);
136
+ });
118
137
  if (remoteProject.models) remoteComponentIds.add("project");
119
138
  if (remoteProject.name || remoteProject.description) remoteComponentIds.add(remoteProject.name || "project");
120
139
  if (remoteProject.agents) Object.values(remoteProject.agents).forEach((agent) => {
121
140
  if (agent.subAgents) {
122
- Object.keys(agent.subAgents).forEach((id) => remoteComponentIds.add(id));
141
+ Object.keys(agent.subAgents).forEach((id) => {
142
+ remoteComponentIds.add(id);
143
+ });
123
144
  Object.values(agent.subAgents).forEach((subAgent) => {
124
- if (subAgent.functionTools) Object.keys(subAgent.functionTools).forEach((id) => remoteComponentIds.add(id));
125
- if (subAgent.tools) Object.keys(subAgent.tools).forEach((id) => remoteComponentIds.add(id));
145
+ if (subAgent.functionTools) Object.keys(subAgent.functionTools).forEach((id) => {
146
+ remoteComponentIds.add(id);
147
+ });
148
+ if (subAgent.tools) Object.keys(subAgent.tools).forEach((id) => {
149
+ remoteComponentIds.add(id);
150
+ });
126
151
  });
127
152
  }
128
- if (agent.contextConfig && agent.contextConfig.id) {
153
+ if (agent.contextConfig?.id) {
129
154
  remoteComponentIds.add(agent.contextConfig.id);
130
155
  if (agent.contextConfig.contextVariables) Object.values(agent.contextConfig.contextVariables).forEach((variable) => {
131
156
  if (variable && typeof variable === "object" && variable.id) remoteComponentIds.add(variable.id);
132
157
  });
133
- if (agent.contextConfig.headers) Object.keys(agent.contextConfig.headers).forEach((id) => remoteComponentIds.add(id));
158
+ if (agent.contextConfig.headers) Object.keys(agent.contextConfig.headers).forEach((id) => {
159
+ remoteComponentIds.add(id);
160
+ });
134
161
  }
135
162
  if (agent.statusUpdates?.statusComponents) agent.statusUpdates.statusComponents.forEach((statusComp) => {
136
163
  const statusCompId = statusComp.type || statusComp.id;
@@ -192,32 +219,60 @@ async function checkAndPromptForStaleComponentCleanup(projectRoot, remoteProject
192
219
  async function cleanupStaleComponents(projectRoot, tempDirName, remoteProject, localRegistry) {
193
220
  const tempDir = join(projectRoot, tempDirName);
194
221
  const remoteComponentIds = /* @__PURE__ */ new Set();
195
- if (remoteProject.agents) Object.keys(remoteProject.agents).forEach((id) => remoteComponentIds.add(id));
196
- if (remoteProject.tools) Object.keys(remoteProject.tools).forEach((id) => remoteComponentIds.add(id));
197
- if (remoteProject.functionTools) Object.keys(remoteProject.functionTools).forEach((id) => remoteComponentIds.add(id));
198
- if (remoteProject.functions) Object.keys(remoteProject.functions).forEach((id) => remoteComponentIds.add(id));
199
- if (remoteProject.dataComponents) Object.keys(remoteProject.dataComponents).forEach((id) => remoteComponentIds.add(id));
200
- if (remoteProject.artifactComponents) Object.keys(remoteProject.artifactComponents).forEach((id) => remoteComponentIds.add(id));
201
- if (remoteProject.credentialReferences) Object.keys(remoteProject.credentialReferences).forEach((id) => remoteComponentIds.add(id));
202
- if (remoteProject.externalAgents) Object.keys(remoteProject.externalAgents).forEach((id) => remoteComponentIds.add(id));
203
- if (remoteProject.environments) Object.keys(remoteProject.environments).forEach((id) => remoteComponentIds.add(id));
204
- if (remoteProject.headers) Object.keys(remoteProject.headers).forEach((id) => remoteComponentIds.add(id));
222
+ if (remoteProject.agents) Object.keys(remoteProject.agents).forEach((id) => {
223
+ remoteComponentIds.add(id);
224
+ });
225
+ if (remoteProject.tools) Object.keys(remoteProject.tools).forEach((id) => {
226
+ remoteComponentIds.add(id);
227
+ });
228
+ if (remoteProject.functionTools) Object.keys(remoteProject.functionTools).forEach((id) => {
229
+ remoteComponentIds.add(id);
230
+ });
231
+ if (remoteProject.functions) Object.keys(remoteProject.functions).forEach((id) => {
232
+ remoteComponentIds.add(id);
233
+ });
234
+ if (remoteProject.dataComponents) Object.keys(remoteProject.dataComponents).forEach((id) => {
235
+ remoteComponentIds.add(id);
236
+ });
237
+ if (remoteProject.artifactComponents) Object.keys(remoteProject.artifactComponents).forEach((id) => {
238
+ remoteComponentIds.add(id);
239
+ });
240
+ if (remoteProject.credentialReferences) Object.keys(remoteProject.credentialReferences).forEach((id) => {
241
+ remoteComponentIds.add(id);
242
+ });
243
+ if (remoteProject.externalAgents) Object.keys(remoteProject.externalAgents).forEach((id) => {
244
+ remoteComponentIds.add(id);
245
+ });
246
+ if (remoteProject.environments) Object.keys(remoteProject.environments).forEach((id) => {
247
+ remoteComponentIds.add(id);
248
+ });
249
+ if (remoteProject.headers) Object.keys(remoteProject.headers).forEach((id) => {
250
+ remoteComponentIds.add(id);
251
+ });
205
252
  if (remoteProject.models) remoteComponentIds.add("project");
206
253
  if (remoteProject.name || remoteProject.description) remoteComponentIds.add(remoteProject.name || "project");
207
254
  if (remoteProject.agents) Object.values(remoteProject.agents).forEach((agent) => {
208
255
  if (agent.subAgents) {
209
- Object.keys(agent.subAgents).forEach((id) => remoteComponentIds.add(id));
256
+ Object.keys(agent.subAgents).forEach((id) => {
257
+ remoteComponentIds.add(id);
258
+ });
210
259
  Object.values(agent.subAgents).forEach((subAgent) => {
211
- if (subAgent.functionTools) Object.keys(subAgent.functionTools).forEach((id) => remoteComponentIds.add(id));
212
- if (subAgent.tools) Object.keys(subAgent.tools).forEach((id) => remoteComponentIds.add(id));
260
+ if (subAgent.functionTools) Object.keys(subAgent.functionTools).forEach((id) => {
261
+ remoteComponentIds.add(id);
262
+ });
263
+ if (subAgent.tools) Object.keys(subAgent.tools).forEach((id) => {
264
+ remoteComponentIds.add(id);
265
+ });
213
266
  });
214
267
  }
215
- if (agent.contextConfig && agent.contextConfig.id) {
268
+ if (agent.contextConfig?.id) {
216
269
  remoteComponentIds.add(agent.contextConfig.id);
217
270
  if (agent.contextConfig.contextVariables) Object.values(agent.contextConfig.contextVariables).forEach((variable) => {
218
271
  if (variable && typeof variable === "object" && variable.id) remoteComponentIds.add(variable.id);
219
272
  });
220
- if (agent.contextConfig.headers) Object.keys(agent.contextConfig.headers).forEach((id) => remoteComponentIds.add(id));
273
+ if (agent.contextConfig.headers) Object.keys(agent.contextConfig.headers).forEach((id) => {
274
+ remoteComponentIds.add(id);
275
+ });
221
276
  }
222
277
  if (agent.statusUpdates?.statusComponents) agent.statusUpdates.statusComponents.forEach((statusComp) => {
223
278
  const statusCompId = statusComp.type || statusComp.id;
@@ -225,9 +280,9 @@ async function cleanupStaleComponents(projectRoot, tempDirName, remoteProject, l
225
280
  });
226
281
  if (agent.models) remoteComponentIds.add(`${agent.id || "unknown"}-models`);
227
282
  });
228
- localRegistry.getAllComponents();
283
+ const allLocalComponents = localRegistry.getAllComponents();
229
284
  const staleComponents = [];
230
- for (const component of localRegistry.getAllComponents()) {
285
+ for (const component of allLocalComponents) {
231
286
  if (component.type === "project") continue;
232
287
  if (!remoteComponentIds.has(component.id)) staleComponents.push(component);
233
288
  }
@@ -236,10 +291,10 @@ async function cleanupStaleComponents(projectRoot, tempDirName, remoteProject, l
236
291
  for (const component of staleComponents) {
237
292
  const filePath = component.filePath;
238
293
  if (!staleComponentsByFile.has(filePath)) staleComponentsByFile.set(filePath, []);
239
- staleComponentsByFile.get(filePath).push(component);
294
+ staleComponentsByFile.get(filePath)?.push(component);
240
295
  }
241
296
  for (const [originalFilePath, staleComponentsInFile] of staleComponentsByFile) {
242
- const tempFilePath = join(tempDir, originalFilePath.replace(projectRoot + "/", ""));
297
+ const tempFilePath = join(tempDir, originalFilePath.replace(`${projectRoot}/`, ""));
243
298
  if (!existsSync(tempFilePath)) continue;
244
299
  if (localRegistry.getComponentsInFile(originalFilePath).filter((component) => !staleComponentsInFile.some((stale) => stale.id === component.id)).length === 0) unlinkSync(tempFilePath);
245
300
  else {
@@ -247,7 +302,7 @@ async function cleanupStaleComponents(projectRoot, tempDirName, remoteProject, l
247
302
  const cleanedContent = await removeComponentsFromFile(currentContent, staleComponentsInFile.map((c) => ({
248
303
  id: c.id,
249
304
  type: c.type
250
- })), tempFilePath);
305
+ })));
251
306
  if (cleanedContent !== currentContent) writeFileSync(tempFilePath, cleanedContent, "utf8");
252
307
  }
253
308
  }
@@ -260,7 +315,12 @@ async function removeComponentsWithLLM(fileContent, prompt) {
260
315
  try {
261
316
  let cleanedResponse = (await generateText({
262
317
  model: await getAvailableModel(),
263
- prompt: prompt + "\n\nFile content:\n```typescript\n" + fileContent + "\n```"
318
+ prompt: `${prompt}
319
+
320
+ File content:
321
+ \`\`\`typescript
322
+ ${fileContent}
323
+ \`\`\``
264
324
  })).text.replace(/^```(?:typescript|ts|javascript|js)?\s*\n?/i, "");
265
325
  cleanedResponse = cleanedResponse.replace(/\n?```\s*$/i, "");
266
326
  return cleanedResponse.trim();
@@ -272,7 +332,7 @@ async function removeComponentsWithLLM(fileContent, prompt) {
272
332
  /**
273
333
  * Use LLM to remove specific components from file content
274
334
  */
275
- async function removeComponentsFromFile(fileContent, componentsToRemove, filePath) {
335
+ async function removeComponentsFromFile(fileContent, componentsToRemove) {
276
336
  const prompt = `Remove the following components from this TypeScript file: ${componentsToRemove.map((c) => `${c.type}:${c.id}`).join(", ")}
277
337
 
278
338
  Please remove these components completely, including:
@@ -289,7 +349,7 @@ ${fileContent}
289
349
  Return only the cleaned TypeScript code with the specified components removed.`;
290
350
  try {
291
351
  return await removeComponentsWithLLM(fileContent, prompt);
292
- } catch (error) {
352
+ } catch {
293
353
  return fileContent;
294
354
  }
295
355
  }
@@ -297,7 +357,7 @@ Return only the cleaned TypeScript code with the specified components removed.`;
297
357
  * Write content to temp directory (overwrite if exists)
298
358
  */
299
359
  function writeToTempDirectory(projectRoot, filePath, content, tempDirName) {
300
- const tempFilePath = join(join(projectRoot, tempDirName), filePath.replace(projectRoot + "/", ""));
360
+ const tempFilePath = join(join(projectRoot, tempDirName), filePath.replace(`${projectRoot}/`, ""));
301
361
  mkdirSync(dirname(tempFilePath), { recursive: true });
302
362
  writeFileSync(tempFilePath, content, "utf8");
303
363
  }
@@ -344,8 +404,7 @@ async function runBiomeOnFile(filePath) {
344
404
  });
345
405
  });
346
406
  return true;
347
- } catch (error) {
348
- error instanceof Error && error.message;
407
+ } catch {
349
408
  return false;
350
409
  }
351
410
  }
@@ -391,14 +450,14 @@ async function runBiomeOnDirectory(dirPath) {
391
450
  });
392
451
  });
393
452
  return true;
394
- } catch (error) {
453
+ } catch {
395
454
  return false;
396
455
  }
397
456
  }
398
457
  /**
399
458
  * Generate updated component content using appropriate generator
400
459
  */
401
- function generateUpdatedComponentContent(componentType, componentId, componentData, remoteProject, localRegistry, environment, actualFilePath) {
460
+ function generateUpdatedComponentContent(componentType, componentId, componentData, remoteProject, localRegistry, actualFilePath) {
402
461
  const defaultStyle = {
403
462
  quotes: "single",
404
463
  indentation: " ",
@@ -426,10 +485,9 @@ function generateUpdatedComponentContent(componentType, componentId, componentDa
426
485
  case "externalAgents": return generateExternalAgentFile(componentId, componentData, defaultStyle, localRegistry);
427
486
  case "credentials": return generateCredentialFile(componentId, componentData, defaultStyle);
428
487
  case "contextConfigs": {
429
- const agentId = componentData._agentId;
430
488
  const cleanComponentData = { ...componentData };
431
489
  delete cleanComponentData._agentId;
432
- return generateContextConfigFile(componentId, cleanComponentData, defaultStyle, localRegistry, agentId);
490
+ return generateContextConfigFile(componentId, cleanComponentData, defaultStyle, localRegistry);
433
491
  }
434
492
  case "fetchDefinitions": return "";
435
493
  case "projects": return generateProjectFile(componentId, componentData, defaultStyle, localRegistry);
@@ -439,7 +497,7 @@ function generateUpdatedComponentContent(componentType, componentId, componentDa
439
497
  /**
440
498
  * Update existing components that have been modified
441
499
  */
442
- async function updateModifiedComponents(comparison, remoteProject, localRegistry, projectRoot, environment, debug = false, providedTempDirName, newComponents) {
500
+ async function updateModifiedComponents(comparison, remoteProject, localRegistry, projectRoot, debug = false, providedTempDirName, newComponents) {
443
501
  const results = [];
444
502
  const tempDirName = providedTempDirName || `.temp-${Date.now()}`;
445
503
  if (!providedTempDirName) {
@@ -464,7 +522,7 @@ async function updateModifiedComponents(comparison, remoteProject, localRegistry
464
522
  if (actualComponent) {
465
523
  const filePath = actualComponent.filePath.startsWith("/") ? actualComponent.filePath : `${projectRoot}/${actualComponent.filePath}`;
466
524
  if (!componentsByFile.has(filePath)) componentsByFile.set(filePath, []);
467
- componentsByFile.get(filePath).push({
525
+ componentsByFile.get(filePath)?.push({
468
526
  type: componentType,
469
527
  id: componentId,
470
528
  registryInfo: actualComponent
@@ -477,7 +535,7 @@ async function updateModifiedComponents(comparison, remoteProject, localRegistry
477
535
  for (const [filePath, fileComponents] of componentsByFile) {
478
536
  fileIndex++;
479
537
  try {
480
- const relativeFilePath = filePath.replace(projectRoot + "/", "");
538
+ const relativeFilePath = filePath.replace(`${projectRoot}/`, "");
481
539
  const componentNames = fileComponents.map((c) => `${c.type}:${c.id}`).join(", ");
482
540
  console.log(chalk.gray(` [${fileIndex}/${totalFiles}] Processing: ${relativeFilePath}`));
483
541
  console.log(chalk.gray(` Components: ${componentNames}`));
@@ -492,10 +550,10 @@ async function updateModifiedComponents(comparison, remoteProject, localRegistry
492
550
  componentData._agentId = agentId;
493
551
  break;
494
552
  }
495
- } else if (componentType === "fetchDefinitions") for (const [agentId, agentData] of Object.entries(remoteProject.agents || {})) {
553
+ } else if (componentType === "fetchDefinitions") for (const agentData of Object.values(remoteProject.agents || {})) {
496
554
  const contextConfig = agentData.contextConfig;
497
- if (contextConfig && contextConfig.contextVariables) {
498
- for (const [varName, variable] of Object.entries(contextConfig.contextVariables)) if (variable?.id === componentId) {
555
+ if (contextConfig?.contextVariables) {
556
+ for (const variable of Object.values(contextConfig.contextVariables)) if (variable?.id === componentId) {
499
557
  componentData = variable;
500
558
  break;
501
559
  }
@@ -503,13 +561,13 @@ async function updateModifiedComponents(comparison, remoteProject, localRegistry
503
561
  }
504
562
  }
505
563
  else if (componentType === "subAgents") {
506
- for (const [agentId, agentData] of Object.entries(remoteProject.agents || {})) if (agentData.subAgents && agentData.subAgents[componentId]) {
564
+ for (const agentData of Object.values(remoteProject.agents || {})) if (agentData.subAgents?.[componentId]) {
507
565
  componentData = agentData.subAgents[componentId];
508
566
  break;
509
567
  }
510
568
  } else if (componentType === "statusComponents") {
511
- for (const [agentId, agentData] of Object.entries(remoteProject.agents || {})) if (agentData.statusUpdates?.statusComponents && agentData.statusUpdates.statusComponents) {
512
- for (const statusComp of agentData.statusUpdates.statusComponents) if (statusComp["type"] === componentId) {
569
+ for (const agentData of Object.values(remoteProject.agents || {})) if (agentData.statusUpdates?.statusComponents && agentData.statusUpdates.statusComponents) {
570
+ for (const statusComp of agentData.statusUpdates.statusComponents) if (statusComp.type === componentId) {
513
571
  componentData = statusComp;
514
572
  break;
515
573
  }
@@ -526,7 +584,7 @@ async function updateModifiedComponents(comparison, remoteProject, localRegistry
526
584
  const agentCredentials = [];
527
585
  const credentialSet = /* @__PURE__ */ new Set();
528
586
  if (componentData.contextConfig?.contextVariables) {
529
- for (const [varName, varData] of Object.entries(componentData.contextConfig.contextVariables)) if (varData && typeof varData === "object" && varData.credentialReferenceId) {
587
+ for (const varData of Object.values(componentData.contextConfig.contextVariables)) if (varData && typeof varData === "object" && varData.credentialReferenceId) {
530
588
  const credId = varData.credentialReferenceId;
531
589
  if (remoteProject.credentialReferences[credId] && !credentialSet.has(credId)) {
532
590
  credentialSet.add(credId);
@@ -554,7 +612,7 @@ async function updateModifiedComponents(comparison, remoteProject, localRegistry
554
612
  continue;
555
613
  }
556
614
  try {
557
- const componentContent = generateUpdatedComponentContent(componentType, componentId, componentData, remoteProject, localRegistry, environment, relativeFilePath);
615
+ const componentContent = generateUpdatedComponentContent(componentType, componentId, componentData, remoteProject, localRegistry, relativeFilePath);
558
616
  componentContentParts.push(`// ${componentType}:${componentId}\n${componentContent}`);
559
617
  componentResults.push({
560
618
  componentId,
@@ -588,7 +646,7 @@ async function updateModifiedComponents(comparison, remoteProject, localRegistry
588
646
  let componentsToExport = [];
589
647
  try {
590
648
  componentsToExport = analyzeComponentsToExport(newComponents || [], relativeFilePath, localRegistry);
591
- } catch (error) {}
649
+ } catch {}
592
650
  const mergeResult = await mergeComponentsWithLLM({
593
651
  oldContent,
594
652
  newContent: newComponentContent,
@@ -604,7 +662,7 @@ async function updateModifiedComponents(comparison, remoteProject, localRegistry
604
662
  if (!mergeResult.success) finalContent = newComponentContent;
605
663
  else finalContent = mergeResult.mergedContent;
606
664
  writeToTempDirectory(projectRoot, filePath, finalContent, tempDirName);
607
- const relativePath = filePath.replace(projectRoot + "/", "");
665
+ const relativePath = filePath.replace(`${projectRoot}/`, "");
608
666
  const tempFilePath = join(projectRoot, tempDirName, relativePath);
609
667
  if (await runBiomeOnFile(tempFilePath)) {
610
668
  const formattedContent = readFileSync(tempFilePath, "utf8");
@@ -684,7 +742,7 @@ function analyzeComponentsToExport(newComponents, currentFilePath, localRegistry
684
742
  if (newComp.filePath === currentFilePath) continue;
685
743
  const allLocalComponents = localRegistry.getAllComponents();
686
744
  for (const localComp of allLocalComponents) if ((localComp.filePath.startsWith("/") ? localComp.filePath.split("/").slice(-2).join("/") : localComp.filePath) === currentFilePath) {
687
- if (shouldComponentBeExported(localComp, newComponents)) {
745
+ if (shouldComponentBeExported(localComp)) {
688
746
  if (!componentsToExport.find((c) => c.componentId === localComp.id)) componentsToExport.push({
689
747
  componentId: localComp.id,
690
748
  variableName: localComp.name,
@@ -698,7 +756,7 @@ function analyzeComponentsToExport(newComponents, currentFilePath, localRegistry
698
756
  /**
699
757
  * Determine if a component should be exported based on heuristics
700
758
  */
701
- function shouldComponentBeExported(localComponent, newComponents) {
759
+ function shouldComponentBeExported(localComponent) {
702
760
  if (localComponent.type === "agents" || localComponent.type === "subAgents") return true;
703
761
  if (localComponent.type === "tools" || localComponent.type === "functionTools") return true;
704
762
  if (localComponent.type === "contextConfigs") return true;
@@ -173,6 +173,13 @@ function generateAgentDefinition(agentId, agentData, style = DEFAULT_STYLE, regi
173
173
  }).join(", ")}]`;
174
174
  lines.push(`${indentation}credentials: () => ${credentialsArray},`);
175
175
  }
176
+ if (agentData.triggers && typeof agentData.triggers === "object" && Object.keys(agentData.triggers).length > 0) {
177
+ if (!registry) throw new Error("Registry is required for triggers generation");
178
+ const triggerIds = Object.keys(agentData.triggers);
179
+ const triggersArray = registry.formatReferencesForCode(triggerIds, "triggers", style, 2);
180
+ if (!triggersArray) throw new Error(`Failed to resolve variable names for triggers: ${triggerIds.join(", ")}`);
181
+ lines.push(`${indentation}triggers: () => ${triggersArray},`);
182
+ }
176
183
  if (agentData.stopWhen) {
177
184
  const stopWhenFormatted = formatStopWhen(agentData.stopWhen, style, 1);
178
185
  if (stopWhenFormatted) lines.push(stopWhenFormatted);
@@ -188,7 +195,7 @@ function generateAgentDefinition(agentId, agentData, style = DEFAULT_STYLE, regi
188
195
  /**
189
196
  * Generate imports needed for an agent file
190
197
  */
191
- function generateAgentImports(agentId, agentData, style = DEFAULT_STYLE, registry, contextConfigData, actualFilePath) {
198
+ function generateAgentImports(agentId, agentData, style = DEFAULT_STYLE, registry, actualFilePath) {
192
199
  const imports = [];
193
200
  imports.push(generateImport(["agent"], "@inkeep/agents-sdk", style));
194
201
  if (registry) {
@@ -201,7 +208,7 @@ function generateAgentImports(agentId, agentData, style = DEFAULT_STYLE, registr
201
208
  type: "subAgents"
202
209
  })));
203
210
  }
204
- if (agentData.statusUpdates && agentData.statusUpdates.statusComponents && Array.isArray(agentData.statusUpdates.statusComponents)) {
211
+ if (agentData.statusUpdates?.statusComponents && Array.isArray(agentData.statusUpdates.statusComponents)) {
205
212
  for (const comp of agentData.statusUpdates.statusComponents) if (typeof comp === "string") referencedComponents.push({
206
213
  id: comp,
207
214
  type: "statusComponents"
@@ -225,6 +232,13 @@ function generateAgentImports(agentId, agentData, style = DEFAULT_STYLE, registr
225
232
  id: agentData.defaultSubAgentId,
226
233
  type: "subAgents"
227
234
  });
235
+ if (agentData.triggers && typeof agentData.triggers === "object") {
236
+ const triggerIds = Object.keys(agentData.triggers);
237
+ referencedComponents.push(...triggerIds.map((id) => ({
238
+ id,
239
+ type: "triggers"
240
+ })));
241
+ }
228
242
  const componentImports = registry.getImportsForFile(currentFilePath, referencedComponents);
229
243
  imports.push(...componentImports);
230
244
  }
@@ -234,7 +248,7 @@ function generateAgentImports(agentId, agentData, style = DEFAULT_STYLE, registr
234
248
  * Generate complete agent file (imports + definition)
235
249
  */
236
250
  function generateAgentFile(agentId, agentData, style = DEFAULT_STYLE, registry, contextConfigData, projectModels, actualFilePath) {
237
- return generateFileContent(generateAgentImports(agentId, agentData, style, registry, contextConfigData, actualFilePath), [generateAgentDefinition(agentId, agentData, style, registry, contextConfigData, projectModels)]);
251
+ return generateFileContent(generateAgentImports(agentId, agentData, style, registry, actualFilePath), [generateAgentDefinition(agentId, agentData, style, registry, contextConfigData, projectModels)]);
238
252
  }
239
253
 
240
254
  //#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
  * Check if schema has any properties with inPreview: true
@@ -47,7 +47,7 @@ function formatArtifactSchema(schema, style) {
47
47
  lines.push(`${indentation}${key}: ${finalZodType},`);
48
48
  }
49
49
  lines.push("})");
50
- if (schema.description) return lines.join("\n") + `.describe(\`${schema.description}\`)`;
50
+ if (schema.description) return `${lines.join("\n")}.describe(\`${schema.description}\`)`;
51
51
  return lines.join("\n");
52
52
  }
53
53
  return convertJsonSchemaToZod(schema);
@@ -89,9 +89,9 @@ function generateArtifactComponentDefinition(componentId, componentData, style =
89
89
  const schemaLines = zodSchema.split("\n");
90
90
  lines.push(`${indentation}props: ${schemaLines[0]}`);
91
91
  schemaLines.slice(1, -1).forEach((line) => {
92
- lines[lines.length - 1] += "\n" + indentation + line;
92
+ lines[lines.length - 1] += `\n${indentation}${line}`;
93
93
  });
94
- lines[lines.length - 1] += "\n" + indentation + schemaLines[schemaLines.length - 1] + ",";
94
+ lines[lines.length - 1] += `\n${indentation}${schemaLines[schemaLines.length - 1]},`;
95
95
  } else lines.push(`${indentation}props: ${zodSchema},`);
96
96
  }
97
97
  if (componentData.render && typeof componentData.render === "object") {
@@ -119,7 +119,7 @@ function generateArtifactComponentDefinition(componentId, componentData, style =
119
119
  /**
120
120
  * Generate imports needed for an artifact component file
121
121
  */
122
- function generateArtifactComponentImports(componentId, componentData, style = DEFAULT_STYLE) {
122
+ function generateArtifactComponentImports(componentData, style = DEFAULT_STYLE) {
123
123
  const { quotes, semicolons } = style;
124
124
  const q = quotes === "single" ? "'" : "\"";
125
125
  const semi = semicolons ? ";" : "";
@@ -134,9 +134,9 @@ function generateArtifactComponentImports(componentId, componentData, style = DE
134
134
  * Generate complete artifact component file (imports + definition)
135
135
  */
136
136
  function generateArtifactComponentFile(componentId, componentData, style = DEFAULT_STYLE) {
137
- const imports = generateArtifactComponentImports(componentId, componentData, style);
137
+ const imports = generateArtifactComponentImports(componentData, style);
138
138
  const definition = generateArtifactComponentDefinition(componentId, componentData, style);
139
- return imports.join("\n") + "\n\n" + definition + "\n";
139
+ return `${imports.join("\n")}\n\n${definition}\n`;
140
140
  }
141
141
 
142
142
  //#endregion
@@ -23,7 +23,7 @@ function processFetchConfigTemplates(fetchConfig, headersVarName) {
23
23
  };
24
24
  const processObject = (obj) => {
25
25
  if (Array.isArray(obj)) return `[${obj.map((item) => processValue(item)).join(", ")}]`;
26
- return `{\n ${Object.entries(obj).filter(([key, val]) => val !== void 0 && val !== null).map(([key, val]) => {
26
+ return `{\n ${Object.entries(obj).filter(([_key, val]) => val !== void 0 && val !== null).map(([key, val]) => {
27
27
  return `${/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : `'${key}'`}: ${processValue(val)}`;
28
28
  }).join(",\n ")}\n }`;
29
29
  };
@@ -33,7 +33,7 @@ function processFetchConfigTemplates(fetchConfig, headersVarName) {
33
33
  * Generate Headers Definition using headers() builder function
34
34
  */
35
35
  function generateHeadersDefinition(headersId, headersData, style = DEFAULT_STYLE) {
36
- const { quotes, semicolons, indentation } = style;
36
+ const { semicolons, indentation } = style;
37
37
  const semi = semicolons ? ";" : "";
38
38
  const headersVarName = toCamelCase(headersId);
39
39
  const lines = [];
@@ -82,7 +82,7 @@ function generateFetchDefinitionDefinition(fetchId, fetchData, style = DEFAULT_S
82
82
  /**
83
83
  * Generate Context Config Definition using contextConfig() builder function
84
84
  */
85
- function generateContextConfigDefinition(contextId, contextData, style = DEFAULT_STYLE, registry, agentId, headersVarName) {
85
+ function generateContextConfigDefinition(contextId, contextData, style = DEFAULT_STYLE, registry, headersVarName) {
86
86
  if (!contextId || typeof contextId !== "string") throw new Error("contextId is required and must be a string");
87
87
  if (!contextData || typeof contextData !== "object") throw new Error(`contextData is required for context config '${contextId}'`);
88
88
  const { quotes, semicolons, indentation } = style;
@@ -124,7 +124,7 @@ function generateContextConfigImports(contextId, contextData, style = DEFAULT_ST
124
124
  if (hasSchemas(contextData)) imports.push(generateImport(["z"], "zod", style));
125
125
  if (registry && contextData.contextVariables) {
126
126
  const credentialRefs = [];
127
- for (const [varName, varData] of Object.entries(contextData.contextVariables)) if (varData && typeof varData === "object" && varData.credentialReferenceId) credentialRefs.push({
127
+ for (const varData of Object.values(contextData.contextVariables)) if (varData && typeof varData === "object" && "credentialReferenceId" in varData) credentialRefs.push({
128
128
  id: varData.credentialReferenceId,
129
129
  type: "credentials"
130
130
  });
@@ -154,7 +154,7 @@ function hasSchemas(contextData) {
154
154
  /**
155
155
  * Generate complete context config file (imports + all definitions)
156
156
  */
157
- function generateContextConfigFile(contextId, contextData, style = DEFAULT_STYLE, registry, agentId) {
157
+ function generateContextConfigFile(contextId, contextData, style = DEFAULT_STYLE, registry) {
158
158
  const imports = generateContextConfigImports(contextId, contextData, style, registry);
159
159
  const definitions = [];
160
160
  let headersVarName;
@@ -170,7 +170,7 @@ function generateContextConfigFile(contextId, contextData, style = DEFAULT_STYLE
170
170
  definitions.push(fetchDefinition);
171
171
  }
172
172
  }
173
- const contextDefinition = generateContextConfigDefinition(contextId, contextData, style, registry, agentId, headersVarName);
173
+ const contextDefinition = generateContextConfigDefinition(contextId, contextData, style, registry, headersVarName);
174
174
  definitions.push(contextDefinition);
175
175
  const exports = [(() => {
176
176
  if (!registry) throw new Error("Registry is required for context config variable name generation");
@@ -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
  * Format retrieval params object
@@ -68,7 +68,7 @@ function generateCredentialDefinition(credentialId, credentialData, style = DEFA
68
68
  /**
69
69
  * Generate imports needed for a credential file
70
70
  */
71
- function generateCredentialImports(credentialId, credentialData, style = DEFAULT_STYLE) {
71
+ function generateCredentialImports(style = DEFAULT_STYLE) {
72
72
  const { quotes, semicolons } = style;
73
73
  const q = quotes === "single" ? "'" : "\"";
74
74
  const semi = semicolons ? ";" : "";
@@ -80,9 +80,9 @@ function generateCredentialImports(credentialId, credentialData, style = DEFAULT
80
80
  * Generate complete credential file (imports + definition)
81
81
  */
82
82
  function generateCredentialFile(credentialId, credentialData, style = DEFAULT_STYLE) {
83
- const imports = generateCredentialImports(credentialId, credentialData, style);
83
+ const imports = generateCredentialImports(style);
84
84
  const definition = generateCredentialDefinition(credentialId, credentialData, style);
85
- return imports.join("\n") + "\n\n" + definition + "\n";
85
+ return `${imports.join("\n")}\n\n${definition}\n`;
86
86
  }
87
87
 
88
88
  //#endregion
@@ -20,7 +20,7 @@ function toCamelCase(str) {
20
20
  function formatString(str, quote = "'", multiline = false) {
21
21
  if (!str) return `${quote}${quote}`;
22
22
  if (multiline && (str.includes("\n") || str.length > 80)) return `\`${str.replace(/`/g, "\\`")}\``;
23
- return `${quote}${str.replace(new RegExp(quote, "g"), "\\" + quote)}${quote}`;
23
+ return `${quote}${str.replace(new RegExp(quote, "g"), `\\${quote}`)}${quote}`;
24
24
  }
25
25
  /**
26
26
  * Convert JSON Schema to Zod schema using existing utility
@@ -80,7 +80,7 @@ function generateDataComponentDefinition(componentId, componentData, style = DEF
80
80
  /**
81
81
  * Generate imports needed for a data component file
82
82
  */
83
- function generateDataComponentImports(componentId, componentData, style = DEFAULT_STYLE) {
83
+ function generateDataComponentImports(componentData, style = DEFAULT_STYLE) {
84
84
  const { quotes, semicolons } = style;
85
85
  const q = quotes === "single" ? "'" : "\"";
86
86
  const semi = semicolons ? ";" : "";
@@ -93,9 +93,9 @@ function generateDataComponentImports(componentId, componentData, style = DEFAUL
93
93
  * Generate complete data component file (imports + definition)
94
94
  */
95
95
  function generateDataComponentFile(componentId, componentData, style = DEFAULT_STYLE) {
96
- const imports = generateDataComponentImports(componentId, componentData, style);
96
+ const imports = generateDataComponentImports(componentData, style);
97
97
  const definition = generateDataComponentDefinition(componentId, componentData, style);
98
- return imports.join("\n") + "\n\n" + definition + "\n";
98
+ return `${imports.join("\n")}\n\n${definition}\n`;
99
99
  }
100
100
 
101
101
  //#endregion