@pleri/olam-cli 0.1.39 → 0.1.41

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.
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Smoke tests for `olam clean`'s formatting + dry-run path. The
3
+ * categorisation logic is exercised against a fixture worlds dir
4
+ * with a known shape; the file ops are limited to fs.rmSync calls
5
+ * we make in --apply mode (covered separately by reapEntry tests
6
+ * if/when that surface needs deeper coverage).
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=clean.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clean.test.d.ts","sourceRoot":"","sources":["../../../src/commands/__tests__/clean.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Smoke tests for `olam clean`'s formatting + dry-run path. The
3
+ * categorisation logic is exercised against a fixture worlds dir
4
+ * with a known shape; the file ops are limited to fs.rmSync calls
5
+ * we make in --apply mode (covered separately by reapEntry tests
6
+ * if/when that surface needs deeper coverage).
7
+ */
8
+ import { describe, expect, it, beforeEach, afterEach, vi } from 'vitest';
9
+ import fs from 'node:fs';
10
+ import os from 'node:os';
11
+ import path from 'node:path';
12
+ import { runClean } from '../clean.js';
13
+ let tmpHome;
14
+ let originalHome;
15
+ let stdoutChunks;
16
+ let stderrChunks;
17
+ function mockStdout() {
18
+ stdoutChunks = [];
19
+ stderrChunks = [];
20
+ vi.spyOn(process.stdout, 'write').mockImplementation((chunk) => {
21
+ stdoutChunks.push(typeof chunk === 'string' ? chunk : Buffer.from(chunk).toString());
22
+ return true;
23
+ });
24
+ vi.spyOn(process.stderr, 'write').mockImplementation((chunk) => {
25
+ stderrChunks.push(typeof chunk === 'string' ? chunk : Buffer.from(chunk).toString());
26
+ return true;
27
+ });
28
+ }
29
+ beforeEach(() => {
30
+ originalHome = process.env.HOME;
31
+ tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'olam-clean-test-'));
32
+ process.env.HOME = tmpHome;
33
+ // Minimal shape — clean.ts only needs ~/.olam/worlds/ + the registry,
34
+ // and we test against the dry-run path so registry can be empty.
35
+ fs.mkdirSync(path.join(tmpHome, '.olam', 'worlds'), { recursive: true });
36
+ });
37
+ afterEach(() => {
38
+ vi.restoreAllMocks();
39
+ if (originalHome !== undefined)
40
+ process.env.HOME = originalHome;
41
+ else
42
+ delete process.env.HOME;
43
+ fs.rmSync(tmpHome, { recursive: true, force: true });
44
+ });
45
+ describe('runClean — dry-run', () => {
46
+ it('returns 0 and lists no entries when worlds dir is empty', async () => {
47
+ mockStdout();
48
+ const code = await runClean({
49
+ apply: false,
50
+ includeDirty: false,
51
+ yes: false,
52
+ json: false,
53
+ });
54
+ expect(code).toBe(0);
55
+ const out = stdoutChunks.join('');
56
+ expect(out).toContain('no worlds on disk');
57
+ expect(out).toContain('Dry-run only');
58
+ });
59
+ it('emits JSON inventory when --json is set', async () => {
60
+ fs.mkdirSync(path.join(tmpHome, '.olam', 'worlds', 'gold-arc-1454'), { recursive: true });
61
+ fs.writeFileSync(path.join(tmpHome, '.olam', 'worlds', 'gold-arc-1454', 'world.db'), Buffer.alloc(1024));
62
+ mockStdout();
63
+ const code = await runClean({
64
+ apply: false,
65
+ includeDirty: false,
66
+ yes: false,
67
+ json: true,
68
+ });
69
+ expect(code).toBe(0);
70
+ const out = stdoutChunks.join('');
71
+ const parsed = JSON.parse(out);
72
+ expect(parsed.entries).toHaveLength(1);
73
+ expect(parsed.entries[0]?.id).toBe('gold-arc-1454');
74
+ expect(parsed.entries[0]?.category).toBe('orphan');
75
+ expect(parsed.entries[0]?.bytes).toBe(1024);
76
+ });
77
+ it('classifies a no-git directory as orphan', async () => {
78
+ fs.mkdirSync(path.join(tmpHome, '.olam', 'worlds', 'no-git-test'), { recursive: true });
79
+ fs.writeFileSync(path.join(tmpHome, '.olam', 'worlds', 'no-git-test', 'a.bin'), Buffer.alloc(2048));
80
+ mockStdout();
81
+ const code = await runClean({
82
+ apply: false,
83
+ includeDirty: false,
84
+ yes: false,
85
+ json: true,
86
+ });
87
+ expect(code).toBe(0);
88
+ const parsed = JSON.parse(stdoutChunks.join(''));
89
+ expect(parsed.entries.find((e) => e.id === 'no-git-test')?.category).toBe('orphan');
90
+ });
91
+ it('handles a missing worlds directory gracefully', async () => {
92
+ fs.rmSync(path.join(tmpHome, '.olam', 'worlds'), { recursive: true });
93
+ mockStdout();
94
+ const code = await runClean({
95
+ apply: false,
96
+ includeDirty: false,
97
+ yes: false,
98
+ json: true,
99
+ });
100
+ expect(code).toBe(0);
101
+ const parsed = JSON.parse(stdoutChunks.join(''));
102
+ expect(parsed.entries).toHaveLength(0);
103
+ });
104
+ });
105
+ //# sourceMappingURL=clean.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clean.test.js","sourceRoot":"","sources":["../../../src/commands/__tests__/clean.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * olam clean — reap orphan world filesystem state.
3
+ *
4
+ * The "no new orphans" half of the contract:
5
+ * - destroy.ts → destroyWorld() already calls fs.rmSync on the
6
+ * workspace dir, but the result is best-effort (try/catch swallows).
7
+ * - This command audits ~/.olam/worlds/<id>/ against the live
8
+ * registry + git worktree state, and either lists what's drift
9
+ * (default, dry-run) or reaps it (`--apply`).
10
+ *
11
+ * Categorisation of each on-disk world:
12
+ *
13
+ * active — registry knows about it AND status != destroyed.
14
+ * Always preserved. Excluded from --apply.
15
+ *
16
+ * dirty — git worktree registered AND has uncommitted changes
17
+ * or unpushed commits. Preserved by default; deletable
18
+ * via `--include-dirty` (with a final summary list so
19
+ * the operator sees what's about to disappear).
20
+ *
21
+ * stale-wt — git worktree registered but clean (no uncommits, no
22
+ * unpushed). Reaped via `git worktree remove --force`,
23
+ * which drops both the registration AND the directory.
24
+ *
25
+ * orphan — neither in the registry nor a registered worktree.
26
+ * Just a directory on disk. Reaped via `rm -rf`.
27
+ *
28
+ * Default invocation prints the table + total reclaimable bytes and
29
+ * exits 0 without touching disk. `--apply` performs the reap.
30
+ */
31
+ import type { Command } from 'commander';
32
+ interface CleanOptions {
33
+ readonly apply: boolean;
34
+ readonly includeDirty: boolean;
35
+ readonly yes: boolean;
36
+ readonly json: boolean;
37
+ }
38
+ export declare function registerClean(program: Command): void;
39
+ export declare function runClean(opts: CleanOptions): Promise<number>;
40
+ export {};
41
+ //# sourceMappingURL=clean.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clean.d.ts","sourceRoot":"","sources":["../../src/commands/clean.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmBzC,UAAU,YAAY;IACpB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAsBpD;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CA8FlE"}
@@ -0,0 +1,382 @@
1
+ /**
2
+ * olam clean — reap orphan world filesystem state.
3
+ *
4
+ * The "no new orphans" half of the contract:
5
+ * - destroy.ts → destroyWorld() already calls fs.rmSync on the
6
+ * workspace dir, but the result is best-effort (try/catch swallows).
7
+ * - This command audits ~/.olam/worlds/<id>/ against the live
8
+ * registry + git worktree state, and either lists what's drift
9
+ * (default, dry-run) or reaps it (`--apply`).
10
+ *
11
+ * Categorisation of each on-disk world:
12
+ *
13
+ * active — registry knows about it AND status != destroyed.
14
+ * Always preserved. Excluded from --apply.
15
+ *
16
+ * dirty — git worktree registered AND has uncommitted changes
17
+ * or unpushed commits. Preserved by default; deletable
18
+ * via `--include-dirty` (with a final summary list so
19
+ * the operator sees what's about to disappear).
20
+ *
21
+ * stale-wt — git worktree registered but clean (no uncommits, no
22
+ * unpushed). Reaped via `git worktree remove --force`,
23
+ * which drops both the registration AND the directory.
24
+ *
25
+ * orphan — neither in the registry nor a registered worktree.
26
+ * Just a directory on disk. Reaped via `rm -rf`.
27
+ *
28
+ * Default invocation prints the table + total reclaimable bytes and
29
+ * exits 0 without touching disk. `--apply` performs the reap.
30
+ */
31
+ import fs from 'node:fs';
32
+ import os from 'node:os';
33
+ import path from 'node:path';
34
+ import { execFileSync } from 'node:child_process';
35
+ import { loadContext } from '../context.js';
36
+ import { printError, printInfo } from '../output.js';
37
+ export function registerClean(program) {
38
+ program
39
+ .command('clean')
40
+ .description('Reap orphan world filesystem state under ~/.olam/worlds/')
41
+ .option('--apply', 'Actually delete the orphans (default is dry-run)', false)
42
+ .option('--include-dirty', "Also delete worktrees with uncommitted changes (default preserves them)", false)
43
+ .option('-y, --yes', 'Skip the confirmation prompt under --apply', false)
44
+ .option('--json', 'Emit a machine-readable JSON inventory instead of the text table', false)
45
+ .action(async (raw) => {
46
+ const opts = {
47
+ apply: raw.apply === true,
48
+ includeDirty: raw.includeDirty === true,
49
+ yes: raw.yes === true,
50
+ json: raw.json === true,
51
+ };
52
+ const exitCode = await runClean(opts);
53
+ process.exitCode = exitCode;
54
+ });
55
+ }
56
+ export async function runClean(opts) {
57
+ const { ctx, error } = await loadContext();
58
+ if (!ctx) {
59
+ printError(error?.message ?? 'Olam is not configured. Run `olam init` first.');
60
+ return 1;
61
+ }
62
+ const worldsDir = path.join(os.homedir(), '.olam', 'worlds');
63
+ if (!fs.existsSync(worldsDir)) {
64
+ if (opts.json) {
65
+ process.stdout.write(`${JSON.stringify({ worldsDir, entries: [] })}\n`);
66
+ }
67
+ else {
68
+ printInfo('Clean', `No ${worldsDir} directory present.`);
69
+ }
70
+ return 0;
71
+ }
72
+ // Set of world ids the registry knows are still live (not destroyed).
73
+ const liveIds = new Set();
74
+ for (const w of ctx.worldManager.listWorlds()) {
75
+ if (w.status !== 'destroyed')
76
+ liveIds.add(w.id);
77
+ }
78
+ // Map of canonical-repo-managed worktrees, keyed by their path. We
79
+ // can't tell from the operator's repo path alone what the canonical
80
+ // repo is, so we resolve it lazily once: walk every world dir's
81
+ // `olam/` subdir, and if it's a worktree, ask its parent.
82
+ const worktreeMap = collectWorktrees(worldsDir);
83
+ const entries = [];
84
+ for (const id of fs.readdirSync(worldsDir).sort()) {
85
+ const fullPath = path.join(worldsDir, id);
86
+ const stat = safeStat(fullPath);
87
+ if (!stat || !stat.isDirectory())
88
+ continue;
89
+ entries.push(classifyWorld({ id, fullPath, liveIds, worktreeMap }));
90
+ }
91
+ if (opts.json) {
92
+ process.stdout.write(`${JSON.stringify({ worldsDir, entries }, null, 2)}\n`);
93
+ return 0;
94
+ }
95
+ printTable(entries);
96
+ // Deletable subset (for both dry-run summary and --apply path).
97
+ const deletable = entries.filter((e) => isDeletable(e, opts));
98
+ const reclaimable = deletable.reduce((acc, e) => acc + e.bytes, 0);
99
+ process.stdout.write(`\n Reclaimable: ${formatBytes(reclaimable)} across ${deletable.length} entries`);
100
+ if (entries.length > deletable.length) {
101
+ process.stdout.write(` (preserved ${entries.length - deletable.length}: live registry + ${opts.includeDirty ? 'none' : 'dirty worktrees'})`);
102
+ }
103
+ process.stdout.write('\n');
104
+ if (!opts.apply) {
105
+ process.stdout.write('\n Dry-run only. Re-run with `--apply` to delete.\n');
106
+ return 0;
107
+ }
108
+ if (deletable.length === 0) {
109
+ process.stdout.write(' Nothing to delete. Exit clean.\n');
110
+ return 0;
111
+ }
112
+ if (!opts.yes) {
113
+ process.stdout.write(`\n About to delete ${deletable.length} entries (${formatBytes(reclaimable)}). Pass --yes to skip this prompt.\n`);
114
+ const confirmed = await confirmInteractive();
115
+ if (!confirmed) {
116
+ process.stdout.write(' Aborted.\n');
117
+ return 0;
118
+ }
119
+ }
120
+ let removedBytes = 0;
121
+ let removedCount = 0;
122
+ for (const entry of deletable) {
123
+ const ok = reapEntry(entry);
124
+ if (ok) {
125
+ removedBytes += entry.bytes;
126
+ removedCount += 1;
127
+ }
128
+ else {
129
+ process.stderr.write(` ! failed to reap ${entry.id}\n`);
130
+ }
131
+ }
132
+ process.stdout.write(`\n Reaped ${removedCount}/${deletable.length} entries · ${formatBytes(removedBytes)} reclaimed.\n`);
133
+ return removedCount === deletable.length ? 0 : 1;
134
+ }
135
+ function classifyWorld(args) {
136
+ const { id, fullPath, liveIds, worktreeMap } = args;
137
+ const bytes = computeBytes(fullPath);
138
+ if (liveIds.has(id)) {
139
+ return { id, path: fullPath, bytes, category: 'active', note: 'in registry' };
140
+ }
141
+ const worktreeChild = path.join(fullPath, 'olam');
142
+ const worktreeInfo = worktreeMap.get(worktreeChild);
143
+ if (worktreeInfo) {
144
+ if (worktreeInfo.dirty > 0 || worktreeInfo.unpushed > 0) {
145
+ const flags = [];
146
+ if (worktreeInfo.dirty > 0)
147
+ flags.push(`dirty=${worktreeInfo.dirty}`);
148
+ if (worktreeInfo.unpushed > 0)
149
+ flags.push(`unpushed=${worktreeInfo.unpushed}`);
150
+ return {
151
+ id,
152
+ path: fullPath,
153
+ bytes,
154
+ category: 'dirty',
155
+ worktreePath: worktreeChild,
156
+ note: `${worktreeInfo.branch} · ${flags.join(' ')}`,
157
+ };
158
+ }
159
+ return {
160
+ id,
161
+ path: fullPath,
162
+ bytes,
163
+ category: 'stale-wt',
164
+ worktreePath: worktreeChild,
165
+ note: worktreeInfo.branch,
166
+ };
167
+ }
168
+ return { id, path: fullPath, bytes, category: 'orphan' };
169
+ }
170
+ function isDeletable(entry, opts) {
171
+ if (entry.category === 'active')
172
+ return false;
173
+ if (entry.category === 'dirty' && !opts.includeDirty)
174
+ return false;
175
+ return true;
176
+ }
177
+ function reapEntry(entry) {
178
+ if (entry.worktreePath) {
179
+ // Try a clean `git worktree remove --force` first — that drops the
180
+ // git registration AND the directory in one call. Fall back to
181
+ // raw rm if git can't find the canonical repo (e.g. deleted).
182
+ try {
183
+ const gitDir = resolveGitDirForWorktree(entry.worktreePath);
184
+ if (gitDir) {
185
+ execFileSync('git', ['worktree', 'remove', '--force', entry.worktreePath], {
186
+ cwd: gitDir,
187
+ stdio: 'pipe',
188
+ });
189
+ }
190
+ }
191
+ catch {
192
+ // Fallthrough to rm.
193
+ }
194
+ }
195
+ try {
196
+ fs.rmSync(entry.path, { recursive: true, force: true });
197
+ }
198
+ catch (err) {
199
+ process.stderr.write(` ! rm ${entry.path}: ${err instanceof Error ? err.message : String(err)}\n`);
200
+ return false;
201
+ }
202
+ // Final sanity check.
203
+ return !fs.existsSync(entry.path);
204
+ }
205
+ // ---------------------------------------------------------------------------
206
+ // Worktree discovery
207
+ // ---------------------------------------------------------------------------
208
+ /**
209
+ * Walk every world's `olam/` subdir, ask its `.git` file what canonical
210
+ * repo it refers to, and bucket worktrees by absolute path. Cheap enough
211
+ * to do every invocation — there are typically <500 dirs.
212
+ */
213
+ function collectWorktrees(worldsDir) {
214
+ const out = new Map();
215
+ for (const id of fs.readdirSync(worldsDir)) {
216
+ // Per-world layout: ~/.olam/worlds/<id>/<repo>/. We're only auditing
217
+ // the canonical "olam" worktree to detect dirty / unpushed; non-olam
218
+ // repos under the same world dir are reaped together with the world.
219
+ const child = path.join(worldsDir, id, 'olam');
220
+ const gitMarker = path.join(child, '.git');
221
+ if (!fs.existsSync(gitMarker))
222
+ continue;
223
+ const gitDir = resolveGitDirForWorktree(child);
224
+ if (!gitDir)
225
+ continue;
226
+ const branch = readBranch(child);
227
+ const dirty = countDirty(child);
228
+ const unpushed = countUnpushed(child);
229
+ out.set(child, { branch, dirty, unpushed, gitDir });
230
+ }
231
+ return out;
232
+ }
233
+ function resolveGitDirForWorktree(worktreePath) {
234
+ const gitMarker = path.join(worktreePath, '.git');
235
+ // .git inside a worktree is a file with `gitdir: <abs-path>`. We don't
236
+ // need to read it — `git rev-parse --show-toplevel` from inside the
237
+ // worktree resolves the canonical repo for us.
238
+ try {
239
+ const top = execFileSync('git', ['rev-parse', '--show-toplevel'], {
240
+ cwd: worktreePath,
241
+ encoding: 'utf-8',
242
+ stdio: 'pipe',
243
+ }).trim();
244
+ if (!top)
245
+ return null;
246
+ // For worktrees, --show-toplevel returns the worktree root; the
247
+ // canonical repo is one level up via --git-common-dir.
248
+ const common = execFileSync('git', ['rev-parse', '--git-common-dir'], {
249
+ cwd: worktreePath,
250
+ encoding: 'utf-8',
251
+ stdio: 'pipe',
252
+ }).trim();
253
+ if (!common)
254
+ return top;
255
+ return path.dirname(path.resolve(worktreePath, common));
256
+ }
257
+ catch {
258
+ return null;
259
+ }
260
+ // (gitMarker referenced for readability above; the lookup uses git itself)
261
+ void gitMarker;
262
+ }
263
+ function readBranch(worktreePath) {
264
+ try {
265
+ return execFileSync('git', ['branch', '--show-current'], {
266
+ cwd: worktreePath,
267
+ encoding: 'utf-8',
268
+ stdio: 'pipe',
269
+ }).trim() || '(detached)';
270
+ }
271
+ catch {
272
+ return '(unknown)';
273
+ }
274
+ }
275
+ function countDirty(worktreePath) {
276
+ try {
277
+ const out = execFileSync('git', ['status', '--porcelain'], {
278
+ cwd: worktreePath,
279
+ encoding: 'utf-8',
280
+ stdio: 'pipe',
281
+ });
282
+ return out.split('\n').filter((l) => l.trim()).length;
283
+ }
284
+ catch {
285
+ return 0;
286
+ }
287
+ }
288
+ function countUnpushed(worktreePath) {
289
+ try {
290
+ const out = execFileSync('git', ['log', '@{u}..HEAD', '--oneline'], {
291
+ cwd: worktreePath,
292
+ encoding: 'utf-8',
293
+ stdio: 'pipe',
294
+ });
295
+ return out.split('\n').filter((l) => l.trim()).length;
296
+ }
297
+ catch {
298
+ // No upstream → can't measure; treat as 0 to avoid false positives.
299
+ return 0;
300
+ }
301
+ }
302
+ // ---------------------------------------------------------------------------
303
+ // Disk + formatting helpers
304
+ // ---------------------------------------------------------------------------
305
+ function safeStat(p) {
306
+ try {
307
+ return fs.statSync(p);
308
+ }
309
+ catch {
310
+ return null;
311
+ }
312
+ }
313
+ function computeBytes(p) {
314
+ let total = 0;
315
+ const stack = [p];
316
+ while (stack.length > 0) {
317
+ const cur = stack.pop();
318
+ let st;
319
+ try {
320
+ st = fs.lstatSync(cur);
321
+ }
322
+ catch {
323
+ continue;
324
+ }
325
+ if (st.isSymbolicLink())
326
+ continue;
327
+ if (st.isDirectory()) {
328
+ let entries;
329
+ try {
330
+ entries = fs.readdirSync(cur);
331
+ }
332
+ catch {
333
+ continue;
334
+ }
335
+ for (const name of entries)
336
+ stack.push(path.join(cur, name));
337
+ }
338
+ else {
339
+ total += st.size;
340
+ }
341
+ }
342
+ return total;
343
+ }
344
+ function formatBytes(n) {
345
+ if (n < 1024)
346
+ return `${n}B`;
347
+ if (n < 1024 * 1024)
348
+ return `${(n / 1024).toFixed(1)}KB`;
349
+ if (n < 1024 * 1024 * 1024)
350
+ return `${(n / 1024 / 1024).toFixed(1)}MB`;
351
+ return `${(n / 1024 / 1024 / 1024).toFixed(2)}GB`;
352
+ }
353
+ function printTable(entries) {
354
+ if (entries.length === 0) {
355
+ process.stdout.write(' (no worlds on disk)\n');
356
+ return;
357
+ }
358
+ // Header.
359
+ process.stdout.write(` ${'category'.padEnd(10)} ${'size'.padStart(10)} ${'world id'.padEnd(28)} note\n`);
360
+ process.stdout.write(` ${'-'.repeat(10)} ${'-'.repeat(10)} ${'-'.repeat(28)} ${'-'.repeat(40)}\n`);
361
+ for (const e of entries) {
362
+ process.stdout.write(` ${e.category.padEnd(10)} ${formatBytes(e.bytes).padStart(10)} ${e.id.padEnd(28)} ${e.note ?? ''}\n`);
363
+ }
364
+ }
365
+ async function confirmInteractive() {
366
+ process.stdout.write(' Type `yes` to proceed: ');
367
+ const buf = [];
368
+ return new Promise((resolve) => {
369
+ const onData = (chunk) => {
370
+ buf.push(chunk);
371
+ if (Buffer.concat(buf).toString('utf-8').includes('\n')) {
372
+ process.stdin.removeListener('data', onData);
373
+ process.stdin.pause();
374
+ const answer = Buffer.concat(buf).toString('utf-8').trim();
375
+ resolve(answer.toLowerCase() === 'yes');
376
+ }
377
+ };
378
+ process.stdin.resume();
379
+ process.stdin.on('data', onData);
380
+ });
381
+ }
382
+ //# sourceMappingURL=clean.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clean.js","sourceRoot":"","sources":["../../src/commands/clean.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAGH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAoBrD,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,0DAA0D,CAAC;SACvE,MAAM,CAAC,SAAS,EAAE,kDAAkD,EAAE,KAAK,CAAC;SAC5E,MAAM,CACL,iBAAiB,EACjB,yEAAyE,EACzE,KAAK,CACN;SACA,MAAM,CAAC,WAAW,EAAE,4CAA4C,EAAE,KAAK,CAAC;SACxE,MAAM,CAAC,QAAQ,EAAE,kEAAkE,EAAE,KAAK,CAAC;SAC3F,MAAM,CAAC,KAAK,EAAE,GAA+E,EAAE,EAAE;QAChG,MAAM,IAAI,GAAiB;YACzB,KAAK,EAAE,GAAG,CAAC,KAAK,KAAK,IAAI;YACzB,YAAY,EAAE,GAAG,CAAC,YAAY,KAAK,IAAI;YACvC,GAAG,EAAE,GAAG,CAAC,GAAG,KAAK,IAAI;YACrB,IAAI,EAAE,GAAG,CAAC,IAAI,KAAK,IAAI;SACxB,CAAC;QACF,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;QACtC,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC9B,CAAC,CAAC,CAAC;AACP,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAkB;IAC/C,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,MAAM,WAAW,EAAE,CAAC;IAC3C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,UAAU,CAAC,KAAK,EAAE,OAAO,IAAI,gDAAgD,CAAC,CAAC;QAC/E,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC7D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;QAC1E,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,OAAO,EAAE,MAAM,SAAS,qBAAqB,CAAC,CAAC;QAC3D,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,sEAAsE;IACtE,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,YAAY,CAAC,UAAU,EAAE,EAAE,CAAC;QAC9C,IAAI,CAAC,CAAC,MAAM,KAAK,WAAW;YAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,mEAAmE;IACnE,oEAAoE;IACpE,gEAAgE;IAChE,0DAA0D;IAC1D,MAAM,WAAW,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAEhD,MAAM,OAAO,GAAiB,EAAE,CAAC;IACjC,KAAK,MAAM,EAAE,IAAI,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;YAAE,SAAS;QAC3C,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QAC7E,OAAO,CAAC,CAAC;IACX,CAAC;IAED,UAAU,CAAC,OAAO,CAAC,CAAC;IAEpB,gEAAgE;IAChE,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IAC9D,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACnE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,WAAW,CAAC,WAAW,CAAC,WAAW,SAAS,CAAC,MAAM,UAAU,CAAC,CAAC;IACxG,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;QACtC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,eAAe,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,qBAC9C,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,iBAC/B,GAAG,CACJ,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAE3B,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;QAC7E,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;QAC3D,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,uBAAuB,SAAS,CAAC,MAAM,aAAa,WAAW,CAAC,WAAW,CAAC,sCAAsC,CACnH,CAAC;QACF,MAAM,SAAS,GAAG,MAAM,kBAAkB,EAAE,CAAC;QAC7C,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YACrC,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IAED,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;QAC9B,MAAM,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;QAC5B,IAAI,EAAE,EAAE,CAAC;YACP,YAAY,IAAI,KAAK,CAAC,KAAK,CAAC;YAC5B,YAAY,IAAI,CAAC,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,cAAc,YAAY,IAAI,SAAS,CAAC,MAAM,cAAc,WAAW,CAAC,YAAY,CAAC,eAAe,CACrG,CAAC;IACF,OAAO,YAAY,KAAK,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,aAAa,CAAC,IAKtB;IACC,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IACpD,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IAErC,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;QACpB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;IAChF,CAAC;IAED,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAClD,MAAM,YAAY,GAAG,WAAW,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IACpD,IAAI,YAAY,EAAE,CAAC;QACjB,IAAI,YAAY,CAAC,KAAK,GAAG,CAAC,IAAI,YAAY,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;YACxD,MAAM,KAAK,GAAa,EAAE,CAAC;YAC3B,IAAI,YAAY,CAAC,KAAK,GAAG,CAAC;gBAAE,KAAK,CAAC,IAAI,CAAC,SAAS,YAAY,CAAC,KAAK,EAAE,CAAC,CAAC;YACtE,IAAI,YAAY,CAAC,QAAQ,GAAG,CAAC;gBAAE,KAAK,CAAC,IAAI,CAAC,YAAY,YAAY,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC/E,OAAO;gBACL,EAAE;gBACF,IAAI,EAAE,QAAQ;gBACd,KAAK;gBACL,QAAQ,EAAE,OAAO;gBACjB,YAAY,EAAE,aAAa;gBAC3B,IAAI,EAAE,GAAG,YAAY,CAAC,MAAM,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;aACpD,CAAC;QACJ,CAAC;QACD,OAAO;YACL,EAAE;YACF,IAAI,EAAE,QAAQ;YACd,KAAK;YACL,QAAQ,EAAE,UAAU;YACpB,YAAY,EAAE,aAAa;YAC3B,IAAI,EAAE,YAAY,CAAC,MAAM;SAC1B,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;AAC3D,CAAC;AAED,SAAS,WAAW,CAAC,KAAiB,EAAE,IAAkB;IACxD,IAAI,KAAK,CAAC,QAAQ,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC9C,IAAI,KAAK,CAAC,QAAQ,KAAK,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY;QAAE,OAAO,KAAK,CAAC;IACnE,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,SAAS,CAAC,KAAiB;IAClC,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;QACvB,mEAAmE;QACnE,+DAA+D;QAC/D,8DAA8D;QAC9D,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,wBAAwB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAC5D,IAAI,MAAM,EAAE,CAAC;gBACX,YAAY,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC,YAAY,CAAC,EAAE;oBACzE,GAAG,EAAE,MAAM;oBACX,KAAK,EAAE,MAAM;iBACd,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,qBAAqB;QACvB,CAAC;IACH,CAAC;IACD,IAAI,CAAC;QACH,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,KAAK,CAAC,IAAI,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpG,OAAO,KAAK,CAAC;IACf,CAAC;IACD,sBAAsB;IACtB,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E;;;;GAIG;AACH,SAAS,gBAAgB,CACvB,SAAiB;IAEjB,MAAM,GAAG,GAAG,IAAI,GAAG,EAA+E,CAAC;IACnG,KAAK,MAAM,EAAE,IAAI,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3C,qEAAqE;QACrE,qEAAqE;QACrE,qEAAqE;QACrE,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;QAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC3C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,SAAS;QACxC,MAAM,MAAM,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QACjC,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QAChC,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;QACtC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,wBAAwB,CAAC,YAAoB;IACpD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAClD,uEAAuE;IACvE,oEAAoE;IACpE,+CAA+C;IAC/C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAAE;YAChE,GAAG,EAAE,YAAY;YACjB,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,MAAM;SACd,CAAC,CAAC,IAAI,EAAE,CAAC;QACV,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QACtB,gEAAgE;QAChE,uDAAuD;QACvD,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,kBAAkB,CAAC,EAAE;YACpE,GAAG,EAAE,YAAY;YACjB,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,MAAM;SACd,CAAC,CAAC,IAAI,EAAE,CAAC;QACV,IAAI,CAAC,MAAM;YAAE,OAAO,GAAG,CAAC;QACxB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,2EAA2E;IAC3E,KAAK,SAAS,CAAC;AACjB,CAAC;AAED,SAAS,UAAU,CAAC,YAAoB;IACtC,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,gBAAgB,CAAC,EAAE;YACvD,GAAG,EAAE,YAAY;YACjB,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,MAAM;SACd,CAAC,CAAC,IAAI,EAAE,IAAI,YAAY,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,WAAW,CAAC;IACrB,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,YAAoB;IACtC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC,EAAE;YACzD,GAAG,EAAE,YAAY;YACjB,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,MAAM;SACd,CAAC,CAAC;QACH,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,YAAoB;IACzC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,WAAW,CAAC,EAAE;YAClE,GAAG,EAAE,YAAY;YACjB,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,MAAM;SACd,CAAC,CAAC;QACH,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,oEAAoE;QACpE,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,4BAA4B;AAC5B,8EAA8E;AAE9E,SAAS,QAAQ,CAAC,CAAS;IACzB,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,CAAS;IAC7B,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;IAClB,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,EAAG,CAAC;QACzB,IAAI,EAAY,CAAC;QACjB,IAAI,CAAC;YACH,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,IAAI,EAAE,CAAC,cAAc,EAAE;YAAE,SAAS;QAClC,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;YACrB,IAAI,OAAiB,CAAC;YACtB,IAAI,CAAC;gBACH,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YAChC,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YACD,KAAK,MAAM,IAAI,IAAI,OAAO;gBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;QAC/D,CAAC;aAAM,CAAC;YACN,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC;QACnB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,WAAW,CAAC,CAAS;IAC5B,IAAI,CAAC,GAAG,IAAI;QAAE,OAAO,GAAG,CAAC,GAAG,CAAC;IAC7B,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI;QAAE,OAAO,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IACzD,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI;QAAE,OAAO,GAAG,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IACvE,OAAO,GAAG,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACpD,CAAC;AAED,SAAS,UAAU,CAAC,OAA8B;IAChD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAChD,OAAO;IACT,CAAC;IACD,UAAU;IACV,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,KAAK,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,CACvF,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IACvG,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,KAAK,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,KAClF,CAAC,CAAC,IAAI,IAAI,EACZ,IAAI,CACL,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,kBAAkB;IAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAClD,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,CAAC,KAAa,EAAQ,EAAE;YACrC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAChB,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxD,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAC7C,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;gBACtB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC3D,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC,CAAC;QACF,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QACvB,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "auth": "sha256:4e2ea22c5ef026ecf7b10892fbe381384b32e83636962d86d9ab1fc572972f8e",
3
- "devbox": "sha256:78fd37ed04b1be8fb8dff51d1fed076a795cdb2a172c8d90f4dbdfd713350154",
4
- "host-cp": "sha256:25788b159a70a543ed79cfb68b4d935006379ed8bfcdebb422fce7f2da43b785",
3
+ "devbox": "sha256:9363a1979d7df0ed2b2c964c183ba3e739383c146416f27b1ceb976f64648fd9",
4
+ "host-cp": "sha256:7687f465665a0a946cd1c16bbc5c384011bd68df752cab2c19e8f4deb2b263cb",
5
5
  "$schema_version": 1,
6
- "$published_version": "0.1.39",
6
+ "$published_version": "0.1.41",
7
7
  "$registry": "ghcr.io/pleri"
8
8
  }