rote-cli 0.16.0__tar.gz → 0.17.0__tar.gz

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 (241) hide show
  1. {rote_cli-0.16.0 → rote_cli-0.17.0}/PKG-INFO +88 -40
  2. {rote_cli-0.16.0 → rote_cli-0.17.0}/README.md +80 -33
  3. rote_cli-0.17.0/examples/docs-digest/README.md +98 -0
  4. rote_cli-0.17.0/examples/docs-digest/compiled/backend.json +4 -0
  5. rote_cli-0.17.0/examples/docs-digest/compiled/compile-metrics.json +17 -0
  6. rote_cli-0.17.0/examples/docs-digest/compiled/compile-report.md +60 -0
  7. rote_cli-0.17.0/examples/docs-digest/compiled/declared-tools.json +134 -0
  8. rote_cli-0.17.0/examples/docs-digest/compiled/eval.yaml +40 -0
  9. rote_cli-0.17.0/examples/docs-digest/compiled/extracted/pick_reading_list.py +21 -0
  10. rote_cli-0.17.0/examples/docs-digest/compiled/extracted/read_repo_outline.py +19 -0
  11. rote_cli-0.17.0/examples/docs-digest/compiled/extracted/search_microsoft_learn.py +56 -0
  12. rote_cli-0.17.0/examples/docs-digest/compiled/extracted/write_digest.py +21 -0
  13. rote_cli-0.17.0/examples/docs-digest/compiled/pipeline.yaml +204 -0
  14. rote_cli-0.17.0/examples/docs-digest/compiled/provenance.json +33 -0
  15. rote_cli-0.17.0/examples/docs-digest/compiled/system1/brief.md +18 -0
  16. rote_cli-0.17.0/examples/docs-digest/compiled/system1/decisions.json +189 -0
  17. rote_cli-0.17.0/examples/docs-digest/compiled/system1/enforcement.json +4 -0
  18. rote_cli-0.17.0/examples/docs-digest/compiled/system1/interface.json +95 -0
  19. rote_cli-0.17.0/examples/docs-digest/compiled/system1/skeleton.yaml +98 -0
  20. rote_cli-0.17.0/examples/docs-digest/compiled/system1/text.yaml +122 -0
  21. rote_cli-0.17.0/examples/docs-digest/compiled/tests/test_pick_reading_list.py +43 -0
  22. rote_cli-0.17.0/examples/docs-digest/compiled/tests/test_write_digest.py +35 -0
  23. rote_cli-0.17.0/examples/docs-digest/reference.json +212 -0
  24. rote_cli-0.17.0/examples/docs-digest/skill/SKILL.md +43 -0
  25. rote_cli-0.17.0/examples/docs-digest/skill/input.json +1 -0
  26. rote_cli-0.17.0/examples/docs-digest/skill/mcp-tools.json +107 -0
  27. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/README.md +18 -9
  28. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/expected/extracted/audit.py +4 -2
  29. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/expected/extracted/report.py +22 -11
  30. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/expected/pipeline-draft.yaml +1 -0
  31. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/expected/pipeline.yaml +10 -2
  32. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/fidelity/reference.json +217 -107
  33. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/runs/2026-10-18-first-agent-run/pipeline.yaml +4 -0
  34. {rote_cli-0.16.0 → rote_cli-0.17.0}/pyproject.toml +40 -10
  35. {rote_cli-0.16.0 → rote_cli-0.17.0}/skills/rote-compile/GENERATE.md +20 -2
  36. {rote_cli-0.16.0 → rote_cli-0.17.0}/skills/rote-compile/SYSTEM1.md +5 -0
  37. {rote_cli-0.16.0 → rote_cli-0.17.0}/skills/rote-compile/references/implementation.md +4 -2
  38. {rote_cli-0.16.0 → rote_cli-0.17.0}/skills/rote-compile/references/ir-schema.md +17 -1
  39. {rote_cli-0.16.0 → rote_cli-0.17.0}/skills/rote-compile/references/llm-judge-extraction.md +31 -0
  40. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/__init__.py +1 -1
  41. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/__main__.py +1 -1
  42. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/adapters/__init__.py +18 -0
  43. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/adapters/_common.py +85 -17
  44. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/adapters/_py_common.py +31 -7
  45. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/adapters/_ts_common.py +521 -72
  46. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/adapters/cloudflare.py +6 -0
  47. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/adapters/dbos.py +5 -3
  48. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/adapters/dbos_ts.py +6 -0
  49. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/adapters/inngest.py +6 -0
  50. rote_cli-0.17.0/src/rote/adapters/skill.py +779 -0
  51. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/adapters/temporal.py +10 -8
  52. rote_cli-0.17.0/src/rote/app_registry.py +136 -0
  53. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/bench/fidelity.py +177 -21
  54. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/bench/fidelity_score.py +79 -1
  55. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/bench/report.py +2 -0
  56. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/bench/runner.py +12 -2
  57. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/bench/score.py +29 -0
  58. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/cli.py +1745 -195
  59. rote_cli-0.17.0/src/rote/clients/__init__.py +89 -0
  60. rote_cli-0.17.0/src/rote/clients/amp.py +244 -0
  61. rote_cli-0.17.0/src/rote/clients/base.py +326 -0
  62. rote_cli-0.17.0/src/rote/clients/claude_code.py +574 -0
  63. rote_cli-0.17.0/src/rote/clients/claude_desktop.py +93 -0
  64. rote_cli-0.17.0/src/rote/clients/codex.py +236 -0
  65. rote_cli-0.17.0/src/rote/clients/collisions.py +81 -0
  66. rote_cli-0.17.0/src/rote/clients/common.py +399 -0
  67. rote_cli-0.17.0/src/rote/clients/copilot.py +200 -0
  68. rote_cli-0.17.0/src/rote/clients/cursor.py +139 -0
  69. rote_cli-0.17.0/src/rote/clients/gemini.py +337 -0
  70. rote_cli-0.17.0/src/rote/clients/goose.py +188 -0
  71. rote_cli-0.17.0/src/rote/clients/normalize.py +309 -0
  72. rote_cli-0.17.0/src/rote/clients/opencode.py +209 -0
  73. rote_cli-0.17.0/src/rote/clients/vscode.py +202 -0
  74. rote_cli-0.17.0/src/rote/clients/windsurf.py +159 -0
  75. rote_cli-0.17.0/src/rote/clients/zed.py +148 -0
  76. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/cloud_compile.py +2 -1
  77. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/__init__.py +130 -28
  78. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/_prefix_runner.py +1 -1
  79. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/drivers/anthropic_api.py +11 -10
  80. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/drivers/openai_api.py +1 -1
  81. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/prefix.py +23 -108
  82. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/provenance.py +108 -3
  83. rote_cli-0.17.0/src/rote/compiler/replay.py +71 -0
  84. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/system1/__init__.py +2 -0
  85. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/system1/decide.py +11 -1
  86. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/system1/enforce.py +4 -1
  87. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/system1/generate.py +134 -6
  88. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/system1/parse.py +42 -18
  89. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/system1/skeleton.py +13 -2
  90. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/system1/structure.py +386 -16
  91. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/tool_grounding.py +187 -9
  92. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/verify.py +150 -31
  93. rote_cli-0.17.0/src/rote/compiler/worth.py +68 -0
  94. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/config.py +222 -17
  95. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/contracts.py +30 -14
  96. rote_cli-0.17.0/src/rote/demo.py +338 -0
  97. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/deploy.py +8 -0
  98. rote_cli-0.17.0/src/rote/entry.py +44 -0
  99. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/eval/baseline.py +145 -53
  100. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/eval/empirical.py +203 -49
  101. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/eval/estimate.py +7 -2
  102. rote_cli-0.17.0/src/rote/eval/gate_server.py +143 -0
  103. rote_cli-0.17.0/src/rote/eval/skill_ab.py +1497 -0
  104. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/examples.py +38 -4
  105. rote_cli-0.17.0/src/rote/extras.py +528 -0
  106. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/inference/__init__.py +2 -0
  107. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/inference/_runtime_helper.py +621 -72
  108. rote_cli-0.17.0/src/rote/init_wizard.py +328 -0
  109. rote_cli-0.17.0/src/rote/interact/__init__.py +7 -0
  110. rote_cli-0.17.0/src/rote/interact/agents.py +124 -0
  111. rote_cli-0.17.0/src/rote/interact/mode.py +145 -0
  112. rote_cli-0.17.0/src/rote/interact/output.py +81 -0
  113. rote_cli-0.17.0/src/rote/interact/plan.py +480 -0
  114. rote_cli-0.17.0/src/rote/interact/prompter.py +421 -0
  115. rote_cli-0.17.0/src/rote/interact/report.py +150 -0
  116. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/ir.py +433 -5
  117. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/isolation.py +7 -0
  118. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/mcp/__init__.py +1 -1
  119. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/mcp/_runtime_helper.py +102 -8
  120. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/mcp/auth.py +105 -13
  121. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/mcp/live_tools.py +11 -8
  122. rote_cli-0.17.0/src/rote/mcp/pending_login.py +624 -0
  123. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/mcp/registry.py +30 -5
  124. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/mcp/release.py +4 -6
  125. rote_cli-0.17.0/src/rote/plan/__init__.py +505 -0
  126. rote_cli-0.17.0/src/rote/proof.py +363 -0
  127. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/runners/__init__.py +61 -30
  128. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/runners/dbos_ts.py +6 -5
  129. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/serve/__init__.py +1 -1
  130. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/serve/backends.py +3 -7
  131. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/serve/registry.py +32 -3
  132. rote_cli-0.17.0/src/rote/setup/__init__.py +126 -0
  133. rote_cli-0.17.0/src/rote/setup/first_run.py +1294 -0
  134. rote_cli-0.17.0/src/rote/setup/install_extra.py +178 -0
  135. rote_cli-0.17.0/src/rote/setup/mcp_import.py +983 -0
  136. rote_cli-0.17.0/src/rote/setup/mcp_login.py +83 -0
  137. rote_cli-0.17.0/src/rote/setup/try_skill.py +1010 -0
  138. rote_cli-0.17.0/src/rote/skill_files.py +121 -0
  139. rote_cli-0.17.0/src/rote/skill_target/__init__.py +100 -0
  140. rote_cli-0.17.0/src/rote/skill_target/_driver.py +2439 -0
  141. rote_cli-0.17.0/src/rote/skill_target/allow_rule.py +140 -0
  142. rote_cli-0.17.0/src/rote/skill_target/commands.py +636 -0
  143. rote_cli-0.17.0/src/rote/skill_target/launch.py +336 -0
  144. rote_cli-0.17.0/src/rote/skill_target/next_steps.py +72 -0
  145. rote_cli-0.17.0/src/rote/skill_target/trust.py +703 -0
  146. rote_cli-0.17.0/src/rote/skills/__init__.py +26 -0
  147. rote_cli-0.17.0/src/rote/skills/discovery.py +475 -0
  148. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/tool_schema.py +3 -0
  149. rote_cli-0.16.0/src/rote/app_registry.py +0 -86
  150. rote_cli-0.16.0/src/rote/extras.py +0 -138
  151. rote_cli-0.16.0/src/rote/init_wizard.py +0 -211
  152. {rote_cli-0.16.0 → rote_cli-0.17.0}/.gitignore +0 -0
  153. {rote_cli-0.16.0 → rote_cli-0.17.0}/LICENSE +0 -0
  154. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/eval-input.json +0 -0
  155. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/expected/eval.yaml +0 -0
  156. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/expected/extracted/checks.py +0 -0
  157. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/expected/extracted/fx.py +0 -0
  158. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/fidelity/cases.yaml +0 -0
  159. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/input.json +0 -0
  160. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/runs/2026-10-18-first-agent-run/compile-metrics.json +0 -0
  161. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/runs/2026-10-18-first-agent-run/compile-report.md +0 -0
  162. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/runs/2026-10-18-first-agent-run/eval.yaml +0 -0
  163. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/runs/2026-10-18-first-agent-run/extracted/checks.py +0 -0
  164. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/runs/2026-10-18-first-agent-run/extracted/fx.py +0 -0
  165. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/runs/2026-10-18-first-agent-run/extracted/policy.py +0 -0
  166. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/runs/2026-10-18-first-agent-run/extracted/report.py +0 -0
  167. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/runs/2026-10-18-first-agent-run/extracted/save.py +0 -0
  168. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/runs/2026-10-18-first-agent-run/provenance.json +0 -0
  169. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/scorecard.md +0 -0
  170. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/skill/SKILL.md +0 -0
  171. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/skill/references/expense-policy.md +0 -0
  172. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/skill/references/fx-rates.md +0 -0
  173. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/skill/references/report-format.md +0 -0
  174. {rote_cli-0.16.0 → rote_cli-0.17.0}/examples/expense-audit/skill/sample-input.json +0 -0
  175. {rote_cli-0.16.0 → rote_cli-0.17.0}/skills/rote-compile/SKILL.md +0 -0
  176. {rote_cli-0.16.0 → rote_cli-0.17.0}/skills/rote-compile/references/crystallization-heuristics.md +0 -0
  177. {rote_cli-0.16.0 → rote_cli-0.17.0}/skills/rote-compile/references/eval-estimates.md +0 -0
  178. {rote_cli-0.16.0 → rote_cli-0.17.0}/skills/rote-compile/references/node-kinds.md +0 -0
  179. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/_dbos.py +0 -0
  180. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/adapters/python.py +0 -0
  181. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/bench/__init__.py +0 -0
  182. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/bench/collect.py +0 -0
  183. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/bench/fixture_mcp.py +0 -0
  184. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/bench/http_fixtures.py +0 -0
  185. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/cloud_auth.py +0 -0
  186. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/api_docs.py +0 -0
  187. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/backend.py +0 -0
  188. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/drivers/__init__.py +0 -0
  189. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/drivers/_fs_tools.py +0 -0
  190. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/drivers/_heartbeat.py +0 -0
  191. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/drivers/claude.py +0 -0
  192. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/drivers/codex.py +0 -0
  193. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/events.py +0 -0
  194. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/grounding.py +0 -0
  195. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/report.py +0 -0
  196. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/sandbox.py +0 -0
  197. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/system1/checker.py +0 -0
  198. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/system1/decision_model.py +0 -0
  199. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/system1/evidence.py +0 -0
  200. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/system1/lane_call.py +0 -0
  201. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/system1/tiebreak.py +0 -0
  202. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/compiler/update.py +0 -0
  203. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/deploy_rote_cloud.py +0 -0
  204. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/eval/__init__.py +0 -0
  205. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/eval/infra_pricing.py +0 -0
  206. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/eval/pricing.py +0 -0
  207. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/eval/priors.py +0 -0
  208. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/eval/scorecard.py +0 -0
  209. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/eval/sidecar.py +0 -0
  210. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/eval/tokens.py +0 -0
  211. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/mcp/client_metadata.json +0 -0
  212. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/mcp/learned.py +0 -0
  213. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/mcp/parked.py +0 -0
  214. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/mcp/tokens.py +0 -0
  215. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/probe.py +0 -0
  216. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/py.typed +0 -0
  217. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/runners/_node.py +0 -0
  218. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/runners/cloudflare.py +0 -0
  219. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/runners/inngest.py +0 -0
  220. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/runners/temporal.py +0 -0
  221. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/serve/server.py +0 -0
  222. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/skill_source.py +0 -0
  223. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/vendor_specs/__init__.py +0 -0
  224. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/vendor_specs/check.py +0 -0
  225. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/vendor_specs/deps.py +0 -0
  226. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/vendor_specs/docs.py +0 -0
  227. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/vendor_specs/extract.py +0 -0
  228. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/vendor_specs/fake.py +0 -0
  229. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/vendor_specs/fixture_store.py +0 -0
  230. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/vendor_specs/fixtures.py +0 -0
  231. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/vendor_specs/google.py +0 -0
  232. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/vendor_specs/graphql.py +0 -0
  233. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/vendor_specs/intercept/sitecustomize.py +0 -0
  234. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/vendor_specs/live.py +0 -0
  235. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/vendor_specs/model.py +0 -0
  236. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/vendor_specs/openapi.py +0 -0
  237. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/vendor_specs/psl.py +0 -0
  238. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/vendor_specs/public_suffix_list.dat +0 -0
  239. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/vendor_specs/schema.py +0 -0
  240. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/vendor_specs/store.py +0 -0
  241. {rote_cli-0.16.0 → rote_cli-0.17.0}/src/rote/xdg.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: rote-cli
