返回 CodeWhale
notice.rs
根目录 / crates / telemetry / src / notice.rs
1 //! The first-run notice copy.
2 //!
3 //! One string, owned by the crate that owns what is collected, so the TUI and
4 //! the CLI cannot drift into describing two different products. Every claim
5 //! below is checked against [`crate::event`] by a test: if the schema grows a
6 //! field this text does not cover, that test fails.
7 //!
8 //! Two properties of the wording are deliberate and load-bearing:
9 //!
10 //! 1. **The declining option is pre-selected and Enter takes it.** Enabling
11 //! requires a deliberate keystroke. There is no third option, no "improve
12 //! the product" checkbox, and nothing pre-checked.
13 //! 2. **The red lines are stated as "not collected", not as "anonymized".**
14 //! Sampling and hashing are not the same promise, and a notice that implies
15 //! them when neither is true is worse than no notice.
16
17 /// Headline shown above [`NOTICE_BODY`].
18 pub const NOTICE_HEADLINE: &str = "Help improve CodeWhale?";
19
20 /// The notice itself.
21 ///
22 /// Wrapped at 72 columns so it renders unchanged in a modal, in a pipe, and in
23 /// an 80-column terminal.
24 pub const NOTICE_BODY: &str = "\
25 CodeWhale can send anonymous usage counts: which version you run, your
26 OS and CPU family, which features you used, how long sessions ran, and
27 how they ended.
28
29 It never sends prompts, code, file names, paths, repo or branch names,
30 model output, model names, or credentials. Not sampled, not hashed —
31 not collected.
32
33 You are identified only by a random ID stored on this machine. It is
34 deleted the moment you turn this off, and it is replaced every 90 days.
35
36 Full schema, field by field: docs/TELEMETRY.md
37 Turn it off any time: codewhale config set telemetry false
38 or CODEWHALE_TELEMETRY=0";
39
40 /// The question, with the declining answer capitalised as the default.
41 pub const NOTICE_PROMPT: &str = "Enable telemetry? [y/N]";
42
43 /// The line printed once a decision is recorded, so the user has a receipt.
44 #[must_use]
45 pub fn decision_receipt(opt_in: bool) -> &'static str {
46 if opt_in {
47 "Telemetry is on. Turn it off any time with `codewhale config set telemetry false`."
48 } else {
49 "Telemetry stays off. You will not be asked again."
50 }
51 }
52
53 /// Whether a typed answer means yes.
54 ///
55 /// Everything else — an empty line, EOF, a closed pipe, `n`, a typo — means no.
56 /// That asymmetry is the point: only an affirmative answer is an affirmative
57 /// answer.
58 #[must_use]
59 pub fn answer_is_yes(input: &str) -> bool {
60 matches!(input.trim().to_ascii_lowercase().as_str(), "y" | "yes")
61 }
62
62 lines RUST