@nocoo/otter 1.0.3 → 1.2.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/cli.d.ts.map +1 -1
- package/dist/cli.js +162 -85
- package/dist/cli.js.map +1 -1
- package/dist/collectors/applications.d.ts +7 -2
- package/dist/collectors/applications.d.ts.map +1 -1
- package/dist/collectors/applications.js +55 -21
- package/dist/collectors/applications.js.map +1 -1
- package/dist/collectors/base.d.ts.map +1 -1
- package/dist/collectors/base.js +1 -0
- package/dist/collectors/base.js.map +1 -1
- package/dist/collectors/cloud-cli.d.ts +9 -0
- package/dist/collectors/cloud-cli.d.ts.map +1 -0
- package/dist/collectors/cloud-cli.js +61 -0
- package/dist/collectors/cloud-cli.js.map +1 -0
- package/dist/collectors/dev-toolchain.d.ts +21 -0
- package/dist/collectors/dev-toolchain.d.ts.map +1 -0
- package/dist/collectors/dev-toolchain.js +252 -0
- package/dist/collectors/dev-toolchain.js.map +1 -0
- package/dist/collectors/docker.d.ts +10 -0
- package/dist/collectors/docker.d.ts.map +1 -0
- package/dist/collectors/docker.js +57 -0
- package/dist/collectors/docker.js.map +1 -0
- package/dist/collectors/fonts.d.ts +9 -0
- package/dist/collectors/fonts.d.ts.map +1 -0
- package/dist/collectors/fonts.js +36 -0
- package/dist/collectors/fonts.js.map +1 -0
- package/dist/collectors/homebrew.d.ts +2 -1
- package/dist/collectors/homebrew.d.ts.map +1 -1
- package/dist/collectors/homebrew.js +56 -12
- package/dist/collectors/homebrew.js.map +1 -1
- package/dist/collectors/index.d.ts +7 -0
- package/dist/collectors/index.d.ts.map +1 -1
- package/dist/collectors/index.js +21 -0
- package/dist/collectors/index.js.map +1 -1
- package/dist/collectors/launch-agents.d.ts +10 -0
- package/dist/collectors/launch-agents.d.ts.map +1 -0
- package/dist/collectors/launch-agents.js +53 -0
- package/dist/collectors/launch-agents.js.map +1 -0
- package/dist/collectors/macos-defaults.d.ts +10 -0
- package/dist/collectors/macos-defaults.d.ts.map +1 -0
- package/dist/collectors/macos-defaults.js +53 -0
- package/dist/collectors/macos-defaults.js.map +1 -0
- package/dist/collectors/vscode.d.ts +15 -0
- package/dist/collectors/vscode.d.ts.map +1 -0
- package/dist/collectors/vscode.js +118 -0
- package/dist/collectors/vscode.js.map +1 -0
- package/dist/commands/scan.d.ts +2 -0
- package/dist/commands/scan.d.ts.map +1 -1
- package/dist/commands/scan.js +2 -0
- package/dist/commands/scan.js.map +1 -1
- package/dist/commands/snapshot.d.ts +2 -9
- package/dist/commands/snapshot.d.ts.map +1 -1
- package/dist/commands/snapshot.js +74 -64
- package/dist/commands/snapshot.js.map +1 -1
- package/dist/snapshot/builder.d.ts.map +1 -1
- package/dist/snapshot/builder.js +1 -0
- package/dist/snapshot/builder.js.map +1 -1
- package/dist/ui.d.ts +63 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +167 -0
- package/dist/ui.js.map +1 -0
- package/dist/utils/icons.d.ts.map +1 -1
- package/dist/utils/icons.js +59 -7
- package/dist/utils/icons.js.map +1 -1
- package/package.json +3 -2
|
@@ -1,50 +1,33 @@
|
|
|
1
1
|
import pc from "picocolors";
|
|
2
|
-
|
|
3
|
-
|
|
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
|
-
}
|
|
2
|
+
import { formatSize, formatDate, table, tree, S, } from "../ui.js";
|
|
3
|
+
// ── snapshot list ───────────────────────────────────────────────────
|
|
25
4
|
/**
|
|
26
5
|
* Format the snapshot list output for the terminal.
|
|
27
6
|
* Pure logic function, returns lines to print.
|
|
28
7
|
*/
|
|
29
8
|
export function formatSnapshotList(metas) {
|
|
30
9
|
if (metas.length === 0) {
|
|
31
|
-
return "No local snapshots found
|
|
10
|
+
return "\n No local snapshots found.\n";
|
|
32
11
|
}
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
12
|
+
const columns = [
|
|
13
|
+
{ label: "ID" },
|
|
14
|
+
{ label: "Date" },
|
|
15
|
+
{ label: "Collectors", align: "right" },
|
|
16
|
+
{ label: "Files", align: "right" },
|
|
17
|
+
{ label: "Items", align: "right" },
|
|
18
|
+
{ label: "Size", align: "right" },
|
|
19
|
+
];
|
|
20
|
+
const rows = metas.map((m) => [
|
|
21
|
+
pc.bold(m.shortId),
|
|
22
|
+
pc.dim(formatDate(m.createdAt)),
|
|
23
|
+
String(m.collectorCount),
|
|
24
|
+
String(m.fileCount),
|
|
25
|
+
String(m.listCount),
|
|
26
|
+
formatSize(m.sizeBytes),
|
|
27
|
+
]);
|
|
28
|
+
return `\n Local snapshots (${metas.length}):\n\n${table(columns, rows)}\n`;
|
|
44
29
|
}
|
|
45
|
-
//
|
|
46
|
-
// snapshot show
|
|
47
|
-
// ---------------------------------------------------------------------------
|
|
30
|
+
// ── snapshot show ───────────────────────────────────────────────────
|
|
48
31
|
/**
|
|
49
32
|
* Format a detailed view of a single snapshot.
|
|
50
33
|
*/
|
|
@@ -52,30 +35,45 @@ export function formatSnapshotDetail(snapshot) {
|
|
|
52
35
|
const lines = [];
|
|
53
36
|
const m = snapshot.machine;
|
|
54
37
|
const machineName = m.computerName || m.hostname;
|
|
55
|
-
lines.push(
|
|
56
|
-
lines.push(`
|
|
57
|
-
lines.push(`
|
|
58
|
-
lines.push(`
|
|
38
|
+
lines.push("");
|
|
39
|
+
lines.push(` Snapshot ${pc.bold(snapshot.id.slice(0, 8))}`);
|
|
40
|
+
lines.push(` Created: ${pc.dim(formatDate(snapshot.createdAt))}`);
|
|
41
|
+
lines.push(` Machine: ${pc.dim(`${machineName} (${m.platform}/${m.arch}, ${m.osVersion})`)}`);
|
|
42
|
+
lines.push(` User: ${pc.dim(m.username)}`);
|
|
59
43
|
lines.push("");
|
|
60
44
|
for (const c of snapshot.collectors) {
|
|
61
|
-
const status = c.errors.length > 0 ?
|
|
62
|
-
|
|
45
|
+
const status = c.errors.length > 0 ? S.warning : S.success;
|
|
46
|
+
const meta = pc.dim(`${c.files.length} files, ${c.lists.length} items`);
|
|
47
|
+
lines.push(` ${status} ${pc.bold(c.label)} ${meta}`);
|
|
48
|
+
// Build tree children
|
|
49
|
+
const children = [];
|
|
50
|
+
// Files
|
|
63
51
|
for (const f of c.files) {
|
|
64
|
-
|
|
52
|
+
// Shorten home dir paths for readability
|
|
53
|
+
const shortPath = f.path.replace(/^\/Users\/[^/]+/, "~");
|
|
54
|
+
children.push({ text: shortPath, detail: formatSize(f.sizeBytes) });
|
|
65
55
|
}
|
|
56
|
+
// List items preview
|
|
66
57
|
if (c.lists.length > 0) {
|
|
67
58
|
const preview = c.lists
|
|
68
59
|
.slice(0, 10)
|
|
69
60
|
.map((l) => l.name)
|
|
70
61
|
.join(", ");
|
|
71
62
|
const suffix = c.lists.length > 10 ? `, ... +${c.lists.length - 10} more` : "";
|
|
72
|
-
|
|
63
|
+
children.push({ text: `items: ${preview}${suffix}`, dim: true });
|
|
73
64
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
65
|
+
// Errors (real failures)
|
|
66
|
+
for (const e of c.errors) {
|
|
67
|
+
children.push({ text: e, color: "yellow" });
|
|
78
68
|
}
|
|
69
|
+
// Skipped (tools not installed — informational, not errors)
|
|
70
|
+
for (const s of c.skipped ?? []) {
|
|
71
|
+
children.push({ text: s, dim: true });
|
|
72
|
+
}
|
|
73
|
+
if (children.length > 0) {
|
|
74
|
+
lines.push(tree(children));
|
|
75
|
+
}
|
|
76
|
+
lines.push("");
|
|
79
77
|
}
|
|
80
78
|
return lines.join("\n");
|
|
81
79
|
}
|
|
@@ -88,7 +86,10 @@ export function formatSnapshotDetail(snapshot) {
|
|
|
88
86
|
export function diffSnapshots(oldSnap, newSnap) {
|
|
89
87
|
const oldCollectorMap = new Map(oldSnap.collectors.map((c) => [c.id, c]));
|
|
90
88
|
const newCollectorMap = new Map(newSnap.collectors.map((c) => [c.id, c]));
|
|
91
|
-
const allIds = new Set([
|
|
89
|
+
const allIds = new Set([
|
|
90
|
+
...oldCollectorMap.keys(),
|
|
91
|
+
...newCollectorMap.keys(),
|
|
92
|
+
]);
|
|
92
93
|
const addedCollectors = [];
|
|
93
94
|
const removedCollectors = [];
|
|
94
95
|
const collectors = [];
|
|
@@ -160,43 +161,52 @@ function diffLists(oldLists, newLists) {
|
|
|
160
161
|
return entries;
|
|
161
162
|
}
|
|
162
163
|
/**
|
|
163
|
-
* Format a diff result for terminal output.
|
|
164
|
+
* Format a diff result for terminal output using tree views.
|
|
164
165
|
*/
|
|
165
166
|
export function formatSnapshotDiff(diff) {
|
|
166
167
|
const lines = [];
|
|
167
|
-
lines.push(
|
|
168
|
+
lines.push("");
|
|
169
|
+
lines.push(` Diff: ${pc.bold(diff.oldId)} \u2192 ${pc.bold(diff.newId)}`);
|
|
168
170
|
lines.push("");
|
|
169
171
|
const hasChanges = diff.addedCollectors.length > 0 ||
|
|
170
172
|
diff.removedCollectors.length > 0 ||
|
|
171
173
|
diff.collectors.length > 0;
|
|
172
174
|
if (!hasChanges) {
|
|
173
|
-
lines.push("No differences found.");
|
|
175
|
+
lines.push(" No differences found.");
|
|
176
|
+
lines.push("");
|
|
174
177
|
return lines.join("\n");
|
|
175
178
|
}
|
|
176
179
|
if (diff.addedCollectors.length > 0) {
|
|
177
|
-
lines.push(
|
|
180
|
+
lines.push(` ${pc.green("+")} Collectors added: ${diff.addedCollectors.join(", ")}`);
|
|
178
181
|
}
|
|
179
182
|
if (diff.removedCollectors.length > 0) {
|
|
180
|
-
lines.push(
|
|
183
|
+
lines.push(` ${pc.red("-")} Collectors removed: ${diff.removedCollectors.join(", ")}`);
|
|
181
184
|
}
|
|
182
185
|
for (const c of diff.collectors) {
|
|
183
186
|
if (c.files.length === 0 && c.lists.length === 0)
|
|
184
187
|
continue;
|
|
185
188
|
lines.push("");
|
|
186
|
-
lines.push(
|
|
189
|
+
lines.push(` ${pc.bold(c.collectorLabel)}`);
|
|
190
|
+
const children = [];
|
|
187
191
|
for (const f of c.files) {
|
|
188
|
-
const prefix = f.type === "added"
|
|
189
|
-
|
|
192
|
+
const prefix = f.type === "added" ? "+" : f.type === "removed" ? "-" : "~";
|
|
193
|
+
const color = f.type === "added"
|
|
194
|
+
? "green"
|
|
190
195
|
: f.type === "removed"
|
|
191
|
-
?
|
|
192
|
-
:
|
|
193
|
-
|
|
196
|
+
? "red"
|
|
197
|
+
: "yellow";
|
|
198
|
+
children.push({ text: `${prefix} ${f.label}`, color });
|
|
194
199
|
}
|
|
195
200
|
for (const l of c.lists) {
|
|
196
|
-
const prefix = l.type === "added" ?
|
|
197
|
-
|
|
201
|
+
const prefix = l.type === "added" ? "+" : "-";
|
|
202
|
+
const color = l.type === "added" ? "green" : "red";
|
|
203
|
+
children.push({ text: `${prefix} ${l.label}`, color });
|
|
204
|
+
}
|
|
205
|
+
if (children.length > 0) {
|
|
206
|
+
lines.push(tree(children));
|
|
198
207
|
}
|
|
199
208
|
}
|
|
209
|
+
lines.push("");
|
|
200
210
|
return lines.join("\n");
|
|
201
211
|
}
|
|
202
212
|
export { formatSize, formatDate };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/commands/snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/commands/snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAG5B,OAAO,EACL,UAAU,EACV,UAAU,EACV,KAAK,EACL,IAAI,EACJ,CAAC,GAGF,MAAM,UAAU,CAAC;AAElB,uEAAuE;AAEvE;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAqB;IACtD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,iCAAiC,CAAC;IAC3C,CAAC;IAED,MAAM,OAAO,GAAa;QACxB,EAAE,KAAK,EAAE,IAAI,EAAE;QACf,EAAE,KAAK,EAAE,MAAM,EAAE;QACjB,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE;QACvC,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;QAClC,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;QAClC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE;KAClC,CAAC;IAEF,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAC5B,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;QAClB,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC/B,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC;QACxB,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;QACnB,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;QACnB,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;KACxB,CAAC,CAAC;IAEH,OAAO,wBAAwB,KAAK,CAAC,MAAM,SAAS,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC;AAC/E,CAAC;AAED,uEAAuE;AAEvE;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAAkB;IACrD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC;IAC3B,MAAM,WAAW,GAAG,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,QAAQ,CAAC;IAEjD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC7D,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC;IACnE,KAAK,CAAC,IAAI,CACR,cAAc,EAAE,CAAC,GAAG,CAAC,GAAG,WAAW,KAAK,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,SAAS,GAAG,CAAC,EAAE,CACnF,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC/C,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QAC3D,MAAM,IAAI,GAAG,EAAE,CAAC,GAAG,CACjB,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,WAAW,CAAC,CAAC,KAAK,CAAC,MAAM,QAAQ,CACnD,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,KAAK,MAAM,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QAExD,sBAAsB;QACtB,MAAM,QAAQ,GAAgB,EAAE,CAAC;QAEjC,QAAQ;QACR,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;YACxB,yCAAyC;YACzC,MAAM,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;YACzD,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QACtE,CAAC;QAED,qBAAqB;QACrB,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK;iBACpB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;iBACZ,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;iBAClB,IAAI,CAAC,IAAI,CAAC,CAAC;YACd,MAAM,MAAM,GACV,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;YAClE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,OAAO,GAAG,MAAM,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;QACnE,CAAC;QAED,yBAAyB;QACzB,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;YACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC9C,CAAC;QAED,4DAA4D;QAC5D,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;YAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;QACxC,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC7B,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AA2BD;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAC3B,OAAiB,EACjB,OAAiB;IAEjB,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1E,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAE1E,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC;QACrB,GAAG,eAAe,CAAC,IAAI,EAAE;QACzB,GAAG,eAAe,CAAC,IAAI,EAAE;KAC1B,CAAC,CAAC;IAEH,MAAM,eAAe,GAAa,EAAE,CAAC;IACrC,MAAM,iBAAiB,GAAa,EAAE,CAAC;IACvC,MAAM,UAAU,GAAoB,EAAE,CAAC;IAEvC,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACrC,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAErC,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC;YAClB,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACjC,SAAS;QACX,CAAC;QACD,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnC,SAAS;QACX,CAAC;QAED,oCAAoC;QACpC,MAAM,SAAS,GAAG,SAAS,CAAC,IAAK,CAAC,KAAK,EAAE,IAAK,CAAC,KAAK,CAAC,CAAC;QACtD,MAAM,SAAS,GAAG,SAAS,CAAC,IAAK,CAAC,KAAK,EAAE,IAAK,CAAC,KAAK,CAAC,CAAC;QAEtD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjD,UAAU,CAAC,IAAI,CAAC;gBACd,WAAW,EAAE,EAAE;gBACf,cAAc,EAAE,IAAK,CAAC,KAAK;gBAC3B,KAAK,EAAE,SAAS;gBAChB,KAAK,EAAE,SAAS;aACjB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QAC7B,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QAC7B,eAAe;QACf,iBAAiB;QACjB,UAAU;KACX,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAChB,QAA4C,EAC5C,QAA4C;IAE5C,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACzD,MAAM,OAAO,GAAgB,EAAE,CAAC;IAEhC,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/C,CAAC;aAAM,IAAI,OAAO,CAAC,SAAS,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC;YACnD,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,SAAS,CAChB,QAA4C,EAC5C,QAA4C;IAE5C,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACtD,MAAM,OAAO,GAAgB,EAAE,CAAC;IAEhC,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAwB;IACzD,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CACR,WAAW,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAC/D,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,MAAM,UAAU,GACd,IAAI,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC;QAC/B,IAAI,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC;QACjC,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;IAE7B,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QACtC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,IAAI,IAAI,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpC,KAAK,CAAC,IAAI,CACR,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,sBAAsB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC1E,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtC,KAAK,CAAC,IAAI,CACR,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,wBAAwB,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC5E,CAAC;IACJ,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QAChC,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAE3D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;QAE7C,MAAM,QAAQ,GAAgB,EAAE,CAAC;QAEjC,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;YACxB,MAAM,MAAM,GACV,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YAC9D,MAAM,KAAK,GACT,CAAC,CAAC,IAAI,KAAK,OAAO;gBAChB,CAAC,CAAC,OAAO;gBACT,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS;oBACpB,CAAC,CAAC,KAAK;oBACP,CAAC,CAAC,QAAQ,CAAC;YACjB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACzD,CAAC;QAED,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YAC9C,MAAM,KAAK,GACT,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;YACvC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACzD,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC"}
|
|
@@ -1 +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;
|
|
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;AAqDrF;;;GAGG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,SAAS,EAAE,GACtB,OAAO,CAAC,QAAQ,CAAC,CAUnB"}
|
package/dist/snapshot/builder.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/snapshot/builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAG/E;;;GAGG;AACH,SAAS,eAAe;IACtB,IAAI,QAAQ,EAAE,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC9C,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,2BAA2B,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,cAAc;IACrB,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;IACxB,OAAO;QACL,QAAQ,EAAE,QAAQ,EAAE;QACpB,YAAY,EAAE,eAAe,EAAE;QAC/B,QAAQ,EAAE,QAAQ,EAAE;QACpB,SAAS,EAAE,OAAO,EAAE;QACpB,IAAI,EAAE,IAAI,EAAE;QACZ,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,OAAO,EAAE,OAAO,EAAE;QAClB,WAAW,EAAE,OAAO,CAAC,OAAO;KAC7B,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,YAAY,CAAC,SAAoB;IAC9C,IAAI,CAAC;QACH,OAAO,MAAM,SAAS,CAAC,OAAO,EAAE,CAAC;IACnC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,EAAE,EAAE,SAAS,CAAC,EAAE;YAChB,KAAK,EAAE,SAAS,CAAC,KAAK;YACtB,QAAQ,EAAE,SAAS,CAAC,QAAQ;YAC5B,KAAK,EAAE,EAAE;YACT,KAAK,EAAE,EAAE;YACT,MAAM,EAAE,CAAC,cAAc,SAAS,CAAC,EAAE,cAAe,GAAa,CAAC,OAAO,EAAE,CAAC;YAC1E,UAAU,EAAE,CAAC;SACd,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,UAAuB;IAEvB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;IAEhE,OAAO;QACL,OAAO,EAAE,CAAC;QACV,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,EAAE,EAAE,UAAU,EAAE;QAChB,OAAO,EAAE,cAAc,EAAE;QACzB,UAAU,EAAE,OAAO;KACpB,CAAC;AACJ,CAAC"}
|
|
1
|
+
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/snapshot/builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAG/E;;;GAGG;AACH,SAAS,eAAe;IACtB,IAAI,QAAQ,EAAE,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC9C,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,2BAA2B,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,cAAc;IACrB,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;IACxB,OAAO;QACL,QAAQ,EAAE,QAAQ,EAAE;QACpB,YAAY,EAAE,eAAe,EAAE;QAC/B,QAAQ,EAAE,QAAQ,EAAE;QACpB,SAAS,EAAE,OAAO,EAAE;QACpB,IAAI,EAAE,IAAI,EAAE;QACZ,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,OAAO,EAAE,OAAO,EAAE;QAClB,WAAW,EAAE,OAAO,CAAC,OAAO;KAC7B,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,YAAY,CAAC,SAAoB;IAC9C,IAAI,CAAC;QACH,OAAO,MAAM,SAAS,CAAC,OAAO,EAAE,CAAC;IACnC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,EAAE,EAAE,SAAS,CAAC,EAAE;YAChB,KAAK,EAAE,SAAS,CAAC,KAAK;YACtB,QAAQ,EAAE,SAAS,CAAC,QAAQ;YAC5B,KAAK,EAAE,EAAE;YACT,KAAK,EAAE,EAAE;YACT,MAAM,EAAE,CAAC,cAAc,SAAS,CAAC,EAAE,cAAe,GAAa,CAAC,OAAO,EAAE,CAAC;YAC1E,OAAO,EAAE,EAAE;YACX,UAAU,EAAE,CAAC;SACd,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,UAAuB;IAEvB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;IAEhE,OAAO;QACL,OAAO,EAAE,CAAC;QACV,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,EAAE,EAAE,UAAU,EAAE;QAChB,OAAO,EAAE,cAAc,EAAE;QACzB,UAAU,EAAE,OAAO;KACpB,CAAC;AACJ,CAAC"}
|
package/dist/ui.d.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ui.ts — Otter CLI output primitives
|
|
3
|
+
*
|
|
4
|
+
* Centralizes all terminal output formatting. Every visual element
|
|
5
|
+
* (banner, progress items, tables, trees, boxes) is defined here
|
|
6
|
+
* so cli.ts and snapshot.ts stay focused on logic.
|
|
7
|
+
*/
|
|
8
|
+
import pc from "picocolors";
|
|
9
|
+
import { consola } from "consola";
|
|
10
|
+
export declare const S: {
|
|
11
|
+
readonly success: string;
|
|
12
|
+
readonly warning: string;
|
|
13
|
+
readonly error: string;
|
|
14
|
+
readonly step: string;
|
|
15
|
+
readonly info: string;
|
|
16
|
+
readonly bar: string;
|
|
17
|
+
readonly treeItem: string;
|
|
18
|
+
readonly treeLast: string;
|
|
19
|
+
};
|
|
20
|
+
export declare function formatDuration(ms: number): string;
|
|
21
|
+
export declare function formatSize(bytes: number): string;
|
|
22
|
+
export declare function formatDate(iso: string): string;
|
|
23
|
+
export declare function banner(version: string): void;
|
|
24
|
+
export declare function step(message: string, current?: number, total?: number): void;
|
|
25
|
+
export interface ItemOptions {
|
|
26
|
+
label: string;
|
|
27
|
+
fileCount: number;
|
|
28
|
+
listCount: number;
|
|
29
|
+
errorCount: number;
|
|
30
|
+
skippedCount: number;
|
|
31
|
+
durationMs: number;
|
|
32
|
+
/** Max label width for alignment. Defaults to 30. */
|
|
33
|
+
labelWidth?: number;
|
|
34
|
+
}
|
|
35
|
+
export declare function item(opts: ItemOptions): void;
|
|
36
|
+
export declare function statusLine(icon: string, message: string, timing?: number): void;
|
|
37
|
+
export interface BoxOptions {
|
|
38
|
+
title: string;
|
|
39
|
+
lines: string[];
|
|
40
|
+
borderColor?: string;
|
|
41
|
+
}
|
|
42
|
+
export declare function box(opts: BoxOptions): void;
|
|
43
|
+
export declare function errorBox(title: string, lines: string[]): void;
|
|
44
|
+
export interface Column {
|
|
45
|
+
label: string;
|
|
46
|
+
align?: "left" | "right";
|
|
47
|
+
}
|
|
48
|
+
export declare function table(columns: Column[], rows: string[][]): string;
|
|
49
|
+
export interface TreeChild {
|
|
50
|
+
text: string;
|
|
51
|
+
/** Right-aligned detail (e.g., file size) */
|
|
52
|
+
detail?: string;
|
|
53
|
+
dim?: boolean;
|
|
54
|
+
color?: "yellow" | "green" | "red";
|
|
55
|
+
}
|
|
56
|
+
export declare function tree(children: TreeChild[]): string;
|
|
57
|
+
export declare function blank(): void;
|
|
58
|
+
export declare function info(message: string): void;
|
|
59
|
+
export declare function warn(message: string): void;
|
|
60
|
+
export declare function error(message: string): void;
|
|
61
|
+
export declare function success(message: string): void;
|
|
62
|
+
export { pc, consola };
|
|
63
|
+
//# sourceMappingURL=ui.d.ts.map
|
package/dist/ui.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAIlC,eAAO,MAAM,CAAC;;;;;;;;;CASJ,CAAC;AAIX,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAMjD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQhD;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI9C;AAID,wBAAgB,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAG5C;AAID,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAI5E;AAID,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAgB5C;AAID,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,GACd,IAAI,CAGN;AAID,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,GAAG,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAS1C;AAID,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAS7D;AAID,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,MAAM,CA2BjE;AAID,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,KAAK,CAAC;CACpC;AAED,wBAAgB,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,CAgClD;AAID,wBAAgB,KAAK,IAAI,IAAI,CAE5B;AAID,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE1C;AAED,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE1C;AAED,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE3C;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE7C;AAID,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC"}
|
package/dist/ui.js
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ui.ts — Otter CLI output primitives
|
|
3
|
+
*
|
|
4
|
+
* Centralizes all terminal output formatting. Every visual element
|
|
5
|
+
* (banner, progress items, tables, trees, boxes) is defined here
|
|
6
|
+
* so cli.ts and snapshot.ts stay focused on logic.
|
|
7
|
+
*/
|
|
8
|
+
import pc from "picocolors";
|
|
9
|
+
import { consola } from "consola";
|
|
10
|
+
// ── Symbols ─────────────────────────────────────────────────────────
|
|
11
|
+
export const S = {
|
|
12
|
+
success: pc.green("✓"),
|
|
13
|
+
warning: pc.yellow("▲"),
|
|
14
|
+
error: pc.red("✗"),
|
|
15
|
+
step: pc.cyan("◆"),
|
|
16
|
+
info: pc.cyan("●"),
|
|
17
|
+
bar: pc.dim("│"),
|
|
18
|
+
treeItem: pc.dim("├──"),
|
|
19
|
+
treeLast: pc.dim("└──"),
|
|
20
|
+
};
|
|
21
|
+
// ── Duration / Size formatting ──────────────────────────────────────
|
|
22
|
+
export function formatDuration(ms) {
|
|
23
|
+
if (ms < 1000)
|
|
24
|
+
return `${ms}ms`;
|
|
25
|
+
if (ms < 60_000)
|
|
26
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
27
|
+
const min = Math.floor(ms / 60_000);
|
|
28
|
+
const sec = Math.floor((ms % 60_000) / 1000);
|
|
29
|
+
return `${min}m ${sec}s`;
|
|
30
|
+
}
|
|
31
|
+
export function formatSize(bytes) {
|
|
32
|
+
if (bytes < 1024)
|
|
33
|
+
return `${bytes} B`;
|
|
34
|
+
const kb = bytes / 1024;
|
|
35
|
+
if (kb < 1024)
|
|
36
|
+
return `${kb.toFixed(1)} KB`;
|
|
37
|
+
const mb = kb / 1024;
|
|
38
|
+
if (mb < 1024)
|
|
39
|
+
return `${mb.toFixed(2)} MB`;
|
|
40
|
+
const gb = mb / 1024;
|
|
41
|
+
return `${gb.toFixed(2)} GB`;
|
|
42
|
+
}
|
|
43
|
+
export function formatDate(iso) {
|
|
44
|
+
const d = new Date(iso);
|
|
45
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
46
|
+
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`;
|
|
47
|
+
}
|
|
48
|
+
// ── Banner ──────────────────────────────────────────────────────────
|
|
49
|
+
export function banner(version) {
|
|
50
|
+
const label = `${pc.bgCyan(pc.black(` otter `))} ${pc.dim(`v${version}`)}`;
|
|
51
|
+
console.log(`\n${label}\n`);
|
|
52
|
+
}
|
|
53
|
+
// ── Step header (for multi-phase commands like backup) ──────────────
|
|
54
|
+
export function step(message, current, total) {
|
|
55
|
+
const counter = current != null && total != null ? ` ${pc.dim(`(${current}/${total})`)}` : "";
|
|
56
|
+
console.log(`${S.step} ${message}${counter}`);
|
|
57
|
+
}
|
|
58
|
+
export function item(opts) {
|
|
59
|
+
const { label, fileCount, listCount, errorCount, skippedCount, durationMs } = opts;
|
|
60
|
+
const w = opts.labelWidth ?? 30;
|
|
61
|
+
const status = errorCount > 0 ? S.warning : S.success;
|
|
62
|
+
const files = `${fileCount} files`.padStart(8);
|
|
63
|
+
const items = `${listCount} items`.padStart(9);
|
|
64
|
+
const errors = errorCount > 0 ? ` ${pc.yellow(`${errorCount} err`)}` : "";
|
|
65
|
+
const skipped = skippedCount > 0 && errorCount === 0
|
|
66
|
+
? ` ${pc.dim(`${skippedCount} skip`)}`
|
|
67
|
+
: "";
|
|
68
|
+
const timing = formatDuration(durationMs).padStart(8);
|
|
69
|
+
console.log(`${status} ${label.padEnd(w)}${pc.dim(files)} ${pc.dim(items)}${errors}${skipped} ${pc.dim(timing)}`);
|
|
70
|
+
}
|
|
71
|
+
// ── Simple status line (for backup sub-steps) ───────────────────────
|
|
72
|
+
export function statusLine(icon, message, timing) {
|
|
73
|
+
const t = timing != null ? ` ${pc.dim(formatDuration(timing).padStart(8))}` : "";
|
|
74
|
+
console.log(`${icon} ${message}${t}`);
|
|
75
|
+
}
|
|
76
|
+
export function box(opts) {
|
|
77
|
+
consola.box({
|
|
78
|
+
title: pc.green(opts.title),
|
|
79
|
+
message: opts.lines.join("\n"),
|
|
80
|
+
style: {
|
|
81
|
+
borderColor: (opts.borderColor ?? "green"),
|
|
82
|
+
marginLeft: 0,
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
// ── Error box ───────────────────────────────────────────────────────
|
|
87
|
+
export function errorBox(title, lines) {
|
|
88
|
+
consola.box({
|
|
89
|
+
title: pc.red(title),
|
|
90
|
+
message: lines.join("\n"),
|
|
91
|
+
style: {
|
|
92
|
+
borderColor: "red",
|
|
93
|
+
marginLeft: 0,
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
export function table(columns, rows) {
|
|
98
|
+
if (rows.length === 0)
|
|
99
|
+
return "";
|
|
100
|
+
// Compute column widths from header + all rows
|
|
101
|
+
const widths = columns.map((col, i) => Math.max(col.label.length, ...rows.map((r) => (r[i] ?? "").length)));
|
|
102
|
+
const pad = (val, width, align) => align === "right" ? val.padStart(width) : val.padEnd(width);
|
|
103
|
+
const gap = " ";
|
|
104
|
+
const headerLine = columns
|
|
105
|
+
.map((col, i) => pc.dim(pad(col.label, widths[i], col.align ?? "left")))
|
|
106
|
+
.join(gap);
|
|
107
|
+
const separator = widths.map((w) => pc.dim("\u2500".repeat(w))).join(gap);
|
|
108
|
+
const dataLines = rows.map((row) => row
|
|
109
|
+
.map((cell, i) => pad(cell, widths[i], columns[i].align ?? "left"))
|
|
110
|
+
.join(gap));
|
|
111
|
+
return [
|
|
112
|
+
headerLine,
|
|
113
|
+
separator,
|
|
114
|
+
...dataLines,
|
|
115
|
+
].join("\n");
|
|
116
|
+
}
|
|
117
|
+
export function tree(children) {
|
|
118
|
+
if (children.length === 0)
|
|
119
|
+
return "";
|
|
120
|
+
const lines = [];
|
|
121
|
+
// Compute padding for right-aligned details
|
|
122
|
+
const maxTextLen = Math.max(...children.map((c) => c.text.length), 1);
|
|
123
|
+
const detailPad = Math.min(maxTextLen + 4, 50);
|
|
124
|
+
for (let i = 0; i < children.length; i++) {
|
|
125
|
+
const child = children[i];
|
|
126
|
+
const isLast = i === children.length - 1;
|
|
127
|
+
const branch = isLast ? S.treeLast : S.treeItem;
|
|
128
|
+
let text = child.text;
|
|
129
|
+
if (child.dim)
|
|
130
|
+
text = pc.dim(text);
|
|
131
|
+
if (child.color === "yellow")
|
|
132
|
+
text = pc.yellow(text);
|
|
133
|
+
if (child.color === "red")
|
|
134
|
+
text = pc.red(text);
|
|
135
|
+
if (child.color === "green")
|
|
136
|
+
text = pc.green(text);
|
|
137
|
+
if (child.detail) {
|
|
138
|
+
const plainTextLen = child.text.length;
|
|
139
|
+
const padding = Math.max(1, detailPad - plainTextLen);
|
|
140
|
+
lines.push(`${S.bar} ${branch} ${text}${" ".repeat(padding)}${pc.dim(child.detail)}`);
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
lines.push(`${S.bar} ${branch} ${text}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return lines.join("\n");
|
|
147
|
+
}
|
|
148
|
+
// ── Blank line ──────────────────────────────────────────────────────
|
|
149
|
+
export function blank() {
|
|
150
|
+
console.log();
|
|
151
|
+
}
|
|
152
|
+
// ── Info / warning / error one-liners ───────────────────────────────
|
|
153
|
+
export function info(message) {
|
|
154
|
+
console.log(`${S.info} ${message}`);
|
|
155
|
+
}
|
|
156
|
+
export function warn(message) {
|
|
157
|
+
console.log(`${S.warning} ${pc.yellow(message)}`);
|
|
158
|
+
}
|
|
159
|
+
export function error(message) {
|
|
160
|
+
console.log(`${S.error} ${pc.red(message)}`);
|
|
161
|
+
}
|
|
162
|
+
export function success(message) {
|
|
163
|
+
console.log(`${S.success} ${message}`);
|
|
164
|
+
}
|
|
165
|
+
// ── Re-export for convenience ───────────────────────────────────────
|
|
166
|
+
export { pc, consola };
|
|
167
|
+
//# sourceMappingURL=ui.js.map
|
package/dist/ui.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../src/utils/icons.ts"],"names":[],"mappings":"AAQA,6CAA6C;AAC7C,MAAM,WAAW,gBAAgB;IAC/B,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,OAAO,EAAE,OAAO,CAAC;IACjB,wCAAwC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,6CAA6C;AAC7C,MAAM,WAAW,kBAAkB;IACjC,sDAAsD;IACtD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;CACjD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAavE;
|
|
1
|
+
{"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../src/utils/icons.ts"],"names":[],"mappings":"AAQA,6CAA6C;AAC7C,MAAM,WAAW,gBAAgB;IAC/B,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,OAAO,EAAE,OAAO,CAAC;IACjB,wCAAwC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,6CAA6C;AAC7C,MAAM,WAAW,kBAAkB;IACjC,sDAAsD;IACtD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;CACjD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAavE;AAsGD;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,gBAAgB,EAAE,CAAC,CA8D7B"}
|
package/dist/utils/icons.js
CHANGED
|
@@ -10,7 +10,7 @@ const execFileAsync = promisify(execFile);
|
|
|
10
10
|
*/
|
|
11
11
|
export function extractIconFileName(plistContent) {
|
|
12
12
|
// Match <key>CFBundleIconFile</key> followed by <string>value</string>
|
|
13
|
-
const pattern = /<key>CFBundleIconFile<\/key>\s*<string>([^<]+)<\/string
|
|
13
|
+
const pattern = /<key>CFBundleIconFile<\/key>\s*<string>([^<]+)<\/string>/i;
|
|
14
14
|
const match = plistContent.match(pattern);
|
|
15
15
|
if (!match)
|
|
16
16
|
return null;
|
|
@@ -21,6 +21,45 @@ export function extractIconFileName(plistContent) {
|
|
|
21
21
|
}
|
|
22
22
|
return iconFile;
|
|
23
23
|
}
|
|
24
|
+
function extractIconCandidates(plistContent) {
|
|
25
|
+
const keys = ["CFBundleIconFile", "CFBundleIconName"];
|
|
26
|
+
const candidates = [];
|
|
27
|
+
for (const key of keys) {
|
|
28
|
+
const pattern = new RegExp(`<key>${key}<\\/key>\\s*<string>([^<]+)<\\/string>`, "i");
|
|
29
|
+
const match = plistContent.match(pattern);
|
|
30
|
+
if (!match)
|
|
31
|
+
continue;
|
|
32
|
+
let iconFile = match[1].trim();
|
|
33
|
+
if (!iconFile.endsWith(".icns")) {
|
|
34
|
+
iconFile += ".icns";
|
|
35
|
+
}
|
|
36
|
+
candidates.push(iconFile);
|
|
37
|
+
}
|
|
38
|
+
return [...new Set(candidates)];
|
|
39
|
+
}
|
|
40
|
+
async function readPlistAsXml(plistPath) {
|
|
41
|
+
try {
|
|
42
|
+
const { stdout } = await execFileAsync("/usr/bin/plutil", [
|
|
43
|
+
"-convert",
|
|
44
|
+
"xml1",
|
|
45
|
+
"-o",
|
|
46
|
+
"-",
|
|
47
|
+
plistPath,
|
|
48
|
+
]);
|
|
49
|
+
if (stdout) {
|
|
50
|
+
return stdout;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// Fall back to direct read below.
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
return await readFile(plistPath, "utf-8");
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
24
63
|
/**
|
|
25
64
|
* Resolve the .icns file path for a given .app bundle.
|
|
26
65
|
* Returns null if the icon cannot be found.
|
|
@@ -28,13 +67,26 @@ export function extractIconFileName(plistContent) {
|
|
|
28
67
|
async function resolveIconPath(appPath) {
|
|
29
68
|
const plistPath = join(appPath, "Contents", "Info.plist");
|
|
30
69
|
try {
|
|
31
|
-
const plistContent = await
|
|
32
|
-
|
|
33
|
-
if (!iconFile)
|
|
70
|
+
const plistContent = await readPlistAsXml(plistPath);
|
|
71
|
+
if (!plistContent)
|
|
34
72
|
return null;
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
73
|
+
for (const iconFile of extractIconCandidates(plistContent)) {
|
|
74
|
+
const iconPath = join(appPath, "Contents", "Resources", iconFile);
|
|
75
|
+
try {
|
|
76
|
+
await access(iconPath);
|
|
77
|
+
return iconPath;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const fallback = extractIconFileName(plistContent);
|
|
84
|
+
if (fallback) {
|
|
85
|
+
const iconPath = join(appPath, "Contents", "Resources", fallback);
|
|
86
|
+
await access(iconPath);
|
|
87
|
+
return iconPath;
|
|
88
|
+
}
|
|
89
|
+
return null;
|
|
38
90
|
}
|
|
39
91
|
catch {
|
|
40
92
|
return null;
|