3
- Version: 0.16.0
3
+ Version: 0.17.0
4
4
  Summary: Compile AI agent skills into cheap, fast, deterministic pipelines that run without an LLM in the loop
5
5
  Project-URL: Homepage, https://roteskills.com
6
6
  Project-URL: Repository, https://github.com/trevhud/rote
@@ -24,10 +24,15 @@ Classifier: Topic :: Software Development :: Code Generators
24
24
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
25
25
  Classifier: Typing :: Typed
26
26
  Requires-Python: >=3.11
27
+ Requires-Dist: fastmcp-slim[client]<5,>=4.1.3
27
28
  Requires-Dist: graphql-core<4,>=3.3
29
+ Requires-Dist: httpx>=0.28
30
+ Requires-Dist: json5<1,>=0.17.3
28
31
  Requires-Dist: pydantic>=2.7
29
32
  Requires-Dist: pytest<10,>=9.0
30
33
  Requires-Dist: pyyaml>=6.0
34
+ Requires-Dist: questionary<3,>=2.1.1
35
+ Requires-Dist: rich<16,>=15.0.0
31
36
  Provides-Extra: api
32
37
  Requires-Dist: anthropic>=1.15; extra == 'api'
33
38
  Provides-Extra: dbos
@@ -35,12 +40,11 @@ Requires-Dist: dbos<4,>=3.3; extra == 'dbos'
35
40
  Provides-Extra: dev
