@wrongstack/webui 0.282.0 → 0.282.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.
Files changed (25) hide show
  1. package/dist/assets/{AnalyticsDashboard-BrQc2ss-.js → AnalyticsDashboard-TCNC-sVb.js} +1 -1
  2. package/dist/assets/{AutoPhaseView-8NTdnZ0a.js → AutoPhaseView-BMUiT6aI.js} +1 -1
  3. package/dist/assets/{CodeEditor-C-pJLtUR.js → CodeEditor-C0si742k.js} +1 -1
  4. package/dist/assets/{DesignGalleryView-M6Hp7s9b.js → DesignGalleryView-BfZTw48N.js} +1 -1
  5. package/dist/assets/{KanbanView-nMv98m0N.js → KanbanView-C4T4y0b7.js} +1 -1
  6. package/dist/assets/{MailboxDetailView-g3IQx4DB.js → MailboxDetailView-DJtjP0NF.js} +1 -1
  7. package/dist/assets/{OfficeMapPanel-D3VE7UCd.js → OfficeMapPanel-CgvHvGQm.js} +1 -1
  8. package/dist/assets/{ProcessMonitor-CbfQYneY.js → ProcessMonitor-D53zn0h4.js} +1 -1
  9. package/dist/assets/{QueuePanel-eGK1SSKx.js → QueuePanel-DTO68vaB.js} +1 -1
  10. package/dist/assets/{SddBoardView-DvuH4f4e.js → SddBoardView-C8X4MiTy.js} +1 -1
  11. package/dist/assets/{SddWizard-G55Yw9Bb.js → SddWizard-t5Cly3CG.js} +1 -1
  12. package/dist/assets/{SkillDetailView-CX9zeWBG.js → SkillDetailView-Dq-fTqSp.js} +1 -1
  13. package/dist/assets/{SpecsView-BnUsqkrG.js → SpecsView-Cwd6PiYr.js} +1 -1
  14. package/dist/assets/{TerminalPanel-BCpddej2.js → TerminalPanel-Bzyhr2aC.js} +1 -1
  15. package/dist/assets/index-CWj2bI87.js +145 -0
  16. package/dist/index.html +1 -1
  17. package/dist/index.js +128 -58
  18. package/dist/index.js.map +1 -1
  19. package/dist/providers.json +2 -2
  20. package/dist/server/entry.js +300 -11
  21. package/dist/server/entry.js.map +1 -1
  22. package/dist/server/index.js +300 -11
  23. package/dist/server/index.js.map +1 -1
  24. package/package.json +6 -6
  25. package/dist/assets/index-BhO3caLf.js +0 -146
package/dist/index.html CHANGED
@@ -5,7 +5,7 @@
5
5
  <link rel="icon" type="image/svg+xml" href="/wrongstack.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>WrongStack WebUI</title>
8
- <script type="module" crossorigin src="/assets/index-BhO3caLf.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-CWj2bI87.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-QTnfLwEv.js">
10
10
  <link rel="modulepreload" crossorigin href="/assets/markdown-D0X23O-i.js">
11
11
  <link rel="modulepreload" crossorigin href="/assets/vendor-Ch4m_qLI.js">
