1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// SPDX-License-Identifier: Apache-2.0
//! Thread command definitions.
use clap::{Args, Subcommand};
use super::{
ThreadAbsorbArgs, ThreadApprovalsArgs, ThreadApproveArgs, ThreadCapturesArgs,
ThreadCheckMergeArgs, ThreadDropArgs, ThreadMoveArgs, ThreadNameArgs, ThreadPromoteArgs,
ThreadRenameArgs, ThreadResolveArgs, ThreadRevokeApprovalArgs, ThreadShowArgs,
};
#[derive(Subcommand, Clone)]
pub enum ThreadCommands {
/// Create a thread ref at the current state.
Create {
/// Thread identifier.
name: String,
/// Mark the thread ephemeral. Auto-collapses after `--ttl` if not
/// promoted. The collapse is recorded as
/// `OpRecord::EphemeralThreadCollapse`; underlying states stay
/// addressable. (W1/A13.)
#[arg(long)]
ephemeral: bool,
/// TTL in seconds. Defaults to 24h when `--ephemeral` is set
/// without `--ttl`.
#[arg(long, requires = "ephemeral")]
ttl_secs: Option<u32>,
},
/// Switch the current checkout to an existing thread ref.
Switch {
/// Thread identifier.
name: String,
},
/// List threads.
List(ThreadListArgs),
/// Show one thread with actor and workflow context.
Show(ThreadShowArgs),
/// Show granular captures on a thread.
Captures(ThreadCapturesArgs),
/// Rename a thread ref.
Rename(ThreadRenameArgs),
/// Refresh a thread onto its target thread.
Refresh(ThreadNameArgs),
/// Move selected captured paths from one thread into another.
Move(ThreadMoveArgs),
/// Absorb a child thread into its parent or another thread.
Absorb(ThreadAbsorbArgs),
/// Guide a blocked or stale thread toward its next clean state.
Resolve(ThreadResolveArgs),
/// Promote a thread to a heavy checkout at a chosen path.
Promote(ThreadPromoteArgs),
/// Drop a thread and mark it abandoned.
Drop(ThreadDropArgs),
/// Record a merge approval for `<source> -> <target>`.
Approve(ThreadApproveArgs),
/// List approvals recorded for `<source> -> <target>`.
Approvals(ThreadApprovalsArgs),
/// Revoke a previously recorded approval by id.
RevokeApproval(ThreadRevokeApprovalArgs),
/// Check whether `<source> -> <target>` would merge under
/// the repo's branch-protection policies. Read-only.
CheckMerge(ThreadCheckMergeArgs),
/// Sweep threads that have outlived their usefulness — drop their
/// checkouts and registry entries to reclaim disk and de-clutter
/// `heddle thread list`.
///
/// Two modes are supported:
/// * `--merged`: drop threads in [`ThreadState::Merged`].
/// * `--auto --older-than <duration>`: drop harness-created
/// threads that have not been touched in the given duration.
///
/// The two flags can be combined to sweep both classes in one
/// invocation. Pair with `--dry-run` to preview the work without
/// changing anything on disk.
Cleanup(ThreadCleanupArgs),
}
/// Arguments for `heddle thread list`.
///
/// The default view hides harness-auto-created threads (those marked
/// with `auto: true` on disk). Pass `--include-auto` to surface them.
#[derive(Args, Clone, Debug, Default)]
pub struct ThreadListArgs {
/// Include threads created automatically by harness integrations
/// (e.g. Claude Code segment-rotation). Hidden by default to keep
/// the view focused on threads the user explicitly created.
#[arg(long)]
pub include_auto: bool,
}
/// Arguments for `heddle thread cleanup`.
///
/// At least one of `--merged` or `--auto` must be set; otherwise the
/// command refuses with a clear message. `--older-than` is required
/// when `--auto` is set.
#[derive(Args, Clone, Debug)]
pub struct ThreadCleanupArgs {
/// Drop threads whose recorded state is `merged`. Their checkouts
/// and registry entries are removed; the underlying ref and
/// states remain addressable.
#[arg(long)]
pub merged: bool,
/// Drop harness-auto-created threads (those tagged `auto: true`).
/// Combine with `--older-than` to gate the sweep on staleness.
#[arg(long)]
pub auto: bool,
/// Maximum age (since `updated_at`) for an auto-thread to be
/// considered live. Threads older than this are eligible for
/// sweep when `--auto` is set. Accepts a Go-style duration like
/// `7d`, `24h`, `30m`, `15s` (or a raw integer interpreted as
/// seconds).
#[arg(long, value_name = "DURATION")]
pub older_than: Option<String>,
/// Print what would be dropped without actually dropping it.
#[arg(long)]
pub dry_run: bool,
}