@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.
- package/PLUGIN.mdl +2 -2
- package/dist/lib/NativeCapabilities.mjs +14 -0
- package/dist/lib/NativeCapabilities.mjs.map +1 -0
- package/dist/lib/NativeEvents.mjs +15 -0
- package/dist/lib/NativeEvents.mjs.map +1 -0
- package/dist/lib/NativePlugin.mjs +13 -27
- package/dist/lib/NativePlugin.mjs.map +1 -1
- package/dist/lib/Settings.mjs +10 -0
- package/dist/lib/Settings.mjs.map +1 -0
- package/dist/lib/Update.mjs +7 -0
- package/dist/lib/Update.mjs.map +1 -0
- package/dist/lib/capabilities.mjs +40 -7
- package/dist/lib/capabilities.mjs.map +1 -1
- package/dist/lib/capabilities.node.mjs +35 -0
- package/dist/lib/capabilities.node.mjs.map +1 -0
- package/dist/lib/capabilities.workerd.mjs +35 -0
- package/dist/lib/capabilities.workerd.mjs.map +1 -0
- package/dist/lib/chunk-NativeSettings.mjs +5 -2
- package/dist/lib/chunk-NativeSettings.mjs.map +1 -1
- package/dist/lib/chunk-ollama.mjs +38 -31
- package/dist/lib/chunk-ollama.mjs.map +1 -1
- package/dist/lib/chunk-react-surface.mjs +3 -2
- package/dist/lib/chunk-react-surface.mjs.map +1 -1
- package/dist/lib/chunk-rolldown-runtime.mjs +13 -0
- package/dist/lib/chunk-settings.mjs +4 -4
- package/dist/lib/chunk-settings.mjs.map +1 -1
- package/dist/lib/chunk-spotlight-listener.mjs +9 -7
- package/dist/lib/chunk-spotlight-listener.mjs.map +1 -1
- package/dist/lib/chunk-updater.mjs +37 -22
- package/dist/lib/chunk-updater.mjs.map +1 -1
- package/dist/lib/index.mjs +4 -2
- package/dist/lib/meta.mjs +33 -1
- package/dist/lib/meta.mjs.map +1 -0
- package/dist/lib/plugin.mjs +6 -5
- package/dist/lib/plugin.mjs.map +1 -1
- package/dist/lib/translations.mjs +2 -1
- package/dist/lib/translations.mjs.map +1 -1
- package/dist/lib/types.mjs +5 -33
- package/dist/types/src/NativePlugin.d.ts +36 -3
- package/dist/types/src/NativePlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/gen/node.d.ts +9 -0
- package/dist/types/src/capabilities/gen/node.d.ts.map +1 -0
- package/dist/types/src/capabilities/gen/workerd.d.ts +9 -0
- package/dist/types/src/capabilities/gen/workerd.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +8 -6
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/ollama.d.ts +4 -4
- package/dist/types/src/capabilities/ollama.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts +2 -2
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/capabilities/settings.d.ts +2 -2
- package/dist/types/src/capabilities/settings.d.ts.map +1 -1
- package/dist/types/src/capabilities/spotlight-listener.d.ts +2 -2
- package/dist/types/src/capabilities/spotlight-listener.d.ts.map +1 -1
- package/dist/types/src/capabilities/updater.d.ts +2 -2
- package/dist/types/src/capabilities/updater.d.ts.map +1 -1
- package/dist/types/src/constants.d.ts +7 -1
- package/dist/types/src/constants.d.ts.map +1 -1
- package/dist/types/src/containers/NativeSettings/NativeSettings.d.ts +3 -0
- package/dist/types/src/containers/NativeSettings/NativeSettings.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +3 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/plugin.d.ts +2 -1
- package/dist/types/src/plugin.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +7 -5
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/NativeCapabilities.d.ts +4 -4
- package/dist/types/src/types/NativeCapabilities.d.ts.map +1 -1
- package/dist/types/src/types/NativeEvents.d.ts +8 -0
- package/dist/types/src/types/NativeEvents.d.ts.map +1 -0
- package/dist/types/src/types/Settings.d.ts +1 -1
- package/dist/types/src/types/Settings.d.ts.map +1 -1
- package/dist/types/src/types/Update.d.ts +3 -1
- package/dist/types/src/types/Update.d.ts.map +1 -1
- package/dist/types/src/types/index.d.ts +1 -0
- package/dist/types/src/types/index.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +68 -29
- package/src/NativePlugin.ts +15 -0
- package/src/capabilities/gen/node.ts +55 -0
- package/src/capabilities/gen/workerd.ts +55 -0
- package/src/capabilities/index.ts +54 -6
- package/src/capabilities/ollama.ts +51 -49
- package/src/capabilities/react-surface.ts +3 -2
- package/src/capabilities/settings.ts +4 -4
- package/src/capabilities/spotlight-listener.ts +6 -4
- package/src/capabilities/updater.ts +24 -21
- package/src/constants.ts +7 -3
- package/src/containers/NativeSettings/NativeSettings.tsx +9 -2
- package/src/index.ts +3 -1
- package/src/meta.ts +1 -1
- package/src/plugin.tsx +29 -0
- package/src/translations.ts +1 -0
- package/src/types/NativeCapabilities.ts +5 -5
- package/src/types/NativeEvents.ts +16 -0
- package/src/types/Settings.ts +2 -1
- package/src/types/Update.ts +4 -1
- package/src/types/index.ts +2 -1
- package/dist/lib/chunk-meta.mjs +0 -34
- package/dist/lib/chunk-meta.mjs.map +0 -1
- package/dist/lib/types.mjs.map +0 -1
- package/src/NativePlugin.tsx +0 -41
- 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
|
|
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
|
|
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 {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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
|
-
|
|
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.
|
|
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 @@
|
|
|
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
|
|
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 =
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
var
|
|
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
|
|
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
|
|
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
|
|
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":";;;;;;;;;;;;;AAkCA,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;EACxD,UAAA,oBAAC,KAAK,UAAN;GAAe,QAAA;GACb,UAAA,oBAAC,KAAK,SAAN,EAAA,UACE,oBAAC,KAAK,SAAN;IAAc,OAAO,KAAK,QAAQ,QAAQ,KAAK,QAAQ;IACrD,UAAA,oBAAC,KAAK,KAAN;KAAU,OAAO,EAAE,wBAAwB;KAAgB;KACxD,UAAA;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;EAC7G,UAAA,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,MAAM,UAAU;EACjC,aAAa,EAAE,8BAA8B;EAC7C,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;GAC7E,UAAA,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;IAAU,UAAA,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;GACxF,UAAA,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,21 +1,22 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
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*
|
|
27
|
+
const registry = yield* Capabilities.AtomRegistry;
|
|
27
28
|
const runtime = ManagedRuntime.make(OllamaSidecar.layerLive);
|
|
28
|
-
const sidecarLayer = Layer.effectContext(runtime.
|
|
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.
|
|
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 (
|
|
68
|
+
if (Result.isFailure(result)) return;
|
|
68
69
|
const before = (yield* getState).loaded.map((model) => model.name);
|
|
69
|
-
const after = result.
|
|
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.
|
|
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 (
|
|
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.
|
|
98
|
+
models: result.success,
|
|
98
99
|
error: void 0
|
|
99
100
|
}));
|
|
100
|
-
yield* Effect.sync(() => log.info("ollama models", { installed: result.
|
|
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.
|
|
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.
|
|
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 (
|
|
200
|
+
if (Result.isFailure(result)) {
|
|
200
201
|
yield* Effect.sync(() => log.warn("ollama load failed", {
|
|
201
202
|
name,
|
|
202
|
-
error: result.
|
|
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.
|
|
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 (
|
|
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 (
|
|
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
|
-
|
|
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.
|
|
249
|
-
static layerLive = Layer.
|
|
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:
|
|
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:
|
|
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:
|
|
282
|
+
L: 310,
|
|
276
283
|
S: this
|
|
277
284
|
});
|
|
278
285
|
return { endpoint: OLLAMA_HOST };
|
|
279
286
|
}));
|
|
280
287
|
};
|
|
281
|
-
var OllamaSidecarModelResolver = Layer.
|
|
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.
|
|
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);
|