alt-plugin-sdk 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,173 @@
1
+ # `alt-plugin-sdk`
2
+
3
+ Type-safe browser SDK and runtime contracts for Alt plugins.
4
+
5
+ Plugins run inside an isolated `WebContentsView` and talk to the host through a single `window.alt` object exposed by Alt's preload bridge. This package ships:
6
+
7
+ - the `alt` runtime client that proxies into `window.alt`
8
+ - the Zod schemas + TypeScript types every Alt plugin call uses
9
+ - `defineManifest(...)` for authoring `manifest.json` in TypeScript
10
+ - `createAltFetch()` / `createAltProvider()` AI helpers for AI-SDK consumers
11
+
12
+ ```ts
13
+ import { alt, defineManifest } from 'alt-plugin-sdk';
14
+
15
+ export const manifest = defineManifest({
16
+ id: 'my.plugin',
17
+ name: 'My Plugin',
18
+ version: '1.0.0',
19
+ entry: 'index.html',
20
+ permissions: ['storage', 'notes:read'],
21
+ });
22
+
23
+ const folders = await alt.notes.listFolders();
24
+ ```
25
+
26
+ ## Manifest
27
+
28
+ `manifest.json` lives at the root of the plugin bundle. Fields:
29
+
30
+ | Field | Type | Notes |
31
+ | ------------- | ---------- | ---------------------------------------------------------------------------------- |
32
+ | `id` | `string` | Lowercase, dots/dashes/underscores allowed |
33
+ | `name` | `string` | Display name |
34
+ | `version` | `string` | Semver string |
35
+ | `entry` | `string` | HTML file path inside the bundle |
36
+ | `permissions` | `string[]` | See below — all requested permissions are granted on install |
37
+ | `sdkVersion` | `string` | Optional. Defaults to `"1"`. The host refuses plugins whose major exceeds its own. |
38
+ | `description` | `string` | Optional, ≤ 500 chars |
39
+ | `author` | `string` | Optional |
40
+ | `icon` | `string` | Optional, data URI or relative path |
41
+
42
+ ## Permissions
43
+
44
+ A plugin is granted exactly what its manifest declares. Methods that need a permission throw at the IPC boundary if it's missing.
45
+
46
+ | Permission | Surface it unlocks |
47
+ | ------------------- | ------------------------------------------------------------------------------------------------------------------------ |
48
+ | `storage` | `alt.storage.*` |
49
+ | `appState:read` | `alt.state.getActiveNoteSummary()` |
50
+ | `events:subscribe` | `alt.events.subscribe(...)` |
51
+ | `notes:read` | `alt.notes.list*`, `getContent`, `getMemo`, `listComponents`, `getComponent` |
52
+ | `notes:write` | `alt.notes.create/update/delete/setMemo/setSummary/appendTranscriptLine/upsertComponent/deleteComponent` |
53
+ | `notes:select` | `alt.notes.select(...)` — focuses a note in Alt's main window |
54
+ | `folders:write` | `alt.folders.create/rename/move/delete` |
55
+ | `ai:chat` | `alt.ai.models.list / stream / chat.stream / complete / summarize` |
56
+ | `recording:control` | `alt.recording.start/stop/getStatus` |
57
+ | `transcription:run` | `alt.transcription.transcribeFile / transcribeNote` |
58
+ | `files:read` | `alt.files.list / read` |
59
+ | `files:write` | `alt.files.attach / delete` |
60
+ | `settings:read` | `alt.settings.get / list` |
61
+ | `actions:notes` | **Legacy.** Old plugins that declare this get `notes:write` + `notes:select` automatically — no manifest changes needed. |
62
+
63
+ ## API surface
64
+
65
+ Every method below is a method on `alt.<namespace>` and returns a `Promise` (or, for streaming, a handle).
66
+
67
+ ### `alt.storage`
68
+
69
+ JSON key-value scoped to your plugin.
70
+
71
+ - `get(key)` / `set(key, value)` / `delete(key)` / `list()`
72
+
73
+ ### `alt.state`
74
+
75
+ - `getActiveNoteSummary()` — the note the user is currently looking at, or `null`.
76
+
77
+ ### `alt.events`
78
+
79
+ `subscribe<TEvent>(event, callback) → unsubscribe`. Events the host emits:
80
+
81
+ - `activeNoteChanged` — payload is the new active note summary or `null`
82
+ - `recordingStatusChanged` — `{ status, noteId, durationMs }`
83
+ - `transcriptUpdated` — `{ noteId }`
84
+ - `noteCreated` / `noteUpdated` — note summary
85
+ - `noteDeleted` — `{ noteId }`
86
+ - `folderCreated` / `folderUpdated` — folder node
87
+ - `folderDeleted` — `{ folderId }`
88
+ - `componentUpdated` — component summary
89
+ - `settingChanged` — `{ key, value }` for a curated app setting
90
+ - `recordingLevel` — reserved; not emitted yet
91
+
92
+ ### `alt.notes`
93
+
94
+ Read:
95
+
96
+ - `listFolders()` → recursive folder tree
97
+ - `list({ folderId?, query?, limit? })` → note summaries (max 200)
98
+ - `getContent(noteId)` → `{ transcript, memo, summary, title }`
99
+ - `getMemo({ noteId })` → `{ markdown }`
100
+ - `listComponents({ noteId })`
101
+ - `getComponent({ componentId })`
102
+
103
+ Write:
104
+
105
+ - `create({ title, folderId? })`
106
+ - `select({ noteId })`
107
+ - `update({ noteId, title?, status?, folderId? })`
108
+ - `delete({ noteId })`
109
+ - `setMemo({ noteId, markdown })` / `setSummary({ noteId, markdown })`
110
+ - `appendTranscriptLine({ noteId, text, startMs, endMs?, speaker? })`
111
+ - `upsertComponent({ noteId, componentType, title, contentText, componentId?, displayOrder? })` — text-based components only
112
+ - `deleteComponent({ componentId })`
113
+
114
+ ### `alt.folders`
115
+
116
+ - `create({ name, parentId? })` / `rename({ folderId, name })` / `move({ folderId, parentId })` / `delete({ folderId })`
117
+
118
+ ### `alt.ai`
119
+
120
+ - `models.list()` → which models are available to this plugin
121
+ - `chat.stream(request, handlers)` → OpenAI-compatible streaming via `MessageChannel`. Plugins typically use `createAltFetch()` / `createAltProvider()` from this package instead.
122
+ - `complete(request)` → non-streaming convenience. Buffers the stream and returns `{ text, finishReason, toolCalls? }`.
123
+ - `summarize({ noteId, style?, outputLanguage?, model? })` → runs Alt's built-in summarize prompt against the note's transcript + memo and returns `{ noteId, text }`.
124
+ - `stream(...)` — **`@deprecated`**. Use `alt.ai.chat.stream` instead.
125
+
126
+ ### `alt.recording`
127
+
128
+ - `start({ noteId, lectureLanguage?, targetTranslationLanguage?, includeSystemAudio?, selectedDeviceId? })` → `{ ok, sessionId }`
129
+ - `stop()` / `getStatus()` → typed `PluginRecordingStatus`
130
+
131
+ Pause/resume are deliberately not exposed — Alt itself doesn't support them.
132
+
133
+ ### `alt.transcription`
134
+
135
+ Both methods stream segments through `PluginTranscriptionStreamHandlers` and return a handle with `cancel()`.
136
+
137
+ - `transcribeFile({ requestId, filePath, language?, diarization? }, handlers)` — arbitrary audio path on disk
138
+ - `transcribeNote({ requestId, noteId, language?, diarization? }, handlers)` — resolves the note's recording component to a path automatically
139
+
140
+ Handler shape: `onStart({ durationMs })`, `onSegment(segment)`, `onProgress({ fraction })`, `onEnd({ segments })`, `onError({ code, message })`.
141
+
142
+ ### `alt.files`
143
+
144
+ - `attach({ noteId, fileName, data, mimeType?, componentType, title?, displayOrder? })` — writes the bytes under Alt's plugin storage directory and creates a `slides` or `recording` component
145
+ - `list({ noteId })` → `PluginAttachedFile[]`
146
+ - `read({ fileId })` → `{ fileName, mimeType, sizeBytes, data: ArrayBuffer }`
147
+ - `delete({ componentId })`
148
+
149
+ ### `alt.settings`
150
+
151
+ Read-only, curated allowlist. Plugins that need their own settings should use `alt.storage`.
152
+
153
+ - `get(key)` — one of `theme`, `language`, `transcription.lectureLanguage`, `transcription.diarizationEnabled`, `transcription.includeSystemAudio`
154
+ - `list()` → snapshot of every key above
155
+
156
+ ## AI helpers
157
+
158
+ ```ts
159
+ import { createAltFetch, createAltProvider } from 'alt-plugin-sdk';
160
+ import { generateText } from 'ai';
161
+
162
+ const provider = createAltProvider();
163
+ const { text } = await generateText({
164
+ model: provider.languageModel('auto'),
165
+ prompt: 'hello',
166
+ });
167
+ ```
168
+
169
+ `createAltFetch()` returns a `fetch`-compatible function that proxies into `alt.ai.chat.stream`, so any AI SDK that accepts a custom `fetch` (Vercel AI SDK, OpenAI SDK, etc.) works out of the box.
170
+
171
+ ## SDK versioning
172
+
173
+ The SDK declares a major version (`PLUGIN_HOST_SDK_MAJOR`). Set `manifest.sdkVersion` to the major your plugin was built against; the host refuses plugins targeting a higher major than it supports. Defaults to `"1"`.
package/dist/ai.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import { type PluginAiModelId } from './contracts.js';
2
+ export interface AltAiFetchOptions {
3
+ model?: PluginAiModelId;
4
+ }
5
+ export declare function createAltFetch(options?: AltAiFetchOptions): typeof fetch;
6
+ export declare function createAltProvider(options?: AltAiFetchOptions): import("@ai-sdk/openai-compatible").OpenAICompatibleProvider<string, string, string, string>;
7
+ //# sourceMappingURL=ai.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../src/ai.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,eAAe,EAErB,MAAM,gBAAgB,CAAC;AAKxB,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB;AAmDD,wBAAgB,cAAc,CAAC,OAAO,GAAE,iBAAsB,GAAG,OAAO,KAAK,CAmE5E;AAED,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,iBAAsB,gGAMhE"}
package/dist/ai.js ADDED
@@ -0,0 +1,103 @@
1
+ import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
2
+ import { pluginAiModelIdSchema, } from './contracts.js';
3
+ import { getAlt } from './client.js';
4
+ const ALT_AI_BASE_URL = 'https://alt-plugin.invalid/v1';
5
+ function getRequestUrl(input) {
6
+ if (input instanceof Request) {
7
+ return input.url;
8
+ }
9
+ return String(input);
10
+ }
11
+ function getEndpoint(input) {
12
+ const url = new URL(getRequestUrl(input));
13
+ if (url.pathname.endsWith('/chat/completions')) {
14
+ return 'chat.completions';
15
+ }
16
+ throw new Error(`Unsupported Alt AI endpoint: ${url.pathname}`);
17
+ }
18
+ function headersToRecord(headers) {
19
+ const record = {};
20
+ headers.forEach((value, key) => {
21
+ if (key.toLowerCase() !== 'authorization' &&
22
+ key.toLowerCase() !== 'x-machine-id') {
23
+ record[key] = value;
24
+ }
25
+ });
26
+ return record;
27
+ }
28
+ async function createRequest(input, init) {
29
+ if (input instanceof Request) {
30
+ return new Request(input, init);
31
+ }
32
+ return new Request(input, init);
33
+ }
34
+ function getModelFromBody(body, fallback) {
35
+ const parsed = JSON.parse(body);
36
+ return pluginAiModelIdSchema.parse(parsed.model ?? fallback);
37
+ }
38
+ export function createAltFetch(options = {}) {
39
+ const defaultModel = options.model ?? 'auto';
40
+ return async (input, init) => {
41
+ const request = await createRequest(input, init);
42
+ const body = await request.text();
43
+ const endpoint = getEndpoint(input);
44
+ const model = getModelFromBody(body, defaultModel);
45
+ return new Promise((resolve, reject) => {
46
+ let streamController = null;
47
+ let started = false;
48
+ let activeHandle = null;
49
+ const stream = new ReadableStream({
50
+ start(controller) {
51
+ streamController = controller;
52
+ },
53
+ cancel() {
54
+ activeHandle?.cancel();
55
+ },
56
+ });
57
+ getAlt()
58
+ .ai.stream({
59
+ requestId: crypto.randomUUID(),
60
+ endpoint,
61
+ model,
62
+ method: 'POST',
63
+ headers: headersToRecord(request.headers),
64
+ body,
65
+ }, {
66
+ onStart: meta => {
67
+ started = true;
68
+ resolve(new Response(stream, {
69
+ status: meta.status,
70
+ headers: meta.headers,
71
+ }));
72
+ },
73
+ onChunk: chunk => {
74
+ streamController?.enqueue(new Uint8Array(chunk));
75
+ },
76
+ onEnd: () => {
77
+ streamController?.close();
78
+ },
79
+ onError: error => {
80
+ const nextError = new Error(error.message);
81
+ nextError.name = error.code;
82
+ if (!started) {
83
+ reject(nextError);
84
+ return;
85
+ }
86
+ streamController?.error(nextError);
87
+ },
88
+ })
89
+ .then(handle => {
90
+ activeHandle = handle;
91
+ })
92
+ .catch(reject);
93
+ });
94
+ };
95
+ }
96
+ export function createAltProvider(options = {}) {
97
+ return createOpenAICompatible({
98
+ baseURL: ALT_AI_BASE_URL,
99
+ fetch: createAltFetch(options),
100
+ name: 'alt-plugin',
101
+ });
102
+ }
103
+ //# sourceMappingURL=ai.js.map
package/dist/ai.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai.js","sourceRoot":"","sources":["../src/ai.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,122 @@
1
+ import type { PluginAction, PluginActionPayloadMap, PluginActionResultMap, PluginActiveNoteSummary, PluginAiModelInfo, PluginAiStreamHandle, PluginAiStreamHandlers, PluginAiStreamRequest, PluginAppendTranscriptLineParams, PluginCreatedNoteSummary, PluginCreateFolderParams, PluginCreateNotePayload, PluginDeleteComponentParams, PluginDeleteFolderParams, PluginDeleteNoteParams, PluginEvent, PluginEventData, PluginFolderNode, PluginGetComponentParams, PluginGetMemoParams, PluginListComponentsParams, PluginMoveFolderParams, PluginNoteComponent, PluginNoteComponentSummary, PluginNoteContent, PluginNoteSummary, PluginNotesListParams, PluginAiCompleteRequest, PluginAiCompleteResult, PluginAiSummarizeRequest, PluginAiSummarizeResult, PluginAppSettingKey, PluginAppSettingValue, PluginAttachFileParams, PluginAttachedFile, PluginDeleteFileParams, PluginListFilesParams, PluginReadFileParams, PluginReadFileResult, PluginRecordingStartParams, PluginRecordingStatus, PluginRenameFolderParams, PluginSdkMethod, PluginSelectNotePayload, PluginSetMemoParams, PluginSetSummaryParams, PluginStorageValue, PluginTranscribeFileRequest, PluginTranscribeNoteRequest, PluginTranscriptionStreamHandle, PluginTranscriptionStreamHandlers, PluginUpdateNoteParams, PluginUpsertComponentParams } from './contracts.js';
2
+ type PluginEventCallback<TEvent extends PluginEvent> = (payload: PluginEventData<TEvent>) => void;
3
+ export interface AltPluginApi {
4
+ storage: {
5
+ get(key: string): Promise<PluginStorageValue | undefined>;
6
+ set(key: string, value: PluginStorageValue): Promise<void>;
7
+ delete(key: string): Promise<void>;
8
+ list(): Promise<Record<string, PluginStorageValue>>;
9
+ };
10
+ state: {
11
+ getActiveNoteSummary(): Promise<PluginActiveNoteSummary | null>;
12
+ };
13
+ events: {
14
+ subscribe<TEvent extends PluginEvent>(event: TEvent, callback: PluginEventCallback<TEvent>): Promise<() => Promise<void>>;
15
+ };
16
+ actions: {
17
+ /**
18
+ * @deprecated Use `alt.notes.create()` and `alt.notes.select()` instead.
19
+ * Retained as a shim for plugins built against SDK v0.
20
+ */
21
+ invoke<TAction extends PluginAction>(action: TAction, payload: PluginActionPayloadMap[TAction]): Promise<PluginActionResultMap[TAction]>;
22
+ };
23
+ ai: {
24
+ models: {
25
+ list(): Promise<PluginAiModelInfo[]>;
26
+ };
27
+ /**
28
+ * @deprecated Use `alt.ai.chat.stream` instead — same call, future-proof name.
29
+ */
30
+ stream(request: PluginAiStreamRequest, handlers: PluginAiStreamHandlers): Promise<PluginAiStreamHandle>;
31
+ chat: {
32
+ stream(request: PluginAiStreamRequest, handlers: PluginAiStreamHandlers): Promise<PluginAiStreamHandle>;
33
+ };
34
+ /** Non-streaming convenience wrapper. Buffers the stream into a single result. */
35
+ complete(request: PluginAiCompleteRequest): Promise<PluginAiCompleteResult>;
36
+ /**
37
+ * Generate a summary of an Alt note using the same prompt the in-app
38
+ * summarize action uses. The host pulls the note's content and runs it
39
+ * through the configured model.
40
+ */
41
+ summarize(request: PluginAiSummarizeRequest): Promise<PluginAiSummarizeResult>;
42
+ };
43
+ notes: {
44
+ listFolders(): Promise<PluginFolderNode[]>;
45
+ list(params?: PluginNotesListParams): Promise<PluginNoteSummary[]>;
46
+ getContent(noteId: number): Promise<PluginNoteContent>;
47
+ create(payload: PluginCreateNotePayload): Promise<PluginCreatedNoteSummary>;
48
+ select(payload: PluginSelectNotePayload): Promise<{
49
+ ok: true;
50
+ }>;
51
+ update(params: PluginUpdateNoteParams): Promise<PluginNoteSummary>;
52
+ delete(params: PluginDeleteNoteParams): Promise<{
53
+ ok: true;
54
+ }>;
55
+ setMemo(params: PluginSetMemoParams): Promise<{
56
+ componentId: number;
57
+ }>;
58
+ getMemo(params: PluginGetMemoParams): Promise<{
59
+ markdown: string;
60
+ }>;
61
+ setSummary(params: PluginSetSummaryParams): Promise<{
62
+ componentId: number;
63
+ }>;
64
+ appendTranscriptLine(params: PluginAppendTranscriptLineParams): Promise<{
65
+ componentId: number;
66
+ }>;
67
+ listComponents(params: PluginListComponentsParams): Promise<PluginNoteComponentSummary[]>;
68
+ getComponent(params: PluginGetComponentParams): Promise<PluginNoteComponent>;
69
+ upsertComponent(params: PluginUpsertComponentParams): Promise<PluginNoteComponentSummary>;
70
+ deleteComponent(params: PluginDeleteComponentParams): Promise<{
71
+ ok: true;
72
+ }>;
73
+ };
74
+ folders: {
75
+ create(params: PluginCreateFolderParams): Promise<PluginFolderNode>;
76
+ rename(params: PluginRenameFolderParams): Promise<PluginFolderNode>;
77
+ move(params: PluginMoveFolderParams): Promise<PluginFolderNode>;
78
+ delete(params: PluginDeleteFolderParams): Promise<{
79
+ ok: true;
80
+ }>;
81
+ };
82
+ recording: {
83
+ start(params: PluginRecordingStartParams): Promise<{
84
+ ok: true;
85
+ sessionId: string;
86
+ }>;
87
+ stop(): Promise<{
88
+ ok: true;
89
+ }>;
90
+ getStatus(): Promise<PluginRecordingStatus>;
91
+ };
92
+ transcription: {
93
+ transcribeFile(request: PluginTranscribeFileRequest, handlers: PluginTranscriptionStreamHandlers): Promise<PluginTranscriptionStreamHandle>;
94
+ transcribeNote(request: PluginTranscribeNoteRequest, handlers: PluginTranscriptionStreamHandlers): Promise<PluginTranscriptionStreamHandle>;
95
+ };
96
+ files: {
97
+ attach(params: PluginAttachFileParams): Promise<PluginAttachedFile>;
98
+ list(params: PluginListFilesParams): Promise<PluginAttachedFile[]>;
99
+ read(params: PluginReadFileParams): Promise<PluginReadFileResult>;
100
+ delete(params: PluginDeleteFileParams): Promise<{
101
+ ok: true;
102
+ }>;
103
+ };
104
+ settings: {
105
+ /** Returns the value of a curated app-level setting, or null if unset. */
106
+ get(key: PluginAppSettingKey): Promise<PluginAppSettingValue>;
107
+ /** Returns the full curated allowlist with current values. */
108
+ list(): Promise<Record<PluginAppSettingKey, PluginAppSettingValue>>;
109
+ };
110
+ }
111
+ export interface AltPluginInvokeBridge {
112
+ invoke(method: PluginSdkMethod, params?: unknown): Promise<unknown>;
113
+ }
114
+ export declare function getAlt(): AltPluginApi;
115
+ export declare const alt: AltPluginApi;
116
+ declare global {
117
+ interface Window {
118
+ alt: AltPluginApi;
119
+ }
120
+ }
121
+ export {};
122
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/client.js ADDED
@@ -0,0 +1,82 @@
1
+ function requireWindowAlt() {
2
+ const maybeWindow = globalThis
3
+ .window;
4
+ if (!maybeWindow?.alt) {
5
+ throw new Error('Alt plugin SDK is only available inside an Alt plugin');
6
+ }
7
+ return maybeWindow.alt;
8
+ }
9
+ export function getAlt() {
10
+ return requireWindowAlt();
11
+ }
12
+ export const alt = {
13
+ storage: {
14
+ get: key => getAlt().storage.get(key),
15
+ set: (key, value) => getAlt().storage.set(key, value),
16
+ delete: key => getAlt().storage.delete(key),
17
+ list: () => getAlt().storage.list(),
18
+ },
19
+ state: {
20
+ getActiveNoteSummary: () => getAlt().state.getActiveNoteSummary(),
21
+ },
22
+ events: {
23
+ subscribe: (event, callback) => getAlt().events.subscribe(event, callback),
24
+ },
25
+ actions: {
26
+ invoke: (action, payload) => getAlt().actions.invoke(action, payload),
27
+ },
28
+ ai: {
29
+ models: {
30
+ list: () => getAlt().ai.models.list(),
31
+ },
32
+ stream: (request, handlers) => getAlt().ai.stream(request, handlers),
33
+ chat: {
34
+ stream: (request, handlers) => getAlt().ai.stream(request, handlers),
35
+ },
36
+ complete: request => getAlt().ai.complete(request),
37
+ summarize: request => getAlt().ai.summarize(request),
38
+ },
39
+ notes: {
40
+ listFolders: () => getAlt().notes.listFolders(),
41
+ list: params => getAlt().notes.list(params),
42
+ getContent: noteId => getAlt().notes.getContent(noteId),
43
+ create: payload => getAlt().notes.create(payload),
44
+ select: payload => getAlt().notes.select(payload),
45
+ update: params => getAlt().notes.update(params),
46
+ delete: params => getAlt().notes.delete(params),
47
+ setMemo: params => getAlt().notes.setMemo(params),
48
+ getMemo: params => getAlt().notes.getMemo(params),
49
+ setSummary: params => getAlt().notes.setSummary(params),
50
+ appendTranscriptLine: params => getAlt().notes.appendTranscriptLine(params),
51
+ listComponents: params => getAlt().notes.listComponents(params),
52
+ getComponent: params => getAlt().notes.getComponent(params),
53
+ upsertComponent: params => getAlt().notes.upsertComponent(params),
54
+ deleteComponent: params => getAlt().notes.deleteComponent(params),
55
+ },
56
+ folders: {
57
+ create: params => getAlt().folders.create(params),
58
+ rename: params => getAlt().folders.rename(params),
59
+ move: params => getAlt().folders.move(params),
60
+ delete: params => getAlt().folders.delete(params),
61
+ },
62
+ recording: {
63
+ start: params => getAlt().recording.start(params),
64
+ stop: () => getAlt().recording.stop(),
65
+ getStatus: () => getAlt().recording.getStatus(),
66
+ },
67
+ transcription: {
68
+ transcribeFile: (request, handlers) => getAlt().transcription.transcribeFile(request, handlers),
69
+ transcribeNote: (request, handlers) => getAlt().transcription.transcribeNote(request, handlers),
70
+ },
71
+ files: {
72
+ attach: params => getAlt().files.attach(params),
73
+ list: params => getAlt().files.list(params),
74
+ read: params => getAlt().files.read(params),
75
+ delete: params => getAlt().files.delete(params),
76
+ },
77
+ settings: {
78
+ get: key => getAlt().settings.get(key),
79
+ list: () => getAlt().settings.list(),
80
+ },
81
+ };
82
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}