claude-dev-env 4.2.0 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/agents/pr-description-writer.md +2 -2
- package/.agents/agents/test_agent_frontmatter.py +2 -2
- package/.agents/agents/test_pr_description_writer_style.py +1 -3
- package/.agents/skills/e-code-review/SKILL.md +12 -12
- package/.agents/skills/e-code-review/preflight-proposal.contract.test.mjs +20 -0
- package/.agents/skills/e-code-review/reference/fix.md +15 -17
- package/.agents/skills/e-code-review/reference/loop.md +35 -39
- package/.agents/skills/e-code-review/reference/mode-contract.test.mjs +2 -1
- package/.agents/skills/e-code-review/reference/preflight-proposal.md +44 -9
- package/.agents/skills/e-code-review/reference/runner-selection.md +13 -14
- package/.agents/skills/issue-tracker/SKILL.md +7 -0
- package/.agents/skills/pull-request/SKILL.md +216 -0
- package/.agents/skills/pull-request/reference/publication-tasks.md +18 -0
- package/.agents/skills/pull-request/scripts/github_pr_command_constants/__init__.py +1 -0
- package/.agents/skills/pull-request/scripts/github_pr_command_constants/config/__init__.py +1 -0
- package/.agents/skills/pull-request/scripts/github_pr_command_constants/config/constants.py +69 -0
- package/.agents/skills/pull-request/scripts/pull_request.py +265 -0
- package/.agents/skills/pull-request/scripts/recover_legacy_author.py +251 -0
- package/.agents/skills/pull-request/scripts/test_github_pr_command_constants.py +58 -0
- package/.agents/skills/pull-request/scripts/test_pull_request.py +396 -0
- package/.agents/skills/pull-request/scripts/test_recover_legacy_author.py +221 -0
- package/.agents/skills/skill-builder/SKILL.md +3 -196
- package/.agents/skills/test-runner/SKILL.md +69 -0
- package/.agents/skills/test-runner/scripts/preflight_checks.py +365 -0
- package/.agents/skills/test-runner/scripts/run_tests.py +316 -0
- package/.agents/skills/test-runner/scripts/test_preflight_checks.py +185 -0
- package/.agents/skills/test-runner/scripts/test_run_tests.py +281 -0
- package/.agents/skills/test-runner/scripts/test_runner_constants/__init__.py +1 -0
- package/.agents/skills/test-runner/scripts/test_runner_constants/config/__init__.py +1 -0
- package/.agents/skills/test-runner/scripts/test_runner_constants/config/constants.py +96 -0
- package/.agents/skills-archived/pr-loop-cloud-transport/reference/identity-and-hooks.md +1 -1
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/terminology_sweep_constants.py +6 -0
- package/_shared/pr-loop/scripts/terminology_sweep.py +64 -19
- package/_shared/pr-loop/scripts/tests/test_terminology_sweep.py +59 -0
- package/bin/ever-shipped-skills.mjs +2 -0
- package/bin/ever-shipped-skills.test.mjs +8 -0
- package/bin/install.agents-home.test.mjs +15 -13
- package/bin/install.mjs +37 -1
- package/bin/install.policy-lint.test.mjs +78 -0
- package/bin/install.prune.test.mjs +149 -20
- package/bin/install.pstack-plugin.test.mjs +114 -0
- package/bin/install.test.mjs +61 -7
- package/bin/refresh-pstack-plugin-skills.test.mjs +211 -0
- package/hooks/advisory/pr_done_reminder.py +342 -0
- package/hooks/advisory/test_pr_done_reminder.py +249 -0
- package/hooks/blocking/bash_post_call_dispatcher.py +53 -6
- package/hooks/blocking/code_rules_paired_test.py +22 -15
- package/hooks/blocking/pii_prevention_blocker.py +32 -51
- package/hooks/blocking/test_bash_post_call_dispatcher.py +55 -17
- package/hooks/blocking/test_bash_pre_tool_use_dispatcher.py +1 -4
- package/hooks/blocking/test_code_rules_command_dispatch.py +2 -2
- package/hooks/blocking/test_code_rules_enforcer_paired_test.py +36 -29
- package/hooks/blocking/test_code_rules_js_resume_task_enumeration.py +4 -4
- package/hooks/blocking/test_code_rules_js_returns_object_schemaless.py +5 -5
- package/hooks/blocking/test_pii_prevention_blocker.py +37 -89
- package/hooks/blocking/test_pre_tool_use_dispatcher.py +68 -133
- package/hooks/blocking/test_pre_tool_use_dispatcher_native.py +20 -51
- package/hooks/blocking/test_precommit_code_rules_gate_native_owner.py +18 -18
- package/hooks/gh_post_body_texts.py +195 -0
- package/hooks/git-hooks/git_hooks_constants/staged_policy_lint.py +12 -0
- package/hooks/git-hooks/pre_commit.py +52 -11
- package/hooks/git-hooks/test_installed_policy_lint.py +159 -0
- package/hooks/git-hooks/test_native_policy_commit.py +87 -0
- package/hooks/git-hooks/test_pre_commit.py +246 -0
- package/hooks/hooks.json +1 -16
- package/hooks/hooks_constants/bash_post_call_dispatcher_constants.py +14 -2
- package/hooks/hooks_constants/bash_pre_tool_use_dispatcher_constants.py +0 -8
- package/hooks/hooks_constants/gh_post_body_texts_constants.py +12 -0
- package/hooks/hooks_constants/pr_done_reminder_constants.py +98 -0
- package/hooks/hooks_constants/pre_tool_use_dispatcher_constants.py +10 -43
- package/hooks/hooks_constants/test_bash_post_call_dispatcher_constants.py +17 -7
- package/hooks/hooks_constants/test_bash_pre_tool_use_dispatcher_constants.py +0 -7
- package/hooks/hooks_constants/test_failure_recorder_constants.py +3 -3
- package/hooks/hooks_constants/test_gh_post_body_texts_constants.py +19 -0
- package/hooks/hooks_constants/test_pr_done_reminder_constants.py +40 -0
- package/hooks/hooks_constants/test_pre_tool_use_dispatcher_constants.py +20 -32
- package/hooks/observability/test_failure_recorder.py +1 -1
- package/hooks/pyproject.toml +1 -1
- package/hooks/test_gh_post_body_texts.py +79 -0
- package/package.json +2 -2
- package/rules/durable-post-artifacts.md +32 -20
- package/rules/gh-cli-conventions.md +23 -13
- package/rules/git-workflow.md +21 -8
- package/scripts/check.ps1 +0 -1
- package/{.agents/skills/run-claude-dev-env/driver.mjs → scripts/ci/installer-lifecycle.mjs} +3 -28
- package/scripts/ci/installer-lifecycle.test.mjs +26 -0
- package/scripts/ci/windows-installer-lifecycle.ps1 +1 -11
- package/scripts/dev_env_scripts_constants/shared_tree_constants.py +4 -5
- package/scripts/durable_post_lint.py +206 -0
- package/scripts/durable_post_lint_config/config/constants.py +96 -0
- package/scripts/durable_post_lint_config/config/test_constants.py +25 -0
- package/scripts/policy_lint/adapter_configuration.py +53 -12
- package/scripts/policy_lint/adapter_detectors.py +13 -6
- package/scripts/policy_lint/adapters.py +7 -4
- package/scripts/policy_lint/config/constants.py +5 -0
- package/scripts/policy_lint/engine.py +48 -4
- package/scripts/policy_lint/model.py +1 -0
- package/scripts/policy_lint/registry.py +1 -1
- package/scripts/policy_lint/selection.py +2 -1
- package/scripts/policy_lint/selection_git.py +2 -0
- package/scripts/refresh_pstack_plugin_skills.mjs +200 -0
- package/scripts/repository_checks/config/constants.py +0 -5
- package/scripts/shared_tree_paths.py +32 -3
- package/scripts/test_durable_post_lint.py +332 -0
- package/scripts/test_shared_tree_paths.py +33 -0
- package/scripts/tests/test_adapter_configuration.py +54 -0
- package/scripts/tests/test_policy_lint_rules_archive.py +120 -0
- package/scripts/tests/test_policy_lint_rules_engine.py +25 -4
- package/scripts/tests/test_policy_lint_rules_installed_loader.py +29 -0
- package/scripts/tests/test_policy_lint_rules_registry.py +227 -13
- package/scripts/tests/test_policy_lint_selection.py +25 -2
- package/scripts/tests/test_policy_lint_selection_native_index.py +30 -0
- package/scripts/tests/test_rules.py +3 -7
- package/.agents/skills/_shared/pr-loop/.claude/CLAUDE.md +0 -1
- package/.agents/skills/_shared/pr-loop/AGENTS.md +0 -1
- package/.agents/skills/_shared/pr-loop/audit-contract.md +0 -5
- package/.agents/skills/_shared/pr-loop/audit-reply-template.md +0 -5
- package/.agents/skills/_shared/pr-loop/code-rules-gate.md +0 -5
- package/.agents/skills/_shared/pr-loop/fix-protocol.md +0 -5
- package/.agents/skills/_shared/pr-loop/gh-payloads.md +0 -5
- package/.agents/skills/_shared/pr-loop/portable-driver.md +0 -149
- package/.agents/skills/_shared/pr-loop/post-audit-thread-contract.md +0 -5
- package/.agents/skills/_shared/pr-loop/precatch-rubric.md +0 -5
- package/.agents/skills/_shared/pr-loop/preflight-proposal.contract.test.mjs +0 -119
- package/.agents/skills/_shared/pr-loop/preflight-proposal.md +0 -5
- package/.agents/skills/_shared/pr-loop/prompts/.claude/CLAUDE.md +0 -1
- package/.agents/skills/_shared/pr-loop/prompts/AGENTS.md +0 -1
- package/.agents/skills/_shared/pr-loop/prompts/pr-consistency-audit.xml +0 -324
- package/.agents/skills/_shared/pr-loop/scripts/.claude/CLAUDE.md +0 -1
- package/.agents/skills/_shared/pr-loop/scripts/AGENTS.md +0 -1
- package/.agents/skills/_shared/pr-loop/scripts/RUNTIME_SCRIPTS.md +0 -29
- package/.agents/skills/_shared/pr-loop/scripts/_cli_utils.py +0 -22
- package/.agents/skills/_shared/pr-loop/scripts/_path_resolver.py +0 -186
- package/.agents/skills/_shared/pr-loop/scripts/_xml_utils.py +0 -20
- package/.agents/skills/_shared/pr-loop/scripts/audit_category_schema.py +0 -355
- package/.agents/skills/_shared/pr-loop/scripts/build_audit_prompt.py +0 -289
- package/.agents/skills/_shared/pr-loop/scripts/build_converge_task_list.py +0 -310
- package/.agents/skills/_shared/pr-loop/scripts/build_fix_prompt.py +0 -292
- package/.agents/skills/_shared/pr-loop/scripts/init_loop_state.py +0 -134
- package/.agents/skills/_shared/pr-loop/scripts/portable_converge_driver.py +0 -1646
- package/.agents/skills/_shared/pr-loop/scripts/preflight_worktree.py +0 -392
- package/.agents/skills/_shared/pr-loop/scripts/select_converge_pacer.py +0 -215
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/.claude/CLAUDE.md +0 -1
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/AGENTS.md +0 -1
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/__init__.py +0 -0
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/audit_category_schema_constants.py +0 -37
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/converge_task_list_constants.py +0 -56
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/handoff_constants.py +0 -45
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/pacer_constants.py +0 -47
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/path_resolver_constants.py +0 -157
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/portable_driver_constants.py +0 -177
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/preflight_constants.py +0 -70
- package/.agents/skills/_shared/pr-loop/scripts/teardown_worktrees.py +0 -172
- package/.agents/skills/_shared/pr-loop/scripts/test__path_resolver.py +0 -106
- package/.agents/skills/_shared/pr-loop/scripts/test_audit_category_schema.py +0 -94
- package/.agents/skills/_shared/pr-loop/scripts/test_build_audit_prompt.py +0 -499
- package/.agents/skills/_shared/pr-loop/scripts/test_build_converge_task_list.py +0 -140
- package/.agents/skills/_shared/pr-loop/scripts/test_build_fix_prompt.py +0 -262
- package/.agents/skills/_shared/pr-loop/scripts/test_init_loop_state.py +0 -71
- package/.agents/skills/_shared/pr-loop/scripts/test_portable_converge_driver.py +0 -1119
- package/.agents/skills/_shared/pr-loop/scripts/test_preflight_worktree.py +0 -287
- package/.agents/skills/_shared/pr-loop/scripts/test_select_converge_pacer.py +0 -207
- package/.agents/skills/_shared/pr-loop/scripts/test_teardown_worktrees.py +0 -59
- package/.agents/skills/_shared/pr-loop/scripts/test_write_handoff.py +0 -201
- package/.agents/skills/_shared/pr-loop/scripts/write_audit_outcomes.py +0 -182
- package/.agents/skills/_shared/pr-loop/scripts/write_fix_outcomes.py +0 -206
- package/.agents/skills/_shared/pr-loop/scripts/write_handoff.py +0 -309
- package/.agents/skills/_shared/pr-loop/state-schema.md +0 -5
- package/.agents/skills/_shared/pr-loop/worker-spawn.md +0 -5
- package/.agents/skills/autoconverge/.claude/CLAUDE.md +0 -1
- package/.agents/skills/autoconverge/AGENTS.md +0 -1
- package/.agents/skills/autoconverge/SKILL.md +0 -431
- package/.agents/skills/autoconverge/reference/.claude/CLAUDE.md +0 -1
- package/.agents/skills/autoconverge/reference/AGENTS.md +0 -1
- package/.agents/skills/autoconverge/reference/closing-report.md +0 -93
- package/.agents/skills/autoconverge/reference/convergence-gates.md +0 -31
- package/.agents/skills/autoconverge/reference/convergence.md +0 -219
- package/.agents/skills/autoconverge/reference/copilot-findings.md +0 -51
- package/.agents/skills/autoconverge/reference/gotchas.md +0 -66
- package/.agents/skills/autoconverge/reference/headless-safety.md +0 -44
- package/.agents/skills/autoconverge/reference/multi-pr.md +0 -128
- package/.agents/skills/autoconverge/reference/self-closing-loop.md +0 -84
- package/.agents/skills/autoconverge/reference/stop-conditions.md +0 -127
- package/.agents/skills/autoconverge/test_portable_pacer_gate.py +0 -54
- package/.agents/skills/autoconverge/workflow/.claude/CLAUDE.md +0 -1
- package/.agents/skills/autoconverge/workflow/AGENTS.md +0 -1
- package/.agents/skills/autoconverge/workflow/aggregate_runs.py +0 -371
- package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/.claude/CLAUDE.md +0 -1
- package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/AGENTS.md +0 -1
- package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/__init__.py +0 -0
- package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/render_report_constants.py +0 -250
- package/.agents/skills/autoconverge/workflow/converge.clean-audit.test.mjs +0 -665
- package/.agents/skills/autoconverge/workflow/converge.codex-gate.test.mjs +0 -472
- package/.agents/skills/autoconverge/workflow/converge.contract.test.mjs +0 -64
- package/.agents/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +0 -1009
- package/.agents/skills/autoconverge/workflow/converge.fix-progress.test.mjs +0 -107
- package/.agents/skills/autoconverge/workflow/converge.fix-recovery.test.mjs +0 -33
- package/.agents/skills/autoconverge/workflow/converge.merge-conflict.test.mjs +0 -15
- package/.agents/skills/autoconverge/workflow/converge.mjs +0 -3132
- package/.agents/skills/autoconverge/workflow/converge.p2-advance.test.mjs +0 -202
- package/.agents/skills/autoconverge/workflow/converge.path-aware.test.mjs +0 -47
- package/.agents/skills/autoconverge/workflow/converge.precatch.test.mjs +0 -152
- package/.agents/skills/autoconverge/workflow/converge.run-input.test.mjs +0 -116
- package/.agents/skills/autoconverge/workflow/converge_multi.mjs +0 -169
- package/.agents/skills/autoconverge/workflow/converge_multi.run-input.test.mjs +0 -173
- package/.agents/skills/autoconverge/workflow/convergence_summary.py +0 -110
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a11d903476b803493.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a26213978adeef6fb.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a3def0d15ed9d9110.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a41f41b1b708ee3b7.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a758b880abecc3ff7.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a8897b89656b1bd16.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-ab1c2d3e4f5a6b7c8.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-abd463d744a1437bc.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-ad19d027ae8ee1816.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/workflows/wf_881252e6-700.json +0 -266
- package/.agents/skills/autoconverge/workflow/render_report.py +0 -1024
- package/.agents/skills/autoconverge/workflow/test_aggregate_runs.py +0 -134
- package/.agents/skills/autoconverge/workflow/test_convergence_summary.py +0 -149
- package/.agents/skills/autoconverge/workflow/test_render_report.py +0 -812
- package/.agents/skills/hitl/SKILL.md +0 -45
- package/.agents/skills/pr-cleanup/SKILL.md +0 -140
- package/.agents/skills/pr-cleanup/reference/process-inventory.md +0 -17
- package/.agents/skills/pr-cleanup/reference/task-seeds.md +0 -22
- package/.agents/skills/pr-name-by-capability/SKILL.md +0 -73
- package/.agents/skills/pr-name-by-capability/reference/fetch-commands.md +0 -29
- package/.agents/skills/pr-name-by-capability/reference/offense-examples.md +0 -32
- package/.agents/skills/pr-name-by-capability/reference/report-template.md +0 -29
- package/.agents/skills/pr-name-by-capability/reference/rule-checklist.md +0 -38
- package/.agents/skills/pr-name-by-capability/reference/task-seeds.md +0 -10
- package/.agents/skills/pr-plain-language-cleanup/SKILL.md +0 -93
- package/.agents/skills/pr-refinement/SKILL.md +0 -31
- package/.agents/skills/pr-shared-extraction/SKILL.md +0 -177
- package/.agents/skills/pr-shared-extraction/reference/examples.md +0 -46
- package/.agents/skills/pr-shared-extraction/reference/offense-taxonomy.md +0 -100
- package/.agents/skills/pr-small-cl/SKILL.md +0 -52
- package/.agents/skills/pr-title-description/SKILL.md +0 -96
- package/.agents/skills/prototype/SKILL.md +0 -85
- package/.agents/skills/prototype/reference/honest-limitations.md +0 -23
- package/.agents/skills/prototype/reference/promotion-tasks.md +0 -23
- package/.agents/skills/prototype/scripts/build_sandbox_settings.py +0 -249
- package/.agents/skills/prototype/scripts/conftest.py +0 -15
- package/.agents/skills/prototype/scripts/launch_sandbox.py +0 -205
- package/.agents/skills/prototype/scripts/probe_sandbox_safety.py +0 -311
- package/.agents/skills/prototype/scripts/prototype_scripts_constants/__init__.py +0 -1
- package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/__init__.py +0 -0
- package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/build_sandbox_settings_constants.py +0 -41
- package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/launch_sandbox_constants.py +0 -23
- package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/probe_sandbox_safety_constants.py +0 -45
- package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/prototype_common_constants.py +0 -10
- package/.agents/skills/prototype/scripts/test_build_sandbox_settings.py +0 -275
- package/.agents/skills/prototype/scripts/test_launch_sandbox.py +0 -303
- package/.agents/skills/prototype/scripts/test_probe_sandbox_safety.py +0 -312
- package/.agents/skills/prototype/workflows/promotion.md +0 -25
- package/.agents/skills/prototype/workflows/sandbox.md +0 -35
- package/.agents/skills/rebase/.claude/CLAUDE.md +0 -1
- package/.agents/skills/rebase/AGENTS.md +0 -1
- package/.agents/skills/rebase/SKILL.md +0 -178
- package/.agents/skills/review-router/SKILL.md +0 -51
- package/.agents/skills/review-router/reference/route-policy.json +0 -7
- package/.agents/skills/review-router/reference/task-seeds.md +0 -1
- package/.agents/skills/review-router/scripts/conftest.py +0 -4
- package/.agents/skills/review-router/scripts/review_router.py +0 -50
- package/.agents/skills/review-router/scripts/review_router_cli.py +0 -211
- package/.agents/skills/review-router/scripts/review_router_constants/__init__.py +0 -1
- package/.agents/skills/review-router/scripts/review_router_constants/config/__init__.py +0 -0
- package/.agents/skills/review-router/scripts/review_router_constants/config/constants.py +0 -13
- package/.agents/skills/review-router/scripts/test_review_router.py +0 -23
- package/.agents/skills/review-router/scripts/test_review_router_cli.py +0 -47
- package/.agents/skills/review-tier/SKILL.md +0 -56
- package/.agents/skills/review-tier/reference/task-seeds.md +0 -1
- package/.agents/skills/review-tier/reference/tier-policy.json +0 -9
- package/.agents/skills/review-tier/scripts/conftest.py +0 -4
- package/.agents/skills/review-tier/scripts/review_tier.py +0 -359
- package/.agents/skills/review-tier/scripts/review_tier_constants/__init__.py +0 -1
- package/.agents/skills/review-tier/scripts/review_tier_constants/config/__init__.py +0 -0
- package/.agents/skills/review-tier/scripts/review_tier_constants/config/constants.py +0 -29
- package/.agents/skills/review-tier/scripts/test_generation.py +0 -159
- package/.agents/skills/review-tier/scripts/test_review_tier.py +0 -33
- package/.agents/skills/run-claude-dev-env/SKILL.md +0 -84
- package/.agents/skills/session-log/.claude/CLAUDE.md +0 -1
- package/.agents/skills/session-log/AGENTS.md +0 -1
- package/.agents/skills/session-log/SKILL.md +0 -170
- package/.agents/skills/session-log/templates/frontmatter.md +0 -40
- package/.agents/skills/session-tidy/.claude/CLAUDE.md +0 -1
- package/.agents/skills/session-tidy/AGENTS.md +0 -1
- package/.agents/skills/session-tidy/SKILL.md +0 -191
- package/.agents/skills/skill-builder/references/.claude/CLAUDE.md +0 -1
- package/.agents/skills/skill-builder/references/AGENTS.md +0 -1
- package/.agents/skills/skill-builder/references/delegation-map.md +0 -130
- package/.agents/skills/skill-builder/references/description-field.md +0 -111
- package/.agents/skills/skill-builder/references/deterministic-elements.md +0 -218
- package/.agents/skills/skill-builder/references/progressive-disclosure.md +0 -122
- package/.agents/skills/skill-builder/references/self-audit-checklist.md +0 -126
- package/.agents/skills/skill-builder/references/skill-modularity.md +0 -111
- package/.agents/skills/skill-builder/references/skill-types.md +0 -232
- package/.agents/skills/skill-builder/references/thariq-x-post-skills.json +0 -33
- package/.agents/skills/skill-builder/templates/.claude/CLAUDE.md +0 -1
- package/.agents/skills/skill-builder/templates/AGENTS.md +0 -1
- package/.agents/skills/skill-builder/templates/gap-analysis.md +0 -87
- package/.agents/skills/skill-builder/workflows/.claude/CLAUDE.md +0 -1
- package/.agents/skills/skill-builder/workflows/AGENTS.md +0 -1
- package/.agents/skills/skill-builder/workflows/improve-skill.md +0 -136
- package/.agents/skills/skill-builder/workflows/new-skill.md +0 -179
- package/.agents/skills/skill-builder/workflows/polish-skill.md +0 -139
- package/.agents/skills/source-command-sr-loop/SKILL.md +0 -82
- package/.agents/skills/update/.claude/CLAUDE.md +0 -1
- package/.agents/skills/update/AGENTS.md +0 -1
- package/.agents/skills/update/SKILL.md +0 -190
- package/_shared/pr-loop/AGENTS.md +0 -1
- package/_shared/pr-loop/CLAUDE.md +0 -1
- package/_shared/pr-loop/audit-contract.md +0 -183
- package/_shared/pr-loop/audit-reply-template.md +0 -151
- package/_shared/pr-loop/code-rules-gate.md +0 -65
- package/_shared/pr-loop/fix-protocol.md +0 -60
- package/_shared/pr-loop/gh-payloads.md +0 -75
- package/_shared/pr-loop/post-audit-thread-contract.md +0 -51
- package/_shared/pr-loop/precatch-rubric.md +0 -66
- package/_shared/pr-loop/preflight-proposal.md +0 -56
- package/_shared/pr-loop/scripts/post_audit_thread.py +0 -1242
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/post_audit_thread_constants.py +0 -199
- package/_shared/pr-loop/scripts/tests/test_post_audit_thread.py +0 -1115
- package/_shared/pr-loop/scripts/tests/test_post_audit_thread_constants.py +0 -129
- package/_shared/pr-loop/state-schema.md +0 -45
- package/_shared/pr-loop/worker-spawn.md +0 -189
- package/hooks/_gh_pr_author_swap_utils.py +0 -1225
- package/hooks/blocking/conventional_pr_title_gate.py +0 -443
- package/hooks/blocking/gh_body_arg_blocker.py +0 -176
- package/hooks/blocking/gh_pr_author_enforcer.py +0 -487
- package/hooks/blocking/gh_pr_author_restore.py +0 -105
- package/hooks/blocking/pr_description_writer_gate.py +0 -256
- package/hooks/blocking/test_conventional_pr_title_gate.py +0 -640
- package/hooks/blocking/test_gh_body_arg_blocker.py +0 -441
- package/hooks/blocking/test_gh_pr_author_enforcer.py +0 -1166
- package/hooks/blocking/test_gh_pr_author_restore.py +0 -513
- package/hooks/blocking/test_gh_pr_author_swap_utils.py +0 -910
- package/hooks/blocking/test_pr_description_writer_gate.py +0 -234
- package/hooks/blocking/test_preflight_check.py +0 -343
- package/hooks/blocking/test_test_preflight_check.py +0 -80
- package/hooks/blocking/test_volatile_path_in_post_blocker.py +0 -322
- package/hooks/blocking/volatile_path_in_post_blocker.py +0 -461
- package/hooks/hooks_constants/conventional_pr_title_gate_constants.py +0 -58
- package/hooks/hooks_constants/gh_pr_author_swap_constants.py +0 -76
- package/hooks/hooks_constants/pr_description_writer_gate_constants.py +0 -73
- package/hooks/hooks_constants/volatile_path_in_post_blocker_constants.py +0 -55
- package/hooks/observability/pr_description_writer_spawn_tracker.py +0 -113
- package/hooks/observability/test_pr_description_writer_spawn_tracker.py +0 -150
- package/hooks/session/gh_pr_author_session_cleanup.py +0 -175
- package/hooks/session/test_gh_pr_author_session_cleanup.py +0 -576
- package/hooks/test__gh_pr_author_swap_utils.py +0 -333
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
"""Contract tests for explicit legacy GitHub author recovery."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import os
|
|
7
|
+
import stat
|
|
8
|
+
import subprocess
|
|
9
|
+
import sys
|
|
10
|
+
from collections.abc import Callable
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from unittest.mock import Mock
|
|
13
|
+
|
|
14
|
+
import pytest
|
|
15
|
+
|
|
16
|
+
_SCRIPTS_DIRECTORY = Path(__file__).resolve().parent
|
|
17
|
+
if str(_SCRIPTS_DIRECTORY) not in sys.path:
|
|
18
|
+
sys.path.insert(0, str(_SCRIPTS_DIRECTORY))
|
|
19
|
+
|
|
20
|
+
import recover_legacy_author
|
|
21
|
+
|
|
22
|
+
CURRENT_TIME_SECONDS = 2_000_000.0
|
|
23
|
+
CURRENT_USER_ID = 41
|
|
24
|
+
LEGACY_ACCOUNT = "previous-account"
|
|
25
|
+
OTHER_ACCOUNT = "other-account"
|
|
26
|
+
STATE_FILENAME = "gh_pr_author_swap_session-a.json"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _completion(
|
|
30
|
+
code: int = 0, stdout: str = "", stderr: str = ""
|
|
31
|
+
) -> subprocess.CompletedProcess[str]:
|
|
32
|
+
return subprocess.CompletedProcess([], code, stdout, stderr)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _write_state(
|
|
36
|
+
directory: Path,
|
|
37
|
+
*,
|
|
38
|
+
filename: str = STATE_FILENAME,
|
|
39
|
+
payload: object | None = None,
|
|
40
|
+
age_seconds: float = 1801.0,
|
|
41
|
+
) -> Path:
|
|
42
|
+
state_file = directory / filename
|
|
43
|
+
state_payload = {"original_account": LEGACY_ACCOUNT} if payload is None else payload
|
|
44
|
+
state_file.write_text(json.dumps(state_payload), encoding="utf-8")
|
|
45
|
+
os.utime(
|
|
46
|
+
state_file,
|
|
47
|
+
(CURRENT_TIME_SECONDS - age_seconds, CURRENT_TIME_SECONDS - age_seconds),
|
|
48
|
+
)
|
|
49
|
+
if hasattr(os, "getuid"):
|
|
50
|
+
state_file.chmod(0o600)
|
|
51
|
+
return state_file
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _run(
|
|
55
|
+
state_file: Path,
|
|
56
|
+
command_runner: Callable[..., subprocess.CompletedProcess[str]],
|
|
57
|
+
*,
|
|
58
|
+
confirm_inactive: bool = True,
|
|
59
|
+
) -> int:
|
|
60
|
+
all_arguments = [str(state_file)]
|
|
61
|
+
if confirm_inactive:
|
|
62
|
+
all_arguments.append("--confirm-inactive")
|
|
63
|
+
return recover_legacy_author.main(
|
|
64
|
+
all_arguments,
|
|
65
|
+
now_seconds=CURRENT_TIME_SECONDS,
|
|
66
|
+
current_user_id=os.getuid() if hasattr(os, "getuid") else None,
|
|
67
|
+
command_runner=command_runner,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def test_success_restores_selected_record_and_preserves_neighbor(
|
|
72
|
+
tmp_path: Path,
|
|
73
|
+
) -> None:
|
|
74
|
+
selected_file = _write_state(tmp_path)
|
|
75
|
+
neighbor_file = _write_state(
|
|
76
|
+
tmp_path,
|
|
77
|
+
filename="gh_pr_author_swap_session-b.json",
|
|
78
|
+
payload={"original_account": OTHER_ACCOUNT},
|
|
79
|
+
)
|
|
80
|
+
command_runner = Mock(return_value=_completion())
|
|
81
|
+
assert _run(selected_file, command_runner) == 0
|
|
82
|
+
command_runner.assert_called_once_with(
|
|
83
|
+
["gh", "auth", "switch", "--user", LEGACY_ACCOUNT],
|
|
84
|
+
capture_output=True,
|
|
85
|
+
check=False,
|
|
86
|
+
shell=False,
|
|
87
|
+
text=True,
|
|
88
|
+
)
|
|
89
|
+
assert not selected_file.exists()
|
|
90
|
+
assert neighbor_file.exists()
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def test_unconfirmed_record_is_unresolved_without_side_effects(
|
|
94
|
+
tmp_path: Path, capsys: pytest.CaptureFixture[str]
|
|
95
|
+
) -> None:
|
|
96
|
+
state_file = _write_state(tmp_path)
|
|
97
|
+
command_runner = Mock()
|
|
98
|
+
assert _run(state_file, command_runner, confirm_inactive=False) == 3
|
|
99
|
+
assert "confirm inactive" in capsys.readouterr().err
|
|
100
|
+
command_runner.assert_not_called()
|
|
101
|
+
assert state_file.exists()
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def test_active_record_is_rejected_without_side_effects(
|
|
105
|
+
tmp_path: Path, capsys: pytest.CaptureFixture[str]
|
|
106
|
+
) -> None:
|
|
107
|
+
state_file = _write_state(tmp_path, age_seconds=10.0)
|
|
108
|
+
command_runner = Mock()
|
|
109
|
+
assert _run(state_file, command_runner) == 2
|
|
110
|
+
assert "record is active" in capsys.readouterr().err
|
|
111
|
+
command_runner.assert_not_called()
|
|
112
|
+
assert state_file.exists()
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@pytest.mark.parametrize(
|
|
116
|
+
"payload",
|
|
117
|
+
[
|
|
118
|
+
[],
|
|
119
|
+
{},
|
|
120
|
+
{"original_account": ""},
|
|
121
|
+
{"original_account": 7},
|
|
122
|
+
{"original_account": LEGACY_ACCOUNT, "extra": True},
|
|
123
|
+
],
|
|
124
|
+
)
|
|
125
|
+
def test_invalid_schema_is_rejected(
|
|
126
|
+
tmp_path: Path, payload: object, capsys: pytest.CaptureFixture[str]
|
|
127
|
+
) -> None:
|
|
128
|
+
state_file = _write_state(tmp_path, payload=payload)
|
|
129
|
+
command_runner = Mock()
|
|
130
|
+
assert _run(state_file, command_runner) == 2
|
|
131
|
+
assert "record is invalid" in capsys.readouterr().err
|
|
132
|
+
command_runner.assert_not_called()
|
|
133
|
+
assert state_file.exists()
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def test_invalid_utf8_is_rejected(tmp_path: Path) -> None:
|
|
137
|
+
state_file = _write_state(tmp_path)
|
|
138
|
+
state_file.write_bytes(b"\xff")
|
|
139
|
+
os.utime(state_file, (CURRENT_TIME_SECONDS - 1801, CURRENT_TIME_SECONDS - 1801))
|
|
140
|
+
command_runner = Mock()
|
|
141
|
+
assert _run(state_file, command_runner) == 2
|
|
142
|
+
command_runner.assert_not_called()
|
|
143
|
+
assert state_file.exists()
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def test_wrong_filename_is_rejected(tmp_path: Path) -> None:
|
|
147
|
+
state_file = _write_state(tmp_path, filename="other.json")
|
|
148
|
+
command_runner = Mock()
|
|
149
|
+
assert _run(state_file, command_runner) == 2
|
|
150
|
+
command_runner.assert_not_called()
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def test_symlink_is_rejected(tmp_path: Path) -> None:
|
|
154
|
+
target_file = _write_state(tmp_path)
|
|
155
|
+
link_file = tmp_path / "gh_pr_author_swap_link.json"
|
|
156
|
+
try:
|
|
157
|
+
link_file.symlink_to(target_file)
|
|
158
|
+
except OSError as error:
|
|
159
|
+
pytest.skip(f"symlink unavailable: {error}")
|
|
160
|
+
command_runner = Mock()
|
|
161
|
+
assert _run(link_file, command_runner) == 2
|
|
162
|
+
command_runner.assert_not_called()
|
|
163
|
+
assert target_file.exists()
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def test_failed_restore_preserves_record_and_hides_child_output(
|
|
167
|
+
tmp_path: Path, capsys: pytest.CaptureFixture[str]
|
|
168
|
+
) -> None:
|
|
169
|
+
state_file = _write_state(tmp_path)
|
|
170
|
+
command_runner = Mock(
|
|
171
|
+
return_value=_completion(1, LEGACY_ACCOUNT, f"unsafe {LEGACY_ACCOUNT}")
|
|
172
|
+
)
|
|
173
|
+
assert _run(state_file, command_runner) == 1
|
|
174
|
+
captured = capsys.readouterr()
|
|
175
|
+
assert captured.err == "error: GitHub account restore failed\n"
|
|
176
|
+
assert LEGACY_ACCOUNT not in captured.out + captured.err
|
|
177
|
+
assert state_file.exists()
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def test_restore_launch_failure_preserves_record(
|
|
181
|
+
tmp_path: Path, capsys: pytest.CaptureFixture[str]
|
|
182
|
+
) -> None:
|
|
183
|
+
state_file = _write_state(tmp_path)
|
|
184
|
+
command_runner = Mock(side_effect=OSError("unavailable"))
|
|
185
|
+
assert _run(state_file, command_runner) == 1
|
|
186
|
+
assert capsys.readouterr().err == "error: GitHub account restore failed\n"
|
|
187
|
+
assert state_file.exists()
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def test_changed_record_after_restore_is_preserved(
|
|
191
|
+
tmp_path: Path, capsys: pytest.CaptureFixture[str]
|
|
192
|
+
) -> None:
|
|
193
|
+
state_file = _write_state(tmp_path)
|
|
194
|
+
|
|
195
|
+
def change_record(
|
|
196
|
+
all_arguments: list[str], **keyword_arguments: object
|
|
197
|
+
) -> subprocess.CompletedProcess[str]:
|
|
198
|
+
state_file.write_text(
|
|
199
|
+
json.dumps({"original_account": OTHER_ACCOUNT}), encoding="utf-8"
|
|
200
|
+
)
|
|
201
|
+
return _completion()
|
|
202
|
+
|
|
203
|
+
assert _run(state_file, change_record) == 1
|
|
204
|
+
assert "record changed" in capsys.readouterr().err
|
|
205
|
+
assert state_file.exists()
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def test_secure_posix_metadata_requires_regular_owner_mode() -> None:
|
|
209
|
+
regular_secure_mode = stat.S_IFREG | 0o600
|
|
210
|
+
assert recover_legacy_author._posix_metadata_is_secure(
|
|
211
|
+
regular_secure_mode, CURRENT_USER_ID, CURRENT_USER_ID
|
|
212
|
+
)
|
|
213
|
+
assert not recover_legacy_author._posix_metadata_is_secure(
|
|
214
|
+
regular_secure_mode, CURRENT_USER_ID + 1, CURRENT_USER_ID
|
|
215
|
+
)
|
|
216
|
+
assert not recover_legacy_author._posix_metadata_is_secure(
|
|
217
|
+
stat.S_IFREG | 0o644, CURRENT_USER_ID, CURRENT_USER_ID
|
|
218
|
+
)
|
|
219
|
+
assert not recover_legacy_author._posix_metadata_is_secure(
|
|
220
|
+
stat.S_IFLNK | 0o600, CURRENT_USER_ID, CURRENT_USER_ID
|
|
221
|
+
)
|
|
@@ -1,202 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: skill-builder
|
|
3
3
|
disable-model-invocation: true
|
|
4
|
-
description:
|
|
5
|
-
Skill lifecycle: classify, scaffold, write via the skill-writer-agent, self-audit, compose
|
|
6
|
-
sub-skills, polish description triggers, enforce deterministic scripts. Triggers:
|
|
7
|
-
build a skill, new skill workflow, improve this skill, optimize skill description,
|
|
8
|
-
skill development lifecycle, skill modularity, skill composition, description
|
|
9
|
-
trigger catalog, deterministic skill scripts.
|
|
4
|
+
description: Placeholder for the skill-builder rework to follow pstack philosophy.
|
|
10
5
|
---
|
|
11
6
|
|
|
12
|
-
# Skill
|
|
7
|
+
# Skill builder
|
|
13
8
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
Sources: [Anthropic best practices](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices), [Lessons from Building Claude Code](references/thariq-x-post-skills.json), model skills (bugteam, pr-converge).
|
|
17
|
-
|
|
18
|
-
## Gotchas
|
|
19
|
-
|
|
20
|
-
Highest-signal content. Append a bullet each time a skill build fails in a new way.
|
|
21
|
-
|
|
22
|
-
> "The highest-signal content in any skill is the Gotchas section. These sections should be built up from common failure points that Claude runs into when using your skill."
|
|
23
|
-
|
|
24
|
-
- Story-form `description` burns always-on context and weakens selection — rewrite to capability stem + `Triggers:` list (`description-field.md`).
|
|
25
|
-
- Multi-capability packages fail modularity audit — split or thin orchestrator + named sub-skills (`skill-modularity.md`).
|
|
26
|
-
- Skipping the composition plan before Write reintroduces silent reimplementation of peer skills.
|
|
27
|
-
- Deterministic steps written only as prose (fenced source, giant `rg` lines, multi-step mechanical sequences) fail audit — extract to `scripts/` / `workflow/` / `templates/` / `reference/` (`deterministic-elements.md`).
|
|
28
|
-
- Markdown `- [ ]` checklists as the agent's progress board fail audit when a task tool exists — seed tasks via `TaskCreate` / `TodoWrite` (`deterministic-elements.md`).
|
|
29
|
-
|
|
30
|
-
## When this skill applies
|
|
31
|
-
|
|
32
|
-
Trigger for requests to **build**, **improve**, or **polish** a skill. This skill orchestrates the process — it classifies, scaffolds, gathers context, delegates writing to the `skill-writer-agent` agent, and self-audits the result.
|
|
33
|
-
|
|
34
|
-
For quick skill syntax questions or one-off SKILL.md edits, spawn the `skill-writer-agent` agent directly.
|
|
35
|
-
|
|
36
|
-
**Refusal cases — first match wins:**
|
|
37
|
-
|
|
38
|
-
- **No clear task or domain.** Respond exactly: `What should this skill do? Give me a one-sentence description of the capability.`
|
|
39
|
-
|
|
40
|
-
## The Process
|
|
41
|
-
|
|
42
|
-
Each workflow file provides step-by-step instructions. After routing below, open the corresponding workflow file and follow it.
|
|
43
|
-
|
|
44
|
-
### Routing
|
|
45
|
-
|
|
46
|
-
Assess the user’s intent:
|
|
47
|
-
|
|
48
|
-
**Creating a new skill?**
|
|
49
|
-
Read `${CLAUDE_SKILL_DIR}/workflows/new-skill.md` and follow it.
|
|
50
|
-
|
|
51
|
-
**Improving an existing skill?**
|
|
52
|
-
Read `${CLAUDE_SKILL_DIR}/workflows/improve-skill.md` and follow it.
|
|
53
|
-
|
|
54
|
-
**Final polish only (description optimization, trigger audit)?**
|
|
55
|
-
Read `${CLAUDE_SKILL_DIR}/workflows/polish-skill.md` and follow it.
|
|
56
|
-
|
|
57
|
-
**Ambiguous?** Ask: "Are you creating a new skill, improving an existing one, or doing a final polish pass?"
|
|
58
|
-
|
|
59
|
-
### The Claude A / Claude B pattern
|
|
60
|
-
|
|
61
|
-
You and the user are **Claude A** — the expert who designs and refines the skill. Subagents running the built skill on real tasks are **Claude B** — the agent using the skill to perform actual work.
|
|
62
|
-
|
|
63
|
-
> "Work with one instance of Claude (‘Claude A’) to create a Skill that is used by other instances (‘Claude B’). Claude A helps you design and refine instructions, while Claude B tests them in real tasks."
|
|
64
|
-
|
|
65
|
-
The feedback loop: observe Claude B’s behavior, bring insights back, refine the skill, test again.
|
|
66
|
-
|
|
67
|
-
## Skill type routing
|
|
68
|
-
|
|
69
|
-
> "After cataloging all of our skills, we noticed they cluster into a few recurring categories."
|
|
70
|
-
|
|
71
|
-
Classify into one of 9 types — type sets folder structure. Taxonomy and layouts: [`references/skill-types.md`](references/skill-types.md).
|
|
72
|
-
|
|
73
|
-
## Principles
|
|
74
|
-
|
|
75
|
-
These are non-negotiable. Every skill must satisfy them. Enforce via [`references/self-audit-checklist.md`](references/self-audit-checklist.md).
|
|
76
|
-
|
|
77
|
-
### Concision and defaults
|
|
78
|
-
|
|
79
|
-
> "Default assumption: Claude is already very smart. Only add context Claude doesn’t already have."
|
|
80
|
-
|
|
81
|
-
> "Don’t State the Obvious — focus on information that pushes Claude out of its normal way of thinking."
|
|
82
|
-
|
|
83
|
-
Challenge each sentence: "Does Claude really need this?"
|
|
84
|
-
|
|
85
|
-
### Degree of freedom
|
|
86
|
-
|
|
87
|
-
> "Match the level of specificity to the task’s fragility and variability."
|
|
88
|
-
|
|
89
|
-
High freedom (text guidance) for open fields. Low freedom (exact scripts, no parameters) for narrow bridges with cliffs.
|
|
90
|
-
|
|
91
|
-
> "Avoid Railroading Claude — give Claude the information it needs, but give it the flexibility to adapt."
|
|
92
|
-
|
|
93
|
-
### Progressive disclosure
|
|
94
|
-
|
|
95
|
-
Hub pattern, line caps, one-level references, TOC and path rules: [`references/progressive-disclosure.md`](references/progressive-disclosure.md).
|
|
96
|
-
|
|
97
|
-
### Modularity and composition
|
|
98
|
-
|
|
99
|
-
One skill = one capability. Multi-step work invokes **sub-skills** (peer skills) by name. Prefer compose over reimplement. Full rules: [`references/skill-modularity.md`](references/skill-modularity.md).
|
|
100
|
-
|
|
101
|
-
> "You can just reference other skills by name, and the model will invoke them if they are installed."
|
|
102
|
-
|
|
103
|
-
New-skill Gather records a composition plan before write. Self-audit modularity items are mandatory.
|
|
104
|
-
|
|
105
|
-
### Description field (trigger catalog)
|
|
106
|
-
|
|
107
|
-
The frontmatter `description` is **selection metadata** pre-loaded for every skill. Write a **trigger catalog**, not a story: short capability stem + concrete trigger phrases. No narrative, benefits language, or process dump.
|
|
108
|
-
|
|
109
|
-
Full rules: [`references/description-field.md`](references/description-field.md). Polish workflow Step 1 is the dedicated rewrite pass.
|
|
110
|
-
|
|
111
|
-
> "The description field is not a summary — it’s a description of when to trigger."
|
|
112
|
-
|
|
113
|
-
### Gotchas
|
|
114
|
-
|
|
115
|
-
Mandatory highest-signal section (see Gotchas above). Capture real failure modes; self-audit requires the section present and actionable.
|
|
116
|
-
|
|
117
|
-
### Templates and examples
|
|
118
|
-
|
|
119
|
-
> "Provide templates for output format" and "Examples help Claude understand the desired style and level of detail more clearly than descriptions alone."
|
|
120
|
-
|
|
121
|
-
Use the template pattern for structured outputs. Use the examples pattern (input/output pairs) for style-dependent work.
|
|
122
|
-
|
|
123
|
-
### Workflows and task seeds
|
|
124
|
-
|
|
125
|
-
Multi-step required work is a **task seed list** (plain bullets in a reference file) plus an instruction to register each item on the host task tool (`TaskCreate`, `TodoWrite`, or equivalent). Agents work the task list and mark complete with evidence.
|
|
126
|
-
|
|
127
|
-
Do **not** ship markdown `- [ ]` boards as the completion protocol when a task tool is available. Do **not** say "copy this checklist into your response and check it off."
|
|
128
|
-
|
|
129
|
-
Quality-critical operations still use feedback loops (run validator → fix → repeat). Spec: [`references/deterministic-elements.md`](references/deterministic-elements.md) (Task-tool tracking).
|
|
130
|
-
|
|
131
|
-
### Scripts
|
|
132
|
-
|
|
133
|
-
> "Handle error conditions rather than punting to Claude." "Make clear whether Claude should execute the script or read it as reference."
|
|
134
|
-
|
|
135
|
-
> "One of the most powerful tools you can give Claude is code — letting Claude spend its turns on composition rather than reconstructing boilerplate."
|
|
136
|
-
|
|
137
|
-
### Deterministic elements (mandatory classification)
|
|
138
|
-
|
|
139
|
-
Any skill element that is **deterministic** (same inputs → same outputs; machine-checkable success) ships as code, a fixed artifact, or a **session task seed** — not prose-only steps or markdown checkbox boards. Judgment, routing, and refusals stay in markdown.
|
|
140
|
-
|
|
141
|
-
Full rules, inventory table, task-tool tracking, CODE_RULES bar for skill scripts, and anti-patterns: [`references/deterministic-elements.md`](references/deterministic-elements.md).
|
|
142
|
-
|
|
143
|
-
New-skill Gather records a deterministic-elements inventory before write. Self-audit items register as session tasks and are mandatory on every delivery (pure-judgment skills mark script rows N/A with evidence).
|
|
144
|
-
|
|
145
|
-
### Setup and memory
|
|
146
|
-
|
|
147
|
-
> "Think through the Setup — some skills may need to be set up with context from the user. A good pattern is to store this in a config.json file."
|
|
148
|
-
|
|
149
|
-
> "Data stored in the skill directory may be deleted when you upgrade the skill, so store persistent data in `${CLAUDE_PLUGIN_DATA}`."
|
|
150
|
-
|
|
151
|
-
### Constraints and refusal cases
|
|
152
|
-
|
|
153
|
-
> bugteam pattern — non-negotiables separated from guidance, with design rationale. Explicit "first match wins" refusal conditions.
|
|
154
|
-
|
|
155
|
-
### Anti-patterns
|
|
156
|
-
|
|
157
|
-
> No Windows paths. Don’t offer too many options — provide a default with escape hatch. Avoid time-sensitive claims. Use consistent terminology. No deeply nested references.
|
|
158
|
-
|
|
159
|
-
Also: story-form descriptions; monolith multi-capability skills; silent reimplementation of peer skills; nested folders used as fake sub-skills; deterministic logic only in prose or fenced source; markdown `- [ ]` as the agent's work tracker.
|
|
160
|
-
|
|
161
|
-
## Self-audit
|
|
162
|
-
|
|
163
|
-
After every build, improvement, or polish pass, load `${CLAUDE_SKILL_DIR}/references/self-audit-checklist.md`, **register every bullet as a session task**, and complete each with evidence. Every item must pass before delivery. Fix failures, then re-audit.
|
|
164
|
-
|
|
165
|
-
## Delegation to skill-writer-agent
|
|
166
|
-
|
|
167
|
-
skill-builder orchestrates; the `skill-writer-agent` agent authors. The caller spawns it with `Agent(subagent_type="skill-writer-agent", ...)`. The handoff packet from Step 4 must include:
|
|
168
|
-
|
|
169
|
-
- Skill type and folder structure
|
|
170
|
-
- Gap analysis or observation findings (composition plan + description triggers + deterministic inventory)
|
|
171
|
-
- Degree of freedom assessment
|
|
172
|
-
- Initial gotchas
|
|
173
|
-
- Composition plan: related skills, sub-skills to invoke, split decisions
|
|
174
|
-
- Description trigger catalog: capability stem + trigger phrases (not prose)
|
|
175
|
-
- Deterministic elements inventory: each process step classified; code paths + paired tests
|
|
176
|
-
- Any constraints
|
|
177
|
-
|
|
178
|
-
See `${CLAUDE_SKILL_DIR}/references/delegation-map.md` for exact patterns.
|
|
179
|
-
|
|
180
|
-
## File index
|
|
181
|
-
|
|
182
|
-
| File | Purpose |
|
|
183
|
-
|------|---------|
|
|
184
|
-
| `SKILL.md` | This hub — principles, process, routing, file index |
|
|
185
|
-
| `references/skill-types.md` | 9-type taxonomy with folder structures per type |
|
|
186
|
-
| `references/progressive-disclosure.md` | Folder conventions, hub pattern, hard rules |
|
|
187
|
-
| `references/skill-modularity.md` | Cross-skill modularity, sub-skills, composition plan |
|
|
188
|
-
| `references/description-field.md` | Description as trigger catalog (not story prose) |
|
|
189
|
-
| `references/deterministic-elements.md` | Deterministic steps as code/task seeds; CODE_RULES; no markdown checkbox boards |
|
|
190
|
-
| `references/self-audit-checklist.md` | Post-build audit task seeds (register via TaskCreate / TodoWrite) |
|
|
191
|
-
| `references/delegation-map.md` | Subagent handoff patterns and transcript guidance |
|
|
192
|
-
| `workflows/new-skill.md` | Full lifecycle for new skills (6 steps) |
|
|
193
|
-
| `workflows/improve-skill.md` | Observation-first flow for existing skills (6 steps) |
|
|
194
|
-
| `workflows/polish-skill.md` | Description trigger-catalog audit and final validation (5 steps) |
|
|
195
|
-
| `templates/gap-analysis.md` | Gaps, composition plan, description triggers, deterministic inventory |
|
|
196
|
-
|
|
197
|
-
## Folder map
|
|
198
|
-
|
|
199
|
-
- `SKILL.md` — hub.
|
|
200
|
-
- `references/` — best-practice specifications and the audit checklist.
|
|
201
|
-
- `workflows/` — step-by-step workflows for each lifecycle phase.
|
|
202
|
-
- `templates/` — reusable templates for skill artifacts.
|
|
9
|
+
TODO: Rework to follow pstack philosophy.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: test-runner
|
|
3
|
+
description: >-
|
|
4
|
+
Run pytest or Playwright through the repository's test command.
|
|
5
|
+
Checks Django and Playwright readiness before launching the
|
|
6
|
+
selected child process. Use when running tests in a repository with local
|
|
7
|
+
Django or frontend services.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# test-runner
|
|
11
|
+
|
|
12
|
+
Run Django and Playwright readiness checks, then launch the selected test
|
|
13
|
+
command. Pass one supported runner after `--`. The command forwards those
|
|
14
|
+
arguments without a shell.
|
|
15
|
+
|
|
16
|
+
## Command
|
|
17
|
+
|
|
18
|
+
Run from the repository that owns the tests:
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
python "${CLAUDE_SKILL_DIR}/scripts/run_tests.py" -- python -m pytest <pytest-arguments>
|
|
22
|
+
python "${CLAUDE_SKILL_DIR}/scripts/run_tests.py" -- npx playwright test <playwright-arguments>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Use `--project <path>` when the test repository is not the current directory:
|
|
26
|
+
|
|
27
|
+
```text
|
|
28
|
+
python "${CLAUDE_SKILL_DIR}/scripts/run_tests.py" --project "<repository>" -- python -m pytest <pytest-arguments>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The supported runner forms are `pytest`, `python -m pytest`, `playwright test`,
|
|
32
|
+
and `npx playwright test`. The child receives the exact arguments after `--`,
|
|
33
|
+
inherits the current environment, writes to the current output streams, runs
|
|
34
|
+
with the selected project as its working directory, and returns its exit
|
|
35
|
+
status.
|
|
36
|
+
|
|
37
|
+
## Preflight
|
|
38
|
+
|
|
39
|
+
The command returns nonzero and launches no child when a required check fails.
|
|
40
|
+
|
|
41
|
+
- A pytest run in a project without `manage.py` runs without preflight.
|
|
42
|
+
- A pytest run in a Django project requires `db.sqlite3` and a healthy Django
|
|
43
|
+
server. The URL defaults to `http://localhost:8000`. A URL in the child
|
|
44
|
+
arguments overrides that default.
|
|
45
|
+
- A Playwright run checks its target server, validates a detected Django
|
|
46
|
+
`runserver` process uses `--test-db`, rejects conflicting Django servers from
|
|
47
|
+
different worktrees, and uses the URL default `http://localhost:3000`.
|
|
48
|
+
- When the project contains `frontend/`, the command runs `npm run build` in
|
|
49
|
+
that directory, then `python manage.py collectstatic --noinput` in the
|
|
50
|
+
project directory before Playwright starts.
|
|
51
|
+
|
|
52
|
+
The command does not parse shell syntax. Keep pipes, redirects, `cd`, and
|
|
53
|
+
background operators outside this command. Run this command directly so its
|
|
54
|
+
exit status reaches the caller.
|
|
55
|
+
|
|
56
|
+
## Unsupported commands
|
|
57
|
+
|
|
58
|
+
Use the normal runner for anything else. This command accepts only the four
|
|
59
|
+
runner forms listed above. It does not install dependencies, start a server,
|
|
60
|
+
run migrations, or repair a failed preflight.
|
|
61
|
+
|
|
62
|
+
## Files
|
|
63
|
+
|
|
64
|
+
- `SKILL.md` covers invocation, checks, and the command boundary.
|
|
65
|
+
- `scripts/run_tests.py` parses the command, runs preflight, and launches the child.
|
|
66
|
+
- `scripts/preflight_checks.py` runs Django and Playwright readiness checks.
|
|
67
|
+
- `scripts/test_run_tests.py` covers the command and preflight.
|
|
68
|
+
- `scripts/test_preflight_checks.py` covers the readiness checks.
|
|
69
|
+
- `scripts/test_runner_constants/` holds command names, messages, and limits.
|