zidane 5.6.7 → 5.6.8

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 (59) hide show
  1. package/dist/{agent-D70rr6Uk.d.ts → agent-CZEvtmJk.d.ts} +45 -2
  2. package/dist/agent-CZEvtmJk.d.ts.map +1 -0
  3. package/dist/chat.d.ts +261 -5
  4. package/dist/chat.d.ts.map +1 -1
  5. package/dist/chat.js +3 -3
  6. package/dist/{index-BjwwNjQd.d.ts → index-BBH6XWFt.d.ts} +2 -2
  7. package/dist/{index-BjwwNjQd.d.ts.map → index-BBH6XWFt.d.ts.map} +1 -1
  8. package/dist/{index-8mn3PIaa.d.ts → index-Cf-131kQ.d.ts} +2 -2
  9. package/dist/index-Cf-131kQ.d.ts.map +1 -0
  10. package/dist/index.d.ts +3 -3
  11. package/dist/index.js +7 -7
  12. package/dist/{login-Btpliwct.js → login-CwLWX6vP.js} +17 -37
  13. package/dist/login-CwLWX6vP.js.map +1 -0
  14. package/dist/{mcp-ngMS0S6N.js → mcp-Wzf0qxaj.js} +120 -26
  15. package/dist/mcp-Wzf0qxaj.js.map +1 -0
  16. package/dist/mcp.d.ts +1 -1
  17. package/dist/mcp.js +1 -1
  18. package/dist/{messages-B5k4DAXy.js → messages-BfmXLDT4.js} +56 -2
  19. package/dist/messages-BfmXLDT4.js.map +1 -0
  20. package/dist/{presets-BXmWG3kd.js → presets-DAA0NaK_.js} +2 -2
  21. package/dist/{presets-BXmWG3kd.js.map → presets-DAA0NaK_.js.map} +1 -1
  22. package/dist/presets.d.ts +2 -2
  23. package/dist/presets.js +1 -1
  24. package/dist/{providers-CaJE2ToS.js → providers-C_ahnRBS.js} +2 -2
  25. package/dist/{providers-CaJE2ToS.js.map → providers-C_ahnRBS.js.map} +1 -1
  26. package/dist/providers.d.ts +1 -1
  27. package/dist/providers.js +2 -2
  28. package/dist/restate.d.ts +1 -1
  29. package/dist/session/sqlite.d.ts +1 -1
  30. package/dist/{session-BoEW_wCR.js → session-PUzXZlG6.js} +2 -2
  31. package/dist/{session-BoEW_wCR.js.map → session-PUzXZlG6.js.map} +1 -1
  32. package/dist/session.d.ts +1 -1
  33. package/dist/session.js +2 -2
  34. package/dist/skills.d.ts +2 -2
  35. package/dist/{tools-FerA0zSl.js → tools-B9aQpZVx.js} +6 -4
  36. package/dist/tools-B9aQpZVx.js.map +1 -0
  37. package/dist/tools.d.ts +2 -2
  38. package/dist/tools.js +1 -1
  39. package/dist/{transcript-anchors-C5Sp1Snh.d.ts → transcript-anchors-CoSZb1PE.d.ts} +42 -4
  40. package/dist/transcript-anchors-CoSZb1PE.d.ts.map +1 -0
  41. package/dist/tui.d.ts +47 -14
  42. package/dist/tui.d.ts.map +1 -1
  43. package/dist/tui.js +703 -148
  44. package/dist/tui.js.map +1 -1
  45. package/dist/{turn-operations-D-OQYUgS.js → turn-operations-D2rHrTQv.js} +375 -14
  46. package/dist/turn-operations-D2rHrTQv.js.map +1 -0
  47. package/dist/types.d.ts +2 -2
  48. package/docs/CHAT.md +4 -1
  49. package/docs/SKILL.md +1 -0
  50. package/docs/TUI.md +1 -0
  51. package/package.json +1 -1
  52. package/dist/agent-D70rr6Uk.d.ts.map +0 -1
  53. package/dist/index-8mn3PIaa.d.ts.map +0 -1
  54. package/dist/login-Btpliwct.js.map +0 -1
  55. package/dist/mcp-ngMS0S6N.js.map +0 -1
  56. package/dist/messages-B5k4DAXy.js.map +0 -1
  57. package/dist/tools-FerA0zSl.js.map +0 -1
  58. package/dist/transcript-anchors-C5Sp1Snh.d.ts.map +0 -1
  59. package/dist/turn-operations-D-OQYUgS.js.map +0 -1
@@ -1,11 +1,11 @@
1
- import { H as previewLine, R as fmtTokens, U as shortId, a as multiEdit, c as grep, d as resolveOldString, f as styleReplacementForVia, i as readFile$1, l as glob, n as createSpawnTool, o as listFiles, t as writeFile$1, u as edit, y as shell } from "./tools-FerA0zSl.js";
1
+ import { H as previewLine, R as fmtTokens, U as shortId, a as multiEdit, c as grep, d as resolveOldString, f as styleReplacementForVia, i as readFile$1, l as glob, n as createSpawnTool, o as listFiles, t as writeFile$1, u as edit, y as shell } from "./tools-B9aQpZVx.js";
2
2
  import { c as errorMessage } from "./errors-DdZXnyXE.js";
3
3
  import { r as toolResultToText } from "./types-oKPBdCmL.js";
4
- import { r as normalizeMcpServers } from "./mcp-ngMS0S6N.js";
4
+ import { r as normalizeMcpServers, t as connectMcpServers } from "./mcp-Wzf0qxaj.js";
5
5
  import { a as discoverSkills } from "./interpolate-DM1UcKeQ.js";
