@vormio/plugin-sdk 0.0.5 → 0.0.7-rc.1

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 CHANGED
@@ -1,8 +1,8 @@
1
1
  # @vormio/plugin-sdk
2
2
 
3
- The manifest schema, runtime helpers and packaging command for writing Vormio plugins, plus the commands that publish a signed plugin catalog. The package is versioned with Vormio-Core (currently 0.0.5) and published to npm under the MIT license: `npm install @vormio/plugin-sdk@0.0.5`.
3
+ The manifest schema, runtime helpers and packaging command for writing Vormio plugins, plus the commands that publish a signed plugin catalog. The package is versioned with Vormio-Core (currently 0.0.7) and published to npm under the MIT license: `npm install @vormio/plugin-sdk@0.0.7`.
4
4
 
5
- Plugin contract version: `apiVersion: 1`. During development (0.0.x) there is no cross-version compatibility promise: the host loads only plugins with the same `apiVersion` as its own.
5
+ Plugin contract version: `apiVersion: 3`. During development (0.0.x) there is no cross-version compatibility promise: the host loads only plugins with the same `apiVersion` as its own.
6
6
 
7
7
  ## What a plugin can do
8
8
 
@@ -28,7 +28,7 @@ A plugin is a folder: a `manifest.json` at the root plus the built static files.
28
28
 
29
29
  ```json
30
30
  {
31
- "apiVersion": 1,
31
+ "apiVersion": 3,
32
32
  "id": "acme.model-viewer",
33
33
  "version": "0.1.0",
34
34
  "name": "Model Viewer",
@@ -78,7 +78,8 @@ Reading more formats or companion formats, or adding an extension point, require
78
78
  ```ts
79
79
  import { analyzer, readCompanion, readInput, thumbnail, viewer } from '@vormio/plugin-sdk'
80
80
 
