riffer-rig 0.12.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 (303) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +129 -0
  3. data/README.md +12 -12
  4. data/lib/riffer/rig/acp/host.rb +67 -24
  5. data/lib/riffer/rig/acp/mapper.rb +242 -0
  6. data/lib/riffer/rig/acp.rb +125 -122
  7. data/lib/riffer/rig/bundled/bash.rb +5 -1
  8. data/lib/riffer/rig/cli/flags.rb +52 -32
  9. data/lib/riffer/rig/cli/sessions.rb +52 -29
  10. data/lib/riffer/rig/cli.rb +24 -13
  11. data/lib/riffer/rig/command/context.rb +1 -1
  12. data/lib/riffer/rig/command.rb +4 -2
  13. data/lib/riffer/rig/commands/auth.rb +23 -23
  14. data/lib/riffer/rig/commands/cost.rb +59 -0
  15. data/lib/riffer/rig/commands/model.rb +24 -18
  16. data/lib/riffer/rig/commands/reload.rb +1 -1
  17. data/lib/riffer/rig/commands/skill.rb +1 -1
  18. data/lib/riffer/rig/commands/trace/replay.rb +88 -0
  19. data/lib/riffer/rig/commands/trace.rb +25 -0
  20. data/lib/riffer/rig/credentials/provider_fields.rb +47 -0
  21. data/lib/riffer/rig/credentials.rb +94 -48
  22. data/lib/riffer/rig/env.rb +1 -1
  23. data/lib/riffer/rig/events/after_response.rb +4 -11
  24. data/lib/riffer/rig/events/after_tool_call.rb +15 -13
  25. data/lib/riffer/rig/events/before_prompt.rb +4 -11
  26. data/lib/riffer/rig/events/before_request.rb +4 -11
  27. data/lib/riffer/rig/events/before_tool_call.rb +12 -13
  28. data/lib/riffer/rig/events/command_output.rb +4 -11
  29. data/lib/riffer/rig/events/job_exit.rb +28 -0
  30. data/lib/riffer/rig/events/notify.rb +4 -11
  31. data/lib/riffer/rig/events/session_end.rb +4 -11
  32. data/lib/riffer/rig/events/session_start.rb +4 -11
  33. data/lib/riffer/rig/events/skill_activated.rb +4 -11
  34. data/lib/riffer/rig/events/turn_end.rb +4 -11
  35. data/lib/riffer/rig/extension.rb +5 -4
  36. data/lib/riffer/rig/headless/host.rb +2 -14
  37. data/lib/riffer/rig/headless/ndjson.rb +1 -1
  38. data/lib/riffer/rig/headless.rb +120 -26
  39. data/lib/riffer/rig/hosts/mirror.rb +8 -5
  40. data/lib/riffer/rig/hosts/non_interactive.rb +24 -0
  41. data/lib/riffer/rig/hosts/null.rb +2 -21
  42. data/lib/riffer/rig/loader/credentials.rb +23 -0
  43. data/lib/riffer/rig/loader/extension_source.rb +177 -0
  44. data/lib/riffer/rig/loader/options.rb +35 -0
  45. data/lib/riffer/rig/loader.rb +96 -329
  46. data/lib/riffer/rig/mcp/auth.rb +3 -1
  47. data/lib/riffer/rig/mcp/declaration.rb +1 -1
  48. data/lib/riffer/rig/provider_setup.rb +2 -2
  49. data/lib/riffer/rig/providers.rb +5 -0
  50. data/lib/riffer/rig/registrar.rb +1 -1
  51. data/lib/riffer/rig/runtime/abort.rb +66 -0
  52. data/lib/riffer/rig/runtime/concurrency.rb +71 -0
  53. data/lib/riffer/rig/runtime/error_message.rb +27 -0
  54. data/lib/riffer/rig/runtime/hooks.rb +6 -2
  55. data/lib/riffer/rig/runtime/job_completion.rb +31 -0
  56. data/lib/riffer/rig/runtime/job_envelope.rb +36 -0
  57. data/lib/riffer/rig/runtime/job_inbox.rb +74 -0
  58. data/lib/riffer/rig/runtime/job_notification.rb +31 -0
  59. data/lib/riffer/rig/runtime/mcp_registrar.rb +91 -0
  60. data/lib/riffer/rig/runtime/request_guardrail.rb +1 -1
  61. data/lib/riffer/rig/runtime/snapshot.rb +80 -0
  62. data/lib/riffer/rig/runtime/system_prompt.rb +56 -0
  63. data/lib/riffer/rig/runtime/tool_runtime.rb +47 -7
  64. data/lib/riffer/rig/runtime/usage.rb +19 -0
  65. data/lib/riffer/rig/runtime.rb +329 -243
  66. data/lib/riffer/rig/sdk.rb +29 -7
  67. data/lib/riffer/rig/settings/file.rb +27 -0
  68. data/lib/riffer/rig/settings/model_options.rb +64 -0
  69. data/lib/riffer/rig/settings.rb +0 -129
  70. data/lib/riffer/rig/stores/entries.rb +23 -0
  71. data/lib/riffer/rig/stores/header.rb +3 -17
  72. data/lib/riffer/rig/stores/jsonl.rb +7 -6
  73. data/lib/riffer/rig/stores/message_entry.rb +10 -10
  74. data/lib/riffer/rig/stores/model_entry.rb +10 -10
  75. data/lib/riffer/rig/stores/recorder.rb +34 -13
  76. data/lib/riffer/rig/stores/skill_entry.rb +10 -10
  77. data/lib/riffer/rig/stores/stamped.rb +9 -0
  78. data/lib/riffer/rig/stores/timestamp.rb +23 -0
  79. data/lib/riffer/rig/support/json_file.rb +53 -0
  80. data/lib/riffer/rig/support/typed_value/schema.rb +16 -0
  81. data/lib/riffer/rig/support/typed_value.rb +17 -0
  82. data/lib/riffer/rig/terminal/autocomplete.rb +133 -0
  83. data/lib/riffer/rig/terminal/banner.rb +48 -11
  84. data/lib/riffer/rig/terminal/blocking_prompter.rb +37 -0
  85. data/lib/riffer/rig/terminal/builtin.rb +16 -0
  86. data/lib/riffer/rig/terminal/columns.rb +63 -0
  87. data/lib/riffer/rig/terminal/console.rb +49 -0
  88. data/lib/riffer/rig/terminal/echo.rb +26 -0
  89. data/lib/riffer/rig/terminal/equalizer.rb +20 -0
  90. data/lib/riffer/rig/terminal/frame.rb +339 -0
  91. data/lib/riffer/rig/terminal/frame_prompter.rb +63 -0
  92. data/lib/riffer/rig/terminal/help.rb +41 -0
  93. data/lib/riffer/rig/terminal/host.rb +7 -28
  94. data/lib/riffer/rig/terminal/job_counter.rb +33 -0
  95. data/lib/riffer/rig/terminal/job_exit_notice.rb +11 -0
  96. data/lib/riffer/rig/terminal/key.rb +38 -0
  97. data/lib/riffer/rig/terminal/key_decoder.rb +219 -0
  98. data/lib/riffer/rig/terminal/key_pipeline.rb +111 -0
  99. data/lib/riffer/rig/terminal/line_editor.rb +183 -0
  100. data/lib/riffer/rig/terminal/markdown/blocks.rb +96 -0
  101. data/lib/riffer/rig/terminal/markdown/flow.rb +77 -0
  102. data/lib/riffer/rig/terminal/markdown/inline.rb +85 -0
  103. data/lib/riffer/rig/terminal/markdown/span.rb +25 -0
  104. data/lib/riffer/rig/terminal/markdown/table.rb +166 -0
  105. data/lib/riffer/rig/terminal/markdown.rb +187 -0
  106. data/lib/riffer/rig/terminal/message_queue/message.rb +13 -0
  107. data/lib/riffer/rig/terminal/message_queue.rb +27 -0
  108. data/lib/riffer/rig/terminal/opening.rb +50 -0
  109. data/lib/riffer/rig/terminal/peek.rb +74 -0
  110. data/lib/riffer/rig/terminal/picker.rb +47 -22
  111. data/lib/riffer/rig/terminal/question.rb +37 -0
  112. data/lib/riffer/rig/terminal/quiet_display.rb +48 -0
  113. data/lib/riffer/rig/terminal/renderer.rb +19 -250
  114. data/lib/riffer/rig/terminal/repl.rb +242 -0
  115. data/lib/riffer/rig/terminal/replay/turn.rb +23 -0
  116. data/lib/riffer/rig/terminal/replay.rb +76 -0
  117. data/lib/riffer/rig/terminal/session.rb +2 -6
  118. data/lib/riffer/rig/terminal/tally.rb +12 -0
  119. data/lib/riffer/rig/terminal/theme.rb +34 -1
  120. data/lib/riffer/rig/terminal/ticker.rb +189 -0
  121. data/lib/riffer/rig/terminal/ticker_display.rb +91 -0
  122. data/lib/riffer/rig/terminal/turn_buffer/stats.rb +19 -0
  123. data/lib/riffer/rig/terminal/turn_buffer.rb +133 -0
  124. data/lib/riffer/rig/terminal/turn_report.rb +100 -0
  125. data/lib/riffer/rig/terminal/wrapper.rb +46 -62
  126. data/lib/riffer/rig/terminal.rb +192 -104
  127. data/lib/riffer/rig/tools/bash/capture.rb +58 -0
  128. data/lib/riffer/rig/tools/bash/job.rb +84 -0
  129. data/lib/riffer/rig/tools/bash/job_log.rb +117 -0
  130. data/lib/riffer/rig/tools/bash/jobs.rb +197 -0
  131. data/lib/riffer/rig/tools/bash/kill.rb +24 -0
  132. data/lib/riffer/rig/tools/bash/kill_group.rb +15 -0
  133. data/lib/riffer/rig/tools/bash/monotonic_clock.rb +8 -0
  134. data/lib/riffer/rig/tools/bash/output.rb +30 -0
  135. data/lib/riffer/rig/tools/bash/truncation.rb +12 -0
  136. data/lib/riffer/rig/tools/bash.rb +42 -29
  137. data/lib/riffer/rig/tools/read.rb +2 -2
  138. data/lib/riffer/rig/trust.rb +9 -18
  139. data/lib/riffer/rig/version.rb +1 -1
  140. data/sig/generated/riffer/rig/acp/host.rbs +29 -8
  141. data/sig/generated/riffer/rig/acp/mapper.rbs +108 -0
  142. data/sig/generated/riffer/rig/acp.rbs +46 -53
  143. data/sig/generated/riffer/rig/cli/flags.rbs +17 -18
  144. data/sig/generated/riffer/rig/cli/sessions.rbs +25 -11
  145. data/sig/generated/riffer/rig/cli.rbs +6 -3
  146. data/sig/generated/riffer/rig/command.rbs +5 -3
  147. data/sig/generated/riffer/rig/commands/auth.rbs +3 -7
  148. data/sig/generated/riffer/rig/commands/cost.rbs +31 -0
  149. data/sig/generated/riffer/rig/commands/model.rbs +2 -0
  150. data/sig/generated/riffer/rig/commands/trace/replay.rbs +53 -0
  151. data/sig/generated/riffer/rig/commands/trace.rbs +14 -0
  152. data/sig/generated/riffer/rig/credentials/provider_fields.rbs +26 -0
  153. data/sig/generated/riffer/rig/credentials.rbs +36 -15
  154. data/sig/generated/riffer/rig/events/after_response.rbs +3 -7
  155. data/sig/generated/riffer/rig/events/after_tool_call.rbs +14 -9
  156. data/sig/generated/riffer/rig/events/before_prompt.rbs +3 -7
  157. data/sig/generated/riffer/rig/events/before_request.rbs +3 -7
  158. data/sig/generated/riffer/rig/events/before_tool_call.rbs +11 -9
  159. data/sig/generated/riffer/rig/events/command_output.rbs +3 -7
  160. data/sig/generated/riffer/rig/events/job_exit.rbs +24 -0
  161. data/sig/generated/riffer/rig/events/notify.rbs +3 -7
  162. data/sig/generated/riffer/rig/events/session_end.rbs +3 -7
  163. data/sig/generated/riffer/rig/events/session_start.rbs +3 -7
  164. data/sig/generated/riffer/rig/events/skill_activated.rbs +3 -7
  165. data/sig/generated/riffer/rig/events/turn_end.rbs +3 -7
  166. data/sig/generated/riffer/rig/extension.rbs +3 -3
  167. data/sig/generated/riffer/rig/headless/host.rbs +2 -10
  168. data/sig/generated/riffer/rig/headless.rbs +41 -10
  169. data/sig/generated/riffer/rig/hosts/mirror.rbs +7 -6
  170. data/sig/generated/riffer/rig/hosts/non_interactive.rbs +18 -0
  171. data/sig/generated/riffer/rig/hosts/null.rbs +2 -15
  172. data/sig/generated/riffer/rig/loader/credentials.rbs +12 -0
  173. data/sig/generated/riffer/rig/loader/extension_source.rbs +89 -0
  174. data/sig/generated/riffer/rig/loader/options.rbs +25 -0
  175. data/sig/generated/riffer/rig/loader.rbs +28 -134
  176. data/sig/generated/riffer/rig/provider_setup.rbs +1 -1
  177. data/sig/generated/riffer/rig/providers.rbs +3 -0
  178. data/sig/generated/riffer/rig/runtime/abort.rbs +36 -0
  179. data/sig/generated/riffer/rig/runtime/concurrency.rbs +41 -0
  180. data/sig/generated/riffer/rig/runtime/error_message.rbs +13 -0
  181. data/sig/generated/riffer/rig/runtime/hooks.rbs +3 -1
  182. data/sig/generated/riffer/rig/runtime/job_completion.rbs +28 -0
  183. data/sig/generated/riffer/rig/runtime/job_envelope.rbs +17 -0
  184. data/sig/generated/riffer/rig/runtime/job_inbox.rbs +40 -0
  185. data/sig/generated/riffer/rig/runtime/job_notification.rbs +22 -0
  186. data/sig/generated/riffer/rig/runtime/mcp_registrar.rbs +46 -0
  187. data/sig/generated/riffer/rig/runtime/snapshot.rbs +42 -0
  188. data/sig/generated/riffer/rig/runtime/system_prompt.rbs +37 -0
  189. data/sig/generated/riffer/rig/runtime/tool_runtime.rbs +25 -1
  190. data/sig/generated/riffer/rig/runtime/usage.rbs +11 -0
  191. data/sig/generated/riffer/rig/runtime.rbs +130 -92
  192. data/sig/generated/riffer/rig/sdk.rbs +11 -1
  193. data/sig/generated/riffer/rig/settings/file.rbs +19 -0
  194. data/sig/generated/riffer/rig/settings/model_options.rbs +31 -0
  195. data/sig/generated/riffer/rig/settings.rbs +0 -66
  196. data/sig/generated/riffer/rig/stores/entries.rbs +12 -0
  197. data/sig/generated/riffer/rig/stores/header.rbs +2 -5
  198. data/sig/generated/riffer/rig/stores/message_entry.rbs +9 -7
  199. data/sig/generated/riffer/rig/stores/model_entry.rbs +9 -7
  200. data/sig/generated/riffer/rig/stores/recorder.rbs +16 -4
  201. data/sig/generated/riffer/rig/stores/skill_entry.rbs +9 -7
  202. data/sig/generated/riffer/rig/stores/stamped.rbs +7 -0
  203. data/sig/generated/riffer/rig/stores/timestamp.rbs +13 -0
  204. data/sig/generated/riffer/rig/support/json_file.rbs +23 -0
  205. data/sig/generated/riffer/rig/support/typed_value/schema.rbs +14 -0
  206. data/sig/generated/riffer/rig/support/typed_value.rbs +13 -0
  207. data/sig/generated/riffer/rig/terminal/autocomplete.rbs +72 -0
  208. data/sig/generated/riffer/rig/terminal/banner.rbs +25 -4
  209. data/sig/generated/riffer/rig/terminal/blocking_prompter.rbs +23 -0
  210. data/sig/generated/riffer/rig/terminal/builtin.rbs +13 -0
  211. data/sig/generated/riffer/rig/terminal/columns.rbs +43 -0
  212. data/sig/generated/riffer/rig/terminal/console.rbs +32 -0
  213. data/sig/generated/riffer/rig/terminal/echo.rbs +15 -0
  214. data/sig/generated/riffer/rig/terminal/equalizer.rbs +12 -0
  215. data/sig/generated/riffer/rig/terminal/frame.rbs +169 -0
  216. data/sig/generated/riffer/rig/terminal/frame_prompter.rbs +34 -0
  217. data/sig/generated/riffer/rig/terminal/help.rbs +22 -0
  218. data/sig/generated/riffer/rig/terminal/host.rbs +5 -11
  219. data/sig/generated/riffer/rig/terminal/job_counter.rbs +21 -0
  220. data/sig/generated/riffer/rig/terminal/job_exit_notice.rbs +7 -0
  221. data/sig/generated/riffer/rig/terminal/key.rbs +27 -0
  222. data/sig/generated/riffer/rig/terminal/key_decoder.rbs +81 -0
  223. data/sig/generated/riffer/rig/terminal/key_pipeline.rbs +54 -0
  224. data/sig/generated/riffer/rig/terminal/line_editor.rbs +108 -0
  225. data/sig/generated/riffer/rig/terminal/markdown/blocks.rbs +57 -0
  226. data/sig/generated/riffer/rig/terminal/markdown/flow.rbs +42 -0
  227. data/sig/generated/riffer/rig/terminal/markdown/inline.rbs +41 -0
  228. data/sig/generated/riffer/rig/terminal/markdown/span.rbs +20 -0
  229. data/sig/generated/riffer/rig/terminal/markdown/table.rbs +101 -0
  230. data/sig/generated/riffer/rig/terminal/markdown.rbs +112 -0
  231. data/sig/generated/riffer/rig/terminal/message_queue/message.rbs +10 -0
  232. data/sig/generated/riffer/rig/terminal/message_queue.rbs +17 -0
  233. data/sig/generated/riffer/rig/terminal/opening.rbs +33 -0
  234. data/sig/generated/riffer/rig/terminal/peek.rbs +37 -0
  235. data/sig/generated/riffer/rig/terminal/picker.rbs +21 -5
  236. data/sig/generated/riffer/rig/terminal/question.rbs +21 -0
  237. data/sig/generated/riffer/rig/terminal/quiet_display.rbs +33 -0
  238. data/sig/generated/riffer/rig/terminal/renderer.rbs +10 -122
  239. data/sig/generated/riffer/rig/terminal/repl.rbs +116 -0
  240. data/sig/generated/riffer/rig/terminal/replay/turn.rbs +20 -0
  241. data/sig/generated/riffer/rig/terminal/replay.rbs +29 -0
  242. data/sig/generated/riffer/rig/terminal/session.rbs +2 -7
  243. data/sig/generated/riffer/rig/terminal/tally.rbs +7 -0
  244. data/sig/generated/riffer/rig/terminal/theme.rbs +23 -2
  245. data/sig/generated/riffer/rig/terminal/ticker.rbs +107 -0
  246. data/sig/generated/riffer/rig/terminal/ticker_display.rbs +48 -0
  247. data/sig/generated/riffer/rig/terminal/turn_buffer/stats.rbs +16 -0
  248. data/sig/generated/riffer/rig/terminal/turn_buffer.rbs +67 -0
  249. data/sig/generated/riffer/rig/terminal/turn_report.rbs +52 -0
  250. data/sig/generated/riffer/rig/terminal/wrapper.rbs +16 -14
  251. data/sig/generated/riffer/rig/terminal.rbs +55 -26
  252. data/sig/generated/riffer/rig/tools/bash/capture.rbs +39 -0
  253. data/sig/generated/riffer/rig/tools/bash/job.rbs +65 -0
  254. data/sig/generated/riffer/rig/tools/bash/job_log.rbs +60 -0
  255. data/sig/generated/riffer/rig/tools/bash/jobs.rbs +86 -0
  256. data/sig/generated/riffer/rig/tools/bash/kill.rbs +8 -0
  257. data/sig/generated/riffer/rig/tools/bash/kill_group.rbs +7 -0
  258. data/sig/generated/riffer/rig/tools/bash/monotonic_clock.rbs +6 -0
  259. data/sig/generated/riffer/rig/tools/bash/output.rbs +10 -0
  260. data/sig/generated/riffer/rig/tools/bash/truncation.rbs +7 -0
  261. data/sig/generated/riffer/rig/tools/bash.rbs +15 -13
  262. data/sig/generated/riffer/rig/trust.rbs +7 -8
  263. data/sig/manual/riffer/rig/acp/mapper.rbs +6 -0
  264. data/sig/manual/riffer/rig/commands/cost.rbs +6 -0
  265. data/sig/manual/riffer/rig/commands/trace/replay.rbs +6 -0
  266. data/sig/manual/riffer/rig/commands/trace.rbs +6 -0
  267. data/sig/manual/riffer/rig/credentials/provider_fields.rbs +6 -0
  268. data/sig/manual/riffer/rig/hosts.rbs +1 -1
  269. data/sig/manual/riffer/rig/loader/credentials.rbs +6 -0
  270. data/sig/manual/riffer/rig/runtime/error_message.rbs +6 -0
  271. data/sig/manual/riffer/rig/runtime/job_envelope.rbs +6 -0
  272. data/sig/manual/riffer/rig/runtime/usage.rbs +6 -0
  273. data/sig/manual/riffer/rig/sdk.rbs +1 -1
  274. data/sig/manual/riffer/rig/settings/file.rbs +6 -0
  275. data/sig/manual/riffer/rig/settings/model_options.rbs +6 -0
  276. data/sig/manual/riffer/rig/stores/entries.rbs +6 -0
  277. data/sig/manual/riffer/rig/stores/timestamp.rbs +6 -0
  278. data/sig/manual/riffer/rig/stores.rbs +8 -0
  279. data/sig/manual/riffer/rig/support/json_file.rbs +6 -0
  280. data/sig/manual/riffer/rig/support.rbs +10 -0
  281. data/sig/manual/riffer/rig/terminal/autocomplete.rbs +8 -0
  282. data/sig/manual/riffer/rig/terminal/columns.rbs +6 -0
  283. data/sig/manual/riffer/rig/terminal/echo.rbs +6 -0
  284. data/sig/manual/riffer/rig/terminal/equalizer.rbs +6 -0
  285. data/sig/manual/riffer/rig/terminal/help.rbs +6 -0
  286. data/sig/manual/riffer/rig/terminal/job_exit_notice.rbs +6 -0
  287. data/sig/manual/riffer/rig/terminal/markdown/blocks.rbs +6 -0
  288. data/sig/manual/riffer/rig/terminal/markdown/flow.rbs +6 -0
  289. data/sig/manual/riffer/rig/terminal/markdown/inline.rbs +6 -0
  290. data/sig/manual/riffer/rig/terminal/markdown/table.rbs +6 -0
  291. data/sig/manual/riffer/rig/terminal/markdown.rbs +6 -0
  292. data/sig/manual/riffer/rig/terminal/question.rbs +6 -0
  293. data/sig/manual/riffer/rig/terminal/replay.rbs +14 -0
  294. data/sig/manual/riffer/rig/terminal/tally.rbs +6 -0
  295. data/sig/manual/riffer/rig/terminal/turn_report.rbs +14 -0
  296. data/sig/manual/riffer/rig/terminal.rbs +29 -4
  297. metadata +184 -11
  298. data/lib/riffer/rig/terminal/animator.rb +0 -139
  299. data/lib/riffer/rig/terminal/cursor.rb +0 -44
  300. data/lib/riffer/rig/terminal/smoother.rb +0 -126
  301. data/sig/generated/riffer/rig/terminal/animator.rbs +0 -68
  302. data/sig/generated/riffer/rig/terminal/cursor.rbs +0 -31
  303. 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: 04c27f5bf6e9339d06df9f64501e3b3dac5fa4724b0272a29641b0d9b707f788
