1use crate::config::VaultLimits;
2use crate::domain::{
3 CandidateNote, LifecycleCandidate, MatchedModule, MatchedProject, MatchedScene,
4};
5use serde::{Deserialize, Serialize};
6use std::path::PathBuf;
7use ts_rs::TS;
8
9#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, TS)]
10#[serde(rename_all = "snake_case")]
11#[ts(export, export_to = "../frontend/src/lib/types/generated/")]
12pub enum TargetTool {
13 Claude,
14 Codex,
15 Opencode,
16}
17
18#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, TS)]
19#[serde(rename_all = "snake_case")]
20#[ts(export, export_to = "../frontend/src/lib/types/generated/")]
21pub enum OutputFormat {
22 Prompt,
23 Markdown,
24 Json,
25}
26
27impl OutputFormat {
28 pub fn as_str(self) -> &'static str {
29 match self {
30 Self::Prompt => "prompt",
31 Self::Markdown => "markdown",
32 Self::Json => "json",
33 }
34 }
35}
36
37#[derive(Debug, Clone, Serialize, TS)]
38#[ts(export, export_to = "../frontend/src/lib/types/generated/")]
39pub struct RouteInput {
40 pub task: String,
41 #[ts(type = "string")]
42 pub cwd: PathBuf,
43 pub files: Vec<String>,
44 pub target: TargetTool,
45 pub format: OutputFormat,
46}
47
48#[derive(Debug, Clone, Serialize, TS)]
49#[ts(export, export_to = "../frontend/src/lib/types/generated/")]
50pub struct DebugTrace {
51 pub matched_project_id: Option<String>,
52 pub note_roots: Vec<String>,
53 pub scan_roots: Vec<String>,
54 pub limits: VaultLimits,
55 pub note_count: usize,
56}
57
58#[derive(Debug, Clone, Serialize, TS)]
59#[ts(export, export_to = "../frontend/src/lib/types/generated/")]
60pub struct RouteResult {
61 pub project: Option<MatchedProject>,
62 pub modules: Vec<MatchedModule>,
63 pub scenes: Vec<MatchedScene>,
64 pub candidates: Vec<CandidateNote>,
65 #[serde(default)]
66 pub lifecycle_candidates: Vec<LifecycleCandidate>,
67 pub sources: Vec<String>,
68 pub debug: DebugTrace,
69 #[serde(default, skip_serializing_if = "Option::is_none")]
72 pub crystallize_hint: Option<String>,
73}