git-sshripped 0.1.4

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/README.md ADDED
@@ -0,0 +1,95 @@
1
+ # git-sshripped
2
+
3
+ Git-transparent encryption using SSH keys. No GPG, no Rust toolchain required.
4
+
5
+ This is the npm distribution of [git-sshripped](https://github.com/BSteffaniak/git-sshripped), a tool that keeps selected files encrypted at rest in Git repositories while letting developers work with plaintext when the repo is unlocked.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install git-sshripped
11
+ ```
12
+
13
+ This installs a prebuilt native binary for your platform. No Rust or Cargo needed.
14
+
15
+ ## Usage
16
+
17
+ ### CLI
18
+
19
+ Once installed, `git-sshripped` is available as a command:
20
+
21
+ ```bash
22
+ # Initialize in a repo
23
+ git-sshripped init --pattern "secrets/**"
24
+
25
+ # Unlock (decrypt files for local development)
26
+ git-sshripped unlock
27
+
28
+ # Lock (scrub plaintext from working tree)
29
+ git-sshripped lock
30
+
31
+ # Check status
32
+ git-sshripped status
33
+ ```
34
+
35
+ ### Auto-unlock in postinstall
36
+
37
+ Add this to your project's `package.json` so that encrypted files are automatically decrypted after `npm install`:
38
+
39
+ ```json
40
+ {
41
+ "scripts": {
42
+ "postinstall": "git-sshripped unlock --soft"
43
+ }
44
+ }
45
+ ```
46
+
47
+ The `--soft` flag ensures that `npm install` won't fail if the user doesn't have access to the encrypted files (e.g., they don't have the right SSH key, or they're a CI bot without credentials). A warning is printed instead.
48
+
49
+ For strict mode (fail if unlock fails):
50
+
51
+ ```json
52
+ {
53
+ "scripts": {
54
+ "postinstall": "git-sshripped unlock"
55
+ }
56
+ }
57
+ ```
58
+
59
+ ### Programmatic API
60
+
61
+ ```js
62
+ const { binaryPath, run } = require("git-sshripped");
63
+
64
+ // Get the path to the binary
65
+ console.log(binaryPath);
66
+
67
+ // Spawn git-sshripped with arguments
68
+ const child = run(["status", "--json"]);
69
+ child.on("exit", (code) => {
70
+ console.log("exit code:", code);
71
+ });
72
+ ```
73
+
74
+ ## Binary resolution
75
+
76
+ The binary is resolved in this order:
77
+
78
+ 1. `GIT_SSHRIPPED_BINARY_PATH` environment variable
79
+ 2. Platform-specific npm package (installed automatically via `optionalDependencies`)
80
+ 3. System-installed `git-sshripped` found in `PATH`
81
+
82
+ ## Supported platforms
83
+
84
+ | Platform | Architecture | npm package |
85
+ |----------|-------------|-------------|
86
+ | macOS | ARM64 (Apple Silicon) | `@git-sshripped/darwin-arm64` |
87
+ | macOS | x64 (Intel) | `@git-sshripped/darwin-x64` |
88
+ | Linux | x64 (glibc) | `@git-sshripped/linux-x64` |
89
+ | Linux | ARM64 (glibc) | `@git-sshripped/linux-arm64` |
90
+ | Linux | x64 (musl/Alpine) | `@git-sshripped/linux-x64-musl` |
91
+ | Windows | x64 | `@git-sshripped/win32-x64` |
92
+
93
+ ## License
94
+
95
+ MPL-2.0
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ const { platform, arch, env, argv } = process;
5
+ const { execSync, spawnSync } = require("child_process");
6
+ const path = require("path");
7
+
8
+ function isMusl() {
9
+ // On non-linux, musl detection is irrelevant
10
+ if (platform !== "linux") return false;
11
+ try {
12
+ const stderr = execSync("ldd --version 2>&1", {
13
+ stdio: ["pipe", "pipe", "pipe"],
14
+ }).toString();
15
+ if (stderr.indexOf("musl") > -1) return true;
16
+ } catch (err) {
17
+ // ldd --version exits non-zero on musl systems and prints to stderr
18
+ if (err.stderr && err.stderr.toString().indexOf("musl") > -1) return true;
19
+ }
20
+ return false;
21
+ }
22
+
23
+ const PLATFORMS = {
24
+ win32: {
25
+ x64: "@git-sshripped/win32-x64/git-sshripped.exe",
26
+ },
27
+ darwin: {
28
+ x64: "@git-sshripped/darwin-x64/git-sshripped",
29
+ arm64: "@git-sshripped/darwin-arm64/git-sshripped",
30
+ },
31
+ linux: {
32
+ x64: "@git-sshripped/linux-x64/git-sshripped",
33
+ arm64: "@git-sshripped/linux-arm64/git-sshripped",
34
+ },
35
+ "linux-musl": {
36
+ x64: "@git-sshripped/linux-x64-musl/git-sshripped",
37
+ },
38
+ };
39
+
40
+ function getBinaryPath() {
41
+ // 1. Environment variable override
42
+ if (env.GIT_SSHRIPPED_BINARY_PATH) {
43
+ return env.GIT_SSHRIPPED_BINARY_PATH;
44
+ }
45
+
46
+ // 2. Resolve from platform-specific package
47
+ const platformKey =
48
+ platform === "linux" && isMusl() ? "linux-musl" : platform;
49
+ const subpath = PLATFORMS?.[platformKey]?.[arch];
50
+
51
+ if (subpath) {
52
+ try {
53
+ return require.resolve(subpath);
54
+ } catch {
55
+ // Platform package not installed, fall through
56
+ }
57
+ }
58
+
59
+ // 3. Fallback: look for git-sshripped in PATH
60
+ try {
61
+ const which = platform === "win32" ? "where" : "which";
62
+ const resolved = execSync(`${which} git-sshripped`, {
63
+ stdio: ["pipe", "pipe", "pipe"],
64
+ })
65
+ .toString()
66
+ .trim()
67
+ .split("\n")[0];
68
+ if (resolved) return resolved;
69
+ } catch {
70
+ // Not found in PATH
71
+ }
72
+
73
+ // 4. Give up with a helpful error
74
+ console.error(
75
+ `Error: No prebuilt git-sshripped binary available for ${platform}/${arch}.
76
+
77
+ To fix this, either:
78
+ - Install git-sshripped via cargo: cargo install git_sshripped_cli
79
+ - Set GIT_SSHRIPPED_BINARY_PATH to point to a git-sshripped binary
80
+ - File an issue: https://github.com/BSteffaniak/git-sshripped/issues`
81
+ );
82
+ process.exit(1);
83
+ }
84
+
85
+ const binPath = getBinaryPath();
86
+ const result = spawnSync(binPath, argv.slice(2), {
87
+ shell: false,
88
+ stdio: "inherit",
89
+ });
90
+
91
+ if (result.error) {
92
+ throw result.error;
93
+ }
94
+
95
+ process.exitCode = result.status;
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "git-sshripped",
3
+ "version": "0.1.4",
4
+ "description": "Git-transparent encryption using SSH keys. No GPG, no Rust toolchain required.",
5
+ "license": "MPL-2.0",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/BSteffaniak/git-sshripped.git"
9
+ },
10
+ "bin": {
11
+ "git-sshripped": "bin/git-sshripped"
12
+ },
13
+ "main": "src/index.js",
14
+ "engines": {
15
+ "node": ">=18"
16
+ },
17
+ "optionalDependencies": {
18
+ "@git-sshripped/darwin-arm64": "0.1.4",
19
+ "@git-sshripped/darwin-x64": "0.1.4",
20
+ "@git-sshripped/linux-arm64": "0.1.4",
21
+ "@git-sshripped/linux-x64": "0.1.4",
22
+ "@git-sshripped/linux-x64-musl": "0.1.4",
23
+ "@git-sshripped/win32-x64": "0.1.4"
24
+ },
25
+ "files": [
26
+ "bin/",
27
+ "src/"
28
+ ],
29
+ "publishConfig": {
30
+ "access": "public",
31
+ "registry": "https://registry.npmjs.org"
32
+ }
33
+ }
package/src/index.js ADDED
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+
3
+ const { platform, arch } = process;
4
+ const { execSync, spawn } = require("child_process");
5
+ const { env } = process;
6
+
7
+ function isMusl() {
8
+ if (platform !== "linux") return false;
9
+ try {
10
+ const stderr = execSync("ldd --version 2>&1", {
11
+ stdio: ["pipe", "pipe", "pipe"],
12
+ }).toString();
13
+ if (stderr.indexOf("musl") > -1) return true;
14
+ } catch (err) {
15
+ if (err.stderr && err.stderr.toString().indexOf("musl") > -1) return true;
16
+ }
17
+ return false;
18
+ }
19
+
20
+ const PLATFORMS = {
21
+ win32: {
22
+ x64: "@git-sshripped/win32-x64/git-sshripped.exe",
23
+ },
24
+ darwin: {
25
+ x64: "@git-sshripped/darwin-x64/git-sshripped",
26
+ arm64: "@git-sshripped/darwin-arm64/git-sshripped",
27
+ },
28
+ linux: {
29
+ x64: "@git-sshripped/linux-x64/git-sshripped",
30
+ arm64: "@git-sshripped/linux-arm64/git-sshripped",
31
+ },
32
+ "linux-musl": {
33
+ x64: "@git-sshripped/linux-x64-musl/git-sshripped",
34
+ },
35
+ };
36
+
37
+ /**
38
+ * Resolves the path to the git-sshripped binary.
39
+ *
40
+ * Resolution order:
41
+ * 1. GIT_SSHRIPPED_BINARY_PATH environment variable
42
+ * 2. Platform-specific npm package
43
+ * 3. System-installed binary in PATH
44
+ *
45
+ * @returns {string} Absolute path to the binary
46
+ * @throws {Error} If no binary can be found
47
+ */
48
+ function getBinaryPath() {
49
+ if (env.GIT_SSHRIPPED_BINARY_PATH) {
50
+ return env.GIT_SSHRIPPED_BINARY_PATH;
51
+ }
52
+
53
+ const platformKey =
54
+ platform === "linux" && isMusl() ? "linux-musl" : platform;
55
+ const subpath = PLATFORMS?.[platformKey]?.[arch];
56
+
57
+ if (subpath) {
58
+ try {
59
+ return require.resolve(subpath);
60
+ } catch {
61
+ // Platform package not installed
62
+ }
63
+ }
64
+
65
+ try {
66
+ const which = platform === "win32" ? "where" : "which";
67
+ const resolved = execSync(`${which} git-sshripped`, {
68
+ stdio: ["pipe", "pipe", "pipe"],
69
+ })
70
+ .toString()
71
+ .trim()
72
+ .split("\n")[0];
73
+ if (resolved) return resolved;
74
+ } catch {
75
+ // Not found in PATH
76
+ }
77
+
78
+ throw new Error(
79
+ `No prebuilt git-sshripped binary available for ${platform}/${arch}. ` +
80
+ `Install via cargo (cargo install git_sshripped_cli) or set GIT_SSHRIPPED_BINARY_PATH.`
81
+ );
82
+ }
83
+
84
+ /**
85
+ * The resolved path to the git-sshripped binary.
86
+ * @type {string}
87
+ */
88
+ const binaryPath = getBinaryPath();
89
+
90
+ /**
91
+ * Spawn git-sshripped with the given arguments.
92
+ *
93
+ * @param {string[]} args - Command-line arguments to pass
94
+ * @param {import("child_process").SpawnOptions} [options] - Options passed to child_process.spawn
95
+ * @returns {import("child_process").ChildProcess}
96
+ */
97
+ function run(args, options) {
98
+ return spawn(binaryPath, args, { stdio: "inherit", ...options });
99
+ }
100
+
101
+ module.exports = { binaryPath, run };