@civitai/cli 0.1.119 → 0.1.121

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 CHANGED
@@ -2,8 +2,10 @@
2
2
 
3
3
  The Civitai CLI — author and ship [Civitai App Blocks](https://github.com/civitai/cli).
4
4
 
5
- This npm package is a **thin wrapper** over the Go CLI. On install it downloads
6
- the prebuilt binary for your platform from the project's
5
+ This npm package is a **thin wrapper** over the Go CLI. On linux/x64 the
6
+ prebuilt binary arrives as an npm package of its own
7
+ (`@civitai/cli-linux-x64`), so installing needs only the npm registry. On other
8
+ platforms the wrapper downloads the binary from the project's
7
9
  [GitHub Releases](https://github.com/civitai/cli/releases) and verifies its
8
10
  sha256 checksum.
9
11
 
@@ -22,7 +24,11 @@ npx @civitai/cli app create my-app
22
24
 
23
25
  ## How it works
24
26
 
25
- - On `npm install`, a `postinstall` step downloads
27
+ - On linux/x64, npm installs `@civitai/cli-linux-x64` (an optional dependency
28
+ pinned to the same version), which contains the binary. Nothing is
29
+ downloaded outside the npm registry.
30
+ - Everywhere else — or if optional dependencies were skipped
31
+ (`--omit=optional`) — a `postinstall` step downloads
26
32
  `civitai_<version>_<os>_<arch>` from the matching GitHub Release and verifies
27
33
  it against `checksums.txt`.
28
34
  - The `civitai` command then execs that binary, forwarding all arguments and
package/bin/civitai.js CHANGED
@@ -1,22 +1,21 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
3
 
4
- // Thin launcher for the @civitai/cli wrapper: locate (or lazily download) the
5
- // prebuilt Go binary and exec it, forwarding args, stdio, and exit status.
4
+ // Thin launcher for the @civitai/cli wrapper: locate the prebuilt Go binary
5
+ // (platform package first, else a lazily downloaded one — see lib/install.js)
6
+ // and exec it, forwarding args, stdio, and exit status.
6
7
 
7
8
  const fs = require("fs");
8
9
  const { spawnSync } = require("child_process");
9
- const { ensureBinary, binaryPath } = require("../lib/install.js");
10
+ const { ensureBinary } = require("../lib/install.js");
10
11
 
11
12
  async function resolveBinary() {
12
13
  // Escape hatch + test hook: use an explicit binary if provided and present.
13
14
  const override = process.env.CIVITAI_CLI_BINARY;
14
15
  if (override && fs.existsSync(override)) return override;
15
16
 
16
- const bin = binaryPath();
17
- if (fs.existsSync(bin)) return bin;
18
-
19
- // Missing (e.g. `npm install --ignore-scripts`) — download it now.
17
+ // The platform package's binary, else the one postinstall downloaded, else
18
+ // (e.g. `npm install --ignore-scripts`) download it now.
20
19
  return ensureBinary();
21
20
  }
22
21
 
package/lib/install.js CHANGED
@@ -2,11 +2,20 @@
2
2
 
3
3
  // Dependency-free installer for the @civitai/cli wrapper.
4
4
  //
5
- // Downloads the prebuilt Go binary produced by GoReleaser from the matching
6
- // GitHub Release, verifies its sha256 against checksums.txt, and drops it at
7
- // lib/binaries/civitai(.exe). Runs from the npm `postinstall` hook, and is also
8
- // exported as ensureBinary() so the launcher can lazily download on first run
9
- // (covers `npm install --ignore-scripts`).
5
+ // Finds the prebuilt Go binary, in this order:
6
+ //
7
+ // 1. The platform package (an `optionalDependencies` entry such as
8
+ // @civitai/cli-linux-x64, listed in ./platforms.json) when npm installed
9
+ // one for this host. It IS the binary, so nothing is downloaded — the
10
+ // install works where only the npm registry is reachable.
11
+ // 2. Otherwise the GitHub Release: download the raw binary GoReleaser
12
+ // produced, verify its sha256 against checksums.txt, and drop it at
13
+ // lib/binaries/civitai(.exe). This is every platform without a row in
14
+ // platforms.json, and any install that skipped optional dependencies.
15
+ //
16
+ // Runs from the npm `postinstall` hook, and is also exported as ensureBinary()
17
+ // so the launcher can resolve lazily on first run (covers
18
+ // `npm install --ignore-scripts`).
10
19
 
11
20
  const fs = require("fs");
12
21
  const path = require("path");
@@ -19,6 +28,15 @@ const PLACEHOLDER_VERSION = "0.0.0-dev";
19
28
 
20
29
  const BINARIES_DIR = path.join(__dirname, "binaries");
21
30
 
31
+ // THE list of platform packages: one row per package, `{ package, os, cpu }` in
32
+ // Node's own process.platform / process.arch vocabulary. This resolver and the
33
+ // release workflow follow it: scripts/release.js generates the published
34
+ // package.json's optionalDependencies from it and tells the workflow what to
35
+ // publish. Adding a non-Windows platform is one row here — and a one-time
36
+ // manual first publish of the new package name, which is why the list is short.
37
+ // A win32 row also needs PLATFORM_BINARY_FILE to gain the `.exe` suffix.
38
+ const PLATFORMS = require("./platforms.json");
39
+
22
40
  // Map Node's platform/arch onto GoReleaser's os/arch tokens.
23
41
  const OS_MAP = { linux: "linux", darwin: "darwin", win32: "windows" };
24
42
  const ARCH_MAP = { x64: "amd64", arm64: "arm64" };
@@ -28,12 +46,12 @@ const ARCH_MAP = { x64: "amd64", arm64: "arm64" };
28
46
  // re-add an entry here if a target is ever dropped from the release matrix.
29
47
  const UNSUPPORTED = new Set([]);
30
48
 
31
- function target() {
32
- const goos = OS_MAP[process.platform];
33
- const goarch = ARCH_MAP[process.arch];
49
+ function target(platform = process.platform, arch = process.arch) {
50
+ const goos = OS_MAP[platform];
51
+ const goarch = ARCH_MAP[arch];
34
52
  if (!goos || !goarch) {
35
53
  throw new Error(
36
- `Unsupported platform for @civitai/cli: ${process.platform}/${process.arch}. ` +
54
+ `Unsupported platform for @civitai/cli: ${platform}/${arch}. ` +
37
55
  `Supported: linux, darwin, windows on x64/arm64. ` +
38
56
  `Install the CLI another way: https://github.com/${REPO}#installation`
39
57
  );
@@ -52,6 +70,51 @@ function binaryPath() {
52
70
  return path.join(BINARIES_DIR, exe);
53
71
  }
54
72
 
73
+ // Where a platform package keeps its binary, relative to the package root.
74
+ const PLATFORM_BINARY_FILE = "bin/civitai";
75
+
76
+ // The binary shipped by this host's platform package, or null when there is no
77
+ // row for this host, npm did not install the package (--omit=optional, an
78
+ // older lockfile, a platform without a row), or the copy node resolves is a
79
+ // different version from this wrapper (a hoisted leftover) — the caller then
80
+ // downloads the right one. Never touches the network.
81
+ function platformBinary() {
82
+ const row = PLATFORMS.find((p) => p.os === process.platform && p.cpu === process.arch);
83
+ if (!row) return null;
84
+ try {
85
+ if (require(`${row.package}/package.json`).version !== require("../package.json").version) {
86
+ return null;
87
+ }
88
+ return require.resolve(`${row.package}/${PLATFORM_BINARY_FILE}`);
89
+ } catch (_) {
90
+ return null;
91
+ }
92
+ }
93
+
94
+ // Keep lib/binaries/civitai pointing at the platform package's binary.
95
+ // `civitai agent-setup --fix-path` writes that directory into shell profiles
96
+ // (it is where the downloaded binary lives), guarded by `[ -x …/civitai ]`;
97
+ // without this link an upgrade to a platform-package version would silently
98
+ // drop `civitai` from those users' PATH. Replaces whatever is there, so a
99
+ // binary downloaded by an older version cannot be left behind. Best effort: the
100
+ // platform binary works without it.
101
+ function linkPlatformBinary(shipped) {
102
+ const dest = binaryPath();
103
+ const want = path.relative(BINARIES_DIR, shipped);
104
+ try {
105
+ if (fs.readlinkSync(dest) === want) return;
106
+ } catch (_) {
107
+ // not a symlink, or not there
108
+ }
109
+ try {
110
+ fs.mkdirSync(BINARIES_DIR, { recursive: true });
111
+ fs.rmSync(dest, { force: true });
112
+ fs.symlinkSync(want, dest);
113
+ } catch (_) {
114
+ // read-only install tree, or a filesystem without symlinks
115
+ }
116
+ }
117
+
55
118
  function resolveVersion() {
56
119
  const { version } = require("../package.json");
57
120
  if (!version || version === PLACEHOLDER_VERSION) {
@@ -139,7 +202,16 @@ function findChecksum(checksumsText, asset) {
139
202
  }
140
203
 
141
204
  async function ensureBinary() {
205
+ const shipped = platformBinary();
206
+ if (shipped) {
207
+ linkPlatformBinary(shipped);
208
+ return shipped;
209
+ }
210
+
142
211
  const dest = binaryPath();
212
+ // A link left by linkPlatformBinary is not a download: the platform package
213
+ // it pointed at is gone or is now the wrong version.
214
+ if (fs.lstatSync(dest, { throwIfNoEntry: false })?.isSymbolicLink()) fs.rmSync(dest);
143
215
  if (fs.existsSync(dest)) return dest;
144
216
 
145
217
  const t = target();
@@ -172,12 +244,21 @@ async function ensureBinary() {
172
244
  return dest;
173
245
  }
174
246
 
175
- module.exports = { ensureBinary, binaryPath };
247
+ module.exports = {
248
+ ensureBinary,
249
+ binaryPath,
250
+ platformBinary,
251
+ // For scripts/release.js, which builds the platform packages at publish time.
252
+ PLATFORMS,
253
+ PLATFORM_BINARY_FILE,
254
+ target,
255
+ assetName,
256
+ };
176
257
 
177
258
  if (require.main === module) {
178
259
  ensureBinary()
179
260
  .then((p) => {
180
- console.log(`@civitai/cli: installed binary at ${p}`);
261
+ console.log(`@civitai/cli: using binary at ${p}`);
181
262
  })
182
263
  .catch((err) => {
183
264
  console.error(`@civitai/cli: failed to install binary.\n${err.message}`);
@@ -0,0 +1,3 @@
1
+ [
2
+ { "package": "@civitai/cli-linux-x64", "os": "linux", "cpu": "x64" }
3
+ ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@civitai/cli",
3
- "version": "0.1.119",
3
+ "version": "0.1.121",
4
4
  "description": "The Civitai CLI — author and ship Civitai App Blocks. Installs the prebuilt Go binary.",
5
5
  "bin": {
6
6
  "civitai": "bin/civitai.js"
@@ -43,5 +43,8 @@
43
43
  "cpu": [
44
44
  "x64",
45
45
  "arm64"
46
- ]
46
+ ],
47
+ "optionalDependencies": {
48
+ "@civitai/cli-linux-x64": "0.1.121"
49
+ }
47
50
  }