@dxos/plugin-native 0.11.1 → 0.12.0-next-2800d0376abcc62d5544afdd744b16b2b960434e

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 (103) hide show
  1. package/PLUGIN.mdl +2 -2
  2. package/dist/lib/NativeCapabilities.mjs +14 -0
  3. package/dist/lib/NativeCapabilities.mjs.map +1 -0
  4. package/dist/lib/NativeEvents.mjs +15 -0
  5. package/dist/lib/NativeEvents.mjs.map +1 -0
  6. package/dist/lib/NativePlugin.mjs +13 -27
  7. package/dist/lib/NativePlugin.mjs.map +1 -1
  8. package/dist/lib/Settings.mjs +10 -0
  9. package/dist/lib/Settings.mjs.map +1 -0
  10. package/dist/lib/Update.mjs +7 -0
  11. package/dist/lib/Update.mjs.map +1 -0
  12. package/dist/lib/capabilities.mjs +40 -7
  13. package/dist/lib/capabilities.mjs.map +1 -1
  14. package/dist/lib/capabilities.node.mjs +35 -0
  15. package/dist/lib/capabilities.node.mjs.map +1 -0
  16. package/dist/lib/capabilities.workerd.mjs +35 -0
  17. package/dist/lib/capabilities.workerd.mjs.map +1 -0
  18. package/dist/lib/chunk-NativeSettings.mjs +5 -2
  19. package/dist/lib/chunk-NativeSettings.mjs.map +1 -1
  20. package/dist/lib/chunk-ollama.mjs +38 -31
  21. package/dist/lib/chunk-ollama.mjs.map +1 -1
  22. package/dist/lib/chunk-react-surface.mjs +3 -2
  23. package/dist/lib/chunk-react-surface.mjs.map +1 -1
  24. package/dist/lib/chunk-rolldown-runtime.mjs +13 -0
  25. package/dist/lib/chunk-settings.mjs +4 -4
  26. package/dist/lib/chunk-settings.mjs.map +1 -1
  27. package/dist/lib/chunk-spotlight-listener.mjs +9 -7
  28. package/dist/lib/chunk-spotlight-listener.mjs.map +1 -1
  29. package/dist/lib/chunk-updater.mjs +37 -22
  30. package/dist/lib/chunk-updater.mjs.map +1 -1
  31. package/dist/lib/index.mjs +4 -2
  32. package/dist/lib/meta.mjs +33 -1
  33. package/dist/lib/meta.mjs.map +1 -0
  34. package/dist/lib/plugin.mjs +6 -5
  35. package/dist/lib/plugin.mjs.map +1 -1
  36. package/dist/lib/translations.mjs +2 -1
  37. package/dist/lib/translations.mjs.map +1 -1
  38. package/dist/lib/types.mjs +5 -33
  39. package/dist/types/src/NativePlugin.d.ts +36 -3
  40. package/dist/types/src/NativePlugin.d.ts.map +1 -1
  41. package/dist/types/src/capabilities/gen/node.d.ts +9 -0
  42. package/dist/types/src/capabilities/gen/node.d.ts.map +1 -0
  43. package/dist/types/src/capabilities/gen/workerd.d.ts +9 -0
  44. package/dist/types/src/capabilities/gen/workerd.d.ts.map +1 -0
  45. package/dist/types/src/capabilities/index.d.ts +8 -6
  46. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  47. package/dist/types/src/capabilities/ollama.d.ts +4 -4
  48. package/dist/types/src/capabilities/ollama.d.ts.map +1 -1
  49. package/dist/types/src/capabilities/react-surface.d.ts +2 -2
  50. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  51. package/dist/types/src/capabilities/settings.d.ts +2 -2
  52. package/dist/types/src/capabilities/settings.d.ts.map +1 -1
  53. package/dist/types/src/capabilities/spotlight-listener.d.ts +2 -2
  54. package/dist/types/src/capabilities/spotlight-listener.d.ts.map +1 -1
  55. package/dist/types/src/capabilities/updater.d.ts +2 -2
  56. package/dist/types/src/capabilities/updater.d.ts.map +1 -1
  57. package/dist/types/src/constants.d.ts +7 -1
  58. package/dist/types/src/constants.d.ts.map +1 -1
  59. package/dist/types/src/containers/NativeSettings/NativeSettings.d.ts +3 -0
  60. package/dist/types/src/containers/NativeSettings/NativeSettings.d.ts.map +1 -1
  61. package/dist/types/src/index.d.ts +3 -1
  62. package/dist/types/src/index.d.ts.map +1 -1
  63. package/dist/types/src/plugin.d.ts +2 -1
  64. package/dist/types/src/plugin.d.ts.map +1 -1
  65. package/dist/types/src/translations.d.ts +7 -5
  66. package/dist/types/src/translations.d.ts.map +1 -1
  67. package/dist/types/src/types/NativeCapabilities.d.ts +4 -4
  68. package/dist/types/src/types/NativeCapabilities.d.ts.map +1 -1
  69. package/dist/types/src/types/NativeEvents.d.ts +8 -0
  70. package/dist/types/src/types/NativeEvents.d.ts.map +1 -0
  71. package/dist/types/src/types/Settings.d.ts +1 -1
  72. package/dist/types/src/types/Settings.d.ts.map +1 -1
  73. package/dist/types/src/types/Update.d.ts +3 -1
  74. package/dist/types/src/types/Update.d.ts.map +1 -1
  75. package/dist/types/src/types/index.d.ts +1 -0
  76. package/dist/types/src/types/index.d.ts.map +1 -1
  77. package/dist/types/tsconfig.tsbuildinfo +1 -1
  78. package/package.json +68 -29
  79. package/src/NativePlugin.ts +15 -0
  80. package/src/capabilities/gen/node.ts +55 -0
  81. package/src/capabilities/gen/workerd.ts +55 -0
  82. package/src/capabilities/index.ts +54 -6
  83. package/src/capabilities/ollama.ts +51 -49
  84. package/src/capabilities/react-surface.ts +3 -2
  85. package/src/capabilities/settings.ts +4 -4
  86. package/src/capabilities/spotlight-listener.ts +6 -4
  87. package/src/capabilities/updater.ts +24 -21
  88. package/src/constants.ts +7 -3
  89. package/src/containers/NativeSettings/NativeSettings.tsx +9 -2
  90. package/src/index.ts +3 -1
  91. package/src/meta.ts +1 -1
  92. package/src/plugin.tsx +29 -0
  93. package/src/translations.ts +1 -0
  94. package/src/types/NativeCapabilities.ts +5 -5
  95. package/src/types/NativeEvents.ts +16 -0
  96. package/src/types/Settings.ts +2 -1
  97. package/src/types/Update.ts +4 -1
  98. package/src/types/index.ts +2 -1
  99. package/dist/lib/chunk-meta.mjs +0 -34
  100. package/dist/lib/chunk-meta.mjs.map +0 -1
  101. package/dist/lib/types.mjs.map +0 -1
  102. package/src/NativePlugin.tsx +0 -41
  103. package/src/plugin.ts +0 -9
package/PLUGIN.mdl CHANGED
@@ -142,7 +142,7 @@ feat F-2: Over-the-Air Updates
142
142
  then: the status atom transitions to failed with a human-readable error string
143
143
 
144
144
  req F-2.4:
145
- when: the app is running in a dev-server build (port ≠ TAURI_LOCALHOST_PORT)
145
+ when: the app is running in a dev-server build (port not in TAURI_LOCALHOST_PORTS)
146
146
  then: the updater is disabled and status remains unsupported
147
147
 
148
148
  req F-2.5:
@@ -207,7 +207,7 @@ test T-4: Failed update check transitions to failed status
207
207
 
