Skip to main content

cli/cli/cli_args/
commands_main.rs

1// SPDX-License-Identifier: Apache-2.0
2//! Top-level CLI commands.
3
4use clap::Subcommand;
5
6#[cfg(feature = "git-overlay")]
7use super::BridgeCommands;
8#[cfg(feature = "semantic")]
9use super::SemanticCommands;
10use super::{
11    commands_args::{
12        ActorDoneArgs, ActorExplainArgs, ActorListArgs, ActorShowArgs, ActorSpawnArgs, AttemptArgs,
13        CloneArgs, CollapseArgs, DelegateArgs, DiagnoseArgs, DiffArgs, DoctorArgs, InitArgs,
14        LogArgs, MergeArgs, PullArgs, PushArgs, ReadyArgs, ResolveArgs, RetroArgs, RevertArgs,
15        RunArgs, SessionEndArgs, SessionListArgs, SessionSegmentArgs, SessionShowArgs,
16        SessionStartArgs, ShipArgs, SnapshotArgs, SyncArgs, ThreadStartArgs, TryArgs, UndoArgs,
17        WatchArgs,
18    },
19    AgentCommands, BisectCommands, CheckpointArgs, ConflictCommands, ContextCommands,
20    DiscussCommands, HookCommands, IntegrationCommands, MarkerCommands, PurgeCommands, QueryArgs,
21    RedactCommands, RemoteCommands, ReviewCommands, StashCommands, ThreadCommands,
22    TransactionCommands, WorkspaceCommands,
23};
24#[cfg(feature = "client")]
25use super::{AuthCommands, SupportCommands};
26
27#[derive(Subcommand)]
28pub enum Commands {
29    /// Initialize a new Heddle repository.
30    Init(InitArgs),
31
32    /// Curated, progressive-disclosure help.
33    ///
34    /// `heddle help` prints the twelve everyday verbs and points at
35    /// `heddle help advanced` for everything else. `heddle help
36    /// <topic>` prints the topic page (e.g. `daemon`, `signals`,
37    /// `bridge`). `heddle help <verb>` falls through to that verb's
38    /// `--help` so the printer never duplicates clap's per-verb
39    /// derivation.
40    Help {
41        /// Topic name (`advanced`, `daemon`, `signals`, …) or verb
42        /// name. When omitted, prints the curated default.
43        topic: Option<String>,
44    },
45
46    /// Show repository status.
47    #[command(after_help = "\
48Examples:
49  heddle status               # current thread, dirty paths, recommended next step
50  heddle status --short       # one-line summary for shell prompts
51  heddle status --watch       # live dashboard that refreshes in place
52")]
53    Status {
54        /// Short format.
55        #[arg(short, long)]
56        short: bool,
57
58        /// Continuously refresh status.
59        #[arg(long)]
60        watch: bool,
61
62        /// Internal helper for tests: stop after N watch updates.
63        #[arg(long, hide = true)]
64        watch_iterations: Option<usize>,
65
66        /// Internal helper for tests: polling interval in milliseconds.
67        #[arg(long, hide = true)]
68        watch_interval_ms: Option<u64>,
69    },
70
71    /// Stream live oplog activity.
72    ///
73    /// Tails the repository's append-only oplog file like `tail -f`,
74    /// emitting snapshots, merges, and thread events as they happen.
75    /// Exits on Ctrl-C.
76    Watch(WatchArgs),
77
78    /// Diagnose repository, thread, actor, and worktree context.
79    Diagnose(DiagnoseArgs),
80
81    /// Explain repository health, or run targeted doctor checks.
82    ///
83    /// `heddle doctor` (no subcommand) reports repository health and
84    /// the next recovery step (the same payload as `heddle diagnose`).
85    /// `heddle doctor docs` diff-checks markdown documentation against
86    /// the actual CLI surface and exits non-zero on drift — wire it
87    /// into CI to stop docs from going stale.
88    Doctor(DoctorArgs),
89
90    /// Show the low-friction Git-overlay workflow.
91    #[cfg(feature = "git-overlay")]
92    GitOverlay,
93
94    /// Print the JSON Schema for a `--json`-emitting verb.
95    ///
96    /// Single-registry introspection over CLI output shapes —
97    /// useful when wiring tools that consume `heddle <verb>
98    /// --json` and want to validate or generate types. The schemas
99    /// live in `crates/cli/src/cli/commands/schemas.rs`; the same
100    /// registry powers `heddle doctor schemas` for drift detection
101    /// against `docs/json-schemas.md`.
102    ///
103    /// `<verb>` is the joined subcommand path — e.g. `status`, `log`,
104    /// `bridge git status`, `marker list`.
105    Schemas {
106        /// The verb whose schema to emit. Run `heddle schemas --help`
107        /// or look at `docs/json-schemas.md` for the registered list.
108        ///
109        /// `trailing_var_arg = true` lets the verb spec carry literal
110        /// `--flag` tokens (e.g. `heddle schemas log --reflog`,
111        /// `heddle schemas marker delete --prefix`) without clap
112        /// parsing them as options on `schemas` itself.
113        #[arg(trailing_var_arg = true, allow_hyphen_values = true)]
114        verb: Vec<String>,
115    },
116
117    /// Show Heddle version. Pass global `--verbose` for bug-report context.
118    Version,
119
120    /// Start a thread for work in Heddle's primary thread-first workflow.
121    Start(ThreadStartArgs),
122
123    /// Run a command in a sandboxed ephemeral thread.
124    ///
125    /// Heddle creates a fresh thread with an isolated checkout, runs
126    /// `<cmd>` inside it, and then either captures the result on a
127    /// zero exit or drops the thread on a non-zero exit. The parent
128    /// thread's working tree is never touched — the ephemeral thread
129    /// is the sandbox. Implements item 3.1 from the heddle 6→8 plan.
130    ///
131    /// `try` is the **new-sandbox** sibling to `run`. Reach for `run`
132    /// when you already have a thread and just want to exec a command
133    /// inside its checkout (no thread creation, no capture, no
134    /// rollback).
135    Try(TryArgs),
136
137    /// Run a command in N parallel sandboxed ephemeral threads and
138    /// rank the results.
139    ///
140    /// Best-of-N parallelism: each attempt gets its own ephemeral
141    /// thread + isolated checkout, runs `<cmd>` inside it, and the
142    /// results are ranked (primary exit code → optional `--evaluate`
143    /// exit → diff size → duration). Failed attempts are dropped
144    /// automatically; successful ones stay around for the user to
145    /// merge or drop. Implements item 3.2 from the heddle 6→8 plan.
146    Attempt(AttemptArgs),
147
148    /// Automation/workflow command: run a command inside an existing
149    /// thread's execution root.
150    ///
151    /// `run` is the **existing-thread** sibling to `try`. It looks up
152    /// the named (or current) thread, sets the child's cwd to that
153    /// thread's checkout, exports `HEDDLE_THREAD_*` and harness-bridge
154    /// env, and runs `<cmd>`. It does NOT create a thread, capture
155    /// state on success, or roll back on failure — those are `try`'s
156    /// job. Reach for `try` when you want the sandbox lifecycle; reach
157    /// for `run` when you already have a thread and just need to exec
158    /// inside it.
159    Run(RunArgs),
160
161    /// Automation/workflow command: refresh the current thread onto its target when safe.
162    Sync(SyncArgs),
163
164    /// Continue the active operation without remembering the specific subcommand.
165    Continue,
166
167    /// Abort the active operation without remembering the specific subcommand.
168    Abort,
169
170    /// Automation/workflow command: capture, integrate, and optionally
171    /// push the current thread.
172    ///
173    /// `ship` is the **do-it** verb: capture outstanding work, refresh
174    /// against the target if stale, merge into the parent (or
175    /// `--remote` push target), checkpoint, and optionally push. It
176    /// fails closed when conflicts or other blockers exist. Pair with
177    /// `ready` (the **check-only** counterpart) when you want to know
178    /// whether a ship would succeed without performing the integration.
179    Ship(ShipArgs),
180
181    /// Automation/workflow command: fan a parent thread into one or
182    /// more delegated child threads.
183    ///
184    /// `delegate <task>...` is the multi-task fan-out wrapper around
185    /// `start`. Each `<task>` is either `task` or `task:provider:model`,
186    /// so you can race different agents on the same prompt in one
187    /// command. It pre-warms the canonical store before materializing N
188    /// child checkouts (relevant for the multi-task case), and stamps
189    /// the spawned threads with `--parent-thread <current>`. For a
190    /// single child with no per-task agent override, `heddle start
191    /// <name>` is the lower-level path.
192    Delegate(DelegateArgs),
193
194    /// Automation/workflow command: capture work, evaluate merge
195    /// readiness, and update thread state.
196    ///
197    /// `ready` is the **check-only** counterpart to `ship`. It captures
198    /// any outstanding work, runs the same readiness preflight `ship`
199    /// uses (conflicts, blockers, freshness, semantic risk), and writes
200    /// `Ready` or `Blocked` onto the thread's state — but it never
201    /// merges, never checkpoints, and never pushes. Reach for it when
202    /// you want a verdict without committing to the integration.
203    Ready(ReadyArgs),
204
205    /// Capture a recoverable Heddle step for undo, provenance, and review.
206    Capture(SnapshotArgs),
207
208    /// Commit the current captured work to the Git-overlay branch/index.
209    Checkpoint(CheckpointArgs),
210
211    /// Show state history.
212    ///
213    /// By default, when a thread name is given (e.g. `heddle log master`),
214    /// the walk is *first-parent only* — equivalent to `git log
215    /// --first-parent <branch>`. To see every ancestor reachable through
216    /// merge commits, pass `--graph` (which renders the full DAG) or
217    /// `--all` (which lists every state regardless of ancestry).
218    Log(LogArgs),
219
220    /// Show state details.
221    Show {
222        /// State by change ID or hash prefix.
223        state: String,
224    },
225
226    /// Summarize a working session.
227    ///
228    /// Combines oplog, agent registry, marker, and context-annotation
229    /// reads into one structured payload — agent-readable retro of
230    /// captures, signals, and notable events since `--since`. Replaces
231    /// the reconstruct-from-`heddle log` boilerplate.
232    Retro(RetroArgs),
233
234    /// Inspect a state or thread (default: current thread).
235    Inspect {
236        /// State ID or thread name.
237        target: Option<String>,
238    },
239
240    /// Move worktree to a state.
241    Goto {
242        /// Target state.
243        target: String,
244
245        /// Discard uncommitted changes.
246        #[arg(short, long)]
247        force: bool,
248    },
249
250    /// Remove untracked files from worktree.
251    Clean {
252        /// Actually remove files (required for safety).
253        #[arg(short, long)]
254        force: bool,
255
256        /// Only show what would be removed.
257        #[arg(long)]
258        dry_run: bool,
259    },
260
261    /// Show differences between states.
262    Diff(DiffArgs),
263
264    /// Open or resolve discussions anchored to symbols.
265    ///
266    /// Open a discussion against a symbol; append turns;
267    /// resolve into an annotation, by edit, or dismissed. Anchors
268    /// travel across renames and cross-file moves on subsequent
269    /// state mutations.
270    #[command(after_help = "\
271Examples:
272  heddle discuss open --path src/auth.rs --symbol verify   # anchor a discussion to a symbol
273  heddle discuss append <id> 'switched to argon2'          # add a turn
274  heddle discuss resolve <id> --as annotation              # close into a context annotation
275")]
276    Discuss {
277        #[command(subcommand)]
278        command: DiscussCommands,
279    },
280
281    /// Structured query over the operation log. Filter by
282    /// actor, time window, signal kind, symbol, thread, verbs. Returns
283    /// structured results consumable by agents.
284    Query(QueryArgs),
285
286    /// Transactional multi-step edits. Begin, commit, abort,
287    /// status. Operations within don't produce intermediate states.
288    ///
289    /// Hidden in alpha: buffered-op replay at commit and rewind-on-abort
290    /// are still follow-on work; the verb stays available for testing
291    /// but is not advertised in `heddle help advanced`.
292    #[command(hide = true)]
293    Transaction {
294        #[command(subcommand)]
295        command: TransactionCommands,
296    },
297
298    /// Structured conflicts. List, show, resolve conflicts as
299    /// data — agents resolve programmatically without parsing markers.
300    Conflict {
301        #[command(subcommand)]
302        command: ConflictCommands,
303    },
304
305    /// Review a state — render the payload, sign, see signal health.
306    ///
307    /// `heddle review show` renders the review payload (summary,
308    /// agent narrative, in-budget signals, anchored discussions).
309    /// `heddle review sign` submits a `read` / `agent_preview` /
310    /// `agent_co_review` signature on the state. `heddle review
311    /// health` reports per-module signal fire rates over a rolling
312    /// window.
313    #[command(after_help = "\
314Examples:
315  heddle review show HEAD                  # render the review payload for HEAD
316  heddle review sign HEAD --as read        # acknowledge a review
317  heddle review health --window 7d         # signal fire-rates over the last week
318")]
319    Review {
320        #[command(subcommand)]
321        command: ReviewCommands,
322    },
323
324    /// Redact a sensitive blob in a state so reads return a stub
325    /// instead of the content.
326    ///
327    /// `heddle redact apply` declares a redaction; the blob bytes stay
328    /// on disk and reads return the operator-supplied stub. `heddle
329    /// purge` afterward physically removes the bytes. Both are signed,
330    /// attributed, oplog-audited operations. See
331    /// `docs/PRINCIPLES.md` (the honesty principle) for context.
332    Redact {
333        #[command(subcommand)]
334        command: RedactCommands,
335    },
336
337    /// Physically remove the bytes referenced by an existing redaction.
338    /// Irreversible; refuses without `--force`.
339    Purge {
340        #[command(subcommand)]
341        command: PurgeCommands,
342    },
343
344    /// Revert changes from a state.
345    Revert(RevertArgs),
346
347    /// Undo last operation.
348    Undo(UndoArgs),
349
350    /// Redo undone operation.
351    Redo {
352        /// Redo N operations.
353        #[arg(short = 'n', long, default_value = "1")]
354        steps: usize,
355
356        /// Preview operations without redoing.
357        #[arg(long)]
358        preview: bool,
359    },
360
361    /// Fork an exploration thread from a state.
362    Fork {
363        /// Name for the fork (creates thread).
364        #[arg(long)]
365        name: Option<String>,
366
367        /// State to fork from (default: HEAD).
368        #[arg(long)]
369        from: Option<String>,
370    },
371
372    /// Collapse (squash) multiple states into one.
373    Collapse(CollapseArgs),
374
375    /// Compare two states.
376    Compare {
377        /// First state.
378        state_a: String,
379
380        /// Second state.
381        state_b: String,
382
383        /// Include semantic analysis.
384        #[arg(long)]
385        semantic: bool,
386    },
387
388    /// Manage markers.
389    Marker {
390        #[command(subcommand)]
391        command: MarkerCommands,
392    },
393
394    /// Manage threads.
395    Thread {
396        #[command(subcommand)]
397        command: ThreadCommands,
398    },
399
400    /// Show the repo-wide workspace control tower.
401    Workspace {
402        #[command(subcommand)]
403        command: WorkspaceCommands,
404    },
405
406    /// Merge a thread into current thread.
407    Merge(MergeArgs),
408
409    /// Resolve merge conflicts.
410    Resolve(ResolveArgs),
411
412    /// Verify repository integrity.
413    Fsck {
414        /// Full check (includes content verification).
415        #[arg(long)]
416        full: bool,
417
418        /// Run slower graph and signature integrity checks.
419        #[arg(long)]
420        thorough: bool,
421
422        /// Attempt to repair issues.
423        #[arg(long)]
424        repair: bool,
425
426        /// Include Git-overlay mirror, mapping, notes, and checkout checks.
427        #[arg(long)]
428        bridge: bool,
429    },
430
431    /// Download objects and refs from remote.
432    Fetch {
433        /// Remote name or URL.
434        remote: Option<String>,
435
436        /// Fetch from all remotes.
437        #[arg(long)]
438        all: bool,
439    },
440
441    /// Push to a remote repository.
442    Push(PushArgs),
443
444    /// Pull from a remote repository.
445    Pull(PullArgs),
446
447    /// Manage remote repositories.
448    Remote {
449        #[command(subcommand)]
450        command: RemoteCommands,
451    },
452
453    /// Authenticate with a Heddle server.
454    #[cfg(feature = "client")]
455    Auth {
456        #[command(subcommand)]
457        command: AuthCommands,
458    },
459
460    /// Manage code context annotations.
461    #[command(after_help = "\
462Examples:
463  heddle context set --path src/auth.rs --scope symbol:verify --kind invariant -m 'returns false on timing mismatch'
464  heddle context get --path src/auth.rs --scope symbol:verify
465  heddle context list --prefix src/auth          # everything attached under a path
466  heddle context check --path src/auth.rs        # surface annotations for editor tooling
467")]
468    Context {
469        #[command(subcommand)]
470        command: ContextCommands,
471    },
472
473    /// Manage ambient harness integrations.
474    Integration {
475        #[command(subcommand)]
476        command: IntegrationCommands,
477    },
478
479    /// Manage stashed changes.
480    Stash {
481        #[command(subcommand)]
482        command: StashCommands,
483    },
484
485    /// Customer-issued temporary admin grants for Heddle staff.
486    /// Time-bounded and audit-trailed; staff need an active grant to
487    /// act on customer resources beyond the operator surface.
488    #[cfg(feature = "client")]
489    Support {
490        #[command(subcommand)]
491        command: SupportCommands,
492    },
493
494    /// Bridge to other version control systems.
495    #[cfg(feature = "git-overlay")]
496    #[command(after_help = "\
497Examples:
498  heddle bridge git status                       # what would import / export look like?
499  heddle bridge git import --ref main            # adopt one branch as a full Heddle lane
500  heddle bridge git sync                         # bidirectional export + import
501  heddle bridge git export ../mirror.git         # write a bare git mirror
502")]
503    Bridge {
504        #[command(subcommand)]
505        command: BridgeCommands,
506    },
507
508    /// Semantic analysis queries (call-graph hot-spots, churn,
509    /// signature-stability surfaces).
510    #[cfg(feature = "semantic")]
511    Semantic {
512        #[command(subcommand)]
513        command: SemanticCommands,
514    },
515
516    /// Generate shell completion scripts.
517    Completion {
518        /// Shell to generate completion for.
519        shell: String,
520    },
521
522    /// Hidden compatibility alias for `maintenance gc`.
523    #[command(hide = true)]
524    Gc {
525        /// Prune unreachable objects.
526        #[arg(long)]
527        prune: bool,
528
529        /// Aggressive garbage collection.
530        #[arg(long)]
531        aggressive: bool,
532
533        /// Show what would be removed without removing.
534        #[arg(long)]
535        dry_run: bool,
536    },
537
538    /// Hidden compatibility alias for `maintenance index`.
539    #[command(hide = true)]
540    Index {
541        /// Dump the index contents in human-readable format.
542        #[arg(long)]
543        dump: bool,
544    },
545
546    /// Hidden compatibility alias for `maintenance monitor`.
547    #[command(hide = true)]
548    Monitor {
549        /// Print changed paths as well as backend/status summary.
550        #[arg(long)]
551        paths: bool,
552
553        /// Internal helper mode: serve monitor queries for this repo.
554        #[arg(long, hide = true)]
555        serve: bool,
556    },
557
558    /// FUSE mount-daemon control plane — distinct from `agent`.
559    ///
560    /// `heddle daemon serve` runs a foreground mount daemon that
561    /// owns FUSE sessions for `--workspace light --daemon`
562    /// threads. It is normally spawned on demand by the per-thread
563    /// CLI; running it interactively is for debugging.
564    /// `status` reports liveness/uptime/mount count without spawning;
565    /// `stop` asks a running daemon to drain mounts and exit.
566    Daemon {
567        #[command(subcommand)]
568        command: DaemonCommands,
569    },
570
571    /// Agent control surface — daemon lifecycle and reservation API.
572    ///
573    /// `heddle agent serve|status|stop` controls the local gRPC
574    /// daemon (Unix socket inside the repo). `heddle agent
575    /// reserve|capture|ready|release|list|heartbeat` is the stable
576    /// JSON contract orchestrators use to coordinate parallel
577    /// writers. Distinct from `heddle daemon` (FUSE mount control
578    /// plane) — different subsystem.
579    Agent {
580        #[command(subcommand)]
581        command: AgentCommands,
582    },
583
584    /// Inspect and refresh rebuildable performance sidecars.
585    Maintenance {
586        #[command(subcommand)]
587        command: MaintenanceCommands,
588    },
589
590    /// Object-store maintenance commands.
591    ///
592    /// `store warm <state>` proactively promotes every blob reachable
593    /// from `<state>` into the canonical loose-uncompressed form.
594    /// This keeps the hardlink-first materializer on its fast path
595    /// after `pack_objects + prune_loose_objects` has consolidated
596    /// blobs into packfiles. Useful before fanning out N worktrees
597    /// from the same state (e.g. before a `heddle delegate` round).
598    Store {
599        #[command(subcommand)]
600        command: StoreCommands,
601    },
602
603    /// Show line-by-line attribution for a file.
604    Blame {
605        /// File to blame.
606        file: String,
607
608        /// State to blame from (default: HEAD).
609        #[arg(long)]
610        state: Option<String>,
611
612        /// Show concise applicable context before blame output.
613        #[arg(long)]
614        context: bool,
615    },
616
617    /// Binary search for bugs.
618    Bisect {
619        #[command(subcommand)]
620        command: BisectCommands,
621    },
622
623    /// Apply specific commits.
624    CherryPick {
625        /// Commit to cherry-pick.
626        commit: String,
627
628        /// Commit message for the cherry-pick.
629        #[arg(short = 'm', long)]
630        message: Option<String>,
631
632        /// Apply changes to worktree without committing.
633        #[arg(long)]
634        no_commit: bool,
635
636        /// Discard uncommitted local changes instead of refusing.
637        #[arg(long)]
638        force: bool,
639    },
640
641    /// Clone from remote.
642    Clone(CloneArgs),
643
644    /// Rebase current thread onto another.
645    Rebase {
646        /// Thread to rebase onto.
647        thread: Option<String>,
648
649        /// Abort an in-progress rebase.
650        #[arg(long)]
651        abort: bool,
652
653        /// Continue an in-progress rebase after resolving conflicts.
654        #[arg(long = "continue", alias = "cont")]
655        cont: bool,
656
657        /// Discard uncommitted local changes instead of refusing.
658        #[arg(long)]
659        force: bool,
660    },
661
662    /// Manage repository hooks.
663    Hook {
664        #[command(subcommand)]
665        command: HookCommands,
666    },
667
668    /// JSONL bridge for harness session reporting.
669    ///
670    /// Internal plumbing — invoked by `heddle run` and integration
671    /// adapters via `HEDDLE_HARNESS_BRIDGE_*` env vars. Hidden from
672    /// `heddle --help` and `heddle help advanced` because it isn't a
673    /// user-facing verb. The verb itself still works and is documented
674    /// in `docs/HARNESS_ACTOR_INTEGRATION.md`.
675    #[command(hide = true)]
676    HarnessBridge,
677
678    /// Advanced debugging/provenance commands for Heddle actors attached to threads.
679    Actor {
680        #[command(subcommand)]
681        command: ActorCommands,
682    },
683
684    /// Advanced debugging/provenance commands for Heddle execution sessions.
685    Session {
686        #[command(subcommand)]
687        command: SessionCommands,
688    },
689
690    /// Advanced debugging/provenance commands for the hosted local-agent presence relay.
691    ///
692    /// `heddle presence publish` runs a foreground publisher that streams
693    /// agent_start / agent_heartbeat / agent_done events to the configured
694    /// hosted server over a bearer-authenticated WebSocket.
695    #[cfg(feature = "client")]
696    Presence {
697        #[command(subcommand)]
698        command: PresenceCommands,
699    },
700}
701
702/// Presence subcommands.
703#[cfg(feature = "client")]
704#[derive(Clone, Debug, clap::Subcommand)]
705pub enum PresenceCommands {
706    /// Publish presence events for the given agent session.
707    ///
708    /// Intended to be launched detached by an orchestrator (or called
709    /// manually for debugging). Reads agent metadata from
710    /// `.heddle/agents/<session>.toml` and hosted upstream from
711    /// `.heddle/config.toml` `[hosted]`. Exits 0 (with a log line) when no
712    /// upstream is configured.
713    Publish {
714        /// Agent session ID (matches `.heddle/agents/<session>.toml`).
715        #[arg(long)]
716        session: String,
717
718        /// Heartbeat interval in seconds (default 15).
719        #[arg(long, default_value = "15")]
720        interval_secs: u64,
721    },
722}
723
724/// Maintenance subcommands.
725#[derive(Clone, Debug, clap::Subcommand)]
726pub enum MaintenanceCommands {
727    /// Inspect repository performance sidecars and repo shape.
728    Inspect,
729
730    /// Rebuild repository performance sidecars without changing repository meaning.
731    Run,
732
733    /// Garbage collect unreachable objects.
734    Gc {
735        /// Prune unreachable objects.
736        #[arg(long)]
737        prune: bool,
738
739        /// Aggressive garbage collection.
740        #[arg(long)]
741        aggressive: bool,
742
743        /// Show what would be removed without removing.
744        #[arg(long)]
745        dry_run: bool,
746    },
747
748    /// Inspect and debug the worktree index.
749    #[command(hide = true)]
750    Index {
751        /// Dump the index contents in human-readable format.
752        #[arg(long)]
753        dump: bool,
754    },
755
756    /// Inspect the local change monitor state.
757    #[command(hide = true)]
758    Monitor {
759        /// Print changed paths as well as backend/status summary.
760        #[arg(long)]
761        paths: bool,
762
763        /// Internal helper mode: serve monitor queries for this repo.
764        #[arg(long, hide = true)]
765        serve: bool,
766    },
767}
768
769/// Store subcommands.
770#[derive(Clone, Debug, clap::Subcommand)]
771pub enum StoreCommands {
772    /// Promote every reachable blob from `<state>` into the
773    /// uncompressed-loose canonical store so the hardlink-first
774    /// materializer can `link(2)` directly without paying
775    /// `decompress + write` on the first materialize.
776    ///
777    /// Defaults to HEAD when `<state>` is omitted. Idempotent: a
778    /// second call is essentially a no-op (every blob is already
779    /// loose+uncompressed).
780    Warm {
781        /// State specifier (HEAD, thread name, marker, change-id);
782        /// defaults to HEAD when omitted.
783        state: Option<String>,
784    },
785}
786
787/// Daemon control plane subcommands. See `Commands::Daemon`.
788#[derive(Clone, Debug, clap::Subcommand)]
789pub enum DaemonCommands {
790    /// Run a foreground mount daemon for this repository.
791    ///
792    /// Normally spawned on demand by the per-thread CLI when
793    /// `--daemon` is passed. Running interactively is for
794    /// debugging the daemon protocol.
795    Serve,
796
797    /// Report daemon liveness, version, uptime, and active mount
798    /// count. No-op success when the daemon isn't running.
799    Status,
800
801    /// Ask the running daemon to drain its mounts and exit. Sweeps
802    /// any leftover registry entries with `fusermount -u` as a
803    /// safety net before returning.
804    Stop,
805}
806
807/// Actor subcommands.
808#[derive(Clone, Debug, clap::Subcommand)]
809pub enum ActorCommands {
810    /// Register a new actor lane (creates a thread + registry entry).
811    /// Does not create a filesystem-isolated checkout — for that use
812    /// `heddle start <name> --path <dir>`.
813    Spawn(ActorSpawnArgs),
814
815    /// List actors known to this repository.
816    List(ActorListArgs),
817
818    /// Show the current or selected actor.
819    Show(ActorShowArgs),
820
821    /// Explain why Heddle attached the current or selected actor.
822    Explain(ActorExplainArgs),
823
824    /// Mark the current or selected actor complete.
825    Done(ActorDoneArgs),
826}
827
828// `AgentCommands` lives in `commands_agent.rs`. Codex's foundation
829// commit added a parallel definition here; deleted during the rebase
830// onto main (which had already introduced the file). The reservation
831// variants Codex contributed are now folded into the canonical enum in
832// `commands_agent.rs`.
833
834/// Session subcommands.
835#[derive(Clone, Debug, clap::Subcommand)]
836pub enum SessionCommands {
837    /// Start a new session.
838    Start(SessionStartArgs),
839
840    /// Create a new segment (provider/model change).
841    Segment(SessionSegmentArgs),
842
843    /// End the current session.
844    End(SessionEndArgs),
845
846    /// Show session details.
847    Show(SessionShowArgs),
848
849    /// List all sessions.
850    List(SessionListArgs),
851}