plugin-updater 1.0.24 → 1.0.26
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/dist/index.d.ts +3 -3
- package/dist/index.js +66 -14
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export declare function getNpmPlugins(configDir: string): NpmPlugin[];
|
|
|
16
16
|
export declare function installNpmPlugin(name: string, configDir: string): string;
|
|
17
17
|
export declare function uninstallNpmPlugin(name: string, configDir: string): string;
|
|
18
18
|
export declare function updateNpmPlugin(name: string, configDir: string, updateInterval?: number): string;
|
|
19
|
-
export declare function updatePluginPublic(pluginName: string, gitUrl: string, branch?: string, commitHash?: string): Promise<void>;
|
|
20
|
-
export declare function earlyLaunch(configDir: string, plugins: Plugin[]): Promise<void>;
|
|
21
|
-
export declare function activate(): Promise<void>;
|
|
19
|
+
export declare function updatePluginPublic(pluginName: string, gitUrl: string, branch?: string, commitHash?: string): Promise<void | object>;
|
|
20
|
+
export declare function earlyLaunch(configDir: string, plugins: Plugin[]): Promise<void | object>;
|
|
21
|
+
export declare function activate(opencodeHookInput?: unknown): Promise<void | object>;
|
|
22
22
|
export {};
|
package/dist/index.js
CHANGED
|
@@ -120,7 +120,15 @@ function writeOpencodeJson(configDir, data) {
|
|
|
120
120
|
fs.writeFileSync(ocPath, JSON.stringify(data, null, 2), "utf8");
|
|
121
121
|
}
|
|
122
122
|
// ── Public API ────────────────────────────────────────────────────────────────
|
|
123
|
+
// opencode invokes every exported function as a plugin hook, passing a context
|
|
124
|
+
// object instead of our protocol arguments; exports detect that and return an
|
|
125
|
+
// inert value so opencode gets a valid (empty) plugin instance
|
|
126
|
+
function isOpencodeHookInvocation(firstArgument) {
|
|
127
|
+
return typeof firstArgument !== "string";
|
|
128
|
+
}
|
|
123
129
|
export function getNpmPlugins(configDir) {
|
|
130
|
+
if (isOpencodeHookInvocation(configDir))
|
|
131
|
+
return [];
|
|
124
132
|
const { plugins } = readOpencodeJson(configDir);
|
|
125
133
|
return plugins.map((raw) => {
|
|
126
134
|
const name = raw.replace(/@[^@/]+$/, "") || raw;
|
|
@@ -129,6 +137,8 @@ export function getNpmPlugins(configDir) {
|
|
|
129
137
|
});
|
|
130
138
|
}
|
|
131
139
|
export function installNpmPlugin(name, configDir) {
|
|
140
|
+
if (isOpencodeHookInvocation(name))
|
|
141
|
+
return "";
|
|
132
142
|
writeLog(`Installing npm plugin: ${name}`);
|
|
133
143
|
try {
|
|
134
144
|
const { plugins, raw } = readOpencodeJson(configDir);
|
|
@@ -147,6 +157,8 @@ export function installNpmPlugin(name, configDir) {
|
|
|
147
157
|
}
|
|
148
158
|
}
|
|
149
159
|
export function uninstallNpmPlugin(name, configDir) {
|
|
160
|
+
if (isOpencodeHookInvocation(name))
|
|
161
|
+
return "";
|
|
150
162
|
writeLog(`Uninstalling npm plugin: ${name}`);
|
|
151
163
|
try {
|
|
152
164
|
const { plugins, raw } = readOpencodeJson(configDir);
|
|
@@ -166,6 +178,8 @@ export function uninstallNpmPlugin(name, configDir) {
|
|
|
166
178
|
}
|
|
167
179
|
}
|
|
168
180
|
export function updateNpmPlugin(name, configDir, updateInterval = 1) {
|
|
181
|
+
if (isOpencodeHookInvocation(name))
|
|
182
|
+
return "";
|
|
169
183
|
writeLog(`Updating npm plugin: ${name}`);
|
|
170
184
|
const checkFile = path.join(configDir, "cache", `.npm-lastcheck-${name.replace(/[^a-z0-9]/gi, "_")}`);
|
|
171
185
|
try {
|
|
@@ -262,6 +276,42 @@ async function callPluginCleanup(pluginExecutionFile, configDir) {
|
|
|
262
276
|
writeLog(`cleanup() call failed for ${pluginExecutionFile}: ${e.message}`, true);
|
|
263
277
|
}
|
|
264
278
|
}
|
|
279
|
+
const BUILD_OUTPUT_DIRS = ["dist", path.join("core", "dist")];
|
|
280
|
+
// npm install creates node_modules/.bin symlinks, which fail on filesystems
|
|
281
|
+
// without symlink support (e.g. Windows-backed Docker bind mounts) — build in
|
|
282
|
+
// the OS temp dir and copy the outputs back instead
|
|
283
|
+
function buildInTempDir(pluginName, sourceDir) {
|
|
284
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), `plugin-updater-${pluginName}-`));
|
|
285
|
+
try {
|
|
286
|
+
fs.cpSync(sourceDir, tempDir, {
|
|
287
|
+
recursive: true,
|
|
288
|
+
filter: (src) => {
|
|
289
|
+
const name = path.basename(src);
|
|
290
|
+
return name !== ".git" && name !== "node_modules";
|
|
291
|
+
},
|
|
292
|
+
});
|
|
293
|
+
writeLog(`Running npm install for ${pluginName}`);
|
|
294
|
+
execSync("npm install", { cwd: tempDir, stdio: "pipe" });
|
|
295
|
+
writeLog(`Finished npm install for ${pluginName}`);
|
|
296
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(tempDir, "package.json"), "utf8"));
|
|
297
|
+
if (pkg.scripts?.build) {
|
|
298
|
+
execSync("npm run build", { cwd: tempDir, stdio: "pipe" });
|
|
299
|
+
writeLog(`Finished npm run build for ${pluginName}`);
|
|
300
|
+
}
|
|
301
|
+
else {
|
|
302
|
+
writeLog(`Skipped npm run build for ${pluginName} (no build script found)`);
|
|
303
|
+
}
|
|
304
|
+
for (const outputDir of BUILD_OUTPUT_DIRS) {
|
|
305
|
+
const builtDir = path.join(tempDir, outputDir);
|
|
306
|
+
if (fs.existsSync(builtDir)) {
|
|
307
|
+
fs.cpSync(builtDir, path.join(sourceDir, outputDir), { recursive: true });
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
finally {
|
|
312
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
313
|
+
}
|
|
314
|
+
}
|
|
265
315
|
async function deployToExecutionDir(pluginName, executionPath, changed, configDir) {
|
|
266
316
|
const sourceDir = path.join(getReposDir(), pluginName);
|
|
267
317
|
if (!fs.existsSync(sourceDir))
|
|
@@ -275,23 +325,17 @@ async function deployToExecutionDir(pluginName, executionPath, changed, configDi
|
|
|
275
325
|
else {
|
|
276
326
|
if (fs.existsSync(packageJsonPath)) {
|
|
277
327
|
try {
|
|
278
|
-
|
|
279
|
-
execSync("npm install", { cwd: sourceDir, stdio: "ignore" });
|
|
280
|
-
writeLog(`Finished npm install for ${pluginName}`);
|
|
281
|
-
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
|
282
|
-
if (pkg.main)
|
|
283
|
-
entryFile = pkg.main;
|
|
284
|
-
if (pkg.scripts?.build) {
|
|
285
|
-
execSync("npm run build", { cwd: sourceDir, stdio: "ignore" });
|
|
286
|
-
writeLog(`Finished npm run build for ${pluginName}`);
|
|
287
|
-
}
|
|
288
|
-
else {
|
|
289
|
-
writeLog(`Skipped npm run build for ${pluginName} (no build script found)`);
|
|
290
|
-
}
|
|
328
|
+
buildInTempDir(pluginName, sourceDir);
|
|
291
329
|
}
|
|
292
330
|
catch (error) {
|
|
293
331
|
const err = error;
|
|
332
|
+
const stderr = err.stderr ? err.stderr.toString().trim() : "";
|
|
333
|
+
const stdout = err.stdout ? err.stdout.toString().trim() : "";
|
|
294
334
|
writeLog(`Build/Install failed for ${pluginName}: ${err.message}`, true);
|
|
335
|
+
if (stderr)
|
|
336
|
+
writeLog(`npm stderr: ${stderr}`, true);
|
|
337
|
+
if (stdout)
|
|
338
|
+
writeLog(`npm stdout: ${stdout}`, true);
|
|
295
339
|
}
|
|
296
340
|
}
|
|
297
341
|
}
|
|
@@ -339,6 +383,8 @@ async function pluginUpdaterEntry(input) {
|
|
|
339
383
|
}
|
|
340
384
|
}
|
|
341
385
|
export async function updatePluginPublic(pluginName, gitUrl, branch, commitHash) {
|
|
386
|
+
if (isOpencodeHookInvocation(pluginName))
|
|
387
|
+
return {};
|
|
342
388
|
writeLog(`Public API update call for ${pluginName}`);
|
|
343
389
|
const appName = process.argv.join(" ").includes("claude") ? "claude" : "opencode";
|
|
344
390
|
const configDir = getAppConfigDir(appName);
|
|
@@ -346,6 +392,8 @@ export async function updatePluginPublic(pluginName, gitUrl, branch, commitHash)
|
|
|
346
392
|
await deployToExecutionDir(pluginName, path.join(configDir, "plugin"), result.changed, configDir);
|
|
347
393
|
}
|
|
348
394
|
export async function earlyLaunch(configDir, plugins) {
|
|
395
|
+
if (isOpencodeHookInvocation(configDir))
|
|
396
|
+
return {};
|
|
349
397
|
EARLY_LAUNCH_CONFIG_DIR = configDir;
|
|
350
398
|
writeLog("Starting earlyLaunch updater sequence");
|
|
351
399
|
// Self-update first
|
|
@@ -387,7 +435,11 @@ export async function earlyLaunch(configDir, plugins) {
|
|
|
387
435
|
}
|
|
388
436
|
}
|
|
389
437
|
}
|
|
390
|
-
export async function activate() {
|
|
438
|
+
export async function activate(opencodeHookInput) {
|
|
439
|
+
// module load below calls activate() with no argument; opencode passes a
|
|
440
|
+
// context object when re-invoking the export — return an inert plugin instance
|
|
441
|
+
if (opencodeHookInput !== undefined)
|
|
442
|
+
return {};
|
|
391
443
|
const isClaude = process.argv.join(" ").includes("claude");
|
|
392
444
|
const appName = isClaude ? "claude" : "opencode";
|
|
393
445
|
const configDir = getAppConfigDir(appName);
|