netbox-super-cli 1.2.0__tar.gz → 1.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (311) hide show
  1. netbox_super_cli-1.3.0/.github/dependabot.yml +16 -0
  2. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/.github/workflows/bench.yml +5 -2
  3. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/.github/workflows/claude.yml +13 -1
  4. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/.github/workflows/docs.yml +3 -3
  5. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/.github/workflows/e2e.yml +16 -2
  6. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/.github/workflows/lint.yml +9 -6
  7. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/.github/workflows/release.yml +3 -3
  8. netbox_super_cli-1.3.0/.github/workflows/skill-convention-review.yml +48 -0
  9. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/.github/workflows/test.yml +5 -2
  10. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/.pre-commit-config.yaml +1 -0
  11. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/AGENTS.md +1 -0
  12. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/CHANGELOG.md +88 -0
  13. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/CLAUDE.md +1 -0
  14. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/PKG-INFO +35 -3
  15. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/README.md +34 -2
  16. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/architecture/caching.md +9 -0
  17. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/architecture/http-client.md +29 -1
  18. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/architecture/overview.md +1 -0
  19. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/contributing/development.md +17 -0
  20. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/getting-started/concepts.md +6 -0
  21. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/getting-started/first-run.md +1 -0
  22. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/getting-started/install.md +10 -2
  23. netbox_super_cli-1.3.0/docs/guides/audit-log.md +71 -0
  24. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/guides/ci-and-automation.md +16 -0
  25. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/guides/managing-profiles.md +6 -0
  26. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/guides/using-with-ai-agents.md +9 -10
  27. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/guides/working-with-plugins.md +10 -0
  28. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/guides/writes-and-safety.md +18 -0
  29. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/index.md +8 -1
  30. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/reference/config.md +2 -1
  31. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/justfile +2 -1
  32. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/mkdocs.yml +1 -0
  33. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/_version.py +1 -1
  34. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/aliases/__init__.py +4 -0
  35. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/aliases/resolver.py +50 -11
  36. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/cli/aliases_commands.py +45 -6
  37. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/cli/app.py +86 -15
  38. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/cli/globals.py +6 -1
  39. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/cli/handlers.py +5 -0
  40. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/cli/registration.py +41 -6
  41. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/cli/runtime.py +1 -0
  42. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/cli/skill_commands.py +11 -14
  43. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/cli/writes/bulk.py +112 -4
  44. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/cli/writes/confirmation.py +24 -0
  45. netbox_super_cli-1.3.0/nsc/completion/__init__.py +11 -0
  46. netbox_super_cli-1.3.0/nsc/completion/cache_probe.py +72 -0
  47. netbox_super_cli-1.3.0/nsc/completion/callbacks.py +119 -0
  48. netbox_super_cli-1.3.0/nsc/completion/providers.py +66 -0
  49. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/config/models.py +9 -0
  50. netbox_super_cli-1.3.0/nsc/config/settings.py +64 -0
  51. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/config/writer.py +4 -2
  52. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/http/audit.py +80 -34
  53. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/http/client.py +13 -1
  54. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/output/errors.py +20 -3
  55. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/bulk.py +4 -1
  56. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/fk.py +21 -0
  57. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/forms.py +22 -4
  58. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/screens/bulk_edit_form.py +82 -5
  59. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/screens/detail.py +14 -6
  60. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/screens/edit_form.py +29 -7
  61. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/pyproject.toml +1 -1
  62. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/skills/netbox-super-cli/SKILL.md +27 -3
  63. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/aliases/test_resolver.py +81 -3
  64. netbox_super_cli-1.3.0/tests/audit/test_redaction_full.py +204 -0
  65. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/test_aliases_commands.py +25 -0
  66. netbox_super_cli-1.3.0/tests/cli/test_completion_protocol_smoke.py +196 -0
  67. netbox_super_cli-1.3.0/tests/cli/test_dynamic_completion.py +247 -0
  68. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/test_skill_commands.py +30 -8
  69. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/test_writes_respx.py +196 -0
  70. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/writes/test_bulk.py +135 -0
  71. netbox_super_cli-1.3.0/tests/config/test_settings_private_dir.py +52 -0
  72. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/config/test_writer_atomicity.py +7 -0
  73. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/e2e/README.md +9 -1
  74. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/e2e/docker-compose.yml +5 -2
  75. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/e2e/wait_for_netbox.sh +1 -1
  76. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/http/test_audit.py +23 -0
  77. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/http/test_audit_permissions.py +7 -0
  78. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/output/test_errors.py +30 -0
  79. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/output/test_errors_aliases.py +14 -0
  80. netbox_super_cli-1.3.0/tests/tui/__init__.py +0 -0
  81. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_bulk_diff.py +9 -1
  82. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_bulk_edit_form.py +232 -1
  83. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_detail_screen.py +91 -1
  84. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_diff.py +3 -2
  85. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_edit_form.py +53 -0
  86. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_fk_resolve.py +14 -0
  87. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_forms.py +43 -1
  88. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/uv.lock +1 -1
  89. netbox_super_cli-1.2.0/nsc/config/settings.py +0 -32
  90. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/.gitignore +0 -0
  91. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/.python-version +0 -0
  92. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/LICENSE +0 -0
  93. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/architecture/command-generation.md +0 -0
  94. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/architecture/schema-loading.md +0 -0
  95. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/assets/tui/detail.svg +0 -0
  96. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/assets/tui/filter.svg +0 -0
  97. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/assets/tui/list.svg +0 -0
  98. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/assets/tui/picker.svg +0 -0
  99. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/assets/tui/search.svg +0 -0
  100. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/contributing/adding-bundled-schemas.md +0 -0
  101. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/contributing/branching.md +0 -0
  102. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/contributing/release-process.md +0 -0
  103. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/guides/interactive-tui.md +0 -0
  104. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/guides/output-formats.md +0 -0
  105. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/reference/cli.md +0 -0
  106. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/reference/exit-codes.md +0 -0
  107. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/docs/reference/schemas.md +0 -0
  108. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/__init__.py +0 -0
  109. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/__main__.py +0 -0
  110. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/auth/__init__.py +0 -0
  111. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/auth/verify.py +0 -0
  112. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/builder/__init__.py +0 -0
  113. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/builder/build.py +0 -0
  114. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/cache/__init__.py +0 -0
  115. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/cache/store.py +0 -0
  116. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/cli/__init__.py +0 -0
  117. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/cli/cache_commands.py +0 -0
  118. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/cli/commands_dump.py +0 -0
  119. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/cli/config_commands.py +0 -0
  120. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/cli/init_commands.py +0 -0
  121. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/cli/login_commands.py +0 -0
  122. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/cli/profiles_commands.py +0 -0
  123. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/cli/tui_commands.py +0 -0
  124. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/cli/writes/__init__.py +0 -0
  125. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/cli/writes/apply.py +0 -0
  126. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/cli/writes/coercion.py +0 -0
  127. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/cli/writes/input.py +0 -0
  128. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/cli/writes/preflight.py +0 -0
  129. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/config/__init__.py +0 -0
  130. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/config/loader.py +0 -0
  131. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/http/__init__.py +0 -0
  132. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/http/errors.py +0 -0
  133. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/http/retry.py +0 -0
  134. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/model/__init__.py +0 -0
  135. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/model/command_model.py +0 -0
  136. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/output/__init__.py +0 -0
  137. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/output/_console.py +0 -0
  138. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/output/csv_.py +0 -0
  139. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/output/explain.py +0 -0
  140. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/output/flatten.py +0 -0
  141. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/output/headers.py +0 -0
  142. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/output/json_.py +0 -0
  143. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/output/jsonl.py +0 -0
  144. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/output/render.py +0 -0
  145. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/output/table.py +0 -0
  146. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/output/yaml_.py +0 -0
  147. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/schema/__init__.py +0 -0
  148. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/schema/hashing.py +0 -0
  149. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/schema/loader.py +0 -0
  150. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/schema/models.py +0 -0
  151. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/schema/source.py +0 -0
  152. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/schemas/__init__.py +0 -0
  153. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/schemas/bundled/__init__.py +0 -0
  154. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/schemas/bundled/manifest.yaml +0 -0
  155. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/schemas/bundled/netbox-4.5.10.json.gz +0 -0
  156. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/schemas/bundled/netbox-4.6.0.json.gz +0 -0
  157. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/skill/__init__.py +0 -0
  158. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/__init__.py +0 -0
  159. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/_bindings.py +0 -0
  160. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/app.py +0 -0
  161. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/catalog.py +0 -0
  162. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/columns.py +0 -0
  163. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/errors.py +0 -0
  164. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/filters.py +0 -0
  165. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/keymap.py +0 -0
  166. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/nav.py +0 -0
  167. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/relations.py +0 -0
  168. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/screens/__init__.py +0 -0
  169. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/screens/columns.py +0 -0
  170. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/screens/filter.py +0 -0
  171. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/screens/global_search.py +0 -0
  172. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/screens/list.py +0 -0
  173. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/screens/picker.py +0 -0
  174. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/screens/record_picker.py +0 -0
  175. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/search.py +0 -0
  176. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/selection.py +0 -0
  177. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/styles.tcss +0 -0
  178. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/view.py +0 -0
  179. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/widgets/__init__.py +0 -0
  180. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/widgets/_modal.py +0 -0
  181. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/widgets/bulk_diff.py +0 -0
  182. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/widgets/bulk_summary.py +0 -0
  183. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/widgets/confirm.py +0 -0
  184. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/widgets/diff.py +0 -0
  185. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/widgets/help.py +0 -0
  186. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/nsc/tui/widgets/nav_tree.py +0 -0
  187. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/scripts/gen_docs.py +0 -0
  188. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/scripts/sync_agents_md.py +0 -0
  189. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/__init__.py +0 -0
  190. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/aliases/__init__.py +0 -0
  191. {netbox_super_cli-1.2.0/tests/auth → netbox_super_cli-1.3.0/tests/audit}/__init__.py +0 -0
  192. {netbox_super_cli-1.2.0/tests/benchmarks → netbox_super_cli-1.3.0/tests/auth}/__init__.py +0 -0
  193. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/auth/test_verify.py +0 -0
  194. {netbox_super_cli-1.2.0/tests/builder → netbox_super_cli-1.3.0/tests/benchmarks}/__init__.py +0 -0
  195. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/benchmarks/test_startup.py +0 -0
  196. {netbox_super_cli-1.2.0/tests/cache → netbox_super_cli-1.3.0/tests/builder}/__init__.py +0 -0
  197. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/builder/test_build.py +0 -0
  198. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/builder/test_default_columns.py +0 -0
  199. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/builder/test_redaction_marking.py +0 -0
  200. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/builder/test_request_body_shape.py +0 -0
  201. {netbox_super_cli-1.2.0/tests/cli → netbox_super_cli-1.3.0/tests/cache}/__init__.py +0 -0
  202. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cache/test_prune.py +0 -0
  203. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cache/test_store.py +0 -0
  204. {netbox_super_cli-1.2.0/tests/cli/writes → netbox_super_cli-1.3.0/tests/cli}/__init__.py +0 -0
  205. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/test_app_smoke.py +0 -0
  206. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/test_cache_commands.py +0 -0
  207. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/test_commands_dump.py +0 -0
  208. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/test_completion_smoke.py +0 -0
  209. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/test_config_commands.py +0 -0
  210. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/test_explain.py +0 -0
  211. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/test_globals_color.py +0 -0
  212. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/test_handlers.py +0 -0
  213. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/test_init_commands.py +0 -0
  214. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/test_lazy_textual_import.py +0 -0
  215. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/test_login_commands.py +0 -0
  216. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/test_meta_subcommands_under_broken_config.py +0 -0
  217. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/test_ndjson_input.py +0 -0
  218. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/test_profiles_commands.py +0 -0
  219. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/test_registration.py +0 -0
  220. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/test_respx_integration.py +0 -0
  221. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/test_runtime.py +0 -0
  222. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/test_runtime_color.py +0 -0
  223. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/test_stdin_sniffer.py +0 -0
  224. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/test_tui_command.py +0 -0
  225. {netbox_super_cli-1.2.0/tests/config → netbox_super_cli-1.3.0/tests/cli/writes}/__init__.py +0 -0
  226. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/writes/test_apply.py +0 -0
  227. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/writes/test_confirmation.py +0 -0
  228. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/writes/test_handler_helpers.py +0 -0
  229. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/writes/test_handlers_audit.py +0 -0
  230. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/writes/test_input.py +0 -0
  231. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/cli/writes/test_preflight.py +0 -0
  232. {netbox_super_cli-1.2.0/tests/http → netbox_super_cli-1.3.0/tests/config}/__init__.py +0 -0
  233. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/config/test_loader.py +0 -0
  234. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/config/test_models.py +0 -0
  235. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/config/test_writer_dotted_paths.py +0 -0
  236. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/config/test_writer_roundtrip.py +0 -0
  237. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/conftest.py +0 -0
  238. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/e2e/__init__.py +0 -0
  239. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/e2e/conftest.py +0 -0
  240. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/e2e/test_audit_redaction.py +0 -0
  241. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/e2e/test_auth_error_envelope.py +0 -0
  242. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/e2e/test_bulk_create_with_loop_fallback.py +0 -0
  243. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/e2e/test_full_cycle.py +0 -0
  244. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/e2e/test_login.py +0 -0
  245. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/e2e/test_ndjson.py +0 -0
  246. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/e2e/test_preflight_blocks_apply.py +0 -0
  247. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/e2e/test_validation_error_envelope_from_netbox.py +0 -0
  248. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/fixtures/profiles/single_profile.yaml +0 -0
  249. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/fixtures/responses/auth_401.json +0 -0
  250. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/fixtures/responses/circuits_providers_list.json +0 -0
  251. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/fixtures/responses/dcim_devices_get.json +0 -0
  252. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/fixtures/responses/dcim_devices_list_p1.json +0 -0
  253. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/fixtures/responses/dcim_devices_list_p2.json +0 -0
  254. {netbox_super_cli-1.2.0/tests/model → netbox_super_cli-1.3.0/tests/http}/__init__.py +0 -0
  255. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/http/test_audit_redaction.py +0 -0
  256. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/http/test_client.py +0 -0
  257. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/http/test_client_redaction_threading.py +0 -0
  258. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/http/test_errors.py +0 -0
  259. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/http/test_retry.py +0 -0
  260. {netbox_super_cli-1.2.0/tests/output → netbox_super_cli-1.3.0/tests/model}/__init__.py +0 -0
  261. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/model/test_command_model.py +0 -0
  262. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/model/test_request_body_shape.py +0 -0
  263. {netbox_super_cli-1.2.0/tests/schema → netbox_super_cli-1.3.0/tests/output}/__init__.py +0 -0
  264. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/output/test_console.py +0 -0
  265. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/output/test_csv.py +0 -0
  266. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/output/test_errors_color.py +0 -0
  267. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/output/test_explain.py +0 -0
  268. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/output/test_explain_color.py +0 -0
  269. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/output/test_flatten.py +0 -0
  270. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/output/test_input_error_envelope.py +0 -0
  271. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/output/test_json.py +0 -0
  272. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/output/test_jsonl.py +0 -0
  273. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/output/test_render_dispatch.py +0 -0
  274. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/output/test_table.py +0 -0
  275. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/output/test_table_color.py +0 -0
  276. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/output/test_yaml.py +0 -0
  277. {netbox_super_cli-1.2.0/tests/scripts → netbox_super_cli-1.3.0/tests/schema}/__init__.py +0 -0
  278. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/schema/test_hashing.py +0 -0
  279. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/schema/test_loader.py +0 -0
  280. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/schema/test_models.py +0 -0
  281. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/schema/test_source.py +0 -0
  282. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/schema/test_source_ttl.py +0 -0
  283. {netbox_super_cli-1.2.0/tests/skill → netbox_super_cli-1.3.0/tests/scripts}/__init__.py +0 -0
  284. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/scripts/test_gen_docs.py +0 -0
  285. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/scripts/test_sync_agents_md.py +0 -0
  286. {netbox_super_cli-1.2.0/tests/tui → netbox_super_cli-1.3.0/tests/skill}/__init__.py +0 -0
  287. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/skill/test_bundle.py +0 -0
  288. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/test_packaging.py +0 -0
  289. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_app.py +0 -0
  290. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_bindings.py +0 -0
  291. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_bulk_apply.py +0 -0
  292. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_bulk_diff_modal.py +0 -0
  293. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_bulk_import_isolation.py +0 -0
  294. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_bulk_summary.py +0 -0
  295. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_catalog.py +0 -0
  296. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_column_chooser.py +0 -0
  297. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_columns.py +0 -0
  298. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_diff_modal.py +0 -0
  299. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_errors.py +0 -0
  300. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_filter_screen.py +0 -0
  301. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_filters.py +0 -0
  302. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_global_search.py +0 -0
  303. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_help_overlay.py +0 -0
  304. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_keymap.py +0 -0
  305. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_list_screen.py +0 -0
  306. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_picker.py +0 -0
  307. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_record_picker.py +0 -0
  308. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_relations.py +0 -0
  309. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_search.py +0 -0
  310. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_selection.py +0 -0
  311. {netbox_super_cli-1.2.0 → netbox_super_cli-1.3.0}/tests/tui/test_view.py +0 -0