81
- // Viewer: called first and on every file change. Returning means ready; throwing reports a failure.
81
+ // Viewer: called first and on every file change. Returning means ready; throwing reports a failure;
82
+ // returning notApplicable() hands the file to the next viewer (see below).
82
83
  viewer(async (input, signal) => {
83
84
  const bytes = await readInput(input)
84
85
  const texture = await readCompanion(input, 'textures/base.png')
@@ -114,12 +115,36 @@ analyzer(async (input) => {
114
115
  | `changed` | The file changed on disk and no longer matches the library's record | 409 |
115
116
  | `unavailable` | Any other reason, such as an offline linked folder or an expired binding | Other |
116
117
 
117
- - Pages that do not use these helpers can call `window.vormio` directly; see the `PluginBridge` type in `@vormio/plugin-sdk/bridge`. A thumbnail handler returns the PNG as an `ArrayBuffer`, and an analyzer handler (`onAnalyzeRequest`) returns the composition report.
118
+ - Pages that do not use these helpers can call `window.vormio` directly; see the `PluginBridge` type in `@vormio/plugin-sdk/bridge`. A thumbnail handler returns the PNG as an `ArrayBuffer`, and an analyzer handler (`onAnalyzeRequest`) returns the composition report; either can return `{ notApplicable: true }` instead, and a viewer calls `notApplicable(input)`.
118
119
  - While a plugin view has focus, unmodified Esc, ← and → are handled by the host (back to the grid, previous, next); the plugin does not receive these keys.
119
120
 
121
+ ## Files that are not your format
122
+
123
+ The host chooses plugins by extension only. When a format you declare is shared with other tools, such as `json`, every file with that extension comes to you. Return `notApplicable()` for the files that are not yours:
124
+
125
+ ```ts
126
+ import { analyzer, notApplicable, readInput, thumbnail, viewer } from '@vormio/plugin-sdk'
127
+
128
+ analyzer(async (input) => {
129
+ const data = JSON.parse(new TextDecoder().decode(await readInput(input)))
130
+ if (!isSkeleton(data)) return notApplicable()
131
+ return analyzeSkeleton(data)
132
+ })
133
+ ```
134
+
135
+ `thumbnail()` and `viewer()` accept the same answer.
136
+
137
+ - It is not a failure. The host records no reason and shows nothing for it:
138
+ - an analyzer's file gets no composition section;
139
+ - thumbnails and viewers move on to the next enabled plugin for the format, then to the built-in preview or the type icon.
140
+ - The host asks each extension point about each file version once. It asks again when the file changes or your plugin's code changes, so a plugin loaded from a development folder is asked again after every reload.
141
+ - Decide from the file alone; companion files read before answering are not tracked. Decide from the start of the file when you can (the input supports Range requests): a viewer's user waits for the answer before seeing the built-in preview.
142
+ - A file that is your format but has a problem should throw, or report diagnostics, so the user sees why.
143
+ - When several enabled plugins declare a format, the host asks them in order of plugin ID. Thumbnails and viewers ask the next one after a `notApplicable()`; analyzers ask only the first.
144
+
120
145
  ## Analyzers
121
146
 
122
- Once a plugin is enabled in a library, the host analyzes its declared formats in the background. Matching files join the queue when linking and scanning find new files or versions, when the plugin is enabled, and when the plugin's code changes. The file whose details the user is viewing goes first, and the user can also re-analyze manually. At most 2 analyses run at once, each with a 30-second timeout. A thrown error, a timeout or an invalid report counts as a failed analysis and shows the reason; the same plugin code is not retried on the same file version.
147
+ Once a plugin is enabled in a library, the host analyzes its declared formats in the background. Matching files join the queue when linking and scanning find new files or versions, when the plugin is enabled, and when the plugin's code changes. The file whose details the user is viewing goes first, and the user can also re-analyze manually. At most 2 analyses run at once, each with a 30-second timeout. A thrown error, a timeout or an invalid report counts as a failed analysis and shows the reason; the same plugin code is not retried on the same file version. For files that are not your format, return `notApplicable()` (see [Files that are not your format](#files-that-are-not-your-format)).
123
148
 
124
149
  A report describes one version of the analyzed file:
125
150
 
@@ -139,6 +164,7 @@ interface CompositionReport {
139
164
  key?: string // Points to a subresource in this file; give exactly one of uri and key
140
165
  role: string // Display role, e.g. "Base color texture"
141
166
  evidence?: string // Location in the file, e.g. "/images/2/uri"
167
+ inferred?: string // Not written in the file: how you inferred it, e.g. "Same name as the skeleton"
142
168
  }[]
143
169
  /** Problems found during analysis, at most 500. */
144
170
  diagnostics: { severity: 'error' | 'warning' | 'info'; message: string; key?: string }[]
@@ -147,12 +173,37 @@ interface CompositionReport {
147
173
  }
148
174
  ```
149
175
 
150
- - The host validates reports with `compositionReportSchema` (`parseReport` also checks the size); plugins can check themselves against the same schema before returning. The report serialized as JSON is at most 4 MiB (counted in UTF-8 bytes). Names and keys are at most 200 characters, kinds and roles 80, evidence 300, diagnostics 500 and addresses 2,048. Names, kinds, roles and evidence must not contain control characters.
151
- - The report is invalid if it has duplicate keys, a `parent`, `from` or `key` that points to a missing subresource, a cyclic hierarchy, or a reference with both or neither of `uri` and `key`.
176
+ - The host validates reports with `compositionReportSchema` (`parseReport` also checks the size); plugins can check themselves against the same schema before returning. The report serialized as JSON is at most 4 MiB (counted in UTF-8 bytes). Names and keys are at most 200 characters, kinds and roles 80, bases of inference 120, evidence 300, diagnostics 500 and addresses 2,048. Names, kinds, roles, bases of inference and evidence must not contain control characters.
177
+ - The report is invalid if it has duplicate keys, a `parent`, `from` or `key` that points to a missing subresource, a cyclic hierarchy, a reference with both or neither of `uri` and `key`, or an `inferred` reference with a `key`.
152
178
  - Write `uri` exactly as it appears in the file; do not resolve it yourself. The host decodes percent-encoding once, ignores everything after `?` and `#`, treats `\` as `/`, resolves it relative to the analyzed file and classifies it: a file in the linked folder, out of bounds (`..` leaving the linked folder), embedded (`data:`), external (absolute paths, drive letters, other schemes) or invalid (undecodable, containing control characters, or pointing to a folder). Whether the target exists is decided by the host at query time.
153
179
  - For embedded data (`data:`), report only the header up to the comma, e.g. `data:image/png;base64`. The host classifies it as embedded by prefix and does not store the content; a full `data:` address often exceeds 2,048 characters and would invalidate the whole report.
154
180
  - Reporting a reference does not require reading the target file, so you do not need `companionFormats` just to report references. Declare them only when the analysis actually reads companion files.
155
181
 
182
+ ### Inferred references
183
+
184
+ Some formats pair files by convention rather than by an address in the file. A Spine skeleton does not name its atlas; the runtime pairs `hero.json` with `hero.atlas` because they share a name. Report such a relation as an inferred reference, with the basis of the inference in `inferred`:
185
+
186
+ ```ts
187
+ analyzer(async (input) => {
188
+ const skeleton = parseSkeleton(await readInput(input))
189
+ const atlas = `${input.name.replace(/\.[^.]*$/, '')}.atlas`
190
+ return {
191
+ ...skeleton.report,
192
+ references: [
193
+ ...skeleton.report.references,
194
+ { uri: atlas, role: 'Atlas', inferred: 'Same name as the skeleton' },
195
+ ],
196
+ }
197
+ })
198
+ ```
199
+
200
+ - Mark a reference as inferred only when the file does not write the address. References read from the file stay as they are.
201
+ - The basis is shown to the user as is. Say why you think the relation exists, not where it is.
202
+ - Write the address relative to the analyzed file and do not check that the target exists: the host decides at query time, so a target that appears or disappears needs no new analysis.
203
+ - The host shows inferred references apart from written ones. A missing target is shown as "not found": it does not count as a missing reference, does not appear in the missing references filter and gets no note about where a moved file went, because the convention may simply not apply.
204
+ - The inference may depend on the file's name. When an analyzed file with inferred references is renamed or moved, the host analyzes it again.
205
+ - Do not report the same target both as written and as inferred.
206
+
156
207
  ## Packaging and development
157
208
 
158
209
  The package declares `"sideEffects": false`: when a plugin page uses only the runtime helpers, bundlers (esbuild, Vite, Rollup, webpack) drop the manifest schema and its zod dependency, leaving about 1 KB of runtime code for a minimal page. Node-side packaging and validation are imported from `@vormio/plugin-sdk/node`.
@@ -165,6 +216,8 @@ The command validates the manifest and every file, then writes a zip-format `.vo
165
216
 
166
217
  During development, open the **插件** (Plugins) page in Vormio, choose **添加开发目录…** (Add development folder…) and point it at the build output folder. The host watches the folder: every change is validated again, and a valid build reloads the plugin. If validation fails, the last valid version stays loaded and the error is shown on the plugin card. Vormio never runs build commands.
167
218
 
219
+ When the host lacks something your plugin needs, or behaves wrongly, open an issue at [Vormio/Vormio-Core](https://github.com/Vormio/Vormio-Core/issues) with the plugin request template: the scenario, the plugin capability it blocks, what you expect, and how to tell it works. Host capabilities are added in a generic form, never for one format. A contract change may first ship as a prerelease under the npm tag `next` (`npm install @vormio/plugin-sdk@next`) so you can try it; `latest` follows Vormio releases.
220
+
168
221
  ## Plugin catalogs
169
222
 
170
223
  A plugin catalog is a signed `catalog.json` plus the plugin packages it lists, on static hosting. Vormio installs and updates plugins from it. Publishers produce one with two commands:
package/dist/bridge.d.ts CHANGED
@@ -39,6 +39,11 @@ export interface ReportReference {
39
39
  role: string;
40
40
  /** Where in the file the reference is, such as "/images/2/uri". */
41
41
  evidence?: string;
42
+ /**
43
+ * The reference is not written in the file: how the analyzer inferred it, shown to the user, such
44
+ * as "Same name as the skeleton". Only with `uri`. A missing target is "not found", not missing.
45
+ */
46
+ inferred?: string;
42
47
  }
43
48
  export interface ReportDiagnostic {
44
49
  severity: 'error' | 'warning' | 'info';
@@ -54,6 +59,16 @@ export interface CompositionReport {
54
59
  /** The analyzer could only finish part of the file. */
55
60
  partial?: boolean;
56
61
  }
62
+ /**
63
+ * A handler's answer for a file that is not its format, such as a JSON file that is no skeleton.
64
+ * It is not a failure: the host shows nothing for it and does not ask again about this version of
65
+ * the file until the plugin's code changes.
66
+ */
67
+ export interface NotApplicable {
68
+ notApplicable: true;
69
+ }
70
+ /** Whether a handler's answer is exactly `{ notApplicable: true }`. */
71
+ export declare function isNotApplicable(value: unknown): value is NotApplicable;
57
72
  /** The frozen object the host's plugin preload exposes as `window.vormio`. */
58
73
  export interface PluginBridge {
59
74
  /** The viewer's current input. */
@@ -64,13 +79,22 @@ export interface PluginBridge {
64
79
  ready(input: PluginInput): void;
65
80
  /** The viewer cannot show `input`; the host shows `message` as plain text. */
66
81
  fail(input: PluginInput, message: string): void;
82
+ /**
83
+ * `input` is not the viewer's format; the host moves on to the next viewer or the built-in
84
+ * preview.
85
+ */
86
+ notApplicable(input: PluginInput): void;
67
87
  /**
68
88
  * Thumbnail pages: handles each request from the host and returns PNG bytes no larger than
69
- * `maxEdge` on either side. (Blobs cannot cross the bridge; `thumbnail()` converts them.)
89
+ * `maxEdge` on either side, or `{ notApplicable: true }`. (Blobs cannot cross the bridge;
90
+ * `thumbnail()` converts them.)
70
91
  */
71
92
  onThumbnailRequest(handler: (input: PluginInput, size: {
72
93
  maxEdge: number;
73
- }) => Promise<ArrayBuffer>): void;
74
- /** Analyzer pages: handles each request from the host and returns the composition report. */
75
- onAnalyzeRequest(handler: (input: PluginInput) => Promise<CompositionReport>): void;
94
+ }) => Promise<ArrayBuffer | NotApplicable>): void;
95
+ /**
96
+ * Analyzer pages: handles each request from the host and returns the composition report, or
97
+ * `{ notApplicable: true }`.
98
+ */
99
+ onAnalyzeRequest(handler: (input: PluginInput) => Promise<CompositionReport | NotApplicable>): void;
76
100
  }
package/dist/bridge.js CHANGED
@@ -1,2 +1,11 @@
1
- // Types shared by plugin pages and the host's plugin preload. No DOM types, so Node code can use them.
2
- export {};
1
+ // Types shared by plugin pages and the host's plugin preload, and one check free of schemas that the
2
+ // preload uses. No DOM types, so Node code can use them.
3
+ /** Whether a handler's answer is exactly `{ notApplicable: true }`. */
4
+ export function isNotApplicable(value) {
5
+ if (typeof value !== 'object' || value === null || Array.isArray(value))
6
+ return false;
7
+ const keys = Object.keys(value);
8
+ return (keys.length === 1 &&
9
+ keys[0] === 'notApplicable' &&
10
+ value.notApplicable === true);
11
+ }
package/dist/index.d.ts CHANGED
@@ -2,4 +2,4 @@ export { contributionsOf, manifestSchema, missingEntries, parseManifest, permiss
2
2
  export { checkPackageFiles, checkPackagePath, packageExtensions, packageLimits, type PackageFile, } from './package-rules.ts';
3
3
  export { compositionReportSchema, parseReport, reportLimits, type ReportResult } from './report.ts';
4
4
  export type { ReportDiagnostic, ReportReference, ReportSubresource } from './bridge.ts';
5
- export { analyzer, bridge, readCompanion, readInput, thumbnail, viewer, type CompanionResult, type CompanionStatus, type CompositionReport, type PluginBridge, type PluginInput, } from './runtime.ts';
5
+ export { analyzer, bridge, isNotApplicable, notApplicable, readCompanion, readInput, thumbnail, viewer, type CompanionResult, type CompanionStatus, type CompositionReport, type NotApplicable, type PluginBridge, type PluginInput, } from './runtime.ts';
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  export { contributionsOf, manifestSchema, missingEntries, parseManifest, permissionSummary, pluginApiVersion, } from "./manifest.js";
2
2
  export { checkPackageFiles, checkPackagePath, packageExtensions, packageLimits, } from "./package-rules.js";
3
3
  export { compositionReportSchema, parseReport, reportLimits } from "./report.js";
4
- export { analyzer, bridge, readCompanion, readInput, thumbnail, viewer, } from "./runtime.js";
4
+ export { analyzer, bridge, isNotApplicable, notApplicable, readCompanion, readInput, thumbnail, viewer, } from "./runtime.js";
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  /** The plugin contract version this SDK describes. Hosts load only plugins with this version. */
3
- export declare const pluginApiVersion = 1;
3
+ export declare const pluginApiVersion = 3;
4
4
  declare const contributionSchema: z.ZodObject<{
5
5
  id: z.ZodString;
6
6
  entry: z.ZodString;
@@ -13,7 +13,7 @@ export declare const pluginIdSchema: z.ZodString;
13
13
  /** A semantic version without build metadata. */
14
14
  export declare const versionSchema: z.ZodString;
15
15
  export declare const manifestSchema: z.ZodObject<{
16
- apiVersion: z.ZodLiteral<1>;
16
+ apiVersion: z.ZodLiteral<3>;
17
17
  id: z.ZodString;
18
18
  version: z.ZodString;
19
19
  name: z.ZodString;
package/dist/manifest.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  import { checkPackagePath } from "./package-rules.js";
3
3
  /** The plugin contract version this SDK describes. Hosts load only plugins with this version. */
4
- export const pluginApiVersion = 1;
4
+ export const pluginApiVersion = 3;
5
5
  const unique = (values) => new Set(values).size === values.length;
6
6
  const extension = z.string().regex(/^[a-z0-9]{1,16}$/, 'Use a lower-case extension without a dot');
7
7
  const extensions = (min) => z.array(extension).min(min).max(64).refine(unique, 'Extensions must not repeat');
package/dist/report.js CHANGED
@@ -27,9 +27,13 @@ const referenceSchema = z
27
27
  key: key.optional(),
28
28
  role: plain(80).min(1),
29
29
  evidence: plain(300).optional(),
30
+ inferred: plain(120).min(1).optional(),
30
31
  })
31
32
  .refine((reference) => (reference.uri === undefined) !== (reference.key === undefined), {
32
33
  message: 'Give exactly one of uri and key',
34
+ })
35
+ .refine((reference) => reference.inferred === undefined || reference.uri !== undefined, {
36
+ message: 'Only a reference with a uri can be inferred',
33
37
  });
34
38
  const diagnosticSchema = z.strictObject({
35
39
  severity: z.enum(['error', 'warning', 'info']),
package/dist/runtime.d.ts CHANGED
@@ -1,5 +1,11 @@
1
- import type { CompanionResult, CompanionStatus, CompositionReport, PluginBridge, PluginInput } from './bridge.ts';
2
- export type { CompanionResult, CompanionStatus, CompositionReport, PluginBridge, PluginInput };
1
+ import { isNotApplicable, type CompanionResult, type CompanionStatus, type CompositionReport, type NotApplicable, type PluginBridge, type PluginInput } from './bridge.ts';
2
+ export type { CompanionResult, CompanionStatus, CompositionReport, NotApplicable, PluginBridge, PluginInput, };
3
+ export { isNotApplicable };
4
+ /**
5
+ * The answer for a file that is not this handler's format. Return it from a viewer, thumbnail or
6
+ * analyzer handler; a file of your format with a problem should throw instead, so the user sees why.
7
+ */
8
+ export declare function notApplicable(): NotApplicable;
3
9
  /** The host bridge; throws outside a Vormio plugin page. */
4
10
  export declare function bridge(): PluginBridge;
5
11
  /**
@@ -11,16 +17,17 @@ export declare function readCompanion(input: PluginInput, relativePath: string):
11
17
  export declare function readInput(input: PluginInput): Promise<ArrayBuffer>;
12
18
  /**
13
19
  * Runs a viewer: `show` is called for the first input and again whenever the host moves to another
14
- * file, with the previous call's signal aborted. Resolving reports ready; throwing reports the
15
- * error message.
20
+ * file, with the previous call's signal aborted. Resolving reports ready, resolving with
21
+ * `notApplicable()` reports the file is not this viewer's format, and throwing reports the error
22
+ * message.
16
23
  */
17
- export declare function viewer(show: (input: PluginInput, signal: AbortSignal) => Promise<void>): void;
18
- /** Runs a thumbnail provider; a canvas is converted to PNG. */
24
+ export declare function viewer(show: (input: PluginInput, signal: AbortSignal) => Promise<void | NotApplicable>): void;
25
+ /** Runs a thumbnail provider; a canvas is converted to PNG. `render` may return `notApplicable()`. */
19
26
  export declare function thumbnail(render: (input: PluginInput, size: {
20
27
  maxEdge: number;
21
- }) => Promise<Blob | HTMLCanvasElement | OffscreenCanvas>): void;
28
+ }) => Promise<Blob | HTMLCanvasElement | OffscreenCanvas | NotApplicable>): void;
22
29
  /**
23
30
  * Runs an analyzer: `analyze` is called once per request and returns the composition report of
24
- * the input. Throwing reports the analysis as failed with the error message.
31
+ * the input, or `notApplicable()`. Throwing reports the analysis as failed with the error message.
25
32
  */
26
- export declare function analyzer(analyze: (input: PluginInput) => Promise<CompositionReport>): void;
33
+ export declare function analyzer(analyze: (input: PluginInput) => Promise<CompositionReport | NotApplicable>): void;
package/dist/runtime.js CHANGED
@@ -1,3 +1,12 @@
1
+ import { isNotApplicable, } from "./bridge.js";
2
+ export { isNotApplicable };
3
+ /**
4
+ * The answer for a file that is not this handler's format. Return it from a viewer, thumbnail or
5
+ * analyzer handler; a file of your format with a problem should throw instead, so the user sees why.
6
+ */
7
+ export function notApplicable() {
8
+ return { notApplicable: true };
9
+ }
1
10
  /** The host bridge; throws outside a Vormio plugin page. */
2
11
  export function bridge() {
3
12
  const host = globalThis.vormio;
@@ -38,8 +47,9 @@ export async function readInput(input) {
38
47
  }
39
48
  /**
40
49
  * Runs a viewer: `show` is called for the first input and again whenever the host moves to another
41
- * file, with the previous call's signal aborted. Resolving reports ready; throwing reports the
42
- * error message.
50
+ * file, with the previous call's signal aborted. Resolving reports ready, resolving with
51
+ * `notApplicable()` reports the file is not this viewer's format, and throwing reports the error
52
+ * message.
43
53
  */
44
54
  export function viewer(show) {
45
55
  const host = bridge();
@@ -49,8 +59,12 @@ export function viewer(show) {
49
59
  const controller = new AbortController();
50
60
  current = controller;
51
61
  try {
52
- await show(input, controller.signal);
53
- if (!controller.signal.aborted)
62
+ const result = await show(input, controller.signal);
63
+ if (controller.signal.aborted)
64
+ return;
65
+ if (isNotApplicable(result))
66
+ host.notApplicable(input);
67
+ else
54
68
  host.ready(input);
55
69
  }
56
70
  catch (error) {
@@ -61,10 +75,12 @@ export function viewer(show) {
61
75
  host.onInput((input) => void run(input));
62
76
  void host.getInput().then(run);
63
77
  }
64
- /** Runs a thumbnail provider; a canvas is converted to PNG. */
78
+ /** Runs a thumbnail provider; a canvas is converted to PNG. `render` may return `notApplicable()`. */
65
79
  export function thumbnail(render) {
66
80
  bridge().onThumbnailRequest(async (input, size) => {
67
81
  const result = await render(input, size);
82
+ if (isNotApplicable(result))
83
+ return result;
68
84
  let blob;
69
85
  if (result instanceof Blob)
70
86
  blob = result;
@@ -77,7 +93,7 @@ export function thumbnail(render) {
77
93
  }
78
94
  /**
79
95
  * Runs an analyzer: `analyze` is called once per request and returns the composition report of
80
- * the input. Throwing reports the analysis as failed with the error message.
96
+ * the input, or `notApplicable()`. Throwing reports the analysis as failed with the error message.
81
97
  */
82
98
  export function analyzer(analyze) {
83
99
  bridge().onAnalyzeRequest(analyze);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vormio/plugin-sdk",
3
- "version": "0.0.5",
3
+ "version": "0.0.7-rc.1",
4
4
  "description": "Manifest schema, runtime helpers and packaging for Vormio plugins.",
5
5
  "license": "MIT",
6
6
  "keywords": [