solwyn-cli 0.2.0__tar.gz → 0.2.0rc1__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 (479) hide show
  1. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/CONTRIBUTING.md +0 -6
  2. solwyn_cli-0.2.0rc1/PKG-INFO +287 -0
  3. solwyn_cli-0.2.0rc1/README.md +268 -0
  4. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/docs/mcp-quickstart.md +3 -4
  5. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/docs/mcp-release.md +3 -3
  6. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/docs/registry/server.draft.json +2 -2
  7. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/examples/mcp/typescript/client.test.ts +1 -37
  8. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/examples/mcp/typescript/client.ts +5 -9
  9. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/pyproject.toml +1 -1
  10. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/scripts/mcp_wheel_smoke.py +2 -6
  11. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/fixtures/mcp_installed_legacy.py +1 -1
  12. solwyn_cli-0.2.0rc1/tests/golden/doctor-mcp-key.json +1 -0
  13. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/mcp_legacy_probe.py +1 -1
  14. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_ci_packaging_smoke.py +1 -1
  15. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_client.py +3 -3
  16. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_mcp_wheel_runner.py +3 -10
  17. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_smoke.py +1 -1
  18. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/uv.lock +6 -6
  19. solwyn_cli-0.2.0/Makefile +0 -8
  20. solwyn_cli-0.2.0/PKG-INFO +0 -151
  21. solwyn_cli-0.2.0/README.md +0 -132
  22. solwyn_cli-0.2.0/docs/caller-owned-spend.md +0 -133
  23. solwyn_cli-0.2.0/docs/staging-smoke.md +0 -136
  24. solwyn_cli-0.2.0/scripts/budget-plane-cli-smoke.py +0 -8
  25. solwyn_cli-0.2.0/scripts/budget-plane-mcp-smoke.py +0 -441
  26. solwyn_cli-0.2.0/scripts/budget_plane_smoke.py +0 -828
  27. solwyn_cli-0.2.0/tests/golden/doctor-mcp-key.json +0 -1
  28. solwyn_cli-0.2.0/tests/test_budget_cli_smoke.py +0 -296
  29. solwyn_cli-0.2.0/tests/test_budget_mcp_smoke.py +0 -109
  30. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  31. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  32. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/.github/workflows/ci.yml +0 -0
  33. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/.github/workflows/publish.yml +0 -0
  34. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/.gitignore +0 -0
  35. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/LICENSE +0 -0
  36. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/SECURITY.md +0 -0
  37. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/docs/commands/alerts.mdx +0 -0
  38. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/docs/commands/attest.mdx +0 -0
  39. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/docs/commands/costs.mdx +0 -0
  40. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/docs/commands/forecast.mdx +0 -0
  41. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/docs/commands/overview.mdx +0 -0
  42. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/docs/commands/status.mdx +0 -0
  43. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/docs/core-followups.md +0 -0
  44. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/docs/mcp-bounded-work.md +0 -0
  45. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/docs/mcp-diagnostics.md +0 -0
  46. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/docs/mcp-profiles.md +0 -0
  47. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/docs/media-confirmation.md +0 -0
  48. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/docs/registry/server.schema.2025-12-11.json +0 -0
  49. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/docs/registry/server.schema.2025-12-11.sha256 +0 -0
  50. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/docs/scripting.mdx +0 -0
  51. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/examples/mcp/python/client.py +0 -0
  52. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/examples/mcp/python/pyproject.toml +0 -0
  53. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/examples/mcp/python/uv.lock +0 -0
  54. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/examples/mcp/typescript/.gitignore +0 -0
  55. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/examples/mcp/typescript/package-lock.json +0 -0
  56. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/examples/mcp/typescript/package.json +0 -0
  57. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/examples/mcp/typescript/tsconfig.json +0 -0
  58. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/scripts/generate_contract.py +0 -0
  59. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/scripts/inspect_wheel.py +0 -0
  60. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/scripts/locks/mcp-legacy.in +0 -0
  61. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/scripts/locks/mcp-legacy.txt +0 -0
  62. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/scripts/sync_spec.py +0 -0
  63. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/scripts/validate_mcp_registry.py +0 -0
  64. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/__init__.py +0 -0
  65. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/_mcp_doctor_helper.py +0 -0
  66. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/_mcp_doctor_ipc.py +0 -0
  67. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/_mcp_doctor_pipe.py +0 -0
  68. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/_mcp_doctor_process.py +0 -0
  69. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/_mcp_launch.py +0 -0
  70. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/_mcp_operation.py +0 -0
  71. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/_vendor/__init__.py +0 -0
  72. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/_vendor/batch.py +0 -0
  73. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/_vendor/notification_wire.py +0 -0
  74. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/_vendor/validation.py +0 -0
  75. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/_vendor/wire.py +0 -0
  76. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/artifacts/__init__.py +0 -0
  77. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/artifacts/_atomic.py +0 -0
  78. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/auth.py +0 -0
  79. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/client.py +0 -0
  80. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/__init__.py +0 -0
  81. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/_cost_advice_models.py +0 -0
  82. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/_cost_filters.py +0 -0
  83. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/_cost_models.py +0 -0
  84. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/_entitlement.py +0 -0
  85. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/_notifications_common.py +0 -0
  86. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/_record.py +0 -0
  87. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/_shared.py +0 -0
  88. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/_tags.py +0 -0
  89. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/account.py +0 -0
  90. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/agent_context.py +0 -0
  91. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/alerts.py +0 -0
  92. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/attest.py +0 -0
  93. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/audit.py +0 -0
  94. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/budget.py +0 -0
  95. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/budget_rules.py +0 -0
  96. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/channels.py +0 -0
  97. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/config.py +0 -0
  98. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/cost_analysis.py +0 -0
  99. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/cost_pricing.py +0 -0
  100. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/costs.py +0 -0
  101. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/doctor.py +0 -0
  102. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/forecast.py +0 -0
  103. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/init.py +0 -0
  104. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/keys.py +0 -0
  105. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/login.py +0 -0
  106. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/mcp.py +0 -0
  107. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/mcp_config.py +0 -0
  108. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/mcp_doctor.py +0 -0
  109. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/notifications.py +0 -0
  110. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/overview.py +0 -0
  111. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/plan.py +0 -0
  112. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/projects.py +0 -0
  113. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/providers.py +0 -0
  114. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/record.py +0 -0
  115. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/runs.py +0 -0
  116. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/status.py +0 -0
  117. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/tags.py +0 -0
  118. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/webhooks.py +0 -0
  119. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/commands/whoami.py +0 -0
  120. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/config.py +0 -0
  121. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/errors.py +0 -0
  122. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/exit_codes.py +0 -0
  123. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/help.py +0 -0
  124. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/main.py +0 -0
  125. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/mcp/__init__.py +0 -0
  126. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/mcp/declarations.py +0 -0
  127. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/mcp/parameters.py +0 -0
  128. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/mcp/server.py +0 -0
  129. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/output.py +0 -0
  130. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/runtime.py +0 -0
  131. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/spec/__init__.py +0 -0
  132. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/src/solwyn_cli/spec/openapi_snapshot.json +0 -0
  133. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/contract/__init__.py +0 -0
  134. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/contract/account_cost_query_parameters.json +0 -0
  135. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/contract/alert_query_parameters.json +0 -0
  136. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/contract/builder.py +0 -0
  137. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/contract/cli_contract.json +0 -0
  138. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/contract/cost_query_parameters.json +0 -0
  139. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/fixtures/mcp_doctor_server.py +0 -0
  140. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/fixtures/mcp_doctor_telemetry.py +0 -0
  141. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/fixtures/mcp_doctor_wheel_smoke.py +0 -0
  142. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/__init__.py +0 -0
  143. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/account-alert-email-clear-json.json +0 -0
  144. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/account-alert-email-clear-table.txt +0 -0
  145. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/account-alert-email-set-json.json +0 -0
  146. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/account-alert-email-set-table.txt +0 -0
  147. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/account-alert-email-show-json.json +0 -0
  148. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/account-alert-email-show-table.txt +0 -0
  149. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/agent-context.txt +0 -0
  150. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/alerts-account-delete-json.json +0 -0
  151. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/alerts-account-delete-table.txt +0 -0
  152. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/alerts-account-preview-json.json +0 -0
  153. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/alerts-account-preview-table.txt +0 -0
  154. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/alerts-account-set-json.json +0 -0
  155. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/alerts-account-set-table.txt +0 -0
  156. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/alerts-account-show-json.json +0 -0
  157. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/alerts-account-show-table.txt +0 -0
  158. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/alerts-account-snooze-json.json +0 -0
  159. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/alerts-account-snooze-table.txt +0 -0
  160. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/alerts-account-unsnooze-json.json +0 -0
  161. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/alerts-account-unsnooze-table.txt +0 -0
  162. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/alerts-list-json.json +0 -0
  163. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/alerts-list-table.txt +0 -0
  164. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/alerts-show-json.json +0 -0
  165. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/alerts-show-table.txt +0 -0
  166. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/attest-account-csv.txt +0 -0
  167. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/attest-project-json.json +0 -0
  168. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/audit-json.json +0 -0
  169. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/audit-table.txt +0 -0
  170. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-check-allow-json.json +0 -0
  171. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-check-allow-table.txt +0 -0
  172. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-check-batch-allowed.json +0 -0
  173. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-check-batch-allowed.table +0 -0
  174. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-check-batch-denied.json +0 -0
  175. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-check-batch-denied.table +0 -0
  176. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-check-batch-mixed.json +0 -0
  177. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-check-batch-mixed.table +0 -0
  178. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-check-batch-partial.json +0 -0
  179. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-check-batch-partial.table +0 -0
  180. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-check-batch-stopped.json +0 -0
  181. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-check-batch-stopped.table +0 -0
  182. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-check-batch-unknown.json +0 -0
  183. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-check-batch-unknown.table +0 -0
  184. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-check-deny-json.json +0 -0
  185. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-check-deny-table.txt +0 -0
  186. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-check-fail-open-json.json +0 -0
  187. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-check-fail-open-table.txt +0 -0
  188. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-check-read-only-key-json.json +0 -0
  189. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-check-read-only-key-table.txt +0 -0
  190. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-check-run-stopped-json.json +0 -0
  191. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-check-run-stopped-table.txt +0 -0
  192. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-check-tag-deny-json.json +0 -0
  193. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-check-tag-deny-table.txt +0 -0
  194. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-confirm-expired-json.json +0 -0
  195. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-confirm-expired-table.txt +0 -0
  196. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-confirm-missing-reservation-json.json +0 -0
  197. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-confirm-missing-reservation-table.txt +0 -0
  198. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-confirm-success-json.json +0 -0
  199. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-confirm-success-table.txt +0 -0
  200. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-restore-defaults-json.json +0 -0
  201. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-restore-defaults-table.txt +0 -0
  202. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-rule-add-budget_threshold-json.json +0 -0
  203. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-rule-add-budget_threshold-table.txt +0 -0
  204. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-rule-add-daily_anomaly-json.json +0 -0
  205. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-rule-add-daily_anomaly-table.txt +0 -0
  206. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-rule-add-forecast_overrun-json.json +0 -0
  207. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-rule-add-forecast_overrun-table.txt +0 -0
  208. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-rule-add-runaway_run-json.json +0 -0
  209. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-rule-add-runaway_run-table.txt +0 -0
  210. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-rule-add-scoped_budget-json.json +0 -0
  211. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-rule-add-scoped_budget-table.txt +0 -0
  212. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-rule-add-unit_cost_anomaly-json.json +0 -0
  213. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-rule-add-unit_cost_anomaly-table.txt +0 -0
  214. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-rule-pause-json.json +0 -0
  215. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-rule-pause-table.txt +0 -0
  216. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-rule-preview-json.json +0 -0
  217. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-rule-preview-table.txt +0 -0
  218. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-rule-remove-json.json +0 -0
  219. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-rule-remove-table.txt +0 -0
  220. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-rule-resume-json.json +0 -0
  221. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-rule-resume-table.txt +0 -0
  222. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-rule-snooze-json.json +0 -0
  223. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-rule-snooze-table.txt +0 -0
  224. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-rule-unsnooze-json.json +0 -0
  225. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-rule-unsnooze-table.txt +0 -0
  226. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-rules-list-json.json +0 -0
  227. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-rules-list-table.txt +0 -0
  228. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-set-json.json +0 -0
  229. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-set-table.txt +0 -0
  230. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-status-json.json +0 -0
  231. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-status-rules-json.json +0 -0
  232. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-status-rules-table.txt +0 -0
  233. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-status-table.txt +0 -0
  234. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-threshold-snooze-json.json +0 -0
  235. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-threshold-snooze-table.txt +0 -0
  236. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-threshold-unsnooze-json.json +0 -0
  237. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/budget-threshold-unsnooze-table.txt +0 -0
  238. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/channels-create-json.json +0 -0
  239. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/channels-create-table.txt +0 -0
  240. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/channels-delete-json.json +0 -0
  241. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/channels-delete-table.txt +0 -0
  242. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/channels-list-json.json +0 -0
  243. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/channels-list-table.txt +0 -0
  244. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/channels-show-json.json +0 -0
  245. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/channels-show-table.txt +0 -0
  246. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/channels-test-json.json +0 -0
  247. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/channels-test-table.txt +0 -0
  248. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/channels-update-json.json +0 -0
  249. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/channels-update-table.txt +0 -0
  250. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-account-json.json +0 -0
  251. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-account-table.txt +0 -0
  252. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-account-withheld-json.json +0 -0
  253. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-account-withheld-table.txt +0 -0
  254. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-agent_run-json.json +0 -0
  255. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-agent_run-table.txt +0 -0
  256. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-baseline-json.json +0 -0
  257. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-baseline-table.txt +0 -0
  258. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-day-json.json +0 -0
  259. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-day-table.txt +0 -0
  260. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-drift-json.json +0 -0
  261. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-drift-table.txt +0 -0
  262. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-events-continuation-stderr.txt +0 -0
  263. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-events-json.json +0 -0
  264. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-events-table.txt +0 -0
  265. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-failover_reason-json.json +0 -0
  266. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-failover_reason-table.txt +0 -0
  267. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-model-json.json +0 -0
  268. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-model-table.txt +0 -0
  269. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-priced-models-json.json +0 -0
  270. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-priced-models-table.txt +0 -0
  271. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-provider-json.json +0 -0
  272. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-provider-table.txt +0 -0
  273. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-provider_region-json.json +0 -0
  274. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-provider_region-table.txt +0 -0
  275. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-service_tier-json.json +0 -0
  276. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-service_tier-table.txt +0 -0
  277. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-simulation-json.json +0 -0
  278. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-simulation-table.txt +0 -0
  279. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-status-json.json +0 -0
  280. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-status-table.txt +0 -0
  281. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-tag-customer-json.json +0 -0
  282. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-tag-customer-table.txt +0 -0
  283. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-total-json.json +0 -0
  284. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-total-table.txt +0 -0
  285. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-truncated-json.json +0 -0
  286. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-truncated-table.txt +0 -0
  287. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-unit-economics-json.json +0 -0
  288. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/costs-unit-economics-table.txt +0 -0
  289. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/doctor-degraded-table.txt +0 -0
  290. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/doctor-jwt.json +0 -0
  291. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/email-not-verified.json +0 -0
  292. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/error.json +0 -0
  293. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/forecast-table.txt +0 -0
  294. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/forecast.json +0 -0
  295. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/harness.py +0 -0
  296. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/human-error.txt +0 -0
  297. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/init-json.json +0 -0
  298. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/init-table.txt +0 -0
  299. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/keys-environment-key-refusal-json.json +0 -0
  300. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/keys-environment-key-refusal-table.txt +0 -0
  301. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/keys-keyring-key-refusal-json.json +0 -0
  302. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/keys-keyring-key-refusal-table.txt +0 -0
  303. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/keys-not-found-json.json +0 -0
  304. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/keys-not-found-table.txt +0 -0
  305. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/keys-revoke-json.json +0 -0
  306. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/keys-revoke-table.txt +0 -0
  307. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/keys-rotate-json.json +0 -0
  308. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/keys-rotate-table.txt +0 -0
  309. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/keys-show-json.json +0 -0
  310. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/keys-show-table.txt +0 -0
  311. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/login-jwt-table.txt +0 -0
  312. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/login-jwt.json +0 -0
  313. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/login-key-table.txt +0 -0
  314. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/login-key.json +0 -0
  315. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/logout-table.txt +0 -0
  316. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/logout.json +0 -0
  317. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/mcp-config.json +0 -0
  318. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/mcp-tools.json +0 -0
  319. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/notifications-set-json.json +0 -0
  320. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/notifications-set-table.txt +0 -0
  321. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/notifications-show-json.json +0 -0
  322. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/notifications-show-table.txt +0 -0
  323. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/notifications-test-json.json +0 -0
  324. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/notifications-test-table.txt +0 -0
  325. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/overview-json.json +0 -0
  326. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/overview-paid-json.json +0 -0
  327. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/overview-table.txt +0 -0
  328. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/plan-team-table.txt +0 -0
  329. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/plan-team.json +0 -0
  330. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/projects-create-display-json.json +0 -0
  331. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/projects-create-display-table.txt +0 -0
  332. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/projects-create-stored-json.json +0 -0
  333. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/projects-create-stored-table.txt +0 -0
  334. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/projects-delete-json.json +0 -0
  335. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/projects-delete-table.txt +0 -0
  336. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/projects-list-environment-key-refusal-json.json +0 -0
  337. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/projects-list-environment-key-refusal-table.txt +0 -0
  338. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/projects-list-jwt-json.json +0 -0
  339. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/projects-list-jwt-table.txt +0 -0
  340. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/projects-list-keyring-key-refusal-json.json +0 -0
  341. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/projects-list-keyring-key-refusal-table.txt +0 -0
  342. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/projects-rename-json.json +0 -0
  343. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/projects-rename-table.txt +0 -0
  344. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/projects-show-jwt-json.json +0 -0
  345. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/projects-show-jwt-table.txt +0 -0
  346. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/projects-show-key-json.json +0 -0
  347. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/projects-show-key-table.txt +0 -0
  348. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/providers-failovers-table.txt +0 -0
  349. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/providers-failovers.json +0 -0
  350. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/providers-untracked-table.txt +0 -0
  351. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/providers-untracked.json +0 -0
  352. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/record-batch-json.json +0 -0
  353. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/record-batch-table.txt +0 -0
  354. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/record-dedup-json.json +0 -0
  355. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/record-dedup-table.txt +0 -0
  356. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/record-legacy-json.json +0 -0
  357. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/record-legacy-table.txt +0 -0
  358. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/record-rejection-json.json +0 -0
  359. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/record-rejection-table.txt +0 -0
  360. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/record-single-json.json +0 -0
  361. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/record-single-table.txt +0 -0
  362. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/runs-list-jwt-json.json +0 -0
  363. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/runs-list-key-table.txt +0 -0
  364. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/runs-show-json.json +0 -0
  365. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/runs-show-table.txt +0 -0
  366. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/runs-stop-json.json +0 -0
  367. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/runs-stop-key-refusal-json.json +0 -0
  368. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/runs-stop-key-refusal-table.txt +0 -0
  369. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/runs-stop-not-stoppable-json.json +0 -0
  370. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/runs-stop-not-stoppable-table.txt +0 -0
  371. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/runs-stop-table.txt +0 -0
  372. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/status-flags-table.txt +0 -0
  373. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/status-flags.json +0 -0
  374. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/status-jwt-savings-json.json +0 -0
  375. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/status-jwt-savings-table.txt +0 -0
  376. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/status-table.txt +0 -0
  377. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/status.json +0 -0
  378. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/success.json +0 -0
  379. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/table-no-color.txt +0 -0
  380. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/table-non-tty.txt +0 -0
  381. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/table-tty.txt +0 -0
  382. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/tags-list-json.json +0 -0
  383. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/tags-list-table.txt +0 -0
  384. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/tags-retire-json.json +0 -0
  385. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/tags-retire-table.txt +0 -0
  386. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/tags-values-json.json +0 -0
  387. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/tags-values-table.txt +0 -0
  388. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/webhooks-create-json.json +0 -0
  389. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/webhooks-create-table.txt +0 -0
  390. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/webhooks-delete-json.json +0 -0
  391. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/webhooks-delete-table.txt +0 -0
  392. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/webhooks-list-json.json +0 -0
  393. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/webhooks-list-table.txt +0 -0
  394. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/webhooks-rotate-json.json +0 -0
  395. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/webhooks-rotate-table.txt +0 -0
  396. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/whoami-jwt-table.txt +0 -0
  397. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/whoami-jwt.json +0 -0
  398. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/whoami-key-table.txt +0 -0
  399. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/whoami-key.json +0 -0
  400. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/whoami-production-json.json +0 -0
  401. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/golden/whoami-production-table.txt +0 -0
  402. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/mcp_batch_fixtures.py +0 -0
  403. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_agent_artifacts.py +0 -0
  404. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_alert_query_contract.py +0 -0
  405. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_alerts_command.py +0 -0
  406. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_atomic_rename.py +0 -0
  407. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_attest_command.py +0 -0
  408. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_attest_contract.py +0 -0
  409. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_attest_models.py +0 -0
  410. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_attribution_commands.py +0 -0
  411. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_audit_command.py +0 -0
  412. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_auth.py +0 -0
  413. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_auth_commands.py +0 -0
  414. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_batch_journal_contract.py +0 -0
  415. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_budget_batch.py +0 -0
  416. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_budget_check_command.py +0 -0
  417. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_budget_command.py +0 -0
  418. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_budget_confirm_command.py +0 -0
  419. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_budget_rules_command.py +0 -0
  420. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_budget_set_command.py +0 -0
  421. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_config.py +0 -0
  422. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_config_command.py +0 -0
  423. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_contract_snapshot.py +0 -0
  424. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_cost_advice_command.py +0 -0
  425. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_cost_advice_contract.py +0 -0
  426. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_cost_advice_registration.py +0 -0
  427. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_cost_filters.py +0 -0
  428. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_cost_query_contract.py +0 -0
  429. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_cost_stream.py +0 -0
  430. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_costs_command.py +0 -0
  431. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_doctor_command.py +0 -0
  432. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_entitlement.py +0 -0
  433. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_errors.py +0 -0
  434. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_exit_codes.py +0 -0
  435. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_forecast_command.py +0 -0
  436. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_foundation.py +0 -0
  437. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_help_snapshots.py +0 -0
  438. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_init_command.py +0 -0
  439. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_keys_command.py +0 -0
  440. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_mcp_adoption.py +0 -0
  441. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_mcp_batch_recovery.py +0 -0
  442. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_mcp_boundary.py +0 -0
  443. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_mcp_bounded_results.py +0 -0
  444. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_mcp_cancellation_stdio.py +0 -0
  445. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_mcp_catalog.py +0 -0
  446. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_mcp_conformance.py +0 -0
  447. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_mcp_diagnostics.py +0 -0
  448. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_mcp_doctor_pipe.py +0 -0
  449. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_mcp_doctor_process.py +0 -0
  450. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_mcp_operation.py +0 -0
  451. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_mcp_pagination.py +0 -0
  452. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_mcp_protocol_privacy.py +0 -0
  453. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_mcp_registry.py +0 -0
  454. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_mcp_sdk_migration.py +0 -0
  455. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_mcp_server.py +0 -0
  456. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_mcp_transport_lifecycle.py +0 -0
  457. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_media_confirmation.py +0 -0
  458. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_notifications_commands.py +0 -0
  459. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_notifications_review_regressions.py +0 -0
  460. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_output.py +0 -0
  461. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_output_discipline.py +0 -0
  462. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_overview_command.py +0 -0
  463. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_plan_command.py +0 -0
  464. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_projects_command.py +0 -0
  465. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_providers_command.py +0 -0
  466. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_record_helpers.py +0 -0
  467. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_request_drift.py +0 -0
  468. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_response_subset.py +0 -0
  469. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_run_attribution_integration.py +0 -0
  470. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_runs_command.py +0 -0
  471. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_runtime.py +0 -0
  472. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_shared_command_auth.py +0 -0
  473. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_snapshot_age.py +0 -0
  474. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_status_command.py +0 -0
  475. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_tags_commands.py +0 -0
  476. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_vendor_sync.py +0 -0
  477. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_vendor_validation.py +0 -0
  478. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_vendor_wire.py +0 -0
  479. {solwyn_cli-0.2.0 → solwyn_cli-0.2.0rc1}/tests/test_webhooks_command.py +0 -0
