@chatcode/chatcode-cli 3.0.4-rc.1 → 3.0.4-rc.3

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 (136) hide show
  1. package/README.i18n.yaml +2 -2
  2. package/README.md +2 -0
  3. package/README.zh.md +2 -0
  4. package/lib/{command-errors-BkCHTQHj.js → command-errors-BJ_ZWzUU.js} +12 -12
  5. package/lib/{command-trees-5HFyC5sI.js → command-trees-C9b7-bci.js} +2 -2
  6. package/lib/{component-identity-De91VHwW.js → component-identity-Jb1DYjke.js} +3 -3
  7. package/lib/{dist-CsDWUvQ4.js → dist-w_sIm4VD.js} +231 -231
  8. package/lib/{extension-events-CdYCRP0o.js → extension-events-DKX4LXOd.js} +26 -26
  9. package/lib/{frames-DOX-Jgk8.js → frames-B89znn_0.js} +4 -4
  10. package/lib/{host-access-Bk4xps5E.js → host-access-CMg6rsWt.js} +1 -1
  11. package/lib/{keymap-CJ1kvLR2.js → keymap-CrC4pSNH.js} +2 -2
  12. package/lib/{plugin-XR7ncbnW.js → plugin-CmyMCGfb.js} +1651 -1365
  13. package/lib/{scenes-CAmWncZD.js → scenes-Cil9RnwU.js} +3 -3
  14. package/lib/{settings-sections-CakcvBv9.js → settings-sections-jVCqXwdH.js} +3 -3
  15. package/lib/{statusBarSettings-BPPS_Usm.js → statusBarSettings-DNoBH3Cq.js} +3 -3
  16. package/lib/{supports-color-DyChQwlI.js → supports-color-CcW-FGjr.js} +2 -2
  17. package/lib/{themes-OjcUpZzw.js → themes-BdgeY3It.js} +12 -12
  18. package/lib/tui-compat-command-trees.js +1 -1
  19. package/lib/tui-compat-extensions.js +3 -3
  20. package/lib/tui-compat-plugin-host.js +5 -5
  21. package/lib/tui-compat-scenes.js +1 -1
  22. package/lib/tui-compat-settings-sections.js +1 -1
  23. package/lib/tui-compat-working-activity.js +4 -4
  24. package/lib/tui-compat-workspaces.js +1 -1
  25. package/lib/tui-compat.js +5 -5
  26. package/lib/{workspaces-XY7UdfXp.js → workspaces-DOatJRYr.js} +2 -2
  27. package/package.json +30 -29
  28. package/runtime/manifest.json +2 -2
  29. package/runtime/node_modules/@deepseek-ai/dsh-agent-default-model/lib/index.js +118 -22
  30. package/runtime/node_modules/@deepseek-ai/dsh-agent-default-model/lib/types/index.d.ts +20 -3
  31. package/runtime/node_modules/@deepseek-ai/dsh-api-remotes/lib/client.js +113 -39
  32. package/runtime/node_modules/@deepseek-ai/dsh-api-remotes/lib/index.js +4 -0
  33. package/runtime/node_modules/@deepseek-ai/dsh-api-remotes/lib/types/remote-events.d.ts +3 -0
  34. package/runtime/node_modules/@deepseek-ai/dsh-api-remotes/lib/types/remote-events.js +1 -0
  35. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/index.js +173 -34
  36. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/typert.host.js +48 -28
  37. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/typert.remote-client.js +24 -19
  38. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/agent.d.ts +9 -1
  39. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/agent.js +36 -6
  40. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/archived-session-gate.js +1 -1
  41. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/catalog.js +4 -1
  42. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/sessions/service.d.ts +1 -1
  43. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/commands.d.ts +2 -2
  44. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/commands.js +24 -8
  45. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/index.d.ts +4 -3
  46. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/index.js +31 -14
  47. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/list.d.ts +6 -0
  48. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/list.js +89 -4
  49. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/remote-events.d.ts +1 -1
  50. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/types.d.ts +18 -1
  51. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/client.js +30 -0
  52. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/index.js +83 -2
  53. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/typert.host.js +104 -11
  54. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/typert.remote-client.d.ts +5 -1
  55. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/typert.remote-client.js +78 -11
  56. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/client/model.d.ts +14 -1
  57. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/client/model.js +17 -0
  58. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/client/service.d.ts +15 -0
  59. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/client/service.js +12 -0
  60. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/commands.d.ts +13 -1
  61. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/commands.js +44 -2
  62. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/index.d.ts +13 -1
  63. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/index.js +22 -0
  64. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/types.d.ts +17 -0
  65. package/runtime/node_modules/@deepseek-ai/dsh-app-boot/lib/index.js +2 -1
  66. package/runtime/node_modules/@deepseek-ai/dsh-atomic-write/lib/index.js +167 -44
  67. package/runtime/node_modules/@deepseek-ai/dsh-atomic-write/lib/types/index.d.ts +14 -6
  68. package/runtime/node_modules/@deepseek-ai/dsh-atomic-write/lib/types/linux-lock.d.ts +18 -0
  69. package/runtime/node_modules/@deepseek-ai/dsh-atomic-write/lib/types/windows-lock.d.ts +7 -0
  70. package/runtime/node_modules/@deepseek-ai/dsh-client-hmr/lib/client.js +931 -7
  71. package/runtime/node_modules/@deepseek-ai/dsh-client-hmr/lib/index.js +57 -19
  72. package/runtime/node_modules/@deepseek-ai/dsh-client-hmr/lib/types/client/index.d.ts +5 -2
  73. package/runtime/node_modules/@deepseek-ai/dsh-client-hmr/lib/types/config.d.ts +12 -0
  74. package/runtime/node_modules/@deepseek-ai/dsh-client-hmr/lib/types/events.d.ts +4 -4
  75. package/runtime/node_modules/@deepseek-ai/dsh-client-hmr/lib/types/index.d.ts +3 -8
  76. package/runtime/node_modules/@deepseek-ai/dsh-client-hmr/package.json +6 -2
  77. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-commands/lib/client.js +10 -0
  78. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-deliverables/lib/types/client/present-open.d.ts +1 -1
  79. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-model-selection/lib/client.js +8 -4
  80. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings-account/lib/client.js +2 -2
  81. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings-general/lib/client.js +1 -1
  82. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-sidebar/lib/client.js +1 -1
  83. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/client.js +1917 -206
  84. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/ArchivedSessions.d.ts +13 -0
  85. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/contract/slots.d.ts +4 -0
  86. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/locales.d.ts +40 -0
  87. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/recent.d.ts +11 -0
  88. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/rows/RecentList.d.ts +15 -0
  89. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/rows/Rows.d.ts +6 -1
  90. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/session-actions/DeleteSession.d.ts +24 -0
  91. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/stores.d.ts +2 -2
  92. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/tree.d.ts +15 -13
  93. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/package.json +3 -1
  94. package/runtime/node_modules/@deepseek-ai/dsh-commands/lib/index.js +16 -0
  95. package/runtime/node_modules/@deepseek-ai/dsh-commands/lib/typert.host.js +7 -3
  96. package/runtime/node_modules/@deepseek-ai/dsh-commands/lib/typert.remote-client.js +6 -2
  97. package/runtime/node_modules/@deepseek-ai/dsh-commands/lib/types/index.js +20 -0
  98. package/runtime/node_modules/@deepseek-ai/dsh-commands/lib/types/types.d.ts +5 -0
  99. package/runtime/node_modules/@deepseek-ai/dsh-cordis-client-runner/lib/client.js +5 -2
  100. package/runtime/node_modules/@deepseek-ai/dsh-llm-deepseek/lib/types/adapter.d.ts +1 -1
  101. package/runtime/node_modules/@deepseek-ai/dsh-llm-deepseek/lib/types/config.d.ts +3 -3
  102. package/runtime/node_modules/@deepseek-ai/dsh-llm-deepseek-account/lib/types/config.d.ts +2 -2
  103. package/runtime/node_modules/@deepseek-ai/dsh-llm-deepseek-api-key/lib/types/config.d.ts +2 -2
  104. package/runtime/node_modules/@deepseek-ai/dsh-schedule/lib/index.js +4 -0
  105. package/runtime/node_modules/@deepseek-ai/dsh-schedule/lib/typert.host.js +5 -5
  106. package/runtime/node_modules/@deepseek-ai/dsh-schedule/lib/typert.remote-client.js +5 -5
  107. package/runtime/node_modules/@deepseek-ai/dsh-schedule/lib/types/index.js +5 -0
  108. package/runtime/node_modules/@deepseek-ai/dsh-session/lib/types/index.d.ts +21 -0
  109. package/runtime/node_modules/@deepseek-ai/dsh-session-persistence/lib/index.js +12 -0
  110. package/runtime/node_modules/@deepseek-ai/dsh-session-persistence/lib/types/index.d.ts +15 -0
  111. package/runtime/node_modules/@deepseek-ai/dsh-session-persistence-jsonl/lib/index.js +95 -2
  112. package/runtime/node_modules/@deepseek-ai/dsh-session-persistence-jsonl/lib/types/index.d.ts +3 -1
  113. package/runtime/node_modules/@deepseek-ai/dsh-session-projection-cache/lib/index.js +25 -1
  114. package/runtime/node_modules/@deepseek-ai/dsh-session-projection-cache/lib/types/index.d.ts +1 -0
  115. package/runtime/node_modules/@deepseek-ai/dsh-session-projection-cache/package.json +2 -1
  116. package/runtime/node_modules/@deepseek-ai/dsh-session-query/lib/index.js +13 -0
  117. package/runtime/node_modules/@deepseek-ai/dsh-session-query/lib/types/observation.d.ts +5 -0
  118. package/runtime/node_modules/@deepseek-ai/dsh-session-query-sqlite/lib/index.js +26 -0
  119. package/runtime/node_modules/@deepseek-ai/dsh-session-query-sqlite/package.json +2 -1
  120. package/runtime/node_modules/@deepseek-ai/dsh-storage-domain/lib/index.js +5 -1
  121. package/runtime/node_modules/@deepseek-ai/dsh-storage-domain/lib/types/domain.d.ts +2 -2
  122. package/runtime/node_modules/@deepseek-ai/dsh-subagent/lib/types/control.d.ts +1 -1
  123. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/index.js +106 -56
  124. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/config.d.ts +2 -2
  125. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/index.d.ts +2 -1
  126. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/tianti/config.d.ts +4 -2
  127. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/tools.d.ts +2 -2
  128. package/runtime/node_modules/@deepseek-ai/dsh-tianti/package.json +2 -0
  129. package/runtime/node_modules/@deepseek-ai/dsh-tool-cordis/lib/types/api-catalog.js +104 -13
  130. package/runtime/node_modules/@deepseek-ai/dsh-workspace/lib/index.js +215 -4
  131. package/runtime/node_modules/@deepseek-ai/dsh-workspace/lib/invariant.js +6 -1
  132. package/runtime/node_modules/@deepseek-ai/dsh-workspace/lib/types/index.d.ts +31 -0
  133. package/runtime/node_modules/@deepseek-ai/dsh-workspace/lib/types/index.js +219 -2
  134. package/runtime/node_modules/@deepseek-ai/dsh-workspace/lib/types/spec.d.ts +4 -0
  135. package/runtime/node_modules/@deepseek-ai/dsh-workspace/lib/types/spec.js +4 -0
  136. package/scripts/launch.mjs +8 -0
