openmeld 0.3.288 → 0.3.290

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 (137) hide show
  1. package/dist/{add-me-membership-BQl3NpHs.js → add-me-membership-inSSCZiT.js} +2 -2
  2. package/dist/{add-me-membership-BQl3NpHs.js.map → add-me-membership-inSSCZiT.js.map} +1 -1
  3. package/dist/{agents-B0w90SR9.js → agents-Dai79qvd.js} +10 -10
  4. package/dist/{agents-B0w90SR9.js.map → agents-Dai79qvd.js.map} +1 -1
  5. package/dist/{api-client-foundation-RM1pxGSx.js → api-client-foundation-BFlKjR9I.js} +1 -1
  6. package/dist/{api-client-foundation-i2KBsQ7r.js → api-client-foundation-DERyHDAT.js} +6 -6
  7. package/dist/{api-client-foundation-i2KBsQ7r.js.map → api-client-foundation-DERyHDAT.js.map} +1 -1
  8. package/dist/{auth-session-DRQMn41Z.js → auth-session-B2lS_bSW.js} +4 -4
  9. package/dist/{auth-session-DRQMn41Z.js.map → auth-session-B2lS_bSW.js.map} +1 -1
  10. package/dist/auth-session-Cj6PrTZ3.js +3 -0
  11. package/dist/{auth-url-Dnpds8Yf.js → auth-url-LPP-DGsD.js} +2 -2
  12. package/dist/{auth-url-Dnpds8Yf.js.map → auth-url-LPP-DGsD.js.map} +1 -1
  13. package/dist/{base-url-b30kK86t.js → base-url-DuppOOaB.js} +2 -2
  14. package/dist/{base-url-b30kK86t.js.map → base-url-DuppOOaB.js.map} +1 -1
  15. package/dist/{base-url-Mw6hstaO.js → base-url-GJgAnOwO.js} +1 -1
  16. package/dist/{channel-CFIRo4fR.js → channel-DFsCrkPT.js} +17 -6
  17. package/dist/channel-DFsCrkPT.js.map +1 -0
  18. package/dist/{client-CBTgmyFC.js → client-BoQLTU0k.js} +2 -2
  19. package/dist/{client-CBTgmyFC.js.map → client-BoQLTU0k.js.map} +1 -1
  20. package/dist/{cloud-computer-CuWSimwt.js → cloud-computer-DYQpdovK.js} +6 -6
  21. package/dist/{cloud-computer-CuWSimwt.js.map → cloud-computer-DYQpdovK.js.map} +1 -1
  22. package/dist/{command-BqcCAQJ_.js → command-BMssGnS1.js} +19 -19
  23. package/dist/{command-BqcCAQJ_.js.map → command-BMssGnS1.js.map} +1 -1
  24. package/dist/{computer-connection-review-Bw3C24LC.js → computer-connection-review-B2VBvkUf.js} +5 -5
  25. package/dist/{computer-connection-review-Bw3C24LC.js.map → computer-connection-review-B2VBvkUf.js.map} +1 -1
  26. package/dist/{computer-disconnect-BXUbY8kY.js → computer-disconnect-BsO7SqGv.js} +9 -9
  27. package/dist/{computer-disconnect-BXUbY8kY.js.map → computer-disconnect-BsO7SqGv.js.map} +1 -1
  28. package/dist/{computer-setup-continuation-uk5s7_vp.js → computer-setup-continuation-DN9nvTdz.js} +5 -5
  29. package/dist/{computer-setup-continuation-uk5s7_vp.js.map → computer-setup-continuation-DN9nvTdz.js.map} +1 -1
  30. package/dist/{computer-update-wait-Bm_oW5Ne.js → computer-update-wait-DjNHPLHV.js} +4 -4
  31. package/dist/{computer-update-wait-Bm_oW5Ne.js.map → computer-update-wait-DjNHPLHV.js.map} +1 -1
  32. package/dist/{context-BvLQjNGR.js → context-C6GiteNY.js} +8 -8
  33. package/dist/{context-BvLQjNGR.js.map → context-C6GiteNY.js.map} +1 -1
  34. package/dist/{daemon-device-id-D-RHe9se.js → daemon-device-id-CGV19VtH.js} +4 -4
  35. package/dist/{daemon-device-id-D-RHe9se.js.map → daemon-device-id-CGV19VtH.js.map} +1 -1
  36. package/dist/{daemon-lifecycle-journal-AyDo0rCV.js → daemon-lifecycle-journal-YFnaFEDn.js} +4 -4
  37. package/dist/{daemon-lifecycle-journal-AyDo0rCV.js.map → daemon-lifecycle-journal-YFnaFEDn.js.map} +1 -1
  38. package/dist/{daemon-runtime-lease-CslvUjEq.js → daemon-runtime-lease-CgP8D7m8.js} +1 -1
  39. package/dist/{daemon-runtime-lease-DRYVXnBQ.js → daemon-runtime-lease-IKWq2O8q.js} +2 -2
  40. package/dist/{daemon-runtime-lease-DRYVXnBQ.js.map → daemon-runtime-lease-IKWq2O8q.js.map} +1 -1
  41. package/dist/{daemon-service-contract-CsANv7K_.js → daemon-service-contract-D8osKBM6.js} +2 -2
  42. package/dist/{daemon-service-contract-CsANv7K_.js.map → daemon-service-contract-D8osKBM6.js.map} +1 -1
  43. package/dist/{daemon-service-manager-DS4kFs8x.js → daemon-service-manager-CAGPGW2q.js} +1 -1
  44. package/dist/{daemon-service-manager-a5tY3qpR.js → daemon-service-manager-DB2rSviv.js} +4 -4
  45. package/dist/{daemon-service-manager-a5tY3qpR.js.map → daemon-service-manager-DB2rSviv.js.map} +1 -1
  46. package/dist/{daemon-service-runtime-CMi7bRwi.js → daemon-service-runtime-Dnu6mxCS.js} +12 -12
  47. package/dist/{daemon-service-runtime-CMi7bRwi.js.map → daemon-service-runtime-Dnu6mxCS.js.map} +1 -1
  48. package/dist/{daemon-service-update-state-BSn45OHj.js → daemon-service-update-state-GCIZ6nGp.js} +2 -2
  49. package/dist/{daemon-service-update-state-BSn45OHj.js.map → daemon-service-update-state-GCIZ6nGp.js.map} +1 -1
  50. package/dist/{daemon-state-CTOVPwNq.js → daemon-state-C72A-n6c.js} +3 -3
  51. package/dist/{daemon-state-CTOVPwNq.js.map → daemon-state-C72A-n6c.js.map} +1 -1
  52. package/dist/{dispatch-owned-runtime-CCeQTcjr.js → dispatch-owned-runtime-CoVWIxYl.js} +12 -12
  53. package/dist/{dispatch-owned-runtime-CCeQTcjr.js.map → dispatch-owned-runtime-CoVWIxYl.js.map} +1 -1
  54. package/dist/{dist-53uvP0DN.js → dist-BC0SB_h-.js} +3 -3
  55. package/dist/{dist-53uvP0DN.js.map → dist-BC0SB_h-.js.map} +1 -1
  56. package/dist/{dist-CqU093n8.js → dist-BuqY1gad.js} +2 -2
  57. package/dist/dist-DahbdeDi.js +34 -0
  58. package/dist/{dist-D7SkvUZW.js → dist-VZtPE-jT.js} +2 -2
  59. package/dist/{dist-D7SkvUZW.js.map → dist-VZtPE-jT.js.map} +1 -1
  60. package/dist/{dist-CZyGORfc.js → dist-zOvEcl-o.js} +1 -1
  61. package/dist/{dual-view-guide-catalog-Buq8NAPC.js → dual-view-guide-catalog-DJVTHfKM.js} +4 -4
  62. package/dist/{dual-view-guide-catalog-Buq8NAPC.js.map → dual-view-guide-catalog-DJVTHfKM.js.map} +1 -1
  63. package/dist/{elapsed-time-jRFzKVlC.js → elapsed-time-CzR72jgL.js} +2 -2
  64. package/dist/{elapsed-time-jRFzKVlC.js.map → elapsed-time-CzR72jgL.js.map} +1 -1
  65. package/dist/{entry-D-22_x6G.js → entry-hCEOH64N.js} +152 -82
  66. package/dist/entry-hCEOH64N.js.map +1 -0
  67. package/dist/{installation-inventory-B7Lj2s1Y.js → installation-inventory-CsSfOQgL.js} +4 -4
  68. package/dist/{installation-inventory-B7Lj2s1Y.js.map → installation-inventory-CsSfOQgL.js.map} +1 -1
  69. package/dist/{installer-BgUOrcah.js → installer-BytXmECH.js} +2 -2
  70. package/dist/{installer-BgUOrcah.js.map → installer-BytXmECH.js.map} +1 -1
  71. package/dist/{lock-DP8d33p_.js → lock-B0YzvcUu.js} +3 -3
  72. package/dist/lock-B0YzvcUu.js.map +1 -0
  73. package/dist/{meta-api-32dKpaJB.js → meta-api-YLzAzgov.js} +8 -8
  74. package/dist/{meta-api-32dKpaJB.js.map → meta-api-YLzAzgov.js.map} +1 -1
  75. package/dist/{openmeld-BOBD0Any.js → openmeld-Dt4vpNjB.js} +43 -43
  76. package/dist/{openmeld-BOBD0Any.js.map → openmeld-Dt4vpNjB.js.map} +1 -1
  77. package/dist/{openmeld-dev-environment-CAETyazL.js → openmeld-dev-environment-Rl0tTXNd.js} +3 -3
  78. package/dist/{openmeld-dev-environment-CAETyazL.js.map → openmeld-dev-environment-Rl0tTXNd.js.map} +1 -1
  79. package/dist/openmeld-dev.js +1 -1
  80. package/dist/{openmeld-environment-target-DydyKO8Z.js → openmeld-environment-target-KDkHbyUB.js} +4 -4
  81. package/dist/{openmeld-environment-target-DydyKO8Z.js.map → openmeld-environment-target-KDkHbyUB.js.map} +1 -1
  82. package/dist/{openmeld-maintenance-worker-C99TPCOq.js → openmeld-maintenance-worker-BIWvvyIf.js} +16 -16
  83. package/dist/{openmeld-maintenance-worker-C99TPCOq.js.map → openmeld-maintenance-worker-BIWvvyIf.js.map} +1 -1
  84. package/dist/{openmeld-tools-update-attempt-state-B6t53OYC.js → openmeld-tools-update-attempt-state-sK3W06wI.js} +2 -2
  85. package/dist/{openmeld-tools-update-attempt-state-B6t53OYC.js.map → openmeld-tools-update-attempt-state-sK3W06wI.js.map} +1 -1
  86. package/dist/{openmeld-tools-update-coordinator-DkC6z3PV.js → openmeld-tools-update-coordinator-BWFtknlg.js} +31 -26
  87. package/dist/{openmeld-tools-update-coordinator-DkC6z3PV.js.map → openmeld-tools-update-coordinator-BWFtknlg.js.map} +1 -1
  88. package/dist/{openmeld-tools-update-join-B0bVe2pL.js → openmeld-tools-update-join-vlA-GmSh.js} +4 -4
  89. package/dist/{openmeld-tools-update-join-B0bVe2pL.js.map → openmeld-tools-update-join-vlA-GmSh.js.map} +1 -1
  90. package/dist/openmeld.js +5 -5
  91. package/dist/{prepare-provider-runtime-m0GVd1Za.js → prepare-provider-runtime-D4X1jiYQ.js} +33 -17
  92. package/dist/prepare-provider-runtime-D4X1jiYQ.js.map +1 -0
  93. package/dist/{prepare-session-executor-C8tvGy6j.js → prepare-session-executor-Cwe666D0.js} +24 -24
  94. package/dist/{prepare-session-executor-C8tvGy6j.js.map → prepare-session-executor-Cwe666D0.js.map} +1 -1
  95. package/dist/{presenter-DMoE2U_q.js → presenter-CfWGbWdq.js} +2 -2
  96. package/dist/{presenter-DMoE2U_q.js.map → presenter-CfWGbWdq.js.map} +1 -1
  97. package/dist/{process-channel-DtJ01mUI.js → process-channel-AjxeujN8.js} +2 -2
  98. package/dist/{process-channel-DtJ01mUI.js.map → process-channel-AjxeujN8.js.map} +1 -1
  99. package/dist/{runtime-DDZRXE1m.js → runtime-DVaIwyJM.js} +163 -75
  100. package/dist/runtime-DVaIwyJM.js.map +1 -0
  101. package/dist/{runtime-agent-controller-reporting-submission-Br2qDki0.js → runtime-agent-controller-reporting-submission-CkiUg9j0.js} +8 -8
  102. package/dist/{runtime-agent-controller-reporting-submission-Br2qDki0.js.map → runtime-agent-controller-reporting-submission-CkiUg9j0.js.map} +1 -1
  103. package/dist/{runtime-transport-Dg7E0ROH.js → runtime-transport-CLpKUHk_.js} +5 -1
  104. package/dist/{runtime-transport-Dg7E0ROH.js.map → runtime-transport-CLpKUHk_.js.map} +1 -1
  105. package/dist/{sensitive-operation-credentials-Dr_neVvL.js → sensitive-operation-credentials-D9DHfCDf.js} +4 -4
  106. package/dist/{sensitive-operation-credentials-Dr_neVvL.js.map → sensitive-operation-credentials-D9DHfCDf.js.map} +1 -1
  107. package/dist/{service-CjVGm1FB.js → service-BoxFPDKp.js} +104 -37
  108. package/dist/service-BoxFPDKp.js.map +1 -0
  109. package/dist/{service-account-authorization-DiSsm3hB.js → service-account-authorization-MARMxBls.js} +5 -5
  110. package/dist/{service-account-authorization-DiSsm3hB.js.map → service-account-authorization-MARMxBls.js.map} +1 -1
  111. package/dist/{service-account-control-C3jIB8Pg.js → service-account-control-D0f6SaS2.js} +13 -13
  112. package/dist/{service-account-control-C3jIB8Pg.js.map → service-account-control-D0f6SaS2.js.map} +1 -1
  113. package/dist/{service-control-capabilities-Bd2t4hQ4.js → service-control-capabilities-C5lV5eqZ.js} +5 -5
  114. package/dist/{service-control-capabilities-Bd2t4hQ4.js.map → service-control-capabilities-C5lV5eqZ.js.map} +1 -1
  115. package/dist/{service-control-capabilities-IVIJRGI7.js → service-control-capabilities-DVnJWbBU.js} +1 -1
  116. package/dist/{state-YbqBm7wx.js → state-LIaPm3LW.js} +2 -2
  117. package/dist/{state-YbqBm7wx.js.map → state-LIaPm3LW.js.map} +1 -1
  118. package/dist/{updates-api-D4OvCDcm.js → updates-api-CV0uvAN1.js} +81 -77
  119. package/dist/updates-api-CV0uvAN1.js.map +1 -0
  120. package/dist/upgrade-Bi-kRFVX.js +3 -0
  121. package/dist/{upgrade-BWDsvax2.js → upgrade-C23MjDuG.js} +10 -10
  122. package/dist/{upgrade-BWDsvax2.js.map → upgrade-C23MjDuG.js.map} +1 -1
  123. package/dist/windows/openmeld-windows-process.exe +0 -0
  124. package/dist/{windows-user-task-CKb_u29X.js → windows-user-task-CR64LZEK.js} +3 -3
  125. package/dist/{windows-user-task-CKb_u29X.js.map → windows-user-task-CR64LZEK.js.map} +1 -1
  126. package/dist/{windows-user-task-zYK9uy2K.js → windows-user-task-Dr1wlrfz.js} +1 -1
  127. package/package.json +9 -9
  128. package/dist/auth-session-C9F7usbn.js +0 -3
  129. package/dist/channel-CFIRo4fR.js.map +0 -1
  130. package/dist/dist-CcuvAb_V.js +0 -34
  131. package/dist/entry-D-22_x6G.js.map +0 -1
  132. package/dist/lock-DP8d33p_.js.map +0 -1
  133. package/dist/prepare-provider-runtime-m0GVd1Za.js.map +0 -1
  134. package/dist/runtime-DDZRXE1m.js.map +0 -1
  135. package/dist/service-CjVGm1FB.js.map +0 -1
  136. package/dist/updates-api-D4OvCDcm.js.map +0 -1
  137. package/dist/upgrade-DUs1kUZ9.js +0 -3