36
41
  Requires-Dist: anthropic>=1.15; extra == 'dev'
37
42
  Requires-Dist: dbos<4,>=3.3; extra == 'dev'
38
- Requires-Dist: fastmcp<5,>=4.1.1; extra == 'dev'
43
+ Requires-Dist: fastmcp<5,>=4.1.3; extra == 'dev'
39
44
  Requires-Dist: google-api-python-client>=2.201.0; extra == 'dev'
40
45
  Requires-Dist: google-auth-httplib2>=0.4.4; extra == 'dev'
41
46
  Requires-Dist: google-auth>=2.62.0; extra == 'dev'
42
47
  Requires-Dist: httplib2>=0.32.0; extra == 'dev'
43
- Requires-Dist: httpx>=0.28; extra == 'dev'
44
48
  Requires-Dist: mypy>=1.10; extra == 'dev'
45
49
  Requires-Dist: openai>=2.45; extra == 'dev'
46
50
  Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
@@ -50,13 +54,10 @@ Requires-Dist: temporalio>=1.7; extra == 'dev'
50
54
  Requires-Dist: trustme>=1.2.1; extra == 'dev'
51
55
  Requires-Dist: types-pyyaml; extra == 'dev'
52
56
  Provides-Extra: mcp
53
- Requires-Dist: fastmcp<5,>=4.1.1; extra == 'mcp'
54
- Requires-Dist: httpx>=0.28; extra == 'mcp'
55
57
  Provides-Extra: openai-api
56
58
  Requires-Dist: openai>=2.45; extra == 'openai-api'
57
59
  Provides-Extra: serve
58
- Requires-Dist: fastmcp<5,>=4.1.1; extra == 'serve'
59
- Requires-Dist: httpx>=0.28; extra == 'serve'
60
+ Requires-Dist: fastmcp<5,>=4.1.3; extra == 'serve'
60
61
  Provides-Extra: temporal
61
62
  Requires-Dist: temporalio>=1.7; extra == 'temporal'
62
63
  Description-Content-Type: text/markdown
@@ -91,7 +92,8 @@ inside the package, so you can emit it and run it before you compile
91
92
  anything of your own:
92
93
 
93
94
  ```sh
94
- uv tool install 'rote-cli[dbos]' # or: python3 -m venv .venv && . .venv/bin/activate && pip install 'rote-cli[dbos]'
95
+ uv tool install rote-cli # or: python3 -m venv .venv && . .venv/bin/activate && pip install rote-cli
96
+ # (the first dbos run offers to add the dbos extra; you confirm it)
95
97
  rote example expense-audit # copies the skill, IR, code and sample input to ./expense-audit
96
98
  # (zero-install: uvx --from rote-cli rote example expense-audit)
97
99
 
@@ -114,12 +116,12 @@ rote run (python): succeeded
114
116
  "status": "draft",
115
117
  "reviewer": null,
116
118
  "reimbursable_usd": 2395.59,
117
- "pending_usd": 844.39,
118
- "returned_usd": 64.17,
119
+ "pending_usd": 18.75,
120
+ "returned_usd": 889.81,
119
121
  "batch_total_usd": 3304.15,
120
122
  "auto_approved": ["Dev Patel", "Emi Tanaka"],
121
- "review_items": 4,
122
- "blocked_items": 2
123
+ "review_items": 1,
124
+ "blocked_items": 5
123
125
  }
124
126
  }
125
127
  ```
