compound-engineering-pi 0.2.3

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 (332) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +124 -0
  3. package/bin/compound-engineering-pi +12 -0
  4. package/bin/compound-plugin +12 -0
  5. package/compound-engineering-pi +12 -0
  6. package/compound-plugin +5 -0
  7. package/docs/pi.md +152 -0
  8. package/extensions/compound-engineering-compat.ts +452 -0
  9. package/package.json +84 -0
  10. package/pi-resources/compound-engineering/mcporter.json +7 -0
  11. package/plugins/coding-tutor/.claude-plugin/plugin.json +9 -0
  12. package/plugins/coding-tutor/README.md +37 -0
  13. package/plugins/coding-tutor/commands/quiz-me.md +1 -0
  14. package/plugins/coding-tutor/commands/sync-tutorials.md +25 -0
  15. package/plugins/coding-tutor/commands/teach-me.md +1 -0
  16. package/plugins/coding-tutor/skills/coding-tutor/SKILL.md +214 -0
  17. package/plugins/coding-tutor/skills/coding-tutor/scripts/create_tutorial.py +207 -0
  18. package/plugins/coding-tutor/skills/coding-tutor/scripts/index_tutorials.py +193 -0
  19. package/plugins/coding-tutor/skills/coding-tutor/scripts/quiz_priority.py +190 -0
  20. package/plugins/coding-tutor/skills/coding-tutor/scripts/setup_tutorials.py +118 -0
  21. package/plugins/compound-engineering/.claude-plugin/plugin.json +33 -0
  22. package/plugins/compound-engineering/CHANGELOG.md +457 -0
  23. package/plugins/compound-engineering/CLAUDE.md +89 -0
  24. package/plugins/compound-engineering/LICENSE +21 -0
  25. package/plugins/compound-engineering/README.md +232 -0
  26. package/plugins/compound-engineering/agents/design/design-implementation-reviewer.md +109 -0
  27. package/plugins/compound-engineering/agents/design/design-iterator.md +224 -0
  28. package/plugins/compound-engineering/agents/design/figma-design-sync.md +190 -0
  29. package/plugins/compound-engineering/agents/docs/ankane-readme-writer.md +65 -0
  30. package/plugins/compound-engineering/agents/research/best-practices-researcher.md +126 -0
  31. package/plugins/compound-engineering/agents/research/framework-docs-researcher.md +106 -0
  32. package/plugins/compound-engineering/agents/research/git-history-analyzer.md +59 -0
  33. package/plugins/compound-engineering/agents/research/learnings-researcher.md +264 -0
  34. package/plugins/compound-engineering/agents/research/repo-research-analyst.md +135 -0
  35. package/plugins/compound-engineering/agents/review/agent-native-reviewer.md +261 -0
  36. package/plugins/compound-engineering/agents/review/architecture-strategist.md +67 -0
  37. package/plugins/compound-engineering/agents/review/code-simplicity-reviewer.md +101 -0
  38. package/plugins/compound-engineering/agents/review/data-integrity-guardian.md +85 -0
  39. package/plugins/compound-engineering/agents/review/data-migration-expert.md +112 -0
  40. package/plugins/compound-engineering/agents/review/deployment-verification-agent.md +174 -0
  41. package/plugins/compound-engineering/agents/review/dhh-rails-reviewer.md +66 -0
  42. package/plugins/compound-engineering/agents/review/julik-frontend-races-reviewer.md +221 -0
  43. package/plugins/compound-engineering/agents/review/kieran-python-reviewer.md +133 -0
  44. package/plugins/compound-engineering/agents/review/kieran-rails-reviewer.md +115 -0
  45. package/plugins/compound-engineering/agents/review/kieran-typescript-reviewer.md +124 -0
  46. package/plugins/compound-engineering/agents/review/pattern-recognition-specialist.md +72 -0
  47. package/plugins/compound-engineering/agents/review/performance-oracle.md +137 -0
  48. package/plugins/compound-engineering/agents/review/schema-drift-detector.md +154 -0
  49. package/plugins/compound-engineering/agents/review/security-sentinel.md +114 -0
  50. package/plugins/compound-engineering/agents/workflow/bug-reproduction-validator.md +82 -0
  51. package/plugins/compound-engineering/agents/workflow/every-style-editor.md +64 -0
  52. package/plugins/compound-engineering/agents/workflow/lint.md +16 -0
  53. package/plugins/compound-engineering/agents/workflow/pr-comment-resolver.md +84 -0
  54. package/plugins/compound-engineering/agents/workflow/spec-flow-analyzer.md +134 -0
  55. package/plugins/compound-engineering/commands/agent-native-audit.md +278 -0
  56. package/plugins/compound-engineering/commands/changelog.md +138 -0
  57. package/plugins/compound-engineering/commands/create-agent-skill.md +9 -0
  58. package/plugins/compound-engineering/commands/deepen-plan.md +546 -0
  59. package/plugins/compound-engineering/commands/deploy-docs.md +113 -0
  60. package/plugins/compound-engineering/commands/feature-video.md +342 -0
  61. package/plugins/compound-engineering/commands/generate_command.md +163 -0
  62. package/plugins/compound-engineering/commands/heal-skill.md +143 -0
  63. package/plugins/compound-engineering/commands/lfg.md +20 -0
  64. package/plugins/compound-engineering/commands/release-docs.md +212 -0
  65. package/plugins/compound-engineering/commands/report-bug.md +151 -0
  66. package/plugins/compound-engineering/commands/reproduce-bug.md +100 -0
  67. package/plugins/compound-engineering/commands/resolve_parallel.md +35 -0
  68. package/plugins/compound-engineering/commands/resolve_todo_parallel.md +37 -0
  69. package/plugins/compound-engineering/commands/slfg.md +32 -0
  70. package/plugins/compound-engineering/commands/technical_review.md +8 -0
  71. package/plugins/compound-engineering/commands/test-browser.md +339 -0
  72. package/plugins/compound-engineering/commands/test-xcode.md +332 -0
  73. package/plugins/compound-engineering/commands/triage.md +311 -0
  74. package/plugins/compound-engineering/commands/workflows/brainstorm.md +124 -0
  75. package/plugins/compound-engineering/commands/workflows/compound.md +239 -0
  76. package/plugins/compound-engineering/commands/workflows/plan.md +551 -0
  77. package/plugins/compound-engineering/commands/workflows/review.md +526 -0
  78. package/plugins/compound-engineering/commands/workflows/work.md +433 -0
  79. package/plugins/compound-engineering/skills/agent-browser/SKILL.md +223 -0
  80. package/plugins/compound-engineering/skills/agent-native-architecture/SKILL.md +435 -0
  81. package/plugins/compound-engineering/skills/agent-native-architecture/references/action-parity-discipline.md +409 -0
  82. package/plugins/compound-engineering/skills/agent-native-architecture/references/agent-execution-patterns.md +467 -0
  83. package/plugins/compound-engineering/skills/agent-native-architecture/references/agent-native-testing.md +582 -0
  84. package/plugins/compound-engineering/skills/agent-native-architecture/references/architecture-patterns.md +478 -0
  85. package/plugins/compound-engineering/skills/agent-native-architecture/references/dynamic-context-injection.md +338 -0
  86. package/plugins/compound-engineering/skills/agent-native-architecture/references/files-universal-interface.md +301 -0
  87. package/plugins/compound-engineering/skills/agent-native-architecture/references/from-primitives-to-domain-tools.md +359 -0
  88. package/plugins/compound-engineering/skills/agent-native-architecture/references/mcp-tool-design.md +506 -0
  89. package/plugins/compound-engineering/skills/agent-native-architecture/references/mobile-patterns.md +871 -0
  90. package/plugins/compound-engineering/skills/agent-native-architecture/references/product-implications.md +443 -0
  91. package/plugins/compound-engineering/skills/agent-native-architecture/references/refactoring-to-prompt-native.md +317 -0
  92. package/plugins/compound-engineering/skills/agent-native-architecture/references/self-modification.md +269 -0
  93. package/plugins/compound-engineering/skills/agent-native-architecture/references/shared-workspace-architecture.md +680 -0
  94. package/plugins/compound-engineering/skills/agent-native-architecture/references/system-prompt-design.md +250 -0
  95. package/plugins/compound-engineering/skills/andrew-kane-gem-writer/SKILL.md +184 -0
  96. package/plugins/compound-engineering/skills/andrew-kane-gem-writer/references/database-adapters.md +231 -0
  97. package/plugins/compound-engineering/skills/andrew-kane-gem-writer/references/module-organization.md +121 -0
  98. package/plugins/compound-engineering/skills/andrew-kane-gem-writer/references/rails-integration.md +183 -0
  99. package/plugins/compound-engineering/skills/andrew-kane-gem-writer/references/resources.md +119 -0
  100. package/plugins/compound-engineering/skills/andrew-kane-gem-writer/references/testing-patterns.md +261 -0
  101. package/plugins/compound-engineering/skills/brainstorming/SKILL.md +190 -0
  102. package/plugins/compound-engineering/skills/compound-docs/SKILL.md +511 -0
  103. package/plugins/compound-engineering/skills/compound-docs/assets/critical-pattern-template.md +34 -0
  104. package/plugins/compound-engineering/skills/compound-docs/assets/resolution-template.md +93 -0
  105. package/plugins/compound-engineering/skills/compound-docs/references/yaml-schema.md +65 -0
  106. package/plugins/compound-engineering/skills/compound-docs/schema.yaml +176 -0
  107. package/plugins/compound-engineering/skills/create-agent-skills/SKILL.md +275 -0
  108. package/plugins/compound-engineering/skills/create-agent-skills/references/api-security.md +226 -0
  109. package/plugins/compound-engineering/skills/create-agent-skills/references/be-clear-and-direct.md +531 -0
  110. package/plugins/compound-engineering/skills/create-agent-skills/references/best-practices.md +404 -0
  111. package/plugins/compound-engineering/skills/create-agent-skills/references/common-patterns.md +595 -0
  112. package/plugins/compound-engineering/skills/create-agent-skills/references/core-principles.md +437 -0
  113. package/plugins/compound-engineering/skills/create-agent-skills/references/executable-code.md +175 -0
  114. package/plugins/compound-engineering/skills/create-agent-skills/references/iteration-and-testing.md +474 -0
  115. package/plugins/compound-engineering/skills/create-agent-skills/references/official-spec.md +134 -0
  116. package/plugins/compound-engineering/skills/create-agent-skills/references/recommended-structure.md +168 -0
  117. package/plugins/compound-engineering/skills/create-agent-skills/references/skill-structure.md +152 -0
  118. package/plugins/compound-engineering/skills/create-agent-skills/references/using-scripts.md +113 -0
  119. package/plugins/compound-engineering/skills/create-agent-skills/references/using-templates.md +112 -0
  120. package/plugins/compound-engineering/skills/create-agent-skills/references/workflows-and-validation.md +510 -0
  121. package/plugins/compound-engineering/skills/create-agent-skills/templates/router-skill.md +73 -0
  122. package/plugins/compound-engineering/skills/create-agent-skills/templates/simple-skill.md +33 -0
  123. package/plugins/compound-engineering/skills/create-agent-skills/workflows/add-reference.md +96 -0
  124. package/plugins/compound-engineering/skills/create-agent-skills/workflows/add-script.md +93 -0
  125. package/plugins/compound-engineering/skills/create-agent-skills/workflows/add-template.md +74 -0
  126. package/plugins/compound-engineering/skills/create-agent-skills/workflows/add-workflow.md +120 -0
  127. package/plugins/compound-engineering/skills/create-agent-skills/workflows/audit-skill.md +138 -0
  128. package/plugins/compound-engineering/skills/create-agent-skills/workflows/create-domain-expertise-skill.md +605 -0
  129. package/plugins/compound-engineering/skills/create-agent-skills/workflows/create-new-skill.md +191 -0
  130. package/plugins/compound-engineering/skills/create-agent-skills/workflows/get-guidance.md +121 -0
  131. package/plugins/compound-engineering/skills/create-agent-skills/workflows/upgrade-to-router.md +161 -0
  132. package/plugins/compound-engineering/skills/create-agent-skills/workflows/verify-skill.md +204 -0
  133. package/plugins/compound-engineering/skills/dhh-rails-style/SKILL.md +185 -0
  134. package/plugins/compound-engineering/skills/dhh-rails-style/references/architecture.md +653 -0
  135. package/plugins/compound-engineering/skills/dhh-rails-style/references/controllers.md +303 -0
  136. package/plugins/compound-engineering/skills/dhh-rails-style/references/frontend.md +510 -0
  137. package/plugins/compound-engineering/skills/dhh-rails-style/references/gems.md +266 -0
  138. package/plugins/compound-engineering/skills/dhh-rails-style/references/models.md +359 -0
  139. package/plugins/compound-engineering/skills/dhh-rails-style/references/testing.md +338 -0
  140. package/plugins/compound-engineering/skills/document-review/SKILL.md +87 -0
  141. package/plugins/compound-engineering/skills/dspy-ruby/SKILL.md +737 -0
  142. package/plugins/compound-engineering/skills/dspy-ruby/assets/config-template.rb +187 -0
  143. package/plugins/compound-engineering/skills/dspy-ruby/assets/module-template.rb +300 -0
  144. package/plugins/compound-engineering/skills/dspy-ruby/assets/signature-template.rb +221 -0
  145. package/plugins/compound-engineering/skills/dspy-ruby/references/core-concepts.md +674 -0
  146. package/plugins/compound-engineering/skills/dspy-ruby/references/observability.md +366 -0
  147. package/plugins/compound-engineering/skills/dspy-ruby/references/optimization.md +603 -0
  148. package/plugins/compound-engineering/skills/dspy-ruby/references/providers.md +418 -0
  149. package/plugins/compound-engineering/skills/dspy-ruby/references/toolsets.md +502 -0
  150. package/plugins/compound-engineering/skills/every-style-editor/SKILL.md +134 -0
  151. package/plugins/compound-engineering/skills/every-style-editor/references/EVERY_WRITE_STYLE.md +529 -0
  152. package/plugins/compound-engineering/skills/file-todos/SKILL.md +252 -0
  153. package/plugins/compound-engineering/skills/file-todos/assets/todo-template.md +155 -0
  154. package/plugins/compound-engineering/skills/frontend-design/SKILL.md +42 -0
  155. package/plugins/compound-engineering/skills/gemini-imagegen/SKILL.md +237 -0
  156. package/plugins/compound-engineering/skills/gemini-imagegen/requirements.txt +2 -0
  157. package/plugins/compound-engineering/skills/gemini-imagegen/scripts/compose_images.py +157 -0
  158. package/plugins/compound-engineering/skills/gemini-imagegen/scripts/edit_image.py +144 -0
  159. package/plugins/compound-engineering/skills/gemini-imagegen/scripts/gemini_images.py +263 -0
  160. package/plugins/compound-engineering/skills/gemini-imagegen/scripts/generate_image.py +133 -0
  161. package/plugins/compound-engineering/skills/gemini-imagegen/scripts/multi_turn_chat.py +216 -0
  162. package/plugins/compound-engineering/skills/git-worktree/SKILL.md +302 -0
  163. package/plugins/compound-engineering/skills/git-worktree/scripts/worktree-manager.sh +337 -0
  164. package/plugins/compound-engineering/skills/orchestrating-swarms/SKILL.md +1718 -0
  165. package/plugins/compound-engineering/skills/rclone/SKILL.md +150 -0
  166. package/plugins/compound-engineering/skills/rclone/scripts/check_setup.sh +60 -0
  167. package/plugins/compound-engineering/skills/resolve-pr-parallel/SKILL.md +89 -0
  168. package/plugins/compound-engineering/skills/resolve-pr-parallel/scripts/get-pr-comments +68 -0
  169. package/plugins/compound-engineering/skills/resolve-pr-parallel/scripts/resolve-pr-thread +23 -0
  170. package/plugins/compound-engineering/skills/skill-creator/SKILL.md +210 -0
  171. package/plugins/compound-engineering/skills/skill-creator/scripts/init_skill.py +303 -0
  172. package/plugins/compound-engineering/skills/skill-creator/scripts/package_skill.py +110 -0
  173. package/plugins/compound-engineering/skills/skill-creator/scripts/quick_validate.py +65 -0
  174. package/prompts/deepen-plan.md +549 -0
  175. package/prompts/feature-video.md +341 -0
  176. package/prompts/resolve_todo_parallel.md +36 -0
  177. package/prompts/test-browser.md +342 -0
  178. package/prompts/workflows-brainstorm.md +123 -0
  179. package/prompts/workflows-compound.md +238 -0
  180. package/prompts/workflows-plan.md +550 -0
  181. package/prompts/workflows-review.md +529 -0
  182. package/prompts/workflows-work.md +432 -0
  183. package/skills/agent-browser/SKILL.md +223 -0
  184. package/skills/agent-native-architecture/SKILL.md +435 -0
  185. package/skills/agent-native-architecture/references/action-parity-discipline.md +409 -0
  186. package/skills/agent-native-architecture/references/agent-execution-patterns.md +467 -0
  187. package/skills/agent-native-architecture/references/agent-native-testing.md +582 -0
  188. package/skills/agent-native-architecture/references/architecture-patterns.md +478 -0
  189. package/skills/agent-native-architecture/references/dynamic-context-injection.md +338 -0
  190. package/skills/agent-native-architecture/references/files-universal-interface.md +301 -0
  191. package/skills/agent-native-architecture/references/from-primitives-to-domain-tools.md +359 -0
  192. package/skills/agent-native-architecture/references/mcp-tool-design.md +506 -0
  193. package/skills/agent-native-architecture/references/mobile-patterns.md +871 -0
  194. package/skills/agent-native-architecture/references/product-implications.md +443 -0
  195. package/skills/agent-native-architecture/references/refactoring-to-prompt-native.md +317 -0
  196. package/skills/agent-native-architecture/references/self-modification.md +269 -0
  197. package/skills/agent-native-architecture/references/shared-workspace-architecture.md +680 -0
  198. package/skills/agent-native-architecture/references/system-prompt-design.md +250 -0
  199. package/skills/agent-native-reviewer/SKILL.md +260 -0
  200. package/skills/andrew-kane-gem-writer/SKILL.md +184 -0
  201. package/skills/andrew-kane-gem-writer/references/database-adapters.md +231 -0
  202. package/skills/andrew-kane-gem-writer/references/module-organization.md +121 -0
  203. package/skills/andrew-kane-gem-writer/references/rails-integration.md +183 -0
  204. package/skills/andrew-kane-gem-writer/references/resources.md +119 -0
  205. package/skills/andrew-kane-gem-writer/references/testing-patterns.md +261 -0
  206. package/skills/ankane-readme-writer/SKILL.md +63 -0
  207. package/skills/architecture-strategist/SKILL.md +66 -0
  208. package/skills/best-practices-researcher/SKILL.md +125 -0
  209. package/skills/brainstorming/SKILL.md +190 -0
  210. package/skills/bug-reproduction-validator/SKILL.md +81 -0
  211. package/skills/code-simplicity-reviewer/SKILL.md +100 -0
  212. package/skills/compound-docs/SKILL.md +511 -0
  213. package/skills/compound-docs/assets/critical-pattern-template.md +34 -0
  214. package/skills/compound-docs/assets/resolution-template.md +93 -0
  215. package/skills/compound-docs/references/yaml-schema.md +65 -0
  216. package/skills/compound-docs/schema.yaml +176 -0
  217. package/skills/create-agent-skills/SKILL.md +275 -0
  218. package/skills/create-agent-skills/references/api-security.md +226 -0
  219. package/skills/create-agent-skills/references/be-clear-and-direct.md +531 -0
  220. package/skills/create-agent-skills/references/best-practices.md +404 -0
  221. package/skills/create-agent-skills/references/common-patterns.md +595 -0
  222. package/skills/create-agent-skills/references/core-principles.md +437 -0
  223. package/skills/create-agent-skills/references/executable-code.md +175 -0
  224. package/skills/create-agent-skills/references/iteration-and-testing.md +474 -0
  225. package/skills/create-agent-skills/references/official-spec.md +134 -0
  226. package/skills/create-agent-skills/references/recommended-structure.md +168 -0
  227. package/skills/create-agent-skills/references/skill-structure.md +152 -0
  228. package/skills/create-agent-skills/references/using-scripts.md +113 -0
  229. package/skills/create-agent-skills/references/using-templates.md +112 -0
  230. package/skills/create-agent-skills/references/workflows-and-validation.md +510 -0
  231. package/skills/create-agent-skills/templates/router-skill.md +73 -0
  232. package/skills/create-agent-skills/templates/simple-skill.md +33 -0
  233. package/skills/create-agent-skills/workflows/add-reference.md +96 -0
  234. package/skills/create-agent-skills/workflows/add-script.md +93 -0
  235. package/skills/create-agent-skills/workflows/add-template.md +74 -0
  236. package/skills/create-agent-skills/workflows/add-workflow.md +120 -0
  237. package/skills/create-agent-skills/workflows/audit-skill.md +138 -0
  238. package/skills/create-agent-skills/workflows/create-domain-expertise-skill.md +605 -0
  239. package/skills/create-agent-skills/workflows/create-new-skill.md +191 -0
  240. package/skills/create-agent-skills/workflows/get-guidance.md +121 -0
  241. package/skills/create-agent-skills/workflows/upgrade-to-router.md +161 -0
  242. package/skills/create-agent-skills/workflows/verify-skill.md +204 -0
  243. package/skills/data-integrity-guardian/SKILL.md +84 -0
  244. package/skills/data-migration-expert/SKILL.md +111 -0
  245. package/skills/deployment-verification-agent/SKILL.md +173 -0
  246. package/skills/design-implementation-reviewer/SKILL.md +107 -0
  247. package/skills/design-iterator/SKILL.md +222 -0
  248. package/skills/dhh-rails-reviewer/SKILL.md +65 -0
  249. package/skills/dhh-rails-style/SKILL.md +185 -0
  250. package/skills/dhh-rails-style/references/architecture.md +653 -0
  251. package/skills/dhh-rails-style/references/controllers.md +303 -0
  252. package/skills/dhh-rails-style/references/frontend.md +510 -0
  253. package/skills/dhh-rails-style/references/gems.md +266 -0
  254. package/skills/dhh-rails-style/references/models.md +359 -0
  255. package/skills/dhh-rails-style/references/testing.md +338 -0
  256. package/skills/document-review/SKILL.md +87 -0
  257. package/skills/dspy-ruby/SKILL.md +737 -0
  258. package/skills/dspy-ruby/assets/config-template.rb +187 -0
  259. package/skills/dspy-ruby/assets/module-template.rb +300 -0
  260. package/skills/dspy-ruby/assets/signature-template.rb +221 -0
  261. package/skills/dspy-ruby/references/core-concepts.md +674 -0
  262. package/skills/dspy-ruby/references/observability.md +366 -0
  263. package/skills/dspy-ruby/references/optimization.md +603 -0
  264. package/skills/dspy-ruby/references/providers.md +418 -0
  265. package/skills/dspy-ruby/references/toolsets.md +502 -0
  266. package/skills/every-style-editor/SKILL.md +134 -0
  267. package/skills/every-style-editor/references/EVERY_WRITE_STYLE.md +529 -0
  268. package/skills/every-style-editor-2/SKILL.md +62 -0
  269. package/skills/figma-design-sync/SKILL.md +188 -0
  270. package/skills/file-todos/SKILL.md +252 -0
  271. package/skills/file-todos/assets/todo-template.md +155 -0
  272. package/skills/framework-docs-researcher/SKILL.md +105 -0
  273. package/skills/frontend-design/SKILL.md +42 -0
  274. package/skills/gemini-imagegen/SKILL.md +237 -0
  275. package/skills/gemini-imagegen/requirements.txt +2 -0
  276. package/skills/gemini-imagegen/scripts/compose_images.py +157 -0
  277. package/skills/gemini-imagegen/scripts/edit_image.py +144 -0
  278. package/skills/gemini-imagegen/scripts/gemini_images.py +263 -0
  279. package/skills/gemini-imagegen/scripts/generate_image.py +133 -0
  280. package/skills/gemini-imagegen/scripts/multi_turn_chat.py +216 -0
  281. package/skills/git-history-analyzer/SKILL.md +58 -0
  282. package/skills/git-worktree/SKILL.md +302 -0
  283. package/skills/git-worktree/scripts/worktree-manager.sh +337 -0
  284. package/skills/julik-frontend-races-reviewer/SKILL.md +220 -0
  285. package/skills/kieran-python-reviewer/SKILL.md +132 -0
  286. package/skills/kieran-rails-reviewer/SKILL.md +114 -0
  287. package/skills/kieran-typescript-reviewer/SKILL.md +123 -0
  288. package/skills/learnings-researcher/SKILL.md +263 -0
  289. package/skills/lint/SKILL.md +14 -0
  290. package/skills/orchestrating-swarms/SKILL.md +1718 -0
  291. package/skills/pattern-recognition-specialist/SKILL.md +71 -0
  292. package/skills/performance-oracle/SKILL.md +136 -0
  293. package/skills/pr-comment-resolver/SKILL.md +82 -0
  294. package/skills/rclone/SKILL.md +150 -0
  295. package/skills/rclone/scripts/check_setup.sh +60 -0
  296. package/skills/repo-research-analyst/SKILL.md +134 -0
  297. package/skills/resolve_pr_parallel/SKILL.md +89 -0
  298. package/skills/resolve_pr_parallel/scripts/get-pr-comments +68 -0
  299. package/skills/resolve_pr_parallel/scripts/resolve-pr-thread +23 -0
  300. package/skills/schema-drift-detector/SKILL.md +153 -0
  301. package/skills/security-sentinel/SKILL.md +113 -0
  302. package/skills/skill-creator/SKILL.md +210 -0
  303. package/skills/skill-creator/scripts/init_skill.py +303 -0
  304. package/skills/skill-creator/scripts/package_skill.py +110 -0
  305. package/skills/skill-creator/scripts/quick_validate.py +65 -0
  306. package/skills/spec-flow-analyzer/SKILL.md +133 -0
  307. package/src/commands/convert.ts +183 -0
  308. package/src/commands/install.ts +273 -0
  309. package/src/commands/list.ts +37 -0
  310. package/src/commands/sync.ts +89 -0
  311. package/src/converters/claude-to-codex.ts +182 -0
  312. package/src/converters/claude-to-opencode.ts +395 -0
  313. package/src/converters/claude-to-pi.ts +205 -0
  314. package/src/index.ts +22 -0
  315. package/src/parsers/claude-home.ts +65 -0
  316. package/src/parsers/claude.ts +252 -0
  317. package/src/sync/codex.ts +92 -0
  318. package/src/sync/opencode.ts +75 -0
  319. package/src/sync/pi.ts +88 -0
  320. package/src/targets/codex.ts +96 -0
  321. package/src/targets/index.ts +38 -0
  322. package/src/targets/opencode.ts +57 -0
  323. package/src/targets/pi.ts +131 -0
  324. package/src/templates/pi/compat-extension.ts +452 -0
  325. package/src/types/claude.ts +90 -0
  326. package/src/types/codex.ts +23 -0
  327. package/src/types/opencode.ts +54 -0
  328. package/src/types/pi.ts +40 -0
  329. package/src/utils/codex-agents.ts +64 -0
  330. package/src/utils/files.ts +77 -0
  331. package/src/utils/frontmatter.ts +65 -0
  332. package/src/utils/symlink.ts +43 -0
