@wrongstack/webui 0.280.1 → 0.281.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.
Files changed (68) hide show
  1. package/dist/assets/AnalyticsDashboard-uYxJjohK.js +1 -0
  2. package/dist/assets/AutoPhaseView-DG8bm0_l.js +1 -0
  3. package/dist/assets/CodeEditor-DLzmCqWF.js +1 -0
  4. package/dist/assets/DebugDashboard-D6-znhBO.js +1 -0
  5. package/dist/assets/DesignGalleryView-CtA0fPrm.js +1 -0
  6. package/dist/assets/MailboxDetailView-2_R4qJn-.js +1 -0
  7. package/dist/assets/OfficeMapPanel-BNZNbZik.js +4 -0
  8. package/dist/assets/ProcessMonitor-DgEXCx7y.js +1 -0
  9. package/dist/assets/QueuePanel-DL8SvR30.js +1 -0
  10. package/dist/assets/RefreshDebugView-pmMPOier.js +1 -0
  11. package/dist/assets/SddBoardView-CFhQv9Pv.js +2 -0
  12. package/dist/assets/SddFlowGraph-WW0qCx0t.js +1 -0
  13. package/dist/assets/SddWizard-Cnksg4-y.js +1 -0
  14. package/dist/assets/SessionsDashboard-VwXvmSxS.js +1 -0
  15. package/dist/assets/SkillDetailView-C1qcnlPI.js +2 -0
  16. package/dist/assets/SpecsView-BY7LKawq.js +1 -0
  17. package/dist/assets/TerminalPanel-Dq0Xdhdv.js +1 -0
  18. package/dist/assets/activity-DT93tsyC.js +5 -0
  19. package/dist/assets/chat-DCAGDU3F.js +1 -0
  20. package/dist/assets/chat-store-YPRVJGbn.js +5 -0
  21. package/dist/assets/commandPalette-DUootORZ.js +1 -0
  22. package/dist/assets/common-D7usadq4.js +1 -0
  23. package/dist/assets/i18n-BJCOtLro.js +2 -0
  24. package/dist/assets/index-CMiinLaB.css +1 -0
  25. package/dist/assets/index-DJpDzI2b.js +145 -0
  26. package/dist/assets/markdown-D0X23O-i.js +44 -0
  27. package/dist/assets/monaco-Br_kD0ds.css +1 -0
  28. package/dist/assets/monaco-DqY9Mr3N.js +1211 -0
  29. package/dist/assets/session-store-Do0MGnXu.js +1 -0
  30. package/dist/assets/settings-CGhOOFpI.js +1 -0
  31. package/dist/assets/setup-B8S3Rhsj.js +1 -0
  32. package/dist/assets/setup-BPkWK-DE.js +1 -0
  33. package/dist/assets/setup-BqoJ89VQ.js +1 -0
  34. package/dist/assets/setup-C4wNoopG.js +1 -0
  35. package/dist/assets/setup-CGWbN6bj.js +1 -0
  36. package/dist/assets/setup-Dr2UDb8s.js +1 -0
  37. package/dist/assets/setup-Iyk4ncan.js +1 -0
  38. package/dist/assets/toasts-BL_8kH4B.js +1 -0
  39. package/dist/assets/ui-store-D3gGpJWY.js +1 -0
  40. package/dist/assets/utils-sFCTikqz.js +1 -0
  41. package/dist/assets/vendor-Bhf0nZ3B.js +70 -0
  42. package/dist/assets/vendor-CcOzUMQS.css +1 -0
  43. package/dist/assets/ws-client-D9IQ9580.js +1 -0
  44. package/dist/assets/xterm-B9RXJkIu.js +36 -0
  45. package/dist/assets/xterm-BrP-ENHg.css +1 -0
  46. package/dist/assets/xyflow-Bp8EMwkC.js +7 -0
  47. package/dist/assets/xyflow-DtxX27Jz.css +1 -0
  48. package/dist/index.css +247 -0
  49. package/dist/index.css.map +1 -1
  50. package/dist/index.html +20 -4
  51. package/dist/index.js +31866 -30427
  52. package/dist/index.js.map +1 -1
  53. package/dist/server/entry.js +119 -44
  54. package/dist/server/entry.js.map +1 -1
  55. package/dist/server/index.js +119 -44
  56. package/dist/server/index.js.map +1 -1
  57. package/dist/types.d.ts +7 -1
  58. package/package.json +6 -13
  59. package/dist/assets/index-BMDGZBnY.css +0 -2
  60. package/dist/assets/index-Ci_SxQGe.js +0 -157
  61. package/dist/assets/setup-B5TfeR6q.js +0 -1
  62. package/dist/assets/setup-BBwNpiE3.js +0 -1
  63. package/dist/assets/setup-BT2iTMm4.js +0 -1
  64. package/dist/assets/setup-CVMjqrZh.js +0 -1
  65. package/dist/assets/setup-DOXm3hFc.js +0 -1
  66. package/dist/assets/setup-Dhb_xOpk.js +0 -1
  67. package/dist/assets/vendor-B_dTeUDT.js +0 -1364
  68. package/dist/assets/vendor-C3aCZA5Q.css +0 -1
