@inkeep/agents-cli 0.22.5 → 0.22.7

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 +657 -111
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -234489,10 +234489,13 @@ function generateMultiPlaceholderString(value, jsonPath, tracker) {
234489
234489
  }
234490
234490
  return value;
234491
234491
  }
234492
- function isJsonSchemaPath(path4) {
234492
+ function isJsonSchemaPath(path4, context) {
234493
234493
  if (path4.endsWith("contextConfig.headersSchema") || path4.endsWith("responseSchema")) {
234494
234494
  return true;
234495
234495
  }
234496
+ if (path4.endsWith("headersSchema") && path4.length > "headersSchema".length) {
234497
+ return true;
234498
+ }
234496
234499
  if (path4.includes("artifactComponents") && path4.endsWith("props")) {
234497
234500
  return true;
234498
234501
  }
@@ -234502,13 +234505,29 @@ function isJsonSchemaPath(path4) {
234502
234505
  if (path4.includes("statusComponents") && path4.endsWith("detailsSchema")) {
234503
234506
  return true;
234504
234507
  }
234508
+ if (path4.endsWith("inputSchema") || path4.endsWith("outputSchema")) {
234509
+ return true;
234510
+ }
234511
+ if (context?.fileType) {
234512
+ if (path4 === "props" && (context.fileType === "dataComponent" || context.fileType === "artifactComponent")) {
234513
+ return true;
234514
+ }
234515
+ if (path4 === "detailsSchema" && context.fileType === "statusComponent") {
234516
+ return true;
234517
+ }
234518
+ if (context.fileType === "contextConfig") {
234519
+ if (path4 === "headersSchema" || path4.endsWith("responseSchema")) {
234520
+ return true;
234521
+ }
234522
+ }
234523
+ }
234505
234524
  return false;
234506
234525
  }
234507
234526
  function updateTracker(tracker, placeholder, value) {
234508
234527
  tracker.placeholderToValue.set(placeholder, value);
234509
234528
  tracker.valueToPlaceholder.set(value, placeholder);
234510
234529
  }
234511
- function processObject(obj, tracker, path4 = "") {
234530
+ function processObject(obj, tracker, path4 = "", context) {
234512
234531
  if (typeof obj === "string") {
234513
234532
  if (containsTemplateLiterals(obj)) {
234514
234533
  return generateMultiPlaceholderString(obj, path4, tracker);
@@ -234531,7 +234550,7 @@ function processObject(obj, tracker, path4 = "") {
234531
234550
  }
234532
234551
  return obj;
234533
234552
  }
234534
- if (isJsonSchemaPath(path4)) {
234553
+ if (isJsonSchemaPath(path4, context)) {
234535
234554
  try {
234536
234555
  const zodSchema = jsonSchemaToZod(obj);
234537
234556
  return zodSchema;
@@ -234540,25 +234559,25 @@ function processObject(obj, tracker, path4 = "") {
234540
234559
  }
234541
234560
  }
234542
234561
  if (Array.isArray(obj)) {
234543
- return obj.map((item, index2) => processObject(item, tracker, `${path4}[${index2}]`));
234562
+ return obj.map((item, index2) => processObject(item, tracker, `${path4}[${index2}]`, context));
234544
234563
  }
234545
234564
  if (obj && typeof obj === "object") {
234546
234565
  const result = {};
234547
234566
  for (const [key, value] of Object.entries(obj)) {
234548
234567
  const currentPath = path4 ? `${path4}.${key}` : key;
234549
- result[key] = processObject(value, tracker, currentPath);
234568
+ result[key] = processObject(value, tracker, currentPath, context);
234550
234569
  }
234551
234570
  return result;
234552
234571
  }
234553
234572
  return obj;
234554
234573
  }
234555
- function createPlaceholders(data) {
234574
+ function createPlaceholders(data, context) {
234556
234575
  const tracker = {
234557
234576
  placeholderToValue: /* @__PURE__ */ new Map(),
234558
234577
  valueToPlaceholder: /* @__PURE__ */ new Map()
234559
234578
  };
234560
234579
  try {
234561
- const processedData = processObject(data, tracker);
234580
+ const processedData = processObject(data, tracker, "", context);
234562
234581
  const replacements = {};
234563
234582
  for (const [placeholder, value] of tracker.placeholderToValue.entries()) {
234564
234583
  replacements[placeholder] = value;
@@ -234681,8 +234700,8 @@ function createModel(config) {
234681
234700
  function cleanGeneratedCode(text2) {
234682
234701
  return text2.replace(/^```(?:typescript|ts)?\n?/, "").replace(/\n?```$/, "").trim();
234683
234702
  }
234684
- async function generateTextWithPlaceholders(model, data, promptTemplate, options, debug = false) {
234685
- const { processedData, replacements } = createPlaceholders(data);
234703
+ async function generateTextWithPlaceholders(model, data, promptTemplate, options, debug = false, context) {
234704
+ const { processedData, replacements } = context ? createPlaceholders(data, context) : createPlaceholders(data);
234686
234705
  if (debug && Object.keys(replacements).length > 0) {
234687
234706
  const savings = calculateTokenSavings(data, processedData);
234688
234707
  console.log(`[DEBUG] Placeholder optimization:`);
@@ -234765,7 +234784,34 @@ Generate ONLY the TypeScript code without any markdown or explanations.`;
234765
234784
  });
234766
234785
  writeFileSync3(outputPath, cleanGeneratedCode(text2));
234767
234786
  }
234768
- async function generateAgentFile(agentData, agentId, outputPath, modelSettings, debug = false) {
234787
+ function generateImportMappings(toolFilenames, componentFilenames) {
234788
+ let result = "";
234789
+ if (toolFilenames && toolFilenames.size > 0) {
234790
+ result += "TOOLS (use exact import paths):\n";
234791
+ for (const [toolId, fileName] of toolFilenames.entries()) {
234792
+ result += ` - Tool ID: "${toolId}" \u2192 Import: "../tools/${fileName.replace(".ts", "")}"
234793
+ `;
234794
+ }
234795
+ result += "\n";
234796
+ }
234797
+ if (componentFilenames && componentFilenames.size > 0) {
234798
+ result += "COMPONENTS (use exact import paths):\n";
234799
+ for (const [componentId, fileName] of componentFilenames.entries()) {
234800
+ let directory = "components";
234801
+ if (fileName.includes("data-") || componentId.includes("data-")) {
234802
+ directory = "data-components";
234803
+ } else if (fileName.includes("artifact-") || componentId.includes("artifact-")) {
234804
+ directory = "artifact-components";
234805
+ } else if (fileName.includes("status-") || componentId.includes("status-")) {
234806
+ directory = "status-components";
234807
+ }
234808
+ result += ` - Component ID: "${componentId}" \u2192 Import: "../${directory}/${fileName.replace(".ts", "")}"
234809
+ `;
234810
+ }
234811
+ }
234812
+ return result;
234813
+ }
234814
+ async function generateAgentFile(agentData, agentId, outputPath, modelSettings, toolFilenames, componentFilenames, debug = false) {
234769
234815
  const model = createModel(modelSettings);
234770
234816
  const promptTemplate = `Generate a TypeScript file for an Inkeep agent.
234771
234817
 
@@ -234774,11 +234820,22 @@ AGENT DATA:
234774
234820
 
234775
234821
  AGENT ID: ${agentId}
234776
234822
 
234777
- ${getTypeDefinitions()}
234823
+ ${toolFilenames || componentFilenames ? `IMPORT PATH MAPPINGS (CRITICAL - USE EXACT PATHS):
234824
+ ${generateImportMappings(toolFilenames, componentFilenames)}
234825
+
234826
+ !!! WARNING: Entity IDs \u2260 File Paths !!!
234827
+ - Entity IDs may use underscores or different naming
234828
+ - File paths use kebab-case naming convention
234829
+ - ALWAYS use the exact import paths from the mappings above
234830
+ - NEVER use entity IDs directly as import paths
234831
+
234832
+ ` : ""}${getTypeDefinitions()}
234778
234833
 
234779
234834
  IMPORTANT CONTEXT:
234780
234835
  - Agents reference resources (tools, components) by their imported variable names
234781
- - The 'tools' field in subAgents contains tool IDs that must match the imported variable names
234836
+ - Tools and components are referenced by variable names in code, but imports use FILE PATHS
234837
+ - CRITICAL: Import statements use file paths (../tools/tool-filename), NOT tool IDs
234838
+ - Variable names in canUse() arrays should match the imported variable names
234782
234839
  - If contextConfig is present, it must be imported from '@inkeep/agents-core' and used to create the context config
234783
234840
 
234784
234841
  ${NAMING_CONVENTION_RULES}
@@ -234786,7 +234843,10 @@ ${NAMING_CONVENTION_RULES}
234786
234843
  ${IMPORT_INSTRUCTIONS}
234787
234844
 
234788
234845
  REQUIREMENTS:
234789
- 1. IMPORTS (CRITICAL):
234846
+ 1. IMPORTS (CRITICAL - USE FILE PATHS, NOT IDs):
234847
+ - For tool/component imports: Use ONLY the exact file paths from IMPORT PATH MAPPINGS above
234848
+ - Import paths are based on actual file names, not entity IDs
234849
+ - Always use kebab-case file paths (../tools/tool-name, not ../tools/tool_name)
234790
234850
  - ALWAYS import { agent, subAgent } from '@inkeep/agents-sdk'
234791
234851
  - ALWAYS import { z } from 'zod' when using ANY Zod schemas (responseSchema, headersSchema, etc.)
234792
234852
  - ALWAYS import { contextConfig, fetchDefinition, headers } from '@inkeep/agents-core' when agent has contextConfig
@@ -235636,28 +235696,28 @@ var init_pull_llm_generate = __esm({
235636
235696
  `;
235637
235697
  NAMING_CONVENTION_RULES = `
235638
235698
  CRITICAL NAMING CONVENTION RULES (Apply to ALL imports/exports):
235639
- - File names ALWAYS use the exact original ID. IDs are made of file safe characters (e.g., '../tools/inkeep_facts', '../data-components/user-profile')
235640
- - Name of consts and variables, especially ones that are exported ones, MUST be camelCase versions of the ID, unless the ID is random/UUID then take it verbatim.
235641
- - Conversion rules for import/export names:
235699
+ - File paths use kebab-case naming (e.g., '../tools/tool-name', '../data-components/component-name')
235700
+ - Variable names MUST be camelCase versions of the entity ID
235701
+ - Conversion rules for variable names:
235642
235702
  - IDs with underscores: 'inkeep_facts' \u2192 inkeepFacts
235643
235703
  - IDs with hyphens: 'weather-api' \u2192 weatherApi
235644
235704
  - IDs with both: 'my_weather-api' \u2192 myWeatherApi
235645
235705
  - Random/UUID IDs: Keep as-is (e.g., 'fUI2riwrBVJ6MepT8rjx0' \u2192 fUI2riwrBVJ6MepT8rjx0)
235646
- - IDs starting with uppercase: Make first letter lowercase unless it's an acronym or random or UUID
235647
235706
  - The ID field in the exported object keeps the original format
235707
+ - IMPORTANT: Import paths use kebab-case file names, NOT entity IDs
235648
235708
  - Examples:
235649
- - Tool: import { inkeepFacts } from '../tools/inkeep_facts'; export const inkeepFacts = mcpTool({ id: 'inkeep_facts', ... })
235650
- - Component: import { userProfile } from '../data-components/user-profile'; export const userProfile = dataComponent({ id: 'user-profile', ... })
235651
- - Agent: import { myAgent } from './agent/my-agent'; export const myAgent = agent({ id: 'my-agent', ... })
235709
+ - Tool: import { toolName } from '../tools/tool-name'; export const toolName = mcpTool({ id: 'tool_id', ... })
235710
+ - Component: import { componentName } from '../data-components/component-name'; export const componentName = dataComponent({ id: 'component-id', ... })
235711
+ - Agent: import { agentName } from './agents/agent-name'; export const agentName = agent({ id: 'agent-id', ... })
235652
235712
  `;
235653
235713
  IMPORT_INSTRUCTIONS = `
235654
235714
  CRITICAL: All imports MUST be alphabetically sorted (both named imports and path names)
235655
235715
 
235656
235716
  CRITICAL IMPORT PATTERNS:
235657
- - Tools: Import from '../tools/{toolId}' (individual files)
235658
- - Data components: Import from '../data-components/{componentId}' (individual files)
235659
- - Artifact components: Import from '../artifact-components/{componentId}' (individual files)
235660
- - Agent: Import from './agent/{agentId}' (individual files)
235717
+ - Tools: Import from '../tools/{file-name}' (use kebab-case file names)
235718
+ - Data components: Import from '../data-components/{file-name}' (use kebab-case file names)
235719
+ - Artifact components: Import from '../artifact-components/{file-name}' (use kebab-case file names)
235720
+ - Agent: Import from './agents/{file-name}' (use kebab-case file names)
235661
235721
 
235662
235722
  NEVER use barrel imports from directories:
235663
235723
  \u274C WRONG: import { ordersList, refundApproval } from '../data-components';
@@ -235692,28 +235752,28 @@ function collectAllEntities(projectData) {
235692
235752
  const entities = [];
235693
235753
  if (projectData.agents) {
235694
235754
  for (const [agentId, agentData] of Object.entries(projectData.agents)) {
235695
- entities.push({ id: agentId, type: "agent" });
235755
+ entities.push({ id: agentId, type: "agent", data: agentData });
235696
235756
  const agentObj = agentData;
235697
235757
  if (agentObj.subAgents) {
235698
- for (const subAgentId of Object.keys(agentObj.subAgents)) {
235699
- entities.push({ id: subAgentId, type: "subAgent" });
235758
+ for (const [subAgentId, subAgentData] of Object.entries(agentObj.subAgents)) {
235759
+ entities.push({ id: subAgentId, type: "subAgent", data: subAgentData });
235700
235760
  }
235701
235761
  }
235702
235762
  }
235703
235763
  }
235704
235764
  if (projectData.tools) {
235705
- for (const toolId of Object.keys(projectData.tools)) {
235706
- entities.push({ id: toolId, type: "tool" });
235765
+ for (const [toolId, toolData] of Object.entries(projectData.tools)) {
235766
+ entities.push({ id: toolId, type: "tool", data: toolData });
235707
235767
  }
235708
235768
  }
235709
235769
  if (projectData.dataComponents) {
235710
- for (const compId of Object.keys(projectData.dataComponents)) {
235711
- entities.push({ id: compId, type: "dataComponent" });
235770
+ for (const [compId, compData] of Object.entries(projectData.dataComponents)) {
235771
+ entities.push({ id: compId, type: "dataComponent", data: compData });
235712
235772
  }
235713
235773
  }
235714
235774
  if (projectData.artifactComponents) {
235715
- for (const compId of Object.keys(projectData.artifactComponents)) {
235716
- entities.push({ id: compId, type: "artifactComponent" });
235775
+ for (const [compId, compData] of Object.entries(projectData.artifactComponents)) {
235776
+ entities.push({ id: compId, type: "artifactComponent", data: compData });
235717
235777
  }
235718
235778
  }
235719
235779
  if (projectData.agents) {
@@ -235728,9 +235788,58 @@ function collectAllEntities(projectData) {
235728
235788
  }
235729
235789
  }
235730
235790
  }
235791
+ const credentialReferences2 = /* @__PURE__ */ new Set();
235731
235792
  if (projectData.credentialReferences) {
235732
235793
  for (const credId of Object.keys(projectData.credentialReferences)) {
235733
- entities.push({ id: credId, type: "credential" });
235794
+ credentialReferences2.add(credId);
235795
+ }
235796
+ }
235797
+ if (projectData.tools) {
235798
+ for (const [_toolId, toolData] of Object.entries(projectData.tools)) {
235799
+ const tool2 = toolData;
235800
+ if (tool2.credentialReferenceId) {
235801
+ credentialReferences2.add(tool2.credentialReferenceId);
235802
+ }
235803
+ }
235804
+ }
235805
+ if (projectData.externalAgents) {
235806
+ for (const [_agentId, agentData] of Object.entries(projectData.externalAgents)) {
235807
+ const agent = agentData;
235808
+ if (agent.credentialReferenceId) {
235809
+ credentialReferences2.add(agent.credentialReferenceId);
235810
+ }
235811
+ }
235812
+ }
235813
+ if (projectData.agents) {
235814
+ for (const [_agentId, agentData] of Object.entries(projectData.agents)) {
235815
+ const agent = agentData;
235816
+ if (agent.contextConfig?.headers?.credentialReferenceId) {
235817
+ credentialReferences2.add(agent.contextConfig.headers.credentialReferenceId);
235818
+ }
235819
+ if (agent.contextConfig?.contextVariables) {
235820
+ for (const [_varId, varData] of Object.entries(agent.contextConfig.contextVariables)) {
235821
+ const contextVar = varData;
235822
+ if (contextVar.credentialReferenceId) {
235823
+ credentialReferences2.add(contextVar.credentialReferenceId);
235824
+ }
235825
+ }
235826
+ }
235827
+ if (agent.subAgents) {
235828
+ for (const [_subAgentId, subAgentData] of Object.entries(agent.subAgents)) {
235829
+ const subAgent = subAgentData;
235830
+ if (subAgent.contextConfig?.headers?.credentialReferenceId) {
235831
+ credentialReferences2.add(subAgent.contextConfig.headers.credentialReferenceId);
235832
+ }
235833
+ if (subAgent.contextConfig?.contextVariables) {
235834
+ for (const [_varId, varData] of Object.entries(subAgent.contextConfig.contextVariables)) {
235835
+ const contextVar = varData;
235836
+ if (contextVar.credentialReferenceId) {
235837
+ credentialReferences2.add(contextVar.credentialReferenceId);
235838
+ }
235839
+ }
235840
+ }
235841
+ }
235842
+ }
235734
235843
  }
235735
235844
  }
235736
235845
  return entities;
@@ -235748,7 +235857,9 @@ var init_variable_name_registry = __esm({
235748
235857
  dataComponentSuffix: null,
235749
235858
  artifactComponentSuffix: null,
235750
235859
  statusComponentSuffix: null,
235751
- credentialSuffix: null
235860
+ credentialSuffix: null,
235861
+ environmentSuffix: null
235862
+ // No suffix needed for environments
235752
235863
  };
235753
235864
  VariableNameGenerator = class {
235754
235865
  registry;
@@ -235763,6 +235874,7 @@ var init_variable_name_registry = __esm({
235763
235874
  artifactComponents: /* @__PURE__ */ new Map(),
235764
235875
  statusComponents: /* @__PURE__ */ new Map(),
235765
235876
  credentials: /* @__PURE__ */ new Map(),
235877
+ environments: /* @__PURE__ */ new Map(),
235766
235878
  usedNames: /* @__PURE__ */ new Map()
235767
235879
  };
235768
235880
  this.conventions = conventions;
@@ -235772,13 +235884,18 @@ var init_variable_name_registry = __esm({
235772
235884
  * Generate unique variable name for an entity
235773
235885
  * Ensures no conflicts across all entity types
235774
235886
  */
235775
- generateVariableName(id, entityType) {
235887
+ generateVariableName(id, entityType, entityData) {
235776
235888
  const registryMap = this.getRegistryMap(entityType);
235777
235889
  const existing = registryMap.get(id);
235778
235890
  if (existing) {
235779
235891
  return existing;
235780
235892
  }
235781
- const baseName = this.idToVariableName(id);
235893
+ let baseName;
235894
+ if (entityType === "tool" && entityData?.name && this.isRandomId(id)) {
235895
+ baseName = this.idToVariableName(entityData.name);
235896
+ } else {
235897
+ baseName = this.idToVariableName(id);
235898
+ }
235782
235899
  if (!this.registry.usedNames.has(baseName)) {
235783
235900
  this.register(id, baseName, entityType);
235784
235901
  return baseName;
@@ -235858,6 +235975,30 @@ var init_variable_name_registry = __esm({
235858
235975
  }
235859
235976
  return false;
235860
235977
  }
235978
+ /**
235979
+ * Generate filename from entity data (for file naming)
235980
+ */
235981
+ generateFileName(id, entityType, entityData) {
235982
+ let baseName;
235983
+ if (entityType === "tool" && entityData?.name && this.isRandomId(id)) {
235984
+ baseName = this.nameToFileName(entityData.name);
235985
+ } else {
235986
+ baseName = this.idToFileName(id);
235987
+ }
235988
+ return baseName;
235989
+ }
235990
+ /**
235991
+ * Convert name to kebab-case filename
235992
+ */
235993
+ nameToFileName(name) {
235994
+ return name.replace(/[^\w\s-]/g, "").trim().replace(/\s+/g, "-").replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
235995
+ }
235996
+ /**
235997
+ * Convert ID to kebab-case filename
235998
+ */
235999
+ idToFileName(id) {
236000
+ return id.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[\s_]+/g, "-").toLowerCase();
236001
+ }
235861
236002
  /**
235862
236003
  * Get appropriate suffix for entity type
235863
236004
  */
@@ -235877,6 +236018,8 @@ var init_variable_name_registry = __esm({
235877
236018
  return this.conventions.statusComponentSuffix || "";
235878
236019
  case "credential":
235879
236020
  return this.conventions.credentialSuffix || "";
236021
+ case "environment":
236022
+ return this.conventions.environmentSuffix || "";
235880
236023
  default:
235881
236024
  return "";
235882
236025
  }
@@ -235900,6 +236043,8 @@ var init_variable_name_registry = __esm({
235900
236043
  return this.registry.statusComponents;
235901
236044
  case "credential":
235902
236045
  return this.registry.credentials;
236046
+ case "environment":
236047
+ return this.registry.environments;
235903
236048
  default:
235904
236049
  throw new Error(`Unknown entity type: ${entityType}`);
235905
236050
  }
@@ -235929,10 +236074,12 @@ async function analyzeExistingPatterns(projectDir) {
235929
236074
  namingConventions,
235930
236075
  codeStyle,
235931
236076
  examples: {
235932
- sampleAgentFile: codeExamples.agentFiles[0]?.content,
235933
- sampleToolFile: codeExamples.toolFiles[0]?.content,
235934
- sampleImports: codeExamples.imports,
235935
- mappings: codeExamples.mappings
236077
+ // Sample files removed to prevent misleading examples
236078
+ // sampleAgentFile: codeExamples.agentFiles[0]?.content,
236079
+ // sampleToolFile: codeExamples.toolFiles[0]?.content,
236080
+ // sampleImports: codeExamples.imports, // Disabled - imports cause confusion with kebab-case vs underscore paths
236081
+ mappings: []
236082
+ // Disabled sample mappings to prevent bad examples from contaminating generation
235936
236083
  }
235937
236084
  };
235938
236085
  }
@@ -236389,7 +236536,7 @@ var plan_builder_exports = {};
236389
236536
  __export(plan_builder_exports, {
236390
236537
  generatePlan: () => generatePlan
236391
236538
  });
236392
- async function generatePlan(projectData, patterns, modelSettings, createModel2) {
236539
+ async function generatePlan(projectData, patterns, modelSettings, createModel2, targetEnvironment = "development") {
236393
236540
  const nameGenerator = new VariableNameGenerator(patterns.namingConventions);
236394
236541
  if (patterns.examples.mappings) {
236395
236542
  for (const mapping of patterns.examples.mappings) {
@@ -236401,10 +236548,15 @@ async function generatePlan(projectData, patterns, modelSettings, createModel2)
236401
236548
  }
236402
236549
  const allEntities = collectAllEntities(projectData);
236403
236550
  for (const entity of allEntities) {
236404
- nameGenerator.generateVariableName(entity.id, entity.type);
236551
+ nameGenerator.generateVariableName(entity.id, entity.type, entity.data);
236552
+ }
236553
+ const fileNameMappings = /* @__PURE__ */ new Map();
236554
+ for (const entity of allEntities) {
236555
+ const fileName = nameGenerator.generateFileName(entity.id, entity.type, entity.data);
236556
+ fileNameMappings.set(entity.id, fileName);
236405
236557
  }
236406
236558
  const model = createModel2(modelSettings);
236407
- const promptTemplate = createPlanningPromptTemplate(nameGenerator.getRegistry(), allEntities);
236559
+ const promptTemplate = createPlanningPromptTemplate(nameGenerator.getRegistry(), allEntities, fileNameMappings, targetEnvironment);
236408
236560
  const promptData = {
236409
236561
  projectData,
236410
236562
  patterns
@@ -236435,8 +236587,9 @@ async function generatePlan(projectData, patterns, modelSettings, createModel2)
236435
236587
  };
236436
236588
  return plan;
236437
236589
  }
236438
- function createPlanningPromptTemplate(registry2, allEntities) {
236590
+ function createPlanningPromptTemplate(registry2, allEntities, fileNameMappings, targetEnvironment = "development") {
236439
236591
  const mappings = formatVariableMappings(registry2, allEntities);
236592
+ const fileNames = formatFileNameMappings(fileNameMappings, allEntities);
236440
236593
  return `You are a code generation planner. Generate a file structure plan for an Inkeep TypeScript project.
236441
236594
 
236442
236595
  DATA (PROJECT AND PATTERNS):
@@ -236449,6 +236602,9 @@ The DATA above contains:
236449
236602
  VARIABLE NAME MAPPINGS (MUST USE THESE EXACT NAMES):
236450
236603
  ${mappings}
236451
236604
 
236605
+ FILENAME MAPPINGS (MUST USE THESE EXACT FILENAMES):
236606
+ ${fileNames}
236607
+
236452
236608
  CRITICAL RULES:
236453
236609
 
236454
236610
  1. TOOL TYPES - VERY IMPORTANT:
@@ -236464,7 +236620,14 @@ CRITICAL RULES:
236464
236620
  - Agents must import status components from status-components/ directory
236465
236621
  - Status components are NEVER inlined in agent files
236466
236622
 
236467
- 3. File Structure:
236623
+ 3. ENVIRONMENT FILES - VERY IMPORTANT:
236624
+ - **When credential references exist**: Create environment files in environments/ directory
236625
+ - **Environment Structure**: Create ONLY "${targetEnvironment}.env.ts" file for target environment (credentials are embedded in this file)
236626
+ - **Environment Index**: Create "environments/index.ts" that imports environment files and exports envSettings using createEnvironmentSettings
236627
+ - **NO separate credential files**: Credentials are defined INSIDE the environment files, not as separate files
236628
+ - **Environment entities**: Use type "environment" for both environment files and index file
236629
+
236630
+ 4. File Structure:
236468
236631
  - If patterns show "toolsLocation": "inline", ALL tools should be in "inlineContent" of agent files
236469
236632
  - If patterns show "toolsLocation": "separate", MCP tools get separate files, function tools still inline
236470
236633
  - Follow the detected file naming convention (kebab-case, camelCase, or snake_case)
@@ -236558,6 +236721,40 @@ OUTPUT FORMAT (JSON):
236558
236721
  "dependencies": [],
236559
236722
  "inlineContent": null
236560
236723
  },
236724
+ {
236725
+ "path": "environments/${targetEnvironment}.env.ts",
236726
+ "type": "environment",
236727
+ "entities": [
236728
+ {
236729
+ "id": "${targetEnvironment}",
236730
+ "variableName": "${targetEnvironment}",
236731
+ "entityType": "environment",
236732
+ "exportName": "${targetEnvironment}"
236733
+ }
236734
+ ],
236735
+ "dependencies": [],
236736
+ "inlineContent": null
236737
+ },
236738
+ {
236739
+ "path": "environments/index.ts",
236740
+ "type": "environment",
236741
+ "entities": [
236742
+ {
236743
+ "id": "envSettings",
236744
+ "variableName": "envSettings",
236745
+ "entityType": "environment",
236746
+ "exportName": "envSettings"
236747
+ }
236748
+ ],
236749
+ "dependencies": [
236750
+ {
236751
+ "variableName": "${targetEnvironment}",
236752
+ "fromPath": "./${targetEnvironment}.env",
236753
+ "entityType": "environment"
236754
+ }
236755
+ ],
236756
+ "inlineContent": null
236757
+ },
236561
236758
  {
236562
236759
  "path": "index.ts",
236563
236760
  "type": "index",
@@ -236596,7 +236793,8 @@ function formatVariableMappings(registry2, allEntities) {
236596
236793
  dataComponent: [],
236597
236794
  artifactComponent: [],
236598
236795
  statusComponent: [],
236599
- credential: []
236796
+ credential: [],
236797
+ environment: []
236600
236798
  };
236601
236799
  for (const entity of allEntities) {
236602
236800
  const registryMap = getRegistryMap(registry2, entity.type);
@@ -236618,6 +236816,45 @@ ${type.toUpperCase()}S:
236618
236816
  }
236619
236817
  return result;
236620
236818
  }
236819
+ function formatFileNameMappings(fileNameMappings, allEntities) {
236820
+ let result = "";
236821
+ const byType = {
236822
+ agent: [],
236823
+ tool: [],
236824
+ dataComponent: [],
236825
+ artifactComponent: [],
236826
+ statusComponent: [],
236827
+ credential: []
236828
+ };
236829
+ for (const entity of allEntities) {
236830
+ const fileName = fileNameMappings.get(entity.id);
236831
+ if (fileName && byType[entity.type]) {
236832
+ byType[entity.type].push({
236833
+ id: entity.id,
236834
+ fileName,
236835
+ name: entity.data?.name
236836
+ // Include human-readable name for context
236837
+ });
236838
+ }
236839
+ }
236840
+ for (const [type, entities] of Object.entries(byType)) {
236841
+ if (entities.length > 0) {
236842
+ result += `
236843
+ ${type.toUpperCase()}S:
236844
+ `;
236845
+ for (const entity of entities) {
236846
+ if (entity.name && entity.name !== entity.id) {
236847
+ result += ` - id: "${entity.id}" (${entity.name}) \u2192 filename: "${entity.fileName}.ts"
236848
+ `;
236849
+ } else {
236850
+ result += ` - id: "${entity.id}" \u2192 filename: "${entity.fileName}.ts"
236851
+ `;
236852
+ }
236853
+ }
236854
+ }
236855
+ }
236856
+ return result;
236857
+ }
236621
236858
  function getRegistryMap(registry2, entityType) {
236622
236859
  switch (entityType) {
236623
236860
  case "agent":
@@ -236806,7 +237043,8 @@ async function generateFile(fileInfo, projectData, plan, dirs, modelSettings, de
236806
237043
  maxOutputTokens: fileInfo.type === "agent" ? 16e3 : 4e3,
236807
237044
  abortSignal: AbortSignal.timeout(fileInfo.type === "agent" ? 24e4 : 6e4)
236808
237045
  },
236809
- debug
237046
+ debug,
237047
+ { fileType: fileInfo.type }
236810
237048
  );
236811
237049
  const llmDuration = ((Date.now() - llmStartTime) / 1e3).toFixed(1);
236812
237050
  const cleanedCode = cleanGeneratedCode(text2);
@@ -236869,21 +237107,154 @@ function extractDataForFile(fileInfo, projectData) {
236869
237107
  }
236870
237108
  return {};
236871
237109
  }
236872
- case "environment":
236873
- return projectData.credentialReferences || {};
237110
+ case "environment": {
237111
+ const credentialData = {};
237112
+ const sources = [];
237113
+ if (projectData.credentialReferences) {
237114
+ Object.assign(credentialData, projectData.credentialReferences);
237115
+ sources.push("direct credentialReferences");
237116
+ }
237117
+ if (projectData.tools) {
237118
+ for (const [toolId, toolData] of Object.entries(projectData.tools)) {
237119
+ const tool2 = toolData;
237120
+ if (tool2.credentialReferenceId && !credentialData[tool2.credentialReferenceId]) {
237121
+ credentialData[tool2.credentialReferenceId] = {
237122
+ id: tool2.credentialReferenceId,
237123
+ type: "api_key",
237124
+ description: `Credential for tool ${tool2.name || toolId}`,
237125
+ _context: {
237126
+ source: "tool",
237127
+ toolId,
237128
+ toolName: tool2.name,
237129
+ serverUrl: tool2.serverUrl
237130
+ }
237131
+ };
237132
+ sources.push(`tool:${toolId}`);
237133
+ }
237134
+ }
237135
+ }
237136
+ if (projectData.externalAgents) {
237137
+ for (const [agentId, agentData] of Object.entries(projectData.externalAgents)) {
237138
+ const agent = agentData;
237139
+ if (agent.credentialReferenceId && !credentialData[agent.credentialReferenceId]) {
237140
+ credentialData[agent.credentialReferenceId] = {
237141
+ id: agent.credentialReferenceId,
237142
+ type: "api_key",
237143
+ description: `Credential for external agent ${agent.name || agentId}`,
237144
+ _context: {
237145
+ source: "externalAgent",
237146
+ agentId,
237147
+ agentName: agent.name,
237148
+ baseUrl: agent.baseUrl
237149
+ }
237150
+ };
237151
+ sources.push(`externalAgent:${agentId}`);
237152
+ }
237153
+ }
237154
+ }
237155
+ if (projectData.agents) {
237156
+ for (const [agentId, agentData] of Object.entries(projectData.agents)) {
237157
+ const agent = agentData;
237158
+ if (agent.contextConfig?.headers?.credentialReferenceId) {
237159
+ const credId = agent.contextConfig.headers.credentialReferenceId;
237160
+ if (!credentialData[credId]) {
237161
+ credentialData[credId] = {
237162
+ id: credId,
237163
+ type: "api_key",
237164
+ description: `Credential for agent ${agent.name || agentId} headers`,
237165
+ _context: {
237166
+ source: "agent.contextConfig.headers",
237167
+ agentId,
237168
+ agentName: agent.name
237169
+ }
237170
+ };
237171
+ sources.push(`agent:${agentId}:headers`);
237172
+ }
237173
+ }
237174
+ if (agent.contextConfig?.contextVariables) {
237175
+ for (const [varId, varData] of Object.entries(agent.contextConfig.contextVariables)) {
237176
+ const contextVar = varData;
237177
+ if (contextVar.credentialReferenceId) {
237178
+ const credId = contextVar.credentialReferenceId;
237179
+ if (!credentialData[credId]) {
237180
+ credentialData[credId] = {
237181
+ id: credId,
237182
+ type: "api_key",
237183
+ description: `Credential for agent ${agent.name || agentId} context variable ${varId}`,
237184
+ _context: {
237185
+ source: "agent.contextConfig.contextVariables",
237186
+ agentId,
237187
+ agentName: agent.name,
237188
+ variableId: varId
237189
+ }
237190
+ };
237191
+ sources.push(`agent:${agentId}:contextVar:${varId}`);
237192
+ }
237193
+ }
237194
+ }
237195
+ }
237196
+ if (agent.subAgents) {
237197
+ for (const [subAgentId, subAgentData] of Object.entries(agent.subAgents)) {
237198
+ const subAgent = subAgentData;
237199
+ if (subAgent.contextConfig?.headers?.credentialReferenceId) {
237200
+ const credId = subAgent.contextConfig.headers.credentialReferenceId;
237201
+ if (!credentialData[credId]) {
237202
+ credentialData[credId] = {
237203
+ id: credId,
237204
+ type: "api_key",
237205
+ description: `Credential for subAgent ${subAgent.name || subAgentId} headers`,
237206
+ _context: {
237207
+ source: "subAgent.contextConfig.headers",
237208
+ agentId,
237209
+ subAgentId,
237210
+ subAgentName: subAgent.name
237211
+ }
237212
+ };
237213
+ sources.push(`subAgent:${subAgentId}:headers`);
237214
+ }
237215
+ }
237216
+ if (subAgent.contextConfig?.contextVariables) {
237217
+ for (const [varId, varData] of Object.entries(subAgent.contextConfig.contextVariables)) {
237218
+ const contextVar = varData;
237219
+ if (contextVar.credentialReferenceId) {
237220
+ const credId = contextVar.credentialReferenceId;
237221
+ if (!credentialData[credId]) {
237222
+ credentialData[credId] = {
237223
+ id: credId,
237224
+ type: "api_key",
237225
+ description: `Credential for subAgent ${subAgent.name || subAgentId} context variable ${varId}`,
237226
+ _context: {
237227
+ source: "subAgent.contextConfig.contextVariables",
237228
+ agentId,
237229
+ subAgentId,
237230
+ subAgentName: subAgent.name,
237231
+ variableId: varId
237232
+ }
237233
+ };
237234
+ sources.push(`subAgent:${subAgentId}:contextVar:${varId}`);
237235
+ }
237236
+ }
237237
+ }
237238
+ }
237239
+ }
237240
+ }
237241
+ }
237242
+ }
237243
+ if (Object.keys(credentialData).length > 0) {
237244
+ credentialData._meta = {
237245
+ foundCredentials: Object.keys(credentialData).filter((k2) => k2 !== "_meta"),
237246
+ sources,
237247
+ extractedFrom: "comprehensive scan of project data"
237248
+ };
237249
+ }
237250
+ return credentialData;
237251
+ }
236874
237252
  default:
236875
237253
  return {};
236876
237254
  }
236877
237255
  }
236878
237256
  function findExampleCode(fileInfo, patterns) {
236879
- switch (fileInfo.type) {
236880
- case "agent":
236881
- return patterns.examples.sampleAgentFile;
236882
- case "tool":
236883
- return patterns.examples.sampleToolFile;
236884
- default:
236885
- return void 0;
236886
- }
237257
+ return void 0;
236887
237258
  }
236888
237259
  function createPromptForFile(fileInfo, fileData, context, registryInfo) {
236889
237260
  const commonInstructions = `
@@ -236907,11 +237278,13 @@ ${NAMING_CONVENTION_RULES}
236907
237278
  ${IMPORT_INSTRUCTIONS}
236908
237279
 
236909
237280
  CRITICAL RULES:
236910
- 1. Use EXACT variable names from the registry above
236911
- 2. The 'id' field in objects keeps the original value
236912
- 3. Variable names must be unique (no conflicts across types)
236913
- 4. Follow detected patterns for code style
236914
- 5. Match existing formatting and conventions
237281
+ 1. Use EXACT variable names from the registry above - DO NOT modify or "improve" them
237282
+ 2. Copy the exact import statements provided in the registry
237283
+ 3. The 'id' field in objects keeps the original value
237284
+ 4. Variable names must be unique (no conflicts across types)
237285
+ 5. Follow detected patterns for code style
237286
+ 6. Match existing formatting and conventions
237287
+ 7. NEVER generate your own variable names - only use what's provided
236915
237288
  `;
236916
237289
  switch (fileInfo.type) {
236917
237290
  case "index":
@@ -236926,12 +237299,14 @@ CRITICAL RULES:
236926
237299
  return createArtifactComponentPrompt(fileData, context, registryInfo, commonInstructions);
236927
237300
  case "statusComponent":
236928
237301
  return createStatusComponentPrompt(fileData, context, registryInfo, commonInstructions);
237302
+ case "environment":
237303
+ return createEnvironmentPrompt(fileData, context, registryInfo, commonInstructions);
236929
237304
  default:
236930
237305
  throw new Error(`Unknown file type: ${fileInfo.type}`);
236931
237306
  }
236932
237307
  }
236933
237308
  function createIndexPrompt(_projectData, context, _registryInfo, commonInstructions) {
236934
- const importMappings = generateImportMappings(context.plan);
237309
+ const importMappings = generateImportMappings2(context.plan);
236935
237310
  return `Generate index.ts for Inkeep project.
236936
237311
 
236937
237312
  PROJECT DATA:
@@ -237035,6 +237410,34 @@ CONTEXT CONFIG (CRITICAL - NO PLAIN OBJECTS):
237035
237410
  - Use myHeaders.toTemplate('key_name') for header values in fetchConfig
237036
237411
  - Use myContext.toTemplate('variable.field') for prompt interpolation
237037
237412
 
237413
+ FETCHDEFINITION STRUCTURE (CRITICAL - COPY EXACT FORMAT):
237414
+ - ALWAYS wrap HTTP config in 'fetchConfig' object
237415
+ - COPY the exact authorization format from source data (don't modify headers)
237416
+ - Use .nullable() instead of z.union([type, z.null()]) for schemas
237417
+ - responseSchema is raw Zod code (NO backticks around it)
237418
+ - String values use template literals (backticks for strings)
237419
+
237420
+ CORRECT fetchDefinition structure:
237421
+ fetchDefinition({
237422
+ id: 'fetch-id',
237423
+ name: 'Fetch Name',
237424
+ trigger: 'initialization',
237425
+ fetchConfig: {
237426
+ url: 'api-endpoint-url',
237427
+ method: 'POST',
237428
+ headers: {
237429
+ 'Content-Type': 'application/json',
237430
+ Authorization: headersVar.toTemplate('key') // COPY EXACT format from source
237431
+ },
237432
+ body: { query: 'request-body' }
237433
+ },
237434
+ responseSchema: z.object({
237435
+ field: z.string().nullable()
237436
+ }),
237437
+ transform: 'data.path',
237438
+ defaultValue: 'fallback'
237439
+ })
237440
+
237038
237441
  STRING LITERALS (CRITICAL - MUST FOLLOW):
237039
237442
  - For STRING VALUES: ALWAYS use template literals (backticks \`)
237040
237443
  - This includes: prompt, description, query, url, method, body, defaultValue, etc.
@@ -237113,7 +237516,28 @@ REQUIREMENTS:
237113
237516
  1. Import mcpTool or functionTool from '@inkeep/agents-sdk'
237114
237517
  2. Use exact variable name from registry
237115
237518
  3. Include serverUrl property if MCP tool
237116
- 4. Handle credentials using envSettings if needed
237519
+ 4. For tools with credentials, import envSettings and use envSettings.getEnvironmentSetting('credential_key')
237520
+ 5. CRITICAL: Transport must be an OBJECT format: transport: { type: 'streamable_http' } NOT a string
237521
+
237522
+ CREDENTIAL HANDLING (CRITICAL):
237523
+ If the tool data includes credential information, you MUST:
237524
+ 1. Import { envSettings } from '../environments'
237525
+ 2. Use credential: envSettings.getEnvironmentSetting('credential_key') in the tool definition
237526
+ 3. Convert credential IDs to underscore format (e.g., 'linear-api' -> 'linear_api')
237527
+
237528
+ Example for tool with credential:
237529
+ \`\`\`typescript
237530
+ import { mcpTool } from '@inkeep/agents-sdk';
237531
+ import { envSettings } from '../environments';
237532
+
237533
+ export const toolName = mcpTool({
237534
+ id: 'tool-id',
237535
+ name: 'Tool Name',
237536
+ serverUrl: 'https://example.com/mcp',
237537
+ credential: envSettings.getEnvironmentSetting('linear_api'), // underscore format
237538
+ transport: { type: 'streamable_http' }
237539
+ });
237540
+ \`\`\`
237117
237541
 
237118
237542
  Generate ONLY the TypeScript code without markdown.`;
237119
237543
  }
@@ -237130,46 +237554,58 @@ dataComponent({
237130
237554
  id: 'component-id',
237131
237555
  name: 'ComponentName',
237132
237556
  description: 'Component description',
237133
- props: { // Use 'props' NOT 'propsSchema'
237134
- $schema: 'https://json-schema.org/draft/2020-12/schema',
237135
- type: 'object',
237136
- properties: { ... },
237137
- required: [...],
237138
- additionalProperties: false
237139
- }
237557
+ props: z.object({
237558
+ fieldName: z.string().describe('Field description'),
237559
+ optionalField: z.number().optional().describe('Optional field description'),
237560
+ })
237140
237561
  })
237141
237562
 
237563
+ REQUIREMENTS:
237564
+ 1. Import dataComponent from '@inkeep/agents-sdk'
237565
+ 2. Import z from 'zod' for schema definitions
237566
+ 3. Use exact variable name from registry
237567
+ 4. Use 'props' property with Zod schema (NOT JSON Schema)
237568
+ 5. Include 'id', 'name', and 'description' properties
237569
+ 6. Use .describe() for field descriptions
237570
+ 7. Use .optional() for optional fields
237571
+ 8. Use .nullable() for nullable fields (not z.union([z.string(), z.null()]))
237572
+ 9. CRITICAL: All imports must be alphabetically sorted to comply with Biome linting
237573
+
237142
237574
  EXAMPLE:
237575
+ import { dataComponent } from '@inkeep/agents-sdk';
237576
+ import { z } from 'zod';
237577
+
237143
237578
  export const weatherForecast = dataComponent({
237144
237579
  id: 'weather-forecast',
237145
237580
  name: 'WeatherForecast',
237146
237581
  description: 'Hourly weather forecast',
237147
- props: {
237148
- $schema: 'https://json-schema.org/draft/2020-12/schema',
237149
- type: 'object',
237150
- properties: {
237151
- forecast: {
237152
- type: 'array',
237153
- items: {
237154
- type: 'object',
237155
- properties: {
237156
- time: { type: 'string' },
237157
- temperature: { type: 'number' }
237158
- },
237159
- required: ['time', 'temperature']
237160
- }
237161
- }
237162
- },
237163
- required: ['forecast'],
237164
- additionalProperties: false
237165
- }
237582
+ props: z.object({
237583
+ forecast: z.array(z.object({
237584
+ time: z.string().describe('The time of current item E.g. 12PM, 1PM'),
237585
+ temperature: z.number().describe('Temperature at given time in Fahrenheit'),
237586
+ code: z.number().describe('Weather code at given time'),
237587
+ })).describe('The hourly forecast for the weather at a given location'),
237588
+ }),
237166
237589
  });
237167
237590
 
237168
- REQUIREMENTS:
237169
- 1. Import dataComponent from '@inkeep/agents-sdk'
237170
- 2. Use exact variable name from registry
237171
- 3. Use 'props' property with JSON Schema format
237172
- 4. Include 'id', 'name', and 'description' properties
237591
+ EXAMPLE WITH OPTIONAL FIELDS:
237592
+ import { dataComponent } from '@inkeep/agents-sdk';
237593
+ import { z } from 'zod';
237594
+
237595
+ export const userProfile = dataComponent({
237596
+ id: 'user-profile',
237597
+ name: 'User Profile',
237598
+ description: 'User profile information',
237599
+ props: z.object({
237600
+ userId: z.string().describe('Unique user identifier'),
237601
+ name: z.string().describe('User full name'),
237602
+ email: z.string().email().describe('User email address'),
237603
+ preferences: z.object({
237604
+ theme: z.enum(['light', 'dark']),
237605
+ notifications: z.boolean(),
237606
+ }).optional().describe('User preferences'),
237607
+ }),
237608
+ });
237173
237609
 
237174
237610
  Generate ONLY the TypeScript code without markdown.`;
237175
237611
  }
@@ -237222,28 +237658,44 @@ export const toolSummary = statusComponent({
237222
237658
  Generate ONLY the TypeScript code without markdown.`;
237223
237659
  }
237224
237660
  function formatRegistryForFile(fileInfo, _registry) {
237225
- let result = "Entities in this file:\n";
237226
- for (const entity of fileInfo.entities) {
237227
- result += ` - ${entity.entityType} "${entity.id}" \u2192 variable: ${entity.variableName}
237661
+ let result = "REQUIRED VARIABLE NAMES (YOU MUST USE ONLY THESE EXACT NAMES):\n\n";
237662
+ if (fileInfo.entities.length > 0) {
237663
+ result += "Variables to define in this file:\n";
237664
+ for (const entity of fileInfo.entities) {
237665
+ result += ` - ID "${entity.id}" \u2192 MUST use variable name: ${entity.variableName}
237228
237666
  `;
237667
+ }
237668
+ result += "\n";
237229
237669
  }
237230
237670
  if (fileInfo.inlineContent && fileInfo.inlineContent.length > 0) {
237231
- result += "\nInline content (defined in this file):\n";
237671
+ result += "Inline variables to define in this file:\n";
237232
237672
  for (const entity of fileInfo.inlineContent) {
237233
- result += ` - ${entity.entityType} "${entity.id}" \u2192 variable: ${entity.variableName}
237673
+ result += ` - ID "${entity.id}" \u2192 MUST use variable name: ${entity.variableName}
237234
237674
  `;
237235
237675
  }
237676
+ result += "\n";
237236
237677
  }
237237
237678
  if (fileInfo.dependencies.length > 0) {
237238
- result += "\nDependencies to import:\n";
237679
+ result += "!!! EXACT IMPORT STATEMENTS - COPY PRECISELY !!!\n";
237239
237680
  for (const dep of fileInfo.dependencies) {
237240
- result += ` - import { ${dep.variableName} } from '${dep.fromPath}';
237681
+ result += `import { ${dep.variableName} } from '${dep.fromPath}';
237241
237682
  `;
237242
237683
  }
237684
+ result += "\n";
237685
+ result += "!!! WARNING: IDs \u2260 FILE PATHS !!!\n";
237686
+ result += "Entity IDs (with underscores) are NOT the same as file paths (with kebab-case):\n";
237687
+ for (const dep of fileInfo.dependencies) {
237688
+ const entity = fileInfo.entities.find((e2) => e2.variableName === dep.variableName) || fileInfo.inlineContent?.find((e2) => e2.variableName === dep.variableName);
237689
+ if (entity && entity.id !== dep.fromPath.split("/").pop()?.replace(".ts", "")) {
237690
+ result += `- Entity ID: "${entity.id}" \u2192 File path: "${dep.fromPath}"
237691
+ `;
237692
+ }
237693
+ }
237694
+ result += "\nCRITICAL: Use the FILE PATHS above, NOT the entity IDs!\n\n";
237243
237695
  }
237244
237696
  return result;
237245
237697
  }
237246
- function generateImportMappings(plan) {
237698
+ function generateImportMappings2(plan) {
237247
237699
  let result = "";
237248
237700
  for (const file of plan.files) {
237249
237701
  if (file.type !== "index" && file.type !== "environment") {
@@ -237256,6 +237708,97 @@ function generateImportMappings(plan) {
237256
237708
  }
237257
237709
  return result;
237258
237710
  }
237711
+ function createEnvironmentPrompt(credentialData, context, _registryInfo, commonInstructions) {
237712
+ const filePath = context.fileInfo.path || "";
237713
+ const fileName = filePath.split("/").pop() || "";
237714
+ if (fileName === "index.ts") {
237715
+ const environmentFiles = context.plan.files.filter(
237716
+ (f) => f.type === "environment" && f.path !== "environments/index.ts"
237717
+ );
237718
+ const imports = environmentFiles.map((envFile) => {
237719
+ const envEntity = envFile.entities[0];
237720
+ if (envEntity) {
237721
+ return `import { ${envEntity.variableName} } from './${envFile.path.replace("environments/", "").replace(".ts", "")}';`;
237722
+ }
237723
+ return "";
237724
+ }).filter(Boolean).join("\n");
237725
+ const envSettings = environmentFiles.map((envFile) => {
237726
+ const envEntity = envFile.entities[0];
237727
+ return envEntity ? ` ${envEntity.variableName},` : "";
237728
+ }).filter(Boolean).join("\n");
237729
+ return `${commonInstructions}
237730
+
237731
+ ENVIRONMENTS INDEX FILE (CRITICAL):
237732
+
237733
+ Create an environments/index.ts file that exports environment settings using createEnvironmentSettings.
237734
+
237735
+ CREDENTIAL DATA (from project):
237736
+ ${JSON.stringify(credentialData, null, 2)}
237737
+
237738
+ EXACT IMPORT STATEMENTS (MUST USE THESE):
237739
+ ${imports}
237740
+
237741
+ ENVIRONMENTS INDEX STRUCTURE (MUST FOLLOW EXACTLY):
237742
+
237743
+ import { createEnvironmentSettings } from '@inkeep/agents-sdk';
237744
+ ${imports}
237745
+
237746
+ export const envSettings = createEnvironmentSettings({
237747
+ ${envSettings}
237748
+ });
237749
+
237750
+ CRITICAL RULES:
237751
+ 1. Import createEnvironmentSettings from '@inkeep/agents-sdk'
237752
+ 2. Use the EXACT import statements provided above - DO NOT modify them
237753
+ 3. Use the EXACT variable names in the createEnvironmentSettings object
237754
+ 4. Export envSettings using createEnvironmentSettings()
237755
+ 5. Include all environments that have credential files
237756
+
237757
+ Generate ONLY the TypeScript code without markdown.`;
237758
+ }
237759
+ const envName = fileName.replace(".env.ts", "") || "development";
237760
+ return `${commonInstructions}
237761
+
237762
+ ENVIRONMENT FILE (CRITICAL):
237763
+
237764
+ Create an environment file that registers credential settings for the "${envName}" environment.
237765
+
237766
+ CREDENTIAL DATA (from project):
237767
+ ${JSON.stringify(credentialData, null, 2)}
237768
+
237769
+ ENVIRONMENT FILE STRUCTURE (MUST FOLLOW EXACTLY):
237770
+
237771
+ import { credential, registerEnvironmentSettings } from '@inkeep/agents-sdk';
237772
+
237773
+ export const ${envName} = registerEnvironmentSettings({
237774
+ credentials: {
237775
+ CREDENTIAL_KEY: credential({
237776
+ id: 'CREDENTIAL_ID',
237777
+ type: 'CREDENTIAL_TYPE',
237778
+ credentialStoreId: 'CREDENTIAL_STORE_ID',
237779
+ retrievalParams: {
237780
+ key: 'ENV_VARIABLE_NAME'
237781
+ }
237782
+ })
237783
+ }
237784
+ });
237785
+
237786
+ CRITICAL RULES:
237787
+ 1. Import { credential, registerEnvironmentSettings } from '@inkeep/agents-sdk'
237788
+ 2. Export a const named "${envName}" (matching the environment)
237789
+ 3. Use registerEnvironmentSettings() wrapper
237790
+ 4. Create credential() objects for each credential in the data
237791
+ 5. Convert credential IDs to environment variable keys (e.g., 'linear-api' -> 'LINEAR_API_KEY')
237792
+ 6. Use exact credential IDs, types, and credentialStoreId from the data provided
237793
+ 7. Set retrievalParams.key to the environment variable name (uppercase with underscores)
237794
+
237795
+ Example for credential with id 'linear-api':
237796
+ - Export const: ${envName}
237797
+ - Credential key: linear_api (underscore format for object key)
237798
+ - retrievalParams.key: 'LINEAR_API_KEY' (uppercase for environment variable)
237799
+
237800
+ Generate ONLY the TypeScript code without markdown.`;
237801
+ }
237259
237802
  var init_unified_generator = __esm({
237260
237803
  "src/codegen/unified-generator.ts"() {
237261
237804
  "use strict";
@@ -238788,6 +239331,7 @@ function performBackgroundVersionCheck() {
238788
239331
 
238789
239332
  // src/commands/pull.ts
238790
239333
  init_pull_llm_generate();
239334
+ init_variable_name_registry();
238791
239335
  async function detectCurrentProject(debug = false) {
238792
239336
  const indexPath = join10(process.cwd(), "index.ts");
238793
239337
  if (debug) {
@@ -238897,14 +239441,15 @@ async function verifyGeneratedFiles(projectDir, originalProjectData, debug = fal
238897
239441
  }
238898
239442
  }
238899
239443
  const toolsDir = join10(projectDir, "tools");
238900
- const expectedTools = Object.keys(originalProjectData.tools || {});
238901
- for (const toolId of expectedTools) {
238902
- const kebabCaseId = toolId.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[\s_]+/g, "-").toLowerCase();
238903
- const toolPath = join10(toolsDir, `${kebabCaseId}.ts`);
239444
+ const expectedTools = Object.entries(originalProjectData.tools || {});
239445
+ const filenameGenerator = new VariableNameGenerator(DEFAULT_NAMING_CONVENTIONS);
239446
+ for (const [toolId, toolData] of expectedTools) {
239447
+ const fileName = filenameGenerator.generateFileName(toolId, "tool", toolData);
239448
+ const toolPath = join10(toolsDir, `${fileName}.ts`);
238904
239449
  if (!existsSync9(toolPath)) {
238905
- errors.push(`Tool file not found: tools/${kebabCaseId}.ts`);
239450
+ errors.push(`Tool file not found: tools/${fileName}.ts`);
238906
239451
  } else if (debug) {
238907
- console.log(chalk9.gray(` \u2713 Tool file exists: tools/${kebabCaseId}.ts`));
239452
+ console.log(chalk9.gray(` \u2713 Tool file exists: tools/${fileName}.ts`));
238908
239453
  }
238909
239454
  }
238910
239455
  const dataComponentsDir = join10(projectDir, "data-components");
@@ -239307,7 +239852,8 @@ async function pullProjectCommand(options) {
239307
239852
  const modelSettings = {
239308
239853
  model: ANTHROPIC_MODELS.CLAUDE_SONNET_4_5
239309
239854
  };
239310
- const plan = await generatePlan2(projectData, patterns, modelSettings, createModel2);
239855
+ const targetEnvironment = options.env || "development";
239856
+ const plan = await generatePlan2(projectData, patterns, modelSettings, createModel2, targetEnvironment);
239311
239857
  spinner.succeed("Generation plan created");
239312
239858
  const { displayPlanSummary: displayPlanSummary2, displayConflictWarning: displayConflictWarning2 } = await Promise.resolve().then(() => (init_display_utils(), display_utils_exports));
239313
239859
  displayPlanSummary2(plan);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inkeep/agents-cli",
3
- "version": "0.22.5",
3
+ "version": "0.22.7",
4
4
  "description": "Inkeep CLI tool",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -46,8 +46,8 @@
46
46
  "recast": "^0.23.0",
47
47
  "ts-morph": "^26.0.0",
48
48
  "tsx": "^4.20.5",
49
- "@inkeep/agents-core": "^0.22.5",
50
- "@inkeep/agents-sdk": "^0.22.5"
49
+ "@inkeep/agents-sdk": "^0.22.7",
50
+ "@inkeep/agents-core": "^0.22.7"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@types/degit": "^2.8.6",