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
//! Project (balls-clone) enumeration and nested-delivery detection
//! (DESIGN §5.1 #1, §15 Y14).
//!
//! A **project** is one balls invocation path — the `bl` control plane keys its
//! per-project state at `$XDG_STATE_HOME/balls/clones/<percent-encoded-path>/`
//! (balls arch §1). The project's *identity* is the decoded path, and it is the
//! cwd every `bl … --json` runs in ([`balls`], DESIGN §5.1 #2). Enumeration is
//! therefore `readdir + percent-decode basename` — one query, nothing stored.
//!
//! **Nested-delivery detection** (§5.1 #1): a decoded path that itself lies
//! under the balls `plugins/bl-delivery/` tree is a ball's own work-worktree
//! that became a balls project — an *internal* clone. The UI hides internal
//! clones by default behind a toggle whose durable state is a `ui.json`
//! collapsed-style override (§4.1 `collapsed`: "explicit user expansion
//! overrides only"); the pure [`visible`] filter takes that resolved bool so
//! this module stays free of `ui_state` (the [`crate::nav`] discipline).
use cratepercent_decode;
use ;
/// One enumerated balls project (§5.1 #1). `path` is the decoded invocation
/// path — the identity and the `bl` cwd; `internal` flags a nested-delivery
/// clone (hidden by default, [`visible`]). Both are derived from the clone
/// basename alone — nothing about the project is stored by yog.
/// The bl-delivery territory a nested-delivery clone lives under, derived from
/// the clones dir (its parent is the balls state root; balls arch §1). `None`
/// only when `clones_dir` has no parent — then no path can be internal.
/// True iff `project` (a decoded invocation path) lies under the bl-delivery
/// tree — a ball's own worktree that became a balls project (§5.1 #1).
/// Enumerate every balls project under `clones_dir` (§5.1 #1): each child dir's
/// basename percent-decodes to the project path, flagged `internal` when it
/// falls under bl-delivery. Sorted by path for a stable roster. A missing or
/// unreadable clones dir yields an empty Vec — the general path with no inputs,
/// not a bootstrap special case (the [`crate::binding`] discipline).
/// The projects shown under the "internal" toggle (§5.1 #1): every project when
/// `show_internal`, else only the non-internal clones. Pure over the resolved
/// toggle bool — the caller derives it from the `ui.json` collapsed override.