open-multi-agent-kit 0.98.3 → 0.98.5

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 (468) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +12 -2
  3. package/dist/cli/args.d.ts +1 -0
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +14 -0
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/cli/help.d.ts.map +1 -1
  8. package/dist/cli/help.js +3 -0
  9. package/dist/cli/help.js.map +1 -1
  10. package/dist/cli/mcp-attach.d.ts +3 -3
  11. package/dist/cli/mcp-attach.d.ts.map +1 -1
  12. package/dist/cli/mcp-attach.js +5 -4
  13. package/dist/cli/mcp-attach.js.map +1 -1
  14. package/dist/cli/model-contract.d.ts +5 -0
  15. package/dist/cli/model-contract.d.ts.map +1 -0
  16. package/dist/cli/model-contract.js +45 -0
  17. package/dist/cli/model-contract.js.map +1 -0
  18. package/dist/commands/adaptorch-doctor-cli.d.ts.map +1 -1
  19. package/dist/commands/adaptorch-doctor-cli.js +32 -10
  20. package/dist/commands/adaptorch-doctor-cli.js.map +1 -1
  21. package/dist/commands/init-cli.d.ts +12 -0
  22. package/dist/commands/init-cli.d.ts.map +1 -0
  23. package/dist/commands/init-cli.js +76 -0
  24. package/dist/commands/init-cli.js.map +1 -0
  25. package/dist/commands/provider-sync-cli.d.ts +27 -0
  26. package/dist/commands/provider-sync-cli.d.ts.map +1 -0
  27. package/dist/commands/provider-sync-cli.js +177 -0
  28. package/dist/commands/provider-sync-cli.js.map +1 -0
  29. package/dist/commands/run-command.d.ts +9 -0
  30. package/dist/commands/run-command.d.ts.map +1 -0
  31. package/dist/commands/run-command.js +34 -0
  32. package/dist/commands/run-command.js.map +1 -0
  33. package/dist/commands/verified-run-cli.d.ts +6 -0
  34. package/dist/commands/verified-run-cli.d.ts.map +1 -0
  35. package/dist/commands/verified-run-cli.js +190 -0
  36. package/dist/commands/verified-run-cli.js.map +1 -0
  37. package/dist/core/active-skill-state.d.ts +7 -0
  38. package/dist/core/active-skill-state.d.ts.map +1 -0
  39. package/dist/core/active-skill-state.js +25 -0
  40. package/dist/core/active-skill-state.js.map +1 -0
  41. package/dist/core/agent-session-services.d.ts +10 -1
  42. package/dist/core/agent-session-services.d.ts.map +1 -1
  43. package/dist/core/agent-session-services.js +43 -0
  44. package/dist/core/agent-session-services.js.map +1 -1
  45. package/dist/core/agent-session.d.ts +7 -9
  46. package/dist/core/agent-session.d.ts.map +1 -1
  47. package/dist/core/agent-session.js +91 -126
  48. package/dist/core/agent-session.js.map +1 -1
  49. package/dist/core/codex-chatgpt-web-bridge.d.ts +99 -0
  50. package/dist/core/codex-chatgpt-web-bridge.d.ts.map +1 -0
  51. package/dist/core/codex-chatgpt-web-bridge.js +192 -0
  52. package/dist/core/codex-chatgpt-web-bridge.js.map +1 -0
  53. package/dist/core/codex-chatgpt-web-sync.d.ts +50 -0
  54. package/dist/core/codex-chatgpt-web-sync.d.ts.map +1 -0
  55. package/dist/core/codex-chatgpt-web-sync.js +119 -0
  56. package/dist/core/codex-chatgpt-web-sync.js.map +1 -0
  57. package/dist/core/compaction/compaction-headroom.d.ts +30 -0
  58. package/dist/core/compaction/compaction-headroom.d.ts.map +1 -0
  59. package/dist/core/compaction/compaction-headroom.js +48 -0
  60. package/dist/core/compaction/compaction-headroom.js.map +1 -0
  61. package/dist/core/compaction/compaction.d.ts +2 -29
  62. package/dist/core/compaction/compaction.d.ts.map +1 -1
  63. package/dist/core/compaction/compaction.js +19 -47
  64. package/dist/core/compaction/compaction.js.map +1 -1
  65. package/dist/core/compaction/overflow-retry-guard.d.ts +20 -0
  66. package/dist/core/compaction/overflow-retry-guard.d.ts.map +1 -0
  67. package/dist/core/compaction/overflow-retry-guard.js +38 -0
  68. package/dist/core/compaction/overflow-retry-guard.js.map +1 -0
  69. package/dist/core/context-budget-headroom-types.d.ts.map +1 -1
  70. package/dist/core/context-budget-headroom-types.js +1 -1
  71. package/dist/core/context-budget-headroom-types.js.map +1 -1
  72. package/dist/core/context-budget-token-counter-types.d.ts +27 -0
  73. package/dist/core/context-budget-token-counter-types.d.ts.map +1 -0
  74. package/dist/core/context-budget-token-counter-types.js +2 -0
  75. package/dist/core/context-budget-token-counter-types.js.map +1 -0
  76. package/dist/core/context-budget-token-counter.d.ts +2 -26
  77. package/dist/core/context-budget-token-counter.d.ts.map +1 -1
  78. package/dist/core/context-budget-token-counter.js +2 -0
  79. package/dist/core/context-budget-token-counter.js.map +1 -1
  80. package/dist/core/context-budget-v2-scoring.d.ts.map +1 -1
  81. package/dist/core/context-budget-v2-scoring.js +14 -10
  82. package/dist/core/context-budget-v2-scoring.js.map +1 -1
  83. package/dist/core/domain-router.d.ts.map +1 -1
  84. package/dist/core/domain-router.js +1 -1
  85. package/dist/core/domain-router.js.map +1 -1
  86. package/dist/core/grok-harness-dispatch.d.ts +4 -0
  87. package/dist/core/grok-harness-dispatch.d.ts.map +1 -1
  88. package/dist/core/grok-harness-dispatch.js +20 -3
  89. package/dist/core/grok-harness-dispatch.js.map +1 -1
  90. package/dist/core/grok-harness.d.ts +15 -9
  91. package/dist/core/grok-harness.d.ts.map +1 -1
  92. package/dist/core/grok-harness.js +34 -8
  93. package/dist/core/grok-harness.js.map +1 -1
  94. package/dist/core/mcp/tools.d.ts +2 -2
  95. package/dist/core/mcp/tools.d.ts.map +1 -1
  96. package/dist/core/mcp/tools.js +29 -3
  97. package/dist/core/mcp/tools.js.map +1 -1
  98. package/dist/core/model-registry-schema.d.ts +1081 -0
  99. package/dist/core/model-registry-schema.d.ts.map +1 -0
  100. package/dist/core/model-registry-schema.js +148 -0
  101. package/dist/core/model-registry-schema.js.map +1 -0
  102. package/dist/core/model-registry.d.ts.map +1 -1
  103. package/dist/core/model-registry.js +1 -146
  104. package/dist/core/model-registry.js.map +1 -1
  105. package/dist/core/model-resolver.d.ts +2 -1
  106. package/dist/core/model-resolver.d.ts.map +1 -1
  107. package/dist/core/model-resolver.js +2 -1
  108. package/dist/core/model-resolver.js.map +1 -1
  109. package/dist/core/prompt-preset.d.ts +1 -1
  110. package/dist/core/prompt-preset.d.ts.map +1 -1
  111. package/dist/core/prompt-preset.js +16 -1
  112. package/dist/core/prompt-preset.js.map +1 -1
  113. package/dist/core/prompt-settlement.d.ts +4 -3
  114. package/dist/core/prompt-settlement.d.ts.map +1 -1
  115. package/dist/core/prompt-settlement.js.map +1 -1
  116. package/dist/core/provider-display-names.d.ts.map +1 -1
  117. package/dist/core/provider-display-names.js +1 -0
  118. package/dist/core/provider-display-names.js.map +1 -1
  119. package/dist/core/provider-resilience.d.ts +8 -0
  120. package/dist/core/provider-resilience.d.ts.map +1 -1
  121. package/dist/core/provider-resilience.js +20 -3
  122. package/dist/core/provider-resilience.js.map +1 -1
  123. package/dist/core/provider-usage-types.d.ts +42 -0
  124. package/dist/core/provider-usage-types.d.ts.map +1 -0
  125. package/dist/core/provider-usage-types.js +2 -0
  126. package/dist/core/provider-usage-types.js.map +1 -0
  127. package/dist/core/provider-usage.d.ts +2 -31
  128. package/dist/core/provider-usage.d.ts.map +1 -1
  129. package/dist/core/provider-usage.js +4 -0
  130. package/dist/core/provider-usage.js.map +1 -1
  131. package/dist/core/redaction.d.ts.map +1 -1
  132. package/dist/core/redaction.js +18 -2
  133. package/dist/core/redaction.js.map +1 -1
  134. package/dist/core/run-budget-policy.d.ts +18 -0
  135. package/dist/core/run-budget-policy.d.ts.map +1 -0
  136. package/dist/core/run-budget-policy.js +52 -0
  137. package/dist/core/run-budget-policy.js.map +1 -0
  138. package/dist/core/run-budget.d.ts +33 -0
  139. package/dist/core/run-budget.d.ts.map +1 -0
  140. package/dist/core/run-budget.js +89 -0
  141. package/dist/core/run-budget.js.map +1 -0
  142. package/dist/core/run-execution-api.d.ts +15 -0
  143. package/dist/core/run-execution-api.d.ts.map +1 -0
  144. package/dist/core/run-execution-api.js +7 -0
  145. package/dist/core/run-execution-api.js.map +1 -0
  146. package/dist/core/run-journal.d.ts.map +1 -1
  147. package/dist/core/run-journal.js +30 -208
  148. package/dist/core/run-journal.js.map +1 -1
  149. package/dist/core/sandbox/policy-merge.d.ts +6 -0
  150. package/dist/core/sandbox/policy-merge.d.ts.map +1 -0
  151. package/dist/core/sandbox/policy-merge.js +74 -0
  152. package/dist/core/sandbox/policy-merge.js.map +1 -0
  153. package/dist/core/sandbox/policy-paths.d.ts +4 -0
  154. package/dist/core/sandbox/policy-paths.d.ts.map +1 -0
  155. package/dist/core/sandbox/policy-paths.js +21 -0
  156. package/dist/core/sandbox/policy-paths.js.map +1 -0
  157. package/dist/core/sandbox/policy-types.d.ts +75 -0
  158. package/dist/core/sandbox/policy-types.d.ts.map +1 -0
  159. package/dist/core/sandbox/policy-types.js +2 -0
  160. package/dist/core/sandbox/policy-types.js.map +1 -0
  161. package/dist/core/sandbox/policy.d.ts +3 -77
  162. package/dist/core/sandbox/policy.d.ts.map +1 -1
  163. package/dist/core/sandbox/policy.js +3 -98
  164. package/dist/core/sandbox/policy.js.map +1 -1
  165. package/dist/core/sdk-provider-stream.d.ts +14 -0
  166. package/dist/core/sdk-provider-stream.d.ts.map +1 -0
  167. package/dist/core/sdk-provider-stream.js +38 -0
  168. package/dist/core/sdk-provider-stream.js.map +1 -0
  169. package/dist/core/sdk.d.ts +5 -1
  170. package/dist/core/sdk.d.ts.map +1 -1
  171. package/dist/core/sdk.js +17 -33
  172. package/dist/core/sdk.js.map +1 -1
  173. package/dist/core/session-bash-service.d.ts +2 -2
  174. package/dist/core/session-bash-service.d.ts.map +1 -1
  175. package/dist/core/session-bash-service.js +21 -9
  176. package/dist/core/session-bash-service.js.map +1 -1
  177. package/dist/core/session-failure-cause.d.ts.map +1 -1
  178. package/dist/core/session-failure-cause.js +15 -3
  179. package/dist/core/session-failure-cause.js.map +1 -1
  180. package/dist/core/session-prompt-lifecycle.d.ts +25 -0
  181. package/dist/core/session-prompt-lifecycle.d.ts.map +1 -0
  182. package/dist/core/session-prompt-lifecycle.js +87 -0
  183. package/dist/core/session-prompt-lifecycle.js.map +1 -0
  184. package/dist/core/session-run-budget.d.ts +28 -0
  185. package/dist/core/session-run-budget.d.ts.map +1 -0
  186. package/dist/core/session-run-budget.js +127 -0
  187. package/dist/core/session-run-budget.js.map +1 -0
  188. package/dist/core/session-run-termination.d.ts +18 -0
  189. package/dist/core/session-run-termination.d.ts.map +1 -0
  190. package/dist/core/session-run-termination.js +72 -0
  191. package/dist/core/session-run-termination.js.map +1 -0
  192. package/dist/core/session-termination-types.d.ts +97 -0
  193. package/dist/core/session-termination-types.d.ts.map +1 -0
  194. package/dist/core/session-termination-types.js +26 -0
  195. package/dist/core/session-termination-types.js.map +1 -0
  196. package/dist/core/session-termination.d.ts +3 -97
  197. package/dist/core/session-termination.d.ts.map +1 -1
  198. package/dist/core/session-termination.js +25 -29
  199. package/dist/core/session-termination.js.map +1 -1
  200. package/dist/core/skill-selector.d.ts +40 -0
  201. package/dist/core/skill-selector.d.ts.map +1 -0
  202. package/dist/core/skill-selector.js +102 -0
  203. package/dist/core/skill-selector.js.map +1 -0
  204. package/dist/core/slash-commands.d.ts.map +1 -1
  205. package/dist/core/slash-commands.js +1 -0
  206. package/dist/core/slash-commands.js.map +1 -1
  207. package/dist/core/subagent-lane-launcher.d.ts +3 -2
  208. package/dist/core/subagent-lane-launcher.d.ts.map +1 -1
  209. package/dist/core/subagent-lane-launcher.js +24 -13
  210. package/dist/core/subagent-lane-launcher.js.map +1 -1
  211. package/dist/core/tools/render-utils.d.ts.map +1 -1
  212. package/dist/core/tools/render-utils.js +2 -4
  213. package/dist/core/tools/render-utils.js.map +1 -1
  214. package/dist/core/turn-metrics-record.d.ts +55 -0
  215. package/dist/core/turn-metrics-record.d.ts.map +1 -0
  216. package/dist/core/turn-metrics-record.js +149 -0
  217. package/dist/core/turn-metrics-record.js.map +1 -0
  218. package/dist/core/turn-metrics.d.ts +4 -56
  219. package/dist/core/turn-metrics.d.ts.map +1 -1
  220. package/dist/core/turn-metrics.js +12 -60
  221. package/dist/core/turn-metrics.js.map +1 -1
  222. package/dist/core/verified-run/broker.d.ts +26 -0
  223. package/dist/core/verified-run/broker.d.ts.map +1 -0
  224. package/dist/core/verified-run/broker.js +210 -0
  225. package/dist/core/verified-run/broker.js.map +1 -0
  226. package/dist/core/verified-run/candidate.d.ts +24 -0
  227. package/dist/core/verified-run/candidate.d.ts.map +1 -0
  228. package/dist/core/verified-run/candidate.js +167 -0
  229. package/dist/core/verified-run/candidate.js.map +1 -0
  230. package/dist/core/verified-run/check-receipt.d.ts +18 -0
  231. package/dist/core/verified-run/check-receipt.d.ts.map +1 -0
  232. package/dist/core/verified-run/check-receipt.js +92 -0
  233. package/dist/core/verified-run/check-receipt.js.map +1 -0
  234. package/dist/core/verified-run/coordinator.d.ts +39 -0
  235. package/dist/core/verified-run/coordinator.d.ts.map +1 -0
  236. package/dist/core/verified-run/coordinator.js +190 -0
  237. package/dist/core/verified-run/coordinator.js.map +1 -0
  238. package/dist/core/verified-run/dag-candidates.d.ts +8 -0
  239. package/dist/core/verified-run/dag-candidates.d.ts.map +1 -0
  240. package/dist/core/verified-run/dag-candidates.js +65 -0
  241. package/dist/core/verified-run/dag-candidates.js.map +1 -0
  242. package/dist/core/verified-run/dag-phase.d.ts +7 -0
  243. package/dist/core/verified-run/dag-phase.d.ts.map +1 -0
  244. package/dist/core/verified-run/dag-phase.js +92 -0
  245. package/dist/core/verified-run/dag-phase.js.map +1 -0
  246. package/dist/core/verified-run/dag-projection.d.ts +7 -0
  247. package/dist/core/verified-run/dag-projection.d.ts.map +1 -0
  248. package/dist/core/verified-run/dag-projection.js +90 -0
  249. package/dist/core/verified-run/dag-projection.js.map +1 -0
  250. package/dist/core/verified-run/dag-recovery.d.ts +13 -0
  251. package/dist/core/verified-run/dag-recovery.d.ts.map +1 -0
  252. package/dist/core/verified-run/dag-recovery.js +98 -0
  253. package/dist/core/verified-run/dag-recovery.js.map +1 -0
  254. package/dist/core/verified-run/dag-retry-projection.d.ts +9 -0
  255. package/dist/core/verified-run/dag-retry-projection.d.ts.map +1 -0
  256. package/dist/core/verified-run/dag-retry-projection.js +43 -0
  257. package/dist/core/verified-run/dag-retry-projection.js.map +1 -0
  258. package/dist/core/verified-run/dag-types.d.ts +47 -0
  259. package/dist/core/verified-run/dag-types.d.ts.map +1 -0
  260. package/dist/core/verified-run/dag-types.js +2 -0
  261. package/dist/core/verified-run/dag-types.js.map +1 -0
  262. package/dist/core/verified-run/event-parser.d.ts +3 -0
  263. package/dist/core/verified-run/event-parser.d.ts.map +1 -0
  264. package/dist/core/verified-run/event-parser.js +153 -0
  265. package/dist/core/verified-run/event-parser.js.map +1 -0
  266. package/dist/core/verified-run/events.d.ts +4 -0
  267. package/dist/core/verified-run/events.d.ts.map +1 -0
  268. package/dist/core/verified-run/events.js +3 -0
  269. package/dist/core/verified-run/events.js.map +1 -0
  270. package/dist/core/verified-run/evidence-binding.d.ts +18 -0
  271. package/dist/core/verified-run/evidence-binding.d.ts.map +1 -0
  272. package/dist/core/verified-run/evidence-binding.js +81 -0
  273. package/dist/core/verified-run/evidence-binding.js.map +1 -0
  274. package/dist/core/verified-run/evidence.d.ts +27 -0
  275. package/dist/core/verified-run/evidence.d.ts.map +1 -0
  276. package/dist/core/verified-run/evidence.js +100 -0
  277. package/dist/core/verified-run/evidence.js.map +1 -0
  278. package/dist/core/verified-run/journal.d.ts +32 -0
  279. package/dist/core/verified-run/journal.d.ts.map +1 -0
  280. package/dist/core/verified-run/journal.js +103 -0
  281. package/dist/core/verified-run/journal.js.map +1 -0
  282. package/dist/core/verified-run/namespace-identity.d.ts +11 -0
  283. package/dist/core/verified-run/namespace-identity.d.ts.map +1 -0
  284. package/dist/core/verified-run/namespace-identity.js +77 -0
  285. package/dist/core/verified-run/namespace-identity.js.map +1 -0
  286. package/dist/core/verified-run/owned-execution.d.ts +21 -0
  287. package/dist/core/verified-run/owned-execution.d.ts.map +1 -0
  288. package/dist/core/verified-run/owned-execution.js +43 -0
  289. package/dist/core/verified-run/owned-execution.js.map +1 -0
  290. package/dist/core/verified-run/phase-context.d.ts +9 -0
  291. package/dist/core/verified-run/phase-context.d.ts.map +1 -0
  292. package/dist/core/verified-run/phase-context.js +2 -0
  293. package/dist/core/verified-run/phase-context.js.map +1 -0
  294. package/dist/core/verified-run/process-gate.d.ts +5 -0
  295. package/dist/core/verified-run/process-gate.d.ts.map +1 -0
  296. package/dist/core/verified-run/process-gate.js +31 -0
  297. package/dist/core/verified-run/process-gate.js.map +1 -0
  298. package/dist/core/verified-run/projection.d.ts +4 -0
  299. package/dist/core/verified-run/projection.d.ts.map +1 -0
  300. package/dist/core/verified-run/projection.js +219 -0
  301. package/dist/core/verified-run/projection.js.map +1 -0
  302. package/dist/core/verified-run/recovery-clock.d.ts +19 -0
  303. package/dist/core/verified-run/recovery-clock.d.ts.map +1 -0
  304. package/dist/core/verified-run/recovery-clock.js +69 -0
  305. package/dist/core/verified-run/recovery-clock.js.map +1 -0
  306. package/dist/core/verified-run/recovery-command.d.ts +11 -0
  307. package/dist/core/verified-run/recovery-command.d.ts.map +1 -0
  308. package/dist/core/verified-run/recovery-command.js +73 -0
  309. package/dist/core/verified-run/recovery-command.js.map +1 -0
  310. package/dist/core/verified-run/recovery-projection.d.ts +12 -0
  311. package/dist/core/verified-run/recovery-projection.d.ts.map +1 -0
  312. package/dist/core/verified-run/recovery-projection.js +88 -0
  313. package/dist/core/verified-run/recovery-projection.js.map +1 -0
  314. package/dist/core/verified-run/recovery.d.ts +12 -0
  315. package/dist/core/verified-run/recovery.d.ts.map +1 -0
  316. package/dist/core/verified-run/recovery.js +115 -0
  317. package/dist/core/verified-run/recovery.js.map +1 -0
  318. package/dist/core/verified-run/run-types.d.ts +103 -0
  319. package/dist/core/verified-run/run-types.d.ts.map +1 -0
  320. package/dist/core/verified-run/run-types.js +2 -0
  321. package/dist/core/verified-run/run-types.js.map +1 -0
  322. package/dist/core/verified-run/scripted-writer.d.ts +15 -0
  323. package/dist/core/verified-run/scripted-writer.d.ts.map +1 -0
  324. package/dist/core/verified-run/scripted-writer.js +94 -0
  325. package/dist/core/verified-run/scripted-writer.js.map +1 -0
  326. package/dist/core/verified-run/session-port.d.ts +27 -0
  327. package/dist/core/verified-run/session-port.d.ts.map +1 -0
  328. package/dist/core/verified-run/session-port.js +2 -0
  329. package/dist/core/verified-run/session-port.js.map +1 -0
  330. package/dist/core/verified-run/storage.d.ts +15 -0
  331. package/dist/core/verified-run/storage.d.ts.map +1 -0
  332. package/dist/core/verified-run/storage.js +96 -0
  333. package/dist/core/verified-run/storage.js.map +1 -0
  334. package/dist/core/verified-run/verification-phase.d.ts +5 -0
  335. package/dist/core/verified-run/verification-phase.d.ts.map +1 -0
  336. package/dist/core/verified-run/verification-phase.js +56 -0
  337. package/dist/core/verified-run/verification-phase.js.map +1 -0
  338. package/dist/core/verified-run/work-recovery.d.ts +8 -0
  339. package/dist/core/verified-run/work-recovery.d.ts.map +1 -0
  340. package/dist/core/verified-run/work-recovery.js +44 -0
  341. package/dist/core/verified-run/work-recovery.js.map +1 -0
  342. package/dist/core/verified-run/writer-completion.d.ts +4 -0
  343. package/dist/core/verified-run/writer-completion.d.ts.map +1 -0
  344. package/dist/core/verified-run/writer-completion.js +27 -0
  345. package/dist/core/verified-run/writer-completion.js.map +1 -0
  346. package/dist/core/verified-run/writer-phase.d.ts +8 -0
  347. package/dist/core/verified-run/writer-phase.d.ts.map +1 -0
  348. package/dist/core/verified-run/writer-phase.js +76 -0
  349. package/dist/core/verified-run/writer-phase.js.map +1 -0
  350. package/dist/core/verified-run/writer-projection.d.ts +11 -0
  351. package/dist/core/verified-run/writer-projection.d.ts.map +1 -0
  352. package/dist/core/verified-run/writer-projection.js +70 -0
  353. package/dist/core/verified-run/writer-projection.js.map +1 -0
  354. package/dist/core/verified-run/writer-recovery.d.ts +16 -0
  355. package/dist/core/verified-run/writer-recovery.d.ts.map +1 -0
  356. package/dist/core/verified-run/writer-recovery.js +107 -0
  357. package/dist/core/verified-run/writer-recovery.js.map +1 -0
  358. package/dist/core/workload-permit-pool.d.ts +1 -3
  359. package/dist/core/workload-permit-pool.d.ts.map +1 -1
  360. package/dist/core/workload-permit-pool.js +11 -11
  361. package/dist/core/workload-permit-pool.js.map +1 -1
  362. package/dist/guardrails/evidence-system.d.ts +1 -1
  363. package/dist/guardrails/evidence-system.d.ts.map +1 -1
  364. package/dist/guardrails/evidence-system.js +18 -29
  365. package/dist/guardrails/evidence-system.js.map +1 -1
  366. package/dist/guardrails/merge-gate-result.d.ts +4 -0
  367. package/dist/guardrails/merge-gate-result.d.ts.map +1 -0
  368. package/dist/guardrails/merge-gate-result.js +32 -0
  369. package/dist/guardrails/merge-gate-result.js.map +1 -0
  370. package/dist/index.d.ts +3 -2
  371. package/dist/index.d.ts.map +1 -1
  372. package/dist/index.js +2 -2
  373. package/dist/index.js.map +1 -1
  374. package/dist/main.d.ts.map +1 -1
  375. package/dist/main.js +17 -23
  376. package/dist/main.js.map +1 -1
  377. package/dist/modes/interactive/components/session-failure.d.ts +13 -0
  378. package/dist/modes/interactive/components/session-failure.d.ts.map +1 -0
  379. package/dist/modes/interactive/components/session-failure.js +81 -0
  380. package/dist/modes/interactive/components/session-failure.js.map +1 -0
  381. package/dist/modes/interactive/interactive-login-options.d.ts +27 -0
  382. package/dist/modes/interactive/interactive-login-options.d.ts.map +1 -0
  383. package/dist/modes/interactive/interactive-login-options.js +54 -0
  384. package/dist/modes/interactive/interactive-login-options.js.map +1 -0
  385. package/dist/modes/interactive/interactive-mode.d.ts +8 -4
  386. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  387. package/dist/modes/interactive/interactive-mode.js +183 -171
  388. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  389. package/dist/modes/interactive/interactive-resume-command.d.ts +3 -0
  390. package/dist/modes/interactive/interactive-resume-command.d.ts.map +1 -0
  391. package/dist/modes/interactive/interactive-resume-command.js +24 -0
  392. package/dist/modes/interactive/interactive-resume-command.js.map +1 -0
  393. package/dist/modes/interactive/interactive-tool-result.d.ts +32 -0
  394. package/dist/modes/interactive/interactive-tool-result.d.ts.map +1 -0
  395. package/dist/modes/interactive/interactive-tool-result.js +59 -0
  396. package/dist/modes/interactive/interactive-tool-result.js.map +1 -0
  397. package/dist/modes/interactive/tui-diagnostics.d.ts +36 -0
  398. package/dist/modes/interactive/tui-diagnostics.d.ts.map +1 -0
  399. package/dist/modes/interactive/tui-diagnostics.js +105 -0
  400. package/dist/modes/interactive/tui-diagnostics.js.map +1 -0
  401. package/dist/modes/interactive/tui-runtime-info.d.ts +20 -0
  402. package/dist/modes/interactive/tui-runtime-info.d.ts.map +1 -0
  403. package/dist/modes/interactive/tui-runtime-info.js +76 -0
  404. package/dist/modes/interactive/tui-runtime-info.js.map +1 -0
  405. package/dist/modes/print-mode.d.ts.map +1 -1
  406. package/dist/modes/print-mode.js +22 -0
  407. package/dist/modes/print-mode.js.map +1 -1
  408. package/dist/utils/clipboard-image.d.ts.map +1 -1
  409. package/dist/utils/clipboard-image.js +10 -60
  410. package/dist/utils/clipboard-image.js.map +1 -1
  411. package/dist/utils/terminal-links.d.ts +13 -0
  412. package/dist/utils/terminal-links.d.ts.map +1 -0
  413. package/dist/utils/terminal-links.js +68 -0
  414. package/dist/utils/terminal-links.js.map +1 -0
  415. package/dist/utils/windows-clipboard-image.d.ts +16 -0
  416. package/dist/utils/windows-clipboard-image.d.ts.map +1 -0
  417. package/dist/utils/windows-clipboard-image.js +87 -0
  418. package/dist/utils/windows-clipboard-image.js.map +1 -0
  419. package/docs/adaptorch-onboarding.md +80 -0
  420. package/docs/containerization.md +12 -0
  421. package/docs/context-files.md +97 -0
  422. package/docs/correctness-wall.md +8 -0
  423. package/docs/custom-provider.md +35 -0
  424. package/docs/development.md +28 -3
  425. package/docs/environment-variables.md +2 -0
  426. package/docs/grok-harness.md +4 -0
  427. package/docs/harness-boundaries.md +154 -0
  428. package/docs/harness-improvements.md +90 -0
  429. package/docs/json.md +19 -0
  430. package/docs/keybindings.md +2 -2
  431. package/docs/mcp.md +22 -2
  432. package/docs/metrics.md +66 -16
  433. package/docs/model-catalog-refresh.md +190 -0
  434. package/docs/model-contract.md +168 -0
  435. package/docs/models.md +21 -4
  436. package/docs/provider-resilience.md +5 -3
  437. package/docs/providers.md +68 -1
  438. package/docs/quickstart.md +4 -0
  439. package/docs/release-audit-0.98.4.md +112 -0
  440. package/docs/release-audit-0.98.5.md +84 -0
  441. package/docs/review-bundle-followup.md +195 -0
  442. package/docs/run-protocol.md +33 -1
  443. package/docs/runtime-algorithms.md +45 -0
  444. package/docs/sdk.md +204 -2
  445. package/docs/sessions.md +1 -1
  446. package/docs/settings.md +17 -1
  447. package/docs/skills.md +2 -0
  448. package/docs/tb21-audit.md +131 -0
  449. package/docs/terminal-setup.md +20 -0
  450. package/docs/usage.md +77 -1
  451. package/docs/verified-run-testing.md +417 -0
  452. package/docs/verified-run.md +388 -0
  453. package/docs/windows.md +48 -0
  454. package/examples/README.md +4 -0
  455. package/examples/context/AGENTS.md +64 -0
  456. package/examples/context/CLAUDE.md +17 -0
  457. package/examples/context/INTERNET.md +42 -0
  458. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  459. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  460. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  461. package/examples/extensions/gondolin/package-lock.json +2 -2
  462. package/examples/extensions/gondolin/package.json +1 -1
  463. package/examples/extensions/sandbox/package-lock.json +2 -2
  464. package/examples/extensions/sandbox/package.json +1 -1
  465. package/examples/extensions/with-deps/package-lock.json +2 -2
  466. package/examples/extensions/with-deps/package.json +1 -1
  467. package/npm-shrinkwrap.json +18 -18
  468. package/package.json +6 -6
