@swarmclawai/swarmclaw 1.2.8 → 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 (195) hide show
  1. package/README.md +30 -6
  2. package/package.json +2 -2
  3. package/src/app/agents/[id]/page.tsx +1 -18
  4. package/src/app/api/agents/thread-route.test.ts +0 -1
  5. package/src/app/api/approvals/route.test.ts +6 -22
  6. package/src/app/api/connectors/route.ts +2 -2
  7. package/src/app/api/portability/export/route.ts +8 -0
  8. package/src/app/api/portability/import/route.test.ts +80 -0
  9. package/src/app/api/portability/import/route.ts +28 -0
  10. package/src/app/api/settings/route.ts +0 -2
  11. package/src/app/api/wallets/[id]/route.ts +15 -157
  12. package/src/app/api/wallets/generate/route.ts +22 -0
  13. package/src/app/api/wallets/route.test.ts +147 -0
  14. package/src/app/api/wallets/route.ts +13 -95
  15. package/src/app/autonomy/page.tsx +2 -57
  16. package/src/app/protocols/page.tsx +2 -21
  17. package/src/app/settings/page.tsx +0 -9
  18. package/src/app/wallets/page.tsx +105 -5
  19. package/src/cli/index.js +21 -33
  20. package/src/cli/spec.js +19 -30
  21. package/src/components/agents/agent-sheet.tsx +2 -40
  22. package/src/components/agents/inspector-panel.tsx +0 -83
  23. package/src/components/chat/chat-card.tsx +0 -31
  24. package/src/components/chat/message-bubble.tsx +1 -108
  25. package/src/components/connectors/connector-sheet.tsx +25 -1
  26. package/src/components/layout/sidebar-rail.tsx +6 -10
  27. package/src/components/projects/project-detail.tsx +3 -35
  28. package/src/components/projects/tabs/overview-tab.tsx +3 -59
  29. package/src/components/projects/tabs/work-tab.tsx +7 -77
  30. package/src/components/protocols/structured-session-launcher.tsx +1 -22
  31. package/src/components/shared/connector-platform-icon.tsx +1 -0
  32. package/src/components/tasks/task-card.tsx +4 -34
  33. package/src/components/tasks/task-sheet.tsx +6 -36
  34. package/src/components/wallets/wallet-list.tsx +150 -0
  35. package/src/lib/app/navigation.test.ts +0 -13
  36. package/src/lib/app/navigation.ts +2 -7
  37. package/src/lib/app/view-constants.ts +14 -19
  38. package/src/lib/server/agents/agent-thread-session.ts +0 -1
  39. package/src/lib/server/agents/delegation-advisory.test.ts +0 -1
  40. package/src/lib/server/agents/delegation-jobs.test.ts +0 -69
  41. package/src/lib/server/agents/delegation-jobs.ts +0 -25
  42. package/src/lib/server/agents/main-agent-loop.ts +1 -49
  43. package/src/lib/server/agents/subagent-runtime.ts +0 -1
  44. package/src/lib/server/approval-match.ts +0 -85
  45. package/src/lib/server/approvals.test.ts +6 -6
  46. package/src/lib/server/approvals.ts +0 -6
  47. package/src/lib/server/autonomy/supervisor-reflection.test.ts +0 -1
  48. package/src/lib/server/builtin-extensions.ts +0 -2
  49. package/src/lib/server/capability-router.test.ts +0 -2
  50. package/src/lib/server/chat-execution/chat-execution-tool-events.test.ts +14 -14
  51. package/src/lib/server/chat-execution/chat-execution-types.ts +0 -2
  52. package/src/lib/server/chat-execution/chat-execution-utils.ts +0 -2
  53. package/src/lib/server/chat-execution/chat-streaming-utils.ts +2 -30
  54. package/src/lib/server/chat-execution/chat-turn-finalization.ts +1 -36
  55. package/src/lib/server/chat-execution/chat-turn-preparation.ts +2 -22
  56. package/src/lib/server/chat-execution/iteration-event-handler.ts +0 -24
  57. package/src/lib/server/chat-execution/message-classifier.test.ts +0 -45
  58. package/src/lib/server/chat-execution/message-classifier.ts +1 -16
  59. package/src/lib/server/chat-execution/prompt-builder.test.ts +0 -1
  60. package/src/lib/server/chat-execution/prompt-builder.ts +0 -30
  61. package/src/lib/server/chat-execution/prompt-sections.ts +0 -1
  62. package/src/lib/server/chat-execution/situational-awareness.test.ts +2 -73
  63. package/src/lib/server/chat-execution/situational-awareness.ts +4 -38
  64. package/src/lib/server/chat-execution/stream-agent-chat.test.ts +8 -123
  65. package/src/lib/server/chat-execution/stream-agent-chat.ts +1 -5
  66. package/src/lib/server/chat-execution/stream-continuation.test.ts +4 -52
  67. package/src/lib/server/chat-execution/stream-continuation.ts +6 -48
  68. package/src/lib/server/chatrooms/session-mailbox.ts +0 -10
  69. package/src/lib/server/chats/chat-session-service.ts +3 -5
  70. package/src/lib/server/connectors/connector-inbound.ts +0 -1
  71. package/src/lib/server/connectors/connector-lifecycle.ts +19 -3
  72. package/src/lib/server/connectors/connector-service.ts +39 -9
  73. package/src/lib/server/connectors/swarmdock-bidding.ts +74 -0
  74. package/src/lib/server/connectors/swarmdock-payloads.test.ts +85 -0
  75. package/src/lib/server/connectors/swarmdock-secret.test.ts +128 -0
  76. package/src/lib/server/connectors/swarmdock-secret.ts +152 -0
  77. package/src/lib/server/connectors/swarmdock-tasks.ts +119 -0
  78. package/src/lib/server/connectors/swarmdock.ts +255 -0
  79. package/src/lib/server/execution-brief.test.ts +2 -25
  80. package/src/lib/server/execution-brief.ts +12 -35
  81. package/src/lib/server/execution-engine/task-attempt.ts +0 -1
  82. package/src/lib/server/persistence/storage-context.ts +0 -5
  83. package/src/lib/server/portability/export.ts +109 -0
  84. package/src/lib/server/portability/import.ts +159 -0
  85. package/src/lib/server/protocols/protocol-normalization.ts +0 -4
  86. package/src/lib/server/protocols/protocol-queries.ts +0 -6
  87. package/src/lib/server/protocols/protocol-run-lifecycle.ts +4 -32
  88. package/src/lib/server/protocols/protocol-service.ts +0 -1
  89. package/src/lib/server/protocols/protocol-step-helpers.ts +0 -4
  90. package/src/lib/server/protocols/protocol-step-processors.ts +0 -6
  91. package/src/lib/server/protocols/protocol-swarm.ts +0 -2
  92. package/src/lib/server/protocols/protocol-types.ts +0 -2
  93. package/src/lib/server/provider-health.ts +0 -9
  94. package/src/lib/server/runtime/daemon-state/core.ts +0 -9
  95. package/src/lib/server/runtime/daemon-state.test.ts +0 -35
  96. package/src/lib/server/runtime/heartbeat-service.ts +3 -23
  97. package/src/lib/server/runtime/queue/core.ts +11 -33
  98. package/src/lib/server/runtime/runtime-storage-write-paths.test.ts +6 -6
  99. package/src/lib/server/runtime/scheduler.ts +0 -13
  100. package/src/lib/server/runtime/session-run-manager/drain.ts +0 -24
  101. package/src/lib/server/runtime/session-run-manager/enqueue.ts +0 -1
  102. package/src/lib/server/runtime/session-run-manager/queries.ts +0 -1
  103. package/src/lib/server/runtime/session-run-manager/recovery.ts +0 -1
  104. package/src/lib/server/runtime/session-run-manager.test.ts +0 -28
  105. package/src/lib/server/session-tools/crud.ts +0 -14
  106. package/src/lib/server/session-tools/delegate.ts +0 -4
  107. package/src/lib/server/session-tools/index.ts +0 -4
  108. package/src/lib/server/session-tools/team-context.ts +0 -3
  109. package/src/lib/server/storage-normalization.ts +8 -0
  110. package/src/lib/server/storage.ts +18 -45
  111. package/src/lib/server/tasks/task-checkout.ts +59 -0
  112. package/src/lib/server/tasks/task-lifecycle.ts +2 -0
  113. package/src/lib/server/tasks/task-route-service.ts +4 -26
  114. package/src/lib/server/tasks/task-service.ts +0 -7
  115. package/src/lib/server/tool-aliases.ts +0 -1
  116. package/src/lib/server/tool-capability-policy-advanced.test.ts +4 -4
  117. package/src/lib/server/tool-capability-policy.ts +0 -2
  118. package/src/lib/server/tool-planning.ts +0 -12
  119. package/src/lib/server/universal-tool-access.ts +0 -1
  120. package/src/lib/server/wallets/wallet-crypto.ts +33 -0
  121. package/src/lib/server/wallets/wallet-repository.ts +24 -0
  122. package/src/lib/server/wallets/wallet-service.ts +119 -0
  123. package/src/lib/server/working-state/extraction.ts +8 -42
  124. package/src/lib/server/working-state/normalization.ts +10 -103
  125. package/src/lib/server/working-state/service.ts +12 -21
  126. package/src/lib/strip-internal-metadata.test.ts +1 -1
  127. package/src/lib/strip-internal-metadata.ts +1 -1
  128. package/src/lib/tool-definitions.ts +0 -1
  129. package/src/lib/validation/schemas.ts +33 -2
  130. package/src/stores/slices/data-slice.ts +5 -1
  131. package/src/stores/slices/ui-slice.ts +0 -4
  132. package/src/types/agent.ts +0 -84
  133. package/src/types/app-settings.ts +0 -2
  134. package/src/types/approval.ts +0 -2
  135. package/src/types/connector.ts +1 -0
  136. package/src/types/index.ts +1 -1
  137. package/src/types/message.ts +0 -1
  138. package/src/types/misc.ts +0 -2
  139. package/src/types/protocol.ts +0 -2
  140. package/src/types/run.ts +0 -3
  141. package/src/types/session.ts +1 -51
  142. package/src/types/swarmdock.ts +29 -0
  143. package/src/types/task.ts +7 -3
  144. package/src/types/working-state.ts +2 -9
  145. package/src/views/settings/section-runtime-loop.tsx +0 -14
  146. package/src/app/api/canvas/[sessionId]/route.ts +0 -35
  147. package/src/app/api/missions/[id]/actions/route.ts +0 -31
  148. package/src/app/api/missions/[id]/events/route.ts +0 -14
  149. package/src/app/api/missions/[id]/route.ts +0 -10
  150. package/src/app/api/missions/route.test.ts +0 -244
  151. package/src/app/api/missions/route.ts +0 -57
  152. package/src/app/api/wallets/[id]/approve/route.ts +0 -79
  153. package/src/app/api/wallets/[id]/balance-history/route.ts +0 -18
  154. package/src/app/api/wallets/[id]/send/route.ts +0 -113
  155. package/src/app/api/wallets/[id]/transactions/route.ts +0 -18
  156. package/src/app/missions/[id]/page.tsx +0 -3
  157. package/src/app/missions/page.tsx +0 -685
  158. package/src/components/canvas/canvas-panel.tsx +0 -267
  159. package/src/components/wallets/wallet-approval-dialog.tsx +0 -107
  160. package/src/components/wallets/wallet-panel.tsx +0 -1010
  161. package/src/components/wallets/wallet-section.tsx +0 -260
  162. package/src/features/missions/queries.ts +0 -23
  163. package/src/lib/canvas-content.test.ts +0 -360
  164. package/src/lib/canvas-content.ts +0 -198
  165. package/src/lib/server/canvas-content.test.ts +0 -32
  166. package/src/lib/server/canvas-content.ts +0 -6
  167. package/src/lib/server/ethereum.ts +0 -591
  168. package/src/lib/server/evm-swap.ts +0 -476
  169. package/src/lib/server/missions/mission-intent.test.ts +0 -63
  170. package/src/lib/server/missions/mission-intent.ts +0 -569
  171. package/src/lib/server/missions/mission-repository.ts +0 -74
  172. package/src/lib/server/missions/mission-service/actions.ts +0 -6
  173. package/src/lib/server/missions/mission-service/bindings.ts +0 -9
  174. package/src/lib/server/missions/mission-service/context.ts +0 -4
  175. package/src/lib/server/missions/mission-service/core.ts +0 -2271
  176. package/src/lib/server/missions/mission-service/queries.ts +0 -12
  177. package/src/lib/server/missions/mission-service/recovery.ts +0 -5
  178. package/src/lib/server/missions/mission-service/ticks.ts +0 -9
  179. package/src/lib/server/missions/mission-service.test.ts +0 -888
  180. package/src/lib/server/missions/mission-service.ts +0 -6
  181. package/src/lib/server/session-tools/canvas.ts +0 -105
  182. package/src/lib/server/session-tools/wallet-tool.test.ts +0 -150
  183. package/src/lib/server/session-tools/wallet.ts +0 -1287
  184. package/src/lib/server/solana.ts +0 -327
  185. package/src/lib/server/wallet/wallet-execution.test.ts +0 -198
  186. package/src/lib/server/wallet/wallet-portfolio.test.ts +0 -98
  187. package/src/lib/server/wallet/wallet-portfolio.ts +0 -772
  188. package/src/lib/server/wallet/wallet-service.test.ts +0 -81
  189. package/src/lib/server/wallet/wallet-service.ts +0 -225
  190. package/src/lib/wallet/wallet-transactions.test.ts +0 -75
  191. package/src/lib/wallet/wallet-transactions.ts +0 -43
  192. package/src/lib/wallet/wallet.test.ts +0 -333
  193. package/src/lib/wallet/wallet.ts +0 -183
  194. package/src/types/mission.ts +0 -185
  195. package/src/views/settings/section-wallets.tsx +0 -35
