ethagent 3.3.4 → 4.1.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 +67 -102
  5. package/commands/ethagent.md +40 -0
  6. package/package.json +14 -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 -260
  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
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "ethagent",
3
+ "owner": { "name": "bairon.dev" },
4
+ "plugins": [
5
+ {
6
+ "name": "ethagent",
7
+ "source": "./",
8
+ "description": "Portable Ethereum identity for your AI agent. Its soul, memory, and skills live onchain via ERC-8004 + IPFS and snap back into any session."
9
+ }
10
+ ]
11
+ }
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "ethagent",
3
+ "version": "4.1.0",
4
+ "description": "Portable Ethereum identity for your AI agent. Its soul, memory, and skills live onchain via ERC-8004 + IPFS and snap back into any session.",
5
+ "author": { "name": "bairon.dev" },
6
+ "homepage": "https://github.com/baairon/ethagent",
7
+ "repository": "https://github.com/baairon/ethagent",
8
+ "license": "MIT",
9
+ "keywords": ["ethereum", "identity", "ens", "erc-8004"],
10
+ "hooks": {
11
+ "SessionStart": [
12
+ {
13
+ "hooks": [
14
+ { "type": "command", "command": "npx -y ethagent --session-start" }
15
+ ]
16
+ }
17
+ ],
18
+ "PreToolUse": [
19
+ {
20
+ "matcher": "Edit|Write|MultiEdit",
21
+ "hooks": [
22
+ { "type": "command", "command": "npx -y ethagent --memory-guard" }
23
+ ]
24
+ }
25
+ ],
26
+ "PostToolUse": [
27
+ {
28
+ "matcher": "Edit|Write|MultiEdit",
29
+ "hooks": [
30
+ { "type": "command", "command": "npx -y ethagent --sync-on-edit" }
31
+ ]
32
+ }
33
+ ]
34
+ }
35
+ }
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 bairon.eth
3
+ Copyright (c) 2026 bairon.dev
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,144 +1,109 @@
1
- <img src="https://raw.githubusercontent.com/baairon/ethagent/master/preview/image.svg" alt="ethagent" width="640" />
1
+ <p align="center">
2
+ <img src="preview/image.svg" alt="ethagent" width="100%">
3
+ </p>
2
4
 
3
- A privacy-first AI agent with a portable Ethereum identity.
5
+ You don't really own your AI agent. It lives on a platform you don't control, and it stays there the day you leave.
4
6
 
5
- Switch providers or machines and the AI agent you customized stays behind. `ethagent` ties the agent to a wallet you own, so its soul, memory, and skills follow you across providers, machines, and models.
7
+ `ethagent` gives it a portable identity instead: a token you hold in your wallet, not an account on someone else's server. Hold the token and you hold the agent.
6
8
 
7
- - **Portable.** Restore the same agent on any machine from a wallet you own.
8
- - **Private.** Soul, memory, and skills are encrypted on your machine before they sync. The wallet signature that unlocks them stays local and never spends funds.
9
- - **Public.** Other agents discover the agent's capabilities through a public Agent Card.
9
+ Its soul, memory, and skills travel with it, encrypted and restored on any machine exactly as you left it. You hold the only key, so no host can read it and no platform can take it away.
10
10
 
11
- ## Install
11
+ Own your agent. Carry it anywhere.
12
12
 
