onto-mcp 0.3.2 → 0.4.0

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 (300) hide show
  1. package/.onto/processes/reconstruct/actionable-ontology-seed-recomposition-design.md +447 -0
  2. package/.onto/processes/reconstruct/foundry-style-ontology-seed-contract.md +934 -0
  3. package/.onto/processes/reconstruct/reconstruct-boundary-contract.md +303 -725
  4. package/.onto/processes/reconstruct/reconstruct-contract-registry.yaml +1645 -0
  5. package/.onto/processes/reconstruct/reconstruct-execution-ux-contract.md +26 -22
  6. package/.onto/processes/reconstruct/source-profile-contract.md +49 -23
  7. package/.onto/processes/reconstruct/source-profiles/code.md +6 -3
  8. package/.onto/processes/reconstruct/source-profiles/database.md +5 -2
  9. package/.onto/processes/reconstruct/source-profiles/document.md +5 -2
  10. package/.onto/processes/reconstruct/source-profiles/spreadsheet.md +5 -4
  11. package/.onto/processes/review/review-execution-ux-contract.md +40 -0
  12. package/.onto/processes/shared/pipeline-execution-ledger-contract.md +26 -10
  13. package/.onto/processes/shared/target-material-kind-contract.md +29 -16
  14. package/AGENTS.md +6 -4
  15. package/README.md +135 -76
  16. package/dist/cli.js +8 -8
  17. package/dist/core-api/reconstruct-api.js +117 -31
  18. package/dist/core-api/review-api.js +47 -0
  19. package/dist/core-runtime/cli/codex-review-unit-executor.js +39 -2
  20. package/dist/core-runtime/cli/complete-review-session.js +2 -2
  21. package/dist/core-runtime/cli/mock-review-unit-executor.js +1 -1
  22. package/dist/core-runtime/cli/review-invoke.js +9 -9
  23. package/dist/core-runtime/cli/run-review-prompt-execution.js +39 -5
  24. package/dist/core-runtime/cli/spawn-watcher.js +266 -47
  25. package/dist/core-runtime/cli/start-review-session.js +3 -3
  26. package/dist/core-runtime/llm/llm-caller.js +11 -0
  27. package/dist/core-runtime/llm/llm-tool-loop.js +2 -0
  28. package/dist/core-runtime/observability/runtime-stream-observation.js +118 -0
  29. package/dist/core-runtime/onboard/cli-host.js +149 -0
  30. package/dist/core-runtime/onboard/host-target.js +22 -0
  31. package/dist/core-runtime/onboard/json-config-host.js +122 -0
  32. package/dist/core-runtime/onboard/path-scan.js +26 -0
  33. package/dist/core-runtime/onboard/prompt.js +51 -0
  34. package/dist/core-runtime/onboard/register.js +207 -0
  35. package/dist/core-runtime/onboard/types.js +27 -0
  36. package/dist/core-runtime/reconstruct/actionable-seed-validation.js +1777 -0
  37. package/dist/core-runtime/reconstruct/artifact-types.js +10 -4
  38. package/dist/core-runtime/reconstruct/contract-registry.js +623 -0
  39. package/dist/core-runtime/reconstruct/domain-id.js +10 -0
  40. package/dist/core-runtime/reconstruct/governing-snapshot.js +716 -0
  41. package/dist/core-runtime/reconstruct/material-profile-validation.js +191 -0
  42. package/dist/core-runtime/reconstruct/materialize-preparation.js +49 -11
  43. package/dist/core-runtime/reconstruct/pipeline-execution-ledger.js +269 -79
  44. package/dist/core-runtime/reconstruct/post-seed-validation.js +1194 -51
  45. package/dist/core-runtime/reconstruct/record.js +104 -20
  46. package/dist/core-runtime/reconstruct/run.js +2107 -413
  47. package/dist/core-runtime/reconstruct/seed-claim-projections.js +268 -0
  48. package/dist/core-runtime/reconstruct/source-profiles.js +93 -4
  49. package/dist/core-runtime/reconstruct/terminal-validation.js +807 -0
  50. package/dist/core-runtime/review/review-invocation-runner.js +4 -4
  51. package/dist/mcp/server.js +110 -38
  52. package/dist/mcp/tool-schemas.js +20 -6
  53. package/package.json +8 -17
  54. package/scripts/onto-review-watch.sh +486 -0
  55. package/scripts/onto-runtime-watch.sh +122 -0
  56. package/scripts/postinstall-hint.js +22 -0
  57. package/.onto/processes/reconstruct/top-level-concept-discovery-contract.md +0 -387
  58. package/dist/core-runtime/cli/bootstrap-review-binding.js +0 -186
  59. package/dist/core-runtime/cli/codex-nested-dispatch.test.js +0 -390
  60. package/dist/core-runtime/cli/codex-nested-teamlead-executor.test.js +0 -335
  61. package/dist/core-runtime/cli/coordinator-helpers.js +0 -583
  62. package/dist/core-runtime/cli/coordinator-state-machine-deliberation.test.js +0 -167
  63. package/dist/core-runtime/cli/coordinator-state-machine.js +0 -794
  64. package/dist/core-runtime/cli/e2e-codex-multi-agent-fixes.test.js +0 -615
  65. package/dist/core-runtime/cli/e2e-start-review-session.test.js +0 -312
  66. package/dist/core-runtime/cli/health.js +0 -44
  67. package/dist/core-runtime/cli/inline-http-review-unit-executor.test.js +0 -567
  68. package/dist/core-runtime/cli/materialize-review-execution-preparation.js +0 -104
  69. package/dist/core-runtime/cli/migrate-session-roots.js +0 -118
  70. package/dist/core-runtime/cli/repo-layout-migration-replace.smoke.test.js +0 -106
  71. package/dist/core-runtime/cli/review-invoke-auto-resolution.test.js +0 -268
  72. package/dist/core-runtime/cli/review-invoke-coordinator-topology.test.js +0 -136
  73. package/dist/core-runtime/cli/review-invoke-resolver-caching.test.js +0 -201
  74. package/dist/core-runtime/cli/review-invoke-topology-dispatch.test.js +0 -192
  75. package/dist/core-runtime/cli/session-root-guard.js +0 -168
  76. package/dist/core-runtime/cli/spawn-watcher.test.js +0 -457
  77. package/dist/core-runtime/cli/strip-wrapping-code-fence.test.js +0 -79
  78. package/dist/core-runtime/cli/teamcreate-lens-deliberation-executor.js +0 -412
  79. package/dist/core-runtime/cli/teamcreate-lens-deliberation-executor.test.js +0 -351
  80. package/dist/core-runtime/cli/topology-executor-mapping.js +0 -139
  81. package/dist/core-runtime/cli/topology-executor-mapping.test.js +0 -173
  82. package/dist/core-runtime/cli/write-review-interpretation.js +0 -81
  83. package/dist/core-runtime/config/onto-config-cli.js +0 -278
  84. package/dist/core-runtime/config/onto-config-key-path.js +0 -288
  85. package/dist/core-runtime/config/onto-config-key-path.test.js +0 -195
  86. package/dist/core-runtime/config/onto-config-preview.js +0 -108
  87. package/dist/core-runtime/config/onto-config-preview.test.js +0 -132
  88. package/dist/core-runtime/discovery/config-chain.js +0 -118
  89. package/dist/core-runtime/discovery/config-chain.test.js +0 -103
  90. package/dist/core-runtime/discovery/config-profile.js +0 -199
  91. package/dist/core-runtime/discovery/config-profile.test.js +0 -233
  92. package/dist/core-runtime/discovery/host-detection.test.js +0 -186
  93. package/dist/core-runtime/discovery/installation-paths.test.js +0 -65
  94. package/dist/core-runtime/discovery/lens-registry.test.js +0 -81
  95. package/dist/core-runtime/discovery/path-normalization.test.js +0 -22
  96. package/dist/core-runtime/discovery/plugin-path.js +0 -72
  97. package/dist/core-runtime/discovery/plugin-path.test.js +0 -95
  98. package/dist/core-runtime/evolve/adapters/code-product/compile/compile-defense.js +0 -344
  99. package/dist/core-runtime/evolve/adapters/code-product/compile/compile-defense.test.js +0 -915
  100. package/dist/core-runtime/evolve/adapters/code-product/compile/compile.js +0 -564
  101. package/dist/core-runtime/evolve/adapters/code-product/compile/compile.test.js +0 -708
  102. package/dist/core-runtime/evolve/adapters/code-product/parsers/brief-parser.js +0 -165
  103. package/dist/core-runtime/evolve/adapters/code-product/parsers/brief-parser.test.js +0 -227
  104. package/dist/core-runtime/evolve/adapters/code-product/validators/validate.js +0 -59
  105. package/dist/core-runtime/evolve/adapters/code-product/validators/validate.test.js +0 -205
  106. package/dist/core-runtime/evolve/adapters/methodology/adapter.js +0 -16
  107. package/dist/core-runtime/evolve/adapters/methodology/adapter.test.js +0 -9
  108. package/dist/core-runtime/evolve/adapters/methodology/perspectives/authority-consistency.js +0 -298
  109. package/dist/core-runtime/evolve/adapters/methodology/perspectives/authority-consistency.test.js +0 -70
  110. package/dist/core-runtime/evolve/adapters/methodology/scope-types/process.js +0 -46
  111. package/dist/core-runtime/evolve/adapters/methodology/scope-types/process.test.js +0 -73
  112. package/dist/core-runtime/evolve/adapters/registry.js +0 -47
  113. package/dist/core-runtime/evolve/adapters/registry.test.js +0 -67
  114. package/dist/core-runtime/evolve/cli.js +0 -256
  115. package/dist/core-runtime/evolve/commands/align.js +0 -194
  116. package/dist/core-runtime/evolve/commands/align.test.js +0 -82
  117. package/dist/core-runtime/evolve/commands/apply.js +0 -161
  118. package/dist/core-runtime/evolve/commands/apply.test.js +0 -138
  119. package/dist/core-runtime/evolve/commands/close.js +0 -39
  120. package/dist/core-runtime/evolve/commands/close.test.js +0 -99
  121. package/dist/core-runtime/evolve/commands/defer.js +0 -40
  122. package/dist/core-runtime/evolve/commands/defer.test.js +0 -134
  123. package/dist/core-runtime/evolve/commands/draft.js +0 -323
  124. package/dist/core-runtime/evolve/commands/draft.test.js +0 -178
  125. package/dist/core-runtime/evolve/commands/e2e-evolve-full-cycle.test.js +0 -208
  126. package/dist/core-runtime/evolve/commands/error-messages.js +0 -125
  127. package/dist/core-runtime/evolve/commands/error-messages.test.js +0 -167
  128. package/dist/core-runtime/evolve/commands/propose-align.js +0 -222
  129. package/dist/core-runtime/evolve/commands/propose-align.test.js +0 -136
  130. package/dist/core-runtime/evolve/commands/reconstruct.js +0 -330
  131. package/dist/core-runtime/evolve/commands/reconstruct.test.js +0 -278
  132. package/dist/core-runtime/evolve/commands/shared.js +0 -22
  133. package/dist/core-runtime/evolve/commands/stale-check.js +0 -103
  134. package/dist/core-runtime/evolve/commands/stale-check.test.js +0 -84
  135. package/dist/core-runtime/evolve/commands/start.js +0 -887
  136. package/dist/core-runtime/evolve/commands/start.test.js +0 -396
  137. package/dist/core-runtime/evolve/config/project-config.js +0 -99
  138. package/dist/core-runtime/evolve/config/project-config.test.js +0 -170
  139. package/dist/core-runtime/evolve/renderers/align-packet.js +0 -280
  140. package/dist/core-runtime/evolve/renderers/align-packet.test.js +0 -332
  141. package/dist/core-runtime/evolve/renderers/draft-packet.js +0 -303
  142. package/dist/core-runtime/evolve/renderers/draft-packet.test.js +0 -377
  143. package/dist/core-runtime/evolve/renderers/format.js +0 -5
  144. package/dist/core-runtime/evolve/renderers/scope-md.js +0 -237
  145. package/dist/core-runtime/evolve/renderers/scope-md.test.js +0 -306
  146. package/dist/core-runtime/govern/cli.js +0 -369
  147. package/dist/core-runtime/govern/cli.test.js +0 -314
  148. package/dist/core-runtime/govern/drift-engine.js +0 -103
  149. package/dist/core-runtime/govern/drift-engine.test.js +0 -319
  150. package/dist/core-runtime/govern/promote-principle.js +0 -206
  151. package/dist/core-runtime/govern/promote-principle.test.js +0 -368
  152. package/dist/core-runtime/govern/queue.js +0 -81
  153. package/dist/core-runtime/govern/types.js +0 -16
  154. package/dist/core-runtime/install/cli.js +0 -530
  155. package/dist/core-runtime/install/detect.js +0 -128
  156. package/dist/core-runtime/install/detect.test.js +0 -155
  157. package/dist/core-runtime/install/gitignore-update.js +0 -74
  158. package/dist/core-runtime/install/gitignore-update.test.js +0 -64
  159. package/dist/core-runtime/install/install-integration.test.js +0 -373
  160. package/dist/core-runtime/install/prompts.js +0 -389
  161. package/dist/core-runtime/install/prompts.test.js +0 -293
  162. package/dist/core-runtime/install/types.js +0 -26
  163. package/dist/core-runtime/install/validation.js +0 -295
  164. package/dist/core-runtime/install/validation.test.js +0 -313
  165. package/dist/core-runtime/install/writer.js +0 -254
  166. package/dist/core-runtime/install/writer.test.js +0 -218
  167. package/dist/core-runtime/learning/extractor.js +0 -461
  168. package/dist/core-runtime/learning/feedback.js +0 -179
  169. package/dist/core-runtime/learning/health-report.js +0 -165
  170. package/dist/core-runtime/learning/health-report.test.js +0 -169
  171. package/dist/core-runtime/learning/loader.js +0 -388
  172. package/dist/core-runtime/learning/loader.test.js +0 -102
  173. package/dist/core-runtime/learning/promote/apply-state.js +0 -240
  174. package/dist/core-runtime/learning/promote/audit-obligation.js +0 -195
  175. package/dist/core-runtime/learning/promote/collector.js +0 -432
  176. package/dist/core-runtime/learning/promote/degraded-state.js +0 -125
  177. package/dist/core-runtime/learning/promote/domain-doc-proposer.js +0 -166
  178. package/dist/core-runtime/learning/promote/e2e-promote.test.js +0 -6385
  179. package/dist/core-runtime/learning/promote/health-snapshot.js +0 -150
  180. package/dist/core-runtime/learning/promote/insight-reclassifier.js +0 -544
  181. package/dist/core-runtime/learning/promote/judgment-auditor.js +0 -517
  182. package/dist/core-runtime/learning/promote/panel-reviewer.js +0 -1158
  183. package/dist/core-runtime/learning/promote/promote-executor.js +0 -1675
  184. package/dist/core-runtime/learning/promote/promoter.js +0 -307
  185. package/dist/core-runtime/learning/promote/retirement.js +0 -122
  186. package/dist/core-runtime/learning/promote/types.js +0 -23
  187. package/dist/core-runtime/learning/prompt-sections.js +0 -51
  188. package/dist/core-runtime/learning/shared/artifact-registry-init.js +0 -45
  189. package/dist/core-runtime/learning/shared/artifact-registry.js +0 -254
  190. package/dist/core-runtime/learning/shared/audit-obligation-kernel.js +0 -73
  191. package/dist/core-runtime/learning/shared/audit-state.js +0 -99
  192. package/dist/core-runtime/learning/shared/duplicate-check.js +0 -28
  193. package/dist/core-runtime/learning/shared/llm-caller.js +0 -831
  194. package/dist/core-runtime/learning/shared/llm-caller.test.js +0 -601
  195. package/dist/core-runtime/learning/shared/llm-tool-loop.js +0 -393
  196. package/dist/core-runtime/learning/shared/mode.js +0 -25
  197. package/dist/core-runtime/learning/shared/paths.js +0 -84
  198. package/dist/core-runtime/learning/shared/paths.test.js +0 -79
  199. package/dist/core-runtime/learning/shared/patterns.js +0 -37
  200. package/dist/core-runtime/learning/shared/recoverability.js +0 -355
  201. package/dist/core-runtime/learning/shared/recovery-context.js +0 -374
  202. package/dist/core-runtime/learning/shared/scope.js +0 -1
  203. package/dist/core-runtime/learning/shared/semantic-classifier.js +0 -94
  204. package/dist/core-runtime/learning/shared/specs/apply-execution-state-spec.js +0 -42
  205. package/dist/core-runtime/learning/shared/specs/audit-state-spec.js +0 -37
  206. package/dist/core-runtime/learning/shared/specs/backup-metadata-spec.js +0 -39
  207. package/dist/core-runtime/learning/shared/specs/emergency-log-spec.js +0 -41
  208. package/dist/core-runtime/learning/shared/specs/layout-version-spec.js +0 -38
  209. package/dist/core-runtime/learning/shared/specs/promote-decisions-spec.js +0 -43
  210. package/dist/core-runtime/learning/shared/specs/promote-report-spec.js +0 -113
  211. package/dist/core-runtime/learning/shared/specs/prune-log-spec.js +0 -36
  212. package/dist/core-runtime/learning/shared/specs/recovery-resolution-spec.js +0 -48
  213. package/dist/core-runtime/learning/shared/specs/restore-manifest-spec.js +0 -43
  214. package/dist/core-runtime/learning/shared/specs/spec-helpers.js +0 -64
  215. package/dist/core-runtime/learning/usage-tracker.js +0 -190
  216. package/dist/core-runtime/learning/usage-tracker.test.js +0 -176
  217. package/dist/core-runtime/onboard/detect-review-axes.js +0 -122
  218. package/dist/core-runtime/onboard/detect-review-axes.test.js +0 -127
  219. package/dist/core-runtime/onboard/write-review-block.js +0 -188
  220. package/dist/core-runtime/onboard/write-review-block.test.js +0 -240
  221. package/dist/core-runtime/readers/brownfield-builder.js +0 -150
  222. package/dist/core-runtime/readers/brownfield-builder.test.js +0 -136
  223. package/dist/core-runtime/readers/code-chunk-collector.js +0 -53
  224. package/dist/core-runtime/readers/code-chunk-collector.test.js +0 -136
  225. package/dist/core-runtime/readers/file-utils.js +0 -240
  226. package/dist/core-runtime/readers/file-utils.test.js +0 -146
  227. package/dist/core-runtime/readers/lexicon-citation-check.js +0 -93
  228. package/dist/core-runtime/readers/lexicon-citation-check.test.js +0 -77
  229. package/dist/core-runtime/readers/mcp-figma.js +0 -30
  230. package/dist/core-runtime/readers/mcp-figma.test.js +0 -82
  231. package/dist/core-runtime/readers/mcp-generic.js +0 -31
  232. package/dist/core-runtime/readers/mcp-generic.test.js +0 -76
  233. package/dist/core-runtime/readers/ontology-index.js +0 -148
  234. package/dist/core-runtime/readers/ontology-index.test.js +0 -245
  235. package/dist/core-runtime/readers/ontology-query.js +0 -168
  236. package/dist/core-runtime/readers/ontology-query.test.js +0 -311
  237. package/dist/core-runtime/readers/ontology-resolve.js +0 -48
  238. package/dist/core-runtime/readers/ontology-resolve.test.js +0 -48
  239. package/dist/core-runtime/readers/patterns/index.js +0 -7
  240. package/dist/core-runtime/readers/review-log.js +0 -213
  241. package/dist/core-runtime/readers/review-log.test.js +0 -313
  242. package/dist/core-runtime/readers/scan-local.js +0 -102
  243. package/dist/core-runtime/readers/scan-local.test.js +0 -102
  244. package/dist/core-runtime/readers/scan-tarball.js +0 -121
  245. package/dist/core-runtime/readers/scan-tarball.test.js +0 -283
  246. package/dist/core-runtime/readers/scan-vault.js +0 -34
  247. package/dist/core-runtime/readers/scan-vault.test.js +0 -81
  248. package/dist/core-runtime/readers/types.js +0 -42
  249. package/dist/core-runtime/readers/types.test.js +0 -94
  250. package/dist/core-runtime/readers/viewpoint-collectors.js +0 -229
  251. package/dist/core-runtime/reconstruct/seed-candidate-validation.js +0 -385
  252. package/dist/core-runtime/review/citation-audit.test.js +0 -165
  253. package/dist/core-runtime/review/execution-plan-resolver.js +0 -247
  254. package/dist/core-runtime/review/execution-plan-resolver.test.js +0 -243
  255. package/dist/core-runtime/review/execution-topology-resolver-axis-first.test.js +0 -246
  256. package/dist/core-runtime/review/execution-topology-resolver.js +0 -401
  257. package/dist/core-runtime/review/execution-topology-resolver.test.js +0 -315
  258. package/dist/core-runtime/review/inline-context-embedder.test.js +0 -154
  259. package/dist/core-runtime/review/legacy-mode-policy.js +0 -88
  260. package/dist/core-runtime/review/materializers-effort-persist.test.js +0 -79
  261. package/dist/core-runtime/review/ontology-path-classifier.js +0 -179
  262. package/dist/core-runtime/review/ontology-path-classifier.test.js +0 -216
  263. package/dist/core-runtime/review/packet-boundary-policy.test.js +0 -107
  264. package/dist/core-runtime/review/participating-lens-paths.test.js +0 -73
  265. package/dist/core-runtime/review/review-config-legacy-translate.js +0 -244
  266. package/dist/core-runtime/review/review-config-legacy-translate.test.js +0 -161
  267. package/dist/core-runtime/review/review-config-validator.js +0 -289
  268. package/dist/core-runtime/review/review-config-validator.test.js +0 -236
  269. package/dist/core-runtime/review/shape-pipeline-audit.test.js +0 -311
  270. package/dist/core-runtime/review/shape-to-topology-id.js +0 -117
  271. package/dist/core-runtime/review/shape-to-topology-id.test.js +0 -132
  272. package/dist/core-runtime/review/topology-shape-derivation.js +0 -155
  273. package/dist/core-runtime/review/topology-shape-derivation.test.js +0 -195
  274. package/dist/core-runtime/scope-runtime/constants.js +0 -12
  275. package/dist/core-runtime/scope-runtime/constraint-pool.js +0 -166
  276. package/dist/core-runtime/scope-runtime/constraint-pool.test.js +0 -674
  277. package/dist/core-runtime/scope-runtime/domain-validation-log.js +0 -135
  278. package/dist/core-runtime/scope-runtime/domain-validation-log.test.js +0 -156
  279. package/dist/core-runtime/scope-runtime/eval-persistence.js +0 -65
  280. package/dist/core-runtime/scope-runtime/eval-persistence.test.js +0 -84
  281. package/dist/core-runtime/scope-runtime/event-pipeline.js +0 -64
  282. package/dist/core-runtime/scope-runtime/event-pipeline.test.js +0 -450
  283. package/dist/core-runtime/scope-runtime/event-store.js +0 -39
  284. package/dist/core-runtime/scope-runtime/event-store.test.js +0 -95
  285. package/dist/core-runtime/scope-runtime/gate-guard.js +0 -348
  286. package/dist/core-runtime/scope-runtime/gate-guard.test.js +0 -1047
  287. package/dist/core-runtime/scope-runtime/hash.js +0 -4
  288. package/dist/core-runtime/scope-runtime/hash.test.js +0 -33
  289. package/dist/core-runtime/scope-runtime/id.js +0 -4
  290. package/dist/core-runtime/scope-runtime/id.test.js +0 -17
  291. package/dist/core-runtime/scope-runtime/reducer.js +0 -297
  292. package/dist/core-runtime/scope-runtime/reducer.test.js +0 -759
  293. package/dist/core-runtime/scope-runtime/scope-manager.js +0 -161
  294. package/dist/core-runtime/scope-runtime/state-machine.js +0 -309
  295. package/dist/core-runtime/scope-runtime/state-machine.test.js +0 -704
  296. package/dist/core-runtime/scope-runtime/types.js +0 -116
  297. package/dist/core-runtime/scope-runtime/types.test.js +0 -69
  298. package/dist/core-runtime/translate/render-for-user.js +0 -169
  299. package/dist/core-runtime/translate/render-for-user.test.js +0 -122
  300. package/dist/providers/capability-contract.js +0 -1
