netbox-super-cli 1.0.3__tar.gz → 1.0.4__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 (219) hide show
  1. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/CHANGELOG.md +15 -2
  2. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/PKG-INFO +10 -4
  3. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/README.md +9 -3
  4. netbox_super_cli-1.0.4/docs/architecture/caching.md +72 -0
  5. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/docs/architecture/command-generation.md +4 -4
  6. netbox_super_cli-1.0.4/docs/architecture/http-client.md +66 -0
  7. netbox_super_cli-1.0.4/docs/architecture/overview.md +48 -0
  8. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/docs/architecture/schema-loading.md +13 -10
  9. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/docs/contributing/adding-bundled-schemas.md +11 -6
  10. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/docs/contributing/development.md +1 -1
  11. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/docs/contributing/release-process.md +6 -0
  12. netbox_super_cli-1.0.4/docs/getting-started/first-run.md +88 -0
  13. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/docs/guides/ci-and-automation.md +10 -3
  14. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/docs/guides/managing-profiles.md +27 -2
  15. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/docs/guides/output-formats.md +5 -2
  16. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/docs/guides/using-with-ai-agents.md +18 -7
  17. netbox_super_cli-1.0.4/docs/guides/working-with-plugins.md +54 -0
  18. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/docs/guides/writes-and-safety.md +18 -0
  19. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/_version.py +1 -1
  20. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/aliases/resolver.py +4 -7
  21. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/builder/build.py +26 -53
  22. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/cache/store.py +3 -23
  23. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/cli/app.py +0 -5
  24. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/cli/commands_dump.py +3 -8
  25. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/cli/config_commands.py +2 -3
  26. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/cli/globals.py +1 -11
  27. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/cli/handlers.py +7 -4
  28. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/cli/runtime.py +23 -29
  29. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/cli/writes/apply.py +3 -5
  30. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/cli/writes/bulk.py +3 -3
  31. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/cli/writes/input.py +1 -5
  32. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/cli/writes/preflight.py +0 -1
  33. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/config/loader.py +1 -3
  34. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/config/models.py +3 -3
  35. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/config/settings.py +1 -5
  36. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/config/writer.py +1 -1
  37. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/http/audit.py +1 -1
  38. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/http/client.py +3 -6
  39. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/http/retry.py +1 -1
  40. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/output/errors.py +0 -3
  41. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/schema/loader.py +1 -1
  42. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/schema/models.py +1 -2
  43. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/schema/source.py +4 -13
  44. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/pyproject.toml +1 -1
  45. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/skills/netbox-super-cli/SKILL.md +50 -21
  46. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/uv.lock +4 -4
  47. netbox_super_cli-1.0.3/docs/architecture/caching.md +0 -46
  48. netbox_super_cli-1.0.3/docs/architecture/http-client.md +0 -44
  49. netbox_super_cli-1.0.3/docs/architecture/overview.md +0 -44
  50. netbox_super_cli-1.0.3/docs/getting-started/first-run.md +0 -72
  51. netbox_super_cli-1.0.3/docs/guides/working-with-plugins.md +0 -46
  52. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/.github/workflows/agents-md-sync.yml +0 -0
  53. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/.github/workflows/bench.yml +0 -0
  54. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/.github/workflows/claude.yml +0 -0
  55. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/.github/workflows/docs.yml +0 -0
  56. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/.github/workflows/e2e.yml +0 -0
  57. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/.github/workflows/lint.yml +0 -0
  58. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/.github/workflows/release.yml +0 -0
  59. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/.github/workflows/test.yml +0 -0
  60. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/.gitignore +0 -0
  61. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/.pre-commit-config.yaml +0 -0
  62. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/.python-version +0 -0
  63. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/AGENTS.md +0 -0
  64. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/CLAUDE.md +0 -0
  65. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/LICENSE +0 -0
  66. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/docs/contributing/branching.md +0 -0
  67. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/docs/getting-started/concepts.md +0 -0
  68. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/docs/getting-started/install.md +0 -0
  69. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/docs/index.md +0 -0
  70. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/docs/reference/cli.md +0 -0
  71. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/docs/reference/config.md +0 -0
  72. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/docs/reference/exit-codes.md +0 -0
  73. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/docs/reference/schemas.md +0 -0
  74. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/justfile +0 -0
  75. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/mkdocs.yml +0 -0
  76. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/__init__.py +0 -0
  77. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/__main__.py +0 -0
  78. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/aliases/__init__.py +0 -0
  79. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/auth/__init__.py +0 -0
  80. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/auth/verify.py +0 -0
  81. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/builder/__init__.py +0 -0
  82. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/cache/__init__.py +0 -0
  83. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/cli/__init__.py +0 -0
  84. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/cli/aliases_commands.py +0 -0
  85. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/cli/cache_commands.py +0 -0
  86. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/cli/init_commands.py +0 -0
  87. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/cli/login_commands.py +0 -0
  88. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/cli/profiles_commands.py +0 -0
  89. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/cli/registration.py +0 -0
  90. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/cli/skill_commands.py +0 -0
  91. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/cli/writes/__init__.py +0 -0
  92. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/cli/writes/coercion.py +0 -0
  93. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/cli/writes/confirmation.py +0 -0
  94. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/config/__init__.py +0 -0
  95. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/http/__init__.py +0 -0
  96. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/http/errors.py +0 -0
  97. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/model/__init__.py +0 -0
  98. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/model/command_model.py +0 -0
  99. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/output/__init__.py +0 -0
  100. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/output/csv_.py +0 -0
  101. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/output/explain.py +0 -0
  102. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/output/flatten.py +0 -0
  103. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/output/headers.py +0 -0
  104. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/output/json_.py +0 -0
  105. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/output/jsonl.py +0 -0
  106. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/output/render.py +0 -0
  107. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/output/table.py +0 -0
  108. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/output/yaml_.py +0 -0
  109. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/schema/__init__.py +0 -0
  110. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/schema/hashing.py +0 -0
  111. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/schemas/__init__.py +0 -0
  112. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/schemas/bundled/__init__.py +0 -0
  113. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/schemas/bundled/manifest.yaml +0 -0
  114. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/schemas/bundled/netbox-4.5.10.json.gz +0 -0
  115. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/schemas/bundled/netbox-4.6.0.json.gz +0 -0
  116. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/nsc/skill/__init__.py +0 -0
  117. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/scripts/gen_docs.py +0 -0
  118. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/scripts/sync_agents_md.py +0 -0
  119. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/__init__.py +0 -0
  120. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/aliases/__init__.py +0 -0
  121. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/aliases/test_resolver.py +0 -0
  122. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/auth/__init__.py +0 -0
  123. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/auth/test_verify.py +0 -0
  124. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/benchmarks/__init__.py +0 -0
  125. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/benchmarks/test_startup.py +0 -0
  126. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/builder/__init__.py +0 -0
  127. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/builder/test_build.py +0 -0
  128. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/builder/test_default_columns.py +0 -0
  129. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/builder/test_redaction_marking.py +0 -0
  130. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/builder/test_request_body_shape.py +0 -0
  131. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cache/__init__.py +0 -0
  132. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cache/test_prune.py +0 -0
  133. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cache/test_store.py +0 -0
  134. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/__init__.py +0 -0
  135. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/test_aliases_commands.py +0 -0
  136. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/test_app_smoke.py +0 -0
  137. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/test_cache_commands.py +0 -0
  138. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/test_commands_dump.py +0 -0
  139. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/test_completion_smoke.py +0 -0
  140. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/test_config_commands.py +0 -0
  141. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/test_explain.py +0 -0
  142. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/test_handlers.py +0 -0
  143. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/test_init_commands.py +0 -0
  144. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/test_login_commands.py +0 -0
  145. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/test_meta_subcommands_under_broken_config.py +0 -0
  146. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/test_ndjson_input.py +0 -0
  147. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/test_profiles_commands.py +0 -0
  148. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/test_registration.py +0 -0
  149. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/test_respx_integration.py +0 -0
  150. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/test_runtime.py +0 -0
  151. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/test_skill_commands.py +0 -0
  152. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/test_stdin_sniffer.py +0 -0
  153. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/test_writes_respx.py +0 -0
  154. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/writes/__init__.py +0 -0
  155. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/writes/test_apply.py +0 -0
  156. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/writes/test_bulk.py +0 -0
  157. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/writes/test_confirmation.py +0 -0
  158. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/writes/test_handler_helpers.py +0 -0
  159. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/writes/test_handlers_audit.py +0 -0
  160. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/writes/test_input.py +0 -0
  161. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/cli/writes/test_preflight.py +0 -0
  162. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/config/__init__.py +0 -0
  163. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/config/test_loader.py +0 -0
  164. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/config/test_models.py +0 -0
  165. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/config/test_writer_atomicity.py +0 -0
  166. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/config/test_writer_dotted_paths.py +0 -0
  167. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/config/test_writer_roundtrip.py +0 -0
  168. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/conftest.py +0 -0
  169. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/e2e/README.md +0 -0
  170. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/e2e/__init__.py +0 -0
  171. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/e2e/conftest.py +0 -0
  172. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/e2e/docker-compose.yml +0 -0
  173. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/e2e/test_audit_redaction.py +0 -0
  174. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/e2e/test_auth_error_envelope.py +0 -0
  175. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/e2e/test_bulk_create_with_loop_fallback.py +0 -0
  176. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/e2e/test_full_cycle.py +0 -0
  177. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/e2e/test_login.py +0 -0
  178. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/e2e/test_ndjson.py +0 -0
  179. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/e2e/test_preflight_blocks_apply.py +0 -0
  180. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/e2e/test_validation_error_envelope_from_netbox.py +0 -0
  181. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/e2e/wait_for_netbox.sh +0 -0
  182. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/fixtures/profiles/single_profile.yaml +0 -0
  183. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/fixtures/responses/auth_401.json +0 -0
  184. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/fixtures/responses/circuits_providers_list.json +0 -0
  185. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/fixtures/responses/dcim_devices_get.json +0 -0
  186. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/fixtures/responses/dcim_devices_list_p1.json +0 -0
  187. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/fixtures/responses/dcim_devices_list_p2.json +0 -0
  188. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/http/__init__.py +0 -0
  189. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/http/test_audit.py +0 -0
  190. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/http/test_audit_redaction.py +0 -0
  191. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/http/test_client.py +0 -0
  192. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/http/test_client_redaction_threading.py +0 -0
  193. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/http/test_errors.py +0 -0
  194. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/http/test_retry.py +0 -0
  195. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/model/__init__.py +0 -0
  196. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/model/test_command_model.py +0 -0
  197. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/model/test_request_body_shape.py +0 -0
  198. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/output/__init__.py +0 -0
  199. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/output/test_csv.py +0 -0
  200. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/output/test_errors.py +0 -0
  201. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/output/test_errors_aliases.py +0 -0
  202. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/output/test_explain.py +0 -0
  203. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/output/test_flatten.py +0 -0
  204. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/output/test_input_error_envelope.py +0 -0
  205. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/output/test_json.py +0 -0
  206. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/output/test_jsonl.py +0 -0
  207. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/output/test_render_dispatch.py +0 -0
  208. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/output/test_table.py +0 -0
  209. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/output/test_yaml.py +0 -0
  210. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/schema/__init__.py +0 -0
  211. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/schema/test_hashing.py +0 -0
  212. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/schema/test_loader.py +0 -0
  213. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/schema/test_models.py +0 -0
  214. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/schema/test_source.py +0 -0
  215. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/schema/test_source_ttl.py +0 -0
  216. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/scripts/__init__.py +0 -0
  217. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/scripts/test_gen_docs.py +0 -0
  218. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/skill/__init__.py +0 -0
  219. {netbox_super_cli-1.0.3 → netbox_super_cli-1.0.4}/tests/skill/test_bundle.py +0 -0
