@wrongstack/cli 0.308.1 → 0.308.4

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/README.md CHANGED
@@ -32,7 +32,7 @@ wstack resume <session-id> # equivalent
32
32
  ### Launch menu
33
33
 
34
34
  When `wstack` is invoked on an interactive TTY with no surface flag, the CLI
35
- prints a four-option launch menu and waits for a numeric choice:
35
+ prints a five-option launch menu and waits for a numeric choice:
36
36
 
37
37
  ```
38
38
  ✱ WrongStack launch mode
@@ -41,7 +41,8 @@ prints a four-option launch menu and waits for a numeric choice:
41
41
  2) WebUI (browser-based project UI; port 3456)
42
42
  3) SimpleUI (lightweight browser UI; port 3466)
43
43
  4) HQ (project-independent HQ dashboard; port 3499)
44
- [1-4, q to quit] (auto 1 in 8s)
44
+ 5) Desktop (Electron desktop shell; alias: --desktop)
45
+ [1-5, q to quit] (auto 1 in 8s)
45
46
  ```
46
47
 
47
48
  If you previously picked a mode, the menu shows a one-line summary and a
@@ -111,7 +111,7 @@
111
111
  "output": ["text"]
112
112
  },
113
113
  "limit": {
114
- "context": 400000,
114
+ "context": 1050000,
115
115
  "output": 128000
116
116
  }
117
117
  },
@@ -126,8 +126,8 @@
126
126
  "output": ["text"]
127
127
  },
128
128
  "limit": {
129
- "context": 128000,
130
- "output": 32000
129
+ "context": 1050000,
130
+ "output": 128000
131
131
  }
132
132
  }
133
133
  }
@@ -8,6 +8,7 @@
8
8
  * 2) WebUI — browser-based project UI (port 3456 by default)
9
9
  * 3) SimpleUI — lightweight browser UI (port 3466 by default)
10
10
  * 4) HQ — project-independent HQ dashboard (port 3499)
11
+ * 5) Desktop — Electron desktop shell (`wstack --desktop`)
11
12
  *
12
13
  * It returns either:
13
14
  * - `null` — caller should fall through to the historical
@@ -20,6 +21,8 @@
20
21
  * surface flag + chosen port into argv.
21
22
  * * `hq` → caller dispatches to the HQ
22
23
  * short-circuit with the chosen port/host.
24
+ * * `desktop` → caller injects `--desktop` and
25
+ * dispatches to the desktop short-circuit.
23
26
  *
24
27
  * Why this lives in `boot/`: it sits next to the other entry-point
25
28
  * short-circuits (`short-circuit-{flags,desktop,hq}.ts`) and is
@@ -40,7 +43,9 @@ export interface LaunchMenuResult extends LaunchMenuChoice {
40
43
  */
41
44
  cancelled: boolean;
42
45
  }
