@overdeck/desktop 0.41.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 (18) hide show
  1. package/package.json +1 -1
  2. package/server/public/assets/{chunk-BO2N2NFS-66nJvb0Y.js → chunk-BO2N2NFS-qb3jozf8.js} +4 -4
  3. package/server/public/assets/{diagram-OG6HWLK6-CnpgVLBi.js → diagram-OG6HWLK6-DCxQdIR-.js} +1 -1
  4. package/server/public/assets/{dist-CHQsz1no.js → dist--I-KHxVY.js} +1 -1
  5. package/server/public/assets/{dist-BFQhMul-.js → dist-99bVzL85.js} +3 -3
  6. package/server/public/assets/{ganttDiagram-6RSMTGT7-CFA1TEUl.js → ganttDiagram-6RSMTGT7-CZQ5wmbx.js} +1 -1
  7. package/server/public/assets/{highlighted-body-OFNGDK62-DbRNyBRD.js → highlighted-body-OFNGDK62-gddTgxaL.js} +1 -1
  8. package/server/public/assets/{index-Cc9hNbWG.js → index-w0Cnkax8.js} +7 -7
  9. package/server/public/assets/{linear-CveL56V8.js → linear-BchPtO53.js} +1 -1
  10. package/server/public/assets/mermaid-GHXKKRXX-CxNSCT26.js +1 -0
  11. package/server/public/assets/{pieDiagram-4H26LBE5-BWMp3bl2.js → pieDiagram-4H26LBE5-COGFoOPX.js} +1 -1
  12. package/server/public/assets/{prod-BtqEDkif.js → prod-CnNbvojd.js} +4 -4
  13. package/server/public/assets/{quadrantDiagram-W4KKPZXB-BXfFUtKT.js → quadrantDiagram-W4KKPZXB-6DBILYRJ.js} +1 -1
  14. package/server/public/assets/{sankeyDiagram-5OEKKPKP-D2A4SsFI.js → sankeyDiagram-5OEKKPKP-DTpZ_e2a.js} +1 -1
  15. package/server/public/assets/{xychartDiagram-2RQKCTM6-BQuEJ-Sx.js → xychartDiagram-2RQKCTM6-guNhhdvI.js} +1 -1
  16. package/server/public/index.html +1 -1
  17. package/server/server.js +203 -82
  18. package/server/public/assets/mermaid-GHXKKRXX-BM8E6NEr.js +0 -1
package/server/server.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { a as __toCommonJS, i as __require, o as __toESM, t as __commonJSMin } from "./rolldown-runtime-DNCzzKnI.js";
2
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-cMZF-UTW.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
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";
@@ -10,80 +10,80 @@ import { E as registerProjectSync, N as setProjectAutoMergeDefaultSync, O as res
10
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
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-rO7znkga.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-BIdrF-U5.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
15
  import { n as AgentsResolverLive, o as init_agents$1 } from "./agents-BX0F_1V2.js";
16
16
  import { i as init_paths$2, l as resolveObservationsFile, r as ensureParentDir, s as resolveIssueMemoryRoot, t as assertMemorySafeSegment } from "./paths-3zDoFwPl.js";
17
17
  import { i as recordBriefingSessionStart, n as ensureSessionContextBriefingFile, r as init_briefing_freshness, t as appendFreshBriefingUpdate } from "./briefing-freshness-BVjg7adf.js";
18
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-bwJnbB6r.js";
21
- import { i as init_agent_state_service, n as AgentStateServiceLive } from "./agent-state-service-BUhXCI_4.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
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
24
  import { i as init_linear_client, r as LinearClientOptionalLive, t as LinearClient } from "./linear-client-BRwBC1ub.js";
25
25
  import { i as init_github_client, r as GitHubClientOptionalLive } from "./github-client-CLhcTuCU.js";
26
26
  import { i as init_rally_client, r as RallyClientOptionalLive } from "./rally-client-C51tvXfE.js";
27
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-Cq0mMaNH.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
29
  import { i as ensureInternalTokenSync, s as init_internal_token } from "./internal-token-C8Bg8u5G.js";
30
30
  import { a as setPipelineHandlerSync, t as init_pipeline_notifier } from "./pipeline-notifier-BOcC7C98.js";
31
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, l as getModelRollupSync, n as getBackgroundCostBySourceSync, r as getCavemanExperimentDataSync, s as getCostsByIssueSync, u as init_cost_sync } from "./cost-sync-DJZXPGqK.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
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
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
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
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 updateForkStatus, A as listArchivedConversationsWithEnrichment, C as getStuckForks, D as init_conversations, E as incrementForkRetryCount, F as markConversationRunning, G as setFavorite, H as setConversationClaudeSessionId, J as unarchiveConversation, K as setForkRequest, M as listFavoritedIds, N as markConversationActive, O as isAgentConversationName, P as markConversationEnded, Q as updateConversationTitle, R as recordConversationHandoff, S as getConversationByTmuxSession, T as importLegacyConversation, U as setConversationHarness, V as setClearedToConvId, W as setConversationModel, X as updateConversationDeliveryMethod, Y as updateConversationCost, Z as updateConversationForkFallbackReason, _ as canReplaceTitle, b as getConversationById, et as updateLastAttached, g as backfillConversationModel, h as archiveConversation, j as listConversations, k as listActiveConversations, q as setImportedConversationLinks, tt as updateSpawnError, v as createConversation, w as hasOtherActiveConversationOnTmuxSession, x as getConversationByName, y as getConversationByClaudeSessionId, z as removeFavorite } from "./conversations-Db3UIeTM.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-IG9dJkAf.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
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-SteL0Yy7.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
46
  import { t as init_pan_dir } from "./pan-dir-CnOUvQm_.js";
