roast-ai 0.4.9 → 0.5.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 (194) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/commands/docs/write-comments.md +36 -0
  3. data/.github/CODEOWNERS +1 -1
  4. data/.github/workflows/ci.yaml +10 -6
  5. data/.gitignore +0 -1
  6. data/.rubocop.yml +7 -1
  7. data/CLAUDE.md +2 -2
  8. data/CONTRIBUTING.md +2 -0
  9. data/Gemfile +18 -18
  10. data/Gemfile.lock +46 -57
  11. data/README.md +118 -1432
  12. data/README_LEGACY.md +1464 -0
  13. data/Rakefile +39 -4
  14. data/dev.yml +29 -0
  15. data/dsl/agent_sessions.rb +20 -0
  16. data/dsl/async_cogs.rb +49 -0
  17. data/dsl/async_cogs_complex.rb +67 -0
  18. data/dsl/call.rb +44 -0
  19. data/dsl/collect_from.rb +72 -0
  20. data/dsl/demo/Gemfile +4 -0
  21. data/dsl/demo/Gemfile.lock +120 -0
  22. data/dsl/demo/cogs/local.rb +15 -0
  23. data/dsl/demo/simple_external_cog.rb +17 -0
  24. data/dsl/json_output.rb +28 -0
  25. data/dsl/map.rb +55 -0
  26. data/dsl/map_reduce.rb +37 -0
  27. data/dsl/map_with_index.rb +49 -0
  28. data/dsl/next_break.rb +40 -0
  29. data/dsl/next_break_parallel.rb +44 -0
  30. data/dsl/outputs.rb +39 -0
  31. data/dsl/outputs_bang.rb +36 -0
  32. data/dsl/parallel_map.rb +37 -0
  33. data/dsl/plugin-gem-example/.gitignore +8 -0
  34. data/dsl/plugin-gem-example/Gemfile +13 -0
  35. data/dsl/plugin-gem-example/Gemfile.lock +178 -0
  36. data/dsl/plugin-gem-example/lib/other.rb +17 -0
  37. data/dsl/plugin-gem-example/lib/plugin_gem_example.rb +5 -0
  38. data/dsl/plugin-gem-example/lib/simple.rb +15 -0
  39. data/dsl/plugin-gem-example/lib/version.rb +10 -0
  40. data/dsl/plugin-gem-example/plugin-gem-example.gemspec +28 -0
  41. data/dsl/prompts/simple_prompt.md.erb +3 -0
  42. data/dsl/prototype.rb +10 -4
  43. data/dsl/repeat_loop_results.rb +53 -0
  44. data/dsl/ruby_cog.rb +72 -0
  45. data/dsl/simple_agent.rb +18 -0
  46. data/dsl/simple_chat.rb +26 -0
  47. data/dsl/simple_repeat.rb +29 -0
  48. data/dsl/skip.rb +36 -0
  49. data/dsl/step_communication.rb +10 -5
  50. data/dsl/targets_and_params.rb +57 -0
  51. data/dsl/temperature.rb +17 -0
  52. data/dsl/temporary_directory.rb +22 -0
  53. data/dsl/tutorial/01_your_first_workflow/README.md +179 -0
  54. data/dsl/tutorial/01_your_first_workflow/configured_chat.rb +33 -0
  55. data/dsl/tutorial/01_your_first_workflow/hello.rb +23 -0
  56. data/dsl/tutorial/02_chaining_cogs/README.md +310 -0
  57. data/dsl/tutorial/02_chaining_cogs/code_review.rb +104 -0
  58. data/dsl/tutorial/02_chaining_cogs/session_resumption.rb +92 -0
  59. data/dsl/tutorial/02_chaining_cogs/simple_chain.rb +84 -0
  60. data/dsl/tutorial/03_targets_and_params/README.md +230 -0
  61. data/dsl/tutorial/03_targets_and_params/multiple_targets.rb +65 -0
  62. data/dsl/tutorial/03_targets_and_params/single_target.rb +65 -0
  63. data/dsl/tutorial/04_configuration_options/README.md +209 -0
  64. data/dsl/tutorial/04_configuration_options/control_display_and_temperature.rb +104 -0
  65. data/dsl/tutorial/04_configuration_options/simple_config.rb +68 -0
  66. data/dsl/tutorial/05_control_flow/README.md +156 -0
  67. data/dsl/tutorial/05_control_flow/conditional_execution.rb +62 -0
  68. data/dsl/tutorial/05_control_flow/handling_failures.rb +77 -0
  69. data/dsl/tutorial/06_reusable_scopes/README.md +172 -0
  70. data/dsl/tutorial/06_reusable_scopes/accessing_scope_outputs.rb +126 -0
  71. data/dsl/tutorial/06_reusable_scopes/basic_scope.rb +63 -0
  72. data/dsl/tutorial/06_reusable_scopes/parameterized_scope.rb +78 -0
  73. data/dsl/tutorial/07_processing_collections/README.md +152 -0
  74. data/dsl/tutorial/07_processing_collections/basic_map.rb +70 -0
  75. data/dsl/tutorial/07_processing_collections/parallel_map.rb +74 -0
  76. data/dsl/tutorial/08_iterative_workflows/README.md +231 -0
  77. data/dsl/tutorial/08_iterative_workflows/basic_repeat.rb +57 -0
  78. data/dsl/tutorial/08_iterative_workflows/conditional_break.rb +57 -0
  79. data/dsl/tutorial/09_async_cogs/README.md +197 -0
  80. data/dsl/tutorial/09_async_cogs/basic_async.rb +38 -0
  81. data/dsl/tutorial/README.md +222 -0
  82. data/dsl/working_directory.rb +16 -0
  83. data/exe/roast +1 -1
  84. data/internal/documentation/architectural-notes.md +115 -0
  85. data/internal/documentation/doc-comments-external.md +686 -0
  86. data/internal/documentation/doc-comments-internal.md +342 -0
  87. data/internal/documentation/doc-comments.md +211 -0
  88. data/lib/roast/dsl/cog/config.rb +280 -4
  89. data/lib/roast/dsl/cog/input.rb +73 -0
  90. data/lib/roast/dsl/cog/output.rb +313 -0
  91. data/lib/roast/dsl/cog/registry.rb +71 -0
  92. data/lib/roast/dsl/cog/stack.rb +3 -2
  93. data/lib/roast/dsl/cog/store.rb +11 -8
  94. data/lib/roast/dsl/cog.rb +108 -31
  95. data/lib/roast/dsl/cog_input_context.rb +44 -0
  96. data/lib/roast/dsl/cog_input_manager.rb +156 -0
  97. data/lib/roast/dsl/cogs/agent/config.rb +465 -0
  98. data/lib/roast/dsl/cogs/agent/input.rb +81 -0
  99. data/lib/roast/dsl/cogs/agent/output.rb +59 -0
  100. data/lib/roast/dsl/cogs/agent/provider.rb +51 -0
  101. data/lib/roast/dsl/cogs/agent/providers/claude/claude_invocation.rb +185 -0
  102. data/lib/roast/dsl/cogs/agent/providers/claude/message.rb +73 -0
  103. data/lib/roast/dsl/cogs/agent/providers/claude/messages/assistant_message.rb +36 -0
  104. data/lib/roast/dsl/cogs/agent/providers/claude/messages/result_message.rb +61 -0
  105. data/lib/roast/dsl/cogs/agent/providers/claude/messages/system_message.rb +47 -0
  106. data/lib/roast/dsl/cogs/agent/providers/claude/messages/text_message.rb +36 -0
  107. data/lib/roast/dsl/cogs/agent/providers/claude/messages/tool_result_message.rb +47 -0
  108. data/lib/roast/dsl/cogs/agent/providers/claude/messages/tool_use_message.rb +46 -0
  109. data/lib/roast/dsl/cogs/agent/providers/claude/messages/unknown_message.rb +27 -0
  110. data/lib/roast/dsl/cogs/agent/providers/claude/messages/user_message.rb +37 -0
  111. data/lib/roast/dsl/cogs/agent/providers/claude/tool_result.rb +51 -0
  112. data/lib/roast/dsl/cogs/agent/providers/claude/tool_use.rb +48 -0
  113. data/lib/roast/dsl/cogs/agent/providers/claude.rb +31 -0
  114. data/lib/roast/dsl/cogs/agent/stats.rb +92 -0
  115. data/lib/roast/dsl/cogs/agent/usage.rb +62 -0
  116. data/lib/roast/dsl/cogs/agent.rb +75 -0
  117. data/lib/roast/dsl/cogs/chat/config.rb +453 -0
  118. data/lib/roast/dsl/cogs/chat/input.rb +92 -0
  119. data/lib/roast/dsl/cogs/chat/output.rb +64 -0
  120. data/lib/roast/dsl/cogs/chat/session.rb +68 -0
  121. data/lib/roast/dsl/cogs/chat.rb +81 -0
  122. data/lib/roast/dsl/cogs/cmd.rb +291 -27
  123. data/lib/roast/dsl/cogs/ruby.rb +171 -0
  124. data/lib/roast/dsl/command_runner.rb +191 -0
  125. data/lib/roast/dsl/config_context.rb +2 -47
  126. data/lib/roast/dsl/config_manager.rb +143 -0
  127. data/lib/roast/dsl/control_flow.rb +41 -0
  128. data/lib/roast/dsl/execution_context.rb +9 -0
  129. data/lib/roast/dsl/execution_manager.rb +267 -0
  130. data/lib/roast/dsl/nil_assertions.rb +23 -0
  131. data/lib/roast/dsl/system_cog/params.rb +32 -0
  132. data/lib/roast/dsl/system_cog.rb +36 -0
  133. data/lib/roast/dsl/system_cogs/call.rb +162 -0
  134. data/lib/roast/dsl/system_cogs/map.rb +448 -0
  135. data/lib/roast/dsl/system_cogs/repeat.rb +242 -0
  136. data/lib/roast/dsl/workflow.rb +123 -0
  137. data/lib/roast/dsl/workflow_context.rb +20 -0
  138. data/lib/roast/dsl/workflow_params.rb +24 -0
  139. data/lib/roast/sorbet_runtime_stub.rb +154 -0
  140. data/lib/roast/tools/apply_diff.rb +1 -3
  141. data/lib/roast/tools/cmd.rb +4 -3
  142. data/lib/roast/tools/read_file.rb +1 -1
  143. data/lib/roast/tools/update_files.rb +1 -1
  144. data/lib/roast/tools/write_file.rb +1 -1
  145. data/lib/roast/version.rb +1 -1
  146. data/lib/roast/workflow/base_workflow.rb +4 -0
  147. data/lib/roast/workflow/step_loader.rb +14 -2
  148. data/lib/roast-ai.rb +4 -0
  149. data/lib/roast.rb +60 -22
  150. data/{roast.gemspec → roast-ai.gemspec} +10 -13
  151. data/sorbet/config +1 -0
  152. data/sorbet/rbi/gems/async@2.34.0.rbi +1577 -0
  153. data/sorbet/rbi/gems/cli-kit@5.2.0.rbi +2063 -0
  154. data/sorbet/rbi/gems/{cli-ui@2.3.0.rbi → cli-ui@2.7.0-6bdefd1d06305e5d6ae312ac76f9c88f88658dda.rbi} +1418 -1013
  155. data/sorbet/rbi/gems/console@1.34.2.rbi +1193 -0
  156. data/sorbet/rbi/gems/fiber-annotation@0.2.0.rbi +50 -0
  157. data/sorbet/rbi/gems/fiber-local@1.1.0.rbi +35 -0
  158. data/sorbet/rbi/gems/fiber-storage@1.0.1.rbi +41 -0
  159. data/sorbet/rbi/gems/io-event@1.14.0.rbi +724 -0
  160. data/sorbet/rbi/gems/marcel@1.1.0.rbi +239 -0
  161. data/sorbet/rbi/gems/metrics@0.15.0.rbi +9 -0
  162. data/sorbet/rbi/gems/ruby_llm@1.8.2.rbi +5703 -0
  163. data/sorbet/rbi/gems/traces@0.18.2.rbi +9 -0
  164. data/sorbet/rbi/shims/lib/roast/dsl/cog_input_context.rbi +1197 -0
  165. data/sorbet/rbi/shims/lib/roast/dsl/config_context.rbi +314 -2
  166. data/sorbet/rbi/shims/lib/roast/dsl/execution_context.rbi +498 -0
  167. data/sorbet/tapioca/config.yml +6 -0
  168. data/sorbet/tapioca/require.rb +2 -0
  169. metadata +198 -34
  170. data/dsl/less_simple.rb +0 -112
  171. data/dsl/simple.rb +0 -8
  172. data/lib/roast/dsl/cog_execution_context.rb +0 -29
  173. data/lib/roast/dsl/cogs/graph.rb +0 -53
  174. data/lib/roast/dsl/cogs.rb +0 -65
  175. data/lib/roast/dsl/executor.rb +0 -82
  176. data/lib/roast/dsl/workflow_execution_context.rb +0 -47
  177. data/sorbet/rbi/gems/cgi@0.5.0.rbi +0 -2961
  178. data/sorbet/rbi/gems/claude_swarm@0.1.19.rbi +0 -568
  179. data/sorbet/rbi/gems/cli-kit@5.0.1.rbi +0 -1991
  180. data/sorbet/rbi/gems/dry-configurable@1.3.0.rbi +0 -672
  181. data/sorbet/rbi/gems/dry-core@1.1.0.rbi +0 -1894
  182. data/sorbet/rbi/gems/dry-inflector@1.2.0.rbi +0 -659
  183. data/sorbet/rbi/gems/dry-initializer@3.2.0.rbi +0 -781
  184. data/sorbet/rbi/gems/dry-logic@1.6.0.rbi +0 -1127
  185. data/sorbet/rbi/gems/dry-schema@1.14.1.rbi +0 -3727
  186. data/sorbet/rbi/gems/dry-types@1.8.3.rbi +0 -3969
  187. data/sorbet/rbi/gems/fast-mcp-annotations@1.5.3.rbi +0 -1588
  188. data/sorbet/rbi/gems/mime-types-data@3.2025.0617.rbi +0 -136
  189. data/sorbet/rbi/gems/mime-types@3.7.0.rbi +0 -1342
  190. data/sorbet/rbi/gems/rack@2.2.18.rbi +0 -5659
  191. data/sorbet/rbi/gems/rbs-inline@0.12.0.rbi +0 -2170
  192. data/sorbet/rbi/gems/yard-sorbet@0.9.0.rbi +0 -435
  193. data/sorbet/rbi/gems/yard@0.9.37.rbi +0 -18492
  194. data/sorbet/rbi/shims/lib/roast/dsl/workflow_execution_context.rbi +0 -11
