@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
@@ -1,267 +0,0 @@
1
- 'use client'
2
-
3
- import { useEffect, useState, useCallback } from 'react'
4
- import ReactMarkdown from 'react-markdown'
5
- import { useWs } from '@/hooks/use-ws'
6
- import { api } from '@/lib/app/api-client'
7
- import { normalizeCanvasContent } from '@/lib/canvas-content'
8
- import type { CanvasContent, CanvasDocument } from '@/types'
9
-
10
- interface CanvasPanelProps {
11
- sessionId: string
12
- agentName?: string
13
- onClose: () => void
14
- }
15
-
16
- const THEME_STYLES: Record<NonNullable<CanvasDocument['theme']>, { accent: string; chip: string }> = {
17
- slate: { accent: 'text-sky-300', chip: 'bg-sky-500/10 text-sky-300 border-sky-500/20' },
18
- sky: { accent: 'text-sky-300', chip: 'bg-sky-500/10 text-sky-300 border-sky-500/20' },
19
- emerald: { accent: 'text-emerald-300', chip: 'bg-emerald-500/10 text-emerald-300 border-emerald-500/20' },
20
- amber: { accent: 'text-amber-300', chip: 'bg-amber-500/10 text-amber-300 border-amber-500/20' },
21
- rose: { accent: 'text-rose-300', chip: 'bg-rose-500/10 text-rose-300 border-rose-500/20' },
22
- }
23
-
24
- function toneClass(tone?: string): string {
25
- switch (tone) {
26
- case 'positive': return 'text-emerald-300'
27
- case 'negative': return 'text-rose-300'
28
- case 'warning': return 'text-amber-300'
29
- default: return 'text-text'
30
- }
31
- }
32
-
33
- function intentClass(intent?: string): string {
34
- switch (intent) {
35
- case 'primary': return 'bg-sky-500 text-white border-sky-400/30'
36
- case 'success': return 'bg-emerald-500 text-white border-emerald-400/30'
37
- case 'danger': return 'bg-rose-500 text-white border-rose-400/30'
38
- default: return 'bg-white/[0.03] text-text-2 border-white/[0.08]'
39
- }
40
- }
41
-
42
- function StructuredCanvasView({ document }: { document: CanvasDocument }) {
43
- const theme = THEME_STYLES[document.theme || 'slate']
44
- return (
45
- <div className="h-full overflow-y-auto bg-bg px-5 py-5">
46
- <div className="max-w-4xl mx-auto space-y-4">
47
- {(document.title || document.subtitle) && (
48
- <div className="rounded-[18px] border border-white/[0.08] bg-white/[0.03] px-5 py-4">
49
- {document.title && <h2 className={`font-display text-[22px] font-700 tracking-[-0.03em] ${theme.accent}`}>{document.title}</h2>}
50
- {document.subtitle && <p className="mt-1 text-[13px] text-text-3/70">{document.subtitle}</p>}
51
- </div>
52
- )}
53
-
54
- {document.blocks.map((block, index) => {
55
- if (block.type === 'markdown') {
56
- return (
57
- <section key={`${block.type}-${index}`} className="rounded-[18px] border border-white/[0.08] bg-white/[0.03] px-5 py-4">
58
- {block.title && <div className={`mb-3 text-[11px] font-700 uppercase tracking-[0.08em] ${theme.accent}`}>{block.title}</div>}
59
- <div className="max-w-none text-[14px] leading-6 text-text-2/90 [&_h1]:font-display [&_h1]:text-[24px] [&_h1]:text-text [&_h2]:font-display [&_h2]:text-[20px] [&_h2]:text-text [&_h3]:font-display [&_h3]:text-[18px] [&_h3]:text-text [&_p]:my-3 [&_ul]:my-3 [&_ul]:pl-5 [&_li]:my-1 [&_code]:rounded [&_code]:bg-black/[0.2] [&_code]:px-1.5 [&_code]:py-0.5">
60
- <ReactMarkdown>{block.markdown}</ReactMarkdown>
61
- </div>
62
- </section>
63
- )
64
- }
65
-
66
- if (block.type === 'metrics') {
67
- return (
68
- <section key={`${block.type}-${index}`} className="rounded-[18px] border border-white/[0.08] bg-white/[0.03] px-5 py-4">
69
- {block.title && <div className={`mb-3 text-[11px] font-700 uppercase tracking-[0.08em] ${theme.accent}`}>{block.title}</div>}
70
- <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-3">
71
- {block.items.map((item) => (
72
- <div key={item.label} className="rounded-[14px] border border-white/[0.08] bg-black/[0.14] px-4 py-3">
73
- <div className="text-[11px] uppercase tracking-[0.08em] text-text-3/60">{item.label}</div>
74
- <div className={`mt-1 text-[24px] font-display font-700 tracking-[-0.03em] ${toneClass(item.tone)}`}>{item.value}</div>
75
- {item.detail && <div className="mt-1 text-[12px] text-text-3/65">{item.detail}</div>}
76
- </div>
77
- ))}
78
- </div>
79
- </section>
80
- )
81
- }
82
-
83
- if (block.type === 'cards') {
84
- return (
85
- <section key={`${block.type}-${index}`} className="rounded-[18px] border border-white/[0.08] bg-white/[0.03] px-5 py-4">
86
- {block.title && <div className={`mb-3 text-[11px] font-700 uppercase tracking-[0.08em] ${theme.accent}`}>{block.title}</div>}
87
- <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
88
- {block.items.map((item) => (
89
- <div key={item.title} className="rounded-[14px] border border-white/[0.08] bg-black/[0.14] px-4 py-3">
90
- <div className={`text-[15px] font-700 ${toneClass(item.tone)}`}>{item.title}</div>
91
- {item.body && <p className="mt-2 text-[13px] leading-6 text-text-2/85 whitespace-pre-wrap">{item.body}</p>}
92
- {item.meta && <div className="mt-3 text-[11px] text-text-3/60">{item.meta}</div>}
93
- </div>
94
- ))}
95
- </div>
96
- </section>
97
- )
98
- }
99
-
100
- if (block.type === 'table') {
101
- return (
102
- <section key={`${block.type}-${index}`} className="rounded-[18px] border border-white/[0.08] bg-white/[0.03] px-5 py-4 overflow-hidden">
103
- {block.title && <div className={`mb-3 text-[11px] font-700 uppercase tracking-[0.08em] ${theme.accent}`}>{block.title}</div>}
104
- <div className="overflow-x-auto rounded-[12px] border border-white/[0.08]">
105
- <table className="min-w-full text-left text-[13px]">
106
- <thead className="bg-black/[0.18]">
107
- <tr>
108
- {block.table.columns.map((column) => (
109
- <th key={column} className="px-3 py-2.5 font-700 text-text-2">{column}</th>
110
- ))}
111
- </tr>
112
- </thead>
113
- <tbody>
114
- {block.table.rows.map((row, rowIndex) => (
115
- <tr key={rowIndex} className="border-t border-white/[0.06]">
116
- {row.map((cell, cellIndex) => (
117
- <td key={cellIndex} className="px-3 py-2.5 text-text-3/80">{cell == null ? '—' : String(cell)}</td>
118
- ))}
119
- </tr>
120
- ))}
121
- </tbody>
122
- </table>
123
- </div>
124
- {block.table.caption && <div className="mt-2 text-[11px] text-text-3/60">{block.table.caption}</div>}
125
- </section>
126
- )
127
- }
128
-
129
- if (block.type === 'code') {
130
- return (
131
- <section key={`${block.type}-${index}`} className="rounded-[18px] border border-white/[0.08] bg-white/[0.03] px-5 py-4">
132
- {block.title && <div className={`mb-3 text-[11px] font-700 uppercase tracking-[0.08em] ${theme.accent}`}>{block.title}</div>}
133
- <pre className="overflow-x-auto rounded-[14px] border border-white/[0.08] bg-black/[0.25] p-4 text-[12px] leading-6 text-text-2">
134
- <code>{block.code}</code>
135
- </pre>
136
- {block.language && <div className={`mt-2 inline-flex rounded-full border px-2 py-1 text-[10px] font-700 uppercase tracking-[0.08em] ${theme.chip}`}>{block.language}</div>}
137
- </section>
138
- )
139
- }
140
-
141
- if (block.type === 'actions') {
142
- return (
143
- <section key={`${block.type}-${index}`} className="rounded-[18px] border border-white/[0.08] bg-white/[0.03] px-5 py-4">
144
- {block.title && <div className={`mb-3 text-[11px] font-700 uppercase tracking-[0.08em] ${theme.accent}`}>{block.title}</div>}
145
- <div className="flex flex-wrap gap-2">
146
- {block.items.map((item) => (
147
- item.href ? (
148
- <a
149
- key={item.label}
150
- href={item.href}
151
- target="_blank"
152
- rel="noreferrer"
153
- className={`inline-flex items-center rounded-[12px] border px-3 py-2 text-[12px] font-700 transition-all hover:brightness-110 ${intentClass(item.intent)}`}
154
- >
155
- {item.label}
156
- </a>
157
- ) : (
158
- <div key={item.label} className={`inline-flex items-center rounded-[12px] border px-3 py-2 text-[12px] font-700 ${intentClass(item.intent)}`}>
159
- {item.label}
160
- </div>
161
- )
162
- ))}
163
- </div>
164
- {block.items.some((item) => item.note) && (
165
- <div className="mt-3 space-y-1">
166
- {block.items.filter((item) => item.note).map((item) => (
167
- <div key={`${item.label}-note`} className="text-[11px] text-text-3/60">{item.label}: {item.note}</div>
168
- ))}
169
- </div>
170
- )}
171
- </section>
172
- )
173
- }
174
-
175
- return null
176
- })}
177
- </div>
178
- </div>
179
- )
180
- }
181
-
182
- export function CanvasPanel({ sessionId, agentName, onClose }: CanvasPanelProps) {
183
- const [content, setContent] = useState<CanvasContent>(null)
184
- const [loaded, setLoaded] = useState(false)
185
-
186
- const loadCanvas = useCallback(async () => {
187
- try {
188
- const res = await api<{ content: CanvasContent }>('GET', `/canvas/${sessionId}`)
189
- setContent(normalizeCanvasContent(res.content))
190
- } catch {
191
- setContent(null)
192
- } finally {
193
- setLoaded(true)
194
- }
195
- }, [sessionId])
196
-
197
- useEffect(() => { loadCanvas() }, [loadCanvas])
198
- useWs(`canvas:${sessionId}`, loadCanvas, 10_000)
199
-
200
- const header = (
201
- <div className="flex items-center gap-3 px-4 py-3 border-b border-white/[0.06] shrink-0">
202
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" className="text-accent-bright shrink-0">
203
- <rect x="2" y="3" width="20" height="14" rx="2" /><path d="M8 21h8" /><path d="M12 17v4" />
204
- </svg>
205
- <span className="text-[13px] font-600 text-text flex-1 truncate">
206
- Canvas{agentName ? ` — ${agentName}` : ''}
207
- </span>
208
- <button
209
- onClick={loadCanvas}
210
- className="p-1.5 rounded-[6px] hover:bg-white/[0.06] transition-colors cursor-pointer border-none bg-transparent text-text-3 hover:text-text-2"
211
- title="Refresh"
212
- >
213
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
214
- <polyline points="23 4 23 10 17 10" /><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10" />
215
- </svg>
216
- </button>
217
- <button
218
- onClick={onClose}
219
- className="p-1.5 rounded-[6px] hover:bg-white/[0.06] transition-colors cursor-pointer border-none bg-transparent text-text-3 hover:text-text-2"
220
- title="Close canvas"
221
- >
222
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
223
- <path d="M18 6L6 18M6 6l12 12" />
224
- </svg>
225
- </button>
226
- </div>
227
- )
228
-
229
- if (!loaded) {
230
- return (
231
- <div className="flex flex-col h-full border-l border-white/[0.06] bg-bg min-w-[400px]">
232
- {header}
233
- <div className="flex-1 flex items-center justify-center">
234
- <div className="text-center">
235
- <div className="w-8 h-8 rounded-full border-2 border-text-3/20 border-t-accent-bright animate-spin mx-auto mb-3" />
236
- <span className="text-[13px] text-text-3">Loading canvas...</span>
237
- </div>
238
- </div>
239
- </div>
240
- )
241
- }
242
-
243
- return (
244
- <div className="flex flex-col h-full border-l border-white/[0.06] bg-bg min-w-[400px]">
245
- {header}
246
- <div className="flex-1 overflow-hidden">
247
- {!content ? (
248
- <div className="h-full flex items-center justify-center text-center px-6">
249
- <div>
250
- <div className="text-[14px] font-600 text-text-2">No canvas content yet</div>
251
- <p className="mt-1 text-[12px] text-text-3/60">Agents can present HTML or structured documents here.</p>
252
- </div>
253
- </div>
254
- ) : typeof content === 'string' ? (
255
- <iframe
256
- sandbox="allow-scripts allow-same-origin"
257
- srcDoc={content}
258
- className="w-full h-full border-none bg-white"
259
- title="Agent Canvas"
260
- />
261
- ) : (
262
- <StructuredCanvasView document={content} />
263
- )}
264
- </div>
265
- </div>
266
- )
267
- }
@@ -1,107 +0,0 @@
1
- 'use client'
2
-
3
- import { useState, useCallback } from 'react'
4
- import { api } from '@/lib/app/api-client'
5
- import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog'
6
- import type { WalletTransaction } from '@/types'
7
- import { formatWalletAmount, getWalletAssetSymbol, getWalletAtomicAmount } from '@/lib/wallet/wallet'
8
- import { errorMessage } from '@/lib/shared-utils'
9
-
10
- interface WalletApprovalDialogProps {
11
- transaction: WalletTransaction
12
- walletAddress: string
13
- onClose: () => void
14
- onResolved: () => void
15
- }
16
-
17
- export function WalletApprovalDialog({ transaction, walletAddress, onClose, onResolved }: WalletApprovalDialogProps) {
18
- const [submitting, setSubmitting] = useState(false)
19
- const [error, setError] = useState<string | null>(null)
20
-
21
- const handleDecision = useCallback(async (decision: 'approve' | 'deny') => {
22
- setSubmitting(true)
23
- setError(null)
24
- try {
25
- await api('POST', `/wallets/${transaction.walletId}/approve`, {
26
- transactionId: transaction.id,
27
- decision,
28
- })
29
- onResolved()
30
- onClose()
31
- } catch (err: unknown) {
32
- setError(errorMessage(err))
33
- } finally {
34
- setSubmitting(false)
35
- }
36
- }, [transaction, onResolved, onClose])
37
-
38
- const amountFormatted = formatWalletAmount(transaction.chain, getWalletAtomicAmount(transaction), { minFractionDigits: 4, maxFractionDigits: 6 })
39
- const symbol = getWalletAssetSymbol(transaction.chain)
40
-
41
- return (
42
- <Dialog open onOpenChange={(nextOpen) => { if (!nextOpen) onClose() }}>
43
- <DialogContent className="sm:max-w-[460px] rounded-[20px] border-white/[0.08] bg-surface/95 p-0 shadow-[0_24px_80px_rgba(0,0,0,0.6)]">
44
- <div className="p-6 space-y-5">
45
- <DialogHeader className="text-left">
46
- <div className="flex items-center gap-2">
47
- <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" className="text-amber-400">
48
- <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" />
49
- <line x1="12" y1="9" x2="12" y2="13" /><line x1="12" y1="17" x2="12.01" y2="17" />
50
- </svg>
51
- <DialogTitle className="font-display text-[16px] font-700 tracking-[-0.02em] text-text-1">
52
- Transaction Approval
53
- </DialogTitle>
54
- </div>
55
- <DialogDescription className="text-[12px] leading-relaxed text-text-3">
56
- Crypto transactions are irreversible. Verify the recipient address carefully before approving.
57
- </DialogDescription>
58
- </DialogHeader>
59
-
60
- <div className="rounded-[14px] border border-white/[0.06] bg-black/20 p-4 space-y-3">
61
- <div className="flex items-center justify-between">
62
- <span className="text-[11px] uppercase tracking-wide text-text-3/70">Amount</span>
63
- <span className="text-[16px] font-600 text-text-1">{amountFormatted} {symbol}</span>
64
- </div>
65
- <div>
66
- <span className="mb-1 block text-[11px] uppercase tracking-wide text-text-3/70">From</span>
67
- <code className="text-[10px] text-text-3 font-mono break-all">{walletAddress}</code>
68
- </div>
69
- <div>
70
- <span className="mb-1 block text-[11px] uppercase tracking-wide text-text-3/70">To</span>
71
- <code className="text-[10px] text-text-3 font-mono break-all">{transaction.toAddress}</code>
72
- </div>
73
- {transaction.memo && (
74
- <div>
75
- <span className="mb-1 block text-[11px] uppercase tracking-wide text-text-3/70">Reason</span>
76
- <p className="text-[12px] text-text-2">{transaction.memo}</p>
77
- </div>
78
- )}
79
- </div>
80
-
81
- {error && <p className="text-[11px] text-red-400">{error}</p>}
82
-
83
- <DialogFooter>
84
- <button
85
- type="button"
86
- onClick={() => handleDecision('deny')}
87
- disabled={submitting}
88
- className="flex-1 rounded-[12px] border border-white/[0.08] bg-surface px-4 py-2.5 text-[12px] font-600 text-text-3 transition-colors hover:border-red-400/30 hover:text-red-400 disabled:opacity-50"
89
- style={{ fontFamily: 'inherit' }}
90
- >
91
- Deny
92
- </button>
93
- <button
94
- type="button"
95
- onClick={() => handleDecision('approve')}
96
- disabled={submitting}
97
- className="flex-1 rounded-[12px] bg-accent px-4 py-2.5 text-[12px] font-600 text-white transition-all hover:brightness-110 disabled:opacity-50"
98
- style={{ fontFamily: 'inherit' }}
99
- >
100
- {submitting ? 'Processing...' : 'Approve & Send'}
101
- </button>
102
- </DialogFooter>
103
- </div>
104
- </DialogContent>
105
- </Dialog>
106
- )
107
- }