@@ -134,7 +136,7 @@ runtime:
134
136
  rote emit expense-audit/expected/pipeline.yaml --runtime dbos --out expense-audit/app-dbos
135
137
  rote run expense-audit/app-dbos --input expense-audit/input.json \
136
138
  --signal controller_review='{"reviewer": "Priya Shah", "approved_ids": ["EXP-2403", "EXP-2413", "EXP-2420"], "rejected_ids": ["EXP-2410"]}'
137
- # ... "status": "final", "reimbursable_usd": 2990.98, "returned_usd": 313.17
139
+ # ... "status": "final", "reimbursable_usd": 2414.34, "returned_usd": 889.81
138
140
  ```
139
141
 
140
142
  What compiling it bought, measured: we ran the same batch twice each way
@@ -172,18 +174,49 @@ pip install rote-cli # or zero-install: uvx --from rote-cli rote ...
172
174
 
173
175
  # `rote compile` runs an LLM agent, so it needs a driver: Claude Code
174
176
  # (`claude`) or Codex (`codex`) installed and authed, or ANTHROPIC_API_KEY
175
- # for the in-process `api` driver. The BDR run below takes ~13 min and
176
- # ~$0.70 with Sonnet. (`rote emit` needs no LLM; see below.)
177
+ # for the in-process `api` driver. (`rote emit` needs no LLM; see below.)
178
+
179
+ # Default target is a compiled skill: the same skill name and trigger,
180
+ # with its fixed steps in code, run by the agent you already use:
181
+ rote compile ./examples/docs-digest/skill --out ./compiled/
182
+ # rote compile: ✓ docs-digest v...
183
+ # next: rote skill install .../compiled/runtime/skill/docs-digest
184
+ # then swap it in for the original docs-digest skill (Claude Code:
185
+ # ln -s .../runtime/skill/docs-digest ~/.claude/skills/docs-digest)
186
+ # or see it give the original's answer first: rote try ./examples/docs-digest/skill
187
+ ```
177
188
 
178
- # Default target is DBOS: durable execution as a plain Python library,
179
- # no orchestrator to run, SQLite for dev / Postgres for prod:
180
- rote compile ./examples/bdr-outreach/skill --out ./compiled/
189
+ rote checks `~/.claude/skills/<name>` before it prints the link. When your
190
+ original skill is already there, `ln -s` would nest the link inside it
191
+ (and exit 0), so rote prints the swap with the original moved aside
192
+ instead, plus the undo. Nothing is deleted, and rote runs none of it:
181
193
 
182
- # Or pick another runtime (see the table below):
183
- rote compile ./examples/bdr-outreach/skill --runtime temporal --out ./compiled/
194
+ ```
195
+ then, for Claude Code: your original docs-digest skill is at ~/.claude/skills/docs-digest.
196
+ To use the compiled one instead, move the original out of the skills folder (nothing is
197
+ deleted): mv ~/.claude/skills/docs-digest ~/docs-digest.original && ln -s .../runtime/skill/docs-digest ~/.claude/skills/docs-digest
198
+ undo: rm ~/.claude/skills/docs-digest && mv ~/docs-digest.original ~/.claude/skills/docs-digest
199
+ ```
200
+
201
+ ```sh
202
+ # Or emit a background workflow instead (see the table below):
203
+ rote compile ./examples/bdr-outreach/skill --runtime dbos --out ./compiled/
184
204
  rote compile ./examples/bdr-outreach/skill --runtime cloudflare --out ./compiled/
185
205
  ```
186
206
 
207
+ Measured on claude-sonnet-4-6, original skill against its compiled skill,
208
+ with every compared field matching within the original's own run-to-run
209
+ noise:
210
+
211
+ | Skill | Original | Compiled skill |
212
+ | --- | --- | --- |
213
+ | expense-audit | 154 s, $0.34 | 43 s, $0.13 |
214
+ | ops-report | 55 s, $0.13 | 42 s, $0.12 |
215
+ | docs-digest | 17.9 s, $0.093 | 16.3 s, $0.049 |
216
+
217
+ `rote try <skill>` runs that comparison on a skill of yours: it compiles,
218
+ installs, and runs both sides on the same input, after showing the cost.
219
+
187
220
  The name comes from *rote learning*: doing something so many times, so
188
221
  reliably, that it becomes mechanical. That's what compilation does to a
189
222
  skill.
@@ -326,6 +359,12 @@ touching Python tooling:
326
359
  /plugin install rote@rote
327
360
  ```
328
361
 
362
+ New here? Run `/rote:setup`, or `uvx --from rote-cli rote setup` in a
363
+ terminal. It imports the MCP servers you already use, compiles one of your
364
+ skills, and shows that the compiled skill gives the same answer, with time
365
+ and cost on each side. It asks before every step and shows the cost before
366
+ anything is spent.
367
+
329
368
  Then say "compile this skill" (or run `/rote:compile`). It confirms the
330
369
  source directory, asks which runtime you want, runs the CLI via
331
370
  [uv](https://docs.astral.sh/uv/) in the background, and reports the
@@ -338,16 +377,17 @@ pipelines up as MCP tools so Claude can trigger the deployed workflows
338
377
  Prefer a terminal? The same thing is one `uvx` command:
339
378
 
340
379
  ```sh
