ethagent 3.3.3 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (322) hide show
  1. package/.claude-plugin/marketplace.json +11 -0
  2. package/.claude-plugin/plugin.json +35 -0
  3. package/LICENSE +1 -1
  4. package/README.md +64 -104
  5. package/commands/ethagent.md +40 -0
  6. package/package.json +16 -16
  7. package/src/app/keybindings/KeybindingProvider.tsx +1 -6
  8. package/src/app/keybindings/types.ts +1 -6
  9. package/src/cli/ResetConfirmView.tsx +54 -53
  10. package/src/cli/demo.ts +86 -0
  11. package/src/cli/hookIo.ts +45 -0
  12. package/src/cli/main.tsx +94 -123
  13. package/src/cli/memoryGuard.ts +49 -0
  14. package/src/cli/reset.ts +28 -70
  15. package/src/cli/sessionStart.ts +33 -0
  16. package/src/cli/status.ts +46 -0
  17. package/src/cli/sync.ts +167 -0
  18. package/src/cli/syncAdapters/claude-code.ts +86 -0
  19. package/src/cli/syncAdapters/codex.ts +66 -0
  20. package/src/cli/syncAdapters/index.ts +45 -0
  21. package/src/cli/syncAdapters/managedBlock.ts +175 -0
  22. package/src/cli/syncAdapters/shared.ts +63 -0
  23. package/src/identity/continuity/envelopeParse.ts +20 -1
  24. package/src/identity/continuity/publicSkills.ts +3 -1
  25. package/src/identity/continuity/skills/publicSkillsSync.ts +2 -1
  26. package/src/identity/continuity/skills/scaffold.ts +5 -2
  27. package/src/identity/continuity/snapshots.ts +12 -5
  28. package/src/identity/continuity/storage/defaults.ts +20 -19
  29. package/src/identity/continuity/storage/status.ts +1 -1
  30. package/src/identity/ens/ensLookup/constants.ts +1 -1
  31. package/src/identity/manager/IdentityManager.tsx +33 -0
  32. package/src/identity/{hub → manager}/OperationalRoutes.tsx +37 -18
  33. package/src/identity/{hub → manager}/Routes.tsx +48 -34
  34. package/src/identity/{hub → manager}/continuity/ContinuityDashboardScreen.tsx +9 -19
  35. package/src/identity/{hub → manager}/continuity/RebackupStorageScreen.tsx +3 -3
  36. package/src/identity/manager/continuity/RecoveryConfirmScreen.tsx +102 -0
  37. package/src/identity/{hub → manager}/continuity/SavePromptScreen.tsx +2 -3
  38. package/src/identity/{hub → manager}/continuity/completion.ts +1 -1
  39. package/src/identity/{hub → manager}/continuity/effects.ts +1 -1
  40. package/src/identity/{hub → manager}/continuity/skills/DeleteSkillConfirmScreen.tsx +2 -2
  41. package/src/identity/{hub → manager}/continuity/skills/NewSkillScreen.tsx +0 -5
  42. package/src/identity/{hub → manager}/continuity/skills/NewSkillVisibilityScreen.tsx +4 -4
  43. package/src/identity/{hub → manager}/continuity/skills/SkillActionsScreen.tsx +6 -22
  44. package/src/identity/{hub → manager}/continuity/skills/SkillsTreeScreen.tsx +5 -17
  45. package/src/identity/{hub → manager}/continuity/snapshot.ts +1 -1
  46. package/src/identity/{hub → manager}/continuity/vault.ts +1 -1
  47. package/src/identity/{hub → manager}/create/CreateFlow.tsx +59 -32
  48. package/src/identity/{hub → manager}/create/effects.ts +19 -10
  49. package/src/identity/manager/create/importScan.ts +122 -0
  50. package/src/identity/{hub → manager}/custody/CustodyEditFlow.tsx +17 -61
  51. package/src/identity/{hub → manager}/custody/actions.ts +1 -15
  52. package/src/identity/{hub → manager}/custody/routes.tsx +20 -40
  53. package/src/identity/{hub → manager}/custody/transactions.ts +1 -0
  54. package/src/identity/{hub → manager}/custody/types.ts +1 -2
  55. package/src/identity/{hub → manager}/custody/useCustodyEffects.ts +1 -1
  56. package/src/identity/{hub → manager}/ens/EnsEditAdvancedScreens.tsx +2 -2
  57. package/src/identity/{hub → manager}/ens/EnsEditMaintenanceScreens.tsx +12 -23
  58. package/src/identity/{hub → manager}/ens/EnsEditReviewScreens.tsx +18 -42
  59. package/src/identity/{hub → manager}/ens/EnsEditRunners.tsx +1 -1
  60. package/src/identity/{hub → manager}/ens/EnsEditShared.tsx +0 -2
  61. package/src/identity/{hub → manager}/ens/EnsEditSimpleScreens.tsx +10 -19
  62. package/src/identity/{hub → manager}/ens/EnsFlow.tsx +133 -41
  63. package/src/identity/{hub → manager}/ens/EnsOperatorWalletsScreen.tsx +14 -19
  64. package/src/identity/{hub → manager}/ens/editCopy.ts +1 -14
  65. package/src/identity/{hub → manager}/profile/EditProfileFlow.tsx +99 -66
  66. package/src/identity/{hub → manager}/profile/effects.ts +1 -3
  67. package/src/identity/{hub → manager}/profile/operatorSave.ts +1 -1
  68. package/src/identity/{hub → manager}/profile/state.ts +1 -1
  69. package/src/identity/{hub/identityHubReducer.ts → manager/reducer.ts} +25 -26
  70. package/src/identity/{hub → manager}/restore/RestoreFlow.tsx +16 -24
  71. package/src/identity/{hub → manager}/restore/apply.ts +1 -1
  72. package/src/identity/{hub → manager}/restore/auth.ts +1 -1
  73. package/src/identity/{hub → manager}/restore/discover.ts +1 -1
  74. package/src/identity/{hub → manager}/restore/fetch.ts +1 -1
  75. package/src/identity/{hub → manager}/restore/restoreAdmin.ts +1 -1
  76. package/src/identity/{hub → manager}/restore/useRestoreEffects.ts +2 -9
  77. package/src/identity/{hub → manager}/settings/StorageCredentialScreen.tsx +10 -25
  78. package/src/identity/{hub → manager}/shared/components/DetailsScreen.tsx +5 -7
  79. package/src/identity/{hub → manager}/shared/components/ErrorScreen.tsx +6 -10
  80. package/src/identity/{hub → manager}/shared/components/FlowTimeline.tsx +4 -3
  81. package/src/identity/{hub → manager}/shared/components/IdentitySummary.tsx +19 -59
  82. package/src/identity/manager/shared/components/LazyMenu.tsx +147 -0
  83. package/src/identity/manager/shared/components/MenuScreen.tsx +220 -0
  84. package/src/identity/manager/shared/components/OperationCompleteScreen.tsx +28 -0
  85. package/src/identity/{hub → manager}/shared/components/UnlinkedIdentityScreen.tsx +9 -10
  86. package/src/identity/{hub → manager}/shared/components/WalletApprovalScreen.tsx +1 -2
  87. package/src/identity/manager/shared/components/Wordmark.tsx +54 -0
  88. package/src/identity/{hub → manager}/shared/components/menuFlagsFromReconciliation.ts +39 -15
  89. package/src/identity/{hub → manager}/shared/effects/profilePrep.ts +1 -1
  90. package/src/identity/manager/shared/effects/types.ts +30 -0
  91. package/src/identity/{hub → manager}/shared/model/copy.ts +0 -4
  92. package/src/identity/{hub → manager}/shared/model/errors.ts +32 -3
  93. package/src/identity/{hub → manager}/shared/model/network.ts +2 -2
  94. package/src/identity/{hub → manager}/shared/reconciliation/agentReconciliation/hook.ts +5 -0
  95. package/src/identity/{hub → manager}/shared/reconciliation/agentReconciliation/run.ts +1 -1
  96. package/src/identity/{hub/shared/reconciliation/useAgentReconciliation.ts → manager/shared/reconciliation/index.ts} +6 -0
  97. package/src/identity/{hub → manager}/shared/utils.ts +6 -10
  98. package/src/identity/{hub → manager}/transfer/TokenTransferFlow.tsx +3 -3
  99. package/src/identity/{hub → manager}/transfer/TokenTransferScreens.tsx +4 -10
  100. package/src/identity/{hub → manager}/transfer/effects.ts +1 -1
  101. package/src/identity/{hub → manager}/types.ts +5 -6
  102. package/src/identity/{hub/useIdentityHubContinuity.ts → manager/useContinuity.ts} +59 -27
  103. package/src/identity/{hub/useIdentityHubController.ts → manager/useController.ts} +38 -35
  104. package/src/identity/{hub/useIdentityHubSideEffects.ts → manager/useSideEffects.ts} +40 -4
  105. package/src/identity/registry/erc8004/discovery.ts +3 -17
  106. package/src/identity/registry/erc8004/utils.ts +1 -1
  107. package/src/identity/storage/ipfs.ts +21 -1
  108. package/src/identity/wallet/browserWallet/html.ts +10 -2
  109. package/src/identity/wallet/browserWallet/http.ts +18 -0
  110. package/src/identity/wallet/browserWallet/requestServer.ts +5 -1
  111. package/src/identity/wallet/browserWallet/requests.ts +10 -28
  112. package/src/identity/wallet/browserWallet/session.ts +26 -33
  113. package/src/identity/wallet/browserWallet/validation.ts +14 -0
  114. package/src/identity/wallet/browserWallet/walletPageSource.ts +22 -40
  115. package/src/identity/wallet/page/boot.ts +43 -0
  116. package/src/identity/wallet/page/config.ts +59 -0
  117. package/src/identity/wallet/page/constants.ts +12 -0
  118. package/src/identity/wallet/page/copy.ts +47 -68
  119. package/src/identity/wallet/page/css.ts +638 -0
  120. package/src/identity/wallet/page/{errorView.ts → errors.ts} +5 -14
  121. package/src/identity/wallet/page/{controller.ts → flow.ts} +4 -71
  122. package/src/identity/wallet/page/markup.ts +44 -34
  123. package/src/identity/wallet/page/{walletProvider.ts → provider.ts} +0 -3
  124. package/src/identity/wallet/page/resize.ts +95 -0
  125. package/src/identity/wallet/page/state.ts +135 -8
  126. package/src/identity/wallet/page/timeline.ts +161 -0
  127. package/src/identity/wallet/page/view.ts +22 -302
  128. package/src/storage/config.ts +30 -80
  129. package/src/storage/reset.ts +31 -0
  130. package/src/storage/secrets.ts +1 -16
  131. package/src/ui/Select.tsx +27 -5
  132. package/src/ui/Spinner.tsx +16 -15
  133. package/src/ui/Surface.tsx +21 -17
  134. package/src/ui/TextArea.tsx +173 -0
  135. package/src/ui/TextInput.tsx +31 -133
  136. package/src/ui/theme.ts +22 -13
  137. package/src/utils/clipboard.ts +0 -140
  138. package/src/app/FirstRun.tsx +0 -577
  139. package/src/app/FirstRunTimeline.tsx +0 -51
  140. package/src/app/firstRunConfig.ts +0 -26
  141. package/src/app/hooks/useCancelRequest.ts +0 -22
  142. package/src/app/hooks/useDoublePress.ts +0 -46
  143. package/src/app/hooks/useExitOnCtrlC.ts +0 -36
  144. package/src/auth/openaiOAuth/credentials.ts +0 -47
  145. package/src/auth/openaiOAuth/crypto.ts +0 -23
  146. package/src/auth/openaiOAuth/index.ts +0 -238
  147. package/src/auth/openaiOAuth/landingPage.ts +0 -116
  148. package/src/auth/openaiOAuth/listener.ts +0 -151
  149. package/src/auth/openaiOAuth/refresh.ts +0 -70
  150. package/src/auth/openaiOAuth/shared.ts +0 -115
  151. package/src/chat/ChatBottomPane.tsx +0 -296
  152. package/src/chat/ChatScreen.tsx +0 -1685
  153. package/src/chat/ConversationStack.tsx +0 -56
  154. package/src/chat/MessageList.tsx +0 -638
  155. package/src/chat/SessionStatus.tsx +0 -53
  156. package/src/chat/chatEnvironment.ts +0 -16
  157. package/src/chat/chatScreenUtils.ts +0 -194
  158. package/src/chat/chatSessionState.ts +0 -146
  159. package/src/chat/chatTurnContext.ts +0 -50
  160. package/src/chat/chatTurnOrchestrator.ts +0 -603
  161. package/src/chat/chatTurnRows.ts +0 -64
  162. package/src/chat/commands.ts +0 -494
  163. package/src/chat/continuityEditReview.ts +0 -42
  164. package/src/chat/display/DiffView.tsx +0 -193
  165. package/src/chat/display/SyntaxText.tsx +0 -192
  166. package/src/chat/display/toolCallDisplay.ts +0 -103
  167. package/src/chat/display/toolResultDisplay.ts +0 -19
  168. package/src/chat/input/ChatInput.tsx +0 -625
  169. package/src/chat/input/chatInputHelpers.ts +0 -62
  170. package/src/chat/input/chatInputState.ts +0 -247
  171. package/src/chat/input/chatPaste.ts +0 -49
  172. package/src/chat/input/imageRefs.ts +0 -30
  173. package/src/chat/input/inputRendering.tsx +0 -93
  174. package/src/chat/input/textCursor.ts +0 -212
  175. package/src/chat/messageMarkdown.ts +0 -220
  176. package/src/chat/messageRows.ts +0 -43
  177. package/src/chat/planImplementation.ts +0 -62
  178. package/src/chat/slashCommandHandlers.ts +0 -122
  179. package/src/chat/slashCommandViews.ts +0 -120
  180. package/src/chat/transcript/TranscriptView.tsx +0 -184
  181. package/src/chat/transcript/transcriptViewport.ts +0 -295
  182. package/src/chat/views/ContextLimitView.tsx +0 -95
  183. package/src/chat/views/ContinuityEditReviewView.tsx +0 -50
  184. package/src/chat/views/CopyPicker.tsx +0 -50
  185. package/src/chat/views/PermissionPrompt.tsx +0 -156
  186. package/src/chat/views/PermissionsView.tsx +0 -165
  187. package/src/chat/views/PlanApprovalView.tsx +0 -91
  188. package/src/chat/views/ResumeView.tsx +0 -273
  189. package/src/chat/views/RewindView.tsx +0 -412
  190. package/src/cli/preview.tsx +0 -14
  191. package/src/cli/updateNotice.ts +0 -54
  192. package/src/identity/continuity/privateEdit/apply.ts +0 -170
  193. package/src/identity/continuity/privateEdit/diff.ts +0 -6
  194. package/src/identity/continuity/privateEdit/files.ts +0 -23
  195. package/src/identity/continuity/privateEdit/types.ts +0 -28
  196. package/src/identity/continuity/privateEdit.ts +0 -46
  197. package/src/identity/hub/IdentityHub.tsx +0 -14
  198. package/src/identity/hub/continuity/RecoveryConfirmScreen.tsx +0 -104
  199. package/src/identity/hub/ens/effects.ts +0 -218
  200. package/src/identity/hub/shared/components/MenuScreen.tsx +0 -241
  201. package/src/identity/hub/shared/effects/types.ts +0 -53
  202. package/src/identity/hub/shared/reconciliation/index.ts +0 -14
  203. package/src/identity/wallet/page/grainient.ts +0 -278
  204. package/src/identity/wallet/page/html.ts +0 -28
  205. package/src/identity/wallet/page/styles/base.ts +0 -259
  206. package/src/identity/wallet/page/styles/components.ts +0 -262
  207. package/src/identity/wallet/page/styles/index.ts +0 -5
  208. package/src/identity/wallet/page/styles/responsive.ts +0 -247
  209. package/src/identity/wallet/page.tsx +0 -38
  210. package/src/mcp/approvals.ts +0 -113
  211. package/src/mcp/config.ts +0 -235
  212. package/src/mcp/manager.ts +0 -482
  213. package/src/mcp/managerHelpers.ts +0 -70
  214. package/src/mcp/names.ts +0 -19
  215. package/src/mcp/output.ts +0 -96
  216. package/src/models/ModelPicker.tsx +0 -1009
  217. package/src/models/catalog.ts +0 -327
  218. package/src/models/huggingface.ts +0 -712
  219. package/src/models/huggingfaceStorage.ts +0 -136
  220. package/src/models/llamacpp.ts +0 -848
  221. package/src/models/llamacppCommands.ts +0 -44
  222. package/src/models/llamacppConfig.ts +0 -34
  223. package/src/models/llamacppDiscovery.ts +0 -176
  224. package/src/models/llamacppOutput.ts +0 -65
  225. package/src/models/llamacppPreflight.ts +0 -158
  226. package/src/models/modelDisplay.ts +0 -180
  227. package/src/models/modelPickerCatalogFlow.ts +0 -56
  228. package/src/models/modelPickerCredentials.ts +0 -166
  229. package/src/models/modelPickerData.ts +0 -41
  230. package/src/models/modelPickerDisplay.tsx +0 -132
  231. package/src/models/modelPickerHfFlow.ts +0 -192
  232. package/src/models/modelPickerLocalRunnerFlow.ts +0 -115
  233. package/src/models/modelPickerOptions.ts +0 -457
  234. package/src/models/modelPickerTypes.ts +0 -69
  235. package/src/models/modelPickerUninstallFlow.ts +0 -48
  236. package/src/models/modelPickerViewHelpers.ts +0 -174
  237. package/src/models/modelRecommendation.ts +0 -139
  238. package/src/models/providerDisplay.ts +0 -16
  239. package/src/models/runtimeDetection.ts +0 -81
  240. package/src/models/uncensoredCatalog.ts +0 -86
  241. package/src/providers/anthropic.ts +0 -290
  242. package/src/providers/contracts.ts +0 -71
  243. package/src/providers/errors.ts +0 -80
  244. package/src/providers/gemini.ts +0 -391
  245. package/src/providers/openai-chat.ts +0 -474
  246. package/src/providers/openai-responses-format.ts +0 -177
  247. package/src/providers/openai-responses.ts +0 -306
  248. package/src/providers/openaiChatWire.ts +0 -124
  249. package/src/providers/registry.ts +0 -120
  250. package/src/providers/retry.ts +0 -58
  251. package/src/providers/sse.ts +0 -93
  252. package/src/runtime/compaction.ts +0 -395
  253. package/src/runtime/cwd.ts +0 -43
  254. package/src/runtime/providerTurn.ts +0 -38
  255. package/src/runtime/sessionMode.ts +0 -55
  256. package/src/runtime/systemPrompt.ts +0 -213
  257. package/src/runtime/textToolParser.ts +0 -161
  258. package/src/runtime/toolClaimGuards.ts +0 -143
  259. package/src/runtime/toolExecution.ts +0 -304
  260. package/src/runtime/toolIntent.ts +0 -143
  261. package/src/runtime/turn.ts +0 -369
  262. package/src/runtime/turnNudges.ts +0 -223
  263. package/src/runtime/turnTypes.ts +0 -86
  264. package/src/storage/factoryReset.ts +0 -127
  265. package/src/storage/history.ts +0 -58
  266. package/src/storage/permissions.ts +0 -76
  267. package/src/storage/rewind.ts +0 -266
  268. package/src/storage/sessionExport.ts +0 -49
  269. package/src/storage/sessions.ts +0 -495
  270. package/src/tools/bashSafety.ts +0 -186
  271. package/src/tools/bashTool.ts +0 -140
  272. package/src/tools/changeDirectoryTool.ts +0 -213
  273. package/src/tools/contracts.ts +0 -192
  274. package/src/tools/deleteFileTool.ts +0 -116
  275. package/src/tools/editTool.ts +0 -165
  276. package/src/tools/editUtils.ts +0 -170
  277. package/src/tools/fileDiff.ts +0 -261
  278. package/src/tools/listDirectoryTool.ts +0 -55
  279. package/src/tools/listSkillFilesTool.ts +0 -77
  280. package/src/tools/listSkillsTool.ts +0 -68
  281. package/src/tools/mcpResourceTools.ts +0 -95
  282. package/src/tools/permissionRules.ts +0 -85
  283. package/src/tools/privateContinuityEditTool.ts +0 -187
  284. package/src/tools/privateContinuityReadTool.ts +0 -106
  285. package/src/tools/readSkillTool.ts +0 -107
  286. package/src/tools/readTool.ts +0 -85
  287. package/src/tools/registry.ts +0 -103
  288. package/src/tools/writeFileTool.ts +0 -167
  289. package/src/ui/BrandSplash.tsx +0 -133
  290. package/src/ui/terminalTitle.ts +0 -30
  291. package/src/utils/images.ts +0 -140
  292. package/src/utils/markdownSegments.ts +0 -51
  293. package/src/utils/messages.ts +0 -37
  294. package/src/utils/withRetry.ts +0 -324
  295. /package/src/identity/{hub → manager}/continuity/state.ts +0 -0
  296. /package/src/identity/{hub → manager}/custody/helpers.ts +0 -0
  297. /package/src/identity/{hub → manager}/custody/preflight.ts +0 -0
  298. /package/src/identity/{hub → manager}/custody/state.ts +0 -0
  299. /package/src/identity/{hub → manager}/custody/useCustodyFlow.tsx +0 -0
  300. /package/src/identity/{hub → manager}/ens/EnsEditFlow.tsx +0 -0
  301. /package/src/identity/{hub → manager}/ens/advancedEnsValidation.ts +0 -0
  302. /package/src/identity/{hub → manager}/ens/state.ts +0 -0
  303. /package/src/identity/{hub → manager}/ens/transactions.ts +0 -0
  304. /package/src/identity/{hub → manager}/ens/types.ts +0 -0
  305. /package/src/identity/{hub → manager}/profile/identity.ts +0 -0
  306. /package/src/identity/{hub → manager}/restore/envelopes.ts +0 -0
  307. /package/src/identity/{hub → manager}/restore/helpers.ts +0 -0
  308. /package/src/identity/{hub → manager}/restore/recovery.ts +0 -0
  309. /package/src/identity/{hub → manager}/restore/resolve.ts +0 -0
  310. /package/src/identity/{hub → manager}/shared/components/BusyScreen.tsx +0 -0
  311. /package/src/identity/{hub → manager}/shared/components/NetworkScreen.tsx +0 -0
  312. /package/src/identity/{hub → manager}/shared/components/PinataJwtInput.tsx +0 -0
  313. /package/src/identity/{hub → manager}/shared/effects/receipts.ts +0 -0
  314. /package/src/identity/{hub → manager}/shared/effects/sync.ts +0 -0
  315. /package/src/identity/{hub → manager}/shared/model/format.ts +0 -0
  316. /package/src/identity/{hub → manager}/shared/operatorWallets.ts +0 -0
  317. /package/src/identity/{hub → manager}/shared/reconciliation/agentReconciliation/ownership.ts +0 -0
  318. /package/src/identity/{hub → manager}/shared/reconciliation/agentReconciliation/types.ts +0 -0
  319. /package/src/identity/{hub → manager}/shared/reconciliation/walletSetup.ts +0 -0
  320. /package/src/identity/{hub → manager}/shared/txGuard.ts +0 -0
  321. /package/src/identity/{hub → manager}/transfer/progress.ts +0 -0
  322. /package/src/identity/{hub → manager}/transfer/state.ts +0 -0
