intent_engine/
cli.rs

1use clap::{Parser, Subcommand};
2
3#[derive(Parser)]
4#[command(name = "intent-engine")]
5#[command(about = "A command-line database service for tracking strategic intent", long_about = None)]
6#[command(version)]
7pub struct Cli {
8    #[command(subcommand)]
9    pub command: Commands,
10}
11
12#[derive(Subcommand)]
13pub enum Commands {
14    /// Task management commands
15    #[command(subcommand)]
16    Task(TaskCommands),
17
18    /// Workspace state management
19    Current {
20        /// Set the current task ID
21        #[arg(long)]
22        set: Option<i64>,
23    },
24
25    /// Generate analysis and reports
26    Report {
27        /// Time duration (e.g., "7d", "2h", "30m")
28        #[arg(long)]
29        since: Option<String>,
30
31        /// Filter by status
32        #[arg(long)]
33        status: Option<String>,
34
35        /// Filter by name pattern (FTS5)
36        #[arg(long)]
37        filter_name: Option<String>,
38
39        /// Filter by spec pattern (FTS5)
40        #[arg(long)]
41        filter_spec: Option<String>,
42
43        /// Output format
44        #[arg(long, default_value = "json")]
45        format: String,
46
47        /// Return summary only
48        #[arg(long)]
49        summary_only: bool,
50    },
51
52    /// Event logging commands
53    #[command(subcommand)]
54    Event(EventCommands),
55
56    /// Check system health and dependencies
57    Doctor,
58
59    /// Start MCP server for AI assistants (JSON-RPC stdio)
60    #[command(name = "mcp-server")]
61    McpServer,
62}
63
64#[derive(Subcommand)]
65pub enum TaskCommands {
66    /// Add a new task
67    Add {
68        /// Task name
69        #[arg(long)]
70        name: String,
71
72        /// Parent task ID
73        #[arg(long)]
74        parent: Option<i64>,
75
76        /// Read spec from stdin
77        #[arg(long)]
78        spec_stdin: bool,
79    },
80
81    /// Get a task by ID
82    Get {
83        /// Task ID
84        id: i64,
85
86        /// Include events summary
87        #[arg(long)]
88        with_events: bool,
89    },
90
91    /// Update a task
92    Update {
93        /// Task ID
94        id: i64,
95
96        /// New task name
97        #[arg(long)]
98        name: Option<String>,
99
100        /// New parent task ID
101        #[arg(long)]
102        parent: Option<i64>,
103
104        /// New status
105        #[arg(long)]
106        status: Option<String>,
107
108        /// Task complexity (1-10)
109        #[arg(long)]
110        complexity: Option<i32>,
111
112        /// Task priority (critical, high, medium, low)
113        #[arg(long)]
114        priority: Option<String>,
115
116        /// Read spec from stdin
117        #[arg(long)]
118        spec_stdin: bool,
119    },
120
121    /// Delete a task
122    Del {
123        /// Task ID
124        id: i64,
125    },
126
127    /// List tasks with filters
128    List {
129        /// Filter by status
130        #[arg(long)]
131        status: Option<String>,
132
133        /// Filter by parent ID (use "null" for no parent)
134        #[arg(long)]
135        parent: Option<String>,
136    },
137
138    /// Find tasks with filters (deprecated: use 'list' instead)
139    #[command(hide = true)]
140    Find {
141        /// Filter by status
142        #[arg(long)]
143        status: Option<String>,
144
145        /// Filter by parent ID (use "null" for no parent)
146        #[arg(long)]
147        parent: Option<String>,
148    },
149
150    /// Start a task (atomic: update status + set current)
151    Start {
152        /// Task ID
153        id: i64,
154
155        /// Include events summary
156        #[arg(long)]
157        with_events: bool,
158    },
159
160    /// Complete the current focused task (atomic: check children + update status + clear current)
161    /// This command only operates on the current_task_id. It will:
162    /// - Check all subtasks are done
163    /// - Update the task status to done
164    /// - Clear the current_task_id
165    ///
166    ///   Prerequisites: A task must be set as current (via `current --set <ID>`)
167    Done,
168
169    /// Intelligently recommend the next task to work on
170    ///
171    /// This command uses a context-aware priority model to recommend a single task:
172    /// 1. First priority: Subtasks of the current focused task (depth-first)
173    /// 2. Second priority: Top-level tasks (breadth-first)
174    ///
175    /// The command is non-interactive and does not modify task status.
176    PickNext {
177        /// Output format (text or json)
178        #[arg(long, default_value = "text")]
179        format: String,
180    },
181
182    /// Create a subtask under current task and switch to it
183    SpawnSubtask {
184        /// Subtask name
185        #[arg(long)]
186        name: String,
187
188        /// Read spec from stdin
189        #[arg(long)]
190        spec_stdin: bool,
191    },
192
193    /// Switch to a specific task (atomic: update to doing + set current)
194    Switch {
195        /// Task ID
196        id: i64,
197    },
198
199    /// Search tasks by content using full-text search
200    Search {
201        /// Search query (supports FTS5 syntax like "bug AND NOT critical")
202        query: String,
203    },
204
205    /// Add a dependency between tasks
206    ///
207    /// Creates a dependency where BLOCKED_TASK depends on BLOCKING_TASK.
208    /// The BLOCKING_TASK must be completed before BLOCKED_TASK can be started.
209    ///
210    /// Example: `task depends-on 42 41` means Task 42 depends on Task 41
211    /// (Task 41 must be done before Task 42 can start)
212    #[command(name = "depends-on")]
213    DependsOn {
214        /// Task ID that has the dependency (blocked task)
215        blocked_task_id: i64,
216
217        /// Task ID that must be completed first (blocking task)
218        blocking_task_id: i64,
219    },
220}
221
222#[derive(Subcommand)]
223pub enum EventCommands {
224    /// Add a new event
225    Add {
226        /// Task ID (optional, uses current task if not specified)
227        #[arg(long)]
228        task_id: Option<i64>,
229
230        /// Log type
231        #[arg(long = "type")]
232        log_type: String,
233
234        /// Read discussion data from stdin
235        #[arg(long)]
236        data_stdin: bool,
237    },
238
239    /// List events for a task
240    List {
241        /// Task ID
242        #[arg(long)]
243        task_id: i64,
244
245        /// Maximum number of events to return
246        #[arg(long)]
247        limit: Option<i64>,
248
249        /// Filter by log type (e.g., "decision", "blocker", "milestone", "note")
250        #[arg(long = "type")]
251        log_type: Option<String>,
252
253        /// Filter events created within duration (e.g., "7d", "24h", "30m")
254        #[arg(long)]
255        since: Option<String>,
256    },
257}