clawdex-mobile 5.0.1 → 5.0.2
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 +4 -0
- package/docs/setup-and-operations.md +3 -1
- package/docs/troubleshooting.md +1 -0
- package/package.json +18 -8
- package/scripts/setup-secure-dev.sh +26 -17
- package/services/rust-bridge/Cargo.lock +1 -1
- package/services/rust-bridge/Cargo.toml +1 -1
- package/vendor/bridge-binaries/darwin-arm64/codex-rust-bridge +0 -0
- package/vendor/bridge-binaries/darwin-x64/codex-rust-bridge +0 -0
- package/vendor/bridge-binaries/linux-x64/codex-rust-bridge +0 -0
- package/vendor/bridge-binaries/win32-x64/codex-rust-bridge.exe +0 -0
- package/.artifacts/bridge-binaries/bridge-binaries-darwin-arm64/codex-rust-bridge +0 -0
- package/.artifacts/bridge-binaries/bridge-binaries-darwin-x64/codex-rust-bridge +0 -0
- package/.artifacts/bridge-binaries/bridge-binaries-linux-x64/codex-rust-bridge +0 -0
- package/.artifacts/bridge-binaries/bridge-binaries-win32-x64/codex-rust-bridge.exe +0 -0
- package/.github/workflows/ci.yml +0 -80
- package/.github/workflows/npm-release.yml +0 -208
- package/.github/workflows/pages.yml +0 -41
- package/AGENTS.md +0 -273
- package/STATUS.md +0 -115
- package/apps/mobile/.env.example +0 -6
- package/apps/mobile/App.tsx +0 -943
- package/apps/mobile/app.json +0 -77
- package/apps/mobile/assets/brand/adaptive-icon.png +0 -0
- package/apps/mobile/assets/brand/app-icon.png +0 -0
- package/apps/mobile/assets/brand/favicon.png +0 -0
- package/apps/mobile/assets/brand/mark.png +0 -0
- package/apps/mobile/assets/brand/splash-icon-white.png +0 -0
- package/apps/mobile/assets/brand/splash-icon.png +0 -0
- package/apps/mobile/babel.config.js +0 -7
- package/apps/mobile/eas.json +0 -40
- package/apps/mobile/eslint.config.cjs +0 -28
- package/apps/mobile/index.js +0 -5
- package/apps/mobile/package.json +0 -57
- package/apps/mobile/plugins/withAndroidCleartextTraffic.js +0 -14
- package/apps/mobile/src/api/__tests__/chatMapping.test.ts +0 -351
- package/apps/mobile/src/api/__tests__/client.test.ts +0 -1494
- package/apps/mobile/src/api/__tests__/ws.test.ts +0 -640
- package/apps/mobile/src/api/account.ts +0 -47
- package/apps/mobile/src/api/chatMapping.ts +0 -1048
- package/apps/mobile/src/api/client.ts +0 -1430
- package/apps/mobile/src/api/rateLimits.ts +0 -143
- package/apps/mobile/src/api/types.ts +0 -435
- package/apps/mobile/src/api/ws.ts +0 -852
- package/apps/mobile/src/bridgeUrl.ts +0 -105
- package/apps/mobile/src/components/ActivityBar.tsx +0 -95
- package/apps/mobile/src/components/ApprovalBanner.tsx +0 -207
- package/apps/mobile/src/components/BrandMark.tsx +0 -43
- package/apps/mobile/src/components/ChatHeader.tsx +0 -107
- package/apps/mobile/src/components/ChatInput.tsx +0 -457
- package/apps/mobile/src/components/ChatMessage.tsx +0 -959
- package/apps/mobile/src/components/ComposerUsageLimits.tsx +0 -167
- package/apps/mobile/src/components/SelectionSheet.tsx +0 -466
- package/apps/mobile/src/components/StatusLine.tsx +0 -52
- package/apps/mobile/src/components/ToolBlock.tsx +0 -67
- package/apps/mobile/src/components/TypingIndicator.tsx +0 -64
- package/apps/mobile/src/components/VoiceRecordingWaveform.tsx +0 -181
- package/apps/mobile/src/components/WorkspacePickerModal.tsx +0 -812
- package/apps/mobile/src/components/__tests__/chat-input-layout.test.ts +0 -35
- package/apps/mobile/src/components/__tests__/chatImageSource.test.ts +0 -44
- package/apps/mobile/src/components/__tests__/composerUsageLimits.test.ts +0 -138
- package/apps/mobile/src/components/__tests__/voiceWaveform.test.ts +0 -31
- package/apps/mobile/src/components/chat-input-layout.ts +0 -59
- package/apps/mobile/src/components/chatImageSource.ts +0 -86
- package/apps/mobile/src/components/usageLimitBadges.ts +0 -109
- package/apps/mobile/src/components/voiceWaveform.ts +0 -46
- package/apps/mobile/src/config.ts +0 -64
- package/apps/mobile/src/hooks/useVoiceRecorder.ts +0 -271
- package/apps/mobile/src/navigation/DrawerContent.tsx +0 -1129
- package/apps/mobile/src/navigation/__tests__/chatThreadTree.test.ts +0 -89
- package/apps/mobile/src/navigation/__tests__/drawerChats.test.ts +0 -65
- package/apps/mobile/src/navigation/chatThreadTree.ts +0 -191
- package/apps/mobile/src/navigation/drawerChats.ts +0 -9
- package/apps/mobile/src/screens/GitScreen.tsx +0 -1489
- package/apps/mobile/src/screens/MainScreen.tsx +0 -10511
- package/apps/mobile/src/screens/OnboardingScreen.tsx +0 -1746
- package/apps/mobile/src/screens/PrivacyScreen.tsx +0 -196
- package/apps/mobile/src/screens/SettingsScreen.tsx +0 -870
- package/apps/mobile/src/screens/TerminalScreen.tsx +0 -248
- package/apps/mobile/src/screens/TermsScreen.tsx +0 -192
- package/apps/mobile/src/screens/__tests__/agentThreadDisplay.test.ts +0 -80
- package/apps/mobile/src/screens/__tests__/agentThreads.test.ts +0 -170
- package/apps/mobile/src/screens/__tests__/gitDiff.test.ts +0 -131
- package/apps/mobile/src/screens/__tests__/planCardState.test.ts +0 -88
- package/apps/mobile/src/screens/__tests__/subAgentTranscript.test.ts +0 -102
- package/apps/mobile/src/screens/__tests__/transcriptMessages.test.ts +0 -97
- package/apps/mobile/src/screens/agentThreadDisplay.ts +0 -261
- package/apps/mobile/src/screens/agentThreads.ts +0 -167
- package/apps/mobile/src/screens/gitDiff.ts +0 -380
- package/apps/mobile/src/screens/planCardState.ts +0 -40
- package/apps/mobile/src/screens/subAgentTranscript.ts +0 -149
- package/apps/mobile/src/screens/transcriptMessages.ts +0 -102
- package/apps/mobile/src/theme.ts +0 -106
- package/apps/mobile/src/types/assets.d.ts +0 -4
- package/apps/mobile/tsconfig.json +0 -33
- package/docs/app-review-notes.md +0 -116
- package/docs/codex-app-server-cli-gap-tracker.md +0 -90
- package/docs/eas-builds.md +0 -91
- package/docs/open-source-license-requirements.md +0 -32
- package/docs/plans/2026-02-20-codex-desktop-style-redesign.md +0 -190
- package/docs/plans/2026-02-20-codex-mobile-implementation.md +0 -1630
- package/docs/plans/2026-02-21-codex-ui-redesign-design.md +0 -101
- package/docs/plans/2026-02-21-codex-ui-redesign.md +0 -1229
- package/docs/privacy-policy.md +0 -54
- package/docs/realtime-streaming-limitations.md +0 -161
- package/docs/terms-of-service.md +0 -33
- package/docs/voice-transcription.md +0 -87
- package/scripts/codex-live-demo.sh +0 -69
- package/scripts/start-bridge-secure.sh +0 -5
- package/scripts/start-expo.sh +0 -176
- package/scripts/sync-versions.js +0 -63
- package/scripts/teardown.sh +0 -136
- package/services/mac-bridge/.env.example +0 -10
- package/services/mac-bridge/codex-types/AbsolutePathBuf.ts +0 -14
- package/services/mac-bridge/codex-types/AddConversationListenerParams.ts +0 -6
- package/services/mac-bridge/codex-types/AddConversationSubscriptionResponse.ts +0 -5
- package/services/mac-bridge/codex-types/AgentMessageContent.ts +0 -5
- package/services/mac-bridge/codex-types/AgentMessageContentDeltaEvent.ts +0 -5
- package/services/mac-bridge/codex-types/AgentMessageDeltaEvent.ts +0 -5
- package/services/mac-bridge/codex-types/AgentMessageEvent.ts +0 -5
- package/services/mac-bridge/codex-types/AgentMessageItem.ts +0 -21
- package/services/mac-bridge/codex-types/AgentReasoningDeltaEvent.ts +0 -5
- package/services/mac-bridge/codex-types/AgentReasoningEvent.ts +0 -5
- package/services/mac-bridge/codex-types/AgentReasoningRawContentDeltaEvent.ts +0 -5
- package/services/mac-bridge/codex-types/AgentReasoningRawContentEvent.ts +0 -5
- package/services/mac-bridge/codex-types/AgentReasoningSectionBreakEvent.ts +0 -5
- package/services/mac-bridge/codex-types/AgentStatus.ts +0 -8
- package/services/mac-bridge/codex-types/ApplyPatchApprovalParams.ts +0 -21
- package/services/mac-bridge/codex-types/ApplyPatchApprovalRequestEvent.ts +0 -23
- package/services/mac-bridge/codex-types/ApplyPatchApprovalResponse.ts +0 -6
- package/services/mac-bridge/codex-types/ArchiveConversationParams.ts +0 -6
- package/services/mac-bridge/codex-types/ArchiveConversationResponse.ts +0 -5
- package/services/mac-bridge/codex-types/AskForApproval.ts +0 -9
- package/services/mac-bridge/codex-types/AuthMode.ts +0 -8
- package/services/mac-bridge/codex-types/AuthStatusChangeNotification.ts +0 -9
- package/services/mac-bridge/codex-types/BackgroundEventEvent.ts +0 -5
- package/services/mac-bridge/codex-types/ByteRange.ts +0 -13
- package/services/mac-bridge/codex-types/CallToolResult.ts +0 -9
- package/services/mac-bridge/codex-types/CancelLoginChatGptParams.ts +0 -5
- package/services/mac-bridge/codex-types/CancelLoginChatGptResponse.ts +0 -5
- package/services/mac-bridge/codex-types/ClientInfo.ts +0 -5
- package/services/mac-bridge/codex-types/ClientNotification.ts +0 -5
- package/services/mac-bridge/codex-types/ClientRequest.ts +0 -60
- package/services/mac-bridge/codex-types/CodexErrorInfo.ts +0 -8
- package/services/mac-bridge/codex-types/CollabAgentInteractionBeginEvent.ts +0 -23
- package/services/mac-bridge/codex-types/CollabAgentInteractionEndEvent.ts +0 -28
- package/services/mac-bridge/codex-types/CollabAgentSpawnBeginEvent.ts +0 -19
- package/services/mac-bridge/codex-types/CollabAgentSpawnEndEvent.ts +0 -28
- package/services/mac-bridge/codex-types/CollabCloseBeginEvent.ts +0 -18
- package/services/mac-bridge/codex-types/CollabCloseEndEvent.ts +0 -24
- package/services/mac-bridge/codex-types/CollabResumeBeginEvent.ts +0 -18
- package/services/mac-bridge/codex-types/CollabResumeEndEvent.ts +0 -24
- package/services/mac-bridge/codex-types/CollabWaitingBeginEvent.ts +0 -18
- package/services/mac-bridge/codex-types/CollabWaitingEndEvent.ts +0 -19
- package/services/mac-bridge/codex-types/CollaborationMode.ts +0 -10
- package/services/mac-bridge/codex-types/CollaborationModeMask.ts +0 -11
- package/services/mac-bridge/codex-types/ContentItem.ts +0 -5
- package/services/mac-bridge/codex-types/ContextCompactedEvent.ts +0 -5
- package/services/mac-bridge/codex-types/ContextCompactionItem.ts +0 -5
- package/services/mac-bridge/codex-types/ConversationGitInfo.ts +0 -5
- package/services/mac-bridge/codex-types/ConversationSummary.ts +0 -8
- package/services/mac-bridge/codex-types/CreditsSnapshot.ts +0 -5
- package/services/mac-bridge/codex-types/CustomPrompt.ts +0 -5
- package/services/mac-bridge/codex-types/DeprecationNoticeEvent.ts +0 -13
- package/services/mac-bridge/codex-types/DynamicToolCallRequest.ts +0 -6
- package/services/mac-bridge/codex-types/ElicitationRequestEvent.ts +0 -5
- package/services/mac-bridge/codex-types/ErrorEvent.ts +0 -6
- package/services/mac-bridge/codex-types/EventMsg.ts +0 -78
- package/services/mac-bridge/codex-types/ExecApprovalRequestEvent.ts +0 -44
- package/services/mac-bridge/codex-types/ExecCommandApprovalParams.ts +0 -16
- package/services/mac-bridge/codex-types/ExecCommandApprovalResponse.ts +0 -6
- package/services/mac-bridge/codex-types/ExecCommandBeginEvent.ts +0 -35
- package/services/mac-bridge/codex-types/ExecCommandEndEvent.ts +0 -64
- package/services/mac-bridge/codex-types/ExecCommandOutputDeltaEvent.ts +0 -18
- package/services/mac-bridge/codex-types/ExecCommandSource.ts +0 -5
- package/services/mac-bridge/codex-types/ExecCommandStatus.ts +0 -5
- package/services/mac-bridge/codex-types/ExecOneOffCommandParams.ts +0 -6
- package/services/mac-bridge/codex-types/ExecOneOffCommandResponse.ts +0 -5
- package/services/mac-bridge/codex-types/ExecOutputStream.ts +0 -5
- package/services/mac-bridge/codex-types/ExecPolicyAmendment.ts +0 -12
- package/services/mac-bridge/codex-types/ExitedReviewModeEvent.ts +0 -6
- package/services/mac-bridge/codex-types/FileChange.ts +0 -5
- package/services/mac-bridge/codex-types/ForcedLoginMethod.ts +0 -5
- package/services/mac-bridge/codex-types/ForkConversationParams.ts +0 -7
- package/services/mac-bridge/codex-types/ForkConversationResponse.ts +0 -7
- package/services/mac-bridge/codex-types/FunctionCallOutputBody.ts +0 -6
- package/services/mac-bridge/codex-types/FunctionCallOutputContentItem.ts +0 -9
- package/services/mac-bridge/codex-types/FunctionCallOutputPayload.ts +0 -12
- package/services/mac-bridge/codex-types/FuzzyFileSearchParams.ts +0 -5
- package/services/mac-bridge/codex-types/FuzzyFileSearchResponse.ts +0 -6
- package/services/mac-bridge/codex-types/FuzzyFileSearchResult.ts +0 -8
- package/services/mac-bridge/codex-types/FuzzyFileSearchSessionCompletedNotification.ts +0 -5
- package/services/mac-bridge/codex-types/FuzzyFileSearchSessionUpdatedNotification.ts +0 -6
- package/services/mac-bridge/codex-types/GetAuthStatusParams.ts +0 -5
- package/services/mac-bridge/codex-types/GetAuthStatusResponse.ts +0 -6
- package/services/mac-bridge/codex-types/GetConversationSummaryParams.ts +0 -6
- package/services/mac-bridge/codex-types/GetConversationSummaryResponse.ts +0 -6
- package/services/mac-bridge/codex-types/GetHistoryEntryResponseEvent.ts +0 -10
- package/services/mac-bridge/codex-types/GetUserAgentResponse.ts +0 -5
- package/services/mac-bridge/codex-types/GetUserSavedConfigResponse.ts +0 -6
- package/services/mac-bridge/codex-types/GhostCommit.ts +0 -8
- package/services/mac-bridge/codex-types/GitDiffToRemoteParams.ts +0 -5
- package/services/mac-bridge/codex-types/GitDiffToRemoteResponse.ts +0 -6
- package/services/mac-bridge/codex-types/GitSha.ts +0 -5
- package/services/mac-bridge/codex-types/HistoryEntry.ts +0 -5
- package/services/mac-bridge/codex-types/InitializeCapabilities.ts +0 -17
- package/services/mac-bridge/codex-types/InitializeParams.ts +0 -7
- package/services/mac-bridge/codex-types/InitializeResponse.ts +0 -5
- package/services/mac-bridge/codex-types/InputItem.ts +0 -10
- package/services/mac-bridge/codex-types/InputModality.ts +0 -8
- package/services/mac-bridge/codex-types/InterruptConversationParams.ts +0 -6
- package/services/mac-bridge/codex-types/InterruptConversationResponse.ts +0 -6
- package/services/mac-bridge/codex-types/ItemCompletedEvent.ts +0 -7
- package/services/mac-bridge/codex-types/ItemStartedEvent.ts +0 -7
- package/services/mac-bridge/codex-types/ListConversationsParams.ts +0 -5
- package/services/mac-bridge/codex-types/ListConversationsResponse.ts +0 -6
- package/services/mac-bridge/codex-types/ListCustomPromptsResponseEvent.ts +0 -9
- package/services/mac-bridge/codex-types/ListRemoteSkillsResponseEvent.ts +0 -9
- package/services/mac-bridge/codex-types/ListSkillsResponseEvent.ts +0 -9
- package/services/mac-bridge/codex-types/LocalShellAction.ts +0 -6
- package/services/mac-bridge/codex-types/LocalShellExecAction.ts +0 -5
- package/services/mac-bridge/codex-types/LocalShellStatus.ts +0 -5
- package/services/mac-bridge/codex-types/LoginApiKeyParams.ts +0 -5
- package/services/mac-bridge/codex-types/LoginApiKeyResponse.ts +0 -5
- package/services/mac-bridge/codex-types/LoginChatGptCompleteNotification.ts +0 -8
- package/services/mac-bridge/codex-types/LoginChatGptResponse.ts +0 -5
- package/services/mac-bridge/codex-types/LogoutChatGptResponse.ts +0 -5
- package/services/mac-bridge/codex-types/McpAuthStatus.ts +0 -5
- package/services/mac-bridge/codex-types/McpInvocation.ts +0 -18
- package/services/mac-bridge/codex-types/McpListToolsResponseEvent.ts +0 -25
- package/services/mac-bridge/codex-types/McpStartupCompleteEvent.ts +0 -6
- package/services/mac-bridge/codex-types/McpStartupFailure.ts +0 -5
- package/services/mac-bridge/codex-types/McpStartupStatus.ts +0 -5
- package/services/mac-bridge/codex-types/McpStartupUpdateEvent.ts +0 -14
- package/services/mac-bridge/codex-types/McpToolCallBeginEvent.ts +0 -10
- package/services/mac-bridge/codex-types/McpToolCallEndEvent.ts +0 -15
- package/services/mac-bridge/codex-types/MessagePhase.ts +0 -11
- package/services/mac-bridge/codex-types/ModeKind.ts +0 -8
- package/services/mac-bridge/codex-types/ModelRerouteEvent.ts +0 -6
- package/services/mac-bridge/codex-types/ModelRerouteReason.ts +0 -5
- package/services/mac-bridge/codex-types/NetworkAccess.ts +0 -8
- package/services/mac-bridge/codex-types/NetworkApprovalContext.ts +0 -6
- package/services/mac-bridge/codex-types/NetworkApprovalProtocol.ts +0 -5
- package/services/mac-bridge/codex-types/NewConversationParams.ts +0 -8
- package/services/mac-bridge/codex-types/NewConversationResponse.ts +0 -7
- package/services/mac-bridge/codex-types/ParsedCommand.ts +0 -12
- package/services/mac-bridge/codex-types/PatchApplyBeginEvent.ts +0 -23
- package/services/mac-bridge/codex-types/PatchApplyEndEvent.ts +0 -36
- package/services/mac-bridge/codex-types/PatchApplyStatus.ts +0 -5
- package/services/mac-bridge/codex-types/Personality.ts +0 -5
- package/services/mac-bridge/codex-types/PlanDeltaEvent.ts +0 -5
- package/services/mac-bridge/codex-types/PlanItem.ts +0 -5
- package/services/mac-bridge/codex-types/PlanItemArg.ts +0 -6
- package/services/mac-bridge/codex-types/PlanType.ts +0 -5
- package/services/mac-bridge/codex-types/Profile.ts +0 -9
- package/services/mac-bridge/codex-types/RateLimitSnapshot.ts +0 -8
- package/services/mac-bridge/codex-types/RateLimitWindow.ts +0 -17
- package/services/mac-bridge/codex-types/RawResponseItemEvent.ts +0 -6
- package/services/mac-bridge/codex-types/ReadOnlyAccess.ts +0 -19
- package/services/mac-bridge/codex-types/ReasoningContentDeltaEvent.ts +0 -5
- package/services/mac-bridge/codex-types/ReasoningEffort.ts +0 -8
- package/services/mac-bridge/codex-types/ReasoningItem.ts +0 -5
- package/services/mac-bridge/codex-types/ReasoningItemContent.ts +0 -5
- package/services/mac-bridge/codex-types/ReasoningItemReasoningSummary.ts +0 -5
- package/services/mac-bridge/codex-types/ReasoningRawContentDeltaEvent.ts +0 -5
- package/services/mac-bridge/codex-types/ReasoningSummary.ts +0 -10
- package/services/mac-bridge/codex-types/RemoteSkillDownloadedEvent.ts +0 -8
- package/services/mac-bridge/codex-types/RemoteSkillSummary.ts +0 -5
- package/services/mac-bridge/codex-types/RemoveConversationListenerParams.ts +0 -5
- package/services/mac-bridge/codex-types/RemoveConversationSubscriptionResponse.ts +0 -5
- package/services/mac-bridge/codex-types/RequestId.ts +0 -5
- package/services/mac-bridge/codex-types/RequestUserInputEvent.ts +0 -15
- package/services/mac-bridge/codex-types/RequestUserInputQuestion.ts +0 -6
- package/services/mac-bridge/codex-types/RequestUserInputQuestionOption.ts +0 -5
- package/services/mac-bridge/codex-types/Resource.ts +0 -9
- package/services/mac-bridge/codex-types/ResourceTemplate.ts +0 -9
- package/services/mac-bridge/codex-types/ResponseItem.ts +0 -18
- package/services/mac-bridge/codex-types/ResumeConversationParams.ts +0 -8
- package/services/mac-bridge/codex-types/ResumeConversationResponse.ts +0 -7
- package/services/mac-bridge/codex-types/ReviewCodeLocation.ts +0 -9
- package/services/mac-bridge/codex-types/ReviewDecision.ts +0 -9
- package/services/mac-bridge/codex-types/ReviewFinding.ts +0 -9
- package/services/mac-bridge/codex-types/ReviewLineRange.ts +0 -8
- package/services/mac-bridge/codex-types/ReviewOutputEvent.ts +0 -9
- package/services/mac-bridge/codex-types/ReviewRequest.ts +0 -9
- package/services/mac-bridge/codex-types/ReviewTarget.ts +0 -9
- package/services/mac-bridge/codex-types/SandboxMode.ts +0 -5
- package/services/mac-bridge/codex-types/SandboxPolicy.ts +0 -44
- package/services/mac-bridge/codex-types/SandboxSettings.ts +0 -6
- package/services/mac-bridge/codex-types/SendUserMessageParams.ts +0 -7
- package/services/mac-bridge/codex-types/SendUserMessageResponse.ts +0 -5
- package/services/mac-bridge/codex-types/SendUserTurnParams.ts +0 -16
- package/services/mac-bridge/codex-types/SendUserTurnResponse.ts +0 -5
- package/services/mac-bridge/codex-types/ServerNotification.ts +0 -45
- package/services/mac-bridge/codex-types/ServerRequest.ts +0 -16
- package/services/mac-bridge/codex-types/SessionConfiguredEvent.ts +0 -57
- package/services/mac-bridge/codex-types/SessionConfiguredNotification.ts +0 -8
- package/services/mac-bridge/codex-types/SessionNetworkProxyRuntime.ts +0 -5
- package/services/mac-bridge/codex-types/SessionSource.ts +0 -6
- package/services/mac-bridge/codex-types/SetDefaultModelParams.ts +0 -6
- package/services/mac-bridge/codex-types/SetDefaultModelResponse.ts +0 -5
- package/services/mac-bridge/codex-types/Settings.ts +0 -9
- package/services/mac-bridge/codex-types/SkillDependencies.ts +0 -6
- package/services/mac-bridge/codex-types/SkillErrorInfo.ts +0 -5
- package/services/mac-bridge/codex-types/SkillInterface.ts +0 -5
- package/services/mac-bridge/codex-types/SkillMetadata.ts +0 -12
- package/services/mac-bridge/codex-types/SkillScope.ts +0 -5
- package/services/mac-bridge/codex-types/SkillToolDependency.ts +0 -5
- package/services/mac-bridge/codex-types/SkillsListEntry.ts +0 -7
- package/services/mac-bridge/codex-types/StepStatus.ts +0 -5
- package/services/mac-bridge/codex-types/StreamErrorEvent.ts +0 -12
- package/services/mac-bridge/codex-types/SubAgentSource.ts +0 -6
- package/services/mac-bridge/codex-types/TerminalInteractionEvent.ts +0 -17
- package/services/mac-bridge/codex-types/TextElement.ts +0 -14
- package/services/mac-bridge/codex-types/ThreadId.ts +0 -5
- package/services/mac-bridge/codex-types/ThreadNameUpdatedEvent.ts +0 -6
- package/services/mac-bridge/codex-types/ThreadRolledBackEvent.ts +0 -9
- package/services/mac-bridge/codex-types/TokenCountEvent.ts +0 -7
- package/services/mac-bridge/codex-types/TokenUsage.ts +0 -5
- package/services/mac-bridge/codex-types/TokenUsageInfo.ts +0 -6
- package/services/mac-bridge/codex-types/Tool.ts +0 -9
- package/services/mac-bridge/codex-types/Tools.ts +0 -5
- package/services/mac-bridge/codex-types/TurnAbortReason.ts +0 -5
- package/services/mac-bridge/codex-types/TurnAbortedEvent.ts +0 -6
- package/services/mac-bridge/codex-types/TurnCompleteEvent.ts +0 -5
- package/services/mac-bridge/codex-types/TurnDiffEvent.ts +0 -5
- package/services/mac-bridge/codex-types/TurnItem.ts +0 -11
- package/services/mac-bridge/codex-types/TurnStartedEvent.ts +0 -6
- package/services/mac-bridge/codex-types/UndoCompletedEvent.ts +0 -5
- package/services/mac-bridge/codex-types/UndoStartedEvent.ts +0 -5
- package/services/mac-bridge/codex-types/UpdatePlanArgs.ts +0 -10
- package/services/mac-bridge/codex-types/UserInfoResponse.ts +0 -5
- package/services/mac-bridge/codex-types/UserInput.ts +0 -16
- package/services/mac-bridge/codex-types/UserMessageEvent.ts +0 -22
- package/services/mac-bridge/codex-types/UserMessageItem.ts +0 -6
- package/services/mac-bridge/codex-types/UserSavedConfig.ts +0 -14
- package/services/mac-bridge/codex-types/Verbosity.ts +0 -9
- package/services/mac-bridge/codex-types/ViewImageToolCallEvent.ts +0 -13
- package/services/mac-bridge/codex-types/WarningEvent.ts +0 -5
- package/services/mac-bridge/codex-types/WebSearchAction.ts +0 -5
- package/services/mac-bridge/codex-types/WebSearchBeginEvent.ts +0 -5
- package/services/mac-bridge/codex-types/WebSearchEndEvent.ts +0 -6
- package/services/mac-bridge/codex-types/WebSearchItem.ts +0 -6
- package/services/mac-bridge/codex-types/WebSearchMode.ts +0 -5
- package/services/mac-bridge/codex-types/index.ts +0 -234
- package/services/mac-bridge/codex-types/serde_json/JsonValue.ts +0 -5
- package/services/mac-bridge/codex-types/v2/Account.ts +0 -6
- package/services/mac-bridge/codex-types/v2/AccountLoginCompletedNotification.ts +0 -5
- package/services/mac-bridge/codex-types/v2/AccountRateLimitsUpdatedNotification.ts +0 -6
- package/services/mac-bridge/codex-types/v2/AccountUpdatedNotification.ts +0 -6
- package/services/mac-bridge/codex-types/v2/AgentMessageDeltaNotification.ts +0 -5
- package/services/mac-bridge/codex-types/v2/AnalyticsConfig.ts +0 -6
- package/services/mac-bridge/codex-types/v2/AppBranding.ts +0 -8
- package/services/mac-bridge/codex-types/v2/AppDisabledReason.ts +0 -5
- package/services/mac-bridge/codex-types/v2/AppInfo.ts +0 -19
- package/services/mac-bridge/codex-types/v2/AppListUpdatedNotification.ts +0 -9
- package/services/mac-bridge/codex-types/v2/AppMetadata.ts +0 -7
- package/services/mac-bridge/codex-types/v2/AppReview.ts +0 -5
- package/services/mac-bridge/codex-types/v2/AppScreenshot.ts +0 -5
- package/services/mac-bridge/codex-types/v2/AppsConfig.ts +0 -6
- package/services/mac-bridge/codex-types/v2/AppsListParams.ts +0 -24
- package/services/mac-bridge/codex-types/v2/AppsListResponse.ts +0 -14
- package/services/mac-bridge/codex-types/v2/AskForApproval.ts +0 -5
- package/services/mac-bridge/codex-types/v2/ByteRange.ts +0 -5
- package/services/mac-bridge/codex-types/v2/CancelLoginAccountParams.ts +0 -5
- package/services/mac-bridge/codex-types/v2/CancelLoginAccountResponse.ts +0 -6
- package/services/mac-bridge/codex-types/v2/CancelLoginAccountStatus.ts +0 -5
- package/services/mac-bridge/codex-types/v2/ChatgptAuthTokensRefreshParams.ts +0 -16
- package/services/mac-bridge/codex-types/v2/ChatgptAuthTokensRefreshReason.ts +0 -5
- package/services/mac-bridge/codex-types/v2/ChatgptAuthTokensRefreshResponse.ts +0 -5
- package/services/mac-bridge/codex-types/v2/CodexErrorInfo.ts +0 -11
- package/services/mac-bridge/codex-types/v2/CollabAgentState.ts +0 -6
- package/services/mac-bridge/codex-types/v2/CollabAgentStatus.ts +0 -5
- package/services/mac-bridge/codex-types/v2/CollabAgentTool.ts +0 -5
- package/services/mac-bridge/codex-types/v2/CollabAgentToolCallStatus.ts +0 -5
- package/services/mac-bridge/codex-types/v2/CommandAction.ts +0 -5
- package/services/mac-bridge/codex-types/v2/CommandExecParams.ts +0 -6
- package/services/mac-bridge/codex-types/v2/CommandExecResponse.ts +0 -5
- package/services/mac-bridge/codex-types/v2/CommandExecutionApprovalDecision.ts +0 -6
- package/services/mac-bridge/codex-types/v2/CommandExecutionOutputDeltaNotification.ts +0 -5
- package/services/mac-bridge/codex-types/v2/CommandExecutionRequestApprovalParams.ts +0 -37
- package/services/mac-bridge/codex-types/v2/CommandExecutionRequestApprovalResponse.ts +0 -6
- package/services/mac-bridge/codex-types/v2/CommandExecutionStatus.ts +0 -5
- package/services/mac-bridge/codex-types/v2/Config.ts +0 -17
- package/services/mac-bridge/codex-types/v2/ConfigBatchWriteParams.ts +0 -10
- package/services/mac-bridge/codex-types/v2/ConfigEdit.ts +0 -7
- package/services/mac-bridge/codex-types/v2/ConfigLayer.ts +0 -7
- package/services/mac-bridge/codex-types/v2/ConfigLayerMetadata.ts +0 -6
- package/services/mac-bridge/codex-types/v2/ConfigLayerSource.ts +0 -16
- package/services/mac-bridge/codex-types/v2/ConfigReadParams.ts +0 -11
- package/services/mac-bridge/codex-types/v2/ConfigReadResponse.ts +0 -8
- package/services/mac-bridge/codex-types/v2/ConfigRequirements.ts +0 -9
- package/services/mac-bridge/codex-types/v2/ConfigRequirementsReadResponse.ts +0 -10
- package/services/mac-bridge/codex-types/v2/ConfigValueWriteParams.ts +0 -11
- package/services/mac-bridge/codex-types/v2/ConfigWarningNotification.ts +0 -22
- package/services/mac-bridge/codex-types/v2/ConfigWriteResponse.ts +0 -12
- package/services/mac-bridge/codex-types/v2/ContextCompactedNotification.ts +0 -8
- package/services/mac-bridge/codex-types/v2/CreditsSnapshot.ts +0 -5
- package/services/mac-bridge/codex-types/v2/DeprecationNoticeNotification.ts +0 -13
- package/services/mac-bridge/codex-types/v2/DynamicToolCallOutputContentItem.ts +0 -5
- package/services/mac-bridge/codex-types/v2/DynamicToolCallParams.ts +0 -6
- package/services/mac-bridge/codex-types/v2/DynamicToolCallResponse.ts +0 -6
- package/services/mac-bridge/codex-types/v2/DynamicToolSpec.ts +0 -6
- package/services/mac-bridge/codex-types/v2/ErrorNotification.ts +0 -6
- package/services/mac-bridge/codex-types/v2/ExecPolicyAmendment.ts +0 -5
- package/services/mac-bridge/codex-types/v2/ExperimentalFeature.ts +0 -37
- package/services/mac-bridge/codex-types/v2/ExperimentalFeatureListParams.ts +0 -13
- package/services/mac-bridge/codex-types/v2/ExperimentalFeatureListResponse.ts +0 -11
- package/services/mac-bridge/codex-types/v2/ExperimentalFeatureStage.ts +0 -5
- package/services/mac-bridge/codex-types/v2/FeedbackUploadParams.ts +0 -5
- package/services/mac-bridge/codex-types/v2/FeedbackUploadResponse.ts +0 -5
- package/services/mac-bridge/codex-types/v2/FileChangeApprovalDecision.ts +0 -5
- package/services/mac-bridge/codex-types/v2/FileChangeOutputDeltaNotification.ts +0 -5
- package/services/mac-bridge/codex-types/v2/FileChangeRequestApprovalParams.ts +0 -14
- package/services/mac-bridge/codex-types/v2/FileChangeRequestApprovalResponse.ts +0 -6
- package/services/mac-bridge/codex-types/v2/FileUpdateChange.ts +0 -6
- package/services/mac-bridge/codex-types/v2/GetAccountParams.ts +0 -13
- package/services/mac-bridge/codex-types/v2/GetAccountRateLimitsResponse.ts +0 -14
- package/services/mac-bridge/codex-types/v2/GetAccountResponse.ts +0 -6
- package/services/mac-bridge/codex-types/v2/GitInfo.ts +0 -5
- package/services/mac-bridge/codex-types/v2/HazelnutScope.ts +0 -5
- package/services/mac-bridge/codex-types/v2/ItemCompletedNotification.ts +0 -6
- package/services/mac-bridge/codex-types/v2/ItemStartedNotification.ts +0 -6
- package/services/mac-bridge/codex-types/v2/ListMcpServerStatusParams.ts +0 -13
- package/services/mac-bridge/codex-types/v2/ListMcpServerStatusResponse.ts +0 -11
- package/services/mac-bridge/codex-types/v2/LoginAccountParams.ts +0 -21
- package/services/mac-bridge/codex-types/v2/LoginAccountResponse.ts +0 -9
- package/services/mac-bridge/codex-types/v2/LogoutAccountResponse.ts +0 -5
- package/services/mac-bridge/codex-types/v2/McpAuthStatus.ts +0 -5
- package/services/mac-bridge/codex-types/v2/McpServerOauthLoginCompletedNotification.ts +0 -5
- package/services/mac-bridge/codex-types/v2/McpServerOauthLoginParams.ts +0 -5
- package/services/mac-bridge/codex-types/v2/McpServerOauthLoginResponse.ts +0 -5
- package/services/mac-bridge/codex-types/v2/McpServerRefreshResponse.ts +0 -5
- package/services/mac-bridge/codex-types/v2/McpServerStatus.ts +0 -9
- package/services/mac-bridge/codex-types/v2/McpToolCallError.ts +0 -5
- package/services/mac-bridge/codex-types/v2/McpToolCallProgressNotification.ts +0 -5
- package/services/mac-bridge/codex-types/v2/McpToolCallResult.ts +0 -6
- package/services/mac-bridge/codex-types/v2/McpToolCallStatus.ts +0 -5
- package/services/mac-bridge/codex-types/v2/MergeStrategy.ts +0 -5
- package/services/mac-bridge/codex-types/v2/Model.ts +0 -8
- package/services/mac-bridge/codex-types/v2/ModelListParams.ts +0 -17
- package/services/mac-bridge/codex-types/v2/ModelListResponse.ts +0 -11
- package/services/mac-bridge/codex-types/v2/ModelRerouteReason.ts +0 -5
- package/services/mac-bridge/codex-types/v2/ModelReroutedNotification.ts +0 -6
- package/services/mac-bridge/codex-types/v2/NetworkAccess.ts +0 -5
- package/services/mac-bridge/codex-types/v2/NetworkRequirements.ts +0 -5
- package/services/mac-bridge/codex-types/v2/OverriddenMetadata.ts +0 -7
- package/services/mac-bridge/codex-types/v2/PatchApplyStatus.ts +0 -5
- package/services/mac-bridge/codex-types/v2/PatchChangeKind.ts +0 -5
- package/services/mac-bridge/codex-types/v2/PlanDeltaNotification.ts +0 -9
- package/services/mac-bridge/codex-types/v2/ProductSurface.ts +0 -5
- package/services/mac-bridge/codex-types/v2/ProfileV2.ts +0 -11
- package/services/mac-bridge/codex-types/v2/RateLimitSnapshot.ts +0 -8
- package/services/mac-bridge/codex-types/v2/RateLimitWindow.ts +0 -5
- package/services/mac-bridge/codex-types/v2/RawResponseItemCompletedNotification.ts +0 -6
- package/services/mac-bridge/codex-types/v2/ReadOnlyAccess.ts +0 -6
- package/services/mac-bridge/codex-types/v2/ReasoningEffortOption.ts +0 -6
- package/services/mac-bridge/codex-types/v2/ReasoningSummaryPartAddedNotification.ts +0 -5
- package/services/mac-bridge/codex-types/v2/ReasoningSummaryTextDeltaNotification.ts +0 -5
- package/services/mac-bridge/codex-types/v2/ReasoningTextDeltaNotification.ts +0 -5
- package/services/mac-bridge/codex-types/v2/RemoteSkillSummary.ts +0 -5
- package/services/mac-bridge/codex-types/v2/ResidencyRequirement.ts +0 -5
- package/services/mac-bridge/codex-types/v2/ReviewDelivery.ts +0 -5
- package/services/mac-bridge/codex-types/v2/ReviewStartParams.ts +0 -12
- package/services/mac-bridge/codex-types/v2/ReviewStartResponse.ts +0 -13
- package/services/mac-bridge/codex-types/v2/ReviewTarget.ts +0 -9
- package/services/mac-bridge/codex-types/v2/SandboxMode.ts +0 -5
- package/services/mac-bridge/codex-types/v2/SandboxPolicy.ts +0 -8
- package/services/mac-bridge/codex-types/v2/SandboxWorkspaceWrite.ts +0 -5
- package/services/mac-bridge/codex-types/v2/SessionSource.ts +0 -6
- package/services/mac-bridge/codex-types/v2/SkillDependencies.ts +0 -6
- package/services/mac-bridge/codex-types/v2/SkillErrorInfo.ts +0 -5
- package/services/mac-bridge/codex-types/v2/SkillInterface.ts +0 -5
- package/services/mac-bridge/codex-types/v2/SkillMetadata.ts +0 -12
- package/services/mac-bridge/codex-types/v2/SkillScope.ts +0 -5
- package/services/mac-bridge/codex-types/v2/SkillToolDependency.ts +0 -5
- package/services/mac-bridge/codex-types/v2/SkillsConfigWriteParams.ts +0 -5
- package/services/mac-bridge/codex-types/v2/SkillsConfigWriteResponse.ts +0 -5
- package/services/mac-bridge/codex-types/v2/SkillsListEntry.ts +0 -7
- package/services/mac-bridge/codex-types/v2/SkillsListExtraRootsForCwd.ts +0 -5
- package/services/mac-bridge/codex-types/v2/SkillsListParams.ts +0 -18
- package/services/mac-bridge/codex-types/v2/SkillsListResponse.ts +0 -6
- package/services/mac-bridge/codex-types/v2/SkillsRemoteReadParams.ts +0 -7
- package/services/mac-bridge/codex-types/v2/SkillsRemoteReadResponse.ts +0 -6
- package/services/mac-bridge/codex-types/v2/SkillsRemoteWriteParams.ts +0 -5
- package/services/mac-bridge/codex-types/v2/SkillsRemoteWriteResponse.ts +0 -5
- package/services/mac-bridge/codex-types/v2/TerminalInteractionNotification.ts +0 -5
- package/services/mac-bridge/codex-types/v2/TextElement.ts +0 -14
- package/services/mac-bridge/codex-types/v2/TextPosition.ts +0 -13
- package/services/mac-bridge/codex-types/v2/TextRange.ts +0 -6
- package/services/mac-bridge/codex-types/v2/Thread.ts +0 -51
- package/services/mac-bridge/codex-types/v2/ThreadArchiveParams.ts +0 -5
- package/services/mac-bridge/codex-types/v2/ThreadArchiveResponse.ts +0 -5
- package/services/mac-bridge/codex-types/v2/ThreadArchivedNotification.ts +0 -5
- package/services/mac-bridge/codex-types/v2/ThreadCompactStartParams.ts +0 -5
- package/services/mac-bridge/codex-types/v2/ThreadCompactStartResponse.ts +0 -5
- package/services/mac-bridge/codex-types/v2/ThreadForkParams.ts +0 -28
- package/services/mac-bridge/codex-types/v2/ThreadForkResponse.ts +0 -9
- package/services/mac-bridge/codex-types/v2/ThreadItem.ts +0 -81
- package/services/mac-bridge/codex-types/v2/ThreadListParams.ts +0 -39
- package/services/mac-bridge/codex-types/v2/ThreadListResponse.ts +0 -11
- package/services/mac-bridge/codex-types/v2/ThreadLoadedListParams.ts +0 -13
- package/services/mac-bridge/codex-types/v2/ThreadLoadedListResponse.ts +0 -14
- package/services/mac-bridge/codex-types/v2/ThreadNameUpdatedNotification.ts +0 -5
- package/services/mac-bridge/codex-types/v2/ThreadReadParams.ts +0 -9
- package/services/mac-bridge/codex-types/v2/ThreadReadResponse.ts +0 -6
- package/services/mac-bridge/codex-types/v2/ThreadResumeParams.ts +0 -37
- package/services/mac-bridge/codex-types/v2/ThreadResumeResponse.ts +0 -9
- package/services/mac-bridge/codex-types/v2/ThreadRollbackParams.ts +0 -12
- package/services/mac-bridge/codex-types/v2/ThreadRollbackResponse.ts +0 -14
- package/services/mac-bridge/codex-types/v2/ThreadSetNameParams.ts +0 -5
- package/services/mac-bridge/codex-types/v2/ThreadSetNameResponse.ts +0 -5
- package/services/mac-bridge/codex-types/v2/ThreadSortKey.ts +0 -5
- package/services/mac-bridge/codex-types/v2/ThreadSourceKind.ts +0 -5
- package/services/mac-bridge/codex-types/v2/ThreadStartParams.ts +0 -17
- package/services/mac-bridge/codex-types/v2/ThreadStartResponse.ts +0 -9
- package/services/mac-bridge/codex-types/v2/ThreadStartedNotification.ts +0 -6
- package/services/mac-bridge/codex-types/v2/ThreadTokenUsage.ts +0 -6
- package/services/mac-bridge/codex-types/v2/ThreadTokenUsageUpdatedNotification.ts +0 -6
- package/services/mac-bridge/codex-types/v2/ThreadUnarchiveParams.ts +0 -5
- package/services/mac-bridge/codex-types/v2/ThreadUnarchiveResponse.ts +0 -6
- package/services/mac-bridge/codex-types/v2/ThreadUnarchivedNotification.ts +0 -5
- package/services/mac-bridge/codex-types/v2/TokenUsageBreakdown.ts +0 -5
- package/services/mac-bridge/codex-types/v2/ToolRequestUserInputAnswer.ts +0 -8
- package/services/mac-bridge/codex-types/v2/ToolRequestUserInputOption.ts +0 -8
- package/services/mac-bridge/codex-types/v2/ToolRequestUserInputParams.ts +0 -9
- package/services/mac-bridge/codex-types/v2/ToolRequestUserInputQuestion.ts +0 -9
- package/services/mac-bridge/codex-types/v2/ToolRequestUserInputResponse.ts +0 -9
- package/services/mac-bridge/codex-types/v2/ToolsV2.ts +0 -5
- package/services/mac-bridge/codex-types/v2/Turn.ts +0 -18
- package/services/mac-bridge/codex-types/v2/TurnCompletedNotification.ts +0 -6
- package/services/mac-bridge/codex-types/v2/TurnDiffUpdatedNotification.ts +0 -9
- package/services/mac-bridge/codex-types/v2/TurnError.ts +0 -6
- package/services/mac-bridge/codex-types/v2/TurnInterruptParams.ts +0 -5
- package/services/mac-bridge/codex-types/v2/TurnInterruptResponse.ts +0 -5
- package/services/mac-bridge/codex-types/v2/TurnPlanStep.ts +0 -6
- package/services/mac-bridge/codex-types/v2/TurnPlanStepStatus.ts +0 -5
- package/services/mac-bridge/codex-types/v2/TurnPlanUpdatedNotification.ts +0 -6
- package/services/mac-bridge/codex-types/v2/TurnStartParams.ts +0 -44
- package/services/mac-bridge/codex-types/v2/TurnStartResponse.ts +0 -6
- package/services/mac-bridge/codex-types/v2/TurnStartedNotification.ts +0 -6
- package/services/mac-bridge/codex-types/v2/TurnStatus.ts +0 -5
- package/services/mac-bridge/codex-types/v2/TurnSteerParams.ts +0 -11
- package/services/mac-bridge/codex-types/v2/TurnSteerResponse.ts +0 -5
- package/services/mac-bridge/codex-types/v2/UserInput.ts +0 -10
- package/services/mac-bridge/codex-types/v2/WebSearchAction.ts +0 -5
- package/services/mac-bridge/codex-types/v2/WindowsWorldWritableWarningNotification.ts +0 -5
- package/services/mac-bridge/codex-types/v2/WriteStatus.ts +0 -5
- package/services/mac-bridge/codex-types/v2/index.ts +0 -204
- package/services/mac-bridge/eslint.config.cjs +0 -22
- package/services/mac-bridge/package.json +0 -30
- package/services/mac-bridge/schema.ts +0 -0
- package/services/mac-bridge/src/index.ts +0 -18
- package/services/mac-bridge/src/server.ts +0 -426
- package/services/mac-bridge/src/services/__tests__/gitService.test.ts +0 -157
- package/services/mac-bridge/src/services/__tests__/realtimeHub.test.ts +0 -116
- package/services/mac-bridge/src/services/__tests__/terminalService.test.ts +0 -51
- package/services/mac-bridge/src/services/codexAppServerClient.ts +0 -507
- package/services/mac-bridge/src/services/codexCliAdapter.ts +0 -622
- package/services/mac-bridge/src/services/gitService.ts +0 -61
- package/services/mac-bridge/src/services/realtimeHub.ts +0 -25
- package/services/mac-bridge/src/services/terminalService.ts +0 -226
- package/services/mac-bridge/src/types.ts +0 -151
- package/services/mac-bridge/src/utils/__tests__/threadMapping.test.ts +0 -397
- package/services/mac-bridge/src/utils/threadMapping.ts +0 -176
- package/services/mac-bridge/tsconfig.json +0 -16
- package/services/mac-bridge/vitest.config.ts +0 -9
- package/services/rust-bridge/.env.example +0 -14
- package/services/rust-bridge/package.json +0 -13
- package/services/rust-bridge/security_best_practices_report.md +0 -24
- package/site/index.html +0 -54
- package/site/privacy/index.html +0 -80
- package/site/styles.css +0 -135
- package/site/support/index.html +0 -51
- package/site/terms/index.html +0 -68
- package/tsconfig.json +0 -4
|
@@ -1,1430 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
mapChat,
|
|
3
|
-
mapChatSummary,
|
|
4
|
-
readString,
|
|
5
|
-
toRecord,
|
|
6
|
-
type RawThread,
|
|
7
|
-
toRawThread,
|
|
8
|
-
} from './chatMapping';
|
|
9
|
-
import { readAccountSnapshot } from './account';
|
|
10
|
-
import { readAccountRateLimits as readSelectedAccountRateLimits } from './rateLimits';
|
|
11
|
-
import type {
|
|
12
|
-
AccountSnapshot,
|
|
13
|
-
AccountRateLimitSnapshot,
|
|
14
|
-
ApprovalPolicy,
|
|
15
|
-
ApprovalDecision,
|
|
16
|
-
CollaborationMode,
|
|
17
|
-
CreateChatRequest,
|
|
18
|
-
Chat,
|
|
19
|
-
ChatSummary,
|
|
20
|
-
GitCommitRequest,
|
|
21
|
-
GitCommitResponse,
|
|
22
|
-
GitDiffResponse,
|
|
23
|
-
GitFileRequest,
|
|
24
|
-
GitPushResponse,
|
|
25
|
-
GitStageAllResponse,
|
|
26
|
-
GitStageResponse,
|
|
27
|
-
GitStatusResponse,
|
|
28
|
-
GitUnstageAllResponse,
|
|
29
|
-
GitUnstageResponse,
|
|
30
|
-
PendingApproval,
|
|
31
|
-
ResolveApprovalResponse,
|
|
32
|
-
ResolveUserInputRequest,
|
|
33
|
-
ResolveUserInputResponse,
|
|
34
|
-
SendChatMessageRequest,
|
|
35
|
-
SteerChatTurnRequest,
|
|
36
|
-
MentionInput,
|
|
37
|
-
LocalImageInput,
|
|
38
|
-
UploadAttachmentRequest,
|
|
39
|
-
UploadAttachmentResponse,
|
|
40
|
-
VoiceTranscribeRequest,
|
|
41
|
-
VoiceTranscribeResponse,
|
|
42
|
-
ModelOption,
|
|
43
|
-
ReasoningEffort,
|
|
44
|
-
ModelReasoningEffortOption,
|
|
45
|
-
ServiceTier,
|
|
46
|
-
TerminalExecRequest,
|
|
47
|
-
TerminalExecResponse,
|
|
48
|
-
WorkspaceListResponse,
|
|
49
|
-
FileSystemListRequest,
|
|
50
|
-
FileSystemListResponse,
|
|
51
|
-
} from './types';
|
|
52
|
-
import type { HostBridgeWsClient } from './ws';
|
|
53
|
-
|
|
54
|
-
interface HealthResponse {
|
|
55
|
-
status: 'ok';
|
|
56
|
-
at: string;
|
|
57
|
-
uptimeSec: number;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
interface ApiClientOptions {
|
|
61
|
-
ws: HostBridgeWsClient;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
interface AppServerListResponse {
|
|
65
|
-
data?: unknown[];
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
interface AppServerLoadedThreadListResponse {
|
|
69
|
-
data?: unknown[];
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
interface AppServerReadResponse {
|
|
73
|
-
thread?: unknown;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
interface AppServerTurnResponse {
|
|
77
|
-
turn?: {
|
|
78
|
-
id?: string;
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
interface AppServerStartResponse {
|
|
83
|
-
thread?: {
|
|
84
|
-
id?: string;
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
interface AppServerForkResponse {
|
|
89
|
-
thread?: unknown;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
interface AppServerModelListResponse {
|
|
93
|
-
data?: unknown[];
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
interface AppServerConfigReadResponse {
|
|
97
|
-
config?: unknown;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
interface AppServerAccountReadResponse {
|
|
101
|
-
account?: unknown;
|
|
102
|
-
requiresOpenaiAuth?: boolean;
|
|
103
|
-
requires_openai_auth?: boolean;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
interface AppServerCollaborationMode {
|
|
107
|
-
mode: 'plan' | 'default';
|
|
108
|
-
settings: {
|
|
109
|
-
model: string;
|
|
110
|
-
reasoning_effort: ReasoningEffort | null;
|
|
111
|
-
developer_instructions: string | null;
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
interface AppServerThreadRuntimeSettings {
|
|
116
|
-
model: string | null;
|
|
117
|
-
effort: ReasoningEffort | null;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
type AppServerThreadSetNameResponse = Record<string, never>;
|
|
121
|
-
|
|
122
|
-
const CHAT_LIST_SOURCE_KINDS = ['cli', 'vscode', 'exec', 'appServer', 'unknown'] as const;
|
|
123
|
-
const CHAT_LIST_SOURCE_KINDS_WITH_SUBAGENTS = [
|
|
124
|
-
...CHAT_LIST_SOURCE_KINDS,
|
|
125
|
-
'subAgent',
|
|
126
|
-
'subAgentReview',
|
|
127
|
-
'subAgentCompact',
|
|
128
|
-
'subAgentThreadSpawn',
|
|
129
|
-
'subAgentOther',
|
|
130
|
-
] as const;
|
|
131
|
-
const MOBILE_DEVELOPER_INSTRUCTIONS =
|
|
132
|
-
'When you need clarification, call request_user_input instead of asking only in plain text. Provide 2-3 concise options whenever possible and use isOther when free-form input is appropriate.';
|
|
133
|
-
const MOBILE_DEFAULT_SANDBOX = 'danger-full-access';
|
|
134
|
-
|
|
135
|
-
interface ChatSnapshot {
|
|
136
|
-
rawThread: RawThread;
|
|
137
|
-
chat: Chat;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
interface TurnInputText {
|
|
141
|
-
type: 'text';
|
|
142
|
-
text: string;
|
|
143
|
-
text_elements: [];
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
interface TurnInputMention {
|
|
147
|
-
type: 'mention';
|
|
148
|
-
name: string;
|
|
149
|
-
path: string;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
interface TurnInputLocalImage {
|
|
153
|
-
type: 'localImage';
|
|
154
|
-
path: string;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
interface SendChatMessageOptions {
|
|
158
|
-
onTurnStarted?: (turnId: string) => void;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
interface ListChatsOptions {
|
|
162
|
-
includeSubAgents?: boolean;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
const ACTIVE_TURN_STATUSES = new Set([
|
|
166
|
-
'inprogress',
|
|
167
|
-
'in_progress',
|
|
168
|
-
'running',
|
|
169
|
-
'active',
|
|
170
|
-
'queued',
|
|
171
|
-
'pending',
|
|
172
|
-
]);
|
|
173
|
-
|
|
174
|
-
export class HostBridgeApiClient {
|
|
175
|
-
private readonly ws: HostBridgeWsClient;
|
|
176
|
-
private readonly renamedTitles = new Map<string, string>();
|
|
177
|
-
|
|
178
|
-
constructor(options: ApiClientOptions) {
|
|
179
|
-
this.ws = options.ws;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
health(): Promise<HealthResponse> {
|
|
183
|
-
return this.ws.request<HealthResponse>('bridge/health/read');
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
async readAccountRateLimits(): Promise<AccountRateLimitSnapshot | null> {
|
|
187
|
-
const response = await this.ws.request<Record<string, unknown>>('account/rateLimits/read');
|
|
188
|
-
return readSelectedAccountRateLimits(response);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
async readAccount(): Promise<AccountSnapshot> {
|
|
192
|
-
const response = await this.ws.request<AppServerAccountReadResponse>('account/read', {
|
|
193
|
-
refreshToken: false,
|
|
194
|
-
});
|
|
195
|
-
return readAccountSnapshot(response);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
async logoutAccount(): Promise<void> {
|
|
199
|
-
await this.ws.request('account/logout');
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
async listChats(options?: ListChatsOptions): Promise<ChatSummary[]> {
|
|
203
|
-
const includeSubAgents = options?.includeSubAgents === true;
|
|
204
|
-
const response = await this.ws.request<AppServerListResponse>('thread/list', {
|
|
205
|
-
cursor: null,
|
|
206
|
-
limit: 200,
|
|
207
|
-
sortKey: null,
|
|
208
|
-
modelProviders: null,
|
|
209
|
-
sourceKinds: includeSubAgents
|
|
210
|
-
? CHAT_LIST_SOURCE_KINDS_WITH_SUBAGENTS
|
|
211
|
-
: CHAT_LIST_SOURCE_KINDS,
|
|
212
|
-
archived: false,
|
|
213
|
-
cwd: null,
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
const listRaw = Array.isArray(response.data) ? response.data : [];
|
|
217
|
-
|
|
218
|
-
return listRaw
|
|
219
|
-
.map((item) => {
|
|
220
|
-
const rawThread = toRawThread(item);
|
|
221
|
-
if (rawThread.id && rawThread.name?.trim()) {
|
|
222
|
-
this.renamedTitles.set(rawThread.id, rawThread.name.trim());
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
const mapped = mapChatSummary(rawThread);
|
|
226
|
-
if (!mapped) {
|
|
227
|
-
return null;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
const cachedTitle = this.renamedTitles.get(mapped.id);
|
|
231
|
-
if (cachedTitle) {
|
|
232
|
-
return {
|
|
233
|
-
...mapped,
|
|
234
|
-
title: cachedTitle,
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
return mapped;
|
|
239
|
-
})
|
|
240
|
-
.filter((item): item is ChatSummary => item !== null)
|
|
241
|
-
.filter((item) => includeSubAgents || !isSubAgentSource(item.sourceKind))
|
|
242
|
-
.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
async listLoadedChatIds(): Promise<string[]> {
|
|
246
|
-
const response = await this.ws.request<AppServerLoadedThreadListResponse>(
|
|
247
|
-
'thread/loaded/list',
|
|
248
|
-
undefined
|
|
249
|
-
);
|
|
250
|
-
const ids = Array.isArray(response.data) ? response.data : [];
|
|
251
|
-
return ids
|
|
252
|
-
.map((value) => readString(value)?.trim() ?? '')
|
|
253
|
-
.filter((value): value is string => value.length > 0);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
async listWorkspaceRoots(limit = 200): Promise<WorkspaceListResponse> {
|
|
257
|
-
const response = await this.ws.request<Record<string, unknown>>('bridge/workspaces/list', {
|
|
258
|
-
limit,
|
|
259
|
-
});
|
|
260
|
-
return readWorkspaceListResponse(response);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
async listFilesystemEntries(
|
|
264
|
-
request?: FileSystemListRequest
|
|
265
|
-
): Promise<FileSystemListResponse> {
|
|
266
|
-
const response = await this.ws.request<Record<string, unknown>>('bridge/fs/list', {
|
|
267
|
-
path: normalizeCwd(request?.path) ?? null,
|
|
268
|
-
includeHidden: request?.includeHidden === true,
|
|
269
|
-
directoriesOnly: request?.directoriesOnly !== false,
|
|
270
|
-
});
|
|
271
|
-
return readFileSystemListResponse(response);
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
async createChat(body: CreateChatRequest): Promise<Chat> {
|
|
275
|
-
const requestedCwd = normalizeCwd(body.cwd);
|
|
276
|
-
const requestedModel = normalizeModel(body.model);
|
|
277
|
-
const requestedEffort = normalizeEffort(body.effort);
|
|
278
|
-
const requestedServiceTier = normalizeServiceTier(body.serviceTier);
|
|
279
|
-
const requestedApprovalPolicy = normalizeApprovalPolicy(body.approvalPolicy) ?? 'untrusted';
|
|
280
|
-
const started = await this.ws.request<AppServerStartResponse>('thread/start', {
|
|
281
|
-
model: requestedModel ?? null,
|
|
282
|
-
modelProvider: null,
|
|
283
|
-
cwd: requestedCwd ?? null,
|
|
284
|
-
approvalPolicy: requestedApprovalPolicy,
|
|
285
|
-
sandbox: MOBILE_DEFAULT_SANDBOX,
|
|
286
|
-
config: toThreadConfig(requestedServiceTier),
|
|
287
|
-
baseInstructions: null,
|
|
288
|
-
developerInstructions: MOBILE_DEVELOPER_INSTRUCTIONS,
|
|
289
|
-
personality: null,
|
|
290
|
-
ephemeral: null,
|
|
291
|
-
experimentalRawEvents: true,
|
|
292
|
-
persistExtendedHistory: true,
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
const chatId = started.thread?.id;
|
|
296
|
-
if (!chatId) {
|
|
297
|
-
throw new Error('thread/start did not return a chat id');
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
const initialPrompt = body.message?.trim();
|
|
301
|
-
if (initialPrompt) {
|
|
302
|
-
return this.sendChatMessage(chatId, {
|
|
303
|
-
content: initialPrompt,
|
|
304
|
-
role: 'user',
|
|
305
|
-
cwd: requestedCwd ?? undefined,
|
|
306
|
-
model: requestedModel ?? undefined,
|
|
307
|
-
effort: requestedEffort ?? undefined,
|
|
308
|
-
approvalPolicy: requestedApprovalPolicy,
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
if (started.thread) {
|
|
313
|
-
return this.mapChatWithCachedTitle(started.thread);
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
return this.getChat(chatId);
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
async getChat(id: string): Promise<Chat> {
|
|
320
|
-
const snapshot = await this.readChatSnapshot(id);
|
|
321
|
-
return snapshot.chat;
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
async getChatSummary(id: string): Promise<ChatSummary> {
|
|
325
|
-
const response = await this.ws.request<AppServerReadResponse>('thread/read', {
|
|
326
|
-
threadId: id,
|
|
327
|
-
includeTurns: false,
|
|
328
|
-
});
|
|
329
|
-
const rawThread = toRawThread(response.thread);
|
|
330
|
-
if (rawThread.id && rawThread.name?.trim()) {
|
|
331
|
-
this.renamedTitles.set(rawThread.id, rawThread.name.trim());
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
const mapped = mapChatSummary(rawThread);
|
|
335
|
-
if (!mapped) {
|
|
336
|
-
throw new Error('chat id missing in app-server response');
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
const cachedTitle = this.renamedTitles.get(mapped.id);
|
|
340
|
-
if (!cachedTitle) {
|
|
341
|
-
return mapped;
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
return {
|
|
345
|
-
...mapped,
|
|
346
|
-
title: cachedTitle,
|
|
347
|
-
};
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
async renameChat(id: string, name: string): Promise<Chat> {
|
|
351
|
-
const trimmedName = name.trim();
|
|
352
|
-
if (!trimmedName) {
|
|
353
|
-
throw new Error('Chat name cannot be empty');
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
await this.trySetThreadName(id, {
|
|
357
|
-
threadId: id,
|
|
358
|
-
name: trimmedName,
|
|
359
|
-
});
|
|
360
|
-
await this.trySetThreadName(id, {
|
|
361
|
-
threadId: id,
|
|
362
|
-
threadName: trimmedName,
|
|
363
|
-
});
|
|
364
|
-
|
|
365
|
-
this.renamedTitles.set(id, trimmedName);
|
|
366
|
-
const updated = await this.getChat(id);
|
|
367
|
-
|
|
368
|
-
return {
|
|
369
|
-
...updated,
|
|
370
|
-
title: trimmedName,
|
|
371
|
-
};
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
async setChatWorkspace(id: string, cwd: string): Promise<Chat> {
|
|
375
|
-
const normalizedCwd = normalizeCwd(cwd);
|
|
376
|
-
if (!normalizedCwd) {
|
|
377
|
-
throw new Error('Workspace path cannot be empty');
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
await this.resumeThread(id, {
|
|
381
|
-
cwd: normalizedCwd,
|
|
382
|
-
});
|
|
383
|
-
|
|
384
|
-
const updated = await this.getChat(id);
|
|
385
|
-
if (updated.cwd === normalizedCwd) {
|
|
386
|
-
return updated;
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
return {
|
|
390
|
-
...updated,
|
|
391
|
-
cwd: normalizedCwd,
|
|
392
|
-
};
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
async resumeThread(
|
|
396
|
-
id: string,
|
|
397
|
-
options?: {
|
|
398
|
-
cwd?: string | null;
|
|
399
|
-
model?: string | null;
|
|
400
|
-
approvalPolicy?: ApprovalPolicy | null;
|
|
401
|
-
}
|
|
402
|
-
): Promise<AppServerThreadRuntimeSettings> {
|
|
403
|
-
const threadId = id.trim();
|
|
404
|
-
if (!threadId) {
|
|
405
|
-
throw new Error('thread id is required');
|
|
406
|
-
}
|
|
407
|
-
const requestedApprovalPolicy =
|
|
408
|
-
normalizeApprovalPolicy(options?.approvalPolicy) ?? 'untrusted';
|
|
409
|
-
const fallbackApprovalPolicy =
|
|
410
|
-
requestedApprovalPolicy === 'never' ? 'never' : 'on-request';
|
|
411
|
-
|
|
412
|
-
const primaryRequest = {
|
|
413
|
-
threadId,
|
|
414
|
-
history: null,
|
|
415
|
-
path: null,
|
|
416
|
-
model: normalizeModel(options?.model) ?? null,
|
|
417
|
-
modelProvider: null,
|
|
418
|
-
cwd: normalizeCwd(options?.cwd) ?? null,
|
|
419
|
-
approvalPolicy: requestedApprovalPolicy,
|
|
420
|
-
sandbox: MOBILE_DEFAULT_SANDBOX,
|
|
421
|
-
config: null,
|
|
422
|
-
baseInstructions: null,
|
|
423
|
-
developerInstructions: MOBILE_DEVELOPER_INSTRUCTIONS,
|
|
424
|
-
personality: null,
|
|
425
|
-
experimentalRawEvents: true,
|
|
426
|
-
persistExtendedHistory: true,
|
|
427
|
-
};
|
|
428
|
-
|
|
429
|
-
try {
|
|
430
|
-
const response = await this.ws.request<Record<string, unknown>>(
|
|
431
|
-
'thread/resume',
|
|
432
|
-
primaryRequest
|
|
433
|
-
);
|
|
434
|
-
return readThreadRuntimeSettings(response);
|
|
435
|
-
} catch (primaryError) {
|
|
436
|
-
// First fallback: keep raw-event streaming enabled, but relax approval policy.
|
|
437
|
-
const compatibilityRequest = {
|
|
438
|
-
...primaryRequest,
|
|
439
|
-
approvalPolicy: fallbackApprovalPolicy,
|
|
440
|
-
};
|
|
441
|
-
try {
|
|
442
|
-
const response = await this.ws.request<Record<string, unknown>>(
|
|
443
|
-
'thread/resume',
|
|
444
|
-
compatibilityRequest
|
|
445
|
-
);
|
|
446
|
-
return readThreadRuntimeSettings(response);
|
|
447
|
-
} catch (compatibilityError) {
|
|
448
|
-
// Final compatibility fallback for older app-server builds that reject
|
|
449
|
-
// experimentalRawEvents/developerInstructions on resume.
|
|
450
|
-
const legacyRequest = {
|
|
451
|
-
...compatibilityRequest,
|
|
452
|
-
developerInstructions: null,
|
|
453
|
-
};
|
|
454
|
-
delete (legacyRequest as { experimentalRawEvents?: boolean }).experimentalRawEvents;
|
|
455
|
-
try {
|
|
456
|
-
const response = await this.ws.request<Record<string, unknown>>(
|
|
457
|
-
'thread/resume',
|
|
458
|
-
legacyRequest
|
|
459
|
-
);
|
|
460
|
-
return readThreadRuntimeSettings(response);
|
|
461
|
-
} catch (legacyError) {
|
|
462
|
-
throw new Error(
|
|
463
|
-
`thread/resume failed: ${(primaryError as Error).message}; compatibility failed: ${(compatibilityError as Error).message}; legacy fallback failed: ${(legacyError as Error).message}`
|
|
464
|
-
);
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
async sendChatMessage(
|
|
471
|
-
id: string,
|
|
472
|
-
body: SendChatMessageRequest,
|
|
473
|
-
options?: SendChatMessageOptions
|
|
474
|
-
): Promise<Chat> {
|
|
475
|
-
const content = body.content.trim();
|
|
476
|
-
if (!content) {
|
|
477
|
-
return this.getChat(id);
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
if ((body.role ?? 'user') !== 'user') {
|
|
481
|
-
throw new Error('Only user role is supported in bridge/chat messaging');
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
const normalizedCwd = normalizeCwd(body.cwd);
|
|
485
|
-
const normalizedModel = normalizeModel(body.model);
|
|
486
|
-
const normalizedEffort = normalizeEffort(body.effort);
|
|
487
|
-
const normalizedServiceTier = normalizeServiceTier(body.serviceTier);
|
|
488
|
-
const normalizedApprovalPolicy = normalizeApprovalPolicy(body.approvalPolicy);
|
|
489
|
-
const normalizedMentions = normalizeMentions(body.mentions);
|
|
490
|
-
const normalizedLocalImages = normalizeLocalImages(body.localImages);
|
|
491
|
-
const requestedCollaborationMode = normalizeCollaborationMode(body.collaborationMode);
|
|
492
|
-
let resumedThreadSettings: AppServerThreadRuntimeSettings | null = null;
|
|
493
|
-
|
|
494
|
-
try {
|
|
495
|
-
resumedThreadSettings = await this.resumeThread(id, {
|
|
496
|
-
model: normalizedModel,
|
|
497
|
-
cwd: normalizedCwd,
|
|
498
|
-
approvalPolicy: normalizedApprovalPolicy,
|
|
499
|
-
});
|
|
500
|
-
} catch {
|
|
501
|
-
// Best effort: turn/start still works for recently started chats.
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
let effectiveModel = normalizedModel ?? resumedThreadSettings?.model ?? null;
|
|
505
|
-
if (requestedCollaborationMode && !effectiveModel) {
|
|
506
|
-
try {
|
|
507
|
-
const models = await this.listModels(false);
|
|
508
|
-
effectiveModel =
|
|
509
|
-
models.find((entry) => entry.isDefault)?.id ?? models[0]?.id ?? null;
|
|
510
|
-
} catch {
|
|
511
|
-
// Best effort: fall back to the current thread settings if model lookup fails.
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
const effectiveEffort =
|
|
515
|
-
requestedCollaborationMode
|
|
516
|
-
? normalizedEffort ?? resumedThreadSettings?.effort ?? null
|
|
517
|
-
: normalizedEffort;
|
|
518
|
-
const normalizedCollaborationMode = toTurnCollaborationMode(
|
|
519
|
-
requestedCollaborationMode,
|
|
520
|
-
effectiveModel,
|
|
521
|
-
effectiveEffort
|
|
522
|
-
);
|
|
523
|
-
|
|
524
|
-
const turnStart = await this.ws.request<AppServerTurnResponse>('turn/start', {
|
|
525
|
-
threadId: id,
|
|
526
|
-
input: buildTurnInput(content, normalizedMentions, normalizedLocalImages),
|
|
527
|
-
cwd: normalizedCwd ?? null,
|
|
528
|
-
approvalPolicy: normalizedApprovalPolicy ?? null,
|
|
529
|
-
sandboxPolicy: null,
|
|
530
|
-
model: effectiveModel ?? null,
|
|
531
|
-
effort: effectiveEffort ?? null,
|
|
532
|
-
serviceTier: normalizedServiceTier ?? null,
|
|
533
|
-
summary: null,
|
|
534
|
-
personality: null,
|
|
535
|
-
outputSchema: null,
|
|
536
|
-
collaborationMode: normalizedCollaborationMode,
|
|
537
|
-
});
|
|
538
|
-
|
|
539
|
-
const turnId = turnStart.turn?.id;
|
|
540
|
-
if (!turnId) {
|
|
541
|
-
throw new Error('turn/start did not return turn id');
|
|
542
|
-
}
|
|
543
|
-
options?.onTurnStarted?.(turnId);
|
|
544
|
-
return this.getChatWithUserMessage(id, turnId, content);
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
async steerChatTurn(
|
|
548
|
-
threadId: string,
|
|
549
|
-
expectedTurnId: string,
|
|
550
|
-
body: SteerChatTurnRequest
|
|
551
|
-
): Promise<void> {
|
|
552
|
-
const normalizedThreadId = threadId.trim();
|
|
553
|
-
const normalizedExpectedTurnId = expectedTurnId.trim();
|
|
554
|
-
const content = body.content.trim();
|
|
555
|
-
if (!normalizedThreadId || !normalizedExpectedTurnId || !content) {
|
|
556
|
-
return;
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
const normalizedMentions = normalizeMentions(body.mentions);
|
|
560
|
-
const normalizedLocalImages = normalizeLocalImages(body.localImages);
|
|
561
|
-
|
|
562
|
-
await this.ws.request<Record<string, never>>('turn/steer', {
|
|
563
|
-
threadId: normalizedThreadId,
|
|
564
|
-
expectedTurnId: normalizedExpectedTurnId,
|
|
565
|
-
input: buildTurnInput(content, normalizedMentions, normalizedLocalImages),
|
|
566
|
-
});
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
async interruptTurn(threadId: string, turnId: string): Promise<void> {
|
|
570
|
-
const normalizedThreadId = threadId.trim();
|
|
571
|
-
const normalizedTurnId = turnId.trim();
|
|
572
|
-
if (!normalizedThreadId || !normalizedTurnId) {
|
|
573
|
-
throw new Error('threadId and turnId are required to interrupt a turn');
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
await this.ws.request<Record<string, never>>('turn/interrupt', {
|
|
577
|
-
threadId: normalizedThreadId,
|
|
578
|
-
turnId: normalizedTurnId,
|
|
579
|
-
});
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
async interruptLatestTurn(threadId: string): Promise<string | null> {
|
|
583
|
-
const normalizedThreadId = threadId.trim();
|
|
584
|
-
if (!normalizedThreadId) {
|
|
585
|
-
throw new Error('threadId is required to interrupt the active turn');
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
const snapshot = await this.readChatSnapshot(normalizedThreadId);
|
|
589
|
-
const turns = Array.isArray(snapshot.rawThread.turns) ? snapshot.rawThread.turns : [];
|
|
590
|
-
for (let i = turns.length - 1; i >= 0; i -= 1) {
|
|
591
|
-
const turn = turns[i];
|
|
592
|
-
const turnId = readString(turn.id);
|
|
593
|
-
const status = normalizeTurnStatus(readString(turn.status));
|
|
594
|
-
if (!turnId || !status || !ACTIVE_TURN_STATUSES.has(status)) {
|
|
595
|
-
continue;
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
await this.interruptTurn(normalizedThreadId, turnId);
|
|
599
|
-
return turnId;
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
return null;
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
uploadAttachment(body: UploadAttachmentRequest): Promise<UploadAttachmentResponse> {
|
|
606
|
-
return this.ws.request<UploadAttachmentResponse>('bridge/attachments/upload', body);
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
transcribeVoice(body: VoiceTranscribeRequest): Promise<VoiceTranscribeResponse> {
|
|
610
|
-
return this.ws.request<VoiceTranscribeResponse>('bridge/voice/transcribe', body);
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
async listModels(includeHidden = false): Promise<ModelOption[]> {
|
|
614
|
-
const response = await this.ws.request<AppServerModelListResponse>('model/list', {
|
|
615
|
-
cursor: null,
|
|
616
|
-
limit: 200,
|
|
617
|
-
includeHidden,
|
|
618
|
-
});
|
|
619
|
-
|
|
620
|
-
const rawList = Array.isArray(response.data) ? response.data : [];
|
|
621
|
-
const models: ModelOption[] = [];
|
|
622
|
-
|
|
623
|
-
for (const item of rawList) {
|
|
624
|
-
const record = toRecord(item);
|
|
625
|
-
if (!record) {
|
|
626
|
-
continue;
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
const id = readString(record.id) ?? readString(record.model);
|
|
630
|
-
if (!id) {
|
|
631
|
-
continue;
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
const displayName = readString(record.displayName) ?? id;
|
|
635
|
-
const description = readString(record.description) ?? undefined;
|
|
636
|
-
const hidden = typeof record.hidden === 'boolean' ? record.hidden : undefined;
|
|
637
|
-
const supportsPersonality =
|
|
638
|
-
typeof record.supportsPersonality === 'boolean'
|
|
639
|
-
? record.supportsPersonality
|
|
640
|
-
: undefined;
|
|
641
|
-
const isDefault =
|
|
642
|
-
typeof record.isDefault === 'boolean' ? record.isDefault : undefined;
|
|
643
|
-
const defaultReasoningEffort = normalizeEffort(
|
|
644
|
-
readString(record.defaultReasoningEffort) ?? readString(record.reasoningEffort)
|
|
645
|
-
);
|
|
646
|
-
const reasoningEffort = toReasoningEffortOptions(
|
|
647
|
-
record.supportedReasoningEfforts ?? record.reasoningEffort
|
|
648
|
-
);
|
|
649
|
-
|
|
650
|
-
models.push({
|
|
651
|
-
id,
|
|
652
|
-
displayName,
|
|
653
|
-
description,
|
|
654
|
-
hidden,
|
|
655
|
-
supportsPersonality,
|
|
656
|
-
isDefault,
|
|
657
|
-
defaultReasoningEffort: defaultReasoningEffort ?? undefined,
|
|
658
|
-
reasoningEffort: reasoningEffort.length > 0 ? reasoningEffort : undefined,
|
|
659
|
-
});
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
return models;
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
async compactChat(id: string): Promise<void> {
|
|
666
|
-
await this.ws.request('thread/compact/start', {
|
|
667
|
-
threadId: id,
|
|
668
|
-
});
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
async reviewChat(id: string): Promise<void> {
|
|
672
|
-
await this.ws.request('review/start', {
|
|
673
|
-
threadId: id,
|
|
674
|
-
target: {
|
|
675
|
-
type: 'uncommittedChanges',
|
|
676
|
-
},
|
|
677
|
-
delivery: 'inline',
|
|
678
|
-
});
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
async forkChat(
|
|
682
|
-
id: string,
|
|
683
|
-
options?: {
|
|
684
|
-
cwd?: string;
|
|
685
|
-
model?: string;
|
|
686
|
-
serviceTier?: ServiceTier;
|
|
687
|
-
approvalPolicy?: ApprovalPolicy | null;
|
|
688
|
-
}
|
|
689
|
-
): Promise<Chat> {
|
|
690
|
-
const requestedApprovalPolicy =
|
|
691
|
-
normalizeApprovalPolicy(options?.approvalPolicy) ?? 'untrusted';
|
|
692
|
-
const requestedServiceTier = normalizeServiceTier(options?.serviceTier);
|
|
693
|
-
const response = await this.ws.request<AppServerForkResponse>('thread/fork', {
|
|
694
|
-
threadId: id,
|
|
695
|
-
path: null,
|
|
696
|
-
model: normalizeModel(options?.model) ?? null,
|
|
697
|
-
modelProvider: null,
|
|
698
|
-
cwd: normalizeCwd(options?.cwd) ?? null,
|
|
699
|
-
approvalPolicy: requestedApprovalPolicy,
|
|
700
|
-
sandbox: MOBILE_DEFAULT_SANDBOX,
|
|
701
|
-
config: toThreadConfig(requestedServiceTier),
|
|
702
|
-
baseInstructions: null,
|
|
703
|
-
developerInstructions: MOBILE_DEVELOPER_INSTRUCTIONS,
|
|
704
|
-
persistExtendedHistory: true,
|
|
705
|
-
});
|
|
706
|
-
|
|
707
|
-
if (response.thread) {
|
|
708
|
-
return this.mapChatWithCachedTitle(response.thread);
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
throw new Error('thread/fork did not return a chat payload');
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
async readServiceTierPreference(): Promise<ServiceTier | null> {
|
|
715
|
-
const response = await this.ws.request<AppServerConfigReadResponse>('config/read', {
|
|
716
|
-
includeLayers: false,
|
|
717
|
-
cwd: null,
|
|
718
|
-
});
|
|
719
|
-
const config = toRecord(response.config);
|
|
720
|
-
return normalizeServiceTier(readString(config?.service_tier));
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
listApprovals(): Promise<PendingApproval[]> {
|
|
724
|
-
return this.ws.request<PendingApproval[]>('bridge/approvals/list');
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
resolveApproval(id: string, decision: ApprovalDecision): Promise<ResolveApprovalResponse> {
|
|
728
|
-
return this.ws.request<ResolveApprovalResponse>('bridge/approvals/resolve', {
|
|
729
|
-
id,
|
|
730
|
-
decision,
|
|
731
|
-
});
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
resolveUserInput(
|
|
735
|
-
id: string,
|
|
736
|
-
body: ResolveUserInputRequest
|
|
737
|
-
): Promise<ResolveUserInputResponse> {
|
|
738
|
-
return this.ws.request<ResolveUserInputResponse>('bridge/userInput/resolve', {
|
|
739
|
-
id,
|
|
740
|
-
answers: body.answers,
|
|
741
|
-
});
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
execTerminal(body: TerminalExecRequest): Promise<TerminalExecResponse> {
|
|
745
|
-
return this.ws.request<TerminalExecResponse>('bridge/terminal/exec', body);
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
gitStatus(cwd?: string): Promise<GitStatusResponse> {
|
|
749
|
-
const normalizedCwd = normalizeCwd(cwd);
|
|
750
|
-
return this.ws.request<GitStatusResponse>('bridge/git/status', {
|
|
751
|
-
cwd: normalizedCwd ?? null,
|
|
752
|
-
});
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
gitDiff(cwd?: string): Promise<GitDiffResponse> {
|
|
756
|
-
const normalizedCwd = normalizeCwd(cwd);
|
|
757
|
-
return this.ws.request<GitDiffResponse>('bridge/git/diff', {
|
|
758
|
-
cwd: normalizedCwd ?? null,
|
|
759
|
-
});
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
gitStage(body: GitFileRequest): Promise<GitStageResponse> {
|
|
763
|
-
const path = body.path.trim();
|
|
764
|
-
if (!path) {
|
|
765
|
-
return Promise.reject(new Error('path must not be empty'));
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
return this.ws.request<GitStageResponse>('bridge/git/stage', {
|
|
769
|
-
path,
|
|
770
|
-
cwd: normalizeCwd(body.cwd) ?? null,
|
|
771
|
-
});
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
gitStageAll(cwd?: string): Promise<GitStageAllResponse> {
|
|
775
|
-
const normalizedCwd = normalizeCwd(cwd);
|
|
776
|
-
return this.ws.request<GitStageAllResponse>('bridge/git/stageAll', {
|
|
777
|
-
cwd: normalizedCwd ?? null,
|
|
778
|
-
});
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
gitUnstage(body: GitFileRequest): Promise<GitUnstageResponse> {
|
|
782
|
-
const path = body.path.trim();
|
|
783
|
-
if (!path) {
|
|
784
|
-
return Promise.reject(new Error('path must not be empty'));
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
return this.ws.request<GitUnstageResponse>('bridge/git/unstage', {
|
|
788
|
-
path,
|
|
789
|
-
cwd: normalizeCwd(body.cwd) ?? null,
|
|
790
|
-
});
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
gitUnstageAll(cwd?: string): Promise<GitUnstageAllResponse> {
|
|
794
|
-
const normalizedCwd = normalizeCwd(cwd);
|
|
795
|
-
return this.ws.request<GitUnstageAllResponse>('bridge/git/unstageAll', {
|
|
796
|
-
cwd: normalizedCwd ?? null,
|
|
797
|
-
});
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
gitCommit(body: GitCommitRequest): Promise<GitCommitResponse> {
|
|
801
|
-
return this.ws.request<GitCommitResponse>('bridge/git/commit', {
|
|
802
|
-
...body,
|
|
803
|
-
cwd: normalizeCwd(body.cwd) ?? null,
|
|
804
|
-
});
|
|
805
|
-
}
|
|
806
|
-
|
|
807
|
-
gitPush(cwd?: string): Promise<GitPushResponse> {
|
|
808
|
-
const normalizedCwd = normalizeCwd(cwd);
|
|
809
|
-
return this.ws.request<GitPushResponse>('bridge/git/push', {
|
|
810
|
-
cwd: normalizedCwd ?? null,
|
|
811
|
-
});
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
private mapChatWithCachedTitle(rawThreadValue: unknown): Chat {
|
|
815
|
-
const rawThread = toRawThread(rawThreadValue);
|
|
816
|
-
if (rawThread.id && rawThread.name?.trim()) {
|
|
817
|
-
this.renamedTitles.set(rawThread.id, rawThread.name.trim());
|
|
818
|
-
}
|
|
819
|
-
|
|
820
|
-
const mapped = mapChat(rawThread);
|
|
821
|
-
const cachedTitle = this.renamedTitles.get(mapped.id);
|
|
822
|
-
if (!cachedTitle) {
|
|
823
|
-
return mapped;
|
|
824
|
-
}
|
|
825
|
-
|
|
826
|
-
return {
|
|
827
|
-
...mapped,
|
|
828
|
-
title: cachedTitle,
|
|
829
|
-
};
|
|
830
|
-
}
|
|
831
|
-
|
|
832
|
-
private async trySetThreadName(
|
|
833
|
-
threadId: string,
|
|
834
|
-
payload: Record<string, unknown>
|
|
835
|
-
): Promise<void> {
|
|
836
|
-
try {
|
|
837
|
-
await this.ws.request<AppServerThreadSetNameResponse>('thread/name/set', payload);
|
|
838
|
-
} catch (error) {
|
|
839
|
-
const message = String((error as Error).message ?? error);
|
|
840
|
-
const expectedFieldMismatch =
|
|
841
|
-
message.includes('threadName') ||
|
|
842
|
-
message.includes('name') ||
|
|
843
|
-
message.includes('missing field') ||
|
|
844
|
-
message.includes('unknown field');
|
|
845
|
-
|
|
846
|
-
if (!expectedFieldMismatch) {
|
|
847
|
-
throw error;
|
|
848
|
-
}
|
|
849
|
-
|
|
850
|
-
const triedThreadName = Object.prototype.hasOwnProperty.call(payload, 'threadName');
|
|
851
|
-
const nameValue = readString(payload.threadName) ?? readString(payload.name);
|
|
852
|
-
if (!nameValue) {
|
|
853
|
-
throw error;
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
const fallbackPayload = triedThreadName
|
|
857
|
-
? {
|
|
858
|
-
threadId,
|
|
859
|
-
name: nameValue,
|
|
860
|
-
}
|
|
861
|
-
: {
|
|
862
|
-
threadId,
|
|
863
|
-
threadName: nameValue,
|
|
864
|
-
};
|
|
865
|
-
|
|
866
|
-
await this.ws.request<AppServerThreadSetNameResponse>('thread/name/set', fallbackPayload);
|
|
867
|
-
}
|
|
868
|
-
}
|
|
869
|
-
|
|
870
|
-
private async readChatSnapshot(id: string): Promise<ChatSnapshot> {
|
|
871
|
-
try {
|
|
872
|
-
const response = await this.ws.request<AppServerReadResponse>('thread/read', {
|
|
873
|
-
threadId: id,
|
|
874
|
-
includeTurns: true,
|
|
875
|
-
});
|
|
876
|
-
const rawThread = toRawThread(response.thread);
|
|
877
|
-
return {
|
|
878
|
-
rawThread,
|
|
879
|
-
chat: this.mapChatWithCachedTitle(rawThread),
|
|
880
|
-
};
|
|
881
|
-
} catch (error) {
|
|
882
|
-
if (!isMaterializationGapError(error)) {
|
|
883
|
-
throw error;
|
|
884
|
-
}
|
|
885
|
-
|
|
886
|
-
const response = await this.ws.request<AppServerReadResponse>('thread/read', {
|
|
887
|
-
threadId: id,
|
|
888
|
-
includeTurns: false,
|
|
889
|
-
});
|
|
890
|
-
const rawThread = toRawThread(response.thread);
|
|
891
|
-
return {
|
|
892
|
-
rawThread,
|
|
893
|
-
chat: this.mapChatWithCachedTitle(rawThread),
|
|
894
|
-
};
|
|
895
|
-
}
|
|
896
|
-
}
|
|
897
|
-
|
|
898
|
-
private async getChatWithUserMessage(
|
|
899
|
-
id: string,
|
|
900
|
-
turnId: string,
|
|
901
|
-
content: string
|
|
902
|
-
): Promise<Chat> {
|
|
903
|
-
const normalizedContent = content.trim();
|
|
904
|
-
let latestSnapshot = await this.readChatSnapshot(id);
|
|
905
|
-
let latest = latestSnapshot.chat;
|
|
906
|
-
|
|
907
|
-
if (!normalizedContent) {
|
|
908
|
-
return latest;
|
|
909
|
-
}
|
|
910
|
-
|
|
911
|
-
const hasMatchingTurnMessage = rawThreadHasTurnUserMessage(
|
|
912
|
-
latestSnapshot.rawThread,
|
|
913
|
-
turnId,
|
|
914
|
-
normalizedContent
|
|
915
|
-
);
|
|
916
|
-
const hasFallbackRecentMessage =
|
|
917
|
-
!rawThreadHasTurns(latestSnapshot.rawThread) &&
|
|
918
|
-
chatHasRecentUserMessage(latest, normalizedContent);
|
|
919
|
-
if (hasMatchingTurnMessage || hasFallbackRecentMessage) {
|
|
920
|
-
return latest;
|
|
921
|
-
}
|
|
922
|
-
|
|
923
|
-
const retryDelaysMs = [150, 300, 500, 800];
|
|
924
|
-
for (const delayMs of retryDelaysMs) {
|
|
925
|
-
await sleep(delayMs);
|
|
926
|
-
latestSnapshot = await this.readChatSnapshot(id);
|
|
927
|
-
latest = latestSnapshot.chat;
|
|
928
|
-
|
|
929
|
-
const matchedAfterRetry = rawThreadHasTurnUserMessage(
|
|
930
|
-
latestSnapshot.rawThread,
|
|
931
|
-
turnId,
|
|
932
|
-
normalizedContent
|
|
933
|
-
);
|
|
934
|
-
const matchedByFallback =
|
|
935
|
-
!rawThreadHasTurns(latestSnapshot.rawThread) &&
|
|
936
|
-
chatHasRecentUserMessage(latest, normalizedContent);
|
|
937
|
-
if (matchedAfterRetry || matchedByFallback) {
|
|
938
|
-
return latest;
|
|
939
|
-
}
|
|
940
|
-
}
|
|
941
|
-
|
|
942
|
-
return appendSyntheticUserMessage(latest, normalizedContent);
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
|
|
946
|
-
function isSubAgentSource(sourceKind: string | undefined): boolean {
|
|
947
|
-
return typeof sourceKind === 'string' && sourceKind.startsWith('subAgent');
|
|
948
|
-
}
|
|
949
|
-
|
|
950
|
-
function normalizeCwd(cwd: string | null | undefined): string | null {
|
|
951
|
-
if (typeof cwd !== 'string') {
|
|
952
|
-
return null;
|
|
953
|
-
}
|
|
954
|
-
const trimmed = cwd.trim();
|
|
955
|
-
return trimmed.length > 0 ? trimmed : null;
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
function readTimestampIso(value: unknown): string | null {
|
|
959
|
-
if (typeof value === 'string') {
|
|
960
|
-
const trimmed = value.trim();
|
|
961
|
-
if (!trimmed) {
|
|
962
|
-
return null;
|
|
963
|
-
}
|
|
964
|
-
|
|
965
|
-
const numeric = Number(trimmed);
|
|
966
|
-
if (Number.isFinite(numeric) && numeric > 0) {
|
|
967
|
-
return new Date((numeric > 1_000_000_000_000 ? numeric : numeric * 1000)).toISOString();
|
|
968
|
-
}
|
|
969
|
-
|
|
970
|
-
const parsedMs = Date.parse(trimmed);
|
|
971
|
-
return Number.isFinite(parsedMs) ? new Date(parsedMs).toISOString() : null;
|
|
972
|
-
}
|
|
973
|
-
|
|
974
|
-
if (typeof value === 'number' && Number.isFinite(value) && value > 0) {
|
|
975
|
-
return new Date((value > 1_000_000_000_000 ? value : value * 1000)).toISOString();
|
|
976
|
-
}
|
|
977
|
-
|
|
978
|
-
return null;
|
|
979
|
-
}
|
|
980
|
-
|
|
981
|
-
function readWorkspaceListResponse(value: unknown): WorkspaceListResponse {
|
|
982
|
-
const record = toRecord(value) ?? {};
|
|
983
|
-
const workspacesRaw = Array.isArray(record.workspaces) ? record.workspaces : [];
|
|
984
|
-
|
|
985
|
-
return {
|
|
986
|
-
bridgeRoot: normalizeCwd(readString(record.bridgeRoot)) ?? '',
|
|
987
|
-
allowOutsideRootCwd: record.allowOutsideRootCwd === true,
|
|
988
|
-
workspaces: workspacesRaw
|
|
989
|
-
.map((entry) => {
|
|
990
|
-
const workspace = toRecord(entry);
|
|
991
|
-
if (!workspace) {
|
|
992
|
-
return null;
|
|
993
|
-
}
|
|
994
|
-
|
|
995
|
-
const path = normalizeCwd(readString(workspace.path));
|
|
996
|
-
if (!path) {
|
|
997
|
-
return null;
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
const rawChatCount = workspace.chatCount;
|
|
1001
|
-
const chatCount =
|
|
1002
|
-
typeof rawChatCount === 'number'
|
|
1003
|
-
? Math.max(0, Math.trunc(rawChatCount))
|
|
1004
|
-
: typeof rawChatCount === 'string'
|
|
1005
|
-
? Math.max(0, Number.parseInt(rawChatCount, 10) || 0)
|
|
1006
|
-
: 0;
|
|
1007
|
-
const updatedAt = readTimestampIso(workspace.updatedAt);
|
|
1008
|
-
|
|
1009
|
-
return {
|
|
1010
|
-
path,
|
|
1011
|
-
chatCount,
|
|
1012
|
-
...(updatedAt ? { updatedAt } : {}),
|
|
1013
|
-
};
|
|
1014
|
-
})
|
|
1015
|
-
.filter((entry): entry is WorkspaceListResponse['workspaces'][number] => entry !== null),
|
|
1016
|
-
};
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
function readFileSystemListResponse(value: unknown): FileSystemListResponse {
|
|
1020
|
-
const record = toRecord(value) ?? {};
|
|
1021
|
-
const entriesRaw = Array.isArray(record.entries) ? record.entries : [];
|
|
1022
|
-
|
|
1023
|
-
return {
|
|
1024
|
-
bridgeRoot: normalizeCwd(readString(record.bridgeRoot)) ?? '',
|
|
1025
|
-
path: normalizeCwd(readString(record.path)) ?? '',
|
|
1026
|
-
parentPath: normalizeCwd(readString(record.parentPath)) ?? null,
|
|
1027
|
-
entries: entriesRaw
|
|
1028
|
-
.map((entry) => {
|
|
1029
|
-
const item = toRecord(entry);
|
|
1030
|
-
if (!item) {
|
|
1031
|
-
return null;
|
|
1032
|
-
}
|
|
1033
|
-
|
|
1034
|
-
const path = normalizeCwd(readString(item.path));
|
|
1035
|
-
const name = normalizeCwd(readString(item.name));
|
|
1036
|
-
if (!path || !name) {
|
|
1037
|
-
return null;
|
|
1038
|
-
}
|
|
1039
|
-
|
|
1040
|
-
return {
|
|
1041
|
-
name,
|
|
1042
|
-
path,
|
|
1043
|
-
kind: readString(item.kind) ?? 'directory',
|
|
1044
|
-
hidden: item.hidden === true,
|
|
1045
|
-
selectable: item.selectable !== false,
|
|
1046
|
-
isGitRepo: item.isGitRepo === true,
|
|
1047
|
-
};
|
|
1048
|
-
})
|
|
1049
|
-
.filter((entry): entry is FileSystemListResponse['entries'][number] => entry !== null),
|
|
1050
|
-
};
|
|
1051
|
-
}
|
|
1052
|
-
|
|
1053
|
-
function normalizeModel(model: string | null | undefined): string | null {
|
|
1054
|
-
if (typeof model !== 'string') {
|
|
1055
|
-
return null;
|
|
1056
|
-
}
|
|
1057
|
-
|
|
1058
|
-
const trimmed = model.trim();
|
|
1059
|
-
return trimmed.length > 0 ? trimmed : null;
|
|
1060
|
-
}
|
|
1061
|
-
|
|
1062
|
-
function normalizeEffort(effort: string | null | undefined): ReasoningEffort | null {
|
|
1063
|
-
if (typeof effort !== 'string') {
|
|
1064
|
-
return null;
|
|
1065
|
-
}
|
|
1066
|
-
|
|
1067
|
-
const normalized = effort.trim().toLowerCase();
|
|
1068
|
-
if (
|
|
1069
|
-
normalized === 'none' ||
|
|
1070
|
-
normalized === 'minimal' ||
|
|
1071
|
-
normalized === 'low' ||
|
|
1072
|
-
normalized === 'medium' ||
|
|
1073
|
-
normalized === 'high' ||
|
|
1074
|
-
normalized === 'xhigh'
|
|
1075
|
-
) {
|
|
1076
|
-
return normalized;
|
|
1077
|
-
}
|
|
1078
|
-
|
|
1079
|
-
return null;
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
|
-
function normalizeServiceTier(
|
|
1083
|
-
serviceTier: ServiceTier | string | null | undefined
|
|
1084
|
-
): ServiceTier | null {
|
|
1085
|
-
if (typeof serviceTier !== 'string') {
|
|
1086
|
-
return null;
|
|
1087
|
-
}
|
|
1088
|
-
|
|
1089
|
-
const normalized = serviceTier.trim().toLowerCase();
|
|
1090
|
-
if (normalized === 'flex' || normalized === 'fast') {
|
|
1091
|
-
return normalized;
|
|
1092
|
-
}
|
|
1093
|
-
|
|
1094
|
-
return null;
|
|
1095
|
-
}
|
|
1096
|
-
|
|
1097
|
-
function toThreadConfig(
|
|
1098
|
-
serviceTier: ServiceTier | null
|
|
1099
|
-
): Record<string, ServiceTier> | null {
|
|
1100
|
-
if (!serviceTier) {
|
|
1101
|
-
return null;
|
|
1102
|
-
}
|
|
1103
|
-
|
|
1104
|
-
return {
|
|
1105
|
-
service_tier: serviceTier,
|
|
1106
|
-
};
|
|
1107
|
-
}
|
|
1108
|
-
|
|
1109
|
-
function normalizeApprovalPolicy(
|
|
1110
|
-
policy: string | null | undefined
|
|
1111
|
-
): ApprovalPolicy | null {
|
|
1112
|
-
if (typeof policy !== 'string') {
|
|
1113
|
-
return null;
|
|
1114
|
-
}
|
|
1115
|
-
|
|
1116
|
-
const normalized = policy.trim().toLowerCase();
|
|
1117
|
-
if (
|
|
1118
|
-
normalized === 'untrusted' ||
|
|
1119
|
-
normalized === 'on-request' ||
|
|
1120
|
-
normalized === 'on-failure' ||
|
|
1121
|
-
normalized === 'never'
|
|
1122
|
-
) {
|
|
1123
|
-
return normalized;
|
|
1124
|
-
}
|
|
1125
|
-
|
|
1126
|
-
return null;
|
|
1127
|
-
}
|
|
1128
|
-
|
|
1129
|
-
function normalizeTurnStatus(status: string | null): string | null {
|
|
1130
|
-
if (!status) {
|
|
1131
|
-
return null;
|
|
1132
|
-
}
|
|
1133
|
-
|
|
1134
|
-
const normalized = status.trim().toLowerCase();
|
|
1135
|
-
return normalized.length > 0 ? normalized : null;
|
|
1136
|
-
}
|
|
1137
|
-
|
|
1138
|
-
function buildTurnInput(
|
|
1139
|
-
content: string,
|
|
1140
|
-
mentions: TurnInputMention[],
|
|
1141
|
-
localImages: TurnInputLocalImage[]
|
|
1142
|
-
): Array<TurnInputText | TurnInputMention | TurnInputLocalImage> {
|
|
1143
|
-
const textInput: TurnInputText = {
|
|
1144
|
-
type: 'text',
|
|
1145
|
-
text: content,
|
|
1146
|
-
text_elements: [],
|
|
1147
|
-
};
|
|
1148
|
-
|
|
1149
|
-
if (mentions.length === 0 && localImages.length === 0) {
|
|
1150
|
-
return [textInput];
|
|
1151
|
-
}
|
|
1152
|
-
|
|
1153
|
-
return [textInput, ...mentions, ...localImages];
|
|
1154
|
-
}
|
|
1155
|
-
|
|
1156
|
-
function normalizeMentions(raw: MentionInput[] | undefined): TurnInputMention[] {
|
|
1157
|
-
if (!Array.isArray(raw)) {
|
|
1158
|
-
return [];
|
|
1159
|
-
}
|
|
1160
|
-
|
|
1161
|
-
const normalized: TurnInputMention[] = [];
|
|
1162
|
-
const seenPaths = new Set<string>();
|
|
1163
|
-
|
|
1164
|
-
for (const entry of raw) {
|
|
1165
|
-
if (!entry || typeof entry.path !== 'string') {
|
|
1166
|
-
continue;
|
|
1167
|
-
}
|
|
1168
|
-
|
|
1169
|
-
const path = entry.path.trim();
|
|
1170
|
-
if (!path) {
|
|
1171
|
-
continue;
|
|
1172
|
-
}
|
|
1173
|
-
|
|
1174
|
-
const dedupeKey = path.toLowerCase();
|
|
1175
|
-
if (seenPaths.has(dedupeKey)) {
|
|
1176
|
-
continue;
|
|
1177
|
-
}
|
|
1178
|
-
seenPaths.add(dedupeKey);
|
|
1179
|
-
|
|
1180
|
-
const name = normalizeMentionName(entry.name, path);
|
|
1181
|
-
normalized.push({
|
|
1182
|
-
type: 'mention',
|
|
1183
|
-
name,
|
|
1184
|
-
path,
|
|
1185
|
-
});
|
|
1186
|
-
}
|
|
1187
|
-
|
|
1188
|
-
return normalized;
|
|
1189
|
-
}
|
|
1190
|
-
|
|
1191
|
-
function normalizeMentionName(name: string | undefined, path: string): string {
|
|
1192
|
-
if (typeof name === 'string') {
|
|
1193
|
-
const trimmed = name.trim();
|
|
1194
|
-
if (trimmed.length > 0) {
|
|
1195
|
-
return trimmed;
|
|
1196
|
-
}
|
|
1197
|
-
}
|
|
1198
|
-
|
|
1199
|
-
const pathSegments = path.split(/[\\/]/).filter(Boolean);
|
|
1200
|
-
const inferred = pathSegments[pathSegments.length - 1];
|
|
1201
|
-
if (typeof inferred === 'string' && inferred.trim().length > 0) {
|
|
1202
|
-
return inferred.trim();
|
|
1203
|
-
}
|
|
1204
|
-
|
|
1205
|
-
return path;
|
|
1206
|
-
}
|
|
1207
|
-
|
|
1208
|
-
function normalizeLocalImages(raw: LocalImageInput[] | undefined): TurnInputLocalImage[] {
|
|
1209
|
-
if (!Array.isArray(raw)) {
|
|
1210
|
-
return [];
|
|
1211
|
-
}
|
|
1212
|
-
|
|
1213
|
-
const normalized: TurnInputLocalImage[] = [];
|
|
1214
|
-
const seenPaths = new Set<string>();
|
|
1215
|
-
|
|
1216
|
-
for (const entry of raw) {
|
|
1217
|
-
if (!entry || typeof entry.path !== 'string') {
|
|
1218
|
-
continue;
|
|
1219
|
-
}
|
|
1220
|
-
|
|
1221
|
-
const path = entry.path.trim();
|
|
1222
|
-
if (!path) {
|
|
1223
|
-
continue;
|
|
1224
|
-
}
|
|
1225
|
-
|
|
1226
|
-
const dedupeKey = path.toLowerCase();
|
|
1227
|
-
if (seenPaths.has(dedupeKey)) {
|
|
1228
|
-
continue;
|
|
1229
|
-
}
|
|
1230
|
-
seenPaths.add(dedupeKey);
|
|
1231
|
-
|
|
1232
|
-
normalized.push({
|
|
1233
|
-
type: 'localImage',
|
|
1234
|
-
path,
|
|
1235
|
-
});
|
|
1236
|
-
}
|
|
1237
|
-
|
|
1238
|
-
return normalized;
|
|
1239
|
-
}
|
|
1240
|
-
|
|
1241
|
-
function toTurnCollaborationMode(
|
|
1242
|
-
value: CollaborationMode | string | null | undefined,
|
|
1243
|
-
model: string | null,
|
|
1244
|
-
effort: ReasoningEffort | null
|
|
1245
|
-
): AppServerCollaborationMode | null {
|
|
1246
|
-
if (typeof value !== 'string') {
|
|
1247
|
-
return null;
|
|
1248
|
-
}
|
|
1249
|
-
|
|
1250
|
-
const normalized = value.trim().toLowerCase();
|
|
1251
|
-
if (normalized !== 'plan' && normalized !== 'default') {
|
|
1252
|
-
return null;
|
|
1253
|
-
}
|
|
1254
|
-
|
|
1255
|
-
if (!model) {
|
|
1256
|
-
return null;
|
|
1257
|
-
}
|
|
1258
|
-
|
|
1259
|
-
return {
|
|
1260
|
-
mode: normalized,
|
|
1261
|
-
settings: {
|
|
1262
|
-
model,
|
|
1263
|
-
reasoning_effort: effort,
|
|
1264
|
-
developer_instructions: null,
|
|
1265
|
-
},
|
|
1266
|
-
};
|
|
1267
|
-
}
|
|
1268
|
-
|
|
1269
|
-
function normalizeCollaborationMode(
|
|
1270
|
-
value: CollaborationMode | string | null | undefined
|
|
1271
|
-
): CollaborationMode | null {
|
|
1272
|
-
if (typeof value !== 'string') {
|
|
1273
|
-
return null;
|
|
1274
|
-
}
|
|
1275
|
-
|
|
1276
|
-
const normalized = value.trim().toLowerCase();
|
|
1277
|
-
if (normalized === 'plan' || normalized === 'default') {
|
|
1278
|
-
return normalized;
|
|
1279
|
-
}
|
|
1280
|
-
|
|
1281
|
-
return null;
|
|
1282
|
-
}
|
|
1283
|
-
|
|
1284
|
-
function readThreadRuntimeSettings(value: unknown): AppServerThreadRuntimeSettings {
|
|
1285
|
-
const record = toRecord(value);
|
|
1286
|
-
return {
|
|
1287
|
-
model: normalizeModel(readString(record?.model)),
|
|
1288
|
-
effort: normalizeEffort(
|
|
1289
|
-
readString(record?.reasoningEffort) ?? readString(record?.reasoning_effort)
|
|
1290
|
-
),
|
|
1291
|
-
};
|
|
1292
|
-
}
|
|
1293
|
-
|
|
1294
|
-
function toReasoningEffortOptions(raw: unknown): ModelReasoningEffortOption[] {
|
|
1295
|
-
if (!Array.isArray(raw)) {
|
|
1296
|
-
return [];
|
|
1297
|
-
}
|
|
1298
|
-
|
|
1299
|
-
const options: ModelReasoningEffortOption[] = [];
|
|
1300
|
-
for (const entry of raw) {
|
|
1301
|
-
if (typeof entry === 'string') {
|
|
1302
|
-
const directEffort = normalizeEffort(entry);
|
|
1303
|
-
if (directEffort) {
|
|
1304
|
-
options.push({
|
|
1305
|
-
effort: directEffort,
|
|
1306
|
-
});
|
|
1307
|
-
}
|
|
1308
|
-
continue;
|
|
1309
|
-
}
|
|
1310
|
-
|
|
1311
|
-
const record = toRecord(entry);
|
|
1312
|
-
if (!record) {
|
|
1313
|
-
continue;
|
|
1314
|
-
}
|
|
1315
|
-
|
|
1316
|
-
const effort = normalizeEffort(
|
|
1317
|
-
readString(record.reasoningEffort) ?? readString(record.effort)
|
|
1318
|
-
);
|
|
1319
|
-
if (!effort) {
|
|
1320
|
-
continue;
|
|
1321
|
-
}
|
|
1322
|
-
|
|
1323
|
-
options.push({
|
|
1324
|
-
effort,
|
|
1325
|
-
description: readString(record.description) ?? undefined,
|
|
1326
|
-
});
|
|
1327
|
-
}
|
|
1328
|
-
|
|
1329
|
-
return options;
|
|
1330
|
-
}
|
|
1331
|
-
|
|
1332
|
-
function chatHasRecentUserMessage(chat: Chat, content: string, tailSize = 8): boolean {
|
|
1333
|
-
const normalized = content.trim();
|
|
1334
|
-
if (!normalized) {
|
|
1335
|
-
return true;
|
|
1336
|
-
}
|
|
1337
|
-
|
|
1338
|
-
const tail = chat.messages.slice(-tailSize);
|
|
1339
|
-
return tail.some(
|
|
1340
|
-
(message) => message.role === 'user' && message.content.trim() === normalized
|
|
1341
|
-
);
|
|
1342
|
-
}
|
|
1343
|
-
|
|
1344
|
-
function rawThreadHasTurns(rawThread: RawThread): boolean {
|
|
1345
|
-
return Array.isArray(rawThread.turns) && rawThread.turns.length > 0;
|
|
1346
|
-
}
|
|
1347
|
-
|
|
1348
|
-
function rawThreadHasTurnUserMessage(
|
|
1349
|
-
rawThread: RawThread,
|
|
1350
|
-
turnId: string,
|
|
1351
|
-
content: string
|
|
1352
|
-
): boolean {
|
|
1353
|
-
const normalizedContent = content.trim();
|
|
1354
|
-
const normalizedTurnId = turnId.trim();
|
|
1355
|
-
if (!normalizedContent || !normalizedTurnId) {
|
|
1356
|
-
return false;
|
|
1357
|
-
}
|
|
1358
|
-
|
|
1359
|
-
const turns = Array.isArray(rawThread.turns) ? rawThread.turns : [];
|
|
1360
|
-
const matchedTurn = turns.find((turn) => turn.id === normalizedTurnId);
|
|
1361
|
-
if (!matchedTurn || !Array.isArray(matchedTurn.items)) {
|
|
1362
|
-
return false;
|
|
1363
|
-
}
|
|
1364
|
-
|
|
1365
|
-
return matchedTurn.items.some((item) => {
|
|
1366
|
-
const record = toRecord(item);
|
|
1367
|
-
if (!record || readString(record.type) !== 'userMessage') {
|
|
1368
|
-
return false;
|
|
1369
|
-
}
|
|
1370
|
-
|
|
1371
|
-
return extractUserMessageText(record.content).trim() === normalizedContent;
|
|
1372
|
-
});
|
|
1373
|
-
}
|
|
1374
|
-
|
|
1375
|
-
function extractUserMessageText(value: unknown): string {
|
|
1376
|
-
if (!Array.isArray(value)) {
|
|
1377
|
-
return '';
|
|
1378
|
-
}
|
|
1379
|
-
|
|
1380
|
-
return value
|
|
1381
|
-
.map((entry) => {
|
|
1382
|
-
const record = toRecord(entry);
|
|
1383
|
-
if (!record) {
|
|
1384
|
-
return '';
|
|
1385
|
-
}
|
|
1386
|
-
|
|
1387
|
-
if (readString(record.type) !== 'text') {
|
|
1388
|
-
return '';
|
|
1389
|
-
}
|
|
1390
|
-
|
|
1391
|
-
return readString(record.text) ?? '';
|
|
1392
|
-
})
|
|
1393
|
-
.filter((part) => part.length > 0)
|
|
1394
|
-
.join('\n');
|
|
1395
|
-
}
|
|
1396
|
-
|
|
1397
|
-
function appendSyntheticUserMessage(chat: Chat, content: string): Chat {
|
|
1398
|
-
const normalized = content.trim();
|
|
1399
|
-
if (!normalized) {
|
|
1400
|
-
return chat;
|
|
1401
|
-
}
|
|
1402
|
-
|
|
1403
|
-
const createdAt = new Date().toISOString();
|
|
1404
|
-
return {
|
|
1405
|
-
...chat,
|
|
1406
|
-
updatedAt: createdAt,
|
|
1407
|
-
lastMessagePreview: normalized.slice(0, 120),
|
|
1408
|
-
messages: [
|
|
1409
|
-
...chat.messages,
|
|
1410
|
-
{
|
|
1411
|
-
id: `local-user-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
1412
|
-
role: 'user',
|
|
1413
|
-
content: normalized,
|
|
1414
|
-
createdAt,
|
|
1415
|
-
},
|
|
1416
|
-
],
|
|
1417
|
-
};
|
|
1418
|
-
}
|
|
1419
|
-
|
|
1420
|
-
function sleep(ms: number): Promise<void> {
|
|
1421
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1422
|
-
}
|
|
1423
|
-
|
|
1424
|
-
function isMaterializationGapError(error: unknown): boolean {
|
|
1425
|
-
const message = String((error as Error).message ?? error);
|
|
1426
|
-
return (
|
|
1427
|
-
message.includes('includeTurns') &&
|
|
1428
|
-
(message.includes('material') || message.includes('materialis'))
|
|
1429
|
-
);
|
|
1430
|
-
}
|