@@ -36,7 +36,8 @@ import {
36
36
  requestBrowserWalletSignatureAndTransaction,
37
37
  } from '../../wallet/browserWallet.js'
38
38
  import { initialAgentState, PREFLIGHT_AGENT_URI } from '../profile/identity.js'
39
- import type { Step } from '../identityHubReducer.js'
39
+ import { mergeImportedNotes } from './importScan.js'
40
+ import type { Step } from '../reducer.js'
40
41
  import type { EffectCallbacks } from '../shared/effects/types.js'
41
42
  import { awaitConfirmedReceipt } from '../shared/effects/receipts.js'
42
43
  import { assertVerifiedPin } from '../shared/effects/profilePrep.js'
@@ -63,8 +64,9 @@ export async function runCreatePreflight(
63
64
  const resolution = step.network
64
65
  ? registryResolutionForNetwork(step.network)
65
66
  : registryConfigFromConfig(config)
67
+ const carryNotes = step.importNotes ? { importNotes: step.importNotes } : {}
66
68
  if (!resolution.config) {
67
- callbacks.onStep({ kind: 'create-registry', name: step.name, description: step.description, resolution, custodyMode: step.custodyMode })
69
+ callbacks.onStep({ kind: 'create-registry', name: step.name, description: step.description, resolution, custodyMode: step.custodyMode, ...carryNotes })
68
70
  return
69
71
  }
70
72
  const apiUrl = DEFAULT_IPFS_API_URL
@@ -79,14 +81,15 @@ export async function runCreatePreflight(
79
81
  registry: resolution.config,
80
82
  custodyMode: step.custodyMode,
81
83
  error: (err as Error).message,
84
+ ...carryNotes,
82
85
  })
