delegate-agent-cli 0.23.0__tar.gz → 0.24.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.
Files changed (156) hide show
  1. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/CHANGELOG.md +15 -0
  2. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/PKG-INFO +8 -1
  3. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/README.md +7 -0
  4. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/docs/cli-reference.md +37 -0
  5. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/docs/security-model.md +13 -0
  6. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/docs/worktrees.md +19 -0
  7. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/pyproject.toml +1 -1
  8. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/__init__.py +1 -1
  9. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/cli.py +228 -6
  10. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/cli_parser.py +173 -2
  11. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/command_help.py +61 -0
  12. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/isolation.py +3 -0
  13. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/private_io.py +97 -6
  14. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/prompt_transport.py +6 -0
  15. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/request_build.py +83 -13
  16. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/request_models.py +35 -0
  17. delegate_agent_cli-0.24.0/src/delegate_agent/resume_command.py +861 -0
  18. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/run_metadata.py +3 -0
  19. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/run_registry.py +149 -28
  20. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/run_status.py +9 -4
  21. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/runner.py +63 -7
  22. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/snapshot_view.py +2 -0
  23. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/wait_cancel_commands.py +1 -1
  24. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/workflows/runtime.py +6 -2
  25. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/worktree_execution.py +18 -2
  26. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/worktree_gc.py +19 -0
  27. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/worktree_records.py +78 -7
  28. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/worktree_remove.py +31 -1
  29. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent_cli.egg-info/PKG-INFO +8 -1
  30. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent_cli.egg-info/SOURCES.txt +10 -0
  31. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_command_help.py +1 -0
  32. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_delegate_validation.py +17 -0
  33. delegate_agent_cli-0.24.0/tests/test_resume_attachment.py +604 -0
  34. delegate_agent_cli-0.24.0/tests/test_resume_capture.py +186 -0
  35. delegate_agent_cli-0.24.0/tests/test_resume_inheritance.py +385 -0
  36. delegate_agent_cli-0.24.0/tests/test_resume_parser.py +54 -0
  37. delegate_agent_cli-0.24.0/tests/test_resume_projections.py +87 -0
  38. delegate_agent_cli-0.24.0/tests/test_resume_refusals.py +140 -0
  39. delegate_agent_cli-0.24.0/tests/test_resume_size_guard.py +151 -0
  40. delegate_agent_cli-0.24.0/tests/test_resume_stale.py +172 -0
  41. delegate_agent_cli-0.24.0/tests/test_resume_trust.py +301 -0
  42. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_retention.py +33 -0
  43. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_run_registry.py +164 -0
  44. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_runner_capture.py +80 -0
  45. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/CONTRIBUTING.md +0 -0
  46. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/LICENSE +0 -0
  47. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/MANIFEST.in +0 -0
  48. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/SECURITY.md +0 -0
  49. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/bin/delegate-profile-shim +0 -0
  50. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/bin/delegate.py +0 -0
  51. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/config.example.json +0 -0
  52. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/docs/agent-setup.md +0 -0
  53. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/docs/assets/delegate-agent-header.png +0 -0
  54. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/docs/configuration.md +0 -0
  55. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/docs/delegate-workflows.md +0 -0
  56. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/docs/development.md +0 -0
  57. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/docs/live-runtime.md +0 -0
  58. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/docs/publishing-checklist.md +0 -0
  59. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/docs/troubleshooting.md +0 -0
  60. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/examples/task.claude.json +0 -0
  61. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/examples/task.codex.json +0 -0
  62. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/examples/task.cursor.json +0 -0
  63. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/examples/task.droid.json +0 -0
  64. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/examples/task.grok.json +0 -0
  65. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/examples/task.judge.json +0 -0
  66. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/examples/task.kimi.json +0 -0
  67. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/setup.cfg +0 -0
  68. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/archived_logs.py +0 -0
  69. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/argv_builders.py +0 -0
  70. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/argv_utils.py +0 -0
  71. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/bundled_models.py +0 -0
  72. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/capability_commands.py +0 -0
  73. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/child_failures.py +0 -0
  74. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/command_errors.py +0 -0
  75. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/config.py +0 -0
  76. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/config_commands.py +0 -0
  77. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/constants.py +0 -0
  78. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/describe_payload.py +0 -0
  79. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/errors.py +0 -0
  80. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/git_utils.py +0 -0
  81. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/harness_discovery.py +0 -0
  82. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/harness_events.py +0 -0
  83. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/inspection_commands.py +0 -0
  84. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/json_types.py +0 -0
  85. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/log_output.py +0 -0
  86. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/model_discovery.py +0 -0
  87. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/profile_commands.py +0 -0
  88. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/profile_guard.py +0 -0
  89. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/profiles.py +0 -0
  90. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/prompt_instructions.py +0 -0
  91. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/reasoning.py +0 -0
  92. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/redaction.py +0 -0
  93. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/rendering.py +0 -0
  94. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/retention.py +0 -0
  95. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/run_output_commands.py +0 -0
  96. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/safe_workspace.py +0 -0
  97. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/seatbelt.py +0 -0
  98. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/setup_commands.py +0 -0
  99. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/structured_output.py +0 -0
  100. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/workflows/__init__.py +0 -0
  101. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/workflows/commands.py +0 -0
  102. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/workflows/registry.py +0 -0
  103. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/workflows/schema.py +0 -0
  104. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/workflows/script.py +0 -0
  105. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/worktree_commands.py +0 -0
  106. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/worktree_mgmt.py +0 -0
  107. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/worktree_summary.py +0 -0
  108. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent/wsl.py +0 -0
  109. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent_cli.egg-info/dependency_links.txt +0 -0
  110. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent_cli.egg-info/entry_points.txt +0 -0
  111. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent_cli.egg-info/requires.txt +0 -0
  112. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/src/delegate_agent_cli.egg-info/top_level.txt +0 -0
  113. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_capability_commands.py +0 -0
  114. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_child_failures.py +0 -0
  115. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_codex_pure_sandbox.py +0 -0
  116. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_codex_thread_resilience.py +0 -0
  117. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_config_commands.py +0 -0
  118. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_delegate_help_cli.py +0 -0
  119. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_delegate_isolation.py +0 -0
  120. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_delegate_parser.py +0 -0
  121. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_end_to_end_tracking.py +0 -0
  122. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_engine_argv.py +0 -0
  123. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_execution_argv_and_prompt.py +0 -0
  124. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_execution_dry_run.py +0 -0
  125. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_execution_worktree_failure_cleanup.py +0 -0
  126. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_execution_worktree_preflight.py +0 -0
  127. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_execution_worktree_run.py +0 -0
  128. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_harness_discovery.py +0 -0
  129. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_harness_events.py +0 -0
  130. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_inspection_commands.py +0 -0
  131. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_kimi_commands.py +0 -0
  132. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_model_discovery.py +0 -0
  133. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_model_selection_wave1a.py +0 -0
  134. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_model_selection_wave1b.py +0 -0
  135. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_omp_read_only_behavior.py +0 -0
  136. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_packaging.py +0 -0
  137. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_profiles.py +0 -0
  138. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_pure_call.py +0 -0
  139. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_reasoning_capabilities.py +0 -0
  140. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_safe_workspace_isolation.py +0 -0
  141. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_setup_commands.py +0 -0
  142. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_slash_passthrough.py +0 -0
  143. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_snapshot_redaction.py +0 -0
  144. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_snapshot_rendering.py +0 -0
  145. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_snapshot_run_output.py +0 -0
  146. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_snapshot_view.py +0 -0
  147. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_structured_output.py +0 -0
  148. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_tracked_timeout.py +0 -0
  149. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_utility_modules.py +0 -0
  150. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_wait_cancel_commands.py +0 -0
  151. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_wave4_launch_features.py +0 -0
  152. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_workflow_commands.py +0 -0
  153. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_worktree_list_show.py +0 -0
  154. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_worktree_prune_gc.py +0 -0
  155. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_worktree_remove.py +0 -0
  156. {delegate_agent_cli-0.23.0 → delegate_agent_cli-0.24.0}/tests/test_wsl_guardrails.py +0 -0
