@openvcs/sdk 0.2.15 → 0.2.16

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
@@ -6,8 +6,8 @@
6
6
 
7
7
  OpenVCS SDK for npm-based plugin development.
8
8
 
9
- Install this package in plugin projects, scaffold a starter plugin, and package
10
- plugins into `.ovcsp` bundles. The SDK also exports a Node-only JSON-RPC runtime
9
+ Install this package in plugin projects, scaffold a starter plugin, and build
10
+ plugin runtime assets. The SDK also exports a Node-only JSON-RPC runtime
11
11
  layer and shared protocol/types so plugins do not have to hand-roll stdio
12
12
  framing or method dispatch.
13
13
 
@@ -166,19 +166,6 @@ invokes `OnPluginStart()`, and starts the runtime.
166
166
  Theme-only plugins can also run `npm run build`; the command exits successfully
167
167
  without producing `bin/` output.
168
168
 
169
- ## Build a `.ovcsp` bundle
170
-
171
- In a generated plugin folder:
172
-
173
- ```bash
174
- npm run dist
175
- ```
176
-
177
- This produces `dist/<plugin-id>.ovcsp`.
178
-
179
- `openvcs dist` runs `openvcs build` first unless `--no-build` is provided.
180
- Use `--no-build` when packaging prebuilt plugin assets.
181
-
182
169
  Generated code plugin scripts use this split by default:
183
170
 
184
171
  ```json
@@ -186,7 +173,7 @@ Generated code plugin scripts use this split by default:
186
173
  "scripts": {
187
174
  "build:plugin": "tsc -p tsconfig.json",
188
175
  "build": "openvcs build",
189
- "dist": "openvcs dist --plugin-dir . --out dist"
176
+ "test": "npm run build"
190
177
  }
191
178
  }
192
179
  ```
@@ -194,33 +181,26 @@ Generated code plugin scripts use this split by default:
194
181
  For code plugins, reserve `bin/plugin.js` for the compiled author module and point
195
182
  `module.exec` at a different bootstrap filename such as `openvcs-plugin.js`.
196
183
 
197
- `.ovcsp` is a gzip-compressed tar archive (`tar.gz`) that contains a top-level
198
- `<plugin-id>/` directory with `openvcs.plugin.json` and plugin runtime assets.
199
-
200
- Bundle contents:
201
- - `openvcs.plugin.json` (required)
184
+ Plugin package contents should include:
185
+ - `package.json` with an `openvcs` object (required)
202
186
  - `icon.*` (optional, first found by extension priority)
203
187
  - `bin/` (required for code plugins with `module.exec`)
204
188
  - `entry` directory (required for UI plugins with top-level `entry` field; the entire directory containing the entry file is bundled)
205
189
  - `themes/` (required for theme plugins)
206
- - `node_modules/` (if npm dependencies are bundled)
190
+ - runtime dependencies installable from `dependencies`
207
191
 
208
- Dependency behavior while packaging:
192
+ Dependency behavior:
209
193
 
210
- - npm dependency bundling is enabled by default when `package.json` exists.
211
- - If `package-lock.json` is missing, SDK generates it in the staging area (not the plugin worktree).
212
- - Dependencies are installed into the bundle staging dir with:
213
- - `npm ci --omit=dev --ignore-scripts --no-bin-links --no-audit --no-fund`
214
- - Disable npm dependency processing with `--no-npm-deps`.
215
- - Native Node addons (`*.node`) are rejected for portable bundles.
194
+ - OpenVCS installs runtime dependencies from `dependencies` when resolving a plugin source.
195
+ - Keep runtime-only packages out of `devDependencies`.
196
+ - Native Node addons (`*.node`) are not portable and should be avoided.
216
197
 
217
198
  ## CLI usage
218
199
 
219
- Package a plugin manually:
200
+ Build a plugin manually:
220
201
 
221
202
  ```bash
222
203
  npx openvcs build --plugin-dir /path/to/plugin
223
- npx openvcs dist --plugin-dir /path/to/plugin --out /path/to/dist
224
204
  ```
225
205
 
226
206
  Show command help:
@@ -228,16 +208,13 @@ Show command help:
228
208
  ```bash
229
209
  npx openvcs --help
230
210
  npx openvcs build --help
231
- npx openvcs dist --help
232
211
  npx openvcs init --help
233
212
  ```
