@kbediako/codex-orchestrator 0.1.38 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (311) hide show
  1. package/.agents/plugins/marketplace.json +20 -0
  2. package/README.md +46 -317
  3. package/bin/codex-orchestrator.js +161 -0
  4. package/codex.orchestrator.json +149 -13
  5. package/dist/bin/codex-orchestrator.js +797 -1154
  6. package/dist/orchestrator/src/cli/adapters/CommandBuilder.js +50 -0
  7. package/dist/orchestrator/src/cli/adapters/CommandPlanner.js +22 -4
  8. package/dist/orchestrator/src/cli/adapters/CommandReviewer.js +3 -3
  9. package/dist/orchestrator/src/cli/adapters/CommandTester.js +2 -2
  10. package/dist/orchestrator/src/cli/adapters/cloudFailureDiagnostics.js +295 -11
  11. package/dist/orchestrator/src/cli/coStatusAttachCliShell.js +402 -0
  12. package/dist/orchestrator/src/cli/coStatusCliShell.js +451 -0
  13. package/dist/orchestrator/src/cli/coStatusOperatorAutopilotCliShell.js +120 -0
  14. package/dist/orchestrator/src/cli/codexCliShell.js +119 -0
  15. package/dist/orchestrator/src/cli/codexDefaultsSetup.js +265 -36
  16. package/dist/orchestrator/src/cli/config/delegationConfig.js +317 -5
  17. package/dist/orchestrator/src/cli/config/repoConfigPolicy.js +2 -3
  18. package/dist/orchestrator/src/cli/config/userConfig.js +28 -13
  19. package/dist/orchestrator/src/cli/control/authenticatedControlRouteGate.js +69 -0
  20. package/dist/orchestrator/src/cli/control/authenticatedRouteComposition.js +267 -0
  21. package/dist/orchestrator/src/cli/control/authenticatedRouteController.js +5 -0
  22. package/dist/orchestrator/src/cli/control/authenticatedRouteDispatcher.js +41 -0
  23. package/dist/orchestrator/src/cli/control/compatibilityIssuePresenter.js +1035 -0
  24. package/dist/orchestrator/src/cli/control/confirmationApproveController.js +62 -0
  25. package/dist/orchestrator/src/cli/control/confirmationCreateController.js +69 -0
  26. package/dist/orchestrator/src/cli/control/confirmationIssueConsumeController.js +43 -0
  27. package/dist/orchestrator/src/cli/control/confirmationListController.js +22 -0
  28. package/dist/orchestrator/src/cli/control/confirmationValidateController.js +58 -0
  29. package/dist/orchestrator/src/cli/control/confirmations.js +25 -3
  30. package/dist/orchestrator/src/cli/control/controlActionCancelConfirmation.js +65 -0
  31. package/dist/orchestrator/src/cli/control/controlActionController.js +77 -0
  32. package/dist/orchestrator/src/cli/control/controlActionControllerSequencing.js +161 -0
  33. package/dist/orchestrator/src/cli/control/controlActionExecution.js +142 -0
  34. package/dist/orchestrator/src/cli/control/controlActionFinalization.js +43 -0
  35. package/dist/orchestrator/src/cli/control/controlActionOutcome.js +60 -0
  36. package/dist/orchestrator/src/cli/control/controlActionPreflight.js +476 -0
  37. package/dist/orchestrator/src/cli/control/controlAuthenticatedRouteHandoff.js +57 -0
  38. package/dist/orchestrator/src/cli/control/controlBootstrapAssembly.js +39 -0
  39. package/dist/orchestrator/src/cli/control/controlBootstrapMetadataPersistence.js +16 -0
  40. package/dist/orchestrator/src/cli/control/controlEventTransport.js +49 -0
  41. package/dist/orchestrator/src/cli/control/controlExpiryLifecycle.js +102 -0
  42. package/dist/orchestrator/src/cli/control/controlHostOwnership.js +480 -0
  43. package/dist/orchestrator/src/cli/control/controlHostSupervision.js +630 -0
  44. package/dist/orchestrator/src/cli/control/controlOversightFacade.js +8 -0
  45. package/dist/orchestrator/src/cli/control/controlOversightReadContract.js +1 -0
  46. package/dist/orchestrator/src/cli/control/controlOversightReadService.js +16 -0
  47. package/dist/orchestrator/src/cli/control/controlOversightUpdateContract.js +1 -0
  48. package/dist/orchestrator/src/cli/control/controlPersistenceFiles.js +6 -0
  49. package/dist/orchestrator/src/cli/control/controlQuestionChildResolution.js +18 -0
  50. package/dist/orchestrator/src/cli/control/controlRequestContext.js +42 -0
  51. package/dist/orchestrator/src/cli/control/controlRequestController.js +9 -0
  52. package/dist/orchestrator/src/cli/control/controlRequestPredispatch.js +17 -0
  53. package/dist/orchestrator/src/cli/control/controlRequestRouteDispatch.js +44 -0
  54. package/dist/orchestrator/src/cli/control/controlRuntime.js +1003 -0
  55. package/dist/orchestrator/src/cli/control/controlServer.js +23 -1456
  56. package/dist/orchestrator/src/cli/control/controlServerAuditAndErrorHelpers.js +115 -0
  57. package/dist/orchestrator/src/cli/control/controlServerAuthenticatedRouteBranch.js +29 -0
  58. package/dist/orchestrator/src/cli/control/controlServerBootstrapLifecycle.js +30 -0
  59. package/dist/orchestrator/src/cli/control/controlServerBootstrapStartSequence.js +21 -0
  60. package/dist/orchestrator/src/cli/control/controlServerOwnedRuntimeLifecycle.js +67 -0
  61. package/dist/orchestrator/src/cli/control/controlServerPublicLifecycle.js +756 -0
  62. package/dist/orchestrator/src/cli/control/controlServerPublicRouteHelpers.js +86 -0
  63. package/dist/orchestrator/src/cli/control/controlServerReadyInstanceLifecycle.js +25 -0
  64. package/dist/orchestrator/src/cli/control/controlServerReadyInstanceStartup.js +18 -0
  65. package/dist/orchestrator/src/cli/control/controlServerRequestBodyHelpers.js +37 -0
  66. package/dist/orchestrator/src/cli/control/controlServerRequestShell.js +40 -0
  67. package/dist/orchestrator/src/cli/control/controlServerRequestShellBinding.js +17 -0
  68. package/dist/orchestrator/src/cli/control/controlServerSeedLoading.js +27 -0
  69. package/dist/orchestrator/src/cli/control/controlServerSeededRuntimeAssembly.js +186 -0
  70. package/dist/orchestrator/src/cli/control/controlServerStartupInputPreparation.js +31 -0
  71. package/dist/orchestrator/src/cli/control/controlServerStartupSequence.js +49 -0
  72. package/dist/orchestrator/src/cli/control/controlState.js +233 -2
  73. package/dist/orchestrator/src/cli/control/controlStatusDashboard.js +1904 -0
  74. package/dist/orchestrator/src/cli/control/controlTelegramBridgeBootstrapLifecycle.js +22 -0
  75. package/dist/orchestrator/src/cli/control/controlTelegramBridgeLifecycle.js +67 -0
  76. package/dist/orchestrator/src/cli/control/controlTelegramBridgeOversightFacadeFactory.js +8 -0
  77. package/dist/orchestrator/src/cli/control/controlTelegramCommandController.js +49 -0
  78. package/dist/orchestrator/src/cli/control/controlTelegramDispatchRead.js +40 -0
  79. package/dist/orchestrator/src/cli/control/controlTelegramPollingController.js +89 -0
  80. package/dist/orchestrator/src/cli/control/controlTelegramProjectionNotificationController.js +29 -0
  81. package/dist/orchestrator/src/cli/control/controlTelegramPushState.js +63 -0
  82. package/dist/orchestrator/src/cli/control/controlTelegramQuestionRead.js +13 -0
  83. package/dist/orchestrator/src/cli/control/controlTelegramReadController.js +216 -0
  84. package/dist/orchestrator/src/cli/control/controlTelegramUpdateHandler.js +63 -0
  85. package/dist/orchestrator/src/cli/control/controlWatcher.js +73 -5
  86. package/dist/orchestrator/src/cli/control/delegationRegisterController.js +35 -0
  87. package/dist/orchestrator/src/cli/control/dynamicToolBridgePolicy.js +139 -0
  88. package/dist/orchestrator/src/cli/control/eventsSseController.js +12 -0
  89. package/dist/orchestrator/src/cli/control/linearBudgetState.js +1789 -0
  90. package/dist/orchestrator/src/cli/control/linearDispatchSource.js +1137 -0
  91. package/dist/orchestrator/src/cli/control/linearGraphqlClient.js +150 -0
  92. package/dist/orchestrator/src/cli/control/linearRateLimit.js +102 -0
  93. package/dist/orchestrator/src/cli/control/linearWebhookController.js +499 -0
  94. package/dist/orchestrator/src/cli/control/liveLinearAdvisoryRuntime.js +70 -0
  95. package/dist/orchestrator/src/cli/control/observabilityApiController.js +173 -0
  96. package/dist/orchestrator/src/cli/control/observabilityReadModel.js +500 -0
  97. package/dist/orchestrator/src/cli/control/observabilitySurface.js +284 -0
  98. package/dist/orchestrator/src/cli/control/observabilityUpdateNotifier.js +22 -0
  99. package/dist/orchestrator/src/cli/control/operatorDashboardPresenter.js +252 -0
  100. package/dist/orchestrator/src/cli/control/providerAgentCapacity.js +70 -0
  101. package/dist/orchestrator/src/cli/control/providerControlHostFreshnessGauge.js +1068 -0
  102. package/dist/orchestrator/src/cli/control/providerIntakeState.js +473 -0
  103. package/dist/orchestrator/src/cli/control/providerIssueHandoff.js +6811 -0
  104. package/dist/orchestrator/src/cli/control/providerIssueObservability.js +1348 -0
  105. package/dist/orchestrator/src/cli/control/providerIssueRetryQueue.js +84 -0
  106. package/dist/orchestrator/src/cli/control/providerLinearRuntimeProof.js +588 -0
  107. package/dist/orchestrator/src/cli/control/providerLinearScreenshotProof.js +473 -0
  108. package/dist/orchestrator/src/cli/control/providerLinearWorkerTruth.js +383 -0
  109. package/dist/orchestrator/src/cli/control/providerLinearWorkflowAudit.js +254 -0
  110. package/dist/orchestrator/src/cli/control/providerLinearWorkflowFacade.js +5573 -0
  111. package/dist/orchestrator/src/cli/control/providerLinearWorkflowStates.js +115 -0
  112. package/dist/orchestrator/src/cli/control/providerMergeCloseout.js +1868 -0
  113. package/dist/orchestrator/src/cli/control/providerOperatorAutopilot.js +1580 -0
  114. package/dist/orchestrator/src/cli/control/providerOperatorAutopilotLifecycle.js +154 -0
  115. package/dist/orchestrator/src/cli/control/providerOperatorAutopilotLocalRolloutExecution.js +1006 -0
  116. package/dist/orchestrator/src/cli/control/providerPollingHealth.js +435 -0
  117. package/dist/orchestrator/src/cli/control/providerTerminalCleanup.js +516 -0
  118. package/dist/orchestrator/src/cli/control/providerWorkerHosts.js +191 -0
  119. package/dist/orchestrator/src/cli/control/providerWorkflowConfigStore.js +515 -0
  120. package/dist/orchestrator/src/cli/control/questionChildResolutionAdapter.js +361 -0
  121. package/dist/orchestrator/src/cli/control/questionQueueController.js +181 -0
  122. package/dist/orchestrator/src/cli/control/questionReadRetryDeduplication.js +9 -0
  123. package/dist/orchestrator/src/cli/control/questionReadSequence.js +10 -0
  124. package/dist/orchestrator/src/cli/control/securityViolationController.js +27 -0
  125. package/dist/orchestrator/src/cli/control/selectedRunProjection.js +1885 -0
  126. package/dist/orchestrator/src/cli/control/telegramOversightApiClient.js +48 -0
  127. package/dist/orchestrator/src/cli/control/telegramOversightBridge.js +180 -0
  128. package/dist/orchestrator/src/cli/control/telegramOversightBridgeProjectionDeliveryQueue.js +25 -0
  129. package/dist/orchestrator/src/cli/control/telegramOversightBridgeRuntimeLifecycle.js +45 -0
  130. package/dist/orchestrator/src/cli/control/telegramOversightBridgeStateStore.js +77 -0
  131. package/dist/orchestrator/src/cli/control/telegramOversightControlActionApiClient.js +45 -0
  132. package/dist/orchestrator/src/cli/control/trackerDispatchPilot.js +439 -0
  133. package/dist/orchestrator/src/cli/control/uiDataController.js +34 -0
  134. package/dist/orchestrator/src/cli/control/uiSessionController.js +100 -0
  135. package/dist/orchestrator/src/cli/controlHostCliShell.js +860 -0
  136. package/dist/orchestrator/src/cli/controlHostFreshnessGaugeCliShell.js +129 -0
  137. package/dist/orchestrator/src/cli/controlHostSupervisionCliShell.js +2127 -0
  138. package/dist/orchestrator/src/cli/delegationCliShell.js +62 -0
  139. package/dist/orchestrator/src/cli/delegationServer.js +567 -678
  140. package/dist/orchestrator/src/cli/delegationServerCliShell.js +52 -0
  141. package/dist/orchestrator/src/cli/delegationServerQuestionFlowShell.js +228 -0
  142. package/dist/orchestrator/src/cli/delegationServerToolDispatchShell.js +411 -0
  143. package/dist/orchestrator/src/cli/delegationServerTransport.js +274 -0
  144. package/dist/orchestrator/src/cli/delegationSetup.js +51 -171
  145. package/dist/orchestrator/src/cli/devtoolsCliShell.js +34 -0
  146. package/dist/orchestrator/src/cli/doctor.js +678 -164
  147. package/dist/orchestrator/src/cli/doctorCliRequestShell.js +72 -0
  148. package/dist/orchestrator/src/cli/doctorCliShell.js +138 -0
  149. package/dist/orchestrator/src/cli/doctorUsage.js +119 -15
  150. package/dist/orchestrator/src/cli/exec/experience.js +16 -2
  151. package/dist/orchestrator/src/cli/exec/summary.js +3 -0
  152. package/dist/orchestrator/src/cli/execCliShell.js +51 -0
  153. package/dist/orchestrator/src/cli/flowCliRequestShell.js +44 -0
  154. package/dist/orchestrator/src/cli/flowCliShell.js +239 -0
  155. package/dist/orchestrator/src/cli/frontendTestCliRequestShell.js +80 -0
  156. package/dist/orchestrator/src/cli/frontendTestCliShell.js +41 -0
  157. package/dist/orchestrator/src/cli/init.js +95 -1
  158. package/dist/orchestrator/src/cli/initCliShell.js +50 -0
  159. package/dist/orchestrator/src/cli/linearCliShell.js +1200 -0
  160. package/dist/orchestrator/src/cli/mcpEnableCliShell.js +132 -0
  161. package/dist/orchestrator/src/cli/metrics/metricsAggregator.js +3 -2
  162. package/dist/orchestrator/src/cli/metrics/metricsRecorder.js +56 -0
  163. package/dist/orchestrator/src/cli/orchestrator.js +66 -1376
  164. package/dist/orchestrator/src/cli/planCliShell.js +19 -0
  165. package/dist/orchestrator/src/cli/prCliShell.js +41 -0
  166. package/dist/orchestrator/src/cli/providerLinearChildLanePhaseContract.js +204 -0
  167. package/dist/orchestrator/src/cli/providerLinearChildLaneRunner.js +1835 -0
  168. package/dist/orchestrator/src/cli/providerLinearChildLaneShell.js +2420 -0
  169. package/dist/orchestrator/src/cli/providerLinearChildStreamShell.js +385 -0
  170. package/dist/orchestrator/src/cli/providerLinearWorkerRunner.js +6834 -0
  171. package/dist/orchestrator/src/cli/resumeCliShell.js +14 -0
  172. package/dist/orchestrator/src/cli/reviewCliLaunchShell.js +72 -0
  173. package/dist/orchestrator/src/cli/rlm/alignment.js +3 -3
  174. package/dist/orchestrator/src/cli/rlm/context.js +94 -7
  175. package/dist/orchestrator/src/cli/rlm/rlmCodexRuntimeShell.js +546 -0
  176. package/dist/orchestrator/src/cli/rlm/symbolic.js +4 -2
  177. package/dist/orchestrator/src/cli/rlmCliRequestShell.js +42 -0
  178. package/dist/orchestrator/src/cli/rlmCompletionCliShell.js +46 -0
  179. package/dist/orchestrator/src/cli/rlmLaunchCliShell.js +51 -0
  180. package/dist/orchestrator/src/cli/rlmRunner.js +83 -523
  181. package/dist/orchestrator/src/cli/run/blockMemory.js +500 -0
  182. package/dist/orchestrator/src/cli/run/manifest.js +410 -73
  183. package/dist/orchestrator/src/cli/run/manifestPersister.js +45 -14
  184. package/dist/orchestrator/src/cli/run/runMemoryController.js +216 -0
  185. package/dist/orchestrator/src/cli/run/source0.js +690 -0
  186. package/dist/orchestrator/src/cli/run/workspacePath.js +101 -0
  187. package/dist/orchestrator/src/cli/runtime/mode.js +2 -1
  188. package/dist/orchestrator/src/cli/runtime/provider.js +39 -2
  189. package/dist/orchestrator/src/cli/selfCheckCliShell.js +12 -0
  190. package/dist/orchestrator/src/cli/services/commandRunner.js +698 -18
  191. package/dist/orchestrator/src/cli/services/execRuntime.js +66 -1
  192. package/dist/orchestrator/src/cli/services/orchestratorAutoScoutEvidenceRecorder.js +71 -0
  193. package/dist/orchestrator/src/cli/services/orchestratorCloudBranchResolution.js +8 -0
  194. package/dist/orchestrator/src/cli/services/orchestratorCloudEnvironmentResolution.js +22 -0
  195. package/dist/orchestrator/src/cli/services/orchestratorCloudExecutionLifecycleShell.js +39 -0
  196. package/dist/orchestrator/src/cli/services/orchestratorCloudPromptBuilder.js +37 -0
  197. package/dist/orchestrator/src/cli/services/orchestratorCloudRouteFallbackContract.js +45 -0
  198. package/dist/orchestrator/src/cli/services/orchestratorCloudRouteShell.js +36 -0
  199. package/dist/orchestrator/src/cli/services/orchestratorCloudTargetExecutor.js +277 -0
  200. package/dist/orchestrator/src/cli/services/orchestratorControlPlaneLifecycle.js +98 -0
  201. package/dist/orchestrator/src/cli/services/orchestratorControlPlaneLifecycleShell.js +54 -0
  202. package/dist/orchestrator/src/cli/services/orchestratorExecutionLifecycle.js +112 -0
  203. package/dist/orchestrator/src/cli/services/orchestratorExecutionModePolicy.js +27 -0
  204. package/dist/orchestrator/src/cli/services/orchestratorExecutionRouteAdapterShell.js +59 -0
  205. package/dist/orchestrator/src/cli/services/orchestratorExecutionRouteDecisionShell.js +57 -0
  206. package/dist/orchestrator/src/cli/services/orchestratorExecutionRouteState.js +21 -0
  207. package/dist/orchestrator/src/cli/services/orchestratorExecutionRouter.js +2 -0
  208. package/dist/orchestrator/src/cli/services/orchestratorLocalPipelineExecutor.js +149 -0
  209. package/dist/orchestrator/src/cli/services/orchestratorLocalRouteShell.js +63 -0
  210. package/dist/orchestrator/src/cli/services/orchestratorPlanShell.js +54 -0
  211. package/dist/orchestrator/src/cli/services/orchestratorPlanTargetTracker.js +16 -0
  212. package/dist/orchestrator/src/cli/services/orchestratorResumePreparationShell.js +84 -0
  213. package/dist/orchestrator/src/cli/services/orchestratorResumeTokenValidation.js +15 -0
  214. package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleCompletion.js +31 -0
  215. package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleExecutionRegistration.js +37 -0
  216. package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleOrchestrationShell.js +83 -0
  217. package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleTaskManagerShell.js +37 -0
  218. package/dist/orchestrator/src/cli/services/orchestratorRuntimeManifestMutation.js +20 -0
  219. package/dist/orchestrator/src/cli/services/orchestratorStartPreparationShell.js +56 -0
  220. package/dist/orchestrator/src/cli/services/orchestratorStatusShell.js +70 -0
  221. package/dist/orchestrator/src/cli/services/pipelineResolver.js +7 -3
  222. package/dist/orchestrator/src/cli/services/plannerMemory.js +119 -0
  223. package/dist/orchestrator/src/cli/services/runPreparation.js +7 -3
  224. package/dist/orchestrator/src/cli/services/runSummaryWriter.js +9 -0
  225. package/dist/orchestrator/src/cli/setupBootstrapShell.js +114 -0
  226. package/dist/orchestrator/src/cli/setupCliShell.js +51 -0
  227. package/dist/orchestrator/src/cli/skillsCliShell.js +56 -0
  228. package/dist/orchestrator/src/cli/startCliRequestShell.js +53 -0
  229. package/dist/orchestrator/src/cli/startCliShell.js +68 -0
  230. package/dist/orchestrator/src/cli/statusCliShell.js +22 -0
  231. package/dist/orchestrator/src/cli/utils/authProvenanceFingerprint.js +27 -0
  232. package/dist/orchestrator/src/cli/utils/cloudPreflight.js +285 -7
  233. package/dist/orchestrator/src/cli/utils/codexFeatures.js +60 -0
  234. package/dist/orchestrator/src/cli/utils/delegationConfigParser.js +250 -0
  235. package/dist/orchestrator/src/cli/utils/delegationMcpHealth.js +1382 -0
  236. package/dist/orchestrator/src/cli/utils/devtools.js +2 -54
  237. package/dist/orchestrator/src/cli/utils/mcpServerEntry.js +53 -0
  238. package/dist/orchestrator/src/cli/utils/packageProgramResolver.js +151 -0
  239. package/dist/orchestrator/src/cli/utils/providerOverrideEnv.js +71 -0
  240. package/dist/orchestrator/src/cli/utils/trailingJsonObject.js +59 -0
  241. package/dist/orchestrator/src/learning/crystalizer.js +2 -2
  242. package/dist/orchestrator/src/manager.js +74 -4
  243. package/dist/orchestrator/src/persistence/ExperienceStore.js +233 -49
  244. package/dist/orchestrator/src/persistence/TaskStateStore.js +6 -6
  245. package/dist/orchestrator/src/persistence/lockFile.js +70 -4
  246. package/dist/orchestrator/src/persistence/sanitizeIdentifier.js +39 -0
  247. package/dist/orchestrator/src/sync/createCloudSyncWorker.js +3 -2
  248. package/dist/orchestrator/src/utils/atomicWrite.js +17 -2
  249. package/dist/packages/orchestrator/src/exec/unified-exec.js +99 -6
  250. package/dist/packages/orchestrator/src/instructions/promptPacks.js +150 -19
  251. package/dist/packages/sdk-node/src/orchestrator.js +137 -13
  252. package/dist/packages/shared/config/designConfig.js +8 -1
  253. package/dist/packages/shared/streams/stdio.js +1 -1
  254. package/dist/scripts/design/pipeline/permit.js +15 -0
  255. package/dist/scripts/lib/docs-catalog.js +399 -0
  256. package/dist/scripts/lib/docs-helpers.js +87 -5
  257. package/dist/scripts/lib/pr-watch-merge.js +1088 -80
  258. package/dist/scripts/lib/provider-run-contract.js +26 -0
  259. package/dist/scripts/lib/review-command-intent-classification.js +532 -0
  260. package/dist/scripts/lib/review-command-probe-classification.js +385 -0
  261. package/dist/scripts/lib/review-execution-boundary-preflight.js +279 -0
  262. package/dist/scripts/lib/review-execution-runtime.js +753 -0
  263. package/dist/scripts/lib/review-execution-state.js +1144 -0
  264. package/dist/scripts/lib/review-execution-telemetry.js +215 -0
  265. package/dist/scripts/lib/review-inspection-target-parsing.js +78 -0
  266. package/dist/scripts/lib/review-launch-attempt.js +601 -0
  267. package/dist/scripts/lib/review-meta-surface-boundary-analysis.js +300 -0
  268. package/dist/scripts/lib/review-meta-surface-normalization.js +746 -0
  269. package/dist/scripts/lib/review-non-interactive-handoff.js +61 -0
  270. package/dist/scripts/lib/review-prompt-context.js +376 -0
  271. package/dist/scripts/lib/review-scope-advisory.js +286 -0
  272. package/dist/scripts/lib/review-scope-paths.js +123 -0
  273. package/dist/scripts/lib/review-shell-command-parser.js +389 -0
  274. package/dist/scripts/lib/review-shell-env-interpreter.js +340 -0
  275. package/dist/scripts/lib/run-manifests.js +192 -36
  276. package/dist/scripts/lib/spark-policy-classifier.js +593 -0
  277. package/dist/scripts/run-review.js +507 -1777
  278. package/docs/README.md +43 -20
  279. package/docs/book/README.md +19 -0
  280. package/docs/book/codex-cli-0124-adoption.md +68 -0
  281. package/docs/book/local-hook-impact.md +73 -0
  282. package/docs/book/operations.md +60 -0
  283. package/docs/book/public-posture.md +34 -0
  284. package/docs/book/setup.md +91 -0
  285. package/docs/book/skills.md +11 -0
  286. package/docs/guides/codex-version-policy.md +104 -0
  287. package/docs/public/downstream-setup.md +113 -0
  288. package/docs/public/provider-onboarding.md +173 -0
  289. package/package.json +23 -10
  290. package/plugins/codex-orchestrator/.codex-plugin/plugin.json +30 -0
  291. package/plugins/codex-orchestrator/.mcp.json +13 -0
  292. package/plugins/codex-orchestrator/launcher.mjs +361 -0
  293. package/schemas/manifest.json +411 -0
  294. package/skills/README.md +26 -0
  295. package/skills/collab-subagents-first/SKILL.md +1 -1
  296. package/skills/delegation-usage/DELEGATION_GUIDE.md +30 -12
  297. package/skills/delegation-usage/SKILL.md +25 -14
  298. package/skills/land/SKILL.md +77 -0
  299. package/skills/linear/SKILL.md +255 -0
  300. package/skills/release/SKILL.md +47 -3
  301. package/skills/standalone-review/SKILL.md +6 -1
  302. package/templates/README.md +4 -2
  303. package/templates/codex/.codex/agents/awaiter-high.toml +2 -2
  304. package/templates/codex/.codex/agents/worker-complex.toml +1 -1
  305. package/templates/codex/.codex/config.toml +3 -4
  306. package/templates/codex/.codex/providers/README.md +13 -0
  307. package/templates/codex/.codex/providers/control.example.json +18 -0
  308. package/templates/codex/.codex/providers/provider.env.example +15 -0
  309. package/templates/codex/AGENTS.md +15 -8
  310. package/templates/codex/mcp-client.json +5 -1
  311. package/docs/assets/setup.gif +0 -0