83
86
  return
84
87
  }
85
88
  if (isPinataUploadUrl(apiUrl) && !jwt) {
86
- callbacks.onStep({ kind: 'create-storage', name: step.name, description: step.description, registry: resolution.config, custodyMode: step.custodyMode })
89
+ callbacks.onStep({ kind: 'create-storage', name: step.name, description: step.description, registry: resolution.config, custodyMode: step.custodyMode, ...carryNotes })
87
90
  return
88
91
  }
89
- callbacks.onStep({ kind: 'create-signing', name: step.name, description: step.description, registry: resolution.config, custodyMode: step.custodyMode, pinataJwt: jwt })
92
+ callbacks.onStep({ kind: 'create-signing', name: step.name, description: step.description, registry: resolution.config, custodyMode: step.custodyMode, pinataJwt: jwt, ...carryNotes })
90
93
  }
91
94
 
92
95
  function registryResolutionForNetwork(network: SelectableNetwork): RegistryResolution {
@@ -136,7 +139,9 @@ export async function runCreateSigning(
136
139
  registry: step.registry,
137
140
  state,
138
141
  })
139
- const continuityFiles = defaultContinuityFiles(draftIdentity)
142
+ const continuityFiles = step.importNotes?.length
143
+ ? mergeImportedNotes(defaultContinuityFiles(draftIdentity), step.importNotes)
144
+ : defaultContinuityFiles(draftIdentity)
140
145
  const publicProfile = defaultPublicSkillsProfile(draftIdentity)