234
213
 
235
- ## Releases
236
-
237
- Stable releases are published from `.github/workflows/release.yml`.
214
+ ## Publishing Note
238
215
 
239
- - npm publishes use npm Trusted Publishing (OIDC), so no `NPM_TOKEN` is required.
240
- - `npm prepack` compiles TypeScript so published packages include `bin/` and `lib/` JS outputs.
216
+ Publishing is outside the SDK CLI. Use your normal npm workflow once `openvcs build`
217
+ has produced the runtime assets you want to ship.
241
218
 
242
219
  ## License
243
220
 
package/lib/build.js CHANGED
@@ -34,7 +34,7 @@ function shouldUseWindowsShell(program) {
34
34
  }
35
35
  /** Formats help text for the build command. */
36
36
  function buildUsage(commandName = "openvcs") {
37
- return `${commandName} build [args]\n\n --plugin-dir <path> Plugin repository root (contains openvcs.plugin.json)\n -V, --verbose Enable verbose output\n`;
37
+ return `${commandName} build [args]\n\n --plugin-dir <path> Plugin repository root (contains package.json with openvcs metadata)\n -V, --verbose Enable verbose output\n`;
38
38
  }
39
39
  /** Parses `openvcs build` arguments. */
40
40
  function parseBuildArgs(args) {
@@ -68,7 +68,7 @@ function parseBuildArgs(args) {
68
68
  }
69
69
  /** Reads and validates the plugin manifest. */
70
70
  function readManifest(pluginDir) {
71
- const manifestPath = path.join(pluginDir, "openvcs.plugin.json");
71
+ const manifestPath = path.join(pluginDir, "package.json");
72
72
  let manifestRaw;
73
73
  let manifestFd;
74
74
  let manifest;
@@ -76,13 +76,13 @@ function readManifest(pluginDir) {
76
76
  manifestFd = fs.openSync(manifestPath, "r");
77
77
  const manifestStat = fs.fstatSync(manifestFd);
78
78
  if (!manifestStat.isFile()) {
79
- throw new Error(`missing openvcs.plugin.json at ${manifestPath}`);
79
+ throw new Error(`missing package.json at ${manifestPath}`);
80
80
  }
81
81
  manifestRaw = fs.readFileSync(manifestFd, "utf8");
82
82
  }
83
83
  catch (error) {
84
84
  if (error.code === "ENOENT") {
85
- throw new Error(`missing openvcs.plugin.json at ${manifestPath}`);
85
+ throw new Error(`missing package.json at ${manifestPath}`);
86
86
  }
87
87
  throw error;
88
88
  }
@@ -98,18 +98,22 @@ function readManifest(pluginDir) {
98
98
  const detail = error instanceof Error ? error.message : String(error);
99
99
  throw new Error(`parse ${manifestPath}: ${detail}`);
100
100
  }
101
- const pluginId = typeof manifest.id === "string"
102
- ? manifest.id.trim()
101
+ const openvcs = manifest.openvcs;
102
+ if (!openvcs || typeof openvcs !== "object") {
103
+ throw new Error(`package.json ${manifestPath} is missing an 'openvcs' object`);
104
+ }
105
+ const pluginId = typeof openvcs.id === "string"
106
+ ? openvcs.id.trim()
103
107
  : "";
104
108
  if (!pluginId) {
105
- throw new Error(`manifest ${manifestPath} is missing a string 'id'`);
109
+ throw new Error(`package.json ${manifestPath} is missing openvcs.id`);
106
110
  }
107
111
  if (pluginId === "." || pluginId === ".." || pluginId.includes("/") || pluginId.includes("\\")) {
108
112
  throw new Error(`manifest id must not contain path separators: ${pluginId}`);
109
113
  }
110
- const moduleValue = manifest.module;
114
+ const moduleValue = openvcs.module;
111
115
  const moduleExec = typeof moduleValue?.exec === "string" ? moduleValue.exec.trim() : undefined;
112
- const entryValue = manifest.entry;
116
+ const entryValue = openvcs.entry;
113
117
  const entry = typeof entryValue === "string" ? entryValue.trim() : undefined;
114
118
  return {
115
119
  pluginId,
package/lib/cli.js CHANGED
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.runCli = runCli;
4
4
  const build_1 = require("./build");
5
- const dist_1 = require("./dist");
6
5
  const init_1 = require("./init");
7
6
  const packageJson = require("../package.json");
8
7
  function hasCode(error, code) {
@@ -12,7 +11,7 @@ function hasCode(error, code) {
12
11
  error.code === code);
13
12
  }
14
13
  function usage() {
15
- return "Usage: openvcs <command> [options]\n\nCommands:\n build [args] Build plugin runtime assets\n dist [args] Package plugin into .ovcsp\n init [--theme] [dir] Interactively scaffold a plugin project\n -v, --version Show version information\n\nBuild args:\n --plugin-dir <path> Plugin root containing openvcs.plugin.json\n -V, --verbose Verbose output\n\nDist args:\n --plugin-dir <path> Plugin root containing openvcs.plugin.json\n --out <path> Output directory (default: ./dist)\n --no-build Skip plugin build before packaging\n --no-npm-deps Skip npm dependency bundling\n -V, --verbose Verbose output\n";
14
+ return "Usage: openvcs <command> [options]\n\nCommands:\n build [args] Build plugin runtime assets\n init [--theme] [dir] Interactively scaffold a plugin project\n -v, --version Show version information\n\nBuild args:\n --plugin-dir <path> Plugin root containing package.json with openvcs metadata\n -V, --verbose Verbose output\n";
16
15
  }
17
16
  async function runCli(args) {
18
17
  if (args.length === 0) {
@@ -29,24 +28,6 @@ async function runCli(args) {
29
28
  process.stdout.write(usage());
30
29
  return;
31
30
  }
32
- if (command === "dist") {
33
- if (rest.includes("--help")) {
34
- process.stdout.write((0, dist_1.distUsage)());
35
- return;
36
- }
37
- try {
38
- const parsed = (0, dist_1.parseDistArgs)(rest);
39
- const outPath = await (0, dist_1.bundlePlugin)(parsed);
40
- process.stdout.write(`${outPath}\n`);
41
- return;
42
- }
43
- catch (error) {
44
- if (hasCode(error, "USAGE")) {
45
- throw new Error((0, dist_1.distUsage)());
46
- }
47
- throw error;
48
- }
49
- }
50
31
  if (command === "build") {
51
32
  if (rest.includes("--help")) {
52
33
  process.stdout.write((0, build_1.buildUsage)());
package/lib/init.js CHANGED
@@ -183,13 +183,6 @@ function runNpmInstall(targetDir) {
183
183
  }
184
184
  }
185
185
  function writeCommonFiles(answers) {
186
- writeJson(path.join(answers.targetDir, "openvcs.plugin.json"), {
187
- id: answers.pluginId,
188
- name: answers.pluginName,
189
- version: answers.pluginVersion,
190
- default_enabled: answers.defaultEnabled,
191
- ...(answers.kind === "module" ? { module: { exec: "openvcs-plugin.js" } } : {}),
192
- });
193
186
  writeText(path.join(answers.targetDir, ".gitignore"), "node_modules/\ndist/\n");
194
187
  }
195
188
  function writeModuleTemplate(answers) {
@@ -199,11 +192,17 @@ function writeModuleTemplate(answers) {
199
192
  version: answers.pluginVersion,
200
193
  private: true,
201
194
  type: "module",
195
+ openvcs: {
196
+ id: answers.pluginId,
197
+ name: answers.pluginName,
198
+ version: answers.pluginVersion,
199
+ default_enabled: answers.defaultEnabled,
200
+ module: { exec: "openvcs-plugin.js" },
201
+ },
202
202
  scripts: {
203
203
  "build:plugin": "tsc -p tsconfig.json",
204
204
  build: "openvcs build",
205
- dist: "openvcs dist --plugin-dir . --out dist",
206
- test: "openvcs dist --plugin-dir . --out dist --no-build --no-npm-deps",
205
+ test: "npm run build",
207
206
  },
208
207
  dependencies: {
209
208
  "@openvcs/sdk": `^${packageJson.version}`,
@@ -234,10 +233,15 @@ function writeThemeTemplate(answers) {
234
233
  name: answers.pluginId,
235
234
  version: answers.pluginVersion,
236
235
  private: true,
236
+ openvcs: {
237
+ id: answers.pluginId,
238
+ name: answers.pluginName,
239
+ version: answers.pluginVersion,
240
+ default_enabled: answers.defaultEnabled,
241
+ },
237
242
  scripts: {
238
243
  build: "openvcs build",
239
- dist: "openvcs dist --plugin-dir . --out dist",
240
- test: "openvcs dist --plugin-dir . --out dist --no-build --no-npm-deps",
244
+ test: "npm run build",
241
245
  },
242
246
  dependencies: {
243
247
  "@openvcs/sdk": `^${packageJson.version}`,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@openvcs/sdk",
3
- "version": "0.2.15",
4
- "description": "OpenVCS SDK CLI for plugin scaffolding and .ovcsp tar.gz packaging",
3
+ "version": "0.2.16",
4
+ "description": "OpenVCS SDK CLI for plugin scaffolding and runtime asset builds",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "homepage": "https://openvcs.app/",
7
7
  "repository": {
package/src/lib/build.ts CHANGED
@@ -51,7 +51,7 @@ export function shouldUseWindowsShell(program: string): boolean {
51
51
 
52
52
  /** Formats help text for the build command. */
53
53
  export function buildUsage(commandName = "openvcs"): string {
54
- return `${commandName} build [args]\n\n --plugin-dir <path> Plugin repository root (contains openvcs.plugin.json)\n -V, --verbose Enable verbose output\n`;
54
+ return `${commandName} build [args]\n\n --plugin-dir <path> Plugin repository root (contains package.json with openvcs metadata)\n -V, --verbose Enable verbose output\n`;
55
55
  }
56
56
 
57
57
  /** Parses `openvcs build` arguments. */
@@ -89,7 +89,7 @@ export function parseBuildArgs(args: string[]): BuildArgs {
89
89
 
90
90
  /** Reads and validates the plugin manifest. */
91
91
  export function readManifest(pluginDir: string): ManifestInfo {
92
- const manifestPath = path.join(pluginDir, "openvcs.plugin.json");
92
+ const manifestPath = path.join(pluginDir, "package.json");
93
93
  let manifestRaw: string;
94
94
  let manifestFd: number | undefined;
95
95
  let manifest: unknown;
@@ -97,12 +97,12 @@ export function readManifest(pluginDir: string): ManifestInfo {
97
97
  manifestFd = fs.openSync(manifestPath, "r");
98
98
  const manifestStat = fs.fstatSync(manifestFd);
99
99
  if (!manifestStat.isFile()) {
100
- throw new Error(`missing openvcs.plugin.json at ${manifestPath}`);
100
+ throw new Error(`missing package.json at ${manifestPath}`);
101
101
  }
102
102
  manifestRaw = fs.readFileSync(manifestFd, "utf8");
103
103
  } catch (error: unknown) {
104
104
  if ((error as NodeJS.ErrnoException).code === "ENOENT") {
105
- throw new Error(`missing openvcs.plugin.json at ${manifestPath}`);
105
+ throw new Error(`missing package.json at ${manifestPath}`);
106
106
  }
107
107
  throw error;
108
108
  } finally {
@@ -118,21 +118,28 @@ export function readManifest(pluginDir: string): ManifestInfo {
118
118
  throw new Error(`parse ${manifestPath}: ${detail}`);
119
119
  }
120
120
 
121
+ const openvcs = (manifest as { openvcs?: unknown }).openvcs as
122
+ | { id?: unknown; module?: { exec?: unknown }; entry?: unknown }
123
+ | undefined;
124
+ if (!openvcs || typeof openvcs !== "object") {
125
+ throw new Error(`package.json ${manifestPath} is missing an 'openvcs' object`);
126
+ }
127
+
121
128
  const pluginId =
122
- typeof (manifest as { id?: unknown }).id === "string"
123
- ? ((manifest as { id: string }).id.trim() as string)
129
+ typeof openvcs.id === "string"
130
+ ? (openvcs.id.trim() as string)
124
131
  : "";
125
132
  if (!pluginId) {
126
- throw new Error(`manifest ${manifestPath} is missing a string 'id'`);
133
+ throw new Error(`package.json ${manifestPath} is missing openvcs.id`);
127
134
  }
128
135
  if (pluginId === "." || pluginId === ".." || pluginId.includes("/") || pluginId.includes("\\")) {
129
136
  throw new Error(`manifest id must not contain path separators: ${pluginId}`);
130
137
  }
131
138
 
132
- const moduleValue = (manifest as { module?: { exec?: unknown } }).module;
139
+ const moduleValue = openvcs.module;
133
140
  const moduleExec = typeof moduleValue?.exec === "string" ? moduleValue.exec.trim() : undefined;
134
141
 
135
- const entryValue = (manifest as { entry?: unknown }).entry;
142
+ const entryValue = openvcs.entry;
136
143
  const entry = typeof entryValue === "string" ? entryValue.trim() : undefined;
137
144
 
138
145
  return {
package/src/lib/cli.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { buildPluginAssets, buildUsage, parseBuildArgs } from "./build";
2
- import { bundlePlugin, distUsage, parseDistArgs } from "./dist";
3
2
  import { initUsage, runInitCommand } from "./init";
4
3
 
5
4
  const packageJson: { version: string } = require("../package.json");
@@ -18,7 +17,7 @@ function hasCode(error: unknown, code: string): boolean {
18
17
  }
19
18
 
20
19
  function usage(): string {
21
- return "Usage: openvcs <command> [options]\n\nCommands:\n build [args] Build plugin runtime assets\n dist [args] Package plugin into .ovcsp\n init [--theme] [dir] Interactively scaffold a plugin project\n -v, --version Show version information\n\nBuild args:\n --plugin-dir <path> Plugin root containing openvcs.plugin.json\n -V, --verbose Verbose output\n\nDist args:\n --plugin-dir <path> Plugin root containing openvcs.plugin.json\n --out <path> Output directory (default: ./dist)\n --no-build Skip plugin build before packaging\n --no-npm-deps Skip npm dependency bundling\n -V, --verbose Verbose output\n";
20
+ return "Usage: openvcs <command> [options]\n\nCommands:\n build [args] Build plugin runtime assets\n init [--theme] [dir] Interactively scaffold a plugin project\n -v, --version Show version information\n\nBuild args:\n --plugin-dir <path> Plugin root containing package.json with openvcs metadata\n -V, --verbose Verbose output\n";
22
21
  }
23
22
 
24
23
  export async function runCli(args: string[]): Promise<void> {
@@ -39,24 +38,6 @@ export async function runCli(args: string[]): Promise<void> {
39
38
  return;
40
39
  }
41
40
 
42
- if (command === "dist") {
43
- if (rest.includes("--help")) {
44
- process.stdout.write(distUsage());
45
- return;
46
- }
47
- try {
48
- const parsed = parseDistArgs(rest);
49
- const outPath = await bundlePlugin(parsed);
50
- process.stdout.write(`${outPath}\n`);
51
- return;
52
- } catch (error: unknown) {
53
- if (hasCode(error, "USAGE")) {
54
- throw new Error(distUsage());
55
- }
56
- throw error;
57
- }
58
- }
59
-
60
41
  if (command === "build") {
61
42
  if (rest.includes("--help")) {
62
43
  process.stdout.write(buildUsage());
package/src/lib/init.ts CHANGED
@@ -228,13 +228,6 @@ function runNpmInstall(targetDir: string): void {
228
228
  }
229
229
 
230
230
  function writeCommonFiles(answers: InitAnswers): void {
231
- writeJson(path.join(answers.targetDir, "openvcs.plugin.json"), {
232
- id: answers.pluginId,
233
- name: answers.pluginName,
234
- version: answers.pluginVersion,
235
- default_enabled: answers.defaultEnabled,
236
- ...(answers.kind === "module" ? { module: { exec: "openvcs-plugin.js" } } : {}),
237
- });
238
231
  writeText(path.join(answers.targetDir, ".gitignore"), "node_modules/\ndist/\n");
239
232
  }
240
233
 
@@ -245,11 +238,17 @@ function writeModuleTemplate(answers: InitAnswers): void {
245
238
  version: answers.pluginVersion,
246
239
  private: true,
247
240
  type: "module",
241
+ openvcs: {
242
+ id: answers.pluginId,
243
+ name: answers.pluginName,
244
+ version: answers.pluginVersion,
245
+ default_enabled: answers.defaultEnabled,
246
+ module: { exec: "openvcs-plugin.js" },
247
+ },
248
248
  scripts: {
249
249
  "build:plugin": "tsc -p tsconfig.json",
250
250
  build: "openvcs build",
251
- dist: "openvcs dist --plugin-dir . --out dist",
252
- test: "openvcs dist --plugin-dir . --out dist --no-build --no-npm-deps",
251
+ test: "npm run build",
253
252
  },
254
253
  dependencies: {
255
254
  "@openvcs/sdk": `^${packageJson.version}`,
@@ -284,10 +283,15 @@ function writeThemeTemplate(answers: InitAnswers): void {
284
283
  name: answers.pluginId,
285
284
  version: answers.pluginVersion,
286
285
  private: true,
286
+ openvcs: {
287
+ id: answers.pluginId,
288
+ name: answers.pluginName,
289
+ version: answers.pluginVersion,
290
+ default_enabled: answers.defaultEnabled,
291
+ },
287
292
  scripts: {
288
293
  build: "openvcs build",
289
- dist: "openvcs dist --plugin-dir . --out dist",
290
- test: "openvcs dist --plugin-dir . --out dist --no-build --no-npm-deps",
294
+ test: "npm run build",
291
295
  },
292
296
  dependencies: {
293
297
  "@openvcs/sdk": `^${packageJson.version}`,
@@ -52,7 +52,10 @@ test("buildPluginAssets no-ops for theme-only plugins", () => {
52
52
  const root = makeTempDir("openvcs-sdk-test");
53
53
  const pluginDir = path.join(root, "plugin");
54
54
 
55
- writeJson(path.join(pluginDir, "openvcs.plugin.json"), { id: "theme-only" });
55
+ writeJson(path.join(pluginDir, "package.json"), {
56
+ name: "theme-only",
57
+ openvcs: { id: "theme-only" },
58
+ });
56
59
  const manifest = buildPluginAssets({ pluginDir, verbose: false });
57
60
 
58
61
  assert.equal(manifest.pluginId, "theme-only");
@@ -63,14 +66,17 @@ test("buildPluginAssets requires package.json for code plugins", () => {
63
66
  const root = makeTempDir("openvcs-sdk-test");
64
67
  const pluginDir = path.join(root, "plugin");
65
68
 
66
- writeJson(path.join(pluginDir, "openvcs.plugin.json"), {
67
- id: "missing-package",
68
- module: { exec: "openvcs-plugin.js" },
69
+ writeJson(path.join(pluginDir, "package.json"), {
70
+ name: "missing-package",
71
+ openvcs: {
72
+ id: "missing-package",
73
+ module: { exec: "openvcs-plugin.js" },
74
+ },
69
75
  });
70
76
 
71
77
  assert.throws(
72
78
  () => buildPluginAssets({ pluginDir, verbose: false }),
73
- /code plugins must include package\.json/
79
+ /code plugins must define scripts\["build:plugin"\]/
74
80
  );
75
81
 
76
82
  cleanupTempDir(root);
@@ -80,13 +86,13 @@ test("buildPluginAssets runs build:plugin and validates output", () => {
80
86
  const root = makeTempDir("openvcs-sdk-test");
81
87
  const pluginDir = path.join(root, "plugin");
82
88
 
83
- writeJson(path.join(pluginDir, "openvcs.plugin.json"), {
84
- id: "builder",
85
- module: { exec: "openvcs-plugin.js" },
86
- });
87
89
  writeJson(path.join(pluginDir, "package.json"), {
88
90
  name: "builder",
89
91
  private: true,
92
+ openvcs: {
93
+ id: "builder",
94
+ module: { exec: "openvcs-plugin.js" },
95
+ },
90
96
  scripts: {
91
97
  "build:plugin": "node ./scripts/build-plugin.js",
92
98
  },
@@ -112,9 +118,12 @@ test("readManifest and validateDeclaredModuleExec stay reusable", () => {
112
118
  const root = makeTempDir("openvcs-sdk-test");
113
119
  const pluginDir = path.join(root, "plugin");
114
120
 
115
- writeJson(path.join(pluginDir, "openvcs.plugin.json"), {
116
- id: "reusable",
117
- module: { exec: "openvcs-plugin.js" },
121
+ writeJson(path.join(pluginDir, "package.json"), {
122
+ name: "reusable",
123
+ openvcs: {
124
+ id: "reusable",
125
+ module: { exec: "openvcs-plugin.js" },
126
+ },
118
127
  });
119
128
  writeText(path.join(pluginDir, "bin", "plugin.js"), "export function OnPluginStart() {}\n");
120
129
  writeText(path.join(pluginDir, "bin", "openvcs-plugin.js"), "export {};\n");
@@ -163,14 +172,14 @@ test("generateModuleBootstrap handles subdirectory module.exec paths", () => {
163
172
  const root = makeTempDir("openvcs-sdk-test");
164
173
  const pluginDir = path.join(root, "plugin");
165
174
 
166
- writeJson(path.join(pluginDir, "openvcs.plugin.json"), {
167
- id: "subdir-plugin",
168
- module: { exec: "subdir/openvcs-plugin.js" },
169
- });
170
175
  writeJson(path.join(pluginDir, "package.json"), {
171
176
  name: "subdir-plugin",
172
177
  type: "module",
173
178
  private: true,
179
+ openvcs: {
180
+ id: "subdir-plugin",
181
+ module: { exec: "subdir/openvcs-plugin.js" },
182
+ },
174
183
  scripts: { "build:plugin": "node ./scripts/build.js" },
175
184
  });
176
185
  writeText(path.join(pluginDir, "bin", "plugin.js"), "export function OnPluginStart() {}\n");
@@ -191,13 +200,13 @@ test("detectEsmMode returns true for package.json type: module", () => {
191
200
  const root = makeTempDir("openvcs-sdk-test");
192
201
  const pluginDir = path.join(root, "plugin");
193
202
 
194
- writeJson(path.join(pluginDir, "openvcs.plugin.json"), {
195
- id: "esm-plugin",
196
- module: { exec: "bootstrap.js" },
197
- });
198
203
  writeJson(path.join(pluginDir, "package.json"), {
199
204
  name: "esm-plugin",
200
205
  type: "module",
206
+ openvcs: {
207
+ id: "esm-plugin",
208
+ module: { exec: "bootstrap.js" },
209
+ },
201
210
  });
202
211
  writeText(path.join(pluginDir, "bin", "plugin.js"), "export function OnPluginStart() {}\n");
203
212
  writeText(path.join(pluginDir, "bin", "bootstrap.js"), "export {};\n");
@@ -215,13 +224,13 @@ test("detectEsmMode returns false for package.json type: commonjs", () => {
215
224
  const root = makeTempDir("openvcs-sdk-test");
216
225
  const pluginDir = path.join(root, "plugin");
217
226
 
218
- writeJson(path.join(pluginDir, "openvcs.plugin.json"), {
219
- id: "cjs-plugin",
220
- module: { exec: "bootstrap.js" },
221
- });
222
227
  writeJson(path.join(pluginDir, "package.json"), {
223
228
  name: "cjs-plugin",
224
229
  type: "commonjs",
230
+ openvcs: {
231
+ id: "cjs-plugin",
232
+ module: { exec: "bootstrap.js" },
233
+ },
225
234
  });
226
235
  writeText(path.join(pluginDir, "bin", "plugin.js"), "export function OnPluginStart() {}\n");
227
236
  writeText(path.join(pluginDir, "bin", "bootstrap.js"), "export {};\n");
package/test/cli.test.js CHANGED
@@ -36,12 +36,6 @@ test("openvcs with no args exits non-zero", () => {
36
36
  assert.match(result.stderr, /Usage: openvcs <command>/);
37
37
  });
38
38
 
39
- test("openvcs dist --help prints dist usage", () => {
40
- const result = runCli(["dist", "--help"]);
41
- assert.equal(result.status, 0);
42
- assert.match(result.stdout, /openvcs dist \[args\]/);
43
- });
44
-
45
39
  test("openvcs build --help prints build usage", () => {
46
40
  const result = runCli(["build", "--help"]);
47
41
  assert.equal(result.status, 0);
@@ -60,52 +54,17 @@ test("openvcs rejects unknown command", () => {
60
54
  assert.match(result.stderr, /unknown command: unknown/);
61
55
  });
62
56
 
63
- test("openvcs dist command creates bundle", () => {
64
- const root = makeTempDir("openvcs-sdk-test");
65
- const pluginDir = path.join(root, "plugin");
66
- const outDir = path.join(root, "out");
67
-
68
- writeJson(path.join(pluginDir, "openvcs.plugin.json"), {
69
- id: "cli-plugin",
70
- module: { exec: "openvcs-plugin.js" },
71
- });
72
- writeText(path.join(pluginDir, "bin", "plugin.js"), "export function OnPluginStart() {}\n");
73
- writeText(path.join(pluginDir, "bin", "openvcs-plugin.js"), "export {};\n");
74
-
75
- const result = runCli([
76
- "dist",
77
- "--plugin-dir",
78
- pluginDir,
79
- "--out",
80
- outDir,
81
- "--no-build",
82
- "--no-npm-deps",
83
- ]);
84
-
85
- assert.equal(result.status, 0);
86
- assert.match(result.stdout.trim(), /cli-plugin\.ovcsp$/);
87
- assert.equal(fs.existsSync(path.join(outDir, "cli-plugin.ovcsp")), true);
88
-
89
- cleanupTempDir(root);
90
- });
91
-
92
- test("openvcs dist reports argument errors", () => {
93
- const result = runCli(["dist", "--plugin-dir"]);
94
- assert.equal(result.status, 1);
95
- assert.match(result.stderr, /missing value for --plugin-dir/);
96
- });
97
-
98
57
  test("openvcs build command builds code plugin assets", () => {
99
58
  const root = makeTempDir("openvcs-sdk-test");
100
59
  const pluginDir = path.join(root, "plugin");
101
60
 
102
- writeJson(path.join(pluginDir, "openvcs.plugin.json"), {
103
- id: "build-plugin",
104
- module: { exec: "openvcs-plugin.js" },
105
- });
106
61
  writeJson(path.join(pluginDir, "package.json"), {
107
62
  name: "build-plugin",
108
63
  private: true,
64
+ openvcs: {
65
+ id: "build-plugin",
66
+ module: { exec: "openvcs-plugin.js" },
67
+ },
109
68
  scripts: {
110
69
  "build:plugin": "node ./scripts/build-plugin.js",
111
70
  },
package/test/init.test.js CHANGED
@@ -81,11 +81,11 @@ test("writeModuleTemplate scaffolds SDK runtime entrypoint", () => {
81
81
  });
82
82
 
83
83
  const pluginSource = fs.readFileSync(path.join(targetDir, "src", "plugin.ts"), "utf8");
84
- const manifest = JSON.parse(
85
- fs.readFileSync(path.join(targetDir, "openvcs.plugin.json"), "utf8")
84
+ const packageJson = JSON.parse(
85
+ fs.readFileSync(path.join(targetDir, "package.json"), "utf8")
86
86
  );
87
87
 
88
- assert.equal(manifest.module.exec, "openvcs-plugin.js");
88
+ assert.equal(packageJson.openvcs.module.exec, "openvcs-plugin.js");
89
89
  assert.match(pluginSource, /OnPluginStart/);
90
90
  assert.match(pluginSource, /PluginDefinition/);
91
91
  assert.match(pluginSource, /context\.host\.info\('OpenVCS plugin started'\)/);
package/lib/dist.d.ts DELETED
@@ -1,27 +0,0 @@
1
- import { readManifest, validateDeclaredModuleExec } from "./build";
2
- interface DistArgs {
3
- pluginDir: string;
4
- outDir: string;
5
- verbose: boolean;
6
- noNpmDeps: boolean;
7
- noBuild: boolean;
8
- }
9
- export declare function distUsage(commandName?: string): string;
10
- export declare function parseDistArgs(args: string[]): DistArgs;
11
- declare function validateManifestEntry(pluginDir: string, entry: string): void;
12
- declare function rejectNativeAddonsRecursive(dirPath: string): void;
13
- declare function copyIcon(pluginDir: string, bundleDir: string): void;
14
- declare function uniqueStagingDir(outDir: string): string;
15
- declare function writeTarGz(outPath: string, baseDir: string, folderName: string): Promise<void>;
16
- export declare function bundlePlugin(parsedArgs: DistArgs): Promise<string>;
17
- export declare const __private: {
18
- ICON_EXTENSIONS: string[];
19
- copyIcon: typeof copyIcon;
20
- readManifest: typeof readManifest;
21
- rejectNativeAddonsRecursive: typeof rejectNativeAddonsRecursive;
22
- uniqueStagingDir: typeof uniqueStagingDir;
23
- validateDeclaredModuleExec: typeof validateDeclaredModuleExec;
24
- validateManifestEntry: typeof validateManifestEntry;
25
- writeTarGz: typeof writeTarGz;
26
- };
27
- export {};