@swarmclawai/swarmclaw 1.2.6 → 1.2.9

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 (269) hide show
  1. package/README.md +54 -23
  2. package/next.config.ts +1 -0
  3. package/package.json +4 -3
  4. package/scripts/easy-setup.mjs +1 -1
  5. package/scripts/postinstall.mjs +1 -1
  6. package/skills/swarmclaw.md +115 -0
  7. package/skills/tools/browser.md +131 -0
  8. package/skills/tools/execute.md +98 -0
  9. package/skills/tools/files.md +98 -0
  10. package/skills/tools/memory.md +104 -0
  11. package/skills/tools/platform.md +144 -0
  12. package/skills/tools/skills.md +83 -0
  13. package/src/app/agents/[id]/page.tsx +1 -18
  14. package/src/app/api/agents/thread-route.test.ts +0 -1
  15. package/src/app/api/approvals/route.test.ts +6 -22
  16. package/src/app/api/chats/[id]/messages/route.ts +23 -19
  17. package/src/app/api/chats/messages-route.test.ts +105 -51
  18. package/src/app/api/connectors/route.ts +2 -2
  19. package/src/app/api/mcp-servers/[id]/test/route.ts +3 -2
  20. package/src/app/api/openclaw/deploy/route.ts +2 -0
  21. package/src/app/api/portability/export/route.ts +8 -0
  22. package/src/app/api/portability/import/route.test.ts +80 -0
  23. package/src/app/api/portability/import/route.ts +28 -0
  24. package/src/app/api/settings/route.ts +0 -2
  25. package/src/app/api/setup/doctor/route.ts +4 -4
  26. package/src/app/api/wallets/[id]/route.ts +15 -157
  27. package/src/app/api/wallets/generate/route.ts +22 -0
  28. package/src/app/api/wallets/route.test.ts +147 -0
  29. package/src/app/api/wallets/route.ts +13 -95
  30. package/src/app/autonomy/page.tsx +2 -57
  31. package/src/app/protocols/page.tsx +2 -21
  32. package/src/app/settings/page.tsx +0 -9
  33. package/src/app/wallets/page.tsx +105 -5
  34. package/src/cli/index.js +21 -33
  35. package/src/cli/spec.js +19 -30
  36. package/src/components/agents/agent-chat-list.tsx +23 -1
  37. package/src/components/agents/agent-sheet.tsx +2 -40
  38. package/src/components/agents/inspector-panel.tsx +165 -131
  39. package/src/components/chat/chat-area.tsx +38 -9
  40. package/src/components/chat/chat-card.tsx +0 -31
  41. package/src/components/chat/message-bubble.tsx +1 -108
  42. package/src/components/chat/message-list.tsx +33 -19
  43. package/src/components/connectors/connector-sheet.tsx +25 -1
  44. package/src/components/gateways/gateway-sheet.tsx +5 -2
  45. package/src/components/layout/sidebar-rail.tsx +6 -10
  46. package/src/components/projects/project-detail.tsx +3 -35
  47. package/src/components/projects/tabs/overview-tab.tsx +3 -59
  48. package/src/components/projects/tabs/work-tab.tsx +7 -77
  49. package/src/components/protocols/structured-session-launcher.tsx +1 -22
  50. package/src/components/shared/connector-platform-icon.tsx +1 -0
  51. package/src/components/tasks/task-card.tsx +4 -34
  52. package/src/components/tasks/task-sheet.tsx +6 -36
  53. package/src/components/wallets/wallet-list.tsx +150 -0
  54. package/src/lib/agent-execute-defaults.test.ts +24 -0
  55. package/src/lib/agent-execute-defaults.ts +62 -0
  56. package/src/lib/app/navigation.test.ts +0 -13
  57. package/src/lib/app/navigation.ts +2 -7
  58. package/src/lib/app/view-constants.ts +14 -19
  59. package/src/lib/chat/queued-message-queue.test.ts +134 -1
  60. package/src/lib/chat/queued-message-queue.ts +77 -2
  61. package/src/lib/server/agents/agent-service.ts +5 -0
  62. package/src/lib/server/agents/agent-thread-session.ts +0 -1
  63. package/src/lib/server/agents/delegation-advisory.test.ts +0 -1
  64. package/src/lib/server/agents/delegation-jobs.test.ts +0 -69
  65. package/src/lib/server/agents/delegation-jobs.ts +0 -25
  66. package/src/lib/server/agents/main-agent-loop.ts +1 -49
  67. package/src/lib/server/agents/subagent-runtime.ts +0 -1
  68. package/src/lib/server/approval-match.ts +0 -85
  69. package/src/lib/server/approvals.test.ts +6 -6
  70. package/src/lib/server/approvals.ts +0 -6
  71. package/src/lib/server/autonomy/supervisor-reflection.test.ts +0 -1
  72. package/src/lib/server/builtin-extensions.ts +1 -2
  73. package/src/lib/server/capability-router.test.ts +0 -2
  74. package/src/lib/server/chat-execution/chat-execution-advanced.test.ts +1 -1
  75. package/src/lib/server/chat-execution/chat-execution-tool-events.test.ts +15 -14
  76. package/src/lib/server/chat-execution/chat-execution-types.ts +0 -2
  77. package/src/lib/server/chat-execution/chat-execution-utils.ts +2 -4
  78. package/src/lib/server/chat-execution/chat-streaming-utils.ts +2 -30
  79. package/src/lib/server/chat-execution/chat-turn-finalization.ts +1 -36
  80. package/src/lib/server/chat-execution/chat-turn-preparation.ts +81 -64
  81. package/src/lib/server/chat-execution/chat-turn-stream-execution.ts +4 -0
  82. package/src/lib/server/chat-execution/continuation-evaluator.ts +8 -0
  83. package/src/lib/server/chat-execution/iteration-event-handler.ts +0 -24
  84. package/src/lib/server/chat-execution/memory-mutation-tools.ts +1 -1
  85. package/src/lib/server/chat-execution/message-classifier.test.ts +0 -45
  86. package/src/lib/server/chat-execution/message-classifier.ts +11 -16
  87. package/src/lib/server/chat-execution/prompt-builder.test.ts +27 -0
  88. package/src/lib/server/chat-execution/prompt-builder.ts +14 -31
  89. package/src/lib/server/chat-execution/prompt-mode.test.ts +24 -0
  90. package/src/lib/server/chat-execution/prompt-mode.ts +5 -1
  91. package/src/lib/server/chat-execution/prompt-sections.ts +0 -1
  92. package/src/lib/server/chat-execution/situational-awareness.test.ts +2 -73
  93. package/src/lib/server/chat-execution/situational-awareness.ts +4 -38
  94. package/src/lib/server/chat-execution/stream-agent-chat.test.ts +13 -126
  95. package/src/lib/server/chat-execution/stream-agent-chat.ts +46 -21
  96. package/src/lib/server/chat-execution/stream-continuation.test.ts +4 -52
  97. package/src/lib/server/chat-execution/stream-continuation.ts +6 -48
  98. package/src/lib/server/chatrooms/chatroom-routing.test.ts +4 -0
  99. package/src/lib/server/chatrooms/session-mailbox.ts +0 -10
  100. package/src/lib/server/chats/chat-session-service.ts +3 -5
  101. package/src/lib/server/connectors/connector-inbound.ts +0 -1
  102. package/src/lib/server/connectors/connector-lifecycle.ts +19 -3
  103. package/src/lib/server/connectors/connector-service.ts +39 -9
  104. package/src/lib/server/connectors/discord.ts +2 -2
  105. package/src/lib/server/connectors/matrix.ts +3 -2
  106. package/src/lib/server/connectors/signal.ts +5 -4
  107. package/src/lib/server/connectors/slack.ts +10 -9
  108. package/src/lib/server/connectors/swarmdock-bidding.ts +74 -0
  109. package/src/lib/server/connectors/swarmdock-payloads.test.ts +85 -0
  110. package/src/lib/server/connectors/swarmdock-secret.test.ts +128 -0
  111. package/src/lib/server/connectors/swarmdock-secret.ts +152 -0
  112. package/src/lib/server/connectors/swarmdock-tasks.ts +119 -0
  113. package/src/lib/server/connectors/swarmdock.ts +255 -0
  114. package/src/lib/server/connectors/teams.ts +3 -2
  115. package/src/lib/server/connectors/telegram.ts +4 -4
  116. package/src/lib/server/connectors/whatsapp.ts +2 -2
  117. package/src/lib/server/daemon/controller.ts +7 -0
  118. package/src/lib/server/execution-brief.test.ts +2 -25
  119. package/src/lib/server/execution-brief.ts +12 -35
  120. package/src/lib/server/execution-engine/task-attempt.ts +0 -1
  121. package/src/lib/server/gateways/gateway-profile-service.ts +19 -1
  122. package/src/lib/server/messages/message-repository.test.ts +70 -0
  123. package/src/lib/server/messages/message-repository.ts +11 -6
  124. package/src/lib/server/openclaw/deploy.ts +32 -2
  125. package/src/lib/server/persistence/storage-context.ts +0 -5
  126. package/src/lib/server/plugins-advanced.test.ts +1 -2
  127. package/src/lib/server/portability/export.ts +109 -0
  128. package/src/lib/server/portability/import.ts +159 -0
  129. package/src/lib/server/protocols/protocol-normalization.ts +0 -4
  130. package/src/lib/server/protocols/protocol-queries.ts +0 -6
  131. package/src/lib/server/protocols/protocol-run-lifecycle.ts +4 -32
  132. package/src/lib/server/protocols/protocol-service.ts +0 -1
  133. package/src/lib/server/protocols/protocol-step-helpers.ts +0 -4
  134. package/src/lib/server/protocols/protocol-step-processors.ts +0 -6
  135. package/src/lib/server/protocols/protocol-swarm.ts +0 -2
  136. package/src/lib/server/protocols/protocol-types.ts +0 -2
  137. package/src/lib/server/provider-health.ts +1 -10
  138. package/src/lib/server/runtime/daemon-state/core.ts +0 -9
  139. package/src/lib/server/runtime/daemon-state.test.ts +0 -35
  140. package/src/lib/server/runtime/heartbeat-service.ts +3 -23
  141. package/src/lib/server/runtime/process-manager.ts +13 -9
  142. package/src/lib/server/runtime/queue/core.ts +11 -33
  143. package/src/lib/server/runtime/runtime-storage-write-paths.test.ts +6 -6
  144. package/src/lib/server/runtime/scheduler.ts +0 -13
  145. package/src/lib/server/runtime/session-run-manager/drain.ts +0 -24
  146. package/src/lib/server/runtime/session-run-manager/enqueue.ts +0 -1
  147. package/src/lib/server/runtime/session-run-manager/queries.ts +15 -1
  148. package/src/lib/server/runtime/session-run-manager/recovery.ts +0 -1
  149. package/src/lib/server/runtime/session-run-manager.test.ts +58 -28
  150. package/src/lib/server/sandbox/session-runtime.test.ts +18 -1
  151. package/src/lib/server/sandbox/session-runtime.ts +40 -28
  152. package/src/lib/server/session-tools/autonomy-tools.test.ts +7 -9
  153. package/src/lib/server/session-tools/context.ts +1 -1
  154. package/src/lib/server/session-tools/credential-env.ts +109 -0
  155. package/src/lib/server/session-tools/crud.ts +3 -17
  156. package/src/lib/server/session-tools/delegate.ts +0 -4
  157. package/src/lib/server/session-tools/edit_file.ts +3 -2
  158. package/src/lib/server/session-tools/execute.test.ts +58 -0
  159. package/src/lib/server/session-tools/execute.ts +334 -0
  160. package/src/lib/server/session-tools/files-tool.ts +635 -0
  161. package/src/lib/server/session-tools/index.ts +14 -8
  162. package/src/lib/server/session-tools/memory-tool.ts +242 -0
  163. package/src/lib/server/session-tools/memory.ts +1 -1
  164. package/src/lib/server/session-tools/openclaw-nodes.ts +3 -2
  165. package/src/lib/server/session-tools/openclaw-workspace.ts +3 -2
  166. package/src/lib/server/session-tools/platform-tool.ts +617 -0
  167. package/src/lib/server/session-tools/session-info.ts +3 -2
  168. package/src/lib/server/session-tools/session-tools-wiring.test.ts +3 -4
  169. package/src/lib/server/session-tools/shell.ts +7 -122
  170. package/src/lib/server/session-tools/skills-tool.ts +396 -0
  171. package/src/lib/server/session-tools/team-context.ts +0 -3
  172. package/src/lib/server/session-tools/web.ts +2 -2
  173. package/src/lib/server/storage-normalization.ts +10 -0
  174. package/src/lib/server/storage.ts +18 -45
  175. package/src/lib/server/tasks/task-checkout.ts +59 -0
  176. package/src/lib/server/tasks/task-lifecycle.ts +2 -0
  177. package/src/lib/server/tasks/task-route-service.ts +4 -26
  178. package/src/lib/server/tasks/task-service.ts +0 -7
  179. package/src/lib/server/tool-aliases.ts +2 -2
  180. package/src/lib/server/tool-capability-policy-advanced.test.ts +13 -6
  181. package/src/lib/server/tool-capability-policy.test.ts +2 -1
  182. package/src/lib/server/tool-capability-policy.ts +60 -35
  183. package/src/lib/server/tool-planning.ts +11 -12
  184. package/src/lib/server/universal-tool-access.ts +0 -1
  185. package/src/lib/server/wallets/wallet-crypto.ts +33 -0
  186. package/src/lib/server/wallets/wallet-repository.ts +24 -0
  187. package/src/lib/server/wallets/wallet-service.ts +119 -0
  188. package/src/lib/server/working-state/extraction.ts +8 -42
  189. package/src/lib/server/working-state/normalization.ts +10 -103
  190. package/src/lib/server/working-state/service.ts +12 -21
  191. package/src/lib/setup-defaults.ts +5 -0
  192. package/src/lib/strip-internal-metadata.test.ts +1 -1
  193. package/src/lib/strip-internal-metadata.ts +1 -1
  194. package/src/lib/tool-definitions.ts +1 -1
  195. package/src/lib/validation/schemas.test.ts +16 -0
  196. package/src/lib/validation/schemas.ts +49 -2
  197. package/src/stores/slices/data-slice.ts +5 -1
  198. package/src/stores/slices/ui-slice.ts +0 -4
  199. package/src/stores/use-chat-store.test.ts +231 -0
  200. package/src/stores/use-chat-store.ts +62 -13
  201. package/src/types/agent.ts +264 -0
  202. package/src/types/app-settings.ts +173 -0
  203. package/src/types/approval.ts +25 -0
  204. package/src/types/connector.ts +188 -0
  205. package/src/types/extension.ts +386 -0
  206. package/src/types/index.ts +16 -3555
  207. package/src/types/message.ts +56 -0
  208. package/src/types/misc.ts +737 -0
  209. package/src/types/protocol.ts +420 -0
  210. package/src/types/provider.ts +52 -0
  211. package/src/types/run.ts +180 -0
  212. package/src/types/schedule.ts +59 -0
  213. package/src/types/session.ts +215 -0
  214. package/src/types/skill.ts +157 -0
  215. package/src/types/swarmdock.ts +29 -0
  216. package/src/types/task.ts +144 -0
  217. package/src/types/working-state.ts +204 -0
  218. package/src/views/settings/section-heartbeat.tsx +2 -2
  219. package/src/views/settings/section-runtime-loop.tsx +0 -14
  220. package/src/app/api/canvas/[sessionId]/route.ts +0 -35
  221. package/src/app/api/missions/[id]/actions/route.ts +0 -31
  222. package/src/app/api/missions/[id]/events/route.ts +0 -14
  223. package/src/app/api/missions/[id]/route.ts +0 -10
  224. package/src/app/api/missions/route.test.ts +0 -244
  225. package/src/app/api/missions/route.ts +0 -57
  226. package/src/app/api/wallets/[id]/approve/route.ts +0 -79
  227. package/src/app/api/wallets/[id]/balance-history/route.ts +0 -18
  228. package/src/app/api/wallets/[id]/send/route.ts +0 -113
  229. package/src/app/api/wallets/[id]/transactions/route.ts +0 -18
  230. package/src/app/missions/[id]/page.tsx +0 -3
  231. package/src/app/missions/page.tsx +0 -685
  232. package/src/components/canvas/canvas-panel.tsx +0 -267
  233. package/src/components/wallets/wallet-approval-dialog.tsx +0 -107
  234. package/src/components/wallets/wallet-panel.tsx +0 -1010
  235. package/src/components/wallets/wallet-section.tsx +0 -260
  236. package/src/features/missions/queries.ts +0 -23
  237. package/src/lib/canvas-content.test.ts +0 -360
  238. package/src/lib/canvas-content.ts +0 -198
  239. package/src/lib/server/canvas-content.test.ts +0 -32
  240. package/src/lib/server/canvas-content.ts +0 -6
  241. package/src/lib/server/ethereum.ts +0 -591
  242. package/src/lib/server/evm-swap.ts +0 -476
  243. package/src/lib/server/missions/mission-intent.test.ts +0 -63
  244. package/src/lib/server/missions/mission-intent.ts +0 -569
  245. package/src/lib/server/missions/mission-repository.ts +0 -74
  246. package/src/lib/server/missions/mission-service/actions.ts +0 -6
  247. package/src/lib/server/missions/mission-service/bindings.ts +0 -9
  248. package/src/lib/server/missions/mission-service/context.ts +0 -4
  249. package/src/lib/server/missions/mission-service/core.ts +0 -2271
  250. package/src/lib/server/missions/mission-service/queries.ts +0 -12
  251. package/src/lib/server/missions/mission-service/recovery.ts +0 -5
  252. package/src/lib/server/missions/mission-service/ticks.ts +0 -9
  253. package/src/lib/server/missions/mission-service.test.ts +0 -888
  254. package/src/lib/server/missions/mission-service.ts +0 -6
  255. package/src/lib/server/session-tools/canvas.ts +0 -105
  256. package/src/lib/server/session-tools/sandbox.ts +0 -281
  257. package/src/lib/server/session-tools/wallet-tool.test.ts +0 -150
  258. package/src/lib/server/session-tools/wallet.ts +0 -1287
  259. package/src/lib/server/solana.ts +0 -327
  260. package/src/lib/server/wallet/wallet-execution.test.ts +0 -198
  261. package/src/lib/server/wallet/wallet-portfolio.test.ts +0 -98
  262. package/src/lib/server/wallet/wallet-portfolio.ts +0 -772
  263. package/src/lib/server/wallet/wallet-service.test.ts +0 -81
  264. package/src/lib/server/wallet/wallet-service.ts +0 -225
  265. package/src/lib/wallet/wallet-transactions.test.ts +0 -75
  266. package/src/lib/wallet/wallet-transactions.ts +0 -43
  267. package/src/lib/wallet/wallet.test.ts +0 -333
  268. package/src/lib/wallet/wallet.ts +0 -183
  269. package/src/views/settings/section-wallets.tsx +0 -35