@@ -0,0 +1,3 @@
1
+ import type { SessionManager } from "../../core/session-manager.ts";
2
+ export declare function formatResumeCommand(sessionManager: SessionManager): string | undefined;
3
+ //# sourceMappingURL=interactive-resume-command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive-resume-command.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-resume-command.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AASpE,wBAAgB,mBAAmB,CAAC,cAAc,EAAE,cAAc,GAAG,MAAM,GAAG,SAAS,CAatF","sourcesContent":["import * as fs from \"node:fs\";\nimport { APP_NAME } from \"../../config.ts\";\nimport type { SessionManager } from \"../../core/session-manager.ts\";\n\nfunction quoteIfNeeded(value: string): string {\n\tif (value.length > 0 && !/[^a-zA-Z0-9_\\-./~:@]/.test(value)) {\n\t\treturn value;\n\t}\n\treturn `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n\nexport function formatResumeCommand(sessionManager: SessionManager): string | undefined {\n\tif (!process.stdout.isTTY) return undefined;\n\tif (!sessionManager.isPersisted()) return undefined;\n\n\tconst sessionFile = sessionManager.getSessionFile();\n\tif (!sessionFile || !fs.existsSync(sessionFile)) return undefined;\n\n\tconst args = [APP_NAME];\n\tif (!sessionManager.usesDefaultSessionDir()) {\n\t\targs.push(\"--session-dir\", quoteIfNeeded(sessionManager.getSessionDir()));\n\t}\n\targs.push(\"--session\", sessionManager.getSessionId());\n\treturn args.join(\" \");\n}\n"]}
@@ -0,0 +1,24 @@
1
+ import * as fs from "node:fs";
2
+ import { APP_NAME } from "../../config.js";
3
+ function quoteIfNeeded(value) {
4
+ if (value.length > 0 && !/[^a-zA-Z0-9_\-./~:@]/.test(value)) {
5
+ return value;
6
+ }
7
+ return `'${value.replace(/'/g, `'\\''`)}'`;
8
+ }
9
+ export function formatResumeCommand(sessionManager) {
10
+ if (!process.stdout.isTTY)
11
+ return undefined;
12
+ if (!sessionManager.isPersisted())
13
+ return undefined;
14
+ const sessionFile = sessionManager.getSessionFile();
15
+ if (!sessionFile || !fs.existsSync(sessionFile))
16
+ return undefined;
17
+ const args = [APP_NAME];
18
+ if (!sessionManager.usesDefaultSessionDir()) {
19
+ args.push("--session-dir", quoteIfNeeded(sessionManager.getSessionDir()));
20
+ }
21
+ args.push("--session", sessionManager.getSessionId());
22
+ return args.join(" ");
23
+ }
24
+ //# sourceMappingURL=interactive-resume-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive-resume-command.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-resume-command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAG3C,SAAS,aAAa,CAAC,KAAa,EAAU;IAC7C,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7D,OAAO,KAAK,CAAC;IACd,CAAC;IACD,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC;AAAA,CAC3C;AAED,MAAM,UAAU,mBAAmB,CAAC,cAA8B,EAAsB;IACvF,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC5C,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE;QAAE,OAAO,SAAS,CAAC;IAEpD,MAAM,WAAW,GAAG,cAAc,CAAC,cAAc,EAAE,CAAC;IACpD,IAAI,CAAC,WAAW,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,SAAS,CAAC;IAElE,MAAM,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IACxB,IAAI,CAAC,cAAc,CAAC,qBAAqB,EAAE,EAAE,CAAC;QAC7C,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,aAAa,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,YAAY,EAAE,CAAC,CAAC;IACtD,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAAA,CACtB","sourcesContent":["import * as fs from \"node:fs\";\nimport { APP_NAME } from \"../../config.ts\";\nimport type { SessionManager } from \"../../core/session-manager.ts\";\n\nfunction quoteIfNeeded(value: string): string {\n\tif (value.length > 0 && !/[^a-zA-Z0-9_\\-./~:@]/.test(value)) {\n\t\treturn value;\n\t}\n\treturn `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n\nexport function formatResumeCommand(sessionManager: SessionManager): string | undefined {\n\tif (!process.stdout.isTTY) return undefined;\n\tif (!sessionManager.isPersisted()) return undefined;\n\n\tconst sessionFile = sessionManager.getSessionFile();\n\tif (!sessionFile || !fs.existsSync(sessionFile)) return undefined;\n\n\tconst args = [APP_NAME];\n\tif (!sessionManager.usesDefaultSessionDir()) {\n\t\targs.push(\"--session-dir\", quoteIfNeeded(sessionManager.getSessionDir()));\n\t}\n\targs.push(\"--session\", sessionManager.getSessionId());\n\treturn args.join(\" \");\n}\n"]}
@@ -0,0 +1,32 @@
1
+ import { Text } from "omk-tui";
2
+ /** Interface for components that can be expanded/collapsed */
3
+ interface Expandable {
4
+ setExpanded(expanded: boolean): void;
5
+ }
6
+ export declare function isExpandable(obj: unknown): obj is Expandable;
7
+ export declare function disposeComponent(component: unknown): void;
8
+ type ToolExecutionContent = {
9
+ type: "text";
10
+ text: string;
11
+ } | {
12
+ type: "image";
13
+ data: string;
14
+ mimeType: string;
15
+ };
16
+ type ToolExecutionResult = {
17
+ content: ToolExecutionContent[];
18
+ details?: unknown;
19
+ };
20
+ export declare function normalizeToolExecutionResult(result: unknown, isError: boolean): ToolExecutionResult & {
21
+ isError: boolean;
22
+ };
23
+ export declare class ExpandableText extends Text implements Expandable {
24
+ private readonly getCollapsedText;
25
+ private readonly getExpandedText;
26
+ private expanded;
27
+ constructor(getCollapsedText: () => string, getExpandedText: () => string, expanded?: boolean, paddingX?: number, paddingY?: number);
28
+ setExpanded(expanded: boolean): void;
29
+ invalidate(): void;
30
+ }
31
+ export {};
32
+ //# sourceMappingURL=interactive-tool-result.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive-tool-result.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-tool-result.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE/B,8DAA8D;AAC9D,UAAU,UAAU;IACnB,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;CACrC;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,UAAU,CAE5D;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CASzD;AACD,KAAK,oBAAoB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/G,KAAK,mBAAmB,GAAG;IAC1B,OAAO,EAAE,oBAAoB,EAAE,CAAC;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAgBF,wBAAgB,4BAA4B,CAC3C,MAAM,EAAE,OAAO,EACf,OAAO,EAAE,OAAO,GACd,mBAAmB,GAAG;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAa5C;AAED,qBAAa,cAAe,SAAQ,IAAK,YAAW,UAAU;IAC7D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAe;IAChD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAe;IAC/C,OAAO,CAAC,QAAQ,CAAU;IAE1B,YACC,gBAAgB,EAAE,MAAM,MAAM,EAC9B,eAAe,EAAE,MAAM,MAAM,EAC7B,QAAQ,UAAQ,EAChB,QAAQ,SAAI,EACZ,QAAQ,SAAI,EAMZ;IAED,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAGnC;IAEQ,UAAU,IAAI,IAAI,CAG1B;CACD","sourcesContent":["import { Text } from \"omk-tui\";\n\n/** Interface for components that can be expanded/collapsed */\ninterface Expandable {\n\tsetExpanded(expanded: boolean): void;\n}\n\nexport function isExpandable(obj: unknown): obj is Expandable {\n\treturn typeof obj === \"object\" && obj !== null && \"setExpanded\" in obj && typeof obj.setExpanded === \"function\";\n}\n\nexport function disposeComponent(component: unknown): void {\n\tif (\n\t\ttypeof component === \"object\" &&\n\t\tcomponent !== null &&\n\t\t\"dispose\" in component &&\n\t\ttypeof component.dispose === \"function\"\n\t) {\n\t\tcomponent.dispose();\n\t}\n}\ntype ToolExecutionContent = { type: \"text\"; text: string } | { type: \"image\"; data: string; mimeType: string };\n\ntype ToolExecutionResult = {\n\tcontent: ToolExecutionContent[];\n\tdetails?: unknown;\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isToolExecutionContent(value: unknown): value is ToolExecutionContent {\n\tif (!isRecord(value)) return false;\n\tif (value.type === \"text\") return typeof value.text === \"string\";\n\treturn value.type === \"image\" && typeof value.data === \"string\" && typeof value.mimeType === \"string\";\n}\n\nfunction isToolExecutionResult(value: unknown): value is ToolExecutionResult {\n\treturn isRecord(value) && Array.isArray(value.content) && value.content.every(isToolExecutionContent);\n}\n\nexport function normalizeToolExecutionResult(\n\tresult: unknown,\n\tisError: boolean,\n): ToolExecutionResult & { isError: boolean } {\n\ttry {\n\t\tif (isToolExecutionResult(result)) {\n\t\t\treturn { content: result.content, details: result.details, isError };\n\t\t}\n\t} catch {\n\t\t// Treat inaccessible or malformed extension payloads as invalid results.\n\t}\n\n\treturn {\n\t\tcontent: [{ type: \"text\", text: \"Tool returned an invalid result.\" }],\n\t\tisError: true,\n\t};\n}\n\nexport class ExpandableText extends Text implements Expandable {\n\tprivate readonly getCollapsedText: () => string;\n\tprivate readonly getExpandedText: () => string;\n\tprivate expanded: boolean;\n\n\tconstructor(\n\t\tgetCollapsedText: () => string,\n\t\tgetExpandedText: () => string,\n\t\texpanded = false,\n\t\tpaddingX = 0,\n\t\tpaddingY = 0,\n\t) {\n\t\tsuper(expanded ? getExpandedText() : getCollapsedText(), paddingX, paddingY);\n\t\tthis.getCollapsedText = getCollapsedText;\n\t\tthis.getExpandedText = getExpandedText;\n\t\tthis.expanded = expanded;\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.setText(expanded ? this.getExpandedText() : this.getCollapsedText());\n\t}\n\n\toverride invalidate(): void {\n\t\tthis.setText(this.expanded ? this.getExpandedText() : this.getCollapsedText());\n\t\tsuper.invalidate();\n\t}\n}\n"]}
@@ -0,0 +1,59 @@
1
+ import { Text } from "omk-tui";
2
+ export function isExpandable(obj) {
3
+ return typeof obj === "object" && obj !== null && "setExpanded" in obj && typeof obj.setExpanded === "function";
4
+ }
5
+ export function disposeComponent(component) {
6
+ if (typeof component === "object" &&
7
+ component !== null &&
8
+ "dispose" in component &&
9
+ typeof component.dispose === "function") {
10
+ component.dispose();
11
+ }
12
+ }
13
+ function isRecord(value) {
14
+ return typeof value === "object" && value !== null && !Array.isArray(value);
15
+ }
16
+ function isToolExecutionContent(value) {
17
+ if (!isRecord(value))
18
+ return false;
19
+ if (value.type === "text")
20
+ return typeof value.text === "string";
21
+ return value.type === "image" && typeof value.data === "string" && typeof value.mimeType === "string";
22
+ }
23
+ function isToolExecutionResult(value) {
24
+ return isRecord(value) && Array.isArray(value.content) && value.content.every(isToolExecutionContent);
25
+ }
26
+ export function normalizeToolExecutionResult(result, isError) {
27
+ try {
28
+ if (isToolExecutionResult(result)) {
29
+ return { content: result.content, details: result.details, isError };
30
+ }
31
+ }
32
+ catch {
33
+ // Treat inaccessible or malformed extension payloads as invalid results.
34
+ }
35
+ return {
36
+ content: [{ type: "text", text: "Tool returned an invalid result." }],
37
+ isError: true,
38
+ };
39
+ }
40
+ export class ExpandableText extends Text {
41
+ getCollapsedText;
42
+ getExpandedText;
43
+ expanded;
44
+ constructor(getCollapsedText, getExpandedText, expanded = false, paddingX = 0, paddingY = 0) {
45
+ super(expanded ? getExpandedText() : getCollapsedText(), paddingX, paddingY);
46
+ this.getCollapsedText = getCollapsedText;
47
+ this.getExpandedText = getExpandedText;
48
+ this.expanded = expanded;
49
+ }
50
+ setExpanded(expanded) {
51
+ this.expanded = expanded;
52
+ this.setText(expanded ? this.getExpandedText() : this.getCollapsedText());
53
+ }
54
+ invalidate() {
55
+ this.setText(this.expanded ? this.getExpandedText() : this.getCollapsedText());
56
+ super.invalidate();
57
+ }
58
+ }
59
+ //# sourceMappingURL=interactive-tool-result.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive-tool-result.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-tool-result.ts"],"names":[],"mappings":"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","sourcesContent":["import { Text } from \"omk-tui\";\n\n/** Interface for components that can be expanded/collapsed */\ninterface Expandable {\n\tsetExpanded(expanded: boolean): void;\n}\n\nexport function isExpandable(obj: unknown): obj is Expandable {\n\treturn typeof obj === \"object\" && obj !== null && \"setExpanded\" in obj && typeof obj.setExpanded === \"function\";\n}\n\nexport function disposeComponent(component: unknown): void {\n\tif (\n\t\ttypeof component === \"object\" &&\n\t\tcomponent !== null &&\n\t\t\"dispose\" in component &&\n\t\ttypeof component.dispose === \"function\"\n\t) {\n\t\tcomponent.dispose();\n\t}\n}\ntype ToolExecutionContent = { type: \"text\"; text: string } | { type: \"image\"; data: string; mimeType: string };\n\ntype ToolExecutionResult = {\n\tcontent: ToolExecutionContent[];\n\tdetails?: unknown;\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isToolExecutionContent(value: unknown): value is ToolExecutionContent {\n\tif (!isRecord(value)) return false;\n\tif (value.type === \"text\") return typeof value.text === \"string\";\n\treturn value.type === \"image\" && typeof value.data === \"string\" && typeof value.mimeType === \"string\";\n}\n\nfunction isToolExecutionResult(value: unknown): value is ToolExecutionResult {\n\treturn isRecord(value) && Array.isArray(value.content) && value.content.every(isToolExecutionContent);\n}\n\nexport function normalizeToolExecutionResult(\n\tresult: unknown,\n\tisError: boolean,\n): ToolExecutionResult & { isError: boolean } {\n\ttry {\n\t\tif (isToolExecutionResult(result)) {\n\t\t\treturn { content: result.content, details: result.details, isError };\n\t\t}\n\t} catch {\n\t\t// Treat inaccessible or malformed extension payloads as invalid results.\n\t}\n\n\treturn {\n\t\tcontent: [{ type: \"text\", text: \"Tool returned an invalid result.\" }],\n\t\tisError: true,\n\t};\n}\n\nexport class ExpandableText extends Text implements Expandable {\n\tprivate readonly getCollapsedText: () => string;\n\tprivate readonly getExpandedText: () => string;\n\tprivate expanded: boolean;\n\n\tconstructor(\n\t\tgetCollapsedText: () => string,\n\t\tgetExpandedText: () => string,\n\t\texpanded = false,\n\t\tpaddingX = 0,\n\t\tpaddingY = 0,\n\t) {\n\t\tsuper(expanded ? getExpandedText() : getCollapsedText(), paddingX, paddingY);\n\t\tthis.getCollapsedText = getCollapsedText;\n\t\tthis.getExpandedText = getExpandedText;\n\t\tthis.expanded = expanded;\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.setText(expanded ? this.getExpandedText() : this.getCollapsedText());\n\t}\n\n\toverride invalidate(): void {\n\t\tthis.setText(this.expanded ? this.getExpandedText() : this.getCollapsedText());\n\t\tsuper.invalidate();\n\t}\n}\n"]}
@@ -0,0 +1,36 @@
1
+ import { type Component } from "omk-tui";
2
+ import type { SessionTermination } from "../../core/session-termination-types.ts";
3
+ import type { TuiRuntimeCapture, TuiRuntimeInfo } from "./tui-runtime-info.ts";
4
+ type DiagnosticTermination = Pick<SessionTermination, "kind" | "phase" | "causeCode" | "source" | "sideEffects" | "retryable" | "safeToAutoRetry">;
5
+ export interface TuiDiagnostics {
6
+ readonly schemaVersion: 1;
7
+ readonly privacy: "metadata-only";
8
+ readonly generatedAt: string;
9
+ readonly runtime: Omit<TuiRuntimeInfo, "entryPath" | "modulePath">;
10
+ readonly terminal: {
11
+ readonly columns: number;
12
+ readonly rows: number;
13
+ };
14
+ readonly session: {
15
+ readonly streaming: boolean;
16
+ readonly compacting: boolean;
17
+ readonly messageCount: number;
18
+ readonly lastResourceReloadAt: string | null;
19
+ };
20
+ readonly termination: DiagnosticTermination | null;
21
+ }
22
+ /** Project each approved field; never serialize a session, message, model, config or arbitrary error. */
23
+ export declare function createTuiDiagnostics(input: {
24
+ readonly runtime: TuiRuntimeInfo;
25
+ readonly columns: number;
26
+ readonly rows: number;
27
+ readonly isStreaming: boolean;
28
+ readonly isCompacting: boolean;
29
+ readonly messageCount: number;
30
+ readonly lastResourceReloadAt: string | undefined;
31
+ readonly termination: SessionTermination | undefined;
32
+ }): TuiDiagnostics;
33
+ export declare function saveTuiDiagnostics(report: TuiDiagnostics, directory?: string): string;
34
+ export declare function createTuiDiagnosticsView(report: TuiDiagnostics, locations: TuiRuntimeCapture): Component;
35
+ export {};
36
+ //# sourceMappingURL=tui-diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tui-diagnostics.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/tui-diagnostics.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,SAAS,EAAmB,MAAM,SAAS,CAAC;AAC1D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAIlF,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE/E,KAAK,qBAAqB,GAAG,IAAI,CAChC,kBAAkB,EAClB,MAAM,GAAG,OAAO,GAAG,WAAW,GAAG,QAAQ,GAAG,aAAa,GAAG,WAAW,GAAG,iBAAiB,CAC3F,CAAC;AACF,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,cAAc,EAAE,WAAW,GAAG,YAAY,CAAC,CAAC;IACnE,QAAQ,CAAC,QAAQ,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACvE,QAAQ,CAAC,OAAO,EAAE;QACjB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;QAC5B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;QAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;QAC9B,QAAQ,CAAC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;KAC7C,CAAC;IACF,QAAQ,CAAC,WAAW,EAAE,qBAAqB,GAAG,IAAI,CAAC;CACnD;AAED,yGAAyG;AACzG,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC3C,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC;IAClD,QAAQ,CAAC,WAAW,EAAE,kBAAkB,GAAG,SAAS,CAAC;CACrD,GAAG,cAAc,CAsCjB;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,EAAE,SAAS,SAAW,GAAG,MAAM,CAcvF;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,cAAc,EAAE,SAAS,EAAE,iBAAiB,GAAG,SAAS,CAiDxG","sourcesContent":["import { mkdtempSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { type Component, Container, Text } from \"omk-tui\";\nimport type { SessionTermination } from \"../../core/session-termination-types.ts\";\nimport { DynamicBorder } from \"./components/dynamic-border.ts\";\nimport { diagnosticDisplayText } from \"./components/session-failure.ts\";\nimport { theme } from \"./theme/theme.ts\";\nimport type { TuiRuntimeCapture, TuiRuntimeInfo } from \"./tui-runtime-info.ts\";\n\ntype DiagnosticTermination = Pick<\n\tSessionTermination,\n\t\"kind\" | \"phase\" | \"causeCode\" | \"source\" | \"sideEffects\" | \"retryable\" | \"safeToAutoRetry\"\n>;\nexport interface TuiDiagnostics {\n\treadonly schemaVersion: 1;\n\treadonly privacy: \"metadata-only\";\n\treadonly generatedAt: string;\n\treadonly runtime: Omit<TuiRuntimeInfo, \"entryPath\" | \"modulePath\">;\n\treadonly terminal: { readonly columns: number; readonly rows: number };\n\treadonly session: {\n\t\treadonly streaming: boolean;\n\t\treadonly compacting: boolean;\n\t\treadonly messageCount: number;\n\t\treadonly lastResourceReloadAt: string | null;\n\t};\n\treadonly termination: DiagnosticTermination | null;\n}\n\n/** Project each approved field; never serialize a session, message, model, config or arbitrary error. */\nexport function createTuiDiagnostics(input: {\n\treadonly runtime: TuiRuntimeInfo;\n\treadonly columns: number;\n\treadonly rows: number;\n\treadonly isStreaming: boolean;\n\treadonly isCompacting: boolean;\n\treadonly messageCount: number;\n\treadonly lastResourceReloadAt: string | undefined;\n\treadonly termination: SessionTermination | undefined;\n}): TuiDiagnostics {\n\tconst r = input.runtime;\n\tconst t = input.termination;\n\treturn {\n\t\tschemaVersion: 1,\n\t\tprivacy: \"metadata-only\",\n\t\tgeneratedAt: new Date().toISOString(),\n\t\truntime: {\n\t\t\tversion: r.version,\n\t\t\tnodeVersion: r.nodeVersion,\n\t\t\tplatform: r.platform,\n\t\t\tarch: r.arch,\n\t\t\tcapturedAt: r.capturedAt,\n\t\t\tmoduleKind: r.moduleKind,\n\t\t\tmoduleState: r.moduleState,\n\t\t\tinitialModuleSha256: r.initialModuleSha256,\n\t\t\tcurrentModuleSha256: r.currentModuleSha256,\n\t\t\tbuildRevision: r.buildRevision,\n\t\t},\n\t\tterminal: { columns: input.columns, rows: input.rows },\n\t\tsession: {\n\t\t\tstreaming: input.isStreaming,\n\t\t\tcompacting: input.isCompacting,\n\t\t\tmessageCount: input.messageCount,\n\t\t\tlastResourceReloadAt: input.lastResourceReloadAt ?? null,\n\t\t},\n\t\ttermination: t\n\t\t\t? {\n\t\t\t\t\tkind: t.kind,\n\t\t\t\t\tphase: t.phase,\n\t\t\t\t\tcauseCode: t.causeCode,\n\t\t\t\t\tsource: t.source,\n\t\t\t\t\tsideEffects: t.sideEffects,\n\t\t\t\t\tretryable: t.retryable,\n\t\t\t\t\tsafeToAutoRetry: t.safeToAutoRetry,\n\t\t\t\t}\n\t\t\t: null,\n\t};\n}\n\nexport function saveTuiDiagnostics(report: TuiDiagnostics, directory = tmpdir()): string {\n\tconst ownedDirectory = mkdtempSync(join(directory, \"omk-debug-\"));\n\ttry {\n\t\tconst outputPath = join(ownedDirectory, \"diagnostics.json\");\n\t\twriteFileSync(outputPath, `${JSON.stringify(report, null, 2)}\\n`, { flag: \"wx\", mode: 0o600 });\n\t\treturn outputPath;\n\t} catch (error) {\n\t\ttry {\n\t\t\trmSync(ownedDirectory, { recursive: true, force: true });\n\t\t} catch (cleanupError) {\n\t\t\tthrow new AggregateError([error, cleanupError], \"Diagnostics write and cleanup failed\");\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nexport function createTuiDiagnosticsView(report: TuiDiagnostics, locations: TuiRuntimeCapture): Component {\n\treturn {\n\t\trender(width: number): string[] {\n\t\t\tconst view = new Container();\n\t\t\tview.addChild(new DynamicBorder((s) => theme.fg(\"accent\", s)));\n\t\t\tview.addChild(new Text(theme.fg(\"accent\", theme.bold(\"OMK diagnostics\")), 1, 0));\n\t\t\tconst r = report.runtime;\n\t\t\tconst t = report.termination;\n\t\t\tconst moduleStatus =\n\t\t\t\tr.moduleState === \"changed\"\n\t\t\t\t\t? \"changed since initialization — restart to load code\"\n\t\t\t\t\t: r.moduleState === \"unchanged\"\n\t\t\t\t\t\t? \"unchanged since initialization (this file only)\"\n\t\t\t\t\t\t: \"unavailable — not confirmed\";\n\t\t\tconst lines = [\n\t\t\t\t`Runtime: OMK ${r.version} · Node ${r.nodeVersion} · ${r.platform}/${r.arch}`,\n\t\t\t\t`Loaded UI: ${r.moduleKind} · Initialized: ${r.capturedAt}`,\n\t\t\t\t`UI file on disk: ${moduleStatus}`,\n\t\t\t\t`UI SHA256 at initialization: ${r.initialModuleSha256 ?? \"unavailable\"}`,\n\t\t\t\t\"Build revision: unavailable (checkout HEAD is not a build identity)\",\n\t\t\t\t`Last resource reload: ${report.session.lastResourceReloadAt ?? \"not reloaded in this TUI\"}`,\n\t\t\t\t\"/reload refreshes resources, not core code. Core updates require a restart.\",\n\t\t\t\t`Terminal: ${report.terminal.columns}×${report.terminal.rows} · Messages: ${report.session.messageCount}`,\n\t\t\t\t`Streaming: ${report.session.streaming ? \"yes\" : \"no\"} · Compacting: ${report.session.compacting ? \"yes\" : \"no\"}`,\n\t\t\t\tt ? `Latest outcome: ${t.kind} · ${t.causeCode} · ${t.source}` : \"Latest outcome: none recorded\",\n\t\t\t\t...(t\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t`Effects: ${t.sideEffects} · Retryable: ${t.retryable ? \"yes\" : \"no\"} · Automatic retry: ${t.safeToAutoRetry ? \"yes\" : \"no\"}`,\n\t\t\t\t\t\t]\n\t\t\t\t\t: []),\n\t\t\t\t`Launch path (local only): ${locations.entryPath ?? \"unavailable\"}`,\n\t\t\t\t`UI module (local only): ${locations.modulePath ?? \"unavailable\"}`,\n\t\t\t];\n\t\t\tview.addChild(new Text(lines.map(diagnosticDisplayText).join(\"\\n\"), 1, 0));\n\t\t\tview.addChild(\n\t\t\t\tnew Text(\n\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\"muted\",\n\t\t\t\t\t\t\"Saving is explicit: /debug save writes a metadata-only JSON report locally.\\nMessages, prompts, outputs, config, paths, route names and session/run IDs are excluded. No upload.\",\n\t\t\t\t\t),\n\t\t\t\t\t1,\n\t\t\t\t\t0,\n\t\t\t\t),\n\t\t\t);\n\t\t\tview.addChild(new DynamicBorder((s) => theme.fg(\"accent\", s)));\n\t\t\treturn view.render(width);\n\t\t},\n\t\tinvalidate(): void {},\n\t};\n}\n"]}
@@ -0,0 +1,105 @@
1
+ import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { Container, Text } from "omk-tui";
5
+ import { DynamicBorder } from "./components/dynamic-border.js";
6
+ import { diagnosticDisplayText } from "./components/session-failure.js";
7
+ import { theme } from "./theme/theme.js";
8
+ /** Project each approved field; never serialize a session, message, model, config or arbitrary error. */
9
+ export function createTuiDiagnostics(input) {
10
+ const r = input.runtime;
11
+ const t = input.termination;
12
+ return {
13
+ schemaVersion: 1,
14
+ privacy: "metadata-only",
15
+ generatedAt: new Date().toISOString(),
16
+ runtime: {
17
+ version: r.version,
18
+ nodeVersion: r.nodeVersion,
19
+ platform: r.platform,
20
+ arch: r.arch,
21
+ capturedAt: r.capturedAt,
22
+ moduleKind: r.moduleKind,
23
+ moduleState: r.moduleState,
24
+ initialModuleSha256: r.initialModuleSha256,
25
+ currentModuleSha256: r.currentModuleSha256,
26
+ buildRevision: r.buildRevision,
27
+ },
28
+ terminal: { columns: input.columns, rows: input.rows },
29
+ session: {
30
+ streaming: input.isStreaming,
31
+ compacting: input.isCompacting,
32
+ messageCount: input.messageCount,
33
+ lastResourceReloadAt: input.lastResourceReloadAt ?? null,
34
+ },
35
+ termination: t
36
+ ? {
37
+ kind: t.kind,
38
+ phase: t.phase,
39
+ causeCode: t.causeCode,
40
+ source: t.source,
41
+ sideEffects: t.sideEffects,
42
+ retryable: t.retryable,
43
+ safeToAutoRetry: t.safeToAutoRetry,
44
+ }
45
+ : null,
46
+ };
47
+ }
48
+ export function saveTuiDiagnostics(report, directory = tmpdir()) {
49
+ const ownedDirectory = mkdtempSync(join(directory, "omk-debug-"));
50
+ try {
51
+ const outputPath = join(ownedDirectory, "diagnostics.json");
52
+ writeFileSync(outputPath, `${JSON.stringify(report, null, 2)}\n`, { flag: "wx", mode: 0o600 });
53
+ return outputPath;
54
+ }
55
+ catch (error) {
56
+ try {
57
+ rmSync(ownedDirectory, { recursive: true, force: true });
58
+ }
59
+ catch (cleanupError) {
60
+ throw new AggregateError([error, cleanupError], "Diagnostics write and cleanup failed");
61
+ }
62
+ throw error;
63
+ }
64
+ }
65
+ export function createTuiDiagnosticsView(report, locations) {
66
+ return {
67
+ render(width) {
68
+ const view = new Container();
69
+ view.addChild(new DynamicBorder((s) => theme.fg("accent", s)));
70
+ view.addChild(new Text(theme.fg("accent", theme.bold("OMK diagnostics")), 1, 0));
71
+ const r = report.runtime;
72
+ const t = report.termination;
73
+ const moduleStatus = r.moduleState === "changed"
74
+ ? "changed since initialization — restart to load code"
75
+ : r.moduleState === "unchanged"
76
+ ? "unchanged since initialization (this file only)"
77
+ : "unavailable — not confirmed";
78
+ const lines = [
79
+ `Runtime: OMK ${r.version} · Node ${r.nodeVersion} · ${r.platform}/${r.arch}`,
80
+ `Loaded UI: ${r.moduleKind} · Initialized: ${r.capturedAt}`,
81
+ `UI file on disk: ${moduleStatus}`,
82
+ `UI SHA256 at initialization: ${r.initialModuleSha256 ?? "unavailable"}`,
83
+ "Build revision: unavailable (checkout HEAD is not a build identity)",
84
+ `Last resource reload: ${report.session.lastResourceReloadAt ?? "not reloaded in this TUI"}`,
85
+ "/reload refreshes resources, not core code. Core updates require a restart.",
86
+ `Terminal: ${report.terminal.columns}×${report.terminal.rows} · Messages: ${report.session.messageCount}`,
87
+ `Streaming: ${report.session.streaming ? "yes" : "no"} · Compacting: ${report.session.compacting ? "yes" : "no"}`,
88
+ t ? `Latest outcome: ${t.kind} · ${t.causeCode} · ${t.source}` : "Latest outcome: none recorded",
89
+ ...(t
90
+ ? [
91
+ `Effects: ${t.sideEffects} · Retryable: ${t.retryable ? "yes" : "no"} · Automatic retry: ${t.safeToAutoRetry ? "yes" : "no"}`,
92
+ ]
93
+ : []),
94
+ `Launch path (local only): ${locations.entryPath ?? "unavailable"}`,
95
+ `UI module (local only): ${locations.modulePath ?? "unavailable"}`,
96
+ ];
97
+ view.addChild(new Text(lines.map(diagnosticDisplayText).join("\n"), 1, 0));
98
+ view.addChild(new Text(theme.fg("muted", "Saving is explicit: /debug save writes a metadata-only JSON report locally.\nMessages, prompts, outputs, config, paths, route names and session/run IDs are excluded. No upload."), 1, 0));
99
+ view.addChild(new DynamicBorder((s) => theme.fg("accent", s)));
100
+ return view.render(width);
101
+ },
102
+ invalidate() { },
103
+ };
104
+ }
105
+ //# sourceMappingURL=tui-diagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tui-diagnostics.js","sourceRoot":"","sources":["../../../src/modes/interactive/tui-diagnostics.ts"],"names":[],"mappings":"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","sourcesContent":["import { mkdtempSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { type Component, Container, Text } from \"omk-tui\";\nimport type { SessionTermination } from \"../../core/session-termination-types.ts\";\nimport { DynamicBorder } from \"./components/dynamic-border.ts\";\nimport { diagnosticDisplayText } from \"./components/session-failure.ts\";\nimport { theme } from \"./theme/theme.ts\";\nimport type { TuiRuntimeCapture, TuiRuntimeInfo } from \"./tui-runtime-info.ts\";\n\ntype DiagnosticTermination = Pick<\n\tSessionTermination,\n\t\"kind\" | \"phase\" | \"causeCode\" | \"source\" | \"sideEffects\" | \"retryable\" | \"safeToAutoRetry\"\n>;\nexport interface TuiDiagnostics {\n\treadonly schemaVersion: 1;\n\treadonly privacy: \"metadata-only\";\n\treadonly generatedAt: string;\n\treadonly runtime: Omit<TuiRuntimeInfo, \"entryPath\" | \"modulePath\">;\n\treadonly terminal: { readonly columns: number; readonly rows: number };\n\treadonly session: {\n\t\treadonly streaming: boolean;\n\t\treadonly compacting: boolean;\n\t\treadonly messageCount: number;\n\t\treadonly lastResourceReloadAt: string | null;\n\t};\n\treadonly termination: DiagnosticTermination | null;\n}\n\n/** Project each approved field; never serialize a session, message, model, config or arbitrary error. */\nexport function createTuiDiagnostics(input: {\n\treadonly runtime: TuiRuntimeInfo;\n\treadonly columns: number;\n\treadonly rows: number;\n\treadonly isStreaming: boolean;\n\treadonly isCompacting: boolean;\n\treadonly messageCount: number;\n\treadonly lastResourceReloadAt: string | undefined;\n\treadonly termination: SessionTermination | undefined;\n}): TuiDiagnostics {\n\tconst r = input.runtime;\n\tconst t = input.termination;\n\treturn {\n\t\tschemaVersion: 1,\n\t\tprivacy: \"metadata-only\",\n\t\tgeneratedAt: new Date().toISOString(),\n\t\truntime: {\n\t\t\tversion: r.version,\n\t\t\tnodeVersion: r.nodeVersion,\n\t\t\tplatform: r.platform,\n\t\t\tarch: r.arch,\n\t\t\tcapturedAt: r.capturedAt,\n\t\t\tmoduleKind: r.moduleKind,\n\t\t\tmoduleState: r.moduleState,\n\t\t\tinitialModuleSha256: r.initialModuleSha256,\n\t\t\tcurrentModuleSha256: r.currentModuleSha256,\n\t\t\tbuildRevision: r.buildRevision,\n\t\t},\n\t\tterminal: { columns: input.columns, rows: input.rows },\n\t\tsession: {\n\t\t\tstreaming: input.isStreaming,\n\t\t\tcompacting: input.isCompacting,\n\t\t\tmessageCount: input.messageCount,\n\t\t\tlastResourceReloadAt: input.lastResourceReloadAt ?? null,\n\t\t},\n\t\ttermination: t\n\t\t\t? {\n\t\t\t\t\tkind: t.kind,\n\t\t\t\t\tphase: t.phase,\n\t\t\t\t\tcauseCode: t.causeCode,\n\t\t\t\t\tsource: t.source,\n\t\t\t\t\tsideEffects: t.sideEffects,\n\t\t\t\t\tretryable: t.retryable,\n\t\t\t\t\tsafeToAutoRetry: t.safeToAutoRetry,\n\t\t\t\t}\n\t\t\t: null,\n\t};\n}\n\nexport function saveTuiDiagnostics(report: TuiDiagnostics, directory = tmpdir()): string {\n\tconst ownedDirectory = mkdtempSync(join(directory, \"omk-debug-\"));\n\ttry {\n\t\tconst outputPath = join(ownedDirectory, \"diagnostics.json\");\n\t\twriteFileSync(outputPath, `${JSON.stringify(report, null, 2)}\\n`, { flag: \"wx\", mode: 0o600 });\n\t\treturn outputPath;\n\t} catch (error) {\n\t\ttry {\n\t\t\trmSync(ownedDirectory, { recursive: true, force: true });\n\t\t} catch (cleanupError) {\n\t\t\tthrow new AggregateError([error, cleanupError], \"Diagnostics write and cleanup failed\");\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nexport function createTuiDiagnosticsView(report: TuiDiagnostics, locations: TuiRuntimeCapture): Component {\n\treturn {\n\t\trender(width: number): string[] {\n\t\t\tconst view = new Container();\n\t\t\tview.addChild(new DynamicBorder((s) => theme.fg(\"accent\", s)));\n\t\t\tview.addChild(new Text(theme.fg(\"accent\", theme.bold(\"OMK diagnostics\")), 1, 0));\n\t\t\tconst r = report.runtime;\n\t\t\tconst t = report.termination;\n\t\t\tconst moduleStatus =\n\t\t\t\tr.moduleState === \"changed\"\n\t\t\t\t\t? \"changed since initialization — restart to load code\"\n\t\t\t\t\t: r.moduleState === \"unchanged\"\n\t\t\t\t\t\t? \"unchanged since initialization (this file only)\"\n\t\t\t\t\t\t: \"unavailable — not confirmed\";\n\t\t\tconst lines = [\n\t\t\t\t`Runtime: OMK ${r.version} · Node ${r.nodeVersion} · ${r.platform}/${r.arch}`,\n\t\t\t\t`Loaded UI: ${r.moduleKind} · Initialized: ${r.capturedAt}`,\n\t\t\t\t`UI file on disk: ${moduleStatus}`,\n\t\t\t\t`UI SHA256 at initialization: ${r.initialModuleSha256 ?? \"unavailable\"}`,\n\t\t\t\t\"Build revision: unavailable (checkout HEAD is not a build identity)\",\n\t\t\t\t`Last resource reload: ${report.session.lastResourceReloadAt ?? \"not reloaded in this TUI\"}`,\n\t\t\t\t\"/reload refreshes resources, not core code. Core updates require a restart.\",\n\t\t\t\t`Terminal: ${report.terminal.columns}×${report.terminal.rows} · Messages: ${report.session.messageCount}`,\n\t\t\t\t`Streaming: ${report.session.streaming ? \"yes\" : \"no\"} · Compacting: ${report.session.compacting ? \"yes\" : \"no\"}`,\n\t\t\t\tt ? `Latest outcome: ${t.kind} · ${t.causeCode} · ${t.source}` : \"Latest outcome: none recorded\",\n\t\t\t\t...(t\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t`Effects: ${t.sideEffects} · Retryable: ${t.retryable ? \"yes\" : \"no\"} · Automatic retry: ${t.safeToAutoRetry ? \"yes\" : \"no\"}`,\n\t\t\t\t\t\t]\n\t\t\t\t\t: []),\n\t\t\t\t`Launch path (local only): ${locations.entryPath ?? \"unavailable\"}`,\n\t\t\t\t`UI module (local only): ${locations.modulePath ?? \"unavailable\"}`,\n\t\t\t];\n\t\t\tview.addChild(new Text(lines.map(diagnosticDisplayText).join(\"\\n\"), 1, 0));\n\t\t\tview.addChild(\n\t\t\t\tnew Text(\n\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\"muted\",\n\t\t\t\t\t\t\"Saving is explicit: /debug save writes a metadata-only JSON report locally.\\nMessages, prompts, outputs, config, paths, route names and session/run IDs are excluded. No upload.\",\n\t\t\t\t\t),\n\t\t\t\t\t1,\n\t\t\t\t\t0,\n\t\t\t\t),\n\t\t\t);\n\t\t\tview.addChild(new DynamicBorder((s) => theme.fg(\"accent\", s)));\n\t\t\treturn view.render(width);\n\t\t},\n\t\tinvalidate(): void {},\n\t};\n}\n"]}
@@ -0,0 +1,20 @@
1
+ export interface TuiRuntimeCapture {
2
+ readonly version: string;
3
+ readonly nodeVersion: string;
4
+ readonly platform: NodeJS.Platform;
5
+ readonly arch: string;
6
+ readonly capturedAt: string;
7
+ readonly entryPath: string | null;
8
+ readonly modulePath: string | null;
9
+ readonly moduleKind: "source" | "dist" | "bundled" | "unknown";
10
+ readonly initialModuleSha256: string | null;
11
+ }
12
+ export interface TuiRuntimeInfo extends TuiRuntimeCapture {
13
+ readonly currentModuleSha256: string | null;
14
+ readonly moduleState: "unchanged" | "changed" | "unavailable";
15
+ /** The package currently supplies no build-to-commit binding. Never substitute checkout HEAD. */
16
+ readonly buildRevision: null;
17
+ }
18
+ export declare function captureTuiRuntime(moduleUrl: string): TuiRuntimeCapture;
19
+ export declare function inspectTuiRuntime(capture: TuiRuntimeCapture): TuiRuntimeInfo;
20
+ //# sourceMappingURL=tui-runtime-info.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tui-runtime-info.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/tui-runtime-info.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,UAAU,EAAE,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;IAC/D,QAAQ,CAAC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5C;AACD,MAAM,WAAW,cAAe,SAAQ,iBAAiB;IACxD,QAAQ,CAAC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,QAAQ,CAAC,WAAW,EAAE,WAAW,GAAG,SAAS,GAAG,aAAa,CAAC;IAC9D,iGAAiG;IACjG,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAC;CAC7B;AAqBD,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,CAkCtE;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,iBAAiB,GAAG,cAAc,CAS5E","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { closeSync, constants, fstatSync, openSync, readSync, realpathSync } from \"node:fs\";\nimport { extname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { VERSION } from \"../../config.ts\";\n\nexport interface TuiRuntimeCapture {\n\treadonly version: string;\n\treadonly nodeVersion: string;\n\treadonly platform: NodeJS.Platform;\n\treadonly arch: string;\n\treadonly capturedAt: string;\n\treadonly entryPath: string | null;\n\treadonly modulePath: string | null;\n\treadonly moduleKind: \"source\" | \"dist\" | \"bundled\" | \"unknown\";\n\treadonly initialModuleSha256: string | null;\n}\nexport interface TuiRuntimeInfo extends TuiRuntimeCapture {\n\treadonly currentModuleSha256: string | null;\n\treadonly moduleState: \"unchanged\" | \"changed\" | \"unavailable\";\n\t/** The package currently supplies no build-to-commit binding. Never substitute checkout HEAD. */\n\treadonly buildRevision: null;\n}\n\nfunction moduleDigest(filePath: string | null): string | null {\n\tif (!filePath) return null;\n\tlet fd: number | undefined;\n\ttry {\n\t\tfd = openSync(filePath, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);\n\t\tconst stat = fstatSync(fd);\n\t\tif (!stat.isFile() || stat.size > 1_048_576) return null;\n\t\tconst bytes = Buffer.alloc(stat.size + 1);\n\t\tconst count = readSync(fd, bytes, 0, bytes.length, 0);\n\t\tif (count !== stat.size || fstatSync(fd).mtimeMs !== stat.mtimeMs) return null;\n\t\treturn createHash(\"sha256\").update(bytes.subarray(0, count)).digest(\"hex\");\n\t} catch {\n\t\t// A missing/unreadable/virtual entry is an unavailable observation, not a clean bill of health.\n\t\treturn null;\n\t} finally {\n\t\tif (fd !== undefined) closeSync(fd);\n\t}\n}\n\nexport function captureTuiRuntime(moduleUrl: string): TuiRuntimeCapture {\n\tlet modulePath: string | null = null;\n\ttry {\n\t\tmodulePath = fileURLToPath(moduleUrl);\n\t} catch {\n\t\t// Bundled runtimes need not expose a file URL.\n\t}\n\tlet entryPath = process.argv[1] ? resolve(process.argv[1]) : null;\n\tif (entryPath) {\n\t\ttry {\n\t\t\tentryPath = realpathSync(entryPath);\n\t\t} catch {\n\t\t\t/* Keep the observed launch path when unavailable. */\n\t\t}\n\t}\n\tconst normalized = modulePath?.replaceAll(\"\\\\\", \"/\") ?? moduleUrl;\n\tconst moduleKind = /(?:^bun:|\\/\\$bunfs\\/|\\/~BUN\\/)/u.test(normalized)\n\t\t? \"bundled\"\n\t\t: modulePath && [\".ts\", \".tsx\", \".mts\", \".cts\"].includes(extname(modulePath))\n\t\t\t? \"source\"\n\t\t\t: normalized.includes(\"/dist/\")\n\t\t\t\t? \"dist\"\n\t\t\t\t: \"unknown\";\n\treturn Object.freeze({\n\t\tversion: VERSION,\n\t\tnodeVersion: process.versions.node,\n\t\tplatform: process.platform,\n\t\tarch: process.arch,\n\t\tcapturedAt: new Date().toISOString(),\n\t\tentryPath,\n\t\tmodulePath,\n\t\tmoduleKind,\n\t\tinitialModuleSha256: moduleKind === \"bundled\" ? null : moduleDigest(modulePath),\n\t});\n}\n\nexport function inspectTuiRuntime(capture: TuiRuntimeCapture): TuiRuntimeInfo {\n\tconst currentModuleSha256 = capture.moduleKind === \"bundled\" ? null : moduleDigest(capture.modulePath);\n\tconst moduleState =\n\t\t!capture.initialModuleSha256 || !currentModuleSha256\n\t\t\t? \"unavailable\"\n\t\t\t: capture.initialModuleSha256 === currentModuleSha256\n\t\t\t\t? \"unchanged\"\n\t\t\t\t: \"changed\";\n\treturn { ...capture, currentModuleSha256, moduleState, buildRevision: null };\n}\n"]}
@@ -0,0 +1,76 @@
1
+ import { createHash } from "node:crypto";
2
+ import { closeSync, constants, fstatSync, openSync, readSync, realpathSync } from "node:fs";
3
+ import { extname, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { VERSION } from "../../config.js";
6
+ function moduleDigest(filePath) {
7
+ if (!filePath)
8
+ return null;
9
+ let fd;
10
+ try {
11
+ fd = openSync(filePath, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
12
+ const stat = fstatSync(fd);
13
+ if (!stat.isFile() || stat.size > 1_048_576)
14
+ return null;
15
+ const bytes = Buffer.alloc(stat.size + 1);
16
+ const count = readSync(fd, bytes, 0, bytes.length, 0);
17
+ if (count !== stat.size || fstatSync(fd).mtimeMs !== stat.mtimeMs)
18
+ return null;
19
+ return createHash("sha256").update(bytes.subarray(0, count)).digest("hex");
20
+ }
21
+ catch {
22
+ // A missing/unreadable/virtual entry is an unavailable observation, not a clean bill of health.
23
+ return null;
24
+ }
25
+ finally {
26
+ if (fd !== undefined)
27
+ closeSync(fd);
28
+ }
29
+ }
30
+ export function captureTuiRuntime(moduleUrl) {
31
+ let modulePath = null;
32
+ try {
33
+ modulePath = fileURLToPath(moduleUrl);
34
+ }
35
+ catch {
36
+ // Bundled runtimes need not expose a file URL.
37
+ }
38
+ let entryPath = process.argv[1] ? resolve(process.argv[1]) : null;
39
+ if (entryPath) {
40
+ try {
41
+ entryPath = realpathSync(entryPath);
42
+ }
43
+ catch {
44
+ /* Keep the observed launch path when unavailable. */
45
+ }
46
+ }
47
+ const normalized = modulePath?.replaceAll("\\", "/") ?? moduleUrl;
48
+ const moduleKind = /(?:^bun:|\/\$bunfs\/|\/~BUN\/)/u.test(normalized)
49
+ ? "bundled"
50
+ : modulePath && [".ts", ".tsx", ".mts", ".cts"].includes(extname(modulePath))
51
+ ? "source"
52
+ : normalized.includes("/dist/")
53
+ ? "dist"
54
+ : "unknown";
55
+ return Object.freeze({
56
+ version: VERSION,
57
+ nodeVersion: process.versions.node,
58
+ platform: process.platform,
59
+ arch: process.arch,
60
+ capturedAt: new Date().toISOString(),
61
+ entryPath,
62
+ modulePath,
63
+ moduleKind,
64
+ initialModuleSha256: moduleKind === "bundled" ? null : moduleDigest(modulePath),
65
+ });
66
+ }
67
+ export function inspectTuiRuntime(capture) {
68
+ const currentModuleSha256 = capture.moduleKind === "bundled" ? null : moduleDigest(capture.modulePath);
69
+ const moduleState = !capture.initialModuleSha256 || !currentModuleSha256
70
+ ? "unavailable"
71
+ : capture.initialModuleSha256 === currentModuleSha256
72
+ ? "unchanged"
73
+ : "changed";
74
+ return { ...capture, currentModuleSha256, moduleState, buildRevision: null };
75
+ }
76
+ //# sourceMappingURL=tui-runtime-info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tui-runtime-info.js","sourceRoot":"","sources":["../../../src/modes/interactive/tui-runtime-info.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { closeSync, constants, fstatSync, openSync, readSync, realpathSync } from \"node:fs\";\nimport { extname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { VERSION } from \"../../config.ts\";\n\nexport interface TuiRuntimeCapture {\n\treadonly version: string;\n\treadonly nodeVersion: string;\n\treadonly platform: NodeJS.Platform;\n\treadonly arch: string;\n\treadonly capturedAt: string;\n\treadonly entryPath: string | null;\n\treadonly modulePath: string | null;\n\treadonly moduleKind: \"source\" | \"dist\" | \"bundled\" | \"unknown\";\n\treadonly initialModuleSha256: string | null;\n}\nexport interface TuiRuntimeInfo extends TuiRuntimeCapture {\n\treadonly currentModuleSha256: string | null;\n\treadonly moduleState: \"unchanged\" | \"changed\" | \"unavailable\";\n\t/** The package currently supplies no build-to-commit binding. Never substitute checkout HEAD. */\n\treadonly buildRevision: null;\n}\n\nfunction moduleDigest(filePath: string | null): string | null {\n\tif (!filePath) return null;\n\tlet fd: number | undefined;\n\ttry {\n\t\tfd = openSync(filePath, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);\n\t\tconst stat = fstatSync(fd);\n\t\tif (!stat.isFile() || stat.size > 1_048_576) return null;\n\t\tconst bytes = Buffer.alloc(stat.size + 1);\n\t\tconst count = readSync(fd, bytes, 0, bytes.length, 0);\n\t\tif (count !== stat.size || fstatSync(fd).mtimeMs !== stat.mtimeMs) return null;\n\t\treturn createHash(\"sha256\").update(bytes.subarray(0, count)).digest(\"hex\");\n\t} catch {\n\t\t// A missing/unreadable/virtual entry is an unavailable observation, not a clean bill of health.\n\t\treturn null;\n\t} finally {\n\t\tif (fd !== undefined) closeSync(fd);\n\t}\n}\n\nexport function captureTuiRuntime(moduleUrl: string): TuiRuntimeCapture {\n\tlet modulePath: string | null = null;\n\ttry {\n\t\tmodulePath = fileURLToPath(moduleUrl);\n\t} catch {\n\t\t// Bundled runtimes need not expose a file URL.\n\t}\n\tlet entryPath = process.argv[1] ? resolve(process.argv[1]) : null;\n\tif (entryPath) {\n\t\ttry {\n\t\t\tentryPath = realpathSync(entryPath);\n\t\t} catch {\n\t\t\t/* Keep the observed launch path when unavailable. */\n\t\t}\n\t}\n\tconst normalized = modulePath?.replaceAll(\"\\\\\", \"/\") ?? moduleUrl;\n\tconst moduleKind = /(?:^bun:|\\/\\$bunfs\\/|\\/~BUN\\/)/u.test(normalized)\n\t\t? \"bundled\"\n\t\t: modulePath && [\".ts\", \".tsx\", \".mts\", \".cts\"].includes(extname(modulePath))\n\t\t\t? \"source\"\n\t\t\t: normalized.includes(\"/dist/\")\n\t\t\t\t? \"dist\"\n\t\t\t\t: \"unknown\";\n\treturn Object.freeze({\n\t\tversion: VERSION,\n\t\tnodeVersion: process.versions.node,\n\t\tplatform: process.platform,\n\t\tarch: process.arch,\n\t\tcapturedAt: new Date().toISOString(),\n\t\tentryPath,\n\t\tmodulePath,\n\t\tmoduleKind,\n\t\tinitialModuleSha256: moduleKind === \"bundled\" ? null : moduleDigest(modulePath),\n\t});\n}\n\nexport function inspectTuiRuntime(capture: TuiRuntimeCapture): TuiRuntimeInfo {\n\tconst currentModuleSha256 = capture.moduleKind === \"bundled\" ? null : moduleDigest(capture.modulePath);\n\tconst moduleState =\n\t\t!capture.initialModuleSha256 || !currentModuleSha256\n\t\t\t? \"unavailable\"\n\t\t\t: capture.initialModuleSha256 === currentModuleSha256\n\t\t\t\t? \"unchanged\"\n\t\t\t\t: \"changed\";\n\treturn { ...capture, currentModuleSha256, moduleState, buildRevision: null };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"print-mode.d.ts","sourceRoot":"","sources":["../../src/modes/print-mode.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAoB,YAAY,EAAE,MAAM,QAAQ,CAAC;AAC7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAK5E;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAChC,yEAAyE;IACzE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,wDAAwD;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8CAA8C;IAC9C,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;CAC/B;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,WAAW,EAAE,mBAAmB,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAkL/G","sourcesContent":["/**\n * Print mode (single-shot): Send prompts, output result, exit.\n *\n * Used for:\n * - `omk -p \"prompt\"` - text output\n * - `omk --mode json \"prompt\"` - JSON event stream\n */\n\nimport type { AssistantMessage, ImageContent } from \"omk-ai\";\nimport type { AgentSessionRuntime } from \"../core/agent-session-runtime.ts\";\nimport { flushRawStdout, writeRawStdout } from \"../core/output-guard.ts\";\nimport { formatSessionTermination, type SessionTermination } from \"../core/session-termination.ts\";\nimport { killTrackedDetachedChildren } from \"../utils/shell.ts\";\n\n/**\n * Options for print mode.\n */\nexport interface PrintModeOptions {\n\t/** Output mode: \"text\" for final response only, \"json\" for all events */\n\tmode: \"text\" | \"json\";\n\t/** Array of additional prompts to send after initialMessage */\n\tmessages?: string[];\n\t/** First message to send (may contain @file content) */\n\tinitialMessage?: string;\n\t/** Images to attach to the initial message */\n\tinitialImages?: ImageContent[];\n}\n\n/**\n * Run in print (single-shot) mode.\n * Sends prompts to the agent and outputs the result.\n */\nexport async function runPrintMode(runtimeHost: AgentSessionRuntime, options: PrintModeOptions): Promise<number> {\n\tconst { mode, messages = [], initialMessage, initialImages } = options;\n\tlet exitCode = 0;\n\tlet session = runtimeHost.session;\n\tlet unsubscribe: (() => void) | undefined;\n\tlet disposed = false;\n\tlet promptStarted = false;\n\tlet latestTermination: SessionTermination | undefined;\n\tlet renderedTermination: SessionTermination | undefined;\n\tconst signalCleanupHandlers: Array<() => void> = [];\n\n\tconst renderTermination = (termination: SessionTermination): void => {\n\t\tif (termination.kind === \"completed\" || renderedTermination === termination) return;\n\t\trenderedTermination = termination;\n\t\tif (mode === \"json\") {\n\t\t\twriteRawStdout(`${JSON.stringify({ type: \"session_termination\", termination })}\\n`);\n\t\t} else {\n\t\t\tconsole.error(formatSessionTermination(termination));\n\t\t}\n\t};\n\n\tconst renderFailure = (fallback: string): void => {\n\t\tconst termination = latestTermination ?? (!promptStarted ? session.lastTermination : undefined);\n\t\tif (termination && termination.kind !== \"completed\") {\n\t\t\trenderTermination(termination);\n\t\t\treturn;\n\t\t}\n\t\tconsole.error(fallback);\n\t};\n\n\tconst disposeRuntime = async (): Promise<void> => {\n\t\tif (disposed) return;\n\t\tdisposed = true;\n\t\tunsubscribe?.();\n\t\tawait runtimeHost.dispose();\n\t};\n\n\tconst registerSignalHandlers = (): void => {\n\t\tconst signals: Array<\"SIGTERM\" | \"SIGHUP\"> = [\"SIGTERM\"];\n\t\tif (process.platform !== \"win32\") {\n\t\t\tsignals.push(\"SIGHUP\");\n\t\t}\n\n\t\tfor (const signal of signals) {\n\t\t\tconst handler = () => {\n\t\t\t\tsession.recordProcessSignal(signal);\n\t\t\t\tkillTrackedDetachedChildren();\n\t\t\t\tvoid disposeRuntime().finally(() => {\n\t\t\t\t\tprocess.exit(signal === \"SIGHUP\" ? 129 : 143);\n\t\t\t\t});\n\t\t\t};\n\t\t\tprocess.on(signal, handler);\n\t\t\tsignalCleanupHandlers.push(() => process.off(signal, handler));\n\t\t}\n\t};\n\n\tregisterSignalHandlers();\n\n\truntimeHost.setRebindSession(async () => {\n\t\tawait rebindSession();\n\t});\n\n\tconst rebindSession = async (): Promise<void> => {\n\t\tsession = runtimeHost.session;\n\t\tpromptStarted = false;\n\t\tlatestTermination = undefined;\n\t\tawait session.bindExtensions({\n\t\t\tmode: mode === \"json\" ? \"json\" : \"print\",\n\t\t\tcommandContextActions: {\n\t\t\t\twaitForIdle: () => session.agent.waitForIdle(),\n\t\t\t\tnewSession: async (newSessionOptions) => runtimeHost.newSession(newSessionOptions),\n\t\t\t\tfork: async (entryId, forkOptions) => {\n\t\t\t\t\tconst result = await runtimeHost.fork(entryId, forkOptions);\n\t\t\t\t\treturn { cancelled: result.cancelled };\n\t\t\t\t},\n\t\t\t\tnavigateTree: async (targetId, navigateOptions) => {\n\t\t\t\t\tconst result = await session.navigateTree(targetId, {\n\t\t\t\t\t\tsummarize: navigateOptions?.summarize,\n\t\t\t\t\t\tcustomInstructions: navigateOptions?.customInstructions,\n\t\t\t\t\t\treplaceInstructions: navigateOptions?.replaceInstructions,\n\t\t\t\t\t\tlabel: navigateOptions?.label,\n\t\t\t\t\t});\n\t\t\t\t\treturn { cancelled: result.cancelled };\n\t\t\t\t},\n\t\t\t\tswitchSession: async (sessionPath, switchOptions) => {\n\t\t\t\t\treturn runtimeHost.switchSession(sessionPath, switchOptions);\n\t\t\t\t},\n\t\t\t\treload: async () => {\n\t\t\t\t\tawait session.reload();\n\t\t\t\t},\n\t\t\t},\n\t\t\tonError: (err) => {\n\t\t\t\tconsole.error(`Extension error (${err.extensionPath}): ${err.error}`);\n\t\t\t},\n\t\t});\n\n\t\tunsubscribe?.();\n\t\tunsubscribe = session.subscribe((event) => {\n\t\t\tif (event.type === \"session_termination\") {\n\t\t\t\tlatestTermination = event.termination;\n\t\t\t\tif (mode === \"text\") {\n\t\t\t\t\trenderTermination(event.termination);\n\t\t\t\t} else {\n\t\t\t\t\trenderedTermination = event.termination;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (mode === \"json\") {\n\t\t\t\twriteRawStdout(`${JSON.stringify(event)}\\n`);\n\t\t\t}\n\t\t});\n\n\t\tconst startupTermination = session.lastTermination;\n\t\tif (startupTermination?.kind === \"process_crash\" && startupTermination.source === \"inferred_on_resume\") {\n\t\t\trenderTermination(startupTermination);\n\t\t}\n\t};\n\n\ttry {\n\t\tif (mode === \"json\") {\n\t\t\tconst header = session.sessionManager.getHeader();\n\t\t\tif (header) {\n\t\t\t\twriteRawStdout(`${JSON.stringify(header)}\\n`);\n\t\t\t}\n\t\t}\n\n\t\tawait rebindSession();\n\n\t\tconst hasPrompt =\n\t\t\t!!initialMessage?.trim() ||\n\t\t\tmessages.some((m) => typeof m === \"string\" && m.trim().length > 0) ||\n\t\t\t!!(initialImages && initialImages.length > 0);\n\t\tif (!hasPrompt) {\n\t\t\t// Bare `omk` with no prompt used to exit silently in print mode.\n\t\t\tconsole.error('No prompt provided. Use: omk -p \"...\" or run `omk` in an interactive terminal.');\n\t\t\texitCode = 2;\n\t\t\treturn exitCode;\n\t\t}\n\n\t\tif (initialMessage) {\n\t\t\tpromptStarted = true;\n\t\t\tawait session.prompt(initialMessage, { images: initialImages });\n\t\t}\n\n\t\tfor (const message of messages) {\n\t\t\tpromptStarted = true;\n\t\t\tawait session.prompt(message);\n\t\t}\n\n\t\tif (mode === \"text\") {\n\t\t\tconst state = session.state;\n\t\t\tconst lastMessage = state.messages[state.messages.length - 1];\n\n\t\t\tif (lastMessage?.role === \"assistant\") {\n\t\t\t\tconst assistantMsg = lastMessage as AssistantMessage;\n\t\t\t\tif (assistantMsg.stopReason === \"error\" || assistantMsg.stopReason === \"aborted\") {\n\t\t\t\t\trenderFailure(assistantMsg.errorMessage || `Request ${assistantMsg.stopReason}`);\n\t\t\t\t\texitCode = 1;\n\t\t\t\t} else {\n\t\t\t\t\tfor (const content of assistantMsg.content) {\n\t\t\t\t\t\tif (content.type === \"text\") {\n\t\t\t\t\t\t\twriteRawStdout(`${content.text}\\n`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn exitCode;\n\t} catch (error: unknown) {\n\t\trenderFailure(error instanceof Error ? error.message : String(error));\n\t\treturn 1;\n\t} finally {\n\t\tfor (const cleanup of signalCleanupHandlers) {\n\t\t\tcleanup();\n\t\t}\n\t\tawait disposeRuntime();\n\t\tawait flushRawStdout();\n\t}\n}\n"]}
1
+ {"version":3,"file":"print-mode.d.ts","sourceRoot":"","sources":["../../src/modes/print-mode.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAoB,YAAY,EAAE,MAAM,QAAQ,CAAC;AAC7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAM5E;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAChC,yEAAyE;IACzE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,wDAAwD;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8CAA8C;IAC9C,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;CAC/B;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,WAAW,EAAE,mBAAmB,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CA0M/G","sourcesContent":["/**\n * Print mode (single-shot): Send prompts, output result, exit.\n *\n * Used for:\n * - `omk -p \"prompt\"` - text output\n * - `omk --mode json \"prompt\"` - JSON event stream\n */\n\nimport type { AssistantMessage, ImageContent } from \"omk-ai\";\nimport type { AgentSessionRuntime } from \"../core/agent-session-runtime.ts\";\nimport { flushRawStdout, writeRawStdout } from \"../core/output-guard.ts\";\nimport type { PromptSettlementOutcome } from \"../core/prompt-settlement.ts\";\nimport { formatSessionTermination, type SessionTermination } from \"../core/session-termination.ts\";\nimport { killTrackedDetachedChildren } from \"../utils/shell.ts\";\n\n/**\n * Options for print mode.\n */\nexport interface PrintModeOptions {\n\t/** Output mode: \"text\" for final response only, \"json\" for all events */\n\tmode: \"text\" | \"json\";\n\t/** Array of additional prompts to send after initialMessage */\n\tmessages?: string[];\n\t/** First message to send (may contain @file content) */\n\tinitialMessage?: string;\n\t/** Images to attach to the initial message */\n\tinitialImages?: ImageContent[];\n}\n\n/**\n * Run in print (single-shot) mode.\n * Sends prompts to the agent and outputs the result.\n */\nexport async function runPrintMode(runtimeHost: AgentSessionRuntime, options: PrintModeOptions): Promise<number> {\n\tconst { mode, messages = [], initialMessage, initialImages } = options;\n\tlet exitCode = 0;\n\tlet session = runtimeHost.session;\n\tlet unsubscribe: (() => void) | undefined;\n\tlet disposed = false;\n\tlet promptStarted = false;\n\tlet latestTermination: SessionTermination | undefined;\n\tlet latestOutcome: PromptSettlementOutcome | undefined;\n\tlet renderedTermination: SessionTermination | undefined;\n\tconst signalCleanupHandlers: Array<() => void> = [];\n\n\tconst renderTermination = (termination: SessionTermination): void => {\n\t\tif (termination.kind === \"completed\" || renderedTermination === termination) return;\n\t\trenderedTermination = termination;\n\t\tif (mode === \"json\") {\n\t\t\twriteRawStdout(`${JSON.stringify({ type: \"session_termination\", termination })}\\n`);\n\t\t} else {\n\t\t\tconsole.error(formatSessionTermination(termination));\n\t\t}\n\t};\n\n\tconst renderFailure = (fallback: string): void => {\n\t\tconst termination = latestTermination ?? (!promptStarted ? session.lastTermination : undefined);\n\t\tif (termination && termination.kind !== \"completed\") {\n\t\t\trenderTermination(termination);\n\t\t\treturn;\n\t\t}\n\t\tconsole.error(fallback);\n\t};\n\n\tconst promptFailed = (): boolean => {\n\t\tconst last = session.state.messages.at(-1);\n\t\tconst assistantFailed =\n\t\t\tlast?.role === \"assistant\" && (last.stopReason === \"error\" || last.stopReason === \"aborted\");\n\t\tconst failed =\n\t\t\tlatestOutcome !== undefined\n\t\t\t\t? latestOutcome !== \"completed\"\n\t\t\t\t: assistantFailed || (latestTermination !== undefined && latestTermination.kind !== \"completed\");\n\t\tif (failed)\n\t\t\trenderFailure(\n\t\t\t\tassistantFailed ? last.errorMessage || `Request ${last.stopReason}` : \"Prompt did not complete.\",\n\t\t\t);\n\t\treturn failed;\n\t};\n\n\tconst disposeRuntime = async (): Promise<void> => {\n\t\tif (disposed) return;\n\t\tdisposed = true;\n\t\tunsubscribe?.();\n\t\tawait runtimeHost.dispose();\n\t};\n\n\tconst registerSignalHandlers = (): void => {\n\t\tconst signals: Array<\"SIGTERM\" | \"SIGHUP\"> = [\"SIGTERM\"];\n\t\tif (process.platform !== \"win32\") {\n\t\t\tsignals.push(\"SIGHUP\");\n\t\t}\n\n\t\tfor (const signal of signals) {\n\t\t\tconst handler = () => {\n\t\t\t\tsession.recordProcessSignal(signal);\n\t\t\t\tkillTrackedDetachedChildren();\n\t\t\t\tvoid disposeRuntime().finally(() => {\n\t\t\t\t\tprocess.exit(signal === \"SIGHUP\" ? 129 : 143);\n\t\t\t\t});\n\t\t\t};\n\t\t\tprocess.on(signal, handler);\n\t\t\tsignalCleanupHandlers.push(() => process.off(signal, handler));\n\t\t}\n\t};\n\n\tregisterSignalHandlers();\n\n\truntimeHost.setRebindSession(async () => {\n\t\tawait rebindSession();\n\t});\n\n\tconst rebindSession = async (): Promise<void> => {\n\t\tsession = runtimeHost.session;\n\t\tpromptStarted = false;\n\t\tlatestTermination = undefined;\n\t\tlatestOutcome = undefined;\n\t\tawait session.bindExtensions({\n\t\t\tmode: mode === \"json\" ? \"json\" : \"print\",\n\t\t\tcommandContextActions: {\n\t\t\t\twaitForIdle: () => session.agent.waitForIdle(),\n\t\t\t\tnewSession: async (newSessionOptions) => runtimeHost.newSession(newSessionOptions),\n\t\t\t\tfork: async (entryId, forkOptions) => {\n\t\t\t\t\tconst result = await runtimeHost.fork(entryId, forkOptions);\n\t\t\t\t\treturn { cancelled: result.cancelled };\n\t\t\t\t},\n\t\t\t\tnavigateTree: async (targetId, navigateOptions) => {\n\t\t\t\t\tconst result = await session.navigateTree(targetId, {\n\t\t\t\t\t\tsummarize: navigateOptions?.summarize,\n\t\t\t\t\t\tcustomInstructions: navigateOptions?.customInstructions,\n\t\t\t\t\t\treplaceInstructions: navigateOptions?.replaceInstructions,\n\t\t\t\t\t\tlabel: navigateOptions?.label,\n\t\t\t\t\t});\n\t\t\t\t\treturn { cancelled: result.cancelled };\n\t\t\t\t},\n\t\t\t\tswitchSession: async (sessionPath, switchOptions) => {\n\t\t\t\t\treturn runtimeHost.switchSession(sessionPath, switchOptions);\n\t\t\t\t},\n\t\t\t\treload: async () => {\n\t\t\t\t\tawait session.reload();\n\t\t\t\t},\n\t\t\t},\n\t\t\tonError: (err) => {\n\t\t\t\tconsole.error(`Extension error (${err.extensionPath}): ${err.error}`);\n\t\t\t},\n\t\t});\n\n\t\tunsubscribe?.();\n\t\tunsubscribe = session.subscribe((event) => {\n\t\t\tif (event.type === \"prompt_settled\") latestOutcome = event.outcome;\n\t\t\tif (event.type === \"session_termination\") {\n\t\t\t\tlatestTermination = event.termination;\n\t\t\t\tif (mode === \"text\") {\n\t\t\t\t\trenderTermination(event.termination);\n\t\t\t\t} else {\n\t\t\t\t\trenderedTermination = event.termination;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (mode === \"json\") {\n\t\t\t\twriteRawStdout(`${JSON.stringify(event)}\\n`);\n\t\t\t}\n\t\t});\n\n\t\tconst startupTermination = session.lastTermination;\n\t\tif (startupTermination?.kind === \"process_crash\" && startupTermination.source === \"inferred_on_resume\") {\n\t\t\trenderTermination(startupTermination);\n\t\t}\n\t};\n\n\ttry {\n\t\tif (mode === \"json\") {\n\t\t\tconst header = session.sessionManager.getHeader();\n\t\t\tif (header) {\n\t\t\t\twriteRawStdout(`${JSON.stringify(header)}\\n`);\n\t\t\t}\n\t\t}\n\n\t\tawait rebindSession();\n\n\t\tconst hasPrompt =\n\t\t\t!!initialMessage?.trim() ||\n\t\t\tmessages.some((m) => typeof m === \"string\" && m.trim().length > 0) ||\n\t\t\t!!(initialImages && initialImages.length > 0);\n\t\tif (!hasPrompt) {\n\t\t\t// Bare `omk` with no prompt used to exit silently in print mode.\n\t\t\tconsole.error('No prompt provided. Use: omk -p \"...\" or run `omk` in an interactive terminal.');\n\t\t\texitCode = 2;\n\t\t\treturn exitCode;\n\t\t}\n\n\t\tif (initialMessage) {\n\t\t\tpromptStarted = true;\n\t\t\tlatestTermination = undefined;\n\t\t\tlatestOutcome = undefined;\n\t\t\tawait session.prompt(initialMessage, { images: initialImages });\n\t\t\tif (promptFailed()) return 1;\n\t\t}\n\n\t\tfor (const message of messages) {\n\t\t\tpromptStarted = true;\n\t\t\tlatestTermination = undefined;\n\t\t\tlatestOutcome = undefined;\n\t\t\tawait session.prompt(message);\n\t\t\tif (promptFailed()) return 1;\n\t\t}\n\n\t\tif (mode === \"text\") {\n\t\t\tconst state = session.state;\n\t\t\tconst lastMessage = state.messages[state.messages.length - 1];\n\n\t\t\tif (lastMessage?.role === \"assistant\") {\n\t\t\t\tconst assistantMsg = lastMessage as AssistantMessage;\n\t\t\t\tif (assistantMsg.stopReason === \"error\" || assistantMsg.stopReason === \"aborted\") {\n\t\t\t\t\trenderFailure(assistantMsg.errorMessage || `Request ${assistantMsg.stopReason}`);\n\t\t\t\t\texitCode = 1;\n\t\t\t\t} else {\n\t\t\t\t\tfor (const content of assistantMsg.content) {\n\t\t\t\t\t\tif (content.type === \"text\") {\n\t\t\t\t\t\t\twriteRawStdout(`${content.text}\\n`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn exitCode;\n\t} catch (error: unknown) {\n\t\trenderFailure(error instanceof Error ? error.message : String(error));\n\t\treturn 1;\n\t} finally {\n\t\tfor (const cleanup of signalCleanupHandlers) {\n\t\t\tcleanup();\n\t\t}\n\t\tawait disposeRuntime();\n\t\tawait flushRawStdout();\n\t}\n}\n"]}
@@ -20,6 +20,7 @@ export async function runPrintMode(runtimeHost, options) {
20
20
  let disposed = false;
21
21
  let promptStarted = false;
22
22
  let latestTermination;
23
+ let latestOutcome;
23
24
  let renderedTermination;
24
25
  const signalCleanupHandlers = [];
25
26
  const renderTermination = (termination) => {
@@ -41,6 +42,16 @@ export async function runPrintMode(runtimeHost, options) {
41
42
  }
42
43
  console.error(fallback);
43
44
  };
45
+ const promptFailed = () => {
46
+ const last = session.state.messages.at(-1);
47
+ const assistantFailed = last?.role === "assistant" && (last.stopReason === "error" || last.stopReason === "aborted");
48
+ const failed = latestOutcome !== undefined
49
+ ? latestOutcome !== "completed"
50
+ : assistantFailed || (latestTermination !== undefined && latestTermination.kind !== "completed");
51
+ if (failed)
52
+ renderFailure(assistantFailed ? last.errorMessage || `Request ${last.stopReason}` : "Prompt did not complete.");
53
+ return failed;
54
+ };
44
55
  const disposeRuntime = async () => {
45
56
  if (disposed)
46
57
  return;
@@ -73,6 +84,7 @@ export async function runPrintMode(runtimeHost, options) {
73
84
  session = runtimeHost.session;
74
85
  promptStarted = false;
75
86
  latestTermination = undefined;
87
+ latestOutcome = undefined;
76
88
  await session.bindExtensions({
77
89
  mode: mode === "json" ? "json" : "print",
78
90
  commandContextActions: {
@@ -104,6 +116,8 @@ export async function runPrintMode(runtimeHost, options) {
104
116
  });
105
117
  unsubscribe?.();
106
118
  unsubscribe = session.subscribe((event) => {
119
+ if (event.type === "prompt_settled")
120
+ latestOutcome = event.outcome;
107
121
  if (event.type === "session_termination") {
108
122
  latestTermination = event.termination;
109
123
  if (mode === "text") {
@@ -141,11 +155,19 @@ export async function runPrintMode(runtimeHost, options) {
141
155
  }
142
156
  if (initialMessage) {
143
157
  promptStarted = true;
158
+ latestTermination = undefined;
159
+ latestOutcome = undefined;
144
160
  await session.prompt(initialMessage, { images: initialImages });
161
+ if (promptFailed())
162
+ return 1;
145
163
  }
146
164
  for (const message of messages) {
147
165
  promptStarted = true;
166
+ latestTermination = undefined;
167
+ latestOutcome = undefined;
148
168
  await session.prompt(message);
169
+ if (promptFailed())
170
+ return 1;
149
171
  }
150
172
  if (mode === "text") {
151
173
  const state = session.state;