ryco-cli 0.1.6 → 0.1.8
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/dist/{AzureDevOpsSourceControlProvider-CC2_COxP.mjs → AzureDevOpsSourceControlProvider-B5vb4DOU.mjs} +2 -2
- package/dist/{AzureDevOpsSourceControlProvider-6holYS_D.cjs → AzureDevOpsSourceControlProvider-CYZmJqSM.cjs} +2 -2
- package/dist/{BitbucketSourceControlProvider-CYR_BD1d.mjs → BitbucketSourceControlProvider-CcAb4IgH.mjs} +2 -2
- package/dist/{BitbucketSourceControlProvider-a0IsNFyG.cjs → BitbucketSourceControlProvider-D_7i4YQz.cjs} +2 -2
- package/dist/{ClaudeDriver-D3nsxwH9.mjs → ClaudeDriver-CoPBpdrp.mjs} +198 -8
- package/dist/{ClaudeDriver-C6tQNEWO.cjs → ClaudeDriver-ScqmbPKW.cjs} +197 -7
- package/dist/{CodexDriver-ms_YgFD7.cjs → CodexDriver-CtCCc3CC.cjs} +36 -8
- package/dist/{CodexDriver-BILrJG8o.mjs → CodexDriver-DH7vqku4.mjs} +37 -9
- package/dist/{CodexTextGeneration-BIKHl7E3.mjs → CodexTextGeneration-CJV1jPda.mjs} +3 -3
- package/dist/{CodexTextGeneration-CHEgoANm.cjs → CodexTextGeneration-Db2hn8Qz.cjs} +2 -2
- package/dist/{CopilotDriver-CmD3Ffyl.mjs → CopilotDriver-CFCF68Te.mjs} +7 -6
- package/dist/{CopilotDriver-B0--ZwIK.cjs → CopilotDriver-DLN2KEoc.cjs} +6 -5
- package/dist/{CursorDriver-DTVPXZ-R.cjs → CursorDriver-BlvQbOEZ.cjs} +201 -15
- package/dist/{CursorDriver-CbeaIbdb.mjs → CursorDriver-Dej81rwD.mjs} +202 -16
- package/dist/{ForgejoSourceControlProvider-DX6d9gvz.mjs → ForgejoSourceControlProvider-3cFD7SqY.mjs} +2 -2
- package/dist/{ForgejoSourceControlProvider-DwAog76b.cjs → ForgejoSourceControlProvider-DYFUGvBk.cjs} +2 -2
- package/dist/{GitHubSourceControlProvider-9lJFzjsu.cjs → GitHubSourceControlProvider-B1Tp0TbY.cjs} +27 -4
- package/dist/{GitHubSourceControlProvider-C-LGwho3.mjs → GitHubSourceControlProvider-Kf4rrBTF.mjs} +27 -4
- package/dist/{GitLabSourceControlProvider-CvKA74lg.cjs → GitLabSourceControlProvider-D3vvKrB4.cjs} +2 -2
- package/dist/{GitLabSourceControlProvider-CkeT2aEx.mjs → GitLabSourceControlProvider-Ygppeftk.mjs} +2 -2
- package/dist/{NodeSqliteClient-B5aDHbNc.cjs → NodeSqliteClient-D1O-MR8w.cjs} +4 -1
- package/dist/{NodeSqliteClient-A1TEgwj_.mjs → NodeSqliteClient-DdTjpAko.mjs} +4 -1
- package/dist/{OpenCodeDriver-ClWtCk0j.mjs → OpenCodeDriver-BGa9Tkot.mjs} +326 -39
- package/dist/{OpenCodeDriver-CXUsnl5o.cjs → OpenCodeDriver-mbR9mF54.cjs} +325 -38
- package/dist/{SourceControlProviderDiscoveryCatalog-_rg0mc1o.cjs → SourceControlProviderDiscoveryCatalog-CTb100Uk.cjs} +1 -64
- package/dist/{SourceControlProviderDiscoveryCatalog-yMDer_Yh.mjs → SourceControlProviderDiscoveryCatalog-Zk11tJoL.mjs} +3 -48
- package/dist/bin.cjs +1481 -704
- package/dist/bin.mjs +1435 -659
- package/dist/client/assets/{AnimatedHeight-DgItDSis.js → AnimatedHeight-CPQ2q38I.js} +1 -1
- package/dist/client/assets/AppearanceSettings-B0FYiIxL.js +1 -0
- package/dist/client/assets/{BranchToolbar.logic-C_xHEt9C.js → BranchToolbar.logic-C1yjFjxJ.js} +1 -1
- package/dist/client/assets/ChatRightPanel-CJDSKMU2.js +188 -0
- package/dist/client/assets/ChatThreadRouteView-BaKwKGbC.js +1 -0
- package/dist/client/assets/CommandPaletteDialog-BHG_MdZk.js +1 -0
- package/dist/client/assets/CompositeRoot-Bs0hfelE.js +1 -0
- package/dist/client/assets/ConnectionsSettings-DvZNgO60.js +1 -0
- package/dist/client/assets/{DiagnosticsSettings-B340S_mq.js → DiagnosticsSettings-0v_hh1Qh.js} +1 -1
- package/dist/client/assets/{DialogHandle-BJY7cHCV.js → DialogHandle-CwEAVRF_.js} +1 -1
- package/dist/client/assets/{DialogRoot-Ej1FVk-_.js → DialogRoot-CYuaaDI3.js} +1 -1
- package/dist/client/assets/DialogTitle-Cak6zT3u.js +1 -0
- package/dist/client/assets/DialogTrigger-BD0KYYT-.js +1 -0
- package/dist/client/assets/{DialogViewport-DvjAl76K.js → DialogViewport-9sGf4JUp.js} +1 -1
- package/dist/client/assets/{DraftChatThreadRouteView-pOkyeKPS.js → DraftChatThreadRouteView-nvKLHlii.js} +1 -1
- package/dist/client/assets/{JetBrainsIcons-DTTF47I0.js → JetBrainsIcons-CflvH7gO.js} +1 -1
- package/dist/client/assets/KeybindingsSettings-DhLKhgYn.js +7 -0
- package/dist/client/assets/McpServersSettings-COs_dng1.js +6 -0
- package/dist/client/assets/{NoActiveThreadState-DVHwrkCp.js → NoActiveThreadState-cxMCW-cQ.js} +1 -1
- package/dist/client/assets/OpinionatedPluginsSettings-ag_OgOGj.js +1 -0
- package/dist/client/assets/{ProjectFavicon-TDP7HRfn.js → ProjectFavicon-D97Hy4xo.js} +1 -1
- package/dist/client/assets/{ProviderUpdateLaunchNotification.logic-6TpFsmiI.js → ProviderUpdateLaunchNotification.logic-RMYvRSEk.js} +1 -1
- package/dist/client/assets/ProvidersSettingsPanel-DcdVMRVC.js +1 -0
- package/dist/client/assets/{RedactedSensitiveText-BfoVjPsE.js → RedactedSensitiveText-CQY4pFAq.js} +1 -1
- package/dist/client/assets/RootAppShell-BRjETnaT.js +12 -0
- package/dist/client/assets/SettingsDialog-DRi5jsmq.js +2 -0
- package/dist/client/assets/SourceControlSettings-CdUulS4O.js +1 -0
- package/dist/client/assets/StatisticsPanel-NLU3ecLt.js +64 -0
- package/dist/client/assets/{ThreadStatusIndicators-B0leIJGD.js → ThreadStatusIndicators-CebYbeXP.js} +1 -1
- package/dist/client/assets/{ThreadTerminalDrawer-COq2Fk17.js → ThreadTerminalDrawer-DlI0gGer.js} +17 -17
- package/dist/client/assets/ThreadWorkspacePanel-CEIVrCZ0.js +166 -0
- package/dist/client/assets/{alert-dialog-lMfKpG2t.js → alert-dialog-wh07u3JU.js} +1 -1
- package/dist/client/assets/chart-column-Cg34FxwD.js +1 -0
- package/dist/client/assets/{chatThreadActions-PPyTj_x0.js → chatThreadActions-UitETN_n.js} +1 -1
- package/dist/client/assets/chevron-up-C3DS3evc.js +1 -0
- package/dist/client/assets/{clamp-JiD4IZ0Z.js → clamp-DPbdAzEu.js} +1 -1
- package/dist/client/assets/{clipboard-copy-CYBLSG2q.js → clipboard-copy-ClVNnHW5.js} +1 -1
- package/dist/client/assets/clock-Cr66Pt4W.js +1 -0
- package/dist/client/assets/{commandPaletteStore-uVfCD7zE.js → commandPaletteStore-DzUBFRor.js} +1 -1
- package/dist/client/assets/composerDraftStore-BfLPHwHL.js +21 -0
- package/dist/client/assets/{desktopUpdateAtoms-X6uM5SoD.js → desktopUpdateAtoms-BiqPT2_z.js} +1 -1
- package/dist/client/assets/{download-DLBlpp4h.js → download-DJ1juHK4.js} +1 -1
- package/dist/client/assets/{draft-input-dLlVMl5P.js → draft-input-B1txZFC7.js} +1 -1
- package/dist/client/assets/editorPreferences-Bbmh6Bm1.js +1 -0
- package/dist/client/assets/{empty-DlLY-Hhj.js → empty-CUEYr1p8.js} +1 -1
- package/dist/client/assets/{group-zDBPF7rR.js → group-BouZ2n9F.js} +1 -1
- package/dist/client/assets/{index-Dq8sT2lF.js → index-DiHgOLH_.js} +2 -2
- package/dist/client/assets/{input-B9-RWT56.js → input-Do_m9U-4.js} +1 -1
- package/dist/client/assets/kbd-DJilTfYF.js +1 -0
- package/dist/client/assets/{keybindings-Dx4Nc1vY.js → keybindings-CRkz0yvp.js} +1 -1
- package/dist/client/assets/{keyboard-DDTWQkr0.js → keyboard-D3WgbAUQ.js} +1 -1
- package/dist/client/assets/{keyedQuery-Ds4OGhX2.js → keyedQuery-PQcOnB2O.js} +0 -0
- package/dist/client/assets/{main-DxfpmoKJ.js → main-C-491vdD.js} +2 -2
- package/dist/client/assets/main-fW5L_SdM.css +2 -0
- package/dist/client/assets/{palette-BQcz-ZYV.js → palette-BRoYo327.js} +1 -1
- package/dist/client/assets/{play-QloDGe4R.js → play-BZbHk_vw.js} +1 -1
- package/dist/client/assets/plus-D0S72hZS.js +1 -0
- package/dist/client/assets/projectAtoms-KYCIIuVn.js +1 -0
- package/dist/client/assets/providerDriverMeta-BX4CLldz.js +1 -0
- package/dist/client/assets/providerIconUtils-DTRc3qno.js +47 -0
- package/dist/client/assets/radio-group-De3hRQoY.js +1 -0
- package/dist/client/assets/{refresh-cw-DkBMGllm.js → refresh-cw-D_1NT-T2.js} +1 -1
- package/dist/client/assets/{resolveAriaLabelledBy-DDfIbj05.js → resolveAriaLabelledBy-RblUm3b1.js} +1 -1
- package/dist/client/assets/rightPanelRouteSearch-DLllyqRr.js +1 -0
- package/dist/client/assets/{scale-BActunFu.js → scale-s57Ro96s.js} +1 -1
- package/dist/client/assets/{scroll-area-D-YOUG02.js → scroll-area-B0_k8-iT.js} +1 -1
- package/dist/client/assets/{separator-TInKeIDo.js → separator-AyXRgdnJ.js} +1 -1
- package/dist/client/assets/{server-BtEG3NAw.js → server-Z-m1OqE5.js} +1 -1
- package/dist/client/assets/{session-logic-DNf1aXq_.js → session-logic-B87Htlw4.js} +2 -2
- package/dist/client/assets/settingsDialogStore-CxUfUnd9.js +1 -0
- package/dist/client/assets/{settingsLayout-D22Mm0u3.js → settingsLayout-BtKS3Z8f.js} +1 -1
- package/dist/client/assets/sidebar-B0WxOej2.js +1 -0
- package/dist/client/assets/sidebarStatusText-C_EsHj20.js +1 -0
- package/dist/client/assets/{skeleton-DWaac_qp.js → skeleton-COt2Az5i.js} +1 -1
- package/dist/client/assets/{storeSelectors-Cx1IYPA4.js → storeSelectors-BuB4Kzj6.js} +1 -1
- package/dist/client/assets/threadSelectionStore-BS6X6HHt.js +1 -0
- package/dist/client/assets/toast-CaV8TQi_.js +1 -0
- package/dist/client/assets/toggle-DE4ApNIU.js +1 -0
- package/dist/client/assets/{toggle-group-CnLjaHSL.js → toggle-group-BuzAkAEk.js} +1 -1
- package/dist/client/assets/{tokenModePresentation-BSYdIvBm.js → tokenModePresentation-BCL2aeat.js} +1 -1
- package/dist/client/assets/{trash-2-BI5xcbsm.js → trash-2-ZZ1feCT6.js} +1 -1
- package/dist/client/assets/{triangle-alert-DJef_Uvh.js → triangle-alert-CL3zqnKL.js} +1 -1
- package/dist/client/assets/{undo-2-DeZ2cMGS.js → undo-2-Cu9H3R3q.js} +1 -1
- package/dist/client/assets/{useHandleNewThread-XB82O6SA.js → useHandleNewThread-Gke-ZFBr.js} +1 -1
- package/dist/client/assets/useLabelableId-DfuxWqrk.js +1 -0
- package/dist/client/assets/{useNavigate-B2tgshhW.js → useNavigate-DQEHh6ky.js} +1 -1
- package/dist/client/assets/useTheme-HcKmBfpF.js +1 -0
- package/dist/client/assets/{vscode-icons-DM9qFoEr.js → vscode-icons-DGDiHkqG.js} +1 -1
- package/dist/client/assets/{wrench-je4QOyG-.js → wrench-C_OATMLq.js} +1 -1
- package/dist/client/assets/x-BG9zZGeD.js +1 -0
- package/dist/client/index.html +1 -1
- package/dist/{collectUint8StreamText-TCG6xW_P.cjs → collectUint8StreamText-B-GW3u_2.cjs} +367 -15
- package/dist/{collectUint8StreamText-C2z5Y8tF.mjs → collectUint8StreamText-COE2_gie.mjs} +345 -17
- package/dist/{makeManagedServerProvider-BXO8QvzC.mjs → makeManagedServerProvider-D1_iEWGi.mjs} +1 -1
- package/dist/{makeManagedServerProvider-DPFw9gV_.cjs → makeManagedServerProvider-DTsQ87HL.cjs} +1 -1
- package/package.json +4 -2
- package/dist/client/assets/AppearanceSettings-BlsMFBvJ.js +0 -1
- package/dist/client/assets/ChatRightPanel-CThudBb1.js +0 -188
- package/dist/client/assets/ChatThreadRouteView-CV6ETYG5.js +0 -1
- package/dist/client/assets/CommandPaletteDialog-C_H7R8S5.js +0 -1
- package/dist/client/assets/CompositeRoot-DjnzUIwC.js +0 -1
- package/dist/client/assets/ConnectionsSettings-hArR4Oe3.js +0 -1
- package/dist/client/assets/DialogTitle-H1yIMmA9.js +0 -1
- package/dist/client/assets/DialogTrigger-BHMq_K2G.js +0 -1
- package/dist/client/assets/KeybindingsSettings-CW3RRi-7.js +0 -7
- package/dist/client/assets/McpServersSettings-dQ3BzOWY.js +0 -6
- package/dist/client/assets/OpinionatedPluginsSettings-Cjj23Fs4.js +0 -1
- package/dist/client/assets/ProvidersSettingsPanel-D15EeWAq.js +0 -1
- package/dist/client/assets/RootAppShell-CWBPSA2w.js +0 -12
- package/dist/client/assets/SettingsDialog-oJCE5foT.js +0 -2
- package/dist/client/assets/SourceControlSettings-CPnlMxNm.js +0 -1
- package/dist/client/assets/ThreadWorkspacePanel-qF9y6QT9.js +0 -166
- package/dist/client/assets/composerDraftStore-D12lUSfh.js +0 -21
- package/dist/client/assets/editorPreferences-BLeEBSD_.js +0 -1
- package/dist/client/assets/folder-open-DMjz0lpx.js +0 -1
- package/dist/client/assets/kbd-aeSsjiPI.js +0 -1
- package/dist/client/assets/main-C57RhHZ_.css +0 -2
- package/dist/client/assets/plus-4Oy56d-3.js +0 -1
- package/dist/client/assets/projectAtoms-DUEBb7Zz.js +0 -1
- package/dist/client/assets/providerDriverMeta-Dwi6Zqgd.js +0 -1
- package/dist/client/assets/providerIconUtils-uhWb4bdg.js +0 -47
- package/dist/client/assets/radio-group-DHyQlLeX.js +0 -1
- package/dist/client/assets/rightPanelRouteSearch-DfuWVvXN.js +0 -1
- package/dist/client/assets/settingsDialogStore-BINi7pdD.js +0 -1
- package/dist/client/assets/sidebar-DHwNQmWp.js +0 -1
- package/dist/client/assets/threadSelectionStore-C0ig4405.js +0 -1
- package/dist/client/assets/toast-DE7a4wkW.js +0 -1
- package/dist/client/assets/toggle-BIW4AyPY.js +0 -1
- package/dist/client/assets/useLabelableId-DBAgv9qQ.js +0 -1
- package/dist/client/assets/useTheme-Dv42Z8uy.js +0 -1
- package/dist/client/assets/x-fI9snvD3.js +0 -1
package/dist/bin.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { $ as
|
|
4
|
-
import { _ as formatSchemaError, a as makeForgejoDiscovery, c as sourceBranch, d as firstNonEmptyLine, f as probeSourceControlProvider, g as decodeJsonResult, h as layer$19, i as makeBitbucketDiscovery, m as VcsProcess, n as githubDiscovery, o as SourceControlProvider, p as refineUnknownRemoteProvider, r as gitlabDiscovery, s as parseSourceControlOwnerRef, t as azureDevOpsDiscovery, u as detailFromCause, v as fromLenientJson } from "./SourceControlProviderDiscoveryCatalog-yMDer_Yh.mjs";
|
|
3
|
+
import { $ as ProviderRespondToUserInputInput, $n as AuthRevokeClientSessionInput, $t as ThreadDeletedPayload$1, A as McpServerName, At as OrchestrationSession, B as DEFAULT_SERVER_SETTINGS, Bn as ProviderInstanceId, Bt as ProjectMetaUpdatedPayload$1, C as McpInventoryResourceTemplate, Cn as WorkItemProviderError, Ct as OrchestrationGetTurnDiffError, D as McpProviderSupport, Dn as SourceControlRepositoryError, Dt as OrchestrationProposedPlanId, E as McpOauthLoginResult, En as SourceControlProviderError, Et as OrchestrationMessageRole, F as ServerProviderUpdateError, Ft as OrchestrationWorktreeShell, G as KeybindingsConfig, Gn as TerminalHistoryError, H as ServerSettings, Hn as isProviderDriverKind, Ht as ProjectScript, I as ClaudeSettings, In as DEFAULT_GIT_TEXT_GENERATION_MODEL_BY_PROVIDER, J as ResolvedKeybindingRule, Jn as EDITORS, Jt as RuntimeMode, K as KeybindingsConfigError, Kn as TerminalNotRunningError, Kt as ProviderInteractionMode, L as CodexSettings, Ln as DEFAULT_MODEL, Lt as ProjectAvatarSetPayload$1, M as McpWorkspaceId, Mt as OrchestrationShellSnapshot, N as OpinionatedPluginError, Nt as OrchestrationThread, O as McpServer, Ot as OrchestrationReadModel, P as ServerProvider, Pn as VcsUnsupportedOperationError, Pt as OrchestrationThreadActivityTone, Q as ProviderRespondToRequestInput, Qn as AuthCreatePairingCredentialInput, Qt as ThreadCreatedPayload$1, R as CopilotSettings, Rn as MODEL_SLUG_ALIASES_BY_PROVIDER, Rt as ProjectCreatedPayload$1, S as McpInventoryResource, Sn as WORK_ITEM_DETAIL_COMMENT_BODY_MAX_BYTES, Sr as TurnId, St as OrchestrationGetSnapshotError, T as McpListServersResult, Tt as OrchestrationMessage, U as ServerSettingsError, Ut as ProjectionPendingApprovalDecision, V as OpenCodeSettings, Vn as defaultInstanceIdForDriver, Vt as ProjectMetadataDir, W as KeybindingRule, Wn as TerminalCwdError, Wt as ProjectionPendingApprovalStatus, X as isToolLifecycleItemType, Xn as AuthBootstrapInput, Xt as ThreadArchivedPayload$1, Y as THREAD_JUMP_KEYBINDING_COMMANDS, Yn as OpenError, Yt as ThreadActivityAppendedPayload$1, Z as ProviderInterruptTurnInput, Zn as AuthClientMetadataDeviceType, Zt as ThreadAttachedToWorktreePayload$1, _ as AtlassianConnectionStatus, _n as WorktreeSourceControlStateUpdatedPayload$1, _t as OrchestrationDispatchCommandError, a as WS_METHODS, an as ThreadRuntimeModeSetPayload$1, ar as AuthSessionId, at as ClientOrchestrationCommand, b as GitManagerError, bn as WorktreeId, br as ThreadId, bt as OrchestrationEventType, cn as ThreadTokenModeSetPayload$1, cr as EnvironmentId, ct as DEFAULT_PROVIDER_INTERACTION_MODE, d as ProjectSearchEntriesError, dn as WorktreeArchivedPayload$1, dr as MessageId, dt as OrchestrationActorKind, en as ThreadInteractionModeSetPayload$1, er as AuthRevokePairingLinkInput, et as ProviderSendTurnInput, f as ProjectStageFileReferenceError, fn as WorktreeCreatedPayload$1, fr as NonNegativeInt, ft as OrchestrationAggregateKind, g as AtlassianConnectionKind, gn as WorktreeRestoredPayload$1, gt as OrchestrationCommandReceiptStatus, h as AtlassianConnectionError, hn as WorktreeMetaUpdatedPayload$1, ht as OrchestrationCheckpointSummary, i as fromLenientJson, in as ThreadRevertedPayload$1, ir as AtlassianResourceId, it as ChatAttachment, j as McpSettingsError, jn as VcsProcessExitError, jt as OrchestrationSessionStatus, k as McpServerConfig, kn as VcsDriverKind, kt as OrchestrationReplayEventsError, l as ProjectListEntriesError, ln as ThreadTurnDiffCompletedPayload$1, lr as EventId, lt as ModelSelection, m as AtlassianCapability, mn as WorktreeManualPositionSetPayload$1, mr as ProjectId, mt as OrchestrationCheckpointStatus, n as decodeJsonResult, nn as ThreadMetaUpdatedPayload$1, nr as ApprovalRequestId, nt as ProviderStopSessionInput, o as WsRpcGroup, on as ThreadSessionSetPayload$1, or as CheckpointRef, ot as DEFAULT_AGENT_TOKEN_MODE, p as ProjectWriteFileError, pn as WorktreeDeletedPayload$1, pr as PositiveInt, pt as OrchestrationCheckpointFile, q as MODEL_PICKER_JUMP_KEYBINDING_COMMANDS, qn as TerminalSessionLookupError, qt as ProviderSessionRuntimeStatus, r as formatSchemaError, rn as ThreadProposedPlanUpsertedPayload$1, rr as AtlassianConnectionId, rt as AgentTokenMode, s as FilesystemBrowseError, sn as ThreadStatusBucketOverriddenPayload$1, sr as CommandId, t as collectUint8StreamText, tn as ThreadMessageSentPayload, tr as AuthRpcError, tt as ProviderSessionStartInput, u as ProjectReadFileError, un as ThreadUnarchivedPayload$1, ur as IsoDateTime, ut as ORCHESTRATION_WS_METHODS, v as AtlassianProduct, vn as StatusBucket, vt as OrchestrationEvent, w as McpInventoryTool, wn as WorkItemProviderKind, wt as OrchestrationGetTurnDiffResult, x as TextGenerationError, xn as WORK_ITEM_DETAIL_BODY_MAX_BYTES, xr as TrimmedNonEmptyString, xt as OrchestrationGetFullThreadDiffError, y as GitCommandError, yn as Worktree, yt as OrchestrationEventMetadata, z as CursorSettings, zn as ProviderDriverKind, zt as ProjectDeletedPayload$1 } from "./collectUint8StreamText-COE2_gie.mjs";
|
|
5
4
|
import { A as terminalRestartsTotal, B as mergeGitStatusParts, C as runtimeQueueDequeuesTotal, D as startupCommandGateQueueDepth, E as startupCommandGateEnqueuesTotal, F as WORKTREE_BRANCH_PREFIX, G as compactTraceAttributes, H as resolveAutoFeatureBranchName, I as buildTemporaryWorktreeBranchName, J as RuntimeMode$1, K as outcomeFromExit, L as dedupeRemoteBranchesWithLocalMatches, M as withMetrics, N as LocalDiagnosticsMetrics, O as startupCommandGateQueueHighWater, P as LocalDiagnosticsMetricsLive, Q as resolveStaticDir, R as detectSourceControlProviderFromGitRemoteUrl, S as runtimeQueueDepth, T as runtimeQueueHighWater, U as sanitizeBranchFragment, V as normalizeGitRemoteUrl, W as sanitizeFeatureBranchName, X as deriveServerPaths, Y as ServerConfig, Z as ensureServerDirectories, _ as providerTurnDuration, a as orchestrationCommandAckDuration, b as rpcRequestDuration, c as orchestrationEventsProcessedTotal, d as providerRuntimeEventsTotal, f as providerSessionsTotal, g as providerStartupQueueWaitDuration, h as providerStartupQueueHighWater, i as metricAttributes, j as terminalSessionsTotal, k as startupCommandGateQueueWaitDuration, l as providerEventLogRecordsDroppedTotal, m as providerStartupQueueDepth, n as gitCommandsTotal, o as orchestrationCommandDuration, p as providerStartupAdmissionTotal, q as DEFAULT_PORT, r as increment, s as orchestrationCommandsTotal, t as gitCommandDuration, u as providerMetricAttributes, v as providerTurnMetricAttributes, w as runtimeQueueEnqueuesTotal, x as rpcRequestsTotal, y as providerTurnsTotal, z as isTemporaryWorktreeBranch } from "./Metrics-6Xj17Se3.mjs";
|
|
5
|
+
import { a as makeForgejoDiscovery, c as sourceBranch, d as firstNonEmptyLine, f as probeSourceControlProvider, h as layer$19, i as makeBitbucketDiscovery, m as VcsProcess, n as githubDiscovery, o as SourceControlProvider, p as refineUnknownRemoteProvider, r as gitlabDiscovery, s as parseSourceControlOwnerRef, t as azureDevOpsDiscovery, u as detailFromCause } from "./SourceControlProviderDiscoveryCatalog-Zk11tJoL.mjs";
|
|
6
6
|
import { n as detectSourceControlProviderFromRemoteUrl, r as getChangeRequestTerminologyForKind } from "./sourceControl-iWG-m4wE.mjs";
|
|
7
7
|
import * as NodeRuntime from "@effect/platform-node/NodeRuntime";
|
|
8
8
|
import * as NodeServices from "@effect/platform-node/NodeServices";
|
|
@@ -31,10 +31,10 @@ import sharp from "sharp";
|
|
|
31
31
|
import { RpcSerialization, RpcServer } from "effect/unstable/rpc";
|
|
32
32
|
import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
|
|
33
33
|
import * as Semaphore$1 from "effect/Semaphore";
|
|
34
|
+
import * as Random$1 from "effect/Random";
|
|
34
35
|
import "effect/PlatformError";
|
|
35
36
|
import * as SqlClient from "effect/unstable/sql/SqlClient";
|
|
36
37
|
import * as Migrator from "effect/unstable/sql/Migrator";
|
|
37
|
-
import * as Random$1 from "effect/Random";
|
|
38
38
|
import fsPromises, { open, realpath } from "node:fs/promises";
|
|
39
39
|
import * as Context$1 from "effect/Context";
|
|
40
40
|
import "effect/Scope";
|
|
@@ -46,8 +46,8 @@ import * as Ref$1 from "effect/Ref";
|
|
|
46
46
|
import * as Stream$1 from "effect/Stream";
|
|
47
47
|
import * as SchemaIssue$1 from "effect/SchemaIssue";
|
|
48
48
|
import * as Sink$1 from "effect/Sink";
|
|
49
|
-
import { clamp } from "effect/Number";
|
|
50
49
|
import * as SqlSchema from "effect/unstable/sql/SqlSchema";
|
|
50
|
+
import { clamp } from "effect/Number";
|
|
51
51
|
import { pathToFileURL } from "node:url";
|
|
52
52
|
import { parsePatchFiles } from "@pierre/diffs";
|
|
53
53
|
import { monitorEventLoopDelay } from "node:perf_hooks";
|
|
@@ -1629,6 +1629,388 @@ const makeProviderMaintenanceCommandCoordinator = Effect.fn("makeProviderMainten
|
|
|
1629
1629
|
return { withCommandLock };
|
|
1630
1630
|
});
|
|
1631
1631
|
//#endregion
|
|
1632
|
+
//#region src/atomicWrite.ts
|
|
1633
|
+
const writeFileStringAtomically = (input) => Effect.scoped(Effect.gen(function* () {
|
|
1634
|
+
const fs = yield* FileSystem.FileSystem;
|
|
1635
|
+
const path = yield* Path.Path;
|
|
1636
|
+
const tempFileId = yield* Random$1.nextUUIDv4;
|
|
1637
|
+
const targetDirectory = path.dirname(input.filePath);
|
|
1638
|
+
yield* fs.makeDirectory(targetDirectory, { recursive: true });
|
|
1639
|
+
const tempDirectory = yield* fs.makeTempDirectoryScoped({
|
|
1640
|
+
directory: targetDirectory,
|
|
1641
|
+
prefix: `${path.basename(input.filePath)}.`
|
|
1642
|
+
});
|
|
1643
|
+
const tempPath = path.join(tempDirectory, `${tempFileId}.tmp`);
|
|
1644
|
+
yield* fs.writeFileString(tempPath, input.contents);
|
|
1645
|
+
yield* fs.rename(tempPath, input.filePath);
|
|
1646
|
+
}));
|
|
1647
|
+
//#endregion
|
|
1648
|
+
//#region src/auth/Services/ServerSecretStore.ts
|
|
1649
|
+
var SecretStoreError = class extends Data.TaggedError("SecretStoreError") {};
|
|
1650
|
+
var ServerSecretStore = class extends Context.Service()("ryco/auth/Services/ServerSecretStore") {};
|
|
1651
|
+
//#endregion
|
|
1652
|
+
//#region src/auth/Layers/ServerSecretStore.ts
|
|
1653
|
+
const makeServerSecretStore = Effect.gen(function* () {
|
|
1654
|
+
const fileSystem = yield* FileSystem.FileSystem;
|
|
1655
|
+
const path = yield* Path.Path;
|
|
1656
|
+
const serverConfig = yield* ServerConfig;
|
|
1657
|
+
yield* fileSystem.makeDirectory(serverConfig.secretsDir, { recursive: true });
|
|
1658
|
+
yield* fileSystem.chmod(serverConfig.secretsDir, 448).pipe(Effect.mapError((cause) => new SecretStoreError({
|
|
1659
|
+
message: `Failed to secure secrets directory ${serverConfig.secretsDir}.`,
|
|
1660
|
+
cause
|
|
1661
|
+
})));
|
|
1662
|
+
const resolveSecretPath = (name) => path.join(serverConfig.secretsDir, `${name}.bin`);
|
|
1663
|
+
const ensureSecretDirectory = (secretPath) => {
|
|
1664
|
+
const directory = path.dirname(secretPath);
|
|
1665
|
+
return fileSystem.makeDirectory(directory, { recursive: true }).pipe(Effect.flatMap(() => fileSystem.chmod(directory, 448)));
|
|
1666
|
+
};
|
|
1667
|
+
const isPlatformError = (u) => Predicate.isTagged(u, "PlatformError");
|
|
1668
|
+
const get = (name) => fileSystem.readFile(resolveSecretPath(name)).pipe(Effect.map((bytes) => Uint8Array.from(bytes)), Effect.catch((cause) => cause.reason._tag === "NotFound" ? Effect.succeed(null) : Effect.fail(new SecretStoreError({
|
|
1669
|
+
message: `Failed to read secret ${name}.`,
|
|
1670
|
+
cause
|
|
1671
|
+
}))));
|
|
1672
|
+
const set = (name, value) => {
|
|
1673
|
+
const secretPath = resolveSecretPath(name);
|
|
1674
|
+
const tempPath = `${secretPath}.${Crypto.randomUUID()}.tmp`;
|
|
1675
|
+
return Effect.gen(function* () {
|
|
1676
|
+
yield* ensureSecretDirectory(secretPath);
|
|
1677
|
+
yield* fileSystem.writeFile(tempPath, value);
|
|
1678
|
+
yield* fileSystem.chmod(tempPath, 384);
|
|
1679
|
+
yield* fileSystem.rename(tempPath, secretPath);
|
|
1680
|
+
yield* fileSystem.chmod(secretPath, 384);
|
|
1681
|
+
}).pipe(Effect.catch((cause) => fileSystem.remove(tempPath).pipe(Effect.ignore, Effect.flatMap(() => Effect.fail(new SecretStoreError({
|
|
1682
|
+
message: `Failed to persist secret ${name}.`,
|
|
1683
|
+
cause
|
|
1684
|
+
}))))));
|
|
1685
|
+
};
|
|
1686
|
+
const create = (name, value) => {
|
|
1687
|
+
const secretPath = resolveSecretPath(name);
|
|
1688
|
+
return Effect.scoped(Effect.gen(function* () {
|
|
1689
|
+
yield* ensureSecretDirectory(secretPath);
|
|
1690
|
+
const file = yield* fileSystem.open(secretPath, {
|
|
1691
|
+
flag: "wx",
|
|
1692
|
+
mode: 384
|
|
1693
|
+
});
|
|
1694
|
+
yield* file.writeAll(value);
|
|
1695
|
+
yield* file.sync;
|
|
1696
|
+
yield* fileSystem.chmod(secretPath, 384);
|
|
1697
|
+
})).pipe(Effect.mapError((cause) => new SecretStoreError({
|
|
1698
|
+
message: `Failed to persist secret ${name}.`,
|
|
1699
|
+
cause
|
|
1700
|
+
})));
|
|
1701
|
+
};
|
|
1702
|
+
const getOrCreateRandom = (name, bytes) => get(name).pipe(Effect.flatMap((existing) => {
|
|
1703
|
+
if (existing) return Effect.succeed(existing);
|
|
1704
|
+
const generated = Crypto.randomBytes(bytes);
|
|
1705
|
+
return create(name, generated).pipe(Effect.as(Uint8Array.from(generated)), Effect.catchTag("SecretStoreError", (error) => isPlatformError(error.cause) && error.cause.reason._tag === "AlreadyExists" ? get(name).pipe(Effect.flatMap((created) => created !== null ? Effect.succeed(created) : Effect.fail(new SecretStoreError({ message: `Failed to read secret ${name} after concurrent creation.` })))) : Effect.fail(error)));
|
|
1706
|
+
}));
|
|
1707
|
+
const remove = (name) => fileSystem.remove(resolveSecretPath(name)).pipe(Effect.catch((cause) => cause.reason._tag === "NotFound" ? Effect.void : Effect.fail(new SecretStoreError({
|
|
1708
|
+
message: `Failed to remove secret ${name}.`,
|
|
1709
|
+
cause
|
|
1710
|
+
}))));
|
|
1711
|
+
return {
|
|
1712
|
+
get,
|
|
1713
|
+
set,
|
|
1714
|
+
getOrCreateRandom,
|
|
1715
|
+
remove
|
|
1716
|
+
};
|
|
1717
|
+
});
|
|
1718
|
+
const ServerSecretStoreLive = Layer.effect(ServerSecretStore, makeServerSecretStore);
|
|
1719
|
+
//#endregion
|
|
1720
|
+
//#region src/serverSettings.ts
|
|
1721
|
+
/**
|
|
1722
|
+
* ServerSettings - Server-authoritative settings service.
|
|
1723
|
+
*
|
|
1724
|
+
* Owns persistence, validation, and change notification of settings that affect
|
|
1725
|
+
* server-side behavior (binary paths, streaming mode, env mode, custom models,
|
|
1726
|
+
* text generation model selection).
|
|
1727
|
+
*
|
|
1728
|
+
* Follows the same pattern as `keybindings.ts`: JSON file + Cache + PubSub +
|
|
1729
|
+
* Semaphore + FileSystem.watch for concurrency and external edit detection.
|
|
1730
|
+
*
|
|
1731
|
+
* @module ServerSettings
|
|
1732
|
+
*/
|
|
1733
|
+
const textEncoder$2 = new TextEncoder();
|
|
1734
|
+
const textDecoder$2 = new TextDecoder();
|
|
1735
|
+
function providerEnvironmentSecretName(input) {
|
|
1736
|
+
return `provider-env-${Buffer.from(input.instanceId, "utf8").toString("base64url")}-${Buffer.from(input.name, "utf8").toString("base64url")}`;
|
|
1737
|
+
}
|
|
1738
|
+
function redactProviderEnvironmentVariable(variable) {
|
|
1739
|
+
if (!variable.sensitive) {
|
|
1740
|
+
const { valueRedacted: _omit, ...rest } = variable;
|
|
1741
|
+
return rest;
|
|
1742
|
+
}
|
|
1743
|
+
return {
|
|
1744
|
+
...variable,
|
|
1745
|
+
value: "",
|
|
1746
|
+
...variable.value.length > 0 || variable.valueRedacted ? { valueRedacted: true } : {}
|
|
1747
|
+
};
|
|
1748
|
+
}
|
|
1749
|
+
function redactServerSettingsForClient(settings) {
|
|
1750
|
+
const providerInstances = Object.fromEntries(Object.entries(settings.providerInstances).map(([instanceId, instance]) => [instanceId, instance.environment ? {
|
|
1751
|
+
...instance,
|
|
1752
|
+
environment: instance.environment.map(redactProviderEnvironmentVariable)
|
|
1753
|
+
} : instance]));
|
|
1754
|
+
return {
|
|
1755
|
+
...settings,
|
|
1756
|
+
providerInstances
|
|
1757
|
+
};
|
|
1758
|
+
}
|
|
1759
|
+
var ServerSettingsService = class ServerSettingsService extends Context.Service()("ryco/serverSettings/ServerSettingsService") {
|
|
1760
|
+
static layerTest = (overrides = {}) => Layer.effect(ServerSettingsService, Effect.gen(function* () {
|
|
1761
|
+
const currentSettingsRef = yield* Ref.make(deepMerge(DEFAULT_SERVER_SETTINGS, overrides));
|
|
1762
|
+
return {
|
|
1763
|
+
start: Effect.void,
|
|
1764
|
+
ready: Effect.void,
|
|
1765
|
+
getSettings: Ref.get(currentSettingsRef),
|
|
1766
|
+
updateSettings: (patch) => Ref.get(currentSettingsRef).pipe(Effect.flatMap((currentSettings) => Schema.decodeEffect(ServerSettings)(applyServerSettingsPatch(currentSettings, patch)).pipe(Effect.mapError((cause) => new ServerSettingsError({
|
|
1767
|
+
settingsPath: "<memory>",
|
|
1768
|
+
detail: `failed to normalize server settings: ${SchemaIssue.makeFormatterDefault()(cause.issue)}`,
|
|
1769
|
+
cause
|
|
1770
|
+
})))), Effect.tap((nextSettings) => Ref.set(currentSettingsRef, nextSettings))),
|
|
1771
|
+
streamChanges: Stream.empty
|
|
1772
|
+
};
|
|
1773
|
+
}));
|
|
1774
|
+
};
|
|
1775
|
+
const ServerSettingsJson = fromLenientJson(ServerSettings);
|
|
1776
|
+
const getLegacyProviderSettings = (settings, provider) => settings.providers[provider];
|
|
1777
|
+
/**
|
|
1778
|
+
* Ensure the `textGenerationModelSelection` points to an enabled provider.
|
|
1779
|
+
* If the selected provider is disabled, fall back to the first enabled
|
|
1780
|
+
* provider with its default model. This is applied at read-time so the
|
|
1781
|
+
* persisted preference is preserved for when a provider is re-enabled.
|
|
1782
|
+
*/
|
|
1783
|
+
function resolveTextGenerationProvider(settings) {
|
|
1784
|
+
const selection = settings.textGenerationModelSelection;
|
|
1785
|
+
const instanceConfig = settings.providerInstances[selection.instanceId];
|
|
1786
|
+
if (instanceConfig !== void 0) return instanceConfig.enabled ?? true ? settings : fallbackTextGenerationProvider(settings);
|
|
1787
|
+
if (isProviderDriverKind(selection.instanceId) && getLegacyProviderSettings(settings, selection.instanceId)?.enabled) return settings;
|
|
1788
|
+
return fallbackTextGenerationProvider(settings);
|
|
1789
|
+
}
|
|
1790
|
+
function fallbackTextGenerationProvider(settings) {
|
|
1791
|
+
const fallbackEntry = Object.entries(settings.providers).find(([, provider]) => provider.enabled);
|
|
1792
|
+
const fallback = fallbackEntry ? ProviderDriverKind.make(fallbackEntry[0]) : void 0;
|
|
1793
|
+
if (!fallback) return settings;
|
|
1794
|
+
return {
|
|
1795
|
+
...settings,
|
|
1796
|
+
textGenerationModelSelection: {
|
|
1797
|
+
instanceId: ProviderInstanceId.make(fallback),
|
|
1798
|
+
model: DEFAULT_GIT_TEXT_GENERATION_MODEL_BY_PROVIDER[fallback] ?? "gpt-5.4-mini"
|
|
1799
|
+
}
|
|
1800
|
+
};
|
|
1801
|
+
}
|
|
1802
|
+
const ATOMIC_SETTINGS_KEYS = new Set(["textGenerationModelSelection"]);
|
|
1803
|
+
function stripDefaultServerSettings(current, defaults) {
|
|
1804
|
+
if (Array.isArray(current) || Array.isArray(defaults)) return Equal.equals(current, defaults) ? void 0 : current;
|
|
1805
|
+
if (current !== null && defaults !== null && typeof current === "object" && typeof defaults === "object") {
|
|
1806
|
+
const currentRecord = current;
|
|
1807
|
+
const defaultsRecord = defaults;
|
|
1808
|
+
const next = {};
|
|
1809
|
+
for (const key of Object.keys(currentRecord)) if (ATOMIC_SETTINGS_KEYS.has(key)) {
|
|
1810
|
+
if (!Equal.equals(currentRecord[key], defaultsRecord[key])) next[key] = currentRecord[key];
|
|
1811
|
+
} else {
|
|
1812
|
+
const stripped = stripDefaultServerSettings(currentRecord[key], defaultsRecord[key]);
|
|
1813
|
+
if (stripped !== void 0) next[key] = stripped;
|
|
1814
|
+
}
|
|
1815
|
+
return Object.keys(next).length > 0 ? next : void 0;
|
|
1816
|
+
}
|
|
1817
|
+
return Object.is(current, defaults) ? void 0 : current;
|
|
1818
|
+
}
|
|
1819
|
+
const makeServerSettings = Effect.gen(function* () {
|
|
1820
|
+
const { settingsPath } = yield* ServerConfig;
|
|
1821
|
+
const fs = yield* FileSystem.FileSystem;
|
|
1822
|
+
const pathService = yield* Path.Path;
|
|
1823
|
+
const secretStore = yield* ServerSecretStore;
|
|
1824
|
+
const writeSemaphore = yield* Semaphore$1.make(1);
|
|
1825
|
+
const cacheKey = "settings";
|
|
1826
|
+
const changesPubSub = yield* PubSub.unbounded();
|
|
1827
|
+
const startedRef = yield* Ref.make(false);
|
|
1828
|
+
const startedDeferred = yield* Deferred.make();
|
|
1829
|
+
const watcherScope = yield* Scope.make("sequential");
|
|
1830
|
+
yield* Effect.addFinalizer(() => Scope.close(watcherScope, Exit.void));
|
|
1831
|
+
const emitChange = (settings) => PubSub.publish(changesPubSub, settings).pipe(Effect.asVoid);
|
|
1832
|
+
const readConfigExists = fs.exists(settingsPath).pipe(Effect.mapError((cause) => new ServerSettingsError({
|
|
1833
|
+
settingsPath,
|
|
1834
|
+
detail: "failed to check settings file existence",
|
|
1835
|
+
cause
|
|
1836
|
+
})));
|
|
1837
|
+
const readRawConfig = fs.readFileString(settingsPath).pipe(Effect.mapError((cause) => new ServerSettingsError({
|
|
1838
|
+
settingsPath,
|
|
1839
|
+
detail: "failed to read settings file",
|
|
1840
|
+
cause
|
|
1841
|
+
})));
|
|
1842
|
+
const loadSettingsFromDisk = Effect.gen(function* () {
|
|
1843
|
+
if (!(yield* readConfigExists)) return DEFAULT_SERVER_SETTINGS;
|
|
1844
|
+
const raw = yield* readRawConfig;
|
|
1845
|
+
const decoded = Schema.decodeUnknownExit(ServerSettingsJson)(raw);
|
|
1846
|
+
if (decoded._tag === "Failure") {
|
|
1847
|
+
yield* Effect.logWarning("failed to parse settings.json, using defaults", {
|
|
1848
|
+
path: settingsPath,
|
|
1849
|
+
issues: Cause.pretty(decoded.cause)
|
|
1850
|
+
});
|
|
1851
|
+
return DEFAULT_SERVER_SETTINGS;
|
|
1852
|
+
}
|
|
1853
|
+
return decoded.value;
|
|
1854
|
+
});
|
|
1855
|
+
const settingsCache = yield* Cache.make({
|
|
1856
|
+
capacity: 1,
|
|
1857
|
+
lookup: () => loadSettingsFromDisk
|
|
1858
|
+
});
|
|
1859
|
+
const getSettingsFromCache = Cache.get(settingsCache, cacheKey);
|
|
1860
|
+
const toSettingsError = (detail, cause) => new ServerSettingsError({
|
|
1861
|
+
settingsPath,
|
|
1862
|
+
detail,
|
|
1863
|
+
cause
|
|
1864
|
+
});
|
|
1865
|
+
const materializeProviderEnvironmentSecrets = (settings) => Effect.gen(function* () {
|
|
1866
|
+
const providerInstances = { ...settings.providerInstances };
|
|
1867
|
+
for (const [instanceId, instance] of Object.entries(settings.providerInstances)) {
|
|
1868
|
+
if (!instance.environment) continue;
|
|
1869
|
+
const environment = [];
|
|
1870
|
+
for (const variable of instance.environment) {
|
|
1871
|
+
if (!variable.sensitive || !variable.valueRedacted) {
|
|
1872
|
+
environment.push(variable);
|
|
1873
|
+
continue;
|
|
1874
|
+
}
|
|
1875
|
+
const secret = yield* secretStore.get(providerEnvironmentSecretName({
|
|
1876
|
+
instanceId,
|
|
1877
|
+
name: variable.name
|
|
1878
|
+
})).pipe(Effect.mapError((cause) => toSettingsError(`failed to read sensitive environment variable ${variable.name}`, cause)));
|
|
1879
|
+
environment.push({
|
|
1880
|
+
...variable,
|
|
1881
|
+
value: secret ? textDecoder$2.decode(secret) : ""
|
|
1882
|
+
});
|
|
1883
|
+
}
|
|
1884
|
+
providerInstances[instanceId] = {
|
|
1885
|
+
...instance,
|
|
1886
|
+
environment
|
|
1887
|
+
};
|
|
1888
|
+
}
|
|
1889
|
+
return {
|
|
1890
|
+
...settings,
|
|
1891
|
+
providerInstances
|
|
1892
|
+
};
|
|
1893
|
+
});
|
|
1894
|
+
const persistProviderEnvironmentSecrets = (current, next) => Effect.gen(function* () {
|
|
1895
|
+
const providerInstances = { ...next.providerInstances };
|
|
1896
|
+
const nextSecretKeys = /* @__PURE__ */ new Set();
|
|
1897
|
+
for (const [instanceId, instance] of Object.entries(next.providerInstances)) {
|
|
1898
|
+
if (!instance.environment) continue;
|
|
1899
|
+
const environment = [];
|
|
1900
|
+
for (const variable of instance.environment) {
|
|
1901
|
+
const secretName = providerEnvironmentSecretName({
|
|
1902
|
+
instanceId,
|
|
1903
|
+
name: variable.name
|
|
1904
|
+
});
|
|
1905
|
+
if (!variable.sensitive) {
|
|
1906
|
+
yield* secretStore.remove(secretName).pipe(Effect.mapError((cause) => toSettingsError(`failed to remove environment secret ${variable.name}`, cause)));
|
|
1907
|
+
environment.push(redactProviderEnvironmentVariable(variable));
|
|
1908
|
+
continue;
|
|
1909
|
+
}
|
|
1910
|
+
nextSecretKeys.add(secretName);
|
|
1911
|
+
if (!variable.valueRedacted) {
|
|
1912
|
+
if (variable.value.length > 0) {
|
|
1913
|
+
yield* secretStore.set(secretName, textEncoder$2.encode(variable.value)).pipe(Effect.mapError((cause) => toSettingsError(`failed to persist environment secret ${variable.name}`, cause)));
|
|
1914
|
+
environment.push({
|
|
1915
|
+
...variable,
|
|
1916
|
+
value: "",
|
|
1917
|
+
valueRedacted: true
|
|
1918
|
+
});
|
|
1919
|
+
} else {
|
|
1920
|
+
yield* secretStore.remove(secretName).pipe(Effect.mapError((cause) => toSettingsError(`failed to remove environment secret ${variable.name}`, cause)));
|
|
1921
|
+
const { valueRedacted: _omit, ...rest } = variable;
|
|
1922
|
+
environment.push(rest);
|
|
1923
|
+
}
|
|
1924
|
+
continue;
|
|
1925
|
+
}
|
|
1926
|
+
environment.push(redactProviderEnvironmentVariable(variable));
|
|
1927
|
+
}
|
|
1928
|
+
providerInstances[instanceId] = {
|
|
1929
|
+
...instance,
|
|
1930
|
+
environment
|
|
1931
|
+
};
|
|
1932
|
+
}
|
|
1933
|
+
for (const [instanceId, instance] of Object.entries(current.providerInstances)) for (const variable of instance.environment ?? []) {
|
|
1934
|
+
if (!variable.sensitive) continue;
|
|
1935
|
+
const secretName = providerEnvironmentSecretName({
|
|
1936
|
+
instanceId,
|
|
1937
|
+
name: variable.name
|
|
1938
|
+
});
|
|
1939
|
+
if (nextSecretKeys.has(secretName)) continue;
|
|
1940
|
+
yield* secretStore.remove(secretName).pipe(Effect.mapError((cause) => toSettingsError(`failed to remove stale environment secret ${variable.name}`, cause)));
|
|
1941
|
+
}
|
|
1942
|
+
return {
|
|
1943
|
+
...next,
|
|
1944
|
+
providerInstances
|
|
1945
|
+
};
|
|
1946
|
+
});
|
|
1947
|
+
const writeSettingsAtomically = (settings) => {
|
|
1948
|
+
const sparseSettings = stripDefaultServerSettings(settings, DEFAULT_SERVER_SETTINGS) ?? {};
|
|
1949
|
+
return writeFileStringAtomically({
|
|
1950
|
+
filePath: settingsPath,
|
|
1951
|
+
contents: `${JSON.stringify(sparseSettings, null, 2)}\n`
|
|
1952
|
+
}).pipe(Effect.provideService(FileSystem.FileSystem, fs), Effect.provideService(Path.Path, pathService), Effect.mapError((cause) => new ServerSettingsError({
|
|
1953
|
+
settingsPath,
|
|
1954
|
+
detail: "failed to write settings file",
|
|
1955
|
+
cause
|
|
1956
|
+
})));
|
|
1957
|
+
};
|
|
1958
|
+
const revalidateAndEmit = writeSemaphore.withPermits(1)(Effect.gen(function* () {
|
|
1959
|
+
yield* Cache.invalidate(settingsCache, cacheKey);
|
|
1960
|
+
yield* emitChange(yield* getSettingsFromCache);
|
|
1961
|
+
}));
|
|
1962
|
+
const startWatcher = Effect.gen(function* () {
|
|
1963
|
+
const settingsDir = pathService.dirname(settingsPath);
|
|
1964
|
+
const settingsFile = pathService.basename(settingsPath);
|
|
1965
|
+
const settingsPathResolved = pathService.resolve(settingsPath);
|
|
1966
|
+
yield* fs.makeDirectory(settingsDir, { recursive: true }).pipe(Effect.mapError((cause) => new ServerSettingsError({
|
|
1967
|
+
settingsPath,
|
|
1968
|
+
detail: "failed to prepare settings directory",
|
|
1969
|
+
cause
|
|
1970
|
+
})));
|
|
1971
|
+
const revalidateAndEmitSafely = revalidateAndEmit.pipe(Effect.ignoreCause({ log: true }));
|
|
1972
|
+
const debouncedSettingsEvents = fs.watch(settingsDir).pipe(Stream.filter((event) => {
|
|
1973
|
+
return event.path === settingsFile || event.path === settingsPath || pathService.resolve(settingsDir, event.path) === settingsPathResolved;
|
|
1974
|
+
}), Stream.debounce(Duration.millis(100)));
|
|
1975
|
+
yield* Stream.runForEach(debouncedSettingsEvents, () => revalidateAndEmitSafely).pipe(Effect.ignoreCause({ log: true }), Effect.forkIn(watcherScope), Effect.asVoid);
|
|
1976
|
+
});
|
|
1977
|
+
return {
|
|
1978
|
+
start: Effect.gen(function* () {
|
|
1979
|
+
if (!(yield* Ref.modify(startedRef, (started) => [!started, true]))) return yield* Deferred.await(startedDeferred);
|
|
1980
|
+
const startup = Effect.gen(function* () {
|
|
1981
|
+
yield* startWatcher;
|
|
1982
|
+
yield* Cache.invalidate(settingsCache, cacheKey);
|
|
1983
|
+
yield* getSettingsFromCache;
|
|
1984
|
+
});
|
|
1985
|
+
const startupExit = yield* Effect.exit(startup);
|
|
1986
|
+
if (startupExit._tag === "Failure") {
|
|
1987
|
+
yield* Deferred.failCause(startedDeferred, startupExit.cause).pipe(Effect.orDie);
|
|
1988
|
+
return yield* Effect.failCause(startupExit.cause);
|
|
1989
|
+
}
|
|
1990
|
+
yield* Deferred.succeed(startedDeferred, void 0).pipe(Effect.orDie);
|
|
1991
|
+
}),
|
|
1992
|
+
ready: Deferred.await(startedDeferred),
|
|
1993
|
+
getSettings: getSettingsFromCache.pipe(Effect.flatMap(materializeProviderEnvironmentSecrets), Effect.map(resolveTextGenerationProvider)),
|
|
1994
|
+
updateSettings: (patch) => writeSemaphore.withPermits(1)(Effect.gen(function* () {
|
|
1995
|
+
const current = yield* getSettingsFromCache;
|
|
1996
|
+
const nextPersisted = yield* persistProviderEnvironmentSecrets(current, applyServerSettingsPatch(current, patch));
|
|
1997
|
+
const next = yield* Schema.decodeEffect(ServerSettings)(nextPersisted).pipe(Effect.mapError((cause) => new ServerSettingsError({
|
|
1998
|
+
settingsPath: "<memory>",
|
|
1999
|
+
detail: `failed to normalize server settings: ${SchemaIssue.makeFormatterDefault()(cause.issue)}`,
|
|
2000
|
+
cause
|
|
2001
|
+
})));
|
|
2002
|
+
yield* writeSettingsAtomically(next);
|
|
2003
|
+
yield* Cache.set(settingsCache, cacheKey, next);
|
|
2004
|
+
yield* emitChange(next);
|
|
2005
|
+
return resolveTextGenerationProvider(yield* materializeProviderEnvironmentSecrets(next));
|
|
2006
|
+
})),
|
|
2007
|
+
get streamChanges() {
|
|
2008
|
+
return Stream.fromPubSub(changesPubSub).pipe(Stream.mapEffect((settings) => materializeProviderEnvironmentSecrets(settings).pipe(Effect.catch((error) => Effect.logWarning("failed to materialize provider environment secrets", { detail: error.detail }).pipe(Effect.as(settings))))), Stream.map(resolveTextGenerationProvider));
|
|
2009
|
+
}
|
|
2010
|
+
};
|
|
2011
|
+
});
|
|
2012
|
+
const ServerSettingsLive = Layer.effect(ServerSettingsService, makeServerSettings).pipe(Layer.provide(ServerSecretStoreLive));
|
|
2013
|
+
//#endregion
|
|
1632
2014
|
//#region src/provider/cliVersion.ts
|
|
1633
2015
|
const CLI_VERSION_NUMBER_SEGMENT = /^\d+$/;
|
|
1634
2016
|
function normalizeCliVersion(version) {
|
|
@@ -1929,7 +2311,8 @@ const resolveLatestProviderVersion = Effect.fn("resolveLatestProviderVersion")(f
|
|
|
1929
2311
|
});
|
|
1930
2312
|
const enrichProviderSnapshotWithVersionAdvisory = Effect.fn("enrichProviderSnapshotWithVersionAdvisory")(function* (snapshot, maintenanceCapabilities) {
|
|
1931
2313
|
const capabilities = maintenanceCapabilities ?? makeManualProviderMaintenanceCapabilities$1(snapshot.driver);
|
|
1932
|
-
|
|
2314
|
+
const { enableProviderUpdateChecks } = yield* (yield* ServerSettingsService).getSettings.pipe(Effect.orElseSucceed(() => DEFAULT_SERVER_SETTINGS));
|
|
2315
|
+
if (!enableProviderUpdateChecks || !snapshot.enabled || !snapshot.installed || !snapshot.version) return {
|
|
1933
2316
|
...snapshot,
|
|
1934
2317
|
versionAdvisory: createProviderVersionAdvisory({
|
|
1935
2318
|
driver: snapshot.driver,
|
|
@@ -2024,6 +2407,7 @@ const make$21 = Effect.fn("ProviderMaintenanceRunner.make")(function* () {
|
|
|
2024
2407
|
const providerRegistry = yield* ProviderRegistry;
|
|
2025
2408
|
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
|
|
2026
2409
|
const httpClient = yield* HttpClient.HttpClient;
|
|
2410
|
+
const serverSettings = yield* ServerSettingsService;
|
|
2027
2411
|
const runMaintenanceCommand = (command, args) => runProviderMaintenanceCommandWithSpawner({
|
|
2028
2412
|
spawner,
|
|
2029
2413
|
command,
|
|
@@ -2042,7 +2426,7 @@ const make$21 = Effect.fn("ProviderMaintenanceRunner.make")(function* () {
|
|
|
2042
2426
|
providers,
|
|
2043
2427
|
verifiedProviders: []
|
|
2044
2428
|
});
|
|
2045
|
-
return Effect.forEach(refreshedProviders, (refreshedProvider) => enrichProviderSnapshotWithVersionAdvisory(refreshedProvider, maintenanceCapabilities).pipe(Effect.provideService(HttpClient.HttpClient, httpClient)), { concurrency: "unbounded" }).pipe(Effect.map((verifiedProviders) => ({
|
|
2429
|
+
return Effect.forEach(refreshedProviders, (refreshedProvider) => enrichProviderSnapshotWithVersionAdvisory(refreshedProvider, maintenanceCapabilities).pipe(Effect.provideService(HttpClient.HttpClient, httpClient), Effect.provideService(ServerSettingsService, serverSettings)), { concurrency: "unbounded" }).pipe(Effect.map((verifiedProviders) => ({
|
|
2046
2430
|
providers,
|
|
2047
2431
|
verifiedProviders
|
|
2048
2432
|
})), Effect.catchCause((cause) => Effect.logWarning("Provider post-update version verification failed", {
|
|
@@ -2132,78 +2516,6 @@ const make$21 = Effect.fn("ProviderMaintenanceRunner.make")(function* () {
|
|
|
2132
2516
|
});
|
|
2133
2517
|
const layer$18 = Layer.effect(ProviderMaintenanceRunner, make$21());
|
|
2134
2518
|
//#endregion
|
|
2135
|
-
//#region src/auth/Services/ServerSecretStore.ts
|
|
2136
|
-
var SecretStoreError = class extends Data.TaggedError("SecretStoreError") {};
|
|
2137
|
-
var ServerSecretStore = class extends Context.Service()("ryco/auth/Services/ServerSecretStore") {};
|
|
2138
|
-
//#endregion
|
|
2139
|
-
//#region src/auth/Layers/ServerSecretStore.ts
|
|
2140
|
-
const makeServerSecretStore = Effect.gen(function* () {
|
|
2141
|
-
const fileSystem = yield* FileSystem.FileSystem;
|
|
2142
|
-
const path = yield* Path.Path;
|
|
2143
|
-
const serverConfig = yield* ServerConfig;
|
|
2144
|
-
yield* fileSystem.makeDirectory(serverConfig.secretsDir, { recursive: true });
|
|
2145
|
-
yield* fileSystem.chmod(serverConfig.secretsDir, 448).pipe(Effect.mapError((cause) => new SecretStoreError({
|
|
2146
|
-
message: `Failed to secure secrets directory ${serverConfig.secretsDir}.`,
|
|
2147
|
-
cause
|
|
2148
|
-
})));
|
|
2149
|
-
const resolveSecretPath = (name) => path.join(serverConfig.secretsDir, `${name}.bin`);
|
|
2150
|
-
const ensureSecretDirectory = (secretPath) => {
|
|
2151
|
-
const directory = path.dirname(secretPath);
|
|
2152
|
-
return fileSystem.makeDirectory(directory, { recursive: true }).pipe(Effect.flatMap(() => fileSystem.chmod(directory, 448)));
|
|
2153
|
-
};
|
|
2154
|
-
const isPlatformError = (u) => Predicate.isTagged(u, "PlatformError");
|
|
2155
|
-
const get = (name) => fileSystem.readFile(resolveSecretPath(name)).pipe(Effect.map((bytes) => Uint8Array.from(bytes)), Effect.catch((cause) => cause.reason._tag === "NotFound" ? Effect.succeed(null) : Effect.fail(new SecretStoreError({
|
|
2156
|
-
message: `Failed to read secret ${name}.`,
|
|
2157
|
-
cause
|
|
2158
|
-
}))));
|
|
2159
|
-
const set = (name, value) => {
|
|
2160
|
-
const secretPath = resolveSecretPath(name);
|
|
2161
|
-
const tempPath = `${secretPath}.${Crypto.randomUUID()}.tmp`;
|
|
2162
|
-
return Effect.gen(function* () {
|
|
2163
|
-
yield* ensureSecretDirectory(secretPath);
|
|
2164
|
-
yield* fileSystem.writeFile(tempPath, value);
|
|
2165
|
-
yield* fileSystem.chmod(tempPath, 384);
|
|
2166
|
-
yield* fileSystem.rename(tempPath, secretPath);
|
|
2167
|
-
yield* fileSystem.chmod(secretPath, 384);
|
|
2168
|
-
}).pipe(Effect.catch((cause) => fileSystem.remove(tempPath).pipe(Effect.ignore, Effect.flatMap(() => Effect.fail(new SecretStoreError({
|
|
2169
|
-
message: `Failed to persist secret ${name}.`,
|
|
2170
|
-
cause
|
|
2171
|
-
}))))));
|
|
2172
|
-
};
|
|
2173
|
-
const create = (name, value) => {
|
|
2174
|
-
const secretPath = resolveSecretPath(name);
|
|
2175
|
-
return Effect.scoped(Effect.gen(function* () {
|
|
2176
|
-
yield* ensureSecretDirectory(secretPath);
|
|
2177
|
-
const file = yield* fileSystem.open(secretPath, {
|
|
2178
|
-
flag: "wx",
|
|
2179
|
-
mode: 384
|
|
2180
|
-
});
|
|
2181
|
-
yield* file.writeAll(value);
|
|
2182
|
-
yield* file.sync;
|
|
2183
|
-
yield* fileSystem.chmod(secretPath, 384);
|
|
2184
|
-
})).pipe(Effect.mapError((cause) => new SecretStoreError({
|
|
2185
|
-
message: `Failed to persist secret ${name}.`,
|
|
2186
|
-
cause
|
|
2187
|
-
})));
|
|
2188
|
-
};
|
|
2189
|
-
const getOrCreateRandom = (name, bytes) => get(name).pipe(Effect.flatMap((existing) => {
|
|
2190
|
-
if (existing) return Effect.succeed(existing);
|
|
2191
|
-
const generated = Crypto.randomBytes(bytes);
|
|
2192
|
-
return create(name, generated).pipe(Effect.as(Uint8Array.from(generated)), Effect.catchTag("SecretStoreError", (error) => isPlatformError(error.cause) && error.cause.reason._tag === "AlreadyExists" ? get(name).pipe(Effect.flatMap((created) => created !== null ? Effect.succeed(created) : Effect.fail(new SecretStoreError({ message: `Failed to read secret ${name} after concurrent creation.` })))) : Effect.fail(error)));
|
|
2193
|
-
}));
|
|
2194
|
-
const remove = (name) => fileSystem.remove(resolveSecretPath(name)).pipe(Effect.catch((cause) => cause.reason._tag === "NotFound" ? Effect.void : Effect.fail(new SecretStoreError({
|
|
2195
|
-
message: `Failed to remove secret ${name}.`,
|
|
2196
|
-
cause
|
|
2197
|
-
}))));
|
|
2198
|
-
return {
|
|
2199
|
-
get,
|
|
2200
|
-
set,
|
|
2201
|
-
getOrCreateRandom,
|
|
2202
|
-
remove
|
|
2203
|
-
};
|
|
2204
|
-
});
|
|
2205
|
-
const ServerSecretStoreLive = Layer.effect(ServerSecretStore, makeServerSecretStore);
|
|
2206
|
-
//#endregion
|
|
2207
2519
|
//#region src/persistence/Errors.ts
|
|
2208
2520
|
var PersistenceSqlError = class extends Schema.TaggedErrorClass()("PersistenceSqlError", {
|
|
2209
2521
|
operation: Schema.String,
|
|
@@ -3897,6 +4209,35 @@ var _040_ProjectionThreadsProjectUpdatedAtIndex_default = Effect$1.gen(function*
|
|
|
3897
4209
|
`;
|
|
3898
4210
|
});
|
|
3899
4211
|
//#endregion
|
|
4212
|
+
//#region src/persistence/Migrations/041_ProjectionThreadsSubagentNesting.ts
|
|
4213
|
+
var _041_ProjectionThreadsSubagentNesting_default = Effect$1.gen(function* () {
|
|
4214
|
+
const sql = yield* SqlClient.SqlClient;
|
|
4215
|
+
const columns = yield* sql`
|
|
4216
|
+
PRAGMA table_info(projection_threads)
|
|
4217
|
+
`;
|
|
4218
|
+
const columnNames = new Set(columns.map((column) => column.name));
|
|
4219
|
+
if (!columnNames.has("thread_kind")) yield* sql`
|
|
4220
|
+
ALTER TABLE projection_threads
|
|
4221
|
+
ADD COLUMN thread_kind TEXT NOT NULL DEFAULT 'normal'
|
|
4222
|
+
`;
|
|
4223
|
+
if (!columnNames.has("visibility")) yield* sql`
|
|
4224
|
+
ALTER TABLE projection_threads
|
|
4225
|
+
ADD COLUMN visibility TEXT NOT NULL DEFAULT 'normal'
|
|
4226
|
+
`;
|
|
4227
|
+
if (!columnNames.has("parent_thread_id")) yield* sql`
|
|
4228
|
+
ALTER TABLE projection_threads
|
|
4229
|
+
ADD COLUMN parent_thread_id TEXT
|
|
4230
|
+
`;
|
|
4231
|
+
if (!columnNames.has("parent_subagent_id")) yield* sql`
|
|
4232
|
+
ALTER TABLE projection_threads
|
|
4233
|
+
ADD COLUMN parent_subagent_id TEXT
|
|
4234
|
+
`;
|
|
4235
|
+
yield* sql`
|
|
4236
|
+
CREATE INDEX IF NOT EXISTS idx_projection_threads_parent_thread
|
|
4237
|
+
ON projection_threads(parent_thread_id, created_at, thread_id)
|
|
4238
|
+
`;
|
|
4239
|
+
});
|
|
4240
|
+
//#endregion
|
|
3900
4241
|
//#region src/persistence/Migrations.ts
|
|
3901
4242
|
/**
|
|
3902
4243
|
* MigrationsLive - Migration runner with inline loader
|
|
@@ -4117,6 +4458,11 @@ const migrationEntries = [
|
|
|
4117
4458
|
40,
|
|
4118
4459
|
"ProjectionThreadsProjectUpdatedAtIndex",
|
|
4119
4460
|
_040_ProjectionThreadsProjectUpdatedAtIndex_default
|
|
4461
|
+
],
|
|
4462
|
+
[
|
|
4463
|
+
41,
|
|
4464
|
+
"ProjectionThreadsSubagentNesting",
|
|
4465
|
+
_041_ProjectionThreadsSubagentNesting_default
|
|
4120
4466
|
]
|
|
4121
4467
|
];
|
|
4122
4468
|
const makeMigrationLoader = (throughId) => Migrator.fromRecord(Object.fromEntries(migrationEntries.filter(([id]) => throughId === void 0 || id <= throughId).map(([id, name, migration]) => [`${id}_${name}`, migration])));
|
|
@@ -4186,6 +4532,45 @@ const repairProjectionTokenModeColumns = Effect$1.fn("repairProjectionTokenModeC
|
|
|
4186
4532
|
yield* Effect$1.log("Repaired projection_thread_sessions.token_mode column");
|
|
4187
4533
|
}
|
|
4188
4534
|
});
|
|
4535
|
+
const repairProjectionThreadSubagentNestingColumns = Effect$1.fn("repairProjectionThreadSubagentNestingColumns")(function* () {
|
|
4536
|
+
const sql = yield* SqlClient.SqlClient;
|
|
4537
|
+
if ((yield* sql`
|
|
4538
|
+
SELECT name FROM sqlite_master
|
|
4539
|
+
WHERE type = 'table' AND name = 'projection_threads'
|
|
4540
|
+
`).length === 0) return;
|
|
4541
|
+
const columns = yield* sql`
|
|
4542
|
+
PRAGMA table_info(projection_threads)
|
|
4543
|
+
`;
|
|
4544
|
+
const columnNames = new Set(columns.map((column) => column.name));
|
|
4545
|
+
if (!columnNames.has("thread_kind")) {
|
|
4546
|
+
yield* sql`
|
|
4547
|
+
ALTER TABLE projection_threads
|
|
4548
|
+
ADD COLUMN thread_kind TEXT NOT NULL DEFAULT 'normal'
|
|
4549
|
+
`;
|
|
4550
|
+
yield* Effect$1.log("Repaired projection_threads.thread_kind column");
|
|
4551
|
+
}
|
|
4552
|
+
if (!columnNames.has("visibility")) {
|
|
4553
|
+
yield* sql`
|
|
4554
|
+
ALTER TABLE projection_threads
|
|
4555
|
+
ADD COLUMN visibility TEXT NOT NULL DEFAULT 'normal'
|
|
4556
|
+
`;
|
|
4557
|
+
yield* Effect$1.log("Repaired projection_threads.visibility column");
|
|
4558
|
+
}
|
|
4559
|
+
if (!columnNames.has("parent_thread_id")) {
|
|
4560
|
+
yield* sql`
|
|
4561
|
+
ALTER TABLE projection_threads
|
|
4562
|
+
ADD COLUMN parent_thread_id TEXT
|
|
4563
|
+
`;
|
|
4564
|
+
yield* Effect$1.log("Repaired projection_threads.parent_thread_id column");
|
|
4565
|
+
}
|
|
4566
|
+
if (!columnNames.has("parent_subagent_id")) {
|
|
4567
|
+
yield* sql`
|
|
4568
|
+
ALTER TABLE projection_threads
|
|
4569
|
+
ADD COLUMN parent_subagent_id TEXT
|
|
4570
|
+
`;
|
|
4571
|
+
yield* Effect$1.log("Repaired projection_threads.parent_subagent_id column");
|
|
4572
|
+
}
|
|
4573
|
+
});
|
|
4189
4574
|
/**
|
|
4190
4575
|
* Run all pending migrations.
|
|
4191
4576
|
*
|
|
@@ -4202,6 +4587,7 @@ const runMigrations = Effect$1.fn("runMigrations")(function* ({ toMigrationInclu
|
|
|
4202
4587
|
if (toMigrationInclusive === void 0 || toMigrationInclusive >= 31) yield* repairProjectionWorktreeTitleColumn();
|
|
4203
4588
|
if (toMigrationInclusive === void 0 || toMigrationInclusive >= 34) yield* repairProjectionProjectAvatarColumns();
|
|
4204
4589
|
if (toMigrationInclusive === void 0 || toMigrationInclusive >= 35) yield* repairProjectionTokenModeColumns();
|
|
4590
|
+
if (toMigrationInclusive === void 0 || toMigrationInclusive >= 41) yield* repairProjectionThreadSubagentNestingColumns();
|
|
4205
4591
|
yield* Effect$1.log("Migrations ran successfully").pipe(Effect$1.annotateLogs({ migrations: executedMigrations.map(([id, name]) => `${id}_${name}`) }));
|
|
4206
4592
|
return executedMigrations;
|
|
4207
4593
|
});
|
|
@@ -4210,7 +4596,7 @@ Layer$1.effectDiscard(runMigrations());
|
|
|
4210
4596
|
//#region src/persistence/Layers/Sqlite.ts
|
|
4211
4597
|
const defaultSqliteClientLoaders = {
|
|
4212
4598
|
bun: () => import("@effect/sql-sqlite-bun/SqliteClient"),
|
|
4213
|
-
node: () => import("./NodeSqliteClient-
|
|
4599
|
+
node: () => import("./NodeSqliteClient-DdTjpAko.mjs")
|
|
4214
4600
|
};
|
|
4215
4601
|
const makeRuntimeSqliteLayer = Effect.fn("makeRuntimeSqliteLayer")(function* (config) {
|
|
4216
4602
|
const loader = defaultSqliteClientLoaders[process.versions.bun !== void 0 ? "bun" : "node"];
|
|
@@ -4995,7 +5381,7 @@ Schema.Struct({
|
|
|
4995
5381
|
var ProjectAtlassianLinkRepository = class extends Context.Service()("ryco/persistence/Services/ProjectAtlassianLinks/ProjectAtlassianLinkRepository") {};
|
|
4996
5382
|
//#endregion
|
|
4997
5383
|
//#region src/atlassian/AtlassianConnectionService.ts
|
|
4998
|
-
const textEncoder$
|
|
5384
|
+
const textEncoder$1 = new TextEncoder();
|
|
4999
5385
|
var AtlassianConnectionService = class extends Context.Service()("ryco/atlassian/AtlassianConnectionService") {};
|
|
5000
5386
|
function atlassianError(operation, detail, cause) {
|
|
5001
5387
|
return new AtlassianConnectionError({
|
|
@@ -5123,7 +5509,7 @@ const make$19 = Effect.fn("makeAtlassianConnectionService")(function* () {
|
|
|
5123
5509
|
createdAt,
|
|
5124
5510
|
updatedAt: createdAt
|
|
5125
5511
|
};
|
|
5126
|
-
return secretStore.set(manualBitbucketTokenSecretName(connectionId), textEncoder$
|
|
5512
|
+
return secretStore.set(manualBitbucketTokenSecretName(connectionId), textEncoder$1.encode(input.token)).pipe(Effect.flatMap(() => connections.upsert(record)), cleanupSecretOnFailure(manualBitbucketTokenSecretName(connectionId)), Effect.as(toSummary(record)), Effect.mapError(mapError$1("atlassian.saveManualBitbucketToken", "Failed to save the Bitbucket token.")));
|
|
5127
5513
|
},
|
|
5128
5514
|
saveManualJiraToken: (input) => {
|
|
5129
5515
|
const createdAt = nowIso$2();
|
|
@@ -5159,7 +5545,7 @@ const make$19 = Effect.fn("makeAtlassianConnectionService")(function* () {
|
|
|
5159
5545
|
avatarUrl: null,
|
|
5160
5546
|
updatedAt: createdAt
|
|
5161
5547
|
};
|
|
5162
|
-
return secretStore.set(manualJiraTokenSecretName(connectionId), textEncoder$
|
|
5548
|
+
return secretStore.set(manualJiraTokenSecretName(connectionId), textEncoder$1.encode(input.token)).pipe(Effect.flatMap(() => connections.upsert(record)), Effect.flatMap(() => resources.upsertForConnection({
|
|
5163
5549
|
connectionId,
|
|
5164
5550
|
resources: [resource]
|
|
5165
5551
|
})), cleanupSecretOnFailure(manualJiraTokenSecretName(connectionId)), Effect.as(toSummary(record)), Effect.mapError(mapError$1("atlassian.saveManualJiraToken", "Failed to save the Jira API token.")));
|
|
@@ -5275,6 +5661,11 @@ const NON_REPOSITORY_STATUS_DETAILS = Object.freeze({
|
|
|
5275
5661
|
behindCount: 0,
|
|
5276
5662
|
aheadOfDefaultCount: 0
|
|
5277
5663
|
});
|
|
5664
|
+
const emptyDiffTotals = () => ({
|
|
5665
|
+
files: [],
|
|
5666
|
+
insertions: 0,
|
|
5667
|
+
deletions: 0
|
|
5668
|
+
});
|
|
5278
5669
|
var StatusRemoteRefreshCacheKey = class extends Data.Class {};
|
|
5279
5670
|
function parseBranchAb(value) {
|
|
5280
5671
|
const match = value.match(/^\+(\d+)\s+-(\d+)$/);
|
|
@@ -5921,6 +6312,31 @@ const makeGitVcsDriverCore = Effect.fn("makeGitVcsDriverCore")(function* (option
|
|
|
5921
6312
|
const parsed = Number.parseInt(result.stdout.trim(), 10);
|
|
5922
6313
|
return Number.isFinite(parsed) ? Math.max(0, parsed) : 0;
|
|
5923
6314
|
});
|
|
6315
|
+
const readCommittedAgainstBase = Effect.fn("readCommittedAgainstBase")(function* (cwd, refName) {
|
|
6316
|
+
const baseRef = yield* resolveBaseBranchForNoUpstream(cwd, refName).pipe(Effect.catch(() => Effect.succeed(null)));
|
|
6317
|
+
if (!baseRef) return emptyDiffTotals();
|
|
6318
|
+
const result = yield* executeGit("GitVcsDriver.readCommittedAgainstBase.diff", cwd, [
|
|
6319
|
+
"diff",
|
|
6320
|
+
"--numstat",
|
|
6321
|
+
`${baseRef}...HEAD`
|
|
6322
|
+
], { allowNonZeroExit: true });
|
|
6323
|
+
if (result.exitCode !== 0) return emptyDiffTotals();
|
|
6324
|
+
let insertions = 0;
|
|
6325
|
+
let deletions = 0;
|
|
6326
|
+
return {
|
|
6327
|
+
files: parseNumstatEntries(result.stdout).map((entry) => {
|
|
6328
|
+
insertions += entry.insertions;
|
|
6329
|
+
deletions += entry.deletions;
|
|
6330
|
+
return {
|
|
6331
|
+
path: entry.path,
|
|
6332
|
+
insertions: entry.insertions,
|
|
6333
|
+
deletions: entry.deletions
|
|
6334
|
+
};
|
|
6335
|
+
}).toSorted((a, b) => a.path.localeCompare(b.path)),
|
|
6336
|
+
insertions,
|
|
6337
|
+
deletions
|
|
6338
|
+
};
|
|
6339
|
+
});
|
|
5924
6340
|
const readBranchRecency = Effect.fn("readBranchRecency")(function* (cwd) {
|
|
5925
6341
|
const branchRecency = yield* executeGit("GitVcsDriver.readBranchRecency", cwd, [
|
|
5926
6342
|
"for-each-ref",
|
|
@@ -6039,6 +6455,7 @@ const makeGitVcsDriverCore = Effect.fn("makeGitVcsDriverCore")(function* (option
|
|
|
6039
6455
|
});
|
|
6040
6456
|
}
|
|
6041
6457
|
files.sort((a, b) => a.path.localeCompare(b.path));
|
|
6458
|
+
const committed = refName && !isDefaultBranch ? yield* readCommittedAgainstBase(cwd, refName).pipe(Effect.catch(() => Effect.succeed(emptyDiffTotals()))) : void 0;
|
|
6042
6459
|
return {
|
|
6043
6460
|
isRepo: true,
|
|
6044
6461
|
hasOriginRemote: hasPrimaryRemote,
|
|
@@ -6051,6 +6468,7 @@ const makeGitVcsDriverCore = Effect.fn("makeGitVcsDriverCore")(function* (option
|
|
|
6051
6468
|
insertions,
|
|
6052
6469
|
deletions
|
|
6053
6470
|
},
|
|
6471
|
+
...committed ? { committed } : {},
|
|
6054
6472
|
hasUpstream: upstreamRef !== null,
|
|
6055
6473
|
aheadCount,
|
|
6056
6474
|
behindCount,
|
|
@@ -6071,6 +6489,7 @@ const makeGitVcsDriverCore = Effect.fn("makeGitVcsDriverCore")(function* (option
|
|
|
6071
6489
|
refName: details.branch,
|
|
6072
6490
|
hasWorkingTreeChanges: details.hasWorkingTreeChanges,
|
|
6073
6491
|
workingTree: details.workingTree,
|
|
6492
|
+
...details.committed ? { committed: details.committed } : {},
|
|
6074
6493
|
hasUpstream: details.hasUpstream,
|
|
6075
6494
|
aheadCount: details.aheadCount,
|
|
6076
6495
|
behindCount: details.behindCount,
|
|
@@ -6963,7 +7382,7 @@ const layer$13 = Layer.effect(VcsDriverRegistry, make$16()).pipe(Layer.provide(l
|
|
|
6963
7382
|
//#endregion
|
|
6964
7383
|
//#region src/sourceControl/BitbucketApi.ts
|
|
6965
7384
|
const DEFAULT_API_BASE_URL = "https://api.bitbucket.org/2.0";
|
|
6966
|
-
const textDecoder$
|
|
7385
|
+
const textDecoder$1 = new TextDecoder();
|
|
6967
7386
|
const BitbucketApiEnvConfig = Config.all({
|
|
6968
7387
|
baseUrl: Config.string("RYCO_BITBUCKET_API_BASE_URL").pipe(Config.withDefault(DEFAULT_API_BASE_URL)),
|
|
6969
7388
|
accessToken: Config.string("RYCO_BITBUCKET_ACCESS_TOKEN").pipe(Config.option),
|
|
@@ -7308,7 +7727,7 @@ const make$15 = Effect.fn("makeBitbucketApi")(function* () {
|
|
|
7308
7727
|
cause
|
|
7309
7728
|
})));
|
|
7310
7729
|
if (!tokenBytes || tokenBytes.length === 0) continue;
|
|
7311
|
-
const token = textDecoder$
|
|
7730
|
+
const token = textDecoder$1.decode(tokenBytes).trim();
|
|
7312
7731
|
if (!token) continue;
|
|
7313
7732
|
return {
|
|
7314
7733
|
source: "stored",
|
|
@@ -9268,6 +9687,7 @@ function workflowRunsEndpoint(input) {
|
|
|
9268
9687
|
const params = new URLSearchParams();
|
|
9269
9688
|
params.set("per_page", String(workflowRunLimit(input.limit)));
|
|
9270
9689
|
if (input.headSha?.trim()) params.set("head_sha", input.headSha.trim());
|
|
9690
|
+
else if (input.branch?.trim()) params.set("branch", input.branch.trim());
|
|
9271
9691
|
return `repos/{owner}/{repo}/actions/runs?${params.toString()}`;
|
|
9272
9692
|
}
|
|
9273
9693
|
function isWorkflowRerunStateError(error) {
|
|
@@ -10532,26 +10952,26 @@ const make$11 = Effect.fn("makeSourceControlProviderRegistry")(function* () {
|
|
|
10532
10952
|
const azureDevOpsCli = yield* AzureDevOpsCli;
|
|
10533
10953
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
10534
10954
|
const github = yield* makeLazyProvider("github", Effect.tryPromise({
|
|
10535
|
-
try: () => import("./GitHubSourceControlProvider-
|
|
10955
|
+
try: () => import("./GitHubSourceControlProvider-Kf4rrBTF.mjs"),
|
|
10536
10956
|
catch: (cause) => providerLoadError("github", cause)
|
|
10537
10957
|
}).pipe(Effect.flatMap((module) => module.make()), Effect.provideService(GitHubCli, githubCli), Effect.provideService(FileSystem.FileSystem, fileSystem)));
|
|
10538
10958
|
const gitlab = yield* makeLazyProvider("gitlab", Effect.tryPromise({
|
|
10539
|
-
try: () => import("./GitLabSourceControlProvider-
|
|
10959
|
+
try: () => import("./GitLabSourceControlProvider-Ygppeftk.mjs"),
|
|
10540
10960
|
catch: (cause) => providerLoadError("gitlab", cause)
|
|
10541
10961
|
}).pipe(Effect.flatMap((module) => module.make()), Effect.provideService(GitLabCli, gitlabCli)));
|
|
10542
10962
|
const bitbucket = yield* makeLazyProvider("bitbucket", Effect.tryPromise({
|
|
10543
|
-
try: () => import("./BitbucketSourceControlProvider-
|
|
10963
|
+
try: () => import("./BitbucketSourceControlProvider-CcAb4IgH.mjs"),
|
|
10544
10964
|
catch: (cause) => providerLoadError("bitbucket", cause)
|
|
10545
10965
|
}).pipe(Effect.flatMap((module) => module.make()), Effect.provideService(BitbucketApi, bitbucketApi)), {
|
|
10546
10966
|
searchRepositories: true,
|
|
10547
10967
|
cloneAuthentication: true
|
|
10548
10968
|
});
|
|
10549
10969
|
const forgejo = yield* makeLazyProvider("forgejo", Effect.tryPromise({
|
|
10550
|
-
try: () => import("./ForgejoSourceControlProvider-
|
|
10970
|
+
try: () => import("./ForgejoSourceControlProvider-3cFD7SqY.mjs"),
|
|
10551
10971
|
catch: (cause) => providerLoadError("forgejo", cause)
|
|
10552
10972
|
}).pipe(Effect.flatMap((module) => module.make()), Effect.provideService(ForgejoApi, forgejoApi)));
|
|
10553
10973
|
const azureDevOps = yield* makeLazyProvider("azure-devops", Effect.tryPromise({
|
|
10554
|
-
try: () => import("./AzureDevOpsSourceControlProvider-
|
|
10974
|
+
try: () => import("./AzureDevOpsSourceControlProvider-B5vb4DOU.mjs"),
|
|
10555
10975
|
catch: (cause) => providerLoadError("azure-devops", cause)
|
|
10556
10976
|
}).pipe(Effect.flatMap((module) => module.make()), Effect.provideService(AzureDevOpsCli, azureDevOpsCli)));
|
|
10557
10977
|
const bitbucketDiscovery = makeBitbucketDiscovery(bitbucketApi);
|
|
@@ -10674,22 +11094,6 @@ var CheckpointDiffQuery = class extends Context.Service()("ryco/checkpointing/Se
|
|
|
10674
11094
|
//#region src/diagnostics/Services/Diagnostics.ts
|
|
10675
11095
|
var Diagnostics = class extends Context.Service()("ryco/diagnostics/Services/Diagnostics") {};
|
|
10676
11096
|
//#endregion
|
|
10677
|
-
//#region src/atomicWrite.ts
|
|
10678
|
-
const writeFileStringAtomically = (input) => Effect.scoped(Effect.gen(function* () {
|
|
10679
|
-
const fs = yield* FileSystem.FileSystem;
|
|
10680
|
-
const path = yield* Path.Path;
|
|
10681
|
-
const tempFileId = yield* Random$1.nextUUIDv4;
|
|
10682
|
-
const targetDirectory = path.dirname(input.filePath);
|
|
10683
|
-
yield* fs.makeDirectory(targetDirectory, { recursive: true });
|
|
10684
|
-
const tempDirectory = yield* fs.makeTempDirectoryScoped({
|
|
10685
|
-
directory: targetDirectory,
|
|
10686
|
-
prefix: `${path.basename(input.filePath)}.`
|
|
10687
|
-
});
|
|
10688
|
-
const tempPath = path.join(tempDirectory, `${tempFileId}.tmp`);
|
|
10689
|
-
yield* fs.writeFileString(tempPath, input.contents);
|
|
10690
|
-
yield* fs.rename(tempPath, input.filePath);
|
|
10691
|
-
}));
|
|
10692
|
-
//#endregion
|
|
10693
11097
|
//#region ../../packages/shared/src/keybindings.ts
|
|
10694
11098
|
const DEFAULT_KEYBINDINGS = [
|
|
10695
11099
|
{
|
|
@@ -10760,6 +11164,11 @@ const DEFAULT_KEYBINDINGS = [
|
|
|
10760
11164
|
key: "mod+o",
|
|
10761
11165
|
command: "editor.openFavorite"
|
|
10762
11166
|
},
|
|
11167
|
+
{
|
|
11168
|
+
key: "mod+f",
|
|
11169
|
+
command: "thread.find",
|
|
11170
|
+
when: "!terminalFocus"
|
|
11171
|
+
},
|
|
10763
11172
|
{
|
|
10764
11173
|
key: "mod+shift+[",
|
|
10765
11174
|
command: "thread.previous"
|
|
@@ -11581,14 +11990,7 @@ const ClientRequest__PluginsMigration = Schema$1.Struct({
|
|
|
11581
11990
|
marketplaceName: Schema$1.String,
|
|
11582
11991
|
pluginNames: Schema$1.Array(Schema$1.String)
|
|
11583
11992
|
});
|
|
11584
|
-
const ClientRequest__ReasoningEffort = Schema$1.
|
|
11585
|
-
"none",
|
|
11586
|
-
"minimal",
|
|
11587
|
-
"low",
|
|
11588
|
-
"medium",
|
|
11589
|
-
"high",
|
|
11590
|
-
"xhigh"
|
|
11591
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
11993
|
+
const ClientRequest__ReasoningEffort = Schema$1.String.check(Schema$1.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
11592
11994
|
const ClientRequest__ReasoningItemContent = Schema$1.Union([Schema$1.Struct({
|
|
11593
11995
|
text: Schema$1.String,
|
|
11594
11996
|
type: Schema$1.Literal("reasoning_text").annotate({ title: "ReasoningTextReasoningItemContentType" })
|
|
@@ -12164,14 +12566,7 @@ const ServerNotification__RateLimitWindow = Schema$1.Struct({
|
|
|
12164
12566
|
windowDurationMins: Schema$1.optionalKey(Schema$1.Union([Schema$1.Number.annotate({ format: "int64" }).check(Schema$1.isInt()), Schema$1.Null]))
|
|
12165
12567
|
});
|
|
12166
12568
|
const ServerNotification__RealtimeConversationVersion = Schema$1.Literals(["v1", "v2"]);
|
|
12167
|
-
const ServerNotification__ReasoningEffort = Schema$1.
|
|
12168
|
-
"none",
|
|
12169
|
-
"minimal",
|
|
12170
|
-
"low",
|
|
12171
|
-
"medium",
|
|
12172
|
-
"high",
|
|
12173
|
-
"xhigh"
|
|
12174
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
12569
|
+
const ServerNotification__ReasoningEffort = Schema$1.String.check(Schema$1.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
12175
12570
|
const ServerNotification__ReasoningSummaryPartAddedNotification = Schema$1.Struct({
|
|
12176
12571
|
itemId: Schema$1.String,
|
|
12177
12572
|
summaryIndex: Schema$1.Number.annotate({ format: "int64" }).check(Schema$1.isInt()),
|
|
@@ -12550,14 +12945,7 @@ const V2ConfigReadResponse__AskForApproval = Schema$1.Union([Schema$1.Literals([
|
|
|
12550
12945
|
skill_approval: Schema$1.optionalKey(Schema$1.Boolean.annotate({ default: false }))
|
|
12551
12946
|
}) }).annotate({ title: "GranularAskForApproval" })], { mode: "oneOf" });
|
|
12552
12947
|
const V2ConfigReadResponse__ForcedLoginMethod = Schema$1.Literals(["chatgpt", "api"]);
|
|
12553
|
-
const V2ConfigReadResponse__ReasoningEffort = Schema$1.
|
|
12554
|
-
"none",
|
|
12555
|
-
"minimal",
|
|
12556
|
-
"low",
|
|
12557
|
-
"medium",
|
|
12558
|
-
"high",
|
|
12559
|
-
"xhigh"
|
|
12560
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
12948
|
+
const V2ConfigReadResponse__ReasoningEffort = Schema$1.String.check(Schema$1.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
12561
12949
|
const V2ConfigReadResponse__ReasoningSummary = Schema$1.Union([Schema$1.Literals([
|
|
12562
12950
|
"auto",
|
|
12563
12951
|
"concise",
|
|
@@ -12875,14 +13263,7 @@ const V2ItemCompletedNotification__PatchChangeKind = Schema$1.Union([
|
|
|
12875
13263
|
type: Schema$1.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
12876
13264
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
12877
13265
|
], { mode: "oneOf" });
|
|
12878
|
-
const V2ItemCompletedNotification__ReasoningEffort = Schema$1.
|
|
12879
|
-
"none",
|
|
12880
|
-
"minimal",
|
|
12881
|
-
"low",
|
|
12882
|
-
"medium",
|
|
12883
|
-
"high",
|
|
12884
|
-
"xhigh"
|
|
12885
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
13266
|
+
const V2ItemCompletedNotification__ReasoningEffort = Schema$1.String.check(Schema$1.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
12886
13267
|
const V2ItemCompletedNotification__TextElement = Schema$1.Struct({
|
|
12887
13268
|
byteRange: Schema$1.Struct({
|
|
12888
13269
|
end: Schema$1.Number.annotate({ format: "uint" }).check(Schema$1.isInt()).check(Schema$1.isGreaterThanOrEqualTo(0)),
|
|
@@ -13070,14 +13451,7 @@ const V2ItemStartedNotification__PatchChangeKind = Schema$1.Union([
|
|
|
13070
13451
|
type: Schema$1.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
13071
13452
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
13072
13453
|
], { mode: "oneOf" });
|
|
13073
|
-
const V2ItemStartedNotification__ReasoningEffort = Schema$1.
|
|
13074
|
-
"none",
|
|
13075
|
-
"minimal",
|
|
13076
|
-
"low",
|
|
13077
|
-
"medium",
|
|
13078
|
-
"high",
|
|
13079
|
-
"xhigh"
|
|
13080
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
13454
|
+
const V2ItemStartedNotification__ReasoningEffort = Schema$1.String.check(Schema$1.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
13081
13455
|
const V2ItemStartedNotification__TextElement = Schema$1.Struct({
|
|
13082
13456
|
byteRange: Schema$1.Struct({
|
|
13083
13457
|
end: Schema$1.Number.annotate({ format: "uint" }).check(Schema$1.isInt()).check(Schema$1.isGreaterThanOrEqualTo(0)),
|
|
@@ -13165,14 +13539,7 @@ const V2ModelListResponse__ModelUpgradeInfo = Schema$1.Struct({
|
|
|
13165
13539
|
modelLink: Schema$1.optionalKey(Schema$1.Union([Schema$1.String, Schema$1.Null])),
|
|
13166
13540
|
upgradeCopy: Schema$1.optionalKey(Schema$1.Union([Schema$1.String, Schema$1.Null]))
|
|
13167
13541
|
});
|
|
13168
|
-
const V2ModelListResponse__ReasoningEffort = Schema$1.
|
|
13169
|
-
"none",
|
|
13170
|
-
"minimal",
|
|
13171
|
-
"low",
|
|
13172
|
-
"medium",
|
|
13173
|
-
"high",
|
|
13174
|
-
"xhigh"
|
|
13175
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
13542
|
+
const V2ModelListResponse__ReasoningEffort = Schema$1.String.check(Schema$1.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
13176
13543
|
const V2ModelReroutedNotification__ModelRerouteReason = Schema$1.Literal("highRiskCyberActivity");
|
|
13177
13544
|
const V2PluginInstallParams__AbsolutePathBuf = Schema$1.String.annotate({ description: "A path that is guaranteed to be absolute and normalized (though it is not guaranteed to be canonicalized or exist on the filesystem).\n\nIMPORTANT: When deserializing an `AbsolutePathBuf`, a base path must be set using [AbsolutePathBufGuard::new]. If no base path is set, the deserialization will fail unless the path being deserialized is already absolute." });
|
|
13178
13545
|
const V2PluginInstallResponse__AppSummary = Schema$1.Struct({
|
|
@@ -13355,14 +13722,7 @@ const V2ReviewStartResponse__PatchChangeKind = Schema$1.Union([
|
|
|
13355
13722
|
type: Schema$1.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
13356
13723
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
13357
13724
|
], { mode: "oneOf" });
|
|
13358
|
-
const V2ReviewStartResponse__ReasoningEffort = Schema$1.
|
|
13359
|
-
"none",
|
|
13360
|
-
"minimal",
|
|
13361
|
-
"low",
|
|
13362
|
-
"medium",
|
|
13363
|
-
"high",
|
|
13364
|
-
"xhigh"
|
|
13365
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
13725
|
+
const V2ReviewStartResponse__ReasoningEffort = Schema$1.String.check(Schema$1.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
13366
13726
|
const V2ReviewStartResponse__TextElement = Schema$1.Struct({
|
|
13367
13727
|
byteRange: Schema$1.Struct({
|
|
13368
13728
|
end: Schema$1.Number.annotate({ format: "uint" }).check(Schema$1.isInt()).check(Schema$1.isGreaterThanOrEqualTo(0)),
|
|
@@ -13526,14 +13886,7 @@ const V2ThreadForkResponse__PatchChangeKind = Schema$1.Union([
|
|
|
13526
13886
|
type: Schema$1.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
13527
13887
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
13528
13888
|
], { mode: "oneOf" });
|
|
13529
|
-
const V2ThreadForkResponse__ReasoningEffort = Schema$1.
|
|
13530
|
-
"none",
|
|
13531
|
-
"minimal",
|
|
13532
|
-
"low",
|
|
13533
|
-
"medium",
|
|
13534
|
-
"high",
|
|
13535
|
-
"xhigh"
|
|
13536
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
13889
|
+
const V2ThreadForkResponse__ReasoningEffort = Schema$1.String.check(Schema$1.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
13537
13890
|
const V2ThreadForkResponse__ServiceTier = Schema$1.Literals([
|
|
13538
13891
|
"fast",
|
|
13539
13892
|
"flex",
|
|
@@ -13656,14 +14009,7 @@ const V2ThreadListResponse__PatchChangeKind = Schema$1.Union([
|
|
|
13656
14009
|
type: Schema$1.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
13657
14010
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
13658
14011
|
], { mode: "oneOf" });
|
|
13659
|
-
const V2ThreadListResponse__ReasoningEffort = Schema$1.
|
|
13660
|
-
"none",
|
|
13661
|
-
"minimal",
|
|
13662
|
-
"low",
|
|
13663
|
-
"medium",
|
|
13664
|
-
"high",
|
|
13665
|
-
"xhigh"
|
|
13666
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
14012
|
+
const V2ThreadListResponse__ReasoningEffort = Schema$1.String.check(Schema$1.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
13667
14013
|
const V2ThreadListResponse__TextElement = Schema$1.Struct({
|
|
13668
14014
|
byteRange: Schema$1.Struct({
|
|
13669
14015
|
end: Schema$1.Number.annotate({ format: "uint" }).check(Schema$1.isInt()).check(Schema$1.isGreaterThanOrEqualTo(0)),
|
|
@@ -13772,14 +14118,7 @@ const V2ThreadMetadataUpdateResponse__PatchChangeKind = Schema$1.Union([
|
|
|
13772
14118
|
type: Schema$1.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
13773
14119
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
13774
14120
|
], { mode: "oneOf" });
|
|
13775
|
-
const V2ThreadMetadataUpdateResponse__ReasoningEffort = Schema$1.
|
|
13776
|
-
"none",
|
|
13777
|
-
"minimal",
|
|
13778
|
-
"low",
|
|
13779
|
-
"medium",
|
|
13780
|
-
"high",
|
|
13781
|
-
"xhigh"
|
|
13782
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
14121
|
+
const V2ThreadMetadataUpdateResponse__ReasoningEffort = Schema$1.String.check(Schema$1.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
13783
14122
|
const V2ThreadMetadataUpdateResponse__TextElement = Schema$1.Struct({
|
|
13784
14123
|
byteRange: Schema$1.Struct({
|
|
13785
14124
|
end: Schema$1.Number.annotate({ format: "uint" }).check(Schema$1.isInt()).check(Schema$1.isGreaterThanOrEqualTo(0)),
|
|
@@ -13883,14 +14222,7 @@ const V2ThreadReadResponse__PatchChangeKind = Schema$1.Union([
|
|
|
13883
14222
|
type: Schema$1.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
13884
14223
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
13885
14224
|
], { mode: "oneOf" });
|
|
13886
|
-
const V2ThreadReadResponse__ReasoningEffort = Schema$1.
|
|
13887
|
-
"none",
|
|
13888
|
-
"minimal",
|
|
13889
|
-
"low",
|
|
13890
|
-
"medium",
|
|
13891
|
-
"high",
|
|
13892
|
-
"xhigh"
|
|
13893
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
14225
|
+
const V2ThreadReadResponse__ReasoningEffort = Schema$1.String.check(Schema$1.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
13894
14226
|
const V2ThreadReadResponse__TextElement = Schema$1.Struct({
|
|
13895
14227
|
byteRange: Schema$1.Struct({
|
|
13896
14228
|
end: Schema$1.Number.annotate({ format: "uint" }).check(Schema$1.isInt()).check(Schema$1.isGreaterThanOrEqualTo(0)),
|
|
@@ -14096,14 +14428,7 @@ const V2ThreadResumeResponse__PatchChangeKind = Schema$1.Union([
|
|
|
14096
14428
|
type: Schema$1.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
14097
14429
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
14098
14430
|
], { mode: "oneOf" });
|
|
14099
|
-
const V2ThreadResumeResponse__ReasoningEffort = Schema$1.
|
|
14100
|
-
"none",
|
|
14101
|
-
"minimal",
|
|
14102
|
-
"low",
|
|
14103
|
-
"medium",
|
|
14104
|
-
"high",
|
|
14105
|
-
"xhigh"
|
|
14106
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
14431
|
+
const V2ThreadResumeResponse__ReasoningEffort = Schema$1.String.check(Schema$1.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
14107
14432
|
const V2ThreadResumeResponse__ServiceTier = Schema$1.Literals([
|
|
14108
14433
|
"fast",
|
|
14109
14434
|
"flex",
|
|
@@ -14212,14 +14537,7 @@ const V2ThreadRollbackResponse__PatchChangeKind = Schema$1.Union([
|
|
|
14212
14537
|
type: Schema$1.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
14213
14538
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
14214
14539
|
], { mode: "oneOf" });
|
|
14215
|
-
const V2ThreadRollbackResponse__ReasoningEffort = Schema$1.
|
|
14216
|
-
"none",
|
|
14217
|
-
"minimal",
|
|
14218
|
-
"low",
|
|
14219
|
-
"medium",
|
|
14220
|
-
"high",
|
|
14221
|
-
"xhigh"
|
|
14222
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
14540
|
+
const V2ThreadRollbackResponse__ReasoningEffort = Schema$1.String.check(Schema$1.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
14223
14541
|
const V2ThreadRollbackResponse__TextElement = Schema$1.Struct({
|
|
14224
14542
|
byteRange: Schema$1.Struct({
|
|
14225
14543
|
end: Schema$1.Number.annotate({ format: "uint" }).check(Schema$1.isInt()).check(Schema$1.isGreaterThanOrEqualTo(0)),
|
|
@@ -14323,14 +14641,7 @@ const V2ThreadStartedNotification__PatchChangeKind = Schema$1.Union([
|
|
|
14323
14641
|
type: Schema$1.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
14324
14642
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
14325
14643
|
], { mode: "oneOf" });
|
|
14326
|
-
const V2ThreadStartedNotification__ReasoningEffort = Schema$1.
|
|
14327
|
-
"none",
|
|
14328
|
-
"minimal",
|
|
14329
|
-
"low",
|
|
14330
|
-
"medium",
|
|
14331
|
-
"high",
|
|
14332
|
-
"xhigh"
|
|
14333
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
14644
|
+
const V2ThreadStartedNotification__ReasoningEffort = Schema$1.String.check(Schema$1.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
14334
14645
|
const V2ThreadStartedNotification__TextElement = Schema$1.Struct({
|
|
14335
14646
|
byteRange: Schema$1.Struct({
|
|
14336
14647
|
end: Schema$1.Number.annotate({ format: "uint" }).check(Schema$1.isInt()).check(Schema$1.isGreaterThanOrEqualTo(0)),
|
|
@@ -14475,14 +14786,7 @@ const V2ThreadStartResponse__PatchChangeKind = Schema$1.Union([
|
|
|
14475
14786
|
type: Schema$1.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
14476
14787
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
14477
14788
|
], { mode: "oneOf" });
|
|
14478
|
-
const V2ThreadStartResponse__ReasoningEffort = Schema$1.
|
|
14479
|
-
"none",
|
|
14480
|
-
"minimal",
|
|
14481
|
-
"low",
|
|
14482
|
-
"medium",
|
|
14483
|
-
"high",
|
|
14484
|
-
"xhigh"
|
|
14485
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
14789
|
+
const V2ThreadStartResponse__ReasoningEffort = Schema$1.String.check(Schema$1.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
14486
14790
|
const V2ThreadStartResponse__ServiceTier = Schema$1.Literals([
|
|
14487
14791
|
"fast",
|
|
14488
14792
|
"flex",
|
|
@@ -14594,14 +14898,7 @@ const V2ThreadTurnsListResponse__PatchChangeKind = Schema$1.Union([
|
|
|
14594
14898
|
type: Schema$1.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
14595
14899
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
14596
14900
|
], { mode: "oneOf" });
|
|
14597
|
-
const V2ThreadTurnsListResponse__ReasoningEffort = Schema$1.
|
|
14598
|
-
"none",
|
|
14599
|
-
"minimal",
|
|
14600
|
-
"low",
|
|
14601
|
-
"medium",
|
|
14602
|
-
"high",
|
|
14603
|
-
"xhigh"
|
|
14604
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
14901
|
+
const V2ThreadTurnsListResponse__ReasoningEffort = Schema$1.String.check(Schema$1.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
14605
14902
|
const V2ThreadTurnsListResponse__TextElement = Schema$1.Struct({
|
|
14606
14903
|
byteRange: Schema$1.Struct({
|
|
14607
14904
|
end: Schema$1.Number.annotate({ format: "uint" }).check(Schema$1.isInt()).check(Schema$1.isGreaterThanOrEqualTo(0)),
|
|
@@ -14703,14 +15000,7 @@ const V2ThreadUnarchiveResponse__PatchChangeKind = Schema$1.Union([
|
|
|
14703
15000
|
type: Schema$1.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
14704
15001
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
14705
15002
|
], { mode: "oneOf" });
|
|
14706
|
-
const V2ThreadUnarchiveResponse__ReasoningEffort = Schema$1.
|
|
14707
|
-
"none",
|
|
14708
|
-
"minimal",
|
|
14709
|
-
"low",
|
|
14710
|
-
"medium",
|
|
14711
|
-
"high",
|
|
14712
|
-
"xhigh"
|
|
14713
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
15003
|
+
const V2ThreadUnarchiveResponse__ReasoningEffort = Schema$1.String.check(Schema$1.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
14714
15004
|
const V2ThreadUnarchiveResponse__TextElement = Schema$1.Struct({
|
|
14715
15005
|
byteRange: Schema$1.Struct({
|
|
14716
15006
|
end: Schema$1.Number.annotate({ format: "uint" }).check(Schema$1.isInt()).check(Schema$1.isGreaterThanOrEqualTo(0)),
|
|
@@ -14813,14 +15103,7 @@ const V2TurnCompletedNotification__PatchChangeKind = Schema$1.Union([
|
|
|
14813
15103
|
type: Schema$1.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
14814
15104
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
14815
15105
|
], { mode: "oneOf" });
|
|
14816
|
-
const V2TurnCompletedNotification__ReasoningEffort = Schema$1.
|
|
14817
|
-
"none",
|
|
14818
|
-
"minimal",
|
|
14819
|
-
"low",
|
|
14820
|
-
"medium",
|
|
14821
|
-
"high",
|
|
14822
|
-
"xhigh"
|
|
14823
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
15106
|
+
const V2TurnCompletedNotification__ReasoningEffort = Schema$1.String.check(Schema$1.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
14824
15107
|
const V2TurnCompletedNotification__TextElement = Schema$1.Struct({
|
|
14825
15108
|
byteRange: Schema$1.Struct({
|
|
14826
15109
|
end: Schema$1.Number.annotate({ format: "uint" }).check(Schema$1.isInt()).check(Schema$1.isGreaterThanOrEqualTo(0)),
|
|
@@ -14921,14 +15204,7 @@ const V2TurnStartedNotification__PatchChangeKind = Schema$1.Union([
|
|
|
14921
15204
|
type: Schema$1.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
14922
15205
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
14923
15206
|
], { mode: "oneOf" });
|
|
14924
|
-
const V2TurnStartedNotification__ReasoningEffort = Schema$1.
|
|
14925
|
-
"none",
|
|
14926
|
-
"minimal",
|
|
14927
|
-
"low",
|
|
14928
|
-
"medium",
|
|
14929
|
-
"high",
|
|
14930
|
-
"xhigh"
|
|
14931
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
15207
|
+
const V2TurnStartedNotification__ReasoningEffort = Schema$1.String.check(Schema$1.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
14932
15208
|
const V2TurnStartedNotification__TextElement = Schema$1.Struct({
|
|
14933
15209
|
byteRange: Schema$1.Struct({
|
|
14934
15210
|
end: Schema$1.Number.annotate({ format: "uint" }).check(Schema$1.isInt()).check(Schema$1.isGreaterThanOrEqualTo(0)),
|
|
@@ -14979,14 +15255,7 @@ const V2TurnStartParams__Personality = Schema$1.Literals([
|
|
|
14979
15255
|
"friendly",
|
|
14980
15256
|
"pragmatic"
|
|
14981
15257
|
]);
|
|
14982
|
-
const V2TurnStartParams__ReasoningEffort = Schema$1.
|
|
14983
|
-
"none",
|
|
14984
|
-
"minimal",
|
|
14985
|
-
"low",
|
|
14986
|
-
"medium",
|
|
14987
|
-
"high",
|
|
14988
|
-
"xhigh"
|
|
14989
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
15258
|
+
const V2TurnStartParams__ReasoningEffort = Schema$1.String.check(Schema$1.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
14990
15259
|
const V2TurnStartParams__ReasoningSummary = Schema$1.Union([Schema$1.Literals([
|
|
14991
15260
|
"auto",
|
|
14992
15261
|
"concise",
|
|
@@ -15069,14 +15338,7 @@ const V2TurnStartResponse__PatchChangeKind = Schema$1.Union([
|
|
|
15069
15338
|
type: Schema$1.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
15070
15339
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
15071
15340
|
], { mode: "oneOf" });
|
|
15072
|
-
const V2TurnStartResponse__ReasoningEffort = Schema$1.
|
|
15073
|
-
"none",
|
|
15074
|
-
"minimal",
|
|
15075
|
-
"low",
|
|
15076
|
-
"medium",
|
|
15077
|
-
"high",
|
|
15078
|
-
"xhigh"
|
|
15079
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
15341
|
+
const V2TurnStartResponse__ReasoningEffort = Schema$1.String.check(Schema$1.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
15080
15342
|
const V2TurnStartResponse__TextElement = Schema$1.Struct({
|
|
15081
15343
|
byteRange: Schema$1.Struct({
|
|
15082
15344
|
end: Schema$1.Number.annotate({ format: "uint" }).check(Schema$1.isInt()).check(Schema$1.isGreaterThanOrEqualTo(0)),
|
|
@@ -26075,300 +26337,6 @@ async function runProcess(command, args, options = {}) {
|
|
|
26075
26337
|
});
|
|
26076
26338
|
}
|
|
26077
26339
|
//#endregion
|
|
26078
|
-
//#region src/serverSettings.ts
|
|
26079
|
-
/**
|
|
26080
|
-
* ServerSettings - Server-authoritative settings service.
|
|
26081
|
-
*
|
|
26082
|
-
* Owns persistence, validation, and change notification of settings that affect
|
|
26083
|
-
* server-side behavior (binary paths, streaming mode, env mode, custom models,
|
|
26084
|
-
* text generation model selection).
|
|
26085
|
-
*
|
|
26086
|
-
* Follows the same pattern as `keybindings.ts`: JSON file + Cache + PubSub +
|
|
26087
|
-
* Semaphore + FileSystem.watch for concurrency and external edit detection.
|
|
26088
|
-
*
|
|
26089
|
-
* @module ServerSettings
|
|
26090
|
-
*/
|
|
26091
|
-
const textEncoder$1 = new TextEncoder();
|
|
26092
|
-
const textDecoder$1 = new TextDecoder();
|
|
26093
|
-
function providerEnvironmentSecretName(input) {
|
|
26094
|
-
return `provider-env-${Buffer.from(input.instanceId, "utf8").toString("base64url")}-${Buffer.from(input.name, "utf8").toString("base64url")}`;
|
|
26095
|
-
}
|
|
26096
|
-
function redactProviderEnvironmentVariable(variable) {
|
|
26097
|
-
if (!variable.sensitive) {
|
|
26098
|
-
const { valueRedacted: _omit, ...rest } = variable;
|
|
26099
|
-
return rest;
|
|
26100
|
-
}
|
|
26101
|
-
return {
|
|
26102
|
-
...variable,
|
|
26103
|
-
value: "",
|
|
26104
|
-
...variable.value.length > 0 || variable.valueRedacted ? { valueRedacted: true } : {}
|
|
26105
|
-
};
|
|
26106
|
-
}
|
|
26107
|
-
function redactServerSettingsForClient(settings) {
|
|
26108
|
-
const providerInstances = Object.fromEntries(Object.entries(settings.providerInstances).map(([instanceId, instance]) => [instanceId, instance.environment ? {
|
|
26109
|
-
...instance,
|
|
26110
|
-
environment: instance.environment.map(redactProviderEnvironmentVariable)
|
|
26111
|
-
} : instance]));
|
|
26112
|
-
return {
|
|
26113
|
-
...settings,
|
|
26114
|
-
providerInstances
|
|
26115
|
-
};
|
|
26116
|
-
}
|
|
26117
|
-
var ServerSettingsService = class ServerSettingsService extends Context.Service()("ryco/serverSettings/ServerSettingsService") {
|
|
26118
|
-
static layerTest = (overrides = {}) => Layer.effect(ServerSettingsService, Effect.gen(function* () {
|
|
26119
|
-
const currentSettingsRef = yield* Ref.make(deepMerge(DEFAULT_SERVER_SETTINGS, overrides));
|
|
26120
|
-
return {
|
|
26121
|
-
start: Effect.void,
|
|
26122
|
-
ready: Effect.void,
|
|
26123
|
-
getSettings: Ref.get(currentSettingsRef),
|
|
26124
|
-
updateSettings: (patch) => Ref.get(currentSettingsRef).pipe(Effect.flatMap((currentSettings) => Schema.decodeEffect(ServerSettings)(applyServerSettingsPatch(currentSettings, patch)).pipe(Effect.mapError((cause) => new ServerSettingsError({
|
|
26125
|
-
settingsPath: "<memory>",
|
|
26126
|
-
detail: `failed to normalize server settings: ${SchemaIssue.makeFormatterDefault()(cause.issue)}`,
|
|
26127
|
-
cause
|
|
26128
|
-
})))), Effect.tap((nextSettings) => Ref.set(currentSettingsRef, nextSettings))),
|
|
26129
|
-
streamChanges: Stream.empty
|
|
26130
|
-
};
|
|
26131
|
-
}));
|
|
26132
|
-
};
|
|
26133
|
-
const ServerSettingsJson = fromLenientJson(ServerSettings);
|
|
26134
|
-
const getLegacyProviderSettings = (settings, provider) => settings.providers[provider];
|
|
26135
|
-
/**
|
|
26136
|
-
* Ensure the `textGenerationModelSelection` points to an enabled provider.
|
|
26137
|
-
* If the selected provider is disabled, fall back to the first enabled
|
|
26138
|
-
* provider with its default model. This is applied at read-time so the
|
|
26139
|
-
* persisted preference is preserved for when a provider is re-enabled.
|
|
26140
|
-
*/
|
|
26141
|
-
function resolveTextGenerationProvider(settings) {
|
|
26142
|
-
const selection = settings.textGenerationModelSelection;
|
|
26143
|
-
const instanceConfig = settings.providerInstances[selection.instanceId];
|
|
26144
|
-
if (instanceConfig !== void 0) return instanceConfig.enabled ?? true ? settings : fallbackTextGenerationProvider(settings);
|
|
26145
|
-
if (isProviderDriverKind(selection.instanceId) && getLegacyProviderSettings(settings, selection.instanceId)?.enabled) return settings;
|
|
26146
|
-
return fallbackTextGenerationProvider(settings);
|
|
26147
|
-
}
|
|
26148
|
-
function fallbackTextGenerationProvider(settings) {
|
|
26149
|
-
const fallbackEntry = Object.entries(settings.providers).find(([, provider]) => provider.enabled);
|
|
26150
|
-
const fallback = fallbackEntry ? ProviderDriverKind.make(fallbackEntry[0]) : void 0;
|
|
26151
|
-
if (!fallback) return settings;
|
|
26152
|
-
return {
|
|
26153
|
-
...settings,
|
|
26154
|
-
textGenerationModelSelection: {
|
|
26155
|
-
instanceId: ProviderInstanceId.make(fallback),
|
|
26156
|
-
model: DEFAULT_GIT_TEXT_GENERATION_MODEL_BY_PROVIDER[fallback] ?? "gpt-5.4-mini"
|
|
26157
|
-
}
|
|
26158
|
-
};
|
|
26159
|
-
}
|
|
26160
|
-
const ATOMIC_SETTINGS_KEYS = new Set(["textGenerationModelSelection"]);
|
|
26161
|
-
function stripDefaultServerSettings(current, defaults) {
|
|
26162
|
-
if (Array.isArray(current) || Array.isArray(defaults)) return Equal.equals(current, defaults) ? void 0 : current;
|
|
26163
|
-
if (current !== null && defaults !== null && typeof current === "object" && typeof defaults === "object") {
|
|
26164
|
-
const currentRecord = current;
|
|
26165
|
-
const defaultsRecord = defaults;
|
|
26166
|
-
const next = {};
|
|
26167
|
-
for (const key of Object.keys(currentRecord)) if (ATOMIC_SETTINGS_KEYS.has(key)) {
|
|
26168
|
-
if (!Equal.equals(currentRecord[key], defaultsRecord[key])) next[key] = currentRecord[key];
|
|
26169
|
-
} else {
|
|
26170
|
-
const stripped = stripDefaultServerSettings(currentRecord[key], defaultsRecord[key]);
|
|
26171
|
-
if (stripped !== void 0) next[key] = stripped;
|
|
26172
|
-
}
|
|
26173
|
-
return Object.keys(next).length > 0 ? next : void 0;
|
|
26174
|
-
}
|
|
26175
|
-
return Object.is(current, defaults) ? void 0 : current;
|
|
26176
|
-
}
|
|
26177
|
-
const makeServerSettings = Effect.gen(function* () {
|
|
26178
|
-
const { settingsPath } = yield* ServerConfig;
|
|
26179
|
-
const fs = yield* FileSystem.FileSystem;
|
|
26180
|
-
const pathService = yield* Path.Path;
|
|
26181
|
-
const secretStore = yield* ServerSecretStore;
|
|
26182
|
-
const writeSemaphore = yield* Semaphore$1.make(1);
|
|
26183
|
-
const cacheKey = "settings";
|
|
26184
|
-
const changesPubSub = yield* PubSub.unbounded();
|
|
26185
|
-
const startedRef = yield* Ref.make(false);
|
|
26186
|
-
const startedDeferred = yield* Deferred.make();
|
|
26187
|
-
const watcherScope = yield* Scope.make("sequential");
|
|
26188
|
-
yield* Effect.addFinalizer(() => Scope.close(watcherScope, Exit.void));
|
|
26189
|
-
const emitChange = (settings) => PubSub.publish(changesPubSub, settings).pipe(Effect.asVoid);
|
|
26190
|
-
const readConfigExists = fs.exists(settingsPath).pipe(Effect.mapError((cause) => new ServerSettingsError({
|
|
26191
|
-
settingsPath,
|
|
26192
|
-
detail: "failed to check settings file existence",
|
|
26193
|
-
cause
|
|
26194
|
-
})));
|
|
26195
|
-
const readRawConfig = fs.readFileString(settingsPath).pipe(Effect.mapError((cause) => new ServerSettingsError({
|
|
26196
|
-
settingsPath,
|
|
26197
|
-
detail: "failed to read settings file",
|
|
26198
|
-
cause
|
|
26199
|
-
})));
|
|
26200
|
-
const loadSettingsFromDisk = Effect.gen(function* () {
|
|
26201
|
-
if (!(yield* readConfigExists)) return DEFAULT_SERVER_SETTINGS;
|
|
26202
|
-
const raw = yield* readRawConfig;
|
|
26203
|
-
const decoded = Schema.decodeUnknownExit(ServerSettingsJson)(raw);
|
|
26204
|
-
if (decoded._tag === "Failure") {
|
|
26205
|
-
yield* Effect.logWarning("failed to parse settings.json, using defaults", {
|
|
26206
|
-
path: settingsPath,
|
|
26207
|
-
issues: Cause.pretty(decoded.cause)
|
|
26208
|
-
});
|
|
26209
|
-
return DEFAULT_SERVER_SETTINGS;
|
|
26210
|
-
}
|
|
26211
|
-
return decoded.value;
|
|
26212
|
-
});
|
|
26213
|
-
const settingsCache = yield* Cache.make({
|
|
26214
|
-
capacity: 1,
|
|
26215
|
-
lookup: () => loadSettingsFromDisk
|
|
26216
|
-
});
|
|
26217
|
-
const getSettingsFromCache = Cache.get(settingsCache, cacheKey);
|
|
26218
|
-
const toSettingsError = (detail, cause) => new ServerSettingsError({
|
|
26219
|
-
settingsPath,
|
|
26220
|
-
detail,
|
|
26221
|
-
cause
|
|
26222
|
-
});
|
|
26223
|
-
const materializeProviderEnvironmentSecrets = (settings) => Effect.gen(function* () {
|
|
26224
|
-
const providerInstances = { ...settings.providerInstances };
|
|
26225
|
-
for (const [instanceId, instance] of Object.entries(settings.providerInstances)) {
|
|
26226
|
-
if (!instance.environment) continue;
|
|
26227
|
-
const environment = [];
|
|
26228
|
-
for (const variable of instance.environment) {
|
|
26229
|
-
if (!variable.sensitive || !variable.valueRedacted) {
|
|
26230
|
-
environment.push(variable);
|
|
26231
|
-
continue;
|
|
26232
|
-
}
|
|
26233
|
-
const secret = yield* secretStore.get(providerEnvironmentSecretName({
|
|
26234
|
-
instanceId,
|
|
26235
|
-
name: variable.name
|
|
26236
|
-
})).pipe(Effect.mapError((cause) => toSettingsError(`failed to read sensitive environment variable ${variable.name}`, cause)));
|
|
26237
|
-
environment.push({
|
|
26238
|
-
...variable,
|
|
26239
|
-
value: secret ? textDecoder$1.decode(secret) : ""
|
|
26240
|
-
});
|
|
26241
|
-
}
|
|
26242
|
-
providerInstances[instanceId] = {
|
|
26243
|
-
...instance,
|
|
26244
|
-
environment
|
|
26245
|
-
};
|
|
26246
|
-
}
|
|
26247
|
-
return {
|
|
26248
|
-
...settings,
|
|
26249
|
-
providerInstances
|
|
26250
|
-
};
|
|
26251
|
-
});
|
|
26252
|
-
const persistProviderEnvironmentSecrets = (current, next) => Effect.gen(function* () {
|
|
26253
|
-
const providerInstances = { ...next.providerInstances };
|
|
26254
|
-
const nextSecretKeys = /* @__PURE__ */ new Set();
|
|
26255
|
-
for (const [instanceId, instance] of Object.entries(next.providerInstances)) {
|
|
26256
|
-
if (!instance.environment) continue;
|
|
26257
|
-
const environment = [];
|
|
26258
|
-
for (const variable of instance.environment) {
|
|
26259
|
-
const secretName = providerEnvironmentSecretName({
|
|
26260
|
-
instanceId,
|
|
26261
|
-
name: variable.name
|
|
26262
|
-
});
|
|
26263
|
-
if (!variable.sensitive) {
|
|
26264
|
-
yield* secretStore.remove(secretName).pipe(Effect.mapError((cause) => toSettingsError(`failed to remove environment secret ${variable.name}`, cause)));
|
|
26265
|
-
environment.push(redactProviderEnvironmentVariable(variable));
|
|
26266
|
-
continue;
|
|
26267
|
-
}
|
|
26268
|
-
nextSecretKeys.add(secretName);
|
|
26269
|
-
if (!variable.valueRedacted) {
|
|
26270
|
-
if (variable.value.length > 0) {
|
|
26271
|
-
yield* secretStore.set(secretName, textEncoder$1.encode(variable.value)).pipe(Effect.mapError((cause) => toSettingsError(`failed to persist environment secret ${variable.name}`, cause)));
|
|
26272
|
-
environment.push({
|
|
26273
|
-
...variable,
|
|
26274
|
-
value: "",
|
|
26275
|
-
valueRedacted: true
|
|
26276
|
-
});
|
|
26277
|
-
} else {
|
|
26278
|
-
yield* secretStore.remove(secretName).pipe(Effect.mapError((cause) => toSettingsError(`failed to remove environment secret ${variable.name}`, cause)));
|
|
26279
|
-
const { valueRedacted: _omit, ...rest } = variable;
|
|
26280
|
-
environment.push(rest);
|
|
26281
|
-
}
|
|
26282
|
-
continue;
|
|
26283
|
-
}
|
|
26284
|
-
environment.push(redactProviderEnvironmentVariable(variable));
|
|
26285
|
-
}
|
|
26286
|
-
providerInstances[instanceId] = {
|
|
26287
|
-
...instance,
|
|
26288
|
-
environment
|
|
26289
|
-
};
|
|
26290
|
-
}
|
|
26291
|
-
for (const [instanceId, instance] of Object.entries(current.providerInstances)) for (const variable of instance.environment ?? []) {
|
|
26292
|
-
if (!variable.sensitive) continue;
|
|
26293
|
-
const secretName = providerEnvironmentSecretName({
|
|
26294
|
-
instanceId,
|
|
26295
|
-
name: variable.name
|
|
26296
|
-
});
|
|
26297
|
-
if (nextSecretKeys.has(secretName)) continue;
|
|
26298
|
-
yield* secretStore.remove(secretName).pipe(Effect.mapError((cause) => toSettingsError(`failed to remove stale environment secret ${variable.name}`, cause)));
|
|
26299
|
-
}
|
|
26300
|
-
return {
|
|
26301
|
-
...next,
|
|
26302
|
-
providerInstances
|
|
26303
|
-
};
|
|
26304
|
-
});
|
|
26305
|
-
const writeSettingsAtomically = (settings) => {
|
|
26306
|
-
const sparseSettings = stripDefaultServerSettings(settings, DEFAULT_SERVER_SETTINGS) ?? {};
|
|
26307
|
-
return writeFileStringAtomically({
|
|
26308
|
-
filePath: settingsPath,
|
|
26309
|
-
contents: `${JSON.stringify(sparseSettings, null, 2)}\n`
|
|
26310
|
-
}).pipe(Effect.provideService(FileSystem.FileSystem, fs), Effect.provideService(Path.Path, pathService), Effect.mapError((cause) => new ServerSettingsError({
|
|
26311
|
-
settingsPath,
|
|
26312
|
-
detail: "failed to write settings file",
|
|
26313
|
-
cause
|
|
26314
|
-
})));
|
|
26315
|
-
};
|
|
26316
|
-
const revalidateAndEmit = writeSemaphore.withPermits(1)(Effect.gen(function* () {
|
|
26317
|
-
yield* Cache.invalidate(settingsCache, cacheKey);
|
|
26318
|
-
yield* emitChange(yield* getSettingsFromCache);
|
|
26319
|
-
}));
|
|
26320
|
-
const startWatcher = Effect.gen(function* () {
|
|
26321
|
-
const settingsDir = pathService.dirname(settingsPath);
|
|
26322
|
-
const settingsFile = pathService.basename(settingsPath);
|
|
26323
|
-
const settingsPathResolved = pathService.resolve(settingsPath);
|
|
26324
|
-
yield* fs.makeDirectory(settingsDir, { recursive: true }).pipe(Effect.mapError((cause) => new ServerSettingsError({
|
|
26325
|
-
settingsPath,
|
|
26326
|
-
detail: "failed to prepare settings directory",
|
|
26327
|
-
cause
|
|
26328
|
-
})));
|
|
26329
|
-
const revalidateAndEmitSafely = revalidateAndEmit.pipe(Effect.ignoreCause({ log: true }));
|
|
26330
|
-
const debouncedSettingsEvents = fs.watch(settingsDir).pipe(Stream.filter((event) => {
|
|
26331
|
-
return event.path === settingsFile || event.path === settingsPath || pathService.resolve(settingsDir, event.path) === settingsPathResolved;
|
|
26332
|
-
}), Stream.debounce(Duration.millis(100)));
|
|
26333
|
-
yield* Stream.runForEach(debouncedSettingsEvents, () => revalidateAndEmitSafely).pipe(Effect.ignoreCause({ log: true }), Effect.forkIn(watcherScope), Effect.asVoid);
|
|
26334
|
-
});
|
|
26335
|
-
return {
|
|
26336
|
-
start: Effect.gen(function* () {
|
|
26337
|
-
if (!(yield* Ref.modify(startedRef, (started) => [!started, true]))) return yield* Deferred.await(startedDeferred);
|
|
26338
|
-
const startup = Effect.gen(function* () {
|
|
26339
|
-
yield* startWatcher;
|
|
26340
|
-
yield* Cache.invalidate(settingsCache, cacheKey);
|
|
26341
|
-
yield* getSettingsFromCache;
|
|
26342
|
-
});
|
|
26343
|
-
const startupExit = yield* Effect.exit(startup);
|
|
26344
|
-
if (startupExit._tag === "Failure") {
|
|
26345
|
-
yield* Deferred.failCause(startedDeferred, startupExit.cause).pipe(Effect.orDie);
|
|
26346
|
-
return yield* Effect.failCause(startupExit.cause);
|
|
26347
|
-
}
|
|
26348
|
-
yield* Deferred.succeed(startedDeferred, void 0).pipe(Effect.orDie);
|
|
26349
|
-
}),
|
|
26350
|
-
ready: Deferred.await(startedDeferred),
|
|
26351
|
-
getSettings: getSettingsFromCache.pipe(Effect.flatMap(materializeProviderEnvironmentSecrets), Effect.map(resolveTextGenerationProvider)),
|
|
26352
|
-
updateSettings: (patch) => writeSemaphore.withPermits(1)(Effect.gen(function* () {
|
|
26353
|
-
const current = yield* getSettingsFromCache;
|
|
26354
|
-
const nextPersisted = yield* persistProviderEnvironmentSecrets(current, applyServerSettingsPatch(current, patch));
|
|
26355
|
-
const next = yield* Schema.decodeEffect(ServerSettings)(nextPersisted).pipe(Effect.mapError((cause) => new ServerSettingsError({
|
|
26356
|
-
settingsPath: "<memory>",
|
|
26357
|
-
detail: `failed to normalize server settings: ${SchemaIssue.makeFormatterDefault()(cause.issue)}`,
|
|
26358
|
-
cause
|
|
26359
|
-
})));
|
|
26360
|
-
yield* writeSettingsAtomically(next);
|
|
26361
|
-
yield* Cache.set(settingsCache, cacheKey, next);
|
|
26362
|
-
yield* emitChange(next);
|
|
26363
|
-
return resolveTextGenerationProvider(yield* materializeProviderEnvironmentSecrets(next));
|
|
26364
|
-
})),
|
|
26365
|
-
get streamChanges() {
|
|
26366
|
-
return Stream.fromPubSub(changesPubSub).pipe(Stream.mapEffect((settings) => materializeProviderEnvironmentSecrets(settings).pipe(Effect.catch((error) => Effect.logWarning("failed to materialize provider environment secrets", { detail: error.detail }).pipe(Effect.as(settings))))), Stream.map(resolveTextGenerationProvider));
|
|
26367
|
-
}
|
|
26368
|
-
};
|
|
26369
|
-
});
|
|
26370
|
-
const ServerSettingsLive = Layer.effect(ServerSettingsService, makeServerSettings).pipe(Layer.provide(ServerSecretStoreLive));
|
|
26371
|
-
//#endregion
|
|
26372
26340
|
//#region src/pathExpansion.ts
|
|
26373
26341
|
/**
|
|
26374
26342
|
* Expand a leading `~` (or `~/…`, `~\…`) in a user-supplied path to the
|
|
@@ -26689,7 +26657,7 @@ const BUILT_IN_DRIVERS = [
|
|
|
26689
26657
|
configSchema: CodexSettings,
|
|
26690
26658
|
defaultConfig: () => Schema.decodeSync(CodexSettings)({}),
|
|
26691
26659
|
create: (input) => Effect.tryPromise({
|
|
26692
|
-
try: () => import("./CodexDriver-
|
|
26660
|
+
try: () => import("./CodexDriver-DH7vqku4.mjs"),
|
|
26693
26661
|
catch: (cause) => driverImportError(codexDriverKind, input, cause)
|
|
26694
26662
|
}).pipe(Effect.flatMap(({ CodexDriver }) => CodexDriver.create(input)))
|
|
26695
26663
|
},
|
|
@@ -26702,7 +26670,7 @@ const BUILT_IN_DRIVERS = [
|
|
|
26702
26670
|
configSchema: ClaudeSettings,
|
|
26703
26671
|
defaultConfig: () => Schema.decodeSync(ClaudeSettings)({}),
|
|
26704
26672
|
create: (input) => Effect.tryPromise({
|
|
26705
|
-
try: () => import("./ClaudeDriver-
|
|
26673
|
+
try: () => import("./ClaudeDriver-CoPBpdrp.mjs"),
|
|
26706
26674
|
catch: (cause) => driverImportError(claudeDriverKind, input, cause)
|
|
26707
26675
|
}).pipe(Effect.flatMap(({ ClaudeDriver }) => ClaudeDriver.create(input)))
|
|
26708
26676
|
},
|
|
@@ -26715,7 +26683,7 @@ const BUILT_IN_DRIVERS = [
|
|
|
26715
26683
|
configSchema: CopilotSettings,
|
|
26716
26684
|
defaultConfig: () => Schema.decodeSync(CopilotSettings)({}),
|
|
26717
26685
|
create: (input) => Effect.tryPromise({
|
|
26718
|
-
try: () => import("./CopilotDriver-
|
|
26686
|
+
try: () => import("./CopilotDriver-CFCF68Te.mjs"),
|
|
26719
26687
|
catch: (cause) => driverImportError(copilotDriverKind, input, cause)
|
|
26720
26688
|
}).pipe(Effect.flatMap(({ CopilotDriver }) => CopilotDriver.create(input)))
|
|
26721
26689
|
},
|
|
@@ -26728,7 +26696,7 @@ const BUILT_IN_DRIVERS = [
|
|
|
26728
26696
|
configSchema: CursorSettings,
|
|
26729
26697
|
defaultConfig: () => Schema.decodeSync(CursorSettings)({}),
|
|
26730
26698
|
create: (input) => Effect.tryPromise({
|
|
26731
|
-
try: () => import("./CursorDriver-
|
|
26699
|
+
try: () => import("./CursorDriver-Dej81rwD.mjs"),
|
|
26732
26700
|
catch: (cause) => driverImportError(cursorDriverKind, input, cause)
|
|
26733
26701
|
}).pipe(Effect.flatMap(({ CursorDriver }) => CursorDriver.create(input)))
|
|
26734
26702
|
},
|
|
@@ -26741,7 +26709,7 @@ const BUILT_IN_DRIVERS = [
|
|
|
26741
26709
|
configSchema: OpenCodeSettings,
|
|
26742
26710
|
defaultConfig: () => Schema.decodeSync(OpenCodeSettings)({}),
|
|
26743
26711
|
create: (input) => Effect.tryPromise({
|
|
26744
|
-
try: () => import("./OpenCodeDriver-
|
|
26712
|
+
try: () => import("./OpenCodeDriver-BGa9Tkot.mjs"),
|
|
26745
26713
|
catch: (cause) => driverImportError(openCodeDriverKind, input, cause)
|
|
26746
26714
|
}).pipe(Effect.flatMap(({ OpenCodeDriver }) => OpenCodeDriver.create(input)))
|
|
26747
26715
|
}
|
|
@@ -26841,6 +26809,7 @@ function buildServerProvider(input) {
|
|
|
26841
26809
|
displayName: input.presentation.displayName,
|
|
26842
26810
|
...input.presentation.badgeLabel ? { badgeLabel: input.presentation.badgeLabel } : {},
|
|
26843
26811
|
...typeof input.presentation.showInteractionModeToggle === "boolean" ? { showInteractionModeToggle: input.presentation.showInteractionModeToggle } : {},
|
|
26812
|
+
...typeof input.presentation.supportsAskMode === "boolean" ? { supportsAskMode: input.presentation.supportsAskMode } : {},
|
|
26844
26813
|
enabled: input.enabled,
|
|
26845
26814
|
installed: input.probe.installed,
|
|
26846
26815
|
version: input.probe.version,
|
|
@@ -27454,13 +27423,14 @@ const scopedSafeTeardown = (label) => (effect) => Effect.gen(function* () {
|
|
|
27454
27423
|
});
|
|
27455
27424
|
//#endregion
|
|
27456
27425
|
//#region package.json
|
|
27457
|
-
var version = "0.1.
|
|
27426
|
+
var version = "0.1.8";
|
|
27458
27427
|
//#endregion
|
|
27459
27428
|
//#region src/provider/Layers/CodexProvider.ts
|
|
27460
27429
|
const PROVIDER_PROBE_TIMEOUT_MS = 8e3;
|
|
27461
27430
|
const CODEX_PRESENTATION = {
|
|
27462
27431
|
displayName: "Codex",
|
|
27463
|
-
showInteractionModeToggle: true
|
|
27432
|
+
showInteractionModeToggle: true,
|
|
27433
|
+
supportsAskMode: true
|
|
27464
27434
|
};
|
|
27465
27435
|
const REASONING_EFFORT_LABELS = {
|
|
27466
27436
|
none: "None",
|
|
@@ -27468,8 +27438,15 @@ const REASONING_EFFORT_LABELS = {
|
|
|
27468
27438
|
low: "Low",
|
|
27469
27439
|
medium: "Medium",
|
|
27470
27440
|
high: "High",
|
|
27471
|
-
xhigh: "Extra High"
|
|
27441
|
+
xhigh: "Extra High",
|
|
27442
|
+
max: "Max",
|
|
27443
|
+
ultra: "Ultra"
|
|
27472
27444
|
};
|
|
27445
|
+
function formatReasoningEffortLabel(reasoningEffort) {
|
|
27446
|
+
const known = REASONING_EFFORT_LABELS[reasoningEffort];
|
|
27447
|
+
if (known) return known;
|
|
27448
|
+
return reasoningEffort.replace(/[_-]+/g, " ").replace(/\b\w/g, (char) => char.toUpperCase());
|
|
27449
|
+
}
|
|
27473
27450
|
function codexAccountAuthLabel(account) {
|
|
27474
27451
|
if (!account) return void 0;
|
|
27475
27452
|
if (account.type === "apiKey") return "OpenAI API Key";
|
|
@@ -27498,11 +27475,11 @@ function codexAccountEmail(account) {
|
|
|
27498
27475
|
function mapCodexModelCapabilities(model) {
|
|
27499
27476
|
const reasoningOptions = model.supportedReasoningEfforts.map(({ reasoningEffort }) => reasoningEffort === model.defaultReasoningEffort ? {
|
|
27500
27477
|
id: reasoningEffort,
|
|
27501
|
-
label:
|
|
27478
|
+
label: formatReasoningEffortLabel(reasoningEffort),
|
|
27502
27479
|
isDefault: true
|
|
27503
27480
|
} : {
|
|
27504
27481
|
id: reasoningEffort,
|
|
27505
|
-
label:
|
|
27482
|
+
label: formatReasoningEffortLabel(reasoningEffort)
|
|
27506
27483
|
});
|
|
27507
27484
|
const defaultReasoning = reasoningOptions.find((option) => option.isDefault)?.id;
|
|
27508
27485
|
const supportsFastMode = (model.additionalSpeedTiers ?? []).includes("fast");
|
|
@@ -28491,6 +28468,425 @@ var OrchestrationEngineService = class extends Context.Service()("ryco/orchestra
|
|
|
28491
28468
|
*/
|
|
28492
28469
|
var ProjectionSnapshotQuery = class extends Context.Service()("ryco/orchestration/Services/ProjectionSnapshotQuery") {};
|
|
28493
28470
|
//#endregion
|
|
28471
|
+
//#region src/statistics/StatisticsQuery.ts
|
|
28472
|
+
/**
|
|
28473
|
+
* StatisticsQuery - usage analytics over the orchestration projection tables.
|
|
28474
|
+
*
|
|
28475
|
+
* Aggregates the existing read models (threads, sessions, token-usage
|
|
28476
|
+
* activities, turns/checkpoints, worktrees) into a {@link StatisticsSnapshot}
|
|
28477
|
+
* on demand. No dedicated statistics tables exist; everything is derived from
|
|
28478
|
+
* data already persisted by the projection pipeline.
|
|
28479
|
+
*
|
|
28480
|
+
* Token figures prefer per-turn attribution: for each `(thread, turn)` with
|
|
28481
|
+
* exact `last*` breakdowns we read the final `context-window.updated` activity
|
|
28482
|
+
* and bucket its provider-reported turn total by day/project/provider/model.
|
|
28483
|
+
* Threads without exact deltas (older data / providers that only report
|
|
28484
|
+
* cumulative context usage) fall back to attributing the latest cumulative
|
|
28485
|
+
* total to the thread's primary model and last-activity day.
|
|
28486
|
+
*
|
|
28487
|
+
* @module StatisticsQuery
|
|
28488
|
+
*/
|
|
28489
|
+
/**
|
|
28490
|
+
* StatisticsQuery - service tag.
|
|
28491
|
+
*/
|
|
28492
|
+
var StatisticsQuery = class extends Context.Service()("ryco/statistics/StatisticsQuery") {};
|
|
28493
|
+
function toPersistenceSqlOrDecodeError$7(sqlOperation, decodeOperation) {
|
|
28494
|
+
return (cause) => Schema.isSchemaError(cause) ? toPersistenceDecodeError(decodeOperation)(cause) : toPersistenceSqlError(sqlOperation)(cause);
|
|
28495
|
+
}
|
|
28496
|
+
const ThreadRow = Schema.Struct({
|
|
28497
|
+
threadId: Schema.String,
|
|
28498
|
+
projectId: ProjectId,
|
|
28499
|
+
model: Schema.NullOr(Schema.String),
|
|
28500
|
+
providerInstanceId: Schema.NullOr(Schema.String),
|
|
28501
|
+
createdAt: Schema.String,
|
|
28502
|
+
providerName: Schema.NullOr(Schema.String)
|
|
28503
|
+
});
|
|
28504
|
+
const ProjectRow = Schema.Struct({
|
|
28505
|
+
projectId: ProjectId,
|
|
28506
|
+
title: Schema.String,
|
|
28507
|
+
deletedAt: Schema.NullOr(Schema.String)
|
|
28508
|
+
});
|
|
28509
|
+
const TokenActivityRow = Schema.Struct({
|
|
28510
|
+
threadId: Schema.String,
|
|
28511
|
+
turnId: Schema.NullOr(Schema.String),
|
|
28512
|
+
sequence: Schema.NullOr(Schema.Number),
|
|
28513
|
+
createdAt: Schema.String,
|
|
28514
|
+
payloadJson: Schema.String
|
|
28515
|
+
});
|
|
28516
|
+
const ToolUseRow = Schema.Struct({
|
|
28517
|
+
threadId: Schema.String,
|
|
28518
|
+
date: Schema.String,
|
|
28519
|
+
count: Schema.Number
|
|
28520
|
+
});
|
|
28521
|
+
const TurnRow = Schema.Struct({
|
|
28522
|
+
threadId: Schema.String,
|
|
28523
|
+
startedAt: Schema.NullOr(Schema.String),
|
|
28524
|
+
completedAt: Schema.NullOr(Schema.String),
|
|
28525
|
+
checkpointTurnCount: Schema.NullOr(Schema.Number),
|
|
28526
|
+
filesJson: Schema.String
|
|
28527
|
+
});
|
|
28528
|
+
const WorktreeRow = Schema.Struct({
|
|
28529
|
+
createdAt: Schema.String,
|
|
28530
|
+
archivedAt: Schema.NullOr(Schema.String),
|
|
28531
|
+
prNumber: Schema.NullOr(Schema.Number)
|
|
28532
|
+
});
|
|
28533
|
+
function num(value) {
|
|
28534
|
+
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
28535
|
+
}
|
|
28536
|
+
function dayOf(iso) {
|
|
28537
|
+
return iso.length >= 10 ? iso.slice(0, 10) : null;
|
|
28538
|
+
}
|
|
28539
|
+
function bestPerTurnTotalTokenCount(payload) {
|
|
28540
|
+
const reportedTotal = num(payload?.lastUsedTokens);
|
|
28541
|
+
if (reportedTotal > 0) return reportedTotal;
|
|
28542
|
+
return num(payload?.lastInputTokens) + num(payload?.lastOutputTokens);
|
|
28543
|
+
}
|
|
28544
|
+
function bestCumulativeTotalTokenCount(payload) {
|
|
28545
|
+
const reportedTotal = num(payload?.usedTokens);
|
|
28546
|
+
if (reportedTotal > 0) return reportedTotal;
|
|
28547
|
+
return num(payload?.inputTokens) + num(payload?.outputTokens);
|
|
28548
|
+
}
|
|
28549
|
+
function hasExactPerTurnBreakdown(payload) {
|
|
28550
|
+
return num(payload?.lastInputTokens) + num(payload?.lastOutputTokens) + num(payload?.lastCachedInputTokens) + num(payload?.lastReasoningOutputTokens) > 0;
|
|
28551
|
+
}
|
|
28552
|
+
function addPerTurnUsage(bucket, payload) {
|
|
28553
|
+
bucket.inputTokens += num(payload?.lastInputTokens);
|
|
28554
|
+
bucket.outputTokens += num(payload?.lastOutputTokens);
|
|
28555
|
+
bucket.cachedInputTokens += num(payload?.lastCachedInputTokens);
|
|
28556
|
+
bucket.reasoningTokens += num(payload?.lastReasoningOutputTokens);
|
|
28557
|
+
bucket.totalTokens += bestPerTurnTotalTokenCount(payload);
|
|
28558
|
+
}
|
|
28559
|
+
function addCumulativeUsage(bucket, payload) {
|
|
28560
|
+
bucket.inputTokens += num(payload?.inputTokens);
|
|
28561
|
+
bucket.outputTokens += num(payload?.outputTokens);
|
|
28562
|
+
bucket.cachedInputTokens += num(payload?.cachedInputTokens);
|
|
28563
|
+
bucket.reasoningTokens += num(payload?.reasoningOutputTokens);
|
|
28564
|
+
bucket.totalTokens += bestCumulativeTotalTokenCount(payload);
|
|
28565
|
+
}
|
|
28566
|
+
const makeStatisticsQuery = Effect.gen(function* () {
|
|
28567
|
+
const sql = yield* SqlClient.SqlClient;
|
|
28568
|
+
const listThreadRows = SqlSchema.findAll({
|
|
28569
|
+
Request: Schema.Void,
|
|
28570
|
+
Result: ThreadRow,
|
|
28571
|
+
execute: () => sql`
|
|
28572
|
+
SELECT
|
|
28573
|
+
t.thread_id AS "threadId",
|
|
28574
|
+
t.project_id AS "projectId",
|
|
28575
|
+
json_extract(t.model_selection_json, '$.model') AS "model",
|
|
28576
|
+
COALESCE(
|
|
28577
|
+
json_extract(t.model_selection_json, '$.instanceId'),
|
|
28578
|
+
json_extract(t.model_selection_json, '$.provider')
|
|
28579
|
+
) AS "providerInstanceId",
|
|
28580
|
+
t.created_at AS "createdAt",
|
|
28581
|
+
COALESCE(
|
|
28582
|
+
s.provider_name,
|
|
28583
|
+
json_extract(t.model_selection_json, '$.instanceId'),
|
|
28584
|
+
json_extract(t.model_selection_json, '$.provider')
|
|
28585
|
+
) AS "providerName"
|
|
28586
|
+
FROM projection_threads t
|
|
28587
|
+
LEFT JOIN projection_thread_sessions s ON s.thread_id = t.thread_id
|
|
28588
|
+
`
|
|
28589
|
+
});
|
|
28590
|
+
const listProjectRows = SqlSchema.findAll({
|
|
28591
|
+
Request: Schema.Void,
|
|
28592
|
+
Result: ProjectRow,
|
|
28593
|
+
execute: () => sql`
|
|
28594
|
+
SELECT
|
|
28595
|
+
project_id AS "projectId",
|
|
28596
|
+
title,
|
|
28597
|
+
deleted_at AS "deletedAt"
|
|
28598
|
+
FROM projection_projects
|
|
28599
|
+
`
|
|
28600
|
+
});
|
|
28601
|
+
const listTokenActivityRows = SqlSchema.findAll({
|
|
28602
|
+
Request: Schema.Void,
|
|
28603
|
+
Result: TokenActivityRow,
|
|
28604
|
+
execute: () => sql`
|
|
28605
|
+
SELECT
|
|
28606
|
+
thread_id AS "threadId",
|
|
28607
|
+
turn_id AS "turnId",
|
|
28608
|
+
sequence,
|
|
28609
|
+
created_at AS "createdAt",
|
|
28610
|
+
payload_json AS "payloadJson"
|
|
28611
|
+
FROM projection_thread_activities
|
|
28612
|
+
WHERE kind = 'context-window.updated'
|
|
28613
|
+
ORDER BY thread_id ASC, turn_id ASC, sequence ASC, created_at ASC, activity_id ASC
|
|
28614
|
+
`
|
|
28615
|
+
});
|
|
28616
|
+
const listToolUseRows = SqlSchema.findAll({
|
|
28617
|
+
Request: Schema.Void,
|
|
28618
|
+
Result: ToolUseRow,
|
|
28619
|
+
execute: () => sql`
|
|
28620
|
+
SELECT
|
|
28621
|
+
thread_id AS "threadId",
|
|
28622
|
+
substr(created_at, 1, 10) AS "date",
|
|
28623
|
+
COUNT(*) AS "count"
|
|
28624
|
+
FROM projection_thread_activities
|
|
28625
|
+
WHERE kind = 'tool.completed'
|
|
28626
|
+
GROUP BY thread_id, substr(created_at, 1, 10)
|
|
28627
|
+
`
|
|
28628
|
+
});
|
|
28629
|
+
const listTurnRows = SqlSchema.findAll({
|
|
28630
|
+
Request: Schema.Void,
|
|
28631
|
+
Result: TurnRow,
|
|
28632
|
+
execute: () => sql`
|
|
28633
|
+
SELECT
|
|
28634
|
+
thread_id AS "threadId",
|
|
28635
|
+
started_at AS "startedAt",
|
|
28636
|
+
completed_at AS "completedAt",
|
|
28637
|
+
checkpoint_turn_count AS "checkpointTurnCount",
|
|
28638
|
+
checkpoint_files_json AS "filesJson"
|
|
28639
|
+
FROM projection_turns
|
|
28640
|
+
`
|
|
28641
|
+
});
|
|
28642
|
+
const listWorktreeRows = SqlSchema.findAll({
|
|
28643
|
+
Request: Schema.Void,
|
|
28644
|
+
Result: WorktreeRow,
|
|
28645
|
+
execute: () => sql`
|
|
28646
|
+
SELECT
|
|
28647
|
+
created_at AS "createdAt",
|
|
28648
|
+
archived_at AS "archivedAt",
|
|
28649
|
+
pr_number AS "prNumber"
|
|
28650
|
+
FROM projection_worktrees
|
|
28651
|
+
`
|
|
28652
|
+
});
|
|
28653
|
+
const getStatistics = () => Effect.gen(function* () {
|
|
28654
|
+
const [threadRows, projectRows, tokenRows, toolRows, turnRows, worktreeRows] = yield* Effect.all([
|
|
28655
|
+
listThreadRows(void 0).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$7("StatisticsQuery.getStatistics:listThreads:query", "StatisticsQuery.getStatistics:listThreads:decodeRows"))),
|
|
28656
|
+
listProjectRows(void 0).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$7("StatisticsQuery.getStatistics:listProjects:query", "StatisticsQuery.getStatistics:listProjects:decodeRows"))),
|
|
28657
|
+
listTokenActivityRows(void 0).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$7("StatisticsQuery.getStatistics:listTokenActivities:query", "StatisticsQuery.getStatistics:listTokenActivities:decodeRows"))),
|
|
28658
|
+
listToolUseRows(void 0).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$7("StatisticsQuery.getStatistics:listToolUses:query", "StatisticsQuery.getStatistics:listToolUses:decodeRows"))),
|
|
28659
|
+
listTurnRows(void 0).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$7("StatisticsQuery.getStatistics:listTurns:query", "StatisticsQuery.getStatistics:listTurns:decodeRows"))),
|
|
28660
|
+
listWorktreeRows(void 0).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$7("StatisticsQuery.getStatistics:listWorktrees:query", "StatisticsQuery.getStatistics:listWorktrees:decodeRows")))
|
|
28661
|
+
], { concurrency: "unbounded" });
|
|
28662
|
+
const threadMeta = /* @__PURE__ */ new Map();
|
|
28663
|
+
const modelRefs = /* @__PURE__ */ new Map();
|
|
28664
|
+
for (const row of threadRows) {
|
|
28665
|
+
const provider = row.providerName?.trim() || row.providerInstanceId?.trim() || void 0;
|
|
28666
|
+
const model = (row.model ?? "").trim() || "unknown";
|
|
28667
|
+
threadMeta.set(row.threadId, {
|
|
28668
|
+
projectId: row.projectId,
|
|
28669
|
+
model,
|
|
28670
|
+
provider,
|
|
28671
|
+
createdAt: row.createdAt
|
|
28672
|
+
});
|
|
28673
|
+
const modelKey = `${provider ?? ""}\u0000${model}`;
|
|
28674
|
+
modelRefs.set(modelKey, provider ? {
|
|
28675
|
+
model,
|
|
28676
|
+
provider
|
|
28677
|
+
} : { model });
|
|
28678
|
+
}
|
|
28679
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
28680
|
+
const getBucket = (date, projectId, model, provider) => {
|
|
28681
|
+
const key = `${date}\u0000${projectId}\u0000${provider ?? ""}\u0000${model}`;
|
|
28682
|
+
let bucket = buckets.get(key);
|
|
28683
|
+
if (!bucket) {
|
|
28684
|
+
bucket = {
|
|
28685
|
+
date,
|
|
28686
|
+
projectId,
|
|
28687
|
+
model,
|
|
28688
|
+
provider,
|
|
28689
|
+
inputTokens: 0,
|
|
28690
|
+
outputTokens: 0,
|
|
28691
|
+
cachedInputTokens: 0,
|
|
28692
|
+
reasoningTokens: 0,
|
|
28693
|
+
totalTokens: 0,
|
|
28694
|
+
turns: 0,
|
|
28695
|
+
activeMs: 0,
|
|
28696
|
+
toolUses: 0,
|
|
28697
|
+
filesChanged: 0,
|
|
28698
|
+
additions: 0,
|
|
28699
|
+
deletions: 0,
|
|
28700
|
+
commits: 0,
|
|
28701
|
+
pushes: 0,
|
|
28702
|
+
threadsCreated: 0
|
|
28703
|
+
};
|
|
28704
|
+
buckets.set(key, bucket);
|
|
28705
|
+
}
|
|
28706
|
+
return bucket;
|
|
28707
|
+
};
|
|
28708
|
+
let earliest;
|
|
28709
|
+
const considerIso = (iso) => {
|
|
28710
|
+
if (iso && (earliest === void 0 || iso < earliest)) earliest = iso;
|
|
28711
|
+
};
|
|
28712
|
+
const lastPerTurn = /* @__PURE__ */ new Map();
|
|
28713
|
+
const isLater = (a, b) => {
|
|
28714
|
+
if (a.createdAt !== b.createdAt) return a.createdAt > b.createdAt;
|
|
28715
|
+
return (a.sequence ?? -1) >= (b.sequence ?? -1);
|
|
28716
|
+
};
|
|
28717
|
+
for (const row of tokenRows) {
|
|
28718
|
+
considerIso(row.createdAt);
|
|
28719
|
+
const turnKey = `${row.threadId}\u0000${row.turnId ?? ""}`;
|
|
28720
|
+
const prevTurn = lastPerTurn.get(turnKey);
|
|
28721
|
+
if (!prevTurn || isLater(row, prevTurn)) lastPerTurn.set(turnKey, row);
|
|
28722
|
+
}
|
|
28723
|
+
const firstExactPerThread = /* @__PURE__ */ new Map();
|
|
28724
|
+
for (const row of lastPerTurn.values()) if (hasExactPerTurnBreakdown(safeParse(row.payloadJson))) {
|
|
28725
|
+
const prev = firstExactPerThread.get(row.threadId);
|
|
28726
|
+
if (!prev || isLater(prev, row)) firstExactPerThread.set(row.threadId, row);
|
|
28727
|
+
}
|
|
28728
|
+
const cumulativeFallbackByThread = /* @__PURE__ */ new Map();
|
|
28729
|
+
for (const row of lastPerTurn.values()) {
|
|
28730
|
+
if (hasExactPerTurnBreakdown(safeParse(row.payloadJson))) continue;
|
|
28731
|
+
const firstExact = firstExactPerThread.get(row.threadId);
|
|
28732
|
+
if (firstExact && !isLater(firstExact, row)) continue;
|
|
28733
|
+
const prev = cumulativeFallbackByThread.get(row.threadId);
|
|
28734
|
+
if (!prev || isLater(row, prev)) cumulativeFallbackByThread.set(row.threadId, row);
|
|
28735
|
+
}
|
|
28736
|
+
let usedExactPerTurn = false;
|
|
28737
|
+
let usedCumulativeFallback = false;
|
|
28738
|
+
for (const row of lastPerTurn.values()) {
|
|
28739
|
+
const payload = safeParse(row.payloadJson);
|
|
28740
|
+
if (!hasExactPerTurnBreakdown(payload)) continue;
|
|
28741
|
+
const meta = threadMeta.get(row.threadId);
|
|
28742
|
+
const date = dayOf(row.createdAt);
|
|
28743
|
+
if (!meta || !date) continue;
|
|
28744
|
+
addPerTurnUsage(getBucket(date, meta.projectId, meta.model, meta.provider), payload);
|
|
28745
|
+
usedExactPerTurn = true;
|
|
28746
|
+
}
|
|
28747
|
+
for (const row of cumulativeFallbackByThread.values()) {
|
|
28748
|
+
const meta = threadMeta.get(row.threadId);
|
|
28749
|
+
const date = dayOf(row.createdAt);
|
|
28750
|
+
if (!meta || !date) continue;
|
|
28751
|
+
const payload = safeParse(row.payloadJson);
|
|
28752
|
+
if (bestCumulativeTotalTokenCount(payload) <= 0) continue;
|
|
28753
|
+
addCumulativeUsage(getBucket(date, meta.projectId, meta.model, meta.provider), payload);
|
|
28754
|
+
usedCumulativeFallback = true;
|
|
28755
|
+
}
|
|
28756
|
+
const attribution = usedExactPerTurn && usedCumulativeFallback ? "mixed" : usedCumulativeFallback ? "thread-cumulative" : "per-turn-delta";
|
|
28757
|
+
for (const row of turnRows) {
|
|
28758
|
+
const meta = threadMeta.get(row.threadId);
|
|
28759
|
+
if (!meta) continue;
|
|
28760
|
+
considerIso(row.startedAt);
|
|
28761
|
+
considerIso(row.completedAt);
|
|
28762
|
+
const anchor = row.completedAt ?? row.startedAt;
|
|
28763
|
+
const date = anchor ? dayOf(anchor) : null;
|
|
28764
|
+
if (!date) continue;
|
|
28765
|
+
const bucket = getBucket(date, meta.projectId, meta.model, meta.provider);
|
|
28766
|
+
if (row.completedAt) {
|
|
28767
|
+
bucket.turns += 1;
|
|
28768
|
+
if (row.startedAt) {
|
|
28769
|
+
const delta = Date.parse(row.completedAt) - Date.parse(row.startedAt);
|
|
28770
|
+
if (Number.isFinite(delta) && delta > 0) bucket.activeMs += delta;
|
|
28771
|
+
}
|
|
28772
|
+
}
|
|
28773
|
+
const files = safeParseArray(row.filesJson);
|
|
28774
|
+
if (files.length > 0) {
|
|
28775
|
+
bucket.filesChanged += files.length;
|
|
28776
|
+
for (const file of files) {
|
|
28777
|
+
bucket.additions += num(file?.additions);
|
|
28778
|
+
bucket.deletions += num(file?.deletions);
|
|
28779
|
+
}
|
|
28780
|
+
}
|
|
28781
|
+
}
|
|
28782
|
+
for (const row of toolRows) {
|
|
28783
|
+
const meta = threadMeta.get(row.threadId);
|
|
28784
|
+
if (!meta) continue;
|
|
28785
|
+
const bucket = getBucket(row.date, meta.projectId, meta.model, meta.provider);
|
|
28786
|
+
bucket.toolUses += num(row.count);
|
|
28787
|
+
}
|
|
28788
|
+
for (const meta of threadMeta.values()) {
|
|
28789
|
+
considerIso(meta.createdAt);
|
|
28790
|
+
const date = dayOf(meta.createdAt);
|
|
28791
|
+
if (!date) continue;
|
|
28792
|
+
getBucket(date, meta.projectId, meta.model, meta.provider).threadsCreated += 1;
|
|
28793
|
+
}
|
|
28794
|
+
let wtCreated = 0;
|
|
28795
|
+
let wtArchived = 0;
|
|
28796
|
+
let wtOpenPrs = 0;
|
|
28797
|
+
for (const row of worktreeRows) {
|
|
28798
|
+
considerIso(row.createdAt);
|
|
28799
|
+
wtCreated += 1;
|
|
28800
|
+
if (row.archivedAt) wtArchived += 1;
|
|
28801
|
+
else if (row.prNumber !== null) wtOpenPrs += 1;
|
|
28802
|
+
}
|
|
28803
|
+
const dailyBuckets = [];
|
|
28804
|
+
const totals = {
|
|
28805
|
+
inputTokens: 0,
|
|
28806
|
+
outputTokens: 0,
|
|
28807
|
+
cachedInputTokens: 0,
|
|
28808
|
+
reasoningTokens: 0,
|
|
28809
|
+
totalTokens: 0,
|
|
28810
|
+
turns: 0,
|
|
28811
|
+
activeMs: 0,
|
|
28812
|
+
toolUses: 0,
|
|
28813
|
+
filesChanged: 0,
|
|
28814
|
+
additions: 0,
|
|
28815
|
+
deletions: 0,
|
|
28816
|
+
commits: 0,
|
|
28817
|
+
pushes: 0,
|
|
28818
|
+
threads: threadMeta.size,
|
|
28819
|
+
projects: 0
|
|
28820
|
+
};
|
|
28821
|
+
for (const bucket of buckets.values()) {
|
|
28822
|
+
const { provider, ...rest } = bucket;
|
|
28823
|
+
dailyBuckets.push(provider ? {
|
|
28824
|
+
...rest,
|
|
28825
|
+
provider
|
|
28826
|
+
} : rest);
|
|
28827
|
+
totals.inputTokens += bucket.inputTokens;
|
|
28828
|
+
totals.outputTokens += bucket.outputTokens;
|
|
28829
|
+
totals.cachedInputTokens += bucket.cachedInputTokens;
|
|
28830
|
+
totals.reasoningTokens += bucket.reasoningTokens;
|
|
28831
|
+
totals.turns += bucket.turns;
|
|
28832
|
+
totals.activeMs += bucket.activeMs;
|
|
28833
|
+
totals.toolUses += bucket.toolUses;
|
|
28834
|
+
totals.filesChanged += bucket.filesChanged;
|
|
28835
|
+
totals.additions += bucket.additions;
|
|
28836
|
+
totals.deletions += bucket.deletions;
|
|
28837
|
+
totals.commits += bucket.commits;
|
|
28838
|
+
totals.pushes += bucket.pushes;
|
|
28839
|
+
totals.totalTokens += bucket.totalTokens;
|
|
28840
|
+
}
|
|
28841
|
+
dailyBuckets.sort((a, b) => a.date === b.date ? a.projectId === b.projectId ? (a.provider ?? "").localeCompare(b.provider ?? "") || a.model.localeCompare(b.model) : a.projectId.localeCompare(b.projectId) : a.date.localeCompare(b.date));
|
|
28842
|
+
const projectTitle = /* @__PURE__ */ new Map();
|
|
28843
|
+
for (const row of projectRows) projectTitle.set(row.projectId, row.title);
|
|
28844
|
+
const projectIdsInData = /* @__PURE__ */ new Set();
|
|
28845
|
+
for (const meta of threadMeta.values()) projectIdsInData.add(meta.projectId);
|
|
28846
|
+
for (const bucket of buckets.values()) projectIdsInData.add(bucket.projectId);
|
|
28847
|
+
totals.projects = projectIdsInData.size;
|
|
28848
|
+
const projects = [...projectIdsInData].map((id) => ({
|
|
28849
|
+
id,
|
|
28850
|
+
title: projectTitle.get(id)?.trim() || id
|
|
28851
|
+
}));
|
|
28852
|
+
projects.sort((a, b) => a.title.localeCompare(b.title) || a.id.localeCompare(b.id));
|
|
28853
|
+
const models = [...modelRefs.values()].toSorted((a, b) => (a.provider ?? "").localeCompare(b.provider ?? "") || a.model.localeCompare(b.model));
|
|
28854
|
+
return {
|
|
28855
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
28856
|
+
...earliest ? { earliestActivityAt: earliest } : {},
|
|
28857
|
+
projects,
|
|
28858
|
+
models,
|
|
28859
|
+
dailyBuckets,
|
|
28860
|
+
worktrees: {
|
|
28861
|
+
created: wtCreated,
|
|
28862
|
+
archived: wtArchived,
|
|
28863
|
+
active: wtCreated - wtArchived,
|
|
28864
|
+
openPrs: wtOpenPrs
|
|
28865
|
+
},
|
|
28866
|
+
totals,
|
|
28867
|
+
tokenAttribution: attribution
|
|
28868
|
+
};
|
|
28869
|
+
});
|
|
28870
|
+
return { getStatistics };
|
|
28871
|
+
});
|
|
28872
|
+
function safeParse(json) {
|
|
28873
|
+
try {
|
|
28874
|
+
const parsed = JSON.parse(json);
|
|
28875
|
+
return parsed && typeof parsed === "object" ? parsed : null;
|
|
28876
|
+
} catch {
|
|
28877
|
+
return null;
|
|
28878
|
+
}
|
|
28879
|
+
}
|
|
28880
|
+
function safeParseArray(json) {
|
|
28881
|
+
try {
|
|
28882
|
+
const parsed = JSON.parse(json);
|
|
28883
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
28884
|
+
} catch {
|
|
28885
|
+
return [];
|
|
28886
|
+
}
|
|
28887
|
+
}
|
|
28888
|
+
const StatisticsQueryLive = Layer.effect(StatisticsQuery, makeStatisticsQuery);
|
|
28889
|
+
//#endregion
|
|
28494
28890
|
//#region src/serverLifecycleEvents.ts
|
|
28495
28891
|
var ServerLifecycleEvents = class extends Context.Service()("ryco/serverLifecycleEvents") {};
|
|
28496
28892
|
const ServerLifecycleEventsLive = Layer.effect(ServerLifecycleEvents, Effect.gen(function* () {
|
|
@@ -30380,7 +30776,8 @@ const makeGitManager = Effect.fn("makeGitManager")(function* () {
|
|
|
30380
30776
|
isDefaultRef: details.isDefaultBranch,
|
|
30381
30777
|
refName: details.branch,
|
|
30382
30778
|
hasWorkingTreeChanges: details.hasWorkingTreeChanges,
|
|
30383
|
-
workingTree: details.workingTree
|
|
30779
|
+
workingTree: details.workingTree,
|
|
30780
|
+
...details.committed ? { committed: details.committed } : {}
|
|
30384
30781
|
};
|
|
30385
30782
|
});
|
|
30386
30783
|
const localStatusResultCache = yield* Cache.makeWith(readLocalStatus, {
|
|
@@ -32514,6 +32911,8 @@ const layer = Layer.effect(JiraWorkItemService, make$5());
|
|
|
32514
32911
|
//#region src/remote/Services/AdvertisedEndpointRegistry.ts
|
|
32515
32912
|
var AdvertisedEndpointRegistry = class extends Context.Service()("ryco/remote/Services/AdvertisedEndpointRegistry") {};
|
|
32516
32913
|
const ORCHESTRATION_REPLAY_PAGE_MAX_LIMIT = 1e3;
|
|
32914
|
+
const ORCHESTRATION_LEGACY_REPLAY_MAX_EVENTS = ORCHESTRATION_REPLAY_PAGE_MAX_LIMIT;
|
|
32915
|
+
const ORCHESTRATION_LIVE_QUEUE_MAX_EVENTS = 1e3;
|
|
32517
32916
|
//#endregion
|
|
32518
32917
|
//#region src/ws/context/gitErrors.ts
|
|
32519
32918
|
function gitErrorText(error) {
|
|
@@ -32547,6 +32946,10 @@ const failGitWorkflow = (operation, detail, cause) => Effect.fail(toGitManagerEr
|
|
|
32547
32946
|
const wsOrchestrationReplayDepth = Metric.gauge("t3_ws_orchestration_replay_depth", { description: "Current persisted orchestration event replay depth for a replayable WebSocket subscription." });
|
|
32548
32947
|
const wsOrchestrationLiveBufferDepth = Metric.gauge("t3_ws_orchestration_live_buffer_depth", { description: "Current live orchestration event buffer depth for a replayable WebSocket subscription." });
|
|
32549
32948
|
const wsOrchestrationLiveBufferHighWater = Metric.gauge("t3_ws_orchestration_live_buffer_high_water", { description: "Highest observed live orchestration event buffer depth for a replayable WebSocket subscription." });
|
|
32949
|
+
const wsOrchestrationLiveBufferOverflowsTotal = Metric.counter("t3_ws_orchestration_live_buffer_overflows_total", {
|
|
32950
|
+
description: "Total live orchestration event buffer overflows that forced replayable WebSocket subscription resync.",
|
|
32951
|
+
incremental: true
|
|
32952
|
+
});
|
|
32550
32953
|
const wsOrchestrationReplayLag = Metric.gauge("t3_ws_orchestration_replay_lag", { description: "Sequence lag between the latest live event observed and the latest replay/live event drained by a replayable WebSocket subscription." });
|
|
32551
32954
|
const normalizeSequence = (sequence) => Number.isFinite(sequence) ? Math.max(0, Math.floor(sequence)) : 0;
|
|
32552
32955
|
const updateGauge$1 = (metric, attributes, value) => Metric.update(Metric.withAttributes(metric, attributes), value);
|
|
@@ -32584,6 +32987,18 @@ const makeWsReplayMetrics = (input) => Effect.gen(function* () {
|
|
|
32584
32987
|
yield* recordLiveBuffer(yield* Ref.updateAndGet(liveBufferDepth, (current) => Math.max(0, current - 1)), yield* Ref.get(liveBufferHighWater));
|
|
32585
32988
|
yield* markDrained(sequence);
|
|
32586
32989
|
}),
|
|
32990
|
+
recordLiveOverflow: (sequence, capacity) => Effect.gen(function* () {
|
|
32991
|
+
const normalizedSequence = normalizeSequence(sequence);
|
|
32992
|
+
const normalizedCapacity = Math.max(0, Math.floor(capacity));
|
|
32993
|
+
yield* Ref.update(latestLiveSequence, (current) => Math.max(current, normalizedSequence));
|
|
32994
|
+
yield* Ref.set(liveBufferDepth, normalizedCapacity);
|
|
32995
|
+
const highWater = yield* Ref.updateAndGet(liveBufferHighWater, (current) => Math.max(current, normalizedCapacity));
|
|
32996
|
+
yield* Effect.all([
|
|
32997
|
+
recordLiveBuffer(normalizedCapacity, highWater),
|
|
32998
|
+
updateGauge$1(wsOrchestrationLiveBufferOverflowsTotal, attributes, 1),
|
|
32999
|
+
recordLag
|
|
33000
|
+
], { discard: true });
|
|
33001
|
+
}),
|
|
32587
33002
|
reset: Effect.all([
|
|
32588
33003
|
updateGauge$1(wsOrchestrationReplayDepth, attributes, 0),
|
|
32589
33004
|
updateGauge$1(wsOrchestrationLiveBufferDepth, attributes, 0),
|
|
@@ -32634,6 +33049,29 @@ const buildWorkItemBranchNameMessage = (input) => {
|
|
|
32634
33049
|
};
|
|
32635
33050
|
//#endregion
|
|
32636
33051
|
//#region src/ws/context/orchestrationStreams.ts
|
|
33052
|
+
const makeLiveQueueOverflowError = (input) => new OrchestrationGetSnapshotError({
|
|
33053
|
+
message: `Orchestration ${input.stream} live event queue overflowed; reconnect to resynchronize`,
|
|
33054
|
+
cause: /* @__PURE__ */ new Error(`orchestration ${input.stream} live queue overflow at sequence ${input.sequence} with capacity ${input.capacity}`)
|
|
33055
|
+
});
|
|
33056
|
+
const offerOrchestrationLiveEventOrFail = (input) => Effect.gen(function* () {
|
|
33057
|
+
const capacity = input.capacity ?? 1e3;
|
|
33058
|
+
if (Queue.offerUnsafe(input.liveQueue, input.event)) {
|
|
33059
|
+
yield* input.replayMetrics.recordLiveEnqueued(input.event.sequence);
|
|
33060
|
+
return;
|
|
33061
|
+
}
|
|
33062
|
+
if (!(yield* Ref.modify(input.overflowedRef, (overflowed) => [!overflowed, true]))) return;
|
|
33063
|
+
yield* input.replayMetrics.recordLiveOverflow(input.event.sequence, capacity);
|
|
33064
|
+
yield* Effect.logWarning("orchestration live stream queue overflow; forcing resync", {
|
|
33065
|
+
stream: input.stream,
|
|
33066
|
+
sequence: input.event.sequence,
|
|
33067
|
+
capacity
|
|
33068
|
+
});
|
|
33069
|
+
yield* Queue.fail(input.liveQueue, makeLiveQueueOverflowError({
|
|
33070
|
+
stream: input.stream,
|
|
33071
|
+
sequence: input.event.sequence,
|
|
33072
|
+
capacity
|
|
33073
|
+
}));
|
|
33074
|
+
});
|
|
32637
33075
|
const makeOrchestrationStreamHelpers = (deps) => {
|
|
32638
33076
|
const { orchestrationEngine, projectionSnapshotQuery, repositoryIdentityResolver } = deps;
|
|
32639
33077
|
const enrichProjectEvent = (event) => {
|
|
@@ -32753,8 +33191,9 @@ const makeOrchestrationStreamHelpers = (deps) => {
|
|
|
32753
33191
|
const loadedSnapshot = yield* snapshot;
|
|
32754
33192
|
const snapshotSequence = loadedSnapshot.snapshotSequence;
|
|
32755
33193
|
const liveSubscription = yield* orchestrationEngine.subscribeDomainEvents;
|
|
32756
|
-
const liveQueue = yield* Queue.
|
|
33194
|
+
const liveQueue = yield* Queue.bounded(ORCHESTRATION_LIVE_QUEUE_MAX_EVENTS);
|
|
32757
33195
|
const lastSequenceRef = yield* Ref.make(snapshotSequence);
|
|
33196
|
+
const overflowedRef = yield* Ref.make(false);
|
|
32758
33197
|
const replayBoundary = yield* makeReplayBoundaryTracker(snapshotSequence);
|
|
32759
33198
|
const replayMetrics = yield* makeWsReplayMetrics({
|
|
32760
33199
|
stream: "shell",
|
|
@@ -32763,8 +33202,13 @@ const makeOrchestrationStreamHelpers = (deps) => {
|
|
|
32763
33202
|
});
|
|
32764
33203
|
yield* Stream.fromSubscription(liveSubscription).pipe(Stream.runForEach((event) => Effect.gen(function* () {
|
|
32765
33204
|
yield* replayBoundary.recordLiveSequence(event.sequence);
|
|
32766
|
-
yield*
|
|
32767
|
-
|
|
33205
|
+
yield* offerOrchestrationLiveEventOrFail({
|
|
33206
|
+
stream: "shell",
|
|
33207
|
+
event,
|
|
33208
|
+
liveQueue,
|
|
33209
|
+
overflowedRef,
|
|
33210
|
+
replayMetrics
|
|
33211
|
+
});
|
|
32768
33212
|
})), Effect.ensuring(Queue.shutdown(liveQueue)), Effect.ignoreCause({ log: true }), Effect.forkScoped);
|
|
32769
33213
|
const replayStream = makeBoundedReplayStream({
|
|
32770
33214
|
snapshotSequence,
|
|
@@ -32782,8 +33226,9 @@ const makeOrchestrationStreamHelpers = (deps) => {
|
|
|
32782
33226
|
const loadedSnapshot = yield* snapshot;
|
|
32783
33227
|
const snapshotSequence = loadedSnapshot.snapshotSequence;
|
|
32784
33228
|
const liveSubscription = yield* orchestrationEngine.subscribeDomainEvents;
|
|
32785
|
-
const liveQueue = yield* Queue.
|
|
33229
|
+
const liveQueue = yield* Queue.bounded(ORCHESTRATION_LIVE_QUEUE_MAX_EVENTS);
|
|
32786
33230
|
const lastSequenceRef = yield* Ref.make(snapshotSequence);
|
|
33231
|
+
const overflowedRef = yield* Ref.make(false);
|
|
32787
33232
|
const replayBoundary = yield* makeReplayBoundaryTracker(snapshotSequence);
|
|
32788
33233
|
const replayMetrics = yield* makeWsReplayMetrics({
|
|
32789
33234
|
stream: "thread",
|
|
@@ -32796,8 +33241,13 @@ const makeOrchestrationStreamHelpers = (deps) => {
|
|
|
32796
33241
|
})));
|
|
32797
33242
|
yield* Stream.fromSubscription(liveSubscription).pipe(Stream.runForEach((event) => Effect.gen(function* () {
|
|
32798
33243
|
yield* replayBoundary.recordLiveSequence(event.sequence);
|
|
32799
|
-
yield*
|
|
32800
|
-
|
|
33244
|
+
yield* offerOrchestrationLiveEventOrFail({
|
|
33245
|
+
stream: "thread",
|
|
33246
|
+
event,
|
|
33247
|
+
liveQueue,
|
|
33248
|
+
overflowedRef,
|
|
33249
|
+
replayMetrics
|
|
33250
|
+
});
|
|
32801
33251
|
})), Effect.ensuring(Queue.shutdown(liveQueue)), Effect.ignoreCause({ log: true }), Effect.forkScoped);
|
|
32802
33252
|
const replayStream = makeBoundedReplayStream({
|
|
32803
33253
|
snapshotSequence,
|
|
@@ -32829,6 +33279,13 @@ const makeWorktreeOperations = (deps) => {
|
|
|
32829
33279
|
onNone: () => failGitWorkflow(operation, `Worktree ${worktreeId} not found.`),
|
|
32830
33280
|
onSome: Effect.succeed
|
|
32831
33281
|
})));
|
|
33282
|
+
const isProjectRootPath = (candidate, projectRoot) => {
|
|
33283
|
+
const normalize = (value) => {
|
|
33284
|
+
const resolved = path.resolve(value).replace(/[\\/]+$/g, "");
|
|
33285
|
+
return process.platform === "win32" || process.platform === "darwin" ? resolved.toLowerCase() : resolved;
|
|
33286
|
+
};
|
|
33287
|
+
return normalize(candidate) === normalize(projectRoot);
|
|
33288
|
+
};
|
|
32832
33289
|
const dispatchWorktreeCommand = (command, operation) => dispatchNormalizedCommand(command).pipe(Effect.mapError((cause) => toGitManagerError(operation, "Failed to dispatch orchestration command.", cause)), Effect.asVoid);
|
|
32833
33290
|
const launchSetupScriptForWorktreeInBackground = (input) => Effect.gen(function* () {
|
|
32834
33291
|
const requestedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -33052,20 +33509,27 @@ const makeWorktreeOperations = (deps) => {
|
|
|
33052
33509
|
break;
|
|
33053
33510
|
}
|
|
33054
33511
|
}
|
|
33055
|
-
|
|
33056
|
-
|
|
33057
|
-
|
|
33058
|
-
|
|
33059
|
-
|
|
33512
|
+
let worktreePath;
|
|
33513
|
+
if (preparedWorktreePath !== null) {
|
|
33514
|
+
if (isProjectRootPath(preparedWorktreePath, project.workspaceRoot)) return yield* failGitWorkflow(operation, "Cannot create a worktree at the project root.");
|
|
33515
|
+
worktreePath = preparedWorktreePath;
|
|
33516
|
+
} else {
|
|
33517
|
+
const targetPath = resolveWorktreeCheckoutPath({
|
|
33060
33518
|
location: input.worktreeLocation,
|
|
33061
33519
|
appWorktreesRoot: config.worktreesDir,
|
|
33062
33520
|
projectId: input.projectId,
|
|
33063
33521
|
workspaceRoot: project.workspaceRoot,
|
|
33064
33522
|
projectMetadataDir: project.projectMetadataDir,
|
|
33065
33523
|
branchName: branch
|
|
33066
|
-
})
|
|
33067
|
-
|
|
33068
|
-
|
|
33524
|
+
});
|
|
33525
|
+
if (isProjectRootPath(targetPath, project.workspaceRoot)) return yield* failGitWorkflow(operation, "Cannot create a worktree at the project root.");
|
|
33526
|
+
worktreePath = (yield* gitWorkflow.createWorktree({
|
|
33527
|
+
cwd: project.workspaceRoot,
|
|
33528
|
+
refName,
|
|
33529
|
+
...newRefName !== void 0 ? { newRefName } : {},
|
|
33530
|
+
path: targetPath
|
|
33531
|
+
})).worktree.path;
|
|
33532
|
+
if (isProjectRootPath(worktreePath, project.workspaceRoot)) return yield* failGitWorkflow(operation, "Refusing to register a worktree that resolved to the project root.");
|
|
33069
33533
|
ownedWorktreePath = worktreePath;
|
|
33070
33534
|
if (newRefName !== void 0) ownedBranchName = newRefName;
|
|
33071
33535
|
}
|
|
@@ -33206,6 +33670,7 @@ const makeWorktreeOperations = (deps) => {
|
|
|
33206
33670
|
const worktree = yield* loadWorktreeForGitWorkflow(operation, input.worktreeId);
|
|
33207
33671
|
if (worktree.origin === "main") return yield* failGitWorkflow(operation, "Cannot delete the main worktree.");
|
|
33208
33672
|
const project = yield* loadProjectForGitWorkflow(operation, worktree.projectId);
|
|
33673
|
+
if (worktree.worktreePath !== null && isProjectRootPath(worktree.worktreePath, project.workspaceRoot)) return yield* failGitWorkflow(operation, "Cannot delete a worktree that points at the project root.");
|
|
33209
33674
|
if (input.force) {
|
|
33210
33675
|
if (worktree.worktreePath !== null) {
|
|
33211
33676
|
if (existsSync(worktree.worktreePath)) return yield* failGitWorkflow(operation, "Cannot force delete: the worktree path still exists on disk. Use a regular delete instead.");
|
|
@@ -33338,6 +33803,7 @@ function toDiagnosticsProviderProcess(provider) {
|
|
|
33338
33803
|
const makeWsRpcContext = (session) => Effect.gen(function* () {
|
|
33339
33804
|
const currentSessionId = session.sessionId;
|
|
33340
33805
|
const projectionSnapshotQuery = yield* ProjectionSnapshotQuery;
|
|
33806
|
+
const statisticsQuery = yield* StatisticsQuery;
|
|
33341
33807
|
const orchestrationEngine = yield* OrchestrationEngineService;
|
|
33342
33808
|
const checkpointDiffQuery = yield* CheckpointDiffQuery;
|
|
33343
33809
|
const keybindings = yield* Keybindings;
|
|
@@ -33661,6 +34127,7 @@ const makeWsRpcContext = (session) => Effect.gen(function* () {
|
|
|
33661
34127
|
return {
|
|
33662
34128
|
currentSessionId,
|
|
33663
34129
|
projectionSnapshotQuery,
|
|
34130
|
+
statisticsQuery,
|
|
33664
34131
|
orchestrationEngine,
|
|
33665
34132
|
checkpointDiffQuery,
|
|
33666
34133
|
keybindings,
|
|
@@ -33938,9 +34405,9 @@ function recordServerPerfPayload(label, value, record) {
|
|
|
33938
34405
|
//#endregion
|
|
33939
34406
|
//#region src/ws/orchestrationRpc.ts
|
|
33940
34407
|
const makeOrchestrationHandlers = (ctx) => {
|
|
33941
|
-
const {
|
|
34408
|
+
const { ownerEffect, projectionSnapshotQuery, dispatchNormalizedCommand, dispatchWorktreeCommand, serverCommandId, terminalManager, checkpointDiffQuery, orchestrationEngine, enrichOrchestrationEvents, makeReplayableShellStream, makeReplayableThreadStream } = ctx;
|
|
33942
34409
|
return defineWsHandlers({
|
|
33943
|
-
[ORCHESTRATION_WS_METHODS.dispatchCommand]: (command) => observeRpcEffect(ORCHESTRATION_WS_METHODS.dispatchCommand,
|
|
34410
|
+
[ORCHESTRATION_WS_METHODS.dispatchCommand]: (command) => observeRpcEffect(ORCHESTRATION_WS_METHODS.dispatchCommand, ownerEffect(ORCHESTRATION_WS_METHODS.dispatchCommand, Effect.gen(function* () {
|
|
33944
34411
|
const normalizedCommand = yield* normalizeDispatchCommand(command);
|
|
33945
34412
|
const shouldStopSessionAfterArchive = normalizedCommand.type === "thread.archive" ? yield* projectionSnapshotQuery.getThreadShellById(normalizedCommand.threadId).pipe(Effect.map(Option.match({
|
|
33946
34413
|
onNone: () => false,
|
|
@@ -33977,10 +34444,20 @@ const makeOrchestrationHandlers = (ctx) => {
|
|
|
33977
34444
|
message: "Failed to load full thread diff",
|
|
33978
34445
|
cause
|
|
33979
34446
|
}))), { "rpc.aggregate": "orchestration" }),
|
|
34447
|
+
[ORCHESTRATION_WS_METHODS.searchThreadMessages]: (input) => observeRpcEffect(ORCHESTRATION_WS_METHODS.searchThreadMessages, projectionSnapshotQuery.searchThreadMessages({
|
|
34448
|
+
...input,
|
|
34449
|
+
limit: clamp(input.limit, {
|
|
34450
|
+
maximum: 50,
|
|
34451
|
+
minimum: 1
|
|
34452
|
+
})
|
|
34453
|
+
}).pipe(Effect.mapError((cause) => new OrchestrationGetSnapshotError({
|
|
34454
|
+
message: "Failed to search thread messages",
|
|
34455
|
+
cause
|
|
34456
|
+
}))), { "rpc.aggregate": "orchestration" }),
|
|
33980
34457
|
[ORCHESTRATION_WS_METHODS.replayEvents]: (input) => observeRpcEffect(ORCHESTRATION_WS_METHODS.replayEvents, Stream.runCollect(orchestrationEngine.readEvents(clamp(input.fromSequenceExclusive, {
|
|
33981
34458
|
maximum: Number.MAX_SAFE_INTEGER,
|
|
33982
34459
|
minimum: 0
|
|
33983
|
-
}))).pipe(Effect.map((events) => Array.from(events)), Effect.flatMap(enrichOrchestrationEvents), Effect.mapError((cause) => new OrchestrationReplayEventsError({
|
|
34460
|
+
}), ORCHESTRATION_LEGACY_REPLAY_MAX_EVENTS)).pipe(Effect.map((events) => Array.from(events)), Effect.flatMap(enrichOrchestrationEvents), Effect.mapError((cause) => new OrchestrationReplayEventsError({
|
|
33984
34461
|
message: "Failed to replay orchestration events",
|
|
33985
34462
|
cause
|
|
33986
34463
|
}))), { "rpc.aggregate": "orchestration" }),
|
|
@@ -34036,7 +34513,22 @@ const makeOrchestrationHandlers = (ctx) => {
|
|
|
34036
34513
|
threadId: input.threadId,
|
|
34037
34514
|
position: input.position,
|
|
34038
34515
|
changedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
34039
|
-
}, "threads.setManualPosition").pipe(Effect.as({}))), { "rpc.aggregate": "orchestration" })
|
|
34516
|
+
}, "threads.setManualPosition").pipe(Effect.as({}))), { "rpc.aggregate": "orchestration" }),
|
|
34517
|
+
[WS_METHODS.searchThreadMessages]: (input) => observeRpcEffect(WS_METHODS.searchThreadMessages, ownerEffect(WS_METHODS.searchThreadMessages, Effect.gen(function* () {
|
|
34518
|
+
const query = input.query.trim();
|
|
34519
|
+
if (query.length === 0) return { results: [] };
|
|
34520
|
+
return { results: yield* projectionSnapshotQuery.searchThreadMessages({
|
|
34521
|
+
query,
|
|
34522
|
+
...input.projectId ? { projectId: input.projectId } : {},
|
|
34523
|
+
limit: clamp(input.limit ?? 20, {
|
|
34524
|
+
maximum: 50,
|
|
34525
|
+
minimum: 1
|
|
34526
|
+
})
|
|
34527
|
+
}) };
|
|
34528
|
+
}).pipe(Effect.mapError(() => new AuthRpcError({
|
|
34529
|
+
message: "Failed to search thread messages.",
|
|
34530
|
+
status: 403
|
|
34531
|
+
})))), { "rpc.aggregate": "orchestration" })
|
|
34040
34532
|
});
|
|
34041
34533
|
};
|
|
34042
34534
|
//#endregion
|
|
@@ -34111,10 +34603,25 @@ const makeTerminalHandlers = (ctx) => {
|
|
|
34111
34603
|
[WS_METHODS.terminalClear]: (input) => observeRpcEffect(WS_METHODS.terminalClear, ownerEffect(WS_METHODS.terminalClear, terminalManager.clear(input)), { "rpc.aggregate": "terminal" }),
|
|
34112
34604
|
[WS_METHODS.terminalRestart]: (input) => observeRpcEffect(WS_METHODS.terminalRestart, ownerEffect(WS_METHODS.terminalRestart, terminalManager.restart(input)), { "rpc.aggregate": "terminal" }),
|
|
34113
34605
|
[WS_METHODS.terminalClose]: (input) => observeRpcEffect(WS_METHODS.terminalClose, ownerEffect(WS_METHODS.terminalClose, terminalManager.close(input)), { "rpc.aggregate": "terminal" }),
|
|
34114
|
-
[WS_METHODS.subscribeTerminalEvents]: (_input) => observeRpcStream(WS_METHODS.subscribeTerminalEvents, ownerStream(WS_METHODS.subscribeTerminalEvents, Stream.callback((queue) => Effect.acquireRelease(
|
|
34115
|
-
|
|
34116
|
-
|
|
34117
|
-
|
|
34606
|
+
[WS_METHODS.subscribeTerminalEvents]: (_input) => observeRpcStream(WS_METHODS.subscribeTerminalEvents, ownerStream(WS_METHODS.subscribeTerminalEvents, Stream.callback((queue) => Effect.acquireRelease(Effect.gen(function* () {
|
|
34607
|
+
const unsubscribe = yield* terminalManager.subscribe((event) => Effect.gen(function* () {
|
|
34608
|
+
recordServerPerfPayload("server.ws.terminal.events", event);
|
|
34609
|
+
yield* Queue.offer(queue, event);
|
|
34610
|
+
}));
|
|
34611
|
+
const snapshots = yield* terminalManager.listSessions;
|
|
34612
|
+
yield* Effect.forEach(snapshots.filter((snapshot) => snapshot.status === "running"), (snapshot) => {
|
|
34613
|
+
const event = {
|
|
34614
|
+
type: "started",
|
|
34615
|
+
threadId: snapshot.threadId,
|
|
34616
|
+
terminalId: snapshot.terminalId,
|
|
34617
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34618
|
+
snapshot
|
|
34619
|
+
};
|
|
34620
|
+
recordServerPerfPayload("server.ws.terminal.events", event);
|
|
34621
|
+
return Queue.offer(queue, event);
|
|
34622
|
+
}, { discard: true });
|
|
34623
|
+
return unsubscribe;
|
|
34624
|
+
}), (unsubscribe) => Effect.sync(unsubscribe)))), { "rpc.aggregate": "terminal" })
|
|
34118
34625
|
});
|
|
34119
34626
|
};
|
|
34120
34627
|
//#endregion
|
|
@@ -34209,7 +34716,7 @@ const makeSourceControlHandlers = (ctx) => {
|
|
|
34209
34716
|
cwd,
|
|
34210
34717
|
reason: "sourceControl.searchIssues"
|
|
34211
34718
|
})))), { "rpc.aggregate": "source-control" }),
|
|
34212
|
-
[WS_METHODS.sourceControlListChangeRequests]: ({ cwd, state, limit, query }) => observeRpcEffect(WS_METHODS.sourceControlListChangeRequests, sourceControlRegistry.resolve({ cwd }).pipe(Effect.flatMap((provider) => {
|
|
34719
|
+
[WS_METHODS.sourceControlListChangeRequests]: ({ cwd, state, limit, query }) => observeRpcEffect(WS_METHODS.sourceControlListChangeRequests, ownerEffect(WS_METHODS.sourceControlListChangeRequests, sourceControlRegistry.resolve({ cwd }).pipe(Effect.flatMap((provider) => {
|
|
34213
34720
|
const trimmedQuery = query?.trim() ?? "";
|
|
34214
34721
|
if (trimmedQuery.length > 0) return provider.searchChangeRequests({
|
|
34215
34722
|
cwd,
|
|
@@ -34225,7 +34732,7 @@ const makeSourceControlHandlers = (ctx) => {
|
|
|
34225
34732
|
}), Effect.tap(() => refreshLinkedWorktreeSourceControlStates({
|
|
34226
34733
|
cwd,
|
|
34227
34734
|
reason: "sourceControl.listChangeRequests"
|
|
34228
|
-
}))), { "rpc.aggregate": "source-control" }),
|
|
34735
|
+
})))), { "rpc.aggregate": "source-control" }),
|
|
34229
34736
|
[WS_METHODS.sourceControlSearchChangeRequests]: ({ cwd, query, limit }) => observeRpcEffect(WS_METHODS.sourceControlSearchChangeRequests, ownerEffect(WS_METHODS.sourceControlSearchChangeRequests, sourceControlRegistry.resolve({ cwd }).pipe(Effect.flatMap((provider) => provider.searchChangeRequests({
|
|
34230
34737
|
cwd,
|
|
34231
34738
|
query,
|
|
@@ -34303,7 +34810,7 @@ const makeSourceControlHandlers = (ctx) => {
|
|
|
34303
34810
|
})), { "rpc.aggregate": "source-control" }),
|
|
34304
34811
|
[WS_METHODS.sourceControlListIssueLabels]: ({ cwd }) => observeRpcEffect(WS_METHODS.sourceControlListIssueLabels, ownerEffect(WS_METHODS.sourceControlListIssueLabels, sourceControlRegistry.resolve({ cwd }).pipe(Effect.flatMap((provider) => provider.listLabels({ cwd })))), { "rpc.aggregate": "source-control" }),
|
|
34305
34812
|
[WS_METHODS.sourceControlListIssueAssignees]: ({ cwd }) => observeRpcEffect(WS_METHODS.sourceControlListIssueAssignees, ownerEffect(WS_METHODS.sourceControlListIssueAssignees, sourceControlRegistry.resolve({ cwd }).pipe(Effect.flatMap((provider) => provider.listAssignees({ cwd })))), { "rpc.aggregate": "source-control" }),
|
|
34306
|
-
[WS_METHODS.sourceControlListWorkflowRuns]: ({ cwd, pullRequestNumber, commitSha, limit }) => observeRpcEffect(WS_METHODS.sourceControlListWorkflowRuns, ownerEffect(WS_METHODS.sourceControlListWorkflowRuns, callSourceControlWorkflowMethod({
|
|
34813
|
+
[WS_METHODS.sourceControlListWorkflowRuns]: ({ cwd, pullRequestNumber, commitSha, branch, limit }) => observeRpcEffect(WS_METHODS.sourceControlListWorkflowRuns, ownerEffect(WS_METHODS.sourceControlListWorkflowRuns, callSourceControlWorkflowMethod({
|
|
34307
34814
|
cwd,
|
|
34308
34815
|
operation: "listWorkflowRuns",
|
|
34309
34816
|
invoke: (provider) => {
|
|
@@ -34312,6 +34819,7 @@ const makeSourceControlHandlers = (ctx) => {
|
|
|
34312
34819
|
cwd,
|
|
34313
34820
|
...pullRequestNumber !== void 0 ? { pullRequestNumber } : {},
|
|
34314
34821
|
...commitSha !== void 0 ? { commitSha } : {},
|
|
34822
|
+
...branch !== void 0 ? { branch } : {},
|
|
34315
34823
|
...limit !== void 0 ? { limit } : {}
|
|
34316
34824
|
});
|
|
34317
34825
|
}
|
|
@@ -34975,12 +35483,19 @@ const makeProviderHandlers = (ctx) => {
|
|
|
34975
35483
|
});
|
|
34976
35484
|
};
|
|
34977
35485
|
//#endregion
|
|
35486
|
+
//#region src/ws/statisticsRpc.ts
|
|
35487
|
+
const makeStatisticsHandlers = (ctx) => {
|
|
35488
|
+
const { statisticsQuery, ownerEffect } = ctx;
|
|
35489
|
+
return defineWsHandlers({ [WS_METHODS.serverGetStatistics]: (_input) => observeRpcEffect(WS_METHODS.serverGetStatistics, ownerEffect(WS_METHODS.serverGetStatistics, statisticsQuery.getStatistics().pipe(Effect.orDie)), { "rpc.aggregate": "server" }) });
|
|
35490
|
+
};
|
|
35491
|
+
//#endregion
|
|
34978
35492
|
//#region src/ws/index.ts
|
|
34979
35493
|
const makeWsRpcLayer = (session) => WsRpcGroup.toLayer(Effect.gen(function* () {
|
|
34980
35494
|
const ctx = yield* makeWsRpcContext(session);
|
|
34981
35495
|
return WsRpcGroup.of({
|
|
34982
35496
|
...makeOrchestrationHandlers(ctx),
|
|
34983
35497
|
...makeProviderHandlers(ctx),
|
|
35498
|
+
...makeStatisticsHandlers(ctx),
|
|
34984
35499
|
...makeSourceControlHandlers(ctx),
|
|
34985
35500
|
...makeProjectHandlers(ctx),
|
|
34986
35501
|
...makeGitHandlers(ctx),
|
|
@@ -35071,7 +35586,7 @@ const TelemetryEnvConfig = Config.all({
|
|
|
35071
35586
|
maxBufferedEvents: Config.number("RYCO_TELEMETRY_MAX_BUFFERED_EVENTS").pipe(Config.withDefault(1e3))
|
|
35072
35587
|
});
|
|
35073
35588
|
const makeAnalyticsService = Effect.gen(function* () {
|
|
35074
|
-
const telemetryConfig = yield* TelemetryEnvConfig
|
|
35589
|
+
const telemetryConfig = yield* TelemetryEnvConfig;
|
|
35075
35590
|
const httpClient = yield* HttpClient.HttpClient;
|
|
35076
35591
|
const serverConfig = yield* ServerConfig;
|
|
35077
35592
|
const identifier = yield* getTelemetryIdentifier;
|
|
@@ -37398,6 +37913,8 @@ const DEFAULT_PERSIST_DEBOUNCE_MS = 40;
|
|
|
37398
37913
|
const DEFAULT_SUBPROCESS_POLL_INTERVAL_MS = 1e3;
|
|
37399
37914
|
const DEFAULT_PROCESS_KILL_GRACE_MS = 1e3;
|
|
37400
37915
|
const DEFAULT_MAX_RETAINED_INACTIVE_SESSIONS = 128;
|
|
37916
|
+
const DEFAULT_MAX_PENDING_PROCESS_EVENTS = 2048;
|
|
37917
|
+
const DEFAULT_MAX_PENDING_PROCESS_OUTPUT_BYTES = 2 * 1024 * 1024;
|
|
37401
37918
|
const DEFAULT_OPEN_COLS = 120;
|
|
37402
37919
|
const DEFAULT_OPEN_ROWS = 30;
|
|
37403
37920
|
const TERMINAL_ENV_BLOCKLIST = new Set([
|
|
@@ -37454,13 +37971,86 @@ function cleanupProcessHandles(session) {
|
|
|
37454
37971
|
session.unsubscribeExit?.();
|
|
37455
37972
|
session.unsubscribeExit = null;
|
|
37456
37973
|
}
|
|
37457
|
-
function
|
|
37974
|
+
function clearPendingProcessEvents(session) {
|
|
37975
|
+
session.pendingProcessEvents = [];
|
|
37976
|
+
session.pendingProcessEventIndex = 0;
|
|
37977
|
+
session.pendingProcessOutputBytes = 0;
|
|
37978
|
+
session.processEventDrainRunning = false;
|
|
37979
|
+
}
|
|
37980
|
+
function enqueueProcessEvent(session, expectedPid, event, limits) {
|
|
37458
37981
|
if (!session.process || session.status !== "running" || session.pid !== expectedPid) return false;
|
|
37982
|
+
if (event.type === "output" && session.pendingProcessEvents.some((pendingEvent) => pendingEvent.type === "exit")) return false;
|
|
37983
|
+
compactPendingProcessEvents(session);
|
|
37459
37984
|
session.pendingProcessEvents.push(event);
|
|
37985
|
+
if (event.type === "output") session.pendingProcessOutputBytes += event.byteLength;
|
|
37986
|
+
enforcePendingProcessEventLimits(session, limits);
|
|
37460
37987
|
if (session.processEventDrainRunning) return false;
|
|
37461
37988
|
session.processEventDrainRunning = true;
|
|
37462
37989
|
return true;
|
|
37463
37990
|
}
|
|
37991
|
+
function compactPendingProcessEvents(session) {
|
|
37992
|
+
if (session.pendingProcessEventIndex <= 0) return;
|
|
37993
|
+
session.pendingProcessEvents = session.pendingProcessEvents.slice(session.pendingProcessEventIndex);
|
|
37994
|
+
session.pendingProcessEventIndex = 0;
|
|
37995
|
+
}
|
|
37996
|
+
function coalesceOldestPendingOutputPair(session) {
|
|
37997
|
+
for (let index = 0; index < session.pendingProcessEvents.length - 1; index += 1) {
|
|
37998
|
+
const current = session.pendingProcessEvents[index];
|
|
37999
|
+
const next = session.pendingProcessEvents[index + 1];
|
|
38000
|
+
if (current?.type !== "output" || next?.type !== "output") continue;
|
|
38001
|
+
session.pendingProcessEvents.splice(index, 2, {
|
|
38002
|
+
type: "output",
|
|
38003
|
+
data: `${current.data}${next.data}`,
|
|
38004
|
+
byteLength: current.byteLength + next.byteLength
|
|
38005
|
+
});
|
|
38006
|
+
return true;
|
|
38007
|
+
}
|
|
38008
|
+
return false;
|
|
38009
|
+
}
|
|
38010
|
+
function trimOutputDataToApproxBytes(data, maxBytes) {
|
|
38011
|
+
if (maxBytes <= 0 || data.length === 0) return {
|
|
38012
|
+
data: "",
|
|
38013
|
+
byteLength: 0
|
|
38014
|
+
};
|
|
38015
|
+
let nextData = data;
|
|
38016
|
+
let byteLength = approximateTextBytes(nextData);
|
|
38017
|
+
while (byteLength > maxBytes && nextData.length > 0) {
|
|
38018
|
+
const excessBytes = byteLength - maxBytes;
|
|
38019
|
+
const sliceStart = Math.min(nextData.length, Math.max(1, excessBytes));
|
|
38020
|
+
nextData = nextData.slice(sliceStart);
|
|
38021
|
+
byteLength = approximateTextBytes(nextData);
|
|
38022
|
+
}
|
|
38023
|
+
return {
|
|
38024
|
+
data: nextData,
|
|
38025
|
+
byteLength
|
|
38026
|
+
};
|
|
38027
|
+
}
|
|
38028
|
+
function trimPendingOutputBytesToLimit(session, maxPendingProcessOutputBytes) {
|
|
38029
|
+
if (session.pendingProcessOutputBytes <= maxPendingProcessOutputBytes) return;
|
|
38030
|
+
for (let index = 0; index < session.pendingProcessEvents.length; index += 1) {
|
|
38031
|
+
if (session.pendingProcessOutputBytes <= maxPendingProcessOutputBytes) return;
|
|
38032
|
+
const event = session.pendingProcessEvents[index];
|
|
38033
|
+
if (event?.type !== "output") continue;
|
|
38034
|
+
const targetEventBytes = Math.max(0, event.byteLength - (session.pendingProcessOutputBytes - maxPendingProcessOutputBytes));
|
|
38035
|
+
if (targetEventBytes <= 0) {
|
|
38036
|
+
session.pendingProcessEvents.splice(index, 1);
|
|
38037
|
+
session.pendingProcessOutputBytes = Math.max(0, session.pendingProcessOutputBytes - event.byteLength);
|
|
38038
|
+
index -= 1;
|
|
38039
|
+
continue;
|
|
38040
|
+
}
|
|
38041
|
+
const trimmed = trimOutputDataToApproxBytes(event.data, targetEventBytes);
|
|
38042
|
+
session.pendingProcessEvents[index] = {
|
|
38043
|
+
type: "output",
|
|
38044
|
+
data: trimmed.data,
|
|
38045
|
+
byteLength: trimmed.byteLength
|
|
38046
|
+
};
|
|
38047
|
+
session.pendingProcessOutputBytes = Math.max(0, session.pendingProcessOutputBytes - (event.byteLength - trimmed.byteLength));
|
|
38048
|
+
}
|
|
38049
|
+
}
|
|
38050
|
+
function enforcePendingProcessEventLimits(session, limits) {
|
|
38051
|
+
while (session.pendingProcessEvents.length > limits.maxPendingProcessEvents && coalesceOldestPendingOutputPair(session));
|
|
38052
|
+
trimPendingOutputBytesToLimit(session, limits.maxPendingProcessOutputBytes);
|
|
38053
|
+
}
|
|
37464
38054
|
function defaultShellResolver(platform = process.platform, env = process.env) {
|
|
37465
38055
|
if (platform === "win32") return "pwsh.exe";
|
|
37466
38056
|
return env.SHELL ?? "bash";
|
|
@@ -37827,6 +38417,10 @@ const makeTerminalManagerWithOptions = Effect.fn("makeTerminalManagerWithOptions
|
|
|
37827
38417
|
const subprocessPollIntervalMs = options.subprocessPollIntervalMs ?? DEFAULT_SUBPROCESS_POLL_INTERVAL_MS;
|
|
37828
38418
|
const processKillGraceMs = options.processKillGraceMs ?? DEFAULT_PROCESS_KILL_GRACE_MS;
|
|
37829
38419
|
const maxRetainedInactiveSessions = options.maxRetainedInactiveSessions ?? DEFAULT_MAX_RETAINED_INACTIVE_SESSIONS;
|
|
38420
|
+
const pendingProcessEventLimits = {
|
|
38421
|
+
maxPendingProcessEvents: Math.max(1, options.maxPendingProcessEvents ?? DEFAULT_MAX_PENDING_PROCESS_EVENTS),
|
|
38422
|
+
maxPendingProcessOutputBytes: Math.max(1, options.maxPendingProcessOutputBytes ?? DEFAULT_MAX_PENDING_PROCESS_OUTPUT_BYTES)
|
|
38423
|
+
};
|
|
37830
38424
|
yield* fileSystem.makeDirectory(logsDir, { recursive: true }).pipe(Effect.orDie);
|
|
37831
38425
|
const managerStateRef = yield* SynchronizedRef.make({
|
|
37832
38426
|
sessions: /* @__PURE__ */ new Map(),
|
|
@@ -38063,16 +38657,12 @@ const makeTerminalManagerWithOptions = Effect.fn("makeTerminalManagerWithOptions
|
|
|
38063
38657
|
while (true) {
|
|
38064
38658
|
const action = yield* Effect.sync(() => {
|
|
38065
38659
|
if (session.pid !== expectedPid || !session.process || session.status !== "running") {
|
|
38066
|
-
session
|
|
38067
|
-
session.pendingProcessEventIndex = 0;
|
|
38068
|
-
session.processEventDrainRunning = false;
|
|
38660
|
+
clearPendingProcessEvents(session);
|
|
38069
38661
|
return { type: "idle" };
|
|
38070
38662
|
}
|
|
38071
38663
|
const nextEvent = session.pendingProcessEvents[session.pendingProcessEventIndex];
|
|
38072
38664
|
if (!nextEvent) {
|
|
38073
|
-
session
|
|
38074
|
-
session.pendingProcessEventIndex = 0;
|
|
38075
|
-
session.processEventDrainRunning = false;
|
|
38665
|
+
clearPendingProcessEvents(session);
|
|
38076
38666
|
return { type: "idle" };
|
|
38077
38667
|
}
|
|
38078
38668
|
session.pendingProcessEventIndex += 1;
|
|
@@ -38081,6 +38671,7 @@ const makeTerminalManagerWithOptions = Effect.fn("makeTerminalManagerWithOptions
|
|
|
38081
38671
|
session.pendingProcessEventIndex = 0;
|
|
38082
38672
|
}
|
|
38083
38673
|
if (nextEvent.type === "output") {
|
|
38674
|
+
session.pendingProcessOutputBytes = Math.max(0, session.pendingProcessOutputBytes - nextEvent.byteLength);
|
|
38084
38675
|
const sanitized = sanitizeTerminalHistoryChunk(session.pendingHistoryControlSequence, nextEvent.data);
|
|
38085
38676
|
session.pendingHistoryControlSequence = sanitized.pendingControlSequence;
|
|
38086
38677
|
if (sanitized.visibleText.length > 0) session.history = capHistory(`${session.history}${sanitized.visibleText}`, historyLineLimit);
|
|
@@ -38100,9 +38691,7 @@ const makeTerminalManagerWithOptions = Effect.fn("makeTerminalManagerWithOptions
|
|
|
38100
38691
|
session.hasRunningSubprocess = false;
|
|
38101
38692
|
session.status = "exited";
|
|
38102
38693
|
session.pendingHistoryControlSequence = "";
|
|
38103
|
-
session
|
|
38104
|
-
session.pendingProcessEventIndex = 0;
|
|
38105
|
-
session.processEventDrainRunning = false;
|
|
38694
|
+
clearPendingProcessEvents(session);
|
|
38106
38695
|
session.exitCode = Number.isInteger(nextEvent.event.exitCode) ? nextEvent.event.exitCode : null;
|
|
38107
38696
|
session.exitSignal = Number.isInteger(nextEvent.event.signal) ? nextEvent.event.signal : null;
|
|
38108
38697
|
session.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -38150,9 +38739,7 @@ const makeTerminalManagerWithOptions = Effect.fn("makeTerminalManagerWithOptions
|
|
|
38150
38739
|
session.hasRunningSubprocess = false;
|
|
38151
38740
|
session.status = "exited";
|
|
38152
38741
|
session.pendingHistoryControlSequence = "";
|
|
38153
|
-
session
|
|
38154
|
-
session.pendingProcessEventIndex = 0;
|
|
38155
|
-
session.processEventDrainRunning = false;
|
|
38742
|
+
clearPendingProcessEvents(session);
|
|
38156
38743
|
session.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
38157
38744
|
return [void 0, state];
|
|
38158
38745
|
});
|
|
@@ -38204,9 +38791,7 @@ const makeTerminalManagerWithOptions = Effect.fn("makeTerminalManagerWithOptions
|
|
|
38204
38791
|
session.exitCode = null;
|
|
38205
38792
|
session.exitSignal = null;
|
|
38206
38793
|
session.hasRunningSubprocess = false;
|
|
38207
|
-
session
|
|
38208
|
-
session.pendingProcessEventIndex = 0;
|
|
38209
|
-
session.processEventDrainRunning = false;
|
|
38794
|
+
clearPendingProcessEvents(session);
|
|
38210
38795
|
session.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
38211
38796
|
return [void 0, state];
|
|
38212
38797
|
});
|
|
@@ -38220,15 +38805,16 @@ const makeTerminalManagerWithOptions = Effect.fn("makeTerminalManagerWithOptions
|
|
|
38220
38805
|
const unsubscribeData = ptyProcess.onData((data) => {
|
|
38221
38806
|
if (!enqueueProcessEvent(session, processPid, {
|
|
38222
38807
|
type: "output",
|
|
38223
|
-
data
|
|
38224
|
-
|
|
38808
|
+
data,
|
|
38809
|
+
byteLength: approximateTextBytes(data)
|
|
38810
|
+
}, pendingProcessEventLimits)) return;
|
|
38225
38811
|
runFork(drainProcessEvents(session, processPid));
|
|
38226
38812
|
});
|
|
38227
38813
|
const unsubscribeExit = ptyProcess.onExit((event) => {
|
|
38228
38814
|
if (!enqueueProcessEvent(session, processPid, {
|
|
38229
38815
|
type: "exit",
|
|
38230
38816
|
event
|
|
38231
|
-
})) return;
|
|
38817
|
+
}, pendingProcessEventLimits)) return;
|
|
38232
38818
|
runFork(drainProcessEvents(session, processPid));
|
|
38233
38819
|
});
|
|
38234
38820
|
yield* modifyManagerState((state) => {
|
|
@@ -38260,9 +38846,7 @@ const makeTerminalManagerWithOptions = Effect.fn("makeTerminalManagerWithOptions
|
|
|
38260
38846
|
session.unsubscribeData = null;
|
|
38261
38847
|
session.unsubscribeExit = null;
|
|
38262
38848
|
session.hasRunningSubprocess = false;
|
|
38263
|
-
session
|
|
38264
|
-
session.pendingProcessEventIndex = 0;
|
|
38265
|
-
session.processEventDrainRunning = false;
|
|
38849
|
+
clearPendingProcessEvents(session);
|
|
38266
38850
|
session.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
38267
38851
|
return [void 0, state];
|
|
38268
38852
|
});
|
|
@@ -38372,6 +38956,7 @@ const makeTerminalManagerWithOptions = Effect.fn("makeTerminalManagerWithOptions
|
|
|
38372
38956
|
pendingHistoryControlSequence: "",
|
|
38373
38957
|
pendingProcessEvents: [],
|
|
38374
38958
|
pendingProcessEventIndex: 0,
|
|
38959
|
+
pendingProcessOutputBytes: 0,
|
|
38375
38960
|
processEventDrainRunning: false,
|
|
38376
38961
|
exitCode: null,
|
|
38377
38962
|
exitSignal: null,
|
|
@@ -38418,18 +39003,14 @@ const makeTerminalManagerWithOptions = Effect.fn("makeTerminalManagerWithOptions
|
|
|
38418
39003
|
liveSession.runtimeEnv = nextRuntimeEnv;
|
|
38419
39004
|
liveSession.history = "";
|
|
38420
39005
|
liveSession.pendingHistoryControlSequence = "";
|
|
38421
|
-
liveSession
|
|
38422
|
-
liveSession.pendingProcessEventIndex = 0;
|
|
38423
|
-
liveSession.processEventDrainRunning = false;
|
|
39006
|
+
clearPendingProcessEvents(liveSession);
|
|
38424
39007
|
yield* persistHistory(liveSession.threadId, liveSession.terminalId, liveSession.history);
|
|
38425
39008
|
} else if (liveSession.status === "exited" || liveSession.status === "error") {
|
|
38426
39009
|
liveSession.runtimeEnv = nextRuntimeEnv;
|
|
38427
39010
|
liveSession.worktreePath = input.worktreePath ?? null;
|
|
38428
39011
|
liveSession.history = "";
|
|
38429
39012
|
liveSession.pendingHistoryControlSequence = "";
|
|
38430
|
-
liveSession
|
|
38431
|
-
liveSession.pendingProcessEventIndex = 0;
|
|
38432
|
-
liveSession.processEventDrainRunning = false;
|
|
39013
|
+
clearPendingProcessEvents(liveSession);
|
|
38433
39014
|
yield* persistHistory(liveSession.threadId, liveSession.terminalId, liveSession.history);
|
|
38434
39015
|
}
|
|
38435
39016
|
if (!liveSession.process) {
|
|
@@ -38483,9 +39064,7 @@ const makeTerminalManagerWithOptions = Effect.fn("makeTerminalManagerWithOptions
|
|
|
38483
39064
|
const session = yield* requireSession(input.threadId, terminalId);
|
|
38484
39065
|
session.history = "";
|
|
38485
39066
|
session.pendingHistoryControlSequence = "";
|
|
38486
|
-
session
|
|
38487
|
-
session.pendingProcessEventIndex = 0;
|
|
38488
|
-
session.processEventDrainRunning = false;
|
|
39067
|
+
clearPendingProcessEvents(session);
|
|
38489
39068
|
session.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
38490
39069
|
yield* persistHistory(input.threadId, terminalId, session.history);
|
|
38491
39070
|
yield* publishEvent({
|
|
@@ -38516,6 +39095,7 @@ const makeTerminalManagerWithOptions = Effect.fn("makeTerminalManagerWithOptions
|
|
|
38516
39095
|
pendingHistoryControlSequence: "",
|
|
38517
39096
|
pendingProcessEvents: [],
|
|
38518
39097
|
pendingProcessEventIndex: 0,
|
|
39098
|
+
pendingProcessOutputBytes: 0,
|
|
38519
39099
|
processEventDrainRunning: false,
|
|
38520
39100
|
exitCode: null,
|
|
38521
39101
|
exitSignal: null,
|
|
@@ -38549,9 +39129,7 @@ const makeTerminalManagerWithOptions = Effect.fn("makeTerminalManagerWithOptions
|
|
|
38549
39129
|
const rows = input.rows ?? session.rows;
|
|
38550
39130
|
session.history = "";
|
|
38551
39131
|
session.pendingHistoryControlSequence = "";
|
|
38552
|
-
session
|
|
38553
|
-
session.pendingProcessEventIndex = 0;
|
|
38554
|
-
session.processEventDrainRunning = false;
|
|
39132
|
+
clearPendingProcessEvents(session);
|
|
38555
39133
|
yield* persistHistory(input.threadId, terminalId, session.history);
|
|
38556
39134
|
yield* startSession(session, {
|
|
38557
39135
|
threadId: input.threadId,
|
|
@@ -38573,6 +39151,7 @@ const makeTerminalManagerWithOptions = Effect.fn("makeTerminalManagerWithOptions
|
|
|
38573
39151
|
yield* Effect.forEach(threadSessions, (session) => closeSession(input.threadId, session.terminalId, false), { discard: true });
|
|
38574
39152
|
if (input.deleteHistory) yield* deleteAllHistoryForThread(input.threadId);
|
|
38575
39153
|
}));
|
|
39154
|
+
const listSessions = SynchronizedRef.get(managerStateRef).pipe(Effect.map((state) => [...state.sessions.values()].map(snapshot).toSorted((left, right) => right.updatedAt.localeCompare(left.updatedAt))));
|
|
38576
39155
|
return {
|
|
38577
39156
|
open,
|
|
38578
39157
|
write,
|
|
@@ -38581,6 +39160,7 @@ const makeTerminalManagerWithOptions = Effect.fn("makeTerminalManagerWithOptions
|
|
|
38581
39160
|
restart,
|
|
38582
39161
|
close,
|
|
38583
39162
|
listDiagnostics: SynchronizedRef.get(managerStateRef).pipe(Effect.map((state) => [...state.sessions.values()].map(diagnosticsSnapshot).toSorted((left, right) => right.updatedAt.localeCompare(left.updatedAt)))),
|
|
39163
|
+
listSessions,
|
|
38584
39164
|
subscribe: (listener) => Effect.sync(() => {
|
|
38585
39165
|
terminalEventListeners.add(listener);
|
|
38586
39166
|
return () => {
|
|
@@ -39076,7 +39656,7 @@ function isGitRepository(cwd) {
|
|
|
39076
39656
|
//#endregion
|
|
39077
39657
|
//#region src/orchestration/Layers/ProviderRuntimeIngestion.ts
|
|
39078
39658
|
const providerTurnKey = (threadId, turnId) => `${threadId}:${turnId}`;
|
|
39079
|
-
const providerCommandId = (event, tag) => CommandId.make(`provider:${event.eventId}:${tag}:${
|
|
39659
|
+
const providerCommandId = (event, tag, discriminator) => CommandId.make(discriminator === void 0 ? `provider:${event.eventId}:${tag}` : `provider:${event.eventId}:${tag}:${discriminator}`);
|
|
39080
39660
|
const liveAssistantDeltaBufferKey = (threadId, messageId) => `${threadId}:${messageId}`;
|
|
39081
39661
|
const TURN_MESSAGE_IDS_BY_TURN_CACHE_CAPACITY = 1e4;
|
|
39082
39662
|
const TURN_MESSAGE_IDS_BY_TURN_TTL = Duration.minutes(120);
|
|
@@ -39150,6 +39730,7 @@ function rawPayloadThreadId(event) {
|
|
|
39150
39730
|
return asTrimmedString(asRecord(event.raw?.payload)?.threadId);
|
|
39151
39731
|
}
|
|
39152
39732
|
function collabReceiverThreadIdsFromRuntimeEvent(event) {
|
|
39733
|
+
if (event.type === "subagent.started" || event.type === "subagent.updated" || event.type === "subagent.completed") return event.payload.subagent.providerThreadId ? [event.payload.subagent.providerThreadId] : [];
|
|
39153
39734
|
if (event.type !== "item.started" && event.type !== "item.updated" && event.type !== "item.completed") return [];
|
|
39154
39735
|
if (event.payload.itemType !== "collab_agent_tool_call") return [];
|
|
39155
39736
|
const item = asRecord(asRecord(event.payload.data)?.item);
|
|
@@ -39207,6 +39788,9 @@ function normalizeRuntimeTurnState(value) {
|
|
|
39207
39788
|
default: return "completed";
|
|
39208
39789
|
}
|
|
39209
39790
|
}
|
|
39791
|
+
function isTerminalProjectionTurnState(state) {
|
|
39792
|
+
return state === "completed" || state === "error" || state === "interrupted";
|
|
39793
|
+
}
|
|
39210
39794
|
function orchestrationSessionStatusFromRuntimeState(state) {
|
|
39211
39795
|
switch (state) {
|
|
39212
39796
|
case "starting": return "starting";
|
|
@@ -39394,6 +39978,53 @@ function runtimeEventToActivities(event) {
|
|
|
39394
39978
|
turnId: toTurnId$1(event.turnId) ?? null,
|
|
39395
39979
|
...maybeSequence
|
|
39396
39980
|
}];
|
|
39981
|
+
case "subagent.started": return [{
|
|
39982
|
+
id: event.eventId,
|
|
39983
|
+
createdAt: event.createdAt,
|
|
39984
|
+
tone: "tool",
|
|
39985
|
+
kind: "subagent.started",
|
|
39986
|
+
summary: `${event.payload.subagent.label ?? "Subagent"} started`,
|
|
39987
|
+
payload: {
|
|
39988
|
+
itemType: "collab_agent_tool_call",
|
|
39989
|
+
status: "running",
|
|
39990
|
+
subagent: event.payload.subagent
|
|
39991
|
+
},
|
|
39992
|
+
turnId: toTurnId$1(event.turnId) ?? null,
|
|
39993
|
+
...maybeSequence
|
|
39994
|
+
}];
|
|
39995
|
+
case "subagent.updated": return [{
|
|
39996
|
+
id: event.eventId,
|
|
39997
|
+
createdAt: event.createdAt,
|
|
39998
|
+
tone: "tool",
|
|
39999
|
+
kind: "subagent.updated",
|
|
40000
|
+
summary: event.payload.summary ?? `${event.payload.subagent.label ?? "Subagent"} updated`,
|
|
40001
|
+
payload: {
|
|
40002
|
+
itemType: "collab_agent_tool_call",
|
|
40003
|
+
...event.payload.status ? { status: event.payload.status } : {},
|
|
40004
|
+
subagent: event.payload.subagent,
|
|
40005
|
+
...event.payload.detail ? { detail: truncateDetail(event.payload.detail) } : {},
|
|
40006
|
+
...event.payload.summary ? { summary: truncateDetail(event.payload.summary) } : {},
|
|
40007
|
+
...event.payload.usage !== void 0 ? { usage: event.payload.usage } : {}
|
|
40008
|
+
},
|
|
40009
|
+
turnId: toTurnId$1(event.turnId) ?? null,
|
|
40010
|
+
...maybeSequence
|
|
40011
|
+
}];
|
|
40012
|
+
case "subagent.completed": return [{
|
|
40013
|
+
id: event.eventId,
|
|
40014
|
+
createdAt: event.createdAt,
|
|
40015
|
+
tone: event.payload.status === "failed" ? "error" : "tool",
|
|
40016
|
+
kind: "subagent.completed",
|
|
40017
|
+
summary: event.payload.status === "failed" ? `${event.payload.subagent.label ?? "Subagent"} failed` : event.payload.status === "stopped" ? `${event.payload.subagent.label ?? "Subagent"} stopped` : `${event.payload.subagent.label ?? "Subagent"} completed`,
|
|
40018
|
+
payload: {
|
|
40019
|
+
itemType: "collab_agent_tool_call",
|
|
40020
|
+
status: event.payload.status,
|
|
40021
|
+
subagent: event.payload.subagent,
|
|
40022
|
+
...event.payload.summary ? { detail: truncateDetail(event.payload.summary) } : {},
|
|
40023
|
+
...event.payload.usage !== void 0 ? { usage: event.payload.usage } : {}
|
|
40024
|
+
},
|
|
40025
|
+
turnId: toTurnId$1(event.turnId) ?? null,
|
|
40026
|
+
...maybeSequence
|
|
40027
|
+
}];
|
|
39397
40028
|
case "thread.state.changed":
|
|
39398
40029
|
if (event.payload.state !== "compacted") return [];
|
|
39399
40030
|
return [{
|
|
@@ -39586,7 +40217,7 @@ const make$3 = Effect.gen(function* () {
|
|
|
39586
40217
|
}
|
|
39587
40218
|
yield* orchestrationEngine.dispatch({
|
|
39588
40219
|
type: "thread.message.assistant.delta",
|
|
39589
|
-
commandId: providerCommandId(buffer.event, input.commandTag),
|
|
40220
|
+
commandId: providerCommandId(buffer.event, input.commandTag, String(buffer.messageId)),
|
|
39590
40221
|
threadId: buffer.threadId,
|
|
39591
40222
|
messageId: buffer.messageId,
|
|
39592
40223
|
delta: buffer.text,
|
|
@@ -39665,9 +40296,10 @@ const make$3 = Effect.gen(function* () {
|
|
|
39665
40296
|
};
|
|
39666
40297
|
const upsertSubagentMessageActivity = (input) => Effect.gen(function* () {
|
|
39667
40298
|
const sessionSequence = input.event.sessionSequence;
|
|
40299
|
+
const commandKey = `${input.providerThreadId}:${input.providerItemId}`;
|
|
39668
40300
|
yield* orchestrationEngine.dispatch({
|
|
39669
40301
|
type: "thread.activity.append",
|
|
39670
|
-
commandId: providerCommandId(input.event, "subagent-message-upsert"),
|
|
40302
|
+
commandId: providerCommandId(input.event, "subagent-message-upsert", commandKey),
|
|
39671
40303
|
threadId: input.threadId,
|
|
39672
40304
|
activity: {
|
|
39673
40305
|
id: subagentMessageActivityId({
|
|
@@ -39685,6 +40317,7 @@ const make$3 = Effect.gen(function* () {
|
|
|
39685
40317
|
streaming: input.streaming,
|
|
39686
40318
|
providerThreadId: input.providerThreadId,
|
|
39687
40319
|
providerItemId: input.providerItemId,
|
|
40320
|
+
...input.subagentId ? { subagentId: input.subagentId } : {},
|
|
39688
40321
|
...input.event.providerRefs ? { providerRefs: input.event.providerRefs } : {}
|
|
39689
40322
|
},
|
|
39690
40323
|
turnId: toTurnId$1(input.event.turnId) ?? null,
|
|
@@ -39724,6 +40357,16 @@ const make$3 = Effect.gen(function* () {
|
|
|
39724
40357
|
streaming: false
|
|
39725
40358
|
});
|
|
39726
40359
|
});
|
|
40360
|
+
const bufferedSubagentProviderItemIds = (input) => {
|
|
40361
|
+
const prefix = subagentMessageBufferKey({
|
|
40362
|
+
threadId: input.threadId,
|
|
40363
|
+
providerThreadId: input.providerThreadId,
|
|
40364
|
+
providerItemId: ""
|
|
40365
|
+
});
|
|
40366
|
+
const providerItemIds = /* @__PURE__ */ new Set();
|
|
40367
|
+
for (const key of subagentMessageTextByKey.keys()) if (key.startsWith(prefix)) providerItemIds.add(key.slice(prefix.length));
|
|
40368
|
+
return [...providerItemIds];
|
|
40369
|
+
};
|
|
39727
40370
|
const clearSubagentMessageBuffersForThread = (threadId) => Effect.sync(() => {
|
|
39728
40371
|
const prefix = `${threadId}:`;
|
|
39729
40372
|
for (const key of subagentMessageTextByKey.keys()) if (key.startsWith(prefix)) subagentMessageTextByKey.delete(key);
|
|
@@ -39757,7 +40400,7 @@ const make$3 = Effect.gen(function* () {
|
|
|
39757
40400
|
if (!hasRenderableAssistantText(bufferedText)) return false;
|
|
39758
40401
|
yield* orchestrationEngine.dispatch({
|
|
39759
40402
|
type: "thread.message.assistant.delta",
|
|
39760
|
-
commandId: providerCommandId(input.event, input.commandTag),
|
|
40403
|
+
commandId: providerCommandId(input.event, input.commandTag, String(input.messageId)),
|
|
39761
40404
|
threadId: input.threadId,
|
|
39762
40405
|
messageId: input.messageId,
|
|
39763
40406
|
delta: bufferedText,
|
|
@@ -39785,7 +40428,7 @@ const make$3 = Effect.gen(function* () {
|
|
|
39785
40428
|
const hasRenderableText = hasRenderableAssistantText(text);
|
|
39786
40429
|
if (hasRenderableText) yield* orchestrationEngine.dispatch({
|
|
39787
40430
|
type: "thread.message.assistant.delta",
|
|
39788
|
-
commandId: providerCommandId(input.event, input.finalDeltaCommandTag),
|
|
40431
|
+
commandId: providerCommandId(input.event, input.finalDeltaCommandTag, String(input.messageId)),
|
|
39789
40432
|
threadId: input.threadId,
|
|
39790
40433
|
messageId: input.messageId,
|
|
39791
40434
|
delta: text,
|
|
@@ -39794,7 +40437,7 @@ const make$3 = Effect.gen(function* () {
|
|
|
39794
40437
|
});
|
|
39795
40438
|
if (input.hasProjectedMessage || hasRenderableText) yield* orchestrationEngine.dispatch({
|
|
39796
40439
|
type: "thread.message.assistant.complete",
|
|
39797
|
-
commandId: providerCommandId(input.event, input.commandTag),
|
|
40440
|
+
commandId: providerCommandId(input.event, input.commandTag, String(input.messageId)),
|
|
39798
40441
|
threadId: input.threadId,
|
|
39799
40442
|
messageId: input.messageId,
|
|
39800
40443
|
...input.turnId ? { turnId: input.turnId } : {},
|
|
@@ -39828,7 +40471,7 @@ const make$3 = Effect.gen(function* () {
|
|
|
39828
40471
|
const existingPlan = findProposedPlanById(input.threadProposedPlans, input.planId);
|
|
39829
40472
|
yield* orchestrationEngine.dispatch({
|
|
39830
40473
|
type: "thread.proposed-plan.upsert",
|
|
39831
|
-
commandId: providerCommandId(input.event, "proposed-plan-upsert"),
|
|
40474
|
+
commandId: providerCommandId(input.event, "proposed-plan-upsert", input.planId),
|
|
39832
40475
|
threadId: input.threadId,
|
|
39833
40476
|
proposedPlan: {
|
|
39834
40477
|
id: input.planId,
|
|
@@ -39895,13 +40538,13 @@ const make$3 = Effect.gen(function* () {
|
|
|
39895
40538
|
if (!sameId$1(yield* getExpectedProviderTurnIdForThread(threadId), eventTurnId)) return null;
|
|
39896
40539
|
return yield* getSourceProposedPlanReferenceForPendingTurnStart(threadId);
|
|
39897
40540
|
});
|
|
39898
|
-
const markSourceProposedPlanImplemented = Effect.fn("markSourceProposedPlanImplemented")(function* (sourceThreadId, sourcePlanId, implementationThreadId, implementedAt) {
|
|
40541
|
+
const markSourceProposedPlanImplemented = Effect.fn("markSourceProposedPlanImplemented")(function* (event, sourceThreadId, sourcePlanId, implementationThreadId, implementedAt) {
|
|
39899
40542
|
const sourceThread = yield* resolveThreadDetail(sourceThreadId);
|
|
39900
40543
|
const sourcePlan = sourceThread?.proposedPlans.find((entry) => entry.id === sourcePlanId);
|
|
39901
40544
|
if (!sourceThread || !sourcePlan || sourcePlan.implementedAt !== null) return;
|
|
39902
40545
|
yield* orchestrationEngine.dispatch({
|
|
39903
40546
|
type: "thread.proposed-plan.upsert",
|
|
39904
|
-
commandId:
|
|
40547
|
+
commandId: providerCommandId(event, "source-proposed-plan-implemented", `${sourceThreadId}:${sourcePlanId}:${implementationThreadId}`),
|
|
39905
40548
|
threadId: sourceThread.id,
|
|
39906
40549
|
proposedPlan: {
|
|
39907
40550
|
...sourcePlan,
|
|
@@ -39926,6 +40569,12 @@ const make$3 = Effect.gen(function* () {
|
|
|
39926
40569
|
const activeTurnId = thread.session?.activeTurnId ?? null;
|
|
39927
40570
|
const conflictsWithActiveTurn = activeTurnId !== null && eventTurnId !== void 0 && !sameId$1(activeTurnId, eventTurnId);
|
|
39928
40571
|
const missingTurnForActiveTurn = activeTurnId !== null && eventTurnId === void 0;
|
|
40572
|
+
const existingEventTurn = event.type === "turn.started" && eventTurnId !== void 0 ? yield* projectionTurnRepository.getByTurnId({
|
|
40573
|
+
threadId: thread.id,
|
|
40574
|
+
turnId: eventTurnId
|
|
40575
|
+
}) : Option.none();
|
|
40576
|
+
const eventTurnAlreadyTerminal = Option.isSome(existingEventTurn) && isTerminalProjectionTurnState(existingEventTurn.value.state);
|
|
40577
|
+
const eventTurnAlreadyProjectedWithoutActiveSession = activeTurnId === null && Option.isSome(existingEventTurn);
|
|
39929
40578
|
if (!isAssistantTextDeltaEvent(event)) yield* flushLiveAssistantDeltaBuffersSafely({ commandTag: "assistant-delta-flush-before-runtime-event" });
|
|
39930
40579
|
yield* rememberSubagentProviderThreadIds(thread.id, event);
|
|
39931
40580
|
const eventProviderThreadId = rawPayloadThreadId(event);
|
|
@@ -39936,8 +40585,9 @@ const make$3 = Effect.gen(function* () {
|
|
|
39936
40585
|
case "session.exited": return true;
|
|
39937
40586
|
case "session.started":
|
|
39938
40587
|
case "thread.started": return true;
|
|
39939
|
-
case "turn.started": return !conflictsWithActiveTurn;
|
|
40588
|
+
case "turn.started": return !conflictsWithActiveTurn && !eventTurnAlreadyTerminal && !eventTurnAlreadyProjectedWithoutActiveSession;
|
|
39940
40589
|
case "turn.completed":
|
|
40590
|
+
case "turn.aborted":
|
|
39941
40591
|
if (conflictsWithActiveTurn || missingTurnForActiveTurn) return false;
|
|
39942
40592
|
if (activeTurnId !== null && eventTurnId !== void 0) return sameId$1(activeTurnId, eventTurnId);
|
|
39943
40593
|
return true;
|
|
@@ -39945,21 +40595,22 @@ const make$3 = Effect.gen(function* () {
|
|
|
39945
40595
|
}
|
|
39946
40596
|
})();
|
|
39947
40597
|
const acceptedTurnStartedSourcePlan = event.type === "turn.started" && shouldApplyThreadLifecycle ? yield* getSourceProposedPlanReferenceForAcceptedTurnStart(thread.id, eventTurnId) : null;
|
|
39948
|
-
if (event.type === "session.started" || event.type === "session.state.changed" || event.type === "session.exited" || event.type === "thread.started" || event.type === "turn.started" || event.type === "turn.completed") {
|
|
39949
|
-
const nextActiveTurnId = event.type === "turn.started" ? eventTurnId ?? null : event.type === "turn.completed" || event.type === "session.exited" ? null : activeTurnId;
|
|
40598
|
+
if (event.type === "session.started" || event.type === "session.state.changed" || event.type === "session.exited" || event.type === "thread.started" || event.type === "turn.started" || event.type === "turn.completed" || event.type === "turn.aborted") {
|
|
40599
|
+
const nextActiveTurnId = event.type === "turn.started" ? eventTurnId ?? null : event.type === "turn.completed" || event.type === "turn.aborted" || event.type === "session.exited" ? null : activeTurnId;
|
|
39950
40600
|
const status = (() => {
|
|
39951
40601
|
switch (event.type) {
|
|
39952
40602
|
case "session.state.changed": return orchestrationSessionStatusFromRuntimeState(event.payload.state);
|
|
39953
40603
|
case "turn.started": return "running";
|
|
39954
40604
|
case "session.exited": return "stopped";
|
|
39955
40605
|
case "turn.completed": return normalizeRuntimeTurnState(event.payload.state) === "failed" ? "error" : "ready";
|
|
40606
|
+
case "turn.aborted": return "ready";
|
|
39956
40607
|
case "session.started":
|
|
39957
40608
|
case "thread.started": return activeTurnId !== null ? "running" : "ready";
|
|
39958
40609
|
}
|
|
39959
40610
|
})();
|
|
39960
40611
|
const lastError = event.type === "session.state.changed" && event.payload.state === "error" ? event.payload.reason ?? thread.session?.lastError ?? "Provider session error" : event.type === "turn.completed" && normalizeRuntimeTurnState(event.payload.state) === "failed" ? event.payload.errorMessage ?? thread.session?.lastError ?? "Turn failed" : status === "ready" ? null : thread.session?.lastError ?? null;
|
|
39961
40612
|
if (shouldApplyThreadLifecycle) {
|
|
39962
|
-
if (event.type === "turn.started" && acceptedTurnStartedSourcePlan !== null) yield* markSourceProposedPlanImplemented(acceptedTurnStartedSourcePlan.sourceThreadId, acceptedTurnStartedSourcePlan.sourcePlanId, thread.id, now).pipe(Effect.catchCause((cause) => Effect.logWarning("provider runtime ingestion failed to mark source proposed plan", {
|
|
40613
|
+
if (event.type === "turn.started" && acceptedTurnStartedSourcePlan !== null) yield* markSourceProposedPlanImplemented(event, acceptedTurnStartedSourcePlan.sourceThreadId, acceptedTurnStartedSourcePlan.sourcePlanId, thread.id, now).pipe(Effect.catchCause((cause) => Effect.logWarning("provider runtime ingestion failed to mark source proposed plan", {
|
|
39963
40614
|
eventId: event.eventId,
|
|
39964
40615
|
eventType: event.type,
|
|
39965
40616
|
cause: Cause.pretty(cause)
|
|
@@ -39981,11 +40632,30 @@ const make$3 = Effect.gen(function* () {
|
|
|
39981
40632
|
},
|
|
39982
40633
|
createdAt: now
|
|
39983
40634
|
});
|
|
40635
|
+
if (event.type === "turn.aborted" && eventTurnId !== void 0) yield* orchestrationEngine.dispatch({
|
|
40636
|
+
type: "thread.turn.interrupt",
|
|
40637
|
+
commandId: providerCommandId(event, "thread-turn-interrupt", String(eventTurnId)),
|
|
40638
|
+
threadId: thread.id,
|
|
40639
|
+
turnId: eventTurnId,
|
|
40640
|
+
createdAt: now
|
|
40641
|
+
});
|
|
39984
40642
|
}
|
|
39985
40643
|
}
|
|
39986
40644
|
const assistantDelta = isAssistantTextDeltaEvent(event) ? event.payload.delta : void 0;
|
|
40645
|
+
const subagentDelta = event.type === "subagent.message.delta" ? event.payload.delta : void 0;
|
|
39987
40646
|
const proposedPlanDelta = event.type === "turn.proposed.delta" ? event.payload.delta : void 0;
|
|
39988
|
-
if (
|
|
40647
|
+
if (event.type === "subagent.message.delta" && subagentDelta && subagentDelta.length > 0) {
|
|
40648
|
+
const subagentPayload = event.payload;
|
|
40649
|
+
yield* appendSubagentMessageDelta({
|
|
40650
|
+
event,
|
|
40651
|
+
threadId: thread.id,
|
|
40652
|
+
subagentId: String(subagentPayload.subagentId),
|
|
40653
|
+
providerThreadId: subagentPayload.providerThreadId ?? String(subagentPayload.subagentId),
|
|
40654
|
+
providerItemId: subagentPayload.providerMessageId ?? String(subagentPayload.subagentId),
|
|
40655
|
+
delta: subagentDelta,
|
|
40656
|
+
createdAt: now
|
|
40657
|
+
});
|
|
40658
|
+
} else if (assistantDelta && assistantDelta.length > 0 && isSubagentProviderThread && eventProviderThreadId) yield* appendSubagentMessageDelta({
|
|
39989
40659
|
event,
|
|
39990
40660
|
threadId: thread.id,
|
|
39991
40661
|
providerThreadId: eventProviderThreadId,
|
|
@@ -40005,7 +40675,7 @@ const make$3 = Effect.gen(function* () {
|
|
|
40005
40675
|
const spillChunk = yield* appendBufferedAssistantText(assistantMessageId, assistantDelta);
|
|
40006
40676
|
if (spillChunk.length > 0) yield* orchestrationEngine.dispatch({
|
|
40007
40677
|
type: "thread.message.assistant.delta",
|
|
40008
|
-
commandId: providerCommandId(event, "assistant-delta-buffer-spill"),
|
|
40678
|
+
commandId: providerCommandId(event, "assistant-delta-buffer-spill", String(assistantMessageId)),
|
|
40009
40679
|
threadId: thread.id,
|
|
40010
40680
|
messageId: assistantMessageId,
|
|
40011
40681
|
delta: spillChunk,
|
|
@@ -40090,6 +40760,26 @@ const make$3 = Effect.gen(function* () {
|
|
|
40090
40760
|
...subagentMessageCompletion.fallbackText !== void 0 ? { fallbackText: subagentMessageCompletion.fallbackText } : {},
|
|
40091
40761
|
createdAt: now
|
|
40092
40762
|
});
|
|
40763
|
+
if (event.type === "subagent.completed") {
|
|
40764
|
+
const subagentId = String(event.payload.subagent.subagentId);
|
|
40765
|
+
const providerThreadId = event.payload.subagent.providerThreadId ?? subagentId;
|
|
40766
|
+
const providerItemIds = bufferedSubagentProviderItemIds({
|
|
40767
|
+
threadId: thread.id,
|
|
40768
|
+
providerThreadId
|
|
40769
|
+
});
|
|
40770
|
+
yield* Effect.forEach(providerItemIds.length > 0 ? providerItemIds : [subagentId], (providerItemId) => completeSubagentMessage({
|
|
40771
|
+
event,
|
|
40772
|
+
threadId: thread.id,
|
|
40773
|
+
subagentId,
|
|
40774
|
+
providerThreadId,
|
|
40775
|
+
providerItemId,
|
|
40776
|
+
...event.payload.summary !== void 0 ? { fallbackText: event.payload.summary } : {},
|
|
40777
|
+
createdAt: now
|
|
40778
|
+
}), {
|
|
40779
|
+
concurrency: 1,
|
|
40780
|
+
discard: true
|
|
40781
|
+
});
|
|
40782
|
+
}
|
|
40093
40783
|
if (proposedPlanCompletion) {
|
|
40094
40784
|
const detailedThread = yield* getLoadedThreadDetail();
|
|
40095
40785
|
yield* finalizeBufferedProposedPlan({
|
|
@@ -40102,7 +40792,7 @@ const make$3 = Effect.gen(function* () {
|
|
|
40102
40792
|
updatedAt: now
|
|
40103
40793
|
});
|
|
40104
40794
|
}
|
|
40105
|
-
if (event.type === "turn.completed") {
|
|
40795
|
+
if (event.type === "turn.completed" || event.type === "turn.aborted") {
|
|
40106
40796
|
const detailedThread = yield* getLoadedThreadDetail();
|
|
40107
40797
|
const messages = detailedThread?.messages ?? [];
|
|
40108
40798
|
const proposedPlans = detailedThread?.proposedPlans ?? [];
|
|
@@ -40172,7 +40862,7 @@ const make$3 = Effect.gen(function* () {
|
|
|
40172
40862
|
const assistantMessageId = MessageId.make(`assistant:${event.itemId ?? event.turnId ?? event.eventId}`);
|
|
40173
40863
|
yield* orchestrationEngine.dispatch({
|
|
40174
40864
|
type: "thread.turn.diff.complete",
|
|
40175
|
-
commandId: providerCommandId(event, "thread-turn-diff-complete"),
|
|
40865
|
+
commandId: providerCommandId(event, "thread-turn-diff-complete", String(turnId)),
|
|
40176
40866
|
threadId: thread.id,
|
|
40177
40867
|
turnId,
|
|
40178
40868
|
completedAt: now,
|
|
@@ -40188,7 +40878,7 @@ const make$3 = Effect.gen(function* () {
|
|
|
40188
40878
|
const activities = runtimeEventToActivities(event);
|
|
40189
40879
|
yield* Effect.forEach(activities, (activity) => orchestrationEngine.dispatch({
|
|
40190
40880
|
type: "thread.activity.append",
|
|
40191
|
-
commandId: providerCommandId(event, "thread-activity-append"),
|
|
40881
|
+
commandId: providerCommandId(event, "thread-activity-append", String(activity.id)),
|
|
40192
40882
|
threadId: thread.id,
|
|
40193
40883
|
activity,
|
|
40194
40884
|
createdAt: activity.createdAt
|
|
@@ -40252,6 +40942,7 @@ function mapProviderSessionStatusToOrchestrationStatus(status) {
|
|
|
40252
40942
|
}
|
|
40253
40943
|
const turnStartKeyForEvent = (event) => event.commandId !== null ? `command:${event.commandId}` : `event:${event.eventId}`;
|
|
40254
40944
|
const serverCommandId$1 = (tag) => CommandId.make(`server:${tag}:${crypto.randomUUID()}`);
|
|
40945
|
+
const isProviderOriginatedCommandId = (commandId) => commandId !== null && String(commandId).startsWith("provider:");
|
|
40255
40946
|
const HANDLED_TURN_START_KEY_MAX = 1e4;
|
|
40256
40947
|
const HANDLED_TURN_START_KEY_TTL = Duration.minutes(30);
|
|
40257
40948
|
const DEFAULT_RUNTIME_MODE = "full-access";
|
|
@@ -40603,6 +41294,17 @@ const make$2 = Effect.gen(function* () {
|
|
|
40603
41294
|
if (yield* hasHandledTurnStartRecently(turnStartKeyForEvent(event))) return;
|
|
40604
41295
|
const thread = yield* resolveThread(event.payload.threadId);
|
|
40605
41296
|
if (!thread) return;
|
|
41297
|
+
if (thread.session?.status === "running" && thread.session.activeTurnId !== null) {
|
|
41298
|
+
yield* appendProviderFailureActivity({
|
|
41299
|
+
threadId: event.payload.threadId,
|
|
41300
|
+
kind: "provider.turn.start.failed",
|
|
41301
|
+
summary: "Provider turn start rejected",
|
|
41302
|
+
detail: `Thread already has active turn '${thread.session.activeTurnId}'. Queuing overlapping turns is not supported; wait for the active turn to finish before starting another.`,
|
|
41303
|
+
turnId: null,
|
|
41304
|
+
createdAt: event.payload.createdAt
|
|
41305
|
+
});
|
|
41306
|
+
return;
|
|
41307
|
+
}
|
|
40606
41308
|
const message = thread.messages.find((entry) => entry.id === event.payload.messageId);
|
|
40607
41309
|
if (!message || message.role !== "user") {
|
|
40608
41310
|
yield* appendProviderFailureActivity({
|
|
@@ -40673,6 +41375,7 @@ const make$2 = Effect.gen(function* () {
|
|
|
40673
41375
|
yield* providerService.sendTurn(sendTurnRequest.value).pipe(Effect.catchCause(recoverTurnStartFailure), Effect.forkScoped);
|
|
40674
41376
|
});
|
|
40675
41377
|
const processTurnInterruptRequested = Effect.fn("processTurnInterruptRequested")(function* (event) {
|
|
41378
|
+
if (isProviderOriginatedCommandId(event.commandId)) return;
|
|
40676
41379
|
const thread = yield* resolveThread(event.payload.threadId);
|
|
40677
41380
|
if (!thread) return;
|
|
40678
41381
|
if (!(thread.session && thread.session.status !== "stopped")) return yield* appendProviderFailureActivity({
|
|
@@ -46969,6 +47672,10 @@ const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand")(funct
|
|
|
46969
47672
|
command,
|
|
46970
47673
|
threadId: command.threadId
|
|
46971
47674
|
});
|
|
47675
|
+
if (targetThread.session?.status === "running" && targetThread.session.activeTurnId !== null) return yield* new OrchestrationCommandInvariantError({
|
|
47676
|
+
commandType: command.type,
|
|
47677
|
+
detail: `Thread '${command.threadId}' already has active turn '${targetThread.session.activeTurnId}' and cannot start another turn until it finishes.`
|
|
47678
|
+
});
|
|
46972
47679
|
const sourceProposedPlan = command.sourceProposedPlan;
|
|
46973
47680
|
const sourceThread = sourceProposedPlan ? yield* requireThread({
|
|
46974
47681
|
readModel,
|
|
@@ -49816,8 +50523,20 @@ const WorkspaceRootLookupInput = Schema.Struct({ workspaceRoot: Schema.String })
|
|
|
49816
50523
|
const ProjectIdLookupInput = Schema.Struct({ projectId: ProjectId });
|
|
49817
50524
|
const ThreadIdLookupInput = Schema.Struct({ threadId: ThreadId });
|
|
49818
50525
|
const WorktreeIdLookupInput = Schema.Struct({ worktreeId: WorktreeId });
|
|
50526
|
+
const ThreadMessageSearchQueryInput = Schema.Struct({
|
|
50527
|
+
likePattern: Schema.String,
|
|
50528
|
+
projectId: Schema.NullOr(ProjectId),
|
|
50529
|
+
limit: NonNegativeInt
|
|
50530
|
+
});
|
|
49819
50531
|
const ProjectionProjectLookupRowSchema = ProjectionProjectDbRowSchema;
|
|
49820
50532
|
const ProjectionThreadIdLookupRowSchema = Schema.Struct({ threadId: ThreadId });
|
|
50533
|
+
const ProjectionThreadMessageSearchRowSchema = Schema.Struct({
|
|
50534
|
+
threadId: ThreadId,
|
|
50535
|
+
messageId: MessageId,
|
|
50536
|
+
text: Schema.String,
|
|
50537
|
+
createdAt: IsoDateTime,
|
|
50538
|
+
updatedAt: IsoDateTime
|
|
50539
|
+
});
|
|
49821
50540
|
const ProjectionThreadCheckpointContextThreadRowSchema = Schema.Struct({
|
|
49822
50541
|
threadId: ThreadId,
|
|
49823
50542
|
projectId: ProjectId,
|
|
@@ -49849,6 +50568,20 @@ function computeSnapshotSequence(stateRows) {
|
|
|
49849
50568
|
}
|
|
49850
50569
|
return Number.isFinite(minSequence) ? minSequence : 0;
|
|
49851
50570
|
}
|
|
50571
|
+
function escapeSqlLikePattern(value) {
|
|
50572
|
+
return value.replace(/[\\%_]/g, (match) => `\\${match}`);
|
|
50573
|
+
}
|
|
50574
|
+
function buildMessageSearchSnippet(input) {
|
|
50575
|
+
const maxLength = input.maxLength ?? 180;
|
|
50576
|
+
const normalizedQuery = input.query.trim().toLowerCase();
|
|
50577
|
+
const normalizedText = input.text.toLowerCase();
|
|
50578
|
+
const matchIndex = normalizedQuery.length > 0 ? normalizedText.indexOf(normalizedQuery) : -1;
|
|
50579
|
+
const contextLength = Math.floor(maxLength / 2);
|
|
50580
|
+
const start = matchIndex <= contextLength ? 0 : Math.max(0, matchIndex - Math.floor(contextLength / 2));
|
|
50581
|
+
const end = Math.min(input.text.length, start + maxLength);
|
|
50582
|
+
const snippet = input.text.slice(start, end).replace(/\s+/g, " ").trim();
|
|
50583
|
+
return `${start > 0 ? "..." : ""}${snippet}${end < input.text.length ? "..." : ""}`;
|
|
50584
|
+
}
|
|
49852
50585
|
function mapLatestTurn(row) {
|
|
49853
50586
|
return {
|
|
49854
50587
|
turnId: row.turnId,
|
|
@@ -50318,6 +51051,30 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
50318
51051
|
FROM projection_thread_messages
|
|
50319
51052
|
WHERE thread_id = ${threadId}
|
|
50320
51053
|
ORDER BY created_at ASC, message_id ASC
|
|
51054
|
+
`
|
|
51055
|
+
});
|
|
51056
|
+
const searchThreadMessageRows = SqlSchema.findAll({
|
|
51057
|
+
Request: ThreadMessageSearchQueryInput,
|
|
51058
|
+
Result: ProjectionThreadMessageSearchRowSchema,
|
|
51059
|
+
execute: ({ likePattern, projectId, limit }) => sql`
|
|
51060
|
+
SELECT
|
|
51061
|
+
messages.thread_id AS "threadId",
|
|
51062
|
+
messages.message_id AS "messageId",
|
|
51063
|
+
messages.text,
|
|
51064
|
+
messages.created_at AS "createdAt",
|
|
51065
|
+
messages.updated_at AS "updatedAt"
|
|
51066
|
+
FROM projection_thread_messages AS messages
|
|
51067
|
+
INNER JOIN projection_threads AS threads
|
|
51068
|
+
ON threads.thread_id = messages.thread_id
|
|
51069
|
+
INNER JOIN projection_projects AS projects
|
|
51070
|
+
ON projects.project_id = threads.project_id
|
|
51071
|
+
WHERE threads.deleted_at IS NULL
|
|
51072
|
+
AND projects.deleted_at IS NULL
|
|
51073
|
+
AND messages.role IN ('user', 'assistant')
|
|
51074
|
+
AND (${projectId} IS NULL OR threads.project_id = ${projectId})
|
|
51075
|
+
AND lower(messages.text) LIKE ${likePattern} ESCAPE '\\'
|
|
51076
|
+
ORDER BY messages.created_at DESC, messages.message_id DESC
|
|
51077
|
+
LIMIT ${limit}
|
|
50321
51078
|
`
|
|
50322
51079
|
});
|
|
50323
51080
|
const listThreadProposedPlanRowsByThread = SqlSchema.findAll({
|
|
@@ -50906,6 +51663,24 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
50906
51663
|
};
|
|
50907
51664
|
return Option.some(yield* decodeThread(thread).pipe(Effect.mapError(toPersistenceDecodeError("ProjectionSnapshotQuery.getThreadDetailById:decodeThread"))));
|
|
50908
51665
|
});
|
|
51666
|
+
const searchThreadMessages = (input) => {
|
|
51667
|
+
const query = input.query.trim();
|
|
51668
|
+
if (query.length === 0) return Effect.succeed([]);
|
|
51669
|
+
const limit = Math.min(Math.max(1, input.limit), 50);
|
|
51670
|
+
return searchThreadMessageRows({
|
|
51671
|
+
likePattern: `%${escapeSqlLikePattern(query.toLowerCase())}%`,
|
|
51672
|
+
projectId: input.projectId ?? null,
|
|
51673
|
+
limit
|
|
51674
|
+
}).pipe(Effect.mapError(toPersistenceSqlOrDecodeError("ProjectionSnapshotQuery.searchThreadMessages:query", "ProjectionSnapshotQuery.searchThreadMessages:decodeRows")), Effect.map((rows) => rows.map((row) => ({
|
|
51675
|
+
threadId: row.threadId,
|
|
51676
|
+
messageId: row.messageId,
|
|
51677
|
+
snippet: buildMessageSearchSnippet({
|
|
51678
|
+
text: row.text,
|
|
51679
|
+
query
|
|
51680
|
+
}),
|
|
51681
|
+
timestamp: row.createdAt
|
|
51682
|
+
}))));
|
|
51683
|
+
};
|
|
50909
51684
|
return {
|
|
50910
51685
|
getCommandReadModel,
|
|
50911
51686
|
getSnapshot,
|
|
@@ -50918,7 +51693,8 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
50918
51693
|
getThreadCheckpointContext,
|
|
50919
51694
|
getThreadShellById,
|
|
50920
51695
|
getWorktreeShellById,
|
|
50921
|
-
getThreadDetailById
|
|
51696
|
+
getThreadDetailById,
|
|
51697
|
+
searchThreadMessages
|
|
50922
51698
|
};
|
|
50923
51699
|
});
|
|
50924
51700
|
const OrchestrationProjectionSnapshotQueryLive = Layer.effect(ProjectionSnapshotQuery, makeProjectionSnapshotQuery);
|
|
@@ -50926,7 +51702,7 @@ const OrchestrationProjectionSnapshotQueryLive = Layer.effect(ProjectionSnapshot
|
|
|
50926
51702
|
//#region src/orchestration/runtimeLayer.ts
|
|
50927
51703
|
const OrchestrationEventInfrastructureLayerLive = Layer.mergeAll(OrchestrationEventStoreLive, OrchestrationCommandReceiptRepositoryLive);
|
|
50928
51704
|
const OrchestrationProjectionPipelineLayerLive = OrchestrationProjectionPipelineLive.pipe(Layer.provide(OrchestrationEventStoreLive));
|
|
50929
|
-
const OrchestrationInfrastructureLayerLive = Layer.mergeAll(OrchestrationProjectionSnapshotQueryLive, OrchestrationEventInfrastructureLayerLive, OrchestrationProjectionPipelineLayerLive);
|
|
51705
|
+
const OrchestrationInfrastructureLayerLive = Layer.mergeAll(OrchestrationProjectionSnapshotQueryLive, StatisticsQueryLive, OrchestrationEventInfrastructureLayerLive, OrchestrationProjectionPipelineLayerLive);
|
|
50930
51706
|
const OrchestrationLayerLive = Layer.mergeAll(OrchestrationInfrastructureLayerLive, OrchestrationEngineLive.pipe(Layer.provide(OrchestrationInfrastructureLayerLive)));
|
|
50931
51707
|
//#endregion
|
|
50932
51708
|
//#region src/serverRuntimeState.ts
|
|
@@ -51702,4 +52478,4 @@ const CliRuntimeLayer = Layer$1.mergeAll(NodeServices.layer, NetService.layer);
|
|
|
51702
52478
|
const program = Command.run(cli, { version }).pipe(Effect$1.scoped, Effect$1.provide(CliRuntimeLayer));
|
|
51703
52479
|
NodeRuntime.runMain(program);
|
|
51704
52480
|
//#endregion
|
|
51705
|
-
export { ServerRequest__CommandExecutionRequestApprovalParams as $, makeProviderMaintenanceCapabilities as $t, nonEmptyTrimmed as A, V2ThreadStatusChangedNotification as At, codexContinuationIdentity as B, GitLabCli as Bt, DEFAULT_TIMEOUT_MS as C, V2ThreadNameUpdatedNotification as Ct, collectStreamAsString as D, V2ThreadRealtimeOutputAudioDeltaNotification as Dt, buildServerProvider as E, V2ThreadRealtimeItemAddedNotification as Et, ProviderAdapterRequestError as F, V2TurnStartParams as Ft, layerChildProcess as G, withoutStatusCheckRollupJsonField as Gt, resolveCodexHomeLayout as H, GitHubCli as Ht, ProviderAdapterSessionClosedError as I, V2TurnStartParams__CollaborationMode as It, CodexAppServerRequestError as J, BitbucketApi as Jt, CodexAppServerProcessExitedError as K, decodeGitHubPullRequestListJson as Kt, ProviderAdapterSessionNotFoundError as L, V2TurnStartResponse as Lt, providerModelsFromSettings as M, V2TurnCompletedNotification as Mt, spawnAndCollect as N, V2TurnDiffUpdatedNotification as Nt, detailFromResult as O, V2ThreadRealtimeStartedNotification as Ot, ProviderAdapterProcessError as P, V2TurnPlanUpdatedNotification as Pt, ServerRequest__ApplyPatchApprovalParams as Q, makePackageManagedProviderMaintenanceResolver as Qt, ProviderAdapterValidationError as R, V2WindowsSandboxSetupCompletedNotification as Rt, makePendingCodexProvider as S, V2ServerRequestResolvedNotification as St, buildSelectOptionDescriptor as T, V2ThreadRealtimeErrorNotification as Tt, expandHomePath$3 as U, formatGitHubJsonFields as Ut, materializeCodexShadowHome as V, GITHUB_PULL_REQUEST_LIST_JSON_FIELDS as Vt, CodexAppServerClient as W, isStatusCheckRollupAccessError as Wt, CodexAppServerTransportError as X, enrichProviderSnapshotWithVersionAdvisory as Xt, CodexAppServerSpawnError as Y, AzureDevOpsCli as Yt, SERVER_NOTIFICATION_METHODS as Z, makeManualOnlyProviderMaintenanceCapabilities as Zt, buildTokenReductionInstructions as _, V2McpToolCallProgressNotification as _t, OpenCodeRuntime as a,
|
|
52481
|
+
export { ServerRequest__CommandExecutionRequestApprovalParams as $, makeProviderMaintenanceCapabilities as $t, nonEmptyTrimmed as A, V2ThreadStatusChangedNotification as At, codexContinuationIdentity as B, GitLabCli as Bt, DEFAULT_TIMEOUT_MS as C, V2ThreadNameUpdatedNotification as Ct, collectStreamAsString as D, V2ThreadRealtimeOutputAudioDeltaNotification as Dt, buildServerProvider as E, V2ThreadRealtimeItemAddedNotification as Et, ProviderAdapterRequestError as F, V2TurnStartParams as Ft, layerChildProcess as G, withoutStatusCheckRollupJsonField as Gt, resolveCodexHomeLayout as H, GitHubCli as Ht, ProviderAdapterSessionClosedError as I, V2TurnStartParams__CollaborationMode as It, CodexAppServerRequestError as J, BitbucketApi as Jt, CodexAppServerProcessExitedError as K, decodeGitHubPullRequestListJson as Kt, ProviderAdapterSessionNotFoundError as L, V2TurnStartResponse as Lt, providerModelsFromSettings as M, V2TurnCompletedNotification as Mt, spawnAndCollect as N, V2TurnDiffUpdatedNotification as Nt, detailFromResult as O, V2ThreadRealtimeStartedNotification as Ot, ProviderAdapterProcessError as P, V2TurnPlanUpdatedNotification as Pt, ServerRequest__ApplyPatchApprovalParams as Q, makePackageManagedProviderMaintenanceResolver as Qt, ProviderAdapterValidationError as R, V2WindowsSandboxSetupCompletedNotification as Rt, makePendingCodexProvider as S, V2ServerRequestResolvedNotification as St, buildSelectOptionDescriptor as T, V2ThreadRealtimeErrorNotification as Tt, expandHomePath$3 as U, formatGitHubJsonFields as Ut, materializeCodexShadowHome as V, GITHUB_PULL_REQUEST_LIST_JSON_FIELDS as Vt, CodexAppServerClient as W, isStatusCheckRollupAccessError as Wt, CodexAppServerTransportError as X, enrichProviderSnapshotWithVersionAdvisory as Xt, CodexAppServerSpawnError as Y, AzureDevOpsCli as Yt, SERVER_NOTIFICATION_METHODS as Z, makeManualOnlyProviderMaintenanceCapabilities as Zt, buildTokenReductionInstructions as _, V2McpToolCallProgressNotification as _t, OpenCodeRuntime as a, resolveAttachmentPath as an, ToolRequestUserInputResponse as at, buildCodexInitializeParams as b, V2ReasoningSummaryTextDeltaNotification as bt, openCodeQuestionId as c, createModelCapabilities as cn, V2AgentMessageDeltaNotification as ct, runOpenCodeSdk as d, getProviderOptionBooleanSelectionValue as dn, V2DeprecationNoticeNotification as dt, makeStaticProviderMaintenanceResolver as en, ServerRequest__DynamicToolCallParams as et, toOpenCodeFileParts as f, getProviderOptionCurrentValue as fn, V2ErrorNotification as ft, makeEventNdjsonLogger as g, resolvePromptInjectedEffort as gn, V2McpServerOauthLoginCompletedNotification as gt, ProviderEventLoggers as h, normalizeModelSlug as hn, V2ItemStartedNotification as ht, PtySpawnError as i, ServerSettingsService as in, ToolRequestUserInputParams as it, parseGenericCliVersion as j, V2ThreadTokenUsageUpdatedNotification as jt, isCommandMissingCause as k, V2ThreadStartedNotification as kt, openCodeRuntimeErrorDetail as l, getModelSelectionBooleanOptionValue as ln, V2CommandExecutionOutputDeltaNotification as lt, toOpenCodeQuestionAnswers as m, getProviderOptionStringSelectionValue as mn, V2ItemCompletedNotification as mt, ignoreProviderBackgroundCause as n, resolveProviderMaintenanceCapabilitiesEffect as nn, ServerRequest__FileChangeRequestApprovalParams as nt, OpenCodeRuntimeError as o, resolveCommandPath as on, V2AccountRateLimitsUpdatedNotification as ot, toOpenCodePermissionReply as p, getProviderOptionDescriptors as pn, V2FileChangeOutputDeltaNotification as pt, CodexAppServerProtocolParseError as q, ForgejoApi as qt, PtyAdapter as r, compareCliVersions as rn, ServerRequest__ToolRequestUserInputParams as rt, buildOpenCodePermissionRules as s, applyClaudePromptEffortPrefix as sn, V2AccountUpdatedNotification as st, makeServerQueueMetrics as t, normalizeCommandPath as tn, ServerRequest__ExecCommandApprovalParams as tt, parseOpenCodeModelSlug as u, getModelSelectionStringOptionValue as un, V2ConfigWarningNotification as ut, checkRtkAvailability as v, V2ModelReroutedNotification as vt, buildBooleanOptionDescriptor as w, V2ThreadRealtimeClosedNotification as wt, checkCodexProviderStatus as x, V2ReasoningTextDeltaNotification as xt, mergeProviderInstanceEnvironment as y, V2PlanDeltaNotification as yt, ProviderDriverError as z, V2WindowsWorldWritableWarningNotification as zt };
|