@wrongstack/webui-server 0.291.0 → 0.291.2
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 +142 -69
- package/dist/index.js.map +3 -3
- package/dist/server/entry.js +141 -69
- package/dist/server/entry.js.map +3 -3
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/memory-handlers.d.ts +13 -0
- package/dist/server/memory-handlers.d.ts.map +1 -1
- package/dist/server/message-dispatcher.d.ts.map +1 -1
- package/dist/server/pref-helpers.d.ts +4 -7
- package/dist/server/pref-helpers.d.ts.map +1 -1
- package/dist/server/provider-config-io.d.ts +2 -1
- package/dist/server/provider-config-io.d.ts.map +1 -1
- package/dist/server/provider-handlers.d.ts +2 -0
- package/dist/server/provider-handlers.d.ts.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/start-webui.d.ts.map +1 -1
- package/package.json +10 -10
package/dist/server/entry.js
CHANGED
|
@@ -1813,15 +1813,15 @@ async function handleGitChanges(ws, projectRoot) {
|
|
|
1813
1813
|
if (!m) continue;
|
|
1814
1814
|
const added = m[1] === "-" ? 0 : Number(m[1]);
|
|
1815
1815
|
const deleted = m[2] === "-" ? 0 : Number(m[2]);
|
|
1816
|
-
let
|
|
1817
|
-
if (
|
|
1816
|
+
let path24 = m[3] ?? "";
|
|
1817
|
+
if (path24 === "") {
|
|
1818
1818
|
i += 1;
|
|
1819
|
-
|
|
1819
|
+
path24 = parts[i + 1] ?? parts[i] ?? "";
|
|
1820
1820
|
i += 1;
|
|
1821
1821
|
}
|
|
1822
|
-
if (!
|
|
1823
|
-
const prev = counts.get(
|
|
1824
|
-
counts.set(
|
|
1822
|
+
if (!path24) continue;
|
|
1823
|
+
const prev = counts.get(path24) ?? { added: 0, deleted: 0 };
|
|
1824
|
+
counts.set(path24, { added: prev.added + added, deleted: prev.deleted + deleted });
|
|
1825
1825
|
}
|
|
1826
1826
|
};
|
|
1827
1827
|
parseNumstat(unstagedNumstat);
|
|
@@ -1833,7 +1833,7 @@ async function handleGitChanges(ws, projectRoot) {
|
|
|
1833
1833
|
if (!rec || rec.length < 3) continue;
|
|
1834
1834
|
const x = rec[0] ?? " ";
|
|
1835
1835
|
const y = rec[1] ?? " ";
|
|
1836
|
-
const
|
|
1836
|
+
const path24 = rec.slice(3);
|
|
1837
1837
|
const isRename = x === "R" || x === "C" || y === "R" || y === "C";
|
|
1838
1838
|
if (isRename) i += 1;
|
|
1839
1839
|
let status;
|
|
@@ -1845,13 +1845,13 @@ async function handleGitChanges(ws, projectRoot) {
|
|
|
1845
1845
|
else if (x === "D" || y === "D") status = "D";
|
|
1846
1846
|
else status = "M";
|
|
1847
1847
|
const staged = x !== " " && x !== "?";
|
|
1848
|
-
let added = counts.get(
|
|
1849
|
-
let deleted = counts.get(
|
|
1848
|
+
let added = counts.get(path24)?.added ?? 0;
|
|
1849
|
+
let deleted = counts.get(path24)?.deleted ?? 0;
|
|
1850
1850
|
if (status === "?") {
|
|
1851
1851
|
added = 0;
|
|
1852
1852
|
deleted = 0;
|
|
1853
1853
|
}
|
|
1854
|
-
files.push({ path:
|
|
1854
|
+
files.push({ path: path24, status, added, deleted, staged });
|
|
1855
1855
|
}
|
|
1856
1856
|
send(ws, { type: "git.changes", payload: { files } });
|
|
1857
1857
|
} catch (err) {
|
|
@@ -1862,10 +1862,10 @@ async function handleGitChanges(ws, projectRoot) {
|
|
|
1862
1862
|
}
|
|
1863
1863
|
}
|
|
1864
1864
|
var MAX_DIFF_BYTES = 2 * 1024 * 1024;
|
|
1865
|
-
async function handleGitDiff(ws, projectRoot,
|
|
1865
|
+
async function handleGitDiff(ws, projectRoot, path24) {
|
|
1866
1866
|
const cwd = projectRoot || void 0;
|
|
1867
|
-
const reply = (extra) => send(ws, { type: "git.diff", payload: { path:
|
|
1868
|
-
if (!
|
|
1867
|
+
const reply = (extra) => send(ws, { type: "git.diff", payload: { path: path24, ...extra } });
|
|
1868
|
+
if (!path24 || path24.includes("\0") || path24.includes("..") || nodePath.isAbsolute(path24)) {
|
|
1869
1869
|
reply({ oldText: "", newText: "", error: "invalid path" });
|
|
1870
1870
|
return;
|
|
1871
1871
|
}
|
|
@@ -1873,10 +1873,10 @@ async function handleGitDiff(ws, projectRoot, path23) {
|
|
|
1873
1873
|
const git = makeGit(cwd);
|
|
1874
1874
|
const { readFile: readFile10 } = await import("node:fs/promises");
|
|
1875
1875
|
const { join: join14 } = await import("node:path");
|
|
1876
|
-
const oldText = await git(["show", `HEAD:${
|
|
1876
|
+
const oldText = await git(["show", `HEAD:${path24}`]);
|
|
1877
1877
|
let newText = "";
|
|
1878
1878
|
try {
|
|
1879
|
-
const abs = cwd ? join14(cwd,
|
|
1879
|
+
const abs = cwd ? join14(cwd, path24) : path24;
|
|
1880
1880
|
const buf = await readFile10(abs);
|
|
1881
1881
|
if (buf.includes(0)) {
|
|
1882
1882
|
reply({ oldText: "", newText: "", binary: true });
|
|
@@ -3750,6 +3750,44 @@ async function handleSuperMemoryList(ws, memoryStore) {
|
|
|
3750
3750
|
send(ws, { type: "memory.super.list", payload: { error: errMessage(err) } });
|
|
3751
3751
|
}
|
|
3752
3752
|
}
|
|
3753
|
+
async function handleSuperMemoryListPage(ws, msg, memoryStore) {
|
|
3754
|
+
if (!isSuperMemoryStore(memoryStore)) {
|
|
3755
|
+
send(ws, { type: "memory.super.listPage", payload: { error: requiresSuperMemory("memory.super.listPage") } });
|
|
3756
|
+
return;
|
|
3757
|
+
}
|
|
3758
|
+
try {
|
|
3759
|
+
const payload = msg.payload ?? {};
|
|
3760
|
+
const options = {
|
|
3761
|
+
statuses: Array.isArray(payload["statuses"]) ? payload["statuses"].filter((s) => typeof s === "string") : void 0,
|
|
3762
|
+
kind: typeof payload["kind"] === "string" ? payload["kind"] : void 0,
|
|
3763
|
+
query: typeof payload["query"] === "string" ? payload["query"] : void 0,
|
|
3764
|
+
limit: typeof payload["limit"] === "number" ? payload["limit"] : void 0,
|
|
3765
|
+
cursor: typeof payload["cursor"] === "string" ? payload["cursor"] : void 0
|
|
3766
|
+
};
|
|
3767
|
+
if (typeof memoryStore.listSuperPage === "function") {
|
|
3768
|
+
const page = await memoryStore.listSuperPage(options);
|
|
3769
|
+
send(ws, { type: "memory.super.listPage", payload: page });
|
|
3770
|
+
return;
|
|
3771
|
+
}
|
|
3772
|
+
const allowed = options.statuses && options.statuses.length > 0 ? new Set(options.statuses) : void 0;
|
|
3773
|
+
const everything = await memoryStore.listSuper();
|
|
3774
|
+
const statusCounts = {};
|
|
3775
|
+
for (const m of everything) statusCounts[m.status] = (statusCounts[m.status] ?? 0) + 1;
|
|
3776
|
+
const kind = options.kind && options.kind !== "all" ? options.kind : void 0;
|
|
3777
|
+
const q = options.query?.trim().toLowerCase();
|
|
3778
|
+
const filtered = everything.filter((m) => {
|
|
3779
|
+
if (allowed) return allowed.has(m.status);
|
|
3780
|
+
return m.status !== "deleted";
|
|
3781
|
+
}).filter((m) => !kind || m.kind === kind).filter((m) => !q || m.text.toLowerCase().includes(q));
|
|
3782
|
+
const limit = Math.max(1, Math.min(500, Math.floor(options.limit ?? 50)));
|
|
3783
|
+
send(ws, {
|
|
3784
|
+
type: "memory.super.listPage",
|
|
3785
|
+
payload: { memories: filtered.slice(0, limit), nextCursor: null, total: filtered.length, statusCounts }
|
|
3786
|
+
});
|
|
3787
|
+
} catch (err) {
|
|
3788
|
+
send(ws, { type: "memory.super.listPage", payload: { error: errMessage(err) } });
|
|
3789
|
+
}
|
|
3790
|
+
}
|
|
3753
3791
|
async function handleSuperMemoryGet(ws, msg, memoryStore) {
|
|
3754
3792
|
if (!isSuperMemoryStore(memoryStore)) {
|
|
3755
3793
|
send(ws, { type: "memory.super.get", payload: { error: requiresSuperMemory("memory.super.get") } });
|
|
@@ -4299,7 +4337,7 @@ async function loadSavedProviders(configPath, vault) {
|
|
|
4299
4337
|
if (!parsed.providers) return {};
|
|
4300
4338
|
return decryptConfigSecrets(parsed.providers, vault);
|
|
4301
4339
|
}
|
|
4302
|
-
async function saveProviders(configPath, vault, providers) {
|
|
4340
|
+
async function saveProviders(configPath, vault, providers, profileConfigPath) {
|
|
4303
4341
|
let raw;
|
|
4304
4342
|
let fileExists = true;
|
|
4305
4343
|
try {
|
|
@@ -4333,6 +4371,23 @@ async function saveProviders(configPath, vault, providers) {
|
|
|
4333
4371
|
parsed.providers = providers;
|
|
4334
4372
|
const encrypted = encryptConfigSecrets(parsed, vault);
|
|
4335
4373
|
await atomicWrite4(configPath, JSON.stringify(encrypted, null, 2), { mode: 384 });
|
|
4374
|
+
if (profileConfigPath && profileConfigPath !== configPath) {
|
|
4375
|
+
let profileRaw;
|
|
4376
|
+
try {
|
|
4377
|
+
profileRaw = await fs8.readFile(profileConfigPath, "utf8");
|
|
4378
|
+
} catch {
|
|
4379
|
+
profileRaw = "{}";
|
|
4380
|
+
}
|
|
4381
|
+
let profileParsed;
|
|
4382
|
+
try {
|
|
4383
|
+
profileParsed = JSON.parse(profileRaw);
|
|
4384
|
+
} catch {
|
|
4385
|
+
return;
|
|
4386
|
+
}
|
|
4387
|
+
profileParsed.providers = providers;
|
|
4388
|
+
const profileEncrypted = encryptConfigSecrets(profileParsed, vault);
|
|
4389
|
+
await atomicWrite4(profileConfigPath, JSON.stringify(profileEncrypted, null, 2), { mode: 384 });
|
|
4390
|
+
}
|
|
4336
4391
|
}
|
|
4337
4392
|
|
|
4338
4393
|
// src/server/provider-keys.ts
|
|
@@ -5247,34 +5302,34 @@ var ENUM_PREF_KEYS = {
|
|
|
5247
5302
|
chimeraAutoFix: /* @__PURE__ */ new Set(["off", "ask", "auto"]),
|
|
5248
5303
|
autoReviewCascadeOn: /* @__PURE__ */ new Set(["off", "critical", "high"])
|
|
5249
5304
|
};
|
|
5250
|
-
function validateModelRuntimeValue(modelRuntime,
|
|
5305
|
+
function validateModelRuntimeValue(modelRuntime, path24) {
|
|
5251
5306
|
const reasoning = modelRuntime["reasoning"];
|
|
5252
5307
|
if (reasoning !== void 0) {
|
|
5253
|
-
if (!isRecord(reasoning)) return `${
|
|
5308
|
+
if (!isRecord(reasoning)) return `${path24}.reasoning must be an object when provided`;
|
|
5254
5309
|
const mode = reasoning["mode"];
|
|
5255
5310
|
const effort = reasoning["effort"];
|
|
5256
5311
|
const preserve = reasoning["preserve"];
|
|
5257
5312
|
if (mode !== void 0 && (typeof mode !== "string" || !REASONING_MODE_VALUES.has(mode))) {
|
|
5258
|
-
return `${
|
|
5313
|
+
return `${path24}.reasoning.mode must be one of: ${Array.from(REASONING_MODE_VALUES).join(", ")}`;
|
|
5259
5314
|
}
|
|
5260
5315
|
if (effort !== void 0 && (typeof effort !== "string" || !REASONING_EFFORT_VALUES.has(effort))) {
|
|
5261
|
-
return `${
|
|
5316
|
+
return `${path24}.reasoning.effort must be one of: ${Array.from(REASONING_EFFORT_VALUES).join(", ")}`;
|
|
5262
5317
|
}
|
|
5263
5318
|
if (preserve !== void 0 && typeof preserve !== "boolean") {
|
|
5264
|
-
return `${
|
|
5319
|
+
return `${path24}.reasoning.preserve must be a boolean when provided`;
|
|
5265
5320
|
}
|
|
5266
5321
|
}
|
|
5267
5322
|
const cache = modelRuntime["cache"];
|
|
5268
5323
|
if (cache !== void 0) {
|
|
5269
|
-
if (!isRecord(cache)) return `${
|
|
5324
|
+
if (!isRecord(cache)) return `${path24}.cache must be an object when provided`;
|
|
5270
5325
|
const ttl = cache["ttl"];
|
|
5271
5326
|
if (ttl !== void 0 && (typeof ttl !== "string" || !CACHE_TTL_VALUES.has(ttl) || ttl === "default")) {
|
|
5272
|
-
return `${
|
|
5327
|
+
return `${path24}.cache.ttl must be one of: 5m, 1h`;
|
|
5273
5328
|
}
|
|
5274
5329
|
}
|
|
5275
5330
|
const parameters = modelRuntime["parameters"];
|
|
5276
5331
|
if (parameters !== void 0 && !isRecord(parameters)) {
|
|
5277
|
-
return `${
|
|
5332
|
+
return `${path24}.parameters must be an object when provided`;
|
|
5278
5333
|
}
|
|
5279
5334
|
return null;
|
|
5280
5335
|
}
|
|
@@ -5567,8 +5622,8 @@ function validateShellOpenPayload(payload) {
|
|
|
5567
5622
|
if (!isRecord(payload)) {
|
|
5568
5623
|
return { ok: false, message: "shell.open payload must be an object with string path" };
|
|
5569
5624
|
}
|
|
5570
|
-
const
|
|
5571
|
-
if (typeof
|
|
5625
|
+
const path24 = payload["path"];
|
|
5626
|
+
if (typeof path24 !== "string" || path24.trim().length === 0) {
|
|
5572
5627
|
return { ok: false, message: "shell.open payload.path must be a non-empty string" };
|
|
5573
5628
|
}
|
|
5574
5629
|
const target = payload["target"];
|
|
@@ -5581,7 +5636,7 @@ function validateShellOpenPayload(payload) {
|
|
|
5581
5636
|
return {
|
|
5582
5637
|
ok: true,
|
|
5583
5638
|
value: {
|
|
5584
|
-
path:
|
|
5639
|
+
path: path24,
|
|
5585
5640
|
...target !== void 0 ? { target } : {}
|
|
5586
5641
|
}
|
|
5587
5642
|
};
|
|
@@ -5590,14 +5645,14 @@ function validateGitDiffPayload(payload) {
|
|
|
5590
5645
|
if (!isRecord(payload)) {
|
|
5591
5646
|
return { ok: false, message: "git.diff payload must be an object" };
|
|
5592
5647
|
}
|
|
5593
|
-
const
|
|
5594
|
-
if (
|
|
5648
|
+
const path24 = payload["path"];
|
|
5649
|
+
if (path24 === void 0 || path24 === null) {
|
|
5595
5650
|
return { ok: true, value: { path: "" } };
|
|
5596
5651
|
}
|
|
5597
|
-
if (typeof
|
|
5652
|
+
if (typeof path24 !== "string") {
|
|
5598
5653
|
return { ok: false, message: "git.diff payload.path must be a string when provided" };
|
|
5599
5654
|
}
|
|
5600
|
-
return { ok: true, value: { path:
|
|
5655
|
+
return { ok: true, value: { path: path24 } };
|
|
5601
5656
|
}
|
|
5602
5657
|
|
|
5603
5658
|
// src/server/zip.ts
|
|
@@ -8927,7 +8982,7 @@ function isSuperMemoryService(memoryStore) {
|
|
|
8927
8982
|
}
|
|
8928
8983
|
|
|
8929
8984
|
// src/server/start-webui.ts
|
|
8930
|
-
import * as
|
|
8985
|
+
import * as path23 from "node:path";
|
|
8931
8986
|
import {
|
|
8932
8987
|
createDefaultPipelines,
|
|
8933
8988
|
createSessionEventBridge,
|
|
@@ -12695,6 +12750,8 @@ function createMessageDispatcher(opts) {
|
|
|
12695
12750
|
// ── SuperMemory operations ──
|
|
12696
12751
|
case "memory.super.list":
|
|
12697
12752
|
return handleSuperMemoryList(ws, deps2.memoryStore);
|
|
12753
|
+
case "memory.super.listPage":
|
|
12754
|
+
return handleSuperMemoryListPage(ws, msg, deps2.memoryStore);
|
|
12698
12755
|
case "memory.super.get":
|
|
12699
12756
|
return handleSuperMemoryGet(ws, msg, deps2.memoryStore);
|
|
12700
12757
|
case "memory.super.update":
|
|
@@ -13046,8 +13103,9 @@ function createMessageDispatcher(opts) {
|
|
|
13046
13103
|
|
|
13047
13104
|
// src/server/pref-helpers.ts
|
|
13048
13105
|
import * as fs14 from "node:fs/promises";
|
|
13106
|
+
import * as path20 from "node:path";
|
|
13049
13107
|
import { decryptConfigSecrets as decryptConfigSecrets2, encryptConfigSecrets as encryptConfigSecrets2 } from "@wrongstack/core/security";
|
|
13050
|
-
import { atomicWrite as atomicWrite6, FORBIDDEN_PROTO_KEYS as FORBIDDEN_PROTO_KEYS2 } from "@wrongstack/core/utils";
|
|
13108
|
+
import { atomicWrite as atomicWrite6, backupConfigFile, FORBIDDEN_PROTO_KEYS as FORBIDDEN_PROTO_KEYS2 } from "@wrongstack/core/utils";
|
|
13051
13109
|
var PREF_KEYS = [
|
|
13052
13110
|
"autonomy",
|
|
13053
13111
|
"autonomyDelayMs",
|
|
@@ -13136,26 +13194,34 @@ function prefSnapshot(contextMeta) {
|
|
|
13136
13194
|
}
|
|
13137
13195
|
return snapshot;
|
|
13138
13196
|
}
|
|
13197
|
+
async function writeGlobalConfigFile(filePath, vault, mutate, logger, errorLabel) {
|
|
13198
|
+
const globalRoot = path20.dirname(filePath);
|
|
13199
|
+
await backupConfigFile(filePath, { globalRoot });
|
|
13200
|
+
let raw;
|
|
13201
|
+
try {
|
|
13202
|
+
raw = await fs14.readFile(filePath, "utf8");
|
|
13203
|
+
} catch {
|
|
13204
|
+
raw = "{}";
|
|
13205
|
+
}
|
|
13206
|
+
let parsed;
|
|
13207
|
+
try {
|
|
13208
|
+
parsed = JSON.parse(raw);
|
|
13209
|
+
} catch {
|
|
13210
|
+
logger.warn(`${errorLabel}: refusing to overwrite corrupt config at ${filePath}`);
|
|
13211
|
+
return;
|
|
13212
|
+
}
|
|
13213
|
+
const decrypted = decryptConfigSecrets2(parsed, vault);
|
|
13214
|
+
mutate(decrypted);
|
|
13215
|
+
const encrypted = encryptConfigSecrets2(decrypted, vault);
|
|
13216
|
+
await atomicWrite6(filePath, JSON.stringify(encrypted, null, 2), { mode: 384 });
|
|
13217
|
+
}
|
|
13139
13218
|
async function updateGlobalConfig(deps2, holder, mutate, errorLabel) {
|
|
13140
|
-
const { globalConfigPath, vault, logger } = deps2;
|
|
13219
|
+
const { globalConfigPath, profileConfigPath, vault, logger } = deps2;
|
|
13141
13220
|
const write = async () => {
|
|
13142
|
-
|
|
13143
|
-
|
|
13144
|
-
|
|
13145
|
-
} catch {
|
|
13146
|
-
raw = "{}";
|
|
13221
|
+
await writeGlobalConfigFile(globalConfigPath, vault, mutate, logger, errorLabel);
|
|
13222
|
+
if (profileConfigPath && profileConfigPath !== globalConfigPath) {
|
|
13223
|
+
await writeGlobalConfigFile(profileConfigPath, vault, mutate, logger, errorLabel);
|
|
13147
13224
|
}
|
|
13148
|
-
let parsed;
|
|
13149
|
-
try {
|
|
13150
|
-
parsed = JSON.parse(raw);
|
|
13151
|
-
} catch {
|
|
13152
|
-
logger.warn(`${errorLabel}: refusing to overwrite corrupt config at ${globalConfigPath}`);
|
|
13153
|
-
return;
|
|
13154
|
-
}
|
|
13155
|
-
const decrypted = decryptConfigSecrets2(parsed, vault);
|
|
13156
|
-
mutate(decrypted);
|
|
13157
|
-
const encrypted = encryptConfigSecrets2(decrypted, vault);
|
|
13158
|
-
await atomicWrite6(globalConfigPath, JSON.stringify(encrypted, null, 2), { mode: 384 });
|
|
13159
13225
|
};
|
|
13160
13226
|
const next = holder.lock.then(write);
|
|
13161
13227
|
holder.lock = next.then(
|
|
@@ -13472,13 +13538,13 @@ async function probeModelDescriptors(cfg) {
|
|
|
13472
13538
|
}
|
|
13473
13539
|
}
|
|
13474
13540
|
function createProviderHandlers(deps2) {
|
|
13475
|
-
const { globalConfigPath, vault, broadcast: broadcast2, clients } = deps2;
|
|
13541
|
+
const { globalConfigPath, profileConfigPath, vault, broadcast: broadcast2, clients } = deps2;
|
|
13476
13542
|
let configWriteLock = deps2.getConfigWriteLock();
|
|
13477
13543
|
async function loadConfigProviders() {
|
|
13478
13544
|
return loadSavedProviders(globalConfigPath, vault);
|
|
13479
13545
|
}
|
|
13480
13546
|
async function saveConfigProviders(providers) {
|
|
13481
|
-
const next = configWriteLock.then(() => saveProviders(globalConfigPath, vault, providers)).catch((err) => {
|
|
13547
|
+
const next = configWriteLock.then(() => saveProviders(globalConfigPath, vault, providers, profileConfigPath)).catch((err) => {
|
|
13482
13548
|
const msg = toErrorMessage9(err);
|
|
13483
13549
|
console.error(JSON.stringify({
|
|
13484
13550
|
level: "error",
|
|
@@ -13753,7 +13819,7 @@ function createProviderHandlers(deps2) {
|
|
|
13753
13819
|
}
|
|
13754
13820
|
|
|
13755
13821
|
// src/server/routes.ts
|
|
13756
|
-
import
|
|
13822
|
+
import path22 from "node:path";
|
|
13757
13823
|
import {
|
|
13758
13824
|
buildRefinerContextSections,
|
|
13759
13825
|
enhanceUserPrompt,
|
|
@@ -13964,7 +14030,7 @@ function createModeHandlers(ctx) {
|
|
|
13964
14030
|
}
|
|
13965
14031
|
|
|
13966
14032
|
// src/server/project-handlers.ts
|
|
13967
|
-
import * as
|
|
14033
|
+
import * as path21 from "node:path";
|
|
13968
14034
|
function createProjectHandlers(ctx) {
|
|
13969
14035
|
return {
|
|
13970
14036
|
listProjects: async (ws) => {
|
|
@@ -13990,7 +14056,7 @@ function createProjectHandlers(ctx) {
|
|
|
13990
14056
|
selectProject: async (ws, msg) => {
|
|
13991
14057
|
const payload = msg.payload;
|
|
13992
14058
|
const root = typeof payload?.root === "string" ? payload.root : "";
|
|
13993
|
-
const name2 = typeof payload?.name === "string" ? payload.name : root ?
|
|
14059
|
+
const name2 = typeof payload?.name === "string" ? payload.name : root ? path21.basename(root) : "";
|
|
13994
14060
|
send(ws, {
|
|
13995
14061
|
type: "projects.selected",
|
|
13996
14062
|
payload: {
|
|
@@ -14444,7 +14510,9 @@ async function enrichProviderModelDescriptors(modelsRegistry, providerId, cfg, m
|
|
|
14444
14510
|
if (resolved.capabilities.vision) capabilities.add("vision");
|
|
14445
14511
|
return {
|
|
14446
14512
|
...model,
|
|
14447
|
-
contextWindow: model.contextWindow
|
|
14513
|
+
contextWindow: model.contextWindow ?? resolved.capabilities.maxContext ?? void 0,
|
|
14514
|
+
inputCost: model.inputCost ?? resolved.cost?.input,
|
|
14515
|
+
outputCost: model.outputCost ?? resolved.cost?.output,
|
|
14448
14516
|
capabilities: [...capabilities]
|
|
14449
14517
|
};
|
|
14450
14518
|
})
|
|
@@ -14453,6 +14521,7 @@ async function enrichProviderModelDescriptors(modelsRegistry, providerId, cfg, m
|
|
|
14453
14521
|
function buildRoutes(state, deps2, cb) {
|
|
14454
14522
|
const providerHandlers = createProviderHandlers({
|
|
14455
14523
|
globalConfigPath: deps2.globalConfigPath,
|
|
14524
|
+
profileConfigPath: deps2.profileConfigPath,
|
|
14456
14525
|
vault: deps2.vault,
|
|
14457
14526
|
getConfigWriteLock: state.getConfigWriteLock,
|
|
14458
14527
|
setConfigWriteLock: state.setConfigWriteLock,
|
|
@@ -14920,7 +14989,7 @@ function buildRoutes(state, deps2, cb) {
|
|
|
14920
14989
|
}
|
|
14921
14990
|
return handleMailboxMessages(
|
|
14922
14991
|
ws,
|
|
14923
|
-
{ projectRoot: state.getProjectRoot(), globalRoot:
|
|
14992
|
+
{ projectRoot: state.getProjectRoot(), globalRoot: path22.dirname(deps2.globalConfigPath) },
|
|
14924
14993
|
parsed.value
|
|
14925
14994
|
);
|
|
14926
14995
|
},
|
|
@@ -14932,13 +15001,13 @@ function buildRoutes(state, deps2, cb) {
|
|
|
14932
15001
|
}
|
|
14933
15002
|
return handleMailboxAgents(
|
|
14934
15003
|
ws,
|
|
14935
|
-
{ projectRoot: state.getProjectRoot(), globalRoot:
|
|
15004
|
+
{ projectRoot: state.getProjectRoot(), globalRoot: path22.dirname(deps2.globalConfigPath) },
|
|
14936
15005
|
parsed.value
|
|
14937
15006
|
);
|
|
14938
15007
|
},
|
|
14939
15008
|
clear: (ws) => handleMailboxClear(ws, {
|
|
14940
15009
|
projectRoot: state.getProjectRoot(),
|
|
14941
|
-
globalRoot:
|
|
15010
|
+
globalRoot: path22.dirname(deps2.globalConfigPath)
|
|
14942
15011
|
}),
|
|
14943
15012
|
purge: (ws, msg) => {
|
|
14944
15013
|
const parsed = validateMailboxPurgePayload(msg.payload);
|
|
@@ -14948,14 +15017,14 @@ function buildRoutes(state, deps2, cb) {
|
|
|
14948
15017
|
}
|
|
14949
15018
|
return handleMailboxPurge(
|
|
14950
15019
|
ws,
|
|
14951
|
-
{ projectRoot: state.getProjectRoot(), globalRoot:
|
|
15020
|
+
{ projectRoot: state.getProjectRoot(), globalRoot: path22.dirname(deps2.globalConfigPath) },
|
|
14952
15021
|
parsed.value
|
|
14953
15022
|
);
|
|
14954
15023
|
},
|
|
14955
15024
|
compact: (ws, msg) => {
|
|
14956
15025
|
return handleMailboxCompact(
|
|
14957
15026
|
ws,
|
|
14958
|
-
{ projectRoot: state.getProjectRoot(), globalRoot:
|
|
15027
|
+
{ projectRoot: state.getProjectRoot(), globalRoot: path22.dirname(deps2.globalConfigPath) },
|
|
14959
15028
|
msg.payload ?? {}
|
|
14960
15029
|
);
|
|
14961
15030
|
}
|
|
@@ -15106,7 +15175,9 @@ async function startWebUI(opts = {}) {
|
|
|
15106
15175
|
let projectRoot = boot.projectRoot;
|
|
15107
15176
|
let workingDir = projectRoot;
|
|
15108
15177
|
const configWriteLock = { lock: Promise.resolve() };
|
|
15109
|
-
const
|
|
15178
|
+
const activeProfile = config.activeProfile ?? "default";
|
|
15179
|
+
const profileConfigPath = wpaths.profileConfig(activeProfile);
|
|
15180
|
+
const prefHelperDeps = { globalConfigPath, profileConfigPath, vault, logger };
|
|
15110
15181
|
const updateGlobalConfig2 = async (mutate, errorLabel) => updateGlobalConfig(prefHelperDeps, configWriteLock, mutate, errorLabel);
|
|
15111
15182
|
console.log("[WebUI] Config loaded:", config.provider ?? "(none)", "/", config.model ?? "(none)");
|
|
15112
15183
|
if (!config.provider && config.providers && typeof config.providers === "object" && config.providers !== null && !Array.isArray(config.providers) && Object.keys(config.providers).length > 0) {
|
|
@@ -15268,21 +15339,21 @@ async function startWebUI(opts = {}) {
|
|
|
15268
15339
|
wpaths
|
|
15269
15340
|
}, watcherMetricsRef);
|
|
15270
15341
|
async function touchProjectEntry(root, workDir) {
|
|
15271
|
-
const resolved =
|
|
15342
|
+
const resolved = path23.resolve(root);
|
|
15272
15343
|
const manifest = await loadManifest(globalConfigPath);
|
|
15273
15344
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
15274
|
-
const existing = manifest.projects.find((p) =>
|
|
15345
|
+
const existing = manifest.projects.find((p) => path23.resolve(p.root) === resolved);
|
|
15275
15346
|
if (existing) {
|
|
15276
15347
|
existing.lastSeen = now;
|
|
15277
|
-
if (workDir) existing.lastWorkingDir =
|
|
15348
|
+
if (workDir) existing.lastWorkingDir = path23.resolve(workDir);
|
|
15278
15349
|
} else {
|
|
15279
15350
|
manifest.projects.push({
|
|
15280
|
-
name:
|
|
15351
|
+
name: path23.basename(resolved),
|
|
15281
15352
|
root: resolved,
|
|
15282
15353
|
slug: generateProjectSlug(resolved),
|
|
15283
15354
|
createdAt: now,
|
|
15284
15355
|
lastSeen: now,
|
|
15285
|
-
lastWorkingDir: workDir ?
|
|
15356
|
+
lastWorkingDir: workDir ? path23.resolve(workDir) : void 0
|
|
15286
15357
|
});
|
|
15287
15358
|
}
|
|
15288
15359
|
await saveManifest(manifest, globalConfigPath);
|
|
@@ -15389,6 +15460,7 @@ async function startWebUI(opts = {}) {
|
|
|
15389
15460
|
persistPrefsToConfig: persistPrefsToConfig2,
|
|
15390
15461
|
prefSnapshot: prefSnapshot2
|
|
15391
15462
|
};
|
|
15463
|
+
const watchConfigPath = profileConfigPath ?? globalConfigPath;
|
|
15392
15464
|
let credentialWatcherClose;
|
|
15393
15465
|
if (process.env["WRONGSTACK_DISABLE_CONFIG_WATCH"] !== "1") {
|
|
15394
15466
|
let lastActiveCfg = JSON.stringify(
|
|
@@ -15396,7 +15468,7 @@ async function startWebUI(opts = {}) {
|
|
|
15396
15468
|
);
|
|
15397
15469
|
let lastUiLocale = state.getConfig().uiLocale;
|
|
15398
15470
|
const credentialWatcher = watchProviderConfig(
|
|
15399
|
-
|
|
15471
|
+
watchConfigPath,
|
|
15400
15472
|
vault,
|
|
15401
15473
|
(snapshot) => {
|
|
15402
15474
|
state.setConfig(
|
|
@@ -15537,7 +15609,7 @@ async function startWebUI(opts = {}) {
|
|
|
15537
15609
|
archiveLowConfidenceAfterDays: config.superMemory?.hygiene?.archiveLowConfidenceAfterDays
|
|
15538
15610
|
}).catch((err) => logger.warn(`super-memory session hygiene failed: ${toErrorMessage10(err)}`));
|
|
15539
15611
|
}
|
|
15540
|
-
await unregisterInstance(process.pid,
|
|
15612
|
+
await unregisterInstance(process.pid, path23.dirname(globalConfigPath));
|
|
15541
15613
|
}
|
|
15542
15614
|
});
|
|
15543
15615
|
}
|