netbox-super-cli 1.2.1__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.
- netbox_super_cli-1.3.0/.github/dependabot.yml +16 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/.github/workflows/bench.yml +5 -2
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/.github/workflows/claude.yml +13 -1
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/.github/workflows/docs.yml +3 -3
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/.github/workflows/e2e.yml +16 -2
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/.github/workflows/lint.yml +9 -6
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/.github/workflows/release.yml +3 -3
- netbox_super_cli-1.3.0/.github/workflows/skill-convention-review.yml +48 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/.github/workflows/test.yml +5 -2
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/.pre-commit-config.yaml +1 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/AGENTS.md +1 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/CHANGELOG.md +67 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/CLAUDE.md +1 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/PKG-INFO +35 -3
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/README.md +34 -2
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/architecture/caching.md +9 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/architecture/http-client.md +29 -1
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/architecture/overview.md +1 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/contributing/development.md +17 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/getting-started/concepts.md +6 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/getting-started/first-run.md +1 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/getting-started/install.md +10 -2
- netbox_super_cli-1.3.0/docs/guides/audit-log.md +71 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/guides/ci-and-automation.md +16 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/guides/managing-profiles.md +6 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/guides/using-with-ai-agents.md +9 -10
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/guides/working-with-plugins.md +10 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/guides/writes-and-safety.md +18 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/index.md +8 -1
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/reference/config.md +2 -1
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/justfile +2 -1
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/mkdocs.yml +1 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/_version.py +1 -1
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/aliases/__init__.py +4 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/aliases/resolver.py +50 -11
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/cli/aliases_commands.py +45 -6
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/cli/app.py +86 -15
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/cli/globals.py +6 -1
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/cli/handlers.py +5 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/cli/registration.py +41 -6
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/cli/runtime.py +1 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/cli/skill_commands.py +11 -14
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/cli/writes/bulk.py +112 -4
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/cli/writes/confirmation.py +24 -0
- netbox_super_cli-1.3.0/nsc/completion/__init__.py +11 -0
- netbox_super_cli-1.3.0/nsc/completion/cache_probe.py +72 -0
- netbox_super_cli-1.3.0/nsc/completion/callbacks.py +119 -0
- netbox_super_cli-1.3.0/nsc/completion/providers.py +66 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/config/models.py +9 -0
- netbox_super_cli-1.3.0/nsc/config/settings.py +64 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/config/writer.py +4 -2
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/http/audit.py +80 -34
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/http/client.py +13 -1
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/output/errors.py +20 -3
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/pyproject.toml +1 -1
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/skills/netbox-super-cli/SKILL.md +27 -3
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/aliases/test_resolver.py +81 -3
- netbox_super_cli-1.3.0/tests/audit/test_redaction_full.py +204 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/test_aliases_commands.py +25 -0
- netbox_super_cli-1.3.0/tests/cli/test_completion_protocol_smoke.py +196 -0
- netbox_super_cli-1.3.0/tests/cli/test_dynamic_completion.py +247 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/test_skill_commands.py +30 -8
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/test_writes_respx.py +196 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/writes/test_bulk.py +135 -0
- netbox_super_cli-1.3.0/tests/config/test_settings_private_dir.py +52 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/config/test_writer_atomicity.py +7 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/e2e/README.md +9 -1
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/e2e/docker-compose.yml +5 -2
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/e2e/wait_for_netbox.sh +1 -1
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/http/test_audit.py +23 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/http/test_audit_permissions.py +7 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/output/test_errors.py +30 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/output/test_errors_aliases.py +14 -0
- netbox_super_cli-1.3.0/tests/tui/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/uv.lock +1 -1
- netbox_super_cli-1.2.1/nsc/config/settings.py +0 -32
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/.gitignore +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/.python-version +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/LICENSE +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/architecture/command-generation.md +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/architecture/schema-loading.md +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/assets/tui/detail.svg +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/assets/tui/filter.svg +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/assets/tui/list.svg +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/assets/tui/picker.svg +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/assets/tui/search.svg +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/contributing/adding-bundled-schemas.md +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/contributing/branching.md +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/contributing/release-process.md +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/guides/interactive-tui.md +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/guides/output-formats.md +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/reference/cli.md +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/reference/exit-codes.md +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/docs/reference/schemas.md +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/__main__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/auth/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/auth/verify.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/builder/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/builder/build.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/cache/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/cache/store.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/cli/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/cli/cache_commands.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/cli/commands_dump.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/cli/config_commands.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/cli/init_commands.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/cli/login_commands.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/cli/profiles_commands.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/cli/tui_commands.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/cli/writes/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/cli/writes/apply.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/cli/writes/coercion.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/cli/writes/input.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/cli/writes/preflight.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/config/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/config/loader.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/http/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/http/errors.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/http/retry.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/model/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/model/command_model.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/output/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/output/_console.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/output/csv_.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/output/explain.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/output/flatten.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/output/headers.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/output/json_.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/output/jsonl.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/output/render.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/output/table.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/output/yaml_.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/schema/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/schema/hashing.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/schema/loader.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/schema/models.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/schema/source.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/schemas/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/schemas/bundled/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/schemas/bundled/manifest.yaml +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/schemas/bundled/netbox-4.5.10.json.gz +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/schemas/bundled/netbox-4.6.0.json.gz +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/skill/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/_bindings.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/app.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/bulk.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/catalog.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/columns.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/errors.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/filters.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/fk.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/forms.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/keymap.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/nav.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/relations.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/screens/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/screens/bulk_edit_form.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/screens/columns.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/screens/detail.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/screens/edit_form.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/screens/filter.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/screens/global_search.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/screens/list.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/screens/picker.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/screens/record_picker.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/search.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/selection.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/styles.tcss +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/view.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/widgets/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/widgets/_modal.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/widgets/bulk_diff.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/widgets/bulk_summary.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/widgets/confirm.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/widgets/diff.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/widgets/help.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/nsc/tui/widgets/nav_tree.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/scripts/gen_docs.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/scripts/sync_agents_md.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/aliases/__init__.py +0 -0
- {netbox_super_cli-1.2.1/tests/auth → netbox_super_cli-1.3.0/tests/audit}/__init__.py +0 -0
- {netbox_super_cli-1.2.1/tests/benchmarks → netbox_super_cli-1.3.0/tests/auth}/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/auth/test_verify.py +0 -0
- {netbox_super_cli-1.2.1/tests/builder → netbox_super_cli-1.3.0/tests/benchmarks}/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/benchmarks/test_startup.py +0 -0
- {netbox_super_cli-1.2.1/tests/cache → netbox_super_cli-1.3.0/tests/builder}/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/builder/test_build.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/builder/test_default_columns.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/builder/test_redaction_marking.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/builder/test_request_body_shape.py +0 -0
- {netbox_super_cli-1.2.1/tests/cli → netbox_super_cli-1.3.0/tests/cache}/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cache/test_prune.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cache/test_store.py +0 -0
- {netbox_super_cli-1.2.1/tests/cli/writes → netbox_super_cli-1.3.0/tests/cli}/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/test_app_smoke.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/test_cache_commands.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/test_commands_dump.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/test_completion_smoke.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/test_config_commands.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/test_explain.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/test_globals_color.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/test_handlers.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/test_init_commands.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/test_lazy_textual_import.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/test_login_commands.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/test_meta_subcommands_under_broken_config.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/test_ndjson_input.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/test_profiles_commands.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/test_registration.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/test_respx_integration.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/test_runtime.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/test_runtime_color.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/test_stdin_sniffer.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/test_tui_command.py +0 -0
- {netbox_super_cli-1.2.1/tests/config → netbox_super_cli-1.3.0/tests/cli/writes}/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/writes/test_apply.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/writes/test_confirmation.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/writes/test_handler_helpers.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/writes/test_handlers_audit.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/writes/test_input.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/cli/writes/test_preflight.py +0 -0
- {netbox_super_cli-1.2.1/tests/http → netbox_super_cli-1.3.0/tests/config}/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/config/test_loader.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/config/test_models.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/config/test_writer_dotted_paths.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/config/test_writer_roundtrip.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/conftest.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/e2e/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/e2e/conftest.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/e2e/test_audit_redaction.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/e2e/test_auth_error_envelope.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/e2e/test_bulk_create_with_loop_fallback.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/e2e/test_full_cycle.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/e2e/test_login.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/e2e/test_ndjson.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/e2e/test_preflight_blocks_apply.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/e2e/test_validation_error_envelope_from_netbox.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/fixtures/profiles/single_profile.yaml +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/fixtures/responses/auth_401.json +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/fixtures/responses/circuits_providers_list.json +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/fixtures/responses/dcim_devices_get.json +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/fixtures/responses/dcim_devices_list_p1.json +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/fixtures/responses/dcim_devices_list_p2.json +0 -0
- {netbox_super_cli-1.2.1/tests/model → netbox_super_cli-1.3.0/tests/http}/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/http/test_audit_redaction.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/http/test_client.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/http/test_client_redaction_threading.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/http/test_errors.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/http/test_retry.py +0 -0
- {netbox_super_cli-1.2.1/tests/output → netbox_super_cli-1.3.0/tests/model}/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/model/test_command_model.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/model/test_request_body_shape.py +0 -0
- {netbox_super_cli-1.2.1/tests/schema → netbox_super_cli-1.3.0/tests/output}/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/output/test_console.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/output/test_csv.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/output/test_errors_color.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/output/test_explain.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/output/test_explain_color.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/output/test_flatten.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/output/test_input_error_envelope.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/output/test_json.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/output/test_jsonl.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/output/test_render_dispatch.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/output/test_table.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/output/test_table_color.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/output/test_yaml.py +0 -0
- {netbox_super_cli-1.2.1/tests/scripts → netbox_super_cli-1.3.0/tests/schema}/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/schema/test_hashing.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/schema/test_loader.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/schema/test_models.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/schema/test_source.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/schema/test_source_ttl.py +0 -0
- {netbox_super_cli-1.2.1/tests/skill → netbox_super_cli-1.3.0/tests/scripts}/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/scripts/test_gen_docs.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/scripts/test_sync_agents_md.py +0 -0
- {netbox_super_cli-1.2.1/tests/tui → netbox_super_cli-1.3.0/tests/skill}/__init__.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/skill/test_bundle.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/test_packaging.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_app.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_bindings.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_bulk_apply.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_bulk_diff.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_bulk_diff_modal.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_bulk_edit_form.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_bulk_import_isolation.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_bulk_summary.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_catalog.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_column_chooser.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_columns.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_detail_screen.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_diff.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_diff_modal.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_edit_form.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_errors.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_filter_screen.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_filters.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_fk_resolve.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_forms.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_global_search.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_help_overlay.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_keymap.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_list_screen.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_picker.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_record_picker.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_relations.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_search.py +0 -0
- {netbox_super_cli-1.2.1 → netbox_super_cli-1.3.0}/tests/tui/test_selection.py +0 -0
- {netbox_super_cli-1.2.1 → 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@
|
|
14
|
-
- uses: astral-sh/setup-uv@
|
|
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@
|
|
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@
|
|
29
|
+
- uses: actions/checkout@v5
|
|
30
30
|
- name: Install uv
|
|
31
|
-
uses: astral-sh/setup-uv@
|
|
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@
|
|
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@
|
|
24
|
-
- uses: astral-sh/setup-uv@
|
|
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@
|
|
15
|
+
- uses: actions/checkout@v5
|
|
13
16
|
- name: Install uv
|
|
14
|
-
uses: astral-sh/setup-uv@
|
|
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@
|
|
34
|
+
- uses: actions/checkout@v5
|
|
32
35
|
- name: Install uv
|
|
33
|
-
uses: astral-sh/setup-uv@
|
|
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@
|
|
49
|
+
- uses: actions/checkout@v5
|
|
47
50
|
- name: Install uv
|
|
48
|
-
uses: astral-sh/setup-uv@
|
|
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@
|
|
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@
|
|
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@
|
|
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@
|
|
20
|
+
- uses: actions/checkout@v5
|
|
18
21
|
- name: Install uv
|
|
19
|
-
uses: astral-sh/setup-uv@
|
|
22
|
+
uses: astral-sh/setup-uv@v7
|
|
20
23
|
with:
|
|
21
24
|
enable-cache: true
|
|
22
25
|
- name: Install Python
|
|
@@ -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,73 @@
|
|
|
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
|
+
|
|
5
72
|
## v1.2.1 — 2026-06-25
|
|
6
73
|
|
|
7
74
|
Patch release. Fixes foreign-key handling in the interactive TUI.
|
|
@@ -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.
|
|
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.
|
|
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`.
|
|
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.
|
|
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`.
|
|
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.
|
|
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
|
-
|
|
54
|
-
|
|
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
|
|