zcode-acp-server 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. package/README.md +98 -1
  2. package/README.zh-CN.md +81 -1
  3. package/dist/backend/client.d.ts +12 -4
  4. package/dist/backend/client.d.ts.map +1 -1
  5. package/dist/backend/client.js +72 -7
  6. package/dist/backend/client.js.map +1 -1
  7. package/dist/backend/credentials.d.ts.map +1 -1
  8. package/dist/backend/credentials.js +2 -1
  9. package/dist/backend/credentials.js.map +1 -1
  10. package/dist/backend/listener.d.ts +12 -4
  11. package/dist/backend/listener.d.ts.map +1 -1
  12. package/dist/backend/listener.js +68 -12
  13. package/dist/backend/listener.js.map +1 -1
  14. package/dist/backend/types.d.ts +1 -1
  15. package/dist/backend/types.d.ts.map +1 -1
  16. package/dist/bin/quota.d.ts +54 -0
  17. package/dist/bin/quota.d.ts.map +1 -0
  18. package/dist/bin/quota.js +333 -0
  19. package/dist/bin/quota.js.map +1 -0
  20. package/dist/config/auto-compact.d.ts +23 -0
  21. package/dist/config/auto-compact.d.ts.map +1 -0
  22. package/dist/config/auto-compact.js +67 -0
  23. package/dist/config/auto-compact.js.map +1 -0
  24. package/dist/config/mcp-discovery.d.ts +34 -0
  25. package/dist/config/mcp-discovery.d.ts.map +1 -0
  26. package/dist/config/mcp-discovery.js +153 -0
  27. package/dist/config/mcp-discovery.js.map +1 -0
  28. package/dist/config/model-cache.d.ts +12 -1
  29. package/dist/config/model-cache.d.ts.map +1 -1
  30. package/dist/config/model-cache.js +30 -8
  31. package/dist/config/model-cache.js.map +1 -1
  32. package/dist/config/options.d.ts +87 -9
  33. package/dist/config/options.d.ts.map +1 -1
  34. package/dist/config/options.js +248 -45
  35. package/dist/config/options.js.map +1 -1
  36. package/dist/config/plugin-commands.d.ts +24 -0
  37. package/dist/config/plugin-commands.d.ts.map +1 -0
  38. package/dist/config/plugin-commands.js +107 -0
  39. package/dist/config/plugin-commands.js.map +1 -0
  40. package/dist/config/provider-registry.d.ts +60 -0
  41. package/dist/config/provider-registry.d.ts.map +1 -0
  42. package/dist/config/provider-registry.js +128 -0
  43. package/dist/config/provider-registry.js.map +1 -0
  44. package/dist/config/runtime-model.d.ts +54 -18
  45. package/dist/config/runtime-model.d.ts.map +1 -1
  46. package/dist/config/runtime-model.js +105 -61
  47. package/dist/config/runtime-model.js.map +1 -1
  48. package/dist/config/skill-discovery.d.ts +35 -0
  49. package/dist/config/skill-discovery.d.ts.map +1 -0
  50. package/dist/config/skill-discovery.js +188 -0
  51. package/dist/config/skill-discovery.js.map +1 -0
  52. package/dist/handlers/background-tasks.d.ts +72 -0
  53. package/dist/handlers/background-tasks.d.ts.map +1 -0
  54. package/dist/handlers/background-tasks.js +330 -0
  55. package/dist/handlers/background-tasks.js.map +1 -0
  56. package/dist/handlers/dispatch.d.ts.map +1 -1
  57. package/dist/handlers/dispatch.js +134 -22
  58. package/dist/handlers/dispatch.js.map +1 -1
  59. package/dist/handlers/extensions.d.ts +15 -0
  60. package/dist/handlers/extensions.d.ts.map +1 -1
  61. package/dist/handlers/extensions.js +43 -27
  62. package/dist/handlers/extensions.js.map +1 -1
  63. package/dist/handlers/io.d.ts +11 -2
  64. package/dist/handlers/io.d.ts.map +1 -1
  65. package/dist/handlers/io.js +51 -7
  66. package/dist/handlers/io.js.map +1 -1
  67. package/dist/handlers/server-requests.d.ts +20 -4
  68. package/dist/handlers/server-requests.d.ts.map +1 -1
  69. package/dist/handlers/server-requests.js +293 -63
  70. package/dist/handlers/server-requests.js.map +1 -1
  71. package/dist/handlers/session.d.ts +113 -10
  72. package/dist/handlers/session.d.ts.map +1 -1
  73. package/dist/handlers/session.js +876 -220
  74. package/dist/handlers/session.js.map +1 -1
  75. package/dist/handlers/slash.d.ts +14 -0
  76. package/dist/handlers/slash.d.ts.map +1 -1
  77. package/dist/handlers/slash.js +80 -6
  78. package/dist/handlers/slash.js.map +1 -1
  79. package/dist/index.js +38 -4
  80. package/dist/index.js.map +1 -1
  81. package/dist/interaction/adapter.d.ts +19 -33
  82. package/dist/interaction/adapter.d.ts.map +1 -1
  83. package/dist/interaction/adapter.js +80 -79
  84. package/dist/interaction/adapter.js.map +1 -1
  85. package/dist/lazy-sessions.d.ts +35 -0
  86. package/dist/lazy-sessions.d.ts.map +1 -0
  87. package/dist/lazy-sessions.js +98 -0
  88. package/dist/lazy-sessions.js.map +1 -0
  89. package/dist/quota/cache.d.ts +18 -0
  90. package/dist/quota/cache.d.ts.map +1 -0
  91. package/dist/quota/cache.js +32 -0
  92. package/dist/quota/cache.js.map +1 -0
  93. package/dist/quota/client.d.ts +30 -0
  94. package/dist/quota/client.d.ts.map +1 -0
  95. package/dist/quota/client.js +57 -0
  96. package/dist/quota/client.js.map +1 -0
  97. package/dist/quota/color.d.ts +58 -0
  98. package/dist/quota/color.d.ts.map +1 -0
  99. package/dist/quota/color.js +95 -0
  100. package/dist/quota/color.js.map +1 -0
  101. package/dist/quota/combined.d.ts +66 -0
  102. package/dist/quota/combined.d.ts.map +1 -0
  103. package/dist/quota/combined.js +179 -0
  104. package/dist/quota/combined.js.map +1 -0
  105. package/dist/quota/format.d.ts +105 -0
  106. package/dist/quota/format.d.ts.map +1 -0
  107. package/dist/quota/format.js +219 -0
  108. package/dist/quota/format.js.map +1 -0
  109. package/dist/quota/index.d.ts +23 -0
  110. package/dist/quota/index.d.ts.map +1 -0
  111. package/dist/quota/index.js +42 -0
  112. package/dist/quota/index.js.map +1 -0
  113. package/dist/quota/opencode-go/cache.d.ts +17 -0
  114. package/dist/quota/opencode-go/cache.d.ts.map +1 -0
  115. package/dist/quota/opencode-go/cache.js +31 -0
  116. package/dist/quota/opencode-go/cache.js.map +1 -0
  117. package/dist/quota/opencode-go/client.d.ts +28 -0
  118. package/dist/quota/opencode-go/client.d.ts.map +1 -0
  119. package/dist/quota/opencode-go/client.js +48 -0
  120. package/dist/quota/opencode-go/client.js.map +1 -0
  121. package/dist/quota/opencode-go/config.d.ts +37 -0
  122. package/dist/quota/opencode-go/config.d.ts.map +1 -0
  123. package/dist/quota/opencode-go/config.js +58 -0
  124. package/dist/quota/opencode-go/config.js.map +1 -0
  125. package/dist/quota/opencode-go/format.d.ts +36 -0
  126. package/dist/quota/opencode-go/format.d.ts.map +1 -0
  127. package/dist/quota/opencode-go/format.js +87 -0
  128. package/dist/quota/opencode-go/format.js.map +1 -0
  129. package/dist/quota/opencode-go/index.d.ts +30 -0
  130. package/dist/quota/opencode-go/index.d.ts.map +1 -0
  131. package/dist/quota/opencode-go/index.js +108 -0
  132. package/dist/quota/opencode-go/index.js.map +1 -0
  133. package/dist/quota/opencode-go/parse.d.ts +41 -0
  134. package/dist/quota/opencode-go/parse.d.ts.map +1 -0
  135. package/dist/quota/opencode-go/parse.js +75 -0
  136. package/dist/quota/opencode-go/parse.js.map +1 -0
  137. package/dist/quota/opencode-go/types.d.ts +48 -0
  138. package/dist/quota/opencode-go/types.d.ts.map +1 -0
  139. package/dist/quota/opencode-go/types.js +11 -0
  140. package/dist/quota/opencode-go/types.js.map +1 -0
  141. package/dist/quota/parse.d.ts +33 -0
  142. package/dist/quota/parse.d.ts.map +1 -0
  143. package/dist/quota/parse.js +200 -0
  144. package/dist/quota/parse.js.map +1 -0
  145. package/dist/quota/types.d.ts +72 -0
  146. package/dist/quota/types.d.ts.map +1 -0
  147. package/dist/quota/types.js +10 -0
  148. package/dist/quota/types.js.map +1 -0
  149. package/dist/server.d.ts +104 -0
  150. package/dist/server.d.ts.map +1 -1
  151. package/dist/server.js +119 -2
  152. package/dist/server.js.map +1 -1
  153. package/dist/tasks-index.d.ts +14 -4
  154. package/dist/tasks-index.d.ts.map +1 -1
  155. package/dist/tasks-index.js +145 -46
  156. package/dist/tasks-index.js.map +1 -1
  157. package/dist/translators/event-translator.d.ts +33 -0
  158. package/dist/translators/event-translator.d.ts.map +1 -1
  159. package/dist/translators/event-translator.js +101 -0
  160. package/dist/translators/event-translator.js.map +1 -1
  161. package/dist/translators/index.d.ts +1 -1
  162. package/dist/translators/index.d.ts.map +1 -1
  163. package/dist/translators/index.js +1 -1
  164. package/dist/translators/index.js.map +1 -1
  165. package/dist/translators/projection-differ.d.ts +8 -0
  166. package/dist/translators/projection-differ.d.ts.map +1 -1
  167. package/dist/translators/projection-differ.js +19 -9
  168. package/dist/translators/projection-differ.js.map +1 -1
  169. package/dist/translators/tool-helpers.d.ts +28 -0
  170. package/dist/translators/tool-helpers.d.ts.map +1 -1
  171. package/dist/translators/tool-helpers.js +104 -0
  172. package/dist/translators/tool-helpers.js.map +1 -1
  173. package/dist/translators/types.d.ts +38 -1
  174. package/dist/translators/types.d.ts.map +1 -1
  175. package/dist/translators/types.js.map +1 -1
  176. package/dist/utils.d.ts +35 -6
  177. package/dist/utils.d.ts.map +1 -1
  178. package/dist/utils.js +52 -4
  179. package/dist/utils.js.map +1 -1
  180. package/docs/ARCHITECTURE.md +96 -38
  181. package/docs/BACKLOG.md +57 -0
  182. package/docs/DEVELOPMENT.md +5 -0
  183. package/docs/PROTOCOL.md +270 -5
  184. package/docs/TROUBLESHOOTING.md +98 -14
  185. package/docs/agents/domain.md +51 -0
  186. package/docs/agents/issue-tracker.md +22 -0
  187. package/docs/agents/triage-labels.md +15 -0
  188. package/package.json +6 -5
