@dxos/plugin-crx 0.0.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/lib/CrxCapabilities.mjs.map +1 -1
  2. package/dist/lib/capabilities.browser.mjs +39 -0
  3. package/dist/lib/capabilities.browser.mjs.map +1 -0
  4. package/dist/lib/capabilities.mjs +1 -3
  5. package/dist/lib/capabilities.mjs.map +1 -1
  6. package/dist/lib/capabilities.tauri.mjs +39 -0
  7. package/dist/lib/capabilities.tauri.mjs.map +1 -0
  8. package/dist/lib/chunk-PLUGIN.mjs +6 -0
  9. package/dist/lib/chunk-PLUGIN.mjs.map +1 -0
  10. package/dist/lib/chunk-install-page-actions.mjs +2 -2
  11. package/dist/lib/chunk-react-surface.mjs +2 -2
  12. package/dist/lib/chunk-react-surface.mjs.map +1 -1
  13. package/dist/lib/chunk-settings.mjs +2 -2
  14. package/dist/lib/chunk-settings.mjs.map +1 -1
  15. package/dist/lib/containers.mjs +12 -10
  16. package/dist/lib/containers.mjs.map +1 -1
  17. package/dist/lib/index.mjs +0 -1
  18. package/dist/lib/translations.mjs.map +1 -1
  19. package/dist/types/src/capabilities/gen/browser.d.ts +9 -0
  20. package/dist/types/src/capabilities/gen/browser.d.ts.map +1 -0
  21. package/dist/types/src/capabilities/gen/tauri.d.ts +9 -0
  22. package/dist/types/src/capabilities/gen/tauri.d.ts.map +1 -0
  23. package/dist/types/src/containers/CrxSettings/CrxSettings.d.ts +1 -1
  24. package/dist/types/src/containers/CrxSettings/CrxSettings.d.ts.map +1 -1
  25. package/dist/types/src/index.d.ts +0 -1
  26. package/dist/types/src/index.d.ts.map +1 -1
  27. package/dist/types/src/stories/Testbench.stories.d.ts.map +1 -1
  28. package/dist/types/src/translations.d.ts.map +1 -1
  29. package/dist/types/src/types/CrxCapabilities.d.ts +1 -1
  30. package/dist/types/src/types/CrxCapabilities.d.ts.map +1 -1
  31. package/dist/types/tsconfig.tsbuildinfo +1 -1
  32. package/package.json +27 -25
  33. package/src/capabilities/gen/browser.ts +54 -0
  34. package/src/capabilities/gen/tauri.ts +54 -0
  35. package/src/capabilities/react-surface.ts +2 -2
  36. package/src/capabilities/settings.ts +2 -2
  37. package/src/containers/CrxSettings/CrxSettings.stories.tsx +1 -1
  38. package/src/containers/CrxSettings/CrxSettings.tsx +15 -12
  39. package/src/index.ts +0 -1
  40. package/src/stories/Testbench.stories.tsx +4 -3
  41. package/src/translations.ts +2 -2
  42. package/src/types/CrxCapabilities.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"CrxCapabilities.mjs","names":[],"sources":["../../src/types/CrxCapabilities.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// @import-as-namespace\n\nimport type * as Atom from 'effect/unstable/reactivity/Atom';\n\nimport * as Capability from '@dxos/app-framework/Capability';\n\nimport { meta } from '#meta';\n\n/**\n * Writable atom holding the plugin's Settings.\n */\nexport const Settings = Capability.makeSingleton<Atom.Writable<import('./Settings.ts').Settings>>()(\n `${meta.profile.key}.capability.settings`,\n);\n\n/**\n * Page actions contributed by plugins for the browser extension to surface.\n * Multi: each contributor provides one array (e.g. plugin-bookmarks); consumers flatten via `getAll`.\n */\nexport const PageAction = Capability.make<import('./PageAction.ts').PageAction[]>()(\n `${meta.profile.key}.capability.pageAction`,\n);\n"],"mappings":";;;;;;;;;;;AAeA,IAAa,WAAW,WAAW,cAA+D,CAAC,CACjG,GAAG,KAAK,QAAQ,IAAI,qBACtB;;;;;AAMA,IAAa,aAAa,WAAW,KAA6C,CAAC,CACjF,GAAG,KAAK,QAAQ,IAAI,uBACtB"}
1
+ {"version":3,"file":"CrxCapabilities.mjs","names":[],"sources":["../../src/types/CrxCapabilities.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// @import-as-namespace\n\nimport type * as Atom from 'effect/reactivity/Atom';\n\nimport * as Capability from '@dxos/app-framework/Capability';\n\nimport { meta } from '#meta';\n\n/**\n * Writable atom holding the plugin's Settings.\n */\nexport const Settings = Capability.makeSingleton<Atom.Writable<import('./Settings.ts').Settings>>()(\n `${meta.profile.key}.capability.settings`,\n);\n\n/**\n * Page actions contributed by plugins for the browser extension to surface.\n * Multi: each contributor provides one array (e.g. plugin-bookmarks); consumers flatten via `getAll`.\n */\nexport const PageAction = Capability.make<import('./PageAction.ts').PageAction[]>()(\n `${meta.profile.key}.capability.pageAction`,\n);\n"],"mappings":";;;;;;;;;;;AAeA,IAAa,WAAW,WAAW,cAA+D,CAAC,CACjG,GAAG,KAAK,QAAQ,IAAI,qBACtB;;;;;AAMA,IAAa,aAAa,WAAW,KAA6C,CAAC,CACjF,GAAG,KAAK,QAAQ,IAAI,uBACtB"}
@@ -0,0 +1,39 @@
1
+ import { t as PLUGIN_default } from "./chunk-PLUGIN.mjs";
2
+ import * as ActivationEvents from "@dxos/app-framework/ActivationEvents";
3
+ import * as Capabilities from "@dxos/app-framework/Capabilities";
4
+ import * as Capability from "@dxos/app-framework/Capability";
5
+ import * as AppCapability from "@dxos/app-toolkit/AppCapability";
6
+ import { translations } from "#translations";
7
+ import { CrxCapabilities, CrxEvents } from "#types";
8
+ import { meta } from "#meta";
9
+ //#region src/capabilities/gen/browser.ts
10
+ var CrxSettings = AppCapability.settings(() => import("./chunk-settings.mjs"), {
11
+ activatesOn: ActivationEvents.Idle,
12
+ provides: [CrxCapabilities.Settings]
13
+ });
14
+ var InstallPageActions = Capability.lazyModule("InstallPageActions", {
15
+ requires: [
16
+ Capabilities.OperationInvoker,
17
+ Capabilities.AtomRegistry,
18
+ CrxCapabilities.Settings
19
+ ],
20
+ provides: [],
21
+ activatesOn: CrxEvents.Start
22
+ }, () => import("./chunk-install-page-actions.mjs"));
23
+ var OperationHandler = AppCapability.operationHandler(() => import("./chunk-operation-handler.mjs"), { activatesOn: ActivationEvents.Idle });
24
+ var PageActionProvider = Capability.lazyModule("PageActionProvider", {
25
+ provides: [CrxCapabilities.PageAction],
26
+ activatesOn: CrxEvents.Start
27
+ }, () => import("./chunk-page-action-provider.mjs"));
28
+ var PluginAsset = AppCapability.pluginAsset({
29
+ pluginId: meta.profile.key,
30
+ path: "PLUGIN.mdl",
31
+ content: PLUGIN_default,
32
+ mimeType: "application/x-mdl"
33
+ });
34
+ var ReactSurface = AppCapability.surface(() => import("./chunk-react-surface.mjs"), { roles: ["org.dxos.role.article"] });
35
+ var Translations = AppCapability.translations(translations);
36
+ //#endregion
37
+ export { CrxSettings, InstallPageActions, OperationHandler, PageActionProvider, PluginAsset, ReactSurface, Translations };
38
+
39
+ //# sourceMappingURL=capabilities.browser.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.browser.mjs","names":[],"sources":["../../src/capabilities/gen/browser.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// GENERATED by dx-plugin — do not edit. Sliced from ../index.ts for the 'browser' condition.\n\nimport * as ActivationEvents from '@dxos/app-framework/ActivationEvents';\nimport * as Capabilities from '@dxos/app-framework/Capabilities';\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\n\nimport { meta } from '#meta';\nimport { translations } from '#translations';\nimport { CrxCapabilities, CrxEvents } from '#types';\n\nimport pluginSpec from '../../../PLUGIN.mdl?raw';\n\nexport const CrxSettings = AppCapability.settings(() => import('../settings.ts'), {\n activatesOn: ActivationEvents.Idle,\n provides: [CrxCapabilities.Settings],\n});\n\nexport const InstallPageActions = Capability.lazyModule(\n 'InstallPageActions',\n {\n requires: [Capabilities.OperationInvoker, Capabilities.AtomRegistry, CrxCapabilities.Settings],\n provides: [],\n activatesOn: CrxEvents.Start,\n },\n () => import('../install-page-actions.ts'),\n);\n\nexport const OperationHandler = AppCapability.operationHandler(() => import('../operation-handler.ts'), {\n activatesOn: ActivationEvents.Idle,\n});\n\nexport const PageActionProvider = Capability.lazyModule(\n 'PageActionProvider',\n { provides: [CrxCapabilities.PageAction], activatesOn: CrxEvents.Start },\n () => import('../page-action-provider.ts'),\n);\n\nexport const PluginAsset = AppCapability.pluginAsset({\n pluginId: meta.profile.key,\n path: 'PLUGIN.mdl',\n content: pluginSpec,\n mimeType: 'application/x-mdl',\n});\n\nexport const ReactSurface = AppCapability.surface(() => import('../react-surface.ts'), {\n roles: ['org.dxos.role.article'],\n});\n\nexport const Translations = AppCapability.translations(translations);\n"],"mappings":";;;;;;;;;AAiBA,IAAa,cAAc,cAAc,eAAe,OAAO,yBAAmB;CAChF,aAAa,iBAAiB;CAC9B,UAAU,CAAC,gBAAgB,QAAQ;AACrC,CAAC;AAED,IAAa,qBAAqB,WAAW,WAC3C,sBACA;CACE,UAAU;EAAC,aAAa;EAAkB,aAAa;EAAc,gBAAgB;CAAQ;CAC7F,UAAU,CAAC;CACX,aAAa,UAAU;AACzB,SACM,OAAO,mCACf;AAEA,IAAa,mBAAmB,cAAc,uBAAuB,OAAO,kCAA4B,EACtG,aAAa,iBAAiB,KAChC,CAAC;AAED,IAAa,qBAAqB,WAAW,WAC3C,sBACA;CAAE,UAAU,CAAC,gBAAgB,UAAU;CAAG,aAAa,UAAU;AAAM,SACjE,OAAO,mCACf;AAEA,IAAa,cAAc,cAAc,YAAY;CACnD,UAAU,KAAK,QAAQ;CACvB,MAAM;CACN,SAAS;CACT,UAAU;AACZ,CAAC;AAED,IAAa,eAAe,cAAc,cAAc,OAAO,8BAAwB,EACrF,OAAO,CAAC,uBAAuB,EACjC,CAAC;AAED,IAAa,eAAe,cAAc,aAAa,YAAY"}
@@ -1,3 +1,4 @@
1
+ import { t as PLUGIN_default } from "./chunk-PLUGIN.mjs";
1
2
  import * as ActivationEvents from "@dxos/app-framework/ActivationEvents";
2
3
  import * as Capabilities from "@dxos/app-framework/Capabilities";
3
4
  import * as Capability from "@dxos/app-framework/Capability";
@@ -5,9 +6,6 @@ import * as AppCapability from "@dxos/app-toolkit/AppCapability";
5
6
  import { translations } from "#translations";
6
7
  import { CrxCapabilities, CrxEvents } from "#types";
7
8
  import { meta } from "#meta";