@@ -1,54 +1,128 @@
1
1
  import { spawnSync } from "node:child_process";
2
2
  import fs from "node:fs";
3
+ import os from "node:os";
3
4
  import path from "node:path";
4
- /**
5
- * Attempt to spawn the onto:review live watcher in a side pane / split / new tab
6
- * using the most appropriate terminal multiplexer detected from the environment.
7
- *
8
- * Detection priority (most universal first):
9
- * 1. tmux (any OS, via $TMUX env var) — splits the pane identified by
10
- * `$TMUX_PANE` so the watcher stays beside the invoking pane even if
11
- * the user has switched panes during startReviewSession.
12
- * 2. iTerm2 on macOS (via $TERM_PROGRAM === 'iTerm.app') — targets the
13
- * session identified by `$ITERM_SESSION_ID`, which is inherited from
14
- * the invoking session at process start, so splits land beside the
15
- * pane that actually launched onto:review. If the env var is missing
16
- * or no matching session is found, the spawn is refused (returns
17
- * spawned: false) rather than falling back to the currently-focused
18
- * tab — a default target would land the watcher on whichever tab happens to
19
- * be frontmost at spawn time, which is the bug this path exists to
20
- * avoid.
21
- * 3. Apple Terminal on macOS (via $TERM_PROGRAM === 'Apple_Terminal')
22
- * — best effort; Terminal.app lacks a stable session identifier, so
23
- * the spawn opens a new tab rather than a tab-targeted split.
24
- *
25
- * `sessionRoot` is required. It is passed through to the watcher script as
26
- * an explicit argument, which bypasses the `.onto/review/.latest-session`
27
- * pointer and therefore avoids the cross-session race that the global
28
- * pointer would otherwise create under concurrent review invocations.
29
- *
30
- * Returns silently with `spawned: false` if no supported mechanism is found.
31
- * The caller should print an explicit recovery hint in that case.
32
- *
33
- * This function never throws — it returns a result object instead, so the
34
- * runtime continues even if the spawn fails.
35
- */
36
- export function spawnWatcherPane(projectRoot, sessionRoot, ontoHome) {
37
- // Resolution order for the watcher helper:
38
- // 1. <projectRoot>/scripts/onto-review-watch.sh co-located with the
39
- // review target (onto repo invocations, full-repo projects).
40
- // 2. <ontoHome>/scripts/onto-review-watch.sh — install-local script when
41
- // projectRoot is an isolated workspace and the watcher helper lives in
42
- // the repo home.
43
- // Without the install-local script branch, any invocation with --project-root pointed at a
44
- // non-repo location silently degrades to "watcher script not found"
45
- // (observed 2026-04-22 self-review finding). The two-slot search keeps
46
- // deterministic wrappers viable without forcing them to symlink or copy.
47
- const candidates = [
48
- path.join(projectRoot, "scripts", "onto-review-watch.sh"),
5
+ const CODEX_APP_LAUNCHER_ENV = "ONTO_RUNTIME_WATCHER_CODEX_APP_LAUNCHER";
6
+ function escapeAppleScriptString(value) {
7
+ return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
8
+ }
9
+ function expandHomePath(value) {
10
+ if (value === "~")
11
+ return os.homedir();
12
+ if (value.startsWith("~/"))
13
+ return path.join(os.homedir(), value.slice(2));
14
+ return value;
15
+ }
16
+ function resolveConfiguredPath(value) {
17
+ const expanded = expandHomePath(value.trim());
18
+ return path.isAbsolute(expanded) ? expanded : path.resolve(expanded);
19
+ }
20
+ function yamlDoubleQuote(value) {
21
+ return JSON.stringify(value);
22
+ }
23
+ function sanitizedConfigName(sessionRoot) {
24
+ return `onto-runtime-${path.basename(sessionRoot).replace(/[^A-Za-z0-9._-]/g, "-")}`;
25
+ }
26
+ function warpLaunchConfigurationRoot() {
27
+ if (process.platform === "win32") {
28
+ const appData = process.env.APPDATA ?? path.join(os.homedir(), "AppData", "Roaming");
29
+ return path.join(appData, "warp", "Warp", "data", "launch_configurations");
30
+ }
31
+ if (process.platform === "darwin") {
32
+ return path.join(os.homedir(), ".warp", "launch_configurations");
33
+ }
34
+ const xdgDataHome = process.env.XDG_DATA_HOME ?? path.join(os.homedir(), ".local", "share");
35
+ return path.join(xdgDataHome, "warp-terminal", "launch_configurations");
36
+ }
37
+ function openUri(uri) {
38
+ if (process.platform === "darwin") {
39
+ return spawnSync("open", [uri], { stdio: "ignore" }).status === 0;
40
+ }
41
+ if (process.platform === "win32") {
42
+ return spawnSync("cmd", ["/c", "start", "", uri], {
43
+ stdio: "ignore",
44
+ windowsHide: true,
45
+ }).status === 0;
46
+ }
47
+ return spawnSync("xdg-open", [uri], { stdio: "ignore" }).status === 0;
48
+ }
49
+ function writeWarpLaunchConfiguration(projectRoot, sessionRoot, watcherArgs) {
50
+ const configName = sanitizedConfigName(sessionRoot);
51
+ const configRoot = warpLaunchConfigurationRoot();
52
+ fs.mkdirSync(configRoot, { recursive: true });
53
+ const configPath = path.join(configRoot, `${configName}.yaml`);
54
+ fs.writeFileSync(configPath, [
55
+ "# Generated by onto-mcp runtime stream observation.",
56
+ "---",
57
+ `name: ${yamlDoubleQuote(`Onto Runtime ${path.basename(sessionRoot)}`)}`,
58
+ "windows:",
59
+ " - tabs:",
60
+ " - title: onto runtime",
61
+ " layout:",
62
+ ` cwd: ${yamlDoubleQuote(path.resolve(projectRoot))}`,
63
+ " commands:",
64
+ ` - exec: ${yamlDoubleQuote(watcherArgs)}`,
65
+ " color: cyan",
66
+ "",
67
+ ].join("\n"), "utf8");
68
+ return configName;
69
+ }
70
+ function isCodexDesktopShell() {
71
+ return (process.env.CODEX_SHELL === "1" ||
72
+ typeof process.env.CODEX_THREAD_ID === "string" ||
73
+ (process.env.CODEX_INTERNAL_ORIGINATOR_OVERRIDE ?? "")
74
+ .toLowerCase()
75
+ .includes("codex"));
76
+ }
77
+ function isWarpShell() {
78
+ return (process.env.TERM_PROGRAM === "WarpTerminal" ||
79
+ process.env.WARP_IS_LOCAL_SHELL_SESSION === "1" ||
80
+ typeof process.env.WARP_BOOTSTRAPPED === "string");
81
+ }
82
+ function isCursorIntegratedTerminal() {
83
+ const cursorSignals = [
84
+ process.env.CURSOR_TRACE_ID,
85
+ process.env.CURSOR_AGENT,
86
+ process.env.CURSOR_SESSION_ID,
87
+ process.env.VSCODE_CWD,
88
+ process.env.VSCODE_IPC_HOOK_CLI,
89
+ process.env.VSCODE_GIT_ASKPASS_MAIN,
49
90
  ];
91
+ return (process.env.TERM_PROGRAM === "vscode" &&
92
+ cursorSignals.some((value) => value?.toLowerCase().includes("cursor")));
93
+ }
94
+ function spawnViaMacAppKeystrokes(args) {
95
+ if (process.platform !== "darwin")
96
+ return false;
97
+ const escapedAppName = escapeAppleScriptString(args.appName);
98
+ const escapedCommand = escapeAppleScriptString(args.watcherArgs);
99
+ const script = `set previousClipboard to the clipboard\n` +
100
+ `set the clipboard to "${escapedCommand}"\n` +
101
+ `tell application "${escapedAppName}" to activate\n` +
102
+ `delay 0.2\n` +
103
+ `tell application "System Events"\n` +
104
+ args.focusTerminalScript +
105
+ ` delay 0.2\n` +
106
+ ` keystroke "v" using {command down}\n` +
107
+ ` key code 36\n` +
108
+ `end tell\n` +
109
+ `delay 0.2\n` +
110
+ `set the clipboard to previousClipboard\n` +
111
+ `return "matched"`;
112
+ const result = spawnSync("osascript", ["-e", script], { encoding: "utf8" });
113
+ return result.status === 0 && result.stdout.trim() === "matched";
114
+ }
115
+ function spawnViaConfiguredLauncher(args) {
116
+ const result = spawnSync(args.launcherPath, [args.watcherScript, args.sessionRoot, args.projectRoot, args.watcherArgs], { stdio: "ignore" });
117
+ return result.status === 0;
118
+ }
119
+ function spawnWatcherPaneForScript(projectRoot, sessionRoot, scriptName, ontoHome, disabledEnvName) {
120
+ if (disabledEnvName && process.env[disabledEnvName] === "0") {
121
+ return { spawned: false, reason: `${disabledEnvName}=0` };
122
+ }
123
+ const candidates = [path.join(projectRoot, "scripts", scriptName)];
50
124
  if (ontoHome && ontoHome !== projectRoot) {
51
- candidates.push(path.join(ontoHome, "scripts", "onto-review-watch.sh"));
125
+ candidates.push(path.join(ontoHome, "scripts", scriptName));
52
126
  }
53
127
  const watcherScript = candidates.find((c) => fs.existsSync(c));
54
128
  if (!watcherScript) {
@@ -61,6 +135,30 @@ export function spawnWatcherPane(projectRoot, sessionRoot, ontoHome) {
61
135
  // without producing a visible side pane or extra terminal tab on every
62
136
  // run. Enabled via `ONTO_WATCHER_DRY_RUN=1`.
63
137
  const dryRun = process.env.ONTO_WATCHER_DRY_RUN === "1";
138
+ const skippedAttachReasons = [];
139
+ const customCommand = process.env.ONTO_RUNTIME_WATCHER_COMMAND;
140
+ if (typeof customCommand === "string" && customCommand.trim().length > 0) {
141
+ if (dryRun) {
142
+ return { spawned: true, mechanism: "custom_command", dry_run: true };
143
+ }
144
+ const command = customCommand
145
+ .replaceAll("{watcherCommand}", watcherArgs)
146
+ .replaceAll("{watcherScript}", watcherScript)
147
+ .replaceAll("{sessionRoot}", sessionRoot)
148
+ .replaceAll("{projectRoot}", projectRoot);
149
+ try {
150
+ const result = spawnSync(command, [], {
151
+ shell: true,
152
+ stdio: "ignore",
153
+ });
154
+ if (result.status === 0) {
155
+ return { spawned: true, mechanism: "custom_command" };
156
+ }
157
+ }
158
+ catch {
159
+ // fall through
160
+ }
161
+ }
64
162
  // Priority 1: tmux (works on any OS, most universal)
65
163
  if (process.env.TMUX) {
66
164
  if (dryRun) {
@@ -86,6 +184,69 @@ export function spawnWatcherPane(projectRoot, sessionRoot, ontoHome) {
86
184
  // fall through
87
185
  }
88
186
  }
187
+ if (isCodexDesktopShell()) {
188
+ const configuredLauncher = process.env[CODEX_APP_LAUNCHER_ENV];
189
+ if (configuredLauncher?.trim()) {
190
+ const launcherPath = resolveConfiguredPath(configuredLauncher);
191
+ if (!fs.existsSync(launcherPath)) {
192
+ skippedAttachReasons.push(`${CODEX_APP_LAUNCHER_ENV} not found`);
193
+ }
194
+ else if (dryRun) {
195
+ return { spawned: true, mechanism: "codex_app", dry_run: true };
196
+ }
197
+ else {
198
+ try {
199
+ if (spawnViaConfiguredLauncher({
200
+ launcherPath,
201
+ watcherScript,
202
+ sessionRoot,
203
+ projectRoot,
204
+ watcherArgs,
205
+ })) {
206
+ return { spawned: true, mechanism: "codex_app" };
207
+ }
208
+ skippedAttachReasons.push(`${CODEX_APP_LAUNCHER_ENV} failed`);
209
+ }
210
+ catch {
211
+ skippedAttachReasons.push(`${CODEX_APP_LAUNCHER_ENV} failed`);
212
+ }
213
+ }
214
+ }
215
+ else {
216
+ skippedAttachReasons.push(`${CODEX_APP_LAUNCHER_ENV} not set`);
217
+ }
218
+ }
219
+ if (isWarpShell()) {
220
+ if (dryRun) {
221
+ return { spawned: true, mechanism: "warp", dry_run: true };
222
+ }
223
+ try {
224
+ const configName = writeWarpLaunchConfiguration(projectRoot, sessionRoot, watcherArgs);
225
+ if (openUri(`warp://launch/${encodeURIComponent(configName)}`)) {
226
+ return { spawned: true, mechanism: "warp" };
227
+ }
228
+ }
229
+ catch {
230
+ // fall through
231
+ }
232
+ }
233
+ if (isCursorIntegratedTerminal()) {
234
+ if (dryRun) {
235
+ return { spawned: true, mechanism: "cursor", dry_run: true };
236
+ }
237
+ try {
238
+ if (spawnViaMacAppKeystrokes({
239
+ appName: "Cursor",
240
+ watcherArgs,
241
+ focusTerminalScript: ` key code 50 using {control down, shift down}\n`,
242
+ })) {
243
+ return { spawned: true, mechanism: "cursor" };
244
+ }
245
+ }
246
+ catch {
247
+ // fall through
248
+ }
249
+ }
89
250
  // Priority 2: iTerm2 on macOS
90
251
  // Target the originating session via $ITERM_SESSION_ID (inherited at
91
252
  // process start), so the split lands beside the pane that launched
@@ -168,6 +329,64 @@ export function spawnWatcherPane(projectRoot, sessionRoot, ontoHome) {
168
329
  }
169
330
  return {
170
331
  spawned: false,
171
- reason: "no supported terminal multiplexer detected (tmux, iTerm2, Apple Terminal)",
332
+ reason: [
333
+ ...skippedAttachReasons,
334
+ "no supported terminal attach target detected (tmux, configured Codex app launcher, Warp, Cursor, iTerm2, Apple Terminal)",
335
+ ].join("; "),
172
336
  };
173
337
  }
338
+ /**
339
+ * Attempt to spawn the onto:review live watcher in a side pane / split / new tab
340
+ * using the most appropriate terminal multiplexer detected from the environment.
341
+ *
342
+ * Detection priority (most universal first):
343
+ * 1. ONTO_RUNTIME_WATCHER_COMMAND — host-provided launcher template.
344
+ * 2. tmux (any OS, via $TMUX env var) — splits the pane identified by
345
+ * `$TMUX_PANE` so the watcher stays beside the invoking pane even if
346
+ * the user has switched panes during startReviewSession.
347
+ * 3. Codex Desktop — only via ONTO_RUNTIME_WATCHER_CODEX_APP_LAUNCHER;
348
+ * default UI keystroke automation is intentionally not used because
349
+ * the app chat composer and terminal panel are not distinguishable by
350
+ * a stable runtime-owned handle.
351
+ * 4. Warp — writes a launch configuration and opens the Warp launch URI.
352
+ * 5. Cursor — best-effort integrated-terminal UI automation.
353
+ * 6. iTerm2 on macOS (via $TERM_PROGRAM === 'iTerm.app') — targets the
354
+ * session identified by `$ITERM_SESSION_ID`, which is inherited from
355
+ * the invoking session at process start, so splits land beside the
356
+ * pane that actually launched onto:review. If the env var is missing
357
+ * or no matching session is found, the spawn is refused (returns
358
+ * spawned: false) rather than falling back to the currently-focused
359
+ * tab — a default target would land the watcher on whichever tab happens to
360
+ * be frontmost at spawn time, which is the bug this path exists to
361
+ * avoid.
362
+ * 7. Apple Terminal on macOS (via $TERM_PROGRAM === 'Apple_Terminal')
363
+ * — best effort; Terminal.app lacks a stable session identifier, so
364
+ * the spawn opens a new tab rather than a tab-targeted split.
365
+ *
366
+ * `sessionRoot` is required. It is passed through to the watcher script as
367
+ * an explicit argument, which bypasses the `.onto/review/.latest-session`
368
+ * pointer and therefore avoids the cross-session race that the global
369
+ * pointer would otherwise create under concurrent review invocations.
370
+ *
371
+ * Returns silently with `spawned: false` if no supported mechanism is found.
372
+ * The caller should print an explicit recovery hint in that case.
373
+ *
374
+ * This function never throws — it returns a result object instead, so the
375
+ * runtime continues even if the spawn fails.
376
+ */
377
+ export function spawnWatcherPane(projectRoot, sessionRoot, ontoHome) {
378
+ // Resolution order for the watcher helper:
379
+ // 1. <projectRoot>/scripts/onto-review-watch.sh — co-located with the
380
+ // review target (onto repo invocations, full-repo projects).
381
+ // 2. <ontoHome>/scripts/onto-review-watch.sh — install-local script when
382
+ // projectRoot is an isolated workspace and the watcher helper lives in
383
+ // the repo home.
384
+ // Without the install-local script branch, any invocation with --project-root pointed at a
385
+ // non-repo location silently degrades to "watcher script not found"
386
+ // (observed 2026-04-22 self-review finding). The two-slot search keeps
387
+ // deterministic wrappers viable without forcing them to symlink or copy.
388
+ return spawnWatcherPaneForScript(projectRoot, sessionRoot, "onto-review-watch.sh", ontoHome);
389
+ }
390
+ export function spawnRuntimeWatcherPane(projectRoot, sessionRoot, ontoHome) {
391
+ return spawnWatcherPaneForScript(projectRoot, sessionRoot, "onto-runtime-watch.sh", ontoHome, "ONTO_RUNTIME_WATCHER");
392
+ }
@@ -37,7 +37,7 @@ export async function startReviewSession(argv) {
37
37
  }
38
38
  await runMaterializeReviewPromptPacketsCli(promptPacketsArgs);
39
39
  // Write `.latest-session` pointer so the watcher script and other tools can
40
- // auto-discover the current session without parsing buffered npm stdout.
40
+ // auto-discover the current session without parsing buffered adapter stdout.
41
41
  // This is a deterministic side-effect: a single line containing the absolute
42
42
  // session-root path. Best-effort — failure here must not block session start.
43
43
  try {
@@ -50,8 +50,8 @@ export async function startReviewSession(argv) {
50
50
  return {
51
51
  session_root: sessionRoot,
52
52
  bounded_start_steps: [
53
- "review:prepare-session",
54
- "review:materialize-prompt-packets",
53
+ "prepare_review_session",
54
+ "materialize_review_prompt_packets",
55
55
  ],
56
56
  };
57
57
  }
@@ -19,6 +19,7 @@ import path from "node:path";
19
19
  import os from "node:os";
20
20
  import { loadCoreLensRegistry } from "../discovery/lens-registry.js";
21
21
  import { DEFAULT_GROK_BASE_URL, DEFAULT_LMSTUDIO_BASE_URL, normalizeLlmModelSwitcher, } from "./model-switcher.js";
22
+ import { appendRuntimeModelCallLogFromCurrentContext, appendRuntimeStreamChunkFromCurrentContextSync, } from "../observability/runtime-stream-observation.js";
22
23
  /**
23
24
  * Bridge: OntoConfig + CLI overrides → Partial<LlmCallConfig> that callLlm consumes.
24
25
  *
@@ -83,6 +84,7 @@ const DEFAULT_MAX_RETRIES = 1;
83
84
  */
84
85
  function emitModelCallLog(line) {
85
86
  process.stderr.write(`[model-call] ${line}\n`);
87
+ appendRuntimeModelCallLogFromCurrentContext(line);
86
88
  }
87
89
  function readCodexAuthState() {
88
90
  const codexAuthPath = path.join(os.homedir(), ".codex", "auth.json");
@@ -311,14 +313,23 @@ async function callCodexCli(systemPrompt, userPrompt, modelId, reasoningEffort,
311
313
  const child = spawn("codex", args, {
312
314
  stdio: ["pipe", "pipe", "pipe"],
313
315
  });
316
+ const codexStreamSourceBase = {
317
+ kind: "process",
318
+ label: "codex-cli",
319
+ };
320
+ const codexStreamSource = child.pid !== undefined
321
+ ? { ...codexStreamSourceBase, processId: child.pid }
322
+ : codexStreamSourceBase;
314
323
  let stdout = "";
315
324
  let stderr = "";
316
325
  let timedOut = false;
317
326
  child.stdout.on("data", (chunk) => {
318
327
  stdout += String(chunk);
328
+ appendRuntimeStreamChunkFromCurrentContextSync("stdout", chunk, codexStreamSource);
319
329
  });
320
330
  child.stderr.on("data", (chunk) => {
321
331
  stderr += String(chunk);
332
+ appendRuntimeStreamChunkFromCurrentContextSync("stderr", chunk, codexStreamSource);
322
333
  });
323
334
  child.stdin.write(combinedPrompt);
324
335
  child.stdin.end();
@@ -50,6 +50,7 @@
50
50
  */
51
51
  import { BoundaryViolationError, findToolByName, } from "../cli/onto-tools.js";
52
52
  import { DEFAULT_GROK_BASE_URL, DEFAULT_LMSTUDIO_BASE_URL, } from "./model-switcher.js";
53
+ import { appendRuntimeModelCallLogFromCurrentContext, } from "../observability/runtime-stream-observation.js";
53
54
  const MAX_ITERATIONS = 12;
54
55
  const MAX_TOKENS_PER_TURN = 4096;
55
56
  /**
@@ -61,6 +62,7 @@ const MAX_TOKENS_PER_TURN = 4096;
61
62
  */
62
63
  function emitModelCallLog(line) {
63
64
  process.stderr.write(`[model-call] ${line}\n`);
65
+ appendRuntimeModelCallLogFromCurrentContext(line);
64
66
  }
65
67
  /**
66
68
  * Run a tool-calling conversation until the model produces a final text
@@ -0,0 +1,118 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ const runtimeObservationContext = new AsyncLocalStorage();
5
+ export function runtimeStreamEventLogPath(sessionRoot) {
6
+ return path.join(path.resolve(sessionRoot), "runtime-events.ndjson");
7
+ }
8
+ export function runWithRuntimeObservationContext(context, fn) {
9
+ const normalized = {
10
+ pipeline: context.pipeline,
11
+ sessionRoot: path.resolve(context.sessionRoot),
12
+ ...(context.source ? { source: context.source } : {}),
13
+ };
14
+ return runtimeObservationContext.run(normalized, fn);
15
+ }
16
+ function buildSource(source) {
17
+ const result = {
18
+ kind: source?.kind ?? "runtime",
19
+ label: source?.label ?? source?.kind ?? "runtime",
20
+ };
21
+ if (source?.unitId)
22
+ result.unitId = source.unitId;
23
+ if (source?.stageId)
24
+ result.stageId = source.stageId;
25
+ if (source?.processId !== undefined)
26
+ result.processId = source.processId;
27
+ return result;
28
+ }
29
+ function buildRuntimeStreamEvent(input) {
30
+ const sessionRoot = path.resolve(input.sessionRoot);
31
+ return {
32
+ schema_version: 1,
33
+ event_kind: "runtime_stream",
34
+ timestamp: (input.timestamp ?? new Date()).toISOString(),
35
+ pipeline: input.pipeline,
36
+ session_id: path.basename(sessionRoot),
37
+ session_root: sessionRoot,
38
+ source: buildSource(input.source),
39
+ stream: input.stream,
40
+ message: input.message,
41
+ };
42
+ }
43
+ export function appendRuntimeStreamEventSync(input) {
44
+ try {
45
+ const sessionRoot = path.resolve(input.sessionRoot);
46
+ fs.mkdirSync(sessionRoot, { recursive: true });
47
+ const event = buildRuntimeStreamEvent({ ...input, sessionRoot });
48
+ fs.appendFileSync(runtimeStreamEventLogPath(sessionRoot), `${JSON.stringify(event)}\n`, "utf8");
49
+ }
50
+ catch {
51
+ // Observation is operational; it must never affect pipeline execution.
52
+ }
53
+ }
54
+ export function appendRuntimeStreamChunkSync(input, chunk) {
55
+ const text = String(chunk).replace(/\r\n/g, "\n").replace(/\r/g, "\n");
56
+ for (const line of text.split("\n")) {
57
+ if (line.length === 0)
58
+ continue;
59
+ appendRuntimeStreamEventSync({
60
+ ...input,
61
+ message: line,
62
+ });
63
+ }
64
+ }
65
+ export function appendRuntimeStatusEventSync(args) {
66
+ appendRuntimeStreamEventSync({
67
+ pipeline: args.pipeline,
68
+ sessionRoot: args.sessionRoot,
69
+ source: {
70
+ kind: args.sourceKind ?? "runtime",
71
+ label: args.sourceLabel,
72
+ ...(args.stageId ? { stageId: args.stageId } : {}),
73
+ },
74
+ stream: "status",
75
+ message: args.message,
76
+ });
77
+ }
78
+ export function appendRuntimeModelCallLogFromCurrentContext(line) {
79
+ const context = runtimeObservationContext.getStore();
80
+ if (!context)
81
+ return;
82
+ appendRuntimeStreamEventSync({
83
+ pipeline: context.pipeline,
84
+ sessionRoot: context.sessionRoot,
85
+ source: {
86
+ kind: "llm",
87
+ label: context.source?.label ?? "model-call",
88
+ ...(context.source?.unitId ? { unitId: context.source.unitId } : {}),
89
+ ...(context.source?.stageId ? { stageId: context.source.stageId } : {}),
90
+ },
91
+ stream: "stderr",
92
+ message: `[model-call] ${line}`,
93
+ });
94
+ }
95
+ export function appendRuntimeStreamChunkFromCurrentContextSync(stream, chunk, source) {
96
+ const context = runtimeObservationContext.getStore();
97
+ if (!context)
98
+ return;
99
+ const mergedSource = {
100
+ kind: source?.kind ?? context.source?.kind ?? "runtime",
101
+ label: source?.label ?? context.source?.label ?? "runtime",
102
+ };
103
+ const unitId = source?.unitId ?? context.source?.unitId;
104
+ if (unitId)
105
+ mergedSource.unitId = unitId;
106
+ const stageId = source?.stageId ?? context.source?.stageId;
107
+ if (stageId)
108
+ mergedSource.stageId = stageId;
109
+ const processId = source?.processId ?? context.source?.processId;
110
+ if (processId !== undefined)
111
+ mergedSource.processId = processId;
112
+ appendRuntimeStreamChunkSync({
113
+ pipeline: context.pipeline,
114
+ sessionRoot: context.sessionRoot,
115
+ source: mergedSource,
116
+ stream,
117
+ }, chunk);
118
+ }