nerftools 0.3.2__tar.gz → 1.1.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.
- {nerftools-0.3.2 → nerftools-1.1.0}/.cspell.json +10 -14
- {nerftools-0.3.2 → nerftools-1.1.0}/.github/workflows/ci.yml +1 -1
- {nerftools-0.3.2 → nerftools-1.1.0}/.github/workflows/release-please.yml +8 -9
- {nerftools-0.3.2 → nerftools-1.1.0}/.gitignore +3 -0
- nerftools-1.1.0/.release-please-manifest.json +3 -0
- nerftools-1.1.0/CHANGELOG.md +136 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/CONTRIBUTING.md +3 -3
- {nerftools-0.3.2 → nerftools-1.1.0}/PKG-INFO +1 -1
- {nerftools-0.3.2 → nerftools-1.1.0}/README.md +16 -6
- {nerftools-0.3.2 → nerftools-1.1.0}/docs/nerf-manifest.md +167 -3
- nerftools-1.1.0/docs/sdd/2026-04-04-nerf-refactor/frd.md +401 -0
- nerftools-1.1.0/docs/sdd/2026-04-04-nerf-refactor/hla.md +530 -0
- nerftools-1.1.0/docs/sdd/2026-04-04-nerf-refactor/locked.md +9 -0
- nerftools-1.1.0/docs/sdd/2026-04-04-nerf-refactor/manifest-spec.md +1032 -0
- nerftools-1.1.0/docs/sdd/2026-04-04-nerf-refactor/plan.md +227 -0
- nerftools-1.1.0/nerf.yaml +22 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/nerftools/__init__.py +0 -1
- {nerftools-0.3.2 → nerftools-1.1.0}/nerftools/builder.py +228 -23
- {nerftools-0.3.2 → nerftools-1.1.0}/nerftools/cli.py +49 -18
- nerftools-1.1.0/nerftools/config.py +391 -0
- nerftools-1.1.0/nerftools/default_manifests/az-account.yaml +48 -0
- nerftools-1.1.0/nerftools/default_manifests/az-aks.yaml +293 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/nerftools/default_manifests/az-boards.yaml +146 -18
- nerftools-1.1.0/nerftools/default_manifests/az-cosmosdb.yaml +133 -0
- nerftools-1.1.0/nerftools/default_manifests/az-devops.yaml +33 -0
- nerftools-1.1.0/nerftools/default_manifests/az-keyvault.yaml +171 -0
- nerftools-1.1.0/nerftools/default_manifests/az-monitor.yaml +152 -0
- nerftools-1.1.0/nerftools/default_manifests/az-network.yaml +602 -0
- nerftools-1.1.0/nerftools/default_manifests/az-pipelines.yaml +114 -0
- nerftools-1.1.0/nerftools/default_manifests/az-postgres.yaml +103 -0
- nerftools-1.1.0/nerftools/default_manifests/az-repos.yaml +248 -0
- nerftools-1.1.0/nerftools/default_manifests/az-resource.yaml +110 -0
- nerftools-1.1.0/nerftools/default_manifests/az-role.yaml +119 -0
- nerftools-1.1.0/nerftools/default_manifests/az-storage.yaml +102 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/nerftools/default_manifests/gh.yaml +118 -13
- nerftools-1.1.0/nerftools/default_manifests/git.yaml +541 -0
- nerftools-1.1.0/nerftools/default_manifests/kubectl.yaml +449 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/nerftools/default_manifests/nx.yaml +6 -6
- {nerftools-0.3.2 → nerftools-1.1.0}/nerftools/default_manifests/pkgrun.yaml +3 -3
- {nerftools-0.3.2 → nerftools-1.1.0}/nerftools/default_manifests/tg.yaml +10 -10
- {nerftools-0.3.2 → nerftools-1.1.0}/nerftools/default_manifests/uv.yaml +4 -4
- {nerftools-0.3.2 → nerftools-1.1.0}/nerftools/formats.py +2 -2
- {nerftools-0.3.2 → nerftools-1.1.0}/nerftools/manifest.py +177 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/nerftools/rendering.py +49 -5
- {nerftools-0.3.2 → nerftools-1.1.0}/nerftools/skill.py +1 -1
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/.claude-plugin/plugin.json +1 -1
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-account/SKILL.md +57 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-account/scripts/nerf-az-account-list +39 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-account/scripts/nerf-az-account-set +69 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-account/scripts/nerf-az-account-show +39 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-aks/SKILL.md +165 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-aks/scripts/nerf-az-aks-command-invoke +100 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-aks/scripts/nerf-az-aks-get-credentials +94 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-aks/scripts/nerf-az-aks-get-credentials-admin +94 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-aks/scripts/nerf-az-aks-get-versions +77 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-aks/scripts/nerf-az-aks-list +52 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-aks/scripts/nerf-az-aks-nodepool-list +88 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-aks/scripts/nerf-az-aks-nodepool-show +99 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-aks/scripts/nerf-az-aks-show +88 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-az-boards/SKILL.md +69 -28
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-boards/scripts/nerf-az-boards-area-list +47 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-az-boards/scripts/nerf-az-boards-mywi-comment +41 -13
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-az-boards/scripts/nerf-az-boards-mywi-show +31 -9
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-az-boards/scripts/nerf-az-boards-wi-add-parent +41 -13
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-az-boards/scripts/nerf-az-boards-wi-comment +41 -13
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-boards/scripts/nerf-az-boards-wi-create +129 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-boards/scripts/nerf-az-boards-wi-list +77 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-boards/scripts/nerf-az-boards-wi-show +87 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-boards/scripts/nerf-az-boards-wi-update +122 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-cosmosdb/SKILL.md +84 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-cosmosdb/scripts/nerf-az-cosmosdb-database-list +88 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-cosmosdb/scripts/nerf-az-cosmosdb-list +52 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-cosmosdb/scripts/nerf-az-cosmosdb-network-rule-list +88 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-cosmosdb/scripts/nerf-az-cosmosdb-show +88 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-devops/SKILL.md +27 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-devops/scripts/nerf-az-devops-set-default-project +69 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-keyvault/SKILL.md +101 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-keyvault/scripts/nerf-az-keyvault-list +52 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-keyvault/scripts/nerf-az-keyvault-network-rule-list +82 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-keyvault/scripts/nerf-az-keyvault-secret-list +77 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-keyvault/scripts/nerf-az-keyvault-secret-stats +118 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-keyvault/scripts/nerf-az-keyvault-show +82 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-monitor/SKILL.md +71 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-monitor/scripts/nerf-az-monitor-activity-log +113 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-monitor/scripts/nerf-az-monitor-diagnostic-settings-list +77 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-monitor/scripts/nerf-az-monitor-metrics-list +126 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-network/SKILL.md +339 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-network/scripts/nerf-az-network-nic-show +88 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-network/scripts/nerf-az-network-nsg-list +52 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-network/scripts/nerf-az-network-nsg-show +88 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-network/scripts/nerf-az-network-private-dns-link-list +88 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-network/scripts/nerf-az-network-private-dns-link-show +99 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-network/scripts/nerf-az-network-private-dns-record-list +88 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-network/scripts/nerf-az-network-private-dns-zone-list +52 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-network/scripts/nerf-az-network-private-dns-zone-show +88 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-network/scripts/nerf-az-network-private-endpoint-list +52 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-network/scripts/nerf-az-network-private-endpoint-show +88 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-network/scripts/nerf-az-network-private-link-resource-list +77 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-network/scripts/nerf-az-network-public-ip-list +52 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-network/scripts/nerf-az-network-public-ip-show +88 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-network/scripts/nerf-az-network-route-table-show +88 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-network/scripts/nerf-az-network-subnet-show +99 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-network/scripts/nerf-az-network-vnet-list +52 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-network/scripts/nerf-az-network-vnet-peering-list +88 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-network/scripts/nerf-az-network-vnet-peering-show +99 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-network/scripts/nerf-az-network-vnet-show +88 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-pipelines/SKILL.md +76 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-az-pipelines/scripts/nerf-az-pipelines-check +31 -9
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-pipelines/scripts/nerf-az-pipelines-list +47 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-pipelines/scripts/nerf-az-pipelines-run-show +87 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-pipelines/scripts/nerf-az-pipelines-runs +47 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-postgres/SKILL.md +66 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-postgres/scripts/nerf-az-postgres-flexible-server-firewall-rule-list +88 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-postgres/scripts/nerf-az-postgres-flexible-server-list +52 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-postgres/scripts/nerf-az-postgres-flexible-server-show +88 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-repos/SKILL.md +126 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-az-repos/scripts/nerf-az-repos-pr-comments +30 -9
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-az-repos/scripts/nerf-az-repos-pr-create +39 -12
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-repos/scripts/nerf-az-repos-pr-list +86 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-repos/scripts/nerf-az-repos-pr-set-status +118 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-az-repos/scripts/nerf-az-repos-pr-show +31 -9
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-repos/scripts/nerf-az-repos-pr-vote +118 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-resource/SKILL.md +78 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-resource/scripts/nerf-az-group-list +47 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-resource/scripts/nerf-az-group-show +77 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-resource/scripts/nerf-az-resource-list +62 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-resource/scripts/nerf-az-resource-show +77 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-role/SKILL.md +72 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-role/scripts/nerf-az-role-assignment-by-id +77 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-role/scripts/nerf-az-role-assignment-list +73 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-role/scripts/nerf-az-role-definition-list +63 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-storage/SKILL.md +65 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-storage/scripts/nerf-az-storage-account-list +52 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-storage/scripts/nerf-az-storage-account-network-rule-list +88 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-az-storage/scripts/nerf-az-storage-account-show +88 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-gh/SKILL.md +68 -7
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-gh/scripts/nerf-gh-issue-comment +28 -8
- nerftools-1.1.0/out/claude-plugin/skills/nerf-gh/scripts/nerf-gh-issue-create +87 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-gh/scripts/nerf-gh-issue-list +16 -9
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-gh/scripts/nerf-gh-issue-view +19 -5
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-gh/scripts/nerf-gh-pr-create +26 -9
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-gh/scripts/nerf-gh-pr-diff +19 -5
- nerftools-1.1.0/out/claude-plugin/skills/nerf-gh/scripts/nerf-gh-pr-inline-comments +79 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-gh/scripts/nerf-gh-pr-list +16 -9
- nerftools-1.1.0/out/claude-plugin/skills/nerf-gh/scripts/nerf-gh-pr-review-comments +111 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-gh/scripts/nerf-gh-pr-reviews +99 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-gh/scripts/nerf-gh-pr-thread-comment +91 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-gh/scripts/nerf-gh-pr-thread-comments +79 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-gh/scripts/nerf-gh-pr-view +19 -5
- nerftools-1.1.0/out/claude-plugin/skills/nerf-gh/scripts/nerf-gh-run-list +81 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-gh/scripts/nerf-gh-run-view +20 -6
- nerftools-1.1.0/out/claude-plugin/skills/nerf-git/SKILL.md +372 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-git/scripts/nerf-git-add +148 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-git/scripts/nerf-git-branch-checkout-remote +200 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-git/scripts/nerf-git-branch-delete-merged +189 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-git/scripts/nerf-git-branch-list-local +128 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-git/scripts/nerf-git-branch-list-remote +128 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-git/scripts/nerf-git-commit +171 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-git/scripts/nerf-git-commit-amend +188 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-git/scripts/nerf-git-create-branch +168 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-git/scripts/nerf-git-diff +128 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-git/scripts/nerf-git-diff-staged +128 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-git/scripts/nerf-git-fetch +168 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-git/scripts/nerf-git-log +128 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-git/scripts/nerf-git-pull +168 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-git/scripts/nerf-git-push-branch +188 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-git/scripts/nerf-git-push-main +168 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-git/scripts/nerf-git-rebase-unpushed +194 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-git/scripts/nerf-git-reset-hard-last +148 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-git/scripts/nerf-git-reset-unpushed +200 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-git/scripts/nerf-git-revert +158 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-git/scripts/nerf-git-status +128 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-git/scripts/nerf-git-switch +168 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-git/scripts/nerf-git-tag +170 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-kubectl/SKILL.md +290 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-kubectl/scripts/nerf-kubectl-api-resources +57 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-kubectl/scripts/nerf-kubectl-api-versions +39 -0
- nerftools-0.3.2/out/claude-plugin/skills/nerf-az-pipelines/scripts/nerf-az-pipelines-list → nerftools-1.1.0/out/claude-plugin/skills/nerf-kubectl/scripts/nerf-kubectl-cluster-info +10 -7
- nerftools-1.1.0/out/claude-plugin/skills/nerf-kubectl/scripts/nerf-kubectl-config-current-context +39 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-kubectl/scripts/nerf-kubectl-config-get-contexts +39 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-kubectl/scripts/nerf-kubectl-config-use-context +79 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-kubectl/scripts/nerf-kubectl-describe +131 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-kubectl/scripts/nerf-kubectl-exec +124 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-kubectl/scripts/nerf-kubectl-explain +86 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-kubectl/scripts/nerf-kubectl-get +145 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-kubectl/scripts/nerf-kubectl-get-secrets +107 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-kubectl/scripts/nerf-kubectl-logs +133 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-kubectl/scripts/nerf-kubectl-port-forward +152 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-kubectl/scripts/nerf-kubectl-rollout-restart +97 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-kubectl/scripts/nerf-kubectl-top-nodes +47 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-kubectl/scripts/nerf-kubectl-top-pods +68 -0
- nerftools-1.1.0/out/claude-plugin/skills/nerf-kubectl/scripts/nerf-kubectl-version +39 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-nx/scripts/nerf-nx-affected +5 -2
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-nx/scripts/nerf-nx-graph +5 -2
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-nx/scripts/nerf-nx-reset +5 -2
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-nx/scripts/nerf-nx-run +20 -6
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-nx/scripts/nerf-nx-show-project +20 -6
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-nx/scripts/nerf-nx-show-projects +5 -2
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-pkgrun/scripts/nerf-pkgrun-cspell +13 -2
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-pkgrun/scripts/nerf-pkgrun-markdownlint +13 -2
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-pkgrun/scripts/nerf-pkgrun-prettier +13 -2
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-stdutils/SKILL.md +4 -4
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-stdutils/scripts/nerf-find +1 -1
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-stdutils/scripts/nerf-find-cwd +1 -1
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-stdutils/scripts/nerf-grep +14 -5
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-stdutils/scripts/nerf-grep-recursive-cwd +19 -5
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-tg/scripts/nerf-tg-fmt +5 -2
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-tg/scripts/nerf-tg-fmt-all +5 -2
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-tg/scripts/nerf-tg-init +5 -2
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-tg/scripts/nerf-tg-init-all +5 -2
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-tg/scripts/nerf-tg-output +5 -2
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-tg/scripts/nerf-tg-output-all +5 -2
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-tg/scripts/nerf-tg-plan +5 -2
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-tg/scripts/nerf-tg-plan-all +5 -2
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-tg/scripts/nerf-tg-validate +5 -2
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-tg/scripts/nerf-tg-validate-all +5 -2
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-uv/scripts/nerf-uv-mypy +13 -2
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-uv/scripts/nerf-uv-pytest +13 -2
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-uv/scripts/nerf-uv-ruff-check +13 -2
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-uv/scripts/nerf-uv-ruff-fix +13 -2
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerftools/SKILL.md +12 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/pyproject.toml +1 -1
- {nerftools-0.3.2 → nerftools-1.1.0}/release-please-config.json +1 -1
- nerftools-1.1.0/tests/test_builder.py +1202 -0
- nerftools-1.1.0/tests/test_config.py +297 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/tests/test_formats.py +14 -3
- {nerftools-0.3.2 → nerftools-1.1.0}/tests/test_manifest.py +371 -37
- {nerftools-0.3.2 → nerftools-1.1.0}/tests/test_nerfctl.py +1 -15
- nerftools-1.1.0/tests/test_rendering.py +59 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/tests/test_skill.py +42 -2
- {nerftools-0.3.2 → nerftools-1.1.0}/uv.lock +1 -1
- nerftools-0.3.2/.release-please-manifest.json +0 -3
- nerftools-0.3.2/CHANGELOG.md +0 -66
- nerftools-0.3.2/nerf-plugin.yaml +0 -21
- nerftools-0.3.2/nerftools/default_manifests/az-pipelines.yaml +0 -42
- nerftools-0.3.2/nerftools/default_manifests/az-repos.yaml +0 -137
- nerftools-0.3.2/nerftools/default_manifests/git.yaml +0 -202
- nerftools-0.3.2/nerftools/nerfctl/claude/install-plugin.sh +0 -57
- nerftools-0.3.2/nerftools/plugin_meta.py +0 -200
- nerftools-0.3.2/out/claude-plugin/scripts/nerfctl-install-plugin +0 -57
- nerftools-0.3.2/out/claude-plugin/skills/nerf-az-boards/scripts/nerf-az-boards-wi-create +0 -98
- nerftools-0.3.2/out/claude-plugin/skills/nerf-az-boards/scripts/nerf-az-boards-wi-list +0 -55
- nerftools-0.3.2/out/claude-plugin/skills/nerf-az-boards/scripts/nerf-az-boards-wi-show +0 -65
- nerftools-0.3.2/out/claude-plugin/skills/nerf-az-boards/scripts/nerf-az-boards-wi-update +0 -96
- nerftools-0.3.2/out/claude-plugin/skills/nerf-az-pipelines/SKILL.md +0 -50
- nerftools-0.3.2/out/claude-plugin/skills/nerf-az-pipelines/scripts/nerf-az-pipelines-runs +0 -36
- nerftools-0.3.2/out/claude-plugin/skills/nerf-az-repos/SKILL.md +0 -73
- nerftools-0.3.2/out/claude-plugin/skills/nerf-az-repos/scripts/nerf-az-repos-pr-list +0 -74
- nerftools-0.3.2/out/claude-plugin/skills/nerf-gh/scripts/nerf-gh-issue-create +0 -70
- nerftools-0.3.2/out/claude-plugin/skills/nerf-gh/scripts/nerf-gh-pr-comment +0 -71
- nerftools-0.3.2/out/claude-plugin/skills/nerf-gh/scripts/nerf-gh-pr-review-comments +0 -65
- nerftools-0.3.2/out/claude-plugin/skills/nerf-gh/scripts/nerf-gh-run-list +0 -74
- nerftools-0.3.2/out/claude-plugin/skills/nerf-git/SKILL.md +0 -153
- nerftools-0.3.2/out/claude-plugin/skills/nerf-git/scripts/nerf-git-add +0 -56
- nerftools-0.3.2/out/claude-plugin/skills/nerf-git/scripts/nerf-git-commit +0 -68
- nerftools-0.3.2/out/claude-plugin/skills/nerf-git/scripts/nerf-git-commit-amend +0 -85
- nerftools-0.3.2/out/claude-plugin/skills/nerf-git/scripts/nerf-git-fetch +0 -65
- nerftools-0.3.2/out/claude-plugin/skills/nerf-git/scripts/nerf-git-log +0 -36
- nerftools-0.3.2/out/claude-plugin/skills/nerf-git/scripts/nerf-git-pull +0 -65
- nerftools-0.3.2/out/claude-plugin/skills/nerf-git/scripts/nerf-git-push-branch +0 -84
- nerftools-0.3.2/out/claude-plugin/skills/nerf-git/scripts/nerf-git-push-main +0 -65
- nerftools-0.3.2/out/claude-plugin/skills/nerf-git/scripts/nerf-git-reset-hard-last +0 -56
- nerftools-0.3.2/out/claude-plugin/skills/nerf-git/scripts/nerf-git-revert +0 -55
- nerftools-0.3.2/out/claude-plugin/skills/nerf-git/scripts/nerf-git-tag +0 -67
- nerftools-0.3.2/tests/test_builder.py +0 -646
- nerftools-0.3.2/tests/test_plugin_meta.py +0 -187
- {nerftools-0.3.2 → nerftools-1.1.0}/.claude-plugin/marketplace.json +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/.editorconfig +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/.github/workflows/release.yml +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/.markdownlint-cli2.jsonc +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/.prettierrc +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/.python-version +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/LICENSE +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/nerftools/default_manifests/README.md +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/nerftools/default_manifests/__init__.py +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/nerftools/default_manifests/stdutils.yaml +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/nerftools/nerfctl/__init__.py +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/nerftools/nerfctl/claude/grant-allow.sh +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/nerftools/nerfctl/claude/grant-by-threat.sh +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/nerftools/nerfctl/claude/grant-deny.sh +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/nerftools/nerfctl/claude/grant-list.sh +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/nerftools/nerfctl/claude/grant-reset.sh +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/scripts/nerfctl-grant-allow +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/scripts/nerfctl-grant-by-threat +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/scripts/nerfctl-grant-deny +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/scripts/nerfctl-grant-list +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/scripts/nerfctl-grant-reset +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-nx/SKILL.md +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-pkgrun/SKILL.md +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-tg/SKILL.md +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerf-uv/SKILL.md +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerfctl-grant-allow/SKILL.md +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerfctl-grant-by-threat/SKILL.md +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerfctl-grant-deny/SKILL.md +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerfctl-grant-list/SKILL.md +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/out/claude-plugin/skills/nerfctl-grant-reset/SKILL.md +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/pypi-dist/.gitignore +0 -0
- {nerftools-0.3.2 → nerftools-1.1.0}/tests/__init__.py +0 -0
|
@@ -5,26 +5,22 @@
|
|
|
5
5
|
"agentic",
|
|
6
6
|
"Agentworks",
|
|
7
7
|
"bunx",
|
|
8
|
+
"codegen",
|
|
9
|
+
"coreutils",
|
|
8
10
|
"dataclass",
|
|
9
11
|
"dataclasses",
|
|
10
|
-
"
|
|
11
|
-
"elif",
|
|
12
|
+
"errexit",
|
|
12
13
|
"esac",
|
|
14
|
+
"footguns",
|
|
13
15
|
"execdir",
|
|
14
16
|
"exitcode",
|
|
15
|
-
"frontmatter",
|
|
16
|
-
"gwat",
|
|
17
|
-
"invokable",
|
|
18
17
|
"metacharacter",
|
|
19
18
|
"metacharacters",
|
|
20
19
|
"myapp",
|
|
21
20
|
"mypy",
|
|
22
21
|
"mywi",
|
|
23
22
|
"nerfctl",
|
|
24
|
-
"nerfed",
|
|
25
23
|
"nerftools",
|
|
26
|
-
"noprofile",
|
|
27
|
-
"norc",
|
|
28
24
|
"okdir",
|
|
29
25
|
"oneline",
|
|
30
26
|
"permissioning",
|
|
@@ -33,16 +29,13 @@
|
|
|
33
29
|
"pnpx",
|
|
34
30
|
"pyproject",
|
|
35
31
|
"pytest",
|
|
36
|
-
"pytestmark",
|
|
37
32
|
"rulesync",
|
|
38
33
|
"Rulesync",
|
|
39
34
|
"stdutils",
|
|
40
35
|
"subshell",
|
|
41
|
-
"
|
|
42
|
-
"
|
|
36
|
+
"TOCTOU",
|
|
37
|
+
"typer",
|
|
43
38
|
"uppercased",
|
|
44
|
-
"usecases",
|
|
45
|
-
"variadics",
|
|
46
39
|
"wiql",
|
|
47
40
|
"WIQL"
|
|
48
41
|
],
|
|
@@ -52,6 +45,9 @@
|
|
|
52
45
|
"ignorePaths": [
|
|
53
46
|
"node_modules",
|
|
54
47
|
"out/",
|
|
55
|
-
"CHANGELOG.md"
|
|
48
|
+
"CHANGELOG.md",
|
|
49
|
+
"**/*.yaml",
|
|
50
|
+
"**/*.yml",
|
|
51
|
+
"**/*.py"
|
|
56
52
|
]
|
|
57
53
|
}
|
|
@@ -13,12 +13,11 @@ jobs:
|
|
|
13
13
|
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
|
|
14
14
|
outputs:
|
|
15
15
|
pr_branch: ${{ steps.extract.outputs.pr_branch }}
|
|
16
|
-
app_token: ${{ steps.app-token.outputs.token }}
|
|
17
16
|
steps:
|
|
18
17
|
# Use a GitHub App token so the release PR (and any subsequent pushes
|
|
19
18
|
# to its branch) trigger CI workflows. The default GITHUB_TOKEN creates
|
|
20
19
|
# events as github-actions[bot], which GitHub won't run workflows for.
|
|
21
|
-
- uses: actions/create-github-app-token@
|
|
20
|
+
- uses: actions/create-github-app-token@v3
|
|
22
21
|
id: app-token
|
|
23
22
|
with:
|
|
24
23
|
app-id: ${{ vars.RELEASE_APP_ID }}
|
|
@@ -43,7 +42,7 @@ jobs:
|
|
|
43
42
|
if: needs.release-please.outputs.pr_branch
|
|
44
43
|
runs-on: ubuntu-latest
|
|
45
44
|
steps:
|
|
46
|
-
- uses: actions/create-github-app-token@
|
|
45
|
+
- uses: actions/create-github-app-token@v3
|
|
47
46
|
id: app-token
|
|
48
47
|
with:
|
|
49
48
|
app-id: ${{ vars.RELEASE_APP_ID }}
|
|
@@ -59,19 +58,19 @@ jobs:
|
|
|
59
58
|
with:
|
|
60
59
|
enable-cache: true
|
|
61
60
|
|
|
62
|
-
- name:
|
|
63
|
-
run: uv sync
|
|
61
|
+
- name: Sync lockfile and install dependencies
|
|
62
|
+
run: uv sync
|
|
64
63
|
|
|
65
64
|
- name: Regenerate Claude Code plugin
|
|
66
|
-
run: uv run nerf generate --target claude-plugin
|
|
65
|
+
run: uv run nerf generate --target claude-plugin -c nerf.yaml --outdir ./out/claude-plugin
|
|
67
66
|
|
|
68
|
-
- name: Commit updated plugin
|
|
67
|
+
- name: Commit updated plugin and lockfile
|
|
69
68
|
run: |
|
|
70
69
|
git config user.name "nerftools-release[bot]"
|
|
71
70
|
git config user.email "nerftools-release[bot]@users.noreply.github.com"
|
|
72
|
-
git add out/claude-plugin/
|
|
71
|
+
git add out/claude-plugin/ uv.lock
|
|
73
72
|
if git diff --cached --quiet; then
|
|
74
|
-
echo "No changes to plugin output"
|
|
73
|
+
echo "No changes to plugin output or lockfile"
|
|
75
74
|
else
|
|
76
75
|
git commit -m "build: regenerate Claude Code plugin for release"
|
|
77
76
|
git push
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [1.1.0](https://github.com/WayfarerLabs/nerftools/compare/v1.0.0...v1.1.0) (2026-05-04)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **az-devops:** new package with az-devops-set-default-project tool ([0fb4a15](https://github.com/WayfarerLabs/nerftools/commit/0fb4a15347edd279481f51a85506e3ad254a7479))
|
|
9
|
+
* **azdo:** --project everywhere, new pipelines/repos tools, area listing ([a42f7e7](https://github.com/WayfarerLabs/nerftools/commit/a42f7e71eab7e3d5dcc04de50377ef504c7fefaa))
|
|
10
|
+
* **azdo:** --project everywhere, new tools, set-default-project ([2dab02d](https://github.com/WayfarerLabs/nerftools/commit/2dab02df9d885d6636e37bfe718b57a3617dbded))
|
|
11
|
+
* **gh:** differentiate the four PR comment surfaces ([567b64d](https://github.com/WayfarerLabs/nerftools/commit/567b64dc18444ff3df17e2f0ee04e67d24469dfc))
|
|
12
|
+
* **gh:** differentiate the four PR comment surfaces; add reviews tool ([ca9ab91](https://github.com/WayfarerLabs/nerftools/commit/ca9ab910ebd7e426b4704b47994cbdc1b4518232))
|
|
13
|
+
* **manifest:** add path_tests for filesystem-typed parameters ([e035eac](https://github.com/WayfarerLabs/nerftools/commit/e035eac70eabf84a6b02ef508b7995fe943708ec))
|
|
14
|
+
* **manifest:** add path_tests for filesystem-typed parameters ([fdb64cd](https://github.com/WayfarerLabs/nerftools/commit/fdb64cde6201f3d567cdfb04ff8e1c955c08d0a7))
|
|
15
|
+
* massive add of az-related default tools ([818fe04](https://github.com/WayfarerLabs/nerftools/commit/818fe04326be536924de4e7450e202db759df362))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* address PR review feedback on az and kubectl tools ([4395484](https://github.com/WayfarerLabs/nerftools/commit/4395484f4388f99ee760a774ae7be406d40d586b))
|
|
21
|
+
* address two minor PR review nits ([adad61d](https://github.com/WayfarerLabs/nerftools/commit/adad61d071fc325325e12148b8e58104def93b0e))
|
|
22
|
+
* **az-aks:** split admin credential fetch, mark command-invoke admin, fix variadic ([f152896](https://github.com/WayfarerLabs/nerftools/commit/f152896f4af595b235be0d3af1d5d1e1b7e1cd91))
|
|
23
|
+
* **az-keyvault:** drop secret fingerprint and tighten masked output ([242f8d7](https://github.com/WayfarerLabs/nerftools/commit/242f8d79e4c9a3d3a34a59dd6ab58d12476409b5))
|
|
24
|
+
* **az-monitor:** dry-run honors validation; --interval allows P1D and FULL ([c246266](https://github.com/WayfarerLabs/nerftools/commit/c2462661def1d26d9556925b359ef79d2fa43b88))
|
|
25
|
+
* **builder:** add hint lines to path_tests errors; doc symlink semantics ([a1e602b](https://github.com/WayfarerLabs/nerftools/commit/a1e602b691091c1b08f5017074467d397f3bb382))
|
|
26
|
+
* **builder:** preserve shell quoting in dry-run output via printf %q ([5ef4816](https://github.com/WayfarerLabs/nerftools/commit/5ef4816f086833445310674d4f9d157c609ad91d))
|
|
27
|
+
* **builder:** reject --nerf-dry-run tokens inside variadic+allow_flags args ([854519c](https://github.com/WayfarerLabs/nerftools/commit/854519c4070a35592b0f5358e223e270d812ad3d))
|
|
28
|
+
* **builder:** reject trailing tokens after declared positionals ([9580f8b](https://github.com/WayfarerLabs/nerftools/commit/9580f8b32dcc41332caca08d7bbebffd2a643409))
|
|
29
|
+
* **builder:** revert ineffective set -e in _nerf_pre, document the limitation ([7e6787a](https://github.com/WayfarerLabs/nerftools/commit/7e6787a788a58b37ae63bd5486c068af2238ea17))
|
|
30
|
+
* **builder:** under_cwd accepts paths under root when cwd is "/" ([3b05ccd](https://github.com/WayfarerLabs/nerftools/commit/3b05ccd02c0ffa8e91cefcad6a3112228b281d0a))
|
|
31
|
+
* cross-platform date in az-monitor, drop None aggregation, simplify timeout msg ([616385d](https://github.com/WayfarerLabs/nerftools/commit/616385d7f411cfc091c6c8ef81ecbcd94b33ca45))
|
|
32
|
+
* **gh-pr-reviews:** use --paginate; fix Changes-requested wording ([97e5f41](https://github.com/WayfarerLabs/nerftools/commit/97e5f412d9d37378e366b25b8044b2cd8274ec10))
|
|
33
|
+
* **gh:** add --slurp so paginated jq aggregates across pages ([8ebd3eb](https://github.com/WayfarerLabs/nerftools/commit/8ebd3eb00bcb3b7687306fdcdde5263599b8dac5))
|
|
34
|
+
* high-impact security and correctness from second-pass review ([022af82](https://github.com/WayfarerLabs/nerftools/commit/022af82533d88258680c7ca02b9d9b95302e35e1))
|
|
35
|
+
* **kubectl:** convert read-only tools from passthrough to template ([782b3a7](https://github.com/WayfarerLabs/nerftools/commit/782b3a7c0f97fd9feda09d6c363c66c0d93c2768))
|
|
36
|
+
* **kubectl:** kubectl-config-use-context is admin-threat, tighten pattern ([f1265ce](https://github.com/WayfarerLabs/nerftools/commit/f1265ce1b67f5396829879a3c39d75f23f389edf))
|
|
37
|
+
* more PR review feedback (rename misleading tool, guard external deps) ([6c101a4](https://github.com/WayfarerLabs/nerftools/commit/6c101a48b08560acc44342dc0c3d763ce2e72a20))
|
|
38
|
+
* paginate the remaining gh read tools; tighten cross-refs and doc ([8d48ed5](https://github.com/WayfarerLabs/nerftools/commit/8d48ed5d8c11abb5c72c73aee032ac1d23ef1a82))
|
|
39
|
+
* require 3+ word tool descriptions to catch trivial placeholders ([3433ffd](https://github.com/WayfarerLabs/nerftools/commit/3433ffd6a79c92a91743968639311be9b199a6a9))
|
|
40
|
+
* smaller hardening from second-pass review ([5079b21](https://github.com/WayfarerLabs/nerftools/commit/5079b21039265787dfc63721a47c6b3cf358c089))
|
|
41
|
+
* stop appending "." to descriptions; require terminal punctuation in manifest ([2ce0f11](https://github.com/WayfarerLabs/nerftools/commit/2ce0f11f514e57e4e0a029a786686cb5b54cdd04))
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
### Documentation
|
|
45
|
+
|
|
46
|
+
* address review feedback on coverage gap and template paragraph ([dec48de](https://github.com/WayfarerLabs/nerftools/commit/dec48def42011233452ed7b85d0e85697c78431a))
|
|
47
|
+
* **az-account:** document --subscription scope boundary ([b105f2b](https://github.com/WayfarerLabs/nerftools/commit/b105f2b008cafe9d548a743885c5fa93b2cf02b8))
|
|
48
|
+
* correct --nerf-dry-run position claim and warn against local in pre ([9231598](https://github.com/WayfarerLabs/nerftools/commit/923159816725486aa12c3f9f26442b75da5f04cb))
|
|
49
|
+
* document passthrough security limitations around alternative flag syntax ([44031d5](https://github.com/WayfarerLabs/nerftools/commit/44031d5a71864313a6dbc1362d547ac6ddb6ccca))
|
|
50
|
+
|
|
51
|
+
## [1.0.0](https://github.com/WayfarerLabs/nerftools/compare/v0.3.2...v1.0.0) (2026-04-19)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
### ⚠ BREAKING CHANGES
|
|
55
|
+
|
|
56
|
+
* `--plugin-config` and `--prefix` flags are removed. Use `-c <path>` to pass a config file. `--prefix` is now configured via `defaults.prefix` in the config file.
|
|
57
|
+
|
|
58
|
+
### Features
|
|
59
|
+
|
|
60
|
+
* introduce optional config file, drop --plugin-config and install script ([f6a1ab9](https://github.com/WayfarerLabs/nerftools/commit/f6a1ab95f7f1e22fc84d6fea111390db38ef6ebb))
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
### Bug Fixes
|
|
64
|
+
|
|
65
|
+
* address review feedback from Copilot ([60f4bc5](https://github.com/WayfarerLabs/nerftools/commit/60f4bc53ca87607b40873554a48ba7984a7b6c9e))
|
|
66
|
+
* **ci:** sync uv.lock during release to prevent version drift ([6eef9b8](https://github.com/WayfarerLabs/nerftools/commit/6eef9b8d6dfd2ccc0646cca71bdcc95fff779f48))
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
### Documentation
|
|
70
|
+
|
|
71
|
+
* **sdd:** capture the refactor sdd as it defined the fundamental structure ([5c7cad4](https://github.com/WayfarerLabs/nerftools/commit/5c7cad4248c3320cd7d67848d4963376dd8f24ee))
|
|
72
|
+
|
|
73
|
+
## [0.3.2](https://github.com/WayfarerLabs/nerftools/compare/v0.3.1...v0.3.2) (2026-04-14)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
### Documentation
|
|
77
|
+
|
|
78
|
+
* clean up pypi description ([d2b5f7f](https://github.com/WayfarerLabs/nerftools/commit/d2b5f7fef31e4ac0048a0a35059b2d24ea3e07ac))
|
|
79
|
+
* clean up pypi description ([d2ab29d](https://github.com/WayfarerLabs/nerftools/commit/d2ab29d03366f92e1e6660ba99745b7d2a0469f5))
|
|
80
|
+
|
|
81
|
+
## [0.3.1](https://github.com/WayfarerLabs/nerftools/compare/v0.3.0...v0.3.1) (2026-04-14)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
### Bug Fixes
|
|
85
|
+
|
|
86
|
+
* use app token for regenerate-dist pushes so CI triggers on release PRs ([e78ae87](https://github.com/WayfarerLabs/nerftools/commit/e78ae875208a100d77cde6cb0881186e61b83e60))
|
|
87
|
+
|
|
88
|
+
## [0.3.0](https://github.com/WayfarerLabs/nerftools/compare/v0.2.0...v0.3.0) (2026-04-14)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
### Features
|
|
92
|
+
|
|
93
|
+
* add --embed-marketplace option for standalone plugin deployment ([d00ae28](https://github.com/WayfarerLabs/nerftools/commit/d00ae28170857702a29141f24bec15c62e034c8b))
|
|
94
|
+
* initial nerftools repo with Python package and pre-built Claude Code plugin ([55eee79](https://github.com/WayfarerLabs/nerftools/commit/55eee79eb462dfb996568d42e05b86fe3a11ce3a))
|
|
95
|
+
* templatize plugin metadata via nerf-plugin.yaml config ([05086d6](https://github.com/WayfarerLabs/nerftools/commit/05086d63214351f2f9cef21fd4b6dc0679a52bd4))
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
### Bug Fixes
|
|
99
|
+
|
|
100
|
+
* doc update as fix to trigger release pipeline ([79ede3c](https://github.com/WayfarerLabs/nerftools/commit/79ede3c0f7fad1446e960bef3f943c5ca83e1a08))
|
|
101
|
+
* drop component prefix from release-please tags to match release … ([ac70693](https://github.com/WayfarerLabs/nerftools/commit/ac70693efa1e418348e5b7f10b964ebed82258db))
|
|
102
|
+
* drop component prefix from release-please tags to match release workflow ([6f92386](https://github.com/WayfarerLabs/nerftools/commit/6f92386f6fdc3dab9b63cc12ad9fcfead327382b))
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
### Documentation
|
|
106
|
+
|
|
107
|
+
* additional readme tweaks ([4f7267f](https://github.com/WayfarerLabs/nerftools/commit/4f7267f8112c215ffc0fd50d0cdd2a9d6430ea87))
|
|
108
|
+
* document the release process in CONTRIBUTING.md ([cfd29c8](https://github.com/WayfarerLabs/nerftools/commit/cfd29c8b144d17d58232c6b8677451c427627d8a))
|
|
109
|
+
* fix manifest spec link and split threat model content between README and spec ([60493c8](https://github.com/WayfarerLabs/nerftools/commit/60493c846bb9fbffde8875a576a4698e4ae2e461))
|
|
110
|
+
* move manifest guide and ref from readme ([6392c0b](https://github.com/WayfarerLabs/nerftools/commit/6392c0b716892080137b133487f3a536650590b3))
|
|
111
|
+
* polish README intro and update quick start with --plugin-config ([6cd3dde](https://github.com/WayfarerLabs/nerftools/commit/6cd3dde8c3b98dc8be7c57b1d0a3de84429bd9d0))
|
|
112
|
+
* update readme with additional context ([a93632d](https://github.com/WayfarerLabs/nerftools/commit/a93632dd217d5dad44ee4df3c86a31c282640636))
|
|
113
|
+
|
|
114
|
+
## [0.2.0](https://github.com/WayfarerLabs/nerftools/compare/nerftools-v0.1.0...nerftools-v0.2.0) (2026-04-14)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
### Features
|
|
118
|
+
|
|
119
|
+
* add --embed-marketplace option for standalone plugin deployment ([d00ae28](https://github.com/WayfarerLabs/nerftools/commit/d00ae28170857702a29141f24bec15c62e034c8b))
|
|
120
|
+
* initial nerftools repo with Python package and pre-built Claude Code plugin ([55eee79](https://github.com/WayfarerLabs/nerftools/commit/55eee79eb462dfb996568d42e05b86fe3a11ce3a))
|
|
121
|
+
* templatize plugin metadata via nerf-plugin.yaml config ([05086d6](https://github.com/WayfarerLabs/nerftools/commit/05086d63214351f2f9cef21fd4b6dc0679a52bd4))
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
### Bug Fixes
|
|
125
|
+
|
|
126
|
+
* doc update as fix to trigger release pipeline ([79ede3c](https://github.com/WayfarerLabs/nerftools/commit/79ede3c0f7fad1446e960bef3f943c5ca83e1a08))
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
### Documentation
|
|
130
|
+
|
|
131
|
+
* additional readme tweaks ([4f7267f](https://github.com/WayfarerLabs/nerftools/commit/4f7267f8112c215ffc0fd50d0cdd2a9d6430ea87))
|
|
132
|
+
* document the release process in CONTRIBUTING.md ([cfd29c8](https://github.com/WayfarerLabs/nerftools/commit/cfd29c8b144d17d58232c6b8677451c427627d8a))
|
|
133
|
+
* fix manifest spec link and split threat model content between README and spec ([60493c8](https://github.com/WayfarerLabs/nerftools/commit/60493c846bb9fbffde8875a576a4698e4ae2e461))
|
|
134
|
+
* move manifest guide and ref from readme ([6392c0b](https://github.com/WayfarerLabs/nerftools/commit/6392c0b716892080137b133487f3a536650590b3))
|
|
135
|
+
* polish README intro and update quick start with --plugin-config ([6cd3dde](https://github.com/WayfarerLabs/nerftools/commit/6cd3dde8c3b98dc8be7c57b1d0a3de84429bd9d0))
|
|
136
|
+
* update readme with additional context ([a93632d](https://github.com/WayfarerLabs/nerftools/commit/a93632dd217d5dad44ee4df3c86a31c282640636))
|
|
@@ -38,7 +38,7 @@ After changing manifests or plugin generation code, you can rebuild the pre-buil
|
|
|
38
38
|
to preview the output:
|
|
39
39
|
|
|
40
40
|
```bash
|
|
41
|
-
uv run nerf generate --target claude-plugin
|
|
41
|
+
uv run nerf generate --target claude-plugin -c nerf.yaml --outdir ./out/claude-plugin
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
You don't need to commit the regenerated `out/` -- CI regenerates it as part of the release PR.
|
|
@@ -55,7 +55,7 @@ and conventional commits. No one manually bumps versions or creates tags.
|
|
|
55
55
|
2. The `release-please` workflow keeps an open PR titled `chore(main): release X.Y.Z` that
|
|
56
56
|
accumulates changes. On each push to `main` it:
|
|
57
57
|
- Computes the next version from the conventional commits since the last release.
|
|
58
|
-
- Updates the version in `pyproject.toml`, `nerf
|
|
58
|
+
- Updates the version in `pyproject.toml`, `nerf.yaml`, and `.release-please-manifest.json`.
|
|
59
59
|
- Updates `CHANGELOG.md`.
|
|
60
60
|
- Regenerates `out/claude-plugin/` with the new version baked into `plugin.json`.
|
|
61
61
|
3. When you're ready to release, merge the release PR.
|
|
@@ -75,7 +75,7 @@ and conventional commits. No one manually bumps versions or creates tags.
|
|
|
75
75
|
- Don't create tags by hand. `release-please` creates tags on merge of the release PR.
|
|
76
76
|
- Don't edit `CHANGELOG.md` by hand. It's regenerated from commit messages.
|
|
77
77
|
- Don't edit `out/claude-plugin/` by hand. Edit the source (`nerftools/`, manifests, or
|
|
78
|
-
`nerf
|
|
78
|
+
`nerf.yaml`) and the release PR will regenerate it.
|
|
79
79
|
|
|
80
80
|
### Breaking changes
|
|
81
81
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nerftools
|
|
3
|
-
Version:
|
|
3
|
+
Version: 1.1.0
|
|
4
4
|
Summary: Define and generate nerf tools: limited-scope wrappers for common CLI utilities that allow for fine-grained control over agent execution
|
|
5
5
|
Project-URL: Homepage, https://github.com/WayfarerLabs/nerftools
|
|
6
6
|
Project-URL: Repository, https://github.com/WayfarerLabs/nerftools
|
|
@@ -100,14 +100,23 @@ uv run nerf generate --target bin --outdir ./bin
|
|
|
100
100
|
# Generate rulesync skills
|
|
101
101
|
uv run nerf generate --target skills --outdir ./skills
|
|
102
102
|
|
|
103
|
-
# Generate a Claude Code plugin (
|
|
104
|
-
uv run nerf generate --target claude-plugin
|
|
105
|
-
|
|
106
|
-
|
|
103
|
+
# Generate a Claude Code plugin (uses built-in defaults if no config)
|
|
104
|
+
uv run nerf generate --target claude-plugin --outdir ./claude-plugin
|
|
105
|
+
|
|
106
|
+
# Generate a Claude Code plugin with custom identity
|
|
107
|
+
uv run nerf generate --target claude-plugin -c nerf.yaml --outdir ./claude-plugin
|
|
107
108
|
```
|
|
108
109
|
|
|
109
|
-
|
|
110
|
-
|
|
110
|
+
Package identity and per-target settings live in an optional config file passed via `-c <path>`.
|
|
111
|
+
When omitted, sensible defaults produce an installable plugin. See [nerf.yaml](nerf.yaml) for an
|
|
112
|
+
example.
|
|
113
|
+
|
|
114
|
+
To install the generated plugin:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
claude plugin marketplace add <plugin-dir>
|
|
118
|
+
claude plugin install <plugin-name>@<marketplace-name>
|
|
119
|
+
```
|
|
111
120
|
|
|
112
121
|
## Default Manifests/Packages
|
|
113
122
|
|
|
@@ -183,6 +192,7 @@ nerftools/ Python package
|
|
|
183
192
|
rendering.py Shared display helpers (maps-to, usage tokens)
|
|
184
193
|
skill.py Rulesync skill generation
|
|
185
194
|
formats.py Claude Code plugin builder
|
|
195
|
+
config.py Config loader, plugin metadata, defaults resolution
|
|
186
196
|
cli.py CLI (validate + generate)
|
|
187
197
|
nerfctl/claude/ Grant management shell scripts
|
|
188
198
|
default_manifests/ Default tool package manifests (YAML)
|
|
@@ -235,6 +235,18 @@ Rules:
|
|
|
235
235
|
- A variadic argument's `{{kind.name}}` must be the last element of `command`.
|
|
236
236
|
- The generated script ends with `exec`, replacing the process.
|
|
237
237
|
|
|
238
|
+
**Literal command tokens are passed unquoted to bash.** Placeholder substitutions
|
|
239
|
+
(`{{switches.x}}`, `{{options.x}}`, `{{arguments.x}}`) emit shell-quoted variable references and
|
|
240
|
+
are always safe -- a value like `*.md` passed via `{{arguments.target}}` reaches the wrapped tool
|
|
241
|
+
verbatim, with no glob expansion. The unquoted-token concern applies *only* to the static literal
|
|
242
|
+
strings you put in `template.command`. The codegen lays each literal token down unquoted in the
|
|
243
|
+
generated `exec` line, so bash sees them raw. This works for simple words, flags, and
|
|
244
|
+
comma-separated lists (e.g. `--json title,body,state`), which covers the vast majority of cases.
|
|
245
|
+
It does *not* work for literal tokens containing shell-special characters -- braces, parens,
|
|
246
|
+
brackets, glob characters (`*`, `?`), tilde, redirects, pipes, dollar signs, backticks, quotes,
|
|
247
|
+
whitespace, etc. If you need a literal token like that (a `jq` expression, etc.), or if you need
|
|
248
|
+
any pipe / redirection / transformation logic, use `script` mode instead.
|
|
249
|
+
|
|
238
250
|
Example:
|
|
239
251
|
|
|
240
252
|
```yaml
|
|
@@ -299,6 +311,33 @@ safe-find:
|
|
|
299
311
|
prefix: [.]
|
|
300
312
|
```
|
|
301
313
|
|
|
314
|
+
#### Known security limitations
|
|
315
|
+
|
|
316
|
+
Passthrough deny operates on whole tokens, so it cannot enforce restrictions when the wrapped
|
|
317
|
+
tool accepts alternative flag syntax:
|
|
318
|
+
|
|
319
|
+
- **Short-flag stacking.** Tools that use POSIX-style or `pflag` short flags (notably `kubectl`,
|
|
320
|
+
many `getopt`-based utilities) allow combining boolean short flags into one token: `-Aw` is
|
|
321
|
+
parsed as `-A -w`. A deny entry of `-w` matches only the exact token `-w`, not `-Aw`, `-wA`,
|
|
322
|
+
`-Aow`, or any other stack containing `w`.
|
|
323
|
+
- **Inline value forms.** For a flag that takes a value, the deny patterns `--watch` and `-w`
|
|
324
|
+
do not catch `--watch=true`, `-w=true`, or `-wtrue` (BSD-style short flag with concatenated
|
|
325
|
+
value). The first two can be partially mitigated with glob denies like `--watch=*` and
|
|
326
|
+
`-w=*`. The concatenated form `-wtrue` is syntactically indistinguishable from a short-flag
|
|
327
|
+
stack and cannot be reliably denied at the token level.
|
|
328
|
+
|
|
329
|
+
**When this matters.** Use `template` mode when the wrapped tool is an agent-escape vector and
|
|
330
|
+
supports either of the above syntaxes. Templates declare the entire surface up front, so any
|
|
331
|
+
flag not declared in the manifest cannot reach the underlying command. Use passthrough only
|
|
332
|
+
when the wrapped tool's flag surface is well-understood, or when an undeclared flag slipping
|
|
333
|
+
through is purely an ergonomic issue rather than a safety one.
|
|
334
|
+
|
|
335
|
+
**Future direction.** A future opt-in deny extension may recognize tokens matching
|
|
336
|
+
`^-[a-zA-Z]{2,}$` and decompose them for deny matching, closing the short-flag-stacking gap.
|
|
337
|
+
The concatenated-value form is likely to remain a passthrough limitation because it cannot be
|
|
338
|
+
distinguished from a stack without per-tool flag knowledge. When in doubt, prefer template
|
|
339
|
+
mode.
|
|
340
|
+
|
|
302
341
|
### script
|
|
303
342
|
|
|
304
343
|
Run an inline bash script. Best for tools that need custom logic beyond wrapping a single command.
|
|
@@ -386,6 +425,8 @@ options:
|
|
|
386
425
|
pattern: <string> # Regex the value must match (auto-anchored with ^...$)
|
|
387
426
|
allow: [<string>, ...] # Exhaustive list of allowed values
|
|
388
427
|
deny: [<string>, ...] # Values to reject
|
|
428
|
+
path_tests: [<test>, ...] # Mark as a filesystem path; see "Path tests" below
|
|
429
|
+
default: <string> # Default value seeded into the bash variable when the flag is omitted
|
|
389
430
|
```
|
|
390
431
|
|
|
391
432
|
Rules:
|
|
@@ -396,6 +437,12 @@ Rules:
|
|
|
396
437
|
- `pattern` is automatically anchored to a full match in the generated bash script.
|
|
397
438
|
- When `repeatable: true`, the option can be passed multiple times. The generated script accumulates
|
|
398
439
|
flag-value pairs in an array so `"${VAR[@]}"` expands to `--flag val1 --flag val2`.
|
|
440
|
+
- `default` seeds the bash variable so inline placeholder substitutions like
|
|
441
|
+
`"{{options.x}}/foo"` see the value even when the agent omits the flag. `default` is
|
|
442
|
+
validated at manifest-load time: it must satisfy `pattern` / `allow` / `deny`, and is
|
|
443
|
+
mutually exclusive with `required: true`, `repeatable: true`, and `path_tests`
|
|
444
|
+
(path tests only evaluate against runtime cwd, so they cannot validate a load-time
|
|
445
|
+
default). `default` must be a string; YAML `null`, `true`, `0`, etc. are rejected.
|
|
399
446
|
|
|
400
447
|
### arguments
|
|
401
448
|
|
|
@@ -411,6 +458,7 @@ arguments:
|
|
|
411
458
|
pattern: <string> # Regex the value must match (auto-anchored)
|
|
412
459
|
allow: [<string>, ...] # Exhaustive list of allowed values
|
|
413
460
|
deny: [<string>, ...] # Values to reject
|
|
461
|
+
path_tests: [<test>, ...] # Mark as a filesystem path; see "Path tests" below
|
|
414
462
|
```
|
|
415
463
|
|
|
416
464
|
Rules:
|
|
@@ -421,6 +469,104 @@ Rules:
|
|
|
421
469
|
- Variadic arguments become bash arrays; all others become scalar variables.
|
|
422
470
|
- By default, variadic arguments reject tokens starting with `-` to prevent flag injection. Set
|
|
423
471
|
`allow_flags: true` when forwarding to a tool that expects its own flags (e.g. pytest, ruff).
|
|
472
|
+
- Arguments do not have a `default` field. Required positional arguments always receive a value;
|
|
473
|
+
optional positionals are exposed to the wrapped tool only when the agent supplies one.
|
|
474
|
+
|
|
475
|
+
## Path tests
|
|
476
|
+
|
|
477
|
+
Mark an option or argument as a filesystem path by setting `path_tests` to a non-empty list of
|
|
478
|
+
test names. The generated script applies a baseline check (control characters rejected,
|
|
479
|
+
canonicalization succeeds) plus the listed tests in a deterministic order.
|
|
480
|
+
|
|
481
|
+
```yaml
|
|
482
|
+
options:
|
|
483
|
+
directory:
|
|
484
|
+
description: Directory to run in
|
|
485
|
+
flag: -C
|
|
486
|
+
path_tests: [under_cwd, dir]
|
|
487
|
+
arguments:
|
|
488
|
+
target:
|
|
489
|
+
description: File to format
|
|
490
|
+
required: true
|
|
491
|
+
path_tests: [under_cwd, file]
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
### Test catalog
|
|
495
|
+
|
|
496
|
+
| Test | Meaning | Bash primitive |
|
|
497
|
+
| ------------- | --------------------------------------------------------------- | -------------- |
|
|
498
|
+
| `under_cwd` | Canonicalized path is `$PWD` itself or under it (symlink-aware) | `realpath -m` |
|
|
499
|
+
| `exists` | Path exists | `[[ -e ]]` |
|
|
500
|
+
| `not_exists` | Path does not exist (e.g. for new-file targets) | `[[ ! -e ]]` |
|
|
501
|
+
| `file` | Exists and is a regular file (implies `exists`) | `[[ -f ]]` |
|
|
502
|
+
| `dir` | Exists and is a directory (implies `exists`) | `[[ -d ]]` |
|
|
503
|
+
| `readable` | Readable by the current user (implies `exists`) | `[[ -r ]]` |
|
|
504
|
+
| `writable` | Writable by the current user (implies `exists`) | `[[ -w ]]` |
|
|
505
|
+
| `executable` | Executable by the current user (implies `exists`) | `[[ -x ]]` |
|
|
506
|
+
| `symlink` | Path is a symlink | `[[ -L ]]` |
|
|
507
|
+
| `not_symlink` | Path is not a symlink | `! [[ -L ]]` |
|
|
508
|
+
|
|
509
|
+
**Symlinks behave differently across tests.** `under_cwd` follows symlinks via `realpath -m`,
|
|
510
|
+
so a symlink whose target is outside the workspace fails the boundary check even if the link
|
|
511
|
+
itself is inside. The `exists`/`file`/`dir`/`readable`/`writable`/`executable` tests also follow
|
|
512
|
+
symlinks (they check the target, not the link). Only `symlink` and `not_symlink` test the path
|
|
513
|
+
itself without following the link. Combine them deliberately if you mean both, e.g.
|
|
514
|
+
`[under_cwd, file]` requires the resolved target to be a regular file inside the workspace,
|
|
515
|
+
while `[under_cwd, not_symlink, file]` additionally rejects symlinks even when their targets
|
|
516
|
+
would qualify.
|
|
517
|
+
|
|
518
|
+
### Evaluation order
|
|
519
|
+
|
|
520
|
+
For each path-typed parameter, the helper runs:
|
|
521
|
+
|
|
522
|
+
1. **Baseline** -- reject `\n` / `\r` / `\t` in the input, canonicalize `$PWD` and the input.
|
|
523
|
+
2. **Boundary** -- `under_cwd`.
|
|
524
|
+
3. **Existence** -- `exists`, `not_exists`.
|
|
525
|
+
4. **Type** -- `file`, `dir`, `symlink`, `not_symlink`.
|
|
526
|
+
5. **Access** -- `readable`, `writable`, `executable`.
|
|
527
|
+
|
|
528
|
+
The helper short-circuits on the first failure and reports the failed test name.
|
|
529
|
+
|
|
530
|
+
### Rules
|
|
531
|
+
|
|
532
|
+
- `path_tests` only applies to `options` and `arguments`, not `switches`.
|
|
533
|
+
- An empty list is rejected at validation time. Omit the field entirely if you do not want path
|
|
534
|
+
validation.
|
|
535
|
+
- Mutually exclusive: `exists` and `not_exists`; `file` and `dir`; `symlink` and `not_symlink`.
|
|
536
|
+
- `not_exists` cannot be combined with `file`, `dir`, `readable`, `writable`, `executable`, or
|
|
537
|
+
`symlink` -- those tests require the path to exist.
|
|
538
|
+
- Unknown test names are rejected at validation time.
|
|
539
|
+
- For variadic arguments the helper runs once per element.
|
|
540
|
+
- Optional parameters are skipped when unset; required parameters are checked after the
|
|
541
|
+
required-value check.
|
|
542
|
+
|
|
543
|
+
### Threat-scope implication
|
|
544
|
+
|
|
545
|
+
A parameter with `path_tests: [under_cwd, ...]` is constrained to the workspace, so the tool can
|
|
546
|
+
credibly claim `read: workspace` or `write: workspace` rather than `read: machine` or
|
|
547
|
+
`write: machine` for that filesystem-touching surface.
|
|
548
|
+
|
|
549
|
+
### Don't duplicate the wrapped tool's own checks
|
|
550
|
+
|
|
551
|
+
`path_tests` exists to enforce *boundaries* (workspace containment, control characters, basic
|
|
552
|
+
canonicalization). It is not a place to recreate validation that the wrapped tool already does.
|
|
553
|
+
For most cases, `[under_cwd]` alone is the right answer: it locks the path to the workspace and
|
|
554
|
+
delegates type, existence, and content checks to the tool you're calling.
|
|
555
|
+
|
|
556
|
+
For example, `git -C <dir>` already produces a clear `fatal: cannot change to '...': Not a
|
|
557
|
+
directory` if the path is wrong. Adding `dir` to `path_tests` would only duplicate that check
|
|
558
|
+
and produce a less informative error than git's. Reach for the longer test lists only when the
|
|
559
|
+
wrapped tool's behavior on the failure mode is genuinely worse than failing at the boundary
|
|
560
|
+
(e.g. silently no-oping, hanging, or modifying state).
|
|
561
|
+
|
|
562
|
+
### Caveats
|
|
563
|
+
|
|
564
|
+
- Symlink resolution uses `realpath -m`, which follows symlinks. A symlink inside `$PWD` whose
|
|
565
|
+
target is outside `$PWD` fails `under_cwd`. This is intentional.
|
|
566
|
+
- The check is not a security boundary against an adversarial filesystem actor (TOCTOU between
|
|
567
|
+
validation and use is possible).
|
|
568
|
+
- `realpath` is required and is part of GNU coreutils on Linux and modern macOS coreutils. Pure
|
|
569
|
+
BSD environments are not supported.
|
|
424
570
|
|
|
425
571
|
## Lifecycle
|
|
426
572
|
|
|
@@ -462,7 +608,14 @@ The pre script is wrapped in a shell function (`_nerf_pre`). Key points:
|
|
|
462
608
|
- **Print your own error messages.** The fallback message is generic. Write `echo "error: ..." >&2`
|
|
463
609
|
before `return 1`.
|
|
464
610
|
- **Shell variables set in pre are visible to main.** Functions execute in the caller's scope.
|
|
611
|
+
Do **not** use `local` -- a `local` declaration limits scope to the function body and the
|
|
612
|
+
variable will be empty when main runs.
|
|
465
613
|
- **`{{kind.name}}` placeholders work.** Parameters are parsed before pre runs.
|
|
614
|
+
- **`set -e` does NOT abort pre on bare command failure.** Bash suppresses errexit inside any
|
|
615
|
+
function whose return code is being tested by the caller, and the wrapper invokes pre via
|
|
616
|
+
`_nerf_pre || _nerf_pre_rc=$?`. Even adding `set -e` inside the function body has no effect
|
|
617
|
+
per POSIX/bash semantics. **Always check command results explicitly with `if`/`||` and
|
|
618
|
+
`return 1`.**
|
|
466
619
|
|
|
467
620
|
Example:
|
|
468
621
|
|
|
@@ -543,7 +696,8 @@ error: nerf-safe-find: token '-exec' is not allowed (matched deny pattern '-exec
|
|
|
543
696
|
|
|
544
697
|
## Dry-run mode
|
|
545
698
|
|
|
546
|
-
Every generated tool supports `--nerf-dry-run`. When passed
|
|
699
|
+
Every generated tool supports `--nerf-dry-run`. When passed in the flag region (before any
|
|
700
|
+
positional argument), the tool runs all
|
|
547
701
|
validation, guards, pre-hooks, and deny scans as normal, but instead of executing the final command
|
|
548
702
|
it prints what would be run and exits.
|
|
549
703
|
|
|
@@ -565,8 +719,12 @@ $ nerf-find-cwd --nerf-dry-run -exec echo {} \;
|
|
|
565
719
|
error: nerf-find-cwd: token '-exec' is not allowed (matched deny pattern '-exec')
|
|
566
720
|
```
|
|
567
721
|
|
|
568
|
-
`--nerf-dry-run`
|
|
569
|
-
|
|
722
|
+
`--nerf-dry-run` may appear anywhere in the flag region (before the first positional argument);
|
|
723
|
+
like other declared flags it is recognized in any order. The parser stops consuming flags at the
|
|
724
|
+
first non-flag token, so `--nerf-dry-run` placed after a positional argument is captured into
|
|
725
|
+
that argument (or rejected as an extra) and does not enable dry-run. For tools with
|
|
726
|
+
variadic+allow_flags arguments, the codegen rejects `--nerf-dry-run` tokens inside the variadic
|
|
727
|
+
explicitly to prevent silent dry-run bypass.
|
|
570
728
|
|
|
571
729
|
## Generated documentation
|
|
572
730
|
|
|
@@ -606,3 +764,9 @@ Generated skill files follow the same structure formatted as markdown for AI ass
|
|
|
606
764
|
| `pattern` is a valid regex | options, arguments |
|
|
607
765
|
| `env` keys match `[A-Z_][A-Z0-9_]*` | env |
|
|
608
766
|
| Guard has exactly one of `command` or `script` | guards |
|
|
767
|
+
| `path_tests` is non-empty if present | options, arguments |
|
|
768
|
+
| `path_tests` entries are known names | options, arguments |
|
|
769
|
+
| `path_tests` mutual exclusions enforced | options, arguments |
|
|
770
|
+
| `default` must be a string | options |
|
|
771
|
+
| `default` mutually exclusive with `required`, `repeatable`, `path_tests` | options |
|
|
772
|
+
| `default` must satisfy `pattern` / `allow` / `deny` if present | options |
|