sync: embed synckit.toml via include_str! instead of option_env!
option_env!("SYNCKIT_API_KEY") silently evaluates to None when the env
var is missing at compile time, so a rebuild without the var loses sync
with no warning. Mirror the GoingsOn fix: bundle synckit.toml in the
project root and pull the key out with a small parser at startup. The
file is mandatory (include_str! fails the build if it's missing) and the
placeholder value cleanly disables sync until a real key is provisioned
on the MNW dashboard.
The API key is a public client identifier — safe to commit.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3 files changed,
+33 insertions,
-4 deletions
| 34 |
34 |
|
|
| 35 |
35 |
|
## SyncKit Parity with GoingsOn (2026-05-11) (remaining)
|
| 36 |
36 |
|
|
| 37 |
|
- |
- [ ] **synckit.toml** — create `synckit.toml` with BB's API key (need to create sync app on MNW dashboard first). Replace `option_env!("SYNCKIT_API_KEY")` in state.rs with `include_str!("../../synckit.toml")` + parser. Current approach breaks silently on recompile without env var.
|
|
37 |
+ |
- [x] **synckit.toml** — `include_str!("../../synckit.toml")` + `parse_synckit_toml_key()` parser in state.rs replaces `option_env!("SYNCKIT_API_KEY")`. File contains placeholder `REPLACE_WITH_BB_SYNC_API_KEY`; parser returns None for placeholder so sync stays cleanly disabled until a real key is provisioned.
|
|
38 |
+ |
- [ ] Register BB as a sync app on the MNW dashboard, then replace the placeholder in `synckit.toml` with the issued client identifier.
|
| 38 |
39 |
|
|
| 39 |
40 |
|
---
|
| 40 |
41 |
|
|
| 14 |
14 |
|
/// Default sync server URL.
|
| 15 |
15 |
|
pub const SYNC_SERVER_URL: &str = "https://makenot.work";
|
| 16 |
16 |
|
|
| 17 |
|
- |
/// Embedded SyncKit API key, set at build time via SYNCKIT_API_KEY env var.
|
| 18 |
|
- |
pub const EMBEDDED_API_KEY: Option<&str> = option_env!("SYNCKIT_API_KEY");
|
|
17 |
+ |
/// Bundled SyncKit config. Compile-time embed so a missing file is a build
|
|
18 |
+ |
/// error, not a silent runtime no-op. The API key is a public client
|
|
19 |
+ |
/// identifier, not a secret.
|
|
20 |
+ |
const SYNCKIT_TOML: &str = include_str!("../../synckit.toml");
|
|
21 |
+ |
|
|
22 |
+ |
/// Extract `api_key = "..."` from the bundled synckit.toml.
|
|
23 |
+ |
/// Returns None for an empty value or the unconfigured placeholder so
|
|
24 |
+ |
/// sync stays cleanly disabled until a real key is provisioned.
|
|
25 |
+ |
fn parse_synckit_toml_key() -> Option<&'static str> {
|
|
26 |
+ |
for line in SYNCKIT_TOML.lines() {
|
|
27 |
+ |
let line = line.trim();
|
|
28 |
+ |
if let Some(rest) = line.strip_prefix("api_key") {
|
|
29 |
+ |
let rest = rest.trim_start().strip_prefix('=')?.trim();
|
|
30 |
+ |
let key = rest.trim_matches('"');
|
|
31 |
+ |
if !key.is_empty() && key != "REPLACE_WITH_BB_SYNC_API_KEY" {
|
|
32 |
+ |
return Some(key);
|
|
33 |
+ |
}
|
|
34 |
+ |
}
|
|
35 |
+ |
}
|
|
36 |
+ |
None
|
|
37 |
+ |
}
|
| 19 |
38 |
|
|
| 20 |
39 |
|
/// Application state wrapping the Orchestrator
|
| 21 |
40 |
|
pub struct AppState {
|
| 200 |
219 |
|
return Some(key);
|
| 201 |
220 |
|
}
|
| 202 |
221 |
|
|
| 203 |
|
- |
EMBEDDED_API_KEY.map(String::from)
|
|
222 |
+ |
parse_synckit_toml_key().map(String::from)
|
| 204 |
223 |
|
}
|
| 205 |
224 |
|
|
| 206 |
225 |
|
/// Save API key to the data directory.
|
|
1 |
+ |
# SyncKit configuration — embedded in distribution builds.
|
|
2 |
+ |
# The API key is a client identifier (not a secret). It identifies this app
|
|
3 |
+ |
# to the MNW server. User authentication happens via OAuth2 PKCE.
|
|
4 |
+ |
#
|
|
5 |
+ |
# TODO: Replace the placeholder below with the real BB API key once the
|
|
6 |
+ |
# sync app has been registered on the MNW dashboard. While the placeholder
|
|
7 |
+ |
# is in place, parse_synckit_toml_key() returns None and sync is disabled.
|
|
8 |
+ |
api_key = "REPLACE_WITH_BB_SYNC_API_KEY"
|
|
9 |
+ |
server_url = "https://makenot.work"
|