for each in {1..${#_extras[@]}} doesn't expand as a range - bash does
brace expansion before parameter expansion, so the range endpoint
isn't resolved yet when brace expansion runs. The loop always ran
exactly once, leaving preselect at length 1 regardless of how many
extras exist. Invisible until now because there was only ever one
extra (model-cache-redirect); would have silently broken any
preselected-true default on a 2nd+ extra. Switched to a C-style loop.
This is almost certainly the multiselect misbehavior from years back -
tracked down while verifying multiselect() itself (functions/PRbL
submodule, fixed separately) didn't have a toggle-isolation bug.
Adds a manifest-driven "Install CircuitForge Apps" menu to install.sh,
alongside the existing extras-menu pattern.
- cf-apps/*.manifest: one file per product (circuitforge-core, peregrine,
kiwi, snipe, turnstone, pagepiper, linnet - the beta/alpha menagerie
products), declaring repo URLs, supported install types, conda env,
.env template, and per-install-type setup hooks. Hooks prefer shelling
out to each product's own install.sh/Makefile/docker-compose rather
than reimplementing their setup logic.
- lib/cf-apps.functions: registry loader, provisioning-profile prompt
(oem/collaborator/orchard), app multiselect menu, and the install
dispatcher (clone, .env bootstrap, install-type selection, hook
dispatch). circuitforge-core installs automatically as a dependency
for apps that declare app_needs_core=true.
Provisioning profiles gate both which apps are offered and which remote
credentials are used:
- oem: public CircuitForgeLLC GitHub mirrors only, no Forgejo access,
no circuitforge-orch (product install menu only)
- collaborator: private Circuit-Forge Forgejo, same product menu
- orchard: narrow flow, not the product menu - clones circuitforge-orch
(Forgejo-only, no public mirror exists) and hands off interactively to
its own install.sh, which gathers agent/coordinator topology itself
(it has no --topology/--coordinator-url flags to script around).
NOTE: circuitforge-orch has no model-sync/cache-sync mechanism today
(checked its install.sh and README); this wrapper doesn't invent one.
Design rationale and survey of each product's real install story:
circuitforge-plans/cf-node-bootstrap/superpowers/plans/2026-07-17-cf-apps-install-menu.md
bc is required by power monitoring functions for floating-point math
and was missing from the apt packages list, causing failures on
minimal installs like RPiOS Lite.
Slipstream.install and golang.install extras removed as they are
no longer maintained here.