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    /// Restore session context for AI agents (Focus Restoration - Phase 1)
64    ///
65    /// This command returns all context needed to restore work continuity:
66    /// - Current focused task
67    /// - Parent task and siblings progress
68    /// - Child tasks status
69    /// - Recent events (decisions, blockers, notes)
70    /// - Suggested next commands
71    ///
72    /// Designed for SessionStart hooks to inject context at the beginning of new sessions.
73    #[command(name = "session-restore")]
74    SessionRestore {
75        /// Number of recent events to include (default: 3)
76        #[arg(long, default_value = "3")]
77        include_events: usize,
78
79        /// Workspace path (default: current directory)
80        #[arg(long)]
81        workspace: Option<String>,
82    },
83
84    /// Setup Claude Code integration (install SessionStart hook)
85    ///
86    /// Automatically configures .claude/hooks/session-start.sh to enable
87    /// focus restoration on every new Claude Code session.
88    #[command(name = "setup-claude-code")]
89    SetupClaudeCode {
90        /// Show what would be done without actually doing it
91        #[arg(long)]
92        dry_run: bool,
93
94        /// Specify .claude directory location (default: ./.claude)
95        #[arg(long)]
96        claude_dir: Option<String>,
97
98        /// Overwrite existing hook
99        #[arg(long)]
100        force: bool,
101    },
102}
103
104#[derive(Subcommand)]
105pub enum TaskCommands {
106    /// Add a new task
107    Add {
108        /// Task name
109        #[arg(long)]
110        name: String,
111
112        /// Parent task ID
113        #[arg(long)]
114        parent: Option<i64>,
115
116        /// Read spec from stdin
117        #[arg(long)]
118        spec_stdin: bool,
119    },
120
121    /// Get a task by ID
122    Get {
123        /// Task ID
124        id: i64,
125
126        /// Include events summary
127        #[arg(long)]
128        with_events: bool,
129    },
130
131    /// Update a task
132    Update {
133        /// Task ID
134        id: i64,
135
136        /// New task name
137        #[arg(long)]
138        name: Option<String>,
139
140        /// New parent task ID
141        #[arg(long)]
142        parent: Option<i64>,
143
144        /// New status
145        #[arg(long)]
146        status: Option<String>,
147
148        /// Task complexity (1-10)
149        #[arg(long)]
150        complexity: Option<i32>,
151
152        /// Task priority (critical, high, medium, low)
153        #[arg(long)]
154        priority: Option<String>,
155
156        /// Read spec from stdin
157        #[arg(long)]
158        spec_stdin: bool,
159    },
160
161    /// Delete a task
162    Del {
163        /// Task ID
164        id: i64,
165    },
166
167    /// List tasks with filters
168    List {
169        /// Filter by status
170        #[arg(long)]
171        status: Option<String>,
172
173        /// Filter by parent ID (use "null" for no parent)
174        #[arg(long)]
175        parent: Option<String>,
176    },
177
178    /// Find tasks with filters (deprecated: use 'list' instead)
179    #[command(hide = true)]
180    Find {
181        /// Filter by status
182        #[arg(long)]
183        status: Option<String>,
184
185        /// Filter by parent ID (use "null" for no parent)
186        #[arg(long)]
187        parent: Option<String>,
188    },
189
190    /// Start a task (atomic: update status + set current)
191    Start {
192        /// Task ID
193        id: i64,
194
195        /// Include events summary
196        #[arg(long)]
197        with_events: bool,
198    },
199
200    /// Complete the current focused task (atomic: check children + update status + clear current)
201    /// This command only operates on the current_task_id. It will:
202    /// - Check all subtasks are done
203    /// - Update the task status to done
204    /// - Clear the current_task_id
205    ///
206    ///   Prerequisites: A task must be set as current (via `current --set <ID>`)
207    Done,
208
209    /// Intelligently recommend the next task to work on
210    ///
211    /// This command uses a context-aware priority model to recommend a single task:
212    /// 1. First priority: Subtasks of the current focused task (depth-first)
213    /// 2. Second priority: Top-level tasks (breadth-first)
214    ///
215    /// The command is non-interactive and does not modify task status.
216    PickNext {
217        /// Output format (text or json)
218        #[arg(long, default_value = "text")]
219        format: String,
220    },
221
222    /// Create a subtask under current task and switch to it
223    SpawnSubtask {
224        /// Subtask name
225        #[arg(long)]
226        name: String,
227
228        /// Read spec from stdin
229        #[arg(long)]
230        spec_stdin: bool,
231    },
232
233    /// Switch to a specific task (atomic: update to doing + set current)
234    Switch {
235        /// Task ID
236        id: i64,
237    },
238
239    /// Search tasks by content using full-text search
240    Search {
241        /// Search query (supports FTS5 syntax like "bug AND NOT critical")
242        query: String,
243    },
244
245    /// Add a dependency between tasks
246    ///
247    /// Creates a dependency where BLOCKED_TASK depends on BLOCKING_TASK.
248    /// The BLOCKING_TASK must be completed before BLOCKED_TASK can be started.
249    ///
250    /// Example: `task depends-on 42 41` means Task 42 depends on Task 41
251    /// (Task 41 must be done before Task 42 can start)
252    #[command(name = "depends-on")]
253    DependsOn {
254        /// Task ID that has the dependency (blocked task)
255        blocked_task_id: i64,
256
257        /// Task ID that must be completed first (blocking task)
258        blocking_task_id: i64,
259    },
260}
261
262#[derive(Subcommand)]
263pub enum EventCommands {
264    /// Add a new event
265    Add {
266        /// Task ID (optional, uses current task if not specified)
267        #[arg(long)]
268        task_id: Option<i64>,
269
270        /// Log type
271        #[arg(long = "type")]
272        log_type: String,
273
274        /// Read discussion data from stdin
275        #[arg(long)]
276        data_stdin: bool,
277    },
278
279    /// List events for a task
280    List {
281        /// Task ID
282        #[arg(long)]
283        task_id: i64,
284
285        /// Maximum number of events to return
286        #[arg(long)]
287        limit: Option<i64>,
288
289        /// Filter by log type (e.g., "decision", "blocker", "milestone", "note")
290        #[arg(long = "type")]
291        log_type: Option<String>,
292
293        /// Filter events created within duration (e.g., "7d", "24h", "30m")
294        #[arg(long)]
295        since: Option<String>,
296    },
297}