@inkeep/agents-cli 0.51.0 → 0.52.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 (69) hide show
  1. package/dist/agents-cli/package.js +6 -0
  2. package/dist/commands/config.js +1 -1
  3. package/dist/commands/dev.js +1 -1
  4. package/dist/commands/init.js +1 -1
  5. package/dist/commands/pull-v3/component-parser.js +4 -10
  6. package/dist/commands/pull-v4/agent-generator.js +274 -0
  7. package/dist/commands/pull-v4/artifact-component-generator.js +69 -0
  8. package/dist/commands/pull-v4/context-config-generator.js +264 -0
  9. package/dist/commands/pull-v4/credential-generator.js +30 -0
  10. package/dist/commands/pull-v4/data-component-generator.js +50 -0
  11. package/dist/commands/pull-v4/environment-generator.js +123 -0
  12. package/dist/commands/pull-v4/external-agent-generator.js +56 -0
  13. package/dist/commands/pull-v4/function-tool-generator.js +48 -0
  14. package/dist/commands/pull-v4/introspect/index.js +365 -0
  15. package/dist/commands/pull-v4/introspect/test-helpers.js +143 -0
  16. package/dist/commands/pull-v4/introspect-generator.js +691 -0
  17. package/dist/commands/pull-v4/mcp-tool-generator.js +91 -0
  18. package/dist/commands/pull-v4/module-merge.js +379 -0
  19. package/dist/commands/pull-v4/project-generator.js +101 -0
  20. package/dist/commands/pull-v4/status-component-generator.js +35 -0
  21. package/dist/commands/pull-v4/sub-agent-generator.js +168 -0
  22. package/dist/commands/pull-v4/trigger-generator.js +58 -0
  23. package/dist/commands/pull-v4/utils.js +219 -0
  24. package/dist/commands/push.js +1 -1
  25. package/dist/commands/update.js +2 -2
  26. package/dist/index.js +18 -44
  27. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/array.js +18 -0
  28. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/base.js +180 -0
  29. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/character.js +8 -0
  30. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/css.js +12 -0
  31. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/json.js +60 -0
  32. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/line.js +37 -0
  33. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/sentence.js +31 -0
  34. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/word.js +118 -0
  35. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/index.js +11 -0
  36. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/patch/create.js +141 -0
  37. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/util/string.js +63 -0
  38. package/dist/utils/ci-environment.js +1 -1
  39. package/dist/utils/config.js +1 -1
  40. package/dist/utils/environment-loader.js +1 -1
  41. package/dist/utils/file-finder.js +1 -1
  42. package/dist/utils/mcp-runner.js +1 -1
  43. package/dist/utils/profile-config.js +1 -1
  44. package/dist/utils/profiles/profile-manager.js +1 -1
  45. package/dist/utils/project-directory.js +1 -1
  46. package/dist/utils/project-loader.js +1 -1
  47. package/dist/utils/version-check.js +6 -15
  48. package/package.json +5 -4
  49. package/dist/commands/pull-v3/component-updater.js +0 -768
  50. package/dist/commands/pull-v3/components/agent-generator.js +0 -255
  51. package/dist/commands/pull-v3/components/artifact-component-generator.js +0 -143
  52. package/dist/commands/pull-v3/components/context-config-generator.js +0 -190
  53. package/dist/commands/pull-v3/components/credential-generator.js +0 -89
  54. package/dist/commands/pull-v3/components/data-component-generator.js +0 -102
  55. package/dist/commands/pull-v3/components/environment-generator.js +0 -173
  56. package/dist/commands/pull-v3/components/external-agent-generator.js +0 -75
  57. package/dist/commands/pull-v3/components/function-tool-generator.js +0 -92
  58. package/dist/commands/pull-v3/components/mcp-tool-generator.js +0 -86
  59. package/dist/commands/pull-v3/components/project-generator.js +0 -157
  60. package/dist/commands/pull-v3/components/status-component-generator.js +0 -92
  61. package/dist/commands/pull-v3/components/sub-agent-generator.js +0 -295
  62. package/dist/commands/pull-v3/components/trigger-generator.js +0 -185
  63. package/dist/commands/pull-v3/index.js +0 -510
  64. package/dist/commands/pull-v3/introspect-generator.js +0 -286
  65. package/dist/commands/pull-v3/llm-content-merger.js +0 -192
  66. package/dist/commands/pull-v3/new-component-generator.js +0 -279
  67. package/dist/commands/pull-v3/project-index-generator.js +0 -32
  68. package/dist/commands/pull-v3/project-validator.js +0 -358
  69. package/dist/utils/url.js +0 -26
