project-init 0.5.2__tar.gz → 0.6.1__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.
- {project_init-0.5.2/templates/lifecycle/dot_claude → project_init-0.6.1/.claude}/hooks/dag_workflow.py +95 -11
- {project_init-0.5.2 → project_init-0.6.1}/.claude/scripts/monitor_pr.sh +57 -16
- {project_init-0.5.2 → project_init-0.6.1}/.claude/scripts/push_wiki.sh +7 -2
- {project_init-0.5.2 → project_init-0.6.1}/.claude/settings.json +1 -1
- project_init-0.6.1/.githooks/pre-push +34 -0
- {project_init-0.5.2 → project_init-0.6.1}/.github/workflows/ci.yml +41 -17
- {project_init-0.5.2 → project_init-0.6.1}/.github/workflows/docs.yml +4 -4
- {project_init-0.5.2 → project_init-0.6.1}/.github/workflows/release.yml +17 -7
- {project_init-0.5.2/templates/lifecycle/dot_github → project_init-0.6.1/.github}/workflows/review-status.yml +5 -1
- project_init-0.6.1/.github/workflows/tag-release.yml +68 -0
- {project_init-0.5.2 → project_init-0.6.1}/.github/workflows/third-party-updates.yml +2 -2
- {project_init-0.5.2 → project_init-0.6.1}/CITATION.cff +1 -1
- {project_init-0.5.2 → project_init-0.6.1}/CLAUDE.md +13 -3
- {project_init-0.5.2 → project_init-0.6.1}/CONTRIBUTING.md +5 -1
- {project_init-0.5.2 → project_init-0.6.1}/PKG-INFO +4 -8
- {project_init-0.5.2 → project_init-0.6.1}/README.md +3 -3
- project_init-0.6.1/docs/reviews/2026-07-project-review.md +249 -0
- {project_init-0.5.2 → project_init-0.6.1}/install.sh +33 -8
- {project_init-0.5.2 → project_init-0.6.1}/justfile +4 -2
- {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-lifecycle/.claude-plugin/plugin.json +1 -1
- {project_init-0.5.2/plugins/project-init-workflow → project_init-0.6.1/plugins/project-init-lifecycle}/hooks/_py.sh +2 -2
- {project_init-0.5.2/.claude → project_init-0.6.1/plugins/project-init-lifecycle}/hooks/dag_workflow.py +95 -11
- {project_init-0.5.2/templates/lifecycle_fallback/dot_claude → project_init-0.6.1/plugins/project-init-lifecycle}/hooks/github_command_guard.sh +1 -1
- {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-lifecycle/hooks/hooks.json +1 -1
- {project_init-0.5.2/templates/lifecycle_fallback/dot_claude → project_init-0.6.1/plugins/project-init-lifecycle}/hooks/workflow_state_reminder.sh +24 -4
- {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-workflow/.claude-plugin/plugin.json +1 -1
- {project_init-0.5.2/plugins/project-init-lifecycle → project_init-0.6.1/plugins/project-init-workflow}/hooks/_py.sh +2 -2
- {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-workflow/hooks/hooks.json +6 -0
- project_init-0.6.1/plugins/project-init-workflow/hooks/package_guard.py +370 -0
- project_init-0.6.1/plugins/project-init-workflow/hooks/post_edit_lint.sh +111 -0
- project_init-0.6.1/plugins/project-init-workflow/hooks/pre_commit_gate.sh +156 -0
- {project_init-0.5.2/templates/base/dot_claude → project_init-0.6.1/plugins/project-init-workflow}/hooks/prod_guard.py +10 -1
- {project_init-0.5.2/templates/fallback/dot_claude → project_init-0.6.1/plugins/project-init-workflow}/hooks/session_setup.sh +14 -8
- project_init-0.6.1/plugins/project-init-workflow/skills/report_upstream_issue/SKILL.md +114 -0
- {project_init-0.5.2 → project_init-0.6.1}/pyproject.toml +9 -4
- {project_init-0.5.2 → project_init-0.6.1}/renovate.json +2 -2
- {project_init-0.5.2 → project_init-0.6.1}/src/project_init/__init__.py +2 -2
- {project_init-0.5.2 → project_init-0.6.1}/src/project_init/__main__.py +261 -66
- {project_init-0.5.2 → project_init-0.6.1}/src/project_init/capabilities.py +19 -7
- {project_init-0.5.2 → project_init-0.6.1}/src/project_init/concerns.py +67 -17
- {project_init-0.5.2 → project_init-0.6.1}/src/project_init/governance.py +24 -4
- {project_init-0.5.2 → project_init-0.6.1}/src/project_init/mcps.py +12 -0
- {project_init-0.5.2 → project_init-0.6.1}/src/project_init/migration_notes.py +50 -7
- {project_init-0.5.2 → project_init-0.6.1}/src/project_init/scaffold.py +269 -57
- {project_init-0.5.2 → project_init-0.6.1}/src/project_init/surfaces.py +0 -9
- {project_init-0.5.2 → project_init-0.6.1}/src/project_init/upgrade.py +175 -21
- project_init-0.6.1/templates/amp/dot_agents/skills/report_upstream_issue/SKILL.md +114 -0
- project_init-0.6.1/templates/antigravity/dot_agents/skills/report_upstream_issue/SKILL.md +114 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/auto/dot_claude/scripts/lint_memory.sh +31 -15
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/AGENTS.md.tmpl +4 -3
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/Dockerfile.tmpl +34 -3
- project_init-0.6.1/templates/base/bunfig.toml.tmpl +14 -0
- project_init-0.6.1/templates/base/clippy.toml.tmpl +10 -0
- project_init-0.6.1/templates/base/deny.toml.tmpl +40 -0
- project_init-0.6.1/templates/base/dot_cargo/config.toml.tmpl +7 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/config.yaml.tmpl +1 -1
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/hooks/_py.sh +2 -2
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/hooks/agent_guard_adapter.py.tmpl +21 -9
- project_init-0.6.1/templates/base/dot_claude/hooks/package_guard.py +370 -0
- {project_init-0.5.2/plugins/project-init-workflow → project_init-0.6.1/templates/base/dot_claude}/hooks/prod_guard.py +10 -1
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/project-init.md.tmpl +2 -1
- project_init-0.6.1/templates/base/dot_claude/rules/go.md +37 -0
- project_init-0.6.1/templates/base/dot_claude/rules/node.md +40 -0
- project_init-0.6.1/templates/base/dot_claude/rules/python.md +57 -0
- project_init-0.6.1/templates/base/dot_claude/rules/rust.md +64 -0
- project_init-0.6.1/templates/base/dot_claude/rules/typescript.md +45 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/scripts/gh_host.sh +14 -5
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/scripts/setup_env_protection.sh.tmpl +32 -9
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/scripts/whats_deployed.sh.tmpl +4 -3
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/settings.json.tmpl +7 -1
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/skills/README.md.tmpl +2 -1
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_devcontainer/devcontainer.json.tmpl +4 -1
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_env.example.tmpl +1 -1
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_github/hooks/commit-msg +1 -1
- project_init-0.6.1/templates/base/dot_github/hooks/pre-commit +75 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_github/hooks/pre-push.tmpl +34 -0
- project_init-0.6.1/templates/base/dot_github/workflows/ci.yml.tmpl +722 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_github/workflows/deploy.yml.tmpl +12 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_github/workflows/registry-publish.yml.tmpl +18 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_github/workflows/release.yml.tmpl +72 -5
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_gitignore.tmpl +7 -2
- project_init-0.6.1/templates/base/dot_gitleaks.toml +17 -0
- project_init-0.6.1/templates/base/dot_golangci.yml.tmpl +43 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_vscode/extensions.json.tmpl +2 -1
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_vscode/settings.json.tmpl +4 -1
- project_init-0.6.1/templates/base/eslint.config.mjs.tmpl +87 -0
- project_init-0.6.1/templates/base/justfile.tmpl +315 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/mise.toml.tmpl +9 -1
- project_init-0.6.1/templates/base/mypy.ini.tmpl +19 -0
- project_init-0.6.1/templates/base/ruff.toml.tmpl +50 -0
- project_init-0.6.1/templates/base/rustfmt.toml.tmpl +4 -0
- project_init-0.6.1/templates/base/tsconfig.base.json.tmpl +19 -0
- project_init-0.6.1/templates/base/tsconfig.json.tmpl +6 -0
- project_init-0.6.1/templates/codex/dot_agents/skills/report_upstream_issue/SKILL.md +114 -0
- project_init-0.6.1/templates/fallback/dot_claude/hooks/post_edit_lint.sh +111 -0
- project_init-0.6.1/templates/fallback/dot_claude/hooks/pre_commit_gate.sh +156 -0
- {project_init-0.5.2/plugins/project-init-workflow → project_init-0.6.1/templates/fallback/dot_claude}/hooks/session_setup.sh +14 -8
- {project_init-0.5.2 → project_init-0.6.1}/templates/fallback/dot_claude/skills/INDEX.md.tmpl +1 -0
- project_init-0.6.1/templates/fallback/dot_claude/skills/report_upstream_issue/SKILL.md +114 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/governance/dot_claude/scripts/governance_gate.sh +6 -1
- project_init-0.6.1/templates/junie/dot_junie/skills/report_upstream_issue/SKILL.md +114 -0
- {project_init-0.5.2/plugins/project-init-lifecycle → project_init-0.6.1/templates/lifecycle/dot_claude}/hooks/dag_workflow.py +95 -11
- {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_claude/scripts/create_issue.sh +145 -107
- {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_claude/scripts/monitor_pr.sh +96 -25
- {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_claude/scripts/setup_github.sh +78 -52
- {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_claude/scripts/start_issue.sh +42 -25
- {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_github/copilot-instructions.md.tmpl +1 -1
- {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_github/workflows/board-automation.yml +44 -30
- project_init-0.6.1/templates/lifecycle/dot_github/workflows/issue-validation.yml +121 -0
- {project_init-0.5.2/plugins/project-init-lifecycle → project_init-0.6.1/templates/lifecycle_fallback/dot_claude}/hooks/github_command_guard.sh +1 -1
- {project_init-0.5.2/plugins/project-init-lifecycle → project_init-0.6.1/templates/lifecycle_fallback/dot_claude}/hooks/workflow_state_reminder.sh +24 -4
- {project_init-0.5.2 → project_init-0.6.1}/templates/multi_model/dot_claude/scripts/models.sh +44 -15
- {project_init-0.5.2 → project_init-0.6.1}/templates/multi_model/dot_claude/scripts/setup_models.sh +34 -17
- project_init-0.6.1/templates/observability/dot_claude/scripts/observability.sh +60 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/rag/dot_claude/scripts/setup_rag.sh +2 -2
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_capabilities.py +9 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_cross_stack_examples.py +3 -3
- project_init-0.6.1/tests/contracts/test_dockerfile_lint.py +96 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_emission_hardening.py +7 -8
- project_init-0.6.1/tests/contracts/test_fuzzing.py +81 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_governance.py +10 -4
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_governance_overlay.py +20 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_governance_product.py +73 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_hook_portability.py +15 -0
- project_init-0.6.1/tests/contracts/test_image_scan.py +79 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_justfile.py +105 -5
- project_init-0.6.1/tests/contracts/test_justfile_combinations.py +59 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_library_release.py +6 -1
- project_init-0.6.1/tests/contracts/test_license_scan.py +105 -0
- project_init-0.6.1/tests/contracts/test_lifecycle_byte_identity.py +217 -0
- project_init-0.6.1/tests/contracts/test_lifecycle_script_hardening.py +151 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_memory_byte_identity.py +85 -1
- project_init-0.6.1/tests/contracts/test_package_guard.py +247 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_parity_bundle.py +8 -4
- project_init-0.6.1/tests/contracts/test_post_edit_lint_typecheck.py +64 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_prod_guard.py +6 -0
- project_init-0.6.1/tests/contracts/test_provenance.py +88 -0
- project_init-0.6.1/tests/contracts/test_quality_toolchain.py +617 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_release_engineering.py +41 -5
- project_init-0.6.1/tests/contracts/test_sbom.py +100 -0
- project_init-0.6.1/tests/contracts/test_scorecard.py +72 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_templates.py +38 -0
- {project_init-0.5.2/tests/fixtures/memory_baseline → project_init-0.6.1/tests/fixtures/lifecycle_baseline}/obsidian-graphify__no_plugin.json +6 -6
- {project_init-0.5.2/tests/fixtures/memory_baseline → project_init-0.6.1/tests/fixtures/lifecycle_baseline}/obsidian-graphify__plugin.json +4 -4
- {project_init-0.5.2 → project_init-0.6.1}/tests/fixtures/lifecycle_baseline/obsidian-only__no_plugin.json +6 -6
- {project_init-0.5.2 → project_init-0.6.1}/tests/fixtures/lifecycle_baseline/obsidian-only__plugin.json +4 -4
- {project_init-0.5.2/tests/fixtures/lifecycle_baseline → project_init-0.6.1/tests/fixtures/memory_baseline}/obsidian-graphify__no_plugin.json +6 -6
- {project_init-0.5.2/tests/fixtures/lifecycle_baseline → project_init-0.6.1/tests/fixtures/memory_baseline}/obsidian-graphify__plugin.json +4 -4
- {project_init-0.5.2 → project_init-0.6.1}/tests/fixtures/memory_baseline/obsidian-only__no_plugin.json +6 -6
- {project_init-0.5.2 → project_init-0.6.1}/tests/fixtures/memory_baseline/obsidian-only__plugin.json +4 -4
- {project_init-0.5.2 → project_init-0.6.1}/tests/helpers.py +1 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_cli.py +39 -6
- project_init-0.6.1/tests/integration/test_commit_hook_gates.py +190 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_concern_add_remove.py +22 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_dag_workflow.py +64 -0
- project_init-0.6.1/tests/integration/test_gitignore_scaffold.py +77 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_issue_metadata_workflow.py +38 -2
- {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_memory_backends.py +7 -1
- {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_memory_starters.py +30 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_overwrite_protection.py +124 -0
- project_init-0.6.1/tests/integration/test_quality_gate_lint.py +94 -0
- project_init-0.6.1/tests/integration/test_report_upstream_issue_skill.py +91 -0
- project_init-0.6.1/tests/integration/test_shell_lint_gate.py +119 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_upgrade.py +41 -5
- project_init-0.6.1/tests/integration/test_upgrade_edges.py +87 -0
- project_init-0.6.1/tests/unit/test_audit_fixes.py +194 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/unit/test_presets_inheritance.py +11 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/unit/test_third_party_updates.py +16 -0
- {project_init-0.5.2 → project_init-0.6.1}/tools/check_third_party_updates.py +20 -18
- {project_init-0.5.2 → project_init-0.6.1}/tools/sync_plugin.py +69 -3
- {project_init-0.5.2 → project_init-0.6.1}/uv.lock +14 -8
- project_init-0.5.2/plugins/project-init-workflow/hooks/post_edit_lint.sh +0 -68
- project_init-0.5.2/plugins/project-init-workflow/hooks/pre_commit_gate.sh +0 -96
- project_init-0.5.2/templates/base/dot_claude/rules/go.md +0 -14
- project_init-0.5.2/templates/base/dot_claude/rules/node.md +0 -17
- project_init-0.5.2/templates/base/dot_claude/rules/python.md +0 -25
- project_init-0.5.2/templates/base/dot_github/hooks/pre-commit +0 -16
- project_init-0.5.2/templates/base/dot_github/workflows/ci.yml.tmpl +0 -328
- project_init-0.5.2/templates/base/dot_golangci.yml.tmpl +0 -20
- project_init-0.5.2/templates/base/eslint.config.mjs.tmpl +0 -29
- project_init-0.5.2/templates/base/justfile.tmpl +0 -113
- project_init-0.5.2/templates/base/ruff.toml.tmpl +0 -31
- project_init-0.5.2/templates/fallback/dot_claude/hooks/post_edit_lint.sh +0 -68
- project_init-0.5.2/templates/fallback/dot_claude/hooks/pre_commit_gate.sh +0 -96
- project_init-0.5.2/templates/lifecycle/dot_github/workflows/issue-validation.yml +0 -72
- project_init-0.5.2/templates/observability/dot_claude/scripts/observability.sh +0 -52
- project_init-0.5.2/tests/contracts/test_lifecycle_byte_identity.py +0 -116
- project_init-0.5.2/tests/contracts/test_quality_toolchain.py +0 -204
- project_init-0.5.2/tests/integration/test_quality_gate_lint.py +0 -52
- {project_init-0.5.2 → project_init-0.6.1}/.claude/hooks/github_command_guard.sh +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.claude/hooks/workflow_state_reminder.sh +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.claude/scripts/create_nojira_pr.sh +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.claude/scripts/finish_pr.sh +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.claude/scripts/promote_review.sh +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.claude/scripts/push_branch.sh +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.claude/skills/INDEX.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.claude/skills/README.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.claude/skills/add_command/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.claude/skills/add_hook/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.claude/skills/github_workflow/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.claude/skills/live_test/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.claude/skills/session_summary/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.claude/skills/start_task/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.claude/skills/wiki/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.claude/skills/wiki/templates/architecture.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.claude/skills/wiki/templates/implementation-guide.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.claude/skills/wiki/templates/preset-guide.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.claude/skills/wiki/templates/scaffolder-logic.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.claude-plugin/marketplace.json +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.gitattributes +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.github/ISSUE_TEMPLATE/bug.yml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.github/ISSUE_TEMPLATE/chore.yml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.github/ISSUE_TEMPLATE/docs.yml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.github/ISSUE_TEMPLATE/feature.yml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.github/ISSUE_TEMPLATE/test.yml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.github/copilot-instructions.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.github/workflows/board-automation.yml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.github/workflows/validate-pr.yml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.gitignore +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/.gitleaks.toml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/AGENTS.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/LICENSE +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/cliff.toml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/README.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-001-scaffolder-design.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-002-dotglob-template-convention.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-003-github-native-workflow.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-004-obsidian-docs-integration.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-005-github-pr-board-workflow.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-006-conventional-commit-titles.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-007-security-enforcement-layers.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-008-distribution-channel.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-009-graphify-memory-preset.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-010-plugin-marketplace-dual-ship.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-011-pypi-trusted-publishing.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-012-prod-safety-guard.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-013-distribution-governance-model.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-014-environment-promotion-chains.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-015-env-deploy-model.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-016-model-agnostic-switching.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-017-per-surface-config-generator.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-018-ai-governance-overlay.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-019-local-observability-overlay.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-020-memory-backend-decomposition.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-021-quality-vs-lifecycle-tier-boundary.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-022-toolchain-gate-map.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-023-wizard-explanation-standard.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-024-memory-tier-model.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-025-agentic-os-root-layer.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-026-tier3-rag-engine-cocoindex.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/development/agentic-os-root-layer.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/development/build-reproducibility.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/development/contributing.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/development/enforcement-classification.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/development/enterprise-github-support-matrix.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/development/measurement-methodology.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/development/memory-descriptor.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/development/mobile-remote-access.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/development/non-cli-surface-matrix.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/development/template-system.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/development/testing.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/guides/org-fork-lifecycle.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/guides/using-project-init.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/positioning.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/docs/research/model-agnostic-switching.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/mkdocs.yml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-lifecycle/hooks/_usage_log.sh +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-lifecycle/skills/audit/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-lifecycle/skills/create_issue/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-lifecycle/skills/github_workflow/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-lifecycle/skills/request_review/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-lifecycle/skills/start_task/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-workflow/hooks/_usage_log.sh +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-workflow/skills/add_adr/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-workflow/skills/add_command/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-workflow/skills/add_hook/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-workflow/skills/review/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-workflow/skills/save_memory/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-workflow/skills/session_summary/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-workflow/skills/status/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/amp/dot_agents/skills/add_adr/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/amp/dot_agents/skills/add_command/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/amp/dot_agents/skills/add_hook/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/amp/dot_agents/skills/audit/SKILL.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/amp/dot_agents/skills/create_issue/SKILL.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/amp/dot_agents/skills/github_workflow/SKILL.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/amp/dot_agents/skills/plan/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/amp/dot_agents/skills/request_review/SKILL.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/amp/dot_agents/skills/review/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/amp/dot_agents/skills/save_memory/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/amp/dot_agents/skills/session_summary/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/amp/dot_agents/skills/start_task/SKILL.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/amp/dot_agents/skills/status/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/antigravity/dot_agents/skills/add_adr/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/antigravity/dot_agents/skills/add_command/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/antigravity/dot_agents/skills/add_hook/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/antigravity/dot_agents/skills/audit/SKILL.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/antigravity/dot_agents/skills/create_issue/SKILL.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/antigravity/dot_agents/skills/github_workflow/SKILL.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/antigravity/dot_agents/skills/plan/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/antigravity/dot_agents/skills/request_review/SKILL.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/antigravity/dot_agents/skills/review/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/antigravity/dot_agents/skills/save_memory/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/antigravity/dot_agents/skills/session_summary/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/antigravity/dot_agents/skills/start_task/SKILL.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/antigravity/dot_agents/skills/status/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/auto/dot_claude/memory/MEMORY.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/auto/dot_claude/memory/README.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/auto/dot_claude/memory/SCHEMA.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/auto/dot_claude/memory/feedback_conventions.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/auto/dot_claude/memory/project_context.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/auto/dot_claude/memory/user_role.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/CLAUDE.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/CONTRIBUTING.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/LICENSE.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/SECURITY.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/compose.yaml.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/deploy/environments.yaml.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/docs/explanation/index.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/docs/how-to/index.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/docs/index.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/docs/reference/index.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/docs/tutorials/index.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/agents/README.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/agents/code-reviewer.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/agents/explore.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/docs/README.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/docs/adr/adr-002-mcp-choices.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/docs/adr/adr-template.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/docs/development/conventions.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/docs/development/testing.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/docs/guides/cloud-integration.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/docs/guides/developer-onboarding.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/docs/guides/environments.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/docs/guides/secrets.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/hooks/README.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/rules/hooks.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/scripts/README.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/scripts/gen_code_map.py.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/scripts/install_hooks.sh +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/skills/plan/SKILL.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_devcontainer/post-create.sh.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_dockerignore.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_gitattributes +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_github/CODEOWNERS.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_github/workflows/infra.yml.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/infra/README.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/infra/backend.tf.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/infra/dot_gitignore.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/infra/dot_pre-commit-config.yaml.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/infra/main.tf.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/infra/outputs.tf.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/infra/variables.tf.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/infra/versions.tf.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/mkdocs.yml.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/renovate.json.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/base/typedoc.json.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_agents/skills/add_adr/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_agents/skills/add_command/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_agents/skills/add_hook/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_agents/skills/audit/SKILL.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_agents/skills/create_issue/SKILL.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_agents/skills/github_workflow/SKILL.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_agents/skills/plan/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_agents/skills/request_review/SKILL.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_agents/skills/review/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_agents/skills/save_memory/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_agents/skills/session_summary/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_agents/skills/start_task/SKILL.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_agents/skills/status/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_codex/hooks.json.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/fallback/dot_claude/hooks/_usage_log.sh +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/fallback/dot_claude/skills/add_adr/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/fallback/dot_claude/skills/add_command/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/fallback/dot_claude/skills/add_hook/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/fallback/dot_claude/skills/review/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/fallback/dot_claude/skills/save_memory/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/fallback/dot_claude/skills/session_summary/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/fallback/dot_claude/skills/status/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/governance/dot_claude/governance/AI_USAGE_POLICY.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/governance/dot_claude/governance/NIST_RMF_CROSSWALK.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/governance/dot_claude/governance/README.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/governance/dot_claude/governance/ai-code-provenance.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/governance/dot_claude/governance/ai-declarations.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/governance/dot_claude/governance/approved-tools.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/governance/dot_claude/governance/config.example.json +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/governance/dot_claude/governance/data-handling.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/governance/dot_claude/governance/examples/SYSTEM_CARD.example.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/governance/dot_claude/governance/examples/SYSTEM_CARD.template.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/governance/dot_claude/scripts/governance_gate.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/graphify/dot_claude/docs/guides/using-graphify.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/graphify/dot_claude/rules/graphify.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/graphify/dot_claude/scripts/setup_graphify.sh +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/junie/dot_junie/skills/add_adr/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/junie/dot_junie/skills/add_command/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/junie/dot_junie/skills/add_hook/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/junie/dot_junie/skills/audit/SKILL.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/junie/dot_junie/skills/create_issue/SKILL.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/junie/dot_junie/skills/github_workflow/SKILL.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/junie/dot_junie/skills/plan/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/junie/dot_junie/skills/request_review/SKILL.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/junie/dot_junie/skills/review/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/junie/dot_junie/skills/save_memory/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/junie/dot_junie/skills/session_summary/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/junie/dot_junie/skills/start_task/SKILL.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/junie/dot_junie/skills/status/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_claude/docs/guides/issue-metadata.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_claude/scripts/create_nojira_pr.sh +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_claude/scripts/finish_pr.sh +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_claude/scripts/promote_review.sh +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_claude/scripts/push_branch.sh +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_claude/scripts/push_wiki.sh +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_github/ISSUE_TEMPLATE/bug.yml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_github/ISSUE_TEMPLATE/chore.yml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_github/ISSUE_TEMPLATE/config.yml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_github/ISSUE_TEMPLATE/docs.yml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_github/ISSUE_TEMPLATE/feature.yml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_github/ISSUE_TEMPLATE/test.yml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_github/pull_request_template.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_github/workflows/project-init-upgrade.yml.tmpl +0 -0
- {project_init-0.5.2/.github → project_init-0.6.1/templates/lifecycle/dot_github}/workflows/review-status.yml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_github/workflows/validate-pr.yml.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle_fallback/dot_claude/skills/audit/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle_fallback/dot_claude/skills/create_issue/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle_fallback/dot_claude/skills/github_workflow/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle_fallback/dot_claude/skills/request_review/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle_fallback/dot_claude/skills/start_task/SKILL.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/multi_model/dot_claude/docs/guides/using-multi-model.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/multi_model/dot_claude/multi-model/README.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/multi_model/dot_claude/multi-model/config.json +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/multi_model/dot_claude/multi-model/dot_env.example +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/observability/dot_claude/docs/guides/upgrading-observability.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/observability/dot_claude/docs/guides/using-observability.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/observability/dot_claude/observability/.keep +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/observability/dot_claude/observability/README.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/observability/dot_claude/observability/dot_gitignore +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/observability/dot_claude/observability/usage_report.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/docs/adr/adr-001-memory-stack.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/docs/guides/using-memory.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/README.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/decisions/README.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/decisions/adr-000-project-setup.md.tmpl +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/design/README.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/dot_obsidian/README.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/dot_obsidian/app.json +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/dot_obsidian/community-plugins.json +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/dot_obsidian/core-plugins.json +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/knowledge/README.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/log.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/sessions/README.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/templates/decision.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/templates/design-note.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/templates/knowledge-note.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/templates/session-note.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/presets/auto.toml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/presets/core.toml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/presets/governed.toml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/presets/obsidian-graphify.toml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/presets/obsidian-only.toml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/rag/dot_claude/docs/guides/using-rag.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/templates/rag/dot_claude/rules/rag.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/__init__.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/conftest.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_agent_overlays.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_agents_canonical.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_benchmark_cost_latency.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_benchmark_harness.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_benchmark_report.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_benchmark_scoring.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_deploy_overlay.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_docs_renovate.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_enforcement.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_enterprise_host.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_env_tooling.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_iac_overlay.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_integration_seam.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_integrity.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_interpreter_portability.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_lifecycle_none.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_marketplace_source.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_memory_none.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_multi_model_overlay.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_no_bytecode_leak.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_no_egress.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_observability_overlay.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_observability_report.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_observability_self_log.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_plugin_marketplace.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_portability_hardening.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_renovate.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_repo_validate_pr.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_scaffold_graphify.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_scaffold_obsidian.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_session_bootstrap.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_skill_index.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_subagent_specs.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_surface_emission.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_third_party_pin_contract.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_upgrade_pr_workflow.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_variable_contract.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_wiki_skill.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_wizard_explanations.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_code_map.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_combination_matrix.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_compose_interop.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_concern_skill_gating.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_consent.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_hooks_and_safety.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_install_script.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_json_output.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_lifecycle.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_memory_descriptor.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_observability.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_org_lifecycle.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_rag_seam.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_readme_examples.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_session_cold_start.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/smoke/test_packaging.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/unit/test_command_variables.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/unit/test_interactive_prompts.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/unit/test_mcps.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/unit/test_migration_notes.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/unit/test_presets.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/unit/test_profile.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/unit/test_render_nesting.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/unit/test_scaffold_inputs.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/unit/test_shell_portability.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/unit/test_surfaces.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tests/unit/test_version_span.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tools/benchmark/README.md +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tools/benchmark/harness.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tools/benchmark/latency.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tools/benchmark/model_prices.json +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tools/benchmark/prices.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tools/benchmark/record.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tools/benchmark/report.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tools/benchmark/scoring.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tools/benchmark/tasks/feat.toml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tools/benchmark/tasks/fix.toml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tools/benchmark/tasks/noop.toml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tools/benchmark/tasks/qa.toml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tools/benchmark/transcript.py +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tools/pinned_third_party.toml +0 -0
- {project_init-0.5.2 → project_init-0.6.1}/tools/propose_third_party_bumps.sh +0 -0
|
@@ -42,8 +42,6 @@ import sys
|
|
|
42
42
|
import time
|
|
43
43
|
from pathlib import Path
|
|
44
44
|
|
|
45
|
-
CACHE_PATH = Path(".claude/.workflow-state.json")
|
|
46
|
-
|
|
47
45
|
GRAPH: dict[str, list[str]] = {
|
|
48
46
|
"issue.created": [],
|
|
49
47
|
"branch.created": [],
|
|
@@ -64,8 +62,11 @@ else:
|
|
|
64
62
|
|
|
65
63
|
|
|
66
64
|
def _run(cmd: list[str]) -> tuple[int, str]:
|
|
65
|
+
# Per-call timeout must stay well below the hook budget (settings.json
|
|
66
|
+
# "timeout": 60): a PreToolUse hook that exceeds its budget is killed and
|
|
67
|
+
# FAILS OPEN, so one hung gh call must never eat the whole allowance.
|
|
67
68
|
try:
|
|
68
|
-
proc = subprocess.run(cmd, capture_output=True, text=True, timeout=
|
|
69
|
+
proc = subprocess.run(cmd, capture_output=True, text=True, timeout=10) # noqa: S603 — argv list built from internal literals/validated state, never a shell string
|
|
69
70
|
except (subprocess.TimeoutExpired, FileNotFoundError):
|
|
70
71
|
return 1, ""
|
|
71
72
|
return proc.returncode, proc.stdout
|
|
@@ -253,6 +254,17 @@ COMMAND_RULES: list[tuple[re.Pattern[str], str | None, str]] = [
|
|
|
253
254
|
"pr.merged",
|
|
254
255
|
"Use .claude/scripts/monitor_pr.sh <pr> --merge instead of `gh api .../merge` so CI and review gates are honored.",
|
|
255
256
|
),
|
|
257
|
+
(
|
|
258
|
+
# GraphQL merges bypass the REST-path rule above (2026-07 review): a
|
|
259
|
+
# `gh api graphql` mutation can merge or enable auto-merge without ever
|
|
260
|
+
# naming `/pulls/N/merge`. Block the mutation fields themselves.
|
|
261
|
+
re.compile(
|
|
262
|
+
r"\bgh\s+api\b[^&;]*\bgraphql\b[^&;]*"
|
|
263
|
+
r"(?:mergePullRequest|enablePullRequestAutoMerge)"
|
|
264
|
+
),
|
|
265
|
+
"pr.merged",
|
|
266
|
+
"Use .claude/scripts/monitor_pr.sh <pr> --merge instead of a `gh api graphql` merge mutation so CI and review gates are honored.",
|
|
267
|
+
),
|
|
256
268
|
(
|
|
257
269
|
re.compile(r"\bgh\s+pr\s+merge\b"),
|
|
258
270
|
"pr.merged",
|
|
@@ -291,12 +303,69 @@ _HEREDOC_RE = re.compile(
|
|
|
291
303
|
re.DOTALL,
|
|
292
304
|
)
|
|
293
305
|
|
|
306
|
+
# Git global options that sit BETWEEN `git` and the subcommand (`git -C dir
|
|
307
|
+
# push`, `git -c k=v push`). Left unnormalized they defeat every `git push`
|
|
308
|
+
# rule, including the direct-push-to-main block (2026-07 review). Options that
|
|
309
|
+
# consume a value are listed with their value; boolean options stand alone.
|
|
310
|
+
# An option value is one shell word INCLUDING quoted runs — `-c foo='a b'`
|
|
311
|
+
# must normalize away too: a bare \S+ stops at the space inside the quotes
|
|
312
|
+
# and the mangled residue defeats every git rule (mirrors the quoted-value
|
|
313
|
+
# matcher in pre_commit_gate.sh).
|
|
314
|
+
_GIT_OPT_VAL = r"(?:[^\s'\"]|'[^']*'|\"[^\"]*\")+"
|
|
315
|
+
_GIT_GLOBAL_OPT = (
|
|
316
|
+
r"(?:"
|
|
317
|
+
rf"-C[ \t]+{_GIT_OPT_VAL}" # -C <path>
|
|
318
|
+
rf"|-c[ \t]+{_GIT_OPT_VAL}" # -c <name=value>
|
|
319
|
+
rf"|--git-dir(?:={_GIT_OPT_VAL}|[ \t]+{_GIT_OPT_VAL})"
|
|
320
|
+
rf"|--work-tree(?:={_GIT_OPT_VAL}|[ \t]+{_GIT_OPT_VAL})"
|
|
321
|
+
rf"|--namespace(?:={_GIT_OPT_VAL}|[ \t]+{_GIT_OPT_VAL})"
|
|
322
|
+
rf"|--config-env(?:={_GIT_OPT_VAL}|[ \t]+{_GIT_OPT_VAL})"
|
|
323
|
+
rf"|--exec-path(?:={_GIT_OPT_VAL})?"
|
|
324
|
+
r"|--no-pager|--paginate|-p|-P|--bare"
|
|
325
|
+
r"|--no-replace-objects|--literal-pathspecs|--no-optional-locks|--icase-pathspecs"
|
|
326
|
+
r")"
|
|
327
|
+
)
|
|
328
|
+
_GIT_NORMALIZE_RE = re.compile(r"\bgit((?:[ \t]+" + _GIT_GLOBAL_OPT + r")+)[ \t]+")
|
|
329
|
+
|
|
330
|
+
# An interpreter receiving a heredoc executes its body, so a guarded command
|
|
331
|
+
# hidden in `bash <<'EOF' … EOF` must still be scanned (2026-07 review). The
|
|
332
|
+
# negative lookbehind lets `/bin/bash` match while sparing `rebash`.
|
|
333
|
+
_INTERP = r"(?:bash|sh|zsh|dash|ksh|python3?|python2|eval|source)"
|
|
334
|
+
_INTERP_INTRO_RE = re.compile(r"(?<![\w.-])" + _INTERP + r"\b")
|
|
335
|
+
_PIPE_INTERP_RE = re.compile(r"^\s*\|\s*(?:sudo[ \t]+)?(?<![\w.-])" + _INTERP + r"\b")
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
def _normalize_git_globals(cmd: str) -> str:
|
|
339
|
+
"""Rewrite ``git <global-opts> <subcommand>`` to ``git <subcommand>`` for
|
|
340
|
+
matching, so interposed ``-C``/``-c``/``--git-dir`` flags can't smuggle a
|
|
341
|
+
push past the rules (2026-07 review)."""
|
|
342
|
+
return _GIT_NORMALIZE_RE.sub("git ", cmd)
|
|
343
|
+
|
|
294
344
|
|
|
295
345
|
def _strip_heredocs(cmd: str) -> str:
|
|
296
346
|
"""Remove heredoc body text so pattern rules don't fire on body content."""
|
|
297
347
|
return _HEREDOC_RE.sub("", cmd)
|
|
298
348
|
|
|
299
349
|
|
|
350
|
+
def _executing_heredoc_bodies(cmd: str) -> str:
|
|
351
|
+
"""Concatenate heredoc bodies that WILL run — those fed to an interpreter
|
|
352
|
+
directly (``bash <<EOF``) or via a pipe (``cat <<EOF … | bash``).
|
|
353
|
+
|
|
354
|
+
``_strip_heredocs`` removes every body to spare prose (a commit message or
|
|
355
|
+
``gh pr comment --body-file - <<EOF`` mentioning "git push main"), but that
|
|
356
|
+
also hid genuinely-executing bodies. Re-surfacing only the interpreter-fed
|
|
357
|
+
ones keeps prose exempt while closing the execution bypass (2026-07 review).
|
|
358
|
+
"""
|
|
359
|
+
bodies = []
|
|
360
|
+
for m in _HEREDOC_RE.finditer(cmd):
|
|
361
|
+
line_start = cmd.rfind("\n", 0, m.start()) + 1
|
|
362
|
+
intro = cmd[line_start : m.start()]
|
|
363
|
+
after = cmd[m.end() : m.end() + 60]
|
|
364
|
+
if _INTERP_INTRO_RE.search(intro) or _PIPE_INTERP_RE.match(after):
|
|
365
|
+
bodies.append(m.group(0))
|
|
366
|
+
return "\n".join(bodies)
|
|
367
|
+
|
|
368
|
+
|
|
300
369
|
# Free-text flag values carry arbitrary prose (commit messages, issue/PR comment
|
|
301
370
|
# and release bodies, titles) that must not be scanned for command patterns — a
|
|
302
371
|
# `--body` mentioning the literal "git push main" is data, not an invocation.
|
|
@@ -358,8 +427,15 @@ def guard(payload: dict) -> dict | None:
|
|
|
358
427
|
|
|
359
428
|
# Strip heredoc bodies and free-text flag values so pattern rules don't fire
|
|
360
429
|
# on prose content (e.g. `gh issue create --body "$(cat <<'EOF'\n...git
|
|
361
|
-
# push...\nEOF\n)"`, or `gh pr comment --body "...git push main..."`)
|
|
362
|
-
|
|
430
|
+
# push...\nEOF\n)"`, or `gh pr comment --body "...git push main..."`), then
|
|
431
|
+
# normalize interposed git global options so `git -C dir push` is matched
|
|
432
|
+
# like `git push` (2026-07 review).
|
|
433
|
+
cmd_scan = _normalize_git_globals(_strip_text_flag_values(_strip_heredocs(cmd)))
|
|
434
|
+
# A heredoc fed to an interpreter DOES execute its body — scan those too, so
|
|
435
|
+
# `bash <<'EOF' … git push … EOF` is not a bypass (2026-07 review).
|
|
436
|
+
exec_bodies = _executing_heredoc_bodies(cmd)
|
|
437
|
+
if exec_bodies:
|
|
438
|
+
cmd_scan += "\n" + _normalize_git_globals(_strip_text_flag_values(exec_bodies))
|
|
363
439
|
|
|
364
440
|
for pattern, target, message in COMMAND_RULES:
|
|
365
441
|
if not pattern.search(cmd_scan):
|
|
@@ -463,7 +539,7 @@ def cmd_push(branch: str | None, max_retries: int, *, force: bool = False) -> in
|
|
|
463
539
|
push_cmd = ["git", "push", "-u", "origin", branch]
|
|
464
540
|
if force:
|
|
465
541
|
push_cmd.append("--force-with-lease")
|
|
466
|
-
proc = subprocess.run(push_cmd)
|
|
542
|
+
proc = subprocess.run(push_cmd) # noqa: S603 — fixed git argv + validated branch name, never a shell string
|
|
467
543
|
if proc.returncode == 0:
|
|
468
544
|
sys.stdout.write(f"push: pushed {branch} ({expected_sha})\n")
|
|
469
545
|
return 0
|
|
@@ -559,7 +635,7 @@ def cmd_finish(pr_number: int | None, review_cycle: int | None) -> int:
|
|
|
559
635
|
monitor_args = ["bash", str(script), str(pr_number), "--merge"]
|
|
560
636
|
if review_cycle is not None:
|
|
561
637
|
monitor_args += ["--review-cycle", str(review_cycle)]
|
|
562
|
-
return subprocess.run(monitor_args).returncode
|
|
638
|
+
return subprocess.run(monitor_args).returncode # noqa: S603 — fixed bash argv + resolved script path, never a shell string
|
|
563
639
|
|
|
564
640
|
|
|
565
641
|
_VALID_TYPES = {"feat", "fix", "chore", "docs", "test"}
|
|
@@ -620,10 +696,18 @@ def cmd_create_pr_nojira(
|
|
|
620
696
|
if rc != 0:
|
|
621
697
|
return rc
|
|
622
698
|
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
699
|
+
# `gh pr view` with no selector also resolves the most recent CLOSED/MERGED
|
|
700
|
+
# PR for the branch — reusing a branch name after a merge must open a new
|
|
701
|
+
# PR, not report the merged one as "already exists" (matches check_pr_opened).
|
|
702
|
+
code, out = _gh(["pr", "view", "--json", "url,state"])
|
|
703
|
+
if code == 0:
|
|
704
|
+
try:
|
|
705
|
+
data = json.loads(out or "{}")
|
|
706
|
+
except json.JSONDecodeError:
|
|
707
|
+
data = {}
|
|
708
|
+
if data.get("state") == "OPEN" and data.get("url"):
|
|
709
|
+
sys.stdout.write(f"Draft PR already exists: {data['url']}\n")
|
|
710
|
+
return 0
|
|
627
711
|
|
|
628
712
|
# Conventional Commits, no scope = no linked issue (ADR-006)
|
|
629
713
|
pr_title = f"{type_}: {title}"
|
|
@@ -4,9 +4,13 @@
|
|
|
4
4
|
# Requires: gh, python3 (stdlib only — no jq dependency).
|
|
5
5
|
#
|
|
6
6
|
# Usage:
|
|
7
|
-
# .claude/scripts/monitor_pr.sh <pr-number> [--merge] [--review-cycle N] [--no-review]
|
|
7
|
+
# .claude/scripts/monitor_pr.sh <pr-number> [--merge] [--review-cycle N] [--no-review] [--admin]
|
|
8
8
|
#
|
|
9
9
|
# --merge: squash-merge and delete branch automatically when all checks pass.
|
|
10
|
+
# --admin: allow an admin override when the PR is BLOCKED by branch protection
|
|
11
|
+
# AFTER the review gate passed (e.g. an unresolved conversation). Without it,
|
|
12
|
+
# a post-review BLOCKED state fails with guidance instead of silently
|
|
13
|
+
# overriding the protection setup_github.sh provisioned (2026-07 review).
|
|
10
14
|
# --review-cycle N: current review fix cycle count (0-based, default 0).
|
|
11
15
|
# When N >= MAX_REVIEW_CYCLES and review/decision is still failing or pending,
|
|
12
16
|
# force-merges with --admin.
|
|
@@ -29,33 +33,49 @@
|
|
|
29
33
|
set -euo pipefail
|
|
30
34
|
|
|
31
35
|
PR_NUMBER="${1:-}"
|
|
32
|
-
MODE="
|
|
36
|
+
MODE=""
|
|
33
37
|
REVIEW_CYCLE=0
|
|
34
38
|
MAX_REVIEW_CYCLES=2
|
|
35
39
|
NO_REVIEW=0
|
|
40
|
+
ALLOW_ADMIN=0
|
|
36
41
|
|
|
37
42
|
if [ -z "$PR_NUMBER" ]; then
|
|
38
|
-
echo "Usage: monitor_pr.sh <pr-number> [--merge] [--review-cycle N] [--no-review]" >&2
|
|
43
|
+
echo "Usage: monitor_pr.sh <pr-number> [--merge] [--review-cycle N] [--no-review] [--admin]" >&2
|
|
39
44
|
exit 1
|
|
40
45
|
fi
|
|
41
46
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
fi
|
|
46
|
-
|
|
47
|
-
# Parse remaining flags (order-independent after position 2).
|
|
48
|
-
# Shift past <pr-number> and optional --merge; remaining args are flags.
|
|
47
|
+
# Parse flags (order-independent). --merge is just another flag: the usage
|
|
48
|
+
# line presents every flag as independent, so `monitor_pr.sh 12 --no-review`
|
|
49
|
+
# must not be rejected for lacking --merge in position 2.
|
|
49
50
|
shift 1 # drop PR_NUMBER
|
|
50
|
-
[ "$MODE" = "--merge" ] && shift 1 # drop --merge if present
|
|
51
51
|
while [ $# -gt 0 ]; do
|
|
52
52
|
case "$1" in
|
|
53
|
-
--
|
|
53
|
+
--merge) MODE="--merge"; shift ;;
|
|
54
|
+
--review-cycle)
|
|
55
|
+
# Validate before `shift 2`: with no value, the shift fails under set -e
|
|
56
|
+
# and aborts with no message (Copilot review).
|
|
57
|
+
if [ $# -lt 2 ]; then
|
|
58
|
+
echo "--review-cycle requires a numeric value" >&2
|
|
59
|
+
exit 2
|
|
60
|
+
fi
|
|
61
|
+
REVIEW_CYCLE="$2"; shift 2 ;;
|
|
54
62
|
--review-cycle=*) REVIEW_CYCLE="${1#*=}"; shift ;;
|
|
55
63
|
--no-review) NO_REVIEW=1; shift ;;
|
|
64
|
+
--admin) ALLOW_ADMIN=1; shift ;;
|
|
56
65
|
*) echo "Unknown option: $1" >&2; exit 2 ;;
|
|
57
66
|
esac
|
|
58
67
|
done
|
|
68
|
+
case "$REVIEW_CYCLE" in
|
|
69
|
+
'' | *[!0-9]*) echo "--review-cycle must be a non-negative integer (got '$REVIEW_CYCLE')" >&2; exit 2 ;;
|
|
70
|
+
esac
|
|
71
|
+
|
|
72
|
+
# --admin, --no-review and --review-cycle only take effect while merging. Warn
|
|
73
|
+
# loudly if they were passed without --merge so the flag isn't silently a no-op.
|
|
74
|
+
if [ "$MODE" != "--merge" ]; then
|
|
75
|
+
if [ "$ALLOW_ADMIN" -eq 1 ] || [ "$NO_REVIEW" -eq 1 ] || [ "$REVIEW_CYCLE" -ne 0 ]; then
|
|
76
|
+
echo "WARNING: --admin/--no-review/--review-cycle only apply with --merge; ignoring (monitor-only run)." >&2
|
|
77
|
+
fi
|
|
78
|
+
fi
|
|
59
79
|
|
|
60
80
|
_count_pending() {
|
|
61
81
|
echo "$1" | python3 -c "
|
|
@@ -212,6 +232,7 @@ while { [ "$REVIEW_DECISION" = "REVIEW_REQUIRED" ] || [ "$REVIEW_DECISION" = "UN
|
|
|
212
232
|
# Bot reviewers like Codex post comments without changing reviewDecision.
|
|
213
233
|
if [ "$REVIEW_DECISION" = "REVIEW_REQUIRED" ] && _has_review_activity; then
|
|
214
234
|
echo " Review comments detected — proceeding without waiting for formal approval."
|
|
235
|
+
REVIEW_ACTIVITY=1
|
|
215
236
|
break
|
|
216
237
|
fi
|
|
217
238
|
CHECKS=$(gh pr checks "$PR_NUMBER" --json name,state,bucket 2>/dev/null) || CHECKS="[]"
|
|
@@ -241,8 +262,15 @@ if [ "$REVIEW_DECISION" = "CHANGES_REQUESTED" ]; then
|
|
|
241
262
|
fi
|
|
242
263
|
|
|
243
264
|
if [ "$REVIEW_DECISION" = "REVIEW_REQUIRED" ]; then
|
|
244
|
-
|
|
245
|
-
|
|
265
|
+
if [ "${REVIEW_ACTIVITY:-0}" -eq 1 ]; then
|
|
266
|
+
# The wait loop broke early because reviews were posted (e.g. a bot's
|
|
267
|
+
# COMMENTED review) — surface them instead of claiming nobody acted.
|
|
268
|
+
echo "PR #$PR_NUMBER: review comments posted, but no formal approval yet:"
|
|
269
|
+
_print_review_comments
|
|
270
|
+
else
|
|
271
|
+
echo "PR #$PR_NUMBER: review/decision still pending after ${REVIEW_TIMEOUT}s — no reviewer has acted."
|
|
272
|
+
echo " Full PR: $(gh pr view "$PR_NUMBER" --json url -q '.url' 2>/dev/null || true)"
|
|
273
|
+
fi
|
|
246
274
|
|
|
247
275
|
if [ "$MODE" = "--merge" ]; then
|
|
248
276
|
if [ "$REVIEW_CYCLE" -ge "$MAX_REVIEW_CYCLES" ]; then
|
|
@@ -272,8 +300,21 @@ if [ "$MODE" = "--merge" ]; then
|
|
|
272
300
|
exit 1
|
|
273
301
|
fi
|
|
274
302
|
elif [ "$MERGE_STATE" = "BLOCKED" ]; then
|
|
275
|
-
|
|
276
|
-
|
|
303
|
+
# The review gate already passed to reach here, so BLOCKED means a DIFFERENT
|
|
304
|
+
# branch-protection rule is unmet — most often an unresolved review thread.
|
|
305
|
+
# Auto-admin-merging past it on cycle 0 silently defeats the protection this
|
|
306
|
+
# very tool set up, so it requires an explicit --admin opt-in (2026-07
|
|
307
|
+
# review; backported from the template copy).
|
|
308
|
+
if [ "$ALLOW_ADMIN" -eq 1 ]; then
|
|
309
|
+
echo "PR is blocked by branch protection — merging with admin override (--admin)."
|
|
310
|
+
_admin_merge
|
|
311
|
+
else
|
|
312
|
+
echo "ERROR: PR #$PR_NUMBER is BLOCKED by branch protection after the review gate" >&2
|
|
313
|
+
echo " passed — typically an unresolved review conversation, or a required" >&2
|
|
314
|
+
echo " check that has not reported. Resolve the blocker, or re-run with --admin" >&2
|
|
315
|
+
echo " to override." >&2
|
|
316
|
+
exit 1
|
|
317
|
+
fi
|
|
277
318
|
else
|
|
278
319
|
if ! _run_gh pr merge "$PR_NUMBER" --squash --delete-branch; then
|
|
279
320
|
if ! _run_gh pr merge "$PR_NUMBER" --squash --delete-branch --auto; then
|
|
@@ -41,8 +41,13 @@ git clone "https://github.com/${REPO_SLUG}.wiki.git" "$WIKI_DIR"
|
|
|
41
41
|
cp "$SOURCE_FILE" "$WIKI_DIR/Home.md"
|
|
42
42
|
|
|
43
43
|
cd "$WIKI_DIR"
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
# ${arr[@]+...} guard: expanding an empty array under `set -u` is a fatal
|
|
45
|
+
# "unbound variable" on bash 3.2-4.3 (stock macOS), aborting before the commit.
|
|
46
|
+
for page in ${PRUNE_PAGES[@]+"${PRUNE_PAGES[@]}"}; do
|
|
47
|
+
if [[ -f "$page" ]]; then
|
|
48
|
+
git rm -q "$page"
|
|
49
|
+
echo "Pruned $page"
|
|
50
|
+
fi
|
|
46
51
|
done
|
|
47
52
|
git add Home.md
|
|
48
53
|
if git diff --cached --quiet; then
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# pre-push gate for the project-init repo itself (dogfood).
|
|
3
|
+
#
|
|
4
|
+
# Runs the SAME `just ci` (lint + tests) that CI runs, before the push leaves
|
|
5
|
+
# the machine — so nothing red reaches a PR and the push→CI-fail→fix→re-push
|
|
6
|
+
# loop is caught locally. This is the local↔CI parity gate whose absence let a
|
|
7
|
+
# fresh-scaffold lint failure ship (the scaffolder's CI caught it only after a
|
|
8
|
+
# push, and even then incompletely).
|
|
9
|
+
#
|
|
10
|
+
# Enabled automatically by `just setup` (git config core.hooksPath .githooks).
|
|
11
|
+
# Bypass in an emergency with: git push --no-verify
|
|
12
|
+
set -euo pipefail
|
|
13
|
+
|
|
14
|
+
if command -v just >/dev/null 2>&1; then
|
|
15
|
+
# `just ci` tests the working tree, but the push ships the committed tree.
|
|
16
|
+
# Skip (fail-open) on a dirty worktree rather than test a tree that isn't what
|
|
17
|
+
# gets pushed — a WIP fix could mask a failure, or unrelated WIP fail a clean
|
|
18
|
+
# push. CI stays the backstop.
|
|
19
|
+
if [ -n "$(git status --porcelain 2>/dev/null)" ]; then
|
|
20
|
+
echo "pre-push: working tree is dirty — skipping the 'just ci' gate" >&2
|
|
21
|
+
echo " (it would test the worktree, not the commit being pushed)." >&2
|
|
22
|
+
echo " Commit or stash your changes to run the gate before pushing." >&2
|
|
23
|
+
else
|
|
24
|
+
echo "pre-push: running 'just ci' (lint + tests)…"
|
|
25
|
+
if ! just ci; then
|
|
26
|
+
echo ""
|
|
27
|
+
echo "❌ pre-push: 'just ci' failed — fix the errors above before pushing."
|
|
28
|
+
echo " (bypass in an emergency with: git push --no-verify)"
|
|
29
|
+
exit 1
|
|
30
|
+
fi
|
|
31
|
+
fi
|
|
32
|
+
else
|
|
33
|
+
echo "pre-push: 'just' not found — skipping local CI gate (CI still runs)." >&2
|
|
34
|
+
fi
|
|
@@ -14,35 +14,59 @@ jobs:
|
|
|
14
14
|
name: Lint and test
|
|
15
15
|
runs-on: ubuntu-24.04
|
|
16
16
|
steps:
|
|
17
|
-
- uses: actions/checkout@v6
|
|
17
|
+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
|
18
18
|
|
|
19
19
|
- name: Install uv
|
|
20
|
-
uses: astral-sh/setup-uv@v8.1.0
|
|
20
|
+
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
|
21
21
|
with:
|
|
22
22
|
version: "0.11.7"
|
|
23
23
|
enable-cache: true
|
|
24
24
|
cache-dependency-glob: "uv.lock"
|
|
25
25
|
python-version: "3.12"
|
|
26
26
|
|
|
27
|
+
# shellcheck ships preinstalled on ubuntu-24.04; shfmt does not. The
|
|
28
|
+
# scaffolded-output lint guard (test_shell_lint_gate.py) skips when its
|
|
29
|
+
# tool is absent, so without this step the shfmt guard would silently
|
|
30
|
+
# no-op in CI — a green check that tested nothing. Pinned + checksum-
|
|
31
|
+
# verified, mirroring the install the scaffolded ci.yml.tmpl ships.
|
|
32
|
+
- name: Install shfmt
|
|
33
|
+
run: |
|
|
34
|
+
mkdir -p "$HOME/.local/bin"
|
|
35
|
+
tmp="$(mktemp -d)"
|
|
36
|
+
curl -sSfL https://github.com/mvdan/sh/releases/download/v3.8.0/shfmt_v3.8.0_linux_amd64 -o "$tmp/shfmt_v3.8.0_linux_amd64"
|
|
37
|
+
curl -sSfL https://github.com/mvdan/sh/releases/download/v3.8.0/sha256sums.txt -o "$tmp/sha256sums.txt"
|
|
38
|
+
( cd "$tmp" && grep 'shfmt_v3.8.0_linux_amd64$' sha256sums.txt | sha256sum -c - )
|
|
39
|
+
chmod +x "$tmp/shfmt_v3.8.0_linux_amd64"
|
|
40
|
+
mv "$tmp/shfmt_v3.8.0_linux_amd64" "$HOME/.local/bin/shfmt"
|
|
41
|
+
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
|
|
42
|
+
|
|
27
43
|
- name: Sync dev dependencies
|
|
28
|
-
run: uv sync --
|
|
44
|
+
run: uv sync --group dev --locked
|
|
29
45
|
|
|
30
46
|
- name: Lint (ruff)
|
|
31
47
|
run: uv run ruff check .
|
|
32
48
|
|
|
33
49
|
- name: Tests (pytest) — parallel mode
|
|
34
|
-
#
|
|
35
|
-
|
|
50
|
+
# Use xdist when importable, else single-threaded — decided by an
|
|
51
|
+
# explicit capability check, not `|| retry`, so a genuinely failing
|
|
52
|
+
# suite is not run twice with its first-pass stderr hidden (2026-07
|
|
53
|
+
# review).
|
|
54
|
+
run: |
|
|
55
|
+
if uv run python -c "import xdist" 2>/dev/null; then
|
|
56
|
+
uv run pytest -n auto --tb=short -q
|
|
57
|
+
else
|
|
58
|
+
uv run pytest --tb=short -q
|
|
59
|
+
fi
|
|
36
60
|
|
|
37
61
|
wheel-smoke:
|
|
38
62
|
name: Wheel smoke test
|
|
39
63
|
runs-on: ubuntu-24.04
|
|
40
64
|
needs: lint-and-test
|
|
41
65
|
steps:
|
|
42
|
-
- uses: actions/checkout@v6
|
|
66
|
+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
|
43
67
|
|
|
44
68
|
- name: Install uv
|
|
45
|
-
uses: astral-sh/setup-uv@v8.1.0
|
|
69
|
+
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
|
46
70
|
with:
|
|
47
71
|
version: "0.11.7"
|
|
48
72
|
enable-cache: true
|
|
@@ -89,12 +113,12 @@ jobs:
|
|
|
89
113
|
name: Secret scan (gitleaks)
|
|
90
114
|
runs-on: ubuntu-24.04
|
|
91
115
|
steps:
|
|
92
|
-
- uses: actions/checkout@v6
|
|
116
|
+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
|
93
117
|
with:
|
|
94
118
|
# Full history so leaked commits are caught, not just the latest diff
|
|
95
119
|
fetch-depth: 0
|
|
96
120
|
|
|
97
|
-
- uses: gitleaks/gitleaks-action@v3
|
|
121
|
+
- uses: gitleaks/gitleaks-action@e0c47f4f8be36e29cdc102c57e68cb5cbf0e8d1e # v3
|
|
98
122
|
env:
|
|
99
123
|
GITHUB_TOKEN: ${{ github.token }}
|
|
100
124
|
|
|
@@ -104,10 +128,10 @@ jobs:
|
|
|
104
128
|
name: ShellCheck (scaffolded scripts)
|
|
105
129
|
runs-on: ubuntu-24.04
|
|
106
130
|
steps:
|
|
107
|
-
- uses: actions/checkout@v6
|
|
131
|
+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
|
108
132
|
|
|
109
133
|
- name: Install uv
|
|
110
|
-
uses: astral-sh/setup-uv@v8.1.0
|
|
134
|
+
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
|
111
135
|
with:
|
|
112
136
|
version: "0.11.7"
|
|
113
137
|
enable-cache: true
|
|
@@ -146,8 +170,8 @@ jobs:
|
|
|
146
170
|
outputs:
|
|
147
171
|
shell: ${{ steps.filter.outputs.shell }}
|
|
148
172
|
steps:
|
|
149
|
-
- uses: actions/checkout@v6
|
|
150
|
-
- uses: dorny/paths-filter@v3
|
|
173
|
+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
|
174
|
+
- uses: dorny/paths-filter@d1c1ffe0248fe513906c8e24db8ea791d46f8590 # v3
|
|
151
175
|
id: filter
|
|
152
176
|
with:
|
|
153
177
|
filters: |
|
|
@@ -170,10 +194,10 @@ jobs:
|
|
|
170
194
|
if: needs.changes.outputs.shell == 'true'
|
|
171
195
|
runs-on: macos-latest
|
|
172
196
|
steps:
|
|
173
|
-
- uses: actions/checkout@v6
|
|
197
|
+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
|
174
198
|
|
|
175
199
|
- name: Install uv
|
|
176
|
-
uses: astral-sh/setup-uv@v8.1.0
|
|
200
|
+
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
|
177
201
|
with:
|
|
178
202
|
version: "0.11.7"
|
|
179
203
|
python-version: "3.12"
|
|
@@ -228,10 +252,10 @@ jobs:
|
|
|
228
252
|
run:
|
|
229
253
|
shell: bash # GitHub's "bash" on Windows is Git Bash — the supported path
|
|
230
254
|
steps:
|
|
231
|
-
- uses: actions/checkout@v6
|
|
255
|
+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
|
232
256
|
|
|
233
257
|
- name: Install uv
|
|
234
|
-
uses: astral-sh/setup-uv@v8.1.0
|
|
258
|
+
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
|
235
259
|
with:
|
|
236
260
|
version: "0.11.7"
|
|
237
261
|
python-version: "3.12"
|
|
@@ -35,10 +35,10 @@ jobs:
|
|
|
35
35
|
name: Build site
|
|
36
36
|
runs-on: ubuntu-24.04
|
|
37
37
|
steps:
|
|
38
|
-
- uses: actions/checkout@v6
|
|
38
|
+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
|
39
39
|
|
|
40
40
|
- name: Install uv
|
|
41
|
-
uses: astral-sh/setup-uv@v8.1.0
|
|
41
|
+
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
|
42
42
|
with:
|
|
43
43
|
version: "0.11.7"
|
|
44
44
|
enable-cache: true
|
|
@@ -54,7 +54,7 @@ jobs:
|
|
|
54
54
|
run: uv run mkdocs build --strict
|
|
55
55
|
|
|
56
56
|
- name: Upload Pages artifact
|
|
57
|
-
uses: actions/upload-pages-artifact@v3
|
|
57
|
+
uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3
|
|
58
58
|
with:
|
|
59
59
|
path: site
|
|
60
60
|
|
|
@@ -72,4 +72,4 @@ jobs:
|
|
|
72
72
|
steps:
|
|
73
73
|
- name: Deploy to GitHub Pages
|
|
74
74
|
id: deployment
|
|
75
|
-
uses: actions/deploy-pages@v4
|
|
75
|
+
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4
|
|
@@ -5,11 +5,21 @@
|
|
|
5
5
|
# Cutting a release:
|
|
6
6
|
# 1. Bump version in pyproject.toml AND src/project_init/__init__.py
|
|
7
7
|
# 2. git tag vX.Y.Z && push the tag
|
|
8
|
+
# — or, where a tag can't be pushed directly, run the "Tag Release"
|
|
9
|
+
# workflow (tag-release.yml): it verifies + creates the tag and then
|
|
10
|
+
# dispatches THIS workflow on the new tag ref.
|
|
8
11
|
name: Release
|
|
9
12
|
|
|
10
13
|
on:
|
|
11
14
|
push:
|
|
12
15
|
tags: ["v*"]
|
|
16
|
+
# Dispatchable on an EXISTING v* tag ref (tag-release.yml does this after
|
|
17
|
+
# creating the tag — a GITHUB_TOKEN tag push never triggers the tag-push
|
|
18
|
+
# path above, by GitHub's recursive-workflow rule). Every step below reads
|
|
19
|
+
# the tag from the run ref, so a dispatch on a non-tag ref fails the
|
|
20
|
+
# version guard cleanly. Keeping the run ON the tag ref also satisfies the
|
|
21
|
+
# pypi environment's v*-tags-only deployment rule (ADR-011).
|
|
22
|
+
workflow_dispatch: {}
|
|
13
23
|
|
|
14
24
|
permissions:
|
|
15
25
|
contents: write
|
|
@@ -18,13 +28,13 @@ jobs:
|
|
|
18
28
|
release:
|
|
19
29
|
runs-on: ubuntu-24.04
|
|
20
30
|
steps:
|
|
21
|
-
- uses: actions/checkout@v6
|
|
31
|
+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
|
22
32
|
with:
|
|
23
33
|
# Full history — git-cliff needs prior tags to scope --latest.
|
|
24
34
|
fetch-depth: 0
|
|
25
35
|
|
|
26
36
|
- name: Install uv
|
|
27
|
-
uses: astral-sh/setup-uv@v8.1.0
|
|
37
|
+
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
|
28
38
|
with:
|
|
29
39
|
version: "0.11.7"
|
|
30
40
|
|
|
@@ -40,7 +50,7 @@ jobs:
|
|
|
40
50
|
run: uv build
|
|
41
51
|
|
|
42
52
|
- name: Generate changelog (latest tag)
|
|
43
|
-
uses: orhun/git-cliff-action@v4
|
|
53
|
+
uses: orhun/git-cliff-action@f50e11560dce63f7c33227798f90b924471a88b5 # v4
|
|
44
54
|
with:
|
|
45
55
|
config: cliff.toml
|
|
46
56
|
args: --latest
|
|
@@ -48,7 +58,7 @@ jobs:
|
|
|
48
58
|
OUTPUT: RELEASE_NOTES.md
|
|
49
59
|
|
|
50
60
|
- name: Create GitHub Release
|
|
51
|
-
uses: softprops/action-gh-release@v3
|
|
61
|
+
uses: softprops/action-gh-release@718ea10b132b3b2eba29c1007bb80653f286566b # v3
|
|
52
62
|
with:
|
|
53
63
|
# Only the build artifacts — an unscoped glob also picks up the
|
|
54
64
|
# tracked dist/.gitignore and uploads it as a stray
|
|
@@ -72,10 +82,10 @@ jobs:
|
|
|
72
82
|
contents: read
|
|
73
83
|
id-token: write
|
|
74
84
|
steps:
|
|
75
|
-
- uses: actions/checkout@v6
|
|
85
|
+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
|
76
86
|
|
|
77
87
|
- name: Install uv
|
|
78
|
-
uses: astral-sh/setup-uv@v8.1.0
|
|
88
|
+
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
|
79
89
|
with:
|
|
80
90
|
version: "0.11.7"
|
|
81
91
|
|
|
@@ -83,4 +93,4 @@ jobs:
|
|
|
83
93
|
run: uv build
|
|
84
94
|
|
|
85
95
|
- name: Publish to PyPI
|
|
86
|
-
uses: pypa/gh-action-pypi-publish@release/v1
|
|
96
|
+
uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # release/v1
|
|
@@ -31,6 +31,10 @@ jobs:
|
|
|
31
31
|
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
32
32
|
SHA: ${{ github.event.pull_request.head.sha }}
|
|
33
33
|
REPO: ${{ github.repository }}
|
|
34
|
+
# Route the event value through env, not inline ${{ }} in the script —
|
|
35
|
+
# keeps the whole workflow to one untrusted-input discipline (2026-07
|
|
36
|
+
# review). GitHub-generated URL, so risk is low; consistency matters.
|
|
37
|
+
REVIEW_URL: ${{ github.event.review.html_url }}
|
|
34
38
|
run: |
|
|
35
39
|
DECISION=$(gh pr view "$PR_NUMBER" --repo "$REPO" --json reviewDecision -q '.reviewDecision // ""')
|
|
36
40
|
case "$DECISION" in
|
|
@@ -45,4 +49,4 @@ jobs:
|
|
|
45
49
|
--field state="$STATE" \
|
|
46
50
|
--field description="$DESCRIPTION" \
|
|
47
51
|
--field context="review/decision" \
|
|
48
|
-
--field target_url="$
|
|
52
|
+
--field target_url="$REVIEW_URL"
|