@inkeep/agents-cli 0.51.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 (76) 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 → pull-v4}/component-parser.js +6 -12
  6. package/dist/commands/{pull-v3/utils → pull-v4}/component-registry.js +1 -1
  7. package/dist/commands/pull-v4/generators/agent-generator.js +258 -0
  8. package/dist/commands/pull-v4/generators/artifact-component-generator.js +69 -0
  9. package/dist/commands/pull-v4/generators/context-config-generator.js +264 -0
  10. package/dist/commands/pull-v4/generators/credential-generator.js +30 -0
  11. package/dist/commands/pull-v4/generators/data-component-generator.js +50 -0
  12. package/dist/commands/pull-v4/generators/environment-generator.js +123 -0
  13. package/dist/commands/pull-v4/generators/external-agent-generator.js +56 -0
  14. package/dist/commands/pull-v4/generators/function-tool-generator.js +48 -0
  15. package/dist/commands/pull-v4/generators/mcp-tool-generator.js +91 -0
  16. package/dist/commands/pull-v4/generators/project-generator.js +125 -0
  17. package/dist/commands/{pull-v3/components → pull-v4/generators}/skill-generator.js +1 -1
  18. package/dist/commands/pull-v4/generators/status-component-generator.js +35 -0
  19. package/dist/commands/pull-v4/generators/sub-agent-generator.js +269 -0
  20. package/dist/commands/pull-v4/generators/trigger-generator.js +58 -0
  21. package/dist/commands/pull-v4/introspect/index.js +365 -0
  22. package/dist/commands/pull-v4/introspect/test-helpers.js +143 -0
  23. package/dist/commands/pull-v4/introspect-generator.js +706 -0
  24. package/dist/commands/pull-v4/module-merge.js +405 -0
  25. package/dist/commands/pull-v4/utils.js +235 -0
  26. package/dist/commands/push.js +1 -1
  27. package/dist/commands/update.js +2 -2
  28. package/dist/index.js +18 -44
  29. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/array.js +18 -0
  30. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/base.js +180 -0
  31. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/character.js +8 -0
  32. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/css.js +12 -0
  33. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/json.js +60 -0
  34. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/line.js +37 -0
  35. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/sentence.js +31 -0
  36. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/word.js +118 -0
  37. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/index.js +11 -0
  38. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/patch/create.js +141 -0
  39. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/util/string.js +63 -0
  40. package/dist/utils/ci-environment.js +1 -1
  41. package/dist/utils/config.js +1 -1
  42. package/dist/utils/environment-loader.js +1 -1
  43. package/dist/utils/file-finder.js +1 -1
  44. package/dist/utils/mcp-runner.js +1 -1
  45. package/dist/utils/profile-config.js +1 -1
  46. package/dist/utils/profiles/profile-manager.js +1 -1
  47. package/dist/utils/project-directory.js +1 -1
  48. package/dist/utils/project-loader.js +1 -1
  49. package/dist/utils/version-check.js +6 -15
  50. package/package.json +5 -7
  51. package/dist/commands/pull-v3/component-updater.js +0 -768
  52. package/dist/commands/pull-v3/components/agent-generator.js +0 -255
  53. package/dist/commands/pull-v3/components/artifact-component-generator.js +0 -143
  54. package/dist/commands/pull-v3/components/context-config-generator.js +0 -190
  55. package/dist/commands/pull-v3/components/credential-generator.js +0 -89
  56. package/dist/commands/pull-v3/components/data-component-generator.js +0 -102
  57. package/dist/commands/pull-v3/components/environment-generator.js +0 -173
  58. package/dist/commands/pull-v3/components/external-agent-generator.js +0 -75
  59. package/dist/commands/pull-v3/components/function-tool-generator.js +0 -92
  60. package/dist/commands/pull-v3/components/mcp-tool-generator.js +0 -86
  61. package/dist/commands/pull-v3/components/project-generator.js +0 -157
  62. package/dist/commands/pull-v3/components/status-component-generator.js +0 -92
  63. package/dist/commands/pull-v3/components/sub-agent-generator.js +0 -295
  64. package/dist/commands/pull-v3/components/trigger-generator.js +0 -185
  65. package/dist/commands/pull-v3/index.js +0 -510
  66. package/dist/commands/pull-v3/introspect-generator.js +0 -286
  67. package/dist/commands/pull-v3/llm-content-merger.js +0 -192
  68. package/dist/commands/pull-v3/new-component-generator.js +0 -279
  69. package/dist/commands/pull-v3/project-comparator.js +0 -914
  70. package/dist/commands/pull-v3/project-index-generator.js +0 -32
  71. package/dist/commands/pull-v3/project-validator.js +0 -358
  72. package/dist/commands/pull-v3/targeted-typescript-placeholders.js +0 -173
  73. package/dist/commands/pull-v3/utils/component-tracker.js +0 -165
  74. package/dist/commands/pull-v3/utils/generator-utils.js +0 -146
  75. package/dist/commands/pull-v3/utils/model-provider-detector.js +0 -50
  76. package/dist/utils/url.js +0 -26