@@ -10,12 +10,6 @@ uv run ruff format --check .
10
10
  uv run pytest
11
11
  ```
12
12
 
13
- For deployed API validation, export a staging account JWT as `SOLWYN_JWT` and run
14
- `make smoke-cli` or `make smoke-mcp`. Each command creates a disposable project,
15
- records synthetic durable spend, tests budget enforcement and reporting, and
16
- archives the project afterward. See [staging smoke tests](docs/staging-smoke.md)
17
- for prerequisites, coverage, and dashboard inspection options.
18
-
19
13
  ## Command and output contracts
20
14
 
21
15
  Treat command names, flags, help text, exit codes, stdout/stderr behavior, and JSON schemas as
@@ -0,0 +1,287 @@
1
+ Metadata-Version: 2.5
2
+ Name: solwyn-cli
3
+ Version: 0.2.0rc1
4
+ Summary: Command-line client for Solwyn
5
+ Author-email: Solwyn <hello@solwyn.ai>
6
+ License-Expression: Apache-2.0
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.11
9
+ Requires-Dist: click>=8.1
10
+ Requires-Dist: httpx>=0.27
11
+ Requires-Dist: keyring>=25
12
+ Requires-Dist: mcp==2.1.1
13
+ Requires-Dist: platformdirs>=4
14
+ Requires-Dist: pydantic>=2
15
+ Requires-Dist: rich>=13
16
+ Requires-Dist: tomli-w>=1
17
+ Requires-Dist: typer>=0.12
18
+ Description-Content-Type: text/markdown
19
+
20
+ # Solwyn CLI
21
+
22
+ Work with Solwyn from the command line: enforce and attribute LLM spend for calls the Solwyn SDK does not instrument, inspect budgets, costs, and provider health, and recover from leaked or expired project keys — from your terminal, your scripts, or your coding agent.
23
+
24
+ > **Status:** pre-release. This repository is private while the first release is prepared, and the package is not yet published to PyPI.
25
+
26
+ ## Installation
27
+
28
+ Until the first release, install from a local checkout:
29
+
30
+ ```console
31
+ uv tool install .
32
+ solwyn --version
33
+ ```
34
+
35
+ Requires Python 3.11 or newer. The package installs two identical executables: `solwyn` and `solwyn-cli` (an alias matching the package name).
36
+
37
+ ## Getting started
38
+
39
+ ```console
40
+ solwyn login # authenticate; use --with-key to store a project key instead
41
+ solwyn init # configure Solwyn for the current repository
42
+ solwyn status # project budget and provider health at a glance
43
+ ```
44
+
45
+ `solwyn init` inspects the repository, writes local configuration, and renders SDK snippets for the providers it detects; add `--agents` to also write guidance files for Claude, Cursor, and `AGENTS.md`.
46
+
47
+ ## Commands
48
+
49
+ | Command | What it does |
50
+ | --- | --- |
51
+ | `login` / `logout` / `whoami` | Manage credentials and show the current identity and project context. |
52
+ | `init` | Configure Solwyn safely for the current repository. |
53
+ | `status` | Show project budget and provider health. |
54
+ | `costs` | Show project costs across server-advertised dimensions, including agent runs and tags. |
55
+ | `record` | Attribute one completed call, or a JSON batch, without a reservation. |
56
+ | `tags list`, `tags values` | Discover account-scoped keys and values (Team+). |
57
+ | `tags retire` | Retire a registered account tag key (JWT admin/owner). |
58
+ | `budget status` | Read current budget status without authorizing spend. |
59
+ | `budget check` / `budget confirm` | Pre-flight guardrail loop for un-instrumented provider calls (below). |
60
+ | `budget set` | Update selected budget settings while preserving all other configuration. |
61
+ | `runs list` / `show` / `stop` | Inspect agent runs and stop their future checks and lease renewals. |
62
+ | `projects create` / `list` / `show` | Manage projects; `create --scope` mints the first key with an explicit scope. |
63
+ | `keys show` / `rotate` / `revoke` | Inspect key metadata (including its scope), rotate with `--scope` to change it, or hard-revoke. |
64
+ | `mcp` | Serve Solwyn tools to agents over local MCP stdio. |
65
+ | `mcp-config` | Generate an offline command/args descriptor; defaults to the read profile. |
66
+ | `doctor --mcp` | Check MCP discovery, selected project/key context and an authenticated read when supported. |
67
+ | `agent-context` | Print safe Solwyn budget guidance for coding agents. |
68
+ | `config` | Inspect and update local configuration. |
69
+
70
+ Every command's `--help` states its exit codes, authentication requirements, and JSON output schema.
71
+
72
+ ## Budget guardrails for un-instrumented calls
73
+
74
+ Calls made through the Solwyn SDK are enforced and attributed automatically. For everything else — a `curl`, another language, a one-off script — the CLI provides an explicit two-step loop that covers enforcement and attribution:
75
+
76
+ ```console
77
+ # 1. Reserve budget immediately before the call. A denied check exits with
78
+ # code 4, so scripts and CI can gate on it directly.
79
+ solwyn budget check --provider openai --model gpt-4.1 --estimated-input-tokens 1200
80
+
81
+ # 2. Make the provider call yourself.
82
+
83
+ # 3. Settle the reservation with what the call actually used.
84
+ solwyn budget confirm --call-id 12345678-1234-1234-1234-123456789abc --provider openai --model gpt-4.1 \
85
+ --reservation-id "$RESERVATION" --input-tokens 1180 --output-tokens 640
86
+ ```
87
+
88
+ The CLI's caller-owned workflow maintains parity with Solwyn Python SDK 0.6.0 semantics and covers enforcement and attribution. Confirmation records attribution after settlement by default, using the same canonical call ID; add `--no-record` only when attribution is intentionally handled elsewhere.
89
+
90
+ The loop covers more than text tokens:
91
+
92
+ - **Media calls** — pass the billed quantities to `budget check` (`--image-count`, `--video-seconds`, `--audio-seconds`, `--input-characters`, `--generation-count`, `--resolution`, `--quality`) so unit-priced image, video, audio, and speech calls are priced and deniable before they run.
93
+ - **Image-token models** — `budget confirm` accepts `--image-input-tokens` and `--image-output-tokens` so image-rate spend settles at its real cost.
94
+ - **Fallbacks** — declare failover intent with repeated `--fallback-provider` / `--fallback-model` pairs.
95
+ - **Per-run caps** — scope enforcement to a single agent run with `--agent-run-id`.
96
+
97
+ Use `budget status` to poll; `check` is for the moment immediately before spend.
98
+
99
+ ## For coding agents
100
+
101
+ Start with the [MCP quickstart](docs/mcp-quickstart.md): install the local wheel,
102
+ generate a read-first descriptor, diagnose credentials, and run the tested
103
+ Python or TypeScript client. The [release checklist](docs/mcp-release.md) and
104
+ Registry metadata are unpublished preparation.
105
+
106
+ `solwyn mcp` serves read, guardrail, and attribution tools over stdio, resolving configuration and credentials fresh on every call. Standard MCP capability and schema discovery exposes the exact tools and input/output shapes in the running version. `solwyn agent-context` prints a compact SDK 0.6 capability contract suitable for pasting into an agent's context, and `solwyn init --agents` writes the equivalent guidance into the repository.
107
+
108
+ Use `solwyn --project proj_0123456789abcdef01234567 mcp --profile read` for the 13 read tools
109
+ (replace the synthetic ID with your project);
110
+ the default `guardrails` profile keeps all 17. Profiles are fixed at launch and
111
+ never grant permissions. See [MCP profiles and tool contracts](docs/mcp-profiles.md)
112
+ for authentication, discovery caching, and operation-specific replay rules.
113
+
114
+ ## Scripting
115
+
116
+ All commands support `--json` for schema-bearing JSON output (each payload names its schema, e.g. `solwyn.costs.v1`), and exit codes are stable and documented per command: `0` success, `2` usage, with distinct codes for API, auth, budget-denial, and not-found failures. Global flags select the project (`--project`), API base URL (`--api-url`), and output format.
117
+
118
+ ## Development
119
+
120
+ The project uses [uv](https://docs.astral.sh/uv/) for dependency and environment management.
121
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for the full local workflow and contract-update rules.
122
+
123
+ ```console
124
+ uv sync --locked --all-groups
125
+ uv run solwyn --version
126
+ uv run ruff check .
127
+ uv run ruff format --check .
128
+ uv run pytest
129
+ ```
130
+
131
+ Two test-suite properties worth knowing before contributing:
132
+
133
+ - Any change to the CLI surface (commands, flags, help text, exit codes, JSON output) requires regenerating the machine-readable contract snapshot with `scripts/generate_contract.py`; `tests/test_contract_snapshot.py` fails until you do.
134
+ - The vendored OpenAPI snapshot and its drift guards are self-invalidating by design — adopt fields properly or record a decline in the registry; never loosen a guard to make a test pass.
135
+
136
+ The vendored snapshot has two independent safeguards: public CLI CI checks its age and the
137
+ checked-in request/response contracts, while a proposed private monitor compares its content
138
+ with Core. The private monitor, ownership, and verified Core follow-ups are documented in
139
+ [Core contract follow-ups](docs/core-followups.md) and tracked in
140
+ [Core issue #403](https://github.com/solwyn-ai/core/issues/403).
141
+
142
+
143
+ ## Recording caller-owned spend
144
+
145
+ `budget confirm` records attribution after successful settlement by default.
146
+ `--no-record` skips attribution; a recording failure warns without undoing settlement.
147
+ Use `record` for completed calls that have no reservation, including local providers:
148
+
149
+ ```sh
150
+ export SOLWYN_AGENT_RUN_ID="job-42"
151
+ export SOLWYN_TAGS="environment=prod,team=ops"
152
+ solwyn record --provider ollama --model llama3 --input-tokens 120 --output-tokens 30
153
+ solwyn record --batch events.json --json
154
+ solwyn --project YOUR_PROJECT_ID tags list
155
+ ```
156
+
157
+ Reuse the same canonical lowercase `--call-id` UUID for retries of one logical event
158
+ (generate one with `uuidgen | tr A-F a-f`). `record --batch FILE|-` takes a nonempty
159
+ JSON array of event inputs and chunks it into at most 1000 events per request. Each
160
+ invocation uses a fresh `sdk_instance_id` across all its chunks. Never send `cost_usd`
161
+ or `lease_id`; Core computes prices. Inspect `rejected` and `duplicates`: call-ID
162
+ replays succeed, while rejections and legacy timestamp collisions exit 1. On an uncertain
163
+ or partial write, retain the returned `call_ids` in input order before retrying; the
164
+ result has `status=failed` and preserves the dispositions already received.
165
+
166
+ Repeat `--tag key=value` to override environment tags. Keys and values preserve
167
+ whitespace and case; empty values and equals signs in values are legal, commas in
168
+ flag values are not. Tags allow at most 10 keys, keys of 1–64 characters, and values
169
+ up to 256 characters, with no NUL. Reusing `SOLWYN_AGENT_RUN_ID` groups a job's calls;
170
+ otherwise Core creates automatic runs from each invocation's ID.
171
+
172
+ Denied budget checks also record receipts unless `--no-record` is set. Supply
173
+ `--estimated-output-tokens` to attribute the upper savings bound. Tag submission
174
+ and enforcement work on every tier; discovery is account-scoped and requires Team.
175
+ `tags values KEY --prefix Q` pages through values; retiring a key frees an active
176
+ key slot, and later successful ingest may reactivate it.
177
+
178
+ ## Batch budget checks
179
+
180
+ `solwyn budget check --batch checks.json --json` reads a nonempty JSON array of
181
+ check bodies; use `--batch -` for stdin. For example:
182
+
183
+ ```json
184
+ [{"model":"gpt-4o","provider":"openai","estimated_input_tokens":1200,"agent_run_id":"job-42","tags":{"environment":"prod"}}]
185
+ ```
186
+
187
+ All bodies validate before submission. Requests contain at most 32 checks, preserve
188
+ input order, and count every item against `checks_per_minute`. Each allowed item
189
+ normally holds its own reservation: confirm it after its provider call. A fail-open
190
+ item has a null reservation and must not be confirmed. Do not poll or repeat checks
191
+ to refresh reservations. Denied items record one receipt each unless `--no-record`
192
+ is set, sharing a fresh invocation ID. `--estimated-output-tokens` applies the same
193
+ savings upper bound to every denial. Put all other per-check options in the JSON;
194
+ missing tags and run IDs inherit `SOLWYN_TAGS` and `SOLWYN_AGENT_RUN_ID`. Explicit
195
+ nulls suppress these defaults. A run ID opts into termination directives.
196
+
197
+ The `solwyn.budget.check.batch.v1` payload has index-aligned `results`: each contains
198
+ either a nullable `result`, or `error_code` and `error_message`. Unknown models are
199
+ per-item errors. All allowed exits 0, any denial exits 4, and errors without a denial
200
+ exit 1. A request-level 404 or 503 fails the chunk. If an earlier chunk completed,
201
+ its results and reservation IDs remain in output, alongside `failed_chunk_start`
202
+ and `total_checks`; later chunks were not submitted. Reservation state inside a
203
+ 503-failed chunk is unknown. Do not replay completed checks or assume rollback.
204
+ The MCP `budget_check_batch` tool submits at most 32 checks to Core’s durable
205
+ journal with a caller-retained UUIDv7. Recovery uses GET only; explicit denial
206
+ attribution retry preserves its exact event. See [bounded MCP work and recovery](docs/mcp-bounded-work.md)
207
+ for limits, required Core rollout, indexed outcomes and recording uncertainty.
208
+
209
+ ## Trust posture
210
+
211
+ Solwyn CLI:
212
+
213
+ - sends only your own spend events; `sdk_instance_id` is an invocation ID (the retained operation UUID for recoverable MCP batches); no telemetry;
214
+
215
+ - never captures, logs, or transmits prompts or responses;
216
+ - never collects, stores, or proxies provider API keys;
217
+ - has no telemetry, update checks, or phone-home behavior; and
218
+ - stores Solwyn credentials only in the operating system keychain, never in configuration files, command-line arguments, or output.
219
+
220
+ ## Security
221
+
222
+ Please report security issues privately as described in [SECURITY.md](SECURITY.md).
223
+
224
+ ## License
225
+
226
+ Licensed under the Apache License 2.0. See [LICENSE](LICENSE).
227
+
228
+ ### Budget rules and per-run caps
229
+
230
+ List rule conditions, routing, and separate pause/snooze state:
231
+
232
+ ```sh
233
+ solwyn --project proj_example budget rules list
234
+ solwyn --json --project proj_example budget rules list
235
+ ```
236
+
237
+ Rule mutations require a user login with owner/admin permissions. Each rule may
238
+ reference notification channels with repeatable `--channel ID` options:
239
+
240
+ ```sh
241
+ solwyn budget rule add --type budget_threshold --percent 80
242
+ solwyn budget rule add --type runaway_run --spend 5 --mode hard_deny
243
+ solwyn budget rule add --type scoped_budget --scope tag --match env --value prod --limit 25 --mode hard_deny
244
+ solwyn budget rule add --type forecast_overrun --spend 200
245
+ solwyn budget rule add --type daily_anomaly --multiplier 2 --lookback 7
246
+ solwyn budget rule add --type unit_cost_anomaly --multiplier 3
247
+ ```
248
+
249
+ Runaway `--calls N` and `--window MIN` must be supplied together. Scoped caps also
250
+ accept `--scope model|provider|agent_run`; `--value` is valid only for tag scope.
251
+ The rule count limit includes all six types. Adding a rule preserves the complete
252
+ budget configuration and re-reads it before writing. Core has no concurrency token,
253
+ so this detects changes before the final write but cannot eliminate the remaining
254
+ race. A 503 after a write triggers a read to confirm the complete configuration;
255
+ an unconfirmed outcome requires reviewing the budget before retrying.
256
+
257
+ ```sh
258
+ solwyn budget rule pause RULE_KEY
259
+ solwyn budget rule resume RULE_KEY
260
+ solwyn budget rule snooze RULE_KEY --until +2h
261
+ solwyn budget rule unsnooze RULE_KEY
262
+ solwyn budget rule remove RULE_KEY
263
+ solwyn budget threshold snooze 80 --until 2026-12-01T12:00:00Z
264
+ solwyn budget threshold unsnooze 80
265
+ solwyn budget restore-defaults
266
+ ```
267
+
268
+ Snooze accepts timezone-aware ISO datetimes or `+30m`, `+2h`, and `+1d` durations,
269
+ which the CLI converts to absolute timestamps. **A snoozed hard-deny rule still
270
+ denies; pause releases enforcement.** Rule keys are content-addressed: editing
271
+ keyed condition fields changes the key. Restore-defaults preserves non-threshold
272
+ rules, and the CLI re-reads and prints the full rule state afterward.
273
+
274
+ Preview routing with a project key or user login, including an unsaved condition:
275
+
276
+ ```sh
277
+ solwyn budget rule preview
278
+ solwyn budget rule preview RULE_KEY --channel CHANNEL_ID
279
+ solwyn budget rule preview --type runaway_run --spend 5 --mode hard_deny
280
+ ```
281
+
282
+ During interactive project creation, `solwyn init --run-cap 5` adds a wildcard
283
+ `runaway_run` rule with `hard_deny` immediately after creation. It caps every run at
284
+ `min(caps)` when run identity is supplied; scoped run caps and wildcard caps share
285
+ the strictest limit. For an existing project, use `budget rule add` instead.
286
+ The default MCP surface includes the pure-read `list_budget_rules` tool; rule
287
+ mutations remain CLI operations.
@@ -0,0 +1,268 @@
1
+ # Solwyn CLI
2
+
3
+ Work with Solwyn from the command line: enforce and attribute LLM spend for calls the Solwyn SDK does not instrument, inspect budgets, costs, and provider health, and recover from leaked or expired project keys — from your terminal, your scripts, or your coding agent.
4
+
5
+ > **Status:** pre-release. This repository is private while the first release is prepared, and the package is not yet published to PyPI.
6
+
7
+ ## Installation
8
+
9
+ Until the first release, install from a local checkout:
10
+
11
+ ```console
12
+ uv tool install .
13
+ solwyn --version
14
+ ```
15
+
16
+ Requires Python 3.11 or newer. The package installs two identical executables: `solwyn` and `solwyn-cli` (an alias matching the package name).
17
+
18
+ ## Getting started
19
+
20
+ ```console
21
+ solwyn login # authenticate; use --with-key to store a project key instead
22
+ solwyn init # configure Solwyn for the current repository
23
+ solwyn status # project budget and provider health at a glance
24
+ ```
25
+
26
+ `solwyn init` inspects the repository, writes local configuration, and renders SDK snippets for the providers it detects; add `--agents` to also write guidance files for Claude, Cursor, and `AGENTS.md`.
27
+
28
+ ## Commands
29
+
30
+ | Command | What it does |
31
+ | --- | --- |
32
+ | `login` / `logout` / `whoami` | Manage credentials and show the current identity and project context. |
33
+ | `init` | Configure Solwyn safely for the current repository. |
34
+ | `status` | Show project budget and provider health. |
35
+ | `costs` | Show project costs across server-advertised dimensions, including agent runs and tags. |
36
+ | `record` | Attribute one completed call, or a JSON batch, without a reservation. |
37
+ | `tags list`, `tags values` | Discover account-scoped keys and values (Team+). |
38
+ | `tags retire` | Retire a registered account tag key (JWT admin/owner). |
39
+ | `budget status` | Read current budget status without authorizing spend. |
40
+ | `budget check` / `budget confirm` | Pre-flight guardrail loop for un-instrumented provider calls (below). |
41
+ | `budget set` | Update selected budget settings while preserving all other configuration. |
42
+ | `runs list` / `show` / `stop` | Inspect agent runs and stop their future checks and lease renewals. |
43
+ | `projects create` / `list` / `show` | Manage projects; `create --scope` mints the first key with an explicit scope. |
44
+ | `keys show` / `rotate` / `revoke` | Inspect key metadata (including its scope), rotate with `--scope` to change it, or hard-revoke. |
45
+ | `mcp` | Serve Solwyn tools to agents over local MCP stdio. |
46
+ | `mcp-config` | Generate an offline command/args descriptor; defaults to the read profile. |
47
+ | `doctor --mcp` | Check MCP discovery, selected project/key context and an authenticated read when supported. |
48
+ | `agent-context` | Print safe Solwyn budget guidance for coding agents. |
49
+ | `config` | Inspect and update local configuration. |
50
+
51
+ Every command's `--help` states its exit codes, authentication requirements, and JSON output schema.
52
+
53
+ ## Budget guardrails for un-instrumented calls
54
+
55
+ Calls made through the Solwyn SDK are enforced and attributed automatically. For everything else — a `curl`, another language, a one-off script — the CLI provides an explicit two-step loop that covers enforcement and attribution:
56
+
57
+ ```console
58
+ # 1. Reserve budget immediately before the call. A denied check exits with
59
+ # code 4, so scripts and CI can gate on it directly.
60
+ solwyn budget check --provider openai --model gpt-4.1 --estimated-input-tokens 1200
61
+
62
+ # 2. Make the provider call yourself.
63
+
64
+ # 3. Settle the reservation with what the call actually used.
65
+ solwyn budget confirm --call-id 12345678-1234-1234-1234-123456789abc --provider openai --model gpt-4.1 \
66
+ --reservation-id "$RESERVATION" --input-tokens 1180 --output-tokens 640
67
+ ```
68
+
69
+ The CLI's caller-owned workflow maintains parity with Solwyn Python SDK 0.6.0 semantics and covers enforcement and attribution. Confirmation records attribution after settlement by default, using the same canonical call ID; add `--no-record` only when attribution is intentionally handled elsewhere.
70
+
71
+ The loop covers more than text tokens:
72
+
73
+ - **Media calls** — pass the billed quantities to `budget check` (`--image-count`, `--video-seconds`, `--audio-seconds`, `--input-characters`, `--generation-count`, `--resolution`, `--quality`) so unit-priced image, video, audio, and speech calls are priced and deniable before they run.
74
+ - **Image-token models** — `budget confirm` accepts `--image-input-tokens` and `--image-output-tokens` so image-rate spend settles at its real cost.
75
+ - **Fallbacks** — declare failover intent with repeated `--fallback-provider` / `--fallback-model` pairs.
76
+ - **Per-run caps** — scope enforcement to a single agent run with `--agent-run-id`.
77
+
78
+ Use `budget status` to poll; `check` is for the moment immediately before spend.
79
+
80
+ ## For coding agents
81
+
82
+ Start with the [MCP quickstart](docs/mcp-quickstart.md): install the local wheel,
83
+ generate a read-first descriptor, diagnose credentials, and run the tested
84
+ Python or TypeScript client. The [release checklist](docs/mcp-release.md) and
85
+ Registry metadata are unpublished preparation.
86
+
87
+ `solwyn mcp` serves read, guardrail, and attribution tools over stdio, resolving configuration and credentials fresh on every call. Standard MCP capability and schema discovery exposes the exact tools and input/output shapes in the running version. `solwyn agent-context` prints a compact SDK 0.6 capability contract suitable for pasting into an agent's context, and `solwyn init --agents` writes the equivalent guidance into the repository.
88
+
89
+ Use `solwyn --project proj_0123456789abcdef01234567 mcp --profile read` for the 13 read tools
90
+ (replace the synthetic ID with your project);
91
+ the default `guardrails` profile keeps all 17. Profiles are fixed at launch and
92
+ never grant permissions. See [MCP profiles and tool contracts](docs/mcp-profiles.md)
93
+ for authentication, discovery caching, and operation-specific replay rules.
94
+
95
+ ## Scripting
96
+
97
+ All commands support `--json` for schema-bearing JSON output (each payload names its schema, e.g. `solwyn.costs.v1`), and exit codes are stable and documented per command: `0` success, `2` usage, with distinct codes for API, auth, budget-denial, and not-found failures. Global flags select the project (`--project`), API base URL (`--api-url`), and output format.
98
+
99
+ ## Development
100
+
101
+ The project uses [uv](https://docs.astral.sh/uv/) for dependency and environment management.
102
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for the full local workflow and contract-update rules.
103
+
104
+ ```console
105
+ uv sync --locked --all-groups
106
+ uv run solwyn --version
107
+ uv run ruff check .
108
+ uv run ruff format --check .
109
+ uv run pytest
110
+ ```
111
+
112
+ Two test-suite properties worth knowing before contributing:
113
+
114
+ - Any change to the CLI surface (commands, flags, help text, exit codes, JSON output) requires regenerating the machine-readable contract snapshot with `scripts/generate_contract.py`; `tests/test_contract_snapshot.py` fails until you do.
115
+ - The vendored OpenAPI snapshot and its drift guards are self-invalidating by design — adopt fields properly or record a decline in the registry; never loosen a guard to make a test pass.
116
+
117
+ The vendored snapshot has two independent safeguards: public CLI CI checks its age and the
118
+ checked-in request/response contracts, while a proposed private monitor compares its content
119
+ with Core. The private monitor, ownership, and verified Core follow-ups are documented in
120
+ [Core contract follow-ups](docs/core-followups.md) and tracked in
121
+ [Core issue #403](https://github.com/solwyn-ai/core/issues/403).
122
+
123
+
124
+ ## Recording caller-owned spend
125
+
126
+ `budget confirm` records attribution after successful settlement by default.
127
+ `--no-record` skips attribution; a recording failure warns without undoing settlement.
128
+ Use `record` for completed calls that have no reservation, including local providers:
129
+
130
+ ```sh
131
+ export SOLWYN_AGENT_RUN_ID="job-42"
132
+ export SOLWYN_TAGS="environment=prod,team=ops"
133
+ solwyn record --provider ollama --model llama3 --input-tokens 120 --output-tokens 30
134
+ solwyn record --batch events.json --json
135
+ solwyn --project YOUR_PROJECT_ID tags list
136
+ ```
137
+
138
+ Reuse the same canonical lowercase `--call-id` UUID for retries of one logical event
139
+ (generate one with `uuidgen | tr A-F a-f`). `record --batch FILE|-` takes a nonempty
140
+ JSON array of event inputs and chunks it into at most 1000 events per request. Each
141
+ invocation uses a fresh `sdk_instance_id` across all its chunks. Never send `cost_usd`
142
+ or `lease_id`; Core computes prices. Inspect `rejected` and `duplicates`: call-ID
143
+ replays succeed, while rejections and legacy timestamp collisions exit 1. On an uncertain
144
+ or partial write, retain the returned `call_ids` in input order before retrying; the
145
+ result has `status=failed` and preserves the dispositions already received.
146
+
147
+ Repeat `--tag key=value` to override environment tags. Keys and values preserve
148
+ whitespace and case; empty values and equals signs in values are legal, commas in
149
+ flag values are not. Tags allow at most 10 keys, keys of 1–64 characters, and values
150
+ up to 256 characters, with no NUL. Reusing `SOLWYN_AGENT_RUN_ID` groups a job's calls;
151
+ otherwise Core creates automatic runs from each invocation's ID.
152
+
153
+ Denied budget checks also record receipts unless `--no-record` is set. Supply
154
+ `--estimated-output-tokens` to attribute the upper savings bound. Tag submission
155
+ and enforcement work on every tier; discovery is account-scoped and requires Team.
156
+ `tags values KEY --prefix Q` pages through values; retiring a key frees an active
157
+ key slot, and later successful ingest may reactivate it.
158
+
159
+ ## Batch budget checks
160
+
161
+ `solwyn budget check --batch checks.json --json` reads a nonempty JSON array of
162
+ check bodies; use `--batch -` for stdin. For example:
163
+
164
+ ```json
165
+ [{"model":"gpt-4o","provider":"openai","estimated_input_tokens":1200,"agent_run_id":"job-42","tags":{"environment":"prod"}}]
166
+ ```
167
+
168
+ All bodies validate before submission. Requests contain at most 32 checks, preserve
169
+ input order, and count every item against `checks_per_minute`. Each allowed item
170
+ normally holds its own reservation: confirm it after its provider call. A fail-open
171
+ item has a null reservation and must not be confirmed. Do not poll or repeat checks
172
+ to refresh reservations. Denied items record one receipt each unless `--no-record`
173
+ is set, sharing a fresh invocation ID. `--estimated-output-tokens` applies the same
174
+ savings upper bound to every denial. Put all other per-check options in the JSON;
175
+ missing tags and run IDs inherit `SOLWYN_TAGS` and `SOLWYN_AGENT_RUN_ID`. Explicit
176
+ nulls suppress these defaults. A run ID opts into termination directives.
177
+
178
+ The `solwyn.budget.check.batch.v1` payload has index-aligned `results`: each contains
179
+ either a nullable `result`, or `error_code` and `error_message`. Unknown models are
180
+ per-item errors. All allowed exits 0, any denial exits 4, and errors without a denial
181
+ exit 1. A request-level 404 or 503 fails the chunk. If an earlier chunk completed,
182
+ its results and reservation IDs remain in output, alongside `failed_chunk_start`
183
+ and `total_checks`; later chunks were not submitted. Reservation state inside a
184
+ 503-failed chunk is unknown. Do not replay completed checks or assume rollback.
185
+ The MCP `budget_check_batch` tool submits at most 32 checks to Core’s durable
186
+ journal with a caller-retained UUIDv7. Recovery uses GET only; explicit denial
187
+ attribution retry preserves its exact event. See [bounded MCP work and recovery](docs/mcp-bounded-work.md)
188
+ for limits, required Core rollout, indexed outcomes and recording uncertainty.
189
+
190
+ ## Trust posture
191
+
192
+ Solwyn CLI:
193
+
194
+ - sends only your own spend events; `sdk_instance_id` is an invocation ID (the retained operation UUID for recoverable MCP batches); no telemetry;
195
+
196
+ - never captures, logs, or transmits prompts or responses;
197
+ - never collects, stores, or proxies provider API keys;
198
+ - has no telemetry, update checks, or phone-home behavior; and
199
+ - stores Solwyn credentials only in the operating system keychain, never in configuration files, command-line arguments, or output.
200
+
201
+ ## Security
202
+
203
+ Please report security issues privately as described in [SECURITY.md](SECURITY.md).
204
+
205
+ ## License
206
+
207
+ Licensed under the Apache License 2.0. See [LICENSE](LICENSE).
208
+
209
+ ### Budget rules and per-run caps
210
+
211
+ List rule conditions, routing, and separate pause/snooze state:
212
+
213
+ ```sh
214
+ solwyn --project proj_example budget rules list
215
+ solwyn --json --project proj_example budget rules list
216
+ ```
217
+
218
+ Rule mutations require a user login with owner/admin permissions. Each rule may
219
+ reference notification channels with repeatable `--channel ID` options:
220
+
221
+ ```sh
222
+ solwyn budget rule add --type budget_threshold --percent 80
223
+ solwyn budget rule add --type runaway_run --spend 5 --mode hard_deny
224
+ solwyn budget rule add --type scoped_budget --scope tag --match env --value prod --limit 25 --mode hard_deny
225
+ solwyn budget rule add --type forecast_overrun --spend 200
226
+ solwyn budget rule add --type daily_anomaly --multiplier 2 --lookback 7
227
+ solwyn budget rule add --type unit_cost_anomaly --multiplier 3
228
+ ```
229
+
230
+ Runaway `--calls N` and `--window MIN` must be supplied together. Scoped caps also
231
+ accept `--scope model|provider|agent_run`; `--value` is valid only for tag scope.
232
+ The rule count limit includes all six types. Adding a rule preserves the complete
233
+ budget configuration and re-reads it before writing. Core has no concurrency token,
234
+ so this detects changes before the final write but cannot eliminate the remaining
235
+ race. A 503 after a write triggers a read to confirm the complete configuration;
236
+ an unconfirmed outcome requires reviewing the budget before retrying.
237
+
238
+ ```sh
239
+ solwyn budget rule pause RULE_KEY
240
+ solwyn budget rule resume RULE_KEY
241
+ solwyn budget rule snooze RULE_KEY --until +2h
242
+ solwyn budget rule unsnooze RULE_KEY
243
+ solwyn budget rule remove RULE_KEY
244
+ solwyn budget threshold snooze 80 --until 2026-12-01T12:00:00Z
245
+ solwyn budget threshold unsnooze 80
246
+ solwyn budget restore-defaults
247
+ ```
248
+
249
+ Snooze accepts timezone-aware ISO datetimes or `+30m`, `+2h`, and `+1d` durations,
250
+ which the CLI converts to absolute timestamps. **A snoozed hard-deny rule still
251
+ denies; pause releases enforcement.** Rule keys are content-addressed: editing
252
+ keyed condition fields changes the key. Restore-defaults preserves non-threshold
253
+ rules, and the CLI re-reads and prints the full rule state afterward.
254
+
255
+ Preview routing with a project key or user login, including an unsaved condition:
256
+
257
+ ```sh
258
+ solwyn budget rule preview
259
+ solwyn budget rule preview RULE_KEY --channel CHANNEL_ID
260
+ solwyn budget rule preview --type runaway_run --spend 5 --mode hard_deny
261
+ ```
262
+
263
+ During interactive project creation, `solwyn init --run-cap 5` adds a wildcard
264
+ `runaway_run` rule with `hard_deny` immediately after creation. It caps every run at
265
+ `min(caps)` when run identity is supplied; scoped run caps and wildcard caps share
266
+ the strictest limit. For an existing project, use `budget rule add` instead.
267
+ The default MCP surface includes the pure-read `list_budget_rules` tool; rule
268
+ mutations remain CLI operations.
@@ -1,6 +1,6 @@
1
1
  # Connect a harness to Solwyn MCP
2
2
 
3
- Solwyn 0.2.0 is **pre-release, private and not published to PyPI**. Start from an
3
+ Solwyn 0.2.0rc1 is **pre-release, private and not published to PyPI**. Start from an
4
4
  authorized source checkout or a wheel built from it. This guide uses local stdio;
5
5
  there is no hosted MCP endpoint. Account/project access is a separate prerequisite.
6
6
 
@@ -11,7 +11,7 @@ From the authorized CLI checkout:
11
11
  ```sh
