wade-cli 0.53.0__tar.gz → 0.54.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.
- {wade_cli-0.53.0 → wade_cli-0.54.0}/CHANGELOG.md +12 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/PKG-INFO +26 -12
- {wade_cli-0.53.0 → wade_cli-0.54.0}/README.md +25 -11
- {wade_cli-0.53.0 → wade_cli-0.54.0}/docs/dev/architecture.md +31 -11
- {wade_cli-0.53.0 → wade_cli-0.54.0}/pyproject.toml +1 -1
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/__init__.py +1 -1
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/cli/main.py +7 -4
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/cli/review.py +2 -2
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/models/config.py +23 -10
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/ai_resolution.py +14 -11
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/implementation_service/core.py +55 -15
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/plan_service.py +4 -1
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/review_service.py +3 -2
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/utils/terminal.py +97 -1
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_cli/test_work_cli.py +7 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_config/test_loader.py +6 -3
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_ai_resolution.py +25 -5
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_batch_build_cmd.py +2 -2
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_implementation_launch_context.py +162 -10
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_plan_service.py +1 -1
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_review_service.py +3 -3
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_utils/test_terminal_launch.py +40 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/.gitattributes +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/.github/workflows/auto-version.yml +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/.github/workflows/ci.yml +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/.github/workflows/pr-title-lint.yml +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/.github/workflows/publish.yml +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/.github/workflows/release.yml +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/.gitignore +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/.pre-commit-config.yaml +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/.wade.yml +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/AGENTS.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/CONTRIBUTING.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/KNOWLEDGE.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/KNOWLEDGE.ratings.jsonl +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/assets/wade.png +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/docker-compose.e2e.yml +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/docs/dev/documentation-policies.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/docs/dev/extending.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/docs/dev/skills-system.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/docs/dev/testing.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/docs/dev/workflows-and-skills.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/install.sh +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/scripts/auto_version.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/scripts/changelog.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/scripts/check-all.sh +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/scripts/check.sh +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/scripts/fmt.sh +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/scripts/hooks/pre-push +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/scripts/install-hooks.sh +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/scripts/release.sh +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/scripts/setup-worktree.sh +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/scripts/test-concurrency.sh +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/scripts/test-e2e-docker.sh +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/scripts/test-e2e.sh +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/scripts/test-live-ai-taskr.sh +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/scripts/test-live-ai.sh +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/scripts/test-live-gh.sh +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/scripts/test.sh +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/__main__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/cli/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/cli/admin.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/cli/autocomplete.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/cli/deps_session.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/cli/hook.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/cli/implementation_session.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/cli/knowledge.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/cli/plan_session.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/cli/review_pr_comments_session.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/cli/session.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/cli/session_shared.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/cli/skills.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/cli/task.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/cli/worktree.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/config/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/config/loader.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/config/migrations.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/config/schema.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/git/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/git/branch.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/git/hooks.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/git/pr.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/git/repo.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/git/stash.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/git/sync.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/git/worktree.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/hooks/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/hooks/cli.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/hooks/policies.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/logging/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/logging/context.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/logging/setup.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/models/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/models/batch.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/models/delegation.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/models/deps.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/models/events.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/models/hooks.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/models/permission.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/models/readiness.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/models/review.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/models/session.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/models/session_manifest.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/models/skill.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/models/task.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/models/workflow.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/models/worktree.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/providers/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/providers/_pr_delegate.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/providers/base.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/providers/clickup.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/providers/github.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/providers/markdown.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/providers/registry.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/batch_review_service.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/bot_trigger.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/check_service.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/delegation_service.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/deps_service.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/documentation_receipt_service.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/implementation_service/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/implementation_service/_shared.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/implementation_service/batch.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/implementation_service/bootstrap.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/implementation_service/cleanup.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/implementation_service/done.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/implementation_service/draft_pr.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/implementation_service/lifecycle.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/implementation_service/sync.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/implementation_service/usage_tracking.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/init_service/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/init_service/auth.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/init_service/commands.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/init_service/config_io.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/init_service/manifest.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/init_service/migrations.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/init_service/prompts_ai.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/init_service/prompts_setup.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/init_service/shell.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/knowledge_recovery.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/knowledge_search.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/knowledge_service.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/prompt_delivery.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/review_delegation_service.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/review_record_service.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/review_settle.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/session_composition_service.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/skill_diagnostics_service.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/skill_invocation_service.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/smart_start.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/services/task_service.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/skills/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/skills/catalog.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/skills/discovery.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/skills/doc_targets.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/skills/installer.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/skills/materializer.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/skills/pointer.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/skills/resolver.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/skills/validation.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/ui/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/ui/console.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/ui/prompts.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/utils/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/utils/body_markers.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/utils/clipboard.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/utils/conventional.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/utils/filelock.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/utils/gitref.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/utils/http.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/utils/install.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/utils/knowledge_file.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/utils/markdown.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/utils/markers.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/utils/paths.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/utils/plan_validation.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/utils/process.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/utils/safe_state.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/utils/slug.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/utils/stale_base.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/utils/templates.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/utils/token_usage_markdown.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/src/wade/utils/update_check.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/agents-pointer.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/hooks/commit-msg +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/hooks/pre-commit +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/hooks/pre-push +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/prompts/deps-analysis.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/prompts/implement-context.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/prompts/plan-session.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/prompts/review-batch.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/prompts/review-code.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/prompts/review-plan.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/prompts/review-pr-comments.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/prompts/session-start-implement.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/prompts/session-start-plan.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/prompts/session-start-review.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/setup-worktree.sh.example +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/skills/batch-review/SKILL.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/skills/code-review/SKILL.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/skills/dependency-analysis/SKILL.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/skills/implementation/SKILL.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/skills/knowledge/SKILL.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/skills/plan-review/SKILL.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/skills/planning/SKILL.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/skills/review-comments/SKILL.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/skills/task/SKILL.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/skills/task/examples.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/skills/task/plan-format.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/skills/task/reference/session-summary-format.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/statusline-command.sh +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/workflows/_partials/completion.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/workflows/_partials/documentation-step.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/workflows/_partials/interaction-policy.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/workflows/_partials/knowledge-step.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/workflows/_partials/review-budget.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/workflows/implementation.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/workflows/plan.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/workflows/reference/documentation.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/workflows/reference/new-plan.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/workflows/reference/plan-output-contract.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/workflows/reference/pr-summary-format.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/workflows/reference/recovery.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/workflows/reference/session-summary-format.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/workflows/reference/tracking-issues.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/templates/workflows/review-pr-comments.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/concurrency/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/concurrency/test_batch_multi_pr.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/concurrency/test_knowledge_merge.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/concurrency/test_lock_retry.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/concurrency/test_stash_race.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/conftest.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/e2e/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/e2e/_support.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/e2e/conftest.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/e2e/mock_gh_script.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/e2e/test_admin_contract.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/e2e/test_check_contract.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/e2e/test_implement_work_done_contract.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/e2e/test_knowledge_contract.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/e2e/test_mock_gh_contract.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/e2e/test_plan_contract.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/e2e/test_review_contract.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/e2e/test_smart_start_contract.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/e2e/test_task_contract.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/e2e/test_work_sync_list_contract.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/fixtures/live/taskr_header_hi_body.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/fixtures/live/taskr_header_howdy_body.md +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/fixtures/transcripts/claude_session.txt +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/fixtures/transcripts/codex_session.txt +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/fixtures/transcripts/copilot_session.txt +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/fixtures/transcripts/generic_session.txt +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/integration/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/integration/test_autostash.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/integration/test_check.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/integration/test_dynamic_skill_sessions.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/integration/test_git.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/integration/test_implementation_lifecycle.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/integration/test_init.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/integration/test_knowledge.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/integration/test_markdown_provider.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/integration/test_skill_context_budget.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/integration/test_skill_install.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/live/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/live/test_wade_live_ai.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/live/test_wade_live_ai_taskr.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/live/test_wade_live_gh.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/test_cli_basics.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/conftest.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_cli/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_cli/test_done_doc_pass_advisory.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_cli/test_done_review_hint.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_cli/test_knowledge_cli.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_cli/test_review_cli.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_cli/test_session_subapps.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_cli/test_shell_init.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_cli/test_skills_session_cli.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_cli/test_task_cli.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_cli/test_work_ai_flags.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_config/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_config/test_bot_review_config.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_config/test_dynamic_skill_config.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_config/test_merge_strategy_migration.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_config/test_migrations.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_config/test_migrations_atomic.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_console.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_effort.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_git/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_git/test_all_patches_present.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_git/test_branch_list.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_git/test_branch_slugify.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_git/test_detached_worktree.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_git/test_is_merged_into.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_git/test_main_checkout_root.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_git/test_merge_count.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_git/test_pr_base.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_git/test_pr_lookup.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_git/test_pr_retry.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_git/test_pr_title.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_git/test_repo.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_git/test_reset_branch.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_git/test_scaffold_commit.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_git/test_stash_drop.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_git/test_sync_conflicted_files.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_git/test_tip_commit_is_empty.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_git/test_worktree_remove.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_hooks/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_hooks/test_hook_cli.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_hooks/test_policies.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_hooks/test_post_tool_use.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_hooks/test_session_start.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_models/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_models/test_batch.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_models/test_config_models.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_models/test_delegation.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_models/test_deps_models.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_models/test_deps_partition.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_models/test_review.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_models/test_review_expectation.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_models/test_task_models.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_models/test_workflow_models.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_permission_mode.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_providers/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_providers/test_clickup.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_providers/test_github.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_providers/test_github_pr.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_providers/test_markdown.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_batch_pr_index.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_batch_review_service.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_bootstrap_allowlist.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_bootstrap_guard_matcher.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_bootstrap_hook_timeout.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_bootstrap_post_tool_use.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_bootstrap_pre_push.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_bootstrap_session_start.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_bot_trigger.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_catchup.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_catchup_reconcile.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_check.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_cleanup_loss_guard.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_codex_worktree_launch_context.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_delegation_service.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_deps_service.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_documentation_receipt.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_done_gates.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_done_idempotent.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_done_plan_flag.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_done_pr_title_sync.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_draft_pr_base_fetch.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_draft_pr_retarget.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_implementation_done_sync.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_implementation_service.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_implementation_service_resume.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_init.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_init_shell_integration.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_knowledge_recovery.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_knowledge_search.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_knowledge_service.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_managed_git_hooks.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_no_direct_git.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_poll_for_reviews.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_post_implementation_lifecycle.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_pr_lookup_guards.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_pr_summary_path.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_pre_push_backstop.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_preserve_session_data.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_prompt_delivery.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_push_recovery.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_resolve_task_branch.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_resume_autonomy.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_review_delegation_service.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_review_receipts.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_review_records.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_review_status_block.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_skill_diagnostics_service.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_smart_start.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_smart_start_resume.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_stale_base_surface.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_sync_base_branch.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_task_service.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_tracked_managed_files.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_services/test_worktree_gitignore.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_skills/test_crossby_contract.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_skills/test_doc_targets.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_skills/test_dynamic_skills.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_skills/test_generic_builtin_boundaries.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_skills/test_knowledge_attributes.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_skills/test_managed_gitignore.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_skills/test_pointer.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_skills/test_review_budget_partial.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_utils/__init__.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_utils/test_body_markers.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_utils/test_conventional.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_utils/test_filelock.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_utils/test_gitref.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_utils/test_http.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_utils/test_install.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_utils/test_markdown.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_utils/test_markers.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_utils/test_plan_validation.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_utils/test_process.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_utils/test_prompts.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_utils/test_slug.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_utils/test_stale_base.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_utils/test_terminal.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_utils/test_update_check.py +0 -0
- {wade_cli-0.53.0 → wade_cli-0.54.0}/tests/unit/test_yolo.py +0 -0
|
@@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Conventional Commits](https://conventionalcommits.org/).
|
|
6
6
|
|
|
7
|
+
## [v0.54.0] — 2026-08-31
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
- enable Codex implementation network access by default (#475) (0679c81)
|
|
12
|
+
|
|
13
|
+
## [v0.53.1] — 2026-08-31
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
- relaunch Codex with implementation network policy after plan handoff (#473) (202018b)
|
|
18
|
+
|
|
7
19
|
## [v0.53.0] — 2026-08-31
|
|
8
20
|
|
|
9
21
|
### Features
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: wade-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.54.0
|
|
4
4
|
Summary: WADE — Workflow for AI-Driven Engineering
|
|
5
5
|
Project-URL: Homepage, https://github.com/ivanviragine/wade
|
|
6
6
|
Project-URL: Repository, https://github.com/ivanviragine/wade
|
|
@@ -276,7 +276,7 @@ These are invoked by the AI during a session — you normally don't run them by
|
|
|
276
276
|
| `wade plan-session done <plan_dir>` | Finalize a planning session |
|
|
277
277
|
| `wade deps-session check` | Verify the detached dependency-analysis runtime before writing output or staging a knowledge vote |
|
|
278
278
|
|
|
279
|
-
Most workflow commands accept `--ai <tool>`, `--model <model>`, `--effort <level>`, `--permission-mode <tier>`, and `--yolo` to override configured defaults. `plan`, `implement`, and `review pr-comments` accept repeatable `--skill` and `--review-skill` methodology bindings plus `--refresh-skills` for an existing frozen session; `implement-batch` forwards the same binding request to every child session. Standalone plan/code/batch review and `task deps` accept repeatable `--skill`. `implement`, `review pr-comments`, and the `wade <N>` shorthand also accept `--network` / `--no-network` (see [Codex sandbox](#codex-sandbox--network-policy));
|
|
279
|
+
Most workflow commands accept `--ai <tool>`, `--model <model>`, `--effort <level>`, `--permission-mode <tier>`, and `--yolo` to override configured defaults. `plan`, `implement`, and `review pr-comments` accept repeatable `--skill` and `--review-skill` methodology bindings plus `--refresh-skills` for an existing frozen session; `implement-batch` forwards the same binding request to every child session. Standalone plan/code/batch review and `task deps` accept repeatable `--skill`. `implement`, `implement-batch`, `review pr-comments`, and the `wade <N>` shorthand also accept `--network` / `--no-network` (see [Codex sandbox](#codex-sandbox--network-policy)); batch and shorthand forward an explicit flag to the child session they launch. `implement` additionally supports `--detach` (new terminal tab), `--cd` (print worktree path only), and `--base <branch>` (see [Planning & base branches](#planning--base-branches)).
|
|
280
280
|
|
|
281
281
|
## Planning & base branches
|
|
282
282
|
|
|
@@ -707,15 +707,17 @@ needed, and it only affects Codex (every other tool ignores it).
|
|
|
707
707
|
above makes **local** git work (stage, commit, stash, ref updates, and the
|
|
708
708
|
local legs of `sync`/`done`) succeed with **network off**. Only operations that
|
|
709
709
|
reach the network — `git fetch` (hence `sync`) and `git push` (hence the network
|
|
710
|
-
leg of `done`) — need network access
|
|
711
|
-
|
|
712
|
-
pr-comments`,
|
|
710
|
+
leg of `done`) — need network access. It is **enabled by default** for the
|
|
711
|
+
interactive lifecycle commands `wade implement` (including its batch children)
|
|
712
|
+
and `wade review pr-comments`, because their readiness, sync, and completion
|
|
713
|
+
steps require GitHub. Choose offline operation explicitly with `--no-network`,
|
|
714
|
+
or in `.wade.yml`:
|
|
713
715
|
|
|
714
716
|
```yaml
|
|
715
717
|
ai:
|
|
716
|
-
network_access:
|
|
718
|
+
network_access: false # offline opt-out for interactive session commands
|
|
717
719
|
implement:
|
|
718
|
-
network_access:
|
|
720
|
+
network_access: true # per-command override wins
|
|
719
721
|
```
|
|
720
722
|
|
|
721
723
|
The policy applies to the **interactive session commands** — `wade implement`
|
|
@@ -725,10 +727,21 @@ may need `fetch`/`push`. The headless/analytical paths (`plan`, `deps`,
|
|
|
725
727
|
they never fetch or push, so `ai.network_access` does not apply to them and no
|
|
726
728
|
flag enables it there. Precedence for the commands that honor it is
|
|
727
729
|
`--network`/`--no-network` > `ai.<command>.network_access` >
|
|
728
|
-
`ai.network_access` > **
|
|
730
|
+
`ai.network_access` > **on for `implement` and `review_pr_comments`, otherwise
|
|
731
|
+
off**. WADE always passes an explicit pin, so an ambient
|
|
729
732
|
`network_access = true` in your own Codex `config.toml` can never silently
|
|
730
|
-
enable network for a WADE-managed sandbox. Enabling network
|
|
731
|
-
|
|
733
|
+
enable network for a WADE-managed sandbox. Enabling network permits outbound
|
|
734
|
+
access for commands inside the Codex workspace-write sandbox; it does not
|
|
735
|
+
disable filesystem sandboxing or change approval-policy semantics.
|
|
736
|
+
|
|
737
|
+
An accepted single-issue plan handoff starts implementation from a planning
|
|
738
|
+
session that is always network-off. When both the planning tool and resolved
|
|
739
|
+
implementation tool are Codex and the implementation policy resolves to enabled,
|
|
740
|
+
WADE starts a fresh detached Codex context with network explicitly enabled;
|
|
741
|
+
reusing the planner process would retain its immutable network-off sandbox. If
|
|
742
|
+
WADE cannot open that detached context, the handoff fails rather than reporting
|
|
743
|
+
an implementation session ready. Open a new host terminal and run the displayed
|
|
744
|
+
`wade implement <issue> --network` command to continue with the required policy.
|
|
732
745
|
|
|
733
746
|
### Session readiness and least-privilege remediation
|
|
734
747
|
|
|
@@ -789,8 +802,9 @@ timeout still counts as a bounded review attempt, so the review/fix loop cannot
|
|
|
789
802
|
run forever.
|
|
790
803
|
|
|
791
804
|
For Codex, keep `--sandbox workspace-write`; WADE/crossby add only the linked
|
|
792
|
-
worktree's private/common Git metadata directories
|
|
793
|
-
|
|
805
|
+
worktree's private/common Git metadata directories. Implementation and PR-comment
|
|
806
|
+
sessions have network access by default for their GitHub lifecycle; use
|
|
807
|
+
`--no-network` or `ai.network_access: false` when an offline sandbox is required.
|
|
794
808
|
For Claude Code and Cursor, allowlist the worktree/Git metadata paths and only
|
|
795
809
|
the GitHub domains needed by the session rather than choosing unrestricted shell
|
|
796
810
|
access. Copilot and VS Code need network plus usable `gh` credentials in their
|
|
@@ -240,7 +240,7 @@ These are invoked by the AI during a session — you normally don't run them by
|
|
|
240
240
|
| `wade plan-session done <plan_dir>` | Finalize a planning session |
|
|
241
241
|
| `wade deps-session check` | Verify the detached dependency-analysis runtime before writing output or staging a knowledge vote |
|
|
242
242
|
|
|
243
|
-
Most workflow commands accept `--ai <tool>`, `--model <model>`, `--effort <level>`, `--permission-mode <tier>`, and `--yolo` to override configured defaults. `plan`, `implement`, and `review pr-comments` accept repeatable `--skill` and `--review-skill` methodology bindings plus `--refresh-skills` for an existing frozen session; `implement-batch` forwards the same binding request to every child session. Standalone plan/code/batch review and `task deps` accept repeatable `--skill`. `implement`, `review pr-comments`, and the `wade <N>` shorthand also accept `--network` / `--no-network` (see [Codex sandbox](#codex-sandbox--network-policy));
|
|
243
|
+
Most workflow commands accept `--ai <tool>`, `--model <model>`, `--effort <level>`, `--permission-mode <tier>`, and `--yolo` to override configured defaults. `plan`, `implement`, and `review pr-comments` accept repeatable `--skill` and `--review-skill` methodology bindings plus `--refresh-skills` for an existing frozen session; `implement-batch` forwards the same binding request to every child session. Standalone plan/code/batch review and `task deps` accept repeatable `--skill`. `implement`, `implement-batch`, `review pr-comments`, and the `wade <N>` shorthand also accept `--network` / `--no-network` (see [Codex sandbox](#codex-sandbox--network-policy)); batch and shorthand forward an explicit flag to the child session they launch. `implement` additionally supports `--detach` (new terminal tab), `--cd` (print worktree path only), and `--base <branch>` (see [Planning & base branches](#planning--base-branches)).
|
|
244
244
|
|
|
245
245
|
## Planning & base branches
|
|
246
246
|
|
|
@@ -671,15 +671,17 @@ needed, and it only affects Codex (every other tool ignores it).
|
|
|
671
671
|
above makes **local** git work (stage, commit, stash, ref updates, and the
|
|
672
672
|
local legs of `sync`/`done`) succeed with **network off**. Only operations that
|
|
673
673
|
reach the network — `git fetch` (hence `sync`) and `git push` (hence the network
|
|
674
|
-
leg of `done`) — need network access
|
|
675
|
-
|
|
676
|
-
pr-comments`,
|
|
674
|
+
leg of `done`) — need network access. It is **enabled by default** for the
|
|
675
|
+
interactive lifecycle commands `wade implement` (including its batch children)
|
|
676
|
+
and `wade review pr-comments`, because their readiness, sync, and completion
|
|
677
|
+
steps require GitHub. Choose offline operation explicitly with `--no-network`,
|
|
678
|
+
or in `.wade.yml`:
|
|
677
679
|
|
|
678
680
|
```yaml
|
|
679
681
|
ai:
|
|
680
|
-
network_access:
|
|
682
|
+
network_access: false # offline opt-out for interactive session commands
|
|
681
683
|
implement:
|
|
682
|
-
network_access:
|
|
684
|
+
network_access: true # per-command override wins
|
|
683
685
|
```
|
|
684
686
|
|
|
685
687
|
The policy applies to the **interactive session commands** — `wade implement`
|
|
@@ -689,10 +691,21 @@ may need `fetch`/`push`. The headless/analytical paths (`plan`, `deps`,
|
|
|
689
691
|
they never fetch or push, so `ai.network_access` does not apply to them and no
|
|
690
692
|
flag enables it there. Precedence for the commands that honor it is
|
|
691
693
|
`--network`/`--no-network` > `ai.<command>.network_access` >
|
|
692
|
-
`ai.network_access` > **
|
|
694
|
+
`ai.network_access` > **on for `implement` and `review_pr_comments`, otherwise
|
|
695
|
+
off**. WADE always passes an explicit pin, so an ambient
|
|
693
696
|
`network_access = true` in your own Codex `config.toml` can never silently
|
|
694
|
-
enable network for a WADE-managed sandbox. Enabling network
|
|
695
|
-
|
|
697
|
+
enable network for a WADE-managed sandbox. Enabling network permits outbound
|
|
698
|
+
access for commands inside the Codex workspace-write sandbox; it does not
|
|
699
|
+
disable filesystem sandboxing or change approval-policy semantics.
|
|
700
|
+
|
|
701
|
+
An accepted single-issue plan handoff starts implementation from a planning
|
|
702
|
+
session that is always network-off. When both the planning tool and resolved
|
|
703
|
+
implementation tool are Codex and the implementation policy resolves to enabled,
|
|
704
|
+
WADE starts a fresh detached Codex context with network explicitly enabled;
|
|
705
|
+
reusing the planner process would retain its immutable network-off sandbox. If
|
|
706
|
+
WADE cannot open that detached context, the handoff fails rather than reporting
|
|
707
|
+
an implementation session ready. Open a new host terminal and run the displayed
|
|
708
|
+
`wade implement <issue> --network` command to continue with the required policy.
|
|
696
709
|
|
|
697
710
|
### Session readiness and least-privilege remediation
|
|
698
711
|
|
|
@@ -753,8 +766,9 @@ timeout still counts as a bounded review attempt, so the review/fix loop cannot
|
|
|
753
766
|
run forever.
|
|
754
767
|
|
|
755
768
|
For Codex, keep `--sandbox workspace-write`; WADE/crossby add only the linked
|
|
756
|
-
worktree's private/common Git metadata directories
|
|
757
|
-
|
|
769
|
+
worktree's private/common Git metadata directories. Implementation and PR-comment
|
|
770
|
+
sessions have network access by default for their GitHub lifecycle; use
|
|
771
|
+
`--no-network` or `ai.network_access: false` when an offline sandbox is required.
|
|
758
772
|
For Claude Code and Cursor, allowlist the worktree/Git metadata paths and only
|
|
759
773
|
the GitHub domains needed by the session rather than choosing unrestricted shell
|
|
760
774
|
access. Copilot and VS Code need network plus usable `gh` credentials in their
|
|
@@ -478,16 +478,23 @@ review detached/inline launches (`implementation_service/core.py`,
|
|
|
478
478
|
`working_dir` with network **off** for their worktree-capable paths.
|
|
479
479
|
|
|
480
480
|
**Filesystem writes and network are independent axes.** The `working_dir` grant
|
|
481
|
-
makes local
|
|
482
|
-
`
|
|
483
|
-
`
|
|
484
|
-
`
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
481
|
+
makes local Git metadata writes work under `network_access=False`. GitHub API
|
|
482
|
+
calls — including readiness's `gh api user` and review-data fetch/resolve — and
|
|
483
|
+
remote Git operations (`git fetch`/`git push`, the network legs of `sync`/`done`)
|
|
484
|
+
need `network_access=True`. For `implement` and `review_pr_comments`, WADE
|
|
485
|
+
resolves `network_access: bool` through `resolve_network_access()` (CLI
|
|
486
|
+
`--network`/`--no-network` > command config > global `ai.network_access` >
|
|
487
|
+
**enabled by default**). Planning, dependency analysis, bounded reviews, and
|
|
488
|
+
every command outside `NETWORK_ENABLED_BY_DEFAULT_COMMANDS` are forcibly
|
|
489
|
+
disabled regardless of CLI or configuration. WADE
|
|
490
|
+
**always passes it explicitly** to the builder, so an ambient
|
|
491
|
+
`network_access = true` in the user's Codex `config.toml` can never silently
|
|
492
|
+
change a WADE-managed sandbox. Only Codex acts on either value — crossby
|
|
493
|
+
capability-gates every other tool via `supports_network_access` — and resume
|
|
494
|
+
re-resolves both fresh from current config (a launch-time OS concern, not
|
|
495
|
+
persisted session state). Network access permits outbound connections inside the
|
|
496
|
+
workspace-write sandbox; it neither widens the filesystem sandbox nor changes
|
|
497
|
+
approval policy.
|
|
491
498
|
|
|
492
499
|
The **explicit** `--network`/`--no-network` override (the tri-state
|
|
493
500
|
`bool | None`, not the resolved bool) is threaded through every session **handoff**
|
|
@@ -499,6 +506,17 @@ picks (implement / batch / review). `None` (unset) still re-resolves per the
|
|
|
499
506
|
routed command's own config, matching how a non-explicit `permission_mode` is
|
|
500
507
|
threaded.
|
|
501
508
|
|
|
509
|
+
Planning itself is always network-off, including when it later offers an
|
|
510
|
+
accepted single-issue implementation handoff. The internal `plan_handoff`
|
|
511
|
+
intent keeps implementation-network resolution at `implementation_service.start`.
|
|
512
|
+
If that handoff originates in Codex, resolves the implementation tool to Codex,
|
|
513
|
+
and resolves network access to enabled, implementation must create a fresh
|
|
514
|
+
detached Codex launch with an explicit `network_access=True` pin. It cannot reuse
|
|
515
|
+
the planner's immutable network-off sandbox. If the detached launch cannot be
|
|
516
|
+
created, the handoff fails closed and prints `wade implement <issue> --network`
|
|
517
|
+
for the user to run from a new host terminal; it must not fall back to an inline
|
|
518
|
+
or nested agent. All other nested-agent starts retain the ordinary launch guard.
|
|
519
|
+
|
|
502
520
|
### Phase-aware session readiness (#462)
|
|
503
521
|
|
|
504
522
|
`check_service.check_session_readiness()` applies the declarative
|
|
@@ -939,7 +957,7 @@ exactly as before #448. See knowledge `cc91cd11` for the generalized principle.
|
|
|
939
957
|
|
|
940
958
|
**Model complexity mapping**: The `models` section maps AI tool names to complexity-tiered model IDs (`easy`, `medium`, `complex`, `very_complex`). When `wade implement` is invoked, the service reads the `complexity:X` label from the issue (falling back to `## Complexity` in the body), maps it to the appropriate configured model, and passes it as `--model` to the AI tool — unless the user explicitly passed `--model` themselves.
|
|
941
959
|
|
|
942
|
-
**Per-command AI tool and model overrides**: The `ai` section supports `plan`, `deps`, `implement`, `review_plan`, `review_implementation`, `review_batch`, and `review_pr_comments` sub-sections (`AI_COMMAND_NAMES` in `models/config.py`), with optional `tool`, `model`, `mode`, `effort`, `enabled`, `yolo`, `permission_mode`, `network_access`, and `timeout` keys as applicable. `network_access` (global `ai.network_access` or per-command
|
|
960
|
+
**Per-command AI tool and model overrides**: The `ai` section supports `plan`, `deps`, `implement`, `review_plan`, `review_implementation`, `review_batch`, and `review_pr_comments` sub-sections (`AI_COMMAND_NAMES` in `models/config.py`), with optional `tool`, `model`, `mode`, `effort`, `enabled`, `yolo`, `permission_mode`, `network_access`, and `timeout` keys as applicable. `network_access` (global `ai.network_access` or per-command) is the Codex sandbox network pin resolved by `resolve_network_access()`: it defaults to **True** for `implement` and `review_pr_comments`, whose lifecycle requires GitHub, and **False** for every other command. The CLI, per-command, and global policy levels remain higher-precedence opt-outs — see the "Codex sandboxed-worktree git writes & network policy" section above. `timeout` bounds a headless subprocess (seconds). When **unset**, the review/deps services compute the budget with `effective_timeout` (`delegation_service.py`, #366): it scales from **payload bytes + reasoning effort** — `scaled_timeout` starts at a **600s floor** (`TIMEOUT_FLOOR`, covers CLI cold-start + a small high-effort run), adds ~0.0075 s/byte of prompt, multiplies high/xhigh/max effort by 1.5–1.75×, and clamps to a **1500s ceiling** (`TIMEOUT_CEILING`). A headless timeout is **not** discarded: `run` (`utils/process.py`) decodes and reattaches the partial stdout (bytes even under `text=True`), `_delegate_headless` returns it as `feedback` with `DelegationResult.timed_out=True`, and wade **retries once** at a longer budget (`extended_timeout`, 1.5×) — bounding the *sum* of both legs to `TOTAL_TIMEOUT_CAP` (`TIMEOUT_CEILING + TIMEOUT_CEILING * TIMEOUT_RETRY_MULTIPLIER`, ~3750s / 62.5 min) so the worst case is predictable while the retry always gets the full multiplier, never a shorter budget than the attempt that just timed out (#366 review). The pre-launch advisory — now also printed by `deps_service.analyze_deps` before a headless run, not just the review commands (#366 review) — announces that worst-case total. A crash (`CommandError` / non-zero exit) is never retried and never flagged `timed_out`. Setting `ai.<cmd>.timeout` **explicitly** is a deliberate override: it is honored verbatim and **bypasses scaling and the retry math** — the escape hatch for orchestrators with a hard tool-timeout (set it below the harness limit). The fallback chain (tool/model) is: CLI `--ai`/`--model` flag -> command-specific config -> global `default_tool`. This is implemented in `ProjectConfig.get_ai_tool(command)` and `ProjectConfig.get_model(command)`. When `mode` is omitted, `review_plan` and `review_implementation` default to `prompt`, while `review_batch` defaults to `interactive`. `review_pr_comments` (#389) governs the **auto-launched review session** (post-`done` "Wait for reviews" → comments land → `review_service.start`): it resolves that session's tool, model, effort, and autonomy tier under its own key rather than inheriting `ai.implement.*`. The inherited implementation-session `tool` / `model` / `permission_mode` are honored only when the user set them *explicitly* (`--ai` / `--model` / `--permission-mode` / `--yolo`); the implementation flow forwards its already-*resolved* concrete values (never `None`), which would otherwise short-circuit the resolvers and shadow `ai.review_pr_comments` — so a merely config/default-derived value is dropped and the review config (then global `ai.*`) governs.
|
|
943
961
|
|
|
944
962
|
**Permission (autonomy) mode vs. delegation `mode` — two orthogonal axes**: The `mode` key (`DelegationMode`: `prompt`/`interactive`/`headless`, `models/delegation.py`) governs *how* a tool is dispatched. `permission_mode` (`PermissionMode`: `default`/`accept-edits`/`auto`/`yolo`, `models/permission.py`) governs *how much* the tool may do without prompting — the autonomy axis crossby exposes via the `yolo`/`auto`/`accept_edits` launch booleans. Do **not** conflate them: they live in separate modules on purpose. Resolution (`resolve_permission_mode()` in `ai_resolution.py`) follows CLI `--permission-mode` > `--yolo` alias > command config > global config > `default`; `permission_mode` wins over the legacy `yolo` alias at any level, and `get_yolo()`/`resolve_yolo()` are thin shims that derive from the resolved mode so the alias has a single source of truth. WADE forwards only the *requested* tier and does **not** gate on per-tool capability — crossby owns capability-aware downgrades and warnings (`_autonomy_launch_args`), so `auto` on a non-Claude tool downgrades to `accept-edits` instead of WADE silently disabling it. The headless delegation path always forces `default` (no autonomy grant) regardless of config, since `deps`/`review_plan`/`review_implementation`/`review_batch` are read/analytical; `review_pr_comments` is the exception — it launches an *interactive* session and honors its configured `ai.review_pr_comments.permission_mode`. `plan` is intentionally excluded from `PermissionMode` (WADE drives plan mode separately via `plan_service` → `plan_mode=True` for native plan tools, and `plan_mode=False` for Antigravity CLI whose native plan mode sandboxes writes to an external brain store while WADE's plan-artifact guard enforces containment); a configured or CLI-supplied `permission_mode: plan` (or any invalid value) warns and falls back to `default`. Every launch command (`plan`, `implement`, `implement-batch`, `review pr-comments`, `review plan`/`implementation`/`batch`, `task deps`, and the delegation paths) exposes `--yolo`/`--permission-mode` and resolves + forwards the tier; `confirm_ai_selection()` (`ai_resolution.py`) **always displays** the resolved tool/model/effort/permission mode with a per-tier descriptor (`permission.describe_permission_mode`) before its skip guard, so the mode surfaces on every path (TTY, non-TTY, headless, all-flags-explicit) and what is shown always equals what is applied. For the read-only headless paths (`deps`/`review_*` in headless mode), the service computes the *effective* mode as `default` and uses that single value for both display and the `DelegationRequest`, mirroring the `delegation_service` headless force-default rule. In addition, a completed non-zero headless exit preserves trimmed stdout and appends a clearly labeled stderr tail (the final 20 non-empty lines, capped at 4,000 characters, with truncation labeled); only failures with neither stream retain the generic no-output fallback.
|
|
945
963
|
|
|
@@ -1199,6 +1217,8 @@ When wade installs skills into a target project (per session, via worktree boots
|
|
|
1199
1217
|
|
|
1200
1218
|
**`wade implement-batch`:**
|
|
1201
1219
|
- `--model` — Pass a specific AI model to all parallel sessions.
|
|
1220
|
+
- `--network` / `--no-network` — Pin network access for every child session;
|
|
1221
|
+
when omitted, each child resolves its normal implementation default.
|
|
1202
1222
|
- `--skill` / `--review-skill` — Repeatable ordered bindings forwarded to every
|
|
1203
1223
|
child implementation session.
|
|
1204
1224
|
- `--refresh-skills` — Explicitly refresh frozen bindings in resumed child
|
|
@@ -217,13 +217,14 @@ _PERMISSION_MODE_OPT = typer.Option(
|
|
|
217
217
|
# Shared tri-state flag for the Codex sandbox network policy. ``--network``
|
|
218
218
|
# enables network access inside the sandbox (needed for git fetch/push, hence
|
|
219
219
|
# the network legs of sync/done); ``--no-network`` forces it off; omitted (None)
|
|
220
|
-
# defers to
|
|
221
|
-
#
|
|
220
|
+
# defers to command/global config and then the command default. Interactive
|
|
221
|
+
# implementation and PR-comment sessions default on; other commands default off.
|
|
222
|
+
# Only Codex acts on it — every other tool ignores it upstream.
|
|
222
223
|
_NETWORK_ACCESS_OPT = typer.Option(
|
|
223
224
|
None,
|
|
224
225
|
"--network/--no-network",
|
|
225
|
-
help="Allow network access inside the Codex sandbox (default:
|
|
226
|
-
"
|
|
226
|
+
help="Allow network access inside the Codex sandbox (default: on for implementation "
|
|
227
|
+
"and PR-comment sessions). Overrides ai.network_access.",
|
|
227
228
|
)
|
|
228
229
|
|
|
229
230
|
|
|
@@ -411,6 +412,7 @@ def implement_batch_cmd(
|
|
|
411
412
|
),
|
|
412
413
|
yolo: bool = typer.Option(False, "--yolo", help="Skip AI tool permission prompts."),
|
|
413
414
|
permission_mode: str | None = _PERMISSION_MODE_OPT,
|
|
415
|
+
network_access: bool | None = _NETWORK_ACCESS_OPT,
|
|
414
416
|
skill: list[str] | None = typer.Option( # noqa: B008
|
|
415
417
|
None, "--skill", help="WORK methodology skill ref forwarded to every child session."
|
|
416
418
|
),
|
|
@@ -458,6 +460,7 @@ def implement_batch_cmd(
|
|
|
458
460
|
effort_explicit=effort is not None,
|
|
459
461
|
yolo=yolo or None,
|
|
460
462
|
permission_mode=permission_mode,
|
|
463
|
+
network_access=network_access,
|
|
461
464
|
work_skills=skill,
|
|
462
465
|
review_skills=review_skill,
|
|
463
466
|
refresh_skills=refresh_skills,
|
|
@@ -198,8 +198,8 @@ def review_pr_comments_cmd(
|
|
|
198
198
|
network_access: bool | None = typer.Option(
|
|
199
199
|
None,
|
|
200
200
|
"--network/--no-network",
|
|
201
|
-
help="Allow network access inside the Codex sandbox (default:
|
|
202
|
-
"
|
|
201
|
+
help="Allow network access inside the Codex sandbox (default: on for PR-comment "
|
|
202
|
+
"sessions). Overrides ai.network_access.",
|
|
203
203
|
),
|
|
204
204
|
skill: list[str] | None = typer.Option( # noqa: B008
|
|
205
205
|
None, "--skill", help="WORK methodology skill ref. Repeat for an ordered binding."
|
|
@@ -115,6 +115,15 @@ AI_COMMAND_NAMES: tuple[str, ...] = tuple(command.value for command in AICommand
|
|
|
115
115
|
"""Canonical per-command AI config sections supported by WADE."""
|
|
116
116
|
|
|
117
117
|
|
|
118
|
+
NETWORK_ENABLED_BY_DEFAULT_COMMANDS: frozenset[str] = frozenset(
|
|
119
|
+
{
|
|
120
|
+
AICommandKey.IMPLEMENT,
|
|
121
|
+
AICommandKey.REVIEW_PR_COMMENTS,
|
|
122
|
+
}
|
|
123
|
+
)
|
|
124
|
+
"""Interactive Codex session commands whose required lifecycle needs network access."""
|
|
125
|
+
|
|
126
|
+
|
|
118
127
|
LEGACY_AI_COMMAND_ALIASES: dict[str, str] = {"work": "implement"}
|
|
119
128
|
"""Back-compat aliases accepted in config validation/loading paths."""
|
|
120
129
|
|
|
@@ -127,11 +136,11 @@ class AIConfig(BaseModel):
|
|
|
127
136
|
effort: str | None = None
|
|
128
137
|
permission_mode: str | None = None
|
|
129
138
|
yolo: bool | None = None
|
|
130
|
-
# Global Codex sandbox network policy
|
|
131
|
-
#
|
|
132
|
-
#
|
|
133
|
-
#
|
|
134
|
-
#
|
|
139
|
+
# Global Codex sandbox network policy. ``None`` defers to the command's
|
|
140
|
+
# built-in default: enabled for interactive implementation and PR-comment
|
|
141
|
+
# sessions, disabled for every other command. Wade always passes an explicit
|
|
142
|
+
# pin at launch so ambient Codex ``config.toml`` can never silently change
|
|
143
|
+
# a wade-managed sandbox.
|
|
135
144
|
network_access: bool | None = None
|
|
136
145
|
plan: AICommandConfig = AICommandConfig()
|
|
137
146
|
deps: AICommandConfig = AICommandConfig()
|
|
@@ -598,15 +607,19 @@ class ProjectConfig(BaseModel):
|
|
|
598
607
|
"""Resolve the Codex sandbox network policy for a command.
|
|
599
608
|
|
|
600
609
|
Fallback: command-specific ``ai.<command>.network_access`` → global
|
|
601
|
-
``ai.network_access`` →
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
610
|
+
``ai.network_access`` → command default. Interactive implementation and
|
|
611
|
+
PR-comment sessions default to enabled because their required lifecycle
|
|
612
|
+
reaches GitHub; all other commands are always disabled. Only Codex
|
|
613
|
+
honors this (crossby capability-gates every other tool), and wade always
|
|
614
|
+
forwards the resolved bool so ambient Codex config can never silently
|
|
615
|
+
flip it on.
|
|
605
616
|
"""
|
|
617
|
+
if command and command not in NETWORK_ENABLED_BY_DEFAULT_COMMANDS:
|
|
618
|
+
return False
|
|
606
619
|
if command:
|
|
607
620
|
cmd_config = getattr(self.ai, command, None)
|
|
608
621
|
if isinstance(cmd_config, AICommandConfig) and cmd_config.network_access is not None:
|
|
609
622
|
return cmd_config.network_access
|
|
610
623
|
if self.ai.network_access is not None:
|
|
611
624
|
return self.ai.network_access
|
|
612
|
-
return
|
|
625
|
+
return command in NETWORK_ENABLED_BY_DEFAULT_COMMANDS
|
|
@@ -22,7 +22,7 @@ import structlog
|
|
|
22
22
|
from crossby.ai_tools import AbstractAITool
|
|
23
23
|
from crossby.models.ai import AIToolID, EffortLevel
|
|
24
24
|
|
|
25
|
-
from wade.models.config import AICommandConfig, ProjectConfig
|
|
25
|
+
from wade.models.config import NETWORK_ENABLED_BY_DEFAULT_COMMANDS, AICommandConfig, ProjectConfig
|
|
26
26
|
from wade.models.delegation import DelegationMode
|
|
27
27
|
from wade.models.permission import (
|
|
28
28
|
PermissionMode,
|
|
@@ -206,7 +206,7 @@ def resolve_permission_mode(
|
|
|
206
206
|
) -> PermissionMode:
|
|
207
207
|
"""Resolve the autonomy tier from args -> config -> ``default``.
|
|
208
208
|
|
|
209
|
-
|
|
209
|
+
The fallback chain (highest precedence first) is:
|
|
210
210
|
1. Explicit ``--permission-mode`` CLI value
|
|
211
211
|
2. ``--yolo`` CLI alias (equivalent to ``permission_mode=yolo``)
|
|
212
212
|
3. Command/global config (``ai.<command>.permission_mode`` / ``yolo``,
|
|
@@ -246,21 +246,24 @@ def resolve_network_access(
|
|
|
246
246
|
config: ProjectConfig,
|
|
247
247
|
command: str = "plan",
|
|
248
248
|
) -> bool:
|
|
249
|
-
"""Resolve the Codex sandbox network policy from args -> config ->
|
|
249
|
+
"""Resolve the Codex sandbox network policy from args -> config -> command default.
|
|
250
250
|
|
|
251
251
|
Fallback chain (highest precedence first):
|
|
252
252
|
1. Explicit ``--network`` / ``--no-network`` CLI value
|
|
253
253
|
2. Command-specific config (``ai.<command>.network_access``)
|
|
254
254
|
3. Global config (``ai.network_access``)
|
|
255
|
-
4. ``
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
255
|
+
4. Command default: enabled for ``implement`` and ``review_pr_comments``;
|
|
256
|
+
disabled for all other commands.
|
|
257
|
+
|
|
258
|
+
Wade forwards the resolved bool as an explicit pin so an ambient Codex
|
|
259
|
+
``config.toml`` can never silently change network access for a wade-managed
|
|
260
|
+
sandbox. Non-Codex tools ignore the value (crossby capability-gates it via
|
|
261
|
+
``supports_network_access``), so this resolves for every tool but only Codex
|
|
262
|
+
acts on it. Non-interactive commands remain disabled even when the project
|
|
263
|
+
config enables network globally.
|
|
263
264
|
"""
|
|
265
|
+
if command not in NETWORK_ENABLED_BY_DEFAULT_COMMANDS:
|
|
266
|
+
return False
|
|
264
267
|
if network_access is not None:
|
|
265
268
|
return network_access
|
|
266
269
|
return config.get_network_access(command)
|
|
@@ -434,6 +434,7 @@ def start(
|
|
|
434
434
|
work_skills: list[str] | None = None,
|
|
435
435
|
review_skills: list[str] | None = None,
|
|
436
436
|
refresh_skills: bool = False,
|
|
437
|
+
plan_handoff: bool = False,
|
|
437
438
|
) -> ImplementResult:
|
|
438
439
|
"""Start an implementation session on an issue.
|
|
439
440
|
|
|
@@ -453,6 +454,10 @@ def start(
|
|
|
453
454
|
project_root: Repository root (defaults to CWD).
|
|
454
455
|
detach: If True, launch AI in a new terminal tab.
|
|
455
456
|
cd_only: If True, create worktree and print path only (no AI launch).
|
|
457
|
+
plan_handoff: Internal marker for an accepted ``wade plan`` handoff.
|
|
458
|
+
A network-enabled Codex implementation must launch in a fresh
|
|
459
|
+
detached context rather than inherit the planner's network-off
|
|
460
|
+
sandbox.
|
|
456
461
|
|
|
457
462
|
Returns:
|
|
458
463
|
ImplementResult with success/merged status.
|
|
@@ -639,9 +644,10 @@ def start(
|
|
|
639
644
|
permission_mode, yolo, config, "implement"
|
|
640
645
|
)
|
|
641
646
|
|
|
642
|
-
# Resolve the Codex sandbox network policy (default
|
|
643
|
-
# passed explicitly at launch so ambient
|
|
644
|
-
#
|
|
647
|
+
# Resolve the Codex sandbox network policy (enabled by default for this
|
|
648
|
+
# interactive lifecycle). Always passed explicitly at launch so ambient
|
|
649
|
+
# Codex config can never silently change this wade-managed sandbox; only
|
|
650
|
+
# Codex acts on it.
|
|
645
651
|
resolved_network_access = resolve_network_access(network_access, config, "implement")
|
|
646
652
|
|
|
647
653
|
# When resuming, override the resolved tool and skip interactive confirmation
|
|
@@ -931,9 +937,19 @@ def start(
|
|
|
931
937
|
return ImplementResult(success=True)
|
|
932
938
|
|
|
933
939
|
# AI-initiated start guard: if we're inside an AI CLI session,
|
|
934
|
-
# don't launch another AI tool — just print the worktree path.
|
|
940
|
+
# don't launch another AI tool — just print the worktree path. The
|
|
941
|
+
# one exception is a plan handoff from Codex to a network-enabled Codex
|
|
942
|
+
# implementation: network is a launch-time sandbox property, and the
|
|
943
|
+
# planner always ran with it disabled, so that handoff needs a fresh
|
|
944
|
+
# detached process instead of reusing this agent context.
|
|
935
945
|
detected_env = _detect_ai_cli_env()
|
|
936
|
-
|
|
946
|
+
requires_fresh_codex_handoff = (
|
|
947
|
+
plan_handoff
|
|
948
|
+
and detected_env == "CODEX_CLI"
|
|
949
|
+
and resolved_tool == AIToolID.CODEX.value
|
|
950
|
+
and resolved_network_access
|
|
951
|
+
)
|
|
952
|
+
if detected_env and not requires_fresh_codex_handoff:
|
|
937
953
|
logger.info(
|
|
938
954
|
"implementation.ai_launch_skipped",
|
|
939
955
|
reason="inside_ai_cli",
|
|
@@ -960,8 +976,10 @@ def start(
|
|
|
960
976
|
except OSError:
|
|
961
977
|
logger.warning("implementation.transcript_dir_failed")
|
|
962
978
|
|
|
963
|
-
# Detach mode: launch AI tool in a new terminal, don't block
|
|
964
|
-
|
|
979
|
+
# Detach mode: launch AI tool in a new terminal, don't block. A
|
|
980
|
+
# network-enabled Codex plan handoff is forced through this path so it
|
|
981
|
+
# cannot inherit the planner's immutable network-off sandbox.
|
|
982
|
+
if (detach or requires_fresh_codex_handoff) and resolved_tool:
|
|
965
983
|
cmd: list[str] | None = None
|
|
966
984
|
try:
|
|
967
985
|
detach_adapter = AbstractAITool.get(AIToolID(resolved_tool))
|
|
@@ -995,18 +1013,40 @@ def start(
|
|
|
995
1013
|
effort=resolved_effort,
|
|
996
1014
|
allowed_commands=config.permissions.allowed_commands,
|
|
997
1015
|
working_dir=worktree_path,
|
|
998
|
-
|
|
1016
|
+
# ``requires_fresh_codex_handoff`` already established
|
|
1017
|
+
# the resolved value is true; pin it explicitly for the
|
|
1018
|
+
# new Codex process rather than relying on ambient config.
|
|
1019
|
+
network_access=(
|
|
1020
|
+
True if requires_fresh_codex_handoff else resolved_network_access
|
|
1021
|
+
),
|
|
999
1022
|
**permission_mode_launch_kwargs(resolved_permission_mode),
|
|
1000
1023
|
)
|
|
1001
1024
|
except (ValueError, KeyError):
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1025
|
+
# A fresh Codex handoff must retain its explicit sandbox,
|
|
1026
|
+
# network, permission, and prompt arguments. Do not replace a
|
|
1027
|
+
# failed build with bare ``codex``, which would bypass them.
|
|
1028
|
+
if not requires_fresh_codex_handoff:
|
|
1029
|
+
cmd = [resolved_tool]
|
|
1030
|
+
|
|
1031
|
+
if cmd is not None:
|
|
1032
|
+
console.step(f"Launching {resolved_tool} in new terminal...")
|
|
1033
|
+
if launch_in_new_terminal(
|
|
1034
|
+
cmd,
|
|
1035
|
+
cwd=str(worktree_path),
|
|
1036
|
+
title=work_title,
|
|
1037
|
+
wait_for_ready=requires_fresh_codex_handoff,
|
|
1038
|
+
):
|
|
1039
|
+
console.success(f"Detached AI session for #{task.id}")
|
|
1040
|
+
stop_title_keeper()
|
|
1041
|
+
return ImplementResult(success=True)
|
|
1042
|
+
if requires_fresh_codex_handoff:
|
|
1043
|
+
console.error(
|
|
1044
|
+
"Could not launch a fresh Codex implementation session with network access."
|
|
1045
|
+
)
|
|
1046
|
+
console.hint("Open a new host terminal, then run:")
|
|
1047
|
+
console.detail(f"wade implement {task.id} --network")
|
|
1008
1048
|
stop_title_keeper()
|
|
1009
|
-
return ImplementResult(success=
|
|
1049
|
+
return ImplementResult(success=False)
|
|
1010
1050
|
console.warn("Could not launch in new terminal — falling back to inline")
|
|
1011
1051
|
detach = False
|
|
1012
1052
|
# Fall through to inline launch below
|
|
@@ -1539,7 +1539,10 @@ def _offer_to_implement(
|
|
|
1539
1539
|
return False
|
|
1540
1540
|
|
|
1541
1541
|
try:
|
|
1542
|
-
|
|
1542
|
+
# Planning always launches with network disabled. Tell implementation
|
|
1543
|
+
# startup this is an accepted handoff so it can establish a fresh Codex
|
|
1544
|
+
# context when its independently resolved policy needs network access.
|
|
1545
|
+
result = start_implementation_session(target=issue_number, plan_handoff=True)
|
|
1543
1546
|
return result.success
|
|
1544
1547
|
except Exception:
|
|
1545
1548
|
logger.exception("plan.work_session_start_failed", issue=issue_number)
|
|
@@ -1173,8 +1173,9 @@ def start(
|
|
|
1173
1173
|
resolved_permission_mode = resolve_permission_mode(
|
|
1174
1174
|
effective_pm, yolo, config, "review_pr_comments"
|
|
1175
1175
|
)
|
|
1176
|
-
# Codex sandbox network policy (default
|
|
1177
|
-
#
|
|
1176
|
+
# Codex sandbox network policy (enabled by default for this interactive
|
|
1177
|
+
# lifecycle); always pinned explicitly so ambient Codex config cannot
|
|
1178
|
+
# silently change it.
|
|
1178
1179
|
resolved_network_access = resolve_network_access(network_access, config, "review_pr_comments")
|
|
1179
1180
|
|
|
1180
1181
|
if not detach:
|