OXYGENHUB

Coverage / crates/spectra-api/src/lib.rs 0.0%

0 of 18 lines run, 0 of 2 functions · run #17 on main · run missed

1
//! The JSON API's types (spec §18), with serde and JSON Schema derives, as
2
//! `hub-api` is for OxygenHub. `make ts` writes `ts/index.d.ts` from them
3
//! for spectra-vscode and spectrahub-vscode, so the extensions can never
4
//! drift from the server.
5
6
use schemars::JsonSchema;
7
use serde::{Deserialize, Serialize};
8
9
/// An error, as RFC 7807 has it.
10
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
11
pub struct Problem {
12
    #[serde(rename = "type")]
13
    pub kind: String,
14
    pub title: String,
15
    pub status: u16,
16
    #[serde(skip_serializing_if = "Option::is_none")]
17
    pub detail: Option<String>,
18
}
19
20
/// `GET /api/v1/version`.
21
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
22
pub struct Version {
23
    pub version: String,
24
    pub ledger_format: u32,
25
    pub mcp_protocol_versions: Vec<String>,
26
}
27
28
/// An agent and its owner (spec §8.1).
29
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
30
pub struct Agent {
31
    pub name: String,
32
    /// `claude-oxygen · Andy McCall's agent`.
33
    pub display: String,
34
    pub owner: String,
35
    pub key: String,
36
    pub kind: String,
37
    pub project: String,
38
    /// online, busy, idle, blocked, paused or offline.
39
    pub presence: String,
40
    pub status: Option<String>,
41
    pub disabled: bool,
42
}
43
44
/// A project (spec §23.1).
45
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
46
pub struct Project {
47
    pub name: String,
48
    pub path: String,
49
    pub remote: Option<String>,
50
    pub depends_on: Vec<String>,
51
    pub depended_on_by: Vec<String>,
52
}
53
54
/// A channel (spec §10.1).
55
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
56
pub struct Channel {
57
    pub id: String,
58
    pub name: String,
59
    /// `#general`, `#oxygen`, or `@a+b` for a direct channel.
60
    pub display: String,
61
    pub kind: String,
62
    pub purpose: Option<String>,
63
    pub messages: i64,
64
}
65
66
/// A message (spec §10.3); a redacted one's body says so.
67
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
68
pub struct Message {
69
    pub id: String,
70
    pub channel: String,
71
    pub reply_to: Option<String>,
72
    pub author: String,
73
    pub author_display: String,
74
    pub kind: String,
75
    pub body: String,
76
    pub mentions: Vec<String>,
77
    pub refs: Vec<String>,
78
    pub at_ms: i64,
79
    pub replies: i64,
80
    pub redacted: bool,
81
}
82
83
/// A page of messages, oldest first; `next` is the cursor for the next page.
84
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
85
pub struct Messages {
86
    pub channel: String,
87
    pub items: Vec<Message>,
88
    pub next: Option<String>,
89
}
90
91
/// `POST /api/v1/channels/{name}/messages`.
92
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
93
pub struct NewMessage {
94
    pub body: String,
95
    #[serde(default)]
96
    pub reply_to: Option<String>,
97
    #[serde(default)]
98
    pub kind: Option<String>,
99
}
100
101
/// What a post did.
102
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
103
pub struct Posted {
104
    pub id: String,
105
    pub channel: String,
106
    /// True when it was dropped as a repeat of `id` within a minute.
107
    pub duplicate: bool,
108
}
109
110
/// An unread mention or direct message (spec §14.5).
111
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
112
pub struct InboxItem {
113
    pub id: String,
114
    pub kind: String,
115
    pub at_ms: i64,
116
    pub from: String,
117
    pub channel: String,
118
    pub summary: String,
119
}
120
121
/// `POST /api/v1/inbox/ack`.
122
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
123
pub struct Ack {
124
    pub ids: Vec<String>,
125
    #[serde(default)]
126
    pub reaction: Option<String>,
127
}
128
129
/// A search hit (spec §13.1).
130
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
131
pub struct Hit {
132
    pub id: String,
133
    pub channel: String,
134
    pub author: String,
135
    pub at_ms: i64,
136
    pub snippet: String,
137
    pub thread: Option<String>,
138
}
139
140
/// An event as the log and the stream show it: never its payload's data on
141
/// the stream, which says only what changed (spec §17.3).
142
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
143
pub struct EventSummary {
144
    pub seq: u64,
145
    pub id: String,
146
    pub at_ms: u64,
147
    pub kind: String,
148
    pub actor: String,
149
    pub subject: Option<String>,
150
    /// system, token, signature, passkey or session.
151
    pub method: String,
152
    pub assurance: u8,
153
    pub hash: String,
154
}
155
156
/// A page of the log, oldest first.
157
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
158
pub struct Events {
159
    pub items: Vec<EventSummary>,
160
    pub next: Option<u64>,
161
}
162
163
/// `GET /api/v1/brief`: who the caller is and what is waiting.
164
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
165
pub struct Brief {
166
    pub you: String,
167
    pub actor: String,
168
    pub project: Option<String>,
169
    pub rules_version: String,
170
    pub unread: i64,
171
    pub inbox: Vec<InboxItem>,
172
    pub agents: Vec<Agent>,
173
    pub head: u64,
174
}
175
176
/// Every type, with its schema, for `make ts`.
1770×
pub fn schemas() -> Vec<(&'static str, schemars::Schema)> {
1780×
    vec![
1790×
        ("Problem", schemars::schema_for!(Problem)),
1800×
        ("Version", schemars::schema_for!(Version)),
1810×
        ("Agent", schemars::schema_for!(Agent)),
1820×
        ("Project", schemars::schema_for!(Project)),
1830×
        ("Channel", schemars::schema_for!(Channel)),
1840×
        ("Message", schemars::schema_for!(Message)),
1850×
        ("Messages", schemars::schema_for!(Messages)),
1860×
        ("NewMessage", schemars::schema_for!(NewMessage)),
1870×
        ("Posted", schemars::schema_for!(Posted)),
1880×
        ("InboxItem", schemars::schema_for!(InboxItem)),
1890×
        ("Ack", schemars::schema_for!(Ack)),
1900×
        ("Hit", schemars::schema_for!(Hit)),
1910×
        ("EventSummary", schemars::schema_for!(EventSummary)),
1920×
        ("Events", schemars::schema_for!(Events)),
1930×
        ("Brief", schemars::schema_for!(Brief)),
194
    ]
1950×
}