@@ -0,0 +1,1904 @@
1
+ import { mkdir, writeFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import process from 'node:process';
4
+ import { logger } from '../../logger.js';
5
+ import { evaluateInteractiveGate } from '../utils/interactive.js';
6
+ import { readUiDataset } from './operatorDashboardPresenter.js';
7
+ const graphemeSegmenter = typeof Intl !== 'undefined' && typeof Intl.Segmenter === 'function'
8
+ ? new Intl.Segmenter(undefined, { granularity: 'grapheme' })
9
+ : null;
10
+ const combiningMarkPattern = /^\p{Mark}$/u;
11
+ const extendedPictographicPattern = /\p{Extended_Pictographic}/u;
12
+ const keycapPattern = /^[0-9#*]\uFE0F?\u20E3$/u;
13
+ const ANSI_CLEAR_HOME = '\u001b[H\u001b[2J';
14
+ const ANSI_CLEAR_DOWN = '\u001b[J';
15
+ const ANSI_ENTER_ALT_SCREEN = '\u001b[?1049h';
16
+ const ANSI_EXIT_ALT_SCREEN = '\u001b[?1049l';
17
+ const ANSI_RESET = '\u001b[0m';
18
+ const ANSI_BOLD = '\u001b[1m';
19
+ const ANSI_BLUE = '\u001b[34m';
20
+ const ANSI_CYAN = '\u001b[36m';
21
+ const ANSI_DIM = '\u001b[2m';
22
+ const ANSI_GREEN = '\u001b[32m';
23
+ const ANSI_MAGENTA = '\u001b[35m';
24
+ const ANSI_RED = '\u001b[31m';
25
+ const ANSI_YELLOW = '\u001b[33m';
26
+ const ANSI_GRAY = '\u001b[90m';
27
+ const ANSI_CLEAR_CONTROL = '\u001b';
28
+ const ANSI_CLEAR_BELL = '\u0007';
29
+ const CONTROL_CHARACTER_CLASS = `${String.fromCharCode(0x00)}-${String.fromCharCode(0x1f)}${String.fromCharCode(0x7f)}-${String.fromCharCode(0x9f)}`;
30
+ const ANSI_CONTROL_SEQUENCE_PATTERN = new RegExp(`${ANSI_CLEAR_CONTROL}(?:\\[[0-?]*[ -/]*[@-~]|\\][^${ANSI_CLEAR_BELL}${ANSI_CLEAR_CONTROL}]*(?:${ANSI_CLEAR_BELL}|${ANSI_CLEAR_CONTROL}\\\\)|[@-Z\\\\-_])`, 'g');
31
+ const CONTROL_CHARACTER_PATTERN = new RegExp(`[${CONTROL_CHARACTER_CLASS}]`, 'g');
32
+ const DEFAULT_REFRESH_INTERVAL_MS = 1_000;
33
+ const DEFAULT_TERMINAL_COLUMNS = 115;
34
+ const THROUGHPUT_WINDOW_MS = 5_000;
35
+ const DEFAULT_OUTPUT = process.stdout;
36
+ const DEFAULT_INPUT = process.stdin;
37
+ const NUMBER_FORMAT = new Intl.NumberFormat('en-US');
38
+ const DASHBOARD_SNAPSHOT_DIRNAME = 'co-status-snapshots';
39
+ const DEFAULT_DEPENDENCIES = {
40
+ readDataset: async (runtime) => await readUiDataset({
41
+ readCompatibilityProjection: async () => await runtime.snapshot().readCompatibilityProjection()
42
+ }),
43
+ setTimeout,
44
+ clearTimeout,
45
+ now: () => new Date()
46
+ };
47
+ export function shouldEnableControlStatusDashboard(input) {
48
+ return evaluateInteractiveGate({
49
+ requested: true,
50
+ format: input.format,
51
+ stdoutIsTTY: input.stdoutIsTTY,
52
+ stderrIsTTY: input.stderrIsTTY,
53
+ term: input.term,
54
+ // CO STATUS is a real terminal surface, so inherited CI markers should
55
+ // not suppress it when both output streams are interactive.
56
+ env: input.env === undefined
57
+ ? undefined
58
+ : {
59
+ ...input.env,
60
+ CI: undefined
61
+ }
62
+ }).enabled;
63
+ }
64
+ export function startControlStatusDashboard(options, overrides = {}) {
65
+ const deps = { ...DEFAULT_DEPENDENCIES, ...overrides };
66
+ const liveOutput = options.output ?? DEFAULT_OUTPUT;
67
+ return startControlStatusViewer({
68
+ readDataset: async () => await deps.readDataset(options.runtime),
69
+ requestRefresh: async () => {
70
+ await options.runtime.requestRefresh();
71
+ },
72
+ subscribe: (listener) => options.runtime.subscribe(listener),
73
+ baseUrl: options.baseUrl,
74
+ taskId: options.taskId,
75
+ runId: options.runId,
76
+ runDir: options.runDir,
77
+ startPipelineId: options.startPipelineId,
78
+ refreshIntervalMs: options.refreshIntervalMs,
79
+ output: options.output,
80
+ input: options.input,
81
+ liveSurfaceMode: liveOutput.isTTY === true ? 'alternate' : 'primary',
82
+ showDashboardLine: false
83
+ }, deps);
84
+ }
85
+ export function startAttachedControlStatusDashboard(options, overrides = {}) {
86
+ const deps = { ...DEFAULT_DEPENDENCIES, ...overrides };
87
+ return startControlStatusViewer({
88
+ readDataset: options.readDataset,
89
+ requestRefresh: null,
90
+ subscribe: null,
91
+ baseUrl: options.baseUrl,
92
+ taskId: options.taskId,
93
+ runId: options.runId,
94
+ runDir: options.runDir,
95
+ startPipelineId: options.startPipelineId,
96
+ refreshIntervalMs: options.refreshIntervalMs,
97
+ output: options.output,
98
+ input: options.input,
99
+ liveSurfaceMode: 'primary',
100
+ showDashboardLine: false
101
+ }, deps);
102
+ }
103
+ function startControlStatusViewer(options, deps) {
104
+ const refreshIntervalMs = Math.max(250, options.refreshIntervalMs ?? DEFAULT_REFRESH_INTERVAL_MS);
105
+ const output = options.output ?? DEFAULT_OUTPUT;
106
+ const input = options.input ?? DEFAULT_INPUT;
107
+ let stopped = false;
108
+ let timer = null;
109
+ let activeRender = null;
110
+ let activeReadController = null;
111
+ let queuedRender = false;
112
+ let queuedForceRefresh = false;
113
+ let queuedReadDataset = false;
114
+ let queuedUseCachedFrame = false;
115
+ let tokenSamples = [];
116
+ let renderedState = null;
117
+ let escapeSequenceState = 'idle';
118
+ const liveSurfaceMode = options.liveSurfaceMode ?? 'primary';
119
+ const enablePinnedPrimaryLiveRegion = liveSurfaceMode === 'primary' && output.isTTY === true;
120
+ let activeSurfaceMode = 'primary';
121
+ let activePrimaryFrame = null;
122
+ let primarySurfacePromptNeedsNewline = false;
123
+ let frameState = {
124
+ paused: false,
125
+ pausedLiveReferenceTime: null,
126
+ viewMode: 'full',
127
+ surfaceMode: liveSurfaceMode,
128
+ pendingUpdate: false,
129
+ snapshotStatus: 'idle',
130
+ snapshotPath: null,
131
+ snapshotMessage: null
132
+ };
133
+ let snapshotWrite = null;
134
+ const queueRender = (forceRefresh, useCachedFrame) => {
135
+ if (stopped) {
136
+ return;
137
+ }
138
+ queuedForceRefresh = queuedForceRefresh || forceRefresh;
139
+ queuedReadDataset = queuedReadDataset || forceRefresh || !useCachedFrame;
140
+ queuedUseCachedFrame = queuedUseCachedFrame || useCachedFrame;
141
+ if (activeRender) {
142
+ queuedRender = true;
143
+ return;
144
+ }
145
+ startQueuedRender();
146
+ };
147
+ const requestRender = (forceRefresh) => {
148
+ if (stopped) {
149
+ return;
150
+ }
151
+ if (frameState.paused) {
152
+ frameState = {
153
+ ...frameState,
154
+ pendingUpdate: true
155
+ };
156
+ return;
157
+ }
158
+ queueRender(forceRefresh, false);
159
+ };
160
+ const requestCachedFrameRender = () => {
161
+ if (stopped) {
162
+ return;
163
+ }
164
+ queueRender(false, true);
165
+ };
166
+ const clearQueuedRenderState = () => {
167
+ const hadQueuedRender = queuedRender || queuedForceRefresh || queuedReadDataset || queuedUseCachedFrame;
168
+ queuedRender = false;
169
+ queuedForceRefresh = false;
170
+ queuedReadDataset = false;
171
+ queuedUseCachedFrame = false;
172
+ return hadQueuedRender;
173
+ };
174
+ const startQueuedRender = () => {
175
+ const forceRefresh = queuedForceRefresh;
176
+ const useCachedFrame = queuedUseCachedFrame && !queuedReadDataset && !forceRefresh;
177
+ queuedRender = false;
178
+ queuedForceRefresh = false;
179
+ queuedReadDataset = false;
180
+ queuedUseCachedFrame = false;
181
+ activeRender = renderFrame(forceRefresh, useCachedFrame).finally(() => {
182
+ activeRender = null;
183
+ if (stopped || !queuedRender) {
184
+ return;
185
+ }
186
+ startQueuedRender();
187
+ });
188
+ };
189
+ const scheduleTick = () => {
190
+ if (stopped) {
191
+ return;
192
+ }
193
+ timer = deps.setTimeout(() => {
194
+ timer = null;
195
+ if (stopped) {
196
+ return;
197
+ }
198
+ requestRender(true);
199
+ if (stopped) {
200
+ return;
201
+ }
202
+ scheduleTick();
203
+ }, refreshIntervalMs);
204
+ timer.unref?.();
205
+ };
206
+ const unsubscribe = options.subscribe?.(() => {
207
+ requestRender(false);
208
+ }) ?? (() => undefined);
209
+ const detachInput = attachInteractiveInput();
210
+ requestRender(true);
211
+ scheduleTick();
212
+ return {
213
+ stop() {
214
+ stopped = true;
215
+ queuedRender = false;
216
+ queuedForceRefresh = false;
217
+ activeReadController?.abort();
218
+ if (timer) {
219
+ deps.clearTimeout(timer);
220
+ timer = null;
221
+ }
222
+ detachInput();
223
+ unsubscribe();
224
+ if (activeSurfaceMode === 'alternate') {
225
+ output.write(`${ANSI_EXIT_ALT_SCREEN}${primarySurfacePromptNeedsNewline ? '\n' : ''}`);
226
+ activeSurfaceMode = 'primary';
227
+ }
228
+ else if (primarySurfacePromptNeedsNewline || activePrimaryFrame !== null) {
229
+ output.write('\n');
230
+ }
231
+ activePrimaryFrame = null;
232
+ primarySurfacePromptNeedsNewline = false;
233
+ },
234
+ async flush() {
235
+ await activeRender;
236
+ await snapshotWrite;
237
+ await activeRender;
238
+ }
239
+ };
240
+ function attachInteractiveInput() {
241
+ if (input.isTTY !== true || typeof input.on !== 'function' || typeof input.off !== 'function') {
242
+ return () => undefined;
243
+ }
244
+ let rawModeEnabled = false;
245
+ const onData = (chunk) => {
246
+ void handleInputChunk(chunk);
247
+ };
248
+ try {
249
+ input.setRawMode?.(true);
250
+ rawModeEnabled = true;
251
+ }
252
+ catch {
253
+ return () => undefined;
254
+ }
255
+ input.resume?.();
256
+ input.on('data', onData);
257
+ return () => {
258
+ input.off('data', onData);
259
+ if (rawModeEnabled) {
260
+ try {
261
+ input.setRawMode?.(false);
262
+ }
263
+ catch {
264
+ // Ignore TTY restore failures during shutdown.
265
+ }
266
+ }
267
+ input.pause?.();
268
+ };
269
+ }
270
+ async function handleInputChunk(chunk) {
271
+ const text = Buffer.isBuffer(chunk) ? chunk.toString('utf8') : String(chunk);
272
+ for (const character of text) {
273
+ if (escapeSequenceState === 'escape') {
274
+ if (character === '[' || character === 'O') {
275
+ escapeSequenceState = 'control';
276
+ continue;
277
+ }
278
+ escapeSequenceState = 'idle';
279
+ continue;
280
+ }
281
+ if (escapeSequenceState === 'control') {
282
+ if (character >= '@' && character <= '~') {
283
+ escapeSequenceState = 'idle';
284
+ }
285
+ continue;
286
+ }
287
+ if (character === '\u001b') {
288
+ escapeSequenceState = 'escape';
289
+ continue;
290
+ }
291
+ if (character === '\u0003') {
292
+ process.kill(process.pid, 'SIGINT');
293
+ return;
294
+ }
295
+ if (isControlCharacter(character)) {
296
+ continue;
297
+ }
298
+ const key = character.toLowerCase();
299
+ if (key === 'p') {
300
+ const enteringPaused = !frameState.paused;
301
+ frameState = {
302
+ ...frameState,
303
+ paused: enteringPaused,
304
+ pausedLiveReferenceTime: enteringPaused && renderedState ? deriveLiveReferenceTime(renderedState, deps.now()) : null,
305
+ surfaceMode: enteringPaused ? 'primary' : liveSurfaceMode
306
+ };
307
+ if (frameState.paused) {
308
+ if (activeRender) {
309
+ const hadQueuedRender = clearQueuedRenderState();
310
+ frameState = {
311
+ ...frameState,
312
+ pendingUpdate: frameState.pendingUpdate || hadQueuedRender
313
+ };
314
+ if (renderedState) {
315
+ queuedRender = true;
316
+ queuedUseCachedFrame = true;
317
+ }
318
+ continue;
319
+ }
320
+ requestCachedFrameRender();
321
+ }
322
+ else {
323
+ const shouldForceRefresh = frameState.pendingUpdate;
324
+ frameState = {
325
+ ...frameState,
326
+ pendingUpdate: false
327
+ };
328
+ queueRender(shouldForceRefresh, false);
329
+ }
330
+ continue;
331
+ }
332
+ if (key === 'c') {
333
+ frameState = {
334
+ ...frameState,
335
+ viewMode: frameState.viewMode === 'full' ? 'compact' : 'full'
336
+ };
337
+ requestCachedFrameRender();
338
+ continue;
339
+ }
340
+ if (key === 's') {
341
+ if (!snapshotWrite) {
342
+ snapshotWrite = exportSnapshot().finally(() => {
343
+ snapshotWrite = null;
344
+ });
345
+ }
346
+ }
347
+ }
348
+ }
349
+ async function exportSnapshot() {
350
+ if (!renderedState) {
351
+ return;
352
+ }
353
+ const timestamp = formatSnapshotTimestamp(deps.now());
354
+ const snapshotDir = join(options.runDir, DASHBOARD_SNAPSHOT_DIRNAME);
355
+ const snapshotPath = join(snapshotDir, `co-status-${timestamp}.txt`);
356
+ try {
357
+ await mkdir(snapshotDir, { recursive: true });
358
+ const frame = renderControlStatusFrame({
359
+ dataset: renderedState.dataset,
360
+ baseUrl: options.baseUrl,
361
+ taskId: options.taskId,
362
+ runId: options.runId,
363
+ runDir: options.runDir,
364
+ startPipelineId: options.startPipelineId,
365
+ showDashboardLine: options.showDashboardLine,
366
+ terminalColumns: output.columns ?? null,
367
+ terminalRows: output.rows ?? null,
368
+ throughputTps: renderedState.throughputTps,
369
+ referenceTime: renderedState.referenceTime,
370
+ liveReferenceTime: resolveDisplayedLiveReferenceTime(renderedState, frameState, deps.now()),
371
+ paused: frameState.paused,
372
+ viewMode: frameState.viewMode,
373
+ surfaceMode: frameState.surfaceMode,
374
+ pendingUpdate: frameState.pendingUpdate,
375
+ snapshotStatus: 'saved',
376
+ snapshotPath,
377
+ snapshotMessage: 'saved'
378
+ });
379
+ await writeFile(snapshotPath, `${stripAnsiSequences(frame)}\n`, 'utf8');
380
+ frameState = {
381
+ ...frameState,
382
+ snapshotStatus: 'saved',
383
+ snapshotPath,
384
+ snapshotMessage: 'saved'
385
+ };
386
+ }
387
+ catch (error) {
388
+ frameState = {
389
+ ...frameState,
390
+ snapshotStatus: 'failed',
391
+ snapshotMessage: sanitizeDisplayValue(error?.message ?? String(error))
392
+ };
393
+ }
394
+ requestCachedFrameRender();
395
+ }
396
+ async function renderFrame(forceRefresh, useCachedFrame) {
397
+ try {
398
+ if (useCachedFrame && renderedState && !forceRefresh) {
399
+ const frame = renderControlStatusFrame({
400
+ dataset: renderedState.dataset,
401
+ baseUrl: options.baseUrl,
402
+ taskId: options.taskId,
403
+ runId: options.runId,
404
+ runDir: options.runDir,
405
+ startPipelineId: options.startPipelineId,
406
+ showDashboardLine: options.showDashboardLine,
407
+ terminalColumns: output.columns ?? null,
408
+ terminalRows: output.rows ?? null,
409
+ throughputTps: renderedState.throughputTps,
410
+ referenceTime: renderedState.referenceTime,
411
+ liveReferenceTime: resolveDisplayedLiveReferenceTime(renderedState, frameState, deps.now()),
412
+ paused: frameState.paused,
413
+ viewMode: frameState.viewMode,
414
+ surfaceMode: frameState.surfaceMode,
415
+ pendingUpdate: frameState.pendingUpdate,
416
+ snapshotStatus: frameState.snapshotStatus,
417
+ snapshotPath: frameState.snapshotPath,
418
+ snapshotMessage: frameState.snapshotMessage
419
+ });
420
+ writeFrame(frame);
421
+ return;
422
+ }
423
+ if (forceRefresh) {
424
+ await options.requestRefresh?.();
425
+ }
426
+ if (stopped) {
427
+ return;
428
+ }
429
+ const readController = new AbortController();
430
+ activeReadController = readController;
431
+ const dataset = await options.readDataset(readController.signal).finally(() => {
432
+ if (activeReadController === readController) {
433
+ activeReadController = null;
434
+ }
435
+ });
436
+ if (stopped) {
437
+ return;
438
+ }
439
+ const now = deps.now();
440
+ const referenceTime = resolveReferenceTime(undefined, dataset.generated_at, now);
441
+ const liveClockStartedAt = renderedState && renderedState.dataset.generated_at === dataset.generated_at
442
+ ? renderedState.liveClockStartedAt
443
+ : now;
444
+ tokenSamples = appendTokenSample(tokenSamples, now.getTime(), dataset.totals.total_tokens);
445
+ const throughputTps = rollingTokensPerSecond(tokenSamples);
446
+ const nextRenderedState = {
447
+ dataset,
448
+ referenceTime,
449
+ liveClockStartedAt,
450
+ throughputTps
451
+ };
452
+ if (frameState.paused && renderedState) {
453
+ frameState = {
454
+ ...frameState,
455
+ pendingUpdate: true
456
+ };
457
+ return;
458
+ }
459
+ const liveReferenceTime = frameState.paused && frameState.pausedLiveReferenceTime === null
460
+ ? deriveLiveReferenceTime(nextRenderedState, now)
461
+ : resolveDisplayedLiveReferenceTime(nextRenderedState, frameState, now);
462
+ renderedState = nextRenderedState;
463
+ frameState = {
464
+ ...frameState,
465
+ pausedLiveReferenceTime: frameState.paused && frameState.pausedLiveReferenceTime === null
466
+ ? liveReferenceTime
467
+ : frameState.pausedLiveReferenceTime,
468
+ pendingUpdate: frameState.paused ? frameState.pendingUpdate : false
469
+ };
470
+ const frame = renderControlStatusFrame({
471
+ dataset,
472
+ baseUrl: options.baseUrl,
473
+ taskId: options.taskId,
474
+ runId: options.runId,
475
+ runDir: options.runDir,
476
+ startPipelineId: options.startPipelineId,
477
+ showDashboardLine: options.showDashboardLine,
478
+ terminalColumns: output.columns ?? null,
479
+ terminalRows: output.rows ?? null,
480
+ throughputTps,
481
+ referenceTime,
482
+ liveReferenceTime,
483
+ paused: frameState.paused,
484
+ viewMode: frameState.viewMode,
485
+ surfaceMode: frameState.surfaceMode,
486
+ pendingUpdate: frameState.pendingUpdate,
487
+ snapshotStatus: frameState.snapshotStatus,
488
+ snapshotPath: frameState.snapshotPath,
489
+ snapshotMessage: frameState.snapshotMessage
490
+ });
491
+ writeFrame(frame);
492
+ }
493
+ catch (error) {
494
+ const message = error?.message ?? String(error);
495
+ if (stopped) {
496
+ return;
497
+ }
498
+ logger.warn(`Failed rendering CO STATUS dashboard frame: ${message}`);
499
+ writeFrame(renderControlStatusErrorFrame(options, deps.now(), message, output.columns ?? null));
500
+ }
501
+ }
502
+ function writeFrame(frame) {
503
+ if (frameState.surfaceMode === 'alternate') {
504
+ activePrimaryFrame = null;
505
+ if (activeSurfaceMode !== 'alternate') {
506
+ activeSurfaceMode = 'alternate';
507
+ output.write(`${ANSI_ENTER_ALT_SCREEN}${ANSI_CLEAR_HOME}${frame}`);
508
+ return;
509
+ }
510
+ output.write(`${ANSI_CLEAR_HOME}${frame}`);
511
+ return;
512
+ }
513
+ if (activeSurfaceMode === 'alternate') {
514
+ activeSurfaceMode = 'primary';
515
+ activePrimaryFrame = null;
516
+ primarySurfacePromptNeedsNewline = false;
517
+ output.write(`${ANSI_EXIT_ALT_SCREEN}${ANSI_CLEAR_HOME}${frame}\n`);
518
+ return;
519
+ }
520
+ primarySurfacePromptNeedsNewline = true;
521
+ if (enablePinnedPrimaryLiveRegion) {
522
+ if (activePrimaryFrame !== null) {
523
+ const viewportRows = resolveTerminalRows(output.rows ?? null);
524
+ const previousRowCount = countFrameRows(activePrimaryFrame, output.columns ?? null);
525
+ const currentRowCount = countFrameRows(frame, output.columns ?? null);
526
+ if (previousRowCount > viewportRows || currentRowCount > viewportRows) {
527
+ output.write(`${ANSI_CLEAR_HOME}${frame}`);
528
+ }
529
+ else {
530
+ output.write(rewritePrimaryFrame(frame, previousRowCount));
531
+ }
532
+ }
533
+ else {
534
+ output.write(frame);
535
+ }
536
+ activePrimaryFrame = frame;
537
+ return;
538
+ }
539
+ activePrimaryFrame = null;
540
+ output.write(`${ANSI_CLEAR_HOME}${frame}`);
541
+ }
542
+ }
543
+ function countFrameRows(frame, terminalColumns) {
544
+ if (frame.length === 0) {
545
+ return 0;
546
+ }
547
+ const columns = resolveTerminalColumns(terminalColumns);
548
+ return frame
549
+ .split('\n')
550
+ .reduce((rowCount, line) => rowCount + countWrappedTerminalRows(stripAnsiSequences(line), columns), 0);
551
+ }
552
+ function countWrappedTerminalRows(line, terminalColumns) {
553
+ if (terminalColumns <= 0) {
554
+ return 1;
555
+ }
556
+ return Math.max(1, Math.ceil(measureTerminalDisplayWidth(line) / terminalColumns));
557
+ }
558
+ function measureTerminalDisplayWidth(line) {
559
+ if (line.length === 0) {
560
+ return 0;
561
+ }
562
+ if (graphemeSegmenter === null) {
563
+ return Array.from(line).reduce((width, grapheme) => width + measureTerminalGraphemeWidth(grapheme), 0);
564
+ }
565
+ let width = 0;
566
+ for (const { segment } of graphemeSegmenter.segment(line)) {
567
+ width += measureTerminalGraphemeWidth(segment);
568
+ }
569
+ return width;
570
+ }
571
+ function measureTerminalGraphemeWidth(grapheme) {
572
+ if (grapheme.length === 0) {
573
+ return 0;
574
+ }
575
+ if (containsExtendedPictographic(grapheme) || isRegionalIndicatorCluster(grapheme) || isKeycapCluster(grapheme)) {
576
+ return 2;
577
+ }
578
+ let width = 0;
579
+ for (const char of grapheme) {
580
+ width += measureTerminalCodePointWidth(char);
581
+ }
582
+ return width;
583
+ }
584
+ function measureTerminalCodePointWidth(char) {
585
+ const codePoint = char.codePointAt(0);
586
+ if (codePoint === undefined || isZeroWidthCodePoint(codePoint) || combiningMarkPattern.test(char)) {
587
+ return 0;
588
+ }
589
+ return isFullwidthCodePoint(codePoint) ? 2 : 1;
590
+ }
591
+ function containsExtendedPictographic(value) {
592
+ return extendedPictographicPattern.test(value);
593
+ }
594
+ function isRegionalIndicatorCluster(value) {
595
+ const codePoints = Array.from(value, (char) => char.codePointAt(0) ?? 0);
596
+ return codePoints.length > 0 && codePoints.every((codePoint) => codePoint >= 0x1f1e6 && codePoint <= 0x1f1ff);
597
+ }
598
+ function isKeycapCluster(value) {
599
+ return keycapPattern.test(value);
600
+ }
601
+ function isZeroWidthCodePoint(codePoint) {
602
+ return (codePoint < 0x20 ||
603
+ (codePoint >= 0x7f && codePoint < 0xa0) ||
604
+ codePoint === 0x200b ||
605
+ codePoint === 0x200c ||
606
+ codePoint === 0x200d ||
607
+ codePoint === 0x2060 ||
608
+ (codePoint >= 0xfe00 && codePoint <= 0xfe0f) ||
609
+ (codePoint >= 0xe0100 && codePoint <= 0xe01ef));
610
+ }
611
+ function isFullwidthCodePoint(codePoint) {
612
+ return (codePoint >= 0x1100 &&
613
+ (codePoint <= 0x115f ||
614
+ codePoint === 0x2329 ||
615
+ codePoint === 0x232a ||
616
+ (codePoint >= 0x2e80 && codePoint <= 0x3247 && codePoint !== 0x303f) ||
617
+ (codePoint >= 0x3250 && codePoint <= 0x4dbf) ||
618
+ (codePoint >= 0x4e00 && codePoint <= 0xa4c6) ||
619
+ (codePoint >= 0xa960 && codePoint <= 0xa97c) ||
620
+ (codePoint >= 0xac00 && codePoint <= 0xd7a3) ||
621
+ (codePoint >= 0xf900 && codePoint <= 0xfaff) ||
622
+ (codePoint >= 0xfe10 && codePoint <= 0xfe19) ||
623
+ (codePoint >= 0xfe30 && codePoint <= 0xfe6b) ||
624
+ (codePoint >= 0xff01 && codePoint <= 0xff60) ||
625
+ (codePoint >= 0xffe0 && codePoint <= 0xffe6) ||
626
+ (codePoint >= 0x1b000 && codePoint <= 0x1b001) ||
627
+ (codePoint >= 0x1f200 && codePoint <= 0x1f251) ||
628
+ (codePoint >= 0x20000 && codePoint <= 0x3fffd)));
629
+ }
630
+ function rewritePrimaryFrame(frame, previousRowCount) {
631
+ let prefix = '\r';
632
+ if (previousRowCount > 1) {
633
+ prefix += `\u001b[${previousRowCount - 1}A`;
634
+ }
635
+ return `${prefix}${ANSI_CLEAR_DOWN}${frame}`;
636
+ }
637
+ export function renderControlStatusFrame(input) {
638
+ const referenceTime = resolveReferenceTime(input.referenceTime, input.dataset.generated_at);
639
+ const liveReferenceTime = resolveLiveReferenceTime(input.liveReferenceTime, referenceTime);
640
+ const terminalColumns = resolveTerminalColumns(input.terminalColumns);
641
+ const terminalRows = resolveTerminalRows(input.terminalRows);
642
+ const frameState = {
643
+ paused: input.paused === true,
644
+ pausedLiveReferenceTime: null,
645
+ viewMode: input.viewMode ?? 'full',
646
+ surfaceMode: input.surfaceMode ?? (input.paused === true ? 'primary' : 'alternate'),
647
+ pendingUpdate: input.pendingUpdate === true,
648
+ snapshotStatus: input.snapshotStatus ?? 'idle',
649
+ snapshotPath: input.snapshotPath ?? null,
650
+ snapshotMessage: input.snapshotMessage ?? null
651
+ };
652
+ if (frameState.viewMode === 'compact') {
653
+ return renderCompactControlStatusFrame(input, referenceTime, liveReferenceTime, terminalColumns, terminalRows, frameState);
654
+ }
655
+ const runningColumns = selectRunningColumns(terminalColumns);
656
+ const lines = [
657
+ colorize('╭─ CO STATUS', ANSI_BOLD),
658
+ renderAgentsLine(input.dataset, terminalColumns),
659
+ renderThroughputLine(input.throughputTps ?? 0, terminalColumns),
660
+ renderRuntimeLine(input.dataset, referenceTime, liveReferenceTime, terminalColumns),
661
+ renderTokensLine(input.dataset, terminalColumns),
662
+ renderRateLimitsLine(input.dataset, referenceTime, terminalColumns),
663
+ renderProjectLine(input.dataset, terminalColumns),
664
+ renderNextRefreshLine(input.dataset, liveReferenceTime, terminalColumns),
665
+ colorize('├─ Running', ANSI_BOLD),
666
+ '│',
667
+ renderRunningHeaderRow(runningColumns),
668
+ renderRunningSeparatorRow(runningColumns)
669
+ ];
670
+ lines.push(...renderRunningRows(input.dataset.running, runningColumns, liveReferenceTime));
671
+ lines.push('│');
672
+ lines.push(colorize('├─ Backoff queue', ANSI_BOLD));
673
+ lines.push('│');
674
+ lines.push(...renderRetryRows(input.dataset.retrying, referenceTime, terminalColumns));
675
+ lines.push('│');
676
+ lines.push(colorize('├─ Status controls', ANSI_BOLD));
677
+ lines.push(renderControlsLine(terminalColumns, frameState));
678
+ lines.push(renderInspectLine(terminalColumns, frameState, linesWillExceedTerminalHeight(terminalRows, lines.length + 3) && frameState.viewMode === 'full'));
679
+ lines.push(renderSnapshotLine(terminalColumns, frameState));
680
+ lines.push('╰─');
681
+ return lines.join('\n');
682
+ }
683
+ function renderCompactControlStatusFrame(input, referenceTime, liveReferenceTime, terminalColumns, terminalRows, frameState) {
684
+ const lines = [
685
+ colorize('╭─ CO STATUS', ANSI_BOLD),
686
+ renderCompactStatusLine(input.dataset, referenceTime, liveReferenceTime, terminalColumns),
687
+ renderTokensLine(input.dataset, terminalColumns),
688
+ renderRateLimitsLine(input.dataset, referenceTime, terminalColumns),
689
+ renderCompactRunningLine(input.dataset.running, liveReferenceTime, terminalColumns),
690
+ renderCompactRetryLine(input.dataset.retrying, referenceTime, terminalColumns),
691
+ renderControlsLine(terminalColumns, frameState),
692
+ renderInspectLine(terminalColumns, frameState, linesWillExceedTerminalHeight(terminalRows, 10)),
693
+ renderSnapshotLine(terminalColumns, frameState),
694
+ '╰─'
695
+ ];
696
+ return lines.join('\n');
697
+ }
698
+ function renderControlStatusErrorFrame(input, now, message, terminalColumns) {
699
+ const safe = (value) => sanitizeDisplayValue(value);
700
+ const columns = resolveTerminalColumns(terminalColumns);
701
+ const lines = [
702
+ colorize('╭─ CO STATUS', ANSI_BOLD),
703
+ renderSummaryLine('Generated', [{ text: now.toISOString(), color: ANSI_CYAN }], columns),
704
+ renderSummaryLine('Task', [
705
+ { text: safe(input.taskId), color: ANSI_CYAN },
706
+ { text: ' | ', color: ANSI_GRAY },
707
+ { text: 'Run: ', color: ANSI_BOLD },
708
+ { text: safe(input.runId), color: ANSI_CYAN }
709
+ ], columns),
710
+ renderSummaryLine('Pipeline', [
711
+ { text: safe(input.startPipelineId), color: ANSI_CYAN },
712
+ { text: ' | ', color: ANSI_GRAY },
713
+ { text: 'Run dir: ', color: ANSI_BOLD },
714
+ { text: safe(input.runDir), color: ANSI_CYAN, truncateMode: 'middle' }
715
+ ], columns),
716
+ renderSummaryLine('Dashboard error', [{ text: safe(message), color: ANSI_RED }], columns),
717
+ '╰─'
718
+ ];
719
+ return lines.join('\n');
720
+ }
721
+ function renderAgentsLine(dataset, terminalColumns) {
722
+ const maxAllowed = resolveMaxAllowedAgents(dataset);
723
+ return renderSummaryLine('Agents', [
724
+ { text: formatCount(dataset.counts.running), color: ANSI_GREEN },
725
+ { text: '/', color: ANSI_GRAY },
726
+ { text: `${formatOptionalCount(maxAllowed)} max allowed`, color: ANSI_GRAY }
727
+ ], terminalColumns);
728
+ }
729
+ function renderThroughputLine(throughputTps, terminalColumns) {
730
+ return renderSummaryLine('Throughput', [{ text: `${formatTps(throughputTps)} tps`, color: ANSI_CYAN }], terminalColumns);
731
+ }
732
+ function renderRuntimeLine(dataset, referenceTime, liveReferenceTime, terminalColumns) {
733
+ return renderSummaryLine('Runtime', [{ text: formatLiveRuntimeSeconds(dataset, referenceTime, liveReferenceTime), color: ANSI_MAGENTA }], terminalColumns);
734
+ }
735
+ function renderTokensLine(dataset, terminalColumns) {
736
+ return renderSummaryLine('Tokens', [
737
+ { text: `in ${formatOptionalCount(dataset.totals.input_tokens)}`, color: ANSI_YELLOW },
738
+ { text: ' | ', color: ANSI_GRAY },
739
+ { text: `out ${formatOptionalCount(dataset.totals.output_tokens)}`, color: ANSI_YELLOW },
740
+ { text: ' | ', color: ANSI_GRAY },
741
+ { text: `total ${formatOptionalCount(dataset.totals.total_tokens)}`, color: ANSI_YELLOW },
742
+ { text: ' | ', color: ANSI_GRAY },
743
+ {
744
+ text: `reasoning ${formatOptionalCount(dataset.totals.reasoning_output_tokens)}`,
745
+ color: ANSI_YELLOW
746
+ }
747
+ ], terminalColumns);
748
+ }
749
+ function renderRateLimitsLine(dataset, referenceTime, terminalColumns) {
750
+ return renderSummaryLine('Rate Limits', formatRateLimitSegments(dataset.rate_limits, referenceTime), terminalColumns);
751
+ }
752
+ function renderProjectLine(dataset, terminalColumns) {
753
+ const project = resolveProjectLabel(dataset);
754
+ return renderSummaryLine('Project', [{ text: project, color: project === 'n/a' ? ANSI_GRAY : ANSI_CYAN }], terminalColumns);
755
+ }
756
+ function renderNextRefreshLine(dataset, liveReferenceTime, terminalColumns) {
757
+ const nextRefreshText = resolveNextRefreshSummaryText(dataset.polling);
758
+ const freshnessSegments = buildPollingFreshnessSegments(dataset.polling, liveReferenceTime);
759
+ if (nextRefreshText === 'checking now...') {
760
+ return renderSummaryLine('Next refresh', [{ text: 'checking now...', color: ANSI_CYAN }, ...freshnessSegments], terminalColumns);
761
+ }
762
+ if (nextRefreshText) {
763
+ return renderSummaryLine('Next refresh', [{ text: nextRefreshText, color: ANSI_CYAN }, ...freshnessSegments], terminalColumns);
764
+ }
765
+ return renderSummaryLine('Next refresh', [{ text: 'n/a', color: ANSI_GRAY }, ...freshnessSegments], terminalColumns);
766
+ }
767
+ function renderCompactStatusLine(dataset, referenceTime, liveReferenceTime, terminalColumns) {
768
+ const maxAllowed = resolveMaxAllowedAgents(dataset);
769
+ const nextRefreshText = resolveNextRefreshSummaryText(dataset.polling);
770
+ const sourceFreshnessText = resolvePollingSourceFreshnessText(dataset.polling, liveReferenceTime);
771
+ const refreshText = nextRefreshText === null
772
+ ? 'next n/a'
773
+ : nextRefreshText === 'checking now...'
774
+ ? nextRefreshText
775
+ : `next ${nextRefreshText}`;
776
+ const freshnessColor = resolvePollingSourceFreshnessColor(dataset.polling, liveReferenceTime);
777
+ return renderSummaryLine('Status', [
778
+ {
779
+ text: `${formatCount(dataset.counts.running)}/${formatOptionalCount(maxAllowed)} max allowed`,
780
+ color: ANSI_GREEN
781
+ },
782
+ { text: ' | ', color: ANSI_GRAY },
783
+ { text: formatLiveRuntimeSeconds(dataset, referenceTime, liveReferenceTime), color: ANSI_MAGENTA },
784
+ { text: ' | ', color: ANSI_GRAY },
785
+ { text: refreshText, color: ANSI_CYAN },
786
+ ...(sourceFreshnessText
787
+ ? [
788
+ { text: ' | ', color: ANSI_GRAY },
789
+ { text: sourceFreshnessText, color: freshnessColor }
790
+ ]
791
+ : [])
792
+ ], terminalColumns);
793
+ }
794
+ function resolveNextRefreshSummaryText(polling) {
795
+ const hasProjectedState = polling?.next_refresh_state !== undefined && polling?.next_refresh_state !== null;
796
+ const projectedState = polling?.next_refresh_state === 'cooldown' ||
797
+ polling?.next_refresh_state === 'checking' ||
798
+ polling?.next_refresh_state === 'scheduled' ||
799
+ polling?.next_refresh_state === 'unknown'
800
+ ? polling.next_refresh_state
801
+ : null;
802
+ const projectedCountdown = typeof polling?.next_refresh_in_ms === 'number' &&
803
+ Number.isFinite(polling.next_refresh_in_ms) &&
804
+ polling.next_refresh_in_ms >= 0
805
+ ? polling.next_refresh_in_ms
806
+ : null;
807
+ if (projectedState === 'checking') {
808
+ return 'checking now...';
809
+ }
810
+ if (projectedState === 'unknown') {
811
+ return null;
812
+ }
813
+ if ((projectedState === 'cooldown' || projectedState === 'scheduled') &&
814
+ projectedCountdown !== null) {
815
+ return formatCountdownMs(projectedCountdown);
816
+ }
817
+ if (hasProjectedState) {
818
+ return null;
819
+ }
820
+ if (polling?.checking) {
821
+ return 'checking now...';
822
+ }
823
+ if (typeof polling?.next_poll_in_ms === 'number' &&
824
+ Number.isFinite(polling.next_poll_in_ms) &&
825
+ polling.next_poll_in_ms >= 0) {
826
+ return formatCountdownMs(polling.next_poll_in_ms);
827
+ }
828
+ return null;
829
+ }
830
+ function buildPollingFreshnessSegments(polling, liveReferenceTime) {
831
+ const freshnessText = resolvePollingSourceFreshnessText(polling, liveReferenceTime);
832
+ if (!freshnessText) {
833
+ return [];
834
+ }
835
+ return [
836
+ { text: ' | ', color: ANSI_GRAY },
837
+ {
838
+ text: freshnessText,
839
+ color: resolvePollingSourceFreshnessColor(polling, liveReferenceTime)
840
+ }
841
+ ];
842
+ }
843
+ function resolvePollingSourceFreshnessText(polling, liveReferenceTime) {
844
+ const freshnessAge = formatRelativePast(polling?.source_updated_at ?? null, liveReferenceTime);
845
+ return freshnessAge === null ? null : `source ${freshnessAge} old`;
846
+ }
847
+ function resolvePollingSourceFreshnessColor(polling, liveReferenceTime) {
848
+ const sourceUpdatedAtMs = parseTimestamp(polling?.source_updated_at ?? null);
849
+ const intervalMs = typeof polling?.interval_ms === 'number' && Number.isFinite(polling.interval_ms) && polling.interval_ms > 0
850
+ ? polling.interval_ms
851
+ : null;
852
+ const referenceMs = liveReferenceTime.getTime();
853
+ if (sourceUpdatedAtMs === null || intervalMs === null || !Number.isFinite(referenceMs)) {
854
+ return ANSI_GRAY;
855
+ }
856
+ return referenceMs - sourceUpdatedAtMs > intervalMs ? ANSI_YELLOW : ANSI_GRAY;
857
+ }
858
+ function renderCompactRunningLine(entries, referenceTime, terminalColumns) {
859
+ if (entries.length === 0) {
860
+ return renderSummaryLine('Running', [{ text: 'No active agents', color: ANSI_GRAY }], terminalColumns);
861
+ }
862
+ const [entry] = [...entries].sort((left, right) => left.issue_identifier.localeCompare(right.issue_identifier));
863
+ return renderSummaryLine('Running', [
864
+ { text: sanitizeDisplayValue(entry.issue_identifier), color: ANSI_CYAN },
865
+ { text: ' | ', color: ANSI_GRAY },
866
+ { text: sanitizeDisplayValue(entry.display_state), color: resolveRunningAccent(entry) },
867
+ { text: ' | ', color: ANSI_GRAY },
868
+ { text: summarizeRunningEvent(entry, referenceTime), color: ANSI_GRAY, truncateMode: 'end' }
869
+ ], terminalColumns);
870
+ }
871
+ function renderCompactRetryLine(entries, referenceTime, terminalColumns) {
872
+ if (entries.length === 0) {
873
+ return renderSummaryLine('Retry', [{ text: 'No queued retries', color: ANSI_GRAY }], terminalColumns);
874
+ }
875
+ const [entry] = [...entries].sort((left, right) => compareDueAt(left.due_at, right.due_at));
876
+ return renderSummaryLine('Retry', [
877
+ { text: sanitizeDisplayValue(entry.issue_identifier), color: ANSI_RED },
878
+ { text: ' | ', color: ANSI_GRAY },
879
+ { text: `${summarizeRetryHeadline(entry)} in ${formatRelativeDue(entry.due_at, referenceTime)}`, color: ANSI_CYAN },
880
+ { text: ' | ', color: ANSI_GRAY },
881
+ { text: summarizeRetryDetail(entry), color: ANSI_GRAY, truncateMode: 'end' }
882
+ ], terminalColumns);
883
+ }
884
+ function renderControlsLine(terminalColumns, frameState) {
885
+ return renderSummaryLine('Controls', [
886
+ { text: `p ${frameState.paused ? 'resume live redraw' : 'freeze live redraw'}`, color: ANSI_CYAN },
887
+ { text: ' | ', color: ANSI_GRAY },
888
+ { text: `c ${frameState.viewMode === 'full' ? 'compact inspect' : 'full frame'}`, color: ANSI_CYAN },
889
+ { text: ' | ', color: ANSI_GRAY },
890
+ { text: 's snapshot export', color: ANSI_CYAN }
891
+ ], terminalColumns);
892
+ }
893
+ function renderInspectLine(terminalColumns, frameState, frameExceedsTerminalHeight) {
894
+ const surfaceLabel = frameState.surfaceMode === 'alternate'
895
+ ? 'alternate screen'
896
+ : frameState.paused
897
+ ? 'primary snapshot'
898
+ : 'primary scrollback';
899
+ const segments = [
900
+ { text: frameState.paused ? 'paused' : 'live', color: frameState.paused ? ANSI_YELLOW : ANSI_GREEN },
901
+ { text: ' | ', color: ANSI_GRAY },
902
+ { text: surfaceLabel, color: frameState.surfaceMode === 'alternate' ? ANSI_BLUE : ANSI_MAGENTA },
903
+ { text: ' | ', color: ANSI_GRAY },
904
+ { text: frameState.viewMode === 'compact' ? 'compact inspect' : 'full frame', color: ANSI_CYAN }
905
+ ];
906
+ if (frameState.pendingUpdate) {
907
+ segments.push({ text: ' | ', color: ANSI_GRAY });
908
+ segments.push({ text: 'updates waiting', color: ANSI_YELLOW });
909
+ }
910
+ if (frameExceedsTerminalHeight && frameState.viewMode === 'full') {
911
+ segments.push({ text: ' | ', color: ANSI_GRAY });
912
+ segments.push({ text: 'short terminal: pause then compact', color: ANSI_RED });
913
+ }
914
+ return renderSummaryLine('Inspect', segments, terminalColumns);
915
+ }
916
+ function renderSnapshotLine(terminalColumns, frameState) {
917
+ if (frameState.snapshotStatus === 'saved' && frameState.snapshotPath) {
918
+ return renderSummaryLine('Snapshot', [
919
+ { text: 'saved', color: ANSI_GREEN },
920
+ { text: ' | ', color: ANSI_GRAY },
921
+ { text: frameState.snapshotPath, color: ANSI_CYAN, truncateMode: 'middle' }
922
+ ], terminalColumns);
923
+ }
924
+ if (frameState.snapshotStatus === 'failed') {
925
+ return renderSummaryLine('Snapshot', [
926
+ { text: 'save failed', color: ANSI_RED },
927
+ { text: ' | ', color: ANSI_GRAY },
928
+ { text: frameState.snapshotMessage ?? 'unknown error', color: ANSI_GRAY, truncateMode: 'end' }
929
+ ], terminalColumns);
930
+ }
931
+ return renderSummaryLine('Snapshot', [{ text: 'press s to export a stable frame under run dir', color: ANSI_GRAY, truncateMode: 'end' }], terminalColumns);
932
+ }
933
+ function renderRunningHeaderRow(columns) {
934
+ const labels = columns.map((column) => formatCell(column.label, column.width));
935
+ return `│ ${colorize(labels.join(' '), ANSI_GRAY)}`;
936
+ }
937
+ function renderRunningSeparatorRow(columns) {
938
+ const separatorWidth = columns.reduce((sum, column) => sum + column.width, 0) + Math.max(0, columns.length - 1);
939
+ return `│ ${colorize('─'.repeat(separatorWidth), ANSI_GRAY)}`;
940
+ }
941
+ function renderRunningRows(entries, columns, referenceTime) {
942
+ if (entries.length === 0) {
943
+ return [`│ ${colorize('No active agents', ANSI_GRAY)}`];
944
+ }
945
+ return [...entries]
946
+ .sort((left, right) => left.issue_identifier.localeCompare(right.issue_identifier))
947
+ .map((entry) => renderRunningRow(entry, columns, referenceTime));
948
+ }
949
+ function renderRunningRow(entry, columns, referenceTime) {
950
+ const accent = resolveRunningAccent(entry);
951
+ const cells = columns.map((column) => {
952
+ const value = formatRunningColumnValue(entry, column.key, referenceTime);
953
+ const formatted = formatCell(value, column.width, column.align);
954
+ switch (column.key) {
955
+ case 'id':
956
+ return colorize(formatted, ANSI_CYAN);
957
+ case 'age':
958
+ return colorize(formatted, ANSI_MAGENTA);
959
+ case 'tokens':
960
+ return colorize(formatted, ANSI_YELLOW);
961
+ case 'pid':
962
+ return colorize(formatted, ANSI_YELLOW);
963
+ case 'session':
964
+ return colorize(formatted, ANSI_CYAN);
965
+ case 'stage':
966
+ case 'event':
967
+ return colorize(formatted, accent);
968
+ default:
969
+ return formatted;
970
+ }
971
+ });
972
+ return `│ ${colorize('●', accent)} ${cells.join(' ')}`;
973
+ }
974
+ function renderRetryRows(entries, referenceTime, terminalColumns) {
975
+ if (entries.length === 0) {
976
+ return [`│ ${colorize('No queued retries', ANSI_GRAY)}`];
977
+ }
978
+ return [...entries]
979
+ .sort((left, right) => compareDueAt(left.due_at, right.due_at))
980
+ .map((entry) => renderRetryRow(entry, referenceTime, terminalColumns));
981
+ }
982
+ function renderRetryRow(entry, referenceTime, terminalColumns) {
983
+ const issueIdentifier = sanitizeDisplayValue(entry.issue_identifier);
984
+ const attempt = formatNullable(entry.attempt);
985
+ const relativeDue = formatRelativeDue(entry.due_at, referenceTime);
986
+ const plainPrefix = `│ ↻ ${issueIdentifier} `;
987
+ const coloredPrefix = `│ ${colorize('↻', ANSI_YELLOW)} ${colorize(issueIdentifier, ANSI_RED)} `;
988
+ const detail = summarizeRetryDetail(entry);
989
+ const segments = [
990
+ { text: summarizeRetryHeadline(entry), color: ANSI_YELLOW },
991
+ { text: ' in ', color: ANSI_DIM },
992
+ { text: relativeDue, color: ANSI_CYAN }
993
+ ];
994
+ if (attempt !== '-') {
995
+ segments.push({ text: ' | ', color: ANSI_GRAY });
996
+ segments.push({ text: `attempt ${attempt}`, color: ANSI_YELLOW });
997
+ }
998
+ if (detail !== 'n/a') {
999
+ segments.push({ text: ' | ', color: ANSI_GRAY });
1000
+ segments.push({ text: detail, color: ANSI_GRAY, truncateMode: 'end' });
1001
+ }
1002
+ return coloredPrefix + colorizeSummarySegments(segments, Math.max(0, terminalColumns - plainPrefix.length));
1003
+ }
1004
+ function resolveRunningAccent(entry) {
1005
+ const lastEvent = normalizeRunningEventKey(entry.last_event) ?? '';
1006
+ const displayState = sanitizeDisplayValue(entry.display_state).toLowerCase();
1007
+ if (lastEvent.includes('turn_completed')) {
1008
+ return ANSI_MAGENTA;
1009
+ }
1010
+ if (lastEvent.includes('task_started') || lastEvent.includes('turn_started')) {
1011
+ return ANSI_GREEN;
1012
+ }
1013
+ if (lastEvent.includes('token')) {
1014
+ return ANSI_YELLOW;
1015
+ }
1016
+ if (displayState.includes('retry')) {
1017
+ return ANSI_BLUE;
1018
+ }
1019
+ if (displayState.includes('fail') || displayState.includes('error')) {
1020
+ return ANSI_RED;
1021
+ }
1022
+ return ANSI_BLUE;
1023
+ }
1024
+ function formatRunningColumnValue(entry, key, referenceTime) {
1025
+ switch (key) {
1026
+ case 'id':
1027
+ return sanitizeDisplayValue(entry.issue_identifier);
1028
+ case 'stage':
1029
+ return sanitizeDisplayValue(entry.display_state);
1030
+ case 'pid':
1031
+ return formatPid(entry.pid);
1032
+ case 'age':
1033
+ return formatRuntimeAndTurns(entry.started_at, referenceTime, entry.turn_count);
1034
+ case 'tokens':
1035
+ return formatOptionalCount(entry.tokens.total_tokens);
1036
+ case 'session':
1037
+ return compactSessionId(entry.session_id);
1038
+ case 'event':
1039
+ return summarizeRunningEvent(entry, referenceTime);
1040
+ default:
1041
+ return 'n/a';
1042
+ }
1043
+ }
1044
+ function summarizeRunningEvent(entry, referenceTime) {
1045
+ const displayEvent = sanitizeDisplayValue(entry.display_event);
1046
+ if (displayEvent !== '-') {
1047
+ return appendWorkerHostSummary(displayEvent, entry.worker_host);
1048
+ }
1049
+ const displayState = sanitizeDisplayValue(entry.display_state).toLowerCase();
1050
+ const lastMessage = sanitizeDisplayValue(entry.last_message);
1051
+ if (isHighSignalStatusText(lastMessage, displayState)) {
1052
+ return appendWorkerHostSummary(lastMessage, entry.worker_host);
1053
+ }
1054
+ const summary = sanitizeDisplayValue(entry.summary);
1055
+ if (isHighSignalStatusText(summary, displayState) && !sameStatusText(summary, lastMessage)) {
1056
+ return appendWorkerHostSummary(summary, entry.worker_host);
1057
+ }
1058
+ const humanizedEvent = humanizeRunningEvent(entry.last_event);
1059
+ const eventAge = formatRelativePast(entry.last_event_at, referenceTime);
1060
+ if (isHighSignalStatusText(humanizedEvent, displayState)) {
1061
+ return appendWorkerHostSummary(humanizedEvent, entry.worker_host);
1062
+ }
1063
+ const statusReason = humanizeRunningEvent(entry.status_reason);
1064
+ if (isHighSignalStatusText(statusReason, displayState)) {
1065
+ return appendWorkerHostSummary(statusReason, entry.worker_host);
1066
+ }
1067
+ if (humanizedEvent !== 'n/a' && eventAge !== null) {
1068
+ return appendWorkerHostSummary(`${humanizedEvent} (${eventAge} ago)`, entry.worker_host);
1069
+ }
1070
+ if (summary !== '-') {
1071
+ return appendWorkerHostSummary(summary, entry.worker_host);
1072
+ }
1073
+ if (lastMessage !== '-') {
1074
+ return appendWorkerHostSummary(eventAge === null ? lastMessage : `${lastMessage} (${eventAge} ago)`, entry.worker_host);
1075
+ }
1076
+ return appendWorkerHostSummary('n/a', entry.worker_host);
1077
+ }
1078
+ function summarizeRetryHeadline(entry) {
1079
+ const lastEvent = humanizeRunningEvent(entry.last_event);
1080
+ if (lastEvent !== 'n/a') {
1081
+ return lastEvent;
1082
+ }
1083
+ const statusReason = humanizeRunningEvent(entry.status_reason);
1084
+ if (statusReason !== 'n/a') {
1085
+ return statusReason;
1086
+ }
1087
+ const displayState = sanitizeDisplayValue(entry.display_state);
1088
+ return displayState === '-' ? 'retrying' : displayState;
1089
+ }
1090
+ function summarizeRetryDetail(entry) {
1091
+ const headline = summarizeRetryHeadline(entry).toLowerCase();
1092
+ const displayState = sanitizeDisplayValue(entry.display_state).toLowerCase();
1093
+ const error = sanitizeDisplayValue(entry.error);
1094
+ if (isHighSignalStatusText(error, displayState) && !sameStatusText(error, headline)) {
1095
+ return appendWorkerHostSummary(error, entry.worker_host);
1096
+ }
1097
+ const summary = sanitizeDisplayValue(entry.summary);
1098
+ if (isHighSignalStatusText(summary, displayState) && !sameStatusText(summary, headline)) {
1099
+ return appendWorkerHostSummary(summary, entry.worker_host);
1100
+ }
1101
+ const lastMessage = sanitizeDisplayValue(entry.last_message);
1102
+ if (isHighSignalStatusText(lastMessage, displayState) && !sameStatusText(lastMessage, headline)) {
1103
+ return appendWorkerHostSummary(lastMessage, entry.worker_host);
1104
+ }
1105
+ const statusReason = humanizeRunningEvent(entry.status_reason);
1106
+ if (isHighSignalStatusText(statusReason, displayState) && !sameStatusText(statusReason, headline)) {
1107
+ return appendWorkerHostSummary(statusReason, entry.worker_host);
1108
+ }
1109
+ return appendWorkerHostSummary('n/a', entry.worker_host);
1110
+ }
1111
+ function appendWorkerHostSummary(summary, workerHost) {
1112
+ const displayWorkerHost = sanitizeDisplayValue(workerHost);
1113
+ if (displayWorkerHost === '-') {
1114
+ return summary;
1115
+ }
1116
+ if (summary === 'n/a') {
1117
+ return `worker ${displayWorkerHost}`;
1118
+ }
1119
+ return `${displayWorkerHost} | ${summary}`;
1120
+ }
1121
+ function selectRunningColumns(terminalColumns) {
1122
+ const baseColumns = terminalColumns >= 120
1123
+ ? [
1124
+ { key: 'id', label: 'ID', width: 10 },
1125
+ { key: 'stage', label: 'STAGE', width: 12 },
1126
+ { key: 'pid', label: 'PID', width: 8 },
1127
+ { key: 'age', label: 'AGE / TURN', width: 12 },
1128
+ { key: 'tokens', label: 'TOKENS', width: 10, align: 'right' },
1129
+ { key: 'session', label: 'SESSION', width: 14 },
1130
+ { key: 'event', label: 'EVENT', width: 0 }
1131
+ ]
1132
+ : terminalColumns >= 96
1133
+ ? [
1134
+ { key: 'id', label: 'ID', width: 9 },
1135
+ { key: 'stage', label: 'STAGE', width: 10 },
1136
+ { key: 'pid', label: 'PID', width: 7 },
1137
+ { key: 'age', label: 'AGE / TURN', width: 12 },
1138
+ { key: 'tokens', label: 'TOKENS', width: 9, align: 'right' },
1139
+ { key: 'session', label: 'SESSION', width: 12 },
1140
+ { key: 'event', label: 'EVENT', width: 0 }
1141
+ ]
1142
+ : terminalColumns >= 78
1143
+ ? [
1144
+ { key: 'id', label: 'ID', width: 9 },
1145
+ { key: 'stage', label: 'STAGE', width: 10 },
1146
+ { key: 'pid', label: 'PID', width: 7 },
1147
+ { key: 'tokens', label: 'TOKENS', width: 9, align: 'right' },
1148
+ { key: 'event', label: 'EVENT', width: 0 }
1149
+ ]
1150
+ : [
1151
+ { key: 'id', label: 'ID', width: 8 },
1152
+ { key: 'stage', label: 'STAGE', width: 8 },
1153
+ { key: 'event', label: 'EVENT', width: 0 }
1154
+ ];
1155
+ const fixedWidth = baseColumns
1156
+ .filter((column) => column.key !== 'event')
1157
+ .reduce((sum, column) => sum + column.width, 0);
1158
+ const gapWidth = Math.max(0, baseColumns.length - 1);
1159
+ const minimumEventWidth = terminalColumns >= 96 ? 18 : 12;
1160
+ const eventWidth = Math.max(minimumEventWidth, terminalColumns - 4 - fixedWidth - gapWidth);
1161
+ return baseColumns.map((column) => column.key === 'event' ? { ...column, width: eventWidth } : column);
1162
+ }
1163
+ function resolveProjectLabel(dataset) {
1164
+ const projectName = dataset.tracked?.linear?.project_name ??
1165
+ dataset.selected?.tracked?.linear?.project_name ??
1166
+ dataset.issues
1167
+ .map((issue) => issue.tracked?.linear?.project_name ?? null)
1168
+ .find((value) => typeof value === 'string' && value.trim().length > 0) ??
1169
+ null;
1170
+ if (!projectName) {
1171
+ return 'n/a';
1172
+ }
1173
+ return sanitizeDisplayValue(projectName);
1174
+ }
1175
+ function appendTokenSample(samples, timestampMs, totalTokens) {
1176
+ const normalizedTotal = normalizeFiniteNumber(totalTokens);
1177
+ if (totalTokens === null || totalTokens === undefined || !Number.isFinite(totalTokens)) {
1178
+ return samples.filter((sample) => sample.timestampMs >= timestampMs - THROUGHPUT_WINDOW_MS);
1179
+ }
1180
+ const baselineSamples = samples.length > 0 && normalizedTotal < samples[0].totalTokens ? [] : samples;
1181
+ return [{ timestampMs, totalTokens: normalizedTotal }, ...baselineSamples].filter((sample) => sample.timestampMs >= timestampMs - THROUGHPUT_WINDOW_MS);
1182
+ }
1183
+ function rollingTokensPerSecond(samples) {
1184
+ if (samples.length < 2) {
1185
+ return 0;
1186
+ }
1187
+ const newest = samples[0];
1188
+ const oldest = samples[samples.length - 1];
1189
+ const elapsedMs = newest.timestampMs - oldest.timestampMs;
1190
+ const deltaTokens = Math.max(0, newest.totalTokens - oldest.totalTokens);
1191
+ if (elapsedMs <= 0) {
1192
+ return 0;
1193
+ }
1194
+ return deltaTokens / (elapsedMs / 1000);
1195
+ }
1196
+ function compareDueAt(left, right) {
1197
+ const leftMs = parseTimestamp(left);
1198
+ const rightMs = parseTimestamp(right);
1199
+ if (leftMs === null && rightMs === null) {
1200
+ return 0;
1201
+ }
1202
+ if (leftMs === null) {
1203
+ return 1;
1204
+ }
1205
+ if (rightMs === null) {
1206
+ return -1;
1207
+ }
1208
+ return leftMs - rightMs;
1209
+ }
1210
+ function formatRelativeDue(dueAt, referenceTime) {
1211
+ const dueTimestamp = parseTimestamp(dueAt);
1212
+ if (dueTimestamp === null) {
1213
+ return 'n/a';
1214
+ }
1215
+ const remainingMs = Math.max(0, dueTimestamp - referenceTime.getTime());
1216
+ return formatCountdownMs(remainingMs);
1217
+ }
1218
+ function formatRelativePast(timestamp, referenceTime) {
1219
+ const parsedTimestamp = parseTimestamp(timestamp);
1220
+ if (parsedTimestamp === null) {
1221
+ return null;
1222
+ }
1223
+ const elapsedSeconds = Math.max(0, Math.floor((referenceTime.getTime() - parsedTimestamp) / 1000));
1224
+ return formatHumanDurationShort(elapsedSeconds);
1225
+ }
1226
+ function formatRuntimeAndTurns(startedAt, referenceTime, turnCount) {
1227
+ const startedTimestamp = parseTimestamp(startedAt);
1228
+ const runtime = startedTimestamp === null
1229
+ ? 'n/a'
1230
+ : formatRuntimeSeconds(Math.max(0, (referenceTime.getTime() - startedTimestamp) / 1000));
1231
+ const turns = typeof turnCount === 'number' && Number.isFinite(turnCount) && turnCount >= 0
1232
+ ? String(Math.floor(turnCount))
1233
+ : 'n/a';
1234
+ return `${runtime} / ${turns}`;
1235
+ }
1236
+ function formatRuntimeSeconds(value) {
1237
+ return formatHumanDurationShort(Math.max(0, Math.floor(normalizeFiniteNumber(value))));
1238
+ }
1239
+ function formatLiveRuntimeSeconds(dataset, referenceTime, liveReferenceTime) {
1240
+ const liveDeltaSeconds = Math.max(0, (liveReferenceTime.getTime() - referenceTime.getTime()) / 1000);
1241
+ return formatRuntimeSeconds(normalizeFiniteNumber(dataset.totals.seconds_running) + liveDeltaSeconds);
1242
+ }
1243
+ function formatTps(value) {
1244
+ return formatCount(Math.max(0, Math.floor(normalizeFiniteNumber(value))));
1245
+ }
1246
+ function formatCount(value) {
1247
+ if (typeof value === 'string') {
1248
+ const trimmed = value.trim();
1249
+ if (trimmed.length === 0) {
1250
+ return '0';
1251
+ }
1252
+ const parsed = Number(trimmed);
1253
+ if (Number.isFinite(parsed)) {
1254
+ return NUMBER_FORMAT.format(Math.trunc(parsed));
1255
+ }
1256
+ return sanitizeDisplayValue(trimmed);
1257
+ }
1258
+ if (typeof value === 'number' && Number.isFinite(value)) {
1259
+ return NUMBER_FORMAT.format(Math.trunc(value));
1260
+ }
1261
+ return '0';
1262
+ }
1263
+ function formatOptionalCount(value) {
1264
+ if (value === null || value === undefined) {
1265
+ return 'n/a';
1266
+ }
1267
+ if (typeof value === 'string') {
1268
+ const trimmed = value.trim();
1269
+ if (trimmed.length === 0) {
1270
+ return 'n/a';
1271
+ }
1272
+ const parsed = Number(trimmed);
1273
+ if (Number.isFinite(parsed)) {
1274
+ return NUMBER_FORMAT.format(Math.trunc(parsed));
1275
+ }
1276
+ return sanitizeDisplayValue(trimmed);
1277
+ }
1278
+ if (typeof value === 'number' && Number.isFinite(value)) {
1279
+ return NUMBER_FORMAT.format(Math.trunc(value));
1280
+ }
1281
+ return 'n/a';
1282
+ }
1283
+ function formatRateLimitSegments(value, referenceTime) {
1284
+ if (!value || Object.keys(value).length === 0) {
1285
+ return [{ text: 'unavailable', color: ANSI_GRAY }];
1286
+ }
1287
+ const combined = formatCombinedRateLimitSegments(value, referenceTime);
1288
+ if (combined) {
1289
+ return combined;
1290
+ }
1291
+ const codexRateLimits = formatCodexRateLimitSegments(value, referenceTime);
1292
+ if (codexRateLimits) {
1293
+ return codexRateLimits;
1294
+ }
1295
+ const linearBudget = formatLinearBudgetSegments(value, referenceTime);
1296
+ if (linearBudget) {
1297
+ return linearBudget;
1298
+ }
1299
+ return [{ text: formatRecord(value), color: ANSI_GRAY }];
1300
+ }
1301
+ function formatCombinedRateLimitSegments(value, referenceTime) {
1302
+ const codex = asRecord(value.codex);
1303
+ const linearBudget = asRecord(value.linear_budget) ?? asRecord(value.linearBudget);
1304
+ if (!codex || !linearBudget) {
1305
+ return null;
1306
+ }
1307
+ const pieces = [];
1308
+ const codexPieces = formatCompactCodexRateLimitSegments(codex, referenceTime, {
1309
+ allowLegacyMetadata: true
1310
+ });
1311
+ if (codexPieces) {
1312
+ pieces.push(...codexPieces);
1313
+ }
1314
+ const linearPieces = formatCompactLinearBudgetSegments(linearBudget, referenceTime);
1315
+ if (linearPieces) {
1316
+ if (pieces.length > 0) {
1317
+ pieces.push({ text: ' || ', color: ANSI_GRAY });
1318
+ }
1319
+ pieces.push(...linearPieces);
1320
+ }
1321
+ return pieces.length > 0 ? pieces : null;
1322
+ }
1323
+ function formatCompactCodexRateLimitSegments(value, referenceTime, options = {}) {
1324
+ return formatOperatorCodexRateLimitSegments(value, referenceTime, {
1325
+ allowLegacyMetadata: options.allowLegacyMetadata,
1326
+ formatBucket: formatCompactRateLimitBucket,
1327
+ formatCredits: formatCompactRateLimitCredits
1328
+ });
1329
+ }
1330
+ function formatCodexRateLimitSegments(value, referenceTime, options = {}) {
1331
+ return formatOperatorCodexRateLimitSegments(value, referenceTime, {
1332
+ allowLegacyMetadata: options.allowLegacyMetadata,
1333
+ formatBucket: formatRateLimitBucket,
1334
+ formatCredits: formatRateLimitCredits
1335
+ });
1336
+ }
1337
+ function formatOperatorCodexRateLimitSegments(value, referenceTime, options) {
1338
+ const limitId = readRecordString(value, ['limit_id', 'limitId', 'limit_name', 'limitName']);
1339
+ const primary = asRecord(value.primary);
1340
+ const secondary = asRecord(value.secondary);
1341
+ const credits = asRecord(value.credits);
1342
+ const requests = asRecord(value.requests);
1343
+ const endpointRequests = asRecord(value.endpoint_requests);
1344
+ const observedAt = readRecordString(value, ['observed_at', 'observedAt']);
1345
+ const suppression = readRecordString(value, ['suppression']);
1346
+ const retryAfterSeconds = readRecordNumber(value, ['retry_after_seconds', 'retryAfterSeconds']);
1347
+ if (!limitId && !primary && !secondary && !credits) {
1348
+ if (!requests && !endpointRequests) {
1349
+ return null;
1350
+ }
1351
+ if (options.allowLegacyMetadata !== true &&
1352
+ (observedAt !== null || suppression !== null || retryAfterSeconds !== null)) {
1353
+ return null;
1354
+ }
1355
+ const pieces = [{ text: 'Codex', color: ANSI_YELLOW }];
1356
+ const displayRequests = selectOperatorVisibleBudgetBucket(requests, endpointRequests, referenceTime);
1357
+ if (displayRequests) {
1358
+ appendOperatorRateLimitSegment(pieces, `requests ${options.formatBucket(displayRequests, referenceTime)}`, ANSI_CYAN);
1359
+ }
1360
+ return pieces;
1361
+ }
1362
+ const pieces = [{ text: 'Codex', color: ANSI_YELLOW }];
1363
+ if (primary) {
1364
+ appendOperatorRateLimitSegment(pieces, `${resolveCodexRateLimitBucketLabel(primary) ?? 'primary'} ${options.formatBucket(primary, referenceTime)}`, ANSI_CYAN);
1365
+ }
1366
+ if (secondary) {
1367
+ appendOperatorRateLimitSegment(pieces, `${resolveCodexRateLimitBucketLabel(secondary) ?? 'secondary'} ${options.formatBucket(secondary, referenceTime)}`, ANSI_CYAN);
1368
+ }
1369
+ if (credits) {
1370
+ appendOperatorRateLimitSegment(pieces, options.formatCredits(credits), ANSI_GREEN);
1371
+ }
1372
+ return pieces;
1373
+ }
1374
+ function resolveCodexRateLimitBucketLabel(bucket) {
1375
+ const windowDurationMins = readRecordNumber(bucket, [
1376
+ 'windowDurationMins',
1377
+ 'window_duration_mins',
1378
+ 'window_minutes'
1379
+ ]);
1380
+ const normalizedWindowMinutes = windowDurationMins !== null && Number.isFinite(windowDurationMins)
1381
+ ? Math.max(0, Math.trunc(windowDurationMins))
1382
+ : null;
1383
+ if (normalizedWindowMinutes === 300) {
1384
+ return '5-hour';
1385
+ }
1386
+ if (normalizedWindowMinutes === 10_080) {
1387
+ return 'weekly';
1388
+ }
1389
+ return null;
1390
+ }
1391
+ function formatLinearBudgetSegments(value, referenceTime) {
1392
+ return formatOperatorLinearBudgetSegments(value, referenceTime, formatRateLimitBucket);
1393
+ }
1394
+ function formatCompactLinearBudgetSegments(value, referenceTime) {
1395
+ return formatOperatorLinearBudgetSegments(value, referenceTime, formatCompactRateLimitBucket);
1396
+ }
1397
+ function formatOperatorLinearBudgetSegments(value, referenceTime, formatBucket) {
1398
+ const requests = asRecord(value.requests);
1399
+ const complexity = asRecord(value.complexity);
1400
+ const endpointRequests = asRecord(value.endpoint_requests);
1401
+ const endpointComplexity = asRecord(value.endpoint_complexity);
1402
+ const observedAt = readRecordString(value, ['observed_at', 'observedAt']);
1403
+ const source = readRecordString(value, ['source']);
1404
+ const suppression = readRecordString(value, ['suppression']);
1405
+ const retryAfterSeconds = readRecordNumber(value, ['retry_after_seconds', 'retryAfterSeconds']);
1406
+ const looksLikeLinearBudget = observedAt !== null ||
1407
+ suppression !== null ||
1408
+ retryAfterSeconds !== null ||
1409
+ source?.toLowerCase().startsWith('linear') === true;
1410
+ if (!looksLikeLinearBudget) {
1411
+ return null;
1412
+ }
1413
+ const pieces = [{ text: 'Linear', color: ANSI_YELLOW }];
1414
+ const displayRequests = selectOperatorVisibleBudgetBucket(requests, endpointRequests, referenceTime);
1415
+ if (displayRequests) {
1416
+ appendOperatorRateLimitSegment(pieces, `requests ${formatBucket(displayRequests, referenceTime)}`, ANSI_CYAN);
1417
+ }
1418
+ const displayComplexity = selectOperatorVisibleBudgetBucket(complexity, endpointComplexity, referenceTime);
1419
+ if (displayComplexity) {
1420
+ appendOperatorRateLimitSegment(pieces, `complexity ${formatBucket(displayComplexity, referenceTime)}`, ANSI_CYAN);
1421
+ }
1422
+ return pieces;
1423
+ }
1424
+ function selectOperatorVisibleBudgetBucket(primary, endpoint, referenceTime) {
1425
+ if (!primary) {
1426
+ return endpoint;
1427
+ }
1428
+ if (!endpoint) {
1429
+ return primary;
1430
+ }
1431
+ const primaryExhausted = isOperatorRateLimitBucketExhausted(primary);
1432
+ const endpointExhausted = isOperatorRateLimitBucketExhausted(endpoint);
1433
+ if (endpointExhausted && !primaryExhausted) {
1434
+ return endpoint;
1435
+ }
1436
+ if (primaryExhausted && !endpointExhausted) {
1437
+ return primary;
1438
+ }
1439
+ if (primaryExhausted && endpointExhausted) {
1440
+ return compareOperatorRateLimitBucketResetMs(primary, endpoint, referenceTime) >= 0
1441
+ ? primary
1442
+ : endpoint;
1443
+ }
1444
+ return primary;
1445
+ }
1446
+ function formatRateLimitBucket(bucket, referenceTime) {
1447
+ return formatOperatorRateLimitBucket(bucket, referenceTime);
1448
+ }
1449
+ function formatCompactRateLimitBucket(bucket, referenceTime) {
1450
+ return formatOperatorRateLimitBucket(bucket, referenceTime);
1451
+ }
1452
+ function formatRateLimitCredits(credits) {
1453
+ if (readRecordBoolean(credits, ['unlimited']) === true) {
1454
+ return 'credits unlimited';
1455
+ }
1456
+ if (readRecordBoolean(credits, ['has_credits', 'hasCredits']) === false) {
1457
+ return 'credits none';
1458
+ }
1459
+ const balance = readRecordNumber(credits, ['balance']);
1460
+ if (balance !== null) {
1461
+ return `credits ${balance.toFixed(2)}`;
1462
+ }
1463
+ return 'credits available';
1464
+ }
1465
+ function isOperatorRateLimitBucketExhausted(bucket) {
1466
+ const remaining = readRecordNumber(bucket, ['remaining']);
1467
+ if (remaining !== null) {
1468
+ return remaining <= 0;
1469
+ }
1470
+ const usedPercent = readRecordNumber(bucket, ['usedPercent', 'used_percent']);
1471
+ if (usedPercent !== null) {
1472
+ return usedPercent >= 100;
1473
+ }
1474
+ return false;
1475
+ }
1476
+ function compareOperatorRateLimitBucketResetMs(left, right, referenceTime) {
1477
+ const leftMs = resolveOperatorRateLimitBucketResetMs(left, referenceTime);
1478
+ const rightMs = resolveOperatorRateLimitBucketResetMs(right, referenceTime);
1479
+ if (leftMs === null && rightMs === null) {
1480
+ return 0;
1481
+ }
1482
+ if (leftMs === null) {
1483
+ return -1;
1484
+ }
1485
+ if (rightMs === null) {
1486
+ return 1;
1487
+ }
1488
+ return leftMs - rightMs;
1489
+ }
1490
+ function resolveOperatorRateLimitBucketResetMs(bucket, referenceTime) {
1491
+ const resetAt = readRecordString(bucket, ['reset_at', 'resetAt', 'resets_at', 'resetsAt']);
1492
+ if (resetAt) {
1493
+ const parsed = Date.parse(resetAt);
1494
+ if (Number.isFinite(parsed)) {
1495
+ return parsed;
1496
+ }
1497
+ }
1498
+ const resetInSeconds = readRecordNumber(bucket, ['reset_in_seconds', 'resetInSeconds']);
1499
+ if (resetInSeconds !== null) {
1500
+ return referenceTime.getTime() + Math.max(0, resetInSeconds) * 1000;
1501
+ }
1502
+ return null;
1503
+ }
1504
+ function formatCompactRateLimitCredits(credits) {
1505
+ return formatRateLimitCredits(credits);
1506
+ }
1507
+ function appendOperatorRateLimitSegment(pieces, text, color) {
1508
+ pieces.push({ text: pieces.length === 1 ? ' ' : ' | ', color: ANSI_GRAY });
1509
+ pieces.push({ text, color });
1510
+ }
1511
+ function formatOperatorRateLimitBucket(bucket, referenceTime) {
1512
+ if (isRateLimitBucketExhausted(bucket)) {
1513
+ const resetSeconds = resolveRateLimitBucketResetSeconds(bucket, referenceTime);
1514
+ if (resetSeconds !== null) {
1515
+ return `resets ${formatHumanDurationShort(resetSeconds)}`;
1516
+ }
1517
+ }
1518
+ const remainingPercent = resolveRateLimitBucketRemainingPercent(bucket);
1519
+ if (remainingPercent !== null) {
1520
+ return formatPercent(remainingPercent);
1521
+ }
1522
+ const remaining = readRecordNumber(bucket, ['remaining']);
1523
+ const limit = readRecordNumber(bucket, ['limit']);
1524
+ if (remaining !== null && limit !== null) {
1525
+ return `${formatCount(remaining)}/${formatCount(limit)}`;
1526
+ }
1527
+ if (remaining !== null) {
1528
+ return `remaining ${formatCount(remaining)}`;
1529
+ }
1530
+ if (limit !== null) {
1531
+ return `limit ${formatCount(limit)}`;
1532
+ }
1533
+ return 'n/a';
1534
+ }
1535
+ function resolveRateLimitBucketRemainingPercent(bucket) {
1536
+ const usedPercent = readRecordNumber(bucket, ['usedPercent', 'used_percent']);
1537
+ if (usedPercent !== null) {
1538
+ return Math.min(100, Math.max(0, 100 - usedPercent));
1539
+ }
1540
+ const remaining = readRecordNumber(bucket, ['remaining']);
1541
+ const limit = readRecordNumber(bucket, ['limit']);
1542
+ if (remaining !== null && limit !== null && limit > 0) {
1543
+ return Math.min(100, Math.max(0, (remaining / limit) * 100));
1544
+ }
1545
+ return null;
1546
+ }
1547
+ function isRateLimitBucketExhausted(bucket) {
1548
+ const remaining = readRecordNumber(bucket, ['remaining']);
1549
+ if (remaining !== null) {
1550
+ return remaining <= 0;
1551
+ }
1552
+ const usedPercent = readRecordNumber(bucket, ['usedPercent', 'used_percent']);
1553
+ return usedPercent !== null ? usedPercent >= 100 : false;
1554
+ }
1555
+ function resolveRateLimitBucketResetSeconds(bucket, referenceTime) {
1556
+ return (readRecordNumber(bucket, ['reset_in_seconds', 'resetInSeconds']) ??
1557
+ secondsUntilTimestamp(readRecordString(bucket, ['reset_at', 'resetAt', 'resets_at', 'resetsAt']), referenceTime));
1558
+ }
1559
+ function formatPercent(value) {
1560
+ const rounded = Math.round(value * 10) / 10;
1561
+ return Number.isInteger(rounded) ? `${rounded.toFixed(0)}%` : `${rounded.toFixed(1).replace(/\.0$/, '')}%`;
1562
+ }
1563
+ function formatRecord(value) {
1564
+ return truncate(Object.entries(value)
1565
+ .map(([key, entry]) => `${sanitizeDisplayValue(key)}=${formatRecordValue(entry)}`)
1566
+ .join(' | '), 140);
1567
+ }
1568
+ function formatRecordValue(value) {
1569
+ if (value === null || value === undefined) {
1570
+ return '-';
1571
+ }
1572
+ if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
1573
+ return sanitizeDisplayValue(value);
1574
+ }
1575
+ try {
1576
+ return sanitizeDisplayValue(JSON.stringify(value));
1577
+ }
1578
+ catch {
1579
+ return sanitizeDisplayValue(String(value));
1580
+ }
1581
+ }
1582
+ function compactSessionId(sessionId) {
1583
+ const sanitized = sanitizeDisplayValue(sessionId);
1584
+ if (sanitized === '-') {
1585
+ return 'n/a';
1586
+ }
1587
+ if (sanitized.length <= 10) {
1588
+ return sanitized;
1589
+ }
1590
+ return `${sanitized.slice(0, 4)}...${sanitized.slice(-6)}`;
1591
+ }
1592
+ function formatPid(pid) {
1593
+ const sanitized = sanitizeDisplayValue(pid);
1594
+ return sanitized === '-' ? 'n/a' : sanitized;
1595
+ }
1596
+ function renderSummaryLine(label, segments, terminalColumns) {
1597
+ const prefix = `│ ${label}: `;
1598
+ const maxWidth = Math.max(0, terminalColumns - prefix.length);
1599
+ return colorize(prefix, ANSI_BOLD) + colorizeSummarySegments(segments, maxWidth);
1600
+ }
1601
+ function colorizeSummarySegments(segments, maxWidth) {
1602
+ if (maxWidth <= 0 || segments.length === 0) {
1603
+ return '';
1604
+ }
1605
+ if (segments.length === 1 && segments[0]?.truncateMode === 'middle') {
1606
+ return colorize(truncateMiddle(segments[0].text, maxWidth), segments[0].color);
1607
+ }
1608
+ const totalWidth = segments.reduce((sum, segment) => sum + segment.text.length, 0);
1609
+ if (totalWidth <= maxWidth) {
1610
+ return segments.map((segment) => colorize(segment.text, segment.color)).join('');
1611
+ }
1612
+ if (maxWidth <= 3) {
1613
+ return colorize(segments
1614
+ .map((segment) => segment.text)
1615
+ .join('')
1616
+ .slice(0, maxWidth), segments[0]?.color ?? ANSI_GRAY);
1617
+ }
1618
+ let remaining = maxWidth - 3;
1619
+ let ellipsisColor = segments[0]?.color ?? ANSI_GRAY;
1620
+ const rendered = [];
1621
+ for (const segment of segments) {
1622
+ if (remaining <= 0) {
1623
+ ellipsisColor = segment.color;
1624
+ break;
1625
+ }
1626
+ if (segment.text.length <= remaining) {
1627
+ rendered.push(colorize(segment.text, segment.color));
1628
+ remaining -= segment.text.length;
1629
+ ellipsisColor = segment.color;
1630
+ continue;
1631
+ }
1632
+ rendered.push(colorize(segment.text.slice(0, remaining), segment.color));
1633
+ ellipsisColor = segment.color;
1634
+ remaining = 0;
1635
+ break;
1636
+ }
1637
+ rendered.push(colorize('...', ellipsisColor));
1638
+ return rendered.join('');
1639
+ }
1640
+ function formatCell(value, width, align = 'left') {
1641
+ const sanitized = truncatePlain(sanitizeDisplayValue(value), width);
1642
+ return align === 'right' ? sanitized.padStart(width) : sanitized.padEnd(width);
1643
+ }
1644
+ function truncatePlain(value, maxLength) {
1645
+ if (value.length <= maxLength) {
1646
+ return value;
1647
+ }
1648
+ if (maxLength <= 3) {
1649
+ return value.slice(0, maxLength);
1650
+ }
1651
+ return `${value.slice(0, maxLength - 3)}...`;
1652
+ }
1653
+ function sanitizeDisplayValue(value) {
1654
+ if (value === null || value === undefined) {
1655
+ return '-';
1656
+ }
1657
+ const sanitized = sanitizeTerminalText(String(value));
1658
+ return sanitized.length === 0 ? '-' : sanitized;
1659
+ }
1660
+ function humanizeRunningEvent(event) {
1661
+ const normalized = normalizeRunningEventKey(event);
1662
+ if (!normalized) {
1663
+ return 'n/a';
1664
+ }
1665
+ switch (normalized) {
1666
+ case 'agent_message':
1667
+ return 'agent message';
1668
+ case 'task_started':
1669
+ return 'session started';
1670
+ case 'task_complete':
1671
+ case 'turn_completed':
1672
+ return 'turn completed';
1673
+ case 'turn_started':
1674
+ return 'turn started';
1675
+ case 'turn_failed':
1676
+ return 'turn failed';
1677
+ case 'turn_cancelled':
1678
+ return 'turn cancelled';
1679
+ case 'thread_tokenusage_updated':
1680
+ return 'token usage updated';
1681
+ case 'account_ratelimits_updated':
1682
+ return 'rate limits updated';
1683
+ case 'queued_questions':
1684
+ return 'queued questions';
1685
+ case 'notification':
1686
+ return 'notification';
1687
+ case 'item_started':
1688
+ return 'item started';
1689
+ case 'item_completed':
1690
+ return 'item completed';
1691
+ case 'item_updated':
1692
+ return 'item updated';
1693
+ case 'retry_scheduled':
1694
+ return 'retry scheduled';
1695
+ default:
1696
+ return normalized.replace(/_/g, ' ');
1697
+ }
1698
+ }
1699
+ function isHighSignalStatusText(value, displayState) {
1700
+ if (value === '-' || value === 'n/a' || value.toLowerCase() === displayState) {
1701
+ return false;
1702
+ }
1703
+ const normalized = value.toLowerCase();
1704
+ if (normalized === 'retry queued' ||
1705
+ normalized === 'turn running' ||
1706
+ normalized === 'worker turn active' ||
1707
+ normalized === 'provider worker turn is active.' ||
1708
+ normalized === 'provider worker turn is active' ||
1709
+ normalized === 'turn active') {
1710
+ return false;
1711
+ }
1712
+ return true;
1713
+ }
1714
+ function sameStatusText(left, right) {
1715
+ return left.toLowerCase() === right.toLowerCase();
1716
+ }
1717
+ function normalizeRunningEventKey(value) {
1718
+ const sanitized = sanitizeDisplayValue(value);
1719
+ if (sanitized === '-') {
1720
+ return null;
1721
+ }
1722
+ return sanitized
1723
+ .toLowerCase()
1724
+ .replace(/^codex\/event\//u, '')
1725
+ .replace(/[./]+/gu, '_')
1726
+ .replace(/[^a-z0-9_]+/gu, '_')
1727
+ .replace(/_+/gu, '_')
1728
+ .replace(/^_|_$/gu, '');
1729
+ }
1730
+ function formatHumanDurationShort(valueSeconds) {
1731
+ const totalSeconds = Math.max(0, Math.floor(normalizeFiniteNumber(valueSeconds)));
1732
+ const days = Math.floor(totalSeconds / 86_400);
1733
+ const hours = Math.floor(totalSeconds / 3600);
1734
+ const minutes = Math.floor((totalSeconds % 3600) / 60);
1735
+ const seconds = totalSeconds % 60;
1736
+ if (days > 0) {
1737
+ return hours % 24 > 0 ? `${days}d ${hours % 24}h` : `${days}d`;
1738
+ }
1739
+ if (hours > 0) {
1740
+ return minutes > 0 ? `${hours}h ${minutes}m` : `${hours}h`;
1741
+ }
1742
+ if (minutes > 0) {
1743
+ return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;
1744
+ }
1745
+ return `${seconds}s`;
1746
+ }
1747
+ function formatCountdownMs(valueMs) {
1748
+ if (!Number.isFinite(valueMs)) {
1749
+ return 'n/a';
1750
+ }
1751
+ if (valueMs <= 0) {
1752
+ return 'now';
1753
+ }
1754
+ return formatHumanDurationShort(Math.ceil(valueMs / 1000));
1755
+ }
1756
+ function truncate(value, maxLength) {
1757
+ const sanitized = sanitizeDisplayValue(value);
1758
+ if (sanitized.length <= maxLength) {
1759
+ return sanitized;
1760
+ }
1761
+ if (maxLength <= 3) {
1762
+ return sanitized.slice(0, maxLength);
1763
+ }
1764
+ return `${sanitized.slice(0, maxLength - 3)}...`;
1765
+ }
1766
+ function truncateMiddle(value, maxLength) {
1767
+ const sanitized = sanitizeDisplayValue(value);
1768
+ if (sanitized.length <= maxLength) {
1769
+ return sanitized;
1770
+ }
1771
+ const headLength = Math.max(1, Math.floor((maxLength - 3) / 2));
1772
+ const tailLength = Math.max(1, maxLength - 3 - headLength);
1773
+ return `${sanitized.slice(0, headLength)}...${sanitized.slice(-tailLength)}`;
1774
+ }
1775
+ function sanitizeTerminalText(value) {
1776
+ return value
1777
+ .replace(/\r\n|\n|\r/g, ' ')
1778
+ .replace(ANSI_CONTROL_SEQUENCE_PATTERN, ' ')
1779
+ .replace(CONTROL_CHARACTER_PATTERN, ' ')
1780
+ .replace(/\s+/g, ' ')
1781
+ .trim();
1782
+ }
1783
+ function resolveReferenceTime(referenceTime, generatedAt, fallbackTime = new Date(0)) {
1784
+ if (referenceTime instanceof Date && Number.isFinite(referenceTime.getTime())) {
1785
+ return referenceTime;
1786
+ }
1787
+ const parsed = parseTimestamp(generatedAt);
1788
+ return parsed === null ? fallbackTime : new Date(parsed);
1789
+ }
1790
+ function resolveLiveReferenceTime(liveReferenceTime, fallbackTime) {
1791
+ if (liveReferenceTime instanceof Date && Number.isFinite(liveReferenceTime.getTime())) {
1792
+ return liveReferenceTime;
1793
+ }
1794
+ return fallbackTime;
1795
+ }
1796
+ function deriveLiveReferenceTime(renderedState, now) {
1797
+ const elapsedMs = Math.max(0, now.getTime() - renderedState.liveClockStartedAt.getTime());
1798
+ return new Date(renderedState.referenceTime.getTime() + elapsedMs);
1799
+ }
1800
+ function resolveDisplayedLiveReferenceTime(renderedState, frameState, now) {
1801
+ if (frameState.paused && frameState.pausedLiveReferenceTime) {
1802
+ return frameState.pausedLiveReferenceTime;
1803
+ }
1804
+ return deriveLiveReferenceTime(renderedState, now);
1805
+ }
1806
+ function resolveMaxAllowedAgents(dataset) {
1807
+ const value = dataset.counts.max_allowed;
1808
+ if (typeof value === 'number' && Number.isFinite(value) && value > 0) {
1809
+ return Math.floor(value);
1810
+ }
1811
+ return null;
1812
+ }
1813
+ function resolveTerminalColumns(value) {
1814
+ if (typeof value === 'number' && Number.isFinite(value) && value > 0) {
1815
+ return Math.floor(value);
1816
+ }
1817
+ return DEFAULT_TERMINAL_COLUMNS;
1818
+ }
1819
+ function resolveTerminalRows(value) {
1820
+ if (typeof value === 'number' && Number.isFinite(value) && value > 0) {
1821
+ return Math.floor(value);
1822
+ }
1823
+ return Number.POSITIVE_INFINITY;
1824
+ }
1825
+ function linesWillExceedTerminalHeight(terminalRows, lineCount) {
1826
+ return Number.isFinite(terminalRows) && lineCount > terminalRows;
1827
+ }
1828
+ function isControlCharacter(value) {
1829
+ if (value.length === 0) {
1830
+ return false;
1831
+ }
1832
+ const codePoint = value.charCodeAt(0);
1833
+ return (codePoint >= 0x00 && codePoint <= 0x1f) || (codePoint >= 0x7f && codePoint <= 0x9f);
1834
+ }
1835
+ function parseTimestamp(value) {
1836
+ if (typeof value !== 'string' || value.trim().length === 0) {
1837
+ return null;
1838
+ }
1839
+ const parsed = Date.parse(value);
1840
+ return Number.isFinite(parsed) ? parsed : null;
1841
+ }
1842
+ function secondsUntilTimestamp(value, referenceTime) {
1843
+ const timestamp = parseTimestamp(value);
1844
+ if (timestamp === null) {
1845
+ return null;
1846
+ }
1847
+ return Math.max(0, Math.floor((timestamp - referenceTime.getTime()) / 1000));
1848
+ }
1849
+ function normalizeFiniteNumber(value) {
1850
+ return typeof value === 'number' && Number.isFinite(value) ? value : 0;
1851
+ }
1852
+ function formatNullable(value) {
1853
+ if (value === null || value === undefined) {
1854
+ return '-';
1855
+ }
1856
+ return sanitizeDisplayValue(value);
1857
+ }
1858
+ function readRecordString(record, keys) {
1859
+ for (const key of keys) {
1860
+ const value = record[key];
1861
+ if (typeof value === 'string' && value.trim().length > 0) {
1862
+ return value.trim();
1863
+ }
1864
+ }
1865
+ return null;
1866
+ }
1867
+ function readRecordNumber(record, keys) {
1868
+ for (const key of keys) {
1869
+ const value = record[key];
1870
+ if (typeof value === 'number' && Number.isFinite(value)) {
1871
+ return value;
1872
+ }
1873
+ if (typeof value === 'string' && value.trim().length > 0) {
1874
+ const parsed = Number(value.trim());
1875
+ if (Number.isFinite(parsed)) {
1876
+ return parsed;
1877
+ }
1878
+ }
1879
+ }
1880
+ return null;
1881
+ }
1882
+ function readRecordBoolean(record, keys) {
1883
+ for (const key of keys) {
1884
+ const value = record[key];
1885
+ if (typeof value === 'boolean') {
1886
+ return value;
1887
+ }
1888
+ }
1889
+ return null;
1890
+ }
1891
+ function asRecord(value) {
1892
+ return value !== null && typeof value === 'object' && !Array.isArray(value)
1893
+ ? value
1894
+ : null;
1895
+ }
1896
+ function colorize(value, ansiCode) {
1897
+ return `${ansiCode}${value}${ANSI_RESET}`;
1898
+ }
1899
+ function stripAnsiSequences(value) {
1900
+ return value.replace(ANSI_CONTROL_SEQUENCE_PATTERN, '');
1901
+ }
1902
+ function formatSnapshotTimestamp(value) {
1903
+ return value.toISOString().replace(/[-:.]/g, '');
1904
+ }