@overdeck/desktop 0.40.0 → 0.41.1

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.
Files changed (19) hide show
  1. package/package.json +1 -1
  2. package/server/public/assets/{chunk-BO2N2NFS-CW1ZdFdY.js → chunk-BO2N2NFS-qb3jozf8.js} +4 -4
  3. package/server/public/assets/{diagram-OG6HWLK6-Cw_BgPPR.js → diagram-OG6HWLK6-DCxQdIR-.js} +1 -1
  4. package/server/public/assets/{dist-913yenhq.js → dist--I-KHxVY.js} +1 -1
  5. package/server/public/assets/{dist-CGMAxsiA.js → dist-99bVzL85.js} +3 -3
  6. package/server/public/assets/{ganttDiagram-6RSMTGT7-CUPZhXKC.js → ganttDiagram-6RSMTGT7-CZQ5wmbx.js} +1 -1
  7. package/server/public/assets/{highlighted-body-OFNGDK62-PZCZRTma.js → highlighted-body-OFNGDK62-gddTgxaL.js} +1 -1
  8. package/server/public/assets/{index-D_duUQjN.css → index-By2KY9vK.css} +1 -1
  9. package/server/public/assets/{index-2sJIy1Mo.js → index-w0Cnkax8.js} +129 -129
  10. package/server/public/assets/{linear-CaWsupFC.js → linear-BchPtO53.js} +1 -1
  11. package/server/public/assets/mermaid-GHXKKRXX-CxNSCT26.js +1 -0
  12. package/server/public/assets/{pieDiagram-4H26LBE5-BhU2fIWh.js → pieDiagram-4H26LBE5-COGFoOPX.js} +1 -1
  13. package/server/public/assets/{prod-Dk-iWRhQ.js → prod-CnNbvojd.js} +4 -4
  14. package/server/public/assets/{quadrantDiagram-W4KKPZXB-DGOsJ_nS.js → quadrantDiagram-W4KKPZXB-6DBILYRJ.js} +1 -1
  15. package/server/public/assets/{sankeyDiagram-5OEKKPKP-CzirInk6.js → sankeyDiagram-5OEKKPKP-DTpZ_e2a.js} +1 -1
  16. package/server/public/assets/{xychartDiagram-2RQKCTM6-CG8FHgaF.js → xychartDiagram-2RQKCTM6-guNhhdvI.js} +1 -1
  17. package/server/public/index.html +2 -2
  18. package/server/server.js +442 -134
  19. package/server/public/assets/mermaid-GHXKKRXX-CD7SbVD6.js +0 -1
package/server/server.js CHANGED
@@ -1,90 +1,90 @@
1
1
  import { a as __toCommonJS, i as __require, o as __toESM, t as __commonJSMin } from "./rolldown-runtime-DNCzzKnI.js";
2
- import { C as isDevMode, E as sessionFilePath, S as init_paths, T as resolveOhmypiExtensionPath, _ as SYNC_SOURCES, l as LOGS_DIR, o as CLAUDE_DIR, t as AGENTS_DIR, u as OVERDECK_HOME, w as packageRoot, x as getOverdeckHome, y as encodeClaudeProjectDir } from "./paths-jZvjmiV6.js";
2
+ import { C as init_paths, D as sessionFilePath, E as resolveOhmypiExtensionPath, S as getOverdeckHome, T as packageRoot, _ as SYNC_SOURCES, l as LOGS_DIR, o as CLAUDE_DIR, t as AGENTS_DIR, u as OVERDECK_HOME, w as isDevMode, x as getLegacyHome, y as encodeClaudeProjectDir } from "./paths-tknG80xs.js";
3
3
  import { A as init_model_capabilities, B as FsError, C as defaultBackgroundAiFeatures, E as MODEL_DEPRECATIONS, F as require_dist$1, H as GitHubApiError, J as TrackerError, K as ProcessSpawnError, M as resolveModelIdSync, N as init_js_yaml, O as getModelEffortLevelsSync, P as jsYaml, S as updateConversationsConfig, T as MODEL_CAPABILITIES, X as init_errors, _ as loadConfigNoMigration, a as ROLE_EFFORTS, b as mergeTtsDaemonConfigs, c as getConversationSearchConfigSync, d as getDefaultTtsDaemonConfig, f as getGlobalConfigPath, g as isTldrEnabledSync, i as PARENT_MODEL_REF, j as modelSupportsImagesSync, k as hasModelCapabilitySync, l as getConversationsConfig, m as isClaudeCodeChannelsEnabled, n as DEFAULT_ROLES, o as clearConfigCache, p as init_config_yaml, r as DEFAULT_WORKHORSES, s as computeModelOrigin, t as COMPLIANCE_MODES, v as loadConfigSync, w as init_registry, x as resolveModel, y as mergeConfigs } from "./config-yaml-DKmldcyb.js";
4
- import { A as getAgentJsonlMtime, B as isTrustedOriginForHost, C as resolveAgentHarness, D as resolvePiSessionPath, E as resolveJsonlPath, F as init_agent_input_detection, G as init_codex_auth, H as validateOrigin$1, I as parseCodexApprovalPrompt, K as httpHandler, L as getHeaderFromMap, M as scanPendingInputsPromise, N as detectAwaitingInputForAgent, O as computeAgentEnrichment, P as detectAwaitingInputFromPaneSync, S as readLauncherPinnedSessionId, T as resolveCodexRolloutPath, U as validateOriginHeaders, W as checkCodexAuthStatus, X as init_http_helpers, Z as jsonResponse, _ as getRuntimeForAgent, a as init_agent_projection, b as init_health, c as init_git_info, d as getSystemHealthSnapshot, f as init_system_health_service, g as init_service, h as getCloisterService, j as init_agent_enrichment, n as init_agents, o as saveAgentStateAndEmitEvent, q as init_http_handler, s as saveAgentStateAndEmitEventProgram, t as agentsRouteLayer, u as resolveConversationGitInfo, v as init_runtimes, w as resolveClaudeSessionId, x as init_jsonl_resolver, y as getAgentHealth, z as init_origin_validation } from "./agents-L3yA6mO7.js";
4
+ import { A as getAgentJsonlMtime, B as isTrustedOriginForHost, C as resolveAgentHarness, D as resolvePiSessionPath, E as resolveJsonlPath, F as init_agent_input_detection, G as init_codex_auth, H as validateOrigin$1, I as parseCodexApprovalPrompt, K as httpHandler, L as getHeaderFromMap, M as scanPendingInputsPromise, N as detectAwaitingInputForAgent, O as computeAgentEnrichment, P as detectAwaitingInputFromPaneSync, S as readLauncherPinnedSessionId, T as resolveCodexRolloutPath, U as validateOriginHeaders, W as checkCodexAuthStatus, X as init_http_helpers, Z as jsonResponse, _ as getRuntimeForAgent, a as init_agent_projection, b as init_health, c as init_git_info, d as getSystemHealthSnapshot, f as init_system_health_service, g as init_service, h as getCloisterService, j as init_agent_enrichment, n as init_agents, o as saveAgentStateAndEmitEvent, q as init_http_handler, s as saveAgentStateAndEmitEventProgram, t as agentsRouteLayer, u as resolveConversationGitInfo, v as init_runtimes, w as resolveClaudeSessionId, x as init_jsonl_resolver, y as getAgentHealth, z as init_origin_validation } from "./agents-7Q89VRVF.js";
5
5
  import { a as init_activity_logger, i as emitDashboardLifecycleSync, n as emitActivityEntrySync, r as emitActivityTtsSync } from "./activity-logger-DW1XjyNu.js";
6
- import { A as init_paths$1, O as OVERDECK_MIGRATION_PATH, d as getOverdeckDatabaseSync, f as init_infra, i as DbLive, k as getOverdeckDatabasePath, u as TmuxLive } from "./infra-V576nNrp.js";
6
+ import { A as init_paths$1, O as OVERDECK_MIGRATION_PATH, d as getOverdeckDatabaseSync, f as init_infra, i as DbLive, k as getOverdeckDatabasePath, u as TmuxLive } from "./infra-uzOlAtyu.js";
7
7
  import { n as openDatabase, t as init_driver } from "./driver-CYPr28GN.js";
8
8
  import { a as parseIssueIdSync, n as extractPrefixSync, r as init_issue_id } from "./issue-id-9iS2dwrp.js";
9
- import { E as registerProjectSync, N as setProjectAutoMergeDefaultSync, O as resolveProjectFromIssue, _ as init_projects, b as listProjects, d as getProjectSync, k as resolveProjectFromIssueSync, l as getIssuePrefix, r as extractTeamPrefix, s as findProjectByTeamSync, x as listProjectsSync } from "./projects-BpstKN1Q.js";
10
- import { B as init_ui_theme, D as listSessionNames, F as sessionExists, G as init_child_env, H as BLANKED_PROVIDER_ENV, L as setOption, N as sendKeys, P as sendRawKeystroke, S as isHarnessProcessAlive, U as buildChildEnvSync, V as setUiTheme, W as buildChildEnvWithoutTmuxSync, b as getWindowDimensions, c as ensureManagedTmuxContextOnce, d as exactPaneTarget, i as capturePane, j as resizeWindow, k as listSessionsSync, n as buildTmuxArgs, o as createSession, p as findManagedServerPidSync, w as killSession, x as init_tmux } from "./tmux-DuzZlrCh.js";
11
- import { a as init_event_store, i as initEventStore, n as getEventStore, r as getSharedDb } from "./event-store-hdZZ-JnB.js";
9
+ import { E as registerProjectSync, N as setProjectAutoMergeDefaultSync, O as resolveProjectFromIssue, _ as init_projects, b as listProjects, d as getProjectSync, k as resolveProjectFromIssueSync, l as getIssuePrefix, r as extractTeamPrefix, s as findProjectByTeamSync, x as listProjectsSync } from "./projects-9JNVPnww.js";
10
+ import { B as init_ui_theme, D as listSessionNames, F as sessionExists, G as init_child_env, H as BLANKED_PROVIDER_ENV, L as setOption, N as sendKeys, P as sendRawKeystroke, S as isHarnessProcessAlive, U as buildChildEnvSync, V as setUiTheme, W as buildChildEnvWithoutTmuxSync, b as getWindowDimensions, c as ensureManagedTmuxContextOnce, d as exactPaneTarget, i as capturePane, j as resizeWindow, k as listSessionsSync, n as buildTmuxArgs, o as createSession, p as findManagedServerPidSync, w as killSession, x as init_tmux } from "./tmux-fuzPZ-S7.js";
11
+ import { a as init_event_store, i as initEventStore, n as getEventStore, r as getSharedDb } from "./event-store-Dx53k8E7.js";
12
12
  import { _ as MemoryObservation, d as PanRpcGroup, f as WS_METHODS, h as EDITORS, i as FlywheelStats, m as FlywheelStatus, n as ContextLayerSaveRequest, p as FlywheelRunId, r as ContextPreviewRequest, t as init_src, u as PanRpcError } from "./src-wyzx0Z0w.js";