@@ -0,0 +1,91 @@
1
+ import { addValueToObject, createFactoryDefinition, formatInlineLiteral, formatStringLiteral, toCamelCase } from "./utils.js";
2
+ import { z } from "zod";
3
+
4
+ //#region src/commands/pull-v4/mcp-tool-generator.ts
5
+ const McpToolSchema = z.looseObject({
6
+ mcpToolId: z.string().nonempty(),
7
+ name: z.string().nonempty(),
8
+ description: z.string().nullable().optional(),
9
+ config: z.looseObject({ mcp: z.looseObject({
10
+ server: z.looseObject({ url: z.string().optional() }).optional(),
11
+ transport: z.unknown().optional(),
12
+ activeTools: z.array(z.unknown()).optional()
13
+ }).optional() }).optional(),
14
+ serverUrl: z.string().optional(),
15
+ transport: z.object({ type: z.string() }).optional(),
16
+ activeTools: z.array(z.unknown()).optional(),
17
+ imageUrl: z.string().optional(),
18
+ headers: z.unknown().optional(),
19
+ credential: z.unknown().optional(),
20
+ credentialReferenceId: z.string().optional()
21
+ }).superRefine((value, context) => {
22
+ if (!resolveServerUrl(value)) context.addIssue({
23
+ code: "custom",
24
+ message: "serverUrl is required (from config.mcp.server.url or serverUrl)",
25
+ path: ["serverUrl"]
26
+ });
27
+ });
28
+ function generateMcpToolDefinition(data) {
29
+ const result = McpToolSchema.safeParse(data);
30
+ if (!result.success) throw new Error(`Validation failed for MCP tool:\n${z.prettifyError(result.error)}`);
31
+ const parsed = result.data;
32
+ const { sourceFile, configObject } = createFactoryDefinition({
33
+ importName: "mcpTool",
34
+ variableName: toCamelCase(parsed.mcpToolId)
35
+ });
36
+ if (parsed.credentialReferenceId && parsed.credential === void 0) sourceFile.addImportDeclaration({
37
+ namedImports: ["envSettings"],
38
+ moduleSpecifier: "../environments"
39
+ });
40
+ writeMcpToolConfig(configObject, parsed);
41
+ return sourceFile;
42
+ }
43
+ function writeMcpToolConfig(configObject, { mcpToolId, description, serverUrl, config, transport, activeTools, credential, credentialReferenceId, ...rest }) {
44
+ for (const [k, v] of Object.entries({
45
+ id: mcpToolId,
46
+ ...rest,
47
+ description: description ?? void 0,
48
+ serverUrl: resolveServerUrl({
49
+ config,
50
+ serverUrl
51
+ }),
52
+ transport: resolveTransport({
53
+ config,
54
+ transport
55
+ }),
56
+ activeTools: resolveActiveTools({
57
+ config,
58
+ activeTools
59
+ })
60
+ })) addValueToObject(configObject, k, v);
61
+ if (credential !== void 0 && credential !== null) {
62
+ if (typeof credential === "string") {
63
+ configObject.addPropertyAssignment({
64
+ name: "credential",
65
+ initializer: credential
66
+ });
67
+ return;
68
+ }
69
+ configObject.addPropertyAssignment({
70
+ name: "credential",
71
+ initializer: formatInlineLiteral(credential)
72
+ });
73
+ return;
74
+ }
75
+ if (credentialReferenceId) configObject.addPropertyAssignment({
76
+ name: "credential",
77
+ initializer: `envSettings.getEnvironmentCredential(${formatStringLiteral(credentialReferenceId)})`
78
+ });
79
+ }
80
+ function resolveServerUrl(data) {
81
+ return data.config?.mcp?.server?.url ?? data.serverUrl;
82
+ }
83
+ function resolveTransport(data) {
84
+ return data.config?.mcp?.transport ?? data.transport;
85
+ }
86
+ function resolveActiveTools(data) {
87
+ return data.config?.mcp?.activeTools ?? data.activeTools;
88
+ }
89
+
90
+ //#endregion
91
+ export { generateMcpToolDefinition };
@@ -0,0 +1,379 @@
1
+ import { createInMemoryProject } from "./utils.js";
2
+ import { Node, SyntaxKind } from "ts-morph";
3
+
4
+ //#region src/commands/pull-v4/module-merge.ts
5
+ function mergeGeneratedModule(existingContent, generatedContent) {
6
+ const project = createInMemoryProject();
7
+ const existingSourceFile = project.createSourceFile("existing.ts", existingContent, { overwrite: true });
8
+ const generatedSourceFile = project.createSourceFile("generated.ts", generatedContent, { overwrite: true });
9
+ mergeImports(existingSourceFile, generatedSourceFile);
10
+ for (const statement of generatedSourceFile.getStatements()) {
11
+ if (Node.isImportDeclaration(statement)) continue;
12
+ upsertStatement(existingSourceFile, statement);
13
+ }
14
+ return dedupeConsecutiveIdenticalSingleLineComments(existingSourceFile.getFullText().trimEnd());
15
+ }
16
+ function mergeImports(existingFile, generatedFile) {
17
+ for (const generatedImport of generatedFile.getImportDeclarations()) {
18
+ const moduleSpecifier = generatedImport.getModuleSpecifierValue();
19
+ const matchingImports = existingFile.getImportDeclarations().filter((existingImport) => existingImport.getModuleSpecifierValue() === moduleSpecifier);
20
+ if (!matchingImports.length) {
21
+ if (areGeneratedImportBindingsAlreadyPresent(existingFile, generatedImport)) continue;
22
+ existingFile.addImportDeclaration(generatedImport.getStructure());
23
+ continue;
24
+ }
25
+ const targetImport = findBestImportTarget(matchingImports, generatedImport);
26
+ if (!targetImport) {
27
+ if (!hasImportWithText(matchingImports, generatedImport.getText())) existingFile.addImportDeclaration(generatedImport.getStructure());
28
+ continue;
29
+ }
30
+ if (!generatedImport.isTypeOnly() && targetImport.isTypeOnly()) targetImport.setIsTypeOnly(false);
31
+ const generatedDefaultImport = generatedImport.getDefaultImport();
32
+ if (generatedDefaultImport && !targetImport.getDefaultImport()) targetImport.setDefaultImport(generatedDefaultImport.getText());
33
+ const generatedNamespaceImport = generatedImport.getNamespaceImport();
34
+ if (generatedNamespaceImport && !targetImport.getNamespaceImport()) targetImport.setNamespaceImport(generatedNamespaceImport.getText());
35
+ for (const generatedNamedImport of generatedImport.getNamedImports()) {
36
+ const generatedName = generatedNamedImport.getName();
37
+ const generatedAlias = generatedNamedImport.getAliasNode()?.getText();
38
+ const generatedIsTypeOnly = generatedNamedImport.isTypeOnly();
39
+ if (!targetImport.getNamedImports().some((existingNamedImport) => {
40
+ return existingNamedImport.getName() === generatedName && existingNamedImport.getAliasNode()?.getText() === generatedAlias && existingNamedImport.isTypeOnly() === generatedIsTypeOnly;
41
+ })) targetImport.addNamedImport({
42
+ name: generatedName,
43
+ alias: generatedAlias,
44
+ isTypeOnly: generatedIsTypeOnly
45
+ });
46
+ }
47
+ }
48
+ }
49
+ function findBestImportTarget(matchingImports, generatedImport) {
50
+ if (generatedImport.getNamespaceImport()) {
51
+ const namespaceText = generatedImport.getNamespaceImport()?.getText();
52
+ return matchingImports.find((importDeclaration) => importDeclaration.getNamespaceImport()?.getText() === namespaceText);
53
+ }
54
+ const nonNamespaceImport = matchingImports.find((importDeclaration) => !importDeclaration.getNamespaceImport());
55
+ if (nonNamespaceImport) return nonNamespaceImport;
56
+ }
57
+ function hasImportWithText(imports, text) {
58
+ return imports.some((importDeclaration) => importDeclaration.getText() === text);
59
+ }
60
+ function areGeneratedImportBindingsAlreadyPresent(existingFile, generatedImport) {
61
+ const generatedBindings = getImportBindingNames(generatedImport);
62
+ if (!generatedBindings.length) return false;
63
+ const existingImports = existingFile.getImportDeclarations();
64
+ return generatedBindings.every((binding) => existingImports.some((existingImport) => importHasBinding(existingImport, binding)));
65
+ }
66
+ function getImportBindingNames(importDeclaration) {
67
+ const bindings = [];
68
+ const defaultImport = importDeclaration.getDefaultImport();
69
+ if (defaultImport) bindings.push(defaultImport.getText());
70
+ const namespaceImport = importDeclaration.getNamespaceImport();
71
+ if (namespaceImport) bindings.push(namespaceImport.getText());
72
+ for (const namedImport of importDeclaration.getNamedImports()) bindings.push(namedImport.getAliasNode()?.getText() ?? namedImport.getName());
73
+ return bindings;
74
+ }
75
+ function importHasBinding(importDeclaration, bindingName) {
76
+ if (importDeclaration.getDefaultImport()?.getText() === bindingName) return true;
77
+ if (importDeclaration.getNamespaceImport()?.getText() === bindingName) return true;
78
+ return importDeclaration.getNamedImports().some((namedImport) => {
79
+ return (namedImport.getAliasNode()?.getText() ?? namedImport.getName()) === bindingName;
80
+ });
81
+ }
82
+ function upsertStatement(existingFile, generatedStatement) {
83
+ if (Node.isVariableStatement(generatedStatement)) {
84
+ upsertVariableStatement(existingFile, generatedStatement);
85
+ return;
86
+ }
87
+ if (Node.isFunctionDeclaration(generatedStatement)) {
88
+ upsertNamedStatement(existingFile, generatedStatement, (sourceFile, name) => sourceFile.getFunction(name));
89
+ return;
90
+ }
91
+ if (Node.isClassDeclaration(generatedStatement)) {
92
+ upsertNamedStatement(existingFile, generatedStatement, (sourceFile, name) => sourceFile.getClass(name));
93
+ return;
94
+ }
95
+ if (Node.isInterfaceDeclaration(generatedStatement)) {
96
+ upsertNamedStatement(existingFile, generatedStatement, (sourceFile, name) => sourceFile.getInterface(name));
97
+ return;
98
+ }
99
+ if (Node.isTypeAliasDeclaration(generatedStatement)) {
100
+ upsertNamedStatement(existingFile, generatedStatement, (sourceFile, name) => sourceFile.getTypeAlias(name));
101
+ return;
102
+ }
103
+ if (Node.isEnumDeclaration(generatedStatement)) {
104
+ upsertNamedStatement(existingFile, generatedStatement, (sourceFile, name) => sourceFile.getEnum(name));
105
+ return;
106
+ }
107
+ appendUniqueStatement(existingFile, generatedStatement);
108
+ }
109
+ function upsertVariableStatement(existingFile, generatedStatement) {
110
+ if (!Node.isVariableStatement(generatedStatement)) return;
111
+ const generatedDeclarations = generatedStatement.getDeclarations();
112
+ if (!generatedDeclarations.length) {
113
+ appendUniqueStatement(existingFile, generatedStatement);
114
+ return;
115
+ }
116
+ const existingStatements = /* @__PURE__ */ new Set();
117
+ for (const generatedDeclaration of generatedDeclarations) {
118
+ let existingDeclaration = existingFile.getVariableDeclaration(generatedDeclaration.getName());
119
+ if (!existingDeclaration) {
120
+ existingDeclaration = findExistingDeclarationByEntitySignature(existingFile, generatedDeclaration);
121
+ if (existingDeclaration) generatedDeclaration.rename(existingDeclaration.getName());
122
+ }
123
+ if (!existingDeclaration) continue;
124
+ const existingStatement = existingDeclaration.getFirstAncestorByKind(SyntaxKind.VariableStatement);
125
+ if (existingStatement) existingStatements.add(existingStatement);
126
+ }
127
+ if (!existingStatements.size) {
128
+ appendUniqueStatement(existingFile, generatedStatement);
129
+ return;
130
+ }
131
+ const [firstExistingStatement, ...remainingStatements] = [...existingStatements];
132
+ if (firstExistingStatement) firstExistingStatement.replaceWithText(buildReplacementStatementText(firstExistingStatement, generatedStatement));
133
+ for (const statement of remainingStatements) statement.remove();
134
+ }
135
+ function findExistingDeclarationByEntitySignature(existingFile, generatedDeclaration) {
136
+ const generatedSignature = getVariableDeclarationEntitySignature(generatedDeclaration);
137
+ if (!generatedSignature) return;
138
+ const matchingDeclarations = existingFile.getVariableDeclarations().filter((declaration) => getVariableDeclarationEntitySignature(declaration) === generatedSignature);
139
+ if (!matchingDeclarations.length) return;
140
+ return matchingDeclarations.find((declaration) => declaration.getFirstAncestorByKind(SyntaxKind.VariableStatement)?.hasExportKeyword()) ?? matchingDeclarations[0];
141
+ }
142
+ function getVariableDeclarationEntitySignature(declaration) {
143
+ const initializer = declaration.getInitializer();
144
+ if (!initializer || !Node.isCallExpression(initializer)) return;
145
+ const expression = initializer.getExpression();
146
+ if (!Node.isIdentifier(expression)) return;
147
+ const args = initializer.getArguments();
148
+ if (!args.length || !Node.isObjectLiteralExpression(args[0])) return;
149
+ const factoryName = expression.getText();
150
+ const entityId = readEntityId(args[0], factoryName);
151
+ if (!entityId) return;
152
+ return `${factoryName}:${entityId}`;
153
+ }
154
+ function readEntityId(configObject, factoryName) {
155
+ const idProperty = configObject.getProperty("id");
156
+ if (idProperty && Node.isPropertyAssignment(idProperty)) {
157
+ const idInitializer = idProperty.getInitializer();
158
+ if (idInitializer && Node.isStringLiteral(idInitializer)) return idInitializer.getLiteralValue();
159
+ }
160
+ if (factoryName === "statusComponent") {
161
+ const typeProperty = configObject.getProperty("type");
162
+ if (typeProperty && Node.isPropertyAssignment(typeProperty)) {
163
+ const typeInitializer = typeProperty.getInitializer();
164
+ if (typeInitializer && Node.isStringLiteral(typeInitializer)) return typeInitializer.getLiteralValue();
165
+ }
166
+ }
167
+ if (factoryName === "functionTool") {
168
+ const nameProperty = configObject.getProperty("name");
169
+ if (nameProperty && Node.isPropertyAssignment(nameProperty)) {
170
+ const nameInitializer = nameProperty.getInitializer();
171
+ if (nameInitializer && Node.isStringLiteral(nameInitializer)) return nameInitializer.getLiteralValue();
172
+ }
173
+ }
174
+ }
175
+ function upsertNamedStatement(existingFile, generatedStatement, finder) {
176
+ const statementName = Node.isFunctionDeclaration(generatedStatement) || Node.isClassDeclaration(generatedStatement) || Node.isInterfaceDeclaration(generatedStatement) || Node.isTypeAliasDeclaration(generatedStatement) || Node.isEnumDeclaration(generatedStatement) ? generatedStatement.getName() : void 0;
177
+ if (!statementName) {
178
+ appendUniqueStatement(existingFile, generatedStatement);
179
+ return;
180
+ }
181
+ const existingStatement = finder(existingFile, statementName);
182
+ if (!existingStatement) {
183
+ appendUniqueStatement(existingFile, generatedStatement);
184
+ return;
185
+ }
186
+ existingStatement.replaceWithText(buildReplacementStatementText(existingStatement, generatedStatement));
187
+ }
188
+ function appendUniqueStatement(existingFile, generatedStatement) {
189
+ const statementText = generatedStatement.getText();
190
+ if (existingFile.getStatements().some((statement) => statement.getText() === statementText)) return;
191
+ existingFile.addStatements([statementText]);
192
+ }
193
+ function buildReplacementStatementText(existingStatement, generatedStatement) {
194
+ return withPreservedLeadingComments(existingStatement, alignStatementOrdering(existingStatement, generatedStatement));
195
+ }
196
+ function alignStatementOrdering(existingStatement, generatedStatement) {
197
+ if (Node.isVariableStatement(existingStatement) && Node.isVariableStatement(generatedStatement)) return alignVariableStatementOrdering(existingStatement, generatedStatement);
198
+ return generatedStatement.getText();
199
+ }
200
+ function alignVariableStatementOrdering(existingStatement, generatedStatement) {
201
+ generatedStatement.setIsExported(existingStatement.isExported());
202
+ const generatedText = generatedStatement.getText();
203
+ const generatedStatementStart = generatedStatement.getStart();
204
+ const existingDeclarationsByName = new Map(existingStatement.getDeclarations().map((declaration) => [declaration.getName(), declaration]));
205
+ const replacements = [];
206
+ for (const generatedDeclaration of generatedStatement.getDeclarations()) {
207
+ const existingDeclaration = existingDeclarationsByName.get(generatedDeclaration.getName());
208
+ if (!existingDeclaration) continue;
209
+ const generatedInitializer = generatedDeclaration.getInitializer();
210
+ const existingInitializer = existingDeclaration.getInitializer();
211
+ if (!generatedInitializer || !existingInitializer) continue;
212
+ const alignedInitializerText = alignExpressionText(existingInitializer, generatedInitializer);
213
+ if (alignedInitializerText === generatedInitializer.getText()) continue;
214
+ replacements.push({
215
+ start: generatedInitializer.getStart() - generatedStatementStart,
216
+ end: generatedInitializer.getEnd() - generatedStatementStart,
217
+ text: alignedInitializerText
218
+ });
219
+ }
220
+ return applyTextReplacements(generatedText, replacements);
221
+ }
222
+ function alignExpressionText(existingExpression, generatedExpression) {
223
+ if (!existingExpression) return generatedExpression.getText();
224
+ if (Node.isObjectLiteralExpression(existingExpression) && Node.isObjectLiteralExpression(generatedExpression)) return alignObjectLiteralText(existingExpression, generatedExpression);
225
+ if (Node.isArrayLiteralExpression(existingExpression) && Node.isArrayLiteralExpression(generatedExpression)) return alignArrayLiteralText(existingExpression, generatedExpression);
226
+ if (Node.isArrowFunction(existingExpression) && Node.isArrowFunction(generatedExpression)) return alignArrowFunctionText(existingExpression, generatedExpression);
227
+ if (Node.isCallExpression(existingExpression) && Node.isCallExpression(generatedExpression)) return alignCallExpressionText(existingExpression, generatedExpression);
228
+ if (Node.isParenthesizedExpression(existingExpression) && Node.isParenthesizedExpression(generatedExpression)) return `(${alignExpressionText(existingExpression.getExpression(), generatedExpression.getExpression())})`;
229
+ return generatedExpression.getText();
230
+ }
231
+ function alignCallExpressionText(existingCall, generatedCall) {
232
+ if (!Node.isCallExpression(existingCall) || !Node.isCallExpression(generatedCall)) return generatedCall.getText();
233
+ const generatedText = generatedCall.getText();
234
+ const generatedCallStart = generatedCall.getStart();
235
+ const existingArguments = existingCall.getArguments();
236
+ const generatedArguments = generatedCall.getArguments();
237
+ const replacements = [];
238
+ for (const [index, generatedArgument] of generatedArguments.entries()) {
239
+ const existingArgument = existingArguments[index];
240
+ if (!existingArgument) continue;
241
+ const alignedArgumentText = alignExpressionText(existingArgument, generatedArgument);
242
+ if (alignedArgumentText === generatedArgument.getText()) continue;
243
+ replacements.push({
244
+ start: generatedArgument.getStart() - generatedCallStart,
245
+ end: generatedArgument.getEnd() - generatedCallStart,
246
+ text: alignedArgumentText
247
+ });
248
+ }
249
+ return applyTextReplacements(generatedText, replacements);
250
+ }
251
+ function alignArrowFunctionText(existingArrow, generatedArrow) {
252
+ if (!Node.isArrowFunction(existingArrow) || !Node.isArrowFunction(generatedArrow)) return generatedArrow.getText();
253
+ const existingBody = existingArrow.getBody();
254
+ const generatedBody = generatedArrow.getBody();
255
+ if (!Node.isExpression(existingBody) || !Node.isExpression(generatedBody)) return generatedArrow.getText();
256
+ const alignedBodyText = alignExpressionText(existingBody, generatedBody);
257
+ if (alignedBodyText === generatedBody.getText()) return generatedArrow.getText();
258
+ return applyTextReplacements(generatedArrow.getText(), [{
259
+ start: generatedBody.getStart() - generatedArrow.getStart(),
260
+ end: generatedBody.getEnd() - generatedArrow.getStart(),
261
+ text: alignedBodyText
262
+ }]);
263
+ }
264
+ function alignObjectLiteralText(existingObject, generatedObject) {
265
+ const propertyTexts = orderObjectProperties(existingObject.getProperties(), generatedObject.getProperties()).map(({ existingProperty, generatedProperty }) => {
266
+ if (!existingProperty) return generatedProperty.getText();
267
+ return withPreservedLeadingComments(existingProperty, alignObjectPropertyText(existingProperty, generatedProperty));
268
+ });
269
+ return formatCollectionLiteralText(generatedObject.getText(), propertyTexts, "{", "}");
270
+ }
271
+ function alignObjectPropertyText(existingProperty, generatedProperty) {
272
+ const text = generatedProperty.getText();
273
+ if (!Node.isPropertyAssignment(generatedProperty)) return text;
274
+ const generatedInitializer = generatedProperty.getInitializer();
275
+ if (!generatedInitializer) return text;
276
+ const alignedInitializerText = alignExpressionText(Node.isPropertyAssignment(existingProperty) ? existingProperty.getInitializer() : void 0, generatedInitializer);
277
+ return `${generatedProperty.getNameNode().getText()}: ${alignedInitializerText}`;
278
+ }
279
+ function alignArrayLiteralText(existingArray, generatedArray) {
280
+ if (!Node.isArrayLiteralExpression(existingArray) || !Node.isArrayLiteralExpression(generatedArray)) return generatedArray.getText();
281
+ const elementTexts = orderArrayElements(existingArray.getElements(), generatedArray.getElements()).map(({ existingElement, generatedElement }) => alignExpressionText(existingElement, generatedElement));
282
+ return formatCollectionLiteralText(generatedArray.getText(), elementTexts, "[", "]");
283
+ }
284
+ function orderObjectProperties(existingProperties, generatedProperties) {
285
+ return orderNodesBySignature(existingProperties, generatedProperties, getObjectPropertyKey, getObjectPropertyKey).map(({ existingNode, generatedNode }) => ({
286
+ existingProperty: existingNode,
287
+ generatedProperty: generatedNode
288
+ }));
289
+ }
290
+ function orderArrayElements(existingElements, generatedElements) {
291
+ return orderNodesBySignature(existingElements, generatedElements, getArrayElementSignature, getArrayElementSignature).map(({ existingNode, generatedNode }) => ({
292
+ existingElement: existingNode,
293
+ generatedElement: generatedNode
294
+ }));
295
+ }
296
+ function orderNodesBySignature(existingNodes, generatedNodes, getExistingSignature, getGeneratedSignature) {
297
+ const generatedEntries = generatedNodes.map((generatedNode) => ({
298
+ generatedNode,
299
+ signature: getGeneratedSignature(generatedNode)
300
+ }));
301
+ const usedGeneratedIndexes = /* @__PURE__ */ new Set();
302
+ const ordered = [];
303
+ for (const existingNode of existingNodes) {
304
+ const existingSignature = getExistingSignature(existingNode);
305
+ if (!existingSignature) continue;
306
+ const generatedIndex = generatedEntries.findIndex((entry, index) => !usedGeneratedIndexes.has(index) && entry.signature === existingSignature);
307
+ if (generatedIndex === -1) continue;
308
+ const generatedEntry = generatedEntries[generatedIndex];
309
+ if (!generatedEntry) continue;
310
+ usedGeneratedIndexes.add(generatedIndex);
311
+ ordered.push({
312
+ existingNode,
313
+ generatedNode: generatedEntry.generatedNode
314
+ });
315
+ }
316
+ for (const [index, generatedEntry] of generatedEntries.entries()) {
317
+ if (usedGeneratedIndexes.has(index)) continue;
318
+ ordered.push({ generatedNode: generatedEntry.generatedNode });
319
+ }
320
+ return ordered;
321
+ }
322
+ function getObjectPropertyKey(property) {
323
+ if (Node.isPropertyAssignment(property) || Node.isShorthandPropertyAssignment(property) || Node.isMethodDeclaration(property) || Node.isGetAccessorDeclaration(property) || Node.isSetAccessorDeclaration(property)) return property.getName();
324
+ if (Node.isSpreadAssignment(property)) return `...${property.getExpression().getText()}`;
325
+ }
326
+ function getArrayElementSignature(node) {
327
+ if (Node.isIdentifier(node)) return `id:${node.getText()}`;
328
+ if (Node.isStringLiteral(node)) return `str:${node.getLiteralValue()}`;
329
+ if (Node.isObjectLiteralExpression(node)) {
330
+ const objectId = readStringLiteralObjectProperty(node, "id") || readStringLiteralObjectProperty(node, "type") || readStringLiteralObjectProperty(node, "name");
331
+ if (objectId) return `obj:${objectId}`;
332
+ }
333
+ if (Node.isCallExpression(node)) {
334
+ const expression = node.getExpression();
335
+ if (Node.isPropertyAccessExpression(expression) && expression.getName() === "with") return `with:${expression.getExpression().getText()}`;
336
+ }
337
+ return node.getText();
338
+ }
339
+ function readStringLiteralObjectProperty(objectLiteral, propertyName) {
340
+ const property = objectLiteral.getProperty(propertyName);
341
+ if (!property || !Node.isPropertyAssignment(property)) return;
342
+ const initializer = property.getInitializer();
343
+ if (!initializer || !Node.isStringLiteral(initializer)) return;
344
+ return initializer.getLiteralValue();
345
+ }
346
+ function formatCollectionLiteralText(originalText, itemTexts, openToken, closeToken) {
347
+ if (originalText.includes("\n")) return `${openToken}\n${itemTexts.map((line) => {
348
+ return line.replaceAll(/^\s+\*/gm, " *");
349
+ }).join(",\n")}${closeToken}`;
350
+ const openingWithSpacing = originalText.startsWith(`${openToken} `) ? `${openToken} ` : openToken;
351
+ const closingWithSpacing = originalText.endsWith(` ${closeToken}`) ? ` ${closeToken}` : closeToken;
352
+ return `${openingWithSpacing}${itemTexts.join(", ")}${closingWithSpacing}`;
353
+ }
354
+ function applyTextReplacements(sourceText, replacements) {
355
+ if (!replacements.length) return sourceText;
356
+ let nextText = sourceText;
357
+ const replacementsInDescendingOrder = [...replacements].sort((a, b) => b.start - a.start);
358
+ for (const replacement of replacementsInDescendingOrder) nextText = nextText.slice(0, replacement.start) + replacement.text + nextText.slice(replacement.end);
359
+ return nextText;
360
+ }
361
+ function withPreservedLeadingComments(existingStatement, replacementText) {
362
+ const leadingComments = existingStatement.getLeadingCommentRanges().map((comment) => comment.getText()).join("\n");
363
+ if (!leadingComments) return replacementText;
364
+ return `${leadingComments}\n${replacementText}`;
365
+ }
366
+ function dedupeConsecutiveIdenticalSingleLineComments(content) {
367
+ const lines = content.split("\n");
368
+ const deduped = [];
369
+ for (const line of lines) {
370
+ const trimmedLine = line.trim();
371
+ const previousTrimmedLine = deduped.at(-1)?.trim();
372
+ if (trimmedLine.startsWith("//") && previousTrimmedLine?.startsWith("//") && trimmedLine === previousTrimmedLine) continue;
373
+ deduped.push(line);
374
+ }
375
+ return deduped.join("\n");
376
+ }
377
+
378
+ //#endregion
379
+ export { mergeGeneratedModule };
@@ -0,0 +1,101 @@
1
+ import { addReferenceGetterProperty, addValueToObject, convertNullToUndefined, createFactoryDefinition, formatStringLiteral, hasReferences, resolveReferenceName, toCamelCase } from "./utils.js";
2
+ import { z } from "zod";
3
+
4
+ //#region src/commands/pull-v4/project-generator.ts
5
+ const ReferenceNameByIdSchema = z.record(z.string(), z.string().nonempty());
6
+ const ReferenceOverridesSchema = z.object({
7
+ agents: ReferenceNameByIdSchema.optional(),
8
+ tools: ReferenceNameByIdSchema.optional(),
9
+ externalAgents: ReferenceNameByIdSchema.optional(),
10
+ dataComponents: ReferenceNameByIdSchema.optional(),
11
+ artifactComponents: ReferenceNameByIdSchema.optional(),
12
+ credentialReferences: ReferenceNameByIdSchema.optional()
13
+ });
14
+ const ProjectSchema = z.looseObject({
15
+ projectId: z.string().nonempty(),
16
+ name: z.string().nonempty(),
17
+ description: z.string().optional(),
18
+ models: z.looseObject({
19
+ base: z.looseObject({ model: z.string().nonempty() }),
20
+ structuredOutput: z.looseObject({}).optional(),
21
+ summarizer: z.looseObject({}).optional()
22
+ }),
23
+ stopWhen: z.preprocess(convertNullToUndefined, z.strictObject({
24
+ transferCountIs: z.int().optional(),
25
+ stepCountIs: z.int().optional()
26
+ }).optional()),
27
+ skills: z.array(z.string()).optional(),
28
+ agents: z.array(z.string()).optional(),
29
+ tools: z.array(z.string()).optional(),
30
+ externalAgents: z.array(z.string()).optional(),
31
+ dataComponents: z.array(z.string()).optional(),
32
+ artifactComponents: z.array(z.string()).optional(),
33
+ credentialReferences: z.array(z.string()).optional(),
34
+ referenceOverrides: ReferenceOverridesSchema.optional()
35
+ });
36
+ function generateProjectDefinition(data) {
37
+ const result = ProjectSchema.safeParse(data);
38
+ if (!result.success) throw new Error(`Validation failed for project:
39
+ ${z.prettifyError(result.error)}`);
40
+ const parsed = result.data;
41
+ const { sourceFile, configObject } = createFactoryDefinition({
42
+ importName: "project",
43
+ variableName: toCamelCase(parsed.projectId)
44
+ });
45
+ if (hasReferences(parsed.skills)) {
46
+ sourceFile.getImportDeclarationOrThrow("@inkeep/agents-sdk").addNamedImport("loadSkills");
47
+ sourceFile.addImportDeclaration({
48
+ defaultImport: "path",
49
+ moduleSpecifier: "node:path"
50
+ });
51
+ }
52
+ const { projectId, skills, agents, tools, externalAgents, dataComponents, artifactComponents, credentialReferences, referenceOverrides, ...rest } = parsed;
53
+ for (const [key, value] of Object.entries({
54
+ id: projectId,
55
+ ...rest
56
+ })) addValueToObject(configObject, key, value);
57
+ if (hasReferences(skills)) configObject.addPropertyAssignment({
58
+ name: "skills",
59
+ initializer: `() => loadSkills(path.join(${formatStringLiteral(projectId)}, 'skills'))`
60
+ });
61
+ if (hasReferences(agents)) {
62
+ addReferenceImports(sourceFile, agents, "./agents", referenceOverrides?.agents);
63
+ addReferenceGetterProperty(configObject, "agents", toReferenceNames(agents, referenceOverrides?.agents));
64
+ }
65
+ if (hasReferences(tools)) {
66
+ addReferenceImports(sourceFile, tools, "./tools", referenceOverrides?.tools);
67
+ addReferenceGetterProperty(configObject, "tools", toReferenceNames(tools, referenceOverrides?.tools));
68
+ }
69
+ if (hasReferences(externalAgents)) {
70
+ addReferenceImports(sourceFile, externalAgents, "./external-agents", referenceOverrides?.externalAgents);
71
+ addReferenceGetterProperty(configObject, "externalAgents", toReferenceNames(externalAgents, referenceOverrides?.externalAgents));
72
+ }
73
+ if (hasReferences(dataComponents)) {
74
+ addReferenceImports(sourceFile, dataComponents, "./data-components", referenceOverrides?.dataComponents);
75
+ addReferenceGetterProperty(configObject, "dataComponents", toReferenceNames(dataComponents, referenceOverrides?.dataComponents));
76
+ }
77
+ if (hasReferences(artifactComponents)) {
78
+ addReferenceImports(sourceFile, artifactComponents, "./artifact-components", referenceOverrides?.artifactComponents);
79
+ addReferenceGetterProperty(configObject, "artifactComponents", toReferenceNames(artifactComponents, referenceOverrides?.artifactComponents));
80
+ }
81
+ if (hasReferences(credentialReferences)) {
82
+ addReferenceImports(sourceFile, credentialReferences, "./credentials", referenceOverrides?.credentialReferences);
83
+ addReferenceGetterProperty(configObject, "credentialReferences", toReferenceNames(credentialReferences, referenceOverrides?.credentialReferences));
84
+ }
85
+ return sourceFile;
86
+ }
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}`
93
+ });
94
+ }
95
+ }
96
+ function toReferenceNames(references, referenceOverrides) {
97
+ return references.map((reference) => resolveReferenceName(reference, [referenceOverrides]));
98
+ }
99
+
100
+ //#endregion
101
+ export { generateProjectDefinition };
@@ -0,0 +1,35 @@
1
+ import { addValueToObject, convertJsonSchemaToZodSafe, createFactoryDefinition, toCamelCase } from "./utils.js";
2
+ import { z } from "zod";
3
+
4
+ //#region src/commands/pull-v4/status-component-generator.ts
5
+ const StatusComponentSchema = z.looseObject({
6
+ statusComponentId: z.string().nonempty(),
7
+ type: z.string().nonempty(),
8
+ description: z.string().optional(),
9
+ detailsSchema: z.unknown().optional(),
10
+ schema: z.unknown().optional()
11
+ });
12
+ function generateStatusComponentDefinition(data) {
13
+ const result = StatusComponentSchema.safeParse(data);
14
+ if (!result.success) throw new Error(`Validation failed for status component:\n${z.prettifyError(result.error)}`);
15
+ const parsed = result.data;
16
+ const detailsSchema = parsed.detailsSchema !== void 0 ? parsed.detailsSchema : parsed.schema;
17
+ const { sourceFile, configObject } = createFactoryDefinition({
18
+ importName: "statusComponent",
19
+ variableName: toCamelCase(parsed.statusComponentId)
20
+ });
21
+ if (detailsSchema !== void 0) sourceFile.addImportDeclaration({
22
+ namedImports: ["z"],
23
+ moduleSpecifier: "zod"
24
+ });
25
+ const { statusComponentId, id, detailsSchema: _, schema: _2, ...rest } = parsed;
26
+ for (const [k, v] of Object.entries(rest)) addValueToObject(configObject, k, v);
27
+ if (detailsSchema) configObject.addPropertyAssignment({
28
+ name: "detailsSchema",
29
+ initializer: convertJsonSchemaToZodSafe(detailsSchema)
30
+ });
31
+ return sourceFile;
32
+ }
33
+
34
+ //#endregion
35
+ export { generateStatusComponentDefinition };