@@ -5,6 +5,20 @@ All notable changes to this project are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.24.0] - 2026-07-31
9
+
10
+ ### Added
11
+
12
+ - Added `delegate resume` for relaunching terminal Runs with a bounded,
13
+ untrusted continuation built from the original prompt and prior result.
14
+ Resume preserves compatible launch settings, supports explicit cross-engine
15
+ resumes, and attaches to an existing persistent worktree with a live cleanup
16
+ lease rather than creating a second worktree.
17
+ - Added private `prompt.txt` capture for new tracked Runs so their original
18
+ prompts can be resumed without placing prompt text in the Manifest or
19
+ Snapshot. Legacy records without that capture fail closed with a clear
20
+ `resume_prompt_unavailable` error.
21
+
8
22
  ## [0.23.0] - 2026-07-30
9
23
 
10
24
  ### Added
@@ -769,6 +783,7 @@ Usage-audit fix wave: 82 sessions and 1,241 delegate invocations from one week o
769
783
 
770
784
  - Releases before 0.1.3 predate this changelog.
771
785
 
786
+ [0.24.0]: https://github.com/treygoff24/delegate-agent/compare/v0.23.0...v0.24.0
772
787
  [0.23.0]: https://github.com/treygoff24/delegate-agent/compare/v0.22.0...v0.23.0
