Skip to main content

flow_core/
task.rs

1use serde::{Deserialize, Serialize};
2
3/// A task from Claude Code's JSON file format (~/.claude/tasks/{session}/{id}.json).
4#[derive(Debug, Clone, Serialize, Deserialize)]
5#[serde(rename_all = "camelCase")]
6pub struct Task {
7    pub id: String,
8    pub subject: String,
9    #[serde(default)]
10    pub description: String,
11    #[serde(default, rename = "activeForm")]
12    pub active_form: String,
13    #[serde(default)]
14    pub status: String,
15    #[serde(default)]
16    pub owner: String,
17    #[serde(default)]
18    pub blocks: Vec<String>,
19    #[serde(default, rename = "blockedBy")]
20    pub blocked_by: Vec<String>,
21}
22
23/// Session list item for the web UI.
24#[derive(Debug, Clone, Serialize)]
25#[serde(rename_all = "camelCase")]
26pub struct SessionListItem {
27    pub id: String,
28    pub name: Option<String>,
29    pub slug: Option<String>,
30    pub project: Option<String>,
31    pub description: Option<String>,
32    pub git_branch: Option<String>,
33    pub task_count: usize,
34    pub completed: usize,
35    pub in_progress: usize,
36    pub pending: usize,
37    pub created_at: Option<String>,
38    pub modified_at: String,
39}
40
41/// A task with its session context.
42#[derive(Debug, Clone, Serialize)]
43#[serde(rename_all = "camelCase")]
44pub struct TaskWithSession {
45    #[serde(flatten)]
46    pub task: Task,
47    pub session_id: String,
48    pub session_name: Option<String>,
49    pub project: Option<String>,
50}
51
52/// Session metadata extracted from JSONL files.
53#[derive(Debug, Clone, Default)]
54pub struct SessionMeta {
55    pub custom_title: Option<String>,
56    pub slug: Option<String>,
57    pub project_path: Option<String>,
58    pub description: Option<String>,
59    pub git_branch: Option<String>,
60    pub created: Option<String>,
61}
62
63impl SessionMeta {
64    /// Get display name: customTitle > slug > None.
65    pub fn display_name(&self) -> Option<String> {
66        self.custom_title.clone().or_else(|| self.slug.clone())
67    }
68}