6
6
  import { n as formatTokenUsage } from "./stats-Lc3zL3RM.js";
7
- import { n as definePreset, t as composePresets } from "./presets-BXmWG3kd.js";
8
- import { a as writeFileAtomic, i as anthropic, n as openai, r as cerebras, t as openrouter } from "./providers-CaJE2ToS.js";
7
+ import { n as definePreset, t as composePresets } from "./presets-DAA0NaK_.js";
8
+ import { a as writeFileAtomic, i as anthropic, n as openai, r as cerebras, t as openrouter } from "./providers-C_ahnRBS.js";
9
9
  import { createRequire } from "node:module";
10
10
  import { dirname, isAbsolute, join, posix, relative, resolve, sep } from "node:path";
11
11
  import { homedir, tmpdir } from "node:os";
@@ -7903,6 +7903,326 @@ function patchMcpCredential(store, name, patch) {
7903
7903
  });
7904
7904
  }
7905
7905
  //#endregion
7906
+ //#region src/chat/mcp-rows.ts
7907
+ /**
7908
+ * Flatten a server catalog plus the per-server expanded set into the
7909
+ * visible-row list a renderer cycles through.
7910
+ *
7911
+ * - `catalog` — filtered / ordered server list (post-search,
7912
+ * post-allow-list).
7913
+ * - `expanded` — names of servers whose tool list is open.
7914
+ * Servers not in this set render as a single
7915
+ * server-header row.
7916
+ * - `toolsByServer` — per-server full tool catalog (from
7917
+ * `chat/mcp-tools-cache.ts`). Missing key →
7918
+ * `'tool-empty'` placeholder under the
7919
+ * expanded server.
7920
+ */
7921
+ function buildVisibleMcpRows(catalog, expanded, toolsByServer) {
7922
+ const out = [];
7923
+ for (const entry of catalog) {
7924
+ out.push({
7925
+ kind: "server",
7926
+ entry
7927
+ });
7928
+ if (!expanded.has(entry.config.name)) continue;
7929
+ const tools = toolsByServer[entry.config.name] ?? [];
7930
+ if (tools.length === 0) {
7931
+ out.push({
7932
+ kind: "tool-empty",
7933
+ serverName: entry.config.name
7934
+ });
7935
+ continue;
7936
+ }
7937
+ for (const tool of tools) out.push({
7938
+ kind: "tool",
7939
+ serverName: entry.config.name,
7940
+ tool
7941
+ });
7942
+ }
7943
+ return out;
7944
+ }
7945
+ /**
7946
+ * Server name a row "belongs to" for catalog / toggle / auth lookups.
7947
+ * For a server row that's its own name; for tool / tool-empty rows
7948
+ * it's the parent server's name.
7949
+ */
7950
+ function parentServerName(row) {
7951
+ return row.kind === "server" ? row.entry.config.name : row.serverName;
7952
+ }
7953
+ /**
7954
+ * Index in `rows` of the server header for the given parent name. `-1`
7955
+ * when not present. Used by collapse handlers to snap the cursor up
7956
+ * to the parent BEFORE shrinking the row list — otherwise the cursor
7957
+ * would land on whichever sibling row now occupies the same flat
7958
+ * index.
7959
+ */
7960
+ function indexOfServerRow(rows, parentName) {
7961
+ return rows.findIndex((r) => r.kind === "server" && r.entry.config.name === parentName);
7962
+ }
7963
+ //#endregion
7964
+ //#region src/chat/mcp-tool-toggle.ts
7965
+ /**
7966
+ * Bind a single MCP server's per-tool toggle to
7967
+ * `Settings.disabledMcpTools[serverName]`.
7968
+ *
7969
+ * `catalog` is the FULL list of tools the server advertises (i.e. the
7970
+ * cached `listTools()` payload from `chat/mcp-tools-cache.ts`). The
7971
+ * hook needs it both to render `enabledSet` (every catalog tool not in
7972
+ * the persisted deny-list) and to garbage-collect stale deny-list
7973
+ * entries on every write.
7974
+ */
7975
+ function useMcpToolToggleSet(opts) {
7976
+ const { settings, setSetting } = useSettings();
7977
+ const setDisabled = useCallback((next) => setSetting("disabledMcpTools", next), [setSetting]);
7978
+ const catalogNames = useMemo(() => opts.catalog.map((t) => t.name), [opts.catalog]);
7979
+ const persistedDenyAll = settings.disabledMcpTools;
7980
+ return useMemo(() => buildToolToggle({
7981
+ serverName: opts.serverName,
7982
+ catalogNames,
7983
+ persistedDenyAll,
7984
+ setDisabledMcpTools: setDisabled
7985
+ }), [
7986
+ opts.serverName,
7987
+ catalogNames,
7988
+ persistedDenyAll,
7989
+ setDisabled
7990
+ ]);
7991
+ }
7992
+ /**
7993
+ * Bind every server in `catalogByServer` to its own per-tool toggle in
7994
+ * a single hook call. Returns a `serverName → McpToolToggleSet` map.
7995
+ *
7996
+ * Use this when a host needs handlers for multiple servers at once
7997
+ * (the TUI's MCP settings panel keyboard dispatcher is the canonical
7998
+ * example) — calling {@link useMcpToolToggleSet} in a `for` / `.map`
7999
+ * over a dynamic catalog would change the hook-call order whenever a
8000
+ * server is added or removed, violating React's rules-of-hooks. This
8001
+ * hook calls `useMemo` exactly once regardless of server count.
8002
+ *
8003
+ * Servers absent from `catalogByServer` get no entry in the result.
8004
+ * The persisted deny-list still keeps their entries on disk — they
8005
+ * just stay invisible to this consumer until the catalog re-includes
8006
+ * them.
8007
+ */
8008
+ function useMcpToolToggleMap(opts) {
8009
+ const { settings, setSetting } = useSettings();
8010
+ const setDisabled = useCallback((next) => setSetting("disabledMcpTools", next), [setSetting]);
8011
+ const persistedDenyAll = settings.disabledMcpTools;
8012
+ return useMemo(() => {
8013
+ const out = {};
8014
+ for (const [serverName, catalog] of Object.entries(opts.catalogByServer)) out[serverName] = buildToolToggle({
8015
+ serverName,
8016
+ catalogNames: catalog.map((t) => t.name),
8017
+ persistedDenyAll,
8018
+ setDisabledMcpTools: setDisabled
8019
+ });
8020
+ return out;
8021
+ }, [
8022
+ opts.catalogByServer,
8023
+ persistedDenyAll,
8024
+ setDisabled
8025
+ ]);
8026
+ }
8027
+ /**
8028
+ * Pure factory shared by both hook flavors. Captures `persistedDenyAll`
8029
+ * + `setDisabledMcpTools` at the call site so toggle handlers stay
8030
+ * referentially stable across renders that don't touch the underlying
8031
+ * settings entry — important for `useKeyboard` to avoid re-binding on
8032
+ * every catalog change.
8033
+ *
8034
+ * Exported for direct use by non-React consumers (CLI, GUI shells)
8035
+ * that want the same write semantics without the hook plumbing.
8036
+ */
8037
+ function buildToolToggle(args) {
8038
+ const { serverName, catalogNames, persistedDenyAll, setDisabledMcpTools } = args;
8039
+ const persistedDeny = persistedDenyAll?.[serverName];
8040
+ const catalogSet = new Set(catalogNames);
8041
+ const enabledSet = (() => {
8042
+ if (!persistedDeny || persistedDeny.length === 0) return new Set(catalogNames);
8043
+ const deny = new Set(persistedDeny);
8044
+ return new Set(catalogNames.filter((name) => !deny.has(name)));
8045
+ })();
8046
+ const toggle = (toolName) => {
8047
+ const currentDeny = new Set(persistedDeny ?? []);
8048
+ if (currentDeny.has(toolName)) currentDeny.delete(toolName);
8049
+ else currentDeny.add(toolName);
8050
+ const nextForServer = [...currentDeny].filter((n) => catalogSet.has(n)).sort();
8051
+ const nextMap = { ...persistedDenyAll ?? {} };
8052
+ if (nextForServer.length === 0) delete nextMap[serverName];
8053
+ else nextMap[serverName] = nextForServer;
8054
+ setDisabledMcpTools(Object.keys(nextMap).length === 0 ? void 0 : nextMap);
8055
+ };
8056
+ return {
8057
+ enabledSet,
8058
+ toggle
8059
+ };
8060
+ }
8061
+ //#endregion
8062
+ //#region src/chat/mcp-tools-cache.ts
8063
+ /**
8064
+ * Disk filename. Versioned so a future schema change (e.g. adding
8065
+ * provenance / TTL) can ship a parallel `v2` file without colliding.
8066
+ */
8067
+ const CACHE_FILENAME = "mcp-tools-cache.json";
8068
+ /**
8069
+ * Resolve the on-disk cache path under a host's data directory. Exposed
8070
+ * for tests + advanced hosts that want to inspect / delete the file
8071
+ * without re-implementing the path convention.
8072
+ */
8073
+ function mcpToolsCachePath(dataDir) {
8074
+ return resolve(dataDir, CACHE_FILENAME);
8075
+ }
8076
+ /**
8077
+ * Best-effort cache read. Returns `{}` when the file is missing, when
8078
+ * JSON.parse rejects, or when the top-level shape isn't a plain object —
8079
+ * a corrupt cache must never crash the host on startup.
8080
+ *
8081
+ * Per-entry shape validation is light (presence of an array `tools`):
8082
+ * deeper validation would lock the cache to a single zidane version,
8083
+ * which is the opposite of what a long-lived cache wants. Entries that
8084
+ * survive the light check feed back through `McpToolSchema`'s `unknown`
8085
+ * `inputSchema` so downstream readers stay tolerant of upstream churn.
8086
+ */
8087
+ function loadMcpToolsCache(opts) {
8088
+ const path = mcpToolsCachePath(opts.dataDir);
8089
+ if (!existsSync(path)) return {};
8090
+ try {
8091
+ const raw = readFileSync(path, "utf-8");
8092
+ const parsed = JSON.parse(raw);
8093
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
8094
+ const out = {};
8095
+ for (const [name, entry] of Object.entries(parsed)) if (isCachedEntry(entry)) out[name] = entry;
8096
+ return out;
8097
+ } catch {
8098
+ return {};
8099
+ }
8100
+ }
8101
+ /**
8102
+ * Atomic full-cache write. Used by {@link subscribeMcpToolsCache} after
8103
+ * each upsert. Failures bubble up as the underlying `writeFileAtomic`
8104
+ * error — the caller logs under `ZIDANE_DEBUG` and swallows.
8105
+ */
8106
+ function saveMcpToolsCache(opts) {
8107
+ writeFileAtomic(mcpToolsCachePath(opts.dataDir), `${JSON.stringify(opts.cache, null, 2)}\n`, { ensureDir: true });
8108
+ }
8109
+ /**
8110
+ * Drop entries for one or more servers, or wipe the cache when no
8111
+ * server is named. Idempotent — entries that aren't present are
8112
+ * silently skipped. Returns the resulting cache so callers can refresh
8113
+ * any in-memory mirror without re-reading from disk.
8114
+ *
8115
+ * Intended for a future "rescan server" affordance in the settings UI
8116
+ * (clear → trigger a real bootstrap → cache repopulates on the
8117
+ * `mcp:tools:list` hook).
8118
+ */
8119
+ function clearMcpToolsCache(opts) {
8120
+ const current = loadMcpToolsCache(opts);
8121
+ if (!opts.serverNames) {
8122
+ saveMcpToolsCache({
8123
+ dataDir: opts.dataDir,
8124
+ cache: {}
8125
+ });
8126
+ return {};
8127
+ }
8128
+ const next = { ...current };
8129
+ for (const name of opts.serverNames) delete next[name];
8130
+ saveMcpToolsCache({
8131
+ dataDir: opts.dataDir,
8132
+ cache: next
8133
+ });
8134
+ return next;
8135
+ }
8136
+ /**
8137
+ * Subscribe to `mcp:tools:list` and persist every successful bootstrap
8138
+ * into the on-disk cache. Returns an unsubscribe function — call it
8139
+ * during agent teardown so a long-lived host (Settings modal that
8140
+ * outlives one agent) doesn't accumulate stale subscribers.
8141
+ *
8142
+ * Each write loads the current cache, upserts the named entry, then
8143
+ * atomic-writes the full file. The read-modify-write is safe under
8144
+ * Node single-threaded event loop semantics — concurrent bootstraps in
8145
+ * the same process serialize through the hook bus.
8146
+ *
8147
+ * Optional `onChange` callback fires synchronously after every
8148
+ * successful disk write with the entry that was just upserted. Lets a
8149
+ * React host trigger a state refresh without polling the disk.
8150
+ *
8151
+ * Write failures are swallowed (logged under `ZIDANE_DEBUG`): the cache
8152
+ * is an accelerator, not a correctness boundary. If the disk is full
8153
+ * the agent run still works — the settings UI just shows stale data
8154
+ * until the next successful write.
8155
+ */
8156
+ function subscribeMcpToolsCache(hooks, opts) {
8157
+ return hooks.hook("mcp:tools:list", (ctx) => {
8158
+ const entry = {
8159
+ tools: [...ctx.tools],
8160
+ updatedAt: Date.now(),
8161
+ transport: ctx.transport
8162
+ };
8163
+ try {
8164
+ const next = {
8165
+ ...loadMcpToolsCache({ dataDir: opts.dataDir }),
8166
+ [ctx.name]: entry
8167
+ };
8168
+ saveMcpToolsCache({
8169
+ dataDir: opts.dataDir,
8170
+ cache: next
8171
+ });
8172
+ opts.onChange?.({
8173
+ name: ctx.name,
8174
+ ...entry
8175
+ });
8176
+ } catch (err) {
8177
+ if (process.env.ZIDANE_DEBUG) process.stderr.write(`[zidane/chat] mcp-tools-cache write failed for "${ctx.name}": ${errorMessage(err)}\n`);
8178
+ }
8179
+ });
8180
+ }
8181
+ /**
8182
+ * Force-refresh the on-disk tools cache by opening a transient MCP
8183
+ * connection to every server, capturing the `mcp:tools:list` hook on
8184
+ * the way through, and closing the connection immediately. The
8185
+ * underlying `connectMcpServers` runs every server's bootstrap in
8186
+ * parallel, so the wall-clock cost collapses to the slowest server.
8187
+ *
8188
+ * Two design choices worth noting:
8189
+ *
8190
+ * - **Shared hook bus.** The caller passes the SAME `Hookable`
8191
+ * instance that has the cache subscriber wired (typically
8192
+ * `agent.hooks` after `subscribeMcpToolsCache(agent.hooks, …)`
8193
+ * ran). That way `mcp:tools:list` fires on the bus the
8194
+ * subscriber is listening to and the cache lands on disk
8195
+ * without a separate write path.
8196
+ * - **Transient, NOT shared with the live agent.** The connection
8197
+ * opened here is closed immediately. The agent's own MCP
8198
+ * connection is untouched, so a refresh never disrupts an
8199
+ * in-flight tool call.
8200
+ *
8201
+ * The function intentionally swallows per-server failures (they're
8202
+ * already surfaced via `mcp:bootstrap:end ok: false` for any host
8203
+ * that wired the listener). The Promise resolves once every server's
8204
+ * bootstrap settles, success or otherwise.
8205
+ */
8206
+ async function refreshMcpToolsCatalog(opts) {
8207
+ if (opts.servers.length === 0) return;
8208
+ await (await connectMcpServers(opts.servers, void 0, opts.hooks, opts.buildAuthProvider ? { buildAuthProvider: opts.buildAuthProvider } : void 0)).close().catch((err) => {
8209
+ if (process.env.ZIDANE_DEBUG) process.stderr.write(`[zidane/chat] mcp-tools-cache transient close failed: ${errorMessage(err)}\n`);
8210
+ });
8211
+ }
8212
+ /**
8213
+ * Type-narrowing check used by {@link loadMcpToolsCache}. Kept private
8214
+ * — callers that want a richer validation surface should layer it on
8215
+ * top of the loose disk shape rather than tightening this predicate.
8216
+ */
8217
+ function isCachedEntry(value) {
8218
+ if (!value || typeof value !== "object") return false;
8219
+ const entry = value;
8220
+ if (!Array.isArray(entry.tools)) return false;
8221
+ if (typeof entry.updatedAt !== "number" || !Number.isFinite(entry.updatedAt)) return false;
8222
+ if (entry.transport !== "stdio" && entry.transport !== "sse" && entry.transport !== "streamable-http") return false;
8223
+ return true;
8224
+ }
8225
+ //#endregion
7906
8226
  //#region src/chat/project-user-paths.ts
