opencode-rules-md 0.8.5 → 0.8.6
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/cli.mjs +252 -261
- package/dist/src/cli/config.d.ts +11 -0
- package/dist/src/cli/config.d.ts.map +1 -1
- package/dist/src/cli/config.js +15 -0
- package/dist/src/cli/config.js.map +1 -1
- package/dist/src/cli/install.d.ts +35 -20
- package/dist/src/cli/install.d.ts.map +1 -1
- package/dist/src/cli/install.js +50 -131
- package/dist/src/cli/install.js.map +1 -1
- package/dist/src/cli/main.d.ts +5 -0
- package/dist/src/cli/main.d.ts.map +1 -1
- package/dist/src/cli/main.js +29 -26
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/cli/spawn.d.ts +29 -0
- package/dist/src/cli/spawn.d.ts.map +1 -0
- package/dist/src/cli/spawn.js +48 -0
- package/dist/src/cli/spawn.js.map +1 -0
- package/dist/src/cli/status.d.ts +15 -8
- package/dist/src/cli/status.d.ts.map +1 -1
- package/dist/src/cli/status.js +63 -31
- package/dist/src/cli/status.js.map +1 -1
- package/dist/src/cli/uninstall.d.ts +5 -2
- package/dist/src/cli/uninstall.d.ts.map +1 -1
- package/dist/src/cli/uninstall.js +78 -51
- package/dist/src/cli/uninstall.js.map +1 -1
- package/dist/src/cli/update.d.ts +50 -16
- package/dist/src/cli/update.d.ts.map +1 -1
- package/dist/src/cli/update.js +156 -124
- package/dist/src/cli/update.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/config.ts +19 -0
- package/src/cli/install.ts +66 -174
- package/src/cli/main.ts +34 -25
- package/src/cli/spawn.ts +76 -0
- package/src/cli/status.ts +83 -37
- package/src/cli/uninstall.ts +88 -57
- package/src/cli/update.ts +182 -148
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/cli/update.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/cli/update.ts"],"names":[],"mappings":"AAmBA,OAAO,EAIL,KAAK,KAAK,EAEX,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAIjD,mEAAmE;AACnE,eAAO,MAAM,qBAAqB,6CAA8C,CAAC;AAEjF,kFAAkF;AAClF,eAAO,MAAM,kBAAkB,sBAAsB,CAAC;AAEtD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAExE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAE/E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,EAAE,CAAC,EAAE,KAAK,GACT,MAAM,EAAE,CAoBV;AAED,MAAM,WAAW,aAAa;IAC5B,0EAA0E;IAC1E,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC1C,kDAAkD;IAClD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,OAAO,mBAAmB,CAAC;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,aAAa,CAAC;IAC5C,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,+DAA+D;IAC/D,WAAW,EAAE,MAAM,CAAC;CACrB;AAeD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI/D;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAqC/D;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,SAAS,GACpB,IAAI,KAAK,EACT,KAAK,MAAM,CAAC,UAAU,EACtB,KAAK,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,EACxB,QAAQ,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,EAC3B,OAAM,aAAkB,KACvB,OAAO,CAAC,YAAY,CAkEtB,CAAC"}
|
package/dist/src/cli/update.js
CHANGED
|
@@ -1,132 +1,100 @@
|
|
|
1
1
|
// ---------------------------------------------------------------------------
|
|
2
2
|
// src/cli/update.ts — `omd update` command implementation.
|
|
3
3
|
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
4
|
+
// Like install, update is now a thin wrapper around OpenCode's own CLI.
|
|
5
|
+
// We compare the installed version (read from `data['plugin']` — singular —
|
|
6
|
+
// with a backward-compat fallback to the legacy `data['plugins']`) against
|
|
7
|
+
// the latest npm version. When stale we purge the on-disk cache under
|
|
8
|
+
// ~/.cache/opencode/packages/ (the actual location OpenCode uses) and
|
|
9
|
+
// invoke `opencode plugin opencode-rules-md --global --force` to refresh
|
|
10
|
+
// the registration.
|
|
11
|
+
//
|
|
12
|
+
// The cache purge matters because OpenCode caches the resolved package
|
|
13
|
+
// by specifier — once a cached copy exists, `--force` re-registers without
|
|
14
|
+
// re-fetching unless we first remove the stale entry.
|
|
7
15
|
// ---------------------------------------------------------------------------
|
|
8
16
|
import { homedir } from 'os';
|
|
9
17
|
import { join } from 'path';
|
|
10
18
|
import { fetchLatestVersion, isStale } from './registry.js';
|
|
11
|
-
import { loadGlobalConfig, matchesPlugin,
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
19
|
+
import { loadGlobalConfig, matchesPlugin, readInstalledPlugins, } from './config.js';
|
|
20
|
+
import { spawnOpencodePlugin } from './spawn.js';
|
|
21
|
+
const CONFIG_BASENAMES = ['opencode', 'tui'];
|
|
22
|
+
/** Package directory used by OpenCode to cache plugin installs. */
|
|
23
|
+
export const PACKAGES_DIR_BASENAME = ['.cache', 'opencode', 'packages'];
|
|
24
|
+
/** Exact cache directory name we look for (bare specifier, no version suffix). */
|
|
25
|
+
export const CACHE_DIR_BASENAME = 'opencode-rules-md';
|
|
15
26
|
/**
|
|
16
|
-
* Resolve the
|
|
17
|
-
*
|
|
18
|
-
* resolveConfigDir fallback strategy.
|
|
27
|
+
* Resolve the user's home directory, honoring a custom HOME env var.
|
|
28
|
+
* Used by both resolveCachePaths and the config loader.
|
|
19
29
|
*/
|
|
20
|
-
export function
|
|
21
|
-
return
|
|
30
|
+
export function resolveHome(env = process.env) {
|
|
31
|
+
return env.HOME ?? homedir();
|
|
22
32
|
}
|
|
23
33
|
/**
|
|
24
|
-
*
|
|
25
|
-
* Returns null when the cache is missing or unreadable.
|
|
34
|
+
* Return the absolute path of the OpenCode packages cache directory.
|
|
26
35
|
*/
|
|
27
|
-
function
|
|
28
|
-
|
|
29
|
-
try {
|
|
30
|
-
if (!fs.existsSync(pkgPath)) {
|
|
31
|
-
return null;
|
|
32
|
-
}
|
|
33
|
-
const pkg = JSON.parse(fs.readFileSync(pkgPath));
|
|
34
|
-
return typeof pkg.version === 'string' ? pkg.version : null;
|
|
35
|
-
}
|
|
36
|
-
catch {
|
|
37
|
-
return null;
|
|
38
|
-
}
|
|
36
|
+
export function resolvePackagesDir(env = process.env) {
|
|
37
|
+
return join(resolveHome(env), ...PACKAGES_DIR_BASENAME);
|
|
39
38
|
}
|
|
40
|
-
// ─── runUpdate ────────────────────────────────────────────────────────────────
|
|
41
|
-
const CONFIG_BASENAMES = ['opencode', 'tui'];
|
|
42
39
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
40
|
+
* Return the cache directories that match the opencode-rules-md prefix.
|
|
41
|
+
*
|
|
42
|
+
* Real-world layout under ~/.cache/opencode/packages/ looks like:
|
|
43
|
+
* opencode-rules-md/
|
|
44
|
+
* opencode-rules-md@latest/
|
|
45
|
+
* some-other-plugin/
|
|
46
|
+
*
|
|
47
|
+
* We glob-match anything starting with `opencode-rules-md` (exact or with
|
|
48
|
+
* an `@<version>` suffix). When an injected fs is provided we list the
|
|
49
|
+
* directory and filter; without one we return the two most common shapes
|
|
50
|
+
* so callers can pre-check existence cheaply.
|
|
49
51
|
*/
|
|
50
|
-
export
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
? opts.latestVersion
|
|
54
|
-
: await fetchLatestVersion();
|
|
55
|
-
const cachePath = resolveCachePath(env);
|
|
56
|
-
if (latest === null) {
|
|
57
|
-
log('omd: could not determine latest version from npm registry');
|
|
58
|
-
return {
|
|
59
|
-
status: 'unreachable',
|
|
60
|
-
cachePath,
|
|
61
|
-
instruction: 'npx opencode-rules-md@latest install',
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
// Determine installed version from config (check both configs)
|
|
65
|
-
let installedVersion = null;
|
|
66
|
-
for (const basename of CONFIG_BASENAMES) {
|
|
67
|
-
const loaded = loadGlobalConfig(fs, env, basename);
|
|
68
|
-
const plugins = normalizePlugin(loaded.data['plugins']);
|
|
69
|
-
const match = plugins.find(p => matchesPlugin(p));
|
|
70
|
-
if (match) {
|
|
71
|
-
// Extract version from specifier (e.g. 'opencode-rules-md@2.0.0' -> '2.0.0')
|
|
72
|
-
const atIndex = match.lastIndexOf('@');
|
|
73
|
-
installedVersion = atIndex >= 0 ? match.slice(atIndex + 1) : null;
|
|
74
|
-
break; // use first config that has it
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
const instruction = `npx opencode-rules-md@latest install`;
|
|
78
|
-
// Check staleness: only stale if installed version differs from latest
|
|
79
|
-
if (installedVersion !== null && !isStale(installedVersion, latest)) {
|
|
80
|
-
log(`omd: opencode-rules-md@${installedVersion} is already the latest`);
|
|
81
|
-
return {
|
|
82
|
-
status: 'current',
|
|
83
|
-
cachePath,
|
|
84
|
-
instruction,
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
// Before purging, decide whether the cache is actually stale. When the cache
|
|
88
|
-
// version is already equal to the latest resolved version, skip the purge
|
|
89
|
-
// so we do not delete a valid cache. If the version cannot be determined,
|
|
90
|
-
// fall back to purging to be safe.
|
|
91
|
-
const cacheVersion = readCacheVersion(fs, cachePath);
|
|
92
|
-
const shouldPurge = cacheVersion === null || cacheVersion !== latest;
|
|
93
|
-
if (opts.dryRun) {
|
|
94
|
-
log(`omd: update check (dry-run)`);
|
|
95
|
-
log(` latest version: ${latest}`);
|
|
96
|
-
log(` installed version: ${installedVersion ?? 'not installed'}`);
|
|
97
|
-
log(` would purge: ${shouldPurge ? cachePath : '(nothing to purge)'}`);
|
|
98
|
-
log(` would instruct: ${instruction}`);
|
|
99
|
-
return {
|
|
100
|
-
status: 'stale',
|
|
101
|
-
cachePath,
|
|
102
|
-
instruction,
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
// Purge the cache directory using the injected fs (allows test faking)
|
|
106
|
-
if (shouldPurge) {
|
|
52
|
+
export function resolveCachePaths(env = process.env, fs) {
|
|
53
|
+
const packagesDir = resolvePackagesDir(env);
|
|
54
|
+
if (fs && fs.existsSync(packagesDir)) {
|
|
107
55
|
try {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
56
|
+
const entries = fs.readdirSync(packagesDir);
|
|
57
|
+
return entries
|
|
58
|
+
.filter((name) => name === CACHE_DIR_BASENAME || name.startsWith(`${CACHE_DIR_BASENAME}@`))
|
|
59
|
+
.map((name) => join(packagesDir, name));
|
|
112
60
|
}
|
|
113
61
|
catch {
|
|
114
|
-
|
|
62
|
+
return [];
|
|
115
63
|
}
|
|
116
64
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
instruction,
|
|
125
|
-
};
|
|
126
|
-
};
|
|
127
|
-
// ─── purgeDirectory ────────────────────────────────────────────────────────────
|
|
65
|
+
// No fs injection — return the conventional candidates. Callers that care
|
|
66
|
+
// about existence should still check with existsSync().
|
|
67
|
+
return [
|
|
68
|
+
join(packagesDir, CACHE_DIR_BASENAME),
|
|
69
|
+
join(packagesDir, `${CACHE_DIR_BASENAME}@latest`),
|
|
70
|
+
];
|
|
71
|
+
}
|
|
128
72
|
/**
|
|
129
|
-
*
|
|
73
|
+
* Look up the installed specifier across both config files, returning the
|
|
74
|
+
* first one we find. Returns null when neither file registers the plugin.
|
|
75
|
+
*/
|
|
76
|
+
function findInstalledSpecifier(loaded) {
|
|
77
|
+
for (const cfg of loaded) {
|
|
78
|
+
const plugins = readInstalledPlugins(cfg);
|
|
79
|
+
const match = plugins.find((p) => matchesPlugin(p));
|
|
80
|
+
if (match)
|
|
81
|
+
return match;
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Extract the version portion of an `opencode-rules-md@<version>` specifier.
|
|
87
|
+
* Returns null when the specifier has no `@version` segment.
|
|
88
|
+
*/
|
|
89
|
+
export function extractVersion(specifier) {
|
|
90
|
+
const at = specifier.lastIndexOf('@');
|
|
91
|
+
if (at < 0 || at === specifier.length - 1)
|
|
92
|
+
return null;
|
|
93
|
+
return specifier.slice(at + 1);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Recursively delete a directory and all its contents using the injected fs.
|
|
97
|
+
* Best-effort — a failed purge is not fatal; we want the update to keep going.
|
|
130
98
|
*/
|
|
131
99
|
export function purgeDirectory(fs, dirPath) {
|
|
132
100
|
let entries = [];
|
|
@@ -139,25 +107,25 @@ export function purgeDirectory(fs, dirPath) {
|
|
|
139
107
|
for (const entry of entries) {
|
|
140
108
|
const entryPath = join(dirPath, entry);
|
|
141
109
|
try {
|
|
142
|
-
if (fs.existsSync(entryPath))
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
// Non-empty directory — recurse
|
|
152
|
-
purgeDirectory(fs, entryPath);
|
|
153
|
-
fs.rmdirSync(entryPath);
|
|
154
|
-
}
|
|
110
|
+
if (!fs.existsSync(entryPath))
|
|
111
|
+
continue;
|
|
112
|
+
// Probe to differentiate empty dirs / non-empty dirs / files. The injected
|
|
113
|
+
// fs interface does not expose stat, so we try readdir first and fall back
|
|
114
|
+
// to unlink for leaves.
|
|
115
|
+
try {
|
|
116
|
+
const subEntries = fs.readdirSync(entryPath);
|
|
117
|
+
if (subEntries.length === 0) {
|
|
118
|
+
fs.rmdirSync(entryPath);
|
|
155
119
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
fs.
|
|
120
|
+
else {
|
|
121
|
+
purgeDirectory(fs, entryPath);
|
|
122
|
+
fs.rmdirSync(entryPath);
|
|
159
123
|
}
|
|
160
124
|
}
|
|
125
|
+
catch {
|
|
126
|
+
// Not a directory (or unreadable) — best-effort unlink.
|
|
127
|
+
fs.unlinkSync(entryPath);
|
|
128
|
+
}
|
|
161
129
|
}
|
|
162
130
|
catch {
|
|
163
131
|
// best-effort per entry
|
|
@@ -170,4 +138,68 @@ export function purgeDirectory(fs, dirPath) {
|
|
|
170
138
|
// best-effort
|
|
171
139
|
}
|
|
172
140
|
}
|
|
141
|
+
/**
|
|
142
|
+
* Run the update command.
|
|
143
|
+
*
|
|
144
|
+
* 1. Resolve the latest published version from npm (or use the injected mock).
|
|
145
|
+
* 2. Read the installed version from the user's opencode config.
|
|
146
|
+
* 3. If unreachable, log and return.
|
|
147
|
+
* 4. If current, log and return.
|
|
148
|
+
* 5. Otherwise: purge stale cache directories, then spawn
|
|
149
|
+
* `opencode plugin opencode-rules-md --global --force`.
|
|
150
|
+
*/
|
|
151
|
+
export const runUpdate = async (fs, env, log, _error, opts = {}) => {
|
|
152
|
+
// 1. Resolve latest.
|
|
153
|
+
const latest = opts.latestVersion !== undefined ? opts.latestVersion : await fetchLatestVersion();
|
|
154
|
+
const cachePaths = resolveCachePaths(env, fs);
|
|
155
|
+
const instruction = 'opencode plugin opencode-rules-md --global --force';
|
|
156
|
+
const spawnFn = opts.spawn ?? spawnOpencodePlugin;
|
|
157
|
+
// 2. Unreachable.
|
|
158
|
+
if (latest === null) {
|
|
159
|
+
log('omd: could not determine latest version from npm registry');
|
|
160
|
+
return { status: 'unreachable', cachePaths, instruction };
|
|
161
|
+
}
|
|
162
|
+
// 3. Installed version (read both configs).
|
|
163
|
+
const configs = CONFIG_BASENAMES.map((basename) => loadGlobalConfig(fs, env, basename));
|
|
164
|
+
const installedSpecifier = findInstalledSpecifier(configs);
|
|
165
|
+
const installedVersion = installedSpecifier ? extractVersion(installedSpecifier) : null;
|
|
166
|
+
// 4. Current.
|
|
167
|
+
if (installedVersion !== null && !isStale(installedVersion, latest)) {
|
|
168
|
+
log(`omd: opencode-rules-md@${installedVersion} is already the latest`);
|
|
169
|
+
return { status: 'current', cachePaths, instruction: '' };
|
|
170
|
+
}
|
|
171
|
+
// 5. Stale — describe plan.
|
|
172
|
+
if (opts.dryRun) {
|
|
173
|
+
log('omd: update check (dry-run)');
|
|
174
|
+
log(` latest version: ${latest}`);
|
|
175
|
+
log(` installed version: ${installedVersion ?? 'not installed'}`);
|
|
176
|
+
log(` would purge: ${cachePaths.join(', ') || '(none found)'}`);
|
|
177
|
+
log(` would instruct: ${instruction}`);
|
|
178
|
+
return { status: 'stale', cachePaths, instruction };
|
|
179
|
+
}
|
|
180
|
+
log(installedVersion === null
|
|
181
|
+
? `omd: opencode-rules-md is not installed; registering latest (${latest})`
|
|
182
|
+
: `omd: opencode-rules-md is stale (installed ${installedVersion}, latest ${latest})`);
|
|
183
|
+
// Purge each matching cache directory. Best-effort per path.
|
|
184
|
+
for (const cachePath of cachePaths) {
|
|
185
|
+
try {
|
|
186
|
+
if (fs.existsSync(cachePath)) {
|
|
187
|
+
purgeDirectory(fs, cachePath);
|
|
188
|
+
log(`omd: purged cache ${cachePath}`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
// ignore individual purge failures
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// Re-register via OpenCode's CLI. Failure here is fatal — surface it.
|
|
196
|
+
const result = await spawnFn(['opencode-rules-md', '--global', '--force'], {
|
|
197
|
+
env: process.env,
|
|
198
|
+
stdio: 'inherit',
|
|
199
|
+
});
|
|
200
|
+
if ((result.status ?? 0) !== 0) {
|
|
201
|
+
throw new Error(`opencode plugin opencode-rules-md --global --force exited with status ${String(result.status)}`);
|
|
202
|
+
}
|
|
203
|
+
return { status: 'stale', cachePaths, instruction: '' };
|
|
204
|
+
};
|
|
173
205
|
//# sourceMappingURL=update.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/cli/update.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,2DAA2D;AAC3D,EAAE;AACF,
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/cli/update.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/cli/config.ts
CHANGED
|
@@ -239,6 +239,22 @@ export function normalizePlugin(raw: unknown): string[] {
|
|
|
239
239
|
return [];
|
|
240
240
|
}
|
|
241
241
|
|
|
242
|
+
/**
|
|
243
|
+
* Read the installed plugin list from a loaded config, honoring both the
|
|
244
|
+
* modern `plugin` field (singular — what OpenCode actually uses) and the
|
|
245
|
+
* legacy `plugins` field (plural — written by older versions of `omd`).
|
|
246
|
+
*
|
|
247
|
+
* The modern field wins when both are present, matching OpenCode's own
|
|
248
|
+
* resolution order.
|
|
249
|
+
*/
|
|
250
|
+
export function readInstalledPlugins(config: GlobalConfig): string[] {
|
|
251
|
+
const modern = config.data['plugin'];
|
|
252
|
+
if (modern !== undefined) {
|
|
253
|
+
return normalizePlugin(modern);
|
|
254
|
+
}
|
|
255
|
+
return normalizePlugin(config.data['plugins']);
|
|
256
|
+
}
|
|
257
|
+
|
|
242
258
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
243
259
|
// matchesPlugin
|
|
244
260
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -312,6 +328,9 @@ export interface GlobalConfig {
|
|
|
312
328
|
data: Record<string, unknown>;
|
|
313
329
|
}
|
|
314
330
|
|
|
331
|
+
/** Backwards-compatible alias used by update.ts / status.ts. */
|
|
332
|
+
export type LoadedConfig = GlobalConfig;
|
|
333
|
+
|
|
315
334
|
/**
|
|
316
335
|
* Load and parse a global config file.
|
|
317
336
|
* Returns { path, exists, data }. data is {} when file absent or empty.
|