4
- data.tar.gz: a89ddd0ef08516f50c3ea42c2374ff7ff80ea78b55ba1ed8a561851df6280745
3
+ metadata.gz: 8fe0ea5d0af46d44401a20ba9880877d1f631d4131de70452256a5def7d206aa
4
+ data.tar.gz: '0108f44f3cd248417bee1320ef14921cf75d8018784b103ebf85d676f941cd79'
5
5
  SHA512:
6
- metadata.gz: 11115efca8ca651cf9d1211c0c17e112e4369ce72f606c0c3886e1caae0c3a5b48b281f298a88481fdfff630eb57b19b2de2aa2dffbb9ef3e01a23fe0fa32a11
7
- data.tar.gz: f0548a971011eb9b8439de4237bdeaf61803867a2a692f02cf37ea8f69e6ddb1f4492e5fb5e49fe81d95ac3b379909383ca15949822e5e50f2c39c4686cf77b7
6
+ metadata.gz: 761434ca55b8f51971328b39ad0dfa02d4a89e21c41f03b1dfb55778c09cac14f4d3328799e8a6e1b25027f9d30a953d3278f4a0264a0ae558e6f56ef577c779
7
+ data.tar.gz: f9e88b15b40d562553f4b0b871a1b992c0da8c6b883159561be132e3b74312b7fce5d31b18391db99366e7bc6a4d0070639efce9abe7b454e572d9d4e7acc659
data/CHANGELOG.md CHANGED
@@ -1,5 +1,134 @@
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
+
3
132
  ## [0.12.0](https://github.com/bottrall/riffer-rig/compare/v0.11.0...v0.12.0) (2026-10-07)
