objectiveai_sdk/cli/output/notification/updater.rs
1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4/// Wire shapes emitted by `crate::updater::maybe_auto_update`. Every
5/// non-cooldown skip path AND every active step emits one of these.
6/// The ONLY silent path is the 2-hour marker cooldown — when the marker
7/// says we already checked within the time frame, the updater exits
8/// without emission.
9///
10/// Errors are emitted as `super::super::Output::Error` (level=warn,
11/// fatal=false), not as a variant here.
12///
13/// Wire (in combination with `super::super::Output::Notification` +
14/// `super::Notification`'s `value` wrapper):
15/// `{"type":"notification","value":{"event":"checking",...}}`.
16#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema)]
17#[serde(tag = "event", rename_all = "snake_case")]
18#[schemars(rename = "cli.output.notification.Updater")]
19pub enum Updater {
20 /// Skipped this run for a non-cooldown reason. (Cooldown is silent.)
21 #[schemars(title = "Skipped")]
22 Skipped {
23 reason: SkipReason,
24 },
25 /// All gates passed; about to call
26 /// `GET /repos/ObjectiveAI/objectiveai/releases/latest`. The very
27 /// first emitted line of any active update run.
28 #[schemars(title = "Checking")]
29 Checking {
30 asset_name: String,
31 current_version: String,
32 },
33 /// GitHub returned the latest release tag and it's ≤ current.
34 /// Terminal — no more events follow.
35 #[schemars(title = "UpToDate")]
36 UpToDate {
37 current_version: String,
38 remote_version: String,
39 },
40 /// Found a newer release with our asset attached; about to download.
41 #[schemars(title = "Found")]
42 Found {
43 current_version: String,
44 remote_version: String,
45 asset_name: String,
46 url: String,
47 },
48 /// Swap complete; the next line of output will come from the
49 /// re-exec'd new binary, not this one. Terminal for the current
50 /// process.
51 #[schemars(title = "Installed")]
52 Installed {
53 current_version: String,
54 remote_version: String,
55 },
56}
57
58/// Reasons the updater can skip a run *and emit a notification about it*.
59/// The 2-hour marker cooldown is NOT included here because cooldown
60/// skips are silent (no notification emitted).
61#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema)]
62#[serde(rename_all = "snake_case")]
63#[schemars(rename = "cli.output.notification.SkipReason")]
64pub enum SkipReason {
65 /// Host OS/arch combination doesn't have a release asset.
66 #[schemars(title = "UnsupportedPlatform")]
67 UnsupportedPlatform,
68 /// `OBJECTIVEAI_SKIP_UPDATE` env var is set. The updater respects
69 /// this so re-exec'd children don't loop, and so users can disable
70 /// auto-update by setting it.
71 #[schemars(title = "OptedOut")]
72 OptedOut,
73 /// Binary is running out of a `target*/` directory — looks like a
74 /// dev build (`cargo run`), not an installed binary.
75 #[schemars(title = "DevTree")]
76 DevTree,
77}