@jinn-network/client 0.1.7 → 0.1.8

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 (319) hide show
  1. package/README.md +67 -1
  2. package/dist/adapters/mech/adapter.d.ts +19 -1
  3. package/dist/adapters/mech/adapter.js +130 -14
  4. package/dist/adapters/mech/adapter.js.map +1 -1
  5. package/dist/adapters/mech/contracts.d.ts +22 -1
  6. package/dist/adapters/mech/contracts.js +34 -24
  7. package/dist/adapters/mech/contracts.js.map +1 -1
  8. package/dist/adapters/mech/safe.d.ts +1 -1
  9. package/dist/adapters/mech/safe.js +5 -3
  10. package/dist/adapters/mech/safe.js.map +1 -1
  11. package/dist/adapters/mech/types.d.ts +6 -1
  12. package/dist/adapters/mech/types.js.map +1 -1
  13. package/dist/agent/operator-claude.js +8 -0
  14. package/dist/agent/operator-claude.js.map +1 -1
  15. package/dist/api/activity-events-endpoint.d.ts +14 -0
  16. package/dist/api/activity-events-endpoint.js +59 -0
  17. package/dist/api/activity-events-endpoint.js.map +1 -0
  18. package/dist/api/bootstrap-endpoint.d.ts +1 -2
  19. package/dist/api/bootstrap-endpoint.js +42 -24
  20. package/dist/api/bootstrap-endpoint.js.map +1 -1
  21. package/dist/api/codex-doctor-endpoint.d.ts +22 -5
  22. package/dist/api/codex-doctor-endpoint.js +136 -17
  23. package/dist/api/codex-doctor-endpoint.js.map +1 -1
  24. package/dist/api/debug-report-endpoint.d.ts +27 -0
  25. package/dist/api/debug-report-endpoint.js +157 -0
  26. package/dist/api/debug-report-endpoint.js.map +1 -0
  27. package/dist/api/gather-status.d.ts +33 -0
  28. package/dist/api/gather-status.js +211 -26
  29. package/dist/api/gather-status.js.map +1 -1
  30. package/dist/api/hermes-doctor-endpoint.d.ts +15 -7
  31. package/dist/api/hermes-doctor-endpoint.js +56 -19
  32. package/dist/api/hermes-doctor-endpoint.js.map +1 -1
  33. package/dist/api/launcher-status.d.ts +4 -2
  34. package/dist/api/launcher-status.js +11 -10
  35. package/dist/api/launcher-status.js.map +1 -1
  36. package/dist/api/launcher-tasks.d.ts +1 -1
  37. package/dist/api/launcher-tasks.js +12 -8
  38. package/dist/api/launcher-tasks.js.map +1 -1
  39. package/dist/api/operator-artifacts-endpoint.js +73 -6
  40. package/dist/api/operator-artifacts-endpoint.js.map +1 -1
  41. package/dist/api/portfolio-v0-build.d.ts +7 -1
  42. package/dist/api/portfolio-v0-build.js +6 -2
  43. package/dist/api/portfolio-v0-build.js.map +1 -1
  44. package/dist/api/prediction-v1-build.d.ts +6 -0
  45. package/dist/api/prediction-v1-build.js +3 -1
  46. package/dist/api/prediction-v1-build.js.map +1 -1
  47. package/dist/api/server.d.ts +17 -0
  48. package/dist/api/server.js +40 -1
  49. package/dist/api/server.js.map +1 -1
  50. package/dist/api/setup-endpoints.d.ts +0 -9
  51. package/dist/api/setup-endpoints.js +11 -153
  52. package/dist/api/setup-endpoints.js.map +1 -1
  53. package/dist/api/solvernets-endpoints.js +30 -63
  54. package/dist/api/solvernets-endpoints.js.map +1 -1
  55. package/dist/api/status-build.d.ts +115 -2
  56. package/dist/api/status-build.js +47 -11
  57. package/dist/api/status-build.js.map +1 -1
  58. package/dist/api/status-harness-rollup.d.ts +35 -0
  59. package/dist/api/status-harness-rollup.js +45 -0
  60. package/dist/api/status-harness-rollup.js.map +1 -0
  61. package/dist/api/task-runs-build.d.ts +8 -0
  62. package/dist/api/task-runs-build.js +5 -1
  63. package/dist/api/task-runs-build.js.map +1 -1
  64. package/dist/build-info.json +4 -4
  65. package/dist/build-meta.json +1 -1
  66. package/dist/captures/live-publisher.js +24 -4
  67. package/dist/captures/live-publisher.js.map +1 -1
  68. package/dist/captures/publish.d.ts +1 -1
  69. package/dist/chain-read-errors.d.ts +12 -0
  70. package/dist/chain-read-errors.js +26 -1
  71. package/dist/chain-read-errors.js.map +1 -1
  72. package/dist/cli/commands/codedigest-revert-check.d.ts +33 -0
  73. package/dist/cli/commands/codedigest-revert-check.js +249 -0
  74. package/dist/cli/commands/codedigest-revert-check.js.map +1 -0
  75. package/dist/cli/commands/solver-nets.d.ts +1 -0
  76. package/dist/cli/commands/solver-nets.js +177 -22
  77. package/dist/cli/commands/solver-nets.js.map +1 -1
  78. package/dist/cli/commands/solver-plugins-block.d.ts +33 -0
  79. package/dist/cli/commands/solver-plugins-block.js +118 -0
  80. package/dist/cli/commands/solver-plugins-block.js.map +1 -0
  81. package/dist/cli/commands/solver-plugins-feedback.d.ts +72 -0
  82. package/dist/cli/commands/solver-plugins-feedback.js +262 -0
  83. package/dist/cli/commands/solver-plugins-feedback.js.map +1 -0
  84. package/dist/cli/commands/solver-plugins-read.d.ts +54 -0
  85. package/dist/cli/commands/solver-plugins-read.js +259 -0
  86. package/dist/cli/commands/solver-plugins-read.js.map +1 -0
  87. package/dist/cli/commands/solver-plugins.d.ts +35 -0
  88. package/dist/cli/commands/solver-plugins.js +399 -2
  89. package/dist/cli/commands/solver-plugins.js.map +1 -1
  90. package/dist/cli/commands/tasks.js +15 -2
  91. package/dist/cli/commands/tasks.js.map +1 -1
  92. package/dist/cli/index.js +2 -0
  93. package/dist/cli/index.js.map +1 -1
  94. package/dist/cli/task-native-readiness.d.ts +7 -0
  95. package/dist/cli/task-native-readiness.js +7 -5
  96. package/dist/cli/task-native-readiness.js.map +1 -1
  97. package/dist/config.d.ts +183 -232
  98. package/dist/config.js +232 -107
  99. package/dist/config.js.map +1 -1
  100. package/dist/daemon/ai-units-gate.d.ts +54 -0
  101. package/dist/daemon/ai-units-gate.js +82 -0
  102. package/dist/daemon/ai-units-gate.js.map +1 -0
  103. package/dist/daemon/creator.js +13 -0
  104. package/dist/daemon/creator.js.map +1 -1
  105. package/dist/daemon/daemon.d.ts +10 -0
  106. package/dist/daemon/daemon.js +203 -30
  107. package/dist/daemon/daemon.js.map +1 -1
  108. package/dist/daemon/gate-logger.d.ts +9 -0
  109. package/dist/daemon/gate-logger.js +2 -0
  110. package/dist/daemon/gate-logger.js.map +1 -0
  111. package/dist/daemon/jinn-claim-loop.js +22 -4
  112. package/dist/daemon/jinn-claim-loop.js.map +1 -1
  113. package/dist/daemon/readiness-gate.d.ts +1 -4
  114. package/dist/daemon/readiness-gate.js.map +1 -1
  115. package/dist/daemon/spend-cap-gate.d.ts +40 -0
  116. package/dist/daemon/spend-cap-gate.js +46 -0
  117. package/dist/daemon/spend-cap-gate.js.map +1 -0
  118. package/dist/dashboard/assets/index-CzKxvMcU.css +32 -0
  119. package/dist/dashboard/assets/index-yVemxHot.js +351 -0
  120. package/dist/dashboard/index.html +2 -2
  121. package/dist/discovery/http.js +328 -1
  122. package/dist/discovery/http.js.map +1 -1
  123. package/dist/discovery/onchain.js +42 -4
  124. package/dist/discovery/onchain.js.map +1 -1
  125. package/dist/discovery/types.d.ts +129 -0
  126. package/dist/discovery/types.js.map +1 -1
  127. package/dist/discovery/with-fallback.js +27 -0
  128. package/dist/discovery/with-fallback.js.map +1 -1
  129. package/dist/earning/bootstrap.d.ts +8 -3
  130. package/dist/earning/bootstrap.js +36 -13
  131. package/dist/earning/bootstrap.js.map +1 -1
  132. package/dist/earning/safe-adapter.js +23 -11
  133. package/dist/earning/safe-adapter.js.map +1 -1
  134. package/dist/earning/types.d.ts +6 -6
  135. package/dist/earning/viem-clients.d.ts +11 -4
  136. package/dist/earning/viem-clients.js +14 -5
  137. package/dist/earning/viem-clients.js.map +1 -1
  138. package/dist/erc8004/identity.d.ts +19 -3
  139. package/dist/erc8004/identity.js +38 -11
  140. package/dist/erc8004/identity.js.map +1 -1
  141. package/dist/erc8004/index.d.ts +1 -1
  142. package/dist/erc8004/index.js.map +1 -1
  143. package/dist/events/types.d.ts +2 -2
  144. package/dist/harnesses/cost-estimates.d.ts +10 -31
  145. package/dist/harnesses/cost-estimates.js +11 -43
  146. package/dist/harnesses/cost-estimates.js.map +1 -1
  147. package/dist/harnesses/engine/engine.d.ts +28 -4
  148. package/dist/harnesses/engine/engine.js +103 -17
  149. package/dist/harnesses/engine/engine.js.map +1 -1
  150. package/dist/harnesses/engine/persistence.d.ts +21 -4
  151. package/dist/harnesses/engine/persistence.js +43 -6
  152. package/dist/harnesses/engine/persistence.js.map +1 -1
  153. package/dist/harnesses/engine/state.d.ts +9 -0
  154. package/dist/harnesses/engine/state.js +23 -10
  155. package/dist/harnesses/engine/state.js.map +1 -1
  156. package/dist/harnesses/impls/hermes-agent/bootstrap.js +4 -2
  157. package/dist/harnesses/impls/hermes-agent/bootstrap.js.map +1 -1
  158. package/dist/harnesses/impls/hermes-agent/config-builder.d.ts +1 -1
  159. package/dist/harnesses/impls/hermes-agent/config-builder.js +4 -2
  160. package/dist/harnesses/impls/hermes-agent/config-builder.js.map +1 -1
  161. package/dist/harnesses/impls/hermes-agent/harness.d.ts +14 -0
  162. package/dist/harnesses/impls/hermes-agent/harness.js +16 -2
  163. package/dist/harnesses/impls/hermes-agent/harness.js.map +1 -1
  164. package/dist/harnesses/impls/hermes-agent/prompt.d.ts +6 -6
  165. package/dist/harnesses/impls/hermes-agent/prompt.js +6 -6
  166. package/dist/harnesses/impls/learner/adapters/claude-code.d.ts +17 -0
  167. package/dist/harnesses/impls/learner/adapters/claude-code.js +113 -14
  168. package/dist/harnesses/impls/learner/adapters/claude-code.js.map +1 -1
  169. package/dist/harnesses/impls/learner/adapters/codex-code.d.ts +9 -0
  170. package/dist/harnesses/impls/learner/adapters/codex-code.js +30 -8
  171. package/dist/harnesses/impls/learner/adapters/codex-code.js.map +1 -1
  172. package/dist/harnesses/impls/learner/harness.d.ts +24 -0
  173. package/dist/harnesses/impls/learner/harness.js +27 -3
  174. package/dist/harnesses/impls/learner/harness.js.map +1 -1
  175. package/dist/harnesses/impls/learner/harvest.d.ts +1 -1
  176. package/dist/harnesses/impls/learner/harvest.js +23 -5
  177. package/dist/harnesses/impls/learner/harvest.js.map +1 -1
  178. package/dist/harnesses/impls/learner/restoration-patch.d.ts +2 -2
  179. package/dist/harnesses/impls/learner/restoration-patch.js +25 -6
  180. package/dist/harnesses/impls/learner/restoration-patch.js.map +1 -1
  181. package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.js +21 -1
  182. package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.js.map +1 -1
  183. package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.d.ts +74 -5
  184. package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.js +103 -32
  185. package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.js.map +1 -1
  186. package/dist/harnesses/readiness-registry.d.ts +7 -0
  187. package/dist/harnesses/readiness-registry.js +9 -0
  188. package/dist/harnesses/readiness-registry.js.map +1 -1
  189. package/dist/learner/revert-decision.d.ts +59 -0
  190. package/dist/learner/revert-decision.js +53 -0
  191. package/dist/learner/revert-decision.js.map +1 -0
  192. package/dist/learner/revert-stats.d.ts +24 -0
  193. package/dist/learner/revert-stats.js +44 -0
  194. package/dist/learner/revert-stats.js.map +1 -0
  195. package/dist/main.js +177 -104
  196. package/dist/main.js.map +1 -1
  197. package/dist/mcp/get-codedigest-reward.d.ts +13 -0
  198. package/dist/mcp/get-codedigest-reward.js +23 -0
  199. package/dist/mcp/get-codedigest-reward.js.map +1 -0
  200. package/dist/mcp/server.js +23 -0
  201. package/dist/mcp/server.js.map +1 -1
  202. package/dist/observability/debug-report-assemble.d.ts +43 -0
  203. package/dist/observability/debug-report-assemble.js +80 -0
  204. package/dist/observability/debug-report-assemble.js.map +1 -0
  205. package/dist/observability/emit-event.d.ts +9 -2
  206. package/dist/observability/emit-event.js +36 -2
  207. package/dist/observability/emit-event.js.map +1 -1
  208. package/dist/observability/file-logger.d.ts +69 -0
  209. package/dist/observability/file-logger.js +177 -0
  210. package/dist/observability/file-logger.js.map +1 -0
  211. package/dist/observability/redact-secrets.d.ts +65 -0
  212. package/dist/observability/redact-secrets.js +300 -0
  213. package/dist/observability/redact-secrets.js.map +1 -0
  214. package/dist/observability/tar.d.ts +30 -0
  215. package/dist/observability/tar.js +102 -0
  216. package/dist/observability/tar.js.map +1 -0
  217. package/dist/plugins/learner/skills/learn/consolidator-prompt.md +18 -1
  218. package/dist/plugins/learner/skills/learn/promoter-prompt.md +72 -1
  219. package/dist/preflight/pidfile-liveness.d.ts +44 -0
  220. package/dist/preflight/pidfile-liveness.js +103 -0
  221. package/dist/preflight/pidfile-liveness.js.map +1 -0
  222. package/dist/preflight/rpc-network.d.ts +40 -0
  223. package/dist/preflight/rpc-network.js +67 -1
  224. package/dist/preflight/rpc-network.js.map +1 -1
  225. package/dist/rpc/transport.d.ts +109 -0
  226. package/dist/rpc/transport.js +220 -0
  227. package/dist/rpc/transport.js.map +1 -0
  228. package/dist/scripts/donation-consumption-acceptance.js +7 -28
  229. package/dist/scripts/donation-consumption-acceptance.js.map +1 -1
  230. package/dist/scripts/swe-rebench-v2-pytest-missing.json +16 -0
  231. package/dist/solver-nets/prediction-operator-ux.d.ts +1 -2
  232. package/dist/solver-nets/prediction-operator-ux.js +56 -53
  233. package/dist/solver-nets/prediction-operator-ux.js.map +1 -1
  234. package/dist/solver-nets/registry.d.ts +19 -1
  235. package/dist/solver-nets/registry.js +37 -24
  236. package/dist/solver-nets/registry.js.map +1 -1
  237. package/dist/solver-types/_swe-rebench-v2-pool.d.ts +9 -2
  238. package/dist/solver-types/_swe-rebench-v2-pool.js +15 -20
  239. package/dist/solver-types/_swe-rebench-v2-pool.js.map +1 -1
  240. package/dist/solver-types/_swe-rebench-v2-state.d.ts +15 -0
  241. package/dist/solver-types/_swe-rebench-v2-state.js +19 -0
  242. package/dist/solver-types/_swe-rebench-v2-state.js.map +1 -1
  243. package/dist/solver-types/_swe-rebench-v2-validated-pool.d.ts +116 -2
  244. package/dist/solver-types/_swe-rebench-v2-validated-pool.js +296 -21
  245. package/dist/solver-types/_swe-rebench-v2-validated-pool.js.map +1 -1
  246. package/dist/solver-types/swe-rebench-v2-auto.d.ts +20 -11
  247. package/dist/solver-types/swe-rebench-v2-auto.js +64 -19
  248. package/dist/solver-types/swe-rebench-v2-auto.js.map +1 -1
  249. package/dist/solver-types/swe-rebench-v2.d.ts +8 -2
  250. package/dist/solver-types/swe-rebench-v2.js +127 -11
  251. package/dist/solver-types/swe-rebench-v2.js.map +1 -1
  252. package/dist/solvernets/daemon-init.d.ts +1 -1
  253. package/dist/solvernets/daemon-init.js +19 -4
  254. package/dist/solvernets/daemon-init.js.map +1 -1
  255. package/dist/solvernets/launched-record-dispatcher.d.ts +4 -0
  256. package/dist/solvernets/launched-record-dispatcher.js +10 -4
  257. package/dist/solvernets/launched-record-dispatcher.js.map +1 -1
  258. package/dist/solvernets/registry-client-erc8004.js +11 -0
  259. package/dist/solvernets/registry-client-erc8004.js.map +1 -1
  260. package/dist/solvernets/store.d.ts +2 -2
  261. package/dist/spend/ai-units-config.d.ts +39 -0
  262. package/dist/spend/ai-units-config.js +28 -0
  263. package/dist/spend/ai-units-config.js.map +1 -0
  264. package/dist/spend/ai-units.d.ts +89 -0
  265. package/dist/spend/ai-units.js +156 -0
  266. package/dist/spend/ai-units.js.map +1 -0
  267. package/dist/spend/cost-surface-status.d.ts +12 -0
  268. package/dist/spend/cost-surface-status.js +24 -0
  269. package/dist/spend/cost-surface-status.js.map +1 -0
  270. package/dist/spend/credential.d.ts +39 -0
  271. package/dist/spend/credential.js +71 -0
  272. package/dist/spend/credential.js.map +1 -0
  273. package/dist/spend/daemon-config.d.ts +13 -0
  274. package/dist/spend/daemon-config.js +24 -0
  275. package/dist/spend/daemon-config.js.map +1 -0
  276. package/dist/spend/pricing.d.ts +16 -0
  277. package/dist/spend/pricing.js +26 -0
  278. package/dist/spend/pricing.js.map +1 -0
  279. package/dist/spend/record.d.ts +13 -0
  280. package/dist/spend/record.js +36 -0
  281. package/dist/spend/record.js.map +1 -0
  282. package/dist/spend/usage.d.ts +27 -0
  283. package/dist/spend/usage.js +113 -0
  284. package/dist/spend/usage.js.map +1 -0
  285. package/dist/store/store.d.ts +101 -0
  286. package/dist/store/store.js +304 -4
  287. package/dist/store/store.js.map +1 -1
  288. package/dist/trajectory/transcript-parsers/codex-session.d.ts +12 -6
  289. package/dist/trajectory/transcript-parsers/codex-session.js +114 -13
  290. package/dist/trajectory/transcript-parsers/codex-session.js.map +1 -1
  291. package/dist/trajectory/transcript-parsers/types.d.ts +8 -8
  292. package/dist/trajectory/transcript-session-dirs.d.ts +18 -0
  293. package/dist/trajectory/transcript-session-dirs.js +85 -0
  294. package/dist/trajectory/transcript-session-dirs.js.map +1 -0
  295. package/dist/trajectory/transcript-watcher.d.ts +20 -1
  296. package/dist/trajectory/transcript-watcher.js +108 -32
  297. package/dist/trajectory/transcript-watcher.js.map +1 -1
  298. package/dist/tx-retry.d.ts +25 -0
  299. package/dist/tx-retry.js +95 -7
  300. package/dist/tx-retry.js.map +1 -1
  301. package/dist/types/payloads/portfolio-v0.d.ts +3 -3
  302. package/dist/types/payloads/prediction-apy-v0.d.ts +3 -3
  303. package/dist/types/payloads/prediction-v0.d.ts +12 -12
  304. package/package.json +11 -3
  305. package/plugins/learner/skills/learn/consolidator-prompt.md +18 -1
  306. package/plugins/learner/skills/learn/promoter-prompt.md +72 -1
  307. package/plugins/swe-rebench-v2-diffmin/README.md +10 -9
  308. package/plugins/swe-rebench-v2-diffmin/jinn.plugin.json +1 -1
  309. package/plugins/swe-rebench-v2-diffmin/skills/diffmin/SKILL.md +15 -10
  310. package/plugins/swe-rebench-v2-diffmin/skills/test-map/SKILL.md +10 -12
  311. package/plugins/swe-rebench-v2-runtime/.claude-plugin/plugin.json +1 -1
  312. package/plugins/swe-rebench-v2-runtime/.codex-plugin/plugin.json +3 -3
  313. package/plugins/swe-rebench-v2-runtime/README.md +6 -6
  314. package/plugins/swe-rebench-v2-runtime/jinn.plugin.json +2 -3
  315. package/plugins/swe-rebench-v2-runtime/skills/task/SKILL.md +81 -0
  316. package/dist/dashboard/assets/index-BUlE8F3Y.js +0 -330
  317. package/dist/dashboard/assets/index-blqc7eqq.css +0 -32
  318. package/plugins/swe-rebench-v2-runtime/skills/orient/SKILL.md +0 -29
  319. package/plugins/swe-rebench-v2-runtime/skills/plan/SKILL.md +0 -53