@@ -1,8 +1,9 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
- import { join } from "node:path";
2
+ import { mkdir } from "node:fs/promises";
3
+ import { dirname, join } from "node:path";
3
4
  import { Service } from "@deepseek-ai/cordis";
4
5
  import z from "@deepseek-ai/schemastery";
5
- import { writeFileAtomic } from "@deepseek-ai/dsh-atomic-write";
6
+ import { withFileLock, writeFileAtomic } from "@deepseek-ai/dsh-atomic-write";
6
7
  import { resolveChatCodeCliHome } from "@deepseek-ai/dsh-home-paths";
7
8
  import { ReasoningEffortId } from "@deepseek-ai/dsh-llm";
8
9
  //#region lib/types/index.js
@@ -17,12 +18,12 @@ function selection(settings) {
17
18
  };
18
19
  }
19
20
  /** Parse one product-wide model preference without accepting partial records. */
20
- function sharedPreference(path) {
21
+ function sharedPreference(path, warn) {
21
22
  try {
22
23
  const parsed = JSON.parse(readFileSync(path, "utf8"));
23
- if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) return void 0;
24
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("expected a model preference object");
24
25
  const record = parsed;
25
- if (typeof record.provider !== "string" || record.provider.length === 0 || typeof record.model !== "string" || record.model.length === 0) return void 0;
26
+ if (typeof record.provider !== "string" || record.provider.length === 0 || typeof record.model !== "string" || record.model.length === 0) throw new Error("expected non-empty provider and model IDs");
26
27
  const route = selection({
27
28
  provider: record.provider,
28
29
  model: record.model,
@@ -33,7 +34,8 @@ function sharedPreference(path) {
33
34
  selection: route,
34
35
  ...displayName === "" ? {} : { displayName }
35
36
  };
36
- } catch (_error) {
37
+ } catch (error) {
38
+ if (error.code !== "ENOENT") warn(`Cannot read model preference at ${path}: ${String(error)}`);
37
39
  return;
38
40
  }
39
41
  }
@@ -48,6 +50,9 @@ var AgentDefaultModelConfig = class extends Service {
48
50
  saves = Promise.resolve();
49
51
  sharedPath;
50
52
  shared;
53
+ displayName;
54
+ awaitingDefault = false;
55
+ allowCatalogDefault = false;
51
56
  static Config = z.object({
52
57
  provider: z.string().required().volatile(),
53
58
  model: z.string().required().volatile(),
@@ -58,16 +63,47 @@ var AgentDefaultModelConfig = class extends Service {
58
63
  this.ownerContext = ownerContext;
59
64
  this.config = config;
60
65
  this.sharedPath = process.env[PRODUCT_VERSION_ENV]?.trim() ? join(resolveChatCodeCliHome(), SHARED_MODEL_FILENAME) : void 0;
61
- if (this.sharedPath !== void 0) this.shared = sharedPreference(existsSync(this.sharedPath) ? this.sharedPath : join(resolveChatCodeCliHome(), "tui", SHARED_MODEL_FILENAME))?.selection;
66
+ if (this.sharedPath !== void 0) {
67
+ const stored = sharedPreference(existsSync(this.sharedPath) ? this.sharedPath : join(resolveChatCodeCliHome(), "tui", SHARED_MODEL_FILENAME), (message) => {
68
+ ownerContext.logger.warn(message);
69
+ });
70
+ const reasoningEffort = config.reasoningEffort.get();
71
+ this.shared = stored?.selection ?? selection({
72
+ provider: config.provider.get(),
73
+ model: config.model.get(),
74
+ ...reasoningEffort === void 0 ? {} : { reasoningEffort }
75
+ });
76
+ this.awaitingDefault = stored === void 0 && (this.shared.provider === "" || this.shared.model === "");
77
+ this.allowCatalogDefault = stored === void 0;
78
+ this.displayName = stored?.displayName;
79
+ }
62
80
  ownerContext.inject(["settings"], (child) => {
63
81
  child.effect(() => child.settings.configure({ auto: false }, ownerContext.fiber));
64
82
  });
83
+ ownerContext.effect(() => () => this.saves);
65
84
  }
66
85
  /**
67
86
  * Read the current default model selection.
87
+ * A first launch without a valid preference adopts the first complete Config
88
+ * default when it arrives; that process-local choice then stays cached.
68
89
  * @returns a detached provider, model, and optional reasoning selection.
69
90
  */
70
91
  currentSelection() {
92
+ if (this.awaitingDefault) {
93
+ const provider = this.config.provider.get();
94
+ const model = this.config.model.get();
95
+ if (provider === "" || model === "") return {
96
+ provider: "",
97
+ model: ""
98
+ };
99
+ const reasoningEffort = this.config.reasoningEffort.get();
100
+ this.shared = selection({
101
+ provider,
102
+ model,
103
+ ...reasoningEffort === void 0 ? {} : { reasoningEffort }
104
+ });
105
+ this.awaitingDefault = false;
106
+ }
71
107
  if (this.shared !== void 0) return { ...this.shared };
72
108
  const reasoningEffort = this.config.reasoningEffort.get();
73
109
  return selection({
@@ -76,28 +112,84 @@ var AgentDefaultModelConfig = class extends Service {
76
112
  ...reasoningEffort === void 0 ? {} : { reasoningEffort }
77
113
  });
78
114
  }
79
- /** Read the latest shared display name without changing this process's model selection.
115
+ /** Whether this product uses a process-local selection initialized from Home at startup.
116
+ * @returns true for the integrated ChatCode CLI and Web profiles.
117
+ */
118
+ usesSharedPreference() {
119
+ return this.sharedPath !== void 0;
120
+ }
121
+ /** Resolve the cached route against the live catalog without reading or writing preferences.
122
+ * A first launch without a valid preference may adopt an advertised fallback
123
+ * until its first available default is resolved. Saved or initialized choices
124
+ * never switch implicitly. Catalog errors preserve the candidate for retry.
125
+ * @returns the exact available selection, an unverified candidate, or an empty provider/model pair.
126
+ */
127
+ async resolveSelection() {
128
+ const route = this.currentSelection();
129
+ if (!this.usesSharedPreference()) return route;
130
+ const llm = this.ctx.get("llm");
131
+ if (llm === void 0) return route;
132
+ const cached = this.shared;
133
+ const providers = llm.listProviders();
134
+ let routeModels = [];
135
+ if (providers.some((provider) => provider.id === route.provider)) {
136
+ try {
137
+ routeModels = await llm.listModels(route.provider);
138
+ } catch (_error) {
139
+ if (this.shared !== cached) return this.resolveSelection();
140
+ return route;
141
+ }
142
+ if (this.shared !== cached) return this.resolveSelection();
143
+ if (routeModels.some((model) => model.id === route.model)) {
144
+ this.allowCatalogDefault = false;
145
+ return route;
146
+ }
147
+ }
148
+ if (!this.allowCatalogDefault) return {
149
+ provider: "",
150
+ model: ""
151
+ };
152
+ for (const provider of providers) {
153
+ const models = provider.id === route.provider ? routeModels : await llm.listModels(provider.id).catch(() => []);
154
+ if (this.shared !== cached) return this.resolveSelection();
155
+ const model = models[0];
156
+ if (model === void 0) continue;
157
+ this.shared = {
158
+ provider: provider.id,
159
+ model: model.id
160
+ };
161
+ this.awaitingDefault = false;
162
+ this.allowCatalogDefault = false;
163
+ return { ...this.shared };
164
+ }
165
+ return {
166
+ provider: "",
167
+ model: ""
168
+ };
169
+ }
170
+ /** Read this process's cached display name without observing another process's saves.
80
171
  * @returns The saved provider/model/name tuple, or undefined for missing or invalid name metadata.
81
172
  */
82
173
  sharedDisplayName() {
83
174
  if (this.sharedPath === void 0) return void 0;
84
- const stored = sharedPreference(this.sharedPath);
85
- if (stored?.displayName === void 0) return void 0;
175
+ if (this.displayName === void 0) return void 0;
176
+ const route = this.currentSelection();
86
177
  return {
87
- provider: stored.selection.provider,
88
- model: stored.selection.model,
89
- name: stored.displayName
178
+ provider: route.provider,
179
+ model: route.model,
180
+ name: this.displayName
90
181
  };
91
182
  }
92
183
  /**
93
184
  * Save the complete default model selection to the shared ChatCode Home file,
94
185
  * or the owning profile entry in other deployments. Saves commit in submission
95
186
  * order; a failed save rejects its caller without blocking later saves.
96
- * A shared save also retains an available catalog name; metadata failures do not reject the route save.
187
+ * A shared save uses the caller's already resolved catalog name without an additional lookup.
97
188
  * @param next - resolved selection accepted by an entry point.
189
+ * @param name - optional display name from the entry point's catalog.
98
190
  * @returns fulfillment after the preference or optional profile write settles.
99
191
  */
100
- async saveSelection(next) {
192
+ async saveSelection(next, name) {
101
193
  const entry = this.ownerContext.fiber.entry;
102
194
  const editor = this.ctx.get("configEditor");
103
195
  const config = {
@@ -110,20 +202,24 @@ var AgentDefaultModelConfig = class extends Service {
110
202
  if (this.sharedPath !== void 0) {
111
203
  const previous = this.sharedDisplayName();
112
204
  let displayName = previous?.provider === config.provider && previous.model === config.model ? previous.name : void 0;
113
- const llm = this.ctx.get("llm");
114
- if (llm !== void 0) try {
115
- const name = (await llm.listModels(config.provider)).find((model) => model.id === config.model)?.name.trim();
116
- if (name !== void 0 && name !== "" && (name !== config.model || displayName === void 0)) displayName = name;
117
- } catch (_error) {}
205
+ if (name?.trim()) displayName = name.trim();
118
206
  const preference = {
119
207
  ...config,
120
208
  ...displayName === void 0 ? {} : { displayName }
121
209
  };
122
- await writeFileAtomic(this.sharedPath, `${JSON.stringify(preference, null, 2)}\n`, {
210
+ const path = this.sharedPath;
211
+ await mkdir(dirname(path), {
212
+ recursive: true,
213
+ mode: 448
214
+ });
215
+ await withFileLock(path, () => writeFileAtomic(path, `${JSON.stringify(preference, null, 2)}\n`, {
123
216
  mode: 384,
124
217
  dirMode: 448
125
- });
218
+ }));
126
219
  this.shared = selection(config);
220
+ this.displayName = displayName;
221
+ this.awaitingDefault = false;
222
+ this.allowCatalogDefault = false;
127
223
  } else if (entry !== void 0 && editor !== void 0) await editor.edit(entry, () => config);
128
224
  });
129
225
  this.saves = saved.catch(() => {});
@@ -28,6 +28,9 @@ export declare class AgentDefaultModelConfig extends Service {
28
28
  private saves;
29
29
  private readonly sharedPath;
30
30
  private shared;
31
+ private displayName;
32
+ private awaitingDefault;
33
+ private allowCatalogDefault;
31
34
  static Config: z<Schemastery.ObjectS<NoInfer<{
32
35
  provider: z<string, string, "volatile-defined">;
33
36
  model: z<string, string, "volatile-defined">;
@@ -40,10 +43,23 @@ export declare class AgentDefaultModelConfig extends Service {
40
43
  constructor(ownerContext: Context, config: Config);
41
44
  /**
42
45
  * Read the current default model selection.
46
+ * A first launch without a valid preference adopts the first complete Config
47
+ * default when it arrives; that process-local choice then stays cached.
43
48
  * @returns a detached provider, model, and optional reasoning selection.
44
49
  */
45
50
  currentSelection(): ModelSelection;
46
- /** Read the latest shared display name without changing this process's model selection.
51
+ /** Whether this product uses a process-local selection initialized from Home at startup.
52
+ * @returns true for the integrated ChatCode CLI and Web profiles.
53
+ */
54
+ usesSharedPreference(): boolean;
55
+ /** Resolve the cached route against the live catalog without reading or writing preferences.
56
+ * A first launch without a valid preference may adopt an advertised fallback
57
+ * until its first available default is resolved. Saved or initialized choices
58
+ * never switch implicitly. Catalog errors preserve the candidate for retry.
59
+ * @returns the exact available selection, an unverified candidate, or an empty provider/model pair.
60
+ */
61
+ resolveSelection(): Promise<ModelSelection>;
62
+ /** Read this process's cached display name without observing another process's saves.
47
63
  * @returns The saved provider/model/name tuple, or undefined for missing or invalid name metadata.
48
64
  */
49
65
  sharedDisplayName(): {
@@ -55,11 +71,12 @@ export declare class AgentDefaultModelConfig extends Service {
55
71
  * Save the complete default model selection to the shared ChatCode Home file,
56
72
  * or the owning profile entry in other deployments. Saves commit in submission
57
73
  * order; a failed save rejects its caller without blocking later saves.
58
- * A shared save also retains an available catalog name; metadata failures do not reject the route save.
74
+ * A shared save uses the caller's already resolved catalog name without an additional lookup.
59
75
  * @param next - resolved selection accepted by an entry point.
76
+ * @param name - optional display name from the entry point's catalog.
60
77
  * @returns fulfillment after the preference or optional profile write settles.
61
78
  */
62
- saveSelection(next: ModelSelection): Promise<void>;
79
+ saveSelection(next: ModelSelection, name?: string): Promise<void>;
63
80
  }
64
81
  export default AgentDefaultModelConfig;
65
82
  //# sourceMappingURL=index.d.ts.map