@nocoo/otter 1.0.3 → 1.1.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.js +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/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/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 +1 -1
package/dist/cli.js
CHANGED
|
@@ -393,7 +393,7 @@ const loginCommand = defineCommand({
|
|
|
393
393
|
export const main = defineCommand({
|
|
394
394
|
meta: {
|
|
395
395
|
name: "otter",
|
|
396
|
-
version: "1.0
|
|
396
|
+
version: "1.1.0",
|
|
397
397
|
description: "Backup and restore your Mac development environment configuration",
|
|
398
398
|
},
|
|
399
399
|
subCommands: {
|
|
@@ -8,12 +8,17 @@ import type { CollectorCategory, CollectorResult } from "@otter/core";
|
|
|
8
8
|
* to a deterministic R2 URL (SHA-256 hash of app name).
|
|
9
9
|
*/
|
|
10
10
|
export declare class ApplicationsCollector extends BaseCollector {
|
|
11
|
-
private readonly
|
|
11
|
+
private readonly systemAppsDir;
|
|
12
12
|
private readonly iconBaseUrl?;
|
|
13
|
-
|
|
13
|
+
private readonly userAppsDir;
|
|
14
|
+
constructor(homeDir: string, systemAppsDir?: string, iconBaseUrl?: string | undefined, userAppsDir?: string);
|
|
15
|
+
/** Overridable for testing — executes a shell command and returns stdout */
|
|
16
|
+
_execCommand: (cmd: string) => Promise<string>;
|
|
14
17
|
readonly id = "applications";
|
|
15
18
|
readonly label = "Installed Applications";
|
|
16
19
|
readonly category: CollectorCategory;
|
|
17
20
|
collect(): Promise<CollectorResult>;
|
|
21
|
+
private collectFromDir;
|
|
22
|
+
private getAppVersion;
|
|
18
23
|
}
|
|
19
24
|
//# sourceMappingURL=applications.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"applications.d.ts","sourceRoot":"","sources":["../../src/collectors/applications.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"applications.d.ts","sourceRoot":"","sources":["../../src/collectors/applications.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,KAAK,EACV,iBAAiB,EACjB,eAAe,EAEhB,MAAM,aAAa,CAAC;AAUrB;;;;;;GAMG;AACH,qBAAa,qBAAsB,SAAQ,aAAa;IAKpD,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;IAL/B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAGnC,OAAO,EAAE,MAAM,EACE,aAAa,GAAE,MAAwB,EACvC,WAAW,CAAC,EAAE,MAAM,YAAA,EACrC,WAAW,CAAC,EAAE,MAAM;IAMtB,4EAA4E;IAC5E,YAAY,GAAU,KAAK,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC,CAGjD;IAEF,QAAQ,CAAC,EAAE,kBAAkB;IAC7B,QAAQ,CAAC,KAAK,4BAA4B;IAC1C,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAiB;IAE/C,OAAO,IAAI,OAAO,CAAC,eAAe,CAAC;YAa3B,cAAc;YAiCd,aAAa;CAe5B"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
+
import { exec } from "node:child_process";
|
|
2
3
|
import { readdir } from "node:fs/promises";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { promisify } from "node:util";
|
|
3
6
|
import { BaseCollector } from "./base.js";
|
|
7
|
+
const execAsync = promisify(exec);
|
|
4
8
|
/** Generate a deterministic icon URL from an app name and base URL */
|
|
5
9
|
function iconUrl(appName, baseUrl) {
|
|
6
10
|
const hash = createHash("sha256").update(appName).digest("hex").slice(0, 12);
|
|
@@ -14,38 +18,68 @@ function iconUrl(appName, baseUrl) {
|
|
|
14
18
|
* to a deterministic R2 URL (SHA-256 hash of app name).
|
|
15
19
|
*/
|
|
16
20
|
export class ApplicationsCollector extends BaseCollector {
|
|
17
|
-
|
|
21
|
+
systemAppsDir;
|
|
18
22
|
iconBaseUrl;
|
|
19
|
-
|
|
23
|
+
userAppsDir;
|
|
24
|
+
constructor(homeDir, systemAppsDir = "/Applications", iconBaseUrl, userAppsDir) {
|
|
20
25
|
super(homeDir);
|
|
21
|
-
this.
|
|
26
|
+
this.systemAppsDir = systemAppsDir;
|
|
22
27
|
this.iconBaseUrl = iconBaseUrl;
|
|
28
|
+
this.userAppsDir = userAppsDir ?? join(homeDir, "Applications");
|
|
23
29
|
}
|
|
30
|
+
/** Overridable for testing — executes a shell command and returns stdout */
|
|
31
|
+
_execCommand = async (cmd) => {
|
|
32
|
+
const { stdout } = await execAsync(cmd);
|
|
33
|
+
return stdout;
|
|
34
|
+
};
|
|
24
35
|
id = "applications";
|
|
25
36
|
label = "Installed Applications";
|
|
26
37
|
category = "environment";
|
|
27
38
|
async collect() {
|
|
28
39
|
return this.timed(async (result) => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
40
|
+
const apps = new Map();
|
|
41
|
+
await this.collectFromDir(this.systemAppsDir, apps, result);
|
|
42
|
+
await this.collectFromDir(this.userAppsDir, apps, result);
|
|
43
|
+
result.lists.push(...Array.from(apps.values()).sort((a, b) => a.name.localeCompare(b.name)));
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
async collectFromDir(appsDir, apps, result) {
|
|
47
|
+
try {
|
|
48
|
+
const entries = await readdir(appsDir, { withFileTypes: true });
|
|
49
|
+
for (const entry of entries) {
|
|
50
|
+
if (!entry.isDirectory() || !entry.name.endsWith(".app"))
|
|
51
|
+
continue;
|
|
52
|
+
const name = entry.name.replace(/\.app$/, "");
|
|
53
|
+
const existing = apps.get(name);
|
|
54
|
+
if (existing)
|
|
55
|
+
continue;
|
|
56
|
+
const version = await this.getAppVersion(appsDir, entry.name);
|
|
57
|
+
const item = {
|
|
58
|
+
name,
|
|
59
|
+
...(version ? { version } : {}),
|
|
60
|
+
};
|
|
61
|
+
if (this.iconBaseUrl) {
|
|
62
|
+
item.meta = { iconUrl: iconUrl(name, this.iconBaseUrl) };
|
|
46
63
|
}
|
|
64
|
+
apps.set(name, item);
|
|
47
65
|
}
|
|
48
|
-
}
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
if (err.code !== "ENOENT") {
|
|
69
|
+
result.errors.push(`Failed to read applications directory ${appsDir}: ${err.message}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async getAppVersion(appsDir, entryName) {
|
|
74
|
+
const plistPath = join(appsDir, entryName, "Contents", "Info.plist");
|
|
75
|
+
try {
|
|
76
|
+
const version = await this._execCommand(`defaults read ${JSON.stringify(plistPath)} CFBundleShortVersionString`);
|
|
77
|
+
const trimmed = version.trim();
|
|
78
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
49
83
|
}
|
|
50
84
|
}
|
|
51
85
|
//# sourceMappingURL=applications.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"applications.js","sourceRoot":"","sources":["../../src/collectors/applications.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAO1C,sEAAsE;AACtE,SAAS,OAAO,CAAC,OAAe,EAAE,OAAe;IAC/C,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC7E,OAAO,GAAG,OAAO,IAAI,IAAI,MAAM,CAAC;AAClC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,OAAO,qBAAsB,SAAQ,aAAa;
|
|
1
|
+
{"version":3,"file":"applications.js","sourceRoot":"","sources":["../../src/collectors/applications.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BaseCollector } from "./base.js";
|
|
2
|
+
import type { CollectorCategory, CollectorResult } from "@otter/core";
|
|
3
|
+
export declare class CloudCLICollector extends BaseCollector {
|
|
4
|
+
readonly id = "cloud-cli";
|
|
5
|
+
readonly label = "Cloud CLI Configuration";
|
|
6
|
+
readonly category: CollectorCategory;
|
|
7
|
+
collect(): Promise<CollectorResult>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=cloud-cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloud-cli.d.ts","sourceRoot":"","sources":["../../src/collectors/cloud-cli.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,KAAK,EACV,iBAAiB,EACjB,eAAe,EAEhB,MAAM,aAAa,CAAC;AAoBrB,qBAAa,iBAAkB,SAAQ,aAAa;IAClD,QAAQ,CAAC,EAAE,eAAe;IAC1B,QAAQ,CAAC,KAAK,6BAA6B;IAC3C,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAY;IAE1C,OAAO,IAAI,OAAO,CAAC,eAAe,CAAC;CAgE1C"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { BaseCollector } from "./base.js";
|
|
3
|
+
function parseAwsProfiles(content) {
|
|
4
|
+
return content
|
|
5
|
+
.split("\n")
|
|
6
|
+
.map((line) => line.trim())
|
|
7
|
+
.filter((line) => line.startsWith("[") && line.endsWith("]"))
|
|
8
|
+
.map((line) => line.slice(1, -1))
|
|
9
|
+
.flatMap((section) => {
|
|
10
|
+
const profile = section.startsWith("profile ")
|
|
11
|
+
? section.slice("profile ".length)
|
|
12
|
+
: section === "default"
|
|
13
|
+
? "default"
|
|
14
|
+
: null;
|
|
15
|
+
return profile
|
|
16
|
+
? [{ name: profile, meta: { type: "aws-profile" } }]
|
|
17
|
+
: [];
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
export class CloudCLICollector extends BaseCollector {
|
|
21
|
+
id = "cloud-cli";
|
|
22
|
+
label = "Cloud CLI Configuration";
|
|
23
|
+
category = "config";
|
|
24
|
+
async collect() {
|
|
25
|
+
return this.timed(async (result) => {
|
|
26
|
+
const azureConfig = await this.safeReadFile(join(this.homeDir, ".azure", "config"), result, { redact: true });
|
|
27
|
+
if (azureConfig)
|
|
28
|
+
result.files.push(azureConfig);
|
|
29
|
+
const azureProfile = await this.safeReadFile(join(this.homeDir, ".azure", "azureProfile.json"), result, { redact: true });
|
|
30
|
+
if (azureProfile)
|
|
31
|
+
result.files.push(azureProfile);
|
|
32
|
+
const azureClouds = await this.safeReadFile(join(this.homeDir, ".azure", "clouds.config"), result);
|
|
33
|
+
if (azureClouds)
|
|
34
|
+
result.files.push(azureClouds);
|
|
35
|
+
const awsConfig = await this.safeReadFile(join(this.homeDir, ".aws", "config"), result, { redact: true });
|
|
36
|
+
if (awsConfig) {
|
|
37
|
+
result.files.push(awsConfig);
|
|
38
|
+
result.lists.push(...parseAwsProfiles(awsConfig.content));
|
|
39
|
+
}
|
|
40
|
+
const gcloudProperties = await this.safeReadFile(join(this.homeDir, ".config", "gcloud", "properties"), result, { redact: true });
|
|
41
|
+
if (gcloudProperties)
|
|
42
|
+
result.files.push(gcloudProperties);
|
|
43
|
+
const gcloudConfigurations = await this.collectDir(join(this.homeDir, ".config", "gcloud", "configurations"), result, {
|
|
44
|
+
redact: true,
|
|
45
|
+
filter: (filePath) => {
|
|
46
|
+
const blocked = [
|
|
47
|
+
"credentials.db",
|
|
48
|
+
"access_tokens.db",
|
|
49
|
+
"application_default_credentials.json",
|
|
50
|
+
];
|
|
51
|
+
return !blocked.some((suffix) => filePath.endsWith(suffix));
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
result.files.push(...gcloudConfigurations);
|
|
55
|
+
const railwayConfig = await this.safeReadFile(join(this.homeDir, ".config", "railway", "config.json"), result, { redact: true });
|
|
56
|
+
if (railwayConfig)
|
|
57
|
+
result.files.push(railwayConfig);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=cloud-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloud-cli.js","sourceRoot":"","sources":["../../src/collectors/cloud-cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { BaseCollector } from "./base.js";
|
|
2
|
+
import type { CollectorCategory, CollectorResult } from "@otter/core";
|
|
3
|
+
export declare class DevToolchainCollector extends BaseCollector {
|
|
4
|
+
readonly id = "dev-toolchain";
|
|
5
|
+
readonly label = "Development Toolchain";
|
|
6
|
+
readonly category: CollectorCategory;
|
|
7
|
+
_execCommand: (cmd: string) => Promise<string>;
|
|
8
|
+
collect(): Promise<CollectorResult>;
|
|
9
|
+
private collectFnm;
|
|
10
|
+
private collectVolta;
|
|
11
|
+
private collectNpmGlobals;
|
|
12
|
+
private collectBunGlobals;
|
|
13
|
+
private collectRustup;
|
|
14
|
+
private collectCargoGlobals;
|
|
15
|
+
private collectPyenv;
|
|
16
|
+
private collectRbenv;
|
|
17
|
+
private collectGo;
|
|
18
|
+
private pushMissingToolError;
|
|
19
|
+
private shouldIgnoreBunGlobalError;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=dev-toolchain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-toolchain.d.ts","sourceRoot":"","sources":["../../src/collectors/dev-toolchain.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,KAAK,EACV,iBAAiB,EACjB,eAAe,EAEhB,MAAM,aAAa,CAAC;AAoCrB,qBAAa,qBAAsB,SAAQ,aAAa;IACtD,QAAQ,CAAC,EAAE,mBAAmB;IAC9B,QAAQ,CAAC,KAAK,2BAA2B;IACzC,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAiB;IAErD,YAAY,GAAU,KAAK,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC,CAGjD;IAEI,OAAO,IAAI,OAAO,CAAC,eAAe,CAAC;YAc3B,UAAU;YA0BV,YAAY;YAmBZ,iBAAiB;YAmBjB,iBAAiB;YAuBjB,aAAa;YAuBb,mBAAmB;YAqBnB,YAAY;YAcZ,YAAY;YAcZ,SAAS;IAkBvB,OAAO,CAAC,oBAAoB;IAiB5B,OAAO,CAAC,0BAA0B;CAOnC"}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { exec } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
import { BaseCollector } from "./base.js";
|
|
4
|
+
const execAsync = promisify(exec);
|
|
5
|
+
function lines(output) {
|
|
6
|
+
return output
|
|
7
|
+
.split("\n")
|
|
8
|
+
.map((line) => line.trim())
|
|
9
|
+
.filter((line) => line.length > 0);
|
|
10
|
+
}
|
|
11
|
+
function parseFnmVersion(line) {
|
|
12
|
+
const versionMatch = line.match(/v(\d+\.\d+\.\d+)/);
|
|
13
|
+
return versionMatch?.[1] ?? null;
|
|
14
|
+
}
|
|
15
|
+
function parseInstalledRustToolchains(output) {
|
|
16
|
+
const allLines = output.split("\n");
|
|
17
|
+
const startIndex = allLines.findIndex((line) => line.trim() === "installed toolchains");
|
|
18
|
+
if (startIndex === -1)
|
|
19
|
+
return [];
|
|
20
|
+
const toolchains = [];
|
|
21
|
+
for (const rawLine of allLines.slice(startIndex + 1)) {
|
|
22
|
+
const line = rawLine.trim();
|
|
23
|
+
if (!line) {
|
|
24
|
+
if (toolchains.length > 0)
|
|
25
|
+
break;
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (/^-+$/.test(line))
|
|
29
|
+
continue;
|
|
30
|
+
if (line.endsWith(":"))
|
|
31
|
+
break;
|
|
32
|
+
toolchains.push(line);
|
|
33
|
+
}
|
|
34
|
+
return toolchains;
|
|
35
|
+
}
|
|
36
|
+
export class DevToolchainCollector extends BaseCollector {
|
|
37
|
+
id = "dev-toolchain";
|
|
38
|
+
label = "Development Toolchain";
|
|
39
|
+
category = "environment";
|
|
40
|
+
_execCommand = async (cmd) => {
|
|
41
|
+
const { stdout } = await execAsync(cmd, { shell: "/bin/bash" });
|
|
42
|
+
return stdout;
|
|
43
|
+
};
|
|
44
|
+
async collect() {
|
|
45
|
+
return this.timed(async (result) => {
|
|
46
|
+
result.lists.push(...(await this.collectFnm(result)));
|
|
47
|
+
result.lists.push(...(await this.collectVolta(result)));
|
|
48
|
+
result.lists.push(...(await this.collectNpmGlobals(result)));
|
|
49
|
+
result.lists.push(...(await this.collectBunGlobals(result)));
|
|
50
|
+
result.lists.push(...(await this.collectRustup(result)));
|
|
51
|
+
result.lists.push(...(await this.collectCargoGlobals(result)));
|
|
52
|
+
result.lists.push(...(await this.collectPyenv(result)));
|
|
53
|
+
result.lists.push(...(await this.collectRbenv(result)));
|
|
54
|
+
result.lists.push(...(await this.collectGo(result)));
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
async collectFnm(result) {
|
|
58
|
+
try {
|
|
59
|
+
const output = await this._execCommand("fnm list");
|
|
60
|
+
return lines(output)
|
|
61
|
+
.flatMap((line) => {
|
|
62
|
+
const version = parseFnmVersion(line);
|
|
63
|
+
if (!version)
|
|
64
|
+
return [];
|
|
65
|
+
return [
|
|
66
|
+
{
|
|
67
|
+
name: `node/v${version}`,
|
|
68
|
+
version,
|
|
69
|
+
meta: {
|
|
70
|
+
type: "node-version",
|
|
71
|
+
manager: "fnm",
|
|
72
|
+
...(line.includes("default") ? { default: "true" } : {}),
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
];
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
this.pushMissingToolError(result, "fnm", err);
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async collectVolta(result) {
|
|
84
|
+
try {
|
|
85
|
+
const output = await this._execCommand("volta list all");
|
|
86
|
+
return lines(output)
|
|
87
|
+
.filter((line) => /^(node|npm|yarn|pnpm)\s+/.test(line))
|
|
88
|
+
.map((line) => {
|
|
89
|
+
const [tool, version] = line.split(/\s+/);
|
|
90
|
+
return {
|
|
91
|
+
name: tool,
|
|
92
|
+
version,
|
|
93
|
+
meta: { type: "tool-version", manager: "volta" },
|
|
94
|
+
};
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
this.pushMissingToolError(result, "volta", err);
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
async collectNpmGlobals(result) {
|
|
103
|
+
try {
|
|
104
|
+
const output = await this._execCommand("npm list -g --depth=0 --json");
|
|
105
|
+
const parsed = JSON.parse(output);
|
|
106
|
+
return Object.entries(parsed.dependencies ?? {})
|
|
107
|
+
.map(([name, meta]) => ({
|
|
108
|
+
name,
|
|
109
|
+
...(meta.version ? { version: meta.version } : {}),
|
|
110
|
+
meta: { type: "npm-global" },
|
|
111
|
+
}))
|
|
112
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
this.pushMissingToolError(result, "npm", err);
|
|
116
|
+
return [];
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
async collectBunGlobals(result) {
|
|
120
|
+
try {
|
|
121
|
+
const output = await this._execCommand("bun pm ls -g");
|
|
122
|
+
return lines(output)
|
|
123
|
+
.map((line) => line.replace(/^[├└─\s]+/, "").trim())
|
|
124
|
+
.filter((line) => line.includes("@"))
|
|
125
|
+
.map((line) => {
|
|
126
|
+
const atIndex = line.lastIndexOf("@");
|
|
127
|
+
return {
|
|
128
|
+
name: line.slice(0, atIndex),
|
|
129
|
+
version: line.slice(atIndex + 1),
|
|
130
|
+
meta: { type: "bun-global" },
|
|
131
|
+
};
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
if (this.shouldIgnoreBunGlobalError(err)) {
|
|
136
|
+
return [];
|
|
137
|
+
}
|
|
138
|
+
this.pushMissingToolError(result, "bun", err);
|
|
139
|
+
return [];
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
async collectRustup(result) {
|
|
143
|
+
try {
|
|
144
|
+
const output = await this._execCommand("rustup show");
|
|
145
|
+
return parseInstalledRustToolchains(output)
|
|
146
|
+
.map((line) => {
|
|
147
|
+
const isDefault = line.includes("default");
|
|
148
|
+
const isActive = line.includes("active");
|
|
149
|
+
const name = line.replace(/\s*\((?:active(?:,\s*)?)?default\)/, "").trim();
|
|
150
|
+
return {
|
|
151
|
+
name,
|
|
152
|
+
meta: {
|
|
153
|
+
type: "rust-toolchain",
|
|
154
|
+
...(isActive ? { active: "true" } : {}),
|
|
155
|
+
...(isDefault ? { default: "true" } : {}),
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
this.pushMissingToolError(result, "rustup", err);
|
|
162
|
+
return [];
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
async collectCargoGlobals(result) {
|
|
166
|
+
try {
|
|
167
|
+
const output = await this._execCommand("cargo install --list");
|
|
168
|
+
const items = [];
|
|
169
|
+
for (const line of lines(output)) {
|
|
170
|
+
if (!line.includes(" v"))
|
|
171
|
+
continue;
|
|
172
|
+
const match = line.match(/^([^\s]+) v([^:]+):?$/);
|
|
173
|
+
if (!match)
|
|
174
|
+
continue;
|
|
175
|
+
items.push({
|
|
176
|
+
name: match[1],
|
|
177
|
+
version: match[2],
|
|
178
|
+
meta: { type: "cargo-global" },
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
return items;
|
|
182
|
+
}
|
|
183
|
+
catch (err) {
|
|
184
|
+
this.pushMissingToolError(result, "cargo", err);
|
|
185
|
+
return [];
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
async collectPyenv(result) {
|
|
189
|
+
try {
|
|
190
|
+
const output = await this._execCommand("pyenv versions --bare");
|
|
191
|
+
return lines(output).map((version) => ({
|
|
192
|
+
name: `python/${version}`,
|
|
193
|
+
version,
|
|
194
|
+
meta: { type: "python-version" },
|
|
195
|
+
}));
|
|
196
|
+
}
|
|
197
|
+
catch (err) {
|
|
198
|
+
this.pushMissingToolError(result, "pyenv", err);
|
|
199
|
+
return [];
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
async collectRbenv(result) {
|
|
203
|
+
try {
|
|
204
|
+
const output = await this._execCommand("rbenv versions --bare");
|
|
205
|
+
return lines(output).map((version) => ({
|
|
206
|
+
name: `ruby/${version}`,
|
|
207
|
+
version,
|
|
208
|
+
meta: { type: "ruby-version" },
|
|
209
|
+
}));
|
|
210
|
+
}
|
|
211
|
+
catch (err) {
|
|
212
|
+
this.pushMissingToolError(result, "rbenv", err);
|
|
213
|
+
return [];
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
async collectGo(result) {
|
|
217
|
+
try {
|
|
218
|
+
const output = await this._execCommand("go version");
|
|
219
|
+
const match = output.match(/go version go([^\s]+)/);
|
|
220
|
+
if (!match)
|
|
221
|
+
return [];
|
|
222
|
+
return [
|
|
223
|
+
{
|
|
224
|
+
name: "go",
|
|
225
|
+
version: match[1],
|
|
226
|
+
meta: { type: "go-version" },
|
|
227
|
+
},
|
|
228
|
+
];
|
|
229
|
+
}
|
|
230
|
+
catch (err) {
|
|
231
|
+
this.pushMissingToolError(result, "go", err);
|
|
232
|
+
return [];
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
pushMissingToolError(result, tool, err) {
|
|
236
|
+
const message = err.message;
|
|
237
|
+
if (message.includes("not found") ||
|
|
238
|
+
message.includes("command not found") ||
|
|
239
|
+
message.includes("No such file")) {
|
|
240
|
+
result.errors.push(`Skipped ${tool}: not installed`);
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
result.errors.push(`Failed to collect ${tool}: ${message}`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
shouldIgnoreBunGlobalError(err) {
|
|
247
|
+
const message = err.message;
|
|
248
|
+
return (message.includes('No package.json was found for directory') ||
|
|
249
|
+
message.includes('Run "bun init" to initialize a project'));
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=dev-toolchain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-toolchain.js","sourceRoot":"","sources":["../../src/collectors/dev-toolchain.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BaseCollector } from "./base.js";
|
|
2
|
+
import type { CollectorCategory, CollectorResult } from "@otter/core";
|
|
3
|
+
export declare class DockerCollector extends BaseCollector {
|
|
4
|
+
readonly id = "docker";
|
|
5
|
+
readonly label = "Docker Configuration";
|
|
6
|
+
readonly category: CollectorCategory;
|
|
7
|
+
_execCommand: (cmd: string) => Promise<string>;
|
|
8
|
+
collect(): Promise<CollectorResult>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=docker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../../src/collectors/docker.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,KAAK,EACV,iBAAiB,EACjB,eAAe,EAEhB,MAAM,aAAa,CAAC;AAmCrB,qBAAa,eAAgB,SAAQ,aAAa;IAChD,QAAQ,CAAC,EAAE,YAAY;IACvB,QAAQ,CAAC,KAAK,0BAA0B;IACxC,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAiB;IAErD,YAAY,GAAU,KAAK,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC,CAGjD;IAEI,OAAO,IAAI,OAAO,CAAC,eAAe,CAAC;CAmB1C"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { exec } from "node:child_process";
|
|
3
|
+
import { promisify } from "node:util";
|
|
4
|
+
import { BaseCollector } from "./base.js";
|
|
5
|
+
const execAsync = promisify(exec);
|
|
6
|
+
function parseDockerContexts(output) {
|
|
7
|
+
return output
|
|
8
|
+
.split("\n")
|
|
9
|
+
.map((line) => line.trim())
|
|
10
|
+
.filter((line) => line.length > 0)
|
|
11
|
+
.flatMap((line) => {
|
|
12
|
+
try {
|
|
13
|
+
const parsed = JSON.parse(line);
|
|
14
|
+
if (!parsed.Name)
|
|
15
|
+
return [];
|
|
16
|
+
return [
|
|
17
|
+
{
|
|
18
|
+
name: parsed.Name,
|
|
19
|
+
meta: {
|
|
20
|
+
type: "docker-context",
|
|
21
|
+
...(parsed.Current ? { current: "true" } : {}),
|
|
22
|
+
...(parsed.DockerEndpoint
|
|
23
|
+
? { endpoint: parsed.DockerEndpoint }
|
|
24
|
+
: {}),
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
export class DockerCollector extends BaseCollector {
|
|
35
|
+
id = "docker";
|
|
36
|
+
label = "Docker Configuration";
|
|
37
|
+
category = "environment";
|
|
38
|
+
_execCommand = async (cmd) => {
|
|
39
|
+
const { stdout } = await execAsync(cmd);
|
|
40
|
+
return stdout;
|
|
41
|
+
};
|
|
42
|
+
async collect() {
|
|
43
|
+
return this.timed(async (result) => {
|
|
44
|
+
const config = await this.safeReadFile(join(this.homeDir, ".docker", "config.json"), result, { redact: true });
|
|
45
|
+
if (config)
|
|
46
|
+
result.files.push(config);
|
|
47
|
+
try {
|
|
48
|
+
const output = await this._execCommand("docker context ls --format json");
|
|
49
|
+
result.lists.push(...parseDockerContexts(output));
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
result.errors.push(`Failed to run 'docker context ls --format json': ${err.message}`);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=docker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker.js","sourceRoot":"","sources":["../../src/collectors/docker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAO1C,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAElC,SAAS,mBAAmB,CAAC,MAAc;IACzC,OAAO,MAAM;SACV,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;SACjC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QAChB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAI7B,CAAC;YACF,IAAI,CAAC,MAAM,CAAC,IAAI;gBAAE,OAAO,EAAE,CAAC;YAC5B,OAAO;gBACL;oBACE,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,IAAI,EAAE;wBACJ,IAAI,EAAE,gBAAgB;wBACtB,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBAC9C,GAAG,CAAC,MAAM,CAAC,cAAc;4BACvB,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,cAAc,EAAE;4BACrC,CAAC,CAAC,EAAE,CAAC;qBACR;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC;AAED,MAAM,OAAO,eAAgB,SAAQ,aAAa;IACvC,EAAE,GAAG,QAAQ,CAAC;IACd,KAAK,GAAG,sBAAsB,CAAC;IAC/B,QAAQ,GAAsB,aAAa,CAAC;IAErD,YAAY,GAAG,KAAK,EAAE,GAAW,EAAmB,EAAE;QACpD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC;QACxC,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;IAEF,KAAK,CAAC,OAAO;QACX,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;YACjC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CACpC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,aAAa,CAAC,EAC5C,MAAM,EACN,EAAE,MAAM,EAAE,IAAI,EAAE,CACjB,CAAC;YACF,IAAI,MAAM;gBAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAEtC,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,iCAAiC,CAAC,CAAC;gBAC1E,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC;YACpD,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,MAAM,CAAC,IAAI,CAChB,oDAAqD,GAAa,CAAC,OAAO,EAAE,CAC7E,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BaseCollector } from "./base.js";
|
|
2
|
+
import type { CollectorCategory, CollectorResult } from "@otter/core";
|
|
3
|
+
export declare class FontsCollector extends BaseCollector {
|
|
4
|
+
readonly id = "fonts";
|
|
5
|
+
readonly label = "Installed Fonts";
|
|
6
|
+
readonly category: CollectorCategory;
|
|
7
|
+
collect(): Promise<CollectorResult>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=fonts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fonts.d.ts","sourceRoot":"","sources":["../../src/collectors/fonts.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,KAAK,EACV,iBAAiB,EACjB,eAAe,EAEhB,MAAM,aAAa,CAAC;AAErB,qBAAa,cAAe,SAAQ,aAAa;IAC/C,QAAQ,CAAC,EAAE,WAAW;IACtB,QAAQ,CAAC,KAAK,qBAAqB;IACnC,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAiB;IAE/C,OAAO,IAAI,OAAO,CAAC,eAAe,CAAC;CA6B1C"}
|