341
- uvx --from rote-cli rote compile ./my-skill --runtime dbos --out ./compiled
380
+ uvx --from rote-cli rote compile ./my-skill --out ./compiled
342
381
  ```
343
382
 
344
383
  **Hosted platform:** [roteskills.com](https://roteskills.com) is the
345
384
  project site (concepts, benchmarks methodology, worked examples).
346
385
  [app.roteskills.com](https://app.roteskills.com) is Rote Cloud, a
347
386
  managed path for teams that would rather not operate a runtime: run
348
- `rote login` and `rote compile` then runs server-side, streams progress
349
- back, auto-deploys, and downloads the artifacts locally. Everything in
350
- this README still works logged out.
387
+ `rote login`, then `rote compile --cloud` (or set `deploy: rote-cloud`
388
+ with `rote init`) runs server-side, streams progress back, auto-deploys,
389
+ and downloads the artifacts locally. Everything in this README still
390
+ works logged out.
351
391
 
352
392
  > **Naming note:** the `rote` package on PyPI is an unrelated
353
393
  > memoization library that also installs `import rote`, so the two can't
@@ -440,26 +480,29 @@ through your API credentials.
440
480
  (over SSH, `--device` prints the code + URL instead), you click
441
481
  Approve, and the CLI stores a tenant API key at
442
482
  `~/.local/share/rote/cloud.json` (mode 0600). Once logged in,
443
- `rote compile` runs **on rote cloud by default**: the skill bundle
483
+ `rote compile --cloud` runs **on rote cloud**, and so does a compile
484
+ whose runtime is `cloudflare` or whose `deploy` is `rote-cloud`
485
+ (flag, env or config). A flagless compile stays local and emits a
486
+ compiled skill, logged in or not. On rote cloud the skill bundle
444
487
  syncs up (sha-diffed, so unchanged files don't re-upload), the
445
488
  platform runs the compilation server-side, live progress streams back
446
489
  through the same renderer as a local run, the result auto-deploys,
447
490
  and the artifacts download into your `--out` directory in the exact
448
- local layout. `--local` keeps the compilation on your machine (then
449
- the cloudflare-emit + auto-deploy flow applies), `--no-deploy` or a
450
- config opt-out (`runtime:` pinned to a local target, or
451
- `deploy: none`) keeps everything local; `--cloud` forces the server
452
- even where config says otherwise. Logged out, everything works
453
- locally exactly as before. `rote whoami` shows the account (verified
491
+ local layout. `--local` keeps the compilation on your machine (a
492
+ cloudflare compile then emits locally and auto-deploys), `--no-deploy`
493
+ or `deploy: none` keeps everything local; `--cloud` forces the server
494
+ even where config says otherwise. `rote whoami` shows the account (verified
454
495
  live); `rote logout` revokes the key server-side and clears the store.
455
- - **`rote init`**: one-time interactive onboarding: pick where
456
- compiled pipelines run (rote cloud, with login offered inline, or
457
- a local runtime, with a one-line pitch for each), which compiler
458
- driver does the work (availability probed live), and optionally a
459
- model. Answers are saved to `~/.config/rote/config.yaml`
496
+ - **`rote init`**: one-time onboarding: pick where compiled pipelines
497
+ run (locally, with `skill` first and recommended, or rote cloud, with
498
+ login offered), which
499
+ compiler driver and model do the work, and who decides a local
500
+ compile's structure. It shows what it will write and asks before
501
+ writing. Answers are saved to `~/.config/rote/config.yaml`
460
502
  (`--project` writes a `./rote.yaml` that overrides it per-repo) and
461
- every later command reads them. It's the only interactive command
462
- besides login; CI never hits a prompt.
503
+ every later command reads them. Every question has a flag, so CI and
504
+ agents run it with flags and `--yes`; it never prompts without a
505
+ person at a terminal.
463
506
  - **`rote config`**: print every configurable default with its
464
507
  effective value *and the layer that set it*. Resolution everywhere is
465
508
  `flag > ROTE_* env (ROTE_RUNTIME, ROTE_DEPLOY, ROTE_AGENT,
@@ -471,7 +514,11 @@ through your API credentials.
471
514
  much of the run is still LLM-decided). `rote compile` writes this to
472
515
  `compiled/scorecard.md` automatically. Add `--run` to *measure*
473
516
  instead of estimate: it executes both sides for real and appends
474
- measured cost, turns, and output agreement across trials.
517
+ measured cost, turns, and output agreement across trials. With
518
+ `--run --runtime skill` the after side is the compiled skill, run by
519
+ an agent through `rote skill run`, so both sides are agents and the
520
+ table compares context, tokens, time, cost and field fidelity
521
+ (`--budget` is required).
475
522
  - **Per-node inference**: emitted judges read `ROTE_MODEL_<ID>` and
476
523
  `ROTE_BASE_URL_<ID>` at runtime, so you can swap the model or point at
477
524
  any OpenAI-compatible endpoint (Ollama, vLLM, a gateway) without
@@ -515,7 +562,8 @@ see [`docs/mcp-client.md`](docs/mcp-client.md).
515
562
 
516
563
  | Runtime | `--runtime` | Language | Shape | Notes |
517
564
  | --- | --- | --- | --- | --- |
518
- | **DBOS** (default) | `dbos` | Python | `main.py` with `@DBOS.workflow` + `@DBOS.step` per node | No orchestrator to deploy; SQLite (dev) / Postgres (prod) |
565
+ | **Compiled skill** (default) | `skill` | Python driver + SKILL.md | a skill dir: the original's name and description, `scripts/` runs the fixed steps, the agent answers only judges and gates | Install with `rote skill install`; runs in Claude Code, Codex and other skill clients through `rote skill run` |
566
+ | DBOS | `dbos` | Python | `main.py` with `@DBOS.workflow` + `@DBOS.step` per node | No orchestrator to deploy; SQLite (dev) / Postgres (prod) |
519
567
  | Temporal | `temporal` | Python | `workflow.py` + `activities.py` | Signal handlers for HITL gates |
520
568
  | Plain Python | `python` | Python | single `main.py` script | Max legibility, stdlib only; refuses HITL-gate pipelines |
521
569
  | Cloudflare Workflows | `cloudflare` | TypeScript | `WorkflowEntrypoint` + `wrangler.jsonc` | `wrangler deploy`-ready |
@@ -28,7 +28,8 @@ inside the package, so you can emit it and run it before you compile
28
28
  anything of your own:
29
29
 
30
30
  ```sh
31
- uv tool install 'rote-cli[dbos]' # or: python3 -m venv .venv && . .venv/bin/activate && pip install 'rote-cli[dbos]'
31
+ uv tool install rote-cli # or: python3 -m venv .venv && . .venv/bin/activate && pip install rote-cli
32
+ # (the first dbos run offers to add the dbos extra; you confirm it)
32
33
  rote example expense-audit # copies the skill, IR, code and sample input to ./expense-audit
33
34
  # (zero-install: uvx --from rote-cli rote example expense-audit)
34
35
 
@@ -51,12 +52,12 @@ rote run (python): succeeded
51
52
  "status": "draft",
52
53
  "reviewer": null,
53
54
  "reimbursable_usd": 2395.59,
54
- "pending_usd": 844.39,
55
- "returned_usd": 64.17,
55
+ "pending_usd": 18.75,
56
+ "returned_usd": 889.81,
56
57
  "batch_total_usd": 3304.15,
57
58
  "auto_approved": ["Dev Patel", "Emi Tanaka"],
58
- "review_items": 4,
59
- "blocked_items": 2
59
+ "review_items": 1,
60
+ "blocked_items": 5
60
61
  }
61
62
  }
62
63
  ```
@@ -71,7 +72,7 @@ runtime:
71
72
  rote emit expense-audit/expected/pipeline.yaml --runtime dbos --out expense-audit/app-dbos
72
73
  rote run expense-audit/app-dbos --input expense-audit/input.json \
73
74
  --signal controller_review='{"reviewer": "Priya Shah", "approved_ids": ["EXP-2403", "EXP-2413", "EXP-2420"], "rejected_ids": ["EXP-2410"]}'