@@ -0,0 +1,686 @@
1
+ # User-Facing Documentation Guidelines
2
+
3
+ This document provides guidelines for writing user-facing documentation comments in Roast. User-facing documentation appears in interfaces that Roast users interact with directly in their workflows.
4
+
5
+ ## Where This Applies
6
+
7
+ User-facing documentation must be extremely thorough and should **NOT assume knowledge** of how Roast works internally.
8
+
9
+ **Required locations:**
10
+
11
+ - All `Config` classes for cogs (e.g., `Agent::Config`, `Chat::Config`, `Cmd::Config`)
12
+ - All `Input` classes for cogs (e.g., `Agent::Input`, `Chat::Input`)
13
+ - All `Output` classes for cogs (e.g., `Agent::Output`, `Chat::Output`)
14
+ - `.rbi` shims in `sorbet/rbi/shims/lib/roast/` - **These are critically important!**
15
+
16
+ ## Architectural Context
17
+
18
+ Before writing user-facing documentation, consult [architectural-notes.md](./architectural-notes.md) for key architectural decisions and distinctions. This is especially important when documenting cog capabilities and distinctions. For example:
19
+
20
+ - The `agent` vs `chat` cog distinction (local system access vs pure LLM interaction)
21
+ - Avoiding misleading characterizations (e.g., don't call `chat` "simple" - it's capable of complex reasoning)
22
+ - Understanding the true limitations and capabilities of each cog
23
+
24
+ Always ensure your documentation accurately reflects the architectural design and doesn't inadvertently mislead users about what each cog can or cannot do.
25
+
26
+ ### Why .rbi Shims Are Critical
27
+
28
+ The `.rbi` shim files contain some of the most important user-facing documentation in Roast. These files define the methods that users call when writing workflows, and the documentation in these files is what users see in their IDE when they invoke these methods.
29
+
30
+ **Key .rbi shim files and their purposes:**
31
+
32
+ - **`execution_context.rbi`**: Documents methods users call when defining cogs in `execute` blocks of their workflows
33
+ - Methods like `agent!`, `chat!`, `cmd!`, `call!`, `map!`, `repeat!`
34
+ - These are the primary ways users invoke cogs in their workflow definitions
35
+
36
+ - **`config_context.rbi`**: Documents methods users call when configuring cogs in `config` blocks of their workflows
37
+ - Methods like `agent { ... }`, `chat { ... }`, `cmd { ... }`
38
+ - These are how users apply configuration to cogs before execution
39
+
40
+ - **`cog_input_context.rbi`**: Documents methods users call in cog input blocks to access outputs from other cogs
41
+ - Methods like `from`, `collect`, `reduce`
42
+ - These are how users access and transform cog outputs within their workflow
43
+
44
+ These files provide the primary interface between users and Roast. The documentation must be exceptional because it's what users see at the exact moment they need help. When a user types `agent!` in their workflow, the documentation from `execution_context.rbi` is what appears in their IDE to guide them.
45
+
46
+ ## Documentation Requirements
47
+
48
+ User-facing documentation should be comprehensive and include:
49
+
50
+ - Be extremely thorough
51
+ - Include comprehensive `#### See Also` sections with cross-references
52
+ - Explain default behaviors and edge cases
53
+ - Document error conditions
54
+ - Provide context about what the method does and why you'd use it
55
+ - Don't assume the reader understands Roast internals
56
+
57
+ ## Basic Format
58
+
59
+ Documentation comments follow this structure:
60
+
61
+ ```ruby
62
+ # [One-line summary of what the method does]
63
+ #
64
+ # [Optional: Additional details, context, or explanation]
65
+ #
66
+ # [Optional: Subsections for cross-references, notes, etc.]
67
+ #
68
+ #: (ParamType) -> ReturnType # Type signatures are enforced by Sorbet/RuboCop
69
+ def method_name(param)
70
+ # implementation
71
+ end
72
+ ```
73
+
74
+ ## Writing Clear Descriptions
75
+
76
+ ### One-Line Descriptions
77
+
78
+ Start with a clear, action-oriented description in imperative mood. The first line should **not** end with a period:
79
+
80
+ ```ruby
81
+ # Configure the cog to write STDOUT to the console
82
+ #: () -> void
83
+ def print_stdout!
84
+ @values[:print_stdout] = true
85
+ end
86
+ ```
87
+
88
+ **Good patterns:**
89
+
90
+ - "Configure the cog to..."
91
+ - "Get the validated..."
92
+ - "Check if the cog is configured to..."
93
+
94
+ **Avoid:**
95
+
96
+ - Passive voice: "The cog is configured to..."
97
+ - Redundant phrases: "This method configures..."
98
+ - Vague descriptions: "Sets a value"
99
+ - Ending with a period
100
+
101
+ ### Multi-Line Descriptions
102
+
103
+ When more context is needed, separate paragraphs with blank comment lines. All lines after the first line should be complete sentences ending with a period or other appropriate punctuation:
104
+
105
+ ```ruby
106
+ # Get the validated provider name that the cog is configured to use when invoking an agent
107
+ #
108
+ # Note: this method will return the name of a valid provider or raise an `InvalidConfigError`.
109
+ # It will not, however, validate that the agent is properly installed on your system.
110
+ # If the agent is not properly installed, you will likely experience a failure when Roast attempts to
111
+ # run your workflow.
112
+ #
113
+ #: () -> Symbol
114
+ def valid_provider!
115
+ # implementation
116
+ end
117
+ ```
118
+
119
+ ## Markdown Formatting
120
+
121
+ ### Emphasis
122
+
123
+ Use double underscores for bold emphasis to highlight critical negating words in key sentences:
124
+
125
+ ```ruby
126
+ # Configure the cog __not__ to write STDOUT to the console
127
+ #: () -> void
128
+ def no_print_stdout!
129
+ @values[:print_stdout] = false
130
+ end
131
+ ```
132
+
133
+ **When to bold negating words:**
134
+
135
+ Bold negating words (like "not", "no", "never", "without") when:
136
+ - The word is critical to understanding what the method does
137
+ - A reader who misses the word would get a categorically incorrect understanding
138
+ - The negation is the key distinguishing feature of the method or statement
139
+
140
+ **When not to bold:**
141
+
142
+ Do not bold negating words when:
143
+ - The negation is obvious from context
144
+ - Missing the negating word wouldn't cause categorical misunderstanding
145
+ - The negative meaning is already clear from surrounding text
146
+
147
+ ### Inline Code
148
+
149
+ Use backticks for:
150
+
151
+ - Method names: `` `provider` ``
152
+ - Values: `` `true` ``, `` `:claude` ``
153
+ - Symbols: `` `:name` ``
154
+ - Cog names: `` `call` ``, `` `map` ``, `` `agent` `` (they appear as methods from a user's perspective)
155
+ - Class names: Use **fully qualified names** (e.g., `` `Roast::DSL::Cog::Config::InvalidConfigError` ``)
156
+
157
+ **Important:** Always use fully qualified class/module names in documentation to avoid ambiguity.
158
+ Due to significant name overlap in the system (e.g., multiple `Input`, `Output`, `Config` classes),
159
+ shortened names can be confusing. Use the complete module path.
160
+
161
+ **Note:** "System" cogs are an internal implementation detail. From the user's perspective, all cogs provided by core Roast should be presented the same way. Never distinguish between "system cogs" and "regular cogs" in user-facing documentation.
162
+
163
+ **Note:** `ExecutionManager` is an internal implementation detail. Never mention execution managers in user-facing documentation. Focus on what the user can do with the output, not on the internal mechanisms used to produce it.
164
+
165
+ ```ruby
166
+ # Configure the cog to use the default provider when invoking an agent
167
+ #
168
+ # The default provider used by Roast is Anthropic Claude Code (`:claude`).
169
+ #: () -> void
170
+ def use_default_provider!
171
+ @values[:provider] = nil
172
+ end
173
+ ```
174
+
175
+ **Examples:**
176
+ - ✅ Good: `` `Roast::DSL::SystemCogs::Call::Output` ``
177
+ - ✅ Good: `` `Roast::DSL::Cogs::Agent::Config` ``
178
+ - ❌ Bad: `` `Call::Output` `` (ambiguous)
179
+ - ❌ Bad: `` `Agent::Config` `` (which Agent?)
180
+
181
+ ### Subsections
182
+
183
+ Use `####` for subsection headers (four hashes):
184
+
185
+ ```ruby
186
+ # Configure the cog to apply permissions when running the agent
187
+ #
188
+ # The cog's default behaviour is to run with __no__ permissions.
189
+ #
190
+ # #### Alias Methods
191
+ # - `apply_permissions!`
192
+ # - `no_skip_permissions!`
193
+ #
194
+ # #### Inverse Methods
195
+ # - `skip_permissions!`
196
+ # - `no_apply_permissions!`
197
+ #
198
+ #: () -> void
199
+ def apply_permissions!
200
+ @values[:apply_permissions] = true
201
+ end
202
+ ```
203
+
204
+ ### Lists
205
+
206
+ Use `-` for bullet lists:
207
+
208
+ ```ruby
209
+ # Configure the cog to use a specified provider when invoking an agent
210
+ #
211
+ # A provider must be properly installed on your system in order for Roast to be able to use it.
212
+ #
213
+ # #### See Also
214
+ # - `use_default_provider!`
215
+ #
216
+ #: (Symbol) -> void
217
+ def provider(provider)
218
+ @values[:provider] = provider
219
+ end
220
+ ```
221
+
222
+ ## Cross-References and Related Methods
223
+
224
+ ### See Also Sections
225
+
226
+ Always use `#### See Also` to list related user-facing methods and attributes in user-facing documentation.
227
+
228
+ **Critical Rule:** Only reference methods and attributes that users would actually call or access in their workflows, using user-facing syntax. Do __not__ reference class names or internal implementation details.
229
+
230
+ ```ruby
231
+ # Configure the cog to use the provider's default model when invoking the agent
232
+ #
233
+ # Note: the default model will be different for different providers.
234
+ #
235
+ # #### See Also
236
+ # - `model`
237
+ #
238
+ #: () -> void
239
+ def use_default_model!
240
+ @values[:model] = nil
241
+ end
242
+ ```
243
+
244
+ **When to include See Also:**
245
+
246
+ - Complementary methods (setter/getter pairs)
247
+ - Alternative approaches to the same goal
248
+ - Related predicate methods (e.g., `show_prompt?`)
249
+ - Methods from included modules (e.g., `text`, `lines`, `json`, `json!`)
250
+ - Other user-facing methods and attributes that users would call in their workflows
251
+
252
+ **Do NOT include in See Also:**
253
+
254
+ - `valid_*` validation methods when documenting user-facing Config setter methods - these are internal implementation details
255
+ - Class names (e.g., `Roast::DSL::Cogs::Agent::Config`) - these are not user-facing references
256
+ - Internal implementation details or mechanisms
257
+ - Anything users wouldn't directly reference in their workflow code
258
+
259
+ **Formatting examples:**
260
+ - ✅ User-facing method: `` - `model` ``
261
+ - ✅ Attribute from same class: `` - `response` ``
262
+ - ✅ Method from included module: `` - `text` ``
263
+ - ❌ Class name: `` - `Roast::DSL::Cogs::Agent::Input` ``
264
+ - ❌ Internal method: `` - `valid_model!` ``
265
+
266
+ ### Alias and Inverse Method Documentation
267
+
268
+ For methods with aliases or inverse methods, document them in dedicated subsections using `#### Alias Methods` and `#### Inverse Methods`.
269
+
270
+ **Critical: List the method itself in its alias list**
271
+
272
+ Because Ruby aliases share the same documentation, when a user looks up an alias method, they see the original method's doc comment. Therefore, the `#### Alias Methods` list must include the method itself as the first entry, followed by all its aliases in alphabetical order.
273
+
274
+ ```ruby
275
+ # Configure the cog to run the agent with __no__ permissions applied
276
+ #
277
+ # The cog's default behaviour is to run with __no__ permissions.
278
+ #
279
+ # #### Alias Methods
280
+ # - `no_apply_permissions!`
281
+ # - `skip_permissions!`
282
+ #
283
+ # #### Inverse Methods
284
+ # - `apply_permissions!`
285
+ # - `no_skip_permissions!`
286
+ #
287
+ #: () -> void
288
+ def no_apply_permissions!
289
+ @values[:apply_permissions] = false
290
+ end
291
+
292
+ alias_method(:skip_permissions!, :no_apply_permissions!)
293
+ ```
294
+
295
+ **Key points:**
296
+
297
+ - Always use subsections for aliases (never inline documentation)
298
+ - Use `#### Alias Methods` for the subsection header
299
+ - **Always include the method itself as the first entry in the alias list**
300
+ - List remaining aliases in alphabetical order after the primary method
301
+ - List inverse methods in a separate `#### Inverse Methods` subsection
302
+
303
+ ## Documenting Defaults and Behavior
304
+
305
+ ### Default Values
306
+
307
+ Always document default behavior:
308
+
309
+ ```ruby
310
+ # Configure the cog to strip surrounding whitespace from the values in its output object
311
+ #
312
+ # Default: `true`
313
+ #
314
+ #: () -> void
315
+ def clean_output!
316
+ @values[:raw_output] = false
317
+ end
318
+ ```
319
+
320
+ ### Nil Handling
321
+
322
+ Explain what `nil` values mean when used as parameters or configuration states:
323
+
324
+ ```ruby
325
+ # Configure the cog to use a specific model when invoking the agent
326
+ #
327
+ # Pass `nil` to use the provider's default model configuration.
328
+ #
329
+ #: (String?) -> void
330
+ def model(model)
331
+ @values[:model] = model
332
+ end
333
+ ```
334
+
335
+ ### Error Conditions
336
+
337
+ Document when methods raise errors:
338
+
339
+ ```ruby
340
+ # Get the validated provider name that the cog is configured to use when invoking an agent
341
+ #
342
+ # Note: this method will return the name of a valid provider or raise an `InvalidConfigError`.
343
+ # It will not, however, validate that the agent is properly installed on your system.
344
+ #
345
+ #: () -> Symbol
346
+ def valid_provider!
347
+ # implementation
348
+ end
349
+ ```
350
+
351
+ ## Config Method Documentation
352
+
353
+ Config methods have specific patterns that should be followed consistently.
354
+
355
+ ### Bang Method Convention
356
+
357
+ The bang (`!`) suffix is used in two distinct contexts:
358
+
359
+ 1. **No-argument state setters** - Methods that set a configuration value to a specific state without taking arguments (e.g., `print_stdout!`, `no_display!`)
360
+ 2. **Validation getters** - Methods that retrieve and validate configuration values and may raise errors (e.g., `valid_provider!`, `valid_working_directory_path!`)
361
+
362
+ Do **not** use bang for:
363
+ - Setter methods that accept a value parameter (e.g., `provider(value)`, `model(value)`)
364
+ - Simple predicate methods that check state (e.g., `print_stdout?`, `apply_permissions?`)
365
+
366
+ ### Configuration Setters
367
+
368
+ Configuration setter methods come in two forms:
369
+
370
+ **Bang methods (no arguments)** - Use `method!` for no-argument methods that set a configuration value to a specific state:
371
+
372
+ ```ruby
373
+ # Configure the cog to write STDOUT to the console
374
+ #
375
+ # Disabled by default
376
+ #
377
+ #: () -> void
378
+ def print_stdout!
379
+ @values[:print_stdout] = true
380
+ end
381
+ ```
382
+
383
+ **Value setters (with arguments)** - Use `method` without bang for methods that accept a value:
384
+
385
+ ```ruby
386
+ # Configure the cog to use a specified provider when invoking an agent
387
+ #
388
+ # The provider is the source of the agent tool itself.
389
+ # If no provider is specified, Anthropic Claude Code (`:claude`) will be used as the default provider.
390
+ #
391
+ # A provider must be properly installed on your system in order for Roast to be able to use it.
392
+ #
393
+ # #### See Also
394
+ # - `use_default_provider!`
395
+ #
396
+ #: (Symbol) -> void
397
+ def provider(provider)
398
+ @values[:provider] = provider
399
+ end
400
+ ```
401
+
402
+ **Key points:**
403
+
404
+ - Use bang (`!`) only for no-argument state-setting methods
405
+ - Do not use bang for methods that accept a value parameter
406
+ - Describe what aspect of the cog is being configured
407
+ - Explain the purpose and context
408
+ - Document any requirements or prerequisites
409
+ - Cross-reference related methods
410
+
411
+ ### Validation Getters
412
+
413
+ Validation getter methods use the `valid_*!` pattern and return a validated/coerced value or raise an error if validation fails. Currently primarily used for not-nil assertions, but will expand to other validations.
414
+
415
+ **Important:** These methods are internal implementation details. Configuration setter methods should __not__ cross-reference validation methods in their documentation. However, validation methods may cross-reference their corresponding setter methods.
416
+
417
+ ```ruby
418
+ # Get the validated, configured value for the working directory path in which the cog should run the agent
419
+ #
420
+ # This method will raise an `InvalidConfigError` if the path does not exist or is not a directory.
421
+ #
422
+ # #### See Also
423
+ # - `working_directory`
424
+ # - `use_current_working_directory!`
425
+ #
426
+ #: () -> String
427
+ def valid_working_directory_path!
428
+ # implementation with validation and error raising
429
+ end
430
+ ```
431
+
432
+ **Key points:**
433
+
434
+ - Use the `valid_*!` naming pattern with bang suffix
435
+ - Return the validated/coerced value on success
436
+ - Raise an error if validation fails
437
+ - Always document what errors can be raised and under what conditions
438
+ - Start descriptions with "Get the validated..."
439
+ - These methods may cross-reference their related setter methods
440
+ - Configuration setter methods should __not__ reference validation methods
441
+
442
+ ### Boolean Predicates
443
+
444
+ Predicate methods (those ending in `?`) check configuration state:
445
+
446
+ ```ruby
447
+ # Check if the cog is configured to apply permissions when running the agent
448
+ #
449
+ # #### See Also
450
+ # - `apply_permissions!`
451
+ # - `no_apply_permissions!`
452
+ # - `skip_permissions!`
453
+ # - `no_skip_permissions!`
454
+ #
455
+ #: () -> bool
456
+ def apply_permissions?
457
+ !!@values[:apply_permissions]
458
+ end
459
+ ```
460
+
461
+ **Key points:**
462
+
463
+ - Start with "Check if..."
464
+ - Reference all related configuration methods
465
+ - Document what `true` and `false` mean if not obvious
466
+
467
+ ### Path and Directory Configuration
468
+
469
+ Methods dealing with paths require extra documentation:
470
+
471
+ ```ruby
472
+ # Configure the cog to run the agent in the specified working directory
473
+ #
474
+ # The directory given can be relative or absolute.
475
+ # If relative, it will be understood in relation to the directory from which Roast is invoked.
476
+ #
477
+ # #### See Also
478
+ # - `use_current_working_directory!`
479
+ #
480
+ #: (String) -> void
481
+ def working_directory(directory)
482
+ @values[:working_directory] = directory
483
+ end
484
+ ```
485
+
486
+ **Key points:**
487
+
488
+ - Explain relative vs absolute path handling
489
+ - Document the base directory for relative paths
490
+ - Cross-reference complementary configuration methods
491
+
492
+ ## ConfigContext Method Documentation (.rbi shims)
493
+
494
+ Methods in `config_context.rbi` expose cog configuration interfaces and are the **primary way users discover what configuration options are available**. These require exceptionally thorough documentation.
495
+
496
+ ### Critical Requirements
497
+
498
+ **Document ALL user-facing configuration methods** - The documentation must list every configuration method that users can call on the cog's `Config` object. This is their primary discovery mechanism.
499
+
500
+ **Exclude internal methods** - Do NOT document internal implementation methods like `valid_*` validation methods.
501
+
502
+ **Group by purpose** - Organize configuration options by their purpose using `####` subsection headers. This helps users understand how options relate to each other.
503
+
504
+ ### Structure
505
+
506
+ ```ruby
507
+ # Configure the `agent` cog
508
+ #
509
+ # [Brief description of what this cog does - reference architectural-notes.md]
510
+ #
511
+ # ### Usage
512
+ # - `agent { &blk }` - Apply configuration to all instances of the `agent` cog
513
+ # - `agent(:name) { &blk }` - Apply configuration to the `agent` cog instance named `:name`
514
+ # - `agent(/regexp/) { &blk }` - Apply configuration to any `agent` cog whose name matches `/regexp/`
515
+ #
516
+ # ### Available Options
517
+ #
518
+ # Apply configuration within the block passed to `agent`:
519
+ #
520
+ # #### Configure the LLM provider
521
+ # - `provider(symbol)` - Set the agent provider (e.g., `:claude`)
522
+ # - `use_default_provider!` - Use the default provider (`:claude`)
523
+ #
524
+ # #### Configure the base command used to run the coding agent
525
+ # - `command(string_or_array)` - Set the base command for invoking the agent
526
+ # - `use_default_command!` - Use the provider's default command
527
+ #
528
+ # #### Configure the LLM model the agent should use
529
+ # - `model(string)` - Set the model to use
530
+ # - `use_default_model!` - Use the provider's default model
531
+ #
532
+ # #### Configure the working directory in which the coding agent process should run
533
+ # - `working_directory(path)` - Set the working directory for agent execution
534
+ # - `use_current_working_directory!` - Use the current working directory
535
+ #
536
+ # #### Configure whether the coding agent should be constrained by project- and user-level permissions specs
537
+ # - `apply_permissions!` - Apply permissions when running the agent
538
+ # - `skip_permissions!` (alias `no_apply_permissions!`) - Skip permissions (default)
539
+ #
540
+ #: (?(Symbol | Regexp)?) {() [self: Roast::DSL::Cogs::Agent::Config] -> void} -> void
541
+ def agent(name = nil, &block); end
542
+ ```
543
+
544
+ ### Key Guidelines
545
+
546
+ **Required sections:**
547
+
548
+ 1. **Brief description** - One or two sentences describing the cog (consult `architectural-notes.md` for accurate characterizations)
549
+ 2. **Usage** - Show all three calling patterns (all, named, regex)
550
+ 3. **Available Options** - List ALL user-facing config methods, grouped by purpose
551
+
552
+ **Grouping configuration options:**
553
+
554
+ - Use `####` (four hashes) for purpose-based groupings
555
+ - Create clear, descriptive group headers (e.g., "Configure the LLM provider", "Configure the working directory")
556
+ - Within each group, list related methods together
557
+ - Each method should have a brief one-line description
558
+ - Note aliases inline using `(alias method_name)`
559
+
560
+ **What to include:**
561
+
562
+ - ✅ ALL setter methods that accept parameters (e.g., `provider(symbol)`, `model(string)`)
563
+ - ✅ ALL no-argument state-setting methods (e.g., `apply_permissions!`, `use_default_provider!`)
564
+ - ✅ Note default values where applicable (e.g., "Skip permissions (default)")
565
+
566
+ **What to exclude:**
567
+
568
+ - ❌ Validation methods (e.g., `valid_provider!`, `valid_model!`) - these are internal
569
+ - ❌ Predicate methods (e.g., `apply_permissions?`) - these are internal
570
+ - ❌ Any other internal implementation methods
571
+
572
+ ## Common Patterns and Examples
573
+
574
+ ### Setter/Getter Pairs
575
+
576
+ ```ruby
577
+ # Configure the cog to use a specific model when invoking the agent
578
+ #
579
+ #: (String) -> void
580
+ def model(model)
581
+ @values[:model] = model
582
+ end
583
+
584
+ # Configure the cog to use the provider's default model when invoking the agent
585
+ #
586
+ # Note: the default model will be different for different providers.
587
+ #
588
+ # #### See Also
589
+ # - `model`
590
+ #
591
+ #: () -> void
592
+ def use_default_model!
593
+ @values[:model] = nil
594
+ end
595
+
596
+ # Get the validated, configured model that the cog will use when running the agent
597
+ #
598
+ # This method will raise an `InvalidConfigError` if no valid model is configured.
599
+ #
600
+ # #### See Also
601
+ # - `model`
602
+ # - `use_default_model!`
603
+ #
604
+ #: () -> String
605
+ def valid_model!
606
+ @values[:model].presence || raise(InvalidConfigError, "No valid model configured")
607
+ end
608
+ ```
609
+
610
+ ### Boolean Toggle Pairs
611
+
612
+ ```ruby
613
+ # Configure the cog to write STDOUT to the console
614
+ #
615
+ # Disabled by default.
616
+ #
617
+ #: () -> void
618
+ def print_stdout!
619
+ @values[:print_stdout] = true
620
+ end
621
+
622
+ # Configure the cog __not__ to write STDOUT to the console
623
+ #
624
+ #: () -> void
625
+ def no_print_stdout!
626
+ @values[:print_stdout] = false
627
+ end
628
+
629
+ # Check if the cog is configured to write STDOUT to the console
630
+ #
631
+ #: () -> bool
632
+ def print_stdout?
633
+ !!@values[:print_stdout]
634
+ end
635
+ ```
636
+
637
+ ## What Not to Document
638
+
639
+ Avoid documenting:
640
+
641
+ - **Implementation details** - Focus on behavior, not how it's achieved
642
+ - **Obvious information** - Don't state what's clear from the method name
643
+ - **Internal mechanics** - How `@values` hash works, etc.
644
+
645
+ **Bad example:**
646
+
647
+ ```ruby
648
+ # Sets the print_stdout value in the @values hash to true
649
+ #: () -> void
650
+ def print_stdout!
651
+ @values[:print_stdout] = true # Sets the value
652
+ end
653
+ ```
654
+
655
+ **Good example:**
656
+
657
+ ```ruby
658
+ # Configure the cog to write STDOUT to the console
659
+ #
660
+ # Disabled by default
661
+ #
662
+ #: () -> void
663
+ def print_stdout!
664
+ @values[:print_stdout] = true
665
+ end
666
+ ```
667
+
668
+ ## Review Checklist
669
+
670
+ Before finalizing user-facing documentation, verify:
671
+
672
+ - [ ] One-line description is clear and action-oriented
673
+ - [ ] First line does not end with a period
674
+ - [ ] All subsequent lines are complete sentences with proper punctuation
675
+ - [ ] Default behavior is documented (if applicable)
676
+ - [ ] Related user-facing methods/attributes are cross-referenced in `#### See Also` sections using user-facing syntax only
677
+ - [ ] `#### See Also` does NOT include class names, `valid_*` methods, or other internal implementation details
678
+ - [ ] Aliases are documented in an `#### Alias Methods` subsection (if applicable)
679
+ - [ ] The method itself is listed first in its own alias list, followed by aliases in alphabetical order
680
+ - [ ] Nil/false/true semantics are explained when not obvious
681
+ - [ ] Error conditions are mentioned and explained
682
+ - [ ] Critical negating words are bolded where missing them would cause misunderstanding
683
+ - [ ] Markdown formatting is correct
684
+ - [ ] No implementation details are exposed
685
+ - [ ] Context is provided about why you'd use this method
686
+ - [ ] No assumptions are made about the reader's knowledge of Roast internals