@agile-vibe-coding/avc 0.1.1 → 0.3.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 (239) hide show
  1. package/cli/agent-loader.js +21 -0
  2. package/cli/agents/agent-selector.md +152 -0
  3. package/cli/agents/architecture-recommender.md +418 -0
  4. package/cli/agents/code-implementer.md +117 -0
  5. package/cli/agents/code-validator.md +80 -0
  6. package/cli/agents/context-reviewer-epic.md +101 -0
  7. package/cli/agents/context-reviewer-story.md +92 -0
  8. package/cli/agents/context-writer-epic.md +145 -0
  9. package/cli/agents/context-writer-story.md +111 -0
  10. package/cli/agents/database-deep-dive.md +470 -0
  11. package/cli/agents/database-recommender.md +634 -0
  12. package/cli/agents/doc-distributor.md +176 -0
  13. package/cli/agents/doc-writer-epic.md +42 -0
  14. package/cli/agents/doc-writer-story.md +43 -0
  15. package/cli/agents/documentation-updater.md +203 -0
  16. package/cli/agents/duplicate-detector.md +110 -0
  17. package/cli/agents/epic-story-decomposer.md +559 -0
  18. package/cli/agents/feature-context-generator.md +91 -0
  19. package/cli/agents/gap-checker-epic.md +52 -0
  20. package/cli/agents/impact-checker-story.md +51 -0
  21. package/cli/agents/migration-guide-generator.md +305 -0
  22. package/cli/agents/mission-scope-generator.md +143 -0
  23. package/cli/agents/mission-scope-validator.md +146 -0
  24. package/cli/agents/project-context-extractor.md +122 -0
  25. package/cli/agents/project-documentation-creator.json +226 -0
  26. package/cli/agents/project-documentation-creator.md +595 -0
  27. package/cli/agents/question-prefiller.md +269 -0
  28. package/cli/agents/refiner-epic.md +39 -0
  29. package/cli/agents/refiner-story.md +42 -0
  30. package/cli/agents/scaffolding-generator.md +99 -0
  31. package/cli/agents/seed-validator.md +71 -0
  32. package/cli/agents/story-doc-enricher.md +133 -0
  33. package/cli/agents/story-scope-reviewer.md +147 -0
  34. package/cli/agents/story-splitter.md +83 -0
  35. package/cli/agents/suggestion-business-analyst.md +88 -0
  36. package/cli/agents/suggestion-deployment-architect.md +263 -0
  37. package/cli/agents/suggestion-product-manager.md +129 -0
  38. package/cli/agents/suggestion-security-specialist.md +156 -0
  39. package/cli/agents/suggestion-technical-architect.md +269 -0
  40. package/cli/agents/suggestion-ux-researcher.md +93 -0
  41. package/cli/agents/task-subtask-decomposer.md +188 -0
  42. package/cli/agents/validator-documentation.json +183 -0
  43. package/cli/agents/validator-documentation.md +455 -0
  44. package/cli/agents/validator-selector.md +211 -0
  45. package/cli/ansi-colors.js +21 -0
  46. package/cli/api-reference-tool.js +368 -0
  47. package/cli/build-docs.js +29 -8
  48. package/cli/ceremony-history.js +369 -0
  49. package/cli/checks/catalog.json +76 -0
  50. package/cli/checks/code/quality.json +26 -0
  51. package/cli/checks/code/testing.json +14 -0
  52. package/cli/checks/code/traceability.json +26 -0
  53. package/cli/checks/cross-refs/epic.json +171 -0
  54. package/cli/checks/cross-refs/story.json +149 -0
  55. package/cli/checks/epic/api.json +114 -0
  56. package/cli/checks/epic/backend.json +126 -0
  57. package/cli/checks/epic/cloud.json +126 -0
  58. package/cli/checks/epic/data.json +102 -0
  59. package/cli/checks/epic/database.json +114 -0
  60. package/cli/checks/epic/developer.json +182 -0
  61. package/cli/checks/epic/devops.json +174 -0
  62. package/cli/checks/epic/frontend.json +162 -0
  63. package/cli/checks/epic/mobile.json +102 -0
  64. package/cli/checks/epic/qa.json +90 -0
  65. package/cli/checks/epic/security.json +184 -0
  66. package/cli/checks/epic/solution-architect.json +192 -0
  67. package/cli/checks/epic/test-architect.json +90 -0
  68. package/cli/checks/epic/ui.json +102 -0
  69. package/cli/checks/epic/ux.json +90 -0
  70. package/cli/checks/fixes/epic-fix-template.md +10 -0
  71. package/cli/checks/fixes/story-fix-template.md +10 -0
  72. package/cli/checks/story/api.json +186 -0
  73. package/cli/checks/story/backend.json +102 -0
  74. package/cli/checks/story/cloud.json +102 -0
  75. package/cli/checks/story/data.json +210 -0
  76. package/cli/checks/story/database.json +102 -0
  77. package/cli/checks/story/developer.json +168 -0
  78. package/cli/checks/story/devops.json +102 -0
  79. package/cli/checks/story/frontend.json +174 -0
  80. package/cli/checks/story/mobile.json +102 -0
  81. package/cli/checks/story/qa.json +210 -0
  82. package/cli/checks/story/security.json +198 -0
  83. package/cli/checks/story/solution-architect.json +230 -0
  84. package/cli/checks/story/test-architect.json +210 -0
  85. package/cli/checks/story/ui.json +102 -0
  86. package/cli/checks/story/ux.json +102 -0
  87. package/cli/coding-order.js +401 -0
  88. package/cli/command-logger.js +49 -12
  89. package/cli/components/static-output.js +63 -0
  90. package/cli/console-output-manager.js +94 -0
  91. package/cli/dependency-checker.js +72 -0
  92. package/cli/docs-sync.js +306 -0
  93. package/cli/epic-story-validator.js +659 -0
  94. package/cli/evaluation-prompts.js +1008 -0
  95. package/cli/execution-context.js +195 -0
  96. package/cli/generate-summary-table.js +340 -0
  97. package/cli/init-model-config.js +704 -0
  98. package/cli/init.js +1737 -278
  99. package/cli/kanban-server-manager.js +227 -0
  100. package/cli/llm-claude.js +150 -1
  101. package/cli/llm-gemini.js +109 -0
  102. package/cli/llm-local.js +493 -0
  103. package/cli/llm-mock.js +233 -0
  104. package/cli/llm-openai.js +454 -0
  105. package/cli/llm-provider.js +379 -3
  106. package/cli/llm-token-limits.js +211 -0
  107. package/cli/llm-verifier.js +662 -0
  108. package/cli/llm-xiaomi.js +143 -0
  109. package/cli/message-constants.js +49 -0
  110. package/cli/message-manager.js +334 -0
  111. package/cli/message-types.js +96 -0
  112. package/cli/messaging-api.js +291 -0
  113. package/cli/micro-check-fixer.js +335 -0
  114. package/cli/micro-check-runner.js +449 -0
  115. package/cli/micro-check-scorer.js +148 -0
  116. package/cli/micro-check-validator.js +538 -0
  117. package/cli/model-pricing.js +192 -0
  118. package/cli/model-query-engine.js +468 -0
  119. package/cli/model-recommendation-analyzer.js +495 -0
  120. package/cli/model-selector.js +270 -0
  121. package/cli/output-buffer.js +107 -0
  122. package/cli/process-manager.js +73 -2
  123. package/cli/prompt-logger.js +57 -0
  124. package/cli/repl-ink.js +4625 -1094
  125. package/cli/repl-old.js +3 -4
  126. package/cli/seed-processor.js +962 -0
  127. package/cli/sprint-planning-processor.js +4162 -0
  128. package/cli/template-processor.js +2149 -105
  129. package/cli/templates/project.md +25 -8
  130. package/cli/templates/vitepress-config.mts.template +5 -4
  131. package/cli/token-tracker.js +547 -0
  132. package/cli/tools/generate-story-validators.js +317 -0
  133. package/cli/tools/generate-validators.js +669 -0
  134. package/cli/update-checker.js +19 -17
  135. package/cli/update-notifier.js +4 -4
  136. package/cli/validation-router.js +667 -0
  137. package/cli/verification-tracker.js +563 -0
  138. package/cli/worktree-runner.js +654 -0
  139. package/kanban/README.md +386 -0
  140. package/kanban/client/README.md +205 -0
  141. package/kanban/client/components.json +20 -0
  142. package/kanban/client/dist/assets/index-D_KC5EQT.css +1 -0
  143. package/kanban/client/dist/assets/index-DjY5zqW7.js +351 -0
  144. package/kanban/client/dist/index.html +16 -0
  145. package/kanban/client/dist/vite.svg +1 -0
  146. package/kanban/client/index.html +15 -0
  147. package/kanban/client/package-lock.json +9442 -0
  148. package/kanban/client/package.json +44 -0
  149. package/kanban/client/postcss.config.js +6 -0
  150. package/kanban/client/public/vite.svg +1 -0
  151. package/kanban/client/src/App.jsx +651 -0
  152. package/kanban/client/src/components/ProjectFileEditorPopup.jsx +117 -0
  153. package/kanban/client/src/components/ceremony/AskArchPopup.jsx +420 -0
  154. package/kanban/client/src/components/ceremony/AskModelPopup.jsx +629 -0
  155. package/kanban/client/src/components/ceremony/CeremonyWorkflowModal.jsx +1133 -0
  156. package/kanban/client/src/components/ceremony/EpicStorySelectionModal.jsx +254 -0
  157. package/kanban/client/src/components/ceremony/ProviderSwitcherButton.jsx +290 -0
  158. package/kanban/client/src/components/ceremony/SponsorCallModal.jsx +686 -0
  159. package/kanban/client/src/components/ceremony/SprintPlanningModal.jsx +838 -0
  160. package/kanban/client/src/components/ceremony/steps/ArchitectureStep.jsx +150 -0
  161. package/kanban/client/src/components/ceremony/steps/CompleteStep.jsx +136 -0
  162. package/kanban/client/src/components/ceremony/steps/DatabaseStep.jsx +202 -0
  163. package/kanban/client/src/components/ceremony/steps/DeploymentStep.jsx +123 -0
  164. package/kanban/client/src/components/ceremony/steps/MissionStep.jsx +106 -0
  165. package/kanban/client/src/components/ceremony/steps/ReviewAnswersStep.jsx +329 -0
  166. package/kanban/client/src/components/ceremony/steps/RunningStep.jsx +249 -0
  167. package/kanban/client/src/components/kanban/CardDetailModal.jsx +646 -0
  168. package/kanban/client/src/components/kanban/EpicSection.jsx +146 -0
  169. package/kanban/client/src/components/kanban/FilterToolbar.jsx +222 -0
  170. package/kanban/client/src/components/kanban/GroupingSelector.jsx +63 -0
  171. package/kanban/client/src/components/kanban/KanbanBoard.jsx +211 -0
  172. package/kanban/client/src/components/kanban/KanbanCard.jsx +147 -0
  173. package/kanban/client/src/components/kanban/KanbanColumn.jsx +90 -0
  174. package/kanban/client/src/components/kanban/RefineWorkItemPopup.jsx +784 -0
  175. package/kanban/client/src/components/kanban/RunButton.jsx +162 -0
  176. package/kanban/client/src/components/kanban/SeedButton.jsx +176 -0
  177. package/kanban/client/src/components/layout/LoadingScreen.jsx +82 -0
  178. package/kanban/client/src/components/process/ProcessMonitorBar.jsx +80 -0
  179. package/kanban/client/src/components/settings/AgentEditorPopup.jsx +171 -0
  180. package/kanban/client/src/components/settings/AgentsTab.jsx +381 -0
  181. package/kanban/client/src/components/settings/ApiKeysTab.jsx +142 -0
  182. package/kanban/client/src/components/settings/CeremonyModelsTab.jsx +105 -0
  183. package/kanban/client/src/components/settings/CheckEditorPopup.jsx +507 -0
  184. package/kanban/client/src/components/settings/CostThresholdsTab.jsx +95 -0
  185. package/kanban/client/src/components/settings/ModelPricingTab.jsx +269 -0
  186. package/kanban/client/src/components/settings/OpenAIAuthSection.jsx +412 -0
  187. package/kanban/client/src/components/settings/ServersTab.jsx +121 -0
  188. package/kanban/client/src/components/settings/SettingsModal.jsx +84 -0
  189. package/kanban/client/src/components/stats/CostModal.jsx +384 -0
  190. package/kanban/client/src/components/ui/badge.jsx +27 -0
  191. package/kanban/client/src/components/ui/dialog.jsx +121 -0
  192. package/kanban/client/src/components/ui/tabs.jsx +85 -0
  193. package/kanban/client/src/hooks/__tests__/useGrouping.test.js +232 -0
  194. package/kanban/client/src/hooks/useGrouping.js +177 -0
  195. package/kanban/client/src/hooks/useWebSocket.js +120 -0
  196. package/kanban/client/src/lib/__tests__/api.test.js +196 -0
  197. package/kanban/client/src/lib/__tests__/status-grouping.test.js +94 -0
  198. package/kanban/client/src/lib/api.js +515 -0
  199. package/kanban/client/src/lib/status-grouping.js +154 -0
  200. package/kanban/client/src/lib/utils.js +11 -0
  201. package/kanban/client/src/main.jsx +10 -0
  202. package/kanban/client/src/store/__tests__/kanbanStore.test.js +164 -0
  203. package/kanban/client/src/store/ceremonyStore.js +172 -0
  204. package/kanban/client/src/store/filterStore.js +201 -0
  205. package/kanban/client/src/store/kanbanStore.js +123 -0
  206. package/kanban/client/src/store/processStore.js +65 -0
  207. package/kanban/client/src/store/sprintPlanningStore.js +33 -0
  208. package/kanban/client/src/styles/globals.css +59 -0
  209. package/kanban/client/tailwind.config.js +77 -0
  210. package/kanban/client/vite.config.js +28 -0
  211. package/kanban/client/vitest.config.js +28 -0
  212. package/kanban/dev-start.sh +47 -0
  213. package/kanban/package.json +12 -0
  214. package/kanban/server/index.js +537 -0
  215. package/kanban/server/routes/ceremony.js +454 -0
  216. package/kanban/server/routes/costs.js +163 -0
  217. package/kanban/server/routes/openai-oauth.js +366 -0
  218. package/kanban/server/routes/processes.js +50 -0
  219. package/kanban/server/routes/settings.js +736 -0
  220. package/kanban/server/routes/websocket.js +281 -0
  221. package/kanban/server/routes/work-items.js +487 -0
  222. package/kanban/server/services/CeremonyService.js +1441 -0
  223. package/kanban/server/services/FileSystemScanner.js +95 -0
  224. package/kanban/server/services/FileWatcher.js +144 -0
  225. package/kanban/server/services/HierarchyBuilder.js +196 -0
  226. package/kanban/server/services/ProcessRegistry.js +122 -0
  227. package/kanban/server/services/TaskRunnerService.js +261 -0
  228. package/kanban/server/services/WorkItemReader.js +123 -0
  229. package/kanban/server/services/WorkItemRefineService.js +510 -0
  230. package/kanban/server/start.js +49 -0
  231. package/kanban/server/utils/kanban-logger.js +132 -0
  232. package/kanban/server/utils/markdown.js +91 -0
  233. package/kanban/server/utils/status-grouping.js +107 -0
  234. package/kanban/server/workers/run-task-worker.js +121 -0
  235. package/kanban/server/workers/seed-worker.js +94 -0
  236. package/kanban/server/workers/sponsor-call-worker.js +92 -0
  237. package/kanban/server/workers/sprint-planning-worker.js +212 -0
  238. package/package.json +19 -7
  239. package/cli/agents/documentation.md +0 -302