74
- # ... "status": "final", "reimbursable_usd": 2990.98, "returned_usd": 313.17
75
+ # ... "status": "final", "reimbursable_usd": 2414.34, "returned_usd": 889.81
75
76
  ```
76
77
 
77
78
  What compiling it bought, measured: we ran the same batch twice each way
@@ -109,18 +110,49 @@ pip install rote-cli # or zero-install: uvx --from rote-cli rote ...
109
110
 
110
111
  # `rote compile` runs an LLM agent, so it needs a driver: Claude Code
111
112
  # (`claude`) or Codex (`codex`) installed and authed, or ANTHROPIC_API_KEY
112
- # for the in-process `api` driver. The BDR run below takes ~13 min and
113
- # ~$0.70 with Sonnet. (`rote emit` needs no LLM; see below.)
113
+ # for the in-process `api` driver. (`rote emit` needs no LLM; see below.)
114
+
115
+ # Default target is a compiled skill: the same skill name and trigger,
116
+ # with its fixed steps in code, run by the agent you already use:
117
+ rote compile ./examples/docs-digest/skill --out ./compiled/
118
+ # rote compile: ✓ docs-digest v...
119
+ # next: rote skill install .../compiled/runtime/skill/docs-digest
120
+ # then swap it in for the original docs-digest skill (Claude Code:
121
+ # ln -s .../runtime/skill/docs-digest ~/.claude/skills/docs-digest)
122
+ # or see it give the original's answer first: rote try ./examples/docs-digest/skill
123
+ ```
114
124
 
115
- # Default target is DBOS: durable execution as a plain Python library,
116
- # no orchestrator to run, SQLite for dev / Postgres for prod:
117
- rote compile ./examples/bdr-outreach/skill --out ./compiled/
125
+ rote checks `~/.claude/skills/<name>` before it prints the link. When your
126
+ original skill is already there, `ln -s` would nest the link inside it
127
+ (and exit 0), so rote prints the swap with the original moved aside
128
+ instead, plus the undo. Nothing is deleted, and rote runs none of it:
118
129
 
119
- # Or pick another runtime (see the table below):
120
- rote compile ./examples/bdr-outreach/skill --runtime temporal --out ./compiled/
130
+ ```
131
+ then, for Claude Code: your original docs-digest skill is at ~/.claude/skills/docs-digest.
132
+ To use the compiled one instead, move the original out of the skills folder (nothing is
133
+ deleted): mv ~/.claude/skills/docs-digest ~/docs-digest.original && ln -s .../runtime/skill/docs-digest ~/.claude/skills/docs-digest
134
+ undo: rm ~/.claude/skills/docs-digest && mv ~/docs-digest.original ~/.claude/skills/docs-digest
135
+ ```
136
+
137
+ ```sh
138
+ # Or emit a background workflow instead (see the table below):
139
+ rote compile ./examples/bdr-outreach/skill --runtime dbos --out ./compiled/
121
140
  rote compile ./examples/bdr-outreach/skill --runtime cloudflare --out ./compiled/
122
141
  ```
123
142
 
143
+ Measured on claude-sonnet-4-6, original skill against its compiled skill,
144
+ with every compared field matching within the original's own run-to-run
145
+ noise:
146
+
147
+ | Skill | Original | Compiled skill |
148
+ | --- | --- | --- |
149
+ | expense-audit | 154 s, $0.34 | 43 s, $0.13 |
150
+ | ops-report | 55 s, $0.13 | 42 s, $0.12 |
151
+ | docs-digest | 17.9 s, $0.093 | 16.3 s, $0.049 |
152
+
153
+ `rote try <skill>` runs that comparison on a skill of yours: it compiles,
154
+ installs, and runs both sides on the same input, after showing the cost.
155
+
124
156
  The name comes from *rote learning*: doing something so many times, so
125
157
  reliably, that it becomes mechanical. That's what compilation does to a
126
158
  skill.
@@ -263,6 +295,12 @@ touching Python tooling:
263
295
  /plugin install rote@rote
264
296
  ```
265
297
 
298
+ New here? Run `/rote:setup`, or `uvx --from rote-cli rote setup` in a
299
+ terminal. It imports the MCP servers you already use, compiles one of your
300
+ skills, and shows that the compiled skill gives the same answer, with time
301
+ and cost on each side. It asks before every step and shows the cost before
302
+ anything is spent.
303
+
266
304
  Then say "compile this skill" (or run `/rote:compile`). It confirms the
267
305
  source directory, asks which runtime you want, runs the CLI via
268
306
  [uv](https://docs.astral.sh/uv/) in the background, and reports the
@@ -275,16 +313,17 @@ pipelines up as MCP tools so Claude can trigger the deployed workflows
275
313
  Prefer a terminal? The same thing is one `uvx` command:
276
314
 
277
315
  ```sh
278
- uvx --from rote-cli rote compile ./my-skill --runtime dbos --out ./compiled
316
+ uvx --from rote-cli rote compile ./my-skill --out ./compiled
279
317
  ```
280
318
 
281
319
  **Hosted platform:** [roteskills.com](https://roteskills.com) is the
282
320
  project site (concepts, benchmarks methodology, worked examples).
283
321
  [app.roteskills.com](https://app.roteskills.com) is Rote Cloud, a
284
322
  managed path for teams that would rather not operate a runtime: run
285
- `rote login` and `rote compile` then runs server-side, streams progress
286
- back, auto-deploys, and downloads the artifacts locally. Everything in
287
- this README still works logged out.
323
+ `rote login`, then `rote compile --cloud` (or set `deploy: rote-cloud`
324
+ with `rote init`) runs server-side, streams progress back, auto-deploys,
325
+ and downloads the artifacts locally. Everything in this README still
326
+ works logged out.
288
327
 
289
328
  > **Naming note:** the `rote` package on PyPI is an unrelated
290
329
  > memoization library that also installs `import rote`, so the two can't
@@ -377,26 +416,29 @@ through your API credentials.
377
416
  (over SSH, `--device` prints the code + URL instead), you click
378
417
  Approve, and the CLI stores a tenant API key at
379
418
  `~/.local/share/rote/cloud.json` (mode 0600). Once logged in,
380
- `rote compile` runs **on rote cloud by default**: the skill bundle
419
+ `rote compile --cloud` runs **on rote cloud**, and so does a compile
420
+ whose runtime is `cloudflare` or whose `deploy` is `rote-cloud`
421
+ (flag, env or config). A flagless compile stays local and emits a
422
+ compiled skill, logged in or not. On rote cloud the skill bundle
381
423
  syncs up (sha-diffed, so unchanged files don't re-upload), the
382
424
  platform runs the compilation server-side, live progress streams back
383
425
  through the same renderer as a local run, the result auto-deploys,
384
426
  and the artifacts download into your `--out` directory in the exact
385
- local layout. `--local` keeps the compilation on your machine (then
386
- the cloudflare-emit + auto-deploy flow applies), `--no-deploy` or a
387
- config opt-out (`runtime:` pinned to a local target, or
388
- `deploy: none`) keeps everything local; `--cloud` forces the server
389
- even where config says otherwise. Logged out, everything works
390
- locally exactly as before. `rote whoami` shows the account (verified
427
+ local layout. `--local` keeps the compilation on your machine (a
428
+ cloudflare compile then emits locally and auto-deploys), `--no-deploy`
429
+ or `deploy: none` keeps everything local; `--cloud` forces the server
430
+ even where config says otherwise. `rote whoami` shows the account (verified
391
431
  live); `rote logout` revokes the key server-side and clears the store.
392
- - **`rote init`**: one-time interactive onboarding: pick where
393
- compiled pipelines run (rote cloud, with login offered inline, or
394
- a local runtime, with a one-line pitch for each), which compiler
395
- driver does the work (availability probed live), and optionally a
396
- model. Answers are saved to `~/.config/rote/config.yaml`
432
+ - **`rote init`**: one-time onboarding: pick where compiled pipelines
433
+ run (locally, with `skill` first and recommended, or rote cloud, with
434
+ login offered), which
435
+ compiler driver and model do the work, and who decides a local
436
+ compile's structure. It shows what it will write and asks before
437
+ writing. Answers are saved to `~/.config/rote/config.yaml`
397
438
  (`--project` writes a `./rote.yaml` that overrides it per-repo) and
398
- every later command reads them. It's the only interactive command
399
- besides login; CI never hits a prompt.
439
+ every later command reads them. Every question has a flag, so CI and
440
+ agents run it with flags and `--yes`; it never prompts without a
441
+ person at a terminal.
400
442
  - **`rote config`**: print every configurable default with its
401
443
  effective value *and the layer that set it*. Resolution everywhere is
402
444
  `flag > ROTE_* env (ROTE_RUNTIME, ROTE_DEPLOY, ROTE_AGENT,
@@ -408,7 +450,11 @@ through your API credentials.
408
450
  much of the run is still LLM-decided). `rote compile` writes this to
