ethagent 3.3.4 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +11 -0
- package/.claude-plugin/plugin.json +35 -0
- package/LICENSE +1 -1
- package/README.md +64 -104
- package/commands/ethagent.md +40 -0
- package/package.json +16 -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
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import { Box, Text } from 'ink'
|
|
3
|
-
import { theme } from '../../ui/theme.js'
|
|
4
|
-
import { inferLanguageFromPath, SyntaxLine } from './SyntaxText.js'
|
|
5
|
-
|
|
6
|
-
const EMPTY_DIFF_LINE = ' '
|
|
7
|
-
|
|
8
|
-
type DiffLineTone = 'added' | 'removed' | 'added-header' | 'removed-header' | 'hunk' | 'context' | 'marker'
|
|
9
|
-
|
|
10
|
-
type DiffLineStyle = {
|
|
11
|
-
tone: DiffLineTone
|
|
12
|
-
color: string
|
|
13
|
-
backgroundColor?: string
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
type NumberedDiffLine = {
|
|
17
|
-
line: string
|
|
18
|
-
oldLine?: number
|
|
19
|
-
newLine?: number
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function diffLineColor(line: string): string {
|
|
23
|
-
return diffLineStyle(line).color
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function diffLineStyle(line: string): DiffLineStyle {
|
|
27
|
-
if (line.startsWith('+++')) return { tone: 'added-header', color: theme.diffAdded }
|
|
28
|
-
if (line.startsWith('---')) return { tone: 'removed-header', color: theme.diffRemoved }
|
|
29
|
-
if (line.startsWith('+')) {
|
|
30
|
-
return { tone: 'added', color: theme.text, backgroundColor: theme.diffAddedBackground }
|
|
31
|
-
}
|
|
32
|
-
if (line.startsWith('-')) {
|
|
33
|
-
return { tone: 'removed', color: theme.text, backgroundColor: theme.diffRemovedBackground }
|
|
34
|
-
}
|
|
35
|
-
if (line.startsWith('@@')) return { tone: 'hunk', color: theme.accentPeriwinkle }
|
|
36
|
-
if (line.startsWith('...')) return { tone: 'marker', color: theme.dim }
|
|
37
|
-
return { tone: 'context', color: theme.textSubtle }
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export const DiffView: React.FC<{ diff: string }> = ({ diff }) => (
|
|
41
|
-
<DiffLines lines={visibleDiffLines(numberDiffLines(diff))} language={inferDiffLanguage(diff)} />
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
const DiffLines: React.FC<{ lines: NumberedDiffLine[]; language: string | null }> = ({ lines, language }) => {
|
|
45
|
-
const width = lineNumberWidth(lines)
|
|
46
|
-
return (
|
|
47
|
-
<Box flexDirection="column">
|
|
48
|
-
{lines.map((line, index) => (
|
|
49
|
-
<DiffLine
|
|
50
|
-
key={index}
|
|
51
|
-
line={line.line}
|
|
52
|
-
oldLine={line.oldLine}
|
|
53
|
-
newLine={line.newLine}
|
|
54
|
-
width={width}
|
|
55
|
-
language={language}
|
|
56
|
-
/>
|
|
57
|
-
))}
|
|
58
|
-
</Box>
|
|
59
|
-
)
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const DiffLine: React.FC<{
|
|
63
|
-
line: string
|
|
64
|
-
oldLine?: number
|
|
65
|
-
newLine?: number
|
|
66
|
-
width: number
|
|
67
|
-
language: string | null
|
|
68
|
-
}> = ({
|
|
69
|
-
line,
|
|
70
|
-
oldLine,
|
|
71
|
-
newLine,
|
|
72
|
-
width,
|
|
73
|
-
language,
|
|
74
|
-
}) => {
|
|
75
|
-
const style = diffLineStyle(line)
|
|
76
|
-
const number = renderLineNumber(displayLineNumber(oldLine, newLine, style.tone), width)
|
|
77
|
-
if (line.length === 0) {
|
|
78
|
-
return <Text color={style.color}>{EMPTY_DIFF_LINE}</Text>
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (style.tone === 'added' || style.tone === 'removed') {
|
|
82
|
-
const prefixColor = style.tone === 'added' ? theme.diffAdded : theme.diffRemoved
|
|
83
|
-
return (
|
|
84
|
-
<Box width="100%" backgroundColor={style.backgroundColor}>
|
|
85
|
-
<Text>
|
|
86
|
-
{number}
|
|
87
|
-
<Text color={prefixColor}>{line.slice(0, 1)} </Text>
|
|
88
|
-
<SyntaxLine line={line.slice(1)} lang={language} fallbackColor={style.color} />
|
|
89
|
-
</Text>
|
|
90
|
-
</Box>
|
|
91
|
-
)
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (style.tone === 'context' && line.startsWith(' ')) {
|
|
95
|
-
return (
|
|
96
|
-
<Text color={style.color}>
|
|
97
|
-
{number}
|
|
98
|
-
<Text>{' '}</Text>
|
|
99
|
-
<SyntaxLine line={line.slice(1)} lang={language} fallbackColor={style.color} />
|
|
100
|
-
</Text>
|
|
101
|
-
)
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return <Text color={style.color}>{line}</Text>
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function lineNumberWidth(lines: NumberedDiffLine[]): number {
|
|
108
|
-
return Math.max(
|
|
109
|
-
2,
|
|
110
|
-
...lines.map(line => String(displayLineNumber(line.oldLine, line.newLine, diffLineStyle(line.line).tone) ?? '').length),
|
|
111
|
-
)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function displayLineNumber(
|
|
115
|
-
oldLine: number | undefined,
|
|
116
|
-
newLine: number | undefined,
|
|
117
|
-
tone: DiffLineTone,
|
|
118
|
-
): number | undefined {
|
|
119
|
-
if (tone === 'removed') return oldLine
|
|
120
|
-
return newLine ?? oldLine
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
function renderLineNumber(line: number | undefined, width: number): React.ReactNode {
|
|
124
|
-
if (line === undefined) return null
|
|
125
|
-
return <Text color={theme.dim}>{String(line).padStart(width, ' ')} </Text>
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function visibleDiffLines(lines: NumberedDiffLine[]): NumberedDiffLine[] {
|
|
129
|
-
return lines.filter(line => {
|
|
130
|
-
const tone = diffLineStyle(line.line).tone
|
|
131
|
-
return tone !== 'added-header' && tone !== 'removed-header' && tone !== 'hunk'
|
|
132
|
-
})
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function inferDiffLanguage(diff: string): string | null {
|
|
136
|
-
for (const line of diff.split('\n')) {
|
|
137
|
-
if (!line.startsWith('+++ ') || line === '+++ /dev/null') continue
|
|
138
|
-
return inferLanguageFromPath(line.slice(4).trim())
|
|
139
|
-
}
|
|
140
|
-
for (const line of diff.split('\n')) {
|
|
141
|
-
if (!line.startsWith('--- ') || line === '--- /dev/null') continue
|
|
142
|
-
return inferLanguageFromPath(line.slice(4).trim())
|
|
143
|
-
}
|
|
144
|
-
return null
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
export function numberDiffLines(diff: string): NumberedDiffLine[] {
|
|
148
|
-
const out: NumberedDiffLine[] = []
|
|
149
|
-
let oldLine: number | undefined
|
|
150
|
-
let newLine: number | undefined
|
|
151
|
-
|
|
152
|
-
for (const line of diff.split('\n')) {
|
|
153
|
-
const hunk = parseHunkHeader(line)
|
|
154
|
-
if (hunk) {
|
|
155
|
-
oldLine = hunk.oldStart
|
|
156
|
-
newLine = hunk.newStart
|
|
157
|
-
out.push({ line })
|
|
158
|
-
continue
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
if (oldLine !== undefined && newLine !== undefined) {
|
|
162
|
-
if (line.startsWith(' ')) {
|
|
163
|
-
out.push({ line, oldLine, newLine })
|
|
164
|
-
oldLine += 1
|
|
165
|
-
newLine += 1
|
|
166
|
-
continue
|
|
167
|
-
}
|
|
168
|
-
if (line.startsWith('-') && !line.startsWith('---')) {
|
|
169
|
-
out.push({ line, oldLine })
|
|
170
|
-
oldLine += 1
|
|
171
|
-
continue
|
|
172
|
-
}
|
|
173
|
-
if (line.startsWith('+') && !line.startsWith('+++')) {
|
|
174
|
-
out.push({ line, newLine })
|
|
175
|
-
newLine += 1
|
|
176
|
-
continue
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
out.push({ line })
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
return out
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
function parseHunkHeader(line: string): { oldStart: number; newStart: number } | null {
|
|
187
|
-
const match = line.match(/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/)
|
|
188
|
-
if (!match) return null
|
|
189
|
-
return {
|
|
190
|
-
oldStart: Number(match[1]),
|
|
191
|
-
newStart: Number(match[2]),
|
|
192
|
-
}
|
|
193
|
-
}
|
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import { Text } from 'ink'
|
|
3
|
-
import { styledCharsFromTokens, tokenize } from '@alcalzone/ansi-tokenize'
|
|
4
|
-
import { highlight, supportsLanguage, type Theme } from 'cli-highlight'
|
|
5
|
-
import { theme } from '../../ui/theme.js'
|
|
6
|
-
|
|
7
|
-
type Span = {
|
|
8
|
-
text: string
|
|
9
|
-
color?: string
|
|
10
|
-
bold?: boolean
|
|
11
|
-
italic?: boolean
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const ANSI_RESET_FG = '\x1B[39m'
|
|
15
|
-
const ANSI_RESET_BOLD = '\x1B[22m'
|
|
16
|
-
const ANSI_RESET_ITALIC = '\x1B[23m'
|
|
17
|
-
|
|
18
|
-
const HIGHLIGHT_THEME: Theme = {
|
|
19
|
-
keyword: style(theme.codeKeyword, { bold: true }),
|
|
20
|
-
built_in: style(theme.codeBuiltin),
|
|
21
|
-
type: style(theme.codeType),
|
|
22
|
-
literal: style(theme.codeKeyword),
|
|
23
|
-
number: style(theme.codeNumber),
|
|
24
|
-
regexp: style(theme.codeString),
|
|
25
|
-
string: style(theme.codeString),
|
|
26
|
-
class: style(theme.codeType),
|
|
27
|
-
function: style(theme.codeFunction),
|
|
28
|
-
title: style(theme.codeFunction),
|
|
29
|
-
comment: style(theme.codeComment, { italic: true }),
|
|
30
|
-
doctag: style(theme.codeComment, { italic: true }),
|
|
31
|
-
meta: style(theme.dim),
|
|
32
|
-
tag: style(theme.codeTag, { bold: true }),
|
|
33
|
-
name: style(theme.codeTag, { bold: true }),
|
|
34
|
-
attr: style(theme.codeAttribute),
|
|
35
|
-
attribute: style(theme.codeProperty),
|
|
36
|
-
variable: style(theme.codeProperty),
|
|
37
|
-
addition: style(theme.diffAdded),
|
|
38
|
-
deletion: style(theme.diffRemoved),
|
|
39
|
-
default: style(theme.textSubtle),
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const PROGRAMMING_LANGUAGES = new Set([
|
|
43
|
-
'bash',
|
|
44
|
-
'css',
|
|
45
|
-
'go',
|
|
46
|
-
'java',
|
|
47
|
-
'javascript',
|
|
48
|
-
'json',
|
|
49
|
-
'python',
|
|
50
|
-
'rust',
|
|
51
|
-
'solidity',
|
|
52
|
-
'sql',
|
|
53
|
-
'typescript',
|
|
54
|
-
'xml',
|
|
55
|
-
'yaml',
|
|
56
|
-
])
|
|
57
|
-
|
|
58
|
-
const LANGUAGE_BY_EXTENSION: Record<string, string> = {
|
|
59
|
-
cjs: 'javascript',
|
|
60
|
-
css: 'css',
|
|
61
|
-
html: 'xml',
|
|
62
|
-
js: 'javascript',
|
|
63
|
-
json: 'json',
|
|
64
|
-
jsonc: 'json',
|
|
65
|
-
jsx: 'javascript',
|
|
66
|
-
md: 'markdown',
|
|
67
|
-
mjs: 'javascript',
|
|
68
|
-
py: 'python',
|
|
69
|
-
sh: 'bash',
|
|
70
|
-
ts: 'typescript',
|
|
71
|
-
tsx: 'typescript',
|
|
72
|
-
yml: 'yaml',
|
|
73
|
-
yaml: 'yaml',
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export const SyntaxLine: React.FC<{ line: string; lang?: string | null; fallbackColor?: string }> = ({
|
|
77
|
-
line,
|
|
78
|
-
lang,
|
|
79
|
-
fallbackColor = theme.textSubtle,
|
|
80
|
-
}) => (
|
|
81
|
-
<>
|
|
82
|
-
{syntaxLineSpans(line, lang, fallbackColor).map((span, index) => (
|
|
83
|
-
<Text key={index} color={span.color} bold={span.bold} italic={span.italic}>
|
|
84
|
-
{span.text}
|
|
85
|
-
</Text>
|
|
86
|
-
))}
|
|
87
|
-
</>
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
export function syntaxLineSpans(line: string, lang?: string | null, fallbackColor: string = theme.textSubtle): Span[] {
|
|
91
|
-
const code = line.length === 0 ? ' ' : line
|
|
92
|
-
const language = supportedLanguage(lang)
|
|
93
|
-
if (!language || !PROGRAMMING_LANGUAGES.has(language)) {
|
|
94
|
-
return [{ text: code, color: fallbackColor }]
|
|
95
|
-
}
|
|
96
|
-
const highlighted = highlight(code, {
|
|
97
|
-
language: language ?? undefined,
|
|
98
|
-
ignoreIllegals: true,
|
|
99
|
-
theme: HIGHLIGHT_THEME,
|
|
100
|
-
})
|
|
101
|
-
const spans = spansFromAnsi(highlighted)
|
|
102
|
-
return spans.length > 0 ? spans : [{ text: code, color: fallbackColor }]
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
export function inferLanguageFromPath(path: string): string | null {
|
|
106
|
-
const clean = path
|
|
107
|
-
.replace(/^["']|["']$/g, '')
|
|
108
|
-
.replace(/^[ab]\//, '')
|
|
109
|
-
.replace(/\\/g, '/')
|
|
110
|
-
.split('/')
|
|
111
|
-
.pop()
|
|
112
|
-
const extension = clean?.match(/\.([A-Za-z0-9]+)$/)?.[1]?.toLowerCase()
|
|
113
|
-
return extension ? LANGUAGE_BY_EXTENSION[extension] ?? null : null
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function supportedLanguage(lang?: string | null): string | null {
|
|
117
|
-
if (!lang) return null
|
|
118
|
-
const normalized = LANGUAGE_BY_EXTENSION[lang.toLowerCase()] ?? lang.toLowerCase()
|
|
119
|
-
return supportsLanguage(normalized) ? normalized : null
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
function style(color: string, options: { bold?: boolean; italic?: boolean } = {}): (text: string) => string {
|
|
123
|
-
return text => [
|
|
124
|
-
colorCode(color),
|
|
125
|
-
options.bold ? '\x1B[1m' : '',
|
|
126
|
-
options.italic ? '\x1B[3m' : '',
|
|
127
|
-
text,
|
|
128
|
-
options.italic ? ANSI_RESET_ITALIC : '',
|
|
129
|
-
options.bold ? ANSI_RESET_BOLD : '',
|
|
130
|
-
ANSI_RESET_FG,
|
|
131
|
-
].join('')
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
function colorCode(hex: string): string {
|
|
135
|
-
const [r, g, b] = parseHexColor(hex)
|
|
136
|
-
return `\x1B[38;2;${r};${g};${b}m`
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function parseHexColor(hex: string): [number, number, number] {
|
|
140
|
-
const clean = hex.replace(/^#/, '')
|
|
141
|
-
return [
|
|
142
|
-
Number.parseInt(clean.slice(0, 2), 16),
|
|
143
|
-
Number.parseInt(clean.slice(2, 4), 16),
|
|
144
|
-
Number.parseInt(clean.slice(4, 6), 16),
|
|
145
|
-
]
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
function spansFromAnsi(value: string): Span[] {
|
|
149
|
-
const chars = styledCharsFromTokens(tokenize(value))
|
|
150
|
-
const spans: Span[] = []
|
|
151
|
-
for (const char of chars) {
|
|
152
|
-
const span = spanFromCodes(char.value, char.styles.map(styleCode => styleCode.code))
|
|
153
|
-
const previous = spans[spans.length - 1]
|
|
154
|
-
if (previous && sameStyle(previous, span)) {
|
|
155
|
-
previous.text += span.text
|
|
156
|
-
} else {
|
|
157
|
-
spans.push(span)
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
return spans
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
function spanFromCodes(text: string, codes: string[]): Span {
|
|
164
|
-
return {
|
|
165
|
-
text,
|
|
166
|
-
color: colorFromCodes(codes),
|
|
167
|
-
bold: codes.includes('\x1B[1m') || undefined,
|
|
168
|
-
italic: codes.includes('\x1B[3m') || undefined,
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
function colorFromCodes(codes: string[]): string | undefined {
|
|
173
|
-
for (let index = codes.length - 1; index >= 0; index -= 1) {
|
|
174
|
-
const match = codes[index]?.match(/\x1B\[38;2;(\d+);(\d+);(\d+)m/)
|
|
175
|
-
if (match) {
|
|
176
|
-
return rgbToHex(Number(match[1]), Number(match[2]), Number(match[3]))
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
return undefined
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
function rgbToHex(r: number, g: number, b: number): string {
|
|
183
|
-
return `#${hexByte(r)}${hexByte(g)}${hexByte(b)}`
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
function hexByte(value: number): string {
|
|
187
|
-
return Math.max(0, Math.min(255, value)).toString(16).padStart(2, '0')
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
function sameStyle(a: Span, b: Span): boolean {
|
|
191
|
-
return a.color === b.color && a.bold === b.bold && a.italic === b.italic
|
|
192
|
-
}
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
const MAX_ARG_SUMMARY = 80
|
|
2
|
-
|
|
3
|
-
export function formatToolCall(
|
|
4
|
-
name: string,
|
|
5
|
-
input: Record<string, unknown> | undefined,
|
|
6
|
-
): { displayName: string; argSummary: string } {
|
|
7
|
-
const safeInput = isRecord(input) ? input : {}
|
|
8
|
-
switch (name) {
|
|
9
|
-
case 'read_file':
|
|
10
|
-
return { displayName: 'Read', argSummary: readArgs(safeInput) }
|
|
11
|
-
case 'list_directory':
|
|
12
|
-
return { displayName: 'List', argSummary: pathArg(safeInput, '.') }
|
|
13
|
-
case 'run_bash':
|
|
14
|
-
return { displayName: 'Bash', argSummary: bashArgs(safeInput) }
|
|
15
|
-
case 'edit_file':
|
|
16
|
-
return { displayName: 'Edit', argSummary: pathArg(safeInput) }
|
|
17
|
-
case 'write_file':
|
|
18
|
-
return { displayName: 'Write', argSummary: pathArg(safeInput) }
|
|
19
|
-
case 'delete_file':
|
|
20
|
-
return { displayName: 'Delete', argSummary: pathArg(safeInput) }
|
|
21
|
-
case 'change_directory':
|
|
22
|
-
return { displayName: 'Cd', argSummary: pathArg(safeInput) }
|
|
23
|
-
case 'read_private_continuity_file':
|
|
24
|
-
return { displayName: 'ReadPrivate', argSummary: privateArgs(safeInput) }
|
|
25
|
-
case 'propose_private_continuity_edit':
|
|
26
|
-
return { displayName: 'EditPrivate', argSummary: stringArg(safeInput, 'file') }
|
|
27
|
-
case 'list_mcp_resources':
|
|
28
|
-
return { displayName: 'ListMcp', argSummary: stringArg(safeInput, 'server') }
|
|
29
|
-
case 'read_mcp_resource':
|
|
30
|
-
return { displayName: 'ReadMcp', argSummary: mcpReadArgs(safeInput) }
|
|
31
|
-
default:
|
|
32
|
-
return { displayName: humanize(name), argSummary: '' }
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function readArgs(input: Record<string, unknown>): string {
|
|
37
|
-
const filePath = pathArg(input)
|
|
38
|
-
const start = numberArg(input, 'startLine')
|
|
39
|
-
const end = numberArg(input, 'endLine')
|
|
40
|
-
if (start || end) {
|
|
41
|
-
const range = `lines ${start ?? 1}-${end ?? 'end'}`
|
|
42
|
-
return truncate(filePath ? `${filePath} · ${range}` : range)
|
|
43
|
-
}
|
|
44
|
-
return truncate(filePath)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function privateArgs(input: Record<string, unknown>): string {
|
|
48
|
-
const file = stringArg(input, 'file')
|
|
49
|
-
const start = numberArg(input, 'startLine')
|
|
50
|
-
const end = numberArg(input, 'endLine')
|
|
51
|
-
if (start || end) {
|
|
52
|
-
return truncate(`${file} · lines ${start ?? 1}-${end ?? 'end'}`)
|
|
53
|
-
}
|
|
54
|
-
return truncate(file)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function bashArgs(input: Record<string, unknown>): string {
|
|
58
|
-
const command = stringArg(input, 'command')
|
|
59
|
-
if (!command) return ''
|
|
60
|
-
const firstLine = command.split('\n')[0]?.trim() ?? ''
|
|
61
|
-
return truncate(firstLine)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function mcpReadArgs(input: Record<string, unknown>): string {
|
|
65
|
-
const server = stringArg(input, 'server')
|
|
66
|
-
const uri = stringArg(input, 'uri')
|
|
67
|
-
if (server && uri) return truncate(`${server} / ${uri}`)
|
|
68
|
-
return truncate(server || uri)
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function pathArg(input: Record<string, unknown>, fallback = ''): string {
|
|
72
|
-
const raw = stringArg(input, 'path')
|
|
73
|
-
if (!raw) return fallback
|
|
74
|
-
return raw.replace(/\\/g, '/')
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function stringArg(input: Record<string, unknown>, key: string): string {
|
|
78
|
-
const value = input[key]
|
|
79
|
-
return typeof value === 'string' ? value : ''
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function numberArg(input: Record<string, unknown>, key: string): number | undefined {
|
|
83
|
-
const value = input[key]
|
|
84
|
-
return typeof value === 'number' && Number.isFinite(value) ? value : undefined
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function truncate(text: string): string {
|
|
88
|
-
const flat = text.replace(/\s+/g, ' ').trim()
|
|
89
|
-
if (flat.length <= MAX_ARG_SUMMARY) return flat
|
|
90
|
-
return `${flat.slice(0, MAX_ARG_SUMMARY - 1)}…`
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function humanize(name: string): string {
|
|
94
|
-
return name
|
|
95
|
-
.split('_')
|
|
96
|
-
.filter(part => part.length > 0)
|
|
97
|
-
.map(part => part.charAt(0).toUpperCase() + part.slice(1))
|
|
98
|
-
.join('')
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
102
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
103
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { splitFileChangeResult } from '../../tools/fileDiff.js'
|
|
2
|
-
|
|
3
|
-
const COMPACT_SUCCESS_TOOL_RESULTS = new Set([
|
|
4
|
-
'read_file',
|
|
5
|
-
'read_private_continuity_file',
|
|
6
|
-
])
|
|
7
|
-
|
|
8
|
-
export function hidesSuccessfulToolResultContent(name: string, isError?: boolean): boolean {
|
|
9
|
-
return !isError && COMPACT_SUCCESS_TOOL_RESULTS.has(name)
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function toolResultDiffContent(content: string, isError?: boolean): string | undefined {
|
|
13
|
-
if (isError) return undefined
|
|
14
|
-
return splitFileChangeResult(content).diff
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function toolResultTextContent(content: string): string {
|
|
18
|
-
return splitFileChangeResult(content).content
|
|
19
|
-
}
|