208
208
  ```mdl
209
209
  test T-5: Dev-server build disables updater
210
- given: the app is served on a port other than TAURI_LOCALHOST_PORT
210
+ given: the app is served on a port outside TAURI_LOCALHOST_PORTS
211
211
  when: the Updater module activates
212
212
  then:
213
213
  - status is set to unsupported immediately
@@ -0,0 +1,14 @@
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/NativeCapabilities.ts
5
+ var NativeCapabilities_exports = /* @__PURE__ */ __exportAll({
6
+ Settings: () => Settings,
7
+ UpdateManager: () => UpdateManager
8
+ });
9
+ var Settings = Capability.makeSingleton()(`${meta.profile.key}.capability.settings`);
10
+ var UpdateManager = Capability.makeSingleton()(`${meta.profile.key}.capability.updateManager`);
11
+ //#endregion
12
+ export { Settings, UpdateManager, NativeCapabilities_exports as t };
13
+
14
+ //# sourceMappingURL=NativeCapabilities.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NativeCapabilities.mjs","names":[],"sources":["../../src/types/NativeCapabilities.ts"],"sourcesContent":["//\n// Copyright 2025 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// Inline imports to avoid `Settings` / `Update` namespace aliases colliding with the\n// capability constants exported below.\nexport const Settings = Capability.makeSingleton<Atom.Writable<import('./Settings').Settings>>()(\n `${meta.profile.key}.capability.settings`,\n);\nexport const UpdateManager = Capability.makeSingleton<import('./Update').Manager>()(\n `${meta.profile.key}.capability.updateManager`,\n);\n"],"mappings":";;;;;;;;AAcA,IAAa,WAAW,WAAW,cAA4D,CAAC,CAC9F,GAAG,KAAK,QAAQ,IAAI,qBACtB;AACA,IAAa,gBAAgB,WAAW,cAA0C,CAAC,CACjF,GAAG,KAAK,QAAQ,IAAI,0BACtB"}
@@ -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/NativeEvents.ts
5
+ var NativeEvents_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, NativeEvents_exports as t };
14
+
15
+ //# sourceMappingURL=NativeEvents.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NativeEvents.mjs","names":[],"sources":["../../src/types/NativeEvents.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"}
@@ -1,30 +1,16 @@
1
- import { ActivationEvents, Plugin } from "@dxos/app-framework";
2
- import { AppPlugin } from "@dxos/app-toolkit";
3
- import { AssistantEvents } from "@dxos/plugin-assistant";
4
- import { NativeSettings, Ollama, ReactSurface, SpotlightListener, Updater } from "#capabilities";
5
- import { meta } from "#meta";
6
- import { translations } from "#translations";
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/NativePlugin.ts
5
+ var NativePlugin_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"));
7
13
  //#endregion
8
- //#region src/NativePlugin.tsx
9
- var NativePlugin = Plugin.define(meta).pipe(AppPlugin.addSettingsModule({ activate: NativeSettings }), AppPlugin.addSurfaceModule({ activate: ReactSurface }), AppPlugin.addTranslationsModule({ translations }), Plugin.addModule({
10
- id: "spotlight-listener",
11
- activatesOn: ActivationEvents.ProcessManagerReady,
12
- activate: SpotlightListener
13
- }), Plugin.addModule({
14
- id: "updater",
15
- activatesOn: ActivationEvents.ProcessManagerReady,
16
- activate: Updater
17
- }), Plugin.addModule({
18
- id: "ollama",
19
- activatesOn: AssistantEvents.SetupAiServiceProviders,
20
- activate: Ollama
21
- }), AppPlugin.addPluginAssetModule({ asset: {
22
- pluginId: meta.profile.key,
23
- path: "PLUGIN.mdl",
24
- content: "---\nid: org.dxos.plugin.native\nname: NativePlugin\nversion: 0.1.0\n---\n\nA Tauri-based native platform integration plugin for DXOS Composer that enables desktop-specific\ncapabilities on macOS, Linux, and Windows. It manages Spotlight window integration, over-the-air\napplication updates, and an Ollama sidecar process for local AI model inference.\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| `test` | `org.dxos.mdl.test@1.0` |\n| `component` | `org.dxos.mdl.component@1.0` |\n| `op` | `org.dxos.mdl.op@1.0` |\n\n## Types\n\n```mdl\ntype Settings\n fields:\n # No user-visible settings fields yet; reserved for future configuration.\n```\n\n```mdl\ntype UpdateStatus\n literals: unsupported | idle | checking | up-to-date | available | downloading | ready | failed\n```\n\n```mdl\ntype UpdateState\n fields:\n kind: UpdateStatus\n version?: string # set when kind = available\n checkedAt?: number # epoch ms; set when kind = up-to-date\n downloaded?: number # bytes received; set when kind = downloading\n contentLength?: number # total bytes; set when kind = downloading\n error?: string # set when kind = failed\n```\n\n## Components\n\n```mdl\ncomponent NativeSettings\n desc: |\n Settings panel section rendered inside the global Settings dialog under the\n App (native) plugin entry. Shows the current update status and exposes\n Check / Update Now / Relaunch actions depending on the UpdateState.\n props:\n settings: Settings\n onSettingsChange(patch: Partial<Settings>)\n state:\n pending: null | 'check' | 'install' | 'relaunch'\n status: UpdateState # derived from UpdateManager capability\n actions:\n checkForUpdate()\n installUpdate()\n relaunchApp()\n layout: |\n ┌─────────────────────────────────────────┐\n │ Updates │\n ├─────────────────────────────────────────┤\n │ [status description] [Check / Update]│\n └─────────────────────────────────────────┘\n```\n\n## Operations\n\n```mdl\nop CheckForUpdate\n desc: |\n Initiates an OTA update check via the Tauri updater plugin.\n Updates the UpdateManager status atom as the check progresses.\n input: void\n output: void\n effects: [http]\n note: No-op on unsupported platforms; guarded by SUPPORTS_OTA list.\n```\n\n```mdl\nop InstallUpdate\n desc: |\n Downloads and installs a pending update, streaming progress events to the\n UpdateManager status atom. Does not relaunch the app automatically.\n input: void\n output: void\n effects: [http, fs]\n note: Only valid when UpdateManager status kind = available.\n```\n\n```mdl\nop RelaunchApp\n desc: |\n Relaunches the Tauri app process to apply the installed update.\n input: void\n output: void\n effects: [process]\n```\n\n## Features\n\n```mdl\nfeat F-1: Spotlight Window Integration\n\n req F-1.1:\n when: the main Composer window receives a spotlight:invoke Tauri event with operation = 'open'\n then: the LayoutOperation.Open intent is dispatched with the provided payload\n\n req F-1.2:\n when: the main Composer window receives a spotlight:invoke event with operation = 'switch-workspace'\n then: the LayoutOperation.SwitchWorkspace intent is dispatched with the provided payload\n\n req F-1.3:\n when: a spotlight:invoke event is handled successfully\n then: the main Composer window is shown and brought to focus\n\n req F-1.4:\n when: a spotlight:invoke event carries an unrecognised operation\n then: a warning is logged and no intent is dispatched\n```\n\n```mdl\nfeat F-2: Over-the-Air Updates\n\n req F-2.1:\n when: the Updater module activates on a supported platform (macOS, Linux, Windows) in production\n then: a background Effect fiber is started that checks for updates immediately and repeats hourly\n\n req F-2.2:\n when: an update is available and successfully downloaded\n then: a toast notification is shown with a Relaunch action; the status atom transitions to ready\n\n req F-2.3:\n when: the Tauri updater check throws\n then: the status atom transitions to failed with a human-readable error string\n\n req F-2.4:\n when: the app is running in a dev-server build (port ≠ TAURI_LOCALHOST_PORT)\n then: the updater is disabled and status remains unsupported\n\n req F-2.5:\n when: the Updater module is torn down\n then: the background update-check fiber is interrupted cleanly\n```\n\n```mdl\nfeat F-3: Ollama Sidecar\n\n req F-3.1:\n when: the AssistantEvents.SetupAiServiceProviders event fires\n then: the Ollama sidecar binary is spawned via Tauri shell on localhost port 21434\n\n req F-3.2:\n when: the Ollama sidecar is running\n then: it is registered as an AiModelResolver under AppCapabilities.AiModelResolver\n\n req F-3.3:\n when: the Ollama capability is torn down\n then: the sidecar process is killed and the managed runtime is disposed\n```\n\n## Acceptance\n\n```mdl\ntest T-1: Spotlight open dispatches LayoutOperation.Open\n given: Composer is running and SpotlightListener is active\n when: a spotlight:invoke Tauri event arrives with operation = 'open' and payload { spaceId: 'abc' }\n then:\n - LayoutOperation.Open is invoked with { spaceId: 'abc' }\n - main window is visible and focused\n```\n\n```mdl\ntest T-2: Unknown spotlight operation is silently dropped\n given: SpotlightListener is active\n when: a spotlight:invoke event arrives with operation = 'foobar'\n then:\n - no intent is dispatched\n - a warning log entry is emitted with the unknown operation name\n```\n\n```mdl\ntest T-3: Update check transitions status atom\n given: Updater module is active on a supported platform\n when: CheckForUpdate is called\n then:\n - status transitions to checking while the HTTP call is in-flight\n - status transitions to up-to-date if no update is available\n - status transitions to available with a version string if an update exists\n```\n\n```mdl\ntest T-4: Failed update check transitions to failed status\n given: Updater module is active\n when: the Tauri updater plugin throws an error during check\n then:\n - status transitions to failed\n - status.error contains a human-readable description\n```\n\n```mdl\ntest T-5: Dev-server build disables updater\n given: the app is served on a port other than TAURI_LOCALHOST_PORT\n when: the Updater module activates\n then:\n - status is set to unsupported immediately\n - no HTTP update check is performed\n```\n\n---\n\n## Appendix: Extension Definitions\n\nExtension block types used in this document are defined below using\nthe core `ext` primitive — the only construct the base language provides.\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 # name[?]: TypeExpr (# inline comment)\n literals?: UnionList # a | b | c\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 # feat blocks may contain feat blocks\n```\n\n```mdl\next test\n uri: org.dxos.mdl.test@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\n```mdl\next component\n uri: org.dxos.mdl.component@1.0\n desc: A UI component with props, internal state, slots, actions, and events.\n fields:\n desc?: Prose\n props?: FieldMap # external inputs (immutable inside component)\n state?: FieldMap # internal reactive state\n slots?: FieldMap # named ReactNode injection points\n actions?: ActionMap # methods the component exposes or handles\n emits?: EventMap # events the component raises to its parent\n layout?: CodeBlock # ASCII sketch of visual structure (non-normative)\n```\n\n```mdl\next op\n uri: org.dxos.mdl.op@1.0\n desc: |\n A named operation with typed inputs, outputs, and declared errors.\n Pure ops have no effects or requires. Effectful ops declare both.\n fields:\n desc?: Prose\n input?: FieldMap # named input parameters\n output?: TypeExpr # return type\n errors?: ErrorMap # name: Prose (when this error occurs)\n effects?: EffectList # echo:read | echo:write | http | fs | ...\n requires?: ServiceList # injected service dependencies\n note?: Prose # implementation guidance (non-normative)\n```\n",
25
- mimeType: "application/x-mdl"
26
- } }), Plugin.make);
27
- //#endregion
28
- export { NativePlugin, NativePlugin as default };
14
+ export { make, meta, NativePlugin_exports as t };
29
15
 