@@ -8,7 +8,7 @@ import { OverviewTab } from './tabs/overview-tab'
8
8
  import { WorkTab } from './tabs/work-tab'
9
9
  import { OperationsTab } from './tabs/operations-tab'
10
10
  import { ActivityTab } from './tabs/activity-tab'
11
- import type { BoardTask, Mission } from '@/types'
11
+ import type { BoardTask } from '@/types'
12
12
 
13
13
  export function ProjectDetail() {
14
14
  const activeProjectFilter = useAppStore((s) => s.activeProjectFilter)
@@ -17,43 +17,11 @@ export function ProjectDetail() {
17
17
  const activeTab = useAppStore((s) => s.projectDetailTab)
18
18
  const loadSecrets = useAppStore((s) => s.loadSecrets)
19
19
 
20
- const [projectMissionSnapshot, setProjectMissionSnapshot] = useState<{ projectId: string | null; missions: Mission[] }>({
21
- projectId: null,
22
- missions: [],
23
- })
24
-
25
20
  useEffect(() => {
26
21
  if (!activeProjectFilter) return
27
22
  void loadSecrets()
28
23
  }, [activeProjectFilter, loadSecrets])
29
24
 
30
- useEffect(() => {
31
- let cancelled = false
32
- if (!activeProjectFilter) return
33
- void api<Mission[]>('GET', `/missions?projectId=${encodeURIComponent(activeProjectFilter)}&status=non_terminal&limit=8`)
34
- .then((missions) => {
35
- if (!cancelled) {
36
- setProjectMissionSnapshot({
37
- projectId: activeProjectFilter,
38
- missions: Array.isArray(missions) ? missions : [],
39
- })
40
- }
41
- })
42
- .catch(() => {
43
- if (!cancelled) {
44
- setProjectMissionSnapshot({
45
- projectId: activeProjectFilter,
46
- missions: [],
47
- })
48
- }
49
- })
50
- return () => { cancelled = true }
51
- }, [activeProjectFilter])
52
-
53
- const projectMissions = projectMissionSnapshot.projectId === activeProjectFilter
54
- ? projectMissionSnapshot.missions
55
- : []
56
-
57
25
  const project = activeProjectFilter ? projects[activeProjectFilter] : null
58
26
 
59
27
  const projectTasks = useMemo(
@@ -107,10 +75,10 @@ export function ProjectDetail() {
107
75
  />
108
76
  <div className="flex-1 overflow-y-auto">
109
77
  {activeTab === 'overview' && (
110
- <OverviewTab project={project} missions={projectMissions} />
78
+ <OverviewTab project={project} />
111
79
  )}
112
80
  {activeTab === 'work' && (
113
- <WorkTab missions={projectMissions} />
81
+ <WorkTab />
114
82
  )}
115
83
  {activeTab === 'operations' && (
116
84
  <OperationsTab project={project} />
@@ -1,19 +1,15 @@
1
1
  'use client'
2
2
 
3
3
  import { useEffect, useMemo, useState } from 'react'
4
- import { useRouter } from 'next/navigation'
5
4
  import { useAppStore } from '@/stores/use-app-store'
6
5
  import { relativeDate } from '../project-utils'
7
- import { getMissionPath } from '@/lib/app/navigation'
8
- import type { BoardTask, Mission, Project, Schedule } from '@/types'
6
+ import type { BoardTask, Project, Schedule } from '@/types'
9
7
 
10
8
  interface OverviewTabProps {
11
9
  project: Project
12
- missions: Mission[]
13
10
  }
14
11
 
15
- export function OverviewTab({ project, missions }: OverviewTabProps) {
16
- const router = useRouter()
12
+ export function OverviewTab({ project }: OverviewTabProps) {
17
13
  const tasks = useAppStore((s) => s.tasks) as Record<string, BoardTask>
18
14
  const schedules = useAppStore((s) => s.schedules) as Record<string, Schedule>
19
15
  const activeProjectFilter = useAppStore((s) => s.activeProjectFilter)
@@ -66,8 +62,6 @@ export function OverviewTab({ project, missions }: OverviewTabProps) {
66
62
  { label: 'Stale', value: staleCount, tone: 'text-sky-400', hint: 'No meaningful progress in 3+ days' },
67
63
  ]
68
64
 
69
- const displayedMissions = missions.slice(0, 5)
70
-
71
65
  return (
72
66
  <div className="max-w-3xl mx-auto px-8 py-6 space-y-6">
73
67
  {/* Section 1: Project Identity */}
@@ -110,57 +104,7 @@ export function OverviewTab({ project, missions }: OverviewTabProps) {
110
104
  </div>
111
105
  </div>
112
106
 
113
- {/* Section 3: Active Missions */}
114
- <div>
115
- <h3 className="text-[12px] font-700 uppercase tracking-[0.08em] text-text-3/60 mb-3">Active Missions</h3>
116
- {displayedMissions.length === 0 ? (
117
- <p className="text-[12px] text-text-3/45">No active missions.</p>
118
- ) : (
119
- <div className="flex flex-col gap-2">
120
- {displayedMissions.map((mission) => (
121
- <button
122
- key={mission.id}
123
- onClick={() => router.push(getMissionPath(mission.id))}
124
- className="w-full flex items-center justify-between gap-3 px-4 py-3 rounded-[12px] border border-white/[0.06] bg-white/[0.02] hover:bg-white/[0.04] transition-all cursor-pointer text-left"
125
- style={{ fontFamily: 'inherit' }}
126
- >
127
- <div className="min-w-0 flex-1">
128
- <div className="text-[13px] font-600 text-text truncate">{mission.objective}</div>
129
- <div className="flex items-center gap-2 mt-1 flex-wrap">
130
- <span className={`text-[9px] font-600 uppercase tracking-wider px-1.5 py-0.5 rounded-[4px] ${
131
- mission.status === 'active' ? 'bg-sky-500/15 text-sky-400'
132
- : mission.status === 'waiting' ? 'bg-amber-500/15 text-amber-400'
133
- : 'bg-white/[0.06] text-text-3'
134
- }`}>
135
- {mission.status}
136
- </span>
137
- {mission.status === 'waiting' && (
138
- <span className="text-[9px] font-600 px-1.5 py-0.5 rounded-[4px] bg-amber-500/10 text-amber-400/70">waiting</span>
139
- )}
140
- {mission.status === 'failed' && (
141
- <span className="text-[9px] font-600 px-1.5 py-0.5 rounded-[4px] bg-red-500/10 text-red-400/70">blocked</span>
142
- )}
143
- {(mission.childMissionIds?.length || 0) > 0 && (
144
- <span className="text-[9px] font-600 px-1.5 py-0.5 rounded-[4px] bg-sky-500/10 text-sky-400/70">{mission.childMissionIds?.length} children</span>
145
- )}
146
- {(mission.taskIds?.length || 0) > 0 && (
147
- <span className="text-[9px] font-600 px-1.5 py-0.5 rounded-[4px] bg-white/[0.06] text-text-3/60">{mission.taskIds?.length} task{mission.taskIds?.length === 1 ? '' : 's'}</span>
148
- )}
149
- </div>
150
- </div>
151
- <span className="text-[10px] text-text-3/35 shrink-0">{relativeDate(mission.updatedAt)}</span>
152
- </button>
153
- ))}
154
- {missions.length > 5 && (
155
- <p className="text-[11px] text-accent-bright/70 text-center py-1">
156
- {missions.length - 5} more mission{missions.length - 5 === 1 ? '' : 's'}
157
- </p>
158
- )}
159
- </div>
160
- )}
161
- </div>
162
-
163
- {/* Section 4: Progress */}
107
+ {/* Section 3: Progress */}
164
108
  {totalTasks > 0 && (
165
109
  <div className="rounded-[12px] border border-white/[0.06] bg-white/[0.02] px-5 py-4">
166
110
  <div className="flex items-center justify-between mb-2.5">
@@ -4,7 +4,7 @@ import { useMemo, useState } from 'react'
4
4
  import { useAppStore } from '@/stores/use-app-store'
5
5
  import { AgentAvatar } from '@/components/agents/agent-avatar'
6
6
  import { relativeDate, STATUS_STYLES } from '../project-utils'
7
- import type { Agent, BoardTask, Mission } from '@/types'
7
+ import type { Agent, BoardTask } from '@/types'
8
8
 
9
9
  type SortKey = 'status' | 'updated' | 'agent'
10
10
  type StatusFilter = 'all' | 'backlog' | 'queued' | 'running' | 'completed' | 'failed'
@@ -13,11 +13,7 @@ const STATUS_PRIORITY: Record<string, number> = {
13
13
  failed: 0, running: 1, queued: 2, backlog: 3, deferred: 4, completed: 5, cancelled: 6, archived: 7,
14
14
  }
15
15
 
16
- interface WorkTabProps {
17
- missions: Mission[]
18
- }
19
-
20
- export function WorkTab({ missions }: WorkTabProps) {
16
+ export function WorkTab() {
21
17
  const tasks = useAppStore((s) => s.tasks) as Record<string, BoardTask>
22
18
  const agents = useAppStore((s) => s.agents) as Record<string, Agent>
23
19
  const activeProjectFilter = useAppStore((s) => s.activeProjectFilter)
@@ -27,37 +23,20 @@ export function WorkTab({ missions }: WorkTabProps) {
27
23
  const [sortKey, setSortKey] = useState<SortKey>('status')
28
24
  const [statusFilter, setStatusFilter] = useState<StatusFilter>('all')
29
25
  const [agentFilter, setAgentFilter] = useState<string | null>(null)
30
- const [missionFilter, setMissionFilter] = useState<string | null>(null)
31
- const [missionSummaryOpen, setMissionSummaryOpen] = useState(false)
32
26
 
33
27
  const projectTasks = useMemo(
34
28
  () => Object.values(tasks).filter((t) => t.projectId === activeProjectFilter),
35
29
  [tasks, activeProjectFilter],
36
30
  )
37
31
 
38
- // Build taskId -> mission lookup from Mission.taskIds
39
- const taskIdToMission = useMemo(() => {
40
- const lookup: Record<string, Mission> = {}
41
- for (const m of missions) {
42
- for (const tid of m.taskIds || []) {
43
- lookup[tid] = m
44
- }
45
- }
46
- return lookup
47
- }, [missions])
48
-
49
32
  // Filter
50
33
  const filteredTasks = useMemo(() => {
51
34
  return projectTasks.filter((t) => {
52
35
  if (statusFilter !== 'all' && t.status !== statusFilter) return false
53
36
  if (agentFilter && t.agentId !== agentFilter) return false
54
- if (missionFilter) {
55
- const m = taskIdToMission[t.id]
56
- if (!m || m.id !== missionFilter) return false
57
- }
58
37
  return true
59
38
  })
60
- }, [projectTasks, statusFilter, agentFilter, missionFilter, taskIdToMission])
39
+ }, [projectTasks, statusFilter, agentFilter])
61
40
 
62
41
  // Sort
63
42
  const sortedTasks = useMemo(() => {
@@ -78,56 +57,8 @@ export function WorkTab({ missions }: WorkTabProps) {
78
57
  return Array.from(ids)
79
58
  }, [projectTasks])
80
59
 
81
- // Mission status summary
82
- const missionStatusSummary = useMemo(() => {
83
- const counts: Record<string, number> = {}
84
- for (const m of missions) {
85
- counts[m.status] = (counts[m.status] || 0) + 1
86
- }
87
- return counts
88
- }, [missions])
89
-
90
60
  return (
91
61
  <div className="max-w-3xl mx-auto px-8 py-6 space-y-4">
92
- {/* Mission summary (collapsible) */}
93
- {missions.length > 0 && (
94
- <div className="rounded-[12px] border border-white/[0.06] bg-white/[0.02] overflow-hidden">
95
- <button
96
- onClick={() => setMissionSummaryOpen(!missionSummaryOpen)}
97
- className="w-full flex items-center justify-between px-4 py-3 cursor-pointer bg-transparent border-none text-left"
98
- style={{ fontFamily: 'inherit' }}
99
- >
100
- <span className="text-[12px] font-600 text-text-2">
101
- Missions: {Object.entries(missionStatusSummary).map(([s, c]) => `${c} ${s}`).join(', ')}
102
- </span>
103
- <svg
104
- width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"
105
- className={`text-text-3/40 transition-transform ${missionSummaryOpen ? 'rotate-180' : ''}`}
106
- >
107
- <polyline points="6 9 12 15 18 9" />
108
- </svg>
109
- </button>
110
- {missionSummaryOpen && (
111
- <div className="border-t border-white/[0.06] px-4 py-2 space-y-1">
112
- {missions.map((m) => (
113
- <button
114
- key={m.id}
115
- onClick={() => setMissionFilter(missionFilter === m.id ? null : m.id)}
116
- className={`w-full flex items-center justify-between px-2 py-1.5 rounded-[8px] text-left cursor-pointer bg-transparent border-none transition-colors
117
- ${missionFilter === m.id ? 'bg-accent-soft' : 'hover:bg-white/[0.04]'}`}
118
- style={{ fontFamily: 'inherit' }}
119
- >
120
- <span className="text-[12px] text-text truncate">{m.objective}</span>
121
- <span className={`text-[9px] font-600 uppercase tracking-wider px-1.5 py-0.5 rounded-[4px] shrink-0 ${
122
- m.status === 'active' ? 'bg-sky-500/15 text-sky-400' : 'bg-white/[0.06] text-text-3'
123
- }`}>{m.status}</span>
124
- </button>
125
- ))}
126
- </div>
127
- )}
128
- </div>
129
- )}
130
-
131
62
  {/* Controls row */}
132
63
  <div className="flex items-center justify-between gap-3">
133
64
  <div className="flex items-center gap-2">
@@ -174,9 +105,9 @@ export function WorkTab({ missions }: WorkTabProps) {
174
105
  )}
175
106
 
176
107
  {/* Clear filters */}
177
- {(statusFilter !== 'all' || agentFilter || missionFilter) && (
108
+ {(statusFilter !== 'all' || agentFilter) && (
178
109
  <button
179
- onClick={() => { setStatusFilter('all'); setAgentFilter(null); setMissionFilter(null) }}
110
+ onClick={() => { setStatusFilter('all'); setAgentFilter(null) }}
180
111
  className="text-[10px] text-accent-bright/70 hover:text-accent-bright cursor-pointer bg-transparent border-none"
181
112
  style={{ fontFamily: 'inherit' }}
182
113
  >
@@ -212,7 +143,6 @@ export function WorkTab({ missions }: WorkTabProps) {
212
143
  <div className="flex flex-col gap-1.5">
213
144
  {sortedTasks.map((task) => {
214
145
  const agent = task.agentId ? agents[task.agentId] : null
215
- const mission = taskIdToMission[task.id]
216
146
  return (
217
147
  <button
218
148
  key={task.id}
@@ -225,8 +155,8 @@ export function WorkTab({ missions }: WorkTabProps) {
225
155
  </span>
226
156
  <div className="flex-1 min-w-0">
227
157
  <span className="text-[13px] text-text truncate block">{task.title}</span>
228
- {mission && (
229
- <span className="text-[10px] text-text-3/40 truncate block mt-0.5">{mission.objective}</span>
158
+ {task.objective && (
159
+ <span className="text-[10px] text-text-3/40 truncate block mt-0.5">{task.objective}</span>
230
160
  )}
231
161
  </div>
232
162
  {agent && (
@@ -3,12 +3,11 @@
3
3
  import { useEffect, useMemo, useState } from 'react'
4
4
  import { useAgentsQuery } from '@/features/agents/queries'
5
5
  import { useChatroomsQuery } from '@/features/chatrooms/queries'
6
- import { useMissionsQuery } from '@/features/missions/queries'
7
6
  import { useCreateProtocolRunMutation, useProtocolTemplatesQuery } from '@/features/protocols/queries'
8
7
  import { useTasksQuery } from '@/features/tasks/queries'
9
8
  import { BottomSheet } from '@/components/shared/bottom-sheet'
10
9
  import { SheetFooter } from '@/components/shared/sheet-footer'
11
- import type { BoardTask, Chatroom, Mission, ProtocolRun, ProtocolTemplate } from '@/types'
10
+ import type { BoardTask, Chatroom, ProtocolRun, ProtocolTemplate } from '@/types'
12
11
 
13
12
  export type StructuredSessionLaunchContext = {
14
13
  templateId?: string | null
@@ -21,8 +20,6 @@ export type StructuredSessionLaunchContext = {
21
20
  sessionLabel?: string | null
22
21
  parentChatroomId?: string | null
23
22
  parentChatroomLabel?: string | null
24
- missionId?: string | null
25
- missionLabel?: string | null
26
23
  taskId?: string | null
27
24
  taskLabel?: string | null
28
25
  autoStart?: boolean
@@ -52,7 +49,6 @@ type FormState = {
52
49
  facilitatorAgentId: string
53
50
  sessionId: string
54
51
  parentChatroomId: string
55
- missionId: string
56
52
  taskId: string
57
53
  autoStart: boolean
58
54
  createTranscript: boolean
@@ -62,7 +58,6 @@ const DEFAULT_TEMPLATE_ID = 'facilitated_discussion'
62
58
 
63
59
  function buildDefaultTitle(context: StructuredSessionLaunchContext | null | undefined): string {
64
60
  if (context?.title?.trim()) return context.title.trim()
65
- if (context?.missionLabel?.trim()) return `Structured session: ${context.missionLabel.trim()}`
66
61
  if (context?.taskLabel?.trim()) return `Structured session: ${context.taskLabel.trim()}`
67
62
  if (context?.parentChatroomLabel?.trim()) return `Structured session: ${context.parentChatroomLabel.trim()}`
68
63
  if (context?.sessionLabel?.trim()) return `Structured session: ${context.sessionLabel.trim()}`
@@ -81,7 +76,6 @@ function buildInitialState(context: StructuredSessionLaunchContext | null | unde
81
76
  facilitatorAgentId: context?.facilitatorAgentId?.trim() || '',
82
77
  sessionId: context?.sessionId?.trim() || '',
83
78
  parentChatroomId: context?.parentChatroomId?.trim() || '',
84
- missionId: context?.missionId?.trim() || '',
85
79
  taskId: context?.taskId?.trim() || '',
86
80
  autoStart: context?.autoStart !== false,
87
81
  createTranscript: context?.createTranscript !== false,
@@ -108,19 +102,16 @@ export function StructuredSessionLauncher({
108
102
  const templatesQuery = useProtocolTemplatesQuery({ enabled: open })
109
103
  const agentsQuery = useAgentsQuery({ enabled: open })
110
104
  const chatroomsQuery = useChatroomsQuery({ enabled: open && allowContextSelection })
111
- const missionsQuery = useMissionsQuery({ enabled: open && allowContextSelection, limit: 80 })
112
105
  const tasksQuery = useTasksQuery({ includeArchived: true, enabled: open && allowContextSelection })
113
106
  const createRunMutation = useCreateProtocolRunMutation()
114
107
  const templates = templatesQuery.data ?? []
115
108
  const agents = agentsQuery.data ?? {}
116
109
  const chatrooms = chatroomsQuery.data ?? {}
117
- const missions = missionsQuery.data ?? []
118
110
  const tasks = tasksQuery.data ?? {}
119
111
  const loading = (
120
112
  templatesQuery.isLoading
121
113
  || agentsQuery.isLoading
122
114
  || chatroomsQuery.isLoading
123
- || missionsQuery.isLoading
124
115
  || tasksQuery.isLoading
125
116
  )
126
117
  const breakoutMode = variant === 'breakout'
@@ -145,7 +136,6 @@ export function StructuredSessionLauncher({
145
136
  () => [
146
137
  contextChip('Chat', initialContext?.sessionLabel),
147
138
  contextChip('Chatroom', initialContext?.parentChatroomLabel),
148
- contextChip('Mission', initialContext?.missionLabel),
149
139
  contextChip('Task', initialContext?.taskLabel),
150
140
  ].filter(Boolean) as Array<{ label: string; value: string }>,
151
141
  [initialContext],
@@ -180,7 +170,6 @@ export function StructuredSessionLauncher({
180
170
  facilitatorAgentId: form.facilitatorAgentId || null,
181
171
  sessionId: form.sessionId || null,
182
172
  parentChatroomId: form.parentChatroomId || null,
183
- missionId: form.missionId || null,
184
173
  taskId: form.taskId || null,
185
174
  autoStart: form.autoStart,
186
175
  createTranscript: form.createTranscript,
@@ -413,16 +402,6 @@ export function StructuredSessionLauncher({
413
402
  <option key={chatroom.id} value={chatroom.id}>{chatroom.name}</option>
414
403
  ))}
415
404
  </select>
416
- <select
417
- value={form.missionId}
418
- onChange={(event) => setForm((current) => ({ ...current, missionId: event.target.value }))}
419
- className="rounded-[12px] border border-white/[0.06] bg-black/20 px-3 py-2.5 text-[14px] text-text outline-none"
420
- >
421
- <option value="">No linked mission</option>
422
- {missions.map((mission) => (
423
- <option key={mission.id} value={mission.id}>{mission.objective}</option>
424
- ))}
425
- </select>
426
405
  <select
427
406
  value={form.taskId}
428
407
  onChange={(event) => setForm((current) => ({ ...current, taskId: event.target.value }))}
@@ -26,6 +26,7 @@ export const CONNECTOR_PLATFORM_META: Record<ConnectorPlatform, { label: string;
26
26
  email: { label: 'Email', color: '#EA4335' },
27
27
  webchat: { label: 'Web Chat', color: '#0EA5E9' },
28
28
  mockmail: { label: 'MockMail', color: '#7C3AED' },
29
+ swarmdock: { label: 'SwarmDock', color: '#F59E0B' },
29
30
  }
30
31
 
31
32
  const FALLBACK_CONNECTOR_PLATFORM_META = { label: 'Connector', color: '#64748B' } as const
@@ -1,9 +1,8 @@
1
1
  'use client'
2
2
 
3
3
  import { useState, useCallback, useEffect } from 'react'
4
- import { useRouter } from 'next/navigation'
5
4
  import { useAppStore } from '@/stores/use-app-store'
6
- import { getMissionPath, useNavigate } from '@/lib/app/navigation'
5
+ import { useNavigate } from '@/lib/app/navigation'
7
6
  import { useUpdateTaskMutation } from '@/features/tasks/queries'
8
7
  import { ConfirmDialog } from '@/components/shared/confirm-dialog'
9
8
  import { AgentAvatar } from '@/components/agents/agent-avatar'
@@ -36,7 +35,6 @@ export function TaskCard({
36
35
  const setTaskSheetOpen = useAppStore((s) => s.setTaskSheetOpen)
37
36
  const setCurrentAgent = useAppStore((s) => s.setCurrentAgent)
38
37
  const navigateTo = useNavigate()
39
- const router = useRouter()
40
38
  const updateTaskMutation = useUpdateTaskMutation()
41
39
  const [dragging, setDragging] = useState(false)
42
40
  const [confirmArchive, setConfirmArchive] = useState(false)
@@ -175,38 +173,10 @@ export function TaskCard({
175
173
  <p className="text-[12px] text-text-3 line-clamp-2 mb-3">{task.description}</p>
176
174
  )}
177
175
 
178
- {task.missionSummary && (
176
+ {task.objective && (
179
177
  <div className="mb-3 rounded-[12px] border border-white/[0.06] bg-white/[0.02] px-3 py-2">
180
- <div className="mb-1 flex items-center justify-between gap-2">
181
- <span className="text-[10px] font-700 uppercase tracking-[0.08em] text-text-3/68">Mission</span>
182
- <div className="flex items-center gap-2">
183
- <span className={`rounded-full px-2 py-0.5 text-[10px] font-700 uppercase tracking-[0.08em] ${
184
- task.missionSummary.status === 'waiting' || task.missionSummary.status === 'failed' || task.missionSummary.status === 'cancelled'
185
- ? 'bg-amber-500/12 text-amber-300'
186
- : task.missionSummary.status === 'completed'
187
- ? 'bg-emerald-500/12 text-emerald-300'
188
- : 'bg-sky-500/12 text-sky-300'
189
- }`}>
190
- {task.missionSummary.status}
191
- </span>
192
- <button
193
- type="button"
194
- onClick={(event) => {
195
- event.stopPropagation()
196
- router.push(getMissionPath(task.missionSummary?.id || null))
197
- }}
198
- className="rounded-[8px] border border-white/[0.08] px-2 py-1 text-[10px] font-700 uppercase tracking-[0.08em] text-text-2 transition-colors hover:bg-white/[0.05]"
199
- >
200
- Open
201
- </button>
202
- </div>
203
- </div>
204
- <div className="text-[12px] font-600 text-text line-clamp-2">{task.missionSummary.objective}</div>
205
- {(task.missionSummary.waitingReason || task.missionSummary.currentStep) && (
206
- <div className="mt-1 text-[11px] text-text-3/70 line-clamp-2">
207
- {task.missionSummary.waitingReason || task.missionSummary.currentStep}
208
- </div>
209
- )}
178
+ <span className="text-[10px] font-700 uppercase tracking-[0.08em] text-text-3/68">Objective</span>
179
+ <div className="text-[12px] font-600 text-text line-clamp-2 mt-1">{task.objective}</div>
210
180
  </div>
211
181
  )}
212
182
 
@@ -15,7 +15,6 @@ import {
15
15
  import { useProjectsQuery } from '@/features/projects/queries'
16
16
  import { useAppSettingsQuery } from '@/features/settings/queries'
17
17
  import { useProtocolRunsQuery } from '@/features/protocols/queries'
18
- import { getMissionPath } from '@/lib/app/navigation'
19
18
  import { BottomSheet } from '@/components/shared/bottom-sheet'
20
19
  import { AgentPickerList } from '@/components/shared/agent-picker-list'
21
20
  import { DirBrowser } from '@/components/shared/dir-browser'
@@ -342,28 +341,11 @@ export function TaskSheet() {
342
341
  </div>
343
342
  )}
344
343
 
345
- {editing.missionSummary && (
344
+ {editing.objective && (
346
345
  <div className="mb-8">
347
- <SectionLabel>Mission</SectionLabel>
346
+ <SectionLabel>Objective</SectionLabel>
348
347
  <div className="rounded-[14px] border border-white/[0.06] bg-surface px-4 py-3">
349
- <div className="mb-2 flex items-center justify-between gap-3">
350
- <div className="text-[14px] font-600 text-text">{editing.missionSummary.objective}</div>
351
- <div className="flex items-center gap-2">
352
- <span className="rounded-full bg-sky-500/10 px-2.5 py-1 text-[10px] font-700 uppercase tracking-[0.08em] text-sky-300">
353
- {editing.missionSummary.status}
354
- </span>
355
- <button
356
- type="button"
357
- onClick={() => router.push(getMissionPath(editing.missionSummary?.id || null))}
358
- className="rounded-[8px] border border-white/[0.08] px-2 py-1 text-[10px] font-700 uppercase tracking-[0.08em] text-text-2 transition-colors hover:bg-white/[0.05]"
359
- >
360
- Open
361
- </button>
362
- </div>
363
- </div>
364
- <div className="text-[12px] leading-[1.7] text-text-3/72">
365
- {editing.missionSummary.waitingReason || editing.missionSummary.currentStep || 'Mission linked to this task.'}
366
- </div>
348
+ <div className="text-[14px] font-600 text-text">{editing.objective}</div>
367
349
  </div>
368
350
  </div>
369
351
  )}
@@ -691,23 +673,11 @@ export function TaskSheet() {
691
673
  />
692
674
  </div>
693
675
 
694
- {editing?.missionSummary && (
676
+ {editing?.objective && (
695
677
  <div className="mb-8">
696
- <SectionLabel>Mission</SectionLabel>
678
+ <SectionLabel>Objective</SectionLabel>
697
679
  <div className="rounded-[14px] border border-white/[0.06] bg-surface px-4 py-3 text-[12px] leading-[1.7] text-text-3/75">
698
- <div className="flex items-center justify-between gap-3">
699
- <div className="font-600 text-text">{editing.missionSummary.objective}</div>
700
- <button
701
- type="button"
702
- onClick={() => router.push(getMissionPath(editing.missionSummary?.id || null))}
703
- className="rounded-[8px] border border-white/[0.08] px-2 py-1 text-[10px] font-700 uppercase tracking-[0.08em] text-text-2 transition-colors hover:bg-white/[0.05]"
704
- >
705
- Open
706
- </button>
707
- </div>
708
- <div className="mt-1">
709
- {editing.missionSummary.waitingReason || editing.missionSummary.currentStep || `Status: ${editing.missionSummary.status}`}
710
- </div>
680
+ <div className="font-600 text-text">{editing.objective}</div>
711
681
  </div>
712
682
  </div>
713
683
  )}