@manyoars/oars 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (320) hide show
  1. package/README.md +147 -28
  2. package/dist/api.js +1 -1
  3. package/dist/bin.js +6 -29
  4. package/dist/cli.d.ts +10 -4
  5. package/dist/cli.js +440 -91
  6. package/dist/commands/keys.d.ts +31 -0
  7. package/dist/commands/keys.js +65 -0
  8. package/dist/commands/login.d.ts +1 -1
  9. package/dist/commands/login.js +3 -3
  10. package/dist/errors.d.ts +13 -13
  11. package/dist/errors.js +28 -11
  12. package/dist/gate/checks.d.ts +68 -0
  13. package/dist/gate/checks.js +584 -0
  14. package/dist/gate/command.d.ts +14 -0
  15. package/dist/gate/command.js +61 -0
  16. package/dist/gate/hook-fill-main.d.ts +1 -0
  17. package/dist/gate/hook-fill-main.js +16 -0
  18. package/dist/gate/hook-fill.d.ts +38 -0
  19. package/dist/gate/hook-fill.js +94 -0
  20. package/dist/gate/hook-main.d.ts +1 -0
  21. package/dist/gate/hook-main.js +47 -0
  22. package/dist/gate/hook-process.d.ts +24 -0
  23. package/dist/gate/hook-process.js +112 -0
  24. package/dist/gate/hook-record.d.ts +3 -0
  25. package/dist/gate/hook-record.js +8 -0
  26. package/dist/gate/hook.d.ts +48 -0
  27. package/dist/gate/hook.js +259 -0
  28. package/dist/gate/install.d.ts +25 -0
  29. package/dist/gate/install.js +126 -0
  30. package/dist/gate/local-bin.d.ts +8 -0
  31. package/dist/gate/local-bin.js +36 -0
  32. package/dist/gate/notes.d.ts +19 -0
  33. package/dist/gate/notes.js +27 -0
  34. package/dist/gate/novelty.d.ts +35 -0
  35. package/dist/gate/novelty.js +99 -0
  36. package/dist/gate/policy.d.ts +25 -0
  37. package/dist/gate/policy.js +73 -0
  38. package/dist/gate/record.d.ts +120 -0
  39. package/dist/gate/record.js +125 -0
  40. package/dist/gate/registry-state.d.ts +10 -0
  41. package/dist/gate/registry-state.js +30 -0
  42. package/dist/gate/registry.d.ts +56 -0
  43. package/dist/gate/registry.js +94 -0
  44. package/dist/gate/replay.d.ts +20 -0
  45. package/dist/gate/replay.js +254 -0
  46. package/dist/gate/report.d.ts +50 -0
  47. package/dist/gate/report.js +89 -0
  48. package/dist/gate/scope.d.ts +7 -0
  49. package/dist/gate/scope.js +27 -0
  50. package/dist/gate/transcripts.d.ts +68 -0
  51. package/dist/gate/transcripts.js +232 -0
  52. package/dist/hook-bin.d.ts +1 -0
  53. package/dist/hook-bin.js +50 -0
  54. package/dist/issuer.d.ts +10 -6
  55. package/dist/issuer.js +19 -24
  56. package/dist/main.d.ts +1 -0
  57. package/dist/main.js +67 -0
  58. package/dist/oidc.js +1 -1
  59. package/dist/sessions/actions.d.ts +35 -0
  60. package/dist/sessions/actions.js +429 -0
  61. package/dist/sessions/allow.d.ts +23 -0
  62. package/dist/sessions/allow.js +71 -0
  63. package/dist/sessions/archive.d.ts +11 -0
  64. package/dist/sessions/archive.js +38 -0
  65. package/dist/sessions/audit.d.ts +42 -0
  66. package/dist/sessions/audit.js +104 -0
  67. package/dist/sessions/baseline.d.ts +62 -0
  68. package/dist/sessions/baseline.js +190 -0
  69. package/dist/sessions/call-shape.d.ts +19 -0
  70. package/dist/sessions/call-shape.js +85 -0
  71. package/dist/sessions/capture-runtime.d.ts +10 -0
  72. package/dist/sessions/capture-runtime.js +12 -0
  73. package/dist/sessions/cell-increments.d.ts +47 -0
  74. package/dist/sessions/cell-increments.js +243 -0
  75. package/dist/sessions/cells.d.ts +109 -0
  76. package/dist/sessions/cells.js +261 -0
  77. package/dist/sessions/codex.d.ts +53 -0
  78. package/dist/sessions/codex.js +745 -0
  79. package/dist/sessions/command.d.ts +127 -0
  80. package/dist/sessions/command.js +419 -0
  81. package/dist/sessions/copilot.d.ts +40 -0
  82. package/dist/sessions/copilot.js +432 -0
  83. package/dist/sessions/coverage.d.ts +19 -0
  84. package/dist/sessions/coverage.js +56 -0
  85. package/dist/sessions/cursor.d.ts +24 -0
  86. package/dist/sessions/cursor.js +324 -0
  87. package/dist/sessions/derive.d.ts +57 -0
  88. package/dist/sessions/derive.js +386 -0
  89. package/dist/sessions/exclusion.d.ts +87 -0
  90. package/dist/sessions/exclusion.js +361 -0
  91. package/dist/sessions/extract.d.ts +181 -0
  92. package/dist/sessions/extract.js +1806 -0
  93. package/dist/sessions/fold.d.ts +17 -0
  94. package/dist/sessions/fold.js +71 -0
  95. package/dist/sessions/frame.d.ts +24 -0
  96. package/dist/sessions/frame.js +95 -0
  97. package/dist/sessions/gemini.d.ts +37 -0
  98. package/dist/sessions/gemini.js +613 -0
  99. package/dist/sessions/gold-arms.d.ts +67 -0
  100. package/dist/sessions/gold-arms.js +172 -0
  101. package/dist/sessions/gold.d.ts +197 -0
  102. package/dist/sessions/gold.js +463 -0
  103. package/dist/sessions/graph.d.ts +12 -0
  104. package/dist/sessions/graph.js +34 -0
  105. package/dist/sessions/grok.d.ts +36 -0
  106. package/dist/sessions/grok.js +421 -0
  107. package/dist/sessions/hook-calls.d.ts +3 -0
  108. package/dist/sessions/hook-calls.js +47 -0
  109. package/dist/sessions/hook-index.d.ts +66 -0
  110. package/dist/sessions/hook-index.js +164 -0
  111. package/dist/sessions/hooks.d.ts +17 -0
  112. package/dist/sessions/hooks.js +281 -0
  113. package/dist/sessions/identity.d.ts +27 -0
  114. package/dist/sessions/identity.js +131 -0
  115. package/dist/sessions/install.d.ts +70 -0
  116. package/dist/sessions/install.js +246 -0
  117. package/dist/sessions/lineage.d.ts +19 -0
  118. package/dist/sessions/lineage.js +118 -0
  119. package/dist/sessions/mcp.d.ts +7 -0
  120. package/dist/sessions/mcp.js +157 -0
  121. package/dist/sessions/merkle.d.ts +7 -0
  122. package/dist/sessions/merkle.js +28 -0
  123. package/dist/sessions/motif.d.ts +44 -0
  124. package/dist/sessions/motif.js +59 -0
  125. package/dist/sessions/opencode.d.ts +33 -0
  126. package/dist/sessions/opencode.js +319 -0
  127. package/dist/sessions/otel.d.ts +60 -0
  128. package/dist/sessions/otel.js +494 -0
  129. package/dist/sessions/package-books.d.ts +48 -0
  130. package/dist/sessions/package-books.js +120 -0
  131. package/dist/sessions/package-resolve.d.ts +32 -0
  132. package/dist/sessions/package-resolve.js +185 -0
  133. package/dist/sessions/pending.d.ts +34 -0
  134. package/dist/sessions/pending.js +142 -0
  135. package/dist/sessions/pi.d.ts +36 -0
  136. package/dist/sessions/pi.js +353 -0
  137. package/dist/sessions/pool-books.d.ts +21 -0
  138. package/dist/sessions/pool-books.js +75 -0
  139. package/dist/sessions/pool-choices.d.ts +5 -0
  140. package/dist/sessions/pool-choices.js +11 -0
  141. package/dist/sessions/pool-command.d.ts +115 -0
  142. package/dist/sessions/pool-command.js +669 -0
  143. package/dist/sessions/pool-delta.d.ts +54 -0
  144. package/dist/sessions/pool-delta.js +190 -0
  145. package/dist/sessions/pool-nightly-deps.d.ts +3 -0
  146. package/dist/sessions/pool-nightly-deps.js +11 -0
  147. package/dist/sessions/pool-nightly.d.ts +10 -0
  148. package/dist/sessions/pool-nightly.js +85 -0
  149. package/dist/sessions/pool-outbox.d.ts +76 -0
  150. package/dist/sessions/pool-outbox.js +313 -0
  151. package/dist/sessions/pool-print.d.ts +26 -0
  152. package/dist/sessions/pool-print.js +68 -0
  153. package/dist/sessions/pool-raw.d.ts +27 -0
  154. package/dist/sessions/pool-raw.js +68 -0
  155. package/dist/sessions/pool-replica.d.ts +35 -0
  156. package/dist/sessions/pool-replica.js +91 -0
  157. package/dist/sessions/pool-send-lock.d.ts +20 -0
  158. package/dist/sessions/pool-send-lock.js +87 -0
  159. package/dist/sessions/pool-sent.d.ts +4 -0
  160. package/dist/sessions/pool-sent.js +26 -0
  161. package/dist/sessions/pool-totals.d.ts +10 -0
  162. package/dist/sessions/pool-totals.js +21 -0
  163. package/dist/sessions/pool-wire.d.ts +435 -0
  164. package/dist/sessions/pool-wire.js +1100 -0
  165. package/dist/sessions/pool.d.ts +32 -0
  166. package/dist/sessions/pool.js +164 -0
  167. package/dist/sessions/projection.d.ts +75 -0
  168. package/dist/sessions/projection.js +165 -0
  169. package/dist/sessions/public-vocabulary.d.ts +72 -0
  170. package/dist/sessions/public-vocabulary.js +295 -0
  171. package/dist/sessions/query.d.ts +123 -0
  172. package/dist/sessions/query.js +268 -0
  173. package/dist/sessions/read-adoption.d.ts +2 -0
  174. package/dist/sessions/read-adoption.js +27 -0
  175. package/dist/sessions/read-call-shape.d.ts +2 -0
  176. package/dist/sessions/read-call-shape.js +25 -0
  177. package/dist/sessions/read-change.d.ts +2 -0
  178. package/dist/sessions/read-change.js +30 -0
  179. package/dist/sessions/read-cost.d.ts +4 -0
  180. package/dist/sessions/read-cost.js +48 -0
  181. package/dist/sessions/read-day-move.d.ts +3 -0
  182. package/dist/sessions/read-day-move.js +65 -0
  183. package/dist/sessions/read-fit.d.ts +7 -0
  184. package/dist/sessions/read-fit.js +41 -0
  185. package/dist/sessions/read-interaction.d.ts +5 -0
  186. package/dist/sessions/read-interaction.js +62 -0
  187. package/dist/sessions/read-lead-lag.d.ts +15 -0
  188. package/dist/sessions/read-lead-lag.js +81 -0
  189. package/dist/sessions/read-live.d.ts +6 -0
  190. package/dist/sessions/read-live.js +38 -0
  191. package/dist/sessions/read-method.d.ts +2 -0
  192. package/dist/sessions/read-method.js +29 -0
  193. package/dist/sessions/read-next-step.d.ts +2 -0
  194. package/dist/sessions/read-next-step.js +35 -0
  195. package/dist/sessions/read-order.d.ts +54 -0
  196. package/dist/sessions/read-order.js +62 -0
  197. package/dist/sessions/read-readable.d.ts +8 -0
  198. package/dist/sessions/read-readable.js +24 -0
  199. package/dist/sessions/read-recovery-edge.d.ts +2 -0
  200. package/dist/sessions/read-recovery-edge.js +26 -0
  201. package/dist/sessions/read-recovery.d.ts +20 -0
  202. package/dist/sessions/read-recovery.js +97 -0
  203. package/dist/sessions/read-rows.d.ts +13 -0
  204. package/dist/sessions/read-rows.js +47 -0
  205. package/dist/sessions/read-substitution.d.ts +5 -0
  206. package/dist/sessions/read-substitution.js +51 -0
  207. package/dist/sessions/read-support.d.ts +48 -0
  208. package/dist/sessions/read-support.js +73 -0
  209. package/dist/sessions/read-tool-day.d.ts +2 -0
  210. package/dist/sessions/read-tool-day.js +26 -0
  211. package/dist/sessions/read-version-boundary.d.ts +31 -0
  212. package/dist/sessions/read-version-boundary.js +95 -0
  213. package/dist/sessions/read.d.ts +86 -0
  214. package/dist/sessions/read.js +87 -0
  215. package/dist/sessions/recall-bundle.d.ts +12 -0
  216. package/dist/sessions/recall-bundle.js +33 -0
  217. package/dist/sessions/recall-consequence.d.ts +45 -0
  218. package/dist/sessions/recall-consequence.js +179 -0
  219. package/dist/sessions/recall-frames.d.ts +18 -0
  220. package/dist/sessions/recall-frames.js +44 -0
  221. package/dist/sessions/recall-next.d.ts +145 -0
  222. package/dist/sessions/recall-next.js +241 -0
  223. package/dist/sessions/recall-object.d.ts +139 -0
  224. package/dist/sessions/recall-object.js +78 -0
  225. package/dist/sessions/recall-pool.d.ts +19 -0
  226. package/dist/sessions/recall-pool.js +96 -0
  227. package/dist/sessions/recall-push.d.ts +26 -0
  228. package/dist/sessions/recall-push.js +47 -0
  229. package/dist/sessions/recall-reads.d.ts +124 -0
  230. package/dist/sessions/recall-reads.js +417 -0
  231. package/dist/sessions/recall-render.d.ts +19 -0
  232. package/dist/sessions/recall-render.js +168 -0
  233. package/dist/sessions/recovery-calls.d.ts +21 -0
  234. package/dist/sessions/recovery-calls.js +25 -0
  235. package/dist/sessions/redact.d.ts +17 -0
  236. package/dist/sessions/redact.js +113 -0
  237. package/dist/sessions/repo-root.d.ts +10 -0
  238. package/dist/sessions/repo-root.js +101 -0
  239. package/dist/sessions/schema.d.ts +694 -0
  240. package/dist/sessions/schema.js +167 -0
  241. package/dist/sessions/session-shape.d.ts +76 -0
  242. package/dist/sessions/session-shape.js +355 -0
  243. package/dist/sessions/sources.d.ts +50 -0
  244. package/dist/sessions/sources.js +233 -0
  245. package/dist/sessions/steps.d.ts +105 -0
  246. package/dist/sessions/steps.js +250 -0
  247. package/dist/sessions/store.d.ts +309 -0
  248. package/dist/sessions/store.js +1498 -0
  249. package/dist/sessions/strata.d.ts +26 -0
  250. package/dist/sessions/strata.js +77 -0
  251. package/dist/sessions/survival.d.ts +27 -0
  252. package/dist/sessions/survival.js +230 -0
  253. package/dist/sessions/transcript-tail.d.ts +14 -0
  254. package/dist/sessions/transcript-tail.js +64 -0
  255. package/dist/sessions/verify.d.ts +53 -0
  256. package/dist/sessions/verify.js +286 -0
  257. package/dist/sessions/vocab-load.d.ts +26 -0
  258. package/dist/sessions/vocab-load.js +61 -0
  259. package/dist/sessions/vscode-copilot.d.ts +38 -0
  260. package/dist/sessions/vscode-copilot.js +494 -0
  261. package/dist/telemetry/command.d.ts +8 -0
  262. package/dist/telemetry/command.js +85 -0
  263. package/dist/telemetry/consent.d.ts +17 -0
  264. package/dist/telemetry/consent.js +63 -0
  265. package/dist/telemetry/crash.d.ts +8 -0
  266. package/dist/telemetry/crash.js +52 -0
  267. package/dist/telemetry/emit.d.ts +31 -0
  268. package/dist/telemetry/emit.js +42 -0
  269. package/dist/telemetry/fields.d.ts +16 -0
  270. package/dist/telemetry/fields.js +26 -0
  271. package/dist/telemetry/health.d.ts +21 -0
  272. package/dist/telemetry/health.js +108 -0
  273. package/dist/telemetry/hook-emit.d.ts +4 -0
  274. package/dist/telemetry/hook-emit.js +18 -0
  275. package/dist/telemetry/measures.d.ts +32 -0
  276. package/dist/telemetry/measures.js +128 -0
  277. package/dist/telemetry/observe.d.ts +13 -0
  278. package/dist/telemetry/observe.js +51 -0
  279. package/dist/telemetry/read-events.d.ts +9 -0
  280. package/dist/telemetry/read-events.js +17 -0
  281. package/dist/telemetry/record.d.ts +17 -0
  282. package/dist/telemetry/record.js +26 -0
  283. package/dist/telemetry/report.d.ts +77 -0
  284. package/dist/telemetry/report.js +188 -0
  285. package/dist/telemetry/schema.d.ts +40 -0
  286. package/dist/telemetry/schema.js +187 -0
  287. package/dist/telemetry/send-main.d.ts +1 -0
  288. package/dist/telemetry/send-main.js +11 -0
  289. package/dist/telemetry/send.d.ts +36 -0
  290. package/dist/telemetry/send.js +172 -0
  291. package/dist/telemetry/spool.d.ts +17 -0
  292. package/dist/telemetry/spool.js +70 -0
  293. package/dist/telemetry/wire.d.ts +25 -0
  294. package/dist/telemetry/wire.js +76 -0
  295. package/package.json +4 -5
  296. package/vocab/crates.json +1 -0
  297. package/vocab/go.json +1 -0
  298. package/vocab/harness.json +1 -0
  299. package/vocab/homebrew.json +1 -0
  300. package/vocab/manifest.json +1 -0
  301. package/vocab/maven.json +1 -0
  302. package/vocab/models.json +1 -0
  303. package/vocab/npm.json +1 -0
  304. package/vocab/programs.json +1 -0
  305. package/vocab/pypi.json +1 -0
  306. package/vocab/rubygems.json +1 -0
  307. package/dist/commands/deploy-input.d.ts +0 -38
  308. package/dist/commands/deploy-input.js +0 -150
  309. package/dist/commands/deploy.d.ts +0 -22
  310. package/dist/commands/deploy.js +0 -124
  311. package/dist/commands/status.d.ts +0 -7
  312. package/dist/commands/status.js +0 -18
  313. package/dist/commands/templates.d.ts +0 -11
  314. package/dist/commands/templates.js +0 -32
  315. package/dist/commands/test-charge.d.ts +0 -11
  316. package/dist/commands/test-charge.js +0 -34
  317. package/dist/journal.d.ts +0 -26
  318. package/dist/journal.js +0 -58
  319. package/parity/deploy-plans/paid-api.json +0 -34
  320. package/parity/deploy-plans/per-task-agent.json +0 -34