13
- import { _ as setReviewStatus, a as fixStuckCommentedReviews, c as getReviewStatusSync, l as init_review_status, n as clearReviewStatus, o as fixStuckReadyForMerge, r as clearStuckMergeStatuses, s as getReviewStatus, u as loadReviewStatuses } from "./review-status-D_w3kLBb.js";
14
- import { a as EventStoreService, c as ReadModelService, d as init_read_model, f as toAgentResolution, i as init_issue_lifecycle, l as ReadModelServiceLive, m as toRole, n as IssueLifecycleLive, o as EventStoreServiceLive, p as toAgentStatus, s as init_domain_services } from "./issue-lifecycle-D4DcNPZ-.js";
15
- import { n as AgentsResolverLive, o as init_agents$1 } from "./agents-BOX5w2kT.js";
16
- import { i as init_paths$2, l as resolveObservationsFile, r as ensureParentDir, s as resolveIssueMemoryRoot, t as assertMemorySafeSegment } from "./paths-zPOV7_VB.js";
17
- import { i as recordBriefingSessionStart, n as ensureSessionContextBriefingFile, r as init_briefing_freshness, t as appendFreshBriefingUpdate } from "./briefing-freshness--_mHhmzI.js";
18
- import { n as listFeatureRegistryEntries, t as init_feature_registry_storage } from "./feature-registry-storage-5mIu-zwl.js";
13
+ import { _ as setReviewStatus, a as fixStuckCommentedReviews, c as getReviewStatusSync, l as init_review_status, n as clearReviewStatus, o as fixStuckReadyForMerge, r as clearStuckMergeStatuses, s as getReviewStatus, u as loadReviewStatuses } from "./review-status-BNAmNTNz.js";
14
+ import { a as EventStoreService, c as ReadModelService, d as init_read_model, f as toAgentResolution, i as init_issue_lifecycle, l as ReadModelServiceLive, m as toRole, n as IssueLifecycleLive, o as EventStoreServiceLive, p as toAgentStatus, s as init_domain_services } from "./issue-lifecycle-ltm4JzoA.js";
15
+ import { n as AgentsResolverLive, o as init_agents$1 } from "./agents-BX0F_1V2.js";
16
+ import { i as init_paths$2, l as resolveObservationsFile, r as ensureParentDir, s as resolveIssueMemoryRoot, t as assertMemorySafeSegment } from "./paths-3zDoFwPl.js";
17
+ import { i as recordBriefingSessionStart, n as ensureSessionContextBriefingFile, r as init_briefing_freshness, t as appendFreshBriefingUpdate } from "./briefing-freshness-BVjg7adf.js";
18
+ import { n as listFeatureRegistryEntries, t as init_feature_registry_storage } from "./feature-registry-storage-BjEVR7fj.js";
19
19
  import { a as diffAgainstMainFiles, c as diffFilesAgainstHead, d as findCommitAtTime, i as diffAgainstMain, l as diffPatchFilesAgainstHead, m as listCheckpoints, o as diffCheckpointFiles, p as init_checkpoint_manager, s as diffCheckpoints, t as captureCheckpoint, u as diffPatchSinceCommit } from "./checkpoint-manager-B8USYP2J.js";
20
- import { _ as init_cost, a as init_costs, c as init_reconciler, d as migrateAllSessionsSync, f as getCostsForIssueSync, g as CostResolverLive, h as CostResolver, i as resolveIssueHeadlineCost, l as reconcile, m as syncCacheSync, n as init_running_agents_cache, o as init_sync_wal, p as rebuildCacheSync, r as init_issue_cost_resolver, s as syncWalFromAllProjects, t as getCachedRunningAgents, u as reconcilePiTranscripts } from "./running-agents-cache-CoFoCGgg.js";
21
- import { i as init_agent_state_service, n as AgentStateServiceLive } from "./agent-state-service-CoVk44dM.js";
22
- import { a as init_tracker_config, i as initTrackerConfigCache, n as getLinearApiKey, r as getRallyConfig, t as getGitHubConfig } from "./tracker-config-Clt5yfo6.js";
20
+ import { _ as init_cost, a as init_costs, c as init_reconciler, d as migrateAllSessionsSync, f as getCostsForIssueSync, g as CostResolverLive, h as CostResolver, i as resolveIssueHeadlineCost, l as reconcile, m as syncCacheSync, n as init_running_agents_cache, o as init_sync_wal, p as rebuildCacheSync, r as init_issue_cost_resolver, s as syncWalFromAllProjects, t as getCachedRunningAgents, u as reconcilePiTranscripts } from "./running-agents-cache-DEOooWJX.js";
21
+ import { i as init_agent_state_service, n as AgentStateServiceLive } from "./agent-state-service-WIfk7QHr.js";
22
+ import { a as init_tracker_config, i as initTrackerConfigCache, n as getLinearApiKey, r as getRallyConfig, t as getGitHubConfig } from "./tracker-config-NzBQEKKo.js";
23
23
  import { d as init_typed_errors, l as WorkspaceCreateError, n as AgentStartError, r as BeadsNotInitialized, t as AgentAlreadyRunning, u as WorkspaceNotFound } from "./typed-errors-BRDFMoss.js";
24
- import { i as init_linear_client, r as LinearClientOptionalLive, t as LinearClient } from "./linear-client-DCCtUBEM.js";
25
- import { i as init_github_client, r as GitHubClientOptionalLive } from "./github-client-Dxt2nXAf.js";
26
- import { i as init_rally_client, r as RallyClientOptionalLive } from "./rally-client-CFxmPAi2.js";
27
- import { i as resolveGitHubIssueSync, n as init_tracker_utils } from "./tracker-utils-k1WKm_mu.js";
28
- import { a as CacheService, i as startSharedIssueService, n as init_issue_service_singleton, o as init_cache_service, r as issue_service_singleton_exports, s as parseIntegerHeader, t as getSharedIssueService } from "./issue-service-singleton-0AVb8ADy.js";
29
- import { i as ensureInternalTokenSync, s as init_internal_token } from "./internal-token-R4gY8z44.js";
30
- import { a as setPipelineHandlerSync, t as init_pipeline_notifier } from "./pipeline-notifier-C5ZCbH9K.js";
31
- import { c as init_review_status_sync, i as getMergeBlockerReconcileCandidates, r as getAllReviewStatusesFromDb } from "./review-status-sync-DGaMxP95.js";
32
- import { a as getCostForIssueAggregateSync, c as getDailyTrendsSync, l as getModelRollupSync, n as getBackgroundCostBySourceSync, r as getCavemanExperimentDataSync, s as getCostsByIssueSync, u as init_cost_sync } from "./cost-sync-CI1Gfwnb.js";
33
- import { C as transitionToMerging, _ as markFailed, c as isFlywheelGloballyPaused, d as listDuePendingAutoMerges, f as listProblemAutoMerges, g as markBlocked, n as getActionableAutoMerge, o as init_merge_sync, t as cancelPending, u as listActiveAutoMerges, v as markMerged, x as scheduleAutoMergeWithResult, y as requeueToPending } from "./merge-sync-CKUHrPQl.js";
34
- import { A as PAN_CONTINUE_FILENAME, I as init_types, _ as findSpecByIssue, a as init_io, j as PAN_DIRNAME, l as readWorkspacePlan, n as findPlan, s as readPlan, y as init_specs } from "./io-cnr9mD4B.js";
35
- import { C as restartCliproxy, S as readPidFile, T as stopCliproxy, b as isCliproxyInstalled, d as getCliproxyAuthDir, o as bridgeCodexAuthToCliproxy, v as init_cliproxy, w as startCliproxy, x as isCliproxyRunning, y as installCliproxy } from "./cliproxy-O755gANb.js";
36
- import { f as init_config, m as loadConfigSync$1, s as getDashboardApiUrlSync } from "./config-B8QT8B9M.js";
24
+ import { i as init_linear_client, r as LinearClientOptionalLive, t as LinearClient } from "./linear-client-BRwBC1ub.js";
25
+ import { i as init_github_client, r as GitHubClientOptionalLive } from "./github-client-CLhcTuCU.js";
26
+ import { i as init_rally_client, r as RallyClientOptionalLive } from "./rally-client-C51tvXfE.js";
27
+ import { i as resolveGitHubIssueSync, n as init_tracker_utils } from "./tracker-utils-zk9EsKQs.js";
28
+ import { a as CacheService, i as startSharedIssueService, n as init_issue_service_singleton, o as init_cache_service, r as issue_service_singleton_exports, s as parseIntegerHeader, t as getSharedIssueService } from "./issue-service-singleton-Ci--QAmc.js";
29
+ import { i as ensureInternalTokenSync, s as init_internal_token } from "./internal-token-C8Bg8u5G.js";
30
+ import { a as setPipelineHandlerSync, t as init_pipeline_notifier } from "./pipeline-notifier-BOcC7C98.js";
31
+ import { c as init_review_status_sync, i as getMergeBlockerReconcileCandidates, r as getAllReviewStatusesFromDb } from "./review-status-sync-D1KZJHeS.js";
32
+ import { a as getCostForIssueAggregateSync, c as getDailyTrendsSync, d as init_cost_sync, l as getModelRollupSync, n as getBackgroundCostBySourceSync, r as getCavemanExperimentDataSync, s as getCostsByIssueSync, u as getTodayCostSync } from "./cost-sync-BG3EnaXL.js";
33
+ import { C as transitionToMerging, _ as markFailed, c as isFlywheelGloballyPaused, d as listDuePendingAutoMerges, f as listProblemAutoMerges, g as markBlocked, n as getActionableAutoMerge, o as init_merge_sync, t as cancelPending, u as listActiveAutoMerges, v as markMerged, x as scheduleAutoMergeWithResult, y as requeueToPending } from "./merge-sync-bO1W7sg-.js";
34
+ import { A as PAN_CONTINUE_FILENAME, I as init_types, _ as findSpecByIssue, a as init_io, j as PAN_DIRNAME, l as readWorkspacePlan, n as findPlan, s as readPlan, y as init_specs } from "./io-BsBjfxgG.js";
35
+ import { C as restartCliproxy, S as readPidFile, T as stopCliproxy, b as isCliproxyInstalled, d as getCliproxyAuthDir, o as bridgeCodexAuthToCliproxy, v as init_cliproxy, w as startCliproxy, x as isCliproxyRunning, y as installCliproxy } from "./cliproxy-shDfFOk1.js";
36
+ import { f as init_config, m as loadConfigSync$1, s as getDashboardApiUrlSync } from "./config-DrT6EhRW.js";
37
37
  import { n as require_auth_errors, r as require_token_error, t as require_token_util } from "./token-util-CROoF5ic.js";
38
- import { $ as updateSpawnError, A as listConversations, B as setClearedToConvId, C as getStuckForks, E as init_conversations, G as setForkRequest, H as setConversationHarness, J as updateConversationDeliveryMethod, K as unarchiveConversation, L as recordConversationHandoff, M as markConversationActive, N as markConversationEnded, O as listActiveConversations, P as markConversationRunning, Q as updateLastAttached, R as removeFavorite, S as getConversationByTmuxSession, T as incrementForkRetryCount, U as setConversationModel, V as setConversationClaudeSessionId, W as setFavorite, X as updateConversationTitle, Y as updateConversationForkFallbackReason, Z as updateForkStatus, _ as canReplaceTitle, b as getConversationById, g as backfillConversationModel, h as archiveConversation, j as listFavoritedIds, k as listArchivedConversationsWithEnrichment, q as updateConversationCost, v as createConversation, w as hasOtherActiveConversationOnTmuxSession, x as getConversationByName, y as getConversationByClaudeSessionId } from "./conversations-_HbvcXw1.js";
39
- import { _ as init_codex_conversation_parser, a as init_conversation_service, c as parseFromLastCompactBoundary, d as init_ohmypi_conversation_parser, f as isOhmypiSessionFile, g as parsePiConversationMessages, h as isPiSessionFile, i as gateSnapshotEmission, l as summarizeConversationActivity, m as init_pi_conversation_parser, n as contextUsageFromParseResult, o as parseConversationMessages, p as parseOhmypiConversationMessages, t as computeContextUsage, u as watchConversation, v as parseCodexConversationMessages } from "./conversation-service-CJimCSkV.js";
38
+ import { $ as updateConversationTitle, A as listActiveConversations, B as removeFavorite, C as getConversationLedgerCosts, D as incrementForkRetryCount, E as importLegacyConversation, F as markConversationEnded, G as setConversationModel, H as setClearedToConvId, I as markConversationRunning, J as setImportedConversationLinks, K as setFavorite, M as listConversations, N as listFavoritedIds, O as init_conversations, P as markConversationActive, Q as updateConversationForkFallbackReason, S as getConversationByTmuxSession, T as hasOtherActiveConversationOnTmuxSession, U as setConversationClaudeSessionId, W as setConversationHarness, X as updateConversationCost, Y as unarchiveConversation, Z as updateConversationDeliveryMethod, _ as canReplaceTitle, b as getConversationById, et as updateForkStatus, g as backfillConversationModel, h as archiveConversation, j as listArchivedConversationsWithEnrichment, k as isAgentConversationName, nt as updateSpawnError, q as setForkRequest, tt as updateLastAttached, v as createConversation, w as getStuckForks, x as getConversationByName, y as getConversationByClaudeSessionId, z as recordConversationHandoff } from "./conversations-TDFrjruR.js";
39
+ import { _ as init_codex_conversation_parser, a as init_conversation_service, c as parseFromLastCompactBoundary, d as init_ohmypi_conversation_parser, f as isOhmypiSessionFile, g as parsePiConversationMessages, h as isPiSessionFile, i as gateSnapshotEmission, l as summarizeConversationActivity, m as init_pi_conversation_parser, n as contextUsageFromParseResult, o as parseConversationMessages, p as parseOhmypiConversationMessages, s as parseEntireConversation, t as computeContextUsage, u as watchConversation, v as parseCodexConversationMessages } from "./conversation-service-CAyL41UH.js";
40
40
  import { i as getClaudePermissionFlagsStringSync, o as init_claude_permissions, s as resolvePermissionModeSync, t as BYPASS_PERMISSION_MODE } from "./claude-permissions-BqmkURDk.js";