@@ -0,0 +1,16 @@
1
+ version: 2
2
+
3
+ updates:
4
+ # Keep GitHub Actions pinned to commit SHAs maintainable: when an upstream
5
+ # action ships a new release, Dependabot opens a PR bumping the SHA and
6
+ # updates the trailing `# vX.Y.Z` comment to the new semver. `directory: "/"`
7
+ # monitors every workflow under .github/workflows/. Actions left on a
8
+ # floating tag by design (e.g. pypa/gh-action-pypi-publish@release/v1) are
9
+ # not bumped because they have no SHA to advance.
10
+ - package-ecosystem: "github-actions"
11
+ directory: "/"
12
+ schedule:
13
+ interval: "weekly"
14
+ open-pull-requests-limit: 5
15
+ commit-message:
16
+ prefix: "ci"
@@ -6,12 +6,15 @@ on:
6
6
  branches: [main]
7
7
  workflow_dispatch:
8
8
 
9
+ permissions:
10
+ contents: read
11
+
9
12
  jobs:
10
13
  startup-time:
11
14
  runs-on: ubuntu-latest
12
15
  steps:
13
- - uses: actions/checkout@v4
14
- - uses: astral-sh/setup-uv@v4
16
+ - uses: actions/checkout@v5
17
+ - uses: astral-sh/setup-uv@v7
15
18
  - name: Install
