Skip to content

feat(page): connect the page.effect verb to a host-effect registry - #286

Merged
omridevk merged 2 commits into
page-chain-269from
effect-verb-227
Aug 7, 2026
Merged

feat(page): connect the page.effect verb to a host-effect registry#286
omridevk merged 2 commits into
page-chain-269from
effect-verb-227

Conversation

@omridevk

@omridevk omridevk commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Stacked on #284; retarget after it merges.

Closes #227

What

The page.effect verb was a permanent stub (effects not initialized). It now drives real host-registered effects:

  • Registry shape: an extension's client() factory may return effects: [{name, description, set(enabled), enabled()}] alongside value/dispose. The mount collects them off the mounted extension instances (collectClientEffects, mirror of collectClientTools), hands them to makeDomPageDriver({tools, effects}), and the dispatcher exposes them on ClientToolCtx.effects. No window globals, no module-level state — effect state lives in the factory closure, per mount.
  • Verb behavior: enable/start, disable/stop, toggle, report, list (default). Unknown name fails with the declared UNKNOWN_EFFECT error naming what is registered; a driving action without --effect is invalid-args pointing at list.
  • First real effect: the conciv app's highlight inspector registers as highlight; Alt-hold and effect-driven activation share one derived active(), and Escape clears both.
  • Catalog honesty: the declaration now describes the real capability, declares mutating: true (enable/disable change page presentation, so calls journal like other edits), a strict output union, and the declared error code. The CLI derives conciv page effect --effect X --action Y from this signature unchanged.

Tests

  • New browser IT (packages/extensions/page/test/effects.browser.test.ts): enabling a registered effect visibly changes the page, disable reverts, toggle flips, start/stop alias, list reports with per-name dedupe, unknown name = declared error — replaces the stub schema-parse test.
  • Embed IT (page-dispatch-boot.it.test.ts): end-to-end over the real widget bundle — page.effect enable highlight shows the inspector overlay on the host page, disable removes it, toggle flips, unknown rejects with UNKNOWN_EFFECT.

🤖 Generated with Claude Code

omridevk and others added 2 commits August 7, 2026 10:26
Hosts register named effects from their extension client factory
({name, description, set, enabled}); the mount collects them off the
mounted extension instances exactly like client tools and hands them to
the dom page driver, which exposes them on the client tool ctx. The
page.effect body drives them for real: enable/disable/toggle/start/stop
flip an effect, report reads it, list names what exists, and an unknown
name fails with the declared UNKNOWN_EFFECT error. The highlight
inspector in the conciv app is the first registered effect, and the
declaration now advertises the real capability (mutating, honest output
union) instead of the documented stub.

Closes #227

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…owner, list rejects effect arg, report covers disabled

- makeDomPageDriver.dispose() now calls effect.set(false) for every
  effect left enabled, so host-DOM-mutating effects can't leak past
  widget/driver teardown.
- collectClientEffects warns naming both the kept and dropped
  extension when a later extension declares a colliding effect name.
- page.effect action:list now rejects a passed effect name as
  invalid-args instead of silently ignoring it.
- Adds the missing report-on-disabled-effect matrix cell.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@omridevk
omridevk merged commit 1c83abe into main Aug 7, 2026
22 checks passed
@omridevk
omridevk deleted the effect-verb-227 branch August 7, 2026 08:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

page: the effect verb is a permanent stub — connect it for real

1 participant