409
451
  `compiled/scorecard.md` automatically. Add `--run` to *measure*
410
452
  instead of estimate: it executes both sides for real and appends
411
- measured cost, turns, and output agreement across trials.
453
+ measured cost, turns, and output agreement across trials. With
454
+ `--run --runtime skill` the after side is the compiled skill, run by
455
+ an agent through `rote skill run`, so both sides are agents and the
456
+ table compares context, tokens, time, cost and field fidelity
457
+ (`--budget` is required).
412
458
  - **Per-node inference**: emitted judges read `ROTE_MODEL_<ID>` and
413
459
  `ROTE_BASE_URL_<ID>` at runtime, so you can swap the model or point at
414
460
  any OpenAI-compatible endpoint (Ollama, vLLM, a gateway) without
@@ -452,7 +498,8 @@ see [`docs/mcp-client.md`](docs/mcp-client.md).
452
498
 
453
499
  | Runtime | `--runtime` | Language | Shape | Notes |
454
500
  | --- | --- | --- | --- | --- |
455
- | **DBOS** (default) | `dbos` | Python | `main.py` with `@DBOS.workflow` + `@DBOS.step` per node | No orchestrator to deploy; SQLite (dev) / Postgres (prod) |
501
+ | **Compiled skill** (default) | `skill` | Python driver + SKILL.md | a skill dir: the original's name and description, `scripts/` runs the fixed steps, the agent answers only judges and gates | Install with `rote skill install`; runs in Claude Code, Codex and other skill clients through `rote skill run` |
502
+ | DBOS | `dbos` | Python | `main.py` with `@DBOS.workflow` + `@DBOS.step` per node | No orchestrator to deploy; SQLite (dev) / Postgres (prod) |
456
503
  | Temporal | `temporal` | Python | `workflow.py` + `activities.py` | Signal handlers for HITL gates |
457
504
  | Plain Python | `python` | Python | single `main.py` script | Max legibility, stdlib only; refuses HITL-gate pipelines |
458
505
  | Cloudflare Workflows | `cloudflare` | TypeScript | `WorkflowEntrypoint` + `wrangler.jsonc` | `wrangler deploy`-ready |