141
146
  const agentCardJson = serializeAgentCard(createAgentCard(publicProfile))
142
147
  const agentCardPin = await addToIpfs(DEFAULT_IPFS_API_URL, agentCardJson, fetch, { pinataJwt: step.pinataJwt })
@@ -231,8 +236,11 @@ export async function runCreateSigning(
231
236
  backup,
232
237
  agentCard: result.prepared.agentCard,
233
238
  }
239
+ const finalContinuityFiles = step.importNotes?.length
240
+ ? mergeImportedNotes(defaultContinuityFiles(nextIdentity), step.importNotes)
241
+ : defaultContinuityFiles(nextIdentity)
234
242
  await writeIdentityMarkdownScaffold(nextIdentity, {
235
- ...defaultContinuityFiles(nextIdentity),
243
+ ...finalContinuityFiles,
236
244
  'agent-card.json': result.prepared.agentCardJson,
237
245
  })
238
246
  await recordPublishedContinuitySnapshot({ identity: nextIdentity, label: 'initial published snapshot' }).catch(() => null)
@@ -264,18 +272,19 @@ export async function runRegistrySubmit(
264
272
  onConfigChange(next)
265
273
  }
266
274
  const apiUrl = DEFAULT_IPFS_API_URL
275
+ const carryNotes = step.importNotes ? { importNotes: step.importNotes } : {}
267
276
  let jwt: string | undefined
268
277
  try {
269
278
  jwt = isPinataUploadUrl(apiUrl) ? await resolveValidatedPinataJwt() : undefined
270
279
  } catch (err: unknown) {
271
- callbacks.onStep({ kind: 'create-storage', name: step.name, description: step.description, registry, custodyMode: step.custodyMode, error: (err as Error).message })
280
+ callbacks.onStep({ kind: 'create-storage', name: step.name, description: step.description, registry, custodyMode: step.custodyMode, error: (err as Error).message, ...carryNotes })
272
281
  return
273
282
  }
274
283
  if (isPinataUploadUrl(apiUrl) && !jwt) {
275
- callbacks.onStep({ kind: 'create-storage', name: step.name, description: step.description, registry, custodyMode: step.custodyMode })
284
+ callbacks.onStep({ kind: 'create-storage', name: step.name, description: step.description, registry, custodyMode: step.custodyMode, ...carryNotes })
276
285
  return
277
286
  }
278
- callbacks.onStep({ kind: 'create-signing', name: step.name, description: step.description, registry, custodyMode: step.custodyMode, pinataJwt: jwt })
287
+ callbacks.onStep({ kind: 'create-signing', name: step.name, description: step.description, registry, custodyMode: step.custodyMode, pinataJwt: jwt, ...carryNotes })
279
288
  }
280
289
 