7907
8227
  /**
7908
8228
  * Shared search-path builder for project + user config discovery.
@@ -8174,14 +8494,46 @@ function discoverProjectMcps(opts = {}) {
8174
8494
  * - `enabled === [names]` → allowlist; servers not in the list are
8175
8495
  * dropped.
8176
8496
  *
8497
+ * `disabledTools` is the per-server tool deny-list from
8498
+ * `Settings.disabledMcpTools`. For each server that survives the
8499
+ * server-level enable filter, the per-tool names are merged into
8500
+ * `McpServerConfig.disabledTools` via **union** with anything the JSON
8501
+ * file already pinned — a tool listed in either source is dropped.
8502
+ * Union (not override) keeps JSON-side policy stable: a server file
8503
+ * that pins `disabledTools: ['dangerous_tool']` can't be re-enabled
8504
+ * via the UI by accident.
8505
+ *
8506
+ * `enabledTools` (JSON-side allowlist) takes precedence over the
8507
+ * UI-side deny-list when both are set on the same server — the
8508
+ * allowlist's "only these" semantics would be meaningless if a UI
8509
+ * deny-list could subtract from it again. We don't emit `disabledTools`
8510
+ * when `enabledTools` is present.
8511
+ *
8177
8512
  * Returns a fresh array — callers can mutate without affecting the
8178
- * underlying discovery list.
8513
+ * underlying discovery list. Per-server config objects are also fresh
8514
+ * copies (shallow), so the merged `disabledTools` doesn't leak back
8515
+ * onto the discovery catalog.
8179
8516
  */
