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.cjs
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
4
4
|
const require_chunk = require("./chunk-jM1PLTSZ.cjs");
|
|
5
|
-
const require_collectUint8StreamText = require("./collectUint8StreamText-
|
|
6
|
-
const require_SourceControlProviderDiscoveryCatalog = require("./SourceControlProviderDiscoveryCatalog-_rg0mc1o.cjs");
|
|
5
|
+
const require_collectUint8StreamText = require("./collectUint8StreamText-B-GW3u_2.cjs");
|
|
7
6
|
const require_Metrics = require("./Metrics-CIW1QH7M.cjs");
|
|
7
|
+
const require_SourceControlProviderDiscoveryCatalog = require("./SourceControlProviderDiscoveryCatalog-CTb100Uk.cjs");
|
|
8
8
|
const require_sourceControl = require("./sourceControl-x2t62T8h.cjs");
|
|
9
9
|
let _effect_platform_node_NodeRuntime = require("@effect/platform-node/NodeRuntime");
|
|
10
10
|
_effect_platform_node_NodeRuntime = require_chunk.__toESM(_effect_platform_node_NodeRuntime, 1);
|
|
@@ -44,13 +44,13 @@ let effect_unstable_rpc = require("effect/unstable/rpc");
|
|
|
44
44
|
let effect_unstable_process = require("effect/unstable/process");
|
|
45
45
|
let effect_Semaphore = require("effect/Semaphore");
|
|
46
46
|
effect_Semaphore = require_chunk.__toESM(effect_Semaphore, 1);
|
|
47
|
+
let effect_Random = require("effect/Random");
|
|
48
|
+
effect_Random = require_chunk.__toESM(effect_Random, 1);
|
|
47
49
|
require("effect/PlatformError");
|
|
48
50
|
let effect_unstable_sql_SqlClient = require("effect/unstable/sql/SqlClient");
|
|
49
51
|
effect_unstable_sql_SqlClient = require_chunk.__toESM(effect_unstable_sql_SqlClient, 1);
|
|
50
52
|
let effect_unstable_sql_Migrator = require("effect/unstable/sql/Migrator");
|
|
51
53
|
effect_unstable_sql_Migrator = require_chunk.__toESM(effect_unstable_sql_Migrator, 1);
|
|
52
|
-
let effect_Random = require("effect/Random");
|
|
53
|
-
effect_Random = require_chunk.__toESM(effect_Random, 1);
|
|
54
54
|
let node_fs_promises = require("node:fs/promises");
|
|
55
55
|
node_fs_promises = require_chunk.__toESM(node_fs_promises, 1);
|
|
56
56
|
let effect_Context = require("effect/Context");
|
|
@@ -72,9 +72,9 @@ let effect_SchemaIssue = require("effect/SchemaIssue");
|
|
|
72
72
|
effect_SchemaIssue = require_chunk.__toESM(effect_SchemaIssue, 1);
|
|
73
73
|
let effect_Sink = require("effect/Sink");
|
|
74
74
|
effect_Sink = require_chunk.__toESM(effect_Sink, 1);
|
|
75
|
-
let effect_Number = require("effect/Number");
|
|
76
75
|
let effect_unstable_sql_SqlSchema = require("effect/unstable/sql/SqlSchema");
|
|
77
76
|
effect_unstable_sql_SqlSchema = require_chunk.__toESM(effect_unstable_sql_SqlSchema, 1);
|
|
77
|
+
let effect_Number = require("effect/Number");
|
|
78
78
|
let node_url = require("node:url");
|
|
79
79
|
let _pierre_diffs = require("@pierre/diffs");
|
|
80
80
|
let node_perf_hooks = require("node:perf_hooks");
|
|
@@ -336,7 +336,7 @@ function applyClaudePromptEffortPrefix(text, effort) {
|
|
|
336
336
|
}
|
|
337
337
|
//#endregion
|
|
338
338
|
//#region ../../packages/shared/src/serverSettings.ts
|
|
339
|
-
const ServerSettingsJson$1 =
|
|
339
|
+
const ServerSettingsJson$1 = require_collectUint8StreamText.fromLenientJson(require_collectUint8StreamText.ServerSettings);
|
|
340
340
|
function normalizePersistedServerSettingString(value) {
|
|
341
341
|
const trimmed = value?.trim();
|
|
342
342
|
return trimmed && trimmed.length > 0 ? trimmed : void 0;
|
|
@@ -424,7 +424,7 @@ const readBootstrapEnvelope = effect.Effect.fn("readBootstrapEnvelope")(function
|
|
|
424
424
|
})));
|
|
425
425
|
};
|
|
426
426
|
const handleLine = (line) => {
|
|
427
|
-
const parsed =
|
|
427
|
+
const parsed = require_collectUint8StreamText.decodeJsonResult(schema)(line);
|
|
428
428
|
if (effect.Result.isSuccess(parsed)) resume(effect.Effect.succeedSome(parsed.success));
|
|
429
429
|
else resume(effect.Effect.fail(new BootstrapError({
|
|
430
430
|
message: "Failed to decode bootstrap envelope.",
|
|
@@ -1657,6 +1657,388 @@ const makeProviderMaintenanceCommandCoordinator = effect.Effect.fn("makeProvider
|
|
|
1657
1657
|
return { withCommandLock };
|
|
1658
1658
|
});
|
|
1659
1659
|
//#endregion
|
|
1660
|
+
//#region src/atomicWrite.ts
|
|
1661
|
+
const writeFileStringAtomically = (input) => effect.Effect.scoped(effect.Effect.gen(function* () {
|
|
1662
|
+
const fs = yield* effect.FileSystem.FileSystem;
|
|
1663
|
+
const path = yield* effect.Path.Path;
|
|
1664
|
+
const tempFileId = yield* effect_Random.nextUUIDv4;
|
|
1665
|
+
const targetDirectory = path.dirname(input.filePath);
|
|
1666
|
+
yield* fs.makeDirectory(targetDirectory, { recursive: true });
|
|
1667
|
+
const tempDirectory = yield* fs.makeTempDirectoryScoped({
|
|
1668
|
+
directory: targetDirectory,
|
|
1669
|
+
prefix: `${path.basename(input.filePath)}.`
|
|
1670
|
+
});
|
|
1671
|
+
const tempPath = path.join(tempDirectory, `${tempFileId}.tmp`);
|
|
1672
|
+
yield* fs.writeFileString(tempPath, input.contents);
|
|
1673
|
+
yield* fs.rename(tempPath, input.filePath);
|
|
1674
|
+
}));
|
|
1675
|
+
//#endregion
|
|
1676
|
+
//#region src/auth/Services/ServerSecretStore.ts
|
|
1677
|
+
var SecretStoreError = class extends effect.Data.TaggedError("SecretStoreError") {};
|
|
1678
|
+
var ServerSecretStore = class extends effect.Context.Service()("ryco/auth/Services/ServerSecretStore") {};
|
|
1679
|
+
//#endregion
|
|
1680
|
+
//#region src/auth/Layers/ServerSecretStore.ts
|
|
1681
|
+
const makeServerSecretStore = effect.Effect.gen(function* () {
|
|
1682
|
+
const fileSystem = yield* effect.FileSystem.FileSystem;
|
|
1683
|
+
const path = yield* effect.Path.Path;
|
|
1684
|
+
const serverConfig = yield* require_Metrics.ServerConfig;
|
|
1685
|
+
yield* fileSystem.makeDirectory(serverConfig.secretsDir, { recursive: true });
|
|
1686
|
+
yield* fileSystem.chmod(serverConfig.secretsDir, 448).pipe(effect.Effect.mapError((cause) => new SecretStoreError({
|
|
1687
|
+
message: `Failed to secure secrets directory ${serverConfig.secretsDir}.`,
|
|
1688
|
+
cause
|
|
1689
|
+
})));
|
|
1690
|
+
const resolveSecretPath = (name) => path.join(serverConfig.secretsDir, `${name}.bin`);
|
|
1691
|
+
const ensureSecretDirectory = (secretPath) => {
|
|
1692
|
+
const directory = path.dirname(secretPath);
|
|
1693
|
+
return fileSystem.makeDirectory(directory, { recursive: true }).pipe(effect.Effect.flatMap(() => fileSystem.chmod(directory, 448)));
|
|
1694
|
+
};
|
|
1695
|
+
const isPlatformError = (u) => effect.Predicate.isTagged(u, "PlatformError");
|
|
1696
|
+
const get = (name) => fileSystem.readFile(resolveSecretPath(name)).pipe(effect.Effect.map((bytes) => Uint8Array.from(bytes)), effect.Effect.catch((cause) => cause.reason._tag === "NotFound" ? effect.Effect.succeed(null) : effect.Effect.fail(new SecretStoreError({
|
|
1697
|
+
message: `Failed to read secret ${name}.`,
|
|
1698
|
+
cause
|
|
1699
|
+
}))));
|
|
1700
|
+
const set = (name, value) => {
|
|
1701
|
+
const secretPath = resolveSecretPath(name);
|
|
1702
|
+
const tempPath = `${secretPath}.${node_crypto.randomUUID()}.tmp`;
|
|
1703
|
+
return effect.Effect.gen(function* () {
|
|
1704
|
+
yield* ensureSecretDirectory(secretPath);
|
|
1705
|
+
yield* fileSystem.writeFile(tempPath, value);
|
|
1706
|
+
yield* fileSystem.chmod(tempPath, 384);
|
|
1707
|
+
yield* fileSystem.rename(tempPath, secretPath);
|
|
1708
|
+
yield* fileSystem.chmod(secretPath, 384);
|
|
1709
|
+
}).pipe(effect.Effect.catch((cause) => fileSystem.remove(tempPath).pipe(effect.Effect.ignore, effect.Effect.flatMap(() => effect.Effect.fail(new SecretStoreError({
|
|
1710
|
+
message: `Failed to persist secret ${name}.`,
|
|
1711
|
+
cause
|
|
1712
|
+
}))))));
|
|
1713
|
+
};
|
|
1714
|
+
const create = (name, value) => {
|
|
1715
|
+
const secretPath = resolveSecretPath(name);
|
|
1716
|
+
return effect.Effect.scoped(effect.Effect.gen(function* () {
|
|
1717
|
+
yield* ensureSecretDirectory(secretPath);
|
|
1718
|
+
const file = yield* fileSystem.open(secretPath, {
|
|
1719
|
+
flag: "wx",
|
|
1720
|
+
mode: 384
|
|
1721
|
+
});
|
|
1722
|
+
yield* file.writeAll(value);
|
|
1723
|
+
yield* file.sync;
|
|
1724
|
+
yield* fileSystem.chmod(secretPath, 384);
|
|
1725
|
+
})).pipe(effect.Effect.mapError((cause) => new SecretStoreError({
|
|
1726
|
+
message: `Failed to persist secret ${name}.`,
|
|
1727
|
+
cause
|
|
1728
|
+
})));
|
|
1729
|
+
};
|
|
1730
|
+
const getOrCreateRandom = (name, bytes) => get(name).pipe(effect.Effect.flatMap((existing) => {
|
|
1731
|
+
if (existing) return effect.Effect.succeed(existing);
|
|
1732
|
+
const generated = node_crypto.randomBytes(bytes);
|
|
1733
|
+
return create(name, generated).pipe(effect.Effect.as(Uint8Array.from(generated)), effect.Effect.catchTag("SecretStoreError", (error) => isPlatformError(error.cause) && error.cause.reason._tag === "AlreadyExists" ? get(name).pipe(effect.Effect.flatMap((created) => created !== null ? effect.Effect.succeed(created) : effect.Effect.fail(new SecretStoreError({ message: `Failed to read secret ${name} after concurrent creation.` })))) : effect.Effect.fail(error)));
|
|
1734
|
+
}));
|
|
1735
|
+
const remove = (name) => fileSystem.remove(resolveSecretPath(name)).pipe(effect.Effect.catch((cause) => cause.reason._tag === "NotFound" ? effect.Effect.void : effect.Effect.fail(new SecretStoreError({
|
|
1736
|
+
message: `Failed to remove secret ${name}.`,
|
|
1737
|
+
cause
|
|
1738
|
+
}))));
|
|
1739
|
+
return {
|
|
1740
|
+
get,
|
|
1741
|
+
set,
|
|
1742
|
+
getOrCreateRandom,
|
|
1743
|
+
remove
|
|
1744
|
+
};
|
|
1745
|
+
});
|
|
1746
|
+
const ServerSecretStoreLive = effect.Layer.effect(ServerSecretStore, makeServerSecretStore);
|
|
1747
|
+
//#endregion
|
|
1748
|
+
//#region src/serverSettings.ts
|
|
1749
|
+
/**
|
|
1750
|
+
* ServerSettings - Server-authoritative settings service.
|
|
1751
|
+
*
|
|
1752
|
+
* Owns persistence, validation, and change notification of settings that affect
|
|
1753
|
+
* server-side behavior (binary paths, streaming mode, env mode, custom models,
|
|
1754
|
+
* text generation model selection).
|
|
1755
|
+
*
|
|
1756
|
+
* Follows the same pattern as `keybindings.ts`: JSON file + Cache + PubSub +
|
|
1757
|
+
* Semaphore + FileSystem.watch for concurrency and external edit detection.
|
|
1758
|
+
*
|
|
1759
|
+
* @module ServerSettings
|
|
1760
|
+
*/
|
|
1761
|
+
const textEncoder$2 = new TextEncoder();
|
|
1762
|
+
const textDecoder$2 = new TextDecoder();
|
|
1763
|
+
function providerEnvironmentSecretName(input) {
|
|
1764
|
+
return `provider-env-${Buffer.from(input.instanceId, "utf8").toString("base64url")}-${Buffer.from(input.name, "utf8").toString("base64url")}`;
|
|
1765
|
+
}
|
|
1766
|
+
function redactProviderEnvironmentVariable(variable) {
|
|
1767
|
+
if (!variable.sensitive) {
|
|
1768
|
+
const { valueRedacted: _omit, ...rest } = variable;
|
|
1769
|
+
return rest;
|
|
1770
|
+
}
|
|
1771
|
+
return {
|
|
1772
|
+
...variable,
|
|
1773
|
+
value: "",
|
|
1774
|
+
...variable.value.length > 0 || variable.valueRedacted ? { valueRedacted: true } : {}
|
|
1775
|
+
};
|
|
1776
|
+
}
|
|
1777
|
+
function redactServerSettingsForClient(settings) {
|
|
1778
|
+
const providerInstances = Object.fromEntries(Object.entries(settings.providerInstances).map(([instanceId, instance]) => [instanceId, instance.environment ? {
|
|
1779
|
+
...instance,
|
|
1780
|
+
environment: instance.environment.map(redactProviderEnvironmentVariable)
|
|
1781
|
+
} : instance]));
|
|
1782
|
+
return {
|
|
1783
|
+
...settings,
|
|
1784
|
+
providerInstances
|
|
1785
|
+
};
|
|
1786
|
+
}
|
|
1787
|
+
var ServerSettingsService = class ServerSettingsService extends effect.Context.Service()("ryco/serverSettings/ServerSettingsService") {
|
|
1788
|
+
static layerTest = (overrides = {}) => effect.Layer.effect(ServerSettingsService, effect.Effect.gen(function* () {
|
|
1789
|
+
const currentSettingsRef = yield* effect.Ref.make(deepMerge(require_collectUint8StreamText.DEFAULT_SERVER_SETTINGS, overrides));
|
|
1790
|
+
return {
|
|
1791
|
+
start: effect.Effect.void,
|
|
1792
|
+
ready: effect.Effect.void,
|
|
1793
|
+
getSettings: effect.Ref.get(currentSettingsRef),
|
|
1794
|
+
updateSettings: (patch) => effect.Ref.get(currentSettingsRef).pipe(effect.Effect.flatMap((currentSettings) => effect.Schema.decodeEffect(require_collectUint8StreamText.ServerSettings)(applyServerSettingsPatch(currentSettings, patch)).pipe(effect.Effect.mapError((cause) => new require_collectUint8StreamText.ServerSettingsError({
|
|
1795
|
+
settingsPath: "<memory>",
|
|
1796
|
+
detail: `failed to normalize server settings: ${effect.SchemaIssue.makeFormatterDefault()(cause.issue)}`,
|
|
1797
|
+
cause
|
|
1798
|
+
})))), effect.Effect.tap((nextSettings) => effect.Ref.set(currentSettingsRef, nextSettings))),
|
|
1799
|
+
streamChanges: effect.Stream.empty
|
|
1800
|
+
};
|
|
1801
|
+
}));
|
|
1802
|
+
};
|
|
1803
|
+
const ServerSettingsJson = require_collectUint8StreamText.fromLenientJson(require_collectUint8StreamText.ServerSettings);
|
|
1804
|
+
const getLegacyProviderSettings = (settings, provider) => settings.providers[provider];
|
|
1805
|
+
/**
|
|
1806
|
+
* Ensure the `textGenerationModelSelection` points to an enabled provider.
|
|
1807
|
+
* If the selected provider is disabled, fall back to the first enabled
|
|
1808
|
+
* provider with its default model. This is applied at read-time so the
|
|
1809
|
+
* persisted preference is preserved for when a provider is re-enabled.
|
|
1810
|
+
*/
|
|
1811
|
+
function resolveTextGenerationProvider(settings) {
|
|
1812
|
+
const selection = settings.textGenerationModelSelection;
|
|
1813
|
+
const instanceConfig = settings.providerInstances[selection.instanceId];
|
|
1814
|
+
if (instanceConfig !== void 0) return instanceConfig.enabled ?? true ? settings : fallbackTextGenerationProvider(settings);
|
|
1815
|
+
if (require_collectUint8StreamText.isProviderDriverKind(selection.instanceId) && getLegacyProviderSettings(settings, selection.instanceId)?.enabled) return settings;
|
|
1816
|
+
return fallbackTextGenerationProvider(settings);
|
|
1817
|
+
}
|
|
1818
|
+
function fallbackTextGenerationProvider(settings) {
|
|
1819
|
+
const fallbackEntry = Object.entries(settings.providers).find(([, provider]) => provider.enabled);
|
|
1820
|
+
const fallback = fallbackEntry ? require_collectUint8StreamText.ProviderDriverKind.make(fallbackEntry[0]) : void 0;
|
|
1821
|
+
if (!fallback) return settings;
|
|
1822
|
+
return {
|
|
1823
|
+
...settings,
|
|
1824
|
+
textGenerationModelSelection: {
|
|
1825
|
+
instanceId: require_collectUint8StreamText.ProviderInstanceId.make(fallback),
|
|
1826
|
+
model: require_collectUint8StreamText.DEFAULT_GIT_TEXT_GENERATION_MODEL_BY_PROVIDER[fallback] ?? "gpt-5.4-mini"
|
|
1827
|
+
}
|
|
1828
|
+
};
|
|
1829
|
+
}
|
|
1830
|
+
const ATOMIC_SETTINGS_KEYS = new Set(["textGenerationModelSelection"]);
|
|
1831
|
+
function stripDefaultServerSettings(current, defaults) {
|
|
1832
|
+
if (Array.isArray(current) || Array.isArray(defaults)) return effect.Equal.equals(current, defaults) ? void 0 : current;
|
|
1833
|
+
if (current !== null && defaults !== null && typeof current === "object" && typeof defaults === "object") {
|
|
1834
|
+
const currentRecord = current;
|
|
1835
|
+
const defaultsRecord = defaults;
|
|
1836
|
+
const next = {};
|
|
1837
|
+
for (const key of Object.keys(currentRecord)) if (ATOMIC_SETTINGS_KEYS.has(key)) {
|
|
1838
|
+
if (!effect.Equal.equals(currentRecord[key], defaultsRecord[key])) next[key] = currentRecord[key];
|
|
1839
|
+
} else {
|
|
1840
|
+
const stripped = stripDefaultServerSettings(currentRecord[key], defaultsRecord[key]);
|
|
1841
|
+
if (stripped !== void 0) next[key] = stripped;
|
|
1842
|
+
}
|
|
1843
|
+
return Object.keys(next).length > 0 ? next : void 0;
|
|
1844
|
+
}
|
|
1845
|
+
return Object.is(current, defaults) ? void 0 : current;
|
|
1846
|
+
}
|
|
1847
|
+
const makeServerSettings = effect.Effect.gen(function* () {
|
|
1848
|
+
const { settingsPath } = yield* require_Metrics.ServerConfig;
|
|
1849
|
+
const fs = yield* effect.FileSystem.FileSystem;
|
|
1850
|
+
const pathService = yield* effect.Path.Path;
|
|
1851
|
+
const secretStore = yield* ServerSecretStore;
|
|
1852
|
+
const writeSemaphore = yield* effect_Semaphore.make(1);
|
|
1853
|
+
const cacheKey = "settings";
|
|
1854
|
+
const changesPubSub = yield* effect.PubSub.unbounded();
|
|
1855
|
+
const startedRef = yield* effect.Ref.make(false);
|
|
1856
|
+
const startedDeferred = yield* effect.Deferred.make();
|
|
1857
|
+
const watcherScope = yield* effect.Scope.make("sequential");
|
|
1858
|
+
yield* effect.Effect.addFinalizer(() => effect.Scope.close(watcherScope, effect.Exit.void));
|
|
1859
|
+
const emitChange = (settings) => effect.PubSub.publish(changesPubSub, settings).pipe(effect.Effect.asVoid);
|
|
1860
|
+
const readConfigExists = fs.exists(settingsPath).pipe(effect.Effect.mapError((cause) => new require_collectUint8StreamText.ServerSettingsError({
|
|
1861
|
+
settingsPath,
|
|
1862
|
+
detail: "failed to check settings file existence",
|
|
1863
|
+
cause
|
|
1864
|
+
})));
|
|
1865
|
+
const readRawConfig = fs.readFileString(settingsPath).pipe(effect.Effect.mapError((cause) => new require_collectUint8StreamText.ServerSettingsError({
|
|
1866
|
+
settingsPath,
|
|
1867
|
+
detail: "failed to read settings file",
|
|
1868
|
+
cause
|
|
1869
|
+
})));
|
|
1870
|
+
const loadSettingsFromDisk = effect.Effect.gen(function* () {
|
|
1871
|
+
if (!(yield* readConfigExists)) return require_collectUint8StreamText.DEFAULT_SERVER_SETTINGS;
|
|
1872
|
+
const raw = yield* readRawConfig;
|
|
1873
|
+
const decoded = effect.Schema.decodeUnknownExit(ServerSettingsJson)(raw);
|
|
1874
|
+
if (decoded._tag === "Failure") {
|
|
1875
|
+
yield* effect.Effect.logWarning("failed to parse settings.json, using defaults", {
|
|
1876
|
+
path: settingsPath,
|
|
1877
|
+
issues: effect.Cause.pretty(decoded.cause)
|
|
1878
|
+
});
|
|
1879
|
+
return require_collectUint8StreamText.DEFAULT_SERVER_SETTINGS;
|
|
1880
|
+
}
|
|
1881
|
+
return decoded.value;
|
|
1882
|
+
});
|
|
1883
|
+
const settingsCache = yield* effect.Cache.make({
|
|
1884
|
+
capacity: 1,
|
|
1885
|
+
lookup: () => loadSettingsFromDisk
|
|
1886
|
+
});
|
|
1887
|
+
const getSettingsFromCache = effect.Cache.get(settingsCache, cacheKey);
|
|
1888
|
+
const toSettingsError = (detail, cause) => new require_collectUint8StreamText.ServerSettingsError({
|
|
1889
|
+
settingsPath,
|
|
1890
|
+
detail,
|
|
1891
|
+
cause
|
|
1892
|
+
});
|
|
1893
|
+
const materializeProviderEnvironmentSecrets = (settings) => effect.Effect.gen(function* () {
|
|
1894
|
+
const providerInstances = { ...settings.providerInstances };
|
|
1895
|
+
for (const [instanceId, instance] of Object.entries(settings.providerInstances)) {
|
|
1896
|
+
if (!instance.environment) continue;
|
|
1897
|
+
const environment = [];
|
|
1898
|
+
for (const variable of instance.environment) {
|
|
1899
|
+
if (!variable.sensitive || !variable.valueRedacted) {
|
|
1900
|
+
environment.push(variable);
|
|
1901
|
+
continue;
|
|
1902
|
+
}
|
|
1903
|
+
const secret = yield* secretStore.get(providerEnvironmentSecretName({
|
|
1904
|
+
instanceId,
|
|
1905
|
+
name: variable.name
|
|
1906
|
+
})).pipe(effect.Effect.mapError((cause) => toSettingsError(`failed to read sensitive environment variable ${variable.name}`, cause)));
|
|
1907
|
+
environment.push({
|
|
1908
|
+
...variable,
|
|
1909
|
+
value: secret ? textDecoder$2.decode(secret) : ""
|
|
1910
|
+
});
|
|
1911
|
+
}
|
|
1912
|
+
providerInstances[instanceId] = {
|
|
1913
|
+
...instance,
|
|
1914
|
+
environment
|
|
1915
|
+
};
|
|
1916
|
+
}
|
|
1917
|
+
return {
|
|
1918
|
+
...settings,
|
|
1919
|
+
providerInstances
|
|
1920
|
+
};
|
|
1921
|
+
});
|
|
1922
|
+
const persistProviderEnvironmentSecrets = (current, next) => effect.Effect.gen(function* () {
|
|
1923
|
+
const providerInstances = { ...next.providerInstances };
|
|
1924
|
+
const nextSecretKeys = /* @__PURE__ */ new Set();
|
|
1925
|
+
for (const [instanceId, instance] of Object.entries(next.providerInstances)) {
|
|
1926
|
+
if (!instance.environment) continue;
|
|
1927
|
+
const environment = [];
|
|
1928
|
+
for (const variable of instance.environment) {
|
|
1929
|
+
const secretName = providerEnvironmentSecretName({
|
|
1930
|
+
instanceId,
|
|
1931
|
+
name: variable.name
|
|
1932
|
+
});
|
|
1933
|
+
if (!variable.sensitive) {
|
|
1934
|
+
yield* secretStore.remove(secretName).pipe(effect.Effect.mapError((cause) => toSettingsError(`failed to remove environment secret ${variable.name}`, cause)));
|
|
1935
|
+
environment.push(redactProviderEnvironmentVariable(variable));
|
|
1936
|
+
continue;
|
|
1937
|
+
}
|
|
1938
|
+
nextSecretKeys.add(secretName);
|
|
1939
|
+
if (!variable.valueRedacted) {
|
|
1940
|
+
if (variable.value.length > 0) {
|
|
1941
|
+
yield* secretStore.set(secretName, textEncoder$2.encode(variable.value)).pipe(effect.Effect.mapError((cause) => toSettingsError(`failed to persist environment secret ${variable.name}`, cause)));
|
|
1942
|
+
environment.push({
|
|
1943
|
+
...variable,
|
|
1944
|
+
value: "",
|
|
1945
|
+
valueRedacted: true
|
|
1946
|
+
});
|
|
1947
|
+
} else {
|
|
1948
|
+
yield* secretStore.remove(secretName).pipe(effect.Effect.mapError((cause) => toSettingsError(`failed to remove environment secret ${variable.name}`, cause)));
|
|
1949
|
+
const { valueRedacted: _omit, ...rest } = variable;
|
|
1950
|
+
environment.push(rest);
|
|
1951
|
+
}
|
|
1952
|
+
continue;
|
|
1953
|
+
}
|
|
1954
|
+
environment.push(redactProviderEnvironmentVariable(variable));
|
|
1955
|
+
}
|
|
1956
|
+
providerInstances[instanceId] = {
|
|
1957
|
+
...instance,
|
|
1958
|
+
environment
|
|
1959
|
+
};
|
|
1960
|
+
}
|
|
1961
|
+
for (const [instanceId, instance] of Object.entries(current.providerInstances)) for (const variable of instance.environment ?? []) {
|
|
1962
|
+
if (!variable.sensitive) continue;
|
|
1963
|
+
const secretName = providerEnvironmentSecretName({
|
|
1964
|
+
instanceId,
|
|
1965
|
+
name: variable.name
|
|
1966
|
+
});
|
|
1967
|
+
if (nextSecretKeys.has(secretName)) continue;
|
|
1968
|
+
yield* secretStore.remove(secretName).pipe(effect.Effect.mapError((cause) => toSettingsError(`failed to remove stale environment secret ${variable.name}`, cause)));
|
|
1969
|
+
}
|
|
1970
|
+
return {
|
|
1971
|
+
...next,
|
|
1972
|
+
providerInstances
|
|
1973
|
+
};
|
|
1974
|
+
});
|
|
1975
|
+
const writeSettingsAtomically = (settings) => {
|
|
1976
|
+
const sparseSettings = stripDefaultServerSettings(settings, require_collectUint8StreamText.DEFAULT_SERVER_SETTINGS) ?? {};
|
|
1977
|
+
return writeFileStringAtomically({
|
|
1978
|
+
filePath: settingsPath,
|
|
1979
|
+
contents: `${JSON.stringify(sparseSettings, null, 2)}\n`
|
|
1980
|
+
}).pipe(effect.Effect.provideService(effect.FileSystem.FileSystem, fs), effect.Effect.provideService(effect.Path.Path, pathService), effect.Effect.mapError((cause) => new require_collectUint8StreamText.ServerSettingsError({
|
|
1981
|
+
settingsPath,
|
|
1982
|
+
detail: "failed to write settings file",
|
|
1983
|
+
cause
|
|
1984
|
+
})));
|
|
1985
|
+
};
|
|
1986
|
+
const revalidateAndEmit = writeSemaphore.withPermits(1)(effect.Effect.gen(function* () {
|
|
1987
|
+
yield* effect.Cache.invalidate(settingsCache, cacheKey);
|
|
1988
|
+
yield* emitChange(yield* getSettingsFromCache);
|
|
1989
|
+
}));
|
|
1990
|
+
const startWatcher = effect.Effect.gen(function* () {
|
|
1991
|
+
const settingsDir = pathService.dirname(settingsPath);
|
|
1992
|
+
const settingsFile = pathService.basename(settingsPath);
|
|
1993
|
+
const settingsPathResolved = pathService.resolve(settingsPath);
|
|
1994
|
+
yield* fs.makeDirectory(settingsDir, { recursive: true }).pipe(effect.Effect.mapError((cause) => new require_collectUint8StreamText.ServerSettingsError({
|
|
1995
|
+
settingsPath,
|
|
1996
|
+
detail: "failed to prepare settings directory",
|
|
1997
|
+
cause
|
|
1998
|
+
})));
|
|
1999
|
+
const revalidateAndEmitSafely = revalidateAndEmit.pipe(effect.Effect.ignoreCause({ log: true }));
|
|
2000
|
+
const debouncedSettingsEvents = fs.watch(settingsDir).pipe(effect.Stream.filter((event) => {
|
|
2001
|
+
return event.path === settingsFile || event.path === settingsPath || pathService.resolve(settingsDir, event.path) === settingsPathResolved;
|
|
2002
|
+
}), effect.Stream.debounce(effect.Duration.millis(100)));
|
|
2003
|
+
yield* effect.Stream.runForEach(debouncedSettingsEvents, () => revalidateAndEmitSafely).pipe(effect.Effect.ignoreCause({ log: true }), effect.Effect.forkIn(watcherScope), effect.Effect.asVoid);
|
|
2004
|
+
});
|
|
2005
|
+
return {
|
|
2006
|
+
start: effect.Effect.gen(function* () {
|
|
2007
|
+
if (!(yield* effect.Ref.modify(startedRef, (started) => [!started, true]))) return yield* effect.Deferred.await(startedDeferred);
|
|
2008
|
+
const startup = effect.Effect.gen(function* () {
|
|
2009
|
+
yield* startWatcher;
|
|
2010
|
+
yield* effect.Cache.invalidate(settingsCache, cacheKey);
|
|
2011
|
+
yield* getSettingsFromCache;
|
|
2012
|
+
});
|
|
2013
|
+
const startupExit = yield* effect.Effect.exit(startup);
|
|
2014
|
+
if (startupExit._tag === "Failure") {
|
|
2015
|
+
yield* effect.Deferred.failCause(startedDeferred, startupExit.cause).pipe(effect.Effect.orDie);
|
|
2016
|
+
return yield* effect.Effect.failCause(startupExit.cause);
|
|
2017
|
+
}
|
|
2018
|
+
yield* effect.Deferred.succeed(startedDeferred, void 0).pipe(effect.Effect.orDie);
|
|
2019
|
+
}),
|
|
2020
|
+
ready: effect.Deferred.await(startedDeferred),
|
|
2021
|
+
getSettings: getSettingsFromCache.pipe(effect.Effect.flatMap(materializeProviderEnvironmentSecrets), effect.Effect.map(resolveTextGenerationProvider)),
|
|
2022
|
+
updateSettings: (patch) => writeSemaphore.withPermits(1)(effect.Effect.gen(function* () {
|
|
2023
|
+
const current = yield* getSettingsFromCache;
|
|
2024
|
+
const nextPersisted = yield* persistProviderEnvironmentSecrets(current, applyServerSettingsPatch(current, patch));
|
|
2025
|
+
const next = yield* effect.Schema.decodeEffect(require_collectUint8StreamText.ServerSettings)(nextPersisted).pipe(effect.Effect.mapError((cause) => new require_collectUint8StreamText.ServerSettingsError({
|
|
2026
|
+
settingsPath: "<memory>",
|
|
2027
|
+
detail: `failed to normalize server settings: ${effect.SchemaIssue.makeFormatterDefault()(cause.issue)}`,
|
|
2028
|
+
cause
|
|
2029
|
+
})));
|
|
2030
|
+
yield* writeSettingsAtomically(next);
|
|
2031
|
+
yield* effect.Cache.set(settingsCache, cacheKey, next);
|
|
2032
|
+
yield* emitChange(next);
|
|
2033
|
+
return resolveTextGenerationProvider(yield* materializeProviderEnvironmentSecrets(next));
|
|
2034
|
+
})),
|
|
2035
|
+
get streamChanges() {
|
|
2036
|
+
return effect.Stream.fromPubSub(changesPubSub).pipe(effect.Stream.mapEffect((settings) => materializeProviderEnvironmentSecrets(settings).pipe(effect.Effect.catch((error) => effect.Effect.logWarning("failed to materialize provider environment secrets", { detail: error.detail }).pipe(effect.Effect.as(settings))))), effect.Stream.map(resolveTextGenerationProvider));
|
|
2037
|
+
}
|
|
2038
|
+
};
|
|
2039
|
+
});
|
|
2040
|
+
const ServerSettingsLive = effect.Layer.effect(ServerSettingsService, makeServerSettings).pipe(effect.Layer.provide(ServerSecretStoreLive));
|
|
2041
|
+
//#endregion
|
|
1660
2042
|
//#region src/provider/cliVersion.ts
|
|
1661
2043
|
const CLI_VERSION_NUMBER_SEGMENT = /^\d+$/;
|
|
1662
2044
|
function normalizeCliVersion(version) {
|
|
@@ -1957,7 +2339,8 @@ const resolveLatestProviderVersion = effect.Effect.fn("resolveLatestProviderVers
|
|
|
1957
2339
|
});
|
|
1958
2340
|
const enrichProviderSnapshotWithVersionAdvisory = effect.Effect.fn("enrichProviderSnapshotWithVersionAdvisory")(function* (snapshot, maintenanceCapabilities) {
|
|
1959
2341
|
const capabilities = maintenanceCapabilities ?? makeManualProviderMaintenanceCapabilities$1(snapshot.driver);
|
|
1960
|
-
|
|
2342
|
+
const { enableProviderUpdateChecks } = yield* (yield* ServerSettingsService).getSettings.pipe(effect.Effect.orElseSucceed(() => require_collectUint8StreamText.DEFAULT_SERVER_SETTINGS));
|
|
2343
|
+
if (!enableProviderUpdateChecks || !snapshot.enabled || !snapshot.installed || !snapshot.version) return {
|
|
1961
2344
|
...snapshot,
|
|
1962
2345
|
versionAdvisory: createProviderVersionAdvisory({
|
|
1963
2346
|
driver: snapshot.driver,
|
|
@@ -2052,6 +2435,7 @@ const make$21 = effect.Effect.fn("ProviderMaintenanceRunner.make")(function* ()
|
|
|
2052
2435
|
const providerRegistry = yield* ProviderRegistry;
|
|
2053
2436
|
const spawner = yield* effect_unstable_process.ChildProcessSpawner.ChildProcessSpawner;
|
|
2054
2437
|
const httpClient = yield* effect_unstable_http.HttpClient.HttpClient;
|
|
2438
|
+
const serverSettings = yield* ServerSettingsService;
|
|
2055
2439
|
const runMaintenanceCommand = (command, args) => runProviderMaintenanceCommandWithSpawner({
|
|
2056
2440
|
spawner,
|
|
2057
2441
|
command,
|
|
@@ -2070,7 +2454,7 @@ const make$21 = effect.Effect.fn("ProviderMaintenanceRunner.make")(function* ()
|
|
|
2070
2454
|
providers,
|
|
2071
2455
|
verifiedProviders: []
|
|
2072
2456
|
});
|
|
2073
|
-
return effect.Effect.forEach(refreshedProviders, (refreshedProvider) => enrichProviderSnapshotWithVersionAdvisory(refreshedProvider, maintenanceCapabilities).pipe(effect.Effect.provideService(effect_unstable_http.HttpClient.HttpClient, httpClient)), { concurrency: "unbounded" }).pipe(effect.Effect.map((verifiedProviders) => ({
|
|
2457
|
+
return effect.Effect.forEach(refreshedProviders, (refreshedProvider) => enrichProviderSnapshotWithVersionAdvisory(refreshedProvider, maintenanceCapabilities).pipe(effect.Effect.provideService(effect_unstable_http.HttpClient.HttpClient, httpClient), effect.Effect.provideService(ServerSettingsService, serverSettings)), { concurrency: "unbounded" }).pipe(effect.Effect.map((verifiedProviders) => ({
|
|
2074
2458
|
providers,
|
|
2075
2459
|
verifiedProviders
|
|
2076
2460
|
})), effect.Effect.catchCause((cause) => effect.Effect.logWarning("Provider post-update version verification failed", {
|
|
@@ -2160,78 +2544,6 @@ const make$21 = effect.Effect.fn("ProviderMaintenanceRunner.make")(function* ()
|
|
|
2160
2544
|
});
|
|
2161
2545
|
const layer$18 = effect.Layer.effect(ProviderMaintenanceRunner, make$21());
|
|
2162
2546
|
//#endregion
|
|
2163
|
-
//#region src/auth/Services/ServerSecretStore.ts
|
|
2164
|
-
var SecretStoreError = class extends effect.Data.TaggedError("SecretStoreError") {};
|
|
2165
|
-
var ServerSecretStore = class extends effect.Context.Service()("ryco/auth/Services/ServerSecretStore") {};
|
|
2166
|
-
//#endregion
|
|
2167
|
-
//#region src/auth/Layers/ServerSecretStore.ts
|
|
2168
|
-
const makeServerSecretStore = effect.Effect.gen(function* () {
|
|
2169
|
-
const fileSystem = yield* effect.FileSystem.FileSystem;
|
|
2170
|
-
const path = yield* effect.Path.Path;
|
|
2171
|
-
const serverConfig = yield* require_Metrics.ServerConfig;
|
|
2172
|
-
yield* fileSystem.makeDirectory(serverConfig.secretsDir, { recursive: true });
|
|
2173
|
-
yield* fileSystem.chmod(serverConfig.secretsDir, 448).pipe(effect.Effect.mapError((cause) => new SecretStoreError({
|
|
2174
|
-
message: `Failed to secure secrets directory ${serverConfig.secretsDir}.`,
|
|
2175
|
-
cause
|
|
2176
|
-
})));
|
|
2177
|
-
const resolveSecretPath = (name) => path.join(serverConfig.secretsDir, `${name}.bin`);
|
|
2178
|
-
const ensureSecretDirectory = (secretPath) => {
|
|
2179
|
-
const directory = path.dirname(secretPath);
|
|
2180
|
-
return fileSystem.makeDirectory(directory, { recursive: true }).pipe(effect.Effect.flatMap(() => fileSystem.chmod(directory, 448)));
|
|
2181
|
-
};
|
|
2182
|
-
const isPlatformError = (u) => effect.Predicate.isTagged(u, "PlatformError");
|
|
2183
|
-
const get = (name) => fileSystem.readFile(resolveSecretPath(name)).pipe(effect.Effect.map((bytes) => Uint8Array.from(bytes)), effect.Effect.catch((cause) => cause.reason._tag === "NotFound" ? effect.Effect.succeed(null) : effect.Effect.fail(new SecretStoreError({
|
|
2184
|
-
message: `Failed to read secret ${name}.`,
|
|
2185
|
-
cause
|
|
2186
|
-
}))));
|
|
2187
|
-
const set = (name, value) => {
|
|
2188
|
-
const secretPath = resolveSecretPath(name);
|
|
2189
|
-
const tempPath = `${secretPath}.${node_crypto.randomUUID()}.tmp`;
|
|
2190
|
-
return effect.Effect.gen(function* () {
|
|
2191
|
-
yield* ensureSecretDirectory(secretPath);
|
|
2192
|
-
yield* fileSystem.writeFile(tempPath, value);
|
|
2193
|
-
yield* fileSystem.chmod(tempPath, 384);
|
|
2194
|
-
yield* fileSystem.rename(tempPath, secretPath);
|
|
2195
|
-
yield* fileSystem.chmod(secretPath, 384);
|
|
2196
|
-
}).pipe(effect.Effect.catch((cause) => fileSystem.remove(tempPath).pipe(effect.Effect.ignore, effect.Effect.flatMap(() => effect.Effect.fail(new SecretStoreError({
|
|
2197
|
-
message: `Failed to persist secret ${name}.`,
|
|
2198
|
-
cause
|
|
2199
|
-
}))))));
|
|
2200
|
-
};
|
|
2201
|
-
const create = (name, value) => {
|
|
2202
|
-
const secretPath = resolveSecretPath(name);
|
|
2203
|
-
return effect.Effect.scoped(effect.Effect.gen(function* () {
|
|
2204
|
-
yield* ensureSecretDirectory(secretPath);
|
|
2205
|
-
const file = yield* fileSystem.open(secretPath, {
|
|
2206
|
-
flag: "wx",
|
|
2207
|
-
mode: 384
|
|
2208
|
-
});
|
|
2209
|
-
yield* file.writeAll(value);
|
|
2210
|
-
yield* file.sync;
|
|
2211
|
-
yield* fileSystem.chmod(secretPath, 384);
|
|
2212
|
-
})).pipe(effect.Effect.mapError((cause) => new SecretStoreError({
|
|
2213
|
-
message: `Failed to persist secret ${name}.`,
|
|
2214
|
-
cause
|
|
2215
|
-
})));
|
|
2216
|
-
};
|
|
2217
|
-
const getOrCreateRandom = (name, bytes) => get(name).pipe(effect.Effect.flatMap((existing) => {
|
|
2218
|
-
if (existing) return effect.Effect.succeed(existing);
|
|
2219
|
-
const generated = node_crypto.randomBytes(bytes);
|
|
2220
|
-
return create(name, generated).pipe(effect.Effect.as(Uint8Array.from(generated)), effect.Effect.catchTag("SecretStoreError", (error) => isPlatformError(error.cause) && error.cause.reason._tag === "AlreadyExists" ? get(name).pipe(effect.Effect.flatMap((created) => created !== null ? effect.Effect.succeed(created) : effect.Effect.fail(new SecretStoreError({ message: `Failed to read secret ${name} after concurrent creation.` })))) : effect.Effect.fail(error)));
|
|
2221
|
-
}));
|
|
2222
|
-
const remove = (name) => fileSystem.remove(resolveSecretPath(name)).pipe(effect.Effect.catch((cause) => cause.reason._tag === "NotFound" ? effect.Effect.void : effect.Effect.fail(new SecretStoreError({
|
|
2223
|
-
message: `Failed to remove secret ${name}.`,
|
|
2224
|
-
cause
|
|
2225
|
-
}))));
|
|
2226
|
-
return {
|
|
2227
|
-
get,
|
|
2228
|
-
set,
|
|
2229
|
-
getOrCreateRandom,
|
|
2230
|
-
remove
|
|
2231
|
-
};
|
|
2232
|
-
});
|
|
2233
|
-
const ServerSecretStoreLive = effect.Layer.effect(ServerSecretStore, makeServerSecretStore);
|
|
2234
|
-
//#endregion
|
|
2235
2547
|
//#region src/persistence/Errors.ts
|
|
2236
2548
|
var PersistenceSqlError = class extends effect.Schema.TaggedErrorClass()("PersistenceSqlError", {
|
|
2237
2549
|
operation: effect.Schema.String,
|
|
@@ -3925,6 +4237,35 @@ var _040_ProjectionThreadsProjectUpdatedAtIndex_default = effect_Effect.gen(func
|
|
|
3925
4237
|
`;
|
|
3926
4238
|
});
|
|
3927
4239
|
//#endregion
|
|
4240
|
+
//#region src/persistence/Migrations/041_ProjectionThreadsSubagentNesting.ts
|
|
4241
|
+
var _041_ProjectionThreadsSubagentNesting_default = effect_Effect.gen(function* () {
|
|
4242
|
+
const sql = yield* effect_unstable_sql_SqlClient.SqlClient;
|
|
4243
|
+
const columns = yield* sql`
|
|
4244
|
+
PRAGMA table_info(projection_threads)
|
|
4245
|
+
`;
|
|
4246
|
+
const columnNames = new Set(columns.map((column) => column.name));
|
|
4247
|
+
if (!columnNames.has("thread_kind")) yield* sql`
|
|
4248
|
+
ALTER TABLE projection_threads
|
|
4249
|
+
ADD COLUMN thread_kind TEXT NOT NULL DEFAULT 'normal'
|
|
4250
|
+
`;
|
|
4251
|
+
if (!columnNames.has("visibility")) yield* sql`
|
|
4252
|
+
ALTER TABLE projection_threads
|
|
4253
|
+
ADD COLUMN visibility TEXT NOT NULL DEFAULT 'normal'
|
|
4254
|
+
`;
|
|
4255
|
+
if (!columnNames.has("parent_thread_id")) yield* sql`
|
|
4256
|
+
ALTER TABLE projection_threads
|
|
4257
|
+
ADD COLUMN parent_thread_id TEXT
|
|
4258
|
+
`;
|
|
4259
|
+
if (!columnNames.has("parent_subagent_id")) yield* sql`
|
|
4260
|
+
ALTER TABLE projection_threads
|
|
4261
|
+
ADD COLUMN parent_subagent_id TEXT
|
|
4262
|
+
`;
|
|
4263
|
+
yield* sql`
|
|
4264
|
+
CREATE INDEX IF NOT EXISTS idx_projection_threads_parent_thread
|
|
4265
|
+
ON projection_threads(parent_thread_id, created_at, thread_id)
|
|
4266
|
+
`;
|
|
4267
|
+
});
|
|
4268
|
+
//#endregion
|
|
3928
4269
|
//#region src/persistence/Migrations.ts
|
|
3929
4270
|
/**
|
|
3930
4271
|
* MigrationsLive - Migration runner with inline loader
|
|
@@ -4145,6 +4486,11 @@ const migrationEntries = [
|
|
|
4145
4486
|
40,
|
|
4146
4487
|
"ProjectionThreadsProjectUpdatedAtIndex",
|
|
4147
4488
|
_040_ProjectionThreadsProjectUpdatedAtIndex_default
|
|
4489
|
+
],
|
|
4490
|
+
[
|
|
4491
|
+
41,
|
|
4492
|
+
"ProjectionThreadsSubagentNesting",
|
|
4493
|
+
_041_ProjectionThreadsSubagentNesting_default
|
|
4148
4494
|
]
|
|
4149
4495
|
];
|
|
4150
4496
|
const makeMigrationLoader = (throughId) => effect_unstable_sql_Migrator.fromRecord(Object.fromEntries(migrationEntries.filter(([id]) => throughId === void 0 || id <= throughId).map(([id, name, migration]) => [`${id}_${name}`, migration])));
|
|
@@ -4214,6 +4560,45 @@ const repairProjectionTokenModeColumns = effect_Effect.fn("repairProjectionToken
|
|
|
4214
4560
|
yield* effect_Effect.log("Repaired projection_thread_sessions.token_mode column");
|
|
4215
4561
|
}
|
|
4216
4562
|
});
|
|
4563
|
+
const repairProjectionThreadSubagentNestingColumns = effect_Effect.fn("repairProjectionThreadSubagentNestingColumns")(function* () {
|
|
4564
|
+
const sql = yield* effect_unstable_sql_SqlClient.SqlClient;
|
|
4565
|
+
if ((yield* sql`
|
|
4566
|
+
SELECT name FROM sqlite_master
|
|
4567
|
+
WHERE type = 'table' AND name = 'projection_threads'
|
|
4568
|
+
`).length === 0) return;
|
|
4569
|
+
const columns = yield* sql`
|
|
4570
|
+
PRAGMA table_info(projection_threads)
|
|
4571
|
+
`;
|
|
4572
|
+
const columnNames = new Set(columns.map((column) => column.name));
|
|
4573
|
+
if (!columnNames.has("thread_kind")) {
|
|
4574
|
+
yield* sql`
|
|
4575
|
+
ALTER TABLE projection_threads
|
|
4576
|
+
ADD COLUMN thread_kind TEXT NOT NULL DEFAULT 'normal'
|
|
4577
|
+
`;
|
|
4578
|
+
yield* effect_Effect.log("Repaired projection_threads.thread_kind column");
|
|
4579
|
+
}
|
|
4580
|
+
if (!columnNames.has("visibility")) {
|
|
4581
|
+
yield* sql`
|
|
4582
|
+
ALTER TABLE projection_threads
|
|
4583
|
+
ADD COLUMN visibility TEXT NOT NULL DEFAULT 'normal'
|
|
4584
|
+
`;
|
|
4585
|
+
yield* effect_Effect.log("Repaired projection_threads.visibility column");
|
|
4586
|
+
}
|
|
4587
|
+
if (!columnNames.has("parent_thread_id")) {
|
|
4588
|
+
yield* sql`
|
|
4589
|
+
ALTER TABLE projection_threads
|
|
4590
|
+
ADD COLUMN parent_thread_id TEXT
|
|
4591
|
+
`;
|
|
4592
|
+
yield* effect_Effect.log("Repaired projection_threads.parent_thread_id column");
|
|
4593
|
+
}
|
|
4594
|
+
if (!columnNames.has("parent_subagent_id")) {
|
|
4595
|
+
yield* sql`
|
|
4596
|
+
ALTER TABLE projection_threads
|
|
4597
|
+
ADD COLUMN parent_subagent_id TEXT
|
|
4598
|
+
`;
|
|
4599
|
+
yield* effect_Effect.log("Repaired projection_threads.parent_subagent_id column");
|
|
4600
|
+
}
|
|
4601
|
+
});
|
|
4217
4602
|
/**
|
|
4218
4603
|
* Run all pending migrations.
|
|
4219
4604
|
*
|
|
@@ -4230,6 +4615,7 @@ const runMigrations = effect_Effect.fn("runMigrations")(function* ({ toMigration
|
|
|
4230
4615
|
if (toMigrationInclusive === void 0 || toMigrationInclusive >= 31) yield* repairProjectionWorktreeTitleColumn();
|
|
4231
4616
|
if (toMigrationInclusive === void 0 || toMigrationInclusive >= 34) yield* repairProjectionProjectAvatarColumns();
|
|
4232
4617
|
if (toMigrationInclusive === void 0 || toMigrationInclusive >= 35) yield* repairProjectionTokenModeColumns();
|
|
4618
|
+
if (toMigrationInclusive === void 0 || toMigrationInclusive >= 41) yield* repairProjectionThreadSubagentNestingColumns();
|
|
4233
4619
|
yield* effect_Effect.log("Migrations ran successfully").pipe(effect_Effect.annotateLogs({ migrations: executedMigrations.map(([id, name]) => `${id}_${name}`) }));
|
|
4234
4620
|
return executedMigrations;
|
|
4235
4621
|
});
|
|
@@ -4238,7 +4624,7 @@ effect_Layer.effectDiscard(runMigrations());
|
|
|
4238
4624
|
//#region src/persistence/Layers/Sqlite.ts
|
|
4239
4625
|
const defaultSqliteClientLoaders = {
|
|
4240
4626
|
bun: () => import("@effect/sql-sqlite-bun/SqliteClient"),
|
|
4241
|
-
node: () => Promise.resolve().then(() => require("./NodeSqliteClient-
|
|
4627
|
+
node: () => Promise.resolve().then(() => require("./NodeSqliteClient-D1O-MR8w.cjs"))
|
|
4242
4628
|
};
|
|
4243
4629
|
const makeRuntimeSqliteLayer = effect.Effect.fn("makeRuntimeSqliteLayer")(function* (config) {
|
|
4244
4630
|
const loader = defaultSqliteClientLoaders[process.versions.bun !== void 0 ? "bun" : "node"];
|
|
@@ -4304,10 +4690,10 @@ function normalizeAzureDevOpsPullRequestRecord(raw) {
|
|
|
4304
4690
|
updatedAt: (raw.closedDate ?? effect.Option.none()).pipe(effect.Option.orElse(() => raw.creationDate ?? effect.Option.none()))
|
|
4305
4691
|
};
|
|
4306
4692
|
}
|
|
4307
|
-
const decodeAzureDevOpsPullRequestList =
|
|
4308
|
-
const decodeAzureDevOpsPullRequest =
|
|
4693
|
+
const decodeAzureDevOpsPullRequestList = require_collectUint8StreamText.decodeJsonResult(effect.Schema.Array(effect.Schema.Unknown));
|
|
4694
|
+
const decodeAzureDevOpsPullRequest = require_collectUint8StreamText.decodeJsonResult(AzureDevOpsPullRequestSchema);
|
|
4309
4695
|
const decodeAzureDevOpsPullRequestEntry = effect.Schema.decodeUnknownExit(AzureDevOpsPullRequestSchema);
|
|
4310
|
-
const formatAzureDevOpsJsonDecodeError =
|
|
4696
|
+
const formatAzureDevOpsJsonDecodeError = require_collectUint8StreamText.formatSchemaError;
|
|
4311
4697
|
function decodeAzureDevOpsPullRequestListJson(raw) {
|
|
4312
4698
|
const result = decodeAzureDevOpsPullRequestList(raw);
|
|
4313
4699
|
if (effect.Result.isSuccess(result)) {
|
|
@@ -4345,7 +4731,7 @@ function flattenThreadComments(threads) {
|
|
|
4345
4731
|
createdAt: c.publishedDate ?? ""
|
|
4346
4732
|
}));
|
|
4347
4733
|
}
|
|
4348
|
-
const decodeAzurePullRequestDetail =
|
|
4734
|
+
const decodeAzurePullRequestDetail = require_collectUint8StreamText.decodeJsonResult(effect.Schema.Struct({
|
|
4349
4735
|
...AzureDevOpsPullRequestSchema.fields,
|
|
4350
4736
|
description: effect.Schema.optional(effect.Schema.NullOr(effect.Schema.String)),
|
|
4351
4737
|
threads: effect.Schema.optional(effect.Schema.Array(AzureThreadSchema))
|
|
@@ -4360,7 +4746,7 @@ function decodeAzureDevOpsPullRequestDetailJson(raw) {
|
|
|
4360
4746
|
comments: flattenThreadComments(result.success.threads ?? [])
|
|
4361
4747
|
});
|
|
4362
4748
|
}
|
|
4363
|
-
const decodeThreadList =
|
|
4749
|
+
const decodeThreadList = require_collectUint8StreamText.decodeJsonResult(effect.Schema.Array(AzureThreadSchema));
|
|
4364
4750
|
function decodeAzureDevOpsPullRequestThreadsJson(raw) {
|
|
4365
4751
|
if (raw.length === 0) return effect.Result.succeed([]);
|
|
4366
4752
|
const result = decodeThreadList(raw);
|
|
@@ -4434,10 +4820,10 @@ function normalize(raw) {
|
|
|
4434
4820
|
labels: labelsFromTags(raw.fields["System.Tags"])
|
|
4435
4821
|
};
|
|
4436
4822
|
}
|
|
4437
|
-
const decodeWorkItemList =
|
|
4823
|
+
const decodeWorkItemList = require_collectUint8StreamText.decodeJsonResult(effect.Schema.Array(effect.Schema.Unknown));
|
|
4438
4824
|
const decodeWorkItemEntry = effect.Schema.decodeUnknownExit(AzureWorkItemSchema);
|
|
4439
|
-
const decodeWorkItemDetail =
|
|
4440
|
-
const formatAzureDevOpsWorkItemDecodeError =
|
|
4825
|
+
const decodeWorkItemDetail = require_collectUint8StreamText.decodeJsonResult(AzureWorkItemSchema);
|
|
4826
|
+
const formatAzureDevOpsWorkItemDecodeError = require_collectUint8StreamText.formatSchemaError;
|
|
4441
4827
|
function decodeAzureDevOpsWorkItemListJson(raw) {
|
|
4442
4828
|
const result = decodeWorkItemList(raw);
|
|
4443
4829
|
if (!effect.Result.isSuccess(result)) return effect.Result.fail(result.failure);
|
|
@@ -4855,9 +5241,9 @@ function normalizeBitbucketCommentList(decoded) {
|
|
|
4855
5241
|
createdAt: c.created_on
|
|
4856
5242
|
}));
|
|
4857
5243
|
}
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
5244
|
+
require_collectUint8StreamText.decodeJsonResult(BitbucketIssueListSchema);
|
|
5245
|
+
require_collectUint8StreamText.decodeJsonResult(BitbucketIssueSchema);
|
|
5246
|
+
require_collectUint8StreamText.decodeJsonResult(BitbucketCommentListSchema);
|
|
4861
5247
|
//#endregion
|
|
4862
5248
|
//#region src/sourceControl/bitbucketPullRequests.ts
|
|
4863
5249
|
const BitbucketRepositoryRefSchema = effect.Schema.Struct({
|
|
@@ -4940,7 +5326,7 @@ const BitbucketPullRequestDetailSchema = effect.Schema.Struct({
|
|
|
4940
5326
|
...BitbucketPullRequestSchema.fields,
|
|
4941
5327
|
summary: effect.Schema.optional(effect.Schema.NullOr(effect.Schema.Struct({ raw: effect.Schema.optional(effect.Schema.NullOr(effect.Schema.String)) })))
|
|
4942
5328
|
});
|
|
4943
|
-
|
|
5329
|
+
require_collectUint8StreamText.decodeJsonResult(BitbucketPullRequestDetailSchema);
|
|
4944
5330
|
const WORK_ITEM_KEY_PATTERN = /\b([A-Z][A-Z0-9]{1,9})-(\d+)\b/giu;
|
|
4945
5331
|
function extractWorkItemKeys(input) {
|
|
4946
5332
|
const keys = /* @__PURE__ */ new Set();
|
|
@@ -5023,7 +5409,7 @@ effect.Schema.Struct({
|
|
|
5023
5409
|
var ProjectAtlassianLinkRepository = class extends effect.Context.Service()("ryco/persistence/Services/ProjectAtlassianLinks/ProjectAtlassianLinkRepository") {};
|
|
5024
5410
|
//#endregion
|
|
5025
5411
|
//#region src/atlassian/AtlassianConnectionService.ts
|
|
5026
|
-
const textEncoder$
|
|
5412
|
+
const textEncoder$1 = new TextEncoder();
|
|
5027
5413
|
var AtlassianConnectionService = class extends effect.Context.Service()("ryco/atlassian/AtlassianConnectionService") {};
|
|
5028
5414
|
function atlassianError(operation, detail, cause) {
|
|
5029
5415
|
return new require_collectUint8StreamText.AtlassianConnectionError({
|
|
@@ -5151,7 +5537,7 @@ const make$19 = effect.Effect.fn("makeAtlassianConnectionService")(function* ()
|
|
|
5151
5537
|
createdAt,
|
|
5152
5538
|
updatedAt: createdAt
|
|
5153
5539
|
};
|
|
5154
|
-
return secretStore.set(manualBitbucketTokenSecretName(connectionId), textEncoder$
|
|
5540
|
+
return secretStore.set(manualBitbucketTokenSecretName(connectionId), textEncoder$1.encode(input.token)).pipe(effect.Effect.flatMap(() => connections.upsert(record)), cleanupSecretOnFailure(manualBitbucketTokenSecretName(connectionId)), effect.Effect.as(toSummary(record)), effect.Effect.mapError(mapError$1("atlassian.saveManualBitbucketToken", "Failed to save the Bitbucket token.")));
|
|
5155
5541
|
},
|
|
5156
5542
|
saveManualJiraToken: (input) => {
|
|
5157
5543
|
const createdAt = nowIso$2();
|
|
@@ -5187,7 +5573,7 @@ const make$19 = effect.Effect.fn("makeAtlassianConnectionService")(function* ()
|
|
|
5187
5573
|
avatarUrl: null,
|
|
5188
5574
|
updatedAt: createdAt
|
|
5189
5575
|
};
|
|
5190
|
-
return secretStore.set(manualJiraTokenSecretName(connectionId), textEncoder$
|
|
5576
|
+
return secretStore.set(manualJiraTokenSecretName(connectionId), textEncoder$1.encode(input.token)).pipe(effect.Effect.flatMap(() => connections.upsert(record)), effect.Effect.flatMap(() => resources.upsertForConnection({
|
|
5191
5577
|
connectionId,
|
|
5192
5578
|
resources: [resource]
|
|
5193
5579
|
})), cleanupSecretOnFailure(manualJiraTokenSecretName(connectionId)), effect.Effect.as(toSummary(record)), effect.Effect.mapError(mapError$1("atlassian.saveManualJiraToken", "Failed to save the Jira API token.")));
|
|
@@ -5303,6 +5689,11 @@ const NON_REPOSITORY_STATUS_DETAILS = Object.freeze({
|
|
|
5303
5689
|
behindCount: 0,
|
|
5304
5690
|
aheadOfDefaultCount: 0
|
|
5305
5691
|
});
|
|
5692
|
+
const emptyDiffTotals = () => ({
|
|
5693
|
+
files: [],
|
|
5694
|
+
insertions: 0,
|
|
5695
|
+
deletions: 0
|
|
5696
|
+
});
|
|
5306
5697
|
var StatusRemoteRefreshCacheKey = class extends effect.Data.Class {};
|
|
5307
5698
|
function parseBranchAb(value) {
|
|
5308
5699
|
const match = value.match(/^\+(\d+)\s+-(\d+)$/);
|
|
@@ -5502,7 +5893,7 @@ const createTrace2Monitor = effect.Effect.fn("createTrace2Monitor")(function* (i
|
|
|
5502
5893
|
const handleTraceLine = effect.Effect.fn("handleTraceLine")(function* (line) {
|
|
5503
5894
|
const trimmedLine = line.trim();
|
|
5504
5895
|
if (trimmedLine.length === 0) return;
|
|
5505
|
-
const traceRecord =
|
|
5896
|
+
const traceRecord = require_collectUint8StreamText.decodeJsonResult(Trace2Record)(trimmedLine);
|
|
5506
5897
|
if (effect.Result.isFailure(traceRecord)) {
|
|
5507
5898
|
yield* effect.Effect.logDebug(`GitVcsDriver.trace2: failed to parse trace line for ${quoteGitCommand(input.args)} in ${input.cwd}`, traceRecord.failure);
|
|
5508
5899
|
return;
|
|
@@ -5949,6 +6340,31 @@ const makeGitVcsDriverCore = effect.Effect.fn("makeGitVcsDriverCore")(function*
|
|
|
5949
6340
|
const parsed = Number.parseInt(result.stdout.trim(), 10);
|
|
5950
6341
|
return Number.isFinite(parsed) ? Math.max(0, parsed) : 0;
|
|
5951
6342
|
});
|
|
6343
|
+
const readCommittedAgainstBase = effect.Effect.fn("readCommittedAgainstBase")(function* (cwd, refName) {
|
|
6344
|
+
const baseRef = yield* resolveBaseBranchForNoUpstream(cwd, refName).pipe(effect.Effect.catch(() => effect.Effect.succeed(null)));
|
|
6345
|
+
if (!baseRef) return emptyDiffTotals();
|
|
6346
|
+
const result = yield* executeGit("GitVcsDriver.readCommittedAgainstBase.diff", cwd, [
|
|
6347
|
+
"diff",
|
|
6348
|
+
"--numstat",
|
|
6349
|
+
`${baseRef}...HEAD`
|
|
6350
|
+
], { allowNonZeroExit: true });
|
|
6351
|
+
if (result.exitCode !== 0) return emptyDiffTotals();
|
|
6352
|
+
let insertions = 0;
|
|
6353
|
+
let deletions = 0;
|
|
6354
|
+
return {
|
|
6355
|
+
files: parseNumstatEntries(result.stdout).map((entry) => {
|
|
6356
|
+
insertions += entry.insertions;
|
|
6357
|
+
deletions += entry.deletions;
|
|
6358
|
+
return {
|
|
6359
|
+
path: entry.path,
|
|
6360
|
+
insertions: entry.insertions,
|
|
6361
|
+
deletions: entry.deletions
|
|
6362
|
+
};
|
|
6363
|
+
}).toSorted((a, b) => a.path.localeCompare(b.path)),
|
|
6364
|
+
insertions,
|
|
6365
|
+
deletions
|
|
6366
|
+
};
|
|
6367
|
+
});
|
|
5952
6368
|
const readBranchRecency = effect.Effect.fn("readBranchRecency")(function* (cwd) {
|
|
5953
6369
|
const branchRecency = yield* executeGit("GitVcsDriver.readBranchRecency", cwd, [
|
|
5954
6370
|
"for-each-ref",
|
|
@@ -6067,6 +6483,7 @@ const makeGitVcsDriverCore = effect.Effect.fn("makeGitVcsDriverCore")(function*
|
|
|
6067
6483
|
});
|
|
6068
6484
|
}
|
|
6069
6485
|
files.sort((a, b) => a.path.localeCompare(b.path));
|
|
6486
|
+
const committed = refName && !isDefaultBranch ? yield* readCommittedAgainstBase(cwd, refName).pipe(effect.Effect.catch(() => effect.Effect.succeed(emptyDiffTotals()))) : void 0;
|
|
6070
6487
|
return {
|
|
6071
6488
|
isRepo: true,
|
|
6072
6489
|
hasOriginRemote: hasPrimaryRemote,
|
|
@@ -6079,6 +6496,7 @@ const makeGitVcsDriverCore = effect.Effect.fn("makeGitVcsDriverCore")(function*
|
|
|
6079
6496
|
insertions,
|
|
6080
6497
|
deletions
|
|
6081
6498
|
},
|
|
6499
|
+
...committed ? { committed } : {},
|
|
6082
6500
|
hasUpstream: upstreamRef !== null,
|
|
6083
6501
|
aheadCount,
|
|
6084
6502
|
behindCount,
|
|
@@ -6099,6 +6517,7 @@ const makeGitVcsDriverCore = effect.Effect.fn("makeGitVcsDriverCore")(function*
|
|
|
6099
6517
|
refName: details.branch,
|
|
6100
6518
|
hasWorkingTreeChanges: details.hasWorkingTreeChanges,
|
|
6101
6519
|
workingTree: details.workingTree,
|
|
6520
|
+
...details.committed ? { committed: details.committed } : {},
|
|
6102
6521
|
hasUpstream: details.hasUpstream,
|
|
6103
6522
|
aheadCount: details.aheadCount,
|
|
6104
6523
|
behindCount: details.behindCount,
|
|
@@ -6991,7 +7410,7 @@ const layer$13 = effect.Layer.effect(VcsDriverRegistry, make$16()).pipe(effect.L
|
|
|
6991
7410
|
//#endregion
|
|
6992
7411
|
//#region src/sourceControl/BitbucketApi.ts
|
|
6993
7412
|
const DEFAULT_API_BASE_URL = "https://api.bitbucket.org/2.0";
|
|
6994
|
-
const textDecoder$
|
|
7413
|
+
const textDecoder$1 = new TextDecoder();
|
|
6995
7414
|
const BitbucketApiEnvConfig = effect.Config.all({
|
|
6996
7415
|
baseUrl: effect.Config.string("RYCO_BITBUCKET_API_BASE_URL").pipe(effect.Config.withDefault(DEFAULT_API_BASE_URL)),
|
|
6997
7416
|
accessToken: effect.Config.string("RYCO_BITBUCKET_ACCESS_TOKEN").pipe(effect.Config.option),
|
|
@@ -7336,7 +7755,7 @@ const make$15 = effect.Effect.fn("makeBitbucketApi")(function* () {
|
|
|
7336
7755
|
cause
|
|
7337
7756
|
})));
|
|
7338
7757
|
if (!tokenBytes || tokenBytes.length === 0) continue;
|
|
7339
|
-
const token = textDecoder$
|
|
7758
|
+
const token = textDecoder$1.decode(tokenBytes).trim();
|
|
7340
7759
|
if (!token) continue;
|
|
7341
7760
|
return {
|
|
7342
7761
|
source: "stored",
|
|
@@ -7741,9 +8160,9 @@ function normalizeForgejoIssueDetail(input) {
|
|
|
7741
8160
|
comments: input.comments.map(normalizeForgejoComment)
|
|
7742
8161
|
};
|
|
7743
8162
|
}
|
|
7744
|
-
|
|
7745
|
-
|
|
7746
|
-
|
|
8163
|
+
require_collectUint8StreamText.decodeJsonResult(effect.Schema.Array(effect.Schema.Unknown));
|
|
8164
|
+
require_collectUint8StreamText.decodeJsonResult(ForgejoIssueSchema);
|
|
8165
|
+
require_collectUint8StreamText.decodeJsonResult(ForgejoCommentListSchema);
|
|
7747
8166
|
effect.Schema.decodeUnknownExit(ForgejoIssueSchema);
|
|
7748
8167
|
//#endregion
|
|
7749
8168
|
//#region src/sourceControl/forgejoPullRequests.ts
|
|
@@ -7882,8 +8301,8 @@ function normalizeForgejoPullRequestDetail(input) {
|
|
|
7882
8301
|
files
|
|
7883
8302
|
};
|
|
7884
8303
|
}
|
|
7885
|
-
|
|
7886
|
-
|
|
8304
|
+
require_collectUint8StreamText.decodeJsonResult(effect.Schema.Array(effect.Schema.Unknown));
|
|
8305
|
+
require_collectUint8StreamText.decodeJsonResult(ForgejoPullRequestSchema);
|
|
7887
8306
|
effect.Schema.decodeUnknownExit(ForgejoPullRequestSchema);
|
|
7888
8307
|
//#endregion
|
|
7889
8308
|
//#region src/sourceControl/ForgejoApi.ts
|
|
@@ -7915,7 +8334,7 @@ const ForgejoCliLoginSchema = effect.Schema.Struct({
|
|
|
7915
8334
|
name: effect.Schema.optional(require_collectUint8StreamText.TrimmedNonEmptyString),
|
|
7916
8335
|
token: effect.Schema.optional(require_collectUint8StreamText.TrimmedNonEmptyString)
|
|
7917
8336
|
});
|
|
7918
|
-
const decodeForgejoCliKeysJson =
|
|
8337
|
+
const decodeForgejoCliKeysJson = require_collectUint8StreamText.decodeJsonResult(effect.Schema.Struct({ hosts: effect.Schema.optional(effect.Schema.Record(effect.Schema.String, ForgejoCliLoginSchema)) }));
|
|
7919
8338
|
var ForgejoApi = class extends effect.Context.Service()("ryco/source-control/ForgejoApi") {};
|
|
7920
8339
|
function nonEmpty$1(value) {
|
|
7921
8340
|
const trimmed = value?.trim();
|
|
@@ -8478,7 +8897,7 @@ const RawGitHubReactionGroupSchema = effect.Schema.Struct({
|
|
|
8478
8897
|
reactors: effect.Schema.optional(effect.Schema.Struct({ totalCount: effect.Schema.optional(effect.Schema.Number) })),
|
|
8479
8898
|
users: effect.Schema.optional(effect.Schema.Struct({ totalCount: effect.Schema.optional(effect.Schema.Number) }))
|
|
8480
8899
|
});
|
|
8481
|
-
const decodeReactionGroupsBySubject =
|
|
8900
|
+
const decodeReactionGroupsBySubject = require_collectUint8StreamText.decodeJsonResult(effect.Schema.Struct({ data: effect.Schema.Struct({ nodes: effect.Schema.Array(effect.Schema.NullOr(effect.Schema.Struct({
|
|
8482
8901
|
id: effect.Schema.String,
|
|
8483
8902
|
reactionGroups: effect.Schema.Array(RawGitHubReactionGroupSchema)
|
|
8484
8903
|
}))) }) }));
|
|
@@ -8521,7 +8940,7 @@ function normalizeReactionGroups(raw) {
|
|
|
8521
8940
|
}];
|
|
8522
8941
|
});
|
|
8523
8942
|
}
|
|
8524
|
-
const formatGitHubReactionGroupsDecodeError =
|
|
8943
|
+
const formatGitHubReactionGroupsDecodeError = require_collectUint8StreamText.formatSchemaError;
|
|
8525
8944
|
function decodeGitHubReactionGroupsBySubjectJson(raw) {
|
|
8526
8945
|
const result = decodeReactionGroupsBySubject(raw);
|
|
8527
8946
|
if (!effect.Result.isSuccess(result)) return effect.Result.fail(result.failure);
|
|
@@ -8599,8 +9018,8 @@ function normalizeGitHubIssueRecord(raw) {
|
|
|
8599
9018
|
commentsCount
|
|
8600
9019
|
};
|
|
8601
9020
|
}
|
|
8602
|
-
const decodeIssueList$1 =
|
|
8603
|
-
const decodeIssueDetail$1 =
|
|
9021
|
+
const decodeIssueList$1 = require_collectUint8StreamText.decodeJsonResult(effect.Schema.Array(effect.Schema.Unknown));
|
|
9022
|
+
const decodeIssueDetail$1 = require_collectUint8StreamText.decodeJsonResult(GitHubIssueSchema);
|
|
8604
9023
|
const decodeIssueEntry$1 = effect.Schema.decodeUnknownExit(GitHubIssueSchema);
|
|
8605
9024
|
const GitHubLabelSchema = effect.Schema.Struct({
|
|
8606
9025
|
name: effect.Schema.String,
|
|
@@ -8612,9 +9031,9 @@ const GitHubAssigneeSchema = effect.Schema.Struct({
|
|
|
8612
9031
|
name: effect.Schema.optional(effect.Schema.NullOr(effect.Schema.String)),
|
|
8613
9032
|
avatar_url: effect.Schema.optional(effect.Schema.NullOr(effect.Schema.String))
|
|
8614
9033
|
});
|
|
8615
|
-
const decodeJsonLabelList =
|
|
8616
|
-
const decodeJsonAssigneeList =
|
|
8617
|
-
const formatGitHubIssueDecodeError =
|
|
9034
|
+
const decodeJsonLabelList = require_collectUint8StreamText.decodeJsonResult(effect.Schema.Array(GitHubLabelSchema));
|
|
9035
|
+
const decodeJsonAssigneeList = require_collectUint8StreamText.decodeJsonResult(effect.Schema.Array(GitHubAssigneeSchema));
|
|
9036
|
+
const formatGitHubIssueDecodeError = require_collectUint8StreamText.formatSchemaError;
|
|
8618
9037
|
function decodeGitHubIssueListJson(raw) {
|
|
8619
9038
|
const result = decodeIssueList$1(raw);
|
|
8620
9039
|
if (!effect.Result.isSuccess(result)) return effect.Result.fail(result.failure);
|
|
@@ -8763,10 +9182,10 @@ function normalizePullRequestWorkflowContext(raw) {
|
|
|
8763
9182
|
baseRepositoryNameWithOwner: optionalTrimmed(raw.base?.repo?.full_name)
|
|
8764
9183
|
};
|
|
8765
9184
|
}
|
|
8766
|
-
const decodeWorkflowRunsResponse =
|
|
8767
|
-
const decodeWorkflowJobsResponse =
|
|
8768
|
-
const decodePullRequestWorkflowContext =
|
|
8769
|
-
const formatGitHubWorkflowDecodeError =
|
|
9185
|
+
const decodeWorkflowRunsResponse = require_collectUint8StreamText.decodeJsonResult(RawGitHubWorkflowRunsResponseSchema);
|
|
9186
|
+
const decodeWorkflowJobsResponse = require_collectUint8StreamText.decodeJsonResult(RawGitHubWorkflowJobsPayloadSchema);
|
|
9187
|
+
const decodePullRequestWorkflowContext = require_collectUint8StreamText.decodeJsonResult(RawGitHubPullRequestWorkflowContextSchema);
|
|
9188
|
+
const formatGitHubWorkflowDecodeError = require_collectUint8StreamText.formatSchemaError;
|
|
8770
9189
|
function decodeGitHubWorkflowRunsJson(raw) {
|
|
8771
9190
|
const result = decodeWorkflowRunsResponse(raw);
|
|
8772
9191
|
return effect.Result.isSuccess(result) ? effect.Result.succeed(result.success.workflow_runs.map(normalizeWorkflowRun)) : effect.Result.fail(result.failure);
|
|
@@ -8974,10 +9393,10 @@ function normalizeGitHubPullRequestRecord(raw) {
|
|
|
8974
9393
|
...raw.statusCheckRollup ? { checkRollup: raw.statusCheckRollup.map((item, index) => normalizeCheckRollupItem(item, index)) } : {}
|
|
8975
9394
|
};
|
|
8976
9395
|
}
|
|
8977
|
-
const decodeGitHubPullRequestList =
|
|
8978
|
-
const decodeGitHubPullRequest =
|
|
9396
|
+
const decodeGitHubPullRequestList = require_collectUint8StreamText.decodeJsonResult(effect.Schema.Array(effect.Schema.Unknown));
|
|
9397
|
+
const decodeGitHubPullRequest = require_collectUint8StreamText.decodeJsonResult(GitHubPullRequestSchema);
|
|
8979
9398
|
const decodeGitHubPullRequestEntry = effect.Schema.decodeUnknownExit(GitHubPullRequestSchema);
|
|
8980
|
-
const formatGitHubJsonDecodeError =
|
|
9399
|
+
const formatGitHubJsonDecodeError = require_collectUint8StreamText.formatSchemaError;
|
|
8981
9400
|
function decodeGitHubPullRequestListJson(raw) {
|
|
8982
9401
|
const result = decodeGitHubPullRequestList(raw);
|
|
8983
9402
|
if (effect.Result.isSuccess(result)) {
|
|
@@ -9296,6 +9715,7 @@ function workflowRunsEndpoint(input) {
|
|
|
9296
9715
|
const params = new URLSearchParams();
|
|
9297
9716
|
params.set("per_page", String(workflowRunLimit(input.limit)));
|
|
9298
9717
|
if (input.headSha?.trim()) params.set("head_sha", input.headSha.trim());
|
|
9718
|
+
else if (input.branch?.trim()) params.set("branch", input.branch.trim());
|
|
9299
9719
|
return `repos/{owner}/{repo}/actions/runs?${params.toString()}`;
|
|
9300
9720
|
}
|
|
9301
9721
|
function isWorkflowRerunStateError(error) {
|
|
@@ -9650,7 +10070,7 @@ const make$13 = effect.Effect.fn("makeGitHubCli")(function* () {
|
|
|
9650
10070
|
...l.description ? { description: l.description } : {}
|
|
9651
10071
|
}))) : effect.Effect.fail(new GitHubCliError({
|
|
9652
10072
|
operation: "listLabels",
|
|
9653
|
-
detail: `Invalid label list output: ${
|
|
10073
|
+
detail: `Invalid label list output: ${require_collectUint8StreamText.formatSchemaError(decoded.failure)}`,
|
|
9654
10074
|
cause: decoded.failure
|
|
9655
10075
|
})))))),
|
|
9656
10076
|
listAssignees: (input) => execute({
|
|
@@ -9670,7 +10090,7 @@ const make$13 = effect.Effect.fn("makeGitHubCli")(function* () {
|
|
|
9670
10090
|
...u.avatar_url ? { avatarUrl: u.avatar_url } : {}
|
|
9671
10091
|
}))) : effect.Effect.fail(new GitHubCliError({
|
|
9672
10092
|
operation: "listAssignees",
|
|
9673
|
-
detail: `Invalid assignees output: ${
|
|
10093
|
+
detail: `Invalid assignees output: ${require_collectUint8StreamText.formatSchemaError(decoded.failure)}`,
|
|
9674
10094
|
cause: decoded.failure
|
|
9675
10095
|
})))))),
|
|
9676
10096
|
listWorkflowRuns: (input) => execute({
|
|
@@ -9779,10 +10199,10 @@ function normalizeGitLabIssueRecord(raw) {
|
|
|
9779
10199
|
labels: raw.labels ?? []
|
|
9780
10200
|
};
|
|
9781
10201
|
}
|
|
9782
|
-
const decodeIssueList =
|
|
9783
|
-
const decodeIssueDetail =
|
|
10202
|
+
const decodeIssueList = require_collectUint8StreamText.decodeJsonResult(effect.Schema.Array(effect.Schema.Unknown));
|
|
10203
|
+
const decodeIssueDetail = require_collectUint8StreamText.decodeJsonResult(GitLabIssueSchema);
|
|
9784
10204
|
const decodeIssueEntry = effect.Schema.decodeUnknownExit(GitLabIssueSchema);
|
|
9785
|
-
const formatGitLabIssueDecodeError =
|
|
10205
|
+
const formatGitLabIssueDecodeError = require_collectUint8StreamText.formatSchemaError;
|
|
9786
10206
|
function decodeGitLabIssueListJson(raw) {
|
|
9787
10207
|
const result = decodeIssueList(raw);
|
|
9788
10208
|
if (!effect.Result.isSuccess(result)) return effect.Result.fail(result.failure);
|
|
@@ -9869,10 +10289,10 @@ function normalizeGitLabMergeRequestRecord(raw) {
|
|
|
9869
10289
|
...headRepositoryOwnerLogin ? { headRepositoryOwnerLogin } : {}
|
|
9870
10290
|
};
|
|
9871
10291
|
}
|
|
9872
|
-
const decodeGitLabMergeRequestList =
|
|
9873
|
-
const decodeGitLabMergeRequest =
|
|
10292
|
+
const decodeGitLabMergeRequestList = require_collectUint8StreamText.decodeJsonResult(effect.Schema.Array(effect.Schema.Unknown));
|
|
10293
|
+
const decodeGitLabMergeRequest = require_collectUint8StreamText.decodeJsonResult(GitLabMergeRequestSchema);
|
|
9874
10294
|
const decodeGitLabMergeRequestEntry = effect.Schema.decodeUnknownExit(GitLabMergeRequestSchema);
|
|
9875
|
-
const formatGitLabJsonDecodeError =
|
|
10295
|
+
const formatGitLabJsonDecodeError = require_collectUint8StreamText.formatSchemaError;
|
|
9876
10296
|
function decodeGitLabMergeRequestListJson(raw) {
|
|
9877
10297
|
const result = decodeGitLabMergeRequestList(raw);
|
|
9878
10298
|
if (effect.Result.isSuccess(result)) {
|
|
@@ -9891,7 +10311,7 @@ function decodeGitLabMergeRequestJson(raw) {
|
|
|
9891
10311
|
if (effect.Result.isSuccess(result)) return effect.Result.succeed(normalizeGitLabMergeRequestRecord(result.success));
|
|
9892
10312
|
return effect.Result.fail(result.failure);
|
|
9893
10313
|
}
|
|
9894
|
-
const decodeGitLabMergeRequestDetail =
|
|
10314
|
+
const decodeGitLabMergeRequestDetail = require_collectUint8StreamText.decodeJsonResult(effect.Schema.Struct({
|
|
9895
10315
|
...GitLabMergeRequestSchema.fields,
|
|
9896
10316
|
description: effect.Schema.optional(effect.Schema.NullOr(effect.Schema.String)),
|
|
9897
10317
|
notes: effect.Schema.optional(effect.Schema.Array(effect.Schema.Struct({
|
|
@@ -10561,26 +10981,26 @@ const make$11 = effect.Effect.fn("makeSourceControlProviderRegistry")(function*
|
|
|
10561
10981
|
const azureDevOpsCli = yield* AzureDevOpsCli;
|
|
10562
10982
|
const fileSystem = yield* effect.FileSystem.FileSystem;
|
|
10563
10983
|
const github = yield* makeLazyProvider("github", effect.Effect.tryPromise({
|
|
10564
|
-
try: () => Promise.resolve().then(() => require("./GitHubSourceControlProvider-
|
|
10984
|
+
try: () => Promise.resolve().then(() => require("./GitHubSourceControlProvider-B1Tp0TbY.cjs")),
|
|
10565
10985
|
catch: (cause) => providerLoadError("github", cause)
|
|
10566
10986
|
}).pipe(effect.Effect.flatMap((module) => module.make()), effect.Effect.provideService(GitHubCli, githubCli), effect.Effect.provideService(effect.FileSystem.FileSystem, fileSystem)));
|
|
10567
10987
|
const gitlab = yield* makeLazyProvider("gitlab", effect.Effect.tryPromise({
|
|
10568
|
-
try: () => Promise.resolve().then(() => require("./GitLabSourceControlProvider-
|
|
10988
|
+
try: () => Promise.resolve().then(() => require("./GitLabSourceControlProvider-D3vvKrB4.cjs")),
|
|
10569
10989
|
catch: (cause) => providerLoadError("gitlab", cause)
|
|
10570
10990
|
}).pipe(effect.Effect.flatMap((module) => module.make()), effect.Effect.provideService(GitLabCli, gitlabCli)));
|
|
10571
10991
|
const bitbucket = yield* makeLazyProvider("bitbucket", effect.Effect.tryPromise({
|
|
10572
|
-
try: () => Promise.resolve().then(() => require("./BitbucketSourceControlProvider-
|
|
10992
|
+
try: () => Promise.resolve().then(() => require("./BitbucketSourceControlProvider-D_7i4YQz.cjs")),
|
|
10573
10993
|
catch: (cause) => providerLoadError("bitbucket", cause)
|
|
10574
10994
|
}).pipe(effect.Effect.flatMap((module) => module.make()), effect.Effect.provideService(BitbucketApi, bitbucketApi)), {
|
|
10575
10995
|
searchRepositories: true,
|
|
10576
10996
|
cloneAuthentication: true
|
|
10577
10997
|
});
|
|
10578
10998
|
const forgejo = yield* makeLazyProvider("forgejo", effect.Effect.tryPromise({
|
|
10579
|
-
try: () => Promise.resolve().then(() => require("./ForgejoSourceControlProvider-
|
|
10999
|
+
try: () => Promise.resolve().then(() => require("./ForgejoSourceControlProvider-DYFUGvBk.cjs")),
|
|
10580
11000
|
catch: (cause) => providerLoadError("forgejo", cause)
|
|
10581
11001
|
}).pipe(effect.Effect.flatMap((module) => module.make()), effect.Effect.provideService(ForgejoApi, forgejoApi)));
|
|
10582
11002
|
const azureDevOps = yield* makeLazyProvider("azure-devops", effect.Effect.tryPromise({
|
|
10583
|
-
try: () => Promise.resolve().then(() => require("./AzureDevOpsSourceControlProvider-
|
|
11003
|
+
try: () => Promise.resolve().then(() => require("./AzureDevOpsSourceControlProvider-CYZmJqSM.cjs")),
|
|
10584
11004
|
catch: (cause) => providerLoadError("azure-devops", cause)
|
|
10585
11005
|
}).pipe(effect.Effect.flatMap((module) => module.make()), effect.Effect.provideService(AzureDevOpsCli, azureDevOpsCli)));
|
|
10586
11006
|
const bitbucketDiscovery = require_SourceControlProviderDiscoveryCatalog.makeBitbucketDiscovery(bitbucketApi);
|
|
@@ -10703,22 +11123,6 @@ var CheckpointDiffQuery = class extends effect.Context.Service()("ryco/checkpoin
|
|
|
10703
11123
|
//#region src/diagnostics/Services/Diagnostics.ts
|
|
10704
11124
|
var Diagnostics = class extends effect.Context.Service()("ryco/diagnostics/Services/Diagnostics") {};
|
|
10705
11125
|
//#endregion
|
|
10706
|
-
//#region src/atomicWrite.ts
|
|
10707
|
-
const writeFileStringAtomically = (input) => effect.Effect.scoped(effect.Effect.gen(function* () {
|
|
10708
|
-
const fs = yield* effect.FileSystem.FileSystem;
|
|
10709
|
-
const path = yield* effect.Path.Path;
|
|
10710
|
-
const tempFileId = yield* effect_Random.nextUUIDv4;
|
|
10711
|
-
const targetDirectory = path.dirname(input.filePath);
|
|
10712
|
-
yield* fs.makeDirectory(targetDirectory, { recursive: true });
|
|
10713
|
-
const tempDirectory = yield* fs.makeTempDirectoryScoped({
|
|
10714
|
-
directory: targetDirectory,
|
|
10715
|
-
prefix: `${path.basename(input.filePath)}.`
|
|
10716
|
-
});
|
|
10717
|
-
const tempPath = path.join(tempDirectory, `${tempFileId}.tmp`);
|
|
10718
|
-
yield* fs.writeFileString(tempPath, input.contents);
|
|
10719
|
-
yield* fs.rename(tempPath, input.filePath);
|
|
10720
|
-
}));
|
|
10721
|
-
//#endregion
|
|
10722
11126
|
//#region ../../packages/shared/src/keybindings.ts
|
|
10723
11127
|
const DEFAULT_KEYBINDINGS = [
|
|
10724
11128
|
{
|
|
@@ -10789,6 +11193,11 @@ const DEFAULT_KEYBINDINGS = [
|
|
|
10789
11193
|
key: "mod+o",
|
|
10790
11194
|
command: "editor.openFavorite"
|
|
10791
11195
|
},
|
|
11196
|
+
{
|
|
11197
|
+
key: "mod+f",
|
|
11198
|
+
command: "thread.find",
|
|
11199
|
+
when: "!terminalFocus"
|
|
11200
|
+
},
|
|
10792
11201
|
{
|
|
10793
11202
|
key: "mod+shift+[",
|
|
10794
11203
|
command: "thread.previous"
|
|
@@ -11069,7 +11478,7 @@ function encodeWhenAst(node) {
|
|
|
11069
11478
|
case "or": return `(${encodeWhenAst(node.left)} || ${encodeWhenAst(node.right)})`;
|
|
11070
11479
|
}
|
|
11071
11480
|
}
|
|
11072
|
-
const RawKeybindingsEntries =
|
|
11481
|
+
const RawKeybindingsEntries = require_collectUint8StreamText.fromLenientJson(effect.Schema.Array(effect.Schema.Unknown));
|
|
11073
11482
|
const KeybindingsConfigJson = effect.Schema.fromJsonString(require_collectUint8StreamText.KeybindingsConfig);
|
|
11074
11483
|
const PrettyJsonString = effect.SchemaGetter.parseJson().compose(effect.SchemaGetter.stringifyJson({ space: 2 }));
|
|
11075
11484
|
const KeybindingsConfigPrettyJson = KeybindingsConfigJson.pipe(effect.Schema.encode({
|
|
@@ -11610,14 +12019,7 @@ const ClientRequest__PluginsMigration = effect_Schema.Struct({
|
|
|
11610
12019
|
marketplaceName: effect_Schema.String,
|
|
11611
12020
|
pluginNames: effect_Schema.Array(effect_Schema.String)
|
|
11612
12021
|
});
|
|
11613
|
-
const ClientRequest__ReasoningEffort = effect_Schema.
|
|
11614
|
-
"none",
|
|
11615
|
-
"minimal",
|
|
11616
|
-
"low",
|
|
11617
|
-
"medium",
|
|
11618
|
-
"high",
|
|
11619
|
-
"xhigh"
|
|
11620
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
12022
|
+
const ClientRequest__ReasoningEffort = effect_Schema.String.check(effect_Schema.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
11621
12023
|
const ClientRequest__ReasoningItemContent = effect_Schema.Union([effect_Schema.Struct({
|
|
11622
12024
|
text: effect_Schema.String,
|
|
11623
12025
|
type: effect_Schema.Literal("reasoning_text").annotate({ title: "ReasoningTextReasoningItemContentType" })
|
|
@@ -12193,14 +12595,7 @@ const ServerNotification__RateLimitWindow = effect_Schema.Struct({
|
|
|
12193
12595
|
windowDurationMins: effect_Schema.optionalKey(effect_Schema.Union([effect_Schema.Number.annotate({ format: "int64" }).check(effect_Schema.isInt()), effect_Schema.Null]))
|
|
12194
12596
|
});
|
|
12195
12597
|
const ServerNotification__RealtimeConversationVersion = effect_Schema.Literals(["v1", "v2"]);
|
|
12196
|
-
const ServerNotification__ReasoningEffort = effect_Schema.
|
|
12197
|
-
"none",
|
|
12198
|
-
"minimal",
|
|
12199
|
-
"low",
|
|
12200
|
-
"medium",
|
|
12201
|
-
"high",
|
|
12202
|
-
"xhigh"
|
|
12203
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
12598
|
+
const ServerNotification__ReasoningEffort = effect_Schema.String.check(effect_Schema.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
12204
12599
|
const ServerNotification__ReasoningSummaryPartAddedNotification = effect_Schema.Struct({
|
|
12205
12600
|
itemId: effect_Schema.String,
|
|
12206
12601
|
summaryIndex: effect_Schema.Number.annotate({ format: "int64" }).check(effect_Schema.isInt()),
|
|
@@ -12579,14 +12974,7 @@ const V2ConfigReadResponse__AskForApproval = effect_Schema.Union([effect_Schema.
|
|
|
12579
12974
|
skill_approval: effect_Schema.optionalKey(effect_Schema.Boolean.annotate({ default: false }))
|
|
12580
12975
|
}) }).annotate({ title: "GranularAskForApproval" })], { mode: "oneOf" });
|
|
12581
12976
|
const V2ConfigReadResponse__ForcedLoginMethod = effect_Schema.Literals(["chatgpt", "api"]);
|
|
12582
|
-
const V2ConfigReadResponse__ReasoningEffort = effect_Schema.
|
|
12583
|
-
"none",
|
|
12584
|
-
"minimal",
|
|
12585
|
-
"low",
|
|
12586
|
-
"medium",
|
|
12587
|
-
"high",
|
|
12588
|
-
"xhigh"
|
|
12589
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
12977
|
+
const V2ConfigReadResponse__ReasoningEffort = effect_Schema.String.check(effect_Schema.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
12590
12978
|
const V2ConfigReadResponse__ReasoningSummary = effect_Schema.Union([effect_Schema.Literals([
|
|
12591
12979
|
"auto",
|
|
12592
12980
|
"concise",
|
|
@@ -12904,14 +13292,7 @@ const V2ItemCompletedNotification__PatchChangeKind = effect_Schema.Union([
|
|
|
12904
13292
|
type: effect_Schema.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
12905
13293
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
12906
13294
|
], { mode: "oneOf" });
|
|
12907
|
-
const V2ItemCompletedNotification__ReasoningEffort = effect_Schema.
|
|
12908
|
-
"none",
|
|
12909
|
-
"minimal",
|
|
12910
|
-
"low",
|
|
12911
|
-
"medium",
|
|
12912
|
-
"high",
|
|
12913
|
-
"xhigh"
|
|
12914
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
13295
|
+
const V2ItemCompletedNotification__ReasoningEffort = effect_Schema.String.check(effect_Schema.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
12915
13296
|
const V2ItemCompletedNotification__TextElement = effect_Schema.Struct({
|
|
12916
13297
|
byteRange: effect_Schema.Struct({
|
|
12917
13298
|
end: effect_Schema.Number.annotate({ format: "uint" }).check(effect_Schema.isInt()).check(effect_Schema.isGreaterThanOrEqualTo(0)),
|
|
@@ -13099,14 +13480,7 @@ const V2ItemStartedNotification__PatchChangeKind = effect_Schema.Union([
|
|
|
13099
13480
|
type: effect_Schema.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
13100
13481
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
13101
13482
|
], { mode: "oneOf" });
|
|
13102
|
-
const V2ItemStartedNotification__ReasoningEffort = effect_Schema.
|
|
13103
|
-
"none",
|
|
13104
|
-
"minimal",
|
|
13105
|
-
"low",
|
|
13106
|
-
"medium",
|
|
13107
|
-
"high",
|
|
13108
|
-
"xhigh"
|
|
13109
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
13483
|
+
const V2ItemStartedNotification__ReasoningEffort = effect_Schema.String.check(effect_Schema.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
13110
13484
|
const V2ItemStartedNotification__TextElement = effect_Schema.Struct({
|
|
13111
13485
|
byteRange: effect_Schema.Struct({
|
|
13112
13486
|
end: effect_Schema.Number.annotate({ format: "uint" }).check(effect_Schema.isInt()).check(effect_Schema.isGreaterThanOrEqualTo(0)),
|
|
@@ -13194,14 +13568,7 @@ const V2ModelListResponse__ModelUpgradeInfo = effect_Schema.Struct({
|
|
|
13194
13568
|
modelLink: effect_Schema.optionalKey(effect_Schema.Union([effect_Schema.String, effect_Schema.Null])),
|
|
13195
13569
|
upgradeCopy: effect_Schema.optionalKey(effect_Schema.Union([effect_Schema.String, effect_Schema.Null]))
|
|
13196
13570
|
});
|
|
13197
|
-
const V2ModelListResponse__ReasoningEffort = effect_Schema.
|
|
13198
|
-
"none",
|
|
13199
|
-
"minimal",
|
|
13200
|
-
"low",
|
|
13201
|
-
"medium",
|
|
13202
|
-
"high",
|
|
13203
|
-
"xhigh"
|
|
13204
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
13571
|
+
const V2ModelListResponse__ReasoningEffort = effect_Schema.String.check(effect_Schema.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
13205
13572
|
const V2ModelReroutedNotification__ModelRerouteReason = effect_Schema.Literal("highRiskCyberActivity");
|
|
13206
13573
|
const V2PluginInstallParams__AbsolutePathBuf = effect_Schema.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." });
|
|
13207
13574
|
const V2PluginInstallResponse__AppSummary = effect_Schema.Struct({
|
|
@@ -13384,14 +13751,7 @@ const V2ReviewStartResponse__PatchChangeKind = effect_Schema.Union([
|
|
|
13384
13751
|
type: effect_Schema.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
13385
13752
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
13386
13753
|
], { mode: "oneOf" });
|
|
13387
|
-
const V2ReviewStartResponse__ReasoningEffort = effect_Schema.
|
|
13388
|
-
"none",
|
|
13389
|
-
"minimal",
|
|
13390
|
-
"low",
|
|
13391
|
-
"medium",
|
|
13392
|
-
"high",
|
|
13393
|
-
"xhigh"
|
|
13394
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
13754
|
+
const V2ReviewStartResponse__ReasoningEffort = effect_Schema.String.check(effect_Schema.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
13395
13755
|
const V2ReviewStartResponse__TextElement = effect_Schema.Struct({
|
|
13396
13756
|
byteRange: effect_Schema.Struct({
|
|
13397
13757
|
end: effect_Schema.Number.annotate({ format: "uint" }).check(effect_Schema.isInt()).check(effect_Schema.isGreaterThanOrEqualTo(0)),
|
|
@@ -13555,14 +13915,7 @@ const V2ThreadForkResponse__PatchChangeKind = effect_Schema.Union([
|
|
|
13555
13915
|
type: effect_Schema.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
13556
13916
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
13557
13917
|
], { mode: "oneOf" });
|
|
13558
|
-
const V2ThreadForkResponse__ReasoningEffort = effect_Schema.
|
|
13559
|
-
"none",
|
|
13560
|
-
"minimal",
|
|
13561
|
-
"low",
|
|
13562
|
-
"medium",
|
|
13563
|
-
"high",
|
|
13564
|
-
"xhigh"
|
|
13565
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
13918
|
+
const V2ThreadForkResponse__ReasoningEffort = effect_Schema.String.check(effect_Schema.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
13566
13919
|
const V2ThreadForkResponse__ServiceTier = effect_Schema.Literals([
|
|
13567
13920
|
"fast",
|
|
13568
13921
|
"flex",
|
|
@@ -13685,14 +14038,7 @@ const V2ThreadListResponse__PatchChangeKind = effect_Schema.Union([
|
|
|
13685
14038
|
type: effect_Schema.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
13686
14039
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
13687
14040
|
], { mode: "oneOf" });
|
|
13688
|
-
const V2ThreadListResponse__ReasoningEffort = effect_Schema.
|
|
13689
|
-
"none",
|
|
13690
|
-
"minimal",
|
|
13691
|
-
"low",
|
|
13692
|
-
"medium",
|
|
13693
|
-
"high",
|
|
13694
|
-
"xhigh"
|
|
13695
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
14041
|
+
const V2ThreadListResponse__ReasoningEffort = effect_Schema.String.check(effect_Schema.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
13696
14042
|
const V2ThreadListResponse__TextElement = effect_Schema.Struct({
|
|
13697
14043
|
byteRange: effect_Schema.Struct({
|
|
13698
14044
|
end: effect_Schema.Number.annotate({ format: "uint" }).check(effect_Schema.isInt()).check(effect_Schema.isGreaterThanOrEqualTo(0)),
|
|
@@ -13801,14 +14147,7 @@ const V2ThreadMetadataUpdateResponse__PatchChangeKind = effect_Schema.Union([
|
|
|
13801
14147
|
type: effect_Schema.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
13802
14148
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
13803
14149
|
], { mode: "oneOf" });
|
|
13804
|
-
const V2ThreadMetadataUpdateResponse__ReasoningEffort = effect_Schema.
|
|
13805
|
-
"none",
|
|
13806
|
-
"minimal",
|
|
13807
|
-
"low",
|
|
13808
|
-
"medium",
|
|
13809
|
-
"high",
|
|
13810
|
-
"xhigh"
|
|
13811
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
14150
|
+
const V2ThreadMetadataUpdateResponse__ReasoningEffort = effect_Schema.String.check(effect_Schema.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
13812
14151
|
const V2ThreadMetadataUpdateResponse__TextElement = effect_Schema.Struct({
|
|
13813
14152
|
byteRange: effect_Schema.Struct({
|
|
13814
14153
|
end: effect_Schema.Number.annotate({ format: "uint" }).check(effect_Schema.isInt()).check(effect_Schema.isGreaterThanOrEqualTo(0)),
|
|
@@ -13912,14 +14251,7 @@ const V2ThreadReadResponse__PatchChangeKind = effect_Schema.Union([
|
|
|
13912
14251
|
type: effect_Schema.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
13913
14252
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
13914
14253
|
], { mode: "oneOf" });
|
|
13915
|
-
const V2ThreadReadResponse__ReasoningEffort = effect_Schema.
|
|
13916
|
-
"none",
|
|
13917
|
-
"minimal",
|
|
13918
|
-
"low",
|
|
13919
|
-
"medium",
|
|
13920
|
-
"high",
|
|
13921
|
-
"xhigh"
|
|
13922
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
14254
|
+
const V2ThreadReadResponse__ReasoningEffort = effect_Schema.String.check(effect_Schema.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
13923
14255
|
const V2ThreadReadResponse__TextElement = effect_Schema.Struct({
|
|
13924
14256
|
byteRange: effect_Schema.Struct({
|
|
13925
14257
|
end: effect_Schema.Number.annotate({ format: "uint" }).check(effect_Schema.isInt()).check(effect_Schema.isGreaterThanOrEqualTo(0)),
|
|
@@ -14125,14 +14457,7 @@ const V2ThreadResumeResponse__PatchChangeKind = effect_Schema.Union([
|
|
|
14125
14457
|
type: effect_Schema.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
14126
14458
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
14127
14459
|
], { mode: "oneOf" });
|
|
14128
|
-
const V2ThreadResumeResponse__ReasoningEffort = effect_Schema.
|
|
14129
|
-
"none",
|
|
14130
|
-
"minimal",
|
|
14131
|
-
"low",
|
|
14132
|
-
"medium",
|
|
14133
|
-
"high",
|
|
14134
|
-
"xhigh"
|
|
14135
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
14460
|
+
const V2ThreadResumeResponse__ReasoningEffort = effect_Schema.String.check(effect_Schema.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
14136
14461
|
const V2ThreadResumeResponse__ServiceTier = effect_Schema.Literals([
|
|
14137
14462
|
"fast",
|
|
14138
14463
|
"flex",
|
|
@@ -14241,14 +14566,7 @@ const V2ThreadRollbackResponse__PatchChangeKind = effect_Schema.Union([
|
|
|
14241
14566
|
type: effect_Schema.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
14242
14567
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
14243
14568
|
], { mode: "oneOf" });
|
|
14244
|
-
const V2ThreadRollbackResponse__ReasoningEffort = effect_Schema.
|
|
14245
|
-
"none",
|
|
14246
|
-
"minimal",
|
|
14247
|
-
"low",
|
|
14248
|
-
"medium",
|
|
14249
|
-
"high",
|
|
14250
|
-
"xhigh"
|
|
14251
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
14569
|
+
const V2ThreadRollbackResponse__ReasoningEffort = effect_Schema.String.check(effect_Schema.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
14252
14570
|
const V2ThreadRollbackResponse__TextElement = effect_Schema.Struct({
|
|
14253
14571
|
byteRange: effect_Schema.Struct({
|
|
14254
14572
|
end: effect_Schema.Number.annotate({ format: "uint" }).check(effect_Schema.isInt()).check(effect_Schema.isGreaterThanOrEqualTo(0)),
|
|
@@ -14352,14 +14670,7 @@ const V2ThreadStartedNotification__PatchChangeKind = effect_Schema.Union([
|
|
|
14352
14670
|
type: effect_Schema.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
14353
14671
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
14354
14672
|
], { mode: "oneOf" });
|
|
14355
|
-
const V2ThreadStartedNotification__ReasoningEffort = effect_Schema.
|
|
14356
|
-
"none",
|
|
14357
|
-
"minimal",
|
|
14358
|
-
"low",
|
|
14359
|
-
"medium",
|
|
14360
|
-
"high",
|
|
14361
|
-
"xhigh"
|
|
14362
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
14673
|
+
const V2ThreadStartedNotification__ReasoningEffort = effect_Schema.String.check(effect_Schema.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
14363
14674
|
const V2ThreadStartedNotification__TextElement = effect_Schema.Struct({
|
|
14364
14675
|
byteRange: effect_Schema.Struct({
|
|
14365
14676
|
end: effect_Schema.Number.annotate({ format: "uint" }).check(effect_Schema.isInt()).check(effect_Schema.isGreaterThanOrEqualTo(0)),
|
|
@@ -14504,14 +14815,7 @@ const V2ThreadStartResponse__PatchChangeKind = effect_Schema.Union([
|
|
|
14504
14815
|
type: effect_Schema.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
14505
14816
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
14506
14817
|
], { mode: "oneOf" });
|
|
14507
|
-
const V2ThreadStartResponse__ReasoningEffort = effect_Schema.
|
|
14508
|
-
"none",
|
|
14509
|
-
"minimal",
|
|
14510
|
-
"low",
|
|
14511
|
-
"medium",
|
|
14512
|
-
"high",
|
|
14513
|
-
"xhigh"
|
|
14514
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
14818
|
+
const V2ThreadStartResponse__ReasoningEffort = effect_Schema.String.check(effect_Schema.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
14515
14819
|
const V2ThreadStartResponse__ServiceTier = effect_Schema.Literals([
|
|
14516
14820
|
"fast",
|
|
14517
14821
|
"flex",
|
|
@@ -14623,14 +14927,7 @@ const V2ThreadTurnsListResponse__PatchChangeKind = effect_Schema.Union([
|
|
|
14623
14927
|
type: effect_Schema.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
14624
14928
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
14625
14929
|
], { mode: "oneOf" });
|
|
14626
|
-
const V2ThreadTurnsListResponse__ReasoningEffort = effect_Schema.
|
|
14627
|
-
"none",
|
|
14628
|
-
"minimal",
|
|
14629
|
-
"low",
|
|
14630
|
-
"medium",
|
|
14631
|
-
"high",
|
|
14632
|
-
"xhigh"
|
|
14633
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
14930
|
+
const V2ThreadTurnsListResponse__ReasoningEffort = effect_Schema.String.check(effect_Schema.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
14634
14931
|
const V2ThreadTurnsListResponse__TextElement = effect_Schema.Struct({
|
|
14635
14932
|
byteRange: effect_Schema.Struct({
|
|
14636
14933
|
end: effect_Schema.Number.annotate({ format: "uint" }).check(effect_Schema.isInt()).check(effect_Schema.isGreaterThanOrEqualTo(0)),
|
|
@@ -14732,14 +15029,7 @@ const V2ThreadUnarchiveResponse__PatchChangeKind = effect_Schema.Union([
|
|
|
14732
15029
|
type: effect_Schema.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
14733
15030
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
14734
15031
|
], { mode: "oneOf" });
|
|
14735
|
-
const V2ThreadUnarchiveResponse__ReasoningEffort = effect_Schema.
|
|
14736
|
-
"none",
|
|
14737
|
-
"minimal",
|
|
14738
|
-
"low",
|
|
14739
|
-
"medium",
|
|
14740
|
-
"high",
|
|
14741
|
-
"xhigh"
|
|
14742
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
15032
|
+
const V2ThreadUnarchiveResponse__ReasoningEffort = effect_Schema.String.check(effect_Schema.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
14743
15033
|
const V2ThreadUnarchiveResponse__TextElement = effect_Schema.Struct({
|
|
14744
15034
|
byteRange: effect_Schema.Struct({
|
|
14745
15035
|
end: effect_Schema.Number.annotate({ format: "uint" }).check(effect_Schema.isInt()).check(effect_Schema.isGreaterThanOrEqualTo(0)),
|
|
@@ -14842,14 +15132,7 @@ const V2TurnCompletedNotification__PatchChangeKind = effect_Schema.Union([
|
|
|
14842
15132
|
type: effect_Schema.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
14843
15133
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
14844
15134
|
], { mode: "oneOf" });
|
|
14845
|
-
const V2TurnCompletedNotification__ReasoningEffort = effect_Schema.
|
|
14846
|
-
"none",
|
|
14847
|
-
"minimal",
|
|
14848
|
-
"low",
|
|
14849
|
-
"medium",
|
|
14850
|
-
"high",
|
|
14851
|
-
"xhigh"
|
|
14852
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
15135
|
+
const V2TurnCompletedNotification__ReasoningEffort = effect_Schema.String.check(effect_Schema.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
14853
15136
|
const V2TurnCompletedNotification__TextElement = effect_Schema.Struct({
|
|
14854
15137
|
byteRange: effect_Schema.Struct({
|
|
14855
15138
|
end: effect_Schema.Number.annotate({ format: "uint" }).check(effect_Schema.isInt()).check(effect_Schema.isGreaterThanOrEqualTo(0)),
|
|
@@ -14950,14 +15233,7 @@ const V2TurnStartedNotification__PatchChangeKind = effect_Schema.Union([
|
|
|
14950
15233
|
type: effect_Schema.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
14951
15234
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
14952
15235
|
], { mode: "oneOf" });
|
|
14953
|
-
const V2TurnStartedNotification__ReasoningEffort = effect_Schema.
|
|
14954
|
-
"none",
|
|
14955
|
-
"minimal",
|
|
14956
|
-
"low",
|
|
14957
|
-
"medium",
|
|
14958
|
-
"high",
|
|
14959
|
-
"xhigh"
|
|
14960
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
15236
|
+
const V2TurnStartedNotification__ReasoningEffort = effect_Schema.String.check(effect_Schema.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
14961
15237
|
const V2TurnStartedNotification__TextElement = effect_Schema.Struct({
|
|
14962
15238
|
byteRange: effect_Schema.Struct({
|
|
14963
15239
|
end: effect_Schema.Number.annotate({ format: "uint" }).check(effect_Schema.isInt()).check(effect_Schema.isGreaterThanOrEqualTo(0)),
|
|
@@ -15008,14 +15284,7 @@ const V2TurnStartParams__Personality = effect_Schema.Literals([
|
|
|
15008
15284
|
"friendly",
|
|
15009
15285
|
"pragmatic"
|
|
15010
15286
|
]);
|
|
15011
|
-
const V2TurnStartParams__ReasoningEffort = effect_Schema.
|
|
15012
|
-
"none",
|
|
15013
|
-
"minimal",
|
|
15014
|
-
"low",
|
|
15015
|
-
"medium",
|
|
15016
|
-
"high",
|
|
15017
|
-
"xhigh"
|
|
15018
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
15287
|
+
const V2TurnStartParams__ReasoningEffort = effect_Schema.String.check(effect_Schema.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
15019
15288
|
const V2TurnStartParams__ReasoningSummary = effect_Schema.Union([effect_Schema.Literals([
|
|
15020
15289
|
"auto",
|
|
15021
15290
|
"concise",
|
|
@@ -15098,14 +15367,7 @@ const V2TurnStartResponse__PatchChangeKind = effect_Schema.Union([
|
|
|
15098
15367
|
type: effect_Schema.Literal("update").annotate({ title: "UpdatePatchChangeKindType" })
|
|
15099
15368
|
}).annotate({ title: "UpdatePatchChangeKind" })
|
|
15100
15369
|
], { mode: "oneOf" });
|
|
15101
|
-
const V2TurnStartResponse__ReasoningEffort = effect_Schema.
|
|
15102
|
-
"none",
|
|
15103
|
-
"minimal",
|
|
15104
|
-
"low",
|
|
15105
|
-
"medium",
|
|
15106
|
-
"high",
|
|
15107
|
-
"xhigh"
|
|
15108
|
-
]).annotate({ description: "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" });
|
|
15370
|
+
const V2TurnStartResponse__ReasoningEffort = effect_Schema.String.check(effect_Schema.isNonEmpty()).annotate({ description: "A non-empty reasoning effort value advertised by the model." });
|
|
15109
15371
|
const V2TurnStartResponse__TextElement = effect_Schema.Struct({
|
|
15110
15372
|
byteRange: effect_Schema.Struct({
|
|
15111
15373
|
end: effect_Schema.Number.annotate({ format: "uint" }).check(effect_Schema.isInt()).check(effect_Schema.isGreaterThanOrEqualTo(0)),
|
|
@@ -26104,300 +26366,6 @@ async function runProcess(command, args, options = {}) {
|
|
|
26104
26366
|
});
|
|
26105
26367
|
}
|
|
26106
26368
|
//#endregion
|
|
26107
|
-
//#region src/serverSettings.ts
|
|
26108
|
-
/**
|
|
26109
|
-
* ServerSettings - Server-authoritative settings service.
|
|
26110
|
-
*
|
|
26111
|
-
* Owns persistence, validation, and change notification of settings that affect
|
|
26112
|
-
* server-side behavior (binary paths, streaming mode, env mode, custom models,
|
|
26113
|
-
* text generation model selection).
|
|
26114
|
-
*
|
|
26115
|
-
* Follows the same pattern as `keybindings.ts`: JSON file + Cache + PubSub +
|
|
26116
|
-
* Semaphore + FileSystem.watch for concurrency and external edit detection.
|
|
26117
|
-
*
|
|
26118
|
-
* @module ServerSettings
|
|
26119
|
-
*/
|
|
26120
|
-
const textEncoder$1 = new TextEncoder();
|
|
26121
|
-
const textDecoder$1 = new TextDecoder();
|
|
26122
|
-
function providerEnvironmentSecretName(input) {
|
|
26123
|
-
return `provider-env-${Buffer.from(input.instanceId, "utf8").toString("base64url")}-${Buffer.from(input.name, "utf8").toString("base64url")}`;
|
|
26124
|
-
}
|
|
26125
|
-
function redactProviderEnvironmentVariable(variable) {
|
|
26126
|
-
if (!variable.sensitive) {
|
|
26127
|
-
const { valueRedacted: _omit, ...rest } = variable;
|
|
26128
|
-
return rest;
|
|
26129
|
-
}
|
|
26130
|
-
return {
|
|
26131
|
-
...variable,
|
|
26132
|
-
value: "",
|
|
26133
|
-
...variable.value.length > 0 || variable.valueRedacted ? { valueRedacted: true } : {}
|
|
26134
|
-
};
|
|
26135
|
-
}
|
|
26136
|
-
function redactServerSettingsForClient(settings) {
|
|
26137
|
-
const providerInstances = Object.fromEntries(Object.entries(settings.providerInstances).map(([instanceId, instance]) => [instanceId, instance.environment ? {
|
|
26138
|
-
...instance,
|
|
26139
|
-
environment: instance.environment.map(redactProviderEnvironmentVariable)
|
|
26140
|
-
} : instance]));
|
|
26141
|
-
return {
|
|
26142
|
-
...settings,
|
|
26143
|
-
providerInstances
|
|
26144
|
-
};
|
|
26145
|
-
}
|
|
26146
|
-
var ServerSettingsService = class ServerSettingsService extends effect.Context.Service()("ryco/serverSettings/ServerSettingsService") {
|
|
26147
|
-
static layerTest = (overrides = {}) => effect.Layer.effect(ServerSettingsService, effect.Effect.gen(function* () {
|
|
26148
|
-
const currentSettingsRef = yield* effect.Ref.make(deepMerge(require_collectUint8StreamText.DEFAULT_SERVER_SETTINGS, overrides));
|
|
26149
|
-
return {
|
|
26150
|
-
start: effect.Effect.void,
|
|
26151
|
-
ready: effect.Effect.void,
|
|
26152
|
-
getSettings: effect.Ref.get(currentSettingsRef),
|
|
26153
|
-
updateSettings: (patch) => effect.Ref.get(currentSettingsRef).pipe(effect.Effect.flatMap((currentSettings) => effect.Schema.decodeEffect(require_collectUint8StreamText.ServerSettings)(applyServerSettingsPatch(currentSettings, patch)).pipe(effect.Effect.mapError((cause) => new require_collectUint8StreamText.ServerSettingsError({
|
|
26154
|
-
settingsPath: "<memory>",
|
|
26155
|
-
detail: `failed to normalize server settings: ${effect.SchemaIssue.makeFormatterDefault()(cause.issue)}`,
|
|
26156
|
-
cause
|
|
26157
|
-
})))), effect.Effect.tap((nextSettings) => effect.Ref.set(currentSettingsRef, nextSettings))),
|
|
26158
|
-
streamChanges: effect.Stream.empty
|
|
26159
|
-
};
|
|
26160
|
-
}));
|
|
26161
|
-
};
|
|
26162
|
-
const ServerSettingsJson = require_SourceControlProviderDiscoveryCatalog.fromLenientJson(require_collectUint8StreamText.ServerSettings);
|
|
26163
|
-
const getLegacyProviderSettings = (settings, provider) => settings.providers[provider];
|
|
26164
|
-
/**
|
|
26165
|
-
* Ensure the `textGenerationModelSelection` points to an enabled provider.
|
|
26166
|
-
* If the selected provider is disabled, fall back to the first enabled
|
|
26167
|
-
* provider with its default model. This is applied at read-time so the
|
|
26168
|
-
* persisted preference is preserved for when a provider is re-enabled.
|
|
26169
|
-
*/
|
|
26170
|
-
function resolveTextGenerationProvider(settings) {
|
|
26171
|
-
const selection = settings.textGenerationModelSelection;
|
|
26172
|
-
const instanceConfig = settings.providerInstances[selection.instanceId];
|
|
26173
|
-
if (instanceConfig !== void 0) return instanceConfig.enabled ?? true ? settings : fallbackTextGenerationProvider(settings);
|
|
26174
|
-
if (require_collectUint8StreamText.isProviderDriverKind(selection.instanceId) && getLegacyProviderSettings(settings, selection.instanceId)?.enabled) return settings;
|
|
26175
|
-
return fallbackTextGenerationProvider(settings);
|
|
26176
|
-
}
|
|
26177
|
-
function fallbackTextGenerationProvider(settings) {
|
|
26178
|
-
const fallbackEntry = Object.entries(settings.providers).find(([, provider]) => provider.enabled);
|
|
26179
|
-
const fallback = fallbackEntry ? require_collectUint8StreamText.ProviderDriverKind.make(fallbackEntry[0]) : void 0;
|
|
26180
|
-
if (!fallback) return settings;
|
|
26181
|
-
return {
|
|
26182
|
-
...settings,
|
|
26183
|
-
textGenerationModelSelection: {
|
|
26184
|
-
instanceId: require_collectUint8StreamText.ProviderInstanceId.make(fallback),
|
|
26185
|
-
model: require_collectUint8StreamText.DEFAULT_GIT_TEXT_GENERATION_MODEL_BY_PROVIDER[fallback] ?? "gpt-5.4-mini"
|
|
26186
|
-
}
|
|
26187
|
-
};
|
|
26188
|
-
}
|
|
26189
|
-
const ATOMIC_SETTINGS_KEYS = new Set(["textGenerationModelSelection"]);
|
|
26190
|
-
function stripDefaultServerSettings(current, defaults) {
|
|
26191
|
-
if (Array.isArray(current) || Array.isArray(defaults)) return effect.Equal.equals(current, defaults) ? void 0 : current;
|
|
26192
|
-
if (current !== null && defaults !== null && typeof current === "object" && typeof defaults === "object") {
|
|
26193
|
-
const currentRecord = current;
|
|
26194
|
-
const defaultsRecord = defaults;
|
|
26195
|
-
const next = {};
|
|
26196
|
-
for (const key of Object.keys(currentRecord)) if (ATOMIC_SETTINGS_KEYS.has(key)) {
|
|
26197
|
-
if (!effect.Equal.equals(currentRecord[key], defaultsRecord[key])) next[key] = currentRecord[key];
|
|
26198
|
-
} else {
|
|
26199
|
-
const stripped = stripDefaultServerSettings(currentRecord[key], defaultsRecord[key]);
|
|
26200
|
-
if (stripped !== void 0) next[key] = stripped;
|
|
26201
|
-
}
|
|
26202
|
-
return Object.keys(next).length > 0 ? next : void 0;
|
|
26203
|
-
}
|
|
26204
|
-
return Object.is(current, defaults) ? void 0 : current;
|
|
26205
|
-
}
|
|
26206
|
-
const makeServerSettings = effect.Effect.gen(function* () {
|
|
26207
|
-
const { settingsPath } = yield* require_Metrics.ServerConfig;
|
|
26208
|
-
const fs = yield* effect.FileSystem.FileSystem;
|
|
26209
|
-
const pathService = yield* effect.Path.Path;
|
|
26210
|
-
const secretStore = yield* ServerSecretStore;
|
|
26211
|
-
const writeSemaphore = yield* effect_Semaphore.make(1);
|
|
26212
|
-
const cacheKey = "settings";
|
|
26213
|
-
const changesPubSub = yield* effect.PubSub.unbounded();
|
|
26214
|
-
const startedRef = yield* effect.Ref.make(false);
|
|
26215
|
-
const startedDeferred = yield* effect.Deferred.make();
|
|
26216
|
-
const watcherScope = yield* effect.Scope.make("sequential");
|
|
26217
|
-
yield* effect.Effect.addFinalizer(() => effect.Scope.close(watcherScope, effect.Exit.void));
|
|
26218
|
-
const emitChange = (settings) => effect.PubSub.publish(changesPubSub, settings).pipe(effect.Effect.asVoid);
|
|
26219
|
-
const readConfigExists = fs.exists(settingsPath).pipe(effect.Effect.mapError((cause) => new require_collectUint8StreamText.ServerSettingsError({
|
|
26220
|
-
settingsPath,
|
|
26221
|
-
detail: "failed to check settings file existence",
|
|
26222
|
-
cause
|
|
26223
|
-
})));
|
|
26224
|
-
const readRawConfig = fs.readFileString(settingsPath).pipe(effect.Effect.mapError((cause) => new require_collectUint8StreamText.ServerSettingsError({
|
|
26225
|
-
settingsPath,
|
|
26226
|
-
detail: "failed to read settings file",
|
|
26227
|
-
cause
|
|
26228
|
-
})));
|
|
26229
|
-
const loadSettingsFromDisk = effect.Effect.gen(function* () {
|
|
26230
|
-
if (!(yield* readConfigExists)) return require_collectUint8StreamText.DEFAULT_SERVER_SETTINGS;
|
|
26231
|
-
const raw = yield* readRawConfig;
|
|
26232
|
-
const decoded = effect.Schema.decodeUnknownExit(ServerSettingsJson)(raw);
|
|
26233
|
-
if (decoded._tag === "Failure") {
|
|
26234
|
-
yield* effect.Effect.logWarning("failed to parse settings.json, using defaults", {
|
|
26235
|
-
path: settingsPath,
|
|
26236
|
-
issues: effect.Cause.pretty(decoded.cause)
|
|
26237
|
-
});
|
|
26238
|
-
return require_collectUint8StreamText.DEFAULT_SERVER_SETTINGS;
|
|
26239
|
-
}
|
|
26240
|
-
return decoded.value;
|
|
26241
|
-
});
|
|
26242
|
-
const settingsCache = yield* effect.Cache.make({
|
|
26243
|
-
capacity: 1,
|
|
26244
|
-
lookup: () => loadSettingsFromDisk
|
|
26245
|
-
});
|
|
26246
|
-
const getSettingsFromCache = effect.Cache.get(settingsCache, cacheKey);
|
|
26247
|
-
const toSettingsError = (detail, cause) => new require_collectUint8StreamText.ServerSettingsError({
|
|
26248
|
-
settingsPath,
|
|
26249
|
-
detail,
|
|
26250
|
-
cause
|
|
26251
|
-
});
|
|
26252
|
-
const materializeProviderEnvironmentSecrets = (settings) => effect.Effect.gen(function* () {
|
|
26253
|
-
const providerInstances = { ...settings.providerInstances };
|
|
26254
|
-
for (const [instanceId, instance] of Object.entries(settings.providerInstances)) {
|
|
26255
|
-
if (!instance.environment) continue;
|
|
26256
|
-
const environment = [];
|
|
26257
|
-
for (const variable of instance.environment) {
|
|
26258
|
-
if (!variable.sensitive || !variable.valueRedacted) {
|
|
26259
|
-
environment.push(variable);
|
|
26260
|
-
continue;
|
|
26261
|
-
}
|
|
26262
|
-
const secret = yield* secretStore.get(providerEnvironmentSecretName({
|
|
26263
|
-
instanceId,
|
|
26264
|
-
name: variable.name
|
|
26265
|
-
})).pipe(effect.Effect.mapError((cause) => toSettingsError(`failed to read sensitive environment variable ${variable.name}`, cause)));
|
|
26266
|
-
environment.push({
|
|
26267
|
-
...variable,
|
|
26268
|
-
value: secret ? textDecoder$1.decode(secret) : ""
|
|
26269
|
-
});
|
|
26270
|
-
}
|
|
26271
|
-
providerInstances[instanceId] = {
|
|
26272
|
-
...instance,
|
|
26273
|
-
environment
|
|
26274
|
-
};
|
|
26275
|
-
}
|
|
26276
|
-
return {
|
|
26277
|
-
...settings,
|
|
26278
|
-
providerInstances
|
|
26279
|
-
};
|
|
26280
|
-
});
|
|
26281
|
-
const persistProviderEnvironmentSecrets = (current, next) => effect.Effect.gen(function* () {
|
|
26282
|
-
const providerInstances = { ...next.providerInstances };
|
|
26283
|
-
const nextSecretKeys = /* @__PURE__ */ new Set();
|
|
26284
|
-
for (const [instanceId, instance] of Object.entries(next.providerInstances)) {
|
|
26285
|
-
if (!instance.environment) continue;
|
|
26286
|
-
const environment = [];
|
|
26287
|
-
for (const variable of instance.environment) {
|
|
26288
|
-
const secretName = providerEnvironmentSecretName({
|
|
26289
|
-
instanceId,
|
|
26290
|
-
name: variable.name
|
|
26291
|
-
});
|
|
26292
|
-
if (!variable.sensitive) {
|
|
26293
|
-
yield* secretStore.remove(secretName).pipe(effect.Effect.mapError((cause) => toSettingsError(`failed to remove environment secret ${variable.name}`, cause)));
|
|
26294
|
-
environment.push(redactProviderEnvironmentVariable(variable));
|
|
26295
|
-
continue;
|
|
26296
|
-
}
|
|
26297
|
-
nextSecretKeys.add(secretName);
|
|
26298
|
-
if (!variable.valueRedacted) {
|
|
26299
|
-
if (variable.value.length > 0) {
|
|
26300
|
-
yield* secretStore.set(secretName, textEncoder$1.encode(variable.value)).pipe(effect.Effect.mapError((cause) => toSettingsError(`failed to persist environment secret ${variable.name}`, cause)));
|
|
26301
|
-
environment.push({
|
|
26302
|
-
...variable,
|
|
26303
|
-
value: "",
|
|
26304
|
-
valueRedacted: true
|
|
26305
|
-
});
|
|
26306
|
-
} else {
|
|
26307
|
-
yield* secretStore.remove(secretName).pipe(effect.Effect.mapError((cause) => toSettingsError(`failed to remove environment secret ${variable.name}`, cause)));
|
|
26308
|
-
const { valueRedacted: _omit, ...rest } = variable;
|
|
26309
|
-
environment.push(rest);
|
|
26310
|
-
}
|
|
26311
|
-
continue;
|
|
26312
|
-
}
|
|
26313
|
-
environment.push(redactProviderEnvironmentVariable(variable));
|
|
26314
|
-
}
|
|
26315
|
-
providerInstances[instanceId] = {
|
|
26316
|
-
...instance,
|
|
26317
|
-
environment
|
|
26318
|
-
};
|
|
26319
|
-
}
|
|
26320
|
-
for (const [instanceId, instance] of Object.entries(current.providerInstances)) for (const variable of instance.environment ?? []) {
|
|
26321
|
-
if (!variable.sensitive) continue;
|
|
26322
|
-
const secretName = providerEnvironmentSecretName({
|
|
26323
|
-
instanceId,
|
|
26324
|
-
name: variable.name
|
|
26325
|
-
});
|
|
26326
|
-
if (nextSecretKeys.has(secretName)) continue;
|
|
26327
|
-
yield* secretStore.remove(secretName).pipe(effect.Effect.mapError((cause) => toSettingsError(`failed to remove stale environment secret ${variable.name}`, cause)));
|
|
26328
|
-
}
|
|
26329
|
-
return {
|
|
26330
|
-
...next,
|
|
26331
|
-
providerInstances
|
|
26332
|
-
};
|
|
26333
|
-
});
|
|
26334
|
-
const writeSettingsAtomically = (settings) => {
|
|
26335
|
-
const sparseSettings = stripDefaultServerSettings(settings, require_collectUint8StreamText.DEFAULT_SERVER_SETTINGS) ?? {};
|
|
26336
|
-
return writeFileStringAtomically({
|
|
26337
|
-
filePath: settingsPath,
|
|
26338
|
-
contents: `${JSON.stringify(sparseSettings, null, 2)}\n`
|
|
26339
|
-
}).pipe(effect.Effect.provideService(effect.FileSystem.FileSystem, fs), effect.Effect.provideService(effect.Path.Path, pathService), effect.Effect.mapError((cause) => new require_collectUint8StreamText.ServerSettingsError({
|
|
26340
|
-
settingsPath,
|
|
26341
|
-
detail: "failed to write settings file",
|
|
26342
|
-
cause
|
|
26343
|
-
})));
|
|
26344
|
-
};
|
|
26345
|
-
const revalidateAndEmit = writeSemaphore.withPermits(1)(effect.Effect.gen(function* () {
|
|
26346
|
-
yield* effect.Cache.invalidate(settingsCache, cacheKey);
|
|
26347
|
-
yield* emitChange(yield* getSettingsFromCache);
|
|
26348
|
-
}));
|
|
26349
|
-
const startWatcher = effect.Effect.gen(function* () {
|
|
26350
|
-
const settingsDir = pathService.dirname(settingsPath);
|
|
26351
|
-
const settingsFile = pathService.basename(settingsPath);
|
|
26352
|
-
const settingsPathResolved = pathService.resolve(settingsPath);
|
|
26353
|
-
yield* fs.makeDirectory(settingsDir, { recursive: true }).pipe(effect.Effect.mapError((cause) => new require_collectUint8StreamText.ServerSettingsError({
|
|
26354
|
-
settingsPath,
|
|
26355
|
-
detail: "failed to prepare settings directory",
|
|
26356
|
-
cause
|
|
26357
|
-
})));
|
|
26358
|
-
const revalidateAndEmitSafely = revalidateAndEmit.pipe(effect.Effect.ignoreCause({ log: true }));
|
|
26359
|
-
const debouncedSettingsEvents = fs.watch(settingsDir).pipe(effect.Stream.filter((event) => {
|
|
26360
|
-
return event.path === settingsFile || event.path === settingsPath || pathService.resolve(settingsDir, event.path) === settingsPathResolved;
|
|
26361
|
-
}), effect.Stream.debounce(effect.Duration.millis(100)));
|
|
26362
|
-
yield* effect.Stream.runForEach(debouncedSettingsEvents, () => revalidateAndEmitSafely).pipe(effect.Effect.ignoreCause({ log: true }), effect.Effect.forkIn(watcherScope), effect.Effect.asVoid);
|
|
26363
|
-
});
|
|
26364
|
-
return {
|
|
26365
|
-
start: effect.Effect.gen(function* () {
|
|
26366
|
-
if (!(yield* effect.Ref.modify(startedRef, (started) => [!started, true]))) return yield* effect.Deferred.await(startedDeferred);
|
|
26367
|
-
const startup = effect.Effect.gen(function* () {
|
|
26368
|
-
yield* startWatcher;
|
|
26369
|
-
yield* effect.Cache.invalidate(settingsCache, cacheKey);
|
|
26370
|
-
yield* getSettingsFromCache;
|
|
26371
|
-
});
|
|
26372
|
-
const startupExit = yield* effect.Effect.exit(startup);
|
|
26373
|
-
if (startupExit._tag === "Failure") {
|
|
26374
|
-
yield* effect.Deferred.failCause(startedDeferred, startupExit.cause).pipe(effect.Effect.orDie);
|
|
26375
|
-
return yield* effect.Effect.failCause(startupExit.cause);
|
|
26376
|
-
}
|
|
26377
|
-
yield* effect.Deferred.succeed(startedDeferred, void 0).pipe(effect.Effect.orDie);
|
|
26378
|
-
}),
|
|
26379
|
-
ready: effect.Deferred.await(startedDeferred),
|
|
26380
|
-
getSettings: getSettingsFromCache.pipe(effect.Effect.flatMap(materializeProviderEnvironmentSecrets), effect.Effect.map(resolveTextGenerationProvider)),
|
|
26381
|
-
updateSettings: (patch) => writeSemaphore.withPermits(1)(effect.Effect.gen(function* () {
|
|
26382
|
-
const current = yield* getSettingsFromCache;
|
|
26383
|
-
const nextPersisted = yield* persistProviderEnvironmentSecrets(current, applyServerSettingsPatch(current, patch));
|
|
26384
|
-
const next = yield* effect.Schema.decodeEffect(require_collectUint8StreamText.ServerSettings)(nextPersisted).pipe(effect.Effect.mapError((cause) => new require_collectUint8StreamText.ServerSettingsError({
|
|
26385
|
-
settingsPath: "<memory>",
|
|
26386
|
-
detail: `failed to normalize server settings: ${effect.SchemaIssue.makeFormatterDefault()(cause.issue)}`,
|
|
26387
|
-
cause
|
|
26388
|
-
})));
|
|
26389
|
-
yield* writeSettingsAtomically(next);
|
|
26390
|
-
yield* effect.Cache.set(settingsCache, cacheKey, next);
|
|
26391
|
-
yield* emitChange(next);
|
|
26392
|
-
return resolveTextGenerationProvider(yield* materializeProviderEnvironmentSecrets(next));
|
|
26393
|
-
})),
|
|
26394
|
-
get streamChanges() {
|
|
26395
|
-
return effect.Stream.fromPubSub(changesPubSub).pipe(effect.Stream.mapEffect((settings) => materializeProviderEnvironmentSecrets(settings).pipe(effect.Effect.catch((error) => effect.Effect.logWarning("failed to materialize provider environment secrets", { detail: error.detail }).pipe(effect.Effect.as(settings))))), effect.Stream.map(resolveTextGenerationProvider));
|
|
26396
|
-
}
|
|
26397
|
-
};
|
|
26398
|
-
});
|
|
26399
|
-
const ServerSettingsLive = effect.Layer.effect(ServerSettingsService, makeServerSettings).pipe(effect.Layer.provide(ServerSecretStoreLive));
|
|
26400
|
-
//#endregion
|
|
26401
26369
|
//#region src/pathExpansion.ts
|
|
26402
26370
|
/**
|
|
26403
26371
|
* Expand a leading `~` (or `~/…`, `~\…`) in a user-supplied path to the
|
|
@@ -26718,7 +26686,7 @@ const BUILT_IN_DRIVERS = [
|
|
|
26718
26686
|
configSchema: require_collectUint8StreamText.CodexSettings,
|
|
26719
26687
|
defaultConfig: () => effect.Schema.decodeSync(require_collectUint8StreamText.CodexSettings)({}),
|
|
26720
26688
|
create: (input) => effect.Effect.tryPromise({
|
|
26721
|
-
try: () => Promise.resolve().then(() => require("./CodexDriver-
|
|
26689
|
+
try: () => Promise.resolve().then(() => require("./CodexDriver-CtCCc3CC.cjs")),
|
|
26722
26690
|
catch: (cause) => driverImportError(codexDriverKind, input, cause)
|
|
26723
26691
|
}).pipe(effect.Effect.flatMap(({ CodexDriver }) => CodexDriver.create(input)))
|
|
26724
26692
|
},
|
|
@@ -26731,7 +26699,7 @@ const BUILT_IN_DRIVERS = [
|
|
|
26731
26699
|
configSchema: require_collectUint8StreamText.ClaudeSettings,
|
|
26732
26700
|
defaultConfig: () => effect.Schema.decodeSync(require_collectUint8StreamText.ClaudeSettings)({}),
|
|
26733
26701
|
create: (input) => effect.Effect.tryPromise({
|
|
26734
|
-
try: () => Promise.resolve().then(() => require("./ClaudeDriver-
|
|
26702
|
+
try: () => Promise.resolve().then(() => require("./ClaudeDriver-ScqmbPKW.cjs")),
|
|
26735
26703
|
catch: (cause) => driverImportError(claudeDriverKind, input, cause)
|
|
26736
26704
|
}).pipe(effect.Effect.flatMap(({ ClaudeDriver }) => ClaudeDriver.create(input)))
|
|
26737
26705
|
},
|
|
@@ -26744,7 +26712,7 @@ const BUILT_IN_DRIVERS = [
|
|
|
26744
26712
|
configSchema: require_collectUint8StreamText.CopilotSettings,
|
|
26745
26713
|
defaultConfig: () => effect.Schema.decodeSync(require_collectUint8StreamText.CopilotSettings)({}),
|
|
26746
26714
|
create: (input) => effect.Effect.tryPromise({
|
|
26747
|
-
try: () => Promise.resolve().then(() => require("./CopilotDriver-
|
|
26715
|
+
try: () => Promise.resolve().then(() => require("./CopilotDriver-DLN2KEoc.cjs")),
|
|
26748
26716
|
catch: (cause) => driverImportError(copilotDriverKind, input, cause)
|
|
26749
26717
|
}).pipe(effect.Effect.flatMap(({ CopilotDriver }) => CopilotDriver.create(input)))
|
|
26750
26718
|
},
|
|
@@ -26757,7 +26725,7 @@ const BUILT_IN_DRIVERS = [
|
|
|
26757
26725
|
configSchema: require_collectUint8StreamText.CursorSettings,
|
|
26758
26726
|
defaultConfig: () => effect.Schema.decodeSync(require_collectUint8StreamText.CursorSettings)({}),
|
|
26759
26727
|
create: (input) => effect.Effect.tryPromise({
|
|
26760
|
-
try: () => Promise.resolve().then(() => require("./CursorDriver-
|
|
26728
|
+
try: () => Promise.resolve().then(() => require("./CursorDriver-BlvQbOEZ.cjs")),
|
|
26761
26729
|
catch: (cause) => driverImportError(cursorDriverKind, input, cause)
|
|
26762
26730
|
}).pipe(effect.Effect.flatMap(({ CursorDriver }) => CursorDriver.create(input)))
|
|
26763
26731
|
},
|
|
@@ -26770,7 +26738,7 @@ const BUILT_IN_DRIVERS = [
|
|
|
26770
26738
|
configSchema: require_collectUint8StreamText.OpenCodeSettings,
|
|
26771
26739
|
defaultConfig: () => effect.Schema.decodeSync(require_collectUint8StreamText.OpenCodeSettings)({}),
|
|
26772
26740
|
create: (input) => effect.Effect.tryPromise({
|
|
26773
|
-
try: () => Promise.resolve().then(() => require("./OpenCodeDriver-
|
|
26741
|
+
try: () => Promise.resolve().then(() => require("./OpenCodeDriver-mbR9mF54.cjs")),
|
|
26774
26742
|
catch: (cause) => driverImportError(openCodeDriverKind, input, cause)
|
|
26775
26743
|
}).pipe(effect.Effect.flatMap(({ OpenCodeDriver }) => OpenCodeDriver.create(input)))
|
|
26776
26744
|
}
|
|
@@ -26870,6 +26838,7 @@ function buildServerProvider(input) {
|
|
|
26870
26838
|
displayName: input.presentation.displayName,
|
|
26871
26839
|
...input.presentation.badgeLabel ? { badgeLabel: input.presentation.badgeLabel } : {},
|
|
26872
26840
|
...typeof input.presentation.showInteractionModeToggle === "boolean" ? { showInteractionModeToggle: input.presentation.showInteractionModeToggle } : {},
|
|
26841
|
+
...typeof input.presentation.supportsAskMode === "boolean" ? { supportsAskMode: input.presentation.supportsAskMode } : {},
|
|
26873
26842
|
enabled: input.enabled,
|
|
26874
26843
|
installed: input.probe.installed,
|
|
26875
26844
|
version: input.probe.version,
|
|
@@ -27483,13 +27452,14 @@ const scopedSafeTeardown = (label) => (effect$15) => effect.Effect.gen(function*
|
|
|
27483
27452
|
});
|
|
27484
27453
|
//#endregion
|
|
27485
27454
|
//#region package.json
|
|
27486
|
-
var version = "0.1.
|
|
27455
|
+
var version = "0.1.8";
|
|
27487
27456
|
//#endregion
|
|
27488
27457
|
//#region src/provider/Layers/CodexProvider.ts
|
|
27489
27458
|
const PROVIDER_PROBE_TIMEOUT_MS = 8e3;
|
|
27490
27459
|
const CODEX_PRESENTATION = {
|
|
27491
27460
|
displayName: "Codex",
|
|
27492
|
-
showInteractionModeToggle: true
|
|
27461
|
+
showInteractionModeToggle: true,
|
|
27462
|
+
supportsAskMode: true
|
|
27493
27463
|
};
|
|
27494
27464
|
const REASONING_EFFORT_LABELS = {
|
|
27495
27465
|
none: "None",
|
|
@@ -27497,8 +27467,15 @@ const REASONING_EFFORT_LABELS = {
|
|
|
27497
27467
|
low: "Low",
|
|
27498
27468
|
medium: "Medium",
|
|
27499
27469
|
high: "High",
|
|
27500
|
-
xhigh: "Extra High"
|
|
27470
|
+
xhigh: "Extra High",
|
|
27471
|
+
max: "Max",
|
|
27472
|
+
ultra: "Ultra"
|
|
27501
27473
|
};
|
|
27474
|
+
function formatReasoningEffortLabel(reasoningEffort) {
|
|
27475
|
+
const known = REASONING_EFFORT_LABELS[reasoningEffort];
|
|
27476
|
+
if (known) return known;
|
|
27477
|
+
return reasoningEffort.replace(/[_-]+/g, " ").replace(/\b\w/g, (char) => char.toUpperCase());
|
|
27478
|
+
}
|
|
27502
27479
|
function codexAccountAuthLabel(account) {
|
|
27503
27480
|
if (!account) return void 0;
|
|
27504
27481
|
if (account.type === "apiKey") return "OpenAI API Key";
|
|
@@ -27527,11 +27504,11 @@ function codexAccountEmail(account) {
|
|
|
27527
27504
|
function mapCodexModelCapabilities(model) {
|
|
27528
27505
|
const reasoningOptions = model.supportedReasoningEfforts.map(({ reasoningEffort }) => reasoningEffort === model.defaultReasoningEffort ? {
|
|
27529
27506
|
id: reasoningEffort,
|
|
27530
|
-
label:
|
|
27507
|
+
label: formatReasoningEffortLabel(reasoningEffort),
|
|
27531
27508
|
isDefault: true
|
|
27532
27509
|
} : {
|
|
27533
27510
|
id: reasoningEffort,
|
|
27534
|
-
label:
|
|
27511
|
+
label: formatReasoningEffortLabel(reasoningEffort)
|
|
27535
27512
|
});
|
|
27536
27513
|
const defaultReasoning = reasoningOptions.find((option) => option.isDefault)?.id;
|
|
27537
27514
|
const supportsFastMode = (model.additionalSpeedTiers ?? []).includes("fast");
|
|
@@ -28520,6 +28497,425 @@ var OrchestrationEngineService = class extends effect.Context.Service()("ryco/or
|
|
|
28520
28497
|
*/
|
|
28521
28498
|
var ProjectionSnapshotQuery = class extends effect.Context.Service()("ryco/orchestration/Services/ProjectionSnapshotQuery") {};
|
|
28522
28499
|
//#endregion
|
|
28500
|
+
//#region src/statistics/StatisticsQuery.ts
|
|
28501
|
+
/**
|
|
28502
|
+
* StatisticsQuery - usage analytics over the orchestration projection tables.
|
|
28503
|
+
*
|
|
28504
|
+
* Aggregates the existing read models (threads, sessions, token-usage
|
|
28505
|
+
* activities, turns/checkpoints, worktrees) into a {@link StatisticsSnapshot}
|
|
28506
|
+
* on demand. No dedicated statistics tables exist; everything is derived from
|
|
28507
|
+
* data already persisted by the projection pipeline.
|
|
28508
|
+
*
|
|
28509
|
+
* Token figures prefer per-turn attribution: for each `(thread, turn)` with
|
|
28510
|
+
* exact `last*` breakdowns we read the final `context-window.updated` activity
|
|
28511
|
+
* and bucket its provider-reported turn total by day/project/provider/model.
|
|
28512
|
+
* Threads without exact deltas (older data / providers that only report
|
|
28513
|
+
* cumulative context usage) fall back to attributing the latest cumulative
|
|
28514
|
+
* total to the thread's primary model and last-activity day.
|
|
28515
|
+
*
|
|
28516
|
+
* @module StatisticsQuery
|
|
28517
|
+
*/
|
|
28518
|
+
/**
|
|
28519
|
+
* StatisticsQuery - service tag.
|
|
28520
|
+
*/
|
|
28521
|
+
var StatisticsQuery = class extends effect.Context.Service()("ryco/statistics/StatisticsQuery") {};
|
|
28522
|
+
function toPersistenceSqlOrDecodeError$7(sqlOperation, decodeOperation) {
|
|
28523
|
+
return (cause) => effect.Schema.isSchemaError(cause) ? toPersistenceDecodeError(decodeOperation)(cause) : toPersistenceSqlError(sqlOperation)(cause);
|
|
28524
|
+
}
|
|
28525
|
+
const ThreadRow = effect.Schema.Struct({
|
|
28526
|
+
threadId: effect.Schema.String,
|
|
28527
|
+
projectId: require_collectUint8StreamText.ProjectId,
|
|
28528
|
+
model: effect.Schema.NullOr(effect.Schema.String),
|
|
28529
|
+
providerInstanceId: effect.Schema.NullOr(effect.Schema.String),
|
|
28530
|
+
createdAt: effect.Schema.String,
|
|
28531
|
+
providerName: effect.Schema.NullOr(effect.Schema.String)
|
|
28532
|
+
});
|
|
28533
|
+
const ProjectRow = effect.Schema.Struct({
|
|
28534
|
+
projectId: require_collectUint8StreamText.ProjectId,
|
|
28535
|
+
title: effect.Schema.String,
|
|
28536
|
+
deletedAt: effect.Schema.NullOr(effect.Schema.String)
|
|
28537
|
+
});
|
|
28538
|
+
const TokenActivityRow = effect.Schema.Struct({
|
|
28539
|
+
threadId: effect.Schema.String,
|
|
28540
|
+
turnId: effect.Schema.NullOr(effect.Schema.String),
|
|
28541
|
+
sequence: effect.Schema.NullOr(effect.Schema.Number),
|
|
28542
|
+
createdAt: effect.Schema.String,
|
|
28543
|
+
payloadJson: effect.Schema.String
|
|
28544
|
+
});
|
|
28545
|
+
const ToolUseRow = effect.Schema.Struct({
|
|
28546
|
+
threadId: effect.Schema.String,
|
|
28547
|
+
date: effect.Schema.String,
|
|
28548
|
+
count: effect.Schema.Number
|
|
28549
|
+
});
|
|
28550
|
+
const TurnRow = effect.Schema.Struct({
|
|
28551
|
+
threadId: effect.Schema.String,
|
|
28552
|
+
startedAt: effect.Schema.NullOr(effect.Schema.String),
|
|
28553
|
+
completedAt: effect.Schema.NullOr(effect.Schema.String),
|
|
28554
|
+
checkpointTurnCount: effect.Schema.NullOr(effect.Schema.Number),
|
|
28555
|
+
filesJson: effect.Schema.String
|
|
28556
|
+
});
|
|
28557
|
+
const WorktreeRow = effect.Schema.Struct({
|
|
28558
|
+
createdAt: effect.Schema.String,
|
|
28559
|
+
archivedAt: effect.Schema.NullOr(effect.Schema.String),
|
|
28560
|
+
prNumber: effect.Schema.NullOr(effect.Schema.Number)
|
|
28561
|
+
});
|
|
28562
|
+
function num(value) {
|
|
28563
|
+
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
28564
|
+
}
|
|
28565
|
+
function dayOf(iso) {
|
|
28566
|
+
return iso.length >= 10 ? iso.slice(0, 10) : null;
|
|
28567
|
+
}
|
|
28568
|
+
function bestPerTurnTotalTokenCount(payload) {
|
|
28569
|
+
const reportedTotal = num(payload?.lastUsedTokens);
|
|
28570
|
+
if (reportedTotal > 0) return reportedTotal;
|
|
28571
|
+
return num(payload?.lastInputTokens) + num(payload?.lastOutputTokens);
|
|
28572
|
+
}
|
|
28573
|
+
function bestCumulativeTotalTokenCount(payload) {
|
|
28574
|
+
const reportedTotal = num(payload?.usedTokens);
|
|
28575
|
+
if (reportedTotal > 0) return reportedTotal;
|
|
28576
|
+
return num(payload?.inputTokens) + num(payload?.outputTokens);
|
|
28577
|
+
}
|
|
28578
|
+
function hasExactPerTurnBreakdown(payload) {
|
|
28579
|
+
return num(payload?.lastInputTokens) + num(payload?.lastOutputTokens) + num(payload?.lastCachedInputTokens) + num(payload?.lastReasoningOutputTokens) > 0;
|
|
28580
|
+
}
|
|
28581
|
+
function addPerTurnUsage(bucket, payload) {
|
|
28582
|
+
bucket.inputTokens += num(payload?.lastInputTokens);
|
|
28583
|
+
bucket.outputTokens += num(payload?.lastOutputTokens);
|
|
28584
|
+
bucket.cachedInputTokens += num(payload?.lastCachedInputTokens);
|
|
28585
|
+
bucket.reasoningTokens += num(payload?.lastReasoningOutputTokens);
|
|
28586
|
+
bucket.totalTokens += bestPerTurnTotalTokenCount(payload);
|
|
28587
|
+
}
|
|
28588
|
+
function addCumulativeUsage(bucket, payload) {
|
|
28589
|
+
bucket.inputTokens += num(payload?.inputTokens);
|
|
28590
|
+
bucket.outputTokens += num(payload?.outputTokens);
|
|
28591
|
+
bucket.cachedInputTokens += num(payload?.cachedInputTokens);
|
|
28592
|
+
bucket.reasoningTokens += num(payload?.reasoningOutputTokens);
|
|
28593
|
+
bucket.totalTokens += bestCumulativeTotalTokenCount(payload);
|
|
28594
|
+
}
|
|
28595
|
+
const makeStatisticsQuery = effect.Effect.gen(function* () {
|
|
28596
|
+
const sql = yield* effect_unstable_sql_SqlClient.SqlClient;
|
|
28597
|
+
const listThreadRows = effect_unstable_sql_SqlSchema.findAll({
|
|
28598
|
+
Request: effect.Schema.Void,
|
|
28599
|
+
Result: ThreadRow,
|
|
28600
|
+
execute: () => sql`
|
|
28601
|
+
SELECT
|
|
28602
|
+
t.thread_id AS "threadId",
|
|
28603
|
+
t.project_id AS "projectId",
|
|
28604
|
+
json_extract(t.model_selection_json, '$.model') AS "model",
|
|
28605
|
+
COALESCE(
|
|
28606
|
+
json_extract(t.model_selection_json, '$.instanceId'),
|
|
28607
|
+
json_extract(t.model_selection_json, '$.provider')
|
|
28608
|
+
) AS "providerInstanceId",
|
|
28609
|
+
t.created_at AS "createdAt",
|
|
28610
|
+
COALESCE(
|
|
28611
|
+
s.provider_name,
|
|
28612
|
+
json_extract(t.model_selection_json, '$.instanceId'),
|
|
28613
|
+
json_extract(t.model_selection_json, '$.provider')
|
|
28614
|
+
) AS "providerName"
|
|
28615
|
+
FROM projection_threads t
|
|
28616
|
+
LEFT JOIN projection_thread_sessions s ON s.thread_id = t.thread_id
|
|
28617
|
+
`
|
|
28618
|
+
});
|
|
28619
|
+
const listProjectRows = effect_unstable_sql_SqlSchema.findAll({
|
|
28620
|
+
Request: effect.Schema.Void,
|
|
28621
|
+
Result: ProjectRow,
|
|
28622
|
+
execute: () => sql`
|
|
28623
|
+
SELECT
|
|
28624
|
+
project_id AS "projectId",
|
|
28625
|
+
title,
|
|
28626
|
+
deleted_at AS "deletedAt"
|
|
28627
|
+
FROM projection_projects
|
|
28628
|
+
`
|
|
28629
|
+
});
|
|
28630
|
+
const listTokenActivityRows = effect_unstable_sql_SqlSchema.findAll({
|
|
28631
|
+
Request: effect.Schema.Void,
|
|
28632
|
+
Result: TokenActivityRow,
|
|
28633
|
+
execute: () => sql`
|
|
28634
|
+
SELECT
|
|
28635
|
+
thread_id AS "threadId",
|
|
28636
|
+
turn_id AS "turnId",
|
|
28637
|
+
sequence,
|
|
28638
|
+
created_at AS "createdAt",
|
|
28639
|
+
payload_json AS "payloadJson"
|
|
28640
|
+
FROM projection_thread_activities
|
|
28641
|
+
WHERE kind = 'context-window.updated'
|
|
28642
|
+
ORDER BY thread_id ASC, turn_id ASC, sequence ASC, created_at ASC, activity_id ASC
|
|
28643
|
+
`
|
|
28644
|
+
});
|
|
28645
|
+
const listToolUseRows = effect_unstable_sql_SqlSchema.findAll({
|
|
28646
|
+
Request: effect.Schema.Void,
|
|
28647
|
+
Result: ToolUseRow,
|
|
28648
|
+
execute: () => sql`
|
|
28649
|
+
SELECT
|
|
28650
|
+
thread_id AS "threadId",
|
|
28651
|
+
substr(created_at, 1, 10) AS "date",
|
|
28652
|
+
COUNT(*) AS "count"
|
|
28653
|
+
FROM projection_thread_activities
|
|
28654
|
+
WHERE kind = 'tool.completed'
|
|
28655
|
+
GROUP BY thread_id, substr(created_at, 1, 10)
|
|
28656
|
+
`
|
|
28657
|
+
});
|
|
28658
|
+
const listTurnRows = effect_unstable_sql_SqlSchema.findAll({
|
|
28659
|
+
Request: effect.Schema.Void,
|
|
28660
|
+
Result: TurnRow,
|
|
28661
|
+
execute: () => sql`
|
|
28662
|
+
SELECT
|
|
28663
|
+
thread_id AS "threadId",
|
|
28664
|
+
started_at AS "startedAt",
|
|
28665
|
+
completed_at AS "completedAt",
|
|
28666
|
+
checkpoint_turn_count AS "checkpointTurnCount",
|
|
28667
|
+
checkpoint_files_json AS "filesJson"
|
|
28668
|
+
FROM projection_turns
|
|
28669
|
+
`
|
|
28670
|
+
});
|
|
28671
|
+
const listWorktreeRows = effect_unstable_sql_SqlSchema.findAll({
|
|
28672
|
+
Request: effect.Schema.Void,
|
|
28673
|
+
Result: WorktreeRow,
|
|
28674
|
+
execute: () => sql`
|
|
28675
|
+
SELECT
|
|
28676
|
+
created_at AS "createdAt",
|
|
28677
|
+
archived_at AS "archivedAt",
|
|
28678
|
+
pr_number AS "prNumber"
|
|
28679
|
+
FROM projection_worktrees
|
|
28680
|
+
`
|
|
28681
|
+
});
|
|
28682
|
+
const getStatistics = () => effect.Effect.gen(function* () {
|
|
28683
|
+
const [threadRows, projectRows, tokenRows, toolRows, turnRows, worktreeRows] = yield* effect.Effect.all([
|
|
28684
|
+
listThreadRows(void 0).pipe(effect.Effect.mapError(toPersistenceSqlOrDecodeError$7("StatisticsQuery.getStatistics:listThreads:query", "StatisticsQuery.getStatistics:listThreads:decodeRows"))),
|
|
28685
|
+
listProjectRows(void 0).pipe(effect.Effect.mapError(toPersistenceSqlOrDecodeError$7("StatisticsQuery.getStatistics:listProjects:query", "StatisticsQuery.getStatistics:listProjects:decodeRows"))),
|
|
28686
|
+
listTokenActivityRows(void 0).pipe(effect.Effect.mapError(toPersistenceSqlOrDecodeError$7("StatisticsQuery.getStatistics:listTokenActivities:query", "StatisticsQuery.getStatistics:listTokenActivities:decodeRows"))),
|
|
28687
|
+
listToolUseRows(void 0).pipe(effect.Effect.mapError(toPersistenceSqlOrDecodeError$7("StatisticsQuery.getStatistics:listToolUses:query", "StatisticsQuery.getStatistics:listToolUses:decodeRows"))),
|
|
28688
|
+
listTurnRows(void 0).pipe(effect.Effect.mapError(toPersistenceSqlOrDecodeError$7("StatisticsQuery.getStatistics:listTurns:query", "StatisticsQuery.getStatistics:listTurns:decodeRows"))),
|
|
28689
|
+
listWorktreeRows(void 0).pipe(effect.Effect.mapError(toPersistenceSqlOrDecodeError$7("StatisticsQuery.getStatistics:listWorktrees:query", "StatisticsQuery.getStatistics:listWorktrees:decodeRows")))
|
|
28690
|
+
], { concurrency: "unbounded" });
|
|
28691
|
+
const threadMeta = /* @__PURE__ */ new Map();
|
|
28692
|
+
const modelRefs = /* @__PURE__ */ new Map();
|
|
28693
|
+
for (const row of threadRows) {
|
|
28694
|
+
const provider = row.providerName?.trim() || row.providerInstanceId?.trim() || void 0;
|
|
28695
|
+
const model = (row.model ?? "").trim() || "unknown";
|
|
28696
|
+
threadMeta.set(row.threadId, {
|
|
28697
|
+
projectId: row.projectId,
|
|
28698
|
+
model,
|
|
28699
|
+
provider,
|
|
28700
|
+
createdAt: row.createdAt
|
|
28701
|
+
});
|
|
28702
|
+
const modelKey = `${provider ?? ""}\u0000${model}`;
|
|
28703
|
+
modelRefs.set(modelKey, provider ? {
|
|
28704
|
+
model,
|
|
28705
|
+
provider
|
|
28706
|
+
} : { model });
|
|
28707
|
+
}
|
|
28708
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
28709
|
+
const getBucket = (date, projectId, model, provider) => {
|
|
28710
|
+
const key = `${date}\u0000${projectId}\u0000${provider ?? ""}\u0000${model}`;
|
|
28711
|
+
let bucket = buckets.get(key);
|
|
28712
|
+
if (!bucket) {
|
|
28713
|
+
bucket = {
|
|
28714
|
+
date,
|
|
28715
|
+
projectId,
|
|
28716
|
+
model,
|
|
28717
|
+
provider,
|
|
28718
|
+
inputTokens: 0,
|
|
28719
|
+
outputTokens: 0,
|
|
28720
|
+
cachedInputTokens: 0,
|
|
28721
|
+
reasoningTokens: 0,
|
|
28722
|
+
totalTokens: 0,
|
|
28723
|
+
turns: 0,
|
|
28724
|
+
activeMs: 0,
|
|
28725
|
+
toolUses: 0,
|
|
28726
|
+
filesChanged: 0,
|
|
28727
|
+
additions: 0,
|
|
28728
|
+
deletions: 0,
|
|
28729
|
+
commits: 0,
|
|
28730
|
+
pushes: 0,
|
|
28731
|
+
threadsCreated: 0
|
|
28732
|
+
};
|
|
28733
|
+
buckets.set(key, bucket);
|
|
28734
|
+
}
|
|
28735
|
+
return bucket;
|
|
28736
|
+
};
|
|
28737
|
+
let earliest;
|
|
28738
|
+
const considerIso = (iso) => {
|
|
28739
|
+
if (iso && (earliest === void 0 || iso < earliest)) earliest = iso;
|
|
28740
|
+
};
|
|
28741
|
+
const lastPerTurn = /* @__PURE__ */ new Map();
|
|
28742
|
+
const isLater = (a, b) => {
|
|
28743
|
+
if (a.createdAt !== b.createdAt) return a.createdAt > b.createdAt;
|
|
28744
|
+
return (a.sequence ?? -1) >= (b.sequence ?? -1);
|
|
28745
|
+
};
|
|
28746
|
+
for (const row of tokenRows) {
|
|
28747
|
+
considerIso(row.createdAt);
|
|
28748
|
+
const turnKey = `${row.threadId}\u0000${row.turnId ?? ""}`;
|
|
28749
|
+
const prevTurn = lastPerTurn.get(turnKey);
|
|
28750
|
+
if (!prevTurn || isLater(row, prevTurn)) lastPerTurn.set(turnKey, row);
|
|
28751
|
+
}
|
|
28752
|
+
const firstExactPerThread = /* @__PURE__ */ new Map();
|
|
28753
|
+
for (const row of lastPerTurn.values()) if (hasExactPerTurnBreakdown(safeParse(row.payloadJson))) {
|
|
28754
|
+
const prev = firstExactPerThread.get(row.threadId);
|
|
28755
|
+
if (!prev || isLater(prev, row)) firstExactPerThread.set(row.threadId, row);
|
|
28756
|
+
}
|
|
28757
|
+
const cumulativeFallbackByThread = /* @__PURE__ */ new Map();
|
|
28758
|
+
for (const row of lastPerTurn.values()) {
|
|
28759
|
+
if (hasExactPerTurnBreakdown(safeParse(row.payloadJson))) continue;
|
|
28760
|
+
const firstExact = firstExactPerThread.get(row.threadId);
|
|
28761
|
+
if (firstExact && !isLater(firstExact, row)) continue;
|
|
28762
|
+
const prev = cumulativeFallbackByThread.get(row.threadId);
|
|
28763
|
+
if (!prev || isLater(row, prev)) cumulativeFallbackByThread.set(row.threadId, row);
|
|
28764
|
+
}
|
|
28765
|
+
let usedExactPerTurn = false;
|
|
28766
|
+
let usedCumulativeFallback = false;
|
|
28767
|
+
for (const row of lastPerTurn.values()) {
|
|
28768
|
+
const payload = safeParse(row.payloadJson);
|
|
28769
|
+
if (!hasExactPerTurnBreakdown(payload)) continue;
|
|
28770
|
+
const meta = threadMeta.get(row.threadId);
|
|
28771
|
+
const date = dayOf(row.createdAt);
|
|
28772
|
+
if (!meta || !date) continue;
|
|
28773
|
+
addPerTurnUsage(getBucket(date, meta.projectId, meta.model, meta.provider), payload);
|
|
28774
|
+
usedExactPerTurn = true;
|
|
28775
|
+
}
|
|
28776
|
+
for (const row of cumulativeFallbackByThread.values()) {
|
|
28777
|
+
const meta = threadMeta.get(row.threadId);
|
|
28778
|
+
const date = dayOf(row.createdAt);
|
|
28779
|
+
if (!meta || !date) continue;
|
|
28780
|
+
const payload = safeParse(row.payloadJson);
|
|
28781
|
+
if (bestCumulativeTotalTokenCount(payload) <= 0) continue;
|
|
28782
|
+
addCumulativeUsage(getBucket(date, meta.projectId, meta.model, meta.provider), payload);
|
|
28783
|
+
usedCumulativeFallback = true;
|
|
28784
|
+
}
|
|
28785
|
+
const attribution = usedExactPerTurn && usedCumulativeFallback ? "mixed" : usedCumulativeFallback ? "thread-cumulative" : "per-turn-delta";
|
|
28786
|
+
for (const row of turnRows) {
|
|
28787
|
+
const meta = threadMeta.get(row.threadId);
|
|
28788
|
+
if (!meta) continue;
|
|
28789
|
+
considerIso(row.startedAt);
|
|
28790
|
+
considerIso(row.completedAt);
|
|
28791
|
+
const anchor = row.completedAt ?? row.startedAt;
|
|
28792
|
+
const date = anchor ? dayOf(anchor) : null;
|
|
28793
|
+
if (!date) continue;
|
|
28794
|
+
const bucket = getBucket(date, meta.projectId, meta.model, meta.provider);
|
|
28795
|
+
if (row.completedAt) {
|
|
28796
|
+
bucket.turns += 1;
|
|
28797
|
+
if (row.startedAt) {
|
|
28798
|
+
const delta = Date.parse(row.completedAt) - Date.parse(row.startedAt);
|
|
28799
|
+
if (Number.isFinite(delta) && delta > 0) bucket.activeMs += delta;
|
|
28800
|
+
}
|
|
28801
|
+
}
|
|
28802
|
+
const files = safeParseArray(row.filesJson);
|
|
28803
|
+
if (files.length > 0) {
|
|
28804
|
+
bucket.filesChanged += files.length;
|
|
28805
|
+
for (const file of files) {
|
|
28806
|
+
bucket.additions += num(file?.additions);
|
|
28807
|
+
bucket.deletions += num(file?.deletions);
|
|
28808
|
+
}
|
|
28809
|
+
}
|
|
28810
|
+
}
|
|
28811
|
+
for (const row of toolRows) {
|
|
28812
|
+
const meta = threadMeta.get(row.threadId);
|
|
28813
|
+
if (!meta) continue;
|
|
28814
|
+
const bucket = getBucket(row.date, meta.projectId, meta.model, meta.provider);
|
|
28815
|
+
bucket.toolUses += num(row.count);
|
|
28816
|
+
}
|
|
28817
|
+
for (const meta of threadMeta.values()) {
|
|
28818
|
+
considerIso(meta.createdAt);
|
|
28819
|
+
const date = dayOf(meta.createdAt);
|
|
28820
|
+
if (!date) continue;
|
|
28821
|
+
getBucket(date, meta.projectId, meta.model, meta.provider).threadsCreated += 1;
|
|
28822
|
+
}
|
|
28823
|
+
let wtCreated = 0;
|
|
28824
|
+
let wtArchived = 0;
|
|
28825
|
+
let wtOpenPrs = 0;
|
|
28826
|
+
for (const row of worktreeRows) {
|
|
28827
|
+
considerIso(row.createdAt);
|
|
28828
|
+
wtCreated += 1;
|
|
28829
|
+
if (row.archivedAt) wtArchived += 1;
|
|
28830
|
+
else if (row.prNumber !== null) wtOpenPrs += 1;
|
|
28831
|
+
}
|
|
28832
|
+
const dailyBuckets = [];
|
|
28833
|
+
const totals = {
|
|
28834
|
+
inputTokens: 0,
|
|
28835
|
+
outputTokens: 0,
|
|
28836
|
+
cachedInputTokens: 0,
|
|
28837
|
+
reasoningTokens: 0,
|
|
28838
|
+
totalTokens: 0,
|
|
28839
|
+
turns: 0,
|
|
28840
|
+
activeMs: 0,
|
|
28841
|
+
toolUses: 0,
|
|
28842
|
+
filesChanged: 0,
|
|
28843
|
+
additions: 0,
|
|
28844
|
+
deletions: 0,
|
|
28845
|
+
commits: 0,
|
|
28846
|
+
pushes: 0,
|
|
28847
|
+
threads: threadMeta.size,
|
|
28848
|
+
projects: 0
|
|
28849
|
+
};
|
|
28850
|
+
for (const bucket of buckets.values()) {
|
|
28851
|
+
const { provider, ...rest } = bucket;
|
|
28852
|
+
dailyBuckets.push(provider ? {
|
|
28853
|
+
...rest,
|
|
28854
|
+
provider
|
|
28855
|
+
} : rest);
|
|
28856
|
+
totals.inputTokens += bucket.inputTokens;
|
|
28857
|
+
totals.outputTokens += bucket.outputTokens;
|
|
28858
|
+
totals.cachedInputTokens += bucket.cachedInputTokens;
|
|
28859
|
+
totals.reasoningTokens += bucket.reasoningTokens;
|
|
28860
|
+
totals.turns += bucket.turns;
|
|
28861
|
+
totals.activeMs += bucket.activeMs;
|
|
28862
|
+
totals.toolUses += bucket.toolUses;
|
|
28863
|
+
totals.filesChanged += bucket.filesChanged;
|
|
28864
|
+
totals.additions += bucket.additions;
|
|
28865
|
+
totals.deletions += bucket.deletions;
|
|
28866
|
+
totals.commits += bucket.commits;
|
|
28867
|
+
totals.pushes += bucket.pushes;
|
|
28868
|
+
totals.totalTokens += bucket.totalTokens;
|
|
28869
|
+
}
|
|
28870
|
+
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));
|
|
28871
|
+
const projectTitle = /* @__PURE__ */ new Map();
|
|
28872
|
+
for (const row of projectRows) projectTitle.set(row.projectId, row.title);
|
|
28873
|
+
const projectIdsInData = /* @__PURE__ */ new Set();
|
|
28874
|
+
for (const meta of threadMeta.values()) projectIdsInData.add(meta.projectId);
|
|
28875
|
+
for (const bucket of buckets.values()) projectIdsInData.add(bucket.projectId);
|
|
28876
|
+
totals.projects = projectIdsInData.size;
|
|
28877
|
+
const projects = [...projectIdsInData].map((id) => ({
|
|
28878
|
+
id,
|
|
28879
|
+
title: projectTitle.get(id)?.trim() || id
|
|
28880
|
+
}));
|
|
28881
|
+
projects.sort((a, b) => a.title.localeCompare(b.title) || a.id.localeCompare(b.id));
|
|
28882
|
+
const models = [...modelRefs.values()].toSorted((a, b) => (a.provider ?? "").localeCompare(b.provider ?? "") || a.model.localeCompare(b.model));
|
|
28883
|
+
return {
|
|
28884
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
28885
|
+
...earliest ? { earliestActivityAt: earliest } : {},
|
|
28886
|
+
projects,
|
|
28887
|
+
models,
|
|
28888
|
+
dailyBuckets,
|
|
28889
|
+
worktrees: {
|
|
28890
|
+
created: wtCreated,
|
|
28891
|
+
archived: wtArchived,
|
|
28892
|
+
active: wtCreated - wtArchived,
|
|
28893
|
+
openPrs: wtOpenPrs
|
|
28894
|
+
},
|
|
28895
|
+
totals,
|
|
28896
|
+
tokenAttribution: attribution
|
|
28897
|
+
};
|
|
28898
|
+
});
|
|
28899
|
+
return { getStatistics };
|
|
28900
|
+
});
|
|
28901
|
+
function safeParse(json) {
|
|
28902
|
+
try {
|
|
28903
|
+
const parsed = JSON.parse(json);
|
|
28904
|
+
return parsed && typeof parsed === "object" ? parsed : null;
|
|
28905
|
+
} catch {
|
|
28906
|
+
return null;
|
|
28907
|
+
}
|
|
28908
|
+
}
|
|
28909
|
+
function safeParseArray(json) {
|
|
28910
|
+
try {
|
|
28911
|
+
const parsed = JSON.parse(json);
|
|
28912
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
28913
|
+
} catch {
|
|
28914
|
+
return [];
|
|
28915
|
+
}
|
|
28916
|
+
}
|
|
28917
|
+
const StatisticsQueryLive = effect.Layer.effect(StatisticsQuery, makeStatisticsQuery);
|
|
28918
|
+
//#endregion
|
|
28523
28919
|
//#region src/serverLifecycleEvents.ts
|
|
28524
28920
|
var ServerLifecycleEvents = class extends effect.Context.Service()("ryco/serverLifecycleEvents") {};
|
|
28525
28921
|
const ServerLifecycleEventsLive = effect.Layer.effect(ServerLifecycleEvents, effect.Effect.gen(function* () {
|
|
@@ -30409,7 +30805,8 @@ const makeGitManager = effect.Effect.fn("makeGitManager")(function* () {
|
|
|
30409
30805
|
isDefaultRef: details.isDefaultBranch,
|
|
30410
30806
|
refName: details.branch,
|
|
30411
30807
|
hasWorkingTreeChanges: details.hasWorkingTreeChanges,
|
|
30412
|
-
workingTree: details.workingTree
|
|
30808
|
+
workingTree: details.workingTree,
|
|
30809
|
+
...details.committed ? { committed: details.committed } : {}
|
|
30413
30810
|
};
|
|
30414
30811
|
});
|
|
30415
30812
|
const localStatusResultCache = yield* effect.Cache.makeWith(readLocalStatus, {
|
|
@@ -32543,6 +32940,8 @@ const layer = effect.Layer.effect(JiraWorkItemService, make$5());
|
|
|
32543
32940
|
//#region src/remote/Services/AdvertisedEndpointRegistry.ts
|
|
32544
32941
|
var AdvertisedEndpointRegistry = class extends effect.Context.Service()("ryco/remote/Services/AdvertisedEndpointRegistry") {};
|
|
32545
32942
|
const ORCHESTRATION_REPLAY_PAGE_MAX_LIMIT = 1e3;
|
|
32943
|
+
const ORCHESTRATION_LEGACY_REPLAY_MAX_EVENTS = ORCHESTRATION_REPLAY_PAGE_MAX_LIMIT;
|
|
32944
|
+
const ORCHESTRATION_LIVE_QUEUE_MAX_EVENTS = 1e3;
|
|
32546
32945
|
//#endregion
|
|
32547
32946
|
//#region src/ws/context/gitErrors.ts
|
|
32548
32947
|
function gitErrorText(error) {
|
|
@@ -32576,6 +32975,10 @@ const failGitWorkflow = (operation, detail, cause) => effect.Effect.fail(toGitMa
|
|
|
32576
32975
|
const wsOrchestrationReplayDepth = effect.Metric.gauge("t3_ws_orchestration_replay_depth", { description: "Current persisted orchestration event replay depth for a replayable WebSocket subscription." });
|
|
32577
32976
|
const wsOrchestrationLiveBufferDepth = effect.Metric.gauge("t3_ws_orchestration_live_buffer_depth", { description: "Current live orchestration event buffer depth for a replayable WebSocket subscription." });
|
|
32578
32977
|
const wsOrchestrationLiveBufferHighWater = effect.Metric.gauge("t3_ws_orchestration_live_buffer_high_water", { description: "Highest observed live orchestration event buffer depth for a replayable WebSocket subscription." });
|
|
32978
|
+
const wsOrchestrationLiveBufferOverflowsTotal = effect.Metric.counter("t3_ws_orchestration_live_buffer_overflows_total", {
|
|
32979
|
+
description: "Total live orchestration event buffer overflows that forced replayable WebSocket subscription resync.",
|
|
32980
|
+
incremental: true
|
|
32981
|
+
});
|
|
32579
32982
|
const wsOrchestrationReplayLag = effect.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." });
|
|
32580
32983
|
const normalizeSequence = (sequence) => Number.isFinite(sequence) ? Math.max(0, Math.floor(sequence)) : 0;
|
|
32581
32984
|
const updateGauge$1 = (metric, attributes, value) => effect.Metric.update(effect.Metric.withAttributes(metric, attributes), value);
|
|
@@ -32613,6 +33016,18 @@ const makeWsReplayMetrics = (input) => effect.Effect.gen(function* () {
|
|
|
32613
33016
|
yield* recordLiveBuffer(yield* effect.Ref.updateAndGet(liveBufferDepth, (current) => Math.max(0, current - 1)), yield* effect.Ref.get(liveBufferHighWater));
|
|
32614
33017
|
yield* markDrained(sequence);
|
|
32615
33018
|
}),
|
|
33019
|
+
recordLiveOverflow: (sequence, capacity) => effect.Effect.gen(function* () {
|
|
33020
|
+
const normalizedSequence = normalizeSequence(sequence);
|
|
33021
|
+
const normalizedCapacity = Math.max(0, Math.floor(capacity));
|
|
33022
|
+
yield* effect.Ref.update(latestLiveSequence, (current) => Math.max(current, normalizedSequence));
|
|
33023
|
+
yield* effect.Ref.set(liveBufferDepth, normalizedCapacity);
|
|
33024
|
+
const highWater = yield* effect.Ref.updateAndGet(liveBufferHighWater, (current) => Math.max(current, normalizedCapacity));
|
|
33025
|
+
yield* effect.Effect.all([
|
|
33026
|
+
recordLiveBuffer(normalizedCapacity, highWater),
|
|
33027
|
+
updateGauge$1(wsOrchestrationLiveBufferOverflowsTotal, attributes, 1),
|
|
33028
|
+
recordLag
|
|
33029
|
+
], { discard: true });
|
|
33030
|
+
}),
|
|
32616
33031
|
reset: effect.Effect.all([
|
|
32617
33032
|
updateGauge$1(wsOrchestrationReplayDepth, attributes, 0),
|
|
32618
33033
|
updateGauge$1(wsOrchestrationLiveBufferDepth, attributes, 0),
|
|
@@ -32663,6 +33078,29 @@ const buildWorkItemBranchNameMessage = (input) => {
|
|
|
32663
33078
|
};
|
|
32664
33079
|
//#endregion
|
|
32665
33080
|
//#region src/ws/context/orchestrationStreams.ts
|
|
33081
|
+
const makeLiveQueueOverflowError = (input) => new require_collectUint8StreamText.OrchestrationGetSnapshotError({
|
|
33082
|
+
message: `Orchestration ${input.stream} live event queue overflowed; reconnect to resynchronize`,
|
|
33083
|
+
cause: /* @__PURE__ */ new Error(`orchestration ${input.stream} live queue overflow at sequence ${input.sequence} with capacity ${input.capacity}`)
|
|
33084
|
+
});
|
|
33085
|
+
const offerOrchestrationLiveEventOrFail = (input) => effect.Effect.gen(function* () {
|
|
33086
|
+
const capacity = input.capacity ?? 1e3;
|
|
33087
|
+
if (effect.Queue.offerUnsafe(input.liveQueue, input.event)) {
|
|
33088
|
+
yield* input.replayMetrics.recordLiveEnqueued(input.event.sequence);
|
|
33089
|
+
return;
|
|
33090
|
+
}
|
|
33091
|
+
if (!(yield* effect.Ref.modify(input.overflowedRef, (overflowed) => [!overflowed, true]))) return;
|
|
33092
|
+
yield* input.replayMetrics.recordLiveOverflow(input.event.sequence, capacity);
|
|
33093
|
+
yield* effect.Effect.logWarning("orchestration live stream queue overflow; forcing resync", {
|
|
33094
|
+
stream: input.stream,
|
|
33095
|
+
sequence: input.event.sequence,
|
|
33096
|
+
capacity
|
|
33097
|
+
});
|
|
33098
|
+
yield* effect.Queue.fail(input.liveQueue, makeLiveQueueOverflowError({
|
|
33099
|
+
stream: input.stream,
|
|
33100
|
+
sequence: input.event.sequence,
|
|
33101
|
+
capacity
|
|
33102
|
+
}));
|
|
33103
|
+
});
|
|
32666
33104
|
const makeOrchestrationStreamHelpers = (deps) => {
|
|
32667
33105
|
const { orchestrationEngine, projectionSnapshotQuery, repositoryIdentityResolver } = deps;
|
|
32668
33106
|
const enrichProjectEvent = (event) => {
|
|
@@ -32782,8 +33220,9 @@ const makeOrchestrationStreamHelpers = (deps) => {
|
|
|
32782
33220
|
const loadedSnapshot = yield* snapshot;
|
|
32783
33221
|
const snapshotSequence = loadedSnapshot.snapshotSequence;
|
|
32784
33222
|
const liveSubscription = yield* orchestrationEngine.subscribeDomainEvents;
|
|
32785
|
-
const liveQueue = yield* effect.Queue.
|
|
33223
|
+
const liveQueue = yield* effect.Queue.bounded(ORCHESTRATION_LIVE_QUEUE_MAX_EVENTS);
|
|
32786
33224
|
const lastSequenceRef = yield* effect.Ref.make(snapshotSequence);
|
|
33225
|
+
const overflowedRef = yield* effect.Ref.make(false);
|
|
32787
33226
|
const replayBoundary = yield* makeReplayBoundaryTracker(snapshotSequence);
|
|
32788
33227
|
const replayMetrics = yield* makeWsReplayMetrics({
|
|
32789
33228
|
stream: "shell",
|
|
@@ -32792,8 +33231,13 @@ const makeOrchestrationStreamHelpers = (deps) => {
|
|
|
32792
33231
|
});
|
|
32793
33232
|
yield* effect.Stream.fromSubscription(liveSubscription).pipe(effect.Stream.runForEach((event) => effect.Effect.gen(function* () {
|
|
32794
33233
|
yield* replayBoundary.recordLiveSequence(event.sequence);
|
|
32795
|
-
yield*
|
|
32796
|
-
|
|
33234
|
+
yield* offerOrchestrationLiveEventOrFail({
|
|
33235
|
+
stream: "shell",
|
|
33236
|
+
event,
|
|
33237
|
+
liveQueue,
|
|
33238
|
+
overflowedRef,
|
|
33239
|
+
replayMetrics
|
|
33240
|
+
});
|
|
32797
33241
|
})), effect.Effect.ensuring(effect.Queue.shutdown(liveQueue)), effect.Effect.ignoreCause({ log: true }), effect.Effect.forkScoped);
|
|
32798
33242
|
const replayStream = makeBoundedReplayStream({
|
|
32799
33243
|
snapshotSequence,
|
|
@@ -32811,8 +33255,9 @@ const makeOrchestrationStreamHelpers = (deps) => {
|
|
|
32811
33255
|
const loadedSnapshot = yield* snapshot;
|
|
32812
33256
|
const snapshotSequence = loadedSnapshot.snapshotSequence;
|
|
32813
33257
|
const liveSubscription = yield* orchestrationEngine.subscribeDomainEvents;
|
|
32814
|
-
const liveQueue = yield* effect.Queue.
|
|
33258
|
+
const liveQueue = yield* effect.Queue.bounded(ORCHESTRATION_LIVE_QUEUE_MAX_EVENTS);
|
|
32815
33259
|
const lastSequenceRef = yield* effect.Ref.make(snapshotSequence);
|
|
33260
|
+
const overflowedRef = yield* effect.Ref.make(false);
|
|
32816
33261
|
const replayBoundary = yield* makeReplayBoundaryTracker(snapshotSequence);
|
|
32817
33262
|
const replayMetrics = yield* makeWsReplayMetrics({
|
|
32818
33263
|
stream: "thread",
|
|
@@ -32825,8 +33270,13 @@ const makeOrchestrationStreamHelpers = (deps) => {
|
|
|
32825
33270
|
})));
|
|
32826
33271
|
yield* effect.Stream.fromSubscription(liveSubscription).pipe(effect.Stream.runForEach((event) => effect.Effect.gen(function* () {
|
|
32827
33272
|
yield* replayBoundary.recordLiveSequence(event.sequence);
|
|
32828
|
-
yield*
|
|
32829
|
-
|
|
33273
|
+
yield* offerOrchestrationLiveEventOrFail({
|
|
33274
|
+
stream: "thread",
|
|
33275
|
+
event,
|
|
33276
|
+
liveQueue,
|
|
33277
|
+
overflowedRef,
|
|
33278
|
+
replayMetrics
|
|
33279
|
+
});
|
|
32830
33280
|
})), effect.Effect.ensuring(effect.Queue.shutdown(liveQueue)), effect.Effect.ignoreCause({ log: true }), effect.Effect.forkScoped);
|
|
32831
33281
|
const replayStream = makeBoundedReplayStream({
|
|
32832
33282
|
snapshotSequence,
|
|
@@ -32858,6 +33308,13 @@ const makeWorktreeOperations = (deps) => {
|
|
|
32858
33308
|
onNone: () => failGitWorkflow(operation, `Worktree ${worktreeId} not found.`),
|
|
32859
33309
|
onSome: effect.Effect.succeed
|
|
32860
33310
|
})));
|
|
33311
|
+
const isProjectRootPath = (candidate, projectRoot) => {
|
|
33312
|
+
const normalize = (value) => {
|
|
33313
|
+
const resolved = node_path.default.resolve(value).replace(/[\\/]+$/g, "");
|
|
33314
|
+
return process.platform === "win32" || process.platform === "darwin" ? resolved.toLowerCase() : resolved;
|
|
33315
|
+
};
|
|
33316
|
+
return normalize(candidate) === normalize(projectRoot);
|
|
33317
|
+
};
|
|
32861
33318
|
const dispatchWorktreeCommand = (command, operation) => dispatchNormalizedCommand(command).pipe(effect.Effect.mapError((cause) => toGitManagerError(operation, "Failed to dispatch orchestration command.", cause)), effect.Effect.asVoid);
|
|
32862
33319
|
const launchSetupScriptForWorktreeInBackground = (input) => effect.Effect.gen(function* () {
|
|
32863
33320
|
const requestedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -33081,20 +33538,27 @@ const makeWorktreeOperations = (deps) => {
|
|
|
33081
33538
|
break;
|
|
33082
33539
|
}
|
|
33083
33540
|
}
|
|
33084
|
-
|
|
33085
|
-
|
|
33086
|
-
|
|
33087
|
-
|
|
33088
|
-
|
|
33541
|
+
let worktreePath;
|
|
33542
|
+
if (preparedWorktreePath !== null) {
|
|
33543
|
+
if (isProjectRootPath(preparedWorktreePath, project.workspaceRoot)) return yield* failGitWorkflow(operation, "Cannot create a worktree at the project root.");
|
|
33544
|
+
worktreePath = preparedWorktreePath;
|
|
33545
|
+
} else {
|
|
33546
|
+
const targetPath = resolveWorktreeCheckoutPath({
|
|
33089
33547
|
location: input.worktreeLocation,
|
|
33090
33548
|
appWorktreesRoot: config.worktreesDir,
|
|
33091
33549
|
projectId: input.projectId,
|
|
33092
33550
|
workspaceRoot: project.workspaceRoot,
|
|
33093
33551
|
projectMetadataDir: project.projectMetadataDir,
|
|
33094
33552
|
branchName: branch
|
|
33095
|
-
})
|
|
33096
|
-
|
|
33097
|
-
|
|
33553
|
+
});
|
|
33554
|
+
if (isProjectRootPath(targetPath, project.workspaceRoot)) return yield* failGitWorkflow(operation, "Cannot create a worktree at the project root.");
|
|
33555
|
+
worktreePath = (yield* gitWorkflow.createWorktree({
|
|
33556
|
+
cwd: project.workspaceRoot,
|
|
33557
|
+
refName,
|
|
33558
|
+
...newRefName !== void 0 ? { newRefName } : {},
|
|
33559
|
+
path: targetPath
|
|
33560
|
+
})).worktree.path;
|
|
33561
|
+
if (isProjectRootPath(worktreePath, project.workspaceRoot)) return yield* failGitWorkflow(operation, "Refusing to register a worktree that resolved to the project root.");
|
|
33098
33562
|
ownedWorktreePath = worktreePath;
|
|
33099
33563
|
if (newRefName !== void 0) ownedBranchName = newRefName;
|
|
33100
33564
|
}
|
|
@@ -33235,6 +33699,7 @@ const makeWorktreeOperations = (deps) => {
|
|
|
33235
33699
|
const worktree = yield* loadWorktreeForGitWorkflow(operation, input.worktreeId);
|
|
33236
33700
|
if (worktree.origin === "main") return yield* failGitWorkflow(operation, "Cannot delete the main worktree.");
|
|
33237
33701
|
const project = yield* loadProjectForGitWorkflow(operation, worktree.projectId);
|
|
33702
|
+
if (worktree.worktreePath !== null && isProjectRootPath(worktree.worktreePath, project.workspaceRoot)) return yield* failGitWorkflow(operation, "Cannot delete a worktree that points at the project root.");
|
|
33238
33703
|
if (input.force) {
|
|
33239
33704
|
if (worktree.worktreePath !== null) {
|
|
33240
33705
|
if ((0, node_fs.existsSync)(worktree.worktreePath)) return yield* failGitWorkflow(operation, "Cannot force delete: the worktree path still exists on disk. Use a regular delete instead.");
|
|
@@ -33367,6 +33832,7 @@ function toDiagnosticsProviderProcess(provider) {
|
|
|
33367
33832
|
const makeWsRpcContext = (session) => effect.Effect.gen(function* () {
|
|
33368
33833
|
const currentSessionId = session.sessionId;
|
|
33369
33834
|
const projectionSnapshotQuery = yield* ProjectionSnapshotQuery;
|
|
33835
|
+
const statisticsQuery = yield* StatisticsQuery;
|
|
33370
33836
|
const orchestrationEngine = yield* OrchestrationEngineService;
|
|
33371
33837
|
const checkpointDiffQuery = yield* CheckpointDiffQuery;
|
|
33372
33838
|
const keybindings = yield* Keybindings;
|
|
@@ -33690,6 +34156,7 @@ const makeWsRpcContext = (session) => effect.Effect.gen(function* () {
|
|
|
33690
34156
|
return {
|
|
33691
34157
|
currentSessionId,
|
|
33692
34158
|
projectionSnapshotQuery,
|
|
34159
|
+
statisticsQuery,
|
|
33693
34160
|
orchestrationEngine,
|
|
33694
34161
|
checkpointDiffQuery,
|
|
33695
34162
|
keybindings,
|
|
@@ -33967,9 +34434,9 @@ function recordServerPerfPayload(label, value, record) {
|
|
|
33967
34434
|
//#endregion
|
|
33968
34435
|
//#region src/ws/orchestrationRpc.ts
|
|
33969
34436
|
const makeOrchestrationHandlers = (ctx) => {
|
|
33970
|
-
const {
|
|
34437
|
+
const { ownerEffect, projectionSnapshotQuery, dispatchNormalizedCommand, dispatchWorktreeCommand, serverCommandId, terminalManager, checkpointDiffQuery, orchestrationEngine, enrichOrchestrationEvents, makeReplayableShellStream, makeReplayableThreadStream } = ctx;
|
|
33971
34438
|
return defineWsHandlers({
|
|
33972
|
-
[require_collectUint8StreamText.ORCHESTRATION_WS_METHODS.dispatchCommand]: (command) => observeRpcEffect(require_collectUint8StreamText.ORCHESTRATION_WS_METHODS.dispatchCommand,
|
|
34439
|
+
[require_collectUint8StreamText.ORCHESTRATION_WS_METHODS.dispatchCommand]: (command) => observeRpcEffect(require_collectUint8StreamText.ORCHESTRATION_WS_METHODS.dispatchCommand, ownerEffect(require_collectUint8StreamText.ORCHESTRATION_WS_METHODS.dispatchCommand, effect.Effect.gen(function* () {
|
|
33973
34440
|
const normalizedCommand = yield* normalizeDispatchCommand(command);
|
|
33974
34441
|
const shouldStopSessionAfterArchive = normalizedCommand.type === "thread.archive" ? yield* projectionSnapshotQuery.getThreadShellById(normalizedCommand.threadId).pipe(effect.Effect.map(effect.Option.match({
|
|
33975
34442
|
onNone: () => false,
|
|
@@ -34006,10 +34473,20 @@ const makeOrchestrationHandlers = (ctx) => {
|
|
|
34006
34473
|
message: "Failed to load full thread diff",
|
|
34007
34474
|
cause
|
|
34008
34475
|
}))), { "rpc.aggregate": "orchestration" }),
|
|
34476
|
+
[require_collectUint8StreamText.ORCHESTRATION_WS_METHODS.searchThreadMessages]: (input) => observeRpcEffect(require_collectUint8StreamText.ORCHESTRATION_WS_METHODS.searchThreadMessages, projectionSnapshotQuery.searchThreadMessages({
|
|
34477
|
+
...input,
|
|
34478
|
+
limit: (0, effect_Number.clamp)(input.limit, {
|
|
34479
|
+
maximum: 50,
|
|
34480
|
+
minimum: 1
|
|
34481
|
+
})
|
|
34482
|
+
}).pipe(effect.Effect.mapError((cause) => new require_collectUint8StreamText.OrchestrationGetSnapshotError({
|
|
34483
|
+
message: "Failed to search thread messages",
|
|
34484
|
+
cause
|
|
34485
|
+
}))), { "rpc.aggregate": "orchestration" }),
|
|
34009
34486
|
[require_collectUint8StreamText.ORCHESTRATION_WS_METHODS.replayEvents]: (input) => observeRpcEffect(require_collectUint8StreamText.ORCHESTRATION_WS_METHODS.replayEvents, effect.Stream.runCollect(orchestrationEngine.readEvents((0, effect_Number.clamp)(input.fromSequenceExclusive, {
|
|
34010
34487
|
maximum: Number.MAX_SAFE_INTEGER,
|
|
34011
34488
|
minimum: 0
|
|
34012
|
-
}))).pipe(effect.Effect.map((events) => Array.from(events)), effect.Effect.flatMap(enrichOrchestrationEvents), effect.Effect.mapError((cause) => new require_collectUint8StreamText.OrchestrationReplayEventsError({
|
|
34489
|
+
}), ORCHESTRATION_LEGACY_REPLAY_MAX_EVENTS)).pipe(effect.Effect.map((events) => Array.from(events)), effect.Effect.flatMap(enrichOrchestrationEvents), effect.Effect.mapError((cause) => new require_collectUint8StreamText.OrchestrationReplayEventsError({
|
|
34013
34490
|
message: "Failed to replay orchestration events",
|
|
34014
34491
|
cause
|
|
34015
34492
|
}))), { "rpc.aggregate": "orchestration" }),
|
|
@@ -34065,7 +34542,22 @@ const makeOrchestrationHandlers = (ctx) => {
|
|
|
34065
34542
|
threadId: input.threadId,
|
|
34066
34543
|
position: input.position,
|
|
34067
34544
|
changedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
34068
|
-
}, "threads.setManualPosition").pipe(effect.Effect.as({}))), { "rpc.aggregate": "orchestration" })
|
|
34545
|
+
}, "threads.setManualPosition").pipe(effect.Effect.as({}))), { "rpc.aggregate": "orchestration" }),
|
|
34546
|
+
[require_collectUint8StreamText.WS_METHODS.searchThreadMessages]: (input) => observeRpcEffect(require_collectUint8StreamText.WS_METHODS.searchThreadMessages, ownerEffect(require_collectUint8StreamText.WS_METHODS.searchThreadMessages, effect.Effect.gen(function* () {
|
|
34547
|
+
const query = input.query.trim();
|
|
34548
|
+
if (query.length === 0) return { results: [] };
|
|
34549
|
+
return { results: yield* projectionSnapshotQuery.searchThreadMessages({
|
|
34550
|
+
query,
|
|
34551
|
+
...input.projectId ? { projectId: input.projectId } : {},
|
|
34552
|
+
limit: (0, effect_Number.clamp)(input.limit ?? 20, {
|
|
34553
|
+
maximum: 50,
|
|
34554
|
+
minimum: 1
|
|
34555
|
+
})
|
|
34556
|
+
}) };
|
|
34557
|
+
}).pipe(effect.Effect.mapError(() => new require_collectUint8StreamText.AuthRpcError({
|
|
34558
|
+
message: "Failed to search thread messages.",
|
|
34559
|
+
status: 403
|
|
34560
|
+
})))), { "rpc.aggregate": "orchestration" })
|
|
34069
34561
|
});
|
|
34070
34562
|
};
|
|
34071
34563
|
//#endregion
|
|
@@ -34140,10 +34632,25 @@ const makeTerminalHandlers = (ctx) => {
|
|
|
34140
34632
|
[require_collectUint8StreamText.WS_METHODS.terminalClear]: (input) => observeRpcEffect(require_collectUint8StreamText.WS_METHODS.terminalClear, ownerEffect(require_collectUint8StreamText.WS_METHODS.terminalClear, terminalManager.clear(input)), { "rpc.aggregate": "terminal" }),
|
|
34141
34633
|
[require_collectUint8StreamText.WS_METHODS.terminalRestart]: (input) => observeRpcEffect(require_collectUint8StreamText.WS_METHODS.terminalRestart, ownerEffect(require_collectUint8StreamText.WS_METHODS.terminalRestart, terminalManager.restart(input)), { "rpc.aggregate": "terminal" }),
|
|
34142
34634
|
[require_collectUint8StreamText.WS_METHODS.terminalClose]: (input) => observeRpcEffect(require_collectUint8StreamText.WS_METHODS.terminalClose, ownerEffect(require_collectUint8StreamText.WS_METHODS.terminalClose, terminalManager.close(input)), { "rpc.aggregate": "terminal" }),
|
|
34143
|
-
[require_collectUint8StreamText.WS_METHODS.subscribeTerminalEvents]: (_input) => observeRpcStream(require_collectUint8StreamText.WS_METHODS.subscribeTerminalEvents, ownerStream(require_collectUint8StreamText.WS_METHODS.subscribeTerminalEvents, effect.Stream.callback((queue) => effect.Effect.acquireRelease(
|
|
34144
|
-
|
|
34145
|
-
|
|
34146
|
-
|
|
34635
|
+
[require_collectUint8StreamText.WS_METHODS.subscribeTerminalEvents]: (_input) => observeRpcStream(require_collectUint8StreamText.WS_METHODS.subscribeTerminalEvents, ownerStream(require_collectUint8StreamText.WS_METHODS.subscribeTerminalEvents, effect.Stream.callback((queue) => effect.Effect.acquireRelease(effect.Effect.gen(function* () {
|
|
34636
|
+
const unsubscribe = yield* terminalManager.subscribe((event) => effect.Effect.gen(function* () {
|
|
34637
|
+
recordServerPerfPayload("server.ws.terminal.events", event);
|
|
34638
|
+
yield* effect.Queue.offer(queue, event);
|
|
34639
|
+
}));
|
|
34640
|
+
const snapshots = yield* terminalManager.listSessions;
|
|
34641
|
+
yield* effect.Effect.forEach(snapshots.filter((snapshot) => snapshot.status === "running"), (snapshot) => {
|
|
34642
|
+
const event = {
|
|
34643
|
+
type: "started",
|
|
34644
|
+
threadId: snapshot.threadId,
|
|
34645
|
+
terminalId: snapshot.terminalId,
|
|
34646
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34647
|
+
snapshot
|
|
34648
|
+
};
|
|
34649
|
+
recordServerPerfPayload("server.ws.terminal.events", event);
|
|
34650
|
+
return effect.Queue.offer(queue, event);
|
|
34651
|
+
}, { discard: true });
|
|
34652
|
+
return unsubscribe;
|
|
34653
|
+
}), (unsubscribe) => effect.Effect.sync(unsubscribe)))), { "rpc.aggregate": "terminal" })
|
|
34147
34654
|
});
|
|
34148
34655
|
};
|
|
34149
34656
|
//#endregion
|
|
@@ -34238,7 +34745,7 @@ const makeSourceControlHandlers = (ctx) => {
|
|
|
34238
34745
|
cwd,
|
|
34239
34746
|
reason: "sourceControl.searchIssues"
|
|
34240
34747
|
})))), { "rpc.aggregate": "source-control" }),
|
|
34241
|
-
[require_collectUint8StreamText.WS_METHODS.sourceControlListChangeRequests]: ({ cwd, state, limit, query }) => observeRpcEffect(require_collectUint8StreamText.WS_METHODS.sourceControlListChangeRequests, sourceControlRegistry.resolve({ cwd }).pipe(effect.Effect.flatMap((provider) => {
|
|
34748
|
+
[require_collectUint8StreamText.WS_METHODS.sourceControlListChangeRequests]: ({ cwd, state, limit, query }) => observeRpcEffect(require_collectUint8StreamText.WS_METHODS.sourceControlListChangeRequests, ownerEffect(require_collectUint8StreamText.WS_METHODS.sourceControlListChangeRequests, sourceControlRegistry.resolve({ cwd }).pipe(effect.Effect.flatMap((provider) => {
|
|
34242
34749
|
const trimmedQuery = query?.trim() ?? "";
|
|
34243
34750
|
if (trimmedQuery.length > 0) return provider.searchChangeRequests({
|
|
34244
34751
|
cwd,
|
|
@@ -34254,7 +34761,7 @@ const makeSourceControlHandlers = (ctx) => {
|
|
|
34254
34761
|
}), effect.Effect.tap(() => refreshLinkedWorktreeSourceControlStates({
|
|
34255
34762
|
cwd,
|
|
34256
34763
|
reason: "sourceControl.listChangeRequests"
|
|
34257
|
-
}))), { "rpc.aggregate": "source-control" }),
|
|
34764
|
+
})))), { "rpc.aggregate": "source-control" }),
|
|
34258
34765
|
[require_collectUint8StreamText.WS_METHODS.sourceControlSearchChangeRequests]: ({ cwd, query, limit }) => observeRpcEffect(require_collectUint8StreamText.WS_METHODS.sourceControlSearchChangeRequests, ownerEffect(require_collectUint8StreamText.WS_METHODS.sourceControlSearchChangeRequests, sourceControlRegistry.resolve({ cwd }).pipe(effect.Effect.flatMap((provider) => provider.searchChangeRequests({
|
|
34259
34766
|
cwd,
|
|
34260
34767
|
query,
|
|
@@ -34332,7 +34839,7 @@ const makeSourceControlHandlers = (ctx) => {
|
|
|
34332
34839
|
})), { "rpc.aggregate": "source-control" }),
|
|
34333
34840
|
[require_collectUint8StreamText.WS_METHODS.sourceControlListIssueLabels]: ({ cwd }) => observeRpcEffect(require_collectUint8StreamText.WS_METHODS.sourceControlListIssueLabels, ownerEffect(require_collectUint8StreamText.WS_METHODS.sourceControlListIssueLabels, sourceControlRegistry.resolve({ cwd }).pipe(effect.Effect.flatMap((provider) => provider.listLabels({ cwd })))), { "rpc.aggregate": "source-control" }),
|
|
34334
34841
|
[require_collectUint8StreamText.WS_METHODS.sourceControlListIssueAssignees]: ({ cwd }) => observeRpcEffect(require_collectUint8StreamText.WS_METHODS.sourceControlListIssueAssignees, ownerEffect(require_collectUint8StreamText.WS_METHODS.sourceControlListIssueAssignees, sourceControlRegistry.resolve({ cwd }).pipe(effect.Effect.flatMap((provider) => provider.listAssignees({ cwd })))), { "rpc.aggregate": "source-control" }),
|
|
34335
|
-
[require_collectUint8StreamText.WS_METHODS.sourceControlListWorkflowRuns]: ({ cwd, pullRequestNumber, commitSha, limit }) => observeRpcEffect(require_collectUint8StreamText.WS_METHODS.sourceControlListWorkflowRuns, ownerEffect(require_collectUint8StreamText.WS_METHODS.sourceControlListWorkflowRuns, callSourceControlWorkflowMethod({
|
|
34842
|
+
[require_collectUint8StreamText.WS_METHODS.sourceControlListWorkflowRuns]: ({ cwd, pullRequestNumber, commitSha, branch, limit }) => observeRpcEffect(require_collectUint8StreamText.WS_METHODS.sourceControlListWorkflowRuns, ownerEffect(require_collectUint8StreamText.WS_METHODS.sourceControlListWorkflowRuns, callSourceControlWorkflowMethod({
|
|
34336
34843
|
cwd,
|
|
34337
34844
|
operation: "listWorkflowRuns",
|
|
34338
34845
|
invoke: (provider) => {
|
|
@@ -34341,6 +34848,7 @@ const makeSourceControlHandlers = (ctx) => {
|
|
|
34341
34848
|
cwd,
|
|
34342
34849
|
...pullRequestNumber !== void 0 ? { pullRequestNumber } : {},
|
|
34343
34850
|
...commitSha !== void 0 ? { commitSha } : {},
|
|
34851
|
+
...branch !== void 0 ? { branch } : {},
|
|
34344
34852
|
...limit !== void 0 ? { limit } : {}
|
|
34345
34853
|
});
|
|
34346
34854
|
}
|
|
@@ -35004,12 +35512,19 @@ const makeProviderHandlers = (ctx) => {
|
|
|
35004
35512
|
});
|
|
35005
35513
|
};
|
|
35006
35514
|
//#endregion
|
|
35515
|
+
//#region src/ws/statisticsRpc.ts
|
|
35516
|
+
const makeStatisticsHandlers = (ctx) => {
|
|
35517
|
+
const { statisticsQuery, ownerEffect } = ctx;
|
|
35518
|
+
return defineWsHandlers({ [require_collectUint8StreamText.WS_METHODS.serverGetStatistics]: (_input) => observeRpcEffect(require_collectUint8StreamText.WS_METHODS.serverGetStatistics, ownerEffect(require_collectUint8StreamText.WS_METHODS.serverGetStatistics, statisticsQuery.getStatistics().pipe(effect.Effect.orDie)), { "rpc.aggregate": "server" }) });
|
|
35519
|
+
};
|
|
35520
|
+
//#endregion
|
|
35007
35521
|
//#region src/ws/index.ts
|
|
35008
35522
|
const makeWsRpcLayer = (session) => require_collectUint8StreamText.WsRpcGroup.toLayer(effect.Effect.gen(function* () {
|
|
35009
35523
|
const ctx = yield* makeWsRpcContext(session);
|
|
35010
35524
|
return require_collectUint8StreamText.WsRpcGroup.of({
|
|
35011
35525
|
...makeOrchestrationHandlers(ctx),
|
|
35012
35526
|
...makeProviderHandlers(ctx),
|
|
35527
|
+
...makeStatisticsHandlers(ctx),
|
|
35013
35528
|
...makeSourceControlHandlers(ctx),
|
|
35014
35529
|
...makeProjectHandlers(ctx),
|
|
35015
35530
|
...makeGitHandlers(ctx),
|
|
@@ -35100,7 +35615,7 @@ const TelemetryEnvConfig = effect.Config.all({
|
|
|
35100
35615
|
maxBufferedEvents: effect.Config.number("RYCO_TELEMETRY_MAX_BUFFERED_EVENTS").pipe(effect.Config.withDefault(1e3))
|
|
35101
35616
|
});
|
|
35102
35617
|
const makeAnalyticsService = effect.Effect.gen(function* () {
|
|
35103
|
-
const telemetryConfig = yield* TelemetryEnvConfig
|
|
35618
|
+
const telemetryConfig = yield* TelemetryEnvConfig;
|
|
35104
35619
|
const httpClient = yield* effect_unstable_http.HttpClient.HttpClient;
|
|
35105
35620
|
const serverConfig = yield* require_Metrics.ServerConfig;
|
|
35106
35621
|
const identifier = yield* getTelemetryIdentifier;
|
|
@@ -37427,6 +37942,8 @@ const DEFAULT_PERSIST_DEBOUNCE_MS = 40;
|
|
|
37427
37942
|
const DEFAULT_SUBPROCESS_POLL_INTERVAL_MS = 1e3;
|
|
37428
37943
|
const DEFAULT_PROCESS_KILL_GRACE_MS = 1e3;
|
|
37429
37944
|
const DEFAULT_MAX_RETAINED_INACTIVE_SESSIONS = 128;
|
|
37945
|
+
const DEFAULT_MAX_PENDING_PROCESS_EVENTS = 2048;
|
|
37946
|
+
const DEFAULT_MAX_PENDING_PROCESS_OUTPUT_BYTES = 2 * 1024 * 1024;
|
|
37430
37947
|
const DEFAULT_OPEN_COLS = 120;
|
|
37431
37948
|
const DEFAULT_OPEN_ROWS = 30;
|
|
37432
37949
|
const TERMINAL_ENV_BLOCKLIST = new Set([
|
|
@@ -37483,13 +38000,86 @@ function cleanupProcessHandles(session) {
|
|
|
37483
38000
|
session.unsubscribeExit?.();
|
|
37484
38001
|
session.unsubscribeExit = null;
|
|
37485
38002
|
}
|
|
37486
|
-
function
|
|
38003
|
+
function clearPendingProcessEvents(session) {
|
|
38004
|
+
session.pendingProcessEvents = [];
|
|
38005
|
+
session.pendingProcessEventIndex = 0;
|
|
38006
|
+
session.pendingProcessOutputBytes = 0;
|
|
38007
|
+
session.processEventDrainRunning = false;
|
|
38008
|
+
}
|
|
38009
|
+
function enqueueProcessEvent(session, expectedPid, event, limits) {
|
|
37487
38010
|
if (!session.process || session.status !== "running" || session.pid !== expectedPid) return false;
|
|
38011
|
+
if (event.type === "output" && session.pendingProcessEvents.some((pendingEvent) => pendingEvent.type === "exit")) return false;
|
|
38012
|
+
compactPendingProcessEvents(session);
|
|
37488
38013
|
session.pendingProcessEvents.push(event);
|
|
38014
|
+
if (event.type === "output") session.pendingProcessOutputBytes += event.byteLength;
|
|
38015
|
+
enforcePendingProcessEventLimits(session, limits);
|
|
37489
38016
|
if (session.processEventDrainRunning) return false;
|
|
37490
38017
|
session.processEventDrainRunning = true;
|
|
37491
38018
|
return true;
|
|
37492
38019
|
}
|
|
38020
|
+
function compactPendingProcessEvents(session) {
|
|
38021
|
+
if (session.pendingProcessEventIndex <= 0) return;
|
|
38022
|
+
session.pendingProcessEvents = session.pendingProcessEvents.slice(session.pendingProcessEventIndex);
|
|
38023
|
+
session.pendingProcessEventIndex = 0;
|
|
38024
|
+
}
|
|
38025
|
+
function coalesceOldestPendingOutputPair(session) {
|
|
38026
|
+
for (let index = 0; index < session.pendingProcessEvents.length - 1; index += 1) {
|
|
38027
|
+
const current = session.pendingProcessEvents[index];
|
|
38028
|
+
const next = session.pendingProcessEvents[index + 1];
|
|
38029
|
+
if (current?.type !== "output" || next?.type !== "output") continue;
|
|
38030
|
+
session.pendingProcessEvents.splice(index, 2, {
|
|
38031
|
+
type: "output",
|
|
38032
|
+
data: `${current.data}${next.data}`,
|
|
38033
|
+
byteLength: current.byteLength + next.byteLength
|
|
38034
|
+
});
|
|
38035
|
+
return true;
|
|
38036
|
+
}
|
|
38037
|
+
return false;
|
|
38038
|
+
}
|
|
38039
|
+
function trimOutputDataToApproxBytes(data, maxBytes) {
|
|
38040
|
+
if (maxBytes <= 0 || data.length === 0) return {
|
|
38041
|
+
data: "",
|
|
38042
|
+
byteLength: 0
|
|
38043
|
+
};
|
|
38044
|
+
let nextData = data;
|
|
38045
|
+
let byteLength = approximateTextBytes(nextData);
|
|
38046
|
+
while (byteLength > maxBytes && nextData.length > 0) {
|
|
38047
|
+
const excessBytes = byteLength - maxBytes;
|
|
38048
|
+
const sliceStart = Math.min(nextData.length, Math.max(1, excessBytes));
|
|
38049
|
+
nextData = nextData.slice(sliceStart);
|
|
38050
|
+
byteLength = approximateTextBytes(nextData);
|
|
38051
|
+
}
|
|
38052
|
+
return {
|
|
38053
|
+
data: nextData,
|
|
38054
|
+
byteLength
|
|
38055
|
+
};
|
|
38056
|
+
}
|
|
38057
|
+
function trimPendingOutputBytesToLimit(session, maxPendingProcessOutputBytes) {
|
|
38058
|
+
if (session.pendingProcessOutputBytes <= maxPendingProcessOutputBytes) return;
|
|
38059
|
+
for (let index = 0; index < session.pendingProcessEvents.length; index += 1) {
|
|
38060
|
+
if (session.pendingProcessOutputBytes <= maxPendingProcessOutputBytes) return;
|
|
38061
|
+
const event = session.pendingProcessEvents[index];
|
|
38062
|
+
if (event?.type !== "output") continue;
|
|
38063
|
+
const targetEventBytes = Math.max(0, event.byteLength - (session.pendingProcessOutputBytes - maxPendingProcessOutputBytes));
|
|
38064
|
+
if (targetEventBytes <= 0) {
|
|
38065
|
+
session.pendingProcessEvents.splice(index, 1);
|
|
38066
|
+
session.pendingProcessOutputBytes = Math.max(0, session.pendingProcessOutputBytes - event.byteLength);
|
|
38067
|
+
index -= 1;
|
|
38068
|
+
continue;
|
|
38069
|
+
}
|
|
38070
|
+
const trimmed = trimOutputDataToApproxBytes(event.data, targetEventBytes);
|
|
38071
|
+
session.pendingProcessEvents[index] = {
|
|
38072
|
+
type: "output",
|
|
38073
|
+
data: trimmed.data,
|
|
38074
|
+
byteLength: trimmed.byteLength
|
|
38075
|
+
};
|
|
38076
|
+
session.pendingProcessOutputBytes = Math.max(0, session.pendingProcessOutputBytes - (event.byteLength - trimmed.byteLength));
|
|
38077
|
+
}
|
|
38078
|
+
}
|
|
38079
|
+
function enforcePendingProcessEventLimits(session, limits) {
|
|
38080
|
+
while (session.pendingProcessEvents.length > limits.maxPendingProcessEvents && coalesceOldestPendingOutputPair(session));
|
|
38081
|
+
trimPendingOutputBytesToLimit(session, limits.maxPendingProcessOutputBytes);
|
|
38082
|
+
}
|
|
37493
38083
|
function defaultShellResolver(platform = process.platform, env = process.env) {
|
|
37494
38084
|
if (platform === "win32") return "pwsh.exe";
|
|
37495
38085
|
return env.SHELL ?? "bash";
|
|
@@ -37856,6 +38446,10 @@ const makeTerminalManagerWithOptions = effect.Effect.fn("makeTerminalManagerWith
|
|
|
37856
38446
|
const subprocessPollIntervalMs = options.subprocessPollIntervalMs ?? DEFAULT_SUBPROCESS_POLL_INTERVAL_MS;
|
|
37857
38447
|
const processKillGraceMs = options.processKillGraceMs ?? DEFAULT_PROCESS_KILL_GRACE_MS;
|
|
37858
38448
|
const maxRetainedInactiveSessions = options.maxRetainedInactiveSessions ?? DEFAULT_MAX_RETAINED_INACTIVE_SESSIONS;
|
|
38449
|
+
const pendingProcessEventLimits = {
|
|
38450
|
+
maxPendingProcessEvents: Math.max(1, options.maxPendingProcessEvents ?? DEFAULT_MAX_PENDING_PROCESS_EVENTS),
|
|
38451
|
+
maxPendingProcessOutputBytes: Math.max(1, options.maxPendingProcessOutputBytes ?? DEFAULT_MAX_PENDING_PROCESS_OUTPUT_BYTES)
|
|
38452
|
+
};
|
|
37859
38453
|
yield* fileSystem.makeDirectory(logsDir, { recursive: true }).pipe(effect.Effect.orDie);
|
|
37860
38454
|
const managerStateRef = yield* effect.SynchronizedRef.make({
|
|
37861
38455
|
sessions: /* @__PURE__ */ new Map(),
|
|
@@ -38092,16 +38686,12 @@ const makeTerminalManagerWithOptions = effect.Effect.fn("makeTerminalManagerWith
|
|
|
38092
38686
|
while (true) {
|
|
38093
38687
|
const action = yield* effect.Effect.sync(() => {
|
|
38094
38688
|
if (session.pid !== expectedPid || !session.process || session.status !== "running") {
|
|
38095
|
-
session
|
|
38096
|
-
session.pendingProcessEventIndex = 0;
|
|
38097
|
-
session.processEventDrainRunning = false;
|
|
38689
|
+
clearPendingProcessEvents(session);
|
|
38098
38690
|
return { type: "idle" };
|
|
38099
38691
|
}
|
|
38100
38692
|
const nextEvent = session.pendingProcessEvents[session.pendingProcessEventIndex];
|
|
38101
38693
|
if (!nextEvent) {
|
|
38102
|
-
session
|
|
38103
|
-
session.pendingProcessEventIndex = 0;
|
|
38104
|
-
session.processEventDrainRunning = false;
|
|
38694
|
+
clearPendingProcessEvents(session);
|
|
38105
38695
|
return { type: "idle" };
|
|
38106
38696
|
}
|
|
38107
38697
|
session.pendingProcessEventIndex += 1;
|
|
@@ -38110,6 +38700,7 @@ const makeTerminalManagerWithOptions = effect.Effect.fn("makeTerminalManagerWith
|
|
|
38110
38700
|
session.pendingProcessEventIndex = 0;
|
|
38111
38701
|
}
|
|
38112
38702
|
if (nextEvent.type === "output") {
|
|
38703
|
+
session.pendingProcessOutputBytes = Math.max(0, session.pendingProcessOutputBytes - nextEvent.byteLength);
|
|
38113
38704
|
const sanitized = sanitizeTerminalHistoryChunk(session.pendingHistoryControlSequence, nextEvent.data);
|
|
38114
38705
|
session.pendingHistoryControlSequence = sanitized.pendingControlSequence;
|
|
38115
38706
|
if (sanitized.visibleText.length > 0) session.history = capHistory(`${session.history}${sanitized.visibleText}`, historyLineLimit);
|
|
@@ -38129,9 +38720,7 @@ const makeTerminalManagerWithOptions = effect.Effect.fn("makeTerminalManagerWith
|
|
|
38129
38720
|
session.hasRunningSubprocess = false;
|
|
38130
38721
|
session.status = "exited";
|
|
38131
38722
|
session.pendingHistoryControlSequence = "";
|
|
38132
|
-
session
|
|
38133
|
-
session.pendingProcessEventIndex = 0;
|
|
38134
|
-
session.processEventDrainRunning = false;
|
|
38723
|
+
clearPendingProcessEvents(session);
|
|
38135
38724
|
session.exitCode = Number.isInteger(nextEvent.event.exitCode) ? nextEvent.event.exitCode : null;
|
|
38136
38725
|
session.exitSignal = Number.isInteger(nextEvent.event.signal) ? nextEvent.event.signal : null;
|
|
38137
38726
|
session.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -38179,9 +38768,7 @@ const makeTerminalManagerWithOptions = effect.Effect.fn("makeTerminalManagerWith
|
|
|
38179
38768
|
session.hasRunningSubprocess = false;
|
|
38180
38769
|
session.status = "exited";
|
|
38181
38770
|
session.pendingHistoryControlSequence = "";
|
|
38182
|
-
session
|
|
38183
|
-
session.pendingProcessEventIndex = 0;
|
|
38184
|
-
session.processEventDrainRunning = false;
|
|
38771
|
+
clearPendingProcessEvents(session);
|
|
38185
38772
|
session.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
38186
38773
|
return [void 0, state];
|
|
38187
38774
|
});
|
|
@@ -38233,9 +38820,7 @@ const makeTerminalManagerWithOptions = effect.Effect.fn("makeTerminalManagerWith
|
|
|
38233
38820
|
session.exitCode = null;
|
|
38234
38821
|
session.exitSignal = null;
|
|
38235
38822
|
session.hasRunningSubprocess = false;
|
|
38236
|
-
session
|
|
38237
|
-
session.pendingProcessEventIndex = 0;
|
|
38238
|
-
session.processEventDrainRunning = false;
|
|
38823
|
+
clearPendingProcessEvents(session);
|
|
38239
38824
|
session.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
38240
38825
|
return [void 0, state];
|
|
38241
38826
|
});
|
|
@@ -38249,15 +38834,16 @@ const makeTerminalManagerWithOptions = effect.Effect.fn("makeTerminalManagerWith
|
|
|
38249
38834
|
const unsubscribeData = ptyProcess.onData((data) => {
|
|
38250
38835
|
if (!enqueueProcessEvent(session, processPid, {
|
|
38251
38836
|
type: "output",
|
|
38252
|
-
data
|
|
38253
|
-
|
|
38837
|
+
data,
|
|
38838
|
+
byteLength: approximateTextBytes(data)
|
|
38839
|
+
}, pendingProcessEventLimits)) return;
|
|
38254
38840
|
runFork(drainProcessEvents(session, processPid));
|
|
38255
38841
|
});
|
|
38256
38842
|
const unsubscribeExit = ptyProcess.onExit((event) => {
|
|
38257
38843
|
if (!enqueueProcessEvent(session, processPid, {
|
|
38258
38844
|
type: "exit",
|
|
38259
38845
|
event
|
|
38260
|
-
})) return;
|
|
38846
|
+
}, pendingProcessEventLimits)) return;
|
|
38261
38847
|
runFork(drainProcessEvents(session, processPid));
|
|
38262
38848
|
});
|
|
38263
38849
|
yield* modifyManagerState((state) => {
|
|
@@ -38289,9 +38875,7 @@ const makeTerminalManagerWithOptions = effect.Effect.fn("makeTerminalManagerWith
|
|
|
38289
38875
|
session.unsubscribeData = null;
|
|
38290
38876
|
session.unsubscribeExit = null;
|
|
38291
38877
|
session.hasRunningSubprocess = false;
|
|
38292
|
-
session
|
|
38293
|
-
session.pendingProcessEventIndex = 0;
|
|
38294
|
-
session.processEventDrainRunning = false;
|
|
38878
|
+
clearPendingProcessEvents(session);
|
|
38295
38879
|
session.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
38296
38880
|
return [void 0, state];
|
|
38297
38881
|
});
|
|
@@ -38401,6 +38985,7 @@ const makeTerminalManagerWithOptions = effect.Effect.fn("makeTerminalManagerWith
|
|
|
38401
38985
|
pendingHistoryControlSequence: "",
|
|
38402
38986
|
pendingProcessEvents: [],
|
|
38403
38987
|
pendingProcessEventIndex: 0,
|
|
38988
|
+
pendingProcessOutputBytes: 0,
|
|
38404
38989
|
processEventDrainRunning: false,
|
|
38405
38990
|
exitCode: null,
|
|
38406
38991
|
exitSignal: null,
|
|
@@ -38447,18 +39032,14 @@ const makeTerminalManagerWithOptions = effect.Effect.fn("makeTerminalManagerWith
|
|
|
38447
39032
|
liveSession.runtimeEnv = nextRuntimeEnv;
|
|
38448
39033
|
liveSession.history = "";
|
|
38449
39034
|
liveSession.pendingHistoryControlSequence = "";
|
|
38450
|
-
liveSession
|
|
38451
|
-
liveSession.pendingProcessEventIndex = 0;
|
|
38452
|
-
liveSession.processEventDrainRunning = false;
|
|
39035
|
+
clearPendingProcessEvents(liveSession);
|
|
38453
39036
|
yield* persistHistory(liveSession.threadId, liveSession.terminalId, liveSession.history);
|
|
38454
39037
|
} else if (liveSession.status === "exited" || liveSession.status === "error") {
|
|
38455
39038
|
liveSession.runtimeEnv = nextRuntimeEnv;
|
|
38456
39039
|
liveSession.worktreePath = input.worktreePath ?? null;
|
|
38457
39040
|
liveSession.history = "";
|
|
38458
39041
|
liveSession.pendingHistoryControlSequence = "";
|
|
38459
|
-
liveSession
|
|
38460
|
-
liveSession.pendingProcessEventIndex = 0;
|
|
38461
|
-
liveSession.processEventDrainRunning = false;
|
|
39042
|
+
clearPendingProcessEvents(liveSession);
|
|
38462
39043
|
yield* persistHistory(liveSession.threadId, liveSession.terminalId, liveSession.history);
|
|
38463
39044
|
}
|
|
38464
39045
|
if (!liveSession.process) {
|
|
@@ -38512,9 +39093,7 @@ const makeTerminalManagerWithOptions = effect.Effect.fn("makeTerminalManagerWith
|
|
|
38512
39093
|
const session = yield* requireSession(input.threadId, terminalId);
|
|
38513
39094
|
session.history = "";
|
|
38514
39095
|
session.pendingHistoryControlSequence = "";
|
|
38515
|
-
session
|
|
38516
|
-
session.pendingProcessEventIndex = 0;
|
|
38517
|
-
session.processEventDrainRunning = false;
|
|
39096
|
+
clearPendingProcessEvents(session);
|
|
38518
39097
|
session.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
38519
39098
|
yield* persistHistory(input.threadId, terminalId, session.history);
|
|
38520
39099
|
yield* publishEvent({
|
|
@@ -38545,6 +39124,7 @@ const makeTerminalManagerWithOptions = effect.Effect.fn("makeTerminalManagerWith
|
|
|
38545
39124
|
pendingHistoryControlSequence: "",
|
|
38546
39125
|
pendingProcessEvents: [],
|
|
38547
39126
|
pendingProcessEventIndex: 0,
|
|
39127
|
+
pendingProcessOutputBytes: 0,
|
|
38548
39128
|
processEventDrainRunning: false,
|
|
38549
39129
|
exitCode: null,
|
|
38550
39130
|
exitSignal: null,
|
|
@@ -38578,9 +39158,7 @@ const makeTerminalManagerWithOptions = effect.Effect.fn("makeTerminalManagerWith
|
|
|
38578
39158
|
const rows = input.rows ?? session.rows;
|
|
38579
39159
|
session.history = "";
|
|
38580
39160
|
session.pendingHistoryControlSequence = "";
|
|
38581
|
-
session
|
|
38582
|
-
session.pendingProcessEventIndex = 0;
|
|
38583
|
-
session.processEventDrainRunning = false;
|
|
39161
|
+
clearPendingProcessEvents(session);
|
|
38584
39162
|
yield* persistHistory(input.threadId, terminalId, session.history);
|
|
38585
39163
|
yield* startSession(session, {
|
|
38586
39164
|
threadId: input.threadId,
|
|
@@ -38602,6 +39180,7 @@ const makeTerminalManagerWithOptions = effect.Effect.fn("makeTerminalManagerWith
|
|
|
38602
39180
|
yield* effect.Effect.forEach(threadSessions, (session) => closeSession(input.threadId, session.terminalId, false), { discard: true });
|
|
38603
39181
|
if (input.deleteHistory) yield* deleteAllHistoryForThread(input.threadId);
|
|
38604
39182
|
}));
|
|
39183
|
+
const listSessions = effect.SynchronizedRef.get(managerStateRef).pipe(effect.Effect.map((state) => [...state.sessions.values()].map(snapshot).toSorted((left, right) => right.updatedAt.localeCompare(left.updatedAt))));
|
|
38605
39184
|
return {
|
|
38606
39185
|
open,
|
|
38607
39186
|
write,
|
|
@@ -38610,6 +39189,7 @@ const makeTerminalManagerWithOptions = effect.Effect.fn("makeTerminalManagerWith
|
|
|
38610
39189
|
restart,
|
|
38611
39190
|
close,
|
|
38612
39191
|
listDiagnostics: effect.SynchronizedRef.get(managerStateRef).pipe(effect.Effect.map((state) => [...state.sessions.values()].map(diagnosticsSnapshot).toSorted((left, right) => right.updatedAt.localeCompare(left.updatedAt)))),
|
|
39192
|
+
listSessions,
|
|
38613
39193
|
subscribe: (listener) => effect.Effect.sync(() => {
|
|
38614
39194
|
terminalEventListeners.add(listener);
|
|
38615
39195
|
return () => {
|
|
@@ -39105,7 +39685,7 @@ function isGitRepository(cwd) {
|
|
|
39105
39685
|
//#endregion
|
|
39106
39686
|
//#region src/orchestration/Layers/ProviderRuntimeIngestion.ts
|
|
39107
39687
|
const providerTurnKey = (threadId, turnId) => `${threadId}:${turnId}`;
|
|
39108
|
-
const providerCommandId = (event, tag) => require_collectUint8StreamText.CommandId.make(`provider:${event.eventId}:${tag}:${
|
|
39688
|
+
const providerCommandId = (event, tag, discriminator) => require_collectUint8StreamText.CommandId.make(discriminator === void 0 ? `provider:${event.eventId}:${tag}` : `provider:${event.eventId}:${tag}:${discriminator}`);
|
|
39109
39689
|
const liveAssistantDeltaBufferKey = (threadId, messageId) => `${threadId}:${messageId}`;
|
|
39110
39690
|
const TURN_MESSAGE_IDS_BY_TURN_CACHE_CAPACITY = 1e4;
|
|
39111
39691
|
const TURN_MESSAGE_IDS_BY_TURN_TTL = effect.Duration.minutes(120);
|
|
@@ -39179,6 +39759,7 @@ function rawPayloadThreadId(event) {
|
|
|
39179
39759
|
return asTrimmedString(asRecord(event.raw?.payload)?.threadId);
|
|
39180
39760
|
}
|
|
39181
39761
|
function collabReceiverThreadIdsFromRuntimeEvent(event) {
|
|
39762
|
+
if (event.type === "subagent.started" || event.type === "subagent.updated" || event.type === "subagent.completed") return event.payload.subagent.providerThreadId ? [event.payload.subagent.providerThreadId] : [];
|
|
39182
39763
|
if (event.type !== "item.started" && event.type !== "item.updated" && event.type !== "item.completed") return [];
|
|
39183
39764
|
if (event.payload.itemType !== "collab_agent_tool_call") return [];
|
|
39184
39765
|
const item = asRecord(asRecord(event.payload.data)?.item);
|
|
@@ -39236,6 +39817,9 @@ function normalizeRuntimeTurnState(value) {
|
|
|
39236
39817
|
default: return "completed";
|
|
39237
39818
|
}
|
|
39238
39819
|
}
|
|
39820
|
+
function isTerminalProjectionTurnState(state) {
|
|
39821
|
+
return state === "completed" || state === "error" || state === "interrupted";
|
|
39822
|
+
}
|
|
39239
39823
|
function orchestrationSessionStatusFromRuntimeState(state) {
|
|
39240
39824
|
switch (state) {
|
|
39241
39825
|
case "starting": return "starting";
|
|
@@ -39423,6 +40007,53 @@ function runtimeEventToActivities(event) {
|
|
|
39423
40007
|
turnId: toTurnId$1(event.turnId) ?? null,
|
|
39424
40008
|
...maybeSequence
|
|
39425
40009
|
}];
|
|
40010
|
+
case "subagent.started": return [{
|
|
40011
|
+
id: event.eventId,
|
|
40012
|
+
createdAt: event.createdAt,
|
|
40013
|
+
tone: "tool",
|
|
40014
|
+
kind: "subagent.started",
|
|
40015
|
+
summary: `${event.payload.subagent.label ?? "Subagent"} started`,
|
|
40016
|
+
payload: {
|
|
40017
|
+
itemType: "collab_agent_tool_call",
|
|
40018
|
+
status: "running",
|
|
40019
|
+
subagent: event.payload.subagent
|
|
40020
|
+
},
|
|
40021
|
+
turnId: toTurnId$1(event.turnId) ?? null,
|
|
40022
|
+
...maybeSequence
|
|
40023
|
+
}];
|
|
40024
|
+
case "subagent.updated": return [{
|
|
40025
|
+
id: event.eventId,
|
|
40026
|
+
createdAt: event.createdAt,
|
|
40027
|
+
tone: "tool",
|
|
40028
|
+
kind: "subagent.updated",
|
|
40029
|
+
summary: event.payload.summary ?? `${event.payload.subagent.label ?? "Subagent"} updated`,
|
|
40030
|
+
payload: {
|
|
40031
|
+
itemType: "collab_agent_tool_call",
|
|
40032
|
+
...event.payload.status ? { status: event.payload.status } : {},
|
|
40033
|
+
subagent: event.payload.subagent,
|
|
40034
|
+
...event.payload.detail ? { detail: truncateDetail(event.payload.detail) } : {},
|
|
40035
|
+
...event.payload.summary ? { summary: truncateDetail(event.payload.summary) } : {},
|
|
40036
|
+
...event.payload.usage !== void 0 ? { usage: event.payload.usage } : {}
|
|
40037
|
+
},
|
|
40038
|
+
turnId: toTurnId$1(event.turnId) ?? null,
|
|
40039
|
+
...maybeSequence
|
|
40040
|
+
}];
|
|
40041
|
+
case "subagent.completed": return [{
|
|
40042
|
+
id: event.eventId,
|
|
40043
|
+
createdAt: event.createdAt,
|
|
40044
|
+
tone: event.payload.status === "failed" ? "error" : "tool",
|
|
40045
|
+
kind: "subagent.completed",
|
|
40046
|
+
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`,
|
|
40047
|
+
payload: {
|
|
40048
|
+
itemType: "collab_agent_tool_call",
|
|
40049
|
+
status: event.payload.status,
|
|
40050
|
+
subagent: event.payload.subagent,
|
|
40051
|
+
...event.payload.summary ? { detail: truncateDetail(event.payload.summary) } : {},
|
|
40052
|
+
...event.payload.usage !== void 0 ? { usage: event.payload.usage } : {}
|
|
40053
|
+
},
|
|
40054
|
+
turnId: toTurnId$1(event.turnId) ?? null,
|
|
40055
|
+
...maybeSequence
|
|
40056
|
+
}];
|
|
39426
40057
|
case "thread.state.changed":
|
|
39427
40058
|
if (event.payload.state !== "compacted") return [];
|
|
39428
40059
|
return [{
|
|
@@ -39615,7 +40246,7 @@ const make$3 = effect.Effect.gen(function* () {
|
|
|
39615
40246
|
}
|
|
39616
40247
|
yield* orchestrationEngine.dispatch({
|
|
39617
40248
|
type: "thread.message.assistant.delta",
|
|
39618
|
-
commandId: providerCommandId(buffer.event, input.commandTag),
|
|
40249
|
+
commandId: providerCommandId(buffer.event, input.commandTag, String(buffer.messageId)),
|
|
39619
40250
|
threadId: buffer.threadId,
|
|
39620
40251
|
messageId: buffer.messageId,
|
|
39621
40252
|
delta: buffer.text,
|
|
@@ -39694,9 +40325,10 @@ const make$3 = effect.Effect.gen(function* () {
|
|
|
39694
40325
|
};
|
|
39695
40326
|
const upsertSubagentMessageActivity = (input) => effect.Effect.gen(function* () {
|
|
39696
40327
|
const sessionSequence = input.event.sessionSequence;
|
|
40328
|
+
const commandKey = `${input.providerThreadId}:${input.providerItemId}`;
|
|
39697
40329
|
yield* orchestrationEngine.dispatch({
|
|
39698
40330
|
type: "thread.activity.append",
|
|
39699
|
-
commandId: providerCommandId(input.event, "subagent-message-upsert"),
|
|
40331
|
+
commandId: providerCommandId(input.event, "subagent-message-upsert", commandKey),
|
|
39700
40332
|
threadId: input.threadId,
|
|
39701
40333
|
activity: {
|
|
39702
40334
|
id: subagentMessageActivityId({
|
|
@@ -39714,6 +40346,7 @@ const make$3 = effect.Effect.gen(function* () {
|
|
|
39714
40346
|
streaming: input.streaming,
|
|
39715
40347
|
providerThreadId: input.providerThreadId,
|
|
39716
40348
|
providerItemId: input.providerItemId,
|
|
40349
|
+
...input.subagentId ? { subagentId: input.subagentId } : {},
|
|
39717
40350
|
...input.event.providerRefs ? { providerRefs: input.event.providerRefs } : {}
|
|
39718
40351
|
},
|
|
39719
40352
|
turnId: toTurnId$1(input.event.turnId) ?? null,
|
|
@@ -39753,6 +40386,16 @@ const make$3 = effect.Effect.gen(function* () {
|
|
|
39753
40386
|
streaming: false
|
|
39754
40387
|
});
|
|
39755
40388
|
});
|
|
40389
|
+
const bufferedSubagentProviderItemIds = (input) => {
|
|
40390
|
+
const prefix = subagentMessageBufferKey({
|
|
40391
|
+
threadId: input.threadId,
|
|
40392
|
+
providerThreadId: input.providerThreadId,
|
|
40393
|
+
providerItemId: ""
|
|
40394
|
+
});
|
|
40395
|
+
const providerItemIds = /* @__PURE__ */ new Set();
|
|
40396
|
+
for (const key of subagentMessageTextByKey.keys()) if (key.startsWith(prefix)) providerItemIds.add(key.slice(prefix.length));
|
|
40397
|
+
return [...providerItemIds];
|
|
40398
|
+
};
|
|
39756
40399
|
const clearSubagentMessageBuffersForThread = (threadId) => effect.Effect.sync(() => {
|
|
39757
40400
|
const prefix = `${threadId}:`;
|
|
39758
40401
|
for (const key of subagentMessageTextByKey.keys()) if (key.startsWith(prefix)) subagentMessageTextByKey.delete(key);
|
|
@@ -39786,7 +40429,7 @@ const make$3 = effect.Effect.gen(function* () {
|
|
|
39786
40429
|
if (!hasRenderableAssistantText(bufferedText)) return false;
|
|
39787
40430
|
yield* orchestrationEngine.dispatch({
|
|
39788
40431
|
type: "thread.message.assistant.delta",
|
|
39789
|
-
commandId: providerCommandId(input.event, input.commandTag),
|
|
40432
|
+
commandId: providerCommandId(input.event, input.commandTag, String(input.messageId)),
|
|
39790
40433
|
threadId: input.threadId,
|
|
39791
40434
|
messageId: input.messageId,
|
|
39792
40435
|
delta: bufferedText,
|
|
@@ -39814,7 +40457,7 @@ const make$3 = effect.Effect.gen(function* () {
|
|
|
39814
40457
|
const hasRenderableText = hasRenderableAssistantText(text);
|
|
39815
40458
|
if (hasRenderableText) yield* orchestrationEngine.dispatch({
|
|
39816
40459
|
type: "thread.message.assistant.delta",
|
|
39817
|
-
commandId: providerCommandId(input.event, input.finalDeltaCommandTag),
|
|
40460
|
+
commandId: providerCommandId(input.event, input.finalDeltaCommandTag, String(input.messageId)),
|
|
39818
40461
|
threadId: input.threadId,
|
|
39819
40462
|
messageId: input.messageId,
|
|
39820
40463
|
delta: text,
|
|
@@ -39823,7 +40466,7 @@ const make$3 = effect.Effect.gen(function* () {
|
|
|
39823
40466
|
});
|
|
39824
40467
|
if (input.hasProjectedMessage || hasRenderableText) yield* orchestrationEngine.dispatch({
|
|
39825
40468
|
type: "thread.message.assistant.complete",
|
|
39826
|
-
commandId: providerCommandId(input.event, input.commandTag),
|
|
40469
|
+
commandId: providerCommandId(input.event, input.commandTag, String(input.messageId)),
|
|
39827
40470
|
threadId: input.threadId,
|
|
39828
40471
|
messageId: input.messageId,
|
|
39829
40472
|
...input.turnId ? { turnId: input.turnId } : {},
|
|
@@ -39857,7 +40500,7 @@ const make$3 = effect.Effect.gen(function* () {
|
|
|
39857
40500
|
const existingPlan = findProposedPlanById(input.threadProposedPlans, input.planId);
|
|
39858
40501
|
yield* orchestrationEngine.dispatch({
|
|
39859
40502
|
type: "thread.proposed-plan.upsert",
|
|
39860
|
-
commandId: providerCommandId(input.event, "proposed-plan-upsert"),
|
|
40503
|
+
commandId: providerCommandId(input.event, "proposed-plan-upsert", input.planId),
|
|
39861
40504
|
threadId: input.threadId,
|
|
39862
40505
|
proposedPlan: {
|
|
39863
40506
|
id: input.planId,
|
|
@@ -39924,13 +40567,13 @@ const make$3 = effect.Effect.gen(function* () {
|
|
|
39924
40567
|
if (!sameId$1(yield* getExpectedProviderTurnIdForThread(threadId), eventTurnId)) return null;
|
|
39925
40568
|
return yield* getSourceProposedPlanReferenceForPendingTurnStart(threadId);
|
|
39926
40569
|
});
|
|
39927
|
-
const markSourceProposedPlanImplemented = effect.Effect.fn("markSourceProposedPlanImplemented")(function* (sourceThreadId, sourcePlanId, implementationThreadId, implementedAt) {
|
|
40570
|
+
const markSourceProposedPlanImplemented = effect.Effect.fn("markSourceProposedPlanImplemented")(function* (event, sourceThreadId, sourcePlanId, implementationThreadId, implementedAt) {
|
|
39928
40571
|
const sourceThread = yield* resolveThreadDetail(sourceThreadId);
|
|
39929
40572
|
const sourcePlan = sourceThread?.proposedPlans.find((entry) => entry.id === sourcePlanId);
|
|
39930
40573
|
if (!sourceThread || !sourcePlan || sourcePlan.implementedAt !== null) return;
|
|
39931
40574
|
yield* orchestrationEngine.dispatch({
|
|
39932
40575
|
type: "thread.proposed-plan.upsert",
|
|
39933
|
-
commandId:
|
|
40576
|
+
commandId: providerCommandId(event, "source-proposed-plan-implemented", `${sourceThreadId}:${sourcePlanId}:${implementationThreadId}`),
|
|
39934
40577
|
threadId: sourceThread.id,
|
|
39935
40578
|
proposedPlan: {
|
|
39936
40579
|
...sourcePlan,
|
|
@@ -39955,6 +40598,12 @@ const make$3 = effect.Effect.gen(function* () {
|
|
|
39955
40598
|
const activeTurnId = thread.session?.activeTurnId ?? null;
|
|
39956
40599
|
const conflictsWithActiveTurn = activeTurnId !== null && eventTurnId !== void 0 && !sameId$1(activeTurnId, eventTurnId);
|
|
39957
40600
|
const missingTurnForActiveTurn = activeTurnId !== null && eventTurnId === void 0;
|
|
40601
|
+
const existingEventTurn = event.type === "turn.started" && eventTurnId !== void 0 ? yield* projectionTurnRepository.getByTurnId({
|
|
40602
|
+
threadId: thread.id,
|
|
40603
|
+
turnId: eventTurnId
|
|
40604
|
+
}) : effect.Option.none();
|
|
40605
|
+
const eventTurnAlreadyTerminal = effect.Option.isSome(existingEventTurn) && isTerminalProjectionTurnState(existingEventTurn.value.state);
|
|
40606
|
+
const eventTurnAlreadyProjectedWithoutActiveSession = activeTurnId === null && effect.Option.isSome(existingEventTurn);
|
|
39958
40607
|
if (!isAssistantTextDeltaEvent(event)) yield* flushLiveAssistantDeltaBuffersSafely({ commandTag: "assistant-delta-flush-before-runtime-event" });
|
|
39959
40608
|
yield* rememberSubagentProviderThreadIds(thread.id, event);
|
|
39960
40609
|
const eventProviderThreadId = rawPayloadThreadId(event);
|
|
@@ -39965,8 +40614,9 @@ const make$3 = effect.Effect.gen(function* () {
|
|
|
39965
40614
|
case "session.exited": return true;
|
|
39966
40615
|
case "session.started":
|
|
39967
40616
|
case "thread.started": return true;
|
|
39968
|
-
case "turn.started": return !conflictsWithActiveTurn;
|
|
40617
|
+
case "turn.started": return !conflictsWithActiveTurn && !eventTurnAlreadyTerminal && !eventTurnAlreadyProjectedWithoutActiveSession;
|
|
39969
40618
|
case "turn.completed":
|
|
40619
|
+
case "turn.aborted":
|
|
39970
40620
|
if (conflictsWithActiveTurn || missingTurnForActiveTurn) return false;
|
|
39971
40621
|
if (activeTurnId !== null && eventTurnId !== void 0) return sameId$1(activeTurnId, eventTurnId);
|
|
39972
40622
|
return true;
|
|
@@ -39974,21 +40624,22 @@ const make$3 = effect.Effect.gen(function* () {
|
|
|
39974
40624
|
}
|
|
39975
40625
|
})();
|
|
39976
40626
|
const acceptedTurnStartedSourcePlan = event.type === "turn.started" && shouldApplyThreadLifecycle ? yield* getSourceProposedPlanReferenceForAcceptedTurnStart(thread.id, eventTurnId) : null;
|
|
39977
|
-
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") {
|
|
39978
|
-
const nextActiveTurnId = event.type === "turn.started" ? eventTurnId ?? null : event.type === "turn.completed" || event.type === "session.exited" ? null : activeTurnId;
|
|
40627
|
+
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") {
|
|
40628
|
+
const nextActiveTurnId = event.type === "turn.started" ? eventTurnId ?? null : event.type === "turn.completed" || event.type === "turn.aborted" || event.type === "session.exited" ? null : activeTurnId;
|
|
39979
40629
|
const status = (() => {
|
|
39980
40630
|
switch (event.type) {
|
|
39981
40631
|
case "session.state.changed": return orchestrationSessionStatusFromRuntimeState(event.payload.state);
|
|
39982
40632
|
case "turn.started": return "running";
|
|
39983
40633
|
case "session.exited": return "stopped";
|
|
39984
40634
|
case "turn.completed": return normalizeRuntimeTurnState(event.payload.state) === "failed" ? "error" : "ready";
|
|
40635
|
+
case "turn.aborted": return "ready";
|
|
39985
40636
|
case "session.started":
|
|
39986
40637
|
case "thread.started": return activeTurnId !== null ? "running" : "ready";
|
|
39987
40638
|
}
|
|
39988
40639
|
})();
|
|
39989
40640
|
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;
|
|
39990
40641
|
if (shouldApplyThreadLifecycle) {
|
|
39991
|
-
if (event.type === "turn.started" && acceptedTurnStartedSourcePlan !== null) yield* markSourceProposedPlanImplemented(acceptedTurnStartedSourcePlan.sourceThreadId, acceptedTurnStartedSourcePlan.sourcePlanId, thread.id, now).pipe(effect.Effect.catchCause((cause) => effect.Effect.logWarning("provider runtime ingestion failed to mark source proposed plan", {
|
|
40642
|
+
if (event.type === "turn.started" && acceptedTurnStartedSourcePlan !== null) yield* markSourceProposedPlanImplemented(event, acceptedTurnStartedSourcePlan.sourceThreadId, acceptedTurnStartedSourcePlan.sourcePlanId, thread.id, now).pipe(effect.Effect.catchCause((cause) => effect.Effect.logWarning("provider runtime ingestion failed to mark source proposed plan", {
|
|
39992
40643
|
eventId: event.eventId,
|
|
39993
40644
|
eventType: event.type,
|
|
39994
40645
|
cause: effect.Cause.pretty(cause)
|
|
@@ -40010,11 +40661,30 @@ const make$3 = effect.Effect.gen(function* () {
|
|
|
40010
40661
|
},
|
|
40011
40662
|
createdAt: now
|
|
40012
40663
|
});
|
|
40664
|
+
if (event.type === "turn.aborted" && eventTurnId !== void 0) yield* orchestrationEngine.dispatch({
|
|
40665
|
+
type: "thread.turn.interrupt",
|
|
40666
|
+
commandId: providerCommandId(event, "thread-turn-interrupt", String(eventTurnId)),
|
|
40667
|
+
threadId: thread.id,
|
|
40668
|
+
turnId: eventTurnId,
|
|
40669
|
+
createdAt: now
|
|
40670
|
+
});
|
|
40013
40671
|
}
|
|
40014
40672
|
}
|
|
40015
40673
|
const assistantDelta = isAssistantTextDeltaEvent(event) ? event.payload.delta : void 0;
|
|
40674
|
+
const subagentDelta = event.type === "subagent.message.delta" ? event.payload.delta : void 0;
|
|
40016
40675
|
const proposedPlanDelta = event.type === "turn.proposed.delta" ? event.payload.delta : void 0;
|
|
40017
|
-
if (
|
|
40676
|
+
if (event.type === "subagent.message.delta" && subagentDelta && subagentDelta.length > 0) {
|
|
40677
|
+
const subagentPayload = event.payload;
|
|
40678
|
+
yield* appendSubagentMessageDelta({
|
|
40679
|
+
event,
|
|
40680
|
+
threadId: thread.id,
|
|
40681
|
+
subagentId: String(subagentPayload.subagentId),
|
|
40682
|
+
providerThreadId: subagentPayload.providerThreadId ?? String(subagentPayload.subagentId),
|
|
40683
|
+
providerItemId: subagentPayload.providerMessageId ?? String(subagentPayload.subagentId),
|
|
40684
|
+
delta: subagentDelta,
|
|
40685
|
+
createdAt: now
|
|
40686
|
+
});
|
|
40687
|
+
} else if (assistantDelta && assistantDelta.length > 0 && isSubagentProviderThread && eventProviderThreadId) yield* appendSubagentMessageDelta({
|
|
40018
40688
|
event,
|
|
40019
40689
|
threadId: thread.id,
|
|
40020
40690
|
providerThreadId: eventProviderThreadId,
|
|
@@ -40034,7 +40704,7 @@ const make$3 = effect.Effect.gen(function* () {
|
|
|
40034
40704
|
const spillChunk = yield* appendBufferedAssistantText(assistantMessageId, assistantDelta);
|
|
40035
40705
|
if (spillChunk.length > 0) yield* orchestrationEngine.dispatch({
|
|
40036
40706
|
type: "thread.message.assistant.delta",
|
|
40037
|
-
commandId: providerCommandId(event, "assistant-delta-buffer-spill"),
|
|
40707
|
+
commandId: providerCommandId(event, "assistant-delta-buffer-spill", String(assistantMessageId)),
|
|
40038
40708
|
threadId: thread.id,
|
|
40039
40709
|
messageId: assistantMessageId,
|
|
40040
40710
|
delta: spillChunk,
|
|
@@ -40119,6 +40789,26 @@ const make$3 = effect.Effect.gen(function* () {
|
|
|
40119
40789
|
...subagentMessageCompletion.fallbackText !== void 0 ? { fallbackText: subagentMessageCompletion.fallbackText } : {},
|
|
40120
40790
|
createdAt: now
|
|
40121
40791
|
});
|
|
40792
|
+
if (event.type === "subagent.completed") {
|
|
40793
|
+
const subagentId = String(event.payload.subagent.subagentId);
|
|
40794
|
+
const providerThreadId = event.payload.subagent.providerThreadId ?? subagentId;
|
|
40795
|
+
const providerItemIds = bufferedSubagentProviderItemIds({
|
|
40796
|
+
threadId: thread.id,
|
|
40797
|
+
providerThreadId
|
|
40798
|
+
});
|
|
40799
|
+
yield* effect.Effect.forEach(providerItemIds.length > 0 ? providerItemIds : [subagentId], (providerItemId) => completeSubagentMessage({
|
|
40800
|
+
event,
|
|
40801
|
+
threadId: thread.id,
|
|
40802
|
+
subagentId,
|
|
40803
|
+
providerThreadId,
|
|
40804
|
+
providerItemId,
|
|
40805
|
+
...event.payload.summary !== void 0 ? { fallbackText: event.payload.summary } : {},
|
|
40806
|
+
createdAt: now
|
|
40807
|
+
}), {
|
|
40808
|
+
concurrency: 1,
|
|
40809
|
+
discard: true
|
|
40810
|
+
});
|
|
40811
|
+
}
|
|
40122
40812
|
if (proposedPlanCompletion) {
|
|
40123
40813
|
const detailedThread = yield* getLoadedThreadDetail();
|
|
40124
40814
|
yield* finalizeBufferedProposedPlan({
|
|
@@ -40131,7 +40821,7 @@ const make$3 = effect.Effect.gen(function* () {
|
|
|
40131
40821
|
updatedAt: now
|
|
40132
40822
|
});
|
|
40133
40823
|
}
|
|
40134
|
-
if (event.type === "turn.completed") {
|
|
40824
|
+
if (event.type === "turn.completed" || event.type === "turn.aborted") {
|
|
40135
40825
|
const detailedThread = yield* getLoadedThreadDetail();
|
|
40136
40826
|
const messages = detailedThread?.messages ?? [];
|
|
40137
40827
|
const proposedPlans = detailedThread?.proposedPlans ?? [];
|
|
@@ -40201,7 +40891,7 @@ const make$3 = effect.Effect.gen(function* () {
|
|
|
40201
40891
|
const assistantMessageId = require_collectUint8StreamText.MessageId.make(`assistant:${event.itemId ?? event.turnId ?? event.eventId}`);
|
|
40202
40892
|
yield* orchestrationEngine.dispatch({
|
|
40203
40893
|
type: "thread.turn.diff.complete",
|
|
40204
|
-
commandId: providerCommandId(event, "thread-turn-diff-complete"),
|
|
40894
|
+
commandId: providerCommandId(event, "thread-turn-diff-complete", String(turnId)),
|
|
40205
40895
|
threadId: thread.id,
|
|
40206
40896
|
turnId,
|
|
40207
40897
|
completedAt: now,
|
|
@@ -40217,7 +40907,7 @@ const make$3 = effect.Effect.gen(function* () {
|
|
|
40217
40907
|
const activities = runtimeEventToActivities(event);
|
|
40218
40908
|
yield* effect.Effect.forEach(activities, (activity) => orchestrationEngine.dispatch({
|
|
40219
40909
|
type: "thread.activity.append",
|
|
40220
|
-
commandId: providerCommandId(event, "thread-activity-append"),
|
|
40910
|
+
commandId: providerCommandId(event, "thread-activity-append", String(activity.id)),
|
|
40221
40911
|
threadId: thread.id,
|
|
40222
40912
|
activity,
|
|
40223
40913
|
createdAt: activity.createdAt
|
|
@@ -40281,6 +40971,7 @@ function mapProviderSessionStatusToOrchestrationStatus(status) {
|
|
|
40281
40971
|
}
|
|
40282
40972
|
const turnStartKeyForEvent = (event) => event.commandId !== null ? `command:${event.commandId}` : `event:${event.eventId}`;
|
|
40283
40973
|
const serverCommandId$1 = (tag) => require_collectUint8StreamText.CommandId.make(`server:${tag}:${crypto.randomUUID()}`);
|
|
40974
|
+
const isProviderOriginatedCommandId = (commandId) => commandId !== null && String(commandId).startsWith("provider:");
|
|
40284
40975
|
const HANDLED_TURN_START_KEY_MAX = 1e4;
|
|
40285
40976
|
const HANDLED_TURN_START_KEY_TTL = effect.Duration.minutes(30);
|
|
40286
40977
|
const DEFAULT_RUNTIME_MODE = "full-access";
|
|
@@ -40632,6 +41323,17 @@ const make$2 = effect.Effect.gen(function* () {
|
|
|
40632
41323
|
if (yield* hasHandledTurnStartRecently(turnStartKeyForEvent(event))) return;
|
|
40633
41324
|
const thread = yield* resolveThread(event.payload.threadId);
|
|
40634
41325
|
if (!thread) return;
|
|
41326
|
+
if (thread.session?.status === "running" && thread.session.activeTurnId !== null) {
|
|
41327
|
+
yield* appendProviderFailureActivity({
|
|
41328
|
+
threadId: event.payload.threadId,
|
|
41329
|
+
kind: "provider.turn.start.failed",
|
|
41330
|
+
summary: "Provider turn start rejected",
|
|
41331
|
+
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.`,
|
|
41332
|
+
turnId: null,
|
|
41333
|
+
createdAt: event.payload.createdAt
|
|
41334
|
+
});
|
|
41335
|
+
return;
|
|
41336
|
+
}
|
|
40635
41337
|
const message = thread.messages.find((entry) => entry.id === event.payload.messageId);
|
|
40636
41338
|
if (!message || message.role !== "user") {
|
|
40637
41339
|
yield* appendProviderFailureActivity({
|
|
@@ -40702,6 +41404,7 @@ const make$2 = effect.Effect.gen(function* () {
|
|
|
40702
41404
|
yield* providerService.sendTurn(sendTurnRequest.value).pipe(effect.Effect.catchCause(recoverTurnStartFailure), effect.Effect.forkScoped);
|
|
40703
41405
|
});
|
|
40704
41406
|
const processTurnInterruptRequested = effect.Effect.fn("processTurnInterruptRequested")(function* (event) {
|
|
41407
|
+
if (isProviderOriginatedCommandId(event.commandId)) return;
|
|
40705
41408
|
const thread = yield* resolveThread(event.payload.threadId);
|
|
40706
41409
|
if (!thread) return;
|
|
40707
41410
|
if (!(thread.session && thread.session.status !== "stopped")) return yield* appendProviderFailureActivity({
|
|
@@ -46998,6 +47701,10 @@ const decideOrchestrationCommand = effect.Effect.fn("decideOrchestrationCommand"
|
|
|
46998
47701
|
command,
|
|
46999
47702
|
threadId: command.threadId
|
|
47000
47703
|
});
|
|
47704
|
+
if (targetThread.session?.status === "running" && targetThread.session.activeTurnId !== null) return yield* new OrchestrationCommandInvariantError({
|
|
47705
|
+
commandType: command.type,
|
|
47706
|
+
detail: `Thread '${command.threadId}' already has active turn '${targetThread.session.activeTurnId}' and cannot start another turn until it finishes.`
|
|
47707
|
+
});
|
|
47001
47708
|
const sourceProposedPlan = command.sourceProposedPlan;
|
|
47002
47709
|
const sourceThread = sourceProposedPlan ? yield* requireThread({
|
|
47003
47710
|
readModel,
|
|
@@ -49845,8 +50552,20 @@ const WorkspaceRootLookupInput = effect.Schema.Struct({ workspaceRoot: effect.Sc
|
|
|
49845
50552
|
const ProjectIdLookupInput = effect.Schema.Struct({ projectId: require_collectUint8StreamText.ProjectId });
|
|
49846
50553
|
const ThreadIdLookupInput = effect.Schema.Struct({ threadId: require_collectUint8StreamText.ThreadId });
|
|
49847
50554
|
const WorktreeIdLookupInput = effect.Schema.Struct({ worktreeId: require_collectUint8StreamText.WorktreeId });
|
|
50555
|
+
const ThreadMessageSearchQueryInput = effect.Schema.Struct({
|
|
50556
|
+
likePattern: effect.Schema.String,
|
|
50557
|
+
projectId: effect.Schema.NullOr(require_collectUint8StreamText.ProjectId),
|
|
50558
|
+
limit: require_collectUint8StreamText.NonNegativeInt
|
|
50559
|
+
});
|
|
49848
50560
|
const ProjectionProjectLookupRowSchema = ProjectionProjectDbRowSchema;
|
|
49849
50561
|
const ProjectionThreadIdLookupRowSchema = effect.Schema.Struct({ threadId: require_collectUint8StreamText.ThreadId });
|
|
50562
|
+
const ProjectionThreadMessageSearchRowSchema = effect.Schema.Struct({
|
|
50563
|
+
threadId: require_collectUint8StreamText.ThreadId,
|
|
50564
|
+
messageId: require_collectUint8StreamText.MessageId,
|
|
50565
|
+
text: effect.Schema.String,
|
|
50566
|
+
createdAt: require_collectUint8StreamText.IsoDateTime,
|
|
50567
|
+
updatedAt: require_collectUint8StreamText.IsoDateTime
|
|
50568
|
+
});
|
|
49850
50569
|
const ProjectionThreadCheckpointContextThreadRowSchema = effect.Schema.Struct({
|
|
49851
50570
|
threadId: require_collectUint8StreamText.ThreadId,
|
|
49852
50571
|
projectId: require_collectUint8StreamText.ProjectId,
|
|
@@ -49878,6 +50597,20 @@ function computeSnapshotSequence(stateRows) {
|
|
|
49878
50597
|
}
|
|
49879
50598
|
return Number.isFinite(minSequence) ? minSequence : 0;
|
|
49880
50599
|
}
|
|
50600
|
+
function escapeSqlLikePattern(value) {
|
|
50601
|
+
return value.replace(/[\\%_]/g, (match) => `\\${match}`);
|
|
50602
|
+
}
|
|
50603
|
+
function buildMessageSearchSnippet(input) {
|
|
50604
|
+
const maxLength = input.maxLength ?? 180;
|
|
50605
|
+
const normalizedQuery = input.query.trim().toLowerCase();
|
|
50606
|
+
const normalizedText = input.text.toLowerCase();
|
|
50607
|
+
const matchIndex = normalizedQuery.length > 0 ? normalizedText.indexOf(normalizedQuery) : -1;
|
|
50608
|
+
const contextLength = Math.floor(maxLength / 2);
|
|
50609
|
+
const start = matchIndex <= contextLength ? 0 : Math.max(0, matchIndex - Math.floor(contextLength / 2));
|
|
50610
|
+
const end = Math.min(input.text.length, start + maxLength);
|
|
50611
|
+
const snippet = input.text.slice(start, end).replace(/\s+/g, " ").trim();
|
|
50612
|
+
return `${start > 0 ? "..." : ""}${snippet}${end < input.text.length ? "..." : ""}`;
|
|
50613
|
+
}
|
|
49881
50614
|
function mapLatestTurn(row) {
|
|
49882
50615
|
return {
|
|
49883
50616
|
turnId: row.turnId,
|
|
@@ -50347,6 +51080,30 @@ const makeProjectionSnapshotQuery = effect.Effect.gen(function* () {
|
|
|
50347
51080
|
FROM projection_thread_messages
|
|
50348
51081
|
WHERE thread_id = ${threadId}
|
|
50349
51082
|
ORDER BY created_at ASC, message_id ASC
|
|
51083
|
+
`
|
|
51084
|
+
});
|
|
51085
|
+
const searchThreadMessageRows = effect_unstable_sql_SqlSchema.findAll({
|
|
51086
|
+
Request: ThreadMessageSearchQueryInput,
|
|
51087
|
+
Result: ProjectionThreadMessageSearchRowSchema,
|
|
51088
|
+
execute: ({ likePattern, projectId, limit }) => sql`
|
|
51089
|
+
SELECT
|
|
51090
|
+
messages.thread_id AS "threadId",
|
|
51091
|
+
messages.message_id AS "messageId",
|
|
51092
|
+
messages.text,
|
|
51093
|
+
messages.created_at AS "createdAt",
|
|
51094
|
+
messages.updated_at AS "updatedAt"
|
|
51095
|
+
FROM projection_thread_messages AS messages
|
|
51096
|
+
INNER JOIN projection_threads AS threads
|
|
51097
|
+
ON threads.thread_id = messages.thread_id
|
|
51098
|
+
INNER JOIN projection_projects AS projects
|
|
51099
|
+
ON projects.project_id = threads.project_id
|
|
51100
|
+
WHERE threads.deleted_at IS NULL
|
|
51101
|
+
AND projects.deleted_at IS NULL
|
|
51102
|
+
AND messages.role IN ('user', 'assistant')
|
|
51103
|
+
AND (${projectId} IS NULL OR threads.project_id = ${projectId})
|
|
51104
|
+
AND lower(messages.text) LIKE ${likePattern} ESCAPE '\\'
|
|
51105
|
+
ORDER BY messages.created_at DESC, messages.message_id DESC
|
|
51106
|
+
LIMIT ${limit}
|
|
50350
51107
|
`
|
|
50351
51108
|
});
|
|
50352
51109
|
const listThreadProposedPlanRowsByThread = effect_unstable_sql_SqlSchema.findAll({
|
|
@@ -50935,6 +51692,24 @@ const makeProjectionSnapshotQuery = effect.Effect.gen(function* () {
|
|
|
50935
51692
|
};
|
|
50936
51693
|
return effect.Option.some(yield* decodeThread(thread).pipe(effect.Effect.mapError(toPersistenceDecodeError("ProjectionSnapshotQuery.getThreadDetailById:decodeThread"))));
|
|
50937
51694
|
});
|
|
51695
|
+
const searchThreadMessages = (input) => {
|
|
51696
|
+
const query = input.query.trim();
|
|
51697
|
+
if (query.length === 0) return effect.Effect.succeed([]);
|
|
51698
|
+
const limit = Math.min(Math.max(1, input.limit), 50);
|
|
51699
|
+
return searchThreadMessageRows({
|
|
51700
|
+
likePattern: `%${escapeSqlLikePattern(query.toLowerCase())}%`,
|
|
51701
|
+
projectId: input.projectId ?? null,
|
|
51702
|
+
limit
|
|
51703
|
+
}).pipe(effect.Effect.mapError(toPersistenceSqlOrDecodeError("ProjectionSnapshotQuery.searchThreadMessages:query", "ProjectionSnapshotQuery.searchThreadMessages:decodeRows")), effect.Effect.map((rows) => rows.map((row) => ({
|
|
51704
|
+
threadId: row.threadId,
|
|
51705
|
+
messageId: row.messageId,
|
|
51706
|
+
snippet: buildMessageSearchSnippet({
|
|
51707
|
+
text: row.text,
|
|
51708
|
+
query
|
|
51709
|
+
}),
|
|
51710
|
+
timestamp: row.createdAt
|
|
51711
|
+
}))));
|
|
51712
|
+
};
|
|
50938
51713
|
return {
|
|
50939
51714
|
getCommandReadModel,
|
|
50940
51715
|
getSnapshot,
|
|
@@ -50947,7 +51722,8 @@ const makeProjectionSnapshotQuery = effect.Effect.gen(function* () {
|
|
|
50947
51722
|
getThreadCheckpointContext,
|
|
50948
51723
|
getThreadShellById,
|
|
50949
51724
|
getWorktreeShellById,
|
|
50950
|
-
getThreadDetailById
|
|
51725
|
+
getThreadDetailById,
|
|
51726
|
+
searchThreadMessages
|
|
50951
51727
|
};
|
|
50952
51728
|
});
|
|
50953
51729
|
const OrchestrationProjectionSnapshotQueryLive = effect.Layer.effect(ProjectionSnapshotQuery, makeProjectionSnapshotQuery);
|
|
@@ -50955,7 +51731,7 @@ const OrchestrationProjectionSnapshotQueryLive = effect.Layer.effect(ProjectionS
|
|
|
50955
51731
|
//#region src/orchestration/runtimeLayer.ts
|
|
50956
51732
|
const OrchestrationEventInfrastructureLayerLive = effect.Layer.mergeAll(OrchestrationEventStoreLive, OrchestrationCommandReceiptRepositoryLive);
|
|
50957
51733
|
const OrchestrationProjectionPipelineLayerLive = OrchestrationProjectionPipelineLive.pipe(effect.Layer.provide(OrchestrationEventStoreLive));
|
|
50958
|
-
const OrchestrationInfrastructureLayerLive = effect.Layer.mergeAll(OrchestrationProjectionSnapshotQueryLive, OrchestrationEventInfrastructureLayerLive, OrchestrationProjectionPipelineLayerLive);
|
|
51734
|
+
const OrchestrationInfrastructureLayerLive = effect.Layer.mergeAll(OrchestrationProjectionSnapshotQueryLive, StatisticsQueryLive, OrchestrationEventInfrastructureLayerLive, OrchestrationProjectionPipelineLayerLive);
|
|
50959
51735
|
const OrchestrationLayerLive = effect.Layer.mergeAll(OrchestrationInfrastructureLayerLive, OrchestrationEngineLive.pipe(effect.Layer.provide(OrchestrationInfrastructureLayerLive)));
|
|
50960
51736
|
//#endregion
|
|
50961
51737
|
//#region src/serverRuntimeState.ts
|
|
@@ -51762,6 +52538,7 @@ exports.ServerRequest__DynamicToolCallParams = ServerRequest__DynamicToolCallPar
|
|
|
51762
52538
|
exports.ServerRequest__ExecCommandApprovalParams = ServerRequest__ExecCommandApprovalParams;
|
|
51763
52539
|
exports.ServerRequest__FileChangeRequestApprovalParams = ServerRequest__FileChangeRequestApprovalParams;
|
|
51764
52540
|
exports.ServerRequest__ToolRequestUserInputParams = ServerRequest__ToolRequestUserInputParams;
|
|
52541
|
+
exports.ServerSettingsService = ServerSettingsService;
|
|
51765
52542
|
exports.ToolRequestUserInputParams = ToolRequestUserInputParams;
|
|
51766
52543
|
exports.ToolRequestUserInputResponse = ToolRequestUserInputResponse;
|
|
51767
52544
|
exports.V2AccountRateLimitsUpdatedNotification = V2AccountRateLimitsUpdatedNotification;
|