filesnap 0.3.1 → 0.4.0-darwin-arm64

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/package.json CHANGED
@@ -1,14 +1,12 @@
1
1
  {
2
2
  "name": "filesnap",
3
- "version": "0.3.1",
4
- "description": "Git-free file snapshots and rewind — put a directory back the way it was, without a repository and without touching your version control.",
5
- "type": "module",
6
- "bin": {
7
- "filesnap": "bin/filesnap.mjs"
8
- },
9
- "files": [
10
- "bin/",
11
- "README.md"
3
+ "version": "0.4.0-darwin-arm64",
4
+ "description": "Git-free file snapshots and rewind — put a directory back the way it was, without a repository and without touching your version control. (darwin-arm64 binary)",
5
+ "os": [
6
+ "darwin"
7
+ ],
8
+ "cpu": [
9
+ "arm64"
12
10
  ],
13
11
  "license": "Apache-2.0",
14
12
  "repository": {
@@ -16,27 +14,7 @@
16
14
  "url": "git+https://github.com/extracurricular-ai/filesnap.git"
17
15
  },
18
16
  "homepage": "https://github.com/extracurricular-ai/filesnap",
19
- "bugs": {
20
- "url": "https://github.com/extracurricular-ai/filesnap/issues"
21
- },
22
- "keywords": [
23
- "snapshot",
24
- "rewind",
25
- "undo",
26
- "checkpoint",
27
- "restore",
28
- "filesystem",
29
- "cli"
30
- ],
31
- "engines": {
32
- "node": ">=18"
33
- },
34
- "optionalDependencies": {
35
- "filesnap-linux-x64": "npm:filesnap@0.3.1-linux-x64",
36
- "filesnap-linux-arm64": "npm:filesnap@0.3.1-linux-arm64",
37
- "filesnap-darwin-x64": "npm:filesnap@0.3.1-darwin-x64",
38
- "filesnap-darwin-arm64": "npm:filesnap@0.3.1-darwin-arm64",
39
- "filesnap-win32-x64": "npm:filesnap@0.3.1-win32-x64",
40
- "filesnap-win32-arm64": "npm:filesnap@0.3.1-win32-arm64"
41
- }
17
+ "files": [
18
+ "vendor/"
19
+ ]
42
20
  }
package/README.md DELETED
@@ -1,47 +0,0 @@
1
- # filesnap
2
-
3
- Git-free file snapshots and rewind: capture what a directory holds at a moment
4
- you name, and put it back later — without a repository, and without touching
5
- your version control.
6
-
7
- ```console
8
- npm install -g filesnap
9
- ```
10
-
11
- This package is a thin launcher. The binary for your platform arrives as an
12
- optional dependency, so the install downloads one build rather than six.
13
-
14
- ```console
15
- $ filesnap capture --session s1 --turn t1
16
- {"v":1,"type":"capture.done","manifest":"a5a2b149…","reused":0,"hashed":1,"dropped":0}
17
-
18
- $ echo "something regrettable" > a.txt
19
-
20
- $ filesnap restore --session s1 --turn t1
21
- {"v":1,"type":"restore.done","written":1,"deleted":0,"failed":0,"safety":"e41358f0…"}
22
- ```
23
-
24
- That `safety` id is the point the rewind itself can be rewound to. Every
25
- restore captures one before it writes anything.
26
-
27
- **Output is JSON Lines on stdout, prose on stderr**, and the exit code is part
28
- of the contract: `0` everything happened, `1` it ran and reported but not
29
- everything happened, `2` it did not run, `3` the arguments were wrong.
30
-
31
- Nine commands — `capture`, `declare`, `log`, `restore`, `undo`, `delete`,
32
- `gc`, `status`, `doctor`. The full surface, the event contract, and what it
33
- deliberately refuses to do are in the
34
- [documentation](https://github.com/extracurricular-ai/filesnap#readme).
35
-
36
- ## Platforms
37
-
38
- Linux, macOS and Windows, on x64 and arm64. The Linux builds are statically
39
- linked against musl, so they do not carry a glibc floor from the machine that
40
- built them.
41
-
42
- Not on this list? `cargo install filesnap-cli` builds the same command from
43
- source.
44
-
45
- ## Licence
46
-
47
- Apache-2.0.
package/bin/filesnap.mjs DELETED
@@ -1,141 +0,0 @@
1
- #!/usr/bin/env node
2
- // The `filesnap` command, as npm installs it.
3
- //
4
- // This file exists to find one binary and get out of the way. The six
5
- // platform builds are published as six *versions of this same npm name*
6
- // (D37), named from here through alias specs in `optionalDependencies`, and
7
- // `os`/`cpu` on each of them is what makes npm unpack exactly one.
8
- //
9
- // **`.mjs`, not `.js`.** As `.js` this file is an ES module only because the
10
- // package.json beside it says `"type": "module"` — a dependency on a sibling
11
- // that is invisible from here, and one node 18 enforces strictly while node 22
12
- // and later paper over with ES-module detection. The extension says what the
13
- // file is, so nothing has to be true elsewhere for it to load.
14
- //
15
- // Everything below is either locating that binary or forwarding a signal to
16
- // it. Nothing here parses arguments or interprets output: the contract is the
17
- // binary's (JSON Lines on stdout, prose on stderr, exit codes 0/1/2/3), and a
18
- // launcher that inspected either would be a second place for it to drift.
19
-
20
- import { spawn } from "node:child_process";
21
- import { existsSync } from "node:fs";
22
- import { createRequire } from "node:module";
23
- import path from "node:path";
24
- import { fileURLToPath } from "node:url";
25
-
26
- const here = path.dirname(fileURLToPath(import.meta.url));
27
- const require = createRequire(import.meta.url);
28
-
29
- // Linux is musl deliberately. A glibc build carries a symbol-version floor set
30
- // by whatever machine produced it, which would break older distributions and
31
- // containers — the one failure an npm-installed binary cannot help its user
32
- // debug. filesnap has no C dependency, so the static build costs nothing; it
33
- // is marginally *smaller* than the glibc one.
34
- const TRIPLE_BY_PLATFORM = {
35
- "linux-x64": "x86_64-unknown-linux-musl",
36
- "linux-arm64": "aarch64-unknown-linux-musl",
37
- "darwin-x64": "x86_64-apple-darwin",
38
- "darwin-arm64": "aarch64-apple-darwin",
39
- "win32-x64": "x86_64-pc-windows-msvc",
40
- "win32-arm64": "aarch64-pc-windows-msvc",
41
- };
42
-
43
- /**
44
- * Exit the way the binary would have.
45
- *
46
- * `2` is the CLI's own "it did not run, or could not report" (D40). A launcher
47
- * that cannot find its binary is exactly that, seen one level up — so a caller
48
- * checking exit codes does not need to know whether it was the wrapper or the
49
- * program that failed. `throw` would print a stack trace, which tells a user
50
- * nothing they can act on.
51
- */
52
- function fail(message) {
53
- process.stderr.write(`filesnap: ${message}\n`);
54
- process.exit(2);
55
- }
56
-
57
- /** How this user would reinstall, so the error names their own tool. */
58
- function installCommand() {
59
- const agent = process.env.npm_config_user_agent || "";
60
- if (agent.startsWith("pnpm")) return "pnpm add -g filesnap";
61
- if (agent.startsWith("yarn")) return "yarn global add filesnap";
62
- if (/\bbun\//.test(agent)) return "bun install -g filesnap";
63
- return "npm install -g filesnap";
64
- }
65
-
66
- // Android runs the Linux builds.
67
- const platform = process.platform === "android" ? "linux" : process.platform;
68
- const slug = `${platform}-${process.arch}`;
69
- const triple = TRIPLE_BY_PLATFORM[slug];
70
- if (!triple) {
71
- fail(
72
- `there is no build for ${process.platform} ${process.arch}. ` +
73
- `Install from source instead: cargo install filesnap-cli`,
74
- );
75
- }
76
-
77
- const platformPackage = `filesnap-${slug}`;
78
-
79
- function locateBinary() {
80
- let vendorRoot;
81
- try {
82
- // Ask the resolver rather than guessing at a path: pnpm, Yarn PnP and
83
- // hoisting all put the platform package somewhere different, and every
84
- // one of them can answer this.
85
- const manifest = require.resolve(`${platformPackage}/package.json`);
86
- vendorRoot = path.join(path.dirname(manifest), "vendor");
87
- } catch {
88
- // No resolver answer: a tarball someone unpacked by hand, or a bundler
89
- // that flattened node_modules. Fall back to this package's own tree.
90
- vendorRoot = path.join(here, "..", "vendor");
91
- }
92
-
93
- const binary = path.join(
94
- vendorRoot,
95
- triple,
96
- "bin",
97
- platform === "win32" ? "filesnap.exe" : "filesnap",
98
- );
99
- return existsSync(binary) ? binary : null;
100
- }
101
-
102
- const binary = locateBinary();
103
- if (!binary) {
104
- fail(
105
- `the ${platformPackage} package is missing or has no binary. ` +
106
- `Reinstall with \`${installCommand()}\`.`,
107
- );
108
- }
109
-
110
- // `spawn`, not `spawnSync`: a synchronous spawn makes Node deaf to signals for
111
- // the whole run, so a Ctrl-C during a capture over a large project would be
112
- // swallowed and the user would watch it keep going.
113
- const child = spawn(binary, process.argv.slice(2), { stdio: "inherit" });
114
-
115
- const FORWARDED = ["SIGINT", "SIGTERM", "SIGHUP"];
116
- const handlers = new Map();
117
- for (const signal of FORWARDED) {
118
- const handler = () => {
119
- if (child.exitCode === null && !child.killed) child.kill(signal);
120
- };
121
- try {
122
- process.on(signal, handler);
123
- handlers.set(signal, handler);
124
- } catch {
125
- // Windows does not raise every one of these. Not being able to forward a
126
- // signal that cannot arrive is not a problem worth reporting.
127
- }
128
- }
129
-
130
- child.on("error", (err) => fail(`could not run ${binary}: ${err.message}`));
131
-
132
- child.on("exit", (code, signal) => {
133
- for (const [name, handler] of handlers) process.off(name, handler);
134
- if (signal) {
135
- // Die of the same signal rather than translating it to a number, so a
136
- // shell reports "terminated" and a supervising process sees what happened.
137
- process.kill(process.pid, signal);
138
- return;
139
- }
140
- process.exit(code ?? 2);
141
- });