ethagent 2.2.0 → 2.4.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/README.md +11 -0
- package/package.json +2 -1
- package/src/app/FirstRun.tsx +3 -7
- package/src/app/FirstRunTimeline.tsx +1 -1
- package/src/chat/ChatBottomPane.tsx +29 -11
- package/src/chat/ChatScreen.tsx +169 -38
- package/src/chat/ConversationStack.tsx +1 -1
- package/src/chat/MessageList.tsx +185 -72
- package/src/chat/SessionStatus.tsx +3 -1
- package/src/chat/chatScreenUtils.ts +11 -15
- package/src/chat/chatSessionState.ts +5 -2
- package/src/chat/chatTurnOrchestrator.ts +7 -9
- package/src/chat/commands.ts +26 -26
- package/src/chat/display/DiffView.tsx +193 -0
- package/src/chat/display/SyntaxText.tsx +192 -0
- package/src/chat/display/toolCallDisplay.ts +103 -0
- package/src/chat/display/toolResultDisplay.ts +19 -0
- package/src/chat/{ChatInput.tsx → input/ChatInput.tsx} +61 -25
- package/src/chat/input/imageRefs.ts +30 -0
- package/src/chat/{TranscriptView.tsx → transcript/TranscriptView.tsx} +24 -50
- package/src/chat/{transcriptViewport.ts → transcript/transcriptViewport.ts} +12 -30
- package/src/chat/{ContextLimitView.tsx → views/ContextLimitView.tsx} +3 -3
- package/src/chat/{ContinuityEditReviewView.tsx → views/ContinuityEditReviewView.tsx} +11 -3
- package/src/chat/{CopyPicker.tsx → views/CopyPicker.tsx} +4 -5
- package/src/chat/{PermissionPrompt.tsx → views/PermissionPrompt.tsx} +16 -17
- package/src/chat/{PermissionsView.tsx → views/PermissionsView.tsx} +6 -6
- package/src/chat/{PlanApprovalView.tsx → views/PlanApprovalView.tsx} +4 -4
- package/src/chat/{ResumeView.tsx → views/ResumeView.tsx} +50 -41
- package/src/chat/views/RewindView.tsx +410 -0
- package/src/identity/continuity/privateEdit/diff.ts +2 -78
- package/src/identity/hub/OperationalRoutes.tsx +21 -21
- package/src/identity/hub/Routes.tsx +13 -13
- package/src/identity/hub/{flows/continuity → continuity}/ContinuityDashboardScreen.tsx +9 -9
- package/src/identity/hub/{flows/continuity → continuity}/RebackupStorageScreen.tsx +2 -2
- package/src/identity/hub/{flows/continuity → continuity}/RecoveryConfirmScreen.tsx +5 -5
- package/src/identity/hub/{flows/continuity → continuity}/SavePromptScreen.tsx +5 -5
- package/src/identity/hub/{effects/rebackup/runRebackup.ts → continuity/effects.ts} +17 -17
- package/src/identity/hub/{effects/rebackup → continuity}/index.ts +1 -1
- package/src/identity/hub/{effects/shared → continuity}/snapshot.ts +8 -8
- package/src/identity/hub/{effects/rebackup → continuity}/vault.ts +15 -15
- package/src/identity/hub/{flows/create → create}/CreateFlow.tsx +13 -13
- package/src/identity/hub/{effects/create.ts → create/effects.ts} +4 -4
- package/src/identity/hub/{flows/custody → custody}/CustodyEditFlow.tsx +9 -9
- package/src/identity/hub/{flows/custody/custodyFlowActions.ts → custody/actions.ts} +6 -6
- package/src/identity/hub/{flows/custody/custodyFlowHelpers.ts → custody/helpers.ts} +4 -4
- package/src/identity/hub/{effects/vault → custody}/preflight.ts +5 -5
- package/src/identity/hub/{flows/custody/custodyFlowRoutes.tsx → custody/routes.tsx} +8 -8
- package/src/identity/hub/{flows/custody/custodyEffects.ts → custody/transactions.ts} +9 -9
- package/src/identity/hub/{flows/custody/custodyFlowTypes.ts → custody/types.ts} +5 -5
- package/src/identity/hub/{flows/custody/custodyFlowEffects.ts → custody/useCustodyEffects.ts} +7 -7
- package/src/identity/hub/{flows/custody → custody}/useCustodyFlow.tsx +5 -5
- package/src/identity/hub/{flows/ens → ens}/EnsEditAdvancedScreens.tsx +13 -13
- package/src/identity/hub/{flows/ens → ens}/EnsEditFlow.tsx +7 -7
- package/src/identity/hub/{flows/ens → ens}/EnsEditMaintenanceScreens.tsx +10 -10
- package/src/identity/hub/{flows/ens → ens}/EnsEditReviewScreens.tsx +12 -12
- package/src/identity/hub/{flows/ens → ens}/EnsEditRunners.tsx +5 -5
- package/src/identity/hub/{flows/ens → ens}/EnsEditShared.tsx +10 -10
- package/src/identity/hub/{flows/ens → ens}/EnsEditSimpleScreens.tsx +14 -14
- package/src/identity/hub/{flows/ens/IdentityHubEnsFlow.tsx → ens/EnsFlow.tsx} +12 -12
- package/src/identity/hub/{flows/ens/OperatorWalletsScreen.tsx → ens/EnsOperatorWalletsScreen.tsx} +17 -17
- package/src/identity/hub/{advancedEnsValidation.ts → ens/advancedEnsValidation.ts} +2 -2
- package/src/identity/hub/{flows/ens/ensEditCopy.ts → ens/editCopy.ts} +3 -3
- package/src/identity/hub/{effects/ens/flows.ts → ens/effects.ts} +7 -7
- package/src/identity/hub/{effects/ens → ens}/index.ts +1 -1
- package/src/identity/hub/{model/ens.ts → ens/state.ts} +1 -1
- package/src/identity/hub/{effects/ens → ens}/transactions.ts +239 -239
- package/src/identity/hub/{flows/ens/ensEditTypes.ts → ens/types.ts} +7 -7
- package/src/identity/hub/identityHubReducer.ts +3 -3
- package/src/identity/hub/{flows/profile → profile}/EditProfileFlow.tsx +11 -11
- package/src/identity/hub/{effects/publicProfile/runPublicProfileSave.ts → profile/effects.ts} +18 -18
- package/src/identity/hub/{model → profile}/identity.ts +3 -3
- package/src/identity/hub/{effects/profile/profileState.ts → profile/state.ts} +181 -181
- package/src/identity/hub/{flows/restore → restore}/RestoreFlow.tsx +16 -16
- package/src/identity/hub/{effects/restore → restore}/apply.ts +10 -10
- package/src/identity/hub/{effects/restore → restore}/auth.ts +7 -7
- package/src/identity/hub/{effects/restore → restore}/discover.ts +6 -6
- package/src/identity/hub/{effects/restore → restore}/envelopes.ts +2 -2
- package/src/identity/hub/{effects/restore → restore}/fetch.ts +3 -3
- package/src/identity/hub/{effects/restore/shared.ts → restore/helpers.ts} +6 -6
- package/src/identity/hub/{effects/restore → restore}/recovery.ts +10 -10
- package/src/identity/hub/{effects/restore → restore}/resolve.ts +4 -4
- package/src/identity/hub/{effects → restore}/restoreAdmin.ts +1 -1
- package/src/identity/hub/{flows/restore/useRestoreFlowEffects.ts → restore/useRestoreEffects.ts} +5 -5
- package/src/identity/hub/{flows/settings → settings}/StorageCredentialScreen.tsx +5 -5
- package/src/identity/hub/{components → shared/components}/BusyScreen.tsx +4 -4
- package/src/identity/hub/{components → shared/components}/DetailsScreen.tsx +4 -4
- package/src/identity/hub/{components → shared/components}/ErrorScreen.tsx +4 -4
- package/src/identity/hub/{components → shared/components}/FlowTimeline.tsx +1 -1
- package/src/identity/hub/{components → shared/components}/IdentitySummary.tsx +8 -8
- package/src/identity/hub/{components → shared/components}/MenuScreen.tsx +7 -7
- package/src/identity/hub/{components → shared/components}/NetworkScreen.tsx +4 -4
- package/src/identity/hub/{components → shared/components}/PinataJwtInput.tsx +4 -4
- package/src/identity/hub/{components → shared/components}/UnlinkedIdentityScreen.tsx +5 -5
- package/src/identity/hub/{components → shared/components}/WalletApprovalScreen.tsx +6 -6
- package/src/identity/hub/{components → shared/components}/menuFlagsFromReconciliation.ts +1 -1
- package/src/identity/hub/{effects/shared → shared/effects}/profilePrep.ts +1 -1
- package/src/identity/hub/{effects → shared/effects}/receipts.ts +2 -2
- package/src/identity/hub/{effects/shared → shared/effects}/sync.ts +4 -4
- package/src/identity/hub/{effects → shared/effects}/types.ts +3 -3
- package/src/identity/hub/{model → shared/model}/copy.ts +2 -2
- package/src/identity/hub/{model → shared/model}/errors.ts +5 -5
- package/src/identity/hub/{model → shared/model}/network.ts +3 -3
- package/src/identity/hub/{operatorWallets.ts → shared/operatorWallets.ts} +1 -1
- package/src/identity/hub/{reconciliation → shared/reconciliation}/agentReconciliation/hook.ts +1 -1
- package/src/identity/hub/{reconciliation → shared/reconciliation}/agentReconciliation/ownership.ts +2 -2
- package/src/identity/hub/{reconciliation → shared/reconciliation}/agentReconciliation/run.ts +6 -6
- package/src/identity/hub/{utils.ts → shared/utils.ts} +5 -5
- package/src/identity/hub/{flows/token-transfer/IdentityHubTokenTransferFlow.tsx → transfer/TokenTransferFlow.tsx} +8 -8
- package/src/identity/hub/{flows/token-transfer → transfer}/TokenTransferScreens.tsx +14 -14
- package/src/identity/hub/{effects/token-transfer/runTokenTransfer.ts → transfer/effects.ts} +16 -16
- package/src/identity/hub/{effects/token-transfer → transfer}/progress.ts +1 -1
- package/src/identity/hub/useIdentityHubController.ts +11 -11
- package/src/identity/hub/useIdentityHubSideEffects.ts +11 -11
- package/src/models/ModelPicker.tsx +143 -9
- package/src/models/catalog.ts +2 -1
- package/src/models/huggingface.ts +180 -2
- package/src/models/llamacpp.ts +110 -15
- package/src/models/llamacppPreflight.ts +30 -11
- package/src/models/modelPickerOptions.ts +16 -15
- package/src/models/providerDisplay.ts +16 -0
- package/src/providers/anthropic.ts +36 -5
- package/src/providers/contracts.ts +9 -1
- package/src/providers/errors.ts +6 -4
- package/src/providers/gemini.ts +29 -3
- package/src/providers/openai-chat.ts +83 -3
- package/src/providers/openai-responses-format.ts +29 -8
- package/src/providers/openai-responses.ts +22 -7
- package/src/providers/registry.ts +1 -0
- package/src/runtime/sessionMode.ts +1 -1
- package/src/runtime/systemPrompt.ts +3 -1
- package/src/runtime/toolExecution.ts +9 -6
- package/src/runtime/turn.ts +29 -0
- package/src/storage/config.ts +1 -0
- package/src/storage/rewind.ts +20 -0
- package/src/storage/sessions.ts +16 -3
- package/src/tools/bashSafety.ts +7 -3
- package/src/tools/bashTool.ts +1 -1
- package/src/tools/contracts.ts +3 -0
- package/src/tools/deleteFileTool.ts +8 -3
- package/src/tools/editTool.ts +10 -5
- package/src/tools/fileDiff.ts +261 -0
- package/src/tools/privateContinuityEditTool.ts +5 -1
- package/src/tools/writeFileTool.ts +8 -3
- package/src/ui/Spinner.tsx +39 -5
- package/src/ui/TextInput.tsx +2 -2
- package/src/ui/theme.ts +19 -0
- package/src/utils/clipboard.ts +10 -7
- package/src/utils/images.ts +140 -0
- package/src/utils/messages.ts +2 -0
- package/src/chat/RewindView.tsx +0 -386
- package/src/chat/toolResultDisplay.ts +0 -8
- package/src/identity/hub/effects/index.ts +0 -73
- package/src/identity/hub/effects/publicProfile/index.ts +0 -5
- package/src/identity/hub/effects/restore/restoreEffects.ts +0 -22
- package/src/identity/hub/effects/token-transfer/index.ts +0 -6
- /package/src/chat/{chatInputState.ts → input/chatInputState.ts} +0 -0
- /package/src/chat/{chatPaste.ts → input/chatPaste.ts} +0 -0
- /package/src/chat/{textCursor.ts → input/textCursor.ts} +0 -0
- /package/src/identity/hub/{model/continuity.ts → continuity/state.ts} +0 -0
- /package/src/identity/hub/{model/custody.ts → custody/state.ts} +0 -0
- /package/src/identity/hub/{effects/restore → restore}/index.ts +0 -0
- /package/src/identity/hub/{model → shared/model}/format.ts +0 -0
- /package/src/identity/hub/{reconciliation → shared/reconciliation}/agentReconciliation/types.ts +0 -0
- /package/src/identity/hub/{reconciliation → shared/reconciliation}/index.ts +0 -0
- /package/src/identity/hub/{reconciliation → shared/reconciliation}/useAgentReconciliation.ts +0 -0
- /package/src/identity/hub/{reconciliation → shared/reconciliation}/walletSetup.ts +0 -0
- /package/src/identity/hub/{txGuard.ts → shared/txGuard.ts} +0 -0
- /package/src/identity/hub/{model/transfer.ts → transfer/state.ts} +0 -0
package/src/chat/RewindView.tsx
DELETED
|
@@ -1,386 +0,0 @@
|
|
|
1
|
-
import React, { useEffect, useState } from 'react'
|
|
2
|
-
import { Box, Text } from 'ink'
|
|
3
|
-
import { Surface } from '../ui/Surface.js'
|
|
4
|
-
import { Select, type SelectOption } from '../ui/Select.js'
|
|
5
|
-
import { Spinner } from '../ui/Spinner.js'
|
|
6
|
-
import { theme } from '../ui/theme.js'
|
|
7
|
-
import { useAppInput } from '../app/input/AppInputProvider.js'
|
|
8
|
-
import {
|
|
9
|
-
listRewindEntries,
|
|
10
|
-
rewindWorkspaceEditsByEntryIds,
|
|
11
|
-
type RewindEntry,
|
|
12
|
-
} from '../storage/rewind.js'
|
|
13
|
-
|
|
14
|
-
type RestoreAction = 'both' | 'code' | 'conversation'
|
|
15
|
-
|
|
16
|
-
type RewindViewProps = {
|
|
17
|
-
cwd: string
|
|
18
|
-
currentSessionId: string
|
|
19
|
-
onRestoreConversation: (turnId: string) => void
|
|
20
|
-
onDone: (message: string, variant?: 'info' | 'error' | 'dim') => void
|
|
21
|
-
onCancel: () => void
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
type ReadyState = {
|
|
25
|
-
kind: 'ready'
|
|
26
|
-
entries: RewindEntry[]
|
|
27
|
-
offset: number
|
|
28
|
-
pageSize: number
|
|
29
|
-
hasMore: boolean
|
|
30
|
-
selectedFilePath: string | null
|
|
31
|
-
selectedId: string | null
|
|
32
|
-
selectedAction: RestoreAction
|
|
33
|
-
stage: 'files' | 'entries' | 'actions'
|
|
34
|
-
restoring: boolean
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
type State =
|
|
38
|
-
| { kind: 'loading' }
|
|
39
|
-
| { kind: 'error'; message: string }
|
|
40
|
-
| ReadyState
|
|
41
|
-
|
|
42
|
-
export const RewindView: React.FC<RewindViewProps> = ({
|
|
43
|
-
cwd,
|
|
44
|
-
currentSessionId,
|
|
45
|
-
onRestoreConversation,
|
|
46
|
-
onDone,
|
|
47
|
-
onCancel,
|
|
48
|
-
}) => {
|
|
49
|
-
const [state, setState] = useState<State>({ kind: 'loading' })
|
|
50
|
-
const pageSize = 12
|
|
51
|
-
|
|
52
|
-
const escActive = state.kind === 'loading' || state.kind === 'error' || (state.kind === 'ready' && state.entries.length === 0)
|
|
53
|
-
useAppInput((_input, key) => {
|
|
54
|
-
if (key.escape) onCancel()
|
|
55
|
-
}, { isActive: escActive })
|
|
56
|
-
|
|
57
|
-
useEffect(() => {
|
|
58
|
-
let cancelled = false
|
|
59
|
-
void (async () => {
|
|
60
|
-
try {
|
|
61
|
-
const entries = await listRewindEntries(cwd, { limit: pageSize, offset: 0 })
|
|
62
|
-
if (cancelled) return
|
|
63
|
-
const firstFilePath = entries[0]?.filePath ?? null
|
|
64
|
-
const firstEntryId = entries.find(entry => entry.filePath === firstFilePath)?.id ?? null
|
|
65
|
-
setState({
|
|
66
|
-
kind: 'ready',
|
|
67
|
-
entries,
|
|
68
|
-
offset: entries.length,
|
|
69
|
-
pageSize,
|
|
70
|
-
hasMore: entries.length === pageSize,
|
|
71
|
-
selectedFilePath: firstFilePath,
|
|
72
|
-
selectedId: firstEntryId,
|
|
73
|
-
selectedAction: 'code',
|
|
74
|
-
stage: 'files',
|
|
75
|
-
restoring: false,
|
|
76
|
-
})
|
|
77
|
-
} catch (err: unknown) {
|
|
78
|
-
if (cancelled) return
|
|
79
|
-
setState({ kind: 'error', message: (err as Error).message })
|
|
80
|
-
}
|
|
81
|
-
})()
|
|
82
|
-
return () => { cancelled = true }
|
|
83
|
-
}, [cwd, pageSize])
|
|
84
|
-
|
|
85
|
-
if (state.kind === 'loading') {
|
|
86
|
-
return (
|
|
87
|
-
<Surface title="Rewind" subtitle="loading checkpoints...">
|
|
88
|
-
<Spinner label="loading rewind history..." />
|
|
89
|
-
</Surface>
|
|
90
|
-
)
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (state.kind === 'error') {
|
|
94
|
-
return (
|
|
95
|
-
<Surface title="Rewind" tone="muted" footer="esc closes">
|
|
96
|
-
<Text color={theme.dim}>{state.message}</Text>
|
|
97
|
-
</Surface>
|
|
98
|
-
)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (state.entries.length === 0) {
|
|
102
|
-
return (
|
|
103
|
-
<Surface title="Rewind" tone="muted" footer="esc closes">
|
|
104
|
-
<Text color={theme.dim}>No managed edits are available to rewind in this workspace.</Text>
|
|
105
|
-
</Surface>
|
|
106
|
-
)
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
const fileEntries = dedupeFiles(state.entries)
|
|
110
|
-
const scopedEntries = state.selectedFilePath
|
|
111
|
-
? state.entries.filter(entry => entry.filePath === state.selectedFilePath)
|
|
112
|
-
: []
|
|
113
|
-
const selectedFile = fileEntries.find(entry => entry.filePath === state.selectedFilePath) ?? fileEntries[0]!
|
|
114
|
-
const selectedEntry = scopedEntries.find(entry => entry.id === state.selectedId) ?? scopedEntries[0] ?? selectedFile
|
|
115
|
-
const canRestoreConversation = Boolean(selectedEntry.turnId && selectedEntry.sessionId === currentSessionId)
|
|
116
|
-
|
|
117
|
-
const executeRestore = async (action: RestoreAction) => {
|
|
118
|
-
setState(prev => prev.kind === 'ready' ? { ...prev, restoring: true, selectedAction: action } : prev)
|
|
119
|
-
try {
|
|
120
|
-
if (action === 'conversation') {
|
|
121
|
-
if (!selectedEntry.turnId || !canRestoreConversation) {
|
|
122
|
-
onDone('conversation restore is not available for this checkpoint.', 'error')
|
|
123
|
-
return
|
|
124
|
-
}
|
|
125
|
-
onRestoreConversation(selectedEntry.turnId)
|
|
126
|
-
onDone(`restored conversation to before: ${selectedEntry.checkpointLabel}`, 'dim')
|
|
127
|
-
return
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const result = await rewindWorkspaceEditsByEntryIds(cwd, [selectedEntry.id])
|
|
131
|
-
if (result.reverted === 0) {
|
|
132
|
-
onDone('no matching rewind entry was found.', 'error')
|
|
133
|
-
return
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
if (action === 'both') {
|
|
137
|
-
if (!selectedEntry.turnId || !canRestoreConversation) {
|
|
138
|
-
onDone('conversation restore is not available for this checkpoint.', 'error')
|
|
139
|
-
return
|
|
140
|
-
}
|
|
141
|
-
onRestoreConversation(selectedEntry.turnId)
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const fileList = result.files.map(file => file.split(/[\\/]/).at(-1) ?? file).join(', ')
|
|
145
|
-
const prefix = action === 'both' ? 'restored code and conversation' : 'restored code'
|
|
146
|
-
onDone(`${prefix}: ${fileList}`, 'dim')
|
|
147
|
-
} catch (err: unknown) {
|
|
148
|
-
onDone(`rewind failed: ${(err as Error).message}`, 'error')
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
const loadMoreEntries = async () => {
|
|
153
|
-
if (state.kind !== 'ready' || !state.hasMore || state.restoring) return
|
|
154
|
-
try {
|
|
155
|
-
const nextEntries = await listRewindEntries(cwd, { limit: state.pageSize, offset: state.offset })
|
|
156
|
-
setState(prev => {
|
|
157
|
-
if (prev.kind !== 'ready') return prev
|
|
158
|
-
const merged = dedupeEntryIds([...prev.entries, ...nextEntries])
|
|
159
|
-
const selectedFilePath = prev.selectedFilePath ?? merged[0]?.filePath ?? null
|
|
160
|
-
const selectedId =
|
|
161
|
-
prev.selectedId && merged.some(entry => entry.id === prev.selectedId)
|
|
162
|
-
? prev.selectedId
|
|
163
|
-
: merged.find(entry => entry.filePath === selectedFilePath)?.id ?? merged[0]?.id ?? null
|
|
164
|
-
return {
|
|
165
|
-
...prev,
|
|
166
|
-
entries: merged,
|
|
167
|
-
offset: prev.offset + nextEntries.length,
|
|
168
|
-
hasMore: nextEntries.length === prev.pageSize,
|
|
169
|
-
selectedFilePath,
|
|
170
|
-
selectedId,
|
|
171
|
-
}
|
|
172
|
-
})
|
|
173
|
-
} catch (err: unknown) {
|
|
174
|
-
onDone(`failed to load older checkpoints: ${(err as Error).message}`, 'error')
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
const handleCancel = () => {
|
|
179
|
-
if (state.stage === 'actions') {
|
|
180
|
-
setState(prev => prev.kind === 'ready' ? { ...prev, stage: 'entries' } : prev)
|
|
181
|
-
return
|
|
182
|
-
}
|
|
183
|
-
if (state.stage === 'entries') {
|
|
184
|
-
setState(prev => prev.kind === 'ready' ? { ...prev, stage: 'files' } : prev)
|
|
185
|
-
return
|
|
186
|
-
}
|
|
187
|
-
onCancel()
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
return (
|
|
191
|
-
<Surface
|
|
192
|
-
title="Rewind"
|
|
193
|
-
subtitle={buildSubtitle(state.stage, selectedEntry.relativePath)}
|
|
194
|
-
footer={buildFooter(state.stage, state.restoring)}
|
|
195
|
-
>
|
|
196
|
-
{state.stage === 'files' ? (
|
|
197
|
-
<>
|
|
198
|
-
<Select
|
|
199
|
-
options={buildFileOptions(fileEntries, state.hasMore)}
|
|
200
|
-
onSubmit={filePath => {
|
|
201
|
-
if (filePath === LOAD_MORE_VALUE) {
|
|
202
|
-
void loadMoreEntries()
|
|
203
|
-
return
|
|
204
|
-
}
|
|
205
|
-
const firstEntry = state.entries.find(entry => entry.filePath === filePath) ?? null
|
|
206
|
-
setState(prev => prev.kind === 'ready'
|
|
207
|
-
? {
|
|
208
|
-
...prev,
|
|
209
|
-
selectedFilePath: filePath,
|
|
210
|
-
selectedId: firstEntry?.id ?? null,
|
|
211
|
-
stage: 'entries',
|
|
212
|
-
}
|
|
213
|
-
: prev)
|
|
214
|
-
}}
|
|
215
|
-
onCancel={handleCancel}
|
|
216
|
-
onHighlight={value => {
|
|
217
|
-
if (value === LOAD_MORE_VALUE) return
|
|
218
|
-
setState(prev => prev.kind === 'ready'
|
|
219
|
-
? {
|
|
220
|
-
...prev,
|
|
221
|
-
selectedFilePath: value,
|
|
222
|
-
selectedId: prev.entries.find(entry => entry.filePath === value)?.id ?? null,
|
|
223
|
-
}
|
|
224
|
-
: prev)
|
|
225
|
-
}}
|
|
226
|
-
/>
|
|
227
|
-
<CompactPreview entry={selectedFile} />
|
|
228
|
-
</>
|
|
229
|
-
) : state.stage === 'entries' ? (
|
|
230
|
-
<>
|
|
231
|
-
<Select
|
|
232
|
-
options={buildEntryOptions(scopedEntries, state.hasMore)}
|
|
233
|
-
onSubmit={entryId => {
|
|
234
|
-
if (entryId === LOAD_MORE_VALUE) {
|
|
235
|
-
void loadMoreEntries()
|
|
236
|
-
return
|
|
237
|
-
}
|
|
238
|
-
setState(prev => prev.kind === 'ready'
|
|
239
|
-
? { ...prev, selectedId: entryId, stage: 'actions' }
|
|
240
|
-
: prev)
|
|
241
|
-
}}
|
|
242
|
-
onCancel={handleCancel}
|
|
243
|
-
onHighlight={value => {
|
|
244
|
-
if (value === LOAD_MORE_VALUE) return
|
|
245
|
-
setState(prev => prev.kind === 'ready'
|
|
246
|
-
? { ...prev, selectedId: value }
|
|
247
|
-
: prev)
|
|
248
|
-
}}
|
|
249
|
-
/>
|
|
250
|
-
<CompactPreview entry={selectedEntry} />
|
|
251
|
-
</>
|
|
252
|
-
) : (
|
|
253
|
-
<>
|
|
254
|
-
<Select
|
|
255
|
-
options={buildActionOptions(canRestoreConversation)}
|
|
256
|
-
onSubmit={value => { void executeRestore(value) }}
|
|
257
|
-
onCancel={handleCancel}
|
|
258
|
-
onHighlight={value => setState(prev => prev.kind === 'ready'
|
|
259
|
-
? { ...prev, selectedAction: value }
|
|
260
|
-
: prev)}
|
|
261
|
-
/>
|
|
262
|
-
<ActionPreview entry={selectedEntry} selectedAction={state.selectedAction} canRestoreConversation={canRestoreConversation} />
|
|
263
|
-
</>
|
|
264
|
-
)}
|
|
265
|
-
</Surface>
|
|
266
|
-
)
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
const LOAD_MORE_VALUE = '__load_more__'
|
|
270
|
-
|
|
271
|
-
function buildFileOptions(entries: RewindEntry[], hasMore: boolean): Array<SelectOption<string>> {
|
|
272
|
-
const options = entries.map(entry => ({
|
|
273
|
-
value: entry.filePath,
|
|
274
|
-
label: entry.relativePath,
|
|
275
|
-
hint: formatTimestamp(entry.createdAt),
|
|
276
|
-
}))
|
|
277
|
-
if (hasMore) {
|
|
278
|
-
options.push({
|
|
279
|
-
value: LOAD_MORE_VALUE,
|
|
280
|
-
label: 'show older checkpoints',
|
|
281
|
-
hint: 'load more file history from this directory',
|
|
282
|
-
})
|
|
283
|
-
}
|
|
284
|
-
return options
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
function buildEntryOptions(entries: RewindEntry[], hasMore: boolean): Array<SelectOption<string>> {
|
|
288
|
-
const options = entries.map(entry => ({
|
|
289
|
-
value: entry.id,
|
|
290
|
-
label: entry.checkpointLabel || 'checkpoint',
|
|
291
|
-
hint: `${formatTimestamp(entry.createdAt)} · ${entry.changeSummary}`,
|
|
292
|
-
}))
|
|
293
|
-
if (hasMore) {
|
|
294
|
-
options.push({
|
|
295
|
-
value: LOAD_MORE_VALUE,
|
|
296
|
-
label: 'show older checkpoints',
|
|
297
|
-
hint: 'load more checkpoints for this directory',
|
|
298
|
-
})
|
|
299
|
-
}
|
|
300
|
-
return options
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
function buildActionOptions(canRestoreConversation: boolean): Array<SelectOption<RestoreAction>> {
|
|
304
|
-
const options: Array<SelectOption<RestoreAction>> = []
|
|
305
|
-
if (canRestoreConversation) {
|
|
306
|
-
options.push({ value: 'both', label: 'restore code and conversation', hint: 'full rewind' })
|
|
307
|
-
options.push({ value: 'conversation', label: 'restore conversation only', hint: 'keep current files unchanged' })
|
|
308
|
-
}
|
|
309
|
-
options.push({ value: 'code', label: 'restore code only', hint: 'revert the selected file checkpoint only' })
|
|
310
|
-
return options
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
const CompactPreview: React.FC<{ entry: RewindEntry }> = ({ entry }) => (
|
|
314
|
-
<Box flexDirection="column" marginTop={1}>
|
|
315
|
-
<Text color={theme.accentPeriwinkle}>{entry.relativePath}</Text>
|
|
316
|
-
<Text color={theme.dim}>{entry.promptSnippet || '(prompt snippet unavailable for older checkpoints)'}</Text>
|
|
317
|
-
</Box>
|
|
318
|
-
)
|
|
319
|
-
|
|
320
|
-
const ActionPreview: React.FC<{
|
|
321
|
-
entry: RewindEntry
|
|
322
|
-
selectedAction: RestoreAction
|
|
323
|
-
canRestoreConversation: boolean
|
|
324
|
-
}> = ({ entry, selectedAction, canRestoreConversation }) => (
|
|
325
|
-
<Box flexDirection="column" marginTop={1}>
|
|
326
|
-
<Text color={theme.accentPeriwinkle}>{entry.relativePath}</Text>
|
|
327
|
-
<Text color={theme.dim}>{formatTimestamp(entry.createdAt)} · {entry.changeSummary}</Text>
|
|
328
|
-
<Text color={theme.textSubtle}>
|
|
329
|
-
{selectedAction === 'both'
|
|
330
|
-
? 'restore the selected file checkpoint and roll the current conversation back to before this prompt.'
|
|
331
|
-
: selectedAction === 'conversation'
|
|
332
|
-
? 'restore only the conversation state to before this prompt.'
|
|
333
|
-
: 'restore only the selected file checkpoint.'}
|
|
334
|
-
</Text>
|
|
335
|
-
{!canRestoreConversation ? (
|
|
336
|
-
<Text color={theme.dim}>Conversation restore is only available for checkpoints from the current session.</Text>
|
|
337
|
-
) : null}
|
|
338
|
-
<Text color={theme.textSubtle}>{previewContent(entry.previousContent)}</Text>
|
|
339
|
-
</Box>
|
|
340
|
-
)
|
|
341
|
-
|
|
342
|
-
function dedupeFiles(entries: RewindEntry[]): RewindEntry[] {
|
|
343
|
-
const seen = new Set<string>()
|
|
344
|
-
const out: RewindEntry[] = []
|
|
345
|
-
for (const entry of entries) {
|
|
346
|
-
if (seen.has(entry.filePath)) continue
|
|
347
|
-
seen.add(entry.filePath)
|
|
348
|
-
out.push(entry)
|
|
349
|
-
}
|
|
350
|
-
return out
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
function dedupeEntryIds(entries: RewindEntry[]): RewindEntry[] {
|
|
354
|
-
const seen = new Set<string>()
|
|
355
|
-
const out: RewindEntry[] = []
|
|
356
|
-
for (const entry of entries) {
|
|
357
|
-
if (seen.has(entry.id)) continue
|
|
358
|
-
seen.add(entry.id)
|
|
359
|
-
out.push(entry)
|
|
360
|
-
}
|
|
361
|
-
return out
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
function previewContent(text: string): string {
|
|
365
|
-
if (!text.trim()) return '(empty before this edit)'
|
|
366
|
-
const normalized = text.replace(/\s+$/g, '')
|
|
367
|
-
return normalized.length <= 140 ? normalized : `${normalized.slice(0, 137)}...`
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
function formatTimestamp(iso: string): string {
|
|
371
|
-
const date = new Date(iso)
|
|
372
|
-
return Number.isNaN(date.getTime()) ? iso : date.toLocaleString()
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
function buildSubtitle(stage: ReadyState['stage'], relativePath: string): string {
|
|
376
|
-
if (stage === 'files') return 'choose a file with saved checkpoints.'
|
|
377
|
-
if (stage === 'entries') return `checkpoints for ${relativePath}`
|
|
378
|
-
return `choose how to restore ${relativePath}`
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
function buildFooter(stage: ReadyState['stage'], restoring: boolean): string {
|
|
382
|
-
if (restoring) return 'restoring...'
|
|
383
|
-
if (stage === 'files') return 'enter selects a file · esc closes'
|
|
384
|
-
if (stage === 'entries') return 'enter chooses a checkpoint · esc back'
|
|
385
|
-
return 'enter restores · esc back'
|
|
386
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
export type {
|
|
2
|
-
CustodySwitchAdvancedProgress,
|
|
3
|
-
EffectCallbacks,
|
|
4
|
-
EnsClearProgress,
|
|
5
|
-
EnsLinkProgress,
|
|
6
|
-
EnsUpdateProgress,
|
|
7
|
-
IdentityCompletionSource,
|
|
8
|
-
RestoreProgress,
|
|
9
|
-
TokenTransferProgress,
|
|
10
|
-
} from './types.js'
|
|
11
|
-
export { awaitConfirmedReceipt } from './receipts.js'
|
|
12
|
-
export {
|
|
13
|
-
ensRecordWritesForUpdate,
|
|
14
|
-
runEnsLinkFlow,
|
|
15
|
-
runEnsSetupRecordsTransaction,
|
|
16
|
-
runEnsSetupRegistryTransaction,
|
|
17
|
-
runEnsUnlinkFlow,
|
|
18
|
-
runEnsUpdateFlow,
|
|
19
|
-
runUpdateEnsRecords,
|
|
20
|
-
} from './ens/index.js'
|
|
21
|
-
export {
|
|
22
|
-
applyEnsValidationState,
|
|
23
|
-
applyOperatorProfileState,
|
|
24
|
-
} from './profile/profileState.js'
|
|
25
|
-
export {
|
|
26
|
-
canRestoreCandidate,
|
|
27
|
-
resolveAgentEnsToCandidate,
|
|
28
|
-
resolveAgentTokenIdToCandidate,
|
|
29
|
-
restoreSignatureRequestForStep,
|
|
30
|
-
restoreTokenSelectionStep,
|
|
31
|
-
runRecoveryRefetch,
|
|
32
|
-
runRestoreAuthorize,
|
|
33
|
-
runRestoreConnectWallet,
|
|
34
|
-
runRestoreDiscover,
|
|
35
|
-
runRestoreFetch,
|
|
36
|
-
} from './restore/restoreEffects.js'
|
|
37
|
-
export {
|
|
38
|
-
assertTokenNotInVault,
|
|
39
|
-
VaultUnavailableError,
|
|
40
|
-
TokenInVaultError,
|
|
41
|
-
} from './vault/preflight.js'
|
|
42
|
-
export {
|
|
43
|
-
createContinuityEnvelopeForSave,
|
|
44
|
-
expectedAccountForSnapshotSave,
|
|
45
|
-
snapshotSaveRequiresOwnerSigner,
|
|
46
|
-
snapshotSaveWalletRole,
|
|
47
|
-
} from './shared/snapshot.js'
|
|
48
|
-
export {
|
|
49
|
-
runCreatePreflight,
|
|
50
|
-
runCreateSigning,
|
|
51
|
-
runRegistrySubmit,
|
|
52
|
-
runStorageSubmit,
|
|
53
|
-
} from './create.js'
|
|
54
|
-
export {
|
|
55
|
-
runRestoreRegistrySubmit,
|
|
56
|
-
} from './restoreAdmin.js'
|
|
57
|
-
export {
|
|
58
|
-
runPublicProfilePreflight,
|
|
59
|
-
runPublicProfileSigning,
|
|
60
|
-
runPublicProfileStorageSubmit,
|
|
61
|
-
} from './publicProfile/runPublicProfileSave.js'
|
|
62
|
-
export {
|
|
63
|
-
runRebackupPreflight,
|
|
64
|
-
runRebackupSigning,
|
|
65
|
-
runRebackupSigningInSession,
|
|
66
|
-
runRebackupStorageSubmit,
|
|
67
|
-
} from './rebackup/runRebackup.js'
|
|
68
|
-
export {
|
|
69
|
-
tokenTransferProgressForPhase,
|
|
70
|
-
runTokenTransferSigning,
|
|
71
|
-
runTokenTransferStorageSubmit,
|
|
72
|
-
runTokenTransferTargetSubmit,
|
|
73
|
-
} from './token-transfer/runTokenTransfer.js'
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
export {
|
|
2
|
-
canRestoreCandidate,
|
|
3
|
-
restoreTokenSelectionStep,
|
|
4
|
-
runRestoreDiscover,
|
|
5
|
-
} from './discover.js'
|
|
6
|
-
export {
|
|
7
|
-
resolveAgentEnsToCandidate,
|
|
8
|
-
resolveAgentTokenIdToCandidate,
|
|
9
|
-
} from './resolve.js'
|
|
10
|
-
export {
|
|
11
|
-
restoreSignatureRequestForStep,
|
|
12
|
-
runRestoreConnectWallet,
|
|
13
|
-
} from './auth.js'
|
|
14
|
-
export {
|
|
15
|
-
runRestoreFetch,
|
|
16
|
-
} from './fetch.js'
|
|
17
|
-
export {
|
|
18
|
-
runRestoreAuthorize,
|
|
19
|
-
} from './apply.js'
|
|
20
|
-
export {
|
|
21
|
-
runRecoveryRefetch,
|
|
22
|
-
} from './recovery.js'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/src/identity/hub/{reconciliation → shared/reconciliation}/agentReconciliation/types.ts
RENAMED
|
File without changes
|
|
File without changes
|
/package/src/identity/hub/{reconciliation → shared/reconciliation}/useAgentReconciliation.ts
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|