12
12
  uv sync --locked --all-groups
13
13
  uv build --wheel
14
- uv tool install --python 3.11 dist/solwyn_cli-0.2.0-py3-none-any.whl
14
+ uv tool install --python 3.11 dist/solwyn_cli-0.2.0rc1-py3-none-any.whl
15
15
  uv tool dir --bin
16
16
  solwyn --version
17
17
  solwyn login --with-key
@@ -145,8 +145,7 @@ proxy credentials and OTel configuration. The SDK adds its OS baseline even when
145
145
  external clients/hosts remain separate from Solwyn's no-telemetry policy.
146
146
 
147
147
  `--timeout` bounds client useful work (10 seconds by default, configurable from
148
- 0.1 to 30). TypeScript discovery uses this same timeout, including slow process
149
- startup on Windows. Timeout/cancellation unwinds the transport explicitly. SDK cleanup
148
+ 0.1 to 30); timeout/cancellation unwinds the transport explicitly. SDK cleanup
150
149
  is additional: Python's inspected waits total up to 6.5 seconds plus scheduling;
151
150
  TypeScript closes stdin, waits up to 2 seconds, then allows up to 2 seconds after
152
151
  termination before killing, and the example observes direct-child exit for up
@@ -1,6 +1,6 @@
1
1
  # MCP release preparation