16
19
  run: uv sync --all-extras --dev
17
20
  - name: Benchmark
@@ -10,6 +10,18 @@ on:
10
10
  pull_request_review:
11
11
  types: [submitted]
12
12
 
13
+ # Least-privilege default for the whole workflow; the single `claude` job
14
+ # below re-declares the same scopes explicitly. The action only reads PRs
15
+ # and issues here (no auto-commit/comment requested), so write scopes are
16
+ # intentionally withheld — id-token: write is the sole write, required for
17
+ # the action's OIDC handshake.
18
+ permissions:
19
+ contents: read
20
+ pull-requests: read
21
+ issues: read
22
+ id-token: write
23
+ actions: read # Required for Claude to read CI results on PRs
24
+
13
25
  jobs:
14
26
  claude:
15
27
  # Only trusted authors (repo owner/members/collaborators) can invoke the
@@ -29,7 +41,7 @@ jobs:
29
41
  actions: read # Required for Claude to read CI results on PRs
30
42
  steps:
31
43
  - name: Checkout repository
32
- uses: actions/checkout@v4
44
+ uses: actions/checkout@v5
33
45
  with:
34
46
  fetch-depth: 1
35
47
 
@@ -26,9 +26,9 @@ jobs:
26
26
  build:
27
27
  runs-on: ubuntu-latest
