pactkit 2.7.0__tar.gz → 2.9.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pactkit-2.7.0 → pactkit-2.9.0}/.github/workflows/ci.yml +2 -2
- {pactkit-2.7.0 → pactkit-2.9.0}/.github/workflows/pactkit.yml +3 -3
- {pactkit-2.7.0 → pactkit-2.9.0}/.github/workflows/publish.yml +2 -2
- {pactkit-2.7.0 → pactkit-2.9.0}/.opencode/pactkit.yaml +4 -4
- {pactkit-2.7.0 → pactkit-2.9.0}/CHANGELOG.md +25 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/PKG-INFO +42 -17
- {pactkit-2.7.0 → pactkit-2.9.0}/README.md +39 -15
- {pactkit-2.7.0 → pactkit-2.9.0}/pyproject.toml +3 -2
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/__init__.py +1 -1
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/cli.py +9 -9
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/config.py +5 -27
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/doctor.py +28 -25
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/generators/deployer.py +41 -11
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/profiles.py +2 -2
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/prompts/commands.py +15 -4
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/e2e/cli/test_cli_e2e.py +15 -15
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug013_config_single_source.py +4 -4
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_config.py +7 -3
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_config_auto_merge.py +6 -7
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_deployer_plugin.py +6 -6
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_selective_deploy.py +1 -1
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story016_claude_md.py +3 -4
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story033_config_backfill.py +3 -3
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story059_codex_removal.py +2 -2
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story063_prompt_slimming.py +2 -1
- {pactkit-2.7.0 → pactkit-2.9.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/.github/dependabot.yml +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/.gitignore +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/AGENTS.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/CODE_OF_CONDUCT.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/CONTRIBUTING.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/LICENSE +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/SECURITY.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/assets/logo.png +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/guides/codex-integration-preresearch.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/guides/tool-integration-checklist.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-001.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-002.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-003.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-004.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-005.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-006.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-007.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-008.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-009.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-010.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-011.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-012.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-013.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-014.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-015.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-016.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-017.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-018.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-019.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-020.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-021.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-022.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-023.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-024.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-025.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-026.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-027.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-028.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-029.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-030.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-031.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-032.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-033.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-034.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-035.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-slim-001.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-slim-002.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-slim-003.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-slim-004.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-slim-005.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-slim-006.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/specs/BUG-slim-007.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/test_cases/BUG-001_case.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/docs/test_cases/BUG-002_case.md +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/opencode.json +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/__main__.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/backfill.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/cleaners.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/context_gen.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/coverage_gate.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/generators/__init__.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/generators/adapter.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/generators/deploy_base.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/guards.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/id_generator.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/invariants.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/issue_sync.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/lazy_visualize.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/lessons.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/lint_runner.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/prompts/__init__.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/prompts/agents.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/prompts/references.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/prompts/rules.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/prompts/skills.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/prompts/workflows.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/regression.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/schemas.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/scripts.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/sec_scope.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/skills/__init__.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/skills/board.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/skills/scaffold.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/skills/spec_linter.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/skills/visualize.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/spec_status.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/test_mapper.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/utils.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/src/pactkit/validators.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/conftest.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/e2e/__init__.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/e2e/cli/__init__.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/integration/__init__.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/integration/test_deploy_classic.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_agent_features.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_agent_frontmatter.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_agents_enrichment.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_board_bug027.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_board_sections.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug001_skill_path.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug002_plugin_paths.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug003_multi_import.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug004_dead_set.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug005_archive_taskless.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug006_scan_excludes.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug007_stale_trace_refs.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug008_stale_command_refs.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug009_project_config_backfill.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug010_rewrite_yaml.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug011_stale_refs.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug012_call_graph_filter.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug014_version_hygiene.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug017_project_init_playbook.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug018_issue_tracker_verification.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug019_venv_deployment.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug020_claude_md_backup.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug025_release_delegation.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug026_version_sync.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug028_ghost_refs.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug029_stack_detection_fallback.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug030_spec_lint_cli.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug031_docstring_accuracy.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug034_plan_metadata_template.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug_021.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug_022.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug_023.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug_024.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug_slim001_env_detection.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug_slim002_instruction_collision.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug_slim003.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug_slim004.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug_slim005.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_bug_slim006.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_check_command.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_command_frontmatter.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_command_visualize_modes.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_constitution_sharpening.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_create_skill.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_cross_flow_matrix.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_deploy_base.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_deployer_cleanup.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_design_command.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_done_gates.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_draw_prompt.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_draw_references.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_drawio_mcp.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_home_path_fix.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_hotfix_command.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_init_guard.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_lang_profiles.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_list_stories.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_mcp_integration.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_model_config.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_modular_constitution.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_multi_prefix.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_pdca_slim.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_profiles.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_project_visibility.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_prompt_cli_refs.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_prompt_structural_invariants.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_prompts_package.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_release.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_release_field.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_release_v110.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_render_prompt.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_review_command.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_rules_enrichment.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_scaffold.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_scaffold_developer_prefix.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_schemas.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_script_extraction.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_session_context.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_skill_structure.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_skills_enrichment.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_smart_regression.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_sprint_command.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_stack_references.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_status_command.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_statusline.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story014_release.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story015_ci_lint_gate.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story017_init_claude_md.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story018_arch_staleness.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story019_bailout.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story020_horizon.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story021_rfc.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story022_decision_tree.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story023_test_quality.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story024_native_agent.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story025_ci_pipeline.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story026_issue_tracker.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story027_hooks.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story028_rule_scoping.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story029_doctor.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story030_lint.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story031_git_init_guard.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story032_greenfield_redirect.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story034_plan_config_refresh.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story035_readme_docs.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story037_regression_fix.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story038_call_graph_update.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story039_venv_config.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story040_layered_claude_md.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story042_spec_linter.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story043_active_clarify.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story044_consistency_check.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story045_auto_pr.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story046_agent_adapter.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story047_enterprise_flags.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story048_worktree_isolation.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story049_community_standards.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story050_doc_only_shortcut.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story051_workflow_streamlining.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story052_conditional_github_release.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story053_impact_regression.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story055_commands.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story055_config.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story055_spec_linter.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story056_commands.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story056_config.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story057_implicit_cleanup.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story058_opencode_extraction.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story058_routing_fix.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story060_init_hang.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story061_remove_thinking.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story062_mcp_recommendations.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story064_venv_local_md.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story065_sprint_model.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story072_developer_prefix.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim009_lazy_rules.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim010_dry_refactor.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim011_command_rules.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim012_ci.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim014_clean.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim014_context.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim014_guard.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim014_lazy_viz.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim014_next_id.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim014_regression.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim014_sec_scope.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim014_validators.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim015_doctor.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim016_testmap_lint.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim017.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim018.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim019_plan_subphases.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim020_explore_stall_fix.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim021.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim022.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim023.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim024.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim025.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim026.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim027.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim028.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim029.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim030.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim031.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim032.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim033.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim034.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim035.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim036.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim037.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim038.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim039.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim040.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim041.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim042.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim043.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim044.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim045.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim046.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim047.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim048.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim049.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim051.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim052.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim053.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim054.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim055.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim056.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim060_codex_profile.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_story_slim063.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_tools.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_update_task.py +0 -0
- {pactkit-2.7.0 → pactkit-2.9.0}/tests/unit/test_visualize_modes.py +0 -0
|
@@ -24,8 +24,8 @@ jobs:
|
|
|
24
24
|
- name: Install dependencies
|
|
25
25
|
run: |
|
|
26
26
|
python -m pip install --upgrade pip
|
|
27
|
-
pip install -e ".[multilang]"
|
|
28
|
-
pip install pytest ruff==0.15.1
|
|
27
|
+
pip install --no-deps -e ".[multilang]"
|
|
28
|
+
pip install pyyaml pytest ruff==0.15.1
|
|
29
29
|
|
|
30
30
|
- name: Lint with ruff
|
|
31
31
|
run: ruff check src/ tests/
|
|
@@ -20,9 +20,9 @@ jobs:
|
|
|
20
20
|
- name: Install dependencies
|
|
21
21
|
run: |
|
|
22
22
|
python -m pip install --upgrade pip
|
|
23
|
-
pip install -e ".[dev]" || pip install -e .
|
|
24
|
-
pip install pytest ruff
|
|
25
|
-
pactkit init
|
|
23
|
+
pip install --no-deps -e ".[dev]" || pip install --no-deps -e .
|
|
24
|
+
pip install pyyaml pytest ruff
|
|
25
|
+
pactkit init --format classic
|
|
26
26
|
|
|
27
27
|
- name: Lint
|
|
28
28
|
run: ruff check src/ tests/
|
|
@@ -27,8 +27,8 @@ jobs:
|
|
|
27
27
|
- name: Install dependencies
|
|
28
28
|
run: |
|
|
29
29
|
python -m pip install --upgrade pip
|
|
30
|
-
pip install -e ".[dev]" || pip install -e .
|
|
31
|
-
pip install pytest ruff
|
|
30
|
+
pip install --no-deps -e ".[dev]" || pip install --no-deps -e .
|
|
31
|
+
pip install pyyaml pytest ruff
|
|
32
32
|
|
|
33
33
|
- name: Lint
|
|
34
34
|
run: ruff check src/ tests/
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# Edit this file to customize which components are deployed.
|
|
3
3
|
# Remove items from a list to disable them. Default: all enabled.
|
|
4
4
|
|
|
5
|
-
version: "2.
|
|
5
|
+
version: "2.8.0"
|
|
6
6
|
stack: python
|
|
7
7
|
root: .
|
|
8
8
|
developer: "slim"
|
|
@@ -23,18 +23,19 @@ agents:
|
|
|
23
23
|
commands:
|
|
24
24
|
- project-act
|
|
25
25
|
- project-check
|
|
26
|
+
- project-clarify
|
|
26
27
|
- project-design
|
|
27
28
|
- project-done
|
|
28
29
|
- project-hotfix
|
|
29
30
|
- project-init
|
|
30
31
|
- project-plan
|
|
31
|
-
- project-sprint
|
|
32
|
-
- project-clarify
|
|
33
32
|
- project-pr
|
|
34
33
|
- project-release
|
|
34
|
+
- project-sprint
|
|
35
35
|
|
|
36
36
|
# Skills — tool scripts
|
|
37
37
|
skills:
|
|
38
|
+
- pactkit-analyze
|
|
38
39
|
- pactkit-board
|
|
39
40
|
- pactkit-doctor
|
|
40
41
|
- pactkit-draw
|
|
@@ -44,7 +45,6 @@ skills:
|
|
|
44
45
|
- pactkit-status
|
|
45
46
|
- pactkit-trace
|
|
46
47
|
- pactkit-visualize
|
|
47
|
-
- pactkit-analyze
|
|
48
48
|
- project-act
|
|
49
49
|
- project-check
|
|
50
50
|
- project-clarify
|
|
@@ -4,6 +4,31 @@ All notable changes to PactKit will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
Format follows [Keep a Changelog](https://keepachangelog.com/).
|
|
6
6
|
|
|
7
|
+
## [2.9.0] - 2026-03-28
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- **`pactkit init` deploys all IDEs by default** — `--format all` is now the CLI default, deploying Claude Code + OpenCode + Codex configs in one shot. No need to specify `--format` per IDE. Packaging modes (plugin, marketplace) excluded from "all".
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- **Entry_point deployer circular import** — Lazy-load entry_point deployers to fix `ValueError` when running `pactkit init` via pipx. Module-level `ep.load()` caused circular import between deployer.py and adapter packages.
|
|
14
|
+
|
|
15
|
+
## [2.8.0] - 2026-03-27
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- **3-IDE default install** — `pip install pactkit` now installs all three IDE adapters (Claude Code + OpenCode + Codex) out of the box.
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
- **OpenCode command architecture** — Reverted OpenCode from skills-only back to `commands/` + `skills/` dual architecture. OpenCode auto-discovers commands from `commands/*.md` (invoked via `/project-plan`), while embedded skills in `skills/` are loaded by AI agent on demand. `opencode.json` command entries now only contain model routing (no `template` field — it was incorrectly treated as file path, but is actually inline text).
|
|
22
|
+
- **Spec version confusion** — `/project-plan` Phase 3.2a no longer reads version from `pactkit.yaml` (PactKit toolkit version). Now explicitly reads from project's package manifest (`pyproject.toml`, `package.json`, `Cargo.toml`).
|
|
23
|
+
- **OpenCode path isolation** — All deployed OpenCode files reference `~/.config/opencode/` paths, CLI commands replaced with `python3 ~/.config/opencode/skills/*/scripts/*.py` invocations.
|
|
24
|
+
- **pactkit.yaml simplification** — Removed redundant component lists (agents/commands/skills/rules) from yaml template. Absence = deploy all from `VALID_*` sets. `pactkit doctor` drift check skips absent keys.
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
- **Cross-IDE command architecture**:
|
|
28
|
+
- Claude Code: skills-only (`skills/project-*/SKILL.md`), prefix `/`
|
|
29
|
+
- OpenCode: commands + skills (`commands/project-*.md` + `skills/pactkit-*/SKILL.md`), prefix `/`
|
|
30
|
+
- Codex: skills-only (`skills/project-*/SKILL.md`), prefix `$`
|
|
31
|
+
|
|
7
32
|
## [2.7.0] - 2026-03-27
|
|
8
33
|
|
|
9
34
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pactkit
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.9.0
|
|
4
4
|
Summary: Spec-driven agentic DevOps toolkit for AI coding assistants
|
|
5
5
|
Project-URL: Homepage, https://pactkit.dev
|
|
6
6
|
Project-URL: Repository, https://github.com/pactkit/pactkit-public
|
|
@@ -21,7 +21,8 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
21
21
|
Classifier: Topic :: Software Development :: Build Tools
|
|
22
22
|
Classifier: Topic :: Software Development :: Quality Assurance
|
|
23
23
|
Requires-Python: >=3.10
|
|
24
|
-
Requires-Dist: pactkit-
|
|
24
|
+
Requires-Dist: pactkit-codex>=2.9.0
|
|
25
|
+
Requires-Dist: pactkit-opencode>=2.9.0
|
|
25
26
|
Requires-Dist: pyyaml>=6.0
|
|
26
27
|
Provides-Extra: multilang
|
|
27
28
|
Requires-Dist: tree-sitter-go>=0.25; extra == 'multilang'
|
|
@@ -45,7 +46,7 @@ Description-Content-Type: text/markdown
|
|
|
45
46
|
|
|
46
47
|
> **PactKit** (Pact 契约 + Kit) is a governance framework that enforces the **P.A.C.T.** contract between humans and AI agents. Deterministic operations run as code, not prompts. Decisions are grounded in data, not memory. AI does what it's best at — creativity and language — while code handles everything that must be repeatable and correct.
|
|
47
48
|
>
|
|
48
|
-
> 25 CLI subcommands, 9 specialized agents, 11 commands, 10 skills, and a full Plan-Act-Check-Done lifecycle. One `pip install`
|
|
49
|
+
> 25 CLI subcommands, 9 specialized agents, 11 commands, 10 skills, and a full Plan-Act-Check-Done lifecycle. One `pip install` deploys to all 3 supported IDEs.
|
|
49
50
|
|
|
50
51
|
### Supported AI Tools
|
|
51
52
|
|
|
@@ -53,6 +54,7 @@ Description-Content-Type: text/markdown
|
|
|
53
54
|
|------|--------|---------|
|
|
54
55
|
| **Claude Code** | Classic | `pactkit init` |
|
|
55
56
|
| **OpenCode** | OpenCode | `pactkit init --format opencode` |
|
|
57
|
+
| **Codex CLI** | Codex | `pactkit init --format codex` |
|
|
56
58
|
|
|
57
59
|
### What it looks like
|
|
58
60
|
|
|
@@ -89,7 +91,7 @@ T Truth Data is the Truth Factual basis for all judgment — no memory,
|
|
|
89
91
|
- **Multi-Agent Ensemble** — 9 specialized agents collaborate, each with constrained tools
|
|
90
92
|
- **Full PDCA Lifecycle** — Plan -> Act -> Check -> Done, with quality gates at every stage
|
|
91
93
|
- **Safe by Design** — TDD-first, safe regression, pre-existing test protection
|
|
92
|
-
- **Multi-Tool Support** — Works with Claude Code and
|
|
94
|
+
- **Multi-Tool Support** — Works with Claude Code, OpenCode, and Codex CLI
|
|
93
95
|
|
|
94
96
|
## Installation
|
|
95
97
|
|
|
@@ -100,6 +102,9 @@ pip install pactkit
|
|
|
100
102
|
Requires Python 3.10+ and one of:
|
|
101
103
|
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code)
|
|
102
104
|
- [OpenCode](https://opencode.ai)
|
|
105
|
+
- [Codex CLI](https://github.com/openai/codex)
|
|
106
|
+
|
|
107
|
+
> `pip install pactkit` automatically installs adapters for all 3 IDEs.
|
|
103
108
|
|
|
104
109
|
## Quick Start
|
|
105
110
|
|
|
@@ -123,6 +128,16 @@ pactkit init --format opencode
|
|
|
123
128
|
pactkit upgrade --format opencode
|
|
124
129
|
```
|
|
125
130
|
|
|
131
|
+
### Codex CLI
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
# Deploy to Codex CLI (global: ~/.codex/)
|
|
135
|
+
pactkit init --format codex
|
|
136
|
+
|
|
137
|
+
# Update existing deployment
|
|
138
|
+
pactkit-codex update
|
|
139
|
+
```
|
|
140
|
+
|
|
126
141
|
Then in any project:
|
|
127
142
|
|
|
128
143
|
```bash
|
|
@@ -277,7 +292,7 @@ PactKit ships 25 deterministic CLI subcommands — operations that were previous
|
|
|
277
292
|
|
|
278
293
|
## Deployment Architecture
|
|
279
294
|
|
|
280
|
-
PactKit supports
|
|
295
|
+
PactKit supports three deployment formats:
|
|
281
296
|
|
|
282
297
|
### Claude Code (Classic)
|
|
283
298
|
|
|
@@ -285,29 +300,38 @@ PactKit supports two deployment formats:
|
|
|
285
300
|
~/.claude/
|
|
286
301
|
├── CLAUDE.md <- Project context entry point
|
|
287
302
|
├── rules/ <- 8 rule modules (loaded per-command, not globally)
|
|
288
|
-
├──
|
|
289
|
-
|
|
290
|
-
└── skills/ <- 10 skill packages
|
|
303
|
+
├── skills/ <- 21 skill packages (11 commands + 10 embedded)
|
|
304
|
+
└── agents/ <- 9 agent definitions
|
|
291
305
|
```
|
|
292
306
|
|
|
307
|
+
Commands are deployed as skills (`skills/project-*/SKILL.md`), invoked with `/project-plan`.
|
|
308
|
+
|
|
293
309
|
### OpenCode
|
|
294
310
|
|
|
295
311
|
```
|
|
296
312
|
~/.config/opencode/
|
|
297
313
|
├── AGENTS.md <- On-demand @reference index (lazy rule loading)
|
|
298
314
|
├── rules/ <- 8 rule modules (3 core always-load + 6 on-demand)
|
|
299
|
-
├── commands/ <- 11 command playbooks (
|
|
315
|
+
├── commands/ <- 11 command playbooks (auto-discovered, invoked via /)
|
|
300
316
|
├── agents/ <- 9 agent definitions (mode: subagent)
|
|
301
|
-
├── skills/ <- 10 skill packages (
|
|
302
|
-
└── opencode.json <- Global config (
|
|
317
|
+
├── skills/ <- 10 skill packages (AI agent loads on demand)
|
|
318
|
+
└── opencode.json <- Global config (model routing, instructions)
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
OpenCode uses dual mechanism: `commands/` for user-facing PDCA entry points, `skills/` for AI-invoked tools.
|
|
322
|
+
|
|
323
|
+
### Codex CLI
|
|
324
|
+
|
|
325
|
+
```
|
|
326
|
+
~/.codex/
|
|
327
|
+
├── AGENTS.md <- Global constitution
|
|
328
|
+
├── config.toml <- Model, sandbox, MCP config
|
|
329
|
+
├── rules/ <- 8 rule modules
|
|
330
|
+
├── skills/ <- 21 skill packages (11 commands + 10 embedded)
|
|
331
|
+
└── .pactkit-version <- Version marker for updates
|
|
303
332
|
```
|
|
304
333
|
|
|
305
|
-
|
|
306
|
-
- **Rules**: Per-command inline embedding; credential safety always loaded via `instructions` (context-aware loading, -20% to -83% tokens per command)
|
|
307
|
-
- **Agents**: `mode: subagent`, no `name` field, tools as record format
|
|
308
|
-
- **Commands**: `agent: build` + `model: provider/model-id` (model routing)
|
|
309
|
-
- **Config**: `pactkit.yaml` in `.opencode/` (not `.claude/`)
|
|
310
|
-
- **Model routing**: Commands auto-route to Sonnet for implementation, inherit main model for planning
|
|
334
|
+
Commands are deployed as skills (`skills/project-*/SKILL.md`), invoked with `$project-plan`.
|
|
311
335
|
|
|
312
336
|
## Multi-Developer Collaboration
|
|
313
337
|
|
|
@@ -399,6 +423,7 @@ All MCP instructions are conditional — gracefully skipped when unavailable.
|
|
|
399
423
|
pip install --upgrade pactkit
|
|
400
424
|
pactkit update # Claude Code
|
|
401
425
|
pactkit upgrade --format opencode # OpenCode
|
|
426
|
+
pactkit-codex update # Codex CLI
|
|
402
427
|
```
|
|
403
428
|
|
|
404
429
|
## Contributing
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
> **PactKit** (Pact 契约 + Kit) is a governance framework that enforces the **P.A.C.T.** contract between humans and AI agents. Deterministic operations run as code, not prompts. Decisions are grounded in data, not memory. AI does what it's best at — creativity and language — while code handles everything that must be repeatable and correct.
|
|
15
15
|
>
|
|
16
|
-
> 25 CLI subcommands, 9 specialized agents, 11 commands, 10 skills, and a full Plan-Act-Check-Done lifecycle. One `pip install`
|
|
16
|
+
> 25 CLI subcommands, 9 specialized agents, 11 commands, 10 skills, and a full Plan-Act-Check-Done lifecycle. One `pip install` deploys to all 3 supported IDEs.
|
|
17
17
|
|
|
18
18
|
### Supported AI Tools
|
|
19
19
|
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
|------|--------|---------|
|
|
22
22
|
| **Claude Code** | Classic | `pactkit init` |
|
|
23
23
|
| **OpenCode** | OpenCode | `pactkit init --format opencode` |
|
|
24
|
+
| **Codex CLI** | Codex | `pactkit init --format codex` |
|
|
24
25
|
|
|
25
26
|
### What it looks like
|
|
26
27
|
|
|
@@ -57,7 +58,7 @@ T Truth Data is the Truth Factual basis for all judgment — no memory,
|
|
|
57
58
|
- **Multi-Agent Ensemble** — 9 specialized agents collaborate, each with constrained tools
|
|
58
59
|
- **Full PDCA Lifecycle** — Plan -> Act -> Check -> Done, with quality gates at every stage
|
|
59
60
|
- **Safe by Design** — TDD-first, safe regression, pre-existing test protection
|
|
60
|
-
- **Multi-Tool Support** — Works with Claude Code and
|
|
61
|
+
- **Multi-Tool Support** — Works with Claude Code, OpenCode, and Codex CLI
|
|
61
62
|
|
|
62
63
|
## Installation
|
|
63
64
|
|
|
@@ -68,6 +69,9 @@ pip install pactkit
|
|
|
68
69
|
Requires Python 3.10+ and one of:
|
|
69
70
|
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code)
|
|
70
71
|
- [OpenCode](https://opencode.ai)
|
|
72
|
+
- [Codex CLI](https://github.com/openai/codex)
|
|
73
|
+
|
|
74
|
+
> `pip install pactkit` automatically installs adapters for all 3 IDEs.
|
|
71
75
|
|
|
72
76
|
## Quick Start
|
|
73
77
|
|
|
@@ -91,6 +95,16 @@ pactkit init --format opencode
|
|
|
91
95
|
pactkit upgrade --format opencode
|
|
92
96
|
```
|
|
93
97
|
|
|
98
|
+
### Codex CLI
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# Deploy to Codex CLI (global: ~/.codex/)
|
|
102
|
+
pactkit init --format codex
|
|
103
|
+
|
|
104
|
+
# Update existing deployment
|
|
105
|
+
pactkit-codex update
|
|
106
|
+
```
|
|
107
|
+
|
|
94
108
|
Then in any project:
|
|
95
109
|
|
|
96
110
|
```bash
|
|
@@ -245,7 +259,7 @@ PactKit ships 25 deterministic CLI subcommands — operations that were previous
|
|
|
245
259
|
|
|
246
260
|
## Deployment Architecture
|
|
247
261
|
|
|
248
|
-
PactKit supports
|
|
262
|
+
PactKit supports three deployment formats:
|
|
249
263
|
|
|
250
264
|
### Claude Code (Classic)
|
|
251
265
|
|
|
@@ -253,29 +267,38 @@ PactKit supports two deployment formats:
|
|
|
253
267
|
~/.claude/
|
|
254
268
|
├── CLAUDE.md <- Project context entry point
|
|
255
269
|
├── rules/ <- 8 rule modules (loaded per-command, not globally)
|
|
256
|
-
├──
|
|
257
|
-
|
|
258
|
-
└── skills/ <- 10 skill packages
|
|
270
|
+
├── skills/ <- 21 skill packages (11 commands + 10 embedded)
|
|
271
|
+
└── agents/ <- 9 agent definitions
|
|
259
272
|
```
|
|
260
273
|
|
|
274
|
+
Commands are deployed as skills (`skills/project-*/SKILL.md`), invoked with `/project-plan`.
|
|
275
|
+
|
|
261
276
|
### OpenCode
|
|
262
277
|
|
|
263
278
|
```
|
|
264
279
|
~/.config/opencode/
|
|
265
280
|
├── AGENTS.md <- On-demand @reference index (lazy rule loading)
|
|
266
281
|
├── rules/ <- 8 rule modules (3 core always-load + 6 on-demand)
|
|
267
|
-
├── commands/ <- 11 command playbooks (
|
|
282
|
+
├── commands/ <- 11 command playbooks (auto-discovered, invoked via /)
|
|
268
283
|
├── agents/ <- 9 agent definitions (mode: subagent)
|
|
269
|
-
├── skills/ <- 10 skill packages (
|
|
270
|
-
└── opencode.json <- Global config (
|
|
284
|
+
├── skills/ <- 10 skill packages (AI agent loads on demand)
|
|
285
|
+
└── opencode.json <- Global config (model routing, instructions)
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
OpenCode uses dual mechanism: `commands/` for user-facing PDCA entry points, `skills/` for AI-invoked tools.
|
|
289
|
+
|
|
290
|
+
### Codex CLI
|
|
291
|
+
|
|
292
|
+
```
|
|
293
|
+
~/.codex/
|
|
294
|
+
├── AGENTS.md <- Global constitution
|
|
295
|
+
├── config.toml <- Model, sandbox, MCP config
|
|
296
|
+
├── rules/ <- 8 rule modules
|
|
297
|
+
├── skills/ <- 21 skill packages (11 commands + 10 embedded)
|
|
298
|
+
└── .pactkit-version <- Version marker for updates
|
|
271
299
|
```
|
|
272
300
|
|
|
273
|
-
|
|
274
|
-
- **Rules**: Per-command inline embedding; credential safety always loaded via `instructions` (context-aware loading, -20% to -83% tokens per command)
|
|
275
|
-
- **Agents**: `mode: subagent`, no `name` field, tools as record format
|
|
276
|
-
- **Commands**: `agent: build` + `model: provider/model-id` (model routing)
|
|
277
|
-
- **Config**: `pactkit.yaml` in `.opencode/` (not `.claude/`)
|
|
278
|
-
- **Model routing**: Commands auto-route to Sonnet for implementation, inherit main model for planning
|
|
301
|
+
Commands are deployed as skills (`skills/project-*/SKILL.md`), invoked with `$project-plan`.
|
|
279
302
|
|
|
280
303
|
## Multi-Developer Collaboration
|
|
281
304
|
|
|
@@ -367,6 +390,7 @@ All MCP instructions are conditional — gracefully skipped when unavailable.
|
|
|
367
390
|
pip install --upgrade pactkit
|
|
368
391
|
pactkit update # Claude Code
|
|
369
392
|
pactkit upgrade --format opencode # OpenCode
|
|
393
|
+
pactkit-codex update # Codex CLI
|
|
370
394
|
```
|
|
371
395
|
|
|
372
396
|
## Contributing
|
|
@@ -4,14 +4,15 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pactkit"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.9.0"
|
|
8
8
|
description = "Spec-driven agentic DevOps toolkit for AI coding assistants"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
11
11
|
requires-python = ">=3.10"
|
|
12
12
|
dependencies = [
|
|
13
13
|
"pyyaml>=6.0",
|
|
14
|
-
"pactkit-opencode>=2.
|
|
14
|
+
"pactkit-opencode>=2.9.0",
|
|
15
|
+
"pactkit-codex>=2.9.0",
|
|
15
16
|
]
|
|
16
17
|
|
|
17
18
|
authors = [
|
|
@@ -64,9 +64,9 @@ def main():
|
|
|
64
64
|
init_parser.add_argument(
|
|
65
65
|
"--format",
|
|
66
66
|
type=str,
|
|
67
|
-
choices=["classic", "plugin", "marketplace", "opencode"],
|
|
68
|
-
default="
|
|
69
|
-
help="Output format:
|
|
67
|
+
choices=["all", "classic", "plugin", "marketplace", "opencode", "codex"],
|
|
68
|
+
default="all",
|
|
69
|
+
help="Output format: all (default, deploy all installed IDEs), or a specific format",
|
|
70
70
|
)
|
|
71
71
|
init_parser.add_argument(
|
|
72
72
|
"--agent",
|
|
@@ -107,9 +107,9 @@ def main():
|
|
|
107
107
|
update_parser.add_argument(
|
|
108
108
|
"--format",
|
|
109
109
|
type=str,
|
|
110
|
-
choices=["classic", "plugin", "marketplace", "opencode"],
|
|
111
|
-
default="
|
|
112
|
-
help="Output format:
|
|
110
|
+
choices=["all", "classic", "plugin", "marketplace", "opencode", "codex"],
|
|
111
|
+
default="all",
|
|
112
|
+
help="Output format: all (default, deploy all installed IDEs), or a specific format",
|
|
113
113
|
)
|
|
114
114
|
update_parser.add_argument(
|
|
115
115
|
"--agent",
|
|
@@ -157,9 +157,9 @@ def main():
|
|
|
157
157
|
upgrade_parser.add_argument(
|
|
158
158
|
"--format",
|
|
159
159
|
type=str,
|
|
160
|
-
choices=["classic", "plugin", "marketplace", "opencode"],
|
|
161
|
-
default="
|
|
162
|
-
help="Output format:
|
|
160
|
+
choices=["all", "classic", "plugin", "marketplace", "opencode", "codex"],
|
|
161
|
+
default="all",
|
|
162
|
+
help="Output format: all (default, deploy all installed IDEs), or a specific format",
|
|
163
163
|
)
|
|
164
164
|
upgrade_parser.add_argument(
|
|
165
165
|
"--agent",
|
|
@@ -448,14 +448,12 @@ def auto_merge_config_file(path: Union[Path, str]) -> list[str]:
|
|
|
448
448
|
added: list[str] = []
|
|
449
449
|
|
|
450
450
|
# --- List-type keys: merge new items ---
|
|
451
|
+
# If a list key is absent from yaml, it means "deploy all" (VALID_* default).
|
|
452
|
+
# Only merge if the user explicitly provides a list (opt-in customization).
|
|
451
453
|
for key, valid_set in _REGISTRY.items():
|
|
452
454
|
user_list = user_data.get(key)
|
|
453
455
|
if user_list is None:
|
|
454
|
-
#
|
|
455
|
-
excluded_items = set(exclude.get(key, []) or [])
|
|
456
|
-
new_items = sorted(item for item in valid_set if item not in excluded_items)
|
|
457
|
-
user_data[key] = new_items
|
|
458
|
-
added.append(f"section: {key}")
|
|
456
|
+
# Key absent = deploy all by default. No backfill needed.
|
|
459
457
|
continue
|
|
460
458
|
if not isinstance(user_list, list):
|
|
461
459
|
continue
|
|
@@ -900,34 +898,14 @@ def generate_default_yaml() -> str:
|
|
|
900
898
|
cfg = get_default_config()
|
|
901
899
|
lines = [
|
|
902
900
|
"# PactKit Configuration",
|
|
903
|
-
"#
|
|
904
|
-
"#
|
|
901
|
+
"# All agents, commands, skills, and rules are deployed by default.",
|
|
902
|
+
"# To exclude specific items, add an exclude list (e.g., exclude_skills: [pactkit-draw]).",
|
|
905
903
|
"",
|
|
906
904
|
f'version: "{cfg["version"]}"',
|
|
907
905
|
f"stack: {cfg['stack']}",
|
|
908
906
|
f"root: {cfg['root']}",
|
|
909
907
|
f'developer: "{cfg["developer"]}"',
|
|
910
|
-
"",
|
|
911
|
-
"# Agents — AI role definitions",
|
|
912
|
-
"agents:",
|
|
913
908
|
]
|
|
914
|
-
for a in cfg["agents"]:
|
|
915
|
-
lines.append(f" - {a}")
|
|
916
|
-
|
|
917
|
-
lines.extend(["", "# Commands — PDCA playbooks"])
|
|
918
|
-
lines.append("commands:")
|
|
919
|
-
for c in cfg["commands"]:
|
|
920
|
-
lines.append(f" - {c}")
|
|
921
|
-
|
|
922
|
-
lines.extend(["", "# Skills — tool scripts"])
|
|
923
|
-
lines.append("skills:")
|
|
924
|
-
for s in cfg["skills"]:
|
|
925
|
-
lines.append(f" - {s}")
|
|
926
|
-
|
|
927
|
-
lines.extend(["", "# Rules — constitution modules"])
|
|
928
|
-
lines.append("rules:")
|
|
929
|
-
for r in cfg["rules"]:
|
|
930
|
-
lines.append(f" - {r}")
|
|
931
909
|
|
|
932
910
|
ci = cfg.get("ci", {})
|
|
933
911
|
lines.extend(["", "# CI/CD — set provider to github or gitlab to generate pipeline config"])
|
|
@@ -55,6 +55,10 @@ def check_orphaned_specs(project_root: Path) -> dict:
|
|
|
55
55
|
def check_config_drift(project_root: Path) -> dict:
|
|
56
56
|
"""Compare pactkit.yaml declared items vs deployed files.
|
|
57
57
|
|
|
58
|
+
Only checks deployment drift when the yaml explicitly declares
|
|
59
|
+
component lists (agents, commands, skills, rules). Default behavior
|
|
60
|
+
(no lists) means "deploy all from VALID_* sets" — no drift possible.
|
|
61
|
+
|
|
58
62
|
Returns:
|
|
59
63
|
{"missing_deployments": [{"type": ..., "name": ...}]}
|
|
60
64
|
"""
|
|
@@ -69,33 +73,32 @@ def check_config_drift(project_root: Path) -> dict:
|
|
|
69
73
|
with open(yaml_path, encoding="utf-8") as f:
|
|
70
74
|
data = yaml.safe_load(f) or {}
|
|
71
75
|
|
|
72
|
-
config_dir = yaml_path.parent # .claude/ or .opencode/
|
|
76
|
+
config_dir = yaml_path.parent # .claude/ or .opencode/ or .codex/
|
|
73
77
|
missing: list[dict] = []
|
|
74
78
|
|
|
75
|
-
#
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
for
|
|
83
|
-
|
|
84
|
-
if not
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
missing.append({"type": "rule", "name": rule})
|
|
79
|
+
# Only check drift for explicitly declared lists.
|
|
80
|
+
# If the key is absent, it means "deploy all" — no drift to check.
|
|
81
|
+
_CHECKS = [
|
|
82
|
+
("agents", "agents", ".md"),
|
|
83
|
+
("commands", "commands", ".md"),
|
|
84
|
+
("rules", "rules", ".md"),
|
|
85
|
+
]
|
|
86
|
+
for key, subdir, suffix in _CHECKS:
|
|
87
|
+
declared = data.get(key)
|
|
88
|
+
if not isinstance(declared, list):
|
|
89
|
+
continue
|
|
90
|
+
for item in declared:
|
|
91
|
+
if not (config_dir / subdir / f"{item}{suffix}").exists():
|
|
92
|
+
missing.append({"type": key.rstrip("s"), "name": item})
|
|
93
|
+
|
|
94
|
+
# Skills: check as directory or .md file
|
|
95
|
+
declared_skills = data.get("skills")
|
|
96
|
+
if isinstance(declared_skills, list):
|
|
97
|
+
for skill in declared_skills:
|
|
98
|
+
skill_dir = config_dir / "skills" / skill
|
|
99
|
+
skill_file = config_dir / "skills" / f"{skill}.md"
|
|
100
|
+
if not skill_dir.is_dir() and not skill_file.exists():
|
|
101
|
+
missing.append({"type": "skill", "name": skill})
|
|
99
102
|
|
|
100
103
|
return {"missing_deployments": missing}
|
|
101
104
|
|
|
@@ -204,16 +204,28 @@ def _load_entry_point_deployers():
|
|
|
204
204
|
eps = entry_points(group="pactkit.deployers")
|
|
205
205
|
for ep in eps:
|
|
206
206
|
if ep.name in _DEPLOYER_REGISTRY:
|
|
207
|
-
continue # built-in or already
|
|
207
|
+
continue # built-in or already loaded via self-registration
|
|
208
208
|
try:
|
|
209
209
|
deployer_cls = ep.load()
|
|
210
|
-
|
|
210
|
+
# ep.load() may trigger adapter's self-registration (force=True).
|
|
211
|
+
# Re-check registry — adapter may have registered itself during import.
|
|
212
|
+
if ep.name not in _DEPLOYER_REGISTRY:
|
|
213
|
+
register_deployer(ep.name, deployer_cls)
|
|
211
214
|
except Exception:
|
|
212
215
|
pass # graceful degradation — adapter package may be broken
|
|
213
216
|
|
|
214
217
|
|
|
215
|
-
#
|
|
216
|
-
|
|
218
|
+
# Lazy discovery: avoid module-level ep.load() which triggers circular imports
|
|
219
|
+
# when adapter packages (pactkit-opencode, pactkit-codex) import from deployer.py.
|
|
220
|
+
_ep_loaded = False
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
def _ensure_entry_point_deployers():
|
|
224
|
+
"""Lazy wrapper — loads entry_point deployers on first deploy() call."""
|
|
225
|
+
global _ep_loaded
|
|
226
|
+
if not _ep_loaded:
|
|
227
|
+
_load_entry_point_deployers()
|
|
228
|
+
_ep_loaded = True
|
|
217
229
|
|
|
218
230
|
|
|
219
231
|
def deploy(
|
|
@@ -224,15 +236,33 @@ def deploy(
|
|
|
224
236
|
|
|
225
237
|
Args:
|
|
226
238
|
config: Optional config dict. If None, loads from pactkit.yaml or defaults.
|
|
227
|
-
target: Optional target directory. If None, uses
|
|
228
|
-
|
|
229
|
-
|
|
239
|
+
target: Optional target directory. If None, uses format-specific default.
|
|
240
|
+
format: Output format — 'classic' (default for Python API), 'all'
|
|
241
|
+
(deploy all installed IDEs, CLI default), or a specific format
|
|
242
|
+
('opencode', 'codex', 'plugin', 'marketplace').
|
|
230
243
|
agent: Target agent format (claude, cursor, copilot, generic, all).
|
|
231
244
|
no_git: Disable all git operations (enterprise: air-gapped environments).
|
|
232
245
|
no_external: Disable external network calls (enterprise).
|
|
233
246
|
non_interactive: Non-interactive mode: auto-accept defaults (CI/CD).
|
|
234
247
|
mode: Deprecated, ignored. Kept for backward compatibility.
|
|
235
248
|
"""
|
|
249
|
+
_ensure_entry_point_deployers()
|
|
250
|
+
|
|
251
|
+
# "all" deploys every IDE environment (classic + installed adapters).
|
|
252
|
+
# Skips packaging modes (plugin, marketplace) — those are distribution
|
|
253
|
+
# formats, not IDE targets.
|
|
254
|
+
_PACKAGING_MODES = {"plugin", "marketplace"}
|
|
255
|
+
if format == "all":
|
|
256
|
+
for fmt_name in sorted(_DEPLOYER_REGISTRY):
|
|
257
|
+
if fmt_name in _PACKAGING_MODES:
|
|
258
|
+
continue
|
|
259
|
+
deployer_cls = _DEPLOYER_REGISTRY[fmt_name]
|
|
260
|
+
deployer_instance = deployer_cls()
|
|
261
|
+
# Classic respects -t target; adapters always deploy to their own default
|
|
262
|
+
fmt_target = target if fmt_name == "classic" else None
|
|
263
|
+
deployer_instance.deploy(config=config, target=fmt_target)
|
|
264
|
+
return
|
|
265
|
+
|
|
236
266
|
if format not in VALID_FORMATS:
|
|
237
267
|
raise ValueError(f"Unknown format: {format!r}. Valid: {', '.join(VALID_FORMATS)}")
|
|
238
268
|
|
|
@@ -301,10 +331,10 @@ def _deploy_classic(config=None, target=None):
|
|
|
301
331
|
d.mkdir(parents=True, exist_ok=True)
|
|
302
332
|
|
|
303
333
|
# Deploy components filtered by config
|
|
304
|
-
enabled_skills = config.get("skills",
|
|
305
|
-
enabled_rules = config.get("rules",
|
|
306
|
-
enabled_agents = config.get("agents",
|
|
307
|
-
enabled_commands = config.get("commands",
|
|
334
|
+
enabled_skills = config.get("skills", sorted(VALID_SKILLS))
|
|
335
|
+
enabled_rules = config.get("rules", sorted(VALID_RULES))
|
|
336
|
+
enabled_agents = config.get("agents", sorted(VALID_AGENTS))
|
|
337
|
+
enabled_commands = config.get("commands", sorted(VALID_COMMANDS))
|
|
308
338
|
|
|
309
339
|
classic_profile = get_profile("classic")
|
|
310
340
|
n_skills = _deploy_skills(skills_dir, enabled_skills, profile=classic_profile)
|
|
@@ -171,8 +171,8 @@ FORMAT_PROFILES: dict[str, FormatProfile] = {
|
|
|
171
171
|
# Deployment modes that are not environment formats
|
|
172
172
|
_DEPLOYMENT_MODES: frozenset[str] = frozenset({"plugin", "marketplace"})
|
|
173
173
|
|
|
174
|
-
# All valid --format values: environment profiles + deployment modes
|
|
175
|
-
VALID_FORMATS: frozenset[str] = frozenset(FORMAT_PROFILES.keys()) | _DEPLOYMENT_MODES
|
|
174
|
+
# All valid --format values: "all" + environment profiles + deployment modes
|
|
175
|
+
VALID_FORMATS: frozenset[str] = frozenset({"all"}) | frozenset(FORMAT_PROFILES.keys()) | _DEPLOYMENT_MODES
|
|
176
176
|
|
|
177
177
|
# Ordered candidate paths for pactkit.yaml discovery (first existing wins)
|
|
178
178
|
# Order = preference: OpenCode > Codex > Classic
|