mixdog 1.0.5 → 1.0.7

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 (50) hide show
  1. package/README.md +206 -475
  2. package/package.json +11 -4
  3. package/src/defaults/skills/setup/references/actions.md +26 -6
  4. package/src/defaults/skills/setup/references/surfaces.md +8 -3
  5. package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +16 -7
  6. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +6 -2
  7. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +0 -3
  8. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +0 -2
  9. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +24 -2
  10. package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +25 -0
  11. package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +14 -1
  12. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +3 -45
  13. package/src/runtime/channels/lib/config.mjs +0 -1
  14. package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +1 -1
  15. package/src/runtime/channels/lib/scheduler.mjs +15 -56
  16. package/src/runtime/channels/lib/worker-main.mjs +2 -9
  17. package/src/runtime/shared/config.mjs +66 -1
  18. package/src/runtime/shared/llm/usage-ledger-quota.mjs +13 -2
  19. package/src/runtime/shared/path-executable.mjs +58 -0
  20. package/src/session-runtime/boot/apis.mjs +6 -2
  21. package/src/session-runtime/boot/begin.mjs +0 -2
  22. package/src/session-runtime/boot/providers.mjs +3 -0
  23. package/src/session-runtime/boot/tools.mjs +0 -1
  24. package/src/session-runtime/config-lifecycle.mjs +11 -0
  25. package/src/session-runtime/internal-tool-executor.mjs +0 -2
  26. package/src/session-runtime/runtime-feature-gates.mjs +2 -3
  27. package/src/session-runtime/schedule-session-run.mjs +0 -1
  28. package/src/session-runtime/services/channel-admin.mjs +8 -26
  29. package/src/session-runtime/settings-compaction-api.mjs +5 -1
  30. package/src/session-runtime/settings-system-api.mjs +2 -20
  31. package/src/session-runtime/setup-tool/executor.mjs +61 -3
  32. package/src/session-runtime/setup-tool/extended-actions.mjs +31 -6
  33. package/src/session-runtime/setup-tool/settings-contract.mjs +27 -3
  34. package/src/session-runtime/setup-tool/tool-defs.mjs +35 -5
  35. package/src/session-runtime/webhook-session-run.mjs +0 -2
  36. package/src/session-runtime/workflow-agents-api/agent-editor.mjs +13 -3
  37. package/src/standalone/daemon-stored-session-views.mjs +4 -0
  38. package/src/standalone/session-protocol.mjs +0 -1
  39. package/src/standalone/session-service/session-calls/session-views.mjs +10 -4
  40. package/src/standalone/session-service/stored-reader.mjs +20 -2
  41. package/src/standalone/session-service/viewers.mjs +3 -3
  42. package/src/standalone/session-service.mjs +3 -1
  43. package/src/tui/App.jsx +6 -1
  44. package/src/tui/app/create-app-pickers.mjs +1 -0
  45. package/src/tui/app/doctor.mjs +6 -14
  46. package/src/tui/app/maintenance-pickers/auto-clear-picker.mjs +8 -3
  47. package/src/tui/app/settings-picker/settings-rows.mjs +5 -1
  48. package/src/tui/app/use-ui-open-request.mjs +13 -3
  49. package/src/tui/dist/index.mjs +41 -9
  50. package/src/tui/session/session-api/settings.mjs +0 -6
