@deleted-ai/deleted 0.1.341 → 0.1.345

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
@@ -1,6 +1,7 @@
1
1
  # @deleted-ai/deleted
2
2
 
3
- npm wrapper for the Deleted AI `deleted` CLI on **Linux arm64** (v0 support floor).
3
+ npm wrapper for the Deleted AI `deleted` CLI on **Linux arm64 and Linux x64**
4
+ (v0 support floor).
4
5
 
5
6
  A brokered tool call with **no Rust toolchain** — Node is the only prerequisite:
6
7
 
@@ -20,8 +21,8 @@ npx @deleted-ai/deleted init my-box
20
21
  with `deleted pack build` (Rust + `wasm-tools` 1.235.x) reproduces the shipped
21
22
  binaries byte for byte.
22
23
 
23
- On install (or first run), the package extracts the bundled linux-arm64 release
24
- binary (or downloads from GitHub Releases when authenticated). No kernel source
24
+ On install (or first run), the package extracts the bundled release binary for
25
+ your host — it ships one tarball per support-floor target and picks the match (or downloads from GitHub Releases when authenticated). No kernel source
25
26
  ships in this package.
26
27
 
27
28
  Author docs ship with the binary under `share/docs/` (for example
@@ -31,19 +32,21 @@ prints the local path — no private GitHub login required.
31
32
  ## Requirements
32
33
 
33
34
  - Node.js `^22.19 || >=24`
34
- - Linux arm64
35
+ - Linux arm64 or Linux x64
35
36
 
36
- Other platforms print a clear error and defer to the tarball install path
37
- (`share/docs/install-deleted.md` in a linux-arm64 release).
37
+ macOS and Windows are deferred: the install prints a clear error and stops
38
+ rather than half-working. Author docs for the tarball path ship at
39
+ `share/docs/install-deleted.md` inside any release.
38
40
 
39
41
  ## Monorepo / CI
40
42
 
41
43
  When building from source, point install at a local release tree:
42
44
 
43
45
  ```bash
44
- export DELETED_RELEASE_TARBALL="$PWD/target/deleted-release/deleted-linux-arm64-<sha>.tar.gz"
46
+ TARGET=linux-$(uname -m | sed 's/aarch64/arm64/;s/x86_64/x64/')
47
+ export DELETED_RELEASE_TARBALL="$PWD/target/deleted-release/deleted-$TARGET-<sha>.tar.gz"
45
48
  # or
46
- export DELETED_RELEASE_DIR="$PWD/target/deleted-release/deleted-linux-arm64"
49
+ export DELETED_RELEASE_DIR="$PWD/target/deleted-release/deleted-$TARGET"
47
50
  npm install ./packages/deleted-npm
48
51
  npx deleted web
49
52
  ```
Binary file
Binary file
package/lib/install.js CHANGED
@@ -4,7 +4,13 @@ import fs from 'node:fs';
4
4
  import os from 'node:os';
5
5
  import path from 'node:path';
6
6
  import { assertSupportedPlatform } from './platform.js';
7
- import { readManifest, releaseDownloadUrl, tarballFileName } from './manifest.js';
7
+ import {
8
+ manifestTarget,
9
+ readManifest,
10
+ releaseDownloadUrl,
11
+ tarballFileName,
12
+ tarballPrefix,
13
+ } from './manifest.js';
8
14
  import {
9
15
  cacheRoot,
10
16
  cacheMatchesManifest,
@@ -22,8 +28,7 @@ function copyTree(src, dest) {
22
28
  fs.cpSync(src, dest, { recursive: true });
23
29
  }
24
30
 
25
- function verifyTarballSha256(tarballPath, manifest) {
26
- const expected = manifest.tarballSha256;
31
+ function verifyTarballSha256(tarballPath, expected) {
27
32
  if (!expected || expected === ZERO_SHA256) {
28
33
  return;
29
34
  }
@@ -66,13 +71,13 @@ function downloadRelease(url, destFile) {
66
71
  );
67
72
  }
68
73
 
69
- function installFromTarball(tarballPath, manifest, destDir) {
70
- verifyTarballSha256(tarballPath, manifest);
74
+ function installFromTarball(tarballPath, expectedSha256, destDir) {
75
+ verifyTarballSha256(tarballPath, expectedSha256);
71
76
  extractTarball(tarballPath, destDir);
72
77
  fs.chmodSync(nativeBinaryPath(destDir), 0o755);
73
78
  }
74
79
 
75
- function resolveLocalTarball(manifest) {
80
+ function resolveLocalTarball(manifest, target) {
76
81
  if (process.env.DELETED_RELEASE_TARBALL) {
77
82
  const p = path.resolve(process.env.DELETED_RELEASE_TARBALL);
78
83
  if (!fs.existsSync(p)) {
@@ -80,7 +85,7 @@ function resolveLocalTarball(manifest) {
80
85
  }
81
86
  return p;
82
87
  }
83
- const bundled = path.join(packageRoot(), 'bundled', 'linux-arm64.tar.gz');
88
+ const bundled = path.join(packageRoot(), 'bundled', `${target}.tar.gz`);
84
89
  if (fs.existsSync(bundled)) {
85
90
  return bundled;
86
91
  }
@@ -90,7 +95,7 @@ function resolveLocalTarball(manifest) {
90
95
  '..',
91
96
  'target',
92
97
  'deleted-release',
93
- tarballFileName(manifest),
98
+ tarballFileName(manifest, target),
94
99
  );
95
100
  if (fs.existsSync(local)) {
96
101
  return local;
@@ -98,7 +103,7 @@ function resolveLocalTarball(manifest) {
98
103
  return null;
99
104
  }
100
105
 
101
- function resolveLocalStagingDir() {
106
+ function resolveLocalStagingDir(target) {
102
107
  if (process.env.DELETED_RELEASE_DIR) {
103
108
  const p = path.resolve(process.env.DELETED_RELEASE_DIR);
104
109
  if (!fs.existsSync(p)) {
@@ -112,7 +117,7 @@ function resolveLocalStagingDir() {
112
117
  '..',
113
118
  'target',
114
119
  'deleted-release',
115
- 'deleted-linux-arm64',
120
+ tarballPrefix(target),
116
121
  );
117
122
  if (fs.existsSync(path.join(local, 'bin', 'deleted'))) {
118
123
  return local;
@@ -120,29 +125,30 @@ function resolveLocalStagingDir() {
120
125
  return null;
121
126
  }
122
127
 
123
- function installFromRelease(manifest, destDir) {
124
- const staging = resolveLocalStagingDir();
128
+ function installFromRelease(manifest, target, destDir) {
129
+ const staging = resolveLocalStagingDir(target);
125
130
  if (staging) {
126
131
  stageFromDirectory(staging, destDir);
127
132
  return;
128
133
  }
129
134
 
130
- const localTarball = resolveLocalTarball(manifest);
135
+ const expectedSha256 = manifestTarget(manifest, target).tarballSha256;
136
+ const localTarball = resolveLocalTarball(manifest, target);
131
137
  if (localTarball) {
132
- installFromTarball(localTarball, manifest, destDir);
138
+ installFromTarball(localTarball, expectedSha256, destDir);
133
139
  return;
134
140
  }
135
141
 
136
- const url = releaseDownloadUrl(manifest);
137
- if (!manifest.tarballSha256 || manifest.tarballSha256 === ZERO_SHA256) {
142
+ const url = releaseDownloadUrl(manifest, target);
143
+ if (!expectedSha256 || expectedSha256 === ZERO_SHA256) {
138
144
  throw new Error(
139
- 'release-manifest.json missing tarballSha256; cannot download unverified binary',
145
+ `release-manifest.json missing tarballSha256 for ${target}; cannot download unverified binary`,
140
146
  );
141
147
  }
142
148
 
143
149
  const token = process.env.DELETED_GITHUB_TOKEN || process.env.GITHUB_TOKEN;
144
150
  const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'deleted-npm-dl-'));
145
- const tmpTarball = path.join(tmpDir, tarballFileName(manifest));
151
+ const tmpTarball = path.join(tmpDir, tarballFileName(manifest, target));
146
152
  try {
147
153
  if (token) {
148
154
  execFileSync(
@@ -164,13 +170,13 @@ function installFromRelease(manifest, destDir) {
164
170
  } else {
165
171
  downloadRelease(url, tmpTarball);
166
172
  }
167
- installFromTarball(tmpTarball, manifest, destDir);
173
+ installFromTarball(tmpTarball, expectedSha256, destDir);
168
174
  } catch (err) {
169
175
  const hint = [
170
- 'Could not download the Deleted AI linux-arm64 release binary.',
176
+ `Could not download the Deleted AI ${target} release binary.`,
171
177
  `URL: ${url}`,
172
178
  '',
173
- 'Published npm packages ship bundled/linux-arm64.tar.gz for anonymous install.',
179
+ `Published npm packages ship bundled/${target}.tar.gz for anonymous install.`,
174
180
  'For CI or monorepo dev, set DELETED_RELEASE_TARBALL or DELETED_RELEASE_DIR.',
175
181
  `Optional GitHub auth: DELETED_GITHUB_TOKEN (private release assets).`,
176
182
  '',
@@ -184,22 +190,22 @@ function installFromRelease(manifest, destDir) {
184
190
 
185
191
  /** Ensure native binary + share/ tree are cached. Returns cache directory. */
186
192
  export function ensureInstalled() {
187
- assertSupportedPlatform();
193
+ const target = assertSupportedPlatform();
188
194
  const manifest = readManifest();
189
195
  const destDir = cacheRoot(manifest.version);
190
- if (isInstalled(destDir) && cacheMatchesManifest(destDir, manifest)) {
196
+ if (isInstalled(destDir) && cacheMatchesManifest(destDir, manifest, target)) {
191
197
  return destDir;
192
198
  }
193
199
  if (fs.existsSync(destDir)) {
194
200
  fs.rmSync(destDir, { recursive: true, force: true });
195
201
  }
196
202
  fs.mkdirSync(path.dirname(destDir), { recursive: true });
197
- installFromRelease(manifest, destDir);
203
+ installFromRelease(manifest, target, destDir);
198
204
  if (!isInstalled(destDir)) {
199
205
  throw new Error(
200
206
  `install incomplete: expected ${nativeBinaryPath(destDir)} and starter harness`,
201
207
  );
202
208
  }
203
- writeInstallStamp(destDir, manifest);
209
+ writeInstallStamp(destDir, manifest, target);
204
210
  return destDir;
205
211
  }
package/lib/manifest.js CHANGED
@@ -2,7 +2,8 @@ import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { packageRoot } from './paths.js';
4
4
 
5
- /** @typedef {{ version: string; gitSha: string; repo: string; tarballPrefix: string; releaseTagPrefix: string }} ReleaseManifest */
5
+ /** @typedef {{ tarballSha256: string }} ReleaseTarget */
6
+ /** @typedef {{ version: string; gitSha: string; repo: string; releaseTagPrefix: string; targets: Record<string, ReleaseTarget> }} ReleaseManifest */
6
7
 
7
8
  /** @returns {ReleaseManifest} */
8
9
  export function readManifest() {
@@ -13,14 +14,35 @@ export function readManifest() {
13
14
  return JSON.parse(raw);
14
15
  }
15
16
 
16
- /** @param {ReleaseManifest} manifest */
17
- export function tarballFileName(manifest) {
18
- return `${manifest.tarballPrefix}-${manifest.gitSha}.tar.gz`;
17
+ /**
18
+ * @param {ReleaseManifest} manifest
19
+ * @param {string} target release target id (e.g. `linux-arm64`)
20
+ * @returns {ReleaseTarget}
21
+ */
22
+ export function manifestTarget(manifest, target) {
23
+ const entry = manifest.targets?.[target];
24
+ if (!entry) {
25
+ throw new Error(
26
+ `release-manifest.json has no entry for target ${target}; ` +
27
+ `known targets: ${Object.keys(manifest.targets ?? {}).join(', ') || '(none)'}`,
28
+ );
29
+ }
30
+ return entry;
19
31
  }
20
32
 
21
- /** @param {ReleaseManifest} manifest */
22
- export function releaseDownloadUrl(manifest) {
33
+ /** @param {string} target */
34
+ export function tarballPrefix(target) {
35
+ return `deleted-${target}`;
36
+ }
37
+
38
+ /** @param {ReleaseManifest} manifest @param {string} target */
39
+ export function tarballFileName(manifest, target) {
40
+ return `${tarballPrefix(target)}-${manifest.gitSha}.tar.gz`;
41
+ }
42
+
43
+ /** @param {ReleaseManifest} manifest @param {string} target */
44
+ export function releaseDownloadUrl(manifest, target) {
23
45
  const tag = `${manifest.releaseTagPrefix}${manifest.version}`;
24
- const file = tarballFileName(manifest);
46
+ const file = tarballFileName(manifest, target);
25
47
  return `https://github.com/${manifest.repo}/releases/download/${tag}/${file}`;
26
48
  }
package/lib/paths.js CHANGED
@@ -36,18 +36,25 @@ export function readInstallStamp(cacheDir) {
36
36
  }
37
37
  }
38
38
 
39
- /** @param {string} cacheDir @param {object} manifest */
40
- export function writeInstallStamp(cacheDir, manifest) {
39
+ /** @param {string} cacheDir @param {object} manifest @param {string} target */
40
+ export function writeInstallStamp(cacheDir, manifest, target) {
41
41
  const stamp = {
42
42
  version: manifest.version,
43
43
  gitSha: manifest.gitSha,
44
- tarballSha256: manifest.tarballSha256,
44
+ target,
45
+ tarballSha256: manifest.targets?.[target]?.tarballSha256,
45
46
  };
46
47
  fs.writeFileSync(installStampPath(cacheDir), `${JSON.stringify(stamp)}\n`);
47
48
  }
48
49
 
49
- /** @param {string} cacheDir @param {object} manifest */
50
- export function cacheMatchesManifest(cacheDir, manifest) {
50
+ /**
51
+ * The cache is keyed by version alone, so a home directory shared across
52
+ * architectures can hold a tree built for the other target — the stamp's
53
+ * `target` is what keeps that from being reused (PER-1046).
54
+ *
55
+ * @param {string} cacheDir @param {object} manifest @param {string} target
56
+ */
57
+ export function cacheMatchesManifest(cacheDir, manifest, target) {
51
58
  const stamp = readInstallStamp(cacheDir);
52
59
  if (!stamp) {
53
60
  return false;
@@ -55,7 +62,8 @@ export function cacheMatchesManifest(cacheDir, manifest) {
55
62
  return (
56
63
  stamp.version === manifest.version &&
57
64
  stamp.gitSha === manifest.gitSha &&
58
- stamp.tarballSha256 === manifest.tarballSha256
65
+ stamp.target === target &&
66
+ stamp.tarballSha256 === manifest.targets?.[target]?.tarballSha256
59
67
  );
60
68
  }
61
69
 
package/lib/platform.js CHANGED
@@ -1,26 +1,45 @@
1
- /** @returns {{ supported: boolean; platform: string; arch: string }} */
1
+ /**
2
+ * Release targets on the v0 support floor. Ids match the CI matrix cell names
3
+ * and the rows in docs/support-floor.md (PER-1046).
4
+ */
5
+ const RELEASE_TARGETS = {
6
+ 'linux:arm64': 'linux-arm64',
7
+ 'linux:x64': 'linux-x64',
8
+ };
9
+
10
+ /** @returns {string | null} release target id for this host, or null if unsupported */
11
+ export function releaseTarget() {
12
+ return RELEASE_TARGETS[`${process.platform}:${process.arch}`] ?? null;
13
+ }
14
+
15
+ /** @returns {{ supported: boolean; platform: string; arch: string; target: string | null }} */
2
16
  export function platformInfo() {
17
+ const target = releaseTarget();
3
18
  return {
4
- supported: process.platform === 'linux' && process.arch === 'arm64',
19
+ supported: target !== null,
5
20
  platform: process.platform,
6
21
  arch: process.arch,
22
+ target,
7
23
  };
8
24
  }
9
25
 
10
26
  export function unsupportedPlatformMessage() {
11
27
  const { platform, arch } = platformInfo();
12
28
  return [
13
- '@deleted-ai/deleted: Linux arm64 only (Deleted AI v0 support floor).',
29
+ '@deleted-ai/deleted: Linux arm64 and Linux x64 only (Deleted AI v0 support floor).',
14
30
  `Your platform: ${platform} ${arch}.`,
15
- 'macOS, Windows, and linux-x64 are deferred — this package will not run here.',
16
- 'On a Linux arm64 host, install with npx @deleted-ai/deleted or the',
17
- 'linux-arm64 release tarball; author docs are then at share/docs/.',
31
+ 'macOS and Windows are deferred — this package will not run here.',
32
+ 'On a supported Linux host, install with npx @deleted-ai/deleted or the',
33
+ 'matching release tarball; author docs are then at share/docs/.',
18
34
  ].join('\n');
19
35
  }
20
36
 
37
+ /** @returns {string} release target id, exiting the process if unsupported */
21
38
  export function assertSupportedPlatform() {
22
- if (!platformInfo().supported) {
39
+ const target = releaseTarget();
40
+ if (target === null) {
23
41
  console.error(unsupportedPlatformMessage());
24
42
  process.exit(1);
25
43
  }
44
+ return target;
26
45
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deleted-ai/deleted",
3
- "version": "0.1.341",
4
- "description": "Deleted AI CLI wrapper — downloads the linux-arm64 native binary on install",
3
+ "version": "0.1.345",
4
+ "description": "Deleted AI CLI wrapper — installs the native binary for this Linux host (arm64 or x64)",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
7
7
  "publishConfig": {
@@ -1,9 +1,15 @@
1
1
  {
2
- "_comment": "Placeholder in git; scripts/publish-deleted-npm.sh stamps version, gitSha, and tarballSha256 at publish. Install fails closed while tarballSha256 is the zero sentinel.",
3
- "version": "0.1.341",
4
- "gitSha": "5e48d46",
2
+ "_comment": "Placeholder in git; scripts/publish-deleted-npm.sh stamps version, gitSha, and a tarballSha256 per target at publish. Install fails closed while a target's tarballSha256 is the zero sentinel.",
3
+ "version": "0.1.345",
4
+ "gitSha": "538b5d8",
5
5
  "repo": "cdlconsultants/deleted-ai",
6
- "tarballPrefix": "deleted-linux-arm64",
7
6
  "releaseTagPrefix": "npm-v",
8
- "tarballSha256": "9f4f407a5dff07bcf96eb8e2c6e996eee6b07b3b0db357855c1d6dc680e1b7cc"
7
+ "targets": {
8
+ "linux-arm64": {
9
+ "tarballSha256": "08c52ff34bb47fa7a428826c428018eb77888e41c442387770b66cc06bca4423"
10
+ },
11
+ "linux-x64": {
12
+ "tarballSha256": "047517ccc1f9df1ae44af04a974d3441e44bcf15448517f008c227cb911b2f0c"
13
+ }
14
+ }
9
15
  }