@wrongstack/webui 0.77.0 → 0.84.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.
@@ -8,11 +8,11 @@ interface WSServerMessage {
8
8
  }
9
9
  interface WSClientMessage {
10
10
  type: string;
11
- payload?: unknown;
11
+ payload?: unknown | undefined;
12
12
  }
13
13
  interface WebUIOptions {
14
- port?: number;
15
- webuiPort?: number;
14
+ port?: number | undefined;
15
+ webuiPort?: number | undefined;
16
16
  }
17
17
  interface BackendServices {
18
18
  agent: Agent;
@@ -33,7 +33,7 @@ interface ConnectedClient {
33
33
 
34
34
  interface CreateHttpServerOptions {
35
35
  /** Port to listen on. Defaults to 3456 (or the `PORT` env var). */
36
- port?: number;
36
+ port?: number | undefined;
37
37
  /** Host/interface to bind. Typically the loopback for the WebUI. */
38
38
  host: string;
39
39
  /** Resolved path to the directory containing the built React assets. */
@@ -84,9 +84,9 @@ declare function createHttpServer(opts: CreateHttpServerOptions): http.Server;
84
84
  declare function isPortFree(host: string, port: number): Promise<boolean>;
85
85
  interface FindFreePortOptions {
86
86
  /** Ports to skip even if free (e.g. one already chosen for the sibling server). */
87
- exclude?: Set<number>;
87
+ exclude?: Set<number> | undefined;
88
88
  /** How many consecutive ports to try before giving up. Default 200. */
89
- maxTries?: number;
89
+ maxTries?: number | undefined;
90
90
  }
91
91
  /**
92
92
  * Find the first free port at or above `startPort` on `host`, skipping any in
@@ -216,13 +216,13 @@ declare function hostHeaderOk(input: {
216
216
  }): boolean;
217
217
  interface VerifyClientInput {
218
218
  /** Browser `Origin` header, or undefined for non-browser clients. */
219
- origin?: string;
219
+ origin?: string | undefined;
220
220
  /** Request URL (`req.url`) — carries the `?token=…` query param. */
221
221
  url: string;
222
222
  /** `Host` header (`req.headers.host`). */
223
- hostHeader?: string;
223
+ hostHeader?: string | undefined;
224
224
  /** Peer address (`req.socket.remoteAddress`). */
225
- remoteAddress?: string;
225
+ remoteAddress?: string | undefined;
226
226
  /** Host/interface the WS server is bound to. */
227
227
  wsHost: string;
228
228
  /** The server's generated auth token. */
@@ -280,8 +280,8 @@ declare function setActiveKey(providers: ProvidersRecord, providerId: string, la
280
280
  declare function addProvider(providers: ProvidersRecord, payload: {
281
281
  id: string;
282
282
  family: string;
283
- baseUrl?: string;
284
- apiKey?: string;
283
+ baseUrl?: string | undefined;
284
+ apiKey?: string | undefined;
285
285
  }, nowIso: string): KeyOpResult;
286
286
  /** Remove an entire provider and all its keys. */
287
287
  declare function removeProvider(providers: ProvidersRecord, providerId: string): KeyOpResult;
@@ -312,9 +312,9 @@ declare function createProviderConfigIO(configPath: string): {
312
312
  };
313
313
 
314
314
  declare function startWebUI(opts?: {
315
- wsPort?: number;
316
- wsHost?: string;
317
- open?: boolean;
315
+ wsPort?: number | undefined;
316
+ wsHost?: string | undefined;
317
+ open?: boolean | undefined;
318
318
  }): Promise<void>;
319
319
 
320
320
  export { type BackendServices, type ConnectedClient, type KeyOpResult, type ProvidersRecord, type VerifyClientInput, type WSClientMessage, type WSServerMessage, type WebUIInstanceRecord, type WebUIOptions, addProvider, broadcast, browserOpenCommand, buildCspHeader, createHttpServer, createProviderConfigIO, defaultBaseDir, deleteKey, errMessage, extractToken, findFreePort, formatInstances, generateAuthToken, hostHeaderOk, injectWsPort, isLoopbackBind, isLoopbackHostname, isPortFree, listInstances, loadSavedProviders, maskedKey, normalizeKeys, openBrowser, registerInstance, registryPath, removeProvider, saveProviders, send, sendResult, setActiveKey, startWebUI, tokenMatches, unregisterInstance, upsertKey, verifyClient, writeKeysBack };
@@ -235,13 +235,18 @@ function createDefaultContainer(opts) {
235
235
  }
236
236
  container.bind(
237
237
  TOKENS.PermissionPolicy,
238
- () => new DefaultPermissionPolicy({
239
- trustFile: wpaths.projectTrust,
240
- yolo: opts.permission?.yolo ?? false,
241
- yoloDestructive: opts.permission?.yoloDestructive ?? opts.permission?.forceAllYolo ?? false,
242
- confirmDestructive: opts.permission?.confirmDestructive ?? false,
243
- promptDelegate: opts.permission?.promptDelegate
244
- })
238
+ () => {
239
+ const policyOptions = {
240
+ trustFile: wpaths.projectTrust,
241
+ yolo: opts.permission?.yolo ?? false,
242
+ yoloDestructive: opts.permission?.yoloDestructive ?? opts.permission?.forceAllYolo ?? false,
243
+ confirmDestructive: opts.permission?.confirmDestructive ?? false
244
+ };
245
+ if (opts.permission?.promptDelegate !== void 0) {
246
+ policyOptions.promptDelegate = opts.permission.promptDelegate;
247
+ }
248
+ return new DefaultPermissionPolicy(policyOptions);
249
+ }
245
250
  );
246
251
  container.bind(
247
252
  TOKENS.Compactor,
@@ -1687,6 +1692,12 @@ function createProviderConfigIO(configPath) {
1687
1692
  }
1688
1693
 
1689
1694
  // src/server/provider-keys.ts
1695
+ function expectDefined(value) {
1696
+ if (value === null || value === void 0) {
1697
+ throw new Error("Expected value to be defined");
1698
+ }
1699
+ return value;
1700
+ }
1690
1701
  function normalizeKeys(cfg) {
1691
1702
  if (Array.isArray(cfg.apiKeys) && cfg.apiKeys.length > 0) {
1692
1703
  return cfg.apiKeys.map((k) => ({ ...k }));
@@ -1704,7 +1715,7 @@ function writeKeysBack(cfg, keys) {
1704
1715
  return;
1705
1716
  }
1706
1717
  cfg.apiKeys = keys;
1707
- const active = keys.find((k) => k.label === cfg.activeKey) ?? keys[0];
1718
+ const active = keys.find((k) => k.label === cfg.activeKey) ?? expectDefined(keys[0]);
1708
1719
  cfg.apiKey = active.apiKey;
1709
1720
  if (!cfg.activeKey || !keys.some((k) => k.label === cfg.activeKey)) {
1710
1721
  cfg.activeKey = active.label;
@@ -1720,7 +1731,7 @@ function upsertKey(providers, providerId, label, apiKey, nowIso) {
1720
1731
  const keys = normalizeKeys(existing);
1721
1732
  const idx = keys.findIndex((k) => k.label === label);
1722
1733
  if (idx >= 0) {
1723
- keys[idx] = { ...keys[idx], apiKey, createdAt: nowIso };
1734
+ keys[idx] = { ...expectDefined(keys[idx]), apiKey, createdAt: nowIso };
1724
1735
  } else {
1725
1736
  keys.push({ label, apiKey, createdAt: nowIso });
1726
1737
  }
@@ -1739,7 +1750,7 @@ function deleteKey(providers, providerId, label) {
1739
1750
  delete providers[providerId];
1740
1751
  } else {
1741
1752
  writeKeysBack(existing, keys);
1742
- if (existing.activeKey === label) existing.activeKey = keys[0].label;
1753
+ if (existing.activeKey === label) existing.activeKey = keys[0]?.label;
1743
1754
  providers[providerId] = existing;
1744
1755
  }
1745
1756
  return { ok: true, message: `Key "${label}" deleted from ${providerId}` };
@@ -1992,6 +2003,12 @@ function estimateContextBreakdown(input) {
1992
2003
  }
1993
2004
 
1994
2005
  // src/server/index.ts
2006
+ function expectDefined2(value) {
2007
+ if (value === null || value === void 0) {
2008
+ throw new Error("Expected value to be defined");
2009
+ }
2010
+ return value;
2011
+ }
1995
2012
  async function startWebUI(opts = {}) {
1996
2013
  const requestedWsPort = opts.wsPort ?? 3457;
1997
2014
  const wsHost = opts.wsHost ?? "127.0.0.1";
@@ -2016,7 +2033,7 @@ async function startWebUI(opts = {}) {
2016
2033
  let configWriteLock = Promise.resolve();
2017
2034
  console.log("[WebUI] Config loaded:", config.provider ?? "(none)", "/", config.model ?? "(none)");
2018
2035
  if (!config.provider && config.providers && typeof config.providers === "object" && config.providers !== null && !Array.isArray(config.providers) && Object.keys(config.providers).length > 0) {
2019
- const firstKey = Object.keys(config.providers)[0];
2036
+ const firstKey = expectDefined2(Object.keys(config.providers)[0]);
2020
2037
  config = patchConfig(config, { provider: firstKey });
2021
2038
  console.log("[WebUI] No active provider \u2014 auto-selected:", firstKey);
2022
2039
  }
@@ -2049,6 +2066,9 @@ async function startWebUI(opts = {}) {
2049
2066
  const events = new EventBus();
2050
2067
  events.setLogger(logger);
2051
2068
  const sessionStore = new DefaultSessionStore2({ dir: wpaths.projectSessions });
2069
+ sessionStore.prune(30).then((count) => {
2070
+ if (count > 0) logger.info(`Pruned ${count} old session${count === 1 ? "" : "s"}.`);
2071
+ }).catch(() => void 0);
2052
2072
  const sessionReader = new DefaultSessionReader({ store: sessionStore });
2053
2073
  const annotationsStore = new AnnotationsStore({ dir: wpaths.projectSessions });
2054
2074
  let session = await sessionStore.create({
@@ -2112,7 +2132,7 @@ async function startWebUI(opts = {}) {
2112
2132
  const savedProviders = config.providers ?? {};
2113
2133
  const firstKey = Object.keys(savedProviders)[0];
2114
2134
  if (firstKey) {
2115
- const firstProvider = savedProviders[firstKey];
2135
+ const firstProvider = expectDefined2(savedProviders[firstKey]);
2116
2136
  try {
2117
2137
  provider = makeProviderFromConfig(firstKey, {
2118
2138
  ...firstProvider,
@@ -2940,7 +2960,7 @@ async function startWebUI(opts = {}) {
2940
2960
  sendResult(ws, false, "Todo not found");
2941
2961
  break;
2942
2962
  }
2943
- const removed = context.todos[targetIdx];
2963
+ const removed = expectDefined2(context.todos[targetIdx]);
2944
2964
  const next = [
2945
2965
  ...context.todos.slice(0, targetIdx),
2946
2966
  ...context.todos.slice(targetIdx + 1)