28
28
  steps:
29
- - uses: actions/checkout@v4
29
+ - uses: actions/checkout@v5
30
30
  - name: Install uv
31
- uses: astral-sh/setup-uv@v3
31
+ uses: astral-sh/setup-uv@v7
32
32
  with:
33
33
  enable-cache: true
34
34
  - name: Install Python
@@ -52,4 +52,4 @@ jobs:
52
52
  url: ${{ steps.deployment.outputs.page_url }}
53
53
  steps:
54
54
  - id: deployment
55
- uses: actions/deploy-pages@v4
55
+ uses: actions/deploy-pages@v5
@@ -15,13 +15,27 @@ on:
15
15
  - '.github/workflows/e2e.yml'
16
16
  workflow_dispatch:
17
17
 
18
+ permissions:
19
+ contents: read
20
+
18
21
  jobs:
19
22
  e2e:
23
+ name: e2e (${{ matrix.netbox-version }})
20
24
  runs-on: ubuntu-latest
21
25
  timeout-minutes: 15
26
+ strategy:
27
+ fail-fast: false
28
+ matrix:
29
+ # Latest patch of each supported NetBox minor. A regression on one
30
+ # version surfaces as a per-dimension failure rather than a sweeping red.
31
+ netbox-version:
32
+ - v4.5.10
33
+ - v4.6.3
34
+ env:
35
+ NETBOX_IMAGE: netboxcommunity/netbox:${{ matrix.netbox-version }}
22
36
  steps:
23
- - uses: actions/checkout@v4
24
- - uses: astral-sh/setup-uv@v3
37
+ - uses: actions/checkout@v5
38
+ - uses: astral-sh/setup-uv@v7
25
39
  - name: Sync deps
26
40
  run: uv sync --frozen
27
41
  - name: Start NetBox
@@ -5,13 +5,16 @@ on:
5
5
  branches: [main]
6
6
  pull_request:
7
7
 
8
+ permissions:
9
+ contents: read
10
+
8
11
  jobs:
9
12
  lint:
10
13
  runs-on: ubuntu-latest
11
14
  steps:
12
- - uses: actions/checkout@v4
15
+ - uses: actions/checkout@v5
13
16
  - name: Install uv
14
- uses: astral-sh/setup-uv@v3
17
+ uses: astral-sh/setup-uv@v7
15
18
  with:
16
19
  enable-cache: true
17
20
  - name: Install Python
@@ -28,9 +31,9 @@ jobs:
28
31
  docs-reference-fresh:
29
32
  runs-on: ubuntu-latest
30
33
  steps:
31
- - uses: actions/checkout@v4
34
+ - uses: actions/checkout@v5
32
35
  - name: Install uv
33
- uses: astral-sh/setup-uv@v3
36
+ uses: astral-sh/setup-uv@v7
34
37
  with:
35
38
  enable-cache: true
36
39
  - name: Install Python
@@ -43,9 +46,9 @@ jobs:
43
46
  agents-md-fresh:
44
47
  runs-on: ubuntu-latest
45
48
  steps:
46
- - uses: actions/checkout@v4
49
+ - uses: actions/checkout@v5
47
50
  - name: Install uv
48
- uses: astral-sh/setup-uv@v3
51
+ uses: astral-sh/setup-uv@v7
49
52
  with:
50
53
  enable-cache: true
51
54
  - name: Install Python
@@ -39,7 +39,7 @@ jobs:
39
39
  # prerequisites).
40
40
  steps:
41
41
  - name: Checkout (full history for changelog notes)
42
- uses: actions/checkout@v4
42
+ uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
43
43
  with:
44
44
  fetch-depth: 0
45
45
 
@@ -51,7 +51,7 @@ jobs:
51
51
  # main. Tags pushed from a topic branch (or any unmerged commit)
52
52
  # would otherwise publish from un-reviewed code. This guard rejects
53
53
  # any tag whose commit is not reachable from origin/main.
54
- # actions/checkout@v4 with fetch-depth: 0 fetches the tag's full
54
+ # actions/checkout@v5 with fetch-depth: 0 fetches the tag's full
55
55
  # history but does not populate origin/main as a ref locally; we
56
56
  # fetch it explicitly here.
57
57
  git fetch origin main
@@ -62,7 +62,7 @@ jobs:
62
62
  echo "Tag $GITHUB_REF_NAME ($GITHUB_SHA) is on main."
63
63
 
64
64
  - name: Install uv
65
- uses: astral-sh/setup-uv@v3
65
+ uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
66
66
  with:
67
67
  enable-cache: true
68
68
 