@@ -0,0 +1,737 @@
1
+ ---
2
+ name: dspy-ruby
3
+ description: Build type-safe LLM applications with DSPy.rb — Ruby's programmatic prompt framework with signatures, modules, agents, and optimization. Use when implementing predictable AI features, creating LLM signatures and modules, configuring language model providers, building agent systems with tools, optimizing prompts, or testing LLM-powered functionality in Ruby applications.
4
+ ---
5
+
6
+ # DSPy.rb
7
+
8
+ > Build LLM apps like you build software. Type-safe, modular, testable.
9
+
10
+ DSPy.rb brings software engineering best practices to LLM development. Instead of tweaking prompts, define what you want with Ruby types and let DSPy handle the rest.
11
+
12
+ ## Overview
13
+
14
+ DSPy.rb is a Ruby framework for building language model applications with programmatic prompts. It provides:
15
+
16
+ - **Type-safe signatures** — Define inputs/outputs with Sorbet types
17
+ - **Modular components** — Compose and reuse LLM logic
18
+ - **Automatic optimization** — Use data to improve prompts, not guesswork
19
+ - **Production-ready** — Built-in observability, testing, and error handling
20
+
21
+ ## Core Concepts
22
+
23
+ ### 1. Signatures
24
+
25
+ Define interfaces between your app and LLMs using Ruby types:
26
+
27
+ ```ruby
28
+ class EmailClassifier < DSPy::Signature
29
+ description "Classify customer support emails by category and priority"
30
+
31
+ class Priority < T::Enum
32
+ enums do
33
+ Low = new('low')
34
+ Medium = new('medium')
35
+ High = new('high')
36
+ Urgent = new('urgent')
37
+ end
38
+ end
39
+
40
+ input do
41
+ const :email_content, String
42
+ const :sender, String
43
+ end
44
+
45
+ output do
46
+ const :category, String
47
+ const :priority, Priority # Type-safe enum with defined values
48
+ const :confidence, Float
49
+ end
50
+ end
51
+ ```
52
+
53
+ ### 2. Modules
54
+
55
+ Build complex workflows from simple building blocks:
56
+
57
+ - **Predict** — Basic LLM calls with signatures
58
+ - **ChainOfThought** — Step-by-step reasoning
59
+ - **ReAct** — Tool-using agents
60
+ - **CodeAct** — Dynamic code generation agents (install the `dspy-code_act` gem)
61
+
62
+ ### 3. Tools & Toolsets
63
+
64
+ Create type-safe tools for agents with comprehensive Sorbet support:
65
+
66
+ ```ruby
67
+ # Enum-based tool with automatic type conversion
68
+ class CalculatorTool < DSPy::Tools::Base
69
+ tool_name 'calculator'
70
+ tool_description 'Performs arithmetic operations with type-safe enum inputs'
71
+
72
+ class Operation < T::Enum
73
+ enums do
74
+ Add = new('add')
75
+ Subtract = new('subtract')
76
+ Multiply = new('multiply')
77
+ Divide = new('divide')
78
+ end
79
+ end
80
+
81
+ sig { params(operation: Operation, num1: Float, num2: Float).returns(T.any(Float, String)) }
82
+ def call(operation:, num1:, num2:)
83
+ case operation
84
+ when Operation::Add then num1 + num2
85
+ when Operation::Subtract then num1 - num2
86
+ when Operation::Multiply then num1 * num2
87
+ when Operation::Divide
88
+ return "Error: Division by zero" if num2 == 0
89
+ num1 / num2
90
+ end
91
+ end
92
+ end
93
+
94
+ # Multi-tool toolset with rich types
95
+ class DataToolset < DSPy::Tools::Toolset
96
+ toolset_name "data_processing"
97
+
98
+ class Format < T::Enum
99
+ enums do
100
+ JSON = new('json')
101
+ CSV = new('csv')
102
+ XML = new('xml')
103
+ end
104
+ end
105
+
106
+ tool :convert, description: "Convert data between formats"
107
+ tool :validate, description: "Validate data structure"
108
+
109
+ sig { params(data: String, from: Format, to: Format).returns(String) }
110
+ def convert(data:, from:, to:)
111
+ "Converted from #{from.serialize} to #{to.serialize}"
112
+ end
113
+
114
+ sig { params(data: String, format: Format).returns(T::Hash[String, T.any(String, Integer, T::Boolean)]) }
115
+ def validate(data:, format:)
116
+ { valid: true, format: format.serialize, row_count: 42, message: "Data validation passed" }
117
+ end
118
+ end
119
+ ```
120
+
121
+ ### 4. Type System & Discriminators
122
+
123
+ DSPy.rb uses sophisticated type discrimination for complex data structures:
124
+
125
+ - **Automatic `_type` field injection** — DSPy adds discriminator fields to structs for type safety
126
+ - **Union type support** — `T.any()` types automatically disambiguated by `_type`
127
+ - **Reserved field name** — Avoid defining your own `_type` fields in structs
128
+ - **Recursive filtering** — `_type` fields filtered during deserialization at all nesting levels
129
+
130
+ ### 5. Optimization
131
+
132
+ Improve accuracy with real data:
133
+
134
+ - **MIPROv2** — Advanced multi-prompt optimization with bootstrap sampling and Bayesian optimization
135
+ - **GEPA** — Genetic-Pareto Reflective Prompt Evolution with feedback maps, experiment tracking, and telemetry
136
+ - **Evaluation** — Comprehensive framework with built-in and custom metrics, error handling, and batch processing
137
+
138
+ ## Quick Start
139
+
140
+ ```ruby
141
+ # Install
142
+ gem 'dspy'
143
+
144
+ # Configure
145
+ DSPy.configure do |c|
146
+ c.lm = DSPy::LM.new('openai/gpt-4o-mini', api_key: ENV['OPENAI_API_KEY'])
147
+ end
148
+
149
+ # Define a task
150
+ class SentimentAnalysis < DSPy::Signature
151
+ description "Analyze sentiment of text"
152
+
153
+ input do
154
+ const :text, String
155
+ end
156
+
157
+ output do
158
+ const :sentiment, String # positive, negative, neutral
159
+ const :score, Float # 0.0 to 1.0
160
+ end
161
+ end
162
+
163
+ # Use it
164
+ analyzer = DSPy::Predict.new(SentimentAnalysis)
165
+ result = analyzer.call(text: "This product is amazing!")
166
+ puts result.sentiment # => "positive"
167
+ puts result.score # => 0.92
168
+ ```
169
+
170
+ ## Provider Adapter Gems
171
+
172
+ Two strategies for connecting to LLM providers:
173
+
174
+ ### Per-provider adapters (direct SDK access)
175
+
176
+ ```ruby
177
+ # Gemfile
178
+ gem 'dspy'
179
+ gem 'dspy-openai' # OpenAI, OpenRouter, Ollama
180
+ gem 'dspy-anthropic' # Claude
181
+ gem 'dspy-gemini' # Gemini
182
+ ```
183
+
184
+ Each adapter gem pulls in the official SDK (`openai`, `anthropic`, `gemini-ai`).
185
+
186
+ ### Unified adapter via RubyLLM (recommended for multi-provider)
187
+
188
+ ```ruby
189
+ # Gemfile
190
+ gem 'dspy'
191
+ gem 'dspy-ruby_llm' # Routes to any provider via ruby_llm
192
+ gem 'ruby_llm'
193
+ ```
194
+
195
+ RubyLLM handles provider routing based on the model name. Use the `ruby_llm/` prefix:
196
+
197
+ ```ruby
198
+ DSPy.configure do |c|
199
+ c.lm = DSPy::LM.new('ruby_llm/gemini-2.5-flash', structured_outputs: true)
200
+ # c.lm = DSPy::LM.new('ruby_llm/claude-sonnet-4-20250514', structured_outputs: true)
201
+ # c.lm = DSPy::LM.new('ruby_llm/gpt-4o-mini', structured_outputs: true)
202
+ end
203
+ ```
204
+
205
+ ## Events System
206
+
207
+ DSPy.rb ships with a structured event bus for observing runtime behavior.
208
+
209
+ ### Module-Scoped Subscriptions (preferred for agents)
210
+
211
+ ```ruby
212
+ class MyAgent < DSPy::Module
213
+ subscribe 'lm.tokens', :track_tokens, scope: :descendants
214
+
215
+ def track_tokens(_event, attrs)
216
+ @total_tokens += attrs.fetch(:total_tokens, 0)
217
+ end
218
+ end
219
+ ```
220
+
221
+ ### Global Subscriptions (for observability/integrations)
222
+
223
+ ```ruby
224
+ subscription_id = DSPy.events.subscribe('score.create') do |event, attrs|
225
+ Langfuse.export_score(attrs)
226
+ end
227
+
228
+ # Wildcards supported
229
+ DSPy.events.subscribe('llm.*') { |name, attrs| puts "[#{name}] tokens=#{attrs[:total_tokens]}" }
230
+ ```
231
+
232
+ Event names use dot-separated namespaces (`llm.generate`, `react.iteration_complete`). Every event includes module metadata (`module_path`, `module_leaf`, `module_scope.ancestry_token`) for filtering.
233
+
234
+ ## Lifecycle Callbacks
235
+
236
+ Rails-style lifecycle hooks ship with every `DSPy::Module`:
237
+
238
+ - **`before`** — Runs ahead of `forward` for setup (metrics, context loading)
239
+ - **`around`** — Wraps `forward`, calls `yield`, and lets you pair setup/teardown logic
240
+ - **`after`** — Fires after `forward` returns for cleanup or persistence
241
+
242
+ ```ruby
243
+ class InstrumentedModule < DSPy::Module
244
+ before :setup_metrics
245
+ around :manage_context
246
+ after :log_metrics
247
+
248
+ def forward(question:)
249
+ @predictor.call(question: question)
250
+ end
251
+
252
+ private
253
+
254
+ def setup_metrics
255
+ @start_time = Time.now
256
+ end
257
+
258
+ def manage_context
259
+ load_context
260
+ result = yield
261
+ save_context
262
+ result
263
+ end
264
+
265
+ def log_metrics
266
+ duration = Time.now - @start_time
267
+ Rails.logger.info "Prediction completed in #{duration}s"
268
+ end
269
+ end
270
+ ```
271
+
272
+ Execution order: before → around (before yield) → forward → around (after yield) → after. Callbacks are inherited from parent classes and execute in registration order.
273
+
274
+ ## Fiber-Local LM Context
275
+
276
+ Override the language model temporarily using fiber-local storage:
277
+
278
+ ```ruby
279
+ fast_model = DSPy::LM.new("openai/gpt-4o-mini", api_key: ENV['OPENAI_API_KEY'])
280
+
281
+ DSPy.with_lm(fast_model) do
282
+ result = classifier.call(text: "test") # Uses fast_model inside this block
283
+ end
284
+ # Back to global LM outside the block
285
+ ```
286
+
287
+ **LM resolution hierarchy**: Instance-level LM → Fiber-local LM (`DSPy.with_lm`) → Global LM (`DSPy.configure`).
288
+
289
+ Use `configure_predictor` for fine-grained control over agent internals:
290
+
291
+ ```ruby
292
+ agent = DSPy::ReAct.new(MySignature, tools: tools)
293
+ agent.configure { |c| c.lm = default_model }
294
+ agent.configure_predictor('thought_generator') { |c| c.lm = powerful_model }
295
+ ```
296
+
297
+ ## Evaluation Framework
298
+
299
+ Systematically test LLM application performance with `DSPy::Evals`:
300
+
301
+ ```ruby
302
+ metric = DSPy::Metrics.exact_match(field: :answer, case_sensitive: false)
303
+ evaluator = DSPy::Evals.new(predictor, metric: metric)
304
+ result = evaluator.evaluate(test_examples, display_table: true)
305
+ puts "Pass Rate: #{(result.pass_rate * 100).round(1)}%"
306
+ ```
307
+
308
+ Built-in metrics: `exact_match`, `contains`, `numeric_difference`, `composite_and`. Custom metrics return `true`/`false` or a `DSPy::Prediction` with `score:` and `feedback:` fields.
309
+
310
+ Use `DSPy::Example` for typed test data and `export_scores: true` to push results to Langfuse.
311
+
312
+ ## GEPA Optimization
313
+
314
+ GEPA (Genetic-Pareto Reflective Prompt Evolution) uses reflection-driven instruction rewrites:
315
+
316
+ ```ruby
317
+ gem 'dspy-gepa'
318
+
319
+ teleprompter = DSPy::Teleprompt::GEPA.new(
320
+ metric: metric,
321
+ reflection_lm: DSPy::ReflectionLM.new('openai/gpt-4o-mini', api_key: ENV['OPENAI_API_KEY']),
322
+ feedback_map: feedback_map,
323
+ config: { max_metric_calls: 600, minibatch_size: 6 }
324
+ )
325
+
326
+ result = teleprompter.compile(program, trainset: train, valset: val)
327
+ optimized_program = result.optimized_program
328
+ ```
329
+
330
+ The metric must return `DSPy::Prediction.new(score:, feedback:)` so the reflection model can reason about failures. Use `feedback_map` to target individual predictors in composite modules.
331
+
332
+ ## Typed Context Pattern
333
+
334
+ Replace opaque string context blobs with `T::Struct` inputs. Each field gets its own `description:` annotation in the JSON schema the LLM sees:
335
+
336
+ ```ruby
337
+ class NavigationContext < T::Struct
338
+ const :workflow_hint, T.nilable(String),
339
+ description: "Current workflow phase guidance for the agent"
340
+ const :action_log, T::Array[String], default: [],
341
+ description: "Compact one-line-per-action history of research steps taken"
342
+ const :iterations_remaining, Integer,
343
+ description: "Budget remaining. Each tool call costs 1 iteration."
344
+ end
345
+
346
+ class ToolSelectionSignature < DSPy::Signature
347
+ input do
348
+ const :query, String
349
+ const :context, NavigationContext # Structured, not an opaque string
350
+ end
351
+
352
+ output do
353
+ const :tool_name, String
354
+ const :tool_args, String, description: "JSON-encoded arguments"
355
+ end
356
+ end
357
+ ```
358
+
359
+ Benefits: type safety at compile time, per-field descriptions in the LLM schema, easy to test as value objects, extensible by adding `const` declarations.
360
+
361
+ ## Schema Formats (BAML / TOON)
362
+
363
+ Control how DSPy describes signature structure to the LLM:
364
+
365
+ - **JSON Schema** (default) — Standard format, works with `structured_outputs: true`
366
+ - **BAML** (`schema_format: :baml`) — 84% token reduction for Enhanced Prompting mode. Requires `sorbet-baml` gem.
367
+ - **TOON** (`schema_format: :toon, data_format: :toon`) — Table-oriented format for both schemas and data. Enhanced Prompting mode only.
368
+
369
+ BAML and TOON apply only when `structured_outputs: false`. With `structured_outputs: true`, the provider receives JSON Schema directly.
370
+
371
+ ## Storage System
372
+
373
+ Persist and reload optimized programs with `DSPy::Storage::ProgramStorage`:
374
+
375
+ ```ruby
376
+ storage = DSPy::Storage::ProgramStorage.new(storage_path: "./dspy_storage")
377
+ storage.save_program(result.optimized_program, result, metadata: { optimizer: 'MIPROv2' })
378
+ ```
379
+
380
+ Supports checkpoint management, optimization history tracking, and import/export between environments.
381
+
382
+ ## Rails Integration
383
+
384
+ ### Directory Structure
385
+
386
+ Organize DSPy components using Rails conventions:
387
+
388
+ ```
389
+ app/
390
+ entities/ # T::Struct types shared across signatures
391
+ signatures/ # DSPy::Signature definitions
392
+ tools/ # DSPy::Tools::Base implementations
393
+ concerns/ # Shared tool behaviors (error handling, etc.)
394
+ modules/ # DSPy::Module orchestrators
395
+ services/ # Plain Ruby services that compose DSPy modules
396
+ config/
397
+ initializers/
398
+ dspy.rb # DSPy + provider configuration
399
+ feature_flags.rb # Model selection per role
400
+ spec/
401
+ signatures/ # Schema validation tests
402
+ tools/ # Tool unit tests
403
+ modules/ # Integration tests with VCR
404
+ vcr_cassettes/ # Recorded HTTP interactions
405
+ ```
406
+
407
+ ### Initializer
408
+
409
+ ```ruby
410
+ # config/initializers/dspy.rb
411
+ Rails.application.config.after_initialize do
412
+ next if Rails.env.test? && ENV["DSPY_ENABLE_IN_TEST"].blank?
413
+
414
+ RubyLLM.configure do |config|
415
+ config.gemini_api_key = ENV["GEMINI_API_KEY"] if ENV["GEMINI_API_KEY"].present?
416
+ config.anthropic_api_key = ENV["ANTHROPIC_API_KEY"] if ENV["ANTHROPIC_API_KEY"].present?
417
+ config.openai_api_key = ENV["OPENAI_API_KEY"] if ENV["OPENAI_API_KEY"].present?
418
+ end
419
+
420
+ model = ENV.fetch("DSPY_MODEL", "ruby_llm/gemini-2.5-flash")
421
+ DSPy.configure do |config|
422
+ config.lm = DSPy::LM.new(model, structured_outputs: true)
423
+ config.logger = Rails.logger
424
+ end
425
+
426
+ # Langfuse observability (optional)
427
+ if ENV["LANGFUSE_PUBLIC_KEY"].present? && ENV["LANGFUSE_SECRET_KEY"].present?
428
+ DSPy::Observability.configure!
429
+ end
430
+ end
431
+ ```
432
+
433
+ ### Feature-Flagged Model Selection
434
+
435
+ Use different models for different roles (fast/cheap for classification, powerful for synthesis):
436
+
437
+ ```ruby
438
+ # config/initializers/feature_flags.rb
439
+ module FeatureFlags
440
+ SELECTOR_MODEL = ENV.fetch("DSPY_SELECTOR_MODEL", "ruby_llm/gemini-2.5-flash-lite")
441
+ SYNTHESIZER_MODEL = ENV.fetch("DSPY_SYNTHESIZER_MODEL", "ruby_llm/gemini-2.5-flash")
442
+ end
443
+ ```
444
+
445
+ Then override per-tool or per-predictor:
446
+
447
+ ```ruby
448
+ class ClassifyTool < DSPy::Tools::Base
449
+ def call(query:)
450
+ predictor = DSPy::Predict.new(ClassifyQuery)
451
+ predictor.configure { |c| c.lm = DSPy::LM.new(FeatureFlags::SELECTOR_MODEL, structured_outputs: true) }
452
+ predictor.call(query: query)
453
+ end
454
+ end
455
+ ```
456
+
457
+ ## Schema-Driven Signatures
458
+
459
+ **Prefer typed schemas over string descriptions.** Let the type system communicate structure to the LLM rather than prose in the signature description.
460
+
461
+ ### Entities as Shared Types
462
+
463
+ Define reusable `T::Struct` and `T::Enum` types in `app/entities/` and reference them across signatures:
464
+
465
+ ```ruby
466
+ # app/entities/search_strategy.rb
467
+ class SearchStrategy < T::Enum
468
+ enums do
469
+ SingleSearch = new("single_search")
470
+ DateDecomposition = new("date_decomposition")
471
+ end
472
+ end
473
+
474
+ # app/entities/scored_item.rb
475
+ class ScoredItem < T::Struct
476
+ const :id, String
477
+ const :score, Float, description: "Relevance score 0.0-1.0"
478
+ const :verdict, String, description: "relevant, maybe, or irrelevant"
479
+ const :reason, String, default: ""
480
+ end
481
+ ```
482
+
483
+ ### Schema vs Description: When to Use Each
484
+
485
+ **Use schemas (T::Struct/T::Enum)** for:
486
+ - Multi-field outputs with specific types
487
+ - Enums with defined values the LLM must pick from
488
+ - Nested structures, arrays of typed objects
489
+ - Outputs consumed by code (not displayed to users)
490
+
491
+ **Use string descriptions** for:
492
+ - Simple single-field outputs where the type is `String`
493
+ - Natural language generation (summaries, answers)
494
+ - Fields where constraint guidance helps (e.g., `description: "YYYY-MM-DD format"`)
495
+
496
+ **Rule of thumb**: If you'd write a `case` statement on the output, it should be a `T::Enum`. If you'd call `.each` on it, it should be `T::Array[SomeStruct]`.
497
+
498
+ ## Tool Patterns
499
+
500
+ ### Tools That Wrap Predictions
501
+
502
+ A common pattern: tools encapsulate a DSPy prediction, adding error handling, model selection, and serialization:
503
+
504
+ ```ruby
505
+ class RerankTool < DSPy::Tools::Base
506
+ tool_name "rerank"
507
+ tool_description "Score and rank search results by relevance"
508
+
509
+ MAX_ITEMS = 200
510
+ MIN_ITEMS_FOR_LLM = 5
511
+
512
+ sig { params(query: String, items: T::Array[T::Hash[Symbol, T.untyped]]).returns(T::Hash[Symbol, T.untyped]) }
513
+ def call(query:, items: [])
514
+ return { scored_items: items, reranked: false } if items.size < MIN_ITEMS_FOR_LLM
515
+
516
+ capped_items = items.first(MAX_ITEMS)
517
+ predictor = DSPy::Predict.new(RerankSignature)
518
+ predictor.configure { |c| c.lm = DSPy::LM.new(FeatureFlags::SYNTHESIZER_MODEL, structured_outputs: true) }
519
+
520
+ result = predictor.call(query: query, items: capped_items)
521
+ { scored_items: result.scored_items, reranked: true }
522
+ rescue => e
523
+ Rails.logger.warn "[RerankTool] LLM rerank failed: #{e.message}"
524
+ { error: "Rerank failed: #{e.message}", scored_items: items, reranked: false }
525
+ end
526
+ end
527
+ ```
528
+
529
+ **Key patterns:**
530
+ - Short-circuit LLM calls when unnecessary (small data, trivial cases)
531
+ - Cap input size to prevent token overflow
532
+ - Per-tool model selection via `configure`
533
+ - Graceful error handling with fallback data
534
+
535
+ ### Error Handling Concern
536
+
537
+ ```ruby
538
+ module ErrorHandling
539
+ extend ActiveSupport::Concern
540
+
541
+ private
542
+
543
+ def safe_predict(signature_class, **inputs)
544
+ predictor = DSPy::Predict.new(signature_class)
545
+ yield predictor if block_given?
546
+ predictor.call(**inputs)
547
+ rescue Faraday::Error, Net::HTTPError => e
548
+ Rails.logger.error "[#{self.class.name}] API error: #{e.message}"
549
+ nil
550
+ rescue JSON::ParserError => e
551
+ Rails.logger.error "[#{self.class.name}] Invalid LLM output: #{e.message}"
552
+ nil
553
+ end
554
+ end
555
+ ```
556
+
557
+ ## Observability
558
+
559
+ ### Tracing with DSPy::Context
560
+
561
+ Wrap operations in spans for Langfuse/OpenTelemetry visibility:
562
+
563
+ ```ruby
564
+ result = DSPy::Context.with_span(
565
+ operation: "tool_selector.select",
566
+ "dspy.module" => "ToolSelector",
567
+ "tool_selector.tools" => tool_names.join(",")
568
+ ) do
569
+ @predictor.call(query: query, context: context, available_tools: schemas)
570
+ end
571
+ ```
572
+
573
+ ### Setup for Langfuse
574
+
575
+ ```ruby
576
+ # Gemfile
577
+ gem 'dspy-o11y'
578
+ gem 'dspy-o11y-langfuse'
579
+
580
+ # .env
581
+ LANGFUSE_PUBLIC_KEY=pk-...
582
+ LANGFUSE_SECRET_KEY=sk-...
583
+ DSPY_TELEMETRY_BATCH_SIZE=5
584
+ ```
585
+
586
+ Every `DSPy::Predict`, `DSPy::ReAct`, and tool call is automatically traced when observability is configured.
587
+
588
+ ### Score Reporting
589
+
590
+ Report evaluation scores to Langfuse:
591
+
592
+ ```ruby
593
+ DSPy.score(name: "relevance", value: 0.85, trace_id: current_trace_id)
594
+ ```
595
+
596
+ ## Testing
597
+
598
+ ### VCR Setup for Rails
599
+
600
+ ```ruby
601
+ VCR.configure do |config|
602
+ config.cassette_library_dir = "spec/vcr_cassettes"
603
+ config.hook_into :webmock
604
+ config.configure_rspec_metadata!
605
+ config.filter_sensitive_data('<GEMINI_API_KEY>') { ENV['GEMINI_API_KEY'] }
606
+ config.filter_sensitive_data('<OPENAI_API_KEY>') { ENV['OPENAI_API_KEY'] }
607
+ end
608
+ ```
609
+
610
+ ### Signature Schema Tests
611
+
612
+ Test that signatures produce valid schemas without calling any LLM:
613
+
614
+ ```ruby
615
+ RSpec.describe ClassifyResearchQuery do
616
+ it "has required input fields" do
617
+ schema = described_class.input_json_schema
618
+ expect(schema[:required]).to include("query")
619
+ end
620
+
621
+ it "has typed output fields" do
622
+ schema = described_class.output_json_schema
623
+ expect(schema[:properties]).to have_key(:search_strategy)
624
+ end
625
+ end
626
+ ```
627
+
628
+ ### Tool Tests with Mocked Predictions
629
+
630
+ ```ruby
631
+ RSpec.describe RerankTool do
632
+ let(:tool) { described_class.new }
633
+
634
+ it "skips LLM for small result sets" do
635
+ expect(DSPy::Predict).not_to receive(:new)
636
+ result = tool.call(query: "test", items: [{ id: "1" }])
637
+ expect(result[:reranked]).to be false
638
+ end
639
+
640
+ it "calls LLM for large result sets", :vcr do
641
+ items = 10.times.map { |i| { id: i.to_s, title: "Item #{i}" } }
642
+ result = tool.call(query: "relevant items", items: items)
643
+ expect(result[:reranked]).to be true
644
+ end
645
+ end
646
+ ```
647
+
648
+ ## Resources
649
+
650
+ - [core-concepts.md](./references/core-concepts.md) — Signatures, modules, predictors, type system deep-dive
651
+ - [toolsets.md](./references/toolsets.md) — Tools::Base, Tools::Toolset DSL, type safety, testing
652
+ - [providers.md](./references/providers.md) — Provider adapters, RubyLLM, fiber-local LM context, compatibility matrix
653
+ - [optimization.md](./references/optimization.md) — MIPROv2, GEPA, evaluation framework, storage system
654
+ - [observability.md](./references/observability.md) — Event system, dspy-o11y gems, Langfuse, score reporting
655
+ - [signature-template.rb](./assets/signature-template.rb) — Signature scaffold with T::Enum, Date/Time, defaults, union types
656
+ - [module-template.rb](./assets/module-template.rb) — Module scaffold with .call(), lifecycle callbacks, fiber-local LM
657
+ - [config-template.rb](./assets/config-template.rb) — Rails initializer with RubyLLM, observability, feature flags
658
+
659
+ ## Key URLs
660
+
661
+ - Homepage: https://oss.vicente.services/dspy.rb/
662
+ - GitHub: https://github.com/vicentereig/dspy.rb
663
+ - Documentation: https://oss.vicente.services/dspy.rb/getting-started/
664
+
665
+ ## Guidelines for Claude
666
+
667
+ When helping users with DSPy.rb:
668
+
669
+ 1. **Schema over prose** — Define output structure with `T::Struct` and `T::Enum` types, not string descriptions
670
+ 2. **Entities in `app/entities/`** — Extract shared types so signatures stay thin
671
+ 3. **Per-tool model selection** — Use `predictor.configure { |c| c.lm = ... }` to pick the right model per task
672
+ 4. **Short-circuit LLM calls** — Skip the LLM for trivial cases (small data, cached results)
673
+ 5. **Cap input sizes** — Prevent token overflow by limiting array sizes before sending to LLM
674
+ 6. **Test schemas without LLM** — Validate `input_json_schema` and `output_json_schema` in unit tests
675
+ 7. **VCR for integration tests** — Record real HTTP interactions, never mock LLM responses by hand
676
+ 8. **Trace with spans** — Wrap tool calls in `DSPy::Context.with_span` for observability
677
+ 9. **Graceful degradation** — Always rescue LLM errors and return fallback data
678
+
679
+ ### Signature Best Practices
680
+
681
+ **Keep description concise** — The signature `description` should state the goal, not the field details:
682
+
683
+ ```ruby
684
+ # Good — concise goal
685
+ class ParseOutline < DSPy::Signature
686
+ description 'Extract block-level structure from HTML as a flat list of skeleton sections.'
687
+
688
+ input do
689
+ const :html, String, description: 'Raw HTML to parse'
690
+ end
691
+
692
+ output do
693
+ const :sections, T::Array[Section], description: 'Block elements: headings, paragraphs, code blocks, lists'
694
+ end
695
+ end
696
+ ```
697
+
698
+ **Use defaults over nilable arrays** — For OpenAI structured outputs compatibility:
699
+
700
+ ```ruby
701
+ # Good — works with OpenAI structured outputs
702
+ class ASTNode < T::Struct
703
+ const :children, T::Array[ASTNode], default: []
704
+ end
705
+ ```
706
+
707
+ ### Recursive Types with `$defs`
708
+
709
+ DSPy.rb supports recursive types in structured outputs using JSON Schema `$defs`:
710
+
711
+ ```ruby
712
+ class TreeNode < T::Struct
713
+ const :value, String
714
+ const :children, T::Array[TreeNode], default: [] # Self-reference
715
+ end
716
+ ```
717
+
718
+ The schema generator automatically creates `#/$defs/TreeNode` references for recursive types, compatible with OpenAI and Gemini structured outputs.
719
+
720
+ ### Field Descriptions for T::Struct
721
+
722
+ DSPy.rb extends T::Struct to support field-level `description:` kwargs that flow to JSON Schema:
723
+
724
+ ```ruby
725
+ class ASTNode < T::Struct
726
+ const :node_type, NodeType, description: 'The type of node (heading, paragraph, etc.)'
727
+ const :text, String, default: "", description: 'Text content of the node'
728
+ const :level, Integer, default: 0 # No description — field is self-explanatory
729
+ const :children, T::Array[ASTNode], default: []
730
+ end
731
+ ```
732
+
733
+ **When to use field descriptions**: complex field semantics, enum-like strings, constrained values, nested structs with ambiguous names. **When to skip**: self-explanatory fields like `name`, `id`, `url`, or boolean flags.
734
+
735
+ ## Version
736
+
737
+ Current: 0.34.3