@dxos/plugin-crx 0.0.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 (168) hide show
  1. package/LICENSE +105 -0
  2. package/PLUGIN.mdl +599 -0
  3. package/README.md +25 -0
  4. package/dist/lib/CrxCapabilities.mjs +21 -0
  5. package/dist/lib/CrxCapabilities.mjs.map +1 -0
  6. package/dist/lib/CrxEvents.mjs +15 -0
  7. package/dist/lib/CrxEvents.mjs.map +1 -0
  8. package/dist/lib/CrxOperation.mjs +50 -0
  9. package/dist/lib/CrxOperation.mjs.map +1 -0
  10. package/dist/lib/CrxPlugin.mjs +16 -0
  11. package/dist/lib/CrxPlugin.mjs.map +1 -0
  12. package/dist/lib/PageAction.mjs +35 -0
  13. package/dist/lib/PageAction.mjs.map +1 -0
  14. package/dist/lib/Settings.mjs +84 -0
  15. package/dist/lib/Settings.mjs.map +1 -0
  16. package/dist/lib/capabilities.mjs +41 -0
  17. package/dist/lib/capabilities.mjs.map +1 -0
  18. package/dist/lib/capabilities.node.mjs +32 -0
  19. package/dist/lib/capabilities.node.mjs.map +1 -0
  20. package/dist/lib/capabilities.workerd.mjs +32 -0
  21. package/dist/lib/capabilities.workerd.mjs.map +1 -0
  22. package/dist/lib/chunk-add-note-from-snapshot.mjs +15 -0
  23. package/dist/lib/chunk-add-note-from-snapshot.mjs.map +1 -0
  24. package/dist/lib/chunk-add-organization-from-snapshot.mjs +15 -0
  25. package/dist/lib/chunk-add-organization-from-snapshot.mjs.map +1 -0
  26. package/dist/lib/chunk-add-person-from-snapshot.mjs +15 -0
  27. package/dist/lib/chunk-add-person-from-snapshot.mjs.map +1 -0
  28. package/dist/lib/chunk-install-page-actions.mjs +284 -0
  29. package/dist/lib/chunk-install-page-actions.mjs.map +1 -0
  30. package/dist/lib/chunk-mapping.mjs +81 -0
  31. package/dist/lib/chunk-mapping.mjs.map +1 -0
  32. package/dist/lib/chunk-operation-handler.mjs +12 -0
  33. package/dist/lib/chunk-operation-handler.mjs.map +1 -0
  34. package/dist/lib/chunk-page-action-provider.mjs +41 -0
  35. package/dist/lib/chunk-page-action-provider.mjs.map +1 -0
  36. package/dist/lib/chunk-react-surface.mjs +18 -0
  37. package/dist/lib/chunk-react-surface.mjs.map +1 -0
  38. package/dist/lib/chunk-rolldown-runtime.mjs +13 -0
  39. package/dist/lib/chunk-settings.mjs +28 -0
  40. package/dist/lib/chunk-settings.mjs.map +1 -0
  41. package/dist/lib/containers.mjs +80 -0
  42. package/dist/lib/containers.mjs.map +1 -0
  43. package/dist/lib/index.mjs +4 -0
  44. package/dist/lib/meta.mjs +34 -0
  45. package/dist/lib/meta.mjs.map +1 -0
  46. package/dist/lib/operations.mjs +13 -0
  47. package/dist/lib/operations.mjs.map +1 -0
  48. package/dist/lib/plugin.mjs +9 -0
  49. package/dist/lib/plugin.mjs.map +1 -0
  50. package/dist/lib/translations.mjs +22 -0
  51. package/dist/lib/translations.mjs.map +1 -0
  52. package/dist/lib/types.mjs +6 -0
  53. package/dist/lib/util.mjs +63 -0
  54. package/dist/lib/util.mjs.map +1 -0
  55. package/dist/types/dx.config.d.ts +28 -0
  56. package/dist/types/dx.config.d.ts.map +1 -0
  57. package/dist/types/src/CrxPlugin.d.ts +37 -0
  58. package/dist/types/src/CrxPlugin.d.ts.map +1 -0
  59. package/dist/types/src/capabilities/gen/node.d.ts +9 -0
  60. package/dist/types/src/capabilities/gen/node.d.ts.map +1 -0
  61. package/dist/types/src/capabilities/gen/workerd.d.ts +9 -0
  62. package/dist/types/src/capabilities/gen/workerd.d.ts.map +1 -0
  63. package/dist/types/src/capabilities/index.d.ts +9 -0
  64. package/dist/types/src/capabilities/index.d.ts.map +1 -0
  65. package/dist/types/src/capabilities/install-page-actions.d.ts +5 -0
  66. package/dist/types/src/capabilities/install-page-actions.d.ts.map +1 -0
  67. package/dist/types/src/capabilities/operation-handler.d.ts +5 -0
  68. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
  69. package/dist/types/src/capabilities/page-action-provider.d.ts +5 -0
  70. package/dist/types/src/capabilities/page-action-provider.d.ts.map +1 -0
  71. package/dist/types/src/capabilities/react-surface.d.ts +5 -0
  72. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  73. package/dist/types/src/capabilities/settings.d.ts +10 -0
  74. package/dist/types/src/capabilities/settings.d.ts.map +1 -0
  75. package/dist/types/src/containers/CrxSettings/CrxSettings.d.ts +10 -0
  76. package/dist/types/src/containers/CrxSettings/CrxSettings.d.ts.map +1 -0
  77. package/dist/types/src/containers/CrxSettings/CrxSettings.stories.d.ts +25 -0
  78. package/dist/types/src/containers/CrxSettings/CrxSettings.stories.d.ts.map +1 -0
  79. package/dist/types/src/containers/CrxSettings/index.d.ts +2 -0
  80. package/dist/types/src/containers/CrxSettings/index.d.ts.map +1 -0
  81. package/dist/types/src/containers/index.d.ts +2 -0
  82. package/dist/types/src/containers/index.d.ts.map +1 -0
  83. package/dist/types/src/index.d.ts +4 -0
  84. package/dist/types/src/index.d.ts.map +1 -0
  85. package/dist/types/src/mapping.d.ts +24 -0
  86. package/dist/types/src/mapping.d.ts.map +1 -0
  87. package/dist/types/src/mapping.test.d.ts +2 -0
  88. package/dist/types/src/mapping.test.d.ts.map +1 -0
  89. package/dist/types/src/meta.d.ts +33 -0
  90. package/dist/types/src/meta.d.ts.map +1 -0
  91. package/dist/types/src/operations/add-note-from-snapshot.d.ts +5 -0
  92. package/dist/types/src/operations/add-note-from-snapshot.d.ts.map +1 -0
  93. package/dist/types/src/operations/add-organization-from-snapshot.d.ts +5 -0
  94. package/dist/types/src/operations/add-organization-from-snapshot.d.ts.map +1 -0
  95. package/dist/types/src/operations/add-person-from-snapshot.d.ts +5 -0
  96. package/dist/types/src/operations/add-person-from-snapshot.d.ts.map +1 -0
  97. package/dist/types/src/operations/index.d.ts +3 -0
  98. package/dist/types/src/operations/index.d.ts.map +1 -0
  99. package/dist/types/src/page-actions.d.ts +39 -0
  100. package/dist/types/src/page-actions.d.ts.map +1 -0
  101. package/dist/types/src/page-actions.test.d.ts +2 -0
  102. package/dist/types/src/page-actions.test.d.ts.map +1 -0
  103. package/dist/types/src/plugin.d.ts +4 -0
  104. package/dist/types/src/plugin.d.ts.map +1 -0
  105. package/dist/types/src/stories/Testbench.stories.d.ts +8 -0
  106. package/dist/types/src/stories/Testbench.stories.d.ts.map +1 -0
  107. package/dist/types/src/translations.d.ts +22 -0
  108. package/dist/types/src/translations.d.ts.map +1 -0
  109. package/dist/types/src/types/CrxCapabilities.d.ts +12 -0
  110. package/dist/types/src/types/CrxCapabilities.d.ts.map +1 -0
  111. package/dist/types/src/types/CrxEvents.d.ts +8 -0
  112. package/dist/types/src/types/CrxEvents.d.ts.map +1 -0
  113. package/dist/types/src/types/CrxOperation.d.ts +108 -0
  114. package/dist/types/src/types/CrxOperation.d.ts.map +1 -0
  115. package/dist/types/src/types/PageAction.d.ts +153 -0
  116. package/dist/types/src/types/PageAction.d.ts.map +1 -0
  117. package/dist/types/src/types/Settings.d.ts +25 -0
  118. package/dist/types/src/types/Settings.d.ts.map +1 -0
  119. package/dist/types/src/types/Settings.test.d.ts +2 -0
  120. package/dist/types/src/types/Settings.test.d.ts.map +1 -0
  121. package/dist/types/src/types/index.d.ts +6 -0
  122. package/dist/types/src/types/index.d.ts.map +1 -0
  123. package/dist/types/src/util/index.d.ts +2 -0
  124. package/dist/types/src/util/index.d.ts.map +1 -0
  125. package/dist/types/src/util/pingExtension.d.ts +15 -0
  126. package/dist/types/src/util/pingExtension.d.ts.map +1 -0
  127. package/dist/types/src/util/pingExtension.test.d.ts +2 -0
  128. package/dist/types/src/util/pingExtension.test.d.ts.map +1 -0
  129. package/dist/types/tsconfig.tsbuildinfo +1 -0
  130. package/dx.config.ts +32 -0
  131. package/package.json +162 -0
  132. package/src/CrxPlugin.ts +15 -0
  133. package/src/capabilities/gen/node.ts +43 -0
  134. package/src/capabilities/gen/workerd.ts +43 -0
  135. package/src/capabilities/index.ts +47 -0
  136. package/src/capabilities/install-page-actions.ts +64 -0
  137. package/src/capabilities/operation-handler.ts +16 -0
  138. package/src/capabilities/page-action-provider.ts +47 -0
  139. package/src/capabilities/react-surface.ts +26 -0
  140. package/src/capabilities/settings.ts +36 -0
  141. package/src/containers/CrxSettings/CrxSettings.stories.tsx +99 -0
  142. package/src/containers/CrxSettings/CrxSettings.tsx +100 -0
  143. package/src/containers/CrxSettings/index.ts +5 -0
  144. package/src/containers/index.ts +5 -0
  145. package/src/index.ts +7 -0
  146. package/src/mapping.test.ts +87 -0
  147. package/src/mapping.ts +101 -0
  148. package/src/meta.ts +9 -0
  149. package/src/operations/add-note-from-snapshot.ts +24 -0
  150. package/src/operations/add-organization-from-snapshot.ts +29 -0
  151. package/src/operations/add-person-from-snapshot.ts +29 -0
  152. package/src/operations/index.ts +16 -0
  153. package/src/page-actions.test.ts +164 -0
  154. package/src/page-actions.ts +171 -0
  155. package/src/plugin.tsx +29 -0
  156. package/src/stories/Testbench.stories.tsx +45 -0
  157. package/src/translations.ts +31 -0
  158. package/src/types/CrxCapabilities.ts +26 -0
  159. package/src/types/CrxEvents.ts +16 -0
  160. package/src/types/CrxOperation.ts +54 -0
  161. package/src/types/PageAction.ts +57 -0
  162. package/src/types/Settings.test.ts +30 -0
  163. package/src/types/Settings.ts +101 -0
  164. package/src/types/index.ts +9 -0
  165. package/src/util/index.ts +5 -0
  166. package/src/util/pingExtension.test.ts +69 -0
  167. package/src/util/pingExtension.ts +83 -0
  168. package/src/vite-env.d.ts +10 -0