2
2
 
3
- **Unpublished draft.** Package metadata currently says `solwyn-cli` 0.2.0; the
3
+ **Unpublished draft.** Package metadata currently says `solwyn-cli` 0.2.0rc1; the
4
4
  source repository is private and no PyPI publication is established. The
5
5
  [Registry draft](registry/server.draft.json) proposes `ai.solwyn/solwyn`;
6
6
  namespace ownership is **unverified**. Neither local validation nor MCP
@@ -33,7 +33,7 @@ resolution remains separate; this is not a claim of byte-identical wheel builds.
33
33
  Inspect the final distribution before uploading; for the current version:
34
34
 
35
35
  ```sh
36
- uv run --no-sync python scripts/inspect_wheel.py dist/solwyn_cli-0.2.0-py3-none-any.whl
36
+ uv run --no-sync python scripts/inspect_wheel.py dist/solwyn_cli-0.2.0rc1-py3-none-any.whl
37
37
  ```
38
38
 
39
39
  Protected checks keep their existing names: `Quality`, `Tests (Python 3.11)`,
@@ -75,7 +75,7 @@ artifacts and the Registry publisher's `mcp-publisher publish` from the director
75
75
  containing the final `server.json`. Obtain credentials through the release
76
76
  system, and follow the publisher's current authentication/namespace verification
77
77
  instructions. Do not run these commands for `server.draft.json` or infer that
78
- 0.2.0 is already installable from an index.
78
+ 0.2.0rc1 is already installable from an index.
79
79
 
80
80
  ## Registry schema and ownership marker
81
81
 
@@ -3,13 +3,13 @@
3
3
  "name": "ai.solwyn/solwyn",
4
4
  "title": "Solwyn",
5
5
  "description": "Inspect Solwyn budgets and attribute model spend through local MCP tools.",
6
- "version": "0.2.0",
6
+ "version": "0.2.0rc1",
7
7
  "packages": [
8
8
  {
9
9
  "registryType": "pypi",
10
10
  "registryBaseUrl": "https://pypi.org",
11
11
  "identifier": "solwyn-cli",
12
- "version": "0.2.0",
12
+ "version": "0.2.0rc1",
13
13
  "runtimeHint": "uvx",
14
14
  "transport": {"type": "stdio"},
15
15
  "packageArguments": [