@@ -1,9 +1,15 @@
1
1
  /**
2
2
  * GET /api/codex/doctor
3
3
  *
4
- * Runs `codex --version` via spawnSync and inspects the auth configuration so
5
- * the operator dashboard can show an install-required / sign-in-required panel
6
- * before the operator saves a Codex harness selection.
4
+ * Runs `codex --version` via async execFile and inspects the auth configuration
5
+ * so the operator dashboard can show an install-required / sign-in-required
6
+ * panel before the operator saves a Codex harness selection.
7
+ *
8
+ * Async (#778 follow-up): the readiness registry refreshes the learner
9
+ * harness's `isReady()` periodically; that path calls `probeCodexDoctor`. The
10
+ * original `spawnSync` blocked the daemon main event loop on every refresh,
11
+ * same wedge class as the Hermes endpoint (see hermes-doctor-endpoint.ts file
12
+ * header). Converted to `promisify(execFile)` with a 10s timeout.
7
13
  *
8
14
  * Response shape:
9
15
  * { installed: boolean, authenticated: boolean,
@@ -40,12 +46,18 @@
40
46
  import type { Hono } from 'hono';
41
47
  /** Classification of Codex credentials. */
42
48
  export type CodexAuthStatus = 'ok' | 'expired' | 'not_configured';