30
16
  //# sourceMappingURL=NativePlugin.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"NativePlugin.mjs","names":[],"sources":["../../src/NativePlugin.tsx"],"sourcesContent":["//\n// Copyright 2023 DXOS.org\n//\n\nimport { ActivationEvents, Plugin } from '@dxos/app-framework';\nimport { AppPlugin } from '@dxos/app-toolkit';\nimport { AssistantEvents } from '@dxos/plugin-assistant';\n\nimport { NativeSettings, Ollama, ReactSurface, SpotlightListener, Updater } from '#capabilities';\nimport { meta } from '#meta';\nimport { translations } from '#translations';\n\n// eslint-disable-next-line import/no-relative-packages\nimport pluginSpec from '../PLUGIN.mdl?raw';\n\nexport const NativePlugin = Plugin.define(meta).pipe(\n AppPlugin.addSettingsModule({ activate: NativeSettings }),\n AppPlugin.addSurfaceModule({ activate: ReactSurface }),\n AppPlugin.addTranslationsModule({ translations }),\n Plugin.addModule({\n id: 'spotlight-listener',\n activatesOn: ActivationEvents.ProcessManagerReady,\n activate: SpotlightListener,\n }),\n Plugin.addModule({\n id: 'updater',\n activatesOn: ActivationEvents.ProcessManagerReady,\n activate: Updater,\n }),\n Plugin.addModule({\n id: 'ollama',\n activatesOn: AssistantEvents.SetupAiServiceProviders,\n activate: Ollama,\n }),\n AppPlugin.addPluginAssetModule({\n asset: { pluginId: meta.profile.key, path: 'PLUGIN.mdl', content: pluginSpec, mimeType: 'application/x-mdl' },\n }),\n Plugin.make,\n);\n\nexport default NativePlugin;\n"],"mappings":";;;;;;;;AAeA,IAAa,eAAe,OAAO,OAAO,IAAI,CAAC,CAAC,KAC9C,UAAU,kBAAkB,EAAE,UAAU,eAAe,CAAC,GACxD,UAAU,iBAAiB,EAAE,UAAU,aAAa,CAAC,GACrD,UAAU,sBAAsB,EAAE,aAAa,CAAC,GAChD,OAAO,UAAU;CACf,IAAI;CACJ,aAAa,iBAAiB;CAC9B,UAAU;AACZ,CAAC,GACD,OAAO,UAAU;CACf,IAAI;CACJ,aAAa,iBAAiB;CAC9B,UAAU;AACZ,CAAC,GACD,OAAO,UAAU;CACf,IAAI;CACJ,aAAa,gBAAgB;CAC7B,UAAU;AACZ,CAAC,GACD,UAAU,qBAAqB,EAC7B,OAAO;CAAE,UAAU,KAAK,QAAQ;CAAK,MAAM;CAAc,SAAS;CAAY,UAAU;AAAoB,EAC9G,CAAC,GACD,OAAO,IACT"}
