opencode-rules-md 0.8.4 → 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.
Files changed (47) hide show
  1. package/dist/cli.mjs +906 -0
  2. package/dist/src/cli/config.d.ts +104 -0
  3. package/dist/src/cli/config.d.ts.map +1 -0
  4. package/dist/src/cli/config.js +397 -0
  5. package/dist/src/cli/config.js.map +1 -0
  6. package/dist/src/cli/install.d.ts +50 -0
  7. package/dist/src/cli/install.d.ts.map +1 -0
  8. package/dist/src/cli/install.js +67 -0
  9. package/dist/src/cli/install.js.map +1 -0
  10. package/dist/src/cli/main.d.ts +19 -0
  11. package/dist/src/cli/main.d.ts.map +1 -0
  12. package/dist/src/cli/main.js +247 -0
  13. package/dist/src/cli/main.js.map +1 -0
  14. package/dist/src/cli/real-fs.d.ts +3 -0
  15. package/dist/src/cli/real-fs.d.ts.map +1 -0
  16. package/dist/src/cli/real-fs.js +32 -0
  17. package/dist/src/cli/real-fs.js.map +1 -0
  18. package/dist/src/cli/registry.d.ts +12 -0
  19. package/dist/src/cli/registry.d.ts.map +1 -0
  20. package/dist/src/cli/registry.js +34 -0
  21. package/dist/src/cli/registry.js.map +1 -0
  22. package/dist/src/cli/spawn.d.ts +29 -0
  23. package/dist/src/cli/spawn.d.ts.map +1 -0
  24. package/dist/src/cli/spawn.js +48 -0
  25. package/dist/src/cli/spawn.js.map +1 -0
  26. package/dist/src/cli/status.d.ts +51 -0
  27. package/dist/src/cli/status.d.ts.map +1 -0
  28. package/dist/src/cli/status.js +214 -0
  29. package/dist/src/cli/status.js.map +1 -0
  30. package/dist/src/cli/uninstall.d.ts +30 -0
  31. package/dist/src/cli/uninstall.d.ts.map +1 -0
  32. package/dist/src/cli/uninstall.js +128 -0
  33. package/dist/src/cli/uninstall.js.map +1 -0
  34. package/dist/src/cli/update.d.ts +65 -0
  35. package/dist/src/cli/update.d.ts.map +1 -0
  36. package/dist/src/cli/update.js +205 -0
  37. package/dist/src/cli/update.js.map +1 -0
  38. package/package.json +7 -2
  39. package/src/cli/config.ts +480 -0
  40. package/src/cli/install.ts +103 -0
  41. package/src/cli/main.ts +308 -0
  42. package/src/cli/real-fs.ts +44 -0
  43. package/src/cli/registry.ts +36 -0
  44. package/src/cli/spawn.ts +76 -0
  45. package/src/cli/status.ts +293 -0
  46. package/src/cli/uninstall.ts +177 -0
  47. package/src/cli/update.ts +254 -0
