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.
- package/dist/cli.mjs +906 -0
- package/dist/src/cli/config.d.ts +104 -0
- package/dist/src/cli/config.d.ts.map +1 -0
- package/dist/src/cli/config.js +397 -0
- package/dist/src/cli/config.js.map +1 -0
- package/dist/src/cli/install.d.ts +50 -0
- package/dist/src/cli/install.d.ts.map +1 -0
- package/dist/src/cli/install.js +67 -0
- package/dist/src/cli/install.js.map +1 -0
- package/dist/src/cli/main.d.ts +19 -0
- package/dist/src/cli/main.d.ts.map +1 -0
- package/dist/src/cli/main.js +247 -0
- package/dist/src/cli/main.js.map +1 -0
- package/dist/src/cli/real-fs.d.ts +3 -0
- package/dist/src/cli/real-fs.d.ts.map +1 -0
- package/dist/src/cli/real-fs.js +32 -0
- package/dist/src/cli/real-fs.js.map +1 -0
- package/dist/src/cli/registry.d.ts +12 -0
- package/dist/src/cli/registry.d.ts.map +1 -0
- package/dist/src/cli/registry.js +34 -0
- package/dist/src/cli/registry.js.map +1 -0
- 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 +51 -0
- package/dist/src/cli/status.d.ts.map +1 -0
- package/dist/src/cli/status.js +214 -0
- package/dist/src/cli/status.js.map +1 -0
- package/dist/src/cli/uninstall.d.ts +30 -0
- package/dist/src/cli/uninstall.d.ts.map +1 -0
- package/dist/src/cli/uninstall.js +128 -0
- package/dist/src/cli/uninstall.js.map +1 -0
- package/dist/src/cli/update.d.ts +65 -0
- package/dist/src/cli/update.d.ts.map +1 -0
- package/dist/src/cli/update.js +205 -0
- package/dist/src/cli/update.js.map +1 -0
- package/package.json +7 -2
- package/src/cli/config.ts +480 -0
- package/src/cli/install.ts +103 -0
- package/src/cli/main.ts +308 -0
- package/src/cli/real-fs.ts +44 -0
- package/src/cli/registry.ts +36 -0
- package/src/cli/spawn.ts +76 -0
- package/src/cli/status.ts +293 -0
- package/src/cli/uninstall.ts +177 -0
- 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":"AAAA,8EAA8E;AAC9E,6EAA6E;AAC7E,EAAE;AACF,2DAA2D;AAC3D,EAAE;AACF,0EAA0E;AAC1E,wEAAwE;AACxE,yCAAyC;AACzC,4EAA4E;AAC5E,gEAAgE;AAChE,yEAAyE;AACzE,uEAAuE;AACvE,6CAA6C;AAC7C,8EAA8E;AAE9E,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,oBAAoB,GAGrB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAuChD,gFAAgF;AAEhF,MAAM,aAAa,GAAG,mBAAmB,CAAC;AAC1C,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAE5B,MAAM,gBAAgB,GAAG,CAAC,UAAU,EAAE,KAAK,CAAU,CAAC;AAEtD,iFAAiF;AAEjF;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAC5B,EAAS,EACT,GAAsB,EACtB,GAAwB,EACxB,OAAsB,EAAE,EACD,EAAE;IACzB,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,KAAK,SAAS;QAC7C,CAAC,CAAC,IAAI,CAAC,aAAa;QACpB,CAAC,CAAC,MAAM,kBAAkB,EAAE,CAAC;IAE/B,KAAK,MAAM,QAAQ,IAAI,gBAAgB,EAAE,CAAC;QACxC,MAAM,MAAM,GAAG,gBAAgB,CAAC,EAAE,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAW,CAAC,CAAC,sBAAsB;QACrE,MAAM,OAAO,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;QAE5D,MAAM,KAAK,GAAgB;YACzB,QAAQ;YACR,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,MAAM;YACN,SAAS,EAAE,KAAK;YAChB,YAAY,EAAE,CAAC,MAAM,CAAC,MAAM,IAAI,KAAK,KAAK,IAAI;YAC9C,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;YACtD,MAAM;YACN,QAAQ,EACN,KAAK,KAAK,IAAI,IAAI,MAAM,KAAK,IAAI;gBAC/B,CAAC,CAAC,KAAK,KAAK,qBAAqB,MAAM,EAAE;gBACzC,CAAC,CAAC,IAAI;SACX,CAAC;QAEF,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAEpB,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACnB,GAAG,CAAC,QAAQ,QAAQ,+BAA+B,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YAClE,SAAS;QACX,CAAC;QAED,GAAG,CAAC,QAAQ,QAAQ,GAAG,MAAM,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAClD,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,aAAa,GACjB,KAAK,CAAC,QAAQ,KAAK,IAAI;gBACrB,CAAC,CAAC,WAAW;gBACb,CAAC,CAAC,KAAK,CAAC,QAAQ,KAAK,KAAK;oBACxB,CAAC,CAAC,uBAAuB,MAAM,IAAI,SAAS,GAAG;oBAC/C,CAAC,CAAC,EAAE,CAAC;YACX,GAAG,CAAC,wBAAwB,KAAK,GAAG,aAAa,EAAE,CAAC,CAAC;QACvD,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,oCAAoC,CAAC,CAAC;QAC5C,CAAC;QAED,IAAI,KAAK,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,GAAG,CAAC,oBAAoB,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,CAAC;AACrB,CAAC,CAAC;AAEF,iFAAiF;AAEjF;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAC5B,EAAS,EACT,GAAsB,EACtB,GAAwB,EACxB,KAA0B,EAC1B,OAAsB,EAAE,EACD,EAAE;IACzB,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,IAAI,GAAa,EAAE,CAAC;IAE1B,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY;IAC9E,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC;IAEjD,2EAA2E;IAC3E,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IACzB,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC5C,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;YAC1B,IAAI,CAAC;gBACH,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,SAAS,CAA6B,CAAC;gBACtE,OAAO,UAAU,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;YAChC,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,6EAA6E;IAC7E,GAAG,CAAC,0BAA0B,CAAC,CAAC;IAChC,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;IACjE,IAAI,SAAS,GAAG,gBAAgB,EAAE,CAAC;QACjC,MAAM,CAAC,IAAI,CAAC,WAAW,WAAW,iCAAiC,gBAAgB,EAAE,CAAC,CAAC;QACvF,KAAK,CAAC,mBAAmB,WAAW,kBAAkB,gBAAgB,2CAA2C,CAAC,CAAC;IACrH,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,aAAa,WAAW,OAAO,CAAC,CAAC;IACvC,CAAC;IAED,8EAA8E;IAC9E,GAAG,CAAC,qBAAqB,CAAC,CAAC;IAC3B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;QAChE,KAAK,CAAC,kEAAkE,CAAC,CAAC;IAC5E,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,uBAAuB,CAAC,CAAC;IAC/B,CAAC;IAED,8EAA8E;IAC9E,KAAK,MAAM,QAAQ,IAAI,gBAAgB,EAAE,CAAC;QACxC,GAAG,CAAC,YAAY,QAAQ,YAAY,CAAC,CAAC;QACtC,MAAM,MAAM,GAAiB,gBAAgB,CAAC,EAAE,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;QAEjE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACnB,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,wBAAwB,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YAChE,GAAG,CAAC,KAAK,QAAQ,gDAAgD,CAAC,CAAC;YACnE,SAAS;QACX,CAAC;QAED,GAAG,CAAC,KAAK,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC5D,MAAM,OAAO,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;QAE5D,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,CAAC,IAAI,CAAC,GAAG,QAAQ,kCAAkC,KAAK,GAAG,CAAC,CAAC;YACjE,GAAG,CAAC,wBAAwB,KAAK,EAAE,CAAC,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,wBAAwB,CAAC,CAAC;YACnD,GAAG,CAAC,oCAAoC,CAAC,CAAC;QAC5C,CAAC;QAED,2EAA2E;QAC3E,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,SAAS,EAAE,CAAC;YAChF,QAAQ,CAAC,IAAI,CACX,GAAG,QAAQ,uGAAuG,CACnH,CAAC;YACF,GAAG,CAAC,YAAY,QAAQ,uDAAuD,CAAC,CAAC;QACnF,CAAC;QAED,6EAA6E;QAC7E,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACpE,IACE,WAAW,KAAK,SAAS;YACzB,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;YAC3B,OAAO,WAAW,KAAK,QAAQ;YAC/B,OAAO,WAAW,KAAK,QAAQ,EAC/B,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,GAAG,QAAQ,qEAAqE,CAAC,CAAC;YAC9F,KAAK,CAAC,WAAW,QAAQ,wBAAwB,CAAC,CAAC;QACrD,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,uBAAuB,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,GAAG,CAAC,4BAA4B,CAAC,CAAC;IAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;IACnE,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,QAAQ,CAAC,IAAI,CAAC,+BAA+B,QAAQ,EAAE,CAAC,CAAC;QACzD,GAAG,CAAC,KAAK,QAAQ,6DAA6D,CAAC,CAAC;IAClF,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,KAAK,QAAQ,UAAU,CAAC,CAAC;IAC/B,CAAC;IAED,6EAA6E;IAC7E,GAAG,CAAC,oCAAoC,CAAC,CAAC;IAC1C,MAAM,UAAU,GAAG,iBAAiB,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAC9C,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,IAAI,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAC;QAChF,GAAG,CAAC,6CAA6C,CAAC,CAAC;IACrD,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,oBAAoB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,8EAA8E;IAC9E,MAAM,SAAS,GAAG,GAAG,CAAC,mBAAmB,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IACpF,GAAG,CAAC,2CAA2C,CAAC,CAAC;IACjD,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IACrC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,2CAA2C,SAAS,EAAE,CAAC,CAAC;QACpE,KAAK,CAAC,sCAAsC,SAAS,EAAE,CAAC,CAAC;IAC3D,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,KAAK,SAAS,YAAY,CAAC,CAAC;IAClC,CAAC;IAED,8EAA8E;IAC9E,GAAG,CAAC,EAAE,CAAC,CAAC;IACR,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,GAAG,CAAC,iCAAiC,CAAC,CAAC;IACzC,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,eAAe,MAAM,CAAC,MAAM,+CAA+C,CAAC,CAAC;QACnF,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAClD,CAAC;IAED,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;QACvB,MAAM;QACN,QAAQ;QACR,IAAI;KACL,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -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"}
|