package/README.md ADDED
@@ -0,0 +1,25 @@
1
+ # @dxos/plugin-crx
2
+
3
+ Coordinates with the [`@dxos/composer-crx`](../../apps/composer-crx) browser
4
+ extension. This plugin owns the Composer side of the page-actions bridge:
5
+
6
+ - Plugins contribute page actions under `CrxCapabilities.PageAction` — a
7
+ serializable descriptor (label, icon, URL patterns, contexts, extractor)
8
+ paired with a target operation. This plugin contributes three picker
9
+ actions (Person, Organization, Note); plugin-bookmarks contributes
10
+ "Add bookmark".
11
+ - The extension lists contributed actions via
12
+ `CustomEvent('composer:page-actions:list')`, caches the descriptors in its
13
+ registry, and invokes an action via
14
+ `CustomEvent('composer:page-action:invoke')`. Every request is acked with
15
+ stable error codes (`invalidPayload`, `unsupportedVersion`,
16
+ `unknownAction`, `noSpace`, `operationFailed`).
17
+ - Picked/extracted content travels as a `PageAction.Snapshot` (source,
18
+ selection, hints, optional image data). The target operation receives
19
+ `{ snapshot, target }` — where `target` is the active space's database —
20
+ and creates the object there; outcomes surface as toasts.
21
+
22
+ It also owns the user-facing settings surface, including the render-proxy
23
+ settings and an extension connection test.
24
+
25
+ See [PLUGIN.mdl](./PLUGIN.mdl) for the specification.
@@ -0,0 +1,21 @@
1
+ import { t as __exportAll } from "./chunk-rolldown-runtime.mjs";
2
+ import * as Capability from "@dxos/app-framework/Capability";
3
+ import { meta } from "#meta";
4
+ //#region src/types/CrxCapabilities.ts
5
+ var CrxCapabilities_exports = /* @__PURE__ */ __exportAll({
6
+ PageAction: () => PageAction,
7
+ Settings: () => Settings
8
+ });
9
+ /**
10
+ * Writable atom holding the plugin's Settings.
11
+ */
12
+ var Settings = Capability.makeSingleton()(`${meta.profile.key}.capability.settings`);
13
+ /**
14
+ * Page actions contributed by plugins for the browser extension to surface.
15
+ * Multi: each contributor provides one array (e.g. plugin-bookmarks); consumers flatten via `getAll`.
16
+ */
17
+ var PageAction = Capability.make()(`${meta.profile.key}.capability.pageAction`);
18
+ //#endregion
19
+ export { PageAction, Settings, CrxCapabilities_exports as t };
20
+
21
+ //# sourceMappingURL=CrxCapabilities.mjs.map
@@ -0,0 +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"}
@@ -0,0 +1,15 @@
1
+ import { t as __exportAll } from "./chunk-rolldown-runtime.mjs";
2
+ import { meta } from "#meta";
3
+ import * as ActivationEvent from "@dxos/app-framework/ActivationEvent";
4
+ //#region src/types/CrxEvents.ts
5
+ var CrxEvents_exports = /* @__PURE__ */ __exportAll({ Start: () => Start });
6
+ /**
7
+ * The feature's start event: the plugin's start-gated modules (and cross-plugin
8
+ * contributions consumed by this feature) activate here. Fired on demand and by the
9
+ * host's idle trickle.
10
+ */
11
+ var Start = ActivationEvent.pluginStart(meta.profile.key);
12
+ //#endregion
13
+ export { Start, CrxEvents_exports as t };
14
+
15
+ //# sourceMappingURL=CrxEvents.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CrxEvents.mjs","names":[],"sources":["../../src/types/CrxEvents.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as ActivationEvent from '@dxos/app-framework/ActivationEvent';\n\nimport { meta } from '#meta';\n\n/**\n * The feature's start event: the plugin's start-gated modules (and cross-plugin\n * contributions consumed by this feature) activate here. Fired on demand and by the\n * host's idle trickle.\n */\nexport const Start = ActivationEvent.pluginStart(meta.profile.key);\n"],"mappings":";;;;;;;;;;AAeA,IAAa,QAAQ,gBAAgB,YAAY,KAAK,QAAQ,GAAG"}
@@ -0,0 +1,50 @@
1
+ import { t as __exportAll } from "./chunk-rolldown-runtime.mjs";
2
+ import { Snapshot } from "./PageAction.mjs";
3
+ import * as Operation from "@dxos/compute/Operation";
4
+ import * as Schema from "effect/Schema";
5
+ import { DXN, Database } from "@dxos/echo";
6
+ //#region src/types/CrxOperation.ts
7
+ var CrxOperation_exports = /* @__PURE__ */ __exportAll({
8
+ AddNoteFromSnapshot: () => AddNoteFromSnapshot,
9
+ AddOrganizationFromSnapshot: () => AddOrganizationFromSnapshot,
10
+ AddPersonFromSnapshot: () => AddPersonFromSnapshot
11
+ });
12
+ var input = Schema.Struct({
13
+ snapshot: Snapshot,
14
+ target: Database.Database.annotate({ description: "The database to add the object to." })
15
+ });
16
+ var output = Schema.Struct({ id: Schema.String });
17
+ var AddPersonFromSnapshot = Operation.make({
18
+ meta: {
19
+ key: DXN.make("org.dxos.operation.crx.addPersonFromSnapshot"),
20
+ name: "Add person",
21
+ description: "Create a person from a page snapshot.",
22
+ icon: "ph--user--regular"
23
+ },
24
+ input,
25
+ output
26
+ });
27
+ var AddOrganizationFromSnapshot = Operation.make({
28
+ meta: {
29
+ key: DXN.make("org.dxos.operation.crx.addOrganizationFromSnapshot"),
30
+ name: "Add organization",
31
+ description: "Create an organization from a page snapshot.",
32
+ icon: "ph--building-office--regular"
33
+ },
34
+ input,
35
+ output
36
+ });
37
+ var AddNoteFromSnapshot = Operation.make({
38
+ meta: {
39
+ key: DXN.make("org.dxos.operation.crx.addNoteFromSnapshot"),
40
+ name: "Add note",
41
+ description: "Create a markdown note from a page snapshot.",
42
+ icon: "ph--note--regular"
43
+ },
44
+ input,
45
+ output
46
+ });
47
+ //#endregion
48
+ export { AddNoteFromSnapshot, AddOrganizationFromSnapshot, AddPersonFromSnapshot, CrxOperation_exports as t };
49
+
50
+ //# sourceMappingURL=CrxOperation.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CrxOperation.mjs","names":[],"sources":["../../src/types/CrxOperation.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as Schema from 'effect/Schema';\n\nimport * as Operation from '@dxos/compute/Operation';\nimport { Database, DXN } from '@dxos/echo';\n\nimport * as PageAction from './PageAction.ts';\n\nconst input = Schema.Struct({\n snapshot: PageAction.Snapshot,\n target: Database.Database.annotate({ description: 'The database to add the object to.' }),\n});\n\nconst output = Schema.Struct({\n id: Schema.String,\n});\n\nexport const AddPersonFromSnapshot = Operation.make({\n meta: {\n key: DXN.make('org.dxos.operation.crx.addPersonFromSnapshot'),\n name: 'Add person',\n description: 'Create a person from a page snapshot.',\n icon: 'ph--user--regular',\n },\n input,\n output,\n});\n\nexport const AddOrganizationFromSnapshot = Operation.make({\n meta: {\n key: DXN.make('org.dxos.operation.crx.addOrganizationFromSnapshot'),\n name: 'Add organization',\n description: 'Create an organization from a page snapshot.',\n icon: 'ph--building-office--regular',\n },\n input,\n output,\n});\n\nexport const AddNoteFromSnapshot = Operation.make({\n meta: {\n key: DXN.make('org.dxos.operation.crx.addNoteFromSnapshot'),\n name: 'Add note',\n description: 'Create a markdown note from a page snapshot.',\n icon: 'ph--note--regular',\n },\n input,\n output,\n});\n"],"mappings":";;;;;;;;;;;AAaA,IAAM,QAAQ,OAAO,OAAO;CAC1B,UAAU;CACV,QAAQ,SAAS,SAAS,SAAS,EAAE,aAAa,qCAAqC,CAAC;AAC1F,CAAC;AAED,IAAM,SAAS,OAAO,OAAO,EAC3B,IAAI,OAAO,OACb,CAAC;AAED,IAAa,wBAAwB,UAAU,KAAK;CAClD,MAAM;EACJ,KAAK,IAAI,KAAK,8CAA8C;EAC5D,MAAM;EACN,aAAa;EACb,MAAM;CACR;CACA;CACA;AACF,CAAC;AAED,IAAa,8BAA8B,UAAU,KAAK;CACxD,MAAM;EACJ,KAAK,IAAI,KAAK,oDAAoD;EAClE,MAAM;EACN,aAAa;EACb,MAAM;CACR;CACA;CACA;AACF,CAAC;AAED,IAAa,sBAAsB,UAAU,KAAK;CAChD,MAAM;EACJ,KAAK,IAAI,KAAK,4CAA4C;EAC1D,MAAM;EACN,aAAa;EACb,MAAM;CACR;CACA;CACA;AACF,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { t as __exportAll } from "./chunk-rolldown-runtime.mjs";
2
+ import { meta as meta$1 } from "#meta";
3
+ import * as Plugin from "@dxos/app-framework/Plugin";
4
+ //#region src/CrxPlugin.ts
5
+ var CrxPlugin_exports = /* @__PURE__ */ __exportAll({
6
+ make: () => make,
7
+ meta: () => meta
8
+ });
9
+ /** Plugin metadata, available without loading the plugin body. */
10
+ var meta = meta$1;
11
+ /** Constructs the plugin; the body loads on first enable. */
12
+ var make = Plugin.lazy(meta, () => import("#plugin"));
13
+ //#endregion
14
+ export { make, meta, CrxPlugin_exports as t };
15
+
16
+ //# sourceMappingURL=CrxPlugin.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CrxPlugin.mjs","names":[],"sources":["../../src/CrxPlugin.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as Plugin from '@dxos/app-framework/Plugin';\n\nimport { meta as pluginMeta } from '#meta';\n\n/** Plugin metadata, available without loading the plugin body. */\nexport const meta = pluginMeta;\n\n/** Constructs the plugin; the body loads on first enable. */\nexport const make = Plugin.lazy(meta, () => import('#plugin'));\n"],"mappings":";;;;;;;;;AAWA,IAAa,OAAO;;AAGpB,IAAa,OAAO,OAAO,KAAK,YAAY,OAAO,UAAU"}
@@ -0,0 +1,35 @@
1
+ import { t as __exportAll } from "./chunk-rolldown-runtime.mjs";
2
+ import { PageAction } from "@dxos/crx-protocol";
3
+ //#region src/types/PageAction.ts
4
+ var PageAction_exports = /* @__PURE__ */ __exportAll({
5
+ Context: () => Context,
6
+ Descriptor: () => Descriptor,
7
+ Envelope: () => Envelope,
8
+ ExtractorRef: () => ExtractorRef,
9
+ Hints: () => Hints,
10
+ INVOKE_ACK_EVENT: () => INVOKE_ACK_EVENT,
11
+ INVOKE_EVENT: () => INVOKE_EVENT,
12
+ InvokeAck: () => InvokeAck,
13
+ InvokeRequest: () => InvokeRequest,
14
+ LIST_ACK_EVENT: () => LIST_ACK_EVENT,
15
+ LIST_EVENT: () => LIST_EVENT,
16
+ ListAck: () => ListAck,
17
+ ListRequest: () => ListRequest,
18
+ PageInfo: () => PageInfo,
19
+ Predicate: () => Predicate,
20
+ READY_EVENT: () => READY_EVENT,
21
+ Rect: () => Rect,
22
+ Selection: () => Selection,
23
+ Snapshot: () => Snapshot,
24
+ Source: () => Source,
25
+ toDescriptor: () => toDescriptor
26
+ });
27
+ var { Rect, Source, Selection, Hints, Snapshot, Predicate, ExtractorRef, Context, Descriptor, PageInfo, Envelope, ListRequest, ListAck, InvokeRequest, InvokeAck, READY_EVENT, LIST_EVENT, LIST_ACK_EVENT, INVOKE_EVENT, INVOKE_ACK_EVENT } = PageAction;
28
+ var toDescriptor = (action) => ({
29
+ ...action,
30
+ operation: action.operation.meta.key.toString()
31
+ });
32
+ //#endregion
33
+ export { Context, Descriptor, Envelope, ExtractorRef, Hints, INVOKE_ACK_EVENT, INVOKE_EVENT, InvokeAck, InvokeRequest, LIST_ACK_EVENT, LIST_EVENT, ListAck, ListRequest, PageInfo, Predicate, READY_EVENT, Rect, Selection, Snapshot, Source, PageAction_exports as t, toDescriptor };
34
+
35
+ //# sourceMappingURL=PageAction.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PageAction.mjs","names":[],"sources":["../../src/types/PageAction.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// @import-as-namespace\n\nimport type * as Operation from '@dxos/compute/Operation';\nimport { PageAction as Protocol } from '@dxos/crx-protocol';\n\n// Re-export the serializable wire schemas from the shared protocol package.\nexport const {\n Rect,\n Source,\n Selection,\n Hints,\n Snapshot,\n Predicate,\n ExtractorRef,\n Context,\n Descriptor,\n PageInfo,\n Envelope,\n ListRequest,\n ListAck,\n InvokeRequest,\n InvokeAck,\n READY_EVENT,\n LIST_EVENT,\n LIST_ACK_EVENT,\n INVOKE_EVENT,\n INVOKE_ACK_EVENT,\n} = Protocol;\n\nexport type Source = Protocol.Source;\nexport type Selection = Protocol.Selection;\nexport type Hints = Protocol.Hints;\nexport type Snapshot = Protocol.Snapshot;\nexport type Predicate = Protocol.Predicate;\nexport type ExtractorRef = Protocol.ExtractorRef;\nexport type Context = Protocol.Context;\nexport type Descriptor = Protocol.Descriptor;\nexport type PageInfo = Protocol.PageInfo;\nexport type Envelope = Protocol.Envelope;\nexport type ListRequest = Protocol.ListRequest;\nexport type ListAck = Protocol.ListAck;\nexport type InvokeRequest = Protocol.InvokeRequest;\nexport type InvokeAck = Protocol.InvokeAck;\n\n/** A live page-action contribution: the target operation accepts `{ snapshot, target }` and returns `{ id }`. */\nexport type PageAction = Omit<Descriptor, 'operation'> & {\n operation: Operation.Definition.Any;\n};\n\nexport const toDescriptor = (action: PageAction): Descriptor => ({\n ...action,\n operation: action.operation.meta.key.toString(),\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAUA,IAAa,EACX,MACA,QACA,WACA,OACA,UACA,WACA,cACA,SACA,YACA,UACA,UACA,aACA,SACA,eACA,WACA,aACA,YACA,gBACA,cACA,qBACE;AAsBJ,IAAa,gBAAgB,YAAoC;CAC/D,GAAG;CACH,WAAW,OAAO,UAAU,KAAK,IAAI,SAAS;AAChD"}
@@ -0,0 +1,84 @@
1
+ import { t as __exportAll } from "./chunk-rolldown-runtime.mjs";
2
+ import * as Schema from "effect/Schema";
3
+ import * as Struct from "effect/Struct";
4
+ //#region src/types/Settings.ts
5
+ var Settings_exports = /* @__PURE__ */ __exportAll({
6
+ Settings: () => Settings,
7
+ defaults: () => defaults,
8
+ withDefaults: () => withDefaults
9
+ });
10
+ /**
11
+ * User preferences that govern how Composer coordinates with the composer-crx
12
+ * browser extension — both the page-actions bridge and the render-proxy. All fields
13
+ * are optional; defaults are applied by consumers when reading the atom.
14
+ */
15
+ var Settings = Schema.Struct({
16
+ /**
17
+ * Master toggle. When false, the bridge plugin ignores incoming extension actions.
18
+ * Defaults to `true`.
19
+ */
20
+ enabled: Schema.optional(Schema.Boolean.annotate({
21
+ title: "Accept extension actions",
22
+ description: "When off, actions sent from the composer-crx browser extension are ignored."
23
+ })),
24
+ /**
25
+ * Navigate to the created object after the extension creates one. Defaults to
26
+ * `false` to avoid yanking focus during active work.
27
+ */
28
+ autoOpenAfterClip: Schema.optional(Schema.Boolean.annotate({
29
+ title: "Open after action",
30
+ description: "Navigate to the created object when the extension creates one."
31
+ })),
32
+ /**
33
+ * Master toggle. When false, plugins fall back to the edge HTTP proxy instead of asking the
34
+ * extension to render pages. Defaults to `true`.
35
+ */
36
+ renderProxyEnabled: Schema.optional(Schema.Boolean.annotate({
37
+ title: "Use extension to render pages",
38
+ description: "Let plugins render pages via the browser extension to scrape client-rendered sites."
39
+ })),
40
+ /**
41
+ * Maximum time (ms) to wait for a page to render before aborting. Defaults to `20000`.
42
+ */
43
+ renderTimeout: Schema.optional(Schema.Number.annotate({
44
+ title: "Render timeout (ms)",
45
+ description: "Maximum time to wait for a page to finish rendering before giving up."
46
+ })),
47
+ /**
48
+ * Render pages in a focused (foreground) tab. Helps sites that defer loading when backgrounded,
49
+ * at the cost of stealing focus. Defaults to `false`.
50
+ */
51
+ renderActiveTab: Schema.optional(Schema.Boolean.annotate({
52
+ title: "Render in focused tab",
53
+ description: "Render pages in a focused tab; helps sites that defer loading when backgrounded."
54
+ })),
55
+ /**
56
+ * Enable verbose logging and debug previews in the extension. Defaults to `false`.
57
+ */
58
+ developerMode: Schema.optional(Schema.Boolean.annotate({
59
+ title: "Developer mode",
60
+ description: "Enable verbose logging and debug previews in the browser extension."
61
+ }))
62
+ }).mapFields(Struct.map(Schema.mutableKey));
63
+ /**
64
+ * Default values applied when a field is absent. Kept separate from the
65
+ * schema so `createKvsStore` can store only user-set values while consumers
66
+ * (this plugin's components, and any downstream reader) see sensible
67
+ * defaults.
68
+ */
69
+ var defaults = {
70
+ enabled: true,
71
+ autoOpenAfterClip: false,
72
+ renderProxyEnabled: true,
73
+ renderTimeout: 2e4,
74
+ renderActiveTab: false,
75
+ developerMode: false
76
+ };
77
+ var withDefaults = (settings) => ({
78
+ ...defaults,
79
+ ...settings
80
+ });
81
+ //#endregion
82
+ export { Settings, defaults, Settings_exports as t, withDefaults };
83
+
84
+ //# sourceMappingURL=Settings.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Settings.mjs","names":[],"sources":["../../src/types/Settings.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as Schema from 'effect/Schema';\nimport * as Struct from 'effect/Struct';\n\n/**\n * User preferences that govern how Composer coordinates with the composer-crx\n * browser extension — both the page-actions bridge and the render-proxy. All fields\n * are optional; defaults are applied by consumers when reading the atom.\n */\nexport const Settings = Schema.Struct({\n /**\n * Master toggle. When false, the bridge plugin ignores incoming extension actions.\n * Defaults to `true`.\n */\n enabled: Schema.optional(\n Schema.Boolean.annotate({\n title: 'Accept extension actions',\n description: 'When off, actions sent from the composer-crx browser extension are ignored.',\n }),\n ),\n\n /**\n * Navigate to the created object after the extension creates one. Defaults to\n * `false` to avoid yanking focus during active work.\n */\n autoOpenAfterClip: Schema.optional(\n Schema.Boolean.annotate({\n title: 'Open after action',\n description: 'Navigate to the created object when the extension creates one.',\n }),\n ),\n\n /**\n * Master toggle. When false, plugins fall back to the edge HTTP proxy instead of asking the\n * extension to render pages. Defaults to `true`.\n */\n renderProxyEnabled: Schema.optional(\n Schema.Boolean.annotate({\n title: 'Use extension to render pages',\n description: 'Let plugins render pages via the browser extension to scrape client-rendered sites.',\n }),\n ),\n\n /**\n * Maximum time (ms) to wait for a page to render before aborting. Defaults to `20000`.\n */\n renderTimeout: Schema.optional(\n Schema.Number.annotate({\n title: 'Render timeout (ms)',\n description: 'Maximum time to wait for a page to finish rendering before giving up.',\n }),\n ),\n\n /**\n * Render pages in a focused (foreground) tab. Helps sites that defer loading when backgrounded,\n * at the cost of stealing focus. Defaults to `false`.\n */\n renderActiveTab: Schema.optional(\n Schema.Boolean.annotate({\n title: 'Render in focused tab',\n description: 'Render pages in a focused tab; helps sites that defer loading when backgrounded.',\n }),\n ),\n\n /**\n * Enable verbose logging and debug previews in the extension. Defaults to `false`.\n */\n developerMode: Schema.optional(\n Schema.Boolean.annotate({\n title: 'Developer mode',\n description: 'Enable verbose logging and debug previews in the browser extension.',\n }),\n ),\n}).mapFields(Struct.map(Schema.mutableKey));\n\nexport interface Settings extends Schema.Schema.Type<typeof Settings> {}\n\n/**\n * Default values applied when a field is absent. Kept separate from the\n * schema so `createKvsStore` can store only user-set values while consumers\n * (this plugin's components, and any downstream reader) see sensible\n * defaults.\n */\nexport const defaults: Required<Settings> = {\n enabled: true,\n autoOpenAfterClip: false,\n renderProxyEnabled: true,\n renderTimeout: 20_000,\n renderActiveTab: false,\n developerMode: false,\n};\n\nexport const withDefaults = (settings: Settings): Required<Settings> => ({\n ...defaults,\n ...settings,\n});\n"],"mappings":";;;;;;;;;;;;;;AAcA,IAAa,WAAW,OAAO,OAAO;;;;;CAKpC,SAAS,OAAO,SACd,OAAO,QAAQ,SAAS;EACtB,OAAO;EACP,aAAa;CACf,CAAC,CACH;;;;;CAMA,mBAAmB,OAAO,SACxB,OAAO,QAAQ,SAAS;EACtB,OAAO;EACP,aAAa;CACf,CAAC,CACH;;;;;CAMA,oBAAoB,OAAO,SACzB,OAAO,QAAQ,SAAS;EACtB,OAAO;EACP,aAAa;CACf,CAAC,CACH;;;;CAKA,eAAe,OAAO,SACpB,OAAO,OAAO,SAAS;EACrB,OAAO;EACP,aAAa;CACf,CAAC,CACH;;;;;CAMA,iBAAiB,OAAO,SACtB,OAAO,QAAQ,SAAS;EACtB,OAAO;EACP,aAAa;CACf,CAAC,CACH;;;;CAKA,eAAe,OAAO,SACpB,OAAO,QAAQ,SAAS;EACtB,OAAO;EACP,aAAa;CACf,CAAC,CACH;AACF,CAAC,CAAC,CAAC,UAAU,OAAO,IAAI,OAAO,UAAU,CAAC;;;;;;;AAU1C,IAAa,WAA+B;CAC1C,SAAS;CACT,mBAAmB;CACnB,oBAAoB;CACpB,eAAe;CACf,iBAAiB;CACjB,eAAe;AACjB;AAEA,IAAa,gBAAgB,cAA4C;CACvE,GAAG;CACH,GAAG;AACL"}
@@ -0,0 +1,41 @@
1
+ import * as ActivationEvents from "@dxos/app-framework/ActivationEvents";
2
+ import * as Capabilities from "@dxos/app-framework/Capabilities";
3
+ import * as Capability from "@dxos/app-framework/Capability";
4
+ import * as AppCapability from "@dxos/app-toolkit/AppCapability";
5
+ import { translations } from "#translations";
6
+ import { CrxCapabilities, CrxEvents } from "#types";
7
+ 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
+ //#region src/capabilities/index.ts
12
+ var CrxSettings = AppCapability.settings(() => import("./chunk-settings.mjs"), {
13
+ activatesOn: ActivationEvents.Idle,
14
+ provides: [CrxCapabilities.Settings]
15
+ });
16
+ var InstallPageActions = Capability.lazyModule("InstallPageActions", {
17
+ requires: [
18
+ Capabilities.OperationInvoker,
19
+ Capabilities.AtomRegistry,
20
+ CrxCapabilities.Settings
21
+ ],
22
+ provides: [],
23
+ activatesOn: CrxEvents.Start
24
+ }, () => import("./chunk-install-page-actions.mjs"));
25
+ var OperationHandler = AppCapability.operationHandler(() => import("./chunk-operation-handler.mjs"), { activatesOn: ActivationEvents.Idle });
26
+ var PageActionProvider = Capability.lazyModule("PageActionProvider", {
27
+ provides: [CrxCapabilities.PageAction],
28
+ activatesOn: CrxEvents.Start
29
+ }, () => import("./chunk-page-action-provider.mjs"));
30
+ var PluginAsset = AppCapability.pluginAsset({
31
+ pluginId: meta.profile.key,
32
+ path: "PLUGIN.mdl",
33
+ content: PLUGIN_default,
34
+ mimeType: "application/x-mdl"
35
+ });
36
+ var ReactSurface = AppCapability.surface(() => import("./chunk-react-surface.mjs"), { roles: ["org.dxos.role.article"] });
37
+ var Translations = AppCapability.translations(translations);
38
+ //#endregion
39
+ export { CrxSettings, InstallPageActions, OperationHandler, PageActionProvider, PluginAsset, ReactSurface, Translations };
40
+
41
+ //# sourceMappingURL=capabilities.mjs.map
@@ -0,0 +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"}
@@ -0,0 +1,32 @@
1
+ import * as ActivationEvents from "@dxos/app-framework/ActivationEvents";
2
+ import * as Capabilities from "@dxos/app-framework/Capabilities";
3
+ import * as Capability from "@dxos/app-framework/Capability";
4
+ import * as AppCapability from "@dxos/app-toolkit/AppCapability";
5
+ import { translations } from "#translations";
6
+ import { CrxCapabilities, CrxEvents } from "#types";
7
+ //#region src/capabilities/gen/node.ts
8
+ var CrxSettings = AppCapability.settings(() => import("./chunk-settings.mjs"), {
9
+ activatesOn: ActivationEvents.Idle,
10
+ provides: [CrxCapabilities.Settings]
11
+ });
12
+ var InstallPageActions = Capability.lazyModule("InstallPageActions", {
13
+ requires: [
14
+ Capabilities.OperationInvoker,
15
+ Capabilities.AtomRegistry,
16
+ CrxCapabilities.Settings
17
+ ],
18
+ provides: [],
19
+ activatesOn: CrxEvents.Start
20
+ }, () => import("./chunk-install-page-actions.mjs"));
21
+ var OperationHandler = AppCapability.operationHandler(() => import("./chunk-operation-handler.mjs"), { activatesOn: ActivationEvents.Idle });
22
+ var PageActionProvider = Capability.lazyModule("PageActionProvider", {
23
+ provides: [CrxCapabilities.PageAction],
24
+ activatesOn: CrxEvents.Start
25
+ }, () => import("./chunk-page-action-provider.mjs"));
26
+ var Translations = AppCapability.translations(translations);
27
+ var PluginAsset = void 0;
28
+ var ReactSurface = void 0;
29
+ //#endregion
30
+ export { CrxSettings, InstallPageActions, OperationHandler, PageActionProvider, PluginAsset, ReactSurface, Translations };
31
+
32
+ //# sourceMappingURL=capabilities.node.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.node.mjs","names":[],"sources":["../../src/capabilities/gen/node.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// GENERATED by dx-plugin — do not edit. Sliced from ../index.ts for the 'node' 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 { translations } from '#translations';\nimport { CrxCapabilities, CrxEvents } from '#types';\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 Translations = AppCapability.translations(translations);\n\nexport const PluginAsset = undefined;\nexport const ReactSurface = undefined;\n"],"mappings":";;;;;;;AAcA,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,eAAe,cAAc,aAAa,YAAY;AAEnE,IAAa,cAAc,KAAA;AAC3B,IAAa,eAAe,KAAA"}
@@ -0,0 +1,32 @@
1
+ import * as ActivationEvents from "@dxos/app-framework/ActivationEvents";
2
+ import * as Capabilities from "@dxos/app-framework/Capabilities";
3
+ import * as Capability from "@dxos/app-framework/Capability";
4
+ import * as AppCapability from "@dxos/app-toolkit/AppCapability";
5
+ import { translations } from "#translations";
6
+ import { CrxCapabilities, CrxEvents } from "#types";
7
+ //#region src/capabilities/gen/workerd.ts
8
+ var CrxSettings = AppCapability.settings(() => import("./chunk-settings.mjs"), {
9
+ activatesOn: ActivationEvents.Idle,
10
+ provides: [CrxCapabilities.Settings]
11
+ });
12
+ var InstallPageActions = Capability.lazyModule("InstallPageActions", {
13
+ requires: [
14
+ Capabilities.OperationInvoker,
15
+ Capabilities.AtomRegistry,
16
+ CrxCapabilities.Settings
17
+ ],
18
+ provides: [],
19
+ activatesOn: CrxEvents.Start
20
+ }, () => import("./chunk-install-page-actions.mjs"));
21
+ var OperationHandler = AppCapability.operationHandler(() => import("./chunk-operation-handler.mjs"), { activatesOn: ActivationEvents.Idle });
22
+ var PageActionProvider = Capability.lazyModule("PageActionProvider", {
23
+ provides: [CrxCapabilities.PageAction],
24
+ activatesOn: CrxEvents.Start
25
+ }, () => import("./chunk-page-action-provider.mjs"));
26
+ var Translations = AppCapability.translations(translations);
27
+ var PluginAsset = void 0;
28
+ var ReactSurface = void 0;
29
+ //#endregion
30
+ export { CrxSettings, InstallPageActions, OperationHandler, PageActionProvider, PluginAsset, ReactSurface, Translations };
31
+
32
+ //# sourceMappingURL=capabilities.workerd.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.workerd.mjs","names":[],"sources":["../../src/capabilities/gen/workerd.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// GENERATED by dx-plugin — do not edit. Sliced from ../index.ts for the 'workerd' 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 { translations } from '#translations';\nimport { CrxCapabilities, CrxEvents } from '#types';\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 Translations = AppCapability.translations(translations);\n\nexport const PluginAsset = undefined;\nexport const ReactSurface = undefined;\n"],"mappings":";;;;;;;AAcA,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,eAAe,cAAc,aAAa,YAAY;AAEnE,IAAa,cAAc,KAAA;AAC3B,IAAa,eAAe,KAAA"}
@@ -0,0 +1,15 @@
1
+ import { t as toNote } from "./chunk-mapping.mjs";
2
+ import { CrxOperation } from "#types";
3
+ import * as Operation from "@dxos/compute/Operation";
4
+ import * as Effect from "effect/Effect";
5
+ import * as SpaceOperation from "@dxos/plugin-space/SpaceOperation";
6
+ //#region src/operations/add-note-from-snapshot.ts
7
+ var handler = CrxOperation.AddNoteFromSnapshot.pipe(Operation.withHandler(Effect.fn(function* ({ snapshot, target }) {
8
+ const note = toNote(snapshot);
9
+ const { id } = yield* Operation.invoke(SpaceOperation.AddObject, { object: note }, { spaceId: target.spaceId });
10
+ return { id };
11
+ })));
12
+ //#endregion
13
+ export { handler as default };
14
+
15
+ //# sourceMappingURL=chunk-add-note-from-snapshot.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-add-note-from-snapshot.mjs","names":[],"sources":["../../src/operations/add-note-from-snapshot.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport * as Operation from '@dxos/compute/Operation';\nimport * as SpaceOperation from '@dxos/plugin-space/SpaceOperation';\n\nimport { CrxOperation } from '#types';\n\nimport { toNote } from '../mapping.ts';\n\nconst handler: Operation.WithHandler<typeof CrxOperation.AddNoteFromSnapshot> = CrxOperation.AddNoteFromSnapshot.pipe(\n Operation.withHandler(\n Effect.fn(function* ({ snapshot, target }) {\n const note = toNote(snapshot);\n const { id } = yield* Operation.invoke(SpaceOperation.AddObject, { object: note }, { spaceId: target.spaceId });\n return { id };\n }),\n ),\n);\n\nexport default handler;\n"],"mappings":";;;;;;AAaA,IAAM,UAA0E,aAAa,oBAAoB,KAC/G,UAAU,YACR,OAAO,GAAG,WAAW,EAAE,UAAU,UAAU;CACzC,MAAM,OAAO,OAAO,QAAQ;CAC5B,MAAM,EAAE,OAAO,OAAO,UAAU,OAAO,eAAe,WAAW,EAAE,QAAQ,KAAK,GAAG,EAAE,SAAS,OAAO,QAAQ,CAAC;CAC9G,OAAO,EAAE,GAAG;AACd,CAAC,CACH,CACF"}
@@ -0,0 +1,15 @@
1
+ import { n as toOrganization } from "./chunk-mapping.mjs";
2
+ import { CrxOperation } from "#types";
3
+ import * as Operation from "@dxos/compute/Operation";
4
+ import * as Effect from "effect/Effect";
5
+ import * as SpaceOperation from "@dxos/plugin-space/SpaceOperation";
6
+ //#region src/operations/add-organization-from-snapshot.ts
7
+ var handler = CrxOperation.AddOrganizationFromSnapshot.pipe(Operation.withHandler(Effect.fn(function* ({ snapshot, target }) {
8
+ const organization = toOrganization(snapshot);
9
+ const { id } = yield* Operation.invoke(SpaceOperation.AddObject, { object: organization }, { spaceId: target.spaceId });
10
+ return { id };
11
+ })));
12
+ //#endregion
13
+ export { handler as default };
14
+
15
+ //# sourceMappingURL=chunk-add-organization-from-snapshot.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-add-organization-from-snapshot.mjs","names":[],"sources":["../../src/operations/add-organization-from-snapshot.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport * as Operation from '@dxos/compute/Operation';\nimport * as SpaceOperation from '@dxos/plugin-space/SpaceOperation';\n\nimport { CrxOperation } from '#types';\n\nimport { toOrganization } from '../mapping.ts';\n\nconst handler: Operation.WithHandler<typeof CrxOperation.AddOrganizationFromSnapshot> =\n CrxOperation.AddOrganizationFromSnapshot.pipe(\n Operation.withHandler(\n Effect.fn(function* ({ snapshot, target }) {\n const organization = toOrganization(snapshot);\n const { id } = yield* Operation.invoke(\n SpaceOperation.AddObject,\n { object: organization },\n { spaceId: target.spaceId },\n );\n return { id };\n }),\n ),\n );\n\nexport default handler;\n"],"mappings":";;;;;;AAaA,IAAM,UACJ,aAAa,4BAA4B,KACvC,UAAU,YACR,OAAO,GAAG,WAAW,EAAE,UAAU,UAAU;CACzC,MAAM,eAAe,eAAe,QAAQ;CAC5C,MAAM,EAAE,OAAO,OAAO,UAAU,OAC9B,eAAe,WACf,EAAE,QAAQ,aAAa,GACvB,EAAE,SAAS,OAAO,QAAQ,CAC5B;CACA,OAAO,EAAE,GAAG;AACd,CAAC,CACH,CACF"}
@@ -0,0 +1,15 @@
1
+ import { r as toPerson } from "./chunk-mapping.mjs";
2
+ import { CrxOperation } from "#types";
3
+ import * as Operation from "@dxos/compute/Operation";
4
+ import * as Effect from "effect/Effect";
5
+ import * as SpaceOperation from "@dxos/plugin-space/SpaceOperation";
6
+ //#region src/operations/add-person-from-snapshot.ts
7
+ var handler = CrxOperation.AddPersonFromSnapshot.pipe(Operation.withHandler(Effect.fn(function* ({ snapshot, target }) {
8
+ const person = toPerson(snapshot);
9
+ const { id } = yield* Operation.invoke(SpaceOperation.AddObject, { object: person }, { spaceId: target.spaceId });
10
+ return { id };
11
+ })));
12
+ //#endregion
13
+ export { handler as default };
14
+
15
+ //# sourceMappingURL=chunk-add-person-from-snapshot.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-add-person-from-snapshot.mjs","names":[],"sources":["../../src/operations/add-person-from-snapshot.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport * as Operation from '@dxos/compute/Operation';\nimport * as SpaceOperation from '@dxos/plugin-space/SpaceOperation';\n\nimport { CrxOperation } from '#types';\n\nimport { toPerson } from '../mapping.ts';\n\nconst handler: Operation.WithHandler<typeof CrxOperation.AddPersonFromSnapshot> =\n CrxOperation.AddPersonFromSnapshot.pipe(\n Operation.withHandler(\n Effect.fn(function* ({ snapshot, target }) {\n const person = toPerson(snapshot);\n const { id } = yield* Operation.invoke(\n SpaceOperation.AddObject,\n { object: person },\n { spaceId: target.spaceId },\n );\n return { id };\n }),\n ),\n );\n\nexport default handler;\n"],"mappings":";;;;;;AAaA,IAAM,UACJ,aAAa,sBAAsB,KACjC,UAAU,YACR,OAAO,GAAG,WAAW,EAAE,UAAU,UAAU;CACzC,MAAM,SAAS,SAAS,QAAQ;CAChC,MAAM,EAAE,OAAO,OAAO,UAAU,OAC9B,eAAe,WACf,EAAE,QAAQ,OAAO,GACjB,EAAE,SAAS,OAAO,QAAQ,CAC5B;CACA,OAAO,EAAE,GAAG;AACd,CAAC,CACH,CACF"}