@di-code/coding-agent 0.1.4 → 0.1.6

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 (111) hide show
  1. package/README.md +74 -23
  2. package/dist/cli.d.ts +15 -0
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +96 -17
  5. package/dist/cli.js.map +1 -1
  6. package/dist/core/clipboard-image.d.ts +3 -3
  7. package/dist/core/clipboard-image.d.ts.map +1 -1
  8. package/dist/core/clipboard-image.js +26 -13
  9. package/dist/core/clipboard-image.js.map +1 -1
  10. package/dist/core/resources/loader.d.ts.map +1 -1
  11. package/dist/core/resources/loader.js +15 -42
  12. package/dist/core/resources/loader.js.map +1 -1
  13. package/dist/core/resources/types.d.ts +6 -9
  14. package/dist/core/resources/types.d.ts.map +1 -1
  15. package/dist/core/resources/types.js.map +1 -1
  16. package/dist/core/session/session-manager.d.ts +12 -1
  17. package/dist/core/session/session-manager.d.ts.map +1 -1
  18. package/dist/core/session/session-manager.js +66 -3
  19. package/dist/core/session/session-manager.js.map +1 -1
  20. package/dist/core/session/session-storage.d.ts.map +1 -1
  21. package/dist/core/session/session-storage.js +29 -15
  22. package/dist/core/session/session-storage.js.map +1 -1
  23. package/dist/core/session/types.d.ts +6 -1
  24. package/dist/core/session/types.d.ts.map +1 -1
  25. package/dist/core/session/types.js +1 -1
  26. package/dist/core/session/types.js.map +1 -1
  27. package/dist/core/session.d.ts +21 -1
  28. package/dist/core/session.d.ts.map +1 -1
  29. package/dist/core/session.js +81 -12
  30. package/dist/core/session.js.map +1 -1
  31. package/dist/core/system-prompt.js +2 -2
  32. package/dist/core/system-prompt.js.map +1 -1
  33. package/dist/core/tools/file-search.d.ts +14 -0
  34. package/dist/core/tools/file-search.d.ts.map +1 -0
  35. package/dist/core/tools/file-search.js +99 -0
  36. package/dist/core/tools/file-search.js.map +1 -0
  37. package/dist/core/tools/glob.d.ts +11 -0
  38. package/dist/core/tools/glob.d.ts.map +1 -0
  39. package/dist/core/tools/glob.js +44 -0
  40. package/dist/core/tools/glob.js.map +1 -0
  41. package/dist/core/tools/grep.d.ts +13 -0
  42. package/dist/core/tools/grep.d.ts.map +1 -0
  43. package/dist/core/tools/grep.js +67 -0
  44. package/dist/core/tools/grep.js.map +1 -0
  45. package/dist/core/tools/load-skill.d.ts +10 -0
  46. package/dist/core/tools/load-skill.d.ts.map +1 -0
  47. package/dist/core/tools/load-skill.js +22 -0
  48. package/dist/core/tools/load-skill.js.map +1 -0
  49. package/dist/core/tools/path-boundary.d.ts +2 -0
  50. package/dist/core/tools/path-boundary.d.ts.map +1 -1
  51. package/dist/core/tools/path-boundary.js +4 -0
  52. package/dist/core/tools/path-boundary.js.map +1 -1
  53. package/dist/core/user-data.d.ts +3 -0
  54. package/dist/core/user-data.d.ts.map +1 -0
  55. package/dist/core/user-data.js +8 -0
  56. package/dist/core/user-data.js.map +1 -0
  57. package/dist/entry.js +13 -0
  58. package/dist/entry.js.map +1 -1
  59. package/dist/extensions/runtime.js +2 -2
  60. package/dist/extensions/runtime.js.map +1 -1
  61. package/dist/i18n.d.ts +5 -0
  62. package/dist/i18n.d.ts.map +1 -0
  63. package/dist/i18n.js +223 -0
  64. package/dist/i18n.js.map +1 -0
  65. package/dist/index.d.ts +3 -0
  66. package/dist/index.d.ts.map +1 -1
  67. package/dist/index.js +3 -0
  68. package/dist/index.js.map +1 -1
  69. package/dist/main.d.ts +17 -0
  70. package/dist/main.d.ts.map +1 -1
  71. package/dist/main.js +238 -11
  72. package/dist/main.js.map +1 -1
  73. package/dist/mcp/config.d.ts +33 -0
  74. package/dist/mcp/config.d.ts.map +1 -0
  75. package/dist/mcp/config.js +211 -0
  76. package/dist/mcp/config.js.map +1 -0
  77. package/dist/mcp/loader.d.ts +21 -0
  78. package/dist/mcp/loader.d.ts.map +1 -0
  79. package/dist/mcp/loader.js +60 -0
  80. package/dist/mcp/loader.js.map +1 -0
  81. package/dist/mcp/tool-adapter.d.ts +5 -0
  82. package/dist/mcp/tool-adapter.d.ts.map +1 -0
  83. package/dist/mcp/tool-adapter.js +149 -0
  84. package/dist/mcp/tool-adapter.js.map +1 -0
  85. package/dist/modes/interactive-components.d.ts +2 -2
  86. package/dist/modes/interactive-components.d.ts.map +1 -1
  87. package/dist/modes/interactive-components.js +30 -33
  88. package/dist/modes/interactive-components.js.map +1 -1
  89. package/dist/modes/interactive-state.d.ts.map +1 -1
  90. package/dist/modes/interactive-state.js +1 -0
  91. package/dist/modes/interactive-state.js.map +1 -1
  92. package/dist/modes/interactive.d.ts +9 -0
  93. package/dist/modes/interactive.d.ts.map +1 -1
  94. package/dist/modes/interactive.js +191 -62
  95. package/dist/modes/interactive.js.map +1 -1
  96. package/dist/modes/tree-selector.d.ts +30 -0
  97. package/dist/modes/tree-selector.d.ts.map +1 -0
  98. package/dist/modes/tree-selector.js +205 -0
  99. package/dist/modes/tree-selector.js.map +1 -0
  100. package/dist/plugins/loader.d.ts +19 -1
  101. package/dist/plugins/loader.d.ts.map +1 -1
  102. package/dist/plugins/loader.js +21 -2
  103. package/dist/plugins/loader.js.map +1 -1
  104. package/dist/provider-onboarding.d.ts.map +1 -1
  105. package/dist/provider-onboarding.js +119 -22
  106. package/dist/provider-onboarding.js.map +1 -1
  107. package/dist/startup.d.ts +24 -1
  108. package/dist/startup.d.ts.map +1 -1
  109. package/dist/startup.js +200 -9
  110. package/dist/startup.js.map +1 -1
  111. package/package.json +6 -4
package/dist/startup.js CHANGED
@@ -1,7 +1,8 @@
1
1
  import { mkdir, readFile, writeFile } from "node:fs/promises";
2
2
  import { homedir } from "node:os";
3
3
  import { join } from "node:path";
4
- import { createAnthropicProvider, createDeepSeekProvider, createFauxProvider, createOpenAIChatCompletionsProvider, createOpenAIProvider, createZhipuProvider, } from "@di-code/ai";
4
+ import { createAnthropicProvider, createDeepSeekProvider, createFauxProvider, createKimiProvider, createOpenAIChatCompletionsProvider, createOpenAIProvider, createZhipuProvider, findBuiltinModel, } from "@di-code/ai";
5
+ import { isLocale } from "./i18n.js";
5
6
  const FAUX_RESPONSES = [
6
7
  {
7
8
  type: "success",
@@ -46,6 +47,43 @@ function nonNegativeNumber(value, path, fallback, settingsPath) {
46
47
  }
47
48
  return result;
48
49
  }
50
+ function parseChatCompletionsCompat(value, path, settingsPath) {
51
+ if (value === undefined)
52
+ return undefined;
53
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
54
+ throw new Error(`${settingsPath}: ${path} must be an object`);
55
+ }
56
+ const compat = value;
57
+ const optionalBoolean = (field) => {
58
+ const candidate = compat[field];
59
+ if (candidate === undefined)
60
+ return undefined;
61
+ if (typeof candidate !== "boolean")
62
+ throw new Error(`${settingsPath}: ${path}.${field} must be a boolean`);
63
+ return candidate;
64
+ };
65
+ const maxTokensField = compat.maxTokensField;
66
+ if (maxTokensField !== undefined && maxTokensField !== "max_tokens" && maxTokensField !== "max_completion_tokens") {
67
+ throw new Error(`${settingsPath}: ${path}.maxTokensField is invalid`);
68
+ }
69
+ const thinkingFormat = compat.thinkingFormat;
70
+ if (thinkingFormat !== undefined &&
71
+ thinkingFormat !== "zai" &&
72
+ thinkingFormat !== "deepseek" &&
73
+ thinkingFormat !== "kimi") {
74
+ throw new Error(`${settingsPath}: ${path}.thinkingFormat is invalid`);
75
+ }
76
+ const supportsUsageInStreaming = optionalBoolean("supportsUsageInStreaming");
77
+ const supportsReasoningEffort = optionalBoolean("supportsReasoningEffort");
78
+ const zaiToolStream = optionalBoolean("zaiToolStream");
79
+ return {
80
+ ...(maxTokensField === undefined ? {} : { maxTokensField }),
81
+ ...(thinkingFormat === undefined ? {} : { thinkingFormat }),
82
+ ...(supportsUsageInStreaming === undefined ? {} : { supportsUsageInStreaming }),
83
+ ...(supportsReasoningEffort === undefined ? {} : { supportsReasoningEffort }),
84
+ ...(zaiToolStream === undefined ? {} : { zaiToolStream }),
85
+ };
86
+ }
49
87
  function parseModels(value, path, providerId, providerApi, providerBaseUrl, settingsPath) {
50
88
  if (value === undefined)
51
89
  return undefined;
@@ -75,9 +113,9 @@ function parseModels(value, path, providerId, providerApi, providerBaseUrl, sett
75
113
  throw new Error(`${settingsPath}: ${modelPath}.reasoningEfforts must be a non-empty array`);
76
114
  }
77
115
  if (model.reasoning !== true ||
78
- configuredReasoningEfforts.some((effort) => effort !== "low" && effort !== "medium" && effort !== "high") ||
116
+ configuredReasoningEfforts.some((effort) => effort !== "low" && effort !== "medium" && effort !== "high" && effort !== "max") ||
79
117
  new Set(configuredReasoningEfforts).size !== configuredReasoningEfforts.length) {
80
- throw new Error(`${settingsPath}: ${modelPath}.reasoningEfforts requires reasoning=true and unique low, medium, or high values`);
118
+ throw new Error(`${settingsPath}: ${modelPath}.reasoningEfforts requires reasoning=true and unique low, medium, high, or max values`);
81
119
  }
82
120
  }
