Repository navigation
Consolidate truenas, proxmox and unifi plugins into one marketplace - #1
Merged
Merged
Conversation
Claude Code plugin (marketplace layout) with one skill, unifi-ops: - scripts/unifi.py: stdlib-only CLI over the UniFi Network Integration API and Site Manager API, with pagination, filters, mock mode and a --yes write guard - scripts/ssh_diag.sh: read-only SSH diagnostics bundle - references: API cheat sheets, SSH commands, troubleshooting playbooks - evals: test prompts, mock fixtures and a mock HTTP server Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SfC3NrzAJoJN4enwxr6opx
- tables carry id and uplink device name so one list call serves reading and follow-up commands - report health includes per-radio txRetriesPct for AP comparison - wired clients get an explicit note that the switch port is not exposed - SKILL.md gains a one-screen command surface instead of per-group --help - playbooks/API gaps: client->port mapping, firmware upgrade, mca-dump Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SfC3NrzAJoJN4enwxr6opx
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SfC3NrzAJoJN4enwxr6opx
Claude Code plugin with a single skill that operates a TrueNAS SCALE 25.x system over the JSON-RPC websocket API (via the official truenas_api_client) and SSH. - skills/truenas/SKILL.md: workflow, discover-before-call rule, job handling, confirm-destructive safety policy, SSH diagnostics, reporting guidance - scripts/tn.py: info | call | methods | jobs | query helper with a code-level gate that refuses destructive methods without --confirm - scripts/setup.sh: installs the client into a private virtualenv - references/: cheat sheets for storage, sharing, apps, system, API basics - tests/: offline unit tests plus end-to-end tests against a fake middleware - evals/evals.json: example prompts for skill evaluation Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014jXNHcVCpS5ch9a5L594j8
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFKwcDK4uJnKCCf6od43tV
… docs Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFKwcDK4uJnKCCf6od43tV
…ock-backed tests Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFKwcDK4uJnKCCf6od43tV
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFKwcDK4uJnKCCf6od43tV
…recipe Addresses the static review from the Homelab session: - tn.py: new `host` subcommand prints the bare hostname so SKILL.md no longer pastes a URI- or port-bearing TRUENAS_HOST into ssh - tn.py: connection failures now carry a `cause` (timeout, certificate, refused, dns) with a cause-specific hint instead of a generic string - SKILL.md: exit-code-1 taxonomy for those causes; SSH examples use a derived SSH_TARGET - api-basics.md: "Reaching a NAS on another VLAN" with the ssh -L recipe, certificate caveats, and the run-on-jump-host alternative - README: private-repo clone via gh or SSH; honest verification status (fake middleware only so far, Python 3.14 untested, live target 25.10.6) - tests: bare_host, classify_connection_error, host subcommand, refused port classification (26 tests) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014jXNHcVCpS5ch9a5L594j8
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFKwcDK4uJnKCCf6od43tV
- cloud commands read UNIFI_CLOUD_API_KEY or UNIFI_SITE_MANAGER_API_KEY and say plainly that the local Integration key is a different credential - README: marketplace add over HTTPS has no credential while the repo is private, so clone with gh/SSH and add the local path Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SfC3NrzAJoJN4enwxr6opx
- remove 'devices locate': the Integration API accepts only RESTART on
/devices/{id}/actions and the dry run cannot detect an invalid enum
- --table hides columns the live list endpoints leave empty (uplink on
devices, security/networkId on wifi, enabled/type on wans)
- report health emits numeric per-band txRetriesPct_2g/5g/6g columns
- firewall policy table shows action.type (action is an object on 10.6)
- references: observed behaviour section, Integration vs v2/legacy id
spaces, differing version fields; README live checklist updated
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SfC3NrzAJoJN4enwxr6opx
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFKwcDK4uJnKCCf6od43tV
…transport Skills should not need an install step, so tn.py no longer depends on truenas_api_client. It now carries: - a minimal RFC 6455 websocket client (handshake, masking, fragmentation, ping/pong, close) speaking JSON-RPC 2.0, with legacy-style job waiting via core.get_jobs events - an ssh transport that runs `midclt call` on the NAS, JSON-quotes arguments, adds `sudo -n` for non-root users, honours TRUENAS_SSH_OPTS (e.g. a jump host), and maps midclt stderr to the same error JSON - transport selection: ws when TRUENAS_API_KEY is set, else ssh; TRUENAS_TRANSPORT / --transport override setup.sh and requirements.txt are removed. SKILL.md, api-basics.md and README describe the two transports; the VLAN section now recommends the ssh transport over a port-forward. Tests: 52 (codec round-trips, RFC accept-key vector, error mapping, ssh argv building, midclt stderr parsing, transport choice; end-to-end over the fake middleware and a fake ssh/midclt, including large responses, failed jobs, sudo handling and unreachable hosts). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014jXNHcVCpS5ch9a5L594j8
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFKwcDK4uJnKCCf6od43tV
…, URL base, TLS warning dedupe, fixtures) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFKwcDK4uJnKCCf6od43tV
…(v0.2.0) - unifi.py redacts credential-shaped keys (passphrase, password, secret, psk, private key, api key) in all printed output, including dry-run bodies, unless --show-secrets is passed: wifi get returns the WPA passphrase in cleartext on 10.6.106 - firewall policies ordering/reorder take --source-zone (required by the API as sourceFirewallZoneId) and optional --dest-zone - wifi table columns use securityConfiguration.type and network.networkId as returned live; fixtures updated to that shape - references: observed SSID/device/wans shapes, ordering parameter, WAN telemetry caveat; SKILL.md: secrets handling section - bump plugin and marketplace version to 0.2.0 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SfC3NrzAJoJN4enwxr6opx
TrueNAS returns secrets in ordinary query results: cloud sync and SSH credential attributes, alert service tokens, app config passwords, SMB and SNMP passwords, exported dataset keys, and job arguments. Stripping them in the tool is more reliable than asking the agent to notice at report time. - values under credential-looking keys (password, secret, token, private key, API key, passphrase, hashes) become "[REDACTED]" - inside credential namespaces (cloudsync, keychaincredential, alertservice, mail, ...) every `attributes` value is redacted except a short descriptive allowlist - whole results of key-export methods are redacted - a stderr note reports the count; --show-secrets or TRUENAS_SHOW_SECRETS=1 disables redaction - SKILL.md tells Claude to use the flag only when the user explicitly asked for a credential Tests: 58 (key matching, nested redaction, credential blocks, whole-result methods, end-to-end over the fake middleware). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014jXNHcVCpS5ch9a5L594j8
Jonas asked that the skill keep a working API path rather than lean on ssh+midclt. The code already prefers ws when an API key is present; the docs now say so explicitly, state the privilege difference (scoped, revocable key vs root on the NAS), and present the port-forward recipe before the ssh fallback in the VLAN section, including how to inspect the certificate's SANs before deciding on verification. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014jXNHcVCpS5ch9a5L594j8
…her codes - ordering/reorder require --source-zone and --dest-zone client-side (the API reports one missing parameter at a time) - reorder refuses a body without orderedFirewallPolicyIds.before/afterSystemDefined - vouchers redact 'code' unless --show-secrets (scoped to that command) - fixtures and references follow the live ordering shape; radius list keys noted Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SfC3NrzAJoJN4enwxr6opx
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SfC3NrzAJoJN4enwxr6opx
…realistic failed-backup log Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFKwcDK4uJnKCCf6od43tV
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFKwcDK4uJnKCCf6od43tV
Every CLI call re-probed /info and re-listed /sites, which was two of every three requests in the eval runs. Discovery is now cached per host under ~/.cache/unifi-ops (UNIFI_CACHE_DIR, TTL 6 h, '0' disables); 'info' always probes fresh, and any 404 clears the cache so a stale entry heals itself. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SfC3NrzAJoJN4enwxr6opx
…only probe of HA groups Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFKwcDK4uJnKCCf6od43tV
A read-only sweep of the live core.get_methods (409 names) found: - update.update only writes update configuration; the OS updater is update.run (job). system.md rewritten; update.run added to the gate. update.check_available does not exist: use update.available_versions and update.status. - pool.dataset.permission does not exist: filesystem.setperm (job, gated) in storage.md and sharing.md. - no smart.* namespace: SMART block now uses disk.temperature* plus smartctl over SSH. - pool.scrub.run is not a job; pool.scrub.scrub is. - zfs.snapshot and bootenv are gone; hedges removed. - REST API deprecation (alert on use, removed in 26.04) and the factory certificate's localhost-only SAN recorded in api-basics.md. - health playbook: usedbydataset vs usedbysnapshots query. tn.py methods: --exact proves a single name exists (exit 1 with similar names otherwise); the gate flag is renamed gated_by_tn so it is not read as server data. ssh "Permission denied (publickey)" is reported as cause ssh-auth with a hint that the API transport is the primary path. README records what is now verified live. Tests: 60. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014jXNHcVCpS5ch9a5L594j8
…refer an existing read-only token Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFKwcDK4uJnKCCf6od43tV
…action, live-verified references TrueNAS skill: dependency-free transports, redaction, live-verified references
…ding, Administrator-only node privileges, empty content-list pitfall, restart after install) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFKwcDK4uJnKCCf6od43tV
…ections, trigger evals Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFKwcDK4uJnKCCf6od43tV
…for 0.2.0 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFKwcDK4uJnKCCf6od43tV
…ndall, tests and lint for 0.2.0 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFKwcDK4uJnKCCf6od43tV
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFKwcDK4uJnKCCf6od43tV
…sh help wording, doc nits) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFKwcDK4uJnKCCf6od43tV
Import the three plugin repositories with their full history under plugins/<name> and publish them from a single root marketplace named "jonasthim". Each stays a separate plugin. - Root .claude-plugin/marketplace.json; per-plugin marketplace files removed - plugin.json homepage/repository point here; MIT LICENSE in each plugin - READMEs: new install lines (claude plugin install <name>@jonasthim) - proxmox lint checks the root marketplace entry; intentional shellcheck infos silenced so the suite is clean with shellcheck installed - unifi: offline smoke test against the eval fixtures - CHANGELOGs for truenas and unifi; CONTRIBUTING.md with shared conventions - mods/README.md: conventions for future function-hook mods - CI: per-plugin tests plus claude plugin validate Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CE5mahfuiAeTFLfTQP2dbR
Older shellcheck (0.9, Ubuntu's apt package used in CI) reports the trap handler as SC2317 instead of SC2329. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CE5mahfuiAeTFLfTQP2dbR
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The review found guard bypasses, credential-exposure paths, and incorrect privilege classification that should be resolved before approval.
Review effort: Balanced
Findings: 3
Open (8)
Make command-pattern matching case-insensitive · New Avoid requesting container passwords in chat · New Prevent token exposure in workflow output · New Redact credentials from dry-run output · New Preserve ACL path scope when classifying capabilities · New Reject unknown diagnostic section names · New Validate required payload arguments locally · New Clarify confirmation rules for lower-risk writes · New
What changed in this PR
Consolidates the TrueNAS, Proxmox, and UniFi plugins into one jonasthim marketplace with shared documentation, CI, licensing, and plugin-local tooling.
Changes:
- Adds the unified marketplace and repository-wide contributor/install documentation.
- Imports three independently installable homelab plugins with metadata and operational guidance.
- Adds offline fixtures, smoke/unit tests, validation, and safety tooling.
| File | Description |
|---|---|
README.md |
Documents the unified marketplace. |
LICENSE |
Adds repository MIT license. |
CONTRIBUTING.md |
Defines shared plugin conventions. |
.claude-plugin/marketplace.json |
Registers all three plugins. |
.github/workflows/ci.yml |
Adds per-plugin CI and validation. |
mods/README.md |
Documents future mod layout. |
plugins/unifi/.claude-plugin/plugin.json |
Defines UniFi metadata. |
plugins/unifi/.gitignore |
Ignores local artifacts. |
plugins/unifi/CHANGELOG.md |
Records migration history. |
plugins/unifi/LICENSE |
Adds plugin-local license. |
plugins/unifi/README.md |
Documents installation and usage. |
plugins/unifi/tests/smoke.sh |
Adds offline smoke tests. |
plugins/unifi/skills/unifi-ops/SKILL.md |
Defines UniFi workflows and safety. |
plugins/unifi/skills/unifi-ops/scripts/ssh_diag.sh |
Adds SSH diagnostics. |
plugins/unifi/skills/unifi-ops/references/ssh-commands.md |
Documents SSH operations. |
plugins/unifi/skills/unifi-ops/references/site-manager-api.md |
Documents cloud API usage. |
plugins/unifi/skills/unifi-ops/evals/mock_server.py |
Adds a fixture-backed API server. |
plugins/unifi/skills/unifi-ops/evals/evals.json |
Defines UniFi evaluations. |
plugins/unifi/skills/unifi-ops/evals/fixtures/README.md |
Explains fixture scenarios. |
plugins/unifi/skills/unifi-ops/evals/fixtures/wifi_broadcasts.json |
Adds SSID fixtures. |
plugins/unifi/skills/unifi-ops/evals/fixtures/wans.json |
Adds WAN fixtures. |
plugins/unifi/skills/unifi-ops/evals/fixtures/vpn_site_to_site_tunnels.json |
Adds tunnel fixtures. |
plugins/unifi/skills/unifi-ops/evals/fixtures/vpn_servers.json |
Adds VPN server fixtures. |
plugins/unifi/skills/unifi-ops/evals/fixtures/traffic_matching_lists.json |
Adds traffic-list fixtures. |
plugins/unifi/skills/unifi-ops/evals/fixtures/sites.json |
Adds site fixtures. |
plugins/unifi/skills/unifi-ops/evals/fixtures/radius_profiles.json |
Adds RADIUS fixtures. |
plugins/unifi/skills/unifi-ops/evals/fixtures/pending_devices.json |
Adds adoption fixtures. |
plugins/unifi/skills/unifi-ops/evals/fixtures/networks.json |
Adds network fixtures. |
plugins/unifi/skills/unifi-ops/evals/fixtures/networks_references.json |
Adds dependency fixtures. |
plugins/unifi/skills/unifi-ops/evals/fixtures/info.json |
Adds API-version fixture. |
plugins/unifi/skills/unifi-ops/evals/fixtures/hotspot_vouchers.json |
Adds voucher fixtures. |
plugins/unifi/skills/unifi-ops/evals/fixtures/firewall_zones.json |
Adds zone fixtures. |
plugins/unifi/skills/unifi-ops/evals/fixtures/firewall_policies.json |
Adds policy fixtures. |
plugins/unifi/skills/unifi-ops/evals/fixtures/firewall_policies_ordering.json |
Adds ordering fixtures. |
plugins/unifi/skills/unifi-ops/evals/fixtures/dpi_categories.json |
Adds DPI category fixtures. |
plugins/unifi/skills/unifi-ops/evals/fixtures/dpi_applications.json |
Adds DPI application fixtures. |
plugins/unifi/skills/unifi-ops/evals/fixtures/dns_policies.json |
Adds DNS fixtures. |
plugins/unifi/skills/unifi-ops/evals/fixtures/devices_statistics_latest.json |
Adds device-statistics fixtures. |
plugins/unifi/skills/unifi-ops/evals/fixtures/cloud_sites.json |
Adds cloud-site fixtures. |
plugins/unifi/skills/unifi-ops/evals/fixtures/cloud_sd_wan_configs.json |
Adds SD-WAN fixtures. |
plugins/unifi/skills/unifi-ops/evals/fixtures/cloud_isp_metrics.json |
Adds generic ISP metrics. |
plugins/unifi/skills/unifi-ops/evals/fixtures/cloud_isp_metrics_5m.json |
Adds five-minute metrics. |
plugins/unifi/skills/unifi-ops/evals/fixtures/cloud_isp_metrics_1h.json |
Adds hourly metrics. |
plugins/unifi/skills/unifi-ops/evals/fixtures/cloud_hosts.json |
Adds cloud-host fixtures. |
plugins/unifi/skills/unifi-ops/evals/fixtures/cloud_devices.json |
Adds cloud-device fixtures. |
plugins/unifi/skills/unifi-ops/evals/fixtures/clients.json |
Adds client fixtures. |
plugins/unifi/skills/unifi-ops/evals/fixtures/acl_rules.json |
Adds ACL fixtures. |
plugins/unifi/skills/unifi-ops/evals/fixtures/acl_rules_ordering.json |
Adds ACL ordering fixtures. |
plugins/truenas/.claude-plugin/plugin.json |
Defines TrueNAS metadata. |
plugins/truenas/.gitignore |
Ignores local artifacts. |
plugins/truenas/CHANGELOG.md |
Records migration history. |
plugins/truenas/LICENSE |
Adds plugin-local license. |
plugins/truenas/README.md |
Documents setup and operation. |
plugins/truenas/evals/evals.json |
Defines TrueNAS evaluations. |
plugins/truenas/tests/fake_ssh.py |
Mocks SSH/midclt behavior. |
plugins/truenas/tests/fake_middleware.py |
Mocks the websocket API. |
plugins/truenas/skills/truenas/references/system.md |
Documents system operations. |
plugins/truenas/skills/truenas/references/storage.md |
Documents storage operations. |
plugins/truenas/skills/truenas/references/sharing.md |
Documents sharing operations. |
plugins/truenas/skills/truenas/references/apps.md |
Documents application operations. |
plugins/proxmox/.claude-plugin/plugin.json |
Defines Proxmox metadata. |
plugins/proxmox/.gitignore |
Ignores local artifacts. |
plugins/proxmox/CHANGELOG.md |
Records plugin history. |
plugins/proxmox/LICENSE |
Adds plugin-local license. |
plugins/proxmox/hooks/hooks.json |
Registers the safety guard. |
plugins/proxmox/agents/proxmox-operator.md |
Defines the operator agent. |
plugins/proxmox/scripts/pve-task.sh |
Adds UPID polling. |
plugins/proxmox/scripts/pve-ssh.sh |
Adds quoted SSH execution. |
plugins/proxmox/tests/guard_cases.txt |
Defines guard test cases. |
plugins/proxmox/skills/vm/SKILL.md |
Defines VM operations. |
plugins/proxmox/skills/status/SKILL.md |
Defines status reporting. |
plugins/proxmox/skills/snapshot/SKILL.md |
Defines snapshot operations. |
plugins/proxmox/skills/doctor/SKILL.md |
Defines connection diagnostics. |
plugins/proxmox/skills/ct/SKILL.md |
Defines container operations. |
plugins/proxmox/skills/backup/SKILL.md |
Defines backup operations. |
plugins/proxmox/skills/pve/evals/evals.json |
Adds behavioral evaluations. |
plugins/proxmox/skills/pve/evals/trigger-evals.json |
Adds trigger evaluations. |
plugins/proxmox/skills/pve/references/troubleshooting.md |
Adds troubleshooting guidance. |
plugins/proxmox/skills/pve/references/storage.md |
Adds storage guidance. |
plugins/proxmox/skills/pve/references/pve9-changes.md |
Documents PVE 9 changes. |
plugins/proxmox/skills/pve/references/permissions.md |
Documents permissions and tokens. |
plugins/proxmox/skills/pve/references/networking-sdn.md |
Documents networking and SDN. |
plugins/proxmox/skills/pve/references/cluster-ha.md |
Documents clusters and HA. |
plugins/proxmox/skills/pve/references/cloud-init.md |
Documents cloud-init workflows. |
plugins/proxmox/skills/pve/references/backups.md |
Documents backup workflows. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
proxmox: - guard.sh matches case-insensitively; pve-api.sh upper-cases its method, so 'pve-api.sh delete ...' ran without the confirmation prompt - PVE_DRY_RUN masks password/secret/private parameters - token creation is the user's own step; the secret is returned once - /proxmox:ct uses a public key and never asks for a password in chat - /proxmox:doctor classifies the token per ACL path unifi: - action/adopt verbs require --action/--macs before any request - ssh_diag.sh rejects unknown section names CONTRIBUTING: the shared confirmation rule covers destructive actions; lower-risk writes are each plugin's call. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CE5mahfuiAeTFLfTQP2dbR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
This PR brings the three homelab plugin repos into this one, with their full commit history, and publishes them from a single marketplace named
jonasthim. Each stays a separate plugin, so you install only what you run:jonasthim/claude-truenas-skill(main)plugins/truenasjonasthim/claude-proxmox-skill(feat/proxmox-plugin)plugins/proxmoxjonasthim/claude-unifi-skill(main,plugins/unifi+ root README)plugins/unifiChanges
.claude-plugin/marketplace.jsonreplaces the three per-plugin ones. Entries carry noversion; eachplugin.jsonis the only source of truth for its version, following proxmox's existing lint rule.plugin.jsonhomepage/repositorynow point at this repo, and each plugin declares MIT.LICENSEis in each plugin (installs copy only the plugin folder) and at the root.README.md,CONTRIBUTING.md(shared conventions: credentials, safety gates, redaction, layout, plus known differences such as UniFi's TLS default) and CHANGELOGs for truenas and unifi.lint_plugin.pychecks the root marketplace entry (./plugins/proxmox).tests/run.share silenced, under both the old and new codes (SC2317 and SC2329).tests/smoke.sh, an offline run ofunifi.pyagainst the eval fixtures that also checks the write gate.mods/README.mdrecords how to add function-hook mods as further plugins in this marketplace. It holds docs only; no mod ships yet..github/workflows/ci.ymlruns one job per plugin, plusclaude plugin validateon the marketplace and each plugin.Review fixes (9f6e619)
Fixes for issues already in the imported code, found in review:
pve-api.sh delete|post|putcan no longer skip the prompt.PVE_DRY_RUNmasks password, secret and private-key parameters./proxmox:ctnever asks for a password in chat./proxmox:doctorclassifies the token per ACL path.actionandadoptverbs require--action/--macsbefore sending.ssh_diag.shrejects unknown section names.Testing
websocketsinstalled, as in CI)tests/run.sh312 passed, 0 failed, with shellcheck 0.10 and 0.9 andclaude plugin validate --stricttests/smoke.sh15 passedclaude plugin validatepasses on the root and on each pluginclaude plugin marketplace add <checkout>in a throwaway HOME, then installing all three plugins: all three enabledAfter merge
Once installs from
jonasthim/claudework for you, the three old repos can be deleted (GitHub → Settings → Delete). Anyone who installed from the old marketplaces must reinstall fromjonasthim.🤖 Generated with Claude Code
https://claude.ai/code/session_01CE5mahfuiAeTFLfTQP2dbR