@@ -0,0 +1,405 @@
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
+ if (hasGeneratedImportBindingConflicts(existingFile, generatedImport)) continue;
23
+ existingFile.addImportDeclaration(generatedImport.getStructure());
24
+ continue;
25
+ }
26
+ const targetImport = findBestImportTarget(matchingImports, generatedImport);
27
+ if (!targetImport) {
28
+ if (!hasImportWithText(matchingImports, generatedImport.getText())) existingFile.addImportDeclaration(generatedImport.getStructure());
29
+ continue;
30
+ }
31
+ if (!generatedImport.isTypeOnly() && targetImport.isTypeOnly()) targetImport.setIsTypeOnly(false);
32
+ const generatedDefaultImport = generatedImport.getDefaultImport();
33
+ if (generatedDefaultImport && !targetImport.getDefaultImport()) {
34
+ const defaultImportName = generatedDefaultImport.getText();
35
+ if (!hasTopLevelDeclarationWithName(existingFile, defaultImportName)) targetImport.setDefaultImport(defaultImportName);
36
+ }
37
+ const generatedNamespaceImport = generatedImport.getNamespaceImport();
38
+ if (generatedNamespaceImport && !targetImport.getNamespaceImport()) {
39
+ const namespaceImportName = generatedNamespaceImport.getText();
40
+ if (!hasTopLevelDeclarationWithName(existingFile, namespaceImportName)) targetImport.setNamespaceImport(namespaceImportName);
41
+ }
42
+ for (const generatedNamedImport of generatedImport.getNamedImports()) {
43
+ const generatedName = generatedNamedImport.getName();
44
+ const generatedAlias = generatedNamedImport.getAliasNode()?.getText();
45
+ const generatedIsTypeOnly = generatedNamedImport.isTypeOnly();
46
+ const generatedBindingName = generatedAlias ?? generatedName;
47
+ if (!targetImport.getNamedImports().some((existingNamedImport) => {
48
+ return existingNamedImport.getName() === generatedName && existingNamedImport.getAliasNode()?.getText() === generatedAlias && existingNamedImport.isTypeOnly() === generatedIsTypeOnly;
49
+ })) {
50
+ if (hasTopLevelDeclarationWithName(existingFile, generatedBindingName)) continue;
51
+ targetImport.addNamedImport({
52
+ name: generatedName,
53
+ alias: generatedAlias,
54
+ isTypeOnly: generatedIsTypeOnly
55
+ });
56
+ }
57
+ }
58
+ }
59
+ }
60
+ function findBestImportTarget(matchingImports, generatedImport) {
61
+ if (generatedImport.getNamespaceImport()) {
62
+ const namespaceText = generatedImport.getNamespaceImport()?.getText();
63
+ return matchingImports.find((importDeclaration) => importDeclaration.getNamespaceImport()?.getText() === namespaceText);
64
+ }
65
+ const nonNamespaceImport = matchingImports.find((importDeclaration) => !importDeclaration.getNamespaceImport());
66
+ if (nonNamespaceImport) return nonNamespaceImport;
67
+ }
68
+ function hasImportWithText(imports, text) {
69
+ return imports.some((importDeclaration) => importDeclaration.getText() === text);
70
+ }
71
+ function areGeneratedImportBindingsAlreadyPresent(existingFile, generatedImport) {
72
+ const generatedBindings = getImportBindingNames(generatedImport);
73
+ if (!generatedBindings.length) return false;
74
+ const existingImports = existingFile.getImportDeclarations();
75
+ return generatedBindings.every((binding) => existingImports.some((existingImport) => importHasBinding(existingImport, binding)));
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
+ }
82
+ function getImportBindingNames(importDeclaration) {
83
+ const bindings = [];
84
+ const defaultImport = importDeclaration.getDefaultImport();
85
+ if (defaultImport) bindings.push(defaultImport.getText());
86
+ const namespaceImport = importDeclaration.getNamespaceImport();
87
+ if (namespaceImport) bindings.push(namespaceImport.getText());
88
+ for (const namedImport of importDeclaration.getNamedImports()) bindings.push(namedImport.getAliasNode()?.getText() ?? namedImport.getName());
89
+ return bindings;
90
+ }
91
+ function importHasBinding(importDeclaration, bindingName) {
92
+ if (importDeclaration.getDefaultImport()?.getText() === bindingName) return true;
93
+ if (importDeclaration.getNamespaceImport()?.getText() === bindingName) return true;
94
+ return importDeclaration.getNamedImports().some((namedImport) => {
95
+ return (namedImport.getAliasNode()?.getText() ?? namedImport.getName()) === bindingName;
96
+ });
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
+ }
108
+ function upsertStatement(existingFile, generatedStatement) {
109
+ if (Node.isVariableStatement(generatedStatement)) {
110
+ upsertVariableStatement(existingFile, generatedStatement);
111
+ return;
112
+ }
113
+ if (Node.isFunctionDeclaration(generatedStatement)) {
114
+ upsertNamedStatement(existingFile, generatedStatement, (sourceFile, name) => sourceFile.getFunction(name));
115
+ return;
116
+ }
117
+ if (Node.isClassDeclaration(generatedStatement)) {
118
+ upsertNamedStatement(existingFile, generatedStatement, (sourceFile, name) => sourceFile.getClass(name));
119
+ return;
120
+ }
121
+ if (Node.isInterfaceDeclaration(generatedStatement)) {
122
+ upsertNamedStatement(existingFile, generatedStatement, (sourceFile, name) => sourceFile.getInterface(name));
123
+ return;
124
+ }
125
+ if (Node.isTypeAliasDeclaration(generatedStatement)) {
126
+ upsertNamedStatement(existingFile, generatedStatement, (sourceFile, name) => sourceFile.getTypeAlias(name));
127
+ return;
128
+ }
129
+ if (Node.isEnumDeclaration(generatedStatement)) {
130
+ upsertNamedStatement(existingFile, generatedStatement, (sourceFile, name) => sourceFile.getEnum(name));
131
+ return;
132
+ }
133
+ appendUniqueStatement(existingFile, generatedStatement);
134
+ }
135
+ function upsertVariableStatement(existingFile, generatedStatement) {
136
+ if (!Node.isVariableStatement(generatedStatement)) return;
137
+ const generatedDeclarations = generatedStatement.getDeclarations();
138
+ if (!generatedDeclarations.length) {
139
+ appendUniqueStatement(existingFile, generatedStatement);
140
+ return;
141
+ }
142
+ const existingStatements = /* @__PURE__ */ new Set();
143
+ for (const generatedDeclaration of generatedDeclarations) {
144
+ let existingDeclaration = existingFile.getVariableDeclaration(generatedDeclaration.getName());
145
+ if (!existingDeclaration) {
146
+ existingDeclaration = findExistingDeclarationByEntitySignature(existingFile, generatedDeclaration);
147
+ if (existingDeclaration) generatedDeclaration.rename(existingDeclaration.getName());
148
+ }
149
+ if (!existingDeclaration) continue;
150
+ const existingStatement = existingDeclaration.getFirstAncestorByKind(SyntaxKind.VariableStatement);
151
+ if (existingStatement) existingStatements.add(existingStatement);
152
+ }
153
+ if (!existingStatements.size) {
154
+ appendUniqueStatement(existingFile, generatedStatement);
155
+ return;
156
+ }
157
+ const [firstExistingStatement, ...remainingStatements] = [...existingStatements];
158
+ if (firstExistingStatement) firstExistingStatement.replaceWithText(buildReplacementStatementText(firstExistingStatement, generatedStatement));
159
+ for (const statement of remainingStatements) statement.remove();
160
+ }
161
+ function findExistingDeclarationByEntitySignature(existingFile, generatedDeclaration) {
162
+ const generatedSignature = getVariableDeclarationEntitySignature(generatedDeclaration);
163
+ if (!generatedSignature) return;
164
+ const matchingDeclarations = existingFile.getVariableDeclarations().filter((declaration) => getVariableDeclarationEntitySignature(declaration) === generatedSignature);
165
+ if (!matchingDeclarations.length) return;
166
+ return matchingDeclarations.find((declaration) => declaration.getFirstAncestorByKind(SyntaxKind.VariableStatement)?.hasExportKeyword()) ?? matchingDeclarations[0];
167
+ }
168
+ function getVariableDeclarationEntitySignature(declaration) {
169
+ const initializer = declaration.getInitializer();
170
+ if (!initializer || !Node.isCallExpression(initializer)) return;
171
+ const expression = initializer.getExpression();
172
+ if (!Node.isIdentifier(expression)) return;
173
+ const args = initializer.getArguments();
174
+ if (!args.length || !Node.isObjectLiteralExpression(args[0])) return;
175
+ const factoryName = expression.getText();
176
+ const entityId = readEntityId(args[0], factoryName);
177
+ if (!entityId) return;
178
+ return `${factoryName}:${entityId}`;
179
+ }
180
+ function readEntityId(configObject, factoryName) {
181
+ const idProperty = configObject.getProperty("id");
182
+ if (idProperty && Node.isPropertyAssignment(idProperty)) {
183
+ const idInitializer = idProperty.getInitializer();
184
+ if (idInitializer && Node.isStringLiteral(idInitializer)) return idInitializer.getLiteralValue();
185
+ }
186
+ if (factoryName === "statusComponent") {
187
+ const typeProperty = configObject.getProperty("type");
188
+ if (typeProperty && Node.isPropertyAssignment(typeProperty)) {
189
+ const typeInitializer = typeProperty.getInitializer();
190
+ if (typeInitializer && Node.isStringLiteral(typeInitializer)) return typeInitializer.getLiteralValue();
191
+ }
192
+ }
193
+ if (factoryName === "functionTool") {
194
+ const nameProperty = configObject.getProperty("name");
195
+ if (nameProperty && Node.isPropertyAssignment(nameProperty)) {
196
+ const nameInitializer = nameProperty.getInitializer();
197
+ if (nameInitializer && Node.isStringLiteral(nameInitializer)) return nameInitializer.getLiteralValue();
198
+ }
199
+ }
200
+ }
201
+ function upsertNamedStatement(existingFile, generatedStatement, finder) {
202
+ const statementName = Node.isFunctionDeclaration(generatedStatement) || Node.isClassDeclaration(generatedStatement) || Node.isInterfaceDeclaration(generatedStatement) || Node.isTypeAliasDeclaration(generatedStatement) || Node.isEnumDeclaration(generatedStatement) ? generatedStatement.getName() : void 0;
203
+ if (!statementName) {
204
+ appendUniqueStatement(existingFile, generatedStatement);
205
+ return;
206
+ }
207
+ const existingStatement = finder(existingFile, statementName);
208
+ if (!existingStatement) {
209
+ appendUniqueStatement(existingFile, generatedStatement);
210
+ return;
211
+ }
212
+ existingStatement.replaceWithText(buildReplacementStatementText(existingStatement, generatedStatement));
213
+ }
214
+ function appendUniqueStatement(existingFile, generatedStatement) {
215
+ const statementText = generatedStatement.getText();
216
+ if (existingFile.getStatements().some((statement) => statement.getText() === statementText)) return;
217
+ existingFile.addStatements([statementText]);
218
+ }
219
+ function buildReplacementStatementText(existingStatement, generatedStatement) {
220
+ return withPreservedLeadingComments(existingStatement, alignStatementOrdering(existingStatement, generatedStatement));
221
+ }
222
+ function alignStatementOrdering(existingStatement, generatedStatement) {
223
+ if (Node.isVariableStatement(existingStatement) && Node.isVariableStatement(generatedStatement)) return alignVariableStatementOrdering(existingStatement, generatedStatement);
224
+ return generatedStatement.getText();
225
+ }
226
+ function alignVariableStatementOrdering(existingStatement, generatedStatement) {
227
+ generatedStatement.setIsExported(existingStatement.isExported());
228
+ const generatedText = generatedStatement.getText();
229
+ const generatedStatementStart = generatedStatement.getStart();
230
+ const existingDeclarationsByName = new Map(existingStatement.getDeclarations().map((declaration) => [declaration.getName(), declaration]));
231
+ const replacements = [];
232
+ for (const generatedDeclaration of generatedStatement.getDeclarations()) {
233
+ const existingDeclaration = existingDeclarationsByName.get(generatedDeclaration.getName());
234
+ if (!existingDeclaration) continue;
235
+ const generatedInitializer = generatedDeclaration.getInitializer();
236
+ const existingInitializer = existingDeclaration.getInitializer();
237
+ if (!generatedInitializer || !existingInitializer) continue;
238
+ const alignedInitializerText = alignExpressionText(existingInitializer, generatedInitializer);
239
+ if (alignedInitializerText === generatedInitializer.getText()) continue;
240
+ replacements.push({
241
+ start: generatedInitializer.getStart() - generatedStatementStart,
242
+ end: generatedInitializer.getEnd() - generatedStatementStart,
243
+ text: alignedInitializerText
244
+ });
245
+ }
246
+ return applyTextReplacements(generatedText, replacements);
247
+ }
248
+ function alignExpressionText(existingExpression, generatedExpression) {
249
+ if (!existingExpression) return generatedExpression.getText();
250
+ if (Node.isObjectLiteralExpression(existingExpression) && Node.isObjectLiteralExpression(generatedExpression)) return alignObjectLiteralText(existingExpression, generatedExpression);
251
+ if (Node.isArrayLiteralExpression(existingExpression) && Node.isArrayLiteralExpression(generatedExpression)) return alignArrayLiteralText(existingExpression, generatedExpression);
252
+ if (Node.isArrowFunction(existingExpression) && Node.isArrowFunction(generatedExpression)) return alignArrowFunctionText(existingExpression, generatedExpression);
253
+ if (Node.isCallExpression(existingExpression) && Node.isCallExpression(generatedExpression)) return alignCallExpressionText(existingExpression, generatedExpression);
254
+ if (Node.isParenthesizedExpression(existingExpression) && Node.isParenthesizedExpression(generatedExpression)) return `(${alignExpressionText(existingExpression.getExpression(), generatedExpression.getExpression())})`;
255
+ return generatedExpression.getText();
256
+ }
257
+ function alignCallExpressionText(existingCall, generatedCall) {
258
+ if (!Node.isCallExpression(existingCall) || !Node.isCallExpression(generatedCall)) return generatedCall.getText();
259
+ const generatedText = generatedCall.getText();
260
+ const generatedCallStart = generatedCall.getStart();
261
+ const existingArguments = existingCall.getArguments();
262
+ const generatedArguments = generatedCall.getArguments();
263
+ const replacements = [];
264
+ for (const [index, generatedArgument] of generatedArguments.entries()) {
265
+ const existingArgument = existingArguments[index];
266
+ if (!existingArgument) continue;
267
+ const alignedArgumentText = alignExpressionText(existingArgument, generatedArgument);
268
+ if (alignedArgumentText === generatedArgument.getText()) continue;
269
+ replacements.push({
270
+ start: generatedArgument.getStart() - generatedCallStart,
271
+ end: generatedArgument.getEnd() - generatedCallStart,
272
+ text: alignedArgumentText
273
+ });
274
+ }
275
+ return applyTextReplacements(generatedText, replacements);
276
+ }
277
+ function alignArrowFunctionText(existingArrow, generatedArrow) {
278
+ if (!Node.isArrowFunction(existingArrow) || !Node.isArrowFunction(generatedArrow)) return generatedArrow.getText();
279
+ const existingBody = existingArrow.getBody();
280
+ const generatedBody = generatedArrow.getBody();
281
+ if (!Node.isExpression(existingBody) || !Node.isExpression(generatedBody)) return generatedArrow.getText();
282
+ const alignedBodyText = alignExpressionText(existingBody, generatedBody);
283
+ if (alignedBodyText === generatedBody.getText()) return generatedArrow.getText();
284
+ return applyTextReplacements(generatedArrow.getText(), [{
285
+ start: generatedBody.getStart() - generatedArrow.getStart(),
286
+ end: generatedBody.getEnd() - generatedArrow.getStart(),
287
+ text: alignedBodyText
288
+ }]);
289
+ }
290
+ function alignObjectLiteralText(existingObject, generatedObject) {
291
+ const propertyTexts = orderObjectProperties(existingObject.getProperties(), generatedObject.getProperties()).map(({ existingProperty, generatedProperty }) => {
292
+ if (!existingProperty) return generatedProperty.getText();
293
+ return withPreservedLeadingComments(existingProperty, alignObjectPropertyText(existingProperty, generatedProperty));
294
+ });
295
+ return formatCollectionLiteralText(generatedObject.getText(), propertyTexts, "{", "}");
296
+ }
297
+ function alignObjectPropertyText(existingProperty, generatedProperty) {
298
+ const text = generatedProperty.getText();
299
+ if (!Node.isPropertyAssignment(generatedProperty)) return text;
300
+ const generatedInitializer = generatedProperty.getInitializer();
301
+ if (!generatedInitializer) return text;
302
+ const alignedInitializerText = alignExpressionText(Node.isPropertyAssignment(existingProperty) ? existingProperty.getInitializer() : void 0, generatedInitializer);
303
+ return `${generatedProperty.getNameNode().getText()}: ${alignedInitializerText}`;
304
+ }
305
+ function alignArrayLiteralText(existingArray, generatedArray) {
306
+ if (!Node.isArrayLiteralExpression(existingArray) || !Node.isArrayLiteralExpression(generatedArray)) return generatedArray.getText();
307
+ const elementTexts = orderArrayElements(existingArray.getElements(), generatedArray.getElements()).map(({ existingElement, generatedElement }) => alignExpressionText(existingElement, generatedElement));
308
+ return formatCollectionLiteralText(generatedArray.getText(), elementTexts, "[", "]");
309
+ }
310
+ function orderObjectProperties(existingProperties, generatedProperties) {
311
+ return orderNodesBySignature(existingProperties, generatedProperties, getObjectPropertyKey, getObjectPropertyKey).map(({ existingNode, generatedNode }) => ({
312
+ existingProperty: existingNode,
313
+ generatedProperty: generatedNode
314
+ }));
315
+ }
316
+ function orderArrayElements(existingElements, generatedElements) {
317
+ return orderNodesBySignature(existingElements, generatedElements, getArrayElementSignature, getArrayElementSignature).map(({ existingNode, generatedNode }) => ({
318
+ existingElement: existingNode,
319
+ generatedElement: generatedNode
320
+ }));
321
+ }
322
+ function orderNodesBySignature(existingNodes, generatedNodes, getExistingSignature, getGeneratedSignature) {
323
+ const generatedEntries = generatedNodes.map((generatedNode) => ({
324
+ generatedNode,
325
+ signature: getGeneratedSignature(generatedNode)
326
+ }));
327
+ const usedGeneratedIndexes = /* @__PURE__ */ new Set();
328
+ const ordered = [];
329
+ for (const existingNode of existingNodes) {
330
+ const existingSignature = getExistingSignature(existingNode);
331
+ if (!existingSignature) continue;
332
+ const generatedIndex = generatedEntries.findIndex((entry, index) => !usedGeneratedIndexes.has(index) && entry.signature === existingSignature);
333
+ if (generatedIndex === -1) continue;
334
+ const generatedEntry = generatedEntries[generatedIndex];
335
+ if (!generatedEntry) continue;
336
+ usedGeneratedIndexes.add(generatedIndex);
337
+ ordered.push({
338
+ existingNode,
339
+ generatedNode: generatedEntry.generatedNode
340
+ });
341
+ }
342
+ for (const [index, generatedEntry] of generatedEntries.entries()) {
343
+ if (usedGeneratedIndexes.has(index)) continue;
344
+ ordered.push({ generatedNode: generatedEntry.generatedNode });
345
+ }
346
+ return ordered;
347
+ }
348
+ function getObjectPropertyKey(property) {
349
+ if (Node.isPropertyAssignment(property) || Node.isShorthandPropertyAssignment(property) || Node.isMethodDeclaration(property) || Node.isGetAccessorDeclaration(property) || Node.isSetAccessorDeclaration(property)) return property.getName();
350
+ if (Node.isSpreadAssignment(property)) return `...${property.getExpression().getText()}`;
351
+ }
352
+ function getArrayElementSignature(node) {
353
+ if (Node.isIdentifier(node)) return `id:${node.getText()}`;
354
+ if (Node.isStringLiteral(node)) return `str:${node.getLiteralValue()}`;
355
+ if (Node.isObjectLiteralExpression(node)) {
356
+ const objectId = readStringLiteralObjectProperty(node, "id") || readStringLiteralObjectProperty(node, "type") || readStringLiteralObjectProperty(node, "name");
357
+ if (objectId) return `obj:${objectId}`;
358
+ }
359
+ if (Node.isCallExpression(node)) {
360
+ const expression = node.getExpression();
361
+ if (Node.isPropertyAccessExpression(expression) && expression.getName() === "with") return `with:${expression.getExpression().getText()}`;
362
+ }
363
+ return node.getText();
364
+ }
365
+ function readStringLiteralObjectProperty(objectLiteral, propertyName) {
366
+ const property = objectLiteral.getProperty(propertyName);
367
+ if (!property || !Node.isPropertyAssignment(property)) return;
368
+ const initializer = property.getInitializer();
369
+ if (!initializer || !Node.isStringLiteral(initializer)) return;
370
+ return initializer.getLiteralValue();
371
+ }
372
+ function formatCollectionLiteralText(originalText, itemTexts, openToken, closeToken) {
373
+ if (originalText.includes("\n")) return `${openToken}\n${itemTexts.map((line) => {
374
+ return line.replaceAll(/^\s+\*/gm, " *");
375
+ }).join(",\n")}${closeToken}`;
376
+ const openingWithSpacing = originalText.startsWith(`${openToken} `) ? `${openToken} ` : openToken;
377
+ const closingWithSpacing = originalText.endsWith(` ${closeToken}`) ? ` ${closeToken}` : closeToken;
378
+ return `${openingWithSpacing}${itemTexts.join(", ")}${closingWithSpacing}`;
379
+ }
380
+ function applyTextReplacements(sourceText, replacements) {
381
+ if (!replacements.length) return sourceText;
382
+ let nextText = sourceText;
383
+ const replacementsInDescendingOrder = [...replacements].sort((a, b) => b.start - a.start);
384
+ for (const replacement of replacementsInDescendingOrder) nextText = nextText.slice(0, replacement.start) + replacement.text + nextText.slice(replacement.end);
385
+ return nextText;
386
+ }
387
+ function withPreservedLeadingComments(existingStatement, replacementText) {
388
+ const leadingComments = existingStatement.getLeadingCommentRanges().map((comment) => comment.getText()).join("\n");
389
+ if (!leadingComments) return replacementText;
390
+ return `${leadingComments}\n${replacementText}`;
391
+ }
392
+ function dedupeConsecutiveIdenticalSingleLineComments(content) {
393
+ const lines = content.split("\n");
394
+ const deduped = [];
395
+ for (const line of lines) {
396
+ const trimmedLine = line.trim();
397
+ const previousTrimmedLine = deduped.at(-1)?.trim();
398
+ if (trimmedLine.startsWith("//") && previousTrimmedLine?.startsWith("//") && trimmedLine === previousTrimmedLine) continue;
399
+ deduped.push(line);
400
+ }
401
+ return deduped.join("\n");
402
+ }
403
+
404
+ //#endregion
405
+ export { mergeGeneratedModule };
@@ -0,0 +1,235 @@
1
+ import path from "node:path";
2
+ import { IndentationText, NewLineKind, Project, QuoteKind, SyntaxKind, VariableDeclarationKind } from "ts-morph";
3
+ import { jsonSchemaToZod } from "json-schema-to-zod";
4
+
5
+ //#region src/commands/pull-v4/utils.ts
6
+ function createInMemoryProject() {
7
+ return new Project({
8
+ useInMemoryFileSystem: true,
9
+ skipLoadingLibFiles: true,
10
+ manipulationSettings: {
11
+ indentationText: IndentationText.TwoSpaces,
12
+ quoteKind: QuoteKind.Single,
13
+ newLineKind: NewLineKind.LineFeed,
14
+ useTrailingCommas: true
15
+ }
16
+ });
17
+ }
18
+ /**
19
+ * Create variable in following pattern
20
+ *
21
+ * (export)? const VARIABLE_NAME = (new)?IMPORT_NAME({})
22
+ */
23
+ function addFactoryConfigVariable({ sourceFile, importName, variableName, isExported, syntaxKind = SyntaxKind.CallExpression }) {
24
+ const initializer = `${syntaxKind === SyntaxKind.NewExpression ? "new " : ""}${importName}({})`;
25
+ const [declaration] = sourceFile.addVariableStatement({
26
+ declarationKind: VariableDeclarationKind.Const,
27
+ isExported,
28
+ declarations: [{
29
+ name: variableName,
30
+ initializer
31
+ }]
32
+ }).getDeclarations();
33
+ const [configArg] = declaration.getInitializerIfKindOrThrow(syntaxKind).getArguments();
34
+ return { configObject: configArg.asKindOrThrow(SyntaxKind.ObjectLiteralExpression) };
35
+ }
36
+ function createFactoryDefinition({ importName, variableName: name, fileName = "definition.ts", moduleSpecifier = "@inkeep/agents-sdk", syntaxKind }) {
37
+ const sourceFile = createInMemoryProject().createSourceFile(fileName, "", { overwrite: true });
38
+ sourceFile.addImportDeclaration({
39
+ namedImports: [importName],
40
+ moduleSpecifier
41
+ });
42
+ const { configObject } = addFactoryConfigVariable({
43
+ sourceFile,
44
+ importName,
45
+ variableName: name,
46
+ isExported: true,
47
+ syntaxKind
48
+ });
49
+ return {
50
+ sourceFile,
51
+ configObject
52
+ };
53
+ }
54
+ function toCamelCase(input) {
55
+ const result = input.replace(/[^a-zA-Z0-9](.)/g, (_, char) => char.toUpperCase()).replace(/^[0-9]/, "_$&");
56
+ return result.charAt(0).toLowerCase() + result.slice(1);
57
+ }
58
+ function createUniqueReferenceName(baseName, reservedNames, conflictSuffix) {
59
+ if (!reservedNames.has(baseName)) {
60
+ reservedNames.add(baseName);
61
+ return baseName;
62
+ }
63
+ const baseCandidate = `${baseName}${conflictSuffix}`;
64
+ if (!reservedNames.has(baseCandidate)) {
65
+ reservedNames.add(baseCandidate);
66
+ return baseCandidate;
67
+ }
68
+ let index = 2;
69
+ while (reservedNames.has(`${baseCandidate}${index}`)) index += 1;
70
+ const uniqueName = `${baseCandidate}${index}`;
71
+ reservedNames.add(uniqueName);
72
+ return uniqueName;
73
+ }
74
+ function resolveReferenceName(referenceId, referenceOverrides) {
75
+ for (const overrideMap of referenceOverrides) {
76
+ const overrideName = overrideMap?.[referenceId];
77
+ if (overrideName) return overrideName;
78
+ }
79
+ return toCamelCase(referenceId);
80
+ }
81
+ function convertJsonSchemaToZodSafe(schema, options) {
82
+ if (!isPlainObject(schema)) {
83
+ console.warn("Schema conversion skipped: non-object schema provided, using z.any()");
84
+ return "z.any()";
85
+ }
86
+ try {
87
+ return jsonSchemaToZod(schema, options?.conversionOptions);
88
+ } catch (error) {
89
+ console.warn(`Schema conversion failed: ${error instanceof Error ? error.message : String(error)}. Falling back to z.any()`);
90
+ return "z.any()";
91
+ }
92
+ }
93
+ function isPlainObject(value) {
94
+ return typeof value === "object" && value !== null && !Array.isArray(value);
95
+ }
96
+ const QUOTE = Object.freeze({
97
+ single: "'",
98
+ double: "\"",
99
+ template: "`"
100
+ });
101
+ const TEMPLATE_VARIABLE_REGEX = /\{\{(?!\{)(?<variableName>[^{}]+)}}/g;
102
+ function formatStringLiteral(value) {
103
+ const hasSingleQuote = value.includes(QUOTE.single);
104
+ const hasDoubleQuote = value.includes(QUOTE.double);
105
+ return escapeStringLiteral(value, value.includes("\n") || value.includes("${") || hasSingleQuote && hasDoubleQuote ? QUOTE.template : hasSingleQuote ? QUOTE.double : QUOTE.single);
106
+ }
107
+ function collectTemplateVariableNames(value) {
108
+ const variables = [];
109
+ for (const match of value.matchAll(TEMPLATE_VARIABLE_REGEX)) {
110
+ const variableName = match.groups?.variableName?.trim();
111
+ if (variableName) variables.push(variableName);
112
+ }
113
+ return variables;
114
+ }
115
+ function formatTemplate(value, references) {
116
+ if (!value.length) return value;
117
+ let didReplace = false;
118
+ const rewrittenValue = value.replace(TEMPLATE_VARIABLE_REGEX, (match, ...args) => {
119
+ const maybeGroups = args.at(-1);
120
+ const variableName = isPlainObject(maybeGroups) && typeof maybeGroups.variableName === "string" ? maybeGroups.variableName.trim() : void 0;
121
+ if (!variableName) return match;
122
+ if (variableName.startsWith("headers.")) {
123
+ const headerPath = variableName.slice(8);
124
+ if (!headerPath || !references.headersReference) return match;
125
+ didReplace = true;
126
+ return `\${${references.headersReference}.toTemplate(${JSON.stringify(headerPath)})}`;
127
+ }
128
+ if (!references.contextReference) return match;
129
+ didReplace = true;
130
+ return `\${${references.contextReference}.toTemplate(${JSON.stringify(variableName)})}`;
131
+ });
132
+ return didReplace ? rewrittenValue : value;
133
+ }
134
+ function escapeStringLiteral(value, quote) {
135
+ return [
136
+ quote,
137
+ value.replaceAll("\\", "\\\\").replaceAll(quote, `\\${quote}`),
138
+ quote
139
+ ].join("");
140
+ }
141
+ function formatPropertyName(key) {
142
+ if (/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key)) return key;
143
+ return formatStringLiteral(key);
144
+ }
145
+ function formatInlineLiteral(value) {
146
+ if (typeof value === "string") return formatStringLiteral(value);
147
+ if (typeof value === "number" || typeof value === "bigint") return String(value);
148
+ if (typeof value === "boolean") return value ? "true" : "false";
149
+ if (value === null) return "null";
150
+ if (Array.isArray(value)) return `[${value.map((item) => formatInlineLiteral(item)).join(", ")}]`;
151
+ if (isPlainObject(value)) {
152
+ const entries = Object.entries(value).filter(([, entryValue]) => entryValue !== void 0);
153
+ if (!entries.length) return "{}";
154
+ return `{ ${entries.map(([key, entryValue]) => `${formatPropertyName(key)}: ${formatInlineLiteral(entryValue)}`).join(", ")} }`;
155
+ }
156
+ return "undefined";
157
+ }
158
+ function addReferenceGetterProperty(configObject, key, refs) {
159
+ configObject.addPropertyAssignment({
160
+ name: key,
161
+ initializer: "() => []"
162
+ }).getInitializerIfKindOrThrow(SyntaxKind.ArrowFunction).getBody().asKindOrThrow(SyntaxKind.ArrayLiteralExpression).addElements(refs);
163
+ }
164
+ function addObjectEntries(target, value) {
165
+ for (const [key, entryValue] of Object.entries(value)) {
166
+ if (entryValue === void 0) continue;
167
+ if (isPlainObject(entryValue)) {
168
+ addObjectEntries(target.addPropertyAssignment({
169
+ name: formatPropertyName(key),
170
+ initializer: "{}"
171
+ }).getInitializerIfKindOrThrow(SyntaxKind.ObjectLiteralExpression), entryValue);
172
+ continue;
173
+ }
174
+ target.addPropertyAssignment({
175
+ name: formatPropertyName(key),
176
+ initializer: formatInlineLiteral(entryValue)
177
+ });
178
+ }
179
+ }
180
+ function addStringProperty(configObject, key, value) {
181
+ configObject.addPropertyAssignment({
182
+ name: key,
183
+ initializer: formatStringLiteral(value)
184
+ });
185
+ }
186
+ function addValueToObject(obj, key, value) {
187
+ if (value === void 0) return;
188
+ if (isPlainObject(value)) {
189
+ const child = obj.addPropertyAssignment({
190
+ name: formatPropertyName(key),
191
+ initializer: "{}"
192
+ }).getInitializerIfKindOrThrow(SyntaxKind.ObjectLiteralExpression);
193
+ for (const [k, v] of Object.entries(value)) addValueToObject(child, k, v);
194
+ return;
195
+ }
196
+ if (Array.isArray(value)) {
197
+ const arr = obj.addPropertyAssignment({
198
+ name: formatPropertyName(key),
199
+ initializer: "[]"
200
+ }).getInitializerIfKindOrThrow(SyntaxKind.ArrayLiteralExpression);
201
+ for (const item of value) addValueToArray(arr, item);
202
+ return;
203
+ }
204
+ obj.addPropertyAssignment({
205
+ name: formatPropertyName(key),
206
+ initializer: formatInlineLiteral(value)
207
+ });
208
+ }
209
+ function addValueToArray(arr, value) {
210
+ if (isPlainObject(value)) {
211
+ const child = arr.addElement("{}").asKindOrThrow(SyntaxKind.ObjectLiteralExpression);
212
+ for (const [k, v] of Object.entries(value)) addValueToObject(child, k, v);
213
+ return;
214
+ }
215
+ if (Array.isArray(value)) {
216
+ const child = arr.addElement("[]").asKindOrThrow(SyntaxKind.ArrayLiteralExpression);
217
+ for (const item of value) addValueToArray(child, item);
218
+ return;
219
+ }
220
+ arr.addElement(formatInlineLiteral(value));
221
+ }
222
+ async function expectSnapshots(definitionV4) {
223
+ const { currentTestName, snapshotState } = expect.getState();
224
+ const snapshotDir = path.basename(snapshotState.testFilePath).replace("-generator.test.ts", "");
225
+ await expect(definitionV4).toMatchFileSnapshot(`__snapshots__/${snapshotDir}/${currentTestName}-v4.txt`);
226
+ }
227
+ function convertNullToUndefined(v) {
228
+ return v == null ? void 0 : v;
229
+ }
230
+ function hasReferences(references) {
231
+ return Array.isArray(references) && references.length > 0;
232
+ }
233
+
234
+ //#endregion
235
+ export { TEMPLATE_VARIABLE_REGEX, addFactoryConfigVariable, addObjectEntries, addReferenceGetterProperty, addStringProperty, addValueToObject, collectTemplateVariableNames, convertJsonSchemaToZodSafe, convertNullToUndefined, createFactoryDefinition, createInMemoryProject, createUniqueReferenceName, expectSnapshots, formatInlineLiteral, formatPropertyName, formatStringLiteral, formatTemplate, hasReferences, isPlainObject, resolveReferenceName, toCamelCase };
@@ -4,10 +4,10 @@ import { initializeCommand } from "../utils/cli-pipeline.js";
4
4
  import { performBackgroundVersionCheck } from "../utils/background-version-check.js";
