Skip to main content

dejavu/cli/
dejavu_cli.rs

1//! The `dejavu` CLI command tree.
2
3use clap::{Parser, Subcommand};
4
5#[derive(Parser, Debug)]
6#[command(
7    name = "dejavu",
8    version,
9    about = "Stop showing agents the same output twice."
10)]
11pub struct Cli {
12    #[command(subcommand)]
13    pub command: DejavuCmd,
14}
15
16#[derive(Subcommand, Debug)]
17pub enum DejavuCmd {
18    /// Launch a coding agent (or any command) with Dejavu active.
19    ///
20    /// Examples: `dejavu start claude`, `dejavu start codex`, `dejavu start -- bash`
21    Start {
22        /// The command to launch, with its arguments.
23        #[arg(
24            trailing_var_arg = true,
25            allow_hyphen_values = true,
26            required = true,
27            value_name = "COMMAND"
28        )]
29        command: Vec<String>,
30    },
31
32    /// Initialize the cache for the current repo (does not modify the repo).
33    Init,
34
35    /// Global activation. With no flag, prints the line for
36    /// `eval "$(dejavu shellenv)"`. With --install, writes it into your shell
37    /// profile(s) so IDE terminals and GUI-launched agents are covered.
38    Shellenv {
39        /// Write the activation block into your shell profile(s).
40        #[arg(long)]
41        install: bool,
42        /// Remove the activation block from your shell profile(s).
43        #[arg(long, conflicts_with = "install")]
44        uninstall: bool,
45        /// Which shell(s): zsh, bash, sh, or all. Default for --install/--uninstall: all.
46        #[arg(long, value_name = "SHELL")]
47        shell: Option<String>,
48    },
49
50    /// Diagnose the Dejavu setup for the current repo.
51    Doctor {
52        /// Emit the checks as JSON instead of text.
53        #[arg(long)]
54        json: bool,
55    },
56
57    /// Internal: invoked by a shim. Runs the real command and reduces output.
58    #[command(hide = true)]
59    Run {
60        /// Name of the shim that was invoked (e.g. `pnpm`, `git`).
61        #[arg(long)]
62        shim_name: String,
63        /// Everything after `--` — the real command's arguments.
64        #[arg(trailing_var_arg = true, allow_hyphen_values = true)]
65        args: Vec<String>,
66    },
67
68    /// Show a captured run (compact by default; raw with a stream flag).
69    Show {
70        /// `latest` or a run id / short prefix.
71        target: String,
72        /// Print the stored raw stdout of the run.
73        #[arg(long)]
74        stdout: bool,
75        /// Print the stored raw stderr of the run.
76        #[arg(long)]
77        stderr: bool,
78        /// Print the normalized text used for run comparison.
79        #[arg(long)]
80        normalized: bool,
81    },
82
83    /// Search the stored raw output of a run.
84    Grep {
85        /// `latest` or a run id / short prefix.
86        target: String,
87        /// Regex to search for (grep-style exit: 0 match, 1 none, 2 error).
88        pattern: String,
89        /// Search the normalized text instead of the raw output.
90        #[arg(long)]
91        normalized: bool,
92    },
93
94    /// Show token-savings stats for the current repo.
95    Stats {
96        /// Emit the stats as JSON instead of text.
97        #[arg(long)]
98        json: bool,
99        /// Aggregate across every repo Dejavu has ever tracked.
100        #[arg(long)]
101        all: bool,
102        /// Omit repo paths and command details that may contain private names.
103        #[arg(long)]
104        public: bool,
105    },
106
107    /// List repos where Dejavu has recorded activity.
108    Repos {
109        /// Emit the repo list as JSON instead of text.
110        #[arg(long)]
111        json: bool,
112        /// Include repos disabled with `dejavu disable`.
113        #[arg(long)]
114        all: bool,
115    },
116
117    /// Emit a Markdown report suitable for sharing.
118    Report {
119        /// Omit repo paths and command details that may contain private names.
120        #[arg(long)]
121        redact: bool,
122    },
123
124    /// Run a reproducible local benchmark suite (no LLM required).
125    Bench {
126        /// Scenario to run (default: all). See the report for available names.
127        #[arg(long)]
128        scenario: Option<String>,
129        /// Emit the benchmark report as JSON instead of text.
130        #[arg(long)]
131        json: bool,
132        /// Fail (exit 2) if any scenario misses its expectations — CI gate.
133        #[arg(long)]
134        check: bool,
135    },
136
137    /// Remove cached runs and logs.
138    Clean {
139        /// Only remove runs older than this age, e.g. `14d`, `12h`, `30m`.
140        #[arg(long, value_name = "AGE")]
141        older_than: Option<String>,
142        /// Remove every run, log, and shim for the current repo's cache.
143        #[arg(long)]
144        all: bool,
145    },
146
147    /// Remove Dejavu's local cache and generated shims for the current repo.
148    Uninstall,
149
150    /// Enable interception for the current repo.
151    Enable,
152
153    /// Disable interception for the current repo.
154    Disable,
155}