@wrongstack/webui-server 0.308.7 → 0.309.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
@@ -8983,7 +8983,7 @@ function verifyClient(input) {
8983
8983
 
8984
8984
  // src/server/http-server/api-router.ts
8985
8985
  import * as v8 from "node:v8";
8986
- import { sanitizeApiError as sanitizeApiError3 } from "@wrongstack/core/security";
8986
+ import { sanitizeApiError as sanitizeApiError4 } from "@wrongstack/core/security";
8987
8987
  import { getIndexState as getIndexState2 } from "@wrongstack/tools";
8988
8988
 
8989
8989
  // src/server/codemap-handlers.ts
@@ -9589,6 +9589,7 @@ async function handleRequirementIntakeArchive(res, service, intakeId) {
9589
9589
 
9590
9590
  // src/server/techstack-handlers.ts
9591
9591
  import { randomUUID as randomUUID3 } from "node:crypto";
9592
+ import { sanitizeApiError } from "@wrongstack/core/security";
9592
9593
  var DEEP_DIVE_TIMEOUT_MS = 6e4;
9593
9594
  function sendJson3(res, status, data) {
9594
9595
  res.writeHead(status, { "Content-Type": "application/json" });
@@ -9618,7 +9619,7 @@ function handleTechStackSnapshot(res, deps2) {
9618
9619
  }
9619
9620
  }
9620
9621
  function errorMessage(error2) {
9621
- return error2 instanceof Error ? error2.message : String(error2);
9622
+ return sanitizeApiError(error2);
9622
9623
  }
9623
9624
  function requireJobDeps(res, deps2) {
9624
9625
  if (!deps2.projectRoot || !deps2.engine) {
@@ -9819,7 +9820,7 @@ async function handleTechStackRemediationApply(req, res, deps2) {
9819
9820
  }
9820
9821
 
9821
9822
  // src/server/http-server/api-handlers.ts
9822
- import { sanitizeApiError } from "@wrongstack/core/security";
9823
+ import { sanitizeApiError as sanitizeApiError2 } from "@wrongstack/core/security";
9823
9824
  async function handleApiSessions(res, globalRoot) {
9824
9825
  if (!globalRoot) {
9825
9826
  res.writeHead(500, { "Content-Type": "application/json" });
@@ -9855,7 +9856,7 @@ async function handleApiSessions(res, globalRoot) {
9855
9856
  res.end(JSON.stringify(result));
9856
9857
  } catch (err) {
9857
9858
  res.writeHead(500, { "Content-Type": "application/json" });
9858
- res.end(JSON.stringify({ error: sanitizeApiError(err) }));
9859
+ res.end(JSON.stringify({ error: sanitizeApiError2(err) }));
9859
9860
  }
9860
9861
  }
9861
9862
  async function handleApiSessionAgents(res, globalRoot, sessionId) {
@@ -9892,7 +9893,7 @@ async function handleApiSessionAgents(res, globalRoot, sessionId) {
9892
9893
  );
9893
9894
  } catch (err) {
9894
9895
  res.writeHead(500, { "Content-Type": "application/json" });
9895
- res.end(JSON.stringify({ error: sanitizeApiError(err) }));
9896
+ res.end(JSON.stringify({ error: sanitizeApiError2(err) }));
9896
9897
  }
9897
9898
  }
9898
9899
  function blocksToText(content) {
@@ -10056,7 +10057,7 @@ async function handleApiSessionEvents(res, globalRoot, sessionId, limit) {
10056
10057
  );
10057
10058
  } catch (err) {
10058
10059
  res.writeHead(500, { "Content-Type": "application/json" });
10059
- res.end(JSON.stringify({ error: sanitizeApiError(err) }));
10060
+ res.end(JSON.stringify({ error: sanitizeApiError2(err) }));
10060
10061
  }
10061
10062
  }
10062
10063
  function readJsonBody3(req) {
@@ -10130,7 +10131,7 @@ async function handleApiSessionMessage(res, req, globalRoot, sessionId) {
10130
10131
  res.end(JSON.stringify({ ok: true, id: sent.id, to, type, delivered: entry.status }));
10131
10132
  } catch (err) {
10132
10133
  res.writeHead(500, { "Content-Type": "application/json" });
10133
- res.end(JSON.stringify({ error: sanitizeApiError(err) }));
10134
+ res.end(JSON.stringify({ error: sanitizeApiError2(err) }));
10134
10135
  }
10135
10136
  }
10136
10137
  async function handleApiSessionMailbox(res, globalRoot, sessionId) {
@@ -10183,7 +10184,7 @@ async function handleApiSessionMailbox(res, globalRoot, sessionId) {
10183
10184
  res.end(JSON.stringify({ sessionId, leader: leaderAddr, status: entry.status, thread }));
10184
10185
  } catch (err) {
10185
10186
  res.writeHead(500, { "Content-Type": "application/json" });
10186
- res.end(JSON.stringify({ error: sanitizeApiError(err) }));
10187
+ res.end(JSON.stringify({ error: sanitizeApiError2(err) }));
10187
10188
  }
10188
10189
  }
10189
10190
  async function handleApiSessionInterrupt(res, req, globalRoot, sessionId) {
@@ -10224,7 +10225,7 @@ async function handleApiSessionInterrupt(res, req, globalRoot, sessionId) {
10224
10225
  res.end(JSON.stringify({ ok: true, id: sent.id, to, delivered: entry.status }));
10225
10226
  } catch (err) {
10226
10227
  res.writeHead(500, { "Content-Type": "application/json" });
10227
- res.end(JSON.stringify({ error: sanitizeApiError(err) }));
10228
+ res.end(JSON.stringify({ error: sanitizeApiError2(err) }));
10228
10229
  }
10229
10230
  }
10230
10231
  async function handleApiFleetBroadcast(res, req, globalRoot) {
@@ -10293,7 +10294,7 @@ async function handleApiFleetBroadcast(res, req, globalRoot) {
10293
10294
  res.end(JSON.stringify({ ok: true, delivered, targets: targets.length }));
10294
10295
  } catch (err) {
10295
10296
  res.writeHead(500, { "Content-Type": "application/json" });
10296
- res.end(JSON.stringify({ error: sanitizeApiError(err) }));
10297
+ res.end(JSON.stringify({ error: sanitizeApiError2(err) }));
10297
10298
  }
10298
10299
  }
10299
10300
 
@@ -10412,7 +10413,7 @@ function strictDecodeParam(segment, res) {
10412
10413
 
10413
10414
  // src/server/http-server/vector-memory-handlers.ts
10414
10415
  import { getSageSurface } from "@wrongstack/sage";
10415
- import { sanitizeApiError as sanitizeApiError2 } from "@wrongstack/core/security";
10416
+ import { sanitizeApiError as sanitizeApiError3 } from "@wrongstack/core/security";
10416
10417
  function snapshotVectorMemory(store, opts = {}) {
10417
10418
  const stats = store.stats();
10418
10419
  return {
@@ -10453,7 +10454,7 @@ async function handleVectorMemoryStatus(res, getStore, opts = {}) {
10453
10454
  res.end(
10454
10455
  JSON.stringify({
10455
10456
  error: "Vector memory status failed",
10456
- detail: sanitizeApiError2(error2)
10457
+ detail: sanitizeApiError3(error2)
10457
10458
  })
10458
10459
  );
10459
10460
  }
@@ -10530,7 +10531,7 @@ async function handleVectorMemorySearch(res, url, getStore) {
10530
10531
  res.end(
10531
10532
  JSON.stringify({
10532
10533
  error: "Vector memory search failed",
10533
- detail: sanitizeApiError2(error2)
10534
+ detail: sanitizeApiError3(error2)
10534
10535
  })
10535
10536
  );
10536
10537
  }
@@ -10591,7 +10592,7 @@ async function handleVectorMemoryStore(res, req, getStore) {
10591
10592
  res.end(
10592
10593
  JSON.stringify({
10593
10594
  error: "Vector memory store failed",
10594
- detail: sanitizeApiError2(error2)
10595
+ detail: sanitizeApiError3(error2)
10595
10596
  })
10596
10597
  );
10597
10598
  }
@@ -10615,7 +10616,7 @@ async function handleVectorMemoryForget(res, url, getStore) {
10615
10616
  res.end(
10616
10617
  JSON.stringify({
10617
10618
  error: "Vector memory forget failed",
10618
- detail: sanitizeApiError2(error2)
10619
+ detail: sanitizeApiError3(error2)
10619
10620
  })
10620
10621
  );
10621
10622
  }
@@ -10695,7 +10696,7 @@ async function handleMemorySearch(res, url, getStore) {
10695
10696
  res.end(
10696
10697
  JSON.stringify({
10697
10698
  error: "Memory search failed",
10698
- detail: sanitizeApiError2(error2)
10699
+ detail: sanitizeApiError3(error2)
10699
10700
  })
10700
10701
  );
10701
10702
  }
@@ -11039,7 +11040,7 @@ async function handleApiRoutes(req, res, url, deps2, requireAccessToken, accessT
11039
11040
  res.end(
11040
11041
  JSON.stringify({
11041
11042
  error: "TechStack store unavailable",
11042
- detail: sanitizeApiError3(error2)
11043
+ detail: sanitizeApiError4(error2)
11043
11044
  })
11044
11045
  );
11045
11046
  return true;
@@ -15173,6 +15174,16 @@ function createModelOperations(context) {
15173
15174
 
15174
15175
  // src/server/open-browser.ts
15175
15176
  import { spawn } from "node:child_process";
15177
+ var URL_METACHAR_REGEX = /[&|;<>(){}^"'`%\n\r\0]/;
15178
+ function isSafeBrowserUrl(url) {
15179
+ if (URL_METACHAR_REGEX.test(url)) return false;
15180
+ try {
15181
+ const parsed = new URL(url);
15182
+ return parsed.protocol === "http:" || parsed.protocol === "https:";
15183
+ } catch {
15184
+ return false;
15185
+ }
15186
+ }
15176
15187
  function browserOpenCommand(url, platform = process.platform) {
15177
15188
  if (platform === "win32") {
15178
15189
  return { command: "cmd", args: ["/c", "start", "", url] };
@@ -15183,6 +15194,16 @@ function browserOpenCommand(url, platform = process.platform) {
15183
15194
  return { command: "xdg-open", args: [url] };
15184
15195
  }
15185
15196
  function openBrowser(url, platform = process.platform) {
15197
+ if (!isSafeBrowserUrl(url)) {
15198
+ console.warn(
15199
+ JSON.stringify({
15200
+ level: "warn",
15201
+ event: "open_browser.refused",
15202
+ message: "Refusing to open a URL with an unexpected scheme or shell metacharacter"
15203
+ })
15204
+ );
15205
+ return;
15206
+ }
15186
15207
  try {
15187
15208
  const { command, args } = browserOpenCommand(url, platform);
15188
15209
  const child = spawn(command, args, { stdio: "ignore", detached: true, windowsHide: true });
@@ -24786,6 +24807,14 @@ function setupEvents(deps2) {
24786
24807
  // src/server/specs-ws-handler.ts
24787
24808
  import { computeTaskProgress } from "@wrongstack/core/tasking";
24788
24809
  import { SpecStore as SpecStore2, TaskGraphStore as TaskGraphStore2 } from "@wrongstack/sdd";
24810
+ var VALID_TASK_STATUSES = /* @__PURE__ */ new Set([
24811
+ "pending",
24812
+ "in_progress",
24813
+ "blocked",
24814
+ "failed",
24815
+ "review",
24816
+ "completed"
24817
+ ]);
24789
24818
  var SpecsWebSocketHandler = class {
24790
24819
  specStore;
24791
24820
  graphStore;
@@ -24824,6 +24853,12 @@ var SpecsWebSocketHandler = class {
24824
24853
  }
24825
24854
  case "specs.taskStatus": {
24826
24855
  const { graphId, taskId, status } = msg.payload;
24856
+ if (!VALID_TASK_STATUSES.has(status)) {
24857
+ throw new Error(`Invalid task status: ${JSON.stringify(status)}`);
24858
+ }
24859
+ if (typeof graphId !== "string" || typeof taskId !== "string") {
24860
+ throw new Error("specs.taskStatus requires string graphId and taskId");
24861
+ }
24827
24862
  await this.updateTaskStatus(graphId, taskId, status);
24828
24863
  break;
24829
24864
  }
@@ -27983,6 +28018,7 @@ function createSessionStartPayload(g) {
27983
28018
  let inputCost = 0;
27984
28019
  let outputCost = 0;
27985
28020
  let cacheReadCost = 0;
28021
+ let reasoningEffortLevels;
27986
28022
  try {
27987
28023
  const m = await resolveProviderModelMetadata(
27988
28024
  g.modelsRegistry,
@@ -27991,6 +28027,10 @@ function createSessionStartPayload(g) {
27991
28027
  config.providers?.[config.provider]
27992
28028
  );
27993
28029
  maxContext = m?.capabilities?.maxContext ?? 0;
28030
+ const rc = m?.capabilities.reasoningConfig;
28031
+ if (rc?.effortSupported && rc.effortLevels?.length) {
28032
+ reasoningEffortLevels = rc.effortLevels;
28033
+ }
27994
28034
  if (!maxContext) {
27995
28035
  try {
27996
28036
  const provider = await g.modelsRegistry.getProvider(config.provider);
@@ -28021,6 +28061,7 @@ function createSessionStartPayload(g) {
28021
28061
  contextMode: g.getContextMode(),
28022
28062
  ...protocolAdvertisement()
28023
28063
  };
28064
+ if (reasoningEffortLevels) result.reasoningEffortLevels = reasoningEffortLevels;
28024
28065
  if (g.getNeedsSetup()) result.needsSetup = true;
28025
28066
  return result;
28026
28067
  };
@@ -8889,7 +8889,7 @@ function verifyClient(input) {
8889
8889
 
8890
8890
  // src/server/http-server/api-router.ts
8891
8891
  import * as v8 from "node:v8";
8892
- import { sanitizeApiError as sanitizeApiError3 } from "@wrongstack/core/security";
8892
+ import { sanitizeApiError as sanitizeApiError4 } from "@wrongstack/core/security";
8893
8893
  import { getIndexState as getIndexState2 } from "@wrongstack/tools";
8894
8894
 
8895
8895
  // src/server/codemap-handlers.ts
@@ -9495,6 +9495,7 @@ async function handleRequirementIntakeArchive(res, service, intakeId) {
9495
9495
 
9496
9496
  // src/server/techstack-handlers.ts
9497
9497
  import { randomUUID as randomUUID3 } from "node:crypto";
9498
+ import { sanitizeApiError } from "@wrongstack/core/security";
9498
9499
  var DEEP_DIVE_TIMEOUT_MS = 6e4;
9499
9500
  function sendJson3(res, status, data) {
9500
9501
  res.writeHead(status, { "Content-Type": "application/json" });
@@ -9524,7 +9525,7 @@ function handleTechStackSnapshot(res, deps2) {
9524
9525
  }
9525
9526
  }
9526
9527
  function errorMessage(error2) {
9527
- return error2 instanceof Error ? error2.message : String(error2);
9528
+ return sanitizeApiError(error2);
9528
9529
  }
9529
9530
  function requireJobDeps(res, deps2) {
9530
9531
  if (!deps2.projectRoot || !deps2.engine) {
@@ -9725,7 +9726,7 @@ async function handleTechStackRemediationApply(req, res, deps2) {
9725
9726
  }
9726
9727
 
9727
9728
  // src/server/http-server/api-handlers.ts
9728
- import { sanitizeApiError } from "@wrongstack/core/security";
9729
+ import { sanitizeApiError as sanitizeApiError2 } from "@wrongstack/core/security";
9729
9730
  async function handleApiSessions(res, globalRoot) {
9730
9731
  if (!globalRoot) {
9731
9732
  res.writeHead(500, { "Content-Type": "application/json" });
@@ -9761,7 +9762,7 @@ async function handleApiSessions(res, globalRoot) {
9761
9762
  res.end(JSON.stringify(result));
9762
9763
  } catch (err) {
9763
9764
  res.writeHead(500, { "Content-Type": "application/json" });
9764
- res.end(JSON.stringify({ error: sanitizeApiError(err) }));
9765
+ res.end(JSON.stringify({ error: sanitizeApiError2(err) }));
9765
9766
  }
9766
9767
  }
9767
9768
  async function handleApiSessionAgents(res, globalRoot, sessionId) {
@@ -9798,7 +9799,7 @@ async function handleApiSessionAgents(res, globalRoot, sessionId) {
9798
9799
  );
9799
9800
  } catch (err) {
9800
9801
  res.writeHead(500, { "Content-Type": "application/json" });
9801
- res.end(JSON.stringify({ error: sanitizeApiError(err) }));
9802
+ res.end(JSON.stringify({ error: sanitizeApiError2(err) }));
9802
9803
  }
9803
9804
  }
9804
9805
  function blocksToText(content) {
@@ -9962,7 +9963,7 @@ async function handleApiSessionEvents(res, globalRoot, sessionId, limit) {
9962
9963
  );
9963
9964
  } catch (err) {
9964
9965
  res.writeHead(500, { "Content-Type": "application/json" });
9965
- res.end(JSON.stringify({ error: sanitizeApiError(err) }));
9966
+ res.end(JSON.stringify({ error: sanitizeApiError2(err) }));
9966
9967
  }
9967
9968
  }
9968
9969
  function readJsonBody3(req) {
@@ -10036,7 +10037,7 @@ async function handleApiSessionMessage(res, req, globalRoot, sessionId) {
10036
10037
  res.end(JSON.stringify({ ok: true, id: sent.id, to, type, delivered: entry.status }));
10037
10038
  } catch (err) {
10038
10039
  res.writeHead(500, { "Content-Type": "application/json" });
10039
- res.end(JSON.stringify({ error: sanitizeApiError(err) }));
10040
+ res.end(JSON.stringify({ error: sanitizeApiError2(err) }));
10040
10041
  }
10041
10042
  }
10042
10043
  async function handleApiSessionMailbox(res, globalRoot, sessionId) {
@@ -10089,7 +10090,7 @@ async function handleApiSessionMailbox(res, globalRoot, sessionId) {
10089
10090
  res.end(JSON.stringify({ sessionId, leader: leaderAddr, status: entry.status, thread }));
10090
10091
  } catch (err) {
10091
10092
  res.writeHead(500, { "Content-Type": "application/json" });
10092
- res.end(JSON.stringify({ error: sanitizeApiError(err) }));
10093
+ res.end(JSON.stringify({ error: sanitizeApiError2(err) }));
10093
10094
  }
10094
10095
  }
10095
10096
  async function handleApiSessionInterrupt(res, req, globalRoot, sessionId) {
@@ -10130,7 +10131,7 @@ async function handleApiSessionInterrupt(res, req, globalRoot, sessionId) {
10130
10131
  res.end(JSON.stringify({ ok: true, id: sent.id, to, delivered: entry.status }));
10131
10132
  } catch (err) {
10132
10133
  res.writeHead(500, { "Content-Type": "application/json" });
10133
- res.end(JSON.stringify({ error: sanitizeApiError(err) }));
10134
+ res.end(JSON.stringify({ error: sanitizeApiError2(err) }));
10134
10135
  }
10135
10136
  }
10136
10137
  async function handleApiFleetBroadcast(res, req, globalRoot) {
@@ -10199,7 +10200,7 @@ async function handleApiFleetBroadcast(res, req, globalRoot) {
10199
10200
  res.end(JSON.stringify({ ok: true, delivered, targets: targets.length }));
10200
10201
  } catch (err) {
10201
10202
  res.writeHead(500, { "Content-Type": "application/json" });
10202
- res.end(JSON.stringify({ error: sanitizeApiError(err) }));
10203
+ res.end(JSON.stringify({ error: sanitizeApiError2(err) }));
10203
10204
  }
10204
10205
  }
10205
10206
 
@@ -10318,7 +10319,7 @@ function strictDecodeParam(segment, res) {
10318
10319
 
10319
10320
  // src/server/http-server/vector-memory-handlers.ts
10320
10321
  import { getSageSurface } from "@wrongstack/sage";
10321
- import { sanitizeApiError as sanitizeApiError2 } from "@wrongstack/core/security";
10322
+ import { sanitizeApiError as sanitizeApiError3 } from "@wrongstack/core/security";
10322
10323
  function snapshotVectorMemory(store, opts = {}) {
10323
10324
  const stats = store.stats();
10324
10325
  return {
@@ -10359,7 +10360,7 @@ async function handleVectorMemoryStatus(res, getStore, opts = {}) {
10359
10360
  res.end(
10360
10361
  JSON.stringify({
10361
10362
  error: "Vector memory status failed",
10362
- detail: sanitizeApiError2(error2)
10363
+ detail: sanitizeApiError3(error2)
10363
10364
  })
10364
10365
  );
10365
10366
  }
@@ -10436,7 +10437,7 @@ async function handleVectorMemorySearch(res, url, getStore) {
10436
10437
  res.end(
10437
10438
  JSON.stringify({
10438
10439
  error: "Vector memory search failed",
10439
- detail: sanitizeApiError2(error2)
10440
+ detail: sanitizeApiError3(error2)
10440
10441
  })
10441
10442
  );
10442
10443
  }
@@ -10497,7 +10498,7 @@ async function handleVectorMemoryStore(res, req, getStore) {
10497
10498
  res.end(
10498
10499
  JSON.stringify({
10499
10500
  error: "Vector memory store failed",
10500
- detail: sanitizeApiError2(error2)
10501
+ detail: sanitizeApiError3(error2)
10501
10502
  })
10502
10503
  );
10503
10504
  }
@@ -10521,7 +10522,7 @@ async function handleVectorMemoryForget(res, url, getStore) {
10521
10522
  res.end(
10522
10523
  JSON.stringify({
10523
10524
  error: "Vector memory forget failed",
10524
- detail: sanitizeApiError2(error2)
10525
+ detail: sanitizeApiError3(error2)
10525
10526
  })
10526
10527
  );
10527
10528
  }
@@ -10601,7 +10602,7 @@ async function handleMemorySearch(res, url, getStore) {
10601
10602
  res.end(
10602
10603
  JSON.stringify({
10603
10604
  error: "Memory search failed",
10604
- detail: sanitizeApiError2(error2)
10605
+ detail: sanitizeApiError3(error2)
10605
10606
  })
10606
10607
  );
10607
10608
  }
@@ -10945,7 +10946,7 @@ async function handleApiRoutes(req, res, url, deps2, requireAccessToken, accessT
10945
10946
  res.end(
10946
10947
  JSON.stringify({
10947
10948
  error: "TechStack store unavailable",
10948
- detail: sanitizeApiError3(error2)
10949
+ detail: sanitizeApiError4(error2)
10949
10950
  })
10950
10951
  );
10951
10952
  return true;
@@ -22638,6 +22639,14 @@ function setupEvents(deps2) {
22638
22639
  // src/server/specs-ws-handler.ts
22639
22640
  import { computeTaskProgress } from "@wrongstack/core/tasking";
22640
22641
  import { SpecStore as SpecStore2, TaskGraphStore as TaskGraphStore2 } from "@wrongstack/sdd";
22642
+ var VALID_TASK_STATUSES = /* @__PURE__ */ new Set([
22643
+ "pending",
22644
+ "in_progress",
22645
+ "blocked",
22646
+ "failed",
22647
+ "review",
22648
+ "completed"
22649
+ ]);
22641
22650
  var SpecsWebSocketHandler = class {
22642
22651
  specStore;
22643
22652
  graphStore;
@@ -22676,6 +22685,12 @@ var SpecsWebSocketHandler = class {
22676
22685
  }
22677
22686
  case "specs.taskStatus": {
22678
22687
  const { graphId, taskId, status } = msg.payload;
22688
+ if (!VALID_TASK_STATUSES.has(status)) {
22689
+ throw new Error(`Invalid task status: ${JSON.stringify(status)}`);
22690
+ }
22691
+ if (typeof graphId !== "string" || typeof taskId !== "string") {
22692
+ throw new Error("specs.taskStatus requires string graphId and taskId");
22693
+ }
22679
22694
  await this.updateTaskStatus(graphId, taskId, status);
22680
22695
  break;
22681
22696
  }
@@ -25835,6 +25850,7 @@ function createSessionStartPayload(g) {
25835
25850
  let inputCost = 0;
25836
25851
  let outputCost = 0;
25837
25852
  let cacheReadCost = 0;
25853
+ let reasoningEffortLevels;
25838
25854
  try {
25839
25855
  const m = await resolveProviderModelMetadata(
25840
25856
  g.modelsRegistry,
@@ -25843,6 +25859,10 @@ function createSessionStartPayload(g) {
25843
25859
  config.providers?.[config.provider]
25844
25860
  );
25845
25861
  maxContext = m?.capabilities?.maxContext ?? 0;
25862
+ const rc = m?.capabilities.reasoningConfig;
25863
+ if (rc?.effortSupported && rc.effortLevels?.length) {
25864
+ reasoningEffortLevels = rc.effortLevels;
25865
+ }
25846
25866
  if (!maxContext) {
25847
25867
  try {
25848
25868
  const provider = await g.modelsRegistry.getProvider(config.provider);
@@ -25873,6 +25893,7 @@ function createSessionStartPayload(g) {
25873
25893
  contextMode: g.getContextMode(),
25874
25894
  ...protocolAdvertisement()
25875
25895
  };
25896
+ if (reasoningEffortLevels) result.reasoningEffortLevels = reasoningEffortLevels;
25876
25897
  if (g.getNeedsSetup()) result.needsSetup = true;
25877
25898
  return result;
25878
25899
  };
@@ -5,6 +5,15 @@
5
5
  * fire-and-forget: a missing opener, a headless box, or a spawn failure must
6
6
  * NEVER take the server down — the URL is always also printed to the console.
7
7
  */
8
+ /**
9
+ * True when `url` is safe to hand to an OS opener.
10
+ *
11
+ * Scheme is checked as well as metacharacters: an opener will happily launch
12
+ * `file:`, `ms-msdt:` or a UNC path, and this function's callers include one
13
+ * (`github-copilot-oauth.ts`) whose URL comes from an HTTP response body rather
14
+ * than from our own code.
15
+ */
16
+ export declare function isSafeBrowserUrl(url: string): boolean;
8
17
  /** Resolve the platform's URL-opener command + args. */
9
18
  export declare function browserOpenCommand(url: string, platform?: NodeJS.Platform): {
10
19
  command: string;
@@ -68,6 +68,7 @@ export declare function createSessionStartPayload(g: SessionStartPayloadGetters)
68
68
  protocolVersion: number;
69
69
  protocolCapabilities: string[];
70
70
  needsSetup?: boolean | undefined;
71
+ reasoningEffortLevels?: string[] | undefined;
71
72
  }>;
72
73
  interface WsServerResult {
73
74
  wssPrimary: WebSocketServer;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wrongstack/webui-server",
3
- "version": "0.308.7",
3
+ "version": "0.309.1",
4
4
  "license": "MIT",
5
5
  "description": "WrongStack WebUI HTTP/WebSocket server module — extracted from @wrongstack/webui in PR #243/244 to remove the CLI -> @wrongstack/webui/server cross-package edge (audit §3.1.1). Pure backend: HTTP routes, WebSocket handlers, MCP tool wrappers, HTML serving. The web frontend lives in @wrongstack/webui; this package is the standalone server it can run on.",
6
6
  "keywords": [
@@ -40,17 +40,17 @@
40
40
  ],
41
41
  "dependencies": {
42
42
  "ws": "^8.21.3",
43
- "@wrongstack/mcp": "0.308.7",
44
- "@wrongstack/providers": "0.308.7",
45
- "@wrongstack/core": "0.308.7",
46
- "@wrongstack/kanban": "0.308.7",
47
- "@wrongstack/requirement-intake": "0.308.7",
48
- "@wrongstack/sage": "0.308.7",
49
- "@wrongstack/sdd": "0.308.7",
50
- "@wrongstack/runtime": "0.308.7",
51
- "@wrongstack/tools": "0.308.7",
52
- "@wrongstack/techstack": "0.308.7",
53
- "@wrongstack/vector-memory": "0.308.7"
43
+ "@wrongstack/mcp": "0.309.1",
44
+ "@wrongstack/core": "0.309.1",
45
+ "@wrongstack/runtime": "0.309.1",
46
+ "@wrongstack/providers": "0.309.1",
47
+ "@wrongstack/requirement-intake": "0.309.1",
48
+ "@wrongstack/kanban": "0.309.1",
49
+ "@wrongstack/sage": "0.309.1",
50
+ "@wrongstack/sdd": "0.309.1",
51
+ "@wrongstack/vector-memory": "0.309.1",
52
+ "@wrongstack/tools": "0.309.1",
53
+ "@wrongstack/techstack": "0.309.1"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@types/node": "^26.2.0",