@wrongstack/webui-server 0.292.1 → 0.295.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 (236) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +18753 -14274
  4. package/dist/index.js.map +4 -4
  5. package/dist/protocol/client-conversation.d.ts +3 -0
  6. package/dist/protocol/client-conversation.d.ts.map +1 -0
  7. package/dist/protocol/client-integrations.d.ts +3 -0
  8. package/dist/protocol/client-integrations.d.ts.map +1 -0
  9. package/dist/protocol/client-operations.d.ts +3 -0
  10. package/dist/protocol/client-operations.d.ts.map +1 -0
  11. package/dist/protocol/client-workspace.d.ts +3 -0
  12. package/dist/protocol/client-workspace.d.ts.map +1 -0
  13. package/dist/protocol/connection-fsm.d.ts +39 -0
  14. package/dist/protocol/connection-fsm.d.ts.map +1 -0
  15. package/dist/protocol/decoder.d.ts +6 -0
  16. package/dist/protocol/decoder.d.ts.map +1 -0
  17. package/dist/protocol/index.d.ts +7 -0
  18. package/dist/protocol/index.d.ts.map +1 -0
  19. package/dist/protocol/index.js +842 -0
  20. package/dist/protocol/index.js.map +7 -0
  21. package/dist/protocol/projections.d.ts +111 -0
  22. package/dist/protocol/projections.d.ts.map +1 -0
  23. package/dist/protocol/registry.d.ts +6 -0
  24. package/dist/protocol/registry.d.ts.map +1 -0
  25. package/dist/protocol/server-conversation.d.ts +3 -0
  26. package/dist/protocol/server-conversation.d.ts.map +1 -0
  27. package/dist/protocol/server-integrations.d.ts +3 -0
  28. package/dist/protocol/server-integrations.d.ts.map +1 -0
  29. package/dist/protocol/server-operations.d.ts +4 -0
  30. package/dist/protocol/server-operations.d.ts.map +1 -0
  31. package/dist/protocol/server-workspace.d.ts +3 -0
  32. package/dist/protocol/server-workspace.d.ts.map +1 -0
  33. package/dist/protocol/types.d.ts +24 -0
  34. package/dist/protocol/types.d.ts.map +1 -0
  35. package/dist/protocol/version.d.ts +20 -0
  36. package/dist/protocol/version.d.ts.map +1 -0
  37. package/dist/server/agent-roster-handlers.d.ts +27 -0
  38. package/dist/server/agent-roster-handlers.d.ts.map +1 -0
  39. package/dist/server/agent-roster-routes.d.ts +8 -0
  40. package/dist/server/agent-roster-routes.d.ts.map +1 -0
  41. package/dist/server/autonomy-routes.d.ts +9 -0
  42. package/dist/server/autonomy-routes.d.ts.map +1 -0
  43. package/dist/server/backend-services.d.ts +19 -6
  44. package/dist/server/backend-services.d.ts.map +1 -1
  45. package/dist/server/boot.d.ts +4 -1
  46. package/dist/server/boot.d.ts.map +1 -1
  47. package/dist/server/brain-handlers.d.ts +47 -0
  48. package/dist/server/brain-handlers.d.ts.map +1 -0
  49. package/dist/server/chronicle-routes.d.ts +12 -0
  50. package/dist/server/chronicle-routes.d.ts.map +1 -0
  51. package/dist/server/client-presence.d.ts +26 -0
  52. package/dist/server/client-presence.d.ts.map +1 -0
  53. package/dist/server/client-transport-routes.d.ts +8 -0
  54. package/dist/server/client-transport-routes.d.ts.map +1 -0
  55. package/dist/server/codebase-indexing.d.ts +3 -1
  56. package/dist/server/codebase-indexing.d.ts.map +1 -1
  57. package/dist/server/codemap-telemetry.d.ts.map +1 -1
  58. package/dist/server/collaboration-ws-handler.d.ts +3 -1
  59. package/dist/server/collaboration-ws-handler.d.ts.map +1 -1
  60. package/dist/server/completion-handlers.d.ts +2 -1
  61. package/dist/server/completion-handlers.d.ts.map +1 -1
  62. package/dist/server/completion-routes.d.ts +7 -0
  63. package/dist/server/completion-routes.d.ts.map +1 -0
  64. package/dist/server/config-doctor.d.ts +11 -0
  65. package/dist/server/config-doctor.d.ts.map +1 -0
  66. package/dist/server/connection-handler.d.ts +8 -46
  67. package/dist/server/connection-handler.d.ts.map +1 -1
  68. package/dist/server/connection-lifecycle.d.ts +43 -0
  69. package/dist/server/connection-lifecycle.d.ts.map +1 -0
  70. package/dist/server/content-routes.d.ts +15 -0
  71. package/dist/server/content-routes.d.ts.map +1 -0
  72. package/dist/server/conversation-operations.d.ts +28 -0
  73. package/dist/server/conversation-operations.d.ts.map +1 -0
  74. package/dist/server/conversation-routes.d.ts +10 -0
  75. package/dist/server/conversation-routes.d.ts.map +1 -0
  76. package/dist/server/custom-context-modes.d.ts +1 -1
  77. package/dist/server/custom-context-modes.d.ts.map +1 -1
  78. package/dist/server/design-handlers.d.ts +8 -0
  79. package/dist/server/design-handlers.d.ts.map +1 -1
  80. package/dist/server/discover-mailbox-bridge.d.ts.map +1 -1
  81. package/dist/server/embedded-host-adapters.d.ts +96 -0
  82. package/dist/server/embedded-host-adapters.d.ts.map +1 -0
  83. package/dist/server/embedded-lifecycle.d.ts +113 -0
  84. package/dist/server/embedded-lifecycle.d.ts.map +1 -0
  85. package/dist/server/embedded-message-router.d.ts +64 -0
  86. package/dist/server/embedded-message-router.d.ts.map +1 -0
  87. package/dist/server/entry.js +16641 -14023
  88. package/dist/server/entry.js.map +4 -4
  89. package/dist/server/eternal-iteration-broadcast.d.ts +1 -1
  90. package/dist/server/eternal-iteration-broadcast.d.ts.map +1 -1
  91. package/dist/server/file-handlers.d.ts.map +1 -1
  92. package/dist/server/frontend-static-serve.d.ts +133 -0
  93. package/dist/server/frontend-static-serve.d.ts.map +1 -0
  94. package/dist/server/git-process.d.ts +4 -0
  95. package/dist/server/git-process.d.ts.map +1 -0
  96. package/dist/server/goal-snapshot-routes.d.ts +7 -0
  97. package/dist/server/goal-snapshot-routes.d.ts.map +1 -0
  98. package/dist/server/goal-ws-handler.d.ts +3 -1
  99. package/dist/server/goal-ws-handler.d.ts.map +1 -1
  100. package/dist/server/handlers/worklist-handlers.d.ts +14 -20
  101. package/dist/server/handlers/worklist-handlers.d.ts.map +1 -1
  102. package/dist/server/handlers.js +150 -121
  103. package/dist/server/handlers.js.map +3 -3
  104. package/dist/server/host-routes.d.ts +7 -0
  105. package/dist/server/host-routes.d.ts.map +1 -0
  106. package/dist/server/http-server/analytics-handler.d.ts +2 -0
  107. package/dist/server/http-server/analytics-handler.d.ts.map +1 -1
  108. package/dist/server/http-server/api-handlers.d.ts.map +1 -1
  109. package/dist/server/http-server.d.ts +20 -23
  110. package/dist/server/http-server.d.ts.map +1 -1
  111. package/dist/server/index.d.ts +55 -22
  112. package/dist/server/index.d.ts.map +1 -1
  113. package/dist/server/instance-registry.d.ts +1 -3
  114. package/dist/server/instance-registry.d.ts.map +1 -1
  115. package/dist/server/introspection-routes.d.ts +19 -0
  116. package/dist/server/introspection-routes.d.ts.map +1 -0
  117. package/dist/server/kanban-dispatch.d.ts +41 -0
  118. package/dist/server/kanban-dispatch.d.ts.map +1 -0
  119. package/dist/server/kanban-host-routes.d.ts +10 -0
  120. package/dist/server/kanban-host-routes.d.ts.map +1 -0
  121. package/dist/server/kanban-routes.d.ts +5 -3
  122. package/dist/server/kanban-routes.d.ts.map +1 -1
  123. package/dist/server/kanban-run-mirror.d.ts +76 -0
  124. package/dist/server/kanban-run-mirror.d.ts.map +1 -0
  125. package/dist/server/kanban-supervisor.d.ts +47 -0
  126. package/dist/server/kanban-supervisor.d.ts.map +1 -0
  127. package/dist/server/mailbox-handlers.d.ts +12 -4
  128. package/dist/server/mailbox-handlers.d.ts.map +1 -1
  129. package/dist/server/mailbox-routes.d.ts +8 -0
  130. package/dist/server/mailbox-routes.d.ts.map +1 -1
  131. package/dist/server/mcp-handlers.d.ts +4 -0
  132. package/dist/server/mcp-handlers.d.ts.map +1 -1
  133. package/dist/server/memory-handlers.d.ts +54 -46
  134. package/dist/server/memory-handlers.d.ts.map +1 -1
  135. package/dist/server/memory-routes.d.ts +11 -0
  136. package/dist/server/memory-routes.d.ts.map +1 -0
  137. package/dist/server/message-dispatcher.d.ts +3 -4
  138. package/dist/server/message-dispatcher.d.ts.map +1 -1
  139. package/dist/server/mode-handlers.d.ts +6 -15
  140. package/dist/server/mode-handlers.d.ts.map +1 -1
  141. package/dist/server/mode-operations.d.ts +24 -0
  142. package/dist/server/mode-operations.d.ts.map +1 -0
  143. package/dist/server/mode-routes.d.ts +2 -0
  144. package/dist/server/mode-routes.d.ts.map +1 -1
  145. package/dist/server/model-auto-discovery.d.ts +1 -1
  146. package/dist/server/model-auto-discovery.d.ts.map +1 -1
  147. package/dist/server/model-catalog.d.ts +1 -1
  148. package/dist/server/model-catalog.d.ts.map +1 -1
  149. package/dist/server/model-operations.d.ts +29 -0
  150. package/dist/server/model-operations.d.ts.map +1 -0
  151. package/dist/server/path-containment.d.ts.map +1 -1
  152. package/dist/server/port-utils.d.ts +18 -25
  153. package/dist/server/port-utils.d.ts.map +1 -1
  154. package/dist/server/pre-context-services.d.ts +32 -5
  155. package/dist/server/pre-context-services.d.ts.map +1 -1
  156. package/dist/server/pref-helpers.d.ts +2 -4
  157. package/dist/server/pref-helpers.d.ts.map +1 -1
  158. package/dist/server/prefs-handlers.d.ts +22 -0
  159. package/dist/server/prefs-handlers.d.ts.map +1 -0
  160. package/dist/server/prefs-routes.d.ts +5 -0
  161. package/dist/server/prefs-routes.d.ts.map +1 -1
  162. package/dist/server/privileged-actions.d.ts +16 -0
  163. package/dist/server/privileged-actions.d.ts.map +1 -0
  164. package/dist/server/process-handlers.d.ts +8 -6
  165. package/dist/server/process-handlers.d.ts.map +1 -1
  166. package/dist/server/process-routes.d.ts +9 -0
  167. package/dist/server/process-routes.d.ts.map +1 -0
  168. package/dist/server/project-handlers.d.ts +25 -33
  169. package/dist/server/project-handlers.d.ts.map +1 -1
  170. package/dist/server/projects-manifest.d.ts +8 -0
  171. package/dist/server/projects-manifest.d.ts.map +1 -1
  172. package/dist/server/prompts-handlers.d.ts +2 -1
  173. package/dist/server/prompts-handlers.d.ts.map +1 -1
  174. package/dist/server/provider-config-io.d.ts +2 -2
  175. package/dist/server/provider-config-io.d.ts.map +1 -1
  176. package/dist/server/provider-config-standalone.d.ts +5 -3
  177. package/dist/server/provider-config-standalone.d.ts.map +1 -1
  178. package/dist/server/provider-handlers.d.ts +63 -6
  179. package/dist/server/provider-handlers.d.ts.map +1 -1
  180. package/dist/server/provider-keys.d.ts +1 -1
  181. package/dist/server/provider-keys.d.ts.map +1 -1
  182. package/dist/server/provider-routes.d.ts +28 -2
  183. package/dist/server/provider-routes.d.ts.map +1 -1
  184. package/dist/server/provider-store.d.ts +5 -4
  185. package/dist/server/provider-store.d.ts.map +1 -1
  186. package/dist/server/route-family-dispatcher.d.ts +71 -0
  187. package/dist/server/route-family-dispatcher.d.ts.map +1 -0
  188. package/dist/server/routes.d.ts +17 -7
  189. package/dist/server/routes.d.ts.map +1 -1
  190. package/dist/server/sdd-board-ws-handler.d.ts +5 -1
  191. package/dist/server/sdd-board-ws-handler.d.ts.map +1 -1
  192. package/dist/server/sdd-wizard-wiring.d.ts +8 -3
  193. package/dist/server/sdd-wizard-wiring.d.ts.map +1 -1
  194. package/dist/server/sdd-wizard-ws-handler.d.ts.map +1 -1
  195. package/dist/server/server-runtime.d.ts +16 -12
  196. package/dist/server/server-runtime.d.ts.map +1 -1
  197. package/dist/server/session-handlers.d.ts +30 -11
  198. package/dist/server/session-handlers.d.ts.map +1 -1
  199. package/dist/server/session-history.d.ts +1 -1
  200. package/dist/server/session-history.d.ts.map +1 -1
  201. package/dist/server/setup-event-projection.d.ts +10 -0
  202. package/dist/server/setup-event-projection.d.ts.map +1 -0
  203. package/dist/server/setup-events-watcher.d.ts +13 -0
  204. package/dist/server/setup-events-watcher.d.ts.map +1 -0
  205. package/dist/server/setup-events.d.ts +11 -21
  206. package/dist/server/setup-events.d.ts.map +1 -1
  207. package/dist/server/setup-screen.d.ts +2 -1
  208. package/dist/server/setup-screen.d.ts.map +1 -1
  209. package/dist/server/shell-open.d.ts +26 -2
  210. package/dist/server/shell-open.d.ts.map +1 -1
  211. package/dist/server/skills-handlers.d.ts +2 -2
  212. package/dist/server/skills-handlers.d.ts.map +1 -1
  213. package/dist/server/specs-ws-handler.d.ts.map +1 -1
  214. package/dist/server/standalone-session-identity.d.ts +3 -2
  215. package/dist/server/standalone-session-identity.d.ts.map +1 -1
  216. package/dist/server/start-webui.d.ts +9 -1
  217. package/dist/server/start-webui.d.ts.map +1 -1
  218. package/dist/server/stream-coalescer.d.ts +49 -0
  219. package/dist/server/stream-coalescer.d.ts.map +1 -0
  220. package/dist/server/techstack-handlers.d.ts +12 -2
  221. package/dist/server/techstack-handlers.d.ts.map +1 -1
  222. package/dist/server/terminal-ws-handler.d.ts +5 -3
  223. package/dist/server/terminal-ws-handler.d.ts.map +1 -1
  224. package/dist/server/types.d.ts +10 -3
  225. package/dist/server/types.d.ts.map +1 -1
  226. package/dist/server/worklist-routes.d.ts +21 -0
  227. package/dist/server/worklist-routes.d.ts.map +1 -0
  228. package/dist/server/worktree-routes.d.ts +10 -0
  229. package/dist/server/worktree-routes.d.ts.map +1 -0
  230. package/dist/server/worktree-ws-handler.d.ts +2 -1
  231. package/dist/server/worktree-ws-handler.d.ts.map +1 -1
  232. package/dist/server/ws-payload-validation.d.ts +11 -0
  233. package/dist/server/ws-payload-validation.d.ts.map +1 -1
  234. package/dist/server/ws-utils.d.ts +8 -0
  235. package/dist/server/ws-utils.d.ts.map +1 -1
  236. package/package.json +14 -10
