opsmith-cli 0.4.6b0__tar.gz → 0.6.1__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 (251) hide show
  1. opsmith_cli-0.6.1/.claude/settings.json +5 -0
  2. opsmith_cli-0.6.1/.flake8 +3 -0
  3. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/.github/workflows/python-publish.yml +2 -2
  4. opsmith_cli-0.6.1/.github/workflows/tests.yml +31 -0
  5. opsmith_cli-0.6.1/.pre-commit-config.yaml +41 -0
  6. opsmith_cli-0.6.1/CHANGELOG.md +246 -0
  7. opsmith_cli-0.6.1/CLAUDE.md +423 -0
  8. opsmith_cli-0.6.1/PKG-INFO +537 -0
  9. opsmith_cli-0.6.1/README.md +496 -0
  10. opsmith_cli-0.6.1/docs/README.md +18 -0
  11. opsmith_cli-0.6.1/docs/notes/2026-09-04-migration-plan.md +289 -0
  12. opsmith_cli-0.6.1/docs/notes/README.md +15 -0
  13. opsmith_cli-0.6.1/docs/reference/2026-09-21-agent-skill.md +142 -0
  14. opsmith_cli-0.6.1/docs/reference/README.md +20 -0
  15. opsmith_cli-0.6.1/docs/specs/2026-09-04-phase-0-headless-core/0a-cli-split-and-errors.md +104 -0
  16. opsmith_cli-0.6.1/docs/specs/2026-09-04-phase-0-headless-core/0b-context-and-events.md +99 -0
  17. opsmith_cli-0.6.1/docs/specs/2026-09-04-phase-0-headless-core/0c-model-config-and-tool-checks.md +90 -0
  18. opsmith_cli-0.6.1/docs/specs/2026-09-04-phase-0-headless-core/0d-interaction-api.md +101 -0
  19. opsmith_cli-0.6.1/docs/specs/2026-09-04-phase-0-headless-core/0e-headless-mode.md +105 -0
  20. opsmith_cli-0.6.1/docs/specs/2026-09-04-phase-0-headless-core/0f-headless-subcommands.md +93 -0
  21. opsmith_cli-0.6.1/docs/specs/2026-09-04-phase-0-headless-core/0g-provider-questions-and-plan.md +93 -0
  22. opsmith_cli-0.6.1/docs/specs/2026-09-04-phase-0-headless-core/README.md +117 -0
  23. opsmith_cli-0.6.1/docs/specs/2026-09-04-phase-1-harness-integration.md +180 -0
  24. opsmith_cli-0.6.1/docs/specs/2026-09-04-phase-2-service-model-v2/2a-schema-v2-and-upgrade.md +188 -0
  25. opsmith_cli-0.6.1/docs/specs/2026-09-04-phase-2-service-model-v2/2b-references-secrets-and-providers.md +154 -0
  26. opsmith_cli-0.6.1/docs/specs/2026-09-04-phase-2-service-model-v2/2c-compose-renderer-and-previews.md +91 -0
  27. opsmith_cli-0.6.1/docs/specs/2026-09-04-phase-2-service-model-v2/2d-deterministic-deploys.md +98 -0
  28. opsmith_cli-0.6.1/docs/specs/2026-09-04-phase-2-service-model-v2/2e-release-and-env-values.md +65 -0
  29. opsmith_cli-0.6.1/docs/specs/2026-09-04-phase-2-service-model-v2/2f-validation-repair-and-init-jobs.md +63 -0
  30. opsmith_cli-0.6.1/docs/specs/2026-09-04-phase-2-service-model-v2/2g-capacity-planning.md +145 -0
  31. opsmith_cli-0.6.1/docs/specs/2026-09-04-phase-2-service-model-v2/2h-image-sources-and-deploy-flow.md +58 -0
  32. opsmith_cli-0.6.1/docs/specs/2026-09-04-phase-2-service-model-v2/README.md +115 -0
  33. opsmith_cli-0.6.1/docs/specs/2026-09-04-phase-3-customization.md +252 -0
  34. opsmith_cli-0.6.1/docs/specs/2026-09-04-phase-4-remote-state.md +199 -0
  35. opsmith_cli-0.6.1/docs/specs/2026-09-04-phase-5-recipes.md +226 -0
  36. opsmith_cli-0.6.1/docs/specs/2026-09-04-phase-6-agentic-analysis.md +165 -0
  37. opsmith_cli-0.6.1/docs/specs/2026-09-04-phase-7-mcp-server.md +94 -0
  38. opsmith_cli-0.6.1/docs/specs/2026-09-04-phase-8-data-durability.md +107 -0
  39. opsmith_cli-0.6.1/docs/specs/README.md +55 -0
  40. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/agent.py +21 -5
  41. opsmith_cli-0.6.1/opsmith/cli/agent_install.py +776 -0
  42. opsmith_cli-0.6.1/opsmith/cli/app.py +578 -0
  43. opsmith_cli-0.6.1/opsmith/cli/commands/__init__.py +71 -0
  44. opsmith_cli-0.6.1/opsmith/cli/commands/agent.py +180 -0
  45. opsmith_cli-0.6.1/opsmith/cli/commands/analyze.py +32 -0
  46. opsmith_cli-0.6.1/opsmith/cli/commands/config.py +121 -0
  47. opsmith_cli-0.6.1/opsmith/cli/commands/deploy.py +80 -0
  48. opsmith_cli-0.6.1/opsmith/cli/commands/env.py +345 -0
  49. opsmith_cli-0.6.1/opsmith/cli/commands/release.py +110 -0
  50. opsmith_cli-0.6.1/opsmith/cli/commands/setup.py +53 -0
  51. opsmith_cli-0.6.1/opsmith/cli/commands/validate.py +79 -0
  52. opsmith_cli-0.6.1/opsmith/cli/flags.py +231 -0
  53. opsmith_cli-0.6.1/opsmith/cli/interaction.py +305 -0
  54. opsmith_cli-0.6.1/opsmith/cli/output.py +396 -0
  55. opsmith_cli-0.6.1/opsmith/cli/skill_refs.py +471 -0
  56. opsmith_cli-0.6.1/opsmith/cli/state.py +63 -0
  57. opsmith_cli-0.6.1/opsmith/cloud_providers/aws.py +262 -0
  58. opsmith_cli-0.6.1/opsmith/cloud_providers/base.py +278 -0
  59. opsmith_cli-0.6.1/opsmith/cloud_providers/gcp.py +348 -0
  60. opsmith_cli-0.6.1/opsmith/core/answers.py +453 -0
  61. opsmith_cli-0.6.1/opsmith/core/config.py +359 -0
  62. opsmith_cli-0.6.1/opsmith/core/context.py +119 -0
  63. opsmith_cli-0.6.1/opsmith/core/errors.py +360 -0
  64. opsmith_cli-0.6.1/opsmith/core/events.py +177 -0
  65. opsmith_cli-0.6.1/opsmith/core/interaction.py +669 -0
  66. opsmith_cli-0.6.1/opsmith/core/llm.py +151 -0
  67. opsmith_cli-0.6.1/opsmith/core/operations.py +1253 -0
  68. opsmith_cli-0.6.1/opsmith/core/provisioners.py +109 -0
  69. opsmith_cli-0.6.1/opsmith/core/questions.py +606 -0
  70. opsmith_cli-0.6.1/opsmith/core/results.py +544 -0
  71. opsmith_cli-0.6.1/opsmith/core/steps.py +127 -0
  72. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/deployment_strategies/base.py +225 -93
  73. opsmith_cli-0.6.1/opsmith/deployment_strategies/monolithic.py +1917 -0
  74. opsmith_cli-0.6.1/opsmith/git_repo.py +179 -0
  75. opsmith_cli-0.6.1/opsmith/infra_provisioners/__init__.py +0 -0
  76. opsmith_cli-0.6.1/opsmith/infra_provisioners/ansible_provisioner.py +112 -0
  77. opsmith_cli-0.6.1/opsmith/infra_provisioners/base_provisioner.py +151 -0
  78. opsmith_cli-0.6.1/opsmith/infra_provisioners/terraform_provisioner.py +112 -0
  79. opsmith_cli-0.6.1/opsmith/main.py +9 -0
  80. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/models.py +25 -14
  81. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/repo_map.py +39 -37
  82. opsmith_cli-0.6.1/opsmith/service_detector.py +518 -0
  83. opsmith_cli-0.6.1/opsmith/settings.py +51 -0
  84. opsmith_cli-0.6.1/opsmith/skill/SKILL.md +279 -0
  85. opsmith_cli-0.6.1/opsmith/skill/references/commands.md +774 -0
  86. opsmith_cli-0.6.1/opsmith/skill/references/config-schema.md +88 -0
  87. opsmith_cli-0.6.1/opsmith/skill/references/ownership.md +64 -0
  88. opsmith_cli-0.6.1/opsmith/skill/references/workflows.md +124 -0
  89. opsmith_cli-0.6.1/opsmith/templates/docker_compose_run/aws/main.yml +63 -0
  90. opsmith_cli-0.6.1/opsmith/templates/docker_compose_run/gcp/main.yml +58 -0
  91. opsmith_cli-0.6.1/opsmith/tests/__init__.py +0 -0
  92. opsmith_cli-0.6.1/opsmith/tests/conftest.py +556 -0
  93. opsmith_cli-0.6.1/opsmith/tests/test_agent_install.py +371 -0
  94. opsmith_cli-0.6.1/opsmith/tests/test_answers.py +299 -0
  95. opsmith_cli-0.6.1/opsmith/tests/test_boundaries.py +120 -0
  96. opsmith_cli-0.6.1/opsmith/tests/test_cli_contract.py +444 -0
  97. opsmith_cli-0.6.1/opsmith/tests/test_cloud_providers.py +273 -0
  98. opsmith_cli-0.6.1/opsmith/tests/test_commands.py +280 -0
  99. opsmith_cli-0.6.1/opsmith/tests/test_config_commands.py +261 -0
  100. opsmith_cli-0.6.1/opsmith/tests/test_env_plan.py +638 -0
  101. opsmith_cli-0.6.1/opsmith/tests/test_error_hints.py +111 -0
  102. opsmith_cli-0.6.1/opsmith/tests/test_events.py +234 -0
  103. opsmith_cli-0.6.1/opsmith/tests/test_flag_mapping.py +227 -0
  104. opsmith_cli-0.6.1/opsmith/tests/test_git_repo.py +144 -0
  105. opsmith_cli-0.6.1/opsmith/tests/test_interaction.py +743 -0
  106. opsmith_cli-0.6.1/opsmith/tests/test_interaction_keys.py +329 -0
  107. opsmith_cli-0.6.1/opsmith/tests/test_llm_config.py +151 -0
  108. opsmith_cli-0.6.1/opsmith/tests/test_monolithic_strategy.py +1199 -0
  109. opsmith_cli-0.6.1/opsmith/tests/test_operations.py +1034 -0
  110. opsmith_cli-0.6.1/opsmith/tests/test_provisioners.py +278 -0
  111. opsmith_cli-0.6.1/opsmith/tests/test_questions.py +328 -0
  112. opsmith_cli-0.6.1/opsmith/tests/test_requirements.py +180 -0
  113. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/tests/test_service_detector.py +111 -4
  114. opsmith_cli-0.6.1/opsmith/tests/test_skill_refs.py +218 -0
  115. opsmith_cli-0.6.1/opsmith/tests/test_steps.py +114 -0
  116. opsmith_cli-0.6.1/opsmith/tests/test_validate_commands.py +385 -0
  117. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/types.py +122 -15
  118. opsmith_cli-0.6.1/opsmith/utils.py +202 -0
  119. opsmith_cli-0.6.1/pyproject.toml +97 -0
  120. opsmith_cli-0.6.1/scripts/build_skill_refs.py +50 -0
  121. opsmith_cli-0.6.1/uv.lock +2304 -0
  122. opsmith_cli-0.4.6b0/.flake8 +0 -3
  123. opsmith_cli-0.4.6b0/.pre-commit-config.yaml +0 -22
  124. opsmith_cli-0.4.6b0/CONVENTIONS.md +0 -35
  125. opsmith_cli-0.4.6b0/PKG-INFO +0 -275
  126. opsmith_cli-0.4.6b0/README.md +0 -236
  127. opsmith_cli-0.4.6b0/opsmith/cloud_providers/aws.py +0 -190
  128. opsmith_cli-0.4.6b0/opsmith/cloud_providers/base.py +0 -176
  129. opsmith_cli-0.4.6b0/opsmith/cloud_providers/gcp.py +0 -233
  130. opsmith_cli-0.4.6b0/opsmith/deployment_strategies/monolithic.py +0 -1336
  131. opsmith_cli-0.4.6b0/opsmith/exceptions.py +0 -10
  132. opsmith_cli-0.4.6b0/opsmith/git_repo.py +0 -114
  133. opsmith_cli-0.4.6b0/opsmith/infra_provisioners/ansible_provisioner.py +0 -53
  134. opsmith_cli-0.4.6b0/opsmith/infra_provisioners/base_provisioner.py +0 -96
  135. opsmith_cli-0.4.6b0/opsmith/infra_provisioners/terraform_provisioner.py +0 -80
  136. opsmith_cli-0.4.6b0/opsmith/main.py +0 -593
  137. opsmith_cli-0.4.6b0/opsmith/service_detector.py +0 -365
  138. opsmith_cli-0.4.6b0/opsmith/settings.py +0 -29
  139. opsmith_cli-0.4.6b0/opsmith/templates/docker_compose_run/aws/main.yml +0 -26
  140. opsmith_cli-0.4.6b0/opsmith/templates/docker_compose_run/gcp/main.yml +0 -26
  141. opsmith_cli-0.4.6b0/opsmith/utils.py +0 -114
  142. opsmith_cli-0.4.6b0/pyproject.toml +0 -67
  143. opsmith_cli-0.4.6b0/uv.lock +0 -3760
  144. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/.gitignore +0 -0
  145. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/LICENSE.txt +0 -0
  146. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/__init__.py +0 -0
  147. {opsmith_cli-0.4.6b0/opsmith/infra_provisioners → opsmith_cli-0.6.1/opsmith/cli}/__init__.py +0 -0
  148. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/cloud_providers/__init__.py +0 -0
  149. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/constants.py +0 -0
  150. {opsmith_cli-0.4.6b0/opsmith/tests → opsmith_cli-0.6.1/opsmith/core}/__init__.py +0 -0
  151. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/deployment_strategies/__init__.py +0 -0
  152. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/prompts.py +0 -0
  153. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/README.md +0 -0
  154. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/arduino-tags.scm +0 -0
  155. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/c-tags.scm +0 -0
  156. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/c_sharp-tags.scm +0 -0
  157. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/chatito-tags.scm +0 -0
  158. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/commonlisp-tags.scm +0 -0
  159. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/cpp-tags.scm +0 -0
  160. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/csharp-tags.scm +0 -0
  161. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/d-tags.scm +0 -0
  162. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/dart-tags.scm +0 -0
  163. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/elisp-tags.scm +0 -0
  164. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/elixir-tags.scm +0 -0
  165. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/elm-tags.scm +0 -0
  166. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/gleam-tags.scm +0 -0
  167. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/go-tags.scm +0 -0
  168. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/hcl-tags.scm +0 -0
  169. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/java-tags.scm +0 -0
  170. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/javascript-tags.scm +0 -0
  171. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/kotlin-tags.scm +0 -0
  172. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/lua-tags.scm +0 -0
  173. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/ocaml-tags.scm +0 -0
  174. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/ocaml_interface-tags.scm +0 -0
  175. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/php-tags.scm +0 -0
  176. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/pony-tags.scm +0 -0
  177. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/properties-tags.scm +0 -0
  178. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/python-tags.scm +0 -0
  179. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/ql-tags.scm +0 -0
  180. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/r-tags.scm +0 -0
  181. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/racket-tags.scm +0 -0
  182. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/ruby-tags.scm +0 -0
  183. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/rust-tags.scm +0 -0
  184. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/scala-tags.scm +0 -0
  185. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/solidity-tags.scm +0 -0
  186. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/swift-tags.scm +0 -0
  187. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/typescript-tags.scm +0 -0
  188. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/queries/tree-sitter-languages/udev-tags.scm +0 -0
  189. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/cloud_storage_cleanup/aws/main.yml +0 -0
  190. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/cloud_storage_cleanup/gcp/main.yml +0 -0
  191. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/container_registry/aws/main.tf +0 -0
  192. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/container_registry/aws/outputs.tf +0 -0
  193. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/container_registry/aws/variables.tf +0 -0
  194. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/container_registry/gcp/main.tf +0 -0
  195. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/container_registry/gcp/outputs.tf +0 -0
  196. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/container_registry/gcp/variables.tf +0 -0
  197. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/docker_build_push/aws/main.yml +0 -0
  198. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/docker_build_push/gcp/main.yml +0 -0
  199. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/docker_compose_deploy/aws/inventory.yml +0 -0
  200. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/docker_compose_deploy/aws/main.yml +0 -0
  201. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/docker_compose_deploy/gcp/inventory.yml +0 -0
  202. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/docker_compose_deploy/gcp/main.yml +0 -0
  203. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/docker_compose_run/aws/inventory.yml +0 -0
  204. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/docker_compose_run/gcp/inventory.yml +0 -0
  205. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/docker_compose_snippets/base.yml +0 -0
  206. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/docker_compose_snippets/elasticsearch.yml +0 -0
  207. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/docker_compose_snippets/kafka.yml +0 -0
  208. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/docker_compose_snippets/mongodb.yml +0 -0
  209. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/docker_compose_snippets/mysql.yml +0 -0
  210. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/docker_compose_snippets/postgresql.yml +0 -0
  211. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/docker_compose_snippets/rabbitmq.yml +0 -0
  212. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/docker_compose_snippets/redis.yml +0 -0
  213. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/docker_compose_snippets/services/backend_api.yml +0 -0
  214. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/docker_compose_snippets/services/backend_worker.yml +0 -0
  215. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/docker_compose_snippets/services/full_stack.yml +0 -0
  216. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/docker_compose_snippets/traefik.yml +0 -0
  217. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/docker_compose_snippets/weaviate.yml +0 -0
  218. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/dockerfiles/python_backend_api +0 -0
  219. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/dockerfiles/python_backend_worker +0 -0
  220. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/fetch_remote_files/aws/inventory.yml +0 -0
  221. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/fetch_remote_files/aws/main.yml +0 -0
  222. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/fetch_remote_files/gcp/inventory.yml +0 -0
  223. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/fetch_remote_files/gcp/main.yml +0 -0
  224. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/frontend_bucket_cert/aws/main.tf +0 -0
  225. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/frontend_bucket_cert/aws/outputs.tf +0 -0
  226. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/frontend_bucket_cert/aws/variables.tf +0 -0
  227. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/frontend_bucket_cert/gcp/main.tf +0 -0
  228. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/frontend_bucket_cert/gcp/outputs.tf +0 -0
  229. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/frontend_bucket_cert/gcp/variables.tf +0 -0
  230. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/frontend_cdn/aws/main.tf +0 -0
  231. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/frontend_cdn/aws/outputs.tf +0 -0
  232. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/frontend_cdn/aws/variables.tf +0 -0
  233. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/frontend_cdn/gcp/main.tf +0 -0
  234. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/frontend_cdn/gcp/outputs.tf +0 -0
  235. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/frontend_cdn/gcp/variables.tf +0 -0
  236. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/frontend_deploy/aws/main.yml +0 -0
  237. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/frontend_deploy/gcp/main.yml +0 -0
  238. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/virtual_machine/aws/main.tf +0 -0
  239. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/virtual_machine/aws/outputs.tf +0 -0
  240. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/virtual_machine/aws/variables.tf +0 -0
  241. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/virtual_machine/gcp/main.tf +0 -0
  242. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/virtual_machine/gcp/outputs.tf +0 -0
  243. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/virtual_machine/gcp/variables.tf +0 -0
  244. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/virtual_machine_setup/aws/inventory.yml +0 -0
  245. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/virtual_machine_setup/aws/main.yml +0 -0
  246. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/virtual_machine_setup/gcp/inventory.yml +0 -0
  247. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/opsmith/templates/virtual_machine_setup/gcp/main.yml +0 -0
  248. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/resources/deploy_demo.gif +0 -0
  249. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/resources/deploy_demo.svg +0 -0
  250. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/resources/setup_demo.gif +0 -0
  251. {opsmith_cli-0.4.6b0 → opsmith_cli-0.6.1}/resources/setup_demo.svg +0 -0
