Both the screenshot 'all on' test and the bridge mock seed were
hand-maintaining a parallel array of preview feature ids. tier
transitions (e.g. promoting huddles to stable) required updating
two places that the type system couldn't help us with.
Add tests/helpers/features.ts as a single source of truth that
imports /features.json directly and filters tier === 'preview'.
The 'all on' test now loops over PREVIEW_FEATURE_IDS, and bridge.ts
re-uses the same constant for its localStorage seeding.
12/12 screenshot-feature-flags tests pass locally.
Signed-off-by: npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w <52a228d6edf316ec6812ac3c9fc0d696ab59fc7954d77e7be31eedcddf91335b@sprout-oss.stage.blox.sqprod.co>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
CI was failing 16 smoke tests (workflows.spec, channels.spec, smoke.spec,
file-attachment.spec) because preview-gated UI (workflows, forum, pulse,
projects) didn't render in mock-bridge tests. Tests clicked testIDs that
were behind <FeatureGate>, timing out.
- bridge.ts: seed sprout-feature-overrides-v1 in localStorage with all
preview feature IDs enabled by default via addInitScript. New
seedPreviewFeatures option (default true) opts out for specs that
exercise the toggle UI itself.
- screenshot-feature-flags.ts: pass seedPreviewFeatures: false so the
Experiments toggle flow still drives each feature on via the UI.
59/59 affected smoke tests passing locally.
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Remove huddles entry from features.json (stable = no manifest entry)
- Unwrap FeatureGate wrappers in AppShell.tsx and ChannelMembersBar.tsx
- Remove unused FeatureGate imports
- Remove huddles screenshot test and view-huddles.png
- Remove huddles toggle from 'all on' test (now 4 features)
12/12 E2E tests passing.
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Rename sidebar label from 'Experimental' to 'Experiments'
- Add h2 title in main body to match other settings panels
- Fix biome formatting: collapse FeatureGate JSX, expand sections array
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Rewrote screenshot-feature-flags.ts: removed stale 'unstable' tier
references (relay-members, identity-archive), updated close button
selector to settings-back-to-app
- Deleted all old screenshots + feature-flags-tour/ artifacts
- Regenerated 13 fresh screenshots matching current UI
- Added Experiments nav group to SettingsView (was defined but missing
from settingsNavGroups)
- Registered test in playwright.config.ts smoke project
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Wrap HuddleIndicator in ChannelMembersBar with FeatureGate
- Wrap HuddleBar in AppShell with FeatureGate
- Keep HuddleProvider in place (useHuddle called unconditionally elsewhere)
- Huddles now properly hidden when preview toggle is off
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Remove 'unstable' from FeatureTier type and resolveEnabled logic
- Remove identity-archive and relay-members from manifest (stable, permission-gated)
- Move mesh-compute to preview tier
- Flatten ExperimentalFeaturesCard to simple list (no disclosure/badges)
- Fix semantic HTML: replace <label> with <div> + aria-labelledby
- Remove featureGate from relay-members settings (role-gated only)
- Remove unstable tier tests
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Rename tab label from 'Preview & Unstable' to 'Experimental'
- Show preview features as a flat list (no section heading)
- Add collapsible disclosure button at bottom to reveal unstable features
- Unstable rows get a warning badge; otherwise visually identical to preview rows
- Collapsed/expanded state is local (not persisted)
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Detect existing installs via prior localStorage keys (sprout-theme,
sprout-workspaces). New installs get clean opt-in; existing users
keep features they were already using.
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
1. Migration: existing users auto-seed experimental features as enabled
on first load (no feature loss on upgrade). New installs get opt-in UX.
2. Reactivity: SettingsView uses useFeatureSnapshot() so section list
updates instantly when toggles change (fixes stale useMemo deps).
3. Standards: Switch component replaces raw checkboxes, data-testid on
every toggle (feature-toggle-{id}, feature-toggle-dev-global).
4. Tests: 11 unit tests for resolveEnabled covering all tiers + edge cases.
5. Architecture: @features-manifest Vite alias replaces fragile ../../../../
relative import. Test loader also resolves the alias.
6. Versioned localStorage: keys now use -v1 suffix aligned to manifest version.
7. Cache: JSON.parse result cached across hook instances per render cycle.
8. Dev warning: console.warn in dev when getFeature() returns undefined.
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Add features.json manifest at repo root (single source of truth)
- Implement useFeatureEnabled hook + FeatureGate component
- Add ExperimentalFeaturesCard settings panel with opt-in toggles
- Gate sidebar items: managed-agents, projects, workflows
- Gate settings sections via featureGate descriptor field
- Three tiers: stable (always on), experimental (opt-in), dev (dev-only)
- Global 'Show developer features' toggle for dev tier suppression
- localStorage persistence for user overrides
- Designed for Flutter consumption (JSON manifest, platforms field)
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>