@inkeep/agents-cli 0.39.4 → 0.40.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 (80) hide show
  1. package/dist/_virtual/rolldown_runtime.js +7 -0
  2. package/dist/api.js +185 -0
  3. package/dist/commands/add.js +139 -0
  4. package/dist/commands/config.js +86 -0
  5. package/dist/commands/dev.js +259 -0
  6. package/dist/commands/init.js +360 -0
  7. package/dist/commands/list-agents.js +56 -0
  8. package/dist/commands/login.js +179 -0
  9. package/dist/commands/logout.js +56 -0
  10. package/dist/commands/profile.js +276 -0
  11. package/dist/{component-parser2.js → commands/pull-v3/component-parser.js} +16 -3
  12. package/dist/commands/pull-v3/component-updater.js +710 -0
  13. package/dist/commands/pull-v3/components/agent-generator.js +241 -0
  14. package/dist/commands/pull-v3/components/artifact-component-generator.js +127 -0
  15. package/dist/commands/pull-v3/components/context-config-generator.js +190 -0
  16. package/dist/commands/pull-v3/components/credential-generator.js +89 -0
  17. package/dist/commands/pull-v3/components/data-component-generator.js +102 -0
  18. package/dist/commands/pull-v3/components/environment-generator.js +170 -0
  19. package/dist/commands/pull-v3/components/external-agent-generator.js +75 -0
  20. package/dist/commands/pull-v3/components/function-tool-generator.js +94 -0
  21. package/dist/commands/pull-v3/components/mcp-tool-generator.js +86 -0
  22. package/dist/commands/pull-v3/components/project-generator.js +145 -0
  23. package/dist/commands/pull-v3/components/status-component-generator.js +92 -0
  24. package/dist/commands/pull-v3/components/sub-agent-generator.js +285 -0
  25. package/dist/commands/pull-v3/index.js +510 -0
  26. package/dist/commands/pull-v3/introspect-generator.js +278 -0
  27. package/dist/commands/pull-v3/llm-content-merger.js +192 -0
  28. package/dist/{new-component-generator.js → commands/pull-v3/new-component-generator.js} +14 -3
  29. package/dist/commands/pull-v3/project-comparator.js +914 -0
  30. package/dist/{project-index-generator.js → commands/pull-v3/project-index-generator.js} +1 -2
  31. package/dist/{project-validator.js → commands/pull-v3/project-validator.js} +4 -4
  32. package/dist/commands/pull-v3/targeted-typescript-placeholders.js +173 -0
  33. package/dist/commands/pull-v3/utils/component-registry.js +369 -0
  34. package/dist/commands/pull-v3/utils/component-tracker.js +165 -0
  35. package/dist/commands/pull-v3/utils/generator-utils.js +146 -0
  36. package/dist/commands/pull-v3/utils/model-provider-detector.js +44 -0
  37. package/dist/commands/push.js +326 -0
  38. package/dist/commands/status.js +89 -0
  39. package/dist/commands/update.js +97 -0
  40. package/dist/commands/whoami.js +38 -0
  41. package/dist/config.js +0 -1
  42. package/dist/env.js +30 -0
  43. package/dist/exports.js +3 -0
  44. package/dist/index.js +28 -196514
  45. package/dist/instrumentation.js +47 -0
  46. package/dist/types/agent.js +1 -0
  47. package/dist/types/tsx.d.d.ts +1 -0
  48. package/dist/utils/background-version-check.js +19 -0
  49. package/dist/utils/ci-environment.js +87 -0
  50. package/dist/utils/cli-pipeline.js +158 -0
  51. package/dist/utils/config.js +290 -0
  52. package/dist/utils/credentials.js +132 -0
  53. package/dist/utils/environment-loader.js +28 -0
  54. package/dist/utils/file-finder.js +62 -0
  55. package/dist/utils/json-comparator.js +185 -0
  56. package/dist/utils/json-comparison.js +232 -0
  57. package/dist/utils/mcp-runner.js +120 -0
  58. package/dist/utils/model-config.js +182 -0
  59. package/dist/utils/package-manager.js +58 -0
  60. package/dist/utils/profile-config.js +85 -0
  61. package/dist/utils/profiles/index.js +4 -0
  62. package/dist/utils/profiles/profile-manager.js +219 -0
  63. package/dist/utils/profiles/types.js +62 -0
  64. package/dist/utils/project-directory.js +33 -0
  65. package/dist/utils/project-loader.js +29 -0
  66. package/dist/utils/schema-introspection.js +44 -0
  67. package/dist/utils/templates.js +198 -0
  68. package/dist/utils/tsx-loader.js +27 -0
  69. package/dist/utils/url.js +26 -0
  70. package/dist/utils/version-check.js +79 -0
  71. package/package.json +4 -19
  72. package/dist/component-parser.js +0 -4
  73. package/dist/component-updater.js +0 -4
  74. package/dist/config2.js +0 -4
  75. package/dist/credential-stores.js +0 -4
  76. package/dist/environment-generator.js +0 -4
  77. package/dist/nodefs.js +0 -27
  78. package/dist/opfs-ahp.js +0 -368
  79. package/dist/project-loader.js +0 -4
  80. package/dist/tsx-loader.js +0 -4