41
- import { l as init_codex, s as findRolloutPath } from "./codex-B8fyHBID.js";
42
- import { $t as init_claude_auth, A as getAgentStateFilePath, At as init_operator_interventions, B as init_agents$2, Bt as init_pty_token, C as dismissDevChannelsDialog, D as getAgentRuntimeState, Dt as captureTranscriptUserRecordSnapshot, E as getAgentRuntimeBaseCommand, Et as writeChannelsBridgeMcpConfig, F as getProviderEnvForModel, G as listAgentStates, Ht as init_bridge_token, I as getProviderExportsForModel, K as listRunningAgents, O as getAgentRuntimeStateSync, Ot as init_transcript_landing, P as getProviderAuthMode, Qt as getClaudeAuthStatus, Rt as init_pi_fifo, St as waitForReadySignal, T as getAgentDir, Ut as writeBridgeTokenSync, V as injectPiConversationMemory, Vt as writePtyToken, Xt as init_agent_record_sync, Z as messageAgent, Zt as readAgentHarnessModelRecordSync, en as getOpenAIAuthStatus, h as clearReadySignal, j as getAgentStateSync, jt as operatorInterventionEvent, k as getAgentState, kt as probeTranscriptSince, tn as init_openai_auth, v as deliverAgentMessage, zt as piFifoPaths } from "./agents-qDfx6gda.js";
41
+ import { l as init_codex, s as findRolloutPath } from "./codex-Bj_hftHG.js";
42
+ import { $t as init_claude_auth, A as getAgentStateFilePath, At as init_operator_interventions, B as init_agents$2, Bt as init_pty_token, C as dismissDevChannelsDialog, D as getAgentRuntimeState, Dt as captureTranscriptUserRecordSnapshot, E as getAgentRuntimeBaseCommand, Et as writeChannelsBridgeMcpConfig, F as getProviderEnvForModel, G as listAgentStates, Ht as init_bridge_token, I as getProviderExportsForModel, K as listRunningAgents, O as getAgentRuntimeStateSync, Ot as init_transcript_landing, P as getProviderAuthMode, Qt as getClaudeAuthStatus, Rt as init_pi_fifo, St as waitForReadySignal, T as getAgentDir, Ut as writeBridgeTokenSync, V as injectPiConversationMemory, Vt as writePtyToken, Xt as init_agent_record_sync, Z as messageAgent, Zt as readAgentHarnessModelRecordSync, en as getOpenAIAuthStatus, h as clearReadySignal, j as getAgentStateSync, jt as operatorInterventionEvent, k as getAgentState, kt as probeTranscriptSince, tn as init_openai_auth, v as deliverAgentMessage, zt as piFifoPaths } from "./agents-DK6l7-xB.js";
43
43
  import { a as getBuiltInDefaultHarness, c as getProviderForModelSync, l as init_providers, o as getKimiAnthropicBaseUrl, u as piProviderForModel } from "./providers-Cju7HorZ.js";
44
44
  import { n as isBackgroundFeatureEnabled, t as init_features } from "./features-BsiM65ZI.js";
45
45
  import { i as init_settings, r as getMemoryWorkerConcurrency, t as areMemoryObservationsEnabled } from "./settings-s_9BJkQW.js";
46
- import { t as init_pan_dir } from "./pan-dir-BfyAUgin.js";
47
- import { n as init_launcher_generator, t as generateLauncherScriptSync } from "./launcher-generator-CZaEkOZW.js";
48
- import { a as globalContextFile$1, d as workspaceContextFile, l as projectContextFile, n as codexGlobalContextFile, o as init_layers, r as ensureProjectLayer, s as piGlobalContextFile } from "./layers-CoMbLSYY.js";
49
- import { i as init_harness_policy, n as resolveHarness, r as canUseHarnessSync, t as init_harness_resolve } from "./harness-resolve-CMrgPv1e.js";
50
- import { c as init_docker_stats } from "./stack-health-KI4ZA4dt.js";
51
- import { i as updateMemoryHealth, n as extractWithProviderPolicy, r as init_health$1, t as init_providers$1 } from "./providers-0791nfjR.js";
52
- import { a as getSetting, b as setSetting, c as isDeaconGloballyPausedSync, d as isFlywheelRequireUatBeforeMerge, f as isMergeTrainEnabled, g as setFlywheelAutoPickupBacklog, l as isFlywheelAutoPickupBacklog, m as setDeaconGloballyPausedSync, o as init_control_settings, u as isFlywheelGloballyPaused$1, v as setFlywheelRequireUatBeforeMerge, y as setMergeTrainEnabled } from "./control-settings-BaPQ0U5p.js";
53
- import { a as parseRelativeTime, n as CostThresholdError, s as embed } from "./scanner-DYR1QDik.js";
54
- import { n as deduplicateEventsSync, o as readEventsSync, s as tailEventsSync } from "./events-C0JbknXU.js";
55
- import { n as recordBackgroundAiCost, t as init_cost$1 } from "./cost-CBa8loyG.js";
56
- import { a as startUatTrainReconciler, c as openFlywheelRunReportForDashboard, d as resumeFlywheelRunForDashboard, f as startFlywheelRunForDashboard, l as pauseFlywheelRunForDashboard, o as stopUatTrainReconciler, p as runDashboardDbJob, s as abortFlywheelRunForDashboard, u as readCurrentFlywheelStatusForDashboard } from "./uat-train-BF905HkK.js";
57
- import { S as subscribeLatestFlywheelStatus, _ as listFlywheelRuns, g as isFlywheelRunId, h as init_flywheel_run_state, l as buildClassifyLookups, p as getFlywheelRunDetail, u as init_lookups, w as writeLatestFlywheelStatus, x as resolveLiveFlywheelRunId, y as readCurrentLatestFlywheelStatus } from "./flywheel-rQwXVZR5.js";
58
- import { f as workspacesRouteLayer, g as getWorkspacePathForIssue, h as processPendingFeedbackDeliveries, m as resumeQueuedMerges, p as enrichReviewStatus } from "./workspaces-CvQySqp3.js";
59
- import { _ as init_platform, g as detectPlatform } from "./workspace-manager-oMP5s9VY.js";
60
- import { a as getShadowState, s as init_shadow_state } from "./shadow-state-xPxOHguz.js";
61
- import { C as init_dashboard_auth, D as init_review_status$1, E as rejectUnsafeDashboardMutationRequest, S as hasDashboardInternalToken, T as rejectUnauthorizedDashboardSessionMintRequest, _ as groupResourceAllocatedIssuesByProject, b as dashboardCsrfToken, g as getCachedResourceAllocatedIssues, m as issuesRouteLayer, p as init_issues, v as init_resource_discovery, w as rejectUnauthorizedDashboardRequest, x as dashboardSessionCookieHeader, y as sanitizeResourceAllocatedIssues } from "./issues-D909CPHX.js";
62
- import { a as loadCloisterConfigSync, i as loadCloisterConfig, o as saveCloisterConfigSync, r as init_config$1, s as shouldAutoStart } from "./config-wf_W38L3.js";
63
- import { O as init_specialists, b as getReviewerSessionName } from "./specialists-C5uBTD_g.js";
64
- import { H as init_deacon, _t as emergencyBrake, ct as setAgentStoppedNotifier, gt as withConcurrencyLimit, ht as init_concurrency$1, i as autoResumeStoppedWorkAgents, lt as setMergeReadyNotifier, rt as resetPatrolHeartbeatForStartup, st as setAgentStatusChangedNotifier, vt as init_concurrency } from "./deacon-BJOrAeJn.js";
46
+ import { t as init_pan_dir } from "./pan-dir-CnOUvQm_.js";
47
+ import { n as init_launcher_generator, t as generateLauncherScriptSync } from "./launcher-generator-Bzj8tdlM.js";
48
+ import { a as globalContextFile$1, d as workspaceContextFile, l as projectContextFile, n as codexGlobalContextFile, o as init_layers, r as ensureProjectLayer, s as piGlobalContextFile } from "./layers-0Zw11iHd.js";
49
+ import { i as init_harness_policy, n as resolveHarness, r as canUseHarnessSync, t as init_harness_resolve } from "./harness-resolve-Cb3nSNlN.js";
50
+ import { c as init_docker_stats } from "./stack-health-DEdzAjBZ.js";
51
+ import { i as updateMemoryHealth, n as extractWithProviderPolicy, r as init_health$1, t as init_providers$1 } from "./providers-BUnK7ZrI.js";
52
+ import { a as getSetting, b as setSetting, c as isDeaconGloballyPausedSync, d as isFlywheelRequireUatBeforeMerge, f as isMergeTrainEnabled, g as setFlywheelAutoPickupBacklog, l as isFlywheelAutoPickupBacklog, m as setDeaconGloballyPausedSync, o as init_control_settings, u as isFlywheelGloballyPaused$1, v as setFlywheelRequireUatBeforeMerge, y as setMergeTrainEnabled } from "./control-settings-ddYZWzH3.js";
53
+ import { a as parseRelativeTime, n as CostThresholdError, s as embed } from "./scanner-C1A6L99P.js";
54
+ import { n as deduplicateEventsSync, o as readEventsSync, s as tailEventsSync } from "./events-DH8idThq.js";
55
+ import { n as recordBackgroundAiCost, t as init_cost$1 } from "./cost-U2aaNgcl.js";
56
+ import { a as startUatTrainReconciler, c as openFlywheelRunReportForDashboard, d as resumeFlywheelRunForDashboard, f as startFlywheelRunForDashboard, l as pauseFlywheelRunForDashboard, o as stopUatTrainReconciler, p as runDashboardDbJob, s as abortFlywheelRunForDashboard, u as readCurrentFlywheelStatusForDashboard } from "./uat-train-Tnr3e2AT.js";
57
+ import { S as subscribeLatestFlywheelStatus, _ as listFlywheelRuns, g as isFlywheelRunId, h as init_flywheel_run_state, l as buildClassifyLookups, p as getFlywheelRunDetail, u as init_lookups, w as writeLatestFlywheelStatus, x as resolveLiveFlywheelRunId, y as readCurrentLatestFlywheelStatus } from "./flywheel-CWT_tAoc.js";
58
+ import { f as workspacesRouteLayer, g as getWorkspacePathForIssue, h as processPendingFeedbackDeliveries, m as resumeQueuedMerges, p as enrichReviewStatus } from "./workspaces-CZIS-XzP.js";
59
+ import { _ as init_platform, g as detectPlatform } from "./workspace-manager-C-2qis5x.js";
60
+ import { a as getShadowState, s as init_shadow_state } from "./shadow-state-CH4do7Wh.js";
61
+ import { C as init_dashboard_auth, D as init_review_status$1, E as rejectUnsafeDashboardMutationRequest, S as hasDashboardInternalToken, T as rejectUnauthorizedDashboardSessionMintRequest, _ as groupResourceAllocatedIssuesByProject, b as dashboardCsrfToken, g as getCachedResourceAllocatedIssues, m as issuesRouteLayer, p as init_issues, v as init_resource_discovery, w as rejectUnauthorizedDashboardRequest, x as dashboardSessionCookieHeader, y as sanitizeResourceAllocatedIssues } from "./issues-Dbl4UsRM.js";
62
+ import { a as loadCloisterConfigSync, i as loadCloisterConfig, o as saveCloisterConfigSync, r as init_config$1, s as shouldAutoStart } from "./config-DijD5z28.js";
63
+ import { O as init_specialists, b as getReviewerSessionName } from "./specialists-BRNyT9Ei.js";
64
+ import { H as init_deacon, _t as emergencyBrake, ct as setAgentStoppedNotifier, gt as withConcurrencyLimit, ht as init_concurrency$1, i as autoResumeStoppedWorkAgents, lt as setMergeReadyNotifier, rt as resetPatrolHeartbeatForStartup, st as setAgentStatusChangedNotifier, vt as init_concurrency } from "./deacon-D4jEL_yc.js";
65
65
  import { n as getNoResumeMode, r as init_no_resume_mode, t as disableNoResumeMode } from "./no-resume-mode-DlMPigWY.js";