@@ -0,0 +1,98 @@
1
+ # Example: Docs Digest
2
+
3
+ The demo that `rote try` and `rote setup` run. A small skill that builds
4
+ a reading list on a Microsoft technology from Microsoft Learn and adds
5
+ the DeepWiki outline of the matching open-source repo. Both MCP servers
6
+ are public and need no login, so the whole thing runs with two
7
+ `rote mcp add` lines and nothing else:
8
+
9
+ | Server | URL | Tool |
10
+ | --- | --- | --- |
11
+ | `mslearn` | https://learn.microsoft.com/api/mcp | `microsoft_docs_search` |
12
+ | `deepwiki` | https://mcp.deepwiki.com/mcp | `read_wiki_structure` |
13
+
14
+ Run as an agent, the skill costs a few cents of model time per run.
15
+ Compiled, it is two MCP calls and two small Python functions, with no
16
+ model call at all.
17
+
18
+ ## What it demonstrates
19
+
20
+ - **MCP-bound steps.** `search_microsoft_learn` and
21
+ `read_repo_outline` are bare tool calls through the emitted MCP
22
+ helper. They run in the same entry wave, concurrently.
23
+ - **Rules lifted out of prose.** "Keep the first 5 results" is the
24
+ node constant `result_count: 5`, which the code reads, so editing it in
25
+ `pipeline.yaml` changes the digest. The two section names are code in
26
+ `compiled/extracted/`.
27
+ - **Live data.** The servers answer from live indexes, so a run today
28
+ can differ from the recorded one. `reference.json` says which fields
29
+ are expected to drift and why.
30
+
31
+ ## Run it
32
+
33
+ From the repo root:
34
+
35
+ ```sh
36
+ rote mcp add mslearn https://learn.microsoft.com/api/mcp --auth none --read-only
37
+ rote mcp add deepwiki https://mcp.deepwiki.com/mcp --auth none --read-only
38
+
39
+ # The precompiled pipeline (dbos on SQLite: no Node, no Docker; the first run
40
+ # offers to install the dbos extra)
41
+ rote emit examples/docs-digest/compiled/pipeline.yaml --runtime dbos --out /tmp/docs-digest-dbos
42
+ rote run /tmp/docs-digest-dbos --input examples/docs-digest/skill/input.json
43
+
44
+ # The skill itself, as an agent, read-only (bills your Claude subscription)
45
+ rote run examples/docs-digest/skill --input examples/docs-digest/skill/input.json
46
+ ```
47
+
48
+ The python runtime cannot run this pipeline. It has no MCP backend, so
49
+ it would call the two tool steps' direct-API modules, and those are stubs
50
+ (rote does not write vendor calls from memory). `rote run` refuses it up
51
+ front. dbos is the runtime that speaks MCP and needs no Node and no
52
+ Docker.
53
+
54
+ ## The recorded reference
55
+
56
+ `reference.json` (format `rote-demo-reference/1`, documented in
57
+ `rote.demo`) holds one real run of each side on `skill/input.json`,
58
+ recorded on 2026-10-22:
59
+
60
+ | | Skill, as an agent | Compile | Pipeline |
61
+ | --- | --- | --- | --- |
62
+ | Wall time | 14.9 s | 28 s | 6.6 s |
63
+ | Turns or calls | 4 turns | 6 generations + 1 structure call | 0 model calls |
64
+ | Cost | $0.088 | $0.076 | $0 |
65
+ | Model | claude-sonnet-4-6 | claude-sonnet-5-5, claude-haiku-5-5 | none |
66
+
67
+ The skill's digest and the pipeline's digest were the same text, except
68
+ that the pipeline ends it with a newline. Five runs over 44 minutes (two
69
+ agent runs, three pipeline runs across two compiles) got identical tool
70
+ results. The `drift` section of the reference lists what is still
71
+ expected to change over days: the reading list first, the repo outline
72
+ slowly. The `fields` it compares on are the digest's sections and the
73
+ reading list's length (equal on every run) and the two sections' text
74
+ (expected to drift).
75
+
76
+ `reference.json` also keeps the pipeline run's two MCP calls
77
+ (`pipeline_run.tool_calls`: the arguments sent and the value received,
78
+ Microsoft Learn's page excerpts dropped, since the pipeline reads only
79
+ titles and links). `tests/test_docs_digest_demo.py` hands them to rote's
80
+ own prefix runner as recorded calls, the interpreter verification uses,
81
+ and requires the recorded digest back.
82
+
83
+ ## Layout
84
+
85
+ ```
86
+ examples/docs-digest/
87
+ ├── README.md
88
+ ├── reference.json # the recorded runs, see above
89
+ ├── skill/
90
+ │ ├── SKILL.md
91
+ │ ├── input.json # the sample input; compile picks it up
92
+ │ └── mcp-tools.json # tools/list snapshot of the two tools
93
+ └── compiled/ # `rote compile --runtime dbos` output
94
+ ├── pipeline.yaml
95
+ ├── extracted/
96
+ ├── tests/
97
+ └── compile-report.md
98
+ ```
@@ -0,0 +1,4 @@
1
+ {
2
+ "schema_version": 1,
3
+ "external_backend": "mcp"
4
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "cost_basis": "driver_estimate",
3
+ "driver": "claude",
4
+ "metadata": {
5
+ "cache_read_tokens": 27945,
6
+ "cache_write_tokens": 14182,
7
+ "cost_usd": 0.072854,
8
+ "duration_ms": 14712,
9
+ "input_tokens": 12,
10
+ "num_turns": 6,
11
+ "output_tokens": 3458,
12
+ "repair_rounds": 0,
13
+ "usage_complete": true,
14
+ "usage_source": "generations"
15
+ },
16
+ "schema_version": 1
17
+ }
@@ -0,0 +1,60 @@
1
+ # Compile report: docs-digest
2
+
3
+ rote wrote this report from `pipeline.yaml` and the extracted code. Each node's description is the compiler's reason for its kind; each `# skill: "..."` citation is the rule a line of code implements; each `# rote: assumption:` marker is a decision the skill does not state.
4
+
5
+ Compiled with System-1: rote decided the structure with a structure pass: claude-haiku-5-5 via claude -p (subscription) read the whole skill and proposed every node in 1 round(s), and code checked each one against the skill's text, its tools' schemas and the sample input; no decision model checked it (--decider rules), and the agent wrote the implementations and judge prompts. Every decision, with its confidence and rule, is in `system1/decisions.json`. Its model calls cost $0.0030 (claude-haiku-5-5, structure pass), on top of the agent's run.
6
+
7
+ ## Summary
8
+
9
+ - 4 node(s): 2 `pure_function`, 2 `external_call`, 0 `llm_judge`, 0 `agent_loop`, 0 `hitl_gate`.
10
+ - Codified (`pure_function` + `external_call`): 4 of 4 non-gate node(s), 100%.
11
+ - Implemented impl node(s): 2 of 4.
12
+ - Entry: `search_microsoft_learn`, `read_repo_outline`.
13
+ - Exit: `write_digest`.
14
+ - Mandatory: `search_microsoft_learn`, `pick_reading_list`, `read_repo_outline`, `write_digest`.
15
+ - MCP servers: `deepwiki` (read_repo_outline), `mslearn` (search_microsoft_learn).
16
+
17
+ ## Nodes
18
+
19
+ | Node | Kind | Implementation | Skill section | Description |
20
+ |---|---|---|---|---|
21
+ | `search_microsoft_learn` | external_call | `extracted/search_microsoft_learn.py:search_microsoft_learn` (stub) | 1. Search Microsoft Learn | Searches Microsoft Learn with the topic as the search text and returns the tool's decoded result, an object whose results array holds the matching articles with title and contentUrl. |
22
+ | `pick_reading_list` | pure_function | `extracted/pick_reading_list.py:pick_reading_list` (implemented) | 2. Pick the reading list | Keeps the first 5 Microsoft Learn search results, each reduced to its title and link. |
23
+ | `read_repo_outline` | external_call | `extracted/read_repo_outline.py:read_repo_outline` (stub) | 3. Read the repo's wiki outline | Calls the deepwiki read_wiki_structure tool for the repository and returns the wiki outline as text, as a string. |
24
+ | `write_digest` | pure_function | `extracted/write_digest.py:write_digest` (implemented) | 4. Write the digest | Builds the markdown digest with a Reading list section of linked titles and a Repo outline section holding the wiki outline as returned. |
25
+
26
+ ## Crystallization log
27
+
28
+ - `extracted/pick_reading_list.py` (1 skill citation(s))
29
+ - line 11: "Keep the first 5 results. For each, keep its title and its link."
30
+ - `extracted/read_repo_outline.py`: 3. Read the repo's wiki outline: direct-API backend stub. (0 skill citation(s))
31
+ - `extracted/search_microsoft_learn.py`: 1. Search Microsoft Learn: direct-API backend stub. (0 skill citation(s))
32
+ - `extracted/write_digest.py` (2 skill citation(s))
33
+ - line 14: "one bullet per kept result, the title linked to its URL."
34
+ - line 19: "the wiki outline, as the server returned it."
35
+
36
+ ## Open questions
37
+
38
+ ### Contract: search_microsoft_learn
39
+
40
+ > result shape of mslearn.microsoft_docs_search is assumed, not recorded; downstream nodes read the whole result. Run `rote baseline` against the real server to record it
41
+
42
+ ### Contract: read_repo_outline
43
+
44
+ > result shape of deepwiki.read_wiki_structure is assumed, not recorded; downstream nodes read the whole result. Run `rote baseline` against the real server to record it
45
+
46
+
47
+ ## Suggested next steps
48
+
49
+ - Review every Open question above; each assumption is a rule the skill does not state, and each low-confidence decision took a conservative default.
50
+ - Run the pipeline once (`rote run`) and compare it with a run of the skill.
51
+ - Recompile with `rote compile` after the skill changes. The skeleton is a model's answer (claude-haiku-5-5's structure pass), checked by code, so two compiles of one skill can differ: compare `system1/skeleton.yaml` between runs before trusting a diff.
52
+
53
+ ## rote verification
54
+
55
+ - Generated tests: passed (11 passed in 0.01s), run in an OS sandbox.
56
+ - Implemented impl nodes: 2 of 4.
57
+ - Unresolved problems: 0.
58
+ - Assumptions the skill does not state: 0.
59
+ - Deterministic prefix on the sample input: 0 of 4 node(s) ran on the sample input (2 no recording, 2 not reached).
60
+ - Tool schemas: deepwiki from a live tools/list, mslearn from a live tools/list.