47
47
  import { n as init_launcher_generator, t as generateLauncherScriptSync } from "./launcher-generator-Bzj8tdlM.js";
48
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-C1dMLCfn.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
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-BjJWJ-lN.js";
51
+ import { i as updateMemoryHealth, n as extractWithProviderPolicy, r as init_health$1, t as init_providers$1 } from "./providers-BUnK7ZrI.js";
52
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-DVDpIEUb.js";
54
- import { n as deduplicateEventsSync, o as readEventsSync, s as tailEventsSync } from "./events-BXe36mwW.js";
55
- import { n as recordBackgroundAiCost, t as init_cost$1 } from "./cost-RWt0c0ft.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-n8HCRtcj.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-Dn6Akk0c.js";
58
- import { f as workspacesRouteLayer, g as getWorkspacePathForIssue, h as processPendingFeedbackDeliveries, m as resumeQueuedMerges, p as enrichReviewStatus } from "./workspaces-B8dRF3nB.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
59
  import { _ as init_platform, g as detectPlatform } from "./workspace-manager-C-2qis5x.js";
60
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-DGG1xJ9W.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
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-CRQv_8TC.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-B1xw9Xx2.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
66
  import { c as init_prd_locations, s as findPrdAtStatusSync } from "./archive-planning-CgavlD03.js";
67
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-0WGOYOmb.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-C_hlPfAU.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
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-Chd_Rt2n.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
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-BliEel5D.js";
75
- import { r as specialistsRouteLayer } from "./specialists-CDM5vkDy.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
76
  import { t as getAgentCommandSync } from "./settings-BYAK9dF4.js";
77
- import { n as init_review_agent, r as isExtendedReviewEnabled } from "./review-agent-DlkjIM6c.js";
77
+ import { n as init_review_agent, r as isExtendedReviewEnabled } from "./review-agent-D7LWj3E4.js";
78
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-Bv8oh7WW.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-gcj_CR2I.js";
82
- import { a as init_conversation_compaction, c as shouldInterceptManualCompact, n as compactConversationNative, o as isCompacting } from "./conversation-compaction-dqaXGhcH.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
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-DZgob0vQ.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
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";
@@ -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-BeWOeR_m.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-HmyOU9y0.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-BeWOeR_m.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-BeWOeR_m.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,7 +710,7 @@ 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-BGSPZ2WT.js");
713
+ const { deepWipe } = await import("./workflows-BNDOBAfu.js");
714
714
  const { resolveProjectFromIssueSync } = await import("./projects-Bx1iT8WM.js");
715
715
  const project = resolveProjectFromIssueSync(issueId);
716
716
  const projectPath = project?.projectPath ?? process.cwd();
@@ -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;
@@ -36904,6 +36900,70 @@ function previewLegacyConversations(path) {
36904
36900
  db.close();
36905
36901
  }