8
- //#region PLUGIN.mdl?raw
9
- var PLUGIN_default = "---\nid: org.dxos.plugin.crx\nname: CrxPlugin\nversion: 0.3.0\n---\n\nCoordinates with the `@dxos/composer-crx` browser extension. Owns the Composer\nside of the page-actions bridge: plugins contribute page actions (serializable\ndescriptor + target operation) under a plugin-scoped capability; the extension\ncaches the descriptors in its registry and invokes them over same-origin\n`window` `CustomEvent`s. This plugin answers registry-list requests, validates\ninvoke requests, resolves the active space, executes the target operation, and\nsurfaces outcomes as toasts. It also contributes three picker actions\n(Person, Organization, Note) whose operations map a page snapshot to an ECHO\nobject, and owns the user-facing settings surface — including the render-proxy\nsettings (absorbed from the retired plugin-extension) for the extension's\npage-rendering facility.\n\nThe extension owns the DOM picker, popup toolbar, extractors, and bridge\nsender; this plugin owns envelope validation, snapshot → ECHO object mapping,\nand user feedback (toast). The extension keeps a hand-validated mirror of the\nwire types at `packages/apps/composer-crx/src/page-actions/types.ts` which\nmust be updated in lockstep.\n\n## Extensions\n\nThe following extension dialects are used in this document.\nEach extension is defined in the Appendix or resolved via its URI.\n\n| Term | URI |\n|--------|--------------------------------|\n| `type` | `org.dxos.mdl.type@1.0` |\n| `feat` | `org.dxos.mdl.feat@1.0` |\n| `scenario` | `org.dxos.mdl.scenario@1.0` |\n| `test` | `org.dxos.mdl.test@1.0` |\n\n## Types\n\n```mdl\ntype Settings\n desc: |\n User preferences for extension ↔ Composer coordination, persisted via the\n app-framework settings store. Only user-set values are stored; defaults\n are applied by consumers when reading the atom. All fields are optional.\n The fields are a configuration surface; enforcement is owned by whichever\n consumer reads the atom.\n fields:\n enabled?: boolean # default: true. \"Accept extension actions\" preference.\n autoOpenAfterClip?: boolean # default: false. \"Open after action\" preference.\n renderProxyEnabled?: boolean # default: true. \"Use extension to render pages\" preference.\n renderTimeout?: number # default: 20000. Max ms to wait for a render.\n renderActiveTab?: boolean # default: false. Render in a focused tab.\n developerMode?: boolean # default: false. Verbose logging / previews.\n```\n\n```mdl\ntype Source\n fields:\n url: string\n title: string\n favicon?: string\n clippedAt: string # ISO timestamp\n```\n\n```mdl\ntype Selection\n fields:\n text: string # innerText of the picked subtree\n html?: string # outerHTML, possibly truncated\n htmlTruncated?: boolean\n rect?: { x: number, y: number, width: number, height: number }\n```\n\n```mdl\ntype Hints\n desc: |\n Cheap signals harvested from the whole page at capture time. The mappings\n use a subset (h1, og:title, og:description, og:image) as fallbacks; a\n future agent stage may interpret all of them.\n fields:\n ogTitle?: string\n ogDescription?: string\n ogImage?: string\n jsonLd?: unknown[]\n h1?: string\n firstImage?: string\n```\n\n```mdl\ntype Snapshot\n desc: |\n Generic page capture produced by the extension's `snapshot` extractor.\n Travels as the `inputs` of an invoke request.\n fields:\n source: Source\n selection?: Selection\n hints?: Hints\n imageData?: string # downscaled primary-image thumbnail (data URL),\n # captured by the extension's background worker\n html?: string\n htmlTruncated?: boolean\n```\n\n```mdl\ntype PageActionDescriptor\n desc: |\n Serializable descriptor for a plugin-contributed page action, synced to\n the extension's registry cache. Invocation is correlated by `id`.\n fields:\n id: string # stable plugin-scoped action id\n label: string # human-readable action name\n icon: string # phosphor icon identifier\n urlPatterns: string[] # match patterns the action applies to\n predicate?: { exists: string } # lazy DOM condition (CSS selector)\n extractor: { name: string, params?: unknown } # extension-bundled extractor\n contexts: string[] # surfaces: popup | page | selection | link | picker\n operation: string # operation key, display/diagnostics only\n```\n\n```mdl\ntype PageAction\n desc: |\n A live page-action contribution: the descriptor fields plus the actual\n operation definition (serialized to its key string when listed). The\n target operation must accept `{ snapshot: Snapshot, target: Database }`\n and return `{ id: string }`.\n```\n\n```mdl\ntype ListRequest\n desc: |\n Sent by the extension as `composer:page-actions:list`; acked as\n `composer:page-actions:list:ack`.\n fields:\n version: number # runtime check: only 1 is supported\n id: string # correlation id, echoed in the ack\n```\n\n```mdl\ntype ListAck\n fields:\n version: number # always 1\n id: string\n ok: boolean\n actions?: PageActionDescriptor[] # when ok = true\n error?: string # stable error code when ok = false\n```\n\n```mdl\ntype InvokeRequest\n desc: |\n Sent by the extension as `composer:page-action:invoke`; acked as\n `composer:page-action:invoke:ack`. Decoded in two passes: a loose\n envelope ({ version, id? }) first, so newer versions yield\n `unsupportedVersion` rather than the generic `invalidPayload` and\n malformed payloads can still echo the request id.\n fields:\n version: number # runtime check: only 1 is supported\n id: string # correlation id, echoed in the ack\n actionId: string # id of the registered action to invoke\n page: { url: string, title: string, favicon?: string }\n inputs: unknown # extractor output; `snapshot` yields Snapshot\n invokedFrom: popup | contextMenu | picker\n```\n\n```mdl\ntype InvokeAck\n fields:\n version: number # always 1\n id: string\n ok: boolean\n objectId?: string # ID of the created object when ok = true\n error?: string # stable error code when ok = false:\n # invalidPayload | unsupportedVersion |\n # unknownAction | noSpace | operationFailed\n```\n\n## Features\n\n```mdl\nfeat F-1: Settings Capability\n\n req F-1.1:\n when: plugin is activated\n then: |\n a single `Settings` atom is registered under a plugin-scoped capability\n and contributed to `AppCapabilities.Settings` so the standard settings\n UI surfaces it.\n\n req F-1.2:\n when: another plugin reads the capability\n then: it receives the current Settings with defaults applied\n```\n\n```mdl\nfeat F-2: Settings Surface\n\n req F-2.1:\n when: the app-framework settings panel renders the CRX section\n then: |\n a schema-driven form is shown covering all Settings fields, wired to\n the Settings atom and persisted on change.\n\n req F-2.2:\n when: the user presses the Test connection button\n then: |\n a ping round-trips over the page → content-script → background path and\n reports the extension's name and version on success, or the failure\n reason otherwise.\n```\n\n```mdl\nfeat F-2c: Settings Enforcement\n\n req F-2c.1:\n when: `enabled` is false and a page-action invoke arrives\n then: |\n no object is created; the request is still acked (so the extension does\n not time out) with the stable error code `disabled`\n\n req F-2c.2:\n when: `autoOpenAfterClip` is true and a page action succeeds\n then: the created object is opened via LayoutOperation.Open\n\n req F-2c.3:\n when: `autoOpenAfterClip` is false (default)\n then: focus is not moved; only the success toast is shown\n```\n\n```mdl\nfeat F-3: Page Action Contributions\n desc: |\n Plugins contribute `PageAction[]` under the plugin-scoped\n `CrxCapabilities.PageAction` capability. Other plugins contribute their\n own actions the same way (e.g. plugin-bookmarks contributes\n \"Add bookmark\").\n\n req F-3.1:\n when: plugin is activated\n then: |\n three picker-only actions are contributed — Person, Organization, and\n Note — each matching `http(s)://*/*`, using the extension-bundled\n `snapshot` extractor, and targeting the corresponding\n AddPersonFromSnapshot / AddOrganizationFromSnapshot /\n AddNoteFromSnapshot operation.\n\n req F-3.2:\n when: the extension lists actions\n then: |\n contributions are resolved per-request, so actions from\n late-activating plugins are included.\n```\n\n```mdl\nfeat F-4: Registry Listing\n\n req F-4.1:\n when: plugin is activated\n then: |\n window event listeners for `composer:page-actions:list` and\n `composer:page-action:invoke` are installed, and a\n `composer:page-actions:ready` event is dispatched so the extension\n relay can refresh its registry even when Composer boots after the\n content script has already installed.\n\n req F-4.2:\n when: a valid list request arrives\n then: |\n the ack carries the currently contributed actions as serializable\n descriptors, with `operation` serialized to the operation's key string.\n\n req F-4.3:\n when: a list request fails schema decoding\n then: |\n the ack is { ok: false, error: 'invalidPayload' } with a best-effort\n echo of the request id so the extension can correlate the failure.\n```\n\n```mdl\nfeat F-5: Invoke Validation & Dispatch\n\n req F-5.1:\n when: an invoke request's envelope fails decoding\n then: ack is { ok: false, error: 'invalidPayload' } and nothing is invoked\n\n req F-5.2:\n when: the envelope has a version other than 1\n then: |\n ack is { ok: false, error: 'unsupportedVersion' } with the request id\n echoed when present.\n\n req F-5.3:\n when: the strict payload fails decoding\n then: ack is { ok: false, error: 'invalidPayload' }\n\n req F-5.4:\n when: `actionId` matches no registered action\n then: ack is { ok: false, error: 'unknownAction' }\n\n req F-5.5:\n when: the active space cannot be determined\n then: nothing is invoked; ack is { ok: false, error: 'noSpace' }\n\n req F-5.6:\n when: the request resolves to an action and an active space\n then: |\n the action's operation is invoked with\n { snapshot: inputs, target: activeSpace.db }; on success the ack is\n { ok: true, objectId } carrying the created object's id.\n\n req F-5.7:\n when: the operation returns an error or throws\n then: ack is { ok: false, error: 'operationFailed' }\n```\n\n```mdl\nfeat F-6: Snapshot → Object Mapping\n desc: |\n Each contributed operation maps a Snapshot to an ECHO object and adds it\n to the target database via SpaceOperation.AddObject.\n\n req F-6.1:\n when: AddPersonFromSnapshot is invoked\n then: |\n a Person is created with best-effort fields:\n fullName ← hints.h1 ?? hints.ogTitle ?? firstLine(selection.text)\n image ← hints.ogImage\n notes ← selection.text (truncated to 4000 chars)\n urls ← [{ label: source.title || source.url, value: source.url }]\n\n req F-6.2:\n when: AddOrganizationFromSnapshot is invoked\n then: |\n an Organization is created with best-effort fields:\n name ← hints.ogTitle ?? hints.h1 ?? firstLine(selection.text)\n description ← hints.ogDescription ?? selection.text (truncated)\n image ← hints.ogImage\n website ← source.url\n\n req F-6.3:\n when: AddNoteFromSnapshot is invoked\n then: |\n a Markdown document is created with a small prelude (title, source\n link, timestamp) followed by the selection's rendered text (truncated\n to 50000 chars). The title falls back through\n hints.h1 ?? hints.ogTitle ?? firstLine(selection.text) ?? source.title.\n\n req F-6.4:\n when: there is no name/title candidate\n then: the object is still created; empty name is acceptable\n```\n\n```mdl\nfeat F-7: User Feedback\n\n req F-7.1:\n when: an invoke ack is produced with ok = true\n then: a success toast is shown\n\n req F-7.2:\n when: an invoke ack is produced with ok = false\n then: an error toast is shown naming the stable error code\n```\n\n```mdl\nfeat F-8: Page Actions Registry & Invocation\n desc: |\n Plugins contribute page actions (serializable descriptor + target\n operation) under a plugin-scoped capability. This plugin answers the\n extension's registry-list requests (`composer:page-actions:list`) with\n descriptors and executes invoke requests (`composer:page-action:invoke`)\n by resolving the active space and invoking the target operation with\n `{ snapshot, target }`. Every request is acked with stable error codes\n (invalidPayload, unsupportedVersion, disabled, unknownAction, noSpace,\n operationFailed); outcomes surface as toasts.\n```\n\n## Acceptance\n\n```mdl\nscenario T-1: Settings atom registered\n given: plugin activated\n then:\n - the Settings capability is available via Capability.get\n - the default atom value is { enabled: true, autoOpenAfterClip: false,\n renderProxyEnabled: true, renderTimeout: 20000, renderActiveTab: false,\n developerMode: false }\n```\n\n```mdl\nscenario T-2: Toggling enabled persists\n given: settings surface rendered\n when: user toggles the `enabled` switch off\n then: subsequent reads of the atom observe enabled === false\n```\n\n```mdl\nscenario T-3: List request returns descriptors\n given: contributed picker actions (Person, Organization, Note)\n when: handleListEvent receives { version: 1, id: 'r1' }\n then:\n - ack is { ok: true, id: 'r1' }\n - ack.actions contains one descriptor per action with `operation`\n serialized to the operation key string\n```\n\n```mdl\nscenario T-4: Invalid list request is rejected\n given: page-actions listeners installed\n when: handleListEvent receives a malformed detail (missing id)\n then: ack is { ok: false, error: 'invalidPayload' }\n```\n\n```mdl\nscenario T-5: Valid person invoke creates Person\n given: a registered add-person action and an active space\n when: |\n handleInvokeEvent receives { version: 1, actionId: <add-person>,\n inputs: snapshot } with snapshot.hints.h1 = 'Jane Doe'\n then:\n - a Person is created with fullName = 'Jane Doe'\n - ack is { ok: true, objectId: <non-empty> }\n - a success toast is shown\n```\n\n```mdl\nscenario T-6: Organization mapping falls back to og:title\n given: a snapshot with hints.ogTitle = 'DXOS' and hints.h1 undefined\n when: AddOrganizationFromSnapshot is invoked\n then:\n - Organization.name === 'DXOS'\n - Organization.website === source.url\n```\n\n```mdl\nscenario T-7: Missing name is allowed\n given: a snapshot with no hints and empty selection text\n when: the add-person action is invoked\n then:\n - a Person is created (empty fullName)\n - ack is { ok: true, objectId: <non-empty> }\n```\n\n```mdl\nscenario T-8: Unsupported envelope version\n given: page-actions listeners installed\n when: handleInvokeEvent receives { version: 2, id: 'r2', ... }\n then:\n - nothing is invoked\n - ack is { ok: false, id: 'r2', error: 'unsupportedVersion' }\n```\n\n```mdl\nscenario T-9: Invalid invoke payload is rejected\n given: page-actions listeners installed\n when: handleInvokeEvent receives a version-1 detail missing `actionId`\n then:\n - nothing is invoked\n - ack is { ok: false, error: 'invalidPayload' } with the envelope id echoed\n```\n\n```mdl\nscenario T-10: Unknown action\n given: no action registered with id 'nope'\n when: handleInvokeEvent receives a valid request with actionId = 'nope'\n then: ack is { ok: false, error: 'unknownAction' }\n```\n\n```mdl\nscenario T-11: No active space\n given: the active space cannot be resolved\n when: a valid invoke request arrives\n then:\n - nothing is invoked\n - ack is { ok: false, error: 'noSpace' }\n```\n\n```mdl\nscenario T-12: Operation failure\n given: the target operation returns an error (or throws)\n when: a valid invoke request arrives\n then:\n - ack is { ok: false, error: 'operationFailed' }\n - an error toast is shown\n```\n\n---\n\n## QA\n\nExecutable tests. Each step carries a human instruction (`do`) and, where the step maps to an\ninvocable operation, an agent binding (`invoke`). Report failures by test and step number.\n\nNote: this document declares no `op` blocks, so the operations below are referenced by their full\nruntime key rather than `[op:...]` — see `src/types/CrxOperation.ts`.\n\n```mdl\ntest QA-1: Add a Person from a page snapshot\n desc: |\n The core snapshot → object mapping (F-6.1), standing in for the browser extension's picker,\n which an agent cannot drive — the extension is a separate, unautomatable browser process. This\n test invokes the target operation directly with a synthetic snapshot, exactly as the plugin's\n own invoke handler does after resolving `{ snapshot, target }` (F-5.6).\n actors: agent\n covers: [F-3.1, F-5.6, F-6.1, T-5]\n status: unverified\n given:\n - an identity exists\n - space: a space is open\n - plugin-crx is enabled — it is OFF by default (not in `getDefaults` and not in the dev-only\n default set; see `packages/apps/composer-app/src/plugin-defs.tsx`)\n - no Person named \"QA Snapshot Person\" exists — ABORT rather than reusing one this test did\n not create\n steps:\n - name: Add the person from a snapshot\n do: |\n (Real path, not automatable here: with the extension installed, open the popup on a page\n and choose the \"Person\" picker action, then select the page region to capture.)\n invoke: |\n org.dxos.operation.crx.addPersonFromSnapshot {\n snapshot: { source: { url: \"https://example.com/qa\", title: \"QA Page\", clippedAt: \"2026-08-27T00:00:00.000Z\" },\n hints: { h1: \"QA Snapshot Person\" } },\n target: $given.space.db\n }\n capture: created\n expect: a Person named \"QA Snapshot Person\" now exists in the space\n assert: return !!$created.id\n after:\n - name: Delete the Person\n do: Right-click \"QA Snapshot Person\" in the navtree and choose Delete.\n invoke: org.dxos.operation.space.removeObjects { objects: [{ \"/\": \"echo://$given.space.id/\" + $created.id }], target: $given.space }\n expect: the row leaves the navtree\n note: |\n `addPersonFromSnapshot` returns a bare `id`, not a live ref, so the DXN envelope is built\n by hand for the removal call — see Rule 4 in `op@1.1`'s parent doc about resolving by the\n invoker path rather than guessing a shortcut.\n```\n\n```mdl\ntest QA-2: Accept-extension-actions toggle gates invocation\n desc: |\n The settings enforcement path (F-2c.1) — no operation exists for the settings atom itself\n (it is a plain app-framework settings store), so this step is human-only.\n actors: human\n covers: [F-1.1, F-2.1, F-2c.1]\n status: unverified\n given:\n - an identity exists\n - plugin-crx is enabled — it is OFF by default (see QA-1)\n - the Settings panel's CRX section is reachable\n steps:\n - name: Disable \"Accept extension actions\"\n do: Open Settings, find the CRX section, and toggle \"Accept extension actions\" off.\n expect: the toggle shows off and the preference persists across a reload\n note: |\n NO `invoke` — the Settings atom has no operation binding; per F-2c.1, an invoke request\n that arrives while this is off is still acked (error `disabled`), which requires the\n extension itself to exercise and cannot be driven from the debug port alone.\n after:\n - name: Re-enable \"Accept extension actions\"\n do: Toggle \"Accept extension actions\" back on.\n expect: the toggle shows on again\n```\n\n---\n\n## Appendix: Extension Definitions\n\n```mdl\next type\n uri: org.dxos.mdl.type@1.0\n desc: A named data structure with typed fields and optional literals.\n fields:\n desc?: Prose\n fields?: FieldMap\n literals?: UnionList\n extends?: TypeRef[]\n```\n\n```mdl\next feat\n uri: org.dxos.mdl.feat@1.0\n desc: A named feature grouping one or more requirements.\n fields:\n desc?: Prose\n req: RequirementList\n nesting: self\n```\n\n```mdl\next scenario\n uri: org.dxos.mdl.scenario@1.0\n desc: An acceptance scenario expressed as given / when / then steps.\n fields:\n given?: Step | Step[]\n when?: Step | Step[]\n then: Step | Step[]\n tags?: TagList\n```\n";
10
- //#endregion
11
9
  //#region src/capabilities/index.ts