8180
8517
  function buildMcpServers(opts) {
8181
- if (opts.enabled === void 0) return opts.discovered.map((d) => d.config);
8182
- if (opts.enabled.length === 0) return [];
8183
- const allow = new Set(opts.enabled);
8184
- return opts.discovered.filter((d) => allow.has(d.config.name)).map((d) => d.config);
8518
+ const survivors = filterByEnabled(opts.discovered, opts.enabled);
8519
+ const deny = opts.disabledTools;
8520
+ if (!deny || Object.keys(deny).length === 0) return survivors.map((d) => ({ ...d.config }));
8521
+ return survivors.map((d) => {
8522
+ const next = { ...d.config };
8523
+ const uiDeny = deny[d.config.name];
8524
+ if (!uiDeny || uiDeny.length === 0) return next;
8525
+ if (next.enabledTools && next.enabledTools.length > 0) return next;
8526
+ const merged = new Set(next.disabledTools ?? []);
8527
+ for (const name of uiDeny) merged.add(name);
8528
+ next.disabledTools = [...merged].sort();
8529
+ return next;
8530
+ });
8531
+ }
8532
+ function filterByEnabled(discovered, enabled) {
8533
+ if (enabled === void 0) return discovered;
8534
+ if (enabled.length === 0) return [];
8535
+ const allow = new Set(enabled);
8536
+ return discovered.filter((d) => allow.has(d.config.name));
8185
8537
  }
