@vestra-player/sdk 1.5.16 → 1.5.18
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/CHANGELOG.md +19 -0
- package/dist/capabilities.js +0 -1
- package/dist/i18n-tools.d.ts +2 -2
- package/dist/i18n-tools.js +19 -1
- package/dist/plugin/local.d.ts +7 -0
- package/dist/plugin/local.js +12 -0
- package/dist/plugin/packages.js +0 -4
- package/dist/plugin/testing.d.ts +4 -12
- package/dist/plugin/testing.js +13 -22
- package/dist/plugin/types.d.ts +6 -22
- package/dist/wire.d.ts +1 -12
- package/dist/wire.js +0 -9
- package/llms-full.txt +27 -40
- package/llms.txt +20 -20
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.5.18
|
|
4
|
+
|
|
5
|
+
Fixes for Windows and for a vendored SDK, and built-ins that can no longer be disabled. `apiVersion` stays `vestra/1`; plugins that do not manage other plugins need no change.
|
|
6
|
+
|
|
7
|
+
- **`TestHost` streams on Windows**: `openStream`'s default transport listened on a socket file in the temp folder, which Windows refuses (`listen EACCES`), so stream tests failed there. It now listens on a named pipe (`\\.\pipe\vestra-test-host-…-producer-<id>`) on Windows and on a Unix socket elsewhere. `producerTransport = "tcp"` still gives the player's own Windows transport (loopback TCP with a token).
|
|
8
|
+
- **The CLI runs from an SDK outside any `node_modules`** (a copy with TypeScript on `NODE_PATH`, as the player's AI workshop vendors it): `dist/i18n-tools.js` resolved TypeScript with a bare ES module import, which ignores `NODE_PATH`, so `vestra-plugin` stopped at start with `ERR_MODULE_NOT_FOUND`. It now resolves TypeScript as the rest of the CLI does.
|
|
9
|
+
- **Built-in plugins cannot be disabled** (user ruling, 2026-10-26: users manage third-party plugins only). The player and `TestHost` answer `packages.setEnabled(builtin, false)` with `unsupported`; a built-in an older player let the user disable runs again after the upgrade. `PluginInfo.builtin`, `Packages.setEnabled` and *Migrating off package rollback* say so; a plugin manager offers no action for a built-in.
|
|
10
|
+
|
|
11
|
+
## 1.5.17
|
|
12
|
+
|
|
13
|
+
**Package rollback is removed**, as announced in 1.5.16: the player keeps no previous plugin version. `apiVersion` stays `vestra/1` (a patch release, as when 1.5.8 removed `PackageCandidate.trial()`); plugins that do not manage other plugins need no change. A plugin manager that still calls `rollback` or reads `previousVersion` no longer compiles. Migration: [Migrating off package rollback](docs/how-to/rollback-migration.md).
|
|
14
|
+
|
|
15
|
+
- **Removed: `Packages.rollback`** and the wire method `packages.rollback`. The player already answers the method with `unsupported` ("unknown package method"). To go back to an older version of a third-party plugin, the user uninstalls it and installs that version's `.vxp`.
|
|
16
|
+
- **Removed: `PluginInfo.previousVersion`** and the wire field `PackageInfo.previousVersion`; `packages.list` and `packages.changed` no longer carry it.
|
|
17
|
+
- **Removed from `CAPABILITY_INFO["plugins.manage"].apis`**: `"Packages.rollback"`; the capability is unchanged otherwise.
|
|
18
|
+
- **`TestHost`**: `host.packages` entries have no `previousVersion` field (delete it from test data), and there is no `packages.rollback` handler.
|
|
19
|
+
- Unchanged: `revisionConflict`, and the `restoring` and `failedDegraded` statuses of `PackageChange`, which belong to recovery from a failed install.
|
|
20
|
+
- Docs: the Capabilities reference loses the deprecation note; *Migrating off package rollback* says what 1.5.17 removed; `llms.txt` and `llms-full.txt` regenerated.
|
|
21
|
+
|
|
3
22
|
## 1.5.16
|
|
4
23
|
|
|
5
24
|
**Package rollback is deprecated: the player keeps no previous plugin version.** `apiVersion` stays `vestra/1`; code still compiles, and plugins that do not manage other plugins need no change. 1.5.17 removes the deprecated symbols, as 1.5.8 removed `PackageCandidate.trial()` at patch level. Migration: [Migrating off package rollback](docs/how-to/rollback-migration.md).
|
package/dist/capabilities.js
CHANGED
package/dist/i18n-tools.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type TS from "typescript";
|
|
2
2
|
/** A translatable text found in the sources. */
|
|
3
3
|
export interface Message {
|
|
4
4
|
context?: string;
|
|
@@ -27,7 +27,7 @@ export interface ExtractOptions {
|
|
|
27
27
|
/** The plugin's production `.ts` / `.mts` files, relative to `directory`. */
|
|
28
28
|
typescript: readonly string[];
|
|
29
29
|
/** Compiler options for a program over those files (as `check` uses). */
|
|
30
|
-
compilerOptions?:
|
|
30
|
+
compilerOptions?: TS.CompilerOptions;
|
|
31
31
|
}
|
|
32
32
|
export declare const pluralForms: (language: string) => "nplurals=1; plural=0;" | "nplurals=2; plural=(n != 1);";
|
|
33
33
|
/** Find every translatable text of a plugin, in reference order. */
|
package/dist/i18n-tools.js
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
1
9
|
/**
|
|
2
10
|
* `vestra-plugin i18n extract` and `vestra-plugin i18n check`, and the
|
|
3
11
|
* catalog step of `vestra-plugin build` (docs/how-to/i18n.md): find the
|
|
@@ -16,9 +24,19 @@
|
|
|
16
24
|
* @module
|
|
17
25
|
*/
|
|
18
26
|
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync, } from "node:fs";
|
|
27
|
+
import { createRequire } from "node:module";
|
|
19
28
|
import { join, relative, sep } from "node:path";
|
|
20
|
-
import
|
|
29
|
+
import { pathToFileURL } from "node:url";
|
|
21
30
|
import { compileCatalog, keyOf, LOCALES, parsePo, placeholders, scanSlint, writePo, } from "./i18n.js";
|
|
31
|
+
/**
|
|
32
|
+
* The SDK's TypeScript dependency, resolved the way the CLI resolves it
|
|
33
|
+
* (`compiler()` in bin/vestra-plugin.mjs): through `require` resolution from
|
|
34
|
+
* this package, which also searches `NODE_PATH`. A bare `import` of
|
|
35
|
+
* "typescript" would search only ancestor `node_modules` directories, so an
|
|
36
|
+
* SDK copied outside any (the player's AI workshop vendors one, and supplies
|
|
37
|
+
* TypeScript on `NODE_PATH`) could not start the CLI.
|
|
38
|
+
*/
|
|
39
|
+
const ts = (await import(__rewriteRelativeImportExtension(pathToFileURL(createRequire(import.meta.url).resolve("typescript")).href))).default;
|
|
22
40
|
/** Locales whose plural has one form (`n == 1` and other are the same). */
|
|
23
41
|
const ONE_FORM = new Set(["zh-Hans", "ja", "ko"]);
|
|
24
42
|
export const pluralForms = (language) => ONE_FORM.has(language)
|
package/dist/plugin/local.d.ts
CHANGED
|
@@ -4,4 +4,11 @@ import type { LocalServices } from "../wire.ts";
|
|
|
4
4
|
* `ffmpeg` with each `PATHEXT` extension (`ffmpeg.exe` first by default).
|
|
5
5
|
*/
|
|
6
6
|
export declare function executableNames(tool: string, platform?: NodeJS.Platform, pathext?: string | undefined): string[];
|
|
7
|
+
/**
|
|
8
|
+
* Where a local stream listens: a Unix socket file `<name>.sock` in
|
|
9
|
+
* `directory` on macOS and Linux; on Windows a named pipe
|
|
10
|
+
* (`\\.\pipe\<directory's name>-<name>`), which Node's `net` listens on and
|
|
11
|
+
* connects to by that path (a socket file there fails with `EACCES`).
|
|
12
|
+
*/
|
|
13
|
+
export declare function localSocketPath(directory: string, name: string, platform?: NodeJS.Platform): string;
|
|
7
14
|
export declare const systemServices: LocalServices;
|
package/dist/plugin/local.js
CHANGED
|
@@ -31,6 +31,18 @@ export function executableNames(tool, platform = process.platform, pathext = pro
|
|
|
31
31
|
.filter((extension) => extension.startsWith("."));
|
|
32
32
|
return [...new Set(extensions)].map((extension) => tool + extension);
|
|
33
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Where a local stream listens: a Unix socket file `<name>.sock` in
|
|
36
|
+
* `directory` on macOS and Linux; on Windows a named pipe
|
|
37
|
+
* (`\\.\pipe\<directory's name>-<name>`), which Node's `net` listens on and
|
|
38
|
+
* connects to by that path (a socket file there fails with `EACCES`).
|
|
39
|
+
*/
|
|
40
|
+
export function localSocketPath(directory, name, platform = process.platform) {
|
|
41
|
+
if (platform !== "win32")
|
|
42
|
+
return join(directory, `${name}.sock`);
|
|
43
|
+
const scope = directory.split(/[\\/]/).filter(Boolean).at(-1) ?? "vestra";
|
|
44
|
+
return `\\\\.\\pipe\\${scope}-${name}`;
|
|
45
|
+
}
|
|
34
46
|
async function executable(path) {
|
|
35
47
|
try {
|
|
36
48
|
await access(path, constants.X_OK);
|
package/dist/plugin/packages.js
CHANGED
|
@@ -126,9 +126,6 @@ export const packages = (scope) => ({
|
|
|
126
126
|
const checked = await scope.runtime.host.packages.validateArchive(path);
|
|
127
127
|
return candidate(scope, path, checked);
|
|
128
128
|
},
|
|
129
|
-
// Deprecated (removed in 1.5.17): still forwarded, so the player's
|
|
130
|
-
// `unsupported` ("unknown package method") reaches the caller.
|
|
131
|
-
rollback: (id) => change(scope, (requestId, revision) => scope.runtime.host.packages.rollback(id, revision, requestId), id),
|
|
132
129
|
list: async () => (await scope.runtime.host.packages.list()).map(info),
|
|
133
130
|
onChange(listener) {
|
|
134
131
|
const watch = scope.runtime.on("packages.changed", (data) => scope.run(listener, data.map(info)), null);
|
|
@@ -154,7 +151,6 @@ const info = (plugin) => Object.freeze({
|
|
|
154
151
|
error: plugin.error,
|
|
155
152
|
capabilities: [...plugin.capabilities],
|
|
156
153
|
directory: plugin.directory,
|
|
157
|
-
previousVersion: plugin.previousVersion ?? null,
|
|
158
154
|
builtin: plugin.builtin === true,
|
|
159
155
|
source: plugin.source ? Object.freeze({ ...plugin.source }) : null,
|
|
160
156
|
dataDirectory: plugin.dataDirectory ?? null,
|
package/dist/plugin/testing.d.ts
CHANGED
|
@@ -917,8 +917,9 @@ export declare class TestHost implements Transport {
|
|
|
917
917
|
*/
|
|
918
918
|
readonly jobs: Map<number, MediaJob>;
|
|
919
919
|
/**
|
|
920
|
-
* `openStream`'s transport: a
|
|
921
|
-
*
|
|
920
|
+
* `openStream`'s transport: a local stream (a Unix socket on macOS and
|
|
921
|
+
* Linux, a named pipe on Windows) or, with `"tcp"`, loopback TCP where the
|
|
922
|
+
* plugin must send the token first, as the player on Windows answers.
|
|
922
923
|
* Set it before the plugin calls `openStream`.
|
|
923
924
|
*/
|
|
924
925
|
producerTransport: "unix" | "tcp";
|
|
@@ -1311,9 +1312,7 @@ export declare class TestHost implements Transport {
|
|
|
1311
1312
|
/**
|
|
1312
1313
|
* What `packages.list` reports; `setEnabled`, `uninstall` and `install`
|
|
1313
1314
|
* update it. `builtin`, `source` and `dataDirectory` are optional here
|
|
1314
|
-
* (default `false`, `null`, `null`).
|
|
1315
|
-
* plugin with `previousVersion: null` and answers `packages.rollback` with
|
|
1316
|
-
* `unsupported` (since 1.5.16).
|
|
1315
|
+
* (default `false`, `null`, `null`).
|
|
1317
1316
|
*/
|
|
1318
1317
|
packages: {
|
|
1319
1318
|
/** The plugin's manifest id. */
|
|
@@ -1330,13 +1329,6 @@ export declare class TestHost implements Transport {
|
|
|
1330
1329
|
capabilities: string[];
|
|
1331
1330
|
/** The package directory. */
|
|
1332
1331
|
directory: string;
|
|
1333
|
-
/**
|
|
1334
|
-
* Ignored: `packages.list` always reports `null`. Still required in
|
|
1335
|
-
* 1.5.16 so that test data shaped like a `PluginInfo` keeps compiling.
|
|
1336
|
-
*
|
|
1337
|
-
* @deprecated Removed in 1.5.17 with `PluginInfo.previousVersion`.
|
|
1338
|
-
*/
|
|
1339
|
-
previousVersion: string | null;
|
|
1340
1332
|
/** Shipped with the player: `uninstall` and `install` are `unsupported`. */
|
|
1341
1333
|
builtin?: boolean;
|
|
1342
1334
|
/** Where it was installed from. */
|
package/dist/plugin/testing.js
CHANGED
|
@@ -65,6 +65,7 @@ import { tmpdir } from "node:os";
|
|
|
65
65
|
import { extname, isAbsolute, join } from "node:path";
|
|
66
66
|
import { fileURLToPath } from "node:url";
|
|
67
67
|
import { HostError } from "../wire.js";
|
|
68
|
+
import { localSocketPath } from "./local.js";
|
|
68
69
|
import { BUILTIN_COMMANDS, BUILTIN_SUBMENUS, COMMAND_LIMITS, MENU_IDS, } from "../commands.js";
|
|
69
70
|
import { CAPABILITY_INFO, MESSAGE_LIMIT } from "../capabilities.js";
|
|
70
71
|
import { OSD_LIMITS } from "./osd.js";
|
|
@@ -1013,8 +1014,9 @@ export class TestHost {
|
|
|
1013
1014
|
*/
|
|
1014
1015
|
jobs = new Map();
|
|
1015
1016
|
/**
|
|
1016
|
-
* `openStream`'s transport: a
|
|
1017
|
-
*
|
|
1017
|
+
* `openStream`'s transport: a local stream (a Unix socket on macOS and
|
|
1018
|
+
* Linux, a named pipe on Windows) or, with `"tcp"`, loopback TCP where the
|
|
1019
|
+
* plugin must send the token first, as the player on Windows answers.
|
|
1018
1020
|
* Set it before the plugin calls `openStream`.
|
|
1019
1021
|
*/
|
|
1020
1022
|
producerTransport = "unix";
|
|
@@ -1862,9 +1864,7 @@ export class TestHost {
|
|
|
1862
1864
|
/**
|
|
1863
1865
|
* What `packages.list` reports; `setEnabled`, `uninstall` and `install`
|
|
1864
1866
|
* update it. `builtin`, `source` and `dataDirectory` are optional here
|
|
1865
|
-
* (default `false`, `null`, `null`).
|
|
1866
|
-
* plugin with `previousVersion: null` and answers `packages.rollback` with
|
|
1867
|
-
* `unsupported` (since 1.5.16).
|
|
1867
|
+
* (default `false`, `null`, `null`).
|
|
1868
1868
|
*/
|
|
1869
1869
|
packages = [];
|
|
1870
1870
|
/** Every `packages.setEnabled` / `uninstall` / `install`, newest last. */
|
|
@@ -1921,14 +1921,7 @@ export class TestHost {
|
|
|
1921
1921
|
*/
|
|
1922
1922
|
setPackages(list) {
|
|
1923
1923
|
this.packages = list;
|
|
1924
|
-
this.emit("packages.changed", this
|
|
1925
|
-
}
|
|
1926
|
-
/** `packages.list` as the player sends it: no previous version is kept. */
|
|
1927
|
-
#listed() {
|
|
1928
|
-
return this.packages.map((entry) => ({
|
|
1929
|
-
...structuredClone(entry),
|
|
1930
|
-
previousVersion: null,
|
|
1931
|
-
}));
|
|
1924
|
+
this.emit("packages.changed", structuredClone(this.packages));
|
|
1932
1925
|
}
|
|
1933
1926
|
#split(key) {
|
|
1934
1927
|
const at = key.indexOf("/");
|
|
@@ -3162,7 +3155,7 @@ export class TestHost {
|
|
|
3162
3155
|
this.bindings.overlay.delete(`${p.plugin}/${p.command}`);
|
|
3163
3156
|
this.emit("bindings.changed", null);
|
|
3164
3157
|
},
|
|
3165
|
-
"packages.list": () => this
|
|
3158
|
+
"packages.list": () => structuredClone(this.packages),
|
|
3166
3159
|
"packages.setEnabled": (p) => {
|
|
3167
3160
|
const id = String(p.id);
|
|
3168
3161
|
if (id === this.manifestId && p.enabled === false)
|
|
@@ -3170,6 +3163,9 @@ export class TestHost {
|
|
|
3170
3163
|
const entry = this.packages.find((each) => each.id === id);
|
|
3171
3164
|
if (!entry)
|
|
3172
3165
|
throw new HostError("missing", `no plugin ${id}`);
|
|
3166
|
+
// As the player (with SDK 1.5.18 on): users manage third-party plugins only.
|
|
3167
|
+
if (entry.builtin && p.enabled === false)
|
|
3168
|
+
throw new HostError("unsupported", `${id} is a built-in plugin: built-in plugins cannot be disabled`);
|
|
3173
3169
|
this.packageCalls.push({
|
|
3174
3170
|
method: "setEnabled",
|
|
3175
3171
|
id,
|
|
@@ -3214,7 +3210,6 @@ export class TestHost {
|
|
|
3214
3210
|
error: null,
|
|
3215
3211
|
capabilities: [...manifest.capabilities],
|
|
3216
3212
|
directory: `/test-host/packages/${manifest.id}`,
|
|
3217
|
-
previousVersion: null,
|
|
3218
3213
|
builtin: false,
|
|
3219
3214
|
source,
|
|
3220
3215
|
dataDirectory: entry?.dataDirectory ?? null,
|
|
@@ -3231,7 +3226,7 @@ export class TestHost {
|
|
|
3231
3226
|
if (!entry)
|
|
3232
3227
|
throw new HostError("missing", `no plugin ${id}`);
|
|
3233
3228
|
if (entry.builtin)
|
|
3234
|
-
throw new HostError("unsupported", "built-in plugins
|
|
3229
|
+
throw new HostError("unsupported", "built-in plugins cannot be uninstalled");
|
|
3235
3230
|
if (entry.origin !== "installed")
|
|
3236
3231
|
throw new HostError("unsupported", "only installed plugins can be uninstalled");
|
|
3237
3232
|
this.packageCalls.push({
|
|
@@ -3242,11 +3237,6 @@ export class TestHost {
|
|
|
3242
3237
|
this.setPackages(this.packages.filter((each) => each.id !== id));
|
|
3243
3238
|
return { operationId: String(p.requestId), status: "committed" };
|
|
3244
3239
|
},
|
|
3245
|
-
// The player no longer keeps a previous version (SDK 1.5.16): the method
|
|
3246
|
-
// is gone and fails like any unknown package method.
|
|
3247
|
-
"packages.rollback": () => {
|
|
3248
|
-
throw new HostError("unsupported", "unknown package method");
|
|
3249
|
-
},
|
|
3250
3240
|
"ui.markdownScan": (p) => {
|
|
3251
3241
|
const text = String(p.text);
|
|
3252
3242
|
const images = [
|
|
@@ -3451,7 +3441,8 @@ export class TestHost {
|
|
|
3451
3441
|
const id = ++this.#next.producer;
|
|
3452
3442
|
const tcp = this.producerTransport === "tcp";
|
|
3453
3443
|
const token = tcp ? randomBytes(32) : null;
|
|
3454
|
-
|
|
3444
|
+
// A Unix socket, or a named pipe on Windows (`localSocketPath`).
|
|
3445
|
+
const path = localSocketPath(this.#scratch, `producer-${id}`);
|
|
3455
3446
|
const producer = {
|
|
3456
3447
|
id,
|
|
3457
3448
|
receivedFrames: 0,
|
package/dist/plugin/types.d.ts
CHANGED
|
@@ -4733,17 +4733,9 @@ export interface PluginInfo {
|
|
|
4733
4733
|
*/
|
|
4734
4734
|
directory: string;
|
|
4735
4735
|
/**
|
|
4736
|
-
*
|
|
4737
|
-
*
|
|
4738
|
-
*
|
|
4739
|
-
* @deprecated Removed in 1.5.17. The player no longer keeps a previous
|
|
4740
|
-
* version, so this is always `null`. See
|
|
4741
|
-
* [Migrating off package rollback](../../docs/how-to/rollback-migration.md).
|
|
4742
|
-
*/
|
|
4743
|
-
previousVersion: string | null;
|
|
4744
|
-
/**
|
|
4745
|
-
* Shipped with the player: it can be disabled, not uninstalled or
|
|
4746
|
-
* replaced. `false` from players before 0.2.0.
|
|
4736
|
+
* Shipped with the player: it always runs; it cannot be disabled,
|
|
4737
|
+
* uninstalled or replaced (older players, before SDK 1.5.18, let it be disabled).
|
|
4738
|
+
* `false` from players before 0.2.0.
|
|
4747
4739
|
*/
|
|
4748
4740
|
builtin: boolean;
|
|
4749
4741
|
/** Where an installed plugin came from; `null` for development loads. */
|
|
@@ -4839,16 +4831,6 @@ export interface Packages {
|
|
|
4839
4831
|
* fails with `reserved`, as in {@link Packages.validate}.
|
|
4840
4832
|
*/
|
|
4841
4833
|
validateArchive(file: string): Promise<PackageCandidate>;
|
|
4842
|
-
/**
|
|
4843
|
-
* Formerly restored a plugin's previous version (`plugins.manage`).
|
|
4844
|
-
*
|
|
4845
|
-
* @deprecated Removed in 1.5.17. The player no longer keeps a previous
|
|
4846
|
-
* version, so this always fails with `unsupported`. To go back to an older
|
|
4847
|
-
* version of a third-party plugin, the user uninstalls it and installs that
|
|
4848
|
-
* version's `.vxp`. See
|
|
4849
|
-
* [Migrating off package rollback](../../docs/how-to/rollback-migration.md).
|
|
4850
|
-
*/
|
|
4851
|
-
rollback(id: string): Promise<PackageChange>;
|
|
4852
4834
|
/** Every plugin: running, installed, and this run's development loads. No capability. */
|
|
4853
4835
|
list(): Promise<PluginInfo[]>;
|
|
4854
4836
|
/** The new list after any start, stop, failure, install or uninstall. No capability. */
|
|
@@ -4857,7 +4839,9 @@ export interface Packages {
|
|
|
4857
4839
|
* Stop or start a plugin (`plugins.manage`). An installed plugin stays
|
|
4858
4840
|
* disabled across launches; a development load only for this run.
|
|
4859
4841
|
* `invalid` to disable oneself, `missing` unknown.
|
|
4860
|
-
* `busy` while it is being installed.
|
|
4842
|
+
* `busy` while it is being installed. `unsupported` to disable a built-in
|
|
4843
|
+
* ({@link PluginInfo.builtin}): users manage third-party plugins only
|
|
4844
|
+
* (players released with SDK 1.5.18 on; older ones disabled built-ins too).
|
|
4861
4845
|
*/
|
|
4862
4846
|
setEnabled(id: string, enabled: boolean): Promise<void>;
|
|
4863
4847
|
/**
|
package/dist/wire.d.ts
CHANGED
|
@@ -102,12 +102,6 @@ export interface PackageInfo {
|
|
|
102
102
|
error: string | null;
|
|
103
103
|
capabilities: string[];
|
|
104
104
|
directory: string;
|
|
105
|
-
/**
|
|
106
|
-
* Always `null` from players that ship with SDK 1.5.16 or later.
|
|
107
|
-
*
|
|
108
|
-
* @deprecated Removed in 1.5.17: the player keeps no previous version.
|
|
109
|
-
*/
|
|
110
|
-
previousVersion: string | null;
|
|
111
105
|
/** Player 0.2.0; absent from older players. */
|
|
112
106
|
builtin?: boolean;
|
|
113
107
|
source?: WireSource | null;
|
|
@@ -572,11 +566,6 @@ export declare function createWire(transport: Transport): {
|
|
|
572
566
|
source?: WireSource;
|
|
573
567
|
replace?: boolean;
|
|
574
568
|
}) => Promise<PackageOperation>;
|
|
575
|
-
/**
|
|
576
|
-
* @deprecated Removed in 1.5.17. The player no longer has this method and
|
|
577
|
-
* rejects it with `unsupported` ("unknown package method").
|
|
578
|
-
*/
|
|
579
|
-
rollback: (id: string, expectedRevision: number, requestId: string) => Promise<PackageOperation>;
|
|
580
569
|
operation: (operationId: string) => Promise<PackageOperation>;
|
|
581
570
|
cancel: (operationId: string) => Promise<PackageOperation>;
|
|
582
571
|
list: () => Promise<PackageInfo[]>;
|
|
@@ -602,7 +591,7 @@ export declare function createWire(transport: Transport): {
|
|
|
602
591
|
sampleTime?: number;
|
|
603
592
|
} | {
|
|
604
593
|
kind: "rawJpeg" | "processedJpeg";
|
|
605
|
-
sampleTime
|
|
594
|
+
sampleTime?: number;
|
|
606
595
|
quality?: number;
|
|
607
596
|
} | {
|
|
608
597
|
kind: "rawMp4" | "processedMp4";
|
package/dist/wire.js
CHANGED
|
@@ -278,15 +278,6 @@ export function createWire(transport) {
|
|
|
278
278
|
...(options.source === undefined ? {} : { source: options.source }),
|
|
279
279
|
...(options.replace ? { replace: true } : {}),
|
|
280
280
|
}),
|
|
281
|
-
/**
|
|
282
|
-
* @deprecated Removed in 1.5.17. The player no longer has this method and
|
|
283
|
-
* rejects it with `unsupported` ("unknown package method").
|
|
284
|
-
*/
|
|
285
|
-
rollback: (id, expectedRevision, requestId) => transport.request("packages.rollback", {
|
|
286
|
-
id,
|
|
287
|
-
expectedRevision,
|
|
288
|
-
requestId,
|
|
289
|
-
}),
|
|
290
281
|
operation: (operationId) => transport.request("packages.operation", {
|
|
291
282
|
operationId,
|
|
292
283
|
}),
|
package/llms-full.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# @vestra-player/sdk 1.5.
|
|
1
|
+
# @vestra-player/sdk 1.5.18: full reference
|
|
2
2
|
|
|
3
3
|
> Everything needed to write a Vestra Player plugin (plugin API `vestra/1`): the guides, every public declaration of `@vestra-player/sdk` and `@vestra-player/sdk/testing` with its documentation, and the complete source of the example plugins. Generated from the SDK's sources by scripts/llms.mjs; the short index is llms.txt.
|
|
4
4
|
|
|
@@ -1840,36 +1840,37 @@ The store shows the newest version's manifest fields, so what you write there is
|
|
|
1840
1840
|
- **Before installing**, the user confirms a dialog that lists the capabilities; an update that adds capabilities lists the new ones. A plugin whose every version needs a newer player shows "needs Vestra Player x.y.z or later" instead of an install button.
|
|
1841
1841
|
- **The README** is rendered as Markdown; relative links and images resolve against the README's own address, and remote images are shown for the official repository.
|
|
1842
1842
|
|
|
1843
|
-
## How-to: Migrating off package rollback (1.5.16)
|
|
1843
|
+
## How-to: Migrating off package rollback (1.5.16, removed in 1.5.17)
|
|
1844
1844
|
|
|
1845
|
-
For plugins that manage other plugins (`plugins.manage`): stores, plugin managers, anything that
|
|
1845
|
+
For plugins that manage other plugins (`plugins.manage`): stores, plugin managers, anything that called `packages.rollback` or read `PluginInfo.previousVersion`. Both were deprecated in 1.5.16 and **removed in 1.5.17**: with 1.5.17 a remaining use is a TypeScript compile error. A plugin that only uses its own API needs no change.
|
|
1846
1846
|
|
|
1847
1847
|
#### What changed
|
|
1848
1848
|
|
|
1849
1849
|
The player no longer keeps a previous version of a plugin. An upgrade replaces the package, so there is nothing to roll back to:
|
|
1850
1850
|
|
|
1851
|
-
- `packages.rollback
|
|
1852
|
-
-
|
|
1853
|
-
- Built-in plugins (`builtin: true`) run in place from the player installation.
|
|
1851
|
+
- There is no `packages.rollback`: the player answers the wire method with `unsupported` ("unknown package method"), and SDK 1.5.17 no longer has it.
|
|
1852
|
+
- `packages.list()` and `packages.onChange` entries have no `previousVersion` (always `null` with SDK 1.5.16, removed in 1.5.17).
|
|
1853
|
+
- Built-in plugins (`builtin: true`) run in place from the player installation. Users manage only third-party plugins: a built-in can be neither uninstalled, replaced nor (from SDK 1.5.18 and the players released with it) disabled; `uninstall` and `setEnabled(id, false)` fail with `unsupported`, and a built-in an older player let the user disable runs again after the upgrade. A built-in's `directory` is inside the installation (`<install resources>/plugins/<id>`) and read-only.
|
|
1854
1854
|
- Third-party plugins can still be uninstalled.
|
|
1855
1855
|
|
|
1856
1856
|
Why: built-ins now run from the read-only installation instead of a copy, and an upgrade replaces the package instead of keeping the old one beside it. Going back to an older version becomes an ordinary uninstall and install that the user starts.
|
|
1857
1857
|
|
|
1858
|
-
`TestHost` behaves the same way
|
|
1858
|
+
`TestHost` behaves the same way, so tests show it too.
|
|
1859
1859
|
|
|
1860
1860
|
#### 1. Remove rollback calls and `previousVersion` checks
|
|
1861
1861
|
|
|
1862
1862
|
Before:
|
|
1863
1863
|
|
|
1864
1864
|
```ts nocheck
|
|
1865
|
-
if (info.previousVersion !== null)
|
|
1865
|
+
if (info.previousVersion !== null)
|
|
1866
|
+
showButton("Roll back", () => plugin.packages.rollback(info.id));
|
|
1866
1867
|
```
|
|
1867
1868
|
|
|
1868
|
-
After: delete both. There is no replacement call; nothing on the player can restore an earlier package. Remove the button, menu item or command, and any state, text or test that depends on `previousVersion`.
|
|
1869
|
+
After: delete both. There is no replacement call; nothing on the player can restore an earlier package. Remove the button, menu item or command, and any state, text or test that depends on `previousVersion`. With SDK 1.5.17 the compiler finds every remaining use.
|
|
1869
1870
|
|
|
1870
1871
|
#### 2. Going back to an older version
|
|
1871
1872
|
|
|
1872
|
-
Managing plugins has exactly three operations: **install**, **uninstall** and **disable/enable**. There is no rollback, no "install older version" and no "Undo install".
|
|
1873
|
+
Managing third-party plugins has exactly three operations: **install**, **uninstall** and **disable/enable**. Built-ins have none of them. There is no rollback, no "install older version" and no "Undo install".
|
|
1873
1874
|
|
|
1874
1875
|
To go back to an older version, the user uninstalls the plugin and installs the older version's `.vxp` file themselves, as two ordinary operations. Do not offer an action that does both, an older-version install from a store, or an "Undo" after an install (the official store and the AI window drop theirs). Uninstalling without `removeData` keeps the plugin's data, and a reinstall from the same source reconnects to it; a `.vxp` file is a different source from a repository, so a plugin first installed from the store gets a new, empty data directory.
|
|
1875
1876
|
|
|
@@ -1884,35 +1885,36 @@ Check `builtin` before offering actions:
|
|
|
1884
1885
|
```ts
|
|
1885
1886
|
for (const info of await plugin.packages.list()) {
|
|
1886
1887
|
const actions = info.builtin
|
|
1887
|
-
? [
|
|
1888
|
-
: ["Disable", "Uninstall"];
|
|
1888
|
+
? []
|
|
1889
|
+
: [info.state === "disabled" ? "Enable" : "Disable", "Uninstall"];
|
|
1889
1890
|
console.log(info.id, actions);
|
|
1890
1891
|
}
|
|
1891
1892
|
```
|
|
1892
1893
|
|
|
1893
|
-
- Offer
|
|
1894
|
+
- Offer no action for a built-in: never disable, uninstall or install over it (the player answers `unsupported`). Built-ins that an older player listed as `disabled` come back as running.
|
|
1894
1895
|
- Never write into a built-in's `directory`, or into any plugin's `directory`: read `manifest.json` from it if you need to. A plugin writes only under its own plugin.dataDirectory.
|
|
1895
1896
|
|
|
1896
1897
|
#### 5. Tests
|
|
1897
1898
|
|
|
1898
|
-
`
|
|
1899
|
+
With SDK 1.5.17, `host.packages` entries have no `previousVersion` field: delete `previousVersion: null` (or any value) from test data, or the test no longer compiles. `TestHost` has no `packages.rollback`. Remove tests that exercised a rollback; there is nothing left to assert. (With 1.5.16 the field was still required but ignored, and `TestHost` answered rollback with `unsupported`.)
|
|
1899
1900
|
|
|
1900
1901
|
#### Timeline
|
|
1901
1902
|
|
|
1902
|
-
| SDK
|
|
1903
|
-
|
|
|
1904
|
-
| 1.5.16 | ships with it | `Packages.rollback` and `PluginInfo.previousVersion` (and the wire field) are `@deprecated`. The player and `TestHost` answer rollback with `unsupported` and list `previousVersion: null`. Code still compiles.
|
|
1905
|
-
| 1.5.17 |
|
|
1903
|
+
| SDK | Player | What happens |
|
|
1904
|
+
| ------ | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1905
|
+
| 1.5.16 | ships with it | `Packages.rollback` and `PluginInfo.previousVersion` (and the wire field) are `@deprecated`. The player and `TestHost` answer rollback with `unsupported` and list `previousVersion: null`. Code still compiles. |
|
|
1906
|
+
| 1.5.17 | ships with it | **Removed:** `Packages.rollback`, `PluginInfo.previousVersion`, the wire method `packages.rollback` and the wire field `previousVersion`, `TestHost`'s `previousVersion` field and its `packages.rollback` handler, and `Packages.rollback` in the `plugins.manage` capability. Remaining uses are TypeScript compile errors. |
|
|
1907
|
+
| 1.5.18 | ships with it | Built-ins can no longer be disabled: the player and `TestHost` answer `setEnabled(builtin, false)` with `unsupported` (user ruling 2026-10-26). |
|
|
1906
1908
|
|
|
1907
1909
|
`apiVersion` stays `vestra/1` in both releases, as when 1.5.8 removed `PackageCandidate.trial()`.
|
|
1908
1910
|
|
|
1909
1911
|
#### Before you hand it in
|
|
1910
1912
|
|
|
1911
1913
|
- [ ] No call to `packages.rollback`; no UI or logic gated on `previousVersion`.
|
|
1912
|
-
- [ ] Built-ins offer
|
|
1914
|
+
- [ ] Built-ins offer no Disable, Enable or Uninstall.
|
|
1913
1915
|
- [ ] Nothing writes into a plugin's `directory`.
|
|
1914
1916
|
- [ ] No Undo after an install, no older-version install; older versions go through uninstall and a user-chosen `.vxp`.
|
|
1915
|
-
- [ ] Tests pass with SDK 1.5.
|
|
1917
|
+
- [ ] Tests compile and pass with SDK 1.5.17; no `previousVersion` is left in `host.packages` test data.
|
|
1916
1918
|
|
|
1917
1919
|
## Guideline: Interface guidelines
|
|
1918
1920
|
|
|
@@ -2176,7 +2178,7 @@ A plugin lists what it may do in the manifest's `capabilities` (Manifest). A cal
|
|
|
2176
2178
|
| `ui.window` | Windows.create | — | Open tool windows | |
|
|
2177
2179
|
| `ui.mount` | Panels.mount, Panels.bottom, Panels.sidebar, Panels.backdrop, PanelSlot.onChange, Panel.onChange, BackdropSlot.onChange | — | Show panels in the bottom bar, the sidebar or behind the video | |
|
|
2178
2180
|
| `ui.dialog` | Dialogs.confirm, Dialogs.openFile, Dialogs.openFiles, Dialogs.openDirectory, Dialogs.saveFile | — | Show file pickers and confirmations | |
|
|
2179
|
-
| `plugins.manage` | Packages.validate, Packages.validateArchive, Packages.
|
|
2181
|
+
| `plugins.manage` | Packages.validate, Packages.validateArchive, Packages.setEnabled, Packages.uninstall | — | Install, uninstall and disable other plugins | yes |
|
|
2180
2182
|
| `processing.video` | Plugin.video.filter, Plugin.video.view, Plugin.video.render | `playback.read` | Process the picture (filters, shaders) | |
|
|
2181
2183
|
| `processing.audio` | Plugin.audio.filter | `playback.read`, `events` | Process the sound | |
|
|
2182
2184
|
| `subtitles.read` | Subtitles.state, Subtitles.onChange, Subtitles.refresh | — | Read subtitles | |
|
|
@@ -2200,8 +2202,6 @@ A plugin lists what it may do in the manifest's `capabilities` (Manifest). A cal
|
|
|
2200
2202
|
- A file resolver (Resolvers.add with file types) also needs `producer.av`.
|
|
2201
2203
|
- Without `events`, Player.state is read at start and after the plugin's own operations, and `onChange` listeners do not fire for changes made elsewhere.
|
|
2202
2204
|
|
|
2203
|
-
**Deprecated:** Packages.rollback in the `plugins.manage` row (since 1.5.16; removed in 1.5.17). The player keeps no previous version, so it always fails with `unsupported`; see Migrating off package rollback.
|
|
2204
|
-
|
|
2205
2205
|
#### Without a capability
|
|
2206
2206
|
|
|
2207
2207
|
A member not in the table needs no capability: `plugin.tools`, `plugin.storage`, `plugin.system`, `plugin.app`, `plugin.ui` (images and Markdown), `plugin.i18n`, reading window.state, appearance.theme and packages.list. The table is `CAPABILITY_INFO`, which tests can import from `@vestra-player/sdk/testing` to check a manifest (CAPABILITY_INFO).
|
|
@@ -6010,11 +6010,8 @@ interface PluginInfo {
|
|
|
6010
6010
|
*/
|
|
6011
6011
|
directory: string;
|
|
6012
6012
|
/**
|
|
6013
|
-
*
|
|
6014
|
-
* @deprecated Removed in 1.5.17. The player no longer keeps a previous version, so this is always `null`. See Migrating off package rollback.
|
|
6013
|
+
* Shipped with the player: it always runs; it cannot be disabled, uninstalled or replaced (older players, before SDK 1.5.18, let it be disabled). `false` from players before 0.2.0.
|
|
6015
6014
|
*/
|
|
6016
|
-
previousVersion: string | null;
|
|
6017
|
-
/** Shipped with the player: it can be disabled, not uninstalled or replaced. `false` from players before 0.2.0. */
|
|
6018
6015
|
builtin: boolean;
|
|
6019
6016
|
/** Where an installed plugin came from; `null` for development loads. */
|
|
6020
6017
|
source: PackageSource | null;
|
|
@@ -6087,17 +6084,12 @@ interface Packages {
|
|
|
6087
6084
|
* Validate a `.vxp` package file (`plugins.manage`, player 0.2.0): the same checks as Packages.validate after unpacking. Check the file's sha256 yourself before calling when you know it. A reserved id fails with `reserved`, as in Packages.validate.
|
|
6088
6085
|
*/
|
|
6089
6086
|
validateArchive(file: string): Promise<PackageCandidate>;
|
|
6090
|
-
/**
|
|
6091
|
-
* Formerly restored a plugin's previous version (`plugins.manage`).
|
|
6092
|
-
* @deprecated Removed in 1.5.17. The player no longer keeps a previous version, so this always fails with `unsupported`. To go back to an older version of a third-party plugin, the user uninstalls it and installs that version's `.vxp`. See Migrating off package rollback.
|
|
6093
|
-
*/
|
|
6094
|
-
rollback(id: string): Promise<PackageChange>;
|
|
6095
6087
|
/** Every plugin: running, installed, and this run's development loads. No capability. */
|
|
6096
6088
|
list(): Promise<PluginInfo[]>;
|
|
6097
6089
|
/** The new list after any start, stop, failure, install or uninstall. No capability. */
|
|
6098
6090
|
onChange(listener: (plugins: PluginInfo[]) => void): Disposable;
|
|
6099
6091
|
/**
|
|
6100
|
-
* Stop or start a plugin (`plugins.manage`). An installed plugin stays disabled across launches; a development load only for this run. `invalid` to disable oneself, `missing` unknown. `busy` while it is being installed.
|
|
6092
|
+
* Stop or start a plugin (`plugins.manage`). An installed plugin stays disabled across launches; a development load only for this run. `invalid` to disable oneself, `missing` unknown. `busy` while it is being installed. `unsupported` to disable a built-in (PluginInfo.builtin): users manage third-party plugins only (players released with SDK 1.5.18 on; older ones disabled built-ins too).
|
|
6101
6093
|
*/
|
|
6102
6094
|
setEnabled(id: string, enabled: boolean): Promise<void>;
|
|
6103
6095
|
/**
|
|
@@ -7193,7 +7185,7 @@ class TestHost implements Transport {
|
|
|
7193
7185
|
/** Export jobs by job id. Each state query advances a job one step (`queued` → `running` → `completed`; `cancelling` → `cancelled`). Wire-level. */
|
|
7194
7186
|
readonly jobs: Map<number, MediaJob>;
|
|
7195
7187
|
/**
|
|
7196
|
-
* `openStream`'s transport: a Unix socket
|
|
7188
|
+
* `openStream`'s transport: a local stream (a Unix socket on macOS and Linux, a named pipe on Windows) or, with `"tcp"`, loopback TCP where the plugin must send the token first, as the player on Windows answers. Set it before the plugin calls `openStream`.
|
|
7197
7189
|
*/
|
|
7198
7190
|
producerTransport: "unix" | "tcp";
|
|
7199
7191
|
/** Generated streams (`player.openStream`) by producer id: the fake player end of each frame connection. Wire-level beyond the FakeProducer fields. */
|
|
@@ -7411,7 +7403,7 @@ class TestHost implements Transport {
|
|
|
7411
7403
|
overlay: Map<string, string[]>;
|
|
7412
7404
|
};
|
|
7413
7405
|
/**
|
|
7414
|
-
* What `packages.list` reports; `setEnabled`, `uninstall` and `install` update it. `builtin`, `source` and `dataDirectory` are optional here (default `false`, `null`, `null`).
|
|
7406
|
+
* What `packages.list` reports; `setEnabled`, `uninstall` and `install` update it. `builtin`, `source` and `dataDirectory` are optional here (default `false`, `null`, `null`).
|
|
7415
7407
|
*/
|
|
7416
7408
|
packages: {
|
|
7417
7409
|
/** The plugin's manifest id. */
|
|
@@ -7428,11 +7420,6 @@ class TestHost implements Transport {
|
|
|
7428
7420
|
capabilities: string[];
|
|
7429
7421
|
/** The package directory. */
|
|
7430
7422
|
directory: string;
|
|
7431
|
-
/**
|
|
7432
|
-
* Ignored: `packages.list` always reports `null`. Still required in 1.5.16 so that test data shaped like a `PluginInfo` keeps compiling.
|
|
7433
|
-
* @deprecated Removed in 1.5.17 with `PluginInfo.previousVersion`.
|
|
7434
|
-
*/
|
|
7435
|
-
previousVersion: string | null;
|
|
7436
7423
|
/** Shipped with the player: `uninstall` and `install` are `unsupported`. */
|
|
7437
7424
|
builtin?: boolean;
|
|
7438
7425
|
/** Where it was installed from. */
|
package/llms.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Vestra Player SDK
|
|
2
2
|
|
|
3
|
-
> @vestra-player/sdk 1.5.
|
|
3
|
+
> @vestra-player/sdk 1.5.18: write plugins for Vestra Player in TypeScript (plugin API `vestra/1`). A plugin is a folder with `manifest.json` and an entry module whose default export `activate(plugin)` the player calls; it runs in its own Node.js process. Everything a plugin creates (commands, windows, panels, filters, listeners…) is a handle that is released automatically when the plugin stops. L<n> are line numbers in llms-full.txt, next to this file: every page, declaration and example.
|
|
4
4
|
|
|
5
5
|
**Rules**
|
|
6
6
|
|
|
@@ -33,7 +33,7 @@ my-plugin/
|
|
|
33
33
|
}
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
Fields: `id`, `version`, `apiVersion`, `entry`, `capabilities`, `name`, `author`, `punchline`, `description`, `tags`, `icon`, `readme`, `changelog`, `sourceUrl`, `license`, `minPlayerVersion`; unknown fields and capabilities are rejected. Rules and limits:
|
|
36
|
+
Fields: `id`, `version`, `apiVersion`, `entry`, `capabilities`, `name`, `author`, `punchline`, `description`, `tags`, `icon`, `readme`, `changelog`, `sourceUrl`, `license`, `minPlayerVersion`; unknown fields and capabilities are rejected. Rules and limits: L2102–2165.
|
|
37
37
|
|
|
38
38
|
**main.ts**
|
|
39
39
|
|
|
@@ -60,7 +60,7 @@ export default async function activate(plugin: Plugin) {
|
|
|
60
60
|
- `ui.window`: Windows.create
|
|
61
61
|
- `ui.mount`: Panels.mount/bottom/sidebar/backdrop, PanelSlot/Panel/BackdropSlot.onChange
|
|
62
62
|
- `ui.dialog`: Dialogs.confirm/openFile/openFiles/openDirectory/saveFile
|
|
63
|
-
- `plugins.manage`: Packages.validate/validateArchive/
|
|
63
|
+
- `plugins.manage`: Packages.validate/validateArchive/setEnabled/uninstall
|
|
64
64
|
- `processing.video`: Plugin.video.filter/video.view/video.render (also `playback.read`)
|
|
65
65
|
- `processing.audio`: Plugin.audio.filter (also `playback.read`, `events`)
|
|
66
66
|
- `subtitles.read`: Subtitles.state/onChange/refresh
|
|
@@ -76,9 +76,9 @@ export default async function activate(plugin: Plugin) {
|
|
|
76
76
|
- `ui.settings`: Settings.page/show
|
|
77
77
|
- `ui.theme`: Appearance.set/setLanguage
|
|
78
78
|
- `secrets`: Secrets.get/set/delete
|
|
79
|
-
- No capability: `tools`, `storage`, `system`, `app`, `ui` (images and Markdown), `i18n`, reading window.state, appearance.theme and packages.list. Details:
|
|
79
|
+
- No capability: `tools`, `storage`, `system`, `app`, `ui` (images and Markdown), `i18n`, reading window.state, appearance.theme and packages.list. Details: L2166–2208.
|
|
80
80
|
|
|
81
|
-
**Test**: `tests/*.test.ts` with `node:test`, run by `vestra-plugin test`. `startPlugin(activate, { directory: new URL("..", import.meta.url) })` from `@vestra-player/sdk/testing` returns `{ host, stop }`; `host` is a TestHost (an in-memory player): `host.setSource(…)`, `host.command(id).run()`, `host.press(key)`, `await host.settle()`, then assert on `host.osd`, `host.window(id).props`… Guide: L1588–1753; TestHost:
|
|
81
|
+
**Test**: `tests/*.test.ts` with `node:test`, run by `vestra-plugin test`. `startPlugin(activate, { directory: new URL("..", import.meta.url) })` from `@vestra-player/sdk/testing` returns `{ host, stop }`; `host` is a TestHost (an in-memory player): `host.setSource(…)`, `host.command(id).run()`, `host.press(key)`, `await host.settle()`, then assert on `host.osd`, `host.window(id).props`… Guide: L1588–1753; TestHost: L6751.
|
|
82
82
|
|
|
83
83
|
**Command line**
|
|
84
84
|
|
|
@@ -113,32 +113,32 @@ export default async function activate(plugin: Plugin) {
|
|
|
113
113
|
- [llms-full.txt](https://vestrasys.github.io/vestra-player-sdk/llms-full.txt), also node_modules/@vestra-player/sdk/llms-full.txt; the pages are on the [site](https://vestrasys.github.io/vestra-player-sdk/).
|
|
114
114
|
- Tutorials: Getting started L9–214
|
|
115
115
|
- Concepts: How a plugin runs L215–364; Commands, menus and key bindings L365–462; Playback state, controls and sources L463–585; Video and audio processing L586–663; Windows, panels, settings pages, dialogs and the OSD L664–950
|
|
116
|
-
- How-to: Keep a slider responsive while dragging L951–1125; Remember a window's state between runs L1126–1255; Translate a plugin L1256–1439; Migrate a plugin to English source text L1440–1587; Test a plugin L1588–1753; Publish a plugin L1754–1842; Migrating off package rollback (1.5.16) L1843–
|
|
117
|
-
- Guidelines: Interface guidelines
|
|
118
|
-
- Reference: Manifest
|
|
119
|
-
- [API: @vestra-player/sdk](https://vestrasys.github.io/vestra-player-sdk/modules/_vestra-player_sdk.html): L3063–
|
|
120
|
-
- [API: @vestra-player/sdk/testing](https://vestrasys.github.io/vestra-player-sdk/modules/_vestra-player_sdk_testing.html):
|
|
116
|
+
- How-to: Keep a slider responsive while dragging L951–1125; Remember a window's state between runs L1126–1255; Translate a plugin L1256–1439; Migrate a plugin to English source text L1440–1587; Test a plugin L1588–1753; Publish a plugin L1754–1842; Migrating off package rollback (1.5.16, removed in 1.5.17) L1843–1918
|
|
117
|
+
- Guidelines: Interface guidelines L1919–2003; Menu guidelines L2004–2101
|
|
118
|
+
- Reference: Manifest L2102–2165; Capabilities L2166–2208; Limits L2209–2303; Commands, menus and bindings L2304–2772; Platforms L2773–2801; Theme L2802–3006; Command line L3007–3062
|
|
119
|
+
- [API: @vestra-player/sdk](https://vestrasys.github.io/vestra-player-sdk/modules/_vestra-player_sdk.html): L3063–6586
|
|
120
|
+
- [API: @vestra-player/sdk/testing](https://vestrasys.github.io/vestra-player-sdk/modules/_vestra-player_sdk_testing.html): L6587–7909
|
|
121
121
|
|
|
122
122
|
## API
|
|
123
123
|
|
|
124
124
|
Where each module of `plugin` (`plugin.<module>`) is declared:
|
|
125
125
|
|
|
126
126
|
- Plugin L3297, Scope L3166, PluginError L3105, Disposable L3078
|
|
127
|
-
- Commands L3509; Windows L3714; Panels L4357; Dialogs L4643; Player L5091; video: VideoFilter L5356, VideoView L5419, RenderOptions L5461; audio: AudioFilter L5380; Subtitles L5559; media: MediaCapture L5719; Resolvers L5824; Packages
|
|
127
|
+
- Commands L3509; Windows L3714; Panels L4357; Dialogs L4643; Player L5091; video: VideoFilter L5356, VideoView L5419, RenderOptions L5461; audio: AudioFilter L5380; Subtitles L5559; media: MediaCapture L5719; Resolvers L5824; Packages L6066; Osd L5292; Host L5240; Clipboard L6181; Power L6201; Tools L6234; Storage L6277; System L6300; Secrets L6318; window: MainWindow L4480; App L4561; Bindings L6151; Ui L3601; Timeline L4437; Drops L4013; Appearance L4042; I18n L4184; Settings L4290.
|
|
128
128
|
|
|
129
129
|
## Examples
|
|
130
130
|
|
|
131
131
|
Tested plugins in [examples/](https://github.com/vestrasys/vestra-player-sdk/tree/main/examples):
|
|
132
132
|
|
|
133
|
-
- hello: The README Quick start: one menu command and an on-screen message.
|
|
134
|
-
- blur: A tool window with one slider that blurs the playing video.
|
|
135
|
-
- signal-generator: Generates its own video and audio: colour bars and a 1 kHz tone.
|
|
136
|
-
- bookmark: A tool window bound to the playback state: remember the position and jump back to it.
|
|
137
|
-
- panel-menu: A sidebar panel with its own right-click menu.
|
|
138
|
-
- menus: Radio menu items, separator groups and a menu item whose title changes.
|
|
139
|
-
- theme-widgets: A tool window drawn with the player's theme and widgets.
|
|
140
|
-
- markdown: A window that shows a Markdown document.
|
|
141
|
-
- i18n: A plugin in the player's language: English source text, a Chinese translation.
|
|
133
|
+
- hello: The README Quick start: one menu command and an on-screen message. L8333–8422
|
|
134
|
+
- blur: A tool window with one slider that blurs the playing video. L8423–8684
|
|
135
|
+
- signal-generator: Generates its own video and audio: colour bars and a 1 kHz tone. L8685–9017
|
|
136
|
+
- bookmark: A tool window bound to the playback state: remember the position and jump back to it. L9018–9202
|
|
137
|
+
- panel-menu: A sidebar panel with its own right-click menu. L9203–9408
|
|
138
|
+
- menus: Radio menu items, separator groups and a menu item whose title changes. L9409–9568
|
|
139
|
+
- theme-widgets: A tool window drawn with the player's theme and widgets. L9569–9732
|
|
140
|
+
- markdown: A window that shows a Markdown document. L9733–9927
|
|
141
|
+
- i18n: A plugin in the player's language: English source text, a Chinese translation. L9928–10095
|
|
142
142
|
|
|
143
143
|
## Optional
|
|
144
144
|
|