1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//! §1/§12 the seed — the app default-config, copied into a fresh landing.
//!
//! The trusted default capability set is config-time, not run-time: there is NO
//! runtime plugin magic, core only ever runs what the landing's `plugins.toml`
//! lists (§0). So the defaults live in a real folder a fresh `bl prime` copies
//! in — making the tracker + delivery plugins ordinary landing entries and the
//! default set swappable POLICY (an org ships its own seed) rather than core code
//! (severability, §1).
//!
//! **Bootstrap source.** The default-config is EMBEDDED in the binary
//! ([`include_str!`]) and written out to `$XDG_CONFIG_HOME/balls/default-config/`
//! on first prime when that folder is ABSENT — so a fresh `cargo install` or a
//! test binary run from `/tmp` always has a seed (no "run a script to get set
//! up"). The XDG folder is an OPTIONAL override: present, it wins, letting an
//! org/user customize the default capability set without touching core (§1).
//!
//! **Bind + prune.** Seeding binds each plugin the schedule names to its sibling
//! binary beside `bl` ([`Registry::bind`]) and PRUNES the hook entries whose
//! binary is absent here, so a tracker-less or test box never aborts (§12).
//! [`rebind`] re-establishes those local `bin/<name>` symlinks on an established
//! landing (a new machine / clone re-deriving the gitignored half), without
//! re-seeding or pruning the committed schedule.
use BTreeSet;
use fs;
use io;
use ;
use crateHooks;
use crateXdg;
use crateRegistry;
/// The embedded install-default `balls.toml` (§4) — the seed of last resort, used
/// to populate `$XDG_CONFIG_HOME/balls/default-config/` on first prime.
const EMBEDDED_BALLS: &str = include_str!;
/// The embedded install-default `plugins.toml` (§6) — the `[hooks]` schedule
/// wiring the shipped `tracker` + `bl-delivery` capabilities.
const EMBEDDED_PLUGINS: &str = include_str!;
/// Seed a fresh landing's `config/` from the default-config source (§12). Copies
/// `balls.toml` verbatim, then writes `plugins.toml` with each named plugin bound
/// to its sibling binary beside `bl` and every absent-binary entry PRUNED.
/// `exe_dir` is the directory holding `bl` (where the shipped siblings live);
/// `None` ⇒ a tracker-less box (every entry prunes, the chain runs empty).
/// Re-establish the local `bin/<name>` bindings for an established landing's
/// committed schedule (§12) — the gitignored half a new machine / clone must
/// re-derive. Idempotent; never prunes or rewrites the committed `plugins.toml`
/// (capabilities change only by `bl install`, never a re-prime).
/// Bind every plugin the `hooks` schedule names to its sibling binary beside
/// `bl`, when present, returning the set that resolved. Shared by [`seed_landing`]
/// (which prunes the rest) and [`rebind`] (which leaves the schedule untouched).
/// The path to a `name`d binary beside `bl` (in `exe_dir`), if it exists — how a
/// shipped sibling plugin is found (§6/§12). An absent `exe_dir` or missing
/// sibling ⇒ `None` (that plugin prunes from the seed; stays dangling on rebind).
/// Resolve the default-config source folder (§1): the XDG override
/// `$XDG_CONFIG_HOME/balls/default-config/` if it exists, else materialize the
/// embedded default there on first prime and use that. Either way the return is a
/// real on-disk folder [`seed_landing`] reads the two files from.
/// Copy `src` → `dest` when `src` exists; an absent source contributes nothing
/// (an override folder may omit a file — that field then falls to its default).