@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,546 @@
1
+ import { spawn } from 'node:child_process';
2
+ import process from 'node:process';
3
+ import { logger } from '../../logger.js';
4
+ import { createRuntimeCodexCommandContext, formatRuntimeSelectionSummary, parseRuntimeMode, resolveRuntimeCodexCommand } from '../runtime/index.js';
5
+ export const COLLAB_FEATURE_CANONICAL = 'multi_agent';
6
+ export const COLLAB_FEATURE_LEGACY = 'collab';
7
+ const DEFAULT_COLLAB_ROLE_POLICY = 'enforce';
8
+ export const COLLAB_ROLE_POLICY_ENV_CANONICAL = 'RLM_SYMBOLIC_MULTI_AGENT_ROLE_POLICY';
9
+ // Keep the legacy env aliases during the multi_agent migration window; the canonical
10
+ // settings win when both are present so existing lanes can upgrade without silent drift.
11
+ export const COLLAB_ROLE_POLICY_ENV_LEGACY = 'RLM_COLLAB_ROLE_POLICY';
12
+ export const COLLAB_ALLOW_DEFAULT_ROLE_ENV_CANONICAL = 'RLM_SYMBOLIC_MULTI_AGENT_ALLOW_DEFAULT_ROLE';
13
+ export const COLLAB_ALLOW_DEFAULT_ROLE_ENV_LEGACY = 'RLM_COLLAB_ALLOW_DEFAULT_ROLE';
14
+ const COLLAB_ROLE_TAG_PATTERN = /^\s*\[(?:agent_type|role)\s*:\s*([a-z0-9._-]+)\]/i;
15
+ const COLLAB_ROLE_TOKEN_PATTERN = /^[a-z0-9._-]+$/;
16
+ function defaultExecRunner(request) {
17
+ return new Promise((resolvePromise, reject) => {
18
+ const child = spawn(request.command, request.args, {
19
+ cwd: request.cwd,
20
+ env: request.env,
21
+ stdio: ['ignore', 'pipe', 'pipe']
22
+ });
23
+ let stdout = '';
24
+ let stderr = '';
25
+ child.stdout?.on('data', (chunk) => {
26
+ const text = chunk.toString();
27
+ stdout += text;
28
+ if (request.mirrorOutput) {
29
+ process.stdout.write(chunk);
30
+ }
31
+ });
32
+ child.stderr?.on('data', (chunk) => {
33
+ const text = chunk.toString();
34
+ stderr += text;
35
+ if (request.mirrorOutput) {
36
+ process.stderr.write(chunk);
37
+ }
38
+ });
39
+ child.once('error', (error) => reject(error instanceof Error ? error : new Error(String(error))));
40
+ child.once('exit', (code) => {
41
+ if (code === 0) {
42
+ resolvePromise({ stdout, stderr });
43
+ }
44
+ else {
45
+ reject(new Error(`codex exec exited with code ${code ?? 'unknown'}`));
46
+ }
47
+ });
48
+ });
49
+ }
50
+ function envFlagEnabled(value) {
51
+ if (!value) {
52
+ return false;
53
+ }
54
+ const normalized = value.trim().toLowerCase();
55
+ return normalized === '1' || normalized === 'true' || normalized === 'yes' || normalized === 'on';
56
+ }
57
+ function readNonEmptyEnvValue(value) {
58
+ return typeof value === 'string' && value.trim().length > 0 ? value : undefined;
59
+ }
60
+ export function createRlmCodexRuntimeShell(options) {
61
+ const createRuntimeContextImpl = options.createRuntimeContextImpl ?? createRuntimeCodexCommandContext;
62
+ const resolveRuntimeCommandImpl = options.resolveRuntimeCommandImpl ?? resolveRuntimeCodexCommand;
63
+ const formatRuntimeSelectionSummaryImpl = options.formatRuntimeSelectionSummaryImpl ?? formatRuntimeSelectionSummary;
64
+ const execRunner = options.execRunner ?? defaultExecRunner;
65
+ const log = options.log ?? logger;
66
+ let runtimeCodexContextPromise = null;
67
+ let runtimeCodexContextLogged = false;
68
+ async function resolveRlmRuntimeCodexContext() {
69
+ if (!runtimeCodexContextPromise) {
70
+ const requestedMode = parseRuntimeMode(options.env.CODEX_ORCHESTRATOR_RUNTIME_MODE_ACTIVE ??
71
+ options.env.CODEX_ORCHESTRATOR_RUNTIME_MODE ??
72
+ null);
73
+ const runId = typeof options.env.CODEX_ORCHESTRATOR_RUN_ID === 'string' &&
74
+ options.env.CODEX_ORCHESTRATOR_RUN_ID.trim().length > 0
75
+ ? options.env.CODEX_ORCHESTRATOR_RUN_ID.trim()
76
+ : `rlm-${Date.now()}`;
77
+ runtimeCodexContextPromise = createRuntimeContextImpl({
78
+ requestedMode,
79
+ executionMode: 'mcp',
80
+ repoRoot: options.repoRoot,
81
+ env: { ...process.env, ...options.env },
82
+ runId
83
+ });
84
+ }
85
+ const runtimeContext = await runtimeCodexContextPromise;
86
+ if (!runtimeCodexContextLogged) {
87
+ log.info(`[rlm-runtime] ${formatRuntimeSelectionSummaryImpl(runtimeContext.runtime)}`);
88
+ runtimeCodexContextLogged = true;
89
+ }
90
+ return runtimeContext;
91
+ }
92
+ async function runCodexExec(args, execOptions) {
93
+ const runtimeContext = await resolveRlmRuntimeCodexContext();
94
+ const { command, args: resolvedArgs } = resolveRuntimeCommandImpl(args, runtimeContext);
95
+ const childEnv = {
96
+ ...process.env,
97
+ ...options.env,
98
+ ...runtimeContext.env
99
+ };
100
+ if (execOptions.nonInteractive) {
101
+ childEnv.CODEX_NON_INTERACTIVE = readNonEmptyEnvValue(childEnv.CODEX_NON_INTERACTIVE) ?? '1';
102
+ childEnv.CODEX_NO_INTERACTIVE = readNonEmptyEnvValue(childEnv.CODEX_NO_INTERACTIVE) ?? '1';
103
+ childEnv.CODEX_INTERACTIVE = readNonEmptyEnvValue(childEnv.CODEX_INTERACTIVE) ?? '0';
104
+ }
105
+ childEnv.CODEX_SUBAGENTS = execOptions.subagentsEnabled ? '1' : '0';
106
+ return execRunner({
107
+ command,
108
+ args: resolvedArgs,
109
+ cwd: options.repoRoot,
110
+ env: childEnv,
111
+ mirrorOutput: execOptions.mirrorOutput
112
+ });
113
+ }
114
+ return {
115
+ async runCompletion(prompt, execOptions) {
116
+ const { stdout, stderr } = await runCodexExec(['exec', prompt], execOptions);
117
+ return [stdout.trim(), stderr.trim()].filter(Boolean).join('\n');
118
+ },
119
+ async runJsonlCompletion(prompt, completionOptions) {
120
+ const { stdout, stderr } = await runCodexExec(['exec', '--json', ...(completionOptions.extraArgs ?? []), prompt], {
121
+ nonInteractive: completionOptions.nonInteractive,
122
+ subagentsEnabled: false,
123
+ mirrorOutput: completionOptions.mirrorOutput
124
+ });
125
+ if (completionOptions.validateCollabLifecycle) {
126
+ const rolePolicy = completionOptions.collabRolePolicy ?? DEFAULT_COLLAB_ROLE_POLICY;
127
+ const validation = validateCollabLifecycle(stdout, {
128
+ requireSpawnRole: rolePolicy !== 'off',
129
+ allowDefaultRole: completionOptions.collabAllowDefaultRole ?? false
130
+ });
131
+ if (!validation.ok) {
132
+ const rolePolicyFailure = isRolePolicyValidationReason(validation.reasonCode);
133
+ if (rolePolicy === 'warn' && rolePolicyFailure) {
134
+ log.warn(`Collab lifecycle validation warning: ${validation.reason}`);
135
+ }
136
+ else {
137
+ throw new Error(`Collab lifecycle validation failed: ${validation.reason}`);
138
+ }
139
+ }
140
+ }
141
+ const message = extractAgentMessageFromJsonl(stdout);
142
+ if (message) {
143
+ return message;
144
+ }
145
+ return [stdout.trim(), stderr.trim()].filter(Boolean).join('\n');
146
+ },
147
+ async runSymbolicPrompt(prompt, options) {
148
+ if (!options.symbolicCollabEnabled) {
149
+ return this.runCompletion(prompt, {
150
+ nonInteractive: options.nonInteractive,
151
+ subagentsEnabled: false,
152
+ mirrorOutput: false
153
+ });
154
+ }
155
+ return this.runJsonlCompletion(buildCollabSubcallPrompt(prompt), {
156
+ nonInteractive: options.nonInteractive,
157
+ mirrorOutput: true,
158
+ extraArgs: ['--enable', options.collabFeatureKey, '--sandbox', 'read-only'],
159
+ validateCollabLifecycle: true,
160
+ collabRolePolicy: options.collabRolePolicy,
161
+ collabAllowDefaultRole: options.collabAllowDefaultRole
162
+ });
163
+ },
164
+ async resolveCollabFeatureKey(nonInteractive) {
165
+ try {
166
+ const { stdout } = await runCodexExec(['features', 'list'], {
167
+ nonInteractive,
168
+ subagentsEnabled: false,
169
+ mirrorOutput: false
170
+ });
171
+ return resolveCollabFeatureKeyFromFlags(parseFeatureFlagsFromText(stdout));
172
+ }
173
+ catch (error) {
174
+ log.debug(`Unable to resolve Codex collab feature key via \`codex features list\`: ${error instanceof Error ? error.message : String(error)}`);
175
+ return COLLAB_FEATURE_LEGACY;
176
+ }
177
+ }
178
+ };
179
+ }
180
+ export function parseFeatureFlagsFromText(raw) {
181
+ const flags = {};
182
+ for (const line of raw.split(/\r?\n/u)) {
183
+ const trimmed = line.trim();
184
+ if (!trimmed) {
185
+ continue;
186
+ }
187
+ const tokens = trimmed.split(/\s+/u);
188
+ if (tokens.length < 2) {
189
+ continue;
190
+ }
191
+ const name = tokens[0] ?? '';
192
+ const enabledToken = tokens[tokens.length - 1] ?? '';
193
+ if (!name) {
194
+ continue;
195
+ }
196
+ if (enabledToken === 'true') {
197
+ flags[name] = true;
198
+ }
199
+ else if (enabledToken === 'false') {
200
+ flags[name] = false;
201
+ }
202
+ }
203
+ return flags;
204
+ }
205
+ export function resolveCollabFeatureKeyFromFlags(flags) {
206
+ if (Object.prototype.hasOwnProperty.call(flags, COLLAB_FEATURE_CANONICAL)) {
207
+ return COLLAB_FEATURE_CANONICAL;
208
+ }
209
+ if (Object.prototype.hasOwnProperty.call(flags, COLLAB_FEATURE_LEGACY)) {
210
+ return COLLAB_FEATURE_LEGACY;
211
+ }
212
+ return COLLAB_FEATURE_LEGACY;
213
+ }
214
+ function extractAgentMessageFromJsonl(raw) {
215
+ let lastMessage = null;
216
+ const lines = raw.split(/\r?\n/);
217
+ for (const line of lines) {
218
+ const trimmed = line.trim();
219
+ if (!trimmed.startsWith('{')) {
220
+ continue;
221
+ }
222
+ try {
223
+ const parsed = JSON.parse(trimmed);
224
+ if ((parsed.type === 'item.completed' || parsed.type === 'item.updated') &&
225
+ parsed.item?.type === 'agent_message' &&
226
+ typeof parsed.item.text === 'string') {
227
+ lastMessage = parsed.item.text;
228
+ }
229
+ }
230
+ catch {
231
+ // ignore parse errors for non-json lines
232
+ }
233
+ }
234
+ return lastMessage;
235
+ }
236
+ function normalizeCollabStatus(value) {
237
+ if (value === 'in_progress' || value === 'completed' || value === 'failed') {
238
+ return value;
239
+ }
240
+ return 'unknown';
241
+ }
242
+ export function parseCollabToolCallsFromJsonl(raw) {
243
+ const lines = raw.split(/\r?\n/);
244
+ const calls = [];
245
+ for (let index = 0; index < lines.length; index += 1) {
246
+ const line = lines[index]?.trim();
247
+ if (!line || !line.startsWith('{') || !line.includes('"collab_tool_call"')) {
248
+ continue;
249
+ }
250
+ try {
251
+ const parsed = JSON.parse(line);
252
+ if ((parsed.type !== 'item.started' &&
253
+ parsed.type !== 'item.updated' &&
254
+ parsed.type !== 'item.completed') ||
255
+ parsed.item?.type !== 'collab_tool_call' ||
256
+ typeof parsed.item.tool !== 'string') {
257
+ continue;
258
+ }
259
+ const receiverThreadIds = Array.isArray(parsed.item.receiver_thread_ids)
260
+ ? parsed.item.receiver_thread_ids.filter((entry) => typeof entry === 'string')
261
+ : [];
262
+ const prompt = typeof parsed.item.prompt === 'string' ? parsed.item.prompt : null;
263
+ calls.push({
264
+ sequence: index,
265
+ eventType: parsed.type,
266
+ tool: parsed.item.tool,
267
+ status: normalizeCollabStatus(parsed.item.status),
268
+ receiverThreadIds,
269
+ prompt,
270
+ agentType: normalizeCollabRoleToken(parsed.item.agent_type),
271
+ promptRole: resolveCollabRoleFromPrompt(prompt)
272
+ });
273
+ }
274
+ catch {
275
+ continue;
276
+ }
277
+ }
278
+ return calls;
279
+ }
280
+ function formatLifecycleIds(ids) {
281
+ return ids.slice(0, 3).join(', ');
282
+ }
283
+ function normalizeCollabRoleToken(value) {
284
+ if (typeof value !== 'string') {
285
+ return null;
286
+ }
287
+ const normalized = value.trim().toLowerCase();
288
+ if (!normalized || !COLLAB_ROLE_TOKEN_PATTERN.test(normalized)) {
289
+ return null;
290
+ }
291
+ return normalized;
292
+ }
293
+ function resolveCollabRoleFromPrompt(value) {
294
+ if (typeof value !== 'string') {
295
+ return null;
296
+ }
297
+ const match = value.match(COLLAB_ROLE_TAG_PATTERN);
298
+ if (!match || typeof match[1] !== 'string') {
299
+ return null;
300
+ }
301
+ return normalizeCollabRoleToken(match[1]);
302
+ }
303
+ export function resolveCollabRolePolicy(value) {
304
+ const normalized = (value ?? '').trim().toLowerCase();
305
+ if (!normalized) {
306
+ return DEFAULT_COLLAB_ROLE_POLICY;
307
+ }
308
+ if (normalized === 'off' ||
309
+ normalized === 'disabled' ||
310
+ normalized === 'none' ||
311
+ normalized === '0' ||
312
+ normalized === 'false') {
313
+ return 'off';
314
+ }
315
+ if (normalized === 'warn' || normalized === 'warning' || normalized === 'soft') {
316
+ return 'warn';
317
+ }
318
+ if (normalized === 'enforce' ||
319
+ normalized === 'strict' ||
320
+ normalized === 'on' ||
321
+ normalized === 'true' ||
322
+ normalized === '1') {
323
+ return 'enforce';
324
+ }
325
+ logger.warn(`Invalid multi-agent role policy value "${value}". Using "${DEFAULT_COLLAB_ROLE_POLICY}" ` +
326
+ `(expected: enforce|warn|off; canonical env ${COLLAB_ROLE_POLICY_ENV_CANONICAL}, ` +
327
+ `legacy alias ${COLLAB_ROLE_POLICY_ENV_LEGACY}).`);
328
+ return DEFAULT_COLLAB_ROLE_POLICY;
329
+ }
330
+ export function resolveCollabRolePolicyConfig(env) {
331
+ const canonical = env[COLLAB_ROLE_POLICY_ENV_CANONICAL];
332
+ const legacy = env[COLLAB_ROLE_POLICY_ENV_LEGACY];
333
+ if (canonical !== undefined) {
334
+ if (legacy !== undefined && legacy.trim().toLowerCase() !== canonical.trim().toLowerCase()) {
335
+ logger.warn(`${COLLAB_ROLE_POLICY_ENV_LEGACY} is ignored because ${COLLAB_ROLE_POLICY_ENV_CANONICAL} is set.`);
336
+ }
337
+ return { value: resolveCollabRolePolicy(canonical), source: 'canonical' };
338
+ }
339
+ if (legacy !== undefined) {
340
+ return { value: resolveCollabRolePolicy(legacy), source: 'legacy' };
341
+ }
342
+ return { value: resolveCollabRolePolicy(undefined), source: null };
343
+ }
344
+ export function resolveCollabAllowDefaultRoleConfig(env) {
345
+ const canonical = env[COLLAB_ALLOW_DEFAULT_ROLE_ENV_CANONICAL];
346
+ const legacy = env[COLLAB_ALLOW_DEFAULT_ROLE_ENV_LEGACY];
347
+ if (canonical !== undefined) {
348
+ if (legacy !== undefined && envFlagEnabled(legacy) !== envFlagEnabled(canonical)) {
349
+ logger.warn(`${COLLAB_ALLOW_DEFAULT_ROLE_ENV_LEGACY} is ignored because ${COLLAB_ALLOW_DEFAULT_ROLE_ENV_CANONICAL} is set.`);
350
+ }
351
+ return { value: envFlagEnabled(canonical), source: 'canonical' };
352
+ }
353
+ if (legacy !== undefined) {
354
+ return { value: envFlagEnabled(legacy), source: 'legacy' };
355
+ }
356
+ return { value: false, source: null };
357
+ }
358
+ export function isRolePolicyValidationReason(reasonCode) {
359
+ return (reasonCode === 'missing_role' ||
360
+ reasonCode === 'default_role_disallowed' ||
361
+ reasonCode === 'role_mismatch');
362
+ }
363
+ function includesThreadLimit(text) {
364
+ return text.toLowerCase().includes('agent thread limit reached');
365
+ }
366
+ function hasCollabSpawnThreadLimitError(raw) {
367
+ const lines = raw.split('\n');
368
+ for (const line of lines) {
369
+ const trimmed = line.trim();
370
+ if (!trimmed.startsWith('{')) {
371
+ continue;
372
+ }
373
+ try {
374
+ const parsed = JSON.parse(trimmed);
375
+ const item = parsed.item;
376
+ if (!item || item.type !== 'collab_tool_call' || item.tool !== 'spawn_agent') {
377
+ continue;
378
+ }
379
+ const candidates = [];
380
+ if (typeof item.error === 'string') {
381
+ candidates.push(item.error);
382
+ }
383
+ if (typeof item.message === 'string') {
384
+ candidates.push(item.message);
385
+ }
386
+ if (typeof item.output === 'string') {
387
+ candidates.push(item.output);
388
+ }
389
+ if (typeof parsed.error?.message === 'string') {
390
+ candidates.push(parsed.error.message);
391
+ }
392
+ if (candidates.some((entry) => includesThreadLimit(entry))) {
393
+ return true;
394
+ }
395
+ }
396
+ catch {
397
+ continue;
398
+ }
399
+ }
400
+ return false;
401
+ }
402
+ export function validateCollabLifecycle(raw, options = {}) {
403
+ const requireSpawnRole = options.requireSpawnRole !== false;
404
+ const allowDefaultRole = options.allowDefaultRole === true;
405
+ if (hasCollabSpawnThreadLimitError(raw)) {
406
+ return { ok: false, reason: 'collab spawn hit thread limit', reasonCode: 'thread_limit' };
407
+ }
408
+ const calls = parseCollabToolCallsFromJsonl(raw);
409
+ if (calls.length === 0) {
410
+ return { ok: true };
411
+ }
412
+ const spawnedAt = new Map();
413
+ const waitedAt = new Map();
414
+ const closedAt = new Map();
415
+ const missingRoleIds = new Set();
416
+ const disallowedDefaultRoleIds = new Set();
417
+ const mismatchedRoleIds = new Set();
418
+ const roleByThread = new Map();
419
+ for (const call of calls) {
420
+ const isCompleted = call.status === 'completed' ||
421
+ (call.status === 'unknown' && call.eventType === 'item.completed');
422
+ if (!isCompleted) {
423
+ continue;
424
+ }
425
+ if (call.tool === 'spawn_agent') {
426
+ const explicitRole = call.agentType;
427
+ const promptRole = call.promptRole;
428
+ const effectiveRole = explicitRole ?? promptRole;
429
+ const roleTargets = call.receiverThreadIds.length > 0 ? call.receiverThreadIds : [`spawn@${call.sequence}`];
430
+ if (requireSpawnRole && !effectiveRole) {
431
+ for (const target of roleTargets) {
432
+ missingRoleIds.add(target);
433
+ }
434
+ }
435
+ else if (effectiveRole === 'default' && !allowDefaultRole) {
436
+ for (const target of roleTargets) {
437
+ disallowedDefaultRoleIds.add(target);
438
+ }
439
+ }
440
+ if (explicitRole && promptRole && explicitRole !== promptRole) {
441
+ for (const target of roleTargets) {
442
+ mismatchedRoleIds.add(target);
443
+ }
444
+ }
445
+ for (const threadId of call.receiverThreadIds) {
446
+ if (!spawnedAt.has(threadId)) {
447
+ spawnedAt.set(threadId, call.sequence);
448
+ }
449
+ if (!effectiveRole) {
450
+ continue;
451
+ }
452
+ const previous = roleByThread.get(threadId);
453
+ if (previous && previous !== effectiveRole) {
454
+ mismatchedRoleIds.add(threadId);
455
+ continue;
456
+ }
457
+ roleByThread.set(threadId, effectiveRole);
458
+ }
459
+ continue;
460
+ }
461
+ for (const threadId of call.receiverThreadIds) {
462
+ if (call.tool === 'wait') {
463
+ waitedAt.set(threadId, call.sequence);
464
+ }
465
+ else if (call.tool === 'close_agent') {
466
+ closedAt.set(threadId, call.sequence);
467
+ }
468
+ }
469
+ }
470
+ const spawnedIds = Array.from(spawnedAt.keys());
471
+ if (spawnedIds.length > 0) {
472
+ const missingWait = spawnedIds.filter((threadId) => !waitedAt.has(threadId));
473
+ if (missingWait.length > 0) {
474
+ return {
475
+ ok: false,
476
+ reason: `missing wait for spawned agent(s): ${formatLifecycleIds(missingWait)}`,
477
+ reasonCode: 'missing_wait'
478
+ };
479
+ }
480
+ const missingClose = spawnedIds.filter((threadId) => !closedAt.has(threadId));
481
+ if (missingClose.length > 0) {
482
+ return {
483
+ ok: false,
484
+ reason: `missing close_agent for spawned agent(s): ${formatLifecycleIds(missingClose)}`,
485
+ reasonCode: 'missing_close'
486
+ };
487
+ }
488
+ const invalidOrder = spawnedIds.filter((threadId) => {
489
+ const waitSequence = waitedAt.get(threadId);
490
+ const closeSequence = closedAt.get(threadId);
491
+ if (waitSequence === undefined || closeSequence === undefined) {
492
+ return false;
493
+ }
494
+ return closeSequence < waitSequence;
495
+ });
496
+ if (invalidOrder.length > 0) {
497
+ return {
498
+ ok: false,
499
+ reason: `close_agent before wait for agent(s): ${formatLifecycleIds(invalidOrder)}`,
500
+ reasonCode: 'close_before_wait'
501
+ };
502
+ }
503
+ }
504
+ if (!requireSpawnRole) {
505
+ return { ok: true };
506
+ }
507
+ if (missingRoleIds.size > 0) {
508
+ return {
509
+ ok: false,
510
+ reason: `missing explicit role for spawn_agent call(s): ${formatLifecycleIds(Array.from(missingRoleIds))}. ` +
511
+ 'Prefix prompts with [agent_type:<role>] and set spawn_agent.agent_type when supported.',
512
+ reasonCode: 'missing_role'
513
+ };
514
+ }
515
+ if (disallowedDefaultRoleIds.size > 0) {
516
+ return {
517
+ ok: false,
518
+ reason: `spawn_agent used disallowed default role for: ${formatLifecycleIds(Array.from(disallowedDefaultRoleIds))}. ` +
519
+ 'Set a non-default agent_type explicitly.',
520
+ reasonCode: 'default_role_disallowed'
521
+ };
522
+ }
523
+ if (mismatchedRoleIds.size > 0) {
524
+ return {
525
+ ok: false,
526
+ reason: `spawn_agent role mismatch for agent(s): ${formatLifecycleIds(Array.from(mismatchedRoleIds))}`,
527
+ reasonCode: 'role_mismatch'
528
+ };
529
+ }
530
+ return { ok: true };
531
+ }
532
+ export function buildCollabSubcallPrompt(prompt) {
533
+ return [
534
+ 'Use collab tools to run the sub-agent prompt below.',
535
+ 'For every spawned agent id, execute this lifecycle in order:',
536
+ '1) spawn_agent with explicit agent_type (never omit it; omission defaults to `default`),',
537
+ ' and prefix the spawned prompt with [agent_type:<same-role>] on the first line',
538
+ '2) wait (for that same id)',
539
+ '3) close_agent (for that same id)',
540
+ 'Never leave spawned agents unclosed, including timeout or error paths.',
541
+ 'Return only the sub-agent response text and nothing else.',
542
+ '',
543
+ 'Sub-agent prompt:',
544
+ prompt
545
+ ].join('\n');
546
+ }
@@ -524,7 +524,7 @@ async function resolveReadExcerpt(params) {
524
524
  return null;
525
525
  }