@@ -0,0 +1,281 @@
1
+ import { WebSocketServer } from 'ws';
2
+
3
+ /**
4
+ * Setup WebSocket server for real-time updates
5
+ * @param {http.Server} server - HTTP server instance
6
+ * @param {object} dataStore - Data store with work items
7
+ * @returns {WebSocketServer}
8
+ */
9
+ export function setupWebSocket(server, dataStore, processRegistry = null, ceremonyService = null) {
10
+ const wss = new WebSocketServer({ server, path: '/ws' });
11
+
12
+ const clients = new Set();
13
+
14
+ wss.on('connection', (ws) => {
15
+ console.log('WebSocket client connected');
16
+ clients.add(ws);
17
+
18
+ // Send initial data
19
+ ws.send(
20
+ JSON.stringify({
21
+ type: 'init',
22
+ data: {
23
+ message: 'Connected to AVC Kanban Board',
24
+ timestamp: Date.now(),
25
+ },
26
+ })
27
+ );
28
+
29
+ // Send current process list so the client is immediately in sync
30
+ if (processRegistry) {
31
+ ws.send(JSON.stringify({ type: 'process:list', processes: processRegistry.list() }));
32
+ }
33
+
34
+ // Send current ceremony status so the client restores running state on reconnect
35
+ if (ceremonyService) {
36
+ const ceremonyStatus = ceremonyService.getStatus();
37
+ if (
38
+ ceremonyStatus.status === 'running' ||
39
+ ceremonyStatus.status === 'cost-limit-pending' ||
40
+ ceremonyStatus.status === 'awaiting-selection'
41
+ ) {
42
+ ws.send(JSON.stringify({ type: 'ceremony:sync', ceremonyStatus }));
43
+ }
44
+ }
45
+
46
+ // Handle client messages
47
+ ws.on('message', (message) => {
48
+ try {
49
+ const data = JSON.parse(message);
50
+ console.log('WebSocket message received:', data);
51
+
52
+ // Handle different message types
53
+ if (data.type === 'ping') {
54
+ ws.send(JSON.stringify({ type: 'pong', timestamp: Date.now() }));
55
+ }
56
+ } catch (error) {
57
+ console.error('Error handling WebSocket message:', error);
58
+ }
59
+ });
60
+
61
+ // Handle client disconnect
62
+ ws.on('close', () => {
63
+ console.log('WebSocket client disconnected');
64
+ clients.delete(ws);
65
+ });
66
+
67
+ // Handle errors
68
+ ws.on('error', (error) => {
69
+ console.error('WebSocket error:', error);
70
+ clients.delete(ws);
71
+ });
72
+ });
73
+
74
+ /**
75
+ * Broadcast message to all connected clients
76
+ * @param {object} message - Message to broadcast
77
+ */
78
+ function broadcast(message) {
79
+ const payload = JSON.stringify(message);
80
+
81
+ clients.forEach((client) => {
82
+ if (client.readyState === 1) {
83
+ // WebSocket.OPEN
84
+ client.send(payload);
85
+ }
86
+ });
87
+ }
88
+
89
+ /**
90
+ * Broadcast work item update
91
+ * @param {string} action - 'added' | 'changed' | 'deleted'
92
+ * @param {string} workItemId - Work item ID
93
+ */
94
+ function broadcastWorkItemUpdate(action, workItemId) {
95
+ const { items } = dataStore.getHierarchy();
96
+ const item = items.get(workItemId);
97
+
98
+ broadcast({
99
+ type: 'work-item-update',
100
+ action,
101
+ data: {
102
+ id: workItemId,
103
+ item: item ? cleanWorkItemForBroadcast(item) : null,
104
+ timestamp: Date.now(),
105
+ },
106
+ });
107
+ }
108
+
109
+ /**
110
+ * Broadcast full refresh (when major changes occur)
111
+ */
112
+ function broadcastRefresh() {
113
+ broadcast({
114
+ type: 'refresh',
115
+ data: {
116
+ message: 'Work items updated, please refresh',
117
+ timestamp: Date.now(),
118
+ },
119
+ });
120
+ }
121
+
122
+ function broadcastCeremonyProgress(message) {
123
+ broadcast({ type: 'ceremony:progress', message });
124
+ }
125
+
126
+ function broadcastCeremonySubstep(substep, meta = {}) {
127
+ broadcast({ type: 'ceremony:substep', substep, meta });
128
+ }
129
+
130
+ function broadcastCeremonyComplete(result) {
131
+ broadcast({ type: 'ceremony:complete', result });
132
+ }
133
+
134
+ function broadcastCeremonyError(error) {
135
+ broadcast({ type: 'ceremony:error', error });
136
+ }
137
+
138
+ function broadcastSprintPlanningProgress(message) {
139
+ broadcast({ type: 'sprint-planning:progress', message });
140
+ }
141
+
142
+ function broadcastSprintPlanningSubstep(substep, meta) {
143
+ broadcast({ type: 'sprint-planning:substep', substep, meta });
144
+ }
145
+
146
+ function broadcastSprintPlanningComplete(result) {
147
+ broadcast({ type: 'sprint-planning:complete', result });
148
+ }
149
+
150
+ function broadcastSprintPlanningError(error) {
151
+ broadcast({ type: 'sprint-planning:error', error });
152
+ }
153
+
154
+ function broadcastMissionProgress(step, message) {
155
+ broadcast({ type: 'mission:progress', step, message });
156
+ }
157
+
158
+ function broadcastCostUpdate() {
159
+ broadcast({ type: 'cost:update' });
160
+ }
161
+
162
+ function broadcastCostLimit(cost, threshold, runningType) {
163
+ broadcast({ type: 'ceremony:cost-limit', cost, threshold, runningType });
164
+ }
165
+
166
+ function broadcastQuotaLimit(provider, model, errMsg, validatorName, runningType) {
167
+ broadcast({ type: 'ceremony:quota-limit', provider, model, errMsg, validatorName, runningType });
168
+ }
169
+
170
+ function broadcastSprintPlanningDecompositionComplete(hierarchy) {
171
+ broadcast({ type: 'sprint-planning:decomposition-complete', hierarchy });
172
+ }
173
+
174
+ function broadcastSprintPlanningPaused() {
175
+ broadcast({ type: 'sprint-planning:paused' });
176
+ }
177
+
178
+ function broadcastSprintPlanningResumed() {
179
+ broadcast({ type: 'sprint-planning:resumed' });
180
+ }
181
+
182
+ function broadcastSprintPlanningCancelled(itemsKept = false) {
183
+ broadcast({ type: 'sprint-planning:cancelled', itemsKept });
184
+ }
185
+
186
+ function broadcastSprintPlanningDetail(detail) {
187
+ broadcast({ type: 'sprint-planning:detail', detail });
188
+ }
189
+
190
+ function broadcastCeremonyDetail(detail) {
191
+ broadcast({ type: 'ceremony:detail', detail });
192
+ }
193
+
194
+ function broadcastCeremonyPaused() {
195
+ broadcast({ type: 'ceremony:paused' });
196
+ }
197
+
198
+ function broadcastCeremonyResumed() {
199
+ broadcast({ type: 'ceremony:resumed' });
200
+ }
201
+
202
+ function broadcastCeremonyCancelled() {
203
+ broadcast({ type: 'ceremony:cancelled' });
204
+ }
205
+
206
+ function broadcastProcessStarted(record) {
207
+ broadcast({
208
+ type: 'process:started',
209
+ processId: record.id,
210
+ processType: record.type,
211
+ label: record.label,
212
+ startedAt: record.startedAt,
213
+ });
214
+ }
215
+
216
+ function broadcastProcessStatus(processId, status, extra = {}) {
217
+ broadcast({ type: 'process:status', processId, status, ...extra });
218
+ }
219
+
220
+ function broadcastRefineProgress(itemId, jobId, message) {
221
+ broadcast({ type: 'refine:progress', itemId, jobId, message });
222
+ }
223
+
224
+ function broadcastRefineComplete(itemId, jobId, result) {
225
+ broadcast({ type: 'refine:complete', itemId, jobId, result });
226
+ }
227
+
228
+ function broadcastRefineError(itemId, jobId, error) {
229
+ broadcast({ type: 'refine:error', itemId, jobId, error });
230
+ }
231
+
232
+ return {
233
+ wss,
234
+ broadcast,
235
+ broadcastWorkItemUpdate,
236
+ broadcastRefresh,
237
+ broadcastCeremonyProgress,
238
+ broadcastCeremonySubstep,
239
+ broadcastCeremonyComplete,
240
+ broadcastCeremonyError,
241
+ broadcastCeremonyPaused,
242
+ broadcastCeremonyResumed,
243
+ broadcastCeremonyCancelled,
244
+ broadcastSprintPlanningProgress,
245
+ broadcastSprintPlanningSubstep,
246
+ broadcastSprintPlanningDetail,
247
+ broadcastSprintPlanningDecompositionComplete,
248
+ broadcastSprintPlanningComplete,
249
+ broadcastSprintPlanningError,
250
+ broadcastSprintPlanningPaused,
251
+ broadcastSprintPlanningResumed,
252
+ broadcastSprintPlanningCancelled,
253
+ broadcastCeremonyDetail,
254
+ broadcastMissionProgress,
255
+ broadcastCostUpdate,
256
+ broadcastCostLimit,
257
+ broadcastQuotaLimit,
258
+ broadcastProcessStarted,
259
+ broadcastProcessStatus,
260
+ broadcastRefineProgress,
261
+ broadcastRefineComplete,
262
+ broadcastRefineError,
263
+ getClientCount: () => clients.size,
264
+ };
265
+ }
266
+
267
+ /**
268
+ * Clean work item for broadcast (remove circular references)
269
+ * @param {object} item - Work item
270
+ * @returns {object} Cleaned work item
271
+ */
272
+ function cleanWorkItemForBroadcast(item) {
273
+ return {
274
+ id: item.id,
275
+ name: item.name,
276
+ type: item._type,
277
+ status: item.status,
278
+ parentId: item._parentId,
279
+ childrenIds: item._children ? item._children.map((c) => c.id) : [],
280
+ };
281
+ }