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.
- package/.claude-plugin/marketplace.json +11 -0
- package/.claude-plugin/plugin.json +35 -0
- package/LICENSE +1 -1
- package/README.md +67 -102
- package/commands/ethagent.md +40 -0
- package/package.json +14 -16
- package/src/app/keybindings/KeybindingProvider.tsx +1 -6
- package/src/app/keybindings/types.ts +1 -6
- package/src/cli/ResetConfirmView.tsx +54 -53
- package/src/cli/demo.ts +86 -0
- package/src/cli/hookIo.ts +45 -0
- package/src/cli/main.tsx +94 -123
- package/src/cli/memoryGuard.ts +49 -0
- package/src/cli/reset.ts +28 -70
- package/src/cli/sessionStart.ts +33 -0
- package/src/cli/status.ts +46 -0
- package/src/cli/sync.ts +167 -0
- package/src/cli/syncAdapters/claude-code.ts +86 -0
- package/src/cli/syncAdapters/codex.ts +66 -0
- package/src/cli/syncAdapters/index.ts +45 -0
- package/src/cli/syncAdapters/managedBlock.ts +175 -0
- package/src/cli/syncAdapters/shared.ts +63 -0
- package/src/identity/continuity/envelopeParse.ts +20 -1
- package/src/identity/continuity/publicSkills.ts +3 -1
- package/src/identity/continuity/skills/publicSkillsSync.ts +2 -1
- package/src/identity/continuity/skills/scaffold.ts +5 -2
- package/src/identity/continuity/snapshots.ts +12 -5
- package/src/identity/continuity/storage/defaults.ts +20 -19
- package/src/identity/continuity/storage/status.ts +1 -1
- package/src/identity/ens/ensLookup/constants.ts +1 -1
- package/src/identity/manager/IdentityManager.tsx +33 -0
- package/src/identity/{hub → manager}/OperationalRoutes.tsx +37 -18
- package/src/identity/{hub → manager}/Routes.tsx +48 -34
- package/src/identity/{hub → manager}/continuity/ContinuityDashboardScreen.tsx +9 -19
- package/src/identity/{hub → manager}/continuity/RebackupStorageScreen.tsx +3 -3
- package/src/identity/manager/continuity/RecoveryConfirmScreen.tsx +102 -0
- package/src/identity/{hub → manager}/continuity/SavePromptScreen.tsx +2 -3
- package/src/identity/{hub → manager}/continuity/completion.ts +1 -1
- package/src/identity/{hub → manager}/continuity/effects.ts +1 -1
- package/src/identity/{hub → manager}/continuity/skills/DeleteSkillConfirmScreen.tsx +2 -2
- package/src/identity/{hub → manager}/continuity/skills/NewSkillScreen.tsx +0 -5
- package/src/identity/{hub → manager}/continuity/skills/NewSkillVisibilityScreen.tsx +4 -4
- package/src/identity/{hub → manager}/continuity/skills/SkillActionsScreen.tsx +6 -22
- package/src/identity/{hub → manager}/continuity/skills/SkillsTreeScreen.tsx +5 -17
- package/src/identity/{hub → manager}/continuity/snapshot.ts +1 -1
- package/src/identity/{hub → manager}/continuity/vault.ts +1 -1
- package/src/identity/{hub → manager}/create/CreateFlow.tsx +59 -32
- package/src/identity/{hub → manager}/create/effects.ts +19 -10
- package/src/identity/manager/create/importScan.ts +122 -0
- package/src/identity/{hub → manager}/custody/CustodyEditFlow.tsx +17 -61
- package/src/identity/{hub → manager}/custody/actions.ts +1 -15
- package/src/identity/{hub → manager}/custody/routes.tsx +20 -40
- package/src/identity/{hub → manager}/custody/transactions.ts +1 -0
- package/src/identity/{hub → manager}/custody/types.ts +1 -2
- package/src/identity/{hub → manager}/custody/useCustodyEffects.ts +1 -1
- package/src/identity/{hub → manager}/ens/EnsEditAdvancedScreens.tsx +2 -2
- package/src/identity/{hub → manager}/ens/EnsEditMaintenanceScreens.tsx +12 -23
- package/src/identity/{hub → manager}/ens/EnsEditReviewScreens.tsx +18 -42
- package/src/identity/{hub → manager}/ens/EnsEditRunners.tsx +1 -1
- package/src/identity/{hub → manager}/ens/EnsEditShared.tsx +0 -2
- package/src/identity/{hub → manager}/ens/EnsEditSimpleScreens.tsx +10 -19
- package/src/identity/{hub → manager}/ens/EnsFlow.tsx +133 -41
- package/src/identity/{hub → manager}/ens/EnsOperatorWalletsScreen.tsx +14 -19
- package/src/identity/{hub → manager}/ens/editCopy.ts +1 -14
- package/src/identity/{hub → manager}/profile/EditProfileFlow.tsx +99 -66
- package/src/identity/{hub → manager}/profile/effects.ts +1 -3
- package/src/identity/{hub → manager}/profile/operatorSave.ts +1 -1
- package/src/identity/{hub → manager}/profile/state.ts +1 -1
- package/src/identity/{hub/identityHubReducer.ts → manager/reducer.ts} +25 -26
- package/src/identity/{hub → manager}/restore/RestoreFlow.tsx +16 -24
- package/src/identity/{hub → manager}/restore/apply.ts +1 -1
- package/src/identity/{hub → manager}/restore/auth.ts +1 -1
- package/src/identity/{hub → manager}/restore/discover.ts +1 -1
- package/src/identity/{hub → manager}/restore/fetch.ts +1 -1
- package/src/identity/{hub → manager}/restore/restoreAdmin.ts +1 -1
- package/src/identity/{hub → manager}/restore/useRestoreEffects.ts +2 -9
- package/src/identity/{hub → manager}/settings/StorageCredentialScreen.tsx +10 -25
- package/src/identity/{hub → manager}/shared/components/DetailsScreen.tsx +5 -7
- package/src/identity/{hub → manager}/shared/components/ErrorScreen.tsx +6 -10
- package/src/identity/{hub → manager}/shared/components/FlowTimeline.tsx +4 -3
- package/src/identity/{hub → manager}/shared/components/IdentitySummary.tsx +19 -59
- package/src/identity/manager/shared/components/LazyMenu.tsx +147 -0
- package/src/identity/manager/shared/components/MenuScreen.tsx +220 -0
- package/src/identity/manager/shared/components/OperationCompleteScreen.tsx +28 -0
- package/src/identity/{hub → manager}/shared/components/UnlinkedIdentityScreen.tsx +9 -10
- package/src/identity/{hub → manager}/shared/components/WalletApprovalScreen.tsx +1 -2
- package/src/identity/manager/shared/components/Wordmark.tsx +54 -0
- package/src/identity/{hub → manager}/shared/components/menuFlagsFromReconciliation.ts +39 -15
- package/src/identity/{hub → manager}/shared/effects/profilePrep.ts +1 -1
- package/src/identity/manager/shared/effects/types.ts +30 -0
- package/src/identity/{hub → manager}/shared/model/copy.ts +0 -4
- package/src/identity/{hub → manager}/shared/model/errors.ts +32 -3
- package/src/identity/{hub → manager}/shared/model/network.ts +2 -2
- package/src/identity/{hub → manager}/shared/reconciliation/agentReconciliation/hook.ts +5 -0
- package/src/identity/{hub → manager}/shared/reconciliation/agentReconciliation/run.ts +1 -1
- package/src/identity/{hub/shared/reconciliation/useAgentReconciliation.ts → manager/shared/reconciliation/index.ts} +6 -0
- package/src/identity/{hub → manager}/shared/utils.ts +6 -10
- package/src/identity/{hub → manager}/transfer/TokenTransferFlow.tsx +3 -3
- package/src/identity/{hub → manager}/transfer/TokenTransferScreens.tsx +4 -10
- package/src/identity/{hub → manager}/transfer/effects.ts +1 -1
- package/src/identity/{hub → manager}/types.ts +5 -6
- package/src/identity/{hub/useIdentityHubContinuity.ts → manager/useContinuity.ts} +59 -27
- package/src/identity/{hub/useIdentityHubController.ts → manager/useController.ts} +38 -35
- package/src/identity/{hub/useIdentityHubSideEffects.ts → manager/useSideEffects.ts} +40 -4
- package/src/identity/registry/erc8004/discovery.ts +3 -17
- package/src/identity/registry/erc8004/utils.ts +1 -1
- package/src/identity/storage/ipfs.ts +21 -1
- package/src/identity/wallet/browserWallet/html.ts +10 -2
- package/src/identity/wallet/browserWallet/http.ts +18 -0
- package/src/identity/wallet/browserWallet/requestServer.ts +5 -1
- package/src/identity/wallet/browserWallet/requests.ts +10 -28
- package/src/identity/wallet/browserWallet/session.ts +26 -33
- package/src/identity/wallet/browserWallet/validation.ts +14 -0
- package/src/identity/wallet/browserWallet/walletPageSource.ts +22 -40
- package/src/identity/wallet/page/boot.ts +43 -0
- package/src/identity/wallet/page/config.ts +59 -0
- package/src/identity/wallet/page/constants.ts +12 -0
- package/src/identity/wallet/page/copy.ts +47 -68
- package/src/identity/wallet/page/css.ts +638 -0
- package/src/identity/wallet/page/{errorView.ts → errors.ts} +5 -14
- package/src/identity/wallet/page/{controller.ts → flow.ts} +4 -71
- package/src/identity/wallet/page/markup.ts +44 -34
- package/src/identity/wallet/page/{walletProvider.ts → provider.ts} +0 -3
- package/src/identity/wallet/page/resize.ts +95 -0
- package/src/identity/wallet/page/state.ts +135 -8
- package/src/identity/wallet/page/timeline.ts +161 -0
- package/src/identity/wallet/page/view.ts +22 -302
- package/src/storage/config.ts +30 -80
- package/src/storage/reset.ts +31 -0
- package/src/storage/secrets.ts +1 -16
- package/src/ui/Select.tsx +27 -5
- package/src/ui/Spinner.tsx +16 -15
- package/src/ui/Surface.tsx +21 -17
- package/src/ui/TextArea.tsx +173 -0
- package/src/ui/TextInput.tsx +31 -133
- package/src/ui/theme.ts +22 -13
- package/src/utils/clipboard.ts +0 -140
- package/src/app/FirstRun.tsx +0 -577
- package/src/app/FirstRunTimeline.tsx +0 -51
- package/src/app/firstRunConfig.ts +0 -26
- package/src/app/hooks/useCancelRequest.ts +0 -22
- package/src/app/hooks/useDoublePress.ts +0 -46
- package/src/app/hooks/useExitOnCtrlC.ts +0 -36
- package/src/auth/openaiOAuth/credentials.ts +0 -47
- package/src/auth/openaiOAuth/crypto.ts +0 -23
- package/src/auth/openaiOAuth/index.ts +0 -238
- package/src/auth/openaiOAuth/landingPage.ts +0 -116
- package/src/auth/openaiOAuth/listener.ts +0 -151
- package/src/auth/openaiOAuth/refresh.ts +0 -70
- package/src/auth/openaiOAuth/shared.ts +0 -115
- package/src/chat/ChatBottomPane.tsx +0 -296
- package/src/chat/ChatScreen.tsx +0 -1685
- package/src/chat/ConversationStack.tsx +0 -56
- package/src/chat/MessageList.tsx +0 -638
- package/src/chat/SessionStatus.tsx +0 -53
- package/src/chat/chatEnvironment.ts +0 -16
- package/src/chat/chatScreenUtils.ts +0 -194
- package/src/chat/chatSessionState.ts +0 -146
- package/src/chat/chatTurnContext.ts +0 -50
- package/src/chat/chatTurnOrchestrator.ts +0 -603
- package/src/chat/chatTurnRows.ts +0 -64
- package/src/chat/commands.ts +0 -494
- package/src/chat/continuityEditReview.ts +0 -42
- package/src/chat/display/DiffView.tsx +0 -193
- package/src/chat/display/SyntaxText.tsx +0 -192
- package/src/chat/display/toolCallDisplay.ts +0 -103
- package/src/chat/display/toolResultDisplay.ts +0 -19
- package/src/chat/input/ChatInput.tsx +0 -625
- package/src/chat/input/chatInputHelpers.ts +0 -62
- package/src/chat/input/chatInputState.ts +0 -247
- package/src/chat/input/chatPaste.ts +0 -49
- package/src/chat/input/imageRefs.ts +0 -30
- package/src/chat/input/inputRendering.tsx +0 -93
- package/src/chat/input/textCursor.ts +0 -212
- package/src/chat/messageMarkdown.ts +0 -220
- package/src/chat/messageRows.ts +0 -43
- package/src/chat/planImplementation.ts +0 -62
- package/src/chat/slashCommandHandlers.ts +0 -122
- package/src/chat/slashCommandViews.ts +0 -120
- package/src/chat/transcript/TranscriptView.tsx +0 -184
- package/src/chat/transcript/transcriptViewport.ts +0 -295
- package/src/chat/views/ContextLimitView.tsx +0 -95
- package/src/chat/views/ContinuityEditReviewView.tsx +0 -50
- package/src/chat/views/CopyPicker.tsx +0 -50
- package/src/chat/views/PermissionPrompt.tsx +0 -156
- package/src/chat/views/PermissionsView.tsx +0 -165
- package/src/chat/views/PlanApprovalView.tsx +0 -91
- package/src/chat/views/ResumeView.tsx +0 -273
- package/src/chat/views/RewindView.tsx +0 -412
- package/src/cli/preview.tsx +0 -14
- package/src/cli/updateNotice.ts +0 -54
- package/src/identity/continuity/privateEdit/apply.ts +0 -170
- package/src/identity/continuity/privateEdit/diff.ts +0 -6
- package/src/identity/continuity/privateEdit/files.ts +0 -23
- package/src/identity/continuity/privateEdit/types.ts +0 -28
- package/src/identity/continuity/privateEdit.ts +0 -46
- package/src/identity/hub/IdentityHub.tsx +0 -14
- package/src/identity/hub/continuity/RecoveryConfirmScreen.tsx +0 -104
- package/src/identity/hub/ens/effects.ts +0 -218
- package/src/identity/hub/shared/components/MenuScreen.tsx +0 -241
- package/src/identity/hub/shared/effects/types.ts +0 -53
- package/src/identity/hub/shared/reconciliation/index.ts +0 -14
- package/src/identity/wallet/page/grainient.ts +0 -278
- package/src/identity/wallet/page/html.ts +0 -28
- package/src/identity/wallet/page/styles/base.ts +0 -260
- package/src/identity/wallet/page/styles/components.ts +0 -262
- package/src/identity/wallet/page/styles/index.ts +0 -5
- package/src/identity/wallet/page/styles/responsive.ts +0 -247
- package/src/identity/wallet/page.tsx +0 -38
- package/src/mcp/approvals.ts +0 -113
- package/src/mcp/config.ts +0 -235
- package/src/mcp/manager.ts +0 -482
- package/src/mcp/managerHelpers.ts +0 -70
- package/src/mcp/names.ts +0 -19
- package/src/mcp/output.ts +0 -96
- package/src/models/ModelPicker.tsx +0 -1009
- package/src/models/catalog.ts +0 -327
- package/src/models/huggingface.ts +0 -712
- package/src/models/huggingfaceStorage.ts +0 -136
- package/src/models/llamacpp.ts +0 -848
- package/src/models/llamacppCommands.ts +0 -44
- package/src/models/llamacppConfig.ts +0 -34
- package/src/models/llamacppDiscovery.ts +0 -176
- package/src/models/llamacppOutput.ts +0 -65
- package/src/models/llamacppPreflight.ts +0 -158
- package/src/models/modelDisplay.ts +0 -180
- package/src/models/modelPickerCatalogFlow.ts +0 -56
- package/src/models/modelPickerCredentials.ts +0 -166
- package/src/models/modelPickerData.ts +0 -41
- package/src/models/modelPickerDisplay.tsx +0 -132
- package/src/models/modelPickerHfFlow.ts +0 -192
- package/src/models/modelPickerLocalRunnerFlow.ts +0 -115
- package/src/models/modelPickerOptions.ts +0 -457
- package/src/models/modelPickerTypes.ts +0 -69
- package/src/models/modelPickerUninstallFlow.ts +0 -48
- package/src/models/modelPickerViewHelpers.ts +0 -174
- package/src/models/modelRecommendation.ts +0 -139
- package/src/models/providerDisplay.ts +0 -16
- package/src/models/runtimeDetection.ts +0 -81
- package/src/models/uncensoredCatalog.ts +0 -86
- package/src/providers/anthropic.ts +0 -290
- package/src/providers/contracts.ts +0 -71
- package/src/providers/errors.ts +0 -80
- package/src/providers/gemini.ts +0 -391
- package/src/providers/openai-chat.ts +0 -474
- package/src/providers/openai-responses-format.ts +0 -177
- package/src/providers/openai-responses.ts +0 -306
- package/src/providers/openaiChatWire.ts +0 -124
- package/src/providers/registry.ts +0 -120
- package/src/providers/retry.ts +0 -58
- package/src/providers/sse.ts +0 -93
- package/src/runtime/compaction.ts +0 -395
- package/src/runtime/cwd.ts +0 -43
- package/src/runtime/providerTurn.ts +0 -38
- package/src/runtime/sessionMode.ts +0 -55
- package/src/runtime/systemPrompt.ts +0 -213
- package/src/runtime/textToolParser.ts +0 -161
- package/src/runtime/toolClaimGuards.ts +0 -143
- package/src/runtime/toolExecution.ts +0 -304
- package/src/runtime/toolIntent.ts +0 -143
- package/src/runtime/turn.ts +0 -369
- package/src/runtime/turnNudges.ts +0 -223
- package/src/runtime/turnTypes.ts +0 -86
- package/src/storage/factoryReset.ts +0 -127
- package/src/storage/history.ts +0 -58
- package/src/storage/permissions.ts +0 -76
- package/src/storage/rewind.ts +0 -266
- package/src/storage/sessionExport.ts +0 -49
- package/src/storage/sessions.ts +0 -495
- package/src/tools/bashSafety.ts +0 -186
- package/src/tools/bashTool.ts +0 -140
- package/src/tools/changeDirectoryTool.ts +0 -213
- package/src/tools/contracts.ts +0 -192
- package/src/tools/deleteFileTool.ts +0 -116
- package/src/tools/editTool.ts +0 -165
- package/src/tools/editUtils.ts +0 -170
- package/src/tools/fileDiff.ts +0 -261
- package/src/tools/listDirectoryTool.ts +0 -55
- package/src/tools/listSkillFilesTool.ts +0 -77
- package/src/tools/listSkillsTool.ts +0 -68
- package/src/tools/mcpResourceTools.ts +0 -95
- package/src/tools/permissionRules.ts +0 -85
- package/src/tools/privateContinuityEditTool.ts +0 -187
- package/src/tools/privateContinuityReadTool.ts +0 -106
- package/src/tools/readSkillTool.ts +0 -107
- package/src/tools/readTool.ts +0 -85
- package/src/tools/registry.ts +0 -103
- package/src/tools/writeFileTool.ts +0 -167
- package/src/ui/BrandSplash.tsx +0 -133
- package/src/ui/terminalTitle.ts +0 -30
- package/src/utils/images.ts +0 -140
- package/src/utils/markdownSegments.ts +0 -51
- package/src/utils/messages.ts +0 -37
- package/src/utils/withRetry.ts +0 -324
- /package/src/identity/{hub → manager}/continuity/state.ts +0 -0
- /package/src/identity/{hub → manager}/custody/helpers.ts +0 -0
- /package/src/identity/{hub → manager}/custody/preflight.ts +0 -0
- /package/src/identity/{hub → manager}/custody/state.ts +0 -0
- /package/src/identity/{hub → manager}/custody/useCustodyFlow.tsx +0 -0
- /package/src/identity/{hub → manager}/ens/EnsEditFlow.tsx +0 -0
- /package/src/identity/{hub → manager}/ens/advancedEnsValidation.ts +0 -0
- /package/src/identity/{hub → manager}/ens/state.ts +0 -0
- /package/src/identity/{hub → manager}/ens/transactions.ts +0 -0
- /package/src/identity/{hub → manager}/ens/types.ts +0 -0
- /package/src/identity/{hub → manager}/profile/identity.ts +0 -0
- /package/src/identity/{hub → manager}/restore/envelopes.ts +0 -0
- /package/src/identity/{hub → manager}/restore/helpers.ts +0 -0
- /package/src/identity/{hub → manager}/restore/recovery.ts +0 -0
- /package/src/identity/{hub → manager}/restore/resolve.ts +0 -0
- /package/src/identity/{hub → manager}/shared/components/BusyScreen.tsx +0 -0
- /package/src/identity/{hub → manager}/shared/components/NetworkScreen.tsx +0 -0
- /package/src/identity/{hub → manager}/shared/components/PinataJwtInput.tsx +0 -0
- /package/src/identity/{hub → manager}/shared/effects/receipts.ts +0 -0
- /package/src/identity/{hub → manager}/shared/effects/sync.ts +0 -0
- /package/src/identity/{hub → manager}/shared/model/format.ts +0 -0
- /package/src/identity/{hub → manager}/shared/operatorWallets.ts +0 -0
- /package/src/identity/{hub → manager}/shared/reconciliation/agentReconciliation/ownership.ts +0 -0
- /package/src/identity/{hub → manager}/shared/reconciliation/agentReconciliation/types.ts +0 -0
- /package/src/identity/{hub → manager}/shared/reconciliation/walletSetup.ts +0 -0
- /package/src/identity/{hub → manager}/shared/txGuard.ts +0 -0
- /package/src/identity/{hub → manager}/transfer/progress.ts +0 -0
- /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
package/README.md
CHANGED
|
@@ -1,144 +1,109 @@
|
|
|
1
|
-
<
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="preview/image.svg" alt="ethagent" width="100%">
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
11
|
+
Own your agent. Carry it anywhere.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
## 🚀 Quick start
|
|
14
|
+
|
|
15
|
+
**1. Create your agent.** In a terminal, run:
|
|
14
16
|
|
|
15
17
|
```bash
|
|
16
|
-
|
|
17
|
-
ethagent
|
|
18
|
+
npx ethagent
|
|
18
19
|
```
|
|
19
20
|
|
|
20
|
-
|
|
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
|
-
|
|
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
|
-
|
|
25
|
+
**2. Add it to Claude Code.** Paste these in one at a time:
|
|
42
26
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
-
|
|
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
|
-
|
|
33
|
+
```
|
|
34
|
+
/plugin install ethagent@ethagent
|
|
35
|
+
```
|
|
58
36
|
|
|
59
|
-
|
|
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
|
-
|
|
39
|
+
That's the whole setup. You'll only open `ethagent` again to hand-edit your agent or save a backup.
|
|
62
40
|
|
|
63
|
-
|
|
41
|
+
## 📦 Soul, memory, skills
|
|
64
42
|
|
|
65
|
-
|
|
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
|
-
|
|
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
|
-
|
|
49
|
+
## 💡 How it works
|
|
70
50
|
|
|
71
|
-
|
|
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
|
-
|
|
56
|
+
## ✨ Using your agent
|
|
74
57
|
|
|
75
|
-
|
|
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
|
-
|
|
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
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
-
|
|
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
|
-
|
|
68
|
+
## 🔒 What stays private
|
|
87
69
|
|
|
88
|
-
|
|
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
|
-
|
|
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
|
-
|
|
76
|
+
In short: the network stores a locked box, and only your wallet holds the key.
|
|
95
77
|
|
|
96
|
-
##
|
|
78
|
+
## 🔑 Custody
|
|
97
79
|
|
|
98
|
-
|
|
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
|
-
|
|
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
|
-
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
125
|
-
git clone https://github.com/baairon/ethagent.git
|
|
126
|
-
cd ethagent && npm install
|
|
127
|
-
npm start
|
|
128
|
-
```
|
|
98
|
+
## ⌨️ Commands
|
|
129
99
|
|
|
130
|
-
|
|
100
|
+
Run with `npx ethagent`:
|
|
131
101
|
|
|
132
102
|
| Command | What it does |
|
|
133
103
|
| --- | --- |
|
|
134
|
-
| `
|
|
135
|
-
| `
|
|
136
|
-
| `
|
|
137
|
-
| `
|
|
138
|
-
| `
|
|
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": "
|
|
4
|
-
"description": "
|
|
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
|
-
"
|
|
34
|
-
"cli",
|
|
35
|
-
"privacy",
|
|
36
|
+
"claude-code",
|
|
36
37
|
"ipfs",
|
|
37
38
|
"wallet",
|
|
38
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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 ?? '
|
|
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'
|
|
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
|
|
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:
|
|
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
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
-
</
|
|
65
|
+
</Box>
|
|
54
66
|
)
|
|
55
67
|
}
|
|
56
68
|
|
|
57
|
-
const Section: React.FC<{
|
|
69
|
+
const Section: React.FC<{ title: string; color: string; lines: string[] }> = ({ title, color, lines }) => (
|
|
58
70
|
<Box flexDirection="column" marginBottom={1}>
|
|
59
|
-
<Text color={
|
|
60
|
-
{lines.map(line => (
|
|
61
|
-
<Text key={
|
|
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
|
-
}
|