66
- import { c as init_prd_locations, s as findPrdAtStatusSync } from "./archive-planning-O-QKXVWX.js";
67
- import { a as writeFeedbackFile, i as init_feedback_writer } from "./feedback-writer-D5GpgTWq.js";
68
- import { n as parseSequenceMd, r as writeSequenceMd, t as init_sequence_io } from "./sequence-io-CMiS9KMK.js";
69
- import { _ as computeStats, b as normalizeGate, c as BLOCKS_MAIN_LABEL, d as READY_LABEL, f as RELEASED_LABEL, g as computeLanes, h as computeCohort, l as OBJECTION_LABEL, m as classifyIssue, p as VETOED_LABEL, u as PARKED_LABEL, v as computeWaves, y as init_pickup } from "./flywheel-merge-order-bSoDRUVw.js";
70
- import { _ as sendToRemoteAgent, a as getRemoteAgentOutput, n as checkRemoteSpendCap, o as init_remote_agents, p as loadRemoteAgentState, u as killRemoteAgent, v as spawnRemoteAgent } from "./remote-agents-DQRd2At2.js";
71
- import { _ as init_git_activity, v as listGitOperationsSync } from "./merge-agent-BsELKm49.js";
66
+ import { c as init_prd_locations, s as findPrdAtStatusSync } from "./archive-planning-CgavlD03.js";
67
+ import { a as writeFeedbackFile, i as init_feedback_writer } from "./feedback-writer-0v4RHIwO.js";
68
+ import { n as parseSequenceMd, r as writeSequenceMd, t as init_sequence_io } from "./sequence-io-D_d3bSP4.js";
69
+ import { _ as computeStats, b as normalizeGate, c as BLOCKS_MAIN_LABEL, d as READY_LABEL, f as RELEASED_LABEL, g as computeLanes, h as computeCohort, l as OBJECTION_LABEL, m as classifyIssue, p as VETOED_LABEL, u as PARKED_LABEL, v as computeWaves, y as init_pickup } from "./flywheel-merge-order-3ybBghfu.js";
70
+ import { _ as sendToRemoteAgent, a as getRemoteAgentOutput, n as checkRemoteSpendCap, o as init_remote_agents, p as loadRemoteAgentState, u as killRemoteAgent, v as spawnRemoteAgent } from "./remote-agents-Ckw0Uup4.js";
71
+ import { _ as init_git_activity, v as listGitOperationsSync } from "./merge-agent-CnPd2Pbc.js";
72
72
  import { n as getTldrDaemonServiceSync, r as init_tldr_daemon } from "./tldr-daemon-C4f0Cv5Z.js";
73
- import { i as runMemoryFtsTransaction, n as init_fts_db, r as runMemoryFtsStatement, t as closeMemoryFtsDatabases } from "./fts-db-DH6pFiOa.js";
74
- import { c as init_pending, l as maybeTriggerStatusRollup, o as readRecentObservations, r as init_rollup, u as writePendingTurn } from "./rollup-_dL7JXdO.js";
75
- import { r as specialistsRouteLayer } from "./specialists-DFDg83jj.js";
76
- import { t as getAgentCommandSync } from "./settings-DVFIQrHs.js";
77
- import { n as init_review_agent, r as isExtendedReviewEnabled } from "./review-agent-GjWZBuhW.js";
78
- import { i as isRemoteAvailable, r as init_remote, t as createFlyProviderFromConfig } from "./remote-br-7Zy2V.js";
73
+ import { i as runMemoryFtsTransaction, n as init_fts_db, r as runMemoryFtsStatement, t as closeMemoryFtsDatabases } from "./fts-db-ByIkpwNP.js";
74
+ import { c as init_pending, l as maybeTriggerStatusRollup, o as readRecentObservations, r as init_rollup, u as writePendingTurn } from "./rollup-Mnw9S0dY.js";
75
+ import { r as specialistsRouteLayer } from "./specialists-BAHc5t3F.js";
76
+ import { t as getAgentCommandSync } from "./settings-BYAK9dF4.js";
77
+ import { n as init_review_agent, r as isExtendedReviewEnabled } from "./review-agent-D7LWj3E4.js";
78
+ import { i as isRemoteAvailable, r as init_remote, t as createFlyProviderFromConfig } from "./remote-Cu-ROCd0.js";
79
79
  import { n as init_claude_settings_overlay, t as detectProviderEnvConflicts } from "./claude-settings-overlay-Ck8qNezZ.js";
80
- import { a as init_query_expansion, i as clearQueryExpansionCache, n as init_injection, o as buildMatchQuery, r as injectPromptTimeMemory, s as init_search } from "./injection-CcJERZro.js";
81
- import { _ as init_transcript_adapter, a as generateFallbackSummary, c as handoffPreconditionFallbackReason, d as prependFallbackFocus, f as requestHandoffFromAgent, g as getTranscriptAdapter, i as copySessionFromCompactBoundary, l as init_summary_fork, o as generateSummaryForFork, p as reserveSummaryForkSession, r as authorHandoffExternal, s as handoffFailureReason, u as logHandoffFallback } from "./summary-fork-znoS388v.js";
82
- import { a as init_conversation_compaction, c as shouldInterceptManualCompact, n as compactConversationNative, o as isCompacting } from "./conversation-compaction-DfmqrfYi.js";
83
- import { a as init_render, d as validateTemplate, i as hasManagedRegion, l as init_harness, o as userContentOutsideRegion, t as init_context_layers, u as renderForHarness } from "./context-layers-CIMR-y8_.js";
80
+ import { a as init_query_expansion, i as clearQueryExpansionCache, n as init_injection, o as buildMatchQuery, r as injectPromptTimeMemory, s as init_search } from "./injection-BJIZEo3K.js";
81
+ import { _ as init_transcript_adapter, a as generateFallbackSummary, c as handoffPreconditionFallbackReason, d as prependFallbackFocus, f as requestHandoffFromAgent, g as getTranscriptAdapter, i as copySessionFromCompactBoundary, l as init_summary_fork, o as generateSummaryForFork, p as reserveSummaryForkSession, r as authorHandoffExternal, s as handoffFailureReason, u as logHandoffFallback } from "./summary-fork-CV23Vz3H.js";
82
+ import { a as init_conversation_compaction, c as shouldInterceptManualCompact, n as compactConversationNative, o as isCompacting } from "./conversation-compaction-D96NswFM.js";
83
+ import { a as init_render, d as validateTemplate, i as hasManagedRegion, l as init_harness, o as userContentOutsideRegion, t as init_context_layers, u as renderForHarness } from "./context-layers-SF7iOUH9.js";
84
84
  import { c as init_github_app, s as getPullRequestState } from "./github-app-DgISqJqI.js";
85
85
  import { i as parseArtifactRef, r as init_forge } from "./forge-mcRx-ba-.js";
86
- import { a as spawnSequencerAgent, i as init_sequencer_agent, n as clearFinishedSequencerRun, r as getSequencerRunStatus, t as SEQUENCER_AGENT_ID } from "./sequencer-agent-CFrrqU0M.js";
87
- import { i as listTranscriptCheckpoints, r as getTranscriptCheckpoint$1 } from "./checkpoints-9h0pTZ5k.js";
86
+ import { a as spawnSequencerAgent, i as init_sequencer_agent, n as clearFinishedSequencerRun, r as getSequencerRunStatus, t as SEQUENCER_AGENT_ID } from "./sequencer-agent-9ByBYskx.js";
87
+ import { i as listTranscriptCheckpoints, r as getTranscriptCheckpoint$1 } from "./checkpoints-D9IV1yvV.js";
88
88
  import { createRequire } from "node:module";
89
89
  import { Cause, Context, Data, Effect, Exit, Fiber, FileSystem, Layer, Option, Path, Queue, Result, Schedule, Schema, Stream } from "effect";
90
90
  import { createReadStream, createWriteStream, existsSync, fstatSync, mkdirSync, readFileSync, statSync, writeFileSync } from "fs";
