@nocoo/otter 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +5 -0
- package/dist/bin.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +365 -0
- package/dist/cli.js.map +1 -0
- package/dist/collectors/applications.d.ts +19 -0
- package/dist/collectors/applications.d.ts.map +1 -0
- package/dist/collectors/applications.js +51 -0
- package/dist/collectors/applications.js.map +1 -0
- package/dist/collectors/base.d.ts +52 -0
- package/dist/collectors/base.d.ts.map +1 -0
- package/dist/collectors/base.js +186 -0
- package/dist/collectors/base.js.map +1 -0
- package/dist/collectors/claude-config.d.ts +39 -0
- package/dist/collectors/claude-config.d.ts.map +1 -0
- package/dist/collectors/claude-config.js +124 -0
- package/dist/collectors/claude-config.js.map +1 -0
- package/dist/collectors/homebrew.d.ts +16 -0
- package/dist/collectors/homebrew.d.ts.map +1 -0
- package/dist/collectors/homebrew.js +43 -0
- package/dist/collectors/homebrew.js.map +1 -0
- package/dist/collectors/index.d.ts +21 -0
- package/dist/collectors/index.d.ts.map +1 -0
- package/dist/collectors/index.js +28 -0
- package/dist/collectors/index.js.map +1 -0
- package/dist/collectors/opencode-config.d.ts +21 -0
- package/dist/collectors/opencode-config.d.ts.map +1 -0
- package/dist/collectors/opencode-config.js +88 -0
- package/dist/collectors/opencode-config.js.map +1 -0
- package/dist/collectors/shell-config.d.ts +24 -0
- package/dist/collectors/shell-config.d.ts.map +1 -0
- package/dist/collectors/shell-config.js +133 -0
- package/dist/collectors/shell-config.js.map +1 -0
- package/dist/commands/config.d.ts +17 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +21 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/scan.d.ts +11 -0
- package/dist/commands/scan.d.ts.map +1 -0
- package/dist/commands/scan.js +36 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/commands/snapshot.d.ts +52 -0
- package/dist/commands/snapshot.d.ts.map +1 -0
- package/dist/commands/snapshot.js +203 -0
- package/dist/commands/snapshot.js.map +1 -0
- package/dist/config/manager.d.ts +13 -0
- package/dist/config/manager.d.ts.map +1 -0
- package/dist/config/manager.js +28 -0
- package/dist/config/manager.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/snapshot/builder.d.ts +7 -0
- package/dist/snapshot/builder.d.ts.map +1 -0
- package/dist/snapshot/builder.js +68 -0
- package/dist/snapshot/builder.js.map +1 -0
- package/dist/storage/local.d.ts +44 -0
- package/dist/storage/local.d.ts.map +1 -0
- package/dist/storage/local.js +107 -0
- package/dist/storage/local.js.map +1 -0
- package/dist/uploader/icons.d.ts +41 -0
- package/dist/uploader/icons.d.ts.map +1 -0
- package/dist/uploader/icons.js +80 -0
- package/dist/uploader/icons.js.map +1 -0
- package/dist/uploader/webhook.d.ts +7 -0
- package/dist/uploader/webhook.d.ts.map +1 -0
- package/dist/uploader/webhook.js +54 -0
- package/dist/uploader/webhook.js.map +1 -0
- package/dist/utils/icons.d.ts +34 -0
- package/dist/utils/icons.d.ts.map +1 -0
- package/dist/utils/icons.js +113 -0
- package/dist/utils/icons.js.map +1 -0
- package/dist/utils/redact.d.ts +41 -0
- package/dist/utils/redact.d.ts.map +1 -0
- package/dist/utils/redact.js +317 -0
- package/dist/utils/redact.js.map +1 -0
- package/package.json +45 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { readdir, stat } from "node:fs/promises";
|
|
3
|
+
import { BaseCollector } from "./base.js";
|
|
4
|
+
/** Well-known dotfiles to collect from home directory */
|
|
5
|
+
const DOTFILES = [
|
|
6
|
+
{ name: ".zshrc", redact: true },
|
|
7
|
+
{ name: ".zprofile", redact: true },
|
|
8
|
+
{ name: ".zshenv", redact: true },
|
|
9
|
+
{ name: ".zlogin", redact: true },
|
|
10
|
+
{ name: ".bashrc", redact: true },
|
|
11
|
+
{ name: ".bash_profile", redact: true },
|
|
12
|
+
{ name: ".profile", redact: true },
|
|
13
|
+
{ name: ".gitconfig", redact: true },
|
|
14
|
+
{ name: ".gitignore_global" },
|
|
15
|
+
{ name: ".vimrc" },
|
|
16
|
+
{ name: ".npmrc", redact: true },
|
|
17
|
+
{ name: ".yarnrc" },
|
|
18
|
+
{ name: ".editorconfig" },
|
|
19
|
+
{ name: ".tmux.conf", redact: true },
|
|
20
|
+
{ name: ".wgetrc", redact: true },
|
|
21
|
+
{ name: ".curlrc", redact: true },
|
|
22
|
+
{ name: ".hushlogin" },
|
|
23
|
+
{ name: ".netrc", redact: true },
|
|
24
|
+
];
|
|
25
|
+
/** Files inside ~/.ssh/ that are safe to collect (config only, no keys) */
|
|
26
|
+
const SSH_SAFE_FILES = ["config", "known_hosts"];
|
|
27
|
+
/** Well-known SSH key filename patterns (without path) */
|
|
28
|
+
const SSH_PRIVATE_KEY_PATTERNS = [
|
|
29
|
+
/^id_/, // id_rsa, id_ed25519, id_ecdsa, id_dsa, id_*
|
|
30
|
+
/^identity$/, // legacy SSH1
|
|
31
|
+
];
|
|
32
|
+
/** Extensions that indicate public keys */
|
|
33
|
+
const SSH_PUBLIC_KEY_EXT = ".pub";
|
|
34
|
+
/** Files in ~/.ssh/ that are NOT keys (skip during key detection) */
|
|
35
|
+
const SSH_NON_KEY_FILES = new Set([
|
|
36
|
+
"config",
|
|
37
|
+
"known_hosts",
|
|
38
|
+
"known_hosts.old",
|
|
39
|
+
"authorized_keys",
|
|
40
|
+
"authorized_keys2",
|
|
41
|
+
"environment",
|
|
42
|
+
"rc",
|
|
43
|
+
"agent",
|
|
44
|
+
]);
|
|
45
|
+
/**
|
|
46
|
+
* Classify an SSH filename as a key type, or null if not a key.
|
|
47
|
+
* Exported for testing.
|
|
48
|
+
*/
|
|
49
|
+
export function classifySshFile(name) {
|
|
50
|
+
if (SSH_NON_KEY_FILES.has(name))
|
|
51
|
+
return null;
|
|
52
|
+
// Public key check first (foo.pub)
|
|
53
|
+
if (name.endsWith(SSH_PUBLIC_KEY_EXT)) {
|
|
54
|
+
return "public-key";
|
|
55
|
+
}
|
|
56
|
+
// Private key patterns
|
|
57
|
+
for (const pattern of SSH_PRIVATE_KEY_PATTERNS) {
|
|
58
|
+
if (pattern.test(name))
|
|
59
|
+
return "private-key";
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Collects shell and developer environment configuration files:
|
|
65
|
+
* - Common dotfiles (.zshrc, .bashrc, .gitconfig, etc.)
|
|
66
|
+
* - SSH config (but NOT private/public keys — only presence indicators)
|
|
67
|
+
*/
|
|
68
|
+
export class ShellConfigCollector extends BaseCollector {
|
|
69
|
+
id = "shell-config";
|
|
70
|
+
label = "Shell Configuration";
|
|
71
|
+
category = "environment";
|
|
72
|
+
async collect() {
|
|
73
|
+
return this.timed(async (result) => {
|
|
74
|
+
// 1. Collect well-known dotfiles
|
|
75
|
+
for (const { name: dotfile, redact } of DOTFILES) {
|
|
76
|
+
const file = await this.safeReadFile(join(this.homeDir, dotfile), result, { redact });
|
|
77
|
+
if (file)
|
|
78
|
+
result.files.push(file);
|
|
79
|
+
}
|
|
80
|
+
// 2. Collect safe SSH config files
|
|
81
|
+
for (const sshFile of SSH_SAFE_FILES) {
|
|
82
|
+
const file = await this.safeReadFile(join(this.homeDir, ".ssh", sshFile), result);
|
|
83
|
+
if (file)
|
|
84
|
+
result.files.push(file);
|
|
85
|
+
}
|
|
86
|
+
// 3. Detect SSH key presence (never collect key content)
|
|
87
|
+
const sshKeys = await this.detectSshKeys(result);
|
|
88
|
+
result.lists.push(...sshKeys);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Scan ~/.ssh/ for key files and return presence indicators.
|
|
93
|
+
* Key content is NEVER read — only filenames and metadata.
|
|
94
|
+
*/
|
|
95
|
+
async detectSshKeys(result) {
|
|
96
|
+
const sshDir = join(this.homeDir, ".ssh");
|
|
97
|
+
const items = [];
|
|
98
|
+
try {
|
|
99
|
+
const entries = await readdir(sshDir, { withFileTypes: true });
|
|
100
|
+
for (const entry of entries) {
|
|
101
|
+
if (!entry.isFile())
|
|
102
|
+
continue;
|
|
103
|
+
const keyType = classifySshFile(entry.name);
|
|
104
|
+
if (!keyType)
|
|
105
|
+
continue;
|
|
106
|
+
// Stat for modification time (useful for identifying stale keys)
|
|
107
|
+
let modifiedAt;
|
|
108
|
+
try {
|
|
109
|
+
const info = await stat(join(sshDir, entry.name));
|
|
110
|
+
modifiedAt = info.mtime.toISOString();
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
// stat failure is non-fatal
|
|
114
|
+
}
|
|
115
|
+
items.push({
|
|
116
|
+
name: entry.name,
|
|
117
|
+
meta: {
|
|
118
|
+
type: keyType,
|
|
119
|
+
source: ".ssh",
|
|
120
|
+
...(modifiedAt ? { modifiedAt } : {}),
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
if (err.code !== "ENOENT") {
|
|
127
|
+
result.errors.push(`Failed to scan SSH directory: ${err.message}`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return items;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=shell-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell-config.js","sourceRoot":"","sources":["../../src/collectors/shell-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { OtterConfig } from "@otter/core";
|
|
2
|
+
import type { ConfigManager } from "../config/manager.js";
|
|
3
|
+
export type ConfigAction = {
|
|
4
|
+
action: "set";
|
|
5
|
+
key: keyof OtterConfig;
|
|
6
|
+
value: string;
|
|
7
|
+
} | {
|
|
8
|
+
action: "get";
|
|
9
|
+
key: keyof OtterConfig;
|
|
10
|
+
} | {
|
|
11
|
+
action: "show";
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Execute a config operation. Pure logic, decoupled from CLI I/O.
|
|
15
|
+
*/
|
|
16
|
+
export declare function executeConfig(manager: ConfigManager, params: ConfigAction): Promise<string | OtterConfig | undefined>;
|
|
17
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,MAAM,YAAY,GACpB;IAAE,MAAM,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACxD;IAAE,MAAM,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,WAAW,CAAA;CAAE,GACzC;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvB;;GAEG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC,CAgB3C"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Execute a config operation. Pure logic, decoupled from CLI I/O.
|
|
3
|
+
*/
|
|
4
|
+
export async function executeConfig(manager, params) {
|
|
5
|
+
switch (params.action) {
|
|
6
|
+
case "set": {
|
|
7
|
+
const config = await manager.load();
|
|
8
|
+
config[params.key] = params.value;
|
|
9
|
+
await manager.save(config);
|
|
10
|
+
return params.value;
|
|
11
|
+
}
|
|
12
|
+
case "get": {
|
|
13
|
+
const config = await manager.load();
|
|
14
|
+
return config[params.key];
|
|
15
|
+
}
|
|
16
|
+
case "show": {
|
|
17
|
+
return await manager.load();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAQA;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,OAAsB,EACtB,MAAoB;IAEpB,QAAQ,MAAM,CAAC,MAAM,EAAE,CAAC;QACtB,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;YACnC,MAAiC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC;YAC9D,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC3B,OAAO,MAAM,CAAC,KAAK,CAAC;QACtB,CAAC;QACD,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;YACpC,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC5B,CAAC;QACD,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,OAAO,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;QAC9B,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Collector, CollectorResult, Snapshot } from "@otter/core";
|
|
2
|
+
export interface ScanOptions {
|
|
3
|
+
/** Called after each collector finishes */
|
|
4
|
+
onProgress?: (collectorId: string, result: CollectorResult) => void;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Execute the scan operation: run all collectors and build a snapshot.
|
|
8
|
+
* This is the pure logic function, decoupled from CLI I/O.
|
|
9
|
+
*/
|
|
10
|
+
export declare function executeScan(collectors: Collector[], options?: ScanOptions): Promise<Snapshot>;
|
|
11
|
+
//# sourceMappingURL=scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGxE,MAAM,WAAW,WAAW;IAC1B,2CAA2C;IAC3C,UAAU,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;CACrE;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,UAAU,EAAE,SAAS,EAAE,EACvB,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,QAAQ,CAAC,CA6BnB"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { buildSnapshot } from "../snapshot/builder.js";
|
|
2
|
+
/**
|
|
3
|
+
* Execute the scan operation: run all collectors and build a snapshot.
|
|
4
|
+
* This is the pure logic function, decoupled from CLI I/O.
|
|
5
|
+
*/
|
|
6
|
+
export async function executeScan(collectors, options = {}) {
|
|
7
|
+
// Run collectors sequentially to allow progress reporting
|
|
8
|
+
const results = [];
|
|
9
|
+
for (const collector of collectors) {
|
|
10
|
+
let result;
|
|
11
|
+
try {
|
|
12
|
+
result = await collector.collect();
|
|
13
|
+
}
|
|
14
|
+
catch (err) {
|
|
15
|
+
result = {
|
|
16
|
+
id: collector.id,
|
|
17
|
+
label: collector.label,
|
|
18
|
+
category: collector.category,
|
|
19
|
+
files: [],
|
|
20
|
+
lists: [],
|
|
21
|
+
errors: [
|
|
22
|
+
`Collector '${collector.id}' crashed: ${err.message}`,
|
|
23
|
+
],
|
|
24
|
+
durationMs: 0,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
results.push(result);
|
|
28
|
+
options.onProgress?.(collector.id, result);
|
|
29
|
+
}
|
|
30
|
+
// Build snapshot with pre-collected results
|
|
31
|
+
// We bypass buildSnapshot's internal collection since we already ran them
|
|
32
|
+
const snapshot = await buildSnapshot([]);
|
|
33
|
+
snapshot.collectors = results;
|
|
34
|
+
return snapshot;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAOvD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,UAAuB,EACvB,UAAuB,EAAE;IAEzB,0DAA0D;IAC1D,MAAM,OAAO,GAAsB,EAAE,CAAC;IACtC,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,MAAuB,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE,CAAC;QACrC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG;gBACP,EAAE,EAAE,SAAS,CAAC,EAAE;gBAChB,KAAK,EAAE,SAAS,CAAC,KAAK;gBACtB,QAAQ,EAAE,SAAS,CAAC,QAAQ;gBAC5B,KAAK,EAAE,EAAE;gBACT,KAAK,EAAE,EAAE;gBACT,MAAM,EAAE;oBACN,cAAc,SAAS,CAAC,EAAE,cAAe,GAAa,CAAC,OAAO,EAAE;iBACjE;gBACD,UAAU,EAAE,CAAC;aACd,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrB,OAAO,CAAC,UAAU,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IAC7C,CAAC;IAED,4CAA4C;IAC5C,0EAA0E;IAC1E,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,EAAE,CAAC,CAAC;IACzC,QAAQ,CAAC,UAAU,GAAG,OAAO,CAAC;IAC9B,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { Snapshot } from "@otter/core";
|
|
2
|
+
import type { SnapshotMeta } from "../storage/local.js";
|
|
3
|
+
/**
|
|
4
|
+
* Format a file size in bytes to a human-readable string.
|
|
5
|
+
*/
|
|
6
|
+
declare function formatSize(bytes: number): string;
|
|
7
|
+
/**
|
|
8
|
+
* Format an ISO 8601 date string to a short "YYYY-MM-DD HH:MM" format.
|
|
9
|
+
*/
|
|
10
|
+
declare function formatDate(iso: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Format the snapshot list output for the terminal.
|
|
13
|
+
* Pure logic function, returns lines to print.
|
|
14
|
+
*/
|
|
15
|
+
export declare function formatSnapshotList(metas: SnapshotMeta[]): string;
|
|
16
|
+
/**
|
|
17
|
+
* Format a detailed view of a single snapshot.
|
|
18
|
+
*/
|
|
19
|
+
export declare function formatSnapshotDetail(snapshot: Snapshot): string;
|
|
20
|
+
/** A single diff entry describing an added, removed, or changed item */
|
|
21
|
+
export interface DiffEntry {
|
|
22
|
+
type: "added" | "removed" | "changed";
|
|
23
|
+
label: string;
|
|
24
|
+
}
|
|
25
|
+
/** Diff result for a single collector */
|
|
26
|
+
export interface CollectorDiff {
|
|
27
|
+
collectorId: string;
|
|
28
|
+
collectorLabel: string;
|
|
29
|
+
files: DiffEntry[];
|
|
30
|
+
lists: DiffEntry[];
|
|
31
|
+
}
|
|
32
|
+
/** Full diff result between two snapshots */
|
|
33
|
+
export interface SnapshotDiffResult {
|
|
34
|
+
oldId: string;
|
|
35
|
+
newId: string;
|
|
36
|
+
addedCollectors: string[];
|
|
37
|
+
removedCollectors: string[];
|
|
38
|
+
collectors: CollectorDiff[];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Compute the diff between two snapshots at file+list level.
|
|
42
|
+
* Files are compared by path; lists are compared by name.
|
|
43
|
+
* Content-level diffing is out of scope — only presence/absence is tracked,
|
|
44
|
+
* plus a "changed" marker when a file exists in both but size differs.
|
|
45
|
+
*/
|
|
46
|
+
export declare function diffSnapshots(oldSnap: Snapshot, newSnap: Snapshot): SnapshotDiffResult;
|
|
47
|
+
/**
|
|
48
|
+
* Format a diff result for terminal output.
|
|
49
|
+
*/
|
|
50
|
+
export declare function formatSnapshotDiff(diff: SnapshotDiffResult): string;
|
|
51
|
+
export { formatSize, formatDate };
|
|
52
|
+
//# sourceMappingURL=snapshot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/commands/snapshot.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD;;GAEG;AACH,iBAAS,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQzC;AAED;;GAEG;AACH,iBAAS,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIvC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,MAAM,CAiBhE;AAMD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAwC/D;AAMD,wEAAwE;AACxE,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;IACtC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,yCAAyC;AACzC,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB;AAED,6CAA6C;AAC7C,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,UAAU,EAAE,aAAa,EAAE,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,QAAQ,EACjB,OAAO,EAAE,QAAQ,GAChB,kBAAkB,CA4CpB;AAmDD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAgDnE;AAED,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC"}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import pc from "picocolors";
|
|
2
|
+
/**
|
|
3
|
+
* Format a file size in bytes to a human-readable string.
|
|
4
|
+
*/
|
|
5
|
+
function formatSize(bytes) {
|
|
6
|
+
if (bytes < 1024)
|
|
7
|
+
return `${bytes} B`;
|
|
8
|
+
const kb = bytes / 1024;
|
|
9
|
+
if (kb < 1024)
|
|
10
|
+
return `${kb.toFixed(1)} KB`;
|
|
11
|
+
const mb = kb / 1024;
|
|
12
|
+
if (mb < 1024)
|
|
13
|
+
return `${mb.toFixed(2)} MB`;
|
|
14
|
+
const gb = mb / 1024;
|
|
15
|
+
return `${gb.toFixed(2)} GB`;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Format an ISO 8601 date string to a short "YYYY-MM-DD HH:MM" format.
|
|
19
|
+
*/
|
|
20
|
+
function formatDate(iso) {
|
|
21
|
+
const d = new Date(iso);
|
|
22
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
23
|
+
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Format the snapshot list output for the terminal.
|
|
27
|
+
* Pure logic function, returns lines to print.
|
|
28
|
+
*/
|
|
29
|
+
export function formatSnapshotList(metas) {
|
|
30
|
+
if (metas.length === 0) {
|
|
31
|
+
return "No local snapshots found.";
|
|
32
|
+
}
|
|
33
|
+
const header = `Local snapshots (${metas.length}):\n`;
|
|
34
|
+
const rows = metas.map((m) => {
|
|
35
|
+
const id = pc.bold(m.shortId);
|
|
36
|
+
const date = pc.dim(formatDate(m.createdAt));
|
|
37
|
+
const collectors = `${m.collectorCount} collectors`;
|
|
38
|
+
const files = `${m.fileCount} files`;
|
|
39
|
+
const lists = `${m.listCount} items`;
|
|
40
|
+
const size = pc.dim(formatSize(m.sizeBytes));
|
|
41
|
+
return ` ${id} ${date} ${collectors} ${files} ${lists} ${size}`;
|
|
42
|
+
});
|
|
43
|
+
return header + rows.join("\n");
|
|
44
|
+
}
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
// snapshot show
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
/**
|
|
49
|
+
* Format a detailed view of a single snapshot.
|
|
50
|
+
*/
|
|
51
|
+
export function formatSnapshotDetail(snapshot) {
|
|
52
|
+
const lines = [];
|
|
53
|
+
const m = snapshot.machine;
|
|
54
|
+
const machineName = m.computerName || m.hostname;
|
|
55
|
+
lines.push(`Snapshot ${pc.bold(snapshot.id.slice(0, 8))}`);
|
|
56
|
+
lines.push(` Created: ${formatDate(snapshot.createdAt)}`);
|
|
57
|
+
lines.push(` Machine: ${machineName} (${m.platform}/${m.arch}, ${m.osVersion})`);
|
|
58
|
+
lines.push(` User: ${m.username}`);
|
|
59
|
+
lines.push("");
|
|
60
|
+
for (const c of snapshot.collectors) {
|
|
61
|
+
const status = c.errors.length > 0 ? pc.yellow("⚠") : pc.green("✓");
|
|
62
|
+
lines.push(`${status} ${pc.bold(c.label)} [${c.id}] ${c.files.length} files, ${c.lists.length} items`);
|
|
63
|
+
for (const f of c.files) {
|
|
64
|
+
lines.push(` ${pc.dim(f.path)} (${formatSize(f.sizeBytes)})`);
|
|
65
|
+
}
|
|
66
|
+
if (c.lists.length > 0) {
|
|
67
|
+
const preview = c.lists
|
|
68
|
+
.slice(0, 10)
|
|
69
|
+
.map((l) => l.name)
|
|
70
|
+
.join(", ");
|
|
71
|
+
const suffix = c.lists.length > 10 ? `, ... +${c.lists.length - 10} more` : "";
|
|
72
|
+
lines.push(` ${pc.dim(`items: ${preview}${suffix}`)}`);
|
|
73
|
+
}
|
|
74
|
+
if (c.errors.length > 0) {
|
|
75
|
+
for (const e of c.errors) {
|
|
76
|
+
lines.push(` ${pc.yellow(`error: ${e}`)}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return lines.join("\n");
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Compute the diff between two snapshots at file+list level.
|
|
84
|
+
* Files are compared by path; lists are compared by name.
|
|
85
|
+
* Content-level diffing is out of scope — only presence/absence is tracked,
|
|
86
|
+
* plus a "changed" marker when a file exists in both but size differs.
|
|
87
|
+
*/
|
|
88
|
+
export function diffSnapshots(oldSnap, newSnap) {
|
|
89
|
+
const oldCollectorMap = new Map(oldSnap.collectors.map((c) => [c.id, c]));
|
|
90
|
+
const newCollectorMap = new Map(newSnap.collectors.map((c) => [c.id, c]));
|
|
91
|
+
const allIds = new Set([...oldCollectorMap.keys(), ...newCollectorMap.keys()]);
|
|
92
|
+
const addedCollectors = [];
|
|
93
|
+
const removedCollectors = [];
|
|
94
|
+
const collectors = [];
|
|
95
|
+
for (const id of allIds) {
|
|
96
|
+
const oldC = oldCollectorMap.get(id);
|
|
97
|
+
const newC = newCollectorMap.get(id);
|
|
98
|
+
if (!oldC && newC) {
|
|
99
|
+
addedCollectors.push(newC.label);
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
if (oldC && !newC) {
|
|
103
|
+
removedCollectors.push(oldC.label);
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
// Both exist — diff files and lists
|
|
107
|
+
const fileDiffs = diffFiles(oldC.files, newC.files);
|
|
108
|
+
const listDiffs = diffLists(oldC.lists, newC.lists);
|
|
109
|
+
if (fileDiffs.length > 0 || listDiffs.length > 0) {
|
|
110
|
+
collectors.push({
|
|
111
|
+
collectorId: id,
|
|
112
|
+
collectorLabel: newC.label,
|
|
113
|
+
files: fileDiffs,
|
|
114
|
+
lists: listDiffs,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
oldId: oldSnap.id.slice(0, 8),
|
|
120
|
+
newId: newSnap.id.slice(0, 8),
|
|
121
|
+
addedCollectors,
|
|
122
|
+
removedCollectors,
|
|
123
|
+
collectors,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function diffFiles(oldFiles, newFiles) {
|
|
127
|
+
const oldMap = new Map(oldFiles.map((f) => [f.path, f]));
|
|
128
|
+
const newMap = new Map(newFiles.map((f) => [f.path, f]));
|
|
129
|
+
const entries = [];
|
|
130
|
+
for (const [path, newFile] of newMap) {
|
|
131
|
+
const oldFile = oldMap.get(path);
|
|
132
|
+
if (!oldFile) {
|
|
133
|
+
entries.push({ type: "added", label: path });
|
|
134
|
+
}
|
|
135
|
+
else if (oldFile.sizeBytes !== newFile.sizeBytes) {
|
|
136
|
+
entries.push({ type: "changed", label: path });
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
for (const path of oldMap.keys()) {
|
|
140
|
+
if (!newMap.has(path)) {
|
|
141
|
+
entries.push({ type: "removed", label: path });
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return entries;
|
|
145
|
+
}
|
|
146
|
+
function diffLists(oldLists, newLists) {
|
|
147
|
+
const oldNames = new Set(oldLists.map((l) => l.name));
|
|
148
|
+
const newNames = new Set(newLists.map((l) => l.name));
|
|
149
|
+
const entries = [];
|
|
150
|
+
for (const name of newNames) {
|
|
151
|
+
if (!oldNames.has(name)) {
|
|
152
|
+
entries.push({ type: "added", label: name });
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
for (const name of oldNames) {
|
|
156
|
+
if (!newNames.has(name)) {
|
|
157
|
+
entries.push({ type: "removed", label: name });
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return entries;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Format a diff result for terminal output.
|
|
164
|
+
*/
|
|
165
|
+
export function formatSnapshotDiff(diff) {
|
|
166
|
+
const lines = [];
|
|
167
|
+
lines.push(`Diff: ${pc.bold(diff.oldId)} → ${pc.bold(diff.newId)}`);
|
|
168
|
+
lines.push("");
|
|
169
|
+
const hasChanges = diff.addedCollectors.length > 0 ||
|
|
170
|
+
diff.removedCollectors.length > 0 ||
|
|
171
|
+
diff.collectors.length > 0;
|
|
172
|
+
if (!hasChanges) {
|
|
173
|
+
lines.push("No differences found.");
|
|
174
|
+
return lines.join("\n");
|
|
175
|
+
}
|
|
176
|
+
if (diff.addedCollectors.length > 0) {
|
|
177
|
+
lines.push(`${pc.green("+ Collectors added:")} ${diff.addedCollectors.join(", ")}`);
|
|
178
|
+
}
|
|
179
|
+
if (diff.removedCollectors.length > 0) {
|
|
180
|
+
lines.push(`${pc.red("- Collectors removed:")} ${diff.removedCollectors.join(", ")}`);
|
|
181
|
+
}
|
|
182
|
+
for (const c of diff.collectors) {
|
|
183
|
+
if (c.files.length === 0 && c.lists.length === 0)
|
|
184
|
+
continue;
|
|
185
|
+
lines.push("");
|
|
186
|
+
lines.push(`${pc.bold(c.collectorLabel)} [${c.collectorId}]`);
|
|
187
|
+
for (const f of c.files) {
|
|
188
|
+
const prefix = f.type === "added"
|
|
189
|
+
? pc.green("+")
|
|
190
|
+
: f.type === "removed"
|
|
191
|
+
? pc.red("-")
|
|
192
|
+
: pc.yellow("~");
|
|
193
|
+
lines.push(` ${prefix} ${f.label}`);
|
|
194
|
+
}
|
|
195
|
+
for (const l of c.lists) {
|
|
196
|
+
const prefix = l.type === "added" ? pc.green("+") : pc.red("-");
|
|
197
|
+
lines.push(` ${prefix} ${l.label}`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return lines.join("\n");
|
|
201
|
+
}
|
|
202
|
+
export { formatSize, formatDate };
|
|
203
|
+
//# sourceMappingURL=snapshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/commands/snapshot.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { OtterConfig } from "@otter/core";
|
|
2
|
+
/**
|
|
3
|
+
* Manages the CLI configuration file at ~/.config/otter/config.json
|
|
4
|
+
*/
|
|
5
|
+
export declare class ConfigManager {
|
|
6
|
+
readonly configPath: string;
|
|
7
|
+
constructor(configDir: string);
|
|
8
|
+
/** Load config from disk. Returns empty config if file doesn't exist or is corrupted. */
|
|
9
|
+
load(): Promise<OtterConfig>;
|
|
10
|
+
/** Save config to disk, creating the directory if needed. */
|
|
11
|
+
save(config: OtterConfig): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/config/manager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;GAEG;AACH,qBAAa,aAAa;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;gBAEhB,SAAS,EAAE,MAAM;IAI7B,yFAAyF;IACnF,IAAI,IAAI,OAAO,CAAC,WAAW,CAAC;IASlC,6DAA6D;IACvD,IAAI,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAK/C"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { readFile, writeFile, mkdir } from "node:fs/promises";
|
|
2
|
+
import { join, dirname } from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Manages the CLI configuration file at ~/.config/otter/config.json
|
|
5
|
+
*/
|
|
6
|
+
export class ConfigManager {
|
|
7
|
+
configPath;
|
|
8
|
+
constructor(configDir) {
|
|
9
|
+
this.configPath = join(configDir, "config.json");
|
|
10
|
+
}
|
|
11
|
+
/** Load config from disk. Returns empty config if file doesn't exist or is corrupted. */
|
|
12
|
+
async load() {
|
|
13
|
+
try {
|
|
14
|
+
const raw = await readFile(this.configPath, "utf-8");
|
|
15
|
+
return JSON.parse(raw);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return {};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/** Save config to disk, creating the directory if needed. */
|
|
22
|
+
async save(config) {
|
|
23
|
+
const dir = dirname(this.configPath);
|
|
24
|
+
await mkdir(dir, { recursive: true });
|
|
25
|
+
await writeFile(this.configPath, JSON.stringify(config, null, 2) + "\n");
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/config/manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAG1C;;GAEG;AACH,MAAM,OAAO,aAAa;IACf,UAAU,CAAS;IAE5B,YAAY,SAAiB;QAC3B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IACnD,CAAC;IAED,yFAAyF;IACzF,KAAK,CAAC,IAAI;QACR,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YACrD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAgB,CAAC;QACxC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED,6DAA6D;IAC7D,KAAK,CAAC,IAAI,CAAC,MAAmB;QAC5B,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACrC,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtC,MAAM,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC3E,CAAC;CACF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { main } from "./cli.js";
|
|
2
|
+
export { executeScan } from "./commands/scan.js";
|
|
3
|
+
export { executeConfig } from "./commands/config.js";
|
|
4
|
+
export { buildSnapshot } from "./snapshot/builder.js";
|
|
5
|
+
export { uploadSnapshot } from "./uploader/webhook.js";
|
|
6
|
+
export { ConfigManager } from "./config/manager.js";
|
|
7
|
+
export { createDefaultCollectors } from "./collectors/index.js";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { main } from "./cli.js";
|
|
2
|
+
export { executeScan } from "./commands/scan.js";
|
|
3
|
+
export { executeConfig } from "./commands/config.js";
|
|
4
|
+
export { buildSnapshot } from "./snapshot/builder.js";
|
|
5
|
+
export { uploadSnapshot } from "./uploader/webhook.js";
|
|
6
|
+
export { ConfigManager } from "./config/manager.js";
|
|
7
|
+
export { createDefaultCollectors } from "./collectors/index.js";
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Collector, Snapshot } from "@otter/core";
|
|
2
|
+
/**
|
|
3
|
+
* Build a complete snapshot by running all provided collectors
|
|
4
|
+
* and assembling results into the unified Snapshot format.
|
|
5
|
+
*/
|
|
6
|
+
export declare function buildSnapshot(collectors: Collector[]): Promise<Snapshot>;
|
|
7
|
+
//# sourceMappingURL=builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/snapshot/builder.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAgC,QAAQ,EAAE,MAAM,aAAa,CAAC;AAoDrF;;;GAGG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,SAAS,EAAE,GACtB,OAAO,CAAC,QAAQ,CAAC,CAUnB"}
|