@wrongstack/webui-server 0.289.0 → 0.291.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/index.js +401 -267
- package/dist/index.js.map +3 -3
- package/dist/server/backend-services.d.ts +2 -2
- package/dist/server/backend-services.d.ts.map +1 -1
- package/dist/server/context-meta.d.ts.map +1 -1
- package/dist/server/entry.js +400 -267
- package/dist/server/entry.js.map +3 -3
- package/dist/server/handlers.js.map +2 -2
- package/dist/server/http-server.d.ts.map +1 -1
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/kanban-routes.d.ts +15 -0
- package/dist/server/kanban-routes.d.ts.map +1 -1
- package/dist/server/message-dispatcher.d.ts +3 -2
- package/dist/server/message-dispatcher.d.ts.map +1 -1
- package/dist/server/pending-confirms.d.ts +1 -0
- package/dist/server/pending-confirms.d.ts.map +1 -1
- package/dist/server/pre-context-services.d.ts +3 -2
- package/dist/server/pre-context-services.d.ts.map +1 -1
- package/dist/server/pref-helpers.d.ts +18 -1
- package/dist/server/pref-helpers.d.ts.map +1 -1
- package/dist/server/routes.d.ts +2 -2
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/server-runtime.d.ts +5 -20
- package/dist/server/server-runtime.d.ts.map +1 -1
- package/dist/server/setup-events.d.ts.map +1 -1
- package/dist/server/terminal-ws-handler.d.ts +2 -1
- package/dist/server/terminal-ws-handler.d.ts.map +1 -1
- package/dist/server/ws-payload-validation.d.ts +24 -23
- package/dist/server/ws-payload-validation.d.ts.map +1 -1
- package/package.json +12 -12
package/dist/index.js
CHANGED
|
@@ -1904,6 +1904,7 @@ async function handleGitDiff(ws, projectRoot, path24) {
|
|
|
1904
1904
|
import * as fs6 from "node:fs/promises";
|
|
1905
1905
|
import * as http from "node:http";
|
|
1906
1906
|
import * as path7 from "node:path";
|
|
1907
|
+
import * as v8 from "node:v8";
|
|
1907
1908
|
|
|
1908
1909
|
// src/server/http-server/api-handlers.ts
|
|
1909
1910
|
async function handleApiSessions(res, globalRoot) {
|
|
@@ -3210,6 +3211,23 @@ function createHttpServer(opts) {
|
|
|
3210
3211
|
}
|
|
3211
3212
|
return;
|
|
3212
3213
|
}
|
|
3214
|
+
if (url.pathname === "/debug/system" && req.method === "GET") {
|
|
3215
|
+
res.writeHead(200, {
|
|
3216
|
+
"Content-Type": "application/json",
|
|
3217
|
+
"Cache-Control": "no-store"
|
|
3218
|
+
});
|
|
3219
|
+
res.end(
|
|
3220
|
+
JSON.stringify({
|
|
3221
|
+
pid: process.pid,
|
|
3222
|
+
memoryUsage: process.memoryUsage(),
|
|
3223
|
+
heapLimit: v8.getHeapStatistics().heap_size_limit,
|
|
3224
|
+
uptime: process.uptime(),
|
|
3225
|
+
cpuUsage: process.cpuUsage(),
|
|
3226
|
+
timestamp: Date.now()
|
|
3227
|
+
})
|
|
3228
|
+
);
|
|
3229
|
+
return;
|
|
3230
|
+
}
|
|
3213
3231
|
let filePath;
|
|
3214
3232
|
if (url.pathname === "/" || url.pathname === "") {
|
|
3215
3233
|
filePath = path7.join(distDir, "index.html");
|
|
@@ -5192,6 +5210,7 @@ var BOOLEAN_PREF_KEYS = /* @__PURE__ */ new Set([
|
|
|
5192
5210
|
"hqRawContent",
|
|
5193
5211
|
"fallbackAuto",
|
|
5194
5212
|
"favoriteModelsOnly",
|
|
5213
|
+
"modelAvailabilitySchedule",
|
|
5195
5214
|
"breakerEnabled",
|
|
5196
5215
|
"debugStream",
|
|
5197
5216
|
// Chimera + auto-review master toggles
|
|
@@ -5336,7 +5355,10 @@ function validatePreferenceValue(key, value) {
|
|
|
5336
5355
|
return `prefs.update payload.${key}.modelRuntime must be an object when provided`;
|
|
5337
5356
|
}
|
|
5338
5357
|
if (isRecord(modelRuntime)) {
|
|
5339
|
-
const runtimeError = validateModelRuntimeValue(
|
|
5358
|
+
const runtimeError = validateModelRuntimeValue(
|
|
5359
|
+
modelRuntime,
|
|
5360
|
+
`prefs.update payload.${key}.modelRuntime`
|
|
5361
|
+
);
|
|
5340
5362
|
if (runtimeError) return runtimeError;
|
|
5341
5363
|
}
|
|
5342
5364
|
if (model === void 0 && fallbackProfile === void 0 && modelRuntime === void 0) {
|
|
@@ -6648,7 +6670,7 @@ function registerShutdownHandlers(res) {
|
|
|
6648
6670
|
import { watch as fsWatch } from "node:fs";
|
|
6649
6671
|
import * as fs11 from "node:fs/promises";
|
|
6650
6672
|
import * as path14 from "node:path";
|
|
6651
|
-
import { getBoard, getKanbanDir } from "@wrongstack/kanban";
|
|
6673
|
+
import { getBoard, getKanbanDir, recordTaskFileActivity } from "@wrongstack/kanban";
|
|
6652
6674
|
|
|
6653
6675
|
// src/server/codemap-telemetry.ts
|
|
6654
6676
|
import * as path13 from "node:path";
|
|
@@ -7044,6 +7066,18 @@ function setupEvents(deps2) {
|
|
|
7044
7066
|
on("file.activity", (e) => {
|
|
7045
7067
|
broadcast2(clients, { type: "codemap.file_event", payload: e });
|
|
7046
7068
|
});
|
|
7069
|
+
on("file.event", (e) => {
|
|
7070
|
+
if (e.scope !== "task" || !e.boardId || !e.taskId) return;
|
|
7071
|
+
void recordTaskFileActivity(context.projectRoot, e.boardId, e.taskId, e).then((recorded) => {
|
|
7072
|
+
if (recorded) {
|
|
7073
|
+
broadcast2(clients, {
|
|
7074
|
+
type: "kanban.task.activity.changed",
|
|
7075
|
+
payload: { boardId: e.boardId, taskId: e.taskId }
|
|
7076
|
+
});
|
|
7077
|
+
}
|
|
7078
|
+
}).catch(() => {
|
|
7079
|
+
});
|
|
7080
|
+
});
|
|
7047
7081
|
on("tool.loop_detected", (e) => {
|
|
7048
7082
|
broadcast2(clients, {
|
|
7049
7083
|
type: "tool.loop_detected",
|
|
@@ -7168,12 +7202,14 @@ function setupEvents(deps2) {
|
|
|
7168
7202
|
input: e.input,
|
|
7169
7203
|
suggestedPattern: e.suggestedPattern,
|
|
7170
7204
|
decisionSource: e.decisionSource,
|
|
7171
|
-
riskTier: e.riskTier
|
|
7205
|
+
riskTier: e.riskTier,
|
|
7206
|
+
boundaryReason: e.boundaryReason
|
|
7172
7207
|
});
|
|
7173
7208
|
pendingConfirms.set(id, {
|
|
7174
7209
|
resolve: e.resolve,
|
|
7175
7210
|
decisionSource: e.decisionSource,
|
|
7176
7211
|
riskTier: e.riskTier,
|
|
7212
|
+
boundaryReason: e.boundaryReason,
|
|
7177
7213
|
payload
|
|
7178
7214
|
});
|
|
7179
7215
|
broadcast2(clients, { type: "tool.confirm_needed", payload });
|
|
@@ -7266,7 +7302,8 @@ function setupEvents(deps2) {
|
|
|
7266
7302
|
oldState: e.oldState,
|
|
7267
7303
|
newState: e.newState,
|
|
7268
7304
|
reason: e.reason,
|
|
7269
|
-
timestamp: e.timestamp
|
|
7305
|
+
timestamp: e.timestamp,
|
|
7306
|
+
stateExpiresAt: e.stateExpiresAt
|
|
7270
7307
|
})
|
|
7271
7308
|
});
|
|
7272
7309
|
});
|
|
@@ -8373,6 +8410,7 @@ function seedContextMeta(config, context) {
|
|
|
8373
8410
|
meta["fallbackProfiles"] = config.fallbackProfiles ?? {};
|
|
8374
8411
|
meta["favoriteModels"] = config.favoriteModels ?? [];
|
|
8375
8412
|
meta["favoriteModelsOnly"] = config.favoriteModelsOnly === true;
|
|
8413
|
+
meta["modelAvailabilitySchedule"] = config.modelAvailabilitySchedule ?? [];
|
|
8376
8414
|
meta["modelMatrix"] = config.modelMatrix ?? {};
|
|
8377
8415
|
meta["fallbackAuto"] = config.fallbackAuto !== false;
|
|
8378
8416
|
if (typeof config.uiLocale === "string" && config.uiLocale) meta["uiLocale"] = config.uiLocale;
|
|
@@ -8455,9 +8493,7 @@ function seedContextMeta(config, context) {
|
|
|
8455
8493
|
} catch {
|
|
8456
8494
|
resolvedChain = [];
|
|
8457
8495
|
}
|
|
8458
|
-
meta["autoReviewFallbackModels"] = resolvedChain.map(
|
|
8459
|
-
(e) => `${e.providerId}/${e.model}`
|
|
8460
|
-
);
|
|
8496
|
+
meta["autoReviewFallbackModels"] = resolvedChain.map((e) => `${e.providerId}/${e.model}`);
|
|
8461
8497
|
}
|
|
8462
8498
|
}
|
|
8463
8499
|
|
|
@@ -9914,7 +9950,7 @@ function setupWebUICodebaseIndexing(deps2) {
|
|
|
9914
9950
|
}
|
|
9915
9951
|
if (idx) {
|
|
9916
9952
|
cancelPendingReindexes();
|
|
9917
|
-
shutdownCodebaseIndexHost();
|
|
9953
|
+
void shutdownCodebaseIndexHost();
|
|
9918
9954
|
}
|
|
9919
9955
|
}
|
|
9920
9956
|
};
|
|
@@ -10081,6 +10117,9 @@ var DEFAULT_COLS = 80;
|
|
|
10081
10117
|
var DEFAULT_ROWS = 24;
|
|
10082
10118
|
var requireFromHere = createRequire4(import.meta.url);
|
|
10083
10119
|
var cachedNodePty;
|
|
10120
|
+
function resolveTerminalShell(platform = process.platform, env = process.env) {
|
|
10121
|
+
return platform === "win32" ? env.COMSPEC || "cmd.exe" : env.SHELL || "/bin/sh";
|
|
10122
|
+
}
|
|
10084
10123
|
var TerminalWebSocketHandler = class {
|
|
10085
10124
|
constructor(getCwd, logger, loadNodePty = defaultLoadNodePty, killProcessTree = defaultKillProcessTree) {
|
|
10086
10125
|
this.getCwd = getCwd;
|
|
@@ -10136,7 +10175,7 @@ var TerminalWebSocketHandler = class {
|
|
|
10136
10175
|
});
|
|
10137
10176
|
return;
|
|
10138
10177
|
}
|
|
10139
|
-
const shell =
|
|
10178
|
+
const shell = resolveTerminalShell();
|
|
10140
10179
|
const nodePty = this.loadNodePty();
|
|
10141
10180
|
if (!nodePty) {
|
|
10142
10181
|
const msg = "Integrated terminal unavailable: optional dependency node-pty is not installed. Install node-pty to enable WebUI terminal sessions.";
|
|
@@ -10456,7 +10495,11 @@ async function createAgentServices(input) {
|
|
|
10456
10495
|
toolExecutor
|
|
10457
10496
|
});
|
|
10458
10497
|
if (config.features.memory && config.features.memoryConsolidation !== false) {
|
|
10459
|
-
|
|
10498
|
+
const consSuperMemory = typeof memoryStore["rememberSuper"] === "function" ? memoryStore : void 0;
|
|
10499
|
+
agent.extensions.register(new SessionMemoryConsolidator({
|
|
10500
|
+
memoryStore,
|
|
10501
|
+
...consSuperMemory ? { superMemory: consSuperMemory } : {}
|
|
10502
|
+
}));
|
|
10460
10503
|
}
|
|
10461
10504
|
console.log("[WebUI] Agent initialized");
|
|
10462
10505
|
const brainCfg = resolveBrainConfigDefaults(config.brain, {
|
|
@@ -10662,6 +10705,7 @@ function isSuperMemoryRetriever(memoryStore) {
|
|
|
10662
10705
|
// src/server/pending-confirms.ts
|
|
10663
10706
|
function resolveYoloEligiblePendingConfirms(pendingConfirms) {
|
|
10664
10707
|
for (const [id, confirm] of pendingConfirms) {
|
|
10708
|
+
if (confirm.boundaryReason) continue;
|
|
10665
10709
|
pendingConfirms.delete(id);
|
|
10666
10710
|
confirm.resolve("yes");
|
|
10667
10711
|
}
|
|
@@ -11141,7 +11185,7 @@ import {
|
|
|
11141
11185
|
createBoard,
|
|
11142
11186
|
duplicateBoard,
|
|
11143
11187
|
exportBoardToTaskGraph,
|
|
11144
|
-
|
|
11188
|
+
createBoardFromText,
|
|
11145
11189
|
getBoard as getBoard2,
|
|
11146
11190
|
getKanbanOrchestrationSnapshot,
|
|
11147
11191
|
getKanbanQueueHealth,
|
|
@@ -11172,6 +11216,32 @@ import {
|
|
|
11172
11216
|
updateTask
|
|
11173
11217
|
} from "@wrongstack/kanban";
|
|
11174
11218
|
import { applySessionKanbanTaskToSource } from "@wrongstack/tools/session-kanban";
|
|
11219
|
+
function paginateKanbanBoards(boards, input) {
|
|
11220
|
+
const pageSize = Math.min(100, Math.max(1, Math.floor(input.pageSize)));
|
|
11221
|
+
const activeSessionIds = new Set(input.activeSessionIds ?? []);
|
|
11222
|
+
const isActive = (board) => board.presence?.some((entry) => entry.active) === true || board.tags?.some(
|
|
11223
|
+
(tag) => tag.startsWith("session:") && activeSessionIds.has(tag.slice(8))
|
|
11224
|
+
) === true;
|
|
11225
|
+
const sorted = [...boards].sort((left, right) => {
|
|
11226
|
+
const activityOrder = Number(isActive(right)) - Number(isActive(left));
|
|
11227
|
+
return activityOrder || right.updatedAt.localeCompare(left.updatedAt);
|
|
11228
|
+
});
|
|
11229
|
+
const activeTotal = sorted.filter(isActive).length;
|
|
11230
|
+
const total = sorted.length;
|
|
11231
|
+
const totalPages = Math.max(1, Math.ceil(total / pageSize));
|
|
11232
|
+
const requestedPage = Number.isFinite(input.page) ? Math.floor(input.page) : 1;
|
|
11233
|
+
const page = Math.min(totalPages, Math.max(1, requestedPage));
|
|
11234
|
+
const start = (page - 1) * pageSize;
|
|
11235
|
+
return {
|
|
11236
|
+
items: sorted.slice(start, start + pageSize),
|
|
11237
|
+
total,
|
|
11238
|
+
page,
|
|
11239
|
+
pageSize,
|
|
11240
|
+
totalPages,
|
|
11241
|
+
activeTotal,
|
|
11242
|
+
orphanedTotal: total - activeTotal
|
|
11243
|
+
};
|
|
11244
|
+
}
|
|
11175
11245
|
async function syncSessionSource(ctx, task, remove = false) {
|
|
11176
11246
|
if (!ctx.context) return;
|
|
11177
11247
|
const update = await applySessionKanbanTaskToSource(ctx.context, task, { remove });
|
|
@@ -11221,9 +11291,26 @@ async function handleKanbanRoute(ws, msg, ctx) {
|
|
|
11221
11291
|
const type = msg.type;
|
|
11222
11292
|
try {
|
|
11223
11293
|
switch (type) {
|
|
11224
|
-
case "kanban.list":
|
|
11225
|
-
|
|
11294
|
+
case "kanban.list": {
|
|
11295
|
+
const boards = await listBoards(ctx.projectRoot);
|
|
11296
|
+
const requestedPage = Number(payload?.page);
|
|
11297
|
+
const requestedPageSize = Number(payload?.pageSize);
|
|
11298
|
+
if (!Number.isFinite(requestedPage) || !Number.isFinite(requestedPageSize)) {
|
|
11299
|
+
ok(ws, type, boards);
|
|
11300
|
+
return true;
|
|
11301
|
+
}
|
|
11302
|
+
const activeSessionIds = Array.isArray(payload?.activeSessionIds) ? payload.activeSessionIds.filter((id) => typeof id === "string") : [];
|
|
11303
|
+
ok(
|
|
11304
|
+
ws,
|
|
11305
|
+
type,
|
|
11306
|
+
paginateKanbanBoards(boards, {
|
|
11307
|
+
page: requestedPage,
|
|
11308
|
+
pageSize: requestedPageSize,
|
|
11309
|
+
activeSessionIds
|
|
11310
|
+
})
|
|
11311
|
+
);
|
|
11226
11312
|
return true;
|
|
11313
|
+
}
|
|
11227
11314
|
case "kanban.get": {
|
|
11228
11315
|
const boardId = payload?.boardId;
|
|
11229
11316
|
if (!boardId) {
|
|
@@ -11289,7 +11376,8 @@ async function handleKanbanRoute(ws, msg, ctx) {
|
|
|
11289
11376
|
...payload?.description ? { description: payload.description } : {},
|
|
11290
11377
|
...payload?.tags ? { tags: payload.tags } : {},
|
|
11291
11378
|
...payload?.columns ? { columns: payload.columns } : {},
|
|
11292
|
-
...has(payload, "lifecycle") ? { lifecycle: payload?.lifecycle } : {}
|
|
11379
|
+
...has(payload, "lifecycle") ? { lifecycle: payload?.lifecycle } : {},
|
|
11380
|
+
...has(payload, "boundary") ? { boundary: payload?.boundary } : {}
|
|
11293
11381
|
})
|
|
11294
11382
|
);
|
|
11295
11383
|
return true;
|
|
@@ -11310,6 +11398,9 @@ async function handleKanbanRoute(ws, msg, ctx) {
|
|
|
11310
11398
|
} : {},
|
|
11311
11399
|
...has(payload, "supervisor") ? {
|
|
11312
11400
|
supervisor: payload?.supervisor ?? null
|
|
11401
|
+
} : {},
|
|
11402
|
+
...has(payload, "boundary") ? {
|
|
11403
|
+
boundary: payload?.boundary ?? null
|
|
11313
11404
|
} : {}
|
|
11314
11405
|
});
|
|
11315
11406
|
board ? ok(ws, type, board) : fail(ws, type, `Board not found: ${boardId}`);
|
|
@@ -11356,7 +11447,7 @@ async function handleKanbanRoute(ws, msg, ctx) {
|
|
|
11356
11447
|
}
|
|
11357
11448
|
const board = await createBoard(
|
|
11358
11449
|
ctx.projectRoot,
|
|
11359
|
-
|
|
11450
|
+
createBoardFromText({
|
|
11360
11451
|
description,
|
|
11361
11452
|
...payload?.title ? { title: payload.title } : {},
|
|
11362
11453
|
...payload?.context ? { context: payload.context } : {}
|
|
@@ -11468,7 +11559,8 @@ async function handleKanbanRoute(ws, msg, ctx) {
|
|
|
11468
11559
|
...payload?.dueDate ? { dueDate: payload.dueDate } : {},
|
|
11469
11560
|
...payload?.priority ? { priority: payload.priority } : {},
|
|
11470
11561
|
...payload?.assignedAgent ? { assignedAgent: payload.assignedAgent } : {},
|
|
11471
|
-
...payload?.labels ? { labels: payload.labels } : {}
|
|
11562
|
+
...payload?.labels ? { labels: payload.labels } : {},
|
|
11563
|
+
...has(payload, "boundary") ? { boundary: payload?.boundary } : {}
|
|
11472
11564
|
},
|
|
11473
11565
|
activityContext(ctx, "webui", payload?.activityNote)
|
|
11474
11566
|
);
|
|
@@ -11549,6 +11641,9 @@ async function handleKanbanRoute(ws, msg, ctx) {
|
|
|
11549
11641
|
} : {},
|
|
11550
11642
|
...has(payload, "costCeilingUsd") ? {
|
|
11551
11643
|
costCeilingUsd: payload?.costCeilingUsd === null || payload?.costCeilingUsd === "" ? null : Number(payload?.costCeilingUsd)
|
|
11644
|
+
} : {},
|
|
11645
|
+
...has(payload, "boundary") ? {
|
|
11646
|
+
boundary: payload?.boundary ?? null
|
|
11552
11647
|
} : {}
|
|
11553
11648
|
},
|
|
11554
11649
|
activityContext(ctx, "webui", payload?.activityNote)
|
|
@@ -12441,7 +12536,7 @@ var chronicleCache = /* @__PURE__ */ new Map();
|
|
|
12441
12536
|
async function chronicleEngine(projectRoot) {
|
|
12442
12537
|
const now = Date.now();
|
|
12443
12538
|
const cached = chronicleCache.get(projectRoot);
|
|
12444
|
-
if (cached && now - cached.loadedAt <
|
|
12539
|
+
if (cached && now - cached.loadedAt < 6e4) return cached.engine;
|
|
12445
12540
|
const paths = resolveWstackPaths2({ projectRoot, userHome: os2.homedir() });
|
|
12446
12541
|
const engine = await ChronicleQueryEngine.fromDirectory(
|
|
12447
12542
|
path20.join(paths.projectDir, "chronicle")
|
|
@@ -12958,7 +13053,7 @@ function createMessageDispatcher(opts) {
|
|
|
12958
13053
|
case "chronicle.query": {
|
|
12959
13054
|
const payload = msg.payload ?? {};
|
|
12960
13055
|
const engine = await chronicleEngine(state.getProjectRoot());
|
|
12961
|
-
send(ws, { type: "chronicle.query_result", payload: engine.query(payload.query ?? {}) });
|
|
13056
|
+
send(ws, { type: "chronicle.query_result", payload: await engine.query(payload.query ?? {}) });
|
|
12962
13057
|
break;
|
|
12963
13058
|
}
|
|
12964
13059
|
case "chronicle.facet": {
|
|
@@ -12988,7 +13083,7 @@ function createMessageDispatcher(opts) {
|
|
|
12988
13083
|
type: "chronicle.facet_result",
|
|
12989
13084
|
payload: {
|
|
12990
13085
|
field: payload.field,
|
|
12991
|
-
values: engine.facet(payload.field, payload.query ?? {}, payload.limit),
|
|
13086
|
+
values: await engine.facet(payload.field, payload.query ?? {}, payload.limit),
|
|
12992
13087
|
diagnostics: engine.diagnostics
|
|
12993
13088
|
}
|
|
12994
13089
|
});
|
|
@@ -12999,7 +13094,7 @@ function createMessageDispatcher(opts) {
|
|
|
12999
13094
|
const engine = await chronicleEngine(state.getProjectRoot());
|
|
13000
13095
|
send(ws, {
|
|
13001
13096
|
type: "chronicle.graph_result",
|
|
13002
|
-
payload: engine.graph(payload.seed ?? {}, payload.hops, payload.maxNodes)
|
|
13097
|
+
payload: await engine.graph(payload.seed ?? {}, payload.hops, payload.maxNodes)
|
|
13003
13098
|
});
|
|
13004
13099
|
break;
|
|
13005
13100
|
}
|
|
@@ -13054,9 +13149,9 @@ function createMessageDispatcher(opts) {
|
|
|
13054
13149
|
}
|
|
13055
13150
|
|
|
13056
13151
|
// src/server/pref-helpers.ts
|
|
13057
|
-
import { atomicWrite as atomicWrite6, FORBIDDEN_PROTO_KEYS as FORBIDDEN_PROTO_KEYS2 } from "@wrongstack/core/utils";
|
|
13058
|
-
import { decryptConfigSecrets as decryptConfigSecrets2, encryptConfigSecrets as encryptConfigSecrets2 } from "@wrongstack/core/security";
|
|
13059
13152
|
import * as fs14 from "node:fs/promises";
|
|
13153
|
+
import { decryptConfigSecrets as decryptConfigSecrets2, encryptConfigSecrets as encryptConfigSecrets2 } from "@wrongstack/core/security";
|
|
13154
|
+
import { atomicWrite as atomicWrite6, FORBIDDEN_PROTO_KEYS as FORBIDDEN_PROTO_KEYS2 } from "@wrongstack/core/utils";
|
|
13060
13155
|
var PREF_KEYS = [
|
|
13061
13156
|
"autonomy",
|
|
13062
13157
|
"autonomyDelayMs",
|
|
@@ -13101,6 +13196,7 @@ var PREF_KEYS = [
|
|
|
13101
13196
|
"fallbackProfiles",
|
|
13102
13197
|
"favoriteModels",
|
|
13103
13198
|
"favoriteModelsOnly",
|
|
13199
|
+
"modelAvailabilitySchedule",
|
|
13104
13200
|
"modelMatrix",
|
|
13105
13201
|
"fallbackAuto",
|
|
13106
13202
|
// Refiner + TUI visual prefs (parity with the CLI's embedded server —
|
|
@@ -13173,256 +13269,264 @@ async function updateGlobalConfig(deps2, holder, mutate, errorLabel) {
|
|
|
13173
13269
|
try {
|
|
13174
13270
|
await next;
|
|
13175
13271
|
} catch (err) {
|
|
13176
|
-
logger.warn(
|
|
13272
|
+
logger.warn(
|
|
13273
|
+
`${errorLabel}: failed to persist to config: ${err instanceof Error ? err.message : String(err)}`
|
|
13274
|
+
);
|
|
13177
13275
|
}
|
|
13178
13276
|
}
|
|
13179
13277
|
async function persistPrefsToConfig(deps2, holder, payload) {
|
|
13180
|
-
return updateGlobalConfig(
|
|
13181
|
-
|
|
13182
|
-
|
|
13183
|
-
|
|
13184
|
-
autonomyCfg
|
|
13185
|
-
autonomyTouched =
|
|
13186
|
-
|
|
13187
|
-
|
|
13188
|
-
|
|
13189
|
-
|
|
13190
|
-
|
|
13191
|
-
|
|
13192
|
-
if (typeof payload["autoProceedMaxIterations"] === "number")
|
|
13193
|
-
setAutonomy("autoProceedMaxIterations", payload["autoProceedMaxIterations"]);
|
|
13194
|
-
if (typeof payload["yolo"] === "boolean") {
|
|
13195
|
-
setAutonomy("yolo", payload["yolo"]);
|
|
13196
|
-
decrypted.yolo = payload["yolo"];
|
|
13197
|
-
}
|
|
13198
|
-
if (typeof payload["chime"] === "boolean") setAutonomy("chime", payload["chime"]);
|
|
13199
|
-
if (typeof payload["confirmExit"] === "boolean")
|
|
13200
|
-
setAutonomy("confirmExit", payload["confirmExit"]);
|
|
13201
|
-
if (typeof payload["streamFleet"] === "boolean")
|
|
13202
|
-
setAutonomy("streamFleet", payload["streamFleet"]);
|
|
13203
|
-
if (typeof payload["enhanceEnabled"] === "boolean")
|
|
13204
|
-
setAutonomy("enhance", payload["enhanceEnabled"]);
|
|
13205
|
-
if (typeof payload["enhanceDelayMs"] === "number")
|
|
13206
|
-
setAutonomy("enhanceDelayMs", payload["enhanceDelayMs"]);
|
|
13207
|
-
if (typeof payload["enhanceLanguage"] === "string")
|
|
13208
|
-
setAutonomy("enhanceLanguage", payload["enhanceLanguage"]);
|
|
13209
|
-
if (typeof payload["refinerProvider"] === "string")
|
|
13210
|
-
setAutonomy("refinerProvider", payload["refinerProvider"]);
|
|
13211
|
-
if (typeof payload["refinerModel"] === "string")
|
|
13212
|
-
setAutonomy("refinerModel", payload["refinerModel"]);
|
|
13213
|
-
if (typeof payload["refinerFallbackProfile"] === "string")
|
|
13214
|
-
setAutonomy("refinerFallbackProfile", payload["refinerFallbackProfile"]);
|
|
13215
|
-
if (typeof payload["thinkingWord"] === "string")
|
|
13216
|
-
setAutonomy("thinkingWord", payload["thinkingWord"]);
|
|
13217
|
-
if (typeof payload["statuslineMode"] === "string")
|
|
13218
|
-
setAutonomy("statuslineMode", payload["statuslineMode"]);
|
|
13219
|
-
if (typeof payload["animationStyle"] === "string")
|
|
13220
|
-
setAutonomy("animationStyle", payload["animationStyle"]);
|
|
13221
|
-
if (typeof payload["showModelReasoning"] === "boolean")
|
|
13222
|
-
setAutonomy("showModelReasoning", payload["showModelReasoning"]);
|
|
13223
|
-
if (autonomyTouched) decrypted.autonomy = autonomyCfg;
|
|
13224
|
-
if (typeof payload["nextPrediction"] === "boolean")
|
|
13225
|
-
decrypted.nextPrediction = payload["nextPrediction"];
|
|
13226
|
-
if (typeof payload["uiLocale"] === "string") decrypted.uiLocale = payload["uiLocale"];
|
|
13227
|
-
if (Array.isArray(payload["fallbackModels"]))
|
|
13228
|
-
decrypted.fallbackModels = payload["fallbackModels"];
|
|
13229
|
-
if (payload["fallbackProfiles"] && typeof payload["fallbackProfiles"] === "object" && !Array.isArray(payload["fallbackProfiles"])) {
|
|
13230
|
-
decrypted.fallbackProfiles = payload["fallbackProfiles"];
|
|
13231
|
-
}
|
|
13232
|
-
if (Array.isArray(payload["favoriteModels"]))
|
|
13233
|
-
decrypted.favoriteModels = payload["favoriteModels"];
|
|
13234
|
-
if (typeof payload["favoriteModelsOnly"] === "boolean")
|
|
13235
|
-
decrypted.favoriteModelsOnly = payload["favoriteModelsOnly"];
|
|
13236
|
-
if (payload["modelMatrix"] && typeof payload["modelMatrix"] === "object" && !Array.isArray(payload["modelMatrix"])) {
|
|
13237
|
-
decrypted.modelMatrix = payload["modelMatrix"];
|
|
13238
|
-
}
|
|
13239
|
-
if (typeof payload["fallbackAuto"] === "boolean")
|
|
13240
|
-
decrypted.fallbackAuto = payload["fallbackAuto"];
|
|
13241
|
-
const FEATURE_MAP = {
|
|
13242
|
-
featureMcp: "mcp",
|
|
13243
|
-
featurePlugins: "plugins",
|
|
13244
|
-
featureMemory: "memory",
|
|
13245
|
-
featureSkills: "skills",
|
|
13246
|
-
featureModelsRegistry: "modelsRegistry"
|
|
13247
|
-
};
|
|
13248
|
-
for (const [prefKey, cfgKey] of Object.entries(FEATURE_MAP)) {
|
|
13249
|
-
if (typeof payload[prefKey] === "boolean") {
|
|
13250
|
-
const feats = decrypted.features ?? {};
|
|
13251
|
-
feats[cfgKey] = payload[prefKey];
|
|
13252
|
-
decrypted.features = feats;
|
|
13253
|
-
}
|
|
13254
|
-
}
|
|
13255
|
-
if (typeof payload["contextAutoCompact"] === "boolean" || typeof payload["contextStrategy"] === "string" || typeof payload["contextMode"] === "string") {
|
|
13256
|
-
const ctxCfg = decrypted.context ?? {};
|
|
13257
|
-
if (typeof payload["contextAutoCompact"] === "boolean")
|
|
13258
|
-
ctxCfg.autoCompact = payload["contextAutoCompact"];
|
|
13259
|
-
if (typeof payload["contextStrategy"] === "string")
|
|
13260
|
-
ctxCfg.strategy = payload["contextStrategy"];
|
|
13261
|
-
if (typeof payload["contextMode"] === "string") ctxCfg.mode = payload["contextMode"];
|
|
13262
|
-
decrypted.context = ctxCfg;
|
|
13263
|
-
}
|
|
13264
|
-
if (typeof payload["tokenSavingTier"] === "string") {
|
|
13265
|
-
const featsCfg = decrypted.features ?? {};
|
|
13266
|
-
featsCfg.tokenSavingMode = payload["tokenSavingTier"];
|
|
13267
|
-
decrypted.features = featsCfg;
|
|
13268
|
-
}
|
|
13269
|
-
if (typeof payload["maxConcurrent"] === "number") {
|
|
13270
|
-
decrypted.maxConcurrent = payload["maxConcurrent"];
|
|
13271
|
-
}
|
|
13272
|
-
if (typeof payload["titleAnimation"] === "boolean") {
|
|
13273
|
-
const autoCfg = decrypted.autonomy ?? {};
|
|
13274
|
-
autoCfg.terminalTitleAnimation = payload["titleAnimation"];
|
|
13275
|
-
decrypted.autonomy = autoCfg;
|
|
13276
|
-
}
|
|
13277
|
-
if (typeof payload["logLevel"] === "string") {
|
|
13278
|
-
const logCfg = decrypted.log ?? {};
|
|
13279
|
-
logCfg.level = payload["logLevel"];
|
|
13280
|
-
decrypted.log = logCfg;
|
|
13281
|
-
}
|
|
13282
|
-
if (typeof payload["auditLevel"] === "string") {
|
|
13283
|
-
const sessionCfg = decrypted.session ?? {};
|
|
13284
|
-
sessionCfg.auditLevel = payload["auditLevel"];
|
|
13285
|
-
decrypted.session = sessionCfg;
|
|
13286
|
-
}
|
|
13287
|
-
if (typeof payload["indexOnStart"] === "boolean") {
|
|
13288
|
-
const indexingCfg = decrypted.indexing ?? {};
|
|
13289
|
-
indexingCfg.onSessionStart = payload["indexOnStart"];
|
|
13290
|
-
decrypted.indexing = indexingCfg;
|
|
13291
|
-
}
|
|
13292
|
-
if (typeof payload["maxIterations"] === "number") {
|
|
13293
|
-
const toolsCfg = decrypted.tools ?? {};
|
|
13294
|
-
toolsCfg.maxIterations = payload["maxIterations"];
|
|
13295
|
-
decrypted.tools = toolsCfg;
|
|
13296
|
-
}
|
|
13297
|
-
const hqTouched = typeof payload["hqEnabled"] === "boolean" || typeof payload["hqUrl"] === "string" || typeof payload["hqToken"] === "string" || typeof payload["hqRawContent"] === "boolean";
|
|
13298
|
-
if (hqTouched) {
|
|
13299
|
-
const hqCfg = decrypted.hq ?? {};
|
|
13300
|
-
if (typeof payload["hqEnabled"] === "boolean") hqCfg.enabled = payload["hqEnabled"];
|
|
13301
|
-
if (typeof payload["hqUrl"] === "string") hqCfg.url = payload["hqUrl"];
|
|
13302
|
-
if (typeof payload["hqToken"] === "string") hqCfg.token = payload["hqToken"];
|
|
13303
|
-
if (typeof payload["hqRawContent"] === "boolean")
|
|
13304
|
-
hqCfg.rawContent = payload["hqRawContent"];
|
|
13305
|
-
decrypted.hq = hqCfg;
|
|
13306
|
-
}
|
|
13307
|
-
const tgTouched = typeof payload["tgSessionEnd"] === "boolean" || typeof payload["tgDelegate"] === "boolean" || typeof payload["tgLongToolMs"] === "number";
|
|
13308
|
-
if (tgTouched) {
|
|
13309
|
-
const ext = decrypted.extensions ?? {};
|
|
13310
|
-
const tg = ext["telegram"] ?? {};
|
|
13311
|
-
if (typeof payload["tgSessionEnd"] === "boolean") {
|
|
13312
|
-
tg["notifyOnSessionEnd"] = payload["tgSessionEnd"];
|
|
13313
|
-
}
|
|
13314
|
-
if (typeof payload["tgDelegate"] === "boolean") {
|
|
13315
|
-
tg["notifyOnDelegate"] = payload["tgDelegate"];
|
|
13316
|
-
}
|
|
13317
|
-
if (typeof payload["tgLongToolMs"] === "number") {
|
|
13318
|
-
tg["longToolThresholdMs"] = payload["tgLongToolMs"];
|
|
13319
|
-
}
|
|
13320
|
-
ext["telegram"] = tg;
|
|
13321
|
-
decrypted.extensions = ext;
|
|
13322
|
-
}
|
|
13323
|
-
const modelRuntimeTouched = typeof payload["reasoningMode"] === "string" || typeof payload["reasoningEffort"] === "string" || typeof payload["reasoningPreserve"] === "boolean" || typeof payload["cacheTtl"] === "string";
|
|
13324
|
-
if (modelRuntimeTouched) {
|
|
13325
|
-
const mr = decrypted.modelRuntime ?? {};
|
|
13326
|
-
const reasoning = mr.reasoning ?? {};
|
|
13327
|
-
if (typeof payload["reasoningMode"] === "string") reasoning.mode = payload["reasoningMode"];
|
|
13328
|
-
if (typeof payload["reasoningEffort"] === "string")
|
|
13329
|
-
reasoning.effort = payload["reasoningEffort"];
|
|
13330
|
-
if (typeof payload["reasoningPreserve"] === "boolean")
|
|
13331
|
-
reasoning.preserve = payload["reasoningPreserve"];
|
|
13332
|
-
mr.reasoning = reasoning;
|
|
13333
|
-
if (typeof payload["cacheTtl"] === "string" && payload["cacheTtl"] !== "default") {
|
|
13334
|
-
mr.cache = { ttl: payload["cacheTtl"] };
|
|
13335
|
-
} else if (payload["cacheTtl"] === "default") {
|
|
13336
|
-
delete mr.cache;
|
|
13337
|
-
}
|
|
13338
|
-
decrypted.modelRuntime = mr;
|
|
13339
|
-
}
|
|
13340
|
-
if (typeof payload["breakerEnabled"] === "boolean" || typeof payload["breakerAutoKillResetMs"] === "number") {
|
|
13341
|
-
const cb = decrypted.circuitBreaker ?? {};
|
|
13342
|
-
if (typeof payload["breakerEnabled"] === "boolean") cb.enabled = payload["breakerEnabled"];
|
|
13343
|
-
if (typeof payload["breakerAutoKillResetMs"] === "number")
|
|
13344
|
-
cb.autoKillResetMs = payload["breakerAutoKillResetMs"];
|
|
13345
|
-
decrypted.circuitBreaker = cb;
|
|
13346
|
-
}
|
|
13347
|
-
if (payload["fsAccess"] === "unrestricted" || payload["fsAccess"] === "project") {
|
|
13348
|
-
const restrict = payload["fsAccess"] === "project";
|
|
13349
|
-
const toolsCfg = decrypted.tools ?? {};
|
|
13350
|
-
toolsCfg.restrictToProjectRoot = restrict;
|
|
13351
|
-
decrypted.tools = toolsCfg;
|
|
13352
|
-
const featsCfg = decrypted.features ?? {};
|
|
13353
|
-
featsCfg.allowOutsideProjectRoot = !restrict;
|
|
13354
|
-
decrypted.features = featsCfg;
|
|
13355
|
-
}
|
|
13356
|
-
if (typeof payload["debugStream"] === "boolean")
|
|
13357
|
-
decrypted.debugStream = payload["debugStream"];
|
|
13358
|
-
if (typeof payload["pluginsEnabled"] === "object" && payload["pluginsEnabled"] !== null) {
|
|
13359
|
-
const ext = decrypted.extensions ?? {};
|
|
13360
|
-
for (const [pluginName, enabled] of Object.entries(
|
|
13361
|
-
payload["pluginsEnabled"]
|
|
13362
|
-
)) {
|
|
13363
|
-
if (FORBIDDEN_PROTO_KEYS2.has(pluginName)) continue;
|
|
13364
|
-
const pExt = ext[pluginName] ?? {};
|
|
13365
|
-
pExt["enabled"] = enabled;
|
|
13366
|
-
ext[pluginName] = pExt;
|
|
13367
|
-
}
|
|
13368
|
-
decrypted.extensions = ext;
|
|
13369
|
-
}
|
|
13370
|
-
const chimeraTouched = typeof payload["chimeraEnabled"] === "boolean" || typeof payload["chimeraProvider"] === "string" || typeof payload["chimeraModel"] === "string" || typeof payload["chimeraMaxFiles"] === "number" || typeof payload["chimeraAutoFix"] === "string";
|
|
13371
|
-
if (chimeraTouched) {
|
|
13372
|
-
const ext = decrypted.extensions ?? {};
|
|
13373
|
-
const chimera = ext["wstack-chimera"] ?? {};
|
|
13374
|
-
if (typeof payload["chimeraEnabled"] === "boolean")
|
|
13375
|
-
chimera["enabled"] = payload["chimeraEnabled"];
|
|
13376
|
-
if (typeof payload["chimeraProvider"] === "string")
|
|
13377
|
-
chimera["provider"] = payload["chimeraProvider"];
|
|
13378
|
-
if (typeof payload["chimeraModel"] === "string")
|
|
13379
|
-
chimera["model"] = payload["chimeraModel"];
|
|
13380
|
-
if (typeof payload["chimeraMaxFiles"] === "number" && payload["chimeraMaxFiles"] >= 1) {
|
|
13381
|
-
chimera["maxFiles"] = payload["chimeraMaxFiles"];
|
|
13382
|
-
}
|
|
13383
|
-
if (typeof payload["chimeraAutoFix"] === "string") {
|
|
13384
|
-
if (payload["chimeraAutoFix"] === "off" || payload["chimeraAutoFix"] === "ask" || payload["chimeraAutoFix"] === "auto") {
|
|
13385
|
-
chimera["autoFix"] = payload["chimeraAutoFix"];
|
|
13386
|
-
}
|
|
13387
|
-
}
|
|
13388
|
-
ext["wstack-chimera"] = chimera;
|
|
13389
|
-
decrypted.extensions = ext;
|
|
13390
|
-
}
|
|
13391
|
-
const autoReviewTouched = typeof payload["autoReviewEnabled"] === "boolean" || typeof payload["autoReviewProvider"] === "string" || typeof payload["autoReviewModel"] === "string" || typeof payload["autoReviewFallbackProfile"] === "string" || Array.isArray(payload["autoReviewFallbackModels"]) || typeof payload["autoReviewDebounceMs"] === "number" || typeof payload["autoReviewMaxFilesPerBatch"] === "number" || typeof payload["autoReviewMaxConcurrentReviews"] === "number" || typeof payload["autoReviewCascadeOn"] === "string";
|
|
13392
|
-
if (autoReviewTouched) {
|
|
13393
|
-
const ext = decrypted.extensions ?? {};
|
|
13394
|
-
const ar = ext["wstack-auto-review"] ?? {};
|
|
13395
|
-
if (typeof payload["autoReviewEnabled"] === "boolean")
|
|
13396
|
-
ar["enabled"] = payload["autoReviewEnabled"];
|
|
13397
|
-
if (typeof payload["autoReviewProvider"] === "string")
|
|
13398
|
-
ar["provider"] = payload["autoReviewProvider"];
|
|
13399
|
-
if (typeof payload["autoReviewModel"] === "string")
|
|
13400
|
-
ar["model"] = payload["autoReviewModel"];
|
|
13401
|
-
if (typeof payload["autoReviewFallbackProfile"] === "string") {
|
|
13402
|
-
if (payload["autoReviewFallbackProfile"] === "") {
|
|
13403
|
-
delete ar["fallbackProfile"];
|
|
13404
|
-
} else {
|
|
13405
|
-
ar["fallbackProfile"] = payload["autoReviewFallbackProfile"];
|
|
13406
|
-
}
|
|
13278
|
+
return updateGlobalConfig(
|
|
13279
|
+
deps2,
|
|
13280
|
+
holder,
|
|
13281
|
+
(decrypted) => {
|
|
13282
|
+
const autonomyCfg = decrypted.autonomy ?? {};
|
|
13283
|
+
let autonomyTouched = false;
|
|
13284
|
+
const setAutonomy = (key, val) => {
|
|
13285
|
+
autonomyCfg[key] = val;
|
|
13286
|
+
autonomyTouched = true;
|
|
13287
|
+
};
|
|
13288
|
+
if (typeof payload["autonomy"] === "string" && ["off", "suggest", "auto"].includes(payload["autonomy"])) {
|
|
13289
|
+
setAutonomy("defaultMode", payload["autonomy"]);
|
|
13407
13290
|
}
|
|
13408
|
-
if (typeof payload["
|
|
13409
|
-
|
|
13291
|
+
if (typeof payload["autonomyDelayMs"] === "number")
|
|
13292
|
+
setAutonomy("autoProceedDelayMs", payload["autonomyDelayMs"]);
|
|
13293
|
+
if (typeof payload["autoProceedMaxIterations"] === "number")
|
|
13294
|
+
setAutonomy("autoProceedMaxIterations", payload["autoProceedMaxIterations"]);
|
|
13295
|
+
if (typeof payload["yolo"] === "boolean") {
|
|
13296
|
+
setAutonomy("yolo", payload["yolo"]);
|
|
13297
|
+
decrypted.yolo = payload["yolo"];
|
|
13298
|
+
}
|
|
13299
|
+
if (typeof payload["chime"] === "boolean") setAutonomy("chime", payload["chime"]);
|
|
13300
|
+
if (typeof payload["confirmExit"] === "boolean")
|
|
13301
|
+
setAutonomy("confirmExit", payload["confirmExit"]);
|
|
13302
|
+
if (typeof payload["streamFleet"] === "boolean")
|
|
13303
|
+
setAutonomy("streamFleet", payload["streamFleet"]);
|
|
13304
|
+
if (typeof payload["enhanceEnabled"] === "boolean")
|
|
13305
|
+
setAutonomy("enhance", payload["enhanceEnabled"]);
|
|
13306
|
+
if (typeof payload["enhanceDelayMs"] === "number")
|
|
13307
|
+
setAutonomy("enhanceDelayMs", payload["enhanceDelayMs"]);
|
|
13308
|
+
if (typeof payload["enhanceLanguage"] === "string")
|
|
13309
|
+
setAutonomy("enhanceLanguage", payload["enhanceLanguage"]);
|
|
13310
|
+
if (typeof payload["refinerProvider"] === "string")
|
|
13311
|
+
setAutonomy("refinerProvider", payload["refinerProvider"]);
|
|
13312
|
+
if (typeof payload["refinerModel"] === "string")
|
|
13313
|
+
setAutonomy("refinerModel", payload["refinerModel"]);
|
|
13314
|
+
if (typeof payload["refinerFallbackProfile"] === "string")
|
|
13315
|
+
setAutonomy("refinerFallbackProfile", payload["refinerFallbackProfile"]);
|
|
13316
|
+
if (typeof payload["thinkingWord"] === "string")
|
|
13317
|
+
setAutonomy("thinkingWord", payload["thinkingWord"]);
|
|
13318
|
+
if (typeof payload["statuslineMode"] === "string")
|
|
13319
|
+
setAutonomy("statuslineMode", payload["statuslineMode"]);
|
|
13320
|
+
if (typeof payload["animationStyle"] === "string")
|
|
13321
|
+
setAutonomy("animationStyle", payload["animationStyle"]);
|
|
13322
|
+
if (typeof payload["showModelReasoning"] === "boolean")
|
|
13323
|
+
setAutonomy("showModelReasoning", payload["showModelReasoning"]);
|
|
13324
|
+
if (autonomyTouched) decrypted.autonomy = autonomyCfg;
|
|
13325
|
+
if (typeof payload["nextPrediction"] === "boolean")
|
|
13326
|
+
decrypted.nextPrediction = payload["nextPrediction"];
|
|
13327
|
+
if (typeof payload["uiLocale"] === "string") decrypted.uiLocale = payload["uiLocale"];
|
|
13328
|
+
if (Array.isArray(payload["fallbackModels"]))
|
|
13329
|
+
decrypted.fallbackModels = payload["fallbackModels"];
|
|
13330
|
+
if (payload["fallbackProfiles"] && typeof payload["fallbackProfiles"] === "object" && !Array.isArray(payload["fallbackProfiles"])) {
|
|
13331
|
+
decrypted.fallbackProfiles = payload["fallbackProfiles"];
|
|
13410
13332
|
}
|
|
13411
|
-
if (
|
|
13412
|
-
|
|
13333
|
+
if (Array.isArray(payload["favoriteModels"]))
|
|
13334
|
+
decrypted.favoriteModels = payload["favoriteModels"];
|
|
13335
|
+
if (typeof payload["favoriteModelsOnly"] === "boolean")
|
|
13336
|
+
decrypted.favoriteModelsOnly = payload["favoriteModelsOnly"];
|
|
13337
|
+
if (Array.isArray(payload["modelAvailabilitySchedule"]))
|
|
13338
|
+
decrypted.modelAvailabilitySchedule = payload["modelAvailabilitySchedule"];
|
|
13339
|
+
if (payload["modelMatrix"] && typeof payload["modelMatrix"] === "object" && !Array.isArray(payload["modelMatrix"])) {
|
|
13340
|
+
decrypted.modelMatrix = payload["modelMatrix"];
|
|
13341
|
+
}
|
|
13342
|
+
if (typeof payload["fallbackAuto"] === "boolean")
|
|
13343
|
+
decrypted.fallbackAuto = payload["fallbackAuto"];
|
|
13344
|
+
const FEATURE_MAP = {
|
|
13345
|
+
featureMcp: "mcp",
|
|
13346
|
+
featurePlugins: "plugins",
|
|
13347
|
+
featureMemory: "memory",
|
|
13348
|
+
featureSkills: "skills",
|
|
13349
|
+
featureModelsRegistry: "modelsRegistry"
|
|
13350
|
+
};
|
|
13351
|
+
for (const [prefKey, cfgKey] of Object.entries(FEATURE_MAP)) {
|
|
13352
|
+
if (typeof payload[prefKey] === "boolean") {
|
|
13353
|
+
const feats = decrypted.features ?? {};
|
|
13354
|
+
feats[cfgKey] = payload[prefKey];
|
|
13355
|
+
decrypted.features = feats;
|
|
13356
|
+
}
|
|
13357
|
+
}
|
|
13358
|
+
if (typeof payload["contextAutoCompact"] === "boolean" || typeof payload["contextStrategy"] === "string" || typeof payload["contextMode"] === "string") {
|
|
13359
|
+
const ctxCfg = decrypted.context ?? {};
|
|
13360
|
+
if (typeof payload["contextAutoCompact"] === "boolean")
|
|
13361
|
+
ctxCfg.autoCompact = payload["contextAutoCompact"];
|
|
13362
|
+
if (typeof payload["contextStrategy"] === "string")
|
|
13363
|
+
ctxCfg.strategy = payload["contextStrategy"];
|
|
13364
|
+
if (typeof payload["contextMode"] === "string") ctxCfg.mode = payload["contextMode"];
|
|
13365
|
+
decrypted.context = ctxCfg;
|
|
13366
|
+
}
|
|
13367
|
+
if (typeof payload["tokenSavingTier"] === "string") {
|
|
13368
|
+
const featsCfg = decrypted.features ?? {};
|
|
13369
|
+
featsCfg.tokenSavingMode = payload["tokenSavingTier"];
|
|
13370
|
+
decrypted.features = featsCfg;
|
|
13371
|
+
}
|
|
13372
|
+
if (typeof payload["maxConcurrent"] === "number") {
|
|
13373
|
+
decrypted.maxConcurrent = payload["maxConcurrent"];
|
|
13374
|
+
}
|
|
13375
|
+
if (typeof payload["titleAnimation"] === "boolean") {
|
|
13376
|
+
const autoCfg = decrypted.autonomy ?? {};
|
|
13377
|
+
autoCfg.terminalTitleAnimation = payload["titleAnimation"];
|
|
13378
|
+
decrypted.autonomy = autoCfg;
|
|
13413
13379
|
}
|
|
13414
|
-
if (typeof payload["
|
|
13415
|
-
|
|
13380
|
+
if (typeof payload["logLevel"] === "string") {
|
|
13381
|
+
const logCfg = decrypted.log ?? {};
|
|
13382
|
+
logCfg.level = payload["logLevel"];
|
|
13383
|
+
decrypted.log = logCfg;
|
|
13384
|
+
}
|
|
13385
|
+
if (typeof payload["auditLevel"] === "string") {
|
|
13386
|
+
const sessionCfg = decrypted.session ?? {};
|
|
13387
|
+
sessionCfg.auditLevel = payload["auditLevel"];
|
|
13388
|
+
decrypted.session = sessionCfg;
|
|
13389
|
+
}
|
|
13390
|
+
if (typeof payload["indexOnStart"] === "boolean") {
|
|
13391
|
+
const indexingCfg = decrypted.indexing ?? {};
|
|
13392
|
+
indexingCfg.onSessionStart = payload["indexOnStart"];
|
|
13393
|
+
decrypted.indexing = indexingCfg;
|
|
13394
|
+
}
|
|
13395
|
+
if (typeof payload["maxIterations"] === "number") {
|
|
13396
|
+
const toolsCfg = decrypted.tools ?? {};
|
|
13397
|
+
toolsCfg.maxIterations = payload["maxIterations"];
|
|
13398
|
+
decrypted.tools = toolsCfg;
|
|
13399
|
+
}
|
|
13400
|
+
const hqTouched = typeof payload["hqEnabled"] === "boolean" || typeof payload["hqUrl"] === "string" || typeof payload["hqToken"] === "string" || typeof payload["hqRawContent"] === "boolean";
|
|
13401
|
+
if (hqTouched) {
|
|
13402
|
+
const hqCfg = decrypted.hq ?? {};
|
|
13403
|
+
if (typeof payload["hqEnabled"] === "boolean") hqCfg.enabled = payload["hqEnabled"];
|
|
13404
|
+
if (typeof payload["hqUrl"] === "string") hqCfg.url = payload["hqUrl"];
|
|
13405
|
+
if (typeof payload["hqToken"] === "string") hqCfg.token = payload["hqToken"];
|
|
13406
|
+
if (typeof payload["hqRawContent"] === "boolean")
|
|
13407
|
+
hqCfg.rawContent = payload["hqRawContent"];
|
|
13408
|
+
decrypted.hq = hqCfg;
|
|
13409
|
+
}
|
|
13410
|
+
const tgTouched = typeof payload["tgSessionEnd"] === "boolean" || typeof payload["tgDelegate"] === "boolean" || typeof payload["tgLongToolMs"] === "number";
|
|
13411
|
+
if (tgTouched) {
|
|
13412
|
+
const ext = decrypted.extensions ?? {};
|
|
13413
|
+
const tg = ext["telegram"] ?? {};
|
|
13414
|
+
if (typeof payload["tgSessionEnd"] === "boolean") {
|
|
13415
|
+
tg["notifyOnSessionEnd"] = payload["tgSessionEnd"];
|
|
13416
|
+
}
|
|
13417
|
+
if (typeof payload["tgDelegate"] === "boolean") {
|
|
13418
|
+
tg["notifyOnDelegate"] = payload["tgDelegate"];
|
|
13419
|
+
}
|
|
13420
|
+
if (typeof payload["tgLongToolMs"] === "number") {
|
|
13421
|
+
tg["longToolThresholdMs"] = payload["tgLongToolMs"];
|
|
13422
|
+
}
|
|
13423
|
+
ext["telegram"] = tg;
|
|
13424
|
+
decrypted.extensions = ext;
|
|
13425
|
+
}
|
|
13426
|
+
const modelRuntimeTouched = typeof payload["reasoningMode"] === "string" || typeof payload["reasoningEffort"] === "string" || typeof payload["reasoningPreserve"] === "boolean" || typeof payload["cacheTtl"] === "string";
|
|
13427
|
+
if (modelRuntimeTouched) {
|
|
13428
|
+
const mr = decrypted.modelRuntime ?? {};
|
|
13429
|
+
const reasoning = mr.reasoning ?? {};
|
|
13430
|
+
if (typeof payload["reasoningMode"] === "string") reasoning.mode = payload["reasoningMode"];
|
|
13431
|
+
if (typeof payload["reasoningEffort"] === "string")
|
|
13432
|
+
reasoning.effort = payload["reasoningEffort"];
|
|
13433
|
+
if (typeof payload["reasoningPreserve"] === "boolean")
|
|
13434
|
+
reasoning.preserve = payload["reasoningPreserve"];
|
|
13435
|
+
mr.reasoning = reasoning;
|
|
13436
|
+
if (typeof payload["cacheTtl"] === "string" && payload["cacheTtl"] !== "default") {
|
|
13437
|
+
mr.cache = { ttl: payload["cacheTtl"] };
|
|
13438
|
+
} else if (payload["cacheTtl"] === "default") {
|
|
13439
|
+
delete mr.cache;
|
|
13440
|
+
}
|
|
13441
|
+
decrypted.modelRuntime = mr;
|
|
13416
13442
|
}
|
|
13417
|
-
if (typeof payload["
|
|
13418
|
-
|
|
13419
|
-
|
|
13443
|
+
if (typeof payload["breakerEnabled"] === "boolean" || typeof payload["breakerAutoKillResetMs"] === "number") {
|
|
13444
|
+
const cb = decrypted.circuitBreaker ?? {};
|
|
13445
|
+
if (typeof payload["breakerEnabled"] === "boolean") cb.enabled = payload["breakerEnabled"];
|
|
13446
|
+
if (typeof payload["breakerAutoKillResetMs"] === "number")
|
|
13447
|
+
cb.autoKillResetMs = payload["breakerAutoKillResetMs"];
|
|
13448
|
+
decrypted.circuitBreaker = cb;
|
|
13449
|
+
}
|
|
13450
|
+
if (payload["fsAccess"] === "unrestricted" || payload["fsAccess"] === "project") {
|
|
13451
|
+
const restrict = payload["fsAccess"] === "project";
|
|
13452
|
+
const toolsCfg = decrypted.tools ?? {};
|
|
13453
|
+
toolsCfg.restrictToProjectRoot = restrict;
|
|
13454
|
+
decrypted.tools = toolsCfg;
|
|
13455
|
+
const featsCfg = decrypted.features ?? {};
|
|
13456
|
+
featsCfg.allowOutsideProjectRoot = !restrict;
|
|
13457
|
+
decrypted.features = featsCfg;
|
|
13458
|
+
}
|
|
13459
|
+
if (typeof payload["debugStream"] === "boolean")
|
|
13460
|
+
decrypted.debugStream = payload["debugStream"];
|
|
13461
|
+
if (typeof payload["pluginsEnabled"] === "object" && payload["pluginsEnabled"] !== null) {
|
|
13462
|
+
const ext = decrypted.extensions ?? {};
|
|
13463
|
+
for (const [pluginName, enabled] of Object.entries(
|
|
13464
|
+
payload["pluginsEnabled"]
|
|
13465
|
+
)) {
|
|
13466
|
+
if (FORBIDDEN_PROTO_KEYS2.has(pluginName)) continue;
|
|
13467
|
+
const pExt = ext[pluginName] ?? {};
|
|
13468
|
+
pExt["enabled"] = enabled;
|
|
13469
|
+
ext[pluginName] = pExt;
|
|
13470
|
+
}
|
|
13471
|
+
decrypted.extensions = ext;
|
|
13472
|
+
}
|
|
13473
|
+
const chimeraTouched = typeof payload["chimeraEnabled"] === "boolean" || typeof payload["chimeraProvider"] === "string" || typeof payload["chimeraModel"] === "string" || typeof payload["chimeraMaxFiles"] === "number" || typeof payload["chimeraAutoFix"] === "string";
|
|
13474
|
+
if (chimeraTouched) {
|
|
13475
|
+
const ext = decrypted.extensions ?? {};
|
|
13476
|
+
const chimera = ext["wstack-chimera"] ?? {};
|
|
13477
|
+
if (typeof payload["chimeraEnabled"] === "boolean")
|
|
13478
|
+
chimera["enabled"] = payload["chimeraEnabled"];
|
|
13479
|
+
if (typeof payload["chimeraProvider"] === "string")
|
|
13480
|
+
chimera["provider"] = payload["chimeraProvider"];
|
|
13481
|
+
if (typeof payload["chimeraModel"] === "string") chimera["model"] = payload["chimeraModel"];
|
|
13482
|
+
if (typeof payload["chimeraMaxFiles"] === "number" && payload["chimeraMaxFiles"] >= 1) {
|
|
13483
|
+
chimera["maxFiles"] = payload["chimeraMaxFiles"];
|
|
13484
|
+
}
|
|
13485
|
+
if (typeof payload["chimeraAutoFix"] === "string") {
|
|
13486
|
+
if (payload["chimeraAutoFix"] === "off" || payload["chimeraAutoFix"] === "ask" || payload["chimeraAutoFix"] === "auto") {
|
|
13487
|
+
chimera["autoFix"] = payload["chimeraAutoFix"];
|
|
13488
|
+
}
|
|
13489
|
+
}
|
|
13490
|
+
ext["wstack-chimera"] = chimera;
|
|
13491
|
+
decrypted.extensions = ext;
|
|
13492
|
+
}
|
|
13493
|
+
const autoReviewTouched = typeof payload["autoReviewEnabled"] === "boolean" || typeof payload["autoReviewProvider"] === "string" || typeof payload["autoReviewModel"] === "string" || typeof payload["autoReviewFallbackProfile"] === "string" || Array.isArray(payload["autoReviewFallbackModels"]) || typeof payload["autoReviewDebounceMs"] === "number" || typeof payload["autoReviewMaxFilesPerBatch"] === "number" || typeof payload["autoReviewMaxConcurrentReviews"] === "number" || typeof payload["autoReviewCascadeOn"] === "string";
|
|
13494
|
+
if (autoReviewTouched) {
|
|
13495
|
+
const ext = decrypted.extensions ?? {};
|
|
13496
|
+
const ar = ext["wstack-auto-review"] ?? {};
|
|
13497
|
+
if (typeof payload["autoReviewEnabled"] === "boolean")
|
|
13498
|
+
ar["enabled"] = payload["autoReviewEnabled"];
|
|
13499
|
+
if (typeof payload["autoReviewProvider"] === "string")
|
|
13500
|
+
ar["provider"] = payload["autoReviewProvider"];
|
|
13501
|
+
if (typeof payload["autoReviewModel"] === "string")
|
|
13502
|
+
ar["model"] = payload["autoReviewModel"];
|
|
13503
|
+
if (typeof payload["autoReviewFallbackProfile"] === "string") {
|
|
13504
|
+
if (payload["autoReviewFallbackProfile"] === "") {
|
|
13505
|
+
delete ar["fallbackProfile"];
|
|
13506
|
+
} else {
|
|
13507
|
+
ar["fallbackProfile"] = payload["autoReviewFallbackProfile"];
|
|
13508
|
+
}
|
|
13509
|
+
}
|
|
13510
|
+
if (typeof payload["autoReviewDebounceMs"] === "number" && payload["autoReviewDebounceMs"] >= 0) {
|
|
13511
|
+
ar["debounceMs"] = payload["autoReviewDebounceMs"];
|
|
13512
|
+
}
|
|
13513
|
+
if (typeof payload["autoReviewMaxFilesPerBatch"] === "number" && payload["autoReviewMaxFilesPerBatch"] >= 1) {
|
|
13514
|
+
ar["maxFilesPerBatch"] = payload["autoReviewMaxFilesPerBatch"];
|
|
13515
|
+
}
|
|
13516
|
+
if (typeof payload["autoReviewMaxConcurrentReviews"] === "number" && payload["autoReviewMaxConcurrentReviews"] >= 1) {
|
|
13517
|
+
ar["maxConcurrentReviews"] = payload["autoReviewMaxConcurrentReviews"];
|
|
13518
|
+
}
|
|
13519
|
+
if (typeof payload["autoReviewCascadeOn"] === "string") {
|
|
13520
|
+
if (payload["autoReviewCascadeOn"] === "off" || payload["autoReviewCascadeOn"] === "critical" || payload["autoReviewCascadeOn"] === "high") {
|
|
13521
|
+
ar["cascadeOn"] = payload["autoReviewCascadeOn"];
|
|
13522
|
+
}
|
|
13420
13523
|
}
|
|
13524
|
+
ext["wstack-auto-review"] = ar;
|
|
13525
|
+
decrypted.extensions = ext;
|
|
13421
13526
|
}
|
|
13422
|
-
|
|
13423
|
-
|
|
13424
|
-
|
|
13425
|
-
}, "prefs");
|
|
13527
|
+
},
|
|
13528
|
+
"prefs"
|
|
13529
|
+
);
|
|
13426
13530
|
}
|
|
13427
13531
|
|
|
13428
13532
|
// src/server/provider-handlers.ts
|
|
@@ -13760,6 +13864,7 @@ import {
|
|
|
13760
13864
|
gatedEnhancerReasoning,
|
|
13761
13865
|
nextEnhanceTimeout,
|
|
13762
13866
|
recentTextTurns,
|
|
13867
|
+
resolveConfiguredRefinerRef,
|
|
13763
13868
|
resolveEnhanceFallbackRef,
|
|
13764
13869
|
resolveProviderModelList
|
|
13765
13870
|
} from "@wrongstack/core";
|
|
@@ -14622,6 +14727,26 @@ function buildRoutes(state, deps2, cb) {
|
|
|
14622
14727
|
});
|
|
14623
14728
|
return;
|
|
14624
14729
|
}
|
|
14730
|
+
} else {
|
|
14731
|
+
const configuredRef = resolveConfiguredRefinerRef({
|
|
14732
|
+
...cfg,
|
|
14733
|
+
provider: providerId,
|
|
14734
|
+
model
|
|
14735
|
+
});
|
|
14736
|
+
if (configuredRef) {
|
|
14737
|
+
const slash = configuredRef.indexOf("/");
|
|
14738
|
+
const configuredProvider = slash > 0 ? configuredRef.slice(0, slash) : providerId;
|
|
14739
|
+
const configuredModel = slash > 0 ? configuredRef.slice(slash + 1) : configuredRef;
|
|
14740
|
+
try {
|
|
14741
|
+
const providerCfg = cfg.providers?.[configuredProvider] ?? {
|
|
14742
|
+
type: configuredProvider
|
|
14743
|
+
};
|
|
14744
|
+
provider = deps2.providerRegistry.has(configuredProvider) ? deps2.providerRegistry.create({ ...providerCfg, type: configuredProvider }) : makeProviderFromConfig2(configuredProvider, providerCfg);
|
|
14745
|
+
providerId = configuredProvider;
|
|
14746
|
+
model = configuredModel;
|
|
14747
|
+
} catch {
|
|
14748
|
+
}
|
|
14749
|
+
}
|
|
14625
14750
|
}
|
|
14626
14751
|
const baseTimeout = 9e4;
|
|
14627
14752
|
const timeoutMs = typeof payload.timeoutMs === "number" && payload.timeoutMs > 0 ? payload.timeoutMs : baseTimeout;
|
|
@@ -14808,19 +14933,27 @@ function buildRoutes(state, deps2, cb) {
|
|
|
14808
14933
|
cfg.favoriteModels = payload["favoriteModels"];
|
|
14809
14934
|
if (typeof payload["favoriteModelsOnly"] === "boolean")
|
|
14810
14935
|
cfg.favoriteModelsOnly = payload["favoriteModelsOnly"];
|
|
14936
|
+
if (Array.isArray(payload["modelAvailabilitySchedule"]))
|
|
14937
|
+
cfg.modelAvailabilitySchedule = payload["modelAvailabilitySchedule"];
|
|
14811
14938
|
if (payload["modelMatrix"] && typeof payload["modelMatrix"] === "object" && !Array.isArray(payload["modelMatrix"])) {
|
|
14812
14939
|
cfg.modelMatrix = payload["modelMatrix"];
|
|
14813
14940
|
}
|
|
14814
14941
|
if (typeof payload["fallbackAuto"] === "boolean") cfg.fallbackAuto = payload["fallbackAuto"];
|
|
14815
14942
|
const routingPatch = {};
|
|
14816
|
-
if (Array.isArray(payload["fallbackModels"]))
|
|
14943
|
+
if (Array.isArray(payload["fallbackModels"]))
|
|
14944
|
+
routingPatch.fallbackModels = payload["fallbackModels"];
|
|
14817
14945
|
if (payload["fallbackProfiles"] && typeof payload["fallbackProfiles"] === "object" && !Array.isArray(payload["fallbackProfiles"]))
|
|
14818
14946
|
routingPatch.fallbackProfiles = payload["fallbackProfiles"];
|
|
14819
|
-
if (Array.isArray(payload["favoriteModels"]))
|
|
14820
|
-
|
|
14947
|
+
if (Array.isArray(payload["favoriteModels"]))
|
|
14948
|
+
routingPatch.favoriteModels = payload["favoriteModels"];
|
|
14949
|
+
if (typeof payload["favoriteModelsOnly"] === "boolean")
|
|
14950
|
+
routingPatch.favoriteModelsOnly = payload["favoriteModelsOnly"];
|
|
14951
|
+
if (Array.isArray(payload["modelAvailabilitySchedule"]))
|
|
14952
|
+
routingPatch.modelAvailabilitySchedule = payload["modelAvailabilitySchedule"];
|
|
14821
14953
|
if (payload["modelMatrix"] && typeof payload["modelMatrix"] === "object" && !Array.isArray(payload["modelMatrix"]))
|
|
14822
14954
|
routingPatch.modelMatrix = payload["modelMatrix"];
|
|
14823
|
-
if (typeof payload["fallbackAuto"] === "boolean")
|
|
14955
|
+
if (typeof payload["fallbackAuto"] === "boolean")
|
|
14956
|
+
routingPatch.fallbackAuto = payload["fallbackAuto"];
|
|
14824
14957
|
if (Object.keys(routingPatch).length > 0)
|
|
14825
14958
|
deps2.configStore.update(routingPatch);
|
|
14826
14959
|
if (typeof payload["contextAutoCompact"] === "boolean") {
|
|
@@ -15744,6 +15877,7 @@ export {
|
|
|
15744
15877
|
normalizeCodeMapFileTarget,
|
|
15745
15878
|
normalizeKeys,
|
|
15746
15879
|
openBrowser,
|
|
15880
|
+
paginateKanbanBoards,
|
|
15747
15881
|
patchConfig,
|
|
15748
15882
|
persistPrefsToConfig,
|
|
15749
15883
|
projectSavedProviders,
|