@symbiosis-lab/moss-api 0.7.11 → 0.10.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 +22 -129
- package/dist/core-serM6jqp.mjs +159 -0
- package/dist/core-serM6jqp.mjs.map +1 -0
- package/dist/event-BovtnpSn.mjs +83 -0
- package/dist/event-BovtnpSn.mjs.map +1 -0
- package/dist/index.d.mts +768 -249
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +500 -525
- package/dist/index.mjs.map +1 -1
- package/dist/testing/index.d.mts +4 -2
- package/dist/testing/index.d.mts.map +1 -1
- package/dist/testing/index.mjs +91 -3
- package/dist/testing/index.mjs.map +1 -1
- package/package.json +13 -12
package/dist/index.d.mts
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
//#region src/types/plugin.d.ts
|
|
2
2
|
/**
|
|
3
|
-
* Base plugin types shared across all
|
|
3
|
+
* Base plugin types shared across all moss plugins
|
|
4
4
|
*/
|
|
5
5
|
interface ProjectInfo {
|
|
6
6
|
project_type: string;
|
|
7
7
|
content_folders: string[];
|
|
8
8
|
total_files: number;
|
|
9
9
|
homepage_file?: string;
|
|
10
|
+
/**
|
|
11
|
+
* Root folder basename (e.g. "刘果"). Plugins that generate a folder home
|
|
12
|
+
* should name it self-named (`<folder_name>.md`) with a `home: true` marker
|
|
13
|
+
* to match moss's folder-home convention.
|
|
14
|
+
*/
|
|
15
|
+
folder_name?: string;
|
|
16
|
+
site_name?: string;
|
|
17
|
+
lang?: string;
|
|
10
18
|
}
|
|
11
19
|
interface PluginManifest {
|
|
12
20
|
name: string;
|
|
@@ -20,8 +28,292 @@ interface PluginManifest {
|
|
|
20
28
|
}
|
|
21
29
|
type PluginCategory = "generator" | "deployer" | "syndicator" | "enhancer" | "processor";
|
|
22
30
|
//#endregion
|
|
31
|
+
//#region src/types/messages.d.ts
|
|
32
|
+
/**
|
|
33
|
+
* Plugin message types for communication with moss
|
|
34
|
+
*/
|
|
35
|
+
/**
|
|
36
|
+
* Messages that plugins can send to moss
|
|
37
|
+
*/
|
|
38
|
+
type PluginMessage = LogMessage | ProgressMessage | ErrorMessage | CompleteMessage;
|
|
39
|
+
interface LogMessage {
|
|
40
|
+
type: "log";
|
|
41
|
+
level: "log" | "warn" | "error";
|
|
42
|
+
message: string;
|
|
43
|
+
}
|
|
44
|
+
interface ProgressMessage {
|
|
45
|
+
type: "progress";
|
|
46
|
+
phase: string;
|
|
47
|
+
current: number;
|
|
48
|
+
total: number;
|
|
49
|
+
message?: string;
|
|
50
|
+
}
|
|
51
|
+
interface ErrorMessage {
|
|
52
|
+
type: "error";
|
|
53
|
+
error: string;
|
|
54
|
+
context?: string;
|
|
55
|
+
fatal: boolean;
|
|
56
|
+
}
|
|
57
|
+
interface CompleteMessage {
|
|
58
|
+
type: "complete";
|
|
59
|
+
success: boolean;
|
|
60
|
+
error?: string;
|
|
61
|
+
result?: unknown;
|
|
62
|
+
}
|
|
63
|
+
//#endregion
|
|
64
|
+
//#region src/utils/messaging.d.ts
|
|
65
|
+
/**
|
|
66
|
+
* Set the message context for subsequent messages
|
|
67
|
+
* This is typically called automatically by the plugin runtime
|
|
68
|
+
*/
|
|
69
|
+
declare function setMessageContext(pluginName: string, hookName: string): void;
|
|
70
|
+
/**
|
|
71
|
+
* Get the current message context
|
|
72
|
+
*/
|
|
73
|
+
declare function getMessageContext(): {
|
|
74
|
+
pluginName: string;
|
|
75
|
+
hookName: string;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Send a message to moss
|
|
79
|
+
*
|
|
80
|
+
* Log and progress messages use events (fire-and-forget) to avoid blocking IPC.
|
|
81
|
+
* Complete and error messages use commands (request-response) for acknowledgment.
|
|
82
|
+
*/
|
|
83
|
+
declare function sendMessage(message: PluginMessage): Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* Report progress to moss
|
|
86
|
+
*/
|
|
87
|
+
declare function reportProgress(phase: string, current: number, total: number, message?: string): Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* Report an error to moss
|
|
90
|
+
*/
|
|
91
|
+
declare function reportError(error: string, context?: string, fatal?: boolean): Promise<void>;
|
|
92
|
+
/**
|
|
93
|
+
* Report completion to moss
|
|
94
|
+
* @param success - Whether the operation succeeded
|
|
95
|
+
* @param result - Optional result data
|
|
96
|
+
* @param error - Optional error message (only used when success is false)
|
|
97
|
+
*/
|
|
98
|
+
declare function reportComplete(success: boolean, result?: unknown, error?: string): Promise<void>;
|
|
99
|
+
/**
|
|
100
|
+
* `PluginHook` mirrors the closed Rust enum in
|
|
101
|
+
* `src-tauri/src/plugins/types.rs`. The router (T1) cross-products
|
|
102
|
+
* `PluginHook × TriggerContext` to pick a UI surface for the task.
|
|
103
|
+
* Plugin authors pick the hook that matches what they're doing; they
|
|
104
|
+
* do NOT pick the surface (the router owns that).
|
|
105
|
+
*/
|
|
106
|
+
type PluginHook = "import" | "publish" | "deploy" | "syndicate" | "process" | "enhance";
|
|
107
|
+
/**
|
|
108
|
+
* `TriggerContext` mirrors the closed Rust enum. Tells the router *why*
|
|
109
|
+
* the task was invoked so it can pick a surface that matches the user's
|
|
110
|
+
* focus context (onboarding cards → ActionPanel; background sync →
|
|
111
|
+
* Workspace).
|
|
112
|
+
*/
|
|
113
|
+
type TriggerContext = "onboarding_flow" | "settings_manual" | "background" | "manual_one";
|
|
114
|
+
/**
|
|
115
|
+
* Escape kind for `awaiting()` calls. The string variants take a
|
|
116
|
+
* free-text affordance label after the colon, mirroring the dev harness
|
|
117
|
+
* dialect (e.g., `"resend:Resend email"`, `"recheck:Recheck DNS"`).
|
|
118
|
+
* Plain `"cancel"` carries no label.
|
|
119
|
+
*/
|
|
120
|
+
type EscapeSpec = "cancel" | `resend:${string}` | `recheck:${string}`;
|
|
121
|
+
/**
|
|
122
|
+
* Which axis of the system an advisory is about. Mirrors the Rust
|
|
123
|
+
* `advisory::Scope` (externally-tagged unit enum → bare string).
|
|
124
|
+
*/
|
|
125
|
+
type AdvisoryScope = "File" | "Config" | "Environment" | "Remote" | "Account";
|
|
126
|
+
/**
|
|
127
|
+
* How serious the plugin proposes an advisory is. moss CLAMPS this (R13): a
|
|
128
|
+
* `Blocking` proposal with no actionable affordance is demoted to a quiet
|
|
129
|
+
* `NeedsAction` hairline dot. Mirrors the Rust `advisory::Severity`.
|
|
130
|
+
*/
|
|
131
|
+
type AdvisorySeverity = "ShippedDegraded" | "NeedsAction" | "Blocking";
|
|
132
|
+
/**
|
|
133
|
+
* A closed set of in-app operations an `AdvisoryAction.InApp` can request.
|
|
134
|
+
* Mirrors the Rust `advisory::AppOp`.
|
|
135
|
+
*/
|
|
136
|
+
type AdvisoryAppOp = "MoveFile" | "OpenBilling" | "SignIn" | "RecheckDns";
|
|
137
|
+
/**
|
|
138
|
+
* The recovery affordance for an advisory, expressed as data — mirrors the
|
|
139
|
+
* Rust `advisory::Action` (externally-tagged: `"None"` for the unit variant,
|
|
140
|
+
* `{ Variant: {...} }` for data variants). `Action !== "None"` is the gavel's
|
|
141
|
+
* deciding input for whether a `Blocking` proposal may pop the panel.
|
|
142
|
+
*/
|
|
143
|
+
type AdvisoryAction = "None" | {
|
|
144
|
+
Command: {
|
|
145
|
+
run: string;
|
|
146
|
+
label: string;
|
|
147
|
+
};
|
|
148
|
+
} | {
|
|
149
|
+
InApp: {
|
|
150
|
+
op: AdvisoryAppOp;
|
|
151
|
+
args: unknown;
|
|
152
|
+
label: string;
|
|
153
|
+
};
|
|
154
|
+
} | {
|
|
155
|
+
Link: {
|
|
156
|
+
href: string;
|
|
157
|
+
label: string;
|
|
158
|
+
};
|
|
159
|
+
};
|
|
160
|
+
/**
|
|
161
|
+
* A plugin's PROPOSED advisory (pre-clamp). Mirrors the Rust
|
|
162
|
+
* `plugins::types::PluginAdvisory` wire shape exactly so it deserializes
|
|
163
|
+
* directly into `PluginTaskLifecycle::Succeeded/Failed { advisories }`. moss
|
|
164
|
+
* is the only constructor of a final `Advisory` — a plugin can never hand moss
|
|
165
|
+
* one (R13).
|
|
166
|
+
*/
|
|
167
|
+
interface AdvisoryProposal {
|
|
168
|
+
/** Which axis of the system this advisory is about. */
|
|
169
|
+
scope: AdvisoryScope;
|
|
170
|
+
/** The severity the plugin REQUESTS. moss clamps it (R13). */
|
|
171
|
+
severity: AdvisorySeverity;
|
|
172
|
+
/** The item this is about — usually a filename. `null` for build-wide. */
|
|
173
|
+
item: string | null;
|
|
174
|
+
/** What happened (free text). */
|
|
175
|
+
what: string;
|
|
176
|
+
/** The recovery affordance the plugin proposes. */
|
|
177
|
+
action: AdvisoryAction;
|
|
178
|
+
}
|
|
179
|
+
interface StartTaskOptions {
|
|
180
|
+
/**
|
|
181
|
+
* Hook the task belongs to. Defaults to "import" — the most common
|
|
182
|
+
* onboarding case. Plugins should pass an explicit hook for non-import
|
|
183
|
+
* work (e.g., a syndicator passes "syndicate").
|
|
184
|
+
*/
|
|
185
|
+
hook?: PluginHook;
|
|
186
|
+
/**
|
|
187
|
+
* Trigger context. Defaults to "background" — the safest fallback
|
|
188
|
+
* because Background routes to Workspace+Ambient, the quietest surface.
|
|
189
|
+
* Plugins running inside the onboarding flow should pass
|
|
190
|
+
* "onboarding_flow" explicitly so they reach the ActionPanel hairline.
|
|
191
|
+
*/
|
|
192
|
+
trigger?: TriggerContext;
|
|
193
|
+
/**
|
|
194
|
+
* Hint to the router that this task will emit `progress()` updates
|
|
195
|
+
* with fractions. Routers and renderers MAY use this to choose between
|
|
196
|
+
* "fills" vs "pulses" visualizations. Defaults to true.
|
|
197
|
+
*/
|
|
198
|
+
hasProgress?: boolean;
|
|
199
|
+
/**
|
|
200
|
+
* Whether the user can cancel this task from the UI. Cancellation
|
|
201
|
+
* plumbing lands in a later ADR phase; the flag is recorded today so
|
|
202
|
+
* renderers can show / hide a cancel affordance.
|
|
203
|
+
*/
|
|
204
|
+
cancellable?: boolean;
|
|
205
|
+
/**
|
|
206
|
+
* Plugin-local job id referencing `contributes.jobs[id]` in the plugin's
|
|
207
|
+
* manifest (Step 3 Phase 5, §8 + R13). When set, moss looks up the declared
|
|
208
|
+
* descriptor (a past-tense `verb` + an amount `noun`), normalizes the verb
|
|
209
|
+
* (`Verb::normalized` — moss owns capitalization/length/glyphs), and on a
|
|
210
|
+
* `succeeded(receipt, count)` stamps its OWN typed `Verb` + `Amount { count,
|
|
211
|
+
* noun }` on the Job — rendering "Syndicated · N posts" from moss's value
|
|
212
|
+
* objects, never the plugin's pre-formatted `receipt` string. Omit it for
|
|
213
|
+
* free-text-receipt tasks (the legacy path, byte-identical).
|
|
214
|
+
*/
|
|
215
|
+
job?: string;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Lifecycle handle returned by `startTask()`. Calls are fire-and-await:
|
|
219
|
+
* each method returns a promise that resolves once the Rust side has
|
|
220
|
+
* applied the transition to the PanelTask registry. Terminal calls
|
|
221
|
+
* (`succeeded`, `failed`, `cancelled`) remove the task from the registry's
|
|
222
|
+
* tracking store; calling any further method on the same handle will
|
|
223
|
+
* reject with "unknown plugin task id".
|
|
224
|
+
*
|
|
225
|
+
* The state machine matches ADR-015 § Layer 2:
|
|
226
|
+
*
|
|
227
|
+
* Running ↔ Awaiting → Succeeded | Failed | Cancelled
|
|
228
|
+
*
|
|
229
|
+
* `progress()` after `awaiting()` implicitly transitions back to Running
|
|
230
|
+
* (no explicit `resumed()`).
|
|
231
|
+
*/
|
|
232
|
+
interface TaskHandle {
|
|
233
|
+
/**
|
|
234
|
+
* In-process task id minted by the Rust registry on `Started`.
|
|
235
|
+
* Exposed for log correlation and tests.
|
|
236
|
+
*
|
|
237
|
+
* Rust-side this is `u64`; specta types `u64` as `string` because
|
|
238
|
+
* JS numbers lose precision above 2^53. The handle carries the
|
|
239
|
+
* exact string through subsequent transitions so no precision is
|
|
240
|
+
* lost in the round-trip.
|
|
241
|
+
*/
|
|
242
|
+
readonly id: string;
|
|
243
|
+
/** Push a progress update. `fraction` in [0,1] if known, else undefined for indeterminate. */
|
|
244
|
+
progress(fraction?: number, message?: string): Promise<void>;
|
|
245
|
+
/**
|
|
246
|
+
* Pause for an out-of-band user action. `directive` describes what
|
|
247
|
+
* the user needs to do ("click the link in your email"); `venue`
|
|
248
|
+
* names where ("your email") — both feed the Awaiting renderer's
|
|
249
|
+
* "Waiting for you to [directive] in [venue]" copy.
|
|
250
|
+
*
|
|
251
|
+
* `escape` defaults to "cancel". For non-cancel escapes, pass
|
|
252
|
+
* "resend:<label>" or "recheck:<label>".
|
|
253
|
+
*/
|
|
254
|
+
awaiting(directive: string, venue: string, escape?: EscapeSpec): Promise<void>;
|
|
255
|
+
/**
|
|
256
|
+
* PROPOSE an advisory on this task (Step 3 Phase 5, §8 + R13). Accumulates
|
|
257
|
+
* the proposal on the handle; it is flushed into the next terminal call
|
|
258
|
+
* (`succeeded`/`failed`) as `advisories: PluginAdvisory[]`. moss holds the
|
|
259
|
+
* severity gavel server-side: a `Blocking` proposal with no actionable
|
|
260
|
+
* `action` is clamped to a quiet `NeedsAction` dot; an actionable `Blocking`
|
|
261
|
+
* on a `succeeded()` flips the run to `Failed` (invariant #1 — the smart
|
|
262
|
+
* constructor decides, not the plugin).
|
|
263
|
+
*
|
|
264
|
+
* `advise()` does NOT emit on its own; advisories ride the terminal IPC so
|
|
265
|
+
* moss applies them atomically with the success/failure transition. Calling
|
|
266
|
+
* `advise()` after a terminal call has no effect — the handle is spent (the
|
|
267
|
+
* terminal methods set a spent flag and `advise()` no-ops once spent).
|
|
268
|
+
*/
|
|
269
|
+
advise(advisory: AdvisoryProposal): Promise<void>;
|
|
270
|
+
/**
|
|
271
|
+
* Terminal: success.
|
|
272
|
+
*
|
|
273
|
+
* @param receipt Optional human-readable receipt (the legacy free-text path).
|
|
274
|
+
* IGNORED for the verb/amount when the task declared a `job` descriptor —
|
|
275
|
+
* moss renders the receipt from its OWN normalized verb + amount instead.
|
|
276
|
+
* @param amount Optional success COUNT. Only meaningful when `startTask` was
|
|
277
|
+
* given a `job` id: moss pairs this count with the descriptor's `noun` to
|
|
278
|
+
* stamp `Amount { count, noun }` and renders "Syndicated · N posts" from its
|
|
279
|
+
* value objects.
|
|
280
|
+
*/
|
|
281
|
+
succeeded(receipt?: string, amount?: number): Promise<void>;
|
|
282
|
+
/**
|
|
283
|
+
* Terminal: failure. `recoverable=false` (default) also fires the
|
|
284
|
+
* toast subscriber (ADR-015 § "Plugin-originated failure toasts").
|
|
285
|
+
*/
|
|
286
|
+
failed(error: string, recoverable?: boolean): Promise<void>;
|
|
287
|
+
/** Terminal: explicit user cancellation. */
|
|
288
|
+
cancelled(): Promise<void>;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Start a plugin task. Returns a `TaskHandle` whose methods drive the
|
|
292
|
+
* lifecycle (progress → awaiting → succeeded/failed/cancelled).
|
|
293
|
+
*
|
|
294
|
+
* The hook + trigger pair flows into the Rust-side `route_plugin_task`
|
|
295
|
+
* router, which picks `(TaskScope, TaskKind, TaskTone)` — i.e., which
|
|
296
|
+
* UI renderer (Ambient hairline / Inline badge / Narrated titlebar /
|
|
297
|
+
* Awaiting pulse) surfaces the task. Plugin authors do NOT pick the
|
|
298
|
+
* surface; they just describe what they're doing and why.
|
|
299
|
+
*
|
|
300
|
+
* Preferred over `reportProgress()` for new code. The legacy API stays
|
|
301
|
+
* supported until ADR-015 Phase 3 sweeps all 151 call sites.
|
|
302
|
+
*
|
|
303
|
+
* @example
|
|
304
|
+
* const task = await startTask("Importing 42 articles", {
|
|
305
|
+
* hook: "import",
|
|
306
|
+
* trigger: "onboarding_flow",
|
|
307
|
+
* });
|
|
308
|
+
* for (let i = 0; i < articles.length; i++) {
|
|
309
|
+
* await task.progress(i / articles.length, `Article ${i + 1}/${articles.length}`);
|
|
310
|
+
* await importOne(articles[i]);
|
|
311
|
+
* }
|
|
312
|
+
* await task.succeeded(`Imported ${articles.length} articles`);
|
|
313
|
+
*/
|
|
314
|
+
declare function startTask(label: string, options?: StartTaskOptions): Promise<TaskHandle>;
|
|
315
|
+
//#endregion
|
|
23
316
|
//#region src/types/context.d.ts
|
|
24
|
-
|
|
25
317
|
/**
|
|
26
318
|
* Base context shared by all hooks
|
|
27
319
|
*
|
|
@@ -35,8 +327,15 @@ interface BaseContext {
|
|
|
35
327
|
}
|
|
36
328
|
/**
|
|
37
329
|
* Context for before_build hook (process capability)
|
|
330
|
+
*
|
|
331
|
+
* `trigger` is stamped by moss (ADR-015): the plugin reads it to declare task
|
|
332
|
+
* intent via `startTask`, it does NOT guess it. Onboarding card → "onboarding_flow"
|
|
333
|
+
* (drives the ambient hairline); every build/preview rebuild → "background".
|
|
334
|
+
* Optional for backward compatibility; absent ⇒ treat as "background".
|
|
38
335
|
*/
|
|
39
|
-
interface
|
|
336
|
+
interface ProcessContext extends BaseContext {
|
|
337
|
+
trigger?: TriggerContext;
|
|
338
|
+
}
|
|
40
339
|
/**
|
|
41
340
|
* A node in the universal Page Tree.
|
|
42
341
|
*
|
|
@@ -68,10 +367,8 @@ interface PageNode {
|
|
|
68
367
|
nav: boolean;
|
|
69
368
|
/** Navigation ordering (lower = first) */
|
|
70
369
|
nav_weight?: number;
|
|
71
|
-
/**
|
|
370
|
+
/** Whether this page is a draft — rendered and published at its direct URL but hidden from listings, feeds, and navigation. */
|
|
72
371
|
draft: boolean;
|
|
73
|
-
/** Generate page but hide from parent's child list */
|
|
74
|
-
unlisted: boolean;
|
|
75
372
|
/** Recursively list all nested content */
|
|
76
373
|
flatten: boolean;
|
|
77
374
|
/** How children display: "list", "grid", or "sidebar" */
|
|
@@ -84,7 +381,7 @@ interface PageNode {
|
|
|
84
381
|
/**
|
|
85
382
|
* Context for on_build hook (generator plugins)
|
|
86
383
|
*/
|
|
87
|
-
interface
|
|
384
|
+
interface GenerateContext extends BaseContext {
|
|
88
385
|
source_files: SourceFiles;
|
|
89
386
|
/** Resolved Page Tree — universal content model for all generators */
|
|
90
387
|
page_tree?: PageNode;
|
|
@@ -92,13 +389,45 @@ interface OnBuildContext extends BaseContext {
|
|
|
92
389
|
/**
|
|
93
390
|
* Context for on_deploy hook (deployer plugins)
|
|
94
391
|
*/
|
|
95
|
-
interface
|
|
392
|
+
interface DeployContext extends BaseContext {
|
|
96
393
|
site_files: string[];
|
|
394
|
+
/** Custom domain from .moss/config.toml [deployment] section (if configured) */
|
|
395
|
+
domain?: string;
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Context for configure_domain hook (custom domain setup on deploy platform)
|
|
399
|
+
*
|
|
400
|
+
* Called after DNS records are configured via moss-oracle. Allows deploy plugins
|
|
401
|
+
* to perform platform-specific domain setup (e.g., GitHub Pages CNAME configuration).
|
|
402
|
+
*
|
|
403
|
+
* This is NOT a separate capability - it's an optional hook on Deploy-capable plugins.
|
|
404
|
+
*
|
|
405
|
+
* ## Idempotency Contract
|
|
406
|
+
*
|
|
407
|
+
* The domain orchestrator calls this hook at multiple lifecycle points:
|
|
408
|
+
* 1. After DNS records are configured (site may not be live yet)
|
|
409
|
+
* 2. After the site is verified live via HTTP 200
|
|
410
|
+
*
|
|
411
|
+
* **Plugins MUST implement this hook as idempotent.** The plugin should:
|
|
412
|
+
* - Check current platform state
|
|
413
|
+
* - Do only the next needed step
|
|
414
|
+
* - Return success as a no-op if already fully configured
|
|
415
|
+
*
|
|
416
|
+
* Example (GitHub Pages):
|
|
417
|
+
* - Call 1: Sets CNAME file via API
|
|
418
|
+
* - Call 2: Verifies CNAME is set, enforces HTTPS via API
|
|
419
|
+
* - Call 3+: Both already done, returns success without changes
|
|
420
|
+
*/
|
|
421
|
+
interface ConfigureDomainContext extends BaseContext {
|
|
422
|
+
/** The custom domain being configured (e.g., "example.com") */
|
|
423
|
+
domain: string;
|
|
424
|
+
/** Deployment information from the last deploy */
|
|
425
|
+
deployment: DeploymentInfo;
|
|
97
426
|
}
|
|
98
427
|
/**
|
|
99
428
|
* Context for after_deploy hook (syndicator plugins)
|
|
100
429
|
*/
|
|
101
|
-
interface
|
|
430
|
+
interface SyndicateContext extends BaseContext {
|
|
102
431
|
site_files: string[];
|
|
103
432
|
articles: ArticleInfo[];
|
|
104
433
|
deployment?: DeploymentInfo;
|
|
@@ -154,7 +483,7 @@ interface DnsRecord {
|
|
|
154
483
|
* DNS configuration provided by deploy plugins
|
|
155
484
|
*
|
|
156
485
|
* Plugins are responsible for generating the appropriate DNS records
|
|
157
|
-
* for their platform.
|
|
486
|
+
* for their platform. moss just passes these through to DNS configuration.
|
|
158
487
|
*/
|
|
159
488
|
interface DnsTarget {
|
|
160
489
|
/** List of DNS records to configure */
|
|
@@ -194,37 +523,66 @@ interface HookResult {
|
|
|
194
523
|
deployment?: DeploymentInfo;
|
|
195
524
|
}
|
|
196
525
|
//#endregion
|
|
197
|
-
//#region src/types/
|
|
526
|
+
//#region src/types/enhance.d.ts
|
|
198
527
|
/**
|
|
199
|
-
*
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
*
|
|
528
|
+
* Types for the content slots system.
|
|
529
|
+
*
|
|
530
|
+
* Plugins declare what content to inject and where using these types.
|
|
531
|
+
* Rust handles insertion during template rendering.
|
|
203
532
|
*/
|
|
204
|
-
|
|
205
|
-
interface
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
533
|
+
/** Context passed to a plugin's `enhance()` method. */
|
|
534
|
+
interface EnhanceContext {
|
|
535
|
+
project_path: string;
|
|
536
|
+
moss_dir: string;
|
|
537
|
+
output_dir: string;
|
|
538
|
+
config: Record<string, unknown>;
|
|
539
|
+
project_info: {
|
|
540
|
+
site_name: string;
|
|
541
|
+
lang: string;
|
|
542
|
+
};
|
|
543
|
+
article_map: Record<string, unknown>;
|
|
209
544
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
545
|
+
/** Content declaration for a single slot. */
|
|
546
|
+
type EnhanceContent = {
|
|
547
|
+
type: "static";
|
|
548
|
+
html: string;
|
|
549
|
+
} | {
|
|
550
|
+
type: "per-page";
|
|
551
|
+
pages: Record<string, string>;
|
|
552
|
+
};
|
|
553
|
+
/** Result returned from a plugin's `enhance()` call. */
|
|
554
|
+
interface EnhanceResult {
|
|
555
|
+
success: boolean;
|
|
556
|
+
slots: Record<string, EnhanceContent>;
|
|
216
557
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
558
|
+
//#endregion
|
|
559
|
+
//#region src/types/social.d.ts
|
|
560
|
+
/** One comment in the .moss/data/social/*.json shared standard.
|
|
561
|
+
* See moss/docs/architecture/social-data-standard.md. */
|
|
562
|
+
interface SocialComment {
|
|
563
|
+
id: string;
|
|
564
|
+
source: string;
|
|
565
|
+
content: string;
|
|
566
|
+
createdAt: string;
|
|
567
|
+
author: {
|
|
568
|
+
displayName: string;
|
|
569
|
+
url?: string;
|
|
570
|
+
};
|
|
571
|
+
replyToId?: string;
|
|
572
|
+
/**
|
|
573
|
+
* Moderation state. Absent or "active" = visible; anything else is filtered
|
|
574
|
+
* at read time. Well-known values: "active" | "removed" | "archived" |
|
|
575
|
+
* "banned" | "collapsed". The Rust side treats this as an open string so
|
|
576
|
+
* future states do not require a client update.
|
|
577
|
+
*/
|
|
578
|
+
state?: string;
|
|
222
579
|
}
|
|
223
|
-
interface
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
580
|
+
interface SocialArticleData {
|
|
581
|
+
comments: SocialComment[];
|
|
582
|
+
}
|
|
583
|
+
interface SocialDataFile {
|
|
584
|
+
schemaVersion: string;
|
|
585
|
+
articles: Record<string, SocialArticleData>;
|
|
228
586
|
}
|
|
229
587
|
//#endregion
|
|
230
588
|
//#region src/utils/tauri.d.ts
|
|
@@ -251,81 +609,37 @@ declare function getTauriCore(): TauriCore;
|
|
|
251
609
|
*/
|
|
252
610
|
declare function isTauriAvailable(): boolean;
|
|
253
611
|
//#endregion
|
|
254
|
-
//#region src/utils/
|
|
255
|
-
/**
|
|
256
|
-
* Set the message context for subsequent messages
|
|
257
|
-
* This is typically called automatically by the plugin runtime
|
|
258
|
-
*/
|
|
259
|
-
declare function setMessageContext(pluginName: string, hookName: string): void;
|
|
260
|
-
/**
|
|
261
|
-
* Get the current message context
|
|
262
|
-
*/
|
|
263
|
-
declare function getMessageContext(): {
|
|
264
|
-
pluginName: string;
|
|
265
|
-
hookName: string;
|
|
266
|
-
};
|
|
267
|
-
/**
|
|
268
|
-
* Send a message to Moss
|
|
269
|
-
*
|
|
270
|
-
* Log and progress messages use events (fire-and-forget) to avoid blocking IPC.
|
|
271
|
-
* Complete and error messages use commands (request-response) for acknowledgment.
|
|
272
|
-
*/
|
|
273
|
-
declare function sendMessage(message: PluginMessage): Promise<void>;
|
|
274
|
-
/**
|
|
275
|
-
* Report progress to Moss
|
|
276
|
-
*/
|
|
277
|
-
declare function reportProgress(phase: string, current: number, total: number, message?: string): Promise<void>;
|
|
278
|
-
/**
|
|
279
|
-
* Report an error to Moss
|
|
280
|
-
*/
|
|
281
|
-
declare function reportError(error: string, context?: string, fatal?: boolean): Promise<void>;
|
|
282
|
-
/**
|
|
283
|
-
* Report completion to Moss
|
|
284
|
-
* @param success - Whether the operation succeeded
|
|
285
|
-
* @param result - Optional result data
|
|
286
|
-
* @param error - Optional error message (only used when success is false)
|
|
287
|
-
*/
|
|
288
|
-
declare function reportComplete(success: boolean, result?: unknown, error?: string): Promise<void>;
|
|
289
|
-
//#endregion
|
|
290
|
-
//#region src/utils/logger.d.ts
|
|
612
|
+
//#region src/utils/env.d.ts
|
|
291
613
|
/**
|
|
292
|
-
*
|
|
293
|
-
*
|
|
294
|
-
* @deprecated All functions in this module are deprecated.
|
|
295
|
-
* Use console.log/warn/error directly instead.
|
|
614
|
+
* Plugin-side env-var access.
|
|
296
615
|
*
|
|
297
|
-
*
|
|
298
|
-
*
|
|
299
|
-
*
|
|
616
|
+
* Plugins run inside a webview (no Node `process.env`), so reading host
|
|
617
|
+
* environment variables requires a Rust→TS bridge. The
|
|
618
|
+
* `get_plugin_env_var` Tauri command in `src-tauri/src/plugins/runtime.rs`
|
|
619
|
+
* enforces a server-side allow-list — plugins cannot read arbitrary
|
|
620
|
+
* environment variables, only the ones moss has whitelisted for test /
|
|
621
|
+
* harness use.
|
|
300
622
|
*
|
|
301
|
-
*
|
|
302
|
-
*
|
|
303
|
-
*
|
|
623
|
+
* Currently allow-listed (see runtime.rs `ALLOWED` constant):
|
|
624
|
+
* - `MOSS_MATTERS_TEST_PROFILE` — bypasses Matters auth and switches to
|
|
625
|
+
* public-fetch mode for the named profile (T8a e2e harness).
|
|
626
|
+
* - `MOSS_MATTERS_DOMAIN` — overrides the Matters domain (e.g. "matters.icu")
|
|
627
|
+
* so moss-claude.sh can target the test env without pre-seeding config.json.
|
|
304
628
|
*
|
|
305
|
-
*
|
|
306
|
-
* console.log("Starting deployment...");
|
|
629
|
+
* New entries require an explicit Rust-side edit + code review.
|
|
307
630
|
*/
|
|
308
631
|
/**
|
|
309
|
-
*
|
|
632
|
+
* Read a host environment variable into the plugin webview.
|
|
310
633
|
*
|
|
311
|
-
*
|
|
312
|
-
*
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* Log a warning message
|
|
317
|
-
*
|
|
318
|
-
* @deprecated Use console.warn() directly instead.
|
|
319
|
-
* Plugin runtime auto-forwards all console.* calls to Rust.
|
|
320
|
-
*/
|
|
321
|
-
declare function warn(message: string): Promise<void>;
|
|
322
|
-
/**
|
|
323
|
-
* Log an error message
|
|
634
|
+
* Returns `undefined` if:
|
|
635
|
+
* - Tauri is unavailable (running outside the moss webview),
|
|
636
|
+
* - the variable is not in the server-side allow-list, or
|
|
637
|
+
* - the variable is not set in the host process.
|
|
324
638
|
*
|
|
325
|
-
*
|
|
326
|
-
*
|
|
639
|
+
* Plugins should treat the return value as best-effort: a missing value
|
|
640
|
+
* is the production default, not an error.
|
|
327
641
|
*/
|
|
328
|
-
declare function
|
|
642
|
+
declare function getPluginEnvVar(name: string): Promise<string | undefined>;
|
|
329
643
|
//#endregion
|
|
330
644
|
//#region src/utils/browser.d.ts
|
|
331
645
|
/**
|
|
@@ -353,7 +667,7 @@ interface BrowserHandle {
|
|
|
353
667
|
closed: Promise<BrowserCloseReason>;
|
|
354
668
|
}
|
|
355
669
|
/**
|
|
356
|
-
* Open a URL in the
|
|
670
|
+
* Open a URL in the action panel
|
|
357
671
|
*
|
|
358
672
|
* Returns a BrowserHandle that can be used to detect when the window is closed.
|
|
359
673
|
*
|
|
@@ -377,9 +691,18 @@ interface BrowserHandle {
|
|
|
377
691
|
*/
|
|
378
692
|
declare function openBrowser(url: string): Promise<BrowserHandle>;
|
|
379
693
|
/**
|
|
380
|
-
* Close the
|
|
694
|
+
* Close the action panel
|
|
381
695
|
*/
|
|
382
696
|
declare function closeBrowser(): Promise<void>;
|
|
697
|
+
/**
|
|
698
|
+
* Ask the app shell to restore the editor in the action panel after a login
|
|
699
|
+
* flow cancel or failure. Clears the onboarding latch and re-mounts the
|
|
700
|
+
* editor (empty-folder onboarding cards) in the action panel slot.
|
|
701
|
+
*
|
|
702
|
+
* Call this after `promptLogin()` returns false on an import (binding /
|
|
703
|
+
* prompt_login) path so the user isn't left with an empty action panel.
|
|
704
|
+
*/
|
|
705
|
+
declare function returnToEditor(): Promise<void>;
|
|
383
706
|
/**
|
|
384
707
|
* Open a URL in the system's default browser
|
|
385
708
|
*
|
|
@@ -395,42 +718,93 @@ declare function closeBrowser(): Promise<void>;
|
|
|
395
718
|
*/
|
|
396
719
|
declare function openSystemBrowser(url: string): Promise<void>;
|
|
397
720
|
/**
|
|
398
|
-
* Open the
|
|
721
|
+
* Open the action panel with dynamic HTML content
|
|
399
722
|
*
|
|
400
723
|
* Automatically injects a bridge script that exposes `window.mossApi` with:
|
|
401
|
-
* - `submit(data)` - emits `moss:browser-form-submit` event
|
|
402
|
-
* - `cancel()` - emits `moss:browser-form-cancel` event
|
|
403
724
|
* - `close()` - closes the browser panel
|
|
404
|
-
* - `emit(name, payload)` -
|
|
725
|
+
* - `emit(name, payload)` - emits custom events for plugin-specific communication
|
|
405
726
|
*
|
|
406
727
|
* Uses a custom protocol (moss-plugin://) to serve HTML content
|
|
407
728
|
* without requiring the `webview-data-url` Cargo feature.
|
|
408
729
|
*
|
|
730
|
+
* **Manual lifecycle control:**
|
|
731
|
+
* After calling this function, the browser panel remains open until you explicitly
|
|
732
|
+
* call `closeBrowser()` or the user closes it. Use `listen()` to handle custom
|
|
733
|
+
* events emitted from the HTML.
|
|
734
|
+
*
|
|
409
735
|
* @param html - Raw HTML content to display
|
|
410
736
|
* @example
|
|
411
737
|
* ```typescript
|
|
738
|
+
* import { openBrowserWithHtml, closeBrowser, listen } from "@symbiosis-lab/moss-api";
|
|
739
|
+
*
|
|
740
|
+
* // Open browser with custom HTML
|
|
412
741
|
* await openBrowserWithHtml(`
|
|
413
742
|
* <!DOCTYPE html>
|
|
414
743
|
* <html>
|
|
415
744
|
* <head><title>My Form</title></head>
|
|
416
745
|
* <body>
|
|
417
|
-
* <form
|
|
418
|
-
* <input name="name" />
|
|
746
|
+
* <form id="myForm">
|
|
747
|
+
* <input id="nameInput" name="name" />
|
|
419
748
|
* <button type="submit">Submit</button>
|
|
420
|
-
* <button type="button" onclick="window.mossApi.
|
|
749
|
+
* <button type="button" onclick="window.mossApi.close()">Cancel</button>
|
|
421
750
|
* </form>
|
|
751
|
+
* <script>
|
|
752
|
+
* document.getElementById('myForm').addEventListener('submit', (e) => {
|
|
753
|
+
* e.preventDefault();
|
|
754
|
+
* window.mossApi.emit('my-plugin:form-submit', {
|
|
755
|
+
* name: document.getElementById('nameInput').value
|
|
756
|
+
* });
|
|
757
|
+
* });
|
|
758
|
+
* </script>
|
|
422
759
|
* </body>
|
|
423
760
|
* </html>
|
|
424
761
|
* `);
|
|
762
|
+
*
|
|
763
|
+
* // Listen for custom event from HTML
|
|
764
|
+
* const unlisten = await listen('my-plugin:form-submit', (event) => {
|
|
765
|
+
* console.log('User submitted:', event.payload);
|
|
766
|
+
* closeBrowser(); // Explicitly close when done
|
|
767
|
+
* });
|
|
425
768
|
* ```
|
|
426
769
|
*/
|
|
427
770
|
declare function openBrowserWithHtml(html: string): Promise<void>;
|
|
428
771
|
/**
|
|
429
772
|
* Show an HTML form in the browser panel and wait for the user to submit or cancel.
|
|
430
773
|
*
|
|
431
|
-
*
|
|
432
|
-
*
|
|
433
|
-
*
|
|
774
|
+
* @deprecated This function couples form lifecycle to moss internals through hidden event listeners.
|
|
775
|
+
* Use `openBrowserWithHtml()` + manual `closeBrowser()` instead for explicit control.
|
|
776
|
+
*
|
|
777
|
+
* **Migration guide:**
|
|
778
|
+
* ```typescript
|
|
779
|
+
* // OLD (deprecated):
|
|
780
|
+
* const result = await showBrowserForm<LoginData>(html);
|
|
781
|
+
* if (result) {
|
|
782
|
+
* console.log("Submitted:", result);
|
|
783
|
+
* }
|
|
784
|
+
*
|
|
785
|
+
* // NEW (recommended):
|
|
786
|
+
* await openBrowserWithHtml(html);
|
|
787
|
+
*
|
|
788
|
+
* // Listen for custom event
|
|
789
|
+
* const unlisten = await listen<LoginData>("my-plugin:submit", (event) => {
|
|
790
|
+
* console.log("Submitted:", event.payload);
|
|
791
|
+
* closeBrowser();
|
|
792
|
+
* });
|
|
793
|
+
*
|
|
794
|
+
* // In your HTML:
|
|
795
|
+
* // <button onclick="window.mossApi.emit('my-plugin:submit', { username: '...' })">Submit</button>
|
|
796
|
+
* // <button onclick="window.mossApi.close()">Cancel</button>
|
|
797
|
+
* ```
|
|
798
|
+
*
|
|
799
|
+
* **Why migrate:**
|
|
800
|
+
* - Explicit browser lifecycle control (no magic auto-close)
|
|
801
|
+
* - No hidden event listeners (`moss:browser-form-submit`, `moss:browser-form-cancel`)
|
|
802
|
+
* - Simpler mental model: open, use, close
|
|
803
|
+
* - Matches modern plugin patterns (see Matters plugin)
|
|
804
|
+
*
|
|
805
|
+
* Note: This deprecated function still listens for `moss:browser-form-submit` and
|
|
806
|
+
* `moss:browser-form-cancel` events for backward compatibility. New code should use
|
|
807
|
+
* `window.mossApi.emit('your-event', data)` and `window.mossApi.close()` instead.
|
|
434
808
|
*
|
|
435
809
|
* Returns the submitted data, or `null` if the user cancelled or the timeout expired.
|
|
436
810
|
* The browser is automatically closed in all cases.
|
|
@@ -438,6 +812,7 @@ declare function openBrowserWithHtml(html: string): Promise<void>;
|
|
|
438
812
|
* @param html - Raw HTML content with a form
|
|
439
813
|
* @param options - Optional configuration
|
|
440
814
|
* @param options.timeoutMs - Maximum time to wait (default: 300000ms / 5 minutes)
|
|
815
|
+
* @param options.closeDelayMs - Optional delay before closing browser (default: 0ms / immediate)
|
|
441
816
|
* @returns The submitted form data, or null on cancel/timeout
|
|
442
817
|
*
|
|
443
818
|
* @example
|
|
@@ -453,12 +828,12 @@ declare function openBrowserWithHtml(html: string): Promise<void>;
|
|
|
453
828
|
* <input id="user" placeholder="Username" />
|
|
454
829
|
* <input id="pass" type="password" placeholder="Password" />
|
|
455
830
|
* <button type="submit">Login</button>
|
|
456
|
-
* <button type="button" onclick="window.mossApi.
|
|
831
|
+
* <button type="button" onclick="window.mossApi.close()">Cancel</button>
|
|
457
832
|
* </form>
|
|
458
833
|
* <script>
|
|
459
834
|
* document.getElementById('login').addEventListener('submit', (e) => {
|
|
460
835
|
* e.preventDefault();
|
|
461
|
-
* window.mossApi.submit
|
|
836
|
+
* window.mossApi.emit('moss:browser-form-submit', {
|
|
462
837
|
* username: document.getElementById('user').value,
|
|
463
838
|
* password: document.getElementById('pass').value,
|
|
464
839
|
* });
|
|
@@ -477,11 +852,12 @@ declare function openBrowserWithHtml(html: string): Promise<void>;
|
|
|
477
852
|
*/
|
|
478
853
|
declare function showBrowserForm<T>(html: string, options?: {
|
|
479
854
|
timeoutMs?: number;
|
|
855
|
+
closeDelayMs?: number;
|
|
480
856
|
}): Promise<T | null>;
|
|
481
857
|
//#endregion
|
|
482
858
|
//#region src/utils/filesystem.d.ts
|
|
483
859
|
/**
|
|
484
|
-
* File system operations for
|
|
860
|
+
* File system operations for moss plugins
|
|
485
861
|
*
|
|
486
862
|
* These functions provide access to project files (user content).
|
|
487
863
|
* Project path is auto-detected from the runtime context.
|
|
@@ -545,6 +921,21 @@ declare function writeFile(relativePath: string, content: string): Promise<void>
|
|
|
545
921
|
* ```
|
|
546
922
|
*/
|
|
547
923
|
declare function listFiles(): Promise<string[]>;
|
|
924
|
+
/** A project file with home-file annotation from Rust's detect_home_file_in_folder */
|
|
925
|
+
interface ProjectFileEntry {
|
|
926
|
+
path: string;
|
|
927
|
+
is_home: boolean;
|
|
928
|
+
}
|
|
929
|
+
/**
|
|
930
|
+
* List all project files with home-file annotations
|
|
931
|
+
*
|
|
932
|
+
* Each file is annotated with `is_home: true` if it's the detected home file
|
|
933
|
+
* for its containing folder (index.md, README.md, self-named folder note, etc.).
|
|
934
|
+
* Detection uses the same logic as the built-in generator.
|
|
935
|
+
*
|
|
936
|
+
* @returns Array of file entries with is_home annotations
|
|
937
|
+
*/
|
|
938
|
+
declare function listProjectTree(): Promise<ProjectFileEntry[]>;
|
|
548
939
|
/**
|
|
549
940
|
* Check if a file exists in the project directory
|
|
550
941
|
*
|
|
@@ -580,10 +971,80 @@ declare function fileExists(relativePath: string): Promise<boolean>;
|
|
|
580
971
|
* ```
|
|
581
972
|
*/
|
|
582
973
|
declare function createSymlink(targetPath: string, linkPath: string): Promise<void>;
|
|
974
|
+
/**
|
|
975
|
+
* Read a file from the compiled site directory (.moss/site/)
|
|
976
|
+
*
|
|
977
|
+
* Returns base64-encoded content. Used by deploy plugins to read
|
|
978
|
+
* site files without direct filesystem access.
|
|
979
|
+
*
|
|
980
|
+
* @param relativePath - Path relative to the site directory (e.g., "index.html")
|
|
981
|
+
* @returns Base64-encoded file content
|
|
982
|
+
* @throws Error if file cannot be read
|
|
983
|
+
*
|
|
984
|
+
* @example
|
|
985
|
+
* ```typescript
|
|
986
|
+
* const base64Content = await readSiteFile("index.html");
|
|
987
|
+
* const base64Image = await readSiteFile("assets/logo.png");
|
|
988
|
+
* ```
|
|
989
|
+
*/
|
|
990
|
+
declare function readSiteFile(relativePath: string): Promise<string>;
|
|
991
|
+
/**
|
|
992
|
+
* Read a file from the project root as base64
|
|
993
|
+
*
|
|
994
|
+
* Returns base64-encoded content. Used by deploy plugins for
|
|
995
|
+
* source file backup operations.
|
|
996
|
+
*
|
|
997
|
+
* @param relativePath - Path relative to the project root
|
|
998
|
+
* @returns Base64-encoded file content
|
|
999
|
+
* @throws Error if file cannot be read
|
|
1000
|
+
*
|
|
1001
|
+
* @example
|
|
1002
|
+
* ```typescript
|
|
1003
|
+
* const base64Content = await readProjectFileBase64("posts/article.md");
|
|
1004
|
+
* ```
|
|
1005
|
+
*/
|
|
1006
|
+
declare function readProjectFileBase64(relativePath: string): Promise<string>;
|
|
1007
|
+
/**
|
|
1008
|
+
* List source files in the project directory
|
|
1009
|
+
*
|
|
1010
|
+
* Returns relative paths of non-hidden files, excluding build artifacts
|
|
1011
|
+
* (.moss/, .git/, node_modules/). Used by deploy plugins for source backup.
|
|
1012
|
+
*
|
|
1013
|
+
* @returns Array of relative file paths
|
|
1014
|
+
* @throws Error if listing fails
|
|
1015
|
+
*
|
|
1016
|
+
* @example
|
|
1017
|
+
* ```typescript
|
|
1018
|
+
* const sourceFiles = await listSourceFiles();
|
|
1019
|
+
* // ["index.md", "posts/hello.md", "assets/logo.png"]
|
|
1020
|
+
* ```
|
|
1021
|
+
*/
|
|
1022
|
+
declare function listSourceFiles(): Promise<string[]>;
|
|
1023
|
+
/**
|
|
1024
|
+
* List social data source names from .moss/data/social/*.json
|
|
1025
|
+
*
|
|
1026
|
+
* Returns file stems (without .json extension) for all JSON files
|
|
1027
|
+
* in the project's .moss/data/social/ directory. Returns empty array
|
|
1028
|
+
* if directory doesn't exist.
|
|
1029
|
+
*
|
|
1030
|
+
* @returns Array of source names (e.g., ["comment", "douban", "matters"])
|
|
1031
|
+
*/
|
|
1032
|
+
declare function listSocialFiles(): Promise<string[]>;
|
|
1033
|
+
/** File path and size from the compiled site directory */
|
|
1034
|
+
interface SiteFileInfo {
|
|
1035
|
+
path: string;
|
|
1036
|
+
size: number;
|
|
1037
|
+
}
|
|
1038
|
+
/**
|
|
1039
|
+
* List all files in the compiled site directory with their sizes
|
|
1040
|
+
*
|
|
1041
|
+
* @returns Array of file info objects with path and size in bytes
|
|
1042
|
+
*/
|
|
1043
|
+
declare function listSiteFilesWithSizes(): Promise<SiteFileInfo[]>;
|
|
583
1044
|
//#endregion
|
|
584
1045
|
//#region src/utils/plugin-storage.d.ts
|
|
585
1046
|
/**
|
|
586
|
-
* Plugin storage API for
|
|
1047
|
+
* Plugin storage API for moss plugins
|
|
587
1048
|
*
|
|
588
1049
|
* Provides access to a plugin's private storage directory at:
|
|
589
1050
|
* .moss/plugins/{plugin-name}/
|
|
@@ -668,7 +1129,7 @@ declare function pluginFileExists(relativePath: string): Promise<boolean>;
|
|
|
668
1129
|
//#endregion
|
|
669
1130
|
//#region src/utils/http.d.ts
|
|
670
1131
|
/**
|
|
671
|
-
* HTTP operations for
|
|
1132
|
+
* HTTP operations for moss plugins
|
|
672
1133
|
*
|
|
673
1134
|
* These functions provide HTTP capabilities that bypass browser CORS
|
|
674
1135
|
* restrictions by using Rust's HTTP client under the hood.
|
|
@@ -770,6 +1231,14 @@ interface PostOptions {
|
|
|
770
1231
|
* }
|
|
771
1232
|
* ```
|
|
772
1233
|
*/
|
|
1234
|
+
/**
|
|
1235
|
+
* Convert an HTML fragment to Markdown via moss's bundled `htmd` converter —
|
|
1236
|
+
* the same converter the rest of the app uses. Plugins call this instead of
|
|
1237
|
+
* shipping their own HTML→Markdown pass, so output (notably hard breaks, which
|
|
1238
|
+
* htmd renders as two trailing spaces rather than a lone backslash) is
|
|
1239
|
+
* consistent app-wide. Returns the input HTML unchanged if conversion fails.
|
|
1240
|
+
*/
|
|
1241
|
+
declare function htmlToMarkdown(html: string): Promise<string>;
|
|
773
1242
|
declare function httpPost(url: string, body: Record<string, unknown>, options?: PostOptions): Promise<FetchResult>;
|
|
774
1243
|
/**
|
|
775
1244
|
* Options for HTTP GET requests
|
|
@@ -804,6 +1273,65 @@ interface GetOptions {
|
|
|
804
1273
|
* ```
|
|
805
1274
|
*/
|
|
806
1275
|
declare function httpGet(url: string, options?: GetOptions): Promise<FetchResult>;
|
|
1276
|
+
/**
|
|
1277
|
+
* One ordered text field in a multipart/form-data POST.
|
|
1278
|
+
*
|
|
1279
|
+
* Order is preserved because the GraphQL multipart request spec requires
|
|
1280
|
+
* `operations` before `map` before the file parts.
|
|
1281
|
+
*/
|
|
1282
|
+
interface MultipartTextField {
|
|
1283
|
+
/** Form field name (e.g. "operations", "map"). */
|
|
1284
|
+
name: string;
|
|
1285
|
+
/** Field value (e.g. the JSON-encoded GraphQL operation). */
|
|
1286
|
+
value: string;
|
|
1287
|
+
}
|
|
1288
|
+
/**
|
|
1289
|
+
* One file part in a multipart/form-data POST. Bytes are passed base64-encoded —
|
|
1290
|
+
* e.g. straight from `readSiteFile`, which already returns base64.
|
|
1291
|
+
*/
|
|
1292
|
+
interface MultipartFilePart {
|
|
1293
|
+
/** Form field name for this file (e.g. "0" per the GraphQL multipart spec). */
|
|
1294
|
+
field: string;
|
|
1295
|
+
/** File name reported in the part's Content-Disposition. */
|
|
1296
|
+
filename: string;
|
|
1297
|
+
/** MIME type for the part's Content-Type header. */
|
|
1298
|
+
contentType: string;
|
|
1299
|
+
/** File contents, base64-encoded. */
|
|
1300
|
+
contentBase64: string;
|
|
1301
|
+
}
|
|
1302
|
+
/**
|
|
1303
|
+
* Options for a multipart POST request.
|
|
1304
|
+
*/
|
|
1305
|
+
interface MultipartPostOptions {
|
|
1306
|
+
/** Timeout in milliseconds (default: 30000) */
|
|
1307
|
+
timeoutMs?: number;
|
|
1308
|
+
/** Additional headers (Content-Type is set automatically and cannot be overridden) */
|
|
1309
|
+
headers?: Record<string, string>;
|
|
1310
|
+
}
|
|
1311
|
+
/**
|
|
1312
|
+
* Perform an HTTP POST with a `multipart/form-data` body.
|
|
1313
|
+
*
|
|
1314
|
+
* Unlike {@link httpPost} (JSON-only), this sends ordered text fields plus
|
|
1315
|
+
* binary file parts — enabling uploads to GraphQL `singleFileUpload`-style
|
|
1316
|
+
* endpoints. File bytes are passed base64-encoded (so they survive the IPC
|
|
1317
|
+
* boundary and can come directly from {@link readSiteFile}); moss builds the
|
|
1318
|
+
* multipart body, generates the boundary, and sets the Content-Type.
|
|
1319
|
+
*
|
|
1320
|
+
* @example
|
|
1321
|
+
* ```typescript
|
|
1322
|
+
* const res = await httpPostMultipart(endpoint, {
|
|
1323
|
+
* textFields: [
|
|
1324
|
+
* { name: "operations", value: JSON.stringify({ query, variables }) },
|
|
1325
|
+
* { name: "map", value: JSON.stringify({ "0": ["variables.input.file"] }) },
|
|
1326
|
+
* ],
|
|
1327
|
+
* files: [{ field: "0", filename: "photo.jpg", contentType: "image/jpeg", contentBase64 }],
|
|
1328
|
+
* }, { headers: { "x-access-token": token } });
|
|
1329
|
+
* ```
|
|
1330
|
+
*/
|
|
1331
|
+
declare function httpPostMultipart(url: string, parts: {
|
|
1332
|
+
textFields?: MultipartTextField[];
|
|
1333
|
+
files?: MultipartFilePart[];
|
|
1334
|
+
}, options?: MultipartPostOptions): Promise<FetchResult>;
|
|
807
1335
|
/**
|
|
808
1336
|
* Download a URL and save directly to disk
|
|
809
1337
|
*
|
|
@@ -834,7 +1362,7 @@ declare function downloadAsset(url: string, targetDir: string, options?: Downloa
|
|
|
834
1362
|
//#endregion
|
|
835
1363
|
//#region src/utils/binary.d.ts
|
|
836
1364
|
/**
|
|
837
|
-
* Binary execution for
|
|
1365
|
+
* Binary execution for moss plugins
|
|
838
1366
|
*
|
|
839
1367
|
* Allows plugins to execute external binaries (git, npm, etc.)
|
|
840
1368
|
* in a controlled environment.
|
|
@@ -856,6 +1384,15 @@ interface ExecuteOptions {
|
|
|
856
1384
|
env?: Record<string, string>;
|
|
857
1385
|
/** Data to pass to stdin (useful for commands like `git credential fill`) */
|
|
858
1386
|
stdin?: string;
|
|
1387
|
+
/** Working directory relative to project root (default: project root itself) */
|
|
1388
|
+
workingDir?: string;
|
|
1389
|
+
/**
|
|
1390
|
+
* Callback for real-time stderr output. When provided, stderr lines are
|
|
1391
|
+
* streamed from the Rust backend via Tauri events as they are produced.
|
|
1392
|
+
* Useful for long-running processes like `git push` where you want to
|
|
1393
|
+
* show progress to the user.
|
|
1394
|
+
*/
|
|
1395
|
+
onStderr?: (line: string) => void;
|
|
859
1396
|
}
|
|
860
1397
|
/**
|
|
861
1398
|
* Result from binary execution
|
|
@@ -910,7 +1447,7 @@ declare function executeBinary(options: ExecuteOptions): Promise<ExecuteResult>;
|
|
|
910
1447
|
//#endregion
|
|
911
1448
|
//#region src/utils/platform.d.ts
|
|
912
1449
|
/**
|
|
913
|
-
* Platform detection utilities for
|
|
1450
|
+
* Platform detection utilities for moss plugins
|
|
914
1451
|
*
|
|
915
1452
|
* Detects the current operating system and architecture to enable
|
|
916
1453
|
* platform-specific binary downloads and operations.
|
|
@@ -966,143 +1503,110 @@ declare function getPlatformInfo(): Promise<PlatformInfo>;
|
|
|
966
1503
|
*/
|
|
967
1504
|
declare function clearPlatformCache(): void;
|
|
968
1505
|
//#endregion
|
|
969
|
-
//#region src/utils/
|
|
970
|
-
/**
|
|
971
|
-
* Archive extraction utilities for Moss plugins
|
|
972
|
-
*
|
|
973
|
-
* Provides functions to extract .tar.gz and .zip archives using
|
|
974
|
-
* system commands (tar, unzip, PowerShell).
|
|
975
|
-
*/
|
|
976
|
-
/**
|
|
977
|
-
* Supported archive formats
|
|
978
|
-
*/
|
|
979
|
-
type ArchiveFormat = "tar.gz" | "zip";
|
|
980
|
-
/**
|
|
981
|
-
* Options for archive extraction
|
|
982
|
-
*/
|
|
983
|
-
interface ExtractOptions {
|
|
984
|
-
/** Path to the archive file (absolute) */
|
|
985
|
-
archivePath: string;
|
|
986
|
-
/** Directory to extract to (absolute) */
|
|
987
|
-
destDir: string;
|
|
988
|
-
/** Archive format (auto-detected from extension if not provided) */
|
|
989
|
-
format?: ArchiveFormat;
|
|
990
|
-
/** Timeout in milliseconds (default: 60000) */
|
|
991
|
-
timeoutMs?: number;
|
|
992
|
-
}
|
|
993
|
-
/**
|
|
994
|
-
* Result of archive extraction
|
|
995
|
-
*/
|
|
996
|
-
interface ExtractResult {
|
|
997
|
-
/** Whether extraction succeeded */
|
|
998
|
-
success: boolean;
|
|
999
|
-
/** Error message if extraction failed */
|
|
1000
|
-
error?: string;
|
|
1001
|
-
}
|
|
1506
|
+
//#region src/utils/binary-resolver.d.ts
|
|
1002
1507
|
/**
|
|
1003
|
-
*
|
|
1004
|
-
*
|
|
1005
|
-
* Uses system commands for extraction:
|
|
1006
|
-
* - .tar.gz: `tar -xzf` (macOS/Linux)
|
|
1007
|
-
* - .zip: `unzip` (macOS/Linux) or PowerShell `Expand-Archive` (Windows)
|
|
1008
|
-
*
|
|
1009
|
-
* @param options - Extraction options
|
|
1010
|
-
* @returns Extraction result
|
|
1508
|
+
* Binary resolver for moss plugins
|
|
1011
1509
|
*
|
|
1012
|
-
*
|
|
1013
|
-
*
|
|
1014
|
-
* const result = await extractArchive({
|
|
1015
|
-
* archivePath: "/path/to/hugo.tar.gz",
|
|
1016
|
-
* destDir: "/path/to/extract/",
|
|
1017
|
-
* });
|
|
1510
|
+
* Thin wrapper around the Rust-side unified binary resolver exposed via Tauri command.
|
|
1511
|
+
* All resolution logic (PATH lookup, cache check, download, extraction) happens in Rust.
|
|
1018
1512
|
*
|
|
1019
|
-
*
|
|
1020
|
-
* console.error(`Extraction failed: ${result.error}`);
|
|
1021
|
-
* }
|
|
1022
|
-
* ```
|
|
1513
|
+
* TypeScript types here mirror the Rust serde shapes from binary_resolver.rs.
|
|
1023
1514
|
*/
|
|
1024
|
-
declare function extractArchive(options: ExtractOptions): Promise<ExtractResult>;
|
|
1025
1515
|
/**
|
|
1026
|
-
*
|
|
1027
|
-
*
|
|
1028
|
-
* Runs `chmod +x` on the specified file. No-op on Windows.
|
|
1029
|
-
*
|
|
1030
|
-
* @param filePath - Absolute path to the file
|
|
1031
|
-
* @returns Whether the operation succeeded
|
|
1032
|
-
*
|
|
1033
|
-
* @example
|
|
1034
|
-
* ```typescript
|
|
1035
|
-
* await makeExecutable("/path/to/binary");
|
|
1036
|
-
* ```
|
|
1037
|
-
*/
|
|
1038
|
-
declare function makeExecutable(filePath: string): Promise<boolean>;
|
|
1039
|
-
//#endregion
|
|
1040
|
-
//#region src/utils/binary-resolver.d.ts
|
|
1041
|
-
/**
|
|
1042
|
-
* GitHub source configuration for binary downloads
|
|
1516
|
+
* GitHub Releases download source.
|
|
1043
1517
|
*/
|
|
1044
1518
|
interface GitHubSource {
|
|
1045
1519
|
/** Repository owner (e.g., "gohugoio") */
|
|
1046
1520
|
owner: string;
|
|
1047
1521
|
/** Repository name (e.g., "hugo") */
|
|
1048
1522
|
repo: string;
|
|
1049
|
-
/**
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
* - {arch}: Architecture (arm64, amd64, x64)
|
|
1054
|
-
*
|
|
1055
|
-
* Example: "hugo_extended_{version}_{os}-{arch}.tar.gz"
|
|
1056
|
-
*/
|
|
1057
|
-
assetPattern: string;
|
|
1523
|
+
/** Asset filename pattern with placeholders: {version}, {os}, {arch} */
|
|
1524
|
+
asset_pattern: string;
|
|
1525
|
+
/** Specific release tag (e.g., "v0.123.0"). If null, fetches "latest". */
|
|
1526
|
+
tag?: string | null;
|
|
1058
1527
|
}
|
|
1059
1528
|
/**
|
|
1060
|
-
*
|
|
1529
|
+
* Archive format for downloaded binaries.
|
|
1530
|
+
*/
|
|
1531
|
+
type ArchiveFormat = "tar_gz" | "zip" | "raw";
|
|
1532
|
+
/**
|
|
1533
|
+
* Platform-specific download source for a binary.
|
|
1061
1534
|
*/
|
|
1062
1535
|
interface BinarySource {
|
|
1063
|
-
/**
|
|
1064
|
-
github?: GitHubSource;
|
|
1065
|
-
/**
|
|
1066
|
-
|
|
1536
|
+
/** Fetch a release asset via the GitHub Releases API. */
|
|
1537
|
+
github?: GitHubSource | null;
|
|
1538
|
+
/** A pinned URL to download from directly (no API call needed). */
|
|
1539
|
+
direct_url?: string | null;
|
|
1540
|
+
/** Expected SHA-256 checksum of the downloaded file (hex string). */
|
|
1541
|
+
sha256?: string | null;
|
|
1542
|
+
/** Archive format of the downloaded file. */
|
|
1543
|
+
archive_format?: ArchiveFormat | null;
|
|
1544
|
+
}
|
|
1545
|
+
/**
|
|
1546
|
+
* How to verify a binary works and extract its version.
|
|
1547
|
+
*/
|
|
1548
|
+
interface VersionCheck {
|
|
1549
|
+
/** Arguments to pass (e.g., ["--version"]) */
|
|
1550
|
+
args: string[];
|
|
1551
|
+
/** Regex pattern with one capture group to extract the version string. */
|
|
1552
|
+
pattern?: string | null;
|
|
1067
1553
|
}
|
|
1068
1554
|
/**
|
|
1069
|
-
*
|
|
1555
|
+
* Describes the internal layout of an archive for complex distributions.
|
|
1556
|
+
*/
|
|
1557
|
+
interface ArchiveLayout {
|
|
1558
|
+
/** Path to the main binary inside the archive (e.g., "bin/git"). */
|
|
1559
|
+
binary_path: string;
|
|
1560
|
+
/** Directories where all files need chmod +x after extraction. */
|
|
1561
|
+
executable_dirs: string[];
|
|
1562
|
+
}
|
|
1563
|
+
/**
|
|
1564
|
+
* Configuration for a binary that can be resolved, cached, and downloaded.
|
|
1565
|
+
*
|
|
1566
|
+
* Platform-specific sources are keyed by platform string
|
|
1567
|
+
* (e.g., "darwin-arm64", "darwin-x64", "linux-x64", "windows-x64").
|
|
1070
1568
|
*/
|
|
1071
1569
|
interface BinaryConfig {
|
|
1072
|
-
/**
|
|
1570
|
+
/** Human-readable name (e.g., "hugo", "ffmpeg", "git") */
|
|
1073
1571
|
name: string;
|
|
1074
|
-
/**
|
|
1075
|
-
|
|
1076
|
-
/**
|
|
1077
|
-
|
|
1078
|
-
/**
|
|
1079
|
-
|
|
1080
|
-
/**
|
|
1081
|
-
|
|
1082
|
-
/**
|
|
1083
|
-
|
|
1572
|
+
/** Filename of the binary if different from name. */
|
|
1573
|
+
binary_name?: string | null;
|
|
1574
|
+
/** How to verify the binary works and extract its version string. */
|
|
1575
|
+
version_check?: VersionCheck | null;
|
|
1576
|
+
/** Platform-specific download sources, keyed by platform string. */
|
|
1577
|
+
sources: Record<string, BinarySource>;
|
|
1578
|
+
/** For complex archives where the binary is nested inside the archive. */
|
|
1579
|
+
archive_layout?: ArchiveLayout | null;
|
|
1580
|
+
/** Subdirectory under ~/.moss/bin/ for caching. */
|
|
1581
|
+
cache_dir?: string | null;
|
|
1582
|
+
/** Minimum disk space required (in bytes) before attempting a download. */
|
|
1583
|
+
required_disk_space?: number | null;
|
|
1084
1584
|
}
|
|
1085
1585
|
/**
|
|
1086
|
-
*
|
|
1586
|
+
* How the binary was found during resolution.
|
|
1587
|
+
*/
|
|
1588
|
+
type ResolutionSource = "configured_path" | "system_path" | "cache" | "downloaded";
|
|
1589
|
+
/**
|
|
1590
|
+
* The result of successfully resolving a binary.
|
|
1087
1591
|
*/
|
|
1088
1592
|
interface BinaryResolution {
|
|
1089
|
-
/** Absolute path to the binary */
|
|
1593
|
+
/** Absolute path to the binary (or just the name if found in system PATH). */
|
|
1090
1594
|
path: string;
|
|
1091
|
-
/**
|
|
1092
|
-
version?: string;
|
|
1093
|
-
/** How the binary was found */
|
|
1094
|
-
source:
|
|
1595
|
+
/** Version string extracted from the binary output, if available. */
|
|
1596
|
+
version?: string | null;
|
|
1597
|
+
/** How the binary was found. */
|
|
1598
|
+
source: ResolutionSource;
|
|
1095
1599
|
}
|
|
1096
1600
|
/**
|
|
1097
1601
|
* Options for binary resolution
|
|
1098
1602
|
*/
|
|
1099
1603
|
interface ResolveBinaryOptions {
|
|
1100
|
-
/**
|
|
1604
|
+
/** User-configured binary path to check first. */
|
|
1101
1605
|
configuredPath?: string;
|
|
1102
|
-
/** Whether to auto-download if not found (default: true) */
|
|
1606
|
+
/** Whether to auto-download if not found (default: true). */
|
|
1103
1607
|
autoDownload?: boolean;
|
|
1104
|
-
/** Progress callback for UI feedback */
|
|
1105
|
-
onProgress?: (
|
|
1608
|
+
/** Progress callback for download UI feedback. */
|
|
1609
|
+
onProgress?: (binary: string, bytesDownloaded: number, totalBytes?: number) => void;
|
|
1106
1610
|
}
|
|
1107
1611
|
/**
|
|
1108
1612
|
* Error thrown during binary resolution
|
|
@@ -1113,37 +1617,43 @@ declare class BinaryResolutionError extends Error {
|
|
|
1113
1617
|
constructor(message: string, phase: "detection" | "download" | "extraction" | "validation", cause?: Error | undefined);
|
|
1114
1618
|
}
|
|
1115
1619
|
/**
|
|
1116
|
-
* Resolve a binary
|
|
1620
|
+
* Resolve a binary by invoking the Rust-side unified resolver via Tauri command.
|
|
1117
1621
|
*
|
|
1118
|
-
* Resolution order:
|
|
1119
|
-
* 1.
|
|
1120
|
-
* 2.
|
|
1121
|
-
* 3.
|
|
1122
|
-
* 4. Download from
|
|
1622
|
+
* Resolution order (handled in Rust):
|
|
1623
|
+
* 1. Check configured path (if provided)
|
|
1624
|
+
* 2. Check system PATH
|
|
1625
|
+
* 3. Check ~/.moss/bin/ cache
|
|
1626
|
+
* 4. Download from configured source (if autoDownload is true)
|
|
1123
1627
|
*
|
|
1124
|
-
* @param config - Binary configuration
|
|
1125
|
-
* @param options - Resolution options
|
|
1126
|
-
* @returns Resolution result with path and source
|
|
1628
|
+
* @param config - Binary configuration matching the Rust BinaryConfig shape
|
|
1629
|
+
* @param options - Resolution options (configured path, auto-download, progress callback)
|
|
1630
|
+
* @returns Resolution result with path, version, and source
|
|
1127
1631
|
* @throws BinaryResolutionError if binary cannot be resolved
|
|
1128
1632
|
*
|
|
1129
1633
|
* @example
|
|
1130
1634
|
* ```typescript
|
|
1131
|
-
* const
|
|
1635
|
+
* const resolution = await resolveBinary({
|
|
1636
|
+
* name: "hugo",
|
|
1637
|
+
* version_check: { args: ["version"], pattern: "v(\\d+\\.\\d+\\.\\d+)" },
|
|
1638
|
+
* sources: {
|
|
1639
|
+
* "darwin-arm64": {
|
|
1640
|
+
* github: { owner: "gohugoio", repo: "hugo", asset_pattern: "hugo_extended_{version}_darwin-arm64.tar.gz" },
|
|
1641
|
+
* archive_format: "tar_gz",
|
|
1642
|
+
* },
|
|
1643
|
+
* },
|
|
1644
|
+
* }, {
|
|
1132
1645
|
* configuredPath: context.config.hugo_path,
|
|
1133
|
-
* onProgress: (
|
|
1646
|
+
* onProgress: (binary, bytes, total) => console.log(`${binary}: ${bytes}/${total}`),
|
|
1134
1647
|
* });
|
|
1135
1648
|
*
|
|
1136
|
-
* await executeBinary({
|
|
1137
|
-
* binaryPath: hugo.path,
|
|
1138
|
-
* args: ["--version"],
|
|
1139
|
-
* });
|
|
1649
|
+
* await executeBinary({ binaryPath: resolution.path, args: ["--version"] });
|
|
1140
1650
|
* ```
|
|
1141
1651
|
*/
|
|
1142
1652
|
declare function resolveBinary(config: BinaryConfig, options?: ResolveBinaryOptions): Promise<BinaryResolution>;
|
|
1143
1653
|
//#endregion
|
|
1144
1654
|
//#region src/utils/cookies.d.ts
|
|
1145
1655
|
/**
|
|
1146
|
-
* Cookie management for
|
|
1656
|
+
* Cookie management for moss plugins
|
|
1147
1657
|
*
|
|
1148
1658
|
* Allows plugins to store and retrieve authentication cookies
|
|
1149
1659
|
* for external services (e.g., Matters.town, GitHub).
|
|
@@ -1210,6 +1720,15 @@ declare function getPluginCookie(): Promise<Cookie[] | null>;
|
|
|
1210
1720
|
* ```
|
|
1211
1721
|
*/
|
|
1212
1722
|
declare function setPluginCookie(cookies: Cookie[]): Promise<void>;
|
|
1723
|
+
/**
|
|
1724
|
+
* Delete ALL cookies on the current plugin's registered (manifest) domain from
|
|
1725
|
+
* the shared WebKit store. Used for force-fresh login: clears any lingering
|
|
1726
|
+
* server session so the login webview presents a real credential screen.
|
|
1727
|
+
*
|
|
1728
|
+
* The plugin's identity is auto-detected from the runtime context.
|
|
1729
|
+
* **Must be called from within a plugin hook.**
|
|
1730
|
+
*/
|
|
1731
|
+
declare function clearPluginCookies(): Promise<void>;
|
|
1213
1732
|
//#endregion
|
|
1214
1733
|
//#region src/utils/events.d.ts
|
|
1215
1734
|
/**
|
|
@@ -1285,13 +1804,13 @@ declare function waitForEvent<T>(event: string, timeoutMs?: number): Promise<T>;
|
|
|
1285
1804
|
/**
|
|
1286
1805
|
* Toast notification utilities for plugins
|
|
1287
1806
|
*
|
|
1288
|
-
* Allows plugins to display toast notifications in the main
|
|
1807
|
+
* Allows plugins to display toast notifications in the main moss UI
|
|
1289
1808
|
* through Tauri's event system.
|
|
1290
1809
|
*
|
|
1291
1810
|
* ## Design Principles
|
|
1292
1811
|
*
|
|
1293
1812
|
* 1. **Plugin Full Control**: Plugins specify exactly what appears in toast
|
|
1294
|
-
* 2. **Minimal Assumptions**:
|
|
1813
|
+
* 2. **Minimal Assumptions**: moss just renders what plugin says
|
|
1295
1814
|
* 3. **Direct Path**: Plugin → showToast() → Frontend renders
|
|
1296
1815
|
* 4. **Separation of Concerns**: Toast (UX) is separate from HookResult (flow control)
|
|
1297
1816
|
*/
|
|
@@ -1355,13 +1874,13 @@ interface ToastOptions {
|
|
|
1355
1874
|
*/
|
|
1356
1875
|
type ToastType = ToastVariant;
|
|
1357
1876
|
/** Event for showing a new toast */
|
|
1358
|
-
declare const TOAST_EVENT = "
|
|
1877
|
+
declare const TOAST_EVENT = "show-toast";
|
|
1359
1878
|
/** Event for updating an existing toast by ID */
|
|
1360
|
-
declare const TOAST_UPDATE_EVENT = "
|
|
1879
|
+
declare const TOAST_UPDATE_EVENT = "show-toast-update";
|
|
1361
1880
|
/** Event for dismissing a toast by ID */
|
|
1362
|
-
declare const TOAST_DISMISS_EVENT = "
|
|
1881
|
+
declare const TOAST_DISMISS_EVENT = "show-toast-dismiss";
|
|
1363
1882
|
/**
|
|
1364
|
-
* Show a toast notification in the main
|
|
1883
|
+
* Show a toast notification in the main moss UI
|
|
1365
1884
|
*
|
|
1366
1885
|
* @param options - Toast options or simple message string
|
|
1367
1886
|
*
|
|
@@ -1431,5 +1950,5 @@ declare function updateToast(id: string, options: Partial<Omit<ToastOptions, "id
|
|
|
1431
1950
|
*/
|
|
1432
1951
|
declare function dismissToast(id: string): Promise<void>;
|
|
1433
1952
|
//#endregion
|
|
1434
|
-
export {
|
|
1953
|
+
export { AdvisoryAction, AdvisoryAppOp, AdvisoryProposal, AdvisoryScope, AdvisorySeverity, ArchType, ArchiveLayout, ArticleInfo, BaseContext, ArchiveFormat as BinaryArchiveFormat, BinaryConfig, BinaryResolution, BinaryResolutionError, BinarySource, BrowserCloseReason, BrowserHandle, CompleteMessage, ConfigureDomainContext, Cookie, DeployContext, DeploymentInfo, DnsRecord, DnsTarget, DownloadOptions, DownloadResult, EnhanceContent, EnhanceContext, EnhanceResult, ErrorMessage, EscapeSpec, ExecuteOptions, ExecuteResult, FetchOptions, FetchResult, GenerateContext, GetOptions, GitHubSource, HookResult, LogMessage, MultipartFilePart, MultipartPostOptions, MultipartTextField, OSType, PageNode, PlatformInfo, PlatformKey, PluginCategory, PluginHook, PluginManifest, PluginMessage, PostOptions, ProcessContext, ProgressMessage, ProjectFileEntry, ProjectInfo, ResolutionSource, ResolveBinaryOptions, SiteFileInfo, SocialArticleData, SocialComment, SocialDataFile, SourceFiles, StartTaskOptions, SyndicateContext, TOAST_DISMISS_EVENT, TOAST_EVENT, TOAST_UPDATE_EVENT, TaskHandle, TauriCore, ToastAction, ToastOptions, ToastType, ToastVariant, TriggerContext, VersionCheck, clearPlatformCache, clearPluginCookies, closeBrowser, createSymlink, dismissToast, downloadAsset, emitEvent, executeBinary, fetchUrl, fileExists, getMessageContext, getPlatformInfo, getPluginCookie, getPluginEnvVar, getTauriCore, htmlToMarkdown, httpGet, httpPost, httpPostMultipart, isEventApiAvailable, isTauriAvailable, listFiles, listPluginFiles, listProjectTree, listSiteFilesWithSizes, listSocialFiles, listSourceFiles, onEvent, openBrowser, openBrowserWithHtml, openSystemBrowser, pluginFileExists, readFile, readPluginFile, readProjectFileBase64, readSiteFile, reportComplete, reportError, reportProgress, resolveBinary, returnToEditor, sendMessage, setMessageContext, setPluginCookie, showBrowserForm, showToast, startTask, updateToast, waitForEvent, writeFile, writePluginFile };
|
|
1435
1954
|
//# sourceMappingURL=index.d.mts.map
|