riffer-rig 0.11.0 → 0.13.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 (313) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +140 -0
  3. data/README.md +102 -39
  4. data/lib/riffer/rig/acp/host.rb +126 -0
  5. data/lib/riffer/rig/acp/mapper.rb +242 -0
  6. data/lib/riffer/rig/acp.rb +356 -0
  7. data/lib/riffer/rig/bundled/bash.rb +5 -1
  8. data/lib/riffer/rig/bundled/mcp.rb +6 -1
  9. data/lib/riffer/rig/cli/flags.rb +75 -22
  10. data/lib/riffer/rig/cli/sessions.rb +147 -0
  11. data/lib/riffer/rig/cli.rb +34 -82
  12. data/lib/riffer/rig/command/context.rb +1 -1
  13. data/lib/riffer/rig/command.rb +4 -2
  14. data/lib/riffer/rig/commands/auth.rb +23 -23
  15. data/lib/riffer/rig/commands/cost.rb +59 -0
  16. data/lib/riffer/rig/commands/model.rb +24 -18
  17. data/lib/riffer/rig/commands/reload.rb +1 -1
  18. data/lib/riffer/rig/commands/skill.rb +1 -1
  19. data/lib/riffer/rig/commands/trace/replay.rb +88 -0
  20. data/lib/riffer/rig/commands/trace.rb +25 -0
  21. data/lib/riffer/rig/credentials/provider_fields.rb +47 -0
  22. data/lib/riffer/rig/credentials.rb +94 -48
  23. data/lib/riffer/rig/env.rb +1 -1
  24. data/lib/riffer/rig/events/after_response.rb +4 -11
  25. data/lib/riffer/rig/events/after_tool_call.rb +15 -13
  26. data/lib/riffer/rig/events/before_prompt.rb +4 -11
  27. data/lib/riffer/rig/events/before_request.rb +4 -11
  28. data/lib/riffer/rig/events/before_tool_call.rb +12 -13
  29. data/lib/riffer/rig/events/command_output.rb +4 -11
  30. data/lib/riffer/rig/events/job_exit.rb +28 -0
  31. data/lib/riffer/rig/events/notify.rb +4 -11
  32. data/lib/riffer/rig/events/session_end.rb +4 -11
  33. data/lib/riffer/rig/events/session_start.rb +4 -11
  34. data/lib/riffer/rig/events/skill_activated.rb +4 -11
  35. data/lib/riffer/rig/events/turn_end.rb +4 -11
  36. data/lib/riffer/rig/extension.rb +5 -4
  37. data/lib/riffer/rig/headless/host.rb +11 -15
  38. data/lib/riffer/rig/headless/ndjson.rb +49 -0
  39. data/lib/riffer/rig/headless.rb +140 -31
  40. data/lib/riffer/rig/hosts/mirror.rb +8 -5
  41. data/lib/riffer/rig/hosts/non_interactive.rb +24 -0
  42. data/lib/riffer/rig/hosts/null.rb +2 -21
  43. data/lib/riffer/rig/loader/credentials.rb +23 -0
  44. data/lib/riffer/rig/loader/extension_source.rb +177 -0
  45. data/lib/riffer/rig/loader/options.rb +35 -0
  46. data/lib/riffer/rig/loader.rb +118 -322
  47. data/lib/riffer/rig/mcp/auth.rb +61 -0
  48. data/lib/riffer/rig/mcp/declaration.rb +29 -5
  49. data/lib/riffer/rig/provider_setup.rb +2 -2
  50. data/lib/riffer/rig/providers.rb +5 -0
  51. data/lib/riffer/rig/registrar.rb +12 -4
  52. data/lib/riffer/rig/runtime/abort.rb +66 -0
  53. data/lib/riffer/rig/runtime/concurrency.rb +71 -0
  54. data/lib/riffer/rig/runtime/error_message.rb +27 -0
  55. data/lib/riffer/rig/runtime/hooks.rb +6 -2
  56. data/lib/riffer/rig/runtime/job_completion.rb +31 -0
  57. data/lib/riffer/rig/runtime/job_envelope.rb +36 -0
  58. data/lib/riffer/rig/runtime/job_inbox.rb +74 -0
  59. data/lib/riffer/rig/runtime/job_notification.rb +31 -0
  60. data/lib/riffer/rig/runtime/mcp_registrar.rb +91 -0
  61. data/lib/riffer/rig/runtime/request_guardrail.rb +1 -1
  62. data/lib/riffer/rig/runtime/snapshot.rb +80 -0
  63. data/lib/riffer/rig/runtime/system_prompt.rb +56 -0
  64. data/lib/riffer/rig/runtime/tool_runtime.rb +47 -7
  65. data/lib/riffer/rig/runtime/usage.rb +19 -0
  66. data/lib/riffer/rig/runtime.rb +333 -213
  67. data/lib/riffer/rig/sdk.rb +29 -7
  68. data/lib/riffer/rig/settings/file.rb +27 -0
  69. data/lib/riffer/rig/settings/model_options.rb +64 -0
  70. data/lib/riffer/rig/settings.rb +0 -129
  71. data/lib/riffer/rig/stores/entries.rb +23 -0
  72. data/lib/riffer/rig/stores/header.rb +3 -17
  73. data/lib/riffer/rig/stores/jsonl.rb +7 -6
  74. data/lib/riffer/rig/stores/message_entry.rb +10 -10
  75. data/lib/riffer/rig/stores/model_entry.rb +10 -10
  76. data/lib/riffer/rig/stores/recorder.rb +34 -13
  77. data/lib/riffer/rig/stores/skill_entry.rb +10 -10
  78. data/lib/riffer/rig/stores/stamped.rb +9 -0
  79. data/lib/riffer/rig/stores/timestamp.rb +23 -0
  80. data/lib/riffer/rig/support/json_file.rb +53 -0
  81. data/lib/riffer/rig/support/typed_value/schema.rb +16 -0
  82. data/lib/riffer/rig/support/typed_value.rb +17 -0
  83. data/lib/riffer/rig/terminal/autocomplete.rb +133 -0
  84. data/lib/riffer/rig/terminal/banner.rb +48 -11
  85. data/lib/riffer/rig/terminal/blocking_prompter.rb +37 -0
  86. data/lib/riffer/rig/terminal/builtin.rb +16 -0
  87. data/lib/riffer/rig/terminal/columns.rb +63 -0
  88. data/lib/riffer/rig/terminal/console.rb +49 -0
  89. data/lib/riffer/rig/terminal/echo.rb +26 -0
  90. data/lib/riffer/rig/terminal/equalizer.rb +20 -0
  91. data/lib/riffer/rig/terminal/frame.rb +339 -0
  92. data/lib/riffer/rig/terminal/frame_prompter.rb +63 -0
  93. data/lib/riffer/rig/terminal/help.rb +41 -0
  94. data/lib/riffer/rig/terminal/host.rb +7 -28
  95. data/lib/riffer/rig/terminal/job_counter.rb +33 -0
  96. data/lib/riffer/rig/terminal/job_exit_notice.rb +11 -0
  97. data/lib/riffer/rig/terminal/key.rb +38 -0
  98. data/lib/riffer/rig/terminal/key_decoder.rb +219 -0
  99. data/lib/riffer/rig/terminal/key_pipeline.rb +111 -0
  100. data/lib/riffer/rig/terminal/line_editor.rb +183 -0
  101. data/lib/riffer/rig/terminal/markdown/blocks.rb +96 -0
  102. data/lib/riffer/rig/terminal/markdown/flow.rb +77 -0
  103. data/lib/riffer/rig/terminal/markdown/inline.rb +85 -0
  104. data/lib/riffer/rig/terminal/markdown/span.rb +25 -0
  105. data/lib/riffer/rig/terminal/markdown/table.rb +166 -0
  106. data/lib/riffer/rig/terminal/markdown.rb +187 -0
  107. data/lib/riffer/rig/terminal/message_queue/message.rb +13 -0
  108. data/lib/riffer/rig/terminal/message_queue.rb +27 -0
  109. data/lib/riffer/rig/terminal/opening.rb +50 -0
  110. data/lib/riffer/rig/terminal/peek.rb +74 -0
  111. data/lib/riffer/rig/terminal/picker.rb +169 -0
  112. data/lib/riffer/rig/terminal/question.rb +37 -0
  113. data/lib/riffer/rig/terminal/quiet_display.rb +48 -0
  114. data/lib/riffer/rig/terminal/renderer.rb +19 -250
  115. data/lib/riffer/rig/terminal/repl.rb +242 -0
  116. data/lib/riffer/rig/terminal/replay/turn.rb +23 -0
  117. data/lib/riffer/rig/terminal/replay.rb +76 -0
  118. data/lib/riffer/rig/terminal/session.rb +29 -0
  119. data/lib/riffer/rig/terminal/tally.rb +12 -0
  120. data/lib/riffer/rig/terminal/theme.rb +34 -1
  121. data/lib/riffer/rig/terminal/ticker.rb +189 -0
  122. data/lib/riffer/rig/terminal/ticker_display.rb +91 -0
  123. data/lib/riffer/rig/terminal/turn_buffer/stats.rb +19 -0
  124. data/lib/riffer/rig/terminal/turn_buffer.rb +133 -0
  125. data/lib/riffer/rig/terminal/turn_report.rb +100 -0
  126. data/lib/riffer/rig/terminal/wrapper.rb +46 -62
  127. data/lib/riffer/rig/terminal.rb +277 -93
  128. data/lib/riffer/rig/tools/bash/capture.rb +58 -0
  129. data/lib/riffer/rig/tools/bash/job.rb +84 -0
  130. data/lib/riffer/rig/tools/bash/job_log.rb +117 -0
  131. data/lib/riffer/rig/tools/bash/jobs.rb +197 -0
  132. data/lib/riffer/rig/tools/bash/kill.rb +24 -0
  133. data/lib/riffer/rig/tools/bash/kill_group.rb +15 -0
  134. data/lib/riffer/rig/tools/bash/monotonic_clock.rb +8 -0
  135. data/lib/riffer/rig/tools/bash/output.rb +30 -0
  136. data/lib/riffer/rig/tools/bash/truncation.rb +12 -0
  137. data/lib/riffer/rig/tools/bash.rb +42 -29
  138. data/lib/riffer/rig/tools/read.rb +2 -2
  139. data/lib/riffer/rig/trust.rb +9 -18
  140. data/lib/riffer/rig/version.rb +1 -1
  141. data/lib/riffer/rig.rb +1 -1
  142. data/sig/generated/riffer/rig/acp/host.rbs +74 -0
  143. data/sig/generated/riffer/rig/acp/mapper.rbs +108 -0
  144. data/sig/generated/riffer/rig/acp.rbs +162 -0
  145. data/sig/generated/riffer/rig/cli/flags.rbs +24 -4
  146. data/sig/generated/riffer/rig/cli/sessions.rbs +86 -0
  147. data/sig/generated/riffer/rig/cli.rbs +7 -32
  148. data/sig/generated/riffer/rig/command.rbs +5 -3
  149. data/sig/generated/riffer/rig/commands/auth.rbs +3 -7
  150. data/sig/generated/riffer/rig/commands/cost.rbs +31 -0
  151. data/sig/generated/riffer/rig/commands/model.rbs +2 -0
  152. data/sig/generated/riffer/rig/commands/trace/replay.rbs +53 -0
  153. data/sig/generated/riffer/rig/commands/trace.rbs +14 -0
  154. data/sig/generated/riffer/rig/credentials/provider_fields.rbs +26 -0
  155. data/sig/generated/riffer/rig/credentials.rbs +36 -15
  156. data/sig/generated/riffer/rig/events/after_response.rbs +3 -7
  157. data/sig/generated/riffer/rig/events/after_tool_call.rbs +14 -9
  158. data/sig/generated/riffer/rig/events/before_prompt.rbs +3 -7
  159. data/sig/generated/riffer/rig/events/before_request.rbs +3 -7
  160. data/sig/generated/riffer/rig/events/before_tool_call.rbs +11 -9
  161. data/sig/generated/riffer/rig/events/command_output.rbs +3 -7
  162. data/sig/generated/riffer/rig/events/job_exit.rbs +24 -0
  163. data/sig/generated/riffer/rig/events/notify.rbs +3 -7
  164. data/sig/generated/riffer/rig/events/session_end.rbs +3 -7
  165. data/sig/generated/riffer/rig/events/session_start.rbs +3 -7
  166. data/sig/generated/riffer/rig/events/skill_activated.rbs +3 -7
  167. data/sig/generated/riffer/rig/events/turn_end.rbs +3 -7
  168. data/sig/generated/riffer/rig/extension.rbs +3 -3
  169. data/sig/generated/riffer/rig/headless/host.rbs +6 -11
  170. data/sig/generated/riffer/rig/headless/ndjson.rbs +27 -0
  171. data/sig/generated/riffer/rig/headless.rbs +49 -9
  172. data/sig/generated/riffer/rig/hosts/mirror.rbs +7 -6
  173. data/sig/generated/riffer/rig/hosts/non_interactive.rbs +18 -0
  174. data/sig/generated/riffer/rig/hosts/null.rbs +2 -15
  175. data/sig/generated/riffer/rig/loader/credentials.rbs +12 -0
  176. data/sig/generated/riffer/rig/loader/extension_source.rbs +89 -0
  177. data/sig/generated/riffer/rig/loader/options.rbs +25 -0
  178. data/sig/generated/riffer/rig/loader.rbs +39 -132
  179. data/sig/generated/riffer/rig/mcp/auth.rbs +32 -0
  180. data/sig/generated/riffer/rig/mcp/declaration.rbs +23 -4
  181. data/sig/generated/riffer/rig/provider_setup.rbs +1 -1
  182. data/sig/generated/riffer/rig/providers.rbs +3 -0
  183. data/sig/generated/riffer/rig/registrar.rbs +6 -2
  184. data/sig/generated/riffer/rig/runtime/abort.rbs +36 -0
  185. data/sig/generated/riffer/rig/runtime/concurrency.rbs +41 -0
  186. data/sig/generated/riffer/rig/runtime/error_message.rbs +13 -0
  187. data/sig/generated/riffer/rig/runtime/hooks.rbs +3 -1
  188. data/sig/generated/riffer/rig/runtime/job_completion.rbs +28 -0
  189. data/sig/generated/riffer/rig/runtime/job_envelope.rbs +17 -0
  190. data/sig/generated/riffer/rig/runtime/job_inbox.rbs +40 -0
  191. data/sig/generated/riffer/rig/runtime/job_notification.rbs +22 -0
  192. data/sig/generated/riffer/rig/runtime/mcp_registrar.rbs +46 -0
  193. data/sig/generated/riffer/rig/runtime/snapshot.rbs +42 -0
  194. data/sig/generated/riffer/rig/runtime/system_prompt.rbs +37 -0
  195. data/sig/generated/riffer/rig/runtime/tool_runtime.rbs +25 -1
  196. data/sig/generated/riffer/rig/runtime/usage.rbs +11 -0
  197. data/sig/generated/riffer/rig/runtime.rbs +131 -80
  198. data/sig/generated/riffer/rig/sdk.rbs +11 -1
  199. data/sig/generated/riffer/rig/settings/file.rbs +19 -0
  200. data/sig/generated/riffer/rig/settings/model_options.rbs +31 -0
  201. data/sig/generated/riffer/rig/settings.rbs +0 -66
  202. data/sig/generated/riffer/rig/stores/entries.rbs +12 -0
  203. data/sig/generated/riffer/rig/stores/header.rbs +2 -5
  204. data/sig/generated/riffer/rig/stores/message_entry.rbs +9 -7
  205. data/sig/generated/riffer/rig/stores/model_entry.rbs +9 -7
  206. data/sig/generated/riffer/rig/stores/recorder.rbs +16 -4
  207. data/sig/generated/riffer/rig/stores/skill_entry.rbs +9 -7
  208. data/sig/generated/riffer/rig/stores/stamped.rbs +7 -0
  209. data/sig/generated/riffer/rig/stores/timestamp.rbs +13 -0
  210. data/sig/generated/riffer/rig/support/json_file.rbs +23 -0
  211. data/sig/generated/riffer/rig/support/typed_value/schema.rbs +14 -0
  212. data/sig/generated/riffer/rig/support/typed_value.rbs +13 -0
  213. data/sig/generated/riffer/rig/terminal/autocomplete.rbs +72 -0
  214. data/sig/generated/riffer/rig/terminal/banner.rbs +25 -4
  215. data/sig/generated/riffer/rig/terminal/blocking_prompter.rbs +23 -0
  216. data/sig/generated/riffer/rig/terminal/builtin.rbs +13 -0
  217. data/sig/generated/riffer/rig/terminal/columns.rbs +43 -0
  218. data/sig/generated/riffer/rig/terminal/console.rbs +32 -0
  219. data/sig/generated/riffer/rig/terminal/echo.rbs +15 -0
  220. data/sig/generated/riffer/rig/terminal/equalizer.rbs +12 -0
  221. data/sig/generated/riffer/rig/terminal/frame.rbs +169 -0
  222. data/sig/generated/riffer/rig/terminal/frame_prompter.rbs +34 -0
  223. data/sig/generated/riffer/rig/terminal/help.rbs +22 -0
  224. data/sig/generated/riffer/rig/terminal/host.rbs +5 -11
  225. data/sig/generated/riffer/rig/terminal/job_counter.rbs +21 -0
  226. data/sig/generated/riffer/rig/terminal/job_exit_notice.rbs +7 -0
  227. data/sig/generated/riffer/rig/terminal/key.rbs +27 -0
  228. data/sig/generated/riffer/rig/terminal/key_decoder.rbs +81 -0
  229. data/sig/generated/riffer/rig/terminal/key_pipeline.rbs +54 -0
  230. data/sig/generated/riffer/rig/terminal/line_editor.rbs +108 -0
  231. data/sig/generated/riffer/rig/terminal/markdown/blocks.rbs +57 -0
  232. data/sig/generated/riffer/rig/terminal/markdown/flow.rbs +42 -0
  233. data/sig/generated/riffer/rig/terminal/markdown/inline.rbs +41 -0
  234. data/sig/generated/riffer/rig/terminal/markdown/span.rbs +20 -0
  235. data/sig/generated/riffer/rig/terminal/markdown/table.rbs +101 -0
  236. data/sig/generated/riffer/rig/terminal/markdown.rbs +112 -0
  237. data/sig/generated/riffer/rig/terminal/message_queue/message.rbs +10 -0
  238. data/sig/generated/riffer/rig/terminal/message_queue.rbs +17 -0
  239. data/sig/generated/riffer/rig/terminal/opening.rbs +33 -0
  240. data/sig/generated/riffer/rig/terminal/peek.rbs +37 -0
  241. data/sig/generated/riffer/rig/terminal/picker.rbs +82 -0
  242. data/sig/generated/riffer/rig/terminal/question.rbs +21 -0
  243. data/sig/generated/riffer/rig/terminal/quiet_display.rbs +33 -0
  244. data/sig/generated/riffer/rig/terminal/renderer.rbs +10 -122
  245. data/sig/generated/riffer/rig/terminal/repl.rbs +116 -0
  246. data/sig/generated/riffer/rig/terminal/replay/turn.rbs +20 -0
  247. data/sig/generated/riffer/rig/terminal/replay.rbs +29 -0
  248. data/sig/generated/riffer/rig/terminal/session.rbs +27 -0
  249. data/sig/generated/riffer/rig/terminal/tally.rbs +7 -0
  250. data/sig/generated/riffer/rig/terminal/theme.rbs +23 -2
  251. data/sig/generated/riffer/rig/terminal/ticker.rbs +107 -0
  252. data/sig/generated/riffer/rig/terminal/ticker_display.rbs +48 -0
  253. data/sig/generated/riffer/rig/terminal/turn_buffer/stats.rbs +16 -0
  254. data/sig/generated/riffer/rig/terminal/turn_buffer.rbs +67 -0
  255. data/sig/generated/riffer/rig/terminal/turn_report.rbs +52 -0
  256. data/sig/generated/riffer/rig/terminal/wrapper.rbs +16 -14
  257. data/sig/generated/riffer/rig/terminal.rbs +101 -28
  258. data/sig/generated/riffer/rig/tools/bash/capture.rbs +39 -0
  259. data/sig/generated/riffer/rig/tools/bash/job.rbs +65 -0
  260. data/sig/generated/riffer/rig/tools/bash/job_log.rbs +60 -0
  261. data/sig/generated/riffer/rig/tools/bash/jobs.rbs +86 -0
  262. data/sig/generated/riffer/rig/tools/bash/kill.rbs +8 -0
  263. data/sig/generated/riffer/rig/tools/bash/kill_group.rbs +7 -0
  264. data/sig/generated/riffer/rig/tools/bash/monotonic_clock.rbs +6 -0
  265. data/sig/generated/riffer/rig/tools/bash/output.rbs +10 -0
  266. data/sig/generated/riffer/rig/tools/bash/truncation.rbs +7 -0
  267. data/sig/generated/riffer/rig/tools/bash.rbs +15 -13
  268. data/sig/generated/riffer/rig/trust.rbs +7 -8
  269. data/sig/manual/riffer/rig/acp/mapper.rbs +6 -0
  270. data/sig/manual/riffer/rig/commands/cost.rbs +6 -0
  271. data/sig/manual/riffer/rig/commands/trace/replay.rbs +6 -0
  272. data/sig/manual/riffer/rig/commands/trace.rbs +6 -0
  273. data/sig/manual/riffer/rig/credentials/provider_fields.rbs +6 -0
  274. data/sig/manual/riffer/rig/events.rbs +1 -0
  275. data/sig/manual/riffer/rig/headless/ndjson.rbs +6 -0
  276. data/sig/manual/riffer/rig/headless.rbs +7 -0
  277. data/sig/manual/riffer/rig/hosts.rbs +1 -1
  278. data/sig/manual/riffer/rig/loader/credentials.rbs +6 -0
  279. data/sig/manual/riffer/rig/mcp/auth.rbs +6 -0
  280. data/sig/manual/riffer/rig/runtime/error_message.rbs +6 -0
  281. data/sig/manual/riffer/rig/runtime/job_envelope.rbs +6 -0
  282. data/sig/manual/riffer/rig/runtime/usage.rbs +6 -0
  283. data/sig/manual/riffer/rig/sdk.rbs +1 -1
  284. data/sig/manual/riffer/rig/settings/file.rbs +6 -0
  285. data/sig/manual/riffer/rig/settings/model_options.rbs +6 -0
  286. data/sig/manual/riffer/rig/stores/entries.rbs +6 -0
  287. data/sig/manual/riffer/rig/stores/timestamp.rbs +6 -0
  288. data/sig/manual/riffer/rig/stores.rbs +8 -0
  289. data/sig/manual/riffer/rig/support/json_file.rbs +6 -0
  290. data/sig/manual/riffer/rig/support.rbs +10 -0
  291. data/sig/manual/riffer/rig/terminal/autocomplete.rbs +8 -0
  292. data/sig/manual/riffer/rig/terminal/columns.rbs +6 -0
  293. data/sig/manual/riffer/rig/terminal/echo.rbs +6 -0
  294. data/sig/manual/riffer/rig/terminal/equalizer.rbs +6 -0
  295. data/sig/manual/riffer/rig/terminal/help.rbs +6 -0
  296. data/sig/manual/riffer/rig/terminal/job_exit_notice.rbs +6 -0
  297. data/sig/manual/riffer/rig/terminal/markdown/blocks.rbs +6 -0
  298. data/sig/manual/riffer/rig/terminal/markdown/flow.rbs +6 -0
  299. data/sig/manual/riffer/rig/terminal/markdown/inline.rbs +6 -0
  300. data/sig/manual/riffer/rig/terminal/markdown/table.rbs +6 -0
  301. data/sig/manual/riffer/rig/terminal/markdown.rbs +6 -0
  302. data/sig/manual/riffer/rig/terminal/question.rbs +6 -0
  303. data/sig/manual/riffer/rig/terminal/replay.rbs +14 -0
  304. data/sig/manual/riffer/rig/terminal/tally.rbs +6 -0
  305. data/sig/manual/riffer/rig/terminal/turn_report.rbs +14 -0
  306. data/sig/manual/riffer/rig/terminal.rbs +37 -0
  307. metadata +214 -9
  308. data/lib/riffer/rig/terminal/animator.rb +0 -139
  309. data/lib/riffer/rig/terminal/cursor.rb +0 -44
  310. data/lib/riffer/rig/terminal/smoother.rb +0 -126
  311. data/sig/generated/riffer/rig/terminal/animator.rbs +0 -68
  312. data/sig/generated/riffer/rig/terminal/cursor.rbs +0 -31
  313. data/sig/generated/riffer/rig/terminal/smoother.rbs +0 -59
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5f79d98c522224290937a01b701fa7f4ac72f2be08fbbb39abf32f06691880f7
4
- data.tar.gz: 3c66dbd81e98e86b1c1132094431e0803d23c757a950684c6663ad5abd8c3369
3
+ metadata.gz: 8fe0ea5d0af46d44401a20ba9880877d1f631d4131de70452256a5def7d206aa
4
+ data.tar.gz: '0108f44f3cd248417bee1320ef14921cf75d8018784b103ebf85d676f941cd79'
5
5
  SHA512:
