claude-code-conductor 2.73.0__tar.gz → 2.75.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.
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/docs/config-policy.md +24 -1
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/hooks/statusline.py +6 -3
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.gitignore +4 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/CHANGELOG.md +62 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/PKG-INFO +27 -1
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/README.md +26 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/__init__.py +1 -1
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/cli_init.py +74 -2
- claude_code_conductor-2.75.0/tests/_sync_semantics.py +421 -0
- claude_code_conductor-2.75.0/tests/conftest.py +57 -0
- claude_code_conductor-2.75.0/tests/hooks/test_statusline_reconfigure_guard.py +197 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_claude_gitignore.py +13 -2
- claude_code_conductor-2.75.0/tests/test_cli_init_symlink_guard.py +704 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_statusline.py +10 -1
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_stop_agent_memory_warn.py +5 -22
- claude_code_conductor-2.75.0/tests/test_three_file_sync.py +1316 -0
- claude_code_conductor-2.73.0/tests/conftest.py +0 -15
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/.gitignore +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/CLAUDE.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/agents/architect.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/agents/code-reviewer.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/agents/design-critic.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/agents/developer.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/agents/doc-writer.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/agents/interviewer.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/agents/planner.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/agents/project-setup.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/agents/security-reviewer.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/agents/systematic-debugger.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/agents/tester.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/agents/wt_developer.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/agents/wt_systematic-debugger.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/agents/wt_tester.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/breaking-changes.txt +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/deletions.txt +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/docs/autonomous-mode-onboarding.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/docs/nul-boundary.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/docs/parallel-agents-setup.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/docs/platform-adapters.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/docs/settings.json.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/hooks/_hook_utils.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/hooks/check_agent_invocation.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/hooks/consolidate_memory.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/hooks/patterns_guard.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/hooks/planner_check.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/hooks/post_tool.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/hooks/pre_compact.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/hooks/pre_tool.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/hooks/recall_autorebuild.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/hooks/recall_inject.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/hooks/report_contract_check.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/hooks/report_path_guard.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/hooks/restore_session.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/hooks/select_tier.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/hooks/session_mode_watch.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/hooks/session_start.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/hooks/session_stop.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/hooks/session_utils.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/hooks/stop.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/hooks/tier_autoapply.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/hooks/tier_gap_check.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/hooks/worktree_guard.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/memory/.gitkeep +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/memory/archive/.gitkeep +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/memory/sessions/.gitkeep +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/reports/.gitkeep +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/rules/judgment-principles.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/rules/promoted/index.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/settings.json +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/autonomous-mode/SKILL.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/autonomous-mode/scripts/mode_line.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/brainstorm/SKILL.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/codex-review/SKILL.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/dev-workflow/SKILL.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/dev-workflow/references/c3-omission-declaration.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/dev-workflow/references/code-review-checklist.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/dev-workflow/references/design-critic-rubric.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/dev-workflow/references/design-rubric.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/dev-workflow/references/interview-rubric.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/dev-workflow/references/plan-design-guidelines.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/dev-workflow/references/reachability-map.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/dev-workflow/references/record-protocol.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/dev-workflow/references/security-review-checklist.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/dev-workflow/scripts/detect_execution_verification.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/dev-workflow/scripts/record_agent_outcome.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/dev-workflow/scripts/record_review_decision.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/dev-workflow/scripts/review_hint_inject.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/develop/SKILL.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/doc/SKILL.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/extract-lib/SKILL.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/init-session/SKILL.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/init-session/scripts/session_guard.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/mcp-config/SKILL.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/parallel-agents/SKILL.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/pattern-status/SKILL.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/promote-pattern/SKILL.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/recall/SKILL.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/report-timestamp/SKILL.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/report-timestamp/scripts/get_timestamp.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/review-phase/SKILL.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/setup/SKILL.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/setup/reference.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/setup/templates/coding-standards-template.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/setup/templates/project-conventions-template.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/start/SKILL.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/skills/start/scripts/archive_reports.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/state/.gitkeep +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/state/setup_done.flag +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/.claude/tmp/.gitkeep +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/ARCHITECTURE.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/LICENSE +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/LICENSES/fastembed-LICENSE +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/LICENSES/fastembed-NOTICE +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/LICENSES/numpy-LICENSE +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/LICENSES/onnxruntime-LICENSE +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/LICENSES/paraphrase-multilingual-MiniLM-L12-v2-LICENSE +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/hatch_build.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/pyproject.toml +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/__main__.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/_db_params.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/_excludes.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/_terminal.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/adapters.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/cli.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/cli_ask.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/cli_doctor.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/cli_list.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/cli_metrics.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/cli_plan.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/cli_recall.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/cli_run.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/cli_tier.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/cli_update.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/db.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/embedding.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/gitutil.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/mcp_server.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/migrate.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/migrations/001_initial.sql +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/migrations/002_agent_cost_runs.sql +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/migrations/003_tier_cost.sql +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/migrations/004_agent_outcomes.sql +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/migrations/005_drop_agent_tier_bandit.sql +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/migrations/006_review_decisions_severity.sql +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/migrations/007_review_decisions_resolution.sql +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/migrations/008_drop_agent_runs.sql +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/migrations/README.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/migrations/__init__.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/paths.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/plan_validator.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/platforms.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/pricing.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/question.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/recall_chunker.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/recall_index.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/refgraph.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/src/c3/usage_ingester.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/__init__.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/_pre_compact_helpers.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/fixtures/usage/README.md +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/fixtures/usage/mainline.jsonl +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/fixtures/usage/subagents/agent-deadbeef.jsonl +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/fixtures/usage/subagents/agent-deadbeef.meta.json +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/__init__.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_check_agent_invocation.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_consolidate_memory.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_detect_execution_verification.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_hook_utils.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_pip_reinstall_reminder.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_planner_check.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_planner_check_dev.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_post_tool.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_pre_tool.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_recall_autorebuild.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_recall_inject.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_record_agent_outcome.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_record_review_decision.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_report_path_guard.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_restore_session.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_review_hint_inject.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_select_tier.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_select_tier_escalation.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_session_start.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_session_stop.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_session_utils.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_settings_local_absolute_paths.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_settings_tier_autoapply_registration.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_similarity_boost.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_statusline.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_statusline_template_sync.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_sync_check.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_template_guard.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_tier_autoapply.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_tier_gap_check.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/hooks/test_tier_security_fixes.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/skills/__init__.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/skills/_skill_helpers.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/skills/test_c3_omission_declaration.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/skills/test_dev_workflow_no_task_type.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/skills/test_e0_verification_exit.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/skills/test_init_session_no_task_type.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/skills/test_marker_compliance.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/skills/test_parallel_agents_skill_tier.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/skills/test_planner_lightweight.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/skills/test_reachability_map.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/skills/test_recall_skill.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/skills/test_session_backlog_reconciliation.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/skills/test_session_guard.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/skills/test_setup_templates.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/skills/test_start_skill_bugfix_flow.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/skills/test_start_skill_new_flow.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/skills/test_start_skill_security_audit_phase.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_adapters.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_archive_reports.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_audit_review_decisions.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_check_deletions.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_ci_workflows.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_cli_ask.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_cli_doctor.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_cli_doctor_launcher.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_cli_entry.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_cli_init.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_cli_list.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_cli_metrics.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_cli_plan.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_cli_recall.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_cli_run.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_cli_tier.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_cli_update_breaking_changes.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_cli_update_deletions.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_db.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_db_connect_lint.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_docstring_consistency.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_embedding.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_excludes.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_extract_breaking_changes.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_gitutil.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_hooks_stdin_idiom.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_init_only_patterns.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_mcp_server_elicit.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_migrate.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_mode_line.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_no_bare_python_launcher.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_no_passonly_tests.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_nul_boundary_lint.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_paths.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_patterns_guard.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_permission_handler_removal.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_plan_validator.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_pre_compact.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_pre_tool_hook.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_precompact_additional.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_precompact_toctou_fixes.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_pricing.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_recall_chunker.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_recall_index.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_references_migration.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_refgraph.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_refgraph_query.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_refgraph_structural.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_report_contract_check.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_scripts_src_bootstrap.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_scripts_stdout_encoding.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_session_mode_watch.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_session_utils_additional.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_settings_hooks_registration.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_skill_no_builtin_conflict.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_start_skill_archive_contract.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_stop_additional.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_stop_hook.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_stop_precompact_fixes.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_sync_template_stop.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_template_pre_tool_hook.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_usage_ingester.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_verify_wheel.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_worktree_guard.py +0 -0
- {claude_code_conductor-2.73.0 → claude_code_conductor-2.75.0}/tests/test_wt_agent_sync.py +0 -0
|
@@ -283,17 +283,40 @@ C3 の wheel 配布除外パターンは **3 つのファイルに分散して
|
|
|
283
283
|
**KEEP 対象が sdist exclude 配下にある場合は `pyproject.toml` の force-include も同期対象**:
|
|
284
284
|
公開ビルドは sdist を経由するため、sdist から落ちたファイルは wheel にも届かない。
|
|
285
285
|
|
|
286
|
+
この辺(KEEP ↔ sdist exclude / force-include)は `tests/test_three_file_sync.py` が双方向に機械検証する
|
|
287
|
+
(救済漏れと、用途不明な force-include キーの増殖の両方を検出する)。
|
|
288
|
+
ただし **KEEP に相当する配布必須ファイルは force-include による救済を認めず、ignore 規則そのもの(否定行)で戻す**
|
|
289
|
+
(force-include で救うと git 履歴から消える脆い救済になるため。force-include が担うのは sdist exclude 経路の救済に限る)。
|
|
290
|
+
この検査は**配布元 C3 のリポジトリ専用**である: 配布元 C3 が公開する wheel に `tests/` は含まれず、
|
|
291
|
+
利用先プロジェクトにこの検査は配置されない。ただし**配布元 C3 が PyPI へ公開する第二の成果物である
|
|
292
|
+
sdist には `tests/` が含まれる**(`pyproject.toml` の sdist `include`)。sdist は PyPI で公開されるため
|
|
293
|
+
`tests/` 配下の内容は第三者が閲覧可能であり、機密情報を書いてはならない。
|
|
294
|
+
|
|
286
295
|
### 同期確認の方法
|
|
287
296
|
|
|
288
297
|
`.dev/hooks/_sync_check.py`(PostToolUse hook)が、3 ファイルのいずれかを変更した時に
|
|
289
298
|
残り 2 ファイルの同期を `stderr` で警告する。警告が出たら必ず対応する。
|
|
290
299
|
|
|
300
|
+
同期の実効一致はテスト 2 本が機械検証する(hook の警告は編集時の即時注意喚起、テストは CI /
|
|
301
|
+
フルスイートでの機械判定という役割分担):
|
|
302
|
+
|
|
303
|
+
| テスト | 検証する辺 |
|
|
304
|
+
|---|---|
|
|
305
|
+
| `tests/test_excludes.py` | `_excludes.py` ↔ `hatch_build.py`(パターン集合の完全一致) |
|
|
306
|
+
| `tests/test_three_file_sync.py` | `.gitignore` ↔ `_excludes.py`(挙動の一致)・`pyproject.toml` の sdist exclude / force-include |
|
|
307
|
+
|
|
308
|
+
これらのテストも**配布元 C3 のリポジトリ専用**である: 配布元 C3 が公開する wheel に `tests/` は
|
|
309
|
+
含まれず、利用先プロジェクトにこれらのテストは配置されない。ただし**配布元 C3 が PyPI へ公開する
|
|
310
|
+
第二の成果物である sdist には `tests/` が含まれる**(`pyproject.toml` の sdist `include`)。
|
|
311
|
+
sdist は PyPI で公開されるため `tests/` 配下の内容は第三者が閲覧可能であり、機密情報を書いてはならない。
|
|
312
|
+
|
|
291
313
|
### 変更手順
|
|
292
314
|
|
|
293
315
|
1. `.gitignore` / `_excludes.py` / `hatch_build.py` のいずれかを変更
|
|
294
316
|
2. `_sync_check.py` の警告を確認
|
|
295
317
|
3. 残り 2 ファイルに同じパターンを追加(または削除)。3 ファイルが既に同じ意図を持っている場合は、出遅れた 1 ファイルを合わせるだけでよい(配布元の root `.gitignore` を `KEEP_PATTERNS` の意図へ合わせた 2026-08-14 の是正が実例)
|
|
296
|
-
4.
|
|
318
|
+
4. 意図的差分(3 ファイルの意図をあえて揃えない例外)を増減する場合は、`tests/test_three_file_sync.py` の許容リスト(理由文字列必須)と件数定数群を同時更新する(配布元専用。増減いずれの場合もレビュー対象)
|
|
319
|
+
5. 配布元では `python scripts/verify_wheel.py` で wheel 実体を機械検証する(`scripts/` は配布物に含まれないため、利用先には存在しないコマンド)
|
|
297
320
|
|
|
298
321
|
### 過去の同期漏れ defect
|
|
299
322
|
|
|
@@ -13,9 +13,12 @@ import threading
|
|
|
13
13
|
from datetime import datetime, timezone
|
|
14
14
|
from typing import Any
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
sys.
|
|
18
|
-
sys.
|
|
16
|
+
try:
|
|
17
|
+
sys.stdin.reconfigure(encoding='utf-8')
|
|
18
|
+
sys.stdout.reconfigure(encoding='utf-8')
|
|
19
|
+
sys.stderr.reconfigure(encoding='utf-8')
|
|
20
|
+
except AttributeError:
|
|
21
|
+
pass
|
|
19
22
|
|
|
20
23
|
MAX_INPUT = 64 * 1024 # 64 KB
|
|
21
24
|
|
|
@@ -86,3 +86,7 @@ site/
|
|
|
86
86
|
# Personal Claude Code overrides (per-user / per-worktree, never committed)
|
|
87
87
|
# wheel からは _excludes.py / hatch_build.py で既に除外済み。git でも tracking しない方針。
|
|
88
88
|
.claude/settings.local.json
|
|
89
|
+
|
|
90
|
+
# agent 作業残骸 pytest_temp.ini の再発防止ガード(2026-05-02 混入・v0.4.2〔44be00f〕で削除+
|
|
91
|
+
# EXCLUDE_PATTERNS ガード化。本行はその git 側の対)
|
|
92
|
+
.claude/pytest_temp.ini
|
|
@@ -1,5 +1,67 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.75.0] - 2026-08-16
|
|
4
|
+
|
|
5
|
+
### 追加
|
|
6
|
+
|
|
7
|
+
- **`c3 init` のテンプレート展開(`_copytree`)に symlink / NTFS ジャンクション防御を追加した**:
|
|
8
|
+
各 entry の realpath が「コピー元ルートの realpath + 相対パス」と完全一致することを検査し、
|
|
9
|
+
一致しない entry(symlink・ジャンクション・壊れたリンク)はコピーせず stderr へ 1 件 1 行の警告を
|
|
10
|
+
出してスキップする。`is_symlink()` 単体判定はジャンクションに `False` を返すため採用せず、
|
|
11
|
+
realpath 完全一致方式に一本化した。比較の両辺とも realpath 済みのため、コピー元ルート自体が
|
|
12
|
+
リンク経由(macOS の `/tmp` 等)でも全件スキップに縮退しない。加えて:
|
|
13
|
+
- entry 側の realpath が `OSError`(`ELOOP` 含む)を送出した場合は「リンク疑い」として
|
|
14
|
+
警告付きスキップに倒す(fail-soft・`c3 init` 全体は異常終了しない。ルート側の解決不能は
|
|
15
|
+
テンプレート根本の異常のため従来どおり例外で停止する)
|
|
16
|
+
- `shutil.copy2` 直前にリンク再検証を行い、検査とコピーの間の差し替え(TOCTOU)の窓を狭めた
|
|
17
|
+
(残余の窓は脅威モデル上許容・docstring に記録)
|
|
18
|
+
- 性質テスト `tests/test_cli_init_symlink_guard.py` を新設(symlink 系・ジャンクション実測・
|
|
19
|
+
ルートをリンク経由で渡す回帰ガード・例外系/再検証の検知テストを含む)。ジャンクション/リンク作成の
|
|
20
|
+
テストヘルパー `_make_link` は `tests/conftest.py` へ共有化した
|
|
21
|
+
- `.claude/hooks/statusline.py` の reconfigure 保護テスト
|
|
22
|
+
`tests/hooks/test_statusline_reconfigure_guard.py` を新設した(`reconfigure` 属性を持たない
|
|
23
|
+
ストリーム環境でも hook のロードがクラッシュしないこと)
|
|
24
|
+
|
|
25
|
+
### 変更
|
|
26
|
+
|
|
27
|
+
- `.claude/hooks/statusline.py` のストリーム reconfigure を canonical 順序(stdin→stdout→stderr)+
|
|
28
|
+
`try/except AttributeError` の確立イディオムへ統一した(配布 hook 22 本で唯一の無保護だった)
|
|
29
|
+
- `README.md` / `docs/getting-started.md` の前提条件に仮想環境(venv)の作成手順を追加した。
|
|
30
|
+
PEP 668(externally-managed-environment)環境で素の `pip install` が失敗する旨と、
|
|
31
|
+
隔離環境の但し書き 3 点(Claude Code を起動するシェルでも同じ venv を activate すること・
|
|
32
|
+
`pipx install claude-code-conductor` の代替・同一シェルでの `c3 doctor` による PATH 解決確認)を明記した
|
|
33
|
+
- root `.gitignore` に `.claude/pytest_temp.ini` のガード行を追加した(2026-05-02 に agent 作業残骸として
|
|
34
|
+
混入し v0.4.2 で削除+`EXCLUDE_PATTERNS` ガード化された経緯の git 側の対)。これに伴い
|
|
35
|
+
`tests/test_three_file_sync.py` の許容リスト A から同エントリを削除し、実効検査件数の下限を
|
|
36
|
+
16 / 16(遊びなし)へ締めた
|
|
37
|
+
|
|
38
|
+
## [2.74.0] - 2026-08-15
|
|
39
|
+
|
|
40
|
+
### 追加
|
|
41
|
+
|
|
42
|
+
- **3 ファイル同期(`.gitignore` / `_excludes.py` / `pyproject.toml`)を機械検証化した**:
|
|
43
|
+
`tests/test_three_file_sync.py`(検査)と `tests/_sync_semantics.py`(検出器・引数注入の
|
|
44
|
+
純粋関数)を追加した。これまで `.dev/hooks/_sync_check.py` の警告(編集時の注意喚起)しか
|
|
45
|
+
無かった辺を、CI / フルスイートで機械判定する:
|
|
46
|
+
- 辺 1: `_excludes.py` の `EXCLUDE_PATTERNS` / `KEEP_PATTERNS` と root `.gitignore` の意図一致を、
|
|
47
|
+
表記の一致ではなく**挙動の一致**(プローブパス+`git check-ignore` の実挙動/`should_skip`)で
|
|
48
|
+
双方向に検証する
|
|
49
|
+
- 辺 2: `KEEP_PATTERNS` と `pyproject.toml` の sdist force-include を双方向に検証する
|
|
50
|
+
(救済漏れと、用途不明な force-include キーの増殖の両方を検出)
|
|
51
|
+
- 辺 3: sdist exclude の `.claude/` エントリが `should_skip` の意図と整合することを検証する
|
|
52
|
+
|
|
53
|
+
意図的差分は理由文字列必須の許容リストとして明示し、実効検査件数の下限・許容リスト件数を
|
|
54
|
+
凍結して「何も検査していないのに緑」になる退化を塞いでいる。
|
|
55
|
+
`.dev/hooks/_sync_check.py` は編集時の即時フィードバック層として存置する。
|
|
56
|
+
|
|
57
|
+
### 変更
|
|
58
|
+
|
|
59
|
+
- `/CLAUDE.md` §2 と `.claude/docs/config-policy.md` §6 に、上記の機械検証 2 本と
|
|
60
|
+
許容リスト・件数定数群の同時更新の運用を追記した(**配布元 C3 のリポジトリ専用の検査**である旨の
|
|
61
|
+
但し書き付き。配布元 C3 が公開する wheel に `tests/` は含まれず利用先プロジェクトには配置されないが、
|
|
62
|
+
配布元 C3 が PyPI へ公開する第二の成果物である sdist には `tests/` が含まれる。sdist は PyPI で
|
|
63
|
+
公開されるため `tests/` 配下の内容は第三者が閲覧可能であり、機密情報を書いてはならない)。
|
|
64
|
+
|
|
3
65
|
## [2.73.0] - 2026-08-15
|
|
4
66
|
|
|
5
67
|
### 追加
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: claude-code-conductor
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.75.0
|
|
4
4
|
Summary: Multi-agent orchestration framework for Claude Code with Codex/Cursor adapters (C3)
|
|
5
5
|
Project-URL: Homepage, https://github.com/satoh-y-0323/claude-code-conductor
|
|
6
6
|
Project-URL: Repository, https://github.com/satoh-y-0323/claude-code-conductor
|
|
@@ -268,6 +268,30 @@ C3 の `.claude/` はプロジェクトコードに一切触れません。既
|
|
|
268
268
|
- [Claude Code](https://claude.ai/code) がインストール済みでログインしていること
|
|
269
269
|
- Python 3.10 以上がインストール済みであること
|
|
270
270
|
|
|
271
|
+
**仮想環境(venv)の準備(推奨)**
|
|
272
|
+
|
|
273
|
+
Python の導入方法によっては、素の `pip install` が PEP 668(externally-managed-environment)により拒否されます(Debian/Ubuntu の apt 版 Python、Homebrew の Python など)。仮想環境(venv)を作ってその中へインストールすれば、この制約を受けずに済みます。
|
|
274
|
+
|
|
275
|
+
Windows(PowerShell):
|
|
276
|
+
|
|
277
|
+
```powershell
|
|
278
|
+
python -m venv .venv
|
|
279
|
+
.\.venv\Scripts\Activate.ps1
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
macOS / Linux:
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
python3 -m venv .venv
|
|
286
|
+
source .venv/bin/activate
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
venv に入れた場合の注意:
|
|
290
|
+
|
|
291
|
+
- C3 の hook は `c3 run` で起動されるため、**Claude Code を起動するシェルでも同じ venv を activate してください**。activate されていないシェルから Claude Code を起動すると `c3` が見つからず、hook が動作しません
|
|
292
|
+
- venv を使わずグローバルに使いたい場合は [pipx](https://pipx.pypa.io/) が代替になります: `pipx install claude-code-conductor`
|
|
293
|
+
- インストール後は、**Claude Code を起動するのと同じシェルで** `c3 doctor` を実行し、`c3` が PATH で解決されることを確認してください(`c3 doctor` が検査するのは実行中シェルの PATH です。別のシェルで実行しても、Claude Code の hook が起動される文脈は再現できません)
|
|
294
|
+
|
|
271
295
|
### 手順(推奨: PyPI から)
|
|
272
296
|
|
|
273
297
|
**1. C3 をインストールする**
|
|
@@ -276,6 +300,8 @@ C3 の `.claude/` はプロジェクトコードに一切触れません。既
|
|
|
276
300
|
pip install claude-code-conductor
|
|
277
301
|
```
|
|
278
302
|
|
|
303
|
+
> このコマンドが PEP 668(externally-managed-environment)で拒否される場合や、インストール後に hook が動作しない場合は、[前提条件](#前提条件)の venv 手順(activate するシェルの注意点を含む)を参照してください。
|
|
304
|
+
|
|
279
305
|
**2. プロジェクトに `.claude/` を展開する**
|
|
280
306
|
|
|
281
307
|
```bash
|
|
@@ -223,6 +223,30 @@ C3 の `.claude/` はプロジェクトコードに一切触れません。既
|
|
|
223
223
|
- [Claude Code](https://claude.ai/code) がインストール済みでログインしていること
|
|
224
224
|
- Python 3.10 以上がインストール済みであること
|
|
225
225
|
|
|
226
|
+
**仮想環境(venv)の準備(推奨)**
|
|
227
|
+
|
|
228
|
+
Python の導入方法によっては、素の `pip install` が PEP 668(externally-managed-environment)により拒否されます(Debian/Ubuntu の apt 版 Python、Homebrew の Python など)。仮想環境(venv)を作ってその中へインストールすれば、この制約を受けずに済みます。
|
|
229
|
+
|
|
230
|
+
Windows(PowerShell):
|
|
231
|
+
|
|
232
|
+
```powershell
|
|
233
|
+
python -m venv .venv
|
|
234
|
+
.\.venv\Scripts\Activate.ps1
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
macOS / Linux:
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
python3 -m venv .venv
|
|
241
|
+
source .venv/bin/activate
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
venv に入れた場合の注意:
|
|
245
|
+
|
|
246
|
+
- C3 の hook は `c3 run` で起動されるため、**Claude Code を起動するシェルでも同じ venv を activate してください**。activate されていないシェルから Claude Code を起動すると `c3` が見つからず、hook が動作しません
|
|
247
|
+
- venv を使わずグローバルに使いたい場合は [pipx](https://pipx.pypa.io/) が代替になります: `pipx install claude-code-conductor`
|
|
248
|
+
- インストール後は、**Claude Code を起動するのと同じシェルで** `c3 doctor` を実行し、`c3` が PATH で解決されることを確認してください(`c3 doctor` が検査するのは実行中シェルの PATH です。別のシェルで実行しても、Claude Code の hook が起動される文脈は再現できません)
|
|
249
|
+
|
|
226
250
|
### 手順(推奨: PyPI から)
|
|
227
251
|
|
|
228
252
|
**1. C3 をインストールする**
|
|
@@ -231,6 +255,8 @@ C3 の `.claude/` はプロジェクトコードに一切触れません。既
|
|
|
231
255
|
pip install claude-code-conductor
|
|
232
256
|
```
|
|
233
257
|
|
|
258
|
+
> このコマンドが PEP 668(externally-managed-environment)で拒否される場合や、インストール後に hook が動作しない場合は、[前提条件](#前提条件)の venv 手順(activate するシェルの注意点を含む)を参照してください。
|
|
259
|
+
|
|
234
260
|
**2. プロジェクトに `.claude/` を展開する**
|
|
235
261
|
|
|
236
262
|
```bash
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import argparse
|
|
6
|
+
import os
|
|
6
7
|
import shutil
|
|
7
8
|
import sys
|
|
8
9
|
from collections.abc import Callable
|
|
@@ -181,28 +182,99 @@ def _do_git_init(target_root: Path) -> None:
|
|
|
181
182
|
)
|
|
182
183
|
|
|
183
184
|
|
|
184
|
-
def
|
|
185
|
+
def _is_link_entry(entry: Path, real_root: str, rel: str) -> bool:
|
|
186
|
+
"""FR-4 choke point: realpath 完全一致でリンク経由の entry を検出する。
|
|
187
|
+
|
|
188
|
+
``entry.is_symlink()`` は NTFS ディレクトリジャンクションに ``False`` を返し
|
|
189
|
+
素通りする(ADR-3・既知パターンの再発 5 回)ため採用しない。判定は
|
|
190
|
+
「entry の realpath」と「コピー元ルートの realpath + ルートからの相対パス」の
|
|
191
|
+
完全一致(``.claude/skills/start/scripts/archive_reports.py`` の
|
|
192
|
+
``_archive_dir_is_contained`` と同じ realpath 封じ込め方式)。
|
|
193
|
+
|
|
194
|
+
``real_root`` は**呼び出し側で解決済みの** コピー元ルートの realpath(文字列)を
|
|
195
|
+
受け取る契約(ADR-3 追補 2・``_copytree`` が再帰境界で 1 回だけ計算して伝播する)。
|
|
196
|
+
本関数は root 側の realpath を行わない。比較の両辺とも realpath 済みであることが
|
|
197
|
+
判定の前提であり、その担保は呼び出し側の責務になる。
|
|
198
|
+
|
|
199
|
+
entry 側の realpath は ``OSError``(ELOOP・EACCES 等)を送出しうる。解決できない
|
|
200
|
+
entry は安全側に倒して「リンク疑い(``True``)」として扱い、呼び出し側の
|
|
201
|
+
警告付きスキップに委ねる(fail-soft・ADR-3 追補 1)。
|
|
202
|
+
"""
|
|
203
|
+
# expected は「rel の各コンポーネントをリンクとして解決せず」文字列結合した
|
|
204
|
+
# 期待パス。os.path.realpath はここでは呼ばない(呼ぶと entry 側と同じ
|
|
205
|
+
# リンクを辿ってしまい、判定そのものが無効化される)。
|
|
206
|
+
expected = os.path.normpath(os.path.join(real_root, *rel.split("/")))
|
|
207
|
+
try:
|
|
208
|
+
actual = os.path.realpath(entry)
|
|
209
|
+
except OSError:
|
|
210
|
+
return True
|
|
211
|
+
return actual != expected
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def _copytree(
|
|
215
|
+
src: Path, dst: Path, *, root: Path | None = None, real_root: str | None = None
|
|
216
|
+
) -> int:
|
|
185
217
|
"""Copy ``src`` -> ``dst`` recursively, skipping personal/working files.
|
|
186
218
|
|
|
187
219
|
``root`` defaults to ``src`` and represents the ``.claude/`` directory; the
|
|
188
220
|
relative path from ``root`` is what ``should_skip`` matches against.
|
|
189
221
|
Returns the number of regular files written.
|
|
222
|
+
|
|
223
|
+
``real_root`` は ``root`` の realpath(解決済み文字列)。``None`` の初回呼び出しで
|
|
224
|
+
1 回だけ計算し、再帰には計算済みの値を渡す(ADR-3 追補 2 の hoist。entry 総数 N 回の
|
|
225
|
+
重複計算を 1 回に落とす)。
|
|
226
|
+
|
|
227
|
+
root 側 realpath の失敗(``OSError``)は捕捉せず伝播させる。root が解決不能なのは
|
|
228
|
+
テンプレート根本の異常であり、全 entry を「リンク疑い」として警告付きスキップし
|
|
229
|
+
「0 件コピーの exit 0」を返すより、例外で止める方が利用者に正しく伝わるため
|
|
230
|
+
(per-entry の fail-soft はコピー継続に意味がある場合の設計であり、根本が解決不能なら
|
|
231
|
+
継続に意味がない・ADR-3 追補 1)。
|
|
232
|
+
|
|
233
|
+
リンク判定 ``_is_link_entry`` の適用位置はファイル経路の 2 箇所のみ:
|
|
234
|
+
(i) ``should_skip`` 前段の初回判定 (ii) ``shutil.copy2`` 直前の再検証。
|
|
235
|
+
ディレクトリ側に再検証は追加しない。ディレクトリ entry が判定後にリンクへ
|
|
236
|
+
差し替わっても、再帰先の per-entry 検査で全子 entry の realpath が
|
|
237
|
+
``real_root`` + rel と一致しなくなり内容は漏れないため(構造的再検証・ADR-3 追補 3)。
|
|
190
238
|
"""
|
|
191
239
|
if root is None:
|
|
192
240
|
root = src
|
|
241
|
+
if real_root is None:
|
|
242
|
+
# root 側の realpath はここで 1 回だけ。失敗は上記のとおり伝播させる。
|
|
243
|
+
real_root = os.path.realpath(root)
|
|
193
244
|
dst.mkdir(parents=True, exist_ok=True)
|
|
194
245
|
count = 0
|
|
195
246
|
for entry in src.iterdir():
|
|
196
247
|
rel = entry.relative_to(root).as_posix()
|
|
197
248
|
target = dst / entry.name
|
|
249
|
+
# FR-4: リンク経由の entry は is_dir()/is_file() 分岐より前にスキップする
|
|
250
|
+
# (両者ともリンクを暗黙に辿るため)。EXCLUDE 対象かどうかに関わらず
|
|
251
|
+
# 検査するため should_skip より前段に置く(架空の EXCLUDE リンクも警告する・
|
|
252
|
+
# architecture DC-GP-003 裁定)。
|
|
253
|
+
if _is_link_entry(entry, real_root, rel):
|
|
254
|
+
print(
|
|
255
|
+
f"c3 init: リンク(symlink/junction)疑いの entry をスキップしました: {rel}",
|
|
256
|
+
file=sys.stderr,
|
|
257
|
+
)
|
|
258
|
+
continue
|
|
198
259
|
if entry.is_dir():
|
|
199
|
-
count += _copytree(entry, target, root=root)
|
|
260
|
+
count += _copytree(entry, target, root=root, real_root=real_root)
|
|
200
261
|
# Drop directories that ended up empty (everything inside was skipped).
|
|
201
262
|
if not any(target.iterdir()):
|
|
202
263
|
target.rmdir()
|
|
203
264
|
elif entry.is_file():
|
|
204
265
|
if should_skip(rel):
|
|
205
266
|
continue
|
|
267
|
+
# 初回判定から copy2 到達までの間にリンクへ差し替わる TOCTOU を狭めるため、
|
|
268
|
+
# copy2 の直前で同じ choke point を再検証する(ADR-3 追補 3)。
|
|
269
|
+
# 残余リスク: 再検証と copy2 の間の窓は閉じない。窓を閉じる ``O_NOFOLLOW`` は
|
|
270
|
+
# POSIX 限定で Windows を含む配布対象では採用できないため不採用とし、
|
|
271
|
+
# 脅威モデル(ローカル開発者ツール)上この残余窓は許容する(ADR-3 追補 5)。
|
|
272
|
+
if _is_link_entry(entry, real_root, rel):
|
|
273
|
+
print(
|
|
274
|
+
f"c3 init: リンク(symlink/junction)疑いの entry をスキップしました: {rel}",
|
|
275
|
+
file=sys.stderr,
|
|
276
|
+
)
|
|
277
|
+
continue
|
|
206
278
|
shutil.copy2(entry, target)
|
|
207
279
|
count += 1
|
|
208
280
|
return count
|