netbox-super-cli 1.0.8__tar.gz → 1.2.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.0.8 → netbox_super_cli-1.2.0}/.github/workflows/claude.yml +7 -5
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/.github/workflows/release.yml +14 -11
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/.gitignore +1 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/.pre-commit-config.yaml +1 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/CHANGELOG.md +86 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/PKG-INFO +24 -2
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/README.md +21 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/docs/architecture/http-client.md +8 -5
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/docs/architecture/schema-loading.md +5 -1
- netbox_super_cli-1.2.0/docs/assets/tui/detail.svg +190 -0
- netbox_super_cli-1.2.0/docs/assets/tui/filter.svg +199 -0
- netbox_super_cli-1.2.0/docs/assets/tui/list.svg +185 -0
- netbox_super_cli-1.2.0/docs/assets/tui/picker.svg +188 -0
- netbox_super_cli-1.2.0/docs/assets/tui/search.svg +192 -0
- netbox_super_cli-1.2.0/docs/guides/interactive-tui.md +197 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/docs/guides/writes-and-safety.md +9 -1
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/docs/index.md +1 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/mkdocs.yml +1 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/_version.py +1 -1
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/builder/build.py +1 -1
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/cli/app.py +10 -6
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/cli/registration.py +6 -2
- netbox_super_cli-1.2.0/nsc/cli/tui_commands.py +69 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/http/audit.py +31 -4
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/output/headers.py +1 -1
- netbox_super_cli-1.2.0/nsc/schema/loader.py +143 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/schema/models.py +19 -1
- netbox_super_cli-1.2.0/nsc/tui/__init__.py +30 -0
- netbox_super_cli-1.2.0/nsc/tui/_bindings.py +17 -0
- netbox_super_cli-1.2.0/nsc/tui/app.py +109 -0
- netbox_super_cli-1.2.0/nsc/tui/bulk.py +113 -0
- netbox_super_cli-1.2.0/nsc/tui/catalog.py +51 -0
- netbox_super_cli-1.2.0/nsc/tui/columns.py +62 -0
- netbox_super_cli-1.2.0/nsc/tui/errors.py +44 -0
- netbox_super_cli-1.2.0/nsc/tui/filters.py +130 -0
- netbox_super_cli-1.2.0/nsc/tui/fk.py +128 -0
- netbox_super_cli-1.2.0/nsc/tui/forms.py +111 -0
- netbox_super_cli-1.2.0/nsc/tui/keymap.py +87 -0
- netbox_super_cli-1.2.0/nsc/tui/nav.py +21 -0
- netbox_super_cli-1.2.0/nsc/tui/relations.py +65 -0
- netbox_super_cli-1.2.0/nsc/tui/screens/bulk_edit_form.py +238 -0
- netbox_super_cli-1.2.0/nsc/tui/screens/columns.py +76 -0
- netbox_super_cli-1.2.0/nsc/tui/screens/detail.py +371 -0
- netbox_super_cli-1.2.0/nsc/tui/screens/edit_form.py +248 -0
- netbox_super_cli-1.2.0/nsc/tui/screens/filter.py +252 -0
- netbox_super_cli-1.2.0/nsc/tui/screens/global_search.py +175 -0
- netbox_super_cli-1.2.0/nsc/tui/screens/list.py +290 -0
- netbox_super_cli-1.2.0/nsc/tui/screens/picker.py +102 -0
- netbox_super_cli-1.2.0/nsc/tui/screens/record_picker.py +116 -0
- netbox_super_cli-1.2.0/nsc/tui/search.py +65 -0
- netbox_super_cli-1.2.0/nsc/tui/selection.py +37 -0
- netbox_super_cli-1.2.0/nsc/tui/styles.tcss +169 -0
- netbox_super_cli-1.2.0/nsc/tui/view.py +46 -0
- netbox_super_cli-1.2.0/nsc/tui/widgets/_modal.py +40 -0
- netbox_super_cli-1.2.0/nsc/tui/widgets/bulk_diff.py +43 -0
- netbox_super_cli-1.2.0/nsc/tui/widgets/bulk_summary.py +56 -0
- netbox_super_cli-1.2.0/nsc/tui/widgets/confirm.py +22 -0
- netbox_super_cli-1.2.0/nsc/tui/widgets/diff.py +36 -0
- netbox_super_cli-1.2.0/nsc/tui/widgets/help.py +66 -0
- netbox_super_cli-1.2.0/nsc/tui/widgets/nav_tree.py +34 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/pyproject.toml +12 -6
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/scripts/gen_docs.py +30 -2
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/scripts/sync_agents_md.py +27 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/skills/netbox-super-cli/SKILL.md +3 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/builder/test_request_body_shape.py +32 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/test_commands_dump.py +27 -20
- netbox_super_cli-1.2.0/tests/cli/test_lazy_textual_import.py +59 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/test_registration.py +12 -1
- netbox_super_cli-1.2.0/tests/cli/test_tui_command.py +111 -0
- netbox_super_cli-1.2.0/tests/http/test_audit_permissions.py +79 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/http/test_audit_redaction.py +19 -0
- netbox_super_cli-1.2.0/tests/schema/test_loader.py +167 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/schema/test_models.py +24 -1
- netbox_super_cli-1.2.0/tests/scripts/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/scripts/test_gen_docs.py +33 -0
- netbox_super_cli-1.2.0/tests/scripts/test_sync_agents_md.py +63 -0
- netbox_super_cli-1.2.0/tests/skill/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/skill/test_bundle.py +1 -6
- netbox_super_cli-1.2.0/tests/tui/__init__.py +0 -0
- netbox_super_cli-1.2.0/tests/tui/test_app.py +137 -0
- netbox_super_cli-1.2.0/tests/tui/test_bindings.py +12 -0
- netbox_super_cli-1.2.0/tests/tui/test_bulk_apply.py +122 -0
- netbox_super_cli-1.2.0/tests/tui/test_bulk_diff.py +109 -0
- netbox_super_cli-1.2.0/tests/tui/test_bulk_diff_modal.py +242 -0
- netbox_super_cli-1.2.0/tests/tui/test_bulk_edit_form.py +576 -0
- netbox_super_cli-1.2.0/tests/tui/test_bulk_import_isolation.py +44 -0
- netbox_super_cli-1.2.0/tests/tui/test_bulk_summary.py +47 -0
- netbox_super_cli-1.2.0/tests/tui/test_catalog.py +99 -0
- netbox_super_cli-1.2.0/tests/tui/test_column_chooser.py +117 -0
- netbox_super_cli-1.2.0/tests/tui/test_columns.py +50 -0
- netbox_super_cli-1.2.0/tests/tui/test_detail_screen.py +543 -0
- netbox_super_cli-1.2.0/tests/tui/test_diff.py +99 -0
- netbox_super_cli-1.2.0/tests/tui/test_diff_modal.py +96 -0
- netbox_super_cli-1.2.0/tests/tui/test_edit_form.py +555 -0
- netbox_super_cli-1.2.0/tests/tui/test_errors.py +29 -0
- netbox_super_cli-1.2.0/tests/tui/test_filter_screen.py +373 -0
- netbox_super_cli-1.2.0/tests/tui/test_filters.py +139 -0
- netbox_super_cli-1.2.0/tests/tui/test_fk_resolve.py +130 -0
- netbox_super_cli-1.2.0/tests/tui/test_forms.py +90 -0
- netbox_super_cli-1.2.0/tests/tui/test_global_search.py +193 -0
- netbox_super_cli-1.2.0/tests/tui/test_help_overlay.py +97 -0
- netbox_super_cli-1.2.0/tests/tui/test_keymap.py +197 -0
- netbox_super_cli-1.2.0/tests/tui/test_list_screen.py +696 -0
- netbox_super_cli-1.2.0/tests/tui/test_picker.py +158 -0
- netbox_super_cli-1.2.0/tests/tui/test_record_picker.py +223 -0
- netbox_super_cli-1.2.0/tests/tui/test_relations.py +138 -0
- netbox_super_cli-1.2.0/tests/tui/test_search.py +69 -0
- netbox_super_cli-1.2.0/tests/tui/test_selection.py +99 -0
- netbox_super_cli-1.2.0/tests/tui/test_view.py +27 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/uv.lock +84 -12
- netbox_super_cli-1.0.8/.github/workflows/agents-md-sync.yml +0 -35
- netbox_super_cli-1.0.8/nsc/schema/loader.py +0 -66
- netbox_super_cli-1.0.8/tests/schema/test_loader.py +0 -81
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/.github/workflows/bench.yml +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/.github/workflows/docs.yml +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/.github/workflows/e2e.yml +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/.github/workflows/lint.yml +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/.github/workflows/test.yml +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/.python-version +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/AGENTS.md +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/CLAUDE.md +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/LICENSE +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/docs/architecture/caching.md +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/docs/architecture/command-generation.md +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/docs/architecture/overview.md +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/docs/contributing/adding-bundled-schemas.md +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/docs/contributing/branching.md +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/docs/contributing/development.md +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/docs/contributing/release-process.md +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/docs/getting-started/concepts.md +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/docs/getting-started/first-run.md +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/docs/getting-started/install.md +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/docs/guides/ci-and-automation.md +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/docs/guides/managing-profiles.md +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/docs/guides/output-formats.md +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/docs/guides/using-with-ai-agents.md +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/docs/guides/working-with-plugins.md +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/docs/reference/cli.md +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/docs/reference/config.md +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/docs/reference/exit-codes.md +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/docs/reference/schemas.md +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/justfile +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/__main__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/aliases/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/aliases/resolver.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/auth/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/auth/verify.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/builder/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/cache/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/cache/store.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/cli/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/cli/aliases_commands.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/cli/cache_commands.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/cli/commands_dump.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/cli/config_commands.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/cli/globals.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/cli/handlers.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/cli/init_commands.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/cli/login_commands.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/cli/profiles_commands.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/cli/runtime.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/cli/skill_commands.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/cli/writes/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/cli/writes/apply.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/cli/writes/bulk.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/cli/writes/coercion.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/cli/writes/confirmation.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/cli/writes/input.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/cli/writes/preflight.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/config/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/config/loader.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/config/models.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/config/settings.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/config/writer.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/http/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/http/client.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/http/errors.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/http/retry.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/model/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/model/command_model.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/output/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/output/_console.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/output/csv_.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/output/errors.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/output/explain.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/output/flatten.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/output/json_.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/output/jsonl.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/output/render.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/output/table.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/output/yaml_.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/schema/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/schema/hashing.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/schema/source.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/schemas/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/schemas/bundled/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/schemas/bundled/manifest.yaml +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/schemas/bundled/netbox-4.5.10.json.gz +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/schemas/bundled/netbox-4.6.0.json.gz +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/nsc/skill/__init__.py +0 -0
- {netbox_super_cli-1.0.8/tests → netbox_super_cli-1.2.0/nsc/tui/screens}/__init__.py +0 -0
- {netbox_super_cli-1.0.8/tests/aliases → netbox_super_cli-1.2.0/nsc/tui/widgets}/__init__.py +0 -0
- {netbox_super_cli-1.0.8/tests/auth → netbox_super_cli-1.2.0/tests}/__init__.py +0 -0
- {netbox_super_cli-1.0.8/tests/benchmarks → netbox_super_cli-1.2.0/tests/aliases}/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/aliases/test_resolver.py +0 -0
- {netbox_super_cli-1.0.8/tests/builder → netbox_super_cli-1.2.0/tests/auth}/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/auth/test_verify.py +0 -0
- {netbox_super_cli-1.0.8/tests/cache → netbox_super_cli-1.2.0/tests/benchmarks}/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/benchmarks/test_startup.py +0 -0
- {netbox_super_cli-1.0.8/tests/cli → netbox_super_cli-1.2.0/tests/builder}/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/builder/test_build.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/builder/test_default_columns.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/builder/test_redaction_marking.py +0 -0
- {netbox_super_cli-1.0.8/tests/cli/writes → netbox_super_cli-1.2.0/tests/cache}/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cache/test_prune.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cache/test_store.py +0 -0
- {netbox_super_cli-1.0.8/tests/config → netbox_super_cli-1.2.0/tests/cli}/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/test_aliases_commands.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/test_app_smoke.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/test_cache_commands.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/test_completion_smoke.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/test_config_commands.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/test_explain.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/test_globals_color.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/test_handlers.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/test_init_commands.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/test_login_commands.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/test_meta_subcommands_under_broken_config.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/test_ndjson_input.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/test_profiles_commands.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/test_respx_integration.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/test_runtime.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/test_runtime_color.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/test_skill_commands.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/test_stdin_sniffer.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/test_writes_respx.py +0 -0
- {netbox_super_cli-1.0.8/tests/http → netbox_super_cli-1.2.0/tests/cli/writes}/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/writes/test_apply.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/writes/test_bulk.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/writes/test_confirmation.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/writes/test_handler_helpers.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/writes/test_handlers_audit.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/writes/test_input.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/cli/writes/test_preflight.py +0 -0
- {netbox_super_cli-1.0.8/tests/model → netbox_super_cli-1.2.0/tests/config}/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/config/test_loader.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/config/test_models.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/config/test_writer_atomicity.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/config/test_writer_dotted_paths.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/config/test_writer_roundtrip.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/conftest.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/e2e/README.md +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/e2e/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/e2e/conftest.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/e2e/docker-compose.yml +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/e2e/test_audit_redaction.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/e2e/test_auth_error_envelope.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/e2e/test_bulk_create_with_loop_fallback.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/e2e/test_full_cycle.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/e2e/test_login.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/e2e/test_ndjson.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/e2e/test_preflight_blocks_apply.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/e2e/test_validation_error_envelope_from_netbox.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/e2e/wait_for_netbox.sh +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/fixtures/profiles/single_profile.yaml +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/fixtures/responses/auth_401.json +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/fixtures/responses/circuits_providers_list.json +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/fixtures/responses/dcim_devices_get.json +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/fixtures/responses/dcim_devices_list_p1.json +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/fixtures/responses/dcim_devices_list_p2.json +0 -0
- {netbox_super_cli-1.0.8/tests/output → netbox_super_cli-1.2.0/tests/http}/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/http/test_audit.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/http/test_client.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/http/test_client_redaction_threading.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/http/test_errors.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/http/test_retry.py +0 -0
- {netbox_super_cli-1.0.8/tests/schema → netbox_super_cli-1.2.0/tests/model}/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/model/test_command_model.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/model/test_request_body_shape.py +0 -0
- {netbox_super_cli-1.0.8/tests/scripts → netbox_super_cli-1.2.0/tests/output}/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/output/test_console.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/output/test_csv.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/output/test_errors.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/output/test_errors_aliases.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/output/test_errors_color.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/output/test_explain.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/output/test_explain_color.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/output/test_flatten.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/output/test_input_error_envelope.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/output/test_json.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/output/test_jsonl.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/output/test_render_dispatch.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/output/test_table.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/output/test_table_color.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/output/test_yaml.py +0 -0
- {netbox_super_cli-1.0.8/tests/skill → netbox_super_cli-1.2.0/tests/schema}/__init__.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/schema/test_hashing.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/schema/test_source.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/schema/test_source_ttl.py +0 -0
- {netbox_super_cli-1.0.8 → netbox_super_cli-1.2.0}/tests/test_packaging.py +0 -0
|
@@ -12,11 +12,14 @@ on:
|
|
|
12
12
|
|
|
13
13
|
jobs:
|
|
14
14
|
claude:
|
|
15
|
+
# Only trusted authors (repo owner/members/collaborators) can invoke the
|
|
16
|
+
# secret-bearing agent; the @claude substring alone is satisfiable by any
|
|
17
|
+
# commenter on a public repo and would bill drive-by API usage (audit L3).
|
|
15
18
|
if: |
|
|
16
|
-
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
|
|
17
|
-
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
|
|
18
|
-
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
|
|
19
|
-
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
|
|
19
|
+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude') && contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)) ||
|
|
20
|
+
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude') && contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)) ||
|
|
21
|
+
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude') && contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.review.author_association)) ||
|
|
22
|
+
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')) && contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.issue.author_association))
|
|
20
23
|
runs-on: ubuntu-latest
|
|
21
24
|
permissions:
|
|
22
25
|
contents: read
|
|
@@ -47,4 +50,3 @@ jobs:
|
|
|
47
50
|
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
|
|
48
51
|
# or https://code.claude.com/docs/en/cli-reference for available options
|
|
49
52
|
# claude_args: '--allowed-tools Bash(gh pr *)'
|
|
50
|
-
|
|
@@ -76,6 +76,9 @@ jobs:
|
|
|
76
76
|
run: |
|
|
77
77
|
set -euo pipefail
|
|
78
78
|
tag_version="${GITHUB_REF_NAME#v}"
|
|
79
|
+
# Derive the version once and export it for the later steps (wheel
|
|
80
|
+
# filename, changelog, GitHub Release) instead of re-deriving it.
|
|
81
|
+
echo "TAG_VERSION=${tag_version}" >> "$GITHUB_ENV"
|
|
79
82
|
pkg_version="$(uv run python -c 'from nsc._version import __version__; print(__version__)')"
|
|
80
83
|
if [ "$tag_version" != "$pkg_version" ]; then
|
|
81
84
|
echo "Tag $GITHUB_REF_NAME -> version $tag_version does not match nsc/_version.py $pkg_version" >&2
|
|
@@ -87,19 +90,21 @@ jobs:
|
|
|
87
90
|
run: |
|
|
88
91
|
rm -rf dist
|
|
89
92
|
uv build --out-dir dist
|
|
93
|
+
# Breadcrumb: leave the artifact listing in the success log so a
|
|
94
|
+
# future post-mortem can confirm exactly what was built (the
|
|
95
|
+
# verify-filename step below already lists dist/ on failure).
|
|
90
96
|
ls -la dist/
|
|
91
97
|
|
|
92
98
|
- name: Verify wheel filename matches tag
|
|
93
99
|
run: |
|
|
94
100
|
set -euo pipefail
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
echo "Wheel for ${tag_version} not found in dist/" >&2
|
|
101
|
+
if ! ls "dist/netbox_super_cli-${TAG_VERSION}-py3-none-any.whl" >/dev/null 2>&1; then
|
|
102
|
+
echo "Wheel for ${TAG_VERSION} not found in dist/" >&2
|
|
98
103
|
ls dist/ >&2
|
|
99
104
|
exit 1
|
|
100
105
|
fi
|
|
101
|
-
if ! ls "dist/netbox_super_cli-${
|
|
102
|
-
echo "Sdist for ${
|
|
106
|
+
if ! ls "dist/netbox_super_cli-${TAG_VERSION}.tar.gz" >/dev/null 2>&1; then
|
|
107
|
+
echo "Sdist for ${TAG_VERSION} not found in dist/" >&2
|
|
103
108
|
ls dist/ >&2
|
|
104
109
|
exit 1
|
|
105
110
|
fi
|
|
@@ -130,18 +135,17 @@ jobs:
|
|
|
130
135
|
id: notes
|
|
131
136
|
run: |
|
|
132
137
|
set -euo pipefail
|
|
133
|
-
tag_version="${GITHUB_REF_NAME#v}"
|
|
134
138
|
# Match `## v<ver><space>...` and capture until the next `## `
|
|
135
139
|
# heading. The trailing space after <ver> in the regex is what
|
|
136
140
|
# disambiguates `v1.0` from `v1.0.1`; what follows (typically an
|
|
137
141
|
# em-dash, date, sub-phase name) is intentionally unconstrained.
|
|
138
|
-
awk -v ver="$
|
|
142
|
+
awk -v ver="$TAG_VERSION" '
|
|
139
143
|
$0 ~ "^## v" ver " " { capture=1; print; next }
|
|
140
144
|
capture && /^## / { exit }
|
|
141
145
|
capture { print }
|
|
142
146
|
' CHANGELOG.md > /tmp/release-notes.md
|
|
143
147
|
if [ ! -s /tmp/release-notes.md ]; then
|
|
144
|
-
echo "Release notes for v${
|
|
148
|
+
echo "Release notes for v${TAG_VERSION} not found in CHANGELOG.md" >&2
|
|
145
149
|
exit 1
|
|
146
150
|
fi
|
|
147
151
|
echo "Extracted $(wc -l < /tmp/release-notes.md) lines of release notes."
|
|
@@ -151,7 +155,6 @@ jobs:
|
|
|
151
155
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
152
156
|
run: |
|
|
153
157
|
set -euo pipefail
|
|
154
|
-
tag_version="${GITHUB_REF_NAME#v}"
|
|
155
158
|
# Use exact filenames (the verify-wheel-filename step proved both
|
|
156
159
|
# exist) rather than glob-expanding `dist/*.whl dist/*.tar.gz` —
|
|
157
160
|
# that glob would silently attach any stray artifact a future
|
|
@@ -159,5 +162,5 @@ jobs:
|
|
|
159
162
|
gh release create "$GITHUB_REF_NAME" \
|
|
160
163
|
--title "$GITHUB_REF_NAME" \
|
|
161
164
|
--notes-file /tmp/release-notes.md \
|
|
162
|
-
"dist/netbox_super_cli-${
|
|
163
|
-
"dist/netbox_super_cli-${
|
|
165
|
+
"dist/netbox_super_cli-${TAG_VERSION}-py3-none-any.whl" \
|
|
166
|
+
"dist/netbox_super_cli-${TAG_VERSION}.tar.gz"
|
|
@@ -2,6 +2,92 @@
|
|
|
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.2.0 — 2026-06-24
|
|
6
|
+
|
|
7
|
+
Minor release. Adds an **interactive terminal UI** — a keyboard-driven, fully
|
|
8
|
+
schema-generic front end over the same command model the CLI uses.
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **`nsc tui` — interactive TUI** (aliases: `nsc interactive`, `nsc i`). A
|
|
13
|
+
Textual app to browse, filter, edit, bulk-edit and search NetBox from the
|
|
14
|
+
keyboard, generated entirely from the OpenAPI-derived command model (works for
|
|
15
|
+
every resource and plugin, no per-model wiring). Textual is imported lazily so
|
|
16
|
+
the regular CLI's startup path is unchanged. See the
|
|
17
|
+
[Interactive TUI guide](https://thomaschristory.github.io/netbox-super-cli/guides/interactive-tui/).
|
|
18
|
+
- **Resource picker** — a collapsible tree of resources grouped by tag, with
|
|
19
|
+
fuzzy filtering (matching groups auto-expand) and expand/collapse-all.
|
|
20
|
+
- **List view** — paginated tables with vim/arrow navigation, multi-select,
|
|
21
|
+
refresh, and an async loading wheel that keeps the input responsive.
|
|
22
|
+
- **Filter builder** (`/`) — a web-UI-like form of curated common fields
|
|
23
|
+
(enum dropdowns, conventional field names), a search box over every query
|
|
24
|
+
parameter, foreign-key record pickers (applied as `…_id`), a raw
|
|
25
|
+
`key=value` line, and removable active-filter chips.
|
|
26
|
+
- **Inline record editing** — the detail view is the edit surface: edit a
|
|
27
|
+
field in place, stage changes, and save them all in one `PATCH` after a
|
|
28
|
+
confirmation diff. Create and delete are supported; foreign keys open a
|
|
29
|
+
searchable picker.
|
|
30
|
+
- **Relationship drill-down** — schema-derived relationship tabs (a device's
|
|
31
|
+
interfaces, modules, cables, …) open a pre-filtered list.
|
|
32
|
+
- **Bulk edit** — set chosen fields across a multi-selection (prepopulated
|
|
33
|
+
from the records' shared value), preview a per-record diff, and apply with a
|
|
34
|
+
progress bar and per-record partial-failure reporting.
|
|
35
|
+
- **Column chooser** (`f`) — toggle and reorder visible columns; the choice
|
|
36
|
+
persists per resource in `~/.nsc/config.yaml` (shared with the CLI's
|
|
37
|
+
`--columns`).
|
|
38
|
+
- **Global search** (`Ctrl`+`F`) — search across a curated set of common
|
|
39
|
+
object types at once, with results grouped by type and a live spinner.
|
|
40
|
+
- **Help overlay** (`?`) — a per-context keymap generated from the live
|
|
41
|
+
bindings, so it can never drift.
|
|
42
|
+
- New dependency: `textual` (loaded only by the TUI).
|
|
43
|
+
|
|
44
|
+
### Documentation
|
|
45
|
+
|
|
46
|
+
- New [Interactive TUI guide](https://thomaschristory.github.io/netbox-super-cli/guides/interactive-tui/)
|
|
47
|
+
with screenshots, linked from the Home page and the README.
|
|
48
|
+
|
|
49
|
+
## v1.1.0 — 2026-06-18
|
|
50
|
+
|
|
51
|
+
Minor release. Hardens the audit log and schema loader against the security
|
|
52
|
+
audit (#88), adopts typer 0.26's vendored click (#82), and lands a batch of
|
|
53
|
+
CI/workflow cleanups.
|
|
54
|
+
|
|
55
|
+
### Security
|
|
56
|
+
|
|
57
|
+
- **Audit logs are owner-only** (#88, M4/L1). `~/.nsc/logs/audit.jsonl` is now
|
|
58
|
+
created `0600` and its directory `0700` (a pre-existing world-readable log is
|
|
59
|
+
clamped back on the next append; the rotated `.1` inherits `0600`), mirroring
|
|
60
|
+
the `0600` treatment of `config.yaml`. Response headers are now redacted like
|
|
61
|
+
request headers, and `set-cookie` joins the sensitive-header set, so NetBox
|
|
62
|
+
session cookies no longer land in the log in cleartext.
|
|
63
|
+
- **Bounded schema fetch and decompression** (#88, L2). The schema loader caps
|
|
64
|
+
both the fetched HTTP body and any gzip-decompressed output at 64 MB. It reads
|
|
65
|
+
raw wire bytes under that cap and requests `Accept-Encoding: identity` so a
|
|
66
|
+
`Content-Encoding` bomb can't be inflated to gigabytes before the check, and
|
|
67
|
+
it rejects truncated or multi-member gzip streams.
|
|
68
|
+
- **Dependency bumps** (#88, M1/M2): `idna` 3.13 → 3.18 (CVE-2026-45409) and the
|
|
69
|
+
docs-build-only `pymdown-extensions` 10.21.2 → 10.21.3 (CVE-2026-46338).
|
|
70
|
+
- **`@claude` workflow author gating** (#88, L3): the secret-bearing Claude Code
|
|
71
|
+
workflow now requires an `OWNER`/`MEMBER`/`COLLABORATOR` author association in
|
|
72
|
+
addition to the `@claude` mention, so drive-by comments can't invoke it.
|
|
73
|
+
|
|
74
|
+
### Changed
|
|
75
|
+
|
|
76
|
+
- **typer 0.26+ vendored click** (#82). typer 0.26 vendored click as
|
|
77
|
+
`typer._click`; nsc's `TyperGroup` overrides are now decoupled from a specific
|
|
78
|
+
click (`Any`-typed) and the choice param type comes from typer's vendored
|
|
79
|
+
`TyperChoice`. The `typer<0.26` stopgap cap from v1.0.7 is lifted and the
|
|
80
|
+
dependency is pinned `typer>=0.26,<0.27`. Runtime behavior (dynamic command
|
|
81
|
+
tree, choice validation, error envelopes) is unchanged.
|
|
82
|
+
|
|
83
|
+
### Internal
|
|
84
|
+
|
|
85
|
+
- CI/workflow cleanups: drop the duplicate `agents-md-sync` workflow now that
|
|
86
|
+
`lint`'s `agents-md-fresh` job covers it (#19), DRY the release `TAG_VERSION`
|
|
87
|
+
derivation (#14), assert (rather than skip) the wheel `SKILL.md` layout (#20),
|
|
88
|
+
print a `difflib` unified diff from the drift-check scripts on `--check`
|
|
89
|
+
failure (#11), and doc-comment the `ls -la dist/` release breadcrumb (#15).
|
|
90
|
+
|
|
5
91
|
## v1.0.8 — 2026-06-10
|
|
6
92
|
|
|
7
93
|
Patch release. Table/CSV columns for choice fields now show their human label
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: netbox-super-cli
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.2.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
|
|
@@ -23,7 +23,8 @@ Requires-Dist: pydantic>=2.7
|
|
|
23
23
|
Requires-Dist: rich>=13.7
|
|
24
24
|
Requires-Dist: ruamel-yaml>=0.18
|
|
25
25
|
Requires-Dist: structlog>=24.1
|
|
26
|
-
Requires-Dist:
|
|
26
|
+
Requires-Dist: textual>=0.50
|
|
27
|
+
Requires-Dist: typer<0.27,>=0.26
|
|
27
28
|
Description-Content-Type: text/markdown
|
|
28
29
|
|
|
29
30
|
# netbox-super-cli (`nsc`)
|
|
@@ -38,6 +39,7 @@ A Python CLI for [NetBox](https://netbox.dev/) that builds its command tree dyna
|
|
|
38
39
|
- **Multi-instance.** Named profiles per NetBox instance, plus env-var overrides.
|
|
39
40
|
- **Safe by default.** POST/PATCH/PUT/DELETE preview as dry-runs unless you pass `--apply`.
|
|
40
41
|
- **Agent-friendly.** Deterministic command shape, machine-readable JSON output, stable error envelope with documented exit codes.
|
|
42
|
+
- **Interactive TUI.** `nsc tui` opens a keyboard-driven terminal UI — see below.
|
|
41
43
|
|
|
42
44
|
## Install
|
|
43
45
|
|
|
@@ -55,6 +57,26 @@ uv sync
|
|
|
55
57
|
uv run nsc --version
|
|
56
58
|
```
|
|
57
59
|
|
|
60
|
+
## Interactive TUI
|
|
61
|
+
|
|
62
|
+
`nsc tui` (aliases `nsc interactive`, `nsc i`) opens a full-screen,
|
|
63
|
+
keyboard-driven UI over your NetBox — browse, filter, edit, bulk-edit and search
|
|
64
|
+
across object types without writing a command. Like the CLI it is generated from
|
|
65
|
+
the live schema, so it works for every resource and plugin.
|
|
66
|
+
|
|
67
|
+

|
|
68
|
+
|
|
69
|
+
```sh
|
|
70
|
+
nsc tui # land on the resource picker
|
|
71
|
+
nsc tui devices # jump straight into the devices list
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Highlights: a collapsible resource picker, a web-UI-style filter builder (`/`),
|
|
75
|
+
inline record editing with a confirm-diff save, schema-derived relationship
|
|
76
|
+
drill-down, bulk edit with a per-record preview, a persisted column chooser
|
|
77
|
+
(`f`), and global search (`Ctrl`+`F`). Full walkthrough in the
|
|
78
|
+
[Interactive TUI guide](https://thomaschristory.github.io/netbox-super-cli/guides/interactive-tui/).
|
|
79
|
+
|
|
58
80
|
## Reading
|
|
59
81
|
|
|
60
82
|
```sh
|
|
@@ -10,6 +10,7 @@ A Python CLI for [NetBox](https://netbox.dev/) that builds its command tree dyna
|
|
|
10
10
|
- **Multi-instance.** Named profiles per NetBox instance, plus env-var overrides.
|
|
11
11
|
- **Safe by default.** POST/PATCH/PUT/DELETE preview as dry-runs unless you pass `--apply`.
|
|
12
12
|
- **Agent-friendly.** Deterministic command shape, machine-readable JSON output, stable error envelope with documented exit codes.
|
|
13
|
+
- **Interactive TUI.** `nsc tui` opens a keyboard-driven terminal UI — see below.
|
|
13
14
|
|
|
14
15
|
## Install
|
|
15
16
|
|
|
@@ -27,6 +28,26 @@ uv sync
|
|
|
27
28
|
uv run nsc --version
|
|
28
29
|
```
|
|
29
30
|
|
|
31
|
+
## Interactive TUI
|
|
32
|
+
|
|
33
|
+
`nsc tui` (aliases `nsc interactive`, `nsc i`) opens a full-screen,
|
|
34
|
+
keyboard-driven UI over your NetBox — browse, filter, edit, bulk-edit and search
|
|
35
|
+
across object types without writing a command. Like the CLI it is generated from
|
|
36
|
+
the live schema, so it works for every resource and plugin.
|
|
37
|
+
|
|
38
|
+

|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
nsc tui # land on the resource picker
|
|
42
|
+
nsc tui devices # jump straight into the devices list
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Highlights: a collapsible resource picker, a web-UI-style filter builder (`/`),
|
|
46
|
+
inline record editing with a confirm-diff save, schema-derived relationship
|
|
47
|
+
drill-down, bulk edit with a per-record preview, a persisted column chooser
|
|
48
|
+
(`f`), and global search (`Ctrl`+`F`). Full walkthrough in the
|
|
49
|
+
[Interactive TUI guide](https://thomaschristory.github.io/netbox-super-cli/guides/interactive-tui/).
|
|
50
|
+
|
|
30
51
|
## Reading
|
|
31
52
|
|
|
32
53
|
```sh
|
|
@@ -42,19 +42,22 @@ Each line of `audit.jsonl` is a JSON object with:
|
|
|
42
42
|
|
|
43
43
|
- `schema_version`, `timestamp` (UTC ISO8601, `…Z`)
|
|
44
44
|
- `operation_id`, `method`, `url`
|
|
45
|
-
- `request.headers` (sensitive headers
|
|
46
|
-
|
|
45
|
+
- `request.headers` (sensitive headers — `Authorization`, `Cookie`,
|
|
46
|
+
`Set-Cookie`, `X-API-Key`, `Proxy-Authorization` — rewritten to
|
|
47
|
+
`"<redacted>"`; the key stays, the value is masked)
|
|
47
48
|
- `request.query`, `request.body` (sensitive `sensitive_paths` fields
|
|
48
49
|
rewritten to `"<redacted>"`); bodies over 256 KB collapse to
|
|
49
50
|
`{"_truncated": true, "_size_bytes": N}` with `request.body_truncated`
|
|
50
|
-
- `response.status_code`, `response.headers
|
|
51
|
+
- `response.status_code`, `response.headers` (redacted with the same
|
|
52
|
+
sensitive-header set as the request side), `response.body` (same
|
|
51
53
|
256 KB truncation via `response.body_truncated`); `response` is `null`
|
|
52
54
|
on a transport failure
|
|
53
55
|
- `duration_ms`, `attempt_n`, `final_attempt`, `error_kind`
|
|
54
56
|
- `dry_run`, `preflight_blocked`, `record_indices`, `applied`, `explain`
|
|
55
57
|
|
|
56
|
-
The audit file is append-only and rotates to `audit.jsonl.1` at 10 MB;
|
|
57
|
-
failed writes do
|
|
58
|
+
The audit file is append-only and rotates to `audit.jsonl.1` at 10 MB; it is
|
|
59
|
+
created owner-only (`0600`) inside a `0700` logs directory, and failed writes do
|
|
60
|
+
NOT unredact. See
|
|
58
61
|
[Writes and safety](../guides/writes-and-safety.md) for the full redaction
|
|
59
62
|
contract.
|
|
60
63
|
|
|
@@ -17,7 +17,11 @@ and an optional `--refresh-schema` override:
|
|
|
17
17
|
3. Live fetch from the active profile's `schema_url` (explicit) or
|
|
18
18
|
`{profile.url}/api/schema/?format=json`. The fetched body is hashed;
|
|
19
19
|
if a cache file already exists at that hash it's loaded directly,
|
|
20
|
-
otherwise the command-model is rebuilt and saved.
|
|
20
|
+
otherwise the command-model is rebuilt and saved. The fetch is bounded:
|
|
21
|
+
the loader streams raw wire bytes under a 64 MB cap, requests
|
|
22
|
+
`Accept-Encoding: identity`, and any `.gz`/`Content-Encoding` body is
|
|
23
|
+
decompressed incrementally to the same cap — so an oversized or
|
|
24
|
+
decompression-bomb schema is rejected rather than exhausting memory.
|
|
21
25
|
4. On fetch failure: the newest valid cached entry for the profile
|
|
22
26
|
(warns once on stderr), sorted by mtime.
|
|
23
27
|
5. Bundled snapshot — the **last (newest) entry** in
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
<svg class="rich-terminal" viewBox="0 0 1385 830.8" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<!-- Generated with Rich https://www.textualize.io -->
|
|
3
|
+
<style>
|
|
4
|
+
|
|
5
|
+
@font-face {
|
|
6
|
+
font-family: "Fira Code";
|
|
7
|
+
src: local("FiraCode-Regular"),
|
|
8
|
+
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2") format("woff2"),
|
|
9
|
+
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff") format("woff");
|
|
10
|
+
font-style: normal;
|
|
11
|
+
font-weight: 400;
|
|
12
|
+
}
|
|
13
|
+
@font-face {
|
|
14
|
+
font-family: "Fira Code";
|
|
15
|
+
src: local("FiraCode-Bold"),
|
|
16
|
+
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Bold.woff2") format("woff2"),
|
|
17
|
+
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Bold.woff") format("woff");
|
|
18
|
+
font-style: bold;
|
|
19
|
+
font-weight: 700;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.terminal-3309028997-matrix {
|
|
23
|
+
font-family: Fira Code, monospace;
|
|
24
|
+
font-size: 20px;
|
|
25
|
+
line-height: 24.4px;
|
|
26
|
+
font-variant-east-asian: full-width;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.terminal-3309028997-title {
|
|
30
|
+
font-size: 18px;
|
|
31
|
+
font-weight: bold;
|
|
32
|
+
font-family: arial;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.terminal-3309028997-r1 { fill: #c5c8c6 }
|
|
36
|
+
.terminal-3309028997-r2 { fill: #e0e0e0 }
|
|
37
|
+
.terminal-3309028997-r3 { fill: #e0e0e0;font-weight: bold }
|
|
38
|
+
.terminal-3309028997-r4 { fill: #272727 }
|
|
39
|
+
.terminal-3309028997-r5 { fill: #ddedf9;font-weight: bold }
|
|
40
|
+
.terminal-3309028997-r6 { fill: #000000 }
|
|
41
|
+
.terminal-3309028997-r7 { fill: #797979 }
|
|
42
|
+
.terminal-3309028997-r8 { fill: #262626 }
|
|
43
|
+
.terminal-3309028997-r9 { fill: #0178d4 }
|
|
44
|
+
.terminal-3309028997-r10 { fill: #ffa62b;font-weight: bold }
|
|
45
|
+
</style>
|
|
46
|
+
|
|
47
|
+
<defs>
|
|
48
|
+
<clipPath id="terminal-3309028997-clip-terminal">
|
|
49
|
+
<rect x="0" y="0" width="1365.3999999999999" height="779.8" />
|
|
50
|
+
</clipPath>
|
|
51
|
+
<clipPath id="terminal-3309028997-line-0">
|
|
52
|
+
<rect x="0" y="1.5" width="1366.4" height="24.65"/>
|
|
53
|
+
</clipPath>
|
|
54
|
+
<clipPath id="terminal-3309028997-line-1">
|
|
55
|
+
<rect x="0" y="25.9" width="1366.4" height="24.65"/>
|
|
56
|
+
</clipPath>
|
|
57
|
+
<clipPath id="terminal-3309028997-line-2">
|
|
58
|
+
<rect x="0" y="50.3" width="1366.4" height="24.65"/>
|
|
59
|
+
</clipPath>
|
|
60
|
+
<clipPath id="terminal-3309028997-line-3">
|
|
61
|
+
<rect x="0" y="74.7" width="1366.4" height="24.65"/>
|
|
62
|
+
</clipPath>
|
|
63
|
+
<clipPath id="terminal-3309028997-line-4">
|
|
64
|
+
<rect x="0" y="99.1" width="1366.4" height="24.65"/>
|
|
65
|
+
</clipPath>
|
|
66
|
+
<clipPath id="terminal-3309028997-line-5">
|
|
67
|
+
<rect x="0" y="123.5" width="1366.4" height="24.65"/>
|
|
68
|
+
</clipPath>
|
|
69
|
+
<clipPath id="terminal-3309028997-line-6">
|
|
70
|
+
<rect x="0" y="147.9" width="1366.4" height="24.65"/>
|
|
71
|
+
</clipPath>
|
|
72
|
+
<clipPath id="terminal-3309028997-line-7">
|
|
73
|
+
<rect x="0" y="172.3" width="1366.4" height="24.65"/>
|
|
74
|
+
</clipPath>
|
|
75
|
+
<clipPath id="terminal-3309028997-line-8">
|
|
76
|
+
<rect x="0" y="196.7" width="1366.4" height="24.65"/>
|
|
77
|
+
</clipPath>
|
|
78
|
+
<clipPath id="terminal-3309028997-line-9">
|
|
79
|
+
<rect x="0" y="221.1" width="1366.4" height="24.65"/>
|
|
80
|
+
</clipPath>
|
|
81
|
+
<clipPath id="terminal-3309028997-line-10">
|
|
82
|
+
<rect x="0" y="245.5" width="1366.4" height="24.65"/>
|
|
83
|
+
</clipPath>
|
|
84
|
+
<clipPath id="terminal-3309028997-line-11">
|
|
85
|
+
<rect x="0" y="269.9" width="1366.4" height="24.65"/>
|
|
86
|
+
</clipPath>
|
|
87
|
+
<clipPath id="terminal-3309028997-line-12">
|
|
88
|
+
<rect x="0" y="294.3" width="1366.4" height="24.65"/>
|
|
89
|
+
</clipPath>
|
|
90
|
+
<clipPath id="terminal-3309028997-line-13">
|
|
91
|
+
<rect x="0" y="318.7" width="1366.4" height="24.65"/>
|
|
92
|
+
</clipPath>
|
|
93
|
+
<clipPath id="terminal-3309028997-line-14">
|
|
94
|
+
<rect x="0" y="343.1" width="1366.4" height="24.65"/>
|
|
95
|
+
</clipPath>
|
|
96
|
+
<clipPath id="terminal-3309028997-line-15">
|
|
97
|
+
<rect x="0" y="367.5" width="1366.4" height="24.65"/>
|
|
98
|
+
</clipPath>
|
|
99
|
+
<clipPath id="terminal-3309028997-line-16">
|
|
100
|
+
<rect x="0" y="391.9" width="1366.4" height="24.65"/>
|
|
101
|
+
</clipPath>
|
|
102
|
+
<clipPath id="terminal-3309028997-line-17">
|
|
103
|
+
<rect x="0" y="416.3" width="1366.4" height="24.65"/>
|
|
104
|
+
</clipPath>
|
|
105
|
+
<clipPath id="terminal-3309028997-line-18">
|
|
106
|
+
<rect x="0" y="440.7" width="1366.4" height="24.65"/>
|
|
107
|
+
</clipPath>
|
|
108
|
+
<clipPath id="terminal-3309028997-line-19">
|
|
109
|
+
<rect x="0" y="465.1" width="1366.4" height="24.65"/>
|
|
110
|
+
</clipPath>
|
|
111
|
+
<clipPath id="terminal-3309028997-line-20">
|
|
112
|
+
<rect x="0" y="489.5" width="1366.4" height="24.65"/>
|
|
113
|
+
</clipPath>
|
|
114
|
+
<clipPath id="terminal-3309028997-line-21">
|
|
115
|
+
<rect x="0" y="513.9" width="1366.4" height="24.65"/>
|
|
116
|
+
</clipPath>
|
|
117
|
+
<clipPath id="terminal-3309028997-line-22">
|
|
118
|
+
<rect x="0" y="538.3" width="1366.4" height="24.65"/>
|
|
119
|
+
</clipPath>
|
|
120
|
+
<clipPath id="terminal-3309028997-line-23">
|
|
121
|
+
<rect x="0" y="562.7" width="1366.4" height="24.65"/>
|
|
122
|
+
</clipPath>
|
|
123
|
+
<clipPath id="terminal-3309028997-line-24">
|
|
124
|
+
<rect x="0" y="587.1" width="1366.4" height="24.65"/>
|
|
125
|
+
</clipPath>
|
|
126
|
+
<clipPath id="terminal-3309028997-line-25">
|
|
127
|
+
<rect x="0" y="611.5" width="1366.4" height="24.65"/>
|
|
128
|
+
</clipPath>
|
|
129
|
+
<clipPath id="terminal-3309028997-line-26">
|
|
130
|
+
<rect x="0" y="635.9" width="1366.4" height="24.65"/>
|
|
131
|
+
</clipPath>
|
|
132
|
+
<clipPath id="terminal-3309028997-line-27">
|
|
133
|
+
<rect x="0" y="660.3" width="1366.4" height="24.65"/>
|
|
134
|
+
</clipPath>
|
|
135
|
+
<clipPath id="terminal-3309028997-line-28">
|
|
136
|
+
<rect x="0" y="684.7" width="1366.4" height="24.65"/>
|
|
137
|
+
</clipPath>
|
|
138
|
+
<clipPath id="terminal-3309028997-line-29">
|
|
139
|
+
<rect x="0" y="709.1" width="1366.4" height="24.65"/>
|
|
140
|
+
</clipPath>
|
|
141
|
+
<clipPath id="terminal-3309028997-line-30">
|
|
142
|
+
<rect x="0" y="733.5" width="1366.4" height="24.65"/>
|
|
143
|
+
</clipPath>
|
|
144
|
+
</defs>
|
|
145
|
+
|
|
146
|
+
<rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="1383" height="828.8" rx="8"/><text class="terminal-3309028997-title" fill="#c5c8c6" text-anchor="middle" x="691" y="27">nsc tui</text>
|
|
147
|
+
<g transform="translate(26,22)">
|
|
148
|
+
<circle cx="0" cy="0" r="7" fill="#ff5f57"/>
|
|
149
|
+
<circle cx="22" cy="0" r="7" fill="#febc2e"/>
|
|
150
|
+
<circle cx="44" cy="0" r="7" fill="#28c840"/>
|
|
151
|
+
</g>
|
|
152
|
+
|
|
153
|
+
<g transform="translate(9, 41)" clip-path="url(#terminal-3309028997-clip-terminal)">
|
|
154
|
+
<rect fill="#242f38" x="0" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="12.2" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="24.4" y="1.5" width="61" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="85.4" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="97.6" y="1.5" width="500.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="597.8" y="1.5" width="146.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="744.2" y="1.5" width="500.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="1244.4" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="1256.6" y="1.5" width="0" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="1256.6" y="1.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="1354.2" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d3740" x="0" y="25.9" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d3740" x="244" y="25.9" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d3740" x="475.8" y="25.9" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="25.9" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#0178d4" x="0" y="50.3" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#0178d4" x="244" y="50.3" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#0178d4" x="475.8" y="50.3" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="50.3" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="74.7" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="74.7" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="74.7" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="74.7" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="99.1" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="99.1" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="99.1" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="99.1" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="123.5" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="123.5" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="123.5" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="123.5" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="147.9" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="147.9" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="147.9" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="147.9" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="172.3" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="172.3" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="172.3" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="172.3" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="196.7" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="196.7" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="196.7" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="196.7" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="221.1" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="221.1" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="221.1" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="221.1" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="245.5" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="245.5" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="245.5" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="245.5" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="269.9" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="269.9" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="269.9" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="269.9" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="294.3" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="294.3" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="294.3" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="294.3" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="318.7" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="318.7" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="318.7" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="318.7" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="343.1" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="343.1" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="343.1" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="343.1" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="367.5" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="367.5" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="367.5" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="367.5" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="391.9" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="391.9" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="391.9" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="391.9" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="416.3" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="416.3" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="416.3" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="416.3" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="440.7" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="440.7" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="440.7" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="440.7" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="465.1" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="465.1" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="465.1" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="465.1" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="489.5" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="489.5" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="489.5" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="489.5" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="513.9" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="513.9" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="513.9" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="513.9" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="538.3" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="538.3" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="538.3" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="538.3" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="562.7" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="562.7" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="562.7" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="562.7" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="587.1" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="587.1" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="587.1" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="587.1" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="611.5" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="611.5" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="611.5" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#000000" x="1342" y="611.5" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="635.9" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="635.9" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="635.9" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#000000" x="1342" y="635.9" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="660.3" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="660.3" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="660.3" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#000000" x="1342" y="660.3" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="684.7" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="684.7" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="684.7" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#000000" x="1342" y="684.7" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="0" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="12.2" y="709.1" width="73.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="85.4" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="97.6" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="109.8" y="709.1" width="158.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="268.4" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="280.6" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="292.8" y="709.1" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="536.8" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="549" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="561.2" y="709.1" width="134.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="695.4" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="707.6" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="719.8" y="709.1" width="134.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="854" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="866.2" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="878.4" y="709.1" width="122" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="1000.4" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="1012.6" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="1024.8" y="709.1" width="183" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="1207.8" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="1220" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="1232.2" y="709.1" width="134.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="0" y="733.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="12.2" y="733.5" width="73.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="85.4" y="733.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="97.6" y="733.5" width="1268.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="0" y="757.9" width="61" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="61" y="757.9" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="170.8" y="757.9" width="134.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="305" y="757.9" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="414.8" y="757.9" width="36.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="451.4" y="757.9" width="61" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="512.4" y="757.9" width="36.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="549" y="757.9" width="61" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="610" y="757.9" width="48.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="658.8" y="757.9" width="170.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="829.6" y="757.9" width="48.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="878.4" y="757.9" width="85.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="963.8" y="757.9" width="61" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="1024.8" y="757.9" width="61" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="1085.8" y="757.9" width="36.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="1122.4" y="757.9" width="134.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="1256.6" y="757.9" width="36.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="1293.2" y="757.9" width="73.2" height="24.65" shape-rendering="crispEdges"/>
|
|
155
|
+
<g class="terminal-3309028997-matrix">
|
|
156
|
+
<text class="terminal-3309028997-r2" x="12.2" y="20" textLength="12.2" clip-path="url(#terminal-3309028997-line-0)">⭘</text><text class="terminal-3309028997-r2" x="597.8" y="20" textLength="146.4" clip-path="url(#terminal-3309028997-line-0)">devices #111</text><text class="terminal-3309028997-r1" x="1366.4" y="20" textLength="12.2" clip-path="url(#terminal-3309028997-line-0)">
|
|
157
|
+
</text><text class="terminal-3309028997-r3" x="0" y="44.4" textLength="244" clip-path="url(#terminal-3309028997-line-1)"> field              </text><text class="terminal-3309028997-r3" x="244" y="44.4" textLength="231.8" clip-path="url(#terminal-3309028997-line-1)"> value             </text><text class="terminal-3309028997-r1" x="1366.4" y="44.4" textLength="12.2" clip-path="url(#terminal-3309028997-line-1)">
|
|
158
|
+
</text><text class="terminal-3309028997-r5" x="0" y="68.8" textLength="244" clip-path="url(#terminal-3309028997-line-2)"> name               </text><text class="terminal-3309028997-r5" x="244" y="68.8" textLength="231.8" clip-path="url(#terminal-3309028997-line-2)"> dmi01-akron-pdu01 </text><text class="terminal-3309028997-r1" x="1366.4" y="68.8" textLength="12.2" clip-path="url(#terminal-3309028997-line-2)">
|
|
159
|
+
</text><text class="terminal-3309028997-r2" x="0" y="93.2" textLength="244" clip-path="url(#terminal-3309028997-line-3)"> device_type        </text><text class="terminal-3309028997-r1" x="1366.4" y="93.2" textLength="12.2" clip-path="url(#terminal-3309028997-line-3)">
|
|
160
|
+
</text><text class="terminal-3309028997-r2" x="0" y="117.6" textLength="244" clip-path="url(#terminal-3309028997-line-4)"> role               </text><text class="terminal-3309028997-r2" x="244" y="117.6" textLength="231.8" clip-path="url(#terminal-3309028997-line-4)"> PDU               </text><text class="terminal-3309028997-r1" x="1366.4" y="117.6" textLength="12.2" clip-path="url(#terminal-3309028997-line-4)">
|
|
161
|
+
</text><text class="terminal-3309028997-r2" x="0" y="142" textLength="244" clip-path="url(#terminal-3309028997-line-5)"> tenant             </text><text class="terminal-3309028997-r1" x="1366.4" y="142" textLength="12.2" clip-path="url(#terminal-3309028997-line-5)">
|
|
162
|
+
</text><text class="terminal-3309028997-r2" x="0" y="166.4" textLength="244" clip-path="url(#terminal-3309028997-line-6)"> platform           </text><text class="terminal-3309028997-r1" x="1366.4" y="166.4" textLength="12.2" clip-path="url(#terminal-3309028997-line-6)">
|
|
163
|
+
</text><text class="terminal-3309028997-r2" x="0" y="190.8" textLength="244" clip-path="url(#terminal-3309028997-line-7)"> serial             </text><text class="terminal-3309028997-r2" x="244" y="190.8" textLength="231.8" clip-path="url(#terminal-3309028997-line-7)"> 6457-2371         </text><text class="terminal-3309028997-r1" x="1366.4" y="190.8" textLength="12.2" clip-path="url(#terminal-3309028997-line-7)">
|
|
164
|
+
</text><text class="terminal-3309028997-r2" x="0" y="215.2" textLength="244" clip-path="url(#terminal-3309028997-line-8)"> asset_tag          </text><text class="terminal-3309028997-r1" x="1366.4" y="215.2" textLength="12.2" clip-path="url(#terminal-3309028997-line-8)">
|
|
165
|
+
</text><text class="terminal-3309028997-r2" x="0" y="239.6" textLength="244" clip-path="url(#terminal-3309028997-line-9)"> site               </text><text class="terminal-3309028997-r2" x="244" y="239.6" textLength="231.8" clip-path="url(#terminal-3309028997-line-9)"> DM-Akron          </text><text class="terminal-3309028997-r1" x="1366.4" y="239.6" textLength="12.2" clip-path="url(#terminal-3309028997-line-9)">
|
|
166
|
+
</text><text class="terminal-3309028997-r2" x="0" y="264" textLength="244" clip-path="url(#terminal-3309028997-line-10)"> location           </text><text class="terminal-3309028997-r1" x="1366.4" y="264" textLength="12.2" clip-path="url(#terminal-3309028997-line-10)">
|
|
167
|
+
</text><text class="terminal-3309028997-r2" x="0" y="288.4" textLength="244" clip-path="url(#terminal-3309028997-line-11)"> rack               </text><text class="terminal-3309028997-r1" x="1366.4" y="288.4" textLength="12.2" clip-path="url(#terminal-3309028997-line-11)">
|
|
168
|
+
</text><text class="terminal-3309028997-r2" x="0" y="312.8" textLength="244" clip-path="url(#terminal-3309028997-line-12)"> position           </text><text class="terminal-3309028997-r1" x="1366.4" y="312.8" textLength="12.2" clip-path="url(#terminal-3309028997-line-12)">
|
|
169
|
+
</text><text class="terminal-3309028997-r2" x="0" y="337.2" textLength="244" clip-path="url(#terminal-3309028997-line-13)"> face               </text><text class="terminal-3309028997-r1" x="1366.4" y="337.2" textLength="12.2" clip-path="url(#terminal-3309028997-line-13)">
|
|
170
|
+
</text><text class="terminal-3309028997-r2" x="0" y="361.6" textLength="244" clip-path="url(#terminal-3309028997-line-14)"> latitude           </text><text class="terminal-3309028997-r1" x="1366.4" y="361.6" textLength="12.2" clip-path="url(#terminal-3309028997-line-14)">
|
|
171
|
+
</text><text class="terminal-3309028997-r2" x="0" y="386" textLength="244" clip-path="url(#terminal-3309028997-line-15)"> longitude          </text><text class="terminal-3309028997-r1" x="1366.4" y="386" textLength="12.2" clip-path="url(#terminal-3309028997-line-15)">
|
|
172
|
+
</text><text class="terminal-3309028997-r2" x="0" y="410.4" textLength="244" clip-path="url(#terminal-3309028997-line-16)"> status             </text><text class="terminal-3309028997-r1" x="1366.4" y="410.4" textLength="12.2" clip-path="url(#terminal-3309028997-line-16)">
|
|
173
|
+
</text><text class="terminal-3309028997-r2" x="0" y="434.8" textLength="244" clip-path="url(#terminal-3309028997-line-17)"> airflow            </text><text class="terminal-3309028997-r1" x="1366.4" y="434.8" textLength="12.2" clip-path="url(#terminal-3309028997-line-17)">
|
|
174
|
+
</text><text class="terminal-3309028997-r2" x="0" y="459.2" textLength="244" clip-path="url(#terminal-3309028997-line-18)"> primary_ip4        </text><text class="terminal-3309028997-r1" x="1366.4" y="459.2" textLength="12.2" clip-path="url(#terminal-3309028997-line-18)">
|
|
175
|
+
</text><text class="terminal-3309028997-r2" x="0" y="483.6" textLength="244" clip-path="url(#terminal-3309028997-line-19)"> primary_ip6        </text><text class="terminal-3309028997-r1" x="1366.4" y="483.6" textLength="12.2" clip-path="url(#terminal-3309028997-line-19)">
|
|
176
|
+
</text><text class="terminal-3309028997-r2" x="0" y="508" textLength="244" clip-path="url(#terminal-3309028997-line-20)"> oob_ip             </text><text class="terminal-3309028997-r1" x="1366.4" y="508" textLength="12.2" clip-path="url(#terminal-3309028997-line-20)">
|
|
177
|
+
</text><text class="terminal-3309028997-r2" x="0" y="532.4" textLength="244" clip-path="url(#terminal-3309028997-line-21)"> cluster            </text><text class="terminal-3309028997-r1" x="1366.4" y="532.4" textLength="12.2" clip-path="url(#terminal-3309028997-line-21)">
|
|
178
|
+
</text><text class="terminal-3309028997-r2" x="0" y="556.8" textLength="244" clip-path="url(#terminal-3309028997-line-22)"> virtual_chassis    </text><text class="terminal-3309028997-r1" x="1366.4" y="556.8" textLength="12.2" clip-path="url(#terminal-3309028997-line-22)">
|
|
179
|
+
</text><text class="terminal-3309028997-r2" x="0" y="581.2" textLength="244" clip-path="url(#terminal-3309028997-line-23)"> vc_position        </text><text class="terminal-3309028997-r1" x="1366.4" y="581.2" textLength="12.2" clip-path="url(#terminal-3309028997-line-23)">
|
|
180
|
+
</text><text class="terminal-3309028997-r2" x="0" y="605.6" textLength="244" clip-path="url(#terminal-3309028997-line-24)"> vc_priority        </text><text class="terminal-3309028997-r6" x="1342" y="605.6" textLength="24.4" clip-path="url(#terminal-3309028997-line-24)">▁▁</text><text class="terminal-3309028997-r1" x="1366.4" y="605.6" textLength="12.2" clip-path="url(#terminal-3309028997-line-24)">
|
|
181
|
+
</text><text class="terminal-3309028997-r2" x="0" y="630" textLength="244" clip-path="url(#terminal-3309028997-line-25)"> description        </text><text class="terminal-3309028997-r1" x="1366.4" y="630" textLength="12.2" clip-path="url(#terminal-3309028997-line-25)">
|
|
182
|
+
</text><text class="terminal-3309028997-r2" x="0" y="654.4" textLength="244" clip-path="url(#terminal-3309028997-line-26)"> owner              </text><text class="terminal-3309028997-r1" x="1366.4" y="654.4" textLength="12.2" clip-path="url(#terminal-3309028997-line-26)">
|
|
183
|
+
</text><text class="terminal-3309028997-r2" x="0" y="678.8" textLength="244" clip-path="url(#terminal-3309028997-line-27)"> comments           </text><text class="terminal-3309028997-r1" x="1366.4" y="678.8" textLength="12.2" clip-path="url(#terminal-3309028997-line-27)">
|
|
184
|
+
</text><text class="terminal-3309028997-r2" x="0" y="703.2" textLength="244" clip-path="url(#terminal-3309028997-line-28)"> config_template    </text><text class="terminal-3309028997-r1" x="1366.4" y="703.2" textLength="12.2" clip-path="url(#terminal-3309028997-line-28)">
|
|
185
|
+
</text><text class="terminal-3309028997-r2" x="12.2" y="727.6" textLength="73.2" clip-path="url(#terminal-3309028997-line-29)">cables</text><text class="terminal-3309028997-r7" x="109.8" y="727.6" textLength="158.6" clip-path="url(#terminal-3309028997-line-29)">console-ports</text><text class="terminal-3309028997-r7" x="292.8" y="727.6" textLength="244" clip-path="url(#terminal-3309028997-line-29)">console-server-ports</text><text class="terminal-3309028997-r7" x="561.2" y="727.6" textLength="134.2" clip-path="url(#terminal-3309028997-line-29)">device-bays</text><text class="terminal-3309028997-r7" x="719.8" y="727.6" textLength="134.2" clip-path="url(#terminal-3309028997-line-29)">front-ports</text><text class="terminal-3309028997-r7" x="878.4" y="727.6" textLength="122" clip-path="url(#terminal-3309028997-line-29)">interfaces</text><text class="terminal-3309028997-r7" x="1024.8" y="727.6" textLength="183" clip-path="url(#terminal-3309028997-line-29)">inventory-items</text><text class="terminal-3309028997-r7" x="1232.2" y="727.6" textLength="134.2" clip-path="url(#terminal-3309028997-line-29)">mac-address</text><text class="terminal-3309028997-r1" x="1366.4" y="727.6" textLength="12.2" clip-path="url(#terminal-3309028997-line-29)">
|
|
186
|
+
</text><text class="terminal-3309028997-r8" x="0" y="752" textLength="12.2" clip-path="url(#terminal-3309028997-line-30)">╸</text><text class="terminal-3309028997-r9" x="12.2" y="752" textLength="73.2" clip-path="url(#terminal-3309028997-line-30)">━━━━━━</text><text class="terminal-3309028997-r8" x="85.4" y="752" textLength="12.2" clip-path="url(#terminal-3309028997-line-30)">╺</text><text class="terminal-3309028997-r8" x="97.6" y="752" textLength="1268.8" clip-path="url(#terminal-3309028997-line-30)">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text class="terminal-3309028997-r1" x="1366.4" y="752" textLength="12.2" clip-path="url(#terminal-3309028997-line-30)">
|
|
187
|
+
</text><text class="terminal-3309028997-r10" x="0" y="776.4" textLength="61" clip-path="url(#terminal-3309028997-line-31)"> tab </text><text class="terminal-3309028997-r2" x="61" y="776.4" textLength="109.8" clip-path="url(#terminal-3309028997-line-31)">Next tab </text><text class="terminal-3309028997-r10" x="170.8" y="776.4" textLength="134.2" clip-path="url(#terminal-3309028997-line-31)"> shift+tab </text><text class="terminal-3309028997-r2" x="305" y="776.4" textLength="109.8" clip-path="url(#terminal-3309028997-line-31)">Prev tab </text><text class="terminal-3309028997-r10" x="414.8" y="776.4" textLength="36.6" clip-path="url(#terminal-3309028997-line-31)"> q </text><text class="terminal-3309028997-r2" x="451.4" y="776.4" textLength="61" clip-path="url(#terminal-3309028997-line-31)">Quit </text><text class="terminal-3309028997-r10" x="512.4" y="776.4" textLength="36.6" clip-path="url(#terminal-3309028997-line-31)"> ? </text><text class="terminal-3309028997-r2" x="549" y="776.4" textLength="61" clip-path="url(#terminal-3309028997-line-31)">Help </text><text class="terminal-3309028997-r10" x="610" y="776.4" textLength="48.8" clip-path="url(#terminal-3309028997-line-31)"> ^p </text><text class="terminal-3309028997-r2" x="658.8" y="776.4" textLength="170.8" clip-path="url(#terminal-3309028997-line-31)">Find resource </text><text class="terminal-3309028997-r10" x="829.6" y="776.4" textLength="48.8" clip-path="url(#terminal-3309028997-line-31)"> ^f </text><text class="terminal-3309028997-r2" x="878.4" y="776.4" textLength="85.4" clip-path="url(#terminal-3309028997-line-31)">Search </text><text class="terminal-3309028997-r10" x="963.8" y="776.4" textLength="61" clip-path="url(#terminal-3309028997-line-31)"> esc </text><text class="terminal-3309028997-r2" x="1024.8" y="776.4" textLength="61" clip-path="url(#terminal-3309028997-line-31)">Back </text><text class="terminal-3309028997-r10" x="1085.8" y="776.4" textLength="36.6" clip-path="url(#terminal-3309028997-line-31)"> e </text><text class="terminal-3309028997-r2" x="1122.4" y="776.4" textLength="134.2" clip-path="url(#terminal-3309028997-line-31)">Edit field </text><text class="terminal-3309028997-r10" x="1256.6" y="776.4" textLength="36.6" clip-path="url(#terminal-3309028997-line-31)"> s </text><text class="terminal-3309028997-r2" x="1293.2" y="776.4" textLength="73.2" clip-path="url(#terminal-3309028997-line-31)">Save c</text>
|
|
188
|
+
</g>
|
|
189
|
+
</g>
|
|
190
|
+
</svg>
|