claude-dev-env 4.2.0 → 7.0.0
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.
- package/.agents/agents/pr-description-writer.md +2 -2
- package/.agents/agents/test_agent_frontmatter.py +2 -2
- package/.agents/agents/test_pr_description_writer_style.py +1 -3
- package/.agents/skills/e-code-review/SKILL.md +12 -12
- package/.agents/skills/e-code-review/preflight-proposal.contract.test.mjs +20 -0
- package/.agents/skills/e-code-review/reference/fix.md +15 -17
- package/.agents/skills/e-code-review/reference/loop.md +35 -39
- package/.agents/skills/e-code-review/reference/mode-contract.test.mjs +2 -1
- package/.agents/skills/e-code-review/reference/preflight-proposal.md +44 -9
- package/.agents/skills/e-code-review/reference/runner-selection.md +13 -14
- package/.agents/skills/issue-tracker/SKILL.md +7 -0
- package/.agents/skills/pull-request/SKILL.md +216 -0
- package/.agents/skills/pull-request/reference/publication-tasks.md +18 -0
- package/.agents/skills/pull-request/scripts/github_pr_command_constants/__init__.py +1 -0
- package/.agents/skills/pull-request/scripts/github_pr_command_constants/config/__init__.py +1 -0
- package/.agents/skills/pull-request/scripts/github_pr_command_constants/config/constants.py +69 -0
- package/.agents/skills/pull-request/scripts/pull_request.py +265 -0
- package/.agents/skills/pull-request/scripts/recover_legacy_author.py +251 -0
- package/.agents/skills/pull-request/scripts/test_github_pr_command_constants.py +58 -0
- package/.agents/skills/pull-request/scripts/test_pull_request.py +396 -0
- package/.agents/skills/pull-request/scripts/test_recover_legacy_author.py +221 -0
- package/.agents/skills/skill-builder/SKILL.md +3 -196
- package/.agents/skills/test-runner/SKILL.md +69 -0
- package/.agents/skills/test-runner/scripts/preflight_checks.py +365 -0
- package/.agents/skills/test-runner/scripts/run_tests.py +316 -0
- package/.agents/skills/test-runner/scripts/test_preflight_checks.py +185 -0
- package/.agents/skills/test-runner/scripts/test_run_tests.py +281 -0
- package/.agents/skills/test-runner/scripts/test_runner_constants/__init__.py +1 -0
- package/.agents/skills/test-runner/scripts/test_runner_constants/config/__init__.py +1 -0
- package/.agents/skills/test-runner/scripts/test_runner_constants/config/constants.py +96 -0
- package/.agents/skills-archived/pr-loop-cloud-transport/reference/identity-and-hooks.md +1 -1
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/terminology_sweep_constants.py +6 -0
- package/_shared/pr-loop/scripts/terminology_sweep.py +64 -19
- package/_shared/pr-loop/scripts/tests/test_terminology_sweep.py +59 -0
- package/bin/ever-shipped-skills.mjs +2 -0
- package/bin/ever-shipped-skills.test.mjs +8 -0
- package/bin/install.agents-home.test.mjs +15 -13
- package/bin/install.mjs +37 -1
- package/bin/install.policy-lint.test.mjs +78 -0
- package/bin/install.prune.test.mjs +149 -20
- package/bin/install.pstack-plugin.test.mjs +114 -0
- package/bin/install.test.mjs +61 -7
- package/bin/refresh-pstack-plugin-skills.test.mjs +211 -0
- package/hooks/advisory/pr_done_reminder.py +342 -0
- package/hooks/advisory/test_pr_done_reminder.py +249 -0
- package/hooks/blocking/bash_post_call_dispatcher.py +53 -6
- package/hooks/blocking/code_rules_paired_test.py +22 -15
- package/hooks/blocking/pii_prevention_blocker.py +32 -51
- package/hooks/blocking/test_bash_post_call_dispatcher.py +55 -17
- package/hooks/blocking/test_bash_pre_tool_use_dispatcher.py +1 -4
- package/hooks/blocking/test_code_rules_command_dispatch.py +2 -2
- package/hooks/blocking/test_code_rules_enforcer_paired_test.py +36 -29
- package/hooks/blocking/test_code_rules_js_resume_task_enumeration.py +4 -4
- package/hooks/blocking/test_code_rules_js_returns_object_schemaless.py +5 -5
- package/hooks/blocking/test_pii_prevention_blocker.py +37 -89
- package/hooks/blocking/test_pre_tool_use_dispatcher.py +68 -133
- package/hooks/blocking/test_pre_tool_use_dispatcher_native.py +20 -51
- package/hooks/blocking/test_precommit_code_rules_gate_native_owner.py +18 -18
- package/hooks/gh_post_body_texts.py +195 -0
- package/hooks/git-hooks/git_hooks_constants/staged_policy_lint.py +12 -0
- package/hooks/git-hooks/pre_commit.py +52 -11
- package/hooks/git-hooks/test_installed_policy_lint.py +159 -0
- package/hooks/git-hooks/test_native_policy_commit.py +87 -0
- package/hooks/git-hooks/test_pre_commit.py +246 -0
- package/hooks/hooks.json +1 -16
- package/hooks/hooks_constants/bash_post_call_dispatcher_constants.py +14 -2
- package/hooks/hooks_constants/bash_pre_tool_use_dispatcher_constants.py +0 -8
- package/hooks/hooks_constants/gh_post_body_texts_constants.py +12 -0
- package/hooks/hooks_constants/pr_done_reminder_constants.py +98 -0
- package/hooks/hooks_constants/pre_tool_use_dispatcher_constants.py +10 -43
- package/hooks/hooks_constants/test_bash_post_call_dispatcher_constants.py +17 -7
- package/hooks/hooks_constants/test_bash_pre_tool_use_dispatcher_constants.py +0 -7
- package/hooks/hooks_constants/test_failure_recorder_constants.py +3 -3
- package/hooks/hooks_constants/test_gh_post_body_texts_constants.py +19 -0
- package/hooks/hooks_constants/test_pr_done_reminder_constants.py +40 -0
- package/hooks/hooks_constants/test_pre_tool_use_dispatcher_constants.py +20 -32
- package/hooks/observability/test_failure_recorder.py +1 -1
- package/hooks/pyproject.toml +1 -1
- package/hooks/test_gh_post_body_texts.py +79 -0
- package/package.json +2 -2
- package/rules/durable-post-artifacts.md +32 -20
- package/rules/gh-cli-conventions.md +23 -13
- package/rules/git-workflow.md +21 -8
- package/scripts/check.ps1 +0 -1
- package/{.agents/skills/run-claude-dev-env/driver.mjs → scripts/ci/installer-lifecycle.mjs} +3 -28
- package/scripts/ci/installer-lifecycle.test.mjs +26 -0
- package/scripts/ci/windows-installer-lifecycle.ps1 +1 -11
- package/scripts/dev_env_scripts_constants/shared_tree_constants.py +4 -5
- package/scripts/durable_post_lint.py +206 -0
- package/scripts/durable_post_lint_config/config/constants.py +96 -0
- package/scripts/durable_post_lint_config/config/test_constants.py +25 -0
- package/scripts/policy_lint/adapter_configuration.py +53 -12
- package/scripts/policy_lint/adapter_detectors.py +13 -6
- package/scripts/policy_lint/adapters.py +7 -4
- package/scripts/policy_lint/config/constants.py +5 -0
- package/scripts/policy_lint/engine.py +48 -4
- package/scripts/policy_lint/model.py +1 -0
- package/scripts/policy_lint/registry.py +1 -1
- package/scripts/policy_lint/selection.py +2 -1
- package/scripts/policy_lint/selection_git.py +2 -0
- package/scripts/refresh_pstack_plugin_skills.mjs +200 -0
- package/scripts/repository_checks/config/constants.py +0 -5
- package/scripts/shared_tree_paths.py +32 -3
- package/scripts/test_durable_post_lint.py +332 -0
- package/scripts/test_shared_tree_paths.py +33 -0
- package/scripts/tests/test_adapter_configuration.py +54 -0
- package/scripts/tests/test_policy_lint_rules_archive.py +120 -0
- package/scripts/tests/test_policy_lint_rules_engine.py +25 -4
- package/scripts/tests/test_policy_lint_rules_installed_loader.py +29 -0
- package/scripts/tests/test_policy_lint_rules_registry.py +227 -13
- package/scripts/tests/test_policy_lint_selection.py +25 -2
- package/scripts/tests/test_policy_lint_selection_native_index.py +30 -0
- package/scripts/tests/test_rules.py +3 -7
- package/.agents/skills/_shared/pr-loop/.claude/CLAUDE.md +0 -1
- package/.agents/skills/_shared/pr-loop/AGENTS.md +0 -1
- package/.agents/skills/_shared/pr-loop/audit-contract.md +0 -5
- package/.agents/skills/_shared/pr-loop/audit-reply-template.md +0 -5
- package/.agents/skills/_shared/pr-loop/code-rules-gate.md +0 -5
- package/.agents/skills/_shared/pr-loop/fix-protocol.md +0 -5
- package/.agents/skills/_shared/pr-loop/gh-payloads.md +0 -5
- package/.agents/skills/_shared/pr-loop/portable-driver.md +0 -149
- package/.agents/skills/_shared/pr-loop/post-audit-thread-contract.md +0 -5
- package/.agents/skills/_shared/pr-loop/precatch-rubric.md +0 -5
- package/.agents/skills/_shared/pr-loop/preflight-proposal.contract.test.mjs +0 -119
- package/.agents/skills/_shared/pr-loop/preflight-proposal.md +0 -5
- package/.agents/skills/_shared/pr-loop/prompts/.claude/CLAUDE.md +0 -1
- package/.agents/skills/_shared/pr-loop/prompts/AGENTS.md +0 -1
- package/.agents/skills/_shared/pr-loop/prompts/pr-consistency-audit.xml +0 -324
- package/.agents/skills/_shared/pr-loop/scripts/.claude/CLAUDE.md +0 -1
- package/.agents/skills/_shared/pr-loop/scripts/AGENTS.md +0 -1
- package/.agents/skills/_shared/pr-loop/scripts/RUNTIME_SCRIPTS.md +0 -29
- package/.agents/skills/_shared/pr-loop/scripts/_cli_utils.py +0 -22
- package/.agents/skills/_shared/pr-loop/scripts/_path_resolver.py +0 -186
- package/.agents/skills/_shared/pr-loop/scripts/_xml_utils.py +0 -20
- package/.agents/skills/_shared/pr-loop/scripts/audit_category_schema.py +0 -355
- package/.agents/skills/_shared/pr-loop/scripts/build_audit_prompt.py +0 -289
- package/.agents/skills/_shared/pr-loop/scripts/build_converge_task_list.py +0 -310
- package/.agents/skills/_shared/pr-loop/scripts/build_fix_prompt.py +0 -292
- package/.agents/skills/_shared/pr-loop/scripts/init_loop_state.py +0 -134
- package/.agents/skills/_shared/pr-loop/scripts/portable_converge_driver.py +0 -1646
- package/.agents/skills/_shared/pr-loop/scripts/preflight_worktree.py +0 -392
- package/.agents/skills/_shared/pr-loop/scripts/select_converge_pacer.py +0 -215
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/.claude/CLAUDE.md +0 -1
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/AGENTS.md +0 -1
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/__init__.py +0 -0
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/audit_category_schema_constants.py +0 -37
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/converge_task_list_constants.py +0 -56
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/handoff_constants.py +0 -45
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/pacer_constants.py +0 -47
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/path_resolver_constants.py +0 -157
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/portable_driver_constants.py +0 -177
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/preflight_constants.py +0 -70
- package/.agents/skills/_shared/pr-loop/scripts/teardown_worktrees.py +0 -172
- package/.agents/skills/_shared/pr-loop/scripts/test__path_resolver.py +0 -106
- package/.agents/skills/_shared/pr-loop/scripts/test_audit_category_schema.py +0 -94
- package/.agents/skills/_shared/pr-loop/scripts/test_build_audit_prompt.py +0 -499
- package/.agents/skills/_shared/pr-loop/scripts/test_build_converge_task_list.py +0 -140
- package/.agents/skills/_shared/pr-loop/scripts/test_build_fix_prompt.py +0 -262
- package/.agents/skills/_shared/pr-loop/scripts/test_init_loop_state.py +0 -71
- package/.agents/skills/_shared/pr-loop/scripts/test_portable_converge_driver.py +0 -1119
- package/.agents/skills/_shared/pr-loop/scripts/test_preflight_worktree.py +0 -287
- package/.agents/skills/_shared/pr-loop/scripts/test_select_converge_pacer.py +0 -207
- package/.agents/skills/_shared/pr-loop/scripts/test_teardown_worktrees.py +0 -59
- package/.agents/skills/_shared/pr-loop/scripts/test_write_handoff.py +0 -201
- package/.agents/skills/_shared/pr-loop/scripts/write_audit_outcomes.py +0 -182
- package/.agents/skills/_shared/pr-loop/scripts/write_fix_outcomes.py +0 -206
- package/.agents/skills/_shared/pr-loop/scripts/write_handoff.py +0 -309
- package/.agents/skills/_shared/pr-loop/state-schema.md +0 -5
- package/.agents/skills/_shared/pr-loop/worker-spawn.md +0 -5
- package/.agents/skills/autoconverge/.claude/CLAUDE.md +0 -1
- package/.agents/skills/autoconverge/AGENTS.md +0 -1
- package/.agents/skills/autoconverge/SKILL.md +0 -431
- package/.agents/skills/autoconverge/reference/.claude/CLAUDE.md +0 -1
- package/.agents/skills/autoconverge/reference/AGENTS.md +0 -1
- package/.agents/skills/autoconverge/reference/closing-report.md +0 -93
- package/.agents/skills/autoconverge/reference/convergence-gates.md +0 -31
- package/.agents/skills/autoconverge/reference/convergence.md +0 -219
- package/.agents/skills/autoconverge/reference/copilot-findings.md +0 -51
- package/.agents/skills/autoconverge/reference/gotchas.md +0 -66
- package/.agents/skills/autoconverge/reference/headless-safety.md +0 -44
- package/.agents/skills/autoconverge/reference/multi-pr.md +0 -128
- package/.agents/skills/autoconverge/reference/self-closing-loop.md +0 -84
- package/.agents/skills/autoconverge/reference/stop-conditions.md +0 -127
- package/.agents/skills/autoconverge/test_portable_pacer_gate.py +0 -54
- package/.agents/skills/autoconverge/workflow/.claude/CLAUDE.md +0 -1
- package/.agents/skills/autoconverge/workflow/AGENTS.md +0 -1
- package/.agents/skills/autoconverge/workflow/aggregate_runs.py +0 -371
- package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/.claude/CLAUDE.md +0 -1
- package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/AGENTS.md +0 -1
- package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/__init__.py +0 -0
- package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/render_report_constants.py +0 -250
- package/.agents/skills/autoconverge/workflow/converge.clean-audit.test.mjs +0 -665
- package/.agents/skills/autoconverge/workflow/converge.codex-gate.test.mjs +0 -472
- package/.agents/skills/autoconverge/workflow/converge.contract.test.mjs +0 -64
- package/.agents/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +0 -1009
- package/.agents/skills/autoconverge/workflow/converge.fix-progress.test.mjs +0 -107
- package/.agents/skills/autoconverge/workflow/converge.fix-recovery.test.mjs +0 -33
- package/.agents/skills/autoconverge/workflow/converge.merge-conflict.test.mjs +0 -15
- package/.agents/skills/autoconverge/workflow/converge.mjs +0 -3132
- package/.agents/skills/autoconverge/workflow/converge.p2-advance.test.mjs +0 -202
- package/.agents/skills/autoconverge/workflow/converge.path-aware.test.mjs +0 -47
- package/.agents/skills/autoconverge/workflow/converge.precatch.test.mjs +0 -152
- package/.agents/skills/autoconverge/workflow/converge.run-input.test.mjs +0 -116
- package/.agents/skills/autoconverge/workflow/converge_multi.mjs +0 -169
- package/.agents/skills/autoconverge/workflow/converge_multi.run-input.test.mjs +0 -173
- package/.agents/skills/autoconverge/workflow/convergence_summary.py +0 -110
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a11d903476b803493.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a26213978adeef6fb.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a3def0d15ed9d9110.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a41f41b1b708ee3b7.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a758b880abecc3ff7.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a8897b89656b1bd16.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-ab1c2d3e4f5a6b7c8.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-abd463d744a1437bc.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-ad19d027ae8ee1816.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/workflows/wf_881252e6-700.json +0 -266
- package/.agents/skills/autoconverge/workflow/render_report.py +0 -1024
- package/.agents/skills/autoconverge/workflow/test_aggregate_runs.py +0 -134
- package/.agents/skills/autoconverge/workflow/test_convergence_summary.py +0 -149
- package/.agents/skills/autoconverge/workflow/test_render_report.py +0 -812
- package/.agents/skills/hitl/SKILL.md +0 -45
- package/.agents/skills/pr-cleanup/SKILL.md +0 -140
- package/.agents/skills/pr-cleanup/reference/process-inventory.md +0 -17
- package/.agents/skills/pr-cleanup/reference/task-seeds.md +0 -22
- package/.agents/skills/pr-name-by-capability/SKILL.md +0 -73
- package/.agents/skills/pr-name-by-capability/reference/fetch-commands.md +0 -29
- package/.agents/skills/pr-name-by-capability/reference/offense-examples.md +0 -32
- package/.agents/skills/pr-name-by-capability/reference/report-template.md +0 -29
- package/.agents/skills/pr-name-by-capability/reference/rule-checklist.md +0 -38
- package/.agents/skills/pr-name-by-capability/reference/task-seeds.md +0 -10
- package/.agents/skills/pr-plain-language-cleanup/SKILL.md +0 -93
- package/.agents/skills/pr-refinement/SKILL.md +0 -31
- package/.agents/skills/pr-shared-extraction/SKILL.md +0 -177
- package/.agents/skills/pr-shared-extraction/reference/examples.md +0 -46
- package/.agents/skills/pr-shared-extraction/reference/offense-taxonomy.md +0 -100
- package/.agents/skills/pr-small-cl/SKILL.md +0 -52
- package/.agents/skills/pr-title-description/SKILL.md +0 -96
- package/.agents/skills/prototype/SKILL.md +0 -85
- package/.agents/skills/prototype/reference/honest-limitations.md +0 -23
- package/.agents/skills/prototype/reference/promotion-tasks.md +0 -23
- package/.agents/skills/prototype/scripts/build_sandbox_settings.py +0 -249
- package/.agents/skills/prototype/scripts/conftest.py +0 -15
- package/.agents/skills/prototype/scripts/launch_sandbox.py +0 -205
- package/.agents/skills/prototype/scripts/probe_sandbox_safety.py +0 -311
- package/.agents/skills/prototype/scripts/prototype_scripts_constants/__init__.py +0 -1
- package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/__init__.py +0 -0
- package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/build_sandbox_settings_constants.py +0 -41
- package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/launch_sandbox_constants.py +0 -23
- package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/probe_sandbox_safety_constants.py +0 -45
- package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/prototype_common_constants.py +0 -10
- package/.agents/skills/prototype/scripts/test_build_sandbox_settings.py +0 -275
- package/.agents/skills/prototype/scripts/test_launch_sandbox.py +0 -303
- package/.agents/skills/prototype/scripts/test_probe_sandbox_safety.py +0 -312
- package/.agents/skills/prototype/workflows/promotion.md +0 -25
- package/.agents/skills/prototype/workflows/sandbox.md +0 -35
- package/.agents/skills/rebase/.claude/CLAUDE.md +0 -1
- package/.agents/skills/rebase/AGENTS.md +0 -1
- package/.agents/skills/rebase/SKILL.md +0 -178
- package/.agents/skills/review-router/SKILL.md +0 -51
- package/.agents/skills/review-router/reference/route-policy.json +0 -7
- package/.agents/skills/review-router/reference/task-seeds.md +0 -1
- package/.agents/skills/review-router/scripts/conftest.py +0 -4
- package/.agents/skills/review-router/scripts/review_router.py +0 -50
- package/.agents/skills/review-router/scripts/review_router_cli.py +0 -211
- package/.agents/skills/review-router/scripts/review_router_constants/__init__.py +0 -1
- package/.agents/skills/review-router/scripts/review_router_constants/config/__init__.py +0 -0
- package/.agents/skills/review-router/scripts/review_router_constants/config/constants.py +0 -13
- package/.agents/skills/review-router/scripts/test_review_router.py +0 -23
- package/.agents/skills/review-router/scripts/test_review_router_cli.py +0 -47
- package/.agents/skills/review-tier/SKILL.md +0 -56
- package/.agents/skills/review-tier/reference/task-seeds.md +0 -1
- package/.agents/skills/review-tier/reference/tier-policy.json +0 -9
- package/.agents/skills/review-tier/scripts/conftest.py +0 -4
- package/.agents/skills/review-tier/scripts/review_tier.py +0 -359
- package/.agents/skills/review-tier/scripts/review_tier_constants/__init__.py +0 -1
- package/.agents/skills/review-tier/scripts/review_tier_constants/config/__init__.py +0 -0
- package/.agents/skills/review-tier/scripts/review_tier_constants/config/constants.py +0 -29
- package/.agents/skills/review-tier/scripts/test_generation.py +0 -159
- package/.agents/skills/review-tier/scripts/test_review_tier.py +0 -33
- package/.agents/skills/run-claude-dev-env/SKILL.md +0 -84
- package/.agents/skills/session-log/.claude/CLAUDE.md +0 -1
- package/.agents/skills/session-log/AGENTS.md +0 -1
- package/.agents/skills/session-log/SKILL.md +0 -170
- package/.agents/skills/session-log/templates/frontmatter.md +0 -40
- package/.agents/skills/session-tidy/.claude/CLAUDE.md +0 -1
- package/.agents/skills/session-tidy/AGENTS.md +0 -1
- package/.agents/skills/session-tidy/SKILL.md +0 -191
- package/.agents/skills/skill-builder/references/.claude/CLAUDE.md +0 -1
- package/.agents/skills/skill-builder/references/AGENTS.md +0 -1
- package/.agents/skills/skill-builder/references/delegation-map.md +0 -130
- package/.agents/skills/skill-builder/references/description-field.md +0 -111
- package/.agents/skills/skill-builder/references/deterministic-elements.md +0 -218
- package/.agents/skills/skill-builder/references/progressive-disclosure.md +0 -122
- package/.agents/skills/skill-builder/references/self-audit-checklist.md +0 -126
- package/.agents/skills/skill-builder/references/skill-modularity.md +0 -111
- package/.agents/skills/skill-builder/references/skill-types.md +0 -232
- package/.agents/skills/skill-builder/references/thariq-x-post-skills.json +0 -33
- package/.agents/skills/skill-builder/templates/.claude/CLAUDE.md +0 -1
- package/.agents/skills/skill-builder/templates/AGENTS.md +0 -1
- package/.agents/skills/skill-builder/templates/gap-analysis.md +0 -87
- package/.agents/skills/skill-builder/workflows/.claude/CLAUDE.md +0 -1
- package/.agents/skills/skill-builder/workflows/AGENTS.md +0 -1
- package/.agents/skills/skill-builder/workflows/improve-skill.md +0 -136
- package/.agents/skills/skill-builder/workflows/new-skill.md +0 -179
- package/.agents/skills/skill-builder/workflows/polish-skill.md +0 -139
- package/.agents/skills/source-command-sr-loop/SKILL.md +0 -82
- package/.agents/skills/update/.claude/CLAUDE.md +0 -1
- package/.agents/skills/update/AGENTS.md +0 -1
- package/.agents/skills/update/SKILL.md +0 -190
- package/_shared/pr-loop/AGENTS.md +0 -1
- package/_shared/pr-loop/CLAUDE.md +0 -1
- package/_shared/pr-loop/audit-contract.md +0 -183
- package/_shared/pr-loop/audit-reply-template.md +0 -151
- package/_shared/pr-loop/code-rules-gate.md +0 -65
- package/_shared/pr-loop/fix-protocol.md +0 -60
- package/_shared/pr-loop/gh-payloads.md +0 -75
- package/_shared/pr-loop/post-audit-thread-contract.md +0 -51
- package/_shared/pr-loop/precatch-rubric.md +0 -66
- package/_shared/pr-loop/preflight-proposal.md +0 -56
- package/_shared/pr-loop/scripts/post_audit_thread.py +0 -1242
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/post_audit_thread_constants.py +0 -199
- package/_shared/pr-loop/scripts/tests/test_post_audit_thread.py +0 -1115
- package/_shared/pr-loop/scripts/tests/test_post_audit_thread_constants.py +0 -129
- package/_shared/pr-loop/state-schema.md +0 -45
- package/_shared/pr-loop/worker-spawn.md +0 -189
- package/hooks/_gh_pr_author_swap_utils.py +0 -1225
- package/hooks/blocking/conventional_pr_title_gate.py +0 -443
- package/hooks/blocking/gh_body_arg_blocker.py +0 -176
- package/hooks/blocking/gh_pr_author_enforcer.py +0 -487
- package/hooks/blocking/gh_pr_author_restore.py +0 -105
- package/hooks/blocking/pr_description_writer_gate.py +0 -256
- package/hooks/blocking/test_conventional_pr_title_gate.py +0 -640
- package/hooks/blocking/test_gh_body_arg_blocker.py +0 -441
- package/hooks/blocking/test_gh_pr_author_enforcer.py +0 -1166
- package/hooks/blocking/test_gh_pr_author_restore.py +0 -513
- package/hooks/blocking/test_gh_pr_author_swap_utils.py +0 -910
- package/hooks/blocking/test_pr_description_writer_gate.py +0 -234
- package/hooks/blocking/test_preflight_check.py +0 -343
- package/hooks/blocking/test_test_preflight_check.py +0 -80
- package/hooks/blocking/test_volatile_path_in_post_blocker.py +0 -322
- package/hooks/blocking/volatile_path_in_post_blocker.py +0 -461
- package/hooks/hooks_constants/conventional_pr_title_gate_constants.py +0 -58
- package/hooks/hooks_constants/gh_pr_author_swap_constants.py +0 -76
- package/hooks/hooks_constants/pr_description_writer_gate_constants.py +0 -73
- package/hooks/hooks_constants/volatile_path_in_post_blocker_constants.py +0 -55
- package/hooks/observability/pr_description_writer_spawn_tracker.py +0 -113
- package/hooks/observability/test_pr_description_writer_spawn_tracker.py +0 -150
- package/hooks/session/gh_pr_author_session_cleanup.py +0 -175
- package/hooks/session/test_gh_pr_author_session_cleanup.py +0 -576
- package/hooks/test__gh_pr_author_swap_utils.py +0 -333
|
@@ -1,322 +0,0 @@
|
|
|
1
|
-
"""Unit and integration tests for the volatile_path_in_post_blocker PreToolUse hook."""
|
|
2
|
-
|
|
3
|
-
import importlib.util
|
|
4
|
-
import json
|
|
5
|
-
import pathlib
|
|
6
|
-
import subprocess
|
|
7
|
-
import sys
|
|
8
|
-
|
|
9
|
-
_HOOK_DIR = pathlib.Path(__file__).parent
|
|
10
|
-
if str(_HOOK_DIR) not in sys.path:
|
|
11
|
-
sys.path.insert(0, str(_HOOK_DIR))
|
|
12
|
-
|
|
13
|
-
hook_spec = importlib.util.spec_from_file_location(
|
|
14
|
-
"volatile_path_in_post_blocker",
|
|
15
|
-
_HOOK_DIR / "volatile_path_in_post_blocker.py",
|
|
16
|
-
)
|
|
17
|
-
assert hook_spec is not None
|
|
18
|
-
assert hook_spec.loader is not None
|
|
19
|
-
hook_module = importlib.util.module_from_spec(hook_spec)
|
|
20
|
-
hook_spec.loader.exec_module(hook_module)
|
|
21
|
-
|
|
22
|
-
scan_text_for_volatile_marker = hook_module.scan_text_for_volatile_marker
|
|
23
|
-
extract_gh_post_body_texts = hook_module.extract_gh_post_body_texts
|
|
24
|
-
extract_mcp_body_texts = hook_module.extract_mcp_body_texts
|
|
25
|
-
_collect_body_texts = hook_module._collect_body_texts
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def _body_names_volatile_path(tool_name: str, tool_input: dict[str, object]) -> bool:
|
|
29
|
-
all_body_texts = _collect_body_texts(tool_name, tool_input)
|
|
30
|
-
return hook_module._first_volatile_marker(all_body_texts) is not None
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
def test_scan_detects_job_scratch_path_backslash() -> None:
|
|
34
|
-
text = r"See C:\Users\example\.claude-profile-a\jobs\95762cea\tmp\staging\contact_sheet.png"
|
|
35
|
-
assert scan_text_for_volatile_marker(text) == ".claude-profile-a/jobs/"
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def test_scan_detects_job_scratch_path_forward_slash() -> None:
|
|
39
|
-
text = "artifact at /home/user/.claude-profile-a/jobs/abc/tmp/out.png"
|
|
40
|
-
assert scan_text_for_volatile_marker(text) == ".claude-profile-a/jobs/"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
def test_scan_detects_worktree_path() -> None:
|
|
44
|
-
text = r"edited C:\Users\me\.claude\worktrees\feature\file.py"
|
|
45
|
-
assert scan_text_for_volatile_marker(text) == ".claude/worktrees/"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def test_scan_detects_appdata_temp_case_insensitive() -> None:
|
|
49
|
-
text = r"C:\Users\example\AppData\Local\Temp\bugteam\worktree"
|
|
50
|
-
assert scan_text_for_volatile_marker(text) == "appdata/local/temp"
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
def test_scan_detects_unix_tmp() -> None:
|
|
54
|
-
assert scan_text_for_volatile_marker("output written to /tmp/run/out.log") == "/tmp/"
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
def test_scan_detects_percent_temp_token() -> None:
|
|
58
|
-
assert scan_text_for_volatile_marker("saved to %TEMP%\\out.txt") == "%temp%"
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
def test_scan_detects_env_temp_token() -> None:
|
|
62
|
-
assert scan_text_for_volatile_marker("path is $env:TEMP\\out.txt") == "$env:temp"
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
def test_scan_detects_claude_job_dir_token() -> None:
|
|
66
|
-
assert scan_text_for_volatile_marker("see $CLAUDE_JOB_DIR/staging/report.md") == "$claude_job_dir"
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
def test_scan_clean_body_returns_none() -> None:
|
|
70
|
-
text = "The failing table is pasted below:\n| case | result |\n| a | pass |"
|
|
71
|
-
assert scan_text_for_volatile_marker(text) is None
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
def test_scan_bare_backticked_worktree_mention_is_allowed() -> None:
|
|
75
|
-
text = "the `.claude/worktrees/` prefix sits in ALL_TOOLING_STATE_PREFIXES"
|
|
76
|
-
assert scan_text_for_volatile_marker(text) is None
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
def test_scan_bare_start_of_text_worktree_mention_is_allowed() -> None:
|
|
80
|
-
text = ".claude/worktrees/ entries are skipped by the manifest"
|
|
81
|
-
assert scan_text_for_volatile_marker(text) is None
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
def test_scan_windows_absolute_worktree_path_is_detected() -> None:
|
|
85
|
-
text = r"C:\Users\me\.claude\worktrees\wt-1\notes.md"
|
|
86
|
-
assert scan_text_for_volatile_marker(text) == ".claude/worktrees/"
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
def test_scan_home_anchored_worktree_path_is_detected() -> None:
|
|
90
|
-
text = "~/.claude/worktrees/wt-2/file.py"
|
|
91
|
-
assert scan_text_for_volatile_marker(text) == ".claude/worktrees/"
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
def test_scan_posix_absolute_job_scratch_path_is_detected() -> None:
|
|
95
|
-
text = "/home/me/.claude-profile-a/jobs/j1/log.txt"
|
|
96
|
-
assert scan_text_for_volatile_marker(text) == ".claude-profile-a/jobs/"
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
def test_scan_bare_parenthesized_job_scratch_mention_is_allowed() -> None:
|
|
100
|
-
text = "(.claude-profile-a/jobs/) as a directory name in prose"
|
|
101
|
-
assert scan_text_for_volatile_marker(text) is None
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
def test_scan_bare_mention_before_anchored_path_is_detected() -> None:
|
|
105
|
-
text = (
|
|
106
|
-
".claude/worktrees/ is the manifest key; the live path is "
|
|
107
|
-
r"C:\Users\me\.claude\worktrees\wt-1\notes.md"
|
|
108
|
-
)
|
|
109
|
-
assert scan_text_for_volatile_marker(text) == ".claude/worktrees/"
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
def test_scan_unchanged_bare_markers_still_detected() -> None:
|
|
113
|
-
assert scan_text_for_volatile_marker(r"saved to %TEMP%\x") == "%temp%"
|
|
114
|
-
assert scan_text_for_volatile_marker("log at /tmp/x") == "/tmp/"
|
|
115
|
-
assert (
|
|
116
|
-
scan_text_for_volatile_marker(r"C:\Users\x\AppData\Local\Temp\y")
|
|
117
|
-
== "appdata/local/temp"
|
|
118
|
-
)
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
def test_scan_space_prefixed_relative_worktree_path_is_detected() -> None:
|
|
122
|
-
text = "see .claude/worktrees/wt-1/notes.md"
|
|
123
|
-
assert scan_text_for_volatile_marker(text) == ".claude/worktrees/"
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
def test_scan_cd_relative_worktree_path_is_detected() -> None:
|
|
127
|
-
text = "cd .claude/worktrees/wt-199 && pytest"
|
|
128
|
-
assert scan_text_for_volatile_marker(text) == ".claude/worktrees/"
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
def test_scan_start_of_text_relative_worktree_path_is_detected() -> None:
|
|
132
|
-
text = ".claude/worktrees/wt-1/notes.md"
|
|
133
|
-
assert scan_text_for_volatile_marker(text) == ".claude/worktrees/"
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
def test_scan_markdown_link_relative_worktree_target_is_detected() -> None:
|
|
137
|
-
text = "[notes](.claude/worktrees/wt-1/notes.md)"
|
|
138
|
-
assert scan_text_for_volatile_marker(text) == ".claude/worktrees/"
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
def test_scan_space_prefixed_relative_job_scratch_path_is_detected() -> None:
|
|
142
|
-
text = "see .claude-profile-a/jobs/j1/log.txt"
|
|
143
|
-
assert scan_text_for_volatile_marker(text) == ".claude-profile-a/jobs/"
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
def test_scan_backslash_relative_worktree_path_is_detected() -> None:
|
|
147
|
-
text = r"see .claude\worktrees\wt-1\notes.md"
|
|
148
|
-
assert scan_text_for_volatile_marker(text) == ".claude/worktrees/"
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
def test_scan_prose_child_token_after_marker_is_detected() -> None:
|
|
152
|
-
text = "the .claude/worktrees/wt-name pattern"
|
|
153
|
-
assert scan_text_for_volatile_marker(text) == ".claude/worktrees/"
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
def test_scan_relative_worktree_path_with_hyphen_child_is_detected() -> None:
|
|
157
|
-
text = "see .claude/worktrees/-scratch/notes.md"
|
|
158
|
-
assert scan_text_for_volatile_marker(text) == ".claude/worktrees/"
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
def test_scan_placeholder_child_segment_is_allowed() -> None:
|
|
162
|
-
text = "worktrees live under `.claude/worktrees/<name>`"
|
|
163
|
-
assert scan_text_for_volatile_marker(text) is None
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
def test_scan_sentence_final_marker_period_is_allowed() -> None:
|
|
167
|
-
text = "the constant is `.claude/worktrees/`. Next."
|
|
168
|
-
assert scan_text_for_volatile_marker(text) is None
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
def test_gh_comment_with_job_scratch_path_is_blocked() -> None:
|
|
172
|
-
command = (
|
|
173
|
-
'gh pr comment 669 --body "Contact sheet at '
|
|
174
|
-
r'C:\Users\example\.claude-profile-a\jobs\95762cea\tmp\staging\contact_sheet.png"'
|
|
175
|
-
)
|
|
176
|
-
assert _body_names_volatile_path("Bash", {"command": command})
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
def test_gh_comment_with_clean_body_is_allowed() -> None:
|
|
180
|
-
command = 'gh pr comment 669 --body "All checks pass. Table pasted inline above."'
|
|
181
|
-
assert not _body_names_volatile_path("Bash", {"command": command})
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
def test_gh_pr_create_short_flag_blocked() -> None:
|
|
185
|
-
command = 'gh pr create --title "T" -b "logs under /tmp/run/out.log"'
|
|
186
|
-
assert _body_names_volatile_path("Bash", {"command": command})
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
def test_gh_issue_create_body_equals_form_blocked() -> None:
|
|
190
|
-
command = 'gh issue create --title "T" --body="dump in %TEMP%\\dump.json"'
|
|
191
|
-
assert _body_names_volatile_path("Bash", {"command": command})
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
def test_body_file_content_is_scanned_and_blocked(tmp_path: pathlib.Path) -> None:
|
|
195
|
-
body_file = tmp_path / "body.md"
|
|
196
|
-
body_file.write_text(
|
|
197
|
-
"Artifact: $CLAUDE_JOB_DIR/tmp/contact_sheet.png",
|
|
198
|
-
encoding="utf-8",
|
|
199
|
-
)
|
|
200
|
-
command = f"gh pr comment 669 --body-file {body_file}"
|
|
201
|
-
assert _body_names_volatile_path("Bash", {"command": command})
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
def test_body_file_clean_content_is_allowed(tmp_path: pathlib.Path) -> None:
|
|
205
|
-
body_file = tmp_path / "body.md"
|
|
206
|
-
body_file.write_text("Everything is green. Results inline above.", encoding="utf-8")
|
|
207
|
-
command = f"gh pr comment 669 --body-file {body_file}"
|
|
208
|
-
assert not _body_names_volatile_path("Bash", {"command": command})
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
def test_non_post_gh_command_is_untouched() -> None:
|
|
212
|
-
assert not _body_names_volatile_path("Bash", {"command": "gh pr list --repo owner/repo"})
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
def test_gh_pr_view_with_tmp_in_flag_is_untouched() -> None:
|
|
216
|
-
command = "gh pr view 10 --json body --jq .body > /tmp/out.json"
|
|
217
|
-
assert not _body_names_volatile_path("Bash", {"command": command})
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
def test_substring_mention_of_gh_post_does_not_classify() -> None:
|
|
221
|
-
command = 'echo "example: gh pr comment 42 --body \\"see /tmp/x\\"" >> notes.txt'
|
|
222
|
-
assert not _body_names_volatile_path("Bash", {"command": command})
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
def test_gh_word_not_first_token_does_not_classify() -> None:
|
|
226
|
-
command = r'echo gh pr comment 42 --body "see C:\.claude-profile-a\jobs\x"'
|
|
227
|
-
assert not _body_names_volatile_path("Bash", {"command": command})
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
def test_env_assignment_prefix_still_classifies() -> None:
|
|
231
|
-
command = 'GH_TOKEN=abc gh pr comment 669 --body "log at /tmp/run.log"'
|
|
232
|
-
assert _body_names_volatile_path("Bash", {"command": command})
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
def test_unparseable_command_is_allowed() -> None:
|
|
236
|
-
assert not _body_names_volatile_path(
|
|
237
|
-
"Bash", {"command": "gh pr comment 1 --body 'unterminated"}
|
|
238
|
-
)
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
def test_mcp_issue_comment_body_blocked() -> None:
|
|
242
|
-
tool_input: dict[str, object] = {"body": "artifact at $CLAUDE_JOB_DIR/tmp/out.png"}
|
|
243
|
-
assert _body_names_volatile_path("mcp__plugin_github_github__add_issue_comment", tool_input)
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
def test_mcp_review_comment_param_blocked() -> None:
|
|
247
|
-
tool_input: dict[str, object] = {"comment": r"see C:\Users\me\.claude\worktrees\x\file"}
|
|
248
|
-
assert _body_names_volatile_path(
|
|
249
|
-
"mcp__plugin_github_github__add_reply_to_pull_request_comment", tool_input
|
|
250
|
-
)
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
def test_mcp_clean_body_allowed() -> None:
|
|
254
|
-
tool_input: dict[str, object] = {"body": "LGTM, results pasted inline."}
|
|
255
|
-
assert not _body_names_volatile_path("mcp__plugin_github_github__add_issue_comment", tool_input)
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
def test_mcp_read_tool_without_body_allowed() -> None:
|
|
259
|
-
tool_input: dict[str, object] = {"pullNumber": 10}
|
|
260
|
-
assert not _body_names_volatile_path("mcp__plugin_github_github__pull_request_read", tool_input)
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
def test_extract_mcp_body_texts_skips_non_string_values() -> None:
|
|
264
|
-
tool_input: dict[str, object] = {"body": None, "comment": 42}
|
|
265
|
-
assert extract_mcp_body_texts(tool_input) == []
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
def test_extract_gh_post_body_texts_returns_inline_and_file(tmp_path: pathlib.Path) -> None:
|
|
269
|
-
body_file = tmp_path / "b.md"
|
|
270
|
-
body_file.write_text("file body text", encoding="utf-8")
|
|
271
|
-
command = f'gh pr create --title "T" --body "inline body" --body-file {body_file}'
|
|
272
|
-
all_texts = extract_gh_post_body_texts(command)
|
|
273
|
-
assert "inline body" in all_texts
|
|
274
|
-
assert "file body text" in all_texts
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
def test_gh_issue_edit_quoting_bare_constant_is_allowed(tmp_path: pathlib.Path) -> None:
|
|
278
|
-
body_file = tmp_path / "issue_body.md"
|
|
279
|
-
body_file.write_text(
|
|
280
|
-
"The manifest skips these tooling-state prefixes:\n"
|
|
281
|
-
' ".claude/worktrees/",\n'
|
|
282
|
-
' ".claude-profile-a/jobs/",\n'
|
|
283
|
-
"Neither is a machine-local path.",
|
|
284
|
-
encoding="utf-8",
|
|
285
|
-
)
|
|
286
|
-
command = f"gh issue edit 134 --body-file {body_file}"
|
|
287
|
-
all_body_texts = extract_gh_post_body_texts(command)
|
|
288
|
-
assert all_body_texts
|
|
289
|
-
assert hook_module._first_volatile_marker(all_body_texts) is None
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
def test_hook_subprocess_denies_volatile_gh_comment() -> None:
|
|
293
|
-
payload = {
|
|
294
|
-
"tool_name": "Bash",
|
|
295
|
-
"tool_input": {
|
|
296
|
-
"command": 'gh pr comment 669 --body "art at $CLAUDE_JOB_DIR/tmp/x.png"',
|
|
297
|
-
},
|
|
298
|
-
}
|
|
299
|
-
completion = subprocess.run(
|
|
300
|
-
[sys.executable, str(_HOOK_DIR / "volatile_path_in_post_blocker.py")],
|
|
301
|
-
input=json.dumps(payload),
|
|
302
|
-
capture_output=True,
|
|
303
|
-
text=True,
|
|
304
|
-
check=False,
|
|
305
|
-
)
|
|
306
|
-
decision = json.loads(completion.stdout)
|
|
307
|
-
assert decision["hookSpecificOutput"]["permissionDecision"] == "deny"
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
def test_hook_subprocess_allows_clean_gh_comment() -> None:
|
|
311
|
-
payload = {
|
|
312
|
-
"tool_name": "Bash",
|
|
313
|
-
"tool_input": {"command": 'gh pr comment 669 --body "all green, results inline"'},
|
|
314
|
-
}
|
|
315
|
-
completion = subprocess.run(
|
|
316
|
-
[sys.executable, str(_HOOK_DIR / "volatile_path_in_post_blocker.py")],
|
|
317
|
-
input=json.dumps(payload),
|
|
318
|
-
capture_output=True,
|
|
319
|
-
text=True,
|
|
320
|
-
check=False,
|
|
321
|
-
)
|
|
322
|
-
assert completion.stdout.strip() == ""
|