package/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # @manyoars/oars
2
2
 
3
- The `oars` command line for Many Oars: sign in, deploy an agent, set its prices and make a test charge against it.
3
+ The `oars` command line for Many Oars: sign in, manage API keys, and keep a local memory of your own coding-agent sessions (`oars sessions`).
4
+
5
+ Accounts are not open yet: `oars login` uses the Many Oars issuer by default, and until Many Oars sign-in at `login.manyoars.com` (and its pool at `pool.manyoars.com`) is deployed it exits 2 with an error that names `login.manyoars.com`.
4
6
 
5
7
  Node 24 or later. ESM only.
6
8
 
@@ -25,53 +27,171 @@ These flags work on every command:
25
27
 
26
28
  - `--json` prints one JSON document on stdout instead of text (see below).
27
29
  - `--api-url <url>` sets the platform API. The default is `OARS_API_URL`, else `https://api.manyoars.com`.
28
- - `--idempotency-key <key>` is the base of every step's idempotency key (default: a fresh UUID). Rerun a failed command with the same key to resume.
30
+ - `--idempotency-key <key>` is the base of the idempotency key (default: a fresh UUID). Rerun a failed command with the same key to replay it.
29
31
 
30
32
  ### login
31
33
 
32
34
  Signs in with your browser (RFC 8628 device flow) and stores the login.
