delegate-agent-cli 0.20.0__tar.gz → 0.21.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.
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/CHANGELOG.md +118 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/PKG-INFO +1 -1
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/docs/cli-reference.md +28 -2
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/docs/worktrees.md +22 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/pyproject.toml +1 -1
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/__init__.py +1 -1
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/capability_commands.py +20 -2
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/cli.py +2 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/cli_parser.py +4 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/command_help.py +19 -2
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/harness_discovery.py +268 -33
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/isolation.py +128 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/private_io.py +23 -5
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/redaction.py +33 -1
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/rendering.py +39 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/request_build.py +243 -43
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/setup_commands.py +26 -4
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/worktree_commands.py +22 -4
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/worktree_execution.py +7 -15
- delegate_agent_cli-0.21.0/src/delegate_agent/worktree_gc.py +1129 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/worktree_mgmt.py +8 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent_cli.egg-info/PKG-INFO +1 -1
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_capability_commands.py +70 -2
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_engine_argv.py +461 -1
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_execution_worktree_run.py +21 -2
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_harness_discovery.py +474 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_setup_commands.py +27 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_snapshot_redaction.py +14 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_worktree_prune_gc.py +1032 -1
- delegate_agent_cli-0.20.0/src/delegate_agent/worktree_gc.py +0 -577
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/CONTRIBUTING.md +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/LICENSE +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/MANIFEST.in +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/README.md +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/SECURITY.md +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/bin/delegate-profile-shim +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/bin/delegate.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/config.example.json +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/docs/agent-setup.md +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/docs/assets/delegate-agent-header.png +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/docs/configuration.md +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/docs/delegate-workflows.md +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/docs/development.md +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/docs/live-runtime.md +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/docs/publishing-checklist.md +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/docs/security-model.md +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/docs/troubleshooting.md +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/examples/task.claude.json +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/examples/task.codex.json +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/examples/task.cursor.json +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/examples/task.droid.json +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/examples/task.grok.json +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/examples/task.judge.json +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/examples/task.kimi.json +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/setup.cfg +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/archived_logs.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/argv_builders.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/argv_utils.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/bundled_models.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/child_failures.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/command_errors.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/config.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/config_commands.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/constants.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/describe_payload.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/errors.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/git_utils.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/harness_events.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/inspection_commands.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/json_types.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/log_output.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/model_discovery.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/profile_commands.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/profile_guard.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/profiles.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/prompt_instructions.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/prompt_transport.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/reasoning.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/request_models.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/retention.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/run_metadata.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/run_output_commands.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/run_registry.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/run_status.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/runner.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/safe_workspace.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/seatbelt.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/snapshot_view.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/structured_output.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/wait_cancel_commands.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/workflows/__init__.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/workflows/commands.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/workflows/registry.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/workflows/runtime.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/workflows/schema.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/workflows/script.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/worktree_records.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/worktree_remove.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/worktree_summary.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/wsl.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent_cli.egg-info/SOURCES.txt +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent_cli.egg-info/dependency_links.txt +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent_cli.egg-info/entry_points.txt +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent_cli.egg-info/requires.txt +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent_cli.egg-info/top_level.txt +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_child_failures.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_codex_pure_sandbox.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_codex_thread_resilience.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_command_help.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_config_commands.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_delegate_help_cli.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_delegate_isolation.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_delegate_parser.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_delegate_validation.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_end_to_end_tracking.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_execution_argv_and_prompt.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_execution_dry_run.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_execution_worktree_failure_cleanup.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_execution_worktree_preflight.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_harness_events.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_inspection_commands.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_kimi_commands.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_model_discovery.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_model_selection_wave1a.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_model_selection_wave1b.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_omp_read_only_behavior.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_packaging.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_profiles.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_pure_call.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_reasoning_capabilities.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_retention.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_run_registry.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_runner_capture.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_safe_workspace_isolation.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_slash_passthrough.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_snapshot_rendering.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_snapshot_run_output.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_snapshot_view.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_structured_output.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_tracked_timeout.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_utility_modules.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_wait_cancel_commands.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_wave4_launch_features.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_workflow_commands.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_worktree_list_show.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_worktree_remove.py +0 -0
- {delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/tests/test_wsl_guardrails.py +0 -0
|
@@ -5,6 +5,123 @@ 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.21.0] - 2026-07-26
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Added `delegate worktree gc --all`, which scans the machine-wide worktree
|
|
13
|
+
pool for worktrees whose source repository no longer exists. Such worktrees
|
|
14
|
+
were previously unreachable by any `gc` invocation, because reaping is driven
|
|
15
|
+
by the run registry inside each source repository and that registry dies with
|
|
16
|
+
the repository. The scan adds no catalog or persistent state: it reads each
|
|
17
|
+
worktree's Git backlink directly, and treats a backlink whose target is gone
|
|
18
|
+
as the sole orphan signal. The scan removes nothing at all, at any depth: a
|
|
19
|
+
missing source repository makes a worktree's uncommitted state impossible to
|
|
20
|
+
inspect, so orphans and empty pool directories alike are reported for
|
|
21
|
+
deliberate manual cleanup. Because that output invites manual deletion, every
|
|
22
|
+
uncertainty resolves away from an orphan verdict: a pointer file that cannot
|
|
23
|
+
be read, a path comparison the filesystem cannot answer, an entry too recently
|
|
24
|
+
modified to have settled, and a directory whose name does not match the pool's
|
|
25
|
+
own fingerprint contract are all reported as warnings rather than orphans.
|
|
26
|
+
That last rule is what keeps a scan of an arbitrary root from labelling
|
|
27
|
+
somebody else's directories. `--pool PATH` scans a different pool root, which
|
|
28
|
+
reaches pools stranded by an earlier `worktrees.dataHome`.
|
|
29
|
+
- `capabilities refresh` and `setup` now name each harness on stderr as it is
|
|
30
|
+
probed, so a harness that hangs is identifiable rather than anonymous
|
|
31
|
+
silence. Progress output is suppressed under `--json`.
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- A launch now fails instead of proceeding when the configured binary for a
|
|
36
|
+
harness identifies itself as a *different* known harness. Delegate re-probes
|
|
37
|
+
`--version` when a cached capability record has refused a run, and during
|
|
38
|
+
`capabilities refresh` and `setup` (see Fixed); when that banner positively
|
|
39
|
+
names another harness — a Codex path replaced in place by Grok, say — the run
|
|
40
|
+
stops with `harness_identity_mismatch` and exit code 2, naming the configured
|
|
41
|
+
harness, the harness that answered, and the selector path.
|
|
42
|
+
Previously the launch continued against that same binary with the same Codex
|
|
43
|
+
argv, sandbox flags, and approval policy, and only the cached capability
|
|
44
|
+
metadata was discarded. This fires solely on a banner that NAMES another known
|
|
45
|
+
harness, never on uncertainty: a probe that errors, times out, exceeds its
|
|
46
|
+
output bound, or prints an unbranded banner still fails open and launches on
|
|
47
|
+
the cached record. An unbranded shape — a bare date-and-hash build ID is the
|
|
48
|
+
clearest case — is deliberately not identification, because wrapper prefixes
|
|
49
|
+
are a supported configuration and refusing a legitimate launch costs more than
|
|
50
|
+
carrying a stale record until the next refresh. The selector is scrubbed of
|
|
51
|
+
credentials before it reaches the message or the diagnostics, since a wrapper
|
|
52
|
+
prefix can carry a token inline or after a flag. Dry runs do not probe and are
|
|
53
|
+
unaffected. The refusal also names the discovery cache file for the active
|
|
54
|
+
auth profile, in its `cachePath` diagnostic and in a next action, because
|
|
55
|
+
`capabilities refresh` cannot clear this state: a refresh keeps the
|
|
56
|
+
last-known-good record whenever a probe fails, which is correct for a flaky
|
|
57
|
+
probe and wrong here, where the record itself is the problem. Without the
|
|
58
|
+
path, a wrong identification would refuse every launch with no documented way
|
|
59
|
+
out short of editing configuration.
|
|
60
|
+
- A run whose cached capability record is discarded for version drift now says
|
|
61
|
+
so, naming `delegate capabilities refresh <engine>`. The record is dropped for
|
|
62
|
+
that run only and the superseded copy stays on disk, so every later launch
|
|
63
|
+
repeats the drop and loses the same discovery-sourced models and reasoning
|
|
64
|
+
levels — previously with no indication that a stale cache was the cause.
|
|
65
|
+
Selector drift stays silent, since `capabilities` already reports it under
|
|
66
|
+
`driftedHarnesses`.
|
|
67
|
+
|
|
68
|
+
### Fixed
|
|
69
|
+
|
|
70
|
+
- Discovery now detects a harness that was upgraded in place. Cached capability
|
|
71
|
+
records were invalidated only by comparing the configured selector, so an
|
|
72
|
+
upgrade behind an unchanged selector left stale capabilities cached
|
|
73
|
+
indefinitely and a newly supported reasoning level was rejected until a manual
|
|
74
|
+
`capabilities refresh`. Delegate now re-probes `--version` for the single
|
|
75
|
+
harness it is about to use and compares it against the version already stored
|
|
76
|
+
in the record, then rebuilds the run against the refreshed picture. The probe
|
|
77
|
+
runs only once the cached record has already cost the run something, never on
|
|
78
|
+
the ordinary path, which therefore spawns no extra process at all — and that
|
|
79
|
+
matters because the probe costs 26-668ms, worst on the Node and Bun harnesses
|
|
80
|
+
that are already slow to start. Two things trigger it: an explicit
|
|
81
|
+
`--reasoning-effort` the record refuses, and a `defaultReasoningEffort` the
|
|
82
|
+
record silently drops. The second is the one most likely to go unnoticed,
|
|
83
|
+
since a configured default degrades to a warning rather than failing the
|
|
84
|
+
launch, and it is set once and then never typed again. A probe that cannot
|
|
85
|
+
repair the default leaves the run exactly as it was: a launch that succeeded
|
|
86
|
+
is never turned into a failure. The check fails open — a probe that errors,
|
|
87
|
+
times out, or prints a banner nothing recognizes keeps the cached record, so a
|
|
88
|
+
failing probe can never prevent a launch. A banner that positively identifies
|
|
89
|
+
a *different* known harness is the exception, and it aborts the launch rather
|
|
90
|
+
than merely invalidating the record — see Changed. Each banner is matched
|
|
91
|
+
against the expected harness's own pattern before anyone else's, so a banner
|
|
92
|
+
mentioning more than one tool is read as the harness that was asked for
|
|
93
|
+
instead of whichever pattern happens to be declared earlier. Banners are read
|
|
94
|
+
with escape sequences stripped, so a colorized version line no longer freezes
|
|
95
|
+
a record permanently. A cached selector whose binary no longer exists is also
|
|
96
|
+
treated as drift.
|
|
97
|
+
- Not covered, deliberately: a harness that *removes* a capability leaves its
|
|
98
|
+
cached record listing more than the harness now supports, which produces no
|
|
99
|
+
refusal and so no probe. The child rejects the effort it was handed, which is
|
|
100
|
+
loud; the one quiet case is Cursor's route table aiming a run at a superseded
|
|
101
|
+
model id. Catching either would cost a probe on every launch, which is the
|
|
102
|
+
trade this path exists to refuse. `capabilities refresh` remains the cure.
|
|
103
|
+
- A dry run never probes the harness for its version. Dry run documents that it
|
|
104
|
+
neither launches a child runtime nor requires the real child binary, and the
|
|
105
|
+
drift probe is a child runtime; it now runs only on a real launch, leaving dry
|
|
106
|
+
run with the two filesystem-local checks.
|
|
107
|
+
- A discovery cache carrying a newer schema than the running build is no longer
|
|
108
|
+
discarded and overwritten. It is left intact while the run degrades to
|
|
109
|
+
probing without persisting, so an older Delegate can no longer destroy a newer
|
|
110
|
+
cache. Losing that race mid-probe degrades the same way rather than failing the
|
|
111
|
+
command: `capabilities refresh` and `setup` both report `cacheWriteSkipped`,
|
|
112
|
+
`setup` additionally leaving `cacheState` at `unchanged`, and each exits
|
|
113
|
+
successfully, since only persistence was lost. The
|
|
114
|
+
schema is re-read immediately before the atomic replacement rather than before
|
|
115
|
+
the snapshot is serialized, which narrows the window in which a newer cache
|
|
116
|
+
could be published and then overwritten down to the `os.replace` call itself.
|
|
117
|
+
POSIX offers no compare-and-swap for a rename, so that last window remains.
|
|
118
|
+
- The test suite no longer writes into the developer's real
|
|
119
|
+
`~/.delegate/worktrees`. Tests exercising persistent-worktree runs created
|
|
120
|
+
real pooled worktrees over temporary source repositories and orphaned them
|
|
121
|
+
permanently, because `worktrees_data_home` falls through to the user's home
|
|
122
|
+
directory with no seam a test could redirect. `HOME` is now redirected at test
|
|
123
|
+
collection time, which reaches every such resolver at once.
|
|
124
|
+
|
|
8
125
|
## [0.20.0] - 2026-07-25
|
|
9
126
|
|
|
10
127
|
### Added
|
|
@@ -631,6 +748,7 @@ Usage-audit fix wave: 82 sessions and 1,241 delegate invocations from one week o
|
|
|
631
748
|
|
|
632
749
|
- Releases before 0.1.3 predate this changelog.
|
|
633
750
|
|
|
751
|
+
[0.21.0]: https://github.com/treygoff24/delegate-agent/compare/v0.20.0...v0.21.0
|
|
634
752
|
[0.20.0]: https://github.com/treygoff24/delegate-agent/compare/v0.19.0...v0.20.0
|
|
635
753
|
[0.19.0]: https://github.com/treygoff24/delegate-agent/compare/v0.18.0...v0.19.0
|
|
636
754
|
[0.18.0]: https://github.com/treygoff24/delegate-agent/compare/v0.17.0...v0.18.0
|
|
@@ -803,7 +803,31 @@ records independently. If one current probe fails, its last-known-good record
|
|
|
803
803
|
is retained and the refresh response lists that harness in `staleHarnesses`.
|
|
804
804
|
If the configured executable selector changes, cached reads mark that harness
|
|
805
805
|
stale and ordinary launches ignore only that harness's record until refresh.
|
|
806
|
-
Cached reads never run `--version` merely to test staleness
|
|
806
|
+
Cached reads never run `--version` merely to test staleness, and neither does an
|
|
807
|
+
ordinary launch: a cached record can only be short of what the harness now
|
|
808
|
+
supports, never claim more, so one that satisfies the run is used as-is.
|
|
809
|
+
|
|
810
|
+
A launch re-probes `--version` for its own harness only when the cached record
|
|
811
|
+
has already cost the run something: it refused an explicit `--reasoning-effort`,
|
|
812
|
+
or it silently dropped a configured `defaultReasoningEffort` (a configured
|
|
813
|
+
default degrades to a warning instead of failing the launch, so nothing else
|
|
814
|
+
would signal it). An in-place upgrade behind an unchanged selector is the reason
|
|
815
|
+
either can be wrong, so the probe compares the live banner against the version
|
|
816
|
+
stored in the record, and a mismatch drops the record and rebuilds the run
|
|
817
|
+
against config and bundled capabilities. If the refreshed picture cannot satisfy
|
|
818
|
+
a configured default either, the run proceeds as it already had — a probe never
|
|
819
|
+
turns a launch that succeeded into one that fails.
|
|
820
|
+
|
|
821
|
+
The reverse case is not covered: a harness that *removes* a capability leaves
|
|
822
|
+
its record listing more than the harness now supports, which produces no refusal
|
|
823
|
+
and therefore no probe. Run `capabilities refresh` after an upgrade that narrows
|
|
824
|
+
what a harness accepts. The result carries a warning naming
|
|
825
|
+
`capabilities refresh <engine>`, because the superseded record stays on disk
|
|
826
|
+
until a refresh rewrites it. The probe fails open — an error, a timeout, or an
|
|
827
|
+
unrecognized banner leaves the original refusal standing — except when the
|
|
828
|
+
banner positively names a *different* known harness, which fails the run with
|
|
829
|
+
`harness_identity_mismatch` rather than handing one harness's argv and sandbox
|
|
830
|
+
policy to another. Dry runs never probe at all.
|
|
807
831
|
|
|
808
832
|
All automatic probes run with `shell=False`, stdin closed, a neutral temporary
|
|
809
833
|
working directory, bounded output, and a timeout. They pass the active profile
|
|
@@ -1079,11 +1103,13 @@ delegate worktree show <handle>
|
|
|
1079
1103
|
delegate worktree show --latest HARNESS
|
|
1080
1104
|
delegate worktree remove <handle|--group NAME> [--discard-uncommitted] [--force-branch] [--force] [--keep-branch]
|
|
1081
1105
|
delegate worktree prune [--merged] [--older-than DAYS] [--harness HARNESS] [--group NAME] [--include-detached] [--dry-run] [--discard-uncommitted] [--force-branch] [--force]
|
|
1082
|
-
delegate worktree gc [--dry-run]
|
|
1106
|
+
delegate worktree gc [--dry-run] [--all] [--pool PATH]
|
|
1083
1107
|
```
|
|
1084
1108
|
|
|
1085
1109
|
`worktree show --latest HARNESS` selects the latest persistent worktree for the harness, not merely the latest run overall. `worktree list` JSON includes a `summary` with status counts, registry drift counts, warning counts, `autoPruneMode`, and whether the returned operation was read-only; `summary.totalPersistentWorktrees` is always registry-wide, while `allStatusCounts` is scoped to the `--harness` / `--group` filters (pre-status-filter) and `statusCounts` to the visible entries. `worktree remove --group NAME` removes all matching persistent worktrees with the same safety checks as single-handle removal. `worktree prune --group NAME` limits prune candidates to the group. `worktree gc --dry-run` reports `wouldPruneSourceRoots` and structured orphan reasons; `worktree gc` JSON also includes `mode`, `effects`, per-entry `action`, and orphan `safeAction` fields. `gc` never deletes worktree directories.
|
|
1086
1110
|
|
|
1111
|
+
`worktree gc --all` additionally scans the machine-wide worktree pool (`worktrees.dataHome`, default `~/.delegate/worktrees`) and adds a `pool` object with `dataHome`, `scannedWorktrees`, `orphans`, `emptyFingerprintDirs`, and `warnings`. A pool orphan is a pooled worktree whose Git admin directory no longer serves it, classified `source_root_missing` or `worktree_metadata_missing` with the same `safeAction` vocabulary as registry orphans, plus `worktreePath`, `fingerprint`, `sourceGitRoot`, and `gitdir` (null when the backlink is absent). This is the only way to see worktrees whose source repository was deleted along with its `.delegate/` registry, so `--all` is accepted outside a Delegate registry. The pool scan removes nothing at all: orphans are reported because uncommitted work in them is undetectable once the source repository is gone, and empty fingerprint directories are reported for the same hand-clearing rather than reclaimed. Only a settled absence produces an orphan — metadata that could not be read (a symlinked, non-regular, oversized, or unreadable `.git` entry, or an admin directory that could not be inspected) is treated as live and reported in `pool.warnings`, and so is any pool entry modified within the last 15 minutes, since worktree creation writes the directory before its metadata and a concurrent scan would otherwise call a worktree being born an orphan (`worktree_unsettled`, `fingerprint_dir_unsettled`). `pool.warnings` also covers first-level directories whose names are not repository fingerprints, fingerprint directories that hold loose files rather than being empty, and unlistable fingerprint directories. `--pool PATH` scans a specific pool root instead of the configured one, which finds pools left behind by an earlier `worktrees.dataHome`; an explicit `--pool` path that is missing, not a directory, or unreadable is an `invalid_pool_root` error.
|
|
1112
|
+
|
|
1087
1113
|
List/show entry fields include `branchMergedIntoSource` (branch graph only), `mergedIntoSource` (backward-compatible branch graph state), `fullyIntegrated` (branch merged and worktree clean), `hasUncommittedChanges`, `integrationStatus`, and `uncommittedChangesIntegrated`. `workSummary` is included on `worktree show` and run completion payloads when Delegate can inspect the worktree; `worktree list` omits the deep summary for responsiveness. Consumers that need safe retirement should require `fullyIntegrated: true` or inspect `integrationStatus`. When `integrationStatus` is `branch-merged-worktree-dirty`, merge/cherry-pick suggestions are suppressed because commit integration is already complete and only uncommitted edits remain.
|
|
1088
1114
|
|
|
1089
1115
|
Unknown persistent-worktree handles return suggestions scoped to persistent
|
|
@@ -216,6 +216,28 @@ delegate worktree gc
|
|
|
216
216
|
|
|
217
217
|
In dry-run mode, `gc` reports `wouldPruneSourceRoots` and classifies un-prunable worktrees with reasons such as `source_root_missing`, `worktree_metadata_missing`, `branch_missing`, and `detached_backlink`. Without `--dry-run`, it may update Delegate registry status (for example, marking missing paths as `missing` or inconsistent metadata as `unknown`) and may run `git worktree prune` to clean Git administrative metadata for already-missing paths, but it does not delete worktree directories. JSON output includes an `effects` object that makes those mutation boundaries explicit.
|
|
218
218
|
|
|
219
|
+
## Find pooled worktrees whose repository is gone
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
delegate worktree gc --all
|
|
223
|
+
delegate worktree gc --all --dry-run
|
|
224
|
+
delegate worktree gc --pool ~/.delegate/worktrees
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Persistent worktrees live in a machine-global pool under `worktrees.dataHome` (default `~/.delegate/worktrees`), but they are tracked in a run registry inside the source repository. Delete the source repository and its registry goes with it, leaving a pooled worktree that no per-repository `gc` can reach. `--all` finds these by walking the pool directly and reading each worktree's `.git` backlink file as text — the ordinary Git-based checks cannot classify them, because every `git` command fails inside a worktree whose repository is gone. Because a live worktree always has a live backlink, the walk is safe to run across every repository on the machine at once. `--all` works outside a Delegate registry for the same reason.
|
|
228
|
+
|
|
229
|
+
The scan adds a `pool` object to the JSON with `dataHome`, `scannedWorktrees`, `orphans`, `emptyFingerprintDirs`, and `warnings`. Each orphan carries `worktreePath`, `fingerprint`, the recovered `sourceGitRoot` (null when the layout does not reveal it), `gitdir` (null when the worktree has no `.git` backlink), a `reason`, and a `safeAction`.
|
|
230
|
+
|
|
231
|
+
A worktree counts as an orphan only when two things are settled. Its `.git` backlink must be definitely gone or definitely unusable — absent, or readable and holding no usable `gitdir:` line. And its Git admin directory must no longer serve it: the admin directory must exist and hold a `gitdir` backfile naming this worktree. Anything that merely *could not be checked* — a `.git` entry that is a symlink, a directory, a FIFO, oversized, or unreadable; an admin directory that could not be inspected — is reported as live and surfaced in `warnings` with reason `worktree_metadata_unverifiable`. A false orphan invites someone to delete real work by hand, while a false live only under-reports, so every unresolved case resolves toward live.
|
|
232
|
+
|
|
233
|
+
Absence also has to have lasted. Creating a persistent worktree is several steps — Delegate makes the fingerprint directory, then `git worktree add` creates the worktree directory, its `.git` pointer, and the admin directory's backfile — and a scan that lands inside that window sees exactly what a deleted repository leaves behind. Since the scan runs in a different process from the one creating the worktree, and often for a different repository, it has nothing to wait on and judges by age instead: a pool entry modified within the last 15 minutes is reported in `warnings` (`worktree_unsettled`, or `fingerprint_dir_unsettled` for an empty directory) and classified on a later run. An entry whose age cannot be read at all is treated the same way. This delays reporting a genuine orphan by one run at most, since a real orphan's metadata never comes back.
|
|
234
|
+
|
|
235
|
+
Only first-level directories named like a repository fingerprint (12 lowercase hex characters, as written by `plan_worktree_path`) are treated as Delegate's. The root is whatever you passed, so anything else is skipped without being descended, and is summarized in `warnings` with reason `not_a_pool_fingerprint_dir` — pointing `--pool` at an ordinary directory yields warnings, never orphans or cleanup candidates.
|
|
236
|
+
|
|
237
|
+
The pool scan removes nothing. With the source repository gone there is no way to tell whether an orphan holds uncommitted work, so removal is a deliberate manual decision — inspect the reported path, rescue anything you need, then delete it yourself. Empty fingerprint directories, left behind when a fingerprint's last worktree was removed, are reported in `emptyFingerprintDirs` for the same hand-clearing; `gc` does not remove those either. "Empty" means the directory holds nothing at all: a fingerprint directory with loose files in it is reported in `warnings` (`fingerprint_dir_not_empty`) instead. Fingerprint directories that could not be listed also appear in `warnings` rather than being reported as empty.
|
|
238
|
+
|
|
239
|
+
Use `--pool PATH` to scan a pool root that is no longer the configured `dataHome`. An explicitly named `--pool` path must exist and be a readable directory; anything else is an `invalid_pool_root` error rather than a successful scan of nothing, including a root that becomes unreadable between validation and the walk. A configured `dataHome` that does not exist yet is not an error — it just means no pool has been created — and is reported in `pool.warnings`.
|
|
240
|
+
|
|
219
241
|
## Security boundary
|
|
220
242
|
|
|
221
243
|
Worktree isolation is source-checkout isolation, not a full sandbox. The child process may still use credentials, network access, external tools, and absolute paths according to its runtime and host permissions. See [Security model](security-model.md).
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "delegate-agent-cli"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.21.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"
|
{delegate_agent_cli-0.20.0 → delegate_agent_cli-0.21.0}/src/delegate_agent/capability_commands.py
RENAMED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from collections.abc import Callable
|
|
3
4
|
from dataclasses import dataclass
|
|
4
5
|
from pathlib import Path
|
|
5
6
|
from typing import TextIO
|
|
@@ -138,9 +139,12 @@ def _refresh_payload(
|
|
|
138
139
|
*,
|
|
139
140
|
profile: profiles.ProfileResolution,
|
|
140
141
|
engines: tuple[str, ...] | None = None,
|
|
142
|
+
progress: Callable[[str], None] | None = None,
|
|
141
143
|
) -> JsonObject:
|
|
142
144
|
try:
|
|
143
|
-
result = harness_discovery.refresh_discovery(
|
|
145
|
+
result = harness_discovery.refresh_discovery(
|
|
146
|
+
config, profile=profile, engines=engines, progress=progress
|
|
147
|
+
)
|
|
144
148
|
except OSError as exc:
|
|
145
149
|
raise CapabilitiesError(
|
|
146
150
|
"capability_refresh_failed",
|
|
@@ -215,6 +219,8 @@ def _refresh_payload(
|
|
|
215
219
|
}
|
|
216
220
|
if drifted_harnesses:
|
|
217
221
|
payload["driftedHarnesses"] = drifted_harnesses
|
|
222
|
+
if result.get("futureSchemaCache") is True:
|
|
223
|
+
payload["cacheWriteSkipped"] = harness_discovery.FUTURE_SCHEMA_CACHE_WARNING
|
|
218
224
|
_add_legacy_cache_fields(payload, legacy_path, reasoning_payload)
|
|
219
225
|
return redaction.scrub_public_projection(payload)
|
|
220
226
|
|
|
@@ -229,6 +235,7 @@ def emit(
|
|
|
229
235
|
profile: profiles.ProfileResolution | None = None,
|
|
230
236
|
discovery: JsonObject | None = None,
|
|
231
237
|
stdout: TextIO,
|
|
238
|
+
stderr: TextIO | None = None,
|
|
232
239
|
) -> int:
|
|
233
240
|
active_profile = profile or profiles.resolve_active_profile(
|
|
234
241
|
config,
|
|
@@ -236,8 +243,16 @@ def emit(
|
|
|
236
243
|
cli_override=auth_profile_override,
|
|
237
244
|
)
|
|
238
245
|
if command.refresh:
|
|
246
|
+
# JSON callers get a clean stdout document and a quiet stderr; the
|
|
247
|
+
# per-harness line exists for a human watching a cold refresh.
|
|
239
248
|
payload = _refresh_payload(
|
|
240
|
-
config,
|
|
249
|
+
config,
|
|
250
|
+
workspace,
|
|
251
|
+
profile=active_profile,
|
|
252
|
+
engines=command.engines,
|
|
253
|
+
progress=(
|
|
254
|
+
None if command.json_mode else harness_discovery.stderr_probe_progress(stderr)
|
|
255
|
+
),
|
|
241
256
|
)
|
|
242
257
|
else:
|
|
243
258
|
payload = capabilities_payload(
|
|
@@ -252,6 +267,9 @@ def emit(
|
|
|
252
267
|
delegate_rendering.print_json(payload, stdout)
|
|
253
268
|
else:
|
|
254
269
|
print(f"reasoning capabilities: {payload['cachePath']}", file=stdout)
|
|
270
|
+
skipped = payload.get("cacheWriteSkipped")
|
|
271
|
+
if isinstance(skipped, str):
|
|
272
|
+
print(skipped, file=stdout)
|
|
255
273
|
drifted = payload.get("driftedHarnesses")
|
|
256
274
|
if isinstance(drifted, list) and drifted:
|
|
257
275
|
print(
|
|
@@ -1087,6 +1087,7 @@ def main(
|
|
|
1087
1087
|
json_mode=global_options.json_mode,
|
|
1088
1088
|
auth_profile_override=global_options.auth_profile,
|
|
1089
1089
|
stdout=stdout,
|
|
1090
|
+
stderr=stderr,
|
|
1090
1091
|
)
|
|
1091
1092
|
|
|
1092
1093
|
# For run --input-json, pre-read the JSON to discover config from the
|
|
@@ -1177,6 +1178,7 @@ def main(
|
|
|
1177
1178
|
profile=discovery_profile,
|
|
1178
1179
|
discovery=discovery_snapshot,
|
|
1179
1180
|
stdout=stdout,
|
|
1181
|
+
stderr=stderr,
|
|
1180
1182
|
)
|
|
1181
1183
|
|
|
1182
1184
|
if parsed.subcommand in {
|
|
@@ -2013,6 +2013,8 @@ WORKTREE_OPTION_SPECS: dict[str, dict[str, WorktreeOptionSpec]] = {
|
|
|
2013
2013
|
},
|
|
2014
2014
|
"gc": {
|
|
2015
2015
|
"--dry-run": ("flag", "dry_run"),
|
|
2016
|
+
"--all": ("flag", "all_pools"),
|
|
2017
|
+
"--pool": ("str", "pool"),
|
|
2016
2018
|
},
|
|
2017
2019
|
}
|
|
2018
2020
|
|
|
@@ -2090,6 +2092,8 @@ def parse_worktree(rest: list[str], json_mode: bool, cwd: str | None) -> ParsedC
|
|
|
2090
2092
|
raise DelegateError(
|
|
2091
2093
|
"unexpected_argument", f"worktree {action} does not accept positional arguments."
|
|
2092
2094
|
)
|
|
2095
|
+
if action == "gc" and options.get("pool") == "":
|
|
2096
|
+
raise DelegateError("invalid_option_value", "worktree gc --pool requires a path.")
|
|
2093
2097
|
if action == "show":
|
|
2094
2098
|
if options.get("latest_harness") is not None:
|
|
2095
2099
|
if positional:
|
|
@@ -1408,19 +1408,36 @@ COMMAND_SPECS: dict[str, CommandSpec] = {
|
|
|
1408
1408
|
"worktree gc": CommandSpec(
|
|
1409
1409
|
name="worktree gc",
|
|
1410
1410
|
summary="Garbage-collect orphaned worktree metadata and stale registry entries.",
|
|
1411
|
-
usage=("delegate [--cwd PATH] [--json] worktree gc [--dry-run]",),
|
|
1411
|
+
usage=("delegate [--cwd PATH] [--json] worktree gc [--dry-run] [--all] [--pool PATH]",),
|
|
1412
1412
|
options=(
|
|
1413
1413
|
OptionSpec(
|
|
1414
1414
|
"--dry-run",
|
|
1415
1415
|
None,
|
|
1416
1416
|
"Report source roots that would be pruned and un-prunable worktree reasons without changing anything.",
|
|
1417
1417
|
),
|
|
1418
|
+
OptionSpec(
|
|
1419
|
+
"--all",
|
|
1420
|
+
None,
|
|
1421
|
+
"Also scan the machine-wide worktree pool for worktrees whose source repository is gone. Reports them; never removes them.",
|
|
1422
|
+
),
|
|
1423
|
+
OptionSpec(
|
|
1424
|
+
"--pool",
|
|
1425
|
+
"PATH",
|
|
1426
|
+
"Scan this worktree pool root instead of the configured worktrees.dataHome (finds pools left behind by an earlier dataHome). The path must exist and be a readable directory.",
|
|
1427
|
+
),
|
|
1418
1428
|
),
|
|
1419
1429
|
examples=(
|
|
1420
1430
|
"delegate worktree gc",
|
|
1421
1431
|
"delegate worktree gc --dry-run",
|
|
1432
|
+
"delegate worktree gc --all",
|
|
1433
|
+
"delegate worktree gc --all --dry-run",
|
|
1434
|
+
),
|
|
1435
|
+
notes=(
|
|
1436
|
+
"GC reconciles registry and Git metadata; it never removes worktree paths.",
|
|
1437
|
+
"--all works outside a Delegate registry, since pooled worktrees outlive the repositories that created them.",
|
|
1438
|
+
"Pool orphans are reported, never removed: their uncommitted state cannot be inspected once the source repository is gone.",
|
|
1439
|
+
"The pool scan removes nothing at all, including empty pool directories — it reports them so you can clear them yourself.",
|
|
1422
1440
|
),
|
|
1423
|
-
notes=("GC reconciles registry and Git metadata; it never removes worktree paths.",),
|
|
1424
1441
|
see_also=("worktree list", "worktree prune", "worktree remove"),
|
|
1425
1442
|
unsupported_global_options=("--isolation", "--auth-profile"),
|
|
1426
1443
|
),
|