@@ -6561,6 +6561,7 @@ function registerShutdown(deps2) {
6561
6561
  import * as path15 from "path";
6562
6562
  import { createRequire } from "module";
6563
6563
  import { WebSocket as WebSocket2 } from "ws";
6564
+ import { DefaultTokenCounter } from "@wrongstack/core/infrastructure";
6564
6565
  import {
6565
6566
  AgentStatusTracker,
6566
6567
  AnnotationsStore,
@@ -6573,7 +6574,6 @@ import {
6573
6574
  DefaultSessionStore,
6574
6575
  DefaultSkillLoader,
6575
6576
  DefaultSystemPromptBuilder,
6576
- DefaultTokenCounter,
6577
6577
  EventBus,
6578
6578
  FleetNotifier,
6579
6579
  GlobalMailbox,
@@ -6589,6 +6589,7 @@ import {
6589
6589
  getSessionRegistry,
6590
6590
  makeMailboxTool,
6591
6591
  makeMailInboxTool,
6592
+ makeFleetStatusTool,
6592
6593
  makeMailSendTool
6593
6594
  } from "@wrongstack/core";
6594
6595
  import { MCPRegistry } from "@wrongstack/mcp";
@@ -6862,6 +6863,7 @@ async function createPreContextServices(input) {
6862
6863
  toolRegistry.register(makeMailboxTool({ projectDir: wpaths.projectDir, events }));
6863
6864
  toolRegistry.register(makeMailSendTool({ projectDir: wpaths.projectDir, events }));
6864
6865
  toolRegistry.register(makeMailInboxTool({ projectDir: wpaths.projectDir, events }));
6866
+ toolRegistry.register(makeFleetStatusTool({ projectDir: wpaths.projectDir, events }));
6865
6867
  applyToolDescriptionModes(toolRegistry, config.tools?.descriptionMode);
6866
6868
  applyToolResultRenderModes(toolRegistry, config.tools?.resultRenderMode);
6867
6869
  configureExecPolicy(config.tools?.exec ?? {});
@@ -6876,7 +6878,25 @@ async function createPreContextServices(input) {
6876
6878
  });
6877
6879
  }
6878
6880
  }
6879
- const sessionStore = opts.services?.session ?? new DefaultSessionStore({ dir: wpaths.projectSessions });
6881
+ const sessionStore = opts.services?.session ?? new DefaultSessionStore({
6882
+ dir: wpaths.projectSessions,
6883
+ // Cross-process guard for delete(): refuses to remove a session that a
6884
+ // live terminal/TUI/WebUI in this project is using. The store also
6885
+ // checks active.json directly; this widens it to every concurrent
6886
+ // surface via the SessionRegistry.
6887
+ isSessionInUse: async (sessionId) => {
6888
+ try {
6889
+ const registry = getSessionRegistry(wpaths.globalRoot);
6890
+ const live = await registry.listByProject(wpaths.projectSlug);
6891
+ const hit = live.find((e) => e.sessionId === sessionId);
6892
+ if (hit) {
6893
+ return `active in ${hit.projectName} (PID ${hit.pid})`;
6894
+ }
6895
+ } catch {
6896
+ }
6897
+ return null;
6898
+ }
6899
+ });
6880
6900
  if (!opts.services?.session) {
6881
6901
  sessionStore.prune(DEFAULT_SESSION_PRUNE_DAYS).then((count) => {
6882
6902
  if (count > 0) logger.info(`Pruned ${count} old session${count === 1 ? "" : "s"}.`);
@@ -9407,6 +9427,9 @@ async function handleSessionRoute(ws, msg, handlers) {
9407
9427
  case "sessions.list":
9408
9428
  await handlers.listSessions(ws, msg);
9409
9429
  return true;
9430
+ case "session.rename":
9431
+ await handlers.renameSession(ws, msg);
9432
+ return true;
9410
9433
  case "session.delete":
9411
9434
  await handlers.deleteSession(ws, msg);
9412
9435
  return true;
@@ -10983,6 +11006,38 @@ function createSessionHandlers(ctx) {
10983
11006
  sendResult(ws, false, errMessage(err));
10984
11007
  }
10985
11008
  },
11009
+ renameSession: async (ws, msg) => {
11010
+ const payload = msg.payload ?? {};
11011
+ const id = typeof payload.id === "string" ? payload.id : "";
11012
+ const name2 = typeof payload.name === "string" ? payload.name : "";
11013
+ if (!id) {
11014
+ sendResult(ws, false, "Session id is required");
11015
+ return;
11016
+ }
11017
+ try {
11018
+ await ctx.getSessionStore().rename(id, name2);
11019
+ sendResult(ws, true, name2 ? `Renamed session to "${name2}"` : `Cleared session name`);
11020
+ const list = await ctx.getSessionStore().list(50);
11021
+ const currentId = ctx.getSession().id;
11022
+ broadcast(ctx.clients, {
11023
+ type: "sessions.list",
11024
+ payload: {
11025
+ sessions: list.map((s) => ({
11026
+ id: s.id,
11027
+ name: s.name,
11028
+ title: s.title,
11029
+ startedAt: s.startedAt,
11030
+ model: s.model,
11031
+ provider: s.provider,
11032
+ tokenTotal: s.tokenTotal,
11033
+ isCurrent: s.id === currentId
11034
+ }))
11035
+ }
11036
+ });
11037
+ } catch (err) {
11038
+ sendResult(ws, false, errMessage(err));
11039
+ }
11040
+ },
10986
11041
  resumeSession: async (ws, msg) => {
10987
11042
  const { id } = msg.payload;
10988
11043
  try {
@@ -11108,15 +11163,17 @@ function buildRoutes(state, deps2, cb) {
11108
11163
  send(ws, {
11109
11164
  type: "provider.catalog",
11110
11165
  payload: {
11111
- providers: providers.map((p) => ({
11112
- id: p.id,
11113
- name: p.name,
11114
- family: p.family,
11115
- apiBase: p.apiBase,
11116
- envVars: p.envVars,
11117
- modelCount: p.models.length,
11118
- hasApiKey: savedIds.has(p.id) || p.envVars.some((v) => !!process.env[v])
11119
- }))
11166
+ providers: providers.map(
11167
+ (p) => ({
11168
+ id: p.id,
11169
+ name: p.name,
11170
+ family: p.family,
11171
+ apiBase: p.apiBase,
11172
+ envVars: p.envVars,
11173
+ modelCount: p.models.length,
11174
+ hasApiKey: savedIds.has(p.id) || p.envVars.some((v) => !!process.env[v])
11175
+ })
11176
+ )
11120
11177
  }
11121
11178
  });
11122
11179
  },
@@ -11131,16 +11188,12 @@ function buildRoutes(state, deps2, cb) {
11131
11188
  const providerId = msg.payload.providerId;
11132
11189
  const saved = await providerHandlers.loadConfigProviders();
11133
11190
  const cfg = saved[providerId];
11134
- const provider = await resolveProviderCatalogForModels(
11135
- deps2.modelsRegistry,
11136
- providerId,
11137
- cfg
11138
- );
11191
+ const provider = await resolveProviderCatalogForModels(deps2.modelsRegistry, providerId, cfg);
11139
11192
  const models = await enrichProviderModelDescriptors(
11140
11193
  deps2.modelsRegistry,
11141
11194
  providerId,
11142
11195
  cfg,
11143
- resolveProviderModelList(cfg?.models, provider)
11196
+ resolveProviderModelList(cfg?.models, provider, cfg?.type ?? providerId)
11144
11197
  );
11145
11198
  send(ws, {
11146
11199
  type: "provider.models",
@@ -11163,7 +11216,9 @@ function buildRoutes(state, deps2, cb) {
11163
11216
  deps2.configStore.update({ provider: newProvider, model: newModel });
11164
11217
  deps2.context.model = newModel;
11165
11218
  const newCfg = state.getConfig();
11166
- const providerCfg = newCfg.providers?.[newProvider] ?? { type: newProvider };
11219
+ const providerCfg = newCfg.providers?.[newProvider] ?? {
11220
+ type: newProvider
11221
+ };
11167
11222
  const newProv = deps2.providerRegistry.has(newProvider) ? deps2.providerRegistry.create({ ...providerCfg, type: newProvider }) : makeProviderFromConfig2(newProvider, providerCfg);
11168
11223
  deps2.context.provider = newProv;
11169
11224
  await cb.updateAutoCompactionMaxContext(newProv, newProvider, providerCfg);
@@ -11217,12 +11272,14 @@ function buildRoutes(state, deps2, cb) {
11217
11272
  timeoutMs: 9e4,
11218
11273
  ...reasoning ? { reasoning } : {},
11219
11274
  onError: (reason) => {
11220
- console.warn(JSON.stringify({
11221
- level: "warn",
11222
- event: "model.refine_failed",
11223
- reason,
11224
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
11225
- }));
11275
+ console.warn(
11276
+ JSON.stringify({
11277
+ level: "warn",
11278
+ event: "model.refine_failed",
11279
+ reason,
11280
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
11281
+ })
11282
+ );
11226
11283
  }
11227
11284
  });
11228
11285
  if (result) {
@@ -11237,12 +11294,14 @@ function buildRoutes(state, deps2, cb) {
11237
11294
  });
11238
11295
  }
11239
11296
  } catch (err) {
11240
- console.error(JSON.stringify({
11241
- level: "error",
11242
- event: "model.refine.error",
11243
- error: errMessage(err),
11244
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
11245
- }));
11297
+ console.error(
11298
+ JSON.stringify({
11299
+ level: "error",
11300
+ event: "model.refine.error",
11301
+ error: errMessage(err),
11302
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
11303
+ })
11304
+ );
11246
11305
  send(ws, {
11247
11306
  type: "model.refine_result",
11248
11307
  payload: { refined: text, english: text, error: errMessage(err) }
@@ -11324,17 +11383,24 @@ function buildRoutes(state, deps2, cb) {
11324
11383
  const cfg = state.getConfig();
11325
11384
  const features = cfg.features ?? {};
11326
11385
  if (typeof payload["featureMcp"] === "boolean") features["mcp"] = payload["featureMcp"];
11327
- if (typeof payload["featurePlugins"] === "boolean") features["plugins"] = payload["featurePlugins"];
11328
- if (typeof payload["featureMemory"] === "boolean") features["memory"] = payload["featureMemory"];
11329
- if (typeof payload["featureSkills"] === "boolean") features["skills"] = payload["featureSkills"];
11330
- if (typeof payload["featureModelsRegistry"] === "boolean") features["modelsRegistry"] = payload["featureModelsRegistry"];
11386
+ if (typeof payload["featurePlugins"] === "boolean")
11387
+ features["plugins"] = payload["featurePlugins"];
11388
+ if (typeof payload["featureMemory"] === "boolean")
11389
+ features["memory"] = payload["featureMemory"];
11390
+ if (typeof payload["featureSkills"] === "boolean")
11391
+ features["skills"] = payload["featureSkills"];
11392
+ if (typeof payload["featureModelsRegistry"] === "boolean")
11393
+ features["modelsRegistry"] = payload["featureModelsRegistry"];
11331
11394
  cfg.features = features;
11332
- if (Array.isArray(payload["fallbackModels"])) cfg.fallbackModels = payload["fallbackModels"];
11395
+ if (Array.isArray(payload["fallbackModels"]))
11396
+ cfg.fallbackModels = payload["fallbackModels"];
11333
11397
  if (payload["fallbackProfiles"] && typeof payload["fallbackProfiles"] === "object" && !Array.isArray(payload["fallbackProfiles"])) {
11334
11398
  cfg.fallbackProfiles = payload["fallbackProfiles"];
11335
11399
  }
11336
- if (Array.isArray(payload["favoriteModels"])) cfg.favoriteModels = payload["favoriteModels"];
11337
- if (typeof payload["favoriteModelsOnly"] === "boolean") cfg.favoriteModelsOnly = payload["favoriteModelsOnly"];
11400
+ if (Array.isArray(payload["favoriteModels"]))
11401
+ cfg.favoriteModels = payload["favoriteModels"];
11402
+ if (typeof payload["favoriteModelsOnly"] === "boolean")
11403
+ cfg.favoriteModelsOnly = payload["favoriteModelsOnly"];
11338
11404
  if (payload["modelMatrix"] && typeof payload["modelMatrix"] === "object" && !Array.isArray(payload["modelMatrix"])) {
11339
11405
  cfg.modelMatrix = payload["modelMatrix"];
11340
11406
  }
@@ -11342,7 +11408,10 @@ function buildRoutes(state, deps2, cb) {
11342
11408
  if (typeof payload["contextAutoCompact"] === "boolean") {
11343
11409
  if (payload["contextAutoCompact"] && deps2.autoCompactor) {
11344
11410
  deps2.pipelines.contextWindow.remove("AutoCompaction", { optional: true });
11345
- deps2.pipelines.contextWindow.use({ name: "AutoCompaction", handler: deps2.autoCompactor.handler() });
11411
+ deps2.pipelines.contextWindow.use({
11412
+ name: "AutoCompaction",
11413
+ handler: deps2.autoCompactor.handler()
11414
+ });
11346
11415
  } else {
11347
11416
  deps2.pipelines.contextWindow.remove("AutoCompaction", { optional: true });
11348
11417
  }
@@ -11377,7 +11446,10 @@ function buildRoutes(state, deps2, cb) {
11377
11446
  sendResult(ws, false, parsed.message);
11378
11447
  return;
11379
11448
  }
11380
- const result = await handleShellOpen(parsed.value, deps2.logger);
11449
+ const result = await handleShellOpen(
11450
+ parsed.value,
11451
+ deps2.logger
11452
+ );
11381
11453
  sendResult(ws, result.success, result.message);
11382
11454
  }
11383
11455
  };
@@ -11406,10 +11478,10 @@ function buildRoutes(state, deps2, cb) {
11406
11478
  parsed.value
11407
11479
  );
11408
11480
  },
11409
- clear: (ws) => handleMailboxClear(
11410
- ws,
11411
- { projectRoot: state.getProjectRoot(), globalRoot: path21.dirname(deps2.globalConfigPath) }
11412
- ),
11481
+ clear: (ws) => handleMailboxClear(ws, {
11482
+ projectRoot: state.getProjectRoot(),
11483
+ globalRoot: path21.dirname(deps2.globalConfigPath)
11484
+ }),
11413
11485
  purge: (ws, msg) => {
11414
11486
  const parsed = validateMailboxPurgePayload(msg.payload);
11415
11487
  if (!parsed.ok) {
@@ -11471,7 +11543,10 @@ function buildRoutes(state, deps2, cb) {
11471
11543
  risk: "medium",
11472
11544
  fallback: "ask_human"
11473
11545
  });
11474
- send(ws, { type: "brain.answer", payload: { sessionId: deps2.context.session?.id, question, decision } });
11546
+ send(ws, {
11547
+ type: "brain.answer",
11548
+ payload: { sessionId: deps2.context.session?.id, question, decision }
11549
+ });
11475
11550
  } catch (err) {
11476
11551
  sendResult(ws, false, `Brain consultation failed: ${errMessage(err)}`);
11477
11552
  }