6
- metadata.gz: 6087cb7527548ca826bf04ab3b214c36ab29e18c676c62f7df84377010bb47fddae9e88b1354d1fa8815efa4967d4599ccc63e022c57660a567b58e226554679
7
- data.tar.gz: 2aae83bea0978c35b33674149527c0281baeb33f7bf186ba38d9b6abdeb905a3649989eae97430d7eae6284a80a253152d0532c8ba3d75f3ae3d7adee6f6a757
6
+ metadata.gz: 761434ca55b8f51971328b39ad0dfa02d4a89e21c41f03b1dfb55778c09cac14f4d3328799e8a6e1b25027f9d30a953d3278f4a0264a0ae558e6f56ef577c779
7
+ data.tar.gz: f9e88b15b40d562553f4b0b871a1b992c0da8c6b883159561be132e3b74312b7fce5d31b18391db99366e7bc6a4d0070639efce9abe7b454e572d9d4e7acc659
data/CHANGELOG.md CHANGED
@@ -1,5 +1,145 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.13.0](https://github.com/bottrall/riffer-rig/compare/v0.12.0...v0.13.0) (2026-10-17)
4
+
5
+
6
+ ### ⚠ BREAKING CHANGES
7
+
8
+ * Riffer::Rig::Loader takes its per-build choices as a Riffer::Rig::Loader::Options instead of keywords. Loader.runtime no longer accepts model:, extensions:, skills:, agents_md:, tools: or max_steps: (ArgumentError: unknown keywords); pass options: Riffer::Rig::Loader::Options.new(model: ..., skills: false). On a Loader instance the Options is the optional first positional argument: runtime(options), continue(options) and resume(id, options). Loader#tracked_files is removed with no replacement.
9
+
10
+ ### Features
11
+
12
+ * **acp:** add adopt: hook and yield the connection from run ([#336](https://github.com/bottrall/riffer-rig/issues/336)) ([612a9c4](https://github.com/bottrall/riffer-rig/commit/612a9c4710f41ab19140d91112887e833c40ce4d)), closes [#302](https://github.com/bottrall/riffer-rig/issues/302)
13
+ * **acp:** announce background job exits between prompts ([#437](https://github.com/bottrall/riffer-rig/issues/437)) ([cd40e5b](https://github.com/bottrall/riffer-rig/commit/cd40e5b1778a72595b4c2f4a376544052c5c1a3d)), closes [#334](https://github.com/bottrall/riffer-rig/issues/334)
14
+ * **acp:** relay host questions to the client ([#337](https://github.com/bottrall/riffer-rig/issues/337)) ([e4fe093](https://github.com/bottrall/riffer-rig/commit/e4fe093505c74f89b7a8fc93680425b95c59e663))
15
+ * carry the tool lifecycle on before/after_tool_call events ([#321](https://github.com/bottrall/riffer-rig/issues/321)) ([c3967e2](https://github.com/bottrall/riffer-rig/commit/c3967e224b2d7427f6fd54e028b47f9644e24375))
16
+ * **commands:** add /cost runtime command ([#431](https://github.com/bottrall/riffer-rig/issues/431)) ([f7f36e8](https://github.com/bottrall/riffer-rig/commit/f7f36e8e91038952ca3a6762d792e0aea8ed67e6)), closes [#260](https://github.com/bottrall/riffer-rig/issues/260)
17
+ * **commands:** add /trace runtime command ([#373](https://github.com/bottrall/riffer-rig/issues/373)) ([95fc4cc](https://github.com/bottrall/riffer-rig/commit/95fc4cca0ab07cc7d1d39d726875e21eaa184fbb)), closes [#250](https://github.com/bottrall/riffer-rig/issues/250)
18
+ * **deps:** upgrade riffer to 0.51.0 ([#306](https://github.com/bottrall/riffer-rig/issues/306)) ([255c3d7](https://github.com/bottrall/riffer-rig/commit/255c3d7474baf3e669b5b093eb492984e3235cbd))
19
+ * **deps:** upgrade riffer to 0.52.1 ([#418](https://github.com/bottrall/riffer-rig/issues/418)) ([7b9c085](https://github.com/bottrall/riffer-rig/commit/7b9c085de9c3ea5d7fc6a5b3c3d4c9b3b6e1825b))
20
+ * **headless:** wait for background jobs at exit ([#438](https://github.com/bottrall/riffer-rig/issues/438)) ([91c7f9f](https://github.com/bottrall/riffer-rig/commit/91c7f9fc09fa6ea0a95c3e0221978979a1ff90f1)), closes [#331](https://github.com/bottrall/riffer-rig/issues/331)
21
+ * **runtime:** deliver background job exits to the model ([#434](https://github.com/bottrall/riffer-rig/issues/434)) ([e3f87b3](https://github.com/bottrall/riffer-rig/commit/e3f87b3a8d8efbe9a1f380b161b80f00bb89da00))
22
+ * **runtime:** keep background jobs running through a cancel ([#436](https://github.com/bottrall/riffer-rig/issues/436)) ([699ebbc](https://github.com/bottrall/riffer-rig/commit/699ebbc9055f11b95e7446a94ed33895387d8661)), closes [#333](https://github.com/bottrall/riffer-rig/issues/333)
23
+ * **stores:** stamp session entries with recorded_at ([#316](https://github.com/bottrall/riffer-rig/issues/316)) ([44dd322](https://github.com/bottrall/riffer-rig/commit/44dd3221b6a6c34528fb17772f15b2449a4ebdfc))
24
+ * **terminal:** add a /help command that lists the session's commands ([#547](https://github.com/bottrall/riffer-rig/issues/547)) ([81acfcf](https://github.com/bottrall/riffer-rig/commit/81acfcf7946033ecc0bebcf886db32b5b2a81e72)), closes [#545](https://github.com/bottrall/riffer-rig/issues/545)
25
+ * **terminal:** add the message queue and its footer chip ([#410](https://github.com/bottrall/riffer-rig/issues/410)) ([9a4c41a](https://github.com/bottrall/riffer-rig/commit/9a4c41a630fdabf4edaf90434ed4cc1c441ecbbb)), closes [#243](https://github.com/bottrall/riffer-rig/issues/243)
26
+ * **terminal:** make the ticker UI the default and document it ([#435](https://github.com/bottrall/riffer-rig/issues/435)) ([3400949](https://github.com/bottrall/riffer-rig/commit/34009492060bec9f36be554ffcebac770b247d4a)), closes [#265](https://github.com/bottrall/riffer-rig/issues/265)
27
+ * **terminal:** replay prior turns on resume ([#432](https://github.com/bottrall/riffer-rig/issues/432)) ([7652083](https://github.com/bottrall/riffer-rig/commit/765208399a1c3a69791ba85bb9a97dc2914206ed)), closes [#262](https://github.com/bottrall/riffer-rig/issues/262)
28
+ * **terminal:** run the REPL as a queue-draining loop ([#429](https://github.com/bottrall/riffer-rig/issues/429)) ([0213860](https://github.com/bottrall/riffer-rig/commit/021386049d753b48226cc6dbb8a63312d03dacdf))
29
+ * **terminal:** show session totals in the banner and redraw on /model ([#317](https://github.com/bottrall/riffer-rig/issues/317)) ([69232fd](https://github.com/bottrall/riffer-rig/commit/69232fde93179869cce86b66bcc6aa0da9dfa731)), closes [#264](https://github.com/bottrall/riffer-rig/issues/264)
30
+ * **terminal:** show turns through the ticker and delete the old renderer ([#433](https://github.com/bottrall/riffer-rig/issues/433)) ([4ec3388](https://github.com/bottrall/riffer-rig/commit/4ec3388df41a01d34b9fa9686df7f63ba0b42062))
31
+ * **terminal:** start a turn when a background job exits at an idle prompt ([#439](https://github.com/bottrall/riffer-rig/issues/439)) ([0d5198a](https://github.com/bottrall/riffer-rig/commit/0d5198af9b1c65c06277b0201fc48355283bce7e)), closes [#332](https://github.com/bottrall/riffer-rig/issues/332)
32
+ * **terminal:** wire slash autocomplete into the REPL ([#495](https://github.com/bottrall/riffer-rig/issues/495)) ([af936d9](https://github.com/bottrall/riffer-rig/commit/af936d96e786ad9e76e1283763b17dfac3c4daba))
33
+ * **tools:** add bash_output and bash_kill for background jobs ([#409](https://github.com/bottrall/riffer-rig/issues/409)) ([88fc7a9](https://github.com/bottrall/riffer-rig/commit/88fc7a9ad321dc443f57dbb3455c599a7db5e5e0)), closes [#329](https://github.com/bottrall/riffer-rig/issues/329)
34
+ * **tools:** job registry for background bash jobs ([#305](https://github.com/bottrall/riffer-rig/issues/305)) ([54f7df1](https://github.com/bottrall/riffer-rig/commit/54f7df15d140b499ec9c3e3b612c6d71df201563)), closes [#276](https://github.com/bottrall/riffer-rig/issues/276)
35
+ * watch background jobs and route their exits through the Runtime ([#376](https://github.com/bottrall/riffer-rig/issues/376)) ([32a3be2](https://github.com/bottrall/riffer-rig/commit/32a3be20edb330f528318e07a6aaf10e5019e0e2)), closes [#328](https://github.com/bottrall/riffer-rig/issues/328)
36
+
37
+
38
+ ### Bug Fixes
39
+
40
+ * acp banner, close TODO, settings key types ([#304](https://github.com/bottrall/riffer-rig/issues/304)) ([baa6597](https://github.com/bottrall/riffer-rig/commit/baa659764ea1293792a0ee1dd8f40e289ed807bc))
41
+ * **acp:** announce the tool call of a relayed question ([#511](https://github.com/bottrall/riffer-rig/issues/511)) ([b20f0ee](https://github.com/bottrall/riffer-rig/commit/b20f0ee38ac722f7804dc15555cc00971ecde457)), closes [#472](https://github.com/bottrall/riffer-rig/issues/472)
42
+ * **acp:** answer a failed prompt with the provider's message ([#526](https://github.com/bottrall/riffer-rig/issues/526)) ([976c670](https://github.com/bottrall/riffer-rig/commit/976c670b6d5db43d50b969cc951e56c068c0fc58)), closes [#519](https://github.com/bottrall/riffer-rig/issues/519)
43
+ * **acp:** answer a prompt on a busy session with invalid request ([#508](https://github.com/bottrall/riffer-rig/issues/508)) ([3a50652](https://github.com/bottrall/riffer-rig/commit/3a50652a23a98b48675ae5e46df7ba1cc5b98c01)), closes [#473](https://github.com/bottrall/riffer-rig/issues/473)
44
+ * **acp:** close the tool call of a relayed question ([#404](https://github.com/bottrall/riffer-rig/issues/404)) ([2dc638c](https://github.com/bottrall/riffer-rig/commit/2dc638cc5a7a275e5d0f968b9e83530aa97967e4)), closes [#395](https://github.com/bottrall/riffer-rig/issues/395)
45
+ * **acp:** declare the client's MCP servers on session/load ([#374](https://github.com/bottrall/riffer-rig/issues/374)) ([06e07bd](https://github.com/bottrall/riffer-rig/commit/06e07bdea43cdf74be02fe6342b06e344aa75d0e)), closes [#343](https://github.com/bottrall/riffer-rig/issues/343)
46
+ * **acp:** decline build-time questions while session/load builds ([#405](https://github.com/bottrall/riffer-rig/issues/405)) ([98cf668](https://github.com/bottrall/riffer-rig/commit/98cf668041eb6b239d9bc8fa3e47288f7469dcf7)), closes [#394](https://github.com/bottrall/riffer-rig/issues/394)
47
+ * **acp:** re-send the command list after a reload changes it ([#535](https://github.com/bottrall/riffer-rig/issues/535)) ([a904bc7](https://github.com/bottrall/riffer-rig/commit/a904bc7cdba4a39506196980ac0333ec2df7a89f)), closes [#521](https://github.com/bottrall/riffer-rig/issues/521)
48
+ * **acp:** run slash commands instead of sending them to the model ([#494](https://github.com/bottrall/riffer-rig/issues/494)) ([3924ce5](https://github.com/bottrall/riffer-rig/commit/3924ce52b39e0ae3ef4d409200ce00ca464d38e3)), closes [#444](https://github.com/bottrall/riffer-rig/issues/444)
49
+ * **acp:** send available_commands_update on session/load ([#403](https://github.com/bottrall/riffer-rig/issues/403)) ([3659b0a](https://github.com/bottrall/riffer-rig/commit/3659b0a9b7129e7c1664f6158f6b51a46a9d95d4)), closes [#383](https://github.com/bottrall/riffer-rig/issues/383)
50
+ * **acp:** send each notice as a paragraph of its own ([#527](https://github.com/bottrall/riffer-rig/issues/527)) ([e665309](https://github.com/bottrall/riffer-rig/commit/e665309ad401330c9abc511e2645054a274838e2)), closes [#520](https://github.com/bottrall/riffer-rig/issues/520)
51
+ * **acp:** skip blank assistant messages when replaying a loaded session ([#509](https://github.com/bottrall/riffer-rig/issues/509)) ([85f0aa3](https://github.com/bottrall/riffer-rig/commit/85f0aa3582c893d2eb5ef58dbb9103cdd89f7568)), closes [#471](https://github.com/bottrall/riffer-rig/issues/471)
52
+ * **cli:** answer --version and -v with the riffer-rig version ([#399](https://github.com/bottrall/riffer-rig/issues/399)) ([08ad995](https://github.com/bottrall/riffer-rig/commit/08ad995ba8570a2aced722fa1305c025939d5ee4)), closes [#380](https://github.com/bottrall/riffer-rig/issues/380)
53
+ * **cli:** open the picker for a bare -r followed by another flag ([#370](https://github.com/bottrall/riffer-rig/issues/370)) ([e01bd20](https://github.com/bottrall/riffer-rig/commit/e01bd20d8c599d208c0e2541e34d7575df9d7e83)), closes [#342](https://github.com/bottrall/riffer-rig/issues/342)
54
+ * **cli:** recognise clustered short flags such as -pc as headless ([#406](https://github.com/bottrall/riffer-rig/issues/406)) ([2e28f63](https://github.com/bottrall/riffer-rig/commit/2e28f630601ac774652467ca0d1efbbaa5208428)), closes [#384](https://github.com/bottrall/riffer-rig/issues/384)
55
+ * **cli:** reject --max-steps values below 1 ([#499](https://github.com/bottrall/riffer-rig/issues/499)) ([e0e33ad](https://github.com/bottrall/riffer-rig/commit/e0e33ad13e3d04d4f555f0e455997f7d6a5938da)), closes [#467](https://github.com/bottrall/riffer-rig/issues/467)
56
+ * **commands:** confirm the save in /model --save ([#500](https://github.com/bottrall/riffer-rig/issues/500)) ([7c0035b](https://github.com/bottrall/riffer-rig/commit/7c0035b1b6780955f8f8508d6cda3459ab4721eb)), closes [#464](https://github.com/bottrall/riffer-rig/issues/464)
57
+ * **credentials:** never overwrite a malformed auth, settings or trust file ([#415](https://github.com/bottrall/riffer-rig/issues/415)) ([c8d66aa](https://github.com/bottrall/riffer-rig/commit/c8d66aa6babdf791ce9e3a47bdbdd168454dffd0)), closes [#381](https://github.com/bottrall/riffer-rig/issues/381)
58
+ * **credentials:** preserve unrecognised auth.json entries on store and remove ([#365](https://github.com/bottrall/riffer-rig/issues/365)) ([a7d26e7](https://github.com/bottrall/riffer-rig/commit/a7d26e799d64099a711a771b30e42bdf4a8c86c8)), closes [#344](https://github.com/bottrall/riffer-rig/issues/344)
59
+ * **credentials:** tighten an existing auth.json to 0600 on rewrite ([#400](https://github.com/bottrall/riffer-rig/issues/400)) ([59765c8](https://github.com/bottrall/riffer-rig/commit/59765c822cbae0b168c7ba63e440b2dfdc6f4529)), closes [#382](https://github.com/bottrall/riffer-rig/issues/382)
60
+ * **deps:** pin acp-sdk to one minor ([#397](https://github.com/bottrall/riffer-rig/issues/397)) ([7bcad06](https://github.com/bottrall/riffer-rig/commit/7bcad0649686e052afe5e5fc371212800d493237))
61
+ * **deps:** upgrade acp-sdk to 0.11.0 ([#338](https://github.com/bottrall/riffer-rig/issues/338)) ([8e61f4a](https://github.com/bottrall/riffer-rig/commit/8e61f4a887ded320cf668300629f210bb02c91f9))
62
+ * **deps:** upgrade acp-sdk to 0.13.0 ([#424](https://github.com/bottrall/riffer-rig/issues/424)) ([ba080c1](https://github.com/bottrall/riffer-rig/commit/ba080c1621cff5d3ea77e73863558e6778ff6445))
63
+ * **headless:** print the --verbose tool trace in --json mode ([#501](https://github.com/bottrall/riffer-rig/issues/501)) ([4fba2a0](https://github.com/bottrall/riffer-rig/commit/4fba2a060bd07e1745d46f41bf6b655a553f8d5a)), closes [#468](https://github.com/bottrall/riffer-rig/issues/468)
64
+ * **headless:** refuse a whitespace-only prompt ([#498](https://github.com/bottrall/riffer-rig/issues/498)) ([633d099](https://github.com/bottrall/riffer-rig/commit/633d099cdaf473a963e20d4b11140749580afe64)), closes [#465](https://github.com/bottrall/riffer-rig/issues/465)
65
+ * **headless:** replace invalid UTF-8 in piped stdin ([#482](https://github.com/bottrall/riffer-rig/issues/482)) ([1e726f4](https://github.com/bottrall/riffer-rig/commit/1e726f4650ea3a968e466aee7480ee57caf86580)), closes [#451](https://github.com/bottrall/riffer-rig/issues/451)
66
+ * **headless:** report a missing session before the missing prompt ([#507](https://github.com/bottrall/riffer-rig/issues/507)) ([60ad490](https://github.com/bottrall/riffer-rig/commit/60ad49009836e7706a0429927d8f0ad2630ec7ac))
67
+ * **headless:** separate follow-up answers with a blank line in text mode ([#505](https://github.com/bottrall/riffer-rig/issues/505)) ([4c74399](https://github.com/bottrall/riffer-rig/commit/4c7439915932155c50378769b5d40f01eba29dc9)), closes [#469](https://github.com/bottrall/riffer-rig/issues/469)
68
+ * **headless:** serialise non-pair Enumerables in Ndjson as arrays ([#357](https://github.com/bottrall/riffer-rig/issues/357)) ([0b5e16a](https://github.com/bottrall/riffer-rig/commit/0b5e16a6339b42d87504bfd85e21f501aeaad9e6)), closes [#348](https://github.com/bottrall/riffer-rig/issues/348)
69
+ * **headless:** stop waiting on a silent stdin when -p has a prompt argument ([#541](https://github.com/bottrall/riffer-rig/issues/541)) ([32d0ca9](https://github.com/bottrall/riffer-rig/commit/32d0ca9cbccf089461030de33f8f4475f1b2fb47)), closes [#529](https://github.com/bottrall/riffer-rig/issues/529)
70
+ * **headless:** stream stdout to pipes and files as it is written ([#484](https://github.com/bottrall/riffer-rig/issues/484)) ([3fbc295](https://github.com/bottrall/riffer-rig/commit/3fbc295ebef30269546ec87c3af0fb4a8a6d6fe1)), closes [#452](https://github.com/bottrall/riffer-rig/issues/452)
71
+ * **loader:** ask again about a trust question left unanswered ([#522](https://github.com/bottrall/riffer-rig/issues/522)) ([c5e8dae](https://github.com/bottrall/riffer-rig/commit/c5e8dae6891cd1388dc71ef8c3d38e5e55021c7f)), closes [#517](https://github.com/bottrall/riffer-rig/issues/517)
72
+ * **mcp:** preserve stdio fields in Declaration#with_headers ([#310](https://github.com/bottrall/riffer-rig/issues/310)) ([90b6f8e](https://github.com/bottrall/riffer-rig/commit/90b6f8e2b87b68b726eec599e5d6c905801681ff)), closes [#307](https://github.com/bottrall/riffer-rig/issues/307)
73
+ * route missing-session wording through the sessions collaborator ([#298](https://github.com/bottrall/riffer-rig/issues/298)) ([a22e2bd](https://github.com/bottrall/riffer-rig/commit/a22e2bd483c44a6ec345f50f0a15a8a84c4c9b66)), closes [#283](https://github.com/bottrall/riffer-rig/issues/283)
74
+ * **runtime:** keep a resumed session's first user message ([#478](https://github.com/bottrall/riffer-rig/issues/478)) ([3a1e7e5](https://github.com/bottrall/riffer-rig/commit/3a1e7e5523ffc5cc060bc57eeeb70a46cc3467cd)), closes [#441](https://github.com/bottrall/riffer-rig/issues/441)
75
+ * **runtime:** show the provider's response body message on HTTP errors ([#491](https://github.com/bottrall/riffer-rig/issues/491)) ([4e93ec4](https://github.com/bottrall/riffer-rig/commit/4e93ec486820f8a49b8d6a00a7838ff9e0f90561))
76
+ * **runtime:** warn about tool allowlist names no extension registered ([#485](https://github.com/bottrall/riffer-rig/issues/485)) ([da61612](https://github.com/bottrall/riffer-rig/commit/da6161282e965dac648c6b4b213c9441d8385b79)), closes [#453](https://github.com/bottrall/riffer-rig/issues/453)
77
+ * **sdk:** return a message when the gem install fails ([#369](https://github.com/bottrall/riffer-rig/issues/369)) ([1cf5557](https://github.com/bottrall/riffer-rig/commit/1cf55574568868fa162200d84b74eb34f73cd9c2)), closes [#351](https://github.com/bottrall/riffer-rig/issues/351)
78
+ * **sessions:** let --model win over a resumed session's /model switch ([#537](https://github.com/bottrall/riffer-rig/issues/537)) ([8233c13](https://github.com/bottrall/riffer-rig/commit/8233c13f75cbb883577c0bc00a40e80b6d9507b4)), closes [#528](https://github.com/bottrall/riffer-rig/issues/528)
79
+ * **sessions:** resume a session in the directory it was saved in ([#544](https://github.com/bottrall/riffer-rig/issues/544)) ([6cd8df2](https://github.com/bottrall/riffer-rig/commit/6cd8df2c80947920d5ea479a4bd5cd1b0b19a892)), closes [#530](https://github.com/bottrall/riffer-rig/issues/530)
80
+ * **settings:** report a non-string model as a settings error ([#510](https://github.com/bottrall/riffer-rig/issues/510)) ([5fde7c2](https://github.com/bottrall/riffer-rig/commit/5fde7c2a0687a99fa3a83c96c0bfc016329f82e7)), closes [#470](https://github.com/bottrall/riffer-rig/issues/470)
81
+ * single credentials install flow, fixing the /auth partial-apply ([#295](https://github.com/bottrall/riffer-rig/issues/295)) ([d6626d8](https://github.com/bottrall/riffer-rig/commit/d6626d8b8f46c78f2c9a7b3a50f4d730c4d63a71))
82
+ * **stores:** keep recording skill activations after a reload ([#371](https://github.com/bottrall/riffer-rig/issues/371)) ([d81abb2](https://github.com/bottrall/riffer-rig/commit/d81abb2a33efba05bf0264ea5708808b95a4e352)), closes [#327](https://github.com/bottrall/riffer-rig/issues/327)
83
+ * **stores:** skip non-object JSON lines in Stores::JSONL ([#361](https://github.com/bottrall/riffer-rig/issues/361)) ([14f9d3a](https://github.com/bottrall/riffer-rig/commit/14f9d3afe2dd46aceb33c5d2ffaa59e773e944ec)), closes [#346](https://github.com/bottrall/riffer-rig/issues/346)
84
+ * **terminal:** announce the exits a follow-up turn actually delivers ([#542](https://github.com/bottrall/riffer-rig/issues/542)) ([f04e762](https://github.com/bottrall/riffer-rig/commit/f04e762922eef0c015ffef25e84b474897973367)), closes [#532](https://github.com/bottrall/riffer-rig/issues/532)
85
+ * **terminal:** cancel a credential question on Ctrl-C ([#490](https://github.com/bottrall/riffer-rig/issues/490)) ([37579b6](https://github.com/bottrall/riffer-rig/commit/37579b61f448d0015ff7947f81e10e5fbb7c03ab))
86
+ * **terminal:** close the session /new or /resume swapped in at exit ([#480](https://github.com/bottrall/riffer-rig/issues/480)) ([dd3de41](https://github.com/bottrall/riffer-rig/commit/dd3de41d87cda9a5b5e39b4693eb927a5a0da9bc)), closes [#442](https://github.com/bottrall/riffer-rig/issues/442)
87
+ * **terminal:** confirm /model in one line instead of the banner ([#401](https://github.com/bottrall/riffer-rig/issues/401)) ([083a2c0](https://github.com/bottrall/riffer-rig/commit/083a2c076a9c6d2b2dc028a26f68200b5ea8cf95)), closes [#378](https://github.com/bottrall/riffer-rig/issues/378)
88
+ * **terminal:** fit the banner to narrow terminals ([#513](https://github.com/bottrall/riffer-rig/issues/513)) ([9a19efa](https://github.com/bottrall/riffer-rig/commit/9a19efaf437c633f89600c9d7b3be18d83eacedb)), closes [#474](https://github.com/bottrall/riffer-rig/issues/474)
89
+ * **terminal:** handle Ctrl-C at idle when SIGINT is inherited as ignored ([#512](https://github.com/bottrall/riffer-rig/issues/512)) ([73d51e7](https://github.com/bottrall/riffer-rig/commit/73d51e7396bf3b9b37a6230fe056501eb85d3852)), closes [#476](https://github.com/bottrall/riffer-rig/issues/476)
90
+ * **terminal:** indent and wrap command output like the turn report ([#497](https://github.com/bottrall/riffer-rig/issues/497)) ([2aadbd0](https://github.com/bottrall/riffer-rig/commit/2aadbd049a96de45e1b11e323e8c89c069eb9a30)), closes [#458](https://github.com/bottrall/riffer-rig/issues/458)
91
+ * **terminal:** interrupt a streaming reply on Ctrl-C ([#416](https://github.com/bottrall/riffer-rig/issues/416)) ([0f123dc](https://github.com/bottrall/riffer-rig/commit/0f123dc01fa2f30ceab3cdd45c08e77a73845efe))
92
+ * **terminal:** keep a blank row between output and the input row ([#534](https://github.com/bottrall/riffer-rig/issues/534)) ([01070f4](https://github.com/bottrall/riffer-rig/commit/01070f40e7b6b6ba0d3a8671d3d6c37bd55ba68f)), closes [#515](https://github.com/bottrall/riffer-rig/issues/515)
93
+ * **terminal:** keep a pasted prompt's line breaks in its echo ([#536](https://github.com/bottrall/riffer-rig/issues/536)) ([73b73ec](https://github.com/bottrall/riffer-rig/commit/73b73ecfb4cd59b8eacb8bc43b38048d17349685)), closes [#525](https://github.com/bottrall/riffer-rig/issues/525)
94
+ * **terminal:** keep a whitespace-only line as a paragraph break ([#366](https://github.com/bottrall/riffer-rig/issues/366)) ([3a402c8](https://github.com/bottrall/riffer-rig/commit/3a402c85b64b61f508a7990b36b032d9276ab6e4)), closes [#341](https://github.com/bottrall/riffer-rig/issues/341)
95
+ * **terminal:** keep the columns of a /trace line that wraps ([#538](https://github.com/bottrall/riffer-rig/issues/538)) ([d24cfc5](https://github.com/bottrall/riffer-rig/commit/d24cfc501cecfd7e3129d12b72487bc467af640a)), closes [#524](https://github.com/bottrall/riffer-rig/issues/524)
96
+ * **terminal:** keep the key reader alive on non-UTF-8 input ([#496](https://github.com/bottrall/riffer-rig/issues/496)) ([f7382c6](https://github.com/bottrall/riffer-rig/commit/f7382c6d4b55fad766285c2c1e6a910ae9f5f291)), closes [#443](https://github.com/bottrall/riffer-rig/issues/443)
97
+ * **terminal:** make the key pipeline restartable and end-of-input aware ([#408](https://github.com/bottrall/riffer-rig/issues/408)) ([c2b4787](https://github.com/bottrall/riffer-rig/commit/c2b4787c35e0e86a1b196b4538d52d8eafe045bd)), closes [#396](https://github.com/bottrall/riffer-rig/issues/396)
98
+ * **terminal:** print the missing-session notice below the banner ([#514](https://github.com/bottrall/riffer-rig/issues/514)) ([2b3a296](https://github.com/bottrall/riffer-rig/commit/2b3a29687a099bfa3eee0d9a4bd767dee6621ea3)), closes [#475](https://github.com/bottrall/riffer-rig/issues/475)
99
+ * **terminal:** render a paragraph's single newlines as line breaks ([#479](https://github.com/bottrall/riffer-rig/issues/479)) ([fa9d08f](https://github.com/bottrall/riffer-rig/commit/fa9d08f9122952a5c7af1c6876ccdfdb21c7550f)), closes [#450](https://github.com/bottrall/riffer-rig/issues/450)
100
+ * **terminal:** render non-object tool-call arguments verbatim ([#359](https://github.com/bottrall/riffer-rig/issues/359)) ([956ae23](https://github.com/bottrall/riffer-rig/commit/956ae2385b42012b1832fc58a7765de570dc4846)), closes [#347](https://github.com/bottrall/riffer-rig/issues/347)
101
+ * **terminal:** replay a job-exit turn on its own when resuming ([#493](https://github.com/bottrall/riffer-rig/issues/493)) ([24c84c2](https://github.com/bottrall/riffer-rig/commit/24c84c29b884b4bcb5818a61fa903a6c8251f5a4))
102
+ * **terminal:** report a bare / instead of sending it to the model ([#504](https://github.com/bottrall/riffer-rig/issues/504)) ([c66d2ae](https://github.com/bottrall/riffer-rig/commit/c66d2ae47a9477d1819b7aeb0f0ccf86fa2952fd)), closes [#460](https://github.com/bottrall/riffer-rig/issues/460)
103
+ * **terminal:** say sessions are off under --no-save instead of none saved ([#506](https://github.com/bottrall/riffer-rig/issues/506)) ([777aba0](https://github.com/bottrall/riffer-rig/commit/777aba0c4b368d6d95f26447b4871f01c2a82201)), closes [#463](https://github.com/bottrall/riffer-rig/issues/463)
104
+ * **terminal:** say when a picker filter matches no session ([#502](https://github.com/bottrall/riffer-rig/issues/502)) ([07b39bd](https://github.com/bottrall/riffer-rig/commit/07b39bdac94ec32731475ac22d844318178ddd3d)), closes [#462](https://github.com/bottrall/riffer-rig/issues/462)
105
+ * **terminal:** say when the /resume picker closes without a pick ([#503](https://github.com/bottrall/riffer-rig/issues/503)) ([327d34b](https://github.com/bottrall/riffer-rig/commit/327d34bc681e18a39bba4dc3e8565242e5a45ad8)), closes [#461](https://github.com/bottrall/riffer-rig/issues/461)
106
+ * **terminal:** show a static hint on the status line while a question waits ([#486](https://github.com/bottrall/riffer-rig/issues/486)) ([ee53ed5](https://github.com/bottrall/riffer-rig/commit/ee53ed5c61eaacf14acf57af7a66578f24ff797a)), closes [#457](https://github.com/bottrall/riffer-rig/issues/457)
107
+ * **terminal:** show every reply of a turn a job exit continued ([#543](https://github.com/bottrall/riffer-rig/issues/543)) ([763558d](https://github.com/bottrall/riffer-rig/commit/763558d845b9387cdd53e74f862991c602034b59)), closes [#531](https://github.com/bottrall/riffer-rig/issues/531)
108
+ * **terminal:** show the cursor while suspended with Ctrl-Z ([#414](https://github.com/bottrall/riffer-rig/issues/414)) ([fa6e7b4](https://github.com/bottrall/riffer-rig/commit/fa6e7b43e42405cb289e15741d7162880ea0583e))
109
+ * **terminal:** size a table by its header and keep pipes in code spans ([#489](https://github.com/bottrall/riffer-rig/issues/489)) ([324ba0e](https://github.com/bottrall/riffer-rig/commit/324ba0eead841027cafff9d60441de90500f4e25)), closes [#455](https://github.com/bottrall/riffer-rig/issues/455)
110
+ * **terminal:** stop Wrapper hanging when the width is at or below the indent ([#367](https://github.com/bottrall/riffer-rig/issues/367)) ([cbbca89](https://github.com/bottrall/riffer-rig/commit/cbbca899769a0782ad146e705f06a6055168daa4)), closes [#340](https://github.com/bottrall/riffer-rig/issues/340)
111
+ * **terminal:** treat 0 in the /resume picker as filter text ([#362](https://github.com/bottrall/riffer-rig/issues/362)) ([ae7516b](https://github.com/bottrall/riffer-rig/commit/ae7516bba9ea207337ef856d4132eaf8ee6095a4)), closes [#350](https://github.com/bottrall/riffer-rig/issues/350)
112
+ * **terminal:** word-wrap questions with a hanging indent ([#540](https://github.com/bottrall/riffer-rig/issues/540)) ([16fb443](https://github.com/bottrall/riffer-rig/commit/16fb443eb38e6428c313fb763dc7480f30cc56b3)), closes [#523](https://github.com/bottrall/riffer-rig/issues/523)
113
+ * **terminal:** word-wrap the echoed prompt with a hanging indent ([#483](https://github.com/bottrall/riffer-rig/issues/483)) ([3f357a1](https://github.com/bottrall/riffer-rig/commit/3f357a12c7af55a676dfc00af3ef4e9d593b9b15)), closes [#459](https://github.com/bottrall/riffer-rig/issues/459)
114
+ * **terminal:** wrap a table column at spaces before breaking a token ([#518](https://github.com/bottrall/riffer-rig/issues/518)) ([6208f11](https://github.com/bottrall/riffer-rig/commit/6208f1195a0bef97307984b35f923487bd865b9b)), closes [#516](https://github.com/bottrall/riffer-rig/issues/516)
115
+ * **terminal:** wrap markdown tables to the terminal width ([#492](https://github.com/bottrall/riffer-rig/issues/492)) ([3b998eb](https://github.com/bottrall/riffer-rig/commit/3b998eba84bf7b2311984c7d0b64c54ee2be3ded))
116
+ * **terminal:** wrap prose by display columns and keep its indentation ([#412](https://github.com/bottrall/riffer-rig/issues/412)) ([40f83ce](https://github.com/bottrall/riffer-rig/commit/40f83ce3b4cd7a00a05a8db0d2fc024b6927b024)), closes [#385](https://github.com/bottrall/riffer-rig/issues/385)
117
+ * **tools:** cap background job output and remove it on close ([#417](https://github.com/bottrall/riffer-rig/issues/417)) ([02a3c5e](https://github.com/bottrall/riffer-rig/commit/02a3c5ec00b8a0435ff70c7560e0ab652ec69cd7)), closes [#391](https://github.com/bottrall/riffer-rig/issues/391)
118
+ * **tools:** end a background job's process group after its leader exits ([#413](https://github.com/bottrall/riffer-rig/issues/413)) ([26de424](https://github.com/bottrall/riffer-rig/commit/26de424d91c7c73623386e9bbd348358536cfc71)), closes [#390](https://github.com/bottrall/riffer-rig/issues/390)
119
+ * **tools:** give background bash jobs an empty stdin ([#488](https://github.com/bottrall/riffer-rig/issues/488)) ([23a1a1c](https://github.com/bottrall/riffer-rig/commit/23a1a1c266f7a938c40c0b07c5a0838be6d24d79)), closes [#445](https://github.com/bottrall/riffer-rig/issues/445)
120
+ * **tools:** keep bash output valid UTF-8 and report sub-second timeouts ([#360](https://github.com/bottrall/riffer-rig/issues/360)) ([9d74845](https://github.com/bottrall/riffer-rig/commit/9d748453ecab23ac32995d0d26495cfe707ad6d9)), closes [#345](https://github.com/bottrall/riffer-rig/issues/345)
121
+ * **tools:** let bash_kill stop a stopped background job ([#487](https://github.com/bottrall/riffer-rig/issues/487)) ([2b5d13e](https://github.com/bottrall/riffer-rig/commit/2b5d13e3096b6a11ab59c5b0002e979f6abf0d21)), closes [#447](https://github.com/bottrall/riffer-rig/issues/447)
122
+ * **tools:** read bash output while the command runs ([#407](https://github.com/bottrall/riffer-rig/issues/407)) ([3a94502](https://github.com/bottrall/riffer-rig/commit/3a94502e5328c7b9edbf1ab5a64ac4386b075610)), closes [#379](https://github.com/bottrall/riffer-rig/issues/379)
123
+ * **tools:** replace invalid UTF-8 bytes in read output ([#481](https://github.com/bottrall/riffer-rig/issues/481)) ([8bc5c8b](https://github.com/bottrall/riffer-rig/commit/8bc5c8b1686ca4511ca595d535860c783eb170db)), closes [#446](https://github.com/bottrall/riffer-rig/issues/446)
124
+ * **tools:** report a background job ended by a signal as killed ([#539](https://github.com/bottrall/riffer-rig/issues/539)) ([db792ec](https://github.com/bottrall/riffer-rig/commit/db792ecde236947ba4681c8132e981def7e04fd0)), closes [#533](https://github.com/bottrall/riffer-rig/issues/533)
125
+ * **tools:** treat a missing background job output file as empty ([#402](https://github.com/bottrall/riffer-rig/issues/402)) ([8464463](https://github.com/bottrall/riffer-rig/commit/846446329657c644e6784c7e8d772ff6d3814047)), closes [#392](https://github.com/bottrall/riffer-rig/issues/392)
126
+
127
+
128
+ ### Documentation
129
+
130
+ * describe the Loader::Options and Credentials.install APIs ([#411](https://github.com/bottrall/riffer-rig/issues/411)) ([a3bb5a4](https://github.com/bottrall/riffer-rig/commit/a3bb5a43d0418042919743c3765a99c034f73321)), closes [#387](https://github.com/bottrall/riffer-rig/issues/387)
131
+
132
+ ## [0.12.0](https://github.com/bottrall/riffer-rig/compare/v0.11.0...v0.12.0) (2026-10-07)
133
+
134
+
135
+ ### Features
136
+
137
+ * --json streams every Runtime event as NDJSON ([#231](https://github.com/bottrall/riffer-rig/issues/231)) ([a5e4641](https://github.com/bottrall/riffer-rig/commit/a5e464172cb84fcbfc2fbce0a311c070b54a539a))
138
+ * /resume picker and /new in the terminal ([#232](https://github.com/bottrall/riffer-rig/issues/232)) ([140fbac](https://github.com/bottrall/riffer-rig/commit/140fbac7c7fc966987ee77c78222204bb755e37f))
139
+ * ACP session/load and session/list ([#237](https://github.com/bottrall/riffer-rig/issues/237)) ([db81553](https://github.com/bottrall/riffer-rig/commit/db815536fa940d3f14615fa55b27af63164665ce))
140
+ * resolve secret MCP headers from env and auth.json ([#234](https://github.com/bottrall/riffer-rig/issues/234)) ([6253f95](https://github.com/bottrall/riffer-rig/commit/6253f95932b81e276cec0850f7aa48abdb332b63))
141
+ * riffer acp serves the Runtime over ACP ([#235](https://github.com/bottrall/riffer-rig/issues/235)) ([9497122](https://github.com/bottrall/riffer-rig/commit/9497122cc0cdac3576481f6efeda6e49f595d999))
142
+
3
143
  ## [0.11.0](https://github.com/bottrall/riffer-rig/compare/v0.10.0...v0.11.0) (2026-10-06)
4
144
 
5
145
 
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # riffer-rig
2
2
 
3
- A dead-simple terminal coding agent built on [riffer](https://github.com/janeapp/riffer).
3
+ **riffer, in your terminal and in your process.**
4
4
 
5
- `riffer-rig` is an interactive terminal coding agent with read, write, edit, and bash tools — point it at your project and chat with it from the command line.
5
+ `riffer-rig` is a general-purpose agent for Ruby developers who want to own their harness. It runs as a terminal agent and, because the runtime is separate from the terminal, it also runs inside any Ruby process: a Rails app, a script, a job. You extend it in Ruby: tools, commands, providers and hooks are ordinary Ruby classes on [riffer](https://github.com/janeapp/riffer)'s primitives, and the same objects work whether the host is the terminal or your app. It ships with a coding toolkit (read, write, edit, bash) as the default bundle, because a shell and file access are the most efficient way to get almost any task done — but the prompt gives it no coding identity. [Overview](docs/OVERVIEW.md) has the full thesis.
6
6
 
7
7
  ## Requirements
8
8
 
@@ -48,10 +48,11 @@ The model is the first of these that is set: `--model`, `RIFFER_MODEL`, `model`
48
48
  | `--max-steps N` | stops a turn after `N` model calls |
49
49
  | `--no-save` | does not save this session to the [store](docs/SESSIONS.md) |
50
50
  | `-c`, `--continue` | continues the most recent session in this directory ([Sessions](docs/SESSIONS.md#resuming)) |
51
- | `-r ID`, `--resume ID` | resumes the session with id `ID` ([Sessions](docs/SESSIONS.md#resuming)) |
51
+ | `-r [ID]`, `--resume [ID]` | resumes the session with id `ID`; bare `-r` opens the [picker](docs/SESSIONS.md#the-picker) ([Sessions](docs/SESSIONS.md#resuming)) |
52
52
  | `-h`, `--help` | prints the usage |
53
+ | `-v`, `--version` | prints the version |
53
54
 
54
- `riffer acp` (an editor's agent over stdio) is reserved: for now it prints the usage and exits with status 2.
55
+ An editor registers the agent as `riffer acp`, the same Runtimes over the [Agent Client Protocol](https://agentclientprotocol.com) on stdio ([ACP](docs/ACP.md)).
55
56
 
56
57
  ### Headless
57
58
 
@@ -63,20 +64,23 @@ git diff | riffer -p "review this diff" # piped stdin appended as context
63
64
  echo "explain this diff" | riffer -p # piped stdin alone is the prompt
64
65
  ```
65
66
 
66
- Everything loads exactly as the REPL does, the shared flags work the same — `-c` and `-r` included: `riffer -p -c "now run the tests"` continues the most recent session in this directory, and a missing session exits 2 ([Headless](docs/HEADLESS.md)). The session is saved like any other unless `--no-save`. Only the assistant's text is printed, streamed to stdout; errors and warnings go to stderr, and `--verbose` adds a one-line trace of each tool call there. Headless never prompts: a missing model, credential, or SDK prints the reason on stderr and exits 2.
67
+ Everything loads exactly as the REPL does, the shared flags work the same — `-c` and `-r` included: `riffer -p -c "now run the tests"` continues the most recent session in this directory, and a missing session exits 2 ([Headless](docs/HEADLESS.md)). The session is saved like any other unless `--no-save`. Only the assistant's text is printed, streamed to stdout; errors and warnings go to stderr, and `--verbose` adds a one-line trace of each tool call there. With `--json`, stdout is instead one JSON object per line for every Runtime event — the NDJSON stream ([Headless](docs/HEADLESS.md#the-ndjson-stream---json)). A run whose model leaves background jobs running waits for them, giving the model a further turn as each one exits, and kills any left after `--job-idle-timeout` seconds (600 by default) without an exit ([Headless](docs/HEADLESS.md#background-jobs)). Headless never prompts: a missing model, credential, or SDK prints the reason on stderr and exits 2.
67
68
 
68
- The exit code says how the turn ended: `0` finished, `1` runtime error, `2` usage or configuration, `3` the turn ended without completing (`--max-steps`, a full context window, a provider content filter), `130` SIGINT (the turn is cancelled first).
69
+ The exit code says how the turn ended: `0` finished, `1` runtime error, `2` usage or configuration, `3` the turn ended without completing (`--max-steps`, a full context window, a provider content filter) or its background jobs passed the idle timeout, `130` SIGINT (the turn is cancelled first).
69
70
 
70
71
  ### In the session
71
72
 
72
- Type a prompt and press Enter; the reply streams in, with each tool call and the first line of its result, and every turn ends with a token line (`↑in · ↓out · session N tok`, plus the session cost when the model is [priced](docs/CONFIGURATION.md#models)).
73
+ Type a prompt and press Enter. While the turn runs, the status line under the input shows its time, steps, tool calls, tokens and cost, and Ctrl-T peeks at what the model is writing; the reply is printed when the turn ends, followed by a stat line (`N steps · mm:ss · ↑in · ↓out · session N tok`, plus the turn's cost and the session's when the model is [priced](docs/CONFIGURATION.md#models)). The input line stays open throughout: a message sent during a turn is queued and runs when the turn ends. [Terminal](docs/TERMINAL.md) has every key.
73
74
 
74
- - Ctrl-C during a turn cancels it and returns to the prompt. Ctrl-C at the prompt asks for a second one, which exits.
75
- - `/exit` or `/quit` ends the session, as does Ctrl-D.
76
- - `/model provider/name` switches the model ([below](#switching-the-model)), and `/skill:<name> [text]` runs a skill ([Skills](docs/SKILLS.md)).
77
- - Any other `/name args` runs the Runtime command of that name, such as one an extension registers ([Extensions](docs/EXTENSIONS.md)); an unknown name is reported and nothing is sent to the model.
75
+ - Ctrl-C during a turn cancels it. Ctrl-C with no turn running asks for a second one, which exits.
76
+ - `/exit` or `/quit` ends the session, as does Ctrl-D on an empty line.
77
+ - `/help` lists the session's slash commands. `/resume [--all]`, `/new`, `/cost`, `/trace`, `/skill:<name>` and the others are described in [Terminal](docs/TERMINAL.md#commands); `/model` is covered [below](#switching-the-model).
78
78
 
79
- ### Authentication
79
+ ### Switching the model
80
+
81
+ `/model provider/name` switches the model for the current session only, keeping the conversation so far, and confirms it in one line: `/model openai/gpt-5` prints `Model switched to openai/gpt-5`. The provider prefix is required: a bare name such as `/model sonnet` is rejected with the list of providers. `/model` alone shows the model in use. Switching runs the same setup for the new provider as startup does: its SDK gem is offered for install (or refused with the exact Gemfile line), and missing credentials are resolved — you are prompted for them when the host can ask, and the values apply to the running session immediately. The switch is refused with one error when the host cannot supply what is missing, and the model is left unchanged. `/model --save` writes the model in effect to the home `settings.json`, so new sessions start with it; `/model provider/name --save` switches and saves in one step, printing `Model switched to openai/gpt-5 and saved to ~/.riffer/settings.json` (a bare `/model --save` prints `Saved openai/gpt-5 to ~/.riffer/settings.json`), and a refused switch saves nothing ([Configuration](docs/CONFIGURATION.md#model)).
82
+
83
+ ## Authentication
80
84
 
81
85
  `riffer-rig` talks to the provider named by the model's prefix — `anthropic/claude-sonnet-4-6` means Anthropic. Provide that provider's credentials in either of two ways:
82
86
 
@@ -107,33 +111,93 @@ The flat `{"anthropic": "sk-…"}` shape earlier versions wrote is no longer rea
107
111
 
108
112
  Inside a session, `/auth` lists every provider with where its secret comes from — `env`, `stored`, `chain` (the SDK's own credential chain, for Bedrock) or `missing`. `/auth <provider>` re-runs that provider's setup, which is how you rotate a key, and applies the new values to the current session, so the next request uses them. `/auth remove <provider>` deletes the provider's `auth.json` entry and its `providers` block in settings.
109
113
 
110
- ### Switching the model
114
+ ## Configuration
111
115
 
112
- `/model provider/name` switches the model for the current session only, keeping the conversation so far — `/model openai/gpt-5`, say. The provider prefix is required: a bare name such as `/model sonnet` is rejected with the list of providers. `/model` alone shows the model in use. Switching runs the same setup for the new provider as startup does: its SDK gem is offered for install (or refused with the exact Gemfile line), and missing credentials are resolved — you are prompted for them when the host can ask, and the values apply to the running session immediately. The switch is refused with one error when the host cannot supply what is missing, and the model is left unchanged. `/model --save` writes the model in effect to the home `settings.json`, so new sessions start with it; `/model provider/name --save` switches and saves in one step, and a refused switch saves nothing ([Configuration](docs/CONFIGURATION.md#model)).
116
+ Settings live in two scopes, both optional: `~/.riffer/settings.json` for every project, and `<cwd>/.riffer/settings.json` for one project, merged key by key with the project winning ([Configuration](docs/CONFIGURATION.md)). Every core key is optional:
113
117
 
114
- ### Configuration
118
+ | Key | What it sets |
119
+ | ------------ | -------------------------------------------------------------------------------- |
120
+ | `model` | the model new sessions start with, as `provider/name` |
121
+ | `reasoning` | the reasoning effort, translated to the provider's own parameter |
122
+ | `models` | prices each model in USD per million tokens |
123
+ | `providers` | non-secret provider fields such as an endpoint or region (home file only) |
124
+ | `extensions` | `disabled` — bundled extensions to leave out; `autoload` — gem extension autoload |
125
+ | `reload` | `"auto"` (default) or `"manual"` — the hot-reload trigger |
126
+ | `sessions` | `save: false` stops saving sessions to the store |
127
+ | `tools` | the provider-native tool switches (`native`), off by default |
115
128
 
116
- - `AGENTS.md` — `~/.riffer/AGENTS.md` and an `AGENTS.md` in the current working directory or any directory above it, whichever exist, are re-read every turn as instructions that take precedence over the default norms ([Instructions](docs/INSTRUCTIONS.md#agentsmd)).
117
- - Skills — Agent Skills in `.agents/skills/` from the current working directory up to the repository root, and in `~/.agents/skills/`, are offered to the model, and each can be run with `/skill:<name>` ([Skills](docs/SKILLS.md)).
118
129
  - `RIFFER_MODEL` — the model for this run as `provider/name`, winning over the `model` setting. A bare name such as `sonnet` is rejected with the list of providers.
119
- - `~/.riffer/settings.json` — optional user settings, and `<cwd>/.riffer/settings.json` for one project, merged key by key with the project winning. Every key is optional:
120
-
121
- ```json
122
- {
123
- "model": "anthropic/claude-sonnet-4-6",
124
- "reasoning": "low",
125
- "models": {
126
- "anthropic/claude-sonnet-4-6": {
127
- "input": 3.0,
128
- "output": 15.0,
129
- "cache_write": 3.75,
130
- "cache_read": 0.3
131
- }
132
- }
133
- }
134
- ```
135
-
136
- `model` is the model new sessions start with; a host built on the [Loader](docs/EMBEDDING.md#building-a-runtime-with-the-loader) asks for one when none is set and writes the answer here. `extensions.disabled` (for example `["mcp"]`) leaves bundled extensions out. `models` prices each model in USD per million tokens; [Configuration](docs/CONFIGURATION.md) has every key. `reasoning` is translated to the provider's own parameter — Anthropic accepts `low`, `medium`, `high`, `xhigh` and `max`; OpenAI and OpenRouter accept `low`, `medium`, `high` and `xhigh`. Omitting it, or supplying an unrecognised value, leaves the model's default reasoning behaviour unchanged.
130
+ - `AGENTS.md` — `~/.riffer/AGENTS.md` and an `AGENTS.md` in the current working directory or any directory above it are re-read every turn as instructions that take precedence over the default norms ([Instructions](docs/INSTRUCTIONS.md#agentsmd)).
131
+ - Skills — Agent Skills in `.agents/skills/` from the working directory up to the repository root, and in `~/.agents/skills/`, are offered to the model, and `/skill:<name> [text]` runs one ([Skills](docs/SKILLS.md)).
132
+ - MCP servers — declared under the `mcp` key in either settings file and registered with the Runtime ([MCP](docs/MCP.md)).
133
+
134
+ ## Extending
135
+
136
+ An extension is a named registrar block in a `rig.rb` file — `~/.riffer/rig.rb` runs in every project, `<project>/.riffer/rig.rb` in one, and the first run of a project file asks you to trust it:
137
+
138
+ ```ruby
139
+ Riffer::Rig.extension('git') do |rig|
140
+ # A tool the model can call
141
+ rig.tool GitLog
142
+
143
+ # A /log command in the session
144
+ rig.command('log', description: 'Recent commits') do |ctx|
145
+ ctx.say `git log --oneline -n #{ctx.args}`
146
+ end
147
+
148
+ # A section appended to the system message, re-read every turn
149
+ rig.prompt(:branch) { |ctx| "Branch: #{`git branch --show-current`}" }
150
+ end
151
+ ```
152
+
153
+ Tools, commands, prompt sections, event handlers, skills, MCP servers and providers register the same way, and the same objects work whether the host is the terminal or your app. [Extensions](docs/EXTENSIONS.md) has all eight seams, error isolation, and packaging an extension as a gem.
154
+
155
+ ## Embedding
156
+
157
+ The runtime is separate from the terminal, so the same agent runs inside any Ruby process:
158
+
159
+ ```ruby
160
+ runtime = Riffer::Rig::Loader.runtime(cwd: Dir.pwd, host: Riffer::Rig::Hosts::Null.new)
161
+ response = runtime.ask('why is this test failing?')
162
+ puts response.content
163
+ ```
164
+
165
+ `Loader.runtime` applies the same filesystem conventions as the terminal — settings, credentials, `rig.rb`, skills. [Embedding](docs/EMBEDDING.md) has the streaming `prompt`, snapshots, and rebuilding after a code reload.
166
+
167
+ ## Documentation
168
+
169
+ The guides, in reading order:
170
+
171
+ Start here:
172
+
173
+ - [Overview](https://riffer.bottrall.dev/guides/overview/) — What riffer-rig is, the four tiers, the runtime and host layers
174
+ - [Getting started](https://riffer.bottrall.dev/guides/getting-started/) — Install, pick a model, first session
175
+
176
+ Using the terminal:
177
+
178
+ - [Terminal](https://riffer.bottrall.dev/guides/terminal/) — The input line and its keys, queueing, the status line, peek, resume replay
179
+ - [Configuration](https://riffer.bottrall.dev/guides/configuration/) — Settings scopes and every core key
180
+ - [Instructions](https://riffer.bottrall.dev/guides/instructions/) — How the system message is built; AGENTS.md
181
+ - [Tools](https://riffer.bottrall.dev/guides/tools/) — The bundled toolkit and provider-native tools
182
+ - [Skills](https://riffer.bottrall.dev/guides/skills/) — Agent Skills directories and activation
183
+ - [MCP](https://riffer.bottrall.dev/guides/mcp/) — Declaring MCP servers
184
+ - [Sessions](https://riffer.bottrall.dev/guides/sessions/) — Saving, resuming, the picker, the JSONL store
185
+ - [Reloading](https://riffer.bottrall.dev/guides/reloading/) — The /reload command, what reloads and what does not
186
+ - [Headless](https://riffer.bottrall.dev/guides/headless/) — riffer -p, NDJSON, exit codes
187
+ - [ACP](https://riffer.bottrall.dev/guides/acp/) — riffer acp, the ACP agent over stdio
188
+
189
+ Extending and embedding:
190
+
191
+ - [Extensions](https://riffer.bottrall.dev/guides/extensions/) — rig.rb, the registrar, the eight seams, commands, handlers, gems
192
+ - [Embedding](https://riffer.bottrall.dev/guides/embedding/) — Runtime and Loader from Ruby; snapshots; rebuild
193
+ - [Hosts](https://riffer.bottrall.dev/guides/hosts/) — The Host interface and writing a host
194
+
195
+ Providers:
196
+
197
+ - [Providers](https://riffer.bottrall.dev/guides/providers/overview/) — Model strings, precedence, credentials, /auth
198
+ - [Custom providers](https://riffer.bottrall.dev/guides/providers/custom/) — Registering a provider from an extension; the setup, credentials, listings
199
+
200
+ The guide sources are in `docs/`. To preview the site locally, run `bin/docs serve` and open <http://localhost:8000>.
137
201
 
138
202
  ## Development
139
203
 
@@ -150,15 +214,14 @@ Every project chore is a script in `bin/`. The Rakefile behind them is an implem
150
214
  | `bin/ci` | Run everything CI runs, serially. Use before pushing |
151
215
  | `bin/build` | Build the gem into `pkg/`; the publish workflow runs this before `gem push` |
152
216
  | `bin/docs` | Build the docs site and API reference into `_site/`; `bin/docs serve` serves it at http://localhost:8000 |
153
- | `bin/plans` | Serve the building plans in `plans/` at http://localhost:8001 |
154
217
 
155
218
  ## Releasing
156
219
 
157
220
  PR titles are [conventional commits](https://www.conventionalcommits.org/) and are linted in CI: `feat:` bumps the minor version, `fix:` bumps the patch, and `feat!:` marks a breaking change (also a minor bump while we are on 0.x). `chore:`, `docs:`, `ci:`, `refactor:` and `test:` never release. Squash-merging makes the title the commit on `main`.
158
221
 
159
- [release-please](https://github.com/googleapis/release-please) keeps a release PR open that bumps `lib/riffer/rig/version.rb` and writes `CHANGELOG.md`. Merging that PR tags `vX.Y.Z`, creates the GitHub Release and publishes the gem to RubyGems.org through Trusted Publishing; nothing is pushed by hand.
222
+ A PR whose code nothing in the live path reaches yet is titled `refactor:`, including fixes to such code; the PR that wires it in carries the `feat:` or `fix:`, titled for what the user gets. The changelog and GitHub Release are generated from titles, so a `feat:` on unreachable code advertises a feature nobody can use.
160
223
 
161
- riffer is pinned to one minor (`~> 0.49.0`) because its 0.x minors may break. When Dependabot opens the riffer bump, retitle it `feat(deps):` or `fix(deps):` before merging so it releases and appears in the changelog.
224
+ [release-please](https://github.com/googleapis/release-please) keeps a release PR open that bumps `lib/riffer/rig/version.rb` and writes `CHANGELOG.md`. Merging that PR tags `vX.Y.Z`, creates the GitHub Release and publishes the gem to RubyGems.org through Trusted Publishing; nothing is pushed by hand.
162
225
 
163
226
  ## Contributing
164
227
 
@@ -174,4 +237,4 @@ Licensed under the MIT License. See [`LICENSE.txt`](LICENSE.txt) for details.
174
237
 
175
238
  ## Maintainer
176
239
 
177
- - Jake Bottrall - https://github.com/bottrall
240
+ - Jake Bottrall - https://github.com/bottrall
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'acp/sdk'
4
+ require 'securerandom'
5
+
6
+ class Riffer::Rig::ACP::Host
7
+ include Riffer::Rig::Hosts::NonInteractive
8
+
9
+ CAPABILITIES = Set[:notify, :ask, :confirm].freeze #: Set[Symbol]
10
+ BUILDING_CAPABILITIES = Set[:notify].freeze #: Set[Symbol]
11
+
12
+ # @rbs @client: ::ACP::AgentConnection::Client
13
+ # @rbs @session_id: String?
14
+ # @rbs @buffered: Array[::ACP::Types::SessionUpdate::t]
15
+ # @rbs @lock: Thread::Mutex
16
+
17
+ # @dynamic client=
18
+ attr_writer :client #: ::ACP::AgentConnection::Client
19
+
20
+ # @rbs client: ::ACP::AgentConnection::Client
21
+ # @rbs return: void
22
+ def initialize(client:)
23
+ @client = client
24
+ @session_id = nil
25
+ @buffered = []
26
+ @lock = Mutex.new
27
+ end
28
+
29
+ # A request to the client names its session, so nothing can be relayed
30
+ # until the agent sets the id.
31
+ # @rbs return: Set[Symbol]
32
+ def capabilities
33
+ @session_id ? CAPABILITIES : BUILDING_CAPABILITIES
34
+ end
35
+
36
+ # @rbs question: String?
37
+ # @rbs options: Array[String]?
38
+ # @rbs secret: bool
39
+ # @rbs return: String?
40
+ def ask(question = nil, options: nil, secret: false)
41
+ id = @session_id
42
+ # ACP forbids asking for a secret in a form elicitation, and rig serves no
43
+ # URL for the URL mode to open.
44
+ return super unless id && !secret
45
+ return elicit(id, question.to_s) unless options
46
+
47
+ selected = permit(id, question.to_s, Riffer::Rig::ACP::Mapper.choices(options))
48
+ selected if options.include?(selected)
49
+ end
50
+
51
+ # @rbs question: String?
52
+ # @rbs return: bool
53
+ def confirm(question = nil)
54
+ id = @session_id
55
+ return super unless id
56
+
57
+ permit(id, question.to_s, Riffer::Rig::ACP::Mapper::CONFIRM_OPTIONS) == Riffer::Rig::ACP::Mapper::CONFIRMED
58
+ end
59
+
60
+ # @rbs message: String?
61
+ # @rbs level: Symbol
62
+ # @rbs return: void
63
+ def notify(message = nil, level: :info)
64
+ update(Riffer::Rig::ACP::Mapper.notice(message.to_s))
65
+ end
66
+
67
+ # @rbs update: ::ACP::Types::SessionUpdate::t
68
+ # @rbs return: void
69
+ def update(update)
70
+ # A job's exit reaches here on the job's own thread, racing session_id= for
71
+ # the buffer.
72
+ @lock.synchronize do
73
+ id = @session_id
74
+ id ? @client.update(id, update) : @buffered << update
75
+ end
76
+ end
77
+
78
+ # @rbs label: String?
79
+ # @rbs &block: ? () -> void
80
+ # @rbs return: void
81
+ def progress(label = nil, &block)
82
+ notify(label) if label
83
+ block&.call
84
+ end
85
+
86
+ # Session updates name their session, and acp-sdk runs session_created after
87
+ # the session/new reply so the client knows the id before any update for it
88
+ # arrives — that is why the build-time notifies wait for this, not for the
89
+ # Runtime's construction to end.
90
+ # @rbs id: String
91
+ # @rbs return: void
92
+ def session_id=(id)
93
+ @lock.synchronize do
94
+ @session_id = id
95
+ @buffered.each { |update| @client.update(id, update) }
96
+ @buffered = []
97
+ end
98
+ end
99
+
100
+ private
101
+
102
+ # @rbs id: String
103
+ # @rbs question: String
104
+ # @rbs options: Array[::ACP::Types::PermissionOption]
105
+ # @rbs return: String?
106
+ def permit(id, question, options)
107
+ # An adopting connection can replace @client while the question is out, and
108
+ # only the client that was asked knows the tool call to close.
109
+ client = @client
110
+ # A permission request must name a tool call, and a host question has none.
111
+ call_id = SecureRandom.uuid
112
+ client.update(id, Riffer::Rig::ACP::Mapper.permission_call(call_id, question))
113
+ request = Riffer::Rig::ACP::Mapper.permission_request(id, call_id, question, options)
114
+ selected = Riffer::Rig::ACP::Mapper.selected_option(client.request_permission(request))
115
+ client.update(id, Riffer::Rig::ACP::Mapper.permission_done(call_id, selected))
116
+ selected
117
+ end
118
+
119
+ # @rbs id: String
120
+ # @rbs question: String
121
+ # @rbs return: String?
122
+ def elicit(id, question)
123
+ request = Riffer::Rig::ACP::Mapper.elicitation_request(id, question)
124
+ Riffer::Rig::ACP::Mapper.elicited_answer(@client.create_elicitation(request))
125
+ end
126
+ end