@@ -0,0 +1,204 @@
1
+
2
+ export type WorkingStateStatus = 'idle' | 'progress' | 'blocked' | 'waiting' | 'completed'
3
+ export type WorkingStateItemStatus = 'active' | 'resolved' | 'superseded'
4
+
5
+ export interface EvidenceRef {
6
+ id: string
7
+ type: 'tool' | 'message' | 'task' | 'artifact' | 'error' | 'approval'
8
+ summary: string
9
+ value?: string | null
10
+ toolName?: string | null
11
+ toolCallId?: string | null
12
+ runId?: string | null
13
+ sessionId?: string | null
14
+ taskId?: string | null
15
+ createdAt: number
16
+ }
17
+
18
+ export interface WorkingPlanStep {
19
+ id: string
20
+ text: string
21
+ status: WorkingStateItemStatus
22
+ createdAt: number
23
+ updatedAt: number
24
+ }
25
+
26
+ export interface WorkingFact {
27
+ id: string
28
+ statement: string
29
+ source: 'user' | 'tool' | 'assistant' | 'system'
30
+ status: WorkingStateItemStatus
31
+ evidenceIds?: string[]
32
+ createdAt: number
33
+ updatedAt: number
34
+ }
35
+
36
+ export interface WorkingArtifact {
37
+ id: string
38
+ label: string
39
+ kind: 'file' | 'url' | 'approval' | 'message' | 'other'
40
+ path?: string | null
41
+ url?: string | null
42
+ sourceTool?: string | null
43
+ status: WorkingStateItemStatus
44
+ evidenceIds?: string[]
45
+ createdAt: number
46
+ updatedAt: number
47
+ }
48
+
49
+ export interface WorkingDecision {
50
+ id: string
51
+ summary: string
52
+ rationale?: string | null
53
+ status: WorkingStateItemStatus
54
+ evidenceIds?: string[]
55
+ createdAt: number
56
+ updatedAt: number
57
+ }
58
+
59
+ export interface WorkingBlocker {
60
+ id: string
61
+ summary: string
62
+ kind?: 'approval' | 'credential' | 'human_input' | 'external_dependency' | 'error' | 'other' | null
63
+ nextAction?: string | null
64
+ status: WorkingStateItemStatus
65
+ evidenceIds?: string[]
66
+ createdAt: number
67
+ updatedAt: number
68
+ }
69
+
70
+ export interface WorkingQuestion {
71
+ id: string
72
+ question: string
73
+ status: WorkingStateItemStatus
74
+ evidenceIds?: string[]
75
+ createdAt: number
76
+ updatedAt: number
77
+ }
78
+
79
+ export interface WorkingHypothesis {
80
+ id: string
81
+ statement: string
82
+ confidence?: 'low' | 'medium' | 'high' | null
83
+ status: WorkingStateItemStatus
84
+ evidenceIds?: string[]
85
+ createdAt: number
86
+ updatedAt: number
87
+ }
88
+
89
+ export interface WorkingPlanStepPatch {
90
+ id?: string | null
91
+ text: string
92
+ status?: WorkingStateItemStatus | null
93
+ }
94
+
95
+ export interface WorkingFactPatch {
96
+ id?: string | null
97
+ statement: string
98
+ source?: WorkingFact['source'] | null
99
+ status?: WorkingStateItemStatus | null
100
+ evidenceIds?: string[]
101
+ }
102
+
103
+ export interface WorkingArtifactPatch {
104
+ id?: string | null
105
+ label: string
106
+ kind?: WorkingArtifact['kind'] | null
107
+ path?: string | null
108
+ url?: string | null
109
+ sourceTool?: string | null
110
+ status?: WorkingStateItemStatus | null
111
+ evidenceIds?: string[]
112
+ }
113
+
114
+ export interface WorkingDecisionPatch {
115
+ id?: string | null
116
+ summary: string
117
+ rationale?: string | null
118
+ status?: WorkingStateItemStatus | null
119
+ evidenceIds?: string[]
120
+ }
121
+
122
+ export interface WorkingBlockerPatch {
123
+ id?: string | null
124
+ summary: string
125
+ kind?: WorkingBlocker['kind']
126
+ nextAction?: string | null
127
+ status?: WorkingStateItemStatus | null
128
+ evidenceIds?: string[]
129
+ }
130
+
131
+ export interface WorkingQuestionPatch {
132
+ id?: string | null
133
+ question: string
134
+ status?: WorkingStateItemStatus | null
135
+ evidenceIds?: string[]
136
+ }
137
+
138
+ export interface WorkingHypothesisPatch {
139
+ id?: string | null
140
+ statement: string
141
+ confidence?: WorkingHypothesis['confidence']
142
+ status?: WorkingStateItemStatus | null
143
+ evidenceIds?: string[]
144
+ }
145
+
146
+ export interface WorkingStatePatch {
147
+ objective?: string | null
148
+ summary?: string | null
149
+ constraints?: string[]
150
+ successCriteria?: string[]
151
+ status?: WorkingStateStatus | null
152
+ nextAction?: string | null
153
+ planSteps?: WorkingPlanStepPatch[]
154
+ factsUpsert?: WorkingFactPatch[]
155
+ artifactsUpsert?: WorkingArtifactPatch[]
156
+ decisionsAppend?: WorkingDecisionPatch[]
157
+ blockersUpsert?: WorkingBlockerPatch[]
158
+ questionsUpsert?: WorkingQuestionPatch[]
159
+ hypothesesUpsert?: WorkingHypothesisPatch[]
160
+ evidenceAppend?: EvidenceRef[]
161
+ supersedeIds?: string[]
162
+ }
163
+
164
+ export interface SessionWorkingState {
165
+ sessionId: string
166
+ objective?: string | null
167
+ summary?: string | null
168
+ constraints: string[]
169
+ successCriteria: string[]
170
+ status: WorkingStateStatus
171
+ nextAction?: string | null
172
+ planSteps: WorkingPlanStep[]
173
+ confirmedFacts: WorkingFact[]
174
+ artifacts: WorkingArtifact[]
175
+ decisions: WorkingDecision[]
176
+ blockers: WorkingBlocker[]
177
+ openQuestions: WorkingQuestion[]
178
+ hypotheses: WorkingHypothesis[]
179
+ evidenceRefs: EvidenceRef[]
180
+ createdAt: number
181
+ updatedAt: number
182
+ lastCompactedAt?: number | null
183
+ }
184
+
185
+ export interface ExecutionBriefPlanStep {
186
+ text: string
187
+ status: WorkingStateItemStatus
188
+ }
189
+
190
+ export interface ExecutionBrief {
191
+ sessionId?: string | null
192
+ objective: string | null
193
+ summary: string | null
194
+ status: WorkingStateStatus
195
+ nextAction: string | null
196
+ plan: ExecutionBriefPlanStep[]
197
+ blockers: string[]
198
+ facts: string[]
199
+ artifacts: string[]
200
+ constraints: string[]
201
+ successCriteria: string[]
202
+ evidenceRefs: EvidenceRef[]
203
+ parentContext: string | null
204
+ }
@@ -35,8 +35,8 @@ export function HeartbeatSection({ appSettings, patchSettings, inputClass }: Set
35
35
  setHeartbeatBulkNotice(
36
36
  `Stopped heartbeat on ${result.updatedSessions} session(s); cancelled ${result.cancelledQueued} queued run(s), aborted ${result.abortedRunning} running run(s).`,
37
37
  )
38
- } catch (err: any) {
39
- setHeartbeatBulkNotice(err?.message || 'Failed to disable heartbeat for all agents.')
38
+ } catch (err: unknown) {
39
+ setHeartbeatBulkNotice(err instanceof Error ? err.message : 'Failed to disable heartbeat for all agents.')
40
40
  } finally {
41
41
  setDisablingHeartbeats(false)
42
42
  }
