Skip to main content

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}