36906
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
+ }
36907
36967
  function parseIsoToMs(iso) {
36908
36968
  if (!iso) return null;
36909
36969
  const ms = new Date(iso).getTime();
@@ -36922,13 +36982,11 @@ function importLegacyConversations(path, names) {
36922
36982
  let legacyRows;
36923
36983
  let favSet;
36924
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));
36925
36987
  const placeholders = names.map(() => "?").join(", ");
36926
- legacyRows = db.prepare(`SELECT id, name, tmux_session, status, cwd, created_at, ended_at, last_attached_at,
36927
- session_file, claude_session_id, title, title_source, title_seed,
36928
- total_cost, total_tokens, archived_at, model, effort, fork_status, fork_error,
36929
- harness, delivery_method, spawn_error, handoff_doc_path, handoff_target_conv_id,
36930
- fork_fallback_reason, cleared_to_conv_id, fork_request, fork_retry_count
36931
- FROM conversations WHERE name IN (${placeholders})`).all(...names);
36988
+ legacyRows = db.prepare(`SELECT ${selectCols.join(", ")}
36989
+ FROM conversations WHERE name IN (${placeholders})`).all(...names).map(normalizeLegacyRow);
36932
36990
  favSet = new Set(db.prepare(`SELECT item_id FROM favorites WHERE type = 'conversation'`).all().map((r) => r.item_id));