@@ -55,20 +55,6 @@ export function RuntimeLoopSection({ appSettings, patchSettings, inputClass }: S
55
55
  </div>
56
56
  </div>
57
57
 
58
- <label className="block font-display text-[11px] font-600 text-text-3 uppercase tracking-[0.08em] mb-3">Mission Human Loop</label>
59
- <div className="flex items-center gap-3 mb-6">
60
- <button
61
- onClick={() => patchSettings({ missionHumanLoopEnabled: !(appSettings.missionHumanLoopEnabled ?? false) })}
62
- className={`relative w-10 h-[22px] rounded-full transition-colors duration-200 cursor-pointer ${(appSettings.missionHumanLoopEnabled ?? false) ? 'bg-accent' : 'bg-white/[0.12]'}`}
63
- >
64
- <span className={`absolute top-[3px] left-[3px] w-4 h-4 rounded-full bg-white transition-transform duration-200 ${(appSettings.missionHumanLoopEnabled ?? false) ? 'translate-x-[18px]' : ''}`} />
65
- </button>
66
- <div>
67
- <div className="text-[12px] text-text-2">Allow missions to stay open waiting for a human follow-up</div>
68
- <div className="text-[11px] text-text-3/60 mt-1">Off by default for new users. When disabled, generic mission handoffs like “waiting for your next instruction” are closed instead of lingering as open waiting missions. Explicit tool approvals and real external blockers still apply.</div>
69
- </div>
70
- </div>
71
-
72
58
  <label className="flex items-center gap-1.5 font-display text-[11px] font-600 text-text-3 uppercase tracking-[0.08em] mb-3">Loop Mode <HintTip text="Bounded = fixed max steps. Ongoing = runs until the task completes (with a safety cap)" /></label>
73
59
  <div className="grid grid-cols-2 gap-2 mb-5">
74
60
  {([
@@ -1,35 +0,0 @@
1
- import { NextResponse } from 'next/server'
2
- import { loadSessions, saveSessions } from '@/lib/server/storage'
3
- import { notify } from '@/lib/server/ws-hub'
4
- import { normalizeCanvasContent } from '@/lib/canvas-content'
5
- import { safeParseBody } from '@/lib/server/safe-parse-body'
6
-
7
- export async function GET(_req: Request, { params }: { params: Promise<{ sessionId: string }> }) {
8
- const { sessionId } = await params
9
- const sessions = loadSessions()
10
- const session = sessions[sessionId]
11
- if (!session) return NextResponse.json({ error: 'Session not found' }, { status: 404 })
12
-
13
- return NextResponse.json({
14
- sessionId,
15
- content: (session as unknown as Record<string, unknown>).canvasContent || null,
16
- })
17
- }
18
-
19
- export async function POST(req: Request, { params }: { params: Promise<{ sessionId: string }> }) {
20
- const { sessionId } = await params
21
- const { data: body, error } = await safeParseBody(req)
22
- if (error) return error
23
- const sessions = loadSessions()
24
- const session = sessions[sessionId]
25
- if (!session) return NextResponse.json({ error: 'Session not found' }, { status: 404 })
26
-
27
- const nextContent = normalizeCanvasContent(body.document ?? body.content)
28
- ;(session as unknown as Record<string, unknown>).canvasContent = nextContent
29
- session.lastActiveAt = Date.now()
30
- sessions[sessionId] = session
31
- saveSessions(sessions)
32
-
33
- notify(`canvas:${sessionId}`)
34
- return NextResponse.json({ ok: true, sessionId })
35
- }
@@ -1,31 +0,0 @@
1
- import { NextResponse } from 'next/server'
2
- import { notFound } from '@/lib/server/collection-helpers'
3
- import { loadMissionById, performMissionAction } from '@/lib/server/missions/mission-service'
4
-
5
- export async function POST(req: Request, { params }: { params: Promise<{ id: string }> }) {
6
- const { id } = await params
7
- const mission = loadMissionById(id)
8
- if (!mission) return notFound()
9
-
10
- const body = await req.json().catch(() => ({}))
11
- const action = body?.action
12
- if (action !== 'resume' && action !== 'replan' && action !== 'cancel' && action !== 'retry_verification' && action !== 'wait') {
13
- return NextResponse.json({ error: 'Invalid mission action.' }, { status: 400 })
14
- }
15
-
16
- const result = performMissionAction({
17
- missionId: id,
18
- action,
19
- reason: typeof body.reason === 'string' ? body.reason : null,
20
- waitKind: typeof body.waitKind === 'string' ? body.waitKind : undefined,
21
- untilAt: typeof body.untilAt === 'number' ? body.untilAt : null,
22
- })
23
- if (!result) {
24
- return NextResponse.json({ error: 'Unable to update mission.' }, { status: 409 })
25
- }
26
- return NextResponse.json({
27
- ok: true,
28
- mission: result.mission,
29
- appendedEvent: result.event,
30
- })
31
- }
@@ -1,14 +0,0 @@
1
- import { NextResponse } from 'next/server'
2
- import { notFound } from '@/lib/server/collection-helpers'
3
- import { listMissionEventsForMission, loadMissionById } from '@/lib/server/missions/mission-service'
4
-
5
- export async function GET(req: Request, { params }: { params: Promise<{ id: string }> }) {
6
- const { id } = await params
7
- const mission = loadMissionById(id)
8
- if (!mission) return notFound()
9
-
10
- const { searchParams } = new URL(req.url)
11
- const limitParam = searchParams.get('limit')
12
- const limit = limitParam ? Number.parseInt(limitParam, 10) : undefined
13
- return NextResponse.json(listMissionEventsForMission(id, Number.isFinite(limit) ? limit : undefined))
14
- }
@@ -1,10 +0,0 @@
1
- import { NextResponse } from 'next/server'
2
- import { notFound } from '@/lib/server/collection-helpers'
3
- import { getMissionDetail } from '@/lib/server/missions/mission-service'
4
-
5
- export async function GET(_req: Request, { params }: { params: Promise<{ id: string }> }) {
6
- const { id } = await params
7
- const mission = getMissionDetail(id)
8
- if (!mission) return notFound()
9
- return NextResponse.json(mission)
10
- }
@@ -1,244 +0,0 @@
1
- import assert from 'node:assert/strict'
2
- import test from 'node:test'
3
-
4
- import { runWithTempDataDir } from '@/lib/server/test-utils/run-with-temp-data-dir'
5
-
6
- test('missions routes list, detail, and events expose durable mission state', () => {
7
- const output = runWithTempDataDir<{
8
- listCount: number
9
- firstMissionId: string | null
10
- detailMissionId: string | null
11
- linkedTaskId: string | null
12
- parentMissionId: string | null
13
- eventsCount: number
14
- latestEventType: string | null
15
- }>(`
16
- const storageMod = await import('./src/lib/server/storage')
17
- const listRouteMod = await import('./src/app/api/missions/route')
18
- const detailRouteMod = await import('./src/app/api/missions/[id]/route')
19
- const eventsRouteMod = await import('./src/app/api/missions/[id]/events/route')
20
- const storage = storageMod.default || storageMod
21
- const listRoute = listRouteMod.default || listRouteMod
22
- const detailRoute = detailRouteMod.default || detailRouteMod
23
- const eventsRoute = eventsRouteMod.default || eventsRouteMod
24
-
25
- storage.saveAgents({
26
- agentA: {
27
- id: 'agentA',
28
- name: 'Agent A',
29
- provider: 'ollama',
30
- model: 'test-model',
31
- systemPrompt: 'test',
32
- },
33
- })
34
-
35
- storage.saveTasks({
36
- taskA: {
37
- id: 'taskA',
38
- title: 'Prepare release summary',
39
- description: 'Create the release summary.',
40
- status: 'backlog',
41
- agentId: 'agentA',
42
- createdAt: 1,
43
- updatedAt: 1,
44
- missionId: 'missionA',
45
- },
46
- })
47
-
48
- storage.saveMissions({
49
- missionParent: {
50
- id: 'missionParent',
51
- source: 'chat',
52
- sourceRef: { kind: 'chat', sessionId: 'sessionA' },
53
- objective: 'Parent mission',
54
- status: 'active',
55
- phase: 'planning',
56
- sessionId: 'sessionA',
57
- agentId: 'agentA',
58
- taskIds: [],
59
- childMissionIds: ['missionA'],
60
- dependencyMissionIds: [],
61
- dependencyTaskIds: [],
62
- createdAt: 1,
63
- updatedAt: 1,
64
- },
65
- missionA: {
66
- id: 'missionA',
67
- source: 'chat',
68
- sourceRef: { kind: 'chat', sessionId: 'sessionA' },
69
- objective: 'Prepare the release handoff',
70
- status: 'waiting',
71
- phase: 'waiting',
72
- sessionId: 'sessionA',
73
- agentId: 'agentA',
74
- parentMissionId: 'missionParent',
75
- rootMissionId: 'missionParent',
76
- taskIds: ['taskA'],
77
- childMissionIds: [],
78
- dependencyMissionIds: [],
79
- dependencyTaskIds: [],
80
- waitState: { kind: 'approval', reason: 'Waiting for release approval.' },
81
- plannerSummary: 'Track the release handoff.',
82
- currentStep: 'Wait for approval',
83
- createdAt: 2,
84
- updatedAt: 3,
85
- },
86
- missionB: {
87
- id: 'missionB',
88
- source: 'manual',
89
- sourceRef: { kind: 'manual' },
90
- objective: 'Unrelated completed mission',
91
- status: 'completed',
92
- phase: 'completed',
93
- sessionId: 'sessionB',
94
- agentId: 'agentA',
95
- taskIds: [],
96
- childMissionIds: [],
97
- dependencyMissionIds: [],
98
- dependencyTaskIds: [],
99
- createdAt: 1,
100
- updatedAt: 1,
101
- },
102
- })
103
-
104
- storage.saveMissionEvents({
105
- eventCreated: {
106
- id: 'eventCreated',
107
- missionId: 'missionA',
108
- type: 'created',
109
- source: 'chat',
110
- summary: 'Mission created.',
111
- sessionId: 'sessionA',
112
- createdAt: 2,
113
- },
114
- eventWaiting: {
115
- id: 'eventWaiting',
116
- missionId: 'missionA',
117
- type: 'waiting',
118
- source: 'system',
119
- summary: 'Waiting for release approval.',
120
- sessionId: 'sessionA',
121
- createdAt: 3,
122
- },
123
- })
124
-
125
- const listResponse = await listRoute.GET(new Request('http://local/api/missions?status=waiting&sessionId=sessionA&limit=1'))
126
- const listPayload = await listResponse.json()
127
-
128
- const detailResponse = await detailRoute.GET(
129
- new Request('http://local/api/missions/missionA'),
130
- { params: Promise.resolve({ id: 'missionA' }) },
131
- )
132
- const detailPayload = await detailResponse.json()
133
-
134
- const eventsResponse = await eventsRoute.GET(
135
- new Request('http://local/api/missions/missionA/events?limit=1'),
136
- { params: Promise.resolve({ id: 'missionA' }) },
137
- )
138
- const eventsPayload = await eventsResponse.json()
139
-
140
- console.log(JSON.stringify({
141
- listCount: Array.isArray(listPayload) ? listPayload.length : -1,
142
- firstMissionId: Array.isArray(listPayload) ? listPayload[0]?.id || null : null,
143
- detailMissionId: detailPayload?.mission?.id || null,
144
- linkedTaskId: Array.isArray(detailPayload?.linkedTasks) ? detailPayload.linkedTasks[0]?.id || null : null,
145
- parentMissionId: detailPayload?.parent?.id || null,
146
- eventsCount: Array.isArray(eventsPayload) ? eventsPayload.length : -1,
147
- latestEventType: Array.isArray(eventsPayload) ? eventsPayload[0]?.type || null : null,
148
- }))
149
- `, { prefix: 'swarmclaw-missions-route-' })
150
-
151
- assert.equal(output.listCount, 1)
152
- assert.equal(output.firstMissionId, 'missionA')
153
- assert.equal(output.detailMissionId, 'missionA')
154
- assert.equal(output.linkedTaskId, 'taskA')
155
- assert.equal(output.parentMissionId, 'missionParent')
156
- assert.equal(output.eventsCount, 1)
157
- assert.equal(output.latestEventType, 'waiting')
158
- })
159
-
160
- test('mission actions route validates input and persists operator wait actions', () => {
161
- const output = runWithTempDataDir<{
162
- invalidStatus: number
163
- invalidError: string | null
164
- waitStatus: number
165
- waitOk: boolean
166
- missionStatus: string | null
167
- missionPhase: string | null
168
- waitKind: string | null
169
- waitReason: string | null
170
- eventType: string | null
171
- eventAction: string | null
172
- }>(`
173
- const storageMod = await import('./src/lib/server/storage')
174
- const actionsRouteMod = await import('./src/app/api/missions/[id]/actions/route')
175
- const storage = storageMod.default || storageMod
176
- const actionsRoute = actionsRouteMod.default || actionsRouteMod
177
-
178
- storage.saveMissions({
179
- missionA: {
180
- id: 'missionA',
181
- source: 'chat',
182
- sourceRef: { kind: 'chat', sessionId: 'sessionA' },
183
- objective: 'Prepare the release handoff',
184
- status: 'active',
185
- phase: 'planning',
186
- sessionId: 'sessionA',
187
- taskIds: [],
188
- childMissionIds: [],
189
- dependencyMissionIds: [],
190
- dependencyTaskIds: [],
191
- createdAt: 1,
192
- updatedAt: 1,
193
- },
194
- })
195
-
196
- const invalidResponse = await actionsRoute.POST(
197
- new Request('http://local/api/missions/missionA/actions', {
198
- method: 'POST',
199
- headers: { 'content-type': 'application/json' },
200
- body: JSON.stringify({ action: 'ship_it' }),
201
- }),
202
- { params: Promise.resolve({ id: 'missionA' }) },
203
- )
204
- const invalidPayload = await invalidResponse.json()
205
-
206
- const waitResponse = await actionsRoute.POST(
207
- new Request('http://local/api/missions/missionA/actions', {
208
- method: 'POST',
209
- headers: { 'content-type': 'application/json' },
210
- body: JSON.stringify({
211
- action: 'wait',
212
- reason: 'Waiting for operator confirmation.',
213
- waitKind: 'approval',
214
- }),
215
- }),
216
- { params: Promise.resolve({ id: 'missionA' }) },
217
- )
218
- const waitPayload = await waitResponse.json()
219
-
220
- console.log(JSON.stringify({
221
- invalidStatus: invalidResponse.status,
222
- invalidError: invalidPayload?.error || null,
223
- waitStatus: waitResponse.status,
224
- waitOk: waitPayload?.ok === true,
225
- missionStatus: waitPayload?.mission?.status || null,
226
- missionPhase: waitPayload?.mission?.phase || null,
227
- waitKind: waitPayload?.mission?.waitState?.kind || null,
228
- waitReason: waitPayload?.mission?.waitState?.reason || null,
229
- eventType: waitPayload?.appendedEvent?.type || null,
230
- eventAction: waitPayload?.appendedEvent?.data?.action || null,
231
- }))
232
- `, { prefix: 'swarmclaw-missions-route-' })
233
-
234
- assert.equal(output.invalidStatus, 400)
235
- assert.match(String(output.invalidError || ''), /invalid mission action/i)
236
- assert.equal(output.waitStatus, 200)
237
- assert.equal(output.waitOk, true)
238
- assert.equal(output.missionStatus, 'waiting')
239
- assert.equal(output.missionPhase, 'waiting')
240
- assert.equal(output.waitKind, 'approval')
241
- assert.equal(output.waitReason, 'Waiting for operator confirmation.')
242
- assert.equal(output.eventType, 'operator_action')
243
- assert.equal(output.eventAction, 'wait')
244
- })
@@ -1,57 +0,0 @@
1
- import { NextResponse } from 'next/server'
2
- import type { MissionPhase, MissionSource, MissionStatus } from '@/types'
3
- import { listMissions } from '@/lib/server/missions/mission-service'
4
-
5
- export const dynamic = 'force-dynamic'
6
-
7
- export async function GET(req: Request) {
8
- const { searchParams } = new URL(req.url)
9
- const sessionId = searchParams.get('sessionId')
10
- const agentId = searchParams.get('agentId')
11
- const projectId = searchParams.get('projectId')
12
- const parentMissionId = searchParams.get('parentMissionId')
13
- const limitParam = searchParams.get('limit')
14
- const rawStatus = searchParams.get('status')
15
- const rawPhase = searchParams.get('phase')
16
- const rawSource = searchParams.get('source')
17
- const limit = limitParam ? Number.parseInt(limitParam, 10) : undefined
18
- const status = rawStatus === 'non_terminal'
19
- || rawStatus === 'active'
20
- || rawStatus === 'waiting'
21
- || rawStatus === 'completed'
22
- || rawStatus === 'failed'
23
- || rawStatus === 'cancelled'
24
- ? rawStatus as MissionStatus | 'non_terminal'
25
- : undefined
26
- const phase = rawPhase === 'intake'
27
- || rawPhase === 'planning'
28
- || rawPhase === 'dispatching'
29
- || rawPhase === 'executing'
30
- || rawPhase === 'verifying'
31
- || rawPhase === 'waiting'
32
- || rawPhase === 'completed'
33
- || rawPhase === 'failed'
34
- ? rawPhase as MissionPhase
35
- : undefined
36
- const source = rawSource === 'chat'
37
- || rawSource === 'connector'
38
- || rawSource === 'heartbeat'
39
- || rawSource === 'main-loop-followup'
40
- || rawSource === 'task'
41
- || rawSource === 'schedule'
42
- || rawSource === 'delegation'
43
- || rawSource === 'manual'
44
- ? rawSource as MissionSource
45
- : undefined
46
-
47
- return NextResponse.json(listMissions({
48
- ...(sessionId ? { sessionId } : {}),
49
- ...(agentId ? { agentId } : {}),
50
- ...(projectId ? { projectId } : {}),
51
- ...(parentMissionId ? { parentMissionId } : {}),
52
- ...(status ? { status } : {}),
53
- ...(phase ? { phase } : {}),
54
- ...(source ? { source } : {}),
55
- ...(Number.isFinite(limit) ? { limit } : {}),
56
- }))
57
- }