773
788
  [0.22.0]: https://github.com/treygoff24/delegate-agent/compare/v0.21.0...v0.22.0
774
789
  [0.21.0]: https://github.com/treygoff24/delegate-agent/compare/v0.20.0...v0.21.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: delegate-agent-cli
3
- Version: 0.23.0
3
+ Version: 0.24.0
4
4
  Summary: A tiny CLI for delegating bounded agent tasks across coding-agent runtimes.
5
5
  Author: Trey Goff
6
6
  License-Expression: MIT
@@ -332,6 +332,7 @@ delegate runs --recent
332
332
  delegate ps # active and stale tracked runs
333
333
  delegate snapshot <alias-or-runId>
334
334
  delegate run-output <alias-or-runId>
335
+ delegate resume <alias-or-runId> "Continue from the previous result and run the tests."
335
336
  delegate runs prune --dry-run # preview GC of terminal run records older than 30 days
336
337
  ```
337
338
 
@@ -341,6 +342,12 @@ newest codex run and `delegate run-output codex:glm` the newest matching
341
342
  model. Envelopes echo `requestedHandle`/`resolvedHandle`/`resolutionKind` so you
342
343
  can confirm which run you addressed.
343
344
 
345
+ `resume` creates a new Run from a terminal source Run. It carries forward the
346
+ source mode and compatible launch settings, places the prior prompt and bounded
347
+ result before your new instructions, and attaches to an existing persistent
348
+ worktree instead of creating another one. Use `--dry-run` to inspect the
349
+ resolved launch without creating a Run.
350
+
344
351
  `run-output` defaults to the best available parent-facing output: a completion
345
352
  report when present, a recovered final assistant message when possible, or
346
353
  bounded stdout/stderr diagnostics. Use `--completion-report` when you want that
@@ -299,6 +299,7 @@ delegate runs --recent
299
299
  delegate ps # active and stale tracked runs
300
300
  delegate snapshot <alias-or-runId>
301
301
  delegate run-output <alias-or-runId>
302
+ delegate resume <alias-or-runId> "Continue from the previous result and run the tests."
302
303
  delegate runs prune --dry-run # preview GC of terminal run records older than 30 days
303
304
  ```
304
305
 
@@ -308,6 +309,12 @@ newest codex run and `delegate run-output codex:glm` the newest matching
308
309
  model. Envelopes echo `requestedHandle`/`resolvedHandle`/`resolutionKind` so you
309
310
  can confirm which run you addressed.
310
311
 
312
+ `resume` creates a new Run from a terminal source Run. It carries forward the
313
+ source mode and compatible launch settings, places the prior prompt and bounded
314
+ result before your new instructions, and attaches to an existing persistent
315
+ worktree instead of creating another one. Use `--dry-run` to inspect the
316
+ resolved launch without creating a Run.
317
+
311
318
  `run-output` defaults to the best available parent-facing output: a completion
312
319
  report when present, a recovered final assistant message when possible, or
313
320
  bounded stdout/stderr diagnostics. Use `--completion-report` when you want that
@@ -935,10 +935,47 @@ delegate runs prune [--older-than DAYS] [--dry-run]
935
935
  delegate ps [--harness HARNESS] [--group NAME] [--limit N]
936
936
  delegate snapshot [--latest HARNESS] [--no-redact] <handle>
937
937
  delegate run-output [--latest HARNESS] <handle> [--completion-report] [--stdout] [--stderr] [--tail N] [--max-chars N] [--raw] [--no-redact]
938
+ delegate resume [--engine ENGINE] [--model MODEL] [--reasoning-effort LEVEL] [--timeout SEC] [--dry-run] <handle> [extra instructions...]
938
939
  delegate wait <handle>... [--latest HARNESS] [--group NAME] [--timeout SEC] [--interval SEC] [--completion-report]
939
940
  delegate cancel <handle>...
