@inkeep/agents-cli 0.33.0 → 0.33.2

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 (2) hide show
  1. package/dist/index.js +1187 -483
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -238,7 +238,8 @@ var init_defaults = __esm({
238
238
  // CONVERSATION_HISTORY_MAX_OUTPUT_TOKENS_DEFAULT: Maximum number of tokens from previous conversation messages
239
239
  // to include in the LLM prompt. Prevents excessive token usage while maintaining relevant conversation context.
240
240
  // Messages exceeding this limit are truncated from the beginning of the conversation.
241
- CONVERSATION_HISTORY_MAX_OUTPUT_TOKENS_DEFAULT: 4e3
241
+ // Increased from 4,000 to 8,000 to accommodate tool results in conversation history.
242
+ CONVERSATION_HISTORY_MAX_OUTPUT_TOKENS_DEFAULT: 8e3
242
243
  };
243
244
  }
244
245
  });
@@ -1693,9 +1694,13 @@ var init_schema = __esm({
1693
1694
  ...agentScoped,
1694
1695
  ...uiProperties,
1695
1696
  prompt: text("prompt").notNull(),
1696
- conversationHistoryConfig: jsonb(
1697
- "conversation_history_config"
1698
- ).$type(),
1697
+ conversationHistoryConfig: jsonb("conversation_history_config").$type().notNull().default({
1698
+ mode: "full",
1699
+ limit: 50,
1700
+ maxOutputTokens: 4e3,
1701
+ includeInternal: false,
1702
+ messageTypes: ["chat", "tool-result"]
1703
+ }),
1699
1704
  models: jsonb("models").$type(),
1700
1705
  stopWhen: jsonb("stop_when").$type(),
1701
1706
  ...timestamps
@@ -14067,7 +14072,7 @@ var require_typescript = __commonJS({
14067
14072
  SymbolDisplayPartKind: () => SymbolDisplayPartKind,
14068
14073
  SymbolFlags: () => SymbolFlags,
14069
14074
  SymbolFormatFlags: () => SymbolFormatFlags,
14070
- SyntaxKind: () => SyntaxKind,
14075
+ SyntaxKind: () => SyntaxKind2,
14071
14076
  Ternary: () => Ternary,
14072
14077
  ThrottledCancellationToken: () => ThrottledCancellationToken,
14073
14078
  TokenClass: () => TokenClass,
@@ -17954,7 +17959,7 @@ Node ${formatSyntaxKind(node.kind)} was unexpected.`,
17954
17959
  function formatSyntaxKind(kind) {
17955
17960
  return formatEnum(
17956
17961
  kind,
17957
- SyntaxKind,
17962
+ SyntaxKind2,
17958
17963
  /*isFlags*/
17959
17964
  false
17960
17965
  );
@@ -19402,7 +19407,7 @@ ${lanes.join("\n")}
19402
19407
  })(tracingEnabled || (tracingEnabled = {}));
19403
19408
  var startTracing = tracingEnabled.startTracing;
19404
19409
  var dumpTracingLegend = tracingEnabled.dumpLegend;
19405
- var SyntaxKind = /* @__PURE__ */ ((SyntaxKind5) => {
19410
+ var SyntaxKind2 = /* @__PURE__ */ ((SyntaxKind5) => {
19406
19411
  SyntaxKind5[SyntaxKind5["Unknown"] = 0] = "Unknown";
19407
19412
  SyntaxKind5[SyntaxKind5["EndOfFileToken"] = 1] = "EndOfFileToken";
19408
19413
  SyntaxKind5[SyntaxKind5["SingleLineCommentTrivia"] = 2] = "SingleLineCommentTrivia";
@@ -19908,7 +19913,7 @@ ${lanes.join("\n")}
19908
19913
  /* LastKeyword */
19909
19914
  ] = "LastContextualKeyword";
19910
19915
  return SyntaxKind5;
19911
- })(SyntaxKind || {});
19916
+ })(SyntaxKind2 || {});
19912
19917
  var NodeFlags = /* @__PURE__ */ ((NodeFlags3) => {
19913
19918
  NodeFlags3[NodeFlags3["None"] = 0] = "None";
19914
19919
  NodeFlags3[NodeFlags3["Let"] = 1] = "Let";
@@ -35992,7 +35997,7 @@ ${lanes.join("\n")}
35992
35997
  this.checker = checker;
35993
35998
  }
35994
35999
  }
35995
- function Node4(kind, pos, end) {
36000
+ function Node42(kind, pos, end) {
35996
36001
  this.pos = pos;
35997
36002
  this.end = end;
35998
36003
  this.kind = kind;
@@ -36031,11 +36036,11 @@ ${lanes.join("\n")}
36031
36036
  this.skipTrivia = skipTrivia2 || ((pos) => pos);
36032
36037
  }
36033
36038
  var objectAllocator = {
36034
- getNodeConstructor: () => Node4,
36039
+ getNodeConstructor: () => Node42,
36035
36040
  getTokenConstructor: () => Token,
36036
36041
  getIdentifierConstructor: () => Identifier2,
36037
- getPrivateIdentifierConstructor: () => Node4,
36038
- getSourceFileConstructor: () => Node4,
36042
+ getPrivateIdentifierConstructor: () => Node42,
36043
+ getSourceFileConstructor: () => Node42,
36039
36044
  getSymbolConstructor: () => Symbol4,
36040
36045
  getTypeConstructor: () => Type3,
36041
36046
  getSignatureConstructor: () => Signature2,
@@ -209570,7 +209575,7 @@ ${options.prefix}` : "\n" : options.prefix
209570
209575
  SymbolDisplayPartKind: () => SymbolDisplayPartKind,
209571
209576
  SymbolFlags: () => SymbolFlags,
209572
209577
  SymbolFormatFlags: () => SymbolFormatFlags,
209573
- SyntaxKind: () => SyntaxKind,
209578
+ SyntaxKind: () => SyntaxKind2,
209574
209579
  Ternary: () => Ternary,
209575
209580
  ThrottledCancellationToken: () => ThrottledCancellationToken,
209576
209581
  TokenClass: () => TokenClass,
@@ -211813,7 +211818,7 @@ ${options.prefix}` : "\n" : options.prefix
211813
211818
  LogLevel: () => LogLevel2,
211814
211819
  Msg: () => Msg,
211815
211820
  OpenFileInfoTelemetryEvent: () => OpenFileInfoTelemetryEvent,
211816
- Project: () => Project2,
211821
+ Project: () => Project22,
211817
211822
  ProjectInfoTelemetryEvent: () => ProjectInfoTelemetryEvent,
211818
211823
  ProjectKind: () => ProjectKind,
211819
211824
  ProjectLanguageServiceStateEvent: () => ProjectLanguageServiceStateEvent,
@@ -213269,7 +213274,7 @@ ${options.prefix}` : "\n" : options.prefix
213269
213274
  }
213270
213275
  return !arrayIsEqualTo(imports1, imports2);
213271
213276
  }
213272
- var Project2 = class _Project {
213277
+ var Project22 = class _Project {
213273
213278
  /** @internal */
213274
213279
  constructor(projectName, projectKind, projectService, hasExplicitListOfFiles, lastFileExceededProgramSize, compilerOptions, compileOnSaveEnabled, watchOptions, directoryStructureHost, currentDirectory) {
213275
213280
  this.projectKind = projectKind;
@@ -214938,7 +214943,7 @@ ${options.prefix}` : "\n" : options.prefix
214938
214943
  return unresolvedImports || emptyArray2;
214939
214944
  });
214940
214945
  }
214941
- var InferredProject2 = class extends Project2 {
214946
+ var InferredProject2 = class extends Project22 {
214942
214947
  /** @internal */
214943
214948
  constructor(projectService, compilerOptions, watchOptions, projectRootPath, currentDirectory, typeAcquisition) {
214944
214949
  super(
@@ -215030,7 +215035,7 @@ ${options.prefix}` : "\n" : options.prefix
215030
215035
  };
215031
215036
  }
215032
215037
  };
215033
- var AuxiliaryProject = class extends Project2 {
215038
+ var AuxiliaryProject = class extends Project22 {
215034
215039
  constructor(hostProject) {
215035
215040
  super(
215036
215041
  hostProject.projectService.newAuxiliaryProjectName(),
@@ -215056,7 +215061,7 @@ ${options.prefix}` : "\n" : options.prefix
215056
215061
  return;
215057
215062
  }
215058
215063
  };
215059
- var _AutoImportProviderProject = class _AutoImportProviderProject2 extends Project2 {
215064
+ var _AutoImportProviderProject = class _AutoImportProviderProject2 extends Project22 {
215060
215065
  /** @internal */
215061
215066
  constructor(hostProject, initialRootNames, compilerOptions) {
215062
215067
  super(
@@ -215325,7 +215330,7 @@ ${options.prefix}` : "\n" : options.prefix
215325
215330
  noLib: true
215326
215331
  };
215327
215332
  var AutoImportProviderProject = _AutoImportProviderProject;
215328
- var ConfiguredProject2 = class extends Project2 {
215333
+ var ConfiguredProject2 = class extends Project22 {
215329
215334
  /** @internal */
215330
215335
  constructor(configFileName, canonicalConfigFilePath, projectService, cachedDirectoryStructureHost, pendingUpdateReason) {
215331
215336
  super(
@@ -215527,7 +215532,7 @@ ${options.prefix}` : "\n" : options.prefix
215527
215532
  );
215528
215533
  }
215529
215534
  };
215530
- var ExternalProject = class extends Project2 {
215535
+ var ExternalProject = class extends Project22 {
215531
215536
  /** @internal */
215532
215537
  constructor(externalProjectName, projectService, compilerOptions, lastFileExceededProgramSize, compileOnSaveEnabled, projectFilePath, watchOptions) {
215533
215538
  super(
@@ -219314,7 +219319,7 @@ Dynamic files must always be opened with service's current directory or service
219314
219319
  return;
219315
219320
  }
219316
219321
  if (this.host.importPlugin) {
219317
- const importPromise = Project2.importServicePluginAsync(
219322
+ const importPromise = Project22.importServicePluginAsync(
219318
219323
  pluginConfigEntry,
219319
219324
  searchPaths,
219320
219325
  this.host,
@@ -219328,7 +219333,7 @@ Dynamic files must always be opened with service's current directory or service
219328
219333
  }
219329
219334
  this.endEnablePlugin(
219330
219335
  project,
219331
- Project2.importServicePluginSync(
219336
+ Project22.importServicePluginSync(
219332
219337
  pluginConfigEntry,
219333
219338
  searchPaths,
219334
219339
  this.host,
@@ -224552,7 +224557,7 @@ Additional information: BADCLIENT: Bad error code, ${badCode} not found in range
224552
224557
  LogLevel: () => LogLevel2,
224553
224558
  Msg: () => Msg,
224554
224559
  OpenFileInfoTelemetryEvent: () => OpenFileInfoTelemetryEvent,
224555
- Project: () => Project2,
224560
+ Project: () => Project22,
224556
224561
  ProjectInfoTelemetryEvent: () => ProjectInfoTelemetryEvent,
224557
224562
  ProjectKind: () => ProjectKind,
224558
224563
  ProjectLanguageServiceStateEvent: () => ProjectLanguageServiceStateEvent,
@@ -226103,7 +226108,7 @@ var init_error = __esm({
226103
226108
  // description: "A URI reference that identifies the problem type.",
226104
226109
  // example: `${ERROR_DOCS_BASE_URL}#${code}`,
226105
226110
  // }),
226106
- status: z5.literal(errorCodeToHttpStatus[code]).openapi({
226111
+ status: z5.number().int().openapi({
226107
226112
  description: "The HTTP status code.",
226108
226113
  example: errorCodeToHttpStatus[code]
226109
226114
  }),
@@ -226534,7 +226539,7 @@ var require_codegen = __commonJS({
226534
226539
  AND: new code_1._Code("&&"),
226535
226540
  ADD: new code_1._Code("+")
226536
226541
  };
226537
- var Node3 = class {
226542
+ var Node5 = class {
226538
226543
  optimizeNodes() {
226539
226544
  return this;
226540
226545
  }
@@ -226542,7 +226547,7 @@ var require_codegen = __commonJS({
226542
226547
  return this;
226543
226548
  }
226544
226549
  };
226545
- var Def = class extends Node3 {
226550
+ var Def = class extends Node5 {
226546
226551
  constructor(varKind, name2, rhs) {
226547
226552
  super();
226548
226553
  this.varKind = varKind;
@@ -226565,7 +226570,7 @@ var require_codegen = __commonJS({
226565
226570
  return this.rhs instanceof code_1._CodeOrName ? this.rhs.names : {};
226566
226571
  }
226567
226572
  };
226568
- var Assign = class extends Node3 {
226573
+ var Assign = class extends Node5 {
226569
226574
  constructor(lhs, rhs, sideEffects) {
226570
226575
  super();
226571
226576
  this.lhs = lhs;
@@ -226595,7 +226600,7 @@ var require_codegen = __commonJS({
226595
226600
  return `${this.lhs} ${this.op}= ${this.rhs};` + _n2;
226596
226601
  }
226597
226602
  };
226598
- var Label = class extends Node3 {
226603
+ var Label = class extends Node5 {
226599
226604
  constructor(label) {
226600
226605
  super();
226601
226606
  this.label = label;
@@ -226605,7 +226610,7 @@ var require_codegen = __commonJS({
226605
226610
  return `${this.label}:` + _n2;
226606
226611
  }
226607
226612
  };
226608
- var Break = class extends Node3 {
226613
+ var Break = class extends Node5 {
226609
226614
  constructor(label) {
226610
226615
  super();
226611
226616
  this.label = label;
@@ -226616,7 +226621,7 @@ var require_codegen = __commonJS({
226616
226621
  return `break${label};` + _n2;
226617
226622
  }
226618
226623
  };
226619
- var Throw = class extends Node3 {
226624
+ var Throw = class extends Node5 {
226620
226625
  constructor(error) {
226621
226626
  super();
226622
226627
  this.error = error;
@@ -226628,7 +226633,7 @@ var require_codegen = __commonJS({
226628
226633
  return this.error.names;
226629
226634
  }
226630
226635
  };
226631
- var AnyCode = class extends Node3 {
226636
+ var AnyCode = class extends Node5 {
226632
226637
  constructor(code) {
226633
226638
  super();
226634
226639
  this.code = code;
@@ -226647,7 +226652,7 @@ var require_codegen = __commonJS({
226647
226652
  return this.code instanceof code_1._CodeOrName ? this.code.names : {};
226648
226653
  }
226649
226654
  };
226650
- var ParentNode = class extends Node3 {
226655
+ var ParentNode = class extends Node5 {
226651
226656
  constructor(nodes = []) {
226652
226657
  super();
226653
226658
  this.nodes = nodes;
@@ -234174,6 +234179,7 @@ var init_dataComponents = __esm({
234174
234179
  "use strict";
234175
234180
  init_esm_shims();
234176
234181
  init_schema();
234182
+ init_utils();
234177
234183
  init_conversations();
234178
234184
  init_props_validation();
234179
234185
  init_render_validation();
@@ -234226,7 +234232,7 @@ var init_contextCache = __esm({
234226
234232
  });
234227
234233
 
234228
234234
  // ../packages/agents-core/src/data-access/conversations.ts
234229
- import { and as and17, count as count14, desc as desc14, eq as eq17 } from "drizzle-orm";
234235
+ import { and as and17, count as count14, desc as desc14, eq as eq17, inArray as inArray4 } from "drizzle-orm";
234230
234236
  var init_conversations2 = __esm({
234231
234237
  "../packages/agents-core/src/data-access/conversations.ts"() {
234232
234238
  "use strict";
@@ -234248,7 +234254,7 @@ var init_ledgerArtifacts = __esm({
234248
234254
  });
234249
234255
 
234250
234256
  // ../packages/agents-core/src/data-access/messages.ts
234251
- import { and as and19, asc as asc2, count as count16, desc as desc15, eq as eq19, inArray as inArray4 } from "drizzle-orm";
234257
+ import { and as and19, asc as asc2, count as count16, desc as desc15, eq as eq19, inArray as inArray5 } from "drizzle-orm";
234252
234258
  var init_messages = __esm({
234253
234259
  "../packages/agents-core/src/data-access/messages.ts"() {
234254
234260
  "use strict";
@@ -235263,6 +235269,171 @@ var init_project_loader = __esm({
235263
235269
  }
235264
235270
  });
235265
235271
 
235272
+ // src/utils/json-comparator.ts
235273
+ function compareJsonObjects(obj1, obj2, options = {}) {
235274
+ const {
235275
+ ignoreArrayOrder = true,
235276
+ ignoreCase = false,
235277
+ ignoreWhitespace = false,
235278
+ ignorePaths = []
235279
+ } = options;
235280
+ const differences = [];
235281
+ const stats = {
235282
+ totalKeys: 0,
235283
+ differentKeys: 0,
235284
+ missingKeys: 0,
235285
+ extraKeys: 0
235286
+ };
235287
+ function normalizeValue(value) {
235288
+ if (typeof value === "string") {
235289
+ let normalized = value;
235290
+ if (ignoreCase) {
235291
+ normalized = normalized.toLowerCase();
235292
+ }
235293
+ if (ignoreWhitespace) {
235294
+ normalized = normalized.trim().replace(/\s+/g, " ");
235295
+ }
235296
+ return normalized;
235297
+ }
235298
+ return value;
235299
+ }
235300
+ function shouldIgnorePath(path5) {
235301
+ return ignorePaths.some((ignorePath) => {
235302
+ if (ignorePath.endsWith("*")) {
235303
+ return path5.startsWith(ignorePath.slice(0, -1));
235304
+ }
235305
+ return path5 === ignorePath;
235306
+ });
235307
+ }
235308
+ function compareValues(value1, value2, path5 = "") {
235309
+ if (shouldIgnorePath(path5)) {
235310
+ return true;
235311
+ }
235312
+ if (value1 === null || value1 === void 0) {
235313
+ if (value2 === null || value2 === void 0) {
235314
+ return true;
235315
+ }
235316
+ differences.push({
235317
+ path: path5,
235318
+ type: "different",
235319
+ value1,
235320
+ value2,
235321
+ description: `Null/undefined mismatch: ${value1} vs ${value2}`
235322
+ });
235323
+ return false;
235324
+ }
235325
+ if (value2 === null || value2 === void 0) {
235326
+ differences.push({
235327
+ path: path5,
235328
+ type: "different",
235329
+ value1,
235330
+ value2,
235331
+ description: `Null/undefined mismatch: ${value1} vs ${value2}`
235332
+ });
235333
+ return false;
235334
+ }
235335
+ if (typeof value1 !== typeof value2) {
235336
+ differences.push({
235337
+ path: path5,
235338
+ type: "type_mismatch",
235339
+ value1,
235340
+ value2,
235341
+ description: `Type mismatch: ${typeof value1} vs ${typeof value2}`
235342
+ });
235343
+ return false;
235344
+ }
235345
+ if (typeof value1 !== "object") {
235346
+ const normalized1 = normalizeValue(value1);
235347
+ const normalized2 = normalizeValue(value2);
235348
+ if (normalized1 !== normalized2) {
235349
+ differences.push({
235350
+ path: path5,
235351
+ type: "different",
235352
+ value1,
235353
+ value2,
235354
+ description: `Value mismatch: ${value1} vs ${value2}`
235355
+ });
235356
+ return false;
235357
+ }
235358
+ return true;
235359
+ }
235360
+ if (Array.isArray(value1) && Array.isArray(value2)) {
235361
+ if (value1.length !== value2.length) {
235362
+ differences.push({
235363
+ path: path5,
235364
+ type: "different",
235365
+ value1: value1.length,
235366
+ value2: value2.length,
235367
+ description: `Array length mismatch: ${value1.length} vs ${value2.length}`
235368
+ });
235369
+ return false;
235370
+ }
235371
+ if (ignoreArrayOrder) {
235372
+ const sorted1 = [...value1].sort(
235373
+ (a2, b3) => JSON.stringify(a2).localeCompare(JSON.stringify(b3))
235374
+ );
235375
+ const sorted2 = [...value2].sort(
235376
+ (a2, b3) => JSON.stringify(a2).localeCompare(JSON.stringify(b3))
235377
+ );
235378
+ for (let i3 = 0; i3 < sorted1.length; i3++) {
235379
+ compareValues(sorted1[i3], sorted2[i3], `${path5}[${i3}]`);
235380
+ }
235381
+ } else {
235382
+ for (let i3 = 0; i3 < value1.length; i3++) {
235383
+ compareValues(value1[i3], value2[i3], `${path5}[${i3}]`);
235384
+ }
235385
+ }
235386
+ return true;
235387
+ }
235388
+ if (typeof value1 === "object" && typeof value2 === "object") {
235389
+ const keys1 = Object.keys(value1);
235390
+ const keys2 = Object.keys(value2);
235391
+ const allKeys = /* @__PURE__ */ new Set([...keys1, ...keys2]);
235392
+ stats.totalKeys += allKeys.size;
235393
+ for (const key of allKeys) {
235394
+ const currentPath = path5 ? `${path5}.${key}` : key;
235395
+ if (!keys1.includes(key)) {
235396
+ differences.push({
235397
+ path: currentPath,
235398
+ type: "missing",
235399
+ value2: value2[key],
235400
+ description: `Missing key in first object: ${key}`
235401
+ });
235402
+ stats.missingKeys++;
235403
+ continue;
235404
+ }
235405
+ if (!keys2.includes(key)) {
235406
+ differences.push({
235407
+ path: currentPath,
235408
+ type: "extra",
235409
+ value1: value1[key],
235410
+ description: `Extra key in first object: ${key}`
235411
+ });
235412
+ stats.extraKeys++;
235413
+ continue;
235414
+ }
235415
+ if (!compareValues(value1[key], value2[key], currentPath)) {
235416
+ stats.differentKeys++;
235417
+ }
235418
+ }
235419
+ return true;
235420
+ }
235421
+ return true;
235422
+ }
235423
+ compareValues(obj1, obj2);
235424
+ return {
235425
+ isEqual: differences.length === 0,
235426
+ differences,
235427
+ stats
235428
+ };
235429
+ }
235430
+ var init_json_comparator = __esm({
235431
+ "src/utils/json-comparator.ts"() {
235432
+ "use strict";
235433
+ init_esm_shims();
235434
+ }
235435
+ });
235436
+
235266
235437
  // src/commands/pull-v3/utils/generator-utils.ts
235267
235438
  function toCamelCase(str) {
235268
235439
  const result = str.replace(/[-_](.)/g, (_3, char) => char.toUpperCase()).replace(/[^a-zA-Z0-9]/g, "").replace(/^[0-9]/, "_$&");
@@ -235464,7 +235635,11 @@ function hasDistinctModels(agentModels, projectModels) {
235464
235635
  if (!agentOptions || !projectOptions) {
235465
235636
  return true;
235466
235637
  }
235467
- if (JSON.stringify(agentOptions) !== JSON.stringify(projectOptions)) {
235638
+ const comparison = compareJsonObjects(agentOptions, projectOptions, {
235639
+ ignoreArrayOrder: true,
235640
+ showDetails: false
235641
+ });
235642
+ if (!comparison.isEqual) {
235468
235643
  return true;
235469
235644
  }
235470
235645
  }
@@ -235593,6 +235768,20 @@ function generateAgentDefinition(agentId, agentData, style = DEFAULT_STYLE, regi
235593
235768
  lines.push(`${indentation}contextConfig: undefined,`);
235594
235769
  }
235595
235770
  }
235771
+ if (agentData.credentials && Array.isArray(agentData.credentials) && agentData.credentials.length > 0) {
235772
+ if (!registry2) {
235773
+ throw new Error("Registry is required for credentials generation");
235774
+ }
235775
+ const credentialVars = agentData.credentials.map((cred) => {
235776
+ const credVarName = registry2.getVariableName(cred.id, "credentials");
235777
+ if (!credVarName) {
235778
+ throw new Error(`Failed to resolve variable name for credential: ${cred.id}`);
235779
+ }
235780
+ return credVarName;
235781
+ });
235782
+ const credentialsArray = `[${credentialVars.join(", ")}]`;
235783
+ lines.push(`${indentation}credentials: () => ${credentialsArray},`);
235784
+ }
235596
235785
  if (agentData.stopWhen) {
235597
235786
  const stopWhenFormatted = formatStopWhen(agentData.stopWhen, style, 1);
235598
235787
  if (stopWhenFormatted) {
@@ -235616,11 +235805,11 @@ function generateAgentDefinition(agentId, agentData, style = DEFAULT_STYLE, regi
235616
235805
  lines.push(`})${semi}`);
235617
235806
  return lines.join("\n");
235618
235807
  }
235619
- function generateAgentImports(agentId, agentData, style = DEFAULT_STYLE, registry2, contextConfigData) {
235808
+ function generateAgentImports(agentId, agentData, style = DEFAULT_STYLE, registry2, contextConfigData, actualFilePath) {
235620
235809
  const imports = [];
235621
235810
  imports.push(generateImport(["agent"], "@inkeep/agents-sdk", style));
235622
235811
  if (registry2) {
235623
- const currentFilePath = `agents/${agentId}.ts`;
235812
+ const currentFilePath = actualFilePath || `agents/${agentId}.ts`;
235624
235813
  const referencedComponents = [];
235625
235814
  if (agentData.subAgents && typeof agentData.subAgents === "object") {
235626
235815
  const subAgentIds = Object.keys(agentData.subAgents);
@@ -235650,8 +235839,15 @@ function generateAgentImports(agentId, agentData, style = DEFAULT_STYLE, registr
235650
235839
  }
235651
235840
  return imports;
235652
235841
  }
235653
- function generateAgentFile(agentId, agentData, style = DEFAULT_STYLE, registry2, contextConfigData, projectModels) {
235654
- const imports = generateAgentImports(agentId, agentData, style, registry2, contextConfigData);
235842
+ function generateAgentFile(agentId, agentData, style = DEFAULT_STYLE, registry2, contextConfigData, projectModels, actualFilePath) {
235843
+ const imports = generateAgentImports(
235844
+ agentId,
235845
+ agentData,
235846
+ style,
235847
+ registry2,
235848
+ contextConfigData,
235849
+ actualFilePath
235850
+ );
235655
235851
  const definition = generateAgentDefinition(
235656
235852
  agentId,
235657
235853
  agentData,
@@ -235666,6 +235862,7 @@ var init_agent_generator = __esm({
235666
235862
  "src/commands/pull-v3/components/agent-generator.ts"() {
235667
235863
  "use strict";
235668
235864
  init_esm_shims();
235865
+ init_json_comparator();
235669
235866
  init_generator_utils();
235670
235867
  }
235671
235868
  });
@@ -235823,7 +236020,12 @@ function processFetchConfigTemplates(fetchConfig, headersVarName) {
235823
236020
  );
235824
236021
  return `\`${convertedStr.replace(/`/g, "\\`")}\``;
235825
236022
  } else {
235826
- return `'${value.replace(/'/g, "\\'")}'`;
236023
+ const isMultiline = value.includes("\n") || value.length > 80;
236024
+ if (isMultiline) {
236025
+ return `\`${value.replace(/`/g, "\\`")}\``;
236026
+ } else {
236027
+ return `'${value.replace(/'/g, "\\'")}'`;
236028
+ }
235827
236029
  }
235828
236030
  } else if (typeof value === "object" && value !== null) {
235829
236031
  return processObject(value);
@@ -235836,7 +236038,7 @@ function processFetchConfigTemplates(fetchConfig, headersVarName) {
235836
236038
  const items = obj.map((item) => processValue(item)).join(", ");
235837
236039
  return `[${items}]`;
235838
236040
  }
235839
- const entries = Object.entries(obj).map(([key, val]) => {
236041
+ const entries = Object.entries(obj).filter(([key, val]) => val !== void 0 && val !== null).map(([key, val]) => {
235840
236042
  const processedKey = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : `'${key}'`;
235841
236043
  return `${processedKey}: ${processValue(val)}`;
235842
236044
  });
@@ -235861,7 +236063,7 @@ function generateHeadersDefinition(headersId, headersData, style = DEFAULT_STYLE
235861
236063
  lines.push(`})${semi}`);
235862
236064
  return lines.join("\n");
235863
236065
  }
235864
- function generateFetchDefinitionDefinition(fetchId, fetchData, style = DEFAULT_STYLE, headersVarName) {
236066
+ function generateFetchDefinitionDefinition(fetchId, fetchData, style = DEFAULT_STYLE, headersVarName, registry2) {
235865
236067
  const { quotes, semicolons, indentation } = style;
235866
236068
  const q3 = quotes === "single" ? "'" : '"';
235867
236069
  const semi = semicolons ? ";" : "";
@@ -235888,11 +236090,18 @@ function generateFetchDefinitionDefinition(fetchId, fetchData, style = DEFAULT_S
235888
236090
  }
235889
236091
  if (fetchData.defaultValue) {
235890
236092
  if (typeof fetchData.defaultValue === "string") {
235891
- lines.push(`${indentation}defaultValue: ${formatString(fetchData.defaultValue, q3)},`);
236093
+ const isMultiline = fetchData.defaultValue.includes("\n") || fetchData.defaultValue.length > 80;
236094
+ lines.push(
236095
+ `${indentation}defaultValue: ${formatString(fetchData.defaultValue, q3, isMultiline)},`
236096
+ );
235892
236097
  } else {
235893
236098
  lines.push(`${indentation}defaultValue: ${JSON.stringify(fetchData.defaultValue)},`);
235894
236099
  }
235895
236100
  }
236101
+ if (fetchData.credentialReferenceId && registry2) {
236102
+ const validKey = registry2.getVariableName(fetchData.credentialReferenceId, "credentials");
236103
+ lines.push(`${indentation}credentialReference: ${validKey},`);
236104
+ }
235896
236105
  removeTrailingComma(lines);
235897
236106
  lines.push(`})${semi}`);
235898
236107
  return lines.join("\n");
@@ -235946,7 +236155,7 @@ function generateContextConfigDefinition(contextId, contextData, style = DEFAULT
235946
236155
  lines.push(`})${semi}`);
235947
236156
  return lines.join("\n");
235948
236157
  }
235949
- function generateContextConfigImports(contextId, contextData, style = DEFAULT_STYLE) {
236158
+ function generateContextConfigImports(contextId, contextData, style = DEFAULT_STYLE, registry2) {
235950
236159
  const imports = [];
235951
236160
  const coreImports = [];
235952
236161
  if (contextData.headers || hasHeadersInData(contextData)) {
@@ -235962,6 +236171,27 @@ function generateContextConfigImports(contextId, contextData, style = DEFAULT_ST
235962
236171
  if (hasSchemas(contextData)) {
235963
236172
  imports.push(generateImport(["z"], "zod", style));
235964
236173
  }
236174
+ if (registry2 && contextData.contextVariables) {
236175
+ const credentialRefs = [];
236176
+ for (const [varName, varData] of Object.entries(contextData.contextVariables)) {
236177
+ if (varData && typeof varData === "object" && varData.credentialReferenceId) {
236178
+ credentialRefs.push({
236179
+ id: varData.credentialReferenceId,
236180
+ type: "credentials"
236181
+ });
236182
+ }
236183
+ }
236184
+ if (credentialRefs.length > 0) {
236185
+ const contextComponent = registry2.get(contextId, "contextConfigs");
236186
+ if (contextComponent) {
236187
+ const credentialImports = registry2.getImportsForFile(
236188
+ contextComponent.filePath,
236189
+ credentialRefs
236190
+ );
236191
+ imports.push(...credentialImports);
236192
+ }
236193
+ }
236194
+ }
235965
236195
  return imports;
235966
236196
  }
235967
236197
  function hasHeadersInData(contextData) {
@@ -235977,7 +236207,7 @@ function hasSchemas(contextData) {
235977
236207
  return dataStr.includes("schema") || dataStr.includes("responseschema");
235978
236208
  }
235979
236209
  function generateContextConfigFile(contextId, contextData, style = DEFAULT_STYLE, registry2, agentId) {
235980
- const imports = generateContextConfigImports(contextId, contextData, style);
236210
+ const imports = generateContextConfigImports(contextId, contextData, style, registry2);
235981
236211
  const definitions = [];
235982
236212
  let headersVarName;
235983
236213
  if (contextData.headersSchema) {
@@ -236000,7 +236230,8 @@ function generateContextConfigFile(contextId, contextData, style = DEFAULT_STYLE
236000
236230
  varName,
236001
236231
  varData,
236002
236232
  style,
236003
- headersVarName
236233
+ headersVarName,
236234
+ registry2
236004
236235
  );
236005
236236
  definitions.push(fetchDefinition2);
236006
236237
  }
@@ -236068,13 +236299,14 @@ function formatRetrievalParams(retrievalParams, style, indentLevel) {
236068
236299
  const indent = indentation.repeat(indentLevel + 1);
236069
236300
  const lines = ["{"];
236070
236301
  for (const [key, value] of Object.entries(retrievalParams)) {
236302
+ const formattedKey = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : `${q3}${key}${q3}`;
236071
236303
  if (typeof value === "string") {
236072
- lines.push(`${indent}${q3}${key}${q3}: ${formatString3(value, q3)},`);
236304
+ lines.push(`${indent}${formattedKey}: ${formatString3(value, q3)},`);
236073
236305
  } else if (typeof value === "number" || typeof value === "boolean") {
236074
- lines.push(`${indent}${q3}${key}${q3}: ${JSON.stringify(value)},`);
236306
+ lines.push(`${indent}${formattedKey}: ${JSON.stringify(value)},`);
236075
236307
  } else if (typeof value === "object" && value !== null) {
236076
236308
  lines.push(
236077
- `${indent}${q3}${key}${q3}: ${formatRetrievalParams(value, style, indentLevel + 1)},`
236309
+ `${indent}${formattedKey}: ${formatRetrievalParams(value, style, indentLevel + 1)},`
236078
236310
  );
236079
236311
  }
236080
236312
  }
@@ -236116,11 +236348,6 @@ function generateCredentialDefinition(credentialId, credentialData, style = DEFA
236116
236348
  } else {
236117
236349
  lines.push(`${indentation}retrievalParams: ${formattedParams},`);
236118
236350
  }
236119
- } else {
236120
- const defaultKey = credentialId.toUpperCase().replace(/-/g, "_");
236121
- lines.push(`${indentation}retrievalParams: {`);
236122
- lines.push(`${indentation}${indentation}${q3}key${q3}: ${formatString3(defaultKey, q3)}`);
236123
- lines.push(`${indentation}},`);
236124
236351
  }
236125
236352
  if (lines.length > 0 && lines[lines.length - 1].endsWith(",")) {
236126
236353
  lines[lines.length - 1] = lines[lines.length - 1].slice(0, -1);
@@ -236207,6 +236434,23 @@ function generateDataComponentDefinition(componentId, componentData, style = DEF
236207
236434
  const zodSchema = convertJsonSchemaToZod2(schema);
236208
236435
  lines.push(`${indentation}props: ${zodSchema},`);
236209
236436
  }
236437
+ if (componentData.render && typeof componentData.render === "object") {
236438
+ const render = componentData.render;
236439
+ if (render.component && typeof render.component === "string") {
236440
+ lines.push(`${indentation}render: {`);
236441
+ const componentString = JSON.stringify(render.component);
236442
+ lines.push(`${indentation}${indentation}component: ${componentString},`);
236443
+ if (render.mockData && typeof render.mockData === "object") {
236444
+ const mockDataStr = JSON.stringify(render.mockData, null, 2);
236445
+ const formattedMockData = mockDataStr.split("\n").map((line, index2) => {
236446
+ if (index2 === 0) return line;
236447
+ return `${indentation}${indentation}${line}`;
236448
+ }).join("\n");
236449
+ lines.push(`${indentation}${indentation}mockData: ${formattedMockData},`);
236450
+ }
236451
+ lines.push(`${indentation}},`);
236452
+ }
236453
+ }
236210
236454
  if (lines.length > 0 && lines[lines.length - 1].endsWith(",")) {
236211
236455
  lines[lines.length - 1] = lines[lines.length - 1].slice(0, -1);
236212
236456
  }
@@ -236724,6 +236968,9 @@ function generateMcpToolDefinition(toolId, toolData, style = DEFAULT_STYLE7, reg
236724
236968
  if (mcpConfig.transport) {
236725
236969
  lines.push(`${indentation}transport: ${JSON.stringify(mcpConfig.transport, null, 2)},`);
236726
236970
  }
236971
+ if (mcpConfig.activeTools && Array.isArray(mcpConfig.activeTools)) {
236972
+ lines.push(`${indentation}activeTools: ${JSON.stringify(mcpConfig.activeTools)},`);
236973
+ }
236727
236974
  }
236728
236975
  if (toolData.description) {
236729
236976
  lines.push(`${indentation}description: ${formatString7(toolData.description, q3, true)},`);
@@ -237096,7 +237343,11 @@ function hasDistinctModels2(subAgentModels, parentModels) {
237096
237343
  if (!subAgentOptions || !parentOptions) {
237097
237344
  return true;
237098
237345
  }
237099
- if (JSON.stringify(subAgentOptions) !== JSON.stringify(parentOptions)) {
237346
+ const comparison = compareJsonObjects(subAgentOptions, parentOptions, {
237347
+ ignoreArrayOrder: true,
237348
+ showDetails: false
237349
+ });
237350
+ if (!comparison.isEqual) {
237100
237351
  return true;
237101
237352
  }
237102
237353
  }
@@ -237369,12 +237620,12 @@ function generateSubAgentDefinition(agentId, agentData, style = DEFAULT_STYLE, r
237369
237620
  lines.push(`})${semi}`);
237370
237621
  return lines.join("\n");
237371
237622
  }
237372
- function generateSubAgentImports(agentId, agentData, style = DEFAULT_STYLE, registry2, parentAgentId, contextConfigData) {
237623
+ function generateSubAgentImports(agentId, agentData, style = DEFAULT_STYLE, registry2, parentAgentId, contextConfigData, actualFilePath) {
237373
237624
  const imports = [];
237374
237625
  imports.push(generateImport(["subAgent"], "@inkeep/agents-sdk", style));
237375
237626
  if (hasTemplateVariables(agentData.prompt) && parentAgentId && registry2 && contextConfigData) {
237376
237627
  const contextConfigId = contextConfigData.id;
237377
- const currentFilePath = `agents/sub-agents/${agentId}.ts`;
237628
+ const currentFilePath = actualFilePath || `agents/sub-agents/${agentId}.ts`;
237378
237629
  const importStatement = registry2.getImportStatement(
237379
237630
  currentFilePath,
237380
237631
  contextConfigId,
@@ -237385,7 +237636,7 @@ function generateSubAgentImports(agentId, agentData, style = DEFAULT_STYLE, regi
237385
237636
  }
237386
237637
  }
237387
237638
  if (registry2) {
237388
- const currentFilePath = `agents/sub-agents/${agentId}.ts`;
237639
+ const currentFilePath = actualFilePath || `agents/sub-agents/${agentId}.ts`;
237389
237640
  const referencedComponents = [];
237390
237641
  if (Array.isArray(agentData.canUse)) {
237391
237642
  for (const toolRelation of agentData.canUse) {
@@ -237450,14 +237701,15 @@ function generateSubAgentImports(agentId, agentData, style = DEFAULT_STYLE, regi
237450
237701
  }
237451
237702
  return imports;
237452
237703
  }
237453
- function generateSubAgentFile(agentId, agentData, style = DEFAULT_STYLE, registry2, parentAgentId, contextConfigData, parentModels) {
237704
+ function generateSubAgentFile(agentId, agentData, style = DEFAULT_STYLE, registry2, parentAgentId, contextConfigData, parentModels, actualFilePath) {
237454
237705
  const imports = generateSubAgentImports(
237455
237706
  agentId,
237456
237707
  agentData,
237457
237708
  style,
237458
237709
  registry2,
237459
237710
  parentAgentId,
237460
- contextConfigData
237711
+ contextConfigData,
237712
+ actualFilePath
237461
237713
  );
237462
237714
  const definition = generateSubAgentDefinition(
237463
237715
  agentId,
@@ -237474,6 +237726,7 @@ var init_sub_agent_generator = __esm({
237474
237726
  "src/commands/pull-v3/components/sub-agent-generator.ts"() {
237475
237727
  "use strict";
237476
237728
  init_esm_shims();
237729
+ init_json_comparator();
237477
237730
  init_generator_utils();
237478
237731
  }
237479
237732
  });
@@ -237526,14 +237779,11 @@ function registerAllComponents(project, registry2) {
237526
237779
  }
237527
237780
  if (project.agents) {
237528
237781
  for (const agentId of Object.keys(project.agents)) {
237529
- console.log(`\u{1F527} Registering agent: ${agentId}`);
237530
237782
  registry2.register(agentId, "agents", `agents/${agentId}.ts`);
237531
237783
  }
237532
237784
  }
237533
237785
  const subAgents2 = extractSubAgents(project);
237534
- console.log(`\u{1F527} Found subAgents:`, Object.keys(subAgents2));
237535
237786
  for (const subAgentId of Object.keys(subAgents2)) {
237536
- console.log(`\u{1F527} Registering subAgent: ${subAgentId}`);
237537
237787
  registry2.register(subAgentId, "subAgents", `agents/sub-agents/${subAgentId}.ts`);
237538
237788
  }
237539
237789
  const contextConfigs2 = extractContextConfigs(project);
@@ -237643,9 +237893,6 @@ var init_component_registry = __esm({
237643
237893
  } else {
237644
237894
  const baseName = this.toCamelCase(id);
237645
237895
  const uniqueName = this.ensureUniqueName(baseName, type);
237646
- console.log(
237647
- `\u{1F527} Registry: ${type}:${id} -> baseName: "${baseName}" -> uniqueName: "${uniqueName}"`
237648
- );
237649
237896
  name2 = uniqueName;
237650
237897
  actualExportName = uniqueName;
237651
237898
  }
@@ -237665,6 +237912,25 @@ var init_component_registry = __esm({
237665
237912
  }
237666
237913
  return info2;
237667
237914
  }
237915
+ /**
237916
+ * Override a credential component with environment settings key
237917
+ * This allows env settings registration to take precedence over standalone credentials
237918
+ */
237919
+ overrideCredentialWithEnvKey(id, filePath, envKey) {
237920
+ const typeKey = `credentials:${id}`;
237921
+ const info2 = {
237922
+ id,
237923
+ type: "credentials",
237924
+ name: envKey,
237925
+ // Use the environment settings key
237926
+ filePath,
237927
+ exportName: envKey,
237928
+ isInline: true
237929
+ };
237930
+ this.componentsByTypeAndId.set(typeKey, info2);
237931
+ this.components.set(`${filePath}:${envKey}`, info2);
237932
+ return info2;
237933
+ }
237668
237934
  /**
237669
237935
  * Get component info by ID and type
237670
237936
  */
@@ -237697,6 +237963,11 @@ var init_component_registry = __esm({
237697
237963
  getImportStatement(fromFilePath, componentId, componentType) {
237698
237964
  const component = this.get(componentId, componentType);
237699
237965
  if (!component) return void 0;
237966
+ const normalizedFrom = this.normalizeToProjectPath(fromFilePath);
237967
+ const normalizedTo = this.normalizeToProjectPath(component.filePath);
237968
+ if (normalizedFrom === normalizedTo) {
237969
+ return void 0;
237970
+ }
237700
237971
  const relativePath = this.calculateRelativeImport(fromFilePath, component.filePath);
237701
237972
  const importStmt = `import { ${component.exportName} } from '${relativePath}';`;
237702
237973
  return importStmt;
@@ -237856,18 +238127,45 @@ var init_component_registry = __esm({
237856
238127
  return "comp";
237857
238128
  }
237858
238129
  }
238130
+ /**
238131
+ * Normalize path to project-relative format using existing registry paths as templates
238132
+ */
238133
+ normalizeToProjectPath(filePath) {
238134
+ if (!filePath.includes("/") || filePath.match(/^(agents|tools|environments|data-components)/)) {
238135
+ return filePath;
238136
+ }
238137
+ const knownDirs = /* @__PURE__ */ new Set();
238138
+ for (const component of this.components.values()) {
238139
+ const firstDir = component.filePath.split("/")[0];
238140
+ if (firstDir) knownDirs.add(firstDir);
238141
+ }
238142
+ const segments = filePath.split("/");
238143
+ for (let i3 = segments.length - 1; i3 >= 0; i3--) {
238144
+ if (knownDirs.has(segments[i3])) {
238145
+ return segments.slice(i3).join("/");
238146
+ }
238147
+ }
238148
+ return segments[segments.length - 1] || filePath;
238149
+ }
237859
238150
  /**
237860
238151
  * Calculate relative import path between files
237861
238152
  */
237862
238153
  calculateRelativeImport(fromPath, toPath) {
237863
238154
  const fromParts = fromPath.replace(".ts", "").split("/");
237864
238155
  const toParts = toPath.replace(".ts", "").split("/");
237865
- fromParts.pop();
238156
+ const fromDir = fromParts.slice(0, -1);
238157
+ const toFile = toParts;
238158
+ let commonLength = 0;
238159
+ while (commonLength < fromDir.length && commonLength < toFile.length - 1 && fromDir[commonLength] === toFile[commonLength]) {
238160
+ commonLength++;
238161
+ }
237866
238162
  let relativePath = "";
237867
- for (let i3 = 0; i3 < fromParts.length; i3++) {
238163
+ const upLevels = fromDir.length - commonLength;
238164
+ for (let i3 = 0; i3 < upLevels; i3++) {
237868
238165
  relativePath += "../";
237869
238166
  }
237870
- relativePath += toParts.join("/");
238167
+ const remainingPath = toFile.slice(commonLength).join("/");
238168
+ relativePath += remainingPath;
237871
238169
  if (relativePath.startsWith("../")) {
237872
238170
  return relativePath;
237873
238171
  } else {
@@ -238578,16 +238876,31 @@ function compareComponentMaps(componentType, localMap, remoteMap, debug) {
238578
238876
  });
238579
238877
  const commonIds = localIds.filter((id) => remoteIds.includes(id));
238580
238878
  commonIds.forEach((id) => {
238581
- const fieldChanges = getDetailedFieldChanges("", localMap[id], remoteMap[id]);
238582
- if (fieldChanges.length > 0) {
238583
- const summary = generateComponentChangeSummary(componentType, fieldChanges);
238584
- changes.push({
238585
- componentType,
238586
- componentId: id,
238587
- changeType: "modified",
238588
- changedFields: fieldChanges,
238589
- summary
238879
+ if (componentType === "artifactComponents") {
238880
+ const comparison = compareJsonObjects(localMap[id], remoteMap[id], {
238881
+ ignoreArrayOrder: true,
238882
+ showDetails: false
238590
238883
  });
238884
+ if (!comparison.isEqual) {
238885
+ changes.push({
238886
+ componentType,
238887
+ componentId: id,
238888
+ changeType: "modified",
238889
+ summary: `Modified ${componentType}: ${id}`
238890
+ });
238891
+ }
238892
+ } else {
238893
+ const fieldChanges = getDetailedFieldChanges("", localMap[id], remoteMap[id]);
238894
+ if (fieldChanges.length > 0) {
238895
+ const summary = generateComponentChangeSummary(componentType, fieldChanges);
238896
+ changes.push({
238897
+ componentType,
238898
+ componentId: id,
238899
+ changeType: "modified",
238900
+ changedFields: fieldChanges,
238901
+ summary
238902
+ });
238903
+ }
238591
238904
  }
238592
238905
  });
238593
238906
  return changes;
@@ -238657,6 +238970,24 @@ function compareArraysAsSet(basePath, oldArray, newArray, depth) {
238657
238970
  }
238658
238971
  return changes;
238659
238972
  }
238973
+ function extractCredentialIds(agentObj) {
238974
+ const credentialIds = [];
238975
+ if (agentObj.credentials && Array.isArray(agentObj.credentials)) {
238976
+ agentObj.credentials.forEach((cred) => {
238977
+ if (cred.id) {
238978
+ credentialIds.push(cred.id);
238979
+ }
238980
+ });
238981
+ }
238982
+ if (agentObj.contextConfig?.contextVariables) {
238983
+ Object.values(agentObj.contextConfig.contextVariables).forEach((variable) => {
238984
+ if (variable && typeof variable === "object" && variable.credentialReferenceId) {
238985
+ credentialIds.push(variable.credentialReferenceId);
238986
+ }
238987
+ });
238988
+ }
238989
+ return [...new Set(credentialIds)];
238990
+ }
238660
238991
  function getDetailedFieldChanges(basePath, oldObj, newObj, depth = 0) {
238661
238992
  const changes = [];
238662
238993
  if (depth > 10) return changes;
@@ -238743,8 +239074,21 @@ function getDetailedFieldChanges(basePath, oldObj, newObj, depth = 0) {
238743
239074
  return false;
238744
239075
  });
238745
239076
  if (shouldIgnore) {
238746
- if (basePath === "" && key === "statusUpdates") {
238747
- console.log(` \u26A0\uFE0F statusUpdates field is being IGNORED due to ignored fields check`);
239077
+ continue;
239078
+ }
239079
+ if (key === "credentials" && basePath === "") {
239080
+ const oldCredIds = extractCredentialIds(oldObj);
239081
+ const newCredIds = extractCredentialIds(newObj);
239082
+ oldCredIds.sort();
239083
+ newCredIds.sort();
239084
+ if (JSON.stringify(oldCredIds) !== JSON.stringify(newCredIds)) {
239085
+ changes.push({
239086
+ field: fieldPath,
239087
+ changeType: "modified",
239088
+ oldValue: oldCredIds,
239089
+ newValue: newCredIds,
239090
+ description: `Credential usage differs: [${oldCredIds.join(", ")}] vs [${newCredIds.join(", ")}]`
239091
+ });
238748
239092
  }
238749
239093
  continue;
238750
239094
  }
@@ -238769,6 +239113,18 @@ function getDetailedFieldChanges(basePath, oldObj, newObj, depth = 0) {
238769
239113
  });
238770
239114
  }
238771
239115
  } else {
239116
+ const oldIsEmpty2 = isEmpty(oldValue);
239117
+ const newIsEmpty2 = isEmpty(newValue);
239118
+ if (oldIsEmpty2 && newIsEmpty2) {
239119
+ continue;
239120
+ }
239121
+ if (key === "models") {
239122
+ const oldIsNull = oldValue === null || oldValue === void 0;
239123
+ const newIsNull = newValue === null || newValue === void 0;
239124
+ if (oldIsNull !== newIsNull) {
239125
+ continue;
239126
+ }
239127
+ }
238772
239128
  const recursiveChanges = getDetailedFieldChanges(fieldPath, oldValue, newValue, depth + 1);
238773
239129
  changes.push(...recursiveChanges);
238774
239130
  }
@@ -239048,9 +239404,11 @@ function compareFetchDefinitions(localProject, remoteProject, debug) {
239048
239404
  summary: `Removed fetchDefinition: ${fetchId}`
239049
239405
  });
239050
239406
  } else if (local && remote) {
239051
- const localStr = JSON.stringify(local, null, 2);
239052
- const remoteStr = JSON.stringify(remote, null, 2);
239053
- if (localStr !== remoteStr) {
239407
+ const comparison = compareJsonObjects(local, remote, {
239408
+ ignoreArrayOrder: true,
239409
+ showDetails: true
239410
+ });
239411
+ if (!comparison.isEqual) {
239054
239412
  changes.push({
239055
239413
  componentType: "fetchDefinitions",
239056
239414
  componentId: fetchId,
@@ -239077,6 +239435,7 @@ var init_project_comparator = __esm({
239077
239435
  "src/commands/pull-v3/project-comparator.ts"() {
239078
239436
  "use strict";
239079
239437
  init_esm_shims();
239438
+ init_json_comparator();
239080
239439
  }
239081
239440
  });
239082
239441
 
@@ -239089,6 +239448,7 @@ __export(component_parser_exports, {
239089
239448
  });
239090
239449
  import { existsSync as existsSync8, readdirSync as readdirSync2, readFileSync as readFileSync3, statSync } from "fs";
239091
239450
  import { extname as extname2, join as join10, relative } from "path";
239451
+ import { Node as Node3, Project } from "ts-morph";
239092
239452
  function parseFileForComponents(filePath, projectRoot, debug = false) {
239093
239453
  if (!existsSync8(filePath)) {
239094
239454
  return [];
@@ -239097,271 +239457,234 @@ function parseFileForComponents(filePath, projectRoot, debug = false) {
239097
239457
  const relativePath = relative(projectRoot, filePath);
239098
239458
  try {
239099
239459
  const content = readFileSync3(filePath, "utf8");
239100
- const lines = content.split("\n");
239101
- const exportedIdPattern = /export\s+const\s+(\w+)\s*=\s*(\w+)\s*\(\s*\{[^}]*?id:\s*['"`]([^'"`]+)['"`]/gs;
239102
- const exportedTypePattern = /export\s+const\s+(\w+)\s*=\s*(\w+)\s*\(\s*\{[^}]*?type:\s*['"`]([^'"`]+)['"`]/gs;
239103
- const exportedNamePattern = /export\s+const\s+(\w+)\s*=\s*(\w+)\s*\(\s*\{[^}]*?name:\s*['"`]([^'"`]+)['"`]/gs;
239104
- const declaredIdPattern = /(?:^|\n)\s*const\s+(\w+)\s*=\s*(\w+)\s*\(\s*\{[^}]*?id:\s*['"`]([^'"`]+)['"`]/gs;
239105
- const declaredTypePattern = /(?:^|\n)\s*const\s+(\w+)\s*=\s*(\w+)\s*\(\s*\{[^}]*?type:\s*['"`]([^'"`]+)['"`]/gs;
239106
- const declaredNamePattern = /(?:^|\n)\s*const\s+(\w+)\s*=\s*(\w+)\s*\(\s*\{[^}]*?name:\s*['"`]([^'"`]+)['"`]/gs;
239107
- const exportedVariables = /* @__PURE__ */ new Set();
239108
- const exportPattern = /export\s*\{\s*([^}]+)\s*\}/g;
239109
- let exportMatch;
239110
- while ((exportMatch = exportPattern.exec(content)) !== null) {
239111
- const exportList = exportMatch[1];
239112
- const variables = exportList.split(",").map((v3) => v3.trim()).filter((v3) => v3);
239113
- variables.forEach((v3) => exportedVariables.add(v3));
239114
- }
239115
- let match2;
239116
- while ((match2 = exportedIdPattern.exec(content)) !== null) {
239117
- const variableName = match2[1];
239118
- const functionName = match2[2];
239119
- const componentId = match2[3];
239120
- const componentType = FUNCTION_NAME_TO_TYPE[functionName];
239121
- if (componentType && VALID_COMPONENT_TYPES.has(componentType)) {
239122
- const lineNumber = content.substring(0, match2.index).split("\n").length;
239123
- components.push({
239124
- id: componentId,
239125
- type: componentType,
239126
- filePath: relativePath,
239127
- variableName,
239128
- startLine: lineNumber,
239129
- isInline: false
239130
- });
239131
- }
239132
- }
239133
- while ((match2 = exportedTypePattern.exec(content)) !== null) {
239134
- const variableName = match2[1];
239135
- const functionName = match2[2];
239136
- const componentId = match2[3];
239137
- const componentType = FUNCTION_NAME_TO_TYPE[functionName];
239138
- if (componentType && VALID_COMPONENT_TYPES.has(componentType) && componentType === "statusComponents") {
239139
- const lineNumber = content.substring(0, match2.index).split("\n").length;
239140
- components.push({
239141
- id: componentId,
239142
- type: componentType,
239143
- filePath: relativePath,
239144
- variableName,
239145
- startLine: lineNumber,
239146
- isInline: false
239147
- });
239148
- }
239149
- }
239150
- while ((match2 = exportedNamePattern.exec(content)) !== null) {
239151
- const variableName = match2[1];
239152
- const functionName = match2[2];
239153
- const componentId = match2[3];
239154
- const componentType = FUNCTION_NAME_TO_TYPE[functionName];
239155
- if (VALID_COMPONENT_TYPES.has(componentType) && componentType === "functionTools") {
239156
- const lineNumber = content.substring(0, match2.index).split("\n").length;
239157
- components.push({
239158
- id: componentId,
239159
- type: componentType,
239160
- filePath: relativePath,
239161
- variableName,
239162
- startLine: lineNumber,
239163
- isInline: false
239164
- });
239165
- }
239166
- }
239167
- while ((match2 = declaredIdPattern.exec(content)) !== null) {
239168
- const variableName = match2[1];
239169
- const functionName = match2[2];
239170
- const componentId = match2[3];
239171
- const componentType = FUNCTION_NAME_TO_TYPE[functionName];
239172
- if (VALID_COMPONENT_TYPES.has(componentType) && exportedVariables.has(variableName)) {
239173
- const lineNumber = content.substring(0, match2.index).split("\n").length;
239174
- components.push({
239175
- id: componentId,
239176
- type: componentType,
239177
- filePath: relativePath,
239178
- variableName,
239179
- startLine: lineNumber,
239180
- isInline: false
239181
- // It's exported via separate export statement
239182
- });
239460
+ const project = new Project({
239461
+ useInMemoryFileSystem: true,
239462
+ compilerOptions: {
239463
+ allowJs: true,
239464
+ target: 99,
239465
+ // Latest
239466
+ jsx: 1
239467
+ // Preserve JSX
239183
239468
  }
239184
- }
239185
- while ((match2 = declaredTypePattern.exec(content)) !== null) {
239186
- const variableName = match2[1];
239187
- const functionName = match2[2];
239188
- const componentId = match2[3];
239189
- const componentType = FUNCTION_NAME_TO_TYPE[functionName];
239190
- if (componentType && VALID_COMPONENT_TYPES.has(componentType) && componentType === "statusComponents" && exportedVariables.has(variableName)) {
239191
- const lineNumber = content.substring(0, match2.index).split("\n").length;
239192
- components.push({
239193
- id: componentId,
239194
- type: componentType,
239195
- filePath: relativePath,
239196
- variableName,
239197
- startLine: lineNumber,
239198
- isInline: false
239199
- // It's exported via separate export statement
239200
- });
239201
- }
239202
- }
239203
- while ((match2 = declaredNamePattern.exec(content)) !== null) {
239204
- const variableName = match2[1];
239205
- const functionName = match2[2];
239206
- const componentId = match2[3];
239207
- const componentType = FUNCTION_NAME_TO_TYPE[functionName];
239208
- if (VALID_COMPONENT_TYPES.has(componentType) && componentType === "functionTools" && exportedVariables.has(variableName)) {
239209
- const lineNumber = content.substring(0, match2.index).split("\n").length;
239210
- components.push({
239211
- id: componentId,
239212
- type: componentType,
239213
- filePath: relativePath,
239469
+ });
239470
+ const sourceFile = project.createSourceFile("temp.ts", content);
239471
+ const exportedVariableDeclarations = sourceFile.getVariableStatements().filter((statement) => statement.hasExportKeyword()).flatMap((statement) => statement.getDeclarationList().getDeclarations());
239472
+ for (const declaration of exportedVariableDeclarations) {
239473
+ const variableName = declaration.getName();
239474
+ const initializer = declaration.getInitializer();
239475
+ if (Node3.isCallExpression(initializer)) {
239476
+ const componentMatch = parseCallExpression(initializer, variableName, false, relativePath);
239477
+ if (componentMatch) {
239478
+ components.push(componentMatch);
239479
+ }
239480
+ }
239481
+ }
239482
+ const exportedNames = /* @__PURE__ */ new Set();
239483
+ sourceFile.getExportDeclarations().forEach((exportDecl) => {
239484
+ const namedExports = exportDecl.getNamedExports();
239485
+ namedExports.forEach((namedExport) => {
239486
+ exportedNames.add(namedExport.getName());
239487
+ });
239488
+ });
239489
+ const allVariableDeclarations = sourceFile.getVariableStatements().filter((statement) => !statement.hasExportKeyword()).flatMap((statement) => statement.getDeclarationList().getDeclarations());
239490
+ for (const declaration of allVariableDeclarations) {
239491
+ const variableName = declaration.getName();
239492
+ const initializer = declaration.getInitializer();
239493
+ if (Node3.isCallExpression(initializer)) {
239494
+ const isExported = exportedNames.has(variableName);
239495
+ const isInline = !isExported;
239496
+ const componentMatch = parseCallExpression(
239497
+ initializer,
239214
239498
  variableName,
239215
- startLine: lineNumber,
239216
- isInline: false
239217
- // It's exported via separate export statement
239218
- });
239499
+ isInline,
239500
+ relativePath
239501
+ );
239502
+ if (componentMatch) {
239503
+ components.push(componentMatch);
239504
+ }
239219
239505
  }
239220
239506
  }
239221
- while ((match2 = declaredIdPattern.exec(content)) !== null) {
239222
- const variableName = match2[1];
239223
- const functionName = match2[2];
239224
- const componentId = match2[3];
239225
- const componentType = FUNCTION_NAME_TO_TYPE[functionName];
239226
- if (VALID_COMPONENT_TYPES.has(componentType) && !exportedVariables.has(variableName)) {
239227
- const lineNumber = content.substring(0, match2.index).split("\n").length;
239228
- components.push({
239229
- id: componentId,
239230
- type: componentType,
239231
- filePath: relativePath,
239232
- variableName,
239233
- startLine: lineNumber,
239234
- isInline: true
239235
- // Not exported, so treated as inline but has variable name
239236
- });
239507
+ sourceFile.forEachDescendant((node) => {
239508
+ if (Node3.isCallExpression(node)) {
239509
+ const parent = node.getParent();
239510
+ const isVariableInitializer = Node3.isVariableDeclaration(parent) && parent.getInitializer() === node;
239511
+ if (!isVariableInitializer) {
239512
+ const componentMatch = parseCallExpression(node, void 0, true, relativePath);
239513
+ if (componentMatch) {
239514
+ components.push(componentMatch);
239515
+ }
239516
+ }
239237
239517
  }
239238
- }
239239
- while ((match2 = declaredTypePattern.exec(content)) !== null) {
239240
- const variableName = match2[1];
239241
- const functionName = match2[2];
239242
- const componentId = match2[3];
239243
- const componentType = FUNCTION_NAME_TO_TYPE[functionName];
239244
- if (componentType && VALID_COMPONENT_TYPES.has(componentType) && componentType === "statusComponents" && !exportedVariables.has(variableName)) {
239245
- const lineNumber = content.substring(0, match2.index).split("\n").length;
239246
- components.push({
239247
- id: componentId,
239248
- type: componentType,
239249
- filePath: relativePath,
239250
- variableName,
239251
- startLine: lineNumber,
239252
- isInline: true
239253
- // Not exported, so treated as inline but has variable name
239254
- });
239518
+ });
239519
+ sourceFile.forEachDescendant((node) => {
239520
+ if (Node3.isCallExpression(node)) {
239521
+ const expression = node.getExpression();
239522
+ if (Node3.isIdentifier(expression) && expression.getText() === "registerEnvironmentSettings") {
239523
+ const args2 = node.getArguments();
239524
+ if (args2.length > 0 && Node3.isObjectLiteralExpression(args2[0])) {
239525
+ const configObject = args2[0];
239526
+ const credentialsProperty = configObject.getProperty("credentials");
239527
+ if (credentialsProperty && Node3.isPropertyAssignment(credentialsProperty)) {
239528
+ const credentialsValue = credentialsProperty.getInitializer();
239529
+ if (Node3.isObjectLiteralExpression(credentialsValue)) {
239530
+ credentialsValue.getProperties().forEach((property) => {
239531
+ if (Node3.isPropertyAssignment(property)) {
239532
+ const credentialKey = property.getName();
239533
+ const credentialConfig = property.getInitializer();
239534
+ if (Node3.isObjectLiteralExpression(credentialConfig)) {
239535
+ const idProperty = credentialConfig.getProperty("id");
239536
+ if (idProperty && Node3.isPropertyAssignment(idProperty)) {
239537
+ const idValue = idProperty.getInitializer();
239538
+ if (Node3.isStringLiteral(idValue)) {
239539
+ const credentialId = idValue.getLiteralValue();
239540
+ const startLine = node.getStartLineNumber();
239541
+ components.push({
239542
+ id: credentialId,
239543
+ type: "credentials",
239544
+ filePath: relativePath,
239545
+ variableName: credentialKey,
239546
+ // Use the key name as variable name
239547
+ startLine,
239548
+ isInline: true
239549
+ // It's nested within environment settings
239550
+ });
239551
+ }
239552
+ }
239553
+ } else if (Node3.isIdentifier(credentialConfig)) {
239554
+ const variableName = credentialConfig.getText();
239555
+ sourceFile.forEachDescendant((varNode) => {
239556
+ if (Node3.isVariableDeclaration(varNode) && varNode.getName() === variableName) {
239557
+ const initializer = varNode.getInitializer();
239558
+ if (Node3.isCallExpression(initializer)) {
239559
+ const callExpression = initializer.getExpression();
239560
+ if (Node3.isIdentifier(callExpression) && callExpression.getText() === "credential") {
239561
+ const args3 = initializer.getArguments();
239562
+ if (args3.length > 0 && Node3.isObjectLiteralExpression(args3[0])) {
239563
+ const configObject2 = args3[0];
239564
+ const idProperty = configObject2.getProperty("id");
239565
+ if (idProperty && Node3.isPropertyAssignment(idProperty)) {
239566
+ const idValue = idProperty.getInitializer();
239567
+ if (Node3.isStringLiteral(idValue)) {
239568
+ const credentialId = idValue.getLiteralValue();
239569
+ const startLine = node.getStartLineNumber();
239570
+ components.push({
239571
+ id: credentialId,
239572
+ type: "credentials",
239573
+ filePath: relativePath,
239574
+ variableName: credentialKey,
239575
+ // Use the env settings key as variable name
239576
+ startLine,
239577
+ isInline: true,
239578
+ overrideExisting: true
239579
+ // Mark this to override any existing registration
239580
+ });
239581
+ }
239582
+ }
239583
+ }
239584
+ }
239585
+ }
239586
+ }
239587
+ });
239588
+ }
239589
+ }
239590
+ });
239591
+ }
239592
+ }
239593
+ }
239594
+ }
239255
239595
  }
239596
+ });
239597
+ return components;
239598
+ } catch (error) {
239599
+ if (debug) {
239600
+ console.warn(`Failed to parse file ${relativePath}: ${error}`);
239256
239601
  }
239257
- while ((match2 = declaredNamePattern.exec(content)) !== null) {
239258
- const variableName = match2[1];
239259
- const functionName = match2[2];
239260
- const componentId = match2[3];
239261
- const componentType = FUNCTION_NAME_TO_TYPE[functionName];
239262
- if (componentType && VALID_COMPONENT_TYPES.has(componentType) && componentType === "functionTools" && !exportedVariables.has(variableName)) {
239263
- const lineNumber = content.substring(0, match2.index).split("\n").length;
239264
- components.push({
239265
- id: componentId,
239266
- type: componentType,
239267
- filePath: relativePath,
239268
- variableName,
239269
- startLine: lineNumber,
239270
- isInline: true
239271
- // Not exported, so treated as inline but has variable name
239272
- });
239273
- }
239602
+ return [];
239603
+ }
239604
+ }
239605
+ function parseCallExpression(callExpression, variableName, isInline, relativePath) {
239606
+ const expression = callExpression.getExpression();
239607
+ let functionName;
239608
+ if (Node3.isIdentifier(expression)) {
239609
+ functionName = expression.getText();
239610
+ } else {
239611
+ return null;
239612
+ }
239613
+ const componentType = FUNCTION_NAME_TO_TYPE[functionName];
239614
+ if (!componentType || !VALID_COMPONENT_TYPES.has(componentType)) {
239615
+ return null;
239616
+ }
239617
+ const args2 = callExpression.getArguments();
239618
+ if (args2.length === 0 || !Node3.isObjectLiteralExpression(args2[0])) {
239619
+ return null;
239620
+ }
239621
+ const configObject = args2[0];
239622
+ let componentId = null;
239623
+ const idProperty = configObject.getProperty("id");
239624
+ if (idProperty && Node3.isPropertyAssignment(idProperty)) {
239625
+ const idValue = idProperty.getInitializer();
239626
+ if (Node3.isStringLiteral(idValue)) {
239627
+ componentId = idValue.getLiteralValue();
239274
239628
  }
239275
- const functionNames = Object.keys(FUNCTION_NAME_TO_TYPE);
239276
- for (const funcName of functionNames) {
239277
- const inlineIdPattern = new RegExp(
239278
- `(?<!(?:export\\s+)?const\\s+\\w+\\s*=\\s*)\\b${funcName}\\s*\\(\\s*\\{[^}]*?id:\\s*['"\`]([^'"\`]+)['"\`]`,
239279
- "gs"
239280
- );
239281
- let inlineMatch;
239282
- while ((inlineMatch = inlineIdPattern.exec(content)) !== null) {
239283
- const componentId = inlineMatch[1];
239284
- const componentType = FUNCTION_NAME_TO_TYPE[funcName];
239285
- const lineNumber = content.substring(0, inlineMatch.index).split("\n").length;
239286
- components.push({
239287
- id: componentId,
239288
- type: componentType,
239289
- filePath: relativePath,
239290
- variableName: void 0,
239291
- // No variable name for inline
239292
- startLine: lineNumber,
239293
- isInline: true
239294
- });
239295
- }
239296
- if (funcName === "functionTool") {
239297
- const inlineNamePattern = new RegExp(
239298
- `(?<!(?:export\\s+)?const\\s+\\w+\\s*=\\s*)\\b${funcName}\\s*\\(\\s*\\{[^}]*?name:\\s*['"\`]([^'"\`]+)['"\`]`,
239299
- "gs"
239300
- );
239301
- while ((inlineMatch = inlineNamePattern.exec(content)) !== null) {
239302
- const componentId = inlineMatch[1];
239303
- const componentType = FUNCTION_NAME_TO_TYPE[funcName];
239304
- const lineNumber = content.substring(0, inlineMatch.index).split("\n").length;
239305
- components.push({
239306
- id: componentId,
239307
- type: componentType,
239308
- filePath: relativePath,
239309
- variableName: void 0,
239310
- // No variable name for inline
239311
- startLine: lineNumber,
239312
- isInline: true
239313
- });
239314
- }
239629
+ }
239630
+ if (!componentId && componentType === "statusComponents") {
239631
+ const typeProperty = configObject.getProperty("type");
239632
+ if (typeProperty && Node3.isPropertyAssignment(typeProperty)) {
239633
+ const typeValue = typeProperty.getInitializer();
239634
+ if (Node3.isStringLiteral(typeValue)) {
239635
+ componentId = typeValue.getLiteralValue();
239315
239636
  }
239316
239637
  }
239317
- const envCredentialsPattern = /registerEnvironmentSettings\s*\(\s*\{[^}]*?credentials:\s*\{([^}]+?)\}/gs;
239318
- let envMatch;
239319
- while ((envMatch = envCredentialsPattern.exec(content)) !== null) {
239320
- const credentialsBlock = envMatch[1];
239321
- const credentialPattern = /(\w+):\s*\{[^}]*?id:\s*['"`]([^'"`]+)['"`]/g;
239322
- let credMatch;
239323
- while ((credMatch = credentialPattern.exec(credentialsBlock)) !== null) {
239324
- const credentialKey = credMatch[1];
239325
- const credentialId = credMatch[2];
239326
- const lineNumber = content.substring(0, envMatch.index).split("\n").length;
239327
- components.push({
239328
- id: credentialId,
239329
- type: "credentials",
239330
- filePath: relativePath,
239331
- variableName: credentialKey,
239332
- // Use the key name as variable name
239333
- startLine: lineNumber,
239334
- isInline: true
239335
- // It's nested within environment settings
239336
- });
239638
+ }
239639
+ if (!componentId && componentType === "functionTools") {
239640
+ const nameProperty = configObject.getProperty("name");
239641
+ if (nameProperty && Node3.isPropertyAssignment(nameProperty)) {
239642
+ const nameValue = nameProperty.getInitializer();
239643
+ if (Node3.isStringLiteral(nameValue)) {
239644
+ componentId = nameValue.getLiteralValue();
239337
239645
  }
239338
239646
  }
239339
- } catch (error) {
239340
- console.warn(`Failed to parse file ${filePath}: ${error}`);
239341
239647
  }
239342
- return components;
239648
+ if (!componentId) {
239649
+ return null;
239650
+ }
239651
+ const startLine = callExpression.getStartLineNumber();
239652
+ return {
239653
+ id: componentId,
239654
+ type: componentType,
239655
+ filePath: relativePath,
239656
+ variableName,
239657
+ startLine,
239658
+ isInline
239659
+ };
239343
239660
  }
239344
239661
  function scanProjectForComponents(projectRoot, debug = false) {
239345
239662
  const allComponents = [];
239346
- function scanDirectory(dirPath) {
239347
- if (!existsSync8(dirPath)) return;
239663
+ if (!existsSync8(projectRoot)) {
239664
+ return allComponents;
239665
+ }
239666
+ const scanDir = (dir) => {
239348
239667
  try {
239349
- const entries = readdirSync2(dirPath);
239350
- for (const entry of entries) {
239351
- const fullPath = join10(dirPath, entry);
239668
+ const items = readdirSync2(dir);
239669
+ for (const item of items) {
239670
+ const fullPath = join10(dir, item);
239352
239671
  const stat = statSync(fullPath);
239353
- if (stat.isFile() && extname2(entry) === ".ts") {
239672
+ if (stat.isDirectory()) {
239673
+ if (!["node_modules", ".next", ".git", "dist", "build"].includes(item) && !item.startsWith(".temp-validation-")) {
239674
+ scanDir(fullPath);
239675
+ }
239676
+ } else if (stat.isFile() && [".ts", ".tsx", ".js", ".jsx"].includes(extname2(item))) {
239354
239677
  const fileComponents = parseFileForComponents(fullPath, projectRoot, debug);
239355
239678
  allComponents.push(...fileComponents);
239356
- } else if (stat.isDirectory() && !entry.startsWith(".") && entry !== "node_modules") {
239357
- scanDirectory(fullPath);
239358
239679
  }
239359
239680
  }
239360
239681
  } catch (error) {
239361
- console.warn(`Failed to scan directory ${dirPath}: ${error}`);
239682
+ if (debug) {
239683
+ console.warn(`Failed to scan directory ${dir}: ${error}`);
239684
+ }
239362
239685
  }
239363
- }
239364
- scanDirectory(projectRoot);
239686
+ };
239687
+ scanDir(projectRoot);
239365
239688
  return allComponents;
239366
239689
  }
239367
239690
  function buildComponentRegistryFromParsing(projectRoot, debug = false) {
@@ -239381,18 +239704,26 @@ function buildComponentRegistryFromParsing(projectRoot, debug = false) {
239381
239704
  const registeredTypeIds = /* @__PURE__ */ new Set();
239382
239705
  for (const component of allComponents) {
239383
239706
  const typeId = `${component.type}:${component.id}`;
239384
- if (registeredTypeIds.has(typeId)) {
239707
+ if (registeredTypeIds.has(typeId) && !component.overrideExisting) {
239385
239708
  continue;
239386
239709
  }
239387
239710
  registeredTypeIds.add(typeId);
239388
239711
  if (component.variableName) {
239389
- registry2.register(
239390
- component.id,
239391
- component.type,
239392
- component.filePath,
239393
- component.variableName,
239394
- component.isInline
239395
- );
239712
+ if (component.overrideExisting && component.type === "credentials") {
239713
+ registry2.overrideCredentialWithEnvKey(
239714
+ component.id,
239715
+ component.filePath,
239716
+ component.variableName
239717
+ );
239718
+ } else {
239719
+ registry2.register(
239720
+ component.id,
239721
+ component.type,
239722
+ component.filePath,
239723
+ component.variableName,
239724
+ component.isInline
239725
+ );
239726
+ }
239396
239727
  } else {
239397
239728
  registry2.register(
239398
239729
  component.id,
@@ -239464,84 +239795,171 @@ var init_component_parser = __esm({
239464
239795
 
239465
239796
  // src/commands/pull-v3/targeted-typescript-placeholders.ts
239466
239797
  import { randomBytes as randomBytes2 } from "crypto";
239798
+ import { Node as Node4, Project as Project2 } from "ts-morph";
239467
239799
  function generatePlaceholderId() {
239468
239800
  return randomBytes2(4).toString("hex").toUpperCase();
239469
239801
  }
239470
239802
  function createTargetedTypeScriptPlaceholders(content, debug = false) {
239471
239803
  const replacements = {};
239472
- let processedContent = content;
239473
239804
  let replacedFields = 0;
239474
239805
  const originalSize = content.length;
239475
- const promptRegex = /(\s+prompt:\s*)((['"`])([^]*?)\3)/g;
239476
- processedContent = processedContent.replace(promptRegex, (match2, prefix, fullValue) => {
239477
- if (fullValue.length >= MIN_REPLACEMENT_LENGTH) {
239478
- const placeholder = `<PROMPT_${generatePlaceholderId()}>`;
239479
- replacements[placeholder] = fullValue;
239480
- replacedFields++;
239481
- return `${prefix}${placeholder}`;
239482
- }
239483
- return match2;
239484
- });
239485
- const descriptionRegex = /(\s+description:\s*)((['"`])([^]*?)\3)/g;
239486
- processedContent = processedContent.replace(descriptionRegex, (match2, prefix, fullValue) => {
239487
- if (fullValue.length >= MIN_REPLACEMENT_LENGTH) {
239488
- const placeholder = `<DESC_${generatePlaceholderId()}>`;
239489
- replacements[placeholder] = fullValue;
239490
- replacedFields++;
239491
- return `${prefix}${placeholder}`;
239492
- }
239493
- return match2;
239494
- });
239495
- const inputSchemaRegex = /(\s+inputSchema:\s*)(\{[^{}]*(?:\{[^{}]*\}[^{}]*)*\})/g;
239496
- processedContent = processedContent.replace(inputSchemaRegex, (match2, prefix, schemaObject) => {
239497
- if (schemaObject.length >= MIN_REPLACEMENT_LENGTH) {
239498
- const placeholder = `<INPUT_SCHEMA_${generatePlaceholderId()}>`;
239499
- replacements[placeholder] = schemaObject;
239500
- replacedFields++;
239501
- return `${prefix}${placeholder}`;
239502
- }
239503
- return match2;
239504
- });
239505
- const detailsSchemaRegex = /(\s+detailsSchema:\s*)(z\.object\(\{[^]*?\}\)(?:\.[^,}\s]+)*)/g;
239506
- processedContent = processedContent.replace(detailsSchemaRegex, (match2, prefix, schemaObject) => {
239507
- if (schemaObject.length >= MIN_REPLACEMENT_LENGTH) {
239508
- const placeholder = `<DETAILS_SCHEMA_${generatePlaceholderId()}>`;
239509
- replacements[placeholder] = schemaObject;
239510
- replacedFields++;
239511
- return `${prefix}${placeholder}`;
239512
- }
239513
- return match2;
239514
- });
239515
- const propsRegex = /(\s+props:\s*)(z\.object\(\{[^]*?\}\)(?:\.[^,}\s]+)*)/g;
239516
- processedContent = processedContent.replace(propsRegex, (match2, prefix, propsObject) => {
239517
- if (propsObject.length >= MIN_REPLACEMENT_LENGTH) {
239518
- const placeholder = `<PROPS_${generatePlaceholderId()}>`;
239519
- replacements[placeholder] = propsObject;
239520
- replacedFields++;
239521
- return `${prefix}${placeholder}`;
239522
- }
239523
- return match2;
239524
- });
239525
- const processedSize = processedContent.length;
239526
- const savings = originalSize - processedSize;
239527
- const savingsPercentage = originalSize > 0 ? savings / originalSize * 100 : 0;
239528
- return {
239529
- processedContent,
239530
- replacements,
239531
- stats: {
239532
- originalSize,
239533
- processedSize,
239534
- savings,
239535
- savingsPercentage,
239536
- replacedFields
239537
- }
239538
- };
239806
+ try {
239807
+ const project = new Project2({ useInMemoryFileSystem: true });
239808
+ const sourceFile = project.createSourceFile("temp.ts", content);
239809
+ const replacementOperations = [];
239810
+ sourceFile.forEachDescendant((node) => {
239811
+ if (Node4.isPropertyAssignment(node)) {
239812
+ const propertyName = node.getName();
239813
+ const valueNode = node.getInitializer();
239814
+ if (!valueNode) return;
239815
+ let valueText = valueNode.getText();
239816
+ if (valueText.trim().length < MIN_REPLACEMENT_LENGTH) return;
239817
+ let placeholderPrefix = "";
239818
+ switch (propertyName) {
239819
+ case "prompt":
239820
+ placeholderPrefix = "PROMPT";
239821
+ break;
239822
+ case "description":
239823
+ placeholderPrefix = "DESC";
239824
+ break;
239825
+ case "inputSchema":
239826
+ placeholderPrefix = "INPUT_SCHEMA";
239827
+ break;
239828
+ case "detailsSchema":
239829
+ placeholderPrefix = "DETAILS_SCHEMA";
239830
+ break;
239831
+ case "props":
239832
+ placeholderPrefix = "PROPS";
239833
+ break;
239834
+ case "render":
239835
+ placeholderPrefix = "RENDER";
239836
+ break;
239837
+ default:
239838
+ return;
239839
+ }
239840
+ const start2 = valueNode.getStart();
239841
+ let end = valueNode.getEnd();
239842
+ const propertyAssignment = node;
239843
+ const propertyEnd = propertyAssignment.getEnd();
239844
+ if (propertyName === "inputSchema" || propertyName === "render") {
239845
+ let searchStart = start2;
239846
+ let braceCount = 0;
239847
+ let correctEnd = -1;
239848
+ let inString = false;
239849
+ let stringChar = "";
239850
+ for (let i3 = searchStart; i3 < content.length; i3++) {
239851
+ const char = content[i3];
239852
+ const prevChar = i3 > 0 ? content[i3 - 1] : "";
239853
+ if ((char === '"' || char === "'") && prevChar !== "\\") {
239854
+ if (!inString) {
239855
+ inString = true;
239856
+ stringChar = char;
239857
+ } else if (char === stringChar) {
239858
+ inString = false;
239859
+ stringChar = "";
239860
+ }
239861
+ }
239862
+ if (!inString) {
239863
+ if (char === "{") {
239864
+ braceCount++;
239865
+ } else if (char === "}") {
239866
+ braceCount--;
239867
+ if (braceCount === 0) {
239868
+ let j3 = i3 + 1;
239869
+ while (j3 < content.length && /\s/.test(content[j3])) {
239870
+ j3++;
239871
+ }
239872
+ if (j3 < content.length && content[j3] === ",") {
239873
+ correctEnd = j3 + 1;
239874
+ break;
239875
+ }
239876
+ }
239877
+ }
239878
+ }
239879
+ }
239880
+ if (correctEnd > start2 && correctEnd < end + 100) {
239881
+ end = correctEnd;
239882
+ valueText = content.slice(start2, end);
239883
+ }
239884
+ } else {
239885
+ const textAfterValue = content.slice(end, end + 20);
239886
+ if (!textAfterValue.match(/^\s*[,}]/)) {
239887
+ let correctEnd = end;
239888
+ while (correctEnd > start2 && !content.slice(correctEnd, correctEnd + 10).match(/^\s*[,}]/)) {
239889
+ correctEnd--;
239890
+ }
239891
+ if (correctEnd > start2) {
239892
+ end = correctEnd;
239893
+ valueText = content.slice(start2, end);
239894
+ } else {
239895
+ return;
239896
+ }
239897
+ }
239898
+ }
239899
+ if (end > propertyEnd) {
239900
+ return;
239901
+ }
239902
+ const actualText = content.slice(start2, end);
239903
+ if (valueText !== actualText) {
239904
+ return;
239905
+ }
239906
+ const finalTextAfterValue = content.slice(end, end + 20);
239907
+ if (!finalTextAfterValue.match(/^\s*[,}]/)) {
239908
+ return;
239909
+ }
239910
+ const placeholder = `<${placeholderPrefix}_${generatePlaceholderId()}>`;
239911
+ replacements[placeholder] = valueText;
239912
+ replacedFields++;
239913
+ replacementOperations.push({
239914
+ start: start2,
239915
+ end,
239916
+ placeholder,
239917
+ originalText: valueText
239918
+ // This now matches what we'll actually replace
239919
+ });
239920
+ }
239921
+ });
239922
+ replacementOperations.sort((a2, b3) => b3.start - a2.start);
239923
+ let processedContent = content;
239924
+ for (const op of replacementOperations) {
239925
+ processedContent = processedContent.slice(0, op.start) + op.placeholder + processedContent.slice(op.end);
239926
+ }
239927
+ const processedSize = processedContent.length;
239928
+ const savings = originalSize - processedSize;
239929
+ const savingsPercentage = originalSize > 0 ? savings / originalSize * 100 : 0;
239930
+ return {
239931
+ processedContent,
239932
+ replacements,
239933
+ stats: {
239934
+ originalSize,
239935
+ processedSize,
239936
+ savings,
239937
+ savingsPercentage,
239938
+ replacedFields
239939
+ }
239940
+ };
239941
+ } catch (error) {
239942
+ return {
239943
+ processedContent: content,
239944
+ replacements: {},
239945
+ stats: {
239946
+ originalSize,
239947
+ processedSize: originalSize,
239948
+ savings: 0,
239949
+ savingsPercentage: 0,
239950
+ replacedFields: 0
239951
+ }
239952
+ };
239953
+ }
239539
239954
  }
239540
239955
  function restoreTargetedTypeScriptPlaceholders(content, replacements) {
239541
239956
  let restoredContent = content;
239542
239957
  const sortedPlaceholders = Object.keys(replacements).sort((a2, b3) => b3.length - a2.length);
239543
239958
  for (const placeholder of sortedPlaceholders) {
239544
239959
  const originalValue = replacements[placeholder];
239960
+ if (!restoredContent.includes(placeholder)) {
239961
+ continue;
239962
+ }
239545
239963
  restoredContent = restoredContent.replace(placeholder, originalValue);
239546
239964
  }
239547
239965
  return restoredContent;
@@ -239624,8 +240042,46 @@ function calculateCostEstimate(promptTokens, completionTokens) {
239624
240042
  return promptCost + completionCost;
239625
240043
  }
239626
240044
  async function mergeComponentsWithLLM(request) {
239627
- const { oldContent, newContent, modifiedComponents, filePath } = request;
240045
+ const {
240046
+ oldContent,
240047
+ newContent,
240048
+ modifiedComponents,
240049
+ filePath,
240050
+ newComponents,
240051
+ componentsToExport
240052
+ } = request;
239628
240053
  const componentList = modifiedComponents.map((c2) => `- ${c2.componentType}:${c2.componentId}`).join("\n");
240054
+ const newComponentsList = newComponents && newComponents.length > 0 ? newComponents.map((c2) => {
240055
+ const currentFilePath = filePath.replace(/^.*\/([^/]+\/[^/]+)$/, "$1");
240056
+ const currentDir = currentFilePath.replace(/\/[^/]+$/, "");
240057
+ let componentPath = c2.filePath;
240058
+ if (componentPath.includes(".temp-")) {
240059
+ componentPath = componentPath.replace(/^.*\.temp-[^/]+\//, "");
240060
+ }
240061
+ componentPath = componentPath.replace(/\.ts$/, "");
240062
+ const importPath = calculateRelativeImportPath(currentDir, componentPath);
240063
+ const variableName = c2.componentId.replace(
240064
+ /-([a-z])/g,
240065
+ (_3, letter) => letter.toUpperCase()
240066
+ );
240067
+ return `- ${c2.componentType}:${c2.componentId} (import as: import { ${variableName} } from '${importPath}')`;
240068
+ }).join("\n") : "";
240069
+ function calculateRelativeImportPath(fromDir, toPath) {
240070
+ const fromParts = fromDir.split("/");
240071
+ const toParts = toPath.split("/");
240072
+ let commonLength = 0;
240073
+ while (commonLength < fromParts.length && commonLength < toParts.length - 1 && fromParts[commonLength] === toParts[commonLength]) {
240074
+ commonLength++;
240075
+ }
240076
+ const upLevels = fromParts.length - commonLength;
240077
+ let relativePath = "";
240078
+ for (let i3 = 0; i3 < upLevels; i3++) {
240079
+ relativePath += "../";
240080
+ }
240081
+ relativePath += toParts.slice(commonLength).join("/");
240082
+ return relativePath.startsWith("../") ? relativePath : "./" + relativePath;
240083
+ }
240084
+ const componentsToExportList = componentsToExport && componentsToExport.length > 0 ? componentsToExport.map((c2) => `- ${c2.variableName} (${c2.reason})`).join("\n") : "";
239629
240085
  const prompt = `You are a TypeScript code expert tasked with intelligently merging component updates.
239630
240086
 
239631
240087
  ## Task
@@ -239633,7 +240089,16 @@ Merge the OLD file content with NEW component definitions, preserving the origin
239633
240089
 
239634
240090
  ## Modified Components to Update
239635
240091
  ${componentList}
240092
+ ${newComponentsList ? `
240093
+ ## New Components Available (can be imported)
240094
+ ${newComponentsList}
240095
+ ` : ""}${componentsToExportList ? `
240096
+ ## Components That Need To Be Exported
240097
+ The following existing components are referenced by new components and must be exported:
240098
+ ${componentsToExportList}
239636
240099
 
240100
+ Ensure these components have export statements (convert \`const\` to \`export const\`, or add \`export\` to existing declarations).
240101
+ ` : ""}
239637
240102
  ## Instructions
239638
240103
  0. **Please ensure you focus changes to minimize git diff size.** We want a clean git history.
239639
240104
  1. **Preserve original structure**: Keep imports, exports, comments, and overall file organization
@@ -239642,7 +240107,13 @@ ${componentList}
239642
240107
  4. **Improve schemas**: Use better zod schemas from the new content where applicable. E.g. if the new content uses something like z.union([z.null(), z.string()]), use z.string().nullable() instead.
239643
240108
  5. **Keep variable names**: Preserve original variable names and declarations
239644
240109
  6. **Preserve non-component code**: Keep any non-component logic, comments, or utilities
239645
- 7. **Please leave all imports at the top of the file.** Don't use .js imports, use .ts imports instead. (import example from './example')
240110
+ 7. **Smart import handling**:
240111
+ - Please leave all imports at the top of the file. Don't use .js imports, use .ts imports instead. (import example from './example')
240112
+ - Preserve all imports from the original content that are not modified.
240113
+ - For NEW components listed above, add proper import statements
240114
+ - For components that exist in the same file (modified components), DO NOT add import statements
240115
+ - Remove any incorrect imports from the NEW component definitions that reference same-file components
240116
+ - Use relative paths for imports (e.g., './example' not './example.js')
239646
240117
  8. **Format JavaScript functions for maximum readability**:
239647
240118
  - When you see compressed/minified function code like \`async({params})=>{...code...}\`, expand and prettify it
239648
240119
  - Add proper line breaks, spacing, and indentation to make the function readable
@@ -239656,12 +240127,12 @@ ${componentList}
239656
240127
  }
239657
240128
  \`\`\`
239658
240129
 
239659
- ## OLD Content:
240130
+ ## OLD File to be updated with new component definitions:
239660
240131
  \`\`\`typescript
239661
240132
  ${oldContent}
239662
240133
  \`\`\`
239663
240134
 
239664
- ## NEW Component Definitions:
240135
+ ## NEW Component Definitions to replace/add to the old file:
239665
240136
  \`\`\`typescript
239666
240137
  ${newContent}
239667
240138
  \`\`\`
@@ -239672,11 +240143,12 @@ Provide the merged TypeScript file that:
239672
240143
  - Updates ONLY the modified components listed above
239673
240144
  - Maintains consistent code style
239674
240145
  - Uses improved schemas where beneficial
239675
- - Preserves all imports, exports, and other code
240146
+ - Preserves all imports, exports, and other code that are necessary to keep the file working.
239676
240147
  - **Formats all function code beautifully with proper spacing, line breaks, and indentation**
239677
240148
  - **Ensures all syntax is valid and compilable TypeScript/JavaScript**
239678
240149
  - Start the code immidiately with the first line of the file, skip any backticks or other formatting announcing that it is a code block or typescript file.
239679
240150
  - Please follow biomes.dev code style.
240151
+ - Please remember the NEW component definitions are to replace/add to the old file.
239680
240152
 
239681
240153
  Return only the merged TypeScript code without any explanation or markdown formatting.`;
239682
240154
  try {
@@ -239755,6 +240227,125 @@ import {
239755
240227
  } from "fs";
239756
240228
  import { basename as basename2, dirname as dirname7, join as join11 } from "path";
239757
240229
  import chalk11 from "chalk";
240230
+ function getObjectPreview(obj, maxLength = 200) {
240231
+ if (obj === null) return "null";
240232
+ if (obj === void 0) return "undefined";
240233
+ try {
240234
+ if (typeof obj === "object") {
240235
+ const jsonStr = JSON.stringify(obj, null, 0);
240236
+ if (jsonStr.length <= maxLength) {
240237
+ return jsonStr;
240238
+ } else {
240239
+ if (obj.component && typeof obj.component === "string") {
240240
+ const componentPreview = obj.component.length > 100 ? obj.component.substring(0, 100) + "..." : obj.component;
240241
+ return `{component: "${componentPreview}", mockData: ${obj.mockData ? "present" : "null"}}`;
240242
+ }
240243
+ return jsonStr.substring(0, maxLength) + "...";
240244
+ }
240245
+ } else {
240246
+ const str = String(obj);
240247
+ return str.length > maxLength ? str.substring(0, maxLength) + "..." : str;
240248
+ }
240249
+ } catch (error) {
240250
+ return `[Error stringifying: ${typeof obj}]`;
240251
+ }
240252
+ }
240253
+ function extractCredentialIds2(agentObj) {
240254
+ const credentialIds = [];
240255
+ if (agentObj.credentials && Array.isArray(agentObj.credentials)) {
240256
+ agentObj.credentials.forEach((cred) => {
240257
+ if (cred.id) {
240258
+ credentialIds.push(cred.id);
240259
+ }
240260
+ });
240261
+ }
240262
+ if (agentObj.contextConfig?.contextVariables) {
240263
+ Object.values(agentObj.contextConfig.contextVariables).forEach((variable) => {
240264
+ if (variable && typeof variable === "object" && variable.credentialReferenceId) {
240265
+ credentialIds.push(variable.credentialReferenceId);
240266
+ }
240267
+ });
240268
+ }
240269
+ return [...new Set(credentialIds)];
240270
+ }
240271
+ function findKeyDifferences(obj1, obj2, componentId) {
240272
+ const differences = [];
240273
+ const allKeys = /* @__PURE__ */ new Set([...Object.keys(obj1 || {}), ...Object.keys(obj2 || {})]);
240274
+ for (const key of allKeys) {
240275
+ const val1 = obj1?.[key];
240276
+ const val2 = obj2?.[key];
240277
+ if (key.startsWith("_") || key === "createdAt" || key === "updatedAt") {
240278
+ continue;
240279
+ }
240280
+ if (key === "credentials") {
240281
+ const creds1 = extractCredentialIds2(obj1);
240282
+ const creds2 = extractCredentialIds2(obj2);
240283
+ creds1.sort();
240284
+ creds2.sort();
240285
+ if (JSON.stringify(creds1) !== JSON.stringify(creds2)) {
240286
+ differences.push(
240287
+ `~ credentials: usage differs (${creds1.join(", ")} vs ${creds2.join(", ")})`
240288
+ );
240289
+ }
240290
+ continue;
240291
+ }
240292
+ const val1IsEmpty = val1 === null || val1 === void 0 || Array.isArray(val1) && val1.length === 0 || typeof val1 === "object" && val1 !== null && Object.keys(val1).length === 0;
240293
+ const val2IsEmpty = val2 === null || val2 === void 0 || Array.isArray(val2) && val2.length === 0 || typeof val2 === "object" && val2 !== null && Object.keys(val2).length === 0;
240294
+ if (val1IsEmpty && val2IsEmpty) {
240295
+ continue;
240296
+ }
240297
+ if (val1IsEmpty && !val2IsEmpty) {
240298
+ differences.push(`+ ${key}: ${typeof val2} (only in remote)`);
240299
+ } else if (!val1IsEmpty && val2IsEmpty) {
240300
+ differences.push(`- ${key}: ${typeof val1} (only in generated)`);
240301
+ } else if (val1 !== val2) {
240302
+ if (Array.isArray(val1) && Array.isArray(val2)) {
240303
+ if (val1.length !== val2.length) {
240304
+ differences.push(`~ ${key}: array length differs (${val1.length} vs ${val2.length})`);
240305
+ }
240306
+ } else if (typeof val1 === "object" && typeof val2 === "object" && val1 !== null && val2 !== null) {
240307
+ const keys1 = Object.keys(val1).filter((k4) => {
240308
+ if (k4.startsWith("_") || k4 === "createdAt" || k4 === "updatedAt" || k4 === "tenantId" || k4 === "projectId" || k4 === "agentId") {
240309
+ return false;
240310
+ }
240311
+ const v3 = val1[k4];
240312
+ return !(v3 === null || v3 === void 0 || Array.isArray(v3) && v3.length === 0 || typeof v3 === "object" && v3 !== null && Object.keys(v3).length === 0);
240313
+ });
240314
+ const keys2 = Object.keys(val2).filter((k4) => {
240315
+ if (k4.startsWith("_") || k4 === "createdAt" || k4 === "updatedAt" || k4 === "tenantId" || k4 === "projectId" || k4 === "agentId") {
240316
+ return false;
240317
+ }
240318
+ const v3 = val2[k4];
240319
+ return !(v3 === null || v3 === void 0 || Array.isArray(v3) && v3.length === 0 || typeof v3 === "object" && v3 !== null && Object.keys(v3).length === 0);
240320
+ });
240321
+ const subKeys1 = keys1.length;
240322
+ const subKeys2 = keys2.length;
240323
+ if (subKeys1 !== subKeys2) {
240324
+ differences.push(`~ ${key}: object size differs (${subKeys1} vs ${subKeys2} keys)`);
240325
+ }
240326
+ } else if (typeof val1 !== typeof val2) {
240327
+ differences.push(`~ ${key}: type differs (${typeof val1} vs ${typeof val2})`);
240328
+ } else {
240329
+ if (key === "render" || key === "component") {
240330
+ const val1Preview = getObjectPreview(val1, 200);
240331
+ const val2Preview = getObjectPreview(val2, 200);
240332
+ differences.push(`~ ${key}:`);
240333
+ differences.push(` Generated: ${val1Preview}`);
240334
+ differences.push(` Remote: ${val2Preview}`);
240335
+ } else {
240336
+ const val1Str = String(val1);
240337
+ const val2Str = String(val2);
240338
+ if (val1Str.length < 100 && val2Str.length < 100) {
240339
+ differences.push(`~ ${key}: "${val1Str}" vs "${val2Str}"`);
240340
+ } else {
240341
+ differences.push(`~ ${key}: values differ (both ${typeof val1})`);
240342
+ }
240343
+ }
240344
+ }
240345
+ }
240346
+ }
240347
+ return differences.slice(0, 10);
240348
+ }
239758
240349
  function getComponentFromProject(project, componentType, componentId) {
239759
240350
  switch (componentType) {
239760
240351
  case "credentials":
@@ -239763,6 +240354,39 @@ function getComponentFromProject(project, componentType, componentId) {
239763
240354
  return project.tools?.[componentId];
239764
240355
  case "agents":
239765
240356
  return project.agents?.[componentId];
240357
+ case "subAgents":
240358
+ if (project.agents) {
240359
+ for (const [agentId, agentData] of Object.entries(project.agents)) {
240360
+ if (agentData.subAgents && agentData.subAgents[componentId]) {
240361
+ return agentData.subAgents[componentId];
240362
+ }
240363
+ }
240364
+ }
240365
+ return null;
240366
+ case "contextConfigs":
240367
+ if (project.agents) {
240368
+ for (const [agentId, agentData] of Object.entries(project.agents)) {
240369
+ if (agentData.contextConfig && agentData.contextConfig.id === componentId) {
240370
+ return agentData.contextConfig;
240371
+ }
240372
+ }
240373
+ }
240374
+ return null;
240375
+ case "fetchDefinitions":
240376
+ if (project.agents) {
240377
+ for (const [agentId, agentData] of Object.entries(project.agents)) {
240378
+ if (agentData.contextConfig?.contextVariables) {
240379
+ for (const [varId, variable] of Object.entries(
240380
+ agentData.contextConfig.contextVariables
240381
+ )) {
240382
+ if (variable && typeof variable === "object" && variable.id === componentId) {
240383
+ return variable;
240384
+ }
240385
+ }
240386
+ }
240387
+ }
240388
+ }
240389
+ return null;
239766
240390
  case "dataComponents":
239767
240391
  return project.dataComponents?.[componentId];
239768
240392
  case "artifactComponents":
@@ -239823,12 +240447,24 @@ async function validateProjectEquivalence(tempDir, remoteProject) {
239823
240447
  componentType,
239824
240448
  modifiedId
239825
240449
  );
239826
- console.log(
239827
- chalk11.gray(`Generated Component: ${JSON.stringify(generatedComponent, null, 2)}`)
239828
- );
239829
- console.log(
239830
- chalk11.gray(`Remote Component: ${JSON.stringify(remoteComponent, null, 2)}`)
239831
- );
240450
+ if (generatedComponent && remoteComponent) {
240451
+ const differences = findKeyDifferences(
240452
+ generatedComponent,
240453
+ remoteComponent,
240454
+ modifiedId
240455
+ );
240456
+ if (differences.length > 0) {
240457
+ differences.forEach((diff) => {
240458
+ console.log(chalk11.gray(` ${diff}`));
240459
+ });
240460
+ } else {
240461
+ console.log(chalk11.gray(` No key-level differences detected`));
240462
+ }
240463
+ } else if (!generatedComponent) {
240464
+ console.log(chalk11.red(` Component missing in generated project`));
240465
+ } else if (!remoteComponent) {
240466
+ console.log(chalk11.red(` Component missing in remote project`));
240467
+ }
239832
240468
  }
239833
240469
  }
239834
240470
  if (changes.deleted.length > 0) {
@@ -239859,15 +240495,26 @@ async function validateTempDirectory(originalProjectRoot, tempDirName, remotePro
239859
240495
  console.log(chalk11.green(` [Y] Yes - Replace files and clean up temp directory`));
239860
240496
  console.log(chalk11.red(` [N] No - Keep temp directory for manual review`));
239861
240497
  return new Promise((resolve6) => {
240498
+ if (isWaitingForInput && currentKeypressHandler) {
240499
+ process.stdin.removeListener("data", currentKeypressHandler);
240500
+ }
239862
240501
  process.stdin.removeAllListeners("data");
239863
- process.stdin.setMaxListeners(15);
239864
- process.stdin.setRawMode(true);
239865
- process.stdin.resume();
240502
+ if (!process.stdin.isRaw) {
240503
+ process.stdin.setRawMode(true);
240504
+ }
240505
+ if (process.stdin.isPaused()) {
240506
+ process.stdin.resume();
240507
+ }
239866
240508
  process.stdin.setEncoding("utf8");
239867
240509
  const onKeypress = (key) => {
240510
+ if (!isWaitingForInput) {
240511
+ return;
240512
+ }
240513
+ isWaitingForInput = false;
240514
+ currentKeypressHandler = null;
240515
+ process.stdin.removeAllListeners("data");
239868
240516
  process.stdin.setRawMode(false);
239869
240517
  process.stdin.pause();
239870
- process.stdin.removeAllListeners("data");
239871
240518
  const normalizedKey = key.toLowerCase();
239872
240519
  if (normalizedKey === "y") {
239873
240520
  console.log(chalk11.green(`
@@ -239897,7 +240544,9 @@ async function validateTempDirectory(originalProjectRoot, tempDirName, remotePro
239897
240544
  process.exit(0);
239898
240545
  }
239899
240546
  };
239900
- process.stdin.on("data", onKeypress);
240547
+ currentKeypressHandler = onKeypress;
240548
+ isWaitingForInput = true;
240549
+ process.stdin.once("data", onKeypress);
239901
240550
  process.stdout.write(chalk11.cyan("\nPress [Y] for Yes or [N] for No: "));
239902
240551
  });
239903
240552
  } else {
@@ -239965,6 +240614,7 @@ function overwriteProjectFiles(originalProjectRoot, tempDirName, tempDir) {
239965
240614
  console.log(chalk11.yellow(` Generated files remain in: ${tempDirName} for manual review`));
239966
240615
  }
239967
240616
  }
240617
+ var isWaitingForInput, currentKeypressHandler;
239968
240618
  var init_project_validator = __esm({
239969
240619
  "src/commands/pull-v3/project-validator.ts"() {
239970
240620
  "use strict";
@@ -239972,6 +240622,8 @@ var init_project_validator = __esm({
239972
240622
  init_pull_v3();
239973
240623
  init_project_comparator();
239974
240624
  init_component_registry();
240625
+ isWaitingForInput = false;
240626
+ currentKeypressHandler = null;
239975
240627
  }
239976
240628
  });
239977
240629
 
@@ -240089,26 +240741,40 @@ async function runBiomeOnDirectory(dirPath) {
240089
240741
  return false;
240090
240742
  }
240091
240743
  }
240092
- function generateUpdatedComponentContent(componentType, componentId, componentData, remoteProject, localRegistry, environment) {
240744
+ function generateUpdatedComponentContent(componentType, componentId, componentData, remoteProject, localRegistry, environment, actualFilePath) {
240093
240745
  const defaultStyle = {
240094
240746
  quotes: "single",
240095
240747
  indentation: " ",
240096
240748
  semicolons: true
240097
240749
  };
240098
240750
  switch (componentType) {
240099
- case "agents":
240100
- return generateAgentFile(componentId, componentData, defaultStyle, localRegistry);
240751
+ case "agents": {
240752
+ const contextConfigData = componentData.contextConfig;
240753
+ const projectModels = remoteProject.models;
240754
+ return generateAgentFile(
240755
+ componentId,
240756
+ componentData,
240757
+ defaultStyle,
240758
+ localRegistry,
240759
+ contextConfigData,
240760
+ projectModels,
240761
+ actualFilePath
240762
+ );
240763
+ }
240101
240764
  case "subAgents": {
240102
240765
  const parentInfo = findSubAgentWithParent(remoteProject, componentId);
240103
240766
  const parentAgentId = parentInfo?.parentAgentId;
240104
240767
  const contextConfigData = parentInfo?.contextConfigData;
240768
+ const parentModels = parentInfo ? remoteProject.agents?.[parentInfo.parentAgentId]?.models : void 0;
240105
240769
  return generateSubAgentFile(
240106
240770
  componentId,
240107
240771
  componentData,
240108
240772
  defaultStyle,
240109
240773
  localRegistry,
240110
240774
  parentAgentId,
240111
- contextConfigData
240775
+ contextConfigData,
240776
+ parentModels,
240777
+ actualFilePath
240112
240778
  );
240113
240779
  }
240114
240780
  case "tools":
@@ -240148,7 +240814,7 @@ function generateUpdatedComponentContent(componentType, componentId, componentDa
240148
240814
  throw new Error(`No generator for component type: ${componentType}`);
240149
240815
  }
240150
240816
  }
240151
- async function updateModifiedComponents(comparison, remoteProject, localRegistry, projectRoot, environment, debug = false, providedTempDirName) {
240817
+ async function updateModifiedComponents(comparison, remoteProject, localRegistry, projectRoot, environment, debug = false, providedTempDirName, newComponents) {
240152
240818
  const results = [];
240153
240819
  const tempDirName = providedTempDirName || `.temp-${Date.now()}`;
240154
240820
  if (!providedTempDirName) {
@@ -240193,6 +240859,7 @@ async function updateModifiedComponents(comparison, remoteProject, localRegistry
240193
240859
  );
240194
240860
  for (const [filePath, fileComponents] of componentsByFile) {
240195
240861
  try {
240862
+ const relativeFilePath = filePath.replace(projectRoot + "/", "");
240196
240863
  const oldContent = readFileSync5(filePath, "utf8");
240197
240864
  const componentContentParts = [];
240198
240865
  const componentResults = [];
@@ -240239,9 +240906,46 @@ async function updateModifiedComponents(comparison, remoteProject, localRegistry
240239
240906
  }
240240
240907
  } else if (componentType === "credentials") {
240241
240908
  componentData = remoteProject.credentialReferences?.[componentId];
240909
+ } else if (componentType === "environments") {
240910
+ componentData = {
240911
+ name: `${componentId} Environment`,
240912
+ description: `Environment configuration for ${componentId}`,
240913
+ credentials: remoteProject.credentialReferences || {}
240914
+ };
240242
240915
  } else {
240243
240916
  const remoteComponents = remoteProject[componentType] || {};
240244
240917
  componentData = remoteComponents[componentId];
240918
+ if (componentType === "agents" && componentData && !componentData.credentials && remoteProject.credentialReferences) {
240919
+ const agentCredentials = [];
240920
+ const credentialSet = /* @__PURE__ */ new Set();
240921
+ if (componentData.contextConfig?.contextVariables) {
240922
+ for (const [varName, varData] of Object.entries(
240923
+ componentData.contextConfig.contextVariables
240924
+ )) {
240925
+ if (varData && typeof varData === "object" && varData.credentialReferenceId) {
240926
+ const credId = varData.credentialReferenceId;
240927
+ if (remoteProject.credentialReferences[credId] && !credentialSet.has(credId)) {
240928
+ credentialSet.add(credId);
240929
+ agentCredentials.push({ id: credId });
240930
+ }
240931
+ }
240932
+ }
240933
+ }
240934
+ for (const [credId, credData] of Object.entries(remoteProject.credentialReferences)) {
240935
+ if (credData.usedBy) {
240936
+ for (const usage of credData.usedBy) {
240937
+ if (usage.type === "agent" && usage.id === componentId && !credentialSet.has(credId)) {
240938
+ credentialSet.add(credId);
240939
+ agentCredentials.push({ id: credId });
240940
+ break;
240941
+ }
240942
+ }
240943
+ }
240944
+ }
240945
+ if (agentCredentials.length > 0) {
240946
+ componentData.credentials = agentCredentials;
240947
+ }
240948
+ }
240245
240949
  }
240246
240950
  if (!componentData) {
240247
240951
  componentResults.push({
@@ -240259,7 +240963,8 @@ async function updateModifiedComponents(comparison, remoteProject, localRegistry
240259
240963
  componentData,
240260
240964
  remoteProject,
240261
240965
  localRegistry,
240262
- environment
240966
+ environment,
240967
+ relativeFilePath
240263
240968
  );
240264
240969
  componentContentParts.push(`// ${componentType}:${componentId}
240265
240970
  ${componentContent}`);
@@ -240294,6 +240999,15 @@ ${componentContent}`);
240294
240999
  }
240295
241000
  }
240296
241001
  const newComponentContent = componentContentParts.join("\n\n");
241002
+ let componentsToExport = [];
241003
+ try {
241004
+ componentsToExport = analyzeComponentsToExport(
241005
+ newComponents || [],
241006
+ relativeFilePath,
241007
+ localRegistry
241008
+ );
241009
+ } catch (error) {
241010
+ }
240297
241011
  const mergeResult = await mergeComponentsWithLLM({
240298
241012
  oldContent,
240299
241013
  newContent: newComponentContent,
@@ -240301,7 +241015,9 @@ ${componentContent}`);
240301
241015
  componentId: c2.id,
240302
241016
  componentType: c2.type
240303
241017
  })),
240304
- filePath
241018
+ filePath,
241019
+ newComponents,
241020
+ componentsToExport
240305
241021
  });
240306
241022
  let finalContent;
240307
241023
  if (!mergeResult.success) {
@@ -240422,6 +241138,46 @@ ${componentContent}`);
240422
241138
  await validateTempDirectory(projectRoot, tempDirName, remoteProject);
240423
241139
  return results;
240424
241140
  }
241141
+ function analyzeComponentsToExport(newComponents, currentFilePath, localRegistry) {
241142
+ const componentsToExport = [];
241143
+ for (const newComp of newComponents) {
241144
+ if (newComp.filePath === currentFilePath) {
241145
+ continue;
241146
+ }
241147
+ const allLocalComponents = localRegistry.getAllComponents();
241148
+ for (const localComp of allLocalComponents) {
241149
+ const localCompRelativePath = localComp.filePath.startsWith("/") ? localComp.filePath.split("/").slice(-2).join("/") : localComp.filePath;
241150
+ if (localCompRelativePath === currentFilePath) {
241151
+ if (shouldComponentBeExported(localComp, newComponents)) {
241152
+ const existingExport = componentsToExport.find((c2) => c2.componentId === localComp.id);
241153
+ if (!existingExport) {
241154
+ componentsToExport.push({
241155
+ componentId: localComp.id,
241156
+ variableName: localComp.name,
241157
+ reason: `referenced by new component ${newComp.componentType}:${newComp.componentId}`
241158
+ });
241159
+ }
241160
+ }
241161
+ }
241162
+ }
241163
+ }
241164
+ return componentsToExport;
241165
+ }
241166
+ function shouldComponentBeExported(localComponent, newComponents) {
241167
+ if (localComponent.type === "agents" || localComponent.type === "subAgents") {
241168
+ return true;
241169
+ }
241170
+ if (localComponent.type === "tools" || localComponent.type === "functionTools") {
241171
+ return true;
241172
+ }
241173
+ if (localComponent.type === "contextConfigs") {
241174
+ return true;
241175
+ }
241176
+ if (localComponent.type === "artifactComponents") {
241177
+ return true;
241178
+ }
241179
+ return false;
241180
+ }
240425
241181
  var init_component_updater = __esm({
240426
241182
  "src/commands/pull-v3/component-updater.ts"() {
240427
241183
  "use strict";
@@ -240884,25 +241640,11 @@ function createProjectStructure(projectDir, projectId) {
240884
241640
  return paths;
240885
241641
  }
240886
241642
  function enrichCanDelegateToWithTypes(project, debug = false) {
240887
- if (debug) {
240888
- console.log(chalk14.gray("\u{1F527} Enriching canDelegateTo with type information..."));
240889
- }
240890
241643
  const agentIds = new Set(project.agents ? Object.keys(project.agents) : []);
240891
241644
  const subAgentIds = new Set(Object.keys(extractSubAgents(project)));
240892
241645
  const externalAgentIds = new Set(
240893
241646
  project.externalAgents ? Object.keys(project.externalAgents) : []
240894
241647
  );
240895
- if (debug) {
240896
- console.log(chalk14.gray(` Available agents: ${Array.from(agentIds).join(", ") || "none"}`));
240897
- console.log(
240898
- chalk14.gray(` Available subAgents: ${Array.from(subAgentIds).join(", ") || "none"}`)
240899
- );
240900
- console.log(
240901
- chalk14.gray(
240902
- ` Available externalAgents: ${Array.from(externalAgentIds).join(", ") || "none"}`
240903
- )
240904
- );
240905
- }
240906
241648
  const enrichCanDelegateToArray = (canDelegateTo, context) => {
240907
241649
  if (!Array.isArray(canDelegateTo)) return;
240908
241650
  for (let i3 = 0; i3 < canDelegateTo.length; i3++) {
@@ -240917,20 +241659,8 @@ function enrichCanDelegateToWithTypes(project, debug = false) {
240917
241659
  } else if (externalAgentIds.has(id)) {
240918
241660
  enrichedItem = { externalAgentId: id };
240919
241661
  } else {
240920
- if (debug) {
240921
- console.log(
240922
- chalk14.yellow(
240923
- ` Warning: canDelegateTo reference "${id}" in ${context} not found in any component collection`
240924
- )
240925
- );
240926
- }
240927
241662
  continue;
240928
241663
  }
240929
- if (debug && enrichedItem) {
240930
- console.log(
240931
- chalk14.gray(` Enriched "${id}" in ${context} -> ${JSON.stringify(enrichedItem)}`)
240932
- );
240933
- }
240934
241664
  canDelegateTo[i3] = enrichedItem;
240935
241665
  }
240936
241666
  };
@@ -240970,22 +241700,6 @@ async function readExistingProject(projectRoot, debug = false) {
240970
241700
  } catch (error) {
240971
241701
  const errorMessage = error instanceof Error ? error.message : String(error);
240972
241702
  const isCredentialError = errorMessage.includes("Credential") && errorMessage.includes("not found");
240973
- if (debug) {
240974
- if (isCredentialError) {
240975
- console.log(
240976
- chalk14.yellow(" \u26A0 Cannot load existing project - credentials not configured:")
240977
- );
240978
- console.log(chalk14.gray(` ${errorMessage}`));
240979
- console.log(
240980
- chalk14.gray(
240981
- " \u{1F4A1} This is expected if you haven't added credentials to environment files yet"
240982
- )
240983
- );
240984
- } else {
240985
- console.log(chalk14.red(" \u2717 Error parsing existing project:"));
240986
- console.log(chalk14.red(` ${errorMessage}`));
240987
- }
240988
- }
240989
241703
  return null;
240990
241704
  }
240991
241705
  }
@@ -241000,7 +241714,7 @@ async function pullV3Command(options) {
241000
241714
  }
241001
241715
  };
241002
241716
  performBackgroundVersionCheck();
241003
- console.log(chalk14.blue("\n\u{1F680} Pull v3 - Clean & Efficient"));
241717
+ console.log(chalk14.blue("\nInkeep Pull:"));
241004
241718
  if (options.introspect) {
241005
241719
  console.log(chalk14.gray(" Introspect mode \u2022 Complete regeneration \u2022 No comparison needed"));
241006
241720
  } else {
@@ -241097,16 +241811,6 @@ async function pullV3Command(options) {
241097
241811
  };
241098
241812
  }
241099
241813
  });
241100
- if (options.debug) {
241101
- const hoistedKeys = Object.keys(agentData.functions).filter(
241102
- (key) => !remoteProject.functions[key]
241103
- );
241104
- if (hoistedKeys.length > 0) {
241105
- console.log(
241106
- chalk14.gray(` Hoisted functions from agent ${agentId}: ${hoistedKeys.join(", ")}`)
241107
- );
241108
- }
241109
- }
241110
241814
  }
241111
241815
  }
241112
241816
  }
@@ -241123,14 +241827,6 @@ async function pullV3Command(options) {
241123
241827
  } else {
241124
241828
  delete agentData.tools;
241125
241829
  }
241126
- if (options.debug) {
241127
- const removedCount = originalToolCount - Object.keys(agentSpecificTools).length;
241128
- if (removedCount > 0) {
241129
- console.log(
241130
- chalk14.gray(` Filtered ${removedCount} project-level tools from agent ${agentId}`)
241131
- );
241132
- }
241133
- }
241134
241830
  }
241135
241831
  }
241136
241832
  }
@@ -241222,10 +241918,11 @@ async function pullV3Command(options) {
241222
241918
  (sum, changes) => sum + changes.added.length,
241223
241919
  0
241224
241920
  );
241921
+ let newComponentResults = [];
241225
241922
  if (newComponentCount > 0) {
241226
241923
  s4.start("Creating new component files in temp directory...");
241227
241924
  const { createNewComponents: createNewComponents2 } = await Promise.resolve().then(() => (init_new_component_generator(), new_component_generator_exports));
241228
- const newComponentResults = await createNewComponents2(
241925
+ newComponentResults = await createNewComponents2(
241229
241926
  comparison,
241230
241927
  remoteProject,
241231
241928
  localRegistry,
@@ -241266,6 +241963,12 @@ async function pullV3Command(options) {
241266
241963
  if (modifiedCount > 0) {
241267
241964
  s4.start("Applying modified components to temp directory...");
241268
241965
  const { updateModifiedComponents: updateModifiedComponents2 } = await Promise.resolve().then(() => (init_component_updater(), component_updater_exports));
241966
+ const newComponentsForContext = newComponentResults && newComponentResults.length > 0 ? newComponentResults.filter((result) => result.success).map((result) => ({
241967
+ componentId: result.componentId,
241968
+ componentType: result.componentType,
241969
+ filePath: result.filePath.replace(paths.projectRoot + "/", "")
241970
+ // Convert to relative path
241971
+ })) : void 0;
241269
241972
  const updateResults = await updateModifiedComponents2(
241270
241973
  comparison,
241271
241974
  remoteProject,
@@ -241273,8 +241976,9 @@ async function pullV3Command(options) {
241273
241976
  paths.projectRoot,
241274
241977
  options.env || "development",
241275
241978
  options.debug,
241276
- tempDirName
241979
+ tempDirName,
241277
241980
  // Use the temp directory we created
241981
+ newComponentsForContext
241278
241982
  );
241279
241983
  s4.message("Modified components applied");
241280
241984
  }