@lucascouts/claude-agent-acp-plus 0.27.0 → 0.29.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.
package/dist/ultracode.js CHANGED
@@ -1,103 +1,236 @@
1
1
  /**
2
- * The "Ultracode" entry of the Effort picker.
2
+ * Ultracode — an independent, session-scoped boolean option.
3
3
  *
4
- * **Ultracode is not a sixth effort level, and reading it as one produces the
5
- * wrong control.** Claude Code's VS Code extension models it as a boolean that
6
- * turns on two things at once — `xhigh` effort *and* standing dynamic-workflow
7
- * orchestration — and its own tooltip says so: `"Ultracode - xhigh +
8
- * workflows"`. Its five real levels are `low` `medium` `high` `xhigh` `max`;
9
- * Ultracode is drawn as one extra notch past the last of them, styled
10
- * differently, and selecting any ordinary level clears it.
4
+ * **What it is.** The SDK's `Settings.ultracode` is *"standing
5
+ * dynamic-workflow orchestration at any effort level"*, session-scoped and
6
+ * applied through `apply_flag_settings`. It is not an effort level and it does
7
+ * not imply one: the CLI (`/effort ultracode on|off`, "any effort level, this
8
+ * session only") and the VS Code extension (a switch in the effort popover)
9
+ * both model it as a toggle beside effort. An earlier version of this module
10
+ * followed an older extension tooltip ("xhigh + workflows") and drew it as a
11
+ * notch in the effort select that forced `xhigh`; that silently raised the
12
+ * effort of a session started with `ultracode: true`, cleared it on any effort
13
+ * pick, and lost it on a model switch (PARITY-REPORT §21.2).
11
14
  *
12
- * ACP has no compound control to carry that, so the adapter projects it the way
13
- * the extension's UI reads rather than the way its state is stored: one more
14
- * entry in the `effort` select. The compound stays here, in one module, instead
15
- * of being spread across the three places `acp-agent.ts` applies effort.
15
+ * **The wire contract** (`applyFlagSettings`, unchanged SDK 0.3.285..0.3.299):
16
+ * - `ultracode: true|false` turns it on or off and leaves effort alone;
17
+ * - an `effortLevel` change sent WITHOUT the key turns it off;
18
+ * - `null` resets it to off.
19
+ * Hence the two payload rules below: the toggle sends `{ultracode:true}` or
20
+ * `{ultracode:null}`, and every effort change re-sends `ultracode:true` while
21
+ * the intent is on — and never `null`.
16
22
  *
17
- * The SDK carries both halves and names the channel: `Settings.ultracode` is
18
- * *"xhigh effort plus standing dynamic-workflow orchestration. Session-scoped —
19
- * typically provided via --settings or the apply_flag_settings control
20
- * request"*. `apply_flag_settings` is already how the effort option is applied,
21
- * so no new transport is involved.
23
+ * **Intent is not availability.** The CLI keeps the request and computes "in
24
+ * effect = requested and available", where available means workflows are
25
+ * enabled and the model supports `xhigh`. The adapter mirrors that: the
26
+ * session holds the intent, the option is shown only while available, and a
27
+ * model switch never drops the intent. The CLI reports both through the
28
+ * `get_settings` control request (`applied.{ultracode, ultracodeRequested,
29
+ * ultracodeAvailable}`), which the SDK runtime exposes as `Query.getSettings()`
30
+ * but `sdk.d.ts` does not declare — {@link readUltracodeState} wraps it.
22
31
  *
23
32
  * Kept self-contained — no import from `acp-agent.ts` — for the reason
24
- * `thinking-option.ts` and `rewind-command.ts` state: that file is ~9,900 lines
25
- * and moves upstream almost daily, so every coupling to it is paid again at
26
- * each sync.
33
+ * `thinking-option.ts` and `rewind-command.ts` state: that file is ~10,000
34
+ * lines and moves upstream almost daily, so every coupling to it is paid again
35
+ * at each sync.
27
36
  */
