opnsense-openapi 0.2.0__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- opnsense_openapi-0.3.0/.claude/CLAUDE.md +64 -0
- opnsense_openapi-0.3.0/.claude/agents/implement-worker.md +67 -0
- opnsense_openapi-0.3.0/.claude/commands/close-issue.md +86 -0
- opnsense_openapi-0.3.0/.claude/commands/finalize.md +86 -0
- opnsense_openapi-0.3.0/.claude/commands/gemini-review.md +42 -0
- opnsense_openapi-0.3.0/.claude/commands/implement.md +81 -0
- opnsense_openapi-0.3.0/.claude/commands/plan-both.md +107 -0
- opnsense_openapi-0.3.0/.claude/commands/plan-issue.md +94 -0
- opnsense_openapi-0.3.0/.claude/commands/review-both.md +105 -0
- opnsense_openapi-0.3.0/.claude/commands/where-am-i.md +75 -0
- opnsense_openapi-0.3.0/.claude/lsp-setup.md +208 -0
- opnsense_openapi-0.3.0/.claude/settings.json +30 -0
- opnsense_openapi-0.3.0/.claude/statusline-command.sh +225 -0
- opnsense_openapi-0.3.0/.codex/config.toml +169 -0
- opnsense_openapi-0.3.0/.config/pyproject_template/settings.toml +3 -0
- opnsense_openapi-0.3.0/.copilot/README.md +33 -0
- opnsense_openapi-0.3.0/.devcontainer/devcontainer.json +43 -0
- opnsense_openapi-0.3.0/.editorconfig +22 -0
- opnsense_openapi-0.3.0/.envrc +43 -0
- opnsense_openapi-0.3.0/.envrc.local.example +30 -0
- opnsense_openapi-0.3.0/.gemini/commands/plan-issue.md +69 -0
- opnsense_openapi-0.3.0/.gemini/commands/review-pr.md +90 -0
- opnsense_openapi-0.3.0/.gemini/settings.json +52 -0
- opnsense_openapi-0.3.0/.github/CODEOWNERS +37 -0
- opnsense_openapi-0.3.0/.github/CODE_OF_CONDUCT.md +133 -0
- opnsense_openapi-0.3.0/.github/CONTRIBUTING.md +911 -0
- opnsense_openapi-0.3.0/.github/ISSUE_TEMPLATE/bug_report.yml +80 -0
- opnsense_openapi-0.3.0/.github/ISSUE_TEMPLATE/chore.yml +72 -0
- opnsense_openapi-0.3.0/.github/ISSUE_TEMPLATE/config.yml +8 -0
- opnsense_openapi-0.3.0/.github/ISSUE_TEMPLATE/documentation.yml +74 -0
- opnsense_openapi-0.3.0/.github/ISSUE_TEMPLATE/feature_request.yml +58 -0
- opnsense_openapi-0.3.0/.github/ISSUE_TEMPLATE/refactor.yml +60 -0
- opnsense_openapi-0.3.0/.github/SECURITY.md +113 -0
- opnsense_openapi-0.3.0/.github/actions/python-versions/action.yml +25 -0
- opnsense_openapi-0.3.0/.github/automerge-config.json +19 -0
- opnsense_openapi-0.3.0/.github/dependabot.yml +35 -0
- opnsense_openapi-0.3.0/.github/hooks/copilot-hooks.json +13 -0
- opnsense_openapi-0.3.0/.github/labels.yml +56 -0
- opnsense_openapi-0.3.0/.github/pull_request_template.md +55 -0
- opnsense_openapi-0.3.0/.github/python-versions.json +4 -0
- opnsense_openapi-0.3.0/.github/release.yml +30 -0
- opnsense_openapi-0.3.0/.github/workflows/benchmark.yml +108 -0
- opnsense_openapi-0.3.0/.github/workflows/breaking-change-detection.yml +157 -0
- opnsense_openapi-0.3.0/.github/workflows/ci-full-matrix.yml +18 -0
- opnsense_openapi-0.3.0/.github/workflows/ci.yml +210 -0
- opnsense_openapi-0.3.0/.github/workflows/codeql.yml +70 -0
- opnsense_openapi-0.3.0/.github/workflows/dependabot-automerge.yml +288 -0
- opnsense_openapi-0.3.0/.github/workflows/dependabot-blocked-label.yml +62 -0
- opnsense_openapi-0.3.0/.github/workflows/generate-matrix.yml +47 -0
- opnsense_openapi-0.3.0/.github/workflows/merge-gate.yml +21 -0
- opnsense_openapi-0.3.0/.github/workflows/mutation.yml +74 -0
- opnsense_openapi-0.3.0/.github/workflows/pr-checks.yml +145 -0
- opnsense_openapi-0.3.0/.github/workflows/release.yml +145 -0
- opnsense_openapi-0.3.0/.github/workflows/testpypi.yml +76 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/.gitignore +41 -17
- opnsense_openapi-0.3.0/.pre-commit-config.yaml +210 -0
- opnsense_openapi-0.3.0/.python-version +1 -0
- opnsense_openapi-0.3.0/.vscode/extensions.json +9 -0
- opnsense_openapi-0.3.0/.vscode/launch.json +43 -0
- opnsense_openapi-0.3.0/.vscode/settings.json +23 -0
- opnsense_openapi-0.3.0/.vscode/tasks.json +54 -0
- opnsense_openapi-0.3.0/AGENTS.md +413 -0
- opnsense_openapi-0.3.0/CHANGELOG.md +94 -0
- opnsense_openapi-0.3.0/CLAUDE.md +104 -0
- opnsense_openapi-0.3.0/GEMINI.md +32 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/PKG-INFO +57 -11
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/README.md +1 -1
- opnsense_openapi-0.3.0/bootstrap.py +297 -0
- opnsense_openapi-0.3.0/completions/doit.bash +130 -0
- opnsense_openapi-0.3.0/completions/doit.zsh +236 -0
- opnsense_openapi-0.3.0/docs/TABLE_OF_CONTENTS.md +157 -0
- opnsense_openapi-0.3.0/docs/decisions/9001-use-uv-for-package-management.md +23 -0
- opnsense_openapi-0.3.0/docs/decisions/9002-use-doit-for-task-automation.md +50 -0
- opnsense_openapi-0.3.0/docs/decisions/9003-use-ruff-for-linting-and-formatting.md +21 -0
- opnsense_openapi-0.3.0/docs/decisions/9004-auto-discover-doit-tasks.md +21 -0
- opnsense_openapi-0.3.0/docs/decisions/9005-ai-agent-command-restrictions.md +29 -0
- opnsense_openapi-0.3.0/docs/decisions/9006-merge-gate-workflow.md +26 -0
- opnsense_openapi-0.3.0/docs/decisions/9007-use-mypy-for-type-checking.md +21 -0
- opnsense_openapi-0.3.0/docs/decisions/9008-pr-based-development-workflow.md +24 -0
- opnsense_openapi-0.3.0/docs/decisions/9009-use-pre-commit-hooks-for-quality-gates.md +25 -0
- opnsense_openapi-0.3.0/docs/decisions/9010-use-conventional-commits-format.md +23 -0
- opnsense_openapi-0.3.0/docs/decisions/9011-use-pytest-for-testing.md +23 -0
- opnsense_openapi-0.3.0/docs/decisions/9012-use-mkdocs-with-material-theme-for-documentation.md +24 -0
- opnsense_openapi-0.3.0/docs/decisions/9013-python-version-support-policy.md +45 -0
- opnsense_openapi-0.3.0/docs/decisions/9014-use-click-for-application-cli.md +92 -0
- opnsense_openapi-0.3.0/docs/decisions/9015-install-tools-framework-archive-extraction-and-custom-urls.md +47 -0
- opnsense_openapi-0.3.0/docs/decisions/9016-unify-adr-directories.md +70 -0
- opnsense_openapi-0.3.0/docs/decisions/README.md +105 -0
- opnsense_openapi-0.3.0/docs/decisions/adr-template.md +24 -0
- opnsense_openapi-0.3.0/docs/deployment/development.md +555 -0
- opnsense_openapi-0.3.0/docs/deployment/production.md +719 -0
- opnsense_openapi-0.2.0/docs/PUBLISHING.md → opnsense_openapi-0.3.0/docs/deployment/publishing.md +11 -0
- opnsense_openapi-0.3.0/docs/development/AI_SETUP.md +423 -0
- opnsense_openapi-0.3.0/docs/development/ai/architectural-conventions.md +87 -0
- opnsense_openapi-0.3.0/docs/development/ai/command-blocking.md +263 -0
- opnsense_openapi-0.3.0/docs/development/ai/enforcement-principles.md +292 -0
- opnsense_openapi-0.3.0/docs/development/ai/first-5-minutes.md +148 -0
- opnsense_openapi-0.3.0/docs/development/ai/ruff-fix-hook.md +86 -0
- opnsense_openapi-0.3.0/docs/development/ai/slash-commands.md +144 -0
- opnsense_openapi-0.3.0/docs/development/ai/statusline.md +104 -0
- opnsense_openapi-0.2.0/docs/ARCHITECTURE.md → opnsense_openapi-0.3.0/docs/development/architecture.md +12 -0
- opnsense_openapi-0.3.0/docs/development/ci-cd-testing.md +841 -0
- opnsense_openapi-0.3.0/docs/development/coding-standards.md +617 -0
- opnsense_openapi-0.3.0/docs/development/dependabot-automerge.md +192 -0
- opnsense_openapi-0.3.0/docs/development/doit-tasks-reference.md +1163 -0
- opnsense_openapi-0.3.0/docs/development/extensions.md +992 -0
- opnsense_openapi-0.3.0/docs/development/github-repository-settings.md +338 -0
- opnsense_openapi-0.2.0/docs/HEURISTICS.md → opnsense_openapi-0.3.0/docs/development/heuristics.md +12 -1
- opnsense_openapi-0.3.0/docs/development/install-tools-framework.md +169 -0
- opnsense_openapi-0.3.0/docs/development/release-and-automation.md +955 -0
- opnsense_openapi-0.3.0/docs/development/tooling-roles.md +103 -0
- opnsense_openapi-0.3.0/docs/examples/README.md +81 -0
- opnsense_openapi-0.3.0/docs/getting-started/installation.md +156 -0
- opnsense_openapi-0.3.0/docs/index.md +82 -0
- opnsense_openapi-0.3.0/docs/reference/api.md +85 -0
- opnsense_openapi-0.3.0/docs/template/ai-sync-checklist.md +275 -0
- opnsense_openapi-0.3.0/docs/template/index.md +86 -0
- opnsense_openapi-0.3.0/docs/template/manage.md +231 -0
- opnsense_openapi-0.3.0/docs/template/migration.md +91 -0
- opnsense_openapi-0.3.0/docs/template/new-project.md +246 -0
- opnsense_openapi-0.3.0/docs/template/tools-reference.md +425 -0
- opnsense_openapi-0.3.0/docs/template/updates.md +221 -0
- opnsense_openapi-0.3.0/docs/usage/basics.md +808 -0
- opnsense_openapi-0.3.0/docs/usage/cli.md +192 -0
- opnsense_openapi-0.2.0/docs/GENERATED_CLIENT_USAGE.md → opnsense_openapi-0.3.0/docs/usage/generated-client.md +14 -3
- opnsense_openapi-0.3.0/dodo.py +9 -0
- opnsense_openapi-0.3.0/mkdocs.yml +131 -0
- opnsense_openapi-0.3.0/pyproject.toml +342 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/__init__.py +5 -2
- opnsense_openapi-0.3.0/src/opnsense_openapi/_version.py +24 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/cli.py +27 -12
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/client/__init__.py +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/client/base.py +6 -5
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/downloader/source_downloader.py +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/generator/openapi_generator.py +6 -6
- opnsense_openapi-0.3.0/src/opnsense_openapi/logging.py +147 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/openapi.py +2 -2
- opnsense_openapi-0.3.0/src/opnsense_openapi/py.typed +3 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-24.1.1.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-24.1.10.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-24.1.2.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-24.1.3.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-24.1.4.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-24.1.5.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-24.1.6.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-24.1.7.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-24.1.8.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-24.1.9.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-24.1.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-24.7.1.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-24.7.10.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-24.7.11.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-24.7.12.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-24.7.2.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-24.7.3.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-24.7.4.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-24.7.5.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-24.7.6.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-24.7.7.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-24.7.8.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-24.7.9.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-24.7.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-25.1.1.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-25.1.10.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-25.1.11.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-25.1.12.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-25.1.2.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-25.1.3.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-25.1.4.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-25.1.5.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-25.1.6.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-25.1.7.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-25.1.8.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-25.1.9.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-25.1.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-25.7.1.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-25.7.10.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-25.7.11.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-25.7.2.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-25.7.3.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-25.7.4.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-25.7.5.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-25.7.6.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-25.7.7.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-25.7.8.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-25.7.9.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-25.7.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-26.1.1.json +1 -1
- opnsense_openapi-0.3.0/src/opnsense_openapi/specs/opnsense-26.1.2.json +44682 -0
- opnsense_openapi-0.3.0/src/opnsense_openapi/specs/opnsense-26.1.3.json +44762 -0
- opnsense_openapi-0.3.0/src/opnsense_openapi/specs/opnsense-26.1.4.json +44770 -0
- opnsense_openapi-0.3.0/src/opnsense_openapi/specs/opnsense-26.1.5.json +45129 -0
- opnsense_openapi-0.3.0/src/opnsense_openapi/specs/opnsense-26.1.6.json +45283 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs/opnsense-26.1.json +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/validator.py +1 -1
- opnsense_openapi-0.3.0/tests/benchmarks/__init__.py +0 -0
- opnsense_openapi-0.3.0/tests/benchmarks/conftest.py +6 -0
- opnsense_openapi-0.3.0/tests/benchmarks/test_bench_generator.py +79 -0
- opnsense_openapi-0.3.0/tests/benchmarks/test_bench_parser.py +104 -0
- opnsense_openapi-0.3.0/tests/conftest.py +233 -0
- opnsense_openapi-0.3.0/tests/template/__init__.py +0 -0
- opnsense_openapi-0.3.0/tests/template/test_bootstrap.py +440 -0
- opnsense_openapi-0.3.0/tests/template/test_cleanup.py +342 -0
- opnsense_openapi-0.3.0/tests/template/test_doit_adr.py +290 -0
- opnsense_openapi-0.3.0/tests/template/test_doit_benchmark.py +64 -0
- opnsense_openapi-0.3.0/tests/template/test_doit_discovery.py +52 -0
- opnsense_openapi-0.3.0/tests/template/test_doit_github.py +1005 -0
- opnsense_openapi-0.3.0/tests/template/test_doit_install.py +109 -0
- opnsense_openapi-0.3.0/tests/template/test_doit_install_tools.py +906 -0
- opnsense_openapi-0.3.0/tests/template/test_doit_release.py +725 -0
- opnsense_openapi-0.3.0/tests/template/test_properties.py +176 -0
- opnsense_openapi-0.3.0/tests/template/test_pyproject_template_main.py +959 -0
- opnsense_openapi-0.3.0/tests/template/test_repo_settings.py +272 -0
- opnsense_openapi-0.3.0/tests/template/test_setup_repo.py +521 -0
- opnsense_openapi-0.3.0/tests/template/test_templates.py +357 -0
- opnsense_openapi-0.3.0/tests/template/test_utils.py +613 -0
- opnsense_openapi-0.3.0/tests/test_benchmark_workflow.py +214 -0
- opnsense_openapi-0.3.0/tests/test_ci_full_matrix_workflow.py +140 -0
- opnsense_openapi-0.3.0/tests/test_ci_workflow.py +166 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/tests/test_cli_comprehensive.py +1 -1
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/tests/test_cli_download.py +5 -5
- opnsense_openapi-0.3.0/tests/test_client_auto_generate.py +97 -0
- opnsense_openapi-0.3.0/tests/test_codeql_workflow.py +277 -0
- opnsense_openapi-0.3.0/tests/test_dependabot_automerge_workflow.py +397 -0
- opnsense_openapi-0.3.0/tests/test_dependabot_blocked_label_workflow.py +208 -0
- opnsense_openapi-0.3.0/tests/test_generated_api.py +162 -0
- opnsense_openapi-0.3.0/tests/test_hook_ruff_fix.py +264 -0
- opnsense_openapi-0.3.0/tests/test_logging.py +307 -0
- opnsense_openapi-0.3.0/tests/test_release_workflow.py +76 -0
- opnsense_openapi-0.3.0/tests/test_source_downloader.py +236 -0
- opnsense_openapi-0.3.0/tests/test_testpypi_workflow.py +73 -0
- opnsense_openapi-0.3.0/tests/test_utils.py +74 -0
- opnsense_openapi-0.3.0/tmp/.gitkeep +0 -0
- opnsense_openapi-0.3.0/tools/__init__.py +1 -0
- opnsense_openapi-0.3.0/tools/doit/__init__.py +42 -0
- opnsense_openapi-0.3.0/tools/doit/adr.py +395 -0
- opnsense_openapi-0.3.0/tools/doit/base.py +174 -0
- opnsense_openapi-0.3.0/tools/doit/benchmark.py +38 -0
- opnsense_openapi-0.3.0/tools/doit/build.py +30 -0
- opnsense_openapi-0.3.0/tools/doit/docs.py +47 -0
- opnsense_openapi-0.3.0/tools/doit/git.py +49 -0
- opnsense_openapi-0.3.0/tools/doit/github.py +1409 -0
- opnsense_openapi-0.3.0/tools/doit/install.py +57 -0
- opnsense_openapi-0.3.0/tools/doit/install_tools.py +349 -0
- opnsense_openapi-0.3.0/tools/doit/maintenance.py +326 -0
- opnsense_openapi-0.3.0/tools/doit/project.py +27 -0
- opnsense_openapi-0.3.0/tools/doit/quality.py +78 -0
- opnsense_openapi-0.3.0/tools/doit/release.py +687 -0
- opnsense_openapi-0.3.0/tools/doit/security.py +53 -0
- opnsense_openapi-0.3.0/tools/doit/template_clean.py +114 -0
- opnsense_openapi-0.3.0/tools/doit/templates.py +359 -0
- opnsense_openapi-0.3.0/tools/doit/testing.py +38 -0
- opnsense_openapi-0.3.0/tools/generate_doc_toc.py +249 -0
- opnsense_openapi-0.3.0/tools/hooks/ai/block-dangerous-commands.py +508 -0
- opnsense_openapi-0.3.0/tools/hooks/ai/ruff-fix-on-edit.py +147 -0
- opnsense_openapi-0.3.0/tools/hooks/ai/test_hook.py +190 -0
- opnsense_openapi-0.3.0/tools/pyproject_template/__init__.py +70 -0
- opnsense_openapi-0.3.0/tools/pyproject_template/check_template_updates.py +320 -0
- opnsense_openapi-0.3.0/tools/pyproject_template/cleanup.py +358 -0
- opnsense_openapi-0.3.0/tools/pyproject_template/configure.py +502 -0
- opnsense_openapi-0.3.0/tools/pyproject_template/manage.py +908 -0
- opnsense_openapi-0.3.0/tools/pyproject_template/migrate_existing_project.py +261 -0
- opnsense_openapi-0.3.0/tools/pyproject_template/repo_settings.py +433 -0
- opnsense_openapi-0.3.0/tools/pyproject_template/settings.py +464 -0
- opnsense_openapi-0.3.0/tools/pyproject_template/setup_repo.py +844 -0
- opnsense_openapi-0.3.0/tools/pyproject_template/utils.py +480 -0
- opnsense_openapi-0.3.0/uv.lock +2722 -0
- opnsense_openapi-0.2.0/.envrc +0 -4
- opnsense_openapi-0.2.0/.envrc.local.example +0 -7
- opnsense_openapi-0.2.0/.github/workflows/ci.yml +0 -73
- opnsense_openapi-0.2.0/.github/workflows/release.yaml +0 -81
- opnsense_openapi-0.2.0/.pre-commit-config.yaml +0 -12
- opnsense_openapi-0.2.0/AGENTS.md +0 -61
- opnsense_openapi-0.2.0/CLAUDE.md +0 -70
- opnsense_openapi-0.2.0/justfile +0 -95
- opnsense_openapi-0.2.0/pyproject.toml +0 -83
- opnsense_openapi-0.2.0/uv.lock +0 -1231
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/LICENSE +0 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/examples/basic_usage.py +0 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/examples/diagnose_api.py +0 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/examples/openapi_example.py +0 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/client/generated_api.py +0 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/downloader/__init__.py +0 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/generated/.gitignore +0 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/generated/README.md +0 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/generator/__init__.py +0 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/parser/__init__.py +0 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/parser/controller_parser.py +0 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/specs.py +0 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/src/opnsense_openapi/utils.py +0 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/tests/__init__.py +0 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/tests/test_client.py +0 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/tests/test_openapi_generator.py +0 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/tests/test_openapi_generator_advanced.py +0 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/tests/test_parser.py +0 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/tests/test_specs.py +0 -0
- {opnsense_openapi-0.2.0 → opnsense_openapi-0.3.0}/tests/test_validator.py +0 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
@../AGENTS.md
|
|
2
|
+
|
|
3
|
+
# BASIC CLAUDE INSTRUCTIONS
|
|
4
|
+
|
|
5
|
+
Claude's #1 priority is to use tokens efficiently:
|
|
6
|
+
- Keep responses brief and to the point
|
|
7
|
+
- Use local tools (Grep, Read, Edit) as a priority over Task tool
|
|
8
|
+
- Only use the Task tool when necessary
|
|
9
|
+
- Always inform user and ask for consent before starting sub agents
|
|
10
|
+
|
|
11
|
+
Examples of when to use local tools instead of Task tool:
|
|
12
|
+
- Updating types in function declarations
|
|
13
|
+
- Creating or updating documentation
|
|
14
|
+
- Renaming variables, functions, etc.
|
|
15
|
+
- Simple code refactoring
|
|
16
|
+
|
|
17
|
+
# TODOWRITE USAGE (MANDATORY)
|
|
18
|
+
|
|
19
|
+
When creating new code (functions, modules, commands, features), Claude MUST use TodoWrite to plan ALL steps:
|
|
20
|
+
|
|
21
|
+
**Required todo items for any code task:**
|
|
22
|
+
1. Implementation file(s)
|
|
23
|
+
2. Test file(s) - NEVER skip this
|
|
24
|
+
3. Run `doit check` to verify
|
|
25
|
+
4. Manual verification/testing
|
|
26
|
+
|
|
27
|
+
**Why this is mandatory:**
|
|
28
|
+
- Removes judgment calls about whether to write tests
|
|
29
|
+
- Makes testing systematic, not optional
|
|
30
|
+
- Ensures complete implementation (code + tests + validation)
|
|
31
|
+
- Provides visibility to user about progress
|
|
32
|
+
|
|
33
|
+
**Examples of when to use TodoWrite:**
|
|
34
|
+
- Creating new Python modules or functions
|
|
35
|
+
- Adding CLI commands or API endpoints
|
|
36
|
+
- Implementing new features or bug fixes
|
|
37
|
+
- Any task involving writing new Python code
|
|
38
|
+
|
|
39
|
+
**Example todo list for "create new CLI command":**
|
|
40
|
+
- [ ] Create src/opnsense_openapi/cli.py
|
|
41
|
+
- [ ] Create tests/test_cli.py with comprehensive tests
|
|
42
|
+
- [ ] Update pyproject.toml (if needed)
|
|
43
|
+
- [ ] Run doit check to verify all tests pass
|
|
44
|
+
- [ ] Test command manually
|
|
45
|
+
|
|
46
|
+
# DEVELOPMENT WORKFLOW (MANDATORY)
|
|
47
|
+
|
|
48
|
+
Before making ANY changes, Claude MUST:
|
|
49
|
+
1. Read AGENTS.md and locate the "## Development Workflow" section
|
|
50
|
+
2. Verify the workflow: Issue → Branch → Commit → PR → Merge
|
|
51
|
+
3. **NEVER commit directly to main**
|
|
52
|
+
4. Ensure a GitHub Issue exists for the task
|
|
53
|
+
5. Create a branch linked to the issue
|
|
54
|
+
6. Work on the branch, then create a PR
|
|
55
|
+
|
|
56
|
+
# COMMIT WORKFLOW (MANDATORY)
|
|
57
|
+
|
|
58
|
+
When asked to create a commit or PR, Claude MUST:
|
|
59
|
+
1. Read AGENTS.md and locate the "## Commit Guidelines" section
|
|
60
|
+
2. Review the commit message format rules under that section
|
|
61
|
+
3. Draft commit message following the exact format specified
|
|
62
|
+
4. Use /commit-commands:commit (not Bash directly)
|
|
63
|
+
|
|
64
|
+
NO EXCEPTIONS. If AGENTS.md has fallen out of context, READ IT FIRST.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: implement-worker
|
|
3
|
+
description: >-
|
|
4
|
+
Performs the implementation step of the /implement workflow after the
|
|
5
|
+
plan comment exists and the branch is created. Reads project rules,
|
|
6
|
+
fetches the plan, edits files, writes tests, and runs `doit check`.
|
|
7
|
+
Do NOT invoke directly — /implement drives this subagent.
|
|
8
|
+
tools: Read, Write, Edit, Glob, Grep, Bash, TodoWrite
|
|
9
|
+
permissionMode: default
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
You implement a GitHub issue's approved plan on an already-created branch. The parent `/implement` command has verified preconditions and created the branch; your job is to read the rules, fetch the plan, edit files, write tests, run `doit check`, and return a summary.
|
|
13
|
+
|
|
14
|
+
## Inputs from the parent
|
|
15
|
+
|
|
16
|
+
The parent prompt will provide:
|
|
17
|
+
|
|
18
|
+
- The **issue number** (so you can fetch the plan).
|
|
19
|
+
- The **branch name** (for context only — you will not switch branches).
|
|
20
|
+
- Any **issue-specific notes** or scope clarifications.
|
|
21
|
+
|
|
22
|
+
## Steps
|
|
23
|
+
|
|
24
|
+
### 1. Read the project rules
|
|
25
|
+
|
|
26
|
+
- Read `AGENTS.md` — understand workflow, conventions, code style, and testing guidelines.
|
|
27
|
+
- Read `.claude/CLAUDE.md` — understand TodoWrite requirements.
|
|
28
|
+
|
|
29
|
+
### 2. Fetch the implementation plan
|
|
30
|
+
|
|
31
|
+
Retrieve all comments and find the one whose body has a heading line starting with `Implementation Plan for`:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
gh api repos/{owner}/{repo}/issues/<issue-number>/comments --jq '.[] | select(.body | test("^#+ Implementation Plan for"; "m")) | .body'
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
- If multiple plan comments exist, use the most recent one.
|
|
38
|
+
- Parse the plan to extract the file list and test plan.
|
|
39
|
+
|
|
40
|
+
### 3. Implement the plan
|
|
41
|
+
|
|
42
|
+
- Follow the plan step by step.
|
|
43
|
+
- Create implementation files.
|
|
44
|
+
- Create test files — this is MANDATORY per AGENTS.md. Never skip tests when there is Python code to test.
|
|
45
|
+
- Follow existing code patterns and conventions.
|
|
46
|
+
- All new code must be type-annotated (mypy strict).
|
|
47
|
+
|
|
48
|
+
### 4. Run validation
|
|
49
|
+
|
|
50
|
+
- Run: `doit check`
|
|
51
|
+
- If checks fail, fix the issues and re-run.
|
|
52
|
+
- Do NOT give up after the first failure — investigate and fix.
|
|
53
|
+
|
|
54
|
+
### 5. Return a summary
|
|
55
|
+
|
|
56
|
+
Report to the parent:
|
|
57
|
+
|
|
58
|
+
- Files created/modified with brief descriptions.
|
|
59
|
+
- Test results (pass/fail counts).
|
|
60
|
+
- Any deviations from the plan and why.
|
|
61
|
+
|
|
62
|
+
## Constraints
|
|
63
|
+
|
|
64
|
+
- **Do NOT switch branches.** The parent `/implement` command has already created and checked out the correct branch.
|
|
65
|
+
- **Do NOT commit.** Committing is handled by the parent's `/finalize` step, not by you.
|
|
66
|
+
- **Do NOT enter plan mode.** Do not call `EnterPlanMode`. You run with `permissionMode: default` so you can edit files directly.
|
|
67
|
+
- **All new code must be type-annotated** (mypy strict mode is enforced by `doit check`).
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Close Issue
|
|
2
|
+
|
|
3
|
+
Close GitHub issue #$ARGUMENTS after verifying its PR has been merged, and handle related issues.
|
|
4
|
+
|
|
5
|
+
## Instructions
|
|
6
|
+
|
|
7
|
+
### Step 1: Verify the PR is merged
|
|
8
|
+
|
|
9
|
+
1. **Find PRs that reference this issue:**
|
|
10
|
+
```bash
|
|
11
|
+
gh pr list --state merged --search "$ARGUMENTS" --json number,title,body,mergedAt
|
|
12
|
+
```
|
|
13
|
+
Also check:
|
|
14
|
+
```bash
|
|
15
|
+
gh pr list --state merged --search "Addresses #$ARGUMENTS" --json number,title,body,mergedAt
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
2. **If no merged PR is found:**
|
|
19
|
+
- Tell the user no merged PR was found for issue #$ARGUMENTS
|
|
20
|
+
- Ask if they want to proceed anyway or check the PR status
|
|
21
|
+
- Do NOT close the issue without a merged PR unless the user explicitly confirms
|
|
22
|
+
|
|
23
|
+
### Step 2: Update issue task checkboxes
|
|
24
|
+
|
|
25
|
+
1. **Fetch the current issue body:**
|
|
26
|
+
```bash
|
|
27
|
+
gh issue view $ARGUMENTS --json body
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
2. **Check for task checkboxes** (`- [ ]` items) in the issue body.
|
|
31
|
+
|
|
32
|
+
3. **If task checkboxes exist:**
|
|
33
|
+
- Review each task against the merged PR changes
|
|
34
|
+
- Mark completed tasks as `- [x]`
|
|
35
|
+
- Update the issue body with checked-off tasks:
|
|
36
|
+
```bash
|
|
37
|
+
gh issue edit $ARGUMENTS --body "<updated body>"
|
|
38
|
+
```
|
|
39
|
+
- Tell the user which tasks were marked complete and which remain unchecked (if any)
|
|
40
|
+
|
|
41
|
+
4. **If unchecked tasks remain**, ask the user:
|
|
42
|
+
> "Some tasks in issue #$ARGUMENTS are not yet complete: <list>. Close anyway?"
|
|
43
|
+
- Wait for user confirmation before proceeding
|
|
44
|
+
|
|
45
|
+
### Step 3: Close the primary issue
|
|
46
|
+
|
|
47
|
+
1. **Add a closing comment:**
|
|
48
|
+
```bash
|
|
49
|
+
gh issue comment $ARGUMENTS --body "Addressed in PR #<pr-number>"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
2. **Close the issue:**
|
|
53
|
+
```bash
|
|
54
|
+
gh issue close $ARGUMENTS
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
3. **Confirm** to the user that issue #$ARGUMENTS has been closed.
|
|
58
|
+
|
|
59
|
+
### Step 4: Find and handle related issues
|
|
60
|
+
|
|
61
|
+
1. **Scan all merged PRs** for this issue to find referenced issues:
|
|
62
|
+
```bash
|
|
63
|
+
gh pr view <pr-number> --json body,comments
|
|
64
|
+
```
|
|
65
|
+
Search the PR body and comments for patterns like:
|
|
66
|
+
- `Addresses #N`
|
|
67
|
+
- `Part of #N`
|
|
68
|
+
- `Related to #N`
|
|
69
|
+
- `Closes #N`
|
|
70
|
+
- `Fixes #N`
|
|
71
|
+
- `References #N`
|
|
72
|
+
- `#N` (bare issue references)
|
|
73
|
+
|
|
74
|
+
Exclude the primary issue (#$ARGUMENTS) from this list.
|
|
75
|
+
|
|
76
|
+
2. **For each related issue found:**
|
|
77
|
+
- Fetch its current state: `gh issue view <N> --json state,title`
|
|
78
|
+
- Skip issues that are already closed
|
|
79
|
+
- For each **open** related issue, ask the user:
|
|
80
|
+
> "Issue #N: <title> is still open and was referenced in PR #<pr>. Would you like to close it?"
|
|
81
|
+
- If the user says yes, close it with comment "Addressed in PR #<pr-number>"
|
|
82
|
+
- If the user says no, move to the next one
|
|
83
|
+
|
|
84
|
+
3. **Summary:** After processing all related issues, show the user a summary:
|
|
85
|
+
- Issues closed in this session
|
|
86
|
+
- Issues left open
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Finalize
|
|
2
|
+
|
|
3
|
+
Finalize the current branch: update documentation, commit changes, and create a PR.
|
|
4
|
+
|
|
5
|
+
## Instructions
|
|
6
|
+
|
|
7
|
+
This command operates on the current branch. It assumes implementation and review are complete.
|
|
8
|
+
|
|
9
|
+
### Step 1: Gather context
|
|
10
|
+
|
|
11
|
+
In the main context (lightweight reads):
|
|
12
|
+
|
|
13
|
+
1. **Detect the current branch and linked issue:**
|
|
14
|
+
```bash
|
|
15
|
+
git branch --show-current
|
|
16
|
+
```
|
|
17
|
+
Extract the issue number from the branch name (e.g., `feat/245-description` → `#245`).
|
|
18
|
+
- If on `main`, tell the user they need to be on a feature branch and stop.
|
|
19
|
+
|
|
20
|
+
2. **Get the issue details:**
|
|
21
|
+
```bash
|
|
22
|
+
gh issue view <number> --json title,labels
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
3. **Check for uncommitted changes:**
|
|
26
|
+
```bash
|
|
27
|
+
git status --short
|
|
28
|
+
```
|
|
29
|
+
- If there are unstaged or uncommitted changes (e.g., from the review/fix cycle), list them for the user
|
|
30
|
+
- These will be included in the commit — confirm with the user that all changes should be included
|
|
31
|
+
|
|
32
|
+
4. **Check what changed vs main:**
|
|
33
|
+
```bash
|
|
34
|
+
git diff main --stat
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Step 2: Spawn a finalization agent
|
|
38
|
+
|
|
39
|
+
Use the Task tool with `subagent_type: "general-purpose"` and provide it with the branch name, issue number, issue title, labels, and the list of changed files. The agent should:
|
|
40
|
+
|
|
41
|
+
1. **Read the project rules:**
|
|
42
|
+
- Read `AGENTS.md` — understand commit guidelines, PR checklist, ADR requirements
|
|
43
|
+
- Read `.github/CONTRIBUTING.md` — understand commit format
|
|
44
|
+
- Read `.github/pull_request_template.md` — understand PR structure
|
|
45
|
+
|
|
46
|
+
2. **Check documentation needs:**
|
|
47
|
+
- Review the changed files — do any user-facing behaviors change?
|
|
48
|
+
- If yes, identify which docs in `docs/` need updating and update them
|
|
49
|
+
- Check `docs/decisions/` for related ADRs that need updating
|
|
50
|
+
|
|
51
|
+
3. **Check ADR needs:**
|
|
52
|
+
- If the issue has the `needs-adr` label, create an ADR using `doit adr`
|
|
53
|
+
- If the changes relate to an existing ADR, update it with the issue link
|
|
54
|
+
- Every ADR must link to documentation in `docs/`
|
|
55
|
+
|
|
56
|
+
4. **Run final validation:**
|
|
57
|
+
- Run: `doit check`
|
|
58
|
+
- ALL checks must pass before proceeding
|
|
59
|
+
|
|
60
|
+
5. **Draft the PR description** and write it to a temp file:
|
|
61
|
+
- Read `.github/pull_request_template.md` for structure
|
|
62
|
+
- Run `mkdir -p tmp/agents/claude` to ensure the directory exists
|
|
63
|
+
- Write the PR body to `tmp/agents/claude/pr-body-issue-<n>.md`
|
|
64
|
+
- The body MUST include `Addresses #<issue-number>`
|
|
65
|
+
|
|
66
|
+
6. **Return** a summary of:
|
|
67
|
+
- Documentation changes made (if any)
|
|
68
|
+
- ADR changes made (if any)
|
|
69
|
+
- Suggested commit message following conventional format: `<type>: <subject>`
|
|
70
|
+
- Suggested PR title following conventional format: `<type>: <subject>`
|
|
71
|
+
- Path to the PR body file (`tmp/agents/claude/pr-body-issue-<n>.md`)
|
|
72
|
+
|
|
73
|
+
### Step 3: Commit and create PR
|
|
74
|
+
|
|
75
|
+
After the agent returns, in the main context:
|
|
76
|
+
|
|
77
|
+
1. **Show the user** the suggested commit message and PR description
|
|
78
|
+
2. **Ask the user** for approval to commit and create the PR
|
|
79
|
+
3. **Only after user confirms:**
|
|
80
|
+
- Stage files: `git add <specific files>` (include all changed files from implementation and review/fix cycle)
|
|
81
|
+
- Commit with the approved message
|
|
82
|
+
- Create PR: `doit pr --title="<type>: <subject>" --body-file=tmp/agents/claude/pr-body-issue-<n>.md`
|
|
83
|
+
- Delete the temp file: `rm tmp/agents/claude/pr-body-issue-<n>.md`
|
|
84
|
+
4. **Report** the PR URL to the user
|
|
85
|
+
|
|
86
|
+
**IMPORTANT:** Do NOT commit or create the PR without explicit user confirmation.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Gemini PR Review
|
|
2
|
+
|
|
3
|
+
Invoke Gemini CLI to review the current branch's pull request and post findings to the PR.
|
|
4
|
+
|
|
5
|
+
## Instructions
|
|
6
|
+
|
|
7
|
+
This command runs in the main conversation context. It invokes Gemini CLI
|
|
8
|
+
non-interactively to get a code review, then posts the findings to the PR.
|
|
9
|
+
|
|
10
|
+
### Step 1: Verify the PR exists
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
gh pr view --json number,title,headRefName
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
- If no PR exists for the current branch, tell the user and stop.
|
|
17
|
+
- Save the PR number for later use.
|
|
18
|
+
|
|
19
|
+
### Step 2: Invoke Gemini CLI
|
|
20
|
+
|
|
21
|
+
Run Gemini in non-interactive mode:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
gemini -p "/review-pr" --yolo 2>/dev/null
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
- Capture the stdout output — this is Gemini's review in markdown format.
|
|
28
|
+
- If Gemini fails or produces empty output, report the error and stop.
|
|
29
|
+
|
|
30
|
+
### Step 3: Post the review to the PR
|
|
31
|
+
|
|
32
|
+
Post Gemini's review as a PR comment:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
gh pr comment <PR_NUMBER> --body "<gemini review output>"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Step 4: Report to user
|
|
39
|
+
|
|
40
|
+
Tell the user:
|
|
41
|
+
- Gemini's review has been posted to PR #<number>
|
|
42
|
+
- Provide a brief summary of Gemini's findings (verdict, critical issues if any)
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Implement Issue
|
|
2
|
+
|
|
3
|
+
Implement the plan for GitHub issue #$ARGUMENTS.
|
|
4
|
+
|
|
5
|
+
## Instructions
|
|
6
|
+
|
|
7
|
+
The implementation is delegated to a sub-agent (Task tool) so raw tool output stays out of the main conversation context. The agent does the coding; you receive the summary for user review.
|
|
8
|
+
|
|
9
|
+
**Plan-mode trap:** parent plan-mode state propagates to the spawned sub-agent mid-execution and freezes it after its first non-readonly action (typically the first `Write`). Check your Claude Code status line before running — if it shows "plan mode", exit before invoking.
|
|
10
|
+
|
|
11
|
+
### Step 1: Validate preconditions
|
|
12
|
+
|
|
13
|
+
1. **Verify the issue exists and is open:**
|
|
14
|
+
```bash
|
|
15
|
+
gh issue view $ARGUMENTS --json number,title,state,labels
|
|
16
|
+
```
|
|
17
|
+
- If the issue does not exist or is closed, tell the user and stop.
|
|
18
|
+
|
|
19
|
+
2. **Verify a plan comment exists:**
|
|
20
|
+
Fetch all comments and search for the plan header:
|
|
21
|
+
```bash
|
|
22
|
+
gh api repos/{owner}/{repo}/issues/$ARGUMENTS/comments --jq '.[].body' | grep -E "^#+ Implementation Plan for"
|
|
23
|
+
```
|
|
24
|
+
- If no plan comment is found, tell the user:
|
|
25
|
+
> "No implementation plan found for issue #$ARGUMENTS. Run `/plan-issue $ARGUMENTS` first."
|
|
26
|
+
- Stop and wait for the user.
|
|
27
|
+
|
|
28
|
+
3. **Check current branch state:**
|
|
29
|
+
```bash
|
|
30
|
+
git branch --show-current
|
|
31
|
+
git status --short
|
|
32
|
+
```
|
|
33
|
+
- If already on a branch matching `*/$ARGUMENTS-*` (e.g., `feat/$ARGUMENTS-description`):
|
|
34
|
+
- Tell the user you're resuming work on the existing branch
|
|
35
|
+
- Skip branch creation (Step 2)
|
|
36
|
+
- If there are uncommitted changes, warn the user and ask how to proceed
|
|
37
|
+
- If on `main` or a different branch: proceed to Step 2
|
|
38
|
+
|
|
39
|
+
### Step 2: Create the branch
|
|
40
|
+
|
|
41
|
+
Only if not already on the correct branch:
|
|
42
|
+
|
|
43
|
+
1. Fetch the issue to determine the branch type:
|
|
44
|
+
```bash
|
|
45
|
+
gh issue view $ARGUMENTS --json title,labels
|
|
46
|
+
```
|
|
47
|
+
2. Determine branch type from labels:
|
|
48
|
+
- `enhancement` → `feat`
|
|
49
|
+
- `bug` → `fix`
|
|
50
|
+
- `refactor` → `refactor`
|
|
51
|
+
- `documentation` → `docs`
|
|
52
|
+
- `chore` → `chore`
|
|
53
|
+
- Default → `issue`
|
|
54
|
+
3. Create and switch to branch:
|
|
55
|
+
```bash
|
|
56
|
+
git checkout main && git pull
|
|
57
|
+
git checkout -b <type>/$ARGUMENTS-<short-description>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Step 3: Spawn the implementation subagent
|
|
61
|
+
|
|
62
|
+
Use the Task tool with `subagent_type: "implement-worker"`. In the prompt, pass:
|
|
63
|
+
|
|
64
|
+
- The issue number (so the subagent can fetch the plan).
|
|
65
|
+
- The branch name (for context; the subagent will not switch branches).
|
|
66
|
+
- Any issue-specific notes or scope clarifications.
|
|
67
|
+
|
|
68
|
+
The subagent carries its own system prompt covering project rules, plan fetch, implementation, and validation — this command does not repeat them. The subagent has `permissionMode: default`, which (per Claude Code's sub-agent precedence rules) should override parent plan mode for operations inside the subagent's context.
|
|
69
|
+
|
|
70
|
+
### Step 4: Present changes to user
|
|
71
|
+
|
|
72
|
+
After the agent returns, show the user:
|
|
73
|
+
- Summary of what was implemented
|
|
74
|
+
- Files changed
|
|
75
|
+
- Test results
|
|
76
|
+
- Any issues or deviations from the plan
|
|
77
|
+
|
|
78
|
+
Tell the user:
|
|
79
|
+
- Review the changes and test as needed
|
|
80
|
+
- Discuss any fixes directly in conversation (no command needed)
|
|
81
|
+
- When satisfied, use `/finalize` to commit and create a PR
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Dual-Agent Plan
|
|
2
|
+
|
|
3
|
+
Both Claude and Gemini independently create implementation plans for GitHub issue
|
|
4
|
+
#$ARGUMENTS in separate contexts, then the user discusses the synthesized plan
|
|
5
|
+
with Claude in the current conversation.
|
|
6
|
+
|
|
7
|
+
## Instructions
|
|
8
|
+
|
|
9
|
+
### Step 1: Validate the issue
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
gh issue view $ARGUMENTS --json number,title,state,labels
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
- If the issue does not exist, tell the user and stop.
|
|
16
|
+
- If the issue is closed, tell the user and ask if they want to reopen it or stop.
|
|
17
|
+
|
|
18
|
+
### Step 2: Check for existing plans
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
gh issue view $ARGUMENTS --json comments --jq '.comments[].body' | grep -lE "^#+ Implementation Plan for"
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
- If plan comments already exist, warn the user:
|
|
25
|
+
> "Issue #$ARGUMENTS already has implementation plan comments. Continuing will post new ones. Proceed?"
|
|
26
|
+
- Wait for user confirmation before continuing.
|
|
27
|
+
|
|
28
|
+
### Step 3: Generate both plans in parallel (separate contexts)
|
|
29
|
+
|
|
30
|
+
Both plans MUST be generated in isolated contexts so neither influences the other.
|
|
31
|
+
|
|
32
|
+
**Claude's plan** — use the Task tool to spawn a subagent:
|
|
33
|
+
|
|
34
|
+
Prompt the subagent with:
|
|
35
|
+
> Read AGENTS.md and .claude/CLAUDE.md for project standards.
|
|
36
|
+
> Fetch issue #$ARGUMENTS via `gh issue view $ARGUMENTS --json title,body,labels,assignees`.
|
|
37
|
+
> Explore the codebase to understand relevant files, patterns, and tests.
|
|
38
|
+
> Create an implementation plan in this exact format:
|
|
39
|
+
>
|
|
40
|
+
> ## Implementation Plan for #<number>: <title>
|
|
41
|
+
> ### Overview
|
|
42
|
+
> ### Files to Create/Modify
|
|
43
|
+
> ### Test Plan
|
|
44
|
+
> ### Documentation
|
|
45
|
+
> ### Validation
|
|
46
|
+
> ### Risks and Considerations
|
|
47
|
+
>
|
|
48
|
+
> End with: `---` followed by `*Plan by: Claude* | *Date: <today's date>*`
|
|
49
|
+
>
|
|
50
|
+
> Output ONLY the plan markdown.
|
|
51
|
+
|
|
52
|
+
Save the subagent's output as Claude's plan.
|
|
53
|
+
|
|
54
|
+
**Gemini's plan** — invoke Gemini CLI non-interactively:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
gemini -p "/plan-issue $ARGUMENTS" --yolo 2>/dev/null
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Capture the stdout output as Gemini's plan.
|
|
61
|
+
|
|
62
|
+
Run both in parallel if possible. If either fails or produces empty output,
|
|
63
|
+
report the error and ask the user if they want to continue with the other
|
|
64
|
+
agent's plan only or retry.
|
|
65
|
+
|
|
66
|
+
### Step 4: Post both plans to the issue
|
|
67
|
+
|
|
68
|
+
Post each plan as a separate comment on the issue:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
gh issue comment $ARGUMENTS --body "<claude plan>"
|
|
72
|
+
gh issue comment $ARGUMENTS --body "<gemini plan>"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Step 5: Synthesize the final plan
|
|
76
|
+
|
|
77
|
+
Read both plans and create a synthesized final plan that:
|
|
78
|
+
- Combines the best elements from both plans
|
|
79
|
+
- Resolves any conflicts or contradictions between them
|
|
80
|
+
- Notes where the plans agreed (higher confidence)
|
|
81
|
+
- Notes where they diverged (needs discussion)
|
|
82
|
+
- Preserves the standard plan format (Overview, Files, Test Plan, Documentation, Validation)
|
|
83
|
+
|
|
84
|
+
Add the signature:
|
|
85
|
+
```
|
|
86
|
+
---
|
|
87
|
+
*Synthesized Plan by: Claude (from Claude + Gemini input)* | *Date: <today's date>*
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Step 6: Review with user
|
|
91
|
+
|
|
92
|
+
Present the synthesized plan to the user for discussion:
|
|
93
|
+
- Highlight areas where the two agents disagreed
|
|
94
|
+
- Ask for feedback and iterate as needed
|
|
95
|
+
- Do NOT post the synthesized plan until the user approves it
|
|
96
|
+
|
|
97
|
+
### Step 7: Post the approved synthesized plan
|
|
98
|
+
|
|
99
|
+
Only after the user approves:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
gh issue comment $ARGUMENTS --body "<synthesized plan>"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Tell the user:
|
|
106
|
+
- All three plans (Claude, Gemini, Synthesized) have been posted to issue #$ARGUMENTS
|
|
107
|
+
- When ready, use `/implement $ARGUMENTS` to start implementation
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Plan Issue
|
|
2
|
+
|
|
3
|
+
Plan the implementation for GitHub issue #$ARGUMENTS.
|
|
4
|
+
|
|
5
|
+
## Instructions
|
|
6
|
+
|
|
7
|
+
This command runs in the main conversation context (NOT in a subagent) so the user can ask questions, discuss tradeoffs, and refine the plan interactively.
|
|
8
|
+
|
|
9
|
+
### Step 1: Go into Plan Mode
|
|
10
|
+
|
|
11
|
+
### Step 2: Validate the issue
|
|
12
|
+
|
|
13
|
+
1. **Verify the issue exists and is open:**
|
|
14
|
+
```bash
|
|
15
|
+
gh issue view $ARGUMENTS --json number,title,state,labels
|
|
16
|
+
```
|
|
17
|
+
- If the issue does not exist, tell the user and stop.
|
|
18
|
+
- If the issue is closed, tell the user and ask if they want to reopen it or stop.
|
|
19
|
+
|
|
20
|
+
2. **Check for an existing plan comment:**
|
|
21
|
+
```bash
|
|
22
|
+
gh issue view $ARGUMENTS --json comments --jq '.comments[].body' | grep -lE "^#+ Implementation Plan for"
|
|
23
|
+
```
|
|
24
|
+
- If a plan comment already exists, warn the user:
|
|
25
|
+
> "Issue #$ARGUMENTS already has an implementation plan comment. Continuing will post a new one. Proceed?"
|
|
26
|
+
- Wait for user confirmation before continuing.
|
|
27
|
+
|
|
28
|
+
### Step 3: Read the project rules
|
|
29
|
+
|
|
30
|
+
- Read `AGENTS.md` — understand workflow, conventions, and commit guidelines
|
|
31
|
+
- Read `.claude/CLAUDE.md` — understand TodoWrite requirements
|
|
32
|
+
|
|
33
|
+
### Step 4: Fetch the issue details
|
|
34
|
+
|
|
35
|
+
- Run: `gh issue view $ARGUMENTS --json title,body,labels,assignees`
|
|
36
|
+
- Parse the issue body to understand what needs to be done
|
|
37
|
+
- Check if the issue has the `needs-adr` label
|
|
38
|
+
|
|
39
|
+
### Step 5: Explore the codebase
|
|
40
|
+
|
|
41
|
+
- Identify which files, modules, and tests are relevant
|
|
42
|
+
- Understand existing patterns and conventions in the affected areas
|
|
43
|
+
- Check for related ADRs in `docs/decisions/`
|
|
44
|
+
- If anything is ambiguous or there are multiple valid approaches, **ask the user** before deciding
|
|
45
|
+
|
|
46
|
+
### Step 6: Draft the plan and iterate with the user (inside plan mode)
|
|
47
|
+
|
|
48
|
+
**Stay in plan mode for this entire step.** Draft the plan, present it, and iterate until the user approves — all before leaving plan mode.
|
|
49
|
+
|
|
50
|
+
1. Present the plan to the user. The plan MUST include these sections:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
## Implementation Plan for #<number>: <title>
|
|
54
|
+
|
|
55
|
+
### Overview
|
|
56
|
+
Brief description of what will be done.
|
|
57
|
+
|
|
58
|
+
### Files to Create/Modify
|
|
59
|
+
- [ ] `path/to/file.py` — description of changes
|
|
60
|
+
- [ ] `tests/test_file.py` — description of test coverage
|
|
61
|
+
|
|
62
|
+
### Test Plan
|
|
63
|
+
- [ ] Test case 1: description
|
|
64
|
+
- [ ] Test case 2: description
|
|
65
|
+
|
|
66
|
+
### Documentation
|
|
67
|
+
- [ ] Any docs that need updating
|
|
68
|
+
- [ ] ADR needed: yes/no (if yes, brief description)
|
|
69
|
+
|
|
70
|
+
### Validation
|
|
71
|
+
- [ ] `doit check` passes
|
|
72
|
+
- [ ] Manual verification steps
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
2. Use `AskUserQuestion` to ask for feedback on the plan.
|
|
76
|
+
3. Discuss alternatives, answer questions, and adjust the plan as the user requests.
|
|
77
|
+
4. Keep iterating inside plan mode until the user explicitly says the plan is approved.
|
|
78
|
+
5. Do NOT leave plan mode until the user confirms approval.
|
|
79
|
+
|
|
80
|
+
### Step 7: Leave plan mode
|
|
81
|
+
|
|
82
|
+
Once the user has approved the plan, leave plan mode. The `ExitPlanMode` approval prompt means: **"Post the approved plan to the issue."** The plan has already been reviewed and approved by the user during Step 6.
|
|
83
|
+
|
|
84
|
+
### Step 8: Post the approved plan to the issue
|
|
85
|
+
|
|
86
|
+
Post the approved plan as a comment on the issue:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
gh issue comment $ARGUMENTS --body "<approved plan>"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Tell the user:
|
|
93
|
+
- The plan has been posted as a comment on issue #$ARGUMENTS
|
|
94
|
+
- When ready, use `/implement $ARGUMENTS` to start implementation
|