33
35
 
34
36
  - `--no-browser` prints the link and code without opening a browser.
35
- - `--issuer-url <url>` is the Keycloak realm URL. The default is `OARS_ISSUER_URL`. With neither, `login` uses the built-in Many Oars issuer once Many Oars has launched, which it learns from `https://manyoars.com/.well-known/oars.json` (`{"launched": true}`). The flag only switches the built-in issuer on; it never supplies a URL. Before launch, with no `--issuer-url` or `OARS_ISSUER_URL`, the command prints "Many Oars has not launched yet: pass --issuer-url or set OARS_ISSUER_URL." and exits 2.
37
+ - `--issuer-url <url>` is the Keycloak realm URL. The default is `OARS_ISSUER_URL`. With neither, `login` uses the built-in Many Oars issuer, `https://login.manyoars.com/realms/aor`; nothing has to be switched on first. When the built-in issuer does not answer discovery (Many Oars and its pool at `pool.manyoars.com` may not be deployed yet), with no `--issuer-url` or `OARS_ISSUER_URL`, the command prints "Cannot reach Many Oars sign-in at login.manyoars.com (Many Oars and its pool at pool.manyoars.com may not be deployed yet). Pass --issuer-url or set OARS_ISSUER_URL to use another issuer." and exits 2.
36
38
 