28
- /** Value of the synthetic "Ultracode" entry in the effort picker. It is a
29
- * reserved sentinel: no `EffortLevel` is spelled this way, so it cannot
30
- * collide with a level the SDK reports in `supportedEffortLevels`. */
31
- export const ULTRACODE_OPTION_VALUE = "ultracode";
32
- /** Display name of that entry, matching the extension's own label. */
37
+ /** Config option id. */
38
+ export const ULTRACODE_CONFIG_ID = "ultracode";
39
+ /** Display name, matching the CLI's and the extension's label. */
33
40
  export const ULTRACODE_OPTION_NAME = "Ultracode";
34
- /** The effort level Ultracode implies. Not configurable: the extension hardcodes
35
- * `xhigh` in `enableUltracode()`, and the SDK's own description of the setting
36
- * names the same level. A different level here would silently mean something
37
- * else than it does in the reference client. */
41
+ const ULTRACODE_DESCRIPTION = "Run dynamic workflows on every task";
42
+ /** Select-fallback values for clients without boolean config options. The
43
+ * same spelling Fast mode uses, so one client-side mapping serves both. */
44
+ export const ULTRACODE_ON = "on";
45
+ export const ULTRACODE_OFF = "off";
46
+ /** The effort level the model must support for Ultracode to be available.
47
+ * Availability only: Ultracode never SETS this level. */
38
48
  export const ULTRACODE_EFFORT_LEVEL = "xhigh";
49
+ /** The value the old effort-select notch carried. Accepted for one release
50
+ * from clients that still send it (see {@link isLegacyUltracodeEffort}). */
51
+ export const LEGACY_ULTRACODE_EFFORT_VALUE = "ultracode";
39
52
  /**
40
- * Whether the Ultracode entry may be offered, under the same two conditions the
41
- * extension checks in its own `ultracodeAvailable`:
53
+ * The fallback availability check, used until (or instead of) the CLI's own
54
+ * `applied.ultracodeAvailable`:
42
55
  *
43
- * 1. workflows are not disabled — Ultracode *is* the workflow half, so offering
44
- * it where `disableWorkflows` is set would advertise something that cannot
45
- * happen;
46
- * 2. the current model supports `xhigh` — Ultracode has no meaning on a model
47
- * that cannot reach the level it implies.
56
+ * 1. workflows are not disabled — Ultracode *is* workflow orchestration;
57
+ * 2. the current model supports `xhigh`.
48
58
  *
49
- * Both are read rather than assumed: an unknown settings shape leaves
50
- * `disableWorkflows` undefined, which is *not* `true`, so the gate opens — the
51
- * same direction the extension's `=== !0` comparison takes.
59
+ * Partial by nature: the CLI also checks managed settings, org policy,
60
+ * `enableWorkflows` and `CLAUDE_CODE_DISABLE_WORKFLOWS`. An absent
61
+ * `disableWorkflows` opens the gate, the same direction the extension's
62
+ * `=== !0` comparison takes.
52
63
  */
53
64
  export function isUltracodeAvailable(supportedEffortLevels, settings) {
54
65
  if (settings?.disableWorkflows === true)
55
66
  return false;
56
67
  return supportedEffortLevels.includes(ULTRACODE_EFFORT_LEVEL);
57
68
  }