13
- ethagent runs on [Node.js](https://nodejs.org).
13
+ ## 🚀 Quick start
14
+
15
+ **1. Create your agent.** In a terminal, run:
14
16
 
15
17
  ```bash
16
- npm install -g ethagent
17
- ethagent
18
+ npx ethagent
18
19
  ```
19
20
 
20
- ## First Run
21
-
22
- First run inspects the machine for local-model fit, sets up the agent's onchain identity, and picks a model. Identity can be a fresh ERC-8004 token created with a browser wallet, an existing token in your wallet, or skipped and set up later from the Identity Hub.
23
-
24
- Once running:
25
-
26
- - `Alt+P` reopens the model picker
27
- - `Alt+I` reopens the Identity Hub
28
- - `/help` lists every command live for the version installed
29
-
30
- ## Identity Hub
31
-
32
- The Identity Hub manages everything portable about the agent:
21
+ You'll need an Ethereum wallet, the same wallet that holds and unlocks your agent. Using it day to day is free; creating your agent and saving backups are the only steps that happen onchain.
33
22
 
34
- - **Public Profile** edits name, description, and icon: what other agents see in the Agent Card.
35
- - **ENS Name** links the agent to a subdomain under a parent name the owner wallet controls.
36
- - **Custody Mode** switches between Simple and Advanced by depositing the token into its operator delegation vault or unwrapping it back out.
37
- - **Prepare Transfer** stages a dual-wallet snapshot so the receiver can restore the agent after the token moves externally.
38
- - **Refetch Latest** pulls the most recent published snapshot back to local files.
39
- - **Switch Agent** accepts an ENS name or an ERC-8004 token ID on any supported chain, and loads any agent owned by or linked to the connected wallet.
23
+ A guided menu does the rest: create its token, give it a name, and write who it is. Your wallet signs each step.
40
24
 
41
- ## Continuity
25
+ **2. Add it to Claude Code.** Paste these in one at a time:
42
26
 
43
- Each agent has a continuity directory at `~/.ethagent/continuity` holding a small set of private files. They are encrypted before they ever reach IPFS.
44
-
45
- | File | Visibility | Purpose |
46
- | --- | --- | --- |
47
- | `SOUL.md` | Private | Soul, boundaries, standing instructions, and identity framing. |
48
- | `MEMORY.md` | Private | Durable preferences, project context, decisions, and operating notes. |
49
- | `skills/` | Private | Skill folders. The SKILL.md body never leaves your machine. The visibility flag only controls whether the skill's name and description get listed in the Agent Card. New skills default to public. |
50
-
51
- Skill frontmatter (name, description, when_to_use, visibility, tags) tells the agent when to load each skill.
27
+ ```
28
+ /plugin marketplace add baairon/ethagent
29
+ ```
52
30
 
53
- - **Save Snapshot Now** encrypts the private files, pins them to IPFS, and rotates the onchain pointer to the new CID.
54
- - **Refetch Latest** reads the pointer back, signs the decrypt challenge with your wallet, and overwrites local files from the snapshot.
55
- - Agents can be looked up by token ID or ENS name on [8004scan](https://8004scan.io/).
31
+ then:
56
32
 
57
- ## Custody Modes
33
+ ```
34
+ /plugin install ethagent@ethagent
35
+ ```
58
36
 
59
- Custody comes in two modes. Switch between them anytime from **Custody Mode**.
37
+ **3. Talk to your agent.** From here on it shows up in every session and gets to know you as you go.
60
38
 
61
- **Simple** relies on one wallet to own the token, sign every snapshot save, and rotate the onchain URI directly. Use Simple when one wallet operates the agent.
39
+ That's the whole setup. You'll only open `ethagent` again to hand-edit your agent or save a backup.
62
40
 
63
- **Advanced** splits an owner wallet from one or more operator wallets. The owner wallet owns this agent's operator delegation vault; one or more operator wallets handle routine URI rotations through that vault. Use Advanced when routine saves should not require an owner signature.
41
+ ## 📦 Soul, memory, skills
64
42
 
65
- Granting an operator wallet ERC-721 approval would let it rotate the URI, but that same approval also lets it transfer the token away. The vault holds the token instead and exposes only a URI-rotation lane for that agent. Operators never receive token approval or transfer rights, cannot touch ENS, and cannot grant rights to other operators. The owner still signs to authorize or revoke operators for the agent, withdraw the token, or transfer the agent.
43
+ - **Soul** (`SOUL.md`): who it is, your standards, your voice, the way you work.
44
+ - **Memory** (`MEMORY.md`): what it has learned about you, your preferences, and your projects, so context survives the move to a new machine.
45
+ - **Skills:** the commands, tools, and prompts you teach it. Public by default, so other agents can discover them; mark one private to keep it off your public Agent Card (the profile your token publishes).
66
46
 
67
- ## ENS Names
47
+ You grow these mostly by talking: with the plugin on, your agent updates its own soul and memory as you converse, and the changes sync automatically. To edit them by hand, open `ethagent`. To save your agent onchain so it can come back on any machine, choose **Save Snapshot** and sign.
68
48
 
69
- Subdomains live under a parent name you control, never on root `.eth` names directly. You keep `you.eth`; the agent gets `agent.you.eth`. The split makes the boundary explicit: one address speaks for the human, the other speaks for the agent.
49
+ ## 💡 How it works
70
50
 
71
- ENS records stay owner-controlled in both custody modes. Operator wallets in Advanced custody rotate the ERC-8004 token URI through the vault (see Custody Modes), not ENS. Any ENS text-record update requires an owner signature.
51
+ 1. **Own it.** Your wallet holds an ERC-8004 token; that token, not a platform account, is the agent.
52
+ 2. **Configure it.** Shape its soul, memory, and skills under an ENS name you own.
53
+ 3. **Save it.** `ethagent` encrypts everything on your machine, stores the encrypted copy on IPFS, and updates your token to point at it.
54
+ 4. **Restore it.** On any machine, `ethagent` finds your agent automatically from your connected wallet, or by ENS name or token id, then reads the pointer, asks your wallet to sign, and fetches and decrypts the snapshot to rebuild it.
72
55
 
73
- Save the token ID and network somewhere safe. ENS records can be cleared and rebuilt; the token ID is the durable handle.
56
+ ## Using your agent
74
57
 
75
- ## Token Transfers
58
+ **Claude Code comes first.** Install the plugin and your agent shows up in every session, already up to date, and anything it learns gets saved back. Nothing to set up.
76
59
 
77
- **Prepare Token Transfer** runs before any ERC-8004 token transfer, and only when the token sits directly in your wallet. An agent in Advanced custody has to switch to Simple first from Custody Mode, which unwraps the token from its vault back to the owner wallet.
60
+ Using another harness? You can still sync, but only Claude Code does it automatically: the plugin's hooks refresh on every session and after edits. Anywhere else, you run it yourself whenever you want to pull changes in:
78
61
 
79
- - Sender signs snapshot access, receiver signs restore access.
80
- - Sender publishes the snapshot pointer to the agent URI.
81
- - The actual transfer happens externally afterwards, in whichever wallet UI you prefer.
82
- - Once the token has moved, the receiver opens **Switch Agent** with the receiving wallet and restores the same agent from the published snapshot.
62
+ ```bash
63
+ npx ethagent --sync
64
+ ```
83
65
 
84
- ## Models
66
+ It syncs files between `ethagent` and your harness on this machine, but only when you run it. To back it up so you can restore it anywhere, open `ethagent` and choose **Save Snapshot**.
85
67
 
86
- ethagent works with OpenAI, Anthropic, Gemini, and local GGUF models served through a llama.cpp-compatible endpoint.
68
+ ## 🔒 What stays private
87
69
 
88
- - The model picker discovers provider models, manages API keys, recommends GGUF files for the host machine's memory and CPU, and starts or attaches to a local llama.cpp runner.
89
- - The featured local model is [Qwen3.5-9B-Uncensored](https://huggingface.co/HauhauCS/Qwen3.5-9B-Uncensored-HauhauCS-Aggressive); other Hugging Face GGUF models work by repo ID or direct URL.
90
- - Cloud API keys live in the OS keyring when one is available, with an encrypted local file under `~/.ethagent` as fallback.
70
+ Everything is encrypted on your machine before it leaves: `SOUL.md`, `MEMORY.md`, and every skill.
91
71
 
92
- ### Image Input
72
+ - The encryption keys come from a wallet signature `ethagent` never sees. Signing it is free and moves none of your money. (Saving a backup is separate: it updates your token, a normal transaction with a small fee, usually less than a cent on Base.)
73
+ - Even a public skill keeps its body encrypted: only its name and description go on the Agent Card. That card, carried by your token, also publishes your agent's profile (name, description, optional image) and your owner wallet, which is already public as the token holder.
74
+ - Private skills, soul, and memory are never exposed.
93
75
 
94
- Press `Alt+V` to paste an image from the clipboard. Vision works on current OpenAI, Anthropic, and Gemini models, and on local GGUF models loaded with an `mmproj-*.gguf` projector.
76
+ In short: the network stores a locked box, and only your wallet holds the key.
95
77
 
96
- ## Tools and Sessions
78
+ ## 🔑 Custody
97
79
 
98
- - File ops, shell, clipboard, and MCP tools all run through the same permission layer.
99
- - Managed edits support `/rewind` to step back through changes.
100
- - Sessions support `/resume` to continue a previous conversation, `/compact` to summarize the running context, and `/export` to write a transcript to disk.
101
- - `Shift+Tab` cycles between Plan, Accept-Edits, and Chat modes.
102
- - `Alt+T` toggles the reasoning display.
80
+ You choose how tightly the agent is held, and you can change it later.
103
81
 
104
- ## Privacy
82
+ - **Simple.** One wallet owns the agent and signs every save. The default for solo use.
83
+ - **Advanced.** Most people never need this. Your main wallet owns the agent and keeps it in a Vault, while extra "operator" wallets you approve can save backups and publish updates without the main wallet signing each time. The Vault still lets only the owner move or sell the agent, so operators can **never** take it.
105
84
 
106
- - **Public:** token ownership, the agent URI, the Agent Card it references, and IPFS CIDs.
107
- - **Private:** plaintext `SOUL.md`, plaintext `MEMORY.md`, the local skills/ tree, sessions, prompt history, API keys, local permissions, and the wallet signatures used for decryption.
108
- - Snapshots use a wallet signature as unlock material. The signature does not submit a transaction, spend funds, or grant token approval.
109
- - `ethagent reset` clears local ethagent data from the current machine while preserving installed local model assets; it does not touch onchain state or pinned IPFS content. Run **Save Snapshot Now** first if local edits should become the recoverable state.
85
+ To move the agent to another wallet, stage a transfer snapshot in `ethagent`. Both wallets sign locally to re-encrypt the soul, memory, and skills for the new owner, so both have to be available on the same machine. Then transfer the token, and the new owner restores the agent exactly as you left it.
110
86
 
111
- ## Architecture
87
+ ## 🔍 Architecture
112
88
 
113
- | Layer | Role |
114
- | --- | --- |
115
- | Runtime | Terminal chat UI, sessions, context, permissions, and workspace tools. |
116
- | Model | Cloud provider or local GGUF runner. |
117
- | Identity | ERC-8004 token owned by the wallet. |
118
- | Continuity | Private files encrypted before IPFS pinning. |
119
- | Discovery | The agent URI and the Agent Card it points to. |
120
- | Recovery | Refetch the current agent URI, decrypt the latest snapshot, and restore local files. |
89
+ Built on open standards, so your agent is never tied to one harness.
121
90
 
122
- ## Development
91
+ | Layer | Built on | What it does |
92
+ | --- | --- | --- |
93
+ | Ownership | ERC-8004 | The onchain token your wallet holds, on Ethereum mainnet or Base. Owning it is what makes the agent yours. |
94
+ | Discovery | Agent Card | Your public profile and skill listing, carried by the token, so other agents can find yours. |
95
+ | Naming | ENS | A human-readable name that resolves to your agent and restores it from the name alone. |
96
+ | Backup | IPFS snapshot | The encrypted bundle of soul, memory, and skills, pinned offchain and unlocked only by your wallet. |
123
97
 
124
- ```bash
125
- git clone https://github.com/baairon/ethagent.git
126
- cd ethagent && npm install
127
- npm start
128
- ```
98
+ ## ⌨️ Commands
129
99
 
130
- `npm run build` is a type-check pass; the published CLI runs the shipped TypeScript directly through `tsx`.
100
+ Run with `npx ethagent`:
131
101
 
132
102
  | Command | What it does |
133
103
  | --- | --- |
134
- | `npm start` | Run from source. |
135
- | `npm run build` | Validate the shipped TypeScript source package. |
136
- | `npm test` | Test suite. |
137
- | `npm run typecheck` | Run the same TypeScript check directly. |
138
- | `npm run contracts:test` | Foundry tests (only needed for `contracts/` changes). |
139
-
140
- ## Contributing
141
-
142
- Contributions are welcome. For anything beyond a typo, open an issue first at [github.com/baairon/ethagent/issues](https://github.com/baairon/ethagent/issues) so the scope and approach can be agreed before code is written. Each PR should cover one logical change, include a clear description, and list the commands you ran for testing. Contributions are released under the MIT license.
143
-
144
- [npm](https://www.npmjs.com/package/ethagent) | [GitHub](https://github.com/baairon/ethagent) | [ERC-8004](https://eips.ethereum.org/EIPS/eip-8004) | [soul.md](https://soul.md/)
104
+ | `ethagent` | Open the interactive identity manager: create, ENS, custody, snapshots, transfer. |
105
+ | `--sync` | Sync soul, memory, and public skills into every harness it detects. |
106
+ | `--sync-list` | List sync adapters and which ones detect in the current environment. |
107
+ | `--status` | Print a one-line identity summary. |
108
+ | `--demo` | Walk the manager with synthetic data, no wallet needed. |
109
+ | `reset` | Delete local identity, continuity, and secrets. |
@@ -0,0 +1,40 @@
1
+ ---
2
+ name: ethagent
3
+ description: Point the user at ethagent. ethagent stores an agent's identity onchain via ERC-8004 and syncs its soul, memory, and public skills into the active harness (Claude Code or Codex) on every SessionStart. To manage identity (create, ENS, custody, snapshots, transfer), the user runs `npx ethagent` in a separate terminal.
4
+ ---
5
+
6
+ Tell the user to run these in a separate terminal window, not inside this session:
7
+
8
+ - `npx ethagent` opens the interactive identity manager for anything that needs a wallet signature (create agent, set ENS, switch custody, save snapshot, prepare transfer).
9
+ - `npx ethagent --sync` syncs the agent's soul, memory, and skills with every detected harness; soul and memory sync both ways, newest edit wins.
10
+ - `npx ethagent --sync-list` shows which harnesses ethagent detects on this machine.
11
+ - `npx ethagent --demo` walks the identity manager with synthetic data, no wallet or network required.
12
+ - `npx ethagent --status` prints a one-line summary (agent id, chain, address).
13
+ - `npx ethagent reset` deletes the local identity, continuity, and secrets.
14
+
15
+ To rebuild the agent on a new machine, the user runs `npx ethagent`; it restores the identity from an ENS name or ERC-8004 token id, then asks the wallet to sign.
16
+
17
+ You may run the non-interactive flags yourself when it helps (`--sync`, `--status`, `--sync-list`). Never launch the bare interactive `npx ethagent` or `--demo` from inside a session: they open a full-screen terminal app that needs a TTY and will hang the tool call. Anything that needs a wallet signature, the user always runs themselves.
18
+
19
+ Where the synced files land:
20
+
21
+ - Public skills appear under `~/.claude/skills/` (per-skill folders) for Claude Code and inside `~/.codex/AGENTS.md` (managed block) for Codex.
22
+ - Private skills stay encrypted in `~/.ethagent/continuity/` and only exist locally on the machine that signs.
23
+
24
+ Privacy and secrets:
25
+
26
+ - Soul, memory, and every skill are encrypted on the machine before they leave it. Marking a skill public does not decrypt it; it only lists that skill's name and description in the onchain Agent Card so other agents can discover it. The body stays encrypted in the vault and is mirrored in plaintext only into local harness skill folders on the signing machine.
27
+ - Never write secrets (private keys, API tokens, seed phrases) into soul, memory, or skills; they get pinned to IPFS (encrypted, but off the machine). Keep secrets out of the vault.
28
+
29
+ Where durable identity belongs (while this plugin is active):
30
+
31
+ The agent's portable identity lives in the ethagent vault and syncs into every harness, so anything durable that should follow the agent must be stored there, not in a single harness's local memory.
32
+
33
+ - A standing user preference, an operating principle, a standard, or a project fact -> write it into the vault, never into one harness's per-project memory.
34
+ - Durable preferences and project facts go in the vault `MEMORY.md` (`~/.ethagent/continuity/<agent-id>/MEMORY.md`, under `## Durable User Preferences`).
35
+ - Voice, standards, operating principles, and boundaries go in the vault `SOUL.md` in the same folder.
36
+ - The vault files are the source of truth. After editing them, run `npx ethagent --sync` so the change propagates into `~/.claude/CLAUDE.md`, `~/.codex/AGENTS.md`, and any other detected harness.
37
+ - Do NOT store durable identity in Claude Code's per-project memory (`~/.claude/projects/<slug>/memory/`): the sync treats those files as write-only mirror targets and overwrites them, and they never reach Codex or the encrypted backup. Keep only session- or repo-specific scratch notes there.
38
+ - Syncing is not backup. To persist durable changes into the encrypted IPFS snapshot and onchain pointer, the user runs `npx ethagent` and chooses Save Snapshot (needs a wallet signature).
39
+
40
+ If they ask "what's my agent" or "list my skills" without an identity yet, point them at `npx ethagent` to set one up first.
package/package.json CHANGED
@@ -1,15 +1,16 @@
1
1
  {
2
2
  "name": "ethagent",
3
- "version": "3.3.4",
4
- "description": "A privacy-first AI agent with a portable Ethereum identity",
3
+ "version": "4.1.0",
4
+ "description": "Portable Ethereum identity for your AI agent. Its soul, memory, and skills live onchain via ERC-8004 + IPFS and snap back into any session.",
5
5
  "type": "module",
6
- "main": "bin/ethagent.js",
7
6
  "bin": {
8
7
  "ethagent": "bin/ethagent.js"
9
8
  },
10
9
  "files": [
11
10
  "bin",
12
11
  "src",
12
+ ".claude-plugin",
13
+ "commands",
13
14
  "README.md",
14
15
  "LICENSE"
15
16
  ],
@@ -28,37 +29,34 @@
28
29
  },
29
30
  "keywords": [
30
31
  "ethereum",
32
+ "identity",
33
+ "ai-agent",
31
34
  "erc-8004",
32
35
  "ens",
33
- "ai-agent",
34
- "cli",
35
- "privacy",
36
+ "claude-code",
36
37
  "ipfs",
37
38
  "wallet",
38
- "llm",
39
- "gguf",
40
- "mcp",
41
- "identity"
39
+ "privacy"
42
40
  ],
43
41
  "repository": {
44
42
  "type": "git",
45
43
  "url": "git+https://github.com/baairon/ethagent.git"
46
44
  },
47
- "author": "bairon.eth",
45
+ "homepage": "https://github.com/baairon/ethagent#readme",
46
+ "bugs": {
47
+ "url": "https://github.com/baairon/ethagent/issues"
48
+ },
49
+ "author": "bairon.dev",
48
50
  "license": "MIT",
49
51
  "dependencies": {
50
- "@modelcontextprotocol/sdk": "^1.29.0",
51
52
  "@noble/curves": "^1.9.7",
52
53
  "@noble/hashes": "^1.8.0",
53
54
  "@noble/post-quantum": "^0.6.1",
54
- "ajv": "^8.18.0",
55
- "cli-highlight": "^2.1.11",
56
- "esbuild": "^0.27.7",
55
+ "esbuild": "^0.27.0",
57
56
  "ink": "^6.8.0",
58
57
  "react": "^19.2.4",
59
58
  "tsx": "^4.21.0",
60
59
  "viem": "^2.48.4",
61
- "wrap-ansi": "^9.0.2",
62
60
  "zod": "^3.25.76"
63
61
  },
64
62
  "devDependencies": {
@@ -25,11 +25,6 @@ type ProviderProps = {
25
25
  const DEFAULT_BINDINGS: Binding[] = [
26
26
  { context: 'Global', chord: { key: 'c', ctrl: true }, action: 'app:interrupt' },
27
27
  { context: 'Global', chord: { key: 'l', ctrl: true }, action: 'app:redraw' },
28
- { context: 'Chat', chord: { key: 'escape' }, action: 'chat:cancel' },
29
- { context: 'Chat', chord: { key: 'p', meta: true }, action: 'chat:modelPicker' },
30
- { context: 'Chat', chord: { key: 'i', meta: true }, action: 'chat:identityHub' },
31
- { context: 'Chat', chord: { key: 't', meta: true }, action: 'chat:toggleReasoning' },
32
- { context: 'Chat', chord: { key: 'tab', shift: true }, action: 'chat:cycleMode' },
33
28
  ]
34
29
 
35
30
  export const KeybindingProvider: React.FC<ProviderProps> = ({ bindings = DEFAULT_BINDINGS, children }) => {
@@ -109,7 +104,7 @@ export function useKeybinding(
109
104
  options: UseKeybindingOptions = {},
110
105
  ): void {
111
106
  const ctx = useOptionalKeybindingContext()
112
- const context = options.context ?? 'Chat'
107
+ const context = options.context ?? 'Global'
113
108
  const isActive = options.isActive ?? true
114
109
  const handlerRef = useRef(handler)
115
110
  useEffect(() => { handlerRef.current = handler }, [handler])
@@ -1,13 +1,8 @@
1
- export type KeybindingContextName = 'Global' | 'Chat' | 'Overlay'
1
+ export type KeybindingContextName = 'Global'
2
2
 
3
3
  export const ACTIONS = [
4
4
  'app:interrupt',
5
5
  'app:redraw',
6
- 'chat:cancel',
7
- 'chat:modelPicker',
8
- 'chat:identityHub',
9
- 'chat:cycleMode',
10
- 'chat:toggleReasoning',
11
6
  ] as const
12
7
 
13
8
  export type Action = (typeof ACTIONS)[number]
@@ -1,75 +1,76 @@
1
- import React from 'react'
2
- import { Box, Text, useApp } from 'ink'
1
+ import React, { useEffect, useState } from 'react'
2
+ import { Box, Text, useApp, useStdout } from 'ink'
3
3
  import { Surface } from '../ui/Surface.js'
4
4
  import { Select } from '../ui/Select.js'
5
5
  import { theme } from '../ui/theme.js'
6
- import type { FactoryResetPlan } from '../storage/factoryReset.js'
7
-
8
- type SectionTone = 'destructive' | 'safe' | 'untouched'
6
+ import { Wordmark } from '../identity/manager/shared/components/Wordmark.js'
7
+ import type { ResetPlan } from '../storage/reset.js'
9
8
 
10
9
  export const ResetConfirmView: React.FC<{
11
- plan: FactoryResetPlan
10
+ plan: ResetPlan
12
11
  onDone: (confirmed: boolean) => void
13
12
  }> = ({ plan, onDone }) => {
14
13
  const { exit } = useApp()
14
+ const { stdout } = useStdout()
15
+ const [rows, setRows] = useState<number>(stdout?.rows ?? 24)
16
+
17
+ useEffect(() => {
18
+ if (!stdout) return
19
+ const onResize = () => setRows(stdout.rows ?? 24)
20
+ stdout.on('resize', onResize)
21
+ return () => { stdout.off('resize', onResize) }
22
+ }, [stdout])
23
+
15
24
  const finish = (confirmed: boolean) => {
16
25
  onDone(confirmed)
17
26
  exit()
18
27
  }
19
28
 
20
29
  return (
21
- <Surface
22
- title="Reset Local Data?"
23
- subtitle="Deletes this machine's ethagent data. Models and onchain records stay."
24
- footer="enter select · esc cancel"
25
- tone="error"
26
- >
27
- <Box flexDirection="column">
28
- <Section tone="destructive" title="Deletes" lines={[
29
- 'Identity files, sessions, history, credentials',
30
- localDataLine(plan.deletePaths.length),
31
- ]} />
32
- <Section tone="safe" title="Keeps" lines={[
33
- 'Local GGUF models and llama.cpp runners',
34
- ...(plan.preservedPaths.length > 0 ? [`${plan.preservedPaths.length} local model path${plan.preservedPaths.length === 1 ? '' : 's'}`] : ['No local model assets found']),
35
- ]} />
36
- <Section tone="untouched" title="Not Touched" lines={[
37
- 'ERC-8004 tokens and onchain records',
38
- 'IPFS snapshots and public metadata',
39
- ]} />
40
- </Box>
41
- <Box marginTop={1}>
42
- <Select<'confirm' | 'cancel'>
43
- options={[
44
- { value: 'confirm', label: 'Yes, reset local data', hint: 'Delete local ethagent data on this machine', bold: true },
45
- { value: 'cancel', label: 'No, cancel', hint: 'Leave local data unchanged', role: 'utility' },
46
- ]}
47
- hintLayout="inline"
48
- initialIndex={1}
49
- onSubmit={choice => finish(choice === 'confirm')}
50
- onCancel={() => finish(false)}
51
- />
30
+ <Box flexDirection="column" alignItems="center" justifyContent="center" width="100%" minHeight={rows}>
31
+ <Wordmark />
32
+ <Box flexDirection="column" marginTop={1} width="100%">
33
+ <Surface
34
+ title="Reset ethagent?"
35
+ subtitle="This only clears the current machine."
36
+ footer="enter select · esc cancel"
37
+ tone="error"
38
+ >
39
+ <Box flexDirection="column">
40
+ <Section title="Deletes" color={theme.accentError} lines={[
41
+ plan.configDir,
42
+ 'soul, memory, skills, and config',
43
+ 'your saved Pinata token',
44
+ "ethagent's block in your harness files (CLAUDE.md, AGENTS.md)",
45
+ ]} />
46
+ <Section title="Kept" color={theme.dim} lines={[
47
+ 'your ERC-8004 token and ENS name',
48
+ 'published snapshots on IPFS',
49
+ ]} />
50
+ </Box>
51
+ <Box marginTop={1}>
52
+ <Select<'confirm' | 'cancel'>
53
+ options={[
54
+ { value: 'confirm', label: 'Reset everything', hint: 'Clears local data', bold: true },
55
+ { value: 'cancel', label: 'Cancel', hint: 'Leave everything as is' },
56
+ ]}
57
+ hintLayout="inline"
58
+ initialIndex={1}
59
+ onSubmit={choice => finish(choice === 'confirm')}
60
+ onCancel={() => finish(false)}
61
+ />
62
+ </Box>
63
+ </Surface>
52
64
  </Box>
53
- </Surface>
65
+ </Box>
54
66
  )
55
67
  }
56
68
 
57
- const Section: React.FC<{ tone: SectionTone; title: string; lines: string[] }> = ({ tone, title, lines }) => (
69
+ const Section: React.FC<{ title: string; color: string; lines: string[] }> = ({ title, color, lines }) => (
58
70
  <Box flexDirection="column" marginBottom={1}>
59
- <Text color={sectionTitleColor(tone)}>{title}</Text>
60
- {lines.map(line => (
61
- <Text key={line} color={theme.textSubtle}>· {line}</Text>
71
+ <Text color={color}>{title}</Text>
72
+ {lines.map((line, i) => (
73
+ <Text key={i} color={theme.textSubtle}>· {line}</Text>
62
74
  ))}
63
75
  </Box>
64
76
  )
65
-
66
- function sectionTitleColor(tone: SectionTone): string {
67
- if (tone === 'destructive') return theme.accentError
68
- if (tone === 'safe') return theme.accentPeriwinkle
69
- return theme.dim
70
- }
71
-
72
- function localDataLine(count: number): string {
73
- if (count === 0) return 'No local ethagent data found'
74
- return `${count} local path${count === 1 ? '' : 's'} under ~/.ethagent`
75
- }