@overdeck/desktop 0.44.0 → 0.45.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.
- package/dist-electron/main.js +14 -5
- package/dist-electron/main.js.map +1 -1
- package/package.json +1 -1
- package/server/public/assets/{chunk-BO2N2NFS-DurskaRQ.js → chunk-BO2N2NFS-CaAvtgHW.js} +4 -4
- package/server/public/assets/{diagram-OG6HWLK6-Dk7-KYG7.js → diagram-OG6HWLK6-C4flU2X9.js} +1 -1
- package/server/public/assets/{dist-Dm4--nOM.js → dist-DXAnG2e9.js} +1 -1
- package/server/public/assets/{dist-CaEw8nYm.js → dist-DygIHsen.js} +3 -3
- package/server/public/assets/{ganttDiagram-6RSMTGT7-CFh4T1Yl.js → ganttDiagram-6RSMTGT7-BJY25etK.js} +1 -1
- package/server/public/assets/{highlighted-body-OFNGDK62--ggf-1jf.js → highlighted-body-OFNGDK62-DIEQLSG_.js} +1 -1
- package/server/public/assets/index-BsKNi2y5.js +796 -0
- package/server/public/assets/{linear-B_aOIp4o.js → linear-CRa2o9KP.js} +1 -1
- package/server/public/assets/mermaid-GHXKKRXX-uIkd-n0c.js +1 -0
- package/server/public/assets/{pieDiagram-4H26LBE5-_QEBgJ8d.js → pieDiagram-4H26LBE5-Cb6OrK_c.js} +1 -1
- package/server/public/assets/{prod-oCB7Fr_u.js → prod-DWpuiL-y.js} +4 -4
- package/server/public/assets/{quadrantDiagram-W4KKPZXB-CAbpwVBa.js → quadrantDiagram-W4KKPZXB-DhZzzcAO.js} +1 -1
- package/server/public/assets/{sankeyDiagram-5OEKKPKP-mPlHirkS.js → sankeyDiagram-5OEKKPKP-CVe6lE5A.js} +1 -1
- package/server/public/assets/{xychartDiagram-2RQKCTM6-m6Efea7b.js → xychartDiagram-2RQKCTM6-zukUz5pI.js} +1 -1
- package/server/public/index.html +1 -1
- package/server/server.js +546 -482
- package/server/public/assets/index-CuIG3f59.js +0 -796
- package/server/public/assets/mermaid-GHXKKRXX-DvZawyn9.js +0 -1
package/server/server.js
CHANGED
|
@@ -1,101 +1,101 @@
|
|
|
1
1
|
import { a as __toCommonJS, i as __require, o as __toESM, t as __commonJSMin } from "./rolldown-runtime-DNCzzKnI.js";
|
|
2
|
-
import { $ as
|
|
3
|
-
import { _ as getDashboardIdentity, c as startUatTrainReconciler, d as openFlywheelRunReportForDashboard, f as pauseFlywheelRunForDashboard, g as runDashboardDbJob, h as startFlywheelRunForDashboard, l as stopUatTrainReconciler, m as resumeFlywheelRunForDashboard, p as readCurrentFlywheelStatusForDashboard, u as abortFlywheelRunForDashboard, v as readHostDashboardApiPort, y as shouldRefuseHostDashboardPort } from "./uat-train-
|
|
4
|
-
import {
|
|
2
|
+
import { $n as init_issue_id, Br as init_paths, C as resolveTieredExecutionEnabled, Cn as getIssuePrefix, Cr as CLAUDE_DIR, Dr as OVERDECK_HOME, E as canUseHarnessSync, En as getProjectSync, Er as LOGS_DIR, Et as getIssueWorkspacePath, F as getKimiAnthropicBaseUrl, Fn as listProjects, G as init_registry, Hr as packageRoot, In as listProjectsSync, Ir as encodeClaudeProjectDir, J as computeModelOrigin, Jn as setProjectAutoMergeDefaultSync, K as DEFAULT_ROLES, L as getProviderForModelSync, M as UnknownModelError, Mn as init_projects, O as init_harness_policy, Ot as init_record, P as getBuiltInDefaultHarness, Pr as SYNC_SOURCES, Q as MODEL_DEPRECATIONS, Qn as extractPrefixSync, R as init_providers, Rr as getLegacyHome, S as init_tier_table, T as validateTieredExecutionConfig, Un as resolveProjectFromIssue, Ur as resolveOhmypiExtensionPath, Vn as registerProjectSync, Vr as isDevMode, W as defaultBackgroundAiFeatures, Wn as resolveProjectFromIssueSync, Wr as sessionFilePath, X as resolveModel, Z as MODEL_CAPABILITIES, _ as getDefaultTtsDaemonConfig, _n as extractTeamPrefix, _r as init_errors, c as isClaudeCodeChannelsEnabled, ct as COMPLIANCE_MODES, d as loadConfigNoMigration, et as getModelEffortLevelsSync, f as loadConfigSync, g as mergeConfigs, h as jsYaml, hr as TrackerError, i as getConversationsConfig, it as resolveModelIdSync, lr as GitHubApiError, lt as PARENT_MODEL_REF, m as init_js_yaml, n as clearConfigCache, nn as flushAutoCommits, nt as init_model_capabilities, o as getGlobalConfigPath, p as updateConversationsConfig, pr as ProcessSpawnError, q as DEFAULT_WORKHORSES, r as getConversationSearchConfigSync, rn as init_auto_commit, rr as require_dist$1, rt as modelSupportsImagesSync, sr as FsError, t as init_config_yaml, tn as flushAllPendingAutoCommits, tr as parseIssueIdSync, tt as hasModelCapabilitySync, u as isTldrEnabledSync, ut as ROLE_EFFORTS, v as mergeTtsDaemonConfigs, vr as AGENTS_DIR, x as TieredExecutionConfigError, xn as findProjectByTeamSync, yn as findProjectByPathSync, z as piProviderForModel, zr as getOverdeckHome } from "./config-yaml-CFi3m2pp.js";
|
|
3
|
+
import { _ as getDashboardIdentity, c as startUatTrainReconciler, d as openFlywheelRunReportForDashboard, f as pauseFlywheelRunForDashboard, g as runDashboardDbJob, h as startFlywheelRunForDashboard, l as stopUatTrainReconciler, m as resumeFlywheelRunForDashboard, p as readCurrentFlywheelStatusForDashboard, u as abortFlywheelRunForDashboard, v as readHostDashboardApiPort, y as shouldRefuseHostDashboardPort } from "./uat-train-BK1II1Ug.js";
|
|
4
|
+
import { C as validateOrigin$1, D as jsonResponse, E as httpHandler, O as jsonStringResponse, T as checkCodexAuthStatus, _ as resolveJsonlPath, a as agentsRouteLayer, c as evaluateSpawnGuardrails, d as resolveConversationGitInfo, g as resolveCodexRolloutPath, h as resolveClaudeSessionId, l as invalidateAgentsCache, m as resolveAgentHarness, o as saveAgentStateAndEmitEvent, p as readLauncherPinnedSessionId, s as saveAgentStateAndEmitEventProgram, t as specialistsRouteLayer, u as resolveAgentGitInfo, v as resolvePiSessionPath, w as validateOriginHeaders, x as isTrustedOriginForHost, y as getHeaderFromMap } from "./specialists-IIjyUvYM.js";
|
|
5
5
|
import { a as init_activity_logger, i as emitDashboardLifecycleSync, n as emitActivityEntrySync, r as emitActivityTtsSync } from "./activity-logger-Dm95Ua07.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-
|
|
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-NrG-t1jj.js";
|
|
7
7
|
import { n as openDatabase, t as init_driver } from "./driver-D-HBOQa_.js";
|
|
8
|
-
import { E as listPaneValues, F as sendKeysAsync, G as buildChildEnvSync, H as init_ui_theme, I as sendRawKeystroke, K as buildChildEnvWithoutTmuxSync, L as sessionExists, M as resizeWindow, O as listSessionNames, P as sendKeys, S as isHarnessProcessAlive, U as setUiTheme, W as BLANKED_PROVIDER_ENV, b as getWindowDimensions, c as ensureManagedTmuxContextOnce, d as exactPaneTarget, i as capturePane, k as listSessions, n as buildTmuxArgs, o as createSession, p as findManagedServerPidSync, q as init_child_env, w as killSession, x as init_tmux, z as setOption } from "./tmux-
|
|
9
|
-
import { a as init_event_store, i as initEventStore, n as getEventStore, r as getSharedDb } from "./event-store-
|
|
10
|
-
import { _ as FlywheelRunId, a as getHarnessBehavior, b as DomainEvent, c as FlywheelStats, g as WS_METHODS, h as PanRpcGroup, m as PanRpcError, o as ContextLayerSaveRequest, s as ContextPreviewRequest, t as init_src, v as FlywheelStatus, x as MemoryObservation, y as EDITORS } from "./src-
|
|
11
|
-
import { a as fixStuckReadyForMerge, c as init_review_status, i as fixStuckCommentedReviews, l as loadReadyForMergeFlags, n as clearReviewStatus, o as getReviewStatus, r as clearStuckMergeStatuses, s as getReviewStatusSync, u as loadReviewStatuses, v as setReviewStatus, y as setReviewStatusSync } from "./review-status-
|
|
12
|
-
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, t as IssueLifecycle } from "./issue-lifecycle-
|
|
13
|
-
import { d as init_agents, i as recordBriefingSessionStart, n as ensureSessionContextBriefingFile, p as listAllAgentsSync, r as init_briefing_freshness, s as AgentsResolverLive, t as appendFreshBriefingUpdate } from "./briefing-freshness-
|
|
14
|
-
import { i as init_paths$2, l as resolveObservationsFile, r as ensureParentDir, s as resolveIssueMemoryRoot, t as assertMemorySafeSegment } from "./paths-
|
|
15
|
-
import { n as listFeatureRegistryEntries, t as init_feature_registry_storage } from "./feature-registry-storage-
|
|
16
|
-
import { a as
|
|
17
|
-
import {
|
|
18
|
-
import { t as init_behavior } from "./behavior-
|
|
19
|
-
import { a as getCostForIssueAggregateSync, c as getDailyTrendsSync, d as init_cost_sync, l as getModelRollupSync, n as getBackgroundCostBySourceSync, p as queryCostEventsSync, r as getCavemanExperimentDataSync, s as getCostsByIssueSync, u as getTodayCostSync } from "./cost-sync-
|
|
20
|
-
import { c as getAgentsNeedingAttention, d as CostResolverLive, f as CostWriter, l as CostDoorLive, n as readCloisterStateFile, o as generateHealthSummary, s as getAgentHealth, t as getCloisterService, u as CostResolver } from "./service-
|
|
21
|
-
import { n as AgentStateServiceLive } from "./agent-state-service-
|
|
22
|
-
import { a as init_tracker_config, i as initTrackerConfigCache, n as getLinearApiKey, r as getRallyConfig, t as getGitHubConfig } from "./tracker-config-
|
|
23
|
-
import { d as init_typed_errors, l as WorkspaceCreateError, n as AgentStartError, r as BeadsNotInitialized, s as TrackerApiError, t as AgentAlreadyRunning, u as WorkspaceNotFound } from "./typed-errors-
|
|
24
|
-
import { i as init_linear_client, r as LinearClientOptionalLive, t as LinearClient } from "./linear-client-
|
|
25
|
-
import { i as init_github_client, r as GitHubClientOptionalLive, t as GitHubClient } from "./github-client-
|
|
26
|
-
import { i as init_rally_client, r as RallyClientOptionalLive, t as RallyClient } from "./rally-client-
|
|
27
|
-
import { a as resolveTrackerTypeSync, i as resolveGitHubIssueSync, n as init_tracker_utils } from "./tracker-utils-
|
|
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-
|
|
29
|
-
import { i as ensureInternalTokenSync, o as getInternalTokenSync, s as init_internal_token, t as INTERNAL_TOKEN_HEADER } from "./internal-token-
|
|
30
|
-
import { a as setPipelineHandlerSync, t as init_pipeline_notifier } from "./pipeline-notifier-
|
|
31
|
-
import { c as init_review_status_sync, i as getMergeBlockerReconcileCandidates } from "./review-status-sync-
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import { C as
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
39
|
-
import { n as
|
|
40
|
-
import {
|
|
41
|
-
import { i as
|
|
42
|
-
import { n as
|
|
43
|
-
import { a as
|
|
44
|
-
import { a as
|
|
45
|
-
import { l as
|
|
46
|
-
import {
|
|
47
|
-
import { c as
|
|
48
|
-
import { n as resolveHarness, t as init_harness_resolve } from "./harness-resolve-
|
|
49
|
-
import { i as checkPrdGateSync, t as init_pan_dir } from "./pan-dir-
|
|
50
|
-
import { a as init_lifecycle_io, t as appendContinueSessionEntryForIssue } from "./lifecycle-io-
|
|
51
|
-
import { r as init_swarm_readiness, t as analyzeSwarmReadiness } from "./swarm-readiness-
|
|
52
|
-
import {
|
|
53
|
-
import { i as CostThresholdError, l as embed, s as parseRelativeTime } from "./scanner-
|
|
54
|
-
import { n as deduplicateEventsSync, o as readEventsSync, s as tailEventsSync } from "./events-
|
|
55
|
-
import { n as recordBackgroundAiCost, t as init_cost } from "./cost-
|
|
56
|
-
import { S as writeLatestFlywheelStatus, _ as readCurrentLatestFlywheelStatus, b as subscribeLatestFlywheelStatus, f as getFlywheelRunDetail, h as listFlywheelRuns, l as buildClassifyLookups, m as isFlywheelRunId, y as resolveLiveFlywheelRunId } from "./flywheel-
|
|
57
|
-
import { C as
|
|
58
|
-
import { l as detectPlatform, u as init_platform } from "./workspace-manager-
|
|
59
|
-
import { O as init_specialists, b as getReviewerSessionName } from "./specialists-
|
|
60
|
-
import { t as withBdMutex } from "./bd-mutex-
|
|
61
|
-
import {
|
|
62
|
-
import { a as getShadowState, s as init_shadow_state } from "./shadow-state-
|
|
63
|
-
import { T as verifyAppCanMerge, d as getPullRequestState, f as init_github_app, l as getMergeBackendStatus, p as isGitHubAppConfigured } from "./github-app-
|
|
64
|
-
import { t as clearIssueClosedCache } from "./issue-closed-
|
|
65
|
-
import { a as writeFeedbackFile, i as init_feedback_writer } from "./feedback-writer-
|
|
66
|
-
import { a as init_boot_gates, i as formatBootGateState, o as resolveBootGates } from "./no-resume-mode-
|
|
67
|
-
import {
|
|
68
|
-
import {
|
|
69
|
-
import { a as loadWorkspaceMetadataSync } from "./workspace-metadata-
|
|
70
|
-
import { i as resolveAutoSpawnOnFinalize, o as spawnPlanningSession } from "./spawn-planning-session-
|
|
71
|
-
import {
|
|
72
|
-
import { r as spawnInspectAgent } from "./inspect-agent-
|
|
73
|
-
import { n as init_github_pr_lookup, r as lookupPullRequestNumberForBranch, t as githubPrLookupSource } from "./github-pr-lookup-
|
|
74
|
-
import { a as init_pull_requests, c as getIssuePrTabCacheGeneration, i as fetchIssuePullRequestDiff, l as init_pr_tab_cache, n as fetchIssuePullRequest, o as bumpIssuePrTabCacheGeneration, r as fetchIssuePullRequestDetails, s as getCachedIssuePrTabResponse, t as fetchIssueCheckRuns, u as setCachedIssuePrTabResponse } from "./pull-requests-
|
|
75
|
-
import { t as enrichReviewStatus } from "./review-status-enrichment-
|
|
76
|
-
import { i as runMemoryFtsTransaction, n as init_fts_db, r as runMemoryFtsStatement, t as closeMemoryFtsDatabases } from "./fts-db-
|
|
77
|
-
import { c as init_pending, l as maybeTriggerStatusRollup, o as readRecentObservations, r as init_rollup, u as writePendingTurn } from "./rollup-
|
|
78
|
-
import { n as getTldrDaemonServiceSync, r as init_tldr_daemon } from "./tldr-daemon-
|
|
79
|
-
import { C as init_git_activity, w as listGitOperationsSync } from "./merge-agent-
|
|
80
|
-
import { t as getAgentCommandSync } from "./settings-
|
|
81
|
-
import { n as init_review_agent, r as isExtendedReviewEnabled } from "./review-agent-
|
|
82
|
-
import { r as isRemoteAvailable, t as createFlyProviderFromConfig } from "./remote-
|
|
83
|
-
import { n as init_claude_settings_overlay, t as detectProviderEnvConflicts } from "./claude-settings-overlay-
|
|
84
|
-
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-
|
|
85
|
-
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-
|
|
86
|
-
import { a as init_conversation_compaction, c as shouldInterceptManualCompact, n as compactConversationNative, o as isCompacting } from "./conversation-compaction-
|
|
87
|
-
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-
|
|
88
|
-
import { r as parseArtifactRef } from "./forge-
|
|
89
|
-
import { t as getMergeBlockersPayload } from "./merge-blockers-
|
|
90
|
-
import { a as spawnSequencerAgent, i as init_sequencer_agent, n as clearFinishedSequencerRun, r as getSequencerRunStatus, t as SEQUENCER_AGENT_ID } from "./sequencer-agent-
|
|
91
|
-
import "./supervisor-
|
|
92
|
-
import { i as listTranscriptCheckpoints, r as getTranscriptCheckpoint$1 } from "./checkpoints-
|
|
8
|
+
import { E as listPaneValues, F as sendKeysAsync, G as buildChildEnvSync, H as init_ui_theme, I as sendRawKeystroke, K as buildChildEnvWithoutTmuxSync, L as sessionExists, M as resizeWindow, O as listSessionNames, P as sendKeys, S as isHarnessProcessAlive, U as setUiTheme, W as BLANKED_PROVIDER_ENV, b as getWindowDimensions, c as ensureManagedTmuxContextOnce, d as exactPaneTarget, i as capturePane, k as listSessions, n as buildTmuxArgs, o as createSession, p as findManagedServerPidSync, q as init_child_env, w as killSession, x as init_tmux, z as setOption } from "./tmux-BvabkAC1.js";
|
|
9
|
+
import { a as init_event_store, i as initEventStore, n as getEventStore, r as getSharedDb } from "./event-store-BH0ESJtK.js";
|
|
10
|
+
import { _ as FlywheelRunId, a as getHarnessBehavior, b as DomainEvent, c as FlywheelStats, g as WS_METHODS, h as PanRpcGroup, m as PanRpcError, o as ContextLayerSaveRequest, s as ContextPreviewRequest, t as init_src, v as FlywheelStatus, x as MemoryObservation, y as EDITORS } from "./src-AXK4mjue.js";
|
|
11
|
+
import { a as fixStuckReadyForMerge, c as init_review_status, i as fixStuckCommentedReviews, l as loadReadyForMergeFlags, n as clearReviewStatus, o as getReviewStatus, r as clearStuckMergeStatuses, s as getReviewStatusSync, u as loadReviewStatuses, v as setReviewStatus, y as setReviewStatusSync } from "./review-status-_HZzpCJZ.js";
|
|
12
|
+
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, t as IssueLifecycle } from "./issue-lifecycle-Dao_ID2V.js";
|
|
13
|
+
import { d as init_agents, i as recordBriefingSessionStart, n as ensureSessionContextBriefingFile, p as listAllAgentsSync, r as init_briefing_freshness, s as AgentsResolverLive, t as appendFreshBriefingUpdate } from "./briefing-freshness-B34zUtI6.js";
|
|
14
|
+
import { i as init_paths$2, l as resolveObservationsFile, r as ensureParentDir, s as resolveIssueMemoryRoot, t as assertMemorySafeSegment } from "./paths-CRDfPnBn.js";
|
|
15
|
+
import { n as listFeatureRegistryEntries, t as init_feature_registry_storage } from "./feature-registry-storage-C3iyyOnJ.js";
|
|
16
|
+
import { a as diffAgainstMain, c as diffCheckpoints, d as diffPatchSinceCommit, f as findCommitAtTime, h as listCheckpoints, l as diffFilesAgainstHead, m as init_checkpoint_manager, o as diffAgainstMainFiles, s as diffCheckpointFiles, t as captureCheckpoint, u as diffPatchFilesAgainstHead } from "./checkpoint-manager-DT3Lukzr.js";
|
|
17
|
+
import { An as getAgentDir, At as init_bridge_token, Dt as captureTranscriptUserRecordSnapshot, Gt as getAgentRuntimeBaseCommand, Jn as saveAgentStateSync, Jt as getProviderAuthMode, M as init_operator_interventions, Mn as getAgentState, N as operatorInterventionEvent, Nn as getAgentStateFilePath, Ot as init_transcript_landing, Pn as getAgentStateSync, Q as listRunningAgentsSync, St as deliverAgentMessage, X as listAgentStates, Z as listRunningAgents, Zt as injectPiConversationMemory, _t as init_config, an as init_claude_auth, ar as init_pty_token, at as init_concurrency, bn as writeChannelsBridgeMcpConfig, bt as saveCloisterConfigSync, c as init_tier_supervisor, en as init_pi_fifo, f as supervisorAgentId, fr as waitForReadySignal, hn as init_openai_auth, in as getClaudeAuthStatus, ir as readAgentHarnessModelRecordSync, j as messageAgent, jt as writeBridgeTokenSync, kt as probeTranscriptSince, ln as getProviderEnvForModel, lr as normalizeAgentId, mn as getOpenAIAuthStatus, mr as getAgentRuntimeStateSync, nn as init_ohmypi_fifo, or as writePtyToken, pr as getAgentRuntimeState, rn as ohmypiFifoPaths, rr as init_agent_record_sync, rt as emergencyBrake, s as deliverCommitForReview, sr as clearReadySignal, t as init_agents$1, tn as piFifoPaths, un as getProviderExportsForModel, vt as loadCloisterConfig, xt as shouldAutoStart, yn as dismissDevChannelsDialog, yt as loadCloisterConfigSync } from "./agents-hAslBDrt.js";
|
|
18
|
+
import { t as init_behavior } from "./behavior-ogCxWPtu.js";
|
|
19
|
+
import { a as getCostForIssueAggregateSync, c as getDailyTrendsSync, d as init_cost_sync, l as getModelRollupSync, n as getBackgroundCostBySourceSync, p as queryCostEventsSync, r as getCavemanExperimentDataSync, s as getCostsByIssueSync, u as getTodayCostSync } from "./cost-sync-B4NiigGa.js";
|
|
20
|
+
import { c as getAgentsNeedingAttention, d as CostResolverLive, f as CostWriter, l as CostDoorLive, n as readCloisterStateFile, o as generateHealthSummary, s as getAgentHealth, t as getCloisterService, u as CostResolver } from "./service-C1j2GOdD.js";
|
|
21
|
+
import { n as AgentStateServiceLive } from "./agent-state-service-ycEfmxxV.js";
|
|
22
|
+
import { a as init_tracker_config, i as initTrackerConfigCache, n as getLinearApiKey, r as getRallyConfig, t as getGitHubConfig } from "./tracker-config-CYfIfbH8.js";
|
|
23
|
+
import { d as init_typed_errors, l as WorkspaceCreateError, n as AgentStartError, r as BeadsNotInitialized, s as TrackerApiError, t as AgentAlreadyRunning, u as WorkspaceNotFound } from "./typed-errors-BEJhbjJg.js";
|
|
24
|
+
import { i as init_linear_client, r as LinearClientOptionalLive, t as LinearClient } from "./linear-client-CkeRcoyg.js";
|
|
25
|
+
import { i as init_github_client, r as GitHubClientOptionalLive, t as GitHubClient } from "./github-client-kAgT9udA.js";
|
|
26
|
+
import { i as init_rally_client, r as RallyClientOptionalLive, t as RallyClient } from "./rally-client-BgQ_z7av.js";
|
|
27
|
+
import { a as resolveTrackerTypeSync, i as resolveGitHubIssueSync, n as init_tracker_utils } from "./tracker-utils-BRZJC_bL.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-BwE8vBo8.js";
|
|
29
|
+
import { i as ensureInternalTokenSync, o as getInternalTokenSync, s as init_internal_token, t as INTERNAL_TOKEN_HEADER } from "./internal-token-CarQ-d2Z.js";
|
|
30
|
+
import { a as setPipelineHandlerSync, t as init_pipeline_notifier } from "./pipeline-notifier-Bu0V4jGJ.js";
|
|
31
|
+
import { c as init_review_status_sync, i as getMergeBlockerReconcileCandidates } from "./review-status-sync-C23_G71k.js";
|
|
32
|
+
import { a as PAN_DIRNAME, f as asPanSpecDocument, i as PAN_CONTINUE_FILENAME, p as init_types } from "./types-CE1m_daD.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-Cayz43rC.js";
|
|
34
|
+
import { C as findSpecByIssue, O as writeSpec, T as init_specs, a as findWorkspaceDraftPlan, b as init_types$1, k as writeSpecForIssue, m as readWorkspacePlanSync, o as init_io, p as readWorkspacePlan, r as findPlan, s as isPlanningComplete, u as readPlan, x as subItemsOf } from "./io-CJp_69VI.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-C-j2CZKA.js";
|
|
36
|
+
import { f as init_config$1, m as loadConfigSync$1, s as getDashboardApiUrlSync } from "./config-D1FRRXcO.js";
|
|
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 updateConversationForkFallbackReason, A as isAgentConversationName, B as removeFavorite, C as getConversationByTmuxSession, D as importLegacyConversation, E as hasOtherActiveConversationOnTmuxSession, F as markConversationEnded, G as setConversationHarness, H as setClearedToConvId, I as markConversationRunning, J as setForkRequest, K as setConversationModel, M as listConversations, N as listFavoritedIds, O as incrementForkRetryCount, P as markConversationActive, Q as updateConversationDeliveryMethod, S as getConversationByName, T as getStuckForks, U as setConversationClaudeSessionId, W as setConversationEffort, X as unarchiveConversation, Y as setImportedConversationLinks, Z as updateConversationCost, _ as canRefineTitle, b as getConversationByClaudeSessionId, et as updateConversationTitle, g as backfillConversationModel, gt as getDiscoveredSessionBySessionId, h as archiveConversation, j as listArchivedConversationsWithEnrichment, k as init_conversations, nt as updateLastAttached, q as setFavorite, rt as updateSpawnError, tt as updateForkStatus, v as canReplaceTitle, w as getConversationLedgerCosts, x as getConversationById, y as createConversation, yt as init_discovered_sessions, z as recordConversationHandoff } from "./conversations-Z-E71Ot6.js";
|
|
39
|
+
import { _ as init_codex_conversation_parser, a as contextUsageFromParseResult, c as parseEntireConversation, d as init_pi_conversation_parser, f as isPiSessionFile, g as parseOhmypiConversationMessages, h as isOhmypiSessionFile, i as computeContextUsage, l as parseFromLastCompactBoundary, m as init_ohmypi_conversation_parser, n as gateSnapshotEmission, o as summarizeConversationActivity, p as parsePiConversationMessages, r as watchConversation, s as parseConversationMessages, t as init_conversation_service, v as parseCodexConversationMessages } from "./conversation-service-2pG8K2RQ.js";
|
|
40
|
+
import { n as isBackgroundFeatureEnabled, t as init_features } from "./features-CNGp14JQ.js";
|
|
41
|
+
import { i as init_settings, r as getMemoryWorkerConcurrency, t as areMemoryObservationsEnabled } from "./settings-V22-6LRB.js";
|
|
42
|
+
import { i as updateMemoryHealth, n as extractWithProviderPolicy, r as init_health, t as init_providers$1 } from "./providers-DS0lghjI.js";
|
|
43
|
+
import { a as init_launcher_generator, i as generateLauncherScriptSync, n as init_state_home, r as isStateMigrated } from "./state-home-Ct7Sc6c_.js";
|
|
44
|
+
import { a as init_claude_permissions, o as resolvePermissionModeSync, r as getClaudePermissionFlagsStringSync, t as BYPASS_PERMISSION_MODE } from "./claude-permissions-yKBS-gdK.js";
|
|
45
|
+
import { a as globalContextFile$1, f as resolveProjectContextFile, h as workspaceContextFile, l as piGlobalContextFile, n as codexGlobalContextFile, o as init_layers, p as resolveWorkspaceContextFile, r as ensureProjectLayer } from "./layers-CTx4opMx.js";
|
|
46
|
+
import { l as init_codex, s as findRolloutPath } from "./codex-_9Yhw2cp.js";
|
|
47
|
+
import { C as setMergeTrainEnabled, S as setFlywheelRequireUatBeforeMerge, b as setFlywheelAutoPickupBacklog, c as isCloisterSpawnsPausedSync, d as isFlywheelAutoPickupBacklog, f as isFlywheelGloballyPaused$1, g as setCloisterSpawnsPausedSync, h as setBootReconciliationDecision, m as isMergeTrainEnabled, o as getSetting, p as isFlywheelRequireUatBeforeMerge, r as getBootReconciliationState, s as init_control_settings, u as isDeaconGloballyPausedSync, v as setDeaconGloballyPausedSync, w as setSetting } from "./control-settings-CDPBWsZY.js";
|
|
48
|
+
import { n as resolveHarness, t as init_harness_resolve } from "./harness-resolve-Doo8mVky.js";
|
|
49
|
+
import { i as checkPrdGateSync, t as init_pan_dir } from "./pan-dir-O79s0Szv.js";
|
|
50
|
+
import { a as init_lifecycle_io, t as appendContinueSessionEntryForIssue } from "./lifecycle-io-Bays2Q9M.js";
|
|
51
|
+
import { r as init_swarm_readiness, t as analyzeSwarmReadiness } from "./swarm-readiness-1xj7dEqT.js";
|
|
52
|
+
import { $t as scanPendingInputsPromise, B as applyIssueBlocksMainLabel, Bt as formatUptime, F as setAgentStatusChangedNotifier, G as applyIssueVetoedLabel, Gt as isSmeeConfiguredSync, H as applyIssueParkedLabel, Ht as getCurrentDockerStats, I as setAgentStoppedNotifier, J as removeIssueParkedLabel, Jt as countPendingAskUserQuestionsForAgent, K as removeIssueBlocksMainLabel, Kt as startSmeeProcessSync, L as setMergeReadyNotifier, Lt as getRuntimeForAgent, O as loadConfig, Q as createInFlightGuard, U as applyIssueReadyLabel, V as applyIssueObjectionLabel, Vt as getContainerHistory, W as applyIssueReleasedLabel, Wt as getSystemHealthSnapshot, X as removeIssueReleasedLabel, Y as removeIssueReadyLabel, Yt as getAgentJsonlMtime, Z as removeIssueVetoedLabel, _t as withConcurrencyLimit, at as listBootReconciliationCandidates, en as detectAwaitingInputForAgent, it as isBootReconciliationCandidate, k as loadState, n as assessDeaconPatrolFreshness, ot as startBootReconciliation, q as removeIssueObjectionLabel, qt as computeAgentEnrichment, rn as parseCodexApprovalPrompt, t as applyBootReconciliationDecision, tn as detectAwaitingInputFromPaneSync, x as getDeaconLogs, zt as getResourceStacks } from "./deacon-580FfaDW.js";
|
|
53
|
+
import { i as CostThresholdError, l as embed, s as parseRelativeTime } from "./scanner-Dn9cqdgz.js";
|
|
54
|
+
import { n as deduplicateEventsSync, o as readEventsSync, s as tailEventsSync } from "./events-BILgSB1a.js";
|
|
55
|
+
import { n as recordBackgroundAiCost, t as init_cost } from "./cost-CDDkx0PI.js";
|
|
56
|
+
import { S as writeLatestFlywheelStatus, _ as readCurrentLatestFlywheelStatus, b as subscribeLatestFlywheelStatus, f as getFlywheelRunDetail, h as listFlywheelRuns, l as buildClassifyLookups, m as isFlywheelRunId, y as resolveLiveFlywheelRunId } from "./flywheel-CIiIHzVE.js";
|
|
57
|
+
import { C as hasDashboardInternalToken, D as getWorkspacePathForIssue, E as rejectUnsafeDashboardMutationRequest, S as dashboardSessionCookieHeader, T as rejectUnauthorizedDashboardSessionMintRequest, _ as syncCacheSync, b as resolveIssueHeadlineCost, d as reconcile, f as reconcilePiTranscripts, g as rebuildCacheSync, h as getCostsForIssueSync, l as resumeQueuedMerges, m as migrateAllSessionsSync, p as reclassifyUnknownCostEventsSync, t as workspacesRouteLayer, u as syncWalFromAllProjects, v as processPendingFeedbackDeliveries, w as rejectUnauthorizedDashboardRequest, x as dashboardCsrfToken, y as getCachedRunningAgents } from "./workspaces-CsMMlvt-.js";
|
|
58
|
+
import { l as detectPlatform, u as init_platform } from "./workspace-manager-VHSAXpA7.js";
|
|
59
|
+
import { O as init_specialists, b as getReviewerSessionName } from "./specialists-C1UrzX2F.js";
|
|
60
|
+
import { t as withBdMutex } from "./bd-mutex-CE6P_MlD.js";
|
|
61
|
+
import { c as findPrdAtStatusSync, l as init_prd_locations } from "./archive-planning-Bu8Pxfva.js";
|
|
62
|
+
import { a as getShadowState, s as init_shadow_state } from "./shadow-state-DWFtwdvF.js";
|
|
63
|
+
import { T as verifyAppCanMerge, d as getPullRequestState, f as init_github_app, l as getMergeBackendStatus, p as isGitHubAppConfigured } from "./github-app-D8_gUbWj.js";
|
|
64
|
+
import { n as init_issue_closed, t as clearIssueClosedCache } from "./issue-closed-ClkGWMyj.js";
|
|
65
|
+
import { a as writeFeedbackFile, i as init_feedback_writer } from "./feedback-writer-CUP2avGi.js";
|
|
66
|
+
import { a as init_boot_gates, i as formatBootGateState, o as resolveBootGates } from "./no-resume-mode-CKy2bwZL.js";
|
|
67
|
+
import { c as computeCohort, d as computeStats, f as computeWaves, h as selectNeedsPlanning, l as computeEpicGroups, m as normalizeGate, s as classifyIssue, u as computeLanes } from "./pickup-DRn-XNXS.js";
|
|
68
|
+
import { n as parseSequenceMd, r as writeSequenceMd, t as init_sequence_io } from "./sequence-io-DMwVfR77.js";
|
|
69
|
+
import { a as loadWorkspaceMetadataSync } from "./workspace-metadata-DZSZ2rMu.js";
|
|
70
|
+
import { i as resolveAutoSpawnOnFinalize, o as spawnPlanningSession } from "./spawn-planning-session-DlYnE0aL.js";
|
|
71
|
+
import { d as killRemoteAgent, m as loadRemoteAgentState, o as getRemoteAgentOutput, r as checkRemoteSpendCap, s as init_remote_agents, v as sendToRemoteAgent, y as spawnRemoteAgent } from "./remote-agents-DyK_DtXM.js";
|
|
72
|
+
import { r as spawnInspectAgent } from "./inspect-agent-Cafn8B4M.js";
|
|
73
|
+
import { n as init_github_pr_lookup, r as lookupPullRequestNumberForBranch, t as githubPrLookupSource } from "./github-pr-lookup-B-aLAA0M.js";
|
|
74
|
+
import { a as init_pull_requests, c as getIssuePrTabCacheGeneration, i as fetchIssuePullRequestDiff, l as init_pr_tab_cache, n as fetchIssuePullRequest, o as bumpIssuePrTabCacheGeneration, r as fetchIssuePullRequestDetails, s as getCachedIssuePrTabResponse, t as fetchIssueCheckRuns, u as setCachedIssuePrTabResponse } from "./pull-requests-ZcXF1jwZ.js";
|
|
75
|
+
import { t as enrichReviewStatus } from "./review-status-enrichment-DiEp5P49.js";
|
|
76
|
+
import { i as runMemoryFtsTransaction, n as init_fts_db, r as runMemoryFtsStatement, t as closeMemoryFtsDatabases } from "./fts-db-CM78vdJ_.js";
|
|
77
|
+
import { c as init_pending, l as maybeTriggerStatusRollup, o as readRecentObservations, r as init_rollup, u as writePendingTurn } from "./rollup-DMkz8dIT.js";
|
|
78
|
+
import { n as getTldrDaemonServiceSync, r as init_tldr_daemon } from "./tldr-daemon-C99OUCjN.js";
|
|
79
|
+
import { C as init_git_activity, w as listGitOperationsSync } from "./merge-agent-CI0LXwm9.js";
|
|
80
|
+
import { t as getAgentCommandSync } from "./settings-j3qWqwCi.js";
|
|
81
|
+
import { n as init_review_agent, r as isExtendedReviewEnabled } from "./review-agent-Vg_iFpfd.js";
|
|
82
|
+
import { r as isRemoteAvailable, t as createFlyProviderFromConfig } from "./remote-BuX3q71f.js";
|
|
83
|
+
import { n as init_claude_settings_overlay, t as detectProviderEnvConflicts } from "./claude-settings-overlay-D6NffMmt.js";
|
|
84
|
+
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-eW0jWzjG.js";
|
|
85
|
+
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-CzPuVQAZ.js";
|
|
86
|
+
import { a as init_conversation_compaction, c as shouldInterceptManualCompact, n as compactConversationNative, o as isCompacting } from "./conversation-compaction-KcA3X6Yy.js";
|
|
87
|
+
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-bWw7hOOG.js";
|
|
88
|
+
import { r as parseArtifactRef } from "./forge-Dj4FMDac.js";
|
|
89
|
+
import { t as getMergeBlockersPayload } from "./merge-blockers-DvMepteF.js";
|
|
90
|
+
import { a as spawnSequencerAgent, i as init_sequencer_agent, n as clearFinishedSequencerRun, r as getSequencerRunStatus, t as SEQUENCER_AGENT_ID } from "./sequencer-agent-BLpcWZlb.js";
|
|
91
|
+
import "./supervisor-C6vsGMQJ.js";
|
|
92
|
+
import { i as listTranscriptCheckpoints, r as getTranscriptCheckpoint$1 } from "./checkpoints-BNs7sSvt.js";
|
|
93
93
|
import { createRequire } from "node:module";
|
|
94
94
|
import { Cause, Context, Data, Duration, Effect, Exit, Fiber, FileSystem, Layer, Option, Path, Queue, Result, Schedule, Schema, Stream } from "effect";
|
|
95
95
|
import { createReadStream, createWriteStream, existsSync, fstatSync, mkdirSync, readFileSync, statSync, writeFileSync } from "fs";
|
|
96
96
|
import { basename, dirname, join, resolve } from "path";
|
|
97
97
|
import { homedir } from "os";
|
|
98
|
-
import { freemem as freemem$1, homedir as homedir$1, loadavg as loadavg$1, totalmem, type } from "node:os";
|
|
98
|
+
import { freemem as freemem$1, homedir as homedir$1, loadavg as loadavg$1, totalmem as totalmem$1, type } from "node:os";
|
|
99
99
|
import { constants, createReadStream as createReadStream$1, existsSync as existsSync$1, mkdirSync as mkdirSync$1, promises as promises$1, readFileSync as readFileSync$1, readdirSync as readdirSync$1, readlinkSync, realpathSync as realpathSync$1, renameSync as renameSync$1, rmSync as rmSync$1, stat, statSync as statSync$1, symlinkSync as symlinkSync$1, unwatchFile, watch, watchFile, writeFileSync as writeFileSync$1 } from "node:fs";
|
|
100
100
|
import * as sp from "node:path";
|
|
101
101
|
import { basename as basename$1, delimiter, dirname as dirname$1, extname as extname$1, isAbsolute as isAbsolute$1, join as join$1, normalize, relative as relative$1, resolve as resolve$1, sep as sep$1 } from "node:path";
|
|
@@ -103,9 +103,9 @@ import { FetchHttpClient, HttpRouter, HttpServer, HttpServerRequest, HttpServerR
|
|
|
103
103
|
import { EventEmitter } from "node:events";
|
|
104
104
|
import { access, appendFile, chmod, lstat, mkdir, open, readFile, readdir, realpath, rename, rm, stat as stat$1, unlink, writeFile } from "node:fs/promises";
|
|
105
105
|
import { createHash, randomUUID } from "crypto";
|
|
106
|
+
import { chmod as chmod$1, mkdir as mkdir$1, open as open$1, readFile as readFile$1, readdir as readdir$1, rename as rename$1, stat as stat$2, unlink as unlink$1, writeFile as writeFile$1 } from "fs/promises";
|
|
106
107
|
import { exec, execFile, execFileSync, execSync, fork, spawn } from "node:child_process";
|
|
107
108
|
import { promisify } from "node:util";
|
|
108
|
-
import { chmod as chmod$1, mkdir as mkdir$1, open as open$1, readFile as readFile$1, readdir as readdir$1, rename as rename$1, stat as stat$2, unlink as unlink$1, writeFile as writeFile$1 } from "fs/promises";
|
|
109
109
|
import { createHmac, randomBytes, randomUUID as randomUUID$1, timingSafeEqual } from "node:crypto";
|
|
110
110
|
import * as pty from "@homebridge/node-pty-prebuilt-multiarch";
|
|
111
111
|
import { Buffer as Buffer$1 } from "node:buffer";
|
|
@@ -294,6 +294,12 @@ const ServerConfigLayer = Layer.effect(ServerConfig, Effect.sync(() => {
|
|
|
294
294
|
const identity = getDashboardIdentity();
|
|
295
295
|
const hostDashboardApiPort = readHostDashboardApiPort();
|
|
296
296
|
const overrideAllowed = process.env["OVERDECK_WORKSPACE_DASHBOARD_ALLOW_PRIMARY"] === "1";
|
|
297
|
+
const agentId = process.env["OVERDECK_AGENT_ID"];
|
|
298
|
+
if (overrideAllowed && agentId !== void 0 && !agentId.startsWith("conv-")) {
|
|
299
|
+
const msg = `Refusing OVERDECK_WORKSPACE_DASHBOARD_ALLOW_PRIMARY=1 for pipeline-role identity OVERDECK_AGENT_ID=${agentId}. Work, planning, review, and flywheel agents must never bind the host dashboard port; use the workspace container endpoint instead. Only an operator-supervised conversation (conv-*) or a process with no agent identity may use this emergency override.`;
|
|
300
|
+
console.error(`[overdeck] ${msg}`);
|
|
301
|
+
throw new ServerConfigError("OVERDECK_WORKSPACE_DASHBOARD_ALLOW_PRIMARY", msg);
|
|
302
|
+
}
|
|
297
303
|
if (shouldRefuseHostDashboardPort({
|
|
298
304
|
repoRoot: identity.repoRoot,
|
|
299
305
|
mode: identity.mode,
|
|
@@ -323,10 +329,10 @@ const ServerConfigLayer = Layer.effect(ServerConfig, Effect.sync(() => {
|
|
|
323
329
|
init_activity_logger();
|
|
324
330
|
init_paths$1();
|
|
325
331
|
init_driver();
|
|
326
|
-
init_auto_commit();
|
|
327
332
|
var import_dist = /* @__PURE__ */ __toESM(require_dist$1(), 1);
|
|
328
333
|
init_issue_id();
|
|
329
334
|
init_projects();
|
|
335
|
+
init_auto_commit();
|
|
330
336
|
init_record();
|
|
331
337
|
init_model_capabilities();
|
|
332
338
|
init_registry();
|
|
@@ -650,7 +656,7 @@ const AgentSpawnerLive = Layer.effect(AgentSpawner, Effect.sync(() => ({
|
|
|
650
656
|
const beadsDir = join$1(workspacePath, ".beads");
|
|
651
657
|
const projectBeadsDir = join$1(workspacePath, "..", "..", ".beads");
|
|
652
658
|
if (!(existsSync$1(beadsDir) || existsSync$1(projectBeadsDir))) throw new BeadsNotInitialized({ workspace: workspacePath });
|
|
653
|
-
const { getAgentState, spawnAgent, normalizeAgentId } = await import("./agents-
|
|
659
|
+
const { getAgentState, spawnAgent, normalizeAgentId } = await import("./agents-2mgtTSeb.js");
|
|
654
660
|
const normalizedId = normalizeAgentId(issueId);
|
|
655
661
|
if ((await Effect.runPromise(getAgentState(normalizedId)))?.status === "running") throw new AgentAlreadyRunning({ id: issueId });
|
|
656
662
|
return {
|
|
@@ -681,7 +687,7 @@ const AgentSpawnerLive = Layer.effect(AgentSpawner, Effect.sync(() => ({
|
|
|
681
687
|
const { workspacePath, projectPath, issue } = opts;
|
|
682
688
|
if (!existsSync$1(workspacePath)) throw new WorkspaceNotFound({ id: issueId });
|
|
683
689
|
const sessionName = opts.sessionName ?? `planning-${issueId.toLowerCase()}`;
|
|
684
|
-
const { spawnPlanningSession } = await import("./spawn-planning-session-
|
|
690
|
+
const { spawnPlanningSession } = await import("./spawn-planning-session-Qyw8s1SD.js");
|
|
685
691
|
const result = await spawnPlanningSession({
|
|
686
692
|
issue: {
|
|
687
693
|
id: issue.id,
|
|
@@ -714,14 +720,14 @@ const AgentSpawnerLive = Layer.effect(AgentSpawner, Effect.sync(() => ({
|
|
|
714
720
|
}),
|
|
715
721
|
kill: (agentId) => Effect.tryPromise({
|
|
716
722
|
try: async () => {
|
|
717
|
-
const { stopAgent } = await import("./agents-
|
|
723
|
+
const { stopAgent } = await import("./agents-2mgtTSeb.js");
|
|
718
724
|
await Effect.runPromise(stopAgent(agentId));
|
|
719
725
|
},
|
|
720
726
|
catch: () => void 0
|
|
721
727
|
}).pipe(Effect.ignore),
|
|
722
728
|
message: (agentId, msg) => Effect.tryPromise({
|
|
723
729
|
try: async () => {
|
|
724
|
-
const { messageAgent } = await import("./agents-
|
|
730
|
+
const { messageAgent } = await import("./agents-2mgtTSeb.js");
|
|
725
731
|
await messageAgent(agentId, msg);
|
|
726
732
|
},
|
|
727
733
|
catch: (err) => new AgentStartError({
|
|
@@ -732,8 +738,8 @@ const AgentSpawnerLive = Layer.effect(AgentSpawner, Effect.sync(() => ({
|
|
|
732
738
|
}),
|
|
733
739
|
deepWipe: (issueId, opts) => Effect.tryPromise({
|
|
734
740
|
try: async () => {
|
|
735
|
-
const { deepWipe } = await import("./workflows-
|
|
736
|
-
const { resolveProjectFromIssueSync } = await import("./projects-
|
|
741
|
+
const { deepWipe } = await import("./workflows-xeMCyhJE.js");
|
|
742
|
+
const { resolveProjectFromIssueSync } = await import("./projects-Daw2zpGk.js");
|
|
737
743
|
const project = resolveProjectFromIssueSync(issueId);
|
|
738
744
|
const projectPath = project?.projectPath ?? process.cwd();
|
|
739
745
|
await Effect.runPromise(deepWipe({
|
|
@@ -762,7 +768,7 @@ const AgentSpawnerLive = Layer.effect(AgentSpawner, Effect.sync(() => ({
|
|
|
762
768
|
* Route handlers and AgentSpawner use this instead of calling workspace-manager directly.
|
|
763
769
|
*/
|
|
764
770
|
init_typed_errors();
|
|
765
|
-
const execAsync$
|
|
771
|
+
const execAsync$11 = promisify(exec);
|
|
766
772
|
var WorkspaceService = class extends Context.Service()("overdeck/dashboard/WorkspaceService") {};
|
|
767
773
|
const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
|
|
768
774
|
function getWorkspacePath(issueId) {
|
|
@@ -789,8 +795,8 @@ const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
|
|
|
789
795
|
const { workspacePath, branch } = getWorkspacePath(issueId);
|
|
790
796
|
const issueLower = issueId.toLowerCase();
|
|
791
797
|
if (existsSync$1(workspacePath)) return workspacePath;
|
|
792
|
-
const { createWorkspace } = await import("./workspace-manager-
|
|
793
|
-
const { loadProjectsConfigSync } = await import("./projects-
|
|
798
|
+
const { createWorkspace } = await import("./workspace-manager-uVfFRWJG.js");
|
|
799
|
+
const { loadProjectsConfigSync } = await import("./projects-Daw2zpGk.js");
|
|
794
800
|
const { projects } = loadProjectsConfigSync();
|
|
795
801
|
const project = resolveProjectFromIssueSync(issueId);
|
|
796
802
|
if (!project) throw new WorkspaceCreateError({
|
|
@@ -825,7 +831,7 @@ const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
|
|
|
825
831
|
const { workspacePath } = getWorkspacePath(issueId);
|
|
826
832
|
const issueLower = issueId.toLowerCase();
|
|
827
833
|
if (!existsSync$1(workspacePath)) throw new WorkspaceNotFound({ id: issueId });
|
|
828
|
-
const { removeWorkspace } = await import("./workspace-manager-
|
|
834
|
+
const { removeWorkspace } = await import("./workspace-manager-uVfFRWJG.js");
|
|
829
835
|
const project = resolveProjectFromIssueSync(issueId);
|
|
830
836
|
if (!project) throw new WorkspaceCreateError({
|
|
831
837
|
id: issueId,
|
|
@@ -856,7 +862,7 @@ const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
|
|
|
856
862
|
try: async () => {
|
|
857
863
|
const { workspacePath } = getWorkspacePath(issueId);
|
|
858
864
|
const issueLower = issueId.toLowerCase();
|
|
859
|
-
const { stopWorkspaceDocker } = await import("./workspace-manager-
|
|
865
|
+
const { stopWorkspaceDocker } = await import("./workspace-manager-uVfFRWJG.js");
|
|
860
866
|
await Effect.runPromise(stopWorkspaceDocker(workspacePath, issueLower));
|
|
861
867
|
},
|
|
862
868
|
catch: () => void 0
|
|
@@ -925,7 +931,7 @@ const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
|
|
|
925
931
|
join$1(workspacePath, ".devcontainer", "docker-compose.devcontainer.yml")
|
|
926
932
|
];
|
|
927
933
|
if (!composePaths.find((p) => existsSync$1(p))) {
|
|
928
|
-
const { ensureDevcontainerSync } = await import("./ensure-devcontainer-
|
|
934
|
+
const { ensureDevcontainerSync } = await import("./ensure-devcontainer-BSPw9WeO.js");
|
|
929
935
|
const ensure = ensureDevcontainerSync({
|
|
930
936
|
workspacePath,
|
|
931
937
|
issueId
|
|
@@ -936,7 +942,7 @@ const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
|
|
|
936
942
|
});
|
|
937
943
|
}
|
|
938
944
|
const finalComposePath = composePaths.find((p) => existsSync$1(p));
|
|
939
|
-
if (finalComposePath) await execAsync$
|
|
945
|
+
if (finalComposePath) await execAsync$11(`docker compose -f "${finalComposePath}" up -d --build`, {
|
|
940
946
|
cwd: dirname$1(finalComposePath),
|
|
941
947
|
timeout: 3e5
|
|
942
948
|
});
|
|
@@ -1099,7 +1105,7 @@ function getDefaultCwd() {
|
|
|
1099
1105
|
//#endregion
|
|
1100
1106
|
//#region services/open.ts
|
|
1101
1107
|
init_src();
|
|
1102
|
-
const execAsync$
|
|
1108
|
+
const execAsync$10 = promisify(exec);
|
|
1103
1109
|
function getFileManagerCommand() {
|
|
1104
1110
|
switch (process.platform) {
|
|
1105
1111
|
case "linux": return "xdg-open";
|
|
@@ -1132,7 +1138,7 @@ function launchDetached(launch) {
|
|
|
1132
1138
|
}
|
|
1133
1139
|
async function isCommandAvailable(command) {
|
|
1134
1140
|
try {
|
|
1135
|
-
await execAsync$
|
|
1141
|
+
await execAsync$10(`${process.platform === "win32" ? "where" : "which"} ${command}`);
|
|
1136
1142
|
return true;
|
|
1137
1143
|
} catch {
|
|
1138
1144
|
return false;
|
|
@@ -15943,7 +15949,7 @@ var require_get_vercel_oidc_token = /* @__PURE__ */ __commonJSMin(((exports, mod
|
|
|
15943
15949
|
err = error;
|
|
15944
15950
|
}
|
|
15945
15951
|
try {
|
|
15946
|
-
const [{ getTokenPayload, isExpired }, { refreshToken }] = await Promise.all([await import("./token-util-
|
|
15952
|
+
const [{ getTokenPayload, isExpired }, { refreshToken }] = await Promise.all([await import("./token-util-xNaV-00f.js").then((m) => /* @__PURE__ */ __toESM(m.default)), await import("./token-CiS3w6Ma.js").then((m) => /* @__PURE__ */ __toESM(m.default))]);
|
|
15947
15953
|
if (!token || isExpired(getTokenPayload(token), options?.expirationBufferMs)) {
|
|
15948
15954
|
await refreshToken(options);
|
|
15949
15955
|
token = getVercelOidcTokenSync();
|
|
@@ -28260,7 +28266,7 @@ var GoogleCloudTranscription = class {
|
|
|
28260
28266
|
}
|
|
28261
28267
|
async start(apiKey, model) {
|
|
28262
28268
|
try {
|
|
28263
|
-
const { SpeechClient } = await import("./src-
|
|
28269
|
+
const { SpeechClient } = await import("./src-CNLON0co.js").then((m) => /* @__PURE__ */ __toESM(m.default, 1)).then((module) => module.v1p1beta1 ?? module.v1);
|
|
28264
28270
|
if (this.closed) return;
|
|
28265
28271
|
const stream = new SpeechClient({ apiKey }).streamingRecognize({
|
|
28266
28272
|
config: {
|
|
@@ -30043,7 +30049,7 @@ const websocketRpcRouteLayer = Layer.unwrap(Effect.gen(function* () {
|
|
|
30043
30049
|
//#endregion
|
|
30044
30050
|
//#region ../../lib/vbrief/quality-lint.ts
|
|
30045
30051
|
init_briefing_freshness();
|
|
30046
|
-
init_types
|
|
30052
|
+
init_types();
|
|
30047
30053
|
init_specs();
|
|
30048
30054
|
init_io();
|
|
30049
30055
|
init_pty_token();
|
|
@@ -30058,11 +30064,12 @@ init_pi_fifo();
|
|
|
30058
30064
|
init_launcher_generator();
|
|
30059
30065
|
init_bridge_token();
|
|
30060
30066
|
init_transcript_landing();
|
|
30067
|
+
init_state_home();
|
|
30061
30068
|
init_operator_interventions();
|
|
30062
30069
|
init_pan_dir();
|
|
30063
30070
|
init_agents$1();
|
|
30064
30071
|
init_remote_agents();
|
|
30065
|
-
init_types();
|
|
30072
|
+
init_types$1();
|
|
30066
30073
|
init_swarm_readiness();
|
|
30067
30074
|
var PlanQualityLintError = class extends Error {
|
|
30068
30075
|
constructor(issues) {
|
|
@@ -30492,7 +30499,7 @@ function isDiscoverableAgentSession(sessionName) {
|
|
|
30492
30499
|
async function loadTrackerIssues() {
|
|
30493
30500
|
const map = /* @__PURE__ */ new Map();
|
|
30494
30501
|
try {
|
|
30495
|
-
const { getSharedIssueService } = await import("./issue-service-singleton-
|
|
30502
|
+
const { getSharedIssueService } = await import("./issue-service-singleton-Cyfvop7U.js");
|
|
30496
30503
|
const issues = (await getSharedIssueService()).getIssues();
|
|
30497
30504
|
for (const issue of issues) if (issue.identifier) map.set(issue.identifier.toUpperCase(), issue);
|
|
30498
30505
|
} catch {
|
|
@@ -30691,7 +30698,7 @@ async function computeResourceAllocatedIssues() {
|
|
|
30691
30698
|
if (!issue.resourceDetails.tmuxSessions.includes(sessionName)) issue.resourceDetails.tmuxSessions.push(sessionName);
|
|
30692
30699
|
}
|
|
30693
30700
|
try {
|
|
30694
|
-
const { listActiveRemoteAgentStates } = await import("./remote-agents-
|
|
30701
|
+
const { listActiveRemoteAgentStates } = await import("./remote-agents-YROPFM-n.js");
|
|
30695
30702
|
for (const remoteState of listActiveRemoteAgentStates()) {
|
|
30696
30703
|
const issue = ensureIssue(remoteState.issueId);
|
|
30697
30704
|
if (!issue) continue;
|
|
@@ -31212,8 +31219,10 @@ function isGitHubIssue$5(issueId) {
|
|
|
31212
31219
|
return { isGitHub: false };
|
|
31213
31220
|
}
|
|
31214
31221
|
const completePlanningGuard = createInFlightGuard();
|
|
31215
|
-
|
|
31222
|
+
const completePlanningAutoSpawnIntent = /* @__PURE__ */ new Set();
|
|
31223
|
+
function beginCompletePlanningLease(issueId, autoSpawnRequested = false) {
|
|
31216
31224
|
const key = issueId.toLowerCase();
|
|
31225
|
+
if (autoSpawnRequested) completePlanningAutoSpawnIntent.add(key);
|
|
31217
31226
|
let release;
|
|
31218
31227
|
const lease = new Promise((resolve) => {
|
|
31219
31228
|
release = resolve;
|
|
@@ -31221,7 +31230,11 @@ function beginCompletePlanningLease(issueId) {
|
|
|
31221
31230
|
const started = completePlanningGuard.run(key, () => lease);
|
|
31222
31231
|
return {
|
|
31223
31232
|
started,
|
|
31224
|
-
|
|
31233
|
+
autoSpawnRequested: () => completePlanningAutoSpawnIntent.has(key),
|
|
31234
|
+
release: started ? () => {
|
|
31235
|
+
completePlanningAutoSpawnIntent.delete(key);
|
|
31236
|
+
release();
|
|
31237
|
+
} : () => void 0
|
|
31225
31238
|
};
|
|
31226
31239
|
}
|
|
31227
31240
|
function emitCompletePlanningPhase(issueId, phase, status, reason, details = {}) {
|
|
@@ -31254,7 +31267,7 @@ async function completePlanningArtifacts(options) {
|
|
|
31254
31267
|
if (workspaceIssueId && workspaceIssueId.toLowerCase() !== issueLower) throw new Error(`Workspace vBRIEF is for ${workspaceIssueId.toUpperCase()}, not ${upperIssueId}`);
|
|
31255
31268
|
assertPlanQuality(workspaceDoc);
|
|
31256
31269
|
const createBeads = options.createBeads ?? (async (path) => {
|
|
31257
|
-
const mod = await import("./beads-
|
|
31270
|
+
const mod = await import("./beads-CuXF6X4l.js");
|
|
31258
31271
|
return await Effect.runPromise(mod.createBeadsFromVBrief(path));
|
|
31259
31272
|
});
|
|
31260
31273
|
emitCompletePlanningPhase(upperIssueId, "specWrite", "start", "writing proposed vBRIEF spec", { projectPath });
|
|
@@ -31312,15 +31325,16 @@ async function completePlanningArtifacts(options) {
|
|
|
31312
31325
|
beadsWarning: null
|
|
31313
31326
|
};
|
|
31314
31327
|
}
|
|
31315
|
-
function completePlanningFilesToStage(projectPath, proposedFilename) {
|
|
31316
|
-
const filesToStage = [`.pan/specs/${proposedFilename}`];
|
|
31317
|
-
if (existsSync$1(join$1(projectPath, ".
|
|
31328
|
+
function completePlanningFilesToStage(projectPath, proposedFilename, migrated = false) {
|
|
31329
|
+
const filesToStage = migrated ? [] : [`.pan/specs/${proposedFilename}`];
|
|
31330
|
+
if (existsSync$1(join$1(projectPath, ".overdeck", "context", "codebase"))) filesToStage.push(".overdeck/context/codebase/");
|
|
31331
|
+
else if (!migrated && existsSync$1(join$1(projectPath, ".pan", "context", "codebase"))) filesToStage.push(".pan/context/codebase/");
|
|
31318
31332
|
return filesToStage;
|
|
31319
31333
|
}
|
|
31320
|
-
function completePlanningWorkspaceGitAddCommands(gitRoot) {
|
|
31334
|
+
function completePlanningWorkspaceGitAddCommands(gitRoot, migrated = false) {
|
|
31321
31335
|
const commands = [];
|
|
31322
|
-
if (existsSync$1(join$1(gitRoot, ".pan"))) commands.push(["add", ".pan/"]);
|
|
31323
|
-
if (existsSync$1(join$1(gitRoot, ".beads"))) commands.push(["add", ".beads/"]);
|
|
31336
|
+
if (!migrated && existsSync$1(join$1(gitRoot, ".pan"))) commands.push(["add", ".pan/"]);
|
|
31337
|
+
if (!migrated && existsSync$1(join$1(gitRoot, ".beads"))) commands.push(["add", ".beads/"]);
|
|
31324
31338
|
if (existsSync$1(join$1(gitRoot, ".gitignore"))) commands.push(["add", ".gitignore"]);
|
|
31325
31339
|
return commands;
|
|
31326
31340
|
}
|
|
@@ -31333,6 +31347,11 @@ function completePlanningWorkspaceGitAddCommands(gitRoot) {
|
|
|
31333
31347
|
* tree handed to auto-start is clean.
|
|
31334
31348
|
*/
|
|
31335
31349
|
async function commitWorkspaceRecordBeforeAutoSpawn(gitRoot, issueId) {
|
|
31350
|
+
const project = findProjectByPathSync(gitRoot);
|
|
31351
|
+
if (project && await isStateMigrated(project)) {
|
|
31352
|
+
await Effect.runPromise(flushAutoCommits(project.path));
|
|
31353
|
+
return;
|
|
31354
|
+
}
|
|
31336
31355
|
if (!existsSync$1(join$1(gitRoot, ".git"))) return;
|
|
31337
31356
|
const issueLower = issueId.toLowerCase();
|
|
31338
31357
|
try {
|
|
@@ -31484,7 +31503,7 @@ async function completePlanningForIssue(options) {
|
|
|
31484
31503
|
}
|
|
31485
31504
|
const sessionName = `planning-${id.toLowerCase()}`;
|
|
31486
31505
|
const issueLower = id.toLowerCase();
|
|
31487
|
-
const completePlanningLease = beginCompletePlanningLease(id);
|
|
31506
|
+
const completePlanningLease = beginCompletePlanningLease(id, autoSpawn);
|
|
31488
31507
|
if (!completePlanningLease.started) {
|
|
31489
31508
|
console.log(`[complete-planning] ${id} already has an in-flight finalize; returning in-flight status`);
|
|
31490
31509
|
return jsonResponse({
|
|
@@ -31583,8 +31602,12 @@ async function completePlanningForIssue(options) {
|
|
|
31583
31602
|
});
|
|
31584
31603
|
console.log(`[complete-planning] Wrote pan spec to ${proposed.path}`);
|
|
31585
31604
|
console.log(`[complete-planning] Materialized ${beadCount} beads for ${upperIssueId}`);
|
|
31586
|
-
const
|
|
31587
|
-
|
|
31605
|
+
const project = findProjectByPathSync(projectPath);
|
|
31606
|
+
const migrated = project ? await isStateMigrated(project) : false;
|
|
31607
|
+
const filesToStage = completePlanningFilesToStage(projectPath, proposed.filename, migrated);
|
|
31608
|
+
const projectIsGitRepo = existsSync$1(join$1(projectPath, ".git"));
|
|
31609
|
+
if (migrated) await Effect.runPromise(flushAutoCommits(projectPath));
|
|
31610
|
+
else if (!projectIsGitRepo) console.log(`[complete-planning] Project root ${projectPath} is not a git repository (polyrepo) — pan spec updated on disk but not committed`);
|
|
31588
31611
|
else {
|
|
31589
31612
|
const { stdout: branchStdout } = await execFileAsync$12("git", [
|
|
31590
31613
|
"rev-parse",
|
|
@@ -31646,7 +31669,7 @@ async function completePlanningForIssue(options) {
|
|
|
31646
31669
|
cwd: gitRoot,
|
|
31647
31670
|
encoding: "utf-8"
|
|
31648
31671
|
});
|
|
31649
|
-
for (const args of completePlanningWorkspaceGitAddCommands(gitRoot)) await execFileAsync$12("git", args, {
|
|
31672
|
+
for (const args of completePlanningWorkspaceGitAddCommands(gitRoot, migrated)) await execFileAsync$12("git", args, {
|
|
31650
31673
|
cwd: gitRoot,
|
|
31651
31674
|
encoding: "utf-8"
|
|
31652
31675
|
});
|
|
@@ -31749,15 +31772,16 @@ async function completePlanningForIssue(options) {
|
|
|
31749
31772
|
source: "planning-agent",
|
|
31750
31773
|
eventType: "planning.complete"
|
|
31751
31774
|
});
|
|
31752
|
-
|
|
31775
|
+
const effectiveAutoSpawn = autoSpawn || completePlanningLease.autoSpawnRequested();
|
|
31776
|
+
if (effectiveAutoSpawn && workspacePath) await commitWorkspaceRecordBeforeAutoSpawn(workspacePath, id);
|
|
31753
31777
|
const autoSpawnResult = await completePlanningAutoSpawnAndKill({
|
|
31754
31778
|
issueId: id,
|
|
31755
|
-
autoSpawn,
|
|
31779
|
+
autoSpawn: effectiveAutoSpawn,
|
|
31756
31780
|
skipKill,
|
|
31757
31781
|
sessionName
|
|
31758
31782
|
});
|
|
31759
31783
|
emitCompletePlanningPhase(id, "terminal", "success", autoSpawnResult?.workAgentSpawned ? "planning complete and work agent spawn requested" : autoSpawnResult?.workAgentSkipReason ?? "planning complete", {
|
|
31760
|
-
autoSpawn,
|
|
31784
|
+
autoSpawn: effectiveAutoSpawn,
|
|
31761
31785
|
workAgentSpawned: autoSpawnResult?.workAgentSpawned ?? false,
|
|
31762
31786
|
workAgentSkipReason: autoSpawnResult?.workAgentSkipReason
|
|
31763
31787
|
});
|
|
@@ -31779,6 +31803,7 @@ async function completePlanningForIssue(options) {
|
|
|
31779
31803
|
init_review_status();
|
|
31780
31804
|
init_projects();
|
|
31781
31805
|
init_lifecycle_io();
|
|
31806
|
+
init_issue_closed();
|
|
31782
31807
|
async function reopenWorkspaceStatePromise(issueId, workspacePath, options = {}) {
|
|
31783
31808
|
const result = {
|
|
31784
31809
|
specialistStatesReset: false,
|
|
@@ -31849,7 +31874,7 @@ init_tracker_utils();
|
|
|
31849
31874
|
init_agents$1();
|
|
31850
31875
|
init_issue_id();
|
|
31851
31876
|
init_io();
|
|
31852
|
-
const execAsync$
|
|
31877
|
+
const execAsync$9 = promisify(exec);
|
|
31853
31878
|
const execFileAsync$11 = promisify(execFile);
|
|
31854
31879
|
function isGitHubIssue$4(issueId) {
|
|
31855
31880
|
const resolved = resolveGitHubIssueSync(issueId);
|
|
@@ -31921,7 +31946,7 @@ async function closeIssuePullRequest(issueId, reason = "Canceled via Overdeck")
|
|
|
31921
31946
|
timeout: 15e3
|
|
31922
31947
|
});
|
|
31923
31948
|
try {
|
|
31924
|
-
const { setReviewStatusSync } = await import("./review-status-
|
|
31949
|
+
const { setReviewStatusSync } = await import("./review-status-CGjyt4SK.js");
|
|
31925
31950
|
setReviewStatusSync(issueId.toUpperCase(), { prUrl: void 0 });
|
|
31926
31951
|
} catch {}
|
|
31927
31952
|
return [`Closed PR #${prNumber} on ${githubCheck.owner}/${githubCheck.repo}`];
|
|
@@ -31975,7 +32000,7 @@ async function runDestructiveIssueLifecycle(id, mode, opts = {}) {
|
|
|
31975
32000
|
const { ctx, projectConfig } = buildLifecycleContext(id, getIssueDataService$8().getIssueSource(id) ?? void 0);
|
|
31976
32001
|
const deleteWorkspace = opts.deleteWorkspace ?? true;
|
|
31977
32002
|
cleanupLog.push(...await closeIssuePullRequest(id, mode === "cancel" ? "Canceled via Overdeck" : "Reset to Todo via Overdeck"));
|
|
31978
|
-
const { resetToTodo, cancelIssueWorkflow } = await import("./lifecycle-
|
|
32003
|
+
const { resetToTodo, cancelIssueWorkflow } = await import("./lifecycle-DEkQYaAt.js");
|
|
31979
32004
|
const workflow = mode === "cancel" ? cancelIssueWorkflow : resetToTodo;
|
|
31980
32005
|
const result = await Effect.runPromise(workflow(ctx, {
|
|
31981
32006
|
deleteWorkspace,
|
|
@@ -31990,7 +32015,7 @@ async function runDestructiveIssueLifecycle(id, mode, opts = {}) {
|
|
|
31990
32015
|
}));
|
|
31991
32016
|
cleanupLog.push(...result.steps.flatMap((step) => step.details || [step.error].filter(Boolean)));
|
|
31992
32017
|
if (mode === "cancel") try {
|
|
31993
|
-
const { transitionVBriefOnMain } = await import("./lifecycle-io-
|
|
32018
|
+
const { transitionVBriefOnMain } = await import("./lifecycle-io-BB-r9Bl_.js");
|
|
31994
32019
|
const tx = await Effect.runPromise(transitionVBriefOnMain(ctx.projectPath, id, "cancelled", "cancelled", `scope: cancel ${id.toUpperCase()} vBRIEF`));
|
|
31995
32020
|
if (tx.moved) cleanupLog.push(`vBRIEF moved ${tx.fromDir} → cancelled`);
|
|
31996
32021
|
if (tx.committed) cleanupLog.push(`Committed vBRIEF cancellation on main`);
|
|
@@ -31998,8 +32023,8 @@ async function runDestructiveIssueLifecycle(id, mode, opts = {}) {
|
|
|
31998
32023
|
cleanupLog.push(`vBRIEF cancel transition failed (non-fatal): ${err?.message ?? err}`);
|
|
31999
32024
|
}
|
|
32000
32025
|
try {
|
|
32001
|
-
const { killAllReviewerSessions } = await import("./review-agent-
|
|
32002
|
-
const { resolveProjectFromIssueSync } = await import("./projects-
|
|
32026
|
+
const { killAllReviewerSessions } = await import("./review-agent-D0X_E1tF.js");
|
|
32027
|
+
const { resolveProjectFromIssueSync } = await import("./projects-Daw2zpGk.js");
|
|
32003
32028
|
const projectKey = resolveProjectFromIssueSync(id)?.projectKey;
|
|
32004
32029
|
if (projectKey) {
|
|
32005
32030
|
const { killed } = await Effect.runPromise(killAllReviewerSessions(projectKey, id.toUpperCase()));
|
|
@@ -32013,7 +32038,7 @@ async function runDestructiveIssueLifecycle(id, mode, opts = {}) {
|
|
|
32013
32038
|
cleanupLog.push("Cleared review status");
|
|
32014
32039
|
} catch {}
|
|
32015
32040
|
try {
|
|
32016
|
-
const { resetPostMergeState } = await import("./merge-agent-
|
|
32041
|
+
const { resetPostMergeState } = await import("./merge-agent-DzbCbjqg.js");
|
|
32017
32042
|
resetPostMergeState(id);
|
|
32018
32043
|
resetPostMergeState(id.toUpperCase());
|
|
32019
32044
|
cleanupLog.push("Cleared merge state");
|
|
@@ -32033,7 +32058,7 @@ function closeIssueTransition(options) {
|
|
|
32033
32058
|
const { issueId, body, eventStore } = options;
|
|
32034
32059
|
const { reason } = body;
|
|
32035
32060
|
const projectPath = getProjectPath$3(void 0, extractPrefixSync(issueId) ?? issueId.split("-")[0]);
|
|
32036
|
-
const { close: closeWorkflow } = yield* Effect.promise(() => import("./lifecycle-
|
|
32061
|
+
const { close: closeWorkflow } = yield* Effect.promise(() => import("./lifecycle-DEkQYaAt.js"));
|
|
32037
32062
|
const githubCheck = isGitHubIssue$4(issueId);
|
|
32038
32063
|
const issueDataService = getIssueDataService$8();
|
|
32039
32064
|
const issueSource = issueDataService.getIssueSource(issueId);
|
|
@@ -32056,7 +32081,7 @@ function closeIssueTransition(options) {
|
|
|
32056
32081
|
};
|
|
32057
32082
|
}
|
|
32058
32083
|
const result = yield* closeWorkflow(ctx, { reason });
|
|
32059
|
-
if (githubCheck.isGitHub) execAsync$
|
|
32084
|
+
if (githubCheck.isGitHub) execAsync$9("pan sync", {
|
|
32060
32085
|
encoding: "utf-8",
|
|
32061
32086
|
timeout: 3e4
|
|
32062
32087
|
}).catch(() => {});
|
|
@@ -32267,13 +32292,13 @@ function reopenIssueTransition(options) {
|
|
|
32267
32292
|
}
|
|
32268
32293
|
yield* Effect.promise(async () => {
|
|
32269
32294
|
try {
|
|
32270
|
-
const { stdout } = await execAsync$
|
|
32295
|
+
const { stdout } = await execAsync$9(`gh pr list --head ${`feature/${id.toLowerCase()}`} --state closed --json number,mergedAt --limit 1`, {
|
|
32271
32296
|
encoding: "utf-8",
|
|
32272
32297
|
timeout: 15e3
|
|
32273
32298
|
});
|
|
32274
32299
|
const prs = JSON.parse(stdout.trim() || "[]");
|
|
32275
32300
|
if (prs.length > 0 && !prs[0].mergedAt) {
|
|
32276
|
-
await execAsync$
|
|
32301
|
+
await execAsync$9(`gh pr reopen ${prs[0].number}`, {
|
|
32277
32302
|
encoding: "utf-8",
|
|
32278
32303
|
timeout: 15e3
|
|
32279
32304
|
});
|
|
@@ -32300,7 +32325,7 @@ function reopenIssueTransition(options) {
|
|
|
32300
32325
|
else clearReviewStatus(id.toUpperCase());
|
|
32301
32326
|
} catch {}
|
|
32302
32327
|
try {
|
|
32303
|
-
const { resetPostMergeState } = await import("./merge-agent-
|
|
32328
|
+
const { resetPostMergeState } = await import("./merge-agent-DzbCbjqg.js");
|
|
32304
32329
|
resetPostMergeState(id);
|
|
32305
32330
|
resetPostMergeState(id.toUpperCase());
|
|
32306
32331
|
} catch {}
|
|
@@ -32320,7 +32345,7 @@ function reopenIssueTransition(options) {
|
|
|
32320
32345
|
const projectPath = (teamPrefix ? findProjectByTeamSync(teamPrefix) : null)?.path || "";
|
|
32321
32346
|
if (projectPath) {
|
|
32322
32347
|
const workspacePath = join$1(projectPath, "workspaces", `feature-${issueLower}`);
|
|
32323
|
-
const { createBeadsFromVBrief } = await import("./beads-
|
|
32348
|
+
const { createBeadsFromVBrief } = await import("./beads-CuXF6X4l.js");
|
|
32324
32349
|
if (existsSync$1(workspacePath) && await Effect.runPromise(findPlan(workspacePath))) try {
|
|
32325
32350
|
const { stdout: bdCheck } = await Effect.runPromise(withBdMutex(() => Effect.promise(() => execFileAsync$11("bd", [
|
|
32326
32351
|
"list",
|
|
@@ -32397,7 +32422,7 @@ function moveIssueStatus(options) {
|
|
|
32397
32422
|
"done"
|
|
32398
32423
|
];
|
|
32399
32424
|
if (!targetStatus || !validStatuses.includes(targetStatus)) return jsonResponse({ error: `Invalid targetStatus. Must be one of: ${validStatuses.join(", ")}` }, { status: 400 });
|
|
32400
|
-
const { updateShadowState } = yield* Effect.promise(() => import("./shadow-state-
|
|
32425
|
+
const { updateShadowState } = yield* Effect.promise(() => import("./shadow-state-B5mlwqQI.js"));
|
|
32401
32426
|
const issueState = {
|
|
32402
32427
|
backlog: "open",
|
|
32403
32428
|
todo: "open",
|
|
@@ -32460,7 +32485,7 @@ function moveIssueStatus(options) {
|
|
|
32460
32485
|
init_issue_service_singleton();
|
|
32461
32486
|
init_issue_id();
|
|
32462
32487
|
init_agents$1();
|
|
32463
|
-
const execAsync$
|
|
32488
|
+
const execAsync$8 = promisify(exec);
|
|
32464
32489
|
function getIssueDataService$7() {
|
|
32465
32490
|
return getSharedIssueService();
|
|
32466
32491
|
}
|
|
@@ -32485,28 +32510,28 @@ async function cleanupWorkspaceForIssue(rawId, eventStore) {
|
|
|
32485
32510
|
if (projectRoot) {
|
|
32486
32511
|
const workspacePath = join$1(projectRoot, "workspaces", `feature-${issueLower}`);
|
|
32487
32512
|
try {
|
|
32488
|
-
if ((await execAsync$
|
|
32513
|
+
if ((await execAsync$8("git worktree list --porcelain", {
|
|
32489
32514
|
cwd: projectRoot,
|
|
32490
32515
|
encoding: "utf-8"
|
|
32491
32516
|
})).stdout.includes(workspacePath)) {
|
|
32492
|
-
await execAsync$
|
|
32517
|
+
await execAsync$8(`git worktree remove "${workspacePath}" --force`, {
|
|
32493
32518
|
cwd: projectRoot,
|
|
32494
32519
|
encoding: "utf-8"
|
|
32495
32520
|
});
|
|
32496
32521
|
cleanupLog.push(`Removed git worktree: ${workspacePath}`);
|
|
32497
32522
|
} else if (existsSync$1(workspacePath)) {
|
|
32498
|
-
await execAsync$
|
|
32523
|
+
await execAsync$8(`rm -rf "${workspacePath}"`, { encoding: "utf-8" });
|
|
32499
32524
|
cleanupLog.push(`Removed directory: ${workspacePath}`);
|
|
32500
32525
|
}
|
|
32501
32526
|
} catch {
|
|
32502
32527
|
if (existsSync$1(workspacePath)) {
|
|
32503
|
-
await execAsync$
|
|
32528
|
+
await execAsync$8(`rm -rf "${workspacePath}"`, { encoding: "utf-8" });
|
|
32504
32529
|
cleanupLog.push(`Removed directory: ${workspacePath}`);
|
|
32505
32530
|
}
|
|
32506
32531
|
}
|
|
32507
32532
|
const branchName = `feature/${issueLower}`;
|
|
32508
32533
|
try {
|
|
32509
|
-
await execAsync$
|
|
32534
|
+
await execAsync$8(`git branch -D "${branchName}" 2>/dev/null || true`, {
|
|
32510
32535
|
cwd: projectRoot,
|
|
32511
32536
|
encoding: "utf-8"
|
|
32512
32537
|
});
|
|
@@ -32515,7 +32540,7 @@ async function cleanupWorkspaceForIssue(rawId, eventStore) {
|
|
|
32515
32540
|
}
|
|
32516
32541
|
const agentDir = join$1(homedir$1(), ".overdeck", "agents", `agent-${issueLower}`);
|
|
32517
32542
|
if (existsSync$1(agentDir)) {
|
|
32518
|
-
await execAsync$
|
|
32543
|
+
await execAsync$8(`rm -rf "${agentDir}"`, { encoding: "utf-8" });
|
|
32519
32544
|
cleanupLog.push(`Removed agent state: ${agentDir}`);
|
|
32520
32545
|
}
|
|
32521
32546
|
await Effect.runPromise(eventStore.append({
|
|
@@ -32624,7 +32649,7 @@ async function copySettingsToWorkspace(id) {
|
|
|
32624
32649
|
success: false,
|
|
32625
32650
|
error: "Workspace not found"
|
|
32626
32651
|
}, { status: 404 });
|
|
32627
|
-
const { copyOverdeckSettingsToWorkspaceSync } = await import("./workspace-manager-
|
|
32652
|
+
const { copyOverdeckSettingsToWorkspaceSync } = await import("./workspace-manager-uVfFRWJG.js");
|
|
32628
32653
|
const result = copyOverdeckSettingsToWorkspaceSync(workspacePath);
|
|
32629
32654
|
return jsonResponse({
|
|
32630
32655
|
success: result.errors.length === 0 || result.copied.length > 0,
|
|
@@ -32634,6 +32659,8 @@ async function copySettingsToWorkspace(id) {
|
|
|
32634
32659
|
}
|
|
32635
32660
|
//#endregion
|
|
32636
32661
|
//#region ../../lib/overdeck/task-generation.ts
|
|
32662
|
+
init_shadow_state();
|
|
32663
|
+
init_github_app();
|
|
32637
32664
|
init_io();
|
|
32638
32665
|
function buildChildStoriesFromRally(children) {
|
|
32639
32666
|
return children.map((c) => ({
|
|
@@ -32657,7 +32684,7 @@ function generateTasksForIssue(id) {
|
|
|
32657
32684
|
success: false,
|
|
32658
32685
|
error: `No vBRIEF spec found on main for ${id} — run planning first.`
|
|
32659
32686
|
}, { status: 409 });
|
|
32660
|
-
const { createBeadsFromVBrief } = yield* Effect.promise(() => import("./beads-
|
|
32687
|
+
const { createBeadsFromVBrief } = yield* Effect.promise(() => import("./beads-CuXF6X4l.js"));
|
|
32661
32688
|
const result = yield* createBeadsFromVBrief(workspacePath);
|
|
32662
32689
|
if (!result.success || result.created.length === 0) {
|
|
32663
32690
|
const errors = result.errors.length > 0 ? result.errors : ["Beads creation produced no tasks"];
|
|
@@ -32687,7 +32714,7 @@ init_projects();
|
|
|
32687
32714
|
init_tracker_utils();
|
|
32688
32715
|
init_tmux();
|
|
32689
32716
|
init_typed_errors();
|
|
32690
|
-
const execAsync$
|
|
32717
|
+
const execAsync$7 = promisify(exec);
|
|
32691
32718
|
const execFileAsync$10 = promisify(execFile);
|
|
32692
32719
|
function getIssueDataService$6() {
|
|
32693
32720
|
return getSharedIssueService();
|
|
@@ -33097,10 +33124,10 @@ function restartFromPlan(options) {
|
|
|
33097
33124
|
});
|
|
33098
33125
|
const resetResult = yield* Effect.promise(async () => {
|
|
33099
33126
|
try {
|
|
33100
|
-
const { runGitResetHard } = await import("./dangerous-git-ops-
|
|
33127
|
+
const { runGitResetHard } = await import("./dangerous-git-ops-Pongxg2d.js");
|
|
33101
33128
|
async function findPlanningCommit(grep, label) {
|
|
33102
33129
|
try {
|
|
33103
|
-
const { stdout } = await execAsync$
|
|
33130
|
+
const { stdout } = await execAsync$7(`git log --grep="${grep.replace(/"/g, "\\\"")}" --format=%H -1`, {
|
|
33104
33131
|
cwd: workspacePath,
|
|
33105
33132
|
encoding: "utf-8",
|
|
33106
33133
|
timeout: 1e4
|
|
@@ -33116,7 +33143,7 @@ function restartFromPlan(options) {
|
|
|
33116
33143
|
}
|
|
33117
33144
|
const found = await findPlanningCommit(`Complete planning for ${id}`, "complete-planning message") ?? await findPlanningCommit(`chore: planning artifacts for ${id}`, "agent-start message") ?? await (async () => {
|
|
33118
33145
|
try {
|
|
33119
|
-
const { stdout } = await execAsync$
|
|
33146
|
+
const { stdout } = await execAsync$7(`git log --diff-filter=A --format=%H -1 -- .pan/spec.vbrief.json`, {
|
|
33120
33147
|
cwd: workspacePath,
|
|
33121
33148
|
encoding: "utf-8",
|
|
33122
33149
|
timeout: 1e4
|
|
@@ -33244,14 +33271,13 @@ function getPlanningState(id) {
|
|
|
33244
33271
|
//#endregion
|
|
33245
33272
|
//#region ../../lib/overdeck/discussions.ts
|
|
33246
33273
|
init_cost_sync();
|
|
33247
|
-
init_github_app();
|
|
33248
33274
|
init_pull_requests();
|
|
33249
33275
|
init_issue_id();
|
|
33250
33276
|
init_github_pr_lookup();
|
|
33251
33277
|
init_tracker_utils();
|
|
33252
33278
|
init_tracker_config();
|
|
33253
33279
|
init_pr_tab_cache();
|
|
33254
|
-
const execAsync$
|
|
33280
|
+
const execAsync$6 = promisify(exec);
|
|
33255
33281
|
function isGitHubIssue$2(issueId) {
|
|
33256
33282
|
const resolved = resolveGitHubIssueSync(issueId);
|
|
33257
33283
|
if (resolved.isGitHub) return {
|
|
@@ -33299,7 +33325,7 @@ async function fetchIssueDiscussions(issueId, deps = {}) {
|
|
|
33299
33325
|
if (githubCheck.isGitHub && githubCheck.owner && githubCheck.repo && githubCheck.number) {
|
|
33300
33326
|
const { owner, repo, number } = githubCheck;
|
|
33301
33327
|
try {
|
|
33302
|
-
const { stdout } = await execAsync$
|
|
33328
|
+
const { stdout } = await execAsync$6(`gh api "repos/${owner}/${repo}/issues/${number}/comments?per_page=100"`, {
|
|
33303
33329
|
encoding: "utf-8",
|
|
33304
33330
|
timeout: 15e3,
|
|
33305
33331
|
maxBuffer: 8 * 1024 * 1024
|
|
@@ -33362,7 +33388,7 @@ async function fetchIssueDiscussions(issueId, deps = {}) {
|
|
|
33362
33388
|
const collectedItems = [];
|
|
33363
33389
|
const prConversation = (async () => {
|
|
33364
33390
|
try {
|
|
33365
|
-
const { stdout } = await execAsync$
|
|
33391
|
+
const { stdout } = await execAsync$6(`gh api "repos/${prOwner}/${prRepo}/issues/${prNumber}/comments?per_page=100"`, {
|
|
33366
33392
|
encoding: "utf-8",
|
|
33367
33393
|
timeout: 15e3,
|
|
33368
33394
|
maxBuffer: 8 * 1024 * 1024
|
|
@@ -33383,7 +33409,7 @@ async function fetchIssueDiscussions(issueId, deps = {}) {
|
|
|
33383
33409
|
})();
|
|
33384
33410
|
const prReviews = (async () => {
|
|
33385
33411
|
try {
|
|
33386
|
-
const { stdout } = await execAsync$
|
|
33412
|
+
const { stdout } = await execAsync$6(`gh api "repos/${prOwner}/${prRepo}/pulls/${prNumber}/reviews?per_page=100"`, {
|
|
33387
33413
|
encoding: "utf-8",
|
|
33388
33414
|
timeout: 15e3,
|
|
33389
33415
|
maxBuffer: 8 * 1024 * 1024
|
|
@@ -33408,7 +33434,7 @@ async function fetchIssueDiscussions(issueId, deps = {}) {
|
|
|
33408
33434
|
})();
|
|
33409
33435
|
const prInlineComments = (async () => {
|
|
33410
33436
|
try {
|
|
33411
|
-
const { stdout } = await execAsync$
|
|
33437
|
+
const { stdout } = await execAsync$6(`gh api "repos/${prOwner}/${prRepo}/pulls/${prNumber}/comments?per_page=100"`, {
|
|
33412
33438
|
encoding: "utf-8",
|
|
33413
33439
|
timeout: 15e3,
|
|
33414
33440
|
maxBuffer: 8 * 1024 * 1024
|
|
@@ -33550,7 +33576,7 @@ function closeOutIssue(id) {
|
|
|
33550
33576
|
}
|
|
33551
33577
|
const closeOutResult = yield* Effect.promise(async () => {
|
|
33552
33578
|
try {
|
|
33553
|
-
const { closeOut } = await import("./lifecycle-
|
|
33579
|
+
const { closeOut } = await import("./lifecycle-DEkQYaAt.js");
|
|
33554
33580
|
return {
|
|
33555
33581
|
ok: true,
|
|
33556
33582
|
result: await Effect.runPromise(closeOut(ctx))
|
|
@@ -33636,7 +33662,7 @@ function bulkCloseOut(body) {
|
|
|
33636
33662
|
const invalidIds = issueIds.filter((id) => !isValidIssueId(id));
|
|
33637
33663
|
if (invalidIds.length > 0) return jsonResponse({ error: `Invalid issue ID format: ${invalidIds.join(", ")}` }, { status: 400 });
|
|
33638
33664
|
const eventStore = yield* EventStoreService;
|
|
33639
|
-
const { closeOut } = yield* Effect.promise(() => import("./lifecycle-
|
|
33665
|
+
const { closeOut } = yield* Effect.promise(() => import("./lifecycle-DEkQYaAt.js"));
|
|
33640
33666
|
const issueDataService = getIssueDataService$5();
|
|
33641
33667
|
const tasks = [];
|
|
33642
33668
|
const agentChecks = yield* withConcurrencyLimit(issueIds.map((id) => Effect.promise(async () => {
|
|
@@ -33832,8 +33858,8 @@ const getIssueShipLogRoute = HttpRouter.add("GET", "/api/issues/:id/ship-log", h
|
|
|
33832
33858
|
const id = (yield* HttpRouter.params)["id"] ?? "";
|
|
33833
33859
|
if (!parseIssueIdSync(id)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
|
|
33834
33860
|
return yield* Effect.promise(async () => {
|
|
33835
|
-
const { getShipLog } = await import("./ship-log-
|
|
33836
|
-
const { getReviewStatusSync } = await import("./review-status-
|
|
33861
|
+
const { getShipLog } = await import("./ship-log-B2EEH__n.js");
|
|
33862
|
+
const { getReviewStatusSync } = await import("./review-status-CGjyt4SK.js");
|
|
33837
33863
|
const log = getShipLog(id);
|
|
33838
33864
|
const rs = getReviewStatusSync(id);
|
|
33839
33865
|
return jsonResponse({
|
|
@@ -34785,27 +34811,6 @@ const getCloisterAgentsHealthRoute = HttpRouter.add("GET", "/api/cloister/agents
|
|
|
34785
34811
|
})));
|
|
34786
34812
|
const cloisterRouteLayer = Layer.mergeAll(getCloisterStatusRoute, postCloisterStartRoute, postCloisterStopRoute, postCloisterEmergencyStopRoute, postCloisterBrakeRoute, postCloisterResumeSpawnsRoute, getCloisterSpawnStatusRoute, getCloisterConfigRoute, putCloisterConfigRoute, getCloisterAgentsHealthRoute);
|
|
34787
34813
|
//#endregion
|
|
34788
|
-
//#region routes/resources/shared.ts
|
|
34789
|
-
init_docker_stats();
|
|
34790
|
-
function getCurrentDockerStats() {
|
|
34791
|
-
return [];
|
|
34792
|
-
}
|
|
34793
|
-
function getContainerHistory(containerId) {
|
|
34794
|
-
return {
|
|
34795
|
-
timestamps: [],
|
|
34796
|
-
cpuPercent: [],
|
|
34797
|
-
memoryPercent: []
|
|
34798
|
-
};
|
|
34799
|
-
}
|
|
34800
|
-
function formatUptime(startedAt) {
|
|
34801
|
-
const ms = Date.now() - new Date(startedAt).getTime();
|
|
34802
|
-
const h = Math.floor(ms / 36e5);
|
|
34803
|
-
const m = Math.floor(ms % 36e5 / 6e4);
|
|
34804
|
-
if (h >= 24) return `${Math.floor(h / 24)}d ${h % 24}h`;
|
|
34805
|
-
if (h > 0) return `${h}h ${m}m`;
|
|
34806
|
-
return `${m}m`;
|
|
34807
|
-
}
|
|
34808
|
-
//#endregion
|
|
34809
34814
|
//#region routes/resources/agents-stats.ts
|
|
34810
34815
|
init_agents$1();
|
|
34811
34816
|
init_cost_sync();
|
|
@@ -35405,7 +35410,7 @@ function computeAgentCounts(agents, fleet, nowMs) {
|
|
|
35405
35410
|
};
|
|
35406
35411
|
}
|
|
35407
35412
|
function getDefaultMemoryVitals() {
|
|
35408
|
-
const total = totalmem();
|
|
35413
|
+
const total = totalmem$1();
|
|
35409
35414
|
const available = freemem$1();
|
|
35410
35415
|
return {
|
|
35411
35416
|
usedBytes: Math.max(0, total - available),
|
|
@@ -35562,86 +35567,6 @@ function spawnGatePressure(decision) {
|
|
|
35562
35567
|
return 12;
|
|
35563
35568
|
}
|
|
35564
35569
|
//#endregion
|
|
35565
|
-
//#region routes/resources/stacks.ts
|
|
35566
|
-
init_review_status();
|
|
35567
|
-
let reviewStatusReader = (issueId) => getReviewStatusSync(issueId);
|
|
35568
|
-
function getResourceStacks(containers) {
|
|
35569
|
-
return buildResourceStacks(containers, reviewStatusesFor(containers));
|
|
35570
|
-
}
|
|
35571
|
-
function buildResourceStacks(containers, reviewStatuses = {}) {
|
|
35572
|
-
const groups = /* @__PURE__ */ new Map();
|
|
35573
|
-
for (const container of containers) {
|
|
35574
|
-
const key = composeProjectFor(container) ?? "unassigned";
|
|
35575
|
-
groups.set(key, [...groups.get(key) ?? [], container]);
|
|
35576
|
-
}
|
|
35577
|
-
return [...groups.entries()].map(([composeProject, services]) => {
|
|
35578
|
-
const issueId = issueIdFor$1(composeProject, services);
|
|
35579
|
-
const reviewStatus = issueId ? reviewStatuses[issueId] : void 0;
|
|
35580
|
-
return {
|
|
35581
|
-
id: issueId ?? composeProject,
|
|
35582
|
-
issueId,
|
|
35583
|
-
issueTitle: issueId ?? "Unassigned",
|
|
35584
|
-
composeProject,
|
|
35585
|
-
serviceCount: services.length,
|
|
35586
|
-
services,
|
|
35587
|
-
aggregates: {
|
|
35588
|
-
cpuPercent: roundOne(services.reduce((sum, service) => sum + (service.cpuPercent ?? 0), 0)),
|
|
35589
|
-
memoryBytes: services.reduce((sum, service) => sum + (service.memoryUsage ?? 0), 0),
|
|
35590
|
-
diskBytes: services.reduce((sum, service) => sum + (service.diskUsage ?? 0), 0)
|
|
35591
|
-
},
|
|
35592
|
-
phase: phaseFor(reviewStatus)
|
|
35593
|
-
};
|
|
35594
|
-
}).sort((a, b) => a.id.localeCompare(b.id));
|
|
35595
|
-
}
|
|
35596
|
-
function reviewStatusesFor(containers) {
|
|
35597
|
-
const issueIds = /* @__PURE__ */ new Set();
|
|
35598
|
-
const groups = /* @__PURE__ */ new Map();
|
|
35599
|
-
for (const container of containers) {
|
|
35600
|
-
const key = composeProjectFor(container) ?? "unassigned";
|
|
35601
|
-
groups.set(key, [...groups.get(key) ?? [], container]);
|
|
35602
|
-
}
|
|
35603
|
-
for (const [composeProject, services] of groups.entries()) {
|
|
35604
|
-
const issueId = issueIdFor$1(composeProject, services);
|
|
35605
|
-
if (issueId) issueIds.add(issueId);
|
|
35606
|
-
}
|
|
35607
|
-
const statuses = {};
|
|
35608
|
-
for (const issueId of issueIds) statuses[issueId] = reviewStatusReader(issueId) ?? void 0;
|
|
35609
|
-
return statuses;
|
|
35610
|
-
}
|
|
35611
|
-
function composeProjectFor(container) {
|
|
35612
|
-
const labelProject = container.labels?.["com.docker.compose.project"]?.trim();
|
|
35613
|
-
if (labelProject) return labelProject;
|
|
35614
|
-
const issueProject = container.name.match(/^(.+?feature[-_](?:pan|min|aur|krux)[-_]?\d+)/i);
|
|
35615
|
-
if (issueProject?.[1]) return issueProject[1];
|
|
35616
|
-
return container.name.match(/^(.+?)[_-][a-z0-9]+[._-][0-9]+$/i)?.[1] ?? null;
|
|
35617
|
-
}
|
|
35618
|
-
function issueIdFor$1(composeProject, services) {
|
|
35619
|
-
if (composeProject === "unassigned") return null;
|
|
35620
|
-
const fromProject = issueIdFromText(composeProject);
|
|
35621
|
-
if (fromProject) return fromProject;
|
|
35622
|
-
for (const service of services) {
|
|
35623
|
-
const fromLabels = issueIdFromText(Object.values(service.labels ?? {}).join(" "));
|
|
35624
|
-
if (fromLabels) return fromLabels;
|
|
35625
|
-
}
|
|
35626
|
-
return null;
|
|
35627
|
-
}
|
|
35628
|
-
function issueIdFromText(value) {
|
|
35629
|
-
const match = value.match(/(?:workspaces[\\/])?feature[-_](pan|min|aur|krux)[-_]?(\d+)/i) ?? value.match(/\b(pan|min|aur|krux)[-_]?(\d+)\b/i);
|
|
35630
|
-
if (!match) return null;
|
|
35631
|
-
return `${match[1].toUpperCase()}-${match[2]}`;
|
|
35632
|
-
}
|
|
35633
|
-
function phaseFor(status) {
|
|
35634
|
-
if (!status) return "todo";
|
|
35635
|
-
if (status.mergeStatus === "merged") return "merged";
|
|
35636
|
-
if (status.mergeStatus === "queued" || status.mergeStatus === "merging" || status.mergeStatus === "verifying" || status.mergeStatus === "failed" || status.readyForMerge === true) return "ship";
|
|
35637
|
-
if (status.verificationStatus === "running") return "verifying";
|
|
35638
|
-
if (status.reviewStatus === "reviewing" || status.reviewStatus === "passed" || status.reviewStatus === "failed" || status.reviewStatus === "blocked" || status.testStatus === "testing" || status.testStatus === "passed" || status.testStatus === "failed" || status.inspectStatus === "inspecting" || status.inspectStatus === "passed" || status.inspectStatus === "failed" || status.inspectStatus === "error") return "review";
|
|
35639
|
-
return "todo";
|
|
35640
|
-
}
|
|
35641
|
-
function roundOne(value) {
|
|
35642
|
-
return Math.round(value * 10) / 10;
|
|
35643
|
-
}
|
|
35644
|
-
//#endregion
|
|
35645
35570
|
//#region routes/resources/snapshot.ts
|
|
35646
35571
|
init_agents$1();
|
|
35647
35572
|
init_tmux();
|
|
@@ -36516,7 +36441,8 @@ const ROLE_NAMES = [
|
|
|
36516
36441
|
"ship",
|
|
36517
36442
|
"flywheel",
|
|
36518
36443
|
"strike",
|
|
36519
|
-
"sequencer"
|
|
36444
|
+
"sequencer",
|
|
36445
|
+
"knowledge"
|
|
36520
36446
|
];
|
|
36521
36447
|
const WORKHORSE_SLOTS = [
|
|
36522
36448
|
"expensive",
|
|
@@ -37245,17 +37171,20 @@ function getAvailableModelsApi() {
|
|
|
37245
37171
|
}
|
|
37246
37172
|
}
|
|
37247
37173
|
const openaiOrder = {
|
|
37248
|
-
"gpt-5.
|
|
37249
|
-
"gpt-5.
|
|
37250
|
-
"gpt-5.
|
|
37251
|
-
"gpt-5.
|
|
37252
|
-
"gpt-5.
|
|
37253
|
-
"gpt-5.
|
|
37254
|
-
"gpt-5.
|
|
37255
|
-
"
|
|
37256
|
-
"
|
|
37257
|
-
"gpt-
|
|
37258
|
-
"
|
|
37174
|
+
"gpt-5.6-sol": 0,
|
|
37175
|
+
"gpt-5.6-terra": 1,
|
|
37176
|
+
"gpt-5.6-luna": 2,
|
|
37177
|
+
"gpt-5.5": 10,
|
|
37178
|
+
"gpt-5.5-pro": 11,
|
|
37179
|
+
"gpt-5.4": 20,
|
|
37180
|
+
"gpt-5.4-pro": 21,
|
|
37181
|
+
"gpt-5.4-mini": 22,
|
|
37182
|
+
"gpt-5.3-codex": 30,
|
|
37183
|
+
"gpt-5.2": 40,
|
|
37184
|
+
"o3": 50,
|
|
37185
|
+
"o4-mini": 51,
|
|
37186
|
+
"gpt-4o": 60,
|
|
37187
|
+
"gpt-4o-mini": 61
|
|
37259
37188
|
};
|
|
37260
37189
|
result.openai.sort((a, b) => (openaiOrder[a.id] ?? 99) - (openaiOrder[b.id] ?? 99));
|
|
37261
37190
|
return result;
|
|
@@ -37623,7 +37552,7 @@ init_linear_client();
|
|
|
37623
37552
|
init_config_yaml();
|
|
37624
37553
|
init_issue_service_singleton();
|
|
37625
37554
|
init_io();
|
|
37626
|
-
const execAsync$
|
|
37555
|
+
const execAsync$5 = promisify(exec);
|
|
37627
37556
|
const execFileAsync$4 = promisify(execFile);
|
|
37628
37557
|
function getIssueDataService$3() {
|
|
37629
37558
|
return getSharedIssueService();
|
|
@@ -37724,16 +37653,21 @@ async function fetchActivityDataWithContext(issueId, context = {}) {
|
|
|
37724
37653
|
const workspacePath = join$1(projectPath, "workspaces", `feature-${issueLower}`);
|
|
37725
37654
|
const agentId = `agent-${issueLower}`;
|
|
37726
37655
|
const planningAgentId = `planning-${issueLower}`;
|
|
37656
|
+
const knowledgeAgentId = `agent-${issueLower}-knowledge`;
|
|
37727
37657
|
const agentsDir = join$1(homedir$1(), ".overdeck", "agents");
|
|
37728
37658
|
let hasPlanningSection = false;
|
|
37729
|
-
for (const checkId of [
|
|
37659
|
+
for (const checkId of [
|
|
37660
|
+
planningAgentId,
|
|
37661
|
+
agentId,
|
|
37662
|
+
knowledgeAgentId
|
|
37663
|
+
]) {
|
|
37730
37664
|
const agentDir = join$1(agentsDir, checkId);
|
|
37731
37665
|
if (!await pathExists$4(agentDir)) continue;
|
|
37732
37666
|
const state = getAgentStateSync(checkId);
|
|
37733
37667
|
if (!state) continue;
|
|
37734
37668
|
try {
|
|
37735
37669
|
const isPlanning = checkId.startsWith("planning-");
|
|
37736
|
-
const sectionType = isPlanning ? "planning" : "work";
|
|
37670
|
+
const sectionType = isPlanning ? "planning" : checkId.endsWith("-knowledge") ? "knowledge" : "work";
|
|
37737
37671
|
if (isPlanning) hasPlanningSection = true;
|
|
37738
37672
|
let transcript = "";
|
|
37739
37673
|
let transcriptFromPane = false;
|
|
@@ -38161,7 +38095,7 @@ async function fetchPlanningData(issueId, options = {}) {
|
|
|
38161
38095
|
const cached = stashCountCache.get(cacheKey);
|
|
38162
38096
|
if (cached && cached.timestamp > Date.now() - STASH_COUNT_CACHE_TTL_MS) result.stashCount = cached.count;
|
|
38163
38097
|
else {
|
|
38164
|
-
const { stdout: stashList } = await execAsync$
|
|
38098
|
+
const { stdout: stashList } = await execAsync$5("git stash list", {
|
|
38165
38099
|
cwd: workspacePath,
|
|
38166
38100
|
encoding: "utf-8"
|
|
38167
38101
|
});
|
|
@@ -38249,7 +38183,7 @@ async function generateStatusReview(issueId) {
|
|
|
38249
38183
|
};
|
|
38250
38184
|
const execSafe = async (cmd, opts) => {
|
|
38251
38185
|
try {
|
|
38252
|
-
const { stdout } = await execAsync$
|
|
38186
|
+
const { stdout } = await execAsync$5(cmd, {
|
|
38253
38187
|
encoding: "utf-8",
|
|
38254
38188
|
timeout: 1e4,
|
|
38255
38189
|
...opts
|
|
@@ -38351,7 +38285,7 @@ Be specific: reference actual file names, function names, requirement text, disc
|
|
|
38351
38285
|
const { command: cliCmd, args: cliArgs } = getAgentCommandSync(statusModelId);
|
|
38352
38286
|
const modelFlag = cliArgs.length > 0 ? ` ${cliArgs.join(" ")}` : "";
|
|
38353
38287
|
const promptFile = join$1(planningDir, ".status-review-prompt.tmp");
|
|
38354
|
-
const { getProviderForModelSync, getProviderEnvSync } = await import("./providers-
|
|
38288
|
+
const { getProviderForModelSync, getProviderEnvSync } = await import("./providers-pkuT25pY.js");
|
|
38355
38289
|
let providerEnvStr = "";
|
|
38356
38290
|
let providerEnv = {};
|
|
38357
38291
|
const statusProvider = getProviderForModelSync(statusModelId);
|
|
@@ -38368,7 +38302,7 @@ Be specific: reference actual file names, function names, requirement text, disc
|
|
|
38368
38302
|
try {
|
|
38369
38303
|
const env = buildChildEnvSync(process.env, providerEnv);
|
|
38370
38304
|
const promptContent = await readFile(promptFile, "utf-8");
|
|
38371
|
-
const { stdout: aiReview } = await execAsync$
|
|
38305
|
+
const { stdout: aiReview } = await execAsync$5(`${cliCmd} -p${modelFlag} --no-session-persistence`, {
|
|
38372
38306
|
encoding: "utf-8",
|
|
38373
38307
|
timeout: 12e4,
|
|
38374
38308
|
maxBuffer: 1024 * 1024,
|
|
@@ -38434,7 +38368,7 @@ const postMissionControlUploadRoute = HttpRouter.add("POST", "/api/command-deck/
|
|
|
38434
38368
|
let safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "-");
|
|
38435
38369
|
let processedContent = content;
|
|
38436
38370
|
if (safeName.endsWith(".vtt")) {
|
|
38437
|
-
const { vttToMarkdown } = yield* Effect.promise(() => import("./vtt-parser-
|
|
38371
|
+
const { vttToMarkdown } = yield* Effect.promise(() => import("./vtt-parser-D-q5-8il.js"));
|
|
38438
38372
|
processedContent = vttToMarkdown(content);
|
|
38439
38373
|
safeName = safeName.replace(/\.vtt$/, ".md");
|
|
38440
38374
|
}
|
|
@@ -42919,6 +42853,9 @@ const readJsonBody$10 = Effect.gen(function* () {
|
|
|
42919
42853
|
});
|
|
42920
42854
|
/** Model ID to API model ID mapping */
|
|
42921
42855
|
const MODEL_API_IDS = {
|
|
42856
|
+
"gpt-5.6-sol": { apiModel: "gpt-5.6-sol" },
|
|
42857
|
+
"gpt-5.6-terra": { apiModel: "gpt-5.6-terra" },
|
|
42858
|
+
"gpt-5.6-luna": { apiModel: "gpt-5.6-luna" },
|
|
42922
42859
|
"gpt-5.5-pro": { apiModel: "gpt-5.5-pro" },
|
|
42923
42860
|
"gpt-5.5": { apiModel: "gpt-5.5" },
|
|
42924
42861
|
"gpt-5.4-pro": { apiModel: "gpt-5.4-pro" },
|
|
@@ -44245,7 +44182,7 @@ const postRallyValidateRoute = HttpRouter.add("POST", "/api/rally/validate", Eff
|
|
|
44245
44182
|
}, { status: 400 });
|
|
44246
44183
|
return yield* Effect.promise(async () => {
|
|
44247
44184
|
try {
|
|
44248
|
-
const { RallyRestApi } = await import("./rally-api-
|
|
44185
|
+
const { RallyRestApi } = await import("./rally-api-DE3UOdHw.js");
|
|
44249
44186
|
const api = new RallyRestApi({
|
|
44250
44187
|
apiKey,
|
|
44251
44188
|
server: server || "https://rally1.rallydev.com"
|
|
@@ -44541,7 +44478,7 @@ const deaconRouteLayer = Layer.mergeAll(getNoResumeModeRoute, postResumeAllRoute
|
|
|
44541
44478
|
//#region routes/misc/planning.ts
|
|
44542
44479
|
init_config_yaml();
|
|
44543
44480
|
init_issue_id();
|
|
44544
|
-
init_types
|
|
44481
|
+
init_types();
|
|
44545
44482
|
init_projects();
|
|
44546
44483
|
init_remote_agents();
|
|
44547
44484
|
init_tmux();
|
|
@@ -44573,7 +44510,7 @@ const getPlanningStatusRoute = HttpRouter.add("GET", "/api/planning/:issueId/sta
|
|
|
44573
44510
|
const remoteState = loadRemoteAgentState(sessionName);
|
|
44574
44511
|
const isRemote = !!remoteState;
|
|
44575
44512
|
const vmName = remoteState?.vmName ?? "";
|
|
44576
|
-
const { getAgentStateSync } = await import("./agents-
|
|
44513
|
+
const { getAgentStateSync } = await import("./agents-2mgtTSeb.js");
|
|
44577
44514
|
const agentStarting = getAgentStateSync(sessionName)?.status === "starting";
|
|
44578
44515
|
let tmuxSessionAlive = false;
|
|
44579
44516
|
if (!isRemote) try {
|
|
@@ -44716,7 +44653,7 @@ Continue the PLANNING session. Do NOT implement anything.
|
|
|
44716
44653
|
`);
|
|
44717
44654
|
const agentCwd = workspacePath;
|
|
44718
44655
|
if (existsSync$1(outputFile)) await rename(outputFile, join$1(planningDir, `output-${Date.now()}.jsonl`));
|
|
44719
|
-
const { getAgentCommandSync } = await import("./settings-
|
|
44656
|
+
const { getAgentCommandSync } = await import("./settings-B27w9z21.js");
|
|
44720
44657
|
let msgPlanningModel = "claude-sonnet-5";
|
|
44721
44658
|
try {
|
|
44722
44659
|
msgPlanningModel = resolveModel("plan", void 0, loadConfigSync().config);
|
|
@@ -44837,7 +44774,7 @@ async function getIndexStats(rootPath, isMain) {
|
|
|
44837
44774
|
}
|
|
44838
44775
|
const getTldrStatusRoute = HttpRouter.add("GET", "/api/services/tldr/status", Effect.promise(async () => {
|
|
44839
44776
|
try {
|
|
44840
|
-
const { getTldrDaemonServiceSync } = await import("./tldr-daemon-
|
|
44777
|
+
const { getTldrDaemonServiceSync } = await import("./tldr-daemon-DkRIsKUT.js");
|
|
44841
44778
|
const projectRoot = process.cwd();
|
|
44842
44779
|
const venvPath = join$1(projectRoot, ".venv");
|
|
44843
44780
|
const results = [];
|
|
@@ -44882,7 +44819,7 @@ const getTldrStatusRoute = HttpRouter.add("GET", "/api/services/tldr/status", Ef
|
|
|
44882
44819
|
}));
|
|
44883
44820
|
const postTldrStartRoute = HttpRouter.add("POST", "/api/services/tldr/start", Effect.promise(async () => {
|
|
44884
44821
|
try {
|
|
44885
|
-
const { getTldrDaemonServiceSync } = await import("./tldr-daemon-
|
|
44822
|
+
const { getTldrDaemonServiceSync } = await import("./tldr-daemon-DkRIsKUT.js");
|
|
44886
44823
|
const projectRoot = process.cwd();
|
|
44887
44824
|
const venvPath = join$1(projectRoot, ".venv");
|
|
44888
44825
|
if (!existsSync$1(venvPath)) return jsonResponse({ error: "No .venv found in project root" }, { status: 404 });
|
|
@@ -44899,7 +44836,7 @@ const postTldrStartRoute = HttpRouter.add("POST", "/api/services/tldr/start", Ef
|
|
|
44899
44836
|
}));
|
|
44900
44837
|
const postTldrStopRoute = HttpRouter.add("POST", "/api/services/tldr/stop", Effect.promise(async () => {
|
|
44901
44838
|
try {
|
|
44902
|
-
const { getTldrDaemonServiceSync } = await import("./tldr-daemon-
|
|
44839
|
+
const { getTldrDaemonServiceSync } = await import("./tldr-daemon-DkRIsKUT.js");
|
|
44903
44840
|
const projectRoot = process.cwd();
|
|
44904
44841
|
const venvPath = join$1(projectRoot, ".venv");
|
|
44905
44842
|
if (!existsSync$1(venvPath)) return jsonResponse({ error: "No .venv found in project root" }, { status: 404 });
|
|
@@ -44916,7 +44853,7 @@ const postTldrStopRoute = HttpRouter.add("POST", "/api/services/tldr/stop", Effe
|
|
|
44916
44853
|
}));
|
|
44917
44854
|
const postTldrReloadRoute = HttpRouter.add("POST", "/api/services/tldr/reload", Effect.promise(async () => {
|
|
44918
44855
|
try {
|
|
44919
|
-
const { getTldrDaemonServiceSync } = await import("./tldr-daemon-
|
|
44856
|
+
const { getTldrDaemonServiceSync } = await import("./tldr-daemon-DkRIsKUT.js");
|
|
44920
44857
|
const enabled = isTldrEnabledSync();
|
|
44921
44858
|
const projectRoot = process.cwd();
|
|
44922
44859
|
const targets = [];
|
|
@@ -44968,7 +44905,7 @@ init_tracker_config();
|
|
|
44968
44905
|
init_issue_id();
|
|
44969
44906
|
init_projects();
|
|
44970
44907
|
init_tmux();
|
|
44971
|
-
const execAsync$
|
|
44908
|
+
const execAsync$4 = promisify(exec);
|
|
44972
44909
|
function getIssueDataService$1() {
|
|
44973
44910
|
const { getSharedIssueService } = (init_issue_service_singleton(), __toCommonJS(issue_service_singleton_exports));
|
|
44974
44911
|
return getSharedIssueService();
|
|
@@ -44992,7 +44929,7 @@ const getVersionRoute = HttpRouter.add("GET", "/api/version", Effect.promise(asy
|
|
|
44992
44929
|
const version = await getOverdeckVersion();
|
|
44993
44930
|
let supervisorUrl = null;
|
|
44994
44931
|
try {
|
|
44995
|
-
const { getSupervisorUrlSync } = await import("./supervisor-
|
|
44932
|
+
const { getSupervisorUrlSync } = await import("./supervisor-BzxM2EIo.js");
|
|
44996
44933
|
supervisorUrl = getSupervisorUrlSync();
|
|
44997
44934
|
} catch {}
|
|
44998
44935
|
return jsonResponse({
|
|
@@ -45156,7 +45093,7 @@ const postShadowMonitorRoute = HttpRouter.add("POST", "/api/shadow/:issueId/moni
|
|
|
45156
45093
|
const projectPath = await getProjectPath(issuePrefix);
|
|
45157
45094
|
const workspacePath = join$1(projectPath, "workspaces", `feature-${issueLower}`);
|
|
45158
45095
|
if (!existsSync$1(workspacePath)) return jsonResponse({ error: "Workspace not found" }, { status: 404 });
|
|
45159
|
-
const { gatherArtifacts, generateBasicInference, updateInferenceDocumentSync } = await import("./shadow-engineering-
|
|
45096
|
+
const { gatherArtifacts, generateBasicInference, updateInferenceDocumentSync } = await import("./shadow-engineering-C1DS3IT9.js");
|
|
45160
45097
|
const config = {
|
|
45161
45098
|
issueId,
|
|
45162
45099
|
workspacePath,
|
|
@@ -45186,7 +45123,7 @@ const postShadowObserveRoute = HttpRouter.add("POST", "/api/shadow/:issueId/obse
|
|
|
45186
45123
|
if (!existsSync$1(workspacePath)) return jsonResponse({ error: "Workspace not found" }, { status: 404 });
|
|
45187
45124
|
const ghConfig = getGitHubConfig();
|
|
45188
45125
|
if (!ghConfig) return jsonResponse({ error: "GitHub not configured - Observer requires GitHub" }, { status: 400 });
|
|
45189
|
-
const { runObserverCycle } = await import("./shadow-engineering-
|
|
45126
|
+
const { runObserverCycle } = await import("./shadow-engineering-C1DS3IT9.js");
|
|
45190
45127
|
const firstRepo = ghConfig.repos[0];
|
|
45191
45128
|
const config = {
|
|
45192
45129
|
issueId,
|
|
@@ -45218,7 +45155,7 @@ const postDevRebuildRoute = HttpRouter.add("POST", "/api/dev/rebuild", Effect.ge
|
|
|
45218
45155
|
if (!overdeckDevMode || !overdeckProjectRoot) return jsonResponse({ error: "Rebuild only available in dev mode" }, { status: 403 });
|
|
45219
45156
|
return yield* Effect.promise(async () => {
|
|
45220
45157
|
try {
|
|
45221
|
-
const { stdout, stderr } = await execAsync$
|
|
45158
|
+
const { stdout, stderr } = await execAsync$4("npm run build", {
|
|
45222
45159
|
cwd: overdeckProjectRoot,
|
|
45223
45160
|
timeout: 12e4
|
|
45224
45161
|
});
|
|
@@ -46251,7 +46188,7 @@ async function cleanupConversationAttachments(name) {
|
|
|
46251
46188
|
* sessions that the lifecycle poller missed. */
|
|
46252
46189
|
async function cleanupOrphanedConversationAttachments() {
|
|
46253
46190
|
try {
|
|
46254
|
-
const { listConversations } = await import("./conversations-
|
|
46191
|
+
const { listConversations } = await import("./conversations-CucKmkR7.js");
|
|
46255
46192
|
const convNames = new Set(listConversations().map((c) => c.name));
|
|
46256
46193
|
const root = getConversationAttachmentsRoot();
|
|
46257
46194
|
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, {
|
|
@@ -46730,7 +46667,7 @@ init_layers();
|
|
|
46730
46667
|
init_briefing_freshness();
|
|
46731
46668
|
init_paths();
|
|
46732
46669
|
init_event_store();
|
|
46733
|
-
const execAsync$
|
|
46670
|
+
const execAsync$3 = promisify(exec);
|
|
46734
46671
|
const execFileAsync$2 = promisify(execFile);
|
|
46735
46672
|
const PROCESS_CLEANUP_GRACE_MS = 750;
|
|
46736
46673
|
const PTY_SUPERVISOR_SOCKET_WAIT_MS = 3e4;
|
|
@@ -46838,7 +46775,7 @@ async function resolveAllowedHarness(requested, model) {
|
|
|
46838
46775
|
}
|
|
46839
46776
|
async function isInsideGitWorkTree(dir) {
|
|
46840
46777
|
try {
|
|
46841
|
-
const { stdout } = await execAsync$
|
|
46778
|
+
const { stdout } = await execAsync$3("git rev-parse --is-inside-work-tree", {
|
|
46842
46779
|
cwd: dir,
|
|
46843
46780
|
encoding: "utf-8"
|
|
46844
46781
|
});
|
|
@@ -46871,9 +46808,9 @@ async function waitForClaudeReady(tmuxSession) {
|
|
|
46871
46808
|
console.warn(`[conversations] Timed out waiting for Claude Code prompt in ${tmuxSession}`);
|
|
46872
46809
|
}
|
|
46873
46810
|
function isPiTuiInputReady(snapshot) {
|
|
46874
|
-
return /^\s*[❯›>]\s/m.test(snapshot) || /(?:^|\s)0(?:\.\d+)?%\s+context\s+used\b/i.test(snapshot);
|
|
46811
|
+
return /^\s*[❯›>]\s/m.test(snapshot) || /(?:^|\s)0(?:\.\d+)?%\s+context\s+used\b/i.test(snapshot) || /⬢[^\n]*◕/.test(snapshot);
|
|
46875
46812
|
}
|
|
46876
|
-
async function waitForPiTuiReady(tmuxSession, timeoutMs =
|
|
46813
|
+
async function waitForPiTuiReady(tmuxSession, timeoutMs = 6e4) {
|
|
46877
46814
|
const deadline = Date.now() + timeoutMs;
|
|
46878
46815
|
while (Date.now() < deadline) {
|
|
46879
46816
|
if (isPiTuiInputReady(await Effect.runPromise(capturePane(tmuxSession, 40).pipe(Effect.catch(() => Effect.succeed("")))))) {
|
|
@@ -46915,8 +46852,9 @@ function shouldUseSupervisorForConversation(harness) {
|
|
|
46915
46852
|
}
|
|
46916
46853
|
async function waitForConversationRuntimeReady(tmuxSession, harness, mode) {
|
|
46917
46854
|
const transcriptKind = getHarnessBehavior(harness).transcriptKind;
|
|
46918
|
-
if (transcriptKind === "ohmypi-jsonl")
|
|
46919
|
-
|
|
46855
|
+
if (transcriptKind === "ohmypi-jsonl") {
|
|
46856
|
+
if (!await waitForPiTuiReady(tmuxSession)) throw new Error(`Pi (ohmypi) did not become interactive in ${tmuxSession} within the startup window — MCP server connections are likely still in progress. Retry once MCP servers finish connecting, or check ~/.claude/mcp.json for a slow/hanging server.`);
|
|
46857
|
+
} else if (transcriptKind !== "codex-rollout-jsonl" && mode === "spawn") {
|
|
46920
46858
|
await waitForClaudeReady(tmuxSession);
|
|
46921
46859
|
console.log(`[conversations] Claude ready in ${tmuxSession}`);
|
|
46922
46860
|
} else if (transcriptKind !== "codex-rollout-jsonl") await waitForReadySignal(tmuxSession, 30);
|
|
@@ -47119,7 +47057,7 @@ async function spawnConversationSession(tmuxSession, cwd, claudeSessionId, model
|
|
|
47119
47057
|
const codexApprovalPolicy = codexPermMode === "full-access" ? "never" : "on-request";
|
|
47120
47058
|
const codexSandboxMode = codexPermMode === "full-access" ? "danger-full-access" : codexPermMode === "read-only" ? "read-only" : "workspace-write";
|
|
47121
47059
|
const codexApprovalsReviewer = codexPermMode === "auto-review" ? "auto_review" : void 0;
|
|
47122
|
-
const { initCodexHome, extractThreadIdFromRollout } = await import("./codex-
|
|
47060
|
+
const { initCodexHome, extractThreadIdFromRollout } = await import("./codex-DG2Dyp0K.js");
|
|
47123
47061
|
initCodexHome(codexHome, {
|
|
47124
47062
|
trustedDir: cwd,
|
|
47125
47063
|
approvalPolicy: codexApprovalPolicy,
|
|
@@ -47189,7 +47127,7 @@ async function spawnConversationSession(tmuxSession, cwd, claudeSessionId, model
|
|
|
47189
47127
|
} catch {}
|
|
47190
47128
|
console.log(`[claude-invoke] purpose=conversation-session | model=${model || "default"} | source=conversations.ts:spawnConversationSession | session=${tmuxSession} | resume=${resume} | command="${runtimeCommand}"`);
|
|
47191
47129
|
try {
|
|
47192
|
-
const { preTrustDirectory } = await import("./workspace-manager-
|
|
47130
|
+
const { preTrustDirectory } = await import("./workspace-manager-uVfFRWJG.js");
|
|
47193
47131
|
preTrustDirectory(cwd);
|
|
47194
47132
|
} catch {}
|
|
47195
47133
|
try {
|
|
@@ -47206,7 +47144,7 @@ async function spawnConversationSession(tmuxSession, cwd, claudeSessionId, model
|
|
|
47206
47144
|
const codexHomeDir = codexFields.codexHome;
|
|
47207
47145
|
(async () => {
|
|
47208
47146
|
try {
|
|
47209
|
-
const { waitForCodexRollout, extractThreadIdFromRollout, writeThreadId } = await import("./codex-
|
|
47147
|
+
const { waitForCodexRollout, extractThreadIdFromRollout, writeThreadId } = await import("./codex-DG2Dyp0K.js");
|
|
47210
47148
|
const rollout = await waitForCodexRollout(codexHomeDir, 12e4);
|
|
47211
47149
|
if (rollout) {
|
|
47212
47150
|
const threadId = extractThreadIdFromRollout(rollout);
|
|
@@ -47837,9 +47775,21 @@ function sanitizeTitle(raw) {
|
|
|
47837
47775
|
*/
|
|
47838
47776
|
function fallbackTranscriptTitle(transcript) {
|
|
47839
47777
|
const lines = transcript.split(/\r?\n/).map((line) => line.trim()).filter((line) => line && !line.startsWith("[…"));
|
|
47840
|
-
|
|
47841
|
-
|
|
47842
|
-
|
|
47778
|
+
return derivePromptTitle(lines.filter((line) => line.startsWith("User:")).map((line) => line.slice(5).trim()).filter(Boolean).at(-1) ?? lines[0]?.replace(/^(User|Assistant):\s*/i, "").trim() ?? "");
|
|
47779
|
+
}
|
|
47780
|
+
/**
|
|
47781
|
+
* Generate a deterministic title directly from a raw prompt string.
|
|
47782
|
+
* Zero model calls; returns '' only for empty/whitespace-only input.
|
|
47783
|
+
*/
|
|
47784
|
+
function derivePromptTitle(prompt) {
|
|
47785
|
+
const trimmed = prompt.trim();
|
|
47786
|
+
if (!trimmed) return "";
|
|
47787
|
+
const compact = trimmed.replace(/```[\s\S]*?```/g, " ").replace(/`([^`]+)`/g, "$1").replace(/\b(?:please|can you|could you|would you)\b/gi, " ").replace(/\b(?:i need you to|i want you to|help me|let's|lets)\b/gi, " ").replace(/https?:\/\/\S+/gi, " ").replace(/[^\p{L}\p{N}#/_+.-]+/gu, " ").replace(/\s+/g, " ").trim();
|
|
47788
|
+
const MAX_TITLE_LEN = 60;
|
|
47789
|
+
if (!compact) return trimmed.slice(0, MAX_TITLE_LEN) + (trimmed.length > MAX_TITLE_LEN ? "…" : "");
|
|
47790
|
+
const sanitized = sanitizeTitle(compact.split(/\s+/).slice(0, 8).join(" ").replace(/\s+(?:and|or|to|for|with)$/i, "").replace(/[.,:;!?]+$/g, ""));
|
|
47791
|
+
if (sanitized.length <= MAX_TITLE_LEN) return sanitized;
|
|
47792
|
+
return sanitized.slice(0, MAX_TITLE_LEN) + "…";
|
|
47843
47793
|
}
|
|
47844
47794
|
/**
|
|
47845
47795
|
* Keep title-generation prompts small and latency-bounded. The serialized
|
|
@@ -48488,86 +48438,6 @@ async function generateAiTitle(conversationName, firstMessage, deps) {
|
|
|
48488
48438
|
}
|
|
48489
48439
|
updateConversationTitle(conversationName, sanitized, "ai");
|
|
48490
48440
|
console.log(`[claude-invoke] SUCCESS purpose=conversation-title | model=${CONVERSATION_TITLE_MODEL} | conversation=${conversationName} | outputChars=${sanitized.length}`);
|
|
48491
|
-
scheduleTitleRefinement(conversationName, deps);
|
|
48492
|
-
}
|
|
48493
|
-
const refinementScheduled = /* @__PURE__ */ new Set();
|
|
48494
|
-
function scheduleTitleRefinement(conversationName, deps) {
|
|
48495
|
-
if (!isBackgroundFeatureEnabled("titleRefinement")) return;
|
|
48496
|
-
if (refinementScheduled.has(conversationName)) return;
|
|
48497
|
-
refinementScheduled.add(conversationName);
|
|
48498
|
-
const TIMEOUT_MS = 600 * 1e3;
|
|
48499
|
-
const POLL_INTERVAL_MS = 1500;
|
|
48500
|
-
const startedAt = Date.now();
|
|
48501
|
-
let timer = null;
|
|
48502
|
-
let running = false;
|
|
48503
|
-
let done = false;
|
|
48504
|
-
const stop = () => {
|
|
48505
|
-
done = true;
|
|
48506
|
-
if (timer) clearTimeout(timer);
|
|
48507
|
-
refinementScheduled.delete(conversationName);
|
|
48508
|
-
};
|
|
48509
|
-
async function tick() {
|
|
48510
|
-
if (done) return;
|
|
48511
|
-
if (running) {
|
|
48512
|
-
timer = setTimeout(tick, POLL_INTERVAL_MS);
|
|
48513
|
-
return;
|
|
48514
|
-
}
|
|
48515
|
-
running = true;
|
|
48516
|
-
try {
|
|
48517
|
-
if (Date.now() - startedAt > TIMEOUT_MS) {
|
|
48518
|
-
console.log(`[title-refine] Timed out waiting for first assistant response in "${conversationName}"`);
|
|
48519
|
-
stop();
|
|
48520
|
-
return;
|
|
48521
|
-
}
|
|
48522
|
-
const conv = getConversationByName(conversationName);
|
|
48523
|
-
if (!conv) {
|
|
48524
|
-
stop();
|
|
48525
|
-
return;
|
|
48526
|
-
}
|
|
48527
|
-
if (conv.titleSource !== "ai") {
|
|
48528
|
-
stop();
|
|
48529
|
-
return;
|
|
48530
|
-
}
|
|
48531
|
-
const sessionFile = await deps.resolveSessionFile(conv);
|
|
48532
|
-
if (!sessionFile || !existsSync$1(sessionFile)) {
|
|
48533
|
-
timer = setTimeout(tick, POLL_INTERVAL_MS);
|
|
48534
|
-
return;
|
|
48535
|
-
}
|
|
48536
|
-
const { messages } = await getCachedMessages(sessionFile, false);
|
|
48537
|
-
if (!messages.find((m) => m.role === "assistant" && m.completedAt)) {
|
|
48538
|
-
timer = setTimeout(tick, POLL_INTERVAL_MS);
|
|
48539
|
-
return;
|
|
48540
|
-
}
|
|
48541
|
-
const transcript = serializeConversationTranscript(messages);
|
|
48542
|
-
if (!transcript.trim()) {
|
|
48543
|
-
timer = setTimeout(tick, POLL_INTERVAL_MS);
|
|
48544
|
-
return;
|
|
48545
|
-
}
|
|
48546
|
-
console.log(`[claude-invoke] purpose=conversation-title-refine | model=${CONVERSATION_TITLE_MODEL} | conversation=${conversationName} | transcriptChars=${transcript.length}`);
|
|
48547
|
-
const refined = await summarizeTranscriptTitle(transcript, configuredTitleModel());
|
|
48548
|
-
if (!refined) {
|
|
48549
|
-
console.warn(`[title-refine] Model returned empty refined title for "${conversationName}"`);
|
|
48550
|
-
stop();
|
|
48551
|
-
return;
|
|
48552
|
-
}
|
|
48553
|
-
const freshConv = getConversationByName(conversationName);
|
|
48554
|
-
if (!freshConv || freshConv.titleSource !== "ai") {
|
|
48555
|
-
console.log(`[title-refine] Conversation "${conversationName}" no longer eligible (source=${freshConv?.titleSource ?? "missing"}); skipping`);
|
|
48556
|
-
stop();
|
|
48557
|
-
return;
|
|
48558
|
-
}
|
|
48559
|
-
updateConversationTitle(conversationName, refined, "ai-refined");
|
|
48560
|
-
console.log(`[claude-invoke] SUCCESS purpose=conversation-title-refine | conversation=${conversationName} | title="${refined}"`);
|
|
48561
|
-
stop();
|
|
48562
|
-
} catch (err) {
|
|
48563
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
48564
|
-
console.error(`[title-refine] failed for "${conversationName}":`, msg);
|
|
48565
|
-
stop();
|
|
48566
|
-
} finally {
|
|
48567
|
-
running = false;
|
|
48568
|
-
}
|
|
48569
|
-
}
|
|
48570
|
-
timer = setTimeout(tick, POLL_INTERVAL_MS);
|
|
48571
48441
|
}
|
|
48572
48442
|
const MAX_TITLE_LENGTH = 200;
|
|
48573
48443
|
function patchConversationTitle(name, body) {
|
|
@@ -48619,7 +48489,7 @@ async function retitleConversation(name, deps) {
|
|
|
48619
48489
|
console.warn(`[conversations] retitle timed out for "${name}"; using deterministic fallback title "${title}"`);
|
|
48620
48490
|
}
|
|
48621
48491
|
if (!title) return result({ error: "Title model returned an empty result" }, 502);
|
|
48622
|
-
updateConversationTitle(name, title, "ai");
|
|
48492
|
+
updateConversationTitle(name, title, "ai-explicit");
|
|
48623
48493
|
console.log(`[claude-invoke] SUCCESS purpose=conversation-retitle | conversation=${name} | title="${title}"`);
|
|
48624
48494
|
return result({ title });
|
|
48625
48495
|
} finally {
|
|
@@ -49073,10 +48943,14 @@ async function handleConversationMessage(name, body, deps = {
|
|
|
49073
48943
|
console.error(`[conversations] eaten-message watcher failed for ${conv.name}: ${msg}`);
|
|
49074
48944
|
});
|
|
49075
48945
|
}
|
|
49076
|
-
if (conv.titleSource === "default")
|
|
49077
|
-
const
|
|
49078
|
-
|
|
49079
|
-
|
|
48946
|
+
if (conv.titleSource === "default") {
|
|
48947
|
+
const derivedTitle = derivePromptTitle(message);
|
|
48948
|
+
if (derivedTitle) updateConversationTitle(name, derivedTitle, "auto");
|
|
48949
|
+
deps.generateAiTitle(name, message).catch((err) => {
|
|
48950
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
48951
|
+
console.error(`[TITLE-GEN-FAILED] AI title generation FAILED for "${name}" — NO RETRY, NO FALLBACK:`, msg);
|
|
48952
|
+
});
|
|
48953
|
+
}
|
|
49080
48954
|
return jsonResponse({
|
|
49081
48955
|
ok: true,
|
|
49082
48956
|
...droppedImageCount > 0 ? { imagesDropped: droppedImageCount } : {}
|
|
@@ -50192,7 +50066,6 @@ const eventsRouteLayer = Layer.mergeAll(getEventStreamRoute, getEventVersionRout
|
|
|
50192
50066
|
* GET /api/show/:issueId/shadow — shadow state details
|
|
50193
50067
|
* GET /api/show/:issueId/health — health + heartbeat only
|
|
50194
50068
|
*/
|
|
50195
|
-
init_shadow_state();
|
|
50196
50069
|
const getShowRoute = HttpRouter.add("GET", "/api/show/:issueId", httpHandler(Effect.gen(function* () {
|
|
50197
50070
|
const issueId = (yield* HttpRouter.params)["issueId"] ?? "";
|
|
50198
50071
|
const shadowState = yield* getShadowState(issueId);
|
|
@@ -50290,7 +50163,7 @@ async function registerProjectFromPath(opts) {
|
|
|
50290
50163
|
registerProjectSync(key, projectConfig);
|
|
50291
50164
|
const seededContextLayer = ensureProjectLayer(fullPath);
|
|
50292
50165
|
try {
|
|
50293
|
-
const { preTrustDirectorySync } = await import("./workspace-manager-
|
|
50166
|
+
const { preTrustDirectorySync } = await import("./workspace-manager-uVfFRWJG.js");
|
|
50294
50167
|
preTrustDirectorySync(fullPath);
|
|
50295
50168
|
} catch {}
|
|
50296
50169
|
let hooksInstalled = 0;
|
|
@@ -50324,9 +50197,9 @@ init_read_model();
|
|
|
50324
50197
|
init_agents$1();
|
|
50325
50198
|
init_pan_dir();
|
|
50326
50199
|
init_paths();
|
|
50327
|
-
const execAsync$
|
|
50200
|
+
const execAsync$2 = promisify(exec);
|
|
50328
50201
|
async function getIssueDataService() {
|
|
50329
|
-
const { getSharedIssueService } = await import("./issue-service-singleton-
|
|
50202
|
+
const { getSharedIssueService } = await import("./issue-service-singleton-Cyfvop7U.js");
|
|
50330
50203
|
return getSharedIssueService();
|
|
50331
50204
|
}
|
|
50332
50205
|
/** Returns true if the path exists (any type). */
|
|
@@ -50438,13 +50311,15 @@ async function collectSessionTreeNodes(issueId, workspacePath, projectPath, cont
|
|
|
50438
50311
|
const agentId = `agent-${issueLower}`;
|
|
50439
50312
|
const planningAgentId = `planning-${issueLower}`;
|
|
50440
50313
|
const strikeAgentId = `strike-${issueLower}`;
|
|
50314
|
+
const knowledgeAgentId = `agent-${issueLower}-knowledge`;
|
|
50441
50315
|
const slotWorkSessionPattern = getSlotWorkSessionPattern(issueLower);
|
|
50442
50316
|
const sections = [];
|
|
50443
50317
|
let hasPlanningSection = false;
|
|
50444
50318
|
const candidateSessionIds = new Set([
|
|
50445
50319
|
planningAgentId,
|
|
50446
50320
|
agentId,
|
|
50447
|
-
strikeAgentId
|
|
50321
|
+
strikeAgentId,
|
|
50322
|
+
knowledgeAgentId
|
|
50448
50323
|
]);
|
|
50449
50324
|
const agentEntries = await readdir(agentsDir, { withFileTypes: true }).catch(() => []);
|
|
50450
50325
|
for (const entry of agentEntries) {
|
|
@@ -50459,7 +50334,7 @@ async function collectSessionTreeNodes(issueId, workspacePath, projectPath, cont
|
|
|
50459
50334
|
try {
|
|
50460
50335
|
const isPlanning = checkId.startsWith("planning-");
|
|
50461
50336
|
const isStrike = checkId.startsWith("strike-");
|
|
50462
|
-
const sectionType = isPlanning ? "planning" : isStrike ? "strike" : "work";
|
|
50337
|
+
const sectionType = isPlanning ? "planning" : isStrike ? "strike" : state.role === "knowledge" ? "knowledge" : "work";
|
|
50463
50338
|
if (isPlanning) hasPlanningSection = true;
|
|
50464
50339
|
const rtState = await Effect.runPromise(getAgentRuntimeState(checkId));
|
|
50465
50340
|
const presence = await deriveSessionPresence(checkId, rtState, context.tmuxSessionNames);
|
|
@@ -50469,7 +50344,7 @@ async function collectSessionTreeNodes(issueId, workspacePath, projectPath, cont
|
|
|
50469
50344
|
sections.push({
|
|
50470
50345
|
type: sectionType,
|
|
50471
50346
|
sessionId: checkId,
|
|
50472
|
-
tmuxSession: sectionType === "work" || sectionType === "planning" || sectionType === "strike" ? checkId : void 0,
|
|
50347
|
+
tmuxSession: sectionType === "work" || sectionType === "planning" || sectionType === "strike" || sectionType === "knowledge" ? checkId : void 0,
|
|
50473
50348
|
model: state.model || "unknown",
|
|
50474
50349
|
startedAt: state.startedAt || (/* @__PURE__ */ new Date()).toISOString(),
|
|
50475
50350
|
endedAt: void 0,
|
|
@@ -50823,7 +50698,7 @@ const postProjectsRoute = HttpRouter.add("POST", "/api/projects", httpHandler(Ef
|
|
|
50823
50698
|
if ((await readdir(target).catch(() => [])).length > 0) return jsonResponse({ error: `target directory already exists and is non-empty: ${target}` }, { status: 409 });
|
|
50824
50699
|
}
|
|
50825
50700
|
await mkdir(target, { recursive: true });
|
|
50826
|
-
await execAsync$
|
|
50701
|
+
await execAsync$2("git init", { cwd: target });
|
|
50827
50702
|
try {
|
|
50828
50703
|
const result = await registerProjectFromPath({
|
|
50829
50704
|
path: target,
|
|
@@ -51021,7 +50896,7 @@ async function describeSyncTarget(harness, layerKind, projectKey, label, path) {
|
|
|
51021
50896
|
async function buildSyncTargets(projects) {
|
|
51022
50897
|
const targets = [await describeSyncTarget("claude-code", "global", void 0, "Claude Code · global", join$1(CLAUDE_DIR, "CLAUDE.md")), await describeSyncTarget("codex", "global", void 0, "Codex · global (codex-global.md)", codexGlobalContextFile())];
|
|
51023
50898
|
for (const { key, config } of projects) {
|
|
51024
|
-
if (!(await readOptionalFile(
|
|
50899
|
+
if (!(await readOptionalFile(resolveProjectContextFile(config.path))).exists) continue;
|
|
51025
50900
|
targets.push(await describeSyncTarget("claude-code", "project", key, `${config.name} · CLAUDE.md`, join$1(config.path, "CLAUDE.md")));
|
|
51026
50901
|
targets.push(await describeSyncTarget("pi", "project", key, `${config.name} · AGENTS.md`, join$1(config.path, "AGENTS.md")));
|
|
51027
50902
|
}
|
|
@@ -51030,11 +50905,11 @@ async function buildSyncTargets(projects) {
|
|
|
51030
50905
|
async function buildContextLayerState(projects, overdeckHome = getOverdeckHome()) {
|
|
51031
50906
|
const catalog = await buildContextCatalog(projects);
|
|
51032
50907
|
const resolvedLayers = [await layerRecord(globalContextFile(overdeckHome), { kind: "global" })];
|
|
51033
|
-
for (const project of catalog.projects) resolvedLayers.push(await layerRecord(
|
|
50908
|
+
for (const project of catalog.projects) resolvedLayers.push(await layerRecord(resolveProjectContextFile(project.config.path), {
|
|
51034
50909
|
kind: "project",
|
|
51035
50910
|
projectKey: project.key
|
|
51036
50911
|
}));
|
|
51037
|
-
for (const workspace of catalog.workspaces) resolvedLayers.push(await layerRecord(
|
|
50912
|
+
for (const workspace of catalog.workspaces) resolvedLayers.push(await layerRecord(resolveWorkspaceContextFile(workspace.path), {
|
|
51038
50913
|
kind: "workspace",
|
|
51039
50914
|
projectKey: workspace.projectKey,
|
|
51040
50915
|
workspacePath: workspace.path
|
|
@@ -51287,14 +51162,16 @@ const postContextSyncRoute = HttpRouter.add("POST", "/api/context/sync", httpHan
|
|
|
51287
51162
|
const contextRouteLayer = Layer.mergeAll(getContextLayersRoute, postContextPreviewRoute, putContextLayerRoute, postContextSyncRoute);
|
|
51288
51163
|
//#endregion
|
|
51289
51164
|
//#region routes/admin.ts
|
|
51165
|
+
init_tldr_daemon();
|
|
51166
|
+
init_projects();
|
|
51167
|
+
init_conversations();
|
|
51290
51168
|
/**
|
|
51291
51169
|
* Admin route module — plumbing endpoints
|
|
51292
51170
|
*
|
|
51293
51171
|
* Implements /api/admin/* endpoints mirroring the `pan admin` CLI namespace:
|
|
51294
|
-
* GET /api/admin/tldr/:issueId
|
|
51172
|
+
* GET /api/admin/tldr/:issueId — TLDR daemon status for a workspace
|
|
51173
|
+
* POST /api/admin/conversations/backfill-titles — retitle stuck conversations
|
|
51295
51174
|
*/
|
|
51296
|
-
init_tldr_daemon();
|
|
51297
|
-
init_projects();
|
|
51298
51175
|
const getAdminTldrRoute = HttpRouter.add("GET", "/api/admin/tldr/:issueId", httpHandler(Effect.gen(function* () {
|
|
51299
51176
|
const issueId = (yield* HttpRouter.params)["issueId"] ?? "";
|
|
51300
51177
|
const workspacePath = join$1(resolveProjectFromIssueSync(issueId)?.projectPath ?? process.cwd(), "workspaces", `feature-${issueId.toLowerCase()}`);
|
|
@@ -51315,7 +51192,76 @@ const getAdminTldrRoute = HttpRouter.add("GET", "/api/admin/tldr/:issueId", http
|
|
|
51315
51192
|
});
|
|
51316
51193
|
});
|
|
51317
51194
|
})));
|
|
51318
|
-
|
|
51195
|
+
async function handleBackfillTitlesBody(body, deps) {
|
|
51196
|
+
const dryRun = body.dryRun === true;
|
|
51197
|
+
const stuck = listConversations().filter((conv) => conv.title === "New conversation" && conv.titleSource === "default");
|
|
51198
|
+
const updated = [];
|
|
51199
|
+
const skipped = [];
|
|
51200
|
+
for (const conv of stuck) try {
|
|
51201
|
+
const sessionFile = await deps.resolveSessionFile(conv);
|
|
51202
|
+
if (!sessionFile) {
|
|
51203
|
+
skipped.push({
|
|
51204
|
+
name: conv.name,
|
|
51205
|
+
reason: "no transcript"
|
|
51206
|
+
});
|
|
51207
|
+
continue;
|
|
51208
|
+
}
|
|
51209
|
+
const { messages } = await deps.getCachedMessages(sessionFile, false);
|
|
51210
|
+
const firstUser = messages.find((m) => m.role === "user" && typeof m.text === "string" && m.text.trim().length > 0);
|
|
51211
|
+
let candidate = "";
|
|
51212
|
+
let reason;
|
|
51213
|
+
if (firstUser) {
|
|
51214
|
+
candidate = derivePromptTitle(firstUser.text);
|
|
51215
|
+
reason = "transcript";
|
|
51216
|
+
}
|
|
51217
|
+
if (!candidate) {
|
|
51218
|
+
candidate = `Untitled — ${new Date(conv.createdAt).toISOString().slice(0, 10)}`;
|
|
51219
|
+
reason = "no transcript";
|
|
51220
|
+
}
|
|
51221
|
+
const fresh = getConversationByName(conv.name);
|
|
51222
|
+
if (!fresh || fresh.title !== "New conversation" || fresh.titleSource !== "default") {
|
|
51223
|
+
skipped.push({
|
|
51224
|
+
name: conv.name,
|
|
51225
|
+
reason: "no longer eligible"
|
|
51226
|
+
});
|
|
51227
|
+
continue;
|
|
51228
|
+
}
|
|
51229
|
+
if (!dryRun) updateConversationTitle(conv.name, candidate, "auto");
|
|
51230
|
+
updated.push({
|
|
51231
|
+
name: conv.name,
|
|
51232
|
+
title: candidate,
|
|
51233
|
+
reason
|
|
51234
|
+
});
|
|
51235
|
+
} catch (err) {
|
|
51236
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
51237
|
+
skipped.push({
|
|
51238
|
+
name: conv.name,
|
|
51239
|
+
reason: `transcript error: ${msg}`
|
|
51240
|
+
});
|
|
51241
|
+
}
|
|
51242
|
+
return {
|
|
51243
|
+
updated,
|
|
51244
|
+
skipped,
|
|
51245
|
+
dryRun
|
|
51246
|
+
};
|
|
51247
|
+
}
|
|
51248
|
+
const postAdminBackfillTitlesRoute = HttpRouter.add("POST", "/api/admin/conversations/backfill-titles", httpHandler(Effect.gen(function* () {
|
|
51249
|
+
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
51250
|
+
if (!hasDashboardInternalToken(request)) return jsonResponse({ error: "unauthorized" }, { status: 401 });
|
|
51251
|
+
const rawBody = yield* request.text;
|
|
51252
|
+
let body;
|
|
51253
|
+
try {
|
|
51254
|
+
body = JSON.parse(rawBody);
|
|
51255
|
+
} catch {
|
|
51256
|
+
return jsonResponse({ error: "invalid JSON" }, { status: 400 });
|
|
51257
|
+
}
|
|
51258
|
+
const dryRun = body.dryRun === true;
|
|
51259
|
+
return jsonResponse(yield* Effect.promise(() => handleBackfillTitlesBody({ dryRun }, {
|
|
51260
|
+
resolveSessionFile,
|
|
51261
|
+
getCachedMessages
|
|
51262
|
+
})));
|
|
51263
|
+
})));
|
|
51264
|
+
const adminRouteLayer = Layer.mergeAll(getAdminTldrRoute, postAdminBackfillTitlesRoute);
|
|
51319
51265
|
//#endregion
|
|
51320
51266
|
//#region ../../lib/prereqs/registry.ts
|
|
51321
51267
|
/**
|
|
@@ -51324,7 +51270,7 @@ const adminRouteLayer = Layer.mergeAll(getAdminTldrRoute);
|
|
|
51324
51270
|
* requiring a heavy `pan install` step before first use.
|
|
51325
51271
|
*/
|
|
51326
51272
|
init_platform();
|
|
51327
|
-
const execAsync$
|
|
51273
|
+
const execAsync$1 = promisify(exec);
|
|
51328
51274
|
const PREREQ_REGISTRY = {
|
|
51329
51275
|
addGitHubProject: ["gh"],
|
|
51330
51276
|
addGitLabProject: ["glab"],
|
|
@@ -51384,8 +51330,8 @@ async function installTool(tool) {
|
|
|
51384
51330
|
}
|
|
51385
51331
|
}
|
|
51386
51332
|
async function installTmux() {
|
|
51387
|
-
if (await Effect.runPromise(detectPlatform()) === "darwin") await execAsync$
|
|
51388
|
-
else await execAsync$
|
|
51333
|
+
if (await Effect.runPromise(detectPlatform()) === "darwin") await execAsync$1("brew install tmux", { timeout: 12e4 });
|
|
51334
|
+
else await execAsync$1("sudo apt-get update && sudo apt-get install -y tmux", { timeout: 12e4 });
|
|
51389
51335
|
return {
|
|
51390
51336
|
tool: "tmux",
|
|
51391
51337
|
success: true,
|
|
@@ -51398,14 +51344,14 @@ async function installTtyd() {
|
|
|
51398
51344
|
mkdirSync$1(binDir, { recursive: true });
|
|
51399
51345
|
const ttydPath = join$1(binDir, "ttyd");
|
|
51400
51346
|
if (plat === "darwin") try {
|
|
51401
|
-
await execAsync$
|
|
51347
|
+
await execAsync$1("brew install ttyd", { timeout: 12e4 });
|
|
51402
51348
|
return {
|
|
51403
51349
|
tool: "ttyd",
|
|
51404
51350
|
success: true,
|
|
51405
51351
|
message: "ttyd installed via Homebrew"
|
|
51406
51352
|
};
|
|
51407
51353
|
} catch {}
|
|
51408
|
-
await execAsync$
|
|
51354
|
+
await execAsync$1(`curl -sL "https://github.com/tsl0922/ttyd/releases/latest/download/ttyd.x86_64" -o "${ttydPath}" && chmod +x "${ttydPath}"`, { timeout: 6e4 });
|
|
51409
51355
|
return {
|
|
51410
51356
|
tool: "ttyd",
|
|
51411
51357
|
success: true,
|
|
@@ -51414,8 +51360,8 @@ async function installTtyd() {
|
|
|
51414
51360
|
}
|
|
51415
51361
|
async function installMkcert() {
|
|
51416
51362
|
if (await Effect.runPromise(detectPlatform()) === "darwin") {
|
|
51417
|
-
await execAsync$
|
|
51418
|
-
await execAsync$
|
|
51363
|
+
await execAsync$1("brew install mkcert", { timeout: 12e4 });
|
|
51364
|
+
await execAsync$1("mkcert -install", { timeout: 3e4 });
|
|
51419
51365
|
return {
|
|
51420
51366
|
tool: "mkcert",
|
|
51421
51367
|
success: true,
|
|
@@ -51425,8 +51371,8 @@ async function installMkcert() {
|
|
|
51425
51371
|
const binDir = join$1(homedir$1(), ".local", "bin");
|
|
51426
51372
|
mkdirSync$1(binDir, { recursive: true });
|
|
51427
51373
|
const mkcertPath = join$1(binDir, "mkcert");
|
|
51428
|
-
await execAsync$
|
|
51429
|
-
await execAsync$
|
|
51374
|
+
await execAsync$1(`curl -sL "https://github.com/FiloSottile/mkcert/releases/latest/download/mkcert-v1.4.4-linux-${process.arch === "x64" ? "amd64" : process.arch}" -o "${mkcertPath}" && chmod +x "${mkcertPath}"`, { timeout: 6e4 });
|
|
51375
|
+
await execAsync$1("mkcert -install", { timeout: 3e4 });
|
|
51430
51376
|
return {
|
|
51431
51377
|
tool: "mkcert",
|
|
51432
51378
|
success: true,
|
|
@@ -51435,14 +51381,14 @@ async function installMkcert() {
|
|
|
51435
51381
|
}
|
|
51436
51382
|
async function installBeads() {
|
|
51437
51383
|
if (await Effect.runPromise(detectPlatform()) === "darwin") try {
|
|
51438
|
-
await execAsync$
|
|
51384
|
+
await execAsync$1("brew install gastownhall/beads/bd", { timeout: 12e4 });
|
|
51439
51385
|
return {
|
|
51440
51386
|
tool: "bd",
|
|
51441
51387
|
success: true,
|
|
51442
51388
|
message: "beads installed via Homebrew"
|
|
51443
51389
|
};
|
|
51444
51390
|
} catch {}
|
|
51445
|
-
await execAsync$
|
|
51391
|
+
await execAsync$1("curl -sSL https://raw.githubusercontent.com/gastownhall/beads/main/scripts/install.sh | bash", { timeout: 12e4 });
|
|
51446
51392
|
return {
|
|
51447
51393
|
tool: "bd",
|
|
51448
51394
|
success: true,
|
|
@@ -51456,7 +51402,7 @@ async function installOx() {
|
|
|
51456
51402
|
const binDir = join$1(homedir$1(), ".local", "bin");
|
|
51457
51403
|
const oxPath = join$1(binDir, "ox");
|
|
51458
51404
|
mkdirSync$1(binDir, { recursive: true });
|
|
51459
|
-
await execAsync$
|
|
51405
|
+
await execAsync$1(`curl -sL "https://github.com/eltmon/ox/releases/download/latest/ox-${platform}-${arch}" -o "${oxPath}" && chmod +x "${oxPath}"`, { timeout: 6e4 });
|
|
51460
51406
|
return {
|
|
51461
51407
|
tool: "ox",
|
|
51462
51408
|
success: true,
|
|
@@ -52253,7 +52199,7 @@ async function refreshMergeStateFromGitHub(issueId, repo, prNumber) {
|
|
|
52253
52199
|
let mergeState;
|
|
52254
52200
|
let isDraft;
|
|
52255
52201
|
let checksFailed;
|
|
52256
|
-
const { isGitHubAppConfigured, getPullRequestState } = await import("./github-app-
|
|
52202
|
+
const { isGitHubAppConfigured, getPullRequestState } = await import("./github-app-BFaGREfW.js");
|
|
52257
52203
|
if (isGitHubAppConfigured()) {
|
|
52258
52204
|
const prState = await Effect.runPromise(getPullRequestState(owner, repoName, prNumber));
|
|
52259
52205
|
mergeable = prState.mergeable === null ? "UNKNOWN" : prState.mergeable ? "MERGEABLE" : "CONFLICTING";
|
|
@@ -52402,8 +52348,8 @@ async function handlePullRequestPromise(payload) {
|
|
|
52402
52348
|
bumpIssuePrTabCacheGeneration(issueId);
|
|
52403
52349
|
const repo = payload.repository.full_name;
|
|
52404
52350
|
if (payload.action === "closed" && pr.merged === true) try {
|
|
52405
|
-
const { postMergeLifecycle } = await import("./merge-agent-
|
|
52406
|
-
const { resolveProjectFromIssueSync } = await import("./projects-
|
|
52351
|
+
const { postMergeLifecycle } = await import("./merge-agent-DzbCbjqg.js");
|
|
52352
|
+
const { resolveProjectFromIssueSync } = await import("./projects-Daw2zpGk.js");
|
|
52407
52353
|
const project = resolveProjectFromIssueSync(issueId);
|
|
52408
52354
|
if (project) {
|
|
52409
52355
|
const branchName = pr.head.ref;
|
|
@@ -52820,9 +52766,75 @@ const webhooksRouteLayer = HttpRouter.add("POST", "/api/webhooks/github", httpHa
|
|
|
52820
52766
|
return yield* runWebhookHandler(body, headers);
|
|
52821
52767
|
})));
|
|
52822
52768
|
//#endregion
|
|
52769
|
+
//#region ../../lib/overdeck/title-refinement.ts
|
|
52770
|
+
init_paths$2();
|
|
52771
|
+
/**
|
|
52772
|
+
* Hook-driven progressive conversation title refinement.
|
|
52773
|
+
*
|
|
52774
|
+
* Replaces the old polling-based refinement scheduler with an event-driven
|
|
52775
|
+
* turn-complete handler. First refinement happens as soon as a completed
|
|
52776
|
+
* assistant message is available; later refinements are debounced by turn count
|
|
52777
|
+
* and wall-clock interval.
|
|
52778
|
+
*/
|
|
52779
|
+
init_features();
|
|
52780
|
+
init_conversations();
|
|
52781
|
+
const LATER_REFINE_MIN_TURNS = 5;
|
|
52782
|
+
const LATER_REFINE_MIN_INTERVAL_MS = 600 * 1e3;
|
|
52783
|
+
const cadenceByConversation = /* @__PURE__ */ new Map();
|
|
52784
|
+
const inFlight$1 = /* @__PURE__ */ new Set();
|
|
52785
|
+
async function handleTurnComplete(conv, deps) {
|
|
52786
|
+
if (!(deps.isBackgroundFeatureEnabled ?? isBackgroundFeatureEnabled)("titleRefinement")) return;
|
|
52787
|
+
if (!canRefineTitle(conv)) return;
|
|
52788
|
+
const name = conv.name;
|
|
52789
|
+
let cadence = cadenceByConversation.get(name);
|
|
52790
|
+
if (!cadence) {
|
|
52791
|
+
cadence = {
|
|
52792
|
+
turnsSinceRefine: 0,
|
|
52793
|
+
lastRefinedAtMs: conv.titleSource === "ai-refined" ? Date.now() : 0
|
|
52794
|
+
};
|
|
52795
|
+
cadenceByConversation.set(name, cadence);
|
|
52796
|
+
}
|
|
52797
|
+
cadence.turnsSinceRefine += 1;
|
|
52798
|
+
if (!(conv.titleSource === "default" || conv.titleSource === "auto" || conv.titleSource === "ai")) {
|
|
52799
|
+
if (!(cadence.turnsSinceRefine >= LATER_REFINE_MIN_TURNS && Date.now() - cadence.lastRefinedAtMs >= LATER_REFINE_MIN_INTERVAL_MS)) return;
|
|
52800
|
+
}
|
|
52801
|
+
if (inFlight$1.has(name)) return;
|
|
52802
|
+
inFlight$1.add(name);
|
|
52803
|
+
const getCachedMessages$1 = deps.getCachedMessages ?? getCachedMessages;
|
|
52804
|
+
const configuredTitleModel$1 = deps.configuredTitleModel ?? configuredTitleModel;
|
|
52805
|
+
const summarizeTranscriptTitle$1 = deps.summarizeTranscriptTitle ?? summarizeTranscriptTitle;
|
|
52806
|
+
try {
|
|
52807
|
+
const sessionFile = await deps.resolveSessionFile(conv);
|
|
52808
|
+
if (!sessionFile || !existsSync$1(sessionFile)) return;
|
|
52809
|
+
const { messages } = await getCachedMessages$1(sessionFile, false);
|
|
52810
|
+
if (!messages.find((m) => m.role === "assistant" && m.completedAt)) return;
|
|
52811
|
+
const transcript = serializeConversationTranscript(messages);
|
|
52812
|
+
if (!transcript.trim()) return;
|
|
52813
|
+
console.log(`[claude-invoke] purpose=conversation-title-refine | model=${configuredTitleModel$1()} | conversation=${name} | transcriptChars=${transcript.length}`);
|
|
52814
|
+
const refined = await summarizeTranscriptTitle$1(transcript, configuredTitleModel$1());
|
|
52815
|
+
if (!refined) {
|
|
52816
|
+
console.warn(`[title-refine] Model returned empty refined title for "${name}"`);
|
|
52817
|
+
return;
|
|
52818
|
+
}
|
|
52819
|
+
const freshConv = getConversationByName(name);
|
|
52820
|
+
if (!freshConv || !canRefineTitle(freshConv)) {
|
|
52821
|
+
console.log(`[title-refine] Conversation "${name}" no longer eligible (source=${freshConv?.titleSource ?? "missing"}); skipping`);
|
|
52822
|
+
return;
|
|
52823
|
+
}
|
|
52824
|
+
updateConversationTitle(name, refined, "ai-refined");
|
|
52825
|
+
console.log(`[claude-invoke] SUCCESS purpose=conversation-title-refine | conversation=${name} | title="${refined}"`);
|
|
52826
|
+
cadence.turnsSinceRefine = 0;
|
|
52827
|
+
cadence.lastRefinedAtMs = Date.now();
|
|
52828
|
+
} catch (err) {
|
|
52829
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
52830
|
+
console.error(`[title-refine] failed for "${name}":`, msg);
|
|
52831
|
+
} finally {
|
|
52832
|
+
inFlight$1.delete(name);
|
|
52833
|
+
}
|
|
52834
|
+
}
|
|
52835
|
+
//#endregion
|
|
52823
52836
|
//#region ../../lib/compliance/advisory-warning.ts
|
|
52824
52837
|
init_config_yaml();
|
|
52825
|
-
init_paths$2();
|
|
52826
52838
|
init_rollup();
|
|
52827
52839
|
const COMPLIANCE_ADVISORY_WARNING = "Last turn included a memory-first trigger but the search wasn't called. Try pan memory search first next time.";
|
|
52828
52840
|
async function resolveComplianceAdvisoryWarning(input) {
|
|
@@ -52902,7 +52914,7 @@ function getCheckpointWorker() {
|
|
|
52902
52914
|
return worker;
|
|
52903
52915
|
}
|
|
52904
52916
|
async function runInline(operation, payload) {
|
|
52905
|
-
const { claimTranscriptRange, commitTranscriptRange, releaseTranscriptRange, getTranscriptCheckpoint, listTranscriptCheckpoints } = await import("./checkpoints-
|
|
52917
|
+
const { claimTranscriptRange, commitTranscriptRange, releaseTranscriptRange, getTranscriptCheckpoint, listTranscriptCheckpoints } = await import("./checkpoints-DjIvtcNL.js");
|
|
52906
52918
|
switch (operation) {
|
|
52907
52919
|
case "claimTranscriptRange": return claimTranscriptRange(payload);
|
|
52908
52920
|
case "commitTranscriptRange": return commitTranscriptRange(payload);
|
|
@@ -54056,7 +54068,7 @@ function buildPendingTurn(input, fromOffset, toOffset, compressed) {
|
|
|
54056
54068
|
};
|
|
54057
54069
|
}
|
|
54058
54070
|
async function emitMemoryObservationCreated(observation, timestamp) {
|
|
54059
|
-
const { initEventStore } = await import("./event-store-
|
|
54071
|
+
const { initEventStore } = await import("./event-store-w76YFiCU.js");
|
|
54060
54072
|
await (await initEventStore()).appendAsync({
|
|
54061
54073
|
type: "memory.observation_created",
|
|
54062
54074
|
timestamp,
|
|
@@ -54819,7 +54831,65 @@ const postPermissionEventRoute = HttpRouter.add("POST", "/api/hooks/permission-e
|
|
|
54819
54831
|
waiting
|
|
54820
54832
|
});
|
|
54821
54833
|
})));
|
|
54822
|
-
|
|
54834
|
+
async function handleUserPromptSubmitBody(body, options = {}) {
|
|
54835
|
+
const sessionId = typeof body.session_id === "string" ? body.session_id : null;
|
|
54836
|
+
const prompt = typeof body.prompt === "string" ? body.prompt : "";
|
|
54837
|
+
if (!sessionId) return { ok: true };
|
|
54838
|
+
const conv = getConversationByClaudeSessionId(sessionId);
|
|
54839
|
+
if (!conv) return { ok: true };
|
|
54840
|
+
if (conv.titleSource === "default") {
|
|
54841
|
+
const derivedTitle = derivePromptTitle(prompt);
|
|
54842
|
+
if (derivedTitle) updateConversationTitle(conv.name, derivedTitle, "auto");
|
|
54843
|
+
(options.generateAiTitle ?? generateAiTitle)(conv.name, prompt, { resolveSessionFile: options.resolveSessionFile ?? resolveSessionFile }).catch((err) => {
|
|
54844
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
54845
|
+
console.error(`[hooks/user-prompt-submit] AI title generation failed for "${conv.name}":`, msg);
|
|
54846
|
+
});
|
|
54847
|
+
}
|
|
54848
|
+
return {
|
|
54849
|
+
ok: true,
|
|
54850
|
+
conversationName: conv.name,
|
|
54851
|
+
updated: conv.titleSource === "default"
|
|
54852
|
+
};
|
|
54853
|
+
}
|
|
54854
|
+
const postUserPromptSubmitRoute = HttpRouter.add("POST", "/api/hooks/user-prompt-submit", httpHandler(Effect.gen(function* () {
|
|
54855
|
+
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
54856
|
+
if (!hasDashboardInternalToken(request)) return jsonResponse({ error: "unauthorized" }, { status: 401 });
|
|
54857
|
+
const rawBody = yield* request.text;
|
|
54858
|
+
let body;
|
|
54859
|
+
try {
|
|
54860
|
+
body = JSON.parse(rawBody);
|
|
54861
|
+
} catch {
|
|
54862
|
+
return jsonResponse({ error: "invalid JSON" }, { status: 400 });
|
|
54863
|
+
}
|
|
54864
|
+
return jsonResponse(yield* Effect.promise(() => handleUserPromptSubmitBody(body)));
|
|
54865
|
+
})));
|
|
54866
|
+
async function handleTurnCompleteBody(body, options = {}) {
|
|
54867
|
+
const sessionId = typeof body.session_id === "string" ? body.session_id : null;
|
|
54868
|
+
if (!sessionId) return { ok: true };
|
|
54869
|
+
const conv = getConversationByClaudeSessionId(sessionId);
|
|
54870
|
+
if (!conv) return { ok: true };
|
|
54871
|
+
(options.handleTurnComplete ?? handleTurnComplete)(conv, { resolveSessionFile }).catch((err) => {
|
|
54872
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
54873
|
+
console.error(`[hooks/turn-complete] title refinement failed for "${conv.name}":`, msg);
|
|
54874
|
+
});
|
|
54875
|
+
return {
|
|
54876
|
+
ok: true,
|
|
54877
|
+
conversationName: conv.name
|
|
54878
|
+
};
|
|
54879
|
+
}
|
|
54880
|
+
const postTurnCompleteRoute = HttpRouter.add("POST", "/api/hooks/turn-complete", httpHandler(Effect.gen(function* () {
|
|
54881
|
+
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
54882
|
+
if (!hasDashboardInternalToken(request)) return jsonResponse({ error: "unauthorized" }, { status: 401 });
|
|
54883
|
+
const rawBody = yield* request.text;
|
|
54884
|
+
let body;
|
|
54885
|
+
try {
|
|
54886
|
+
body = JSON.parse(rawBody);
|
|
54887
|
+
} catch {
|
|
54888
|
+
return jsonResponse({ error: "invalid JSON" }, { status: 400 });
|
|
54889
|
+
}
|
|
54890
|
+
return jsonResponse(yield* Effect.promise(() => handleTurnCompleteBody(body)));
|
|
54891
|
+
})));
|
|
54892
|
+
const hooksRouteLayer = Layer.mergeAll(postMemoryInjectRoute, postMemorySessionStartRoute, postMemoryTurnRoute, postPermissionEventRoute, postUserPromptSubmitRoute, postTurnCompleteRoute);
|
|
54823
54893
|
function parseMemoryIdentity(value, sessionId) {
|
|
54824
54894
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
54825
54895
|
const identity = value;
|
|
@@ -57095,7 +57165,7 @@ async function getFlywheelConversationPayload() {
|
|
|
57095
57165
|
};
|
|
57096
57166
|
}
|
|
57097
57167
|
async function postFlywheelReportPayload() {
|
|
57098
|
-
const { flywheelReportCommand } = await import("./flywheel-
|
|
57168
|
+
const { flywheelReportCommand } = await import("./flywheel-DrNtUqWK.js");
|
|
57099
57169
|
await flywheelReportCommand({ cwd: process.cwd() });
|
|
57100
57170
|
return {
|
|
57101
57171
|
status: 200,
|
|
@@ -57253,11 +57323,11 @@ const getMergeBlockersRoute = HttpRouter.add("GET", "/api/flywheel/merge-blocker
|
|
|
57253
57323
|
async function defaultGetOrderedIssueIds() {
|
|
57254
57324
|
const status = await readCurrentFlywheelStatusForDashboard();
|
|
57255
57325
|
if (!status) return [];
|
|
57256
|
-
const { computeMergeQueue } = await import("./flywheel-merge-order-
|
|
57326
|
+
const { computeMergeQueue } = await import("./flywheel-merge-order-CrZrhwbK.js");
|
|
57257
57327
|
return (await Effect.runPromise(computeMergeQueue(status.activePipeline, process.cwd()).pipe(Effect.provide(layer)))).map((i) => i.issueId);
|
|
57258
57328
|
}
|
|
57259
57329
|
async function defaultMergeOne(issueId) {
|
|
57260
|
-
const { triggerMerge } = await import("./merge-ops-
|
|
57330
|
+
const { triggerMerge } = await import("./merge-ops-CgzhHkd4.js");
|
|
57261
57331
|
const r = await triggerMerge(issueId);
|
|
57262
57332
|
return r.success ? { ok: true } : {
|
|
57263
57333
|
ok: false,
|
|
@@ -57277,7 +57347,7 @@ async function postFlywheelMergeNextPayload(payload, deps = {}) {
|
|
|
57277
57347
|
body: { error: "n must be a positive integer" }
|
|
57278
57348
|
};
|
|
57279
57349
|
const issueIds = (await (deps.getOrderedIssueIds ?? defaultGetOrderedIssueIds)()).slice(0, n);
|
|
57280
|
-
const { shipMergeBatch } = await import("./merge-batch-
|
|
57350
|
+
const { shipMergeBatch } = await import("./merge-batch-LLp_cXUR.js");
|
|
57281
57351
|
return {
|
|
57282
57352
|
status: 200,
|
|
57283
57353
|
body: { outcomes: await shipMergeBatch(issueIds, { merge: deps.merge ?? defaultMergeOne }) }
|
|
@@ -57434,7 +57504,7 @@ const getFlywheelMergeQueueRoute = HttpRouter.add("GET", "/api/flywheel/merge-qu
|
|
|
57434
57504
|
return yield* Effect.promise(async () => {
|
|
57435
57505
|
const status = await readCurrentFlywheelStatusForDashboard();
|
|
57436
57506
|
if (!status) return jsonResponse([]);
|
|
57437
|
-
const { computeMergeQueue, resolveMergeQueuePrUrl } = await import("./flywheel-merge-order-
|
|
57507
|
+
const { computeMergeQueue, resolveMergeQueuePrUrl } = await import("./flywheel-merge-order-CrZrhwbK.js");
|
|
57438
57508
|
return jsonResponse(await Effect.runPromise(computeMergeQueue(status.activePipeline, process.cwd(), { getPrUrl: resolveMergeQueuePrUrl }).pipe(Effect.provide(layer))));
|
|
57439
57509
|
});
|
|
57440
57510
|
})));
|
|
@@ -57448,18 +57518,18 @@ function uatGenerationNameFromParam(param) {
|
|
|
57448
57518
|
return decoded.startsWith("uat/") ? decoded : `uat/${decoded}`;
|
|
57449
57519
|
}
|
|
57450
57520
|
const getUatGenerationsRoute = HttpRouter.add("GET", "/api/flywheel/uat-generations", httpHandler(Effect.gen(function* () {
|
|
57451
|
-
const { getUatGenerationsPayload } = yield* Effect.promise(() => import("./uat-train-
|
|
57521
|
+
const { getUatGenerationsPayload } = yield* Effect.promise(() => import("./uat-train-fTKeQcdW.js"));
|
|
57452
57522
|
return jsonResponse(yield* Effect.promise(() => getUatGenerationsPayload()));
|
|
57453
57523
|
})));
|
|
57454
57524
|
const getUatCandidateRoute = HttpRouter.add("GET", "/api/flywheel/uat-candidate", httpHandler(Effect.gen(function* () {
|
|
57455
|
-
const { getUatCandidatePayload } = yield* Effect.promise(() => import("./uat-train-
|
|
57525
|
+
const { getUatCandidatePayload } = yield* Effect.promise(() => import("./uat-train-fTKeQcdW.js"));
|
|
57456
57526
|
return jsonResponse(yield* Effect.promise(() => getUatCandidatePayload()));
|
|
57457
57527
|
})));
|
|
57458
57528
|
const postUatGenerationStackRoute = HttpRouter.add("POST", "/api/flywheel/uat-generations/:name/stack", httpHandler(Effect.gen(function* () {
|
|
57459
57529
|
const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
|
|
57460
57530
|
if (authError) return authError;
|
|
57461
57531
|
const name = uatGenerationNameFromParam((yield* HttpRouter.params)["name"] ?? "");
|
|
57462
|
-
const { postUatGenerationStackPayload } = yield* Effect.promise(() => import("./uat-train-
|
|
57532
|
+
const { postUatGenerationStackPayload } = yield* Effect.promise(() => import("./uat-train-fTKeQcdW.js"));
|
|
57463
57533
|
const result = yield* Effect.promise(() => postUatGenerationStackPayload(name));
|
|
57464
57534
|
if (!result.ok) return jsonResponse({ error: result.error }, { status: result.status });
|
|
57465
57535
|
return jsonResponse({
|
|
@@ -57471,8 +57541,8 @@ const postUatGenerationPromoteRoute = HttpRouter.add("POST", "/api/flywheel/uat-
|
|
|
57471
57541
|
const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
|
|
57472
57542
|
if (authError) return authError;
|
|
57473
57543
|
const name = uatGenerationNameFromParam((yield* HttpRouter.params)["name"] ?? "");
|
|
57474
|
-
const { postUatGenerationPromotePayload } = yield* Effect.promise(() => import("./uat-train-
|
|
57475
|
-
const { firePostMergeLifecycle } = yield* Effect.promise(() => import("./specialists-
|
|
57544
|
+
const { postUatGenerationPromotePayload } = yield* Effect.promise(() => import("./uat-train-fTKeQcdW.js"));
|
|
57545
|
+
const { firePostMergeLifecycle } = yield* Effect.promise(() => import("./specialists-BWNyQTq6.js"));
|
|
57476
57546
|
const result = yield* Effect.promise(() => postUatGenerationPromotePayload(name, firePostMergeLifecycle));
|
|
57477
57547
|
if (!result.success) return jsonResponse(result, { status: result.reason === "not-found" ? 404 : result.reason === "merge-failed" ? 500 : 409 });
|
|
57478
57548
|
return jsonResponse(result);
|
|
@@ -57485,7 +57555,7 @@ const postUatGenerationPromoteRoute = HttpRouter.add("POST", "/api/flywheel/uat-
|
|
|
57485
57555
|
const postFlywheelAssembleUatRoute = HttpRouter.add("POST", "/api/flywheel/assemble-uat", httpHandler(Effect.gen(function* () {
|
|
57486
57556
|
const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
|
|
57487
57557
|
if (authError) return authError;
|
|
57488
|
-
const { runUatTrainReconcile } = yield* Effect.promise(() => import("./uat-train-
|
|
57558
|
+
const { runUatTrainReconcile } = yield* Effect.promise(() => import("./uat-train-fTKeQcdW.js"));
|
|
57489
57559
|
return jsonResponse(yield* Effect.promise(() => runUatTrainReconcile({ force: true })));
|
|
57490
57560
|
})));
|
|
57491
57561
|
const getFlywheelStateRoute = HttpRouter.add("GET", "/api/flywheel/state", httpHandler(Effect.gen(function* () {
|
|
@@ -57905,36 +57975,8 @@ const postArtifactUnshareRoute = HttpRouter.add("POST", "/api/artifacts/:slug/un
|
|
|
57905
57975
|
})));
|
|
57906
57976
|
const artifactsRouteLayer = Layer.mergeAll(getRawArtifactRoute, getArtifactDetailRoute, getWorkspaceArtifactsRoute, getArtifactThumbnailRoute, postArtifactUnshareRoute);
|
|
57907
57977
|
//#endregion
|
|
57908
|
-
//#region ../../lib/backlog/label-ops.ts
|
|
57909
|
-
init_sequence_io();
|
|
57910
|
-
init_tracker_utils();
|
|
57911
|
-
const execAsync$1 = promisify(exec);
|
|
57912
|
-
/**
|
|
57913
|
-
* Add or remove a GitHub label on an issue. Non-GitHub issues are silently
|
|
57914
|
-
* skipped; the `|| true` keeps a missing-label / already-applied no-op non-fatal.
|
|
57915
|
-
*/
|
|
57916
|
-
async function editIssueLabel(issueId, op, label) {
|
|
57917
|
-
const resolution = resolveGitHubIssueSync(issueId);
|
|
57918
|
-
if (!resolution.isGitHub) return;
|
|
57919
|
-
const { owner, repo, number } = resolution;
|
|
57920
|
-
await execAsync$1(`gh issue edit ${number} --repo ${owner}/${repo} ${op === "add" ? "--add-label" : "--remove-label"} "${label}" 2>/dev/null || true`);
|
|
57921
|
-
}
|
|
57922
|
-
const addIssueLabel = (issueId, label) => editIssueLabel(issueId, "add", label);
|
|
57923
|
-
const removeIssueLabel = (issueId, label) => editIssueLabel(issueId, "remove", label);
|
|
57924
|
-
const applyIssueParkedLabel = (id) => addIssueLabel(id, PARKED_LABEL);
|
|
57925
|
-
const removeIssueParkedLabel = (id) => removeIssueLabel(id, PARKED_LABEL);
|
|
57926
|
-
const applyIssueVetoedLabel = (id) => addIssueLabel(id, VETOED_LABEL);
|
|
57927
|
-
const removeIssueVetoedLabel = (id) => removeIssueLabel(id, VETOED_LABEL);
|
|
57928
|
-
const applyIssueBlocksMainLabel = (id) => addIssueLabel(id, BLOCKS_MAIN_LABEL);
|
|
57929
|
-
const removeIssueBlocksMainLabel = (id) => removeIssueLabel(id, BLOCKS_MAIN_LABEL);
|
|
57930
|
-
const applyIssueReadyLabel = (id) => addIssueLabel(id, READY_LABEL);
|
|
57931
|
-
const removeIssueReadyLabel = (id) => removeIssueLabel(id, READY_LABEL);
|
|
57932
|
-
const applyIssueReleasedLabel = (id) => addIssueLabel(id, RELEASED_LABEL);
|
|
57933
|
-
const removeIssueReleasedLabel = (id) => removeIssueLabel(id, RELEASED_LABEL);
|
|
57934
|
-
const applyIssueObjectionLabel = (id) => addIssueLabel(id, OBJECTION_LABEL);
|
|
57935
|
-
const removeIssueObjectionLabel = (id) => removeIssueLabel(id, OBJECTION_LABEL);
|
|
57936
|
-
//#endregion
|
|
57937
57978
|
//#region ../../lib/database/agent-mappers.ts
|
|
57979
|
+
init_sequence_io();
|
|
57938
57980
|
function agentStateToDbAgent(state) {
|
|
57939
57981
|
return {
|
|
57940
57982
|
id: state.id,
|
|
@@ -57960,6 +58002,9 @@ function agentStateToDbAgent(state) {
|
|
|
57960
58002
|
paused: state.paused ?? null,
|
|
57961
58003
|
pausedReason: state.pausedReason ?? null,
|
|
57962
58004
|
pausedAt: state.pausedAt ?? null,
|
|
58005
|
+
yieldedByScheduler: state.yieldedByScheduler ?? null,
|
|
58006
|
+
yieldedAt: state.yieldedAt ?? null,
|
|
58007
|
+
lastYieldResumeAt: state.lastYieldResumeAt ?? null,
|
|
57963
58008
|
troubled: state.troubled ?? null,
|
|
57964
58009
|
troubledAt: state.troubledAt ?? null,
|
|
57965
58010
|
consecutiveFailures: state.consecutiveFailures ?? null,
|
|
@@ -58006,7 +58051,8 @@ const VALID_ROLES = new Set([
|
|
|
58006
58051
|
"test",
|
|
58007
58052
|
"ship",
|
|
58008
58053
|
"flywheel",
|
|
58009
|
-
"strike"
|
|
58054
|
+
"strike",
|
|
58055
|
+
"knowledge"
|
|
58010
58056
|
]);
|
|
58011
58057
|
const COLUMN_MAP = {
|
|
58012
58058
|
id: "id",
|
|
@@ -58032,6 +58078,9 @@ const COLUMN_MAP = {
|
|
|
58032
58078
|
paused: "paused",
|
|
58033
58079
|
pausedReason: "paused_reason",
|
|
58034
58080
|
pausedAt: "paused_at",
|
|
58081
|
+
yieldedByScheduler: "yielded_by_scheduler",
|
|
58082
|
+
yieldedAt: "yielded_at",
|
|
58083
|
+
lastYieldResumeAt: "last_yield_resume_at",
|
|
58035
58084
|
troubled: "troubled",
|
|
58036
58085
|
troubledAt: "troubled_at",
|
|
58037
58086
|
consecutiveFailures: "consecutive_failures",
|
|
@@ -58588,6 +58637,9 @@ function initSchema(db) {
|
|
|
58588
58637
|
paused INTEGER,
|
|
58589
58638
|
paused_reason TEXT,
|
|
58590
58639
|
paused_at TEXT,
|
|
58640
|
+
yielded_by_scheduler INTEGER,
|
|
58641
|
+
yielded_at TEXT,
|
|
58642
|
+
last_yield_resume_at TEXT,
|
|
58591
58643
|
troubled INTEGER,
|
|
58592
58644
|
troubled_at TEXT,
|
|
58593
58645
|
consecutive_failures INTEGER,
|
|
@@ -58877,7 +58929,7 @@ function initSchema(db) {
|
|
|
58877
58929
|
CREATE INDEX IF NOT EXISTS idx_backlog_sequence_project_rank
|
|
58878
58930
|
ON backlog_sequence(project_key, rank);
|
|
58879
58931
|
`);
|
|
58880
|
-
db.pragma(`user_version =
|
|
58932
|
+
db.pragma(`user_version = 59`);
|
|
58881
58933
|
}
|
|
58882
58934
|
/**
|
|
58883
58935
|
* Run schema migrations if the database version is older than SCHEMA_VERSION.
|
|
@@ -58885,7 +58937,7 @@ function initSchema(db) {
|
|
|
58885
58937
|
*/
|
|
58886
58938
|
function runMigrations(db, dbPath) {
|
|
58887
58939
|
const currentVersion = db.pragma("user_version", { simple: true });
|
|
58888
|
-
if (currentVersion >=
|
|
58940
|
+
if (currentVersion >= 59) return;
|
|
58889
58941
|
if (currentVersion === 0) {
|
|
58890
58942
|
initSchema(db);
|
|
58891
58943
|
return;
|
|
@@ -59619,7 +59671,18 @@ function runMigrations(db, dbPath) {
|
|
|
59619
59671
|
} catch {}
|
|
59620
59672
|
db.exec(`UPDATE discovered_sessions SET harness = 'claude-code' WHERE harness IS NULL`);
|
|
59621
59673
|
}
|
|
59622
|
-
|
|
59674
|
+
if (currentVersion < 59) {
|
|
59675
|
+
try {
|
|
59676
|
+
db.exec(`ALTER TABLE agents ADD COLUMN yielded_by_scheduler INTEGER`);
|
|
59677
|
+
} catch {}
|
|
59678
|
+
try {
|
|
59679
|
+
db.exec(`ALTER TABLE agents ADD COLUMN yielded_at TEXT`);
|
|
59680
|
+
} catch {}
|
|
59681
|
+
try {
|
|
59682
|
+
db.exec(`ALTER TABLE agents ADD COLUMN last_yield_resume_at TEXT`);
|
|
59683
|
+
} catch {}
|
|
59684
|
+
}
|
|
59685
|
+
db.pragma(`user_version = 59`);
|
|
59623
59686
|
}
|
|
59624
59687
|
//#endregion
|
|
59625
59688
|
//#region ../../lib/database/index.ts
|
|
@@ -61001,7 +61064,7 @@ async function pollOnce(state) {
|
|
|
61001
61064
|
try {
|
|
61002
61065
|
const remoteState = await readFile(join$1(homedir$1(), ".overdeck", "agents", agentId, "remote-state.json"), "utf-8").then((text) => JSON.parse(text)).catch(() => null);
|
|
61003
61066
|
if (remoteState?.location === "remote" && remoteState?.vmName) {
|
|
61004
|
-
const { getRemoteAgentOutput } = await import("./remote-agents-
|
|
61067
|
+
const { getRemoteAgentOutput } = await import("./remote-agents-YROPFM-n.js");
|
|
61005
61068
|
stdout = await getRemoteAgentOutput(agentId, remoteState.vmName, 50);
|
|
61006
61069
|
} else stdout = await Effect.runPromise(capturePane(agentId, 50));
|
|
61007
61070
|
} catch {
|
|
@@ -61074,7 +61137,8 @@ const BACKFILL_ROLES = new Set([
|
|
|
61074
61137
|
"work",
|
|
61075
61138
|
"review",
|
|
61076
61139
|
"test",
|
|
61077
|
-
"ship"
|
|
61140
|
+
"ship",
|
|
61141
|
+
"knowledge"
|
|
61078
61142
|
]);
|
|
61079
61143
|
const NON_AGENT_PREFIXES = [
|
|
61080
61144
|
"conv-",
|
|
@@ -62184,7 +62248,7 @@ const RESTART_MARKER = join(homedir(), ".overdeck", "dashboard-restarting.json")
|
|
|
62184
62248
|
* loads new content-hashed chunk filenames (no ERR_MODULE_NOT_FOUND after rebuild).
|
|
62185
62249
|
*/
|
|
62186
62250
|
async function defaultLifecycleRunner(pending) {
|
|
62187
|
-
const { postMergeLifecycle, notifyTldrDaemon } = await import("./merge-agent-
|
|
62251
|
+
const { postMergeLifecycle, notifyTldrDaemon } = await import("./merge-agent-DzbCbjqg.js");
|
|
62188
62252
|
await postMergeLifecycle(pending.issueId, pending.projectPath, pending.sourceBranch, { skipDeploy: true });
|
|
62189
62253
|
if (pending.sourceBranch) await notifyTldrDaemon(pending.projectPath, pending.sourceBranch);
|
|
62190
62254
|
}
|
|
@@ -62505,7 +62569,7 @@ function failureReason(result) {
|
|
|
62505
62569
|
return result.error ?? result.message ?? `merge returned status ${result.statusCode ?? "unknown"}`;
|
|
62506
62570
|
}
|
|
62507
62571
|
async function defaultMergeIssue(issueId) {
|
|
62508
|
-
const { triggerMerge } = await import("./merge-ops-
|
|
62572
|
+
const { triggerMerge } = await import("./merge-ops-CgzhHkd4.js");
|
|
62509
62573
|
return triggerMerge(issueId);
|
|
62510
62574
|
}
|
|
62511
62575
|
function defaultAnnounceFailure(issueId, reason) {
|
|
@@ -63142,7 +63206,7 @@ reconcileStaleGitHubBlockers().then((n) => {
|
|
|
63142
63206
|
}
|
|
63143
63207
|
}).catch((err) => console.warn(`[overdeck] Startup blocker reconciliation failed: ${err.message}`));
|
|
63144
63208
|
try {
|
|
63145
|
-
const { resetProcessingToQueued } = await import("./merge-sync-
|
|
63209
|
+
const { resetProcessingToQueued } = await import("./merge-sync-DD-v3GnC.js");
|
|
63146
63210
|
const resetCount = resetProcessingToQueued();
|
|
63147
63211
|
if (resetCount > 0) {
|
|
63148
63212
|
console.log(`[overdeck] Reset ${resetCount} stuck merge queue entries to queued`);
|