claude-dev-env 4.3.0 → 7.1.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 +5 -4
- package/.agents/skills/pull-request/SKILL.md +11 -13
- package/.agents/skills/pull-request/reference/publication-tasks.md +3 -3
- package/.agents/skills/pull-request/scripts/github_pr_command_constants/config/constants.py +9 -1
- package/.agents/skills/pull-request/scripts/pull_request.py +35 -44
- package/.agents/skills/pull-request/scripts/test_github_pr_command_constants.py +9 -0
- package/.agents/skills/pull-request/scripts/test_pull_request.py +35 -3
- package/.agents/skills/session-continuity/README.md +189 -0
- package/.agents/skills/session-continuity/SKILL.md +114 -0
- package/.agents/skills/session-continuity/continuity.mjs +375 -0
- package/.agents/skills/session-continuity/continuity.test.mjs +303 -0
- package/.agents/skills/skill-builder/SKILL.md +3 -196
- package/.agents/skills/syncing-submodules/scripts/test_sync_parent_pointer.py +0 -7
- package/.agents/skills/windows-scheduled-task/SKILL.md +153 -0
- 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/cde.mjs +36 -8
- package/bin/cde.test.mjs +48 -0
- package/bin/ever-shipped-skills.mjs +2 -20
- package/bin/ever-shipped-skills.test.mjs +8 -0
- package/bin/expand_home_directory_tokens.mjs +4 -5
- package/bin/expand_home_directory_tokens.test.mjs +128 -0
- package/bin/git_hooks_installer.mjs +22 -3
- package/bin/git_hooks_installer.test.mjs +159 -5
- package/bin/install-session-continuity.mjs +78 -0
- package/bin/install-session-continuity.test.mjs +42 -0
- package/bin/install.agents-home.test.mjs +15 -13
- package/bin/install.codex-rules.test.mjs +5 -2
- package/bin/install.cursor-rules.test.mjs +5 -2
- package/bin/install.mjs +506 -63
- package/bin/install.policy-lint.test.mjs +130 -0
- package/bin/install.profiles.test.mjs +10 -0
- package/bin/install.prune.test.mjs +286 -37
- package/bin/install.pstack-plugin.test.mjs +114 -0
- package/bin/install.test.mjs +537 -120
- package/bin/install.transaction.test.mjs +3 -3
- package/bin/refresh-pstack-plugin-skills.test.mjs +211 -0
- package/docs/CODE_RULES.md +1 -1
- 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_banned_identifiers.py +3 -0
- package/hooks/blocking/code_rules_paired_test.py +22 -15
- package/hooks/blocking/precommit_code_rules_gate.py +5 -8
- package/hooks/blocking/test_bash_dispatcher_interpreter_starts.py +7 -52
- package/hooks/blocking/test_bash_post_call_dispatcher.py +65 -4
- package/hooks/blocking/test_bash_pre_tool_use_dispatcher.py +0 -69
- package/hooks/blocking/test_code_rules_banned_identifiers.py +64 -0
- 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_pre_tool_use_dispatcher.py +43 -342
- package/hooks/blocking/test_pre_tool_use_dispatcher_native.py +20 -51
- package/hooks/blocking/test_shared_stdin_adoption.py +1 -47
- package/hooks/git-hooks/git_hooks_constants/staged_policy_lint.py +12 -0
- package/hooks/git-hooks/git_hooks_constants/verification_notice_constants.py +116 -0
- package/hooks/git-hooks/post_commit.py +33 -0
- package/hooks/git-hooks/pre_commit.py +18 -49
- package/hooks/git-hooks/pre_push.py +45 -541
- package/hooks/git-hooks/test_installed_policy_lint.py +208 -0
- package/hooks/git-hooks/test_native_hook_support.py +129 -0
- package/hooks/git-hooks/test_native_policy_commit.py +120 -0
- package/hooks/git-hooks/test_post_commit.py +43 -0
- package/hooks/git-hooks/test_pre_commit.py +38 -148
- package/hooks/git-hooks/test_pre_push.py +48 -1631
- package/hooks/git-hooks/test_verification_notice.py +60 -0
- package/hooks/git-hooks/test_verification_start.py +173 -0
- package/hooks/git-hooks/verification_notice.py +192 -0
- package/hooks/git-hooks/verification_notice_context.py +253 -0
- package/hooks/git-hooks/verification_notice_state.py +237 -0
- package/hooks/git-hooks/verification_start.py +100 -0
- package/hooks/hooks.json +1 -120
- package/hooks/hooks_constants/banned_identifiers_constants.py +4 -0
- package/hooks/hooks_constants/bash_post_call_dispatcher_constants.py +14 -1
- package/hooks/hooks_constants/bash_pre_tool_use_dispatcher_constants.py +1 -15
- package/hooks/hooks_constants/post_tool_use_dispatcher_constants.py +0 -4
- package/hooks/hooks_constants/pr_done_reminder_constants.py +98 -0
- package/hooks/hooks_constants/pre_tool_use_dispatcher_constants.py +10 -93
- package/hooks/hooks_constants/stop_dispatcher_constants.py +1 -4
- package/hooks/hooks_constants/test_bash_post_call_dispatcher_constants.py +19 -2
- package/hooks/hooks_constants/test_bash_pre_tool_use_dispatcher_constants.py +3 -66
- package/hooks/hooks_constants/test_pr_done_reminder_constants.py +40 -0
- package/hooks/hooks_constants/test_pre_tool_use_dispatcher_constants.py +46 -201
- package/hooks/hooks_constants/test_stop_dispatcher_constants.py +3 -25
- package/hooks/validation/test_post_tool_use_dispatcher.py +35 -298
- package/hooks/validators/run_all_validators.py +5 -1
- package/hooks/validators/security_checks.py +57 -2
- package/hooks/validators/test_hook_timing_harness.py +2 -5
- package/hooks/validators/test_run_all_validators_mutation_tool_parity.py +3 -11
- package/hooks/validators/test_run_all_validators_policy_lint.py +36 -0
- package/hooks/validators/test_security_checks.py +57 -0
- package/package.json +2 -2
- package/rules/confirm-implementation-forks.md +2 -0
- package/rules/durable-post-artifacts.md +2 -1
- package/rules/git-workflow.md +18 -6
- package/rules/pstack-host-mapping.md +48 -0
- package/rules/vault-context.md +3 -5
- package/rules/verify-runtime-state.md +7 -0
- package/scripts/audit-hooks-cli.mjs +5 -0
- package/scripts/audit-hooks.mjs +72 -16
- package/scripts/automatic_advisory/__init__.py +1 -0
- package/scripts/automatic_advisory/checkout.py +51 -0
- package/scripts/automatic_advisory/cli.py +334 -0
- package/scripts/automatic_advisory/config/__init__.py +1 -0
- package/scripts/automatic_advisory/config/constants.py +93 -0
- package/scripts/automatic_advisory/config/timing.py +4 -0
- package/scripts/automatic_advisory/configuration.py +197 -0
- package/scripts/automatic_advisory/execution.py +350 -0
- package/scripts/automatic_advisory/git.py +69 -0
- package/scripts/automatic_advisory/model.py +107 -0
- package/scripts/automatic_advisory/process_host.py +32 -0
- package/scripts/automatic_advisory/publisher.py +84 -0
- package/scripts/automatic_advisory/runner.py +399 -0
- package/scripts/automatic_advisory/state.py +116 -0
- package/scripts/automatic_advisory/window_flags.py +41 -0
- package/scripts/automatic_advisory/windows_job.py +122 -0
- 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/codex_compat_materializer.py +99 -13
- package/scripts/dev_env_scripts_constants/shared_tree_constants.py +4 -5
- package/{.agents/skills/_shared/pr-loop/scripts → scripts}/durable_post_lint.py +35 -43
- package/{.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/durable_post_lint_constants.py → scripts/durable_post_lint_config/config/constants.py} +10 -10
- package/{.agents/skills/_shared/pr-loop/scripts/test_durable_post_lint_constants.py → scripts/durable_post_lint_config/config/test_constants.py} +14 -1
- package/scripts/local_report_cli.py +184 -0
- package/scripts/local_report_core.py +247 -0
- package/scripts/local_report_publisher.py +12 -0
- package/scripts/local_report_validation.py +357 -0
- package/scripts/local_verification/__init__.py +23 -0
- package/scripts/local_verification/check_runner.py +364 -0
- package/scripts/local_verification/check_support.py +99 -0
- package/scripts/local_verification/cli.py +158 -0
- package/scripts/local_verification/command_runner.py +84 -0
- package/scripts/local_verification/config/__init__.py +1 -0
- package/scripts/local_verification/config/constants.py +89 -0
- package/scripts/local_verification/config/timing.py +1 -0
- package/scripts/local_verification/git_state.py +146 -0
- package/scripts/local_verification/manifest.py +224 -0
- package/scripts/local_verification/model.py +174 -0
- package/scripts/local_verification/runner.py +234 -0
- package/scripts/policy_lint/adapter_detectors.py +13 -6
- package/scripts/policy_lint/adapter_pairing.py +58 -3
- package/scripts/policy_lint/adapters.py +7 -4
- package/scripts/policy_lint/config/approved_test_pairs.py +323 -0
- 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/pr_verification/__init__.py +1 -0
- package/scripts/pr_verification/branch_refs.py +114 -0
- package/scripts/pr_verification/config/__init__.py +1 -0
- package/scripts/pr_verification/config/constants.py +84 -0
- package/scripts/pr_verification/config/timing.py +5 -0
- package/scripts/pr_verification/github.py +137 -0
- package/scripts/pr_verification/github_api.py +376 -0
- package/scripts/pr_verification/github_labels.py +88 -0
- package/scripts/pr_verification/github_parsing.py +182 -0
- package/scripts/pr_verification/github_transport.py +91 -0
- package/scripts/pr_verification/lock.py +122 -0
- package/scripts/pr_verification/model.py +43 -0
- package/scripts/pr_verification/requirements.txt +1 -0
- package/scripts/refresh_pstack_plugin_skills.mjs +200 -0
- package/scripts/shared_tree_paths.py +32 -3
- package/{.agents/skills/_shared/pr-loop/scripts → scripts}/test_durable_post_lint.py +97 -0
- package/scripts/test_shared_tree_paths.py +33 -0
- package/scripts/tests/test-audit-hooks-cli.mjs +150 -0
- package/scripts/tests/test-audit-hooks.mjs +94 -2
- package/scripts/tests/test_automatic_advisory.py +376 -0
- package/scripts/tests/test_automatic_advisory_job_cleanup.py +71 -0
- package/scripts/tests/test_automatic_advisory_polling.py +216 -0
- package/scripts/tests/test_automatic_advisory_recovery.py +320 -0
- package/scripts/tests/test_automatic_advisory_repairs.py +400 -0
- package/scripts/tests/test_automatic_advisory_settings.py +48 -0
- package/scripts/tests/test_automatic_advisory_window_flags.py +163 -0
- package/scripts/tests/test_closed_pr_label.py +157 -0
- package/scripts/tests/test_codex_compat_materializer.py +189 -6
- package/scripts/tests/test_github_labels.py +101 -0
- package/scripts/tests/test_github_transport.py +125 -0
- package/scripts/tests/test_local_report_publisher.py +396 -0
- package/scripts/tests/test_local_report_publisher_cli.py +85 -0
- package/scripts/tests/test_local_verification.py +348 -0
- package/scripts/tests/test_local_verification_cli.py +98 -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_pairing.py +163 -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_pr_verification_github.py +392 -0
- package/scripts/tests/test_pr_verification_lock.py +168 -0
- package/scripts/tests/test_rules.py +3 -7
- package/scripts/tests/test_verification_notice.py +347 -0
- package/.agents/skills/_shared/pr-loop/.claude/CLAUDE.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/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/blocking/ask_user_question_shape_blocker.py +0 -83
- package/hooks/blocking/bot_mention_comment_blocker.py +0 -76
- package/hooks/blocking/claude_md_orphan_file_blocker.py +0 -129
- package/hooks/blocking/cursor_cli_python_misfire_blocker.py +0 -108
- package/hooks/blocking/destructive_command_blocker.py +0 -2073
- package/hooks/blocking/fable_spawn_gate.py +0 -187
- package/hooks/blocking/luna_fast_mode_gate.py +0 -160
- package/hooks/blocking/nas_ssh_binary_enforcer.py +0 -163
- package/hooks/blocking/orchestrator_refresh_reschedule_gate.py +0 -260
- package/hooks/blocking/package_inventory_stale_blocker.py +0 -107
- package/hooks/blocking/pii_prevention_blocker.py +0 -365
- package/hooks/blocking/piped_pytest_blocker.py +0 -1223
- package/hooks/blocking/question_to_user_enforcer.py +0 -130
- package/hooks/blocking/send_user_file_open_locally_blocker.py +0 -71
- package/hooks/blocking/sensitive_file_protector.py +0 -167
- package/hooks/blocking/session_edit_stage_gate.py +0 -684
- package/hooks/blocking/session_handoff_blocker.py +0 -182
- package/hooks/blocking/shell_substitution_blocker.py +0 -350
- package/hooks/blocking/test_ask_user_question_shape.py +0 -69
- package/hooks/blocking/test_bot_mention_comment_blocker.py +0 -131
- package/hooks/blocking/test_claude_md_orphan_file_blocker.py +0 -1277
- package/hooks/blocking/test_cursor_cli_python_misfire_blocker.py +0 -208
- package/hooks/blocking/test_destructive_command_blocker.py +0 -2024
- package/hooks/blocking/test_destructive_command_blocker_deny_mode.py +0 -105
- package/hooks/blocking/test_destructive_command_blocker_no_verify.py +0 -122
- package/hooks/blocking/test_destructive_command_blocker_patterns.py +0 -133
- package/hooks/blocking/test_fable_spawn_gate.py +0 -381
- package/hooks/blocking/test_inventory_deadlock_resolution.py +0 -154
- package/hooks/blocking/test_luna_fast_mode_gate.py +0 -211
- package/hooks/blocking/test_nas_ssh_binary_enforcer.py +0 -225
- package/hooks/blocking/test_orchestrator_refresh_reschedule_gate.py +0 -231
- package/hooks/blocking/test_package_inventory_stale_blocker.py +0 -382
- package/hooks/blocking/test_pii_prevention_blocker.py +0 -1222
- package/hooks/blocking/test_pii_prevention_windows_git_path.py +0 -41
- package/hooks/blocking/test_pii_write_surface_ephemeral.py +0 -221
- package/hooks/blocking/test_piped_pytest_blocker.py +0 -587
- package/hooks/blocking/test_precommit_code_rules_gate_native_owner.py +0 -233
- package/hooks/blocking/test_question_to_user_enforcer.py +0 -169
- package/hooks/blocking/test_send_user_file_open_locally_blocker.py +0 -118
- package/hooks/blocking/test_sensitive_file_protector.py +0 -365
- package/hooks/blocking/test_session_edit_stage_gate.py +0 -537
- package/hooks/blocking/test_session_edit_stage_gate_staging.py +0 -64
- package/hooks/blocking/test_session_edit_stage_gate_support.py +0 -204
- package/hooks/blocking/test_session_edit_stage_gate_tracker.py +0 -116
- package/hooks/blocking/test_session_handoff_blocker.py +0 -318
- package/hooks/blocking/test_shell_substitution_blocker.py +0 -298
- package/hooks/blocking/test_unscoped_search_blocker.py +0 -102
- package/hooks/blocking/test_write_existing_file_blocker.py +0 -122
- package/hooks/blocking/tests/test_pii_prevention_blocker.py +0 -259
- package/hooks/blocking/unscoped_search_blocker.py +0 -391
- package/hooks/blocking/write_existing_file_blocker.py +0 -124
- package/hooks/hooks_constants/bot_mention_comment_blocker_constants.py +0 -19
- package/hooks/hooks_constants/cursor_cli_python_misfire_blocker_constants.py +0 -79
- package/hooks/hooks_constants/fable_spawn_gate_constants.py +0 -61
- package/hooks/hooks_constants/luna_fast_mode_gate_constants.py +0 -45
- package/hooks/hooks_constants/nas_ssh_binary_enforcer_constants.py +0 -20
- package/hooks/hooks_constants/orchestrator_refresh_reschedule_gate_constants.py +0 -57
- package/hooks/hooks_constants/send_user_file_open_locally_blocker_constants.py +0 -17
- package/hooks/hooks_constants/sensitive_file_protector_constants.py +0 -40
- package/hooks/hooks_constants/session_handoff_blocker_constants.py +0 -10
- package/hooks/hooks_constants/shell_substitution_blocker_constants.py +0 -80
- /package/.agents/skills/{_shared/pr-loop → session-continuity}/AGENTS.md +0 -0
- /package/{_shared/pr-loop → .agents/skills/session-continuity}/CLAUDE.md +0 -0
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""PreToolUse hook — blocks Write and apply_patch "Add File" onto an existing target.
|
|
3
|
-
|
|
4
|
-
Agents should use Edit for modifying existing files, and an apply_patch
|
|
5
|
-
"Update File" section rather than "Add File" for a path that already exists.
|
|
6
|
-
Exemptions: Jupyter notebooks (.ipynb) and files in ~/.claude/hooks/ (standalone scripts).
|
|
7
|
-
|
|
8
|
-
MultiEdit carries no create-or-clobber path this hook needs to guard: every
|
|
9
|
-
MultiEdit edit must match an ``old_string`` already present in the target file,
|
|
10
|
-
so a MultiEdit can never introduce content nobody read the way a blind Write or
|
|
11
|
-
an apply_patch "Add File" can. This hook allows MultiEdit unconditionally.
|
|
12
|
-
"""
|
|
13
|
-
|
|
14
|
-
import json
|
|
15
|
-
import os
|
|
16
|
-
import sys
|
|
17
|
-
from pathlib import Path
|
|
18
|
-
|
|
19
|
-
_hooks_dir = str(Path(__file__).resolve().parent.parent)
|
|
20
|
-
if _hooks_dir not in sys.path:
|
|
21
|
-
sys.path.insert(0, _hooks_dir)
|
|
22
|
-
|
|
23
|
-
try:
|
|
24
|
-
from codex_apply_patch import (
|
|
25
|
-
CODEX_ADD_OPERATION,
|
|
26
|
-
CodexPatchError,
|
|
27
|
-
codex_patch_operation_targets,
|
|
28
|
-
payload_patch_command,
|
|
29
|
-
)
|
|
30
|
-
from hooks_constants.hook_block_logger import log_hook_block
|
|
31
|
-
from hooks_constants.pre_tool_use_stdin import read_hook_input_dictionary_from_stdin
|
|
32
|
-
from hooks_constants.pre_tool_use_dispatcher_constants import APPLY_PATCH_TOOL_NAME
|
|
33
|
-
from sensitive_file_protector import build_deny_response
|
|
34
|
-
except ImportError as import_error:
|
|
35
|
-
raise ImportError(
|
|
36
|
-
"write_existing_file_blocker: cannot import its sibling modules; "
|
|
37
|
-
"ensure the hooks directory is importable."
|
|
38
|
-
) from import_error
|
|
39
|
-
|
|
40
|
-
JUPYTER_EXTENSION = ".ipynb"
|
|
41
|
-
HOOKS_DIRECTORY = os.path.normpath(os.path.expanduser("~/.claude/hooks"))
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def is_jupyter_notebook(file_path: str) -> bool:
|
|
45
|
-
return file_path.lower().endswith(JUPYTER_EXTENSION)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def is_inside_hooks_directory(file_path: str) -> bool:
|
|
49
|
-
normalized_path = os.path.normpath(file_path)
|
|
50
|
-
return normalized_path.startswith(HOOKS_DIRECTORY)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
def _apply_patch_add_deny(payload: dict, tool_input: dict) -> tuple[str, str] | None:
|
|
54
|
-
"""Return (deny_reason, offending_path) for an apply_patch 'Add File' onto an existing path."""
|
|
55
|
-
command, working_directory = payload_patch_command(payload, tool_input)
|
|
56
|
-
if not command:
|
|
57
|
-
return None
|
|
58
|
-
try:
|
|
59
|
-
all_operation_targets = codex_patch_operation_targets(command, working_directory)
|
|
60
|
-
except CodexPatchError:
|
|
61
|
-
return None
|
|
62
|
-
for each_operation, each_target_path in all_operation_targets:
|
|
63
|
-
if each_operation != CODEX_ADD_OPERATION:
|
|
64
|
-
continue
|
|
65
|
-
if os.path.exists(each_target_path):
|
|
66
|
-
deny_reason = (
|
|
67
|
-
f"BLOCKED: apply_patch 'Add File' on existing file {each_target_path}. "
|
|
68
|
-
"Use an 'Update File' section instead."
|
|
69
|
-
)
|
|
70
|
-
return deny_reason, each_target_path
|
|
71
|
-
return None
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
def _write_onto_existing_file_deny(tool_input: dict) -> tuple[str, str] | None:
|
|
75
|
-
"""Return (deny_reason, offending_path) for a Write onto an existing target."""
|
|
76
|
-
target_file_path = tool_input.get("file_path", "")
|
|
77
|
-
if not target_file_path:
|
|
78
|
-
return None
|
|
79
|
-
if is_jupyter_notebook(target_file_path):
|
|
80
|
-
return None
|
|
81
|
-
if is_inside_hooks_directory(target_file_path):
|
|
82
|
-
return None
|
|
83
|
-
if not os.path.exists(target_file_path):
|
|
84
|
-
return None
|
|
85
|
-
deny_reason = f"BLOCKED: Write on existing file {target_file_path}. Use Edit tool instead."
|
|
86
|
-
return deny_reason, target_file_path
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
def _resolve_deny(tool_name: str, payload: dict, tool_input: dict) -> tuple[str, str] | None:
|
|
90
|
-
"""Return (deny_reason, offending_path) for the payload, or None to allow."""
|
|
91
|
-
if tool_name == APPLY_PATCH_TOOL_NAME:
|
|
92
|
-
return _apply_patch_add_deny(payload, tool_input)
|
|
93
|
-
if tool_name != "Write":
|
|
94
|
-
return None
|
|
95
|
-
return _write_onto_existing_file_deny(tool_input)
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
def main() -> None:
|
|
99
|
-
input_payload = read_hook_input_dictionary_from_stdin()
|
|
100
|
-
if input_payload is None:
|
|
101
|
-
sys.exit(0)
|
|
102
|
-
|
|
103
|
-
raw_tool_name = input_payload.get("tool_name", "")
|
|
104
|
-
raw_tool_input = input_payload.get("tool_input", {})
|
|
105
|
-
tool_name = raw_tool_name if isinstance(raw_tool_name, str) else ""
|
|
106
|
-
tool_input = raw_tool_input if isinstance(raw_tool_input, dict) else {}
|
|
107
|
-
|
|
108
|
-
resolved_deny = _resolve_deny(tool_name, input_payload, tool_input)
|
|
109
|
-
if resolved_deny is None:
|
|
110
|
-
sys.exit(0)
|
|
111
|
-
deny_reason, offending_path = resolved_deny
|
|
112
|
-
|
|
113
|
-
log_hook_block(
|
|
114
|
-
calling_hook_name="write_existing_file_blocker.py",
|
|
115
|
-
hook_event="PreToolUse",
|
|
116
|
-
block_reason=deny_reason,
|
|
117
|
-
offending_input_preview=offending_path,
|
|
118
|
-
)
|
|
119
|
-
print(json.dumps(build_deny_response(deny_reason)))
|
|
120
|
-
sys.exit(0)
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
if __name__ == "__main__":
|
|
124
|
-
main()
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
"""Configuration constants for the bot_mention_comment_blocker PreToolUse hook."""
|
|
2
|
-
|
|
3
|
-
TOOL_NAME: str = "mcp__plugin_github_github__add_issue_comment"
|
|
4
|
-
|
|
5
|
-
CURSOR_MENTION_TOKEN: str = "@cursor"
|
|
6
|
-
COPILOT_MENTION_TOKEN: str = "@copilot"
|
|
7
|
-
|
|
8
|
-
CORRECTIVE_MESSAGE_CURSOR: str = (
|
|
9
|
-
"BLOCKED [bot-mention]: Invalid comment. "
|
|
10
|
-
"Post exactly ``bugbot run`` with no other text as your issue comment "
|
|
11
|
-
"to trigger Bugbot."
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
CORRECTIVE_MESSAGE_COPILOT: str = (
|
|
15
|
-
"BLOCKED [bot-mention]: Invalid comment. "
|
|
16
|
-
"To request a Copilot review, use the GitHub REST API:\n"
|
|
17
|
-
" gh api --method POST repos/<owner>/<repo>/pulls/<number>/requested_reviewers \\\n"
|
|
18
|
-
" -f 'reviewers[]=copilot-pull-request-reviewer[bot]'"
|
|
19
|
-
)
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
"""Constants for the Cursor-vs-Python gate misfire PreToolUse blocker.
|
|
2
|
-
|
|
3
|
-
Blocks Shell commands that launch Cursor's CLI or GUI binary against a Python
|
|
4
|
-
script with code-rules-gate flags. That path feeds unknown options into
|
|
5
|
-
Cursor's main process ``resolveArgs``, where ``console.warn`` on a closed pipe
|
|
6
|
-
raises an EPIPE error dialog and still opens the script as an editor path.
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
from __future__ import annotations
|
|
10
|
-
|
|
11
|
-
import re
|
|
12
|
-
|
|
13
|
-
__all__ = [
|
|
14
|
-
"ALL_SUPPORTED_TOOL_NAMES",
|
|
15
|
-
"BASH_TOOL_NAME",
|
|
16
|
-
"POWERSHELL_TOOL_NAME",
|
|
17
|
-
"TOOL_NAME_KEY",
|
|
18
|
-
"TOOL_INPUT_KEY",
|
|
19
|
-
"COMMAND_KEY",
|
|
20
|
-
"HOOK_SPECIFIC_OUTPUT_KEY",
|
|
21
|
-
"HOOK_EVENT_NAME_KEY",
|
|
22
|
-
"HOOK_EVENT_NAME",
|
|
23
|
-
"PERMISSION_DECISION_KEY",
|
|
24
|
-
"DENY_DECISION",
|
|
25
|
-
"PERMISSION_DECISION_REASON_KEY",
|
|
26
|
-
"CALLING_HOOK_NAME",
|
|
27
|
-
"CURSOR_LAUNCH_PATTERN",
|
|
28
|
-
"GATE_SCRIPT_PATTERN",
|
|
29
|
-
"GATE_FLAG_PATTERN",
|
|
30
|
-
"PYTHON_PATH_PATTERN",
|
|
31
|
-
"CORRECTIVE_MESSAGE",
|
|
32
|
-
]
|
|
33
|
-
|
|
34
|
-
BASH_TOOL_NAME = "Bash"
|
|
35
|
-
POWERSHELL_TOOL_NAME = "PowerShell"
|
|
36
|
-
ALL_SUPPORTED_TOOL_NAMES: frozenset[str] = frozenset(
|
|
37
|
-
{BASH_TOOL_NAME, POWERSHELL_TOOL_NAME}
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
TOOL_NAME_KEY = "tool_name"
|
|
41
|
-
TOOL_INPUT_KEY = "tool_input"
|
|
42
|
-
COMMAND_KEY = "command"
|
|
43
|
-
|
|
44
|
-
HOOK_SPECIFIC_OUTPUT_KEY = "hookSpecificOutput"
|
|
45
|
-
HOOK_EVENT_NAME_KEY = "hookEventName"
|
|
46
|
-
HOOK_EVENT_NAME = "PreToolUse"
|
|
47
|
-
PERMISSION_DECISION_KEY = "permissionDecision"
|
|
48
|
-
DENY_DECISION = "deny"
|
|
49
|
-
PERMISSION_DECISION_REASON_KEY = "permissionDecisionReason"
|
|
50
|
-
|
|
51
|
-
CALLING_HOOK_NAME = "cursor_cli_python_misfire_blocker.py"
|
|
52
|
-
|
|
53
|
-
CURSOR_LAUNCH_PATTERN = re.compile(
|
|
54
|
-
r"(?i)"
|
|
55
|
-
r"(?:"
|
|
56
|
-
r"(?:^|[\s;&|])(?:cursor(?:\.cmd|\.exe)?)(?=\s|[\"']|$)"
|
|
57
|
-
r"|"
|
|
58
|
-
r"[\\/](?:cursor(?:\.cmd|\.exe)?)(?=\s|[\"']|$)"
|
|
59
|
-
r")"
|
|
60
|
-
)
|
|
61
|
-
GATE_SCRIPT_PATTERN = re.compile(r"(?i)code_rules_gate\.py\b")
|
|
62
|
-
GATE_FLAG_PATTERN = re.compile(
|
|
63
|
-
r"(?i)(?:^|[\s,\"'])(?:--base|--staged|--repo-root|--only-under)"
|
|
64
|
-
r"(?:\s|=|$|[\"'])"
|
|
65
|
-
)
|
|
66
|
-
PYTHON_PATH_PATTERN = re.compile(r"(?i)\.py(?:\s|$|['\":])")
|
|
67
|
-
|
|
68
|
-
CORRECTIVE_MESSAGE = (
|
|
69
|
-
"BLOCKED [cursor-python-misfire]: Cursor's CLI/GUI was invoked against a "
|
|
70
|
-
"Python script with code-rules-gate flags. Cursor treats those flags as "
|
|
71
|
-
"unknown options, warns on a closed pipe, and raises an EPIPE error dialog "
|
|
72
|
-
"while still opening the script as an editor path.\n\n"
|
|
73
|
-
"To run the gate:\n"
|
|
74
|
-
" python <path-to>/code_rules_gate.py --base origin/main\n\n"
|
|
75
|
-
"To open a file on screen in its native Windows app:\n"
|
|
76
|
-
" Invoke-Item -LiteralPath '<path>'\n\n"
|
|
77
|
-
"Do not pass --base, --staged, --repo-root, or --only-under to cursor / "
|
|
78
|
-
"Cursor.exe."
|
|
79
|
-
)
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
"""Constants for the fable-tier subagent spawn gate.
|
|
2
|
-
|
|
3
|
-
The gate denies an ``Agent`` or ``Task`` spawn at the fable tier whose
|
|
4
|
-
``prompt`` lacks ``FABLE_SPAWN_AUTHORIZATION_MARKER``. ``DENY_REASON`` points
|
|
5
|
-
at the protocol document rather than quoting the token, so pasting a denial
|
|
6
|
-
into a retry prompt authorizes nothing.
|
|
7
|
-
``MODEL_SEGMENT_SPLIT_PATTERN`` finds that tier in a full model id too::
|
|
8
|
-
|
|
9
|
-
fable -> ['fable'] flag: fable tier
|
|
10
|
-
claude-fable-5 -> ['claude', 'fable', '5'] flag: fable tier
|
|
11
|
-
claude-sonnet-4 -> ['claude', 'sonnet', '4'] ok: another tier
|
|
12
|
-
|
|
13
|
-
Every literal the gate body reads lives here. ``AGENT_TOOL_NAME`` and
|
|
14
|
-
``TASK_TOOL_NAME`` name the spawn tools the gate evaluates.
|
|
15
|
-
"""
|
|
16
|
-
|
|
17
|
-
from __future__ import annotations
|
|
18
|
-
|
|
19
|
-
import re
|
|
20
|
-
|
|
21
|
-
AGENT_TOOL_NAME: str = "Agent"
|
|
22
|
-
TASK_TOOL_NAME: str = "Task"
|
|
23
|
-
|
|
24
|
-
ALL_SPAWN_TOOL_NAMES: frozenset[str] = frozenset({AGENT_TOOL_NAME, TASK_TOOL_NAME})
|
|
25
|
-
|
|
26
|
-
FABLE_MODEL_ALIAS: str = "fable"
|
|
27
|
-
MODEL_SEGMENT_SPLIT_PATTERN: re.Pattern[str] = re.compile(r"[^a-z0-9]+")
|
|
28
|
-
FABLE_SPAWN_AUTHORIZATION_MARKER: str = "FABLE-SPAWN-AUTHORIZED"
|
|
29
|
-
ADVISOR_PROTOCOL_DOCUMENT_PATH: str = "_shared/advisor/advisor-protocol.md"
|
|
30
|
-
|
|
31
|
-
TOOL_NAME_FIELD_NAME: str = "tool_name"
|
|
32
|
-
TOOL_INPUT_FIELD_NAME: str = "tool_input"
|
|
33
|
-
MODEL_FIELD_NAME: str = "model"
|
|
34
|
-
PROMPT_FIELD_NAME: str = "prompt"
|
|
35
|
-
|
|
36
|
-
CALLING_HOOK_NAME: str = "fable_spawn_gate.py"
|
|
37
|
-
HOOK_EVENT_NAME: str = "PreToolUse"
|
|
38
|
-
|
|
39
|
-
DENY_REASON: str = (
|
|
40
|
-
"BLOCKED [fable-spawn-gate]: this subagent spawn names the fable tier in "
|
|
41
|
-
"its model field and carries no authorization marker. To authorize a "
|
|
42
|
-
f"fable bind, put the token named in {ADVISOR_PROTOCOL_DOCUMENT_PATH} as "
|
|
43
|
-
"plain text in the spawn prompt (substring match). Otherwise set model "
|
|
44
|
-
"to opus, sonnet, or haiku. The gate checks only model tier and marker "
|
|
45
|
-
"presence — it does not verify which session placed the token."
|
|
46
|
-
)
|
|
47
|
-
|
|
48
|
-
DENY_ADDITIONAL_CONTEXT: str = (
|
|
49
|
-
"[fable-spawn-gate] This Agent/Task spawn was denied: the model field "
|
|
50
|
-
"names the fable tier and the spawn prompt carries no authorization "
|
|
51
|
-
"marker. Preferred recovery: re-spawn at model opus, or an "
|
|
52
|
-
"opus-equivalent tier (sonnet/haiku when opus is unavailable) — those "
|
|
53
|
-
"tiers need no marker. Authorized fable bind only: put the token named "
|
|
54
|
-
f"in {ADVISOR_PROTOCOL_DOCUMENT_PATH} as plain text in the spawn prompt "
|
|
55
|
-
"(substring match), then retry. The gate checks only model tier and "
|
|
56
|
-
"marker presence. Do not paste this denial into a retry prompt — it "
|
|
57
|
-
"does not authorize the spawn."
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
DENY_PREVIEW_TEMPLATE: str = "model={model_text} marker_present=False"
|
|
61
|
-
MAXIMUM_PREVIEW_MODEL_LENGTH: int = 40
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
"""Constants for the Codex Luna fast-mode spawn gate.
|
|
2
|
-
|
|
3
|
-
The gate checks the model and service tier fields on Agent, Task, and native
|
|
4
|
-
Codex multi-agent spawn calls. Agent and Task require exact ``fast``. Native
|
|
5
|
-
Codex accepts exact ``fast`` or ``priority`` for Luna models.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from __future__ import annotations
|
|
9
|
-
|
|
10
|
-
import re
|
|
11
|
-
|
|
12
|
-
AGENT_TOOL_NAME: str = "Agent"
|
|
13
|
-
TASK_TOOL_NAME: str = "Task"
|
|
14
|
-
CODEX_AGENT_TOOL_NAME: str = "multi_agent_v1__spawn_agent"
|
|
15
|
-
ALL_SPAWN_TOOL_NAMES: frozenset[str] = frozenset(
|
|
16
|
-
{AGENT_TOOL_NAME, TASK_TOOL_NAME, CODEX_AGENT_TOOL_NAME}
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
LUNA_MODEL_ALIAS: str = "luna"
|
|
20
|
-
FAST_SERVICE_TIER: str = "fast"
|
|
21
|
-
PRIORITY_SERVICE_TIER: str = "priority"
|
|
22
|
-
MODEL_SEGMENT_SPLIT_PATTERN: re.Pattern[str] = re.compile(r"[^a-z0-9]+")
|
|
23
|
-
|
|
24
|
-
TOOL_NAME_FIELD_NAME: str = "tool_name"
|
|
25
|
-
TOOL_INPUT_FIELD_NAME: str = "tool_input"
|
|
26
|
-
MODEL_FIELD_NAME: str = "model"
|
|
27
|
-
SERVICE_TIER_FIELD_NAME: str = "service_tier"
|
|
28
|
-
|
|
29
|
-
CALLING_HOOK_NAME: str = "luna_fast_mode_gate.py"
|
|
30
|
-
HOOK_EVENT_NAME: str = "PreToolUse"
|
|
31
|
-
|
|
32
|
-
DENY_REASON: str = (
|
|
33
|
-
"BLOCKED [luna-fast-mode-gate]: Agent and Task Luna spawns require "
|
|
34
|
-
"service_tier fast. Native Codex Luna spawns require service_tier fast "
|
|
35
|
-
"or priority. Retry with an allowed service_tier."
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
DENY_ADDITIONAL_CONTEXT: str = (
|
|
39
|
-
"[luna-fast-mode-gate] Agent and Task Luna spawns require service_tier "
|
|
40
|
-
"fast. Native Codex Luna spawns accept service_tier fast or priority. "
|
|
41
|
-
"Retry with an allowed service_tier."
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
DENY_PREVIEW_TEMPLATE: str = "model={model_text} service_tier={service_tier_text}"
|
|
45
|
-
MAXIMUM_PREVIEW_FIELD_LENGTH: int = 40
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
"""Constants for the NAS ssh binary enforcer hook.
|
|
2
|
-
|
|
3
|
-
Holds the Bash tool name, the ssh-family command basenames, the Windows OpenSSH
|
|
4
|
-
binary path suffixes, and the batch-mode pattern. Segment splitting and
|
|
5
|
-
leading-program resolution come from ``shell_command_segments``.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import re
|
|
9
|
-
|
|
10
|
-
BASH_TOOL_NAME = "Bash"
|
|
11
|
-
|
|
12
|
-
ALL_SSH_FAMILY_COMMAND_BASENAMES = frozenset(
|
|
13
|
-
{"ssh", "scp", "sftp", "ssh.exe", "scp.exe", "sftp.exe"}
|
|
14
|
-
)
|
|
15
|
-
ALL_OPENSSH_BINARY_PATH_SUFFIXES = (
|
|
16
|
-
"/openssh/ssh.exe",
|
|
17
|
-
"/openssh/scp.exe",
|
|
18
|
-
"/openssh/sftp.exe",
|
|
19
|
-
)
|
|
20
|
-
BATCH_MODE_PATTERN = re.compile(r"batchmode\s*=\s*yes", re.IGNORECASE)
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
"""Constants for the orchestrator-refresh ScheduleWakeup reschedule gate."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
SCHEDULE_WAKEUP_TOOL_NAME = "ScheduleWakeup"
|
|
6
|
-
CRON_CREATE_TOOL_NAME = "CronCreate"
|
|
7
|
-
ALL_SCHEDULE_TOOL_NAMES: frozenset[str] = frozenset(
|
|
8
|
-
{
|
|
9
|
-
SCHEDULE_WAKEUP_TOOL_NAME,
|
|
10
|
-
CRON_CREATE_TOOL_NAME,
|
|
11
|
-
}
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
ORCHESTRATOR_REFRESH_PROMPT_TOKEN = "/orchestrator-refresh"
|
|
15
|
-
RUN_SLUG_PROMPT_FLAG = "--run-slug"
|
|
16
|
-
RUN_SLUG_PROMPT_VALUE_PATTERN = r"(?:=\s*|\s+)([^\s]+)"
|
|
17
|
-
PROMPT_FIELD_NAME = "prompt"
|
|
18
|
-
TOOL_NAME_FIELD_NAME = "tool_name"
|
|
19
|
-
TOOL_INPUT_FIELD_NAME = "tool_input"
|
|
20
|
-
CWD_FIELD_NAME = "cwd"
|
|
21
|
-
|
|
22
|
-
REASON_CRON_CREATE_FORBIDDEN = "cron_create_forbidden"
|
|
23
|
-
|
|
24
|
-
DENY_REASON_TEMPLATE = (
|
|
25
|
-
"BLOCKED: orchestrator-refresh re-arm denied ({reason}). "
|
|
26
|
-
"Use one-shot delayed wake only (never CronCreate / never recurring). "
|
|
27
|
-
"At most one re-arm slot: begin-firing at refresh start; "
|
|
28
|
-
"should-reschedule then create then claim-rearm (never claim before "
|
|
29
|
-
"ScheduleWakeup). Status must be active: "
|
|
30
|
-
"python skills/orchestrator/scripts/status_gate.py set "
|
|
31
|
-
"--status active. When finished: --status done. Never re-arm an idle loop."
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
CALLING_HOOK_NAME = "orchestrator_refresh_reschedule_gate.py"
|
|
35
|
-
HOOK_EVENT_NAME = "PreToolUse"
|
|
36
|
-
|
|
37
|
-
ALL_PACKAGE_AGENTS_SKILL_SCRIPTS_RELATIVE_PARTS: tuple[str, ...] = (
|
|
38
|
-
".agents",
|
|
39
|
-
"skills",
|
|
40
|
-
"orchestrator",
|
|
41
|
-
"scripts",
|
|
42
|
-
)
|
|
43
|
-
"""Package-source path of orchestrator status_gate.py under the agents home."""
|
|
44
|
-
|
|
45
|
-
ALL_SKILL_SCRIPTS_RELATIVE_PARTS: tuple[str, ...] = (
|
|
46
|
-
"skills",
|
|
47
|
-
"orchestrator",
|
|
48
|
-
"scripts",
|
|
49
|
-
)
|
|
50
|
-
"""Package-root path of orchestrator status_gate.py for a dependency layout."""
|
|
51
|
-
PLUGIN_ROOT_ENV_VAR = "CLAUDE_PLUGIN_ROOT"
|
|
52
|
-
ALL_HOME_SKILLS_RELATIVE_PARTS: tuple[str, ...] = (
|
|
53
|
-
".claude",
|
|
54
|
-
"skills",
|
|
55
|
-
"orchestrator",
|
|
56
|
-
"scripts",
|
|
57
|
-
)
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"""Configuration constants for the send_user_file_open_locally_blocker PreToolUse hook."""
|
|
2
|
-
|
|
3
|
-
TOOL_NAME: str = "SendUserFile"
|
|
4
|
-
|
|
5
|
-
PROACTIVE_STATUS: str = "proactive"
|
|
6
|
-
|
|
7
|
-
CORRECTIVE_MESSAGE: str = (
|
|
8
|
-
"BLOCKED [open-locally]: SendUserFile attaches a file to the session, which "
|
|
9
|
-
"does not let the user see it while they are at the terminal. Open the file on "
|
|
10
|
-
"screen with its native Windows app:\n"
|
|
11
|
-
" Invoke-Item -LiteralPath '<path>'\n"
|
|
12
|
-
"Open every path the user named. Do not launch Cursor.exe or cursor.cmd to open "
|
|
13
|
-
"a file — unknown flags on that path raise an EPIPE error dialog in Cursor's "
|
|
14
|
-
"main process.\n"
|
|
15
|
-
"The one allowed attach is a phone push: when the user has stepped away and you "
|
|
16
|
-
'want the file to reach their phone, call SendUserFile with status "proactive".'
|
|
17
|
-
)
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
"""Constants for the ``sensitive_file_protector`` PreToolUse hook.
|
|
2
|
-
|
|
3
|
-
The hook denies a Write, Edit, or MultiEdit whose target basename names a live
|
|
4
|
-
secret or a lock file, and steps aside for a placeholders-only committed template.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from __future__ import annotations
|
|
8
|
-
|
|
9
|
-
ALL_SENSITIVE_PATTERNS = (
|
|
10
|
-
".env",
|
|
11
|
-
".env.*",
|
|
12
|
-
"*.env",
|
|
13
|
-
"*.pem",
|
|
14
|
-
"*.key",
|
|
15
|
-
"*.p12",
|
|
16
|
-
"*.pfx",
|
|
17
|
-
"credentials.json",
|
|
18
|
-
"secrets.json",
|
|
19
|
-
"id_rsa",
|
|
20
|
-
"id_ed25519",
|
|
21
|
-
"package-lock.json",
|
|
22
|
-
"yarn.lock",
|
|
23
|
-
"Pipfile.lock",
|
|
24
|
-
"poetry.lock",
|
|
25
|
-
"pnpm-lock.yaml",
|
|
26
|
-
"composer.lock",
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
ALL_TEMPLATE_SUFFIXES = (".example", ".sample", ".template")
|
|
30
|
-
|
|
31
|
-
HOOK_SCRIPT_NAME = "sensitive_file_protector.py"
|
|
32
|
-
|
|
33
|
-
HOOK_EVENT_NAME = "PreToolUse"
|
|
34
|
-
|
|
35
|
-
DENY_DECISION = "deny"
|
|
36
|
-
|
|
37
|
-
DENY_REASON_TEMPLATE = (
|
|
38
|
-
"BLOCKED: Sensitive file '{filename}' (pattern: '{matched_pattern}'). "
|
|
39
|
-
"Edit manually outside Claude Code."
|
|
40
|
-
)
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
"""Shared compiled patterns for the session_handoff_blocker hook."""
|
|
2
|
-
|
|
3
|
-
import re
|
|
4
|
-
|
|
5
|
-
FIRST_PERSON_SUBJECT_PATTERN = re.compile(
|
|
6
|
-
r"\b(?:i['’]?m|i['’]?ll|i\s+will|i\s+am|i\s+need\s+to|i\s+should"
|
|
7
|
-
r"|i\s+recommend|i\s+suggest|let\s+me|let['’]?s"
|
|
8
|
-
r"|we\s+(?:should|can|could)|we['’]?ll|we\s+are|we\s+will)\b",
|
|
9
|
-
re.IGNORECASE,
|
|
10
|
-
)
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
"""Constants for the shell-substitution PreToolUse Bash blocker.
|
|
2
|
-
|
|
3
|
-
Holds the tool name, the payload keys, the four detection patterns, the deny
|
|
4
|
-
decision shape, and the corrective message. The hook imports these so no
|
|
5
|
-
single-use constant sits at its file scope.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from __future__ import annotations
|
|
9
|
-
|
|
10
|
-
import re
|
|
11
|
-
|
|
12
|
-
__all__ = [
|
|
13
|
-
"BASH_TOOL_NAME",
|
|
14
|
-
"TOOL_NAME_KEY",
|
|
15
|
-
"TOOL_INPUT_KEY",
|
|
16
|
-
"COMMAND_KEY",
|
|
17
|
-
"HOOK_SPECIFIC_OUTPUT_KEY",
|
|
18
|
-
"HOOK_EVENT_NAME_KEY",
|
|
19
|
-
"HOOK_EVENT_NAME",
|
|
20
|
-
"PERMISSION_DECISION_KEY",
|
|
21
|
-
"DENY_DECISION",
|
|
22
|
-
"PERMISSION_DECISION_REASON_KEY",
|
|
23
|
-
"DOLLAR_PAREN_PATTERN",
|
|
24
|
-
"EVEN_BACKSLASH_BACKTICK_PATTERN",
|
|
25
|
-
"PROCESS_SUBSTITUTION_PATTERN",
|
|
26
|
-
"SINGLE_QUOTED_RUN_PATTERN",
|
|
27
|
-
"STRIPPED_RUN_REPLACEMENT",
|
|
28
|
-
"COMMAND_LINE_SEPARATOR",
|
|
29
|
-
"BACKSLASH_CHARACTER",
|
|
30
|
-
"SINGLE_QUOTE_CHARACTER",
|
|
31
|
-
"DOUBLE_QUOTE_CHARACTER",
|
|
32
|
-
"NO_TERMINATOR_INDEX",
|
|
33
|
-
"CORRECTIVE_MESSAGE",
|
|
34
|
-
]
|
|
35
|
-
|
|
36
|
-
BASH_TOOL_NAME = "Bash"
|
|
37
|
-
|
|
38
|
-
TOOL_NAME_KEY = "tool_name"
|
|
39
|
-
TOOL_INPUT_KEY = "tool_input"
|
|
40
|
-
COMMAND_KEY = "command"
|
|
41
|
-
|
|
42
|
-
HOOK_SPECIFIC_OUTPUT_KEY = "hookSpecificOutput"
|
|
43
|
-
HOOK_EVENT_NAME_KEY = "hookEventName"
|
|
44
|
-
HOOK_EVENT_NAME = "PreToolUse"
|
|
45
|
-
PERMISSION_DECISION_KEY = "permissionDecision"
|
|
46
|
-
DENY_DECISION = "deny"
|
|
47
|
-
PERMISSION_DECISION_REASON_KEY = "permissionDecisionReason"
|
|
48
|
-
|
|
49
|
-
DOLLAR_PAREN_PATTERN = re.compile(r"\$\(")
|
|
50
|
-
OPEN_PAREN_CHARACTER = "("
|
|
51
|
-
CLOSE_PAREN_CHARACTER = ")"
|
|
52
|
-
PAREN_DEPTH_AFTER_DOUBLE_OPEN = 2
|
|
53
|
-
EVEN_BACKSLASH_BACKTICK_PATTERN = re.compile(r"(?<!\\)(?:\\\\)*`")
|
|
54
|
-
PROCESS_SUBSTITUTION_PATTERN = re.compile(r"[<>]\(")
|
|
55
|
-
SINGLE_QUOTED_RUN_PATTERN = re.compile(r"'[^']*'")
|
|
56
|
-
STRIPPED_RUN_REPLACEMENT = ""
|
|
57
|
-
COMMAND_LINE_SEPARATOR = "\n"
|
|
58
|
-
BACKSLASH_CHARACTER = "\\"
|
|
59
|
-
SINGLE_QUOTE_CHARACTER = "'"
|
|
60
|
-
DOUBLE_QUOTE_CHARACTER = '"'
|
|
61
|
-
NO_TERMINATOR_INDEX = -1
|
|
62
|
-
|
|
63
|
-
CORRECTIVE_MESSAGE = (
|
|
64
|
-
"BLOCKED [shell-substitution]: command contains $(...), backtick, or "
|
|
65
|
-
"<(...)/>(...) process substitution, which forces a permission prompt "
|
|
66
|
-
"because the Claude Code allowlist matcher does not descend into "
|
|
67
|
-
"substitutions.\n\n"
|
|
68
|
-
"Fix: split into two Bash tool calls, or rewrite without substitution.\n"
|
|
69
|
-
' cd X && echo "$(git rev-parse HEAD)"\n'
|
|
70
|
-
"becomes either two calls:\n"
|
|
71
|
-
" 1) cd X\n"
|
|
72
|
-
" 2) git rev-parse HEAD\n"
|
|
73
|
-
"or one substitution-free call:\n"
|
|
74
|
-
" git -C X rev-parse HEAD\n\n"
|
|
75
|
-
"Process substitution example:\n"
|
|
76
|
-
" diff <(cat a) <(cat b)\n"
|
|
77
|
-
"becomes two separate Bash calls to `cat a` and `cat b`, with the diff "
|
|
78
|
-
"performed on the captured outputs.\n\n"
|
|
79
|
-
"See `shell-invocation.md` in the rules directory for full guidance."
|
|
80
|
-
)
|
|
File without changes
|
|
File without changes
|