@dexto/agent-management 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/dist/AgentFactory.cjs +1 -2
  2. package/dist/AgentFactory.d.ts +1 -1
  3. package/dist/AgentFactory.d.ts.map +1 -1
  4. package/dist/AgentFactory.js +1 -2
  5. package/dist/config/config-enrichment.cjs +1 -1
  6. package/dist/config/config-enrichment.d.ts +1 -1
  7. package/dist/config/config-enrichment.js +1 -1
  8. package/dist/config/errors.cjs +2 -2
  9. package/dist/config/errors.js +2 -2
  10. package/dist/index.cjs +69 -0
  11. package/dist/index.d.ts +4 -3
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +72 -2
  14. package/dist/installation.cjs +0 -13
  15. package/dist/installation.d.ts +0 -2
  16. package/dist/installation.d.ts.map +1 -1
  17. package/dist/installation.js +0 -13
  18. package/dist/models/custom-models.cjs +43 -2
  19. package/dist/models/custom-models.d.ts +49 -6
  20. package/dist/models/custom-models.d.ts.map +1 -1
  21. package/dist/models/custom-models.js +42 -2
  22. package/dist/models/index.cjs +89 -0
  23. package/dist/models/index.d.ts +11 -0
  24. package/dist/models/index.d.ts.map +1 -0
  25. package/dist/models/index.js +68 -0
  26. package/dist/models/path-resolver.cjs +154 -0
  27. package/dist/models/path-resolver.d.ts +77 -0
  28. package/dist/models/path-resolver.d.ts.map +1 -0
  29. package/dist/models/path-resolver.js +108 -0
  30. package/dist/models/state-manager.cjs +220 -0
  31. package/dist/models/state-manager.d.ts +138 -0
  32. package/dist/models/state-manager.d.ts.map +1 -0
  33. package/dist/models/state-manager.js +184 -0
  34. package/dist/preferences/error-codes.cjs +2 -0
  35. package/dist/preferences/error-codes.d.ts +3 -1
  36. package/dist/preferences/error-codes.d.ts.map +1 -1
  37. package/dist/preferences/error-codes.js +2 -0
  38. package/dist/preferences/index.d.ts +1 -1
  39. package/dist/preferences/index.d.ts.map +1 -1
  40. package/dist/preferences/loader.cjs +32 -6
  41. package/dist/preferences/loader.d.ts +23 -4
  42. package/dist/preferences/loader.d.ts.map +1 -1
  43. package/dist/preferences/loader.js +32 -6
  44. package/dist/preferences/schemas.cjs +21 -3
  45. package/dist/preferences/schemas.d.ts +52 -24
  46. package/dist/preferences/schemas.d.ts.map +1 -1
  47. package/dist/preferences/schemas.js +28 -4
  48. package/dist/registry/registry.cjs +7 -43
  49. package/dist/registry/registry.d.ts +3 -6
  50. package/dist/registry/registry.d.ts.map +1 -1
  51. package/dist/registry/registry.js +7 -43
  52. package/dist/registry/types.d.ts +2 -4
  53. package/dist/registry/types.d.ts.map +1 -1
  54. package/dist/resolver.cjs +20 -20
  55. package/dist/resolver.d.ts +1 -2
  56. package/dist/resolver.d.ts.map +1 -1
  57. package/dist/resolver.js +20 -20
  58. package/dist/utils/api-key-resolver.cjs +19 -1
  59. package/dist/utils/api-key-resolver.d.ts.map +1 -1
  60. package/dist/utils/api-key-resolver.js +19 -1
  61. package/dist/utils/api-key-store.cjs +46 -0
  62. package/dist/utils/api-key-store.d.ts +27 -0
  63. package/dist/utils/api-key-store.d.ts.map +1 -1
  64. package/dist/utils/api-key-store.js +44 -0
  65. package/dist/utils/env-file.cjs +20 -68
  66. package/dist/utils/env-file.d.ts +2 -1
  67. package/dist/utils/env-file.d.ts.map +1 -1
  68. package/dist/utils/env-file.js +20 -68
  69. package/dist/writer.cjs +20 -2
  70. package/dist/writer.d.ts +1 -0
  71. package/dist/writer.d.ts.map +1 -1
  72. package/dist/writer.js +20 -2
  73. package/package.json +2 -2
@@ -115,10 +115,9 @@ export interface AgentRegistry {
115
115
  /**
116
116
  * Installs an agent from the registry by ID
117
117
  * @param agentId - Unique agent identifier
118
- * @param injectPreferences - Whether to inject global preferences (default: true)
119
118
  * @returns Path to the installed agent config
120
119
  */
121
- installAgent(agentId: string, injectPreferences?: boolean): Promise<string>;
120
+ installAgent(agentId: string): Promise<string>;
122
121
  /**
123
122
  * Uninstalls an agent by ID
124
123
  * @param agentId - Unique agent identifier
@@ -133,10 +132,9 @@ export interface AgentRegistry {
133
132
  * Resolves an agent ID or path and optionally auto-installs if needed
134
133
  * @param idOrPath - Agent ID from registry or filesystem path
135
134
  * @param autoInstall - Whether to auto-install from registry (default: true)
136
- * @param injectPreferences - Whether to inject preferences during install (default: true)
137
135
  * @returns Path to the agent config file
138
136
  */
139
- resolveAgent(idOrPath: string, autoInstall?: boolean, injectPreferences?: boolean): Promise<string>;
137
+ resolveAgent(idOrPath: string, autoInstall?: boolean): Promise<string>;
140
138
  }
