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
@@ -0,0 +1,486 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # onto:review live progress watcher
4
+ #
5
+ # Polls .onto/review/{session-id}/error-log.md and renders lens dispatch events.
6
+ # Designed to be invoked automatically (via tmux split-window or iTerm2 osascript)
7
+ # or manually (via this script).
8
+ #
9
+ # Usage:
10
+ # bash scripts/onto-review-watch.sh # auto-discover latest session
11
+ # bash scripts/onto-review-watch.sh /path/to/session # explicit session-root
12
+ #
13
+ # Exits when final-output.md appears (review complete) or on Ctrl+C.
14
+
15
+ set -uo pipefail
16
+
17
+ # Resolve project root from script location
18
+ PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
19
+ cd "$PROJECT_ROOT"
20
+
21
+ # Resolve session-root
22
+ #
23
+ # The auto-spawn path in review-invoke.ts now always passes an explicit
24
+ # session-root, so this zero-arg branch is only exercised by manual
25
+ # manual zero-arg invocations. When multiple review sessions are
26
+ # active concurrently the `.latest-session` pointer and `ls -t` heuristic
27
+ # both point to whichever session was most recently touched — which may
28
+ # not be the one the user wanted to watch. To avoid rendering the wrong
29
+ # session's events, the zero-arg path refuses to guess when more than one
30
+ # session has been active in the recent past; it lists the candidates and
31
+ # exits so the caller can rerun with an explicit argument.
32
+ if [ "${1:-}" != "" ]; then
33
+ SESSION_ROOT="$1"
34
+ else
35
+ # Use each session's error-log.md mtime as the liveness marker.
36
+ # If two or more sessions have a recently updated error-log.md, the
37
+ # zero-arg heuristic is ambiguous; show the candidates and exit so the
38
+ # caller reruns with an explicit session-root.
39
+ RECENT_CANDIDATES=()
40
+ if [ -d ".onto/review" ]; then
41
+ while IFS= read -r error_log; do
42
+ RECENT_CANDIDATES+=("$(dirname "$error_log")")
43
+ done < <(find ".onto/review" -mindepth 2 -maxdepth 2 -type f \
44
+ -name "error-log.md" \
45
+ -newermt "$(date -v-120S '+%Y-%m-%dT%H:%M:%S' 2>/dev/null || date -d '-120 seconds' '+%Y-%m-%dT%H:%M:%S' 2>/dev/null)" \
46
+ 2>/dev/null)
47
+ fi
48
+
49
+ if [ "${#RECENT_CANDIDATES[@]}" -gt 1 ]; then
50
+ echo "${C_YELLOW:-}Ambiguous:${C_RESET:-} multiple review sessions have been active recently:" >&2
51
+ for cand in "${RECENT_CANDIDATES[@]}"; do
52
+ echo " - ${cand}" >&2
53
+ done
54
+ echo "" >&2
55
+ echo "${C_DIM:-}Pass an explicit session-root to avoid picking the wrong one:${C_RESET:-}" >&2
56
+ echo " bash scripts/onto-review-watch.sh \"<session-root>\"" >&2
57
+ exit 2
58
+ fi
59
+
60
+ if [ "${#RECENT_CANDIDATES[@]}" -eq 1 ]; then
61
+ SESSION_ROOT="${RECENT_CANDIDATES[0]}"
62
+ echo "${C_DIM:-}Resolved to ${SESSION_ROOT} via error-log liveness lookup.${C_RESET:-}"
63
+ echo "${C_DIM:-} For explicit targeting: bash scripts/onto-review-watch.sh \"<session-root>\"${C_RESET:-}"
64
+ else
65
+ # No live error-log marker yet; wait for .latest-session to appear, then
66
+ # fall back to the newest session directory. This covers sessions that
67
+ # are still starting and have not created or updated error-log.md.
68
+ echo "${C_DIM:-}Waiting for review session to start (zero-arg mode; no live error-log marker yet)...${C_RESET:-}"
69
+ for i in {1..60}; do
70
+ if [ -f ".onto/review/.latest-session" ]; then
71
+ SESSION_ROOT="$(cat .onto/review/.latest-session)"
72
+ [ -d "$SESSION_ROOT" ] && break
73
+ fi
74
+ sleep 1
75
+ done
76
+
77
+ if [ -z "${SESSION_ROOT:-}" ] || [ ! -d "${SESSION_ROOT:-}" ]; then
78
+ LATEST_DIR="$(ls -t .onto/review/ 2>/dev/null | grep -v '^\.' | head -1)"
79
+ if [ -n "$LATEST_DIR" ] && [ -d ".onto/review/$LATEST_DIR" ]; then
80
+ SESSION_ROOT=".onto/review/$LATEST_DIR"
81
+ fi
82
+ fi
83
+
84
+ if [ -n "${SESSION_ROOT:-}" ] && [ -d "${SESSION_ROOT:-}" ]; then
85
+ echo "${C_DIM:-}Resolved to ${SESSION_ROOT} via zero-arg lookup.${C_RESET:-}"
86
+ echo "${C_DIM:-} For explicit targeting: bash scripts/onto-review-watch.sh \"<session-root>\"${C_RESET:-}"
87
+ fi
88
+ fi
89
+ fi
90
+
91
+ if [ -z "${SESSION_ROOT:-}" ] || [ ! -d "$SESSION_ROOT" ]; then
92
+ echo "Error: no review session found." >&2
93
+ echo " Tried: \$1, error-log liveness lookup, .onto/review/.latest-session, ls .onto/review/" >&2
94
+ exit 1
95
+ fi
96
+
97
+ # Make absolute
98
+ SESSION_ROOT="$(cd "$SESSION_ROOT" && pwd)"
99
+ ERROR_LOG="$SESSION_ROOT/error-log.md"
100
+ EXECUTION_PLAN="$SESSION_ROOT/execution-plan.yaml"
101
+ FINAL_OUTPUT="$SESSION_ROOT/final-output.md"
102
+ SESSION_ID="$(basename "$SESSION_ROOT")"
103
+ # Real-time outer codex stream (nested-workers Codex path only).
104
+ # spawn-watcher/teamlead-executor tee the outer codex stdout into this
105
+ # file as it emits; open in a side pane with `tail -f` to see live
106
+ # reasoning / tool calls / ENV-BEFORE / ENV-AFTER / summary sentinel.
107
+ # The file is absent for other execution profiles.
108
+ NESTED_OUTER_STDOUT="$SESSION_ROOT/nested-outer-stdout.log"
109
+
110
+ # ANSI colors (only if TTY)
111
+ if [ -t 1 ]; then
112
+ C_RESET=$'\033[0m'
113
+ C_BOLD=$'\033[1m'
114
+ C_DIM=$'\033[2m'
115
+ C_GREEN=$'\033[32m'
116
+ C_BLUE=$'\033[34m'
117
+ C_YELLOW=$'\033[33m'
118
+ C_RED=$'\033[31m'
119
+ C_CYAN=$'\033[36m'
120
+ else
121
+ C_RESET=""
122
+ C_BOLD=""
123
+ C_DIM=""
124
+ C_GREEN=""
125
+ C_BLUE=""
126
+ C_YELLOW=""
127
+ C_RED=""
128
+ C_CYAN=""
129
+ fi
130
+
131
+ # Extract a top-level scalar YAML field. Handles both bare and quoted values.
132
+ # Returns empty string when the file or key is missing, so callers can branch
133
+ # on presence without tripping `set -u`.
134
+ read_yaml_scalar() {
135
+ local file="$1" key="$2"
136
+ [ -f "$file" ] || { echo ""; return; }
137
+ sed -n "s/^${key}: *//p" "$file" | head -n 1 | sed 's/^"\(.*\)"$/\1/'
138
+ }
139
+
140
+ file_mtime_epoch() {
141
+ local file="$1"
142
+ local value=""
143
+ [ -e "$file" ] || { echo ""; return; }
144
+ value="$(stat -f %m "$file" 2>/dev/null || true)"
145
+ if [[ "$value" =~ ^[0-9]+$ ]]; then
146
+ echo "$value"
147
+ return
148
+ fi
149
+ value="$(stat -c %Y "$file" 2>/dev/null || true)"
150
+ if [[ "$value" =~ ^[0-9]+$ ]]; then
151
+ echo "$value"
152
+ return
153
+ fi
154
+ echo ""
155
+ }
156
+
157
+ format_age() {
158
+ local epoch="$1"
159
+ [ -n "$epoch" ] || { echo ""; return; }
160
+ local now age
161
+ now="$(date +%s)"
162
+ age=$((now - epoch))
163
+ if [ "$age" -lt 60 ]; then
164
+ echo "${age}s"
165
+ elif [ "$age" -lt 3600 ]; then
166
+ echo "$((age / 60))m"
167
+ else
168
+ echo "$((age / 3600))h"
169
+ fi
170
+ }
171
+
172
+ execution_plan_lens_rows() {
173
+ [ -f "$EXECUTION_PLAN" ] || return
174
+ awk '
175
+ function strip(v) {
176
+ gsub(/^[ \t]+|[ \t]+$/, "", v)
177
+ gsub(/^"/, "", v)
178
+ gsub(/"$/, "", v)
179
+ return v
180
+ }
181
+ function flush() {
182
+ if (lens != "") print lens "|" output
183
+ lens = ""
184
+ output = ""
185
+ }
186
+ /^lens_execution_seats:/ {
187
+ in_lens = 1
188
+ next
189
+ }
190
+ in_lens && /^[^ \t-]/ {
191
+ flush()
192
+ in_lens = 0
193
+ }
194
+ in_lens && /^[ \t]*-[ \t]*lens_id:/ {
195
+ flush()
196
+ value = $0
197
+ sub(/^[ \t]*-[ \t]*lens_id:[ \t]*/, "", value)
198
+ lens = strip(value)
199
+ next
200
+ }
201
+ in_lens && /^[ \t]*lens_id:/ {
202
+ value = $0
203
+ sub(/^[ \t]*lens_id:[ \t]*/, "", value)
204
+ lens = strip(value)
205
+ next
206
+ }
207
+ in_lens && /^[ \t]*output_path:/ {
208
+ value = $0
209
+ sub(/^[ \t]*output_path:[ \t]*/, "", value)
210
+ output = strip(value)
211
+ next
212
+ }
213
+ END {
214
+ if (in_lens) flush()
215
+ }
216
+ ' "$EXECUTION_PLAN"
217
+ }
218
+
219
+ latest_lens_runtime_event() {
220
+ local lens="$1"
221
+ [ -f "$ERROR_LOG" ] || { echo ""; return; }
222
+ awk -v lens="$lens" '
223
+ /^## / {
224
+ if ($0 ~ ("runner dispatch started: " lens "$") ||
225
+ $0 ~ ("runner dispatch retry: " lens "$") ||
226
+ $0 ~ ("runner dispatch completed: " lens "$") ||
227
+ $0 ~ ("runner nested dispatch completed: " lens "$") ||
228
+ $0 ~ ("lens failure: " lens "$")) {
229
+ latest = $0
230
+ }
231
+ }
232
+ END { print latest }
233
+ ' "$ERROR_LOG"
234
+ }
235
+
236
+ unit_signal_epoch() {
237
+ local running_log="$1"
238
+ local latest_epoch=""
239
+ local candidate=""
240
+ if [ -n "$running_log" ]; then
241
+ candidate="$(file_mtime_epoch "$running_log")"
242
+ [ -n "$candidate" ] && latest_epoch="$candidate"
243
+ fi
244
+ candidate="$(file_mtime_epoch "$ERROR_LOG")"
245
+ if [ -n "$candidate" ] && { [ -z "$latest_epoch" ] || [ "$candidate" -gt "$latest_epoch" ]; }; then
246
+ latest_epoch="$candidate"
247
+ fi
248
+ echo "$latest_epoch"
249
+ }
250
+
251
+ LAST_SNAPSHOT=""
252
+ print_lens_snapshot() {
253
+ local rows
254
+ rows="$(execution_plan_lens_rows)"
255
+ [ -n "$rows" ] || return
256
+
257
+ local snapshot=""
258
+ local lens output running_log event status label color detail epoch age
259
+ while IFS='|' read -r lens output; do
260
+ [ -n "$lens" ] || continue
261
+ running_log=""
262
+ if [ -n "$output" ]; then
263
+ running_log="$(dirname "$output")/.${lens}.running.log"
264
+ fi
265
+ event="$(latest_lens_runtime_event "$lens")"
266
+ status="pending"
267
+ if [ -n "$output" ] && [ -s "$output" ]; then
268
+ status="completed"
269
+ elif [[ "$event" == *"runner dispatch completed:"* ]] || [[ "$event" == *"runner nested dispatch completed:"* ]]; then
270
+ status="completed"
271
+ elif [[ "$event" == *"lens failure:"* ]]; then
272
+ status="failed"
273
+ elif [[ "$event" == *"runner dispatch retry:"* ]]; then
274
+ status="retrying"
275
+ elif [[ "$event" == *"runner dispatch started:"* ]] || { [ -n "$running_log" ] && [ -f "$running_log" ]; }; then
276
+ status="running"
277
+ fi
278
+
279
+ epoch="$(unit_signal_epoch "$running_log")"
280
+ age="$(format_age "$epoch")"
281
+ if { [ "$status" = "running" ] || [ "$status" = "retrying" ]; } && [ -n "$epoch" ]; then
282
+ local now stale_age
283
+ now="$(date +%s)"
284
+ stale_age=$((now - epoch))
285
+ if [ "$stale_age" -gt 300 ]; then
286
+ status="running_stale"
287
+ fi
288
+ fi
289
+
290
+ case "$status" in
291
+ completed) label="DONE"; color="$C_GREEN" ;;
292
+ failed) label="FAIL"; color="$C_RED" ;;
293
+ retrying) label="RETRY"; color="$C_YELLOW" ;;
294
+ running_stale) label="STALE"; color="$C_YELLOW" ;;
295
+ running) label="RUN"; color="$C_BLUE" ;;
296
+ *) label="WAIT"; color="$C_DIM" ;;
297
+ esac
298
+
299
+ detail=""
300
+ if [ -n "$running_log" ] && [ -f "$running_log" ]; then
301
+ detail="$running_log"
302
+ elif [ -n "$output" ] && [ -f "$output" ]; then
303
+ detail="$output"
304
+ fi
305
+ [ -n "$age" ] && age=" ${C_DIM}${age}${C_RESET}"
306
+ [ -n "$detail" ] && detail=" ${C_DIM}${detail}${C_RESET}"
307
+ snapshot+=" ${color}${label}${C_RESET} ${lens}${age}${detail}"$'\n'
308
+ done <<< "$rows"
309
+
310
+ [ -n "$snapshot" ] || return
311
+ if [ "$snapshot" != "$LAST_SNAPSHOT" ]; then
312
+ echo "${C_CYAN}──────────────── lens snapshot ────────────────${C_RESET}"
313
+ printf "%s" "$snapshot"
314
+ LAST_SNAPSHOT="$snapshot"
315
+ fi
316
+ }
317
+
318
+ print_header() {
319
+ local metadata="$SESSION_ROOT/session-metadata.yaml"
320
+ local interpretation="$SESSION_ROOT/interpretation.yaml"
321
+ local target domain intent realization host_runtime review_mode profile
322
+ target="$(read_yaml_scalar "$metadata" "requested_target")"
323
+ domain="$(read_yaml_scalar "$metadata" "requested_domain_token")"
324
+ realization="$(read_yaml_scalar "$metadata" "execution_realization")"
325
+ host_runtime="$(read_yaml_scalar "$metadata" "host_runtime")"
326
+ review_mode="$(read_yaml_scalar "$metadata" "review_mode")"
327
+ intent="$(read_yaml_scalar "$interpretation" "intent_summary")"
328
+
329
+ if [ -n "$realization" ] && [ -n "$host_runtime" ]; then
330
+ profile="${realization} + ${host_runtime}"
331
+ [ -n "$review_mode" ] && profile="${profile} (${review_mode})"
332
+ fi
333
+
334
+ echo "${C_CYAN}════════════════════════════════════════════════════════════════${C_RESET}"
335
+ echo "${C_BOLD} onto:review live watcher${C_RESET}"
336
+ echo " Session: ${C_BOLD}${SESSION_ID}${C_RESET}"
337
+ echo " ${C_DIM}${SESSION_ROOT}${C_RESET}"
338
+ if [ -n "$target" ] || [ -n "$intent" ] || [ -n "${profile:-}" ]; then
339
+ echo "${C_CYAN}────────────────────────────────────────────────────────────────${C_RESET}"
340
+ [ -n "$target" ] && echo " Target: ${target}"
341
+ [ -n "$domain" ] && echo " Domain: ${domain}"
342
+ [ -n "$intent" ] && echo " Intent: ${intent}"
343
+ [ -n "${profile:-}" ] && echo " Profile: ${C_DIM}${profile}${C_RESET}"
344
+ fi
345
+ echo "${C_CYAN}════════════════════════════════════════════════════════════════${C_RESET}"
346
+ # Nested-only hint: gate strictly on the outer stream file itself.
347
+ if [ -f "$NESTED_OUTER_STDOUT" ]; then
348
+ echo " ${C_DIM}Outer codex live stream (nested-workers only):${C_RESET}"
349
+ echo " ${C_DIM} tail -f '${NESTED_OUTER_STDOUT}'${C_RESET}"
350
+ echo "${C_CYAN}════════════════════════════════════════════════════════════════${C_RESET}"
351
+ fi
352
+ echo ""
353
+ }
354
+
355
+ print_footer_complete() {
356
+ echo ""
357
+ echo "${C_CYAN}════════════════════════════════════════════════════════════════${C_RESET}"
358
+ echo "${C_GREEN}${C_BOLD} ✓ Review complete${C_RESET}"
359
+ echo " Final: ${FINAL_OUTPUT}"
360
+ echo " Record: ${SESSION_ROOT}/review-record.yaml"
361
+ echo "${C_CYAN}════════════════════════════════════════════════════════════════${C_RESET}"
362
+ echo ""
363
+ echo "${C_DIM}Press Enter to close this pane...${C_RESET}"
364
+ # shellcheck disable=SC2034
365
+ read -r _ || true
366
+ }
367
+
368
+ print_header
369
+ print_lens_snapshot
370
+
371
+ # Session-directory disappearance guard.
372
+ #
373
+ # If the session directory is deleted while we are watching (e.g. the runner
374
+ # aborts and the caller rm -rf's the failed session, or an outer cleanup
375
+ # script moves the tree), continuing to poll an absent file spams the pane
376
+ # with `tail: No such file`. Detect the deletion at each loop head and exit
377
+ # cleanly so stale watcher panes do not outlive their session.
378
+ check_session_alive() {
379
+ if [ ! -d "$SESSION_ROOT" ]; then
380
+ echo ""
381
+ echo "${C_DIM}Session directory removed (${SESSION_ROOT}). Watcher exiting.${C_RESET}"
382
+ exit 0
383
+ fi
384
+ }
385
+
386
+ # Wait for error-log.md to appear (max 60 seconds)
387
+ WAIT_COUNT=0
388
+ while [ ! -f "$ERROR_LOG" ]; do
389
+ check_session_alive
390
+ if [ "$WAIT_COUNT" -ge 60 ]; then
391
+ echo "${C_RED}Error: $ERROR_LOG did not appear within 60s${C_RESET}" >&2
392
+ exit 1
393
+ fi
394
+ if [ "$WAIT_COUNT" -eq 0 ]; then
395
+ echo "${C_DIM}Waiting for runtime to start producing events...${C_RESET}"
396
+ fi
397
+ sleep 1
398
+ WAIT_COUNT=$((WAIT_COUNT + 1))
399
+ done
400
+
401
+ # Trap Ctrl+C for clean exit
402
+ trap 'echo ""; echo "${C_DIM}Watcher stopped (review may still be running).${C_RESET}"; exit 0' INT TERM
403
+
404
+ # Poll loop
405
+ LAST_LINE=0
406
+ LAST_SNAPSHOT_EPOCH=0
407
+ SNAPSHOT_INTERVAL_SECONDS=5
408
+ while true; do
409
+ check_session_alive
410
+ CURRENT_LINES=$(wc -l < "$ERROR_LOG" 2>/dev/null || echo 0)
411
+ if [ "$CURRENT_LINES" -gt "$LAST_LINE" ]; then
412
+ sed -n "$((LAST_LINE + 1)),${CURRENT_LINES}p" "$ERROR_LOG" | awk \
413
+ -v c_green="$C_GREEN" \
414
+ -v c_blue="$C_BLUE" \
415
+ -v c_yellow="$C_YELLOW" \
416
+ -v c_red="$C_RED" \
417
+ -v c_dim="$C_DIM" \
418
+ -v c_reset="$C_RESET" '
419
+ /^## .* runner dispatch started:/ {
420
+ ts = ""
421
+ if (match($0, /## [0-9T:+.-]+/)) {
422
+ ts = substr($0, RSTART + 3, RLENGTH - 3)
423
+ # Extract HH:MM:SS portion
424
+ if (match(ts, /T[0-9:]+/)) {
425
+ ts = substr(ts, RSTART + 1, 8)
426
+ }
427
+ }
428
+ sub(/.*runner dispatch started: /, "")
429
+ printf " %s%s%s %s▶ START%s %s\n", c_dim, ts, c_reset, c_blue, c_reset, $0
430
+ }
431
+ /^## .* runner dispatch completed:/ {
432
+ ts = ""
433
+ if (match($0, /## [0-9T:+.-]+/)) {
434
+ ts = substr($0, RSTART + 3, RLENGTH - 3)
435
+ if (match(ts, /T[0-9:]+/)) {
436
+ ts = substr(ts, RSTART + 1, 8)
437
+ }
438
+ }
439
+ sub(/.*runner dispatch completed: /, "")
440
+ printf " %s%s%s %s✓ DONE%s %s\n", c_dim, ts, c_reset, c_green, c_reset, $0
441
+ }
442
+ /^## .* runner halted:/ {
443
+ ts = ""
444
+ if (match($0, /## [0-9T:+.-]+/)) {
445
+ ts = substr($0, RSTART + 3, RLENGTH - 3)
446
+ if (match(ts, /T[0-9:]+/)) {
447
+ ts = substr(ts, RSTART + 1, 8)
448
+ }
449
+ }
450
+ sub(/.*runner halted: /, "")
451
+ printf " %s%s%s %s✗ HALT%s %s\n", c_dim, ts, c_reset, c_red, c_reset, $0
452
+ }
453
+ /max_concurrent_lenses:/ {
454
+ printf " %s%s%s\n", c_dim, $0, c_reset
455
+ }
456
+ '
457
+ LAST_LINE=$CURRENT_LINES
458
+ print_lens_snapshot
459
+ LAST_SNAPSHOT_EPOCH="$(date +%s)"
460
+ else
461
+ CURRENT_EPOCH="$(date +%s)"
462
+ if [ $((CURRENT_EPOCH - LAST_SNAPSHOT_EPOCH)) -ge "$SNAPSHOT_INTERVAL_SECONDS" ]; then
463
+ print_lens_snapshot
464
+ LAST_SNAPSHOT_EPOCH="$CURRENT_EPOCH"
465
+ fi
466
+ fi
467
+
468
+ if [ -f "$FINAL_OUTPUT" ]; then
469
+ # Final flush, then exit
470
+ sleep 1
471
+ CURRENT_LINES=$(wc -l < "$ERROR_LOG" 2>/dev/null || echo 0)
472
+ if [ "$CURRENT_LINES" -gt "$LAST_LINE" ]; then
473
+ sed -n "$((LAST_LINE + 1)),${CURRENT_LINES}p" "$ERROR_LOG" | awk '
474
+ /runner dispatch completed:/ {
475
+ sub(/.*runner dispatch completed: /, "")
476
+ printf " ✓ DONE %s\n", $0
477
+ }
478
+ '
479
+ fi
480
+ print_lens_snapshot
481
+ print_footer_complete
482
+ exit 0
483
+ fi
484
+
485
+ sleep 1
486
+ done
@@ -0,0 +1,122 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # onto runtime stream watcher
4
+ #
5
+ # Renders runtime-events.ndjson from a review or reconstruct session. The
6
+ # stream is intentionally generic: each line is already tagged with pipeline,
7
+ # source, and stdout/stderr/status by the deterministic runtime.
8
+ #
9
+ # Usage:
10
+ # bash scripts/onto-runtime-watch.sh /path/to/session
11
+ # bash scripts/onto-runtime-watch.sh # newest runtime stream
12
+
13
+ set -uo pipefail
14
+
15
+ PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
16
+ cd "$PROJECT_ROOT"
17
+
18
+ if [ "${1:-}" != "" ]; then
19
+ SESSION_ROOT="$1"
20
+ else
21
+ LATEST_LOG="$(
22
+ find .onto -path '*/runtime-events.ndjson' -type f -print 2>/dev/null \
23
+ | while IFS= read -r log; do
24
+ mtime="$(stat -f %m "$log" 2>/dev/null || stat -c %Y "$log" 2>/dev/null || echo 0)"
25
+ printf '%s\t%s\n' "$mtime" "$log"
26
+ done \
27
+ | sort -rn \
28
+ | head -1 \
29
+ | cut -f2-
30
+ )"
31
+ if [ -n "$LATEST_LOG" ]; then
32
+ SESSION_ROOT="$(dirname "$LATEST_LOG")"
33
+ fi
34
+ fi
35
+
36
+ if [ -z "${SESSION_ROOT:-}" ] || [ ! -d "$SESSION_ROOT" ]; then
37
+ echo "Error: no runtime-observed session found." >&2
38
+ echo " Pass an explicit session-root: bash scripts/onto-runtime-watch.sh \"<session-root>\"" >&2
39
+ exit 1
40
+ fi
41
+
42
+ SESSION_ROOT="$(cd "$SESSION_ROOT" && pwd)"
43
+ EVENT_LOG="$SESSION_ROOT/runtime-events.ndjson"
44
+ SESSION_ID="$(basename "$SESSION_ROOT")"
45
+
46
+ if [ -t 1 ]; then
47
+ C_RESET=$'\033[0m'
48
+ C_BOLD=$'\033[1m'
49
+ C_DIM=$'\033[2m'
50
+ C_GREEN=$'\033[32m'
51
+ C_RED=$'\033[31m'
52
+ C_CYAN=$'\033[36m'
53
+ else
54
+ C_RESET=""
55
+ C_BOLD=""
56
+ C_DIM=""
57
+ C_GREEN=""
58
+ C_RED=""
59
+ C_CYAN=""
60
+ fi
61
+
62
+ echo "${C_BOLD}onto runtime stream${C_RESET} ${C_DIM}${SESSION_ID}${C_RESET}"
63
+ echo "${C_DIM}${SESSION_ROOT}${C_RESET}"
64
+
65
+ for _ in {1..120}; do
66
+ [ -f "$EVENT_LOG" ] && break
67
+ sleep 0.5
68
+ done
69
+
70
+ if [ ! -f "$EVENT_LOG" ]; then
71
+ echo "${C_RED}No runtime-events.ndjson appeared within 60s.${C_RESET}" >&2
72
+ exit 1
73
+ fi
74
+
75
+ tail -n +1 -F "$EVENT_LOG" 2>/dev/null | node -e '
76
+ const readline = require("node:readline");
77
+
78
+ const tty = process.stdout.isTTY;
79
+ const c = {
80
+ reset: tty ? "\u001b[0m" : "",
81
+ dim: tty ? "\u001b[2m" : "",
82
+ green: tty ? "\u001b[32m" : "",
83
+ red: tty ? "\u001b[31m" : "",
84
+ cyan: tty ? "\u001b[36m" : "",
85
+ };
86
+
87
+ function timeOf(value) {
88
+ const date = new Date(value);
89
+ if (Number.isNaN(date.getTime())) return "--:--:--";
90
+ return date.toLocaleTimeString("en-GB", { hour12: false });
91
+ }
92
+
93
+ function streamColor(stream) {
94
+ if (stream === "stderr") return c.red;
95
+ if (stream === "stdout") return c.green;
96
+ return c.cyan;
97
+ }
98
+
99
+ const rl = readline.createInterface({ input: process.stdin });
100
+ rl.on("line", (line) => {
101
+ if (!line.trim()) return;
102
+ let event;
103
+ try {
104
+ event = JSON.parse(line);
105
+ } catch {
106
+ process.stdout.write(`${c.dim}${line}${c.reset}\n`);
107
+ return;
108
+ }
109
+ const source = event.source ?? {};
110
+ const sourceParts = [source.label ?? source.kind ?? "runtime"];
111
+ if (source.unitId) sourceParts.push(source.unitId);
112
+ if (source.stageId) sourceParts.push(source.stageId);
113
+ if (source.processId) sourceParts.push(`pid=${source.processId}`);
114
+ const stream = event.stream ?? "status";
115
+ const prefix =
116
+ `${c.dim}[${timeOf(event.timestamp)}]${c.reset} ` +
117
+ `[${event.pipeline ?? "runtime"}] ` +
118
+ `[${sourceParts.join(":")}] ` +
119
+ `${streamColor(stream)}[${stream}]${c.reset}`;
120
+ process.stdout.write(`${prefix} ${String(event.message ?? "")}\n`);
121
+ });
122
+ '
@@ -0,0 +1,22 @@
1
+ // Post-install hint (dependency-free, ESM).
2
+ //
3
+ // Intentionally does NOT register anything or prompt: npm postinstall runs in
4
+ // many non-interactive contexts (CI, --ignore-scripts, package managers) where
5
+ // a prompt would hang or fail. It only prints a short next-step hint. Wrapped in
6
+ // try/catch so a hint failure can never break the install.
7
+
8
+ try {
9
+ const lines = [
10
+ "",
11
+ "onto-mcp installed.",
12
+ "Next: register the onto MCP server with your hosts:",
13
+ " onto register (interactive: pick hosts in a terminal)",
14
+ " onto register --all --yes (non-interactive: all detected hosts)",
15
+ "Hosts: Claude Code, Codex, Claude Desktop, Cursor.",
16
+ "",
17
+ ];
18
+ // eslint-disable-next-line no-console
19
+ console.log(lines.join("\n"));
20
+ } catch {
21
+ // never fail the install over a hint
22
+ }