@@ -1,3 +1,16 @@
1
+ // src/server/handlers/worklist-handlers.ts
2
+ import {
3
+ addPlanItem,
4
+ emptyPlan,
5
+ getPlanTemplate,
6
+ loadPlan,
7
+ loadTasks,
8
+ mutatePlan,
9
+ mutateTasks,
10
+ savePlan,
11
+ setPlanItemStatus
12
+ } from "@wrongstack/core/storage";
13
+
1
14
  // src/server/ws-payload-validation.ts
2
15
  import { FORBIDDEN_PROTO_KEYS } from "@wrongstack/core/utils";
3
16
  function isRecord(value) {
@@ -18,185 +31,202 @@ function validatePlanTemplateUsePayload(payload) {
18
31
  }
19
32
 
20
33
  // src/server/handlers/worklist-handlers.ts
21
- function sendResult(ws, ctx, ok, message) {
22
- ctx.send(ws, { type: ok ? "ok" : "error", message });
34
+ function sendResult(ctx, ws, success, message) {
35
+ ctx.send(ws, { type: "key.operation_result", payload: { success, message } });
36
+ }
37
+ function currentSessionId(ctx) {
38
+ return ctx.context.session?.id ?? "";
23
39
  }
24
40
  function sessionPayload(ctx, payload) {
25
41
  const provided = payload["sessionId"];
26
- const fallback = ctx.context.session?.id ?? "";
27
- const sessionId = typeof provided === "string" && provided.length > 0 ? provided : fallback;
42
+ const sessionId = typeof provided === "string" && provided.length > 0 ? provided : currentSessionId(ctx);
28
43
  return { ...payload, sessionId };
29
44
  }
45
+ function planPathOf(ctx) {
46
+ const value = ctx.context.meta["plan.path"];
47
+ return typeof value === "string" && value ? value : void 0;
48
+ }
49
+ function taskPathOf(ctx) {
50
+ const value = ctx.context.meta["task.path"];
51
+ return typeof value === "string" && value ? value : void 0;
52
+ }
30
53
  function handleTodosGet(ctx, ws) {
31
- ctx.send(ws, { type: "todos.updated", payload: sessionPayload(ctx, { todos: ctx.context.todos }) });
54
+ ctx.send(ws, {
55
+ type: "todos.updated",
56
+ payload: sessionPayload(ctx, { todos: [...ctx.context.todos] })
57
+ });
32
58
  }
33
59
  function handleTodosClear(ctx, ws) {
34
60
  ctx.replaceTodos?.([]);
35
- ctx.broadcast({ type: "todos.cleared", payload: sessionPayload(ctx, {}) });
36
- sendResult(ws, ctx, true, "Todo board cleared.");
61
+ sendResult(ctx, ws, true, "Todos cleared");
62
+ ctx.broadcast({ type: "todos.updated", payload: sessionPayload(ctx, { todos: [] }) });
37
63
  }
38
64
  function handleTodosRemove(ctx, ws, payload) {
39
- if (!payload || payload.id === void 0 && payload.index === void 0) {
40
- sendResult(ws, ctx, false, "todos.remove requires id or index.");
65
+ if (!payload) {
66
+ sendResult(ctx, ws, false, "Missing id or index");
41
67
  return;
42
68
  }
43
- const next = payload.id !== void 0 ? ctx.context.todos.filter((t) => t.id !== payload.id) : ctx.context.todos.filter((_, i) => i !== payload.index);
69
+ const todos = ctx.context.todos;
70
+ let targetIndex = -1;
71
+ if (typeof payload.id === "string") {
72
+ targetIndex = todos.findIndex((todo) => todo.id === payload.id);
73
+ } else if (typeof payload.index === "number" && payload.index > 0) {
74
+ targetIndex = payload.index - 1;
75
+ }
76
+ const removed = todos[targetIndex];
77
+ if (targetIndex < 0 || !removed) {
78
+ sendResult(ctx, ws, false, "Todo not found");
79
+ return;
80
+ }
81
+ const next = [...todos.slice(0, targetIndex), ...todos.slice(targetIndex + 1)];
44
82
  ctx.replaceTodos?.(next);
83
+ sendResult(ctx, ws, true, `Removed: ${removed.content}`);
45
84
  ctx.broadcast({ type: "todos.updated", payload: sessionPayload(ctx, { todos: next }) });
46
- sendResult(ws, ctx, true, "Todo item removed.");
47
85
  }
48
86
  function handleTodoUpdate(ctx, ws, payload) {
49
- const todo = ctx.context.todos.find((t) => t.id === payload.id);
50
- if (!todo) {
51
- sendResult(ws, ctx, false, `No todo with id "${payload.id}".`);
87
+ const index = ctx.context.todos.findIndex((todo) => todo.id === payload.id);
88
+ const existing = ctx.context.todos[index];
89
+ if (index === -1 || !existing) {
90
+ sendResult(ctx, ws, false, "Todo not found");
52
91
  return;
53
92
  }
54
- const next = ctx.context.todos.map(
55
- (t) => t.id === payload.id ? { ...t, ...payload.status !== void 0 && { status: payload.status }, ...payload.activeForm !== void 0 && { activeForm: payload.activeForm } } : t
56
- );
93
+ const next = [...ctx.context.todos];
94
+ next[index] = {
95
+ ...existing,
96
+ status: payload.status ?? existing.status,
97
+ activeForm: payload.activeForm !== void 0 ? payload.activeForm : existing.activeForm
98
+ };
57
99
  ctx.replaceTodos?.(next);
100
+ sendResult(ctx, ws, true, `Todo "${existing.content}" updated`);
58
101
  ctx.broadcast({ type: "todos.updated", payload: sessionPayload(ctx, { todos: next }) });
59
- sendResult(ws, ctx, true, `Todo "${todo.content}" updated.`);
60
102
  }
61
103
  async function handleTasksGet(ctx, ws) {
62
- const taskPath = ctx.context.meta["task.path"];
63
- if (typeof taskPath === "string" && taskPath) {
64
- try {
65
- const { loadTasks } = await import("@wrongstack/core");
66
- const file = await loadTasks(taskPath);
67
- ctx.send(ws, { type: "tasks.updated", payload: sessionPayload(ctx, { tasks: file?.tasks ?? [] }) });
68
- } catch {
69
- ctx.send(ws, { type: "tasks.updated", payload: sessionPayload(ctx, { tasks: [] }) });
70
- }
71
- } else {
104
+ const taskPath = taskPathOf(ctx);
105
+ if (!taskPath) {
72
106
  ctx.send(ws, {
73
107
  type: "tasks.updated",
74
108
  payload: sessionPayload(ctx, { tasks: [], error: "Task storage not configured." })
75
109
  });
110
+ return;
111
+ }
112
+ try {
113
+ const file = await loadTasks(taskPath);
114
+ ctx.send(ws, {
115
+ type: "tasks.updated",
116
+ payload: sessionPayload(ctx, { tasks: file?.tasks ?? [] })
117
+ });
118
+ } catch {
119
+ ctx.send(ws, { type: "tasks.updated", payload: sessionPayload(ctx, { tasks: [] }) });
76
120
  }
77
121
  }
78
122
  async function handleTaskUpdate(ctx, ws, payload) {
79
- const taskPath = ctx.context.meta["task.path"];
80
- if (typeof taskPath !== "string" || !taskPath) {
81
- sendResult(ws, ctx, false, "Task storage is not configured for this session.");
123
+ const taskPath = taskPathOf(ctx);
124
+ if (!taskPath) {
125
+ sendResult(ctx, ws, false, "Task storage not configured.");
82
126
  return;
83
127
  }
84
128
  try {
85
- const { loadTasks, saveTasks } = await import("@wrongstack/core");
86
- const file = await loadTasks(taskPath);
87
- if (!file) {
88
- sendResult(ws, ctx, false, "No task file found.");
89
- return;
90
- }
91
- const idx = file.tasks.findIndex((t) => t.id === payload.id);
92
- if (idx === -1) {
93
- sendResult(ws, ctx, false, `Task "${payload.id}" not found.`);
94
- return;
95
- }
96
- const existing = file.tasks[idx];
97
- if (!existing) {
98
- sendResult(ws, ctx, false, `Task "${payload.id}" not found.`);
99
- return;
100
- }
101
- file.tasks[idx] = { ...existing, status: payload.status };
102
- await saveTasks(taskPath, file);
103
- ctx.broadcast({ type: "tasks.updated", payload: sessionPayload(ctx, { tasks: file.tasks }) });
104
- sendResult(ws, ctx, true, `Task "${payload.id}" marked ${payload.status}.`);
105
- } catch (err) {
106
- sendResult(ws, ctx, false, String(err));
129
+ const file = await mutateTasks(taskPath, currentSessionId(ctx), async (tasks) => {
130
+ const task = tasks.tasks.find((candidate) => candidate.id === payload.id);
131
+ if (!task) return tasks;
132
+ task.status = payload.status;
133
+ task.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
134
+ return tasks;
135
+ });
136
+ sendResult(ctx, ws, true, `Task status updated to "${payload.status}".`);
137
+ ctx.broadcast({
138
+ type: "tasks.updated",
139
+ payload: sessionPayload(ctx, { tasks: file.tasks })
140
+ });
141
+ } catch (error) {
142
+ sendResult(ctx, ws, false, error instanceof Error ? error.message : String(error));
107
143
  }
108
144
  }
109
145
  async function handlePlanGet(ctx, ws) {
110
- const planPath = ctx.context.meta["plan.path"];
111
- const sessionId = ctx.context.session?.id ?? "";
112
- if (typeof planPath === "string" && planPath) {
113
- try {
114
- const { loadPlan } = await import("@wrongstack/core");
115
- const plan = await loadPlan(planPath);
116
- ctx.send(ws, {
117
- type: "plan.updated",
118
- payload: sessionPayload(ctx, {
119
- plan: plan ?? {
120
- version: 1,
121
- sessionId,
122
- updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
123
- items: []
124
- }
125
- })
126
- });
127
- } catch {
128
- ctx.send(ws, {
129
- type: "plan.updated",
130
- payload: sessionPayload(ctx, {
131
- plan: {
132
- version: 1,
133
- sessionId,
134
- updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
135
- items: []
136
- }
137
- })
138
- });
139
- }
140
- } else {
146
+ const planPath = planPathOf(ctx);
147
+ const emptySnapshot = () => ({
148
+ version: 1,
149
+ sessionId: currentSessionId(ctx),
150
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
151
+ items: []
152
+ });
153
+ if (!planPath) {
154
+ ctx.send(ws, {
155
+ type: "plan.updated",
156
+ payload: sessionPayload(ctx, {
157
+ plan: null,
158
+ error: "Plan storage is not configured for this session."
159
+ })
160
+ });
161
+ return;
162
+ }
163
+ try {
164
+ const plan = await loadPlan(planPath);
141
165
  ctx.send(ws, {
142
166
  type: "plan.updated",
143
- payload: sessionPayload(ctx, { plan: null, error: "Plan storage is not configured for this session." })
167
+ payload: sessionPayload(ctx, { plan: plan ?? emptySnapshot() })
168
+ });
169
+ } catch {
170
+ ctx.send(ws, {
171
+ type: "plan.updated",
172
+ payload: sessionPayload(ctx, { plan: emptySnapshot() })
144
173
  });
145
174
  }
146
175
  }
147
176
  async function handlePlanTemplateUse(ctx, ws, template) {
148
- const planPath = ctx.context.meta["plan.path"];
149
- const sessionId = ctx.context.session?.id ?? "";
150
- if (typeof planPath !== "string" || !planPath) {
151
- sendResult(ws, ctx, false, "Plan storage is not configured for this session.");
177
+ const planPath = planPathOf(ctx);
178
+ if (!planPath) {
179
+ sendResult(ctx, ws, false, "Plan storage is not configured for this session.");
152
180
  return;
153
181
  }
154
182
  try {
155
- const { getPlanTemplate, loadPlan, savePlan, emptyPlan, addPlanItem } = await import("@wrongstack/core");
156
- const tpl = getPlanTemplate(template);
157
- if (!tpl) {
158
- sendResult(ws, ctx, false, `Unknown template "${template}".`);
183
+ const templateDefinition = getPlanTemplate(template);
184
+ if (!templateDefinition) {
185
+ sendResult(ctx, ws, false, `Unknown template "${template}".`);
159
186
  return;
160
187
  }
161
- let plan = await loadPlan(planPath) ?? emptyPlan(sessionId);
162
- for (const item of tpl.items) {
188
+ let plan = await loadPlan(planPath) ?? emptyPlan(currentSessionId(ctx));
189
+ for (const item of templateDefinition.items) {
163
190
  ({ plan } = addPlanItem(plan, item.title, item.details));
164
191
  }
165
192
  await savePlan(planPath, plan);
166
- sendResult(ws, ctx, true, `Applied template "${tpl.name}" \u2014 ${tpl.items.length} items added.`);
193
+ sendResult(
194
+ ctx,
195
+ ws,
196
+ true,
197
+ `Applied template "${templateDefinition.name}" \u2014 ${templateDefinition.items.length} items added.`
198
+ );
167
199
  ctx.broadcast({ type: "plan.updated", payload: sessionPayload(ctx, { plan }) });
168
- } catch (err) {
169
- sendResult(ws, ctx, false, String(err));
200
+ } catch (error) {
201
+ sendResult(ctx, ws, false, error instanceof Error ? error.message : String(error));
170
202
  }
171
203
  }
172
204
  async function handlePlanItemUpdate(ctx, ws, payload) {
173
- const planPath = ctx.context.meta["plan.path"];
174
- const sessionId = ctx.context.session?.id ?? "";
175
- if (typeof planPath !== "string" || !planPath) {
176
- sendResult(ws, ctx, false, "Plan storage is not configured for this session.");
205
+ const planPath = planPathOf(ctx);
206
+ if (!planPath) {
207
+ sendResult(ctx, ws, false, "Plan storage is not configured for this session.");
177
208
  return;
178
209
  }
179
210
  try {
180
- const { mutatePlan, setPlanItemStatus } = await import("@wrongstack/core");
181
211
  let changed = false;
182
- const plan = await mutatePlan(planPath, sessionId, async (p) => {
183
- const before = p.updatedAt;
184
- const updated = setPlanItemStatus(p, payload.target, payload.status);
185
- changed = updated.updatedAt !== before;
186
- return updated;
212
+ const plan = await mutatePlan(planPath, currentSessionId(ctx), async (currentPlan) => {
213
+ const before = currentPlan.updatedAt;
214
+ const next = setPlanItemStatus(currentPlan, payload.target, payload.status);
215
+ changed = next.updatedAt !== before;
216
+ return next;
187
217
  });
188
218
  if (!changed) {
189
- sendResult(ws, ctx, false, `No plan item matched "${payload.target}".`);
219
+ sendResult(ctx, ws, false, `No plan item matched "${payload.target}".`);
190
220
  return;
191
221
  }
192
- sendResult(ws, ctx, true, `Plan item status updated to "${payload.status}".`);
222
+ sendResult(ctx, ws, true, `Plan item status updated to "${payload.status}".`);
193
223
  ctx.broadcast({ type: "plan.updated", payload: sessionPayload(ctx, { plan }) });
194
- } catch (err) {
195
- sendResult(ws, ctx, false, String(err));
224
+ } catch (error) {
225
+ sendResult(ctx, ws, false, error instanceof Error ? error.message : String(error));
196
226
  }
197
227
  }
198
- async function handleWorklistMessage(ctx, ws, msg) {
199
- switch (msg.type) {
228
+ async function handleWorklistMessage(ctx, ws, message) {
229
+ switch (message.type) {
200
230
  case "todos.get":
201
231
  handleTodosGet(ctx, ws);
202
232
  return;
@@ -204,13 +234,13 @@ async function handleWorklistMessage(ctx, ws, msg) {
204
234
  handleTodosClear(ctx, ws);
205
235
  return;
206
236
  case "todos.remove":
207
- handleTodosRemove(ctx, ws, msg.payload);
237
+ handleTodosRemove(ctx, ws, message.payload);
208
238
  return;
209
239
  case "todo.update":
210
240
  handleTodoUpdate(
211
241
  ctx,
212
242
  ws,
213
- msg.payload
243
+ message.payload
214
244
  );
215
245
  return;
216
246
  case "tasks.get":
@@ -220,16 +250,16 @@ async function handleWorklistMessage(ctx, ws, msg) {
220
250
  await handleTaskUpdate(
221
251
  ctx,
222
252
  ws,
223
- msg.payload
253
+ message.payload
224
254
  );
225
255
  return;
226
256
  case "plan.get":
227
257
  await handlePlanGet(ctx, ws);
228
258
  return;
229
259
  case "plan.template_use": {
230
- const parsed = validatePlanTemplateUsePayload(msg.payload);
260
+ const parsed = validatePlanTemplateUsePayload(message.payload);
231
261
  if (!parsed.ok) {
232
- sendResult(ws, ctx, false, parsed.message);
262
+ sendResult(ctx, ws, false, parsed.message);
233
263
  return;
234
264
  }
235
265
  await handlePlanTemplateUse(ctx, ws, parsed.value.template);
@@ -239,9 +269,8 @@ async function handleWorklistMessage(ctx, ws, msg) {
239
269
  await handlePlanItemUpdate(
240
270
  ctx,
241
271
  ws,
242
- msg.payload
272
+ message.payload
243
273
  );
244
- return;
245
274
  }
246
275
  }
247
276
  export {