36933
36991
  } finally {
36934
36992
  db.close();
@@ -37948,6 +38006,7 @@ init_http_helpers();
37948
38006
  init_domain_services();
37949
38007
  init_service();
37950
38008
  init_agents$2();
38009
+ init_cost_sync();
37951
38010
  init_git_activity();
37952
38011
  init_http_handler();
37953
38012
  let _cachedReviewStatuses = null;
@@ -37976,13 +38035,14 @@ const getMetricsSummaryRoute = HttpRouter.add("GET", "/api/metrics/summary", htt
37976
38035
  const service = getCloisterService();
37977
38036
  const status = service.getStatus();
37978
38037
  const costSummary = service.getCostSummary();
38038
+ const todayCost = getTodayCostSync();
37979
38039
  const topAgents = costSummary.topAgents.slice(0, 5);
37980
38040
  const topIssues = costSummary.topIssues.slice(0, 5);
37981
38041
  const runningAgents = yield* listRunningAgents();
37982
38042
  const stuckCount = computeStuckCount(status.agentsNeedingAttention, (id) => service.getAgentHealth(id), buildAgentIssueMap(runningAgents), getReviewStatusesCached());
37983
38043
  return jsonResponse({
37984
38044
  today: {
37985
- totalCost: Math.round(costSummary.dailyTotal * 100) / 100,
38045
+ totalCost: Math.round(todayCost * 100) / 100,
37986
38046
  agentCount: status.summary.total,
37987
38047
  activeCount: status.summary.active,
37988
38048
  stuckCount,
@@ -38824,7 +38884,7 @@ const getPlanningStatusRoute = HttpRouter.add("GET", "/api/planning/:issueId/sta
38824
38884
  const remoteState = loadRemoteAgentState(sessionName);
38825
38885
  const isRemote = !!remoteState;
38826
38886
  const vmName = remoteState?.vmName ?? "";
38827
- const { getAgentStateSync } = await import("./agents-BeWOeR_m.js");
38887
+ const { getAgentStateSync } = await import("./agents-C5t_gXWd.js");
38828
38888
  const agentStarting = getAgentStateSync(sessionName)?.status === "starting";
38829
38889
  let tmuxSessionAlive = false;
38830
38890
  if (!isRemote) try {
@@ -40603,7 +40663,7 @@ async function cleanupConversationAttachments(name) {
40603
40663
  * sessions that the lifecycle poller missed. */
40604
40664
  async function cleanupOrphanedConversationAttachments() {
40605
40665
  try {
40606
- const { listConversations } = await import("./conversations-DumOm1wb.js");
40666
+ const { listConversations } = await import("./conversations-CEIxKTYY.js");
40607
40667
  const convNames = new Set(listConversations().map((c) => c.name));
40608
40668
  const root = getConversationAttachmentsRoot();
40609
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, {
@@ -41129,18 +41189,21 @@ async function waitForClaudeReady(tmuxSession) {
41129
41189
  }
41130
41190
  console.warn(`[conversations] Timed out waiting for Claude Code prompt in ${tmuxSession}`);
41131
41191
  }
41192
+ function isPiTuiInputReady(snapshot) {
41193
+ return /^\s*[❯›>]\s/m.test(snapshot) || /(?:^|\s)0(?:\.\d+)?%\s+context\s+used\b/i.test(snapshot);
41194
+ }
41132
41195
  /**
41133
- * Wait until Pi's TUI has rendered into the tmux pane.
41196
+ * Wait until Pi's TUI is accepting input in the tmux pane.
41134
41197
  *
41135
41198
  * Pi TUI mode does not write a ready.json marker (that was an RPC-mode
41136
- * artifact). We instead poll capture-pane for non-empty content, which
41137
- * indicates Pi has drawn at least its title/prompt line. This is the same
41138
- * 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.
41139
41202
  */
41140
41203
  async function waitForPiTuiReady(tmuxSession, timeoutMs = 3e4) {
41141
41204
  const deadline = Date.now() + timeoutMs;
41142
41205
  while (Date.now() < deadline) {
41143
- 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("")))))) {
41144
41207
  console.log(`[conversations] Pi TUI ready for ${tmuxSession}`);
41145
41208
  return true;
41146
41209
  }
@@ -41149,6 +41212,39 @@ async function waitForPiTuiReady(tmuxSession, timeoutMs = 3e4) {
41149
41212
  console.warn(`[conversations] Timed out waiting for Pi TUI to render in ${tmuxSession}`);
41150
41213
  return false;
41151
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
+ }
41152
41248
  async function resolveSessionFile(conv) {
41153
41249
  if (conv.harness === "ohmypi" || conv.harness === "pi") {
41154
41250
  const piPath = await resolvePiSessionPath(conv.tmuxSession);
@@ -41159,7 +41255,11 @@ async function resolveSessionFile(conv) {
41159
41255
  if (codexPath) return codexPath;
41160
41256
  }
41161
41257
  const sessionId = await readLauncherPinnedSessionId(conv.tmuxSession) ?? conv.claudeSessionId;
41162
- 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
+ }
41163
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.`);
41164
41264
  return null;
41165
41265
  }
@@ -41983,6 +42083,9 @@ const listEnrichmentInFlight = /* @__PURE__ */ new Map();
41983
42083
  function conversationSessionAliveFromState(conv, tmuxSessionAlive) {
41984
42084
  return conv.status === "active" && !conv.forkStatus && tmuxSessionAlive;
41985
42085
  }
42086
+ function conversationNeedsRunningRepair(conv, tmuxSessionAlive, harnessProcessAlive) {
42087
+ return conv.status === "ended" && !conv.forkStatus && tmuxSessionAlive && harnessProcessAlive;
42088
+ }
41986
42089
  function getEnrichedConversationList(limit, offset) {
41987
42090
  const key = `${limit}:${offset}`;
41988
42091
  const now = Date.now();
@@ -42007,16 +42110,31 @@ async function enrichConversationList(limit, offset) {
42007
42110
  offset
42008
42111
  });
42009
42112
  const favoritedNames = getCachedFavoritedIds();
42113
+ const ledgerCosts = getConversationLedgerCosts();
42010
42114
  const liveSessionNames = new Set(await Effect.runPromise(listSessionNames()));
42011
42115
  return Effect.runPromise(withConcurrencyLimit(conversations.map((conv) => Effect.promise(async () => {
42012
- 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
+ }
42013
42131
  let isWorking = false;
42014
42132
  let currentTool = null;
42015
- const convSf = await resolveSessionFile(conv);
42133
+ const convSf = await resolveSessionFile(row);
42016
42134
  if (sessionAlive) {
42017
- const rt = getAgentRuntimeStateSync(conv.tmuxSession);
42018
- if (conv.harness === "codex" && convSf && existsSync$1(convSf)) try {
42019
- 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 });
42020
42138
  isWorking = summary.isWorking;
42021
42139
  currentTool = summary.currentTool;
42022
42140
  } catch {
@@ -42029,7 +42147,7 @@ async function enrichConversationList(limit, offset) {
42029
42147
  isWorking = rt.state === "active";
42030
42148
  currentTool = rt.currentTool ?? null;
42031
42149
  } else if (convSf && existsSync$1(convSf)) try {
42032
- const summary = await summarizeConversationActivity(convSf, { harness: conv.harness });
42150
+ const summary = await summarizeConversationActivity(convSf, { harness: row.harness });
42033
42151
  isWorking = summary.isWorking;
42034
42152
  currentTool = summary.currentTool;
42035
42153
  } catch {}
@@ -42051,25 +42169,28 @@ async function enrichConversationList(limit, offset) {
42051
42169
  pendingInputCount = kinds.length;
42052
42170
  } catch {}
42053
42171
  const compacting = convSf ? isCompacting(convSf) : false;
42054
- const gitInfo = await resolveConversationGitInfo(conv.cwd);
42172
+ const gitInfo = await resolveConversationGitInfo(row.cwd);
42055
42173
  let lastActivityAt = null;
42056
42174
  if (convSf && existsSync$1(convSf)) try {
42057
42175
  lastActivityAt = new Date((await stat$1(convSf)).mtimeMs).toISOString();
42058
42176
  } catch {}
42059
42177
  if (pendingInputCount === 0) {
42060
- const codex = await codexConversationPendingInput(conv, sessionAlive, lastActivityAt ?? (/* @__PURE__ */ new Date()).toISOString());
42178
+ const codex = await codexConversationPendingInput(row, sessionAlive, lastActivityAt ?? (/* @__PURE__ */ new Date()).toISOString());
42061
42179
  if (codex.kinds.length > 0) {
42062
42180
  pendingInputKinds = codex.kinds;
42063
42181
  pendingInputCount = codex.kinds.length;
42064
42182
  if (codex.approval) pendingAskUserQuestion = codex.approval;
42065
42183
  }
42066
42184
  }
42185
+ const ledger = ledgerCosts.get(String(row.id));
42067
42186
  return {
42068
- ...conv,
42187
+ ...row,
42188
+ totalCost: ledger ? ledger.cost : row.totalCost,
42189
+ totalTokens: ledger ? ledger.tokens : row.totalTokens,
42069
42190
  sessionAlive,
42070
42191
  isWorking,
42071
42192
  currentTool,
42072
- isFavorited: favoritedNames.has(conv.name),
42193
+ isFavorited: favoritedNames.has(row.name),
42073
42194
  compacting,
42074
42195
  contextUsage: null,
42075
42196
  lastActivityAt,
@@ -42470,7 +42591,7 @@ const getConversationMessagesRoute = HttpRouter.add("GET", "/api/conversations/:
42470
42591
  if (!conv) {
42471
42592
  const cached = getSpecialistSessionCache(name);
42472
42593
  if (cached) sessionFile = cached;
42473
- else if (/^(specialist-|agent-|planning-)/.test(name)) {
42594
+ else if (/^(specialist-|agent-|planning-|strike-|inspect-)|^(flywheel-orchestrator|conv-flywheel-orchestrator)$/.test(name)) {
42474
42595
  try {
42475
42596
  const agentHarness = await resolveAgentHarness(name);
42476
42597
  if (agentHarness === "codex") {
@@ -42479,7 +42600,7 @@ const getConversationMessagesRoute = HttpRouter.add("GET", "/api/conversations/:
42479
42600
  sessionFile = rollout;
42480
42601
  setSpecialistSessionCache(name, rollout);
42481
42602
  }
42482
- } else if (agentHarness === "ohmypi") {
42603
+ } else if (agentHarness === "ohmypi" || agentHarness === "pi") {
42483
42604
  const piSession = await resolvePiSessionPath(name);
42484
42605
  if (piSession) {
42485
42606
  sessionFile = piSession;
@@ -43965,7 +44086,7 @@ init_jsonl_resolver();
43965
44086
  init_paths();
43966
44087
  const execAsync$2 = promisify(exec);
43967
44088
  async function getIssueDataService() {
43968
- const { getSharedIssueService } = await import("./issue-service-singleton-BoOA6Zoi.js");
44089
+ const { getSharedIssueService } = await import("./issue-service-singleton-BUC8RzRL.js");
43969
44090
  return getSharedIssueService();
43970
44091
  }
43971
44092
  /** Returns true if the path exists (any type). */
@@ -45982,7 +46103,7 @@ async function handlePullRequestPromise(payload) {
45982
46103
  if (!issueId) return;
45983
46104
  const repo = payload.repository.full_name;
45984
46105
  if (payload.action === "closed" && pr.merged === true) try {
45985
- const { postMergeLifecycle } = await import("./merge-agent-PlMChx1A.js");
46106
+ const { postMergeLifecycle } = await import("./merge-agent-C-lC-qQj.js");
45986
46107
  const { resolveProjectFromIssueSync } = await import("./projects-Bx1iT8WM.js");
45987
46108
  const project = resolveProjectFromIssueSync(issueId);
45988
46109
  if (project) {
@@ -50526,7 +50647,7 @@ async function getFlywheelConversationPayload() {
50526
50647
  };
50527
50648
  }
50528
50649
  async function postFlywheelReportPayload() {
50529
- const { flywheelReportCommand } = await import("./flywheel-Bz8p0duH.js");
50650
+ const { flywheelReportCommand } = await import("./flywheel-DHbsUups.js");
50530
50651
  await flywheelReportCommand({ cwd: process.cwd() });
50531
50652
  return {
50532
50653
  status: 200,
@@ -50715,11 +50836,11 @@ const getMergeBlockersRoute = HttpRouter.add("GET", "/api/flywheel/merge-blocker
50715
50836
  async function defaultGetOrderedIssueIds() {
50716
50837
  const status = await readCurrentFlywheelStatusForDashboard();
50717
50838
  if (!status) return [];
50718
- const { computeMergeQueue } = await import("./flywheel-merge-order-B027U7Y2.js");
50839
+ const { computeMergeQueue } = await import("./flywheel-merge-order-3n4imqke.js");
50719
50840
  return (await Effect.runPromise(computeMergeQueue(status.activePipeline, process.cwd()).pipe(Effect.provide(layer)))).map((i) => i.issueId);
50720
50841
  }
50721
50842
  async function defaultMergeOne(issueId) {
50722
- const { triggerMerge } = await import("./workspaces-BB169tZ1.js");
50843
+ const { triggerMerge } = await import("./workspaces-De3JCv6D.js");
50723
50844
  const r = await triggerMerge(issueId);
50724
50845
  return r.success ? { ok: true } : {
50725
50846
  ok: false,
@@ -50896,7 +51017,7 @@ const getFlywheelMergeQueueRoute = HttpRouter.add("GET", "/api/flywheel/merge-qu
50896
51017
  return yield* Effect.promise(async () => {
50897
51018
  const status = await readCurrentFlywheelStatusForDashboard();
50898
51019
  if (!status) return jsonResponse([]);
50899
- const { computeMergeQueue, resolveMergeQueuePrUrl } = await import("./flywheel-merge-order-B027U7Y2.js");
51020
+ const { computeMergeQueue, resolveMergeQueuePrUrl } = await import("./flywheel-merge-order-3n4imqke.js");
50900
51021
  return jsonResponse(await Effect.runPromise(computeMergeQueue(status.activePipeline, process.cwd(), { getPrUrl: resolveMergeQueuePrUrl }).pipe(Effect.provide(layer))));
50901
51022
  });
50902
51023
  })));
@@ -50910,14 +51031,14 @@ function uatGenerationNameFromParam(param) {
50910
51031
  return decoded.startsWith("uat/") ? decoded : `uat/${decoded}`;
50911
51032
  }
50912
51033
  const getUatGenerationsRoute = HttpRouter.add("GET", "/api/flywheel/uat-generations", httpHandler(Effect.gen(function* () {
50913
- const { getUatGenerationsPayload } = yield* Effect.promise(() => import("./uat-train-D0UsTS5S.js"));
51034
+ const { getUatGenerationsPayload } = yield* Effect.promise(() => import("./uat-train-DdRssBsB.js"));
50914
51035
  return jsonResponse(yield* Effect.promise(() => getUatGenerationsPayload()));
50915
51036
  })));
50916
51037
  const postUatGenerationStackRoute = HttpRouter.add("POST", "/api/flywheel/uat-generations/:name/stack", httpHandler(Effect.gen(function* () {
50917
51038
  const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
50918
51039
  if (authError) return authError;
50919
51040
  const name = uatGenerationNameFromParam((yield* HttpRouter.params)["name"] ?? "");
50920
- const { postUatGenerationStackPayload } = yield* Effect.promise(() => import("./uat-train-D0UsTS5S.js"));
51041
+ const { postUatGenerationStackPayload } = yield* Effect.promise(() => import("./uat-train-DdRssBsB.js"));
50921
51042
  const result = yield* Effect.promise(() => postUatGenerationStackPayload(name));
50922
51043
  if (!result.ok) return jsonResponse({ error: result.error }, { status: result.status });
50923
51044
  return jsonResponse({
@@ -50929,8 +51050,8 @@ const postUatGenerationPromoteRoute = HttpRouter.add("POST", "/api/flywheel/uat-
50929
51050
  const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
50930
51051
  if (authError) return authError;
50931
51052
  const name = uatGenerationNameFromParam((yield* HttpRouter.params)["name"] ?? "");
50932
- const { postUatGenerationPromotePayload } = yield* Effect.promise(() => import("./uat-train-D0UsTS5S.js"));
50933
- const { firePostMergeLifecycle } = yield* Effect.promise(() => import("./specialists-ZtyvSxW9.js"));
51053
+ const { postUatGenerationPromotePayload } = yield* Effect.promise(() => import("./uat-train-DdRssBsB.js"));
51054
+ const { firePostMergeLifecycle } = yield* Effect.promise(() => import("./specialists-BMqL-Xh_.js"));
50934
51055
  const result = yield* Effect.promise(() => postUatGenerationPromotePayload(name, firePostMergeLifecycle));
50935
51056
  if (!result.success) return jsonResponse(result, { status: result.reason === "not-found" ? 404 : result.reason === "merge-failed" ? 500 : 409 });
50936
51057
  return jsonResponse(result);
@@ -50943,7 +51064,7 @@ const postUatGenerationPromoteRoute = HttpRouter.add("POST", "/api/flywheel/uat-
50943
51064
  const postFlywheelAssembleUatRoute = HttpRouter.add("POST", "/api/flywheel/assemble-uat", httpHandler(Effect.gen(function* () {
50944
51065
  const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
50945
51066
  if (authError) return authError;
50946
- const { runUatTrainReconcile } = yield* Effect.promise(() => import("./uat-train-D0UsTS5S.js"));
51067
+ const { runUatTrainReconcile } = yield* Effect.promise(() => import("./uat-train-DdRssBsB.js"));
50947
51068
  return jsonResponse(yield* Effect.promise(() => runUatTrainReconcile({ force: true })));
50948
51069
  })));
50949
51070
  const getFlywheelStateRoute = HttpRouter.add("GET", "/api/flywheel/state", httpHandler(Effect.gen(function* () {
@@ -55067,7 +55188,7 @@ const RESTART_MARKER = join(homedir(), ".overdeck", "dashboard-restarting.json")
55067
55188
  * loads new content-hashed chunk filenames (no ERR_MODULE_NOT_FOUND after rebuild).
55068
55189
  */
55069
55190
  async function defaultLifecycleRunner(pending) {
55070
- const { postMergeLifecycle, notifyTldrDaemon } = await import("./merge-agent-PlMChx1A.js");
55191
+ const { postMergeLifecycle, notifyTldrDaemon } = await import("./merge-agent-C-lC-qQj.js");
55071
55192
  await postMergeLifecycle(pending.issueId, pending.projectPath, pending.sourceBranch, { skipDeploy: true });
55072
55193
  if (pending.sourceBranch) await notifyTldrDaemon(pending.projectPath, pending.sourceBranch);
55073
55194
  }
@@ -55388,7 +55509,7 @@ function failureReason(result) {
55388
55509
  return result.error ?? result.message ?? `merge returned status ${result.statusCode ?? "unknown"}`;
55389
55510
  }
55390
55511
  async function defaultMergeIssue(issueId) {
55391
- const { triggerMerge } = await import("./workspaces-BB169tZ1.js");
55512
+ const { triggerMerge } = await import("./workspaces-De3JCv6D.js");
55392
55513
  return triggerMerge(issueId);
55393
55514
  }
55394
55515
  function defaultAnnounceFailure(issueId, reason) {