@@ -0,0 +1,241 @@
1
+ import { compareJsonObjects } from "../../../utils/json-comparator.js";
2
+ import { DEFAULT_STYLE, formatPromptWithContext, formatString, generateFileContent, generateImport, hasTemplateVariables, removeTrailingComma, toCamelCase } from "../utils/generator-utils.js";
3
+
4
+ //#region src/commands/pull-v3/components/agent-generator.ts
5
+ /**
6
+ * Agent Generator - Generate top-level agent definitions
7
+ *
8
+ * Generates top-level agents using the agent() builder function from @inkeep/agents-sdk
9
+ * Top-level agents are the main entry points that handle statusUpdates with statusComponents
10
+ */
11
+ /**
12
+ * Format statusUpdates configuration with statusComponents references
13
+ */
14
+ function formatStatusUpdates(statusUpdatesConfig, style, indentLevel, registry, contextConfigData, agentId) {
15
+ if (!statusUpdatesConfig) return "";
16
+ const { quotes, indentation } = style;
17
+ const q = quotes === "single" ? "'" : "\"";
18
+ const indent = indentation.repeat(indentLevel);
19
+ const lines = [];
20
+ lines.push(`${indent}statusUpdates: {`);
21
+ if (statusUpdatesConfig.numEvents !== void 0) lines.push(`${indent}${indentation}numEvents: ${statusUpdatesConfig.numEvents},`);
22
+ if (statusUpdatesConfig.timeInSeconds !== void 0) lines.push(`${indent}${indentation}timeInSeconds: ${statusUpdatesConfig.timeInSeconds},`);
23
+ if (statusUpdatesConfig.statusComponents && Array.isArray(statusUpdatesConfig.statusComponents) && statusUpdatesConfig.statusComponents.length > 0) {
24
+ const statusComponentIds = statusUpdatesConfig.statusComponents.map((comp) => {
25
+ if (typeof comp === "string") return comp;
26
+ if (typeof comp === "object" && comp) return comp.id || comp.type || comp.name;
27
+ return null;
28
+ }).filter(Boolean);
29
+ if (statusComponentIds.length > 0) {
30
+ lines.push(`${indent}${indentation}statusComponents: [`);
31
+ for (const statusCompId of statusComponentIds) {
32
+ const statusCompVar = registry?.getVariableName(statusCompId, "statusComponents");
33
+ lines.push(`${indent}${indentation}${indentation}${statusCompVar || "undefined"}.config,`);
34
+ }
35
+ lines.push(`${indent}${indentation}],`);
36
+ }
37
+ }
38
+ if (statusUpdatesConfig.prompt) if (hasTemplateVariables(statusUpdatesConfig.prompt) && contextConfigData && agentId && registry) {
39
+ const contextConfigId = contextConfigData.id;
40
+ const contextVarName = registry.getVariableName(contextConfigId, "contextConfigs");
41
+ if (!contextVarName) throw new Error(`Failed to resolve context config variable name for: ${contextConfigId}`);
42
+ lines.push(`${indent}${indentation}prompt: ${formatPromptWithContext(statusUpdatesConfig.prompt, contextVarName, "headersSchema", contextConfigData, q, true)},`);
43
+ } else lines.push(`${indent}${indentation}prompt: ${formatString(statusUpdatesConfig.prompt, q, true)},`);
44
+ removeTrailingComma(lines);
45
+ lines.push(`${indent}},`);
46
+ return lines.join("\n");
47
+ }
48
+ /**
49
+ * Format stopWhen configuration for agents (only supports transferCountIs)
50
+ */
51
+ function formatStopWhen(stopWhenConfig, style, indentLevel) {
52
+ if (!stopWhenConfig || !stopWhenConfig.transferCountIs) return "";
53
+ const { indentation } = style;
54
+ const indent = indentation.repeat(indentLevel);
55
+ return `${indent}stopWhen: {\n${indent}${indentation}transferCountIs: ${stopWhenConfig.transferCountIs} // Max transfers in one conversation\n${indent}},`;
56
+ }
57
+ /**
58
+ * Check if agent models are different from project models
59
+ */
60
+ function hasDistinctModels(agentModels, projectModels) {
61
+ if (!agentModels) return false;
62
+ if (!projectModels) return !!agentModels;
63
+ for (const type of [
64
+ "base",
65
+ "structuredOutput",
66
+ "summarizer"
67
+ ]) {
68
+ const agentModel = agentModels[type]?.model;
69
+ const projectModel = projectModels[type]?.model;
70
+ if (agentModel !== projectModel) return true;
71
+ if (agentModel && projectModel) {
72
+ const agentOptions = agentModels[type]?.providerOptions;
73
+ const projectOptions = projectModels[type]?.providerOptions;
74
+ if (agentOptions !== projectOptions) {
75
+ if (!agentOptions && !projectOptions) continue;
76
+ if (!agentOptions || !projectOptions) return true;
77
+ if (!compareJsonObjects(agentOptions, projectOptions, {
78
+ ignoreArrayOrder: true,
79
+ showDetails: false
80
+ }).isEqual) return true;
81
+ }
82
+ }
83
+ }
84
+ return false;
85
+ }
86
+ /**
87
+ * Generate Agent Definition using agent() builder function
88
+ */
89
+ function generateAgentDefinition(agentId, agentData, style = DEFAULT_STYLE, registry, contextConfigData, projectModels) {
90
+ if (!agentId || typeof agentId !== "string") throw new Error("agentId is required and must be a string");
91
+ if (!agentData || typeof agentData !== "object") throw new Error(`agentData is required for agent '${agentId}'`);
92
+ const missingFields = [
93
+ "name",
94
+ "defaultSubAgentId",
95
+ "subAgents"
96
+ ].filter((field) => !agentData[field] || agentData[field] === null || agentData[field] === void 0);
97
+ if (missingFields.length > 0) throw new Error(`Missing required fields for agent '${agentId}': ${missingFields.join(", ")}`);
98
+ const { quotes, semicolons, indentation } = style;
99
+ const q = quotes === "single" ? "'" : "\"";
100
+ const semi = semicolons ? ";" : "";
101
+ let agentVarName = toCamelCase(agentId);
102
+ if (registry) {
103
+ const registryVarName = registry.getVariableName(agentId, "agents");
104
+ if (registryVarName) agentVarName = registryVarName;
105
+ }
106
+ const lines = [];
107
+ lines.push(`export const ${agentVarName} = agent({`);
108
+ lines.push(`${indentation}id: ${formatString(agentId, q)},`);
109
+ lines.push(`${indentation}name: ${formatString(agentData.name, q)},`);
110
+ if (agentData.description !== void 0 && agentData.description !== null) lines.push(`${indentation}description: ${formatString(agentData.description, q, true)},`);
111
+ if (agentData.prompt !== void 0 && agentData.prompt !== null) if (hasTemplateVariables(agentData.prompt) && contextConfigData && registry) {
112
+ const contextConfigId = contextConfigData.id;
113
+ const contextVarName = registry.getVariableName(contextConfigId, "contextConfigs");
114
+ if (!contextVarName) throw new Error(`Failed to resolve context config variable name for: ${contextConfigId}`);
115
+ lines.push(`${indentation}prompt: ${formatPromptWithContext(agentData.prompt, contextVarName, "headersSchema", contextConfigData, q, true)},`);
116
+ } else lines.push(`${indentation}prompt: ${formatString(agentData.prompt, q, true)},`);
117
+ if (agentData.models && hasDistinctModels(agentData.models, projectModels)) {
118
+ lines.push(`${indentation}models: {`);
119
+ if (agentData.models.base?.model) {
120
+ lines.push(`${indentation}${indentation}base: {`);
121
+ lines.push(`${indentation}${indentation}${indentation}model: ${formatString(agentData.models.base.model, q)}`);
122
+ if (agentData.models.base.providerOptions) {
123
+ lines.push(`${indentation}${indentation}${indentation},`);
124
+ lines.push(`${indentation}${indentation}${indentation}providerOptions: ${JSON.stringify(agentData.models.base.providerOptions)}`);
125
+ }
126
+ lines.push(`${indentation}${indentation}},`);
127
+ }
128
+ if (agentData.models.structuredOutput?.model) {
129
+ lines.push(`${indentation}${indentation}structuredOutput: {`);
130
+ lines.push(`${indentation}${indentation}${indentation}model: ${formatString(agentData.models.structuredOutput.model, q)}`);
131
+ if (agentData.models.structuredOutput.providerOptions) {
132
+ lines.push(`${indentation}${indentation}${indentation},`);
133
+ lines.push(`${indentation}${indentation}${indentation}providerOptions: ${JSON.stringify(agentData.models.structuredOutput.providerOptions)}`);
134
+ }
135
+ lines.push(`${indentation}${indentation}},`);
136
+ }
137
+ if (agentData.models.summarizer?.model) {
138
+ lines.push(`${indentation}${indentation}summarizer: {`);
139
+ lines.push(`${indentation}${indentation}${indentation}model: ${formatString(agentData.models.summarizer.model, q)}`);
140
+ if (agentData.models.summarizer.providerOptions) {
141
+ lines.push(`${indentation}${indentation}${indentation},`);
142
+ lines.push(`${indentation}${indentation}${indentation}providerOptions: ${JSON.stringify(agentData.models.summarizer.providerOptions)}`);
143
+ }
144
+ lines.push(`${indentation}${indentation}},`);
145
+ }
146
+ removeTrailingComma(lines);
147
+ lines.push(`${indentation}},`);
148
+ }
149
+ if (agentData.defaultSubAgentId) {
150
+ if (!registry) throw new Error("Registry is required for defaultSubAgent generation");
151
+ const defaultSubAgentVar = registry.getVariableName(agentData.defaultSubAgentId, "subAgents");
152
+ if (!defaultSubAgentVar) throw new Error(`Failed to resolve variable name for default sub-agent: ${agentData.defaultSubAgentId}`);
153
+ lines.push(`${indentation}defaultSubAgent: ${defaultSubAgentVar},`);
154
+ }
155
+ if (agentData.subAgents && typeof agentData.subAgents === "object" && Object.keys(agentData.subAgents).length > 0) {
156
+ if (!registry) throw new Error("Registry is required for subAgents generation");
157
+ const subAgentIds = Object.keys(agentData.subAgents);
158
+ const subAgentsArray = registry.formatReferencesForCode(subAgentIds, "subAgents", style, 2);
159
+ if (!subAgentsArray) throw new Error(`Failed to resolve variable names for sub-agents: ${subAgentIds.join(", ")}`);
160
+ lines.push(`${indentation}subAgents: () => ${subAgentsArray},`);
161
+ }
162
+ if (agentData.contextConfig && registry && agentData.contextConfig.id) {
163
+ const contextConfigVar = registry.getVariableName(agentData.contextConfig.id, "contextConfigs");
164
+ if (contextConfigVar) lines.push(`${indentation}contextConfig: ${contextConfigVar},`);
165
+ else lines.push(`${indentation}contextConfig: undefined,`);
166
+ }
167
+ if (agentData.credentials && Array.isArray(agentData.credentials) && agentData.credentials.length > 0) {
168
+ if (!registry) throw new Error("Registry is required for credentials generation");
169
+ const credentialsArray = `[${agentData.credentials.map((cred) => {
170
+ const credVarName = registry.getVariableName(cred.id, "credentials");
171
+ if (!credVarName) throw new Error(`Failed to resolve variable name for credential: ${cred.id}`);
172
+ return credVarName;
173
+ }).join(", ")}]`;
174
+ lines.push(`${indentation}credentials: () => ${credentialsArray},`);
175
+ }
176
+ if (agentData.stopWhen) {
177
+ const stopWhenFormatted = formatStopWhen(agentData.stopWhen, style, 1);
178
+ if (stopWhenFormatted) lines.push(stopWhenFormatted);
179
+ }
180
+ if (agentData.statusUpdates) {
181
+ const statusUpdatesFormatted = formatStatusUpdates(agentData.statusUpdates, style, 1, registry, contextConfigData, agentId);
182
+ if (statusUpdatesFormatted) lines.push(statusUpdatesFormatted);
183
+ }
184
+ removeTrailingComma(lines);
185
+ lines.push(`})${semi}`);
186
+ return lines.join("\n");
187
+ }
188
+ /**
189
+ * Generate imports needed for an agent file
190
+ */
191
+ function generateAgentImports(agentId, agentData, style = DEFAULT_STYLE, registry, contextConfigData, actualFilePath) {
192
+ const imports = [];
193
+ imports.push(generateImport(["agent"], "@inkeep/agents-sdk", style));
194
+ if (registry) {
195
+ const currentFilePath = actualFilePath || `agents/${agentId}.ts`;
196
+ const referencedComponents = [];
197
+ if (agentData.subAgents && typeof agentData.subAgents === "object") {
198
+ const subAgentIds = Object.keys(agentData.subAgents);
199
+ referencedComponents.push(...subAgentIds.map((id) => ({
200
+ id,
201
+ type: "subAgents"
202
+ })));
203
+ }
204
+ if (agentData.statusUpdates && agentData.statusUpdates.statusComponents && Array.isArray(agentData.statusUpdates.statusComponents)) {
205
+ for (const comp of agentData.statusUpdates.statusComponents) if (typeof comp === "string") referencedComponents.push({
206
+ id: comp,
207
+ type: "statusComponents"
208
+ });
209
+ else if (typeof comp === "object" && comp) {
210
+ const statusId = comp.id || comp.type || comp.name;
211
+ if (statusId) referencedComponents.push({
212
+ id: statusId,
213
+ type: "statusComponents"
214
+ });
215
+ }
216
+ }
217
+ if (agentData.contextConfig) {
218
+ const contextConfigId = agentData.contextConfig.id;
219
+ referencedComponents.push({
220
+ id: contextConfigId,
221
+ type: "contextConfigs"
222
+ });
223
+ }
224
+ if (agentData.defaultSubAgentId) referencedComponents.push({
225
+ id: agentData.defaultSubAgentId,
226
+ type: "subAgents"
227
+ });
228
+ const componentImports = registry.getImportsForFile(currentFilePath, referencedComponents);
229
+ imports.push(...componentImports);
230
+ }
231
+ return imports;
232
+ }
233
+ /**
234
+ * Generate complete agent file (imports + definition)
235
+ */
236
+ 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)]);
238
+ }
239
+
240
+ //#endregion
241
+ export { generateAgentDefinition, generateAgentFile, generateAgentImports };
@@ -0,0 +1,127 @@
1
+ import { jsonSchemaToZod } from "json-schema-to-zod";
2
+
3
+ //#region src/commands/pull-v3/components/artifact-component-generator.ts
4
+ /**
5
+ * Artifact Component Generator - Generate artifact component definitions
6
+ *
7
+ * Generates artifact components using the artifactComponent() builder function from @inkeep/agents-sdk
8
+ * Handles isPreview flag with preview() function wrapper from @inkeep/agents-core
9
+ */
10
+ const DEFAULT_STYLE = {
11
+ quotes: "single",
12
+ semicolons: true,
13
+ indentation: " "
14
+ };
15
+ /**
16
+ * Utility functions
17
+ */
18
+ function toCamelCase(str) {
19
+ return str.toLowerCase().replace(/[-_](.)/g, (_, char) => char.toUpperCase()).replace(/[^a-zA-Z0-9]/g, "").replace(/^[0-9]/, "_$&");
20
+ }
21
+ function formatString(str, quote = "'", multiline = false) {
22
+ if (!str) return `${quote}${quote}`;
23
+ if (multiline && (str.includes("\n") || str.length > 80)) return `\`${str.replace(/`/g, "\\`")}\``;
24
+ return `${quote}${str.replace(new RegExp(quote, "g"), "\\" + quote)}${quote}`;
25
+ }
26
+ /**
27
+ * Check if schema has any properties with inPreview: true
28
+ */
29
+ function hasInPreviewFields(schema) {
30
+ if (!schema || typeof schema !== "object" || schema.type !== "object" || !schema.properties) return false;
31
+ for (const prop of Object.values(schema.properties)) if (prop.inPreview === true) return true;
32
+ return false;
33
+ }
34
+ /**
35
+ * Format artifact schema with preview() wrappers based on inPreview: true in properties
36
+ */
37
+ function formatArtifactSchema(schema, style) {
38
+ if (!schema || typeof schema !== "object") return "z.any()";
39
+ if (schema.type === "object" && schema.properties) {
40
+ const { indentation } = style;
41
+ const lines = ["z.object({"];
42
+ for (const [key, prop] of Object.entries(schema.properties)) {
43
+ const propCopy = { ...prop };
44
+ delete propCopy.inPreview;
45
+ const baseZodType = convertJsonSchemaToZod(propCopy);
46
+ const finalZodType = prop.inPreview === true ? `preview(${baseZodType})` : baseZodType;
47
+ lines.push(`${indentation}${key}: ${finalZodType},`);
48
+ }
49
+ lines.push("})");
50
+ if (schema.description) return lines.join("\n") + `.describe(\`${schema.description}\`)`;
51
+ return lines.join("\n");
52
+ }
53
+ return convertJsonSchemaToZod(schema);
54
+ }
55
+ /**
56
+ * Convert JSON Schema to Zod schema using existing utility
57
+ */
58
+ function convertJsonSchemaToZod(schema) {
59
+ if (!schema || typeof schema !== "object") return "z.any()";
60
+ try {
61
+ return jsonSchemaToZod(schema);
62
+ } catch (error) {
63
+ console.warn("Failed to convert JSON schema to Zod:", error);
64
+ return "z.any()";
65
+ }
66
+ }
67
+ /**
68
+ * Generate Artifact Component Definition using artifactComponent() builder function
69
+ */
70
+ function generateArtifactComponentDefinition(componentId, componentData, style = DEFAULT_STYLE) {
71
+ if (!componentId || typeof componentId !== "string") throw new Error("componentId is required and must be a string");
72
+ if (!componentData || typeof componentData !== "object") throw new Error(`componentData is required for artifact component '${componentId}'`);
73
+ const missingFields = ["name"].filter((field) => !componentData[field] || componentData[field] === null || componentData[field] === void 0);
74
+ if (!componentData.props) missingFields.push("props");
75
+ if (missingFields.length > 0) throw new Error(`Missing required fields for artifact component '${componentId}': ${missingFields.join(", ")}`);
76
+ const { quotes, semicolons, indentation } = style;
77
+ const q = quotes === "single" ? "'" : "\"";
78
+ const semi = semicolons ? ";" : "";
79
+ const componentVarName = toCamelCase(componentId);
80
+ const lines = [];
81
+ lines.push(`export const ${componentVarName} = artifactComponent({`);
82
+ lines.push(`${indentation}id: ${formatString(componentId, q)},`);
83
+ lines.push(`${indentation}name: ${formatString(componentData.name, q)},`);
84
+ lines.push(`${indentation}description: ${formatString(componentData.description, q, true)},`);
85
+ const schema = componentData.props || componentData.schema;
86
+ if (schema) {
87
+ const zodSchema = formatArtifactSchema(schema, style);
88
+ if (zodSchema.includes("\n")) {
89
+ const schemaLines = zodSchema.split("\n");
90
+ lines.push(`${indentation}props: ${schemaLines[0]}`);
91
+ schemaLines.slice(1, -1).forEach((line) => {
92
+ lines[lines.length - 1] += "\n" + indentation + line;
93
+ });
94
+ lines[lines.length - 1] += "\n" + indentation + schemaLines[schemaLines.length - 1] + ",";
95
+ } else lines.push(`${indentation}props: ${zodSchema},`);
96
+ }
97
+ if (componentData.template) lines.push(`${indentation}template: ${formatString(componentData.template, q, true)},`);
98
+ if (componentData.contentType) lines.push(`${indentation}contentType: ${formatString(componentData.contentType, q)},`);
99
+ if (lines.length > 0 && lines[lines.length - 1].endsWith(",")) lines[lines.length - 1] = lines[lines.length - 1].slice(0, -1);
100
+ lines.push(`})${semi}`);
101
+ return lines.join("\n");
102
+ }
103
+ /**
104
+ * Generate imports needed for an artifact component file
105
+ */
106
+ function generateArtifactComponentImports(componentId, componentData, style = DEFAULT_STYLE) {
107
+ const { quotes, semicolons } = style;
108
+ const q = quotes === "single" ? "'" : "\"";
109
+ const semi = semicolons ? ";" : "";
110
+ const imports = [];
111
+ const schema = componentData.props || componentData.schema;
112
+ if (hasInPreviewFields(schema)) imports.push(`import { preview } from ${q}@inkeep/agents-core${q}${semi}`);
113
+ imports.push(`import { artifactComponent } from ${q}@inkeep/agents-sdk${q}${semi}`);
114
+ if (schema) imports.push(`import { z } from ${q}zod${q}${semi}`);
115
+ return imports;
116
+ }
117
+ /**
118
+ * Generate complete artifact component file (imports + definition)
119
+ */
120
+ function generateArtifactComponentFile(componentId, componentData, style = DEFAULT_STYLE) {
121
+ const imports = generateArtifactComponentImports(componentId, componentData, style);
122
+ const definition = generateArtifactComponentDefinition(componentId, componentData, style);
123
+ return imports.join("\n") + "\n\n" + definition + "\n";
124
+ }
125
+
126
+ //#endregion
127
+ export { generateArtifactComponentDefinition, generateArtifactComponentFile, generateArtifactComponentImports };
@@ -0,0 +1,190 @@
1
+ import { DEFAULT_STYLE, formatString, generateFileContent, generateImport, hasTemplateVariables, removeTrailingComma, toCamelCase } from "../utils/generator-utils.js";
2
+ import { jsonSchemaToZod } from "json-schema-to-zod";
3
+
4
+ //#region src/commands/pull-v3/components/context-config-generator.ts
5
+ /**
6
+ * Context Config Generator - Generate contextConfig definitions
7
+ *
8
+ * Generates contextConfig using contextConfig(), headers(), and fetchDefinition()
9
+ * builder functions from @inkeep/agents-core
10
+ */
11
+ /**
12
+ * Process template variables in fetchConfig objects
13
+ */
14
+ function processFetchConfigTemplates(fetchConfig, headersVarName) {
15
+ const processValue = (value) => {
16
+ if (typeof value === "string") {
17
+ if (hasTemplateVariables(value)) return `\`${value.replace(/\{\{headers\.([^}]+)\}\}/g, `\${${headersVarName}.toTemplate("$1")}`).replace(/`/g, "\\`")}\``;
18
+ if (value.includes("\n") || value.length > 80) return `\`${value.replace(/`/g, "\\`")}\``;
19
+ return `'${value.replace(/'/g, "\\'")}'`;
20
+ }
21
+ if (typeof value === "object" && value !== null) return processObject(value);
22
+ return JSON.stringify(value);
23
+ };
24
+ const processObject = (obj) => {
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]) => {
27
+ return `${/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : `'${key}'`}: ${processValue(val)}`;
28
+ }).join(",\n ")}\n }`;
29
+ };
30
+ return processObject(fetchConfig);
31
+ }
32
+ /**
33
+ * Generate Headers Definition using headers() builder function
34
+ */
35
+ function generateHeadersDefinition(headersId, headersData, style = DEFAULT_STYLE) {
36
+ const { quotes, semicolons, indentation } = style;
37
+ const semi = semicolons ? ";" : "";
38
+ const headersVarName = toCamelCase(headersId);
39
+ const lines = [];
40
+ lines.push(`const ${headersVarName} = headers({`);
41
+ if (headersData.schema) {
42
+ const zodSchema = jsonSchemaToZod(headersData.schema, { module: "none" });
43
+ lines.push(`${indentation}schema: ${zodSchema},`);
44
+ }
45
+ removeTrailingComma(lines);
46
+ lines.push(`})${semi}`);
47
+ return lines.join("\n");
48
+ }
49
+ /**
50
+ * Generate Fetch Definition using fetchDefinition() builder function
51
+ */
52
+ function generateFetchDefinitionDefinition(fetchId, fetchData, style = DEFAULT_STYLE, headersVarName, registry) {
53
+ const { quotes, semicolons, indentation } = style;
54
+ const q = quotes === "single" ? "'" : "\"";
55
+ const semi = semicolons ? ";" : "";
56
+ const fetchVarName = toCamelCase(fetchId);
57
+ const lines = [];
58
+ lines.push(`const ${fetchVarName} = fetchDefinition({`);
59
+ lines.push(`${indentation}id: ${formatString(fetchData.id || fetchId, q)},`);
60
+ if (fetchData.name) lines.push(`${indentation}name: ${formatString(fetchData.name, q)},`);
61
+ if (fetchData.trigger) lines.push(`${indentation}trigger: ${formatString(fetchData.trigger, q)},`);
62
+ if (fetchData.fetchConfig) {
63
+ const processedFetchConfig = processFetchConfigTemplates(fetchData.fetchConfig, headersVarName || "headers");
64
+ lines.push(`${indentation}fetchConfig: ${processedFetchConfig},`);
65
+ }
66
+ if (fetchData.responseSchema) {
67
+ const zodSchema = jsonSchemaToZod(fetchData.responseSchema, { module: "none" });
68
+ lines.push(`${indentation}responseSchema: ${zodSchema},`);
69
+ }
70
+ if (fetchData.defaultValue) if (typeof fetchData.defaultValue === "string") {
71
+ const isMultiline = fetchData.defaultValue.includes("\n") || fetchData.defaultValue.length > 80;
72
+ lines.push(`${indentation}defaultValue: ${formatString(fetchData.defaultValue, q, isMultiline)},`);
73
+ } else lines.push(`${indentation}defaultValue: ${JSON.stringify(fetchData.defaultValue)},`);
74
+ if (fetchData.credentialReferenceId && registry) {
75
+ const validKey = registry.getVariableName(fetchData.credentialReferenceId, "credentials");
76
+ lines.push(`${indentation}credentialReference: ${validKey},`);
77
+ }
78
+ removeTrailingComma(lines);
79
+ lines.push(`})${semi}`);
80
+ return lines.join("\n");
81
+ }
82
+ /**
83
+ * Generate Context Config Definition using contextConfig() builder function
84
+ */
85
+ function generateContextConfigDefinition(contextId, contextData, style = DEFAULT_STYLE, registry, agentId, headersVarName) {
86
+ if (!contextId || typeof contextId !== "string") throw new Error("contextId is required and must be a string");
87
+ if (!contextData || typeof contextData !== "object") throw new Error(`contextData is required for context config '${contextId}'`);
88
+ const { quotes, semicolons, indentation } = style;
89
+ const q = quotes === "single" ? "'" : "\"";
90
+ const semi = semicolons ? ";" : "";
91
+ const contextVarName = (() => {
92
+ if (!registry) throw new Error("Registry is required for context config variable name generation");
93
+ const varName = registry.getVariableName(contextId, "contextConfigs");
94
+ if (!varName) throw new Error(`Failed to resolve variable name for context config: ${contextId}`);
95
+ return varName;
96
+ })();
97
+ const lines = [];
98
+ lines.push(`const ${contextVarName} = contextConfig({`);
99
+ if (contextData.id) lines.push(`${indentation}id: ${formatString(contextData.id, q)},`);
100
+ if (headersVarName) lines.push(`${indentation}headers: ${headersVarName},`);
101
+ else if (contextData.headers) lines.push(`${indentation}headers: ${contextData.headers},`);
102
+ if (contextData.contextVariables) {
103
+ const contextVarLines = [`${indentation}contextVariables: {`];
104
+ for (const [varName, varData] of Object.entries(contextData.contextVariables)) if (typeof varData === "string") contextVarLines.push(`${indentation} ${varName}: ${varData},`);
105
+ else if (varData && typeof varData === "object" && (varData.fetchConfig || varData.responseSchema)) contextVarLines.push(`${indentation} ${varName},`);
106
+ if (contextVarLines[contextVarLines.length - 1].endsWith(",")) contextVarLines[contextVarLines.length - 1] = contextVarLines[contextVarLines.length - 1].slice(0, -1);
107
+ contextVarLines.push(`${indentation}},`);
108
+ lines.push(...contextVarLines);
109
+ }
110
+ removeTrailingComma(lines);
111
+ lines.push(`})${semi}`);
112
+ return lines.join("\n");
113
+ }
114
+ /**
115
+ * Generate imports needed for a context config file
116
+ */
117
+ function generateContextConfigImports(contextId, contextData, style = DEFAULT_STYLE, registry) {
118
+ const imports = [];
119
+ const coreImports = [];
120
+ if (contextData.headers || hasHeadersInData(contextData)) coreImports.push("headers");
121
+ if (contextData.contextVariables && hasFetchDefinitionsInData(contextData)) coreImports.push("fetchDefinition");
122
+ coreImports.push("contextConfig");
123
+ if (coreImports.length > 0) imports.push(generateImport(coreImports, "@inkeep/agents-core", style));
124
+ if (hasSchemas(contextData)) imports.push(generateImport(["z"], "zod", style));
125
+ if (registry && contextData.contextVariables) {
126
+ const credentialRefs = [];
127
+ for (const [varName, varData] of Object.entries(contextData.contextVariables)) if (varData && typeof varData === "object" && varData.credentialReferenceId) credentialRefs.push({
128
+ id: varData.credentialReferenceId,
129
+ type: "credentials"
130
+ });
131
+ if (credentialRefs.length > 0) {
132
+ const contextComponent = registry.get(contextId, "contextConfigs");
133
+ if (contextComponent) {
134
+ const credentialImports = registry.getImportsForFile(contextComponent.filePath, credentialRefs);
135
+ imports.push(...credentialImports);
136
+ }
137
+ }
138
+ }
139
+ return imports;
140
+ }
141
+ /**
142
+ * Helper functions to detect what imports are needed
143
+ */
144
+ function hasHeadersInData(contextData) {
145
+ return !!contextData.headers || JSON.stringify(contextData).includes("headers");
146
+ }
147
+ function hasFetchDefinitionsInData(contextData) {
148
+ return JSON.stringify(contextData).includes("fetchDefinition") || contextData.contextVariables && Object.values(contextData.contextVariables).some((v) => v && typeof v === "object" && (v.fetchConfig || v.responseSchema));
149
+ }
150
+ function hasSchemas(contextData) {
151
+ const dataStr = JSON.stringify(contextData).toLowerCase();
152
+ return dataStr.includes("schema") || dataStr.includes("responseschema");
153
+ }
154
+ /**
155
+ * Generate complete context config file (imports + all definitions)
156
+ */
157
+ function generateContextConfigFile(contextId, contextData, style = DEFAULT_STYLE, registry, agentId) {
158
+ const imports = generateContextConfigImports(contextId, contextData, style, registry);
159
+ const definitions = [];
160
+ let headersVarName;
161
+ if (contextData.headersSchema) {
162
+ if (typeof contextData.headers === "string") headersVarName = contextData.headers;
163
+ else headersVarName = `${toCamelCase(contextId)}Headers`;
164
+ const headersDefinition = generateHeadersDefinition(headersVarName || "headers", { schema: contextData.headersSchema }, style);
165
+ definitions.push(headersDefinition);
166
+ }
167
+ if (contextData.contextVariables) {
168
+ for (const [varName, varData] of Object.entries(contextData.contextVariables)) if (varData && typeof varData === "object" && (varData.fetchConfig || varData.responseSchema)) {
169
+ const fetchDefinition = generateFetchDefinitionDefinition(varName, varData, style, headersVarName, registry);
170
+ definitions.push(fetchDefinition);
171
+ }
172
+ }
173
+ const contextDefinition = generateContextConfigDefinition(contextId, contextData, style, registry, agentId, headersVarName);
174
+ definitions.push(contextDefinition);
175
+ const exports = [(() => {
176
+ if (!registry) throw new Error("Registry is required for context config variable name generation");
177
+ const varName = registry.getVariableName(contextId, "contextConfigs");
178
+ if (!varName) throw new Error(`Failed to resolve variable name for context config: ${contextId}`);
179
+ return varName;
180
+ })()];
181
+ if (headersVarName) exports.push(headersVarName);
182
+ if (contextData.contextVariables) {
183
+ for (const [varName, varData] of Object.entries(contextData.contextVariables)) if (varData && typeof varData === "object" && (varData.fetchConfig || varData.responseSchema)) exports.push(varName);
184
+ }
185
+ definitions.push(`export { ${exports.join(", ")} };`);
186
+ return generateFileContent(imports, definitions);
187
+ }
188
+
189
+ //#endregion
190
+ export { generateContextConfigDefinition, generateContextConfigFile, generateContextConfigImports, generateFetchDefinitionDefinition, generateHeadersDefinition };
@@ -0,0 +1,89 @@
1
+ //#region src/commands/pull-v3/components/credential-generator.ts
2
+ const DEFAULT_STYLE = {
3
+ quotes: "single",
4
+ semicolons: true,
5
+ indentation: " "
6
+ };
7
+ /**
8
+ * Utility functions
9
+ */
10
+ function toCamelCase(str) {
11
+ return str.toLowerCase().replace(/[-_](.)/g, (_, char) => char.toUpperCase()).replace(/[^a-zA-Z0-9]/g, "").replace(/^[0-9]/, "_$&");
12
+ }
13
+ function formatString(str, quote = "'", multiline = false) {
14
+ if (!str) return `${quote}${quote}`;
15
+ if (multiline && (str.includes("\n") || str.length > 80)) return `\`${str.replace(/`/g, "\\`")}\``;
16
+ return `${quote}${str.replace(new RegExp(quote, "g"), "\\" + quote)}${quote}`;
17
+ }
18
+ /**
19
+ * Format retrieval params object
20
+ */
21
+ function formatRetrievalParams(retrievalParams, style, indentLevel) {
22
+ if (!retrievalParams || typeof retrievalParams !== "object") return "{}";
23
+ const { quotes, indentation } = style;
24
+ const q = quotes === "single" ? "'" : "\"";
25
+ const baseIndent = indentation.repeat(indentLevel);
26
+ const indent = indentation.repeat(indentLevel + 1);
27
+ const lines = ["{"];
28
+ for (const [key, value] of Object.entries(retrievalParams)) {
29
+ const formattedKey = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : `${q}${key}${q}`;
30
+ if (typeof value === "string") lines.push(`${indent}${formattedKey}: ${formatString(value, q)},`);
31
+ else if (typeof value === "number" || typeof value === "boolean") lines.push(`${indent}${formattedKey}: ${JSON.stringify(value)},`);
32
+ else if (typeof value === "object" && value !== null) lines.push(`${indent}${formattedKey}: ${formatRetrievalParams(value, style, indentLevel + 1)},`);
33
+ }
34
+ if (lines.length > 1 && lines[lines.length - 1].endsWith(",")) lines[lines.length - 1] = lines[lines.length - 1].slice(0, -1);
35
+ lines.push(`${baseIndent}}`);
36
+ return lines.join("\n");
37
+ }
38
+ /**
39
+ * Generate Credential Definition using credential() builder function
40
+ */
41
+ function generateCredentialDefinition(credentialId, credentialData, style = DEFAULT_STYLE) {
42
+ const { quotes, semicolons, indentation } = style;
43
+ const q = quotes === "single" ? "'" : "\"";
44
+ const semi = semicolons ? ";" : "";
45
+ const credentialVarName = toCamelCase(credentialId);
46
+ const lines = [];
47
+ lines.push(`export const ${credentialVarName} = credential({`);
48
+ lines.push(`${indentation}id: ${formatString(credentialId, q)},`);
49
+ const missingFields = [
50
+ "name",
51
+ "type",
52
+ "credentialStoreId"
53
+ ].filter((field) => !credentialData[field] || credentialData[field] === null || credentialData[field] === void 0);
54
+ if (missingFields.length > 0) throw new Error(`Missing required fields for credential '${credentialId}': ${missingFields.join(", ")}`);
55
+ lines.push(`${indentation}name: ${formatString(credentialData.name, q)},`);
56
+ lines.push(`${indentation}type: ${formatString(credentialData.type, q)},`);
57
+ lines.push(`${indentation}credentialStoreId: ${formatString(credentialData.credentialStoreId, q)},`);
58
+ if (credentialData.description) lines.push(`${indentation}description: ${formatString(credentialData.description, q, true)},`);
59
+ if (credentialData.retrievalParams) {
60
+ const formattedParams = formatRetrievalParams(credentialData.retrievalParams, style, 1);
61
+ if (formattedParams.includes("\n")) lines.push(`${indentation}retrievalParams: ${formattedParams},`);
62
+ else lines.push(`${indentation}retrievalParams: ${formattedParams},`);
63
+ }
64
+ if (lines.length > 0 && lines[lines.length - 1].endsWith(",")) lines[lines.length - 1] = lines[lines.length - 1].slice(0, -1);
65
+ lines.push(`})${semi}`);
66
+ return lines.join("\n");
67
+ }
68
+ /**
69
+ * Generate imports needed for a credential file
70
+ */
71
+ function generateCredentialImports(credentialId, credentialData, style = DEFAULT_STYLE) {
72
+ const { quotes, semicolons } = style;
73
+ const q = quotes === "single" ? "'" : "\"";
74
+ const semi = semicolons ? ";" : "";
75
+ const imports = [];
76
+ imports.push(`import { credential } from ${q}@inkeep/agents-sdk${q}${semi}`);
77
+ return imports;
78
+ }
79
+ /**
80
+ * Generate complete credential file (imports + definition)
81
+ */
82
+ function generateCredentialFile(credentialId, credentialData, style = DEFAULT_STYLE) {
83
+ const imports = generateCredentialImports(credentialId, credentialData, style);
84
+ const definition = generateCredentialDefinition(credentialId, credentialData, style);
85
+ return imports.join("\n") + "\n\n" + definition + "\n";
86
+ }
87
+
88
+ //#endregion
89
+ export { generateCredentialDefinition, generateCredentialFile, generateCredentialImports };