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,201 +0,0 @@
|
|
|
1
|
-
"""Tests for write_handoff: the durable per-run handoff writer."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import importlib.util
|
|
6
|
-
import json
|
|
7
|
-
import sys
|
|
8
|
-
from pathlib import Path
|
|
9
|
-
from types import ModuleType
|
|
10
|
-
|
|
11
|
-
import pytest
|
|
12
|
-
|
|
13
|
-
_SCRIPTS_DIR = Path(__file__).resolve().parent
|
|
14
|
-
if str(_SCRIPTS_DIR) not in sys.path:
|
|
15
|
-
sys.path.insert(0, str(_SCRIPTS_DIR))
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def _load_write_handoff_module() -> ModuleType:
|
|
19
|
-
module_path = _SCRIPTS_DIR / "write_handoff.py"
|
|
20
|
-
spec = importlib.util.spec_from_file_location("write_handoff", module_path)
|
|
21
|
-
assert spec is not None
|
|
22
|
-
assert spec.loader is not None
|
|
23
|
-
module = importlib.util.module_from_spec(spec)
|
|
24
|
-
spec.loader.exec_module(module)
|
|
25
|
-
return module
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
write_handoff = _load_write_handoff_module()
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
_FROZEN_TIMESTAMP = "2026-07-03T12:00:00+00:00"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def _point_base_dir_at(monkeypatch: pytest.MonkeyPatch, base: Path) -> None:
|
|
35
|
-
monkeypatch.setattr(write_handoff, "_handoff_base_dir", lambda: base)
|
|
36
|
-
monkeypatch.setattr(write_handoff, "_now_iso", lambda: _FROZEN_TIMESTAMP)
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
def test_resolve_handoff_dir_joins_run_name_under_base(
|
|
40
|
-
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
|
41
|
-
) -> None:
|
|
42
|
-
"""resolve_handoff_dir places the run's directory under the durable base."""
|
|
43
|
-
_point_base_dir_at(monkeypatch, tmp_path)
|
|
44
|
-
resolved = write_handoff.resolve_handoff_dir("bugteam-pr-4")
|
|
45
|
-
assert resolved == tmp_path / "bugteam-pr-4"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def test_handoff_base_dir_lives_under_home_runtime_pr_loop(
|
|
49
|
-
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
|
50
|
-
) -> None:
|
|
51
|
-
"""The durable base sits under the user home, not the OS temp directory."""
|
|
52
|
-
monkeypatch.setenv("USERPROFILE", str(tmp_path))
|
|
53
|
-
monkeypatch.setenv("HOME", str(tmp_path))
|
|
54
|
-
base = write_handoff._handoff_base_dir()
|
|
55
|
-
assert base == tmp_path / ".claude" / "runtime" / "pr-loop"
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
def test_write_handoff_records_resume_command_and_phase(
|
|
59
|
-
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
|
60
|
-
) -> None:
|
|
61
|
-
"""write_handoff writes handoff.json and HANDOFF.md carrying the resume
|
|
62
|
-
command, phase, run id, completed steps, and a timestamp."""
|
|
63
|
-
_point_base_dir_at(monkeypatch, tmp_path)
|
|
64
|
-
handoff_dir = write_handoff.write_handoff(
|
|
65
|
-
pr_number=4,
|
|
66
|
-
head_ref="feat/pr-loop-durable-handoff",
|
|
67
|
-
phase="tick",
|
|
68
|
-
resume_command="claude --resume /pr-converge",
|
|
69
|
-
run_id="wf_abc123",
|
|
70
|
-
all_completed_steps=["preflight", "audit"],
|
|
71
|
-
note="Copilot wait-gate still open.",
|
|
72
|
-
)
|
|
73
|
-
assert handoff_dir == tmp_path / "bugteam-pr-4"
|
|
74
|
-
|
|
75
|
-
payload = json.loads((handoff_dir / "handoff.json").read_text(encoding="utf-8"))
|
|
76
|
-
assert payload["resume_command"] == "claude --resume /pr-converge"
|
|
77
|
-
assert payload["phase"] == "tick"
|
|
78
|
-
assert payload["run_id"] == "wf_abc123"
|
|
79
|
-
assert payload["completed_steps"] == ["preflight", "audit"]
|
|
80
|
-
assert payload["timestamp"] == _FROZEN_TIMESTAMP
|
|
81
|
-
|
|
82
|
-
markdown = (handoff_dir / "HANDOFF.md").read_text(encoding="utf-8")
|
|
83
|
-
assert "claude --resume /pr-converge" in markdown
|
|
84
|
-
assert "preflight" in markdown
|
|
85
|
-
assert "Copilot wait-gate still open." in markdown
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
def test_write_handoff_copies_state_file_when_given(
|
|
89
|
-
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
|
90
|
-
) -> None:
|
|
91
|
-
"""A supplied --state-file is copied to state-copy.json and the copy path is
|
|
92
|
-
recorded in handoff.json."""
|
|
93
|
-
_point_base_dir_at(monkeypatch, tmp_path)
|
|
94
|
-
source_state = tmp_path / "loop-state.json"
|
|
95
|
-
source_state.write_text('{"loop_count": 3}', encoding="utf-8")
|
|
96
|
-
|
|
97
|
-
handoff_dir = write_handoff.write_handoff(
|
|
98
|
-
pr_number=4,
|
|
99
|
-
head_ref="feat/branch",
|
|
100
|
-
phase="teardown",
|
|
101
|
-
resume_command="claude --resume /autoconverge",
|
|
102
|
-
state_file=source_state,
|
|
103
|
-
)
|
|
104
|
-
|
|
105
|
-
state_copy = handoff_dir / "state-copy.json"
|
|
106
|
-
assert json.loads(state_copy.read_text(encoding="utf-8")) == {"loop_count": 3}
|
|
107
|
-
payload = json.loads((handoff_dir / "handoff.json").read_text(encoding="utf-8"))
|
|
108
|
-
assert payload["state_file"] == state_copy.as_posix()
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
def test_write_handoff_omits_state_copy_when_absent(
|
|
112
|
-
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
|
113
|
-
) -> None:
|
|
114
|
-
"""With no --state-file, no state-copy.json is written and state_file is null."""
|
|
115
|
-
_point_base_dir_at(monkeypatch, tmp_path)
|
|
116
|
-
handoff_dir = write_handoff.write_handoff(
|
|
117
|
-
pr_number=4,
|
|
118
|
-
head_ref="feat/branch",
|
|
119
|
-
phase="tick",
|
|
120
|
-
resume_command="claude --resume /pr-converge",
|
|
121
|
-
)
|
|
122
|
-
assert not (handoff_dir / "state-copy.json").exists()
|
|
123
|
-
payload = json.loads((handoff_dir / "handoff.json").read_text(encoding="utf-8"))
|
|
124
|
-
assert payload["state_file"] is None
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
def test_parse_arguments_reads_completed_steps_value() -> None:
|
|
128
|
-
"""The CLI captures the raw comma-separated --completed-steps value."""
|
|
129
|
-
arguments = write_handoff.parse_arguments(
|
|
130
|
-
[
|
|
131
|
-
"--pr-number",
|
|
132
|
-
"4",
|
|
133
|
-
"--head-ref",
|
|
134
|
-
"feat/branch",
|
|
135
|
-
"--phase",
|
|
136
|
-
"tick",
|
|
137
|
-
"--resume-command",
|
|
138
|
-
"claude --resume /pr-converge",
|
|
139
|
-
"--completed-steps",
|
|
140
|
-
"preflight,audit,fix",
|
|
141
|
-
]
|
|
142
|
-
)
|
|
143
|
-
assert arguments.completed_steps == "preflight,audit,fix"
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
def test_main_writes_handoff_and_prints_dir(
|
|
147
|
-
tmp_path: Path,
|
|
148
|
-
monkeypatch: pytest.MonkeyPatch,
|
|
149
|
-
capsys: pytest.CaptureFixture[str],
|
|
150
|
-
) -> None:
|
|
151
|
-
"""main writes the handoff files and prints the durable directory path."""
|
|
152
|
-
_point_base_dir_at(monkeypatch, tmp_path)
|
|
153
|
-
exit_code = write_handoff.main(
|
|
154
|
-
[
|
|
155
|
-
"--pr-number",
|
|
156
|
-
"4",
|
|
157
|
-
"--head-ref",
|
|
158
|
-
"feat/branch",
|
|
159
|
-
"--phase",
|
|
160
|
-
"tick",
|
|
161
|
-
"--resume-command",
|
|
162
|
-
"claude --resume /pr-converge",
|
|
163
|
-
"--completed-steps",
|
|
164
|
-
"preflight,audit",
|
|
165
|
-
]
|
|
166
|
-
)
|
|
167
|
-
assert exit_code == 0
|
|
168
|
-
printed = capsys.readouterr().out.strip()
|
|
169
|
-
assert "\\" not in printed
|
|
170
|
-
assert printed.endswith("bugteam-pr-4")
|
|
171
|
-
payload = json.loads(
|
|
172
|
-
(tmp_path / "bugteam-pr-4" / "handoff.json").read_text(encoding="utf-8")
|
|
173
|
-
)
|
|
174
|
-
assert payload["completed_steps"] == ["preflight", "audit"]
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
def test_main_returns_one_on_non_utf8_state_file(
|
|
178
|
-
tmp_path: Path,
|
|
179
|
-
monkeypatch: pytest.MonkeyPatch,
|
|
180
|
-
capsys: pytest.CaptureFixture[str],
|
|
181
|
-
) -> None:
|
|
182
|
-
"""main exits 1 rather than crashing when --state-file holds non-UTF-8 bytes."""
|
|
183
|
-
_point_base_dir_at(monkeypatch, tmp_path)
|
|
184
|
-
bad_state = tmp_path / "loop-state.json"
|
|
185
|
-
bad_state.write_bytes(b"\xff\xfe not valid utf-8")
|
|
186
|
-
exit_code = write_handoff.main(
|
|
187
|
-
[
|
|
188
|
-
"--pr-number",
|
|
189
|
-
"4",
|
|
190
|
-
"--head-ref",
|
|
191
|
-
"feat/branch",
|
|
192
|
-
"--phase",
|
|
193
|
-
"teardown",
|
|
194
|
-
"--resume-command",
|
|
195
|
-
"claude --resume /autoconverge",
|
|
196
|
-
"--state-file",
|
|
197
|
-
str(bad_state),
|
|
198
|
-
]
|
|
199
|
-
)
|
|
200
|
-
assert exit_code == 1
|
|
201
|
-
assert "write_handoff failed" in capsys.readouterr().err
|
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
"""Validate Shape A/B contract and write <bugteam_audit> XML at the canonical path.
|
|
2
|
-
|
|
3
|
-
Usage:
|
|
4
|
-
python scripts/write_audit_outcomes.py --pr-number 422 --loop 3 --review-url <URL> --findings-json <PATH> --worktree-path <PATH>
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from __future__ import annotations
|
|
8
|
-
|
|
9
|
-
import argparse
|
|
10
|
-
import json
|
|
11
|
-
import sys
|
|
12
|
-
from pathlib import Path
|
|
13
|
-
from xml.etree.ElementTree import Element, SubElement
|
|
14
|
-
|
|
15
|
-
_self_dir = Path(__file__).resolve().parent
|
|
16
|
-
if str(_self_dir) not in sys.path:
|
|
17
|
-
sys.path.insert(0, str(_self_dir))
|
|
18
|
-
|
|
19
|
-
from _cli_utils import require_file
|
|
20
|
-
from _path_resolver import outcome_xml_path
|
|
21
|
-
from _xml_utils import emit_pretty_xml
|
|
22
|
-
from skills_pr_loop_constants.path_resolver_constants import ALL_FINDING_BODY_ELEMENT_KEYS
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def build_audit_xml(
|
|
26
|
-
*,
|
|
27
|
-
pr_number: int,
|
|
28
|
-
loop: int,
|
|
29
|
-
review_url: str,
|
|
30
|
-
findings_json_path: Path,
|
|
31
|
-
) -> Element:
|
|
32
|
-
"""Build the <bugteam_audit> XML element from findings data.
|
|
33
|
-
|
|
34
|
-
Args:
|
|
35
|
-
pr_number: Pull request number.
|
|
36
|
-
loop: Loop iteration number.
|
|
37
|
-
review_url: URL of the GitHub review.
|
|
38
|
-
findings_json_path: Path to the findings JSON file.
|
|
39
|
-
|
|
40
|
-
Returns:
|
|
41
|
-
Root <bugteam_audit> element.
|
|
42
|
-
|
|
43
|
-
Raises:
|
|
44
|
-
SystemExit: When findings-json is not a JSON array of objects.
|
|
45
|
-
"""
|
|
46
|
-
findings_data = json.loads(findings_json_path.read_text(encoding="utf-8"))
|
|
47
|
-
if not isinstance(findings_data, list):
|
|
48
|
-
print("findings-json must contain a JSON array", file=sys.stderr)
|
|
49
|
-
raise SystemExit(1)
|
|
50
|
-
for each_index, each_finding in enumerate(findings_data):
|
|
51
|
-
if not isinstance(each_finding, dict):
|
|
52
|
-
print(
|
|
53
|
-
f"findings-json[{each_index}]: each entry must be a JSON object",
|
|
54
|
-
file=sys.stderr,
|
|
55
|
-
)
|
|
56
|
-
raise SystemExit(1)
|
|
57
|
-
root = Element("bugteam_audit", {
|
|
58
|
-
"pr": str(pr_number),
|
|
59
|
-
"loop": str(loop),
|
|
60
|
-
"review_url": review_url,
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
findings_elem = SubElement(root, "findings")
|
|
64
|
-
_populate_findings(findings_elem, findings_data)
|
|
65
|
-
return root
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
def _populate_findings(parent: Element, findings_data: list[dict[str, object]]) -> None:
|
|
69
|
-
"""Populate <finding> elements from a validated list of finding dicts.
|
|
70
|
-
|
|
71
|
-
Scalar finding fields become XML attributes on `<finding>`; the
|
|
72
|
-
body fields named in `ALL_FINDING_BODY_ELEMENT_KEYS` (defined in
|
|
73
|
-
`packages/claude-dev-env/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/path_resolver_constants.py`
|
|
74
|
-
and currently `("title", "excerpt", "description")`) become child elements.
|
|
75
|
-
Nested dicts or lists in scalar slots are flattened to string form
|
|
76
|
-
so attribute serialization stays well-defined.
|
|
77
|
-
|
|
78
|
-
Args:
|
|
79
|
-
parent: Parent XML element (typically `<findings>`).
|
|
80
|
-
findings_data: Validated list of finding dicts (caller must have
|
|
81
|
-
confirmed each entry is a dict via the build_audit_xml gate).
|
|
82
|
-
"""
|
|
83
|
-
all_finding_body_element_keys = ALL_FINDING_BODY_ELEMENT_KEYS
|
|
84
|
-
for each_finding in findings_data:
|
|
85
|
-
finding_elem = SubElement(parent, "finding")
|
|
86
|
-
for each_key, each_field_detail in each_finding.items():
|
|
87
|
-
field_text = (
|
|
88
|
-
str(each_field_detail) if each_field_detail is not None else ""
|
|
89
|
-
)
|
|
90
|
-
if each_key in all_finding_body_element_keys:
|
|
91
|
-
child = SubElement(finding_elem, each_key)
|
|
92
|
-
child.text = field_text
|
|
93
|
-
else:
|
|
94
|
-
finding_elem.set(each_key, field_text)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
def write_audit_xml(
|
|
98
|
-
*,
|
|
99
|
-
pr_number: int,
|
|
100
|
-
loop: int,
|
|
101
|
-
review_url: str,
|
|
102
|
-
findings_json_path: Path,
|
|
103
|
-
worktree_path: Path,
|
|
104
|
-
) -> Path:
|
|
105
|
-
"""Write the <bugteam_audit> XML to the canonical outcome path.
|
|
106
|
-
|
|
107
|
-
Args:
|
|
108
|
-
pr_number: Pull request number.
|
|
109
|
-
loop: Loop iteration number.
|
|
110
|
-
review_url: URL of the GitHub review.
|
|
111
|
-
findings_json_path: Path to the findings JSON file.
|
|
112
|
-
worktree_path: Path to the git worktree.
|
|
113
|
-
|
|
114
|
-
Returns:
|
|
115
|
-
Path to the written XML file.
|
|
116
|
-
"""
|
|
117
|
-
root = build_audit_xml(
|
|
118
|
-
pr_number=pr_number,
|
|
119
|
-
loop=loop,
|
|
120
|
-
review_url=review_url,
|
|
121
|
-
findings_json_path=findings_json_path,
|
|
122
|
-
)
|
|
123
|
-
xml_string = emit_pretty_xml(root)
|
|
124
|
-
|
|
125
|
-
output_path = outcome_xml_path(worktree_path, pr_number, loop)
|
|
126
|
-
output_path.write_text(xml_string, encoding="utf-8")
|
|
127
|
-
return output_path
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
def parse_arguments(all_argv: list[str]) -> argparse.Namespace:
|
|
131
|
-
"""Parse command-line arguments.
|
|
132
|
-
|
|
133
|
-
Args:
|
|
134
|
-
all_argv: Command-line argument list.
|
|
135
|
-
|
|
136
|
-
Returns:
|
|
137
|
-
Parsed namespace with pr_number, loop, review_url, findings_json, and worktree_path.
|
|
138
|
-
"""
|
|
139
|
-
parser = argparse.ArgumentParser(description=__doc__)
|
|
140
|
-
parser.add_argument("--pr-number", type=int, required=True)
|
|
141
|
-
parser.add_argument("--loop", type=int, required=True)
|
|
142
|
-
parser.add_argument("--review-url", required=True)
|
|
143
|
-
parser.add_argument("--findings-json", type=Path, required=True)
|
|
144
|
-
parser.add_argument("--worktree-path", type=Path, required=True)
|
|
145
|
-
return parser.parse_args(all_argv)
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
def main(all_arguments: list[str]) -> int:
|
|
149
|
-
"""Entry point: write <bugteam_audit> XML at the canonical path.
|
|
150
|
-
|
|
151
|
-
Args:
|
|
152
|
-
all_arguments: Command-line arguments.
|
|
153
|
-
|
|
154
|
-
Returns:
|
|
155
|
-
0 on success, 1 on validation or write failure.
|
|
156
|
-
"""
|
|
157
|
-
arguments = parse_arguments(all_arguments)
|
|
158
|
-
findings_path = getattr(arguments, "findings_json")
|
|
159
|
-
|
|
160
|
-
early_exit = require_file(findings_path, "findings-json")
|
|
161
|
-
if early_exit is not None:
|
|
162
|
-
return early_exit
|
|
163
|
-
|
|
164
|
-
try:
|
|
165
|
-
output_path = write_audit_xml(
|
|
166
|
-
pr_number=getattr(arguments, "pr_number"),
|
|
167
|
-
loop=arguments.loop,
|
|
168
|
-
review_url=getattr(arguments, "review_url"),
|
|
169
|
-
findings_json_path=findings_path,
|
|
170
|
-
worktree_path=getattr(arguments, "worktree_path"),
|
|
171
|
-
)
|
|
172
|
-
except SystemExit:
|
|
173
|
-
return 1
|
|
174
|
-
except (json.JSONDecodeError, OSError) as exc:
|
|
175
|
-
print(f"write_audit_xml failed: {exc}", file=sys.stderr)
|
|
176
|
-
return 1
|
|
177
|
-
print(output_path)
|
|
178
|
-
return 0
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
if __name__ == "__main__":
|
|
182
|
-
raise SystemExit(main(sys.argv[1:]))
|
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
"""Validate status enum values and write <bugteam_fix> XML at the canonical path.
|
|
2
|
-
|
|
3
|
-
Status enum (canonical source: `ALL_VALID_FIX_STATUSES` in
|
|
4
|
-
`packages/claude-dev-env/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/path_resolver_constants.py`):
|
|
5
|
-
fixed | could_not_address | hook_blocked | unverified_fixed.
|
|
6
|
-
|
|
7
|
-
Each outcome's scalar fields become XML attributes on `<outcome>`; the
|
|
8
|
-
body fields named in `ALL_FIX_OUTCOME_BODY_ELEMENT_KEYS` (currently
|
|
9
|
-
`("reason", "hook_output")`) become child elements.
|
|
10
|
-
|
|
11
|
-
Usage:
|
|
12
|
-
python scripts/write_fix_outcomes.py --pr-number 422 --loop 3 --commit-sha abc1234 --outcomes-json <PATH> --worktree-path <PATH>
|
|
13
|
-
"""
|
|
14
|
-
|
|
15
|
-
from __future__ import annotations
|
|
16
|
-
|
|
17
|
-
import argparse
|
|
18
|
-
import json
|
|
19
|
-
import sys
|
|
20
|
-
from pathlib import Path
|
|
21
|
-
from xml.etree.ElementTree import Element, SubElement
|
|
22
|
-
|
|
23
|
-
_self_dir = Path(__file__).resolve().parent
|
|
24
|
-
if str(_self_dir) not in sys.path:
|
|
25
|
-
sys.path.insert(0, str(_self_dir))
|
|
26
|
-
|
|
27
|
-
from _cli_utils import require_file
|
|
28
|
-
from _path_resolver import fix_outcome_xml_path
|
|
29
|
-
from _xml_utils import emit_pretty_xml
|
|
30
|
-
from skills_pr_loop_constants.path_resolver_constants import (
|
|
31
|
-
ALL_FIX_OUTCOME_BODY_ELEMENT_KEYS,
|
|
32
|
-
ALL_VALID_FIX_STATUSES,
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def validate_fix_statuses(all_outcomes: list[dict[str, object]]) -> list[str]:
|
|
37
|
-
"""Validate that every outcome entry has a recognized status.
|
|
38
|
-
|
|
39
|
-
Args:
|
|
40
|
-
all_outcomes: List of outcome dicts, each expected to have a 'status' key.
|
|
41
|
-
|
|
42
|
-
Returns:
|
|
43
|
-
List of validation error messages (empty when valid).
|
|
44
|
-
"""
|
|
45
|
-
valid_statuses = ALL_VALID_FIX_STATUSES
|
|
46
|
-
errors: list[str] = []
|
|
47
|
-
for each_index, each_outcome in enumerate(all_outcomes):
|
|
48
|
-
status = each_outcome.get("status")
|
|
49
|
-
if not isinstance(status, str):
|
|
50
|
-
errors.append(f"outcome[{each_index}]: status missing or not a string")
|
|
51
|
-
continue
|
|
52
|
-
if status not in valid_statuses:
|
|
53
|
-
errors.append(
|
|
54
|
-
f"outcome[{each_index}]: invalid status '{status}' "
|
|
55
|
-
f"(expected one of {sorted(valid_statuses)})"
|
|
56
|
-
)
|
|
57
|
-
return errors
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
def build_fix_xml(
|
|
61
|
-
*,
|
|
62
|
-
pr_number: int,
|
|
63
|
-
loop: int,
|
|
64
|
-
commit_sha: str,
|
|
65
|
-
outcomes_json_path: Path,
|
|
66
|
-
) -> Element:
|
|
67
|
-
"""Build the <bugteam_fix> XML element from outcomes data.
|
|
68
|
-
|
|
69
|
-
Args:
|
|
70
|
-
pr_number: Pull request number.
|
|
71
|
-
loop: Loop iteration number.
|
|
72
|
-
commit_sha: Commit SHA of the fix commit.
|
|
73
|
-
outcomes_json_path: Path to the outcomes JSON file.
|
|
74
|
-
|
|
75
|
-
Returns:
|
|
76
|
-
Root <bugteam_fix> element.
|
|
77
|
-
|
|
78
|
-
Raises:
|
|
79
|
-
SystemExit: When outcomes-json is not a JSON array of objects, or
|
|
80
|
-
when status validation fails.
|
|
81
|
-
"""
|
|
82
|
-
outcomes_data = json.loads(outcomes_json_path.read_text(encoding="utf-8"))
|
|
83
|
-
if not isinstance(outcomes_data, list):
|
|
84
|
-
print("outcomes-json must contain a JSON array", file=sys.stderr)
|
|
85
|
-
raise SystemExit(1)
|
|
86
|
-
for each_index, each_entry in enumerate(outcomes_data):
|
|
87
|
-
if not isinstance(each_entry, dict):
|
|
88
|
-
print(
|
|
89
|
-
f"outcomes-json[{each_index}]: each entry must be a JSON object",
|
|
90
|
-
file=sys.stderr,
|
|
91
|
-
)
|
|
92
|
-
raise SystemExit(1)
|
|
93
|
-
errors = validate_fix_statuses(outcomes_data)
|
|
94
|
-
if errors:
|
|
95
|
-
for each_error in errors:
|
|
96
|
-
print(each_error, file=sys.stderr)
|
|
97
|
-
raise SystemExit(1)
|
|
98
|
-
|
|
99
|
-
root = Element("bugteam_fix", {
|
|
100
|
-
"pr": str(pr_number),
|
|
101
|
-
"loop": str(loop),
|
|
102
|
-
"commit_sha": commit_sha,
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
all_fix_outcome_body_element_keys = ALL_FIX_OUTCOME_BODY_ELEMENT_KEYS
|
|
106
|
-
outcomes_elem = SubElement(root, "outcomes")
|
|
107
|
-
for each_outcome in outcomes_data:
|
|
108
|
-
outcome_elem = SubElement(outcomes_elem, "outcome")
|
|
109
|
-
for each_key, each_field_detail in each_outcome.items():
|
|
110
|
-
field_text = (
|
|
111
|
-
str(each_field_detail) if each_field_detail is not None else ""
|
|
112
|
-
)
|
|
113
|
-
if each_key in all_fix_outcome_body_element_keys:
|
|
114
|
-
child = SubElement(outcome_elem, each_key)
|
|
115
|
-
child.text = field_text
|
|
116
|
-
else:
|
|
117
|
-
outcome_elem.set(each_key, field_text)
|
|
118
|
-
return root
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
def write_fix_xml(
|
|
122
|
-
*,
|
|
123
|
-
pr_number: int,
|
|
124
|
-
loop: int,
|
|
125
|
-
commit_sha: str,
|
|
126
|
-
outcomes_json_path: Path,
|
|
127
|
-
worktree_path: Path,
|
|
128
|
-
) -> Path:
|
|
129
|
-
"""Write the <bugteam_fix> XML to the canonical outcome path.
|
|
130
|
-
|
|
131
|
-
Args:
|
|
132
|
-
pr_number: Pull request number.
|
|
133
|
-
loop: Loop iteration number.
|
|
134
|
-
commit_sha: Commit SHA of the fix commit.
|
|
135
|
-
outcomes_json_path: Path to the outcomes JSON file.
|
|
136
|
-
worktree_path: Path to the git worktree.
|
|
137
|
-
|
|
138
|
-
Returns:
|
|
139
|
-
Path to the written XML file.
|
|
140
|
-
"""
|
|
141
|
-
root = build_fix_xml(
|
|
142
|
-
pr_number=pr_number,
|
|
143
|
-
loop=loop,
|
|
144
|
-
commit_sha=commit_sha,
|
|
145
|
-
outcomes_json_path=outcomes_json_path,
|
|
146
|
-
)
|
|
147
|
-
xml_string = emit_pretty_xml(root)
|
|
148
|
-
|
|
149
|
-
output_path = fix_outcome_xml_path(worktree_path, pr_number, loop)
|
|
150
|
-
output_path.write_text(xml_string, encoding="utf-8")
|
|
151
|
-
return output_path
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
def parse_arguments(all_argv: list[str]) -> argparse.Namespace:
|
|
155
|
-
"""Parse command-line arguments.
|
|
156
|
-
|
|
157
|
-
Args:
|
|
158
|
-
all_argv: Command-line argument list.
|
|
159
|
-
|
|
160
|
-
Returns:
|
|
161
|
-
Parsed namespace with pr_number, loop, commit_sha, outcomes_json, and worktree_path.
|
|
162
|
-
"""
|
|
163
|
-
parser = argparse.ArgumentParser(description=__doc__)
|
|
164
|
-
parser.add_argument("--pr-number", type=int, required=True)
|
|
165
|
-
parser.add_argument("--loop", type=int, required=True)
|
|
166
|
-
parser.add_argument("--commit-sha", required=True)
|
|
167
|
-
parser.add_argument("--outcomes-json", type=Path, required=True)
|
|
168
|
-
parser.add_argument("--worktree-path", type=Path, required=True)
|
|
169
|
-
return parser.parse_args(all_argv)
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
def main(all_arguments: list[str]) -> int:
|
|
173
|
-
"""Entry point: write <bugteam_fix> XML at the canonical path.
|
|
174
|
-
|
|
175
|
-
Args:
|
|
176
|
-
all_arguments: Command-line arguments.
|
|
177
|
-
|
|
178
|
-
Returns:
|
|
179
|
-
0 on success, 1 on validation or write failure.
|
|
180
|
-
"""
|
|
181
|
-
arguments = parse_arguments(all_arguments)
|
|
182
|
-
outcomes_path = getattr(arguments, "outcomes_json")
|
|
183
|
-
|
|
184
|
-
early_exit = require_file(outcomes_path, "outcomes-json")
|
|
185
|
-
if early_exit is not None:
|
|
186
|
-
return early_exit
|
|
187
|
-
|
|
188
|
-
try:
|
|
189
|
-
output_path = write_fix_xml(
|
|
190
|
-
pr_number=getattr(arguments, "pr_number"),
|
|
191
|
-
loop=arguments.loop,
|
|
192
|
-
commit_sha=getattr(arguments, "commit_sha"),
|
|
193
|
-
outcomes_json_path=outcomes_path,
|
|
194
|
-
worktree_path=getattr(arguments, "worktree_path"),
|
|
195
|
-
)
|
|
196
|
-
except SystemExit:
|
|
197
|
-
return 1
|
|
198
|
-
except (json.JSONDecodeError, OSError) as exc:
|
|
199
|
-
print(f"write_fix_xml failed: {exc}", file=sys.stderr)
|
|
200
|
-
return 1
|
|
201
|
-
print(output_path)
|
|
202
|
-
return 0
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
if __name__ == "__main__":
|
|
206
|
-
raise SystemExit(main(sys.argv[1:]))
|