940
941
  ```
941
942
 
943
+ `delegate resume` relaunches a terminal Run as a new Run. It accepts
944
+ `succeeded`, `failed`, `cancelled`, and stale Runs; an effectively running Run
945
+ is refused. A successful source requires extra instructions. The continuation
946
+ contains the original prompt, then a bounded prior-run Completion Report (or a
947
+ Snapshot digest), then the new instructions last. Prior-run content is framed
948
+ as untrusted data and is disclosed to the target Harness, including on a
949
+ cross-engine resume. Resume options must appear before the handle; trailing
950
+ tokens are continuation instructions.
951
+
952
+ The new Run inherits source settings according to this table. `--engine` and
953
+ the listed resume flags must precede the handle; `--group` and
954
+ `--auth-profile` are global flags and therefore precede `resume`. A persistent
955
+ worktree source is resumed by attaching to its existing worktree rather than
956
+ creating a second one. The attachment is a live lease: `worktree remove`,
957
+ `worktree prune`, and `worktree gc` refuse or skip the worktree while the
958
+ attached Run may still be active. `--dry-run` resolves the continuation without
959
+ creating a Run or writing a prompt record.
960
+
961
+ | Field | Source manifest key | Override flag | Absent or legacy behavior | Cross-engine rule |
962
+ | --- | --- | --- | --- | --- |
963
+ | Engine | `engine`, falling back to `harness` | `--engine` | A missing or unknown source engine refuses resume. | The selected engine becomes the target; engine-scoped fields below may drop. |
964
+ | Mode | `mode` | None; v1 does not override mode. | A missing or invalid mode refuses resume. | Retained unchanged. |
965
+ | Model selection | `modelAlias`, then `modelRequested`, `modelResolved`, then `model` | `--model` | No usable key uses the target engine configuration default and emits a note. | Source model selection drops; pass `--model` to pin a target model. |
966
+ | Reasoning effort | `requestedReasoningEffort`, then `resolvedReasoningEffort`, together with `reasoningEffortSource` | `--reasoning-effort` | Missing effort uses the target default and emits a note. A source value from configuration is re-resolved through target capability/configuration; only `cli` and `input-json` source intent is inherited directly. | Source effort drops with a note; an explicit override remains valid. |
967
+ | Fast tier | `requestedFast` | `--fast` or `--no-fast` | Omitted leaves fast unspecified. | Inherited only for a same-engine Codex resume. Other targets drop it; non-Codex targets emit a drop note when a source value is present. |
968
+ | Progress intent | `progressRequested` (`on`, `off`, or omitted) | `--progress` or `--no-progress` | Omitted uses target progress configuration and emits a note; only `on` and `off` are inherited. | Retained; progress intent is not engine-specific. |
969
+ | Timeout | `timeoutSeconds` | `--timeout` | Omitted uses the target timeout default and emits a note. A present value must be a positive integer (an integral JSON float is accepted). | Retained. |
970
+ | Output schema | Inline `outputSchema` text | `--output-schema PATH` or `--no-output-schema` | Omitted means no schema. Stored text is re-materialized privately only during normal launch. | Only Codex inherits inline schema text. Other engines soft-drop it with a note before output-schema validation. |
971
+ | OpenCode agent | `agent` | None | Omitted means no agent selection. | Inherited only for a same-engine OpenCode resume; otherwise dropped with a note. |
972
+ | Workspace cwd / execution cwd | `cwd`; persistent records also derive `executionCwd`, branch, and source Git root | None (`--cwd` selects the registry workspace and must match recorded `cwd`) | Missing `cwd` falls back to the selected registry workspace; missing persistent-worktree metadata causes attachment validation to refuse. | Retained as workspace context; an attach uses the validated existing worktree rather than copying `executionCwd` into a new worktree. |
973
+ | Isolation / lifecycle | `isolationMode`; persistent detection also reads `isolationLifecycle`, `preservedWorkspace`, `worktreeStatus`, and `worktreeAttachment` | None; `--isolation` is rejected for resume. | Missing ordinary `isolationMode` uses target isolation configuration and emits a note. | Retained. Persistent or attached sources become an `attached` execution lifecycle. |
974
+ | Group | `group` | Global `--group` | Omitted uses the ungrouped target default and emits a note. | Retained. |
975
+ | Auth profile | `authProfile` | Global `--auth-profile` | Omitted uses target profile detection/default and emits a note. | Retained. |
976
+ | Forbid commit | `commitPolicy.forbidCommit` when exactly `true` | None | Omitted or any other value leaves commit prohibition off. | Retained. |
977
+ | Include dirty | `includeDirty` | `--include-dirty` | Source and explicit values are creation-only and are dropped for ordinary resume with a note. | Retained only as a drop decision; on a persistent/attached source, explicit `--include-dirty` is rejected because attachment does not create or sync a worktree. |
978
+
942
979
  `delegate runs` defaults to recent runs. `--active` preserves the legacy active view and includes both live `running` runs and `stale` runs. Use `--running` for only live tracked processes and `--stale` for runs recorded as running whose PID is missing or dead. `--active`, `--running`, `--stale`, and `--recent` are mutually exclusive. `--group NAME` filters by launch group and the runs table shows a `group` column when any visible run has one.
943
980
  `delegate ps` is the shorter first-class form of `delegate runs --active` and
944
981
  accepts the same harness, group, and limit selectors.
@@ -200,6 +200,19 @@ Persistent worktree isolation is not a security sandbox. It does not prevent:
200
200
  - Writes to absolute paths outside the worktree.
201
201
  - Actions taken through authenticated tools, MCP servers, browser sessions, or external CLIs.
202
202
 
203
+ `delegate resume` reads the initial manifest and `prompt.txt` outside the Registry
204
+ lock with bounded, no-follow, single-link readers. It re-checks status and reads
205
+ the report or snapshot history inside the lock using those same readers.
206
+ Completion Reports are used only when the source Run is terminal under the lock;
207
+ otherwise resume falls back to an atomic Snapshot digest. Prompt and report text are untrusted data, not
208
+ Delegate instructions, and are disclosed to the target Harness as part of the
209
+ continuation. `prompt.txt` is verbatim, unredacted, child-tamperable, retained
210
+ until `delegate runs prune`, and an `--engine` override can disclose it to a
211
+ different provider. A persistent-worktree resume attaches to the existing path
212
+ by deriving and validating its Registry record; it does not weaken
213
+ safe/worktree path checks or create a replacement worktree when the original
214
+ has moved.
215
+
203
216
  ## Config and secret hygiene
204
217
 
205
218
  - Keep real config in `~/.delegate/config.json` or a private `DELEGATE_CONFIG` path. Repository-local `.delegate/config.json` is not loaded implicitly.
@@ -83,6 +83,25 @@ Delegate also creates a local branch named like:
83
83
  delegate/<label>-<short-run-id>
84
84
  ```
