plugin-updater 1.3.4 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/commands.js +29 -7
- package/dist/index.js +3 -5
- package/lib/core.js +70 -19
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -91,7 +91,7 @@ Deployed automatically to both apps on each `earlyLaunch` (`~/.config/opencode/c
|
|
|
91
91
|
|
|
92
92
|
## Configuration
|
|
93
93
|
|
|
94
|
-
> Config files are **auto-created with defaults
|
|
94
|
+
> Config files are **never auto-created on launch** — settings are registered with defaults (core `defineConfig`) and edited in the loader's **Plugins → Configure** screen (or `/<plugin>-config`); a file is written only when you change a value. **Global console logging** for every plugin is toggled in `config/settings.json` (`logConsole: true`, the opencode.json-equivalent).
|
|
95
95
|
|
|
96
96
|
Config file: `~/.config/opencode/config/plugin-updater.json` (preferred) or `~/.config/opencode/plugin-updater.json` (fallback); same under `~/.claude` for Claude Code.
|
|
97
97
|
|
package/dist/commands.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
|
-
// Cross-app slash-
|
|
3
|
-
//
|
|
4
|
-
//
|
|
2
|
+
// Cross-app slash-commands for plugin-updater:
|
|
3
|
+
// /plugin-updater-config — plugin-updater's OWN settings (scoped, like every plugin)
|
|
4
|
+
// /config — the UNIFIED entry: global settings + ANY installed plugin
|
|
5
|
+
// plugin-updater is an npm package (not deployed at plugin/<name>.js), so commands shell
|
|
6
|
+
// into this same bundle's index.js by absolute path. The /config dispatcher (config-all)
|
|
7
|
+
// enumerates plugins.json and resolves each plugin's deployed bundle.
|
|
5
8
|
import { fileURLToPath } from "url";
|
|
6
9
|
import { dirname, join } from "path";
|
|
7
|
-
import
|
|
10
|
+
import fs from "fs";
|
|
11
|
+
import { runConfigCli, runAllConfigCli, deployCommands, getAppConfigDir as coreGetAppConfigDir } from "../lib/core.js";
|
|
12
|
+
import { getPlugins } from "./config.js";
|
|
8
13
|
const PLUGIN = "plugin-updater";
|
|
9
|
-
// the deployed entry that carries the maybeRunCli guard (dist/index.js, sibling).
|
|
10
14
|
const SELF = join(dirname(fileURLToPath(import.meta.url)), "index.js");
|
|
11
15
|
export function deployUpdaterCommands() {
|
|
12
16
|
try {
|
|
@@ -18,19 +22,37 @@ export function deployUpdaterCommands() {
|
|
|
18
22
|
shell: `node "${SELF}" config $ARGUMENTS`,
|
|
19
23
|
body: "Above is the plugin-updater config result. Report it; if the user changed a setting, confirm the new value.",
|
|
20
24
|
},
|
|
25
|
+
{
|
|
26
|
+
name: "config",
|
|
27
|
+
description: "View/change ANY plugin's settings and the global settings",
|
|
28
|
+
argumentHint: "[global | <plugin>] [list | get <key> | set <key> <value>]",
|
|
29
|
+
shell: `node "${SELF}" config-all $ARGUMENTS`,
|
|
30
|
+
body: "Above is the unified ecosystem config: the global settings block plus one block per installed plugin. Present it clearly. If the user asked to change a setting, run `/config <target> set <key> <value>` (target is `global` or the plugin name) and confirm the new value.",
|
|
31
|
+
},
|
|
21
32
|
]);
|
|
22
33
|
}
|
|
23
34
|
catch {
|
|
24
35
|
/* best-effort */
|
|
25
36
|
}
|
|
26
37
|
}
|
|
27
|
-
// If invoked as `node dist/index.js config …`, run the config CLI and return true
|
|
28
|
-
// so the entry exits before the updater/self-activate sequence.
|
|
29
38
|
export async function maybeRunCli() {
|
|
30
39
|
const argv = process.argv.slice(2);
|
|
31
40
|
if (argv[0] === "config") {
|
|
32
41
|
runConfigCli(PLUGIN, argv.slice(1));
|
|
33
42
|
return true;
|
|
34
43
|
}
|
|
44
|
+
if (argv[0] === "config-all") {
|
|
45
|
+
// Use core's getAppConfigDir (respects HUB_OPENCODE_DIR / HUB_CLAUDE_DIR env overrides)
|
|
46
|
+
const configDir = coreGetAppConfigDir();
|
|
47
|
+
const names = getPlugins(configDir).map((p) => p.name);
|
|
48
|
+
const resolveBundle = (name) => {
|
|
49
|
+
if (name === PLUGIN)
|
|
50
|
+
return SELF;
|
|
51
|
+
const p = join(configDir, "plugin", `${name}.js`);
|
|
52
|
+
return fs.existsSync(p) ? p : null;
|
|
53
|
+
};
|
|
54
|
+
runAllConfigCli(argv.slice(1), { plugins: [...names, PLUGIN], resolveBundle });
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
35
57
|
return false;
|
|
36
58
|
}
|
package/dist/index.js
CHANGED
|
@@ -8,11 +8,13 @@ import { syncPluginsAcrossApps } from "./syncbridge.js";
|
|
|
8
8
|
// @ts-ignore — generated bundle, no .d.ts
|
|
9
9
|
import { maybeRunCli, deployUpdaterCommands } from "./commands.js";
|
|
10
10
|
// @ts-ignore — generated bundle, no .d.ts
|
|
11
|
-
import {
|
|
11
|
+
import { defineConfig } from "../lib/core.js";
|
|
12
12
|
import path from "path";
|
|
13
13
|
import fs from "fs";
|
|
14
14
|
// `node dist/index.js config …` (from the /plugin-updater-config command) runs the
|
|
15
15
|
// config CLI and exits, before the self-activation/updater sequence below.
|
|
16
|
+
// Register config defaults BEFORE the CLI guard so `config schema` sees them (no write).
|
|
17
|
+
defineConfig("plugin-updater", { logging: true });
|
|
16
18
|
if (await maybeRunCli()) {
|
|
17
19
|
process.exit(0);
|
|
18
20
|
}
|
|
@@ -72,10 +74,6 @@ export async function earlyLaunch(configDir, plugins) {
|
|
|
72
74
|
deployUpdaterCommands();
|
|
73
75
|
}
|
|
74
76
|
catch { /* best-effort */ }
|
|
75
|
-
try {
|
|
76
|
-
ensureConfig("plugin-updater", { logging: true });
|
|
77
|
-
}
|
|
78
|
-
catch { /* best-effort */ }
|
|
79
77
|
// pull in any `sync: true` plugins from the other app BEFORE building, then
|
|
80
78
|
// re-read the list so a freshly-synced-in plugin is cloned/built this pass.
|
|
81
79
|
await syncPluginsAcrossApps(configDir);
|
package/lib/core.js
CHANGED
|
@@ -83,19 +83,13 @@ function loadConfig(name, configDir = getAppConfigDir()) {
|
|
|
83
83
|
CACHE[key] = data && typeof data === "object" && !Array.isArray(data) ? data : {};
|
|
84
84
|
return CACHE[key];
|
|
85
85
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
} catch {
|
|
94
|
-
}
|
|
95
|
-
CACHE[configDir + "::" + name] = { ...defaults };
|
|
96
|
-
return CACHE[configDir + "::" + name];
|
|
97
|
-
}
|
|
98
|
-
return { ...defaults, ...loadConfig(name, configDir) };
|
|
86
|
+
var DEFAULTS = {};
|
|
87
|
+
function defineConfig(name, defaults, configDir = getAppConfigDir()) {
|
|
88
|
+
DEFAULTS[name] = { ...DEFAULTS[name] ?? {}, ...defaults };
|
|
89
|
+
return { ...DEFAULTS[name], ...loadConfig(name, configDir) };
|
|
90
|
+
}
|
|
91
|
+
function getConfigDefaults(name) {
|
|
92
|
+
return { ...DEFAULTS[name] ?? {} };
|
|
99
93
|
}
|
|
100
94
|
function getConfigValue(name, key, configDir = getAppConfigDir()) {
|
|
101
95
|
let node = loadConfig(name, configDir);
|
|
@@ -243,14 +237,22 @@ function configCommand(pluginName, commandName = `${pluginName}-config`) {
|
|
|
243
237
|
// core/src/configcli.ts
|
|
244
238
|
function runConfigCli(pluginName, argv) {
|
|
245
239
|
const [action, key, ...rest] = argv;
|
|
240
|
+
if (action === "schema") {
|
|
241
|
+
console.log(JSON.stringify({ name: pluginName, defaults: getConfigDefaults(pluginName), current: listConfig(pluginName) }));
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
246
244
|
if (!action || action === "list") {
|
|
247
|
-
const
|
|
248
|
-
const
|
|
245
|
+
const defaults = getConfigDefaults(pluginName);
|
|
246
|
+
const current = listConfig(pluginName);
|
|
247
|
+
const keys = Object.keys({ ...defaults, ...current });
|
|
249
248
|
if (!keys.length) {
|
|
250
|
-
console.log(`${pluginName}: no
|
|
249
|
+
console.log(`${pluginName}: no configurable settings.`);
|
|
251
250
|
return;
|
|
252
251
|
}
|
|
253
|
-
for (const k of keys)
|
|
252
|
+
for (const k of keys) {
|
|
253
|
+
const isSet = Object.prototype.hasOwnProperty.call(current, k);
|
|
254
|
+
console.log(`${k} = ${JSON.stringify(isSet ? current[k] : defaults[k])}${isSet ? "" : " (default)"}`);
|
|
255
|
+
}
|
|
254
256
|
return;
|
|
255
257
|
}
|
|
256
258
|
if (action === "get") {
|
|
@@ -271,7 +273,7 @@ function runConfigCli(pluginName, argv) {
|
|
|
271
273
|
console.log(`set ${key} = ${JSON.stringify(value)}`);
|
|
272
274
|
return;
|
|
273
275
|
}
|
|
274
|
-
console.log(`${pluginName} config \u2014 usage: list | get <key> | set <key> <value
|
|
276
|
+
console.log(`${pluginName} config \u2014 usage: list | get <key> | set <key> <value> | schema`);
|
|
275
277
|
}
|
|
276
278
|
function maybeRunConfigCli(pluginName) {
|
|
277
279
|
const argv = process.argv.slice(2);
|
|
@@ -283,19 +285,67 @@ function maybeRunConfigCli(pluginName) {
|
|
|
283
285
|
}
|
|
284
286
|
return true;
|
|
285
287
|
}
|
|
288
|
+
|
|
289
|
+
// core/src/configcli-all.ts
|
|
290
|
+
import { execFileSync } from "child_process";
|
|
291
|
+
var GLOBAL_SETTINGS_DEFAULTS = { logConsole: false, logColor: true };
|
|
292
|
+
var GLOBAL_NAME = "settings";
|
|
293
|
+
function defaultRunChild(bundle, args) {
|
|
294
|
+
return execFileSync(process.execPath, [bundle, "config", ...args], { encoding: "utf8" });
|
|
295
|
+
}
|
|
296
|
+
function msg(e) {
|
|
297
|
+
return String(e?.message ?? e);
|
|
298
|
+
}
|
|
299
|
+
function runAllConfigCli(argv, opts) {
|
|
300
|
+
defineConfig(GLOBAL_NAME, GLOBAL_SETTINGS_DEFAULTS);
|
|
301
|
+
const runChild = opts.runChild ?? defaultRunChild;
|
|
302
|
+
const [target, ...rest] = argv;
|
|
303
|
+
if (!target || target === "list") {
|
|
304
|
+
console.log("# global");
|
|
305
|
+
runConfigCli(GLOBAL_NAME, ["list"]);
|
|
306
|
+
for (const name of opts.plugins) {
|
|
307
|
+
const bundle2 = opts.resolveBundle(name);
|
|
308
|
+
if (!bundle2) continue;
|
|
309
|
+
console.log(`
|
|
310
|
+
# ${name}`);
|
|
311
|
+
try {
|
|
312
|
+
process.stdout.write(runChild(bundle2, ["list"]));
|
|
313
|
+
} catch (e) {
|
|
314
|
+
console.log(` (could not read ${name}: ${msg(e)})`);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
if (target === "global") {
|
|
320
|
+
runConfigCli(GLOBAL_NAME, rest.length ? rest : ["list"]);
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
const bundle = opts.resolveBundle(target);
|
|
324
|
+
if (!bundle) {
|
|
325
|
+
console.log(`Unknown config target: ${target}`);
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
try {
|
|
329
|
+
process.stdout.write(runChild(bundle, rest.length ? rest : ["list"]));
|
|
330
|
+
} catch (e) {
|
|
331
|
+
console.log(`config ${target} failed: ${msg(e)}`);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
286
334
|
export {
|
|
335
|
+
GLOBAL_SETTINGS_DEFAULTS,
|
|
287
336
|
atomicWrite,
|
|
288
337
|
coerce,
|
|
289
338
|
configCommand,
|
|
290
339
|
configPath,
|
|
291
340
|
createLogger,
|
|
341
|
+
defineConfig,
|
|
292
342
|
deployCommands,
|
|
293
|
-
ensureConfig,
|
|
294
343
|
ensureDir,
|
|
295
344
|
existingApps,
|
|
296
345
|
existingConfigDirs,
|
|
297
346
|
getApp,
|
|
298
347
|
getAppConfigDir,
|
|
348
|
+
getConfigDefaults,
|
|
299
349
|
getConfigValue,
|
|
300
350
|
globalSetting,
|
|
301
351
|
isClaude,
|
|
@@ -306,6 +356,7 @@ export {
|
|
|
306
356
|
makeWriteLog,
|
|
307
357
|
maybeRunConfigCli,
|
|
308
358
|
readJson,
|
|
359
|
+
runAllConfigCli,
|
|
309
360
|
runConfigCli,
|
|
310
361
|
setConfigValue,
|
|
311
362
|
writeJson
|