141
139
  export {};
142
140
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/registry/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMtD;AAED;;GAEG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWxB,CAAC;AAEd,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE3E;;GAEG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKd,CAAC;AAEd,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC;AAEvD,KAAK,WAAW,GAAG;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;CAC9C,CAAC;AAEF;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,WAAW,CAsC/D;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IACnC;;OAEG;IACH,kBAAkB,IAAI,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IACzD;;;;;OAKG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5E;;;;OAIG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE;;OAEG;IACH,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACxC;;;;;;OAMG;IACH,YAAY,CACR,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,OAAO,EACrB,iBAAiB,CAAC,EAAE,OAAO,GAC5B,OAAO,CAAC,MAAM,CAAC,CAAC;CACtB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/registry/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMtD;AAED;;GAEG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWxB,CAAC;AAEd,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE3E;;GAEG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKd,CAAC;AAEd,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC;AAEvD,KAAK,WAAW,GAAG;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;CAC9C,CAAC;AAEF;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,WAAW,CAsC/D;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IACnC;;OAEG;IACH,kBAAkB,IAAI,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IACzD;;;;OAIG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/C;;;;OAIG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE;;OAEG;IACH,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACxC;;;;;OAKG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1E"}
package/dist/resolver.cjs CHANGED
@@ -42,7 +42,7 @@ var import_config = require("./config/index.js");
42
42
  var import_errors = require("./registry/errors.js");
43
43
  var import_AgentManager = require("./AgentManager.js");
44
44
  var import_installation = require("./installation.js");