5
5
  import { loadProject } from "../utils/project-loader.js";
6
6
  import { loadEnvironmentCredentials } from "../utils/environment-loader.js";
7
- import { existsSync, readdirSync, statSync } from "node:fs";
8
7
  import { basename, dirname, join, resolve } from "node:path";
9
8
  import * as p from "@clack/prompts";
10
9
  import chalk from "chalk";
10
+ import { existsSync, readdirSync, statSync } from "node:fs";
11
11
 
12
12
  //#region src/commands/push.ts
13
13
  async function pushCommand(options) {
@@ -1,4 +1,4 @@
1
- import { checkForUpdate, getChangelogUrl } from "../utils/version-check.js";
1
+ import { PACKAGE_CHANGELOG, checkForUpdate } from "../utils/version-check.js";
2
2
  import { detectPackageManager, executeUpdate } from "../utils/package-manager.js";
3
3
  import * as p from "@clack/prompts";
4
4
  import chalk from "chalk";
@@ -29,7 +29,7 @@ async function updateCommand(options = {}) {
29
29
  }
30
30
  if (!versionInfo.needsUpdate && options.force) console.log(chalk.yellow("\n⚠️ Forcing reinstall of current version..."));
31
31
  console.log(chalk.cyan("\n📖 Changelog:"));
32
- console.log(chalk.gray(` • ${getChangelogUrl()}`));
32
+ console.log(chalk.gray(` • ${PACKAGE_CHANGELOG}`));
33
33
  s.start("Detecting package manager...");
34
34
  const detectedManager = await detectPackageManager();
35
35
  s.stop();