@@ -0,0 +1,214 @@
1
+ // ---------------------------------------------------------------------------
2
+ // src/cli/status.ts — `omd status` and `omd doctor` command implementations.
3
+ //
4
+ // Three correctness fixes vs. the previous implementation:
5
+ //
6
+ // 1. We read `data['plugin']` (singular) as the source of truth, with a
7
+ // backward-compat fallback to `data['plugins']`. The legacy plural
8
+ // field is no longer authoritative.
9
+ // 2. `runDoctor` warns when a legacy `plugins` field is present, so users
10
+ // upgrading from the buggy version are nudged to clean up.
11
+ // 3. The cache freshness check uses ~/.cache/opencode/packages/ (where
12
+ // OpenCode actually stores plugin installs) instead of the legacy
13
+ // ~/.cache/opencode/node_modules/ path.
14
+ // ---------------------------------------------------------------------------
15
+ import { join, dirname, extname } from 'path';
16
+ import { homedir } from 'os';
17
+ import { loadGlobalConfig, matchesPlugin, readInstalledPlugins, } from './config.js';
18
+ import { fetchLatestVersion } from './registry.js';
19
+ import { resolveCachePaths } from './update.js';
20
+ // ─── Constants ───────────────────────────────────────────────────────────────
21
+ const RULE_DIR_NAME = 'opencode-rules-md';
22
+ const MIN_NODE_VERSION = 20;
23
+ const CONFIG_BASENAMES = ['opencode', 'tui'];
24
+ // ─── runStatus ────────────────────────────────────────────────────────────────
25
+ /**
26
+ * Run the status command: read-only probe for both opencode.json and tui.json.
27
+ * Reports path, format, installed specifier, other plugins, and freshness.
28
+ */
29
+ export const runStatus = async (fs, env, log, opts = {}) => {
30
+ const configs = [];
31
+ const latest = opts.latestVersion !== undefined
32
+ ? opts.latestVersion
33
+ : await fetchLatestVersion();
34
+ for (const basename of CONFIG_BASENAMES) {
35
+ const loaded = loadGlobalConfig(fs, env, basename);
36
+ const format = extname(loaded.path); // '.json' or '.jsonc'
37
+ const plugins = readInstalledPlugins(loaded);
38
+ const match = plugins.find((p) => matchesPlugin(p)) ?? null;
39
+ const entry = {
40
+ basename,
41
+ path: loaded.path,
42
+ format,
43
+ installed: match,
44
+ notInstalled: !loaded.exists || match === null,
45
+ otherPlugins: plugins.filter((p) => !matchesPlugin(p)),
46
+ latest,
47
+ isLatest: match !== null && latest !== null
48
+ ? match === `opencode-rules-md@${latest}`
49
+ : null,
50
+ };
51
+ configs.push(entry);
52
+ if (!loaded.exists) {
53
+ log(`omd: ${basename}.json — config not found at ${loaded.path}`);
54
+ continue;
55
+ }
56
+ log(`omd: ${basename}${format} — ${loaded.path}`);
57
+ if (match) {
58
+ const isLatestLabel = entry.isLatest === true
59
+ ? ' (latest)'
60
+ : entry.isLatest === false
61
+ ? ` (behind: latest is ${latest ?? 'unknown'})`
62
+ : '';
63
+ log(` opencode-rules-md: ${match}${isLatestLabel}`);
64
+ }
65
+ else {
66
+ log(' opencode-rules-md: not installed');
67
+ }
68
+ if (entry.otherPlugins.length > 0) {
69
+ log(` other plugins: ${entry.otherPlugins.join(', ')}`);
70
+ }
71
+ }
72
+ return { configs };
73
+ };
74
+ // ─── runDoctor ────────────────────────────────────────────────────────────────
75
+ /**
76
+ * Run the doctor command: health checks for the plugin environment.
77
+ *
78
+ * Checks:
79
+ * - Node >= 20: issue if below
80
+ * - Bun on PATH: issue if absent
81
+ * - Both configs readable and valid: issue if absent or malformed
82
+ * - Legacy `plugins` field present: warning (no-op for the runtime, but
83
+ * indicates a previous buggy install)
84
+ * - Rule dir existence: warning if absent
85
+ * - Config dir writable: issue if not writable
86
+ * - Package freshness: info line about update availability
87
+ *
88
+ * Exit 1 if any issues found.
89
+ */
90
+ export const runDoctor = async (fs, env, log, error, opts = {}) => {
91
+ const issues = [];
92
+ const warnings = [];
93
+ const info = [];
94
+ const nodeVersion = opts.nodeVersion ?? process.version.slice(1); // strip 'v'
95
+ const ruleDirExists = opts.ruleDirExists ?? true;
96
+ // Check if Bun is available: use override if provided, otherwise scan PATH
97
+ let hasBun = opts.hasBun;
98
+ if (hasBun === undefined) {
99
+ const pathEnv = (env.PATH ?? '').split(':');
100
+ hasBun = pathEnv.some((p) => {
101
+ try {
102
+ const { existsSync } = require('node:fs');
103
+ return existsSync(p + '/bun');
104
+ }
105
+ catch {
106
+ return false;
107
+ }
108
+ });
109
+ }
110
+ // ── Check: Node version ───────────────────────────────────────────────────
111
+ log('Checking Node version...');
112
+ const nodeMajor = parseInt(nodeVersion.split('.')[0] ?? '0', 10);
113
+ if (nodeMajor < MIN_NODE_VERSION) {
114
+ issues.push(`Node.js ${nodeVersion} is too old; requires Node >= ${MIN_NODE_VERSION}`);
115
+ error(`[ISSUE] Node.js ${nodeVersion} — requires >= ${MIN_NODE_VERSION}. Download latest from https://nodejs.org`);
116
+ }
117
+ else {
118
+ log(` Node.js ${nodeVersion} — OK`);
119
+ }
120
+ // ── Check: Bun on PATH ─────────────────────────────────────────────────────
121
+ log('Checking for Bun...');
122
+ if (!hasBun) {
123
+ issues.push('Bun is not on PATH — install from https://bun.sh');
124
+ error('[ISSUE] Bun not found on PATH — install Bun for best performance');
125
+ }
126
+ else {
127
+ log(' Bun — found on PATH');
128
+ }
129
+ // ── Check: both configs readable and valid ─────────────────────────────────
130
+ for (const basename of CONFIG_BASENAMES) {
131
+ log(`Checking ${basename} config...`);
132
+ const loaded = loadGlobalConfig(fs, env, basename);
133
+ if (!loaded.exists) {
134
+ warnings.push(`${basename} config not found at ${loaded.path}`);
135
+ log(` ${basename}: not found (will be created on first install)`);
136
+ continue;
137
+ }
138
+ log(` ${basename}${extname(loaded.path)}: ${loaded.path}`);
139
+ const plugins = readInstalledPlugins(loaded);
140
+ const match = plugins.find((p) => matchesPlugin(p)) ?? null;
141
+ if (match) {
142
+ info.push(`${basename}: opencode-rules-md installed (${match})`);
143
+ log(` opencode-rules-md: ${match}`);
144
+ }
145
+ else {
146
+ warnings.push(`${basename}: plugin not installed`);
147
+ log(' opencode-rules-md: not installed');
148
+ }
149
+ // ── Check legacy `plugins` field (backward-compat warning) ──────────────
150
+ if (loaded.data['plugins'] !== undefined && loaded.data['plugin'] === undefined) {
151
+ warnings.push(`${basename}: legacy "plugins" field present (should be "plugin") — run "omd uninstall && omd install" to migrate`);
152
+ log(` [WARN] ${basename}: legacy "plugins" field present (should be "plugin")`);
153
+ }
154
+ // ── Check plugin shape ────────────────────────────────────────────────────
155
+ const pluginField = loaded.data['plugin'] ?? loaded.data['plugins'];
156
+ if (pluginField !== undefined &&
157
+ !Array.isArray(pluginField) &&
158
+ typeof pluginField !== 'object' &&
159
+ typeof pluginField !== 'string') {
160
+ issues.push(`${basename}: plugin field has invalid type — expected array, object, or string`);
161
+ error(`[ISSUE] ${basename}: invalid plugin shape`);
162
+ }
163
+ else {
164
+ log(' plugin field: valid');
165
+ }
166
+ }
167
+ // ── Check: rule dir existence (warning, not issue) ─────────────────────────
168
+ log('Checking rule directory...');
169
+ const ruleBase = join(homedir(), '.local', 'share', RULE_DIR_NAME);
170
+ if (!ruleDirExists) {
171
+ warnings.push(`Rule directory not found at ${ruleBase}`);
172
+ log(` ${ruleBase}: not found (plugin rules not installed — this is optional)`);
173
+ }
174
+ else {
175
+ log(` ${ruleBase}: exists`);
176
+ }
177
+ // ── Check: package cache directory ────────────────────────────────────────
178
+ log('Checking OpenCode package cache...');
179
+ const cachePaths = resolveCachePaths(env, fs);
180
+ if (cachePaths.length === 0) {
181
+ info.push('No opencode-rules-md cache found under ~/.cache/opencode/packages/');
182
+ log(' no cache entries match opencode-rules-md*');
183
+ }
184
+ else {
185
+ log(` cache entries: ${cachePaths.join(', ')}`);
186
+ }
187
+ // ── Check: config dir writable ─────────────────────────────────────────────
188
+ const configDir = env.OPENCODE_CONFIG_DIR ?? join(homedir(), '.config', 'opencode');
189
+ log('Checking config directory write access...');
190
+ const parentDir = dirname(configDir);
191
+ if (!fs.existsSync(parentDir)) {
192
+ issues.push(`Config parent directory does not exist: ${parentDir}`);
193
+ error(`[ISSUE] Config dir parent missing: ${parentDir}`);
194
+ }
195
+ else {
196
+ log(` ${parentDir}: writable`);
197
+ }
198
+ // ── Summary ────────────────────────────────────────────────────────────────
199
+ log('');
200
+ if (issues.length === 0) {
201
+ log('omd doctor: all checks passed ✓');
202
+ }
203
+ else {
204
+ error(`omd doctor: ${issues.length} issue(s) found — fix before using the plugin`);
205
+ error(`Run 'omd --help' for usage information`);
206
+ }
207
+ return {
208
+ ok: issues.length === 0,
209
+ issues,
210
+ warnings,
211
+ info,
212
+ };
213
+ };
214
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/cli/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { type CliFs } from './config.js';
2
+ export declare const CONFIG_BASENAMES: readonly ["opencode", "tui"];
3
+ export interface UninstallOptions {
4
+ /** Also remove ~/.cache/opencode/packages/opencode-rules-md*. */
5
+ purge?: boolean;
6
+ /** Run the full pipeline without writing to disk. */
7
+ dryRun?: boolean;
8
+ /** Reserved for future prompts — no-op today. */
9
+ yes?: boolean;
10
+ }
11
+ export interface UninstallResultPerFile {
12
+ path: string;
13
+ status: 'wrote' | 'skipped' | 'error';
14
+ backup: string | null;
15
+ }
16
+ export interface UninstallResult {
17
+ status: 'wrote' | 'skipped';
18
+ results: UninstallResultPerFile[];
19
+ purged: boolean;
20
+ }
21
+ /**
22
+ * Uninstall opencode-rules-md from both opencode.json and tui.json configs.
23
+ *
24
+ * Options:
25
+ * purge — also remove ~/.cache/opencode/packages/opencode-rules-md*
26
+ * dryRun — run full pipeline without writing to disk
27
+ * yes — reserved
28
+ */
29
+ export declare const runUninstall: (opts: UninstallOptions | undefined, fs: CliFs, env: NodeJS.ProcessEnv) => UninstallResult;
30
+ //# sourceMappingURL=uninstall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uninstall.d.ts","sourceRoot":"","sources":["../../../src/cli/uninstall.ts"],"names":[],"mappings":"AAoBA,OAAO,EAKL,KAAK,KAAK,EACX,MAAM,aAAa,CAAC;AAGrB,eAAO,MAAM,gBAAgB,8BAA+B,CAAC;AAE7D,MAAM,WAAW,gBAAgB;IAC/B,iEAAiE;IACjE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,qDAAqD;IACrD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iDAAiD;IACjD,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;IACtC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,OAAO,EAAE,sBAAsB,EAAE,CAAC;IAClC,MAAM,EAAE,OAAO,CAAC;CACjB;AA6CD;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,GACvB,MAAM,gBAAgB,YAAK,EAC3B,IAAI,KAAK,EACT,KAAK,MAAM,CAAC,UAAU,KACrB,eAqEF,CAAC"}
@@ -0,0 +1,128 @@
1
+ // ---------------------------------------------------------------------------
2
+ // src/cli/uninstall.ts — `omd uninstall` command implementation.
3
+ //
4
+ // Removes opencode-rules-md from opencode.json and tui.json, and (with
5
+ // `--purge`) wipes the OpenCode package cache. Two important fixes vs.
6
+ // the previous implementation:
7
+ //
8
+ // 1. We read & write `data['plugin']` (singular), the field OpenCode
9
+ // actually honors. The previous code wrote `data['plugins']` (plural),
10
+ // which OpenCode silently ignored — so "uninstall" used to leave
11
+ // the plugin effectively installed.
12
+ // 2. We also strip a stale `data['plugins']` entry if it exists, so
13
+ // users who upgraded from a buggy `omd install` get their legacy
14
+ // field cleaned up too.
15
+ // 3. We purge ~/.cache/opencode/packages/opencode-rules-md* (the real
16
+ // cache OpenCode uses), not the old ~/.cache/opencode/node_modules
17
+ // path.
18
+ // ---------------------------------------------------------------------------
19
+ import { join } from 'path';
20
+ import { loadGlobalConfig, backupIfWritable, rotateBackups, writeAtomically, } from './config.js';
21
+ import { resolveCachePaths, purgeDirectory } from './update.js';
22
+ export const CONFIG_BASENAMES = ['opencode', 'tui'];
23
+ /**
24
+ * Strip `opencode-rules-md` entries from a config payload, cleaning both
25
+ * the modern `plugin` field (array or single string) and any legacy
26
+ * `plugins` field. Returns a tuple [newData, removedCount].
27
+ *
28
+ * `removedCount > 0` indicates the file actually needs to be rewritten.
29
+ */
30
+ function stripFromData(data) {
31
+ let removed = 0;
32
+ const next = { ...data };
33
+ // Modern field: `plugin` (singular). Accept array or single string.
34
+ const currentRaw = next['plugin'] ?? next['plugins'];
35
+ if (currentRaw !== undefined) {
36
+ if (typeof currentRaw === 'string') {
37
+ if (currentRaw.startsWith('opencode-rules-md')) {
38
+ delete next['plugin'];
39
+ delete next['plugins'];
40
+ removed += 1;
41
+ }
42
+ }
43
+ else if (Array.isArray(currentRaw)) {
44
+ const filtered = currentRaw.filter((p) => !(typeof p === 'string' && p.startsWith('opencode-rules-md')));
45
+ if (filtered.length !== currentRaw.length) {
46
+ removed += currentRaw.length - filtered.length;
47
+ if (filtered.length === 0) {
48
+ delete next['plugin'];
49
+ delete next['plugins'];
50
+ }
51
+ else {
52
+ next['plugin'] = filtered;
53
+ delete next['plugins'];
54
+ }
55
+ }
56
+ }
57
+ }
58
+ return { next, removed };
59
+ }
60
+ /**
61
+ * Uninstall opencode-rules-md from both opencode.json and tui.json configs.
62
+ *
63
+ * Options:
64
+ * purge — also remove ~/.cache/opencode/packages/opencode-rules-md*
65
+ * dryRun — run full pipeline without writing to disk
66
+ * yes — reserved
67
+ */
68
+ export const runUninstall = (opts = {}, fs, env) => {
69
+ const results = [];
70
+ let anyProcessed = false;
71
+ let purged = false;
72
+ // ── Purge cache if requested ────────────────────────────────────────────
73
+ if (opts.purge) {
74
+ const cachePaths = resolveCachePaths(env, fs);
75
+ for (const cachePath of cachePaths) {
76
+ try {
77
+ if (fs.existsSync(cachePath)) {
78
+ purgeDirectory(fs, cachePath);
79
+ purged = true;
80
+ }
81
+ }
82
+ catch {
83
+ // best-effort — purge failure is non-fatal
84
+ }
85
+ }
86
+ }
87
+ // ── Remove plugin from both configs ─────────────────────────────────────
88
+ for (const basename of CONFIG_BASENAMES) {
89
+ const loaded = loadGlobalConfig(fs, env, basename);
90
+ if (!loaded.exists) {
91
+ results.push({ path: loaded.path, status: 'skipped', backup: null });
92
+ continue;
93
+ }
94
+ const { next, removed } = stripFromData(loaded.data);
95
+ if (removed === 0) {
96
+ results.push({ path: loaded.path, status: 'skipped', backup: null });
97
+ continue;
98
+ }
99
+ anyProcessed = true;
100
+ const newContent = JSON.stringify(next, null, 2) + '\n';
101
+ if (opts.dryRun) {
102
+ results.push({ path: loaded.path, status: 'wrote', backup: null });
103
+ continue;
104
+ }
105
+ // Backup the existing file before rewriting.
106
+ const backup = backupIfWritable(fs, loaded.path);
107
+ if (backup !== undefined) {
108
+ const segs = loaded.path.replace(/\\/g, '/').split('/');
109
+ const base = segs[segs.length - 1] ?? loaded.path;
110
+ const dot = base.lastIndexOf('.');
111
+ const name = dot >= 0 ? base.slice(0, dot) : base;
112
+ const dir = join(...segs.slice(0, -1));
113
+ rotateBackups(fs, dir, name, 3);
114
+ }
115
+ writeAtomically(fs, loaded.path, newContent);
116
+ results.push({
117
+ path: loaded.path,
118
+ status: 'wrote',
119
+ backup: backup ?? null,
120
+ });
121
+ }
122
+ return {
123
+ status: anyProcessed || purged ? 'wrote' : 'skipped',
124
+ results,
125
+ purged,
126
+ };
127
+ };
128
+ //# sourceMappingURL=uninstall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uninstall.js","sourceRoot":"","sources":["../../../src/cli/uninstall.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ import { type CliFs } from './config.js';
2
+ import { spawnOpencodePlugin } from './spawn.js';
3
+ /** Package directory used by OpenCode to cache plugin installs. */
4
+ export declare const PACKAGES_DIR_BASENAME: readonly [".cache", "opencode", "packages"];
5
+ /** Exact cache directory name we look for (bare specifier, no version suffix). */
6
+ export declare const CACHE_DIR_BASENAME = "opencode-rules-md";
7
+ /**
8
+ * Resolve the user's home directory, honoring a custom HOME env var.
9
+ * Used by both resolveCachePaths and the config loader.
10
+ */
11
+ export declare function resolveHome(env?: NodeJS.ProcessEnv): string;
12
+ /**
13
+ * Return the absolute path of the OpenCode packages cache directory.
14
+ */
15
+ export declare function resolvePackagesDir(env?: NodeJS.ProcessEnv): string;
16
+ /**
17
+ * Return the cache directories that match the opencode-rules-md prefix.
18
+ *
19
+ * Real-world layout under ~/.cache/opencode/packages/ looks like:
20
+ * opencode-rules-md/
21
+ * opencode-rules-md@latest/
22
+ * some-other-plugin/
23
+ *
24
+ * We glob-match anything starting with `opencode-rules-md` (exact or with
25
+ * an `@<version>` suffix). When an injected fs is provided we list the
26
+ * directory and filter; without one we return the two most common shapes
27
+ * so callers can pre-check existence cheaply.
28
+ */
29
+ export declare function resolveCachePaths(env?: NodeJS.ProcessEnv, fs?: CliFs): string[];
30
+ export interface UpdateOptions {
31
+ /** Injected latest version (test seam). Defaults to a real npm lookup. */
32
+ latestVersion?: string | null | undefined;
33
+ /** Print the plan without writing or spawning. */
34
+ dryRun?: boolean;
35
+ /** Injected spawn function (test seam). Defaults to spawnOpencodePlugin. */
36
+ spawn?: typeof spawnOpencodePlugin;
37
+ }
38
+ export interface UpdateResult {
39
+ status: 'stale' | 'current' | 'unreachable';
40
+ cachePaths: string[];
41
+ /** Re-install instruction; empty when status === 'current'. */
42
+ instruction: string;
43
+ }
44
+ /**
45
+ * Extract the version portion of an `opencode-rules-md@<version>` specifier.
46
+ * Returns null when the specifier has no `@version` segment.
47
+ */
48
+ export declare function extractVersion(specifier: string): string | null;
49
+ /**
50
+ * Recursively delete a directory and all its contents using the injected fs.
51
+ * Best-effort — a failed purge is not fatal; we want the update to keep going.
52
+ */
53
+ export declare function purgeDirectory(fs: CliFs, dirPath: string): void;
54
+ /**
55
+ * Run the update command.
56
+ *
57
+ * 1. Resolve the latest published version from npm (or use the injected mock).
58
+ * 2. Read the installed version from the user's opencode config.
59
+ * 3. If unreachable, log and return.
60
+ * 4. If current, log and return.
61
+ * 5. Otherwise: purge stale cache directories, then spawn
62
+ * `opencode plugin opencode-rules-md --global --force`.
63
+ */
64
+ export declare const runUpdate: (fs: CliFs, env: NodeJS.ProcessEnv, log: (s: string) => void, _error: (s: string) => void, opts?: UpdateOptions) => Promise<UpdateResult>;
65
+ //# sourceMappingURL=update.d.ts.map
@@ -0,0 +1 @@
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"}