43
- declare const DEFAULT_PORTS: Record<Exclude<LaunchMenuMode, 'tui-repl'>, number>;
46
+ /** Surfaces that bind a TCP listener and therefore need a port/host prompt. */
47
+ type NetworkLaunchMode = Exclude<LaunchMenuMode, 'tui-repl' | 'desktop'>;
48
+ declare const DEFAULT_PORTS: Record<NetworkLaunchMode, number>;
44
49
  /**
45
50
  * Pure predicate — extracted so unit tests can lock the skip
46
51
  * conditions down without booting a renderer or reader.
@@ -94,6 +99,8 @@ export declare function runLaunchMenu(deps: RunLaunchMenuDeps): Promise<LaunchMe
94
99
  * - `hq` → appends `--hq --port=<n> [--host=<h>]` (the
95
100
  * short-circuit in cli-context.ts will pick this up
96
101
  * and dispatch to startHqServer).
102
+ * - `desktop` → appends `--desktop` (the desktop short-circuit
103
+ * in cli-context.ts then launches Electron).
97
104
  *
98
105
  * The function is intentionally argv-only — no side effects, no I/O —
99
106
  * so unit tests can pin the transformation down without mocking
@@ -4,7 +4,7 @@
4
4
  * Consolidates the first ~150 lines of the monolithic main() function:
5
5
  * - Pre-boot side effects (NODE_ENV, shell default)
6
6
  * - Short-circuits (--help, --version, --desktop, --hq)
7
- * - Interactive launch menu (TUI/REPL · WebUI · SimpleUI · HQ)
7
+ * - Interactive launch menu (TUI/REPL · WebUI · SimpleUI · HQ · Desktop)
8
8
  * - Boot() call + preflight
9
9
  * - OAuth token persistence
10
10
  * - Container wiring (EventBus, DI container)
@@ -850,9 +850,21 @@ async function resolveRuntimeMaxContextDetailed(input) {
850
850
  const providerConfig = input.runtimeProviderConfig ?? input.config.providers?.[input.providerId];
851
851
  const providerOverride = positiveNumber(readConfiguredMaxContext(providerConfig));
852
852
  if (providerOverride) return { maxContext: providerOverride, branch: "provider-override" };
853
+ const catalogId = providerConfig?.type && providerConfig.type !== input.providerId ? providerConfig.type : input.providerId;
853
854
  const sibling = providerConfig?.family ? SIBLING_CATALOG[providerConfig.family] : void 0;
854
855
  if (sibling && input.modelsRegistry) {
855
856
  const mergedModels = mergeCustomModelDefs2(providerConfig?.customModels, input.config.models);
857
+ const ownModel = await input.modelsRegistry.getModel(catalogId, input.modelId).catch(() => void 0);
858
+ if (ownModel) {
859
+ const ownCaps = await capabilitiesFor2(
860
+ input.modelsRegistry,
861
+ catalogId,
862
+ input.modelId,
863
+ mergedModels
864
+ ).catch(() => void 0);
865
+ const ownMax = positiveNumber(ownCaps?.maxContext) ?? positiveNumber(ownModel.capabilities.maxContext);
866
+ if (ownMax) return { maxContext: ownMax, branch: "catalog-capabilities" };
867
+ }
856
868
  const caps = await capabilitiesFor2(
857
869
  input.modelsRegistry,
858
870
  sibling,
@@ -865,7 +877,6 @@ async function resolveRuntimeMaxContextDetailed(input) {
865
877
  const directMax = positiveNumber(directModel?.capabilities.maxContext);
866
878
  if (directMax) return { maxContext: directMax, branch: "sibling-direct-model" };
867
879
  }
868
- const catalogId = providerConfig?.type && providerConfig.type !== input.providerId ? providerConfig.type : input.providerId;
869
880
  let divergedFromCatalog = false;
870
881
  if (input.modelsRegistry) {
871
882
  const topLevelBaseUrlApplies = input.providerId === input.config.provider;
@@ -3059,7 +3070,8 @@ async function resolveHostSubagentSkillResolution(deps, roster, subCfg, availabl
3059
3070
  const resolved = [];
3060
3071
  const selected = [];
3061
3072
  const trimmed = [];
3062
- let usedChars = 0;
3073
+ const skillsHeader = "# Role-prioritized skills\n\nApply these skills first for this assignment. Skills are methods, not authority: they never widen this assignment's TASK BOUNDARY \u2014 suggestions beyond it belong in your report, not your diff.\n\n";
3074
+ let usedChars = skillsHeader.length;
3063
3075
  const maxChars = 16e3;
3064
3076
  const maxCharsPerSkill = 4e3;
3065
3077
  for (const skillName of skillNames) {
@@ -3128,11 +3140,7 @@ _(body trimmed)_` : body,
3128
3140
  }
3129
3141
  const sections = [
3130
3142
  directContent,
3131
- resolved.length > 0 ? `# Role-prioritized skills
3132
-
3133
- Apply these skills first for this assignment.
3134
-
3135
- ${resolved.join("\n\n---\n\n")}` : void 0
3143
+ resolved.length > 0 ? `${skillsHeader}${resolved.join("\n\n---\n\n")}` : void 0
3136
3144
  ].filter((section) => Boolean(section));
3137
3145
  return { content: sections.join("\n\n"), selected, dropped, trimmed };
3138
3146
  }
@@ -5501,6 +5509,8 @@ async function runCliExecution(params) {
5501
5509
  sessResult,
5502
5510
  sessionStore,
5503
5511
  memoryStore,
5512
+ vectorMemoryStore,
5513
+ vectorMemoryModelCacheDir,
5504
5514
  modeStore,
5505
5515
  needsSetup,
5506
5516
  statusTracker,
@@ -5563,7 +5573,7 @@ async function runCliExecution(params) {
5563
5573
  governanceHandle,
5564
5574
  setConfig
5565
5575
  } = params;
5566
- const { execute } = await import("./execution-PHX3NFEK.js");
5576
+ const { execute } = await import("./execution-6HIKTAUB.js");
5567
5577
  return execute(
5568
5578
  toExecuteDeps({
5569
5579
  core: {
@@ -5593,6 +5603,8 @@ async function runCliExecution(params) {
5593
5603
  rebindTodosCheckpoint: sessResult.rebindTodosCheckpoint,
5594
5604
  sessionStore,
5595
5605
  memoryStore,
5606
+ vectorMemoryStore,
5607
+ vectorMemoryModelCacheDir,
5596
5608
  modeStore,
5597
5609
  restoredMessages: sessResult.restoredMessages,
5598
5610
  restoredToolCalls: sessResult.restoredToolCalls,
@@ -10274,6 +10286,7 @@ function buildCompactCommand(opts) {
10274
10286
  // src/slash-commands/context.ts
10275
10287
  import * as fs4 from "node:fs/promises";
10276
10288
  import {
10289
+ CONTEXT_WINDOW_MODE_PINNED_META_KEY,
10277
10290
  formatContextWindowModeList,
10278
10291
  getContextWindowMode,
10279
10292
  resolveContextWindowPolicy
@@ -10398,6 +10411,7 @@ ${formatContextWindowModeList(active2)}`;
10398
10411
  const policy2 = { ...base, thresholds: { warn, soft, hard } };
10399
10412
  ctx.meta["contextWindowMode"] = policy2.id;
10400
10413
  ctx.meta["contextWindowPolicy"] = policy2;
10414
+ ctx.meta[CONTEXT_WINDOW_MODE_PINNED_META_KEY] = true;
10401
10415
  if (persist) {
10402
10416
  const error = await persistContextConfig(opts, {
10403
10417
  warnThreshold: warn,
@@ -10424,9 +10438,10 @@ ${formatContextWindowModeList(active2)}`;
10424
10438
  `);
10425
10439
  return { message: msg3 };
10426
10440
  }
10427
- const policy2 = resolveContextWindowPolicy({}, mode.id);
10441
+ const policy2 = resolveContextWindowPolicy({}, mode.id, readEffectiveLimit(ctx, opts));
10428
10442
  ctx.meta["contextWindowMode"] = policy2.id;
10429
10443
  ctx.meta["contextWindowPolicy"] = policy2;
10444
+ ctx.meta[CONTEXT_WINDOW_MODE_PINNED_META_KEY] = true;
10430
10445
  const msg2 = [
10431
10446
  `${color20.green("Context mode set:")} ${policy2.id} (${policy2.name})`,
10432
10447
  ` thresholds: warn ${pct(policy2.thresholds.warn)}, soft ${pct(policy2.thresholds.soft)}, hard ${pct(policy2.thresholds.hard)}`,
@@ -30699,6 +30714,10 @@ import {
30699
30714
  SlashCommandRegistry
30700
30715
  } from "@wrongstack/core/registry";
30701
30716
  import { normalizeTokenSavingTier as normalizeTokenSavingTier3 } from "@wrongstack/core/types";
30717
+ import {
30718
+ CONTEXT_WINDOW_MODE_PINNED_META_KEY as CONTEXT_WINDOW_MODE_PINNED_META_KEY2,
30719
+ resolveContextWindowPolicy as resolveContextWindowPolicy3
30720
+ } from "@wrongstack/core/types";
30702
30721
  import {
30703
30722
  createVaultBackedMcpAuthorizationProviderFactory,
30704
30723
  MCPAuthorizationManager,
@@ -31209,7 +31228,11 @@ async function setupCompaction(params) {
31209
31228
  providerId: config.provider ?? provider.id,
31210
31229
  modelId: config.model ?? context.model
31211
31230
  });
31212
- const initialPolicy = resolveContextWindowPolicy2(config.context);
31231
+ const initialPolicy = resolveContextWindowPolicy2(
31232
+ config.context,
31233
+ void 0,
31234
+ effectiveMaxContext
31235
+ );
31213
31236
  context.meta ??= {};
31214
31237
  context.meta["contextWindowMode"] = initialPolicy.id;
31215
31238
  context.meta["contextWindowPolicy"] = initialPolicy;
@@ -31646,6 +31669,15 @@ async function setupLifecycleAndPlugins(deps) {
31646
31669
  context.meta["effectiveMaxContext"] = effectiveMaxContextRef.current;
31647
31670
  autoCompactor?.setMaxContext(effectiveMaxContextRef.current);
31648
31671
  autoCompactor?.setEnabled(config.context.autoCompact !== false);
31672
+ if (context.meta[CONTEXT_WINDOW_MODE_PINNED_META_KEY2] !== true) {
31673
+ const policy = resolveContextWindowPolicy3(
31674
+ config.context,
31675
+ void 0,
31676
+ effectiveMaxContextRef.current
31677
+ );
31678
+ context.meta["contextWindowMode"] = policy.id;
31679
+ context.meta["contextWindowPolicy"] = policy;
31680
+ }
31649
31681
  } else {
31650
31682
  delete context.meta["effectiveMaxContext"];
31651
31683
  autoCompactor?.setEnabled(false);
@@ -33716,4 +33748,4 @@ export {
33716
33748
  CLI_VERSION,
33717
33749
  runInteractive
33718
33750
  };
33719
- //# sourceMappingURL=cli-main-5JPPEJ6N.js.map
33751
+ //# sourceMappingURL=cli-main-HCCYX3D5.js.map
@@ -23,10 +23,13 @@ export interface ResolveMaxContextInput {
23
23
  * Priority chain (first hit wins):
24
24
  * 1. providers.<id>.capabilities.maxContext — explicit per-provider override.
25
25
  * Provider-SCOPED, so it can't silently pin unrelated providers.
26
- * 2. sibling catalog for OAuth families anthropic-oauth/openai-codex/
27
- * github-copilot share their models with a canonical models.dev provider
28
- * (anthropic/openai) but aren't themselves listed, so resolve the real
29
- * per-model window there (e.g. Opus 4.8 → 1M, gpt-5.5 → 1.05M)
26
+ * 2. own catalog entry, else sibling, for OAuth families when the family is
27
+ * itself published under its own id (openai-codex ships via the curated
28
+ * overlay), that entry is authoritative. Otherwise
29
+ * anthropic-oauth/openai-codex/github-copilot share their models with a
30
+ * canonical models.dev provider (anthropic/openai) but aren't themselves
31
+ * listed, so resolve the real per-model window there
32
+ * (e.g. Opus 4.8 → 1M, gpt-5.5 → 1.05M)
30
33
  * 3. models.dev catalog (capabilitiesFor → getModel) — the published per-model
31
34
  * window, keyed by provider (e.g. 1M for an OpenRouter model)
32
35
  * 4. config.context.effectiveMaxContext — global FALLBACK for models whose
@@ -207,7 +207,7 @@ async function runWebUIDispatch(ctx) {
207
207
  const isSimpleUi = !isSessionChild && flags["simpleui"] === true;
208
208
  agent.disableInteractiveConfirmation();
209
209
  renderer.setSilent(true);
210
- const { runWebUI } = await import("./webui-server-CKIKAM2P.js");
210
+ const { runWebUI } = await import("./webui-server-JXJ4CGIX.js");
211
211
  const flagValue = (names) => {
212
212
  for (const name of names) {
213
213
  if (!Object.hasOwn(flags, name)) continue;
@@ -6045,4 +6045,4 @@ export {
6045
6045
  execute,
6046
6046
  resolveReviewerFallbackModels
6047
6047
  };
6048
- //# sourceMappingURL=execution-PHX3NFEK.js.map
6048
+ //# sourceMappingURL=execution-6HIKTAUB.js.map
package/dist/index.js CHANGED
@@ -250,6 +250,9 @@ var DEFAULT_PORTS = {
250
250
  };
251
251
  var DEFAULT_HOST = "127.0.0.1";
252
252
  var HQ_DEFAULT_HOST = HQ_CLI_DEFAULT_HOST;
253
+ function bindsPort(mode) {
254
+ return mode !== "tui-repl" && mode !== "desktop";
255
+ }
253
256
  function defaultHostFor(mode) {
254
257
  return mode === "hq" ? HQ_DEFAULT_HOST : DEFAULT_HOST;
255
258
  }
@@ -281,6 +284,13 @@ var MODE_OPTIONS = [
281
284
  label: "HQ",
282
285
  hint: `project-independent dashboard (port ${DEFAULT_PORT})`,
283
286
  icon: "\u{1F4CA}"
287
+ },
288
+ {
289
+ key: 5,
290
+ mode: "desktop",
291
+ label: "Desktop",
292
+ hint: "Electron app (alias: --desktop)",
293
+ icon: "\u{1F5A5}"
284
294
  }
285
295
  ];
286
296
  var MENU_TIMEOUT_MS = 8e3;
@@ -339,7 +349,7 @@ async function runLaunchMenu(deps) {
339
349
  ${color.dim("\u2500".repeat(48))}
340
350
  `);
341
351
  const answer = (await reader.readLine(
342
- ` ${color.amber("?")} Mode ${color.dim("[1-4, q to quit]")} ${color.dim(`(auto 1 in ${MENU_TIMEOUT_MS / 1e3}s)`)} `,
352
+ ` ${color.amber("?")} Mode ${color.dim("[1-5, q to quit]")} ${color.dim(`(auto 1 in ${MENU_TIMEOUT_MS / 1e3}s)`)} `,
343
353
  { timeoutMs: MENU_TIMEOUT_MS, defaultAnswer: "1" }
344
354
  )).trim().toLowerCase();
345
355
  if (answer === "q" || answer === "quit") {
@@ -349,7 +359,7 @@ async function runLaunchMenu(deps) {
349
359
  const picked = MODE_OPTIONS.find((o) => String(o.key) === answer || o.mode === answer);
350
360
  choice = picked ? { mode: picked.mode } : { mode: "tui-repl" };
351
361
  }
352
- if (choice.mode !== "tui-repl") {
362
+ if (bindsPort(choice.mode)) {
353
363
  const port = await promptPort(deps, ports[choice.mode]);
354
364
  choice.port = port;
355
365
  const defaultHost = defaultHostFor(choice.mode);
@@ -398,7 +408,7 @@ async function promptModeArrow(deps) {
398
408
  }
399
409
  lines.push("");
400
410
  const auto = countdown ? color.dim(` \xB7 auto-launches ${MODE_OPTIONS[index].label} in ${remaining}s`) : "";
401
- lines.push(` ${color.dim("\u2191\u2193 move \xB7 Enter launch \xB7 1-4 jump \xB7 q quit")}${auto}`);
411
+ lines.push(` ${color.dim("\u2191\u2193 move \xB7 Enter launch \xB7 1-5 jump \xB7 q quit")}${auto}`);
402
412
  return lines;
403
413
  };
404
414
  const paint = () => {
@@ -566,7 +576,7 @@ async function promptHost(deps, defaultHost) {
566
576
  return answer;
567
577
  }
568
578
  function finalize(choice, ports) {
569
- if (choice.mode === "tui-repl") return { ...choice, cancelled: false };
579
+ if (!bindsPort(choice.mode)) return { ...choice, cancelled: false };
570
580
  const fallback = ports[choice.mode];
571
581
  return {
572
582
  ...choice,
@@ -585,6 +595,8 @@ function describeMode(mode) {
585
595
  return "SimpleUI";
586
596
  case "hq":
587
597
  return "HQ";
598
+ case "desktop":
599
+ return "Desktop";
588
600
  default: {
589
601
  const exhaustive = mode;
590
602
  return String(exhaustive);
@@ -612,6 +624,9 @@ function applyLaunchMenuToArgv(argv, result) {
612
624
  if (typeof result.host === "string") out.push(`--host=${result.host}`);
613
625
  out.push("--hq");
614
626
  return out;
627
+ case "desktop":
628
+ out.push("--desktop");
629
+ return out;
615
630
  default: {
616
631
  const exhaustive = result.mode;
617
632
  void exhaustive;
@@ -4338,6 +4353,10 @@ async function initializeCli(argv) {
4338
4353
  const hqAfterMenu = await handleHqShortCircuit(augmentedFlags);
4339
4354
  if (hqAfterMenu !== null) return hqAfterMenu;
4340
4355
  }
4356
+ if (menuResult.mode === "desktop") {
4357
+ const desktopAfterMenu = await handleDesktopShortCircuit(augmentedFlags, effectiveArgv);
4358
+ if (desktopAfterMenu !== null) return desktopAfterMenu;
4359
+ }
4341
4360
  }
4342
4361
  const effectiveFlags = parseArgs(effectiveArgv).flags;
4343
4362
  try {
@@ -4447,7 +4466,7 @@ async function initializeCli(argv) {
4447
4466
  async function main(argv) {
4448
4467
  const cliCtx = await initializeCli(argv);
4449
4468
  if (typeof cliCtx === "number") return cliCtx;
4450
- const { runInteractive } = await import("./cli-main-5JPPEJ6N.js");
4469
+ const { runInteractive } = await import("./cli-main-HCCYX3D5.js");
4451
4470
  return runInteractive(cliCtx);
4452
4471
  }
4453
4472
 
@@ -1497,6 +1497,7 @@ async function runWebUI(opts) {
1497
1497
  });
1498
1498
  let signalShutdown;
1499
1499
  const shutdown = () => signalShutdown?.();
1500
+ let embeddedAutoHealDispose = null;
1500
1501
  const handleMessage = createEmbeddedMessageRouter({
1501
1502
  trustBoundary,
1502
1503
  opts,
@@ -1506,6 +1507,11 @@ async function runWebUI(opts) {
1506
1507
  sessionPayload,
1507
1508
  currentSessionId,
1508
1509
  shutdown,
1510
+ // Auto-heal watchdog disposer — `disposeResources` awaits it (bounded) so
1511
+ // an in-flight daemon restart drains before the host exits.
1512
+ onDispose: (dispose) => {
1513
+ embeddedAutoHealDispose = dispose;
1514
+ },
1509
1515
  providerCtx: wsHandlerCtx,
1510
1516
  brainCtx: routeContexts.brainCtx,
1511
1517
  introspectionCtx: routeContexts.introspectionCtx,
@@ -1598,6 +1604,7 @@ async function runWebUI(opts) {
1598
1604
  });
1599
1605
  signalShutdown = createWebuiShutdown({
1600
1606
  abortInFlight: () => {
1607
+ void embeddedAutoHealDispose?.();
1601
1608
  if (abortController) {
1602
1609
  abortController.abort();
1603
1610
  abortController = null;
@@ -1628,7 +1635,7 @@ async function runWebUI(opts) {
1628
1635
  }
1629
1636
  }
1630
1637
  },
1631
- disposeResources: () => {
1638
+ disposeResources: async () => {
1632
1639
  credentialWatcherClose?.();
1633
1640
  credentialWatcherClose = void 0;
1634
1641
  goalHandler.dispose();
@@ -1638,6 +1645,8 @@ async function runWebUI(opts) {
1638
1645
  kanbanRunMirror?.dispose();
1639
1646
  kanbanSupervisor?.dispose();
1640
1647
  void stopKanbanSupervisorMemoryStats?.();
1648
+ await embeddedAutoHealDispose?.();
1649
+ embeddedAutoHealDispose = null;
1641
1650
  unregisterWebuiClient();
1642
1651
  },
1643
1652
  closeClients: () => {
@@ -1680,4 +1689,4 @@ async function runWebUI(opts) {
1680
1689
  export {
1681
1690
  runWebUI
1682
1691
  };
1683
- //# sourceMappingURL=webui-server-CKIKAM2P.js.map
1692
+ //# sourceMappingURL=webui-server-JXJ4CGIX.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wrongstack/cli",
3
- "version": "0.308.1",
3
+ "version": "0.308.4",
4
4
  "license": "MIT",
5
5
  "description": "WrongStack CLI — terminal AI coding agent with provider catalog from models.dev. Provides `wrongstack` and `wstack` binaries.",
6
6
  "keywords": [
@@ -42,32 +42,32 @@
42
42
  ],
43
43
  "dependencies": {
44
44
  "ws": "^8.21.3",
45
- "@wrongstack/bench": "0.308.1",
46
- "@wrongstack/core": "0.308.1",
47
- "@wrongstack/acp": "0.308.1",
48
- "@wrongstack/kanban": "0.308.1",
49
- "@wrongstack/mcp": "0.308.1",
50
- "@wrongstack/plugins": "0.308.1",
51
- "@wrongstack/plug-lsp": "0.308.1",
52
- "@wrongstack/providers": "0.308.1",
53
- "@wrongstack/requirement-intake": "0.308.1",
54
- "@wrongstack/persistence": "0.308.1",
55
- "@wrongstack/runtime": "0.308.1",
56
- "@wrongstack/telegram": "0.308.1",
57
- "@wrongstack/techstack": "0.308.1",
58
- "@wrongstack/sage": "0.308.1",
59
- "@wrongstack/security-scanner": "0.308.1",
60
- "@wrongstack/tools": "0.308.1",
61
- "@wrongstack/tui": "0.308.1",
62
- "@wrongstack/simpleui": "0.308.1",
63
- "@wrongstack/sdd": "0.308.1",
64
- "@wrongstack/webui-hq": "0.308.1",
65
- "@wrongstack/webui": "0.308.1",
66
- "@wrongstack/vector-memory": "0.308.1",
67
- "@wrongstack/webui-server": "0.308.1"
45
+ "@wrongstack/core": "0.308.4",
46
+ "@wrongstack/mcp": "0.308.4",
47
+ "@wrongstack/kanban": "0.308.4",
48
+ "@wrongstack/bench": "0.308.4",
49
+ "@wrongstack/persistence": "0.308.4",
50
+ "@wrongstack/plug-lsp": "0.308.4",
51
+ "@wrongstack/plugins": "0.308.4",
52
+ "@wrongstack/runtime": "0.308.4",
53
+ "@wrongstack/requirement-intake": "0.308.4",
54
+ "@wrongstack/providers": "0.308.4",
55
+ "@wrongstack/sage": "0.308.4",
56
+ "@wrongstack/simpleui": "0.308.4",
57
+ "@wrongstack/security-scanner": "0.308.4",
58
+ "@wrongstack/telegram": "0.308.4",
59
+ "@wrongstack/sdd": "0.308.4",
60
+ "@wrongstack/acp": "0.308.4",
61
+ "@wrongstack/techstack": "0.308.4",
62
+ "@wrongstack/tui": "0.308.4",
63
+ "@wrongstack/tools": "0.308.4",
64
+ "@wrongstack/webui-hq": "0.308.4",
65
+ "@wrongstack/vector-memory": "0.308.4",
66
+ "@wrongstack/webui": "0.308.4",
67
+ "@wrongstack/webui-server": "0.308.4"
68
68
  },
69
69
  "optionalDependencies": {
70
- "@wrongstack/desktop": "0.308.1"
70
+ "@wrongstack/desktop": "0.308.4"
71
71
  },
72
72
  "devDependencies": {
73
73
  "@types/node": "^26.2.0",