45
- async function resolveAgentPath(nameOrPath, autoInstall = true, injectPreferences = true) {
45
+ async function resolveAgentPath(nameOrPath, autoInstall = true) {
46
46
  if (nameOrPath && (0, import_path2.isPath)(nameOrPath)) {
47
47
  const resolved = import_path.default.resolve(nameOrPath);
48
48
  try {
@@ -56,11 +56,11 @@ async function resolveAgentPath(nameOrPath, autoInstall = true, injectPreference
56
56
  }
57
57
  }
58
58
  if (nameOrPath) {
59
- return await resolveAgentByName(nameOrPath, autoInstall, injectPreferences);
59
+ return await resolveAgentByName(nameOrPath, autoInstall);
60
60
  }
61
- return await resolveDefaultAgentByContext(autoInstall, injectPreferences);
61
+ return await resolveDefaultAgentByContext(autoInstall);
62
62
  }
63
- async function resolveAgentByName(agentId, autoInstall, injectPreferences) {
63
+ async function resolveAgentByName(agentId, autoInstall) {
64
64
  const agentsDir = (0, import_path2.getDextoGlobalPath)("agents");
65
65
  const installedRegistryPath = import_path.default.join(agentsDir, "registry.json");
66
66
  try {
@@ -76,7 +76,7 @@ async function resolveAgentByName(agentId, autoInstall, injectPreferences) {
76
76
  if (autoInstall) {
77
77
  try {
78
78
  import_core.logger.info(`Auto-installing agent '${agentId}' from bundled registry`);
79
- const configPath = await (0, import_installation.installBundledAgent)(agentId, { injectPreferences });
79
+ const configPath = await (0, import_installation.installBundledAgent)(agentId);
80
80
  return configPath;
81
81
  } catch (error) {
82
82
  import_core.logger.debug(`Failed to auto-install agent '${agentId}': ${error}`);
@@ -97,26 +97,26 @@ async function getAgentConfigPath(agentId) {
97
97
  }
98
98
  return import_path.default.resolve(import_path.default.dirname(installedRegistryPath), agentEntry.configPath);
99
99
  }
100
- async function resolveDefaultAgentByContext(autoInstall = true, injectPreferences = true) {
100
+ async function resolveDefaultAgentByContext(autoInstall = true) {
101
101
  const executionContext = (0, import_execution_context.getExecutionContext)();
102
102
  switch (executionContext) {
103
103
  case "dexto-source":
104
- return await resolveDefaultAgentForDextoSource(autoInstall, injectPreferences);
104
+ return await resolveDefaultAgentForDextoSource(autoInstall);
105
105
  case "dexto-project":
106
- return await resolveDefaultAgentForDextoProject(autoInstall, injectPreferences);
106
+ return await resolveDefaultAgentForDextoProject(autoInstall);
107
107
  case "global-cli":
108
- return await resolveDefaultAgentForGlobalCLI(autoInstall, injectPreferences);
108
+ return await resolveDefaultAgentForGlobalCLI(autoInstall);
109
109
  default:
110
110
  throw import_config.ConfigError.unknownContext(executionContext);
111
111
  }
112
112
  }
113
- async function resolveDefaultAgentForDextoSource(autoInstall = true, injectPreferences = true) {
113
+ async function resolveDefaultAgentForDextoSource(autoInstall = true) {
114
114
  import_core.logger.debug("Resolving default agent for dexto source context");
115
115
  const sourceRoot = (0, import_execution_context.findDextoSourceRoot)();
116
116
  if (!sourceRoot) {
117
117
  throw import_config.ConfigError.bundledNotFound("dexto source directory not found");
118
118
  }
119
- const repoConfigPath = import_path.default.join(sourceRoot, "agents", "default-agent.yml");
119
+ const repoConfigPath = import_path.default.join(sourceRoot, "agents", "coding-agent", "coding-agent.yml");
120
120
  const isDevMode = process.env.DEXTO_DEV_MODE === "true";
121
121
  if (isDevMode) {
122
122
  import_core.logger.debug("Dev mode: using repository config file");
@@ -133,7 +133,7 @@ async function resolveDefaultAgentForDextoSource(autoInstall = true, injectPrefe
133
133
  if (preferences.setup.completed) {
134
134
  import_core.logger.debug("Using user preferences in dexto-source context");
135
135
  const preferredAgentName = preferences.defaults.defaultAgent;
136
- return await resolveAgentByName(preferredAgentName, autoInstall, injectPreferences);
136
+ return await resolveAgentByName(preferredAgentName, autoInstall);
137
137
  }
138
138
  } catch (error) {
139
139
  import_core.logger.warn(`Failed to load preferences, falling back to repo config: ${error}`);
@@ -147,16 +147,16 @@ async function resolveDefaultAgentForDextoSource(autoInstall = true, injectPrefe
147
147
  throw import_config.ConfigError.bundledNotFound(repoConfigPath);
148
148
  }
149
149
  }
150
- async function resolveDefaultAgentForDextoProject(autoInstall = true, injectPreferences = true) {
150
+ async function resolveDefaultAgentForDextoProject(autoInstall = true) {
151
151
  import_core.logger.debug("Resolving default agent for dexto project context");
152
152
  const projectRoot = (0, import_execution_context.findDextoProjectRoot)();
153
153
  if (!projectRoot) {
154
154
  throw import_config.ConfigError.unknownContext("dexto-project: project root not found");
155
155
  }
156
156
  const candidatePaths = [
157
- import_path.default.join(projectRoot, "default-agent.yml"),
158
- import_path.default.join(projectRoot, "agents", "default-agent.yml"),
159
- import_path.default.join(projectRoot, "src", "dexto", "agents", "default-agent.yml")
157
+ import_path.default.join(projectRoot, "coding-agent.yml"),
158
+ import_path.default.join(projectRoot, "agents", "coding-agent.yml"),
159
+ import_path.default.join(projectRoot, "src", "dexto", "agents", "coding-agent.yml")
160
160
  ];
161
161
  for (const p of candidatePaths) {
162
162
  try {
@@ -165,7 +165,7 @@ async function resolveDefaultAgentForDextoProject(autoInstall = true, injectPref
165
165
  } catch {
166
166
  }
167
167
  }
168
- import_core.logger.debug(`No project-local default-agent.yml found in ${projectRoot}`);
168
+ import_core.logger.debug(`No project-local coding-agent.yml found in ${projectRoot}`);
169
169
  if (!(0, import_loader.globalPreferencesExist)()) {
170
170
  throw import_config.ConfigError.noProjectDefault(projectRoot);
171
171
  }
@@ -174,9 +174,9 @@ async function resolveDefaultAgentForDextoProject(autoInstall = true, injectPref
174
174
  throw import_config.ConfigError.setupIncomplete();
175
175
  }
176
176
  const preferredAgentName = preferences.defaults.defaultAgent;
177
- return await resolveAgentByName(preferredAgentName, autoInstall, injectPreferences);
177
+ return await resolveAgentByName(preferredAgentName, autoInstall);
178
178
  }
179
- async function resolveDefaultAgentForGlobalCLI(autoInstall = true, injectPreferences = true) {
179
+ async function resolveDefaultAgentForGlobalCLI(autoInstall = true) {
180
180
  import_core.logger.debug("Resolving default agent for global CLI context");
181
181
  if (!(0, import_loader.globalPreferencesExist)()) {
182
182
  throw import_config.ConfigError.noGlobalPreferences();
@@ -186,7 +186,7 @@ async function resolveDefaultAgentForGlobalCLI(autoInstall = true, injectPrefere
186
186
  throw import_config.ConfigError.setupIncomplete();
187
187
  }
188
188
  const preferredAgentName = preferences.defaults.defaultAgent;
189
- return await resolveAgentByName(preferredAgentName, autoInstall, injectPreferences);
189
+ return await resolveAgentByName(preferredAgentName, autoInstall);
190
190
  }
191
191
  async function updateDefaultAgentPreference(agentName) {
192
192
  const agentsDir = (0, import_path2.getDextoGlobalPath)("agents");
@@ -2,12 +2,11 @@
2
2
  * Resolve agent path with automatic installation if needed
3
3
  * @param nameOrPath Optional agent name or explicit path
4
4
  * @param autoInstall Whether to automatically install missing agents from bundled registry (default: true)
5
- * @param injectPreferences Whether to inject preferences during auto-installation (default: true)
6
5
  * @returns Resolved absolute path to agent config
7
6
  * @throws {ConfigError} For path/config issues (file not found, unknown context, setup incomplete)
8
7
  * @throws {RegistryError} For agent lookup failures (agent not found, not installed)
9
8
  */
10
- export declare function resolveAgentPath(nameOrPath?: string, autoInstall?: boolean, injectPreferences?: boolean): Promise<string>;
9
+ export declare function resolveAgentPath(nameOrPath?: string, autoInstall?: boolean): Promise<string>;
11
10
  /**
12
11
  * Update default agent preference
13
12
  * @param agentName The agent name to set as the new default
@@ -1 +1 @@
1
- {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAoCA;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAClC,UAAU,CAAC,EAAE,MAAM,EACnB,WAAW,GAAE,OAAc,EAC3B,iBAAiB,GAAE,OAAc,GAClC,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAiND;;;;GAIG;AACH,wBAAsB,4BAA4B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BnF"}
1
+ {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAoCA;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CAClC,UAAU,CAAC,EAAE,MAAM,EACnB,WAAW,GAAE,OAAc,GAC5B,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAiMD;;;;GAIG;AACH,wBAAsB,4BAA4B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BnF"}
package/dist/resolver.js CHANGED
@@ -12,7 +12,7 @@ import { ConfigError } from "./config/index.js";
12
12
  import { RegistryError } from "./registry/errors.js";
13
13
  import { AgentManager } from "./AgentManager.js";
14
14
  import { installBundledAgent } from "./installation.js";
15
- async function resolveAgentPath(nameOrPath, autoInstall = true, injectPreferences = true) {
15
+ async function resolveAgentPath(nameOrPath, autoInstall = true) {
16
16
  if (nameOrPath && isPath(nameOrPath)) {
17
17
  const resolved = path.resolve(nameOrPath);
18
18
  try {
@@ -26,11 +26,11 @@ async function resolveAgentPath(nameOrPath, autoInstall = true, injectPreference
26
26
  }
27
27
  }
28
28
  if (nameOrPath) {
29
- return await resolveAgentByName(nameOrPath, autoInstall, injectPreferences);
29
+ return await resolveAgentByName(nameOrPath, autoInstall);
30
30
  }
31
- return await resolveDefaultAgentByContext(autoInstall, injectPreferences);
31
+ return await resolveDefaultAgentByContext(autoInstall);
32
32
  }
33
- async function resolveAgentByName(agentId, autoInstall, injectPreferences) {
33
+ async function resolveAgentByName(agentId, autoInstall) {
34
34
  const agentsDir = getDextoGlobalPath("agents");
35
35
  const installedRegistryPath = path.join(agentsDir, "registry.json");
36
36
  try {
@@ -46,7 +46,7 @@ async function resolveAgentByName(agentId, autoInstall, injectPreferences) {
46
46
  if (autoInstall) {
47
47
  try {
48
48
  logger.info(`Auto-installing agent '${agentId}' from bundled registry`);
49
- const configPath = await installBundledAgent(agentId, { injectPreferences });
49
+ const configPath = await installBundledAgent(agentId);
50
50
  return configPath;
51
51
  } catch (error) {
52
52
  logger.debug(`Failed to auto-install agent '${agentId}': ${error}`);
@@ -67,26 +67,26 @@ async function getAgentConfigPath(agentId) {
67
67
  }
68
68
  return path.resolve(path.dirname(installedRegistryPath), agentEntry.configPath);
69
69
  }
70
- async function resolveDefaultAgentByContext(autoInstall = true, injectPreferences = true) {
70
+ async function resolveDefaultAgentByContext(autoInstall = true) {
71
71
  const executionContext = getExecutionContext();
72
72
  switch (executionContext) {
73
73
  case "dexto-source":
74
- return await resolveDefaultAgentForDextoSource(autoInstall, injectPreferences);
74
+ return await resolveDefaultAgentForDextoSource(autoInstall);
75
75
  case "dexto-project":
76
- return await resolveDefaultAgentForDextoProject(autoInstall, injectPreferences);
76
+ return await resolveDefaultAgentForDextoProject(autoInstall);
77
77
  case "global-cli":
78
- return await resolveDefaultAgentForGlobalCLI(autoInstall, injectPreferences);
78
+ return await resolveDefaultAgentForGlobalCLI(autoInstall);
79
79
  default:
80
80
  throw ConfigError.unknownContext(executionContext);
81
81
  }
82
82
  }
83
- async function resolveDefaultAgentForDextoSource(autoInstall = true, injectPreferences = true) {
83
+ async function resolveDefaultAgentForDextoSource(autoInstall = true) {
84
84
  logger.debug("Resolving default agent for dexto source context");
85
85
  const sourceRoot = findDextoSourceRoot();
86
86
  if (!sourceRoot) {
87
87
  throw ConfigError.bundledNotFound("dexto source directory not found");
88
88
  }
89
- const repoConfigPath = path.join(sourceRoot, "agents", "default-agent.yml");
89
+ const repoConfigPath = path.join(sourceRoot, "agents", "coding-agent", "coding-agent.yml");
90
90
  const isDevMode = process.env.DEXTO_DEV_MODE === "true";
91
91
  if (isDevMode) {
92
92
  logger.debug("Dev mode: using repository config file");
@@ -103,7 +103,7 @@ async function resolveDefaultAgentForDextoSource(autoInstall = true, injectPrefe
103
103
  if (preferences.setup.completed) {
104
104
  logger.debug("Using user preferences in dexto-source context");
105
105
  const preferredAgentName = preferences.defaults.defaultAgent;
106
- return await resolveAgentByName(preferredAgentName, autoInstall, injectPreferences);
106
+ return await resolveAgentByName(preferredAgentName, autoInstall);
107
107
  }
108
108
  } catch (error) {
109
109
  logger.warn(`Failed to load preferences, falling back to repo config: ${error}`);
@@ -117,16 +117,16 @@ async function resolveDefaultAgentForDextoSource(autoInstall = true, injectPrefe
117
117
  throw ConfigError.bundledNotFound(repoConfigPath);
118
118
  }
119
119
  }
120
- async function resolveDefaultAgentForDextoProject(autoInstall = true, injectPreferences = true) {
120
+ async function resolveDefaultAgentForDextoProject(autoInstall = true) {
121
121
  logger.debug("Resolving default agent for dexto project context");
122
122
  const projectRoot = findDextoProjectRoot();
123
123
  if (!projectRoot) {
124
124
  throw ConfigError.unknownContext("dexto-project: project root not found");
125
125
  }
126
126
  const candidatePaths = [
127
- path.join(projectRoot, "default-agent.yml"),
128
- path.join(projectRoot, "agents", "default-agent.yml"),
129
- path.join(projectRoot, "src", "dexto", "agents", "default-agent.yml")
127
+ path.join(projectRoot, "coding-agent.yml"),
128
+ path.join(projectRoot, "agents", "coding-agent.yml"),
129
+ path.join(projectRoot, "src", "dexto", "agents", "coding-agent.yml")
130
130
  ];
131
131
  for (const p of candidatePaths) {
132
132
  try {
@@ -135,7 +135,7 @@ async function resolveDefaultAgentForDextoProject(autoInstall = true, injectPref
135
135
  } catch {
136
136
  }
137
137
  }
138
- logger.debug(`No project-local default-agent.yml found in ${projectRoot}`);
138
+ logger.debug(`No project-local coding-agent.yml found in ${projectRoot}`);
139
139
  if (!globalPreferencesExist()) {
140
140
  throw ConfigError.noProjectDefault(projectRoot);
141
141
  }
@@ -144,9 +144,9 @@ async function resolveDefaultAgentForDextoProject(autoInstall = true, injectPref
144
144
  throw ConfigError.setupIncomplete();
145
145
  }
146
146
  const preferredAgentName = preferences.defaults.defaultAgent;
147
- return await resolveAgentByName(preferredAgentName, autoInstall, injectPreferences);
147
+ return await resolveAgentByName(preferredAgentName, autoInstall);
148
148
  }
149
- async function resolveDefaultAgentForGlobalCLI(autoInstall = true, injectPreferences = true) {
149
+ async function resolveDefaultAgentForGlobalCLI(autoInstall = true) {
150
150
  logger.debug("Resolving default agent for global CLI context");
151
151
  if (!globalPreferencesExist()) {
152
152
  throw ConfigError.noGlobalPreferences();
@@ -156,7 +156,7 @@ async function resolveDefaultAgentForGlobalCLI(autoInstall = true, injectPrefere
156
156
  throw ConfigError.setupIncomplete();
157
157
  }
158
158
  const preferredAgentName = preferences.defaults.defaultAgent;
159
- return await resolveAgentByName(preferredAgentName, autoInstall, injectPreferences);
159
+ return await resolveAgentByName(preferredAgentName, autoInstall);
160
160
  }
161
161
  async function updateDefaultAgentPreference(agentName) {
162
162
  const agentsDir = getDextoGlobalPath("agents");
@@ -31,7 +31,25 @@ const PROVIDER_API_KEY_MAP = {
31
31
  google: ["GOOGLE_GENERATIVE_AI_API_KEY", "GOOGLE_API_KEY", "GEMINI_API_KEY"],
32
32
  groq: ["GROQ_API_KEY"],
33
33
  cohere: ["COHERE_API_KEY"],
34
- xai: ["XAI_API_KEY", "X_AI_API_KEY"]
34
+ xai: ["XAI_API_KEY", "X_AI_API_KEY"],
35
+ openrouter: ["OPENROUTER_API_KEY"],
36
+ litellm: ["LITELLM_API_KEY", "LITELLM_KEY"],
37
+ glama: ["GLAMA_API_KEY"],
38
+ // Vertex uses ADC (Application Default Credentials), not API keys
39
+ // GOOGLE_APPLICATION_CREDENTIALS points to service account JSON (optional)
40
+ // Primary config is GOOGLE_VERTEX_PROJECT (required) + GOOGLE_VERTEX_LOCATION (optional)
41
+ vertex: [],
42
+ // Bedrock supports two auth methods:
43
+ // 1. AWS_BEARER_TOKEN_BEDROCK - Bedrock API key (simplest)
44
+ // 2. AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY + AWS_REGION (IAM credentials)
45
+ // AWS_SESSION_TOKEN (optional, for temporary credentials)
46
+ bedrock: ["AWS_BEARER_TOKEN_BEDROCK"],
47
+ // Local providers don't require API keys
48
+ local: [],
49
+ // Native node-llama-cpp execution
50
+ ollama: []
51
+ // Ollama server (may optionally use OLLAMA_API_KEY for remote servers)
52
+ // TODO: dexto: ['DEXTO_API_KEY'],
35
53
  // perplexity: ['PERPLEXITY_API_KEY'],
36
54
  // together: ['TOGETHER_API_KEY'],
37
55
  // fireworks: ['FIREWORKS_API_KEY'],
@@ -1 +1 @@
1
- {"version":3,"file":"api-key-resolver.d.ts","sourceRoot":"","sources":["../../src/utils/api-key-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;GAGG;AAGH,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,CAY9D,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAelF;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,CAGpE"}
1
+ {"version":3,"file":"api-key-resolver.d.ts","sourceRoot":"","sources":["../../src/utils/api-key-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;GAGG;AAGH,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,CA4B9D,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAelF;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,CAGpE"}
@@ -6,7 +6,25 @@ const PROVIDER_API_KEY_MAP = {
6
6
  google: ["GOOGLE_GENERATIVE_AI_API_KEY", "GOOGLE_API_KEY", "GEMINI_API_KEY"],
7
7
  groq: ["GROQ_API_KEY"],
8
8
  cohere: ["COHERE_API_KEY"],
9
- xai: ["XAI_API_KEY", "X_AI_API_KEY"]
9
+ xai: ["XAI_API_KEY", "X_AI_API_KEY"],
10
+ openrouter: ["OPENROUTER_API_KEY"],
11
+ litellm: ["LITELLM_API_KEY", "LITELLM_KEY"],
12
+ glama: ["GLAMA_API_KEY"],
13
+ // Vertex uses ADC (Application Default Credentials), not API keys
14
+ // GOOGLE_APPLICATION_CREDENTIALS points to service account JSON (optional)
15
+ // Primary config is GOOGLE_VERTEX_PROJECT (required) + GOOGLE_VERTEX_LOCATION (optional)
16
+ vertex: [],
17
+ // Bedrock supports two auth methods:
18
+ // 1. AWS_BEARER_TOKEN_BEDROCK - Bedrock API key (simplest)
19
+ // 2. AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY + AWS_REGION (IAM credentials)
20
+ // AWS_SESSION_TOKEN (optional, for temporary credentials)
21
+ bedrock: ["AWS_BEARER_TOKEN_BEDROCK"],
22
+ // Local providers don't require API keys
23
+ local: [],
24
+ // Native node-llama-cpp execution
25
+ ollama: []
26
+ // Ollama server (may optionally use OLLAMA_API_KEY for remote servers)
27
+ // TODO: dexto: ['DEXTO_API_KEY'],
10
28
  // perplexity: ['PERPLEXITY_API_KEY'],
11
29
  // together: ['TOGETHER_API_KEY'],
12
30
  // fireworks: ['FIREWORKS_API_KEY'],
@@ -18,6 +18,8 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var api_key_store_exports = {};
20
20
  __export(api_key_store_exports, {
21
+ SHARED_API_KEY_PROVIDERS: () => SHARED_API_KEY_PROVIDERS,
22
+ determineApiKeyStorage: () => determineApiKeyStorage,
21
23
  getProviderKeyStatus: () => getProviderKeyStatus,
22
24
  listProviderKeyStatus: () => listProviderKeyStatus,
23
25
  saveProviderApiKey: () => saveProviderApiKey
@@ -37,6 +39,27 @@ async function saveProviderApiKey(provider, apiKey, startPath) {
37
39
  return { envVar, targetEnvPath };
38
40
  }
39
41
  function getProviderKeyStatus(provider) {
42
+ if (provider === "vertex") {
43
+ const projectId = process.env.GOOGLE_VERTEX_PROJECT;
44
+ return {
45
+ hasApiKey: Boolean(projectId && projectId.trim()),
46
+ envVar: "GOOGLE_VERTEX_PROJECT"
47
+ };
48
+ }
49
+ if (provider === "bedrock") {
50
+ const apiKey = process.env.AWS_BEARER_TOKEN_BEDROCK;
51
+ if (apiKey && apiKey.trim()) {
52
+ return {
53
+ hasApiKey: true,
54
+ envVar: "AWS_BEARER_TOKEN_BEDROCK"
55
+ };
56
+ }
57
+ const region = process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION;
58
+ return {
59
+ hasApiKey: Boolean(region && region.trim()),
60
+ envVar: "AWS_REGION"
61
+ };
62
+ }
40
63
  const envVar = (0, import_api_key_resolver.getPrimaryApiKeyEnvVar)(provider);
41
64
  const key = (0, import_api_key_resolver.resolveApiKeyForProvider)(provider);
42
65
  return { hasApiKey: Boolean(key && key.trim()), envVar };
@@ -48,8 +71,31 @@ function listProviderKeyStatus() {
48
71
  }
49
72
  return result;
50
73
  }
74
+ const SHARED_API_KEY_PROVIDERS = ["glama", "openrouter", "litellm"];
75
+ function determineApiKeyStorage(provider, userEnteredKey, providerHasKey, existingProviderKey) {
76
+ const result = {
77
+ saveToProviderEnvVar: false,
78
+ saveAsPerModel: false
79
+ };
80
+ if (!userEnteredKey) {
81
+ return result;
82
+ }
83
+ const hasSharedEnvVarKey = SHARED_API_KEY_PROVIDERS.includes(provider);
84
+ if (hasSharedEnvVarKey) {
85
+ if (!providerHasKey) {
86
+ result.saveToProviderEnvVar = true;
87
+ } else if (existingProviderKey && userEnteredKey !== existingProviderKey) {
88
+ result.saveAsPerModel = true;
89
+ }
90
+ } else {
91
+ result.saveAsPerModel = true;
92
+ }
93
+ return result;
94
+ }
51
95
  // Annotate the CommonJS export names for ESM import in node:
52
96
  0 && (module.exports = {
97
+ SHARED_API_KEY_PROVIDERS,
98
+ determineApiKeyStorage,
53
99
  getProviderKeyStatus,
54
100
  listProviderKeyStatus,
55
101
  saveProviderApiKey
@@ -15,4 +15,31 @@ export declare function listProviderKeyStatus(): Record<string, {
15
15
  hasApiKey: boolean;
16
16
  envVar: string;
17
17
  }>;
18
+ /**
19
+ * Providers that use a shared env var for API keys (vs per-endpoint like openai-compatible).
20
+ * For these providers, we save to the env var if none exists, otherwise per-model override.
21
+ */
22
+ export declare const SHARED_API_KEY_PROVIDERS: readonly ["glama", "openrouter", "litellm"];
23
+ export type ApiKeyStorageStrategy = {
24
+ /** Save the key to provider env var (e.g., GLAMA_API_KEY) */
25
+ saveToProviderEnvVar: boolean;
26
+ /** Save the key as per-model override in custom model config */
27
+ saveAsPerModel: boolean;
28
+ };
29
+ /**
30
+ * Determine where to store an API key for a custom model.
31
+ *
32
+ * Logic:
33
+ * - For glama/openrouter/litellm (shared env var providers):
34
+ * - If NO provider key exists → save to provider env var for reuse
35
+ * - If provider key EXISTS and user entered SAME key → don't save (uses fallback)
36
+ * - If provider key EXISTS and user entered DIFFERENT key → save as per-model override
37
+ * - For openai-compatible: always save as per-model (each endpoint needs own key)
38
+ *
39
+ * @param provider - The custom model provider
40
+ * @param userEnteredKey - The API key entered by user (trimmed, may be empty)
41
+ * @param providerHasKey - Whether the provider already has a key configured
42
+ * @param existingProviderKey - The existing provider key value (for comparison)
43
+ */
44
+ export declare function determineApiKeyStorage(provider: string, userEnteredKey: string | undefined, providerHasKey: boolean, existingProviderKey: string | undefined): ApiKeyStorageStrategy;
18
45
  //# sourceMappingURL=api-key-store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"api-key-store.d.ts","sourceRoot":"","sources":["../../src/utils/api-key-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAM/C;;;GAGG;AACH,wBAAsB,kBAAkB,CACpC,QAAQ,EAAE,WAAW,EACrB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,CAYpD;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,WAAW,GAAG;IACzD,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAClB,CAIA;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAAC,MAAM,EAAE;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAM9F"}
1
+ {"version":3,"file":"api-key-store.d.ts","sourceRoot":"","sources":["../../src/utils/api-key-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAM/C;;;GAGG;AACH,wBAAsB,kBAAkB,CACpC,QAAQ,EAAE,WAAW,EACrB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,CAYpD;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,WAAW,GAAG;IACzD,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAClB,CA4CA;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAAC,MAAM,EAAE;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAM9F;AAED;;;GAGG;AACH,eAAO,MAAM,wBAAwB,6CAA8C,CAAC;AAEpF,MAAM,MAAM,qBAAqB,GAAG;IAChC,6DAA6D;IAC7D,oBAAoB,EAAE,OAAO,CAAC;IAC9B,gEAAgE;IAChE,cAAc,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAClC,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,cAAc,EAAE,OAAO,EACvB,mBAAmB,EAAE,MAAM,GAAG,SAAS,GACxC,qBAAqB,CA2BvB"}
@@ -12,6 +12,27 @@ async function saveProviderApiKey(provider, apiKey, startPath) {
12
12
  return { envVar, targetEnvPath };
13
13
  }
14
14
  function getProviderKeyStatus(provider) {
15
+ if (provider === "vertex") {
16
+ const projectId = process.env.GOOGLE_VERTEX_PROJECT;
17
+ return {
18
+ hasApiKey: Boolean(projectId && projectId.trim()),
19
+ envVar: "GOOGLE_VERTEX_PROJECT"
20
+ };
21
+ }
22
+ if (provider === "bedrock") {
23
+ const apiKey = process.env.AWS_BEARER_TOKEN_BEDROCK;
24
+ if (apiKey && apiKey.trim()) {
25
+ return {
26
+ hasApiKey: true,
27
+ envVar: "AWS_BEARER_TOKEN_BEDROCK"
28
+ };
29
+ }
30
+ const region = process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION;
31
+ return {
32
+ hasApiKey: Boolean(region && region.trim()),
33
+ envVar: "AWS_REGION"
34
+ };
35
+ }
15
36
  const envVar = getPrimaryApiKeyEnvVar(provider);
16
37
  const key = resolveApiKeyForProvider(provider);
17
38
  return { hasApiKey: Boolean(key && key.trim()), envVar };
@@ -23,7 +44,30 @@ function listProviderKeyStatus() {
23
44
  }
24
45
  return result;
25
46
  }
47
+ const SHARED_API_KEY_PROVIDERS = ["glama", "openrouter", "litellm"];
48
+ function determineApiKeyStorage(provider, userEnteredKey, providerHasKey, existingProviderKey) {
49
+ const result = {
50
+ saveToProviderEnvVar: false,
51
+ saveAsPerModel: false
52
+ };
53
+ if (!userEnteredKey) {
54
+ return result;
55
+ }
56
+ const hasSharedEnvVarKey = SHARED_API_KEY_PROVIDERS.includes(provider);
57
+ if (hasSharedEnvVarKey) {
58
+ if (!providerHasKey) {
59
+ result.saveToProviderEnvVar = true;
60
+ } else if (existingProviderKey && userEnteredKey !== existingProviderKey) {
61
+ result.saveAsPerModel = true;
62
+ }
63
+ } else {
64
+ result.saveAsPerModel = true;
65
+ }
66
+ return result;
67
+ }
26
68
  export {
69
+ SHARED_API_KEY_PROVIDERS,
70
+ determineApiKeyStorage,
27
71
  getProviderKeyStatus,
28
72
  listProviderKeyStatus,
29
73
  saveProviderApiKey
@@ -33,84 +33,36 @@ __export(env_file_exports, {
33
33
  module.exports = __toCommonJS(env_file_exports);
34
34
  var path = __toESM(require("node:path"), 1);
35
35
  var import_node_fs = require("node:fs");
36
- const DEXTO_ENV_KEYS = [
37
- "OPENAI_API_KEY",
38
- "ANTHROPIC_API_KEY",
39
- "GOOGLE_GENERATIVE_AI_API_KEY",
40
- "GROQ_API_KEY",
41
- "COHERE_API_KEY",
42
- "XAI_API_KEY",
43
- "DEXTO_LOG_LEVEL"
44
- ];
45
- function isDextoEnvKey(value) {
46
- return DEXTO_ENV_KEYS.includes(value);
47
- }
48
36
  async function updateEnvFile(envFilePath, updates) {
49
37
  await import_node_fs.promises.mkdir(path.dirname(envFilePath), { recursive: true });
50
- let envLines = [];
38
+ let content = "";
51
39
  try {
52
- const existingEnv = await import_node_fs.promises.readFile(envFilePath, "utf8");
53
- envLines = existingEnv.split("\n");
40
+ content = await import_node_fs.promises.readFile(envFilePath, "utf8");
54
41
  } catch {
55
42
  }
56
- const currentValues = {};
57
- envLines.forEach((line) => {
58
- const match = line.match(/^([A-Z0-9_]+)=(.*)$/);
59
- if (match && match[1] && isDextoEnvKey(match[1])) {
60
- const value = match[2] ?? "";
61
- currentValues[match[1]] = value;
43
+ const lines = content.split("\n");
44
+ const updatedKeys = /* @__PURE__ */ new Set();
45
+ const updatedLines = lines.map((line) => {
46
+ const match = line.match(/^([A-Z_][A-Z0-9_]*)=(.*)$/);
47
+ if (match && match[1] && match[1] in updates) {
48
+ const key = match[1];
49
+ updatedKeys.add(key);
50
+ return `${key}=${updates[key]}`;
62
51
  }
52
+ return line;
63
53
  });
64
- const updatedValues = Object.fromEntries(
65
- DEXTO_ENV_KEYS.map((key) => {
66
- const update = updates[key];
67
- const current = currentValues[key];
68
- const fallback = key === "DEXTO_LOG_LEVEL" ? "info" : "";
69
- const value = update !== void 0 ? update : current ?? fallback;
70
- return [key, value];
71
- })
72
- );
73
- const sectionHeader = "## Dexto env variables";
74
- const headerIndex = envLines.findIndex((line) => line.trim() === sectionHeader);
75
- let contentLines;
76
- if (headerIndex !== -1) {
77
- const beforeSection = envLines.slice(0, headerIndex);
78
- let sectionEnd = headerIndex + 1;
79
- while (sectionEnd < envLines.length && envLines[sectionEnd]?.trim() !== "") {
80
- sectionEnd++;
81
- }
82
- if (sectionEnd < envLines.length && envLines[sectionEnd]?.trim() === "") {
83
- sectionEnd++;
54
+ for (const [key, value] of Object.entries(updates)) {
55
+ if (!updatedKeys.has(key)) {
56
+ if (updatedLines.length > 0 && updatedLines[updatedLines.length - 1] !== "") {
57
+ updatedLines.push("");
58
+ }
59
+ updatedLines.push(`${key}=${value}`);
84
60
  }
85
- const afterSection = envLines.slice(sectionEnd);
86
- contentLines = [...beforeSection, ...afterSection];
87
- } else {
88
- contentLines = envLines;
89
61
  }
90
- const existingEnvVars = {};
91
- contentLines.forEach((line) => {
92
- const match = line.match(/^([A-Z0-9_]+)=(.*)$/);
93
- if (match && match[1] && isDextoEnvKey(match[1])) {
94
- const value = match[2] ?? "";
95
- existingEnvVars[match[1]] = value;
96
- }
97
- });
98
- if (contentLines.length > 0) {
99
- if (contentLines[contentLines.length - 1]?.trim() !== "") {
100
- contentLines.push("");
101
- }
102
- } else {
103
- contentLines.push("");
104
- }
105
- contentLines.push(sectionHeader);
106
- for (const key of DEXTO_ENV_KEYS) {
107
- if (key in existingEnvVars && !(key in updates)) {
108
- continue;
109
- }
110
- contentLines.push(`${key}=${updatedValues[key]}`);
62
+ if (updatedLines[updatedLines.length - 1] !== "") {
63
+ updatedLines.push("");
111
64
  }
112
- contentLines.push("");
113
- await import_node_fs.promises.writeFile(envFilePath, contentLines.join("\n"), "utf8");
65
+ await import_node_fs.promises.writeFile(envFilePath, updatedLines.join("\n"), "utf8");
114
66
  }
115
67
  // Annotate the CommonJS export names for ESM import in node:
116
68
  0 && (module.exports = {
@@ -1,5 +1,6 @@
1
1
  /**
2
- * Update a .env file with Dexto environment variables, ensuring our section stays consistent.
2
+ * Update a .env file with the provided key-value pairs.
3
+ * Existing keys are updated in place, new keys are appended.
3
4
  */
4
5
  export declare function updateEnvFile(envFilePath: string, updates: Record<string, string>): Promise<void>;
5
6
  //# sourceMappingURL=env-file.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"env-file.d.ts","sourceRoot":"","sources":["../../src/utils/env-file.ts"],"names":[],"mappings":"AAsBA;;GAEG;AACH,wBAAsB,aAAa,CAC/B,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,OAAO,CAAC,IAAI,CAAC,CAgFf"}
1
+ {"version":3,"file":"env-file.d.ts","sourceRoot":"","sources":["../../src/utils/env-file.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAsB,aAAa,CAC/B,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,OAAO,CAAC,IAAI,CAAC,CAyCf"}