@wrongstack/webui-server 0.291.0 → 0.291.1

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 CHANGED
@@ -1809,15 +1809,15 @@ async function handleGitChanges(ws, projectRoot) {
1809
1809
  if (!m) continue;
1810
1810
  const added = m[1] === "-" ? 0 : Number(m[1]);
1811
1811
  const deleted = m[2] === "-" ? 0 : Number(m[2]);
1812
- let path24 = m[3] ?? "";
1813
- if (path24 === "") {
1812
+ let path25 = m[3] ?? "";
1813
+ if (path25 === "") {
1814
1814
  i += 1;
1815
- path24 = parts[i + 1] ?? parts[i] ?? "";
1815
+ path25 = parts[i + 1] ?? parts[i] ?? "";
1816
1816
  i += 1;
1817
1817
  }
1818
- if (!path24) continue;
1819
- const prev = counts.get(path24) ?? { added: 0, deleted: 0 };
1820
- counts.set(path24, { added: prev.added + added, deleted: prev.deleted + deleted });
1818
+ if (!path25) continue;
1819
+ const prev = counts.get(path25) ?? { added: 0, deleted: 0 };
1820
+ counts.set(path25, { added: prev.added + added, deleted: prev.deleted + deleted });
1821
1821
  }
1822
1822
  };
1823
1823
  parseNumstat(unstagedNumstat);
@@ -1829,7 +1829,7 @@ async function handleGitChanges(ws, projectRoot) {
1829
1829
  if (!rec || rec.length < 3) continue;
1830
1830
  const x = rec[0] ?? " ";
1831
1831
  const y = rec[1] ?? " ";
1832
- const path24 = rec.slice(3);
1832
+ const path25 = rec.slice(3);
1833
1833
  const isRename = x === "R" || x === "C" || y === "R" || y === "C";
1834
1834
  if (isRename) i += 1;
1835
1835
  let status;
@@ -1841,13 +1841,13 @@ async function handleGitChanges(ws, projectRoot) {
1841
1841
  else if (x === "D" || y === "D") status = "D";
1842
1842
  else status = "M";
1843
1843
  const staged = x !== " " && x !== "?";
1844
- let added = counts.get(path24)?.added ?? 0;
1845
- let deleted = counts.get(path24)?.deleted ?? 0;
1844
+ let added = counts.get(path25)?.added ?? 0;
1845
+ let deleted = counts.get(path25)?.deleted ?? 0;
1846
1846
  if (status === "?") {
1847
1847
  added = 0;
1848
1848
  deleted = 0;
1849
1849
  }
1850
- files.push({ path: path24, status, added, deleted, staged });
1850
+ files.push({ path: path25, status, added, deleted, staged });
1851
1851
  }
1852
1852
  send(ws, { type: "git.changes", payload: { files } });
1853
1853
  } catch (err) {
@@ -1858,10 +1858,10 @@ async function handleGitChanges(ws, projectRoot) {
1858
1858
  }
1859
1859
  }
1860
1860
  var MAX_DIFF_BYTES = 2 * 1024 * 1024;
