erk 0.4.5__py3-none-any.whl
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.
- erk/__init__.py +12 -0
- erk/__main__.py +6 -0
- erk/agent_docs/__init__.py +5 -0
- erk/agent_docs/models.py +123 -0
- erk/agent_docs/operations.py +666 -0
- erk/artifacts/__init__.py +5 -0
- erk/artifacts/artifact_health.py +623 -0
- erk/artifacts/detection.py +16 -0
- erk/artifacts/discovery.py +343 -0
- erk/artifacts/models.py +63 -0
- erk/artifacts/staleness.py +56 -0
- erk/artifacts/state.py +100 -0
- erk/artifacts/sync.py +624 -0
- erk/cli/__init__.py +0 -0
- erk/cli/activation.py +132 -0
- erk/cli/alias.py +53 -0
- erk/cli/cli.py +221 -0
- erk/cli/commands/__init__.py +0 -0
- erk/cli/commands/admin.py +153 -0
- erk/cli/commands/artifact/__init__.py +1 -0
- erk/cli/commands/artifact/check.py +260 -0
- erk/cli/commands/artifact/group.py +31 -0
- erk/cli/commands/artifact/list_cmd.py +89 -0
- erk/cli/commands/artifact/show.py +62 -0
- erk/cli/commands/artifact/sync_cmd.py +39 -0
- erk/cli/commands/branch/__init__.py +26 -0
- erk/cli/commands/branch/assign_cmd.py +152 -0
- erk/cli/commands/branch/checkout_cmd.py +357 -0
- erk/cli/commands/branch/create_cmd.py +161 -0
- erk/cli/commands/branch/list_cmd.py +82 -0
- erk/cli/commands/branch/unassign_cmd.py +197 -0
- erk/cli/commands/cc/__init__.py +15 -0
- erk/cli/commands/cc/jsonl_cmd.py +20 -0
- erk/cli/commands/cc/session/AGENTS.md +30 -0
- erk/cli/commands/cc/session/CLAUDE.md +1 -0
- erk/cli/commands/cc/session/__init__.py +15 -0
- erk/cli/commands/cc/session/list_cmd.py +167 -0
- erk/cli/commands/cc/session/show_cmd.py +175 -0
- erk/cli/commands/completion.py +89 -0
- erk/cli/commands/completions.py +165 -0
- erk/cli/commands/config.py +327 -0
- erk/cli/commands/docs/__init__.py +1 -0
- erk/cli/commands/docs/group.py +16 -0
- erk/cli/commands/docs/sync.py +121 -0
- erk/cli/commands/docs/validate.py +102 -0
- erk/cli/commands/doctor.py +243 -0
- erk/cli/commands/down.py +171 -0
- erk/cli/commands/exec/__init__.py +1 -0
- erk/cli/commands/exec/group.py +164 -0
- erk/cli/commands/exec/scripts/AGENTS.md +79 -0
- erk/cli/commands/exec/scripts/CLAUDE.md +1 -0
- erk/cli/commands/exec/scripts/__init__.py +5 -0
- erk/cli/commands/exec/scripts/add_reaction_to_comment.py +69 -0
- erk/cli/commands/exec/scripts/add_remote_execution_note.py +68 -0
- erk/cli/commands/exec/scripts/check_impl.py +152 -0
- erk/cli/commands/exec/scripts/ci_update_pr_body.py +294 -0
- erk/cli/commands/exec/scripts/create_extraction_branch.py +138 -0
- erk/cli/commands/exec/scripts/create_extraction_plan.py +242 -0
- erk/cli/commands/exec/scripts/create_issue_from_session.py +103 -0
- erk/cli/commands/exec/scripts/create_plan_from_context.py +103 -0
- erk/cli/commands/exec/scripts/create_worker_impl_from_issue.py +93 -0
- erk/cli/commands/exec/scripts/detect_trunk_branch.py +121 -0
- erk/cli/commands/exec/scripts/exit_plan_mode_hook.py +777 -0
- erk/cli/commands/exec/scripts/extract_latest_plan.py +49 -0
- erk/cli/commands/exec/scripts/extract_session_from_issue.py +150 -0
- erk/cli/commands/exec/scripts/find_project_dir.py +214 -0
- erk/cli/commands/exec/scripts/generate_pr_summary.py +112 -0
- erk/cli/commands/exec/scripts/get_closing_text.py +98 -0
- erk/cli/commands/exec/scripts/get_embedded_prompt.py +62 -0
- erk/cli/commands/exec/scripts/get_plan_metadata.py +95 -0
- erk/cli/commands/exec/scripts/get_pr_body_footer.py +70 -0
- erk/cli/commands/exec/scripts/get_pr_discussion_comments.py +149 -0
- erk/cli/commands/exec/scripts/get_pr_review_comments.py +155 -0
- erk/cli/commands/exec/scripts/impl_init.py +158 -0
- erk/cli/commands/exec/scripts/impl_signal.py +375 -0
- erk/cli/commands/exec/scripts/impl_verify.py +49 -0
- erk/cli/commands/exec/scripts/issue_title_to_filename.py +34 -0
- erk/cli/commands/exec/scripts/list_sessions.py +296 -0
- erk/cli/commands/exec/scripts/mark_impl_ended.py +188 -0
- erk/cli/commands/exec/scripts/mark_impl_started.py +188 -0
- erk/cli/commands/exec/scripts/marker.py +163 -0
- erk/cli/commands/exec/scripts/objective_save_to_issue.py +109 -0
- erk/cli/commands/exec/scripts/plan_save_to_issue.py +269 -0
- erk/cli/commands/exec/scripts/plan_update_issue.py +147 -0
- erk/cli/commands/exec/scripts/post_extraction_comment.py +237 -0
- erk/cli/commands/exec/scripts/post_or_update_pr_summary.py +133 -0
- erk/cli/commands/exec/scripts/post_pr_inline_comment.py +143 -0
- erk/cli/commands/exec/scripts/post_workflow_started_comment.py +168 -0
- erk/cli/commands/exec/scripts/preprocess_session.py +777 -0
- erk/cli/commands/exec/scripts/quick_submit.py +32 -0
- erk/cli/commands/exec/scripts/rebase_with_conflict_resolution.py +260 -0
- erk/cli/commands/exec/scripts/reply_to_discussion_comment.py +173 -0
- erk/cli/commands/exec/scripts/resolve_review_thread.py +170 -0
- erk/cli/commands/exec/scripts/session_id_injector_hook.py +52 -0
- erk/cli/commands/exec/scripts/setup_impl_from_issue.py +159 -0
- erk/cli/commands/exec/scripts/slot_objective.py +102 -0
- erk/cli/commands/exec/scripts/tripwires_reminder_hook.py +20 -0
- erk/cli/commands/exec/scripts/update_dispatch_info.py +116 -0
- erk/cli/commands/exec/scripts/user_prompt_hook.py +113 -0
- erk/cli/commands/exec/scripts/validate_plan_content.py +98 -0
- erk/cli/commands/exec/scripts/wrap_plan_in_metadata_block.py +34 -0
- erk/cli/commands/implement.py +695 -0
- erk/cli/commands/implement_shared.py +649 -0
- erk/cli/commands/info/__init__.py +14 -0
- erk/cli/commands/info/release_notes_cmd.py +128 -0
- erk/cli/commands/init.py +801 -0
- erk/cli/commands/land_cmd.py +690 -0
- erk/cli/commands/log_cmd.py +137 -0
- erk/cli/commands/md/__init__.py +5 -0
- erk/cli/commands/md/check.py +118 -0
- erk/cli/commands/md/group.py +14 -0
- erk/cli/commands/navigation_helpers.py +430 -0
- erk/cli/commands/objective/__init__.py +16 -0
- erk/cli/commands/objective/list_cmd.py +47 -0
- erk/cli/commands/objective_helpers.py +132 -0
- erk/cli/commands/plan/__init__.py +32 -0
- erk/cli/commands/plan/check_cmd.py +174 -0
- erk/cli/commands/plan/close_cmd.py +69 -0
- erk/cli/commands/plan/create_cmd.py +120 -0
- erk/cli/commands/plan/docs/__init__.py +18 -0
- erk/cli/commands/plan/docs/extract_cmd.py +53 -0
- erk/cli/commands/plan/docs/unextract_cmd.py +38 -0
- erk/cli/commands/plan/docs/unextracted_cmd.py +72 -0
- erk/cli/commands/plan/extraction/__init__.py +16 -0
- erk/cli/commands/plan/extraction/complete_cmd.py +101 -0
- erk/cli/commands/plan/extraction/create_raw_cmd.py +63 -0
- erk/cli/commands/plan/get.py +71 -0
- erk/cli/commands/plan/list_cmd.py +754 -0
- erk/cli/commands/plan/log_cmd.py +440 -0
- erk/cli/commands/plan/start_cmd.py +459 -0
- erk/cli/commands/planner/__init__.py +40 -0
- erk/cli/commands/planner/configure_cmd.py +73 -0
- erk/cli/commands/planner/connect_cmd.py +96 -0
- erk/cli/commands/planner/create_cmd.py +148 -0
- erk/cli/commands/planner/list_cmd.py +51 -0
- erk/cli/commands/planner/register_cmd.py +105 -0
- erk/cli/commands/planner/set_default_cmd.py +23 -0
- erk/cli/commands/planner/unregister_cmd.py +43 -0
- erk/cli/commands/pr/__init__.py +23 -0
- erk/cli/commands/pr/check_cmd.py +112 -0
- erk/cli/commands/pr/checkout_cmd.py +165 -0
- erk/cli/commands/pr/fix_conflicts_cmd.py +82 -0
- erk/cli/commands/pr/parse_pr_reference.py +10 -0
- erk/cli/commands/pr/submit_cmd.py +360 -0
- erk/cli/commands/pr/sync_cmd.py +181 -0
- erk/cli/commands/prepare_cwd_recovery.py +60 -0
- erk/cli/commands/project/__init__.py +16 -0
- erk/cli/commands/project/init_cmd.py +91 -0
- erk/cli/commands/run/__init__.py +17 -0
- erk/cli/commands/run/list_cmd.py +189 -0
- erk/cli/commands/run/logs_cmd.py +54 -0
- erk/cli/commands/run/shared.py +19 -0
- erk/cli/commands/shell_integration.py +29 -0
- erk/cli/commands/slot/__init__.py +23 -0
- erk/cli/commands/slot/check_cmd.py +277 -0
- erk/cli/commands/slot/common.py +314 -0
- erk/cli/commands/slot/init_pool_cmd.py +157 -0
- erk/cli/commands/slot/list_cmd.py +228 -0
- erk/cli/commands/slot/repair_cmd.py +190 -0
- erk/cli/commands/stack/__init__.py +23 -0
- erk/cli/commands/stack/consolidate_cmd.py +470 -0
- erk/cli/commands/stack/list_cmd.py +79 -0
- erk/cli/commands/stack/move_cmd.py +309 -0
- erk/cli/commands/stack/split_old/README.md +64 -0
- erk/cli/commands/stack/split_old/__init__.py +5 -0
- erk/cli/commands/stack/split_old/command.py +233 -0
- erk/cli/commands/stack/split_old/display.py +116 -0
- erk/cli/commands/stack/split_old/plan.py +216 -0
- erk/cli/commands/status.py +58 -0
- erk/cli/commands/submit.py +768 -0
- erk/cli/commands/up.py +154 -0
- erk/cli/commands/upgrade.py +82 -0
- erk/cli/commands/wt/__init__.py +29 -0
- erk/cli/commands/wt/checkout_cmd.py +110 -0
- erk/cli/commands/wt/create_cmd.py +998 -0
- erk/cli/commands/wt/current_cmd.py +35 -0
- erk/cli/commands/wt/delete_cmd.py +573 -0
- erk/cli/commands/wt/list_cmd.py +332 -0
- erk/cli/commands/wt/rename_cmd.py +66 -0
- erk/cli/config.py +242 -0
- erk/cli/constants.py +29 -0
- erk/cli/core.py +65 -0
- erk/cli/debug.py +9 -0
- erk/cli/ensure-conversion-tasks.md +288 -0
- erk/cli/ensure.py +628 -0
- erk/cli/github_parsing.py +96 -0
- erk/cli/graphite.py +81 -0
- erk/cli/graphite_command.py +80 -0
- erk/cli/help_formatter.py +345 -0
- erk/cli/output.py +361 -0
- erk/cli/presets/dagster.toml +12 -0
- erk/cli/presets/generic.toml +12 -0
- erk/cli/prompt_hooks_templates/README.md +68 -0
- erk/cli/script_output.py +32 -0
- erk/cli/shell_integration/bash_wrapper.sh +32 -0
- erk/cli/shell_integration/fish_wrapper.fish +39 -0
- erk/cli/shell_integration/handler.py +338 -0
- erk/cli/shell_integration/zsh_wrapper.sh +32 -0
- erk/cli/shell_utils.py +171 -0
- erk/cli/subprocess_utils.py +92 -0
- erk/cli/uvx_detection.py +59 -0
- erk/core/__init__.py +0 -0
- erk/core/claude_executor.py +511 -0
- erk/core/claude_settings.py +317 -0
- erk/core/command_log.py +406 -0
- erk/core/commit_message_generator.py +234 -0
- erk/core/completion.py +10 -0
- erk/core/consolidation_utils.py +177 -0
- erk/core/context.py +570 -0
- erk/core/display/__init__.py +4 -0
- erk/core/display/abc.py +24 -0
- erk/core/display/real.py +30 -0
- erk/core/display_utils.py +526 -0
- erk/core/file_utils.py +87 -0
- erk/core/health_checks.py +1315 -0
- erk/core/health_checks_dogfooder/__init__.py +85 -0
- erk/core/health_checks_dogfooder/deprecated_dot_agent_config.py +64 -0
- erk/core/health_checks_dogfooder/legacy_claude_docs.py +69 -0
- erk/core/health_checks_dogfooder/legacy_config_locations.py +122 -0
- erk/core/health_checks_dogfooder/legacy_erk_docs_agent.py +61 -0
- erk/core/health_checks_dogfooder/legacy_erk_kits_folder.py +60 -0
- erk/core/health_checks_dogfooder/legacy_hook_settings.py +104 -0
- erk/core/health_checks_dogfooder/legacy_kit_yaml.py +78 -0
- erk/core/health_checks_dogfooder/legacy_kits_toml.py +43 -0
- erk/core/health_checks_dogfooder/outdated_erk_skill.py +43 -0
- erk/core/implementation_queue/__init__.py +1 -0
- erk/core/implementation_queue/github/__init__.py +8 -0
- erk/core/implementation_queue/github/abc.py +7 -0
- erk/core/implementation_queue/github/noop.py +38 -0
- erk/core/implementation_queue/github/printing.py +43 -0
- erk/core/implementation_queue/github/real.py +119 -0
- erk/core/init_utils.py +227 -0
- erk/core/output_filter.py +338 -0
- erk/core/plan_store/__init__.py +6 -0
- erk/core/planner/__init__.py +1 -0
- erk/core/planner/registry_abc.py +8 -0
- erk/core/planner/registry_fake.py +129 -0
- erk/core/planner/registry_real.py +195 -0
- erk/core/planner/types.py +7 -0
- erk/core/pr_utils.py +30 -0
- erk/core/release_notes.py +263 -0
- erk/core/repo_discovery.py +126 -0
- erk/core/script_writer.py +41 -0
- erk/core/services/__init__.py +1 -0
- erk/core/services/plan_list_service.py +94 -0
- erk/core/shell.py +51 -0
- erk/core/user_feedback.py +11 -0
- erk/core/version_check.py +55 -0
- erk/core/workflow_display.py +75 -0
- erk/core/worktree_pool.py +190 -0
- erk/core/worktree_utils.py +300 -0
- erk/data/CHANGELOG.md +438 -0
- erk/data/__init__.py +1 -0
- erk/data/claude/agents/devrun.md +180 -0
- erk/data/claude/commands/erk/__init__.py +0 -0
- erk/data/claude/commands/erk/create-extraction-plan.md +360 -0
- erk/data/claude/commands/erk/fix-conflicts.md +25 -0
- erk/data/claude/commands/erk/git-pr-push.md +345 -0
- erk/data/claude/commands/erk/implement-stacked-plan.md +96 -0
- erk/data/claude/commands/erk/land.md +193 -0
- erk/data/claude/commands/erk/objective-create.md +370 -0
- erk/data/claude/commands/erk/objective-list.md +34 -0
- erk/data/claude/commands/erk/objective-next-plan.md +220 -0
- erk/data/claude/commands/erk/objective-update-with-landed-pr.md +216 -0
- erk/data/claude/commands/erk/plan-implement.md +202 -0
- erk/data/claude/commands/erk/plan-save.md +45 -0
- erk/data/claude/commands/erk/plan-submit.md +39 -0
- erk/data/claude/commands/erk/pr-address.md +367 -0
- erk/data/claude/commands/erk/pr-submit.md +58 -0
- erk/data/claude/skills/dignified-python/SKILL.md +48 -0
- erk/data/claude/skills/dignified-python/cli-patterns.md +155 -0
- erk/data/claude/skills/dignified-python/dignified-python-core.md +1190 -0
- erk/data/claude/skills/dignified-python/subprocess.md +99 -0
- erk/data/claude/skills/dignified-python/versions/python-3.10.md +517 -0
- erk/data/claude/skills/dignified-python/versions/python-3.11.md +536 -0
- erk/data/claude/skills/dignified-python/versions/python-3.12.md +662 -0
- erk/data/claude/skills/dignified-python/versions/python-3.13.md +653 -0
- erk/data/claude/skills/erk-diff-analysis/SKILL.md +27 -0
- erk/data/claude/skills/erk-diff-analysis/references/commit-message-prompt.md +78 -0
- erk/data/claude/skills/learned-docs/SKILL.md +362 -0
- erk/data/github/actions/setup-claude-erk/action.yml +11 -0
- erk/data/github/prompts/dignified-python-review.md +125 -0
- erk/data/github/workflows/dignified-python-review.yml +61 -0
- erk/data/github/workflows/erk-impl.yml +251 -0
- erk/hooks/__init__.py +1 -0
- erk/hooks/decorators.py +319 -0
- erk/status/__init__.py +8 -0
- erk/status/collectors/__init__.py +9 -0
- erk/status/collectors/base.py +52 -0
- erk/status/collectors/git.py +76 -0
- erk/status/collectors/github.py +81 -0
- erk/status/collectors/graphite.py +80 -0
- erk/status/collectors/impl.py +145 -0
- erk/status/models/__init__.py +4 -0
- erk/status/models/status_data.py +404 -0
- erk/status/orchestrator.py +169 -0
- erk/status/renderers/__init__.py +5 -0
- erk/status/renderers/simple.py +322 -0
- erk/tui/AGENTS.md +193 -0
- erk/tui/CLAUDE.md +1 -0
- erk/tui/__init__.py +1 -0
- erk/tui/app.py +1404 -0
- erk/tui/commands/__init__.py +1 -0
- erk/tui/commands/executor.py +66 -0
- erk/tui/commands/provider.py +165 -0
- erk/tui/commands/real_executor.py +63 -0
- erk/tui/commands/registry.py +121 -0
- erk/tui/commands/types.py +36 -0
- erk/tui/data/__init__.py +1 -0
- erk/tui/data/provider.py +492 -0
- erk/tui/data/types.py +104 -0
- erk/tui/filtering/__init__.py +1 -0
- erk/tui/filtering/logic.py +43 -0
- erk/tui/filtering/types.py +55 -0
- erk/tui/jsonl_viewer/__init__.py +1 -0
- erk/tui/jsonl_viewer/app.py +61 -0
- erk/tui/jsonl_viewer/models.py +208 -0
- erk/tui/jsonl_viewer/widgets.py +204 -0
- erk/tui/sorting/__init__.py +6 -0
- erk/tui/sorting/logic.py +55 -0
- erk/tui/sorting/types.py +68 -0
- erk/tui/styles/dash.tcss +95 -0
- erk/tui/widgets/__init__.py +1 -0
- erk/tui/widgets/command_output.py +112 -0
- erk/tui/widgets/plan_table.py +276 -0
- erk/tui/widgets/status_bar.py +116 -0
- erk-0.4.5.dist-info/METADATA +376 -0
- erk-0.4.5.dist-info/RECORD +331 -0
- erk-0.4.5.dist-info/WHEEL +4 -0
- erk-0.4.5.dist-info/entry_points.txt +2 -0
- erk-0.4.5.dist-info/licenses/LICENSE.md +3 -0
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Create git commit and push branch as PR using git + GitHub CLI
|
|
3
|
+
argument-hint: <description>
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Push PR (Git Only)
|
|
7
|
+
|
|
8
|
+
Automatically create a git commit with a helpful summary message and push the current branch as a pull request using standard git + GitHub CLI (no Graphite required).
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
# Invoke the command (description argument is optional but recommended)
|
|
14
|
+
/erk:git-pr-push "Add user authentication feature"
|
|
15
|
+
|
|
16
|
+
# Without argument (will analyze changes automatically)
|
|
17
|
+
/erk:git-pr-push
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## What This Command Does
|
|
21
|
+
|
|
22
|
+
Handles the complete git-only push-pr workflow:
|
|
23
|
+
|
|
24
|
+
1. Check for uncommitted changes and stage/commit them if needed
|
|
25
|
+
2. Analyze git diff to generate meaningful commit message
|
|
26
|
+
3. Create commit with AI-generated message
|
|
27
|
+
4. Push to origin with upstream tracking
|
|
28
|
+
5. Create GitHub PR (or find existing one)
|
|
29
|
+
6. Report results with PR URL
|
|
30
|
+
|
|
31
|
+
## Key Differences from /gt:submit-branch
|
|
32
|
+
|
|
33
|
+
- Uses standard `git push` instead of `gt submit`
|
|
34
|
+
- Uses `gh pr create` instead of Graphite's PR submission
|
|
35
|
+
- No stack operations (no restack, no stack metadata updates)
|
|
36
|
+
- Simpler workflow: git -> push -> PR (no Graphite layer)
|
|
37
|
+
- Works in any git repository (not just Graphite-enabled repos)
|
|
38
|
+
|
|
39
|
+
## Prerequisites
|
|
40
|
+
|
|
41
|
+
- Git repository with remote configured
|
|
42
|
+
- GitHub CLI (`gh`) installed and authenticated
|
|
43
|
+
- Run `gh auth status` to verify authentication
|
|
44
|
+
- Run `gh auth login` if not authenticated
|
|
45
|
+
|
|
46
|
+
## Implementation
|
|
47
|
+
|
|
48
|
+
Execute the git-only push-pr workflow with the following steps:
|
|
49
|
+
|
|
50
|
+
### Step 1: Verify Prerequisites
|
|
51
|
+
|
|
52
|
+
Check GitHub CLI authentication and get current git state:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Check GitHub CLI authentication (show status for verification)
|
|
56
|
+
gh auth status
|
|
57
|
+
|
|
58
|
+
# Get current branch name
|
|
59
|
+
current_branch=$(git branch --show-current)
|
|
60
|
+
|
|
61
|
+
# Check for uncommitted changes
|
|
62
|
+
has_changes=$(git status --porcelain)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
If `gh auth status` fails, report error and tell user to run `gh auth login`.
|
|
66
|
+
|
|
67
|
+
### Step 2: Stage Changes (if needed)
|
|
68
|
+
|
|
69
|
+
If `has_changes` is non-empty, stage all changes:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
git add .
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Step 3: Analyze Staged Diff
|
|
76
|
+
|
|
77
|
+
Get the staged diff and analyze it to generate a commit message:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# Get repository root for relative paths
|
|
81
|
+
repo_root=$(git rev-parse --show-toplevel)
|
|
82
|
+
|
|
83
|
+
# Get staged diff for analysis
|
|
84
|
+
git diff --staged
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Load the `erk-diff-analysis` skill for commit message generation guidance.
|
|
88
|
+
|
|
89
|
+
### Step 4: Create Commit
|
|
90
|
+
|
|
91
|
+
Create the commit with your AI-generated message using heredoc:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
git commit -m "$(cat <<'COMMIT_MSG'
|
|
95
|
+
[Your generated commit message here]
|
|
96
|
+
COMMIT_MSG
|
|
97
|
+
)"
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Step 5: Push to Remote
|
|
101
|
+
|
|
102
|
+
Push the branch to origin with upstream tracking:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
git push -u origin "$(git branch --show-current)"
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Step 6: Get Closing Text
|
|
109
|
+
|
|
110
|
+
Get the issue closing text if this worktree was created from a GitHub issue:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
closing_text=$(erk exec get-closing-text 2>/dev/null || echo "")
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
This reads `.impl/issue.json` and returns `Closes #N` if an issue reference exists.
|
|
117
|
+
|
|
118
|
+
### Step 6.5: Check for Existing PR
|
|
119
|
+
|
|
120
|
+
Before creating a new PR, check if one already exists for the current branch:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
existing_pr=$(gh pr list --head "$(git branch --show-current)" --state open --json number,url,isDraft --jq '.[0]')
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Decision logic:**
|
|
127
|
+
|
|
128
|
+
- If `existing_pr` is empty or null: No existing PR, proceed to Step 7
|
|
129
|
+
- If `existing_pr` has data: PR exists, skip Step 7 and go directly to Step 8
|
|
130
|
+
|
|
131
|
+
If an existing PR was found, extract its details for reporting:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
pr_url=$(echo "$existing_pr" | jq -r '.url')
|
|
135
|
+
pr_number=$(echo "$existing_pr" | jq -r '.number')
|
|
136
|
+
is_draft=$(echo "$existing_pr" | jq -r '.isDraft')
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Step 7: Create GitHub PR (if no existing PR)
|
|
140
|
+
|
|
141
|
+
**Skip this step if an existing PR was found in Step 6.5.** The push in Step 5 already updated the existing PR with new commits.
|
|
142
|
+
|
|
143
|
+
Extract PR title (first line) and body (remaining lines) from commit message, then create PR with closing text appended:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
# Get the commit message
|
|
147
|
+
commit_msg=$(git log -1 --pretty=%B)
|
|
148
|
+
|
|
149
|
+
# Extract first line as title
|
|
150
|
+
pr_title=$(echo "$commit_msg" | head -n 1)
|
|
151
|
+
|
|
152
|
+
# Extract remaining lines as body (skip empty first line after title)
|
|
153
|
+
commit_body=$(echo "$commit_msg" | tail -n +2)
|
|
154
|
+
|
|
155
|
+
# Append closing text if present
|
|
156
|
+
if [ -n "$closing_text" ]; then
|
|
157
|
+
pr_body="${commit_body}
|
|
158
|
+
|
|
159
|
+
${closing_text}"
|
|
160
|
+
else
|
|
161
|
+
pr_body="${commit_body}"
|
|
162
|
+
fi
|
|
163
|
+
|
|
164
|
+
# Create PR using GitHub CLI
|
|
165
|
+
gh pr create --title "$pr_title" --body "$pr_body"
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Step 8: Validate PR Rules
|
|
169
|
+
|
|
170
|
+
Run the PR check command to validate the PR was created correctly:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
erk pr check
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
This validates:
|
|
177
|
+
|
|
178
|
+
- Issue closing reference (Closes #N) is present when `.impl/issue.json` exists
|
|
179
|
+
- PR body contains the standard checkout footer
|
|
180
|
+
|
|
181
|
+
If any checks fail, display the output and warn the user, but continue to Step 9.
|
|
182
|
+
|
|
183
|
+
### Step 9: Report Results
|
|
184
|
+
|
|
185
|
+
Display a clear summary based on whether a PR was created or found:
|
|
186
|
+
|
|
187
|
+
**If a NEW PR was created (Step 7 was executed):**
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
## Branch Submission Complete
|
|
191
|
+
|
|
192
|
+
### What Was Done
|
|
193
|
+
|
|
194
|
+
✓ Staged all uncommitted changes
|
|
195
|
+
✓ Created commit with AI-generated message
|
|
196
|
+
✓ Pushed branch to origin with upstream tracking
|
|
197
|
+
✓ Created GitHub PR
|
|
198
|
+
✓ Linked to issue #N (will auto-close on merge) [only if closing_text was present]
|
|
199
|
+
|
|
200
|
+
### View PR
|
|
201
|
+
|
|
202
|
+
[PR URL from gh pr create output]
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
**If an EXISTING PR was found (Step 7 was skipped):**
|
|
206
|
+
|
|
207
|
+
```
|
|
208
|
+
## Branch Submission Complete
|
|
209
|
+
|
|
210
|
+
### What Was Done
|
|
211
|
+
|
|
212
|
+
✓ Staged all uncommitted changes
|
|
213
|
+
✓ Created commit with AI-generated message
|
|
214
|
+
✓ Pushed branch to origin with upstream tracking
|
|
215
|
+
✓ Found existing PR #N for this branch (skipped PR creation)
|
|
216
|
+
✓ Linked to issue #M (will auto-close on merge) [only if closing_text was present]
|
|
217
|
+
|
|
218
|
+
### Note
|
|
219
|
+
|
|
220
|
+
[If is_draft is true]: This is a draft PR. When ready for review, run: `gh pr ready`
|
|
221
|
+
|
|
222
|
+
### View PR
|
|
223
|
+
|
|
224
|
+
[PR URL extracted from existing_pr]
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**Conditional lines:**
|
|
228
|
+
|
|
229
|
+
- The "Linked to issue" line should only appear if `closing_text` was non-empty
|
|
230
|
+
- The "Note" section with draft guidance should only appear if `is_draft` is true
|
|
231
|
+
|
|
232
|
+
**CRITICAL**: The PR URL MUST be the absolute last line of your output. Do not add any text after it.
|
|
233
|
+
|
|
234
|
+
## Error Handling
|
|
235
|
+
|
|
236
|
+
When errors occur, provide clear guidance:
|
|
237
|
+
|
|
238
|
+
**GitHub CLI not authenticated:**
|
|
239
|
+
|
|
240
|
+
```
|
|
241
|
+
❌ GitHub CLI is not authenticated
|
|
242
|
+
|
|
243
|
+
To use this command, authenticate with GitHub:
|
|
244
|
+
gh auth login
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**Nothing to commit:**
|
|
248
|
+
|
|
249
|
+
```
|
|
250
|
+
❌ No changes to commit
|
|
251
|
+
|
|
252
|
+
Your working directory is clean. Make some changes first.
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
**Push failed (diverged branches):**
|
|
256
|
+
|
|
257
|
+
```
|
|
258
|
+
❌ Push failed: branch has diverged
|
|
259
|
+
|
|
260
|
+
Option 1: Pull and merge
|
|
261
|
+
git pull origin [branch]
|
|
262
|
+
|
|
263
|
+
Option 2: Force push (⚠️ overwrites remote)
|
|
264
|
+
git push -f origin [branch]
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Note: The "PR already exists" case is now handled automatically in Step 6.5. If a PR exists for the current branch, the command will skip PR creation and report the existing PR URL instead.
|
|
268
|
+
|
|
269
|
+
## Best Practices
|
|
270
|
+
|
|
271
|
+
### Never Change Directory
|
|
272
|
+
|
|
273
|
+
**NEVER use `cd` during execution.** Always use absolute paths or git's `-C` flag.
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
# ❌ WRONG
|
|
277
|
+
cd /path/to/repo && git status
|
|
278
|
+
|
|
279
|
+
# ✅ CORRECT
|
|
280
|
+
git -C /path/to/repo status
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
**Rationale:** Changing directories pollutes the execution context and makes it harder to reason about state. The working directory should remain stable throughout the entire workflow.
|
|
284
|
+
|
|
285
|
+
### Never Write to Temporary Files
|
|
286
|
+
|
|
287
|
+
**NEVER write commit messages or other content to temporary files.** Always use in-context manipulation and shell built-ins.
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
# ❌ WRONG - Triggers permission prompts
|
|
291
|
+
echo "$message" > "${TMPDIR:-/tmp}/commit_msg.txt"
|
|
292
|
+
git commit -F "${TMPDIR:-/tmp}/commit_msg.txt"
|
|
293
|
+
|
|
294
|
+
# ✅ CORRECT - In-memory heredoc
|
|
295
|
+
git commit -m "$(cat <<'EOF'
|
|
296
|
+
$message
|
|
297
|
+
EOF
|
|
298
|
+
)"
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
**Rationale:** Temporary files require filesystem permissions and create unnecessary I/O. Since agents operate in isolated contexts, there's no risk of context pollution from in-memory manipulation.
|
|
302
|
+
|
|
303
|
+
## Quality Standards
|
|
304
|
+
|
|
305
|
+
### Always
|
|
306
|
+
|
|
307
|
+
- Be concise and strategic in analysis
|
|
308
|
+
- Use component-level descriptions
|
|
309
|
+
- Highlight breaking changes prominently
|
|
310
|
+
- Note test coverage patterns
|
|
311
|
+
- Use relative paths from repository root
|
|
312
|
+
- Provide clear error guidance
|
|
313
|
+
- Use standard git + GitHub CLI commands (no Graphite dependencies)
|
|
314
|
+
|
|
315
|
+
### Never
|
|
316
|
+
|
|
317
|
+
- Add Claude attribution or footer to commit messages
|
|
318
|
+
- Speculate about intentions without code evidence
|
|
319
|
+
- Provide exhaustive lists of every function touched
|
|
320
|
+
- Include implementation details (specific variable names, line numbers)
|
|
321
|
+
- Provide time estimates
|
|
322
|
+
- Use vague language like "various changes"
|
|
323
|
+
- Retry failed operations automatically
|
|
324
|
+
- Write to temporary files (use in-context quoting and shell built-ins instead)
|
|
325
|
+
- Use Graphite-specific commands (`gt submit`, `gt restack`, etc.)
|
|
326
|
+
|
|
327
|
+
## Self-Verification
|
|
328
|
+
|
|
329
|
+
Before completing, verify:
|
|
330
|
+
|
|
331
|
+
- [ ] GitHub CLI authentication checked
|
|
332
|
+
- [ ] Git status verified
|
|
333
|
+
- [ ] Uncommitted changes staged (if any existed)
|
|
334
|
+
- [ ] Staged diff analyzed
|
|
335
|
+
- [ ] Diff analysis is concise and strategic (3-5 key changes max)
|
|
336
|
+
- [ ] Commit message has no Claude footer
|
|
337
|
+
- [ ] File paths are relative to repository root
|
|
338
|
+
- [ ] Commit created successfully
|
|
339
|
+
- [ ] Branch pushed to origin with upstream tracking
|
|
340
|
+
- [ ] Closing text obtained (if issue reference exists)
|
|
341
|
+
- [ ] GitHub PR created successfully (or existing PR found)
|
|
342
|
+
- [ ] PR URL extracted from output
|
|
343
|
+
- [ ] Results displayed with "What Was Done" section listing actions
|
|
344
|
+
- [ ] PR URL placed at end under "View PR" section
|
|
345
|
+
- [ ] Any errors handled with helpful guidance
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Create a stacked branch and implement a saved plan
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# /erk:implement-stacked-plan
|
|
6
|
+
|
|
7
|
+
Create a graphite-stacked branch from a saved plan issue and implement it in the current worktree.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
/erk:implement-stacked-plan <issue-number>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## When to Use This Command
|
|
16
|
+
|
|
17
|
+
✅ **Use when**: You have a saved plan (GitHub issue) and want to implement it as a stacked branch on top of your current branch.
|
|
18
|
+
|
|
19
|
+
❌ **Don't use when**:
|
|
20
|
+
|
|
21
|
+
- You just finished planning and want to save + implement → Use `/erk:plan-implement`
|
|
22
|
+
- You want to implement in a new worktree → Use `erk implement <issue-number>`
|
|
23
|
+
|
|
24
|
+
## Prerequisites
|
|
25
|
+
|
|
26
|
+
- Must be in a git repository managed by erk
|
|
27
|
+
- Must have a saved plan issue on GitHub (with `erk-plan` label)
|
|
28
|
+
- GitHub CLI (`gh`) must be authenticated
|
|
29
|
+
- Graphite CLI (`gt`) must be available
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Agent Instructions
|
|
34
|
+
|
|
35
|
+
### Step 1: Validate Argument
|
|
36
|
+
|
|
37
|
+
Extract the issue number from the argument (handles `#123` or `123` format).
|
|
38
|
+
|
|
39
|
+
If no issue number provided, display usage and stop:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
Usage: /erk:implement-stacked-plan <issue-number>
|
|
43
|
+
|
|
44
|
+
Example: /erk:implement-stacked-plan 4128
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Step 2: Record Current Branch
|
|
48
|
+
|
|
49
|
+
Get the current branch name (this will be the parent for stacking):
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
git branch --show-current
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Save this as `parent_branch`.
|
|
56
|
+
|
|
57
|
+
### Step 3: Setup Implementation
|
|
58
|
+
|
|
59
|
+
Run the setup command to fetch the plan, create the branch, and set up `.impl/`:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
erk exec setup-impl-from-issue <issue-number>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Parse the output to get the `branch` name from the JSON.
|
|
66
|
+
|
|
67
|
+
If this fails, display the error and stop.
|
|
68
|
+
|
|
69
|
+
### Step 4: Track with Graphite
|
|
70
|
+
|
|
71
|
+
Register the new branch with graphite, stacked on the parent:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
gt track --branch <branch-name> --parent <parent_branch>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
This makes the branch part of the graphite stack for proper PR management.
|
|
78
|
+
|
|
79
|
+
### Step 5: Execute Implementation
|
|
80
|
+
|
|
81
|
+
Invoke the standard implementation workflow:
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
/erk:plan-implement
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
This handles all remaining steps: reading the plan, loading context, executing phases, running CI, and creating the PR.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Notes
|
|
92
|
+
|
|
93
|
+
- The issue must have the `erk-plan` label
|
|
94
|
+
- The branch will be stacked on whatever branch you were on when you started
|
|
95
|
+
- Use this when you want to add a stacked change in the current worktree
|
|
96
|
+
- Differs from `erk implement` which creates a new worktree
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Land PR with objective awareness - updates objective after landing
|
|
3
|
+
argument-hint: "[branch|PR#|URL] [--skip-objective]"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /erk:pr-land
|
|
7
|
+
|
|
8
|
+
Objective-aware wrapper for `erk pr land`. Lands the PR first, then offers to update the linked objective if one exists.
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
# Land PR for current branch
|
|
14
|
+
/erk:pr-land
|
|
15
|
+
|
|
16
|
+
# Land PR for specific branch
|
|
17
|
+
/erk:pr-land feature-branch
|
|
18
|
+
|
|
19
|
+
# Land PR by number
|
|
20
|
+
/erk:pr-land 123
|
|
21
|
+
|
|
22
|
+
# Land PR by URL
|
|
23
|
+
/erk:pr-land https://github.com/owner/repo/pull/123
|
|
24
|
+
|
|
25
|
+
# Skip objective update prompt
|
|
26
|
+
/erk:pr-land --skip-objective
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Agent Instructions
|
|
32
|
+
|
|
33
|
+
### Step 1: Parse Arguments
|
|
34
|
+
|
|
35
|
+
Parse the command arguments:
|
|
36
|
+
|
|
37
|
+
- `$ARGUMENTS` may contain: branch name, PR number, PR URL, or be empty (use current branch)
|
|
38
|
+
- Check for `--skip-objective` flag
|
|
39
|
+
|
|
40
|
+
### Step 2: Determine Branch Name
|
|
41
|
+
|
|
42
|
+
If no branch argument provided, get current branch:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
git branch --show-current
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
If argument is a PR number or URL, extract the branch name:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# For PR number
|
|
52
|
+
gh pr view <number> --json headRefName -q '.headRefName'
|
|
53
|
+
|
|
54
|
+
# For PR URL (extract number first, then use above)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Step 3: Resolve to PR Number
|
|
58
|
+
|
|
59
|
+
**Critical:** Always resolve the branch to a PR number. The `erk pr land` command only accepts PR numbers or URLs, not branch names.
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# Get PR number for branch
|
|
63
|
+
gh pr list --head <branch-name> --state open --json number -q '.[0].number'
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
If no open PR found, check all states:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
gh pr list --head <branch-name> --state all --limit 1 --json number -q '.[0].number'
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**If no PR found:** Report error and exit - cannot land without a PR.
|
|
73
|
+
|
|
74
|
+
### Step 4: Extract Plan Issue Number (P-prefix Detection)
|
|
75
|
+
|
|
76
|
+
Parse the plan issue number from the branch name pattern `P<number>-...`
|
|
77
|
+
|
|
78
|
+
Example: `P3699-objective-aware-pr-land` -> Plan Issue #3699
|
|
79
|
+
|
|
80
|
+
**If branch doesn't have P-prefix:** Record that there's no plan link. Continue to Step 6.
|
|
81
|
+
|
|
82
|
+
### Step 5: Check for Objective Link
|
|
83
|
+
|
|
84
|
+
If branch has P-prefix, use the `get-plan-metadata` exec command to extract the objective issue:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
erk exec get-plan-metadata <plan-number> objective_issue
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Output format:**
|
|
91
|
+
|
|
92
|
+
```json
|
|
93
|
+
{
|
|
94
|
+
"success": true,
|
|
95
|
+
"value": 3400,
|
|
96
|
+
"issue_number": 3509,
|
|
97
|
+
"field": "objective_issue"
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
- If `success` is `true` and `value` is an integer, record that objective issue number
|
|
102
|
+
- If `success` is `true` and `value` is `null`, there's no objective link
|
|
103
|
+
- If `success` is `false`, warn and skip objective workflow (fail-open behavior)
|
|
104
|
+
|
|
105
|
+
### Step 6: Execute erk pr land
|
|
106
|
+
|
|
107
|
+
Land the PR using the resolved PR number. Use `--force` to skip interactive confirmation (required for non-TTY execution):
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
erk pr land <PR_NUMBER> --force
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**If landing fails:** Report the error and exit.
|
|
114
|
+
|
|
115
|
+
### Step 7: Post-Land Objective Update
|
|
116
|
+
|
|
117
|
+
**Only runs if:** Landing succeeded AND plan has `objective_issue` AND `--skip-objective` not passed
|
|
118
|
+
|
|
119
|
+
1. Display: "PR #`<pr>` landed successfully."
|
|
120
|
+
2. Display: "This PR is part of Objective #`<objective>`."
|
|
121
|
+
3. Prompt user with AskUserQuestion:
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
Would you like to update the objective now?
|
|
125
|
+
|
|
126
|
+
Options:
|
|
127
|
+
1. Yes, update objective (Recommended)
|
|
128
|
+
2. Skip - I'll update it later
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**If user selects "Yes":**
|
|
132
|
+
|
|
133
|
+
Run the `/erk:objective-update-with-landed-pr` workflow inline:
|
|
134
|
+
|
|
135
|
+
1. Post an action comment to the objective issue with:
|
|
136
|
+
- What was done (infer from PR title/description)
|
|
137
|
+
- Lessons learned (infer from implementation)
|
|
138
|
+
- Roadmap updates (which steps are now done)
|
|
139
|
+
|
|
140
|
+
2. Update the objective body:
|
|
141
|
+
- Mark relevant roadmap steps as `done`
|
|
142
|
+
- Add PR number to the step
|
|
143
|
+
- Update "Current Focus" section
|
|
144
|
+
|
|
145
|
+
3. Check if all steps are complete - if so, offer to close the objective.
|
|
146
|
+
|
|
147
|
+
**If user selects "Skip":** Just report success and remind them to update later.
|
|
148
|
+
|
|
149
|
+
### Step 8: Report Results
|
|
150
|
+
|
|
151
|
+
Display final status:
|
|
152
|
+
|
|
153
|
+
- PR landing result
|
|
154
|
+
- Objective update result (if applicable)
|
|
155
|
+
- Link to objective issue (if applicable)
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Fail-Open Behavior
|
|
160
|
+
|
|
161
|
+
The command lands normally (no blocking) when:
|
|
162
|
+
|
|
163
|
+
| Scenario | Action |
|
|
164
|
+
| --------------------------------- | ------------------------------- |
|
|
165
|
+
| Branch has no P-prefix | Land normally, skip objective |
|
|
166
|
+
| Plan issue not found | Warn, land normally |
|
|
167
|
+
| `objective_issue` is null/missing | Land normally, skip objective |
|
|
168
|
+
| `--skip-objective` flag passed | Land normally, skip objective |
|
|
169
|
+
| Objective update fails | Warn but report landing success |
|
|
170
|
+
| Any parsing/API error | Warn, continue with landing |
|
|
171
|
+
|
|
172
|
+
**Principle:** Landing always proceeds. Objective update is post-land and optional.
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Output Format
|
|
177
|
+
|
|
178
|
+
- **Start:** "Resolving PR for branch..."
|
|
179
|
+
- **No PR found:** "Error: No PR found for branch `<branch>`"
|
|
180
|
+
- **Landing:** "Landing PR #`<number>`..."
|
|
181
|
+
- **Success:** "PR #`<number>` landed successfully."
|
|
182
|
+
- **Objective prompt:** (as shown above)
|
|
183
|
+
- **Objective updated:** "Objective #`<number>` updated."
|
|
184
|
+
- **End:** Show final status and any relevant links
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Error Handling
|
|
189
|
+
|
|
190
|
+
- **No PR found:** Report error and exit (cannot land without PR)
|
|
191
|
+
- **Landing fails:** Report `erk pr land` error output and exit
|
|
192
|
+
- **Objective update fails:** Warn but report landing as successful
|
|
193
|
+
- **API errors during objective check:** Warn and skip objective workflow
|