526
526
  function buildPlannerPrompt(params) {
527
- const { goal, contextStore, budgets, priorReads, priorSearches, priorSubcalls, deliberationBrief } = params;
527
+ const { goal, contextStore, budgets, runMemoryPromptLines, priorReads, priorSearches, priorSubcalls, deliberationBrief } = params;
528
528
  const baseLines = [
529
529
  'You are a symbolic RLM planner. Return JSON only (no prose).',
530
530
  `Goal: ${goal}`,
@@ -550,7 +550,8 @@ function buildPlannerPrompt(params) {
550
550
  '- Do not include full context; use pointers.',
551
551
  '- Prefer prior subcall pointers for recursive chaining.',
552
552
  '- Request at least one subcall before intent=final.',
553
- ''
553
+ '',
554
+ ...(runMemoryPromptLines && runMemoryPromptLines.length > 0 ? [...runMemoryPromptLines, ''] : [])
554
555
  ];
555
556
  const sections = [];
556
557
  if (priorSearches.length > 0) {
@@ -923,6 +924,7 @@ export async function runSymbolicLoop(options) {
923
924
  goal: options.goal,
924
925
  contextStore: options.contextStore,
925
926
  budgets: options.budgets,
927
+ runMemoryPromptLines: options.runMemoryPromptLines,
926
928
  priorReads,
927
929
  priorSearches,
928
930
  priorSubcalls,
@@ -0,0 +1,42 @@
1
+ import { runRlmLaunchCliShell } from './rlmLaunchCliShell.js';
2
+ const DEFAULT_DEPENDENCIES = {
3
+ runRlmLaunchCliShell
4
+ };
5
+ export async function runRlmCliRequestShell(params, overrides = {}) {
6
+ const dependencies = { ...DEFAULT_DEPENDENCIES, ...overrides };
7
+ const runtimeMode = params.resolveRuntimeModeFlag(params.flags);
8
+ params.applyRepoConfigRequiredPolicy(params.flags);
9
+ const goalFromArgs = params.positionals.length > 0 ? params.positionals.join(' ') : undefined;
10
+ const collabUserChoice = params.flags['collab'] !== undefined ||
11
+ params.flags['multi-agent'] !== undefined ||
12
+ params.env.RLM_SYMBOLIC_COLLAB !== undefined ||
13
+ params.env.RLM_SYMBOLIC_MULTI_AGENT !== undefined;
14
+ await dependencies.runRlmLaunchCliShell({
15
+ orchestrator: params.orchestrator,
16
+ runtimeMode,
17
+ goalFromArgs,
18
+ goalFlag: params.readStringFlag(params.flags, 'goal') ?? undefined,
19
+ goalEnv: params.env.RLM_GOAL,
20
+ taskIdOverride: readRawStringFlagValue(params.flags['task']),
21
+ parentRunId: readRawStringFlagValue(params.flags['parent-run']),
22
+ approvalPolicy: readRawStringFlagValue(params.flags['approval-policy']),
23
+ collabUserChoice,
24
+ runWithUi: params.runWithUi,
25
+ emitRunOutput: params.emitRunOutput,
26
+ applyRlmEnvOverrides: (goal) => params.applyRlmEnvOverrides(params.flags, goal),
27
+ shouldWarnLegacyEnvAlias: () => params.shouldWarnLegacyEnvAlias(params.flags, params.env),
28
+ resolveRlmTaskId: params.resolveRlmTaskId,
29
+ setTaskEnvironment: params.setTaskEnvironment,
30
+ runDoctor: params.runDoctor,
31
+ resolveRepoRoot: params.resolveRepoRoot,
32
+ runCompletionShell: params.runCompletionShell,
33
+ log: params.log,
34
+ warn: params.warn
35
+ });
36
+ }
37
+ function readRawStringFlagValue(value) {
38
+ if (typeof value !== 'string') {
39
+ return undefined;
40
+ }
41
+ return value;
42
+ }
@@ -0,0 +1,46 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ const DEFAULT_DEPENDENCIES = {
4
+ readFile,
5
+ delay: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
6
+ terminalStatuses: new Set(['succeeded', 'failed', 'cancelled']),
7
+ missingStateExitCode: 10
8
+ };
9
+ async function waitForManifestCompletion(manifestPath, dependencies, intervalMs = 2000) {
10
+ for (;;) {
11
+ const raw = await dependencies.readFile(manifestPath, 'utf8');
12
+ const manifest = JSON.parse(raw);
13
+ if (dependencies.terminalStatuses.has(manifest.status)) {
14
+ return manifest;
15
+ }
16
+ await dependencies.delay(intervalMs);
17
+ }
18
+ }
19
+ async function readRlmState(statePath, dependencies) {
20
+ try {
21
+ const raw = await dependencies.readFile(statePath, 'utf8');
22
+ const parsed = JSON.parse(raw);
23
+ if (!parsed.final) {
24
+ return null;
25
+ }
26
+ return parsed.final;
27
+ }
28
+ catch {
29
+ return null;
30
+ }
31
+ }
32
+ export async function runRlmCompletionCliShell(params, overrides = {}) {
33
+ const dependencies = { ...DEFAULT_DEPENDENCIES, ...overrides };
34
+ const manifestPath = join(params.repoRoot, params.artifactRoot, 'manifest.json');
35
+ const manifest = await waitForManifestCompletion(manifestPath, dependencies);
36
+ const statePath = join(params.repoRoot, params.artifactRoot, 'rlm', 'state.json');
37
+ const rlmState = await readRlmState(statePath, dependencies);
38
+ if (rlmState) {
39
+ params.log(`RLM status: ${rlmState.status}`);
40
+ params.setExitCode(rlmState.exitCode);
41
+ return;
42
+ }
43
+ params.log(`RLM status: ${manifest.status}`);
44
+ params.error('RLM state file missing; treating as internal error.');
45
+ params.setExitCode(dependencies.missingStateExitCode);
46
+ }