85
85
 
86
+ ### Resume attachment
87
+
88
+ To continue a terminal Run that used a persistent worktree, use the Run handle
89
+ rather than launching a second persistent worktree:
90
+
91
+ ```bash
92
+ delegate resume <alias-or-runId> "Continue the implementation and run the tests."
93
+ ```
94
+
95
+ The resumed Run attaches to the existing execution path and records an
96
+ attachment lease. It does not create a new branch, copy dirty files, or derive
97
+ a second persistent-worktree record. The lease is released when the attached
98
+ Run reaches a terminal state. Worktree removal, pruning, and registry repair
99
+ refuse or skip a path with a live attached Run; inspect or wait for that Run
100
+ before cleanup. A missing, moved, symlinked, unregistered, or branch-mismatched
101
+ source worktree is refused rather than recreated implicitly. `--include-dirty`
102
+ is rejected on attached resume because it only controls creation-time
103
+ synchronization; ordinary resume drops the flag with a note.
104
+
86
105
  ## Preflight requirements
87
106
 
88
107
  Persistent worktree work-mode runs require:
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "delegate-agent-cli"
7
- version = "0.23.0"
7
+ version = "0.24.0"
8
8
  description = "A tiny CLI for delegating bounded agent tasks across coding-agent runtimes."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -1,5 +1,5 @@
1
1
  """Delegate Agent CLI package."""
2
2
 
3
- VERSION = "0.23.0"
3
+ VERSION = "0.24.0"
4
4
 
5
5
  __all__ = ["VERSION"]