8186
8538
  //#endregion
8187
8539
  //#region src/chat/model-catalog.ts
@@ -9810,7 +10162,7 @@ const TOOL_DISPLAY = {
9810
10162
  format: (input) => {
9811
10163
  const command = stringField(input, "command");
9812
10164
  if (!command) return null;
9813
- return { target: truncate(command.trim(), 200) };
10165
+ return { target: truncate(command, 200) };
9814
10166
  }
9815
10167
  },
9816
10168
  shell_kill: {
@@ -9866,7 +10218,7 @@ const TOOL_DISPLAY = {
9866
10218
  format: (input) => {
9867
10219
  const task = stringField(input, "task");
9868
10220
  if (!task) return null;
9869
- return { target: truncate(task.replace(/\s+/g, " ").trim(), 120) };
10221
+ return { target: truncate(task, 120) };
9870
10222
  }
9871
10223
  },
9872
10224
  tool_search: {
@@ -10011,8 +10363,17 @@ function sentenceCase(s) {
10011
10363
  words[0] = (words[0][0]?.toUpperCase() ?? "") + words[0].slice(1);
10012
10364
  return words.join(" ");
10013
10365
  }
10366
+ /**
10367
+ * Collapse internal whitespace (including newlines) to single spaces
10368
+ * and clip to `max` columns with a trailing `…`. The whitespace
10369
+ * normalisation is the load-bearing bit — tool input strings like a
10370
+ * shell heredoc or a multi-line Python `-c` script otherwise render
10371
+ * across several rows in the transcript even though the `↳ Tool …`
10372
+ * line is meant to be a single-line scannable summary.
10373
+ */
10014
10374
  function truncate(s, max) {
10015
- return s.length <= max ? s : `${s.slice(0, max - 1)}…`;
10375
+ const clean = s.replace(/\s+/g, " ").trim();
10376
+ return clean.length <= max ? clean : `${clean.slice(0, max - 1)}…`;
10016
10377
  }
10017
10378
  function byteLengthUtf8(s) {
10018
10379
  let bytes = 0;
@@ -10188,6 +10549,6 @@ function countNeighbors(turnIds, turnId) {
10188
10549
  };
10189
10550
  }
10190
10551
  //#endregion
10191
- export { patchMcpCredential as $, FILES_TRIGGER as $n, PLAN_AGENT as $r, createStateStore as $t, getSafelist as A, maskToOutcomeKinds as An, setProviderCredential as Ar, SETTINGS_TOGGLES as At, oauthUsesManualCodePaste as B, KEYBINDING_KEY_COL_WIDTH as Bn, modelSupportsReasoning as Br, CATPPUCCIN_LATTE as Bt, resolveSessionExportTarget as C, PLAN_MODE_DOCTRINE as Ci, extractEditPayload as Cn, shouldAutoCompact as Cr, buildHints as Ct, useSafeModeQueue as D, buildBuildSystem as Di, summarizeEditPayload as Dn, readCredentials as Dr, DEFAULT_SETTINGS as Dt, useSafeModeActions as E, TOKEN_DISCIPLINE_DOCTRINE as Ei, splitLines as En, credentialsPath as Er, useEnabledToggleSet as Et, suggestSafelistEntry as F, stripEditOutcomesAnnotation as Fn, cerebrasDescriptor as Fr, DEFAULT_THEME as Ft, indexOfEntry as G, matchesBinding as Gn, discoverAgentsMd as Gr, useDiscovery as Gt, supportsOAuth as H, formatBindingForDisplay as Hn, openaiDescriptor as Hr, CATPPUCCIN_MOCHA as Ht, writeProjects as I, summarizeOutcomes as In, credKeyOf as Ir, resolveChipColor as It, discoverProjectMcps as J, readKeybindings as Jn, BUILD_AGENT as Jr, useConfig as Jt, buildMcpServers as K, mergeKeybindings as Kn, renderAgentsMdBlock as Kr, useDiscoveryOptional as Kt, splitPromptSegments as L, DEFAULT_KEYBINDINGS as Ln, effectiveContextWindow as Lr, resolveTheme as Lt, matchesSafelistEntry as M, parseEditOutcomesFromResult as Mn, BUILTIN_PROVIDERS as Mr, clampFps as Mt, projectsFilePath as N, resolveApprovalForPayload as Nn, OUTPUT_RESERVE_TOKENS as Nr, useSettings as Nt, IMPLICITLY_SAFE_TOOLS as O, buildPlanSystem as Oi, tokenize as On, readProviderCredential as Or, SETTINGS_CATEGORIES as Ot, readProjects as P, rewriteMultiEditHeader as Pn, anthropicDescriptor as Pr, BUILTIN_THEMES as Pt, mcpCredentialsPath as Q, uniqueSkillNamesFromReferences as Qn, DEFAULT_PERSIST_EXCLUDE_TOOLS as Qr, EDIT_TOOL_NAMES as Qt, formatPathForCwd as R, KEYBINDING_DEFS as Rn, getContextWindow as Rr, VAPORWAVE_THEME as Rt, renderSession as S, INTERACTION_GUIDANCE_NO_PROMPTS as Si, computeLineDiff as Sn, AUTO_COMPACT_MIN_GROWTH_FRACTION as Sr, generateSessionTitle as St, SafeModeProvider as T, SUBAGENT_GUIDANCE as Ti, previewEditPayload as Tn, applyApiKeyEnv as Tr, listProjectFiles as Tt, buildModelCatalog as U, groupBindings as Un, openrouterDescriptor as Ur, createDiscoverySlot as Ut, runOAuthLogin as V, ensureKeybindingsFile as Vn, modelsForDescriptor as Vr, CATPPUCCIN_MACCHIATO as Vt, filterModelCatalog as W, keybindingsPath as Wn, piIdOf as Wr, DiscoveryProvider as Wt, projectUserPaths as X, SKILLS_TRIGGER as Xn, DEFAULT_AGENT_ID as Xr, resolveStoragePaths as Xt, parseMcpsFile as Y, stripJsonComments as Yn, BUILTIN_AGENTS as Yr, resolveConfig as Yt, createFileMcpCredentialStore as Z, createSkillsCompletionProvider as Zn, DEFAULT_BUDGET_EXCLUDE_TOOLS as Zr, resolveStorageDirs as Zt, turnContextSize as _, ACTIONS_WITH_CARE_DOCTRINE as _i, updateToolEventOutcomes as _n, detectPackageManager as _r, EMPTY_HINTS as _t, computeTurnAnchors as a, TODOWRITE_TOOL as ai, lastContextSizeFromTurns as an, mergeReferences as ar, splitMarkdownCodeBlocks as at, defaultSkillScanPaths as b, IDENTITY_PREFIX as bi, buildUnifiedDiff as bn, performSelfUpdate as br, truncateTrailing as bt, formatToolCall as c, createTodoTools as ci, marginTopFor as cn, buildLinearRamp as cr, PRESENT_PLAN_TOOL as ct, useSelectStyle as d, isTodoTool as di, stripSpawnTokensLine as dn, bootTick as dr, isInteractionTool as dt, accentColor as ei, deriveSessionTitle as en, createFilesCompletionProvider as er, McpAuthProvider as et, useSurfaces as f, pickActiveRunId as fi, sumRunCosts as fn, buildUpdateHint as fr, makeRequestInteraction as ft, finalizeStreamingMarkdownForOwner as g, useActiveTodos as gi, turnSelectionOwnership as gn, detectLibc as gr, useInteractionsQueue as gt, finalizeStreamingMarkdown as h, setTodosForRun as hi, toolResultText as hn, compareSemver as hr, useInteractionsActions as ht, turnAsText as i, TODOS_METADATA_KEY as ii, isVisible as in, findActiveTrigger as ir, reduceMcpAuth as it, isOnSafelist as j, mergeApprovalAndBodyOutcomes as jn, writeCredentials as jr, SettingsProvider as jt, addToSafelist as k, envSection as ki, buildEditOutcomesAnnotation as kn, removeProviderCredential as kr, SETTINGS_CHOICES as kt, ThemeProvider as l, getArchivedTodosForRun as li, saveState as ln, tryOpenBrowser as lr, buildResumedToolResultsTurn as lt, useTheme as m, selectActiveTodos as mi, toolCallPreview as mn, checkForUpdate as mr, serializeInteractionResponse as mt, deleteTurnSafely as n, singleAgentRegistry as ni, isEditErrorResult as nn, applyInsert as nr, useMcpAuthState as nt, TOOL_DISPLAY as o, TODO_STATUS_GLYPHS as oi, listSessionMeta as on, useCompletion as or, ASK_USER_TOOL as ot, useSyntaxStyles as p, pruneTodosByRun as pi, titleFromTurns as pn, useUpdateCheck as pr, pendingInteractionsFromTurns as pt, defaultMcpsConfigPaths as q, parseBindingSpec as qn, findGitRoot$1 as qr, ConfigProvider as qt, truncateTurnsAt as r, TODOREAD_TOOL as ri, isTurnHighlighted as rn, collectReferences as rr, getMcpAuthStatus as rt, displayNameFor as s, TODO_WRITE_COUNTS_METADATA_KEY as si, loadState as sn, blendHsl as sr, InteractionsProvider as st, countNeighbors as t, resolveAgentId as ti, eventsFromTurns as tn, uniqueFilesFromReferences as tr, useMcpAuthDispatch as tt, useColors as u, getTodosForRun as ui, selectableTurnIds as un, bootProfileEnabled as ur, createInteractionTools as ut, useStreamBuffer as v, COMMUNICATION_DOCTRINE as vi, applyEditPayload as vn, parseSemver as vr, clipHintsToWidth as vt, writeSessionExport as w, PLAN_MODE_DOCTRINE_NO_PROMPTS as wi, filetypeFromPath as wn, detectAuth as wr, shortChord as wt, discoverProjectSkills as x, INTERACTION_GUIDANCE as xi, computeInlineDiff as xn, resolvePlatformPackage as xr, cleanTitle as xt, buildSkillsConfig as y, DOING_TASKS_DOCTRINE as yi, buildContextualDiff as yn, performInPlaceSelfUpdate as yr, hintsLength as yt, fetchOAuthRedirect as z, KEYBINDING_DEF_BY_ACTION as zn, getModelInfo as zr, CATPPUCCIN_FRAPPE as zt };
10552
+ export { mcpToolsCachePath as $, ensureKeybindingsFile as $n, modelsForDescriptor as $r, CATPPUCCIN_MACCHIATO as $t, getSafelist as A, COMMUNICATION_DOCTRINE as Ai, applyEditPayload as An, parseSemver as Ar, clipHintsToWidth as At, oauthUsesManualCodePaste as B, buildPlanSystem as Bi, tokenize as Bn, readProviderCredential as Br, SETTINGS_CATEGORIES as Bt, resolveSessionExportTarget as C, isTodoTool as Ci, stripSpawnTokensLine as Cn, bootTick as Cr, isInteractionTool as Ct, useSafeModeQueue as D, setTodosForRun as Di, toolResultText as Dn, compareSemver as Dr, useInteractionsActions as Dt, useSafeModeActions as E, selectActiveTodos as Ei, toolCallPreview as En, checkForUpdate as Er, serializeInteractionResponse as Et, suggestSafelistEntry as F, PLAN_MODE_DOCTRINE as Fi, extractEditPayload as Fn, shouldAutoCompact as Fr, buildHints as Ft, indexOfEntry as G, resolveApprovalForPayload as Gn, OUTPUT_RESERVE_TOKENS as Gr, useSettings as Gt, supportsOAuth as H, maskToOutcomeKinds as Hn, setProviderCredential as Hr, SETTINGS_TOGGLES as Ht, writeProjects as I, PLAN_MODE_DOCTRINE_NO_PROMPTS as Ii, filetypeFromPath as In, detectAuth as Ir, shortChord as It, discoverProjectMcps as J, summarizeOutcomes as Jn, credKeyOf as Jr, resolveChipColor as Jt, buildMcpServers as K, rewriteMultiEditHeader as Kn, anthropicDescriptor as Kr, BUILTIN_THEMES as Kt, splitPromptSegments as L, SUBAGENT_GUIDANCE as Li, previewEditPayload as Ln, applyApiKeyEnv as Lr, listProjectFiles as Lt, matchesSafelistEntry as M, IDENTITY_PREFIX as Mi, buildUnifiedDiff as Mn, performSelfUpdate as Mr, truncateTrailing as Mt, projectsFilePath as N, INTERACTION_GUIDANCE as Ni, computeInlineDiff as Nn, resolvePlatformPackage as Nr, cleanTitle as Nt, IMPLICITLY_SAFE_TOOLS as O, useActiveTodos as Oi, turnSelectionOwnership as On, detectLibc as Or, useInteractionsQueue as Ot, readProjects as P, INTERACTION_GUIDANCE_NO_PROMPTS as Pi, computeLineDiff as Pn, AUTO_COMPACT_MIN_GROWTH_FRACTION as Pr, generateSessionTitle as Pt, loadMcpToolsCache as Q, KEYBINDING_KEY_COL_WIDTH as Qn, modelSupportsReasoning as Qr, CATPPUCCIN_LATTE as Qt, formatPathForCwd as R, TOKEN_DISCIPLINE_DOCTRINE as Ri, splitLines as Rn, credentialsPath as Rr, useEnabledToggleSet as Rt, renderSession as S, getTodosForRun as Si, selectableTurnIds as Sn, bootProfileEnabled as Sr, createInteractionTools as St, SafeModeProvider as T, pruneTodosByRun as Ti, titleFromTurns as Tn, useUpdateCheck as Tr, pendingInteractionsFromTurns as Tt, buildModelCatalog as U, mergeApprovalAndBodyOutcomes as Un, writeCredentials as Ur, SettingsProvider as Ut, runOAuthLogin as V, envSection as Vi, buildEditOutcomesAnnotation as Vn, removeProviderCredential as Vr, SETTINGS_CHOICES as Vt, filterModelCatalog as W, parseEditOutcomesFromResult as Wn, BUILTIN_PROVIDERS as Wr, clampFps as Wt, projectUserPaths as X, KEYBINDING_DEFS as Xn, getContextWindow as Xr, VAPORWAVE_THEME as Xt, parseMcpsFile as Y, DEFAULT_KEYBINDINGS as Yn, effectiveContextWindow as Yr, resolveTheme as Yt, clearMcpToolsCache as Z, KEYBINDING_DEF_BY_ACTION as Zn, getModelInfo as Zr, CATPPUCCIN_FRAPPE as Zt, turnContextSize as _, TODOWRITE_TOOL as _i, lastContextSizeFromTurns as _n, mergeReferences as _r, splitMarkdownCodeBlocks as _t, computeTurnAnchors as a, findGitRoot$1 as ai, ConfigProvider as an, parseBindingSpec as ar, useMcpToolToggleSet as at, defaultSkillScanPaths as b, createTodoTools as bi, marginTopFor as bn, buildLinearRamp as br, PRESENT_PLAN_TOOL as bt, formatToolCall as c, DEFAULT_AGENT_ID as ci, resolveStoragePaths as cn, SKILLS_TRIGGER as cr, parentServerName as ct, useSelectStyle as d, PLAN_AGENT as di, createStateStore as dn, FILES_TRIGGER as dr, patchMcpCredential as dt, openaiDescriptor as ei, CATPPUCCIN_MOCHA as en, formatBindingForDisplay as er, refreshMcpToolsCatalog as et, useSurfaces as f, accentColor as fi, deriveSessionTitle as fn, createFilesCompletionProvider as fr, McpAuthProvider as ft, finalizeStreamingMarkdownForOwner as g, TODOS_METADATA_KEY as gi, isVisible as gn, findActiveTrigger as gr, reduceMcpAuth as gt, finalizeStreamingMarkdown as h, TODOREAD_TOOL as hi, isTurnHighlighted as hn, collectReferences as hr, getMcpAuthStatus as ht, turnAsText as i, renderAgentsMdBlock as ii, useDiscoveryOptional as in, mergeKeybindings as ir, useMcpToolToggleMap as it, isOnSafelist as j, DOING_TASKS_DOCTRINE as ji, buildContextualDiff as jn, performInPlaceSelfUpdate as jr, hintsLength as jt, addToSafelist as k, ACTIONS_WITH_CARE_DOCTRINE as ki, updateToolEventOutcomes as kn, detectPackageManager as kr, EMPTY_HINTS as kt, ThemeProvider as l, DEFAULT_BUDGET_EXCLUDE_TOOLS as li, resolveStorageDirs as ln, createSkillsCompletionProvider as lr, createFileMcpCredentialStore as lt, useTheme as m, singleAgentRegistry as mi, isEditErrorResult as mn, applyInsert as mr, useMcpAuthState as mt, deleteTurnSafely as n, piIdOf as ni, DiscoveryProvider as nn, keybindingsPath as nr, subscribeMcpToolsCache as nt, TOOL_DISPLAY as o, BUILD_AGENT as oi, useConfig as on, readKeybindings as or, buildVisibleMcpRows as ot, useSyntaxStyles as p, resolveAgentId as pi, eventsFromTurns as pn, uniqueFilesFromReferences as pr, useMcpAuthDispatch as pt, defaultMcpsConfigPaths as q, stripEditOutcomesAnnotation as qn, cerebrasDescriptor as qr, DEFAULT_THEME as qt, truncateTurnsAt as r, discoverAgentsMd as ri, useDiscovery as rn, matchesBinding as rr, buildToolToggle as rt, displayNameFor as s, BUILTIN_AGENTS as si, resolveConfig as sn, stripJsonComments as sr, indexOfServerRow as st, countNeighbors as t, openrouterDescriptor as ti, createDiscoverySlot as tn, groupBindings as tr, saveMcpToolsCache as tt, useColors as u, DEFAULT_PERSIST_EXCLUDE_TOOLS as ui, EDIT_TOOL_NAMES as un, uniqueSkillNamesFromReferences as ur, mcpCredentialsPath as ut, useStreamBuffer as v, TODO_STATUS_GLYPHS as vi, listSessionMeta as vn, useCompletion as vr, ASK_USER_TOOL as vt, writeSessionExport as w, pickActiveRunId as wi, sumRunCosts as wn, buildUpdateHint as wr, makeRequestInteraction as wt, discoverProjectSkills as x, getArchivedTodosForRun as xi, saveState as xn, tryOpenBrowser as xr, buildResumedToolResultsTurn as xt, buildSkillsConfig as y, TODO_WRITE_COUNTS_METADATA_KEY as yi, loadState as yn, blendHsl as yr, InteractionsProvider as yt, fetchOAuthRedirect as z, buildBuildSystem as zi, summarizeEditPayload as zn, readCredentials as zr, DEFAULT_SETTINGS as zt };
10192
10553
 
10193
- //# sourceMappingURL=turn-operations-D-OQYUgS.js.map
10554
+ //# sourceMappingURL=turn-operations-D2rHrTQv.js.map