83
121
  if (model.cacheRetention !== undefined && model.cacheRetention !== "long") {
@@ -100,6 +138,10 @@ function parseModels(value, path, providerId, providerApi, providerBaseUrl, sett
100
138
  : [...configuredReasoningEfforts];
101
139
  const baseUrl = optionalString(model.baseUrl, `${modelPath}.baseUrl`, settingsPath) ?? providerBaseUrl;
102
140
  const id = requiredString(model.id, `${modelPath}.id`, settingsPath);
141
+ const chatCompletionsCompat = parseChatCompletionsCompat(model.chatCompletionsCompat, `${modelPath}.chatCompletionsCompat`, settingsPath);
142
+ if (chatCompletionsCompat !== undefined && typedApi !== "openai-chat-completions") {
143
+ throw new Error(`${settingsPath}: ${modelPath}.chatCompletionsCompat requires api "openai-chat-completions"`);
144
+ }
103
145
  return {
104
146
  id,
105
147
  name: requiredString(model.name ?? id, `${modelPath}.name`, settingsPath),
@@ -109,6 +151,7 @@ function parseModels(value, path, providerId, providerApi, providerBaseUrl, sett
109
151
  input: [...input],
110
152
  reasoning: model.reasoning ?? false,
111
153
  ...(reasoningEfforts ? { reasoningEfforts } : {}),
154
+ ...(chatCompletionsCompat ? { chatCompletionsCompat } : {}),
112
155
  ...(model.cacheRetention === "long" ? { cacheRetention: "long" } : {}),
113
156
  ...(model.sessionAffinity === "codex" ? { sessionAffinity: "codex" } : {}),
114
157
  contextWindow: positiveInteger(model.contextWindow, `${modelPath}.contextWindow`, 128_000, settingsPath),
@@ -122,6 +165,76 @@ function parseModels(value, path, providerId, providerApi, providerBaseUrl, sett
122
165
  };
123
166
  });
124
167
  }
168
+ /** Validates a Custom onboarding endpoint without issuing a network request. */
169
+ export function validateCustomBaseUrl(value) {
170
+ const baseUrl = value.trim();
171
+ if (!baseUrl)
172
+ throw new Error("Base URL cannot be empty.");
173
+ let url;
174
+ try {
175
+ url = new URL(baseUrl);
176
+ }
177
+ catch {
178
+ throw new Error("Base URL must be an absolute http or https URL.");
179
+ }
180
+ if (url.protocol !== "http:" && url.protocol !== "https:")
181
+ throw new Error("Base URL must use http or https.");
182
+ if (url.username || url.password || url.search || url.hash) {
183
+ throw new Error("Base URL must not contain credentials, query, or hash.");
184
+ }
185
+ if (baseUrl.endsWith("/"))
186
+ throw new Error("Base URL must not end with /.");
187
+ return baseUrl;
188
+ }
189
+ function requireCustomValue(value, field) {
190
+ const trimmed = value.trim();
191
+ if (!trimmed)
192
+ throw new Error(`${field === "apiKey" ? "API key" : "Model ID"} cannot be empty.`);
193
+ return trimmed;
194
+ }
195
+ /** Builds the single user-managed Custom provider from validated onboarding input. */
196
+ export function createCustomProviderConfiguration(input) {
197
+ const baseUrl = validateCustomBaseUrl(input.baseUrl);
198
+ const modelId = requireCustomValue(input.modelId, "modelId");
199
+ const apiKey = requireCustomValue(input.apiKey, "apiKey");
200
+ const known = findBuiltinModel(input.api, modelId);
201
+ const model = known
202
+ ? {
203
+ ...known,
204
+ id: modelId,
205
+ provider: "custom",
206
+ api: input.api,
207
+ baseUrl,
208
+ }
209
+ : {
210
+ id: modelId,
211
+ name: modelId,
212
+ provider: "custom",
213
+ api: input.api,
214
+ baseUrl,
215
+ input: ["text"],
216
+ reasoning: false,
217
+ contextWindow: 128_000,
218
+ maxOutputTokens: 16_384,
219
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
220
+ };
221
+ return { id: "custom", name: "Custom", api: input.api, apiKey, baseUrl, models: [model] };
222
+ }
223
+ function serializeModel(model) {
224
+ return {
225
+ id: model.id,
226
+ name: model.name,
227
+ input: model.input,
228
+ reasoning: model.reasoning,
229
+ ...(model.reasoningEfforts ? { reasoningEfforts: model.reasoningEfforts } : {}),
230
+ ...(model.chatCompletionsCompat ? { chatCompletionsCompat: model.chatCompletionsCompat } : {}),
231
+ ...(model.cacheRetention ? { cacheRetention: model.cacheRetention } : {}),
232
+ ...(model.sessionAffinity ? { sessionAffinity: model.sessionAffinity } : {}),
233
+ contextWindow: model.contextWindow,
234
+ maxTokens: model.maxOutputTokens,
235
+ cost: Object.fromEntries(Object.entries(model.cost).map(([key, value]) => [key, value * 1_000_000])),
236
+ };
237
+ }
125
238
  function parseSettings(value, settingsPath) {
126
239
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
127
240
  throw new Error(`${settingsPath}: root value must be an object`);
@@ -149,10 +262,14 @@ function parseSettings(value, settingsPath) {
149
262
  ? undefined
150
263
  : requiredString(record.defaultProvider, "defaultProvider", settingsPath);
151
264
  const defaultModel = record.defaultModel === undefined ? undefined : requiredString(record.defaultModel, "defaultModel", settingsPath);
265
+ if (record.locale !== undefined && !isLocale(record.locale)) {
266
+ throw new Error(`${settingsPath}: locale must be "en" or "zh-CN"`);
267
+ }
152
268
  return {
153
269
  providers,
154
270
  ...(defaultProvider === undefined ? {} : { defaultProvider }),
155
271
  ...(defaultModel === undefined ? {} : { defaultModel }),
272
+ ...(record.locale === undefined ? {} : { locale: record.locale }),
156
273
  };
157
274
  }
158
275
  async function readSettingsFile(path, displayPath) {
@@ -187,12 +304,27 @@ function mergeSettings(globalSettings, projectSettings) {
187
304
  const defaultProvider = projectSettings?.defaultProvider ?? globalSettings?.defaultProvider;
188
305
  const defaultModel = projectSettings?.defaultModel ??
189
306
  (projectSettings?.defaultProvider === undefined ? globalSettings?.defaultModel : undefined);
307
+ const locale = globalSettings?.locale;
190
308
  return {
191
309
  providers,
192
310
  ...(defaultProvider === undefined ? {} : { defaultProvider }),
193
311
  ...(defaultModel === undefined ? {} : { defaultModel }),
312
+ ...(locale === undefined ? {} : { locale }),
194
313
  };
195
314
  }
315
+ /** Persists a user-level terminal language preference without changing project settings. */
316
+ export async function saveGlobalLocale(agentDir, locale) {
317
+ const settingsFilePath = join(agentDir, SETTINGS_FILE_NAME);
318
+ const existingSettings = await readSettingsFile(settingsFilePath, settingsFilePath);
319
+ const settings = {
320
+ providers: existingSettings?.providers ?? {},
321
+ ...(existingSettings?.defaultProvider === undefined ? {} : { defaultProvider: existingSettings.defaultProvider }),
322
+ ...(existingSettings?.defaultModel === undefined ? {} : { defaultModel: existingSettings.defaultModel }),
323
+ locale,
324
+ };
325
+ await mkdir(agentDir, { recursive: true, mode: 0o700 });
326
+ await writeFile(settingsFilePath, `${JSON.stringify(settings, null, "\t")}\n`, { encoding: "utf8", mode: 0o600 });
327
+ }
196
328
  export async function saveGlobalProviderApiKey(agentDir, providerId, api, apiKey, modelId) {
197
329
  const settingsFilePath = join(agentDir, SETTINGS_FILE_NAME);
198
330
  const trimmedApiKey = apiKey.trim();
@@ -207,7 +339,36 @@ export async function saveGlobalProviderApiKey(agentDir, providerId, api, apiKey
207
339
  await mkdir(agentDir, { recursive: true, mode: 0o700 });
208
340
  await writeFile(settingsFilePath, `${JSON.stringify(settings, null, "\t")}\n`, { encoding: "utf8", mode: 0o600 });
209
341
  }
210
- /** Removes only the persisted credential for one provider; environment variables remain untouched. */
342
+ /**
343
+ * Replaces the user-managed `custom` provider while retaining other global
344
+ * providers and preferences. The key is intentionally stored only here, never
345
+ * in project settings or process environment.
346
+ */
347
+ export async function saveGlobalCustomProvider(agentDir, input) {
348
+ const configuration = createCustomProviderConfiguration(input);
349
+ const settingsFilePath = join(agentDir, SETTINGS_FILE_NAME);
350
+ const existingSettings = await readSettingsFile(settingsFilePath, settingsFilePath);
351
+ const settings = mergeSettings(existingSettings, {
352
+ providers: {
353
+ custom: {
354
+ name: configuration.name,
355
+ api: configuration.api,
356
+ baseUrl: configuration.baseUrl,
357
+ apiKey: configuration.apiKey,
358
+ models: configuration.models?.map(serializeModel),
359
+ },
360
+ },
361
+ defaultProvider: "custom",
362
+ defaultModel: configuration.models?.[0]?.id,
363
+ });
364
+ await mkdir(agentDir, { recursive: true, mode: 0o700 });
365
+ await writeFile(settingsFilePath, `${JSON.stringify(settings, null, "\t")}\n`, { encoding: "utf8", mode: 0o600 });
366
+ return configuration;
367
+ }
368
+ /**
369
+ * Removes one persisted credential and clears it as the default when applicable.
370
+ * Environment variables and other Provider configuration remain untouched.
371
+ */
211
372
  export async function removeGlobalProviderApiKey(agentDir, providerId) {
212
373
  const settingsFilePath = join(agentDir, SETTINGS_FILE_NAME);
213
374
  const existingSettings = await readSettingsFile(settingsFilePath, settingsFilePath);
@@ -215,12 +376,19 @@ export async function removeGlobalProviderApiKey(agentDir, providerId) {
215
376
  if (!provider || provider.apiKey === undefined)
216
377
  return false;
217
378
  const { apiKey: _apiKey, ...providerWithoutApiKey } = provider;
379
+ const clearsDefault = existingSettings.defaultProvider === providerId;
218
380
  const settings = {
219
- ...existingSettings,
220
381
  providers: {
221
382
  ...existingSettings.providers,
222
383
  [providerId]: providerWithoutApiKey,
223
384
  },
385
+ ...(clearsDefault || existingSettings.defaultProvider === undefined
386
+ ? {}
387
+ : { defaultProvider: existingSettings.defaultProvider }),
388
+ ...(clearsDefault || existingSettings.defaultModel === undefined
389
+ ? {}
390
+ : { defaultModel: existingSettings.defaultModel }),
391
+ ...(existingSettings.locale === undefined ? {} : { locale: existingSettings.locale }),
224
392
  };
225
393
  await writeFile(settingsFilePath, `${JSON.stringify(settings, null, "\t")}\n`, { encoding: "utf8", mode: 0o600 });
226
394
  return true;
@@ -254,7 +422,9 @@ function selectProviderModel(provider, providerId, env) {
254
422
  ? provider.models.find((candidate) => candidate.id === "gpt-4o")?.id
255
423
  : providerId === "zhipu"
256
424
  ? provider.models.find((candidate) => candidate.id === "glm-5.3")?.id
257
- : undefined) ||
425
+ : providerId === "kimi"
426
+ ? provider.models.find((candidate) => candidate.id === "k3")?.id
427
+ : undefined) ||
258
428
  provider.models[0]?.id;
259
429
  if (!modelId)
260
430
  throw new Error("DI_CODE_MODEL is required when the selected provider has no models");
@@ -282,6 +452,10 @@ function createBuiltInRuntime(env, providerId) {
282
452
  const provider = createZhipuProvider({ env });
283
453
  return { provider, model: selectProviderModel(provider, providerId, env) };
284
454
  }
455
+ if (providerId === "kimi") {
456
+ const provider = createKimiProvider({ env });
457
+ return { provider, model: selectProviderModel(provider, providerId, env) };
458
+ }
285
459
  return undefined;
286
460
  }
287
461
  function createConfiguredRuntime(env, configuration) {
@@ -293,13 +467,14 @@ function createConfiguredRuntime(env, configuration) {
293
467
  if (configuration.id !== "openai" &&
294
468
  configuration.id !== "deepseek" &&
295
469
  configuration.id !== "zhipu" &&
470
+ configuration.id !== "kimi" &&
296
471
  configuration.id !== "anthropic" &&
297
472
  !configuration.models) {
298
473
  throw new Error(`${SETTINGS_PATH}: providers.${configuration.id}.models is required for a custom provider`);
299
474
  }
300
475
  const provider = configuration.api === "openai-chat-completions"
301
476
  ? createOpenAIChatCompletionsProvider({
302
- env: configuration.id === "zhipu" || configuration.id === "deepseek"
477
+ env: configuration.id === "zhipu" || configuration.id === "deepseek" || configuration.id === "kimi"
303
478
  ? env
304
479
  : Object.fromEntries(Object.entries(env).filter(([name]) => name !== "OPENAI_API_KEY" && name !== "OPENAI_BASE_URL")),
305
480
  models: configuration.models,
@@ -319,7 +494,13 @@ function createConfiguredRuntime(env, configuration) {
319
494
  baseUrlEnvironmentVariable: "DEEPSEEK_BASE_URL",
320
495
  defaultBaseUrl: "https://api.deepseek.com",
321
496
  }
322
- : {}),
497
+ : configuration.id === "kimi"
498
+ ? {
499
+ apiKeyEnvironmentVariable: "KIMI_API_KEY",
500
+ baseUrlEnvironmentVariable: "KIMI_BASE_URL",
501
+ defaultBaseUrl: "https://api.kimi.com/coding/v1",
502
+ }
503
+ : {}),
323
504
  })
324
505
  : configuration.api === "anthropic-messages"
325
506
  ? createAnthropicProvider({
@@ -386,6 +567,10 @@ export async function loadStartupConfiguration(cwd, environment = process.env, a
386
567
  readSettingsFile(join(cwd, SETTINGS_PATH), SETTINGS_PATH),
387
568
  ]);
388
569
  const settings = mergeSettings(globalSettings, projectSettings);
570
+ const requestedLocale = environment.DI_CODE_LOCALE?.trim();
571
+ if (requestedLocale !== undefined && requestedLocale !== "" && !isLocale(requestedLocale)) {
572
+ throw new Error('DI_CODE_LOCALE must be "en" or "zh-CN".');
573
+ }
389
574
  const providers = Object.entries(settings.providers).map(([id, provider]) => ({
390
575
  id: requiredString(id, `providers.${id}`),
391
576
  name: provider.name,
@@ -397,7 +582,13 @@ export async function loadStartupConfiguration(cwd, environment = process.env, a
397
582
  const defaults = settings.defaultProvider === undefined && settings.defaultModel === undefined
398
583
  ? undefined
399
584
  : { providerId: settings.defaultProvider, modelId: settings.defaultModel };
400
- return { environment, providers, ...(defaults === undefined ? {} : { defaults }) };
585
+ const locale = requestedLocale && isLocale(requestedLocale) ? requestedLocale : settings.locale;
586
+ return {
587
+ environment,
588
+ providers,
589
+ ...(locale === undefined ? {} : { locale }),
590
+ ...(defaults === undefined ? {} : { defaults }),
591
+ };
401
592
  }
402
593
  export async function loadStartupEnvironment(cwd, environment = process.env) {
403
594
  return (await loadStartupConfiguration(cwd, environment)).environment;
@@ -1 +1 @@
1
- {"version":3,"file":"startup.js","sourceRoot":"","sources":["../src/startup.ts"],"names":[],"mappings":"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","sourcesContent":["import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport {\n\tcreateAnthropicProvider,\n\tcreateDeepSeekProvider,\n\tcreateFauxProvider,\n\tcreateOpenAIChatCompletionsProvider,\n\tcreateOpenAIProvider,\n\tcreateZhipuProvider,\n\ttype FauxResponse,\n\ttype Model,\n\ttype ModelApi,\n\ttype Provider,\n} from \"@di-code/ai\";\n\nexport interface StartupRuntime {\n\treadonly provider: Provider;\n\treadonly model: Model;\n}\n\nexport interface StartupProviderConfiguration {\n\treadonly id: string;\n\treadonly name?: string;\n\treadonly api?: string;\n\treadonly apiKey?: string;\n\treadonly baseUrl?: string;\n\treadonly models?: readonly Model[];\n}\n\nexport interface StartupConfiguration {\n\treadonly environment: Environment;\n\treadonly providers: readonly StartupProviderConfiguration[];\n\treadonly defaults?: StartupDefaults;\n}\n\nexport interface StartupDefaults {\n\treadonly providerId?: string;\n\treadonly modelId?: string;\n}\n\nconst FAUX_RESPONSES: readonly FauxResponse[] = [\n\t{\n\t\ttype: \"success\",\n\t\tcontent: [\n\t\t\t{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: \"你好,我是di-code,一个面向终端的 TypeScript AI Coding Agent,支持多 Provider 流式对话、工具调用、JSONL 会话持久化、交互式 TUI、插件扩展与 JSONL RPC 集成。\",\n\t\t\t},\n\t\t],\n\t},\n\t{ type: \"success\", content: [{ type: \"text\", text: \"当前回复为faux数据\" }] },\n];\n\nconst SETTINGS_FILE_NAME = \"settings.json\";\nconst SETTINGS_PATH = join(\".di-code\", SETTINGS_FILE_NAME);\n\ntype Environment = Readonly<Record<string, string | undefined>>;\n\ninterface SettingsFile {\n\treadonly defaultProvider?: string;\n\treadonly defaultModel?: string;\n\treadonly providers: Record<\n\t\tstring,\n\t\t{\n\t\t\treadonly name?: string;\n\t\t\treadonly baseUrl?: string;\n\t\t\treadonly apiKey?: string;\n\t\t\treadonly api?: string;\n\t\t\treadonly models?: unknown;\n\t\t}\n\t>;\n}\n\nexport function resolveStartupArgs(args: readonly string[]): readonly string[] {\n\treturn args.length === 0 ? [\"--interactive\"] : args;\n}\n\nfunction optionalString(value: unknown, path: string, settingsPath: string): string | undefined {\n\tif (value === undefined) return undefined;\n\tif (typeof value !== \"string\") throw new Error(`${settingsPath}: ${path} must be a string`);\n\treturn value;\n}\n\nfunction requiredString(value: unknown, path: string, settingsPath = SETTINGS_PATH): string {\n\tconst result = optionalString(value, path, settingsPath);\n\tif (!result?.trim()) throw new Error(`${settingsPath}: ${path} must be a non-empty string`);\n\treturn result.trim();\n}\n\nfunction positiveInteger(value: unknown, path: string, fallback: number, settingsPath: string): number {\n\tconst result = value ?? fallback;\n\tif (!Number.isInteger(result) || (result as number) <= 0) {\n\t\tthrow new Error(`${settingsPath}: ${path} must be a positive integer`);\n\t}\n\treturn result as number;\n}\n\nfunction nonNegativeNumber(value: unknown, path: string, fallback: number, settingsPath: string): number {\n\tconst result = value ?? fallback;\n\tif (typeof result !== \"number\" || !Number.isFinite(result) || result < 0) {\n\t\tthrow new Error(`${settingsPath}: ${path} must be a non-negative finite number`);\n\t}\n\treturn result;\n}\n\nfunction parseModels(\n\tvalue: unknown,\n\tpath: string,\n\tproviderId: string,\n\tproviderApi: string | undefined,\n\tproviderBaseUrl: string | undefined,\n\tsettingsPath: string,\n): readonly Model[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) throw new Error(`${settingsPath}: ${path} must be an array`);\n\n\treturn value.map((entry, index) => {\n\t\tconst modelPath = `${path}[${index}]`;\n\t\tif (typeof entry !== \"object\" || entry === null || Array.isArray(entry)) {\n\t\t\tthrow new Error(`${settingsPath}: ${modelPath} must be an object`);\n\t\t}\n\t\tconst model = entry as Record<string, unknown>;\n\t\tconst input = model.input ?? [\"text\"];\n\t\tif (!Array.isArray(input) || input.length === 0 || input.some((item) => item !== \"text\" && item !== \"image\")) {\n\t\t\tthrow new Error(`${settingsPath}: ${modelPath}.input must contain text and/or image`);\n\t\t}\n\t\tconst cost = model.cost ?? {};\n\t\tif (typeof cost !== \"object\" || cost === null || Array.isArray(cost)) {\n\t\t\tthrow new Error(`${settingsPath}: ${modelPath}.cost must be an object`);\n\t\t}\n\t\tconst prices = cost as Record<string, unknown>;\n\t\tif (model.reasoning !== undefined && typeof model.reasoning !== \"boolean\") {\n\t\t\tthrow new Error(`${settingsPath}: ${modelPath}.reasoning must be a boolean`);\n\t\t}\n\t\tconst configuredReasoningEfforts = model.reasoningEfforts;\n\t\tif (configuredReasoningEfforts !== undefined) {\n\t\t\tif (!Array.isArray(configuredReasoningEfforts) || configuredReasoningEfforts.length === 0) {\n\t\t\t\tthrow new Error(`${settingsPath}: ${modelPath}.reasoningEfforts must be a non-empty array`);\n\t\t\t}\n\t\t\tif (\n\t\t\t\tmodel.reasoning !== true ||\n\t\t\t\tconfiguredReasoningEfforts.some((effort) => effort !== \"low\" && effort !== \"medium\" && effort !== \"high\") ||\n\t\t\t\tnew Set(configuredReasoningEfforts).size !== configuredReasoningEfforts.length\n\t\t\t) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`${settingsPath}: ${modelPath}.reasoningEfforts requires reasoning=true and unique low, medium, or high values`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tif (model.cacheRetention !== undefined && model.cacheRetention !== \"long\") {\n\t\t\tthrow new Error(`${settingsPath}: ${modelPath}.cacheRetention must be \"long\" when provided`);\n\t\t}\n\t\tif (model.sessionAffinity !== undefined && model.sessionAffinity !== \"codex\") {\n\t\t\tthrow new Error(`${settingsPath}: ${modelPath}.sessionAffinity must be \"codex\" when provided`);\n\t\t}\n\t\tconst api = optionalString(model.api, `${modelPath}.api`, settingsPath) ?? providerApi;\n\t\tif (!api) throw new Error(`${settingsPath}: ${modelPath}.api is required`);\n\t\tif (![\"faux\", \"openai-responses\", \"openai-chat-completions\", \"anthropic-messages\"].includes(api)) {\n\t\t\tthrow new Error(`${settingsPath}: ${modelPath}.api is unsupported`);\n\t\t}\n\t\tconst typedApi = api as ModelApi;\n\t\tconst reasoningEfforts: Model[\"reasoningEfforts\"] =\n\t\t\tconfiguredReasoningEfforts === undefined && model.reasoning === true && api === \"openai-responses\"\n\t\t\t\t? [\"low\", \"medium\", \"high\"]\n\t\t\t\t: configuredReasoningEfforts === undefined\n\t\t\t\t\t? undefined\n\t\t\t\t\t: ([...configuredReasoningEfforts] as Model[\"reasoningEfforts\"]);\n\t\tconst baseUrl = optionalString(model.baseUrl, `${modelPath}.baseUrl`, settingsPath) ?? providerBaseUrl;\n\t\tconst id = requiredString(model.id, `${modelPath}.id`, settingsPath);\n\t\treturn {\n\t\t\tid,\n\t\t\tname: requiredString(model.name ?? id, `${modelPath}.name`, settingsPath),\n\t\t\tprovider: providerId,\n\t\t\tapi: typedApi,\n\t\t\t...(baseUrl === undefined ? {} : { baseUrl }),\n\t\t\tinput: [...input],\n\t\t\treasoning: model.reasoning ?? false,\n\t\t\t...(reasoningEfforts ? { reasoningEfforts } : {}),\n\t\t\t...(model.cacheRetention === \"long\" ? { cacheRetention: \"long\" as const } : {}),\n\t\t\t...(model.sessionAffinity === \"codex\" ? { sessionAffinity: \"codex\" as const } : {}),\n\t\t\tcontextWindow: positiveInteger(model.contextWindow, `${modelPath}.contextWindow`, 128_000, settingsPath),\n\t\t\tmaxOutputTokens: positiveInteger(\n\t\t\t\tmodel.maxTokens ?? model.maxOutputTokens,\n\t\t\t\t`${modelPath}.maxTokens`,\n\t\t\t\t16_384,\n\t\t\t\tsettingsPath,\n\t\t\t),\n\t\t\tcost: {\n\t\t\t\tinput: nonNegativeNumber(prices.input, `${modelPath}.cost.input`, 0, settingsPath) / 1_000_000,\n\t\t\t\toutput: nonNegativeNumber(prices.output, `${modelPath}.cost.output`, 0, settingsPath) / 1_000_000,\n\t\t\t\tcacheRead: nonNegativeNumber(prices.cacheRead, `${modelPath}.cost.cacheRead`, 0, settingsPath) / 1_000_000,\n\t\t\t\tcacheWrite: nonNegativeNumber(prices.cacheWrite, `${modelPath}.cost.cacheWrite`, 0, settingsPath) / 1_000_000,\n\t\t\t},\n\t\t};\n\t});\n}\n\nfunction parseSettings(value: unknown, settingsPath: string): SettingsFile {\n\tif (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n\t\tthrow new Error(`${settingsPath}: root value must be an object`);\n\t}\n\tconst record = value as Record<string, unknown>;\n\tconst providersValue = record.providers;\n\tif (typeof providersValue !== \"object\" || providersValue === null || Array.isArray(providersValue)) {\n\t\tthrow new Error(`${settingsPath}: providers must be an object`);\n\t}\n\tconst providers: Record<string, SettingsFile[\"providers\"][string]> = {};\n\tfor (const [id, entry] of Object.entries(providersValue as Record<string, unknown>)) {\n\t\tif (typeof entry !== \"object\" || entry === null || Array.isArray(entry)) {\n\t\t\tthrow new Error(`${settingsPath}: providers.${id} must be an object`);\n\t\t}\n\t\tconst provider = entry as Record<string, unknown>;\n\t\tproviders[id] = {\n\t\t\tname: optionalString(provider.name, `providers.${id}.name`, settingsPath),\n\t\t\tbaseUrl: optionalString(provider.baseUrl, `providers.${id}.baseUrl`, settingsPath),\n\t\t\tapiKey: optionalString(provider.apiKey, `providers.${id}.apiKey`, settingsPath),\n\t\t\tapi: optionalString(provider.api, `providers.${id}.api`, settingsPath),\n\t\t\tmodels: provider.models,\n\t\t};\n\t}\n\tconst defaultProvider =\n\t\trecord.defaultProvider === undefined\n\t\t\t? undefined\n\t\t\t: requiredString(record.defaultProvider, \"defaultProvider\", settingsPath);\n\tconst defaultModel =\n\t\trecord.defaultModel === undefined ? undefined : requiredString(record.defaultModel, \"defaultModel\", settingsPath);\n\treturn {\n\t\tproviders,\n\t\t...(defaultProvider === undefined ? {} : { defaultProvider }),\n\t\t...(defaultModel === undefined ? {} : { defaultModel }),\n\t};\n}\n\nasync function readSettingsFile(path: string, displayPath: string): Promise<SettingsFile | undefined> {\n\ttry {\n\t\tconst source = await readFile(path, \"utf8\");\n\t\tif (source.trim().length === 0) return undefined;\n\t\treturn parseSettings(JSON.parse(source), displayPath);\n\t} catch (cause) {\n\t\tif (cause instanceof Error && \"code\" in cause && cause.code === \"ENOENT\") return undefined;\n\t\tif (cause instanceof SyntaxError) throw new Error(`${displayPath}: invalid JSON`, { cause });\n\t\tthrow cause;\n\t}\n}\n\nfunction mergeSettings(\n\tglobalSettings: SettingsFile | undefined,\n\tprojectSettings: SettingsFile | undefined,\n): SettingsFile {\n\tconst globalProviders = globalSettings?.providers ?? {};\n\tconst projectProviders = projectSettings?.providers ?? {};\n\tconst providers = { ...globalProviders };\n\tfor (const [id, projectProvider] of Object.entries(projectProviders)) {\n\t\tproviders[id] = {\n\t\t\t...globalProviders[id],\n\t\t\t...(projectProvider.name === undefined ? {} : { name: projectProvider.name }),\n\t\t\t...(projectProvider.baseUrl === undefined ? {} : { baseUrl: projectProvider.baseUrl }),\n\t\t\t...(projectProvider.apiKey === undefined ? {} : { apiKey: projectProvider.apiKey }),\n\t\t\t...(projectProvider.api === undefined ? {} : { api: projectProvider.api }),\n\t\t\t...(projectProvider.models === undefined ? {} : { models: projectProvider.models }),\n\t\t};\n\t}\n\tconst defaultProvider = projectSettings?.defaultProvider ?? globalSettings?.defaultProvider;\n\tconst defaultModel =\n\t\tprojectSettings?.defaultModel ??\n\t\t(projectSettings?.defaultProvider === undefined ? globalSettings?.defaultModel : undefined);\n\treturn {\n\t\tproviders,\n\t\t...(defaultProvider === undefined ? {} : { defaultProvider }),\n\t\t...(defaultModel === undefined ? {} : { defaultModel }),\n\t};\n}\n\nexport async function saveGlobalProviderApiKey(\n\tagentDir: string,\n\tproviderId: string,\n\tapi: Exclude<ModelApi, \"faux\">,\n\tapiKey: string,\n\tmodelId?: string,\n): Promise<void> {\n\tconst settingsFilePath = join(agentDir, SETTINGS_FILE_NAME);\n\tconst trimmedApiKey = apiKey.trim();\n\tif (!trimmedApiKey) throw new Error(`${settingsFilePath}: apiKey must be a non-empty string`);\n\tconst existingSettings = await readSettingsFile(settingsFilePath, settingsFilePath);\n\tconst settings = mergeSettings(existingSettings, {\n\t\tproviders: { [providerId]: { api, apiKey: trimmedApiKey } },\n\t\tdefaultProvider: providerId,\n\t\t...(modelId === undefined ? {} : { defaultModel: modelId }),\n\t});\n\tawait mkdir(agentDir, { recursive: true, mode: 0o700 });\n\tawait writeFile(settingsFilePath, `${JSON.stringify(settings, null, \"\\t\")}\\n`, { encoding: \"utf8\", mode: 0o600 });\n}\n\n/** Removes only the persisted credential for one provider; environment variables remain untouched. */\nexport async function removeGlobalProviderApiKey(agentDir: string, providerId: string): Promise<boolean> {\n\tconst settingsFilePath = join(agentDir, SETTINGS_FILE_NAME);\n\tconst existingSettings = await readSettingsFile(settingsFilePath, settingsFilePath);\n\tconst provider = existingSettings?.providers[providerId];\n\tif (!provider || provider.apiKey === undefined) return false;\n\n\tconst { apiKey: _apiKey, ...providerWithoutApiKey } = provider;\n\tconst settings: SettingsFile = {\n\t\t...existingSettings,\n\t\tproviders: {\n\t\t\t...existingSettings.providers,\n\t\t\t[providerId]: providerWithoutApiKey,\n\t\t},\n\t};\n\tawait writeFile(settingsFilePath, `${JSON.stringify(settings, null, \"\\t\")}\\n`, { encoding: \"utf8\", mode: 0o600 });\n\treturn true;\n}\n\nfunction resolveConfigValue(value: string | undefined, env: Environment): string | undefined {\n\tif (value === undefined) return undefined;\n\tconst trimmed = value.trim();\n\tconst match = /^\\$\\{([A-Za-z_][A-Za-z0-9_]*)\\}$|^\\$([A-Za-z_][A-Za-z0-9_]*)$/.exec(trimmed);\n\tif (match) {\n\t\tconst name = match[1] ?? match[2];\n\t\tconst resolved = env[name];\n\t\tif (!resolved?.trim()) throw new Error(`Configured apiKey environment variable \"${name}\" is not set.`);\n\t\treturn resolved;\n\t}\n\tif (trimmed.startsWith(\"!\")) {\n\t\tthrow new Error(\"Command-based apiKey values are not supported by di-code; use $ENV_VAR instead.\");\n\t}\n\treturn value;\n}\n\nfunction createFauxRuntime(): StartupRuntime {\n\tconst faux = createFauxProvider({ responses: FAUX_RESPONSES });\n\treturn { provider: faux.provider, model: faux.model };\n}\n\nfunction selectProviderModel(provider: Provider, providerId: string, env: Environment): Model {\n\tconst modelId =\n\t\tenv.DI_CODE_MODEL?.trim() ||\n\t\t(providerId === \"anthropic\"\n\t\t\t? provider.models.find((candidate) => candidate.id === \"claude-sonnet-4-5\")?.id\n\t\t\t: providerId === \"openai\"\n\t\t\t\t? provider.models.find((candidate) => candidate.id === \"gpt-4o\")?.id\n\t\t\t\t: providerId === \"zhipu\"\n\t\t\t\t\t? provider.models.find((candidate) => candidate.id === \"glm-5.3\")?.id\n\t\t\t\t\t: undefined) ||\n\t\tprovider.models[0]?.id;\n\tif (!modelId) throw new Error(\"DI_CODE_MODEL is required when the selected provider has no models\");\n\tconst model = provider.models.find((candidate) => candidate.id === modelId);\n\tif (!model) {\n\t\tconst availableModels = provider.models.map((candidate) => candidate.id).join(\", \");\n\t\tthrow new Error(`Unknown model \"${modelId}\" for provider \"${providerId}\". Available models: ${availableModels}.`);\n\t}\n\treturn model;\n}\n\nfunction createBuiltInRuntime(env: Environment, providerId: string): StartupRuntime | undefined {\n\tif (providerId === \"anthropic\") {\n\t\tconst provider = createAnthropicProvider({ env });\n\t\treturn { provider, model: selectProviderModel(provider, providerId, env) };\n\t}\n\tif (providerId === \"openai\") {\n\t\tconst provider = createOpenAIProvider({ env });\n\t\treturn { provider, model: selectProviderModel(provider, providerId, env) };\n\t}\n\tif (providerId === \"deepseek\") {\n\t\tconst provider = createDeepSeekProvider({ env });\n\t\treturn { provider, model: selectProviderModel(provider, providerId, env) };\n\t}\n\tif (providerId === \"zhipu\") {\n\t\tconst provider = createZhipuProvider({ env });\n\t\treturn { provider, model: selectProviderModel(provider, providerId, env) };\n\t}\n\treturn undefined;\n}\n\nfunction createConfiguredRuntime(env: Environment, configuration: StartupProviderConfiguration): StartupRuntime {\n\tif (\n\t\tconfiguration.api !== \"openai-responses\" &&\n\t\tconfiguration.api !== \"openai-chat-completions\" &&\n\t\tconfiguration.api !== \"anthropic-messages\"\n\t) {\n\t\tthrow new Error(\n\t\t\t`Unsupported API \"${configuration.api ?? \"missing\"}\" for provider \"${configuration.id}\". Expected openai-responses, openai-chat-completions, or anthropic-messages.`,\n\t\t);\n\t}\n\tif (\n\t\tconfiguration.id !== \"openai\" &&\n\t\tconfiguration.id !== \"deepseek\" &&\n\t\tconfiguration.id !== \"zhipu\" &&\n\t\tconfiguration.id !== \"anthropic\" &&\n\t\t!configuration.models\n\t) {\n\t\tthrow new Error(`${SETTINGS_PATH}: providers.${configuration.id}.models is required for a custom provider`);\n\t}\n\tconst provider =\n\t\tconfiguration.api === \"openai-chat-completions\"\n\t\t\t? createOpenAIChatCompletionsProvider({\n\t\t\t\t\tenv:\n\t\t\t\t\t\tconfiguration.id === \"zhipu\" || configuration.id === \"deepseek\"\n\t\t\t\t\t\t\t? env\n\t\t\t\t\t\t\t: Object.fromEntries(\n\t\t\t\t\t\t\t\t\tObject.entries(env).filter(([name]) => name !== \"OPENAI_API_KEY\" && name !== \"OPENAI_BASE_URL\"),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\tmodels: configuration.models,\n\t\t\t\t\tapiKey: resolveConfigValue(configuration.apiKey, env),\n\t\t\t\t\tbaseUrl: configuration.models ? undefined : configuration.baseUrl,\n\t\t\t\t\tproviderId: configuration.id,\n\t\t\t\t\tname: configuration.name ?? configuration.id,\n\t\t\t\t\t...(configuration.id === \"zhipu\"\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tapiKeyEnvironmentVariable: \"ZAI_API_KEY\",\n\t\t\t\t\t\t\t\tbaseUrlEnvironmentVariable: \"ZHIPU_BASE_URL\",\n\t\t\t\t\t\t\t\tdefaultBaseUrl: \"https://open.bigmodel.cn/api/coding/paas/v4\",\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: configuration.id === \"deepseek\"\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\tapiKeyEnvironmentVariable: \"DEEPSEEK_API_KEY\",\n\t\t\t\t\t\t\t\t\tbaseUrlEnvironmentVariable: \"DEEPSEEK_BASE_URL\",\n\t\t\t\t\t\t\t\t\tdefaultBaseUrl: \"https://api.deepseek.com\",\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: {}),\n\t\t\t\t})\n\t\t\t: configuration.api === \"anthropic-messages\"\n\t\t\t\t? createAnthropicProvider({\n\t\t\t\t\t\tenv:\n\t\t\t\t\t\t\tconfiguration.id === \"anthropic\"\n\t\t\t\t\t\t\t\t? env\n\t\t\t\t\t\t\t\t: Object.fromEntries(\n\t\t\t\t\t\t\t\t\t\tObject.entries(env).filter(\n\t\t\t\t\t\t\t\t\t\t\t([name]) => name !== \"ANTHROPIC_API_KEY\" && name !== \"ANTHROPIC_BASE_URL\",\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\tmodels: configuration.models,\n\t\t\t\t\t\tapiKey: resolveConfigValue(configuration.apiKey, env),\n\t\t\t\t\t\tbaseUrl: configuration.models ? undefined : configuration.baseUrl,\n\t\t\t\t\t\tproviderId: configuration.id,\n\t\t\t\t\t\tname: configuration.name,\n\t\t\t\t\t})\n\t\t\t\t: configuration.id === \"deepseek\"\n\t\t\t\t\t? createDeepSeekProvider({\n\t\t\t\t\t\t\tenv,\n\t\t\t\t\t\t\tmodels: configuration.models,\n\t\t\t\t\t\t\tapiKey: resolveConfigValue(configuration.apiKey, env),\n\t\t\t\t\t\t\tbaseUrl: configuration.models ? undefined : configuration.baseUrl,\n\t\t\t\t\t\t})\n\t\t\t\t\t: configuration.id === \"zhipu\"\n\t\t\t\t\t\t? createZhipuProvider({\n\t\t\t\t\t\t\t\tenv,\n\t\t\t\t\t\t\t\tmodels: configuration.models,\n\t\t\t\t\t\t\t\tapiKey: resolveConfigValue(configuration.apiKey, env),\n\t\t\t\t\t\t\t\tbaseUrl: configuration.models ? undefined : configuration.baseUrl,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: createOpenAIProvider({\n\t\t\t\t\t\t\t\tenv:\n\t\t\t\t\t\t\t\t\tconfiguration.id === \"openai\"\n\t\t\t\t\t\t\t\t\t\t? env\n\t\t\t\t\t\t\t\t\t\t: Object.fromEntries(\n\t\t\t\t\t\t\t\t\t\t\t\tObject.entries(env).filter(([name]) => name !== \"OPENAI_API_KEY\" && name !== \"OPENAI_BASE_URL\"),\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tmodels: configuration.models,\n\t\t\t\t\t\t\t\tapiKey: resolveConfigValue(configuration.apiKey, env),\n\t\t\t\t\t\t\t\tbaseUrl: configuration.models ? undefined : configuration.baseUrl,\n\t\t\t\t\t\t\t\tproviderId: configuration.id,\n\t\t\t\t\t\t\t\tname: configuration.name,\n\t\t\t\t\t\t\t});\n\tconst model = selectProviderModel(provider, configuration.id, env);\n\treturn { provider, model };\n}\n\nexport function resolveStartupRuntime(\n\tenv: Environment,\n\tproviders: readonly StartupProviderConfiguration[],\n\tdefaults: StartupDefaults = {},\n): StartupRuntime {\n\tconst selectedProviderId =\n\t\tenv.DI_CODE_PROVIDER?.trim() || defaults.providerId || (providers.length === 1 ? providers[0]?.id : undefined);\n\tif (selectedProviderId === \"faux\") return createFauxRuntime();\n\tif (!selectedProviderId) {\n\t\tif (providers.length === 0) {\n\t\t\tthrow new Error(\"Provider is not configured. Set DI_CODE_PROVIDER or start interactive mode in a TTY.\");\n\t\t}\n\t\tthrow new Error(\"DI_CODE_PROVIDER is required when more than one provider is configured.\");\n\t}\n\tconst runtimeEnvironment =\n\t\tenv.DI_CODE_MODEL?.trim() || defaults.providerId !== selectedProviderId || !defaults.modelId\n\t\t\t? env\n\t\t\t: { ...env, DI_CODE_MODEL: defaults.modelId };\n\tconst selectedProvider = providers.find((provider) => provider.id === selectedProviderId);\n\tif (selectedProvider) return createConfiguredRuntime(runtimeEnvironment, selectedProvider);\n\tconst builtInRuntime = createBuiltInRuntime(runtimeEnvironment, selectedProviderId);\n\tif (builtInRuntime) return builtInRuntime;\n\tthrow new Error(\n\t\t`Unknown configured provider \"${selectedProviderId}\". Available providers: ${providers.map((provider) => provider.id).join(\", \")}.`,\n\t);\n}\n\nexport async function loadStartupConfiguration(\n\tcwd: string,\n\tenvironment: Environment = process.env,\n\tagentDir = join(homedir(), \".di-code\"),\n): Promise<StartupConfiguration> {\n\tconst [globalSettings, projectSettings] = await Promise.all([\n\t\treadSettingsFile(join(agentDir, SETTINGS_FILE_NAME), join(agentDir, SETTINGS_FILE_NAME)),\n\t\treadSettingsFile(join(cwd, SETTINGS_PATH), SETTINGS_PATH),\n\t]);\n\tconst settings = mergeSettings(globalSettings, projectSettings);\n\n\tconst providers = Object.entries(settings.providers).map(([id, provider]) => ({\n\t\tid: requiredString(id, `providers.${id}`),\n\t\tname: provider.name,\n\t\tapi: provider.api,\n\t\tapiKey: provider.apiKey,\n\t\tbaseUrl: provider.baseUrl,\n\t\tmodels: parseModels(provider.models, `providers.${id}.models`, id, provider.api, provider.baseUrl, SETTINGS_PATH),\n\t}));\n\tconst defaults =\n\t\tsettings.defaultProvider === undefined && settings.defaultModel === undefined\n\t\t\t? undefined\n\t\t\t: { providerId: settings.defaultProvider, modelId: settings.defaultModel };\n\treturn { environment, providers, ...(defaults === undefined ? {} : { defaults }) };\n}\n\nexport async function loadStartupEnvironment(\n\tcwd: string,\n\tenvironment: Environment = process.env,\n): Promise<Environment> {\n\treturn (await loadStartupConfiguration(cwd, environment)).environment;\n}\n"]}
1
+ {"version":3,"file":"startup.js","sourceRoot":"","sources":["../src/startup.ts"],"names":[],"mappings":"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","sourcesContent":["import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport {\n\tcreateAnthropicProvider,\n\tcreateDeepSeekProvider,\n\tcreateFauxProvider,\n\tcreateKimiProvider,\n\tcreateOpenAIChatCompletionsProvider,\n\tcreateOpenAIProvider,\n\tcreateZhipuProvider,\n\ttype FauxResponse,\n\tfindBuiltinModel,\n\ttype Model,\n\ttype ModelApi,\n\ttype Provider,\n} from \"@di-code/ai\";\nimport { isLocale, type Locale } from \"./i18n.ts\";\n\nexport interface StartupRuntime {\n\treadonly provider: Provider;\n\treadonly model: Model;\n}\n\nexport interface StartupProviderConfiguration {\n\treadonly id: string;\n\treadonly name?: string;\n\treadonly api?: string;\n\treadonly apiKey?: string;\n\treadonly baseUrl?: string;\n\treadonly models?: readonly Model[];\n}\n\nexport interface StartupConfiguration {\n\treadonly environment: Environment;\n\treadonly providers: readonly StartupProviderConfiguration[];\n\treadonly defaults?: StartupDefaults;\n\treadonly locale?: Locale;\n}\n\nexport interface StartupDefaults {\n\treadonly providerId?: string;\n\treadonly modelId?: string;\n}\n\nexport interface CustomProviderInput {\n\treadonly api: Exclude<ModelApi, \"faux\">;\n\treadonly baseUrl: string;\n\treadonly apiKey: string;\n\treadonly modelId: string;\n}\n\nconst FAUX_RESPONSES: readonly FauxResponse[] = [\n\t{\n\t\ttype: \"success\",\n\t\tcontent: [\n\t\t\t{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: \"你好,我是di-code,一个面向终端的 TypeScript AI Coding Agent,支持多 Provider 流式对话、工具调用、JSONL 会话持久化、交互式 TUI、插件扩展与 JSONL RPC 集成。\",\n\t\t\t},\n\t\t],\n\t},\n\t{ type: \"success\", content: [{ type: \"text\", text: \"当前回复为faux数据\" }] },\n];\n\nconst SETTINGS_FILE_NAME = \"settings.json\";\nconst SETTINGS_PATH = join(\".di-code\", SETTINGS_FILE_NAME);\n\ntype Environment = Readonly<Record<string, string | undefined>>;\n\ninterface SettingsFile {\n\treadonly defaultProvider?: string;\n\treadonly defaultModel?: string;\n\treadonly locale?: Locale;\n\treadonly providers: Record<\n\t\tstring,\n\t\t{\n\t\t\treadonly name?: string;\n\t\t\treadonly baseUrl?: string;\n\t\t\treadonly apiKey?: string;\n\t\t\treadonly api?: string;\n\t\t\treadonly models?: unknown;\n\t\t}\n\t>;\n}\n\nexport function resolveStartupArgs(args: readonly string[]): readonly string[] {\n\treturn args.length === 0 ? [\"--interactive\"] : args;\n}\n\nfunction optionalString(value: unknown, path: string, settingsPath: string): string | undefined {\n\tif (value === undefined) return undefined;\n\tif (typeof value !== \"string\") throw new Error(`${settingsPath}: ${path} must be a string`);\n\treturn value;\n}\n\nfunction requiredString(value: unknown, path: string, settingsPath = SETTINGS_PATH): string {\n\tconst result = optionalString(value, path, settingsPath);\n\tif (!result?.trim()) throw new Error(`${settingsPath}: ${path} must be a non-empty string`);\n\treturn result.trim();\n}\n\nfunction positiveInteger(value: unknown, path: string, fallback: number, settingsPath: string): number {\n\tconst result = value ?? fallback;\n\tif (!Number.isInteger(result) || (result as number) <= 0) {\n\t\tthrow new Error(`${settingsPath}: ${path} must be a positive integer`);\n\t}\n\treturn result as number;\n}\n\nfunction nonNegativeNumber(value: unknown, path: string, fallback: number, settingsPath: string): number {\n\tconst result = value ?? fallback;\n\tif (typeof result !== \"number\" || !Number.isFinite(result) || result < 0) {\n\t\tthrow new Error(`${settingsPath}: ${path} must be a non-negative finite number`);\n\t}\n\treturn result;\n}\n\nfunction parseChatCompletionsCompat(\n\tvalue: unknown,\n\tpath: string,\n\tsettingsPath: string,\n): Model[\"chatCompletionsCompat\"] {\n\tif (value === undefined) return undefined;\n\tif (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n\t\tthrow new Error(`${settingsPath}: ${path} must be an object`);\n\t}\n\tconst compat = value as Record<string, unknown>;\n\tconst optionalBoolean = (field: string): boolean | undefined => {\n\t\tconst candidate = compat[field];\n\t\tif (candidate === undefined) return undefined;\n\t\tif (typeof candidate !== \"boolean\") throw new Error(`${settingsPath}: ${path}.${field} must be a boolean`);\n\t\treturn candidate;\n\t};\n\tconst maxTokensField = compat.maxTokensField;\n\tif (maxTokensField !== undefined && maxTokensField !== \"max_tokens\" && maxTokensField !== \"max_completion_tokens\") {\n\t\tthrow new Error(`${settingsPath}: ${path}.maxTokensField is invalid`);\n\t}\n\tconst thinkingFormat = compat.thinkingFormat;\n\tif (\n\t\tthinkingFormat !== undefined &&\n\t\tthinkingFormat !== \"zai\" &&\n\t\tthinkingFormat !== \"deepseek\" &&\n\t\tthinkingFormat !== \"kimi\"\n\t) {\n\t\tthrow new Error(`${settingsPath}: ${path}.thinkingFormat is invalid`);\n\t}\n\tconst supportsUsageInStreaming = optionalBoolean(\"supportsUsageInStreaming\");\n\tconst supportsReasoningEffort = optionalBoolean(\"supportsReasoningEffort\");\n\tconst zaiToolStream = optionalBoolean(\"zaiToolStream\");\n\treturn {\n\t\t...(maxTokensField === undefined ? {} : { maxTokensField }),\n\t\t...(thinkingFormat === undefined ? {} : { thinkingFormat }),\n\t\t...(supportsUsageInStreaming === undefined ? {} : { supportsUsageInStreaming }),\n\t\t...(supportsReasoningEffort === undefined ? {} : { supportsReasoningEffort }),\n\t\t...(zaiToolStream === undefined ? {} : { zaiToolStream }),\n\t};\n}\n\nfunction parseModels(\n\tvalue: unknown,\n\tpath: string,\n\tproviderId: string,\n\tproviderApi: string | undefined,\n\tproviderBaseUrl: string | undefined,\n\tsettingsPath: string,\n): readonly Model[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) throw new Error(`${settingsPath}: ${path} must be an array`);\n\n\treturn value.map((entry, index) => {\n\t\tconst modelPath = `${path}[${index}]`;\n\t\tif (typeof entry !== \"object\" || entry === null || Array.isArray(entry)) {\n\t\t\tthrow new Error(`${settingsPath}: ${modelPath} must be an object`);\n\t\t}\n\t\tconst model = entry as Record<string, unknown>;\n\t\tconst input = model.input ?? [\"text\"];\n\t\tif (!Array.isArray(input) || input.length === 0 || input.some((item) => item !== \"text\" && item !== \"image\")) {\n\t\t\tthrow new Error(`${settingsPath}: ${modelPath}.input must contain text and/or image`);\n\t\t}\n\t\tconst cost = model.cost ?? {};\n\t\tif (typeof cost !== \"object\" || cost === null || Array.isArray(cost)) {\n\t\t\tthrow new Error(`${settingsPath}: ${modelPath}.cost must be an object`);\n\t\t}\n\t\tconst prices = cost as Record<string, unknown>;\n\t\tif (model.reasoning !== undefined && typeof model.reasoning !== \"boolean\") {\n\t\t\tthrow new Error(`${settingsPath}: ${modelPath}.reasoning must be a boolean`);\n\t\t}\n\t\tconst configuredReasoningEfforts = model.reasoningEfforts;\n\t\tif (configuredReasoningEfforts !== undefined) {\n\t\t\tif (!Array.isArray(configuredReasoningEfforts) || configuredReasoningEfforts.length === 0) {\n\t\t\t\tthrow new Error(`${settingsPath}: ${modelPath}.reasoningEfforts must be a non-empty array`);\n\t\t\t}\n\t\t\tif (\n\t\t\t\tmodel.reasoning !== true ||\n\t\t\t\tconfiguredReasoningEfforts.some(\n\t\t\t\t\t(effort) => effort !== \"low\" && effort !== \"medium\" && effort !== \"high\" && effort !== \"max\",\n\t\t\t\t) ||\n\t\t\t\tnew Set(configuredReasoningEfforts).size !== configuredReasoningEfforts.length\n\t\t\t) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`${settingsPath}: ${modelPath}.reasoningEfforts requires reasoning=true and unique low, medium, high, or max values`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tif (model.cacheRetention !== undefined && model.cacheRetention !== \"long\") {\n\t\t\tthrow new Error(`${settingsPath}: ${modelPath}.cacheRetention must be \"long\" when provided`);\n\t\t}\n\t\tif (model.sessionAffinity !== undefined && model.sessionAffinity !== \"codex\") {\n\t\t\tthrow new Error(`${settingsPath}: ${modelPath}.sessionAffinity must be \"codex\" when provided`);\n\t\t}\n\t\tconst api = optionalString(model.api, `${modelPath}.api`, settingsPath) ?? providerApi;\n\t\tif (!api) throw new Error(`${settingsPath}: ${modelPath}.api is required`);\n\t\tif (![\"faux\", \"openai-responses\", \"openai-chat-completions\", \"anthropic-messages\"].includes(api)) {\n\t\t\tthrow new Error(`${settingsPath}: ${modelPath}.api is unsupported`);\n\t\t}\n\t\tconst typedApi = api as ModelApi;\n\t\tconst reasoningEfforts: Model[\"reasoningEfforts\"] =\n\t\t\tconfiguredReasoningEfforts === undefined && model.reasoning === true && api === \"openai-responses\"\n\t\t\t\t? [\"low\", \"medium\", \"high\"]\n\t\t\t\t: configuredReasoningEfforts === undefined\n\t\t\t\t\t? undefined\n\t\t\t\t\t: ([...configuredReasoningEfforts] as Model[\"reasoningEfforts\"]);\n\t\tconst baseUrl = optionalString(model.baseUrl, `${modelPath}.baseUrl`, settingsPath) ?? providerBaseUrl;\n\t\tconst id = requiredString(model.id, `${modelPath}.id`, settingsPath);\n\t\tconst chatCompletionsCompat = parseChatCompletionsCompat(\n\t\t\tmodel.chatCompletionsCompat,\n\t\t\t`${modelPath}.chatCompletionsCompat`,\n\t\t\tsettingsPath,\n\t\t);\n\t\tif (chatCompletionsCompat !== undefined && typedApi !== \"openai-chat-completions\") {\n\t\t\tthrow new Error(`${settingsPath}: ${modelPath}.chatCompletionsCompat requires api \"openai-chat-completions\"`);\n\t\t}\n\t\treturn {\n\t\t\tid,\n\t\t\tname: requiredString(model.name ?? id, `${modelPath}.name`, settingsPath),\n\t\t\tprovider: providerId,\n\t\t\tapi: typedApi,\n\t\t\t...(baseUrl === undefined ? {} : { baseUrl }),\n\t\t\tinput: [...input],\n\t\t\treasoning: model.reasoning ?? false,\n\t\t\t...(reasoningEfforts ? { reasoningEfforts } : {}),\n\t\t\t...(chatCompletionsCompat ? { chatCompletionsCompat } : {}),\n\t\t\t...(model.cacheRetention === \"long\" ? { cacheRetention: \"long\" as const } : {}),\n\t\t\t...(model.sessionAffinity === \"codex\" ? { sessionAffinity: \"codex\" as const } : {}),\n\t\t\tcontextWindow: positiveInteger(model.contextWindow, `${modelPath}.contextWindow`, 128_000, settingsPath),\n\t\t\tmaxOutputTokens: positiveInteger(\n\t\t\t\tmodel.maxTokens ?? model.maxOutputTokens,\n\t\t\t\t`${modelPath}.maxTokens`,\n\t\t\t\t16_384,\n\t\t\t\tsettingsPath,\n\t\t\t),\n\t\t\tcost: {\n\t\t\t\tinput: nonNegativeNumber(prices.input, `${modelPath}.cost.input`, 0, settingsPath) / 1_000_000,\n\t\t\t\toutput: nonNegativeNumber(prices.output, `${modelPath}.cost.output`, 0, settingsPath) / 1_000_000,\n\t\t\t\tcacheRead: nonNegativeNumber(prices.cacheRead, `${modelPath}.cost.cacheRead`, 0, settingsPath) / 1_000_000,\n\t\t\t\tcacheWrite: nonNegativeNumber(prices.cacheWrite, `${modelPath}.cost.cacheWrite`, 0, settingsPath) / 1_000_000,\n\t\t\t},\n\t\t};\n\t});\n}\n\n/** Validates a Custom onboarding endpoint without issuing a network request. */\nexport function validateCustomBaseUrl(value: string): string {\n\tconst baseUrl = value.trim();\n\tif (!baseUrl) throw new Error(\"Base URL cannot be empty.\");\n\tlet url: URL;\n\ttry {\n\t\turl = new URL(baseUrl);\n\t} catch {\n\t\tthrow new Error(\"Base URL must be an absolute http or https URL.\");\n\t}\n\tif (url.protocol !== \"http:\" && url.protocol !== \"https:\") throw new Error(\"Base URL must use http or https.\");\n\tif (url.username || url.password || url.search || url.hash) {\n\t\tthrow new Error(\"Base URL must not contain credentials, query, or hash.\");\n\t}\n\tif (baseUrl.endsWith(\"/\")) throw new Error(\"Base URL must not end with /.\");\n\treturn baseUrl;\n}\n\nfunction requireCustomValue(value: string, field: \"apiKey\" | \"modelId\"): string {\n\tconst trimmed = value.trim();\n\tif (!trimmed) throw new Error(`${field === \"apiKey\" ? \"API key\" : \"Model ID\"} cannot be empty.`);\n\treturn trimmed;\n}\n\n/** Builds the single user-managed Custom provider from validated onboarding input. */\nexport function createCustomProviderConfiguration(input: CustomProviderInput): StartupProviderConfiguration {\n\tconst baseUrl = validateCustomBaseUrl(input.baseUrl);\n\tconst modelId = requireCustomValue(input.modelId, \"modelId\");\n\tconst apiKey = requireCustomValue(input.apiKey, \"apiKey\");\n\tconst known = findBuiltinModel(input.api, modelId);\n\tconst model: Model = known\n\t\t? {\n\t\t\t\t...known,\n\t\t\t\tid: modelId,\n\t\t\t\tprovider: \"custom\",\n\t\t\t\tapi: input.api,\n\t\t\t\tbaseUrl,\n\t\t\t}\n\t\t: {\n\t\t\t\tid: modelId,\n\t\t\t\tname: modelId,\n\t\t\t\tprovider: \"custom\",\n\t\t\t\tapi: input.api,\n\t\t\t\tbaseUrl,\n\t\t\t\tinput: [\"text\"],\n\t\t\t\treasoning: false,\n\t\t\t\tcontextWindow: 128_000,\n\t\t\t\tmaxOutputTokens: 16_384,\n\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t\t\t};\n\treturn { id: \"custom\", name: \"Custom\", api: input.api, apiKey, baseUrl, models: [model] };\n}\n\nfunction serializeModel(model: Model): Record<string, unknown> {\n\treturn {\n\t\tid: model.id,\n\t\tname: model.name,\n\t\tinput: model.input,\n\t\treasoning: model.reasoning,\n\t\t...(model.reasoningEfforts ? { reasoningEfforts: model.reasoningEfforts } : {}),\n\t\t...(model.chatCompletionsCompat ? { chatCompletionsCompat: model.chatCompletionsCompat } : {}),\n\t\t...(model.cacheRetention ? { cacheRetention: model.cacheRetention } : {}),\n\t\t...(model.sessionAffinity ? { sessionAffinity: model.sessionAffinity } : {}),\n\t\tcontextWindow: model.contextWindow,\n\t\tmaxTokens: model.maxOutputTokens,\n\t\tcost: Object.fromEntries(Object.entries(model.cost).map(([key, value]) => [key, value * 1_000_000])),\n\t};\n}\n\nfunction parseSettings(value: unknown, settingsPath: string): SettingsFile {\n\tif (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n\t\tthrow new Error(`${settingsPath}: root value must be an object`);\n\t}\n\tconst record = value as Record<string, unknown>;\n\tconst providersValue = record.providers;\n\tif (typeof providersValue !== \"object\" || providersValue === null || Array.isArray(providersValue)) {\n\t\tthrow new Error(`${settingsPath}: providers must be an object`);\n\t}\n\tconst providers: Record<string, SettingsFile[\"providers\"][string]> = {};\n\tfor (const [id, entry] of Object.entries(providersValue as Record<string, unknown>)) {\n\t\tif (typeof entry !== \"object\" || entry === null || Array.isArray(entry)) {\n\t\t\tthrow new Error(`${settingsPath}: providers.${id} must be an object`);\n\t\t}\n\t\tconst provider = entry as Record<string, unknown>;\n\t\tproviders[id] = {\n\t\t\tname: optionalString(provider.name, `providers.${id}.name`, settingsPath),\n\t\t\tbaseUrl: optionalString(provider.baseUrl, `providers.${id}.baseUrl`, settingsPath),\n\t\t\tapiKey: optionalString(provider.apiKey, `providers.${id}.apiKey`, settingsPath),\n\t\t\tapi: optionalString(provider.api, `providers.${id}.api`, settingsPath),\n\t\t\tmodels: provider.models,\n\t\t};\n\t}\n\tconst defaultProvider =\n\t\trecord.defaultProvider === undefined\n\t\t\t? undefined\n\t\t\t: requiredString(record.defaultProvider, \"defaultProvider\", settingsPath);\n\tconst defaultModel =\n\t\trecord.defaultModel === undefined ? undefined : requiredString(record.defaultModel, \"defaultModel\", settingsPath);\n\tif (record.locale !== undefined && !isLocale(record.locale)) {\n\t\tthrow new Error(`${settingsPath}: locale must be \"en\" or \"zh-CN\"`);\n\t}\n\treturn {\n\t\tproviders,\n\t\t...(defaultProvider === undefined ? {} : { defaultProvider }),\n\t\t...(defaultModel === undefined ? {} : { defaultModel }),\n\t\t...(record.locale === undefined ? {} : { locale: record.locale }),\n\t};\n}\n\nasync function readSettingsFile(path: string, displayPath: string): Promise<SettingsFile | undefined> {\n\ttry {\n\t\tconst source = await readFile(path, \"utf8\");\n\t\tif (source.trim().length === 0) return undefined;\n\t\treturn parseSettings(JSON.parse(source), displayPath);\n\t} catch (cause) {\n\t\tif (cause instanceof Error && \"code\" in cause && cause.code === \"ENOENT\") return undefined;\n\t\tif (cause instanceof SyntaxError) throw new Error(`${displayPath}: invalid JSON`, { cause });\n\t\tthrow cause;\n\t}\n}\n\nfunction mergeSettings(\n\tglobalSettings: SettingsFile | undefined,\n\tprojectSettings: SettingsFile | undefined,\n): SettingsFile {\n\tconst globalProviders = globalSettings?.providers ?? {};\n\tconst projectProviders = projectSettings?.providers ?? {};\n\tconst providers = { ...globalProviders };\n\tfor (const [id, projectProvider] of Object.entries(projectProviders)) {\n\t\tproviders[id] = {\n\t\t\t...globalProviders[id],\n\t\t\t...(projectProvider.name === undefined ? {} : { name: projectProvider.name }),\n\t\t\t...(projectProvider.baseUrl === undefined ? {} : { baseUrl: projectProvider.baseUrl }),\n\t\t\t...(projectProvider.apiKey === undefined ? {} : { apiKey: projectProvider.apiKey }),\n\t\t\t...(projectProvider.api === undefined ? {} : { api: projectProvider.api }),\n\t\t\t...(projectProvider.models === undefined ? {} : { models: projectProvider.models }),\n\t\t};\n\t}\n\tconst defaultProvider = projectSettings?.defaultProvider ?? globalSettings?.defaultProvider;\n\tconst defaultModel =\n\t\tprojectSettings?.defaultModel ??\n\t\t(projectSettings?.defaultProvider === undefined ? globalSettings?.defaultModel : undefined);\n\tconst locale = globalSettings?.locale;\n\treturn {\n\t\tproviders,\n\t\t...(defaultProvider === undefined ? {} : { defaultProvider }),\n\t\t...(defaultModel === undefined ? {} : { defaultModel }),\n\t\t...(locale === undefined ? {} : { locale }),\n\t};\n}\n\n/** Persists a user-level terminal language preference without changing project settings. */\nexport async function saveGlobalLocale(agentDir: string, locale: Locale): Promise<void> {\n\tconst settingsFilePath = join(agentDir, SETTINGS_FILE_NAME);\n\tconst existingSettings = await readSettingsFile(settingsFilePath, settingsFilePath);\n\tconst settings: SettingsFile = {\n\t\tproviders: existingSettings?.providers ?? {},\n\t\t...(existingSettings?.defaultProvider === undefined ? {} : { defaultProvider: existingSettings.defaultProvider }),\n\t\t...(existingSettings?.defaultModel === undefined ? {} : { defaultModel: existingSettings.defaultModel }),\n\t\tlocale,\n\t};\n\tawait mkdir(agentDir, { recursive: true, mode: 0o700 });\n\tawait writeFile(settingsFilePath, `${JSON.stringify(settings, null, \"\\t\")}\\n`, { encoding: \"utf8\", mode: 0o600 });\n}\n\nexport async function saveGlobalProviderApiKey(\n\tagentDir: string,\n\tproviderId: string,\n\tapi: Exclude<ModelApi, \"faux\">,\n\tapiKey: string,\n\tmodelId?: string,\n): Promise<void> {\n\tconst settingsFilePath = join(agentDir, SETTINGS_FILE_NAME);\n\tconst trimmedApiKey = apiKey.trim();\n\tif (!trimmedApiKey) throw new Error(`${settingsFilePath}: apiKey must be a non-empty string`);\n\tconst existingSettings = await readSettingsFile(settingsFilePath, settingsFilePath);\n\tconst settings = mergeSettings(existingSettings, {\n\t\tproviders: { [providerId]: { api, apiKey: trimmedApiKey } },\n\t\tdefaultProvider: providerId,\n\t\t...(modelId === undefined ? {} : { defaultModel: modelId }),\n\t});\n\tawait mkdir(agentDir, { recursive: true, mode: 0o700 });\n\tawait writeFile(settingsFilePath, `${JSON.stringify(settings, null, \"\\t\")}\\n`, { encoding: \"utf8\", mode: 0o600 });\n}\n\n/**\n * Replaces the user-managed `custom` provider while retaining other global\n * providers and preferences. The key is intentionally stored only here, never\n * in project settings or process environment.\n */\nexport async function saveGlobalCustomProvider(\n\tagentDir: string,\n\tinput: CustomProviderInput,\n): Promise<StartupProviderConfiguration> {\n\tconst configuration = createCustomProviderConfiguration(input);\n\tconst settingsFilePath = join(agentDir, SETTINGS_FILE_NAME);\n\tconst existingSettings = await readSettingsFile(settingsFilePath, settingsFilePath);\n\tconst settings = mergeSettings(existingSettings, {\n\t\tproviders: {\n\t\t\tcustom: {\n\t\t\t\tname: configuration.name,\n\t\t\t\tapi: configuration.api,\n\t\t\t\tbaseUrl: configuration.baseUrl,\n\t\t\t\tapiKey: configuration.apiKey,\n\t\t\t\tmodels: configuration.models?.map(serializeModel),\n\t\t\t},\n\t\t},\n\t\tdefaultProvider: \"custom\",\n\t\tdefaultModel: configuration.models?.[0]?.id,\n\t});\n\tawait mkdir(agentDir, { recursive: true, mode: 0o700 });\n\tawait writeFile(settingsFilePath, `${JSON.stringify(settings, null, \"\\t\")}\\n`, { encoding: \"utf8\", mode: 0o600 });\n\treturn configuration;\n}\n\n/**\n * Removes one persisted credential and clears it as the default when applicable.\n * Environment variables and other Provider configuration remain untouched.\n */\nexport async function removeGlobalProviderApiKey(agentDir: string, providerId: string): Promise<boolean> {\n\tconst settingsFilePath = join(agentDir, SETTINGS_FILE_NAME);\n\tconst existingSettings = await readSettingsFile(settingsFilePath, settingsFilePath);\n\tconst provider = existingSettings?.providers[providerId];\n\tif (!provider || provider.apiKey === undefined) return false;\n\n\tconst { apiKey: _apiKey, ...providerWithoutApiKey } = provider;\n\tconst clearsDefault = existingSettings.defaultProvider === providerId;\n\tconst settings: SettingsFile = {\n\t\tproviders: {\n\t\t\t...existingSettings.providers,\n\t\t\t[providerId]: providerWithoutApiKey,\n\t\t},\n\t\t...(clearsDefault || existingSettings.defaultProvider === undefined\n\t\t\t? {}\n\t\t\t: { defaultProvider: existingSettings.defaultProvider }),\n\t\t...(clearsDefault || existingSettings.defaultModel === undefined\n\t\t\t? {}\n\t\t\t: { defaultModel: existingSettings.defaultModel }),\n\t\t...(existingSettings.locale === undefined ? {} : { locale: existingSettings.locale }),\n\t};\n\tawait writeFile(settingsFilePath, `${JSON.stringify(settings, null, \"\\t\")}\\n`, { encoding: \"utf8\", mode: 0o600 });\n\treturn true;\n}\n\nfunction resolveConfigValue(value: string | undefined, env: Environment): string | undefined {\n\tif (value === undefined) return undefined;\n\tconst trimmed = value.trim();\n\tconst match = /^\\$\\{([A-Za-z_][A-Za-z0-9_]*)\\}$|^\\$([A-Za-z_][A-Za-z0-9_]*)$/.exec(trimmed);\n\tif (match) {\n\t\tconst name = match[1] ?? match[2];\n\t\tconst resolved = env[name];\n\t\tif (!resolved?.trim()) throw new Error(`Configured apiKey environment variable \"${name}\" is not set.`);\n\t\treturn resolved;\n\t}\n\tif (trimmed.startsWith(\"!\")) {\n\t\tthrow new Error(\"Command-based apiKey values are not supported by di-code; use $ENV_VAR instead.\");\n\t}\n\treturn value;\n}\n\nfunction createFauxRuntime(): StartupRuntime {\n\tconst faux = createFauxProvider({ responses: FAUX_RESPONSES });\n\treturn { provider: faux.provider, model: faux.model };\n}\n\nfunction selectProviderModel(provider: Provider, providerId: string, env: Environment): Model {\n\tconst modelId =\n\t\tenv.DI_CODE_MODEL?.trim() ||\n\t\t(providerId === \"anthropic\"\n\t\t\t? provider.models.find((candidate) => candidate.id === \"claude-sonnet-4-5\")?.id\n\t\t\t: providerId === \"openai\"\n\t\t\t\t? provider.models.find((candidate) => candidate.id === \"gpt-4o\")?.id\n\t\t\t\t: providerId === \"zhipu\"\n\t\t\t\t\t? provider.models.find((candidate) => candidate.id === \"glm-5.3\")?.id\n\t\t\t\t\t: providerId === \"kimi\"\n\t\t\t\t\t\t? provider.models.find((candidate) => candidate.id === \"k3\")?.id\n\t\t\t\t\t\t: undefined) ||\n\t\tprovider.models[0]?.id;\n\tif (!modelId) throw new Error(\"DI_CODE_MODEL is required when the selected provider has no models\");\n\tconst model = provider.models.find((candidate) => candidate.id === modelId);\n\tif (!model) {\n\t\tconst availableModels = provider.models.map((candidate) => candidate.id).join(\", \");\n\t\tthrow new Error(`Unknown model \"${modelId}\" for provider \"${providerId}\". Available models: ${availableModels}.`);\n\t}\n\treturn model;\n}\n\nfunction createBuiltInRuntime(env: Environment, providerId: string): StartupRuntime | undefined {\n\tif (providerId === \"anthropic\") {\n\t\tconst provider = createAnthropicProvider({ env });\n\t\treturn { provider, model: selectProviderModel(provider, providerId, env) };\n\t}\n\tif (providerId === \"openai\") {\n\t\tconst provider = createOpenAIProvider({ env });\n\t\treturn { provider, model: selectProviderModel(provider, providerId, env) };\n\t}\n\tif (providerId === \"deepseek\") {\n\t\tconst provider = createDeepSeekProvider({ env });\n\t\treturn { provider, model: selectProviderModel(provider, providerId, env) };\n\t}\n\tif (providerId === \"zhipu\") {\n\t\tconst provider = createZhipuProvider({ env });\n\t\treturn { provider, model: selectProviderModel(provider, providerId, env) };\n\t}\n\tif (providerId === \"kimi\") {\n\t\tconst provider = createKimiProvider({ env });\n\t\treturn { provider, model: selectProviderModel(provider, providerId, env) };\n\t}\n\treturn undefined;\n}\n\nfunction createConfiguredRuntime(env: Environment, configuration: StartupProviderConfiguration): StartupRuntime {\n\tif (\n\t\tconfiguration.api !== \"openai-responses\" &&\n\t\tconfiguration.api !== \"openai-chat-completions\" &&\n\t\tconfiguration.api !== \"anthropic-messages\"\n\t) {\n\t\tthrow new Error(\n\t\t\t`Unsupported API \"${configuration.api ?? \"missing\"}\" for provider \"${configuration.id}\". Expected openai-responses, openai-chat-completions, or anthropic-messages.`,\n\t\t);\n\t}\n\tif (\n\t\tconfiguration.id !== \"openai\" &&\n\t\tconfiguration.id !== \"deepseek\" &&\n\t\tconfiguration.id !== \"zhipu\" &&\n\t\tconfiguration.id !== \"kimi\" &&\n\t\tconfiguration.id !== \"anthropic\" &&\n\t\t!configuration.models\n\t) {\n\t\tthrow new Error(`${SETTINGS_PATH}: providers.${configuration.id}.models is required for a custom provider`);\n\t}\n\tconst provider =\n\t\tconfiguration.api === \"openai-chat-completions\"\n\t\t\t? createOpenAIChatCompletionsProvider({\n\t\t\t\t\tenv:\n\t\t\t\t\t\tconfiguration.id === \"zhipu\" || configuration.id === \"deepseek\" || configuration.id === \"kimi\"\n\t\t\t\t\t\t\t? env\n\t\t\t\t\t\t\t: Object.fromEntries(\n\t\t\t\t\t\t\t\t\tObject.entries(env).filter(([name]) => name !== \"OPENAI_API_KEY\" && name !== \"OPENAI_BASE_URL\"),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\tmodels: configuration.models,\n\t\t\t\t\tapiKey: resolveConfigValue(configuration.apiKey, env),\n\t\t\t\t\tbaseUrl: configuration.models ? undefined : configuration.baseUrl,\n\t\t\t\t\tproviderId: configuration.id,\n\t\t\t\t\tname: configuration.name ?? configuration.id,\n\t\t\t\t\t...(configuration.id === \"zhipu\"\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tapiKeyEnvironmentVariable: \"ZAI_API_KEY\",\n\t\t\t\t\t\t\t\tbaseUrlEnvironmentVariable: \"ZHIPU_BASE_URL\",\n\t\t\t\t\t\t\t\tdefaultBaseUrl: \"https://open.bigmodel.cn/api/coding/paas/v4\",\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: configuration.id === \"deepseek\"\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\tapiKeyEnvironmentVariable: \"DEEPSEEK_API_KEY\",\n\t\t\t\t\t\t\t\t\tbaseUrlEnvironmentVariable: \"DEEPSEEK_BASE_URL\",\n\t\t\t\t\t\t\t\t\tdefaultBaseUrl: \"https://api.deepseek.com\",\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: configuration.id === \"kimi\"\n\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\tapiKeyEnvironmentVariable: \"KIMI_API_KEY\",\n\t\t\t\t\t\t\t\t\t\tbaseUrlEnvironmentVariable: \"KIMI_BASE_URL\",\n\t\t\t\t\t\t\t\t\t\tdefaultBaseUrl: \"https://api.kimi.com/coding/v1\",\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t})\n\t\t\t: configuration.api === \"anthropic-messages\"\n\t\t\t\t? createAnthropicProvider({\n\t\t\t\t\t\tenv:\n\t\t\t\t\t\t\tconfiguration.id === \"anthropic\"\n\t\t\t\t\t\t\t\t? env\n\t\t\t\t\t\t\t\t: Object.fromEntries(\n\t\t\t\t\t\t\t\t\t\tObject.entries(env).filter(\n\t\t\t\t\t\t\t\t\t\t\t([name]) => name !== \"ANTHROPIC_API_KEY\" && name !== \"ANTHROPIC_BASE_URL\",\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\tmodels: configuration.models,\n\t\t\t\t\t\tapiKey: resolveConfigValue(configuration.apiKey, env),\n\t\t\t\t\t\tbaseUrl: configuration.models ? undefined : configuration.baseUrl,\n\t\t\t\t\t\tproviderId: configuration.id,\n\t\t\t\t\t\tname: configuration.name,\n\t\t\t\t\t})\n\t\t\t\t: configuration.id === \"deepseek\"\n\t\t\t\t\t? createDeepSeekProvider({\n\t\t\t\t\t\t\tenv,\n\t\t\t\t\t\t\tmodels: configuration.models,\n\t\t\t\t\t\t\tapiKey: resolveConfigValue(configuration.apiKey, env),\n\t\t\t\t\t\t\tbaseUrl: configuration.models ? undefined : configuration.baseUrl,\n\t\t\t\t\t\t})\n\t\t\t\t\t: configuration.id === \"zhipu\"\n\t\t\t\t\t\t? createZhipuProvider({\n\t\t\t\t\t\t\t\tenv,\n\t\t\t\t\t\t\t\tmodels: configuration.models,\n\t\t\t\t\t\t\t\tapiKey: resolveConfigValue(configuration.apiKey, env),\n\t\t\t\t\t\t\t\tbaseUrl: configuration.models ? undefined : configuration.baseUrl,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: createOpenAIProvider({\n\t\t\t\t\t\t\t\tenv:\n\t\t\t\t\t\t\t\t\tconfiguration.id === \"openai\"\n\t\t\t\t\t\t\t\t\t\t? env\n\t\t\t\t\t\t\t\t\t\t: Object.fromEntries(\n\t\t\t\t\t\t\t\t\t\t\t\tObject.entries(env).filter(([name]) => name !== \"OPENAI_API_KEY\" && name !== \"OPENAI_BASE_URL\"),\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tmodels: configuration.models,\n\t\t\t\t\t\t\t\tapiKey: resolveConfigValue(configuration.apiKey, env),\n\t\t\t\t\t\t\t\tbaseUrl: configuration.models ? undefined : configuration.baseUrl,\n\t\t\t\t\t\t\t\tproviderId: configuration.id,\n\t\t\t\t\t\t\t\tname: configuration.name,\n\t\t\t\t\t\t\t});\n\tconst model = selectProviderModel(provider, configuration.id, env);\n\treturn { provider, model };\n}\n\nexport function resolveStartupRuntime(\n\tenv: Environment,\n\tproviders: readonly StartupProviderConfiguration[],\n\tdefaults: StartupDefaults = {},\n): StartupRuntime {\n\tconst selectedProviderId =\n\t\tenv.DI_CODE_PROVIDER?.trim() || defaults.providerId || (providers.length === 1 ? providers[0]?.id : undefined);\n\tif (selectedProviderId === \"faux\") return createFauxRuntime();\n\tif (!selectedProviderId) {\n\t\tif (providers.length === 0) {\n\t\t\tthrow new Error(\"Provider is not configured. Set DI_CODE_PROVIDER or start interactive mode in a TTY.\");\n\t\t}\n\t\tthrow new Error(\"DI_CODE_PROVIDER is required when more than one provider is configured.\");\n\t}\n\tconst runtimeEnvironment =\n\t\tenv.DI_CODE_MODEL?.trim() || defaults.providerId !== selectedProviderId || !defaults.modelId\n\t\t\t? env\n\t\t\t: { ...env, DI_CODE_MODEL: defaults.modelId };\n\tconst selectedProvider = providers.find((provider) => provider.id === selectedProviderId);\n\tif (selectedProvider) return createConfiguredRuntime(runtimeEnvironment, selectedProvider);\n\tconst builtInRuntime = createBuiltInRuntime(runtimeEnvironment, selectedProviderId);\n\tif (builtInRuntime) return builtInRuntime;\n\tthrow new Error(\n\t\t`Unknown configured provider \"${selectedProviderId}\". Available providers: ${providers.map((provider) => provider.id).join(\", \")}.`,\n\t);\n}\n\nexport async function loadStartupConfiguration(\n\tcwd: string,\n\tenvironment: Environment = process.env,\n\tagentDir = join(homedir(), \".di-code\"),\n): Promise<StartupConfiguration> {\n\tconst [globalSettings, projectSettings] = await Promise.all([\n\t\treadSettingsFile(join(agentDir, SETTINGS_FILE_NAME), join(agentDir, SETTINGS_FILE_NAME)),\n\t\treadSettingsFile(join(cwd, SETTINGS_PATH), SETTINGS_PATH),\n\t]);\n\tconst settings = mergeSettings(globalSettings, projectSettings);\n\tconst requestedLocale = environment.DI_CODE_LOCALE?.trim();\n\tif (requestedLocale !== undefined && requestedLocale !== \"\" && !isLocale(requestedLocale)) {\n\t\tthrow new Error('DI_CODE_LOCALE must be \"en\" or \"zh-CN\".');\n\t}\n\n\tconst providers = Object.entries(settings.providers).map(([id, provider]) => ({\n\t\tid: requiredString(id, `providers.${id}`),\n\t\tname: provider.name,\n\t\tapi: provider.api,\n\t\tapiKey: provider.apiKey,\n\t\tbaseUrl: provider.baseUrl,\n\t\tmodels: parseModels(provider.models, `providers.${id}.models`, id, provider.api, provider.baseUrl, SETTINGS_PATH),\n\t}));\n\tconst defaults =\n\t\tsettings.defaultProvider === undefined && settings.defaultModel === undefined\n\t\t\t? undefined\n\t\t\t: { providerId: settings.defaultProvider, modelId: settings.defaultModel };\n\tconst locale = requestedLocale && isLocale(requestedLocale) ? requestedLocale : settings.locale;\n\treturn {\n\t\tenvironment,\n\t\tproviders,\n\t\t...(locale === undefined ? {} : { locale }),\n\t\t...(defaults === undefined ? {} : { defaults }),\n\t};\n}\n\nexport async function loadStartupEnvironment(\n\tcwd: string,\n\tenvironment: Environment = process.env,\n): Promise<Environment> {\n\treturn (await loadStartupConfiguration(cwd, environment)).environment;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@di-code/coding-agent",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Coding agent product layer for di-code",
5
5
  "keywords": [
6
6
  "ai-coding-agent",
@@ -52,9 +52,11 @@
52
52
  "test": "vitest run --passWithNoTests"
53
53
  },
54
54
  "dependencies": {
55
- "@di-code/agent": "0.1.4",
56
- "@di-code/ai": "0.1.4",
57
- "@di-code/tui": "0.1.4",
55
+ "@di-code/agent": "0.1.6",
56
+ "@di-code/ai": "0.1.6",
57
+ "@di-code/mcp": "0.1.6",
58
+ "@di-code/skills": "0.1.6",
59
+ "@di-code/tui": "0.1.6",
58
60
  "diff": "8.0.4",
59
61
  "highlight.js": "^10.7.3",
60
62
  "jiti": "^2.5.1"