281
290
  export async function runStorageSubmit(
@@ -284,7 +293,7 @@ export async function runStorageSubmit(
284
293
  callbacks: EffectCallbacks,
285
294
  ): Promise<void> {
286
295
  const { jwt: pinataJwt } = await savePinataJwt(input)
287
- callbacks.onStep({ kind: 'create-signing', name: step.name, description: step.description, registry: step.registry, custodyMode: step.custodyMode, pinataJwt })
296
+ callbacks.onStep({ kind: 'create-signing', name: step.name, description: step.description, registry: step.registry, custodyMode: step.custodyMode, pinataJwt, ...(step.importNotes ? { importNotes: step.importNotes } : {}) })
288
297
  }
289
298
 
290
299
  function identityDraftForBackup(args: {
@@ -0,0 +1,122 @@
1
+ import fs from 'node:fs/promises'
2
+ import path from 'node:path'
3
+ import type { EthagentIdentity } from '../../../storage/config.js'
4
+ import type { ContinuityFiles } from '../../continuity/envelope.js'
5
+ import { defaultContinuityFiles } from '../../continuity/storage.js'
6
+ import { extractOutsideManaged } from '../../../cli/syncAdapters/managedBlock.js'
7
+ import { BUILT_IN_ADAPTERS } from '../../../cli/syncAdapters/index.js'
8
+
9
+ export type ImportCandidate = {
10
+ source: string
11
+ raw: string
12
+ contentLines: number
13
+ }
14
+
15
+ const MIN_SUBSTANTIVE_CHARS = 120
16
+ const MIN_CONTENT_LINES = 5
17
+
18
+ function stripIdentityBlocks(text: string): string {
19
+ return text.replace(/<!--\s*ethagent:identity:start\s*-->[\s\S]*?<!--\s*ethagent:identity:end\s*-->/g, '')
20
+ }
21
+
22
+ function substantiveLines(text: string): string[] {
23
+ return stripIdentityBlocks(text)
24
+ .split('\n')
25
+ .map(line => line.trim())
26
+ .filter(line => line.length > 0)
27
+ .filter(line => !line.startsWith('#'))
28
+ .filter(line => !(line.startsWith('<!--') && line.endsWith('-->')))
29
+ }
30
+
31
+ const LEGACY_SCAFFOLD_LINES = [
32
+ 'The standing voice, collaboration style, and behavior this agent keeps across sessions and models.',
33
+ '- Voice: <e.g., direct, concise, no filler>',
34
+ '- Tone: <e.g., warm but professional>',
35
+ '- Communication style: <e.g., bullet lists for technical work, prose for narrative>',
36
+ 'Owner-approved working principles. Decisions that should be made the same way every time.',
37
+ '- <principle: e.g., always confirm before destructive operations>',
38
+ '- <principle: e.g., bias toward editing existing code over creating new files>',
39
+ '- <principle: e.g., never hide errors, always surface them clearly>',
40
+ 'What this agent must never do, regardless of how it is asked.',
41
+ '- <boundary: e.g., never bypass authentication or authorization checks>',
42
+ '- <boundary: e.g., never commit secrets to source control>',
43
+ 'Long-lived owner preferences that survive sessions and model switches. Capture how the user works.',
44
+ '- Communication: <e.g., prefers concise summaries over walls of text>',
45
+ '- Tooling: <e.g., VS Code, zsh, TypeScript over JavaScript>',
46
+ '- Workflow: <e.g., reviews PRs in the morning, deploys on Fridays>',
47
+ '- Repository: <url or local path>',
48
+ '- Stack: <languages, frameworks, key libraries>',
49
+ '- Conventions: <e.g., conventional commits, semver, branch naming>',
50
+ '- Active workstream: <YYYY-MM-DD what you are focused on>',
51
+ ]
52
+
53
+ const SCAFFOLD_LINES: Set<string> = (() => {
54
+ const scaffold = defaultContinuityFiles({
55
+ source: 'erc8004',
56
+ address: '0x0000000000000000000000000000000000000000',
57
+ } as EthagentIdentity)
58
+ return new Set([
59
+ ...substantiveLines(scaffold['SOUL.md']),
60
+ ...substantiveLines(scaffold['MEMORY.md']),
61
+ ...LEGACY_SCAFFOLD_LINES,
62
+ ])
63
+ })()
64
+
65
+ function localOnlyLines(text: string): string[] {
66
+ return substantiveLines(text).filter(line => !SCAFFOLD_LINES.has(line))
67
+ }
68
+
69
+ export function isValuableImport(text: string): boolean {
70
+ const lines = localOnlyLines(text)
71
+ if (lines.length === 0) return false
72
+ const chars = lines.join('').replace(/\s/g, '').length
73
+ return chars >= MIN_SUBSTANTIVE_CHARS || lines.length >= MIN_CONTENT_LINES
74
+ }
75
+
76
+ export async function scanImportCandidates(): Promise<ImportCandidate[]> {
77
+ const out: ImportCandidate[] = []
78
+ for (const adapter of BUILT_IN_ADAPTERS) {
79
+ if (!adapter.managedFilePaths) continue
80
+ const detected = await adapter.detect().catch(() => false)
81
+ if (!detected) continue
82
+ const filePath = adapter.managedFilePaths()[0]
83
+ if (!filePath) continue
84
+ let content: string
85
+ try {
86
+ content = await fs.readFile(filePath, 'utf8')
87
+ } catch {
88
+ continue
89
+ }
90
+ const outside = extractOutsideManaged(content)
91
+ if (!isValuableImport(outside)) continue
92
+ out.push({
93
+ source: path.basename(filePath),
94
+ raw: outside.trim(),
95
+ contentLines: localOnlyLines(outside).length,
96
+ })
97
+ }
98
+ return out
99
+ }
100
+
101
+ export function mergeImportedNotes(
102
+ base: ContinuityFiles,
103
+ candidates: ImportCandidate[],
104
+ now = new Date(),
105
+ ): ContinuityFiles {
106
+ if (candidates.length === 0) return base
107
+ const dateStr = now.toISOString().slice(0, 10)
108
+ const sources = candidates.map(candidate => candidate.source).join(', ')
109
+ const lines: string[] = [
110
+ `## Imported from ${sources} (${dateStr})`,
111
+ '',
112
+ 'Captured from your existing assistant notes at mint time. Reorganize into the sections above as you like.',
113
+ '',
114
+ ]
115
+ for (const candidate of candidates) {
116
+ if (candidates.length > 1) lines.push(`### ${candidate.source}`, '')
117
+ lines.push(candidate.raw, '')
118
+ }
119
+ const importedSection = lines.join('\n').trim()
120
+ const memory = `${base['MEMORY.md'].replace(/\n+$/, '')}\n\n${importedSection}\n`
121
+ return { 'SOUL.md': base['SOUL.md'], 'MEMORY.md': memory }
122
+ }
@@ -4,7 +4,7 @@ import { Box, Text } from 'ink'
4
4
  import { Surface } from '../../../ui/Surface.js'
5
5
  import { Select } from '../../../ui/Select.js'
6
6
  import { theme } from '../../../ui/theme.js'
7
- import type { ProfileUpdates, Step } from '../identityHubReducer.js'
7
+ import type { ProfileUpdates, Step } from '../reducer.js'
8
8
  import {
9
9
  displayCustodyMode,
10
10
  identityOwnerAddress,
@@ -29,8 +29,6 @@ interface CustodyEditFlowProps {
29
29
  onSetStep: (step: Step) => void
30
30
  onSwitchToAdvanced: (returnTo: Step, profileUpdates: ProfileUpdates) => void
31
31
  onSwitchToSimple: (returnTo: Step, profileUpdates: ProfileUpdates) => void
32
- onWithdrawToken: (returnTo: Step) => void
33
- onReturnToVault: (returnTo: Step, vaultAddress: Address) => void
34
32
  onResumeAdvanced: (returnTo: Step) => void
35
33
  onManageOperatorWallets: () => void
36
34
  onPrepareTransfer: () => void
@@ -50,8 +48,6 @@ export const CustodyEditFlow: React.FC<CustodyEditFlowProps> = ({
50
48
  onSetStep,
51
49
  onSwitchToAdvanced,
52
50
  onSwitchToSimple,
53
- onWithdrawToken,
54
- onReturnToVault,
55
51
  onResumeAdvanced,
56
52
  onManageOperatorWallets,
57
53
  onPrepareTransfer,
@@ -72,68 +68,49 @@ export const CustodyEditFlow: React.FC<CustodyEditFlowProps> = ({
72
68
  const tokenOwner = identity.ownerAddress ?? identity.address
73
69
 
74
70
  if (step.kind === 'custody-model') {
75
- type Action = 'switch-advanced' | 'switch-simple' | 'resume-advanced' | 'cancel-advanced' | 'withdraw-token' | 'return-to-vault' | 'manage-operator-wallets' | 'back'
71
+ type Action = 'switch-advanced' | 'switch-simple' | 'resume-advanced' | 'cancel-advanced' | 'manage-operator-wallets' | 'back'
76
72
  const onChainCustody = reconciliation?.custody
77
73
  const midFlow = onChainCustody === 'mid-flow-uri-pending'
78
74
  const isAdvanced = onChainCustody === 'advanced' || midFlow || custodyMode === 'advanced'
79
75
  const vaultHolds = onChainCustody === 'advanced' || midFlow
80
76
  const subtitle = midFlow
81
- ? 'Advanced setup pending. This Vault holds your token. Finish by publishing the first onchain update.'
77
+ ? 'Advanced setup pending.'
82
78
  : isAdvanced
83
- ? 'Advanced is active. Authorized operator wallets publish updates for this agent without an owner signature each time.'
84
- : 'Simple is active. One wallet owns the token and signs every update.'
79
+ ? 'Advanced custody active.'
80
+ : 'Simple custody active.'
85
81
  const modeLabel = midFlow ? 'Advanced (setup pending)' : displayCustodyMode(isAdvanced ? 'advanced' : 'simple')
86
82
  const options: Array<{ value: Action; role?: 'section' | 'utility'; label: string; hint?: string }> = []
87
83
  if (midFlow) {
88
- options.push({ value: 'resume-advanced', role: 'section', label: 'Resume Setup' })
89
84
  options.push({
90
85
  value: 'resume-advanced',
91
86
  label: 'Resume Advanced Setup',
92
- hint: 'Sign once to publish onchain and finish the Vault switch.',
93
87
  })
94
88
  options.push({
95
89
  value: 'cancel-advanced',
96
90
  label: 'Cancel Advanced Setup',
97
- hint: 'Unwrap the token back to the owner wallet and revert to simple.',
98
91
  })
99
92
  }
100
- options.push({ value: 'switch-advanced', role: 'section', label: 'Custody' })
101
93
  if (!isAdvanced) {
102
94
  options.push({
103
95
  value: 'switch-advanced',
104
96
  label: 'Switch to Advanced',
105
- hint: 'Deposit this token into its own Vault so operator wallets can publish updates onchain.',
97
+ hint: 'Operators publish',
106
98
  })
107
99
  } else {
108
100
  if (!midFlow) {
109
101
  options.push({
110
102
  value: 'switch-simple',
111
103
  label: 'Switch to Simple',
112
- hint: 'Unwrap the token and revoke operator delegations.',
104
+ hint: 'Remove Vault',
113
105
  })
114
106
  }
115
- if (vaultHolds) {
116
- options.push({
117
- value: 'withdraw-token',
118
- label: 'Withdraw Token',
119
- hint: 'Unwrap this token to the owner wallet. Vault setup stays for easy redeposit.',
120
- })
121
- } else if (vaultAddress) {
122
- options.push({
123
- value: 'return-to-vault',
124
- label: 'Return Token to Vault',
125
- hint: 'Redeposit this token to its Vault. No redeploy, no operator re-add.',
126
- })
127
- }
128
- options.push({ value: 'manage-operator-wallets', role: 'section', label: 'Operators' })
129
107
  options.push({
130
108
  value: 'manage-operator-wallets',
131
109
  label: 'Manage Operators',
132
- hint: 'Add or revoke wallets that can publish updates onchain.',
110
+ hint: 'Add or revoke',
133
111
  })
134
112
  }
135
- options.push({ value: 'back', role: 'section', label: 'Navigation' })
136
- options.push({ value: 'back', label: 'Back', hint: 'Return to Identity Hub', role: 'utility' })
113
+ options.push({ value: 'back', label: 'Back', role: 'utility' })
137
114
  const notice = step.kind === 'custody-model' ? step.notice : undefined
138
115
  return (
139
116
  <Surface title="Custody Mode" subtitle={subtitle} footer={footerHint('enter select · esc back')}>
@@ -182,11 +159,6 @@ export const CustodyEditFlow: React.FC<CustodyEditFlowProps> = ({
182
159
  onSubmit={choice => {
183
160
  if (choice === 'back') return onBack()
184
161
  if (choice === 'manage-operator-wallets') return onManageOperatorWallets()
185
- if (choice === 'withdraw-token') return onWithdrawToken(returnTo ?? { kind: 'menu' })
186
- if (choice === 'return-to-vault') {
187
- if (!vaultAddress) return
188
- return onReturnToVault(returnTo ?? { kind: 'menu' }, vaultAddress)
189
- }
190
162
  if (choice === 'resume-advanced') return onResumeAdvanced(returnTo ?? { kind: 'menu' })
191
163
  if (choice === 'cancel-advanced') {
192
164
  onSetStep({ kind: 'custody-simple-confirm', identity, registry, returnTo })
@@ -213,31 +185,20 @@ export const CustodyEditFlow: React.FC<CustodyEditFlowProps> = ({
213
185
  return (
214
186
  <Surface
215
187
  title="Switch to Advanced"
216
- subtitle="Move this token into its own Vault so authorized operator wallets can update this agent onchain without your signature each time."
188
+ subtitle="Token goes into a Vault. Operators update onchain without your sig each time."
217
189
  footer={footerHint('enter confirm · esc back')}
218
190
  >
219
191
  <Box flexDirection="column">
220
192
  <Row label="Token" value={tokenLabel} />
221
193
  {agentName ? <Row label="Name" value={agentName} /> : null}
222
194
  <Row label="Owner Wallet" value={shortAddress(ownerAddress || tokenOwner)} />
223
- <Text color={theme.textSubtle}>You sign once now to deposit token #{identity.agentId ?? 'unknown'} into a dedicated Vault.</Text>
224
- <Text color={theme.textSubtle}>This vault can hold only this ERC-8004 token.</Text>
225
- <Text color={theme.textSubtle}>Other agent tokens use their own vaults.</Text>
226
- <Text color={theme.textSubtle}>After that, operator wallets you authorize can publish updates for this agent.</Text>
227
- <Box marginTop={1} flexDirection="column">
228
- <Text color={theme.accentBlue}>Want a different wallet to be the owner?</Text>
229
- <Text color={theme.textSubtle}>Move the token there first via Prepare Token Transfer; your continuity files come along.</Text>
230
- </Box>
231
195
  </Box>
232
196
  <Box marginTop={1}>
233
197
  <Select<Action>
234
198
  options={[
235
- { value: 'confirm', role: 'section', label: 'Confirm' },
236
- { value: 'confirm', label: 'Yes, Switch to Advanced', hint: `Sign with ${shortAddress(ownerAddress || tokenOwner)} to deposit this token into its Vault` },
237
- { value: 'transfer', role: 'section', label: 'Move Token First' },
238
- { value: 'transfer', label: 'Prepare Token Transfer', hint: 'Move the token to a different wallet first, with snapshot handoff' },
239
- { value: 'back', role: 'section', label: 'Navigation' },
240
- { value: 'back', label: 'No, Go Back', hint: 'Return without changing custody', role: 'utility' },
199
+ { value: 'confirm', label: 'Yes, Switch to Advanced' },
200
+ { value: 'transfer', label: 'Prepare Token Transfer' },
201
+ { value: 'back', label: 'Back', role: 'utility' },
241
202
  ]}
242
203
  hintLayout="inline"
243
204
  onSubmit={choice => {
@@ -262,24 +223,19 @@ export const CustodyEditFlow: React.FC<CustodyEditFlowProps> = ({
262
223
  return (
263
224
  <Surface
264
225
  title="Switch to Simple"
265
- subtitle="Unwraps this ERC-8004 token from its Vault and returns it directly to the owner wallet."
226
+ subtitle="Withdraws token from Vault to owner wallet."
266
227
  footer={footerHint('enter confirm · esc back')}
267
228
  >
268
229
  <Box flexDirection="column">
269
230
  <Row label="Token" value={tokenLabel} />
270
231
  {agentName ? <Row label="Name" value={agentName} /> : null}
271
- <Text> </Text>
272
- <Text color={theme.accentBlue}>Operators lose decrypt access on future snapshots immediately.</Text>
273
- <Text color={theme.textSubtle}>Operator approvals are cleared from local state for future snapshots. Revoke onchain via Manage Operators first if needed.</Text>
274
- <Text color={theme.textSubtle}>This switch calls the Vault unwrap function for this token, so the owner wallet must sign the transaction.</Text>
232
+ <Text color={theme.accentError}>Operators lose access immediately.</Text>
275
233
  </Box>
276
234
  <Box marginTop={1}>
277
235
  <Select<Action>
278
236
  options={[
279
- { value: 'confirm', role: 'section', label: 'Confirm' },
280
- { value: 'confirm', label: 'Yes, Switch to Simple', hint: `Sign with the owner wallet to unwrap ${tokenLabel} from its Vault` },
281
- { value: 'back', role: 'section', label: 'Navigation' },
282
- { value: 'back', label: 'No, Go Back', hint: 'Return without changing custody', role: 'utility' },
237
+ { value: 'confirm', label: 'Yes, Switch to Simple' },
238
+ { value: 'back', label: 'Back', role: 'utility' },
283
239
  ]}
284
240
  hintLayout="inline"
285
241
  onSubmit={choice => {
@@ -1,7 +1,7 @@
1
1
  import type { Address } from 'viem'
2
2
  import { createErc8004PublicClient } from '../../registry/erc8004.js'
3
3
  import { discoverPriorVaultFromTokenOwner, isAgentInVault } from '../../registry/vault.js'
4
- import type { ProfileUpdates, Step } from '../identityHubReducer.js'
4
+ import type { ProfileUpdates, Step } from '../reducer.js'
5
5
  import { isCustodyEditStep } from './CustodyEditFlow.js'
6
6
  import { resolveVaultAddress } from './transactions.js'
7
7
  import type { CustodyFlowDeps } from './types.js'
@@ -17,7 +17,6 @@ export function createCustodyFlowActions({
17
17
  beginVaultDeposit: (currentStep: Step, returnTo: Step, profileUpdates: ProfileUpdates) => void
18
18
  beginVaultUnwrap: (currentStep: Step, returnTo: Step, profileUpdates: ProfileUpdates) => void
19
19
  beginWithdrawToken: (currentStep: Step, returnTo: Step, returnContext?: 'ens' | 'simple-exit') => void
20
- beginReturnToVault: (currentStep: Step, returnTo: Step, vaultAddress: Address) => void
21
20
  } {
22
21
  const beginVaultDeposit = (currentStep: Step, returnTo: Step, profileUpdates: ProfileUpdates): void => {
23
22
  if (!isCustodyEditStep(currentStep) || currentStep.kind !== 'custody-advanced-confirm') return
@@ -210,23 +209,10 @@ export function createCustodyFlowActions({
210
209
  })()
211
210
  }
212
211
 
213
- const beginReturnToVault = (currentStep: Step, returnTo: Step, vaultAddress: Address): void => {
214
- if (!isCustodyEditStep(currentStep)) return
215
- setStep({
216
- kind: 'custody-vault-deposit-tx',
217
- identity: currentStep.identity,
218
- registry: currentStep.registry,
219
- vaultAddress,
220
- profileUpdates: withVaultProfileUpdates({}, vaultAddress),
221
- returnTo,
222
- })
223
- }
224
-
225
212
  return {
226
213
  beginVaultDeposit,
227
214
  beginVaultUnwrap,
228
215
  beginWithdrawToken,
229
- beginReturnToVault,
230
216
  }
231
217
  }
232
218
 
@@ -5,7 +5,7 @@ import { Select } from '../../../ui/Select.js'
5
5
  import { theme } from '../../../ui/theme.js'
6
6
  import { WalletApprovalScreen } from '../shared/components/WalletApprovalScreen.js'
7
7
  import { shortAddress } from '../shared/model/format.js'
8
- import type { Step } from '../identityHubReducer.js'
8
+ import type { Step } from '../reducer.js'
9
9
  import type { CustodyFlowDeps } from './types.js'
10
10
  import { chainLabel, humanOwnerAddress } from './helpers.js'
11
11
 
@@ -25,9 +25,9 @@ export function renderCustodyStep({
25
25
  return (
26
26
  <WalletApprovalScreen
27
27
  title="Deploy Vault"
28
- subtitle={`Deploying a dedicated Vault for this ERC-8004 token on ${chainLabel(step.registry.chainId)}.`}
28
+ subtitle={`Deploying Vault on ${chainLabel(step.registry.chainId)}.`}
29
29
  walletSession={walletSession}
30
- label="waiting for owner wallet transaction..."
30
+ label="waiting for wallet to deploy Vault..."
31
31
  onCancel={() => setStep({ kind: 'custody-model', identity: step.identity, registry: step.registry, returnTo: step.returnTo })}
32
32
  />
33
33
  )
@@ -36,9 +36,9 @@ export function renderCustodyStep({
36
36
  return (
37
37
  <WalletApprovalScreen
38
38
  title="Deposit Token Into Vault"
39
- subtitle={`Sign one ${chainLabel(step.registry.chainId)} transaction. Sends ERC-8004 token #${step.identity.agentId ?? ''} to its Vault.`}
39
+ subtitle={`Depositing token #${step.identity.agentId ?? ''} into its Vault.`}
40
40
  walletSession={walletSession}
41
- label="waiting for token-owner wallet transaction..."
41
+ label="waiting for wallet to deposit token..."
42
42
  onCancel={() => setStep({ kind: 'custody-model', identity: step.identity, registry: step.registry, returnTo: step.returnTo })}
43
43
  />
44
44
  )
@@ -49,13 +49,10 @@ export function renderCustodyStep({
49
49
  <Surface
50
50
  title="Checking Vault"
51
51
  subtitle={targetAgentId
52
- ? `Confirming the Vault holds ERC-8004 token #${targetAgentId} on ${chainLabel(step.registry.chainId)}.`
52
+ ? `Checking Vault on ${chainLabel(step.registry.chainId)}.`
53
53
  : `Checking this identity's recorded Vault on ${chainLabel(step.registry.chainId)}.`}
54
54
  footer={<Text color={theme.dim}>esc cancel</Text>}
55
55
  >
56
- <Box marginTop={1}>
57
- <Text color={theme.textSubtle}>Reading vault state from onchain...</Text>
58
- </Box>
59
56
  </Surface>
60
57
  )
61
58
  }
@@ -64,9 +61,9 @@ export function renderCustodyStep({
64
61
  return (
65
62
  <WalletApprovalScreen
66
63
  title="Withdraw Token"
67
- subtitle={`Unwraps ERC-8004 token #${targetAgentId} from its Vault to your owner wallet on ${chainLabel(step.registry.chainId)}.`}
64
+ subtitle={`Withdraws token #${targetAgentId} from its Vault.`}
68
65
  walletSession={walletSession}
69
- label="waiting for owner wallet transaction..."
66
+ label="waiting for wallet to withdraw token..."
70
67
  onCancel={() => setStep({ kind: 'custody-model', identity: step.identity, registry: step.registry, returnTo: step.returnTo })}
71
68
  />
72
69
  )
@@ -76,21 +73,19 @@ export function renderCustodyStep({
76
73
  const options = step.tokens.map(t => ({
77
74
  value: t.agentId,
78
75
  label: `Token #${t.agentId}${activeId && t.agentId === activeId ? ' (active)' : ''}`,
79
- hint: 'Withdraw this token to your owner wallet',
76
+ hint: 'Withdraw to owner wallet',
80
77
  }))
81
78
  return (
82
79
  <Surface
83
80
  title="Pick a Vaulted Token"
84
- subtitle={`Your wallet has ${step.tokens.length} vaulted tokens on ${chainLabel(step.registry.chainId)}. Pick one to withdraw.`}
81
+ subtitle={`${step.tokens.length} vaulted tokens on ${chainLabel(step.registry.chainId)}.`}
85
82
  footer={<Text color={theme.dim}>enter select · esc back</Text>}
86
83
  >
87
84
  <Box marginTop={1}>
88
85
  <Select<string>
89
86
  options={[
90
- { value: 'header', role: 'section', label: 'Vaulted Tokens' },
91
87
  ...options,
92
- { value: 'cancel', role: 'section', label: 'Navigation' },
93
- { value: 'cancel', label: 'Back', hint: 'Return to Custody Mode', role: 'utility' },
88
+ { value: 'cancel', label: 'Back', role: 'utility' },
94
89
  ]}
95
90
  hintLayout="inline"
96
91
  onSubmit={choice => {
@@ -135,23 +130,14 @@ export function renderCustodyStep({
135
130
  return (
136
131
  <Surface
137
132
  title="Token Returned to Owner Wallet"
138
- subtitle={`Token returned to ${shortAddress(step.recipient)} on ${chainLabel(step.registry.chainId)}. The Vault can be reused for this token.`}
133
+ subtitle={`Token returned to ${shortAddress(step.recipient)}.`}
139
134
  footer={<Text color={theme.dim}>enter select · esc back</Text>}
140
135
  >
141
- <Box flexDirection="column">
142
- <Text color={theme.textSubtle}>
143
- {step.returnContext === 'ens'
144
- ? 'Use the token with your owner wallet to set ENS records, then return it to the vault to resume Advanced custody.'
145
- : 'Use the token with your owner wallet for whatever you need, then return it to the vault when finished.'}
146
- </Text>
147
- </Box>
148
136
  <Box marginTop={1}>
149
137
  <Select<'return-to-vault' | 'keep-out'>
150
138
  options={[
151
- { value: 'return-to-vault', role: 'section', label: 'Resume Advanced Custody' },
152
- { value: 'return-to-vault', label: 'Return Token to Vault', hint: 'Redeposit to this Vault. No redeploy, no operator re-add' },
153
- { value: 'keep-out', role: 'section', label: 'Later' },
154
- { value: 'keep-out', label: 'Keep Out For Now', hint: 'Token stays with the owner wallet; redeposit any time from Custody Mode', role: 'utility' },
139
+ { value: 'return-to-vault', label: 'Return Token to Vault', hint: 'Redeposit' },
140
+ { value: 'keep-out', label: 'Keep Out For Now', role: 'utility' },
155
141
  ]}
156
142
  hintLayout="inline"
157
143
  onSubmit={choice => {
@@ -168,9 +154,9 @@ export function renderCustodyStep({
168
154
  return (
169
155
  <WalletApprovalScreen
170
156
  title="Unwrap Token From Vault"
171
- subtitle={`Sign one ${chainLabel(step.registry.chainId)} transaction. Calls the Vault unwrap function to return ERC-8004 token #${step.identity.agentId ?? ''} to the owner wallet.`}
157
+ subtitle={`Unwrapping token #${step.identity.agentId ?? ''} from Vault.`}
172
158
  walletSession={walletSession}
173
- label="waiting for owner wallet transaction..."
159
+ label="waiting for wallet to unwrap token..."
174
160
  onCancel={() => setStep({ kind: 'custody-model', identity: step.identity, registry: step.registry, returnTo: step.returnTo })}
175
161
  />
176
162
  )
@@ -182,20 +168,17 @@ export function renderCustodyStep({
182
168
  return (
183
169
  <Surface
184
170
  title="Advanced Custody Active"
185
- subtitle="Your token is held in its own Vault. Authorized operator wallets can rotate the agent URI onchain without owner signatures."
171
+ subtitle="Token held in its Vault. Operators rotate the URI onchain."
186
172
  footer={<Text color={theme.dim}>enter continues</Text>}
187
173
  >
188
174
  <Box flexDirection="column">
189
175
  {step.vaultAddress ? <Row label="Vault" value={shortAddress(step.vaultAddress)} /> : null}
190
176
  <Row label="Owner Wallet" value={shortAddress(ownerWallet)} />
191
177
  <Row label="Operator Wallets" value={operatorCount === 1 ? '1 approved' : `${operatorCount} approved`} />
192
- <Box marginTop={1}>
193
- <Text color={theme.textSubtle}>Use Manage Operators to add or revoke operator wallets. Use Withdraw Token to pull this token out of its vault temporarily without dismantling advanced custody.</Text>
194
- </Box>
195
178
  </Box>
196
179
  <Box marginTop={1}>
197
180
  <Select<'continue'>
198
- options={[{ value: 'continue', label: 'Return to Custody Mode' }]}
181
+ options={[{ value: 'continue', label: 'Done' }]}
199
182
  onSubmit={() => setStep({ kind: 'custody-model', identity: step.identity, registry: step.registry, returnTo: step.returnTo })}
200
183
  onCancel={() => setStep({ kind: 'custody-model', identity: step.identity, registry: step.registry, returnTo: step.returnTo })}
201
184
  />
@@ -208,18 +191,15 @@ export function renderCustodyStep({
208
191
  return (
209
192
  <Surface
210
193
  title="Simple Custody Active"
211
- subtitle={`The token is back with the owner wallet. Operator slots are cleared.`}
194
+ subtitle="Token back in owner wallet."
212
195
  footer={<Text color={theme.dim}>enter continues</Text>}
213
196
  >
214
197
  <Box flexDirection="column">
215
198
  <Row label="Owner Wallet" value={shortAddress(ownerWallet)} />
216
- <Box marginTop={1}>
217
- <Text color={theme.textSubtle}>Future URI rotations require an owner wallet signature per edit. Switch back to Advanced from Custody Mode at any time.</Text>
218
- </Box>
219
199
  </Box>
220
200
  <Box marginTop={1}>
221
201
  <Select<'continue'>
222
- options={[{ value: 'continue', label: 'Return to Custody Mode' }]}
202
+ options={[{ value: 'continue', label: 'Done' }]}
223
203
  onSubmit={() => setStep({ kind: 'custody-model', identity: step.identity, registry: step.registry, returnTo: step.returnTo })}
224
204
  onCancel={() => setStep({ kind: 'custody-model', identity: step.identity, registry: step.registry, returnTo: step.returnTo })}
225
205
  />
@@ -116,6 +116,7 @@ async function runVaultDepositTransactionInner(args: {
116
116
  if (!identity.agentId) {
117
117
  throw new Error('Cannot deposit token to Vault: agent token ID is missing')
118
118
  }
119
+ await assertVaultBytecode(createErc8004PublicClient(registry), vaultAddress)
119
120
  const tokenOwner = getAddress(identity.ownerAddress ?? identity.address)
120
121
  await assertVaultCanAcceptAgent({
121
122
  registry,
@@ -3,7 +3,7 @@ import type { Address } from 'viem'
3
3
  import type { EthagentConfig, EthagentIdentity } from '../../../storage/config.js'
4
4
  import type { Erc8004RegistryConfig } from '../../registry/erc8004.js'
5
5
  import type { EffectCallbacks } from '../shared/effects/types.js'
6
- import type { ProfileUpdates, Step } from '../identityHubReducer.js'
6
+ import type { ProfileUpdates, Step } from '../reducer.js'
7
7
  import type { WalletApprovalScreen } from '../shared/components/WalletApprovalScreen.js'
8
8
 
9
9
  export type GuardOwnership = (
@@ -36,7 +36,6 @@ export interface CustodyFlow {
36
36
  beginVaultDeposit: (currentStep: Step, returnTo: Step, profileUpdates: ProfileUpdates) => void
37
37
  beginVaultUnwrap: (currentStep: Step, returnTo: Step, profileUpdates: ProfileUpdates) => void
38
38
  beginWithdrawToken: (currentStep: Step, returnTo: Step, returnContext?: 'ens' | 'simple-exit') => void
39
- beginReturnToVault: (currentStep: Step, returnTo: Step, vaultAddress: Address) => void
40
39
  renderCustodyStep: () => React.ReactElement | null
41
40
  renderRebackupSubtitle: (
42
41
  defaultSubtitle: React.ReactNode,
@@ -2,7 +2,7 @@ import { useEffect } from 'react'
2
2
  import { createErc8004PublicClient } from '../../registry/erc8004.js'
3
3
  import { confirmAgentInVault } from '../../registry/vault.js'
4
4
  import { invalidateOwnershipCache } from '../shared/reconciliation/index.js'
5
- import type { ProfileUpdates } from '../identityHubReducer.js'
5
+ import type { ProfileUpdates } from '../reducer.js'
6
6
  import type { CustodyFlowDeps } from './types.js'
7
7
  import { humanOwnerAddress } from './helpers.js'
8
8
  import {