@@ -1 +1 @@
1
- {"version":3,"file":"windows-user-task-CKb_u29X.js","names":[],"sources":["../src/local-service/lifecycle/windows-service-binary.ts","../src/local-service/lifecycle/windows-task-host.ts","../src/local-service/lifecycle/windows-user-task.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { createReadStream } from \"node:fs\";\nimport {\n copyFile,\n mkdir,\n mkdtemp,\n open,\n rename,\n rm,\n stat,\n} from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { pruneWindowsBinaryBundle } from \"@openmeld/adapter-core/windows-system\";\nimport { WINDOWS_PROCESS_HELPER_FILENAME } from \"@openmeld/schemas\";\nimport { daemonRuntimeBundlesPath } from \"../../config/daemon-state\";\nimport type { OpenMeldPathResolutionInput } from \"../../config/paths\";\nimport type { CliBinaryReleaseInfo } from \"../../config/version-state\";\nimport type { DaemonActiveBundleState } from \"./daemon-service-bundle\";\n\nconst FINGERPRINT_PATTERN = /^[0-9a-f]{64}$/u;\n\nexport function windowsMaintenanceBinaryPath(\n bundle: DaemonActiveBundleState,\n pathInput: OpenMeldPathResolutionInput = {}\n): string {\n if (\n !(\n bundle.sourceDistFingerprint &&\n FINGERPRINT_PATTERN.test(bundle.sourceDistFingerprint)\n )\n ) {\n throw new Error(\n \"OpenMeld maintenance needs a verified Windows Service bundle.\"\n );\n }\n return join(\n daemonRuntimeBundlesPath(pathInput),\n `maintenance-${bundle.sourceDistFingerprint}`,\n \"openmeld.exe\"\n );\n}\n\nexport async function prepareWindowsMaintenanceBinary(\n bundle: DaemonActiveBundleState,\n pathInput: OpenMeldPathResolutionInput = {}\n): Promise<string> {\n const target = windowsMaintenanceBinaryPath(bundle, pathInput);\n const expected = bundle.sourceDistFingerprint;\n if (\n (await hashBinaryServiceBundle(target, true).catch(() => null)) === expected\n ) {\n return target;\n }\n if (\n (await hashBinaryServiceBundle(bundle.sourceEntryScriptPath, true)) !==\n expected\n ) {\n throw new Error(\n \"The Windows maintenance source no longer matches its verified bundle.\"\n );\n }\n const directory = dirname(target);\n if (\n await stat(directory).catch((error: NodeJS.ErrnoException) => {\n if (error.code === \"ENOENT\") {\n return null;\n }\n throw error;\n })\n ) {\n const result = await pruneWindowsBinaryBundle(directory);\n if (result !== \"removed\" && result !== \"absent\") {\n throw new Error(\n \"The existing Windows maintenance copy is still in use or contains unrecognized files.\"\n );\n }\n }\n await mkdir(daemonRuntimeBundlesPath(pathInput), { recursive: true });\n const temporary = await mkdtemp(\n join(daemonRuntimeBundlesPath(pathInput), \".maintenance-\")\n );\n try {\n for (const name of [\"openmeld.exe\", WINDOWS_PROCESS_HELPER_FILENAME]) {\n await copyFile(\n name === \"openmeld.exe\"\n ? bundle.sourceEntryScriptPath\n : join(dirname(bundle.sourceEntryScriptPath), name),\n join(temporary, name)\n );\n }\n if (\n (await hashBinaryServiceBundle(join(temporary, \"openmeld.exe\"), true)) !==\n expected\n ) {\n throw new Error(\n \"The prepared Windows maintenance copy failed verification.\"\n );\n }\n await rename(temporary, directory);\n } finally {\n await rm(temporary, { recursive: true, force: true });\n }\n return target;\n}\n\n// Windows binary_v1 bundles contain two indivisible, independently signed files.\n// Keep one bundle fingerprint for inventory, update jobs, and maintenance copies.\nexport function expectedBinaryServiceFingerprint(\n release: CliBinaryReleaseInfo\n): string {\n if (!release.platform.startsWith(\"windows-\")) {\n return release.sha256.toLowerCase();\n }\n if (!release.windows) {\n throw new Error(\n \"The selected Windows Service has no native helper metadata.\"\n );\n }\n return fingerprint(release.sha256, release.windows.processHelper.sha256);\n}\n\nexport async function hashBinaryServiceBundle(\n executablePath: string,\n windows: boolean = process.platform === \"win32\"\n): Promise<string> {\n const executableHash = await hashFile(executablePath);\n return windows\n ? fingerprint(\n executableHash,\n await hashFile(\n join(dirname(executablePath), WINDOWS_PROCESS_HELPER_FILENAME)\n )\n )\n : executableHash;\n}\n\nfunction fingerprint(executableHash: string, helperHash: string): string {\n return createHash(\"sha256\")\n .update(\n JSON.stringify([executableHash.toLowerCase(), helperHash.toLowerCase()])\n )\n .digest(\"hex\");\n}\n\nasync function hashFile(file: string): Promise<string> {\n const hash = createHash(\"sha256\");\n for await (const chunk of createReadStream(file)) {\n hash.update(chunk);\n }\n return hash.digest(\"hex\");\n}\n\n/** A valid signature does not establish the required console-free PE subsystem. */\nexport async function verifyWindowsServiceSubsystem(\n file: string\n): Promise<void> {\n const handle = await open(file, \"r\");\n try {\n const dos = Buffer.alloc(64);\n const first = await handle.read(dos, 0, dos.length, 0);\n if (\n first.bytesRead !== dos.length ||\n dos.toString(\"ascii\", 0, 2) !== \"MZ\"\n ) {\n throw new Error(\"The Windows Service artifact is not a PE executable.\");\n }\n const header = Buffer.alloc(94);\n const second = await handle.read(\n header,\n 0,\n header.length,\n dos.readUInt32LE(0x3c)\n );\n if (\n second.bytesRead !== header.length ||\n header.toString(\"ascii\", 0, 4) !== \"PE\\0\\0\" ||\n header.readUInt16LE(4) !== 0x86_64 ||\n header.readUInt16LE(24 + 68) !== 2\n ) {\n throw new Error(\n \"The selected Windows Service must be a console-free x64 executable.\"\n );\n }\n } finally {\n await handle.close();\n }\n}\n","// Task Scheduler must start a Windows-subsystem executable, not a console\n// executable that hides its window after startup. Keep the existing encoded\n// PowerShell action as the command/environment/logging owner.\n// Windows PowerShell 5.1 compiles this fixed source during guarded installation;\n// no SDK, downloaded executable, WSH/VBScript, or administrator access is needed.\nexport const WINDOWS_TASK_HOST_SOURCE = String.raw`\nusing System;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Reflection;\nusing System.Text;\nusing System.Text.RegularExpressions;\n\npublic static class OpenMeldTaskHostV1 {\n public static int Main(string[] args) {\n string logPath = Assembly.GetExecutingAssembly().Location + \".log\";\n try {\n // Accept only the existing OpenMeld action, never an arbitrary executable\n // or a shell-interpolated command line. Base64 contains no quoting syntax.\n if (args.Length != 7 || args[0] != \"-NoLogo\" || args[1] != \"-NoProfile\" ||\n args[2] != \"-NonInteractive\" || args[3] != \"-WindowStyle\" ||\n args[4] != \"Hidden\" || args[5] != \"-EncodedCommand\" ||\n !Regex.IsMatch(args[6], @\"\\A[A-Za-z0-9+/]+={0,2}\\z\"))\n throw new ArgumentException(\"Invalid OpenMeld task arguments.\");\n Convert.FromBase64String(args[6]);\n var start = new ProcessStartInfo();\n start.FileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System),\n @\"WindowsPowerShell\\v1.0\\powershell.exe\");\n start.Arguments = String.Join(\" \", args);\n start.UseShellExecute = false;\n start.CreateNoWindow = true;\n start.RedirectStandardInput = true;\n start.RedirectStandardOutput = true;\n start.RedirectStandardError = true;\n using (var log = Stream.Synchronized(new FileStream(logPath, FileMode.Append,\n FileAccess.Write, FileShare.ReadWrite)))\n using (var child = new Process()) {\n child.StartInfo = start;\n child.Start();\n child.StandardInput.Close();\n var stdout = child.StandardOutput.BaseStream.CopyToAsync(log);\n var stderr = child.StandardError.BaseStream.CopyToAsync(log);\n // Do not detach or break away from Task Scheduler's process ownership.\n // The task remains running until the action completes, and restart-on-\n // failure still receives the action's real exit code.\n child.WaitForExit();\n stdout.GetAwaiter().GetResult();\n stderr.GetAwaiter().GetResult();\n return child.ExitCode;\n }\n } catch (Exception error) {\n try { File.AppendAllText(logPath, DateTime.UtcNow.ToString(\"o\") + \" \" +\n error.GetType().Name + \": \" + error.Message + Environment.NewLine, Encoding.UTF8); }\n catch { /* Task Scheduler still receives a nonzero result if logging fails. */ }\n return 1;\n }\n }\n}\n`;\n\n// Per-task, lane-owned path: updating the maintenance host cannot replace the\n// executable of a running main Service, or vice versa. Keep v1 stable; a future\n// host format must explicitly support migration from this path.\nexport const WINDOWS_TASK_HOST_SUFFIX = \".task-host-v1.exe\";\n\n// The caller has already verified identity and acquired the lifecycle grant.\n// Build beside the target and replace atomically, never overwrite a running\n// host or fall back to a flashing console when compilation is unavailable.\nexport const WINDOWS_TASK_HOST_INSTALL_SCRIPT = `\n$hostDirectory = [IO.Path]::GetDirectoryName($hostPath)\n$null = [IO.Directory]::CreateDirectory($hostDirectory)\n$temporaryHost = Join-Path $hostDirectory ([Guid]::NewGuid().ToString('N') + '.exe')\ntry {\n Add-Type -TypeDefinition @'\n${WINDOWS_TASK_HOST_SOURCE}\n'@ -OutputAssembly $temporaryHost -OutputType WindowsApplication -ErrorAction Stop\n if ($task -and $task.State -eq 4) { throw 'OpenMeld cannot replace a background task while it is running.' }\n if ([IO.File]::Exists($hostPath)) {\n # PowerShell coerces bare $null to an empty string for this .NET parameter.\n # Pass a real null backup path; an empty path breaks repeat setup/repair.\n [IO.File]::Replace($temporaryHost, $hostPath, [NullString]::Value)\n } else {\n [IO.File]::Move($temporaryHost, $hostPath)\n }\n} finally {\n if ([IO.File]::Exists($temporaryHost)) { [IO.File]::Delete($temporaryHost) }\n}\n`;\n","import { type ExecFileException, execFile } from \"node:child_process\";\nimport { normalizeCommandEnvironment } from \"@openmeld/adapter-core/process-environment\";\nimport {\n powerShellEncodedArguments,\n resolveWindowsPowerShellPath,\n} from \"@openmeld/adapter-core/windows-system\";\nimport {\n type WindowsUserTaskAction,\n type WindowsUserTaskRequest,\n windowsUserTaskActionSchema,\n windowsUserTaskRequestSchema,\n windowsUserTaskStatusSchema,\n windowsUserTaskStoredActionSchema,\n} from \"@openmeld/schemas\";\nimport { currentDaemonServiceLifecycleLock } from \"../../config/daemon-state\";\nimport {\n attachLockProcess,\n type OpenMeldLock,\n releaseLock,\n} from \"../../config/lock\";\nimport { verifyWindowsServiceSubsystem } from \"./windows-service-binary\";\nimport { readWindowsDirectTaskAction } from \"./windows-task-command\";\nimport {\n WINDOWS_TASK_HOST_INSTALL_SCRIPT,\n WINDOWS_TASK_HOST_SUFFIX,\n} from \"./windows-task-host\";\n\n// Task Scheduler runs in the signed-in user's session, with that user's tokens\n// and ordinary permissions. No password, elevation, or third-party service host.\n// Native COM contracts: learn.microsoft.com/windows/win32/taskschd/\nconst TASK_CONTROL = String.raw`\n$ErrorActionPreference = 'Stop'\n$ProgressPreference = 'SilentlyContinue'\n[Console]::OutputEncoding = New-Object System.Text.UTF8Encoding($false)\n$r = ConvertFrom-Json ([Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($env:OPENMELD_TASK_REQUEST)))\nif ($env:OPENMELD_TASK_GRANT_REQUIRED -eq '1' -and [Console]::In.ReadLine() -ne 'execute') { exit 125 }\n$env:OPENMELD_TASK_GRANT_REQUIRED = $null\n$sid = [Security.Principal.WindowsIdentity]::GetCurrent().User.Value\nif ($sid -in @('S-1-5-18','S-1-5-19','S-1-5-20')) { throw 'Run OpenMeld setup from your own Windows account, not a system account.' }\n$scheduler = New-Object -ComObject 'Schedule.Service'\n$scheduler.Connect()\n$folder = $scheduler.GetFolder('\\')\n$name = $r.name + '-' + $sid\n$hostPath = $r.legacyScript + '${WINDOWS_TASK_HOST_SUFFIX}'\n$runtimeRoot = [IO.Path]::GetDirectoryName($r.legacyScript)\nfunction Read-OwnedDirectAction($path, $arguments) {\n if ($arguments -notmatch '(?:^| )--openmeld-windows-task ([A-Za-z0-9+/=]+)$') { return $null }\n $c = ConvertFrom-Json ([Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($Matches[1])))\n $bundles = [IO.Path]::GetFullPath((Join-Path $runtimeRoot 'bundles')) + '\\'\n $fullPath = [IO.Path]::GetFullPath($path)\n if ($c.executable -ne $path -or !$fullPath.StartsWith($bundles, [StringComparison]::OrdinalIgnoreCase) -or [IO.Path]::GetFileName($path) -ne 'openmeld.exe' -or !$c.env.OPENMELD_HOME -or [IO.Path]::GetFullPath((Join-Path $c.env.OPENMELD_HOME 'runtime\\daemon')) -ne [IO.Path]::GetFullPath($runtimeRoot)) {\n throw 'The Windows task does not belong to this OpenMeld installation.'\n }\n return $c\n}\n$existingDirect = $null\n$task = $null\ntry { $task = $folder.GetTask($name) } catch {\n if ($_.Exception.GetBaseException().HResult -ne -2147024894) { throw }\n}\nif ($task) {\n $principal = $task.Definition.Principal\n $taskSid = $principal.UserId\n if ($taskSid -notmatch '^S-\\d-') { $taskSid = ([Security.Principal.NTAccount]$taskSid).Translate([Security.Principal.SecurityIdentifier]).Value }\n $actionPath = $task.Definition.Actions.Item(1).Path\n $existingDirect = Read-OwnedDirectAction $actionPath $task.Definition.Actions.Item(1).Arguments\n if ($taskSid -ne $sid -or $principal.LogonType -ne 3 -or $principal.RunLevel -ne 0 -or $task.Definition.Actions.Count -ne 1 -or (!$existingDirect -and $actionPath -ne (Join-Path $PSHOME 'powershell.exe') -and $actionPath -ne $hostPath)) {\n throw 'An existing OpenMeld task uses a different user or launch configuration. Resolve that installation before continuing.'\n }\n}\n# Migration only owns the exact legacy script in this lane. Never stop another\n# user's or an administrator-customized service merely because its name matches.\n$legacy = Get-CimInstance Win32_Service -Filter (\"Name='\" + $r.name.Replace(\"'\",\"''\") + \"'\")\nif ($legacy -and $legacy.PathName.Trim('\"') -ne $r.legacyScript) {\n throw 'An existing Windows service uses a different installation. Resolve that installation before continuing.'\n}\nswitch ($r.operation) {\n 'install' {\n if ($legacy -and $legacy.State -ne 'Stopped') { throw 'The previous OpenMeld Service must finish stopping before migration.' }\n $nextDirect = Read-OwnedDirectAction $r.executable $r.arguments\n # A running maintenance invocation keeps its immutable copy and lease. Only\n # subsequent invocations select the new copy. Main Service replacement still\n # requires the existing drain and stopped-state proof.\n $maintenanceUpdate = $r.periodic -and $existingDirect -and $nextDirect -and $existingDirect.args.Count -eq 2 -and $nextDirect.args.Count -eq 2 -and $existingDirect.args[0] -eq 'service' -and $existingDirect.args[1] -eq 'update-worker' -and $nextDirect.args[0] -eq 'service' -and $nextDirect.args[1] -eq 'update-worker'\n if ($task -and $task.State -eq 4 -and !$maintenanceUpdate) { throw 'OpenMeld cannot replace a background task while it is running.' }\n if (!$nextDirect) {\n if ($r.executable -ne (Join-Path $PSHOME 'powershell.exe')) { throw 'OpenMeld tasks require a verified background executable.' }\n ${WINDOWS_TASK_HOST_INSTALL_SCRIPT}\n }\n $definition = $scheduler.NewTask(0)\n $definition.RegistrationInfo.Description = 'OpenMeld background process for the signed-in user.'\n $definition.Principal.UserId = $sid\n $definition.Principal.LogonType = 3\n $definition.Principal.RunLevel = 0\n $definition.Settings.Enabled = ($null -eq $legacy)\n $definition.Settings.Hidden = $true\n $definition.Settings.AllowDemandStart = $true\n $definition.Settings.DisallowStartIfOnBatteries = $false\n $definition.Settings.StopIfGoingOnBatteries = $false\n $definition.Settings.RunOnlyIfNetworkAvailable = $false\n $definition.Settings.StartWhenAvailable = $true\n $definition.Settings.ExecutionTimeLimit = 'PT0S'\n $definition.Settings.MultipleInstances = 2\n $definition.Settings.RestartInterval = 'PT1M'\n $definition.Settings.RestartCount = 999\n $trigger = $definition.Triggers.Create(9)\n $trigger.UserId = $sid\n if ($r.periodic) {\n $timer = $definition.Triggers.Create(1)\n $timer.StartBoundary = (Get-Date).AddMinutes(1).ToString('yyyy-MM-ddTHH:mm:ss')\n $timer.Repetition.Interval = 'PT1H'\n }\n $action = $definition.Actions.Create(0)\n $action.Path = $(if ($nextDirect) { $r.executable } else { $hostPath })\n $action.Arguments = $r.arguments\n $action.WorkingDirectory = $r.workingDirectory\n $task = $folder.RegisterTaskDefinition($name, $definition, 6, $sid, $null, 3, $null)\n if ($legacy) {\n try {\n $deleted = Invoke-CimMethod -InputObject $legacy -MethodName Delete\n if ($deleted.ReturnValue -ne 0) { throw ('Cannot remove the old Windows Service (code ' + $deleted.ReturnValue + '). An administrator must remove the old registration before setup can continue.') }\n } catch {\n $folder.DeleteTask($name,0)\n throw\n }\n $task.Enabled = $true\n }\n $legacy = $null\n }\n 'start' { if (!$task) { throw 'OpenMeld background task is not installed. Run setup to repair it.' }; $null = $task.Run($null) }\n 'enable' { if ($task) { $task.Enabled = $true } }\n 'disable' { if ($task) { $task.Enabled = $false }; if ($legacy) { $result = Invoke-CimMethod -InputObject $legacy -MethodName ChangeStartMode -Arguments @{StartMode='Manual'}; if ($result.ReturnValue -ne 0) { throw 'Cannot disable the old Windows Service. Administrator assistance is required.' } } }\n 'stop' {\n if ($task) { $task.Stop(0) }\n if ($legacy -and $legacy.State -ne 'Stopped') {\n $result = Invoke-CimMethod -InputObject $legacy -MethodName StopService\n if ($result.ReturnValue -notin @(0,6)) { throw 'Cannot stop the old Windows Service. Administrator assistance is required.' }\n }\n }\n 'uninstall' {\n if ($task) { $task.Stop(0); $folder.DeleteTask($name,0); $task = $null }\n if ($legacy) {\n if ($legacy.State -ne 'Stopped') { throw 'The old OpenMeld Service is still running.' }\n $result = Invoke-CimMethod -InputObject $legacy -MethodName Delete\n if ($result.ReturnValue -ne 0) { throw 'Cannot remove the old Windows Service. Administrator assistance is required.' }\n $legacy = $null\n }\n }\n 'status' { }\n default { throw 'Unknown OpenMeld task operation.' }\n}\n@{ installed=($null -ne $task -or $null -ne $legacy); running=($(if ($task) { $task.State -eq 4 } else { $legacy -and $legacy.State -ne 'Stopped' })); enabled=($(if ($task) { [bool]$task.Enabled } else { $legacy -and $legacy.StartMode -eq 'Auto' })); legacy=($null -ne $legacy); actionArguments=($(if ($task) { $task.Definition.Actions.Item(1).Arguments } else { $null })) } | ConvertTo-Json -Compress\n`;\n\nexport function windowsPowerShellPath(): string {\n return resolveWindowsPowerShellPath();\n}\n\nexport function windowsTaskActionArguments(\n input: WindowsUserTaskAction\n): string {\n // TypeScript's structural type does not strip fields from a spread spec.\n // Project and validate the actual wire value before encoding it.\n const action = windowsUserTaskActionSchema.parse({\n executable: input.executable,\n args: input.args,\n env: input.env,\n logPath: input.logPath,\n });\n const data = Buffer.from(JSON.stringify(action)).toString(\"base64\");\n const script = String.raw`\n$ErrorActionPreference = 'Stop'\n$c = ConvertFrom-Json ([Text.Encoding]::UTF8.GetString([Convert]::FromBase64String('${data}')))\nfunction Quote-ProcessArgument([string]$value) {\n '\"' + [regex]::Replace([regex]::Replace($value, '(\\\\*)\"', '$1$1\\\"'), '(\\\\+)$', '$1$1') + '\"'\n}\n$start = New-Object Diagnostics.ProcessStartInfo\n$start.FileName = $c.executable\n$start.Arguments = (@($c.args | ForEach-Object { Quote-ProcessArgument $_ }) -join ' ')\n$start.UseShellExecute = $false\n$start.CreateNoWindow = $true\n$start.RedirectStandardOutput = $true\n$start.RedirectStandardError = $true\nforeach ($property in $c.env.PSObject.Properties) { $start.EnvironmentVariables[$property.Name] = [string]$property.Value }\n$log = [IO.Stream]::Synchronized([IO.File]::Open($c.logPath, [IO.FileMode]::Append, [IO.FileAccess]::Write, [IO.FileShare]::ReadWrite))\n$process = New-Object Diagnostics.Process\n$process.StartInfo = $start\ntry {\n $null = $process.Start()\n $stdout = $process.StandardOutput.BaseStream.CopyToAsync($log)\n $stderr = $process.StandardError.BaseStream.CopyToAsync($log)\n $process.WaitForExit()\n $stdout.GetAwaiter().GetResult()\n $stderr.GetAwaiter().GetResult()\n $exitCode = $process.ExitCode\n} finally {\n $log.Dispose()\n $process.Dispose()\n}\nexit $exitCode\n`;\n return `-NoLogo -NoProfile -NonInteractive -WindowStyle Hidden -EncodedCommand ${Buffer.from(script, \"utf16le\").toString(\"base64\")}`;\n}\n\nconst ENCODED_ACTION_PATTERN = /-EncodedCommand ([A-Za-z0-9+/=]+)$/u;\nconst ACTION_DATA_PATTERN = /FromBase64String\\('([A-Za-z0-9+/=]+)'\\)/u;\n\nexport function readWindowsTaskAction(argumentsText: string) {\n const direct = readWindowsDirectTaskAction(argumentsText);\n if (direct) {\n return direct;\n }\n const encoded = argumentsText.match(ENCODED_ACTION_PATTERN)?.[1];\n const data =\n encoded &&\n Buffer.from(encoded, \"base64\")\n .toString(\"utf16le\")\n .match(ACTION_DATA_PATTERN)?.[1];\n if (!data) {\n throw new Error(\n \"Windows task does not contain an OpenMeld launch command.\"\n );\n }\n const action = windowsUserTaskStoredActionSchema.safeParse(\n JSON.parse(Buffer.from(data, \"base64\").toString(\"utf8\"))\n );\n if (!action.success) {\n throw new Error(\n \"Windows task contains an invalid OpenMeld launch command.\"\n );\n }\n return action.data;\n}\n\nexport async function runWindowsUserTask(\n request: WindowsUserTaskRequest\n): Promise<{\n installed: boolean;\n running: boolean;\n enabled: boolean;\n legacy: boolean;\n actionArguments: string | null;\n}> {\n const lock = currentDaemonServiceLifecycleLock();\n if (request.operation === \"install\" && request.arguments) {\n const direct = readWindowsDirectTaskAction(request.arguments);\n if (direct) {\n if (request.executable !== direct.executable) {\n throw new Error(\n \"The Windows task executable does not match its launch envelope.\"\n );\n }\n await verifyWindowsServiceSubsystem(direct.executable);\n }\n }\n const payload = Buffer.from(\n JSON.stringify(windowsUserTaskRequestSchema.parse(request))\n ).toString(\"base64\");\n let finish!: (value: {\n error: ExecFileException | null;\n stdout: string;\n }) => void;\n const completed = new Promise<{\n error: ExecFileException | null;\n stdout: string;\n }>((resolve) => {\n finish = resolve;\n });\n const child = execFile(\n windowsPowerShellPath(),\n powerShellEncodedArguments(TASK_CONTROL),\n {\n encoding: \"utf8\",\n windowsHide: true,\n timeout: 30_000,\n maxBuffer: 1024 * 1024,\n env: {\n ...normalizeCommandEnvironment(process.env),\n OPENMELD_TASK_REQUEST: payload,\n OPENMELD_TASK_GRANT_REQUIRED: lock ? \"1\" : \"0\",\n },\n },\n (error, stdout) => finish({ error, stdout })\n );\n // EOF before the grant prevents the COM operation. Once granted, this exact\n // PowerShell instance retains the existing lifecycle fence if its CLI dies.\n // This is not a Wake Job: the independently scheduled Service must survive it.\n child.stdin?.on(\"error\", () => undefined);\n let participant: OpenMeldLock | undefined;\n try {\n if (lock) {\n if (!child.pid) {\n throw new Error(\"Windows task control did not establish a process.\");\n }\n participant = await attachLockProcess(lock, child.pid);\n }\n child.stdin?.end(lock ? \"execute\\n\" : undefined);\n const result = await completed;\n if (result.error) {\n throw result.error;\n }\n const status = windowsUserTaskStatusSchema.safeParse(\n JSON.parse(result.stdout.trim())\n );\n if (!status.success) {\n throw new Error(\"Windows returned an invalid OpenMeld task status.\");\n }\n return status.data;\n } finally {\n child.stdin?.destroy();\n if (child.exitCode === null && child.signalCode === null) {\n child.kill();\n }\n await completed;\n if (participant) {\n await releaseLock(participant);\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"windows-user-task-CR64LZEK.js","names":[],"sources":["../src/local-service/lifecycle/windows-service-binary.ts","../src/local-service/lifecycle/windows-task-host.ts","../src/local-service/lifecycle/windows-user-task.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { createReadStream } from \"node:fs\";\nimport {\n copyFile,\n mkdir,\n mkdtemp,\n open,\n rename,\n rm,\n stat,\n} from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { pruneWindowsBinaryBundle } from \"@openmeld/adapter-core/windows-system\";\nimport { WINDOWS_PROCESS_HELPER_FILENAME } from \"@openmeld/schemas\";\nimport { daemonRuntimeBundlesPath } from \"../../config/daemon-state\";\nimport type { OpenMeldPathResolutionInput } from \"../../config/paths\";\nimport type { CliBinaryReleaseInfo } from \"../../config/version-state\";\nimport type { DaemonActiveBundleState } from \"./daemon-service-bundle\";\n\nconst FINGERPRINT_PATTERN = /^[0-9a-f]{64}$/u;\n\nexport function windowsMaintenanceBinaryPath(\n bundle: DaemonActiveBundleState,\n pathInput: OpenMeldPathResolutionInput = {}\n): string {\n if (\n !(\n bundle.sourceDistFingerprint &&\n FINGERPRINT_PATTERN.test(bundle.sourceDistFingerprint)\n )\n ) {\n throw new Error(\n \"OpenMeld maintenance needs a verified Windows Service bundle.\"\n );\n }\n return join(\n daemonRuntimeBundlesPath(pathInput),\n `maintenance-${bundle.sourceDistFingerprint}`,\n \"openmeld.exe\"\n );\n}\n\nexport async function prepareWindowsMaintenanceBinary(\n bundle: DaemonActiveBundleState,\n pathInput: OpenMeldPathResolutionInput = {}\n): Promise<string> {\n const target = windowsMaintenanceBinaryPath(bundle, pathInput);\n const expected = bundle.sourceDistFingerprint;\n if (\n (await hashBinaryServiceBundle(target, true).catch(() => null)) === expected\n ) {\n return target;\n }\n if (\n (await hashBinaryServiceBundle(bundle.sourceEntryScriptPath, true)) !==\n expected\n ) {\n throw new Error(\n \"The Windows maintenance source no longer matches its verified bundle.\"\n );\n }\n const directory = dirname(target);\n if (\n await stat(directory).catch((error: NodeJS.ErrnoException) => {\n if (error.code === \"ENOENT\") {\n return null;\n }\n throw error;\n })\n ) {\n const result = await pruneWindowsBinaryBundle(directory);\n if (result !== \"removed\" && result !== \"absent\") {\n throw new Error(\n \"The existing Windows maintenance copy is still in use or contains unrecognized files.\"\n );\n }\n }\n await mkdir(daemonRuntimeBundlesPath(pathInput), { recursive: true });\n const temporary = await mkdtemp(\n join(daemonRuntimeBundlesPath(pathInput), \".maintenance-\")\n );\n try {\n for (const name of [\"openmeld.exe\", WINDOWS_PROCESS_HELPER_FILENAME]) {\n await copyFile(\n name === \"openmeld.exe\"\n ? bundle.sourceEntryScriptPath\n : join(dirname(bundle.sourceEntryScriptPath), name),\n join(temporary, name)\n );\n }\n if (\n (await hashBinaryServiceBundle(join(temporary, \"openmeld.exe\"), true)) !==\n expected\n ) {\n throw new Error(\n \"The prepared Windows maintenance copy failed verification.\"\n );\n }\n await rename(temporary, directory);\n } finally {\n await rm(temporary, { recursive: true, force: true });\n }\n return target;\n}\n\n// Windows binary_v1 bundles contain two indivisible, independently signed files.\n// Keep one bundle fingerprint for inventory, update jobs, and maintenance copies.\nexport function expectedBinaryServiceFingerprint(\n release: CliBinaryReleaseInfo\n): string {\n if (!release.platform.startsWith(\"windows-\")) {\n return release.sha256.toLowerCase();\n }\n if (!release.windows) {\n throw new Error(\n \"The selected Windows Service has no native helper metadata.\"\n );\n }\n return fingerprint(release.sha256, release.windows.processHelper.sha256);\n}\n\nexport async function hashBinaryServiceBundle(\n executablePath: string,\n windows: boolean = process.platform === \"win32\"\n): Promise<string> {\n const executableHash = await hashFile(executablePath);\n return windows\n ? fingerprint(\n executableHash,\n await hashFile(\n join(dirname(executablePath), WINDOWS_PROCESS_HELPER_FILENAME)\n )\n )\n : executableHash;\n}\n\nfunction fingerprint(executableHash: string, helperHash: string): string {\n return createHash(\"sha256\")\n .update(\n JSON.stringify([executableHash.toLowerCase(), helperHash.toLowerCase()])\n )\n .digest(\"hex\");\n}\n\nasync function hashFile(file: string): Promise<string> {\n const hash = createHash(\"sha256\");\n for await (const chunk of createReadStream(file)) {\n hash.update(chunk);\n }\n return hash.digest(\"hex\");\n}\n\n/** A valid signature does not establish the required console-free PE subsystem. */\nexport async function verifyWindowsServiceSubsystem(\n file: string\n): Promise<void> {\n const handle = await open(file, \"r\");\n try {\n const dos = Buffer.alloc(64);\n const first = await handle.read(dos, 0, dos.length, 0);\n if (\n first.bytesRead !== dos.length ||\n dos.toString(\"ascii\", 0, 2) !== \"MZ\"\n ) {\n throw new Error(\"The Windows Service artifact is not a PE executable.\");\n }\n const header = Buffer.alloc(94);\n const second = await handle.read(\n header,\n 0,\n header.length,\n dos.readUInt32LE(0x3c)\n );\n if (\n second.bytesRead !== header.length ||\n header.toString(\"ascii\", 0, 4) !== \"PE\\0\\0\" ||\n header.readUInt16LE(4) !== 0x86_64 ||\n header.readUInt16LE(24 + 68) !== 2\n ) {\n throw new Error(\n \"The selected Windows Service must be a console-free x64 executable.\"\n );\n }\n } finally {\n await handle.close();\n }\n}\n","// Task Scheduler must start a Windows-subsystem executable, not a console\n// executable that hides its window after startup. Keep the existing encoded\n// PowerShell action as the command/environment/logging owner.\n// Windows PowerShell 5.1 compiles this fixed source during guarded installation;\n// no SDK, downloaded executable, WSH/VBScript, or administrator access is needed.\nexport const WINDOWS_TASK_HOST_SOURCE = String.raw`\nusing System;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Reflection;\nusing System.Text;\nusing System.Text.RegularExpressions;\n\npublic static class OpenMeldTaskHostV1 {\n public static int Main(string[] args) {\n string logPath = Assembly.GetExecutingAssembly().Location + \".log\";\n try {\n // Accept only the existing OpenMeld action, never an arbitrary executable\n // or a shell-interpolated command line. Base64 contains no quoting syntax.\n if (args.Length != 7 || args[0] != \"-NoLogo\" || args[1] != \"-NoProfile\" ||\n args[2] != \"-NonInteractive\" || args[3] != \"-WindowStyle\" ||\n args[4] != \"Hidden\" || args[5] != \"-EncodedCommand\" ||\n !Regex.IsMatch(args[6], @\"\\A[A-Za-z0-9+/]+={0,2}\\z\"))\n throw new ArgumentException(\"Invalid OpenMeld task arguments.\");\n Convert.FromBase64String(args[6]);\n var start = new ProcessStartInfo();\n start.FileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System),\n @\"WindowsPowerShell\\v1.0\\powershell.exe\");\n start.Arguments = String.Join(\" \", args);\n start.UseShellExecute = false;\n start.CreateNoWindow = true;\n start.RedirectStandardInput = true;\n start.RedirectStandardOutput = true;\n start.RedirectStandardError = true;\n using (var log = Stream.Synchronized(new FileStream(logPath, FileMode.Append,\n FileAccess.Write, FileShare.ReadWrite)))\n using (var child = new Process()) {\n child.StartInfo = start;\n child.Start();\n child.StandardInput.Close();\n var stdout = child.StandardOutput.BaseStream.CopyToAsync(log);\n var stderr = child.StandardError.BaseStream.CopyToAsync(log);\n // Do not detach or break away from Task Scheduler's process ownership.\n // The task remains running until the action completes, and restart-on-\n // failure still receives the action's real exit code.\n child.WaitForExit();\n stdout.GetAwaiter().GetResult();\n stderr.GetAwaiter().GetResult();\n return child.ExitCode;\n }\n } catch (Exception error) {\n try { File.AppendAllText(logPath, DateTime.UtcNow.ToString(\"o\") + \" \" +\n error.GetType().Name + \": \" + error.Message + Environment.NewLine, Encoding.UTF8); }\n catch { /* Task Scheduler still receives a nonzero result if logging fails. */ }\n return 1;\n }\n }\n}\n`;\n\n// Per-task, lane-owned path: updating the maintenance host cannot replace the\n// executable of a running main Service, or vice versa. Keep v1 stable; a future\n// host format must explicitly support migration from this path.\nexport const WINDOWS_TASK_HOST_SUFFIX = \".task-host-v1.exe\";\n\n// The caller has already verified identity and acquired the lifecycle grant.\n// Build beside the target and replace atomically, never overwrite a running\n// host or fall back to a flashing console when compilation is unavailable.\nexport const WINDOWS_TASK_HOST_INSTALL_SCRIPT = `\n$hostDirectory = [IO.Path]::GetDirectoryName($hostPath)\n$null = [IO.Directory]::CreateDirectory($hostDirectory)\n$temporaryHost = Join-Path $hostDirectory ([Guid]::NewGuid().ToString('N') + '.exe')\ntry {\n Add-Type -TypeDefinition @'\n${WINDOWS_TASK_HOST_SOURCE}\n'@ -OutputAssembly $temporaryHost -OutputType WindowsApplication -ErrorAction Stop\n if ($task -and $task.State -eq 4) { throw 'OpenMeld cannot replace a background task while it is running.' }\n if ([IO.File]::Exists($hostPath)) {\n # PowerShell coerces bare $null to an empty string for this .NET parameter.\n # Pass a real null backup path; an empty path breaks repeat setup/repair.\n [IO.File]::Replace($temporaryHost, $hostPath, [NullString]::Value)\n } else {\n [IO.File]::Move($temporaryHost, $hostPath)\n }\n} finally {\n if ([IO.File]::Exists($temporaryHost)) { [IO.File]::Delete($temporaryHost) }\n}\n`;\n","import { type ExecFileException, execFile } from \"node:child_process\";\nimport { normalizeCommandEnvironment } from \"@openmeld/adapter-core/process-environment\";\nimport {\n powerShellEncodedArguments,\n resolveWindowsPowerShellPath,\n} from \"@openmeld/adapter-core/windows-system\";\nimport {\n type WindowsUserTaskAction,\n type WindowsUserTaskRequest,\n windowsUserTaskActionSchema,\n windowsUserTaskRequestSchema,\n windowsUserTaskStatusSchema,\n windowsUserTaskStoredActionSchema,\n} from \"@openmeld/schemas\";\nimport { currentDaemonServiceLifecycleLock } from \"../../config/daemon-state\";\nimport {\n attachLockProcess,\n type OpenMeldLock,\n releaseLock,\n} from \"../../config/lock\";\nimport { verifyWindowsServiceSubsystem } from \"./windows-service-binary\";\nimport { readWindowsDirectTaskAction } from \"./windows-task-command\";\nimport {\n WINDOWS_TASK_HOST_INSTALL_SCRIPT,\n WINDOWS_TASK_HOST_SUFFIX,\n} from \"./windows-task-host\";\n\n// Task Scheduler runs in the signed-in user's session, with that user's tokens\n// and ordinary permissions. No password, elevation, or third-party service host.\n// Native COM contracts: learn.microsoft.com/windows/win32/taskschd/\nconst TASK_CONTROL = String.raw`\n$ErrorActionPreference = 'Stop'\n$ProgressPreference = 'SilentlyContinue'\n[Console]::OutputEncoding = New-Object System.Text.UTF8Encoding($false)\n$r = ConvertFrom-Json ([Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($env:OPENMELD_TASK_REQUEST)))\nif ($env:OPENMELD_TASK_GRANT_REQUIRED -eq '1' -and [Console]::In.ReadLine() -ne 'execute') { exit 125 }\n$env:OPENMELD_TASK_GRANT_REQUIRED = $null\n$sid = [Security.Principal.WindowsIdentity]::GetCurrent().User.Value\nif ($sid -in @('S-1-5-18','S-1-5-19','S-1-5-20')) { throw 'Run OpenMeld setup from your own Windows account, not a system account.' }\n$scheduler = New-Object -ComObject 'Schedule.Service'\n$scheduler.Connect()\n$folder = $scheduler.GetFolder('\\')\n$name = $r.name + '-' + $sid\n$hostPath = $r.legacyScript + '${WINDOWS_TASK_HOST_SUFFIX}'\n$runtimeRoot = [IO.Path]::GetDirectoryName($r.legacyScript)\nfunction Read-OwnedDirectAction($path, $arguments) {\n if ($arguments -notmatch '(?:^| )--openmeld-windows-task ([A-Za-z0-9+/=]+)$') { return $null }\n $c = ConvertFrom-Json ([Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($Matches[1])))\n $bundles = [IO.Path]::GetFullPath((Join-Path $runtimeRoot 'bundles')) + '\\'\n $fullPath = [IO.Path]::GetFullPath($path)\n if ($c.executable -ne $path -or !$fullPath.StartsWith($bundles, [StringComparison]::OrdinalIgnoreCase) -or [IO.Path]::GetFileName($path) -ne 'openmeld.exe' -or !$c.env.OPENMELD_HOME -or [IO.Path]::GetFullPath((Join-Path $c.env.OPENMELD_HOME 'runtime\\daemon')) -ne [IO.Path]::GetFullPath($runtimeRoot)) {\n throw 'The Windows task does not belong to this OpenMeld installation.'\n }\n return $c\n}\n$existingDirect = $null\n$task = $null\ntry { $task = $folder.GetTask($name) } catch {\n if ($_.Exception.GetBaseException().HResult -ne -2147024894) { throw }\n}\nif ($task) {\n $principal = $task.Definition.Principal\n $taskSid = $principal.UserId\n if ($taskSid -notmatch '^S-\\d-') { $taskSid = ([Security.Principal.NTAccount]$taskSid).Translate([Security.Principal.SecurityIdentifier]).Value }\n $actionPath = $task.Definition.Actions.Item(1).Path\n $existingDirect = Read-OwnedDirectAction $actionPath $task.Definition.Actions.Item(1).Arguments\n if ($taskSid -ne $sid -or $principal.LogonType -ne 3 -or $principal.RunLevel -ne 0 -or $task.Definition.Actions.Count -ne 1 -or (!$existingDirect -and $actionPath -ne (Join-Path $PSHOME 'powershell.exe') -and $actionPath -ne $hostPath)) {\n throw 'An existing OpenMeld task uses a different user or launch configuration. Resolve that installation before continuing.'\n }\n}\n# Migration only owns the exact legacy script in this lane. Never stop another\n# user's or an administrator-customized service merely because its name matches.\n$legacy = Get-CimInstance Win32_Service -Filter (\"Name='\" + $r.name.Replace(\"'\",\"''\") + \"'\")\nif ($legacy -and $legacy.PathName.Trim('\"') -ne $r.legacyScript) {\n throw 'An existing Windows service uses a different installation. Resolve that installation before continuing.'\n}\nswitch ($r.operation) {\n 'install' {\n if ($legacy -and $legacy.State -ne 'Stopped') { throw 'The previous OpenMeld Service must finish stopping before migration.' }\n $nextDirect = Read-OwnedDirectAction $r.executable $r.arguments\n # A running maintenance invocation keeps its immutable copy and lease. Only\n # subsequent invocations select the new copy. Main Service replacement still\n # requires the existing drain and stopped-state proof.\n $maintenanceUpdate = $r.periodic -and $existingDirect -and $nextDirect -and $existingDirect.args.Count -eq 2 -and $nextDirect.args.Count -eq 2 -and $existingDirect.args[0] -eq 'service' -and $existingDirect.args[1] -eq 'update-worker' -and $nextDirect.args[0] -eq 'service' -and $nextDirect.args[1] -eq 'update-worker'\n if ($task -and $task.State -eq 4 -and !$maintenanceUpdate) { throw 'OpenMeld cannot replace a background task while it is running.' }\n if (!$nextDirect) {\n if ($r.executable -ne (Join-Path $PSHOME 'powershell.exe')) { throw 'OpenMeld tasks require a verified background executable.' }\n ${WINDOWS_TASK_HOST_INSTALL_SCRIPT}\n }\n $definition = $scheduler.NewTask(0)\n $definition.RegistrationInfo.Description = 'OpenMeld background process for the signed-in user.'\n $definition.Principal.UserId = $sid\n $definition.Principal.LogonType = 3\n $definition.Principal.RunLevel = 0\n $definition.Settings.Enabled = ($null -eq $legacy)\n $definition.Settings.Hidden = $true\n $definition.Settings.AllowDemandStart = $true\n $definition.Settings.DisallowStartIfOnBatteries = $false\n $definition.Settings.StopIfGoingOnBatteries = $false\n $definition.Settings.RunOnlyIfNetworkAvailable = $false\n $definition.Settings.StartWhenAvailable = $true\n $definition.Settings.ExecutionTimeLimit = 'PT0S'\n $definition.Settings.MultipleInstances = 2\n $definition.Settings.RestartInterval = 'PT1M'\n $definition.Settings.RestartCount = 999\n $trigger = $definition.Triggers.Create(9)\n $trigger.UserId = $sid\n if ($r.periodic) {\n $timer = $definition.Triggers.Create(1)\n $timer.StartBoundary = (Get-Date).AddMinutes(1).ToString('yyyy-MM-ddTHH:mm:ss')\n $timer.Repetition.Interval = 'PT1H'\n }\n $action = $definition.Actions.Create(0)\n $action.Path = $(if ($nextDirect) { $r.executable } else { $hostPath })\n $action.Arguments = $r.arguments\n $action.WorkingDirectory = $r.workingDirectory\n $task = $folder.RegisterTaskDefinition($name, $definition, 6, $sid, $null, 3, $null)\n if ($legacy) {\n try {\n $deleted = Invoke-CimMethod -InputObject $legacy -MethodName Delete\n if ($deleted.ReturnValue -ne 0) { throw ('Cannot remove the old Windows Service (code ' + $deleted.ReturnValue + '). An administrator must remove the old registration before setup can continue.') }\n } catch {\n $folder.DeleteTask($name,0)\n throw\n }\n $task.Enabled = $true\n }\n $legacy = $null\n }\n 'start' { if (!$task) { throw 'OpenMeld background task is not installed. Run setup to repair it.' }; $null = $task.Run($null) }\n 'enable' { if ($task) { $task.Enabled = $true } }\n 'disable' { if ($task) { $task.Enabled = $false }; if ($legacy) { $result = Invoke-CimMethod -InputObject $legacy -MethodName ChangeStartMode -Arguments @{StartMode='Manual'}; if ($result.ReturnValue -ne 0) { throw 'Cannot disable the old Windows Service. Administrator assistance is required.' } } }\n 'stop' {\n if ($task) { $task.Stop(0) }\n if ($legacy -and $legacy.State -ne 'Stopped') {\n $result = Invoke-CimMethod -InputObject $legacy -MethodName StopService\n if ($result.ReturnValue -notin @(0,6)) { throw 'Cannot stop the old Windows Service. Administrator assistance is required.' }\n }\n }\n 'uninstall' {\n if ($task) { $task.Stop(0); $folder.DeleteTask($name,0); $task = $null }\n if ($legacy) {\n if ($legacy.State -ne 'Stopped') { throw 'The old OpenMeld Service is still running.' }\n $result = Invoke-CimMethod -InputObject $legacy -MethodName Delete\n if ($result.ReturnValue -ne 0) { throw 'Cannot remove the old Windows Service. Administrator assistance is required.' }\n $legacy = $null\n }\n }\n 'status' { }\n default { throw 'Unknown OpenMeld task operation.' }\n}\n@{ installed=($null -ne $task -or $null -ne $legacy); running=($(if ($task) { $task.State -eq 4 } else { $legacy -and $legacy.State -ne 'Stopped' })); enabled=($(if ($task) { [bool]$task.Enabled } else { $legacy -and $legacy.StartMode -eq 'Auto' })); legacy=($null -ne $legacy); actionArguments=($(if ($task) { $task.Definition.Actions.Item(1).Arguments } else { $null })) } | ConvertTo-Json -Compress\n`;\n\nexport function windowsPowerShellPath(): string {\n return resolveWindowsPowerShellPath();\n}\n\nexport function windowsTaskActionArguments(\n input: WindowsUserTaskAction\n): string {\n // TypeScript's structural type does not strip fields from a spread spec.\n // Project and validate the actual wire value before encoding it.\n const action = windowsUserTaskActionSchema.parse({\n executable: input.executable,\n args: input.args,\n env: input.env,\n logPath: input.logPath,\n });\n const data = Buffer.from(JSON.stringify(action)).toString(\"base64\");\n const script = String.raw`\n$ErrorActionPreference = 'Stop'\n$c = ConvertFrom-Json ([Text.Encoding]::UTF8.GetString([Convert]::FromBase64String('${data}')))\nfunction Quote-ProcessArgument([string]$value) {\n '\"' + [regex]::Replace([regex]::Replace($value, '(\\\\*)\"', '$1$1\\\"'), '(\\\\+)$', '$1$1') + '\"'\n}\n$start = New-Object Diagnostics.ProcessStartInfo\n$start.FileName = $c.executable\n$start.Arguments = (@($c.args | ForEach-Object { Quote-ProcessArgument $_ }) -join ' ')\n$start.UseShellExecute = $false\n$start.CreateNoWindow = $true\n$start.RedirectStandardOutput = $true\n$start.RedirectStandardError = $true\nforeach ($property in $c.env.PSObject.Properties) { $start.EnvironmentVariables[$property.Name] = [string]$property.Value }\n$log = [IO.Stream]::Synchronized([IO.File]::Open($c.logPath, [IO.FileMode]::Append, [IO.FileAccess]::Write, [IO.FileShare]::ReadWrite))\n$process = New-Object Diagnostics.Process\n$process.StartInfo = $start\ntry {\n $null = $process.Start()\n $stdout = $process.StandardOutput.BaseStream.CopyToAsync($log)\n $stderr = $process.StandardError.BaseStream.CopyToAsync($log)\n $process.WaitForExit()\n $stdout.GetAwaiter().GetResult()\n $stderr.GetAwaiter().GetResult()\n $exitCode = $process.ExitCode\n} finally {\n $log.Dispose()\n $process.Dispose()\n}\nexit $exitCode\n`;\n return `-NoLogo -NoProfile -NonInteractive -WindowStyle Hidden -EncodedCommand ${Buffer.from(script, \"utf16le\").toString(\"base64\")}`;\n}\n\nconst ENCODED_ACTION_PATTERN = /-EncodedCommand ([A-Za-z0-9+/=]+)$/u;\nconst ACTION_DATA_PATTERN = /FromBase64String\\('([A-Za-z0-9+/=]+)'\\)/u;\n\nexport function readWindowsTaskAction(argumentsText: string) {\n const direct = readWindowsDirectTaskAction(argumentsText);\n if (direct) {\n return direct;\n }\n const encoded = argumentsText.match(ENCODED_ACTION_PATTERN)?.[1];\n const data =\n encoded &&\n Buffer.from(encoded, \"base64\")\n .toString(\"utf16le\")\n .match(ACTION_DATA_PATTERN)?.[1];\n if (!data) {\n throw new Error(\n \"Windows task does not contain an OpenMeld launch command.\"\n );\n }\n const action = windowsUserTaskStoredActionSchema.safeParse(\n JSON.parse(Buffer.from(data, \"base64\").toString(\"utf8\"))\n );\n if (!action.success) {\n throw new Error(\n \"Windows task contains an invalid OpenMeld launch command.\"\n );\n }\n return action.data;\n}\n\nexport async function runWindowsUserTask(\n request: WindowsUserTaskRequest\n): Promise<{\n installed: boolean;\n running: boolean;\n enabled: boolean;\n legacy: boolean;\n actionArguments: string | null;\n}> {\n const lock = currentDaemonServiceLifecycleLock();\n if (request.operation === \"install\" && request.arguments) {\n const direct = readWindowsDirectTaskAction(request.arguments);\n if (direct) {\n if (request.executable !== direct.executable) {\n throw new Error(\n \"The Windows task executable does not match its launch envelope.\"\n );\n }\n await verifyWindowsServiceSubsystem(direct.executable);\n }\n }\n const payload = Buffer.from(\n JSON.stringify(windowsUserTaskRequestSchema.parse(request))\n ).toString(\"base64\");\n let finish!: (value: {\n error: ExecFileException | null;\n stdout: string;\n }) => void;\n const completed = new Promise<{\n error: ExecFileException | null;\n stdout: string;\n }>((resolve) => {\n finish = resolve;\n });\n const child = execFile(\n windowsPowerShellPath(),\n powerShellEncodedArguments(TASK_CONTROL),\n {\n encoding: \"utf8\",\n windowsHide: true,\n timeout: 30_000,\n maxBuffer: 1024 * 1024,\n env: {\n ...normalizeCommandEnvironment(process.env),\n OPENMELD_TASK_REQUEST: payload,\n OPENMELD_TASK_GRANT_REQUIRED: lock ? \"1\" : \"0\",\n },\n },\n (error, stdout) => finish({ error, stdout })\n );\n // EOF before the grant prevents the COM operation. Once granted, this exact\n // PowerShell instance retains the existing lifecycle fence if its CLI dies.\n // This is not a Wake Job: the independently scheduled Service must survive it.\n child.stdin?.on(\"error\", () => undefined);\n let participant: OpenMeldLock | undefined;\n try {\n if (lock) {\n if (!child.pid) {\n throw new Error(\"Windows task control did not establish a process.\");\n }\n participant = await attachLockProcess(lock, child.pid);\n }\n child.stdin?.end(lock ? \"execute\\n\" : undefined);\n const result = await completed;\n if (result.error) {\n throw result.error;\n }\n const status = windowsUserTaskStatusSchema.safeParse(\n JSON.parse(result.stdout.trim())\n );\n if (!status.success) {\n throw new Error(\"Windows returned an invalid OpenMeld task status.\");\n }\n return status.data;\n } finally {\n child.stdin?.destroy();\n if (child.exitCode === null && child.signalCode === null) {\n child.kill();\n }\n await completed;\n if (participant) {\n await releaseLock(participant);\n }\n }\n}\n"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- export { t as readWindowsTaskAction, n as runWindowsUserTask } from "./windows-user-task-CKb_u29X.js";
3
+ export { t as readWindowsTaskAction, n as runWindowsUserTask } from "./windows-user-task-CR64LZEK.js";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://www.schemastore.org/package.json",
3
3
  "name": "openmeld",
4
- "version": "0.3.288",
4
+ "version": "0.3.290",
5
5
  "openMeldReleaseDate": "2026-11-02",
6
6
  "description": "OpenMeld CLI - https://openmeld.ai",
7
7
  "license": "MIT",
@@ -50,26 +50,26 @@
50
50
  "vitest": "4.1.11",
51
51
  "@openmeld/adapter-antigravity": "0.0.1",
52
52
  "@openmeld/adapter-codex": "0.0.1",
53
+ "@openmeld/adapter-claude-code": "0.0.1",
53
54
  "@openmeld/adapter-core": "0.0.1",
54
- "@openmeld/adapter-cursor": "0.0.1",
55
55
  "@openmeld/adapter-grok-bot": "0.0.1",
56
+ "@openmeld/adapter-cursor": "0.0.1",
56
57
  "@openmeld/adapter-grok-build": "0.0.1",
57
- "@openmeld/adapter-claude-code": "0.0.1",
58
- "@openmeld/agent-runtime": "0.0.1",
59
58
  "@openmeld/adapter-openclaw": "0.0.1",
60
- "@openmeld/api-client": "0.0.1",
61
59
  "@openmeld/adapter-opencode": "0.0.1",
62
- "@openmeld/local-service": "0.0.1",
63
- "@openmeld/gateway-contract": "0.0.1",
60
+ "@openmeld/agent-runtime": "0.0.1",
61
+ "@openmeld/api-client": "0.0.1",
64
62
  "@openmeld/local-execution": "0.0.1",
65
63
  "@openmeld/projects": "0.0.1",
64
+ "@openmeld/local-service": "0.0.1",
66
65
  "@openmeld/routine-schedule": "0.0.1",
67
66
  "@openmeld/schemas": "0.0.1",
68
67
  "@openmeld/space": "0.0.1",
68
+ "@openmeld/protocol": "0.0.1",
69
69
  "@openmeld/space-mesh": "0.0.1",
70
70
  "@openmeld/start": "0.0.1",
71
71
  "@openmeld/utils": "0.0.1",
72
- "@openmeld/protocol": "0.0.1"
72
+ "@openmeld/gateway-contract": "0.0.1"
73
73
  },
74
74
  "openmeld": {
75
75
  "releaseLine": "openmeld-greenfield-2026-07",
@@ -87,5 +87,5 @@
87
87
  "test:local-service": "vitest run --config vitest.integration.config.ts tests/local-service-state.integration.test.ts tests/local-service-command.integration.test.ts tests/local-service-menu.integration.test.ts tests/local-service-run.integration.test.ts tests/local-service-bootstrap-recommendation.test.ts",
88
88
  "test:watch": "vitest"
89
89
  },
90
- "gitHead": "d43d02943e1e182aa2ca8bcedc461c6e22d318a4"
90
+ "gitHead": "58f900b4818092b8add89cd5ae22bef886a85b6f"
91
91
  }
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- export { u as getAuthSessionMetadata } from "./auth-session-DRQMn41Z.js";
@@ -1 +0,0 @@
1
- {"version":3,"file":"channel-CFIRo4fR.js","names":[],"sources":["../../../packages/schemas/dist/local-execution-input.js","../../../packages/schemas/dist/service-execution-host.js","../src/local-service/execution-host/channel.ts"],"sourcesContent":["import { agentExecutionSteerResponseSchema } from \"./schemas/runtime/agent-execution-steer.js\";\nimport * as z$1 from \"zod/v4\";\n//#region src/local-execution-input.ts\nconst id = z$1.string().min(1).max(1024);\nconst LOCAL_EXECUTION_INPUT_CAPABILITY_HEADER = \"x-openmeld-local-execution-input\";\nconst LOCAL_EXECUTION_INPUT_PENDING_DIAGNOSTIC = \"service.execution_input.pending\";\nconst localExecutionInputRequestSchema = z$1.strictObject({\n\tinputId: id,\n\townerUserId: id,\n\tdispatchId: id,\n\truntimeCoordinatorExecutionId: id,\n\tattemptId: id,\n\truntimeCoordinatorRunId: id,\n\ttargetProfileId: id,\n\tsource: z$1.strictObject({\n\t\tspaceId: id,\n\t\tsignalId: id,\n\t\tauthorProfileId: id,\n\t\trequesterUserId: id,\n\t\teffect: z$1.literal(\"steer\")\n\t}),\n\ttext: z$1.string().trim().min(1).max(1e5)\n});\nconst localExecutionInputResponseSchema = z$1.discriminatedUnion(\"status\", [\n\tagentExecutionSteerResponseSchema.options[0].extend({ inputId: id }),\n\tagentExecutionSteerResponseSchema.options[1].extend({\n\t\tinputId: id,\n\t\ttaskId: id.nullable()\n\t}),\n\tagentExecutionSteerResponseSchema.options[2].extend({ inputId: id }),\n\tz$1.strictObject({\n\t\tinputId: id,\n\t\tstatus: z$1.enum([\n\t\t\t\"not_found\",\n\t\t\t\"conflict\",\n\t\t\t\"capacity\"\n\t\t])\n\t})\n]);\nconst localExecutionInputOperationSchema = z$1.strictObject({\n\toperation: z$1.enum([\"apply\", \"read\"]),\n\trequest: localExecutionInputRequestSchema\n});\nconst localExecutionInputFrameSchema = localExecutionInputOperationSchema.extend({\n\trequestId: id,\n\tconnectionGeneration: z$1.number().int().positive(),\n\tleaseEpoch: z$1.number().int().positive()\n});\nconst localExecutionInputResultFrameSchema = z$1.strictObject({\n\trequestId: id,\n\tresult: localExecutionInputResponseSchema\n});\nconst localExecutionInputResolveSchema = z$1.strictObject({\n\townerUserId: id,\n\truntimeCoordinatorExecutionId: id,\n\tdispatchId: id,\n\ttargetProfileId: id,\n\tspaceId: id,\n\tauthorProfileId: id\n});\nconst localExecutionInputBindingSchema = localExecutionInputRequestSchema.pick({\n\townerUserId: true,\n\truntimeCoordinatorExecutionId: true,\n\tdispatchId: true,\n\ttargetProfileId: true,\n\tattemptId: true,\n\truntimeCoordinatorRunId: true\n});\n//#endregion\nexport { LOCAL_EXECUTION_INPUT_CAPABILITY_HEADER, LOCAL_EXECUTION_INPUT_PENDING_DIAGNOSTIC, localExecutionInputBindingSchema, localExecutionInputFrameSchema, localExecutionInputOperationSchema, localExecutionInputRequestSchema, localExecutionInputResolveSchema, localExecutionInputResponseSchema, localExecutionInputResultFrameSchema };\n\n//# sourceMappingURL=local-execution-input.js.map","import { daemonServiceLaneSchema } from \"./schemas/daemon/service-contract.js\";\nimport { providerDispatchRuntimeContextSchema } from \"./schemas/daemon/provider-runtime-context.js\";\nimport { openMeldDaemonCancelPayloadSchema, openMeldDaemonCancelRequestPayloadSchema, openMeldDaemonConversationExecutionStatusPayloadSchema, openMeldDaemonConversationExecutionStatusRequestPayloadSchema, openMeldDaemonInterruptPayloadSchema, openMeldDaemonInterruptRequestPayloadSchema, openMeldDaemonSetLocalAgentEnabledPayloadSchema, openMeldDaemonSetLocalAgentEnabledRequestPayloadSchema, skippedDaemonProfileSchema } from \"./schemas/daemon/control-plane.js\";\nimport { daemonStreamFrameSchema, localWakeRouteWorkingFolderObservationSchema, runtimeTransportLeaseSchema } from \"./schemas/daemon/runtime-transport.js\";\nimport { localExecutionInputRequestSchema, localExecutionInputResponseSchema } from \"./local-execution-input.js\";\nimport { cachedDaemonRouteConfigSchema } from \"./schemas/daemon/route-catalog-cache.js\";\nimport * as z$1 from \"zod/v4\";\n//#region src/service-execution-host.ts\nconst SERVICE_EXECUTION_HOST_PROTOCOL = \"service-execution-host-v1\";\nconst SERVICE_EXECUTION_HOST_MAX_FRAME_BYTES = 8388608;\nconst SERVICE_EXECUTION_HOST_MAX_PENDING_REQUESTS = 64;\nconst identityString = z$1.string().min(1).max(1024);\nconst count = z$1.number().int().nonnegative();\nconst empty = z$1.strictObject({});\nconst serviceExecutionHostIdentitySchema = z$1.strictObject({\n\townerUserId: identityString,\n\tdeviceId: identityString,\n\tlane: daemonServiceLaneSchema,\n\tdaemonSessionId: identityString,\n\tserviceContractGeneration: count,\n\tsessionIdentity: identityString,\n\tstateRoot: z$1.string().min(1).max(4096),\n\tauthBaseUrl: z$1.url(),\n\tgatewayBaseUrl: z$1.url(),\n\tparentPid: z$1.number().int().positive(),\n\tparentProcessStartedAt: identityString\n});\nconst serviceExecutionHostSnapshotSchema = z$1.strictObject({\n\tpid: z$1.number().int().positive(),\n\tadmission: z$1.enum([\"open\", \"draining\"]),\n\tactiveCount: count,\n\tpendingCount: count,\n\tlocalQuiescent: z$1.boolean(),\n\tunacknowledgedResultCount: count,\n\tstartupReplayPending: z$1.boolean(),\n\tadapterIds: z$1.array(identityString).max(256)\n});\nconst serviceExecutionHostOwnerV1Schema = z$1.strictObject({\n\tschema: z$1.literal(\"service-execution-host-owner-v1\"),\n\thostInstanceId: z$1.uuid(),\n\townerUserId: identityString,\n\tdeviceId: identityString,\n\tlane: daemonServiceLaneSchema,\n\tpid: z$1.number().int().positive(),\n\tbootIdentity: identityString.nullable(),\n\tlocalQuiescent: z$1.boolean()\n});\nconst serviceExecutionHostOwnedProcessTreeSchema = z$1.strictObject({\n\tpid: z$1.number().int().positive(),\n\tprocessStartedAt: identityString,\n\tsignalTarget: z$1.enum([\"process\", \"process_group\"])\n});\nconst serviceExecutionHostOwnerV2Schema = z$1.strictObject({\n\tschema: z$1.literal(\"service-execution-host-owner-v2\"),\n\thostInstanceId: z$1.uuid(),\n\townerUserId: identityString,\n\tdeviceId: identityString,\n\tlane: daemonServiceLaneSchema,\n\tpid: z$1.number().int().positive(),\n\tprocessStartedAt: identityString,\n\tbootIdentity: identityString.nullable(),\n\tlocalQuiescent: z$1.boolean(),\n\tprocessEvidenceComplete: z$1.boolean(),\n\townedProcessTrees: z$1.array(serviceExecutionHostOwnedProcessTreeSchema).max(64)\n});\nconst serviceExecutionHostOwnerSchema = z$1.discriminatedUnion(\"schema\", [serviceExecutionHostOwnerV1Schema, serviceExecutionHostOwnerV2Schema]);\nconst profileWorkingFolderFactSchema = z$1.strictObject({\n\tdefaultProjectId: identityString.nullable(),\n\tlocalProjectBindingGeneration: identityString.nullable(),\n\tobservedAtMs: count,\n\treasonCode: z$1.enum([\n\t\t\"profile.workspace.invalid\",\n\t\t\"profile.workspace.missing\",\n\t\t\"project.local_connection.folder_missing\",\n\t\t\"project.local_connection.invalid\",\n\t\t\"project.local_connection.missing\"\n\t]).nullable(),\n\tsource: z$1.enum([\"default_project\", \"profile_workspace\"]),\n\tstatus: z$1.enum([\n\t\t\"invalid\",\n\t\t\"missing\",\n\t\t\"ready\"\n\t])\n});\nconst readyWorkingFolder = {\n\tconfiguredWorkspacePath: z$1.string().min(1),\n\teffectiveRuntimeWorkingDirectory: z$1.string().min(1),\n\truntimeContext: providerDispatchRuntimeContextSchema,\n\tstatus: z$1.literal(\"ready\"),\n\tworkingFolderFact: profileWorkingFolderFactSchema\n};\nconst workingFolderRuntimeSchema = z$1.union([\n\tz$1.strictObject({\n\t\t...readyWorkingFolder,\n\t\tconfigPath: z$1.string().min(1),\n\t\tworkspaceMode: z$1.enum([\"openmeld_managed\", \"custom\"]),\n\t\tworkingFolderSource: z$1.literal(\"profile_workspace\")\n\t}),\n\tz$1.strictObject({\n\t\tconfigPath: z$1.string().min(1),\n\t\tconfiguredWorkspacePath: z$1.null().optional(),\n\t\treasonCode: z$1.literal(\"workspace.missing\"),\n\t\treasonText: z$1.string().min(1),\n\t\tstatus: z$1.literal(\"missing\"),\n\t\tworkingFolderFact: profileWorkingFolderFactSchema,\n\t\tworkingFolderSource: z$1.literal(\"profile_workspace\"),\n\t\tworkspaceMode: z$1.null().optional()\n\t}),\n\tz$1.strictObject({\n\t\tconfigPath: z$1.string().min(1),\n\t\tconfiguredWorkspacePath: z$1.string().min(1).nullable().optional(),\n\t\treasonCode: z$1.literal(\"workspace.invalid\"),\n\t\treasonText: z$1.string().min(1),\n\t\tstatus: z$1.literal(\"invalid\"),\n\t\tworkingFolderFact: profileWorkingFolderFactSchema,\n\t\tworkingFolderSource: z$1.literal(\"profile_workspace\"),\n\t\tworkspaceMode: z$1.enum([\"openmeld_managed\", \"custom\"]).nullable().optional()\n\t}),\n\tz$1.strictObject({\n\t\t...readyWorkingFolder,\n\t\tconfigPath: z$1.null(),\n\t\tworkspaceMode: z$1.null(),\n\t\tdefaultProjectId: identityString,\n\t\tdefaultProjectBindingGeneration: identityString,\n\t\tworkingFolderSource: z$1.literal(\"default_project\")\n\t}),\n\tz$1.strictObject({\n\t\tconfigPath: z$1.null(),\n\t\tconfiguredWorkspacePath: z$1.string().min(1).nullable(),\n\t\tdefaultProjectBindingGeneration: identityString.optional(),\n\t\tdefaultProjectFailureReason: z$1.enum([\"folder_missing\", \"missing_connection\"]),\n\t\tdefaultProjectId: identityString,\n\t\treasonCode: z$1.literal(\"workspace.missing\"),\n\t\treasonText: z$1.string().min(1),\n\t\tstatus: z$1.literal(\"missing\"),\n\t\tworkingFolderFact: profileWorkingFolderFactSchema,\n\t\tworkingFolderSource: z$1.literal(\"default_project\"),\n\t\tworkspaceMode: z$1.null()\n\t}),\n\tz$1.strictObject({\n\t\tconfigPath: z$1.null(),\n\t\tconfiguredWorkspacePath: z$1.string().min(1),\n\t\tdefaultProjectBindingGeneration: identityString,\n\t\tdefaultProjectId: identityString,\n\t\treasonCode: z$1.literal(\"workspace.invalid\"),\n\t\treasonText: z$1.string().min(1),\n\t\tstatus: z$1.literal(\"invalid\"),\n\t\tworkingFolderFact: profileWorkingFolderFactSchema,\n\t\tworkingFolderSource: z$1.literal(\"default_project\"),\n\t\tworkspaceMode: z$1.null()\n\t})\n]);\nconst serviceExecutionHostRouteSchema = cachedDaemonRouteConfigSchema.extend({\n\tagentControllerConversationId: identityString.nullable().optional(),\n\tworkingFolderRuntime: workingFolderRuntimeSchema.optional()\n});\nconst serviceExecutionHostCatalogSchema = z$1.strictObject({\n\trevision: z$1.number().int().positive(),\n\texpectedRoutesContractVersion: z$1.literal(\"v4\").optional(),\n\tprofileIds: z$1.array(identityString).max(1e4),\n\troutes: z$1.array(serviceExecutionHostRouteSchema).max(1e4),\n\tskippedProfiles: z$1.array(skippedDaemonProfileSchema).max(1e4),\n\tworkingFolderExpectedProfileIds: z$1.array(identityString).max(1e4).optional(),\n\tworkingFolderObservations: z$1.array(localWakeRouteWorkingFolderObservationSchema).max(1e4).optional()\n}).superRefine((catalog, context) => {\n\tconst ids = new Set(catalog.profileIds);\n\tconst routes = new Set(catalog.routes.map((route) => route.profileId));\n\tif (ids.size !== catalog.profileIds.length || routes.size !== catalog.routes.length || ids.size !== routes.size || catalog.profileIds.some((id) => !routes.has(id))) context.addIssue({\n\t\tcode: \"custom\",\n\t\tmessage: \"Host catalog must contain exactly one route per profile.\"\n\t});\n});\nconst reportResult = z$1.strictObject({\n\tstatus: z$1.enum([\"skipped\", \"submitted\"]),\n\treasonCodes: z$1.array(z$1.string().max(256)).max(1024),\n\tsubmittedCount: count,\n\tfailedCount: count\n});\nconst executionFrameCodes = /* @__PURE__ */ new Set([\n\t\"daemon.computer_power.request\",\n\t\"daemon.dispatch.deliver\",\n\t\"daemon.dispatch.lifecycle_acknowledged\",\n\t\"daemon.dispatch.accepted\",\n\t\"daemon.dispatch.interaction_response\",\n\t\"daemon.reasoning.preferences\",\n\t\"daemon.local_agent_control.cancel\",\n\t\"daemon.local_agent_control.interrupt\",\n\t\"daemon.local_agent_control.fork_session\",\n\t\"daemon.local_agent_control.manage_installation\",\n\t\"daemon.local_agent_control.set_enabled\",\n\t\"daemon.execution_recovery.resume_controller_conversation\"\n]);\nconst executionOutputFrameCodes = /* @__PURE__ */ new Set([\n\t\"daemon.computer_power.request_result\",\n\t\"daemon.dispatch.result\",\n\t\"daemon.dispatch.lifecycle\",\n\t\"daemon.dispatch.runtime_evidence\",\n\t\"daemon.dispatch.reasoning\",\n\t\"daemon.dispatch.progress\",\n\t\"daemon.dispatch.reply\",\n\t\"daemon.dispatch.tool_activity\",\n\t\"daemon.dispatch.interaction_request\",\n\t\"daemon.dispatch.interaction_delivered\",\n\t\"daemon.dispatch.preview\",\n\t\"daemon.dispatch.preview_end\",\n\t\"daemon.local_agent_control.result\",\n\t\"daemon.execution_recovery.resume_controller_conversation_result\"\n]);\nconst serviceExecutionHostMethods = {\n\tinitialize: {\n\t\tinput: serviceExecutionHostIdentitySchema,\n\t\toutput: serviceExecutionHostSnapshotSchema\n\t},\n\thealth: {\n\t\tinput: empty,\n\t\toutput: serviceExecutionHostSnapshotSchema\n\t},\n\tloadCatalog: {\n\t\tinput: z$1.strictObject({ initial: z$1.boolean() }),\n\t\toutput: serviceExecutionHostCatalogSchema\n\t},\n\tconfigureConnection: {\n\t\tinput: z$1.strictObject({\n\t\t\texecutionAdmissionConfirmation: z$1.boolean().optional(),\n\t\t\tconnectionGeneration: z$1.number().int().positive(),\n\t\t\tcatalogRevision: count,\n\t\t\tleases: z$1.array(runtimeTransportLeaseSchema).max(1e4)\n\t\t}),\n\t\toutput: serviceExecutionHostSnapshotSchema\n\t},\n\tdetachConnection: {\n\t\tinput: z$1.strictObject({ connectionGeneration: z$1.number().int().positive() }),\n\t\toutput: serviceExecutionHostSnapshotSchema\n\t},\n\theartbeat: {\n\t\tinput: z$1.strictObject({\n\t\t\tconnectionGeneration: z$1.number().int().positive(),\n\t\t\tstaleProfileIds: z$1.array(identityString).max(1e4)\n\t\t}),\n\t\toutput: serviceExecutionHostSnapshotSchema\n\t},\n\thandleFrame: {\n\t\tinput: z$1.strictObject({\n\t\t\tconnectionGeneration: z$1.number().int().positive(),\n\t\t\tframe: daemonStreamFrameSchema.refine((frame) => executionFrameCodes.has(frame.code), \"This frame belongs to the connector, not the execution host.\")\n\t\t}),\n\t\toutput: empty\n\t},\n\tcancel: {\n\t\tinput: openMeldDaemonCancelRequestPayloadSchema,\n\t\toutput: openMeldDaemonCancelPayloadSchema\n\t},\n\tinterrupt: {\n\t\tinput: openMeldDaemonInterruptRequestPayloadSchema,\n\t\toutput: openMeldDaemonInterruptPayloadSchema\n\t},\n\texecutionInput: {\n\t\tinput: z$1.strictObject({\n\t\t\toperation: z$1.enum([\"apply\", \"read\"]),\n\t\t\tconnectionGeneration: z$1.number().int().positive(),\n\t\t\tleaseEpoch: z$1.number().int().positive(),\n\t\t\trequest: localExecutionInputRequestSchema\n\t\t}),\n\t\toutput: localExecutionInputResponseSchema\n\t},\n\tconversationStatus: {\n\t\tinput: openMeldDaemonConversationExecutionStatusRequestPayloadSchema,\n\t\toutput: openMeldDaemonConversationExecutionStatusPayloadSchema\n\t},\n\tsetEnabled: {\n\t\tinput: openMeldDaemonSetLocalAgentEnabledRequestPayloadSchema,\n\t\toutput: openMeldDaemonSetLocalAgentEnabledPayloadSchema\n\t},\n\treportControllers: {\n\t\tinput: z$1.strictObject({ probePolicy: z$1.enum([\"background\", \"fresh\"]) }),\n\t\toutput: reportResult.extend({\n\t\t\treportCount: count,\n\t\t\thasArmedReprobe: z$1.boolean()\n\t\t})\n\t},\n\treportConversations: {\n\t\tinput: empty,\n\t\toutput: reportResult.extend({ proofCount: count })\n\t},\n\tpersistCatalog: {\n\t\tinput: z$1.strictObject({ revision: z$1.number().int().positive() }),\n\t\toutput: empty\n\t},\n\tsyncActivity: {\n\t\tinput: z$1.strictObject({ refreshIntegrations: z$1.boolean().optional() }),\n\t\toutput: empty\n\t},\n\tbeginDrain: {\n\t\tinput: z$1.strictObject({ onlyIfIdle: z$1.literal(true).optional() }),\n\t\toutput: serviceExecutionHostSnapshotSchema\n\t},\n\tdrain: {\n\t\tinput: empty,\n\t\toutput: serviceExecutionHostSnapshotSchema\n\t},\n\tsettleResults: {\n\t\tinput: empty,\n\t\toutput: z$1.strictObject({ status: z$1.enum([\n\t\t\t\"acknowledged\",\n\t\t\t\"connection_closed\",\n\t\t\t\"timeout\"\n\t\t]) })\n\t},\n\tstop: {\n\t\tinput: empty,\n\t\toutput: serviceExecutionHostSnapshotSchema\n\t}\n};\nconst method = z$1.enum(Object.keys(serviceExecutionHostMethods));\nconst envelope = {\n\tprotocol: z$1.literal(SERVICE_EXECUTION_HOST_PROTOCOL),\n\thostInstanceId: z$1.uuid()\n};\nconst serviceExecutionHostRequestSchema = z$1.strictObject({\n\t...envelope,\n\trequestId: z$1.uuid(),\n\tmethod,\n\tpayload: z$1.unknown()\n});\nconst serviceExecutionHostMessageSchema = z$1.discriminatedUnion(\"type\", [\n\tz$1.strictObject({\n\t\t...envelope,\n\t\ttype: z$1.literal(\"reply\"),\n\t\trequestId: z$1.uuid(),\n\t\tmethod,\n\t\tresult: z$1.discriminatedUnion(\"ok\", [z$1.strictObject({\n\t\t\tok: z$1.literal(true),\n\t\t\tpayload: z$1.unknown()\n\t\t}), z$1.strictObject({\n\t\t\tok: z$1.literal(false),\n\t\t\terror: z$1.strictObject({\n\t\t\t\tcode: z$1.string().min(1).max(256),\n\t\t\t\tmessage: z$1.string().min(1).max(4096)\n\t\t\t})\n\t\t})])\n\t}),\n\tz$1.strictObject({\n\t\t...envelope,\n\t\ttype: z$1.literal(\"frame\"),\n\t\tconnectionGeneration: z$1.number().int().positive(),\n\t\tframe: daemonStreamFrameSchema.refine((frame) => executionOutputFrameCodes.has(frame.code), \"The execution host cannot emit connector-owned frames.\")\n\t}),\n\tz$1.strictObject({\n\t\t...envelope,\n\t\ttype: z$1.literal(\"invalidate\"),\n\t\tscope: z$1.enum([\n\t\t\t\"routes\",\n\t\t\t\"activity\",\n\t\t\t\"execution\"\n\t\t])\n\t}),\n\tz$1.strictObject({\n\t\t...envelope,\n\t\ttype: z$1.literal(\"authentication_failure\"),\n\t\tconnectionGeneration: z$1.number().int().positive().nullable(),\n\t\tfailure: z$1.strictObject({\n\t\t\tcredentialFingerprint: z$1.string().min(1).max(256).optional(),\n\t\t\tmessage: z$1.string().min(1).max(4096),\n\t\t\treasonCode: z$1.string().min(1).max(256)\n\t\t})\n\t})\n]);\n//#endregion\nexport { SERVICE_EXECUTION_HOST_MAX_FRAME_BYTES, SERVICE_EXECUTION_HOST_MAX_PENDING_REQUESTS, SERVICE_EXECUTION_HOST_PROTOCOL, profileWorkingFolderFactSchema, serviceExecutionHostCatalogSchema, serviceExecutionHostIdentitySchema, serviceExecutionHostMessageSchema, serviceExecutionHostMethods, serviceExecutionHostOwnerSchema, serviceExecutionHostRequestSchema, serviceExecutionHostRouteSchema, serviceExecutionHostSnapshotSchema };\n\n//# sourceMappingURL=service-execution-host.js.map","import { randomUUID } from \"node:crypto\";\nimport {\n SERVICE_EXECUTION_HOST_MAX_FRAME_BYTES,\n SERVICE_EXECUTION_HOST_MAX_PENDING_REQUESTS,\n SERVICE_EXECUTION_HOST_PROTOCOL,\n type ServiceExecutionHostArguments,\n type ServiceExecutionHostInput,\n type ServiceExecutionHostMessage,\n type ServiceExecutionHostMethod,\n type ServiceExecutionHostOutput,\n serviceExecutionHostMessageSchema,\n serviceExecutionHostMethods,\n serviceExecutionHostRequestSchema,\n} from \"@openmeld/schemas\";\n\nexport type ExecutionHostChannel = {\n connected(): boolean;\n send(message: object, completed: (error: Error | null) => void): void;\n onMessage(listener: (message: unknown) => void): () => void;\n onDisconnect(listener: (error?: Error) => void): () => void;\n};\n\nexport class ExecutionHostError extends Error {\n readonly code: string;\n\n constructor(code: string, message: string) {\n super(message);\n this.name = \"ExecutionHostError\";\n this.code = code;\n }\n}\n\nconst RESERVED_CONTROL_REQUESTS = 4;\nconst controlMethods = new Set<ServiceExecutionHostMethod>([\n \"health\",\n \"beginDrain\",\n \"detachConnection\",\n \"stop\",\n]);\n\nfunction assertFrameSize(message: unknown): number {\n const serialized = JSON.stringify(message);\n if (serialized === undefined) {\n throw new ExecutionHostError(\n \"host.invalid_frame\",\n \"Host IPC requires JSON.\"\n );\n }\n const size = Buffer.byteLength(serialized);\n if (size > SERVICE_EXECUTION_HOST_MAX_FRAME_BYTES) {\n throw new ExecutionHostError(\n \"host.frame_too_large\",\n \"The local execution message exceeds the IPC limit.\"\n );\n }\n return size;\n}\n\nfunction createSender(channel: ExecutionHostChannel) {\n let queuedBytes = 0;\n return (message: object, completed: (error: Error | null) => void): void => {\n const size = assertFrameSize(message);\n if (!channel.connected()) {\n throw new ExecutionHostError(\n \"host.disconnected\",\n \"The Host IPC channel is closed.\"\n );\n }\n if (queuedBytes + size > SERVICE_EXECUTION_HOST_MAX_FRAME_BYTES * 2) {\n throw new ExecutionHostError(\n \"host.backpressure\",\n \"Host IPC is full; no new message was queued.\"\n );\n }\n queuedBytes += size;\n let settled = false;\n const settle = (error: Error | null) => {\n if (settled) {\n return;\n }\n settled = true;\n queuedBytes -= size;\n completed(error);\n };\n try {\n channel.send(message, settle);\n } catch (error) {\n settle(error instanceof Error ? error : new Error(String(error)));\n }\n };\n}\n\ntype PendingRequest = {\n method: ServiceExecutionHostMethod;\n resolve(value: unknown): void;\n reject(error: Error): void;\n timer: ReturnType<typeof setTimeout> | null;\n};\n\nfunction resolveReply(\n request: PendingRequest,\n message: Extract<ServiceExecutionHostMessage, { type: \"reply\" }>\n): void {\n if (!message.result.ok) {\n request.reject(\n new ExecutionHostError(\n message.result.error.code,\n message.result.error.message\n )\n );\n return;\n }\n const result = serviceExecutionHostMethods[request.method].output.safeParse(\n message.result.payload\n );\n if (!result.success) {\n const error = new ExecutionHostError(\n \"host.invalid_response\",\n `Invalid ${request.method} response from the execution host.`\n );\n request.reject(error);\n throw error;\n }\n request.resolve(result.data);\n}\n\nexport function createExecutionHostClient(input: {\n channel: ExecutionHostChannel;\n hostInstanceId: string;\n onEvent?(\n event: Exclude<ServiceExecutionHostMessage, { type: \"reply\" }>\n ): void;\n onFailure?(error: Error): void;\n}) {\n const pending = new Map<string, PendingRequest>();\n const send = createSender(input.channel);\n let failure: Error | null = null;\n\n const fail = (error: Error) => {\n if (failure) {\n return;\n }\n failure = error;\n for (const request of pending.values()) {\n if (request.timer) {\n clearTimeout(request.timer);\n }\n request.reject(error);\n }\n pending.clear();\n input.onFailure?.(error);\n };\n\n const stopMessages = input.channel.onMessage((raw) => {\n if (failure) {\n return;\n }\n try {\n assertFrameSize(raw);\n const parsed = serviceExecutionHostMessageSchema.safeParse(raw);\n if (\n !parsed.success ||\n parsed.data.hostInstanceId !== input.hostInstanceId\n ) {\n throw new ExecutionHostError(\n \"host.invalid_response\",\n \"Host response does not match this process incarnation.\"\n );\n }\n const message = parsed.data;\n if (message.type !== \"reply\") {\n input.onEvent?.(message);\n return;\n }\n const request = pending.get(message.requestId);\n // A timed-out observer is gone, not the accepted operation. Do not retry it\n // or turn its late result into the outcome of a newer request.\n if (!request) {\n return;\n }\n if (request.method !== message.method) {\n throw new ExecutionHostError(\n \"host.invalid_response\",\n \"Host response method does not match its request.\"\n );\n }\n pending.delete(message.requestId);\n if (request.timer) {\n clearTimeout(request.timer);\n }\n resolveReply(request, message);\n } catch (error) {\n fail(error instanceof Error ? error : new Error(String(error)));\n }\n });\n const stopDisconnect = input.channel.onDisconnect((cause) => {\n fail(\n new ExecutionHostError(\n \"host.disconnected\",\n cause\n ? `The execution host disconnected: ${cause.message}. In-flight outcomes are unconfirmed.`\n : \"The execution host disconnected; in-flight outcomes are unconfirmed.\"\n )\n );\n });\n\n return {\n call<M extends ServiceExecutionHostMethod>(\n method: M,\n value: ServiceExecutionHostInput<M>,\n options: { timeoutMs?: number | null } = {}\n ): Promise<ServiceExecutionHostOutput<M>> {\n if (failure) {\n return Promise.reject(failure);\n }\n const limit =\n SERVICE_EXECUTION_HOST_MAX_PENDING_REQUESTS -\n (controlMethods.has(method) ? 0 : RESERVED_CONTROL_REQUESTS);\n if (pending.size >= limit) {\n return Promise.reject(\n new ExecutionHostError(\n \"host.busy\",\n \"Too many outstanding Host requests; no new request was sent.\"\n )\n );\n }\n const payload =\n serviceExecutionHostMethods[method].input.safeParse(value);\n if (!payload.success) {\n return Promise.reject(\n new ExecutionHostError(\n \"host.invalid_request\",\n `Invalid ${method} request.`\n )\n );\n }\n const requestId = randomUUID();\n const timeoutMs =\n options.timeoutMs === undefined ? 30_000 : options.timeoutMs;\n if (\n timeoutMs !== null &&\n (!Number.isFinite(timeoutMs) || timeoutMs <= 0)\n ) {\n return Promise.reject(\n new ExecutionHostError(\n \"host.invalid_timeout\",\n \"The observer deadline must be positive or absent.\"\n )\n );\n }\n return new Promise<ServiceExecutionHostOutput<M>>((resolve, reject) => {\n const request: PendingRequest = {\n method,\n resolve: (result) => resolve(result as ServiceExecutionHostOutput<M>),\n reject,\n timer: null,\n };\n if (timeoutMs !== null) {\n request.timer = setTimeout(() => {\n pending.delete(requestId);\n reject(\n new ExecutionHostError(\n \"host.observation_timeout\",\n `The ${method} response is unconfirmed. No operation was cancelled or retried.`\n )\n );\n }, timeoutMs);\n request.timer.unref?.();\n }\n pending.set(requestId, request);\n try {\n send(\n {\n protocol: SERVICE_EXECUTION_HOST_PROTOCOL,\n hostInstanceId: input.hostInstanceId,\n requestId,\n method,\n payload: payload.data,\n },\n (error) => {\n if (error) {\n fail(error);\n }\n }\n );\n } catch (error) {\n pending.delete(requestId);\n if (request.timer) {\n clearTimeout(request.timer);\n }\n reject(error);\n }\n });\n },\n pendingCount: () => pending.size,\n dispose(): void {\n stopMessages();\n stopDisconnect();\n fail(\n new ExecutionHostError(\n \"host.observer_closed\",\n \"The Host observer closed; accepted work was not cancelled.\"\n )\n );\n },\n };\n}\n\nexport type ExecutionHostHandlers = {\n [M in ServiceExecutionHostMethod]: (\n input: ServiceExecutionHostArguments<M>\n ) => Promise<ServiceExecutionHostOutput<M>> | ServiceExecutionHostOutput<M>;\n};\n\nexport function serveExecutionHost(input: {\n channel: ExecutionHostChannel;\n hostInstanceId: string;\n handlers: ExecutionHostHandlers;\n onFailure(error: Error): void;\n onDisconnect(): void;\n}) {\n const activeIds = new Set<string>();\n const send = createSender(input.channel);\n let closed = false;\n\n const sendMessage = (message: ServiceExecutionHostMessage) => {\n if (closed) {\n throw new ExecutionHostError(\n \"host.disconnected\",\n \"The connector is no longer observing this Host.\"\n );\n }\n send(message, (error) => {\n if (error) {\n input.onFailure(error);\n }\n });\n };\n\n const stopMessages = input.channel.onMessage((raw) => {\n if (closed) {\n return;\n }\n let request: ReturnType<typeof serviceExecutionHostRequestSchema.parse>;\n try {\n assertFrameSize(raw);\n const parsed = serviceExecutionHostRequestSchema.safeParse(raw);\n if (\n !parsed.success ||\n parsed.data.hostInstanceId !== input.hostInstanceId\n ) {\n throw new ExecutionHostError(\n \"host.invalid_request\",\n \"Host request does not match this process incarnation.\"\n );\n }\n request = parsed.data;\n } catch (error) {\n input.onFailure(\n error instanceof Error ? error : new Error(String(error))\n );\n return;\n }\n\n const respond = (\n result: Extract<ServiceExecutionHostMessage, { type: \"reply\" }>[\"result\"]\n ) => {\n if (!closed) {\n sendMessage({\n protocol: SERVICE_EXECUTION_HOST_PROTOCOL,\n hostInstanceId: input.hostInstanceId,\n type: \"reply\",\n requestId: request.requestId,\n method: request.method,\n result,\n });\n }\n };\n const reject = (error: unknown) => {\n try {\n respond({\n ok: false,\n error: {\n code:\n error instanceof ExecutionHostError\n ? error.code\n : \"host.operation_failed\",\n message:\n (error instanceof Error ? error.message : String(error)).slice(\n 0,\n 4096\n ) || \"Host operation failed.\",\n },\n });\n } catch (sendError) {\n input.onFailure(\n sendError instanceof Error ? sendError : new Error(String(sendError))\n );\n }\n };\n\n const limit =\n SERVICE_EXECUTION_HOST_MAX_PENDING_REQUESTS -\n (controlMethods.has(request.method) ? 0 : RESERVED_CONTROL_REQUESTS);\n if (activeIds.has(request.requestId) || activeIds.size >= limit) {\n reject(\n new ExecutionHostError(\n \"host.busy\",\n \"Host request is duplicate or capacity is exhausted; it was not admitted again.\"\n )\n );\n return;\n }\n const method = serviceExecutionHostMethods[request.method];\n const payload = method.input.safeParse(request.payload);\n if (!payload.success) {\n reject(\n new ExecutionHostError(\n \"host.invalid_request\",\n `Invalid ${request.method} payload.`\n )\n );\n return;\n }\n activeIds.add(request.requestId);\n // This cast connects the fixed schema table to its corresponding handler.\n // Both request and response are runtime-validated, including local callers.\n const handler = input.handlers[request.method] as (\n value: unknown\n ) => unknown;\n Promise.resolve()\n .then(() => handler(payload.data))\n .then((result) => {\n const parsed = method.output.safeParse(result);\n if (!parsed.success) {\n throw new ExecutionHostError(\n \"host.invalid_response\",\n `The ${request.method} owner returned an invalid response.`\n );\n }\n respond({ ok: true, payload: parsed.data });\n })\n .catch(reject)\n .finally(() => activeIds.delete(request.requestId));\n });\n const stopDisconnect = input.channel.onDisconnect(() => {\n if (closed) {\n return;\n }\n closed = true;\n input.onDisconnect();\n });\n return {\n emit(event: Exclude<ServiceExecutionHostMessage, { type: \"reply\" }>): void {\n const parsed = serviceExecutionHostMessageSchema.safeParse(event);\n if (!parsed.success || event.hostInstanceId !== input.hostInstanceId) {\n throw new ExecutionHostError(\n \"host.invalid_event\",\n \"Invalid execution-host event.\"\n );\n }\n sendMessage(parsed.data);\n },\n dispose(): void {\n closed = true;\n stopMessages();\n stopDisconnect();\n },\n };\n}\n"],"mappings":"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"}
@@ -1,34 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- export { l as desktopComputerDisconnectRequestSchema } from "./dist-zRc0hA1y.js";
4
- import "./task-result-DhOFm1C_.js";
5
- import "./dist-53uvP0DN.js";
6
- import "./prepare-provider-runtime-m0GVd1Za.js";
7
- import "./dist-D7SkvUZW.js";
8
- import "./runtime-transport-Dg7E0ROH.js";
9
- import "./local-components-B3vffkMy.js";
10
- import "./windows-artifact-D99JU1ll.js";
11
- import "./cli-binary-manifest-CaeaM1Nd.js";
12
- import "./controller-contract-Ciy9Smgo.js";
13
- import "./conversation-execution-state-BOWTCU0B.js";
14
- import "./control-plane-dGjd5iC7.js";
15
- import "./daemon-device-id-D-RHe9se.js";
16
- import "./channel-CFIRo4fR.js";
17
- import "./state-YbqBm7wx.js";
18
- import "./service-CjVGm1FB.js";
19
- import "./dispatch-owned-runtime-CCeQTcjr.js";
20
- import "./service-account-admission-DN33uHmt.js";
21
- import "./meta-api-32dKpaJB.js";
22
- import "./updates-api-D4OvCDcm.js";
23
- import "./daemon-service-runtime-CMi7bRwi.js";
24
- import "./daemon-runtime-lease-DRYVXnBQ.js";
25
- import "./daemon-service-update-state-BSn45OHj.js";
26
- import "./windows-system-DsNqYvVr.js";
27
- import "./windows-task-command-COu_6Ke3.js";
28
- import "./openmeld-tools-update-coordinator-DkC6z3PV.js";
29
- import "./command-BqcCAQJ_.js";
30
- import "./auth-session-DRQMn41Z.js";
31
- import "./lock-DP8d33p_.js";
32
- import "./sensitive-operation-credentials-Dr_neVvL.js";
33
- import "./runtime-DDZRXE1m.js";
34
- import "./openmeld-BOBD0Any.js";
@@ -1 +0,0 @@
1
- {"version":3,"file":"entry-D-22_x6G.js","names":[],"sources":["../src/local-service/execution-host/identity.ts","../src/local-service/execution-host/ownership.ts","../src/local-service/execution-host/entry.ts"],"sourcesContent":["import { resolve } from \"node:path\";\nimport type { ServiceExecutionHostIdentity } from \"@openmeld/schemas\";\nimport {\n buildStoredAuthSessionIdentity,\n getAuthSessionState,\n} from \"../../config/auth-session\";\nimport { resolveBaseUrl } from \"../../config/base-url\";\nimport { readDaemonServiceContract } from \"../../config/daemon-service-contract\";\nimport { resolveOpenMeldRootDir } from \"../../config/paths\";\nimport { readProcessStartIdentity } from \"../../system/process-identity\";\nimport { ExecutionHostError } from \"./channel\";\n\nexport async function validateExecutionHostIdentity(\n identity: ServiceExecutionHostIdentity\n) {\n if (\n process.ppid !== identity.parentPid ||\n (process.platform !== \"win32\" &&\n readProcessStartIdentity(process.ppid) !==\n identity.parentProcessStartedAt) ||\n resolve(resolveOpenMeldRootDir()) !== resolve(identity.stateRoot)\n ) {\n throw new ExecutionHostError(\n \"host.identity_mismatch\",\n \"The Host's parent or installation changed.\"\n );\n }\n const [auth, contract, gateway] = await Promise.all([\n getAuthSessionState(),\n readDaemonServiceContract(),\n resolveBaseUrl(),\n ]);\n const session = auth.session;\n if (\n auth.state !== \"valid\" ||\n !session ||\n !contract ||\n session.user?.id !== identity.ownerUserId ||\n buildStoredAuthSessionIdentity(session) !== identity.sessionIdentity ||\n session.authBaseUrl !== identity.authBaseUrl ||\n gateway !== identity.gatewayBaseUrl ||\n contract.gatewayUrl !== identity.gatewayBaseUrl ||\n contract.ownerUserId !== identity.ownerUserId ||\n contract.deviceId !== identity.deviceId ||\n contract.lane !== identity.lane ||\n contract.generation !== identity.serviceContractGeneration\n ) {\n throw new ExecutionHostError(\n \"host.identity_mismatch\",\n \"The Host's account, device or Service generation changed.\"\n );\n }\n return { session, contract };\n}\n","import { execFile } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { mkdirSync, readFileSync, renameSync, writeFileSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { serviceExecutionHostOwnerSchema } from \"@openmeld/schemas\";\nimport { z } from \"zod/v4\";\nimport { acquireLock, releaseLock } from \"../../config/lock\";\nimport { systemDir } from \"../../config/paths\";\nimport {\n CURRENT_PROCESS_START_IDENTITY,\n isProcessIdentityAlive,\n readProcessStartIdentity,\n} from \"../../system/process-identity\";\nimport { ExecutionHostError } from \"./channel\";\n\nconst run = promisify(execFile);\nconst WINDOWS_BOOT_EVENT = /^\\d+:\\d+$/;\nconst DECIMAL = /^\\d+$/;\n\ntype OwnedProcessEvent = {\n phase: \"process_exit\" | \"process_spawned\";\n processId: number | null;\n signalTarget: \"process\" | \"process_group\";\n};\n\nexport async function readExecutionHostBootIdentity(): Promise<string | null> {\n try {\n return await readBootIdentity();\n } catch {\n // Fresh/quiescent starts do not require reboot evidence. Unknown evidence\n // can never clear an unsafe previous owner, and is not another boot.\n console.warn(\n \"[openmeld.execution_host.boot_unknown] Automatic recovery of unconfirmed work requires operating-system restart evidence.\"\n );\n return null;\n }\n}\n\nasync function readBootIdentity(): Promise<string | null> {\n if (process.platform === \"linux\") {\n const id = z\n .uuid()\n .parse(\n (await readFile(\"/proc/sys/kernel/random/boot_id\", \"utf8\")).trim()\n );\n return `linux:${id.toLowerCase()}`;\n }\n let stdout = \"\";\n if (process.platform === \"darwin\") {\n // XNU's immutable boot-session UUID, not its clock-adjustable boot time.\n ({ stdout } = await run(\n \"/usr/sbin/sysctl\",\n [\"-n\", \"kern.bootsessionuuid\"],\n {\n timeout: 5000,\n }\n ));\n return `darwin:${z.uuid().parse(stdout.trim()).toLowerCase()}`;\n }\n if (process.platform === \"win32\") {\n ({ stdout } = await run(\n \"powershell.exe\",\n [\n \"-NoProfile\",\n \"-NonInteractive\",\n \"-Command\",\n \"$ErrorActionPreference='Stop'; $e=Get-WinEvent -FilterHashtable @{LogName='System';ProviderName='Microsoft-Windows-Kernel-General';Id=12} -MaxEvents 1; if($null -eq $e.RecordId -or $null -eq $e.TimeCreated){throw 'Boot event unavailable'}; [Console]::WriteLine(([string]$e.RecordId)+':'+([string]$e.TimeCreated.ToUniversalTime().Ticks))\",\n ],\n { timeout: 5000, windowsHide: true }\n ));\n if (!WINDOWS_BOOT_EVENT.test(stdout.trim())) {\n throw new Error(\"Invalid Windows boot event\");\n }\n return `win32:${stdout.trim()}`;\n }\n return null;\n}\n\nfunction confirmsNewBoot(\n previous: string | null,\n current: string | null\n): boolean {\n if (!(previous && current) || previous === current) {\n return false;\n }\n const [priorSource, priorId, priorTime] = previous.split(\":\");\n const [source, id, time] = current.split(\":\");\n if (source !== priorSource) {\n return false;\n }\n if (source === \"linux\" || source === \"darwin\") {\n return (\n z.uuid().safeParse(id).success && z.uuid().safeParse(priorId).success\n );\n }\n // Kernel-General 12 records OS startup, not EventLog-service restarts or\n // wall-clock corrections. Require a later retained event in both fields;\n // missing/cleared/rotated evidence cannot authorize replacing unknown work.\n if (\n source !== \"win32\" ||\n !id ||\n !time ||\n !priorId ||\n !priorTime ||\n ![id, time, priorId, priorTime].every((value) => DECIMAL.test(value))\n ) {\n return false;\n }\n return BigInt(id) > BigInt(priorId) && BigInt(time) > BigInt(priorTime);\n}\n\nexport async function acquireExecutionHostOwnership(input: {\n hostInstanceId: string;\n ownerUserId: string;\n deviceId: string;\n lane: \"prod\" | \"dev-local\" | \"canary\";\n stateRoot: string;\n bootIdentity: string | null;\n}) {\n const lock = await acquireLock({\n openMeldProfileId: \"service-execution-host\",\n key: \"process-owner\",\n pathResolution: { env: { ...process.env, OPENMELD_HOME: input.stateRoot } },\n meta: {\n hostInstanceId: input.hostInstanceId,\n ownerUserId: input.ownerUserId,\n },\n });\n const path = join(\n systemDir({ env: { OPENMELD_HOME: input.stateRoot } }),\n \"execution-host-owner.json\"\n );\n try {\n const previous = readOwner(path);\n if (\n previous &&\n !previous.localQuiescent &&\n !confirmsNewBoot(previous.bootIdentity, input.bootIdentity) &&\n !canRecoverPreviousOwnerOnSameBoot(previous)\n ) {\n throw new ExecutionHostError(\n \"host.previous_work_unconfirmed\",\n \"The previous execution host ended before its local work was confirmed stopped. Restart this Computer, then check its connection. If restart evidence is unavailable, inspect the retained Host diagnostics before recovery. Existing results remain saved; no task will be restarted automatically.\"\n );\n }\n let owner = serviceExecutionHostOwnerSchema.parse({\n schema: \"service-execution-host-owner-v2\",\n hostInstanceId: input.hostInstanceId,\n ownerUserId: input.ownerUserId,\n deviceId: input.deviceId,\n lane: input.lane,\n pid: process.pid,\n processStartedAt: CURRENT_PROCESS_START_IDENTITY,\n bootIdentity: input.bootIdentity,\n localQuiescent: true,\n processEvidenceComplete: true,\n ownedProcessTrees: [],\n });\n persist(owner);\n function persist(next: typeof owner) {\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 });\n const temporary = `${path}.${randomUUID()}.tmp`;\n writeFileSync(temporary, JSON.stringify(next), {\n mode: 0o600,\n flag: \"wx\",\n });\n renameSync(temporary, path);\n }\n return {\n observeLocalQuiescence(quiescent: boolean) {\n if (owner.localQuiescent === quiescent) {\n return;\n }\n const next = {\n ...owner,\n localQuiescent: quiescent,\n ...(owner.schema === \"service-execution-host-owner-v2\"\n ? {\n processEvidenceComplete: quiescent,\n ...(quiescent ? { ownedProcessTrees: [] } : {}),\n }\n : {}),\n };\n // The unsafe transition is durable before any provider operation. A\n // failed write refuses that operation rather than weakening the fence.\n persist(next);\n owner = next;\n },\n observeOwnedProcess(event: OwnedProcessEvent) {\n if (owner.schema !== \"service-execution-host-owner-v2\") {\n return;\n }\n if (event.phase === \"process_spawned\") {\n if (event.processId === null) {\n const next = { ...owner, processEvidenceComplete: false };\n persist(next);\n owner = next;\n return;\n }\n const processStartedAt =\n readProcessStartIdentity(event.processId) ??\n `fallback:${event.processId}:unknown`;\n const next = {\n ...owner,\n processEvidenceComplete: true,\n ownedProcessTrees: [\n ...owner.ownedProcessTrees.filter(\n (process) => process.pid !== event.processId\n ),\n {\n pid: event.processId,\n processStartedAt,\n signalTarget: event.signalTarget,\n },\n ],\n };\n persist(next);\n owner = next;\n return;\n }\n if (event.processId === null) {\n return;\n }\n const next = {\n ...owner,\n ownedProcessTrees: owner.ownedProcessTrees.filter(\n (process) =>\n process.pid !== event.processId ||\n isOwnedProcessTreeAlive(process)\n ),\n };\n persist(next);\n owner = next;\n },\n release: () => releaseLock(lock),\n };\n } catch (error) {\n await releaseLock(lock);\n throw error;\n }\n}\n\nfunction canRecoverPreviousOwnerOnSameBoot(\n previous: ReturnType<typeof readOwner>\n): boolean {\n if (\n !previous ||\n previous.schema !== \"service-execution-host-owner-v2\" ||\n !previous.processEvidenceComplete ||\n isProcessIdentityAlive({\n ownerPid: previous.pid,\n ownerProcessStartedAt: previous.processStartedAt,\n })\n ) {\n return false;\n }\n return previous.ownedProcessTrees.every(\n (process) => !isOwnedProcessTreeAlive(process)\n );\n}\n\nfunction isOwnedProcessTreeAlive(input: {\n pid: number;\n processStartedAt: string;\n signalTarget: \"process\" | \"process_group\";\n}): boolean {\n if (input.signalTarget === \"process_group\" && process.platform !== \"win32\") {\n try {\n process.kill(-input.pid, 0);\n return true;\n } catch (error) {\n return !isNodeError(error, \"ESRCH\");\n }\n }\n return isProcessIdentityAlive({\n ownerPid: input.pid,\n ownerProcessStartedAt: input.processStartedAt,\n });\n}\n\nfunction isNodeError(error: unknown, code: string): boolean {\n return (\n error instanceof Error && \"code\" in error && String(error.code) === code\n );\n}\n\nfunction readOwner(path: string) {\n let raw: string;\n try {\n raw = readFileSync(path, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return null;\n }\n throw error;\n }\n const parsed = serviceExecutionHostOwnerSchema.safeParse(JSON.parse(raw));\n if (!parsed.success) {\n throw new ExecutionHostError(\n \"host.owner_corrupt\",\n \"The Host ownership record cannot be verified. Preserve it for diagnostics; automatic replacement is refused.\"\n );\n }\n return parsed.data;\n}\n","import {\n type ServiceExecutionHostIdentity,\n serviceExecutionHostMethods,\n} from \"@openmeld/schemas\";\nimport {\n type StoredAuthSession,\n withAdmittedServiceSession,\n} from \"../../config/auth-session\";\nimport { resolveRuntimeContext } from \"../../runtime/context\";\nimport { createPresenter } from \"../../runtime/presenter/index\";\nimport { ensureDaemonRuntimePaths } from \"../state/daemon-device-id\";\nimport {\n ExecutionHostError,\n type ExecutionHostHandlers,\n serveExecutionHost,\n} from \"./channel\";\nimport { validateExecutionHostIdentity } from \"./identity\";\nimport {\n acquireExecutionHostOwnership,\n readExecutionHostBootIdentity,\n} from \"./ownership\";\nimport { parentExecutionHostChannel } from \"./process-channel\";\n\n// This entry has no public listener and accepts no executable/path override.\n// The inherited pipe, parent incarnation and current Service account are all\n// required before the provider graph or any local runtime state is opened.\nexport function runExecutionHost(hostInstanceId: string): Promise<void> {\n const channel = parentExecutionHostChannel();\n const done = Promise.withResolvers<void>();\n let runtime: Awaited<\n ReturnType<typeof import(\"./runtime\").createExecutionHostRuntime>\n > | null = null;\n let ownership: Awaited<\n ReturnType<typeof acquireExecutionHostOwnership>\n > | null = null;\n let session: StoredAuthSession | null = null;\n let acceptedIdentity: ServiceExecutionHostIdentity | null = null;\n let initializing: Promise<void> | null = null;\n let closing: Promise<void> | null = null;\n let disconnected = false;\n\n const close = (): Promise<void> => {\n if (!closing) {\n closing = (async () => {\n try {\n await initializing;\n if (runtime && session) {\n const currentRuntime = runtime;\n await withAdmittedServiceSession(session, () =>\n currentRuntime.closeAfterConnectorLoss()\n );\n }\n } finally {\n await ownership?.release();\n server.dispose();\n if (process.connected) {\n process.disconnect();\n }\n }\n })();\n closing.then(\n () => done.resolve(),\n (error) => done.reject(error)\n );\n }\n return closing;\n };\n\n const handlers = {\n initialize: async (identity: ServiceExecutionHostIdentity) => {\n if (\n acceptedIdentity &&\n JSON.stringify(acceptedIdentity) !== JSON.stringify(identity)\n ) {\n throw new ExecutionHostError(\n \"host.identity_mismatch\",\n \"This Host is already assigned to a different Service incarnation.\"\n );\n }\n if (!initializing) {\n acceptedIdentity = identity;\n initializing = (async () => {\n const verified = await validateExecutionHostIdentity(identity);\n if (disconnected) {\n throw new ExecutionHostError(\n \"host.disconnected\",\n \"The supervising Service left before Host initialization.\"\n );\n }\n const verifiedOwnership = await acquireExecutionHostOwnership({\n ...identity,\n hostInstanceId,\n bootIdentity: await readExecutionHostBootIdentity(),\n });\n ownership = verifiedOwnership;\n session = verified.session;\n await withAdmittedServiceSession(session, async () => {\n const { createExecutionHostRuntime, createExecutionHostResources } =\n await import(\"./runtime\");\n const runtimePaths = await ensureDaemonRuntimePaths();\n const presenter = createPresenter(\n await resolveRuntimeContext({ view: \"agent\" })\n );\n runtime = await createExecutionHostRuntime({\n resources: await createExecutionHostResources({\n runtimePaths,\n presenter,\n observeOwnedProcess: (event) =>\n verifiedOwnership.observeOwnedProcess(event),\n }),\n hostInstanceId,\n identity,\n runtimePaths,\n serviceBundleId: verified.contract.bundleId,\n profileOwnerName: verified.session.user?.name ?? null,\n presenter,\n emit: (event) => {\n if (!disconnected) {\n server.emit(event);\n }\n },\n onWorkStateChange: (quiescent) =>\n verifiedOwnership.observeLocalQuiescence(quiescent),\n });\n });\n })();\n }\n await initializing;\n if (!runtime || disconnected) {\n throw new ExecutionHostError(\n \"host.disconnected\",\n \"The execution Host is not available.\"\n );\n }\n return runtime.snapshot();\n },\n } as ExecutionHostHandlers;\n\n // Each concrete method is still decoded by the shared method table at both\n // ends; the forwarding bridge cannot select a new account or mutate identity.\n for (const method of Object.keys(serviceExecutionHostMethods) as Array<\n keyof ExecutionHostHandlers\n >) {\n if (method === \"initialize\") {\n continue;\n }\n const target = handlers as unknown as Record<\n string,\n (payload: unknown) => Promise<unknown>\n >;\n target[method] = async (payload) => {\n if (!(runtime && session) || disconnected) {\n throw new ExecutionHostError(\n \"host.not_initialized\",\n \"Initialize this Host through its supervising Service first.\"\n );\n }\n const invoke = runtime.handlers[method] as (value: unknown) => unknown;\n return await withAdmittedServiceSession(\n session,\n async () => await invoke(payload)\n );\n };\n }\n\n const server = serveExecutionHost({\n channel,\n hostInstanceId,\n handlers,\n onFailure: (error) => {\n console.error(\"[openmeld.execution_host.channel_failed]\", error);\n disconnected = true;\n close().catch(() => undefined);\n },\n onDisconnect: () => {\n disconnected = true;\n close().catch(() => undefined);\n },\n });\n return done.promise;\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"lock-DP8d33p_.js","names":["resolveLocksDir","process","resolveRuntimeDir"],"sources":["../../../packages/schemas/dist/schemas/local-machine/recovery.js","../src/system/local-machine-recovery/index.ts","../src/config/openmeld-lane-descriptor.ts","../src/config/session-profile.ts","../src/config/lock.ts"],"sourcesContent":["import * as z$1 from \"zod/v4\";\n//#region src/schemas/local-machine/recovery.ts\nconst LOCAL_MACHINE_RECOVERY_SCHEMA_VERSION = 1;\nconst localMachineIssueCodeSchema = z$1.enum([\n\t\"local_machine.storage.exhausted\",\n\t\"local_machine.storage.not_writable\",\n\t\"local_machine.permission.denied\",\n\t\"local_machine.resources.exhausted\",\n\t\"local_machine.background_execution.blocked\",\n\t\"local_machine.concurrency.active\",\n\t\"local_machine.concurrency.orphaned\",\n\t\"local_machine.failure.unknown\"\n]);\nconst localMachineOperationSchema = z$1.enum([\n\t\"create_lock\",\n\t\"read_local_state\",\n\t\"write_local_state\",\n\t\"start_background_service\",\n\t\"start_process\",\n\t\"unknown\"\n]);\nconst localMachineRecoveryPolicySchema = z$1.enum([\n\t\"automatic\",\n\t\"retry_with_backoff\",\n\t\"user_action\",\n\t\"diagnostics\"\n]);\nconst LOCAL_MACHINE_RECOVERY_POLICY_BY_CODE = {\n\t\"local_machine.storage.exhausted\": \"user_action\",\n\t\"local_machine.storage.not_writable\": \"user_action\",\n\t\"local_machine.permission.denied\": \"user_action\",\n\t\"local_machine.resources.exhausted\": \"user_action\",\n\t\"local_machine.background_execution.blocked\": \"user_action\",\n\t\"local_machine.concurrency.active\": \"user_action\",\n\t\"local_machine.concurrency.orphaned\": \"user_action\",\n\t\"local_machine.failure.unknown\": \"diagnostics\"\n};\nfunction resolveLocalMachineRecoveryPolicy(code) {\n\tif (!Object.hasOwn(LOCAL_MACHINE_RECOVERY_POLICY_BY_CODE, code)) return null;\n\treturn LOCAL_MACHINE_RECOVERY_POLICY_BY_CODE[code];\n}\nconst localMachineUserMessageSchema = z$1.string().trim().min(1).max(512);\nconst localMachineDiagnosticTextSchema = z$1.string().trim().min(1).max(2048);\nconst localMachineAgentMessageSchema = z$1.string().trim().min(1).max(1025);\nfunction formatLocalMachineIssueMessage(issue) {\n\treturn issue.primaryAction ? `${issue.summary} ${issue.primaryAction}` : issue.summary;\n}\nconst localMachineIssueSchema = z$1.strictObject({\n\tschemaVersion: z$1.literal(1),\n\tcode: localMachineIssueCodeSchema,\n\toperation: localMachineOperationSchema,\n\trecoveryPolicy: localMachineRecoveryPolicySchema,\n\tsummary: localMachineUserMessageSchema,\n\tprimaryAction: z$1.union([localMachineUserMessageSchema, z$1.null()]),\n\tdiagnostics: z$1.strictObject({\n\t\tsystemCode: z$1.union([z$1.string().trim().min(1).max(64), z$1.null()]),\n\t\tdetail: z$1.union([localMachineDiagnosticTextSchema, z$1.null()])\n\t})\n}).superRefine((value, context) => {\n\tconst expectedPolicy = resolveLocalMachineRecoveryPolicy(value.code);\n\tif (value.recoveryPolicy !== expectedPolicy) context.addIssue({\n\t\tcode: \"custom\",\n\t\tmessage: `recovery policy must be ${expectedPolicy} for ${value.code}`,\n\t\tpath: [\"recoveryPolicy\"]\n\t});\n});\nconst localMachineIssueAgentEventSchema = z$1.strictObject({\n\ttype: z$1.literal(\"error\"),\n\tcode: localMachineIssueCodeSchema,\n\tmessage: localMachineAgentMessageSchema,\n\trequestId: z$1.string().trim().min(1).max(256).optional(),\n\tpayload: z$1.strictObject({ localMachineIssue: localMachineIssueSchema })\n}).superRefine((value, context) => {\n\tif (value.code !== value.payload.localMachineIssue.code) context.addIssue({\n\t\tcode: \"custom\",\n\t\tmessage: \"agent event code must match local machine issue code\",\n\t\tpath: [\"code\"]\n\t});\n\tconst expectedMessage = formatLocalMachineIssueMessage(value.payload.localMachineIssue);\n\tif (value.message !== expectedMessage) context.addIssue({\n\t\tcode: \"custom\",\n\t\tmessage: \"agent event message must match local machine issue copy\",\n\t\tpath: [\"message\"]\n\t});\n});\n//#endregion\nexport { LOCAL_MACHINE_RECOVERY_POLICY_BY_CODE, LOCAL_MACHINE_RECOVERY_SCHEMA_VERSION, formatLocalMachineIssueMessage, localMachineIssueAgentEventSchema, localMachineIssueCodeSchema, localMachineIssueSchema, localMachineOperationSchema, localMachineRecoveryPolicySchema, resolveLocalMachineRecoveryPolicy };\n\n//# sourceMappingURL=recovery.js.map","import {\n formatLocalMachineIssueMessage,\n type LocalMachineIssue,\n type LocalMachineOperation,\n} from \"@openmeld/schemas\";\n\ntype LocalMachineFailureInput = {\n operation: LocalMachineOperation;\n error: unknown;\n};\n\nexport class LocalMachineFailureError extends Error {\n readonly code: LocalMachineIssue[\"code\"];\n readonly issue: LocalMachineIssue;\n\n constructor(input: { issue: LocalMachineIssue; cause?: unknown }) {\n super(formatLocalMachineIssueMessage(input.issue), {\n cause: input.cause,\n });\n this.name = \"LocalMachineFailureError\";\n this.code = input.issue.code;\n this.issue = input.issue;\n }\n}\n\nexport function isLocalMachineFailureError(\n error: unknown\n): error is LocalMachineFailureError {\n return error instanceof LocalMachineFailureError;\n}\n\nexport function toLocalMachineFailureError(\n input: LocalMachineFailureInput\n): LocalMachineFailureError {\n if (isLocalMachineFailureError(input.error)) {\n return input.error;\n }\n return new LocalMachineFailureError({\n issue: assessLocalMachineFailure(input),\n cause: input.error,\n });\n}\n\nexport function toRecognizedLocalMachineFailureError(\n input: LocalMachineFailureInput\n): LocalMachineFailureError | null {\n if (isLocalMachineFailureError(input.error)) {\n return input.error;\n }\n const issue = assessLocalMachineFailure(input);\n return issue.code === \"local_machine.failure.unknown\"\n ? null\n : new LocalMachineFailureError({\n issue,\n cause: input.error,\n });\n}\n\nexport function assessLocalMachineFailure(\n input: LocalMachineFailureInput\n): LocalMachineIssue {\n const systemCode = readSystemErrorCode(input.error);\n const detail = readErrorMessage(input.error);\n\n if (systemCode === \"ENOSPC\" || systemCode === \"EDQUOT\") {\n return {\n schemaVersion: 1,\n code: \"local_machine.storage.exhausted\",\n operation: input.operation,\n recoveryPolicy: \"user_action\",\n summary:\n \"Your computer is out of storage space. OpenMeld can't save the local files it needs.\",\n primaryAction: \"Free up storage, then try again.\",\n diagnostics: {\n systemCode,\n detail,\n },\n };\n }\n\n if (\n systemCode === \"EROFS\" ||\n ((input.operation === \"create_lock\" ||\n input.operation === \"write_local_state\") &&\n (systemCode === \"EACCES\" || systemCode === \"EPERM\"))\n ) {\n return {\n schemaVersion: 1,\n code: \"local_machine.storage.not_writable\",\n operation: input.operation,\n recoveryPolicy: \"user_action\",\n summary: \"OpenMeld can't write to its local data folder.\",\n primaryAction: \"Make sure the folder is writable, then try again.\",\n diagnostics: {\n systemCode,\n detail,\n },\n };\n }\n\n if (\n systemCode === \"EACCES\" ||\n systemCode === \"EPERM\" ||\n systemCode === \"EROFS\"\n ) {\n return {\n schemaVersion: 1,\n code: \"local_machine.permission.denied\",\n operation: input.operation,\n recoveryPolicy: \"user_action\",\n summary:\n \"OpenMeld doesn't have permission to complete local setup on this computer.\",\n primaryAction:\n \"Allow OpenMeld to access its local files and background services, then try again.\",\n diagnostics: {\n systemCode,\n detail,\n },\n };\n }\n\n if (\n systemCode === \"EMFILE\" ||\n systemCode === \"ENFILE\" ||\n systemCode === \"ENOMEM\"\n ) {\n return {\n schemaVersion: 1,\n code: \"local_machine.resources.exhausted\",\n operation: input.operation,\n recoveryPolicy: \"user_action\",\n summary:\n \"Your computer doesn't have enough available system resources for OpenMeld to continue.\",\n primaryAction: \"Restart your computer, then try again.\",\n diagnostics: {\n systemCode,\n detail,\n },\n };\n }\n\n return {\n schemaVersion: 1,\n code: \"local_machine.failure.unknown\",\n operation: input.operation,\n recoveryPolicy: \"diagnostics\",\n summary: \"OpenMeld couldn't complete a required action on this computer.\",\n primaryAction: \"Try again. If it still fails, open diagnostics.\",\n diagnostics: {\n systemCode,\n detail,\n },\n };\n}\n\nexport function createServiceSpawnPendingIssue(input: {\n detail?: string | null;\n}): LocalMachineIssue {\n return {\n schemaVersion: 1,\n code: \"local_machine.failure.unknown\",\n operation: \"start_background_service\",\n recoveryPolicy: \"diagnostics\",\n summary: \"macOS registered OpenMeld Service but hasn't started it.\",\n primaryAction:\n \"Run `openmeld service snapshot --view agent` to collect startup diagnostics.\",\n diagnostics: {\n systemCode: \"SERVICE_SPAWN_PENDING\",\n detail: input.detail?.trim().slice(0, 2048) || null,\n },\n };\n}\n\nexport function createActiveSetupConcurrencyIssue(input: {\n detail?: string | null;\n primaryAction: string;\n}): LocalMachineIssue {\n return {\n schemaVersion: 1,\n code: \"local_machine.concurrency.active\",\n operation: \"create_lock\",\n recoveryPolicy: \"user_action\",\n summary: \"Another OpenMeld setup is already running on this computer.\",\n primaryAction: input.primaryAction,\n diagnostics: {\n systemCode: \"OPENMELD_LOCK_ACTIVE\",\n detail: input.detail?.trim().slice(0, 2048) || null,\n },\n };\n}\n\nexport function createOrphanedSetupConcurrencyIssue(input: {\n detail?: string | null;\n primaryAction: string;\n}): LocalMachineIssue {\n return createOrphanedLocalConcurrencyIssue({\n ...input,\n summary: \"OpenMeld found a setup lock left by an older version.\",\n });\n}\n\nexport function createOrphanedLocalConcurrencyIssue(input: {\n detail?: string | null;\n primaryAction: string;\n summary: string;\n}): LocalMachineIssue {\n return {\n schemaVersion: 1,\n code: \"local_machine.concurrency.orphaned\",\n operation: \"create_lock\",\n recoveryPolicy: \"user_action\",\n summary: input.summary,\n primaryAction: input.primaryAction,\n diagnostics: {\n systemCode: \"OPENMELD_LOCK_ORPHANED\",\n detail: input.detail?.trim().slice(0, 2048) || null,\n },\n };\n}\n\nfunction readSystemErrorCode(error: unknown): string | null {\n if (!error || typeof error !== \"object\") {\n return null;\n }\n const code = (error as { code?: unknown }).code;\n return typeof code === \"string\" && code.trim().length > 0 ? code : null;\n}\n\nfunction readErrorMessage(error: unknown): string | null {\n if (error instanceof Error && error.message.trim().length > 0) {\n return error.message.trim().slice(0, 2048);\n }\n if (typeof error === \"string\" && error.trim().length > 0) {\n return error.trim().slice(0, 2048);\n }\n return null;\n}\n","import {\n type OpenMeldEnvPreset,\n resolveOpenMeldEnvPreset,\n resolveOpenMeldRootDir,\n} from \"./paths\";\n\nexport type OpenMeldLaneDescriptor = {\n command: \"openmeld\" | \"openmeld-dev\" | \"openmeld-canary\";\n preset: OpenMeldEnvPreset;\n openMeldHome: string;\n destructiveResetAllowed: boolean;\n repairCommand: string;\n removeCommand: string | null;\n resetCommand: string;\n};\n\nexport function resolveOpenMeldLaneDescriptor(input?: {\n env?: NodeJS.ProcessEnv;\n argv?: string[];\n homeDir?: string;\n}): OpenMeldLaneDescriptor {\n const env = input?.env ?? process.env;\n const preset = resolveOpenMeldEnvPreset({\n argv: input?.argv,\n env,\n homeDir: input?.homeDir,\n });\n const command = resolveLaneCommand(preset);\n return {\n command,\n preset,\n openMeldHome: resolveOpenMeldRootDir({\n argv: input?.argv,\n env,\n homeDir: input?.homeDir,\n }),\n destructiveResetAllowed: true,\n repairCommand: `${command} repair local-state`,\n removeCommand: preset === \"canary\" ? \"pnpm openmeld:canary:remove\" : null,\n resetCommand: `${command} reset --yes`,\n };\n}\n\nexport function formatLaneScopeSentence(\n lane: Pick<OpenMeldLaneDescriptor, \"openMeldHome\" | \"command\">\n): string {\n return `This only affects the ${lane.command} lane at ${lane.openMeldHome}.`;\n}\n\nexport function buildLaneScopedCleanupGuidance(\n lane: Pick<\n OpenMeldLaneDescriptor,\n \"command\" | \"repairCommand\" | \"removeCommand\"\n >\n): string {\n const commands = [`\\`${lane.repairCommand}\\``];\n if (lane.removeCommand) {\n commands.unshift(`\\`${lane.removeCommand}\\``);\n }\n return `Optional cleanup for this lane: run ${commands.join(\" or \")}.`;\n}\n\nfunction resolveLaneCommand(\n preset: OpenMeldEnvPreset\n): OpenMeldLaneDescriptor[\"command\"] {\n if (preset === \"dev-local\") {\n return \"openmeld-dev\";\n }\n if (preset === \"canary\") {\n return \"openmeld-canary\";\n }\n return \"openmeld\";\n}\n","import { createHash } from \"node:crypto\";\nimport { mkdir, open, readdir, readFile, rename, rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport {\n normalizeOpenMeldProfileId,\n type OpenMeldProfileId,\n sessionsDir,\n} from \"./paths\";\n\nexport const OPENMELD_CLI_CONTEXT_ENV_KEY = \"OPENMELD_CLI_CONTEXT_ID\";\nexport const LEGACY_OPENMELD_AGENT_SESSION_ENV_KEY =\n \"OPENMELD_AGENT_SESSION_ID\";\n\nexport const CLI_CONTEXT_ENV_KEYS = [\n OPENMELD_CLI_CONTEXT_ENV_KEY,\n LEGACY_OPENMELD_AGENT_SESSION_ENV_KEY,\n] as const;\n\nconst SESSION_FILE_MAX_LENGTH = 128;\nconst SESSION_FILE_HASH_LENGTH = 8;\n\nexport type CliContextResolution = {\n cliContextId: string;\n source: string;\n};\n\nexport type CliContextStateV1 = {\n v: 1;\n sessionId: string;\n updatedAt: string;\n cliContextSource?: string;\n openMeldProfileId?: string;\n selectedOpenMeldProfileId?: string;\n};\n\nexport function resolveCliContext(\n profileIdInput?: string\n): CliContextResolution | null {\n const explicit = normalizeSessionId(profileIdInput);\n if (explicit) {\n return {\n cliContextId: explicit,\n source: \"manual\",\n };\n }\n\n for (const key of CLI_CONTEXT_ENV_KEYS) {\n const sessionId = normalizeSessionId(process.env[key]);\n if (sessionId) {\n return {\n cliContextId: sessionId,\n source: `environment:${key}`,\n };\n }\n }\n\n return resolveTerminalSessionId();\n}\n\nexport function resolveCliContextId(profileIdInput?: string): string | null {\n return resolveCliContext(profileIdInput)?.cliContextId ?? null;\n}\n\nexport function buildSessionProfilePayload(\n session: CliContextResolution,\n openMeldProfileId: OpenMeldProfileId\n): CliContextStateV1 {\n return {\n v: 1,\n sessionId: session.cliContextId,\n cliContextSource: session.source,\n openMeldProfileId: normalizeOpenMeldProfileId(openMeldProfileId),\n updatedAt: new Date().toISOString(),\n };\n}\n\nexport function formatCliContextSource(source: string): string {\n if (source === \"manual\") {\n return \"manual\";\n }\n if (source.startsWith(\"environment:\")) {\n return `environment:${source.slice(\"environment:\".length)}`;\n }\n if (source.startsWith(\"terminal:\")) {\n return \"terminal-fingerprint\";\n }\n return source;\n}\n\nexport function normalizeCliContextResolution(\n value: unknown\n): CliContextResolution | null {\n if (!value || typeof value !== \"object\") {\n return null;\n }\n\n const maybe = value as {\n cliContextId?: unknown;\n source?: unknown;\n };\n const cliContextId = normalizeSessionId(maybe.cliContextId);\n const source = normalizeSessionSource(maybe.source);\n if (!(cliContextId && source)) {\n return null;\n }\n\n return { cliContextId, source };\n}\n\nfunction normalizeSessionSource(raw: unknown): string | null {\n const value = String(raw ?? \"\").trim();\n if (!value) {\n return null;\n }\n return value;\n}\n\nexport async function setSessionOpenMeldProfileId(\n openMeldProfileId: OpenMeldProfileId\n): Promise<boolean> {\n return await writeCliContextState({\n openMeldProfileId,\n });\n}\n\nexport async function getSessionOpenMeldProfileId(): Promise<OpenMeldProfileId | null> {\n return (await readCliContextState())?.openMeldProfileId ?? null;\n}\n\nexport async function clearSessionOpenMeldProfileId(): Promise<boolean> {\n return await writeCliContextState({\n openMeldProfileId: null,\n });\n}\n\nexport async function readCliContextState(input?: {\n sessionId?: string;\n}): Promise<CliContextStateV1 | null> {\n const cliContextId = resolveSessionStateId(input?.sessionId);\n if (!cliContextId) {\n return null;\n }\n\n const raw = await readFile(cliContextStatePath(cliContextId), \"utf8\").catch(\n () => null\n );\n if (!raw) {\n return null;\n }\n\n return parseCliContextState(raw);\n}\n\nexport async function listCliContextStates(): Promise<CliContextStateV1[]> {\n const entryNames = await readdir(sessionsDir()).catch(() => []);\n const states: CliContextStateV1[] = [];\n for (const entryName of entryNames) {\n if (!entryName.endsWith(\".json\")) {\n continue;\n }\n const raw = await readFile(join(sessionsDir(), entryName), \"utf8\").catch(\n () => null\n );\n if (!raw) {\n continue;\n }\n const parsed = parseCliContextState(raw);\n if (!parsed) {\n continue;\n }\n states.push(parsed);\n }\n return states.sort((left, right) =>\n left.sessionId.localeCompare(right.sessionId)\n );\n}\n\nexport async function writeCliContextState(input: {\n sessionId?: string;\n sessionSource?: string;\n openMeldProfileId?: string | null;\n selectedOpenMeldProfileId?: string | null;\n}): Promise<boolean> {\n const cliContext = resolveCliContextStateInput(input) ?? resolveCliContext();\n if (!cliContext) {\n return false;\n }\n\n await mkdir(sessionsDir(), { recursive: true });\n const existing = await readCliContextState({\n sessionId: cliContext.cliContextId,\n });\n const nextOpenMeldProfileId = resolveNextSessionOpenMeldProfileId(\n existing,\n input\n );\n const nextSelectedOpenMeldProfileId = resolveNextSelectedOpenMeldProfileId(\n existing,\n input\n );\n const outputPath = cliContextStatePath(cliContext.cliContextId);\n\n if (!(nextOpenMeldProfileId || nextSelectedOpenMeldProfileId)) {\n await rm(outputPath, { force: true });\n return true;\n }\n\n const payload: CliContextStateV1 = {\n v: 1,\n sessionId: cliContext.cliContextId,\n cliContextSource:\n cliContext.source ?? existing?.cliContextSource ?? \"manual\",\n ...(nextOpenMeldProfileId\n ? { openMeldProfileId: nextOpenMeldProfileId }\n : {}),\n ...(nextSelectedOpenMeldProfileId\n ? { selectedOpenMeldProfileId: nextSelectedOpenMeldProfileId }\n : {}),\n updatedAt: new Date().toISOString(),\n };\n\n await writeCliContextStateFile(outputPath, payload);\n return true;\n}\n\nexport function cliContextStatePath(sessionId: string): string {\n return join(sessionsDir(), `${toSafeSessionFile(sessionId)}.json`);\n}\n\nfunction toSafeSessionFile(value: string): string {\n const hash = createHash(\"sha1\")\n .update(value, \"utf8\")\n .digest(\"hex\")\n .slice(0, SESSION_FILE_HASH_LENGTH);\n const safeBaseRaw = value.replace(/[^a-zA-Z0-9._-]+/g, \"_\");\n const safeBase = safeBaseRaw.length > 0 ? safeBaseRaw : \"session\";\n const maxBaseLength = Math.max(\n 1,\n SESSION_FILE_MAX_LENGTH - SESSION_FILE_HASH_LENGTH - 1\n );\n const truncatedBase = safeBase.slice(0, maxBaseLength);\n return `${truncatedBase}-${hash}`;\n}\n\nfunction resolveCliContextStateInput(input: {\n sessionId?: string;\n sessionSource?: string;\n}): CliContextResolution | null {\n const sessionId = normalizeSessionId(input.sessionId);\n if (!sessionId) {\n return null;\n }\n return {\n cliContextId: sessionId,\n source: normalizeSessionSource(input.sessionSource) ?? \"manual\",\n };\n}\n\nfunction resolveSessionStateId(sessionId?: string): string | null {\n const explicit = normalizeSessionId(sessionId);\n if (explicit) {\n return explicit;\n }\n return resolveCliContext()?.cliContextId ?? null;\n}\n\nfunction parseCliContextState(raw: string): CliContextStateV1 | null {\n let parsed: Partial<CliContextStateV1> & {\n profile?: unknown;\n };\n try {\n parsed = JSON.parse(raw) as Partial<CliContextStateV1> & {\n profile?: unknown;\n };\n } catch {\n return null;\n }\n\n if (parsed.v !== 1) {\n return null;\n }\n const sessionId = normalizeSessionId(parsed.sessionId);\n if (!sessionId) {\n return null;\n }\n const openMeldProfileId = resolveStoredSessionOpenMeldProfileId(parsed);\n const selectedOpenMeldProfileId =\n resolveStoredSelectedOpenMeldProfileId(parsed);\n if (!(openMeldProfileId || selectedOpenMeldProfileId)) {\n return null;\n }\n const cliContextSource = normalizeSessionSource(parsed.cliContextSource);\n return {\n v: 1,\n sessionId,\n ...(cliContextSource ? { cliContextSource } : {}),\n ...(openMeldProfileId ? { openMeldProfileId } : {}),\n ...(selectedOpenMeldProfileId ? { selectedOpenMeldProfileId } : {}),\n updatedAt:\n typeof parsed.updatedAt === \"string\" && parsed.updatedAt.trim().length > 0\n ? parsed.updatedAt\n : new Date(0).toISOString(),\n };\n}\n\nfunction resolveNextSessionOpenMeldProfileId(\n existing: CliContextStateV1 | null,\n input: {\n openMeldProfileId?: string | null;\n selectedOpenMeldProfileId?: string | null;\n }\n): string | undefined {\n if (!(\"openMeldProfileId\" in input)) {\n return existing?.openMeldProfileId;\n }\n return (\n normalizeOptionalOpenMeldProfileId(input.openMeldProfileId) ?? undefined\n );\n}\n\nfunction resolveNextSelectedOpenMeldProfileId(\n existing: CliContextStateV1 | null,\n input: {\n openMeldProfileId?: string | null;\n selectedOpenMeldProfileId?: string | null;\n }\n): string | undefined {\n if (!(\"selectedOpenMeldProfileId\" in input)) {\n return existing?.selectedOpenMeldProfileId;\n }\n return (\n normalizeOptionalOpenMeldProfileId(input.selectedOpenMeldProfileId) ??\n undefined\n );\n}\n\nasync function writeCliContextStateFile(\n outputPath: string,\n payload: CliContextStateV1\n): Promise<void> {\n const tempPath = `${outputPath}.tmp-${process.pid}-${Date.now()}`;\n const file = await open(tempPath, \"w\");\n let writeFailure: unknown = null;\n try {\n await file.writeFile(`${JSON.stringify(payload, null, 2)}\\n`, \"utf8\");\n await file.sync();\n } catch (error) {\n writeFailure = error;\n }\n try {\n await file.close();\n } catch (error) {\n if (!writeFailure) {\n writeFailure = error;\n }\n }\n if (writeFailure) {\n await rm(tempPath, { force: true }).catch(() => undefined);\n throw writeFailure;\n }\n\n try {\n await rename(tempPath, outputPath);\n } catch (error) {\n await rm(tempPath, { force: true }).catch(() => undefined);\n throw error;\n }\n}\n\nfunction normalizeSessionId(value: unknown): string | null {\n const raw = String(value ?? \"\").trim();\n if (!raw) {\n return null;\n }\n return raw.slice(0, 256);\n}\n\nfunction resolveTerminalSessionId(): CliContextResolution | null {\n if (!(process.stdin.isTTY || process.stdout.isTTY)) {\n return null;\n }\n\n const parentPid = Number(process.ppid);\n if (!Number.isInteger(parentPid) || parentPid <= 1) {\n return null;\n }\n\n return {\n cliContextId: `terminal-ppid-${parentPid}`,\n source: `terminal:ppid-${parentPid}`,\n };\n}\n\nfunction resolveStoredSessionOpenMeldProfileId(input: {\n openMeldProfileId?: unknown;\n profile?: unknown;\n}): OpenMeldProfileId | null {\n const openMeldProfileId = normalizeOptionalOpenMeldProfileId(\n input.openMeldProfileId\n );\n const legacyProfile = normalizeOptionalOpenMeldProfileId(input.profile);\n if (\n openMeldProfileId &&\n legacyProfile &&\n openMeldProfileId !== legacyProfile\n ) {\n throw new Error(\n `conflicting stored OpenMeld profile identity: openMeldProfileId=${openMeldProfileId}, profile=${legacyProfile}. Remove or reconcile the legacy profile field so it matches openMeldProfileId.`\n );\n }\n return openMeldProfileId ?? legacyProfile;\n}\n\nfunction resolveStoredSelectedOpenMeldProfileId(input: {\n selectedOpenMeldProfileId?: unknown;\n}): OpenMeldProfileId | null {\n return normalizeOptionalOpenMeldProfileId(input.selectedOpenMeldProfileId);\n}\n\nfunction normalizeOptionalOpenMeldProfileId(\n value: unknown\n): OpenMeldProfileId | null {\n if (typeof value !== \"string\") {\n return null;\n }\n try {\n return normalizeOpenMeldProfileId(value);\n } catch {\n return null;\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport { rmdirSync, unlinkSync } from \"node:fs\";\nimport {\n lstat,\n mkdir,\n open,\n readdir,\n rmdir,\n unlink,\n writeFile,\n} from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport process from \"node:process\";\nimport type { LocalMachineIssue } from \"@openmeld/schemas\";\nimport {\n createOrphanedLocalConcurrencyIssue,\n toRecognizedLocalMachineFailureError,\n} from \"../system/local-machine-recovery\";\nimport {\n CURRENT_PROCESS_START_IDENTITY,\n isPreciseProcessStartIdentity,\n isProcessIdentityAlive,\n readProcessStartIdentity,\n} from \"../system/process-identity\";\nimport { resolveOpenMeldLaneDescriptor } from \"./openmeld-lane-descriptor\";\nimport {\n normalizeOpenMeldProfileId,\n type OpenMeldPathResolutionInput,\n locksDir as resolveLocksDir,\n runtimeDir as resolveRuntimeDir,\n} from \"./paths\";\nimport { resolveCliContextId } from \"./session-profile\";\n\nexport type OpenMeldLock = {\n ownerId: string;\n path: string;\n};\n\nexport type OpenMeldLockMeta = Record<string, unknown>;\nexport type OpenMeldLockContentionState = \"active\" | \"orphaned\" | \"unknown\";\nexport type OpenMeldLegacyLockRepairReport = {\n removedOrphanedLegacyLocks: number;\n};\ntype HeldLockReleaseContext = Record<string, unknown>;\nconst MALFORMED_LOCK_RECOVERY_GRACE_MS = 30_000;\nconst OPENMELD_ORPHANED_LOCK_SUMMARY =\n \"OpenMeld found a local command lock left by an older version.\";\n\nexport class OpenMeldLockError extends Error {\n readonly code = \"openmeld.locked\";\n readonly lockPath: string;\n readonly lockKey: string;\n readonly metaRaw: string | null;\n readonly meta: OpenMeldLockMeta | null;\n readonly contentionState: OpenMeldLockContentionState;\n\n constructor(input: {\n path: string;\n key: string;\n metaRaw?: string;\n contentionState?: OpenMeldLockContentionState;\n }) {\n const normalizedMetaRaw = normalizeMetaRaw(input.metaRaw);\n const contentionState = input.contentionState ?? \"unknown\";\n super(\n buildOpenMeldLockErrorMessage(\n input.path,\n normalizedMetaRaw,\n contentionState\n )\n );\n this.name = \"OpenMeldLockError\";\n this.lockPath = input.path;\n this.lockKey = input.key;\n this.metaRaw = normalizedMetaRaw;\n this.meta = parseOpenMeldLockMeta(normalizedMetaRaw);\n this.contentionState = contentionState;\n }\n}\n\nexport function isOpenMeldLockError(\n error: unknown\n): error is OpenMeldLockError {\n return error instanceof OpenMeldLockError;\n}\n\nexport function isOpenMeldOrphanedLockError(\n error: unknown\n): error is OpenMeldLockError {\n return isOpenMeldLockError(error) && error.contentionState === \"orphaned\";\n}\n\nexport function resolveOpenMeldOrphanedLockIssue(\n error: unknown\n): LocalMachineIssue | null {\n if (!isOpenMeldOrphanedLockError(error)) {\n return null;\n }\n return createOrphanedLocalConcurrencyIssue({\n summary: OPENMELD_ORPHANED_LOCK_SUMMARY,\n primaryAction: buildOpenMeldOrphanedLockAction(),\n detail: error.message,\n });\n}\n\nexport function buildOpenMeldOrphanedLockAction(): string {\n const repairCommand = resolveOpenMeldLaneDescriptor().repairCommand;\n return `Close any other OpenMeld commands, then run \\`${repairCommand}\\` and try again.`;\n}\n\nexport async function acquireLock(input: {\n openMeldProfileId: string;\n key: string;\n meta?: OpenMeldLockMeta;\n pathResolution?: OpenMeldPathResolutionInput;\n}): Promise<OpenMeldLock> {\n const openMeldProfileId = normalizeOpenMeldProfileId(input.openMeldProfileId);\n const sessionId = resolveCliContextId();\n const dir = resolveLocksDir(openMeldProfileId, input.pathResolution);\n const path = resolveLockPath({\n openMeldProfileId,\n key: input.key,\n pathResolution: input.pathResolution,\n });\n const ownerId = randomUUID();\n try {\n await mkdir(dir, { recursive: true });\n } catch (error) {\n throwRecognizedLocalMachineFailure({\n operation: \"create_lock\",\n error,\n });\n }\n\n // A directory is the atomic ownership boundary. Its owner-specific entry\n // lets release remove only the lock it acquired, even if another process\n // publishes a replacement at the same canonical path.\n for (let attempt = 0; attempt < 2; attempt++) {\n const contents = `${JSON.stringify({\n ...(input.meta ? { ...input.meta } : {}),\n pid: process.pid,\n ownerProcessStartedAt: CURRENT_PROCESS_START_IDENTITY,\n openMeldProfileId,\n ...(sessionId ? { sessionId } : {}),\n at: new Date().toISOString(),\n ownerId,\n })}\\n`;\n let published: boolean;\n try {\n published = await tryPublishLock(path, ownerId, contents);\n } catch (error) {\n throwRecognizedLocalMachineFailure({\n operation: \"create_lock\",\n error,\n });\n }\n if (published) {\n return { ownerId, path };\n }\n\n try {\n const existingLock = await readLockSnapshot(path);\n if (\n !existingLock.exists ||\n (await tryCleanupStaleLockPath(path, existingLock))\n ) {\n continue;\n }\n\n throw new OpenMeldLockError({\n path,\n key: input.key,\n metaRaw: existingLock.metaRaw ?? undefined,\n contentionState: resolveLockContentionState(existingLock),\n });\n } catch (error) {\n if (isOpenMeldLockError(error)) {\n throw error;\n }\n throwRecognizedLocalMachineFailure({\n operation: \"create_lock\",\n error,\n });\n }\n }\n\n throw new OpenMeldLockError({\n path,\n key: input.key,\n });\n}\n\nexport async function releaseLock(lock: OpenMeldLock): Promise<void> {\n const removedOwnerEntry = await unlinkOwnedDirectoryEntry(lock);\n if (!removedOwnerEntry) {\n return;\n }\n await rmdir(lock.path).catch((error) => {\n if (![\"ENOENT\", \"ENOTEMPTY\"].includes(getErrorCode(error) ?? \"\")) {\n throw error;\n }\n });\n}\n\n/** Attach a waiting native process before granting it permission to exec. */\nexport async function attachLockProcess(\n lock: OpenMeldLock,\n pid: number\n): Promise<OpenMeldLock> {\n const ownerProcessStartedAt = readProcessStartIdentity(pid);\n if (!isPreciseProcessStartIdentity(ownerProcessStartedAt)) {\n throw new Error(\"Cannot establish native command process identity.\");\n }\n const parent = await open(\n resolveOwnerEntryPath(lock.path, lock.ownerId),\n \"r\"\n );\n try {\n const meta = parseOpenMeldLockMeta(await parent.readFile(\"utf8\"));\n if (\n meta?.ownerId !== lock.ownerId ||\n meta.pid !== process.pid ||\n meta.ownerProcessStartedAt !== CURRENT_PROCESS_START_IDENTITY\n ) {\n throw new Error(\"Native command does not own the lifecycle lock.\");\n }\n const participant = { path: lock.path, ownerId: randomUUID() };\n const contents = `${JSON.stringify({\n ownerId: participant.ownerId,\n parentOwnerId: lock.ownerId,\n pid,\n ownerProcessStartedAt,\n at: new Date().toISOString(),\n })}\\n`;\n await writeFile(\n resolveOwnerEntryPath(lock.path, participant.ownerId),\n contents,\n {\n encoding: \"utf8\",\n flag: \"wx\",\n mode: 0o600,\n }\n );\n // A failed attachment must never grant execution. Keep its entry until\n // the waiting process exits; subsequent recovery proves that identity dead.\n const snapshot = await readLockSnapshot(lock.path);\n if (\n readProcessStartIdentity(pid) !== ownerProcessStartedAt ||\n !(snapshot.ownerEntryNames ?? [snapshot.ownerEntryName]).includes(\n `${encodeURIComponent(participant.ownerId)}.owner.json`\n )\n ) {\n throw new Error(\n \"Native command lifecycle attachment could not be verified.\"\n );\n }\n return participant;\n } finally {\n await parent.close();\n }\n}\n\nexport function releaseLockSync(lock: OpenMeldLock): void {\n try {\n unlinkSync(resolveOwnerEntryPath(lock.path, lock.ownerId));\n } catch (error) {\n if (getErrorCode(error) === \"ENOENT\" || getErrorCode(error) === \"ENOTDIR\") {\n return;\n }\n throw error;\n }\n\n try {\n rmdirSync(lock.path);\n } catch (error) {\n if (getErrorCode(error) === \"ENOENT\") {\n return;\n }\n throw error;\n }\n}\n\nexport async function runWithCleanupPreservingRunError<T>(input: {\n run: () => Promise<T>;\n cleanup: () => Promise<void>;\n onCleanupErrorAfterRunFailure?: (cleanupError: unknown) => void;\n}): Promise<T> {\n let runResult: T | undefined;\n let runSucceeded = false;\n let runError: unknown;\n\n try {\n runResult = await input.run();\n runSucceeded = true;\n } catch (error) {\n runError = error;\n }\n\n try {\n await input.cleanup();\n } catch (cleanupError) {\n if (!runSucceeded) {\n input.onCleanupErrorAfterRunFailure?.(cleanupError);\n throw runError;\n }\n throw cleanupError;\n }\n\n if (!runSucceeded) {\n throw runError;\n }\n\n return runResult as T;\n}\n\nexport async function runWithHeldLock<T>(input: {\n lock: OpenMeldLock;\n run: () => Promise<T>;\n releaseContext?: HeldLockReleaseContext;\n}): Promise<T> {\n return await runWithCleanupPreservingRunError({\n run: input.run,\n cleanup: () => releaseLock(input.lock),\n onCleanupErrorAfterRunFailure: (releaseError) => {\n warnLockReleaseFailure({\n error: releaseError,\n lock: input.lock,\n releaseContext: input.releaseContext,\n });\n },\n });\n}\n\nexport async function readLockMeta(input: {\n openMeldProfileId: string;\n key: string;\n pathResolution?: OpenMeldPathResolutionInput;\n}): Promise<OpenMeldLockMeta | null> {\n const existingLock = await readLockSnapshot(\n resolveLockPath({\n openMeldProfileId: input.openMeldProfileId,\n key: input.key,\n pathResolution: input.pathResolution,\n })\n );\n return existingLock.meta;\n}\n\nexport async function tryCleanupStaleLock(input: {\n openMeldProfileId: string;\n key: string;\n pathResolution?: OpenMeldPathResolutionInput;\n}): Promise<boolean> {\n return await tryCleanupStaleLockPath(\n resolveLockPath({\n openMeldProfileId: input.openMeldProfileId,\n key: input.key,\n pathResolution: input.pathResolution,\n })\n );\n}\n\nexport async function repairOrphanedLegacyLock(input: {\n openMeldProfileId: string;\n key: string;\n}): Promise<boolean> {\n const path = resolveLockPath({\n openMeldProfileId: input.openMeldProfileId,\n key: input.key,\n });\n return await repairOrphanedLegacyLockPath(path);\n}\n\nexport async function repairOrphanedLegacyLocks(): Promise<OpenMeldLegacyLockRepairReport> {\n const locksRootPath = join(resolveRuntimeDir(), \"locks\");\n const profileEntries = await readDirectoryEntries(locksRootPath);\n let removedOrphanedLegacyLocks = 0;\n\n for (const profileEntry of profileEntries.sort((left, right) =>\n left.name.localeCompare(right.name)\n )) {\n if (!profileEntry.isDirectory()) {\n continue;\n }\n const profileLocksPath = join(locksRootPath, profileEntry.name);\n const lockEntries = await readDirectoryEntries(profileLocksPath);\n for (const lockEntry of lockEntries.sort((left, right) =>\n left.name.localeCompare(right.name)\n )) {\n if (!(lockEntry.isFile() && lockEntry.name.endsWith(\".lock\"))) {\n continue;\n }\n if (\n await repairOrphanedLegacyLockPath(\n join(profileLocksPath, lockEntry.name)\n )\n ) {\n removedOrphanedLegacyLocks += 1;\n }\n }\n }\n\n return { removedOrphanedLegacyLocks };\n}\n\nasync function repairOrphanedLegacyLockPath(path: string): Promise<boolean> {\n const firstSnapshot = await readLockSnapshot(path);\n if (\n firstSnapshot.storageKind !== \"legacy_file\" ||\n !isRecoverableStaleLock(firstSnapshot)\n ) {\n return false;\n }\n\n const confirmedSnapshot = await readLockSnapshot(path);\n if (!isSameRecoverableLockSnapshot(firstSnapshot, confirmedSnapshot)) {\n return false;\n }\n\n try {\n // Ordinary lock acquisition never unlinks legacy files because an older\n // client may replace one concurrently. This path is reserved for the\n // explicit local-state repair action after the user has closed other\n // OpenMeld commands that could publish a legacy lock at this path.\n await unlink(path);\n return true;\n } catch (error) {\n if (getErrorCode(error) === \"ENOENT\" || getErrorCode(error) === \"EISDIR\") {\n return false;\n }\n throw error;\n }\n}\n\nasync function readDirectoryEntries(path: string) {\n return await readdir(path, { withFileTypes: true }).catch((error) => {\n if (getErrorCode(error) === \"ENOENT\") {\n return [];\n }\n throw error;\n });\n}\n\ntype LockSnapshot = {\n exists: boolean;\n fileIdentity: string | null;\n ownerEntryName: string | null;\n ownerEntryNames?: string[];\n modifiedAtMs: number | null;\n metaRaw: string | null;\n meta: OpenMeldLockMeta | null;\n pid: number | null;\n hasStaleOwner: boolean;\n storageKind: \"directory\" | \"legacy_file\" | null;\n};\n\nfunction resolveLockPath(input: {\n openMeldProfileId: string;\n key: string;\n pathResolution?: OpenMeldPathResolutionInput;\n}): string {\n const openMeldProfileId = normalizeOpenMeldProfileId(input.openMeldProfileId);\n return join(\n resolveLocksDir(openMeldProfileId, input.pathResolution),\n `${sanitizeFilename(input.key)}.lock`\n );\n}\n\nfunction sanitizeFilename(value: string): string {\n return value.replace(/[^a-zA-Z0-9._-]+/g, \"_\");\n}\n\nfunction safeParse(value: string): unknown {\n try {\n return JSON.parse(value);\n } catch {\n return null;\n }\n}\n\nfunction normalizeMetaRaw(metaRaw: string | undefined): string | null {\n if (typeof metaRaw !== \"string\") {\n return null;\n }\n const normalized = metaRaw.trim();\n return normalized.length > 0 ? normalized : null;\n}\n\nfunction parseOpenMeldLockMeta(\n metaRaw: string | null\n): OpenMeldLockMeta | null {\n if (!metaRaw) {\n return null;\n }\n const parsed = safeParse(metaRaw);\n if (!parsed || typeof parsed !== \"object\") {\n return null;\n }\n return parsed as OpenMeldLockMeta;\n}\n\nfunction buildOpenMeldLockErrorMessage(\n path: string,\n metaRaw: string | null,\n contentionState: OpenMeldLockContentionState\n): string {\n const lockDetail = metaRaw\n ? `space is locked (${path}). Meta: ${metaRaw}`\n : `space is locked (${path})`;\n if (contentionState !== \"orphaned\") {\n return lockDetail;\n }\n return `${lockDetail}. ${OPENMELD_ORPHANED_LOCK_SUMMARY} ${buildOpenMeldOrphanedLockAction()}`;\n}\n\nfunction getPidFromMeta(meta: unknown): number | null {\n if (!meta || typeof meta !== \"object\") {\n return null;\n }\n const pid = (meta as Record<string, unknown>).pid;\n return typeof pid === \"number\" ? pid : null;\n}\n\nfunction missingLockSnapshot(): LockSnapshot {\n return {\n exists: false,\n fileIdentity: null,\n ownerEntryName: null,\n modifiedAtMs: null,\n metaRaw: null,\n meta: null,\n pid: null,\n hasStaleOwner: false,\n storageKind: null,\n };\n}\n\nasync function readLockSnapshot(\n path: string,\n remainingRaceRetries = 2\n): Promise<LockSnapshot> {\n const pathStats = await lstat(path).catch((error) => {\n if (getErrorCode(error) === \"ENOENT\") {\n return null;\n }\n throw error;\n });\n if (!pathStats) {\n return missingLockSnapshot();\n }\n\n if (pathStats.isDirectory()) {\n try {\n return await readDirectoryLockSnapshot(path, pathStats);\n } catch (error) {\n if (\n remainingRaceRetries > 0 &&\n (getErrorCode(error) === \"ENOENT\" || getErrorCode(error) === \"ENOTDIR\")\n ) {\n return await readLockSnapshot(path, remainingRaceRetries - 1);\n }\n throw error;\n }\n }\n\n const handle = await open(path, \"r\").catch((error) => {\n if (getErrorCode(error) === \"ENOENT\") {\n return null;\n }\n if (remainingRaceRetries > 0 && getErrorCode(error) === \"EISDIR\") {\n return \"retry\" as const;\n }\n throw error;\n });\n if (handle === \"retry\") {\n return await readLockSnapshot(path, remainingRaceRetries - 1);\n }\n if (!handle) {\n return missingLockSnapshot();\n }\n\n try {\n const [metaRaw, stats] = await Promise.all([\n handle.readFile(\"utf8\"),\n handle.stat(),\n ]);\n const normalizedMetaRaw = normalizeMetaRaw(metaRaw);\n const meta = parseOpenMeldLockMeta(normalizedMetaRaw);\n const pid = getPidFromMeta(meta);\n return {\n exists: true,\n fileIdentity: `${stats.dev}:${stats.ino}:${stats.mtimeMs}:${stats.size}`,\n ownerEntryName: null,\n modifiedAtMs: stats.mtimeMs,\n metaRaw: normalizedMetaRaw,\n meta,\n pid,\n hasStaleOwner: isLockOwnerStale({ meta, pid }),\n storageKind: \"legacy_file\",\n };\n } finally {\n await handle.close();\n }\n}\n\nasync function readDirectoryLockSnapshot(\n path: string,\n pathStats: Awaited<ReturnType<typeof lstat>>,\n selectedEntry?: string\n): Promise<LockSnapshot> {\n const ownerEntries = (await readdir(path, { withFileTypes: true }))\n .filter((entry) => entry.isFile() && entry.name.endsWith(\".owner.json\"))\n .map((entry) => entry.name)\n .sort();\n const ownerEntryName =\n selectedEntry ?? (ownerEntries.length === 1 ? ownerEntries[0] : null);\n const directoryIdentity = `${pathStats.dev}:${pathStats.ino}:${pathStats.mtimeMs}`;\n\n if (!selectedEntry && ownerEntries.length > 1) {\n const snapshots = await Promise.all(\n ownerEntries.map((entry) =>\n readDirectoryLockSnapshot(path, pathStats, entry)\n )\n );\n const recognized = snapshots.every(\n (snapshot) =>\n typeof snapshot.meta?.ownerId === \"string\" &&\n snapshot.ownerEntryName ===\n `${encodeURIComponent(snapshot.meta.ownerId)}.owner.json` &&\n isPreciseProcessStartIdentity(snapshot.meta.ownerProcessStartedAt) &&\n snapshot.pid !== null\n );\n return {\n exists: true,\n fileIdentity: snapshots\n .map((snapshot) => snapshot.fileIdentity)\n .join(\"|\"),\n ownerEntryName: null,\n ownerEntryNames: recognized ? ownerEntries : undefined,\n modifiedAtMs: Number(pathStats.mtimeMs),\n metaRaw: null,\n meta: null,\n pid: recognized ? (snapshots[0]?.pid ?? null) : null,\n hasStaleOwner:\n recognized && snapshots.every((snapshot) => snapshot.hasStaleOwner),\n storageKind: \"directory\",\n };\n }\n\n if (!ownerEntryName) {\n return {\n exists: true,\n fileIdentity: `${directoryIdentity}:empty-or-malformed`,\n ownerEntryName: null,\n modifiedAtMs: Number(pathStats.mtimeMs),\n metaRaw: null,\n meta: null,\n pid: null,\n hasStaleOwner: false,\n storageKind: \"directory\",\n };\n }\n\n const ownerEntryPath = join(path, ownerEntryName);\n const handle = await open(ownerEntryPath, \"r\");\n try {\n const [metaRaw, stats] = await Promise.all([\n handle.readFile(\"utf8\"),\n handle.stat(),\n ]);\n const normalizedMetaRaw = normalizeMetaRaw(metaRaw);\n const meta = parseOpenMeldLockMeta(normalizedMetaRaw);\n const pid = getPidFromMeta(meta);\n return {\n exists: true,\n fileIdentity: `${directoryIdentity}:${ownerEntryName}:${stats.dev}:${stats.ino}:${stats.mtimeMs}:${stats.size}`,\n ownerEntryName,\n modifiedAtMs: stats.mtimeMs,\n metaRaw: normalizedMetaRaw,\n meta,\n pid,\n hasStaleOwner: isLockOwnerStale({ meta, pid }),\n storageKind: \"directory\",\n };\n } finally {\n await handle.close();\n }\n}\n\nasync function tryCleanupStaleLockPath(\n path: string,\n initialSnapshot?: LockSnapshot\n): Promise<boolean> {\n const firstSnapshot = initialSnapshot ?? (await readLockSnapshot(path));\n\n if (!isRecoverableStaleLock(firstSnapshot)) {\n return false;\n }\n\n // A legacy client can replace a stale file lock with a live file lock at the\n // same path between inspection and unlink. Without owner-scoped storage,\n // cleanup cannot prove that it is removing the same owner, so fail closed\n // throughout the mixed-version rollout.\n if (firstSnapshot.storageKind === \"legacy_file\") {\n return false;\n }\n\n const confirmedSnapshot = await readLockSnapshot(path);\n if (!isSameRecoverableLockSnapshot(firstSnapshot, confirmedSnapshot)) {\n return false;\n }\n\n if (confirmedSnapshot.storageKind === \"directory\") {\n return await cleanupStaleDirectoryLock(path, confirmedSnapshot);\n }\n\n return false;\n}\n\nfunction isSameRecoverableLockSnapshot(\n firstSnapshot: LockSnapshot,\n confirmedSnapshot: LockSnapshot\n): boolean {\n return (\n confirmedSnapshot.exists &&\n confirmedSnapshot.fileIdentity === firstSnapshot.fileIdentity &&\n confirmedSnapshot.ownerEntryName === firstSnapshot.ownerEntryName &&\n confirmedSnapshot.metaRaw === firstSnapshot.metaRaw &&\n confirmedSnapshot.pid === firstSnapshot.pid &&\n confirmedSnapshot.storageKind === firstSnapshot.storageKind &&\n isRecoverableStaleLock(confirmedSnapshot)\n );\n}\n\nfunction resolveLockContentionState(\n snapshot: LockSnapshot\n): OpenMeldLockContentionState {\n if (\n snapshot.storageKind === \"legacy_file\" &&\n isRecoverableStaleLock(snapshot)\n ) {\n return \"orphaned\";\n }\n if (\n snapshot.storageKind !== null &&\n (snapshot.pid === null || !snapshot.hasStaleOwner)\n ) {\n return \"active\";\n }\n return \"unknown\";\n}\n\nasync function cleanupStaleDirectoryLock(\n path: string,\n snapshot: LockSnapshot\n): Promise<boolean> {\n for (const entry of snapshot.ownerEntryNames ??\n (snapshot.ownerEntryName ? [snapshot.ownerEntryName] : [])) {\n try {\n await unlink(join(path, entry));\n } catch (error) {\n if (getErrorCode(error) === \"ENOENT\") {\n return false;\n }\n throw error;\n }\n }\n try {\n await rmdir(path);\n return true;\n } catch (error) {\n if (getErrorCode(error) === \"ENOENT\") {\n return true;\n }\n if (getErrorCode(error) === \"ENOTEMPTY\") {\n return false;\n }\n throw error;\n }\n}\n\nasync function tryPublishLock(\n path: string,\n ownerId: string,\n contents: string\n): Promise<boolean> {\n try {\n await mkdir(path);\n } catch (error) {\n if (getErrorCode(error) === \"EEXIST\") {\n return false;\n }\n throw error;\n }\n\n const ownerEntryPath = resolveOwnerEntryPath(path, ownerId);\n try {\n await writeFile(ownerEntryPath, contents, {\n encoding: \"utf8\",\n flag: \"wx\",\n });\n return true;\n } catch (error) {\n await unlink(ownerEntryPath).catch((cleanupError) => {\n if (getErrorCode(cleanupError) !== \"ENOENT\") {\n console.warn(\"[openmeld.lock.owner_entry_cleanup_warning]\", {\n ownerEntryPath,\n cleanupError: toErrorMessage(cleanupError),\n });\n }\n });\n await rmdir(path).catch((cleanupError) => {\n if (getErrorCode(cleanupError) !== \"ENOENT\") {\n console.warn(\"[openmeld.lock.directory_cleanup_warning]\", {\n lockPath: path,\n cleanupError: toErrorMessage(cleanupError),\n });\n }\n });\n throw error;\n }\n}\n\nasync function unlinkOwnedDirectoryEntry(lock: OpenMeldLock): Promise<boolean> {\n try {\n await unlink(resolveOwnerEntryPath(lock.path, lock.ownerId));\n return true;\n } catch (error) {\n if (getErrorCode(error) === \"ENOENT\" || getErrorCode(error) === \"ENOTDIR\") {\n return false;\n }\n throw error;\n }\n}\n\nfunction resolveOwnerEntryPath(path: string, ownerId: string): string {\n return join(path, `${encodeURIComponent(ownerId)}.owner.json`);\n}\n\nfunction isRecoverableStaleLock(snapshot: LockSnapshot): boolean {\n if (!snapshot.exists) {\n return false;\n }\n if (snapshot.pid !== null) {\n return snapshot.hasStaleOwner;\n }\n return (\n snapshot.modifiedAtMs !== null &&\n Date.now() - snapshot.modifiedAtMs >= MALFORMED_LOCK_RECOVERY_GRACE_MS\n );\n}\n\nfunction isLockOwnerStale(input: {\n meta: OpenMeldLockMeta | null;\n pid: number | null;\n}): boolean {\n if (input.pid === null) {\n return false;\n }\n const ownerProcessStartedAt = getProcessStartIdentityFromMeta(input.meta);\n if (!ownerProcessStartedAt) {\n // Locks from older clients do not carry process-start identity. Keep them\n // while their PID is live, but preserve the existing dead-PID recovery.\n return !isPidAlive(input.pid);\n }\n return !isProcessIdentityAlive({\n ownerPid: input.pid,\n ownerProcessStartedAt,\n });\n}\n\nfunction getProcessStartIdentityFromMeta(meta: unknown): string | null {\n if (!(meta && typeof meta === \"object\")) {\n return null;\n }\n const value = (meta as Record<string, unknown>).ownerProcessStartedAt;\n return typeof value === \"string\" && value.length > 0 ? value : null;\n}\n\nfunction isPidAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (err) {\n if (getErrorCode(err) === \"ESRCH\") {\n return false;\n }\n return true;\n }\n}\n\nfunction getErrorCode(err: unknown): string | undefined {\n if (!err || typeof err !== \"object\") {\n return undefined;\n }\n const code = (err as { code?: unknown }).code;\n return typeof code === \"string\" ? code : undefined;\n}\n\nfunction throwRecognizedLocalMachineFailure(input: {\n operation: \"create_lock\";\n error: unknown;\n}): never {\n const recognizedFailure = toRecognizedLocalMachineFailureError(input);\n throw recognizedFailure ?? input.error;\n}\n\nfunction warnLockReleaseFailure(input: {\n error: unknown;\n lock: OpenMeldLock;\n releaseContext?: HeldLockReleaseContext;\n}): void {\n console.warn(\"[openmeld.lock.release.warning]\", {\n lockPath: input.lock.path,\n releaseError: toErrorMessage(input.error),\n releaseContext: input.releaseContext ?? {},\n });\n}\n\nfunction toErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"],"mappings":"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"}