@inkeep/agents-cli 0.52.0 → 0.53.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 (28) hide show
  1. package/dist/agents-cli/package.js +1 -1
  2. package/dist/commands/{pull-v3 → pull-v4}/component-parser.js +3 -3
  3. package/dist/commands/{pull-v3/utils → pull-v4}/component-registry.js +1 -1
  4. package/dist/commands/pull-v4/{agent-generator.js → generators/agent-generator.js} +2 -18
  5. package/dist/commands/pull-v4/{artifact-component-generator.js → generators/artifact-component-generator.js} +2 -2
  6. package/dist/commands/pull-v4/{context-config-generator.js → generators/context-config-generator.js} +2 -2
  7. package/dist/commands/pull-v4/{credential-generator.js → generators/credential-generator.js} +2 -2
  8. package/dist/commands/pull-v4/{data-component-generator.js → generators/data-component-generator.js} +2 -2
  9. package/dist/commands/pull-v4/{environment-generator.js → generators/environment-generator.js} +2 -2
  10. package/dist/commands/pull-v4/{external-agent-generator.js → generators/external-agent-generator.js} +2 -2
  11. package/dist/commands/pull-v4/{function-tool-generator.js → generators/function-tool-generator.js} +2 -2
  12. package/dist/commands/pull-v4/{mcp-tool-generator.js → generators/mcp-tool-generator.js} +5 -5
  13. package/dist/commands/pull-v4/{project-generator.js → generators/project-generator.js} +48 -24
  14. package/dist/commands/{pull-v3/components → pull-v4/generators}/skill-generator.js +1 -1
  15. package/dist/commands/pull-v4/{status-component-generator.js → generators/status-component-generator.js} +2 -2
  16. package/dist/commands/pull-v4/{sub-agent-generator.js → generators/sub-agent-generator.js} +103 -2
  17. package/dist/commands/pull-v4/{trigger-generator.js → generators/trigger-generator.js} +2 -2
  18. package/dist/commands/pull-v4/introspect/index.js +3 -3
  19. package/dist/commands/pull-v4/introspect/test-helpers.js +1 -1
  20. package/dist/commands/pull-v4/introspect-generator.js +26 -11
  21. package/dist/commands/pull-v4/module-merge.js +33 -7
  22. package/dist/commands/pull-v4/utils.js +17 -1
  23. package/package.json +3 -6
  24. package/dist/commands/pull-v3/project-comparator.js +0 -914
  25. package/dist/commands/pull-v3/targeted-typescript-placeholders.js +0 -173
  26. package/dist/commands/pull-v3/utils/component-tracker.js +0 -165
  27. package/dist/commands/pull-v3/utils/generator-utils.js +0 -146
  28. package/dist/commands/pull-v3/utils/model-provider-detector.js +0 -50
@@ -1,6 +1,6 @@
1
1
  //#region package.json
2
2
  var name = "@inkeep/agents-cli";
3
- var version = "0.52.0";
3
+ var version = "0.53.0";
4
4
 
5
5
  //#endregion
6
6
  export { name, version };
@@ -1,10 +1,10 @@
1
- import { ComponentRegistry } from "./utils/component-registry.js";
2
- import { createInMemoryProject } from "../pull-v4/utils.js";
1
+ import { ComponentRegistry } from "./component-registry.js";
2
+ import { createInMemoryProject } from "./utils.js";
3
3
  import { extname, join, relative } from "node:path";
4
4
  import { Node } from "ts-morph";
5
5
  import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
6
6
 
7
- //#region src/commands/pull-v3/component-parser.ts
7
+ //#region src/commands/pull-v4/component-parser.ts
8
8
  /**
9
9
  * Component Parser - Find all component definitions (exported and inline)
10
10
  * Uses AST parsing to handle complex components including those with render attributes
@@ -1,4 +1,4 @@
1
- //#region src/commands/pull-v3/utils/component-registry.ts
1
+ //#region src/commands/pull-v4/component-registry.ts
2
2
  var ComponentRegistry = class {
3
3
  components = /* @__PURE__ */ new Map();
4
4
  componentsByTypeAndId = /* @__PURE__ */ new Map();
@@ -1,8 +1,8 @@
1
- import { addObjectEntries, addReferenceGetterProperty, addStringProperty, collectTemplateVariableNames, createFactoryDefinition, formatStringLiteral, formatTemplate, isPlainObject, toCamelCase } from "./utils.js";
1
+ import { addObjectEntries, addReferenceGetterProperty, addStringProperty, collectTemplateVariableNames, createFactoryDefinition, createUniqueReferenceName, formatStringLiteral, formatTemplate, isPlainObject, toCamelCase } from "../utils.js";
2
2
  import { z } from "zod";
3
3
  import { SyntaxKind } from "ts-morph";
4
4
 