37
39
  ### logout
38
40
 
39
41
  Revokes the stored login and deletes it.
40
42
 
41
- ### templates
43
+ ### keys
44
+
45
+ `oars keys` manages the API keys of your account.
46
+
47
+ - `oars keys create --name <name>` creates a key and prints its secret once; the platform keeps no copy. The default authorities are `AGENT_OPERATE` and `AGENT_READ`; `--authority <name>` (repeatable) sets others, and `--expires-in-days <n>` sets an expiry. `--expires-in-days` takes 1 to 365; without it the platform sets the expiry, and `oars keys list` shows it. Replace a key before it expires.
48
+ - `--workload <id>` limits the key to one workload you created. Such a key may carry only `AGENT_OPERATE` and `AGENT_READ` (more is a 400, `API_KEY_WORKLOAD_SCOPE_EXCEEDS_CAP`), and it works on that workload only.
49
+ - A retry with the same `--idempotency-key` returns no secret: the command exits 5 and names the key, and you revoke it and create another.
50
+ - Creating or revoking a key needs a signed-in person. With `OARS_API_KEY` set, any API key gets 403 `HUMAN_SESSION_REQUIRED` (exit 3) and logging in again does not help: unset it and use the `oars login` session.
51
+ - `oars keys list` lists the keys with their prefix, scope, and expiry. A secret never comes back.
52
+ - `oars keys revoke <keyId>` ends a key at once. There is no `rotate`: revoke the key and create another.
53
+
54
+ ### telemetry
55
+
56
+ oars records how it is used, on this machine, and says so: on the first run that is not a hook it prints a notice on stderr, once. Each command leaves an event in a local spool under `<config>/oars/telemetry/`: the command path, the names of the flags given (never their values), the duration, the exit code, a closed error class, the oars version, the OS, and the time. So does each fire of a hook (the bare `oars gate hook` included, written after its answer is printed: which hook, how long, hit, miss, held, or error, and the bytes it printed), each recall (how it was asked and which read families it served, as counts), each deposit pass or sent batch (sessions counted, batches, bytes, and how many sessions each gate kept out, never which), and each fetch (an ETag hit, a cap hit). Five more kinds of event are recorded, each only counts, sizes, and closed words: once a night, a `store-health` snapshot of the session store and a `run-cost` event (time and peak memory); a `crash` event when oars fails in a way it did not plan for (the error's class and a hash of its stack, never its message); and, for each `oars pool deposit` pass, one `wire` event per harness (which fields its batches held and how many bytes each took) and, with `--send`, a `wire-send` event (the HTTP status, the pool's refusal code, and the size). Nothing else is recorded: no session content, prompt text, file path, URL, or argument. Every field of every event, with an example, is in [docs/telemetry.md](https://github.com/manyoars/oars/blob/main/docs/telemetry.md). oars sends the events in batches to the pool server in `OARS_POOL_URL` if you set one, else to the Many Oars pool (`https://pool.manyoars.com`), which is not deployed yet: until it is, a send fails and the events stay in the spool. A per-install random id (not derived from your machine or account) is in each event.
57
+
58
+ - `oars telemetry status` says whether it is on, which switch decided that, whether the notice was shown, and how large the spool is.
59
+ - `oars telemetry off` stops recording and sending; `oars telemetry on` resumes it and prints the notice again.
60
+ - `oars telemetry show` prints the spool exactly as stored, oldest first.
61
+ - `oars telemetry report` prints your own numbers from the spool (hook latency percentiles, hit rates, and store health over the last 7 and 30 days) with no server and no account, and the fleet's percentile beside each when `OARS_POOL_URL` names a server that serves it.
62
+ - `OARS_TELEMETRY=0` or `DO_NOT_TRACK=1` turns it off for the process, and wins over `oars telemetry on`.
42
63
 
43
- `oars templates` lists the starter templates `oars deploy --template` takes: each id, name, description, and starter prices. Needs a login.
64
+ Every event type, with an example, is in [docs/telemetry.md](https://github.com/manyoars/oars/blob/main/docs/telemetry.md).
44
65
 
45
- ### deploy
66
+ ### sessions
46
67
 
47
- Registers a workload, creates its prices, and deploys it. Pass exactly one of `--template`, `--image`, or `--manifest`. It stops at the first failed step and exits 9 (see below). A `--template` id the catalog lacks exits 2, and an unreachable catalog exits 8, before anything is registered.
68
+ `oars sessions` keeps a local, deterministic memory of your own coding-agent sessions. The session commands make no model call and no network call, except `gold arms`, which sends redacted text through your own Claude subscription. oars also records telemetry events (a command's path, its flag names, how long it took, its exit code, and its error class, with a random install id, the oars version, the OS, and the time; never session content, prompts, paths, URLs, or argument values), which oars sends in batches to the pool server in `OARS_POOL_URL`, else to the Many Oars pool (not deployed yet, so a send fails and the spool is kept) ([what telemetry records and how to turn it off](https://github.com/manyoars/oars/blob/main/docs/telemetry.md)).
48
69
 
49
- - `--image <ref>` deploys an image pinned by digest (`name@sha256:...`). Companions: `--name <name>`, `--port <n>` (default 8080), `--public`, `--cpu-millicores <n>` (default 250), `--memory-mib <n>` (default 256).
50
- - `--manifest <file>` deploys a JSON workload manifest.
51
- - `--always-on` keeps the public service running instead of idling. It works with every source.
52
- - `--template <id>` deploys a starter template from the catalog (`oars templates`): it registers the entry's manifest, creates every starter price, then deploys. `--price <ref>` (repeatable) creates only the named ones; `--no-prices` creates none. `--name`, `--port`, `--public`, `--cpu-millicores`, `--memory-mib`, and `--price-file` do not combine with it.
53
- - `--price-file <file>` is a JSON array of prices to create (with `--image` or `--manifest`).
54
- - `--secret <NAME=value>` and `--secret-from-env <NAME>` add a workload secret; both repeat. Prefer `--secret-from-env`, which keeps the value out of your shell history.
55
- - `--no-start` registers and prices the workload without deploying it.
70
+ What it captures: by default, the sessions of every Claude Code project folder and the sessions of Cursor, Codex, Copilot CLI, Gemini CLI, Grok Build, OpenCode, Pi, and VS Code Copilot Chat, plus OpenTelemetry GenAI agent traces (OTLP JSON files) from the folder `OARS_OTEL_TRACES` names (else `<config>/oars/otel-traces`), when there is one. `--allow` narrows that to the folders and stores you name (`--allow cursor`, `codex`, `copilot`, `gemini`, `grok`, `opencode`, `pi`, `vscode-copilot`, `otel` name the stores), and `--deny` keeps one out. Where it stores them: `<config>/oars/sessions/` on your machine (`<config>` is `%APPDATA%` on Windows, `$XDG_CONFIG_HOME` or `~/.config` elsewhere). The `raw/` folder in it is on by default and holds raw transcripts (a hard link or copy of each deposited one). Secret masking applies to the log, not to `raw/`: those files are unredacted and keep whatever the transcript held, secrets included. They stay on your machine: apart from `gold arms`, no session command uploads them, telemetry carries nothing from them, and after a yes to the raw prompt (`oars pool raw`) and covenant acceptance, the nightly task uploads a redacted copy of each (never the file itself), except from a folder set to skeleton only or off. To remove them, see [Remove everything](#remove-everything).
56
71
 
57
- The SDK key is shown once, so save it when `deploy` prints it.
72
+ Apart from that and telemetry (on by default, off with `oars telemetry off`, `OARS_TELEMETRY=0`, or `DO_NOT_TRACK=1`; it sends to the pool server in `OARS_POOL_URL`, else to the Many Oars pool at `pool.manyoars.com`, which is not deployed yet, so until it is a send fails and the events stay in the spool), oars itself sends nothing, except what you opted into with a pool server: after you accept its covenant, the nightly task (registered on Windows only) sends closed-vocabulary session skeletons, and, only after a separate yes to the raw prompt, a locally redacted (best-effort) copy of each full transcript; `oars pool outbox` prints what is queued when you run it, but the nightly task builds new batches and sends them in the same run without printing them first, and a folder can be switched to skeleton only or off; the hooks and the MCP tool add recall text to the running session, and your harness sends that to its model like any other context.
58
73
 
59
- ### status
74
+ ```bash
75
+ # Read every folder; or only the ones you name (a path, or its name under ~/.claude/projects); --deny keeps one out.
76
+ oars sessions deposit --redact-domain corp.example
77
+ oars sessions deposit --allow ~/work/app --allow ~/work/tools --deny ~/work/tools/secret
78
+
79
+ # Look up an error as printed, a file, or a prompt class.
80
+ oars sessions recall --error "unexpected EOF while looking for matching \`''"
81
+ oars sessions recall --path src/main.ts --since 30 # sees the first 100 sorted paths of a session
82
+ oars sessions recall --family recovery --class edit-verify --since 30 # a read family; only recovery and fit take --class and --since
83
+ oars sessions recall --entity Monitor # what is known about a public name: a package, a tool, an MCP server, an action, or a model
84
+ oars sessions recall --text "wrong input" # look for text in the local record (counts all time)
85
+ oars sessions recall --pattern <readId> --pattern <readId> # what happened from here, from the read IDs of your steps so far (repeatable; counts all time)
86
+ oars sessions recall --error "..." --session <id> # name the asking session, so what it did next can be read for this recall
87
+
88
+ # Serve the same query to a running agent as one MCP tool, oars_recall (stdio):
89
+ oars sessions recall --mcp
90
+
91
+ oars sessions recall --counts --day 2026-11-03 # push and pull, shown and held, as counts
92
+ oars sessions lineage <recallId or readId> # walk back through the evidence, one line per hop
93
+ oars sessions read # derived reads of your own sessions, largest sample first in each family, with what the store cannot read
94
+ oars sessions read --family version-boundary # order 2: what moved between two harness version buckets; also substitution, interaction, and day-move
95
+ oars sessions read --family lead-lag # order 3: a labeled experiment behind an out-of-time check
96
+ oars sessions read --family fit --slice model=claude-opus-5-5 --json
97
+ oars sessions books --by class --since 30 # tokens, wall time, turns, errors, verify-after-edit rate, and the outcome signals
98
+ oars sessions books --by pull # the same per package, MCP server, plugin, or skill a prompt pulled
99
+ oars sessions books --by harness # the same, grouped by Claude Code, Cursor, Codex, Copilot, Gemini, Grok Build, OpenCode, Pi, and VS Code Copilot Chat (deposit the others with --allow cursor, --allow codex, --allow copilot, --allow gemini, --allow grok, --allow opencode, --allow pi, --allow vscode-copilot, or --allow otel)
100
+ oars sessions measure --last 50 # recurring errors per 100 sessions, cache-write per session, recall calls per session
101
+ oars sessions measure --last 50 --repo <root> # the same, for one repository's sessions
102
+ oars sessions verify # consistency invariants on the stored skeletons and capture records
103
+ oars sessions exclusions # list sessions excluded by the local term file (counts only; OARS_EXCLUSION_TERMS names the file)
104
+ oars sessions gold sample # about 200 prompts to judge blind; needs the term file (`OARS_EXCLUSION_TERMS`), and `--exclude-term <text>` adds to it; `gold arms <file>` adds the claim and fresh readers on your Claude subscription; `gold score <file>` reads each arm against the judgments
105
+ ```
106
+
107
+ `deposit` is idempotent (a file is skipped only when its size, mtime, capture version, salt, and `--redact-domain` set are all unchanged; a store written by an older capture version is captured again from the harness's transcript or from `raw/`, and one written by a newer oars is refused) and appends to `<config>/oars/sessions/observations.jsonl`:
108
+ one record per session, user prompt, tool call, and failed tool result, where each tool call also holds its steps in a canonical action vocabulary and each prompt a frame (harness, model, day, and public stack names); signatures, prompt classes, and recovery episodes are derived
109
+ from that log alone, so a change to a derivation rule never re-reads a transcript. The store format, every field with its class, the two version stamps, and the raw archive are in [`docs/sessions-store.md`](https://github.com/manyoars/oars/blob/main/docs/sessions-store.md);
110
+ the types are in `src/sessions/schema.ts`. Secrets (by pattern and entropy), emails, and the domains you name are masked
111
+ before a line is written (redaction runs on the full text, then the text is cut); lines written before a domain was added stay in the append-only file until it is compacted, and readers use only the latest version of each session. The log is the local derived-records tier: redacted
112
+ text, never raw content. It keeps these text fields and no others: the first 300 characters of each prompt, the first informative line of a
113
+ tool error (cut to 1,000 characters in the error-line record, 160 characters in a derived example), TLDR lines (400) and Confidence lines (120) from assistant text, WebSearch queries, fetched URLs, file
114
+ paths, and git branch names (the last four have no length limit), all redacted first; plus the project folder slug (not redacted, so it
115
+ carries your username and directory names; the log stays local), skill names, effort values, model names, harness versions, tool names (including MCP server names), a shell call's program and subcommand, and tool-input key names. A tool call's file target is a salted hash, never the path. Apart from `gold arms`, no `oars sessions` command uploads anything, and telemetry carries none of these fields; `oars pool` and the nightly task send skeletons that carry some of these names after redaction (skill, effort, model, harness version, tool, and MCP server names, a shell call's program, subcommand, and flag names, tool-input key names, a pulled package's name (and its version only when a public list holds it), and a web host (sent as it is after redaction; the pool hashes it on arrival), each after redaction; see `docs/pool.md`, "Wire field register").
116
+ Subagent transcripts (`<project>/<session>/subagents/`) are deposited with their parent session and subagent type; `books --by class`
117
+ shows their tokens as the `delegated` column, and their errors are in the signatures, `measure`, and recall under the session that
118
+ spawned them, so per-session counts still count main sessions. Every deposited transcript is also
119
+ hard-linked (copied across volumes) into `<config>/oars/sessions/raw/`, so it outlives the harness's own cleanup. For each session it also writes a skeleton (ids, timestamps, tool linkage, token counts, a SHA-256 in place of every content
120
+ field, and a Merkle root over the raw lines) that `verify` checks; the skeleton holds hashes only, never content.
121
+ `verify` exits 0 even when an invariant has exceptions; add `--strict` to exit 4 instead. `verify` also reports every session on its own (`--json`: `sessionResults`, each session's ten rows with a status of `pass`, `fail`, or `not run`) and audits each session against its raw file (`audit`): the raw-file match for a hard link and for a copy (a copy of a different size counts as possible tampering), the Merkle root recomputed over the first `leaves` lines, and the count bindings (`leaves`, `session.lines`, and the skeleton's lines plus `badLines` must agree). Each session lands on one of five results: `root matches and the counts bind`, `changed since deposit`, `root mismatch`, `counts do not bind`, or `not run` (no raw file, no skeleton, no capture record, or a raw file that cannot be read). `root mismatch` and `counts do not bind` fail `--strict`; sessions under 10 `leaves` are flagged. `verify` also scores each session against the operator's own other weeks on its harness (`--json`: `selfBaseline`, layer 2 at T0, local): the session's UTC week is the week of its `tsFirst`; a baseline is that harness's other weeks with at least 1,000 tool calls that ended by now, combined by calls; the result is `F` from the median distance over seven histograms (a dimension with no counts on a side is dropped). It is `not run`, scoring nothing, for a null `tsFirst`, a week under 1,000 calls, or fewer than 4 baseline weeks. A low `F` lowers a weight and rejects nothing. `verify` also names the project folders that hold transcripts but are not on the saved allowlist, so are never read (`--json`: `scope`, with `folders`, `transcripts`, and `names`); it is scope, not a failure, and never fails `--strict`. `books` prints the same line. `measure` prints the recurring-error count
122
+ per hundred sessions and, on a second line, the distinct recurring signatures in the window.
123
+ #### Many folders: `--allow` prefixes, globs, and `--allow-file`
124
+
125
+ An `--allow` entry is a folder (or its slug), a folder prefix with a trailing slash (`~/work/` reads that folder and every project under it), or a glob (`*` any run of characters, `?` one character, matched against the project-folder name Claude Code derives from the path). `--allow-file <list>` reads entries from a file, one per line (blank lines and `#` comments skipped), so hundreds of folders need no batching and no long command line. A leading `~` is expanded to your home folder, in a list file or quoted entry too. Both repeat and combine. With neither, a deposit reads every folder. `--deny <entry>` (or `!<entry>` in a list file) keeps the folders it names out, in any of those forms; it is saved, and it wins over every `--allow` until that exact entry is named with `--allow` again. Naming it again lifts the denial and nothing else when the saved list names no folder (every folder stays in scope); when the saved list names folders, the entry joins them. Entries a deposit saves are what the SessionEnd hook, the nightly task, `oars pool deposit`, and `oars gate replay` reuse; with none saved, they read every folder. An `--allow-file` that names nothing is refused.
126
+
127
+ #### Recall in a running session: hooks
128
+
129
+ `oars sessions hook install` writes five entries into one Claude Code settings file. Each is a deterministic, local, fail-open call into the store (no model, no network); an error inside a hook exits 0 with no output, so a hook never blocks or fails a session.
130
+
131
+ | Event | Does | Timeout written at install |
132
+ |---|---|---|
133
+ | `SessionStart` | injects `oars sessions recall --context` for the session's cwd as additional context: the top 5 errors by sessions within the latest 300 sessions of the repository (the `measure --last 300 --repo` window) and what usually followed. Then, when any position qualifies, a table of the positions where earlier sessions split on the next step (a leading step at 20 to 80 percent of at least 20 observations; names and counts only, at most 600 bytes), from the kept pool bundle for the session's harness and version first and this store's pool second (the local half is derived over that harness and version bucket only, or over the harness's versions when the transcript states none). The table is one `recalls.jsonl` row and falls under the 10 percent holdback | under 500 ms |
134
+ | `UserPromptSubmit` | the same table again, only when it differs from the one this session was last sent (shown or held), so an unchanged table costs a prompt nothing (the check reads the last 64 KB of the recall log, shared by every session, so in a long or parallel session the last table row can fall out of the window and an unchanged table is sent again) | under 500 ms |
135
+ | `PreToolUse` (no matcher: every tool) | the gate hook's role: it fires after the call is decided, so it is a warning and does not claim to move the next step. For a call whose tool and input key names match a shape that fails at least half its calls (of at least 20 calls in at least 3 sessions), and at least twice as often as its action does, injects its counts as additional context, once per session and shape (the check reads the last 64 KB of the recall log, about 44 rows, so a very long session can be told again, and the arm redraws when the nightly index moves), and records the recall. 10 percent of those sessions and shapes are held back: a held arm records what it would have shown and injects nothing. Starts node per call | under 500 ms |
136
+ | `PostToolUseFailure` (matcher: every tool the action table maps, and `mcp__.*`) | the recovery edge: for a failed call it reads what followed this failure (same action and error class) in the kept pool bundle, else in this store, and adds "after a failed X (code), the next step was Y xN". It stays silent when the top next step is the failed action again (a retry), when a local edge has fewer than 5 followed steps, and when nothing followed. A call the cells do not cover keeps the older line, "seen in N sessions; what followed: X", under the same holdback, silent on a strict retry lead. Every served or held line is a `recalls.jsonl` row; 10 percent of sessions are held. For Bash and PowerShell a shell pre-filter in the registered command reads the event first and starts node only when it carries `Exit code` | pre-filter: shell builtins only, no node start; whole path under 1 s |
137
+ | `SessionEnd` | deposits that one transcript (idempotent by size and mtime), only from a folder the saved allowlist holds (every folder until a deposit names some, less any `--deny`). Once per session: `Stop` fires after every turn and would append a new revision of the growing transcript each time. A session the harness ends without `SessionEnd` is picked up by the nightly deposit | under 5 s |
138
+
139
+ Claude Code fires `PostToolUse` on success only; a failed Bash call arrives as `PostToolUseFailure`, so that is the event registered. The pre-filter is a `read`, a `case`, and a `printf | node` in the shell the harness runs hooks in (Git Bash on Windows), so it needs no `findstr` and no extra dependency. Writers of the store (`SessionEnd`, the nightly run, `deposit`) take `store.lock`, so parallel sessions cannot lose each other's `state.json` entries; a lock older than ten minutes is broken.
140
+
141
+ ```bash
142
+ # The default is the user settings file; --scope project or --file names another.
143
+ oars sessions hook install # ~/.claude/settings.json (or $CLAUDE_CONFIG_DIR)
144
+ oars sessions hook install --scope file --file ./.claude/settings.local.json
145
+ oars sessions hook install --scope project # ./.claude/settings.json
146
+ oars sessions hook install --file my-settings.json --keep-retention
147
+ oars sessions hook status # user, project, and the nightly task
148
+ oars sessions hook uninstall --scope user # removes only the entries install wrote
149
+ ```
150
+
151
+ Install merges: existing hooks (a Stop hook that rotates sessions, say) stay, even inside a group that also holds ours or under a name that contains `hook-bin`; re-running replaces only its own entries (the commands ending `hook-bin.js" <session-start|post-tool|stop>`), and a per-turn `Stop` entry of ours from the first build is removed. A settings file that exists but cannot be read is an error that changes nothing. The harness deletes raw transcripts after `cleanupPeriodDays` (30 when unset), which would erase what `deposit` reads, so install raises it to at least 365 in the file it writes, prints the old and new value, and never lowers a higher one. `--keep-retention` leaves it alone and says so. Uninstall does not touch `cleanupPeriodDays`. For a `claude --settings <file>` launch, install into that file with `--scope file`.
152
+
153
+ #### Nightly schedule (Windows)
154
+
155
+ On Windows, `oars sessions hook install` registers the Task Scheduler task `OarsSessionsNightly` (daily, 03:00) unless it is already there; `--schedule nightly` registers it by itself, with no settings file. The task runs the full deposit over the saved `--allow` and `--redact-domain` entries and refreshes the recurrence index the hooks read. `--schedule off` removes it and records the choice in the store (`<config>/oars/sessions/schedule.json`), so a later plain install leaves it off until `--schedule nightly` registers it again and clears the record; `hook status` shows whether it is registered. A machine that refuses the task still gets the hooks, and the install says how to retry. Alone, `--schedule` writes no settings file.
156
+
157
+ #### Reading `measure` before and after
158
+
159
+ `measure` has no cutoff, so its windows move with every deposit. To pin an "after" reading, run `oars sessions measure --last 300 --since <iso time of the install>` (add `--repo <root>` to window one repository's sessions): the current window is the first 300 sessions started at or after that time and the prior window is the 300 before it. Without `--since` the window is the last N. `measure` also prints hook recall calls per session and hook hits per session, and hook deposits per session, counted from `hook-calls.jsonl` in the store.
160
+
161
+ #### Remove everything
162
+
163
+ `oars sessions hook uninstall --scope user` (or the scope you installed); `oars sessions hook install --schedule off`; delete the store folder `<config>/oars/sessions/` (observations, skeletons, state, the hook index, `hook-calls.jsonl`, and `raw/`, which holds the unredacted transcripts). `gold sample` also writes its prompt file and sidecar to `~/.claude/session-commons/review/` (or `$CLAUDE_CONFIG_DIR/session-commons/review/`, or your `--out-dir`); delete those too. oars also writes `<config>/oars/telemetry/` (the telemetry spool and install id; delete it too) and, after `oars login`, `<config>/oars/credentials.json` (`oars logout` deletes it). `cleanupPeriodDays` stays at the value install set unless you change it.
164
+
165
+ ### Gate: what your agents picked
166
+
167
+ ```
168
+ oars gate replay # find installs, fetch-and-runs, MCP servers, and skills in logs on disk, and ask npm or pip what the registry holds
169
+ oars gate replay --no-registry-state # the same, without asking the registry
170
+ oars gate report # counts over crossings.jsonl, by who recorded each, and what replay cannot see
171
+ oars gate install # add the hook to Claude Code at user scope, so crossings are recorded as they happen
172
+ oars gate uninstall # remove only that hook entry
173
+ oars gate policy # print the policy in force (warn, block, or off per class)
174
+ ```
60
175
 
61
- `oars status <workloadId>` shows a workload and its billing mode.
176
+ Replay is local and read-only on your transcripts; it writes `crossings.jsonl` and the novelty index `gate-index.txt` into the sessions store and nothing else (npm and pip also keep their own caches, unless `--no-registry-state`). The hook (`oars gate hook`, run by Claude Code, not by you) appends to `crossings.jsonl` as each crossing happens, plus `gate-index.txt`, `gate-registry.jsonl`, and the empty `gate-ask-*.lock` files in the same store (a registry ask the hook had to cut is finished by a helper process that ends on its own timeouts, and the package manager keeps its own cache outside the store), and always exits 0. With no policy file it adds a note about a name first published in the last 30 days or an npm name the registry does not hold; `gate-policy.json` changes that per class, and a block needs `block` written by you. A block is a labeled deny, and a crossing goes nowhere unless you opt in (no opt-in exists yet). `report` reads only `crossings.jsonl`. Both record picks and neither judges them; a note or label states a fact about the registry and nothing else. See `docs/gate.md` in the repository.
62
177
 
63
- ### test-charge
178
+ ### pool
64
179
 
65
- `oars test-charge <workloadId>` makes a TEST-mode charge against one of the workload's prices.
180
+ `oars pool` uses the Many Oars pool, `https://pool.manyoars.com`, which is not deployed yet (a request to it fails with exit 8), or a pool server you name with `--server <url>` or `OARS_POOL_URL`. Every other command works without it.
66
181
 
67
- - `--price <ref>` picks the price. The default is the workload's only active price.
182
+ - `oars pool login --provider github|google` signs in by the provider's device flow, run here, and prints every request before it sends it. `OARS_GITHUB_CLIENT_ID` (or `OARS_GOOGLE_CLIENT_ID` and `OARS_GOOGLE_CLIENT_SECRET`) must be set; an unset one stops the command before anything is sent and names the variable.
183
+ - `oars pool deposit` writes a batch of session skeletons (a closed list of fields, each value redacted first; a host is hashed by the pool on arrival) to an outbox for each session that passes your folder allowlist and the exclusion check, and stops: it sends nothing itself. `--send <hash>` sends one batch that `outbox` printed and that is unchanged on disk, once this account has accepted the pool covenant (`--accept-covenant <version>`, or an earlier acceptance); before that it reads the covenant, sends no batch, and exits 3 with `covenant_not_accepted`. A hash that was never shown, or a batch that changed, is refused before any request. The nightly task is the other sender: after the pool says your account accepted its covenant, it sends new batches, and raw copies only if you said yes to the raw prompt (`oars pool raw --consent yes`). With no sign-in, no acceptance, or an unreachable server it sends nothing.
184
+ - `deposit`, `outbox`, and `fetch` need `oars pool login` first; without it they exit 3 and name the server.
185
+ - `oars pool coverage [--org-size <band>] [--repo-visibility public|private|unknown]` sets the two coverage bands only you can state, read locally and never from the network; an unset band goes on the wire as `unknown`.
186
+ - `oars pool outbox` prints each batch exactly as it would be sent, with its SHA-256, and `--explain` adds each field's rule.
187
+ - `oars pool fetch --harness-version <version>` fetches that version's signed bundle, verifies it against the key pinned at login, and keeps it locally. It prints the public and disclosure floors the bundle states (and any read family on a floor of its own) and holds no floor of its own: the pool sets them, so a change is a deploy and never a new release of oars.
68
188
 
69
189
  ## The `--json` contract
70
190
 
71
191
  With `--json`, stdout carries exactly one JSON document and a success exits 0.
72
192
 
73
- - Success: `{"ok": true, ...}`. The rest depends on the command: `login` adds `email`; `deploy` adds `workloadId`, `prices`, `started`, `nextSteps` and, when this run minted it, `sdkKey`; `templates` adds `templates`; `status` adds `workload` and `billingMode`; `test-charge` adds `chargeId` and `status`.
74
- - Failure: `{"ok": false, "step": "...", "problem": {...}}`, where `problem` is the platform's problem document (`title`, `detail`, `code`, `actionUrl` when it sent them). A `deploy` that stopped after registering also carries `workloadId`, `rerun` and, if that run minted it, `sdkKey`.
193
+ - Success: `{"ok": true, ...}`. The rest depends on the command: `login` adds `email`; `keys create` adds `key` and `secret`, `keys list` adds `keys`, and `keys revoke` adds `keyId` and `revoked`; `sessions` commands add their own fields (`deposit` the counts, `recall` `matches`, `books` `rows`, `measure` `last` and `before`, `verify` `sessions`, `unreadable`, `invariants`, `sessionResults`, and `audit`).
194
+ - Failure: `{"ok": false, "step": "...", "problem": {...}}`, where `problem` is the platform's problem document (`title`, `detail`, `code`, `actionUrl` when it sent them).
75
195
 
76
196
  Without `--json`, a failure prints the problem to stderr instead.
77
197
 
@@ -82,13 +202,12 @@ Exit codes:
82
202
  | 0 | success |
83
203
  | 1 | unexpected error |
84
204
  | 2 | usage error |
85
- | 3 | authentication failed (login expired or denied, SDK key invalid, HTTP 401 or 403) |
86
- | 4 | the platform rejected the input |
87
- | 5 | conflict (an idempotency key or workload already used) |
88
- | 6 | a person must act first (account, payment method, credits, or compute cap); the last stderr line starts "Needs you:" and names the link |
205
+ | 3 | authentication failed (login expired or denied, HTTP 401 or 403) |
206
+ | 4 | the platform rejected the input, or `sessions verify --strict` found exceptions |
207
+ | 5 | conflict (an idempotency key already used) |
89
208
  | 7 | rate limited |
90
- | 8 | the platform could not be reached |
91
- | 9 | `deploy` stopped part way; rerun the printed command to resume |
209
+ | 8 | the server could not be reached (the platform, the issuer, or a pool server) |
210
+ | 10 | `pool fetch` hit the pool's weekly fetch cap; the bundle on disk is untouched, and the message says when to try again |
92
211
 
93
212
  ## Source
94
213
 
package/dist/api.js CHANGED
@@ -18,7 +18,7 @@ export const apiClient = (deps, options) => {
18
18
  return await send(request);
19
19
  }
20
20
  catch (error) {
21
- throw unreachableError(options.step, error);
21
+ throw unreachableError(options.step, error, options.apiUrl);
22
22
  }
23
23
  },
24
24
  });
package/dist/bin.js CHANGED
@@ -1,30 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { readFileSync } from 'node:fs';
3
- import { homedir } from 'node:os';
4
- import { setTimeout as sleep } from 'node:timers/promises';
5
- import { openBrowser } from './browser.js';
6
- import { run } from './cli.js';
7
- import { defaultConfigDir, fileCredentialStore } from './credentials.js';
8
- import { fileJournalStore } from './journal.js';
9
- /** The version in this package's package.json (one folder up from dist/). */
10
- const readVersion = () => {
11
- const manifest = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
12
- const version = typeof manifest === 'object' && manifest !== null ? Reflect.get(manifest, 'version') : undefined;
13
- return typeof version === 'string' ? version : '0.0.0';
14
- };
15
- const configDir = defaultConfigDir(process.env, process.platform, homedir());
16
- // exitCode rather than process.exit(), so a piped stdout is flushed before the process ends.
17
- process.exitCode = await run(process.argv.slice(2), {
18
- env: process.env,
19
- io: {
20
- stdout: (text) => process.stdout.write(text),
21
- stderr: (text) => process.stderr.write(text),
22
- },
23
- store: fileCredentialStore(configDir),
24
- journal: fileJournalStore(configDir),
25
- version: readVersion(),
26
- sleep: (ms) => sleep(ms),
27
- random: Math.random,
28
- now: Date.now,
29
- openBrowser,
30
- });
2
+ // The `oars` executable. It decides which program to load before loading any: `oars gate hook` is run by the harness before every matching tool call and has under a
3
+ // second to finish, so it must not pay for the whole CLI (its command tree, its sign-in, its HTTP client) just to start. Everything else loads `main.js`, as before.
4
+ // Only the bare command: with an argument (`--help`) the full CLI answers, so its description shows.
5
+ const hook = process.argv.length === 4 && process.argv[2] === 'gate' && process.argv[3] === 'hook';
6
+ await (hook ? import('./gate/hook-main.js') : import('./main.js'));
7
+ export {};
package/dist/cli.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import type { CredentialStore } from './credentials.js';
2
2
  import { ExitCode } from './errors.js';
3
- import type { JournalStore } from './journal.js';
3
+ import type { InstallRuntime } from './sessions/install.js';
4
+ import type { SessionsRuntime } from './sessions/store.js';
5
+ import type { TelemetryRuntime } from './telemetry/record.js';
4
6
  /** Everything the CLI takes from its process, so the tests can stand in for each. */
5
7
  export interface RunDeps {
6
8
  env: NodeJS.ProcessEnv;
@@ -9,8 +11,6 @@ export interface RunDeps {
9
11
  stderr: (text: string) => void;
10
12
  };
11
13
  store: CredentialStore;
12
- /** Where `deploy` keeps its progress between a failed run and the rerun. */
13
- journal: JournalStore;
14
14
  /** Sent as `User-Agent: oars/<version>` and printed by `--version`. */
15
15
  version: string;
16
16
  sleep: (ms: number) => Promise<void>;
@@ -19,11 +19,17 @@ export interface RunDeps {
19
19
  /** Epoch milliseconds. */
20
20
  now: () => number;
21
21
  openBrowser: (url: string) => Promise<void>;
22
+ /** Where `oars sessions` keeps its store and finds the operator's Claude Code logs; absent in a run that has none. */
23
+ sessions?: SessionsRuntime;
24
+ /** Where `oars sessions hook` finds the hook script, the settings files, and schtasks; absent in a run that has none. */
25
+ install?: InstallRuntime;
26
+ /** Where telemetry keeps its id, settings, and spool; absent in a run that has none, which records nothing. */
27
+ telemetry?: TelemetryRuntime | undefined;
22
28
  }
23
29
  /** What a command produced: the `--json` document, and the line a human sees instead. */
24
30
  export interface Outcome {
25
31
  document: object;
26
32
  text: string;
27
33
  }
28
- /** Runs one invocation (`argv` without the node and script entries) and returns the exit code. */
34
+ /** Runs one invocation (`argv` without the node and script entries) and returns the exit code. Telemetry records it afterward and cannot change it. */
29
35
  export declare const run: (argv: string[], deps: RunDeps) => Promise<ExitCode>;