package/dist/index.js CHANGED
@@ -19143,8 +19143,8 @@ var init_config_store = __esm({
19143
19143
  useConfigStore = create6()(
19144
19144
  persist4(
19145
19145
  (set) => ({
19146
- provider: "anthropic",
19147
- model: "claude-sonnet-4-20250514",
19146
+ provider: "",
19147
+ model: "",
19148
19148
  wsUrl: defaultWsUrl(),
19149
19149
  wsConnected: false,
19150
19150
  wsStatus: { state: "connecting" },
@@ -19678,8 +19678,8 @@ var init_file_store = __esm({
19678
19678
  import { ArrowRight, Lightbulb, MousePointerClick, Timer } from "lucide-react";
19679
19679
  import { useEffect, useState } from "react";
19680
19680
  import { jsx, jsxs } from "react/jsx-runtime";
19681
- function parseNextSteps(content, strict = true) {
19682
- const headingMatch = strict ? STRICT_HEADING_RE.exec(content) : buildPermissiveHeadingRe().exec(content);
19681
+ function parseNextSteps(content, _strict = true) {
19682
+ const headingMatch = NEXT_STEPS_TAG_RE.exec(content);
19683
19683
  if (!headingMatch) {
19684
19684
  return { steps: [], stripped: content };
19685
19685
  }
@@ -19692,7 +19692,7 @@ function parseNextSteps(content, strict = true) {
19692
19692
  let found = 0;
19693
19693
  for (const rawLine of lines) {
19694
19694
  const line = rawLine.trim();
19695
- if (line === "</next_steps>") {
19695
+ if (line === "</nextsteps>") {
19696
19696
  consumed += rawLine.length + 1;
19697
19697
  break;
19698
19698
  }
@@ -19719,7 +19719,7 @@ function parseNextSteps(content, strict = true) {
19719
19719
  if (steps.length === 0) {
19720
19720
  return { steps: [], stripped: content };
19721
19721
  }
19722
- if (strict && /<next_steps>/i.test(headingMatch[0]) && !afterHeading.includes("</next_steps>")) {
19722
+ if (!afterHeading.includes("</nextsteps>")) {
19723
19723
  return { steps: [], stripped: content };
19724
19724
  }
19725
19725
  const blockStart = headingMatch.index;
@@ -19727,14 +19727,8 @@ function parseNextSteps(content, strict = true) {
19727
19727
  const stripped = (content.slice(0, blockStart) + content.slice(blockEnd)).replace(/\n{3,}/g, "\n\n").trim();
19728
19728
  return { steps, stripped };
19729
19729
  }
19730
- function buildPermissiveHeadingRe() {
19731
- const variants = PERMISSIVE_HEADING_PATTERNS.map(
19732
- ({ re }) => `(?:${re.source})`
19733
- ).join("|");
19734
- return new RegExp(variants, "i");
19735
- }
19736
19730
  function stripNextStepsBlock(text) {
19737
- return text.replace(/<next_steps\b[^>]*>[\s\S]*?<\/next_steps>/gi, "").replace(/<next_steps\b[^>]*\/?>/gi, "").replace(/\n{3,}/g, "\n\n").trim();
19731
+ return text.replace(/<next_?steps\b[^>]*>[\s\S]*?<\/next_?steps>/gi, "").replace(/<next_?steps\b[^>]*\/?>/gi, "").replace(/\n{3,}/g, "\n\n").trim();
19738
19732
  }
19739
19733
  function fillInput(text) {
19740
19734
  const ta = document.querySelector("textarea");
@@ -19836,20 +19830,14 @@ function NextStepsBar({
19836
19830
  }) })
19837
19831
  ] });
19838
19832
  }
19839
- var STRICT_HEADING_RE, ITEM_RE, MAX_STEPS, PERMISSIVE_HEADING_PATTERNS;
19833
+ var NEXT_STEPS_TAG_RE, ITEM_RE, MAX_STEPS;
19840
19834
  var init_NextStepsBar = __esm({
19841
19835
  "src/components/NextStepsBar.tsx"() {
19842
19836
  "use strict";
19843
19837
  init_i18n();
19844
- STRICT_HEADING_RE = /(?:💡\s*Next steps?|<next_steps>)\s*\n+/i;
19838
+ NEXT_STEPS_TAG_RE = /<nextsteps>\s*\n+/i;
19845
19839
  ITEM_RE = /^(?:(\d+)[.)]\s*|[-*•]\s*)(.+?)(\s+auto="true")?$/;
19846
19840
  MAX_STEPS = 6;
19847
- PERMISSIVE_HEADING_PATTERNS = [
19848
- { re: /💡\s*Next steps?\s*\n+/i, label: "emoji" },
19849
- { re: /##?\s*Next steps?\s*\n+/i, label: "markdown" },
19850
- { re: /\n{1,2}Next steps?\s*\n+/i, label: "plain" },
19851
- { re: /<next_steps>\s*\n+/i, label: "xml-tag" }
19852
- ];
19853
19841
  }
19854
19842
  });
19855
19843
 
@@ -20328,6 +20316,12 @@ function isBoard(value) {
20328
20316
  function isTask(value) {
20329
20317
  return Boolean(value) && typeof value === "object" && typeof value.title === "string";
20330
20318
  }
20319
+ function isTaskEnvelope(value) {
20320
+ return Boolean(value) && typeof value === "object" && typeof value.boardId === "string" && isTask(value.task);
20321
+ }
20322
+ function isBoardEnvelope(value) {
20323
+ return Boolean(value) && typeof value === "object" && isBoard(value.board);
20324
+ }
20331
20325
  function isColumn(value) {
20332
20326
  return Boolean(value) && typeof value === "object" && typeof value.id === "string";
20333
20327
  }
@@ -20381,16 +20375,83 @@ var init_kanban_store = __esm({
20381
20375
  }
20382
20376
  if (type === "kanban.delete") {
20383
20377
  const activeBoardId = get().activeBoardId;
20384
- const removed = data?.removed === true;
20378
+ const deleteResult = data;
20379
+ const removed = deleteResult?.removed === true;
20380
+ const removedBoardId = deleteResult?.boardId ?? activeBoardId;
20385
20381
  set((state) => ({
20386
- boards: removed ? state.boards.filter((board) => board.id !== activeBoardId) : state.boards,
20387
- activeBoardId: removed ? null : state.activeBoardId,
20388
- activeBoard: removed ? null : state.activeBoard,
20382
+ boards: removed ? state.boards.filter((board) => board.id !== removedBoardId) : state.boards,
20383
+ activeBoardId: removed && state.activeBoardId === removedBoardId ? null : state.activeBoardId,
20384
+ activeBoard: removed && state.activeBoard?.id === removedBoardId ? null : state.activeBoard,
20389
20385
  loading: false,
20390
20386
  error: null
20391
20387
  }));
20392
20388
  return;
20393
20389
  }
20390
+ if (type === "kanban.task.remove") {
20391
+ const result = data;
20392
+ set((state) => {
20393
+ const board = isBoard(result?.board) ? result.board : null;
20394
+ if (board && state.activeBoardId === board.id) {
20395
+ return {
20396
+ boards: upsertSummary(state.boards, summarize(board)),
20397
+ activeBoard: board,
20398
+ loading: false,
20399
+ error: null
20400
+ };
20401
+ }
20402
+ const boardId = result?.boardId;
20403
+ const taskId = result?.taskId;
20404
+ const activeBoard = result?.removed === true && taskId && state.activeBoard && (!boardId || state.activeBoard.id === boardId) ? {
20405
+ ...state.activeBoard,
20406
+ tasks: state.activeBoard.tasks.filter((task) => task.id !== taskId)
20407
+ } : state.activeBoard;
20408
+ return {
20409
+ activeBoard,
20410
+ boards: activeBoard ? upsertSummary(state.boards, summarize(activeBoard)) : state.boards,
20411
+ loading: false,
20412
+ error: null
20413
+ };
20414
+ });
20415
+ return;
20416
+ }
20417
+ if (type === "kanban.column.remove") {
20418
+ const result = data;
20419
+ if (isBoard(result?.board)) {
20420
+ const board = result.board;
20421
+ set((state) => ({
20422
+ boards: upsertSummary(state.boards, summarize(board)),
20423
+ activeBoard: state.activeBoardId === board.id ? board : state.activeBoard,
20424
+ loading: false,
20425
+ error: null
20426
+ }));
20427
+ return;
20428
+ }
20429
+ }
20430
+ if (isBoardEnvelope(data)) {
20431
+ const board = data.board;
20432
+ set((state) => ({
20433
+ boards: upsertSummary(state.boards, summarize(board)),
20434
+ activeBoard: state.activeBoardId === board.id ? board : state.activeBoard,
20435
+ loading: false,
20436
+ error: null
20437
+ }));
20438
+ return;
20439
+ }
20440
+ if (isTaskEnvelope(data)) {
20441
+ set((state) => {
20442
+ if (state.activeBoard && state.activeBoard.id === data.boardId) {
20443
+ const activeBoard = upsertTask(state.activeBoard, data.task);
20444
+ return {
20445
+ boards: upsertSummary(state.boards, summarize(activeBoard)),
20446
+ activeBoard,
20447
+ loading: false,
20448
+ error: null
20449
+ };
20450
+ }
20451
+ return { loading: false, error: null };
20452
+ });
20453
+ return;
20454
+ }
20394
20455
  if (isBoard(data)) {
20395
20456
  const summary = summarize(data);
20396
20457
  set((state) => ({
@@ -20404,7 +20465,13 @@ var init_kanban_store = __esm({
20404
20465
  }
20405
20466
  if (isTask(data)) {
20406
20467
  set((state) => ({
20407
- activeBoard: state.activeBoard ? upsertTask(state.activeBoard, data) : state.activeBoard,
20468
+ ...state.activeBoard ? (() => {
20469
+ const activeBoard = upsertTask(state.activeBoard, data);
20470
+ return {
20471
+ activeBoard,
20472
+ boards: upsertSummary(state.boards, summarize(activeBoard))
20473
+ };
20474
+ })() : { activeBoard: state.activeBoard },
20408
20475
  loading: false,
20409
20476
  error: null
20410
20477
  }));
@@ -20412,20 +20479,13 @@ var init_kanban_store = __esm({
20412
20479
  }
20413
20480
  if (Array.isArray(data) && data.every(isColumn)) {
20414
20481
  set((state) => ({
20415
- activeBoard: state.activeBoard ? { ...state.activeBoard, columns: data } : state.activeBoard,
20416
- loading: false,
20417
- error: null
20418
- }));
20419
- return;
20420
- }
20421
- if (type === "kanban.task.remove") {
20422
- set((state) => ({
20423
- activeBoard: state.activeBoard ? {
20424
- ...state.activeBoard,
20425
- tasks: state.activeBoard.tasks.filter(
20426
- (task) => task.id !== (data?.taskId ?? "")
20427
- )
20428
- } : state.activeBoard,
20482
+ ...state.activeBoard ? (() => {
20483
+ const activeBoard = { ...state.activeBoard, columns: data };
20484
+ return {
20485
+ activeBoard,
20486
+ boards: upsertSummary(state.boards, summarize(activeBoard))
20487
+ };
20488
+ })() : { activeBoard: state.activeBoard },
20429
20489
  loading: false,
20430
20490
  error: null
20431
20491
  }));
@@ -22937,11 +22997,23 @@ var init_ws_handlers = __esm({
22937
22997
  "kanban.update": handleKanbanResult,
22938
22998
  "kanban.delete": handleKanbanResult,
22939
22999
  "kanban.generate": handleKanbanResult,
23000
+ "kanban.snapshot": handleKanbanResult,
23001
+ "kanban.taskgraph.export": handleKanbanResult,
23002
+ "kanban.taskgraph.sync": handleKanbanResult,
23003
+ "kanban.task.ready": handleKanbanResult,
22940
23004
  "kanban.task.add": handleKanbanResult,
23005
+ "kanban.task.split": handleKanbanResult,
23006
+ "kanban.task.merge": handleKanbanResult,
22941
23007
  "kanban.task.update": handleKanbanResult,
22942
23008
  "kanban.task.move": handleKanbanResult,
22943
23009
  "kanban.task.copy": handleKanbanResult,
22944
23010
  "kanban.task.transfer": handleKanbanResult,
23011
+ "kanban.task.chain": handleKanbanResult,
23012
+ "kanban.task.chain.get": handleKanbanResult,
23013
+ "kanban.task.claim": handleKanbanResult,
23014
+ "kanban.task.release": handleKanbanResult,
23015
+ "kanban.task.metric.add": handleKanbanResult,
23016
+ "kanban.task.metric.update": handleKanbanResult,
22945
23017
  "kanban.task.assign": handleKanbanResult,
22946
23018
  "kanban.task.dispatch": handleKanbanResult,
22947
23019
  "kanban.task.remove": handleKanbanResult,
@@ -24020,11 +24092,11 @@ var init_utils2 = __esm({
24020
24092
  init_i18n();
24021
24093
  rehypePlugins = [rehypeHighlight];
24022
24094
  markdownComponents = {
24023
- // NOTE: <next_steps> is parsed and rendered in MessageBubble/index.tsx
24095
+ // NOTE: <nextsteps> is parsed and rendered in MessageBubble/index.tsx
24024
24096
  // (post-render, via parseNextSteps + NextStepsBar). We do NOT register a
24025
24097
  // custom component here for two reasons:
24026
24098
  // 1. react-markdown v10's micromark parser doesn't actually dispatch
24027
- // <next_steps> (or any underscored tag) to the components map — they
24099
+ // <nextsteps> (or any underscored tag) to the components map — they
24028
24100
  // fall through as raw HTML, which is exactly what the previous code
24029
24101
  // was trying (and failing) to catch.
24030
24102
  // 2. The MessageBubble path strips the block before passing content to
@@ -37026,7 +37098,7 @@ var SLASH_COMMANDS = [
37026
37098
  { name: "/brain", category: "Inspect", description: "Brain status, risk ceiling (risk <level>), or decision support (ask <question>)" },
37027
37099
  { name: "/plan", category: "Inspect", description: "Strategic plan board: show, add, start, done, promote, clear" },
37028
37100
  { name: "/suggest", category: "Inspect", aliases: ["/next-steps"], description: "Ask the agent for concrete next steps" },
37029
- { name: "/next", category: "Inspect", description: "Show or run numbered next-step suggestions" },
37101
+ { name: "/next", category: "Inspect", aliases: ["/enxt"], description: "Show or run numbered next-step suggestions" },
37030
37102
  // Agent / autonomy
37031
37103
  { name: "/review", category: "Agent", aliases: ["/cr"], description: "Ask the agent to review the pending changes (optional focus)" },
37032
37104
  { name: "/fix", category: "Agent", description: "Diagnose and fix an error (paste it) or the latest failure" },
@@ -38015,7 +38087,8 @@ ${err}` : "Investigate the most recent error or failing test, find the root caus
38015
38087
  }
38016
38088
  return true;
38017
38089
  }
38018
- case "/next": {
38090
+ case "/next":
38091
+ case "/enxt": {
38019
38092
  const narg = args.trim().toLowerCase();
38020
38093
  if (!narg || narg === "list" || narg === "ls" || narg === "show") return handleNextList();
38021
38094
  if (narg === "clear" || narg === "reset") {
@@ -39295,6 +39368,7 @@ function PromptLibraryModal() {
39295
39368
  }
39296
39369
 
39297
39370
  // src/components/ChatInput.tsx
39371
+ init_NextStepsBar();
39298
39372
  init_button();
39299
39373
  import { Fragment as Fragment4, jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
39300
39374
  function ChatInput({
@@ -39393,16 +39467,11 @@ ${promptInsertRequest}` : promptInsertRequest);
39393
39467
  onOpenBreakdown
39394
39468
  ]
39395
39469
  );
39396
- const NEXT_STEPS_RE = /💡\s*Next steps?\s*\n+((?:\d+\.\s+.+\n?)+)/i;
39397
39470
  function parseNextStepsFromContent(content) {
39398
- const match = NEXT_STEPS_RE.exec(content);
39399
- if (!match?.[1]) return [];
39400
- const steps = [];
39401
- for (const line of match[1].split("\n").filter(Boolean)) {
39402
- const m = /^(\d+)\.\s+(.+)$/.exec(line.trim());
39403
- if (m) steps.push({ index: Number.parseInt(m[1], 10), text: m[2].trim() });
39404
- }
39405
- return steps.slice(0, 6);
39471
+ return parseNextSteps(content).steps.map((step) => ({
39472
+ index: step.index,
39473
+ text: step.text
39474
+ }));
39406
39475
  }
39407
39476
  function parseNextStepsFromLastAssistant() {
39408
39477
  const all = useChatStore.getState().messages;
@@ -43370,7 +43439,7 @@ var ErrorBoundary = class extends Component {
43370
43439
  return { error };
43371
43440
  }
43372
43441
  componentDidCatch(error, info) {
43373
- console.error("[ErrorBoundary]", error, info.componentStack);
43442
+ console.error(error, info.componentStack);
43374
43443
  this.props.onError?.(error, info);
43375
43444
  }
43376
43445
  handleReset = () => {
@@ -44789,6 +44858,7 @@ function buildModelCandidates(saved, modelsByProvider, query, currentProvider, c
44789
44858
  provider: sp.id,
44790
44859
  model: m.id,
44791
44860
  modelName: m.name || m.id,
44861
+ description: m.description,
44792
44862
  contextWindow: m.contextWindow,
44793
44863
  isCurrent: sp.id === currentProvider && m.id === currentModel
44794
44864
  });
@@ -44796,7 +44866,7 @@ function buildModelCandidates(saved, modelsByProvider, query, currentProvider, c
44796
44866
  }
44797
44867
  const q = query.toLowerCase().trim();
44798
44868
  const filtered = q ? list.filter(
44799
- (c) => c.provider.toLowerCase().includes(q) || c.model.toLowerCase().includes(q) || c.modelName.toLowerCase().includes(q)
44869
+ (c) => c.provider.toLowerCase().includes(q) || c.model.toLowerCase().includes(q) || c.modelName.toLowerCase().includes(q) || c.description?.toLowerCase().includes(q)
44800
44870
  ) : list;
44801
44871
  return filtered.sort((a, b) => {
44802
44872
  if (a.isCurrent !== b.isCurrent) return a.isCurrent ? -1 : 1;
@@ -48765,7 +48835,7 @@ var DEFAULT_POPULAR_PROVIDERS = [
48765
48835
  {
48766
48836
  id: "anthropic",
48767
48837
  name: "Anthropic",
48768
- description: "Claude Opus, Sonnet, and Haiku",
48838
+ description: "Claude model access",
48769
48839
  icon: "\u{1F9E0}",
48770
48840
  color: "from-amber-500/20 to-amber-500/5 border-amber-500/30 hover:border-amber-500/50",
48771
48841
  keyPlaceholder: "sk-ant-...",
@@ -52419,7 +52489,7 @@ function SkillsList({ className }) {
52419
52489
  const m = msg;
52420
52490
  setExportingAll(false);
52421
52491
  if (m.payload.error) {
52422
- console.error("[skills.export]", m.payload.error);
52492
+ console.error(m.payload.error);
52423
52493
  } else {
52424
52494
  const binary = atob(m.payload.zipBase64);
52425
52495
  const bytes = new Uint8Array(binary.length);
@@ -55365,7 +55435,7 @@ function AppInner() {
55365
55435
  } catch (err) {
55366
55436
  const message = err instanceof Error ? err.message : String(err);
55367
55437
  publishDesktopCommandAck(requestId, false, message);
55368
- console.error("Failed to handle desktop command:", err);
55438
+ console.error(err);
55369
55439
  }
55370
55440
  };
55371
55441
  const bridge = window.wrongstackDesktopCommands;