1
+ {"version":3,"file":"NativePlugin.mjs","names":[],"sources":["../../src/NativePlugin.ts"],"sourcesContent":["//\n// Copyright 2023 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,10 @@
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({ Settings: () => Settings });
6
+ var Settings = Schema.Struct({}).mapFields(Struct.map(Schema.mutableKey));
7
+ //#endregion
8
+ export { Settings, Settings_exports as t };
9
+
10
+ //# sourceMappingURL=Settings.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Settings.mjs","names":[],"sources":["../../src/types/Settings.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as Schema from 'effect/Schema';\nimport * as Struct from 'effect/Struct';\n\nexport const Settings = Schema.Struct({}).mapFields(Struct.map(Schema.mutableKey));\n\nexport interface Settings extends Schema.Schema.Type<typeof Settings> {}\n"],"mappings":";;;;;AASA,IAAa,WAAW,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,UAAU,OAAO,IAAI,OAAO,UAAU,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { t as __exportAll } from "./chunk-rolldown-runtime.mjs";
2
+ //#region src/types/Update.ts
3
+ var Update_exports = /* @__PURE__ */ __exportAll({});
4
+ //#endregion
5
+ export { Update_exports as t };
6
+
7
+ //# sourceMappingURL=Update.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Update.mjs","names":[],"sources":["../../src/types/Update.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport type * as Atom from 'effect/unstable/reactivity/Atom';\n\n// @import-as-namespace\n\nexport type Status =\n // The platform has no OTA channel at all.\n | { kind: 'unsupported' }\n // The platform supports OTA, but this build is served by the dev server.\n | { kind: 'dev' }\n | { kind: 'idle' }\n | { kind: 'checking' }\n | { kind: 'up-to-date'; checkedAt: number }\n | { kind: 'available'; version: string }\n | { kind: 'downloading'; downloaded: number; contentLength: number }\n | { kind: 'ready' }\n | { kind: 'failed'; error: string };\n\nexport type Manager = {\n status: Atom.Writable<Status>;\n check: () => Promise<void>;\n install: () => Promise<void>;\n relaunch: () => Promise<void>;\n};\n"],"mappings":""}
@@ -1,11 +1,44 @@
1
- import { Capability } from "@dxos/app-framework";
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 AppCapabilities from "@dxos/app-toolkit/AppCapabilities";
5
+ import * as AppCapability from "@dxos/app-toolkit/AppCapability";
6
+ import * as AssistantCapabilities from "@dxos/plugin-assistant/AssistantCapabilities";
7
+ import { translations } from "#translations";
8
+ import { NativeCapabilities, NativeEvents } from "#types";
9
+ import { meta } from "#meta";
10
+ //#region PLUGIN.mdl?raw
11
+ var PLUGIN_default = "---\nid: org.dxos.plugin.native\nname: NativePlugin\nversion: 0.1.0\n---\n\nA Tauri-based native platform integration plugin for DXOS Composer that enables desktop-specific\ncapabilities on macOS, Linux, and Windows. It manages Spotlight window integration, over-the-air\napplication updates, and an Ollama sidecar process for local AI model inference.\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| `test` | `org.dxos.mdl.test@1.0` |\n| `component` | `org.dxos.mdl.component@1.0` |\n| `op` | `org.dxos.mdl.op@1.0` |\n\n## Types\n\n```mdl\ntype Settings\n fields:\n # No user-visible settings fields yet; reserved for future configuration.\n```\n\n```mdl\ntype UpdateStatus\n literals: unsupported | idle | checking | up-to-date | available | downloading | ready | failed\n```\n\n```mdl\ntype UpdateState\n fields:\n kind: UpdateStatus\n version?: string # set when kind = available\n checkedAt?: number # epoch ms; set when kind = up-to-date\n downloaded?: number # bytes received; set when kind = downloading\n contentLength?: number # total bytes; set when kind = downloading\n error?: string # set when kind = failed\n```\n\n## Components\n\n```mdl\ncomponent NativeSettings\n desc: |\n Settings panel section rendered inside the global Settings dialog under the\n App (native) plugin entry. Shows the current update status and exposes\n Check / Update Now / Relaunch actions depending on the UpdateState.\n props:\n settings: Settings\n onSettingsChange(patch: Partial<Settings>)\n state:\n pending: null | 'check' | 'install' | 'relaunch'\n status: UpdateState # derived from UpdateManager capability\n actions:\n checkForUpdate()\n installUpdate()\n relaunchApp()\n layout: |\n ┌─────────────────────────────────────────┐\n │ Updates │\n ├─────────────────────────────────────────┤\n │ [status description] [Check / Update]│\n └─────────────────────────────────────────┘\n```\n\n## Operations\n\n```mdl\nop CheckForUpdate\n desc: |\n Initiates an OTA update check via the Tauri updater plugin.\n Updates the UpdateManager status atom as the check progresses.\n input: void\n output: void\n effects: [http]\n note: No-op on unsupported platforms; guarded by SUPPORTS_OTA list.\n```\n\n```mdl\nop InstallUpdate\n desc: |\n Downloads and installs a pending update, streaming progress events to the\n UpdateManager status atom. Does not relaunch the app automatically.\n input: void\n output: void\n effects: [http, fs]\n note: Only valid when UpdateManager status kind = available.\n```\n\n```mdl\nop RelaunchApp\n desc: |\n Relaunches the Tauri app process to apply the installed update.\n input: void\n output: void\n effects: [process]\n```\n\n## Features\n\n```mdl\nfeat F-1: Spotlight Window Integration\n\n req F-1.1:\n when: the main Composer window receives a spotlight:invoke Tauri event with operation = 'open'\n then: the LayoutOperation.Open intent is dispatched with the provided payload\n\n req F-1.2:\n when: the main Composer window receives a spotlight:invoke event with operation = 'switch-workspace'\n then: the LayoutOperation.SwitchWorkspace intent is dispatched with the provided payload\n\n req F-1.3:\n when: a spotlight:invoke event is handled successfully\n then: the main Composer window is shown and brought to focus\n\n req F-1.4:\n when: a spotlight:invoke event carries an unrecognised operation\n then: a warning is logged and no intent is dispatched\n```\n\n```mdl\nfeat F-2: Over-the-Air Updates\n\n req F-2.1:\n when: the Updater module activates on a supported platform (macOS, Linux, Windows) in production\n then: a background Effect fiber is started that checks for updates immediately and repeats hourly\n\n req F-2.2:\n when: an update is available and successfully downloaded\n then: a toast notification is shown with a Relaunch action; the status atom transitions to ready\n\n req F-2.3:\n when: the Tauri updater check throws\n then: the status atom transitions to failed with a human-readable error string\n\n req F-2.4:\n when: the app is running in a dev-server build (port not in TAURI_LOCALHOST_PORTS)\n then: the updater is disabled and status remains unsupported\n\n req F-2.5:\n when: the Updater module is torn down\n then: the background update-check fiber is interrupted cleanly\n```\n\n```mdl\nfeat F-3: Ollama Sidecar\n\n req F-3.1:\n when: the AssistantEvents.SetupAiServiceProviders event fires\n then: the Ollama sidecar binary is spawned via Tauri shell on localhost port 21434\n\n req F-3.2:\n when: the Ollama sidecar is running\n then: it is registered as an AiModelResolver under AppCapabilities.AiModelResolver\n\n req F-3.3:\n when: the Ollama capability is torn down\n then: the sidecar process is killed and the managed runtime is disposed\n```\n\n## Acceptance\n\n```mdl\ntest T-1: Spotlight open dispatches LayoutOperation.Open\n given: Composer is running and SpotlightListener is active\n when: a spotlight:invoke Tauri event arrives with operation = 'open' and payload { spaceId: 'abc' }\n then:\n - LayoutOperation.Open is invoked with { spaceId: 'abc' }\n - main window is visible and focused\n```\n\n```mdl\ntest T-2: Unknown spotlight operation is silently dropped\n given: SpotlightListener is active\n when: a spotlight:invoke event arrives with operation = 'foobar'\n then:\n - no intent is dispatched\n - a warning log entry is emitted with the unknown operation name\n```\n\n```mdl\ntest T-3: Update check transitions status atom\n given: Updater module is active on a supported platform\n when: CheckForUpdate is called\n then:\n - status transitions to checking while the HTTP call is in-flight\n - status transitions to up-to-date if no update is available\n - status transitions to available with a version string if an update exists\n```\n\n```mdl\ntest T-4: Failed update check transitions to failed status\n given: Updater module is active\n when: the Tauri updater plugin throws an error during check\n then:\n - status transitions to failed\n - status.error contains a human-readable description\n```\n\n```mdl\ntest T-5: Dev-server build disables updater\n given: the app is served on a port outside TAURI_LOCALHOST_PORTS\n when: the Updater module activates\n then:\n - status is set to unsupported immediately\n - no HTTP update check is performed\n```\n\n---\n\n## Appendix: Extension Definitions\n\nExtension block types used in this document are defined below using\nthe core `ext` primitive — the only construct the base language provides.\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 # name[?]: TypeExpr (# inline comment)\n literals?: UnionList # a | b | c\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 # feat blocks may contain feat blocks\n```\n\n```mdl\next test\n uri: org.dxos.mdl.test@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\n```mdl\next component\n uri: org.dxos.mdl.component@1.0\n desc: A UI component with props, internal state, slots, actions, and events.\n fields:\n desc?: Prose\n props?: FieldMap # external inputs (immutable inside component)\n state?: FieldMap # internal reactive state\n slots?: FieldMap # named ReactNode injection points\n actions?: ActionMap # methods the component exposes or handles\n emits?: EventMap # events the component raises to its parent\n layout?: CodeBlock # ASCII sketch of visual structure (non-normative)\n```\n\n```mdl\next op\n uri: org.dxos.mdl.op@1.0\n desc: |\n A named operation with typed inputs, outputs, and declared errors.\n Pure ops have no effects or requires. Effectful ops declare both.\n fields:\n desc?: Prose\n input?: FieldMap # named input parameters\n output?: TypeExpr # return type\n errors?: ErrorMap # name: Prose (when this error occurs)\n effects?: EffectList # echo:read | echo:write | http | fs | ...\n requires?: ServiceList # injected service dependencies\n note?: Prose # implementation guidance (non-normative)\n```\n";
12
+ //#endregion
2
13
  //#region src/capabilities/index.ts
3
- var NativeSettings = Capability.lazy("NativeSettings", () => import("./chunk-settings.mjs"));
4
- var Ollama = Capability.lazy("Ollama", () => import("./chunk-ollama.mjs"));
5
- var ReactSurface = Capability.lazy("ReactSurface", () => import("./chunk-react-surface.mjs"));
6
- var SpotlightListener = Capability.lazy("SpotlightListener", () => import("./chunk-spotlight-listener.mjs"));
7
- var Updater = Capability.lazy("Updater", () => import("./chunk-updater.mjs"));
14
+ var NativeSettings = AppCapability.settings(() => import("./chunk-settings.mjs"), {
15
+ activatesOn: ActivationEvents.Idle,
16
+ provides: [NativeCapabilities.Settings]
17
+ });
18
+ var Ollama = Capability.lazyModule("Ollama", {
19
+ requires: [Capabilities.AtomRegistry],
20
+ provides: [AppCapabilities.AiModelResolver, AssistantCapabilities.OllamaManager],
21
+ activatesOn: ActivationEvents.Startup
22
+ }, () => import("./chunk-ollama.mjs"));
23
+ var PluginAsset = AppCapability.pluginAsset({
24
+ pluginId: meta.profile.key,
25
+ path: "PLUGIN.mdl",
26
+ content: PLUGIN_default,
27
+ mimeType: "application/x-mdl"
28
+ });
29
+ var ReactSurface = AppCapability.surface(() => import("./chunk-react-surface.mjs"), { roles: ["org.dxos.role.article"] });
30
+ var SpotlightListener = Capability.lazyModule("SpotlightListener", {
31
+ requires: [Capabilities.OperationInvoker],
32
+ provides: [],
33
+ activatesOn: NativeEvents.Start
34
+ }, () => import("./chunk-spotlight-listener.mjs"));
35
+ var Translations = AppCapability.translations(translations);
36
+ var Updater = Capability.lazyModule("Updater", {
37
+ requires: [Capabilities.AtomRegistry, Capabilities.OperationInvoker],
38
+ provides: [NativeCapabilities.UpdateManager],
39
+ activatesOn: NativeEvents.Start
40
+ }, () => import("./chunk-updater.mjs"));
8
41
  //#endregion
9
- export { NativeSettings, Ollama, ReactSurface, SpotlightListener, Updater };
42
+ export { NativeSettings, Ollama, PluginAsset, ReactSurface, SpotlightListener, Translations, Updater };
10
43
 
11
44
  //# sourceMappingURL=capabilities.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities.mjs","names":[],"sources":["../../src/capabilities/index.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport { Capability } from '@dxos/app-framework';\n\nexport const NativeSettings = Capability.lazy('NativeSettings', () => import('./settings'));\nexport const Ollama = Capability.lazy('Ollama', () => import('./ollama'));\nexport const ReactSurface = Capability.lazy('ReactSurface', () => import('./react-surface'));\nexport const SpotlightListener = Capability.lazy('SpotlightListener', () => import('./spotlight-listener'));\nexport const Updater = Capability.lazy('Updater', () => import('./updater'));\n"],"mappings":";;AAMA,IAAa,iBAAiB,WAAW,KAAK,wBAAwB,OAAO,uBAAa;AAC1F,IAAa,SAAS,WAAW,KAAK,gBAAgB,OAAO,qBAAW;AACxE,IAAa,eAAe,WAAW,KAAK,sBAAsB,OAAO,4BAAkB;AAC3F,IAAa,oBAAoB,WAAW,KAAK,2BAA2B,OAAO,iCAAuB;AAC1G,IAAa,UAAU,WAAW,KAAK,iBAAiB,OAAO,sBAAY"}
1
+ {"version":3,"file":"capabilities.mjs","names":[],"sources":["../../src/capabilities/index.ts"],"sourcesContent":["//\n// Copyright 2025 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 AppCapabilities from '@dxos/app-toolkit/AppCapabilities';\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\nimport * as AssistantCapabilities from '@dxos/plugin-assistant/AssistantCapabilities';\n\nimport { meta } from '#meta';\nimport { translations } from '#translations';\nimport { NativeCapabilities, NativeEvents } from '#types';\n\n// eslint-disable-next-line import/no-relative-packages\nimport pluginSpec from '../../PLUGIN.mdl?raw';\n\nexport const NativeSettings = AppCapability.settings(() => import('./settings'), {\n activatesOn: ActivationEvents.Idle,\n provides: [NativeCapabilities.Settings],\n});\n// Startup, not `AssistantEvents.Start`: `AiService` snapshots its multi-arity `AiModelResolver`\n// require once during startup, so the sidecar resolver contributed in a later round is invisible to\n// it and every `built-in` model fails to resolve. Activation stays cheap — it builds the manager and\n// a lazy layer; the sidecar process spawns on first use, not here.\nexport const Ollama = Capability.lazyModule(\n 'Ollama',\n {\n requires: [Capabilities.AtomRegistry],\n provides: [AppCapabilities.AiModelResolver, AssistantCapabilities.OllamaManager],\n activatesOn: ActivationEvents.Startup,\n },\n () => import('./ollama'),\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'), {\n roles: ['org.dxos.role.article'],\n});\nexport const SpotlightListener = Capability.lazyModule(\n 'SpotlightListener',\n { requires: [Capabilities.OperationInvoker], provides: [], activatesOn: NativeEvents.Start },\n () => import('./spotlight-listener'),\n);\nexport const Translations = AppCapability.translations(translations);\nexport const Updater = Capability.lazyModule(\n 'Updater',\n {\n requires: [Capabilities.AtomRegistry, Capabilities.OperationInvoker],\n provides: [NativeCapabilities.UpdateManager],\n activatesOn: NativeEvents.Start,\n },\n () => import('./updater'),\n);\n"],"mappings":";;;;;;;;;;;;;AAkBA,IAAa,iBAAiB,cAAc,eAAe,OAAO,yBAAe;CAC/E,aAAa,iBAAiB;CAC9B,UAAU,CAAC,mBAAmB,QAAQ;AACxC,CAAC;AAKD,IAAa,SAAS,WAAW,WAC/B,UACA;CACE,UAAU,CAAC,aAAa,YAAY;CACpC,UAAU,CAAC,gBAAgB,iBAAiB,sBAAsB,aAAa;CAC/E,aAAa,iBAAiB;AAChC,SACM,OAAO,qBACf;AACA,IAAa,cAAc,cAAc,YAAY;CACnD,UAAU,KAAK,QAAQ;CACvB,MAAM;CACN,SAAS;CACT,UAAU;AACZ,CAAC;AACD,IAAa,eAAe,cAAc,cAAc,OAAO,8BAAoB,EACjF,OAAO,CAAC,uBAAuB,EACjC,CAAC;AACD,IAAa,oBAAoB,WAAW,WAC1C,qBACA;CAAE,UAAU,CAAC,aAAa,gBAAgB;CAAG,UAAU,CAAC;CAAG,aAAa,aAAa;AAAM,SACrF,OAAO,iCACf;AACA,IAAa,eAAe,cAAc,aAAa,YAAY;AACnE,IAAa,UAAU,WAAW,WAChC,WACA;CACE,UAAU,CAAC,aAAa,cAAc,aAAa,gBAAgB;CACnE,UAAU,CAAC,mBAAmB,aAAa;CAC3C,aAAa,aAAa;AAC5B,SACM,OAAO,sBACf"}
@@ -0,0 +1,35 @@
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 AppCapabilities from "@dxos/app-toolkit/AppCapabilities";
5
+ import * as AppCapability from "@dxos/app-toolkit/AppCapability";
6
+ import * as AssistantCapabilities from "@dxos/plugin-assistant/AssistantCapabilities";
7
+ import { translations } from "#translations";
8
+ import { NativeCapabilities, NativeEvents } from "#types";
9
+ //#region src/capabilities/gen/node.ts
10
+ var NativeSettings = AppCapability.settings(() => import("./chunk-settings.mjs"), {
11
+ activatesOn: ActivationEvents.Idle,
12
+ provides: [NativeCapabilities.Settings]
13
+ });
14
+ var Ollama = Capability.lazyModule("Ollama", {
15
+ requires: [Capabilities.AtomRegistry],
16
+ provides: [AppCapabilities.AiModelResolver, AssistantCapabilities.OllamaManager],
17
+ activatesOn: ActivationEvents.Startup
18
+ }, () => import("./chunk-ollama.mjs"));
19
+ var SpotlightListener = Capability.lazyModule("SpotlightListener", {
20
+ requires: [Capabilities.OperationInvoker],
21
+ provides: [],
22
+ activatesOn: NativeEvents.Start
23
+ }, () => import("./chunk-spotlight-listener.mjs"));
24
+ var Translations = AppCapability.translations(translations);
25
+ var Updater = Capability.lazyModule("Updater", {
26
+ requires: [Capabilities.AtomRegistry, Capabilities.OperationInvoker],
27
+ provides: [NativeCapabilities.UpdateManager],
28
+ activatesOn: NativeEvents.Start
29
+ }, () => import("./chunk-updater.mjs"));
30
+ var PluginAsset = void 0;
31
+ var ReactSurface = void 0;
32
+ //#endregion
33
+ export { NativeSettings, Ollama, PluginAsset, ReactSurface, SpotlightListener, Translations, Updater };
34
+
35
+ //# 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 AppCapabilities from '@dxos/app-toolkit/AppCapabilities';\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\nimport * as AssistantCapabilities from '@dxos/plugin-assistant/AssistantCapabilities';\n\nimport { translations } from '#translations';\nimport { NativeCapabilities, NativeEvents } from '#types';\n\nexport const NativeSettings = AppCapability.settings(() => import('../settings'), {\n activatesOn: ActivationEvents.Idle,\n provides: [NativeCapabilities.Settings],\n});\n\n// Startup, not `AssistantEvents.Start`: `AiService` snapshots its multi-arity `AiModelResolver`\n// require once during startup, so the sidecar resolver contributed in a later round is invisible to\n// it and every `built-in` model fails to resolve. Activation stays cheap — it builds the manager and\n// a lazy layer; the sidecar process spawns on first use, not here.\nexport const Ollama = Capability.lazyModule(\n 'Ollama',\n {\n requires: [Capabilities.AtomRegistry],\n provides: [AppCapabilities.AiModelResolver, AssistantCapabilities.OllamaManager],\n activatesOn: ActivationEvents.Startup,\n },\n () => import('../ollama'),\n);\n\nexport const SpotlightListener = Capability.lazyModule(\n 'SpotlightListener',\n { requires: [Capabilities.OperationInvoker], provides: [], activatesOn: NativeEvents.Start },\n () => import('../spotlight-listener'),\n);\n\nexport const Translations = AppCapability.translations(translations);\n\nexport const Updater = Capability.lazyModule(\n 'Updater',\n {\n requires: [Capabilities.AtomRegistry, Capabilities.OperationInvoker],\n provides: [NativeCapabilities.UpdateManager],\n activatesOn: NativeEvents.Start,\n },\n () => import('../updater'),\n);\n\nexport const PluginAsset = undefined;\nexport const ReactSurface = undefined;\n"],"mappings":";;;;;;;;;AAgBA,IAAa,iBAAiB,cAAc,eAAe,OAAO,yBAAgB;CAChF,aAAa,iBAAiB;CAC9B,UAAU,CAAC,mBAAmB,QAAQ;AACxC,CAAC;AAMD,IAAa,SAAS,WAAW,WAC/B,UACA;CACE,UAAU,CAAC,aAAa,YAAY;CACpC,UAAU,CAAC,gBAAgB,iBAAiB,sBAAsB,aAAa;CAC/E,aAAa,iBAAiB;AAChC,SACM,OAAO,qBACf;AAEA,IAAa,oBAAoB,WAAW,WAC1C,qBACA;CAAE,UAAU,CAAC,aAAa,gBAAgB;CAAG,UAAU,CAAC;CAAG,aAAa,aAAa;AAAM,SACrF,OAAO,iCACf;AAEA,IAAa,eAAe,cAAc,aAAa,YAAY;AAEnE,IAAa,UAAU,WAAW,WAChC,WACA;CACE,UAAU,CAAC,aAAa,cAAc,aAAa,gBAAgB;CACnE,UAAU,CAAC,mBAAmB,aAAa;CAC3C,aAAa,aAAa;AAC5B,SACM,OAAO,sBACf;AAEA,IAAa,cAAc,KAAA;AAC3B,IAAa,eAAe,KAAA"}
@@ -0,0 +1,35 @@
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 AppCapabilities from "@dxos/app-toolkit/AppCapabilities";
5
+ import * as AppCapability from "@dxos/app-toolkit/AppCapability";
6
+ import * as AssistantCapabilities from "@dxos/plugin-assistant/AssistantCapabilities";
7
+ import { translations } from "#translations";
8
+ import { NativeCapabilities, NativeEvents } from "#types";
9
+ //#region src/capabilities/gen/workerd.ts
10
+ var NativeSettings = AppCapability.settings(() => import("./chunk-settings.mjs"), {
11
+ activatesOn: ActivationEvents.Idle,
12
+ provides: [NativeCapabilities.Settings]
13
+ });
14
+ var Ollama = Capability.lazyModule("Ollama", {
15
+ requires: [Capabilities.AtomRegistry],
16
+ provides: [AppCapabilities.AiModelResolver, AssistantCapabilities.OllamaManager],
17
+ activatesOn: ActivationEvents.Startup
18
+ }, () => import("./chunk-ollama.mjs"));
19
+ var SpotlightListener = Capability.lazyModule("SpotlightListener", {
20
+ requires: [Capabilities.OperationInvoker],
21
+ provides: [],
22
+ activatesOn: NativeEvents.Start
23
+ }, () => import("./chunk-spotlight-listener.mjs"));
24
+ var Translations = AppCapability.translations(translations);
25
+ var Updater = Capability.lazyModule("Updater", {
26
+ requires: [Capabilities.AtomRegistry, Capabilities.OperationInvoker],
27
+ provides: [NativeCapabilities.UpdateManager],
28
+ activatesOn: NativeEvents.Start
29
+ }, () => import("./chunk-updater.mjs"));
30
+ var PluginAsset = void 0;
31
+ var ReactSurface = void 0;
32
+ //#endregion
33
+ export { NativeSettings, Ollama, PluginAsset, ReactSurface, SpotlightListener, Translations, Updater };
34
+
35
+ //# 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 AppCapabilities from '@dxos/app-toolkit/AppCapabilities';\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\nimport * as AssistantCapabilities from '@dxos/plugin-assistant/AssistantCapabilities';\n\nimport { translations } from '#translations';\nimport { NativeCapabilities, NativeEvents } from '#types';\n\nexport const NativeSettings = AppCapability.settings(() => import('../settings'), {\n activatesOn: ActivationEvents.Idle,\n provides: [NativeCapabilities.Settings],\n});\n\n// Startup, not `AssistantEvents.Start`: `AiService` snapshots its multi-arity `AiModelResolver`\n// require once during startup, so the sidecar resolver contributed in a later round is invisible to\n// it and every `built-in` model fails to resolve. Activation stays cheap — it builds the manager and\n// a lazy layer; the sidecar process spawns on first use, not here.\nexport const Ollama = Capability.lazyModule(\n 'Ollama',\n {\n requires: [Capabilities.AtomRegistry],\n provides: [AppCapabilities.AiModelResolver, AssistantCapabilities.OllamaManager],\n activatesOn: ActivationEvents.Startup,\n },\n () => import('../ollama'),\n);\n\nexport const SpotlightListener = Capability.lazyModule(\n 'SpotlightListener',\n { requires: [Capabilities.OperationInvoker], provides: [], activatesOn: NativeEvents.Start },\n () => import('../spotlight-listener'),\n);\n\nexport const Translations = AppCapability.translations(translations);\n\nexport const Updater = Capability.lazyModule(\n 'Updater',\n {\n requires: [Capabilities.AtomRegistry, Capabilities.OperationInvoker],\n provides: [NativeCapabilities.UpdateManager],\n activatesOn: NativeEvents.Start,\n },\n () => import('../updater'),\n);\n\nexport const PluginAsset = undefined;\nexport const ReactSurface = undefined;\n"],"mappings":";;;;;;;;;AAgBA,IAAa,iBAAiB,cAAc,eAAe,OAAO,yBAAgB;CAChF,aAAa,iBAAiB;CAC9B,UAAU,CAAC,mBAAmB,QAAQ;AACxC,CAAC;AAMD,IAAa,SAAS,WAAW,WAC/B,UACA;CACE,UAAU,CAAC,aAAa,YAAY;CACpC,UAAU,CAAC,gBAAgB,iBAAiB,sBAAsB,aAAa;CAC/E,aAAa,iBAAiB;AAChC,SACM,OAAO,qBACf;AAEA,IAAa,oBAAoB,WAAW,WAC1C,qBACA;CAAE,UAAU,CAAC,aAAa,gBAAgB;CAAG,UAAU,CAAC;CAAG,aAAa,aAAa;AAAM,SACrF,OAAO,iCACf;AAEA,IAAa,eAAe,cAAc,aAAa,YAAY;AAEnE,IAAa,UAAU,WAAW,WAChC,WACA;CACE,UAAU,CAAC,aAAa,cAAc,aAAa,gBAAgB;CACnE,UAAU,CAAC,mBAAmB,aAAa;CAC3C,aAAa,aAAa;AAC5B,SACM,OAAO,sBACf;AAEA,IAAa,cAAc,KAAA;AAC3B,IAAa,eAAe,KAAA"}
@@ -1,10 +1,10 @@
1
+ import { NativeCapabilities } from "#types";
1
2
  import { meta } from "#meta";
2
3
  import { useState } from "react";
3
4
  import * as Schema from "effect/Schema";
4
5
  import { useCapability } from "@dxos/app-framework/ui";
5
- import { NativeCapabilities } from "#types";
6
6
  import * as Match from "effect/Match";
7
- import { useAtomValue } from "@effect-atom/atom-react";
7
+ import { useAtomValue } from "@effect/atom-react/Hooks";
8
8
  import { formatDistanceToNow } from "date-fns/formatDistanceToNow";
9
9
  import { Button, useTranslation } from "@dxos/react-ui";
10
10
  import { Form } from "@dxos/react-ui-form";
@@ -57,6 +57,9 @@ var renderUpdateRow = (status, pending, t, { onCheck, onInstall, onRelaunch }) =
57
57
  return Match.value(status).pipe(Match.withReturnType(), Match.when({ kind: "unsupported" }, () => ({
58
58
  description: t("settings.updates.unsupported.message"),
59
59
  button: checkButton(true)
60
+ })), Match.when({ kind: "dev" }, () => ({
61
+ description: t("settings.updates.dev.message"),
62
+ button: checkButton(true)
60
63
  })), Match.when({ kind: "idle" }, () => ({
61
64
  description: isChecking ? t("settings.updates.checking.message") : t("settings.updates.idle.message"),
62
65
  button: checkButton()
@@ -1 +1 @@
1
- {"version":3,"file":"chunk-NativeSettings.mjs","names":[],"sources":["../../src/containers/NativeSettings/NativeSettings.tsx"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport { useAtomValue } from '@effect-atom/atom-react';\nimport { formatDistanceToNow } from 'date-fns/formatDistanceToNow';\nimport * as Match from 'effect/Match';\nimport * as Schema from 'effect/Schema';\nimport React, { type ReactNode, useState } from 'react';\n\nimport { useCapability } from '@dxos/app-framework/ui';\nimport { Button, useTranslation } from '@dxos/react-ui';\nimport { Form } from '@dxos/react-ui-form';\n\nimport { meta } from '#meta';\nimport { NativeCapabilities, type Update } from '#types';\n\ntype Pending = null | 'check' | 'install' | 'relaunch';\n\ntype UpdateActions = {\n onCheck: () => Promise<void>;\n onInstall: () => Promise<void>;\n onRelaunch: () => Promise<void>;\n};\n\ntype UpdateRow = {\n description: string;\n button: ReactNode;\n};\n\n/** Update status comes from the update-manager capability, so this panel takes no settings props. */\nexport const NativeSettings = () => {\n const { t } = useTranslation(meta.profile.key);\n const manager = useCapability(NativeCapabilities.UpdateManager);\n const status = useAtomValue(manager.status);\n\n // UI-level pending flag. The status atom can flip between `checking` and `up-to-date` faster\n // than the user can perceive, so we also gate the button on the click handler's lifetime to\n // guarantee no duplicate triggers and a visible busy state.\n const [pending, setPending] = useState<Pending>(null);\n\n const runAction = (kind: Exclude<Pending, null>, action: () => Promise<void>) => async () => {\n setPending(kind);\n try {\n await action();\n } finally {\n setPending(null);\n }\n };\n\n const { description, button } = renderUpdateRow(status, pending, t, {\n onCheck: runAction('check', manager.check),\n onInstall: runAction('install', manager.install),\n onRelaunch: runAction('relaunch', manager.relaunch),\n });\n\n return (\n <Form.Root schema={Schema.Struct({})} values={{}} variant='settings'>\n <Form.Viewport scroll>\n <Form.Content>\n <Form.Section title={meta.profile.name ?? meta.profile.key}>\n <Form.Row label={t('settings.updates.label')} description={description}>\n {button}\n </Form.Row>\n </Form.Section>\n </Form.Content>\n </Form.Viewport>\n </Form.Root>\n );\n};\n\nconst renderUpdateRow = (\n status: Update.Status,\n pending: Pending,\n t: (key: string, options?: Record<string, unknown>) => string,\n { onCheck, onInstall, onRelaunch }: UpdateActions,\n): UpdateRow => {\n const isChecking = pending === 'check' || status.kind === 'checking';\n const isInstalling = pending === 'install' || status.kind === 'downloading';\n\n const checkButton = (disabled = false) => (\n <Button disabled={disabled || isChecking || isInstalling || pending === 'relaunch'} onClick={() => void onCheck()}>\n {isChecking ? t('settings.updates.checking.label') : t('settings.updates.check.label')}\n </Button>\n );\n\n return Match.value(status).pipe(\n Match.withReturnType<UpdateRow>(),\n Match.when({ kind: 'unsupported' }, () => ({\n description: t('settings.updates.unsupported.message'),\n button: checkButton(true),\n })),\n Match.when({ kind: 'idle' }, () => ({\n description: isChecking ? t('settings.updates.checking.message') : t('settings.updates.idle.message'),\n button: checkButton(),\n })),\n Match.when({ kind: 'checking' }, () => ({\n description: t('settings.updates.checking.message'),\n button: checkButton(),\n })),\n Match.when({ kind: 'up-to-date' }, (s) => ({\n description: isChecking\n ? t('settings.updates.checking.message')\n : t('settings.updates.up-to-date.message', {\n checkedAt: formatDistanceToNow(new Date(s.checkedAt), { addSuffix: true }),\n }),\n button: checkButton(),\n })),\n Match.when({ kind: 'available' }, (s) => ({\n description: t('settings.updates.available.message', { version: s.version }),\n button: (\n <Button variant='primary' disabled={isInstalling} onClick={() => void onInstall()}>\n {isInstalling ? t('settings.updates.downloading.label') : t('settings.updates.update-now.label')}\n </Button>\n ),\n })),\n Match.when({ kind: 'downloading' }, (s) => {\n const percent = s.contentLength > 0 ? Math.round((s.downloaded / s.contentLength) * 100) : 0;\n return {\n description: t('settings.updates.downloading.message', { percent }),\n button: <Button disabled>{t('settings.updates.downloading.label')}</Button>,\n };\n }),\n Match.when({ kind: 'ready' }, () => ({\n description: t('settings.updates.ready.message'),\n button: (\n <Button variant='primary' disabled={pending === 'relaunch'} onClick={() => void onRelaunch()}>\n {t('settings.updates.relaunch.label')}\n </Button>\n ),\n })),\n Match.when({ kind: 'failed' }, (s) => ({\n description: t('settings.updates.failed.message', { error: s.error }),\n button: checkButton(),\n })),\n Match.exhaustive,\n );\n};\n\nNativeSettings.displayName = 'NativeSettings';\n"],"mappings":";;;;;;;;;;;;;AA+BA,IAAa,uBAAuB;CAClC,MAAM,EAAE,MAAM,eAAe,KAAK,QAAQ,GAAG;CAC7C,MAAM,UAAU,cAAc,mBAAmB,aAAa;CAC9D,MAAM,SAAS,aAAa,QAAQ,MAAM;CAK1C,MAAM,CAAC,SAAS,cAAc,SAAkB,IAAI;CAEpD,MAAM,aAAa,MAA8B,WAAgC,YAAY;EAC3F,WAAW,IAAI;EACf,IAAI;GACF,MAAM,OAAO;EACf,UAAU;GACR,WAAW,IAAI;EACjB;CACF;CAEA,MAAM,EAAE,aAAa,WAAW,gBAAgB,QAAQ,SAAS,GAAG;EAClE,SAAS,UAAU,SAAS,QAAQ,KAAK;EACzC,WAAW,UAAU,WAAW,QAAQ,OAAO;EAC/C,YAAY,UAAU,YAAY,QAAQ,QAAQ;CACpD,CAAC;CAED,OACE,oBAAC,KAAK,MAAN;EAAW,QAAQ,OAAO,OAAO,CAAC,CAAC;EAAG,QAAQ,CAAC;EAAG,SAAQ;YACxD,oBAAC,KAAK,UAAN;GAAe,QAAA;aACb,oBAAC,KAAK,SAAN,EAAA,UACE,oBAAC,KAAK,SAAN;IAAc,OAAO,KAAK,QAAQ,QAAQ,KAAK,QAAQ;cACrD,oBAAC,KAAK,KAAN;KAAU,OAAO,EAAE,wBAAwB;KAAgB;eACxD;IACO,CAAA;GACE,CAAA,EACF,CAAA;EACD,CAAA;CACN,CAAA;AAEf;AAEA,IAAM,mBACJ,QACA,SACA,GACA,EAAE,SAAS,WAAW,iBACR;CACd,MAAM,aAAa,YAAY,WAAW,OAAO,SAAS;CAC1D,MAAM,eAAe,YAAY,aAAa,OAAO,SAAS;CAE9D,MAAM,eAAe,WAAW,UAC9B,oBAAC,QAAD;EAAQ,UAAU,YAAY,cAAc,gBAAgB,YAAY;EAAY,eAAe,KAAK,QAAQ;YAC7G,aAAa,EAAE,iCAAiC,IAAI,EAAE,8BAA8B;CAC/E,CAAA;CAGV,OAAO,MAAM,MAAM,MAAM,CAAC,CAAC,KACzB,MAAM,eAA0B,GAChC,MAAM,KAAK,EAAE,MAAM,cAAc,UAAU;EACzC,aAAa,EAAE,sCAAsC;EACrD,QAAQ,YAAY,IAAI;CAC1B,EAAE,GACF,MAAM,KAAK,EAAE,MAAM,OAAO,UAAU;EAClC,aAAa,aAAa,EAAE,mCAAmC,IAAI,EAAE,+BAA+B;EACpG,QAAQ,YAAY;CACtB,EAAE,GACF,MAAM,KAAK,EAAE,MAAM,WAAW,UAAU;EACtC,aAAa,EAAE,mCAAmC;EAClD,QAAQ,YAAY;CACtB,EAAE,GACF,MAAM,KAAK,EAAE,MAAM,aAAa,IAAI,OAAO;EACzC,aAAa,aACT,EAAE,mCAAmC,IACrC,EAAE,uCAAuC,EACvC,WAAW,oBAAoB,IAAI,KAAK,EAAE,SAAS,GAAG,EAAE,WAAW,KAAK,CAAC,EAC3E,CAAC;EACL,QAAQ,YAAY;CACtB,EAAE,GACF,MAAM,KAAK,EAAE,MAAM,YAAY,IAAI,OAAO;EACxC,aAAa,EAAE,sCAAsC,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC3E,QACE,oBAAC,QAAD;GAAQ,SAAQ;GAAU,UAAU;GAAc,eAAe,KAAK,UAAU;aAC7E,eAAe,EAAE,oCAAoC,IAAI,EAAE,mCAAmC;EACzF,CAAA;CAEZ,EAAE,GACF,MAAM,KAAK,EAAE,MAAM,cAAc,IAAI,MAAM;EAEzC,OAAO;GACL,aAAa,EAAE,wCAAwC,EAAE,SAF3C,EAAE,gBAAgB,IAAI,KAAK,MAAO,EAAE,aAAa,EAAE,gBAAiB,GAAG,IAAI,EAExB,CAAC;GAClE,QAAQ,oBAAC,QAAD;IAAQ,UAAA;cAAU,EAAE,oCAAoC;GAAU,CAAA;EAC5E;CACF,CAAC,GACD,MAAM,KAAK,EAAE,MAAM,QAAQ,UAAU;EACnC,aAAa,EAAE,gCAAgC;EAC/C,QACE,oBAAC,QAAD;GAAQ,SAAQ;GAAU,UAAU,YAAY;GAAY,eAAe,KAAK,WAAW;aACxF,EAAE,iCAAiC;EAC9B,CAAA;CAEZ,EAAE,GACF,MAAM,KAAK,EAAE,MAAM,SAAS,IAAI,OAAO;EACrC,aAAa,EAAE,mCAAmC,EAAE,OAAO,EAAE,MAAM,CAAC;EACpE,QAAQ,YAAY;CACtB,EAAE,GACF,MAAM,UACR;AACF;AAEA,eAAe,cAAc"}
1
+ {"version":3,"file":"chunk-NativeSettings.mjs","names":[],"sources":["../../src/containers/NativeSettings/NativeSettings.tsx"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport { useAtomValue } from '@effect/atom-react/Hooks';\nimport { formatDistanceToNow } from 'date-fns/formatDistanceToNow';\nimport * as Match from 'effect/Match';\nimport * as Schema from 'effect/Schema';\nimport React, { type ReactNode, useState } from 'react';\n\nimport { useCapability } from '@dxos/app-framework/ui';\nimport { type AppSurface } from '@dxos/app-toolkit/ui';\nimport { Button, useTranslation } from '@dxos/react-ui';\nimport { Form } from '@dxos/react-ui-form';\n\nimport { meta } from '#meta';\nimport { NativeCapabilities, Settings, Update } from '#types';\n\nexport type NativeSettingsProps = AppSurface.SettingsProps<Settings.Settings>;\n\ntype Pending = null | 'check' | 'install' | 'relaunch';\n\ntype UpdateActions = {\n onCheck: () => Promise<void>;\n onInstall: () => Promise<void>;\n onRelaunch: () => Promise<void>;\n};\n\ntype UpdateRow = {\n description: string;\n button: ReactNode;\n};\n\n/** Update status comes from the update-manager capability, so this panel takes no settings props. */\nexport const NativeSettings = () => {\n const { t } = useTranslation(meta.profile.key);\n const manager = useCapability(NativeCapabilities.UpdateManager);\n const status = useAtomValue(manager.status);\n\n // UI-level pending flag. The status atom can flip between `checking` and `up-to-date` faster\n // than the user can perceive, so we also gate the button on the click handler's lifetime to\n // guarantee no duplicate triggers and a visible busy state.\n const [pending, setPending] = useState<Pending>(null);\n\n const runAction = (kind: Exclude<Pending, null>, action: () => Promise<void>) => async () => {\n setPending(kind);\n try {\n await action();\n } finally {\n setPending(null);\n }\n };\n\n const { description, button } = renderUpdateRow(status, pending, t, {\n onCheck: runAction('check', manager.check),\n onInstall: runAction('install', manager.install),\n onRelaunch: runAction('relaunch', manager.relaunch),\n });\n\n return (\n <Form.Root schema={Schema.Struct({})} values={{}} variant='settings'>\n <Form.Viewport scroll>\n <Form.Content>\n <Form.Section title={meta.profile.name ?? meta.profile.key}>\n <Form.Row label={t('settings.updates.label')} description={description}>\n {button}\n </Form.Row>\n </Form.Section>\n </Form.Content>\n </Form.Viewport>\n </Form.Root>\n );\n};\n\nconst renderUpdateRow = (\n status: Update.Status,\n pending: Pending,\n t: (key: string, options?: Record<string, unknown>) => string,\n { onCheck, onInstall, onRelaunch }: UpdateActions,\n): UpdateRow => {\n const isChecking = pending === 'check' || status.kind === 'checking';\n const isInstalling = pending === 'install' || status.kind === 'downloading';\n\n const checkButton = (disabled = false) => (\n <Button disabled={disabled || isChecking || isInstalling || pending === 'relaunch'} onClick={() => void onCheck()}>\n {isChecking ? t('settings.updates.checking.label') : t('settings.updates.check.label')}\n </Button>\n );\n\n return Match.value(status).pipe(\n Match.withReturnType<UpdateRow>(),\n Match.when({ kind: 'unsupported' }, () => ({\n description: t('settings.updates.unsupported.message'),\n button: checkButton(true),\n })),\n Match.when({ kind: 'dev' }, () => ({\n description: t('settings.updates.dev.message'),\n button: checkButton(true),\n })),\n Match.when({ kind: 'idle' }, () => ({\n description: isChecking ? t('settings.updates.checking.message') : t('settings.updates.idle.message'),\n button: checkButton(),\n })),\n Match.when({ kind: 'checking' }, () => ({\n description: t('settings.updates.checking.message'),\n button: checkButton(),\n })),\n Match.when({ kind: 'up-to-date' }, (s) => ({\n description: isChecking\n ? t('settings.updates.checking.message')\n : t('settings.updates.up-to-date.message', {\n checkedAt: formatDistanceToNow(new Date(s.checkedAt), { addSuffix: true }),\n }),\n button: checkButton(),\n })),\n Match.when({ kind: 'available' }, (s) => ({\n description: t('settings.updates.available.message', { version: s.version }),\n button: (\n <Button variant='primary' disabled={isInstalling} onClick={() => void onInstall()}>\n {isInstalling ? t('settings.updates.downloading.label') : t('settings.updates.update-now.label')}\n </Button>\n ),\n })),\n Match.when({ kind: 'downloading' }, (s) => {\n const percent = s.contentLength > 0 ? Math.round((s.downloaded / s.contentLength) * 100) : 0;\n return {\n description: t('settings.updates.downloading.message', { percent }),\n button: <Button disabled>{t('settings.updates.downloading.label')}</Button>,\n };\n }),\n Match.when({ kind: 'ready' }, () => ({\n description: t('settings.updates.ready.message'),\n button: (\n <Button variant='primary' disabled={pending === 'relaunch'} onClick={() => void onRelaunch()}>\n {t('settings.updates.relaunch.label')}\n </Button>\n ),\n })),\n Match.when({ kind: 'failed' }, (s) => ({\n description: t('settings.updates.failed.message', { error: s.error }),\n button: checkButton(),\n })),\n Match.exhaustive,\n );\n};\n\nNativeSettings.displayName = 'NativeSettings';\n"],"mappings":"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"}
@@ -1,21 +1,22 @@
1
- import { Capabilities, Capability } from "@dxos/app-framework";
2
- import { AppCapabilities } from "@dxos/app-toolkit";
3
- import { AssistantCapabilities } from "@dxos/plugin-assistant";
4
- import { Atom } from "@effect-atom/atom";
5
- import * as FetchHttpClient from "@effect/platform/FetchHttpClient";
6
- import * as HttpClient from "@effect/platform/HttpClient";
1
+ import * as Capabilities from "@dxos/app-framework/Capabilities";
2
+ import * as Capability from "@dxos/app-framework/Capability";
3
+ import * as AppCapabilities from "@dxos/app-toolkit/AppCapabilities";
4
+ import * as AssistantCapabilities from "@dxos/plugin-assistant/AssistantCapabilities";
7
5
  import { Command } from "@tauri-apps/plugin-shell";
8
6
  import * as Cause from "effect/Cause";
9
7
  import * as Context from "effect/Context";
10
8
  import * as Duration from "effect/Duration";
11
9
  import * as Effect from "effect/Effect";
12
- import * as Either from "effect/Either";
13
10
  import * as Exit from "effect/Exit";
14
11
  import * as Fiber from "effect/Fiber";
15
12
  import * as Layer from "effect/Layer";
16
13
  import * as ManagedRuntime from "effect/ManagedRuntime";
14
+ import * as Result from "effect/Result";
17
15
  import * as Schedule from "effect/Schedule";
18
16
  import * as Stream from "effect/Stream";
17
+ import * as FetchHttpClient from "effect/unstable/http/FetchHttpClient";
18
+ import * as HttpClient from "effect/unstable/http/HttpClient";
19
+ import * as Atom from "effect/unstable/reactivity/Atom";
19
20
  import { Provider } from "@dxos/ai";
20
21
  import { OllamaAdmin, OllamaResolver } from "@dxos/ai/resolvers";
21
22
  import { log } from "@dxos/log";
@@ -23,9 +24,9 @@ import { log } from "@dxos/log";
23
24
  var __dxlog_file = "/__w/dxos/dxos/packages/plugins/plugin-native/src/capabilities/ollama.ts";
24
25
  var OLLAMA_HOST = "http://localhost:21434";
25
26
  var ollama_default = Capability.makeModule(Effect.fnUntraced(function* () {
26
- const registry = yield* Capability.get(Capabilities.AtomRegistry);
27
+ const registry = yield* Capabilities.AtomRegistry;
27
28
  const runtime = ManagedRuntime.make(OllamaSidecar.layerLive);
28
- const sidecarLayer = Layer.effectContext(runtime.runtimeEffect.pipe(Effect.map((rt) => rt.context.pipe(Context.pick(OllamaSidecar)))));
29
+ const sidecarLayer = Layer.effectContext(runtime.contextEffect.pipe(Effect.map(Context.pick(OllamaSidecar))));
29
30
  const admin = OllamaAdmin.make({ endpoint: OLLAMA_HOST });
30
31
  const stateAtom = Atom.make({
31
32
  kind: "idle",
@@ -60,13 +61,13 @@ var ollama_default = Capability.makeModule(Effect.fnUntraced(function* () {
60
61
  };
61
62
  });
62
63
  const ensureRunning = Effect.asVoid(OllamaSidecar).pipe(Effect.provide(sidecarLayer));
63
- const runAdmin = (effect) => effect.pipe(Effect.provide(clientLayer), Effect.either, Effect.map(Either.mapLeft((error) => error.message)));
64
+ const runAdmin = (effect) => effect.pipe(Effect.provide(clientLayer), Effect.result, Effect.map(Result.mapError((error) => error.message)));
64
65
  const pullFibers = /* @__PURE__ */ new Map();
65
66
  const refreshLoaded = Effect.gen(function* () {
66
67
  const result = yield* runAdmin(admin.ps);
67
- if (Either.isLeft(result)) return;
68
+ if (Result.isFailure(result)) return;
68
69
  const before = (yield* getState).loaded.map((model) => model.name);
69
- const after = result.right.map((model) => model.name);
70
+ const after = result.success.map((model) => model.name);
70
71
  if (before.join() !== after.join()) yield* Effect.sync(() => log.info("ollama loaded models changed", { loaded: after }, {
71
72
  "~LogMeta": "~LogMeta",
72
73
  F: __dxlog_file,
@@ -75,7 +76,7 @@ var ollama_default = Capability.makeModule(Effect.fnUntraced(function* () {
75
76
  }));
76
77
  yield* updateState((state) => ({
77
78
  ...state,
78
- loaded: result.right
79
+ loaded: result.success
79
80
  }));
80
81
  });
81
82
  const refresh = Effect.gen(function* () {
@@ -90,14 +91,14 @@ var ollama_default = Capability.makeModule(Effect.fnUntraced(function* () {
90
91
  schedule: Schedule.spaced(Duration.millis(300)),
91
92
  times: 29
92
93
  })));
93
- if (Either.isLeft(result)) return yield* fail(result.left);
94
+ if (Result.isFailure(result)) return yield* fail(result.failure);
94
95
  yield* updateState((state) => ({
95
96
  ...state,
96
97
  kind: "ready",
97
- models: result.right,
98
+ models: result.success,
98
99
  error: void 0
99
100
  }));
100
- yield* Effect.sync(() => log.info("ollama models", { installed: result.right.map((model) => model.name) }, {
101
+ yield* Effect.sync(() => log.info("ollama models", { installed: result.success.map((model) => model.name) }, {
101
102
  "~LogMeta": "~LogMeta",
102
103
  F: __dxlog_file,
103
104
  L: 134,
@@ -138,7 +139,7 @@ var ollama_default = Capability.makeModule(Effect.fnUntraced(function* () {
138
139
  return setProgress(name, { status: progress.status });
139
140
  });
140
141
  const work = admin.pull(name).pipe(Stream.runForEach(onProgress), Effect.provide(clientLayer), Effect.matchCauseEffect({
141
- onFailure: (cause) => Cause.isInterruptedOnly(cause) ? Effect.sync(() => log.info("ollama pull finished", {
142
+ onFailure: (cause) => Cause.hasInterruptsOnly(cause) ? Effect.sync(() => log.info("ollama pull finished", {
142
143
  name,
143
144
  cancelled: true
144
145
  }, {
@@ -172,7 +173,7 @@ var ollama_default = Capability.makeModule(Effect.fnUntraced(function* () {
172
173
  yield* refresh;
173
174
  })
174
175
  }), Effect.ensuring(setProgress(name, void 0)), Effect.ensuring(Effect.sync(() => pullFibers.delete(name))));
175
- const fiber = yield* Effect.forkDaemon(work);
176
+ const fiber = yield* Effect.forkDetach(work);
176
177
  yield* Effect.sync(() => pullFibers.set(name, fiber));
177
178
  });
178
179
  const cancel = (name) => Effect.gen(function* () {
@@ -196,17 +197,17 @@ var ollama_default = Capability.makeModule(Effect.fnUntraced(function* () {
196
197
  S: this
197
198
  }));
198
199
  const result = yield* runAdmin(admin.load(name));
199
- if (Either.isLeft(result)) {
200
+ if (Result.isFailure(result)) {
200
201
  yield* Effect.sync(() => log.warn("ollama load failed", {
201
202
  name,
202
- error: result.left
203
+ error: result.failure
203
204
  }, {
204
205
  "~LogMeta": "~LogMeta",
205
206
  F: __dxlog_file,
206
207
  L: 215,
207
208
  S: this
208
209
  }));
209
- return yield* setError(name, result.left);
210
+ return yield* setError(name, result.failure);
210
211
  }
211
212
  yield* refreshLoaded;
212
213
  });
@@ -221,7 +222,7 @@ var ollama_default = Capability.makeModule(Effect.fnUntraced(function* () {
221
222
  S: this
222
223
  }));
223
224
  const result = yield* runAdmin(admin.unload(name));
224
- if (Either.isLeft(result)) return yield* setError(name, result.left);
225
+ if (Result.isFailure(result)) return yield* setError(name, result.failure);
225
226
  yield* refreshLoaded;
226
227
  });
227
228
  const remove = (name) => Effect.gen(function* () {
@@ -229,7 +230,7 @@ var ollama_default = Capability.makeModule(Effect.fnUntraced(function* () {
229
230
  const started = yield* Effect.exit(ensureRunning);
230
231
  if (Exit.isFailure(started)) return yield* setError(name, formatError(Cause.squash(started.cause)));
231
232
  const result = yield* runAdmin(admin.remove(name));
232
- if (Either.isLeft(result)) return yield* setError(name, result.left);
233
+ if (Result.isFailure(result)) return yield* setError(name, result.failure);
233
234
  yield* refresh;
234
235
  });
235
236
  const manager = {
@@ -243,10 +244,16 @@ var ollama_default = Capability.makeModule(Effect.fnUntraced(function* () {
243
244
  unload,
244
245
  remove
245
246
  };
246
- return [Capability.contributes(AppCapabilities.AiModelResolver, OllamaSidecarModelResolver.pipe(Layer.provide(sidecarLayer)), () => Effect.tryPromise(() => runtime.dispose())), Capability.contributes(AssistantCapabilities.OllamaManager, manager)];
247
+ yield* Effect.addFinalizer(() => Effect.tryPromise(() => runtime.dispose()).pipe(Effect.catch((error) => Effect.sync(() => log.warn("ollama runtime dispose failed", { error }, {
248
+ "~LogMeta": "~LogMeta",
249
+ F: __dxlog_file,
250
+ L: 265,
251
+ S: this
252
+ })))));
253
+ return [Capability.contribute(AppCapabilities.AiModelResolver, OllamaSidecarModelResolver.pipe(Layer.provide(sidecarLayer))), Capability.contribute(AssistantCapabilities.OllamaManager, manager)];
247
254
  }));
248
- var OllamaSidecar = class OllamaSidecar extends Context.Tag("@dxos/plugin-native/OllamaSidecar")() {
249
- static layerLive = Layer.scoped(OllamaSidecar, Effect.gen(function* () {
255
+ var OllamaSidecar = class OllamaSidecar extends Context.Service()("@dxos/plugin-native/OllamaSidecar") {
256
+ static layerLive = Layer.effect(OllamaSidecar, Effect.gen(function* () {
250
257
  const command = Command.sidecar("sidecar/ollama", ["serve"], { env: {
251
258
  OLLAMA_HOST,
252
259
  OLLAMA_ORIGINS: "*"
@@ -256,13 +263,13 @@ var OllamaSidecar = class OllamaSidecar extends Context.Tag("@dxos/plugin-native
256
263
  command.on("close", (code) => log.info("Ollama process exited", { code }, {
257
264
  "~LogMeta": "~LogMeta",
258
265
  F: __dxlog_file,
259
- L: 299,
266
+ L: 302,
260
267
  S: this
261
268
  }));
262
269
  command.on("error", (error) => log.error("Ollama error", { error }, {
263
270
  "~LogMeta": "~LogMeta",
264
271
  F: __dxlog_file,
265
- L: 300,
272
+ L: 303,
266
273
  S: this
267
274
  }));
268
275
  const child = yield* Effect.promise(() => command.spawn());
@@ -272,18 +279,18 @@ var OllamaSidecar = class OllamaSidecar extends Context.Tag("@dxos/plugin-native
272
279
  log.info("Running ollama", { pid: child.pid }, {
273
280
  "~LogMeta": "~LogMeta",
274
281
  F: __dxlog_file,
275
- L: 307,
282
+ L: 310,
276
283
  S: this
277
284
  });
278
285
  return { endpoint: OLLAMA_HOST };
279
286
  }));
280
287
  };
281
- var OllamaSidecarModelResolver = Layer.unwrapEffect(Effect.gen(function* () {
288
+ var OllamaSidecarModelResolver = Layer.unwrap(Effect.gen(function* () {
282
289
  const { endpoint } = yield* OllamaSidecar;
283
290
  return OllamaResolver.make({
284
291
  endpoint,
285
292
  provider: Provider.builtIn.id,
286
- transformClient: HttpClient.withTracerPropagation(false)
293
+ transformClient: HttpClient.transformResponse(Effect.provideService(HttpClient.TracerPropagationEnabled, false))
287
294
  });
288
295
  })).pipe(Layer.provide(FetchHttpClient.layer));
289
296
  var formatError = (error) => typeof error === "string" ? error : error instanceof Error ? error.message : String(error);