stackbite 0.5.90 → 0.5.91

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,6 +1,6 @@
1
1
  {
2
2
  "name": "stackbite",
3
- "version": "0.5.90",
3
+ "version": "0.5.91",
4
4
  "description": "Verified native Stackbite CLI bootstrapper",
5
5
  "license": "UNLICENSED",
6
6
  "engines": {
@@ -82,10 +82,10 @@ function boundedRunner(limit) {
82
82
  }
83
83
  return task => new Promise((resolve, reject) => { queue.push({ task, resolve, reject }); next(); });
84
84
  }
85
- // Bounded concurrency overlaps file reads; every pinned member is still hashed in full.
85
+ // Bounded concurrency overlaps selected file reads; every selected member is hashed in full.
86
86
  const HASH_CONCURRENCY = 8;
87
87
  // Walks the payload; every file or in-root link must resolve to a bounded regular file and pinned members must match.
88
- async function payloadFiles(root, expected, hashes) {
88
+ async function payloadFiles(root, expected, hashes, includePhone) {
89
89
  const actual = new Set(), run = boundedRunner(HASH_CONCURRENCY), checks = [];
90
90
  let total = 0, entries = 0;
91
91
  async function checkHash(relative, resolved) {
@@ -93,6 +93,9 @@ async function payloadFiles(root, expected, hashes) {
93
93
  }
94
94
  async function visit(directoryPath) {
95
95
  for (const name of await fs.readdir(directoryPath)) {
96
+ // Optional Phone is checked at activation. Do not traverse an unused tree,
97
+ // including a missing or redirected tree; selected runtime links cannot use it.
98
+ if (!includePhone && directoryPath === root && name === 'phone') continue;
96
99
  if (++entries > LIMITS.members * 2) fail('Cached release has too many entries');
97
100
  const target = path.join(directoryPath, name), relative = path.relative(root, target).split(path.sep).join('/');
98
101
  memberPath(relative);
@@ -101,6 +104,7 @@ async function payloadFiles(root, expected, hashes) {
101
104
  if (!entry.isFile() && !entry.isSymbolicLink()) fail('Release contains a special file');
102
105
  const resolved = await fs.realpath(target);
103
106
  if (!inside(root, resolved)) fail('Release link escapes the cache root');
107
+ if (!includePhone && path.relative(root, resolved).split(path.sep)[0] === 'phone') fail('Runtime link resolves into optional Phone payload');
104
108
  const resolvedInfo = await fs.lstat(resolved);
105
109
  if (!resolvedInfo.isFile() || resolvedInfo.size > LIMITS.member) fail('Release link does not resolve to a bounded regular file');
106
110
  total += resolvedInfo.size;
@@ -153,17 +157,18 @@ async function nativeExecutable(root, spec) {
153
157
  if (spec.platform !== 'win32' && process.platform !== 'win32' && !(image.mode & 0o111)) fail('Native release executable has no execute permission');
154
158
  return executable;
155
159
  }
156
- async function validatePayload(directory, spec) {
160
+ async function validatePayload(directory, spec, { includePhone = true } = {}) {
157
161
  const root = await payloadRoot(directory);
158
162
  const { hashes, metadata } = await pinnedDocuments(root, spec);
159
163
  const expected = expectedMembers(hashes);
160
- const actual = await payloadFiles(root, expected, hashes);
164
+ if (!includePhone) for (const name of expected) if (name.startsWith('phone/')) expected.delete(name);
165
+ const actual = await payloadFiles(root, expected, hashes, includePhone);
161
166
  await checkMemberSet(root, spec, hashes, expected, actual);
162
167
  await checkProductIdentity(root, spec, metadata);
163
168
  return nativeExecutable(root, spec);
164
169
  }
165
170
  async function ensureBinary(spec, { cache = cacheDirectory(), downloadImpl = download, extractImpl = extractArchive,
166
- checkOnly = false, reportCached = false, progress = () => {} } = {}) {
171
+ checkOnly = false, reportCached = false, includePhone = false, progress = () => {} } = {}) {
167
172
  cache = path.resolve(cache);
168
173
  if (checkOnly) {
169
174
  if (!await existingCacheDirectory(cache)) fail('Pinned runtime is not cached; run stackbite setup.');
@@ -173,7 +178,7 @@ async function ensureBinary(spec, { cache = cacheDirectory(), downloadImpl = dow
173
178
  const target = path.join(cache, `v1-${cacheKey}`);
174
179
  if (await exists(target)) {
175
180
  if (checkOnly || reportCached) progress('validate');
176
- const installed = { home: target, executable: await validatePayload(target, spec) };
181
+ const installed = { home: target, executable: await validatePayload(target, spec, { includePhone }) };
177
182
  if (checkOnly || reportCached) progress('ready');
178
183
  return installed;
179
184
  }
@@ -231,10 +236,12 @@ async function main(argv = process.argv.slice(2), options = {}) {
231
236
  const platform = options.platform || process.platform;
232
237
  const environment = options.environment || process.env;
233
238
  const spec = releaseSpec(manifest, platform, options.arch || process.arch, options);
234
- // Every launch still verifies the full pinned payload; timing only observes it.
239
+ // First install always verifies everything. Cached TUI/runtime starts defer only
240
+ // Phone; explicit phone/setup/removal commands retain the full pinned check.
235
241
  const installed = await timing.phase(environment, 'launcher.ensure', () => ensureBinary(spec, { ...options,
236
242
  cache: options.cache || cacheDirectory(environment, platform),
237
243
  checkOnly: removing || setup?.checkOnly || false, reportCached: Boolean(setup),
244
+ includePhone: removing || Boolean(setup) || argv[0] === 'phone',
238
245
  progress: options.progress || stageReporter(options.stderr || process.stderr) }));
239
246
  if (setup) return { code: 0, signal: null };
240
247
  timing.mark(environment, 'launcher.exec');
@@ -1,35 +1,35 @@
1
1
  {
2
2
  "schema": 1,
3
- "version": "0.5.90",
4
- "commit": "56d4ca6cf772afab8755bb24be9d0b5d7acb9820",
3
+ "version": "0.5.91",
4
+ "commit": "2d94b964c839d24b1968b4dbb725621d49e9b707",
5
5
  "repository": "Shinick-Han/stackbite",
6
6
  "platforms": {
7
7
  "win32-x64": {
8
- "asset": "stackbite-0.5.90-windows-x64-56d4ca6cf772.zip",
9
- "url": "https://github.com/Shinick-Han/stackbite/releases/download/v0.5.90/stackbite-0.5.90-windows-x64-56d4ca6cf772.zip",
10
- "sha256": "e9ba7356d2b4ad2fbcd60e5280b5e66a9d67fdad7b6c3390e151df593b5b5eac",
11
- "size": 94778285,
12
- "root": "stackbite-0.5.90-windows-x64-56d4ca6cf772",
13
- "manifestSha256": "611a5a174ab0188b1f14ceaf267c99f443fa81244c66b636e27ec252a9e49e99",
14
- "metadataSha256": "c382fc7a1defe257d6415ba3085d141a5b83b8dcf1189d09937df7fc2084bf54"
8
+ "asset": "stackbite-0.5.91-windows-x64-2d94b964c839.zip",
9
+ "url": "https://github.com/Shinick-Han/stackbite/releases/download/v0.5.91/stackbite-0.5.91-windows-x64-2d94b964c839.zip",
10
+ "sha256": "557726a30ece87ec0f7541a3f05794648ec3b5326ecc6e6a64e4cbfaa0b69331",
11
+ "size": 94836414,
12
+ "root": "stackbite-0.5.91-windows-x64-2d94b964c839",
13
+ "manifestSha256": "b2395ba730c0cc30ac500a6bee14f4b005658fd97a330841bcb769794927c393",
14
+ "metadataSha256": "bd05a77015cbca2c7e908c87f64aac79dacfb04d0eee13f703ed5e418e9bb922"
15
15
  },
16
16
  "linux-x64": {
17
- "asset": "stackbite-0.5.90-linux-x86_64-56d4ca6cf772.tar.gz",
18
- "url": "https://github.com/Shinick-Han/stackbite/releases/download/v0.5.90/stackbite-0.5.90-linux-x86_64-56d4ca6cf772.tar.gz",
19
- "sha256": "6243c30e23b037e1449db96cf819b7c38cbc0e2b38b2d2ac8ff1b9d9237a83d7",
20
- "size": 74714723,
21
- "root": "stackbite-0.5.90-linux-x86_64-56d4ca6cf772",
22
- "manifestSha256": "a02b4e350870584b16e6bbd544abf7eaa75b24a6314eadad84252ab1b9c0b424",
23
- "metadataSha256": "f238756ab3e80411e7260cf55b224ee64d78bb34ee8c624bb8fa6b8e31582b34"
17
+ "asset": "stackbite-0.5.91-linux-x86_64-2d94b964c839.tar.gz",
18
+ "url": "https://github.com/Shinick-Han/stackbite/releases/download/v0.5.91/stackbite-0.5.91-linux-x86_64-2d94b964c839.tar.gz",
19
+ "sha256": "72aa084f92dafaf83e414e6098438d531e7e77980fa1b61532f0e9c9a9069d98",
20
+ "size": 74778958,
21
+ "root": "stackbite-0.5.91-linux-x86_64-2d94b964c839",
22
+ "manifestSha256": "e70444ff32b016e9a7e2687f704b667445586b32a9e38d3fb1be138331dfb04f",
23
+ "metadataSha256": "46470951946de8ad3cb0447519d6f7259d8d2080a8808fe2b57e8e0267819fa5"
24
24
  },
25
25
  "darwin-arm64": {
26
- "asset": "stackbite-0.5.90-macos-arm64-56d4ca6cf772.tar.gz",
27
- "url": "https://github.com/Shinick-Han/stackbite/releases/download/v0.5.90/stackbite-0.5.90-macos-arm64-56d4ca6cf772.tar.gz",
28
- "sha256": "3f8b9b59cad56e0b1b6b6f0ab265ce73c5a3b351a3e42e3684b697c86926205a",
29
- "size": 35916960,
30
- "root": "stackbite-0.5.90-macos-arm64-56d4ca6cf772",
31
- "manifestSha256": "ce23b7ea6725e31914a13e516942272a68885ab09798729bb9539c1af3f2a9e2",
32
- "metadataSha256": "845a416ab9f82bc0edcff61c2f971d279f5bb05342e284c45978d9e96891ad23"
26
+ "asset": "stackbite-0.5.91-macos-arm64-2d94b964c839.tar.gz",
27
+ "url": "https://github.com/Shinick-Han/stackbite/releases/download/v0.5.91/stackbite-0.5.91-macos-arm64-2d94b964c839.tar.gz",
28
+ "sha256": "83c15788134abefe06f62f3a549d055d2a93df1eada88a3dbb30927412cde9bf",
29
+ "size": 29944040,
30
+ "root": "stackbite-0.5.91-macos-arm64-2d94b964c839",
31
+ "manifestSha256": "3a3ae1c2c6cc575b90a4b2e893e40f855c2b95591ab0bae0b1b5f513fe4201ab",
32
+ "metadataSha256": "82472bc3cd7124fd725bcd3ff2613b660a98a1bbccb191f62d4e5f08f7d2915e"
33
33
  }
34
34
  }
35
35
  }