4
133
 
5
134
 
data/README.md CHANGED
@@ -48,8 +48,9 @@ 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`; bare `-r` opens the [picker](docs/SESSIONS.md#the-picker) ([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
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
 
@@ -63,23 +64,21 @@ 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. 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)). 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
- - `/resume [--all]` opens the [session picker](docs/SESSIONS.md#the-picker): type to filter, switch with Enter on a single match or a row number, and delete with Ctrl-D and a confirm. `/new` starts a fresh session in place; the one you left stays on disk. Both replace the session the terminal drives and re-render the banner.
77
- - `/model provider/name` switches the model ([below](#switching-the-model)), and `/skill:<name> [text]` runs a skill ([Skills](docs/SKILLS.md)).
78
- - 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).
79
78
 
80
79
  ### Switching the model
81
80
 
82
- `/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)).
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)).
83
82
 
84
83
  ## Authentication
85
84
 
@@ -176,6 +175,7 @@ Start here:
176
175
 
177
176
  Using the terminal:
178
177
 
178
+ - [Terminal](https://riffer.bottrall.dev/guides/terminal/) — The input line and its keys, queueing, the status line, peek, resume replay
179
179
  - [Configuration](https://riffer.bottrall.dev/guides/configuration/) — Settings scopes and every core key
180
180
  - [Instructions](https://riffer.bottrall.dev/guides/instructions/) — How the system message is built; AGENTS.md
181
181
  - [Tools](https://riffer.bottrall.dev/guides/tools/) — The bundled toolkit and provider-native tools
@@ -219,9 +219,9 @@ Every project chore is a script in `bin/`. The Rakefile behind them is an implem
219
219
 
220
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`.
221
221
 
222
- [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.
223
223
 
224
- 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.
225
225
 
226
226
  ## Contributing
227
227
 
@@ -1,25 +1,36 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'acp/sdk'
4
+ require 'securerandom'
4
5
 
5
6
  class Riffer::Rig::ACP::Host
6
- CAPABILITIES = Set[:notify].freeze #: Set[Symbol]
7
+ include Riffer::Rig::Hosts::NonInteractive
7
8
 
8
- # @rbs @client: ::ACP::AgentConnection::_Client
9
+ CAPABILITIES = Set[:notify, :ask, :confirm].freeze #: Set[Symbol]
10
+ BUILDING_CAPABILITIES = Set[:notify].freeze #: Set[Symbol]
11
+
12
+ # @rbs @client: ::ACP::AgentConnection::Client
9
13
  # @rbs @session_id: String?
10
- # @rbs @buffered: Array[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
11
19
 
12
- # @rbs client: ::ACP::AgentConnection::_Client
20
+ # @rbs client: ::ACP::AgentConnection::Client
13
21
  # @rbs return: void
14
22
  def initialize(client:)
15
23
  @client = client
16
24
  @session_id = nil
17
25
  @buffered = []
26
+ @lock = Mutex.new
18
27
  end
19
28
 
29
+ # A request to the client names its session, so nothing can be relayed
30
+ # until the agent sets the id.
20
31
  # @rbs return: Set[Symbol]
21
32
  def capabilities
22
- CAPABILITIES
33
+ @session_id ? CAPABILITIES : BUILDING_CAPABILITIES
23
34
  end
24
35
 
25
36
  # @rbs question: String?
@@ -27,23 +38,41 @@ class Riffer::Rig::ACP::Host
27
38
  # @rbs secret: bool
28
39
  # @rbs return: String?
29
40
  def ask(question = nil, options: nil, secret: false)
30
- nil
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)
31
49
  end
32
50
 
33
51
  # @rbs question: String?
34
52
  # @rbs return: bool
35
- def confirm(_question = nil)
36
- false
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
37
58
  end
38
59
 
39
60
  # @rbs message: String?
40
61
  # @rbs level: Symbol
41
62
  # @rbs return: void
42
63
  def notify(message = nil, level: :info)
43
- id = @session_id
44
- return @buffered << message.to_s unless id
64
+ update(Riffer::Rig::ACP::Mapper.notice(message.to_s))
65
+ end
45
66
 
46
- send_update(id, message.to_s)
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
47
76
  end
48
77
 
49
78
  # @rbs label: String?
@@ -61,23 +90,37 @@ class Riffer::Rig::ACP::Host
61
90
  # @rbs id: String
62
91
  # @rbs return: void
63
92
  def session_id=(id)
64
- @session_id = id
65
- buffered = @buffered
66
- @buffered = []
67
- buffered.each { |message| send_update(id, message) }
93
+ @lock.synchronize do
94
+ @session_id = id
95
+ @buffered.each { |update| @client.update(id, update) }
96
+ @buffered = []
97
+ end
68
98
  end
69
99
 
70
100
  private
71
101
 
72
102
  # @rbs id: String
73
- # @rbs message: String
74
- # @rbs return: void
75
- def send_update(id, message)
76
- @client.update(
77
- id,
78
- ::ACP::Types::SessionUpdate::AgentMessageChunk.new(
79
- content: ::ACP::Types::ContentBlock::Text.new(text: message)
80
- )
81
- )
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))
82
125
  end
83
126
  end