@@ -9,6 +9,7 @@ export function createStoredSessionReader({
9
9
  readStoredGoal,
10
10
  statStoredSession = null,
11
11
  forgetStoredSession = null,
12
+ releaseStoredSession = null,
12
13
  sessionOwner,
13
14
  log,
14
15
  }) {
@@ -46,10 +47,26 @@ export function createStoredSessionReader({
46
47
  .catch((err) => log(`stored projection release failed session=${sessionId}: ${err?.message || err}`));
47
48
  }
48
49
 
49
- function traceStoredProjectionRead({ sessionId, hit, ms, chars, items }) {
50
+ /** Its last view left. The file-identity records stay (a revisit holding
51
+ * the same projection is answered by stat alone) and the store keeps the
52
+ * projection within its idle budget. */
53
+ function releaseStoredProjection(sessionId) {
54
+ if (typeof releaseStoredSession !== 'function') return;
55
+ void Promise.resolve()
56
+ .then(() => releaseStoredSession(sessionId))
57
+ .catch((err) => log(`stored projection idle release failed session=${sessionId}: ${err?.message || err}`));
58
+ }
59
+
60
+ function traceStoredProjectionRead({ sessionId, hit, ms, chars, items, timing = {} }) {
50
61
  // Shared parse waiters are cache hits; report only the parse itself.
51
62
  if (hit || ms < SLOW_STORED_PROJECTION_MS) return;
52
- log(`slow stored projection session=${sessionId} ${Math.round(ms)}ms` + ` chars=${chars} items=${items}`);
63
+ const phases = Object.entries(timing)
64
+ .map(([name, value]) => `${name}=${typeof value === 'number' ? `${Math.round(value)}ms` : value}`)
65
+ .join(' ');
66
+ log(
67
+ `slow stored projection session=${sessionId} ${Math.round(ms)}ms` +
68
+ ` chars=${chars} items=${items}${phases ? ` ${phases}` : ''}`
69
+ );
53
70
  }
54
71
 
55
72
  const itemLimitFor = (hints, window) => {
@@ -164,5 +181,6 @@ export function createStoredSessionReader({
164
181
  storedProjectionUnchanged,
165
182
  requestedMessageSlice,
166
183
  forgetStoredSession: forgetStoredProjection,
184
+ releaseStoredSession: releaseStoredProjection,
167
185
  };
168
186
  }
@@ -35,7 +35,7 @@ export function createViewerRegistry({
35
35
  sessionBusy,
36
36
  currentSessionId,
37
37
  destroy,
38
- forgetStoredSession,
38
+ releaseStoredSession,
39
39
  releaseProjection = () => {},
40
40
  }) {
41
41
  // Client tokens whose reads/subscriptions announced `transcriptPrepend`:
@@ -134,8 +134,8 @@ export function createViewerRegistry({
134
134
  forgetPendingWindow(pendingId, token);
135
135
  if (tokens.delete(token) && tokens.size === 0) {
136
136
  pendingViewers.delete(pendingId);
137
- // The last cold view left: its disk projection is no longer needed.
138
- forgetStoredSession(pendingId);
137
+ // The last cold view left: its disk projection turns idle.
138
+ releaseStoredSession(pendingId);
139
139
  }
140
140
  }
141
141
  for (const entry of sessions) {
@@ -39,6 +39,7 @@ export function createSessionService({
39
39
  readStoredSession = null,
40
40
  statStoredSession = null,
41
41
  forgetStoredSession = null,
42
+ releaseStoredSession = null,
42
43
  readStoredGoal = null,
43
44
  listStoredActiveGoalSessionIds = null,
44
45
  subscribeExternalSessionStates = null,
@@ -114,7 +115,7 @@ export function createSessionService({
114
115
  releaseProjection: retention.releaseProjection,
115
116
  currentSessionId: (entry) => projection.currentSessionId(entry),
116
117
  destroy: (entry, reason, options) => entries.destroy(entry, reason, options),
117
- forgetStoredSession: (sessionId) => storedReader.forgetStoredSession(sessionId),
118
+ releaseStoredSession: (sessionId) => storedReader.releaseStoredSession(sessionId),
118
119
  });
119
120
  // Wire projection + frame publication (see session-service/projection.mjs).
120
121
  const projection = createSessionProjection({
@@ -162,6 +163,7 @@ export function createSessionService({
162
163
  readStoredGoal,
163
164
  statStoredSession,
164
165
  forgetStoredSession,
166
+ releaseStoredSession,
165
167
  sessionOwner: projection.sessionOwner,
166
168
  log,
167
169
  });
package/src/tui/App.jsx CHANGED
@@ -297,6 +297,7 @@ export function App({ store, initialStatusLine = '', forceOnboarding = false, on
297
297
  openOnboardingAuthStep,
298
298
  openProviderSetupPicker,
299
299
  openSettingsPicker,
300
+ openDeveloperPicker,
300
301
  runSlashCommand,
301
302
  } = createAppPickers({
302
303
  state,
@@ -325,7 +326,11 @@ export function App({ store, initialStatusLine = '', forceOnboarding = false, on
325
326
  openContextPicker: (...a) => openContextPicker(...a),
326
327
  });
327
328
  // Setup tool `open` requests: app/use-ui-open-request.mjs.
328
- useUiOpenRequest({ uiOpenRequest: state.uiOpenRequest, runSlashCommand });
329
+ useUiOpenRequest({
330
+ uiOpenRequest: state.uiOpenRequest,
331
+ runSlashCommand,
332
+ sections: { openDeveloperPicker, openSettingsPicker, pushNotice: (...a) => store.pushNotice(...a) },
333
+ });
329
334
  const {
330
335
  dragRef,
331
336
  transcriptViewportRef,
@@ -262,6 +262,7 @@ export function createAppPickers({
262
262
  openWorkflowPicker,
263
263
  openOutputStylePicker,
264
264
  openSettingsPicker,
265
+ openDeveloperPicker,
265
266
  runSlashCommand,
266
267
  };
267
268
  }
@@ -205,31 +205,23 @@ function reportMemory(runtime) {
205
205
 
206
206
  function reportChannels(runtime) {
207
207
  return async (settings, row) => {
208
- if (typeof settings.enabled !== 'boolean') {
209
- row('warn', 'status unavailable');
210
- return;
211
- }
212
- if (!settings.enabled) {
213
- row('ok', 'disabled');
214
- return;
215
- }
216
208
  const worker = settings.status || (await runtime.getChannelWorkerStatus?.());
217
209
  if (typeof worker?.running !== 'boolean') {
218
- row('warn', 'enabled · worker status unavailable');
210
+ row('warn', 'worker status unavailable');
219
211
  return;
220
212
  }
221
213
  if (worker.running) {
222
- row('ok', 'enabled · worker running');
214
+ row('ok', 'worker running');
223
215
  return;
224
216
  }
225
217
  // The worker boots only for enabled schedules or webhooks, so without
226
218
  // them a stopped worker is idle, not a fault.
227
219
  const setup = await runtime.getChannelSetup?.();
228
220
  if (setup && !hasEnabledAutomation(setup)) {
229
- row('ok', 'enabled · idle (no active schedules or webhooks)');
221
+ row('ok', 'idle (no active schedules or webhooks)');
230
222
  return;
231
223
  }
232
- row('warn', setup ? 'enabled · worker stopped with active automation' : 'enabled · worker stopped', {
224
+ row('warn', setup ? 'worker stopped with active automation' : 'worker stopped', {
233
225
  hint: 'enabled schedules and webhooks are not running',
234
226
  });
235
227
  };
@@ -410,8 +402,8 @@ export async function runDoctorChecks(runtime = {}, getState = () => ({}), optio
410
402
  reportVoice,
411
403
  ],
412
404
  [
413
- 'channels',
414
- 'channels',
405
+ 'automation',
406
+ 'automation',
415
407
  () => runtime.getChannelSettings?.({ includeStatus: true }),
416
408
  reportChannels(runtime),
417
409
  ],
@@ -91,7 +91,7 @@ export function createAutoClearPicker({
91
91
  const current = await readCurrent();
92
92
  own.paint({
93
93
  title: 'Auto-clear · Advanced',
94
- description: 'Provider default idle windows. Enter edits the duration text.',
94
+ description: 'Provider idle windows override the global duration. Enter edits the duration text.',
95
95
  help: '↑/↓ Select · Enter Edit · Esc Back',
96
96
  indexMode: 'always',
97
97
  labelWidth: 18,
@@ -110,13 +110,18 @@ export function createAutoClearPicker({
110
110
  const enabled = current?.enabled !== false;
111
111
  const idleMs = Number(current?.idleMs || HOUR_MS);
112
112
  const cacheTtlLabel = !enabled || idleMs >= HOUR_MS ? '1h' : '5m';
113
+ const sourceLabel = current?.providerCustom
114
+ ? `${current.provider} override`
115
+ : current?.custom
116
+ ? 'global'
117
+ : `${current?.provider || 'default'} default`;
113
118
  const items = [
114
119
  {
115
120
  value: 'toggle',
116
121
  label: 'Auto-clear',
117
122
  meta: enabled ? 'On' : 'Off',
118
123
  description: enabled
119
- ? `Clear idle sessions after ${formatDuration(idleMs)} · lead cache TTL ${cacheTtlLabel}.`
124
+ ? `Clear idle sessions after ${formatDuration(idleMs)} (${sourceLabel}) · lead cache TTL ${cacheTtlLabel}.`
120
125
  : 'Idle auto-clear disabled.',
121
126
  _action: 'toggle',
122
127
  },
@@ -129,7 +134,7 @@ export function createAutoClearPicker({
129
134
  ];
130
135
  own.paint({
131
136
  title: 'Auto-clear',
132
- description: `Clear idle context after ${enabled ? formatDuration(idleMs) : 'never'} · lead cache TTL ${cacheTtlLabel}.`,
137
+ description: `Clear idle context after ${enabled ? `${formatDuration(idleMs)} (${sourceLabel})` : 'never'} · lead cache TTL ${cacheTtlLabel}.`,
133
138
  help: '↑/↓ Select · ←/→ Toggle On/Off · Enter Open/Toggle · Esc Close',
134
139
  indexMode: 'always',
135
140
  labelWidth: 10,
@@ -66,7 +66,11 @@ export function buildSettingsItems({
66
66
  const { workflow, mcp, plugins, skills } = view;
67
67
  const outputStyleLabel =
68
68
  outputStyle?.current?.label || outputStyle?.current?.id || outputStyle?.configured || 'Default';
69
- const autoClearSource = autoClear.custom ? '' : ` (${autoClear.provider || 'default'} default)`;
69
+ const autoClearSource = autoClear.providerCustom
70
+ ? ` (${autoClear.provider} override)`
71
+ : autoClear.custom
72
+ ? ' (global)'
73
+ : ` (${autoClear.provider || 'default'} default)`;
70
74
  return [
71
75
  {
72
76
  value: 'model',
@@ -3,7 +3,16 @@
3
3
  // exactly as if the user had typed it (own claim, own notices).
4
4
  import { useEffect, useRef } from 'react';
5
5
 
6
- export function useUiOpenRequest({ uiOpenRequest, runSlashCommand }) {
6
+ /** Setup `open` targets that are settings sections without a slash command
7
+ * (SETUP_SECTION_OPEN_TARGETS in the runtime setup tool). */
8
+ export const SETUP_SECTION_TARGETS = Object.freeze({
9
+ developer: ({ openDeveloperPicker }) => openDeveloperPicker(),
10
+ voice: ({ openSettingsPicker }) => openSettingsPicker(),
11
+ connection: ({ pushNotice }) =>
12
+ pushNotice('Web-app pairing lives in the Desktop app: Settings → Connection.', 'info'),
13
+ });
14
+
15
+ export function useUiOpenRequest({ uiOpenRequest, runSlashCommand, sections }) {
7
16
  const seenRef = useRef(0);
8
17
  useEffect(() => {
9
18
  const request = uiOpenRequest;
@@ -13,6 +22,7 @@ export function useUiOpenRequest({ uiOpenRequest, runSlashCommand }) {
13
22
  // A re-attached TUI replays the retained snapshot; a request older than a
14
23
  // few seconds is history, not an instruction.
15
24
  if (Number(request.at) > 0 && Date.now() - Number(request.at) > 15_000) return;
16
- runSlashCommand(request.command);
17
- }, [uiOpenRequest, runSlashCommand]);
25
+ if (Object.hasOwn(SETUP_SECTION_TARGETS, request.command)) SETUP_SECTION_TARGETS[request.command](sections);
26
+ else runSlashCommand(request.command);
27
+ }, [uiOpenRequest, runSlashCommand, sections]);
18
28
  }
@@ -34101,7 +34101,12 @@ function usePanelTransition({
34101
34101
 
34102
34102
  // src/tui/app/use-ui-open-request.mjs
34103
34103
  import { useEffect as useEffect9, useRef as useRef4 } from "react";
34104
- function useUiOpenRequest({ uiOpenRequest, runSlashCommand }) {
34104
+ var SETUP_SECTION_TARGETS = Object.freeze({
34105
+ developer: ({ openDeveloperPicker }) => openDeveloperPicker(),
34106
+ voice: ({ openSettingsPicker }) => openSettingsPicker(),
34107
+ connection: ({ pushNotice }) => pushNotice("Web-app pairing lives in the Desktop app: Settings \u2192 Connection.", "info")
34108
+ });
34109
+ function useUiOpenRequest({ uiOpenRequest, runSlashCommand, sections }) {
34105
34110
  const seenRef = useRef4(0);
34106
34111
  useEffect9(() => {
34107
34112
  const request = uiOpenRequest;
@@ -34109,8 +34114,9 @@ function useUiOpenRequest({ uiOpenRequest, runSlashCommand }) {
34109
34114
  if (!request?.command || seq <= seenRef.current) return;
34110
34115
  seenRef.current = seq;
34111
34116
  if (Number(request.at) > 0 && Date.now() - Number(request.at) > 15e3) return;
34112
- runSlashCommand(request.command);
34113
- }, [uiOpenRequest, runSlashCommand]);
34117
+ if (Object.hasOwn(SETUP_SECTION_TARGETS, request.command)) SETUP_SECTION_TARGETS[request.command](sections);
34118
+ else runSlashCommand(request.command);
34119
+ }, [uiOpenRequest, runSlashCommand, sections]);
34114
34120
  }
34115
34121
 
34116
34122
  // src/tui/app/use-mouse-input.mjs
@@ -54694,7 +54700,7 @@ function createAutoClearPicker({
54694
54700
  const current = await readCurrent();
54695
54701
  own.paint({
54696
54702
  title: "Auto-clear \xB7 Advanced",
54697
- description: "Provider default idle windows. Enter edits the duration text.",
54703
+ description: "Provider idle windows override the global duration. Enter edits the duration text.",
54698
54704
  help: "\u2191/\u2193 Select \xB7 Enter Edit \xB7 Esc Back",
54699
54705
  indexMode: "always",
54700
54706
  labelWidth: 18,
@@ -54713,12 +54719,13 @@ function createAutoClearPicker({
54713
54719
  const enabled = current?.enabled !== false;
54714
54720
  const idleMs = Number(current?.idleMs || HOUR_MS);
54715
54721
  const cacheTtlLabel = !enabled || idleMs >= HOUR_MS ? "1h" : "5m";
54722
+ const sourceLabel = current?.providerCustom ? `${current.provider} override` : current?.custom ? "global" : `${current?.provider || "default"} default`;
54716
54723
  const items = [
54717
54724
  {
54718
54725
  value: "toggle",
54719
54726
  label: "Auto-clear",
54720
54727
  meta: enabled ? "On" : "Off",
54721
- description: enabled ? `Clear idle sessions after ${formatDuration2(idleMs)} \xB7 lead cache TTL ${cacheTtlLabel}.` : "Idle auto-clear disabled.",
54728
+ description: enabled ? `Clear idle sessions after ${formatDuration2(idleMs)} (${sourceLabel}) \xB7 lead cache TTL ${cacheTtlLabel}.` : "Idle auto-clear disabled.",
54722
54729
  _action: "toggle"
54723
54730
  },
54724
54731
  {
@@ -54730,7 +54737,7 @@ function createAutoClearPicker({
54730
54737
  ];
54731
54738
  own.paint({
54732
54739
  title: "Auto-clear",
54733
- description: `Clear idle context after ${enabled ? formatDuration2(idleMs) : "never"} \xB7 lead cache TTL ${cacheTtlLabel}.`,
54740
+ description: `Clear idle context after ${enabled ? `${formatDuration2(idleMs)} (${sourceLabel})` : "never"} \xB7 lead cache TTL ${cacheTtlLabel}.`,
54734
54741
  help: "\u2191/\u2193 Select \xB7 \u2190/\u2192 Toggle On/Off \xB7 Enter Open/Toggle \xB7 Esc Close",
54735
54742
  indexMode: "always",
54736
54743
  labelWidth: 10,
@@ -57347,7 +57354,7 @@ function createSettingsNavigation({ openers, openSettingsPicker, setSettingsProm
57347
57354
  }
57348
57355
 
57349
57356
  // src/runtime/shared/config.mjs
57350
- import { readFileSync as readFileSync11, statSync as statSync3, mkdirSync as mkdirSync5, existsSync as existsSync10 } from "node:fs";
57357
+ import { readFileSync as readFileSync11, statSync as statSync3, mkdirSync as mkdirSync5, existsSync as existsSync10, watch as fsWatch } from "node:fs";
57351
57358
  import { join as join11, dirname as dirname8 } from "node:path";
57352
57359
  import { createRequire as createRequire3 } from "node:module";
57353
57360
 
@@ -57700,6 +57707,24 @@ function readAllForRmW() {
57700
57707
  return restoreAllForRmWOrThrow(parseErr.message);
57701
57708
  }
57702
57709
  }
57710
+ var CONFIG_CHANGE_DEBOUNCE_MS = 100;
57711
+ var _configChangeListeners = /* @__PURE__ */ new Set();
57712
+ var _configChangeTimer = null;
57713
+ function notifyConfigChanged() {
57714
+ if (!_configChangeListeners.size) return;
57715
+ if (_configChangeTimer) clearTimeout(_configChangeTimer);
57716
+ _configChangeTimer = setTimeout(() => {
57717
+ _configChangeTimer = null;
57718
+ invalidateConfigReadCache();
57719
+ for (const listener of [..._configChangeListeners]) {
57720
+ try {
57721
+ listener();
57722
+ } catch {
57723
+ }
57724
+ }
57725
+ }, CONFIG_CHANGE_DEBOUNCE_MS);
57726
+ _configChangeTimer.unref?.();
57727
+ }
57703
57728
  function readSection(section) {
57704
57729
  return stripGeneratedMarker(readAll()[section] ?? null) ?? {};
57705
57730
  }
@@ -57722,6 +57747,7 @@ async function writeConfigFileAsync(data) {
57722
57747
  }
57723
57748
  async function writeAllAsync(data) {
57724
57749
  await writeConfigFileAsync(canonicalizeUnifiedConfig(data));
57750
+ notifyConfigChanged();
57725
57751
  }
57726
57752
  function withConfigLockAsync(fn) {
57727
57753
  return withFileLock(`${configPath()}.lock`, fn);
@@ -57937,7 +57963,7 @@ function buildSettingsItems({
57937
57963
  const { autoClear, autoClearEnabled, compaction, webSearchOn, memoryToolsOn, systemShell: systemShell2, outputStyle } = view;
57938
57964
  const { workflow, mcp, plugins, skills } = view;
57939
57965
  const outputStyleLabel = outputStyle?.current?.label || outputStyle?.current?.id || outputStyle?.configured || "Default";
57940
- const autoClearSource = autoClear.custom ? "" : ` (${autoClear.provider || "default"} default)`;
57966
+ const autoClearSource = autoClear.providerCustom ? ` (${autoClear.provider} override)` : autoClear.custom ? " (global)" : ` (${autoClear.provider || "default"} default)`;
57941
57967
  return [
57942
57968
  {
57943
57969
  value: "model",
@@ -58946,6 +58972,7 @@ function createAppPickers({
58946
58972
  openWorkflowPicker,
58947
58973
  openOutputStylePicker,
58948
58974
  openSettingsPicker,
58975
+ openDeveloperPicker,
58949
58976
  runSlashCommand
58950
58977
  };
58951
58978
  }
@@ -60946,6 +60973,7 @@ function App2({ store, initialStatusLine = "", forceOnboarding = false, onboardi
60946
60973
  openOnboardingAuthStep,
60947
60974
  openProviderSetupPicker,
60948
60975
  openSettingsPicker,
60976
+ openDeveloperPicker,
60949
60977
  runSlashCommand
60950
60978
  } = createAppPickers({
60951
60979
  state,
@@ -60973,7 +61001,11 @@ function App2({ store, initialStatusLine = "", forceOnboarding = false, onboardi
60973
61001
  openUsagePanel: (...a) => openUsagePanel(...a),
60974
61002
  openContextPicker: (...a) => openContextPicker(...a)
60975
61003
  });
60976
- useUiOpenRequest({ uiOpenRequest: state.uiOpenRequest, runSlashCommand });
61004
+ useUiOpenRequest({
61005
+ uiOpenRequest: state.uiOpenRequest,
61006
+ runSlashCommand,
61007
+ sections: { openDeveloperPicker, openSettingsPicker, pushNotice: (...a) => store.pushNotice(...a) }
61008
+ });
60977
61009
  const {
60978
61010
  dragRef,
60979
61011
  transcriptViewportRef,
@@ -152,15 +152,9 @@ export function createSessionSettingsApi(bag) {
152
152
  getChannelSettings: (options = {}) => {
153
153
  return (
154
154
  runtime.getChannelSettings?.(options) || {
155
- enabled: true,
156
155
  ...(options?.includeStatus === false ? {} : { status: runtime.getChannelWorkerStatus?.() }),
157
156
  }
158
157
  );
159
158
  },
160
- setChannelsEnabled: withCommandLock(async (enabled) => {
161
- const next = await runtime.setChannelsEnabled?.(enabled);
162
- publishRoute();
163
- return next;
164
- }),
165
159
  };
166
160
  }