@@ -0,0 +1,48 @@
1
+ name: skill-convention-review
2
+
3
+ # Quarterly reminder to re-check the four per-platform Skill-install conventions
4
+ # hard-coded in nsc/cli/skill_commands.py `_RESOLVERS`. Opens a tracking issue so
5
+ # a maintainer re-reads each canonical source and updates code+docs on drift.
6
+
7
+ on:
8
+ schedule:
9
+ # 09:00 UTC on the 1st of Feb/May/Aug/Nov.
10
+ - cron: "0 9 1 2,5,8,11 *"
11
+ workflow_dispatch:
12
+
13
+ permissions:
14
+ contents: read
15
+ issues: write
16
+
17
+ jobs:
18
+ open-tracking-issue:
19
+ runs-on: ubuntu-latest
20
+ env:
21
+ GH_TOKEN: ${{ github.token }}
22
+ steps:
23
+ - name: Open quarterly convention re-check issue
24
+ run: |
25
+ gh issue create \
26
+ --repo "${{ github.repository }}" \
27
+ --title "Quarterly: re-check Skill install conventions" \
28
+ --body "$(cat <<'EOF'
29
+ Quarterly re-check of the four per-platform Skill-install conventions
30
+ hard-coded in `nsc/cli/skill_commands.py` `_RESOLVERS`. Re-read each
31
+ canonical source below and confirm the documented user-scoped path is
32
+ still current.
33
+
34
+ - [ ] **claude-code** — https://code.claude.com/docs/en/skills
35
+ - [ ] **codex** — https://developers.openai.com/codex/skills
36
+ - [ ] **gemini** — https://geminicli.com/docs/cli/skills/
37
+ - [ ] **copilot** — https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-skills
38
+
39
+ If any convention drifted, update all of:
40
+
41
+ - `nsc/cli/skill_commands.py` (the relevant `_resolve_*` resolver)
42
+ - `docs/guides/using-with-ai-agents.md` (per-target path table)
43
+ - `skills/netbox-super-cli/SKILL.md` (if it lists per-target paths)
44
+ - `CHANGELOG.md` (note the change under the unreleased section)
45
+
46
+ Close this issue once all four are confirmed (and any drift is shipped).
47
+ EOF
48
+ )"
@@ -5,6 +5,9 @@ on:
5
5
  branches: [main]
6
6
  pull_request:
7
7
 
8
+ permissions:
9
+ contents: read
10
+
8
11
  jobs:
9
12
  test:
10
13
  runs-on: ${{ matrix.os }}
@@ -14,9 +17,9 @@ jobs:
14
17
  os: [ubuntu-latest, macos-latest]
15
18
  python: ["3.12", "3.13"]
16
19
  steps:
17
- - uses: actions/checkout@v4
20
+ - uses: actions/checkout@v5
18
21
  - name: Install uv
19
- uses: astral-sh/setup-uv@v3
22
+ uses: astral-sh/setup-uv@v7
20
23
  with:
21
24
  enable-cache: true
22
25
  - name: Install Python
@@ -24,6 +24,7 @@ repos:
24
24
  # plus type stubs for any third-party packages used in scripts/.
25
25
  additional_dependencies:
26
26
  - pydantic>=2.7
27
+ - click>=8.1
27
28
  - typer>=0.12
28
29
  - rich>=13.7
29
30
  - httpx>=0.27
@@ -21,6 +21,7 @@ This is the contributor guide for AI agents (and humans!) modifying this repo. T
21
21
  - `nsc/cache/` — disk cache for generated command-models.
22
22
  - `nsc/auth/` — login verification helpers (pre-flight probes, token rotate).
23
23
  - `nsc/aliases/` — curated alias resolver (`ls`, `get`, `rm`, `search`). Framework-free.
24
+ - `nsc/completion/` — dynamic shell-completion: framework-free providers + cheap on-disk cache probe + Typer `shell_complete` callbacks.
24
25
  - `nsc/skill/` — bundle-path helper for the portable `SKILL.md` shipped in the wheel.
25
26
  - `nsc/schemas/bundled/` — versioned NetBox OpenAPI snapshots, fallback when offline.
26
27
 
