Commit graph

7 commits

Author SHA1 Message Date
CRT
f6deac4145 DOM hub: open shadow roots of hosts a site names are part of the page
X renders its chat inside an open shadow root since 2026-10-01 (the XChatEmbed
host [data-testid=xchatEmbedRoute]); the hub's document observer saw nothing
of it, selector observers found nothing, feature sheets in <head> did not
reach it and probes could not see it.

A site adapter may name shadowHosts. The hub's one MutationObserver then also
observes each such root (picked up on the next page mutation, or a few timed
retries while a host has no root yet; dropped with the observer), selector
observers search the roots too, domRoots(win) gives features the roots, a
feature's ctx.css sheet is also adopted by each root (CSP-proof, updated in
place, taken off on stop), and probes count matches inside the roots.
Tests: hub observes and searches a root that appears later with one
observer; registry adopts and removes the sheet and a probe inside a root is
never a miss.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 05:02:01 +07:00
CRT
26658e14ae Modes: a mode that no longer matches the features reads "Custom (based on <mode>)" and offers "Re-apply <mode>"
A mode is a starting point, never a lock and never applied again on its own. modeStatus() (runtime)
compares the flags with the mode's preset: custom, what re-applying turns on and off, and which of
those the preset gained in an update since it was applied. mode_set keeps the preset of that moment
(modes.json "preset", flag names only, bounded; forgotten when the mode changes). Settings, the
first-run screen and the app menu's Mode row show Custom; Re-apply lists what it turns on and off
before it writes anything; a preset that grew is mentioned once on the mode row (Review), never applied.
Tests: exact match, changed by the owner, preset grew, choice made before the preset was kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 03:33:41 +07:00
CRT
632ba863c9 Feature health on the area cards: a feature that paused itself is named by its area's "health" palette entry, and the panel reads it for the row and the card (no new report to the host)
The entry opens the notes in the page; its keywords carry the paused flags of that area. English
for the three new words; the other catalogs follow with the words step.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 22:00:04 +07:00
CRT
eed6bdd8f4 Route listeners: one removed by an earlier listener in the same round is not called (a feature stopped by the route re-added its stylesheet); the route poll never keeps a test process alive
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 21:19:02 +07:00
CRT
046f409d23 Feature modules: a feature ported from a plugin keeps that plugin's words (words), so nothing is retranslated; the keep-my-changes question takes its own line
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 19:53:11 +07:00
CRT
381d55466b Feature modules in a new app, i18n rename, and what the first area port needed
- create-waybetter: the generated app has a feature table (one area, one feature, three modes), a feature module, the registry in its runtime, the cards and the first-run screen in its panel
- waybetter i18n rename --map <file> [--copy]: keys move or are copied in every catalog with each language's own value
- feature context: win (no globals in a module), text() for a feature's words (t('...') is read as a whole catalog key by the i18n tools)
- probes: `when` (only counts while the part of the page it lives in is there)
- cards: a caret, an empty area says its features come later; the first-run screen takes the whole panel

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 19:25:15 +07:00
CRT
ca9eec05ab Feature modules: a feature table (areas, flags, modes), a registry that runs a module only on its surfaces, one shared observer for every feature and plugin, settings from a schema, selector health with self-pause
- featureTable.ts: areas, per-feature flags, core flags, modes as presets; sparse storage, ownership (an area that is off turns off what it owns), mode switching that keeps or drops manual changes, table validation
- featureModules.ts: createFeatureRegistry (flag + surface gating, scoped context, palette commands under the area with a budget of 5, settings dialog, probes, hotfix selector overrides and kill flags)
- settingsForm.ts: a settings schema normalizes stored values and draws the controls from the UI kit
- domHub observeSelector; api.observe goes through the shared hub (a root of the caller's own keeps its observer)
- createFeatureFlags: a delivery is the whole state (a flag it does not name is at its default), resolve() for ownership, current()

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 18:11:42 +07:00