5
- //#region src/commands/pull-v4/agent-generator.ts
5
+ //#region src/commands/pull-v4/generators/agent-generator.ts
6
6
  const SubAgentReferenceSchema = z.object({
7
7
  name: z.string().nonempty(),
8
8
  local: z.boolean().optional()
@@ -253,22 +253,6 @@ function createReferenceNameMap(ids, reservedNames, conflictSuffix) {
253
253
  }
254
254
  return map;
255
255
  }
256
- function createUniqueReferenceName(baseName, reservedNames, conflictSuffix) {
257
- if (!reservedNames.has(baseName)) {
258
- reservedNames.add(baseName);
259
- return baseName;
260
- }
261
- const baseCandidate = `${baseName}${conflictSuffix}`;
262
- if (!reservedNames.has(baseCandidate)) {
263
- reservedNames.add(baseCandidate);
264
- return baseCandidate;
265
- }
266
- let index = 2;
267
- while (reservedNames.has(`${baseCandidate}${index}`)) index += 1;
268
- const uniqueName = `${baseCandidate}${index}`;
269
- reservedNames.add(uniqueName);
270
- return uniqueName;
271
- }
272
256
 
273
257
  //#endregion
274
258
  export { generateAgentDefinition };
@@ -1,7 +1,7 @@
1
- import { addValueToObject, convertJsonSchemaToZodSafe, convertNullToUndefined, createFactoryDefinition, formatPropertyName, formatStringLiteral, isPlainObject, toCamelCase } from "./utils.js";
1
+ import { addValueToObject, convertJsonSchemaToZodSafe, convertNullToUndefined, createFactoryDefinition, formatPropertyName, formatStringLiteral, isPlainObject, toCamelCase } from "../utils.js";
2
2
  import { z } from "zod";
3
3
 
4
- //#region src/commands/pull-v4/artifact-component-generator.ts
4
+ //#region src/commands/pull-v4/generators/artifact-component-generator.ts
5
5
  const ArtifactComponentSchema = z.object({
6
6
  artifactComponentId: z.string().nonempty(),
7
7
  name: z.string().nonempty(),
@@ -1,8 +1,8 @@
1
- import { addFactoryConfigVariable, addStringProperty, addValueToObject, convertJsonSchemaToZodSafe, convertNullToUndefined, createInMemoryProject, formatPropertyName, isPlainObject, toCamelCase } from "./utils.js";
1
+ import { addFactoryConfigVariable, addStringProperty, addValueToObject, convertJsonSchemaToZodSafe, convertNullToUndefined, createInMemoryProject, formatPropertyName, isPlainObject, toCamelCase } from "../utils.js";
2
2
  import { z } from "zod";
3
3
  import { SyntaxKind } from "ts-morph";
4
4
 
5
- //#region src/commands/pull-v4/context-config-generator.ts
5
+ //#region src/commands/pull-v4/generators/context-config-generator.ts
6
6
  const ReferenceNameByIdSchema = z.record(z.string(), z.string().nonempty());
7
7
  const ReferenceOverridesSchema = z.object({ credentialReferences: ReferenceNameByIdSchema.optional() });
8
8
  const ContextConfigSchema = z.looseObject({
@@ -1,7 +1,7 @@
1
- import { addValueToObject, createFactoryDefinition, toCamelCase } from "./utils.js";
1
+ import { addValueToObject, createFactoryDefinition, toCamelCase } from "../utils.js";
2
2
  import { z } from "zod";
3
3
 
4
- //#region src/commands/pull-v4/credential-generator.ts
4
+ //#region src/commands/pull-v4/generators/credential-generator.ts
5
5
  const CredentialSchema = z.object({
6
6
  credentialId: z.string().nonempty(),
7
7
  name: z.string().nonempty(),
@@ -1,7 +1,7 @@
1
- import { addStringProperty, addValueToObject, convertJsonSchemaToZodSafe, createFactoryDefinition, toCamelCase } from "./utils.js";
1
+ import { addStringProperty, addValueToObject, convertJsonSchemaToZodSafe, createFactoryDefinition, toCamelCase } from "../utils.js";
2
2
  import { z } from "zod";
3
3
 
4
- //#region src/commands/pull-v4/data-component-generator.ts
4
+ //#region src/commands/pull-v4/generators/data-component-generator.ts
5
5
  const DataComponentSchema = z.object({
6
6
  dataComponentId: z.string().nonempty(),
7
7
  name: z.string().nonempty(),
@@ -1,8 +1,8 @@
1
- import { addStringProperty, createFactoryDefinition, formatInlineLiteral, formatPropertyName, isPlainObject } from "./utils.js";
1
+ import { addStringProperty, createFactoryDefinition, formatInlineLiteral, formatPropertyName, isPlainObject } from "../utils.js";
2
2
  import { z } from "zod";
3
3
  import { SyntaxKind } from "ts-morph";
4
4
 
5
- //#region src/commands/pull-v4/environment-generator.ts
5
+ //#region src/commands/pull-v4/generators/environment-generator.ts
6
6
  const EnvironmentSettingsSchema = z.looseObject({ credentials: z.record(z.string(), z.unknown()).nullable().optional() });
7
7
  const EnvironmentIndexSchema = z.array(z.string());
8
8
  function generateEnvironmentSettingsImports(environmentData) {
@@ -1,8 +1,8 @@
1
- import { addStringProperty, createFactoryDefinition, toCamelCase } from "./utils.js";
1
+ import { addStringProperty, createFactoryDefinition, toCamelCase } from "../utils.js";
2
2
  import { z } from "zod";
3
3
  import { SyntaxKind } from "ts-morph";
4
4
 
5
- //#region src/commands/pull-v4/external-agent-generator.ts
5
+ //#region src/commands/pull-v4/generators/external-agent-generator.ts
6
6
  const ExternalAgentSchema = z.looseObject({
7
7
  externalAgentId: z.string().nonempty(),
8
8
  name: z.string().nonempty(),
@@ -1,7 +1,7 @@
1
- import { addValueToObject, createFactoryDefinition, toCamelCase } from "./utils.js";
1
+ import { addValueToObject, createFactoryDefinition, toCamelCase } from "../utils.js";
2
2
  import { z } from "zod";
3
3
 
4
- //#region src/commands/pull-v4/function-tool-generator.ts
4
+ //#region src/commands/pull-v4/generators/function-tool-generator.ts
5
5
  const FunctionToolSchema = z.looseObject({
6
6
  functionToolId: z.string().nonempty(),
7
7
  name: z.string().nonempty(),
@@ -1,8 +1,8 @@
1
- import { addValueToObject, createFactoryDefinition, formatInlineLiteral, formatStringLiteral, toCamelCase } from "./utils.js";
1
+ import { addValueToObject, createFactoryDefinition, formatInlineLiteral, formatStringLiteral, toCamelCase } from "../utils.js";
2
2
  import { z } from "zod";
3
3
 
4
- //#region src/commands/pull-v4/mcp-tool-generator.ts
5
- const McpToolSchema = z.looseObject({
4
+ //#region src/commands/pull-v4/generators/mcp-tool-generator.ts
5
+ const McpToolSchema = z.object({
6
6
  mcpToolId: z.string().nonempty(),
7
7
  name: z.string().nonempty(),
8
8
  description: z.string().nullable().optional(),
@@ -14,10 +14,10 @@ const McpToolSchema = z.looseObject({
14
14
  serverUrl: z.string().optional(),
15
15
  transport: z.object({ type: z.string() }).optional(),
16
16
  activeTools: z.array(z.unknown()).optional(),
17
- imageUrl: z.string().optional(),
17
+ imageUrl: z.string().nullish(),
18
18
  headers: z.unknown().optional(),
19
19
  credential: z.unknown().optional(),
20
- credentialReferenceId: z.string().optional()
20
+ credentialReferenceId: z.string().nullish()
21
21
  }).superRefine((value, context) => {
22
22
  if (!resolveServerUrl(value)) context.addIssue({
23
23
  code: "custom",
@@ -1,7 +1,7 @@
1
- import { addReferenceGetterProperty, addValueToObject, convertNullToUndefined, createFactoryDefinition, formatStringLiteral, hasReferences, resolveReferenceName, toCamelCase } from "./utils.js";
1
+ import { addReferenceGetterProperty, addValueToObject, convertNullToUndefined, createFactoryDefinition, createUniqueReferenceName, formatStringLiteral, hasReferences, resolveReferenceName, toCamelCase } from "../utils.js";
2
2
  import { z } from "zod";
3
3
 
4
- //#region src/commands/pull-v4/project-generator.ts
4
+ //#region src/commands/pull-v4/generators/project-generator.ts
5
5
  const ReferenceNameByIdSchema = z.record(z.string(), z.string().nonempty());
6
6
  const ReferenceOverridesSchema = z.object({
7
7
  agents: ReferenceNameByIdSchema.optional(),
@@ -38,10 +38,12 @@ function generateProjectDefinition(data) {
38
38
  if (!result.success) throw new Error(`Validation failed for project:
39
39
  ${z.prettifyError(result.error)}`);
40
40
  const parsed = result.data;
41
+ const projectVariableName = toCamelCase(parsed.projectId);
41
42
  const { sourceFile, configObject } = createFactoryDefinition({
42
43
  importName: "project",
43
- variableName: toCamelCase(parsed.projectId)
44
+ variableName: projectVariableName
44
45
  });
46
+ const reservedReferenceNames = new Set([projectVariableName]);
45
47
  if (hasReferences(parsed.skills)) {
46
48
  sourceFile.getImportDeclarationOrThrow("@inkeep/agents-sdk").addNamedImport("loadSkills");
47
49
  sourceFile.addImportDeclaration({
@@ -59,42 +61,64 @@ ${z.prettifyError(result.error)}`);
59
61
  initializer: `() => loadSkills(path.join(${formatStringLiteral(projectId)}, 'skills'))`
60
62
  });
61
63
  if (hasReferences(agents)) {
62
- addReferenceImports(sourceFile, agents, "./agents", referenceOverrides?.agents);
63
- addReferenceGetterProperty(configObject, "agents", toReferenceNames(agents, referenceOverrides?.agents));
64
+ const resolvedReferences = createResolvedReferences(agents, referenceOverrides?.agents, reservedReferenceNames, "Agent");
65
+ addReferenceImports(sourceFile, resolvedReferences, "./agents");
66
+ addReferenceGetterProperty(configObject, "agents", toReferenceNames(resolvedReferences));
64
67
  }
65
68
  if (hasReferences(tools)) {
66
- addReferenceImports(sourceFile, tools, "./tools", referenceOverrides?.tools);
67
- addReferenceGetterProperty(configObject, "tools", toReferenceNames(tools, referenceOverrides?.tools));
69
+ const resolvedReferences = createResolvedReferences(tools, referenceOverrides?.tools, reservedReferenceNames, "Tool");
70
+ addReferenceImports(sourceFile, resolvedReferences, "./tools");
71
+ addReferenceGetterProperty(configObject, "tools", toReferenceNames(resolvedReferences));
68
72
  }
69
73
  if (hasReferences(externalAgents)) {
70
- addReferenceImports(sourceFile, externalAgents, "./external-agents", referenceOverrides?.externalAgents);
71
- addReferenceGetterProperty(configObject, "externalAgents", toReferenceNames(externalAgents, referenceOverrides?.externalAgents));
74
+ const resolvedReferences = createResolvedReferences(externalAgents, referenceOverrides?.externalAgents, reservedReferenceNames, "ExternalAgent");
75
+ addReferenceImports(sourceFile, resolvedReferences, "./external-agents");
76
+ addReferenceGetterProperty(configObject, "externalAgents", toReferenceNames(resolvedReferences));
72
77
  }
73
78
  if (hasReferences(dataComponents)) {
74
- addReferenceImports(sourceFile, dataComponents, "./data-components", referenceOverrides?.dataComponents);
75
- addReferenceGetterProperty(configObject, "dataComponents", toReferenceNames(dataComponents, referenceOverrides?.dataComponents));
79
+ const resolvedReferences = createResolvedReferences(dataComponents, referenceOverrides?.dataComponents, reservedReferenceNames, "DataComponent");
80
+ addReferenceImports(sourceFile, resolvedReferences, "./data-components");
81
+ addReferenceGetterProperty(configObject, "dataComponents", toReferenceNames(resolvedReferences));
76
82
  }
77
83
  if (hasReferences(artifactComponents)) {
78
- addReferenceImports(sourceFile, artifactComponents, "./artifact-components", referenceOverrides?.artifactComponents);
79
- addReferenceGetterProperty(configObject, "artifactComponents", toReferenceNames(artifactComponents, referenceOverrides?.artifactComponents));
84
+ const resolvedReferences = createResolvedReferences(artifactComponents, referenceOverrides?.artifactComponents, reservedReferenceNames, "ArtifactComponent");
85
+ addReferenceImports(sourceFile, resolvedReferences, "./artifact-components");
86
+ addReferenceGetterProperty(configObject, "artifactComponents", toReferenceNames(resolvedReferences));
80
87
  }
81
88
  if (hasReferences(credentialReferences)) {
82
- addReferenceImports(sourceFile, credentialReferences, "./credentials", referenceOverrides?.credentialReferences);
83
- addReferenceGetterProperty(configObject, "credentialReferences", toReferenceNames(credentialReferences, referenceOverrides?.credentialReferences));
89
+ const resolvedReferences = createResolvedReferences(credentialReferences, referenceOverrides?.credentialReferences, reservedReferenceNames, "CredentialReference");
90
+ addReferenceImports(sourceFile, resolvedReferences, "./credentials");
91
+ addReferenceGetterProperty(configObject, "credentialReferences", toReferenceNames(resolvedReferences));
84
92
  }
85
93
  return sourceFile;
86
94
  }
87
- function addReferenceImports(sourceFile, references, basePath, referenceOverrides) {
88
- for (const reference of references) {
89
- const referenceName = resolveReferenceName(reference, [referenceOverrides]);
90
- sourceFile.addImportDeclaration({
91
- namedImports: [referenceName],
92
- moduleSpecifier: `${basePath}/${reference}`
95
+ function addReferenceImports(sourceFile, references, basePath) {
96
+ for (const reference of references) sourceFile.addImportDeclaration({
97
+ namedImports: [reference.importName === reference.localName ? reference.importName : {
98
+ name: reference.importName,
99
+ alias: reference.localName
100
+ }],
101
+ moduleSpecifier: `${basePath}/${reference.id}`
102
+ });
103
+ }
104
+ function toReferenceNames(references) {
105
+ return references.map((reference) => reference.localName);
106
+ }
107
+ function createResolvedReferences(references, referenceOverrides, reservedReferenceNames, suffix) {
108
+ const seenIds = /* @__PURE__ */ new Set();
109
+ const resolvedReferences = [];
110
+ for (const referenceId of references) {
111
+ if (seenIds.has(referenceId)) continue;
112
+ seenIds.add(referenceId);
113
+ const importName = resolveReferenceName(referenceId, [referenceOverrides]);
114
+ const localName = createUniqueReferenceName(importName, reservedReferenceNames, suffix);
115
+ resolvedReferences.push({
116
+ id: referenceId,
117
+ importName,
118
+ localName
93
119
  });
94
120
  }
95
- }
96
- function toReferenceNames(references, referenceOverrides) {
97
- return references.map((reference) => resolveReferenceName(reference, [referenceOverrides]));
121
+ return resolvedReferences;
98
122
  }
99
123
 
100
124
  //#endregion
@@ -2,7 +2,7 @@ import { join } from "node:path";
2
2
  import { stringify } from "yaml";
3
3
  import { mkdir, writeFile } from "node:fs/promises";
4
4
 
5
- //#region src/commands/pull-v3/components/skill-generator.ts
5
+ //#region src/commands/pull-v4/generators/skill-generator.ts
6
6
  function formatMetadata(metadata) {
7
7
  return `metadata:\n${stringify(metadata).split("\n").filter((line) => line.trim() !== "").map((line) => ` ${line}`).join("\n")}`;
8
8
  }
@@ -1,7 +1,7 @@
1
- import { addValueToObject, convertJsonSchemaToZodSafe, createFactoryDefinition, toCamelCase } from "./utils.js";
1
+ import { addValueToObject, convertJsonSchemaToZodSafe, createFactoryDefinition, toCamelCase } from "../utils.js";
2
2
  import { z } from "zod";
3
3
 
4
- //#region src/commands/pull-v4/status-component-generator.ts
4
+ //#region src/commands/pull-v4/generators/status-component-generator.ts
5
5
  const StatusComponentSchema = z.looseObject({
6
6
  statusComponentId: z.string().nonempty(),
7
7
  type: z.string().nonempty(),
@@ -1,9 +1,9 @@
1
- import { addReferenceGetterProperty, addStringProperty, addValueToObject, collectTemplateVariableNames, convertNullToUndefined, createFactoryDefinition, formatInlineLiteral, formatTemplate, hasReferences, isPlainObject, resolveReferenceName, toCamelCase } from "./utils.js";
1
+ import { addReferenceGetterProperty, addStringProperty, addValueToObject, collectTemplateVariableNames, convertNullToUndefined, createFactoryDefinition, formatInlineLiteral, formatTemplate, hasReferences, isPlainObject, resolveReferenceName, toCamelCase } from "../utils.js";
2
2
  import { FullAgentAgentInsertSchema } from "@inkeep/agents-core";
3
3
  import { z } from "zod";
4
4
  import { SyntaxKind } from "ts-morph";
5
5
 
6
- //#region src/commands/pull-v4/sub-agent-generator.ts
6
+ //#region src/commands/pull-v4/generators/sub-agent-generator.ts
7
7
  const ReferenceNameByIdSchema = z.record(z.string(), z.string().nonempty());
8
8
  const ReferenceOverridesSchema = z.object({
9
9
  tools: ReferenceNameByIdSchema.optional(),
@@ -54,12 +54,113 @@ function generateSubAgentDefinition(data) {
54
54
  namedImports: [...new Set(namedImports)],
55
55
  moduleSpecifier: `../context-configs/${parsed.contextConfigId}`
56
56
  });
57
+ addCanUseToolImports(sourceFile, parsed.canUse, parsed.referenceOverrides?.tools);
58
+ addDataComponentImports(sourceFile, parsed.dataComponents, parsed.referenceOverrides?.dataComponents);
59
+ addArtifactComponentImports(sourceFile, parsed.artifactComponents, parsed.referenceOverrides?.artifactComponents);
60
+ addDelegateTargetImports(sourceFile, {
61
+ currentSubAgentId: parsed.id,
62
+ canDelegateTo: parsed.canDelegateTo,
63
+ canTransferTo: parsed.canTransferTo,
64
+ referenceOverrides: {
65
+ subAgents: parsed.referenceOverrides?.subAgents,
66
+ agents: parsed.referenceOverrides?.agents,
67
+ externalAgents: parsed.referenceOverrides?.externalAgents
68
+ }
69
+ });
57
70
  writeSubAgentConfig(configObject, {
58
71
  contextReference: parsed.contextConfigReference?.name,
59
72
  headersReference: parsed.contextConfigHeadersReference?.name
60
73
  }, parsed);
61
74
  return sourceFile;
62
75
  }
76
+ function addCanUseToolImports(sourceFile, canUse, toolReferenceOverrides) {
77
+ const toolImportsById = /* @__PURE__ */ new Map();
78
+ for (const item of canUse ?? []) {
79
+ const toolId = typeof item === "string" ? item : isPlainObject(item) && typeof item.toolId === "string" ? item.toolId : void 0;
80
+ if (!toolId || toolImportsById.has(toolId)) continue;
81
+ toolImportsById.set(toolId, resolveReferenceName(toolId, [toolReferenceOverrides]));
82
+ }
83
+ for (const [toolId, referenceName] of toolImportsById) sourceFile.addImportDeclaration({
84
+ namedImports: [referenceName],
85
+ moduleSpecifier: `../../tools/${toolId}`
86
+ });
87
+ }
88
+ function addDataComponentImports(sourceFile, dataComponents, dataComponentReferenceOverrides) {
89
+ addReferenceImports(sourceFile, dataComponents, "../../data-components", dataComponentReferenceOverrides);
90
+ }
91
+ function addArtifactComponentImports(sourceFile, artifactComponents, artifactComponentReferenceOverrides) {
92
+ addReferenceImports(sourceFile, artifactComponents, "../../artifact-components", artifactComponentReferenceOverrides);
93
+ }
94
+ function addReferenceImports(sourceFile, references, basePath, referenceOverrides) {
95
+ const importByReferenceId = /* @__PURE__ */ new Map();
96
+ for (const referenceId of references ?? []) {
97
+ if (!referenceId || importByReferenceId.has(referenceId)) continue;
98
+ importByReferenceId.set(referenceId, resolveReferenceName(referenceId, [referenceOverrides]));
99
+ }
100
+ for (const [referenceId, referenceName] of importByReferenceId) sourceFile.addImportDeclaration({
101
+ namedImports: [referenceName],
102
+ moduleSpecifier: `${basePath}/${referenceId}`
103
+ });
104
+ }
105
+ function addDelegateTargetImports(sourceFile, options) {
106
+ const importsByTarget = /* @__PURE__ */ new Map();
107
+ for (const item of options.canDelegateTo ?? []) {
108
+ const resolvedTarget = resolveDelegateTargetImport(item, options.referenceOverrides);
109
+ if (!resolvedTarget) continue;
110
+ if (resolvedTarget.type === "subAgents" && resolvedTarget.id === options.currentSubAgentId) continue;
111
+ importsByTarget.set(`${resolvedTarget.type}:${resolvedTarget.id}`, resolvedTarget);
112
+ }
113
+ for (const targetId of options.canTransferTo ?? []) {
114
+ const resolvedTarget = resolveDelegateTargetImport(targetId, options.referenceOverrides);
115
+ if (!resolvedTarget) continue;
116
+ if (resolvedTarget.type === "subAgents" && resolvedTarget.id === options.currentSubAgentId) continue;
117
+ importsByTarget.set(`${resolvedTarget.type}:${resolvedTarget.id}`, resolvedTarget);
118
+ }
119
+ for (const target of importsByTarget.values()) sourceFile.addImportDeclaration({
120
+ namedImports: [target.name],
121
+ moduleSpecifier: resolveDelegateImportModuleSpecifier(target.type, target.id)
122
+ });
123
+ }
124
+ function resolveDelegateTargetImport(canDelegateToEntry, referenceOverrides) {
125
+ if (typeof canDelegateToEntry === "string") {
126
+ const resolvedType = resolveDelegateTargetType(canDelegateToEntry, referenceOverrides);
127
+ if (!resolvedType) return;
128
+ return {
129
+ type: resolvedType,
130
+ id: canDelegateToEntry,
131
+ name: resolveReferenceName(canDelegateToEntry, [referenceOverrides[resolvedType]])
132
+ };
133
+ }
134
+ if (!isPlainObject(canDelegateToEntry)) return;
135
+ if (typeof canDelegateToEntry.subAgentId === "string") return {
136
+ type: "subAgents",
137
+ id: canDelegateToEntry.subAgentId,
138
+ name: resolveReferenceName(canDelegateToEntry.subAgentId, [referenceOverrides.subAgents])
139
+ };
140
+ if (typeof canDelegateToEntry.agentId === "string") return {
141
+ type: "agents",
142
+ id: canDelegateToEntry.agentId,
143
+ name: resolveReferenceName(canDelegateToEntry.agentId, [referenceOverrides.agents])
144
+ };
145
+ if (typeof canDelegateToEntry.externalAgentId === "string") return {
146
+ type: "externalAgents",
147
+ id: canDelegateToEntry.externalAgentId,
148
+ name: resolveReferenceName(canDelegateToEntry.externalAgentId, [referenceOverrides.externalAgents])
149
+ };
150
+ }
151
+ function resolveDelegateTargetType(targetId, referenceOverrides) {
152
+ if (referenceOverrides.subAgents?.[targetId]) return "subAgents";
153
+ if (referenceOverrides.agents?.[targetId]) return "agents";
154
+ if (referenceOverrides.externalAgents?.[targetId]) return "externalAgents";
155
+ return "subAgents";
156
+ }
157
+ function resolveDelegateImportModuleSpecifier(type, id) {
158
+ switch (type) {
159
+ case "subAgents": return `./${id}`;
160
+ case "agents": return `../${id}`;
161
+ case "externalAgents": return `../../external-agents/${id}`;
162
+ }
163
+ }
63
164
  function writeSubAgentConfig(configObject, templateReferences, { dataComponents, name, canDelegateTo, canTransferTo, skills, artifactComponents, canUse, referenceOverrides, contextConfigId: _contextConfigId, contextConfigReference: _contextConfigReference, contextConfigHeadersReference: _contextConfigHeadersReference, ...rest }) {
64
165
  rest = { ...rest };
65
166
  rest.prompt &&= formatTemplate(rest.prompt, templateReferences);
@@ -1,8 +1,8 @@
1
- import { addValueToObject, createFactoryDefinition, toCamelCase } from "./utils.js";
1
+ import { addValueToObject, createFactoryDefinition, toCamelCase } from "../utils.js";
2
2
  import { z } from "zod";
3
3
  import { SyntaxKind } from "ts-morph";
4
4
 
5
- //#region src/commands/pull-v4/trigger-generator.ts
5
+ //#region src/commands/pull-v4/generators/trigger-generator.ts
6
6
  const TriggerSchema = z.looseObject({
7
7
  triggerId: z.string().nonempty(),
8
8
  name: z.string().nonempty(),
@@ -2,7 +2,7 @@ import { ManagementApiClient } from "../../../api.js";
2
2
  import { initializeCommand } from "../../../utils/cli-pipeline.js";
3
3
  import { performBackgroundVersionCheck } from "../../../utils/background-version-check.js";
4
4
  import { loadProject } from "../../../utils/project-loader.js";
5
- import { extractSubAgents } from "../../pull-v3/utils/component-registry.js";
5
+ import { extractSubAgents } from "../component-registry.js";
6
6
  import { introspectGenerate } from "../introspect-generator.js";
7
7
  import { join, resolve } from "node:path";
8
8
  import * as p from "@clack/prompts";
@@ -63,7 +63,7 @@ function enrichCanDelegateToWithTypes(project) {
63
63
  }
64
64
  }
65
65
  /**
66
- * Main pull-v3 command
66
+ * Main pull v4 command
67
67
  * @returns PullResult when in batch mode, otherwise void (exits process)
68
68
  */
69
69
  async function pullV4Command(options) {
@@ -193,7 +193,7 @@ async function pullV4Command(options) {
193
193
  }
194
194
  const paths = createProjectStructure(projectDir);
195
195
  if (remoteProject.skills && Object.keys(remoteProject.skills).length) {
196
- const { generateSkills } = await import("../../pull-v3/components/skill-generator.js");
196
+ const { generateSkills } = await import("../generators/skill-generator.js");
197
197
  await generateSkills(remoteProject.skills, paths.skillsDir);
198
198
  }
199
199
  s.start("Starting generating files...");
@@ -42,7 +42,7 @@ function cleanupTestEnvironment(testDir) {
42
42
  });
43
43
  }
44
44
  function getTestPath() {
45
- return `../__snapshots__/introspect/${expect.getState().currentTestName?.split(" > ").at(-1)}`;
45
+ return `../__tests__/__snapshots__/introspect/${expect.getState().currentTestName?.split(" > ").at(-1)}`;
46
46
  }
47
47
  function createProjectFixture() {
48
48
  return {
@@ -1,15 +1,16 @@
1
1
  import { collectTemplateVariableNames, createInMemoryProject, isPlainObject, toCamelCase } from "./utils.js";
2
- import { buildComponentRegistryFromParsing } from "../pull-v3/component-parser.js";
3
- import { generateAgentDefinition } from "./agent-generator.js";
4
- import { generateArtifactComponentDefinition } from "./artifact-component-generator.js";
5
- import { generateContextConfigDefinition } from "./context-config-generator.js";
6
- import { generateCredentialDefinition } from "./credential-generator.js";
7
- import { generateDataComponentDefinition } from "./data-component-generator.js";
2
+ import { buildComponentRegistryFromParsing } from "./component-parser.js";
3
+ import { generateAgentDefinition } from "./generators/agent-generator.js";
4
+ import { generateArtifactComponentDefinition } from "./generators/artifact-component-generator.js";
5
+ import { generateContextConfigDefinition } from "./generators/context-config-generator.js";
6
+ import { generateCredentialDefinition } from "./generators/credential-generator.js";
7
+ import { generateDataComponentDefinition } from "./generators/data-component-generator.js";
8
+ import { generateMcpToolDefinition } from "./generators/mcp-tool-generator.js";
9
+ import { generateProjectDefinition } from "./generators/project-generator.js";
10
+ import { generateStatusComponentDefinition } from "./generators/status-component-generator.js";
11
+ import { generateSubAgentDefinition } from "./generators/sub-agent-generator.js";
12
+ import { generateTriggerDefinition } from "./generators/trigger-generator.js";
8
13
  import { mergeGeneratedModule } from "./module-merge.js";
9
- import { generateProjectDefinition } from "./project-generator.js";
10
- import { generateStatusComponentDefinition } from "./status-component-generator.js";
11
- import { generateSubAgentDefinition } from "./sub-agent-generator.js";
12
- import { generateTriggerDefinition } from "./trigger-generator.js";
13
14
  import { dirname, join } from "node:path";
14
15
  import { Node, SyntaxKind } from "ts-morph";
15
16
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
@@ -61,6 +62,11 @@ function createGenerationTasks() {
61
62
  collect: collectDataComponentRecords,
62
63
  generate: generateDataComponentDefinition
63
64
  },
65
+ {
66
+ type: "tool",
67
+ collect: collectToolRecords,
68
+ generate: generateMcpToolDefinition
69
+ },
64
70
  {
65
71
  type: "context-config",
66
72
  collect: collectContextConfigRecords,
@@ -154,6 +160,16 @@ function collectContextConfigRecords(context) {
154
160
  }
155
161
  return [...contextConfigRecordsById.values()];
156
162
  }
163
+ function collectToolRecords(context) {
164
+ return Object.entries(context.project.tools ?? {}).map(([toolId, toolData]) => ({
165
+ id: toolId,
166
+ filePath: resolveRecordFilePath(context, "tools", toolId, join(context.paths.toolsDir, `${toolId}.ts`)),
167
+ payload: {
168
+ mcpToolId: toolId,
169
+ ...toolData
170
+ }
171
+ }));
172
+ }
157
173
  function collectContextConfigCredentialReferenceOverrides(context, contextConfigData) {
158
174
  const registry = context.existingComponentRegistry;
159
175
  if (!registry) return;
@@ -360,7 +376,6 @@ function isAgentComplete(agentData) {
360
376
  }
361
377
  function collectUnsupportedComponentCounts(project) {
362
378
  return {
363
- tools: getObjectKeys(project.tools).length,
364
379
  functionTools: getObjectKeys(project.functionTools).length,
365
380
  functions: getObjectKeys(project.functions).length,
366
381
  externalAgents: getObjectKeys(project.externalAgents).length
@@ -19,6 +19,7 @@ function mergeImports(existingFile, generatedFile) {
19
19
  const matchingImports = existingFile.getImportDeclarations().filter((existingImport) => existingImport.getModuleSpecifierValue() === moduleSpecifier);
20
20
  if (!matchingImports.length) {
21
21
  if (areGeneratedImportBindingsAlreadyPresent(existingFile, generatedImport)) continue;
22
+ if (hasGeneratedImportBindingConflicts(existingFile, generatedImport)) continue;
22
23
  existingFile.addImportDeclaration(generatedImport.getStructure());
23
24
  continue;
24
25
  }
@@ -29,20 +30,30 @@ function mergeImports(existingFile, generatedFile) {
29
30
  }
30
31
  if (!generatedImport.isTypeOnly() && targetImport.isTypeOnly()) targetImport.setIsTypeOnly(false);
31
32
  const generatedDefaultImport = generatedImport.getDefaultImport();
32
- if (generatedDefaultImport && !targetImport.getDefaultImport()) targetImport.setDefaultImport(generatedDefaultImport.getText());
33
+ if (generatedDefaultImport && !targetImport.getDefaultImport()) {
34
+ const defaultImportName = generatedDefaultImport.getText();
35
+ if (!hasTopLevelDeclarationWithName(existingFile, defaultImportName)) targetImport.setDefaultImport(defaultImportName);
36
+ }
33
37
  const generatedNamespaceImport = generatedImport.getNamespaceImport();
34
- if (generatedNamespaceImport && !targetImport.getNamespaceImport()) targetImport.setNamespaceImport(generatedNamespaceImport.getText());
38
+ if (generatedNamespaceImport && !targetImport.getNamespaceImport()) {
39
+ const namespaceImportName = generatedNamespaceImport.getText();
40
+ if (!hasTopLevelDeclarationWithName(existingFile, namespaceImportName)) targetImport.setNamespaceImport(namespaceImportName);
41
+ }
35
42
  for (const generatedNamedImport of generatedImport.getNamedImports()) {
36
43
  const generatedName = generatedNamedImport.getName();
37
44
  const generatedAlias = generatedNamedImport.getAliasNode()?.getText();
38
45
  const generatedIsTypeOnly = generatedNamedImport.isTypeOnly();
46
+ const generatedBindingName = generatedAlias ?? generatedName;
39
47
  if (!targetImport.getNamedImports().some((existingNamedImport) => {
40
48
  return existingNamedImport.getName() === generatedName && existingNamedImport.getAliasNode()?.getText() === generatedAlias && existingNamedImport.isTypeOnly() === generatedIsTypeOnly;
41
- })) targetImport.addNamedImport({
42
- name: generatedName,
43
- alias: generatedAlias,
44
- isTypeOnly: generatedIsTypeOnly
45
- });
49
+ })) {
50
+ if (hasTopLevelDeclarationWithName(existingFile, generatedBindingName)) continue;
51
+ targetImport.addNamedImport({
52
+ name: generatedName,
53
+ alias: generatedAlias,
54
+ isTypeOnly: generatedIsTypeOnly
55
+ });
56
+ }
46
57
  }
47
58
  }
48
59
  }
@@ -63,6 +74,11 @@ function areGeneratedImportBindingsAlreadyPresent(existingFile, generatedImport)
63
74
  const existingImports = existingFile.getImportDeclarations();
64
75
  return generatedBindings.every((binding) => existingImports.some((existingImport) => importHasBinding(existingImport, binding)));
65
76
  }
77
+ function hasGeneratedImportBindingConflicts(existingFile, generatedImport) {
78
+ const generatedBindings = getImportBindingNames(generatedImport);
79
+ if (!generatedBindings.length) return false;
80
+ return generatedBindings.some((binding) => hasTopLevelDeclarationWithName(existingFile, binding));
81
+ }
66
82
  function getImportBindingNames(importDeclaration) {
67
83
  const bindings = [];
68
84
  const defaultImport = importDeclaration.getDefaultImport();
@@ -79,6 +95,16 @@ function importHasBinding(importDeclaration, bindingName) {
79
95
  return (namedImport.getAliasNode()?.getText() ?? namedImport.getName()) === bindingName;
80
96
  });
81
97
  }
98
+ function hasTopLevelDeclarationWithName(existingFile, declarationName) {
99
+ if (existingFile.getVariableDeclaration(declarationName)) return true;
100
+ if (existingFile.getFunction(declarationName)) return true;
101
+ if (existingFile.getClass(declarationName)) return true;
102
+ if (existingFile.getInterface(declarationName)) return true;
103
+ if (existingFile.getTypeAlias(declarationName)) return true;
104
+ if (existingFile.getEnum(declarationName)) return true;
105
+ if (existingFile.getModule(declarationName)) return true;
106
+ return false;
107
+ }
82
108
  function upsertStatement(existingFile, generatedStatement) {
83
109
  if (Node.isVariableStatement(generatedStatement)) {
84
110
  upsertVariableStatement(existingFile, generatedStatement);