@@ -23,6 +23,7 @@ from delegate_agent import (
23
23
  profiles,
24
24
  reasoning,
25
25
  redaction,
26
+ resume_command,
26
27
  run_metadata,
27
28
  run_output_commands,
28
29
  run_registry,
@@ -79,7 +80,7 @@ from delegate_agent.errors import (
79
80
  EXIT_USAGE,
80
81
  DelegateError,
81
82
  )
82
- from delegate_agent.git_utils import capture_git_metadata # noqa: F401 # re-exported for tests
83
+ from delegate_agent.git_utils import capture_git_metadata # re-exported for tests
83
84
  from delegate_agent.isolation import ( # noqa: F401 # re-exported for tests
84
85
  IsolationContext,
85
86
  build_isolation_context,
@@ -100,6 +101,7 @@ from delegate_agent.prompt_transport import ( # noqa: F401 # CURSOR_PROMPT_RED
100
101
  )
101
102
  from delegate_agent.request_build import ( # noqa: F401 # re-exported for tests / back-compat
102
103
  CALL_TEMP_CWD_PLACEHOLDER,
104
+ INLINE_OUTPUT_SCHEMA_PLACEHOLDER,
103
105
  RUN_INPUT_KEYS,
104
106
  _load_input_json_object,
105
107
  build_request,
@@ -306,16 +308,28 @@ def dry_run_payload(request: Request) -> JsonObject:
306
308
  run_metadata.add_model_payload_fields(payload, request)
307
309
  reasoning.add_reasoning_payload_fields(payload, request)
308
310
  run_metadata.add_speed_payload_fields(payload, request)
311
+ if request.output_schema_text is not None:
312
+ payload["outputSchemaInline"] = True
313
+ payload["argv"] = [
314
+ "<inline output schema>" if value == INLINE_OUTPUT_SCHEMA_PLACEHOLDER else value
315
+ for value in payload["argv"]
316
+ ]
309
317
  if request.warnings:
310
318
  payload["warnings"] = list(request.warnings)
311
319
  if request.progress:
312
320
  payload["progressRequested"] = True
321
+ if request.timeout is not None:
322
+ payload["timeoutSeconds"] = request.timeout
313
323
  if request.forbid_commit:
314
324
  payload["commitPolicy"] = {"forbidCommit": True}
315
325
  if request.include_dirty:
316
326
  payload["includeDirty"] = True
317
327
  if request.group is not None:
318
328
  payload["group"] = request.group
329
+ if request.agent is not None:
330
+ payload["agent"] = request.agent
331
+ if request.resumed_from is not None:
332
+ payload["resumedFrom"] = request.resumed_from
319
333
  if request.auth_profile is not None:
320
334
  payload["authProfile"] = request.auth_profile
321
335
  if request.fallback_auth_profile is not None:
@@ -329,6 +343,8 @@ def dry_run_payload(request: Request) -> JsonObject:
329
343
  # Keep the existing human-readable `isolation` note for legacy use.
330
344
  if ctx.effective_isolation == "worktree" and ctx.isolation_lifecycle == "persistent":
331
345
  payload["isolation"] = "worktree persistent"
346
+ elif ctx.effective_isolation == "worktree" and ctx.isolation_lifecycle == "attached":
347
+ payload["isolation"] = "worktree attached (resume)"
332
348
  elif ctx.effective_isolation == "worktree":
333
349
  payload["isolation"] = "worktree temporary"
334
350
  elif ctx.effective_isolation == "none":
@@ -344,7 +360,7 @@ def dry_run_payload(request: Request) -> JsonObject:
344
360
  # Only persistent worktree isolation has a planned Delegate-managed
345
361
  # branch/path. Temporary safe-mode isolation is created ephemerally at
346
362
  # execution time and must not claim a persistent worktree plan.
347
- if ctx.isolation_lifecycle == "persistent":
363
+ if ctx.isolation_lifecycle in ("persistent", "attached"):
348
364
  planned_cwd = ctx.planned_execution_cwd or "<planned-worktree-path>"
349
365
  planned_branch = ctx.planned_branch or "<planned-branch>"
350
366
  payload["plannedExecutionCwd"] = planned_cwd
@@ -356,7 +372,11 @@ def dry_run_payload(request: Request) -> JsonObject:
356
372
  payload["plannedBranch"] = None
357
373
 
358
374
  # Always emit isolatedWorkspace as explicit boolean (mirrors preservedWorkspace).
359
- payload["isolatedWorkspace"] = ctx.isolation_lifecycle in ("temporary", "persistent")
375
+ payload["isolatedWorkspace"] = ctx.isolation_lifecycle in (
376
+ "temporary",
377
+ "persistent",
378
+ "attached",
379
+ )
360
380
  else:
361
381
  # Fallback when no isolation context is provided (e.g. direct build_request calls in tests).
362
382
  # Use embedded-default logic: safe local harnesses -> worktree temporary, others -> none.
@@ -498,10 +518,11 @@ def make_run_context(
498
518
  )
499
519
  execution_cwd = request.workspace
500
520
  # isolated_workspace must reflect the EFFECTIVE behavior, not the
501
- # mere presence of an isolation_context object. Only "temporary" or
502
- # "persistent" lifecycle means a physically separate execution workspace.
521
+ # mere presence of an isolation_context object. Only "temporary",
522
+ # "persistent", or "attached" lifecycle means a physically separate
523
+ # execution workspace.
503
524
  isolated_workspace = (
504
- request.isolation_context.isolation_lifecycle in ("temporary", "persistent")
525
+ request.isolation_context.isolation_lifecycle in ("temporary", "persistent", "attached")
505
526
  if request.isolation_context is not None
506
527
  else False
507
528
  )
@@ -575,6 +596,12 @@ def make_run_context(
575
596
  call_read_only=request.call_read_only or request.pure,
576
597
  pure=request.pure,
577
598
  prompt_instruction_mode=request.prompt_instruction_mode,
599
+ source_prompt=request.source_prompt,
600
+ progress_requested=request.progress_requested,
601
+ timeout_seconds=request.timeout,
602
+ output_schema_text=request.output_schema_record_text,
603
+ agent=request.agent,
604
+ resumed_from=request.resumed_from,
578
605
  )
579
606
 
580
607
 
@@ -626,6 +653,173 @@ def _preserve_call_artifacts(
626
653
  )
627
654
 
628
655
 
656
+ def _execute_attached_worktree(
657
+ request: Request,
658
+ json_mode: bool,
659
+ *,
660
+ config: JsonObject,
661
+ config_source: str | None,
662
+ completion_report_mode: str,
663
+ source_workspace: ResolvedWorkspace,
664
+ stdout: TextIO,
665
+ stderr: TextIO,
666
+ ) -> tuple[int, JsonObject | None]:
667
+ """Launch a resumed child inside the source run's existing worktree.
668
+
669
+ Lease-by-derivation: the attachment is recorded in this run's manifest
670
+ (``worktreeAttachment``) and removal paths refuse while the run is
671
+ effectively running. No worktree record is derived for attached runs.
672
+ """
673
+ from dataclasses import replace as dc_replace
674
+
675
+ iso = request.isolation_context
676
+ assert iso is not None and iso.isolation_lifecycle == "attached"
677
+ worktree_path = iso.planned_execution_cwd
678
+ if not worktree_path:
679
+ raise DelegateError("worktree_missing", "Attached execution has no worktree path.")
680
+ wt = Path(worktree_path)
681
+ if wt.is_symlink() or not wt.is_dir():
682
+ raise DelegateError(
683
+ "worktree_missing",
684
+ f"The source run's worktree path is no longer a directory: {worktree_path}",
685
+ )
686
+
687
+ head_probe = capture_git_metadata(worktree_path)
688
+ start_head_oid = head_probe[2]
689
+ if not start_head_oid:
690
+ raise DelegateError(
691
+ "worktree_missing",
692
+ f"Could not resolve HEAD in the attached worktree: {worktree_path}",
693
+ )
694
+
695
+ execution_request = worktree_execution._request_for_execution_workspace(request, worktree_path)
696
+ # Re-check the actual argv payload now that the worktree note (and any
697
+ # forbid-commit note) has been prepended.
698
+ resume_command.enforce_resume_prompt_size(
699
+ request.engine,
700
+ execution_request.argv[-1],
701
+ )
702
+ ensure_binary(
703
+ execution_request.argv,
704
+ engine=request.engine,
705
+ config_source=config_source,
706
+ env_overrides=request.env_overrides,
707
+ )
708
+ if request.engine == "codex":
709
+ profiles.preflight_codex_request(request, config.get("codex", {}))
710
+
711
+ registry_root = run_registry.ensure_registry(
712
+ Path(source_workspace.path),
713
+ workspace_kind=source_workspace.kind,
714
+ )
715
+ maybe_run_retention_pass(registry_root, config)
716
+ run_id, alias = run_registry.register_run(
717
+ registry_root,
718
+ harness=request.engine,
719
+ metadata={
720
+ "mode": request.mode,
721
+ "model": request.model,
722
+ "modelAlias": request.model_alias,
723
+ "modelResolved": request.model,
724
+ "group": request.group,
725
+ "workflowAgentKey": request.workflow_agent_key,
726
+ "cwd": source_workspace.path,
727
+ "worktreeAttachment": {
728
+ **(iso.attachment or {}),
729
+ "startHeadOid": start_head_oid,
730
+ },
731
+ },
732
+ )
733
+ ctx_runner = make_run_context(
734
+ registry_root,
735
+ request,
736
+ run_id=run_id,
737
+ alias=alias,
738
+ source_workspace=source_workspace,
739
+ )
740
+ attachment = {
741
+ **(iso.attachment or {}),
742
+ "startHeadOid": start_head_oid,
743
+ }
744
+ ctx_runner = dc_replace(
745
+ ctx_runner,
746
+ execution_cwd=worktree_path,
747
+ isolated_workspace=True,
748
+ branch=iso.planned_branch,
749
+ source_git_root=iso.source_git_root,
750
+ creation_context={"sourceHeadOid": start_head_oid},
751
+ worktree_attachment=attachment,
752
+ )
753
+ try:
754
+ resume_command.revalidate_attached_target(
755
+ registry_root, attachment, expected_branch=iso.planned_branch
756
+ )
757
+ except DelegateError as exc:
758
+ run_path = run_registry.run_directory(registry_root, run_id)
759
+ if ctx_runner.source_prompt is not None:
760
+ run_registry.write_private_text(
761
+ run_path / run_registry.PROMPT_TXT_FILE, ctx_runner.source_prompt
762
+ )
763
+ delegate_runner.write_manifest(
764
+ run_path,
765
+ delegate_runner.build_manifest(ctx_runner, execution_request.display_argv),
766
+ )
767
+ delegate_runner.write_state(
768
+ run_path,
769
+ delegate_runner.build_state(
770
+ ctx_runner,
771
+ status=run_registry.STATUS_FAILED,
772
+ exit_code=1,
773
+ extra={
774
+ "error": "worktree_missing",
775
+ "message": exc.message,
776
+ "failureReason": "worktree_missing",
777
+ },
778
+ ),
779
+ )
780
+ raise DelegateError("worktree_missing", exc.message) from exc
781
+ execution_root = str(Path(worktree_path).resolve(strict=False))
782
+ source_root = str(Path(source_workspace.path).resolve(strict=False))
783
+ child_env = {
784
+ **(request.env_overrides or {}),
785
+ "DELEGATE_SOURCE_ROOT": source_root,
786
+ "DELEGATE_EXECUTION_ROOT": execution_root,
787
+ "WORKSPACE_ROOT": execution_root,
788
+ }
789
+ ctx_runner = dc_replace(
790
+ ctx_runner,
791
+ env_overrides=child_env,
792
+ fallback_env_overrides=profiles.codex_fallback_child_env_overrides(
793
+ request.profile_resolution,
794
+ child_env,
795
+ ),
796
+ )
797
+ try:
798
+ return delegate_runner.execute_tracked(
799
+ execution_request.argv,
800
+ worktree_path,
801
+ ctx_runner,
802
+ json_mode=json_mode,
803
+ stdout=stdout,
804
+ stderr=stderr,
805
+ completion_report_mode=completion_report_mode,
806
+ stdin_text=execution_request.stdin_text,
807
+ prompt_file_text=execution_request.prompt_file_text,
808
+ prompt_file_placeholder=PROMPT_FILE_ARG_PLACEHOLDER,
809
+ agent_config_text=execution_request.agent_config_text,
810
+ agent_config_placeholder=DEVIN_AGENT_CONFIG_ARG_PLACEHOLDER,
811
+ output_schema_text=request.output_schema_text,
812
+ output_schema_path=request.output_schema,
813
+ manifest_argv=execution_request.display_argv,
814
+ progress=request.progress,
815
+ progress_initial_delay_sec=request.progress_initial_delay_sec,
816
+ progress_interval_sec=request.progress_interval_sec,
817
+ timeout=request.timeout,
818
+ )
819
+ except delegate_runner.RunnerLaunchError as exc:
820
+ raise DelegateError(exc.error, exc.message, exc.exit_code) from exc
821
+
822
+
629
823
  def execute_request(
630
824
  request: Request,
631
825
  json_mode: bool,
@@ -849,6 +1043,21 @@ def execute_request(
849
1043
  profiles.preflight_codex_request(request, config.get("codex", {}))
850
1044
  ctx = request.isolation_context
851
1045
 
1046
+ # Attached resume runs execute inside an existing persistent worktree:
1047
+ # never plan, create, or sync a worktree — short-circuit before the
1048
+ # persistent branch.
1049
+ if ctx is not None and ctx.isolation_lifecycle == "attached":
1050
+ return _execute_attached_worktree(
1051
+ request,
1052
+ json_mode,
1053
+ config=config,
1054
+ config_source=config_source,
1055
+ completion_report_mode=completion_report_mode,
1056
+ source_workspace=source_workspace,
1057
+ stdout=stdout,
1058
+ stderr=stderr,
1059
+ )
1060
+
852
1061
  # Persistent worktree runs (work + worktree) hand off to worktree_execution.
853
1062
  if ctx is not None and ctx.isolation_lifecycle == "persistent":
854
1063
  try:
@@ -875,6 +1084,10 @@ def execute_request(
875
1084
 
876
1085
  with safe_isolated_request(request) as isolated_request:
877
1086
  _set_child_root_env(isolated_request, source_workspace)
1087
+ if isolated_request.resumed_from is not None and isolated_request.argv:
1088
+ resume_command.enforce_resume_prompt_size(
1089
+ isolated_request.engine, isolated_request.argv[-1]
1090
+ )
878
1091
  ensure_binary(
879
1092
  isolated_request.argv,
880
1093
  engine=isolated_request.engine,
@@ -1205,7 +1418,16 @@ def main(
1205
1418
  if parsed.subcommand == "profiles":
1206
1419
  return emit_profiles_command(parsed, config, source, stdout)
1207
1420
 
1421
+ resume_plan: resume_command.ResumePlan | None = None
1422
+ if parsed.subcommand == "resume":
1423
+ resume_plan = resume_command.build_resume_plan(parsed, workspace, config, stderr=stderr)
1424
+ # The plan is a fully ordinary launch; from here on the resume flows
1425
+ # through the normal request build and execution path.
1426
+ parsed = resume_plan.parsed
1427
+ global_options = parsed.global_options
1208
1428
  request = request_from_parsed(parsed, config, stdin)
1429
+ if resume_plan is not None:
1430
+ request = resume_command.apply_resume_to_request(request, resume_plan)
1209
1431
  if request.dry_run:
1210
1432
  payload = dry_run_payload(request)
1211
1433
  if global_options.json_mode: