@elpapi42/pi-fleet 0.1.0-beta.10 → 0.1.0-beta.13

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.
Files changed (43) hide show
  1. package/CHANGELOG.md +28 -1
  2. package/README.md +99 -167
  3. package/dist/cli-meta.json +313 -315
  4. package/dist/cli.mjs +2504 -1812
  5. package/dist/cli.mjs.map +4 -4
  6. package/dist/client/agent-target.d.ts +33 -0
  7. package/dist/client/contracts.d.ts +81 -0
  8. package/dist/client/fleet-client.d.ts +118 -0
  9. package/dist/client/index.d.ts +4 -0
  10. package/dist/client/sdk-connector.d.ts +7 -0
  11. package/dist/client/sdk-facade.d.ts +84 -0
  12. package/dist/client/sdk-transport.d.ts +24 -0
  13. package/dist/client/shared-client.d.ts +18 -0
  14. package/dist/client/socket-fleet-client.d.ts +21 -0
  15. package/dist/client-meta.json +5736 -0
  16. package/dist/client.mjs +4434 -0
  17. package/dist/client.mjs.map +7 -0
  18. package/dist/installer-meta.json +7 -7
  19. package/dist/installer.mjs +47 -13
  20. package/dist/installer.mjs.map +2 -2
  21. package/dist/journal-sqlite-worker-meta.json +149 -0
  22. package/dist/journal-sqlite-worker.mjs +1110 -0
  23. package/dist/journal-sqlite-worker.mjs.map +7 -0
  24. package/dist/pi/external-installation.d.ts +23 -0
  25. package/dist/platform/client/start-runtime.d.ts +25 -0
  26. package/dist/platform/install/runtime-release.d.ts +8 -0
  27. package/dist/platform/install/tree-integrity.d.ts +7 -0
  28. package/dist/platform/shared/paths.d.ts +8 -0
  29. package/dist/platform/shared/runtime-ownership.d.ts +14 -0
  30. package/dist/protocol/jsonl.d.ts +3 -0
  31. package/dist/protocol/pi-identity.d.ts +16 -0
  32. package/dist/protocol/semantic-segmentation.d.ts +22 -0
  33. package/dist/protocol/version.d.ts +2 -0
  34. package/dist/runtime/semantic-events.d.ts +43 -0
  35. package/dist/runtime-manifest.json +156 -31
  36. package/dist/runtime-meta.json +378 -53
  37. package/dist/runtime.mjs +3161 -581
  38. package/dist/runtime.mjs.map +4 -4
  39. package/dist/shared/result.d.ts +9 -0
  40. package/package.json +14 -1
  41. package/dist/sqlite-worker-meta.json +0 -84
  42. package/dist/sqlite-worker.mjs +0 -359
  43. package/dist/sqlite-worker.mjs.map +0 -7
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "inputs": {
3
3
  "src/pi/external-installation.ts": {
4
- "bytes": 9144,
4
+ "bytes": 9540,
5
5
  "imports": [
6
6
  {
7
7
  "path": "node:child_process",
@@ -48,7 +48,7 @@
48
48
  "format": "esm"
49
49
  },
50
50
  "src/platform/install/service-installer.ts": {
51
- "bytes": 6128,
51
+ "bytes": 6874,
52
52
  "imports": [
53
53
  {
54
54
  "path": "node:fs",
@@ -100,7 +100,7 @@
100
100
  "format": "esm"
101
101
  },
102
102
  "src/platform/install/runtime-release.ts": {
103
- "bytes": 15803,
103
+ "bytes": 17608,
104
104
  "imports": [
105
105
  {
106
106
  "path": "node:crypto",
@@ -193,7 +193,7 @@
193
193
  "imports": [],
194
194
  "exports": [],
195
195
  "inputs": {},
196
- "bytes": 64905
196
+ "bytes": 68926
197
197
  },
198
198
  "dist/installer.mjs": {
199
199
  "imports": [
@@ -327,13 +327,13 @@
327
327
  "bytesInOutput": 7521
328
328
  },
329
329
  "src/platform/install/service-installer.ts": {
330
- "bytesInOutput": 5163
330
+ "bytesInOutput": 5655
331
331
  },
332
332
  "src/platform/install/service-definition.ts": {
333
333
  "bytesInOutput": 2835
334
334
  },
335
335
  "src/platform/install/runtime-release.ts": {
336
- "bytesInOutput": 13701
336
+ "bytesInOutput": 14951
337
337
  },
338
338
  "src/platform/install/tree-integrity.ts": {
339
339
  "bytesInOutput": 2233
@@ -342,7 +342,7 @@
342
342
  "bytesInOutput": 404
343
343
  }
344
344
  },
345
- "bytes": 34253
345
+ "bytes": 35995
346
346
  }
347
347
  }
348
348
  }
@@ -329,9 +329,13 @@ async function installUserService(options) {
329
329
  const effectiveDefinition = await preserveInstalledStateRoot(path, options.definition, "linux");
330
330
  const definition = systemdUserUnit(effectiveDefinition);
331
331
  const needsRepair = await serviceDefinitionNeedsRepair(path, definition, effectiveDefinition);
332
- if (needsRepair && options.replaceExisting === false && await exists(path)) {
333
- throw new ServiceRepairDeferredError();
334
- }
332
+ const installed = await exists(path);
333
+ await preflightInstalledReplacement({
334
+ installed,
335
+ needsRepair,
336
+ replaceExisting: options.replaceExisting,
337
+ ownershipPreflight: options.ownershipPreflight
338
+ });
335
339
  if (needsRepair) {
336
340
  await atomicWrite(path, definition);
337
341
  await options.executor.run("systemctl", ["--user", "daemon-reload"]);
@@ -351,10 +355,14 @@ async function installUserService(options) {
351
355
  );
352
356
  const definition = launchdAgentPlist(effectiveDefinition);
353
357
  const needsRepair = await serviceDefinitionNeedsRepair(path, definition, effectiveDefinition);
354
- if (needsRepair && options.replaceExisting === false && await exists(path)) {
355
- throw new ServiceRepairDeferredError();
356
- }
357
- await atomicWrite(path, definition);
358
+ const installed = await exists(path);
359
+ await preflightInstalledReplacement({
360
+ installed,
361
+ needsRepair,
362
+ replaceExisting: options.replaceExisting,
363
+ ownershipPreflight: options.ownershipPreflight
364
+ });
365
+ if (needsRepair) await atomicWrite(path, definition);
358
366
  const domain = `gui/${options.uid ?? process.getuid?.() ?? 0}`;
359
367
  await options.executor.run("launchctl", ["bootout", domain, path]).catch(() => void 0);
360
368
  await options.executor.run("launchctl", ["bootstrap", domain, path]);
@@ -395,6 +403,13 @@ async function serviceDefinitionNeedsRepair(path, expectedContents, definition)
395
403
  return true;
396
404
  }
397
405
  }
406
+ async function preflightInstalledReplacement(options) {
407
+ if (!options.installed || !options.needsRepair) return;
408
+ if (options.replaceExisting !== true || options.ownershipPreflight === void 0) {
409
+ throw new ServiceRepairDeferredError();
410
+ }
411
+ await options.ownershipPreflight();
412
+ }
398
413
  async function preserveInstalledStateRoot(path, definition, platform) {
399
414
  if (definition.stateRoot !== void 0) return definition;
400
415
  const current = await readFile(path, "utf8").catch((error) => {
@@ -494,7 +509,12 @@ var requiredRuntimeArtifacts = /* @__PURE__ */ new Set([
494
509
  "bin/pifleet-runtime.mjs",
495
510
  "dist/cli.mjs",
496
511
  "dist/runtime.mjs",
497
- "dist/sqlite-worker.mjs"
512
+ "dist/journal-sqlite-worker.mjs",
513
+ "dist/client.mjs",
514
+ "dist/client-meta.json",
515
+ "dist/client/index.d.ts",
516
+ "dist/client/sdk-facade.d.ts",
517
+ "dist/client/contracts.d.ts"
498
518
  ]);
499
519
  var dependencyTreePath = "node_modules";
500
520
  async function materializeRuntime(options) {
@@ -649,11 +669,11 @@ async function validateRuntimeManifest(candidate, root) {
649
669
  if (!isRecord(candidate) || candidate.schemaVersion !== 4) {
650
670
  throw new Error("Runtime manifest has an unsupported schema version");
651
671
  }
652
- if (!isRecord(candidate.package) || typeof candidate.package.name !== "string" || typeof candidate.package.version !== "string" || !isRecord(candidate.piRuntime) || candidate.piRuntime.mode !== "external") {
672
+ if (!isRecord(candidate.package) || typeof candidate.package.name !== "string" || typeof candidate.package.version !== "string" || !isRecord(candidate.piRuntime) || candidate.piRuntime.mode !== "external" || !isRuntimeContract(candidate.runtime)) {
653
673
  throw new Error("Runtime manifest has an invalid package identity");
654
674
  }
655
- const packageMetadata = await readPackageMetadata(root);
656
- if (candidate.package.name !== packageMetadata.name || candidate.package.version !== packageMetadata.version) {
675
+ const packageMetadata = await readPackageMetadata(root, true);
676
+ if (candidate.package.name !== packageMetadata.name || candidate.package.version !== packageMetadata.version || packageMetadata.runtime === void 0 || !sameRuntimeContract(candidate.runtime, packageMetadata.runtime) || packageMetadata.clientExport === void 0) {
657
677
  throw new Error("Runtime manifest package identity does not match package.json");
658
678
  }
659
679
  if (!Array.isArray(candidate.files) || !Array.isArray(candidate.dependencies)) {
@@ -707,19 +727,27 @@ async function validateRuntimeManifest(candidate, root) {
707
727
  }
708
728
  }
709
729
  }
710
- async function readPackageMetadata(root) {
730
+ async function readPackageMetadata(root, requireRuntimeContract = false) {
711
731
  let candidate;
712
732
  try {
713
733
  candidate = JSON.parse(await readFile3(join4(root, "package.json"), "utf8"));
714
734
  } catch {
715
735
  throw new Error("Runtime package.json is not valid JSON");
716
736
  }
717
- if (!isRecord(candidate) || typeof candidate.name !== "string" || typeof candidate.version !== "string" || candidate.dependencies !== void 0 && !isRecord(candidate.dependencies) || isRecord(candidate.dependencies) && Object.values(candidate.dependencies).some((version) => typeof version !== "string")) {
737
+ if (!isRecord(candidate) || typeof candidate.name !== "string" || typeof candidate.version !== "string" || requireRuntimeContract && !isRuntimeContract(candidate.pifleet) || candidate.dependencies !== void 0 && !isRecord(candidate.dependencies) || isRecord(candidate.dependencies) && Object.values(candidate.dependencies).some((version) => typeof version !== "string")) {
718
738
  throw new Error("Runtime package.json has invalid package metadata");
719
739
  }
740
+ const clientExport = isRecord(candidate.exports) ? candidate.exports["./client"] : void 0;
720
741
  return {
721
742
  name: candidate.name,
722
743
  version: candidate.version,
744
+ ...isRuntimeContract(candidate.pifleet) ? { runtime: candidate.pifleet } : {},
745
+ ...isRecord(clientExport) && clientExport.types === "./dist/client/index.d.ts" && clientExport.import === "./dist/client.mjs" ? {
746
+ clientExport: {
747
+ types: "./dist/client/index.d.ts",
748
+ import: "./dist/client.mjs"
749
+ }
750
+ } : {},
723
751
  dependencies: isRecord(candidate.dependencies) ? candidate.dependencies : {}
724
752
  };
725
753
  }
@@ -743,6 +771,12 @@ function resolveInside(root, path) {
743
771
  function isRecord(value) {
744
772
  return typeof value === "object" && value !== null;
745
773
  }
774
+ function isRuntimeContract(value) {
775
+ return isRecord(value) && value.protocolVersion === 3 && value.journalSchemaVersion === 3 && value.clientExport === "./client";
776
+ }
777
+ function sameRuntimeContract(left, right) {
778
+ return left.protocolVersion === right.protocolVersion && left.journalSchemaVersion === right.journalSchemaVersion && left.clientExport === right.clientExport;
779
+ }
746
780
  function isManifestPath(value) {
747
781
  return typeof value === "string" && value.length > 0 && !value.includes("\\") && !value.startsWith("/") && posix.normalize(value) === value && value.split("/").every((part) => part.length > 0 && part !== "." && part !== "..");
748
782
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/entry/installer.ts", "../src/pi/external-installation.ts", "../src/platform/install/service-installer.ts", "../src/platform/install/service-definition.ts", "../src/platform/install/runtime-release.ts", "../src/platform/install/tree-integrity.ts", "../src/platform/shared/paths.ts"],
4
- "sourcesContent": ["import { execFile } from \"node:child_process\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { promisify } from \"node:util\";\n\nimport { resolveExternalPiInstallation } from \"../pi/external-installation.js\";\nimport {\n installUserService,\n uninstallUserService,\n type CommandExecutor,\n} from \"../platform/install/service-installer.js\";\nimport { materializeRuntime } from \"../platform/install/runtime-release.js\";\nimport { resolveApplicationRoot } from \"../platform/shared/paths.js\";\n\nconst executor: CommandExecutor = {\n async run(command, args) {\n await promisify(execFile)(command, [...args]);\n },\n};\n\nexport async function installRuntimeService(): Promise<string> {\n return installMaterializedService(process.env.PIFLEET_STATE_ROOT);\n}\n\nexport async function repairRuntimeService(): Promise<string> {\n return installMaterializedService(process.env.PIFLEET_STATE_ROOT);\n}\n\nasync function installMaterializedService(stateRoot: string | undefined): Promise<string> {\n const sourceRoot = dirname(dirname(fileURLToPath(import.meta.url)));\n const release = await materializeRuntime({\n sourceRoot,\n applicationRoot: resolveApplicationRoot(),\n });\n const pi = await resolveExternalPiInstallation({ env: process.env });\n return installUserService({\n platform: process.platform,\n definition: {\n nodePath: process.execPath,\n runtimePath: join(release, \"bin\", \"pifleet-runtime.mjs\"),\n piExecutablePath: pi.selectedPath,\n piNodePath: pi.nodePath,\n ...(stateRoot === undefined ? {} : { stateRoot }),\n },\n executor,\n replaceExisting: false,\n });\n}\n\nexport async function uninstallRuntimeService(): Promise<void> {\n await uninstallUserService({ platform: process.platform, executor });\n}\n\nasync function main(): Promise<void> {\n const command = process.argv[2];\n if (command === \"install\") {\n process.stdout.write(`${await installRuntimeService()}\\n`);\n return;\n }\n if (command === \"repair\") {\n process.stdout.write(`${await repairRuntimeService()}\\n`);\n return;\n }\n if (command === \"uninstall\") {\n await uninstallRuntimeService();\n return;\n }\n throw new Error(\"Usage: node dist/installer.mjs <install|repair|uninstall>\");\n}\n\nif (process.argv[1] !== undefined && import.meta.url === pathToFileURL(process.argv[1]).href) {\n await main();\n}\n", "import { spawn } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport { constants } from \"node:fs\";\nimport { createReadStream } from \"node:fs\";\nimport { access, realpath, stat } from \"node:fs/promises\";\nimport { delimiter, dirname, isAbsolute, join } from \"node:path\";\n\nconst VERSION_TIMEOUT_MS = 3_000;\nconst MAX_VERSION_OUTPUT_BYTES = 4 * 1024;\n\nexport type ExternalPiResolutionErrorCode =\n | \"invalid_arguments\"\n | \"pi_not_found\"\n | \"pi_not_executable\"\n | \"pi_version_unavailable\"\n | \"pi_installation_changed\";\n\nexport class ExternalPiResolutionError extends Error {\n constructor(\n readonly code: ExternalPiResolutionErrorCode,\n message: string,\n ) {\n super(message);\n this.name = \"ExternalPiResolutionError\";\n }\n}\n\nexport interface PiInstallation {\n readonly selectedPath: string;\n readonly realPath: string;\n readonly version: string;\n readonly nodePath: string;\n readonly fingerprint: string;\n}\n\nexport interface ExternalPiResolverOptions {\n readonly env?: NodeJS.ProcessEnv;\n readonly nodePath?: string;\n readonly versionCommand?: (executable: string) => Promise<string>;\n readonly versionTimeoutMs?: number;\n readonly maxVersionOutputBytes?: number;\n}\n\nexport async function resolveExternalPiInstallation(\n options: ExternalPiResolverOptions = {},\n): Promise<PiInstallation> {\n const env = options.env ?? process.env;\n const selectedPath = await resolveSelectedPath(env);\n const nodePath = options.nodePath ?? (await resolveNodePath(env));\n await inspectNode(nodePath);\n\n const executionEnv = externalPiExecutionEnvironment(env, selectedPath, nodePath);\n for (let attempt = 0; attempt < 2; attempt += 1) {\n const observation = await observeInstallation(selectedPath, executionEnv, options);\n if (observation !== null) {\n return {\n selectedPath,\n nodePath,\n ...observation,\n };\n }\n }\n\n throw new ExternalPiResolutionError(\n \"pi_installation_changed\",\n \"Pi changed while its installation was being observed.\",\n );\n}\n\nexport function externalPiExecutionEnvironment(\n env: NodeJS.ProcessEnv,\n selectedPath: string,\n nodePath: string,\n): NodeJS.ProcessEnv {\n return {\n ...env,\n PATH: [dirname(nodePath), dirname(selectedPath), env.PATH]\n .filter((value): value is string => value !== undefined && value.length > 0)\n .join(delimiter),\n };\n}\n\nasync function observeInstallation(\n selectedPath: string,\n env: NodeJS.ProcessEnv,\n options: ExternalPiResolverOptions,\n): Promise<Omit<PiInstallation, \"selectedPath\" | \"nodePath\"> | null> {\n const beforeRealPath = await inspectExecutable(selectedPath, \"Pi\");\n const beforeHash = await hashFile(beforeRealPath);\n const versionOutput = await (\n options.versionCommand ??\n ((executable: string) =>\n readVersion(executable, env, options.versionTimeoutMs, options.maxVersionOutputBytes))\n )(selectedPath);\n const version = parseVersion(versionOutput);\n const afterRealPath = await inspectExecutable(selectedPath, \"Pi\");\n const afterHash = await hashFile(afterRealPath);\n\n if (beforeRealPath !== afterRealPath || beforeHash !== afterHash) return null;\n\n return {\n realPath: afterRealPath,\n version,\n fingerprint: createHash(\"sha256\")\n .update(JSON.stringify([selectedPath, afterRealPath, version, afterHash]))\n .digest(\"hex\"),\n };\n}\n\nasync function resolveSelectedPath(env: NodeJS.ProcessEnv): Promise<string> {\n const explicit = env.PIFLEET_PI_EXECUTABLE;\n if (explicit !== undefined) {\n if (!isAbsolute(explicit)) {\n throw new ExternalPiResolutionError(\n \"invalid_arguments\",\n \"PIFLEET_PI_EXECUTABLE must be an absolute path.\",\n );\n }\n return explicit;\n }\n return resolvePathExecutable(env, \"pi\", \"Pi\", \"pi_not_found\");\n}\n\nasync function resolveNodePath(env: NodeJS.ProcessEnv): Promise<string> {\n return resolvePathExecutable(env, \"node\", \"Node\", \"pi_not_executable\");\n}\n\nasync function resolvePathExecutable(\n env: NodeJS.ProcessEnv,\n name: string,\n label: \"Pi\" | \"Node\",\n missingCode: \"pi_not_found\" | \"pi_not_executable\",\n): Promise<string> {\n const path = env.PATH;\n if (path === undefined || path.length === 0) {\n throw new ExternalPiResolutionError(missingCode, `${label} was not found on PATH.`);\n }\n for (const directory of path.split(delimiter)) {\n if (!isAbsolute(directory)) {\n throw new ExternalPiResolutionError(\n \"invalid_arguments\",\n `PATH entries used to select ${label} must be absolute paths.`,\n );\n }\n const candidate = join(directory, name);\n try {\n await inspectExecutable(candidate, label);\n return candidate;\n } catch (error: unknown) {\n if (\n !(error instanceof ExternalPiResolutionError) ||\n (error.code !== \"pi_not_executable\" && error.code !== \"pi_not_found\")\n ) {\n throw error;\n }\n }\n }\n throw new ExternalPiResolutionError(missingCode, `${label} was not found on PATH.`);\n}\n\nasync function inspectExecutable(path: string, label: \"Pi\" | \"Node\"): Promise<string> {\n try {\n const target = await realpath(path);\n const metadata = await stat(target);\n if (!metadata.isFile()) {\n throw new ExternalPiResolutionError(\"pi_not_executable\", `${label} is not a file: ${path}`);\n }\n await access(path, constants.X_OK);\n return target;\n } catch (error: unknown) {\n if (error instanceof ExternalPiResolutionError) throw error;\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n throw new ExternalPiResolutionError(\"pi_not_found\", `${label} was not found: ${path}`);\n }\n throw new ExternalPiResolutionError(\"pi_not_executable\", `${label} is not executable: ${path}`);\n }\n}\n\nasync function inspectNode(nodePath: string): Promise<void> {\n if (!isAbsolute(nodePath)) {\n throw new ExternalPiResolutionError(\"invalid_arguments\", \"Node must be an absolute path.\");\n }\n try {\n await inspectExecutable(nodePath, \"Node\");\n } catch {\n throw new ExternalPiResolutionError(\"pi_not_executable\", `Node is not executable: ${nodePath}`);\n }\n}\n\nasync function hashFile(path: string): Promise<string> {\n const hash = createHash(\"sha256\");\n await new Promise<void>((resolveHash, rejectHash) => {\n const stream = createReadStream(path);\n stream.on(\"data\", (chunk: string | Buffer) => hash.update(chunk));\n stream.once(\"error\", rejectHash);\n stream.once(\"end\", resolveHash);\n });\n return hash.digest(\"hex\");\n}\n\nasync function readVersion(\n executable: string,\n env: NodeJS.ProcessEnv,\n timeoutMs = VERSION_TIMEOUT_MS,\n maxOutputBytes = MAX_VERSION_OUTPUT_BYTES,\n): Promise<string> {\n const child = spawn(executable, [\"--version\"], {\n detached: process.platform !== \"win32\",\n env,\n shell: false,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n const chunks: Buffer[] = [];\n let outputBytes = 0;\n let terminalError: ExternalPiResolutionError | null = null;\n let terminated = false;\n\n const terminate = () => {\n if (terminated) return;\n terminated = true;\n if (process.platform !== \"win32\" && child.pid !== undefined) {\n try {\n process.kill(-child.pid, \"SIGKILL\");\n return;\n } catch {\n // The group may have already exited; kill the direct child as a fallback.\n }\n }\n child.kill(\"SIGKILL\");\n };\n\n child.stdout.on(\"data\", (chunk: Buffer) => {\n if (terminalError !== null) return;\n outputBytes += chunk.byteLength;\n if (outputBytes > maxOutputBytes) {\n terminalError = new ExternalPiResolutionError(\n \"pi_version_unavailable\",\n \"Pi version output exceeded its limit.\",\n );\n terminate();\n return;\n }\n chunks.push(chunk);\n });\n child.stderr.resume();\n\n return new Promise((resolveVersion, rejectVersion) => {\n const timer = setTimeout(() => {\n terminalError = new ExternalPiResolutionError(\n \"pi_version_unavailable\",\n \"Pi version command timed out.\",\n );\n terminate();\n }, timeoutMs);\n child.once(\"error\", () => {\n terminalError ??= new ExternalPiResolutionError(\n \"pi_version_unavailable\",\n \"Pi version command failed.\",\n );\n });\n child.once(\"close\", (code) => {\n clearTimeout(timer);\n if (terminalError !== null) {\n rejectVersion(terminalError);\n return;\n }\n if (code !== 0) {\n rejectVersion(\n new ExternalPiResolutionError(\"pi_version_unavailable\", \"Pi version command failed.\"),\n );\n return;\n }\n try {\n resolveVersion(new TextDecoder(\"utf-8\", { fatal: true }).decode(Buffer.concat(chunks)));\n } catch {\n rejectVersion(\n new ExternalPiResolutionError(\n \"pi_version_unavailable\",\n \"Pi version command returned invalid UTF-8.\",\n ),\n );\n }\n });\n });\n}\n\nfunction parseVersion(output: string): string {\n const match = /^(?:pi\\s+)?(\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?)\\s*$/i.exec(output);\n if (match?.[1] === undefined) {\n throw new ExternalPiResolutionError(\n \"pi_version_unavailable\",\n \"Pi version command returned an invalid version.\",\n );\n }\n return match[1];\n}\n", "import { constants } from \"node:fs\";\nimport { access, chmod, mkdir, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport {\n launchdAgentPlist,\n systemdUserUnit,\n type ServiceDefinitionOptions,\n} from \"./service-definition.js\";\n\nexport interface CommandExecutor {\n run(command: string, args: readonly string[]): Promise<void>;\n}\n\nexport class ServiceRepairDeferredError extends Error {\n readonly code = \"runtime_upgrade_deferred\";\n\n constructor() {\n super(\n \"The installed pi-fleet service differs from the requested runtime or Pi selection. Automatic replacement is deferred because runtime quiescence cannot be proven; finish active work, stop the existing service explicitly, then install or repair again.\",\n );\n this.name = \"ServiceRepairDeferredError\";\n }\n}\n\nexport async function installUserService(options: {\n readonly platform: NodeJS.Platform;\n readonly definition: ServiceDefinitionOptions;\n readonly executor: CommandExecutor;\n readonly home?: string;\n readonly uid?: number;\n readonly replaceExisting?: boolean;\n}): Promise<string> {\n const home = options.home ?? homedir();\n if (options.platform === \"linux\") {\n const path = join(home, \".config\", \"systemd\", \"user\", \"pi-fleet.service\");\n const effectiveDefinition = await preserveInstalledStateRoot(path, options.definition, \"linux\");\n const definition = systemdUserUnit(effectiveDefinition);\n const needsRepair = await serviceDefinitionNeedsRepair(path, definition, effectiveDefinition);\n if (needsRepair && options.replaceExisting === false && (await exists(path))) {\n throw new ServiceRepairDeferredError();\n }\n if (needsRepair) {\n await atomicWrite(path, definition);\n await options.executor.run(\"systemctl\", [\"--user\", \"daemon-reload\"]);\n }\n await options.executor.run(\"systemctl\", [\"--user\", \"enable\", \"--now\", \"pi-fleet.service\"]);\n if (needsRepair) {\n await options.executor.run(\"systemctl\", [\"--user\", \"restart\", \"pi-fleet.service\"]);\n }\n return path;\n }\n if (options.platform === \"darwin\") {\n const path = join(home, \"Library\", \"LaunchAgents\", \"works.elpapi.pifleet.plist\");\n const effectiveDefinition = await preserveInstalledStateRoot(\n path,\n options.definition,\n \"darwin\",\n );\n const definition = launchdAgentPlist(effectiveDefinition);\n const needsRepair = await serviceDefinitionNeedsRepair(path, definition, effectiveDefinition);\n if (needsRepair && options.replaceExisting === false && (await exists(path))) {\n throw new ServiceRepairDeferredError();\n }\n await atomicWrite(path, definition);\n const domain = `gui/${options.uid ?? process.getuid?.() ?? 0}`;\n await options.executor.run(\"launchctl\", [\"bootout\", domain, path]).catch(() => undefined);\n await options.executor.run(\"launchctl\", [\"bootstrap\", domain, path]);\n await options.executor.run(\"launchctl\", [\"kickstart\", `${domain}/works.elpapi.pifleet`]);\n return path;\n }\n throw new Error(`Native pi-fleet supervision is unsupported on ${options.platform}`);\n}\n\nexport async function uninstallUserService(options: {\n readonly platform: NodeJS.Platform;\n readonly executor: CommandExecutor;\n readonly home?: string;\n readonly uid?: number;\n}): Promise<void> {\n const home = options.home ?? homedir();\n if (options.platform === \"linux\") {\n const path = join(home, \".config\", \"systemd\", \"user\", \"pi-fleet.service\");\n await options.executor.run(\"systemctl\", [\"--user\", \"disable\", \"--now\", \"pi-fleet.service\"]);\n await rm(path, { force: true });\n await options.executor.run(\"systemctl\", [\"--user\", \"daemon-reload\"]);\n return;\n }\n if (options.platform === \"darwin\") {\n const path = join(home, \"Library\", \"LaunchAgents\", \"works.elpapi.pifleet.plist\");\n const domain = `gui/${options.uid ?? process.getuid?.() ?? 0}`;\n await options.executor.run(\"launchctl\", [\"bootout\", domain, path]).catch(() => undefined);\n await rm(path, { force: true });\n return;\n }\n throw new Error(`Native pi-fleet supervision is unsupported on ${options.platform}`);\n}\n\nexport async function serviceDefinitionNeedsRepair(\n path: string,\n expectedContents: string,\n definition: ServiceDefinitionOptions,\n): Promise<boolean> {\n const current = await readFile(path, \"utf8\").catch((error: NodeJS.ErrnoException) => {\n if (error.code === \"ENOENT\") return null;\n throw error;\n });\n if (current !== expectedContents) return true;\n try {\n await access(definition.nodePath, constants.X_OK);\n await access(definition.runtimePath, constants.R_OK);\n return false;\n } catch {\n return true;\n }\n}\n\nasync function preserveInstalledStateRoot(\n path: string,\n definition: ServiceDefinitionOptions,\n platform: \"linux\" | \"darwin\",\n): Promise<ServiceDefinitionOptions> {\n if (definition.stateRoot !== undefined) return definition;\n const current = await readFile(path, \"utf8\").catch((error: NodeJS.ErrnoException) => {\n if (error.code === \"ENOENT\") return null;\n throw error;\n });\n if (current === null) return definition;\n const encoded =\n platform === \"linux\"\n ? /^Environment=PIFLEET_STATE_ROOT=(.+)$/m.exec(current)?.[1]\n : /<key>PIFLEET_STATE_ROOT<\\/key><string>([^<]+)<\\/string>/.exec(current)?.[1];\n if (encoded === undefined) return definition;\n const stateRoot =\n platform === \"linux\"\n ? encoded\n : encoded\n .replaceAll(\"&apos;\", \"'\")\n .replaceAll(\"&quot;\", '\"')\n .replaceAll(\"&gt;\", \">\")\n .replaceAll(\"&lt;\", \"<\")\n .replaceAll(\"&amp;\", \"&\");\n return { ...definition, stateRoot };\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function atomicWrite(path: string, contents: string): Promise<void> {\n await mkdir(dirname(path), { recursive: true, mode: 0o700 });\n const temporary = `${path}.tmp-${process.pid}`;\n await writeFile(temporary, contents, { mode: 0o600 });\n await chmod(temporary, 0o600);\n await rename(temporary, path);\n}\n", "import { isAbsolute } from \"node:path\";\n\nexport interface ServiceDefinitionOptions {\n readonly nodePath: string;\n readonly runtimePath: string;\n readonly piExecutablePath?: string;\n readonly piNodePath?: string;\n readonly stateRoot?: string;\n}\n\nexport function systemdUserUnit(options: ServiceDefinitionOptions): string {\n validate(options);\n const environment = environmentEntries(options)\n .map(([key, value]) => {\n const assignment = `${key}=${value}`;\n return `Environment=${/^[A-Za-z0-9_./:@=-]+$/.test(assignment) ? assignment : systemdQuote(assignment)}\\n`;\n })\n .join(\"\");\n return `[Unit]\nDescription=pi-fleet user runtime\nAfter=default.target\n\n[Service]\nType=simple\nExecStart=${systemdArgument(options.nodePath)} ${systemdArgument(options.runtimePath)}\n${environment}Restart=on-failure\nRestartSec=1\nTimeoutStopSec=10\nUMask=0077\nKillMode=control-group\n\n[Install]\nWantedBy=default.target\n`;\n}\n\nexport function launchdAgentPlist(options: ServiceDefinitionOptions): string {\n validate(options);\n const entries = environmentEntries(options);\n const environment =\n entries.length === 0\n ? \"\"\n : ` <key>EnvironmentVariables</key>\n <dict>${entries\n .map(([key, value]) => `<key>${xmlEscape(key)}</key><string>${xmlEscape(value)}</string>`)\n .join(\"\")}</dict>\n`;\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key><string>works.elpapi.pifleet</string>\n <key>ProgramArguments</key>\n <array>\n <string>${xmlEscape(options.nodePath)}</string>\n <string>${xmlEscape(options.runtimePath)}</string>\n </array>\n${environment} <key>RunAtLoad</key><true/>\n <key>KeepAlive</key><dict><key>SuccessfulExit</key><false/></dict>\n <key>ProcessType</key><string>Background</string>\n</dict>\n</plist>\n`;\n}\n\nfunction environmentEntries(options: ServiceDefinitionOptions): Array<readonly [string, string]> {\n return [\n ...(options.stateRoot === undefined\n ? []\n : [[\"PIFLEET_STATE_ROOT\", options.stateRoot] as const]),\n ...(options.piExecutablePath === undefined\n ? []\n : [[\"PIFLEET_PI_EXECUTABLE\", options.piExecutablePath] as const]),\n ...(options.piNodePath === undefined ? [] : [[\"PIFLEET_PI_NODE\", options.piNodePath] as const]),\n ];\n}\n\nfunction validate(options: ServiceDefinitionOptions): void {\n const paths = [\n options.nodePath,\n options.runtimePath,\n options.piExecutablePath,\n options.piNodePath,\n ].filter((value): value is string => value !== undefined);\n if (paths.some((path) => !isAbsolute(path))) {\n throw new Error(\"Service executables must use absolute paths\");\n }\n if (paths.some((path) => /[\\0\\n\\r]/.test(path))) {\n throw new Error(\"Service paths cannot contain control characters\");\n }\n}\n\nfunction systemdArgument(value: string): string {\n return /^[A-Za-z0-9_./:@-]+$/.test(value) ? value : systemdQuote(value);\n}\n\nfunction systemdQuote(value: string): string {\n if (/[\\0\\n\\r]/.test(value)) throw new Error(\"Unsafe systemd value\");\n return `\"${value.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll('\"', '\\\\\"')}\"`;\n}\n\nfunction xmlEscape(value: string): string {\n return value\n .replaceAll(\"&\", \"&amp;\")\n .replaceAll(\"<\", \"&lt;\")\n .replaceAll(\">\", \"&gt;\")\n .replaceAll('\"', \"&quot;\")\n .replaceAll(\"'\", \"&apos;\");\n}\n", "import { createHash, randomUUID } from \"node:crypto\";\nimport { chmod, cp, lstat, mkdir, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport { join, posix, resolve, sep } from \"node:path\";\n\nimport { hashDirectoryTree, type TreeIntegrity } from \"./tree-integrity.js\";\n\ninterface RuntimeManifestFile {\n readonly path: string;\n readonly bytes: number;\n readonly sha256: string;\n}\n\ninterface RuntimeDependency {\n readonly path: string;\n readonly name: string;\n readonly version: string;\n}\n\ninterface RuntimeClosure {\n readonly sourceManifestSha256: string;\n readonly tree: TreeIntegrity;\n}\n\ninterface RuntimeManifest {\n readonly schemaVersion: 4;\n readonly package: { readonly name: string; readonly version: string };\n readonly piRuntime: { readonly mode: \"external\" };\n readonly files: readonly RuntimeManifestFile[];\n readonly dependencies: readonly RuntimeDependency[];\n readonly closure?: RuntimeClosure;\n}\n\ninterface PackageMetadata {\n readonly name: string;\n readonly version: string;\n readonly dependencies: Readonly<Record<string, string>>;\n}\n\nconst requiredRuntimeArtifacts = new Set([\n \"package.json\",\n \"bin/pifleet.mjs\",\n \"bin/pifleet-runtime.mjs\",\n \"dist/cli.mjs\",\n \"dist/runtime.mjs\",\n \"dist/sqlite-worker.mjs\",\n]);\nconst dependencyTreePath = \"node_modules\";\n\nexport async function materializeRuntime(options: {\n readonly sourceRoot: string;\n readonly applicationRoot: string;\n readonly hooks?: {\n readonly afterDependencyCopy?: () => Promise<void>;\n };\n}): Promise<string> {\n const sourceRoot = resolve(options.sourceRoot);\n const manifestBytes = await readFile(join(sourceRoot, \"dist\", \"runtime-manifest.json\"));\n const sourceManifest = await parseRuntimeManifest(manifestBytes, sourceRoot);\n if (sourceManifest.closure !== undefined) {\n await verifyRuntime(sourceRoot);\n return sourceRoot;\n }\n await verifyRuntimeFiles(sourceRoot, sourceManifest);\n await verifyDependencyIdentities(sourceRoot, sourceManifest.dependencies);\n\n const sourceTreeRoot = resolveInside(sourceRoot, dependencyTreePath);\n const sourceTreeBefore = await hashDirectoryTree(sourceTreeRoot, dependencyTreePath);\n const sourceManifestSha256 = createHash(\"sha256\").update(manifestBytes).digest(\"hex\");\n const materializedManifest: RuntimeManifest = {\n ...sourceManifest,\n closure: { sourceManifestSha256, tree: sourceTreeBefore },\n };\n const materializedManifestBytes = serializeManifest(materializedManifest);\n const closureHash = createHash(\"sha256\")\n .update(sourceManifestSha256)\n .update(\"\\0\")\n .update(JSON.stringify(sourceTreeBefore))\n .digest(\"hex\")\n .slice(0, 16);\n\n const applicationRoot = resolve(options.applicationRoot);\n await ensurePrivateDirectory(applicationRoot);\n const releasesRoot = join(applicationRoot, \"releases\");\n await ensurePrivateDirectory(releasesRoot);\n const destination = join(releasesRoot, `${sourceManifest.package.version}-${closureHash}`);\n\n if (await pathExists(destination)) {\n await verifyExpectedRuntime(destination, materializedManifest, materializedManifestBytes);\n return destination;\n }\n\n const staging = join(releasesRoot, `.staging-${randomUUID()}`);\n await mkdir(staging, { mode: 0o700 });\n try {\n await cp(join(sourceRoot, \"dist\"), join(staging, \"dist\"), {\n recursive: true,\n dereference: true,\n });\n await cp(join(sourceRoot, \"bin\"), join(staging, \"bin\"), {\n recursive: true,\n dereference: true,\n });\n await cp(join(sourceRoot, \"package.json\"), join(staging, \"package.json\"));\n await cp(sourceTreeRoot, join(staging, dependencyTreePath), {\n recursive: true,\n dereference: true,\n });\n await options.hooks?.afterDependencyCopy?.();\n\n const stagedTree = await hashDirectoryTree(\n join(staging, dependencyTreePath),\n dependencyTreePath,\n );\n assertSameTree(sourceTreeBefore, stagedTree, \"copied dependency closure\");\n const sourceTreeAfter = await hashDirectoryTree(sourceTreeRoot, dependencyTreePath);\n assertSameTree(sourceTreeBefore, sourceTreeAfter, \"source dependency closure\");\n\n await writeFile(join(staging, \"dist\", \"runtime-manifest.json\"), materializedManifestBytes);\n await verifyExpectedRuntime(staging, materializedManifest, materializedManifestBytes);\n await chmod(staging, 0o700);\n try {\n await rename(staging, destination);\n } catch (error: unknown) {\n if (!isDestinationRace(error) || !(await pathExists(destination))) throw error;\n await verifyExpectedRuntime(destination, materializedManifest, materializedManifestBytes);\n }\n return destination;\n } finally {\n await rm(staging, { recursive: true, force: true });\n }\n}\n\nexport async function verifyRuntime(root: string): Promise<void> {\n const resolvedRoot = resolve(root);\n const manifestBytes = await readFile(join(resolvedRoot, \"dist\", \"runtime-manifest.json\"));\n const manifest = await parseRuntimeManifest(manifestBytes, resolvedRoot);\n if (manifest.closure === undefined) {\n throw new Error(\"Runtime release manifest is missing its materialized closure\");\n }\n await verifyRuntimeFiles(resolvedRoot, manifest);\n await verifyDependencyIdentities(resolvedRoot, manifest.dependencies);\n const actualTree = await hashDirectoryTree(\n resolveInside(resolvedRoot, dependencyTreePath),\n dependencyTreePath,\n );\n assertSameTree(manifest.closure.tree, actualTree, \"materialized dependency closure\");\n}\n\nasync function verifyExpectedRuntime(\n root: string,\n expected: RuntimeManifest,\n expectedBytes: Buffer,\n): Promise<void> {\n const manifestPath = join(root, \"dist\", \"runtime-manifest.json\");\n const actualBytes = await readFile(manifestPath);\n if (!actualBytes.equals(expectedBytes)) {\n throw new Error(\"Materialized runtime manifest does not match the expected closure\");\n }\n const actual = await parseRuntimeManifest(actualBytes, root);\n if (actual.closure === undefined || expected.closure === undefined) {\n throw new Error(\"Materialized runtime manifest is missing its closure\");\n }\n await verifyRuntimeFiles(root, actual);\n await verifyDependencyIdentities(root, actual.dependencies);\n const actualTree = await hashDirectoryTree(\n resolveInside(root, dependencyTreePath),\n dependencyTreePath,\n );\n assertSameTree(expected.closure.tree, actualTree, \"materialized dependency closure\");\n}\n\nasync function verifyRuntimeFiles(root: string, manifest: RuntimeManifest): Promise<void> {\n for (const file of manifest.files) {\n const path = resolveInside(root, file.path);\n const info = await lstat(path);\n if (info.isSymbolicLink()) {\n throw new Error(`Runtime artifact ${file.path} must not be a symbolic link`);\n }\n if (!info.isFile() || info.size !== file.bytes) {\n throw new Error(`Runtime artifact ${file.path} has changed`);\n }\n const hash = createHash(\"sha256\")\n .update(await readFile(path))\n .digest(\"hex\");\n if (hash !== file.sha256) {\n throw new Error(`Runtime artifact ${file.path} failed verification`);\n }\n }\n}\n\nasync function verifyDependencyIdentities(\n root: string,\n dependencies: readonly RuntimeDependency[],\n): Promise<void> {\n const nodeModules = resolveInside(root, dependencyTreePath);\n const modulesInfo = await lstat(nodeModules);\n if (!modulesInfo.isDirectory() || modulesInfo.isSymbolicLink()) {\n throw new Error(\"Runtime dependency closure must be a regular directory\");\n }\n for (const dependency of dependencies) {\n const packageRoot = resolveInside(root, dependency.path);\n const packageInfo = await lstat(packageRoot);\n if (!packageInfo.isDirectory() || packageInfo.isSymbolicLink()) {\n throw new Error(`Runtime dependency ${dependency.name} must be a regular directory`);\n }\n const packageJsonPath = join(packageRoot, \"package.json\");\n const packageJsonInfo = await lstat(packageJsonPath);\n if (!packageJsonInfo.isFile() || packageJsonInfo.isSymbolicLink()) {\n throw new Error(`Runtime dependency ${dependency.name} has an unsafe package.json`);\n }\n const identity = await readPackageMetadata(packageRoot);\n if (identity.name !== dependency.name || identity.version !== dependency.version) {\n throw new Error(`Runtime dependency ${dependency.name} has an unexpected identity`);\n }\n }\n}\n\nasync function parseRuntimeManifest(bytes: Buffer, root: string): Promise<RuntimeManifest> {\n let candidate: unknown;\n try {\n candidate = JSON.parse(bytes.toString(\"utf8\"));\n } catch {\n throw new Error(\"Runtime manifest is not valid JSON\");\n }\n await validateRuntimeManifest(candidate, root);\n return candidate as RuntimeManifest;\n}\n\nasync function validateRuntimeManifest(candidate: unknown, root: string): Promise<void> {\n if (!isRecord(candidate) || candidate.schemaVersion !== 4) {\n throw new Error(\"Runtime manifest has an unsupported schema version\");\n }\n if (\n !isRecord(candidate.package) ||\n typeof candidate.package.name !== \"string\" ||\n typeof candidate.package.version !== \"string\" ||\n !isRecord(candidate.piRuntime) ||\n candidate.piRuntime.mode !== \"external\"\n ) {\n throw new Error(\"Runtime manifest has an invalid package identity\");\n }\n const packageMetadata = await readPackageMetadata(root);\n if (\n candidate.package.name !== packageMetadata.name ||\n candidate.package.version !== packageMetadata.version\n ) {\n throw new Error(\"Runtime manifest package identity does not match package.json\");\n }\n if (!Array.isArray(candidate.files) || !Array.isArray(candidate.dependencies)) {\n throw new Error(\"Runtime manifest has invalid artifact lists\");\n }\n\n const filePaths = new Set<string>();\n for (const file of candidate.files) {\n if (\n !isRecord(file) ||\n !isManifestPath(file.path) ||\n !isValidSize(file.bytes) ||\n !isSha256(file.sha256)\n ) {\n throw new Error(\"Runtime manifest contains an invalid artifact\");\n }\n if (filePaths.has(file.path)) {\n throw new Error(`Runtime manifest has duplicate path ${file.path}`);\n }\n filePaths.add(file.path);\n }\n for (const required of requiredRuntimeArtifacts) {\n if (!filePaths.has(required)) {\n throw new Error(`Runtime manifest is missing required artifact ${required}`);\n }\n }\n\n const dependencyPaths = new Set<string>();\n const dependencyNames = new Set<string>();\n for (const dependency of candidate.dependencies) {\n if (\n !isRecord(dependency) ||\n !isManifestPath(dependency.path) ||\n typeof dependency.name !== \"string\" ||\n dependency.name.length === 0 ||\n typeof dependency.version !== \"string\" ||\n dependency.version.length === 0 ||\n dependency.path !== `node_modules/${dependency.name}`\n ) {\n throw new Error(\"Runtime manifest contains an invalid dependency declaration\");\n }\n if (dependencyPaths.has(dependency.path) || dependencyNames.has(dependency.name)) {\n throw new Error(`Runtime manifest has duplicate dependency ${dependency.name}`);\n }\n dependencyPaths.add(dependency.path);\n dependencyNames.add(dependency.name);\n }\n const expectedDependencies = packageMetadata.dependencies;\n if (\n dependencyNames.size !== Object.keys(expectedDependencies).length ||\n [...dependencyNames].some(\n (name) =>\n expectedDependencies[name] !==\n (candidate.dependencies as Array<Record<string, unknown>>).find(\n (dependency) => dependency.name === name,\n )?.version,\n )\n ) {\n throw new Error(\"Runtime manifest dependencies do not match package.json\");\n }\n\n for (const filePath of filePaths) {\n for (const dependencyPath of dependencyPaths) {\n if (\n filePath === dependencyPath ||\n filePath.startsWith(`${dependencyPath}/`) ||\n dependencyPath.startsWith(`${filePath}/`)\n ) {\n throw new Error(`Runtime manifest has overlapping paths ${filePath} and ${dependencyPath}`);\n }\n }\n }\n\n if (candidate.closure !== undefined) {\n if (\n !isRecord(candidate.closure) ||\n !isSha256(candidate.closure.sourceManifestSha256) ||\n !isTreeIntegrity(candidate.closure.tree) ||\n candidate.closure.tree.path !== dependencyTreePath\n ) {\n throw new Error(\"Runtime manifest contains an invalid materialized closure\");\n }\n }\n}\n\nasync function readPackageMetadata(root: string): Promise<PackageMetadata> {\n let candidate: unknown;\n try {\n candidate = JSON.parse(await readFile(join(root, \"package.json\"), \"utf8\"));\n } catch {\n throw new Error(\"Runtime package.json is not valid JSON\");\n }\n if (\n !isRecord(candidate) ||\n typeof candidate.name !== \"string\" ||\n typeof candidate.version !== \"string\" ||\n (candidate.dependencies !== undefined && !isRecord(candidate.dependencies)) ||\n (isRecord(candidate.dependencies) &&\n Object.values(candidate.dependencies).some((version) => typeof version !== \"string\"))\n ) {\n throw new Error(\"Runtime package.json has invalid package metadata\");\n }\n return {\n name: candidate.name,\n version: candidate.version,\n dependencies: isRecord(candidate.dependencies)\n ? (candidate.dependencies as Record<string, string>)\n : {},\n };\n}\n\nfunction serializeManifest(manifest: RuntimeManifest): Buffer {\n return Buffer.from(`${JSON.stringify(manifest, null, 2)}\\n`);\n}\n\nfunction assertSameTree(expected: TreeIntegrity, actual: TreeIntegrity, label: string): void {\n if (\n expected.path !== actual.path ||\n expected.files !== actual.files ||\n expected.bytes !== actual.bytes ||\n expected.sha256 !== actual.sha256\n ) {\n throw new Error(`Runtime ${label} changed during materialization`);\n }\n}\n\nfunction resolveInside(root: string, path: string): string {\n if (!isManifestPath(path)) throw new Error(`Runtime manifest contains an unsafe path ${path}`);\n const resolved = resolve(root, path);\n if (!resolved.startsWith(`${root}${sep}`)) {\n throw new Error(`Runtime manifest contains an unsafe path ${path}`);\n }\n return resolved;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isManifestPath(value: unknown): value is string {\n return (\n typeof value === \"string\" &&\n value.length > 0 &&\n !value.includes(\"\\\\\") &&\n !value.startsWith(\"/\") &&\n posix.normalize(value) === value &&\n value.split(\"/\").every((part) => part.length > 0 && part !== \".\" && part !== \"..\")\n );\n}\n\nfunction isValidSize(value: unknown): value is number {\n return typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0;\n}\n\nfunction isSha256(value: unknown): value is string {\n return typeof value === \"string\" && /^[a-f0-9]{64}$/.test(value);\n}\n\nfunction isTreeIntegrity(value: unknown): value is TreeIntegrity {\n return (\n isRecord(value) &&\n isManifestPath(value.path) &&\n isValidSize(value.files) &&\n isValidSize(value.bytes) &&\n isSha256(value.sha256)\n );\n}\n\nfunction isDestinationRace(error: unknown): boolean {\n const code = (error as NodeJS.ErrnoException).code;\n return code === \"EEXIST\" || code === \"ENOTEMPTY\";\n}\n\nasync function ensurePrivateDirectory(path: string): Promise<void> {\n await mkdir(path, { recursive: true, mode: 0o700 });\n const info = await lstat(path);\n if (!info.isDirectory() || info.isSymbolicLink()) {\n throw new Error(`Refusing unsafe runtime release path ${path}`);\n }\n if (typeof process.getuid === \"function\" && info.uid !== process.getuid()) {\n throw new Error(`Runtime release path ${path} is not owned by the current user`);\n }\n await chmod(path, 0o700);\n}\n\nasync function pathExists(path: string): Promise<boolean> {\n try {\n await lstat(path);\n return true;\n } catch (error: unknown) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return false;\n throw error;\n }\n}\n", "import { createHash } from \"node:crypto\";\nimport { lstat, readFile, readdir, realpath, stat } from \"node:fs/promises\";\nimport { join, relative, resolve, sep } from \"node:path\";\n\nexport interface TreeIntegrity {\n readonly path: string;\n readonly files: number;\n readonly bytes: number;\n readonly sha256: string;\n}\n\nexport async function hashDirectoryTree(\n root: string,\n manifestPath: string,\n): Promise<TreeIntegrity> {\n const resolvedRoot = resolve(root);\n const entries = await collectFiles(resolvedRoot, resolvedRoot);\n const hash = createHash(\"sha256\");\n let bytes = 0;\n for (const entry of entries) {\n const contents = await readFile(entry.absolutePath);\n bytes += contents.length;\n hash.update(entry.relativePath);\n hash.update(\"\\0\");\n hash.update(String(contents.length));\n hash.update(\"\\0\");\n hash.update(contents);\n hash.update(\"\\0\");\n }\n return {\n path: manifestPath,\n files: entries.length,\n bytes,\n sha256: hash.digest(\"hex\"),\n };\n}\n\nasync function collectFiles(\n root: string,\n directory: string,\n): Promise<Array<{ readonly absolutePath: string; readonly relativePath: string }>> {\n const output: Array<{ absolutePath: string; relativePath: string }> = [];\n for (const name of (await readdir(directory)).sort()) {\n const absolutePath = join(directory, name);\n const linkInfo = await lstat(absolutePath);\n const info = linkInfo.isSymbolicLink() ? await stat(absolutePath) : linkInfo;\n if (info.isDirectory()) {\n if (linkInfo.isSymbolicLink()) {\n throw new Error(`Runtime dependency tree contains a directory symlink: ${absolutePath}`);\n }\n output.push(...(await collectFiles(root, absolutePath)));\n continue;\n }\n if (!info.isFile()) {\n throw new Error(`Runtime dependency tree contains an unsupported entry: ${absolutePath}`);\n }\n if (linkInfo.isSymbolicLink()) {\n const target = await realpath(absolutePath);\n if (target !== root && !target.startsWith(`${root}${sep}`)) {\n throw new Error(\n `Runtime dependency tree contains an external file symlink: ${absolutePath}`,\n );\n }\n }\n const relativePath = relative(root, absolutePath).split(sep).join(\"/\");\n if (relativePath.length === 0 || relativePath.startsWith(\"../\")) {\n throw new Error(`Runtime dependency path escapes its root: ${absolutePath}`);\n }\n output.push({ absolutePath, relativePath });\n }\n return output.sort((left, right) => left.relativePath.localeCompare(right.relativePath));\n}\n", "import { homedir, tmpdir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\n\nexport interface FleetPaths {\n readonly runtimeRoot: string;\n readonly stateRoot: string;\n readonly socketPath: string;\n readonly databasePath: string;\n}\n\nexport function resolveApplicationRoot(env: NodeJS.ProcessEnv = process.env): string {\n return (\n env.PIFLEET_APPLICATION_ROOT ??\n (process.platform === \"darwin\"\n ? join(homedir(), \"Library\", \"Application Support\", \"pi-fleet\", \"runtime\")\n : join(env.XDG_DATA_HOME ?? join(homedir(), \".local\", \"share\"), \"pi-fleet\"))\n );\n}\n\nexport function resolveFleetPaths(env: NodeJS.ProcessEnv = process.env): FleetPaths {\n const explicitRoot = env.PIFLEET_STATE_ROOT;\n if (explicitRoot !== undefined) {\n const root = resolve(explicitRoot);\n return {\n runtimeRoot: root,\n stateRoot: root,\n socketPath: join(root, \"control.sock\"),\n databasePath: join(root, \"fleet.sqlite\"),\n };\n }\n\n const runtimeRoot = join(\n env.XDG_RUNTIME_DIR ?? tmpdir(),\n `pifleet-${process.getuid?.() ?? \"user\"}`,\n );\n const stateRoot =\n process.platform === \"darwin\"\n ? join(homedir(), \"Library\", \"Application Support\", \"pi-fleet\")\n : join(env.XDG_STATE_HOME ?? join(homedir(), \".local\", \"state\"), \"pi-fleet\");\n return {\n runtimeRoot,\n stateRoot,\n socketPath: join(runtimeRoot, \"control.sock\"),\n databasePath: join(stateRoot, \"fleet.sqlite\"),\n };\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { execFile } from \"node:child_process\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { promisify } from \"node:util\";\n\nimport { resolveExternalPiInstallation } from \"../pi/external-installation.js\";\nimport {\n installUserService,\n uninstallUserService,\n type CommandExecutor,\n} from \"../platform/install/service-installer.js\";\nimport { materializeRuntime } from \"../platform/install/runtime-release.js\";\nimport { resolveApplicationRoot } from \"../platform/shared/paths.js\";\n\nconst executor: CommandExecutor = {\n async run(command, args) {\n await promisify(execFile)(command, [...args]);\n },\n};\n\nexport async function installRuntimeService(): Promise<string> {\n return installMaterializedService(process.env.PIFLEET_STATE_ROOT);\n}\n\nexport async function repairRuntimeService(): Promise<string> {\n return installMaterializedService(process.env.PIFLEET_STATE_ROOT);\n}\n\nasync function installMaterializedService(stateRoot: string | undefined): Promise<string> {\n const sourceRoot = dirname(dirname(fileURLToPath(import.meta.url)));\n const release = await materializeRuntime({\n sourceRoot,\n applicationRoot: resolveApplicationRoot(),\n });\n const pi = await resolveExternalPiInstallation({ env: process.env });\n return installUserService({\n platform: process.platform,\n definition: {\n nodePath: process.execPath,\n runtimePath: join(release, \"bin\", \"pifleet-runtime.mjs\"),\n piExecutablePath: pi.selectedPath,\n piNodePath: pi.nodePath,\n ...(stateRoot === undefined ? {} : { stateRoot }),\n },\n executor,\n replaceExisting: false,\n });\n}\n\nexport async function uninstallRuntimeService(): Promise<void> {\n await uninstallUserService({ platform: process.platform, executor });\n}\n\nasync function main(): Promise<void> {\n const command = process.argv[2];\n if (command === \"install\") {\n process.stdout.write(`${await installRuntimeService()}\\n`);\n return;\n }\n if (command === \"repair\") {\n process.stdout.write(`${await repairRuntimeService()}\\n`);\n return;\n }\n if (command === \"uninstall\") {\n await uninstallRuntimeService();\n return;\n }\n throw new Error(\"Usage: node dist/installer.mjs <install|repair|uninstall>\");\n}\n\nif (process.argv[1] !== undefined && import.meta.url === pathToFileURL(process.argv[1]).href) {\n await main();\n}\n", "import { spawn } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport { constants } from \"node:fs\";\nimport { createReadStream } from \"node:fs\";\nimport { access, realpath, stat } from \"node:fs/promises\";\nimport { delimiter, dirname, isAbsolute, join } from \"node:path\";\n\nimport type { PiRuntimeIdentity } from \"../protocol/pi-identity.js\";\n\nconst VERSION_TIMEOUT_MS = 3_000;\nconst MAX_VERSION_OUTPUT_BYTES = 4 * 1024;\n\nexport type ExternalPiResolutionErrorCode =\n | \"invalid_arguments\"\n | \"pi_not_found\"\n | \"pi_not_executable\"\n | \"pi_version_unavailable\"\n | \"pi_installation_changed\";\n\nexport class ExternalPiResolutionError extends Error {\n constructor(\n readonly code: ExternalPiResolutionErrorCode,\n message: string,\n ) {\n super(message);\n this.name = \"ExternalPiResolutionError\";\n }\n}\n\nexport interface PiInstallation {\n readonly selectedPath: string;\n readonly realPath: string;\n readonly version: string;\n readonly nodePath: string;\n readonly fingerprint: string;\n}\n\nexport function installationIdentity(installation: PiInstallation): PiRuntimeIdentity {\n return {\n mode: \"external\",\n selectedPath: installation.selectedPath,\n nodePath: installation.nodePath,\n realPath: installation.realPath,\n version: installation.version,\n fingerprint: installation.fingerprint,\n };\n}\n\nexport interface ExternalPiResolverOptions {\n readonly env?: NodeJS.ProcessEnv;\n readonly nodePath?: string;\n readonly versionCommand?: (executable: string) => Promise<string>;\n readonly versionTimeoutMs?: number;\n readonly maxVersionOutputBytes?: number;\n}\n\nexport async function resolveExternalPiInstallation(\n options: ExternalPiResolverOptions = {},\n): Promise<PiInstallation> {\n const env = options.env ?? process.env;\n const selectedPath = await resolveSelectedPath(env);\n const nodePath = options.nodePath ?? (await resolveNodePath(env));\n await inspectNode(nodePath);\n\n const executionEnv = externalPiExecutionEnvironment(env, selectedPath, nodePath);\n for (let attempt = 0; attempt < 2; attempt += 1) {\n const observation = await observeInstallation(selectedPath, executionEnv, options);\n if (observation !== null) {\n return {\n selectedPath,\n nodePath,\n ...observation,\n };\n }\n }\n\n throw new ExternalPiResolutionError(\n \"pi_installation_changed\",\n \"Pi changed while its installation was being observed.\",\n );\n}\n\nexport function externalPiExecutionEnvironment(\n env: NodeJS.ProcessEnv,\n selectedPath: string,\n nodePath: string,\n): NodeJS.ProcessEnv {\n return {\n ...env,\n PATH: [dirname(nodePath), dirname(selectedPath), env.PATH]\n .filter((value): value is string => value !== undefined && value.length > 0)\n .join(delimiter),\n };\n}\n\nasync function observeInstallation(\n selectedPath: string,\n env: NodeJS.ProcessEnv,\n options: ExternalPiResolverOptions,\n): Promise<Omit<PiInstallation, \"selectedPath\" | \"nodePath\"> | null> {\n const beforeRealPath = await inspectExecutable(selectedPath, \"Pi\");\n const beforeHash = await hashFile(beforeRealPath);\n const versionOutput = await (\n options.versionCommand ??\n ((executable: string) =>\n readVersion(executable, env, options.versionTimeoutMs, options.maxVersionOutputBytes))\n )(selectedPath);\n const version = parseVersion(versionOutput);\n const afterRealPath = await inspectExecutable(selectedPath, \"Pi\");\n const afterHash = await hashFile(afterRealPath);\n\n if (beforeRealPath !== afterRealPath || beforeHash !== afterHash) return null;\n\n return {\n realPath: afterRealPath,\n version,\n fingerprint: createHash(\"sha256\")\n .update(JSON.stringify([selectedPath, afterRealPath, version, afterHash]))\n .digest(\"hex\"),\n };\n}\n\nasync function resolveSelectedPath(env: NodeJS.ProcessEnv): Promise<string> {\n const explicit = env.PIFLEET_PI_EXECUTABLE;\n if (explicit !== undefined) {\n if (!isAbsolute(explicit)) {\n throw new ExternalPiResolutionError(\n \"invalid_arguments\",\n \"PIFLEET_PI_EXECUTABLE must be an absolute path.\",\n );\n }\n return explicit;\n }\n return resolvePathExecutable(env, \"pi\", \"Pi\", \"pi_not_found\");\n}\n\nasync function resolveNodePath(env: NodeJS.ProcessEnv): Promise<string> {\n return resolvePathExecutable(env, \"node\", \"Node\", \"pi_not_executable\");\n}\n\nasync function resolvePathExecutable(\n env: NodeJS.ProcessEnv,\n name: string,\n label: \"Pi\" | \"Node\",\n missingCode: \"pi_not_found\" | \"pi_not_executable\",\n): Promise<string> {\n const path = env.PATH;\n if (path === undefined || path.length === 0) {\n throw new ExternalPiResolutionError(missingCode, `${label} was not found on PATH.`);\n }\n for (const directory of path.split(delimiter)) {\n if (!isAbsolute(directory)) {\n throw new ExternalPiResolutionError(\n \"invalid_arguments\",\n `PATH entries used to select ${label} must be absolute paths.`,\n );\n }\n const candidate = join(directory, name);\n try {\n await inspectExecutable(candidate, label);\n return candidate;\n } catch (error: unknown) {\n if (\n !(error instanceof ExternalPiResolutionError) ||\n (error.code !== \"pi_not_executable\" && error.code !== \"pi_not_found\")\n ) {\n throw error;\n }\n }\n }\n throw new ExternalPiResolutionError(missingCode, `${label} was not found on PATH.`);\n}\n\nasync function inspectExecutable(path: string, label: \"Pi\" | \"Node\"): Promise<string> {\n try {\n const target = await realpath(path);\n const metadata = await stat(target);\n if (!metadata.isFile()) {\n throw new ExternalPiResolutionError(\"pi_not_executable\", `${label} is not a file: ${path}`);\n }\n await access(path, constants.X_OK);\n return target;\n } catch (error: unknown) {\n if (error instanceof ExternalPiResolutionError) throw error;\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n throw new ExternalPiResolutionError(\"pi_not_found\", `${label} was not found: ${path}`);\n }\n throw new ExternalPiResolutionError(\"pi_not_executable\", `${label} is not executable: ${path}`);\n }\n}\n\nasync function inspectNode(nodePath: string): Promise<void> {\n if (!isAbsolute(nodePath)) {\n throw new ExternalPiResolutionError(\"invalid_arguments\", \"Node must be an absolute path.\");\n }\n try {\n await inspectExecutable(nodePath, \"Node\");\n } catch {\n throw new ExternalPiResolutionError(\"pi_not_executable\", `Node is not executable: ${nodePath}`);\n }\n}\n\nasync function hashFile(path: string): Promise<string> {\n const hash = createHash(\"sha256\");\n await new Promise<void>((resolveHash, rejectHash) => {\n const stream = createReadStream(path);\n stream.on(\"data\", (chunk: string | Buffer) => hash.update(chunk));\n stream.once(\"error\", rejectHash);\n stream.once(\"end\", resolveHash);\n });\n return hash.digest(\"hex\");\n}\n\nasync function readVersion(\n executable: string,\n env: NodeJS.ProcessEnv,\n timeoutMs = VERSION_TIMEOUT_MS,\n maxOutputBytes = MAX_VERSION_OUTPUT_BYTES,\n): Promise<string> {\n const child = spawn(executable, [\"--version\"], {\n detached: process.platform !== \"win32\",\n env,\n shell: false,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n const chunks: Buffer[] = [];\n let outputBytes = 0;\n let terminalError: ExternalPiResolutionError | null = null;\n let terminated = false;\n\n const terminate = () => {\n if (terminated) return;\n terminated = true;\n if (process.platform !== \"win32\" && child.pid !== undefined) {\n try {\n process.kill(-child.pid, \"SIGKILL\");\n return;\n } catch {\n // The group may have already exited; kill the direct child as a fallback.\n }\n }\n child.kill(\"SIGKILL\");\n };\n\n child.stdout.on(\"data\", (chunk: Buffer) => {\n if (terminalError !== null) return;\n outputBytes += chunk.byteLength;\n if (outputBytes > maxOutputBytes) {\n terminalError = new ExternalPiResolutionError(\n \"pi_version_unavailable\",\n \"Pi version output exceeded its limit.\",\n );\n terminate();\n return;\n }\n chunks.push(chunk);\n });\n child.stderr.resume();\n\n return new Promise((resolveVersion, rejectVersion) => {\n const timer = setTimeout(() => {\n terminalError = new ExternalPiResolutionError(\n \"pi_version_unavailable\",\n \"Pi version command timed out.\",\n );\n terminate();\n }, timeoutMs);\n child.once(\"error\", () => {\n terminalError ??= new ExternalPiResolutionError(\n \"pi_version_unavailable\",\n \"Pi version command failed.\",\n );\n });\n child.once(\"close\", (code) => {\n clearTimeout(timer);\n if (terminalError !== null) {\n rejectVersion(terminalError);\n return;\n }\n if (code !== 0) {\n rejectVersion(\n new ExternalPiResolutionError(\"pi_version_unavailable\", \"Pi version command failed.\"),\n );\n return;\n }\n try {\n resolveVersion(new TextDecoder(\"utf-8\", { fatal: true }).decode(Buffer.concat(chunks)));\n } catch {\n rejectVersion(\n new ExternalPiResolutionError(\n \"pi_version_unavailable\",\n \"Pi version command returned invalid UTF-8.\",\n ),\n );\n }\n });\n });\n}\n\nfunction parseVersion(output: string): string {\n const match = /^(?:pi\\s+)?(\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?)\\s*$/i.exec(output);\n if (match?.[1] === undefined) {\n throw new ExternalPiResolutionError(\n \"pi_version_unavailable\",\n \"Pi version command returned an invalid version.\",\n );\n }\n return match[1];\n}\n", "import { constants } from \"node:fs\";\nimport { access, chmod, mkdir, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport {\n launchdAgentPlist,\n systemdUserUnit,\n type ServiceDefinitionOptions,\n} from \"./service-definition.js\";\n\nexport interface CommandExecutor {\n run(command: string, args: readonly string[]): Promise<void>;\n}\n\nexport class ServiceRepairDeferredError extends Error {\n readonly code = \"runtime_upgrade_deferred\";\n\n constructor() {\n super(\n \"The installed pi-fleet service differs from the requested runtime or Pi selection. Automatic replacement is deferred because runtime quiescence cannot be proven; finish active work, stop the existing service explicitly, then install or repair again.\",\n );\n this.name = \"ServiceRepairDeferredError\";\n }\n}\n\nexport async function installUserService(options: {\n readonly platform: NodeJS.Platform;\n readonly definition: ServiceDefinitionOptions;\n readonly executor: CommandExecutor;\n readonly home?: string;\n readonly uid?: number;\n readonly replaceExisting?: boolean;\n readonly ownershipPreflight?: () => Promise<void>;\n}): Promise<string> {\n const home = options.home ?? homedir();\n if (options.platform === \"linux\") {\n const path = join(home, \".config\", \"systemd\", \"user\", \"pi-fleet.service\");\n const effectiveDefinition = await preserveInstalledStateRoot(path, options.definition, \"linux\");\n const definition = systemdUserUnit(effectiveDefinition);\n const needsRepair = await serviceDefinitionNeedsRepair(path, definition, effectiveDefinition);\n const installed = await exists(path);\n await preflightInstalledReplacement({\n installed,\n needsRepair,\n replaceExisting: options.replaceExisting,\n ownershipPreflight: options.ownershipPreflight,\n });\n if (needsRepair) {\n await atomicWrite(path, definition);\n await options.executor.run(\"systemctl\", [\"--user\", \"daemon-reload\"]);\n }\n await options.executor.run(\"systemctl\", [\"--user\", \"enable\", \"--now\", \"pi-fleet.service\"]);\n if (needsRepair) {\n await options.executor.run(\"systemctl\", [\"--user\", \"restart\", \"pi-fleet.service\"]);\n }\n return path;\n }\n if (options.platform === \"darwin\") {\n const path = join(home, \"Library\", \"LaunchAgents\", \"works.elpapi.pifleet.plist\");\n const effectiveDefinition = await preserveInstalledStateRoot(\n path,\n options.definition,\n \"darwin\",\n );\n const definition = launchdAgentPlist(effectiveDefinition);\n const needsRepair = await serviceDefinitionNeedsRepair(path, definition, effectiveDefinition);\n const installed = await exists(path);\n await preflightInstalledReplacement({\n installed,\n needsRepair,\n replaceExisting: options.replaceExisting,\n ownershipPreflight: options.ownershipPreflight,\n });\n if (needsRepair) await atomicWrite(path, definition);\n const domain = `gui/${options.uid ?? process.getuid?.() ?? 0}`;\n await options.executor.run(\"launchctl\", [\"bootout\", domain, path]).catch(() => undefined);\n await options.executor.run(\"launchctl\", [\"bootstrap\", domain, path]);\n await options.executor.run(\"launchctl\", [\"kickstart\", `${domain}/works.elpapi.pifleet`]);\n return path;\n }\n throw new Error(`Native pi-fleet supervision is unsupported on ${options.platform}`);\n}\n\nexport async function uninstallUserService(options: {\n readonly platform: NodeJS.Platform;\n readonly executor: CommandExecutor;\n readonly home?: string;\n readonly uid?: number;\n}): Promise<void> {\n const home = options.home ?? homedir();\n if (options.platform === \"linux\") {\n const path = join(home, \".config\", \"systemd\", \"user\", \"pi-fleet.service\");\n await options.executor.run(\"systemctl\", [\"--user\", \"disable\", \"--now\", \"pi-fleet.service\"]);\n await rm(path, { force: true });\n await options.executor.run(\"systemctl\", [\"--user\", \"daemon-reload\"]);\n return;\n }\n if (options.platform === \"darwin\") {\n const path = join(home, \"Library\", \"LaunchAgents\", \"works.elpapi.pifleet.plist\");\n const domain = `gui/${options.uid ?? process.getuid?.() ?? 0}`;\n await options.executor.run(\"launchctl\", [\"bootout\", domain, path]).catch(() => undefined);\n await rm(path, { force: true });\n return;\n }\n throw new Error(`Native pi-fleet supervision is unsupported on ${options.platform}`);\n}\n\nexport async function serviceDefinitionNeedsRepair(\n path: string,\n expectedContents: string,\n definition: ServiceDefinitionOptions,\n): Promise<boolean> {\n const current = await readFile(path, \"utf8\").catch((error: NodeJS.ErrnoException) => {\n if (error.code === \"ENOENT\") return null;\n throw error;\n });\n if (current !== expectedContents) return true;\n try {\n await access(definition.nodePath, constants.X_OK);\n await access(definition.runtimePath, constants.R_OK);\n return false;\n } catch {\n return true;\n }\n}\n\nasync function preflightInstalledReplacement(options: {\n readonly installed: boolean;\n readonly needsRepair: boolean;\n readonly replaceExisting: boolean | undefined;\n readonly ownershipPreflight: (() => Promise<void>) | undefined;\n}): Promise<void> {\n if (!options.installed || !options.needsRepair) return;\n if (options.replaceExisting !== true || options.ownershipPreflight === undefined) {\n throw new ServiceRepairDeferredError();\n }\n await options.ownershipPreflight();\n}\n\nasync function preserveInstalledStateRoot(\n path: string,\n definition: ServiceDefinitionOptions,\n platform: \"linux\" | \"darwin\",\n): Promise<ServiceDefinitionOptions> {\n if (definition.stateRoot !== undefined) return definition;\n const current = await readFile(path, \"utf8\").catch((error: NodeJS.ErrnoException) => {\n if (error.code === \"ENOENT\") return null;\n throw error;\n });\n if (current === null) return definition;\n const encoded =\n platform === \"linux\"\n ? /^Environment=PIFLEET_STATE_ROOT=(.+)$/m.exec(current)?.[1]\n : /<key>PIFLEET_STATE_ROOT<\\/key><string>([^<]+)<\\/string>/.exec(current)?.[1];\n if (encoded === undefined) return definition;\n const stateRoot =\n platform === \"linux\"\n ? encoded\n : encoded\n .replaceAll(\"&apos;\", \"'\")\n .replaceAll(\"&quot;\", '\"')\n .replaceAll(\"&gt;\", \">\")\n .replaceAll(\"&lt;\", \"<\")\n .replaceAll(\"&amp;\", \"&\");\n return { ...definition, stateRoot };\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function atomicWrite(path: string, contents: string): Promise<void> {\n await mkdir(dirname(path), { recursive: true, mode: 0o700 });\n const temporary = `${path}.tmp-${process.pid}`;\n await writeFile(temporary, contents, { mode: 0o600 });\n await chmod(temporary, 0o600);\n await rename(temporary, path);\n}\n", "import { isAbsolute } from \"node:path\";\n\nexport interface ServiceDefinitionOptions {\n readonly nodePath: string;\n readonly runtimePath: string;\n readonly piExecutablePath?: string;\n readonly piNodePath?: string;\n readonly stateRoot?: string;\n}\n\nexport function systemdUserUnit(options: ServiceDefinitionOptions): string {\n validate(options);\n const environment = environmentEntries(options)\n .map(([key, value]) => {\n const assignment = `${key}=${value}`;\n return `Environment=${/^[A-Za-z0-9_./:@=-]+$/.test(assignment) ? assignment : systemdQuote(assignment)}\\n`;\n })\n .join(\"\");\n return `[Unit]\nDescription=pi-fleet user runtime\nAfter=default.target\n\n[Service]\nType=simple\nExecStart=${systemdArgument(options.nodePath)} ${systemdArgument(options.runtimePath)}\n${environment}Restart=on-failure\nRestartSec=1\nTimeoutStopSec=10\nUMask=0077\nKillMode=control-group\n\n[Install]\nWantedBy=default.target\n`;\n}\n\nexport function launchdAgentPlist(options: ServiceDefinitionOptions): string {\n validate(options);\n const entries = environmentEntries(options);\n const environment =\n entries.length === 0\n ? \"\"\n : ` <key>EnvironmentVariables</key>\n <dict>${entries\n .map(([key, value]) => `<key>${xmlEscape(key)}</key><string>${xmlEscape(value)}</string>`)\n .join(\"\")}</dict>\n`;\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key><string>works.elpapi.pifleet</string>\n <key>ProgramArguments</key>\n <array>\n <string>${xmlEscape(options.nodePath)}</string>\n <string>${xmlEscape(options.runtimePath)}</string>\n </array>\n${environment} <key>RunAtLoad</key><true/>\n <key>KeepAlive</key><dict><key>SuccessfulExit</key><false/></dict>\n <key>ProcessType</key><string>Background</string>\n</dict>\n</plist>\n`;\n}\n\nfunction environmentEntries(options: ServiceDefinitionOptions): Array<readonly [string, string]> {\n return [\n ...(options.stateRoot === undefined\n ? []\n : [[\"PIFLEET_STATE_ROOT\", options.stateRoot] as const]),\n ...(options.piExecutablePath === undefined\n ? []\n : [[\"PIFLEET_PI_EXECUTABLE\", options.piExecutablePath] as const]),\n ...(options.piNodePath === undefined ? [] : [[\"PIFLEET_PI_NODE\", options.piNodePath] as const]),\n ];\n}\n\nfunction validate(options: ServiceDefinitionOptions): void {\n const paths = [\n options.nodePath,\n options.runtimePath,\n options.piExecutablePath,\n options.piNodePath,\n ].filter((value): value is string => value !== undefined);\n if (paths.some((path) => !isAbsolute(path))) {\n throw new Error(\"Service executables must use absolute paths\");\n }\n if (paths.some((path) => /[\\0\\n\\r]/.test(path))) {\n throw new Error(\"Service paths cannot contain control characters\");\n }\n}\n\nfunction systemdArgument(value: string): string {\n return /^[A-Za-z0-9_./:@-]+$/.test(value) ? value : systemdQuote(value);\n}\n\nfunction systemdQuote(value: string): string {\n if (/[\\0\\n\\r]/.test(value)) throw new Error(\"Unsafe systemd value\");\n return `\"${value.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll('\"', '\\\\\"')}\"`;\n}\n\nfunction xmlEscape(value: string): string {\n return value\n .replaceAll(\"&\", \"&amp;\")\n .replaceAll(\"<\", \"&lt;\")\n .replaceAll(\">\", \"&gt;\")\n .replaceAll('\"', \"&quot;\")\n .replaceAll(\"'\", \"&apos;\");\n}\n", "import { createHash, randomUUID } from \"node:crypto\";\nimport { chmod, cp, lstat, mkdir, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport { join, posix, resolve, sep } from \"node:path\";\n\nimport { hashDirectoryTree, type TreeIntegrity } from \"./tree-integrity.js\";\n\ninterface RuntimeManifestFile {\n readonly path: string;\n readonly bytes: number;\n readonly sha256: string;\n}\n\ninterface RuntimeDependency {\n readonly path: string;\n readonly name: string;\n readonly version: string;\n}\n\ninterface RuntimeClosure {\n readonly sourceManifestSha256: string;\n readonly tree: TreeIntegrity;\n}\n\ninterface RuntimeContract {\n readonly protocolVersion: 3;\n readonly journalSchemaVersion: 3;\n readonly clientExport: \"./client\";\n}\n\ninterface RuntimeManifest {\n readonly schemaVersion: 4;\n readonly package: { readonly name: string; readonly version: string };\n readonly piRuntime: { readonly mode: \"external\" };\n readonly runtime: RuntimeContract;\n readonly files: readonly RuntimeManifestFile[];\n readonly dependencies: readonly RuntimeDependency[];\n readonly closure?: RuntimeClosure;\n}\n\ninterface PackageMetadata {\n readonly name: string;\n readonly version: string;\n readonly runtime?: RuntimeContract;\n readonly clientExport?: {\n readonly types: \"./dist/client/index.d.ts\";\n readonly import: \"./dist/client.mjs\";\n };\n readonly dependencies: Readonly<Record<string, string>>;\n}\n\nconst requiredRuntimeArtifacts = new Set([\n \"package.json\",\n \"bin/pifleet.mjs\",\n \"bin/pifleet-runtime.mjs\",\n \"dist/cli.mjs\",\n \"dist/runtime.mjs\",\n \"dist/journal-sqlite-worker.mjs\",\n \"dist/client.mjs\",\n \"dist/client-meta.json\",\n \"dist/client/index.d.ts\",\n \"dist/client/sdk-facade.d.ts\",\n \"dist/client/contracts.d.ts\",\n]);\nconst dependencyTreePath = \"node_modules\";\n\nexport async function materializeRuntime(options: {\n readonly sourceRoot: string;\n readonly applicationRoot: string;\n readonly hooks?: {\n readonly afterDependencyCopy?: () => Promise<void>;\n };\n}): Promise<string> {\n const sourceRoot = resolve(options.sourceRoot);\n const manifestBytes = await readFile(join(sourceRoot, \"dist\", \"runtime-manifest.json\"));\n const sourceManifest = await parseRuntimeManifest(manifestBytes, sourceRoot);\n if (sourceManifest.closure !== undefined) {\n await verifyRuntime(sourceRoot);\n return sourceRoot;\n }\n await verifyRuntimeFiles(sourceRoot, sourceManifest);\n await verifyDependencyIdentities(sourceRoot, sourceManifest.dependencies);\n\n const sourceTreeRoot = resolveInside(sourceRoot, dependencyTreePath);\n const sourceTreeBefore = await hashDirectoryTree(sourceTreeRoot, dependencyTreePath);\n const sourceManifestSha256 = createHash(\"sha256\").update(manifestBytes).digest(\"hex\");\n const materializedManifest: RuntimeManifest = {\n ...sourceManifest,\n closure: { sourceManifestSha256, tree: sourceTreeBefore },\n };\n const materializedManifestBytes = serializeManifest(materializedManifest);\n const closureHash = createHash(\"sha256\")\n .update(sourceManifestSha256)\n .update(\"\\0\")\n .update(JSON.stringify(sourceTreeBefore))\n .digest(\"hex\")\n .slice(0, 16);\n\n const applicationRoot = resolve(options.applicationRoot);\n await ensurePrivateDirectory(applicationRoot);\n const releasesRoot = join(applicationRoot, \"releases\");\n await ensurePrivateDirectory(releasesRoot);\n const destination = join(releasesRoot, `${sourceManifest.package.version}-${closureHash}`);\n\n if (await pathExists(destination)) {\n await verifyExpectedRuntime(destination, materializedManifest, materializedManifestBytes);\n return destination;\n }\n\n const staging = join(releasesRoot, `.staging-${randomUUID()}`);\n await mkdir(staging, { mode: 0o700 });\n try {\n await cp(join(sourceRoot, \"dist\"), join(staging, \"dist\"), {\n recursive: true,\n dereference: true,\n });\n await cp(join(sourceRoot, \"bin\"), join(staging, \"bin\"), {\n recursive: true,\n dereference: true,\n });\n await cp(join(sourceRoot, \"package.json\"), join(staging, \"package.json\"));\n await cp(sourceTreeRoot, join(staging, dependencyTreePath), {\n recursive: true,\n dereference: true,\n });\n await options.hooks?.afterDependencyCopy?.();\n\n const stagedTree = await hashDirectoryTree(\n join(staging, dependencyTreePath),\n dependencyTreePath,\n );\n assertSameTree(sourceTreeBefore, stagedTree, \"copied dependency closure\");\n const sourceTreeAfter = await hashDirectoryTree(sourceTreeRoot, dependencyTreePath);\n assertSameTree(sourceTreeBefore, sourceTreeAfter, \"source dependency closure\");\n\n await writeFile(join(staging, \"dist\", \"runtime-manifest.json\"), materializedManifestBytes);\n await verifyExpectedRuntime(staging, materializedManifest, materializedManifestBytes);\n await chmod(staging, 0o700);\n try {\n await rename(staging, destination);\n } catch (error: unknown) {\n if (!isDestinationRace(error) || !(await pathExists(destination))) throw error;\n await verifyExpectedRuntime(destination, materializedManifest, materializedManifestBytes);\n }\n return destination;\n } finally {\n await rm(staging, { recursive: true, force: true });\n }\n}\n\nexport async function verifyRuntime(root: string): Promise<void> {\n const resolvedRoot = resolve(root);\n const manifestBytes = await readFile(join(resolvedRoot, \"dist\", \"runtime-manifest.json\"));\n const manifest = await parseRuntimeManifest(manifestBytes, resolvedRoot);\n if (manifest.closure === undefined) {\n throw new Error(\"Runtime release manifest is missing its materialized closure\");\n }\n await verifyRuntimeFiles(resolvedRoot, manifest);\n await verifyDependencyIdentities(resolvedRoot, manifest.dependencies);\n const actualTree = await hashDirectoryTree(\n resolveInside(resolvedRoot, dependencyTreePath),\n dependencyTreePath,\n );\n assertSameTree(manifest.closure.tree, actualTree, \"materialized dependency closure\");\n}\n\nasync function verifyExpectedRuntime(\n root: string,\n expected: RuntimeManifest,\n expectedBytes: Buffer,\n): Promise<void> {\n const manifestPath = join(root, \"dist\", \"runtime-manifest.json\");\n const actualBytes = await readFile(manifestPath);\n if (!actualBytes.equals(expectedBytes)) {\n throw new Error(\"Materialized runtime manifest does not match the expected closure\");\n }\n const actual = await parseRuntimeManifest(actualBytes, root);\n if (actual.closure === undefined || expected.closure === undefined) {\n throw new Error(\"Materialized runtime manifest is missing its closure\");\n }\n await verifyRuntimeFiles(root, actual);\n await verifyDependencyIdentities(root, actual.dependencies);\n const actualTree = await hashDirectoryTree(\n resolveInside(root, dependencyTreePath),\n dependencyTreePath,\n );\n assertSameTree(expected.closure.tree, actualTree, \"materialized dependency closure\");\n}\n\nasync function verifyRuntimeFiles(root: string, manifest: RuntimeManifest): Promise<void> {\n for (const file of manifest.files) {\n const path = resolveInside(root, file.path);\n const info = await lstat(path);\n if (info.isSymbolicLink()) {\n throw new Error(`Runtime artifact ${file.path} must not be a symbolic link`);\n }\n if (!info.isFile() || info.size !== file.bytes) {\n throw new Error(`Runtime artifact ${file.path} has changed`);\n }\n const hash = createHash(\"sha256\")\n .update(await readFile(path))\n .digest(\"hex\");\n if (hash !== file.sha256) {\n throw new Error(`Runtime artifact ${file.path} failed verification`);\n }\n }\n}\n\nasync function verifyDependencyIdentities(\n root: string,\n dependencies: readonly RuntimeDependency[],\n): Promise<void> {\n const nodeModules = resolveInside(root, dependencyTreePath);\n const modulesInfo = await lstat(nodeModules);\n if (!modulesInfo.isDirectory() || modulesInfo.isSymbolicLink()) {\n throw new Error(\"Runtime dependency closure must be a regular directory\");\n }\n for (const dependency of dependencies) {\n const packageRoot = resolveInside(root, dependency.path);\n const packageInfo = await lstat(packageRoot);\n if (!packageInfo.isDirectory() || packageInfo.isSymbolicLink()) {\n throw new Error(`Runtime dependency ${dependency.name} must be a regular directory`);\n }\n const packageJsonPath = join(packageRoot, \"package.json\");\n const packageJsonInfo = await lstat(packageJsonPath);\n if (!packageJsonInfo.isFile() || packageJsonInfo.isSymbolicLink()) {\n throw new Error(`Runtime dependency ${dependency.name} has an unsafe package.json`);\n }\n const identity = await readPackageMetadata(packageRoot);\n if (identity.name !== dependency.name || identity.version !== dependency.version) {\n throw new Error(`Runtime dependency ${dependency.name} has an unexpected identity`);\n }\n }\n}\n\nasync function parseRuntimeManifest(bytes: Buffer, root: string): Promise<RuntimeManifest> {\n let candidate: unknown;\n try {\n candidate = JSON.parse(bytes.toString(\"utf8\"));\n } catch {\n throw new Error(\"Runtime manifest is not valid JSON\");\n }\n await validateRuntimeManifest(candidate, root);\n return candidate as RuntimeManifest;\n}\n\nasync function validateRuntimeManifest(candidate: unknown, root: string): Promise<void> {\n if (!isRecord(candidate) || candidate.schemaVersion !== 4) {\n throw new Error(\"Runtime manifest has an unsupported schema version\");\n }\n if (\n !isRecord(candidate.package) ||\n typeof candidate.package.name !== \"string\" ||\n typeof candidate.package.version !== \"string\" ||\n !isRecord(candidate.piRuntime) ||\n candidate.piRuntime.mode !== \"external\" ||\n !isRuntimeContract(candidate.runtime)\n ) {\n throw new Error(\"Runtime manifest has an invalid package identity\");\n }\n const packageMetadata = await readPackageMetadata(root, true);\n if (\n candidate.package.name !== packageMetadata.name ||\n candidate.package.version !== packageMetadata.version ||\n packageMetadata.runtime === undefined ||\n !sameRuntimeContract(candidate.runtime, packageMetadata.runtime) ||\n packageMetadata.clientExport === undefined\n ) {\n throw new Error(\"Runtime manifest package identity does not match package.json\");\n }\n if (!Array.isArray(candidate.files) || !Array.isArray(candidate.dependencies)) {\n throw new Error(\"Runtime manifest has invalid artifact lists\");\n }\n\n const filePaths = new Set<string>();\n for (const file of candidate.files) {\n if (\n !isRecord(file) ||\n !isManifestPath(file.path) ||\n !isValidSize(file.bytes) ||\n !isSha256(file.sha256)\n ) {\n throw new Error(\"Runtime manifest contains an invalid artifact\");\n }\n if (filePaths.has(file.path)) {\n throw new Error(`Runtime manifest has duplicate path ${file.path}`);\n }\n filePaths.add(file.path);\n }\n for (const required of requiredRuntimeArtifacts) {\n if (!filePaths.has(required)) {\n throw new Error(`Runtime manifest is missing required artifact ${required}`);\n }\n }\n\n const dependencyPaths = new Set<string>();\n const dependencyNames = new Set<string>();\n for (const dependency of candidate.dependencies) {\n if (\n !isRecord(dependency) ||\n !isManifestPath(dependency.path) ||\n typeof dependency.name !== \"string\" ||\n dependency.name.length === 0 ||\n typeof dependency.version !== \"string\" ||\n dependency.version.length === 0 ||\n dependency.path !== `node_modules/${dependency.name}`\n ) {\n throw new Error(\"Runtime manifest contains an invalid dependency declaration\");\n }\n if (dependencyPaths.has(dependency.path) || dependencyNames.has(dependency.name)) {\n throw new Error(`Runtime manifest has duplicate dependency ${dependency.name}`);\n }\n dependencyPaths.add(dependency.path);\n dependencyNames.add(dependency.name);\n }\n const expectedDependencies = packageMetadata.dependencies;\n if (\n dependencyNames.size !== Object.keys(expectedDependencies).length ||\n [...dependencyNames].some(\n (name) =>\n expectedDependencies[name] !==\n (candidate.dependencies as Array<Record<string, unknown>>).find(\n (dependency) => dependency.name === name,\n )?.version,\n )\n ) {\n throw new Error(\"Runtime manifest dependencies do not match package.json\");\n }\n\n for (const filePath of filePaths) {\n for (const dependencyPath of dependencyPaths) {\n if (\n filePath === dependencyPath ||\n filePath.startsWith(`${dependencyPath}/`) ||\n dependencyPath.startsWith(`${filePath}/`)\n ) {\n throw new Error(`Runtime manifest has overlapping paths ${filePath} and ${dependencyPath}`);\n }\n }\n }\n\n if (candidate.closure !== undefined) {\n if (\n !isRecord(candidate.closure) ||\n !isSha256(candidate.closure.sourceManifestSha256) ||\n !isTreeIntegrity(candidate.closure.tree) ||\n candidate.closure.tree.path !== dependencyTreePath\n ) {\n throw new Error(\"Runtime manifest contains an invalid materialized closure\");\n }\n }\n}\n\nasync function readPackageMetadata(\n root: string,\n requireRuntimeContract = false,\n): Promise<PackageMetadata> {\n let candidate: unknown;\n try {\n candidate = JSON.parse(await readFile(join(root, \"package.json\"), \"utf8\"));\n } catch {\n throw new Error(\"Runtime package.json is not valid JSON\");\n }\n if (\n !isRecord(candidate) ||\n typeof candidate.name !== \"string\" ||\n typeof candidate.version !== \"string\" ||\n (requireRuntimeContract && !isRuntimeContract(candidate.pifleet)) ||\n (candidate.dependencies !== undefined && !isRecord(candidate.dependencies)) ||\n (isRecord(candidate.dependencies) &&\n Object.values(candidate.dependencies).some((version) => typeof version !== \"string\"))\n ) {\n throw new Error(\"Runtime package.json has invalid package metadata\");\n }\n const clientExport = isRecord(candidate.exports) ? candidate.exports[\"./client\"] : undefined;\n return {\n name: candidate.name,\n version: candidate.version,\n ...(isRuntimeContract(candidate.pifleet) ? { runtime: candidate.pifleet } : {}),\n ...(isRecord(clientExport) &&\n clientExport.types === \"./dist/client/index.d.ts\" &&\n clientExport.import === \"./dist/client.mjs\"\n ? {\n clientExport: {\n types: \"./dist/client/index.d.ts\" as const,\n import: \"./dist/client.mjs\" as const,\n },\n }\n : {}),\n dependencies: isRecord(candidate.dependencies)\n ? (candidate.dependencies as Record<string, string>)\n : {},\n };\n}\n\nfunction serializeManifest(manifest: RuntimeManifest): Buffer {\n return Buffer.from(`${JSON.stringify(manifest, null, 2)}\\n`);\n}\n\nfunction assertSameTree(expected: TreeIntegrity, actual: TreeIntegrity, label: string): void {\n if (\n expected.path !== actual.path ||\n expected.files !== actual.files ||\n expected.bytes !== actual.bytes ||\n expected.sha256 !== actual.sha256\n ) {\n throw new Error(`Runtime ${label} changed during materialization`);\n }\n}\n\nfunction resolveInside(root: string, path: string): string {\n if (!isManifestPath(path)) throw new Error(`Runtime manifest contains an unsafe path ${path}`);\n const resolved = resolve(root, path);\n if (!resolved.startsWith(`${root}${sep}`)) {\n throw new Error(`Runtime manifest contains an unsafe path ${path}`);\n }\n return resolved;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isRuntimeContract(value: unknown): value is RuntimeContract {\n return (\n isRecord(value) &&\n value.protocolVersion === 3 &&\n value.journalSchemaVersion === 3 &&\n value.clientExport === \"./client\"\n );\n}\n\nfunction sameRuntimeContract(left: RuntimeContract, right: RuntimeContract): boolean {\n return (\n left.protocolVersion === right.protocolVersion &&\n left.journalSchemaVersion === right.journalSchemaVersion &&\n left.clientExport === right.clientExport\n );\n}\n\nfunction isManifestPath(value: unknown): value is string {\n return (\n typeof value === \"string\" &&\n value.length > 0 &&\n !value.includes(\"\\\\\") &&\n !value.startsWith(\"/\") &&\n posix.normalize(value) === value &&\n value.split(\"/\").every((part) => part.length > 0 && part !== \".\" && part !== \"..\")\n );\n}\n\nfunction isValidSize(value: unknown): value is number {\n return typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0;\n}\n\nfunction isSha256(value: unknown): value is string {\n return typeof value === \"string\" && /^[a-f0-9]{64}$/.test(value);\n}\n\nfunction isTreeIntegrity(value: unknown): value is TreeIntegrity {\n return (\n isRecord(value) &&\n isManifestPath(value.path) &&\n isValidSize(value.files) &&\n isValidSize(value.bytes) &&\n isSha256(value.sha256)\n );\n}\n\nfunction isDestinationRace(error: unknown): boolean {\n const code = (error as NodeJS.ErrnoException).code;\n return code === \"EEXIST\" || code === \"ENOTEMPTY\";\n}\n\nasync function ensurePrivateDirectory(path: string): Promise<void> {\n await mkdir(path, { recursive: true, mode: 0o700 });\n const info = await lstat(path);\n if (!info.isDirectory() || info.isSymbolicLink()) {\n throw new Error(`Refusing unsafe runtime release path ${path}`);\n }\n if (typeof process.getuid === \"function\" && info.uid !== process.getuid()) {\n throw new Error(`Runtime release path ${path} is not owned by the current user`);\n }\n await chmod(path, 0o700);\n}\n\nasync function pathExists(path: string): Promise<boolean> {\n try {\n await lstat(path);\n return true;\n } catch (error: unknown) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return false;\n throw error;\n }\n}\n", "import { createHash } from \"node:crypto\";\nimport { lstat, readFile, readdir, realpath, stat } from \"node:fs/promises\";\nimport { join, relative, resolve, sep } from \"node:path\";\n\nexport interface TreeIntegrity {\n readonly path: string;\n readonly files: number;\n readonly bytes: number;\n readonly sha256: string;\n}\n\nexport async function hashDirectoryTree(\n root: string,\n manifestPath: string,\n): Promise<TreeIntegrity> {\n const resolvedRoot = resolve(root);\n const entries = await collectFiles(resolvedRoot, resolvedRoot);\n const hash = createHash(\"sha256\");\n let bytes = 0;\n for (const entry of entries) {\n const contents = await readFile(entry.absolutePath);\n bytes += contents.length;\n hash.update(entry.relativePath);\n hash.update(\"\\0\");\n hash.update(String(contents.length));\n hash.update(\"\\0\");\n hash.update(contents);\n hash.update(\"\\0\");\n }\n return {\n path: manifestPath,\n files: entries.length,\n bytes,\n sha256: hash.digest(\"hex\"),\n };\n}\n\nasync function collectFiles(\n root: string,\n directory: string,\n): Promise<Array<{ readonly absolutePath: string; readonly relativePath: string }>> {\n const output: Array<{ absolutePath: string; relativePath: string }> = [];\n for (const name of (await readdir(directory)).sort()) {\n const absolutePath = join(directory, name);\n const linkInfo = await lstat(absolutePath);\n const info = linkInfo.isSymbolicLink() ? await stat(absolutePath) : linkInfo;\n if (info.isDirectory()) {\n if (linkInfo.isSymbolicLink()) {\n throw new Error(`Runtime dependency tree contains a directory symlink: ${absolutePath}`);\n }\n output.push(...(await collectFiles(root, absolutePath)));\n continue;\n }\n if (!info.isFile()) {\n throw new Error(`Runtime dependency tree contains an unsupported entry: ${absolutePath}`);\n }\n if (linkInfo.isSymbolicLink()) {\n const target = await realpath(absolutePath);\n if (target !== root && !target.startsWith(`${root}${sep}`)) {\n throw new Error(\n `Runtime dependency tree contains an external file symlink: ${absolutePath}`,\n );\n }\n }\n const relativePath = relative(root, absolutePath).split(sep).join(\"/\");\n if (relativePath.length === 0 || relativePath.startsWith(\"../\")) {\n throw new Error(`Runtime dependency path escapes its root: ${absolutePath}`);\n }\n output.push({ absolutePath, relativePath });\n }\n return output.sort((left, right) => left.relativePath.localeCompare(right.relativePath));\n}\n", "import { homedir, tmpdir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\n\nexport interface FleetPaths {\n readonly runtimeRoot: string;\n readonly stateRoot: string;\n readonly socketPath: string;\n readonly databasePath: string;\n}\n\nexport function resolveApplicationRoot(env: NodeJS.ProcessEnv = process.env): string {\n return (\n env.PIFLEET_APPLICATION_ROOT ??\n (process.platform === \"darwin\"\n ? join(homedir(), \"Library\", \"Application Support\", \"pi-fleet\", \"runtime\")\n : join(env.XDG_DATA_HOME ?? join(homedir(), \".local\", \"share\"), \"pi-fleet\"))\n );\n}\n\nexport function resolveFleetPaths(env: NodeJS.ProcessEnv = process.env): FleetPaths {\n const explicitRoot = env.PIFLEET_STATE_ROOT;\n if (explicitRoot !== undefined) {\n const root = resolve(explicitRoot);\n return {\n runtimeRoot: root,\n stateRoot: root,\n socketPath: join(root, \"control.sock\"),\n databasePath: join(root, \"fleet.sqlite\"),\n };\n }\n\n const runtimeRoot = join(\n env.XDG_RUNTIME_DIR ?? tmpdir(),\n `pifleet-${process.getuid?.() ?? \"user\"}`,\n );\n const stateRoot =\n process.platform === \"darwin\"\n ? join(homedir(), \"Library\", \"Application Support\", \"pi-fleet\")\n : join(env.XDG_STATE_HOME ?? join(homedir(), \".local\", \"state\"), \"pi-fleet\");\n return {\n runtimeRoot,\n stateRoot,\n socketPath: join(runtimeRoot, \"control.sock\"),\n databasePath: join(stateRoot, \"fleet.sqlite\"),\n };\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["dirname", "join", "constants", "access", "dirname", "join", "isAbsolute", "join", "access", "constants", "dirname", "createHash", "chmod", "lstat", "mkdir", "readFile", "rename", "rm", "writeFile", "join", "resolve", "sep", "createHash", "readFile", "realpath", "stat", "join", "resolve", "readFile", "join", "createHash", "mkdir", "writeFile", "chmod", "rename", "rm", "lstat", "sep", "homedir", "join", "resolve", "dirname", "join"]
7
7
  }