@@ -628,7 +628,7 @@ const AgentSpawnerLive = Layer.effect(AgentSpawner, Effect.sync(() => ({
628
628
  const beadsDir = join$1(workspacePath, ".beads");
629
629
  const projectBeadsDir = join$1(workspacePath, "..", "..", ".beads");
630
630
  if (!(existsSync$1(beadsDir) || existsSync$1(projectBeadsDir))) throw new BeadsNotInitialized({ workspace: workspacePath });
631
- const { getAgentState, spawnAgent, normalizeAgentId } = await import("./agents-DsFz3A8y.js");
631
+ const { getAgentState, spawnAgent, normalizeAgentId } = await import("./agents-C5t_gXWd.js");
632
632
  const normalizedId = normalizeAgentId(issueId);
633
633
  if ((await Effect.runPromise(getAgentState(normalizedId)))?.status === "running") throw new AgentAlreadyRunning({ id: issueId });
634
634
  return {
@@ -659,7 +659,7 @@ const AgentSpawnerLive = Layer.effect(AgentSpawner, Effect.sync(() => ({
659
659
  const { workspacePath, projectPath, issue } = opts;
660
660
  if (!existsSync$1(workspacePath)) throw new WorkspaceNotFound({ id: issueId });
661
661
  const sessionName = opts.sessionName ?? `planning-${issueId.toLowerCase()}`;
662
- const { spawnPlanningSession } = await import("./spawn-planning-session-DnUv0hSH.js");
662
+ const { spawnPlanningSession } = await import("./spawn-planning-session-Br1BnCOe.js");
663
663
  const result = await spawnPlanningSession({
664
664
  issue: {
665
665
  id: issue.id,
@@ -692,14 +692,14 @@ const AgentSpawnerLive = Layer.effect(AgentSpawner, Effect.sync(() => ({
692
692
  }),
693
693
  kill: (agentId) => Effect.tryPromise({
694
694
  try: async () => {
695
- const { stopAgent } = await import("./agents-DsFz3A8y.js");
695
+ const { stopAgent } = await import("./agents-C5t_gXWd.js");
696
696
  await Effect.runPromise(stopAgent(agentId));
697
697
  },
698
698
  catch: () => void 0
699
699
  }).pipe(Effect.ignore),
700
700
  message: (agentId, msg) => Effect.tryPromise({
701
701
  try: async () => {
702
- const { messageAgent } = await import("./agents-DsFz3A8y.js");
702
+ const { messageAgent } = await import("./agents-C5t_gXWd.js");
703
703
  await messageAgent(agentId, msg);
704
704
  },
705
705
  catch: (err) => new AgentStartError({
@@ -710,8 +710,8 @@ const AgentSpawnerLive = Layer.effect(AgentSpawner, Effect.sync(() => ({
710
710
  }),
711
711
  deepWipe: (issueId, opts) => Effect.tryPromise({
712
712
  try: async () => {
713
- const { deepWipe } = await import("./workflows-LNUGDzVu.js");
714
- const { resolveProjectFromIssueSync } = await import("./projects-DWBDcB6V.js");
713
+ const { deepWipe } = await import("./workflows-BNDOBAfu.js");
714
+ const { resolveProjectFromIssueSync } = await import("./projects-Bx1iT8WM.js");
715
715
  const project = resolveProjectFromIssueSync(issueId);
716
716
  const projectPath = project?.projectPath ?? process.cwd();
717
717
  await Effect.runPromise(deepWipe({
@@ -767,8 +767,8 @@ const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
767
767
  const { workspacePath, branch } = getWorkspacePath(issueId);
768
768
  const issueLower = issueId.toLowerCase();
769
769
  if (existsSync$1(workspacePath)) return workspacePath;
770
- const { createWorkspace } = await import("./workspace-manager-XDNuCCXG.js");
771
- const { loadProjectsConfigSync } = await import("./projects-DWBDcB6V.js");
770
+ const { createWorkspace } = await import("./workspace-manager-B7Ji7R9Y.js");
771
+ const { loadProjectsConfigSync } = await import("./projects-Bx1iT8WM.js");
772
772
  const { projects } = loadProjectsConfigSync();
773
773
  const project = resolveProjectFromIssueSync(issueId);
774
774
  if (!project) throw new WorkspaceCreateError({
@@ -803,7 +803,7 @@ const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
803
803
  const { workspacePath } = getWorkspacePath(issueId);
804
804
  const issueLower = issueId.toLowerCase();
805
805
  if (!existsSync$1(workspacePath)) throw new WorkspaceNotFound({ id: issueId });
806
- const { removeWorkspace } = await import("./workspace-manager-XDNuCCXG.js");
806
+ const { removeWorkspace } = await import("./workspace-manager-B7Ji7R9Y.js");
807
807
  const project = resolveProjectFromIssueSync(issueId);
808
808
  if (!project) throw new WorkspaceCreateError({
809
809
  id: issueId,
@@ -834,7 +834,7 @@ const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
834
834
  try: async () => {
835
835
  const { workspacePath } = getWorkspacePath(issueId);
836
836
  const issueLower = issueId.toLowerCase();
837
- const { stopWorkspaceDocker } = await import("./workspace-manager-XDNuCCXG.js");
837
+ const { stopWorkspaceDocker } = await import("./workspace-manager-B7Ji7R9Y.js");
838
838
  await Effect.runPromise(stopWorkspaceDocker(workspacePath, issueLower));
839
839
  },
840
840
  catch: () => void 0
@@ -903,7 +903,7 @@ const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
903
903
  join$1(workspacePath, ".devcontainer", "docker-compose.devcontainer.yml")
904
904
  ];
905
905
  if (!composePaths.find((p) => existsSync$1(p))) {
906
- const { ensureDevcontainerSync } = await import("./ensure-devcontainer-Uu-fGqwo.js");
906
+ const { ensureDevcontainerSync } = await import("./ensure-devcontainer-DLZ2bnuQ.js");
907
907
  const ensure = ensureDevcontainerSync({
908
908
  workspacePath,
909
909
  issueId
@@ -29672,7 +29672,7 @@ const PanRpcLayer = PanRpcGroup.toLayer(Effect.gen(function* () {
29672
29672
  [WS_METHODS.terminalClose]: (input) => terminalService.close(input.sessionName),
29673
29673
  [WS_METHODS.subscribeConversationMessages]: (input) => Stream.unwrap(Effect.gen(function* () {
29674
29674
  const conv = getConversationByName(input.conversationName);
29675
- if (!conv && /^(agent-|planning-|specialist-)/.test(input.conversationName)) {
29675
+ if (!conv && /^(agent-|planning-|specialist-|strike-|inspect-)|^(flywheel-orchestrator|conv-flywheel-orchestrator)$/.test(input.conversationName)) {
29676
29676
  const harness = yield* Effect.promise(() => resolveAgentHarness(input.conversationName));
29677
29677
  if (harness === "ohmypi") return streamResolvedFullParseSnapshots(() => resolvePiSessionPath(input.conversationName), parseOhmypiConversationMessages, null);
29678
29678
  if (harness === "pi") return streamResolvedFullParseSnapshots(() => resolvePiSessionPath(input.conversationName), parsePiConversationMessages, null);
@@ -29696,11 +29696,7 @@ const PanRpcLayer = PanRpcGroup.toLayer(Effect.gen(function* () {
29696
29696
  Queue.offerUnsafe(queue, event);
29697
29697
  } catch {}
29698
29698
  };
29699
- const initial = await parseConversationMessages(sessionFile, 0, {
29700
- pendingToolUse: /* @__PURE__ */ new Map(),
29701
- unresolvedResults: /* @__PURE__ */ new Map(),
29702
- lastSequence: 0
29703
- });
29699
+ const initial = await parseEntireConversation(sessionFile, { flushPendingToolUse: false });
29704
29700
  let currentByteOffset = initial.byteOffset;
29705
29701
  let currentContextUsage = contextUsageFromParseResult(initial, model);
29706
29702
  let highWaterCount = initial.messages.length;
@@ -36870,6 +36866,220 @@ function isAbortError(error) {
36870
36866
  return error instanceof Error && error.name === "AbortError";
36871
36867
  }
36872
36868
  //#endregion
36869
+ //#region ../../lib/overdeck/legacy-import.ts
36870
+ init_driver();
36871
+ init_conversations();
36872
+ function previewLegacyConversations(path) {
36873
+ if (!existsSync$1(path)) return { found: false };
36874
+ const db = openDatabase(path, { readOnly: true });
36875
+ try {
36876
+ const legacyRows = db.prepare(`SELECT name, title, created_at, model, last_attached_at, claude_session_id
36877
+ FROM conversations
36878
+ ORDER BY created_at DESC`).all();
36879
+ const favSet = new Set(db.prepare(`SELECT item_id FROM favorites WHERE type = 'conversation'`).all().map((r) => r.item_id));
36880
+ const rows = [];
36881
+ for (const row of legacyRows) {
36882
+ if (isAgentConversationName(row.name)) continue;
36883
+ rows.push({
36884
+ name: row.name,
36885
+ title: row.title,
36886
+ createdAt: row.created_at,
36887
+ model: row.model,
36888
+ lastActivityAt: row.last_attached_at,
36889
+ messageCount: null,
36890
+ hasFavorite: favSet.has(row.name),
36891
+ claudeSessionId: row.claude_session_id,
36892
+ alreadyImported: getConversationByName(row.name) !== null
36893
+ });
36894
+ }
36895
+ return {
36896
+ found: true,
36897
+ rows
36898
+ };
36899
+ } finally {
36900
+ db.close();
36901
+ }
36902
+ }
36903
+ const LEGACY_CONVERSATION_COLUMNS = [
36904
+ "id",
36905
+ "name",
36906
+ "tmux_session",
36907
+ "status",
36908
+ "cwd",
36909
+ "created_at",
36910
+ "ended_at",
36911
+ "last_attached_at",
36912
+ "session_file",
36913
+ "claude_session_id",
36914
+ "title",
36915
+ "title_source",
36916
+ "title_seed",
36917
+ "total_cost",
36918
+ "total_tokens",
36919
+ "archived_at",
36920
+ "model",
36921
+ "effort",
36922
+ "fork_status",
36923
+ "fork_error",
36924
+ "harness",
36925
+ "delivery_method",
36926
+ "spawn_error",
36927
+ "handoff_doc_path",
36928
+ "handoff_target_conv_id",
36929
+ "fork_fallback_reason",
36930
+ "cleared_to_conv_id",
36931
+ "fork_request",
36932
+ "fork_retry_count"
36933
+ ];
36934
+ function normalizeLegacyRow(row) {
36935
+ return {
36936
+ id: row.id,
36937
+ name: row.name,
36938
+ tmux_session: row.tmux_session ?? null,
36939
+ status: row.status ?? null,
36940
+ cwd: row.cwd ?? "",
36941
+ created_at: row.created_at ?? null,
36942
+ ended_at: row.ended_at ?? null,
36943
+ last_attached_at: row.last_attached_at ?? null,
36944
+ session_file: row.session_file ?? null,
36945
+ claude_session_id: row.claude_session_id ?? null,
36946
+ title: row.title ?? null,
36947
+ title_source: row.title_source ?? null,
36948
+ title_seed: row.title_seed ?? null,
36949
+ total_cost: row.total_cost ?? null,
36950
+ total_tokens: row.total_tokens ?? null,
36951
+ archived_at: row.archived_at ?? null,
36952
+ model: row.model ?? null,
36953
+ effort: row.effort ?? null,
36954
+ fork_status: row.fork_status ?? null,
36955
+ fork_error: row.fork_error ?? null,
36956
+ harness: row.harness ?? null,
36957
+ delivery_method: row.delivery_method ?? null,
36958
+ spawn_error: row.spawn_error ?? null,
36959
+ handoff_doc_path: row.handoff_doc_path ?? null,
36960
+ handoff_target_conv_id: row.handoff_target_conv_id ?? null,
36961
+ fork_fallback_reason: row.fork_fallback_reason ?? null,
36962
+ cleared_to_conv_id: row.cleared_to_conv_id ?? null,
36963
+ fork_request: row.fork_request ?? null,
36964
+ fork_retry_count: row.fork_retry_count ?? null
36965
+ };
36966
+ }
36967
+ function parseIsoToMs(iso) {
36968
+ if (!iso) return null;
36969
+ const ms = new Date(iso).getTime();
36970
+ return Number.isNaN(ms) ? null : ms;
36971
+ }
36972
+ function importLegacyConversations(path, names) {
36973
+ const result = {
36974
+ imported: [],
36975
+ skipped: [],
36976
+ failed: [],
36977
+ warnings: [],
36978
+ favoritesCarried: 0
36979
+ };
36980
+ if (!existsSync$1(path) || names.length === 0) return result;
36981
+ const db = openDatabase(path, { readOnly: true });
36982
+ let legacyRows;
36983
+ let favSet;
36984
+ try {
36985
+ const existingCols = new Set(db.prepare(`PRAGMA table_info(conversations)`).all().map((c) => c.name));
36986
+ const selectCols = LEGACY_CONVERSATION_COLUMNS.filter((c) => existingCols.has(c));
36987
+ const placeholders = names.map(() => "?").join(", ");
36988
+ legacyRows = db.prepare(`SELECT ${selectCols.join(", ")}
36989
+ FROM conversations WHERE name IN (${placeholders})`).all(...names).map(normalizeLegacyRow);
36990
+ favSet = new Set(db.prepare(`SELECT item_id FROM favorites WHERE type = 'conversation'`).all().map((r) => r.item_id));
36991
+ } finally {
36992
+ db.close();
36993
+ }
36994
+ const rowidToUuid = /* @__PURE__ */ new Map();
36995
+ for (const row of legacyRows) {
36996
+ if (isAgentConversationName(row.name)) {
36997
+ result.skipped.push({
36998
+ name: row.name,
36999
+ reason: "agent/planning/specialist conversation excluded from import"
37000
+ });
37001
+ continue;
37002
+ }
37003
+ const createdAtMs = parseIsoToMs(row.created_at);
37004
+ if (createdAtMs === null) {
37005
+ result.failed.push({
37006
+ name: row.name,
37007
+ reason: `unparseable created_at: ${String(row.created_at)}`
37008
+ });
37009
+ continue;
37010
+ }
37011
+ if (getConversationByName(row.name) !== null) {
37012
+ result.skipped.push({
37013
+ name: row.name,
37014
+ reason: "name already exists in overdeck.db"
37015
+ });
37016
+ continue;
37017
+ }
37018
+ if (row.claude_session_id && getConversationByClaudeSessionId(row.claude_session_id) !== null) {
37019
+ result.skipped.push({
37020
+ name: row.name,
37021
+ reason: "claude_session_id already registered in overdeck.db"
37022
+ });
37023
+ continue;
37024
+ }
37025
+ const archivedAtMs = parseIsoToMs(row.archived_at);
37026
+ const status = row.status ?? (archivedAtMs ? "ended" : "active");
37027
+ const { uuid } = importLegacyConversation({
37028
+ name: row.name,
37029
+ tmuxSession: row.tmux_session,
37030
+ status,
37031
+ cwd: row.cwd,
37032
+ createdAt: createdAtMs,
37033
+ endedAt: parseIsoToMs(row.ended_at),
37034
+ lastAttachedAt: parseIsoToMs(row.last_attached_at),
37035
+ sessionFile: row.session_file,
37036
+ claudeSessionId: row.claude_session_id,
37037
+ title: row.title,
37038
+ titleSource: row.title_source,
37039
+ titleSeed: row.title_seed,
37040
+ totalCost: row.total_cost ?? 0,
37041
+ totalTokens: row.total_tokens ?? 0,
37042
+ archivedAt: archivedAtMs,
37043
+ model: row.model,
37044
+ effort: row.effort,
37045
+ forkStatus: row.fork_status,
37046
+ forkError: row.fork_error,
37047
+ harness: row.harness,
37048
+ deliveryMethod: row.delivery_method,
37049
+ spawnError: row.spawn_error,
37050
+ handoffDocPath: row.handoff_doc_path,
37051
+ forkFallbackReason: row.fork_fallback_reason,
37052
+ forkRequest: row.fork_request,
37053
+ forkRetryCount: row.fork_retry_count ?? 0
37054
+ });
37055
+ rowidToUuid.set(row.id, uuid);
37056
+ result.imported.push(row.name);
37057
+ if (favSet.has(row.name)) {
37058
+ setFavorite("conversation", row.name);
37059
+ result.favoritesCarried++;
37060
+ }
37061
+ }
37062
+ for (const row of legacyRows) {
37063
+ const uuid = rowidToUuid.get(row.id);
37064
+ if (!uuid) continue;
37065
+ const handoffTargetUuid = row.handoff_target_conv_id != null ? rowidToUuid.get(row.handoff_target_conv_id) ?? null : null;
37066
+ const clearedToUuid = row.cleared_to_conv_id != null ? rowidToUuid.get(row.cleared_to_conv_id) ?? null : null;
37067
+ if (row.handoff_target_conv_id != null && handoffTargetUuid === null) result.warnings.push({
37068
+ name: row.name,
37069
+ reason: `handoff target (legacy rowid ${row.handoff_target_conv_id}) was not imported; handoff_target_conv_id set to NULL`
37070
+ });
37071
+ if (row.cleared_to_conv_id != null && clearedToUuid === null) result.warnings.push({
37072
+ name: row.name,
37073
+ reason: `cleared_to target (legacy rowid ${row.cleared_to_conv_id}) was not imported; cleared_to_conv_id set to NULL`
37074
+ });
37075
+ if (handoffTargetUuid !== null || clearedToUuid !== null) setImportedConversationLinks(uuid, {
37076
+ handoffTargetUuid,
37077
+ clearedToUuid
37078
+ });
37079
+ }
37080
+ return result;
37081
+ }
37082
+ //#endregion
36873
37083
  //#region routes/settings.ts
36874
37084
  /**
36875
37085
  * Settings route module — Effect HttpRouter.Layer (PAN-428 B15)
@@ -36887,6 +37097,7 @@ init_providers();
36887
37097
  init_http_handler();
36888
37098
  init_agents$2();
36889
37099
  init_config_yaml();
37100
+ init_paths();
36890
37101
  const REINDEX_CONFIRM_THRESHOLD_USD = 1;
36891
37102
  const REINDEX_CONFIRM_TTL_MS = 600 * 1e3;
36892
37103
  const reindexConfirmationNonces = /* @__PURE__ */ new Map();
@@ -37688,7 +37899,41 @@ const getProviderEnvConflictsRoute = HttpRouter.add("GET", "/api/settings/provid
37688
37899
  }
37689
37900
  });
37690
37901
  })));
37691
- const settingsRouteLayer = Layer.mergeAll(getSettingsRoute, getAvailableModelsRoute, getOptimalDefaultsRoute, getMiniMaxDefaultsRoute, getClaudeAuthRoute, getOpenAIAuthRoute, postTestApiKeyRoute, postValidateApiKeyRoute, getConversationSearchStatusRoute, getConversationSearchReindexEstimateRoute, postConversationSearchReindexRoute, getConversationSearchReindexProgressRoute, putSettingsRoute, putUiThemeRoute, getOpenRouterModelsRoute, putOpenRouterFavoritesRoute, putOpenRouterApiKeyRoute, postOpenRouterTestKeyRoute, getHarnessPolicyRoute, getProviderEnvConflictsRoute);
37902
+ const getLegacyImportPreviewRoute = HttpRouter.add("GET", "/api/settings/legacy-import/conversations", httpHandler(Effect.gen(function* () {
37903
+ const request = yield* HttpServerRequest.HttpServerRequest;
37904
+ return yield* Effect.try({
37905
+ try: () => {
37906
+ const urlPath = new URL(request.url, "http://localhost").searchParams.get("path");
37907
+ const defaultPath = join$1(getLegacyHome(), "panopticon.db");
37908
+ const resolvedPath = urlPath?.trim() || defaultPath;
37909
+ const preview = previewLegacyConversations(resolvedPath);
37910
+ if (!preview.found) return jsonResponse({
37911
+ found: false,
37912
+ defaultPath,
37913
+ message: `No legacy database found at ${resolvedPath}`
37914
+ });
37915
+ return jsonResponse({
37916
+ found: true,
37917
+ path: resolvedPath,
37918
+ conversations: preview.rows
37919
+ });
37920
+ },
37921
+ catch: (err) => jsonResponse({ error: err instanceof Error ? err.message : String(err) }, { status: 500 })
37922
+ });
37923
+ })));
37924
+ const postLegacyImportRoute = HttpRouter.add("POST", "/api/settings/legacy-import/conversations", httpHandler(Effect.gen(function* () {
37925
+ const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
37926
+ if (authError) return authError;
37927
+ const body = yield* readJsonBody$8;
37928
+ return yield* Effect.try({
37929
+ try: () => {
37930
+ const { path, names } = body;
37931
+ return jsonResponse(importLegacyConversations(path, names));
37932
+ },
37933
+ catch: (err) => jsonResponse({ error: err instanceof Error ? err.message : String(err) }, { status: 500 })
37934
+ });
37935
+ })));
37936
+ const settingsRouteLayer = Layer.mergeAll(getSettingsRoute, getAvailableModelsRoute, getOptimalDefaultsRoute, getMiniMaxDefaultsRoute, getClaudeAuthRoute, getOpenAIAuthRoute, postTestApiKeyRoute, postValidateApiKeyRoute, getConversationSearchStatusRoute, getConversationSearchReindexEstimateRoute, postConversationSearchReindexRoute, getConversationSearchReindexProgressRoute, putSettingsRoute, putUiThemeRoute, getOpenRouterModelsRoute, putOpenRouterFavoritesRoute, putOpenRouterApiKeyRoute, postOpenRouterTestKeyRoute, getHarnessPolicyRoute, getProviderEnvConflictsRoute, getLegacyImportPreviewRoute, postLegacyImportRoute);
37692
37937
  //#endregion
37693
37938
  //#region routes/autopreso.ts
37694
37939
  init_http_helpers();
@@ -37761,6 +38006,7 @@ init_http_helpers();
37761
38006
  init_domain_services();
37762
38007
  init_service();
37763
38008
  init_agents$2();
38009
+ init_cost_sync();
37764
38010
  init_git_activity();
37765
38011
  init_http_handler();
37766
38012
  let _cachedReviewStatuses = null;
@@ -37789,13 +38035,14 @@ const getMetricsSummaryRoute = HttpRouter.add("GET", "/api/metrics/summary", htt
37789
38035
  const service = getCloisterService();
37790
38036
  const status = service.getStatus();
37791
38037
  const costSummary = service.getCostSummary();
38038
+ const todayCost = getTodayCostSync();
37792
38039
  const topAgents = costSummary.topAgents.slice(0, 5);
37793
38040
  const topIssues = costSummary.topIssues.slice(0, 5);
37794
38041
  const runningAgents = yield* listRunningAgents();
37795
38042
  const stuckCount = computeStuckCount(status.agentsNeedingAttention, (id) => service.getAgentHealth(id), buildAgentIssueMap(runningAgents), getReviewStatusesCached());
37796
38043
  return jsonResponse({
37797
38044
  today: {
37798
- totalCost: Math.round(costSummary.dailyTotal * 100) / 100,
38045
+ totalCost: Math.round(todayCost * 100) / 100,
37799
38046
  agentCount: status.summary.total,
37800
38047
  activeCount: status.summary.active,
37801
38048
  stuckCount,
@@ -38541,7 +38788,7 @@ const getVersionRoute = HttpRouter.add("GET", "/api/version", Effect.promise(asy
38541
38788
  const version = await getOverdeckVersion();
38542
38789
  let supervisorUrl = null;
38543
38790
  try {
38544
- const { getSupervisorUrlSync } = await import("./supervisor-ti-xrTNH.js");
38791
+ const { getSupervisorUrlSync } = await import("./supervisor-DVlsIgfZ.js");
38545
38792
  supervisorUrl = getSupervisorUrlSync();
38546
38793
  } catch {}
38547
38794
  return jsonResponse({
@@ -38637,7 +38884,7 @@ const getPlanningStatusRoute = HttpRouter.add("GET", "/api/planning/:issueId/sta
38637
38884
  const remoteState = loadRemoteAgentState(sessionName);
38638
38885
  const isRemote = !!remoteState;
38639
38886
  const vmName = remoteState?.vmName ?? "";
38640
- const { getAgentStateSync } = await import("./agents-DsFz3A8y.js");
38887
+ const { getAgentStateSync } = await import("./agents-C5t_gXWd.js");
38641
38888
  const agentStarting = getAgentStateSync(sessionName)?.status === "starting";
38642
38889
  let tmuxSessionAlive = false;
38643
38890
  if (!isRemote) try {
@@ -38780,7 +39027,7 @@ Continue the PLANNING session. Do NOT implement anything.
38780
39027
  `);
38781
39028
  const agentCwd = workspacePath;
38782
39029
  if (existsSync$1(outputFile)) await rename(outputFile, join$1(planningDir, `output-${Date.now()}.jsonl`));
38783
- const { getAgentCommandSync } = await import("./settings-oOlkt2wY.js");
39030
+ const { getAgentCommandSync } = await import("./settings-wPqxbDcV.js");
38784
39031
  let msgPlanningModel = "claude-sonnet-4-6";
38785
39032
  try {
38786
39033
  msgPlanningModel = resolveModel("plan", void 0, loadConfigSync().config);
@@ -39046,7 +39293,7 @@ const postShadowMonitorRoute = HttpRouter.add("POST", "/api/shadow/:issueId/moni
39046
39293
  const projectPath = await getProjectPath(issuePrefix);
39047
39294
  const workspacePath = join$1(projectPath, "workspaces", `feature-${issueLower}`);
39048
39295
  if (!existsSync$1(workspacePath)) return jsonResponse({ error: "Workspace not found" }, { status: 404 });
39049
- const { gatherArtifacts, generateBasicInference, updateInferenceDocumentSync } = await import("./shadow-engineering-eRFcHl7F.js");
39296
+ const { gatherArtifacts, generateBasicInference, updateInferenceDocumentSync } = await import("./shadow-engineering-BZTBik_h.js");
39050
39297
  const config = {
39051
39298
  issueId,
39052
39299
  workspacePath,
@@ -39076,7 +39323,7 @@ const postShadowObserveRoute = HttpRouter.add("POST", "/api/shadow/:issueId/obse
39076
39323
  if (!existsSync$1(workspacePath)) return jsonResponse({ error: "Workspace not found" }, { status: 404 });
39077
39324
  const ghConfig = getGitHubConfig();
39078
39325
  if (!ghConfig) return jsonResponse({ error: "GitHub not configured - Observer requires GitHub" }, { status: 400 });
39079
- const { runObserverCycle } = await import("./shadow-engineering-eRFcHl7F.js");
39326
+ const { runObserverCycle } = await import("./shadow-engineering-BZTBik_h.js");
39080
39327
  const firstRepo = ghConfig.repos[0];
39081
39328
  const config = {
39082
39329
  issueId,
@@ -40416,7 +40663,7 @@ async function cleanupConversationAttachments(name) {
40416
40663
  * sessions that the lifecycle poller missed. */
40417
40664
  async function cleanupOrphanedConversationAttachments() {
40418
40665
  try {
40419
- const { listConversations } = await import("./conversations-BtRONkWR.js");
40666
+ const { listConversations } = await import("./conversations-CEIxKTYY.js");
40420
40667
  const convNames = new Set(listConversations().map((c) => c.name));
40421
40668
  const root = getConversationAttachmentsRoot();
40422
40669
  await runInBatches((await readdir(root, { withFileTypes: true })).filter((entry) => entry.isDirectory() && !convNames.has(entry.name)).map((entry) => join$1(root, entry.name)), 10, (path) => rm(path, {
@@ -40942,18 +41189,21 @@ async function waitForClaudeReady(tmuxSession) {
40942
41189
  }
40943
41190
  console.warn(`[conversations] Timed out waiting for Claude Code prompt in ${tmuxSession}`);
40944
41191
  }
41192
+ function isPiTuiInputReady(snapshot) {
41193
+ return /^\s*[❯›>]\s/m.test(snapshot) || /(?:^|\s)0(?:\.\d+)?%\s+context\s+used\b/i.test(snapshot);
41194
+ }
40945
41195
  /**
40946
- * Wait until Pi's TUI has rendered into the tmux pane.
41196
+ * Wait until Pi's TUI is accepting input in the tmux pane.
40947
41197
  *
40948
41198
  * Pi TUI mode does not write a ready.json marker (that was an RPC-mode
40949
- * artifact). We instead poll capture-pane for non-empty content, which
40950
- * indicates Pi has drawn at least its title/prompt line. This is the same
40951
- * shape of readiness check we use for Claude Code's interactive prompt.
41199
+ * artifact). Splash/header output can appear before the prompt is wired; wait
41200
+ * for the actual prompt/context footer so first-turn handoff delivery is not
41201
+ * pasted into a not-yet-ready TUI.
40952
41202
  */
40953
41203
  async function waitForPiTuiReady(tmuxSession, timeoutMs = 3e4) {
40954
41204
  const deadline = Date.now() + timeoutMs;
40955
41205
  while (Date.now() < deadline) {
40956
- if ((await Effect.runPromise(capturePane(tmuxSession, 10).pipe(Effect.catch(() => Effect.succeed(""))))).trim().length > 0) {
41206
+ if (isPiTuiInputReady(await Effect.runPromise(capturePane(tmuxSession, 40).pipe(Effect.catch(() => Effect.succeed("")))))) {
40957
41207
  console.log(`[conversations] Pi TUI ready for ${tmuxSession}`);
40958
41208
  return true;
40959
41209
  }
@@ -40962,6 +41212,39 @@ async function waitForPiTuiReady(tmuxSession, timeoutMs = 3e4) {
40962
41212
  console.warn(`[conversations] Timed out waiting for Pi TUI to render in ${tmuxSession}`);
40963
41213
  return false;
40964
41214
  }
41215
+ /**
41216
+ * Find a Claude Code session JSONL by its (globally-unique) session id, searching
41217
+ * every project dir under ~/.claude/projects/. Claude keys session files by the
41218
+ * cwd AT RUNTIME, so when a repo directory is renamed (e.g. Projects/panopticon-cli
41219
+ * → Projects/overdeck) a conversation's recorded cwd goes stale and the
41220
+ * deterministic sessionFilePath(cwd, id) points at a dir that no longer exists,
41221
+ * while the JSONL itself lives under the new encoded dir. A by-id search recovers
41222
+ * it. Mirrors the cross-dir lookup the non-DB specialist/agent fallback already
41223
+ * uses below.
41224
+ */
41225
+ async function findClaudeSessionFileById(sessionId) {
41226
+ if (!SAFE_SESSION_ID_PATTERN.test(sessionId)) return null;
41227
+ try {
41228
+ const claudeProjects = join$1(homedir$1(), ".claude", "projects");
41229
+ const dirs = await readdir(claudeProjects);
41230
+ const SAFE_DIR_PATTERN = /^[a-zA-Z0-9_.-]+$/;
41231
+ const candidates = dirs.filter((dir) => SAFE_DIR_PATTERN.test(dir)).map((dir) => join$1(claudeProjects, dir, `${sessionId}.jsonl`));
41232
+ const STAT_BATCH_SIZE = 50;
41233
+ for (let i = 0; i < candidates.length; i += STAT_BATCH_SIZE) {
41234
+ const batch = candidates.slice(i, i + STAT_BATCH_SIZE);
41235
+ const found = (await Promise.all(batch.map(async (candidate) => {
41236
+ try {
41237
+ await stat$1(candidate);
41238
+ return candidate;
41239
+ } catch {
41240
+ return null;
41241
+ }
41242
+ }))).find((c) => c !== null);
41243
+ if (found) return found;
41244
+ }
41245
+ } catch {}
41246
+ return null;
41247
+ }
40965
41248
  async function resolveSessionFile(conv) {
40966
41249
  if (conv.harness === "ohmypi" || conv.harness === "pi") {
40967
41250
  const piPath = await resolvePiSessionPath(conv.tmuxSession);
@@ -40972,7 +41255,11 @@ async function resolveSessionFile(conv) {
40972
41255
  if (codexPath) return codexPath;
40973
41256
  }
40974
41257
  const sessionId = await readLauncherPinnedSessionId(conv.tmuxSession) ?? conv.claudeSessionId;
40975
- if (sessionId) return sessionFilePath(conv.cwd, sessionId);
41258
+ if (sessionId) {
41259
+ const deterministic = sessionFilePath(conv.cwd, sessionId);
41260
+ if (existsSync$1(deterministic)) return deterministic;
41261
+ return await findClaudeSessionFileById(sessionId) ?? deterministic;
41262
+ }
40976
41263
  console.error(`[conversations] UNRESOLVED claude-code session for conversation '${conv.name}' (tmux=${conv.tmuxSession}, status=${conv.status}, cwd=${conv.cwd}): no --session-id pinned in launcher.sh and no recorded claudeSessionId. The transcript panel cannot be trusted.`);
40977
41264
  return null;
40978
41265
  }
@@ -41468,7 +41755,7 @@ async function spawnConversationSession(tmuxSession, cwd, claudeSessionId, model
41468
41755
  const codexApprovalPolicy = codexPermMode === "full-access" ? "never" : "on-request";
41469
41756
  const codexSandboxMode = codexPermMode === "full-access" ? "danger-full-access" : codexPermMode === "read-only" ? "read-only" : "workspace-write";
41470
41757
  const codexApprovalsReviewer = codexPermMode === "auto-review" ? "auto_review" : void 0;
41471
- const { initCodexHome, extractThreadIdFromRollout } = await import("./codex-sd8uk-U3.js");
41758
+ const { initCodexHome, extractThreadIdFromRollout } = await import("./codex-DZZiDgis.js");
41472
41759
  initCodexHome(codexHome, {
41473
41760
  trustedDir: cwd,
41474
41761
  approvalPolicy: codexApprovalPolicy,
@@ -41538,7 +41825,7 @@ async function spawnConversationSession(tmuxSession, cwd, claudeSessionId, model
41538
41825
  } catch {}
41539
41826
  console.log(`[claude-invoke] purpose=conversation-session | model=${model || "default"} | source=conversations.ts:spawnConversationSession | session=${tmuxSession} | resume=${resume} | command="${runtimeCommand}"`);
41540
41827
  try {
41541
- const { preTrustDirectory } = await import("./workspace-manager-XDNuCCXG.js");
41828
+ const { preTrustDirectory } = await import("./workspace-manager-B7Ji7R9Y.js");
41542
41829
  preTrustDirectory(cwd);
41543
41830
  } catch {}
41544
41831
  try {
@@ -41555,7 +41842,7 @@ async function spawnConversationSession(tmuxSession, cwd, claudeSessionId, model
41555
41842
  const codexHomeDir = codexFields.codexHome;
41556
41843
  (async () => {
41557
41844
  try {
41558
- const { waitForCodexRollout, extractThreadIdFromRollout, writeThreadId } = await import("./codex-sd8uk-U3.js");
41845
+ const { waitForCodexRollout, extractThreadIdFromRollout, writeThreadId } = await import("./codex-DZZiDgis.js");
41559
41846
  const rollout = await waitForCodexRollout(codexHomeDir, 12e4);
41560
41847
  if (rollout) {
41561
41848
  const threadId = extractThreadIdFromRollout(rollout);
@@ -41796,6 +42083,9 @@ const listEnrichmentInFlight = /* @__PURE__ */ new Map();
41796
42083
  function conversationSessionAliveFromState(conv, tmuxSessionAlive) {
41797
42084
  return conv.status === "active" && !conv.forkStatus && tmuxSessionAlive;
41798
42085
  }
42086
+ function conversationNeedsRunningRepair(conv, tmuxSessionAlive, harnessProcessAlive) {
42087
+ return conv.status === "ended" && !conv.forkStatus && tmuxSessionAlive && harnessProcessAlive;
42088
+ }
41799
42089
  function getEnrichedConversationList(limit, offset) {
41800
42090
  const key = `${limit}:${offset}`;
41801
42091
  const now = Date.now();
@@ -41820,16 +42110,31 @@ async function enrichConversationList(limit, offset) {
41820
42110
  offset
41821
42111
  });
41822
42112
  const favoritedNames = getCachedFavoritedIds();
42113
+ const ledgerCosts = getConversationLedgerCosts();
41823
42114
  const liveSessionNames = new Set(await Effect.runPromise(listSessionNames()));
41824
42115
  return Effect.runPromise(withConcurrencyLimit(conversations.map((conv) => Effect.promise(async () => {
41825
- const sessionAlive = conversationSessionAliveFromState(conv, liveSessionNames.has(conv.tmuxSession));
42116
+ let row = conv;
42117
+ const tmuxSessionAlive = liveSessionNames.has(conv.tmuxSession);
42118
+ let sessionAlive = conversationSessionAliveFromState(row, tmuxSessionAlive);
42119
+ if (!sessionAlive && row.status === "ended" && !row.forkStatus && tmuxSessionAlive) {
42120
+ const harnessAlive = await isHarnessProcessAlive(row.tmuxSession);
42121
+ if (conversationNeedsRunningRepair(row, tmuxSessionAlive, harnessAlive)) {
42122
+ markConversationRunning(row.name);
42123
+ row = {
42124
+ ...row,
42125
+ status: "active",
42126
+ endedAt: null
42127
+ };
42128
+ sessionAlive = true;
42129
+ }
42130
+ }
41826
42131
  let isWorking = false;
41827
42132
  let currentTool = null;
41828
- const convSf = await resolveSessionFile(conv);
42133
+ const convSf = await resolveSessionFile(row);
41829
42134
  if (sessionAlive) {
41830
- const rt = getAgentRuntimeStateSync(conv.tmuxSession);
41831
- if (conv.harness === "codex" && convSf && existsSync$1(convSf)) try {
41832
- const summary = await summarizeConversationActivity(convSf, { harness: conv.harness });
42135
+ const rt = getAgentRuntimeStateSync(row.tmuxSession);
42136
+ if (row.harness === "codex" && convSf && existsSync$1(convSf)) try {
42137
+ const summary = await summarizeConversationActivity(convSf, { harness: row.harness });
41833
42138
  isWorking = summary.isWorking;
41834
42139
  currentTool = summary.currentTool;
41835
42140
  } catch {
@@ -41842,7 +42147,7 @@ async function enrichConversationList(limit, offset) {
41842
42147
  isWorking = rt.state === "active";
41843
42148
  currentTool = rt.currentTool ?? null;
41844
42149
  } else if (convSf && existsSync$1(convSf)) try {
41845
- const summary = await summarizeConversationActivity(convSf, { harness: conv.harness });
42150
+ const summary = await summarizeConversationActivity(convSf, { harness: row.harness });
41846
42151
  isWorking = summary.isWorking;
41847
42152
  currentTool = summary.currentTool;
41848
42153
  } catch {}
@@ -41864,25 +42169,28 @@ async function enrichConversationList(limit, offset) {
41864
42169
  pendingInputCount = kinds.length;
41865
42170
  } catch {}
41866
42171
  const compacting = convSf ? isCompacting(convSf) : false;
41867
- const gitInfo = await resolveConversationGitInfo(conv.cwd);
42172
+ const gitInfo = await resolveConversationGitInfo(row.cwd);
41868
42173
  let lastActivityAt = null;
41869
42174
  if (convSf && existsSync$1(convSf)) try {
41870
42175
  lastActivityAt = new Date((await stat$1(convSf)).mtimeMs).toISOString();
41871
42176
  } catch {}
41872
42177
  if (pendingInputCount === 0) {
41873
- const codex = await codexConversationPendingInput(conv, sessionAlive, lastActivityAt ?? (/* @__PURE__ */ new Date()).toISOString());
42178
+ const codex = await codexConversationPendingInput(row, sessionAlive, lastActivityAt ?? (/* @__PURE__ */ new Date()).toISOString());
41874
42179
  if (codex.kinds.length > 0) {
41875
42180
  pendingInputKinds = codex.kinds;
41876
42181
  pendingInputCount = codex.kinds.length;
41877
42182
  if (codex.approval) pendingAskUserQuestion = codex.approval;
41878
42183
  }
41879
42184
  }
42185
+ const ledger = ledgerCosts.get(String(row.id));
41880
42186
  return {
41881
- ...conv,
42187
+ ...row,
42188
+ totalCost: ledger ? ledger.cost : row.totalCost,
42189
+ totalTokens: ledger ? ledger.tokens : row.totalTokens,
41882
42190
  sessionAlive,
41883
42191
  isWorking,
41884
42192
  currentTool,
41885
- isFavorited: favoritedNames.has(conv.name),
42193
+ isFavorited: favoritedNames.has(row.name),
41886
42194
  compacting,
41887
42195
  contextUsage: null,
41888
42196
  lastActivityAt,
@@ -42283,7 +42591,7 @@ const getConversationMessagesRoute = HttpRouter.add("GET", "/api/conversations/:
42283
42591
  if (!conv) {
42284
42592
  const cached = getSpecialistSessionCache(name);
42285
42593
  if (cached) sessionFile = cached;
42286
- else if (/^(specialist-|agent-|planning-)/.test(name)) {
42594
+ else if (/^(specialist-|agent-|planning-|strike-|inspect-)|^(flywheel-orchestrator|conv-flywheel-orchestrator)$/.test(name)) {
42287
42595
  try {
42288
42596
  const agentHarness = await resolveAgentHarness(name);
42289
42597
  if (agentHarness === "codex") {
@@ -42292,7 +42600,7 @@ const getConversationMessagesRoute = HttpRouter.add("GET", "/api/conversations/:
42292
42600
  sessionFile = rollout;
42293
42601
  setSpecialistSessionCache(name, rollout);
42294
42602
  }
42295
- } else if (agentHarness === "ohmypi") {
42603
+ } else if (agentHarness === "ohmypi" || agentHarness === "pi") {
42296
42604
  const piSession = await resolvePiSessionPath(name);
42297
42605
  if (piSession) {
42298
42606
  sessionFile = piSession;
@@ -43737,7 +44045,7 @@ async function registerProjectFromPath(opts) {
43737
44045
  registerProjectSync(key, projectConfig);
43738
44046
  const seededContextLayer = ensureProjectLayer(fullPath);
43739
44047
  try {
43740
- const { preTrustDirectorySync } = await import("./workspace-manager-XDNuCCXG.js");
44048
+ const { preTrustDirectorySync } = await import("./workspace-manager-B7Ji7R9Y.js");
43741
44049
  preTrustDirectorySync(fullPath);
43742
44050
  } catch {}
43743
44051
  let hooksInstalled = 0;
@@ -43778,7 +44086,7 @@ init_jsonl_resolver();
43778
44086
  init_paths();
43779
44087
  const execAsync$2 = promisify(exec);
43780
44088
  async function getIssueDataService() {
43781
- const { getSharedIssueService } = await import("./issue-service-singleton-DfRSzdFO.js");
44089
+ const { getSharedIssueService } = await import("./issue-service-singleton-BUC8RzRL.js");
43782
44090
  return getSharedIssueService();
43783
44091
  }
43784
44092
  /** Returns true if the path exists (any type). */
@@ -45795,8 +46103,8 @@ async function handlePullRequestPromise(payload) {
45795
46103
  if (!issueId) return;
45796
46104
  const repo = payload.repository.full_name;
45797
46105
  if (payload.action === "closed" && pr.merged === true) try {
45798
- const { postMergeLifecycle } = await import("./merge-agent-CdxCcqFv.js");
45799
- const { resolveProjectFromIssueSync } = await import("./projects-DWBDcB6V.js");
46106
+ const { postMergeLifecycle } = await import("./merge-agent-C-lC-qQj.js");
46107
+ const { resolveProjectFromIssueSync } = await import("./projects-Bx1iT8WM.js");
45800
46108
  const project = resolveProjectFromIssueSync(issueId);
45801
46109
  if (project) {
45802
46110
  const branchName = pr.head.ref;
@@ -46257,7 +46565,7 @@ function getCheckpointWorker() {
46257
46565
  return worker;
46258
46566
  }
46259
46567
  async function runInline(operation, payload) {
46260
- const { claimTranscriptRange, commitTranscriptRange, releaseTranscriptRange, getTranscriptCheckpoint, listTranscriptCheckpoints } = await import("./checkpoints-BRNSJDyI.js");
46568
+ const { claimTranscriptRange, commitTranscriptRange, releaseTranscriptRange, getTranscriptCheckpoint, listTranscriptCheckpoints } = await import("./checkpoints-AfvX58uE.js");
46261
46569
  switch (operation) {
46262
46570
  case "claimTranscriptRange": return claimTranscriptRange(payload);
46263
46571
  case "commitTranscriptRange": return commitTranscriptRange(payload);
@@ -47411,7 +47719,7 @@ function buildPendingTurn(input, fromOffset, toOffset, compressed) {
47411
47719
  };
47412
47720
  }
47413
47721
  async function emitMemoryObservationCreated(observation, timestamp) {
47414
- const { initEventStore } = await import("./event-store-D_9DeP8Y.js");
47722
+ const { initEventStore } = await import("./event-store-wcLlc5KG.js");
47415
47723
  await (await initEventStore()).appendAsync({
47416
47724
  type: "memory.observation_created",
47417
47725
  timestamp,
@@ -50339,7 +50647,7 @@ async function getFlywheelConversationPayload() {
50339
50647
  };
50340
50648
  }
50341
50649
  async function postFlywheelReportPayload() {
50342
- const { flywheelReportCommand } = await import("./flywheel-NZJyASRc.js");
50650
+ const { flywheelReportCommand } = await import("./flywheel-DHbsUups.js");
50343
50651
  await flywheelReportCommand({ cwd: process.cwd() });
50344
50652
  return {
50345
50653
  status: 200,
@@ -50528,11 +50836,11 @@ const getMergeBlockersRoute = HttpRouter.add("GET", "/api/flywheel/merge-blocker
50528
50836
  async function defaultGetOrderedIssueIds() {
50529
50837
  const status = await readCurrentFlywheelStatusForDashboard();
50530
50838
  if (!status) return [];
50531
- const { computeMergeQueue } = await import("./flywheel-merge-order-BkA6937p.js");
50839
+ const { computeMergeQueue } = await import("./flywheel-merge-order-3n4imqke.js");
50532
50840
  return (await Effect.runPromise(computeMergeQueue(status.activePipeline, process.cwd()).pipe(Effect.provide(layer)))).map((i) => i.issueId);
50533
50841
  }
50534
50842
  async function defaultMergeOne(issueId) {
50535
- const { triggerMerge } = await import("./workspaces-DL8hfuDT.js");
50843
+ const { triggerMerge } = await import("./workspaces-De3JCv6D.js");
50536
50844
  const r = await triggerMerge(issueId);
50537
50845
  return r.success ? { ok: true } : {
50538
50846
  ok: false,
@@ -50709,7 +51017,7 @@ const getFlywheelMergeQueueRoute = HttpRouter.add("GET", "/api/flywheel/merge-qu
50709
51017
  return yield* Effect.promise(async () => {
50710
51018
  const status = await readCurrentFlywheelStatusForDashboard();
50711
51019
  if (!status) return jsonResponse([]);
50712
- const { computeMergeQueue, resolveMergeQueuePrUrl } = await import("./flywheel-merge-order-BkA6937p.js");
51020
+ const { computeMergeQueue, resolveMergeQueuePrUrl } = await import("./flywheel-merge-order-3n4imqke.js");
50713
51021
  return jsonResponse(await Effect.runPromise(computeMergeQueue(status.activePipeline, process.cwd(), { getPrUrl: resolveMergeQueuePrUrl }).pipe(Effect.provide(layer))));
50714
51022
  });
50715
51023
  })));
@@ -50723,14 +51031,14 @@ function uatGenerationNameFromParam(param) {
50723
51031
  return decoded.startsWith("uat/") ? decoded : `uat/${decoded}`;
50724
51032
  }
50725
51033
  const getUatGenerationsRoute = HttpRouter.add("GET", "/api/flywheel/uat-generations", httpHandler(Effect.gen(function* () {
50726
- const { getUatGenerationsPayload } = yield* Effect.promise(() => import("./uat-train-C6_NdOfR.js"));
51034
+ const { getUatGenerationsPayload } = yield* Effect.promise(() => import("./uat-train-DdRssBsB.js"));
50727
51035
  return jsonResponse(yield* Effect.promise(() => getUatGenerationsPayload()));
50728
51036
  })));
50729
51037
  const postUatGenerationStackRoute = HttpRouter.add("POST", "/api/flywheel/uat-generations/:name/stack", httpHandler(Effect.gen(function* () {
50730
51038
  const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
50731
51039
  if (authError) return authError;
50732
51040
  const name = uatGenerationNameFromParam((yield* HttpRouter.params)["name"] ?? "");
50733
- const { postUatGenerationStackPayload } = yield* Effect.promise(() => import("./uat-train-C6_NdOfR.js"));
51041
+ const { postUatGenerationStackPayload } = yield* Effect.promise(() => import("./uat-train-DdRssBsB.js"));
50734
51042
  const result = yield* Effect.promise(() => postUatGenerationStackPayload(name));
50735
51043
  if (!result.ok) return jsonResponse({ error: result.error }, { status: result.status });
50736
51044
  return jsonResponse({
@@ -50742,8 +51050,8 @@ const postUatGenerationPromoteRoute = HttpRouter.add("POST", "/api/flywheel/uat-
50742
51050
  const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
50743
51051
  if (authError) return authError;
50744
51052
  const name = uatGenerationNameFromParam((yield* HttpRouter.params)["name"] ?? "");
50745
- const { postUatGenerationPromotePayload } = yield* Effect.promise(() => import("./uat-train-C6_NdOfR.js"));
50746
- const { firePostMergeLifecycle } = yield* Effect.promise(() => import("./specialists-Bbj7bCwh.js"));
51053
+ const { postUatGenerationPromotePayload } = yield* Effect.promise(() => import("./uat-train-DdRssBsB.js"));
51054
+ const { firePostMergeLifecycle } = yield* Effect.promise(() => import("./specialists-BMqL-Xh_.js"));
50747
51055
  const result = yield* Effect.promise(() => postUatGenerationPromotePayload(name, firePostMergeLifecycle));
50748
51056
  if (!result.success) return jsonResponse(result, { status: result.reason === "not-found" ? 404 : result.reason === "merge-failed" ? 500 : 409 });
50749
51057
  return jsonResponse(result);
@@ -50756,7 +51064,7 @@ const postUatGenerationPromoteRoute = HttpRouter.add("POST", "/api/flywheel/uat-
50756
51064
  const postFlywheelAssembleUatRoute = HttpRouter.add("POST", "/api/flywheel/assemble-uat", httpHandler(Effect.gen(function* () {
50757
51065
  const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
50758
51066
  if (authError) return authError;
50759
- const { runUatTrainReconcile } = yield* Effect.promise(() => import("./uat-train-C6_NdOfR.js"));
51067
+ const { runUatTrainReconcile } = yield* Effect.promise(() => import("./uat-train-DdRssBsB.js"));
50760
51068
  return jsonResponse(yield* Effect.promise(() => runUatTrainReconcile({ force: true })));
50761
51069
  })));
50762
51070
  const getFlywheelStateRoute = HttpRouter.add("GET", "/api/flywheel/state", httpHandler(Effect.gen(function* () {
@@ -53927,7 +54235,7 @@ async function pollOnce(state) {
53927
54235
  try {
53928
54236
  const remoteState = await readFile(join$1(homedir$1(), ".overdeck", "agents", agentId, "remote-state.json"), "utf-8").then((text) => JSON.parse(text)).catch(() => null);
53929
54237
  if (remoteState?.location === "remote" && remoteState?.vmName) {
53930
- const { getRemoteAgentOutput } = await import("./remote-agents-DQ2gRI6m.js");
54238
+ const { getRemoteAgentOutput } = await import("./remote-agents-CYhsjnkE.js");
53931
54239
  stdout = await getRemoteAgentOutput(agentId, remoteState.vmName, 50);
53932
54240
  } else stdout = await Effect.runPromise(capturePane(agentId, 50));
53933
54241
  } catch {
@@ -54880,7 +55188,7 @@ const RESTART_MARKER = join(homedir(), ".overdeck", "dashboard-restarting.json")
54880
55188
  * loads new content-hashed chunk filenames (no ERR_MODULE_NOT_FOUND after rebuild).
54881
55189
  */
54882
55190
  async function defaultLifecycleRunner(pending) {
54883
- const { postMergeLifecycle, notifyTldrDaemon } = await import("./merge-agent-CdxCcqFv.js");
55191
+ const { postMergeLifecycle, notifyTldrDaemon } = await import("./merge-agent-C-lC-qQj.js");
54884
55192
  await postMergeLifecycle(pending.issueId, pending.projectPath, pending.sourceBranch, { skipDeploy: true });
54885
55193
  if (pending.sourceBranch) await notifyTldrDaemon(pending.projectPath, pending.sourceBranch);
54886
55194
  }
@@ -55201,7 +55509,7 @@ function failureReason(result) {
55201
55509
  return result.error ?? result.message ?? `merge returned status ${result.statusCode ?? "unknown"}`;
55202
55510
  }
55203
55511
  async function defaultMergeIssue(issueId) {
55204
- const { triggerMerge } = await import("./workspaces-DL8hfuDT.js");
55512
+ const { triggerMerge } = await import("./workspaces-De3JCv6D.js");
55205
55513
  return triggerMerge(issueId);
55206
55514
  }
55207
55515
  function defaultAnnounceFailure(issueId, reason) {
@@ -55812,7 +56120,7 @@ reconcileStaleGitHubBlockers().then((n) => {
55812
56120
  }
55813
56121
  }).catch((err) => console.warn(`[overdeck] Startup blocker reconciliation failed: ${err.message}`));
55814
56122
  try {
55815
- const { resetProcessingToQueued } = await import("./merge-sync-CmpwVmNH.js");
56123
+ const { resetProcessingToQueued } = await import("./merge-sync-Qvqrosks.js");
55816
56124
  const resetCount = resetProcessingToQueued();
55817
56125
  if (resetCount > 0) {
55818
56126
  console.log(`[overdeck] Reset ${resetCount} stuck merge queue entries to queued`);