@@ -10,29 +10,85 @@
10
10
  * reflects the new state.
11
11
  */
12
12
  import { readFileSync } from "node:fs";
13
- import { CONFIG_DISPATCH, CONFIG_META, ZCODE_CREDS_PATH } from "../utils.js";
13
+ import { CONFIG_DISPATCH, CONFIG_META, log, ZCODE_CREDS_PATH } from "../utils.js";
14
14
  import { sendSessionUpdate } from "../handlers/io.js";
15
15
  /** Read the config.json contents (UTF-8). Throws on read/parse failure. */
16
16
  function readConfig() {
17
17
  return JSON.parse(readFileSync(ZCODE_CREDS_PATH, "utf8"));
18
18
  }
19
- /** Read the model id list for the enabled provider from config.json. */
20
- export function loadProviderModels() {
19
+ /**
20
+ * Fallback defaults for when config.json is unreadable or has no enabled
21
+ * provider — keeps a freshly-installed editor functional. Must stay in sync
22
+ * with the model the app ships first in its provider list.
23
+ */
24
+ export const DEFAULT_PROVIDER_ID = "builtin:bigmodel-coding-plan";
25
+ export const DEFAULT_PROVIDER_NAME = "BigModel";
26
+ export const DEFAULT_MODEL_ID = "GLM-5.3";
27
+ /**
28
+ * Collect models from config.json for the dropdown.
29
+ *
30
+ * Builtin providers (id prefix `builtin:`) must be `enabled: true` — they
31
+ * reflect the plans the user activated in the ZCode desktop app. Custom
32
+ * (third-party) providers are included UNLESS explicitly `enabled: false`:
33
+ * the newer CLI leaves the flag unset on active third-party providers, so
34
+ * treating "absent" as enabled keeps them in the dropdown while still
35
+ * honoring an explicit disable.
36
+ */
37
+ export function loadAllModels() {
38
+ try {
39
+ const cfg = readConfig();
40
+ const out = [];
41
+ for (const [pid, p] of Object.entries(cfg.provider ?? {})) {
42
+ if (isBuiltinProvider(pid)) {
43
+ if (p?.enabled !== true)
44
+ continue;
45
+ }
46
+ else if (p?.enabled === false) {
47
+ continue;
48
+ }
49
+ const providerName = p.name ?? pid;
50
+ for (const modelId of Object.keys(p.models ?? {})) {
51
+ out.push({ providerId: pid, providerName, modelId });
52
+ }
53
+ }
54
+ if (out.length === 0) {
55
+ // Fallback: config unreadable or no enabled provider — keep the legacy
56
+ // default so a freshly-installed editor still shows something.
57
+ return [
58
+ {
59
+ providerId: DEFAULT_PROVIDER_ID,
60
+ providerName: DEFAULT_PROVIDER_NAME,
61
+ modelId: DEFAULT_MODEL_ID,
62
+ },
63
+ ];
64
+ }
65
+ return out;
66
+ }
67
+ catch {
68
+ return [
69
+ {
70
+ providerId: DEFAULT_PROVIDER_ID,
71
+ providerName: DEFAULT_PROVIDER_NAME,
72
+ modelId: DEFAULT_MODEL_ID,
73
+ },
74
+ ];
75
+ }
76
+ }
77
+ /** Look up a provider entry by id (any provider, not just enabled). */
78
+ export function findProviderConfig(providerId) {
21
79
  try {
22
80
  const cfg = readConfig();
23
- const models = cfg.provider?.["builtin:bigmodel-coding-plan"]?.models ?? {};
24
- const keys = Object.keys(models);
25
- return keys.length > 0 ? keys : ["GLM-5.2"];
81
+ return cfg.provider?.[providerId] ?? null;
26
82
  }
27
83
  catch {
28
- return ["GLM-5.2"];
84
+ return null;
29
85
  }
30
86
  }
31
- /** Read the context-window size for a model from config.json (limit.context). */
32
- export function modelContextWindow(modelId) {
87
+ /** Read the context-window size for a provider+model from config.json. */
88
+ export function modelContextWindow(providerId, modelId) {
33
89
  try {
34
90
  const cfg = readConfig();
35
- const models = cfg.provider?.["builtin:bigmodel-coding-plan"]?.models ?? {};
91
+ const models = cfg.provider?.[providerId]?.models ?? {};
36
92
  const entry = models[modelId];
37
93
  return entry?.limit?.context ?? 0;
38
94
  }
@@ -40,52 +96,169 @@ export function modelContextWindow(modelId) {
40
96
  return 0;
41
97
  }
42
98
  }
43
- /** Build the ACP SessionModeState ({currentModeId, availableModes}). */
99
+ /** Builtin providerIds are prefixed with `builtin:` (e.g. `builtin:bigmodel`). */
100
+ export function isBuiltinProvider(providerId) {
101
+ return providerId.startsWith("builtin:");
102
+ }
103
+ /**
104
+ * Encode a provider+model pair into a configOption `value` string.
105
+ *
106
+ * Builtin providers encode as the bare modelId (legacy form, keeps the dropdown
107
+ * clean for the common case). Third-party providers encode as
108
+ * `providerId\modelId` — `\` is unambiguous because providerIds (UUIDs) and
109
+ * modelIds (`/`-separated) never contain it.
110
+ */
111
+ export function formatModelValue(providerId, modelId) {
112
+ if (isBuiltinProvider(providerId))
113
+ return modelId;
114
+ return `${providerId}\\${modelId}`;
115
+ }
116
+ /**
117
+ * Parse a configOption `value` back into { providerId, modelId }.
118
+ *
119
+ * A value without `\` is a builtin modelId (legacy form) → resolve to the first
120
+ * enabled builtin provider. A value with `\` is a third-party provider+model.
121
+ */
122
+ export function parseModelValue(value) {
123
+ const idx = value.indexOf("\\");
124
+ if (idx < 0) {
125
+ // Builtin plain modelId — resolve to the first enabled builtin provider
126
+ // (falling back to the legacy default if none configured).
127
+ const firstBuiltin = loadAllModels().find((m) => isBuiltinProvider(m.providerId));
128
+ return {
129
+ providerId: firstBuiltin?.providerId ?? DEFAULT_PROVIDER_ID,
130
+ modelId: value,
131
+ };
132
+ }
133
+ return { providerId: value.slice(0, idx), modelId: value.slice(idx + 1) };
134
+ }
135
+ /** Build the ACP SessionModeState ({currentModeId, availableModes}).
136
+ * zcodeSid null = pending session (session/new not yet materialized) — skip
137
+ * the backend read and return defaults. */
44
138
  export async function buildModes(server, zcodeSid) {
45
139
  let currentMode = "yolo";
46
- try {
47
- const read = await sessionRead(server, zcodeSid);
48
- const settings = (read.settings ?? {});
49
- const modeSet = settings.mode ?? {};
50
- currentMode = modeSet.current ?? currentMode;
51
- }
52
- catch {
53
- // keep default
140
+ if (zcodeSid !== null) {
141
+ try {
142
+ const read = await sessionRead(server, zcodeSid);
143
+ const settings = (read.settings ?? {});
144
+ const modeSet = settings.mode ?? {};
145
+ currentMode = modeSet.current ?? currentMode;
146
+ }
147
+ catch {
148
+ // keep default
149
+ }
54
150
  }
55
151
  return {
56
152
  currentModeId: currentMode,
57
- availableModes: ["plan", "build", "edit", "yolo"].map((m) => ({ id: m, name: capitalize(m) })),
153
+ // ZCode 3.3.0 mode enum: plan/build/edit/yolo/auto. settings.mode only
154
+ // carries `current` (no `available` list, unlike thoughtLevel), so the full
155
+ // enum is advertised here.
156
+ availableModes: ["plan", "build", "edit", "yolo", "auto"].map((m) => ({
157
+ id: m,
158
+ name: capitalize(m),
159
+ })),
58
160
  };
59
161
  }
60
- /** Build the ACP configOptions array (3 items: model/mode/thought). */
162
+ /**
163
+ * Canonical display order for thought-level tokens across models
164
+ * (GLM-5.3: low/high/max; GLM-5-Turbo: enabled/off; others may differ).
165
+ * Unknown tokens keep their config order after the known ones.
166
+ */
167
+ const THOUGHT_ORDER = ["low", "medium", "high", "xhigh", "max", "ultra", "enabled", "disabled", "off"];
168
+ export function orderThoughtVariants(variants) {
169
+ const known = THOUGHT_ORDER.filter((t) => variants.includes(t));
170
+ const extra = variants.filter((t) => !THOUGHT_ORDER.includes(t));
171
+ return [...known, ...extra].map((t) => ({ value: t, name: t }));
172
+ }
173
+ /** Build the ACP configOptions array (3 items: model/mode/thought).
174
+ * zcodeSid null = pending session — skip the backend read and use defaults;
175
+ * mode defaults to "yolo" (the mode session/create hardcodes) so the dropdown
176
+ * matches the mode indicator for a fresh session. */
61
177
  export async function buildConfigOptions(server, zcodeSid) {
62
- let currentModel = "GLM-5.2";
63
- let currentMode = "build";
64
- let currentThought = "high";
178
+ let currentProviderId = "";
179
+ let currentModelId = DEFAULT_MODEL_ID;
180
+ let currentMode = zcodeSid === null ? "yolo" : "build";
181
+ // Matches the enabled provider's default reasoning variants (GLM-5.3:
182
+ // max/high/low, default max). Pending sessions show this until the real
183
+ // session/read thoughtLevel arrives.
184
+ let currentThought = "max";
65
185
  let thoughtOptions = null;
66
- try {
67
- const read = await sessionRead(server, zcodeSid);
68
- const settings = (read.settings ?? {});
69
- const modeSet = settings.mode ?? {};
70
- currentMode = modeSet.current ?? currentMode;
71
- const modelSet = settings.model ?? {};
72
- const cur = modelSet.current ?? {};
73
- if (cur.modelId)
74
- currentModel = cur.modelId;
75
- const tlSet = settings.thoughtLevel ?? {};
76
- currentThought = tlSet.current ?? currentThought;
77
- const tlAvail = tlSet.available ?? [];
78
- if (tlAvail.length > 0) {
79
- thoughtOptions = tlAvail.map((a) => ({ value: a.value, name: a.label ?? a.value }));
186
+ if (zcodeSid === null) {
187
+ // Pending session no backend to read yet, but the thought vocabulary
188
+ // is per model and the runtime's own source of truth is the enabled
189
+ // provider's models[].reasoning.variants in the local config. Advertise
190
+ // THAT for the default model instead of a hardcoded list: a client that
191
+ // relays the options into a picker (Multica's effort selector) would
192
+ // otherwise offer tokens the runtime rejects ("nothink" was fiction,
193
+ // "low" was missing).
194
+ const cur = loadAllModels()[0];
195
+ if (cur) {
196
+ // The advertised current model follows the dropdown's leading entry
197
+ // (the enabled provider's first model — what the runtime actually
198
+ // starts sessions with) rather than the legacy hardcoded "GLM-5.2".
199
+ // ACP clients skip a requested model switch when it equals the
200
+ // advertised current value, so a stale fiction silently pinned the
201
+ // wrong model whenever the requested id happened to match it.
202
+ currentProviderId = cur.providerId;
203
+ currentModelId = cur.modelId;
204
+ try {
205
+ const cfg = readConfig();
206
+ const m = cfg.provider?.[cur.providerId]?.models?.[cur.modelId];
207
+ const reasoning = m?.reasoning;
208
+ const variants = reasoning?.variants;
209
+ if (reasoning?.enabled !== false && variants && variants.length > 0) {
210
+ thoughtOptions = orderThoughtVariants(variants);
211
+ currentThought = reasoning.defaultVariant ?? variants[0];
212
+ }
213
+ }
214
+ catch {
215
+ // unreadable config — the static fallback below applies
216
+ }
80
217
  }
81
218
  }
82
- catch {
83
- // keep defaults
219
+ if (zcodeSid !== null) {
220
+ try {
221
+ const read = await sessionRead(server, zcodeSid);
222
+ const settings = (read.settings ?? {});
223
+ const modeSet = settings.mode ?? {};
224
+ currentMode = modeSet.current ?? currentMode;
225
+ const modelSet = settings.model ?? {};
226
+ // settings.model.current is { providerId, modelId, variant? } — read BOTH so
227
+ // we can disambiguate same-named models across providers.
228
+ const cur = modelSet.current ?? {};
229
+ if (cur.providerId)
230
+ currentProviderId = cur.providerId;
231
+ if (cur.modelId)
232
+ currentModelId = cur.modelId;
233
+ const tlSet = settings.thoughtLevel ?? {};
234
+ // `current` is absent right after session/create — fall back to the
235
+ // backend's defaultLevel (the level the session actually runs at).
236
+ currentThought = tlSet.current ?? tlSet.defaultLevel ?? currentThought;
237
+ const tlAvail = tlSet.available ?? [];
238
+ if (tlAvail.length > 0) {
239
+ thoughtOptions = tlAvail.map((a) => ({ value: a.value, name: a.label ?? a.value }));
240
+ }
241
+ }
242
+ catch {
243
+ // keep defaults
244
+ }
84
245
  }
85
- // Model options: config.json is authoritative (settings.model.available is incomplete).
86
- let modelOptions = loadProviderModels().map((k) => ({ value: k, name: k }));
246
+ // currentValue encodes provider+model so the switch handler can locate the
247
+ // right provider (and its apiKey). Fall back to the first enabled provider
248
+ // when settings omits providerId (legacy sessions).
249
+ const currentModel = formatModelValue(currentProviderId || loadAllModels()[0]?.providerId || DEFAULT_PROVIDER_ID, currentModelId);
250
+ // Model options: config.json enabled providers are authoritative. Builtin
251
+ // models show as the bare modelId (clean dropdown for the common case);
252
+ // third-party models prefix the provider name so they're distinguishable.
253
+ let modelOptions = loadAllModels().map((m) => ({
254
+ value: formatModelValue(m.providerId, m.modelId),
255
+ name: isBuiltinProvider(m.providerId) ? m.modelId : `${m.providerName} › ${m.modelId}`,
256
+ }));
87
257
  if (!modelOptions.some((o) => o.value === currentModel)) {
88
- modelOptions = [{ value: currentModel, name: currentModel }, ...modelOptions];
258
+ // The current model isn't from an enabled provider (e.g. the session was
259
+ // created with a now-disabled provider). Append it so the dropdown still
260
+ // shows the active selection.
261
+ modelOptions = [{ value: currentModel, name: currentModelId }, ...modelOptions];
89
262
  }
90
263
  if (!thoughtOptions)
91
264
  thoughtOptions = [...CONFIG_META.thought.options];
@@ -109,7 +282,12 @@ export async function buildConfigOptions(server, zcodeSid) {
109
282
  {
110
283
  id: "thought",
111
284
  name: CONFIG_META.thought.name,
112
- category: "thought",
285
+ // Category thought_level (not "thought") so ACP clients recognise the
286
+ // option as the reasoning-effort selector: the shared matchers in
287
+ // editors and orchestrators (e.g. Multica's acpEffortOptionIDs) key on
288
+ // id/category "effort"/"thought_level". The id stays "thought" — it is
289
+ // what session/set_config_option addresses.
290
+ category: "thought_level",
113
291
  type: "select",
114
292
  currentValue: currentThought,
115
293
  options: thoughtOptions,
@@ -141,7 +319,11 @@ export async function setConfigOption(server, zcodeSid, configId, value) {
141
319
  return { kind: configId, currentValue: value };
142
320
  }
143
321
  /** Emit a config_option_update (+ current_mode_update for mode) after a change.
144
- * Returns the rebuilt options so the caller can include them in the response. */
322
+ * Returns the rebuilt options so the caller can include them in the response.
323
+ *
324
+ * For model switches, also emit a usage_update with the NEW model's context
325
+ * window (from config.json) so the editor's context bar refreshes immediately
326
+ * instead of waiting for the next turn's UsageDelta. */
145
327
  export async function emitConfigOptionUpdate(server, cx, acpSid, zcodeSid, kind) {
146
328
  const options = await buildConfigOptions(server, zcodeSid);
147
329
  await sendSessionUpdate(cx, acpSid, {
@@ -155,6 +337,27 @@ export async function emitConfigOptionUpdate(server, cx, acpSid, zcodeSid, kind)
155
337
  currentModeId: modes.currentModeId,
156
338
  });
157
339
  }
340
+ if (kind === "model") {
341
+ // Refresh the context bar: the backend's projection.contextWindow lags
342
+ // behind a model switch, so read the new model's limit from config.json.
343
+ try {
344
+ const read = await sessionRead(server, zcodeSid);
345
+ const proj = (read.projection ?? {});
346
+ const used = proj.contextUsed || proj.totalTokenCount || 0;
347
+ // The rebuilt options[0] (model) currentValue is the just-switched value.
348
+ const modelOpt = options.find((o) => o.id === "model");
349
+ const { providerId, modelId } = parseModelValue(String(modelOpt?.currentValue ?? ""));
350
+ const size = modelContextWindow(providerId, modelId);
351
+ await sendSessionUpdate(cx, acpSid, {
352
+ sessionUpdate: "usage_update",
353
+ used,
354
+ size,
355
+ });
356
+ }
357
+ catch (e) {
358
+ log(`options: usage_update after model switch failed (${e instanceof Error ? e.message : String(e)})`);
359
+ }
360
+ }
158
361
  return options;
159
362
  }
160
363
  // ---------- helpers ----------
@@ -1 +1 @@
1
- {"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/config/options.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/config/options.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Plugin command discovery — reads enabled plugins from `~/.zcode/cli/config.json`
3
+ * and scans their `commands/*.md` frontmatter to build slash-command entries.
4
+ *
5
+ * Plugin commands (e.g. `/code-review`) are resolved by the ZCode backend's
6
+ * `customCommandPromptResolver` before the model sees them, so they work in
7
+ * app-server mode without bridge interception.
8
+ */
9
+ /** A slash-command entry compatible with `sendAvailableCommands`. */
10
+ export interface PluginCommandEntry {
11
+ name: string;
12
+ description: string;
13
+ input?: {
14
+ hint: string;
15
+ };
16
+ }
17
+ /**
18
+ * Read enabled plugin commands from `~/.zcode/cli/config.json` + the plugin
19
+ * cache directory. Returns entries suitable for `available_commands_update`.
20
+ *
21
+ * Best-effort: failures are logged and swallowed (returns []).
22
+ */
23
+ export declare function loadPluginCommands(): PluginCommandEntry[];
24
+ //# sourceMappingURL=plugin-commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-commands.d.ts","sourceRoot":"","sources":["../../src/config/plugin-commands.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAyBH,qEAAqE;AACrE,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1B;AA+BD;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,kBAAkB,EAAE,CAyDzD"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Plugin command discovery — reads enabled plugins from `~/.zcode/cli/config.json`
3
+ * and scans their `commands/*.md` frontmatter to build slash-command entries.
4
+ *
5
+ * Plugin commands (e.g. `/code-review`) are resolved by the ZCode backend's
6
+ * `customCommandPromptResolver` before the model sees them, so they work in
7
+ * app-server mode without bridge interception.
8
+ */
9
+ import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
10
+ import { homedir } from "node:os";
11
+ import path from "node:path";
12
+ import { compareVersions, log } from "../utils.js";
13
+ /** Path to the ZCode CLI config (plugins, skills, mcp). */
14
+ const CLI_CONFIG_PATH = path.join(homedir(), ".zcode", "cli", "config.json");
15
+ /** Root of the plugin cache directory. */
16
+ const PLUGIN_CACHE_DIR = path.join(homedir(), ".zcode", "cli", "plugins", "cache");
17
+ /** Parse YAML-like frontmatter from a plugin command .md file. */
18
+ function parseFrontmatter(content) {
19
+ const fm = {};
20
+ const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
21
+ if (!match)
22
+ return fm;
23
+ const lines = match[1].split(/\r?\n/);
24
+ for (const line of lines) {
25
+ const idx = line.indexOf(":");
26
+ if (idx <= 0)
27
+ continue;
28
+ const key = line.slice(0, idx).trim();
29
+ // Strip surrounding quotes from the value (YAML scalar style).
30
+ let val = line.slice(idx + 1).trim();
31
+ if ((val.startsWith('"') && val.endsWith('"')) ||
32
+ (val.startsWith("'") && val.endsWith("'"))) {
33
+ val = val.slice(1, -1);
34
+ }
35
+ if (key)
36
+ fm[key] = val;
37
+ }
38
+ return fm;
39
+ }
40
+ /**
41
+ * Read enabled plugin commands from `~/.zcode/cli/config.json` + the plugin
42
+ * cache directory. Returns entries suitable for `available_commands_update`.
43
+ *
44
+ * Best-effort: failures are logged and swallowed (returns []).
45
+ */
46
+ export function loadPluginCommands() {
47
+ if (!existsSync(CLI_CONFIG_PATH) || !existsSync(PLUGIN_CACHE_DIR))
48
+ return [];
49
+ try {
50
+ const cfg = JSON.parse(readFileSync(CLI_CONFIG_PATH, "utf8"));
51
+ const enabled = cfg.plugins?.enabledPlugins ?? {};
52
+ const entries = [];
53
+ // enabledPlugins keys are "pluginName@marketplace"
54
+ for (const [pluginKey, enabledFlag] of Object.entries(enabled)) {
55
+ if (!enabledFlag)
56
+ continue;
57
+ const atIdx = pluginKey.indexOf("@");
58
+ if (atIdx <= 0)
59
+ continue;
60
+ const pluginName = pluginKey.slice(0, atIdx);
61
+ const marketplace = pluginKey.slice(atIdx + 1);
62
+ // Scan all versions of this plugin in the cache (use latest found).
63
+ const marketDir = path.join(PLUGIN_CACHE_DIR, marketplace);
64
+ if (!existsSync(marketDir))
65
+ continue;
66
+ const pluginDir = path.join(marketDir, pluginName);
67
+ if (!existsSync(pluginDir))
68
+ continue;
69
+ // Find the latest version directory.
70
+ let latestVersion = "";
71
+ for (const entry of readdirSync(pluginDir)) {
72
+ const vDir = path.join(pluginDir, entry);
73
+ if (statSync(vDir).isDirectory() && compareVersions(entry, latestVersion) > 0) {
74
+ latestVersion = entry;
75
+ }
76
+ }
77
+ if (!latestVersion)
78
+ continue;
79
+ const commandsDir = path.join(pluginDir, latestVersion, "commands");
80
+ if (!existsSync(commandsDir))
81
+ continue;
82
+ for (const file of readdirSync(commandsDir)) {
83
+ if (!file.endsWith(".md"))
84
+ continue;
85
+ const cmdPath = path.join(commandsDir, file);
86
+ const content = readFileSync(cmdPath, "utf8");
87
+ const fm = parseFrontmatter(content);
88
+ const name = file.replace(/\.md$/, "");
89
+ const description = fm["description"] ?? "";
90
+ if (!description)
91
+ continue;
92
+ const entry = { name, description };
93
+ const hint = fm["argument-hint"];
94
+ if (hint)
95
+ entry.input = { hint };
96
+ entries.push(entry);
97
+ }
98
+ }
99
+ log(`plugin-commands: loaded ${entries.length} plugin command(s)`);
100
+ return entries;
101
+ }
102
+ catch (e) {
103
+ log(`plugin-commands: load failed (${e instanceof Error ? e.message : String(e)})`);
104
+ return [];
105
+ }
106
+ }
107
+ //# sourceMappingURL=plugin-commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-commands.js","sourceRoot":"","sources":["../../src/config/plugin-commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Build a provider-registry payload for `workspace/updateProviderRegistry`.
3
+ *
4
+ * The V4 backend doesn't auto-load providers from config.json — the host must
5
+ * push them via this RPC after `session/create`, otherwise third-party
6
+ * providers fail with `provider_not_configured` (misclassified as a network
7
+ * error after turn-retry exhausts). ZCode app does this from its
8
+ * ModelProviderService; the bridge mirrors it by reading config.json directly.
9
+ *
10
+ * Provider element schema (from the backend's `j7t` converter in zcode.cjs):
11
+ * { providerId, apiKey?, apiKeyRequired?, apiFormat?, baseURL?, headers?,
12
+ * kind?, label?, models?, providerOptions?, source? }
13
+ * `apiKey` is a discriminated union `{source:"inline", value:"<key>"}` — a
14
+ * bare string is rejected. `apiFormat` maps from `kind`:
15
+ * anthropic → "anthropic-messages", openai-compatible → "openai-chat-completions".
16
+ */
17
+ /** A model entry in config.json (`provider.<id>.models.<modelId>`). */
18
+ export interface ModelEntry {
19
+ name?: string;
20
+ limit?: {
21
+ context?: number;
22
+ output?: number;
23
+ };
24
+ reasoning?: {
25
+ enabled?: boolean;
26
+ variants?: string[];
27
+ defaultVariant?: string;
28
+ };
29
+ }
30
+ /** Registry payload for `workspace/updateProviderRegistry`. */
31
+ export interface ProviderRegistryPayload {
32
+ providers: ReadonlyArray<Record<string, unknown>>;
33
+ generatedAt: number;
34
+ revision: string;
35
+ }
36
+ /**
37
+ * Build a single model element from a config.json model entry.
38
+ *
39
+ * Beyond `{modelId}`, the backend's schema accepts label / contextWindow /
40
+ * maxOutputTokens / reasoning. `reasoning` is the important one: without it
41
+ * the backend falls back to the apiFormat's default thought levels (a 2-state
42
+ * enabled/disabled for anthropic-messages), losing the provider's real
43
+ * variants (e.g. max/high/low) — the session then shows a wrong thought-level
44
+ * dropdown. config.json's `variants`/`defaultVariant` map to the protocol's
45
+ * `levels`/`defaultLevel`.
46
+ *
47
+ * Exported: runtime-model.ts reuses it for the `runtimeModel` overlay — both
48
+ * paths must carry identical model definitions or the overlay (resume /
49
+ * setModel) silently downgrades the session back to the 2-state default.
50
+ */
51
+ export declare function buildModelElement(modelId: string, m: ModelEntry): Record<string, unknown>;
52
+ /**
53
+ * Build the registry payload from ALL providers in config.json.
54
+ *
55
+ * Unlike `loadAllModels` (dropdown, enabled-only), the registry pushes every
56
+ * configured provider so the backend recognises any of them when a session
57
+ * switches to it. The backend applies its own enable/availability rules.
58
+ */
59
+ export declare function buildProviderRegistry(): ProviderRegistryPayload;
60
+ //# sourceMappingURL=provider-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-registry.d.ts","sourceRoot":"","sources":["../../src/config/provider-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,uEAAuE;AACvE,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,SAAS,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACjF;AAgBD,+DAA+D;AAC/D,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAClD,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAUD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAezF;AAmCD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,IAAI,uBAAuB,CAe/D"}