12
10
  var CrxSettings = AppCapability.settings(() => import("./chunk-settings.mjs"), {
13
11
  activatesOn: ActivationEvents.Idle,
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities.mjs","names":[],"sources":["../../src/capabilities/index.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as ActivationEvents from '@dxos/app-framework/ActivationEvents';\nimport * as Capabilities from '@dxos/app-framework/Capabilities';\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\n\nimport { meta } from '#meta';\nimport { translations } from '#translations';\nimport { CrxCapabilities, CrxEvents } from '#types';\n\n// eslint-disable-next-line import/no-relative-packages\nimport pluginSpec from '../../PLUGIN.mdl?raw';\n\nexport const CrxSettings = AppCapability.settings(() => import('./settings.ts'), {\n activatesOn: ActivationEvents.Idle,\n provides: [CrxCapabilities.Settings],\n});\nexport const InstallPageActions = Capability.lazyModule(\n 'InstallPageActions',\n {\n requires: [Capabilities.OperationInvoker, Capabilities.AtomRegistry, CrxCapabilities.Settings],\n provides: [],\n activatesOn: CrxEvents.Start,\n },\n () => import('./install-page-actions.ts'),\n);\nexport const OperationHandler = AppCapability.operationHandler(() => import('./operation-handler.ts'), {\n activatesOn: ActivationEvents.Idle,\n});\nexport const PageActionProvider = Capability.lazyModule(\n 'PageActionProvider',\n { provides: [CrxCapabilities.PageAction], activatesOn: CrxEvents.Start },\n () => import('./page-action-provider.ts'),\n);\nexport const PluginAsset = AppCapability.pluginAsset({\n pluginId: meta.profile.key,\n path: 'PLUGIN.mdl',\n content: pluginSpec,\n mimeType: 'application/x-mdl',\n});\nexport const ReactSurface = AppCapability.surface(() => import('./react-surface.ts'), {\n roles: ['org.dxos.role.article'],\n});\nexport const Translations = AppCapability.translations(translations);\n"],"mappings":";;;;;;;;;;;AAgBA,IAAa,cAAc,cAAc,eAAe,OAAO,yBAAkB;CAC/E,aAAa,iBAAiB;CAC9B,UAAU,CAAC,gBAAgB,QAAQ;AACrC,CAAC;AACD,IAAa,qBAAqB,WAAW,WAC3C,sBACA;CACE,UAAU;EAAC,aAAa;EAAkB,aAAa;EAAc,gBAAgB;CAAQ;CAC7F,UAAU,CAAC;CACX,aAAa,UAAU;AACzB,SACM,OAAO,mCACf;AACA,IAAa,mBAAmB,cAAc,uBAAuB,OAAO,kCAA2B,EACrG,aAAa,iBAAiB,KAChC,CAAC;AACD,IAAa,qBAAqB,WAAW,WAC3C,sBACA;CAAE,UAAU,CAAC,gBAAgB,UAAU;CAAG,aAAa,UAAU;AAAM,SACjE,OAAO,mCACf;AACA,IAAa,cAAc,cAAc,YAAY;CACnD,UAAU,KAAK,QAAQ;CACvB,MAAM;CACN,SAAS;CACT,UAAU;AACZ,CAAC;AACD,IAAa,eAAe,cAAc,cAAc,OAAO,8BAAuB,EACpF,OAAO,CAAC,uBAAuB,EACjC,CAAC;AACD,IAAa,eAAe,cAAc,aAAa,YAAY"}
1
+ {"version":3,"file":"capabilities.mjs","names":[],"sources":["../../src/capabilities/index.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as ActivationEvents from '@dxos/app-framework/ActivationEvents';\nimport * as Capabilities from '@dxos/app-framework/Capabilities';\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\n\nimport { meta } from '#meta';\nimport { translations } from '#translations';\nimport { CrxCapabilities, CrxEvents } from '#types';\n\n// eslint-disable-next-line import/no-relative-packages\nimport pluginSpec from '../../PLUGIN.mdl?raw';\n\nexport const CrxSettings = AppCapability.settings(() => import('./settings.ts'), {\n activatesOn: ActivationEvents.Idle,\n provides: [CrxCapabilities.Settings],\n});\nexport const InstallPageActions = Capability.lazyModule(\n 'InstallPageActions',\n {\n requires: [Capabilities.OperationInvoker, Capabilities.AtomRegistry, CrxCapabilities.Settings],\n provides: [],\n activatesOn: CrxEvents.Start,\n },\n () => import('./install-page-actions.ts'),\n);\nexport const OperationHandler = AppCapability.operationHandler(() => import('./operation-handler.ts'), {\n activatesOn: ActivationEvents.Idle,\n});\nexport const PageActionProvider = Capability.lazyModule(\n 'PageActionProvider',\n { provides: [CrxCapabilities.PageAction], activatesOn: CrxEvents.Start },\n () => import('./page-action-provider.ts'),\n);\nexport const PluginAsset = AppCapability.pluginAsset({\n pluginId: meta.profile.key,\n path: 'PLUGIN.mdl',\n content: pluginSpec,\n mimeType: 'application/x-mdl',\n});\nexport const ReactSurface = AppCapability.surface(() => import('./react-surface.ts'), {\n roles: ['org.dxos.role.article'],\n});\nexport const Translations = AppCapability.translations(translations);\n"],"mappings":";;;;;;;;;AAgBA,IAAa,cAAc,cAAc,eAAe,OAAO,yBAAkB;CAC/E,aAAa,iBAAiB;CAC9B,UAAU,CAAC,gBAAgB,QAAQ;AACrC,CAAC;AACD,IAAa,qBAAqB,WAAW,WAC3C,sBACA;CACE,UAAU;EAAC,aAAa;EAAkB,aAAa;EAAc,gBAAgB;CAAQ;CAC7F,UAAU,CAAC;CACX,aAAa,UAAU;AACzB,SACM,OAAO,mCACf;AACA,IAAa,mBAAmB,cAAc,uBAAuB,OAAO,kCAA2B,EACrG,aAAa,iBAAiB,KAChC,CAAC;AACD,IAAa,qBAAqB,WAAW,WAC3C,sBACA;CAAE,UAAU,CAAC,gBAAgB,UAAU;CAAG,aAAa,UAAU;AAAM,SACjE,OAAO,mCACf;AACA,IAAa,cAAc,cAAc,YAAY;CACnD,UAAU,KAAK,QAAQ;CACvB,MAAM;CACN,SAAS;CACT,UAAU;AACZ,CAAC;AACD,IAAa,eAAe,cAAc,cAAc,OAAO,8BAAuB,EACpF,OAAO,CAAC,uBAAuB,EACjC,CAAC;AACD,IAAa,eAAe,cAAc,aAAa,YAAY"}
@@ -0,0 +1,39 @@
1
+ import { t as PLUGIN_default } from "./chunk-PLUGIN.mjs";
2
+ import * as ActivationEvents from "@dxos/app-framework/ActivationEvents";
3
+ import * as Capabilities from "@dxos/app-framework/Capabilities";
4
+ import * as Capability from "@dxos/app-framework/Capability";
5
+ import * as AppCapability from "@dxos/app-toolkit/AppCapability";
6
+ import { translations } from "#translations";
7
+ import { CrxCapabilities, CrxEvents } from "#types";
8
+ import { meta } from "#meta";
9
+ //#region src/capabilities/gen/tauri.ts
10
+ var CrxSettings = AppCapability.settings(() => import("./chunk-settings.mjs"), {
11
+ activatesOn: ActivationEvents.Idle,
12
+ provides: [CrxCapabilities.Settings]
13
+ });
14
+ var InstallPageActions = Capability.lazyModule("InstallPageActions", {
15
+ requires: [
16
+ Capabilities.OperationInvoker,
17
+ Capabilities.AtomRegistry,
18
+ CrxCapabilities.Settings
19
+ ],
20
+ provides: [],
21
+ activatesOn: CrxEvents.Start
22
+ }, () => import("./chunk-install-page-actions.mjs"));
23
+ var OperationHandler = AppCapability.operationHandler(() => import("./chunk-operation-handler.mjs"), { activatesOn: ActivationEvents.Idle });
24
+ var PageActionProvider = Capability.lazyModule("PageActionProvider", {
25
+ provides: [CrxCapabilities.PageAction],
26
+ activatesOn: CrxEvents.Start
27
+ }, () => import("./chunk-page-action-provider.mjs"));
28
+ var PluginAsset = AppCapability.pluginAsset({
29
+ pluginId: meta.profile.key,
30
+ path: "PLUGIN.mdl",
31
+ content: PLUGIN_default,
32
+ mimeType: "application/x-mdl"
33
+ });
34
+ var ReactSurface = AppCapability.surface(() => import("./chunk-react-surface.mjs"), { roles: ["org.dxos.role.article"] });
35
+ var Translations = AppCapability.translations(translations);
36
+ //#endregion
37
+ export { CrxSettings, InstallPageActions, OperationHandler, PageActionProvider, PluginAsset, ReactSurface, Translations };
38
+
39
+ //# sourceMappingURL=capabilities.tauri.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.tauri.mjs","names":[],"sources":["../../src/capabilities/gen/tauri.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// GENERATED by dx-plugin — do not edit. Sliced from ../index.ts for the 'tauri' condition.\n\nimport * as ActivationEvents from '@dxos/app-framework/ActivationEvents';\nimport * as Capabilities from '@dxos/app-framework/Capabilities';\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\n\nimport { meta } from '#meta';\nimport { translations } from '#translations';\nimport { CrxCapabilities, CrxEvents } from '#types';\n\nimport pluginSpec from '../../../PLUGIN.mdl?raw';\n\nexport const CrxSettings = AppCapability.settings(() => import('../settings.ts'), {\n activatesOn: ActivationEvents.Idle,\n provides: [CrxCapabilities.Settings],\n});\n\nexport const InstallPageActions = Capability.lazyModule(\n 'InstallPageActions',\n {\n requires: [Capabilities.OperationInvoker, Capabilities.AtomRegistry, CrxCapabilities.Settings],\n provides: [],\n activatesOn: CrxEvents.Start,\n },\n () => import('../install-page-actions.ts'),\n);\n\nexport const OperationHandler = AppCapability.operationHandler(() => import('../operation-handler.ts'), {\n activatesOn: ActivationEvents.Idle,\n});\n\nexport const PageActionProvider = Capability.lazyModule(\n 'PageActionProvider',\n { provides: [CrxCapabilities.PageAction], activatesOn: CrxEvents.Start },\n () => import('../page-action-provider.ts'),\n);\n\nexport const PluginAsset = AppCapability.pluginAsset({\n pluginId: meta.profile.key,\n path: 'PLUGIN.mdl',\n content: pluginSpec,\n mimeType: 'application/x-mdl',\n});\n\nexport const ReactSurface = AppCapability.surface(() => import('../react-surface.ts'), {\n roles: ['org.dxos.role.article'],\n});\n\nexport const Translations = AppCapability.translations(translations);\n"],"mappings":";;;;;;;;;AAiBA,IAAa,cAAc,cAAc,eAAe,OAAO,yBAAmB;CAChF,aAAa,iBAAiB;CAC9B,UAAU,CAAC,gBAAgB,QAAQ;AACrC,CAAC;AAED,IAAa,qBAAqB,WAAW,WAC3C,sBACA;CACE,UAAU;EAAC,aAAa;EAAkB,aAAa;EAAc,gBAAgB;CAAQ;CAC7F,UAAU,CAAC;CACX,aAAa,UAAU;AACzB,SACM,OAAO,mCACf;AAEA,IAAa,mBAAmB,cAAc,uBAAuB,OAAO,kCAA4B,EACtG,aAAa,iBAAiB,KAChC,CAAC;AAED,IAAa,qBAAqB,WAAW,WAC3C,sBACA;CAAE,UAAU,CAAC,gBAAgB,UAAU;CAAG,aAAa,UAAU;AAAM,SACjE,OAAO,mCACf;AAEA,IAAa,cAAc,cAAc,YAAY;CACnD,UAAU,KAAK,QAAQ;CACvB,MAAM;CACN,SAAS;CACT,UAAU;AACZ,CAAC;AAED,IAAa,eAAe,cAAc,cAAc,OAAO,8BAAwB,EACrF,OAAO,CAAC,uBAAuB,EACjC,CAAC;AAED,IAAa,eAAe,cAAc,aAAa,YAAY"}
@@ -0,0 +1,6 @@
1
+ //#region PLUGIN.mdl?raw
2
+ var PLUGIN_default = "---\nid: org.dxos.plugin.crx\nname: CrxPlugin\nversion: 0.3.0\n---\n\nCoordinates with the `@dxos/composer-crx` browser extension. Owns the Composer\nside of the page-actions bridge: plugins contribute page actions (serializable\ndescriptor + target operation) under a plugin-scoped capability; the extension\ncaches the descriptors in its registry and invokes them over same-origin\n`window` `CustomEvent`s. This plugin answers registry-list requests, validates\ninvoke requests, resolves the active space, executes the target operation, and\nsurfaces outcomes as toasts. It also contributes three picker actions\n(Person, Organization, Note) whose operations map a page snapshot to an ECHO\nobject, and owns the user-facing settings surface — including the render-proxy\nsettings (absorbed from the retired plugin-extension) for the extension's\npage-rendering facility.\n\nThe extension owns the DOM picker, popup toolbar, extractors, and bridge\nsender; this plugin owns envelope validation, snapshot → ECHO object mapping,\nand user feedback (toast). The extension keeps a hand-validated mirror of the\nwire types at `packages/apps/composer-crx/src/page-actions/types.ts` which\nmust be updated in lockstep.\n\n## Extensions\n\nThe following extension dialects are used in this document.\nEach extension is defined in the Appendix or resolved via its URI.\n\n| Term | URI |\n|--------|--------------------------------|\n| `type` | `org.dxos.mdl.type@1.0` |\n| `feat` | `org.dxos.mdl.feat@1.0` |\n| `scenario` | `org.dxos.mdl.scenario@1.0` |\n| `test` | `org.dxos.mdl.test@1.0` |\n\n## Types\n\n```mdl\ntype Settings\n desc: |\n User preferences for extension ↔ Composer coordination, persisted via the\n app-framework settings store. Only user-set values are stored; defaults\n are applied by consumers when reading the atom. All fields are optional.\n The fields are a configuration surface; enforcement is owned by whichever\n consumer reads the atom.\n fields:\n enabled?: boolean # default: true. \"Accept extension actions\" preference.\n autoOpenAfterClip?: boolean # default: false. \"Open after action\" preference.\n renderProxyEnabled?: boolean # default: true. \"Use extension to render pages\" preference.\n renderTimeout?: number # default: 20000. Max ms to wait for a render.\n renderActiveTab?: boolean # default: false. Render in a focused tab.\n developerMode?: boolean # default: false. Verbose logging / previews.\n```\n\n```mdl\ntype Source\n fields:\n url: string\n title: string\n favicon?: string\n clippedAt: string # ISO timestamp\n```\n\n```mdl\ntype Selection\n fields:\n text: string # innerText of the picked subtree\n html?: string # outerHTML, possibly truncated\n htmlTruncated?: boolean\n rect?: { x: number, y: number, width: number, height: number }\n```\n\n```mdl\ntype Hints\n desc: |\n Cheap signals harvested from the whole page at capture time. The mappings\n use a subset (h1, og:title, og:description, og:image) as fallbacks; a\n future agent stage may interpret all of them.\n fields:\n ogTitle?: string\n ogDescription?: string\n ogImage?: string\n jsonLd?: unknown[]\n h1?: string\n firstImage?: string\n```\n\n```mdl\ntype Snapshot\n desc: |\n Generic page capture produced by the extension's `snapshot` extractor.\n Travels as the `inputs` of an invoke request.\n fields:\n source: Source\n selection?: Selection\n hints?: Hints\n imageData?: string # downscaled primary-image thumbnail (data URL),\n # captured by the extension's background worker\n html?: string\n htmlTruncated?: boolean\n```\n\n```mdl\ntype PageActionDescriptor\n desc: |\n Serializable descriptor for a plugin-contributed page action, synced to\n the extension's registry cache. Invocation is correlated by `id`.\n fields:\n id: string # stable plugin-scoped action id\n label: string # human-readable action name\n icon: string # phosphor icon identifier\n urlPatterns: string[] # match patterns the action applies to\n predicate?: { exists: string } # lazy DOM condition (CSS selector)\n extractor: { name: string, params?: unknown } # extension-bundled extractor\n contexts: string[] # surfaces: popup | page | selection | link | picker\n operation: string # operation key, display/diagnostics only\n```\n\n```mdl\ntype PageAction\n desc: |\n A live page-action contribution: the descriptor fields plus the actual\n operation definition (serialized to its key string when listed). The\n target operation must accept `{ snapshot: Snapshot, target: Database }`\n and return `{ id: string }`.\n```\n\n```mdl\ntype ListRequest\n desc: |\n Sent by the extension as `composer:page-actions:list`; acked as\n `composer:page-actions:list:ack`.\n fields:\n version: number # runtime check: only 1 is supported\n id: string # correlation id, echoed in the ack\n```\n\n```mdl\ntype ListAck\n fields:\n version: number # always 1\n id: string\n ok: boolean\n actions?: PageActionDescriptor[] # when ok = true\n error?: string # stable error code when ok = false\n```\n\n```mdl\ntype InvokeRequest\n desc: |\n Sent by the extension as `composer:page-action:invoke`; acked as\n `composer:page-action:invoke:ack`. Decoded in two passes: a loose\n envelope ({ version, id? }) first, so newer versions yield\n `unsupportedVersion` rather than the generic `invalidPayload` and\n malformed payloads can still echo the request id.\n fields:\n version: number # runtime check: only 1 is supported\n id: string # correlation id, echoed in the ack\n actionId: string # id of the registered action to invoke\n page: { url: string, title: string, favicon?: string }\n inputs: unknown # extractor output; `snapshot` yields Snapshot\n invokedFrom: popup | contextMenu | picker\n```\n\n```mdl\ntype InvokeAck\n fields:\n version: number # always 1\n id: string\n ok: boolean\n objectId?: string # ID of the created object when ok = true\n error?: string # stable error code when ok = false:\n # invalidPayload | unsupportedVersion |\n # unknownAction | noSpace | operationFailed\n```\n\n## Features\n\n```mdl\nfeat F-1: Settings Capability\n\n req F-1.1:\n when: plugin is activated\n then: |\n a single `Settings` atom is registered under a plugin-scoped capability\n and contributed to `AppCapabilities.Settings` so the standard settings\n UI surfaces it.\n\n req F-1.2:\n when: another plugin reads the capability\n then: it receives the current Settings with defaults applied\n```\n\n```mdl\nfeat F-2: Settings Surface\n\n req F-2.1:\n when: the app-framework settings panel renders the CRX section\n then: |\n a schema-driven form is shown covering all Settings fields, wired to\n the Settings atom and persisted on change.\n\n req F-2.2:\n when: the user presses the Test connection button\n then: |\n a ping round-trips over the page → content-script → background path and\n reports the extension's name and version on success, or the failure\n reason otherwise.\n```\n\n```mdl\nfeat F-2c: Settings Enforcement\n\n req F-2c.1:\n when: `enabled` is false and a page-action invoke arrives\n then: |\n no object is created; the request is still acked (so the extension does\n not time out) with the stable error code `disabled`\n\n req F-2c.2:\n when: `autoOpenAfterClip` is true and a page action succeeds\n then: the created object is opened via LayoutOperation.Open\n\n req F-2c.3:\n when: `autoOpenAfterClip` is false (default)\n then: focus is not moved; only the success toast is shown\n```\n\n```mdl\nfeat F-3: Page Action Contributions\n desc: |\n Plugins contribute `PageAction[]` under the plugin-scoped\n `CrxCapabilities.PageAction` capability. Other plugins contribute their\n own actions the same way (e.g. plugin-bookmarks contributes\n \"Add bookmark\").\n\n req F-3.1:\n when: plugin is activated\n then: |\n three picker-only actions are contributed — Person, Organization, and\n Note — each matching `http(s)://*/*`, using the extension-bundled\n `snapshot` extractor, and targeting the corresponding\n AddPersonFromSnapshot / AddOrganizationFromSnapshot /\n AddNoteFromSnapshot operation.\n\n req F-3.2:\n when: the extension lists actions\n then: |\n contributions are resolved per-request, so actions from\n late-activating plugins are included.\n```\n\n```mdl\nfeat F-4: Registry Listing\n\n req F-4.1:\n when: plugin is activated\n then: |\n window event listeners for `composer:page-actions:list` and\n `composer:page-action:invoke` are installed, and a\n `composer:page-actions:ready` event is dispatched so the extension\n relay can refresh its registry even when Composer boots after the\n content script has already installed.\n\n req F-4.2:\n when: a valid list request arrives\n then: |\n the ack carries the currently contributed actions as serializable\n descriptors, with `operation` serialized to the operation's key string.\n\n req F-4.3:\n when: a list request fails schema decoding\n then: |\n the ack is { ok: false, error: 'invalidPayload' } with a best-effort\n echo of the request id so the extension can correlate the failure.\n```\n\n```mdl\nfeat F-5: Invoke Validation & Dispatch\n\n req F-5.1:\n when: an invoke request's envelope fails decoding\n then: ack is { ok: false, error: 'invalidPayload' } and nothing is invoked\n\n req F-5.2:\n when: the envelope has a version other than 1\n then: |\n ack is { ok: false, error: 'unsupportedVersion' } with the request id\n echoed when present.\n\n req F-5.3:\n when: the strict payload fails decoding\n then: ack is { ok: false, error: 'invalidPayload' }\n\n req F-5.4:\n when: `actionId` matches no registered action\n then: ack is { ok: false, error: 'unknownAction' }\n\n req F-5.5:\n when: the active space cannot be determined\n then: nothing is invoked; ack is { ok: false, error: 'noSpace' }\n\n req F-5.6:\n when: the request resolves to an action and an active space\n then: |\n the action's operation is invoked with\n { snapshot: inputs, target: activeSpace.db }; on success the ack is\n { ok: true, objectId } carrying the created object's id.\n\n req F-5.7:\n when: the operation returns an error or throws\n then: ack is { ok: false, error: 'operationFailed' }\n```\n\n```mdl\nfeat F-6: Snapshot → Object Mapping\n desc: |\n Each contributed operation maps a Snapshot to an ECHO object and adds it\n to the target database via SpaceOperation.AddObject.\n\n req F-6.1:\n when: AddPersonFromSnapshot is invoked\n then: |\n a Person is created with best-effort fields:\n fullName ← hints.h1 ?? hints.ogTitle ?? firstLine(selection.text)\n image ← hints.ogImage\n notes ← selection.text (truncated to 4000 chars)\n urls ← [{ label: source.title || source.url, value: source.url }]\n\n req F-6.2:\n when: AddOrganizationFromSnapshot is invoked\n then: |\n an Organization is created with best-effort fields:\n name ← hints.ogTitle ?? hints.h1 ?? firstLine(selection.text)\n description ← hints.ogDescription ?? selection.text (truncated)\n image ← hints.ogImage\n website ← source.url\n\n req F-6.3:\n when: AddNoteFromSnapshot is invoked\n then: |\n a Markdown document is created with a small prelude (title, source\n link, timestamp) followed by the selection's rendered text (truncated\n to 50000 chars). The title falls back through\n hints.h1 ?? hints.ogTitle ?? firstLine(selection.text) ?? source.title.\n\n req F-6.4:\n when: there is no name/title candidate\n then: the object is still created; empty name is acceptable\n```\n\n```mdl\nfeat F-7: User Feedback\n\n req F-7.1:\n when: an invoke ack is produced with ok = true\n then: a success toast is shown\n\n req F-7.2:\n when: an invoke ack is produced with ok = false\n then: an error toast is shown naming the stable error code\n```\n\n```mdl\nfeat F-8: Page Actions Registry & Invocation\n desc: |\n Plugins contribute page actions (serializable descriptor + target\n operation) under a plugin-scoped capability. This plugin answers the\n extension's registry-list requests (`composer:page-actions:list`) with\n descriptors and executes invoke requests (`composer:page-action:invoke`)\n by resolving the active space and invoking the target operation with\n `{ snapshot, target }`. Every request is acked with stable error codes\n (invalidPayload, unsupportedVersion, disabled, unknownAction, noSpace,\n operationFailed); outcomes surface as toasts.\n```\n\n## Acceptance\n\n```mdl\nscenario T-1: Settings atom registered\n given: plugin activated\n then:\n - the Settings capability is available via Capability.get\n - the default atom value is { enabled: true, autoOpenAfterClip: false,\n renderProxyEnabled: true, renderTimeout: 20000, renderActiveTab: false,\n developerMode: false }\n```\n\n```mdl\nscenario T-2: Toggling enabled persists\n given: settings surface rendered\n when: user toggles the `enabled` switch off\n then: subsequent reads of the atom observe enabled === false\n```\n\n```mdl\nscenario T-3: List request returns descriptors\n given: contributed picker actions (Person, Organization, Note)\n when: handleListEvent receives { version: 1, id: 'r1' }\n then:\n - ack is { ok: true, id: 'r1' }\n - ack.actions contains one descriptor per action with `operation`\n serialized to the operation key string\n```\n\n```mdl\nscenario T-4: Invalid list request is rejected\n given: page-actions listeners installed\n when: handleListEvent receives a malformed detail (missing id)\n then: ack is { ok: false, error: 'invalidPayload' }\n```\n\n```mdl\nscenario T-5: Valid person invoke creates Person\n given: a registered add-person action and an active space\n when: |\n handleInvokeEvent receives { version: 1, actionId: <add-person>,\n inputs: snapshot } with snapshot.hints.h1 = 'Jane Doe'\n then:\n - a Person is created with fullName = 'Jane Doe'\n - ack is { ok: true, objectId: <non-empty> }\n - a success toast is shown\n```\n\n```mdl\nscenario T-6: Organization mapping falls back to og:title\n given: a snapshot with hints.ogTitle = 'DXOS' and hints.h1 undefined\n when: AddOrganizationFromSnapshot is invoked\n then:\n - Organization.name === 'DXOS'\n - Organization.website === source.url\n```\n\n```mdl\nscenario T-7: Missing name is allowed\n given: a snapshot with no hints and empty selection text\n when: the add-person action is invoked\n then:\n - a Person is created (empty fullName)\n - ack is { ok: true, objectId: <non-empty> }\n```\n\n```mdl\nscenario T-8: Unsupported envelope version\n given: page-actions listeners installed\n when: handleInvokeEvent receives { version: 2, id: 'r2', ... }\n then:\n - nothing is invoked\n - ack is { ok: false, id: 'r2', error: 'unsupportedVersion' }\n```\n\n```mdl\nscenario T-9: Invalid invoke payload is rejected\n given: page-actions listeners installed\n when: handleInvokeEvent receives a version-1 detail missing `actionId`\n then:\n - nothing is invoked\n - ack is { ok: false, error: 'invalidPayload' } with the envelope id echoed\n```\n\n```mdl\nscenario T-10: Unknown action\n given: no action registered with id 'nope'\n when: handleInvokeEvent receives a valid request with actionId = 'nope'\n then: ack is { ok: false, error: 'unknownAction' }\n```\n\n```mdl\nscenario T-11: No active space\n given: the active space cannot be resolved\n when: a valid invoke request arrives\n then:\n - nothing is invoked\n - ack is { ok: false, error: 'noSpace' }\n```\n\n```mdl\nscenario T-12: Operation failure\n given: the target operation returns an error (or throws)\n when: a valid invoke request arrives\n then:\n - ack is { ok: false, error: 'operationFailed' }\n - an error toast is shown\n```\n\n---\n\n## QA\n\nExecutable tests. Each step carries a human instruction (`do`) and, where the step maps to an\ninvocable operation, an agent binding (`invoke`). Report failures by test and step number.\n\nNote: this document declares no `op` blocks, so the operations below are referenced by their full\nruntime key rather than `[op:...]` — see `src/types/CrxOperation.ts`.\n\n```mdl\ntest QA-1: Add a Person from a page snapshot\n desc: |\n The core snapshot → object mapping (F-6.1), standing in for the browser extension's picker,\n which an agent cannot drive — the extension is a separate, unautomatable browser process. This\n test invokes the target operation directly with a synthetic snapshot, exactly as the plugin's\n own invoke handler does after resolving `{ snapshot, target }` (F-5.6).\n actors: agent\n covers: [F-3.1, F-5.6, F-6.1, T-5]\n status: unverified\n given:\n - an identity exists\n - space: a space is open\n - plugin-crx is enabled — it is OFF by default (not in `getDefaults` and not in the dev-only\n default set; see `packages/apps/composer-app/src/plugin-defs.tsx`)\n - no Person named \"QA Snapshot Person\" exists — ABORT rather than reusing one this test did\n not create\n steps:\n - name: Add the person from a snapshot\n do: |\n (Real path, not automatable here: with the extension installed, open the popup on a page\n and choose the \"Person\" picker action, then select the page region to capture.)\n invoke: |\n org.dxos.operation.crx.addPersonFromSnapshot {\n snapshot: { source: { url: \"https://example.com/qa\", title: \"QA Page\", clippedAt: \"2026-08-27T00:00:00.000Z\" },\n hints: { h1: \"QA Snapshot Person\" } },\n target: $given.space.db\n }\n capture: created\n expect: a Person named \"QA Snapshot Person\" now exists in the space\n assert: return !!$created.id\n after:\n - name: Delete the Person\n do: Right-click \"QA Snapshot Person\" in the navtree and choose Delete.\n invoke: org.dxos.operation.space.removeObjects { objects: [{ \"/\": \"echo://$given.space.id/\" + $created.id }], target: $given.space }\n expect: the row leaves the navtree\n note: |\n `addPersonFromSnapshot` returns a bare `id`, not a live ref, so the DXN envelope is built\n by hand for the removal call — see Rule 4 in `op@1.1`'s parent doc about resolving by the\n invoker path rather than guessing a shortcut.\n```\n\n```mdl\ntest QA-2: Accept-extension-actions toggle gates invocation\n desc: |\n The settings enforcement path (F-2c.1) — no operation exists for the settings atom itself\n (it is a plain app-framework settings store), so this step is human-only.\n actors: human\n covers: [F-1.1, F-2.1, F-2c.1]\n status: unverified\n given:\n - an identity exists\n - plugin-crx is enabled — it is OFF by default (see QA-1)\n - the Settings panel's CRX section is reachable\n steps:\n - name: Disable \"Accept extension actions\"\n do: Open Settings, find the CRX section, and toggle \"Accept extension actions\" off.\n expect: the toggle shows off and the preference persists across a reload\n note: |\n NO `invoke` — the Settings atom has no operation binding; per F-2c.1, an invoke request\n that arrives while this is off is still acked (error `disabled`), which requires the\n extension itself to exercise and cannot be driven from the debug port alone.\n after:\n - name: Re-enable \"Accept extension actions\"\n do: Toggle \"Accept extension actions\" back on.\n expect: the toggle shows on again\n```\n\n---\n\n## Appendix: Extension Definitions\n\n```mdl\next type\n uri: org.dxos.mdl.type@1.0\n desc: A named data structure with typed fields and optional literals.\n fields:\n desc?: Prose\n fields?: FieldMap\n literals?: UnionList\n extends?: TypeRef[]\n```\n\n```mdl\next feat\n uri: org.dxos.mdl.feat@1.0\n desc: A named feature grouping one or more requirements.\n fields:\n desc?: Prose\n req: RequirementList\n nesting: self\n```\n\n```mdl\next scenario\n uri: org.dxos.mdl.scenario@1.0\n desc: An acceptance scenario expressed as given / when / then steps.\n fields:\n given?: Step | Step[]\n when?: Step | Step[]\n then: Step | Step[]\n tags?: TagList\n```\n";
3
+ //#endregion
4
+ export { PLUGIN_default as t };
5
+
6
+ //# sourceMappingURL=chunk-PLUGIN.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-PLUGIN.mjs","names":[],"sources":[],"mappings":""}
@@ -12,7 +12,7 @@ import * as Result from "effect/Result";
12
12
  import * as AppSpace from "@dxos/app-toolkit/AppSpace";
13
13
  import * as ClientCapabilities from "@dxos/plugin-client/ClientCapabilities";
14
14
  //#region src/page-actions.ts
15
- var __dxlog_file$1 = "/Users/dmaretskyi/Code/dxos/dxos/.claude/worktrees/publish-plugin-github/packages/plugins/plugin-crx/src/page-actions.ts";
15
+ var __dxlog_file$1 = "/__w/dxos/dxos/packages/plugins/plugin-crx/src/page-actions.ts";
16
16
  /**
17
17
  * Answer a registry-list request with the currently contributed actions as
18
18
  * serializable descriptors.
@@ -242,7 +242,7 @@ var installPageActionListeners = (capabilities, invoker, onResult) => {
242
242
  };
243
243
  //#endregion
244
244
  //#region src/capabilities/install-page-actions.ts
245
- var __dxlog_file = "/Users/dmaretskyi/Code/dxos/dxos/.claude/worktrees/publish-plugin-github/packages/plugins/plugin-crx/src/capabilities/install-page-actions.ts";
245
+ var __dxlog_file = "/__w/dxos/dxos/packages/plugins/plugin-crx/src/capabilities/install-page-actions.ts";
246
246
  var openObject = async (invoker, uri) => {
247
247
  const { data } = await invoker.invokePromise(NavigationOperation.ResolveNavigationTargets, { query: { uri } });
248
248
  const path = data?.targets[0]?.path;
@@ -1,9 +1,9 @@
1
1
  import * as Capabilities from "@dxos/app-framework/Capabilities";
2
2
  import * as Capability from "@dxos/app-framework/Capability";
3
3
  import { meta } from "#meta";
4
- import { Surface } from "@dxos/app-framework/ui";
5
- import { AppSurface } from "@dxos/app-toolkit/ui";
6
4
  import * as Effect from "effect/Effect";
5
+ import * as Surface from "@dxos/app-framework/Surface";
6
+ import * as AppSurface from "@dxos/app-toolkit/AppSurface";
7
7
  import { CrxSettings } from "#containers";
8
8
  //#region src/capabilities/react-surface.ts
9
9
  var react_surface_default = Capability.makeModule(() => Effect.succeed(Capability.contribute(Capabilities.ReactSurface, [Surface.create({
@@ -1 +1 @@
1
- {"version":3,"file":"chunk-react-surface.mjs","names":[],"sources":["../../src/capabilities/react-surface.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport * as Capabilities from '@dxos/app-framework/Capabilities';\nimport * as Capability from '@dxos/app-framework/Capability';\nimport { Surface } from '@dxos/app-framework/ui';\nimport { AppSurface } from '@dxos/app-toolkit/ui';\n\nimport { CrxSettings } from '#containers';\nimport { meta } from '#meta';\n\nexport default Capability.makeModule(() =>\n Effect.succeed(\n Capability.contribute(Capabilities.ReactSurface, [\n Surface.create({\n id: 'pluginSettings',\n filter: AppSurface.settings(AppSurface.Article, meta.profile.key),\n component: CrxSettings,\n props: ({ data: { subject } }) => ({ subject }),\n }),\n ]),\n ),\n);\n"],"mappings":";;;;;;;;AAcA,IAAA,wBAAe,WAAW,iBACxB,OAAO,QACL,WAAW,WAAW,aAAa,cAAc,CAC/C,QAAQ,OAAO;CACb,IAAI;CACJ,QAAQ,WAAW,SAAS,WAAW,SAAS,KAAK,QAAQ,GAAG;CAChE,WAAW;CACX,QAAQ,EAAE,MAAM,EAAE,iBAAiB,EAAE,QAAQ;AAC/C,CAAC,CACH,CAAC,CACH,CACF"}
1
+ {"version":3,"file":"chunk-react-surface.mjs","names":[],"sources":["../../src/capabilities/react-surface.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport * as Capabilities from '@dxos/app-framework/Capabilities';\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as Surface from '@dxos/app-framework/Surface';\nimport * as AppSurface from '@dxos/app-toolkit/AppSurface';\n\nimport { CrxSettings } from '#containers';\nimport { meta } from '#meta';\n\nexport default Capability.makeModule(() =>\n Effect.succeed(\n Capability.contribute(Capabilities.ReactSurface, [\n Surface.create({\n id: 'pluginSettings',\n filter: AppSurface.settings(AppSurface.Article, meta.profile.key),\n component: CrxSettings,\n props: ({ data: { subject } }) => ({ subject }),\n }),\n ]),\n ),\n);\n"],"mappings":";;;;;;;;AAcA,IAAA,wBAAe,WAAW,iBACxB,OAAO,QACL,WAAW,WAAW,aAAa,cAAc,CAC/C,QAAQ,OAAO;CACb,IAAI;CACJ,QAAQ,WAAW,SAAS,WAAW,SAAS,KAAK,QAAQ,GAAG;CAChE,WAAW;CACX,QAAQ,EAAE,MAAM,EAAE,iBAAiB,EAAE,QAAQ;AAC/C,CAAC,CACH,CAAC,CACH,CACF"}
@@ -3,7 +3,7 @@ import { CrxCapabilities, Settings } from "#types";
3
3
  import { meta } from "#meta";
4
4
  import * as Effect from "effect/Effect";
5
5
  import * as AppCapabilities from "@dxos/app-toolkit/AppCapabilities";
6
- import { createKvsStore } from "@dxos/effect";
6
+ import * as KvsStore from "@dxos/effect/KvsStore";
7
7
  //#region src/capabilities/settings.ts
8
8
  /**
9
9
  * Contributes the Settings atom both under the plugin-scoped capability (so
@@ -11,7 +11,7 @@ import { createKvsStore } from "@dxos/effect";
11
11
  * standard settings panel surfaces it).
12
12
  */
13
13
  var settings_default = Capability.makeModule(() => Effect.sync(() => {
14
- const settingsAtom = createKvsStore({
14
+ const settingsAtom = KvsStore.make({
15
15
  key: meta.profile.key,
16
16
  schema: Settings.Settings,
17
17
  defaultValue: () => Settings.defaults
@@ -1 +1 @@
1
- {"version":3,"file":"chunk-settings.mjs","names":[],"sources":["../../src/capabilities/settings.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as AppCapabilities from '@dxos/app-toolkit/AppCapabilities';\nimport { createKvsStore } from '@dxos/effect';\n\nimport { meta } from '#meta';\nimport { CrxCapabilities, Settings } from '#types';\n\n/**\n * Contributes the Settings atom both under the plugin-scoped capability (so\n * other plugins can read it) and under `AppCapabilities.Settings` (so the\n * standard settings panel surfaces it).\n */\nexport default Capability.makeModule(() =>\n Effect.sync(() => {\n const settingsAtom = createKvsStore({\n key: meta.profile.key,\n schema: Settings.Settings,\n defaultValue: () => Settings.defaults,\n });\n\n return [\n Capability.contribute(CrxCapabilities.Settings, settingsAtom),\n Capability.contribute(AppCapabilities.Settings, {\n prefix: meta.profile.key,\n schema: Settings.Settings,\n atom: settingsAtom,\n }),\n ];\n }),\n);\n"],"mappings":";;;;;;;;;;;;AAkBA,IAAA,mBAAe,WAAW,iBACxB,OAAO,WAAW;CAChB,MAAM,eAAe,eAAe;EAClC,KAAK,KAAK,QAAQ;EAClB,QAAQ,SAAS;EACjB,oBAAoB,SAAS;CAC/B,CAAC;CAED,OAAO,CACL,WAAW,WAAW,gBAAgB,UAAU,YAAY,GAC5D,WAAW,WAAW,gBAAgB,UAAU;EAC9C,QAAQ,KAAK,QAAQ;EACrB,QAAQ,SAAS;EACjB,MAAM;CACR,CAAC,CACH;AACF,CAAC,CACH"}
1
+ {"version":3,"file":"chunk-settings.mjs","names":[],"sources":["../../src/capabilities/settings.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as AppCapabilities from '@dxos/app-toolkit/AppCapabilities';\nimport * as KvsStore from '@dxos/effect/KvsStore';\n\nimport { meta } from '#meta';\nimport { CrxCapabilities, Settings } from '#types';\n\n/**\n * Contributes the Settings atom both under the plugin-scoped capability (so\n * other plugins can read it) and under `AppCapabilities.Settings` (so the\n * standard settings panel surfaces it).\n */\nexport default Capability.makeModule(() =>\n Effect.sync(() => {\n const settingsAtom = KvsStore.make({\n key: meta.profile.key,\n schema: Settings.Settings,\n defaultValue: () => Settings.defaults,\n });\n\n return [\n Capability.contribute(CrxCapabilities.Settings, settingsAtom),\n Capability.contribute(AppCapabilities.Settings, {\n prefix: meta.profile.key,\n schema: Settings.Settings,\n atom: settingsAtom,\n }),\n ];\n }),\n);\n"],"mappings":";;;;;;;;;;;;AAkBA,IAAA,mBAAe,WAAW,iBACxB,OAAO,WAAW;CAChB,MAAM,eAAe,SAAS,KAAK;EACjC,KAAK,KAAK,QAAQ;EAClB,QAAQ,SAAS;EACjB,oBAAoB,SAAS;CAC/B,CAAC;CAED,OAAO,CACL,WAAW,WAAW,gBAAgB,UAAU,YAAY,GAC5D,WAAW,WAAW,gBAAgB,UAAU;EAC9C,QAAQ,KAAK,QAAQ;EACrB,QAAQ,SAAS;EACjB,MAAM;CACR,CAAC,CACH;AACF,CAAC,CACH"}
@@ -2,10 +2,12 @@ import { pingExtension } from "./util.mjs";
2
2
  import { Settings } from "#types";
3
3
  import { meta } from "#meta";
4
4
  import { useCallback, useState } from "react";
5
- import { useSettingsState } from "@dxos/app-framework/ui";
6
- import { SettingsScope } from "@dxos/app-toolkit/ui";
7
- import { Flex, IconButton, useTranslation } from "@dxos/react-ui";
5
+ import * as Hooks from "@dxos/app-framework/Hooks";
6
+ import * as SettingsScope from "@dxos/app-toolkit/SettingsScope";
8
7
  import { Form } from "@dxos/react-ui-form";
8
+ import * as Button from "@dxos/react-ui/Button";
9
+ import * as UiHooks from "@dxos/react-ui/Hooks";
10
+ import * as Layout from "@dxos/react-ui/Layout";
9
11
  import { jsx, jsxs } from "react/jsx-runtime";
10
12
  //#region src/containers/CrxSettings/CrxSettings.tsx
11
13
  /**
@@ -13,8 +15,8 @@ import { jsx, jsxs } from "react/jsx-runtime";
13
15
  * round-trip connection test against the extension's content relay.
14
16
  */
15
17
  var CrxSettings = ({ subject, readonly }) => {
16
- const { t } = useTranslation(meta.profile.key);
17
- const { settings, updateSettings } = useSettingsState(subject.atom);
18
+ const { t } = UiHooks.useTranslation(meta.profile.key);
19
+ const { settings, updateSettings } = Hooks.useSettingsState(subject.atom);
18
20
  const [test, setTest] = useState({ kind: "idle" });
19
21
  const handleTest = useCallback(async () => {
20
22
  setTest({ kind: "pending" });
@@ -48,23 +50,23 @@ var CrxSettings = ({ subject, readonly }) => {
48
50
  children: /* @__PURE__ */ jsxs(Form.Content, { children: [/* @__PURE__ */ jsx(Form.FieldSet, {
49
51
  label: meta.profile.name ?? meta.profile.key,
50
52
  description: t("settings.description"),
51
- actions: readonly ? void 0 : /* @__PURE__ */ jsx(SettingsScope, { prefix: subject.prefix }),
53
+ actions: readonly ? void 0 : /* @__PURE__ */ jsx(SettingsScope.Root, { prefix: subject.prefix }),
52
54
  children: /* @__PURE__ */ jsx(Form.Fields, {})
53
55
  }), /* @__PURE__ */ jsx(Form.FieldSet, {
54
56
  label: t("test.title"),
55
- children: /* @__PURE__ */ jsxs(Flex, {
57
+ children: /* @__PURE__ */ jsxs(Layout.Flex, {
56
58
  gap: "sm",
57
- children: [/* @__PURE__ */ jsx(IconButton, {
59
+ children: [/* @__PURE__ */ jsx(Button.Root, {
58
60
  disabled: test.kind === "pending",
59
61
  icon: "ph--plug--regular",
60
62
  label: t("test.button.label"),
61
63
  onClick: handleTest
62
- }), /* @__PURE__ */ jsx(Flex, {
64
+ }), /* @__PURE__ */ jsx(Layout.Flex, {
63
65
  align: "center",
64
66
  children: /* @__PURE__ */ jsxs("span", {
65
67
  role: "status",
66
68
  "aria-live": "polite",
67
- className: test.kind === "ok" ? "text-sm text-success-text" : test.kind === "error" ? "text-sm text-error-text" : "text-sm text-description",
69
+ className: test.kind === "ok" ? "text-sm text-success-text" : test.kind === "error" ? "text-sm text-error-text" : "text-sm text-fg-muted",
68
70
  children: [test.kind === "ok" || test.kind === "error" ? test.message : "", test.kind === "pending" ? t("test.pending.message") : ""]
69
71
  })
70
72
  })]
@@ -1 +1 @@
1
- {"version":3,"file":"containers.mjs","names":[],"sources":["../../src/containers/CrxSettings/CrxSettings.tsx"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useCallback, useState } from 'react';\n\nimport { useSettingsState } from '@dxos/app-framework/ui';\nimport { type AppSurface, SettingsScope } from '@dxos/app-toolkit/ui';\nimport { Flex, IconButton, useTranslation } from '@dxos/react-ui';\nimport { Form } from '@dxos/react-ui-form';\n\nimport { meta } from '#meta';\nimport { Settings } from '#types';\n\nimport { pingExtension } from '../../util/index.ts';\n\ntype TestState =\n | { kind: 'idle' }\n | { kind: 'pending' }\n | { kind: 'ok'; message: string }\n | { kind: 'error'; message: string };\n\nexport type CrxSettingsProps = AppSurface.SettingsData<{ readonly?: boolean }>;\n\n/**\n * Settings panel for the browser extension: edits the plugin's schema-driven settings and offers a\n * round-trip connection test against the extension's content relay.\n */\nexport const CrxSettings = ({ subject, readonly }: CrxSettingsProps) => {\n const { t } = useTranslation(meta.profile.key);\n const { settings, updateSettings } = useSettingsState<Settings.Settings>(subject.atom);\n const [test, setTest] = useState<TestState>({ kind: 'idle' });\n\n // Round-trip a ping to the extension and report its identity (or why it failed).\n const handleTest = useCallback(async () => {\n setTest({ kind: 'pending' });\n try {\n const info = await pingExtension();\n setTest({\n kind: 'ok',\n message: t('test.connected.message', { name: info.extensionName, version: info.extensionVersion }),\n });\n } catch (err) {\n setTest({ kind: 'error', message: err instanceof Error ? err.message : String(err) });\n }\n }, [t]);\n\n return (\n <Form.Root\n schema={Settings.Settings}\n values={settings}\n variant='settings'\n readonly={readonly}\n onValuesChanged={(values) => updateSettings((current) => ({ ...current, ...values }))}\n >\n <Form.Viewport scroll>\n <Form.Content>\n <Form.FieldSet\n label={meta.profile.name ?? meta.profile.key}\n description={t('settings.description')}\n actions={readonly ? undefined : <SettingsScope prefix={subject.prefix} />}\n >\n <Form.Fields />\n </Form.FieldSet>\n\n <Form.FieldSet label={t('test.title')}>\n <Flex gap='sm'>\n <IconButton\n disabled={test.kind === 'pending'}\n icon='ph--plug--regular'\n label={t('test.button.label')}\n onClick={handleTest}\n />\n\n {/* role=status + aria-live so screen readers announce the async outcome. */}\n <Flex align='center'>\n <span\n role='status'\n aria-live='polite'\n className={\n test.kind === 'ok'\n ? 'text-sm text-success-text'\n : test.kind === 'error'\n ? 'text-sm text-error-text'\n : 'text-sm text-description'\n }\n >\n {test.kind === 'ok' || test.kind === 'error' ? test.message : ''}\n {test.kind === 'pending' ? t('test.pending.message') : ''}\n </span>\n </Flex>\n </Flex>\n </Form.FieldSet>\n </Form.Content>\n </Form.Viewport>\n </Form.Root>\n );\n};\n\nCrxSettings.displayName = 'CrxSettings';\n"],"mappings":";;;;;;;;;;;;;;AA4BA,IAAa,eAAe,EAAE,SAAS,eAAiC;CACtE,MAAM,EAAE,MAAM,eAAe,KAAK,QAAQ,GAAG;CAC7C,MAAM,EAAE,UAAU,mBAAmB,iBAAoC,QAAQ,IAAI;CACrF,MAAM,CAAC,MAAM,WAAW,SAAoB,EAAE,MAAM,OAAO,CAAC;CAG5D,MAAM,aAAa,YAAY,YAAY;EACzC,QAAQ,EAAE,MAAM,UAAU,CAAC;EAC3B,IAAI;GACF,MAAM,OAAO,MAAM,cAAc;GACjC,QAAQ;IACN,MAAM;IACN,SAAS,EAAE,0BAA0B;KAAE,MAAM,KAAK;KAAe,SAAS,KAAK;IAAiB,CAAC;GACnG,CAAC;EACH,SAAS,KAAK;GACZ,QAAQ;IAAE,MAAM;IAAS,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;GAAE,CAAC;EACtF;CACF,GAAG,CAAC,CAAC,CAAC;CAEN,OACE,oBAAC,KAAK,MAAN;EACE,QAAQ,SAAS;EACjB,QAAQ;EACR,SAAQ;EACE;EACV,kBAAkB,WAAW,gBAAgB,aAAa;GAAE,GAAG;GAAS,GAAG;EAAO,EAAE;EAEpF,UAAA,oBAAC,KAAK,UAAN;GAAe,QAAA;GACb,UAAA,qBAAC,KAAK,SAAN,EAAA,UAAA,CACE,oBAAC,KAAK,UAAN;IACE,OAAO,KAAK,QAAQ,QAAQ,KAAK,QAAQ;IACzC,aAAa,EAAE,sBAAsB;IACrC,SAAS,WAAW,KAAA,IAAY,oBAAC,eAAD,EAAe,QAAQ,QAAQ,OAAS,CAAA;IAExE,UAAA,oBAAC,KAAK,QAAN,CAAc,CAAA;GACD,CAAA,GAEf,oBAAC,KAAK,UAAN;IAAe,OAAO,EAAE,YAAY;IAClC,UAAA,qBAAC,MAAD;KAAM,KAAI;KAAV,UAAA,CACE,oBAAC,YAAD;MACE,UAAU,KAAK,SAAS;MACxB,MAAK;MACL,OAAO,EAAE,mBAAmB;MAC5B,SAAS;KACV,CAAA,GAGD,oBAAC,MAAD;MAAM,OAAM;MACV,UAAA,qBAAC,QAAD;OACE,MAAK;OACL,aAAU;OACV,WACE,KAAK,SAAS,OACV,8BACA,KAAK,SAAS,UACZ,4BACA;OARV,UAAA,CAWG,KAAK,SAAS,QAAQ,KAAK,SAAS,UAAU,KAAK,UAAU,IAC7D,KAAK,SAAS,YAAY,EAAE,sBAAsB,IAAI,EACnD;;KACF,CAAA,CACF;;GACO,CAAA,CACH,EAAA,CAAA;EACD,CAAA;CACN,CAAA;AAEf;AAEA,YAAY,cAAc"}
1
+ {"version":3,"file":"containers.mjs","names":[],"sources":["../../src/containers/CrxSettings/CrxSettings.tsx"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useCallback, useState } from 'react';\n\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport type * as AppSurface from '@dxos/app-toolkit/AppSurface';\nimport * as SettingsScope from '@dxos/app-toolkit/SettingsScope';\nimport { Form } from '@dxos/react-ui-form';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as UiHooks from '@dxos/react-ui/Hooks';\nimport * as Layout from '@dxos/react-ui/Layout';\n\nimport { meta } from '#meta';\nimport { Settings } from '#types';\n\nimport { pingExtension } from '../../util/index.ts';\n\ntype TestState =\n | { kind: 'idle' }\n | { kind: 'pending' }\n | { kind: 'ok'; message: string }\n | { kind: 'error'; message: string };\n\nexport type CrxSettingsProps = AppSurface.SettingsData<{ readonly?: boolean }>;\n\n/**\n * Settings panel for the browser extension: edits the plugin's schema-driven settings and offers a\n * round-trip connection test against the extension's content relay.\n */\nexport const CrxSettings = ({ subject, readonly }: CrxSettingsProps) => {\n const { t } = UiHooks.useTranslation(meta.profile.key);\n const { settings, updateSettings } = Hooks.useSettingsState<Settings.Settings>(subject.atom);\n const [test, setTest] = useState<TestState>({ kind: 'idle' });\n\n // Round-trip a ping to the extension and report its identity (or why it failed).\n const handleTest = useCallback(async () => {\n setTest({ kind: 'pending' });\n try {\n const info = await pingExtension();\n setTest({\n kind: 'ok',\n message: t('test.connected.message', { name: info.extensionName, version: info.extensionVersion }),\n });\n } catch (err) {\n setTest({ kind: 'error', message: err instanceof Error ? err.message : String(err) });\n }\n }, [t]);\n\n return (\n <Form.Root\n schema={Settings.Settings}\n values={settings}\n variant='settings'\n readonly={readonly}\n onValuesChanged={(values) => updateSettings((current) => ({ ...current, ...values }))}\n >\n <Form.Viewport scroll>\n <Form.Content>\n <Form.FieldSet\n label={meta.profile.name ?? meta.profile.key}\n description={t('settings.description')}\n actions={readonly ? undefined : <SettingsScope.Root prefix={subject.prefix} />}\n >\n <Form.Fields />\n </Form.FieldSet>\n\n <Form.FieldSet label={t('test.title')}>\n <Layout.Flex gap='sm'>\n <Button.Root\n disabled={test.kind === 'pending'}\n icon='ph--plug--regular'\n label={t('test.button.label')}\n onClick={handleTest}\n />\n\n {/* role=status + aria-live so screen readers announce the async outcome. */}\n <Layout.Flex align='center'>\n <span\n role='status'\n aria-live='polite'\n className={\n test.kind === 'ok'\n ? 'text-sm text-success-text'\n : test.kind === 'error'\n ? 'text-sm text-error-text'\n : 'text-sm text-fg-muted'\n }\n >\n {test.kind === 'ok' || test.kind === 'error' ? test.message : ''}\n {test.kind === 'pending' ? t('test.pending.message') : ''}\n </span>\n </Layout.Flex>\n </Layout.Flex>\n </Form.FieldSet>\n </Form.Content>\n </Form.Viewport>\n </Form.Root>\n );\n};\n\nCrxSettings.displayName = 'CrxSettings';\n"],"mappings":";;;;;;;;;;;;;;;;AA+BA,IAAa,eAAe,EAAE,SAAS,eAAiC;CACtE,MAAM,EAAE,MAAM,QAAQ,eAAe,KAAK,QAAQ,GAAG;CACrD,MAAM,EAAE,UAAU,mBAAmB,MAAM,iBAAoC,QAAQ,IAAI;CAC3F,MAAM,CAAC,MAAM,WAAW,SAAoB,EAAE,MAAM,OAAO,CAAC;CAG5D,MAAM,aAAa,YAAY,YAAY;EACzC,QAAQ,EAAE,MAAM,UAAU,CAAC;EAC3B,IAAI;GACF,MAAM,OAAO,MAAM,cAAc;GACjC,QAAQ;IACN,MAAM;IACN,SAAS,EAAE,0BAA0B;KAAE,MAAM,KAAK;KAAe,SAAS,KAAK;IAAiB,CAAC;GACnG,CAAC;EACH,SAAS,KAAK;GACZ,QAAQ;IAAE,MAAM;IAAS,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;GAAE,CAAC;EACtF;CACF,GAAG,CAAC,CAAC,CAAC;CAEN,OACE,oBAAC,KAAK,MAAN;EACE,QAAQ,SAAS;EACjB,QAAQ;EACR,SAAQ;EACE;EACV,kBAAkB,WAAW,gBAAgB,aAAa;GAAE,GAAG;GAAS,GAAG;EAAO,EAAE;EAEpF,UAAA,oBAAC,KAAK,UAAN;GAAe,QAAA;GACb,UAAA,qBAAC,KAAK,SAAN,EAAA,UAAA,CACE,oBAAC,KAAK,UAAN;IACE,OAAO,KAAK,QAAQ,QAAQ,KAAK,QAAQ;IACzC,aAAa,EAAE,sBAAsB;IACrC,SAAS,WAAW,KAAA,IAAY,oBAAC,cAAc,MAAf,EAAoB,QAAQ,QAAQ,OAAS,CAAA;IAE7E,UAAA,oBAAC,KAAK,QAAN,CAAc,CAAA;GACD,CAAA,GAEf,oBAAC,KAAK,UAAN;IAAe,OAAO,EAAE,YAAY;IAClC,UAAA,qBAAC,OAAO,MAAR;KAAa,KAAI;KAAjB,UAAA,CACE,oBAAC,OAAO,MAAR;MACE,UAAU,KAAK,SAAS;MACxB,MAAK;MACL,OAAO,EAAE,mBAAmB;MAC5B,SAAS;KACV,CAAA,GAGD,oBAAC,OAAO,MAAR;MAAa,OAAM;MACjB,UAAA,qBAAC,QAAD;OACE,MAAK;OACL,aAAU;OACV,WACE,KAAK,SAAS,OACV,8BACA,KAAK,SAAS,UACZ,4BACA;OARV,UAAA,CAWG,KAAK,SAAS,QAAQ,KAAK,SAAS,UAAU,KAAK,UAAU,IAC7D,KAAK,SAAS,YAAY,EAAE,sBAAsB,IAAI,EACnD;;KACK,CAAA,CACF;;GACA,CAAA,CACH,EAAA,CAAA;EACD,CAAA;CACN,CAAA;AAEf;AAEA,YAAY,cAAc"}
@@ -1,4 +1,3 @@
1
1
  import { t as CrxPlugin_exports } from "./CrxPlugin.mjs";
2
2
  export * from "#types";
3
- export * from "#meta";
4
3
  export { CrxPlugin_exports as CrxPlugin };
@@ -1 +1 @@
1
- {"version":3,"file":"translations.mjs","names":[],"sources":["../../src/translations.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport { type Resource } from '@dxos/react-ui';\n\nimport { meta } from '#meta';\n\nexport const translations = [\n {\n 'en-US': {\n [meta.profile.key]: {\n 'plugin.name': 'Browser Extension',\n 'settings.description':\n 'Install the browser extension from the [Chrome Web Store](https://chromewebstore.google.com/detail/composer/ahkmmpagcinoehpnmdhoiohmmbikhnmj?pli=1).',\n 'test.title': 'Connection',\n 'test.button.label': 'Test connection',\n 'test.pending.message': 'Contacting extension…',\n 'test.connected.message': 'Connected to {{name}} v{{version}}.',\n 'toast.error.invalidPayload.message': 'Unrecognized payload.',\n 'toast.error.unsupportedVersion.message': 'Unsupported version — update Composer.',\n 'toast.error.disabled.message': 'Extension actions are disabled in settings.',\n 'toast.error.noSpace.message': 'Open a space first.',\n 'toast.page-action.success.title': 'Action complete',\n 'toast.page-action.error.title': 'Action failed',\n 'toast.error.unknownAction.message': 'Unknown action — update Composer or the extension.',\n 'toast.error.operationFailed.message': 'The action failed to run.',\n },\n },\n },\n] as const satisfies Resource[];\n"],"mappings":";;AAQA,IAAa,eAAe,CAC1B,EACE,SAAS,GACN,KAAK,QAAQ,MAAM;CAClB,eAAe;CACf,wBACE;CACF,cAAc;CACd,qBAAqB;CACrB,wBAAwB;CACxB,0BAA0B;CAC1B,sCAAsC;CACtC,0CAA0C;CAC1C,gCAAgC;CAChC,+BAA+B;CAC/B,mCAAmC;CACnC,iCAAiC;CACjC,qCAAqC;CACrC,uCAAuC;AACzC,EACF,EACF,CACF"}
1
+ {"version":3,"file":"translations.mjs","names":[],"sources":["../../src/translations.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport type * as Theme from '@dxos/react-ui/Theme';\n\nimport { meta } from '#meta';\n\nexport const translations = [\n {\n 'en-US': {\n [meta.profile.key]: {\n 'plugin.name': 'Browser Extension',\n 'settings.description':\n 'Install the browser extension from the [Chrome Web Store](https://chromewebstore.google.com/detail/composer/ahkmmpagcinoehpnmdhoiohmmbikhnmj?pli=1).',\n 'test.title': 'Connection',\n 'test.button.label': 'Test connection',\n 'test.pending.message': 'Contacting extension…',\n 'test.connected.message': 'Connected to {{name}} v{{version}}.',\n 'toast.error.invalidPayload.message': 'Unrecognized payload.',\n 'toast.error.unsupportedVersion.message': 'Unsupported version — update Composer.',\n 'toast.error.disabled.message': 'Extension actions are disabled in settings.',\n 'toast.error.noSpace.message': 'Open a space first.',\n 'toast.page-action.success.title': 'Action complete',\n 'toast.page-action.error.title': 'Action failed',\n 'toast.error.unknownAction.message': 'Unknown action — update Composer or the extension.',\n 'toast.error.operationFailed.message': 'The action failed to run.',\n },\n },\n },\n] as const satisfies Theme.Resource[];\n"],"mappings":";;AAQA,IAAa,eAAe,CAC1B,EACE,SAAS,GACN,KAAK,QAAQ,MAAM;CAClB,eAAe;CACf,wBACE;CACF,cAAc;CACd,qBAAqB;CACrB,wBAAwB;CACxB,0BAA0B;CAC1B,sCAAsC;CACtC,0CAA0C;CAC1C,gCAAgC;CAChC,+BAA+B;CAC/B,mCAAmC;CACnC,iCAAiC;CACjC,qCAAqC;CACrC,uCAAuC;AACzC,EACF,EACF,CACF"}
@@ -0,0 +1,9 @@
1
+ import * as Capability from '@dxos/app-framework/Capability';
2
+ export declare const CrxSettings: Capability.Module<void>;
3
+ export declare const InstallPageActions: Capability.Module<void>;
4
+ export declare const OperationHandler: Capability.Module<void>;
5
+ export declare const PageActionProvider: Capability.Module<void>;
6
+ export declare const PluginAsset: Capability.Module<void>;
7
+ export declare const ReactSurface: Capability.Module<void>;
8
+ export declare const Translations: Capability.Module<void>;
9
+ //# sourceMappingURL=browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../../../../src/capabilities/gen/browser.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,UAAU,MAAM,gCAAgC,CAAC;AAS7D,eAAO,MAAM,WAAW,yBAGtB,CAAC;AAEH,eAAO,MAAM,kBAAkB,yBAQ9B,CAAC;AAEF,eAAO,MAAM,gBAAgB,yBAE3B,CAAC;AAEH,eAAO,MAAM,kBAAkB,yBAI9B,CAAC;AAEF,eAAO,MAAM,WAAW,yBAKtB,CAAC;AAEH,eAAO,MAAM,YAAY,yBAEvB,CAAC;AAEH,eAAO,MAAM,YAAY,yBAA2C,CAAC"}
@@ -0,0 +1,9 @@
1
+ import * as Capability from '@dxos/app-framework/Capability';
2
+ export declare const CrxSettings: Capability.Module<void>;
3
+ export declare const InstallPageActions: Capability.Module<void>;
4
+ export declare const OperationHandler: Capability.Module<void>;
5
+ export declare const PageActionProvider: Capability.Module<void>;
6
+ export declare const PluginAsset: Capability.Module<void>;
7
+ export declare const ReactSurface: Capability.Module<void>;
8
+ export declare const Translations: Capability.Module<void>;
9
+ //# sourceMappingURL=tauri.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tauri.d.ts","sourceRoot":"","sources":["../../../../../src/capabilities/gen/tauri.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,UAAU,MAAM,gCAAgC,CAAC;AAS7D,eAAO,MAAM,WAAW,yBAGtB,CAAC;AAEH,eAAO,MAAM,kBAAkB,yBAQ9B,CAAC;AAEF,eAAO,MAAM,gBAAgB,yBAE3B,CAAC;AAEH,eAAO,MAAM,kBAAkB,yBAI9B,CAAC;AAEF,eAAO,MAAM,WAAW,yBAKtB,CAAC;AAEH,eAAO,MAAM,YAAY,yBAEvB,CAAC;AAEH,eAAO,MAAM,YAAY,yBAA2C,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { type AppSurface } from '@dxos/app-toolkit/ui';
2
+ import type * as AppSurface from '@dxos/app-toolkit/AppSurface';
3
3
  export type CrxSettingsProps = AppSurface.SettingsData<{
4
4
  readonly?: boolean;
5
5
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"CrxSettings.d.ts","sourceRoot":"","sources":["../../../../../src/containers/CrxSettings/CrxSettings.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAgC,MAAM,OAAO,CAAC;AAGrD,OAAO,EAAE,KAAK,UAAU,EAAiB,MAAM,sBAAsB,CAAC;AAetE,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC,YAAY,CAAC;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;oCAMnD,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,gBAAgB"}
1
+ {"version":3,"file":"CrxSettings.d.ts","sourceRoot":"","sources":["../../../../../src/containers/CrxSettings/CrxSettings.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAgC,MAAM,OAAO,CAAC;AAGrD,OAAO,KAAK,KAAK,UAAU,MAAM,8BAA8B,CAAC;AAkBhE,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC,YAAY,CAAC;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;oCAMnD,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,gBAAgB"}
@@ -1,4 +1,3 @@
1
1
  export * as CrxPlugin from './CrxPlugin.ts';
2
- export * from '#meta';
3
2
  export * from '#types';
4
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAC;AAC5C,cAAc,OAAO,CAAC;AACtB,cAAc,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAC;AAC5C,cAAc,QAAQ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Testbench.stories.d.ts","sourceRoot":"","sources":["../../../../src/stories/Testbench.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,KAAkB,MAAM,OAAO,CAAC;AAMvC,QAAA,MAAM,YAAY,yBAqBjB,CAAC;AAEF,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,YAAY,CAInC,CAAC;eAEa,IAAI;AAEnB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAAU,CAAC"}
1
+ {"version":3,"file":"Testbench.stories.d.ts","sourceRoot":"","sources":["../../../../src/stories/Testbench.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,KAAkB,MAAM,OAAO,CAAC;AAOvC,QAAA,MAAM,YAAY,yBAqBjB,CAAC;AAEF,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,YAAY,CAInC,CAAC;eAEa,IAAI;AAEnB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAAU,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"translations.d.ts","sourceRoot":"","sources":["../../../src/translations.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAE7B,eAAO,MAAM,YAAY;;QAGnB,SAAA,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;oCACD,mBAAmB;6CAEhC,sJAAsJ;mCAC1I,YAAY;0CACL,iBAAiB;6CACd,uBAAuB;+CACrB,qCAAqC;2DACzB,uBAAuB;+DACnB,wCAAwC;qDAClD,6CAA6C;oDAC9C,qBAAqB;wDACjB,iBAAiB;sDACnB,eAAe;0DACX,oDAAoD;4DAClD,2BAA2B;UACnE;;EAGwB,CAAC"}
1
+ {"version":3,"file":"translations.d.ts","sourceRoot":"","sources":["../../../src/translations.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAE7B,eAAO,MAAM,YAAY;;QAGnB,SAAA,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;oCACD,mBAAmB;6CAEhC,sJAAsJ;mCAC1I,YAAY;0CACL,iBAAiB;6CACd,uBAAuB;+CACrB,qCAAqC;2DACzB,uBAAuB;+DACnB,wCAAwC;qDAClD,6CAA6C;oDAC9C,qBAAqB;wDACjB,iBAAiB;sDACnB,eAAe;0DACX,oDAAoD;4DAClD,2BAA2B;UACnE;;EAG8B,CAAC"}
@@ -1,4 +1,4 @@
1
- import type * as Atom from 'effect/unstable/reactivity/Atom';
1
+ import type * as Atom from 'effect/reactivity/Atom';
2
2
  import * as Capability from '@dxos/app-framework/Capability';
3
3
  /**
4
4
  * Writable atom holding the plugin's Settings.
@@ -1 +1 @@
1
- {"version":3,"file":"CrxCapabilities.d.ts","sourceRoot":"","sources":["../../../../src/types/CrxCapabilities.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,IAAI,MAAM,iCAAiC,CAAC;AAE7D,OAAO,KAAK,UAAU,MAAM,gCAAgC,CAAC;AAI7D;;GAEG;AACH,eAAO,MAAM,QAAQ,oIAEpB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU,gGAEtB,CAAC"}
1
+ {"version":3,"file":"CrxCapabilities.d.ts","sourceRoot":"","sources":["../../../../src/types/CrxCapabilities.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,IAAI,MAAM,wBAAwB,CAAC;AAEpD,OAAO,KAAK,UAAU,MAAM,gCAAgC,CAAC;AAI7D;;GAEG;AACH,eAAO,MAAM,QAAQ,oIAEpB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU,gGAEtB,CAAC"}