49
+ /** Classification of the installed codex CLI version against the tested range. */
50
+ export type CodexVersionStatus = 'ok' | 'unknown' | 'untested';
43
51
  export interface CodexDoctorResponse {
44
52
  installed: boolean;
45
53
  /** Convenience alias — true iff `authStatus === 'ok'`. */
46
54
  authenticated: boolean;
47
55
  /** Live/expired/absent classification of Codex credentials. */
48
56
  authStatus: CodexAuthStatus;
57
+ /** Parsed semver string from `codex --version`, or null when unparseable. */
58
+ cliVersion: string | null;
59
+ /** ok = within tested range; untested = outside it; unknown = unparseable (#675). */
60
+ versionStatus: CodexVersionStatus;
49
61
  exitCode: number | null;
50
62
  stdout: string;
51
63
  stderr: string;
@@ -65,9 +77,14 @@ export interface CodexDoctorConfig {
65
77
  now?: number;
66
78
  }
67
79
  /**
68
- * Synchronously runs `codex --version` and classifies install + auth state.
80
+ * Asynchronously runs `codex --version` and classifies install + auth state.
69
81
  * Pure (no Hono dependency) so the harness layer can call it without pulling
70
82
  * the API server in.
83
+ *
84
+ * Async (#778 follow-up): see file header — `execFile` failures (non-zero
85
+ * exit OR kill-by-timeout) throw with `{stdout, stderr, code, signal}`
86
+ * attached; we unwrap that into the same classification surface the old
87
+ * sync code produced.
71
88
  */
72
- export declare function probeCodexDoctor(config?: CodexDoctorConfig): CodexDoctorResponse;
89
+ export declare function probeCodexDoctor(config?: CodexDoctorConfig): Promise<CodexDoctorResponse>;
73
90
  export declare function addCodexDoctorRoutes(app: Hono, config?: CodexDoctorConfig): void;
@@ -1,7 +1,25 @@
1
- import { spawnSync } from 'node:child_process';
1
+ import { execFile } from 'node:child_process';
2
2
  import { readFileSync } from 'node:fs';
3
3
  import { homedir } from 'node:os';
4
4
  import { join } from 'node:path';
5
+ import { promisify } from 'node:util';
6
+ const execFileAsync = promisify(execFile);
7
+ /**
8
+ * Tested @openai/codex CLI version window (#675). Below MIN or above MAX, the
9
+ * harness may break — codex 0.133.0 introduced a stdin contract change that
10
+ * silently broke the previous positional-prompt invocation. Bumping these
11
+ * bounds is a deliberate compatibility statement, made with a green run of
12
+ * `yarn test test/harnesses/impls/learner/codex-code-adapter.test.ts` against
13
+ * the new CLI version.
14
+ *
15
+ * The upper bound is compared on major+minor only: patch releases within the
16
+ * same minor as `MAX_TESTED_CODEX_VERSION` are treated as `'ok'`, since codex
17
+ * patch bumps almost never break the CLI contract and warning on every patch
18
+ * would produce alarm fatigue. Bump `MAX_TESTED_CODEX_VERSION` when codex
19
+ * bumps its minor or major; patch bumps stay `'ok'` automatically.
20
+ */
21
+ const MIN_TESTED_CODEX_VERSION = '0.50.0';
22
+ const MAX_TESTED_CODEX_VERSION = '0.133.0';
5
23
  /**
6
24
  * Decodes a JWT's payload and returns its `exp` claim (epoch seconds), or
7
25
  * `undefined` when the token is absent, malformed, or carries no `exp`.
@@ -134,44 +152,145 @@ function hasApiKey(config) {
134
152
  return Boolean(env['OPENAI_API_KEY']?.trim());
135
153
  }
136
154
  /**
137
- * Synchronously runs `codex --version` and classifies install + auth state.
155
+ * Extracts the first `MAJOR.MINOR.PATCH` semver-looking triple from `codex
156
+ * --version` output. Returns null when no such triple is present.
157
+ */
158
+ function parseCodexVersion(stdout) {
159
+ const match = stdout.match(/\d+\.\d+\.\d+/);
160
+ return match ? match[0] : null;
161
+ }
162
+ /**
163
+ * Compares two `MAJOR.MINOR.PATCH` strings segment-by-segment as integers.
164
+ * Returns -1 if `a < b`, 0 if equal, 1 if `a > b`. Non-numeric / missing
165
+ * segments fall back to 0 so a partial input never throws.
166
+ */
167
+ function compareSemver(a, b) {
168
+ const av = a.split('.').map((s) => Number.parseInt(s, 10) || 0);
169
+ const bv = b.split('.').map((s) => Number.parseInt(s, 10) || 0);
170
+ for (let i = 0; i < 3; i++) {
171
+ const ai = av[i] ?? 0;
172
+ const bi = bv[i] ?? 0;
173
+ if (ai < bi)
174
+ return -1;
175
+ if (ai > bi)
176
+ return 1;
177
+ }
178
+ return 0;
179
+ }
180
+ /**
181
+ * Returns true when `a`'s `MAJOR.MINOR` is strictly greater than `b`'s. Patch
182
+ * differences within the same minor are ignored, so 0.133.5 is NOT above
183
+ * 0.133.0, but 0.134.0 and 1.0.0 are. Used for the upper-bound check (#675)
184
+ * so codex patch releases don't trip the untested-version warning.
185
+ */
186
+ function isAboveMinor(a, b) {
187
+ const av = a.split('.').map((s) => Number.parseInt(s, 10) || 0);
188
+ const bv = b.split('.').map((s) => Number.parseInt(s, 10) || 0);
189
+ const [aMajor, aMinor] = [av[0] ?? 0, av[1] ?? 0];
190
+ const [bMajor, bMinor] = [bv[0] ?? 0, bv[1] ?? 0];
191
+ if (aMajor !== bMajor)
192
+ return aMajor > bMajor;
193
+ return aMinor > bMinor;
194
+ }
195
+ /**
196
+ * Classifies a parsed semver against the tested range.
197
+ * - null → 'unknown'
198
+ * - below MIN (full semver compare) → 'untested'
199
+ * - above MAX on major+minor → 'untested' (patch bumps within the tested
200
+ * minor stay 'ok'; bump MAX_TESTED_CODEX_VERSION on minor/major bumps)
201
+ * - otherwise → 'ok'
202
+ */
203
+ function classifyVersion(cliVersion) {
204
+ if (cliVersion === null)
205
+ return 'unknown';
206
+ if (compareSemver(cliVersion, MIN_TESTED_CODEX_VERSION) < 0
207
+ || isAboveMinor(cliVersion, MAX_TESTED_CODEX_VERSION)) {
208
+ return 'untested';
209
+ }
210
+ return 'ok';
211
+ }
212
+ // Module-scoped so the warning fires once per process even though
213
+ // `probeCodexDoctor` is called every readiness tick.
214
+ let untestedVersionWarningEmitted = false;
215
+ /**
216
+ * Asynchronously runs `codex --version` and classifies install + auth state.
138
217
  * Pure (no Hono dependency) so the harness layer can call it without pulling
139
218
  * the API server in.
219
+ *
220
+ * Async (#778 follow-up): see file header — `execFile` failures (non-zero
221
+ * exit OR kill-by-timeout) throw with `{stdout, stderr, code, signal}`
222
+ * attached; we unwrap that into the same classification surface the old
223
+ * sync code produced.
140
224
  */
141
- export function probeCodexDoctor(config = {}) {
225
+ export async function probeCodexDoctor(config = {}) {
142
226
  const codexBin = config.codexPath ?? 'codex';
143
- const timeoutMs = config.codexDoctorTimeoutMs ?? 30_000;
144
- const result = spawnSync(codexBin, ['--version'], {
145
- timeout: timeoutMs,
146
- encoding: 'utf8',
147
- });
148
- const errorCode = result.error?.code;
227
+ // Defaults to 10s here (vs 30s on the sync path) because this fires on the
228
+ // readiness-registry refresh tick a hung shell-out must not snowball into
229
+ // an outstanding 30s timer per tick.
230
+ const timeoutMs = config.codexDoctorTimeoutMs ?? 10_000;
231
+ let status = 0;
232
+ let signal = null;
233
+ let stdout = '';
234
+ let stderr = '';
235
+ let errorCode;
236
+ try {
237
+ const ok = await execFileAsync(codexBin, ['--version'], {
238
+ timeout: timeoutMs,
239
+ encoding: 'utf8',
240
+ });
241
+ stdout = ok.stdout;
242
+ stderr = ok.stderr;
243
+ }
244
+ catch (err) {
245
+ const errno = err;
246
+ const codeIsString = typeof errno.code === 'string';
247
+ status = !codeIsString && typeof errno.code === 'number' ? errno.code : null;
248
+ errorCode = codeIsString ? errno.code : undefined;
249
+ signal = errno.signal ?? null;
250
+ stdout = typeof errno.stdout === 'string' ? errno.stdout : errno.stdout?.toString() ?? '';
251
+ stderr = typeof errno.stderr === 'string' ? errno.stderr : errno.stderr?.toString() ?? '';
252
+ }
149
253
  // installed=true means we found the binary on disk. ENOENT is the only
150
254
  // definitive not-installed signal. Other errors (EACCES = wrong
151
255
  // permissions; ETIMEDOUT = ran but didn't finish in time) indicate the
152
256
  // binary exists but couldn't be exercised cleanly — surface those as
153
257
  // config-issue, not missing.
154
258
  const notFound = errorCode === 'ENOENT';
155
- const installed = !notFound && (result.status !== null
156
- || result.signal !== null
259
+ const installed = !notFound && (status !== null
260
+ || signal !== null
157
261
  || (errorCode != null && errorCode !== 'ENOENT'));
158
262
  // Auth is only meaningful once the binary is present and runnable.
159
- const runnable = installed && result.status === 0;
263
+ const runnable = installed && status === 0;
160
264
  const authStatus = runnable
161
265
  ? detectCodexAuthStatus(config)
162
266
  : 'not_configured';
267
+ // Version surfacing (#675). Parse only when we have a runnable binary;
268
+ // otherwise the stdout is meaningless.
269
+ const cliVersion = runnable ? parseCodexVersion(stdout) : null;
270
+ const versionStatus = runnable
271
+ ? classifyVersion(cliVersion)
272
+ : 'unknown';
273
+ if (versionStatus === 'untested' && !untestedVersionWarningEmitted) {
274
+ untestedVersionWarningEmitted = true;
275
+ // eslint-disable-next-line no-console
276
+ console.warn(`codex CLI version ${cliVersion} is outside the tested range `
277
+ + `${MIN_TESTED_CODEX_VERSION}–${MAX_TESTED_CODEX_VERSION}; the harness `
278
+ + `may break — see issue #675`);
279
+ }
163
280
  return {
164
281
  installed,
165
282
  authenticated: authStatus === 'ok',
166
283
  authStatus,
167
- exitCode: result.status,
168
- stdout: (result.stdout ?? '').slice(0, 4000),
169
- stderr: (result.stderr ?? '').slice(0, 4000),
284
+ cliVersion,
285
+ versionStatus,
286
+ exitCode: status,
287
+ stdout: stdout.slice(0, 4000),
288
+ stderr: stderr.slice(0, 4000),
170
289
  };
171
290
  }
172
291
  export function addCodexDoctorRoutes(app, config = {}) {
173
- app.get('/api/codex/doctor', (c) => {
174
- return c.json(probeCodexDoctor(config));
292
+ app.get('/api/codex/doctor', async (c) => {
293
+ return c.json(await probeCodexDoctor(config));
175
294
  });
176
295
  }
177
296
  //# sourceMappingURL=codex-doctor-endpoint.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"codex-doctor-endpoint.js","sourceRoot":"","sources":["../../src/api/codex-doctor-endpoint.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"codex-doctor-endpoint.js","sourceRoot":"","sources":["../../src/api/codex-doctor-endpoint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * One-click operator debug-report endpoints (issue #420 §2).
3
+ *
4
+ * `GET /v1/debug-report/manifest` — describes what the bundle will contain
5
+ * (file list + redaction summary) so the SPA can show the operator before
6
+ * they download. No screenshot needed.
7
+ *
8
+ * `POST /v1/debug-report` — gathers the daemon status, resolved config,
9
+ * config provenance, recent activity events and rotated log files,
10
+ * assembles a redacted `.tar.gz`, and streams it as an attachment. The
11
+ * request body may carry a client-captured dashboard screenshot.
12
+ *
13
+ * Both routes are gated by the UI token via the `app.use('/v1/debug-report*')`
14
+ * block in `startApiServer`. They register eagerly (no holder needed — the
15
+ * Store and config are available at server-start time).
16
+ */
17
+ import type { Hono } from 'hono';
18
+ import type { Store } from '../store/store.js';
19
+ import type { JinnConfig } from '../config.js';
20
+ export interface DebugReportRoutesConfig {
21
+ store: Store;
22
+ /** The live resolved config object held by `main.ts`. */
23
+ config: JinnConfig;
24
+ /** Explicit config path passed to `loadConfig`, if any. */
25
+ configPath?: string;
26
+ }
27
+ export declare function addDebugReportRoutes(app: Hono, config: DebugReportRoutesConfig): void;
@@ -0,0 +1,157 @@
1
+ /**
2
+ * One-click operator debug-report endpoints (issue #420 §2).
3
+ *
4
+ * `GET /v1/debug-report/manifest` — describes what the bundle will contain
5
+ * (file list + redaction summary) so the SPA can show the operator before
6
+ * they download. No screenshot needed.
7
+ *
8
+ * `POST /v1/debug-report` — gathers the daemon status, resolved config,
9
+ * config provenance, recent activity events and rotated log files,
10
+ * assembles a redacted `.tar.gz`, and streams it as an attachment. The
11
+ * request body may carry a client-captured dashboard screenshot.
12
+ *
13
+ * Both routes are gated by the UI token via the `app.use('/v1/debug-report*')`
14
+ * block in `startApiServer`. They register eagerly (no holder needed — the
15
+ * Store and config are available at server-start time).
16
+ */
17
+ import { basename } from 'node:path';
18
+ import { readFile } from 'node:fs/promises';
19
+ import { buildConfigProvenance } from '../config.js';
20
+ import { gatherStatusForApi } from './gather-status.js';
21
+ import { buildInfo } from '../build-info.js';
22
+ import { getFileLogger } from '../observability/file-logger.js';
23
+ import { assembleDebugReport, DEBUG_REPORT_FILES, } from '../observability/debug-report-assemble.js';
24
+ import { REDACTION_VERSION } from '../observability/redact-secrets.js';
25
+ /** Number of recent lifecycle events to include in the bundle. */
26
+ const ACTIVITY_EVENT_LIMIT = 1000;
27
+ /** Decode a base64 dashboard screenshot from the request body. */
28
+ function decodeScreenshot(value) {
29
+ if (typeof value !== 'string' || value.length === 0)
30
+ return undefined;
31
+ // Tolerate a `data:image/png;base64,` prefix even though the SPA strips it.
32
+ const stripped = value.replace(/^data:image\/png;base64,/, '');
33
+ try {
34
+ const buf = Buffer.from(stripped, 'base64');
35
+ return buf.length > 0 ? buf : undefined;
36
+ }
37
+ catch {
38
+ return undefined;
39
+ }
40
+ }
41
+ /** The rotated log files' on-disk paths, in bundle order. Never throws. */
42
+ function logFilePaths() {
43
+ try {
44
+ return getFileLogger().listLogFiles();
45
+ }
46
+ catch {
47
+ return [];
48
+ }
49
+ }
50
+ /**
51
+ * Read the rotated log files for the bundle. Best-effort — never throws.
52
+ * Async (`fs/promises.readFile`) so reading up to ~25 MiB of rotated logs
53
+ * does not block the daemon event loop on the request path.
54
+ */
55
+ async function readLogFiles() {
56
+ const out = [];
57
+ for (const path of logFilePaths()) {
58
+ try {
59
+ out.push({ name: basename(path), content: await readFile(path) });
60
+ }
61
+ catch {
62
+ // Skip an unreadable log file rather than failing the whole bundle.
63
+ }
64
+ }
65
+ return out;
66
+ }
67
+ export function addDebugReportRoutes(app, config) {
68
+ // GET /v1/debug-report/manifest — describe the bundle before download.
69
+ app.get('/v1/debug-report/manifest', (c) => {
70
+ const logNames = logFilePaths().map((p) => `logs/${basename(p)}`);
71
+ return c.json({
72
+ files: [...DEBUG_REPORT_FILES, ...logNames, 'dashboard-screenshot.png'],
73
+ redaction: {
74
+ version: REDACTION_VERSION,
75
+ redacted: [
76
+ 'keystore password / JINN_PASSWORD',
77
+ 'private keys, mnemonics and seed phrases',
78
+ 'daemon API token, UI token, handshake key',
79
+ 'harness / provider API keys',
80
+ 'RPC URL credential segments',
81
+ ],
82
+ kept: [
83
+ 'wallet addresses (public on-chain)',
84
+ 'RPC hostnames and path shape (needed to reproduce network issues)',
85
+ 'contract and deployment addresses',
86
+ 'file paths',
87
+ ],
88
+ notRedacted: [
89
+ 'dashboard-screenshot.png — a pixel capture of the screen; text '
90
+ + 'redaction does not apply, so anything visible at capture time '
91
+ + 'appears in it. Review before sharing.',
92
+ ],
93
+ },
94
+ });
95
+ });
96
+ // POST /v1/debug-report — assemble and stream the redacted .tar.gz.
97
+ app.post('/v1/debug-report', async (c) => {
98
+ let body = {};
99
+ try {
100
+ body = await c.req.json();
101
+ }
102
+ catch {
103
+ // Empty / missing body is allowed — the screenshot is optional.
104
+ }
105
+ const screenshotPng = decodeScreenshot(body['screenshotPngBase64']);
106
+ let status;
107
+ try {
108
+ status = await gatherStatusForApi(config.store, undefined);
109
+ }
110
+ catch (err) {
111
+ status = {
112
+ error: 'status_gather_failed',
113
+ message: err instanceof Error ? err.message : String(err),
114
+ };
115
+ }
116
+ let configProvenance;
117
+ try {
118
+ configProvenance = buildConfigProvenance(config.configPath, config.config);
119
+ }
120
+ catch (err) {
121
+ configProvenance = {
122
+ error: 'provenance_failed',
123
+ message: err instanceof Error ? err.message : String(err),
124
+ };
125
+ }
126
+ let activityEvents;
127
+ try {
128
+ activityEvents = config.store.getRecentActivityEvents(ACTIVITY_EVENT_LIMIT);
129
+ }
130
+ catch (err) {
131
+ activityEvents = {
132
+ error: 'activity_events_failed',
133
+ message: err instanceof Error ? err.message : String(err),
134
+ };
135
+ }
136
+ const generatedAt = new Date().toISOString();
137
+ const bundle = await assembleDebugReport({
138
+ status,
139
+ config: config.config,
140
+ configProvenance,
141
+ activityEvents,
142
+ logFiles: await readLogFiles(),
143
+ daemonVersion: buildInfo.implVersion,
144
+ screenshotPng,
145
+ generatedAt,
146
+ });
147
+ const filename = `jinn-debug-report-${generatedAt.slice(0, 10)}.tar.gz`;
148
+ return new Response(new Uint8Array(bundle), {
149
+ headers: {
150
+ 'content-type': 'application/gzip',
151
+ 'content-disposition': `attachment; filename="${filename}"`,
152
+ 'content-length': String(bundle.length),
153
+ },
154
+ });
155
+ });
156
+ }
157
+ //# sourceMappingURL=debug-report-endpoint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug-report-endpoint.js","sourceRoot":"","sources":["../../src/api/debug-report-endpoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EACL,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAEvE,kEAAkE;AAClE,MAAM,oBAAoB,GAAG,IAAI,CAAC;AAUlC,kEAAkE;AAClE,SAAS,gBAAgB,CAAC,KAAc;IACtC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACtE,4EAA4E;IAC5E,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,0BAA0B,EAAE,EAAE,CAAC,CAAC;IAC/D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC5C,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,2EAA2E;AAC3E,SAAS,YAAY;IACnB,IAAI,CAAC;QACH,OAAO,aAAa,EAAE,CAAC,YAAY,EAAE,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,YAAY;IACzB,MAAM,GAAG,GAA6C,EAAE,CAAC;IACzD,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpE,CAAC;QAAC,MAAM,CAAC;YACP,oEAAoE;QACtE,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,GAAS,EAAE,MAA+B;IAC7E,uEAAuE;IACvE,GAAG,CAAC,GAAG,CAAC,2BAA2B,EAAE,CAAC,CAAC,EAAE,EAAE;QACzC,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAClE,OAAO,CAAC,CAAC,IAAI,CAAC;YACZ,KAAK,EAAE,CAAC,GAAG,kBAAkB,EAAE,GAAG,QAAQ,EAAE,0BAA0B,CAAC;YACvE,SAAS,EAAE;gBACT,OAAO,EAAE,iBAAiB;gBAC1B,QAAQ,EAAE;oBACR,mCAAmC;oBACnC,0CAA0C;oBAC1C,2CAA2C;oBAC3C,6BAA6B;oBAC7B,6BAA6B;iBAC9B;gBACD,IAAI,EAAE;oBACJ,oCAAoC;oBACpC,mEAAmE;oBACnE,mCAAmC;oBACnC,YAAY;iBACb;gBACD,WAAW,EAAE;oBACX,iEAAiE;0BAC7D,gEAAgE;0BAChE,uCAAuC;iBAC5C;aACF;SACF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,oEAAoE;IACpE,GAAG,CAAC,IAAI,CAAC,kBAAkB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACvC,IAAI,IAAI,GAA4B,EAAE,CAAC;QACvC,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAA2B,CAAC;QACrD,CAAC;QAAC,MAAM,CAAC;YACP,gEAAgE;QAClE,CAAC;QAED,MAAM,aAAa,GAAG,gBAAgB,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;QAEpE,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,kBAAkB,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG;gBACP,KAAK,EAAE,sBAAsB;gBAC7B,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aAC1D,CAAC;QACJ,CAAC;QAED,IAAI,gBAAyB,CAAC;QAC9B,IAAI,CAAC;YACH,gBAAgB,GAAG,qBAAqB,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAC7E,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,gBAAgB,GAAG;gBACjB,KAAK,EAAE,mBAAmB;gBAC1B,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aAC1D,CAAC;QACJ,CAAC;QAED,IAAI,cAAuB,CAAC;QAC5B,IAAI,CAAC;YACH,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC,oBAAoB,CAAC,CAAC;QAC9E,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,cAAc,GAAG;gBACf,KAAK,EAAE,wBAAwB;gBAC/B,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aAC1D,CAAC;QACJ,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC7C,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC;YACvC,MAAM;YACN,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,gBAAgB;YAChB,cAAc;YACd,QAAQ,EAAE,MAAM,YAAY,EAAE;YAC9B,aAAa,EAAE,SAAS,CAAC,WAAW;YACpC,aAAa;YACb,WAAW;SACZ,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,qBAAqB,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC;QACxE,OAAO,IAAI,QAAQ,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE;YAC1C,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,qBAAqB,EAAE,yBAAyB,QAAQ,GAAG;gBAC3D,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;aACxC;SACF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -3,7 +3,12 @@
3
3
  */
4
4
  import type { Store } from '../store/store.js';
5
5
  import type { JinnConfig } from '../config.js';
6
+ import type { CredentialId } from '../spend/credential.js';
7
+ import type { AiUnitsDaemonConfig } from '../spend/ai-units-config.js';
6
8
  import { type GatheredStatusRaw, type StatusV1Response } from './status-build.js';
9
+ import type { HarnessReadinessSnapshot, JoinedHarnessSpec } from '../harnesses/readiness-registry.js';
10
+ /** Test-only: clear the first-seen-evicted tracker. Do not call from production code. */
11
+ export declare function __resetEvictionFirstSeenForTests(): void;
7
12
  /**
8
13
  * Drop any cached prediction operator status for `config`.
9
14
  *
@@ -30,6 +35,14 @@ export interface StatusGatherConfig {
30
35
  tjinnChainId?: number;
31
36
  /** JinnDistributor address used for real operator lifetime claimed totals. */
32
37
  tjinnDistributorAddress?: string;
38
+ /**
39
+ * stOLAS L2 distributor address (`CHAIN_CONFIG.distributorAddress`). Used
40
+ * solely to mirror `main.ts`'s `evictionCheck` predicate (issue #651). The
41
+ * tJINN distributor on L1 is a different contract — do not substitute one
42
+ * for the other even though they happen to bundle together in our current
43
+ * testnet deployment.
44
+ */
45
+ stOlasDistributorAddress?: string;
33
46
  network: 'mainnet' | 'testnet';
34
47
  pollIntervalMs: number;
35
48
  masterEthDailyEstimateWei?: string;
@@ -46,6 +59,26 @@ export interface StatusGatherConfig {
46
59
  /** Full config enables SolverNet/plugin/Harness diagnostics in /v1/status. */
47
60
  config?: JinnConfig;
48
61
  configPath?: string;
62
+ /** Per-credential daily caps; when present, /v1/status carries a `spend` block. */
63
+ spendCaps?: Record<CredentialId, number>;
64
+ /**
65
+ * AI-units gate config (issue #815). When present, /v1/status carries an
66
+ * `aiUnits` block keyed per credential — surfaces unitsThisBlock /
67
+ * unitsThisWeek vs caps + paused flag + reset instants.
68
+ */
69
+ aiUnits?: AiUnitsDaemonConfig;
70
+ /**
71
+ * Optional getter that returns the live HarnessReadinessRegistry snapshot
72
+ * + joinedHarnessesByCid map. Threaded by `server.ts` for the `/v1/status`
73
+ * handler so the response carries a `harness` rollup. Returning `null`
74
+ * means "registry not ready yet" — gather-status leaves `raw.harnessRollup`
75
+ * unset and the assembler defaults to ready. Mirrors the holder pattern
76
+ * already used for `harnessReadinessRegistry` in main.ts.
77
+ */
78
+ harnessReadiness?: () => {
79
+ snapshot: HarnessReadinessSnapshot;
80
+ joinedHarnessesByCid: Record<string, JoinedHarnessSpec>;
81
+ } | null;
49
82
  }
50
83
  /** Collect status inputs without assembling the legacy mega-response. */
51
84
  export declare function gatherGatheredStatusRaw(store: Store, status: StatusGatherConfig | undefined): Promise<GatheredStatusRaw>;