@@ -2,14 +2,27 @@
2
2
 
3
3
  All notable changes to netbox-super-cli are tracked here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) loosely. From v1.0.0 onward, releases follow [Semantic Versioning](https://semver.org/) and the version in `pyproject.toml` matches the git tag. Pre-1.0 milestones (Phase 1-5) were pinned by tag while `pyproject.toml` stayed at `0.0.1`.
4
4
 
5
+ ## v1.0.4 — 2026-05-16
6
+
7
+ Maintenance release: a codebase-wide internal simplification pass (no behavioural change), a full documentation parity audit, and a dependency bump. There are no CLI, config, or output-contract changes — upgrading from v1.0.3 is transparent.
8
+
9
+ ### Changed
10
+
11
+ - **Codebase-wide simplification pass** (PRs #61–#71). Every package was audited to remove dead code, tighten types, and drop unreachable branches: schema parsing (#61), cache store & schema source (#62), output (#63), command model / alias resolver / auth verify (#64), config (#65), http (#66), cli (#68), builder (#69), top-level package files (#70), and the cli writes pipeline (#71). These are internal-only changes — the public CLI surface, command tree, error envelope, and exit codes are unchanged and remain covered by the existing test suite.
12
+ - Bumped `urllib3` 2.6.3 → 2.7.0 (PR #46).
13
+
14
+ ### Documentation
15
+
16
+ - **Full documentation parity audit** (PR #73). Every hand-written user-facing and contributor page, plus the bundled `SKILL.md`, was audited file-by-file against the current code and corrected. Notable fixes: removed references to non-existent `nsc describe` / `nsc refresh` commands; documented the real `replace` (PUT) verb; corrected the HTTP retry policy (writes are never retried on 5xx); corrected the schema-cache invalidation model to the TTL fast-path; documented `nsc skill export`, `nsc login --fetch-schema`, and the post-`login --new` schema-fetch prompt; and corrected exit-code semantics (a malformed single JSON/YAML input is a `client`/exit-6 error — only a bad NDJSON line is `input_error`/exit 4). Auto-generated reference pages were verified current.
17
+
5
18
  ## v1.0.3 — 2026-05-07
6
19
 
7
20
  Third patch release. Headline changes: `nsc login --new` now prompts to fetch the live schema (issue #32), the schema TTL fast-path self-heals on hash-confirmed fetches (issue #39), and bundled schemas are updated to 4.5.10 and 4.6.0.
8
21
 
9
22
  ### Added
10
23
 
11
- - **`nsc login --new` prompts to fetch the live schema** (issue #32, PR #44). After a new profile is created, `nsc login` asks whether to fetch the live OpenAPI spec immediately. Answering yes primes the schema cache so the next command skips the bootstrap fetch entirely.
12
- - **`nsc skill export <dir>`** (PR #37). Copies the bundled `SKILL.md` to an arbitrary directory so it can be dropped into any agent harness without `nsc` on the `PATH`. Useful in CI or shared-skill repos where the package is not installed globally.
24
+ - **`nsc login --new` prompts to fetch the live schema** (issue #32, PR #44). After a new profile is created, `nsc login` asks `Fetch and cache the live schema now?` (defaults `Y`) and fetches if accepted. A new `nsc login --fetch-schema` flag fetches unconditionally (no prompt) and also applies to the bare/`--profile` verify path. Either way the schema is fetched with a forced refresh, priming the cache so the next command skips the bootstrap fetch entirely. `--rotate` does not prompt for or fetch the schema.
25
+ - **`nsc skill export <dir>`** (PR #37). Copies the bundled `SKILL.md` into `<dir>/netbox-super-cli/SKILL.md` so it can be dropped into any agent harness without `nsc` on the `PATH`. Dry-run by default (prints the would-write path); `--apply` actually copies. `--output json` emits a structured envelope. Useful in CI or shared-skill repos where the package is not installed globally.
13
26
  - **Bundled schemas updated** (PR #36). Ships 4.5.10 and 4.6.0; drops the 4.6.0-beta2 snapshot. Offline fallback is now available for both stable release lines.
14
27
 
15
28
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: netbox-super-cli
3
- Version: 1.0.3
3
+ Version: 1.0.4
4
4
  Summary: Dynamic NetBox CLI generated from the live OpenAPI schema.
5
5
  Project-URL: Homepage, https://github.com/thomaschristory/netbox-super-cli
6
6
  Project-URL: Issues, https://github.com/thomaschristory/netbox-super-cli/issues
@@ -171,11 +171,17 @@ JSON output, error envelope, audit log).
171
171
  ```sh
172
172
  nsc skill install --target claude-code # dry-run; prints the destination
173
173
  nsc skill install --target claude-code --apply # actually copies
174
+
175
+ # Or export to an arbitrary directory (e.g. CI or a shared-skill repo).
176
+ nsc skill export ./skills # dry-run; prints the would-write path
177
+ nsc skill export ./skills --apply # writes ./skills/netbox-super-cli/SKILL.md
174
178
  ```
175
179
 
176
- Targets: `claude-code`, `codex`, `gemini`, `copilot`. Where a target has no
177
- documented programmatic install path, the helper prints actionable manual
178
- instructions instead of guessing.
180
+ `skill install` targets: `claude-code`, `codex`, `gemini`, `copilot`. Where a
181
+ target has no documented programmatic install path, the helper prints actionable
182
+ manual instructions instead of guessing. `skill export <dir>` always writes to
183
+ `<dir>/netbox-super-cli/SKILL.md` and, like `install`, is dry-run unless you
184
+ pass `--apply`.
179
185
 
180
186
  ## License
181
187
 
@@ -144,11 +144,17 @@ JSON output, error envelope, audit log).
144
144
  ```sh
145
145
  nsc skill install --target claude-code # dry-run; prints the destination
146
146
  nsc skill install --target claude-code --apply # actually copies
147
+
148
+ # Or export to an arbitrary directory (e.g. CI or a shared-skill repo).
149
+ nsc skill export ./skills # dry-run; prints the would-write path
150
+ nsc skill export ./skills --apply # writes ./skills/netbox-super-cli/SKILL.md
147
151
  ```
148
152
 
149
- Targets: `claude-code`, `codex`, `gemini`, `copilot`. Where a target has no
150
- documented programmatic install path, the helper prints actionable manual
151
- instructions instead of guessing.
153
+ `skill install` targets: `claude-code`, `codex`, `gemini`, `copilot`. Where a
154
+ target has no documented programmatic install path, the helper prints actionable
155
+ manual instructions instead of guessing. `skill export <dir>` always writes to
156
+ `<dir>/netbox-super-cli/SKILL.md` and, like `install`, is dry-run unless you
157
+ pass `--apply`.
152
158
 
153
159
  ## License
154
160
 
@@ -0,0 +1,72 @@
1
+ # Caching
2
+
3
+ `~/.nsc/` holds all on-disk state. Bundled schemas live inside the installed
4
+ wheel and are NOT copied into `~/.nsc/`.
5
+
6
+ ## Layout
7
+
8
+ ```
9
+ ~/.nsc/
10
+ ├── config.yaml
11
+ ├── cache/
12
+ │ ├── prod/<schema-hash>.json # generated CommandModel
13
+ │ ├── prod/<schema-hash>.meta.json # sidecar: {"fetched_at": <epoch>}
14
+ │ ├── lab/<schema-hash>.json
15
+ │ └── adhoc/<schema-hash>.json # env-var-only invocations
16
+ └── logs/
17
+ ├── last-request.json # most recent HTTP exchange (overwritten)
18
+ └── audit.jsonl # append-only mutation log
19
+ # (rotated to audit.jsonl.1 at 10 MB)
20
+ ```
21
+
22
+ The location root is `~/.nsc/` unless `NSC_HOME` is set, in which case it is
23
+ `$NSC_HOME` (expanded and resolved).
24
+
25
+ ## Invalidation
26
+
27
+ The cache is keyed by `sha256` of the canonicalized schema body. There are two
28
+ distinct caches: this **command-model disk cache** (`<hash>.json`), and the
29
+ **schema-source TTL fast-path** that decides whether to re-fetch the live
30
+ schema at all.
31
+
32
+ Invalidation is **TTL-gated**, not "every invocation". Under the default
33
+ `daily` policy (`Defaults.schema_refresh = SchemaRefresh.DAILY`) `nsc` trusts
34
+ the cached command-model — and skips the schema fetch entirely — as long as the
35
+ profile's newest `<hash>.meta.json` sidecar `fetched_at` is within the policy's
36
+ TTL. Only once the TTL has lapsed (or the policy forces it) does `nsc` re-fetch
37
+ the live schema; a changed schema then produces a new hash and a new
38
+ `<hash>.json`. Freshness is keyed off the sidecar's `fetched_at`, **not** the
39
+ cache file's mtime, so a `touch`, backup-restore, or `cp -p` cannot fake
40
+ freshness. A sidecar dated more than 60s in the future (clock skew or
41
+ tampering) is rejected.
42
+
43
+ When a live fetch returns a hash that is already cached, the sidecar's
44
+ `fetched_at` is bumped (`CacheStore.touch_fetched_at`) so the TTL fast-path
45
+ trusts the cache on the next invocation — this also self-heals legacy caches
46
+ written before sidecars existed.
47
+
48
+ Force a re-fetch sooner with the global `--refresh-schema` flag (bypasses the
49
+ TTL fast-path under any policy) or `nsc login --fetch-schema`. The full policy
50
+ table lives in [Schema loading](schema-loading.md#refresh-modes).
51
+
52
+ ## Cleaning up
53
+
54
+ `nsc cache prune` handles three classes of orphan:
55
+
56
+ 1. Profile directories not in `~/.nsc/config.yaml` (e.g., a removed profile).
57
+ 2. `<schema_hash>.json` files inside an active profile whose hash no longer
58
+ matches the live schema. **Skipped per-profile when the profile is
59
+ offline** so a network blip never removes the offline fallback.
60
+ 3. With `--max-age <days>`: cache files older than the threshold (excludes
61
+ files already covered by rule 1).
62
+
63
+ The `adhoc` cache is **never pruned automatically** — it represents valid
64
+ env-var-only usage. Applying a prune also removes each deleted file's
65
+ `<hash>.meta.json` sidecar.
66
+
67
+ ```sh
68
+ nsc cache prune # dry-run
69
+ nsc cache prune --apply # actually delete
70
+ nsc cache prune --max-age 30 --apply
71
+ nsc cache prune --output json # structured envelope
72
+ ```
@@ -5,13 +5,13 @@
5
5
  ## The shape
6
6
 
7
7
  ```python
8
- CommandModel
8
+ CommandModel(info_title, info_version, schema_hash, tags: dict[str, Tag])
9
9
  ├── tags: dict[str, Tag]
10
- │ └── Tag(name, resources: dict[str, Resource])
10
+ │ └── Tag(name, description?, resources: dict[str, Resource])
11
11
  │ └── Resource(name, list_op?, get_op?, create_op?, update_op?, replace_op?,
12
12
  │ delete_op?, custom_actions: list[Operation])
13
- └── Operation(operation_id, http_method, path, parameters, request_body?,
14
- response_schema?, summary?)
13
+ └── Operation(operation_id, http_method, path, summary?, description?,
14
+ parameters, request_body?, default_columns?)
15
15
  ```
16
16
 
17
17
  Pure Pydantic. JSON-serializable. Cached to disk.
@@ -0,0 +1,66 @@
1
+ # HTTP client
2
+
3
+ `nsc/http/` is a thin wrapper around `httpx.Client`.
4
+
5
+ ## What it adds
6
+
7
+ - Token auth: `Authorization: Token <token>` header (plus
8
+ `Accept: application/json`), set once per Client.
9
+ - Configurable `verify_ssl` and `timeout` (default 30s, from
10
+ `Defaults.timeout`).
11
+ - Method-aware retries, up to 3 attempts with exponential backoff
12
+ (`base_delay` 0.5s, ±25% jitter):
13
+ - **Reads** (GET/HEAD/OPTIONS) retry on 5xx **and** on connect
14
+ failures.
15
+ - **Writes** (POST/PATCH/PUT/DELETE) retry **only** on a provable
16
+ connect failure (request never left the client). They are
17
+ **never** retried on 5xx, read-timeout, or ambiguous transport
18
+ errors — a write that may have reached the server is not replayed.
19
+ Every attempt is recorded as its own audit entry with `attempt_n` and
20
+ `final_attempt`; redaction is applied on every write, so a failed
21
+ retry never unredacts.
22
+ - Pagination helper that follows `next` URLs (used by `--all`).
23
+ - Audit log appender at `~/.nsc/logs/audit.jsonl` — written for writes
24
+ always, and for any request when `--debug` is set.
25
+ - A "last request" snapshot at `~/.nsc/logs/last-request.json`
26
+ (overwritten every call, regardless of `--debug`) — handy for triage.
27
+
28
+ ## Auth and the bootstrap path
29
+
30
+ A schema fetch may run before the first command request (only when the
31
+ TTL fast-path misses — see [Caching](caching.md)); it uses its own
32
+ short-lived `httpx.Client` in `nsc/schema/`, not this `NetBoxClient`.
33
+ Command requests then go through a single `NetBoxClient` whose
34
+ `httpx.Client` carries the auth header for the life of the process.
35
+ Token rotation via `nsc login --rotate` does NOT invalidate the cached
36
+ model (the schema hash is what keys the cache; the token never affected
37
+ it).
38
+
39
+ ## Audit entry shape
40
+
41
+ Each line of `audit.jsonl` is a JSON object with:
42
+
43
+ - `schema_version`, `timestamp` (UTC ISO8601, `…Z`)
44
+ - `operation_id`, `method`, `url`
45
+ - `request.headers` (sensitive headers, incl. `Authorization`, rewritten
46
+ to `"<redacted>"` — the key stays, the value is masked)
47
+ - `request.query`, `request.body` (sensitive `sensitive_paths` fields
48
+ rewritten to `"<redacted>"`); bodies over 256 KB collapse to
49
+ `{"_truncated": true, "_size_bytes": N}` with `request.body_truncated`
50
+ - `response.status_code`, `response.headers`, `response.body` (same
51
+ 256 KB truncation via `response.body_truncated`); `response` is `null`
52
+ on a transport failure
53
+ - `duration_ms`, `attempt_n`, `final_attempt`, `error_kind`
54
+ - `dry_run`, `preflight_blocked`, `record_indices`, `applied`, `explain`
55
+
56
+ The audit file is append-only and rotates to `audit.jsonl.1` at 10 MB;
57
+ failed writes do NOT unredact. See
58
+ [Writes and safety](../guides/writes-and-safety.md) for the full redaction
59
+ contract.
60
+
61
+ ## What it deliberately does not do
62
+
63
+ - Async — sync only in v1, kept feasible by httpx if a future async path lands.
64
+ - Connection pooling across profiles — each profile gets its own `Client`.
65
+ - Caching responses — caching the command-model is enough; caching response
66
+ payloads would surprise users.
@@ -0,0 +1,48 @@
1
+ # Architecture overview
2
+
3
+ `nsc` is layered around a framework-free "brain". The brain — schema parsing
4
+ and the normalized command-model — knows nothing about Typer, Rich, or httpx.
5
+ The CLI layer consumes the brain; a future TUI could too without changing the
6
+ brain.
7
+
8
+ ```
9
+ nsc/
10
+ ├── schema/ # OpenAPI fetching, hashing, parsing
11
+ ├── model/ # Normalized command-model (data only, framework-free)
12
+ ├── builder/ # Schema → CommandModel
13
+ ├── cli/ # Typer application; walks the model, registers commands
14
+ ├── http/ # Thin httpx wrapper: auth, retries, audit
15
+ ├── output/ # Formatters (table/json/jsonl/yaml/csv) + error envelope
16
+ ├── config/ # Pydantic config models + ruamel.yaml writer
17
+ ├── cache/ # On-disk cache for generated CommandModels
18
+ ├── auth/ # Login verification helpers (verify probe, token rotate)
19
+ ├── aliases/ # Curated alias resolver (ls/get/rm/search)
20
+ ├── skill/ # Bundle-path helper for the portable SKILL.md
21
+ └── schemas/bundled/ # Versioned NetBox OpenAPI snapshots (offline fallback)
22
+ ```
23
+
24
+ ## The hard rule
25
+
26
+ `nsc/model/` imports nothing from `nsc/cli/`, `nsc/http/`, or any framework.
27
+ If you need to add a dependency to `model/`, you're solving the wrong problem.
28
+
29
+ ## Data flow at runtime
30
+
31
+ 1. `nsc` startup → resolve profile (CLI flags > env > config > adhoc).
32
+ 2. Resolve schema source (`--schema` override > fresh cache within the
33
+ TTL policy > live fetch > stale cache > bundled fallback).
34
+ 3. Hash + parse → build the command-model (or load cached).
35
+ 4. Hand model to Typer; register commands dynamically.
36
+ 5. Dispatch.
37
+ 6. `http/` executes (or shows dry-run).
38
+ 7. `output/` renders.
39
+
40
+ ## Where to read next
41
+
42
+ - [Schema loading](schema-loading.md) — fetch, hash, fallback chain.
43
+ - [Command generation](command-generation.md) — how `operationId` becomes a verb.
44
+ - [HTTP client](http-client.md) — auth, retries, audit log.
45
+ - [Caching](caching.md) — disk layout, invalidation.
46
+
47
+ For the full design rationale, see the specs in `docs/superpowers/specs/` (in
48
+ the repo, not in this site — the planning artifacts are local-only).
@@ -18,10 +18,13 @@ and an optional `--refresh-schema` override:
18
18
  `{profile.url}/api/schema/?format=json`. The fetched body is hashed;
19
19
  if a cache file already exists at that hash it's loaded directly,
20
20
  otherwise the command-model is rebuilt and saved.
21
- 4. On fetch failure: any cached entry for the profile (warns once on
22
- stderr).
23
- 5. Bundled snapshot at `nsc/schemas/bundled/netbox-<closest-version>.json`
24
- (shipped in the wheel) — last-resort offline fallback.
21
+ 4. On fetch failure: the newest valid cached entry for the profile
22
+ (warns once on stderr), sorted by mtime.
23
+ 5. Bundled snapshot the **last (newest) entry** in
24
+ `nsc/schemas/bundled/manifest.yaml` (currently
25
+ `netbox-4.6.0.json.gz`), shipped in the wheel. This is the
26
+ last-resort offline fallback; it is *not* version-matched to the
27
+ unreachable instance.
25
28
 
26
29
  ## Hashing
27
30
 
@@ -49,12 +52,12 @@ that's the upgrade path for caches written before sidecars existed.
49
52
 
50
53
  ## Offline behavior
51
54
 
52
- - Live schema unreachable + cache present → use cache, warn once on
53
- stderr.
54
- - Live schema unreachable + no cache → fall back to the closest bundled
55
- version, warn loudly.
56
- - All such errors include a remediation hint pointing at
57
- `--refresh-schema` for once the instance is reachable again.
55
+ - Live schema unreachable + cache present → use the newest valid cached
56
+ entry, warn once on stderr.
57
+ - Live schema unreachable + no cache → fall back to the newest bundled
58
+ snapshot (last manifest entry), warn once on stderr.
59
+ - Neither cache nor bundled snapshot available `SchemaSourceError`
60
+ (exit 3).
58
61
 
59
62
  ## Refresh modes
60
63
 
@@ -9,14 +9,16 @@ the repo and shipped inside the wheel.
9
9
  ```
10
10
  nsc/schemas/bundled/
11
11
  ├── manifest.yaml
12
- ├── netbox-4.6.0.json.gz
13
- └── netbox-<other-version>.json.gz
12
+ ├── netbox-4.5.10.json.gz
13
+ └── netbox-4.6.0.json.gz
14
14
  ```
15
15
 
16
- `manifest.yaml`:
16
+ `manifest.yaml` (newest entry last):
17
17
 
18
18
  ```yaml
19
19
  schemas:
20
+ - version: "4.5.10"
21
+ file: "netbox-4.5.10.json.gz"
20
22
  - version: "4.6.0"
21
23
  file: "netbox-4.6.0.json.gz"
22
24
  ```
@@ -56,6 +58,9 @@ versions when they're no longer cited by any active deployment.
56
58
 
57
59
  1. **First-run offline.** A new install with no cache, no network — the user
58
60
  gets a usable command tree from the bundled schema.
59
- 2. **CI without a NetBox container.** `nsc commands --schema bundled-default
60
- --output json` produces a deterministic command-model for tests that
61
- don't need a live NetBox.
61
+ 2. **CI without a NetBox container.** Pointing `--schema` at a bundled
62
+ snapshot path (e.g. `nsc commands --schema
63
+ nsc/schemas/bundled/netbox-4.6.0.json.gz --output json`) produces a
64
+ deterministic command-model for tests that don't need a live NetBox.
65
+ `--schema` accepts an `http(s)://` URL or a local path; `.json.gz`
66
+ files are gunzipped automatically — there is no `bundled` keyword.
@@ -22,7 +22,7 @@ just lint # ruff + ruff format --check + mypy --strict
22
22
  just fix # auto-fix ruff issues
23
23
  just bench # cold-start benchmark (target <300ms median)
24
24
  just nsc <args> # run the local CLI (e.g., just nsc dcim devices list)
25
- just docs # serve the docs site at http://localhost:8000
25
+ just docs # serve the docs site at http://127.0.0.1:8000
26
26
  just docs-build # build the site, fail on broken links / missing nav
27
27
  ```
28
28
 
@@ -10,6 +10,12 @@ process assumes. Release prep (CHANGELOG roll + version bumps) happens
10
10
  on a `chore/release-X.Y.Z` feature branch, gets PR-merged into `main`,
11
11
  and only then is `vX.Y.Z` tagged on the resulting merge commit.
12
12
 
13
+ The same `v*` tag push also publishes the documentation site.
14
+ `docs.yml` runs build-only (`mkdocs build --strict`) on docs-touching
15
+ pull requests, but the GitHub Pages **deploy** job only runs on a `v*`
16
+ tag push — the live docs site updates on release, not on merge to
17
+ `main`.
18
+
13
19
  ## Normal release checklist
14
20
 
15
21
  1. Full unit suite green: `just test`.
@@ -0,0 +1,88 @@
1
+ # First run
2
+
3
+ Two paths to your first command:
4
+
5
+ 1. **Interactive wizard** — `nsc init` prompts for everything.
6
+ 2. **Env vars** — `NSC_URL` + `NSC_TOKEN` and you're done; no config file needed.
7
+
8
+ ## Interactive: `nsc init`
9
+
10
+ ```sh
11
+ nsc init
12
+ ```
13
+
14
+ The wizard prompts, in order, for:
15
+
16
+ - A **profile name** (default `default`; e.g., `prod`, `lab`).
17
+ - The NetBox URL.
18
+ - **Verify SSL certificates?** (default yes).
19
+ - **Token storage** — `plaintext` or `env` (default `plaintext`).
20
+ - Then either an **environment variable name** (if you chose `env` storage — written as
21
+ an `!env NAME` indirection) or the **token** itself (hidden input, stored verbatim in
22
+ `~/.nsc/config.yaml`). See [Managing profiles](../guides/managing-profiles.md).
23
+
24
+ `nsc init` is offline-safe: it does not contact NetBox. On success it writes
25
+ `~/.nsc/config.yaml` with the profile, prints the path, and suggests
26
+ `nsc login --profile <name>` as the next step. It does **not** fetch the
27
+ schema — run `nsc login` afterwards to verify the token and prime the schema
28
+ cache (see below).
29
+
30
+ `nsc init` refuses to overwrite an existing config — use
31
+ `nsc login --new --profile <name> --url <url>` to add more profiles.
32
+
33
+ ## Env-var only
34
+
35
+ For one-off use, agents, or CI:
36
+
37
+ ```sh
38
+ export NSC_URL=https://netbox.example.com
39
+ export NSC_TOKEN=$(cat ~/.netbox-token)
40
+
41
+ nsc dcim devices list
42
+ ```
43
+
44
+ No `~/.nsc/config.yaml` required. The cache lives at `~/.nsc/cache/adhoc/`
45
+ when there's no profile.
46
+
47
+ ## Authenticate / verify a profile
48
+
49
+ ```sh
50
+ nsc login # verify the default profile
51
+ nsc login --profile lab # verify a specific profile
52
+ nsc login --new --profile staging --url https://netbox-staging.example.com
53
+ nsc login --rotate --profile prod # rotate the token
54
+ nsc login --fetch-schema # verify, then fetch & cache the live schema
55
+ ```
56
+
57
+ `nsc login` probes `GET /api/status/` and `GET /api/users/tokens/?limit=1`
58
+ (both must succeed) and prints `✓ authenticated as <user>, NetBox <version>`
59
+ on success. On failure it emits the standard auth error envelope
60
+ (`type: auth`, exit 8).
61
+
62
+ `--new` requires both `--profile` and `--url`, prompts for the token
63
+ (hidden input), verifies it before writing, and persists the profile. After a
64
+ successful `--new` it also asks **"Fetch and cache the live schema now?"**
65
+ (default **yes**) — accepting primes the schema cache so your first real
66
+ command skips the bootstrap fetch. Pass `--fetch-schema` to any `nsc login`
67
+ (or `--new`) to fetch the schema unconditionally without the prompt;
68
+ `--rotate` neither prompts for nor fetches the schema.
69
+
70
+ ## Your first read
71
+
72
+ ```sh
73
+ nsc dcim devices list # default page (page_size=50)
74
+ nsc dcim devices list --all # paginate to completion
75
+ nsc dcim devices get 7 # get by id
76
+ nsc ls devices # alias — matches devices.list
77
+ nsc dcim devices list --output json --all # canonical machine-readable form
78
+ ```
79
+
80
+ ## Your first write
81
+
82
+ ```sh
83
+ nsc dcim devices create --field name=test-1 --field site=2 --explain # dry-run + reasoning
84
+ nsc dcim devices create --field name=test-1 --field site=2 --apply # commit
85
+ nsc rm devices test-1 --apply # delete via alias
86
+ ```
87
+
88
+ Every write previews as a dry-run unless you pass `--apply`. See [Writes and safety](../guides/writes-and-safety.md) for the full discipline.
@@ -89,10 +89,17 @@ just means one extra fetch on the next run — never a wrong command tree.
89
89
 
90
90
  ```sh
91
91
  # Verify connectivity + auth before doing anything mutating.
92
- nsc login --output json || { echo "auth failed"; exit 1; }
92
+ nsc login || { echo "auth failed"; exit 1; }
93
93
  ```
94
94
 
95
+ `nsc login` verifies the active profile's token (exit **8** on auth failure,
96
+ **12** on a config/profile problem). It takes no `--output` flag; on failure it
97
+ prints the standard JSON error envelope.
98
+
95
99
  ## Cleaning up the cache
96
100
 
97
- `nsc cache prune` removes orphan profile dirs and stale-hash files (with `--apply`).
98
- Safe to run unattended; never deletes the `adhoc` cache.
101
+ `nsc cache prune` removes orphan profile dirs and stale-hash files (it is
102
+ dry-run unless you pass `--apply`). The default prune never touches the
103
+ `adhoc` cache. Add `--max-age N` to also prune cache files older than N days
104
+ by mtime — note that age-based pruning is profile-agnostic and *will* remove
105
+ aged `adhoc` files too. Safe to run unattended (dry-run by default).
@@ -16,8 +16,8 @@ nsc profiles add lab --url https://netbox-lab.local --token "$LAB_TOKEN"
16
16
  ```
17
17
 
18
18
  This is the scriptable equivalent of `nsc login --new --profile lab`. It runs
19
- the same verification (`GET /api/users/tokens/?limit=1`) before persisting.
20
- Refuses if `lab` already exists.
19
+ the same verification (`GET /api/status/` plus `GET /api/users/tokens/?limit=1`)
20
+ before persisting. Refuses if `lab` already exists.
21
21
 
22
22
  ## Add a profile interactively
23
23
 
@@ -26,6 +26,31 @@ nsc init # first ti
26
26
  nsc login --new --profile staging --url https://netbox-staging.local # subsequent profiles
27
27
  ```
28
28
 
29
+ `nsc login --new` requires both `--profile` and `--url`, then prompts for the
30
+ token (hidden input) and runs verification before persisting. Add `--store env
31
+ --env-var NAME` to store the token as an `!env NAME` reference instead of
32
+ plaintext. Refuses (exit 12) if the profile already exists.
33
+
34
+ After a successful `--new`, `nsc` interactively asks **"Fetch and cache the
35
+ live schema now?"** (default **yes**) — accept it to pre-warm the command-model
36
+ cache, or pass `--fetch-schema` to fetch unconditionally without the prompt.
37
+
38
+ ## Verify, rotate, and fetch the schema
39
+
40
+ ```sh
41
+ nsc login # verify the default profile's token
42
+ nsc login --profile lab # verify a specific profile
43
+ nsc login --profile lab --fetch-schema # verify, then refresh the cached schema
44
+ nsc login --rotate --profile lab # prompt for a new token, verify, then persist
45
+ ```
46
+
47
+ `nsc login` (bare or with `--profile`) verifies the token by probing
48
+ `GET /api/status/` and `GET /api/users/tokens/?limit=1`; it writes no config.
49
+ `--fetch-schema` additionally force-refreshes the cached OpenAPI schema.
50
+ `--rotate` requires `--profile`, prompts for the new token, verifies it
51
+ *before* writing, and does **not** prompt for or fetch the schema. `--new` and
52
+ `--rotate` are mutually exclusive.
53
+
29
54
  ## Rename / set default / remove
30
55
 
31
56
  ```sh
@@ -1,7 +1,10 @@
1
1
  # Output formats
2
2
 
3
- `nsc` ships five output formats. Default is **table** on a TTY and **JSON** when
4
- stdout is piped.
3
+ `nsc` ships five output formats: `table`, `json`, `jsonl`, `yaml`, `csv`.
4
+ Default is **table** on a TTY and **JSON** when stdout is piped — the piped
5
+ default is JSON even if your config sets a different `defaults.output`.
6
+ Selection precedence (highest first): `--output`/`-o` > `NSC_OUTPUT` env var >
7
+ non-TTY → JSON > `defaults.output` in config (default `table`).
5
8
 
6
9
  ## The five formats
7
10
 
@@ -9,7 +9,7 @@ correctly without trial-and-error.
9
9
  | Feature | Mechanism |
10
10
  |---|---|
11
11
  | Predictable command shape | `nsc <tag> <resource> <verb>` — derived from the OpenAPI schema, no hand-curation |
12
- | Self-describing | `nsc commands --output json` dumps the full command-model; `nsc describe <tag> <resource>` dumps a resource's fields/filters/operations |
12
+ | Self-describing | `nsc commands --schema <path-or-url> --output json` dumps the full command-model (tags resources operations) |
13
13
  | Stable machine output | `--output json` everywhere; data on stdout, errors as JSON on stderr (or stdout when `--output json`), non-zero exit on failure |
14
14
  | Stable error envelope | `{error, type, endpoint, method, status_code, operation_id, details}` — locked schema, see [Exit codes](../reference/exit-codes.md) |
15
15
  | Safe by default | Writes preview as dry-runs; `--apply` is the only path to mutation |
@@ -18,15 +18,26 @@ correctly without trial-and-error.
18
18
  ## Bundled portable Skill
19
19
 
20
20
  `nsc` ships a portable Skill bundle at `skills/netbox-super-cli/SKILL.md`
21
- (installed inside the wheel). Install it into your agent harness with:
21
+ (installed inside the wheel). Install it into a known agent harness with:
22
22
 
23
23
  ```sh
24
24
  nsc skill install --target claude-code # dry-run; prints the destination
25
25
  nsc skill install --target claude-code --apply # actually copies
26
26
  ```
27
27
 
28
+ Or export the bundled `SKILL.md` to an arbitrary directory:
29
+
30
+ ```sh
31
+ nsc skill export ./my-skills # dry-run; prints the would-write path
32
+ nsc skill export ./my-skills --apply # actually copies
33
+ ```
34
+
35
+ `nsc skill export <dir>` always writes to `<dir>/netbox-super-cli/SKILL.md` —
36
+ the `netbox-super-cli/` subdirectory is inserted for you. Both `skill install`
37
+ and `skill export` are **dry-run unless `--apply`** is passed.
38
+
28
39
  Use `--output json` for programmatic consumers; the dry-run envelope contains
29
- the resolved `destination` path.
40
+ the resolved destination path.
30
41
 
31
42
  ### Per-target resolved paths
32
43
 
@@ -54,9 +65,9 @@ When briefing an agent to use `nsc`, include:
54
65
  read command.
55
66
  2. **The output format.** "Use `--output json` for everything. Errors are JSON
56
67
  envelopes — read `.type` for the category, the exit code for control flow."
57
- 3. **Discovery commands.** "Run `nsc commands --output json` to see the whole
58
- surface. Run `nsc describe <tag> <resource>` for a specific resource's
59
- fields." This prevents the agent from guessing endpoints.
68
+ 3. **Discovery commands.** "Run `nsc commands --schema <path-or-url> --output
69
+ json` to see the whole surface (tags resources → operations)." This
70
+ prevents the agent from guessing endpoints.
60
71
  4. **The audit log.** "If a command fails unexpectedly, check
61
72
  `~/.nsc/logs/audit.jsonl` — it has the exact request and response." This
62
73
  replaces guesswork with evidence.
@@ -66,6 +77,6 @@ When briefing an agent to use `nsc`, include:
66
77
  - **Asking the agent to skip dry-run.** Just don't. The dry-run is the agent's
67
78
  one chance to surface an objection.
68
79
  - **Hand-curated endpoint lists in the prompt.** They go stale on every NetBox
69
- upgrade. Use `nsc commands --output json` instead.
80
+ upgrade. Use `nsc commands --schema <path-or-url> --output json` instead.
70
81
  - **Authenticating per-command.** Configure a profile (or env vars) once at
71
82
  session start.