@@ -0,0 +1,5 @@
1
+ {
2
+ "enabledPlugins": {
3
+ "claude-md-management@claude-plugins-official": true
4
+ }
5
+ }
@@ -0,0 +1,3 @@
1
+ [flake8]
2
+ ignore = E203,E704,W503,E501
3
+ max-line-length = 100
@@ -20,9 +20,9 @@ jobs:
20
20
  runs-on: ubuntu-latest
21
21
 
22
22
  steps:
23
- - uses: actions/checkout@v4
23
+ - uses: actions/checkout@v5
24
24
 
25
- - uses: actions/setup-python@v5
25
+ - uses: actions/setup-python@v6
26
26
  with:
27
27
  python-version: "3.x"
28
28
 
@@ -0,0 +1,31 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ pytest:
13
+ runs-on: ubuntu-latest
14
+ strategy:
15
+ fail-fast: false
16
+ matrix:
17
+ python-version: ["3.12", "3.13", "3.14"]
18
+
19
+ steps:
20
+ - uses: actions/checkout@v5
21
+
22
+ - name: Install uv
23
+ uses: astral-sh/setup-uv@v7
24
+ with:
25
+ python-version: ${{ matrix.python-version }}
26
+
27
+ - name: Install dependencies
28
+ run: uv sync --group dev
29
+
30
+ - name: Run tests
31
+ run: uv run pytest
@@ -0,0 +1,41 @@
1
+ repos:
2
+ - repo: https://github.com/PyCQA/isort
3
+ rev: 5.12.0
4
+ hooks:
5
+ - id: isort
6
+ args: ["--profile", "black"]
7
+ - repo: https://github.com/psf/black
8
+ rev: 26.5.1
9
+ hooks:
10
+ - id: black
11
+ args: ["--line-length", "100", "--preview"]
12
+ - repo: https://github.com/pycqa/flake8
13
+ rev: 7.1.0
14
+ hooks:
15
+ - id: flake8
16
+ args: ["--show-source"]
17
+ - repo: https://github.com/codespell-project/codespell
18
+ rev: v2.2.6
19
+ hooks:
20
+ - id: codespell
21
+ additional_dependencies:
22
+ - tomli
23
+ - repo: local
24
+ hooks:
25
+ - id: build-skill-refs
26
+ name: regenerate the agent skill references
27
+ # It regenerates rather than complaining, so a change to a command or the schema updates
28
+ # the skill in the same commit. CI enforces it separately, through test_skill_refs.py,
29
+ # because CI runs pytest and nothing else.
30
+ entry: uv run python scripts/build_skill_refs.py
31
+ language: system
32
+ pass_filenames: false
33
+ files: ^(opsmith/(cli|core)/|opsmith/types\.py|scripts/build_skill_refs\.py)
34
+ - id: mypy
35
+ name: mypy
36
+ # Run through uv rather than mirrors-mypy: the pydantic plugin has to import the same
37
+ # pydantic the project pins, which an isolated hook environment would not have.
38
+ entry: uv run mypy
39
+ language: system
40
+ types: [python]
41
+ pass_filenames: false
@@ -0,0 +1,246 @@
1
+ # Changelog
2
+
3
+ All notable changes to Opsmith are recorded here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project follows
5
+ [semantic versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [0.6.1] - 2026-10-01
8
+
9
+ ### Fixed
10
+
11
+ - `opsmith run` no longer runs a slow command more than once on AWS. The command was held open
12
+ as one SSM execution. Any command that took longer than a minute hit the connection's timeout,
13
+ and the connection then executed it again from the start, up to three more times, while the
14
+ earlier runs carried on. The command now starts as a background job on the machine, and
15
+ Opsmith checks on it every ten seconds until it finishes. Starting the job is never retried. A
16
+ command may run for up to 24 hours, after which it is stopped. GCP runs the same way, so a
17
+ dropped IAP tunnel no longer ends the run.
18
+
19
+ ## [0.6.0] - 2026-09-21
20
+
21
+ Coding-harness integration, phase 1 of the
22
+ [migration to 1.0](docs/notes/2026-09-04-migration-plan.md): Opsmith ships the instructions a
23
+ coding agent needs in order to drive it.
24
+
25
+ ### Added
26
+
27
+ - **An Agent Skill, shipped in the package and installed into your harness.**
28
+ `opsmith agent install --target claude` copies it into `.claude/skills/`, and the other
29
+ targets are `agents`, `codex`, `opencode`, `cursor`, `gemini`, plus `auto`;
30
+ `--target` is required, because installing writes into directories belonging to your other
31
+ tools; `opsmith agent status` says where it is
32
+ and whether it is the version you are running; `opsmith agent uninstall` removes exactly what
33
+ was installed and nothing else. None of the three needs a model or a cloud account, because
34
+ copying files does not. `--agents-md` additionally writes an Opsmith section into `AGENTS.md`
35
+ and an `@AGENTS.md` import into `CLAUDE.md`, between markers, so re-running updates in place.
36
+ The skill teaches the workflow, the ownership rules for `.opsmith/`, the exit codes and the
37
+ run-again loop; two of its four references are generated from the CLI and the pydantic models,
38
+ so they cannot drift from the code.
39
+ - **`opsmith dockerfile validate [--service SLUG] [--timeout S]`** builds each service's
40
+ Dockerfile and runs the image, and reports the build and run outcome with the last fifty lines
41
+ of each. It exits 4 when the model judges the failure to be the Dockerfile's fault, with the
42
+ report in `error.details`, and exits 0 when it does not - a container that exits because the
43
+ database it wants does not exist yet is not a broken Dockerfile, and an agent should not try to
44
+ fix one. With no `--service` it checks every service built from a Dockerfile. `--timeout`
45
+ lengthens the container watch; the build ceiling is not configurable, because shortening it
46
+ would turn a slow but correct build into a failure.
47
+ - **`opsmith --version`**, so a harness can tell which release's instructions it is holding.
48
+
49
+ ### Changed
50
+
51
+ - `opsmith config validate`, `config schema` and `config show` return typed results rather than
52
+ ad-hoc dictionaries. The JSON envelopes are unchanged; what changes is that the generated
53
+ command reference can now name each one's result model, which was the point.
54
+ - `opsmith run` and everything else that exits with a status of its own is now described as such
55
+ in the generated reference, derived from the result model rather than written down, so a second
56
+ such command would inherit the note.
57
+
58
+ ### Fixed
59
+
60
+ - A Terraform output that cannot be parsed as JSON now carries a hint naming the command to run in
61
+ the working directory, like every other failure. It was the one error in the package raised
62
+ without one.
63
+
64
+ ## [0.5.0] - 2026-09-20
65
+
66
+ The headless core, phase 0 of the [migration to 1.0](docs/notes/2026-09-04-migration-plan.md),
67
+ complete: parts 0a to 0g.
68
+
69
+ ### Added
70
+
71
+ - `opsmith env plan` reports every answer creating an environment will need, before anything is
72
+ created. For each one it gives the key, the question, the options where it can list them, the
73
+ default where there is one, and the environment variable a secret should arrive in - and says
74
+ which of them this run would actually stop for, which depends on whether `--accept-defaults`
75
+ is in use. It writes nothing, creates nothing, and needs neither docker nor terraform.
76
+ It does read from your cloud account where it can, to list the regions the account really has,
77
+ but a machine that has no credentials yet still gets the plan and is told which parts of it
78
+ went unlisted.
79
+ - Which questions exist depends on the cloud provider and the deployment strategy, so a plan
80
+ that has not been told those two reports what it can, names them as the answers to give first,
81
+ and says `complete: false` rather than passing a short list off as the whole one. The same
82
+ holds for a provider or strategy that declares no questions: `partial_reasons` names it.
83
+ - `opsmith env plan --write-answers FILE` writes that list as a YAML file to fill in and hand
84
+ back with `--answers`. Anything with a default is written with it; anything still to be
85
+ answered is written commented out, because a key present with an empty value counts as an
86
+ answer of the empty string and would quietly satisfy the question it was meant to leave open.
87
+ A secret is always commented out - those belong in a `--env-file`.
88
+ - Cloud providers declare their questions as data. `AWS` declares the region, `GCP` the project,
89
+ the region and the zone, each saying which earlier answer its listing depends on. A question
90
+ declared this way is asked through exactly the same interaction as one asked inline, so a
91
+ flag, a file or an environment variable answers it identically; what is new is only that it
92
+ can be reported before it is reached.
93
+ - Naming a cloud provider or a deployment strategy that is not installed is now
94
+ `INVALID_ARGUMENT` and exit 2, with the names that would have worked in the details. It used
95
+ to be an unhandled `ValueError` reported as an internal failure.
96
+
97
+ - Everything the `setup` and `deploy` menus can do is now a subcommand that takes flags and never
98
+ prompts: `opsmith init`, `env list`, `env create`, `env status`, `release`, `update`, `run` and
99
+ `destroy`. The menus remain, and dispatch to exactly the same functions, so the two cannot
100
+ drift. See "Running Opsmith without a terminal" in the README.
101
+ - Every flag is shorthand for an answer, on the keys the questions already had: `--region
102
+ us-east-1` is `--answer env.region=us-east-1`, and `--domain api=api.example.com` is `--answer
103
+ env.domain.api=api.example.com`. Also `--name`, `--provider`, `--strategy`, `--project-id`,
104
+ `--zone`, `--instance-type`, `--domain-email`, `--env-var KEY=VALUE`, `--build-env
105
+ slug:KEY=VALUE`, `--app-name` and `--rescan`.
106
+ - Every command returns a typed result, which is what `--output json` now puts in the envelope's
107
+ `result` field: the infrastructure, the registry, the urls per service and the DNS records a
108
+ creation asked for; the images and health verdict of a release; what a destroy tore down. Each
109
+ also carries `notices` and `next_steps`, so a driver reading only stdout gets what a person
110
+ watching the terminal would have seen.
111
+ - Infrastructure is reported as a list of `Resource` — a `kind`, an `id`, and whatever of `name`,
112
+ `region`, `address`, `size` and `details` applies — rather than as fields shaped for a single
113
+ virtual machine. A strategy that raises several machines reports several of them; one that
114
+ deploys to a cluster or a serverless platform reports what it actually made. `destroy` reports
115
+ the same shape it created, in place of the strings it used to name things with.
116
+ - `opsmith run` reports which host the command ran on, in the result's `target`.
117
+ - `opsmith run` exits with the exit code of the command it ran, and reports the tail of its
118
+ stdout and stderr in the result. A non-zero exit is no longer reported as a failed playbook.
119
+ - `opsmith env list` and `opsmith env status` read the repository and nothing else. They need no
120
+ cloud account, no docker and no terraform, and run with an empty `PATH`.
121
+ - `opsmith init --app-name "My App"` writes the deployment configuration without scanning the
122
+ repository, for a harness that intends to author the services itself and have Opsmith validate
123
+ them.
124
+ - `opsmith env create --no-deploy` writes the environment to the configuration without creating
125
+ anything. Running `env create` again for an environment that has not been deployed picks it up
126
+ rather than refusing the name, so a creation that stopped part way can be finished.
127
+ - Headless runs. A run with no terminal never blocks on a question: it resolves the answer, or it
128
+ stops with the key that is missing and the command to run again. Answers come from `--answer
129
+ key=value`, `--env-file`, `--answers`, `OPSMITH_ANSWER_<KEY>`, and what the environment has
130
+ already been asked, in that order; `--accept-defaults` takes each question's own default.
131
+ A run is headless when `--non-interactive` or `OPSMITH_NON_INTERACTIVE` says so, when stdin is
132
+ not a terminal, or when `--output json` is in use.
133
+ - Two new stops, both resumable by running the same command again: `MISSING_ANSWER` (exit 3),
134
+ which names the key, the choices and the variable that would carry a secret; and
135
+ `PENDING_ACTION` (exit 8), which names something outside Opsmith that has to happen first. Both
136
+ carry the command to resume with, which is the invocation that stopped, minus its credentials.
137
+ - An answer store per environment. Every answer is written the moment it is given, in both
138
+ interactive and headless runs, so a run that stops never asks for the same thing twice.
139
+ - Opsmith now keeps what it remembers outside your repository, under
140
+ `~/.opsmith/projects/<name>-<digest>/environments/<env>/`: the answers an environment has given,
141
+ the secrets it needs until the environment itself holds them, and the steps a run has finished.
142
+ None of it is authored and none of it belongs in a diff; keeping the secrets out of the tree is
143
+ also the only promise that holds, since an ignore rule says nothing about `git add -f`, an
144
+ archive of the directory, or a build context that never read it. Set `state_dir:` in
145
+ `.opsmith.conf.yml` to put it somewhere else.
146
+ - `opsmith setup --accept-detected` takes the detected services and dependencies as they are,
147
+ instead of opening an editor to review each one.
148
+ - `ctx.steps.once("vm.create")`, a ledger for a step that cannot simply be run again, kept in
149
+ `.opsmith/environments/<env>/steps.yml`. It is a convenience for strategy authors; a strategy
150
+ whose steps are idempotent needs nothing.
151
+ - `opsmith config validate|schema|show`: check, describe and print the deployment configuration
152
+ without a cloud account, docker or terraform. `config schema --format markdown` renders the
153
+ schema as a document.
154
+ - `--output json`: exactly one JSON envelope on stdout, with progress streamed to stderr as NDJSON.
155
+ - The model may be configured without typing it: `--model` falls back to `OPSMITH_MODEL` and then
156
+ to `model:` in `.opsmith.conf.yml`, and `--api-key` falls back to the provider's own key
157
+ variable (`OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GEMINI_API_KEY`).
158
+ - Stable error codes and exit codes: 2 for a usage or validation error, 4 for a failing external
159
+ tool, 5 for cloud credentials, 6 for a model that gave up. Every failure carries a code, a
160
+ message, a hint and machine-readable details.
161
+ - Tracing is an extra: `pip install "opsmith-cli[logfire]"` to use `--logfire-token`.
162
+
163
+ ### Changed
164
+
165
+ - **Breaking, for third-party cloud providers.** `get_account_details` is replaced by three
166
+ classmethods on `BaseCloudProvider`, because it was doing three things that happen at three
167
+ different times: `detect_account` reaches the account and reads the facts that are not a
168
+ matter of choice, and must not ask anything; `questions` declares what needs choosing, as
169
+ data; and `build_detail` turns both into the record the environment keeps. Only the first and
170
+ last are required - a provider that declares no questions and asks inside `build_detail`
171
+ through `ctx.interact` works exactly as before, and gives up nothing but its coverage in
172
+ `env plan`. There are no known third-party providers; this is acceptable before 1.0.
173
+ - **Breaking, for GCP environments created headlessly.** The zone used to be taken silently as
174
+ the first of the region's zones, which is why `--zone` existed and did nothing. It is a real
175
+ question now: at a terminal the first zone is preselected, so pressing enter gives the old
176
+ answer, and a headless run supplies `--zone` or takes the same first zone with
177
+ `--accept-defaults`. A headless GCP run that did neither now stops with `MISSING_ANSWER`
178
+ naming `env.zone`, which `opsmith env plan` will have told it about beforehand.
179
+ - Splitting the providers up narrows their error handling as a side effect worth having: each
180
+ call to a cloud SDK is guarded on its own rather than a whole flow at once, so a failure is
181
+ reported against the thing that actually failed - reaching the account, or listing the regions
182
+ - instead of everything in the block being reported as broken credentials.
183
+ - **Breaking, for third-party deployment strategies.** The five action methods on
184
+ `BaseDeploymentStrategy` now return a result model from `opsmith.core.results` — `deploy` an
185
+ `EnvCreateResult`, `release` a `ReleaseResult`, `update` an `UpdateResult`, `run` a `RunResult`,
186
+ `destroy` a `DestroyResult` — and a sixth method, `status`, reports what an environment is
187
+ running by reading its own state file without contacting a cloud. A strategy still has to
188
+ declare nothing ahead of time and still asks whatever it needs through `ctx.interact`; what
189
+ changed is that it now describes what it did, because the CLI reports that. It may now also
190
+ implement `questions`, listing what it is going to ask so that `opsmith env plan` can report
191
+ it - which is optional, is never asked on the strategy's behalf, and costs a strategy that
192
+ skips it nothing but a line in the plan saying the list is partial. Those descriptions name no
193
+ topology — infrastructure is a list of `Resource`, not a public IP and an instance type — so a
194
+ strategy that is not one machine can still answer honestly. There are no known third-party
195
+ strategies; this is acceptable before 1.0.
196
+ - There is no blanket `--yes`. The draft CLI contract carried one, meaning "accept every
197
+ destructive confirmation in this run"; it is not in 0.5.0. It was pure sugar - `--answer
198
+ delete.confirm=DELETE` already says the same thing for one gate rather than all of them - and
199
+ a flag that generic cannot be read where it is written: `opsmith --yes destroy --env dev` puts
200
+ the approval nowhere near what it approves, and the word says nothing about which of a run's
201
+ confirmations it covers. Anything irreversible is now answered by name, and `--accept-defaults`
202
+ still refuses those keys, so no blanket option approves an irreversible action.
203
+ - Running `deploy` in a repository that has not been set up now exits 2 with `INVALID_CONFIG` and
204
+ a hint naming `opsmith setup`, rather than exiting 1 with no machine-readable reason.
205
+ - Asking for an environment the configuration does not declare is `UNKNOWN_ENVIRONMENT` and exit
206
+ 2, with the names that do exist in the details. It used to be an unhandled `ValueError`.
207
+ - Importing Opsmith no longer requires `git` on the `PATH`. GitPython looks for the executable
208
+ while it is being imported, so a module-level import made every command fail on a machine
209
+ without git, long before anything asked for a repository. It is imported where a repository is
210
+ opened instead, which is what lets the commands that need no tooling run without any.
211
+ - A missing or unrunnable `git` is now a usage error naming git, exit 2, rather than an unhandled
212
+ crash reported as a bug in Opsmith. It is distinct from "this is not a git repository", because
213
+ the two are fixed differently: one wants git installed, the other wants `git init`.
214
+ - The DNS step waits instead of asking. Opsmith shows the records, then polls until they resolve
215
+ rather than asking whether they were created. Interactively it re-checks when you say so;
216
+ headlessly it polls until `--wait-timeout` and then exits 8 with the records that are still
217
+ missing, and creating them and running the command again resumes at the wait.
218
+ - `--model` and `--api-key` no longer prompt when they are missing. A run with no model
219
+ configured exits 2 and names every way to supply one, so a headless run can never hang on a
220
+ prompt. Option order no longer matters either, and `--help` no longer needs either of them.
221
+ - docker and terraform are checked per command rather than for every command, so commands that
222
+ do not deploy anything run on a machine without them. A missing tool now exits 2 rather than 1.
223
+ - The rules that the `setup` editors enforced — a provider left as `user_choice`, the same
224
+ provider listed twice — are now applied by `config validate` as well, against the same code.
225
+
226
+ ### Fixed
227
+
228
+ - Reporting a problem with an edited service or dependency no longer crashes. The details of a
229
+ notice are spread across the event's own fields, and a `ConfigIssue` carries a `message`, which
230
+ collided with the event's - so the one path that reports an invalid edit raised a `TypeError`
231
+ instead of saying what was wrong. Details named after a field of the event are nested now.
232
+ - Ansible variables no longer travel on the command line. They carry the whole compose `.env`
233
+ body, which was readable by every process on the machine and was repeated in the details of a
234
+ failed playbook. They go in a file only the current user can read, removed when the run ends.
235
+ - Build-time environment variables are no longer written to `state.yml` in the clear. They move
236
+ to the environment's answer store, secrets to its secret half. An existing `state.yml` hands
237
+ its values over on the next release or update, so nothing is asked for again, and the field is
238
+ never written back.
239
+
240
+ ### Removed
241
+
242
+ - The unused `networkx` and `pick` dependencies.
243
+ - `pydantic-ai` in favour of `pydantic-ai-slim[anthropic,google,openai]`, which is what the
244
+ bundled models need. `boto3` and `pydantic-settings`, previously used but undeclared, are now
245
+ declared. A third-party model plugin for a provider outside OpenAI, Anthropic and Google must
246
+ now declare the pydantic-ai extra it needs.