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.
- package/README.md +206 -475
- package/package.json +11 -4
- package/src/defaults/skills/setup/references/actions.md +26 -6
- package/src/defaults/skills/setup/references/surfaces.md +8 -3
- package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +16 -7
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +0 -3
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +0 -2
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +24 -2
- package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +25 -0
- package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +14 -1
- package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +3 -45
- package/src/runtime/channels/lib/config.mjs +0 -1
- package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +1 -1
- package/src/runtime/channels/lib/scheduler.mjs +15 -56
- package/src/runtime/channels/lib/worker-main.mjs +2 -9
- package/src/runtime/shared/config.mjs +66 -1
- package/src/runtime/shared/llm/usage-ledger-quota.mjs +13 -2
- package/src/runtime/shared/path-executable.mjs +58 -0
- package/src/session-runtime/boot/apis.mjs +6 -2
- package/src/session-runtime/boot/begin.mjs +0 -2
- package/src/session-runtime/boot/providers.mjs +3 -0
- package/src/session-runtime/boot/tools.mjs +0 -1
- package/src/session-runtime/config-lifecycle.mjs +11 -0
- package/src/session-runtime/internal-tool-executor.mjs +0 -2
- package/src/session-runtime/runtime-feature-gates.mjs +2 -3
- package/src/session-runtime/schedule-session-run.mjs +0 -1
- package/src/session-runtime/services/channel-admin.mjs +8 -26
- package/src/session-runtime/settings-compaction-api.mjs +5 -1
- package/src/session-runtime/settings-system-api.mjs +2 -20
- package/src/session-runtime/setup-tool/executor.mjs +61 -3
- package/src/session-runtime/setup-tool/extended-actions.mjs +31 -6
- package/src/session-runtime/setup-tool/settings-contract.mjs +27 -3
- package/src/session-runtime/setup-tool/tool-defs.mjs +35 -5
- package/src/session-runtime/webhook-session-run.mjs +0 -2
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +13 -3
- package/src/standalone/daemon-stored-session-views.mjs +4 -0
- package/src/standalone/session-protocol.mjs +0 -1
- package/src/standalone/session-service/session-calls/session-views.mjs +10 -4
- package/src/standalone/session-service/stored-reader.mjs +20 -2
- package/src/standalone/session-service/viewers.mjs +3 -3
- package/src/standalone/session-service.mjs +3 -1
- package/src/tui/App.jsx +6 -1
- package/src/tui/app/create-app-pickers.mjs +1 -0
- package/src/tui/app/doctor.mjs +6 -14
- package/src/tui/app/maintenance-pickers/auto-clear-picker.mjs +8 -3
- package/src/tui/app/settings-picker/settings-rows.mjs +5 -1
- package/src/tui/app/use-ui-open-request.mjs +13 -3
- package/src/tui/dist/index.mjs +41 -9
- 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
138
|
-
|
|
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
|
-
|
|
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({
|
|
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,
|
package/src/tui/app/doctor.mjs
CHANGED
|
@@ -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', '
|
|
210
|
+
row('warn', 'worker status unavailable');
|
|
219
211
|
return;
|
|
220
212
|
}
|
|
221
213
|
if (worker.running) {
|
|
222
|
-
row('ok', '
|
|
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', '
|
|
221
|
+
row('ok', 'idle (no active schedules or webhooks)');
|
|
230
222
|
return;
|
|
231
223
|
}
|
|
232
|
-
row('warn', setup ? '
|
|
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
|
-
'
|
|
414
|
-
'
|
|
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
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
17
|
-
|
|
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
|
}
|
package/src/tui/dist/index.mjs
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
34113
|
-
|
|
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
|
|
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({
|
|
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
|
}
|