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    /// Unified setup command for AI tool integrations
85    ///
86    /// This command provides a unified interface for setting up intent-engine integration
87    /// with various AI assistant tools. It handles both hook installation and MCP server
88    /// configuration in one step.
89    ///
90    /// Features:
91    /// - User-level or project-level installation
92    /// - Atomic setup with rollback on failure
93    /// - Built-in connectivity testing
94    /// - Diagnosis mode for troubleshooting
95    Setup {
96        /// Target tool to configure (claude-code, gemini-cli, codex)
97        #[arg(long)]
98        target: Option<String>,
99
100        /// Installation scope: user (default, recommended), project, or both
101        #[arg(long, default_value = "user")]
102        scope: String,
103
104        /// Show what would be done without actually doing it
105        #[arg(long)]
106        dry_run: bool,
107
108        /// Overwrite existing configuration
109        #[arg(long)]
110        force: bool,
111
112        /// Run diagnosis on existing setup instead of installing
113        #[arg(long)]
114        diagnose: bool,
115
116        /// Custom config file path (advanced)
117        #[arg(long)]
118        config_path: Option<String>,
119
120        /// Project directory for INTENT_ENGINE_PROJECT_DIR env var
121        #[arg(long)]
122        project_dir: Option<String>,
123    },
124}
125
126#[derive(Subcommand)]
127pub enum TaskCommands {
128    /// Add a new task
129    Add {
130        /// Task name
131        #[arg(long)]
132        name: String,
133
134        /// Parent task ID
135        #[arg(long)]
136        parent: Option<i64>,
137
138        /// Read spec from stdin
139        #[arg(long)]
140        spec_stdin: bool,
141    },
142
143    /// Get a task by ID
144    Get {
145        /// Task ID
146        id: i64,
147
148        /// Include events summary
149        #[arg(long)]
150        with_events: bool,
151    },
152
153    /// Update a task
154    Update {
155        /// Task ID
156        id: i64,
157
158        /// New task name
159        #[arg(long)]
160        name: Option<String>,
161
162        /// New parent task ID
163        #[arg(long)]
164        parent: Option<i64>,
165
166        /// New status
167        #[arg(long)]
168        status: Option<String>,
169
170        /// Task complexity (1-10)
171        #[arg(long)]
172        complexity: Option<i32>,
173
174        /// Task priority (critical, high, medium, low)
175        #[arg(long)]
176        priority: Option<String>,
177
178        /// Read spec from stdin
179        #[arg(long)]
180        spec_stdin: bool,
181    },
182
183    /// Delete a task
184    Del {
185        /// Task ID
186        id: i64,
187    },
188
189    /// List tasks with filters
190    List {
191        /// Filter by status
192        #[arg(long)]
193        status: Option<String>,
194
195        /// Filter by parent ID (use "null" for no parent)
196        #[arg(long)]
197        parent: Option<String>,
198    },
199
200    /// Start a task (atomic: update status + set current)
201    Start {
202        /// Task ID
203        id: i64,
204
205        /// Include events summary
206        #[arg(long)]
207        with_events: bool,
208    },
209
210    /// Complete the current focused task (atomic: check children + update status + clear current)
211    /// This command only operates on the current_task_id. It will:
212    /// - Check all subtasks are done
213    /// - Update the task status to done
214    /// - Clear the current_task_id
215    ///
216    ///   Prerequisites: A task must be set as current (via `current --set <ID>`)
217    Done,
218
219    /// Intelligently recommend the next task to work on
220    ///
221    /// This command uses a context-aware priority model to recommend a single task:
222    /// 1. First priority: Subtasks of the current focused task (depth-first)
223    /// 2. Second priority: Top-level tasks (breadth-first)
224    ///
225    /// The command is non-interactive and does not modify task status.
226    PickNext {
227        /// Output format (text or json)
228        #[arg(long, default_value = "text")]
229        format: String,
230    },
231
232    /// Create a subtask under current task and switch to it
233    SpawnSubtask {
234        /// Subtask name
235        #[arg(long)]
236        name: String,
237
238        /// Read spec from stdin
239        #[arg(long)]
240        spec_stdin: bool,
241    },
242
243    /// Switch to a specific task (atomic: update to doing + set current)
244    Switch {
245        /// Task ID
246        id: i64,
247    },
248
249    /// Search tasks by content using full-text search
250    Search {
251        /// Search query (supports FTS5 syntax like "bug AND NOT critical")
252        query: String,
253    },
254
255    /// Add a dependency between tasks
256    ///
257    /// Creates a dependency where BLOCKED_TASK depends on BLOCKING_TASK.
258    /// The BLOCKING_TASK must be completed before BLOCKED_TASK can be started.
259    ///
260    /// Example: `task depends-on 42 41` means Task 42 depends on Task 41
261    /// (Task 41 must be done before Task 42 can start)
262    #[command(name = "depends-on")]
263    DependsOn {
264        /// Task ID that has the dependency (blocked task)
265        blocked_task_id: i64,
266
267        /// Task ID that must be completed first (blocking task)
268        blocking_task_id: i64,
269    },
270}
271
272#[derive(Subcommand)]
273pub enum EventCommands {
274    /// Add a new event
275    Add {
276        /// Task ID (optional, uses current task if not specified)
277        #[arg(long)]
278        task_id: Option<i64>,
279
280        /// Log type
281        #[arg(long = "type")]
282        log_type: String,
283
284        /// Read discussion data from stdin
285        #[arg(long)]
286        data_stdin: bool,
287    },
288
289    /// List events for a task
290    List {
291        /// Task ID
292        #[arg(long)]
293        task_id: i64,
294
295        /// Maximum number of events to return
296        #[arg(long)]
297        limit: Option<i64>,
298
299        /// Filter by log type (e.g., "decision", "blocker", "milestone", "note")
300        #[arg(long = "type")]
301        log_type: Option<String>,
302
303        /// Filter events created within duration (e.g., "7d", "24h", "30m")
304        #[arg(long)]
305        since: Option<String>,
306    },
307}