@hasna/hooks 0.10.3 → 0.10.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.
@@ -1,6 +1,6 @@
1
1
  import { spawn, spawnSync } from "node:child_process";
2
2
  import { existsSync } from "node:fs";
3
- import { mkdtemp, mkdir, readFile, realpath, rm, symlink, writeFile } from "node:fs/promises";
3
+ import { copyFile, mkdtemp, mkdir, readFile, realpath, rm, symlink, writeFile } from "node:fs/promises";
4
4
  import { dirname, join } from "node:path";
5
5
 
6
6
  type PackageJson = {
@@ -227,10 +227,19 @@ async function validatePackedNativeSafety(packageDir: string, smokeDir: string):
227
227
  const home = join(smokeDir, "native-safety-home");
228
228
  await mkdir(home, { mode: 0o700 });
229
229
  const settings = join(home, ".codex", "hooks.json");
230
+ // The supervisor retains its install-time runtime directory. A station's Bun
231
+ // directory may also contain Trash, so isolate the runtime for this negative
232
+ // control instead of inheriting the station's executable lookup.
233
+ const runtimeDir = join(smokeDir, "native-runtime");
234
+ await mkdir(runtimeDir, { mode: 0o700 });
235
+ const runtime = join(runtimeDir, "bun");
236
+ await copyFile(await realpath(process.execPath), runtime);
237
+ // An unrelated system trash utility remains subject to the package
238
+ // provenance check; only a verified @hasna/trash is a supported guard.
230
239
  const env: NodeJS.ProcessEnv = { ...process.env, HOME: home, HASNA_STATION: "no-such-station", HASNA_HOOKS_CODEX_SETTINGS_PATH: settings };
231
240
  for (const key of Object.keys(env)) if (/^(HASNA_HOOKS_|HOOKS_)/.test(key) && key !== "HASNA_HOOKS_CODEX_SETTINGS_PATH") delete env[key];
232
241
  const cli = join(packageDir, "bin/index.js");
233
- const installed = spawnSync(process.execPath, [cli, "safety", "install", "trash-guard", "--target", "codex"], { cwd: smokeDir, env, encoding: "utf8", timeout: 15_000 });
242
+ const installed = spawnSync(runtime, [cli, "safety", "install", "trash-guard", "--target", "codex"], { cwd: smokeDir, env, encoding: "utf8", timeout: 15_000 });
234
243
  if (installed.status !== 0 || !JSON.parse(installed.stdout).success) throw new Error("Packed native safety registration failed");
235
244
  if (existsSync(join(home, ".hasna", "hooks"))) throw new Error("Stateless safety registration created app state");
236
245
  const native = JSON.parse(await readFile(settings, "utf8"));
@@ -243,7 +252,7 @@ async function validatePackedNativeSafety(packageDir: string, smokeDir: string):
243
252
  if (refused.status !== 0 || JSON.parse(refused.stdout).hookSpecificOutput.permissionDecision !== "deny") throw new Error("Packed native missing-Trash refusal failed");
244
253
  const probe = join(smokeDir, "native-registration.ts");
245
254
  await writeFile(probe, `import { getRegisteredHooksForTarget } from "@hasna/hooks"; console.log(JSON.stringify(getRegisteredHooksForTarget("global", "codex")));`);
246
- const listed = spawnSync(process.execPath, [probe], { cwd: smokeDir, env, encoding: "utf8", timeout: 15_000 });
255
+ const listed = spawnSync(runtime, [probe], { cwd: smokeDir, env, encoding: "utf8", timeout: 15_000 });
247
256
  if (listed.status !== 0 || JSON.stringify(JSON.parse(listed.stdout)) !== '["trash-guard"]') throw new Error("Packed SDK cannot recognize the compiled CLI safety registration");
248
257
  const worker = join(packageDir, "bin/native-safety-entry.js");
249
258
  const bytes = await readFile(worker);