1861
- async function handleGitDiff(ws, projectRoot, path24) {
1861
+ async function handleGitDiff(ws, projectRoot, path25) {
1862
1862
  const cwd = projectRoot || void 0;
1863
- const reply = (extra) => send(ws, { type: "git.diff", payload: { path: path24, ...extra } });
1864
- if (!path24 || path24.includes("\0") || path24.includes("..") || nodePath.isAbsolute(path24)) {
1863
+ const reply = (extra) => send(ws, { type: "git.diff", payload: { path: path25, ...extra } });
1864
+ if (!path25 || path25.includes("\0") || path25.includes("..") || nodePath.isAbsolute(path25)) {
1865
1865
  reply({ oldText: "", newText: "", error: "invalid path" });
1866
1866
  return;
1867
1867
  }
@@ -1869,10 +1869,10 @@ async function handleGitDiff(ws, projectRoot, path24) {
1869
1869
  const git = makeGit(cwd);
1870
1870
  const { readFile: readFile11 } = await import("node:fs/promises");
1871
1871
  const { join: join15 } = await import("node:path");
1872
- const oldText = await git(["show", `HEAD:${path24}`]);
1872
+ const oldText = await git(["show", `HEAD:${path25}`]);
1873
1873
  let newText = "";
1874
1874
  try {
1875
- const abs = cwd ? join15(cwd, path24) : path24;
1875
+ const abs = cwd ? join15(cwd, path25) : path25;
1876
1876
  const buf = await readFile11(abs);
1877
1877
  if (buf.includes(0)) {
1878
1878
  reply({ oldText: "", newText: "", binary: true });
@@ -3754,6 +3754,44 @@ async function handleSuperMemoryList(ws, memoryStore) {
3754
3754
  send(ws, { type: "memory.super.list", payload: { error: errMessage(err) } });
3755
3755
  }
3756
3756
  }
3757
+ async function handleSuperMemoryListPage(ws, msg, memoryStore) {
3758
+ if (!isSuperMemoryStore(memoryStore)) {
3759
+ send(ws, { type: "memory.super.listPage", payload: { error: requiresSuperMemory("memory.super.listPage") } });
3760
+ return;
3761
+ }
3762
+ try {
3763
+ const payload = msg.payload ?? {};
3764
+ const options = {
3765
+ statuses: Array.isArray(payload["statuses"]) ? payload["statuses"].filter((s) => typeof s === "string") : void 0,
3766
+ kind: typeof payload["kind"] === "string" ? payload["kind"] : void 0,
3767
+ query: typeof payload["query"] === "string" ? payload["query"] : void 0,
3768
+ limit: typeof payload["limit"] === "number" ? payload["limit"] : void 0,
3769
+ cursor: typeof payload["cursor"] === "string" ? payload["cursor"] : void 0
3770
+ };
3771
+ if (typeof memoryStore.listSuperPage === "function") {
3772
+ const page = await memoryStore.listSuperPage(options);
3773
+ send(ws, { type: "memory.super.listPage", payload: page });
3774
+ return;
3775
+ }
3776
+ const allowed = options.statuses && options.statuses.length > 0 ? new Set(options.statuses) : void 0;
3777
+ const everything = await memoryStore.listSuper();
3778
+ const statusCounts = {};
3779
+ for (const m of everything) statusCounts[m.status] = (statusCounts[m.status] ?? 0) + 1;
3780
+ const kind = options.kind && options.kind !== "all" ? options.kind : void 0;
3781
+ const q = options.query?.trim().toLowerCase();
3782
+ const filtered = everything.filter((m) => {
3783
+ if (allowed) return allowed.has(m.status);
3784
+ return m.status !== "deleted";
3785
+ }).filter((m) => !kind || m.kind === kind).filter((m) => !q || m.text.toLowerCase().includes(q));
3786
+ const limit = Math.max(1, Math.min(500, Math.floor(options.limit ?? 50)));
3787
+ send(ws, {
3788
+ type: "memory.super.listPage",
3789
+ payload: { memories: filtered.slice(0, limit), nextCursor: null, total: filtered.length, statusCounts }
3790
+ });
3791
+ } catch (err) {
3792
+ send(ws, { type: "memory.super.listPage", payload: { error: errMessage(err) } });
3793
+ }
3794
+ }
3757
3795
  async function handleSuperMemoryGet(ws, msg, memoryStore) {
3758
3796
  if (!isSuperMemoryStore(memoryStore)) {
3759
3797
  send(ws, { type: "memory.super.get", payload: { error: requiresSuperMemory("memory.super.get") } });
@@ -4317,7 +4355,7 @@ async function loadSavedProviders(configPath, vault) {
4317
4355
  if (!parsed.providers) return {};
4318
4356
  return decryptConfigSecrets(parsed.providers, vault);
4319
4357
  }
4320
- async function saveProviders(configPath, vault, providers) {
4358
+ async function saveProviders(configPath, vault, providers, profileConfigPath) {
4321
4359
  let raw;
4322
4360
  let fileExists = true;
4323
4361
  try {
@@ -4351,6 +4389,23 @@ async function saveProviders(configPath, vault, providers) {
4351
4389
  parsed.providers = providers;
4352
4390
  const encrypted = encryptConfigSecrets(parsed, vault);
4353
4391
  await atomicWrite4(configPath, JSON.stringify(encrypted, null, 2), { mode: 384 });
4392
+ if (profileConfigPath && profileConfigPath !== configPath) {
4393
+ let profileRaw;
4394
+ try {
4395
+ profileRaw = await fs8.readFile(profileConfigPath, "utf8");
4396
+ } catch {
4397
+ profileRaw = "{}";
4398
+ }
4399
+ let profileParsed;
4400
+ try {
4401
+ profileParsed = JSON.parse(profileRaw);
4402
+ } catch {
4403
+ return;
4404
+ }
4405
+ profileParsed.providers = providers;
4406
+ const profileEncrypted = encryptConfigSecrets(profileParsed, vault);
4407
+ await atomicWrite4(profileConfigPath, JSON.stringify(profileEncrypted, null, 2), { mode: 384 });
4408
+ }
4354
4409
  }
4355
4410
 
4356
4411
  // src/server/provider-config-standalone.ts
@@ -5275,34 +5330,34 @@ var ENUM_PREF_KEYS = {
5275
5330
  chimeraAutoFix: /* @__PURE__ */ new Set(["off", "ask", "auto"]),
5276
5331
  autoReviewCascadeOn: /* @__PURE__ */ new Set(["off", "critical", "high"])
5277
5332
  };
5278
- function validateModelRuntimeValue(modelRuntime, path24) {
5333
+ function validateModelRuntimeValue(modelRuntime, path25) {
5279
5334
  const reasoning = modelRuntime["reasoning"];
5280
5335
  if (reasoning !== void 0) {
5281
- if (!isRecord(reasoning)) return `${path24}.reasoning must be an object when provided`;
5336
+ if (!isRecord(reasoning)) return `${path25}.reasoning must be an object when provided`;
5282
5337
  const mode = reasoning["mode"];
5283
5338
  const effort = reasoning["effort"];
5284
5339
  const preserve = reasoning["preserve"];
5285
5340
  if (mode !== void 0 && (typeof mode !== "string" || !REASONING_MODE_VALUES.has(mode))) {
5286
- return `${path24}.reasoning.mode must be one of: ${Array.from(REASONING_MODE_VALUES).join(", ")}`;
5341
+ return `${path25}.reasoning.mode must be one of: ${Array.from(REASONING_MODE_VALUES).join(", ")}`;
5287
5342
  }
5288
5343
  if (effort !== void 0 && (typeof effort !== "string" || !REASONING_EFFORT_VALUES.has(effort))) {
5289
- return `${path24}.reasoning.effort must be one of: ${Array.from(REASONING_EFFORT_VALUES).join(", ")}`;
5344
+ return `${path25}.reasoning.effort must be one of: ${Array.from(REASONING_EFFORT_VALUES).join(", ")}`;
5290
5345
  }
5291
5346
  if (preserve !== void 0 && typeof preserve !== "boolean") {
5292
- return `${path24}.reasoning.preserve must be a boolean when provided`;
5347
+ return `${path25}.reasoning.preserve must be a boolean when provided`;
5293
5348
  }
5294
5349
  }
5295
5350
  const cache = modelRuntime["cache"];
5296
5351
  if (cache !== void 0) {
5297
- if (!isRecord(cache)) return `${path24}.cache must be an object when provided`;
5352
+ if (!isRecord(cache)) return `${path25}.cache must be an object when provided`;
5298
5353
  const ttl = cache["ttl"];
5299
5354
  if (ttl !== void 0 && (typeof ttl !== "string" || !CACHE_TTL_VALUES.has(ttl) || ttl === "default")) {
5300
- return `${path24}.cache.ttl must be one of: 5m, 1h`;
5355
+ return `${path25}.cache.ttl must be one of: 5m, 1h`;
5301
5356
  }
5302
5357
  }
5303
5358
  const parameters = modelRuntime["parameters"];
5304
5359
  if (parameters !== void 0 && !isRecord(parameters)) {
5305
- return `${path24}.parameters must be an object when provided`;
5360
+ return `${path25}.parameters must be an object when provided`;
5306
5361
  }
5307
5362
  return null;
5308
5363
  }
@@ -5595,8 +5650,8 @@ function validateShellOpenPayload(payload) {
5595
5650
  if (!isRecord(payload)) {
5596
5651
  return { ok: false, message: "shell.open payload must be an object with string path" };
5597
5652
  }
5598
- const path24 = payload["path"];
5599
- if (typeof path24 !== "string" || path24.trim().length === 0) {
5653
+ const path25 = payload["path"];
5654
+ if (typeof path25 !== "string" || path25.trim().length === 0) {
5600
5655
  return { ok: false, message: "shell.open payload.path must be a non-empty string" };
5601
5656
  }
5602
5657
  const target = payload["target"];
@@ -5609,7 +5664,7 @@ function validateShellOpenPayload(payload) {
5609
5664
  return {
5610
5665
  ok: true,
5611
5666
  value: {
5612
- path: path24,
5667
+ path: path25,
5613
5668
  ...target !== void 0 ? { target } : {}
5614
5669
  }
5615
5670
  };
@@ -5618,14 +5673,14 @@ function validateGitDiffPayload(payload) {
5618
5673
  if (!isRecord(payload)) {
5619
5674
  return { ok: false, message: "git.diff payload must be an object" };
5620
5675
  }
5621
- const path24 = payload["path"];
5622
- if (path24 === void 0 || path24 === null) {
5676
+ const path25 = payload["path"];
5677
+ if (path25 === void 0 || path25 === null) {
5623
5678
  return { ok: true, value: { path: "" } };
5624
5679
  }
5625
- if (typeof path24 !== "string") {
5680
+ if (typeof path25 !== "string") {
5626
5681
  return { ok: false, message: "git.diff payload.path must be a string when provided" };
5627
5682
  }
5628
- return { ok: true, value: { path: path24 } };
5683
+ return { ok: true, value: { path: path25 } };
5629
5684
  }
5630
5685
  function validateProjectsAddPayload(payload) {
5631
5686
  if (!isRecord(payload)) {
@@ -9031,7 +9086,7 @@ function isSuperMemoryService(memoryStore) {
9031
9086
  }
9032
9087
 
9033
9088
  // src/server/start-webui.ts
9034
- import * as path23 from "node:path";
9089
+ import * as path24 from "node:path";
9035
9090
  import {
9036
9091
  createDefaultPipelines,
9037
9092
  createSessionEventBridge,
@@ -12799,6 +12854,8 @@ function createMessageDispatcher(opts) {
12799
12854
  // ── SuperMemory operations ──
12800
12855
  case "memory.super.list":
12801
12856
  return handleSuperMemoryList(ws, deps2.memoryStore);
12857
+ case "memory.super.listPage":
12858
+ return handleSuperMemoryListPage(ws, msg, deps2.memoryStore);
12802
12859
  case "memory.super.get":
12803
12860
  return handleSuperMemoryGet(ws, msg, deps2.memoryStore);
12804
12861
  case "memory.super.update":
@@ -13150,8 +13207,9 @@ function createMessageDispatcher(opts) {
13150
13207
 
13151
13208
  // src/server/pref-helpers.ts
13152
13209
  import * as fs14 from "node:fs/promises";
13210
+ import * as path21 from "node:path";
13153
13211
  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";
13212
+ import { atomicWrite as atomicWrite6, backupConfigFile, FORBIDDEN_PROTO_KEYS as FORBIDDEN_PROTO_KEYS2 } from "@wrongstack/core/utils";
13155
13213
  var PREF_KEYS = [
13156
13214
  "autonomy",
13157
13215
  "autonomyDelayMs",
@@ -13240,26 +13298,34 @@ function prefSnapshot(contextMeta) {
13240
13298
  }
13241
13299
  return snapshot;
13242
13300
  }
13301
+ async function writeGlobalConfigFile(filePath, vault, mutate, logger, errorLabel) {
13302
+ const globalRoot = path21.dirname(filePath);
13303
+ await backupConfigFile(filePath, { globalRoot });
13304
+ let raw;
13305
+ try {
13306
+ raw = await fs14.readFile(filePath, "utf8");
13307
+ } catch {
13308
+ raw = "{}";
13309
+ }
13310
+ let parsed;
13311
+ try {
13312
+ parsed = JSON.parse(raw);
13313
+ } catch {
13314
+ logger.warn(`${errorLabel}: refusing to overwrite corrupt config at ${filePath}`);
13315
+ return;
13316
+ }
13317
+ const decrypted = decryptConfigSecrets2(parsed, vault);
13318
+ mutate(decrypted);
13319
+ const encrypted = encryptConfigSecrets2(decrypted, vault);
13320
+ await atomicWrite6(filePath, JSON.stringify(encrypted, null, 2), { mode: 384 });
13321
+ }
13243
13322
  async function updateGlobalConfig(deps2, holder, mutate, errorLabel) {
13244
- const { globalConfigPath, vault, logger } = deps2;
13323
+ const { globalConfigPath, profileConfigPath, vault, logger } = deps2;
13245
13324
  const write = async () => {
13246
- let raw;
13247
- try {
13248
- raw = await fs14.readFile(globalConfigPath, "utf8");
13249
- } catch {
13250
- raw = "{}";
13325
+ await writeGlobalConfigFile(globalConfigPath, vault, mutate, logger, errorLabel);
13326
+ if (profileConfigPath && profileConfigPath !== globalConfigPath) {
13327
+ await writeGlobalConfigFile(profileConfigPath, vault, mutate, logger, errorLabel);
13251
13328
  }
13252
- let parsed;
13253
- try {
13254
- parsed = JSON.parse(raw);
13255
- } catch {
13256
- logger.warn(`${errorLabel}: refusing to overwrite corrupt config at ${globalConfigPath}`);
13257
- return;
13258
- }
13259
- const decrypted = decryptConfigSecrets2(parsed, vault);
13260
- mutate(decrypted);
13261
- const encrypted = encryptConfigSecrets2(decrypted, vault);
13262
- await atomicWrite6(globalConfigPath, JSON.stringify(encrypted, null, 2), { mode: 384 });
13263
13329
  };
13264
13330
  const next = holder.lock.then(write);
13265
13331
  holder.lock = next.then(
@@ -13576,13 +13642,13 @@ async function probeModelDescriptors(cfg) {
13576
13642
  }
13577
13643
  }
13578
13644
  function createProviderHandlers(deps2) {
13579
- const { globalConfigPath, vault, broadcast: broadcast2, clients } = deps2;
13645
+ const { globalConfigPath, profileConfigPath, vault, broadcast: broadcast2, clients } = deps2;
13580
13646
  let configWriteLock = deps2.getConfigWriteLock();
13581
13647
  async function loadConfigProviders() {
13582
13648
  return loadSavedProviders(globalConfigPath, vault);
13583
13649
  }
13584
13650
  async function saveConfigProviders(providers) {
13585
- const next = configWriteLock.then(() => saveProviders(globalConfigPath, vault, providers)).catch((err) => {
13651
+ const next = configWriteLock.then(() => saveProviders(globalConfigPath, vault, providers, profileConfigPath)).catch((err) => {
13586
13652
  const msg = toErrorMessage9(err);
13587
13653
  console.error(JSON.stringify({
13588
13654
  level: "error",
@@ -13857,7 +13923,7 @@ function createProviderHandlers(deps2) {
13857
13923
  }
13858
13924
 
13859
13925
  // src/server/routes.ts
13860
- import path22 from "node:path";
13926
+ import path23 from "node:path";
13861
13927
  import {
13862
13928
  buildRefinerContextSections,
13863
13929
  enhanceUserPrompt,
@@ -14068,7 +14134,7 @@ function createModeHandlers(ctx) {
14068
14134
  }
14069
14135
 
14070
14136
  // src/server/project-handlers.ts
14071
- import * as path21 from "node:path";
14137
+ import * as path22 from "node:path";
14072
14138
  function createProjectHandlers(ctx) {
14073
14139
  return {
14074
14140
  listProjects: async (ws) => {
@@ -14094,7 +14160,7 @@ function createProjectHandlers(ctx) {
14094
14160
  selectProject: async (ws, msg) => {
14095
14161
  const payload = msg.payload;
14096
14162
  const root = typeof payload?.root === "string" ? payload.root : "";
14097
- const name2 = typeof payload?.name === "string" ? payload.name : root ? path21.basename(root) : "";
14163
+ const name2 = typeof payload?.name === "string" ? payload.name : root ? path22.basename(root) : "";
14098
14164
  send(ws, {
14099
14165
  type: "projects.selected",
14100
14166
  payload: {
@@ -14548,7 +14614,9 @@ async function enrichProviderModelDescriptors(modelsRegistry, providerId, cfg, m
14548
14614
  if (resolved.capabilities.vision) capabilities.add("vision");
14549
14615
  return {
14550
14616
  ...model,
14551
- contextWindow: model.contextWindow || resolved.capabilities.maxContext || void 0,
14617
+ contextWindow: model.contextWindow ?? resolved.capabilities.maxContext ?? void 0,
14618
+ inputCost: model.inputCost ?? resolved.cost?.input,
14619
+ outputCost: model.outputCost ?? resolved.cost?.output,
14552
14620
  capabilities: [...capabilities]
14553
14621
  };
14554
14622
  })
@@ -14557,6 +14625,7 @@ async function enrichProviderModelDescriptors(modelsRegistry, providerId, cfg, m
14557
14625
  function buildRoutes(state, deps2, cb) {
14558
14626
  const providerHandlers = createProviderHandlers({
14559
14627
  globalConfigPath: deps2.globalConfigPath,
14628
+ profileConfigPath: deps2.profileConfigPath,
14560
14629
  vault: deps2.vault,
14561
14630
  getConfigWriteLock: state.getConfigWriteLock,
14562
14631
  setConfigWriteLock: state.setConfigWriteLock,
@@ -15024,7 +15093,7 @@ function buildRoutes(state, deps2, cb) {
15024
15093
  }
15025
15094
  return handleMailboxMessages(
15026
15095
  ws,
15027
- { projectRoot: state.getProjectRoot(), globalRoot: path22.dirname(deps2.globalConfigPath) },
15096
+ { projectRoot: state.getProjectRoot(), globalRoot: path23.dirname(deps2.globalConfigPath) },
15028
15097
  parsed.value
15029
15098
  );
15030
15099
  },
@@ -15036,13 +15105,13 @@ function buildRoutes(state, deps2, cb) {
15036
15105
  }
15037
15106
  return handleMailboxAgents(
15038
15107
  ws,
15039
- { projectRoot: state.getProjectRoot(), globalRoot: path22.dirname(deps2.globalConfigPath) },
15108
+ { projectRoot: state.getProjectRoot(), globalRoot: path23.dirname(deps2.globalConfigPath) },
15040
15109
  parsed.value
15041
15110
  );
15042
15111
  },
15043
15112
  clear: (ws) => handleMailboxClear(ws, {
15044
15113
  projectRoot: state.getProjectRoot(),
15045
- globalRoot: path22.dirname(deps2.globalConfigPath)
15114
+ globalRoot: path23.dirname(deps2.globalConfigPath)
15046
15115
  }),
15047
15116
  purge: (ws, msg) => {
15048
15117
  const parsed = validateMailboxPurgePayload(msg.payload);
@@ -15052,14 +15121,14 @@ function buildRoutes(state, deps2, cb) {
15052
15121
  }
15053
15122
  return handleMailboxPurge(
15054
15123
  ws,
15055
- { projectRoot: state.getProjectRoot(), globalRoot: path22.dirname(deps2.globalConfigPath) },
15124
+ { projectRoot: state.getProjectRoot(), globalRoot: path23.dirname(deps2.globalConfigPath) },
15056
15125
  parsed.value
15057
15126
  );
15058
15127
  },
15059
15128
  compact: (ws, msg) => {
15060
15129
  return handleMailboxCompact(
15061
15130
  ws,
15062
- { projectRoot: state.getProjectRoot(), globalRoot: path22.dirname(deps2.globalConfigPath) },
15131
+ { projectRoot: state.getProjectRoot(), globalRoot: path23.dirname(deps2.globalConfigPath) },
15063
15132
  msg.payload ?? {}
15064
15133
  );
15065
15134
  }
@@ -15210,7 +15279,9 @@ async function startWebUI(opts = {}) {
15210
15279
  let projectRoot = boot.projectRoot;
15211
15280
  let workingDir = projectRoot;
15212
15281
  const configWriteLock = { lock: Promise.resolve() };
15213
- const prefHelperDeps = { globalConfigPath, vault, logger };
15282
+ const activeProfile = config.activeProfile ?? "default";
15283
+ const profileConfigPath = wpaths.profileConfig(activeProfile);
15284
+ const prefHelperDeps = { globalConfigPath, profileConfigPath, vault, logger };
15214
15285
  const updateGlobalConfig2 = async (mutate, errorLabel) => updateGlobalConfig(prefHelperDeps, configWriteLock, mutate, errorLabel);
15215
15286
  console.log("[WebUI] Config loaded:", config.provider ?? "(none)", "/", config.model ?? "(none)");
15216
15287
  if (!config.provider && config.providers && typeof config.providers === "object" && config.providers !== null && !Array.isArray(config.providers) && Object.keys(config.providers).length > 0) {
@@ -15372,21 +15443,21 @@ async function startWebUI(opts = {}) {
15372
15443
  wpaths
15373
15444
  }, watcherMetricsRef);
15374
15445
  async function touchProjectEntry(root, workDir) {
15375
- const resolved = path23.resolve(root);
15446
+ const resolved = path24.resolve(root);
15376
15447
  const manifest = await loadManifest(globalConfigPath);
15377
15448
  const now = (/* @__PURE__ */ new Date()).toISOString();
15378
- const existing = manifest.projects.find((p) => path23.resolve(p.root) === resolved);
15449
+ const existing = manifest.projects.find((p) => path24.resolve(p.root) === resolved);
15379
15450
  if (existing) {
15380
15451
  existing.lastSeen = now;
15381
- if (workDir) existing.lastWorkingDir = path23.resolve(workDir);
15452
+ if (workDir) existing.lastWorkingDir = path24.resolve(workDir);
15382
15453
  } else {
15383
15454
  manifest.projects.push({
15384
- name: path23.basename(resolved),
15455
+ name: path24.basename(resolved),
15385
15456
  root: resolved,
15386
15457
  slug: generateProjectSlug(resolved),
15387
15458
  createdAt: now,
15388
15459
  lastSeen: now,
15389
- lastWorkingDir: workDir ? path23.resolve(workDir) : void 0
15460
+ lastWorkingDir: workDir ? path24.resolve(workDir) : void 0
15390
15461
  });
15391
15462
  }
15392
15463
  await saveManifest(manifest, globalConfigPath);
@@ -15493,6 +15564,7 @@ async function startWebUI(opts = {}) {
15493
15564
  persistPrefsToConfig: persistPrefsToConfig2,
15494
15565
  prefSnapshot: prefSnapshot2
15495
15566
  };
15567
+ const watchConfigPath = profileConfigPath ?? globalConfigPath;
15496
15568
  let credentialWatcherClose;
15497
15569
  if (process.env["WRONGSTACK_DISABLE_CONFIG_WATCH"] !== "1") {
15498
15570
  let lastActiveCfg = JSON.stringify(
@@ -15500,7 +15572,7 @@ async function startWebUI(opts = {}) {
15500
15572
  );
15501
15573
  let lastUiLocale = state.getConfig().uiLocale;
15502
15574
  const credentialWatcher = watchProviderConfig(
15503
- globalConfigPath,
15575
+ watchConfigPath,
15504
15576
  vault,
15505
15577
  (snapshot) => {
15506
15578
  state.setConfig(
@@ -15641,7 +15713,7 @@ async function startWebUI(opts = {}) {
15641
15713
  archiveLowConfidenceAfterDays: config.superMemory?.hygiene?.archiveLowConfidenceAfterDays
15642
15714
  }).catch((err) => logger.warn(`super-memory session hygiene failed: ${toErrorMessage10(err)}`));
15643
15715
  }
15644
- await unregisterInstance(process.pid, path23.dirname(globalConfigPath));
15716
+ await unregisterInstance(process.pid, path24.dirname(globalConfigPath));
15645
15717
  }
15646
15718
  });
15647
15719
  }
@@ -15852,6 +15924,7 @@ export {
15852
15924
  handleSuperMemoryForFile,
15853
15925
  handleSuperMemoryGet,
15854
15926
  handleSuperMemoryList,
15927
+ handleSuperMemoryListPage,
15855
15928
  handleSuperMemoryRecover,
15856
15929
  handleSuperMemoryRemember,
15857
15930
  handleSuperMemoryUpdate,