@@ -2,6 +2,94 @@
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.3.0 — 2026-06-25
6
+
7
+ Minor release. A batch of user-facing features — singular alias forms, parallel
8
+ bulk writes, dynamic shell completion, and a strict `audit_redaction: full`
9
+ mode — plus a round of state-directory, workflow, and supply-chain hardening.
10
+
11
+ ### Added
12
+
13
+ - **Singular alias forms** ([#6]). `nsc ls device` now resolves like
14
+ `nsc ls devices` for a curated set of nine resources: `device`, `prefix`,
15
+ `tenant`, `vlan`, `site`, `rack`, `interface`, `cable`, and `tag`. A
16
+ non-curated singular that does not resolve suggests the plural
17
+ (e.g. "Did you mean `devices`?") rather than guessing.
18
+ - **`--workers N` on bulk writes** ([#3]). Bulk write commands
19
+ (`create --ndjson`, `update --ndjson`, …) accept `--workers N` to run up to N
20
+ concurrent in-flight requests (default `1`, max `32`). Per-record
21
+ `--on-error` semantics are preserved, and the audit log stays one well-formed
22
+ line per record (writes are thread-safe). With `--on-error stop`, the bound
23
+ applies to *new* submissions — in-flight requests (up to N) are allowed to
24
+ complete.
25
+ - **Dynamic shell completion** ([#2]). Completion now reads the cached schema to
26
+ complete dynamic values: `nsc ls dev<TAB>` →
27
+ `devices device-roles device-types`; `nsc --profile <TAB>` → profile names;
28
+ `nsc <tag> <resource> list --status <TAB>` → enum values. This complements the
29
+ existing static `--install-completion` stubs.
30
+ - **`audit_redaction: full` config mode** ([#5]). A new strict redaction mode
31
+ redacts ALL request/response bodies, leaving only
32
+ `{method, url, status_code, timestamp, profile}` per audit line. The `url` is
33
+ sanitized — the query string and any `user:pass@` credentials are stripped.
34
+ The default stays `safe`.
35
+
36
+ ### Changed
37
+
38
+ - **Faster command-tree registration / startup**. The static command-option
39
+ specs (global read flags and write flags) are now built once at import and
40
+ shared across all commands instead of being rebuilt per command, recovering a
41
+ startup-time regression introduced when `--workers` was added.
42
+ - **`~/.nsc` state root hardened to `0700`** ([#90]). Defense-in-depth on the
43
+ state directory itself; config and audit files were already `0600` and
44
+ `logs/` already `0700`.
45
+ - **CI runners on Node.js 24** ([#9]). Bumped `actions/checkout` to v5,
46
+ `astral-sh/setup-uv` to v7, and `deploy-pages` to v5.
47
+ - **Least-privilege workflow permissions** ([#12]). Every GitHub Actions
48
+ workflow now declares an explicit least-privilege `permissions:` block.
49
+ - **Release workflow actions pinned to commit SHAs** ([#16]). `release.yml`
50
+ pins `checkout` and `setup-uv` to commit SHAs (the PyPA publish action stays
51
+ on its floating tag per PyPA guidance); added `.github/dependabot.yml`
52
+ (github-actions ecosystem, weekly).
53
+ - **E2E CI matrix over NetBox v4.5 and v4.6** ([#4]). The end-to-end job now
54
+ runs against both NetBox lines (`fail-fast: false`, per-version labels).
55
+ - **`nsc skill install` now supports Gemini and Copilot CLI** ([#7]). Their
56
+ user-scoped Skill paths (`~/.gemini/skills/`, `~/.copilot/skills/`) are now
57
+ confirmed and documented, so `--target gemini` / `--target copilot` resolve to
58
+ a real install path instead of printing manual instructions. A quarterly CI
59
+ job opens a tracking issue to re-check the four per-platform conventions.
60
+
61
+ [#6]: https://github.com/thomaschristory/netbox-super-cli/issues/6
62
+ [#3]: https://github.com/thomaschristory/netbox-super-cli/issues/3
63
+ [#2]: https://github.com/thomaschristory/netbox-super-cli/issues/2
64
+ [#5]: https://github.com/thomaschristory/netbox-super-cli/issues/5
65
+ [#7]: https://github.com/thomaschristory/netbox-super-cli/issues/7
66
+ [#90]: https://github.com/thomaschristory/netbox-super-cli/issues/90
67
+ [#9]: https://github.com/thomaschristory/netbox-super-cli/issues/9
68
+ [#12]: https://github.com/thomaschristory/netbox-super-cli/issues/12
69
+ [#16]: https://github.com/thomaschristory/netbox-super-cli/issues/16
70
+ [#4]: https://github.com/thomaschristory/netbox-super-cli/issues/4
71
+
72
+ ## v1.2.1 — 2026-06-25
73
+
74
+ Patch release. Fixes foreign-key handling in the interactive TUI.
75
+
76
+ ### Fixed
77
+
78
+ - **TUI foreign-key fields show names and a chooser, not raw IDs** ([#97]).
79
+ In the bulk-edit, single-edit and detail screens, FK fields (device `role`,
80
+ `site`, `tenant`, `device_type`, …) now render their human-readable
81
+ `display`/`name` in the confirmation diff and present a searchable
82
+ record-picker dropdown of valid related objects, instead of showing the
83
+ numeric id and requiring a raw id to be typed. The outgoing `PATCH` still
84
+ carries the id, so the wire format is unchanged. FK detection is now keyed on
85
+ the record's nested object rather than the widget kind, because NetBox's
86
+ writable schema types FK fields as `oneOf[integer, brief]` (no primitive
87
+ type), which previously fell through to a free-text widget. When a relation's
88
+ target resource has no list endpoint, the field gracefully falls back to
89
+ raw-id entry with a hint rather than an inert chooser button.
90
+
91
+ [#97]: https://github.com/thomaschristory/netbox-super-cli/issues/97
92
+
5
93
  ## v1.2.0 — 2026-06-24
6
94
 
7
95
  Minor release. Adds an **interactive terminal UI** — a keyboard-driven, fully
@@ -14,6 +14,7 @@ This is the contributor guide for AI agents (and humans!) modifying this repo. T
14
14
  - `nsc/cache/` — disk cache for generated command-models.
15
15
  - `nsc/auth/` — login verification helpers (pre-flight probes, token rotate).
16
16
  - `nsc/aliases/` — curated alias resolver (`ls`, `get`, `rm`, `search`). Framework-free.
17
+ - `nsc/completion/` — dynamic shell-completion: framework-free providers + cheap on-disk cache probe + Typer `shell_complete` callbacks.
17
18
  - `nsc/skill/` — bundle-path helper for the portable `SKILL.md` shipped in the wheel.
18
19
  - `nsc/schemas/bundled/` — versioned NetBox OpenAPI snapshots, fallback when offline.
19
20
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: netbox-super-cli
3
- Version: 1.2.0
3
+ Version: 1.3.0
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
@@ -103,6 +103,10 @@ uv run nsc dcim devices create -f device.yaml --apply
103
103
  uv run nsc dcim devices create -f devices.yaml --apply
104
104
  uv run nsc dcim devices create -f devices.yaml --no-bulk --on-error continue --apply
105
105
 
106
+ # Speed up a loop-mode bulk write with concurrent requests (default 1, max 32).
107
+ # Per-record --on-error semantics hold; the audit log stays one line per record.
108
+ uv run nsc dcim devices create -f devices.ndjson --workers 8 --apply
109
+
106
110
  # NDJSON / JSONL — one record per line; parse failures abort the whole batch
107
111
  # before any wire request fires (`type: input_error`, exit 4, `details.bad_lines`).
108
112
  uv run nsc dcim devices create -f devices.ndjson --apply
@@ -137,7 +141,26 @@ Stdin is sniffed from the first 512 bytes (first non-whitespace byte plus a one-
137
141
  - HTTP headers in the `SENSITIVE_HEADERS` set (e.g. `Authorization`, `X-API-Key`) — replaced with `"<redacted>"`.
138
142
  - Request-body fields whose OpenAPI definition has `format: password` OR whose name (case-insensitive) is one of: `password`, `secret`, `token`, `api_key`, `apikey`, `private_key`, `passphrase`, `client_secret`. Nested fields and arrays of objects are walked recursively.
139
143
 
140
- The wire body sent to NetBox is **not** redacted — only the audit log. A failed write still records the redacted body; redaction is irreversible. Treat `audit.jsonl` like a verbose application log: gate it behind your home-directory permissions and rotate / archive accordingly. A "redact everything" mode is on the post-v1.0 roadmap.
144
+ The wire body sent to NetBox is **not** redacted — only the audit log. A failed write still records the redacted body; redaction is irreversible. Treat `audit.jsonl` like a verbose application log: gate it behind your home-directory permissions and rotate / archive accordingly.
145
+
146
+ For a stricter posture, set `audit_redaction: full` in `~/.nsc/config.yaml` (the default is `safe`, the field-level redaction described above). In `full` mode every audit line keeps only `{method, url, status_code, timestamp, profile}` — all request and response bodies are dropped, and the `url` is sanitized (query string and any `user:pass@` credentials stripped).
147
+
148
+ ## Curated aliases
149
+
150
+ `nsc ls`, `nsc get`, `nsc rm`, and `nsc search` are short verbs over the dynamic
151
+ command tree.
152
+
153
+ ```sh
154
+ nsc ls devices # list a resource by plural name
155
+ nsc ls device # singular also works (curated set, see below)
156
+ nsc get devices 7 # one record by id or name
157
+ nsc rm devices 7 --apply # delete (dry-run by default)
158
+ nsc search "rack-42" # /api/search/ on NetBox 4.5+
159
+ ```
160
+
161
+ Singular forms resolve for a curated set of nine resources: `device`, `prefix`,
162
+ `tenant`, `vlan`, `site`, `rack`, `interface`, `cable`, and `tag`. Any other
163
+ singular that does not resolve suggests its plural ("Did you mean `devices`?").
141
164
 
142
165
  ## Output and errors
143
166
 
@@ -183,7 +206,16 @@ nsc --install-completion # auto-detects $SHELL
183
206
  nsc --show-completion # prints the script instead of installing
184
207
  ```
185
208
 
186
- Typer supports `bash`, `zsh`, `fish`, and `pwsh`. Completion of dynamic values (resource names, profile names, filter keys) is on the post-1.0 roadmap.
209
+ Typer supports `bash`, `zsh`, `fish`, and `pwsh`.
210
+
211
+ Completion of dynamic values reads the cached schema and complements the static
212
+ stubs above:
213
+
214
+ ```sh
215
+ nsc ls dev<TAB> # devices device-roles device-types
216
+ nsc --profile <TAB> # configured profile names
217
+ nsc dcim devices list --status <TAB> # enum values for the field
218
+ ```
187
219
 
188
220
  ## Bundled Skill for AI agents
189
221
 
@@ -74,6 +74,10 @@ uv run nsc dcim devices create -f device.yaml --apply
74
74
  uv run nsc dcim devices create -f devices.yaml --apply
75
75
  uv run nsc dcim devices create -f devices.yaml --no-bulk --on-error continue --apply
76
76
 
77
+ # Speed up a loop-mode bulk write with concurrent requests (default 1, max 32).
78
+ # Per-record --on-error semantics hold; the audit log stays one line per record.
79
+ uv run nsc dcim devices create -f devices.ndjson --workers 8 --apply
80
+
77
81
  # NDJSON / JSONL — one record per line; parse failures abort the whole batch
78
82
  # before any wire request fires (`type: input_error`, exit 4, `details.bad_lines`).
79
83
  uv run nsc dcim devices create -f devices.ndjson --apply
@@ -108,7 +112,26 @@ Stdin is sniffed from the first 512 bytes (first non-whitespace byte plus a one-
108
112
  - HTTP headers in the `SENSITIVE_HEADERS` set (e.g. `Authorization`, `X-API-Key`) — replaced with `"<redacted>"`.
109
113
  - Request-body fields whose OpenAPI definition has `format: password` OR whose name (case-insensitive) is one of: `password`, `secret`, `token`, `api_key`, `apikey`, `private_key`, `passphrase`, `client_secret`. Nested fields and arrays of objects are walked recursively.
110
114
 
111
- The wire body sent to NetBox is **not** redacted — only the audit log. A failed write still records the redacted body; redaction is irreversible. Treat `audit.jsonl` like a verbose application log: gate it behind your home-directory permissions and rotate / archive accordingly. A "redact everything" mode is on the post-v1.0 roadmap.
115
+ The wire body sent to NetBox is **not** redacted — only the audit log. A failed write still records the redacted body; redaction is irreversible. Treat `audit.jsonl` like a verbose application log: gate it behind your home-directory permissions and rotate / archive accordingly.
116
+
117
+ For a stricter posture, set `audit_redaction: full` in `~/.nsc/config.yaml` (the default is `safe`, the field-level redaction described above). In `full` mode every audit line keeps only `{method, url, status_code, timestamp, profile}` — all request and response bodies are dropped, and the `url` is sanitized (query string and any `user:pass@` credentials stripped).
118
+
119
+ ## Curated aliases
120
+
121
+ `nsc ls`, `nsc get`, `nsc rm`, and `nsc search` are short verbs over the dynamic
122
+ command tree.
123
+
124
+ ```sh
125
+ nsc ls devices # list a resource by plural name
126
+ nsc ls device # singular also works (curated set, see below)
127
+ nsc get devices 7 # one record by id or name
128
+ nsc rm devices 7 --apply # delete (dry-run by default)
129
+ nsc search "rack-42" # /api/search/ on NetBox 4.5+
130
+ ```
131
+
132
+ Singular forms resolve for a curated set of nine resources: `device`, `prefix`,
133
+ `tenant`, `vlan`, `site`, `rack`, `interface`, `cable`, and `tag`. Any other
134
+ singular that does not resolve suggests its plural ("Did you mean `devices`?").
112
135
 
113
136
  ## Output and errors
114
137
 
@@ -154,7 +177,16 @@ nsc --install-completion # auto-detects $SHELL
154
177
  nsc --show-completion # prints the script instead of installing
155
178
  ```
156
179
 
157
- Typer supports `bash`, `zsh`, `fish`, and `pwsh`. Completion of dynamic values (resource names, profile names, filter keys) is on the post-1.0 roadmap.
180
+ Typer supports `bash`, `zsh`, `fish`, and `pwsh`.
181
+
182
+ Completion of dynamic values reads the cached schema and complements the static
183
+ stubs above:
184
+
185
+ ```sh
186
+ nsc ls dev<TAB> # devices device-roles device-types
187
+ nsc --profile <TAB> # configured profile names
188
+ nsc dcim devices list --status <TAB> # enum values for the field
189
+ ```
158
190
 
159
191
  ## Bundled Skill for AI agents
160
192
 
@@ -70,3 +70,12 @@ nsc cache prune --apply # actually delete
70
70
  nsc cache prune --max-age 30 --apply
71
71
  nsc cache prune --output json # structured envelope
72
72
  ```
73
+
74
+ ## Shell completion reads the cache
75
+
76
+ Dynamic shell completion (`nsc/completion/`) is backed by this same on-disk
77
+ cache. At TAB time the completion providers probe the cached command-model for
78
+ the active profile (`<profile>/<schema-hash>.json`) — never the network — so
79
+ resource-name, profile, and enum suggestions are cheap. A missing or corrupt
80
+ cache degrades to no suggestions rather than blocking the prompt; the cache is
81
+ populated by the first real command (or `nsc login --fetch-schema`).
@@ -22,6 +22,17 @@
22
22
  - Pagination helper that follows `next` URLs (used by `--all`).
23
23
  - Audit log appender at `~/.nsc/logs/audit.jsonl` — written for writes
24
24
  always, and for any request when `--debug` is set.
25
+
26
+ ## Concurrency (`--workers N`)
27
+
28
+ Bulk write commands accept `--workers N` (default 1, max 32) to keep up to N
29
+ requests in flight. Concurrency is **thread-based**: a `ThreadPoolExecutor`
30
+ fans the per-record loop out over the single sync `httpx.Client` — there is no
31
+ async path. Per-record `--on-error` semantics are preserved regardless of
32
+ worker count. Audit appends are serialized by a module-level lock
33
+ (`_APPEND_LOCK` in `nsc/http/audit.py`) wrapped around the whole
34
+ open/write/close, so concurrent workers can never interleave a partial line —
35
+ each record is one well-formed JSON line.
25
36
  - A "last request" snapshot at `~/.nsc/logs/last-request.json`
26
37
  (overwritten every call, regardless of `--debug`) — handy for triage.
27
38
 
@@ -55,9 +66,26 @@ Each line of `audit.jsonl` is a JSON object with:
55
66
  - `duration_ms`, `attempt_n`, `final_attempt`, `error_kind`
56
67
  - `dry_run`, `preflight_blocked`, `record_indices`, `applied`, `explain`
57
68
 
69
+ ## Redaction modes
70
+
71
+ Redaction is applied when each entry is serialized (`nsc/http/audit.py`), so a
72
+ failed retry never unredacts. The `defaults.audit_redaction` config setting
73
+ selects the mode:
74
+
75
+ - `safe` (default) — the full audit shape above, with sensitive headers and
76
+ `sensitive_paths` body fields masked to `"<redacted>"` and bodies over 256 KB
77
+ truncated.
78
+ - `full` — compliance escalation that drops every body, header, and query
79
+ string entirely. Each line keeps exactly five keys —
80
+ `{method, url, status_code, timestamp, profile}` — and `url` is sanitized to
81
+ scheme + host[:port] + path so neither query params nor `user:pass@` userinfo
82
+ can leak through the one remaining string field.
83
+
58
84
  The audit file is append-only and rotates to `audit.jsonl.1` at 10 MB; it is
59
85
  created owner-only (`0600`) inside a `0700` logs directory, and failed writes do
60
- NOT unredact. See
86
+ NOT unredact. The state root (`~/.nsc`) and its subdirectories are clamped to
87
+ `0700` via a shared `ensure_private_dir()` (`nsc/config/settings.py`) used by
88
+ both the config writer and the audit-dir code. See
61
89
  [Writes and safety](../guides/writes-and-safety.md) for the full redaction
62
90
  contract.
63
91
 
@@ -17,6 +17,7 @@ nsc/
17
17
  ├── cache/ # On-disk cache for generated CommandModels
18
18
  ├── auth/ # Login verification helpers (verify probe, token rotate)
19
19
  ├── aliases/ # Curated alias resolver (ls/get/rm/search)
20
+ ├── completion/ # Dynamic shell-completion: providers + cache probe + Typer callbacks
20
21
  ├── skill/ # Bundle-path helper for the portable SKILL.md
21
22
  └── schemas/bundled/ # Versioned NetBox OpenAPI snapshots (offline fallback)
22
23
  ```
@@ -41,6 +41,23 @@ just docs-build # build the site, fail on broken links / missing nav
41
41
  underlying issue and create a new commit. If `ruff format` modifies a file
42
42
  during the hook, re-`git add` and re-commit.
43
43
 
44
+ ## CI
45
+
46
+ GitHub Actions mirrors the local `just` targets, plus an end-to-end suite:
47
+
48
+ - **E2E is multi-version.** The e2e workflow runs a matrix over NetBox **4.5
49
+ and 4.6** (latest patch of each minor) with `fail-fast: false`, so a
50
+ regression on one version surfaces as a per-dimension failure rather than a
51
+ sweeping red.
52
+ - **Runners are on Node.js 24** — the JS-based actions are pinned to their
53
+ Node-24 majors (`actions/checkout@v5`, `astral-sh/setup-uv@v7`,
54
+ `actions/deploy-pages@v5`).
55
+ - **Least-privilege permissions.** Every workflow declares an explicit
56
+ top-level `permissions:` block; the release workflow additionally SHA-pins
57
+ its actions (the PyPA publish action excepted).
58
+ - **Dependabot** watches the `github-actions` ecosystem on a weekly schedule
59
+ (`.github/dependabot.yml`) so action pins stay current.
60
+
44
61
  ## Where the design lives
45
62
 
46
63
  - `docs/superpowers/specs/` — design specs (gitignored; local-only).
@@ -49,6 +49,12 @@ endpoints — without per-plugin code in `nsc`**.
49
49
 
50
50
  A short curated alias layer sits on top: `nsc ls`, `nsc get`, `nsc rm`, `nsc search`.
51
51
 
52
+ For the curated resources — `device`, `prefix`, `tenant`, `vlan`, `site`,
53
+ `rack`, `interface`, `cable`, `tag` — the singular works identically to the
54
+ plural: `nsc ls device` is the same as `nsc ls devices` (likewise for `get` and
55
+ `rm` where supported). A non-curated singular that doesn't resolve suggests the
56
+ plural instead ("Did you mean `devices`?").
57
+
52
58
  ## Dry-run / apply
53
59
 
54
60
  Writes default to dry-run. The CLI shows the resolved request and exits 0
@@ -74,6 +74,7 @@ nsc dcim devices list # default page (page_size=50)
74
74
  nsc dcim devices list --all # paginate to completion
75
75
  nsc dcim devices get 7 # get by id
76
76
  nsc ls devices # alias — matches devices.list
77
+ nsc ls device # singular works too for curated resources
77
78
  nsc dcim devices list --output json --all # canonical machine-readable form
78
79
  ```
79
80
 
@@ -50,8 +50,16 @@ nsc --install-completion=pwsh
50
50
 
51
51
  Restart your shell, then verify with `nsc <TAB><TAB>`.
52
52
 
53
- > Dynamic completion (resource names, profile names, filter keys) is on the
54
- > post-1.0 roadmap.
53
+ ### Dynamic completion
54
+
55
+ Once completion is installed, TAB expands real values from the cached schema —
56
+ no network call at TAB time:
57
+
58
+ ```sh
59
+ nsc ls dev<TAB> # → devices device-roles device-types
60
+ nsc --profile <TAB> # → profile names from ~/.nsc/config.yaml
61
+ nsc dcim devices list --status <TAB> # → schema enum values for that filter
62
+ ```
55
63
 
56
64
  ## Requirements
57
65