58
- /** Whether a picker value denotes Ultracode rather than a plain effort level. */
59
- export function isUltracodeValue(value) {
60
- return value === ULTRACODE_OPTION_VALUE;
69
+ /** Build the option: a native boolean for clients that opted in, an on/off
70
+ * select otherwise (the ACP boolean-config-option RFD makes that a MUST). */
71
+ export function createUltracodeConfigOption(requested, useBooleanOption) {
72
+ const base = {
73
+ id: ULTRACODE_CONFIG_ID,
74
+ name: ULTRACODE_OPTION_NAME,
75
+ description: ULTRACODE_DESCRIPTION,
76
+ category: "model_config",
77
+ };
78
+ if (useBooleanOption) {
79
+ return { ...base, type: "boolean", currentValue: requested };
80
+ }
81
+ return {
82
+ ...base,
83
+ type: "select",
84
+ currentValue: requested ? ULTRACODE_ON : ULTRACODE_OFF,
85
+ options: [
86
+ { value: ULTRACODE_ON, name: "On" },
87
+ { value: ULTRACODE_OFF, name: "Off" },
88
+ ],
89
+ };
90
+ }
91
+ /** The option for a resolved state, or `undefined` while unavailable. */
92
+ export function ultracodeConfigOption(state) {
93
+ if (!state?.available)
94
+ return undefined;
95
+ return createUltracodeConfigOption(state.requested, state.useBooleanOption);
96
+ }
97
+ /**
98
+ * Put the option where it belongs in an existing list — right after `effort`
99
+ * (after `model` when the model has no effort option), before `fast` — or
100
+ * remove it when `next` is undefined. Used when a background readback changes
101
+ * availability without a full rebuild.
102
+ */
103
+ export function placeUltracodeOption(options, next) {
104
+ const rest = options.filter((o) => o.id !== ULTRACODE_CONFIG_ID);
105
+ if (!next)
106
+ return rest;
107
+ let anchor = rest.findIndex((o) => o.id === "effort");
108
+ if (anchor < 0)
109
+ anchor = rest.findIndex((o) => o.id === "model");
110
+ const at = anchor < 0 ? rest.length : anchor + 1;
111
+ return [...rest.slice(0, at), next, ...rest.slice(at)];
112
+ }
113
+ /** Resolve the requested value from `session/set_config_option`: a native
114
+ * boolean, or the on/off select-fallback strings. */
115
+ export function resolveUltracodeRequested(params) {
116
+ const value = params.value;
117
+ if (typeof value === "boolean")
118
+ return value;
119
+ if (value === ULTRACODE_ON)
120
+ return true;
121
+ if (value === ULTRACODE_OFF)
122
+ return false;
123
+ throw new Error(`Invalid value for config option ${ULTRACODE_CONFIG_ID}: ${String(value)}`);
124
+ }
125
+ /** The toggle's payload. Off is an explicit `null`: `undefined` is dropped by
126
+ * JSON transport, and the SDK only clears a flag on `null`. */
127
+ export function ultracodeTogglePayload(requested) {
128
+ return { ultracode: requested ? true : null };
61
129
  }
62
130
  /**
63
- * The `apply_flag_settings` payload for an effort selection, Ultracode included.
131
+ * The `apply_flag_settings` payload for an effort change — a user pick, the
132
+ * model-switch fallback, the initial effort, or a recreate's replay.
64
133
  *
65
- * **The `null` is the load-bearing part.** The SDK shallow-merges flag settings
66
- * and only clears a key when an explicit `null` arrives — `undefined` is dropped
67
- * by JSON transport and leaves the previous value standing. So every selection
68
- * has to say something about `ultracode`, not just the one that turns it on:
69
- * without the clear, picking `High` after Ultracode would lower the effort and
70
- * leave workflow orchestration running, which is a state no picker entry names.
71
- * The same reasoning applies to `effortLevel` — this function absorbed the older
72
- * `toSdkEffortLevel` helper for exactly that reason: both keys are decided in
73
- * one place, so neither can be forgotten on a path the other takes.
134
+ * An `effortLevel` change sent without `ultracode` turns Ultracode off, so the
135
+ * key rides along whenever the intent is on. It is never sent as `null` here:
136
+ * an effort change is not a request to turn Ultracode off.
74
137
  *
75
- * @param value the picker value — `"default"`, an `EffortLevel`, or the
76
- * Ultracode sentinel. `undefined` means the option is absent for this model.
138
+ * @param value the effort select's value — `"default"`, an `EffortLevel`, or
139
+ * `undefined` when the model has no effort option.
77
140
  */
78
- export function ultracodeFlagSettings(value) {
79
- if (isUltracodeValue(value)) {
80
- return { effortLevel: ULTRACODE_EFFORT_LEVEL, ultracode: true };
81
- }
82
- return {
83
- effortLevel: value === undefined || value === "default" ? null : value,
84
- ultracode: null,
85
- };
141
+ export function effortFlagSettings(value, ultracodeRequested) {
142
+ const effortLevel = value === undefined || value === "default" ? null : value;
143
+ return ultracodeRequested ? { effortLevel, ultracode: true } : { effortLevel };
144
+ }
145
+ /** Whether an effort value is the retired Ultracode notch. Clients that saved
146
+ * it get `{effortLevel:'xhigh', ultracode:true}` for one release. */
147
+ export function isLegacyUltracodeEffort(value) {
148
+ return value === LEGACY_ULTRACODE_EFFORT_VALUE;
86
149
  }
87
150
  /**
88
- * The picker value to display, given the persisted effort level and whether the
89
- * Ultracode flag is on.
151
+ * Read `applied.{ultracodeRequested, ultracodeAvailable}` through the SDK's
152
+ * untyped `Query.getSettings()`.
153
+ *
154
+ * Structural, never trusting: an SDK without the method, a rejected request,
155
+ * or a response without `applied` all resolve to `undefined`, and the caller
156
+ * keeps the heuristic. Never rejects.
90
157
  *
91
- * The flag wins over the level, and only when it is *available*: a session that
92
- * carries `ultracode: true` from settings while the current model cannot reach
93
- * `xhigh` must not show an entry the picker is not rendering. The extension
94
- * reaches the same state through `adoptAppliedEffort`, which reads
95
- * `applied.ultracode` first and falls back to inferring it from `xhigh`; we do
96
- * not infer, because `xhigh` alone is a legitimate selection that is not
97
- * Ultracode, and guessing would silently turn workflows on in the label.
158
+ * **Call it in the background, never inline.** Control requests are
159
+ * serialized and queue ahead of interrupt and close (upstream #1216), and on a
160
+ * fresh session the CLI does not service them until the first turn.
161
+ */
162
+ export async function readUltracodeState(query, onError) {
163
+ const getSettings = query?.getSettings;
164
+ if (typeof getSettings !== "function")
165
+ return undefined;
166
+ let response;
167
+ try {
168
+ response = await getSettings.call(query);
169
+ }
170
+ catch (error) {
171
+ onError?.(error);
172
+ return undefined;
173
+ }
174
+ const applied = response?.applied;
175
+ if (typeof applied !== "object" || applied === null)
176
+ return undefined;
177
+ const { ultracodeRequested, ultracodeAvailable } = applied;
178
+ const readback = {};
179
+ if (typeof ultracodeRequested === "boolean")
180
+ readback.requested = ultracodeRequested;
181
+ if (typeof ultracodeAvailable === "boolean")
182
+ readback.available = ultracodeAvailable;
183
+ return readback.requested === undefined && readback.available === undefined
184
+ ? undefined
185
+ : readback;
186
+ }
187
+ /** Rebuild the option in place from the session's state. */
188
+ export function refreshUltracodeOption(session, useBooleanOption) {
189
+ session.configOptions = placeUltracodeOption(session.configOptions, ultracodeConfigOption({
190
+ available: session.ultracodeAvailable,
191
+ requested: session.ultracodeRequested,
192
+ useBooleanOption,
193
+ }));
194
+ }
195
+ /** Toggle the intent. Applies first, then records — a rejected control
196
+ * request leaves the session and its option untouched, as Fast mode does. */
197
+ export async function applyUltracodeToggle(session, requested, useBooleanOption) {
198
+ await session.query.applyFlagSettings(ultracodeTogglePayload(requested));
199
+ session.ultracodeRequested = requested;
200
+ refreshUltracodeOption(session, useBooleanOption);
201
+ }
202
+ /**
203
+ * The one-release migration for clients that still send the retired notch:
204
+ * `effort = "ultracode"` becomes `{effortLevel:'xhigh', ultracode:true}`.
205
+ * Returns `false`, sending nothing, when this model's effort select does not
206
+ * offer `xhigh` — the caller then rejects the value like any other.
98
207
  */
99
- export function effortOptionValue(effortLevel, ultracode) {
100
- if (ultracode?.available && ultracode.enabled)
101
- return ULTRACODE_OPTION_VALUE;
102
- return effortLevel;
208
+ export async function applyLegacyUltracodeEffort(session, useBooleanOption) {
209
+ const effort = session.configOptions.find((o) => o.id === "effort");
210
+ const offersXhigh = effort?.type === "select" &&
211
+ effort.options.some((o) => "value" in o && o.value === ULTRACODE_EFFORT_LEVEL);
212
+ if (!offersXhigh)
213
+ return false;
214
+ await session.query.applyFlagSettings(effortFlagSettings(ULTRACODE_EFFORT_LEVEL, true));
215
+ session.ultracodeRequested = true;
216
+ session.configOptions = session.configOptions.map((o) => o.id === "effort" && o.type === "select" ? { ...o, currentValue: ULTRACODE_EFFORT_LEVEL } : o);
217
+ refreshUltracodeOption(session, useBooleanOption);
218
+ return true;
219
+ }
220
+ /**
221
+ * Fold a CLI readback into the session. Availability is always taken; the
222
+ * intent only when `seedIntent` (session start — a model switch keeps the
223
+ * intent it has). Returns whether the option the client sees changed, i.e.
224
+ * whether a `config_option_update` is owed.
225
+ */
226
+ export function applyUltracodeReadback(session, readback, seedIntent, useBooleanOption) {
227
+ const before = JSON.stringify(session.configOptions.find((o) => o.id === ULTRACODE_CONFIG_ID));
228
+ if (readback.available !== undefined)
229
+ session.ultracodeAvailable = readback.available;
230
+ if (seedIntent && readback.requested !== undefined) {
231
+ session.ultracodeRequested = readback.requested;
232
+ }
233
+ refreshUltracodeOption(session, useBooleanOption);
234
+ const after = JSON.stringify(session.configOptions.find((o) => o.id === ULTRACODE_CONFIG_ID));
235
+ return before !== after;
103
236
  }
@@ -1 +1 @@
1
- {"version":3,"file":"usage-markdown.d.ts","sourceRoot":"","sources":["../src/usage-markdown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AAKxF;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,OAAQ,CAAC;AA6DjD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,0BAA0B,GAAG,IAAI,CAOpF;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAU1E;AA0OD,wEAAwE;AACxE,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,0BAA0B,GAAG,MAAM,CAS7E;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,CACjC,KAAK,EACL,2DAA2D,CAC5D,CAAC;AAEF,0DAA0D;AAC1D,MAAM,MAAM,mBAAmB,GAAG;IAAE,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,CAAC;AAQvE;;;;;;;;;GASG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,gBAAgB,EACvB,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAwDxB"}
1
+ {"version":3,"file":"usage-markdown.d.ts","sourceRoot":"","sources":["../src/usage-markdown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AAKxF;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,OAAQ,CAAC;AA6DjD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,0BAA0B,GAAG,IAAI,CAOpF;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAU1E;AAmSD,wEAAwE;AACxE,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,0BAA0B,GAAG,MAAM,CAS7E;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,CACjC,KAAK,EACL,2DAA2D,CAC5D,CAAC;AAEF,0DAA0D;AAC1D,MAAM,MAAM,mBAAmB,GAAG;IAAE,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,CAAC;AAQvE;;;;;;;;;GASG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,gBAAgB,EACvB,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAwDxB"}
@@ -227,8 +227,65 @@ function appendLimit(lines, label, window) {
227
227
  }
228
228
  /** How many MCP servers one contribution table lists. */
229
229
  const TOP_CONTRIBUTIONS = 3;
230
+ /**
231
+ * Labels for the usage patterns (`behaviors[].key`) the pinned SDK types
232
+ * define, worded as Claude Code's own `/usage` dialog words them (CLI 2.1.285:
233
+ * "41% of your usage hit a >100k-token cache miss"). A key not listed here — a
234
+ * newer CLI adds them ahead of the SDK types — renders from its own name, so it
235
+ * shows without a code change.
236
+ */
237
+ const BEHAVIOR_LABELS = {
238
+ cache_miss: "Hit a >100k-token cache miss",
239
+ long_context: "At >150k context",
240
+ subagent_heavy: "Subagent-heavy sessions",
241
+ high_parallel: "While 4+ sessions ran in parallel",
242
+ cron: "Sessions active for 8+ hours",
243
+ };
244
+ /** `max_effort` -> "Max effort", escaped: the key is the CLI's, not ours. */
245
+ function behaviorLabel(key) {
246
+ const known = BEHAVIOR_LABELS[key];
247
+ if (known !== undefined)
248
+ return known;
249
+ const words = key.replace(/_+/g, " ").trim();
250
+ return escapeMarkdown(words.charAt(0).toUpperCase() + words.slice(1));
251
+ }
252
+ /**
253
+ * A period's usage patterns, read defensively: the schema does not validate
254
+ * `behaviors[]`, so a report from a CLI that reshaped it still renders
255
+ * everything else. An entry with no usable key or share is skipped, and so is
256
+ * one with no share at all — the CLI sends every pattern it knows, most at 0%.
257
+ */
258
+ function readBehaviors(period) {
259
+ const raw = period?.behaviors;
260
+ if (!Array.isArray(raw))
261
+ return [];
262
+ const rows = [];
263
+ for (const entry of raw) {
264
+ if (typeof entry !== "object" || entry === null)
265
+ continue;
266
+ const { key, pct, count } = entry;
267
+ if (typeof key !== "string" || key.trim() === "")
268
+ continue;
269
+ if (typeof pct !== "number" || !Number.isFinite(pct) || pct <= 0)
270
+ continue;
271
+ rows.push({
272
+ key,
273
+ pct,
274
+ count: typeof count === "number" && Number.isFinite(count) && count >= 0 ? count : null,
275
+ });
276
+ }
277
+ return rows.sort((a, b) => b.pct - a.pct);
278
+ }
230
279
  function appendContributions(lines, label, period) {
231
280
  lines.push("", `**${label}** \u00b7 ${period.request_count} requests \u00b7 ${period.session_count} sessions`);
281
+ const behaviors = readBehaviors(period);
282
+ if (behaviors.length > 0) {
283
+ lines.push("", "| Usage pattern | Usage | Requests |", "|:--|--:|--:|");
284
+ for (const behavior of behaviors) {
285
+ const bar = usageBar(normalizeUtilization(behavior.pct) ?? 0);
286
+ lines.push(`| ${behaviorLabel(behavior.key)} | \`${bar}\` ${behavior.pct}% | ${behavior.count ?? "\u2014"} |`);
287
+ }
288
+ }
232
289
  if (period.mcp_servers.length === 0) {
233
290
  return;
234
291
  }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.27.0",
6
+ "version": "0.29.0",
7
7
  "description": "Claude Code in Zed and other ACP clients with the VS Code extension's UX — multi-select questions, refusal consent, live quota windows, background tasks, Ultracode effort and session notices. Fork of claude-agent-acp.",
8
8
  "main": "dist/lib.js",
9
9
  "types": "dist/lib.d.ts",