@elpapi42/pi-fleet 0.1.0-beta.0 → 0.1.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +162 -3
- package/README.md +170 -104
- package/bin/pifleet-runtime.mjs +1 -1
- package/dist/cli-meta.json +5464 -82
- package/dist/cli.mjs +3481 -253
- package/dist/cli.mjs.map +4 -4
- package/dist/installer-meta.json +87 -13
- package/dist/installer.mjs +555 -95
- package/dist/installer.mjs.map +4 -4
- package/dist/runtime-manifest.json +37 -43
- package/dist/runtime-meta.json +2976 -2868
- package/dist/runtime.mjs +6316 -5247
- package/dist/runtime.mjs.map +4 -4
- package/dist/sqlite-worker-meta.json +6 -6
- package/dist/sqlite-worker.mjs +95 -40
- package/dist/sqlite-worker.mjs.map +2 -2
- package/package.json +11 -5
package/dist/installer.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/entry/installer.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 {\n installUserService,\n uninstallUserService,\n type CommandExecutor,\n} from \"../platform/install/service-installer.js\";\nimport { materializeRuntime } from \"../platform/install/runtime-release.js\";\nimport { resolveApplicationRoot, resolveFleetPaths } 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(resolveFleetPaths().stateRoot);\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 return installUserService({\n platform: process.platform,\n definition: {\n nodePath: process.execPath,\n runtimePath: join(release, \"bin\", \"pifleet-runtime.mjs\"),\n ...(stateRoot === undefined ? {} : { stateRoot }),\n },\n executor,\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 { 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 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}): 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) {\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 await atomicWrite(path, launchdAgentPlist(effectiveDefinition));\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(\"'\", \"'\")\n .replaceAll(\""\", '\"')\n .replaceAll(\">\", \">\")\n .replaceAll(\"<\", \"<\")\n .replaceAll(\"&\", \"&\");\n return { ...definition, stateRoot };\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 stateRoot?: string;\n}\n\nexport function systemdUserUnit(options: ServiceDefinitionOptions): string {\n validate(options);\n const environment =\n options.stateRoot === undefined\n ? \"\"\n : `Environment=PIFLEET_STATE_ROOT=${systemdEscape(options.stateRoot)}\\n`;\n return `[Unit]\nDescription=Pi Fleet user runtime\nAfter=default.target\n\n[Service]\nType=simple\nExecStart=${systemdEscape(options.nodePath)} ${systemdEscape(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 environment =\n options.stateRoot === undefined\n ? \"\"\n : ` <key>EnvironmentVariables</key>\n <dict><key>PIFLEET_STATE_ROOT</key><string>${xmlEscape(options.stateRoot)}</string></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 validate(options: ServiceDefinitionOptions): void {\n if (!isAbsolute(options.nodePath) || !isAbsolute(options.runtimePath)) {\n throw new Error(\"Service executables must use absolute paths\");\n }\n}\n\nfunction systemdEscape(value: string): string {\n if (!/^[A-Za-z0-9_./:@-]+$/.test(value)) throw new Error(`Unsafe systemd path ${value}`);\n return value;\n}\n\nfunction xmlEscape(value: string): string {\n return value\n .replaceAll(\"&\", \"&\")\n .replaceAll(\"<\", \"<\")\n .replaceAll(\">\", \">\")\n .replaceAll('\"', \""\")\n .replaceAll(\"'\", \"'\");\n}\n", "import { createHash, randomUUID } from \"node:crypto\";\nimport { chmod, cp, lstat, mkdir, readFile, rename, rm, stat } from \"node:fs/promises\";\nimport { join, resolve, sep } from \"node:path\";\n\nimport { hashDirectoryTree, type TreeIntegrity } from \"./tree-integrity.js\";\n\ninterface RuntimeManifest {\n readonly schemaVersion: 2;\n readonly package: { readonly name: string; readonly version: string };\n readonly files: readonly {\n readonly path: string;\n readonly bytes: number;\n readonly sha256: string;\n }[];\n readonly trees: readonly TreeIntegrity[];\n}\n\nexport async function materializeRuntime(options: {\n readonly sourceRoot: string;\n readonly applicationRoot: string;\n}): Promise<string> {\n const sourceRoot = resolve(options.sourceRoot);\n const applicationRoot = resolve(options.applicationRoot);\n await ensurePrivateDirectory(applicationRoot);\n const manifestBytes = await readFile(join(sourceRoot, \"dist\", \"runtime-manifest.json\"));\n const manifest = JSON.parse(manifestBytes.toString(\"utf8\")) as RuntimeManifest;\n const manifestHash = createHash(\"sha256\").update(manifestBytes).digest(\"hex\").slice(0, 16);\n const releasesRoot = join(applicationRoot, \"releases\");\n await ensurePrivateDirectory(releasesRoot);\n const destination = join(releasesRoot, `${manifest.package.version}-${manifestHash}`);\n\n if (await pathExists(destination)) {\n await verifyRuntime(destination, manifest);\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\"), { recursive: true, dereference: true });\n await cp(join(sourceRoot, \"package.json\"), join(staging, \"package.json\"));\n for (const tree of manifest.trees) {\n const source = resolveInside(sourceRoot, tree.path);\n const destination = resolveInside(staging, tree.path);\n await mkdir(resolve(destination, \"..\"), { recursive: true, mode: 0o700 });\n await cp(source, destination, { recursive: true, dereference: true });\n }\n await verifyRuntime(staging, manifest);\n await chmod(staging, 0o700);\n await rename(staging, destination);\n return destination;\n } catch (error: unknown) {\n await rm(staging, { recursive: true, force: true });\n throw error;\n }\n}\n\nexport async function verifyRuntime(root: string, manifest?: RuntimeManifest): Promise<void> {\n const expected =\n manifest ??\n (JSON.parse(\n await readFile(join(root, \"dist\", \"runtime-manifest.json\"), \"utf8\"),\n ) as RuntimeManifest);\n const resolvedRoot = resolve(root);\n for (const file of expected.files) {\n const path = resolveInside(resolvedRoot, file.path);\n const info = await stat(path);\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 for (const expectedTree of expected.trees) {\n const treeRoot = resolveInside(resolvedRoot, expectedTree.path);\n const actualTree = await hashDirectoryTree(treeRoot, expectedTree.path);\n if (\n actualTree.files !== expectedTree.files ||\n actualTree.bytes !== expectedTree.bytes ||\n actualTree.sha256 !== expectedTree.sha256\n ) {\n throw new Error(`Runtime dependency tree ${expectedTree.path} failed verification`);\n }\n }\n}\n\nfunction resolveInside(root: string, path: string): string {\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\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, 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 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
|
-
"names": ["dirname", "join", "createHash", "chmod", "lstat", "mkdir", "readFile", "rename", "rm", "
|
|
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(\"'\", \"'\")\n .replaceAll(\""\", '\"')\n .replaceAll(\">\", \">\")\n .replaceAll(\"<\", \"<\")\n .replaceAll(\"&\", \"&\");\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(\"&\", \"&\")\n .replaceAll(\"<\", \"<\")\n .replaceAll(\">\", \">\")\n .replaceAll('\"', \""\")\n .replaceAll(\"'\", \"'\");\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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",
|
|
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
|
}
|
|
@@ -1,75 +1,77 @@
|
|
|
1
1
|
{
|
|
2
|
-
"schemaVersion":
|
|
2
|
+
"schemaVersion": 4,
|
|
3
3
|
"package": {
|
|
4
4
|
"name": "@elpapi42/pi-fleet",
|
|
5
|
-
"version": "0.1.0-beta.
|
|
5
|
+
"version": "0.1.0-beta.10"
|
|
6
|
+
},
|
|
7
|
+
"piRuntime": {
|
|
8
|
+
"mode": "external"
|
|
6
9
|
},
|
|
7
|
-
"managedPi": "@earendil-works/pi-coding-agent@0.80.10",
|
|
8
10
|
"files": [
|
|
9
11
|
{
|
|
10
12
|
"path": "dist/cli-meta.json",
|
|
11
|
-
"bytes":
|
|
12
|
-
"sha256": "
|
|
13
|
+
"bytes": 209749,
|
|
14
|
+
"sha256": "4edf80b06cf6bb73dc69aed4590db1b2d1fcf4da6759c0b6ebc0b6994c815f2c"
|
|
13
15
|
},
|
|
14
16
|
{
|
|
15
17
|
"path": "dist/cli.mjs",
|
|
16
|
-
"bytes":
|
|
17
|
-
"sha256": "
|
|
18
|
+
"bytes": 278004,
|
|
19
|
+
"sha256": "3120ad1d956877587dc467eb57f96a18d27f0e3ea5804663bb914567b25b87e4"
|
|
18
20
|
},
|
|
19
21
|
{
|
|
20
22
|
"path": "dist/cli.mjs.map",
|
|
21
|
-
"bytes":
|
|
22
|
-
"sha256": "
|
|
23
|
+
"bytes": 596614,
|
|
24
|
+
"sha256": "9801eb245c03617f14f029eb0f73cd45a4512cb83ead5a258d6328fb5e5f9fa9"
|
|
23
25
|
},
|
|
24
26
|
{
|
|
25
27
|
"path": "dist/installer-meta.json",
|
|
26
|
-
"bytes":
|
|
27
|
-
"sha256": "
|
|
28
|
+
"bytes": 8431,
|
|
29
|
+
"sha256": "34452912362dd4a186797b009acfbcfcff8d463b0edfe641a9ea91884a3bb814"
|
|
28
30
|
},
|
|
29
31
|
{
|
|
30
32
|
"path": "dist/installer.mjs",
|
|
31
|
-
"bytes":
|
|
32
|
-
"sha256": "
|
|
33
|
+
"bytes": 34253,
|
|
34
|
+
"sha256": "42dad7eef5cd4a274a606d4d18f62a3a84ac825d12f49f35b1d16f4f29eb7620"
|
|
33
35
|
},
|
|
34
36
|
{
|
|
35
37
|
"path": "dist/installer.mjs.map",
|
|
36
|
-
"bytes":
|
|
37
|
-
"sha256": "
|
|
38
|
+
"bytes": 64905,
|
|
39
|
+
"sha256": "0bd72cf1cb3651c548aae1de1c9fbaf10202c19fd83e66aec392a989aab23610"
|
|
38
40
|
},
|
|
39
41
|
{
|
|
40
42
|
"path": "dist/runtime-meta.json",
|
|
41
|
-
"bytes":
|
|
42
|
-
"sha256": "
|
|
43
|
+
"bytes": 243785,
|
|
44
|
+
"sha256": "ad5f61124d486c0b91d3b4284cbfd008d63e06aff02169ce95b8b25e4630290e"
|
|
43
45
|
},
|
|
44
46
|
{
|
|
45
47
|
"path": "dist/runtime.mjs",
|
|
46
|
-
"bytes":
|
|
47
|
-
"sha256": "
|
|
48
|
+
"bytes": 353381,
|
|
49
|
+
"sha256": "88f6174c1fb6a1a6807dfd05ac22401b087a42447ab5bfdb0efa6fc9dce5a137"
|
|
48
50
|
},
|
|
49
51
|
{
|
|
50
52
|
"path": "dist/runtime.mjs.map",
|
|
51
|
-
"bytes":
|
|
52
|
-
"sha256": "
|
|
53
|
+
"bytes": 761779,
|
|
54
|
+
"sha256": "c3889d315eb5ba4640bf950e6031d9d0d0f05d1968e899c3920cf21b14cc1d05"
|
|
53
55
|
},
|
|
54
56
|
{
|
|
55
57
|
"path": "dist/sqlite-worker-meta.json",
|
|
56
|
-
"bytes":
|
|
57
|
-
"sha256": "
|
|
58
|
+
"bytes": 1846,
|
|
59
|
+
"sha256": "7fcbb8b2e3ac0f14ff6e842f571258655d53946ab9cd3fe45e158ef121ee4c38"
|
|
58
60
|
},
|
|
59
61
|
{
|
|
60
62
|
"path": "dist/sqlite-worker.mjs",
|
|
61
|
-
"bytes":
|
|
62
|
-
"sha256": "
|
|
63
|
+
"bytes": 14497,
|
|
64
|
+
"sha256": "a12e54d1fc1359138918b7323a241f4957f3d34ae6a87452d94ebbfccc9982dd"
|
|
63
65
|
},
|
|
64
66
|
{
|
|
65
67
|
"path": "dist/sqlite-worker.mjs.map",
|
|
66
|
-
"bytes":
|
|
67
|
-
"sha256": "
|
|
68
|
+
"bytes": 24288,
|
|
69
|
+
"sha256": "d21010e79a1fd8eee3f2beeebe47d4ce01b1590fc91f889786a4f0b7d1f68ac1"
|
|
68
70
|
},
|
|
69
71
|
{
|
|
70
72
|
"path": "bin/pifleet-runtime.mjs",
|
|
71
73
|
"bytes": 536,
|
|
72
|
-
"sha256": "
|
|
74
|
+
"sha256": "252b0ecd10b5d7c44d7b45fe86079bf52d9940661e58a4f6b03a0a55693bcce1"
|
|
73
75
|
},
|
|
74
76
|
{
|
|
75
77
|
"path": "bin/pifleet.mjs",
|
|
@@ -78,28 +80,20 @@
|
|
|
78
80
|
},
|
|
79
81
|
{
|
|
80
82
|
"path": "package.json",
|
|
81
|
-
"bytes":
|
|
82
|
-
"sha256": "
|
|
83
|
+
"bytes": 2463,
|
|
84
|
+
"sha256": "a90970fa3129f54643ea74526d2379e6ab3f52078d83c3d07535c493e10b225d"
|
|
83
85
|
}
|
|
84
86
|
],
|
|
85
|
-
"
|
|
86
|
-
{
|
|
87
|
-
"path": "node_modules/@earendil-works/pi-coding-agent",
|
|
88
|
-
"files": 18577,
|
|
89
|
-
"bytes": 128109797,
|
|
90
|
-
"sha256": "70952c72d8392afb58398368fd4a109f337a1e0d1757efa72ab0abaab67c6fab"
|
|
91
|
-
},
|
|
87
|
+
"dependencies": [
|
|
92
88
|
{
|
|
93
89
|
"path": "node_modules/@sinclair/typebox",
|
|
94
|
-
"
|
|
95
|
-
"
|
|
96
|
-
"sha256": "81ac95c0040ae77129a0f7f0797810bcf3ceff766c7ec20ca033c7358069b911"
|
|
90
|
+
"name": "@sinclair/typebox",
|
|
91
|
+
"version": "0.34.52"
|
|
97
92
|
},
|
|
98
93
|
{
|
|
99
94
|
"path": "node_modules/commander",
|
|
100
|
-
"
|
|
101
|
-
"
|
|
102
|
-
"sha256": "55c788d06a44c350783898c6f830c0c54fde83b063c471a7efa363e2de081230"
|
|
95
|
+
"name": "commander",
|
|
96
|
+
"version": "15.0.0"
|
|
103
97
|
}
|
|
104
98
|
]
|
|
105
99
|
}
|