openmeld 0.3.225 → 0.3.227

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 (136) hide show
  1. package/dist/{add-me-membership-BUuys3IZ.js → add-me-membership-pkREbEJG.js} +2 -2
  2. package/dist/{add-me-membership-BUuys3IZ.js.map → add-me-membership-pkREbEJG.js.map} +1 -1
  3. package/dist/{agents-Blvf8wC0.js → agents-D_RojMEE.js} +11 -11
  4. package/dist/{agents-Blvf8wC0.js.map → agents-D_RojMEE.js.map} +1 -1
  5. package/dist/{api-client-foundation-CqbIn_de.js → api-client-foundation-CEScBsM7.js} +1 -1
  6. package/dist/{api-client-foundation-DpVwrgh-.js → api-client-foundation-Czb9hJvA.js} +3 -3
  7. package/dist/{api-client-foundation-DpVwrgh-.js.map → api-client-foundation-Czb9hJvA.js.map} +1 -1
  8. package/dist/{auth-session-uEk_Tx6T.js → auth-session-Q0B3Nfae.js} +5 -4
  9. package/dist/{auth-session-uEk_Tx6T.js.map → auth-session-Q0B3Nfae.js.map} +1 -1
  10. package/dist/auth-session-ga82_Wa9.js +4 -0
  11. package/dist/{base-url-DXrUiSMI.js → base-url-B8eWb2md.js} +1 -1
  12. package/dist/{base-url-DvjOkKPs.js → base-url-eck31vC8.js} +3 -2
  13. package/dist/{base-url-DvjOkKPs.js.map → base-url-eck31vC8.js.map} +1 -1
  14. package/dist/{channel-B2fD2_be.js → channel-B1gMWx__.js} +3 -3
  15. package/dist/{channel-B2fD2_be.js.map → channel-B1gMWx__.js.map} +1 -1
  16. package/dist/{cli-binary-manifest-CT5X05lk.js → cli-binary-manifest-Bjf6T7Ef.js} +2 -2
  17. package/dist/{cli-binary-manifest-CT5X05lk.js.map → cli-binary-manifest-Bjf6T7Ef.js.map} +1 -1
  18. package/dist/{command-Cjxx-f4g.js → command-B5E_YSAY.js} +18 -17
  19. package/dist/{command-Cjxx-f4g.js.map → command-B5E_YSAY.js.map} +1 -1
  20. package/dist/{computer-connection-Dm7iTnRK.js → computer-connection-BbDdF_MD.js} +2 -2
  21. package/dist/{computer-connection-Dm7iTnRK.js.map → computer-connection-BbDdF_MD.js.map} +1 -1
  22. package/dist/{computer-connection-review-De0X_5c4.js → computer-connection-review-Dop02mby.js} +6 -6
  23. package/dist/{computer-connection-review-De0X_5c4.js.map → computer-connection-review-Dop02mby.js.map} +1 -1
  24. package/dist/{computer-disconnect-CvBzCJF9.js → computer-disconnect-pH6HaHQq.js} +9 -9
  25. package/dist/{computer-disconnect-CvBzCJF9.js.map → computer-disconnect-pH6HaHQq.js.map} +1 -1
  26. package/dist/{computer-setup-continuation-CaUPhhdb.js → computer-setup-continuation-BhM3HsRI.js} +3 -3
  27. package/dist/{computer-setup-continuation-CaUPhhdb.js.map → computer-setup-continuation-BhM3HsRI.js.map} +1 -1
  28. package/dist/{context-Bdh3nAzw.js → context-D3kAC8RG.js} +5 -5
  29. package/dist/{context-Bdh3nAzw.js.map → context-D3kAC8RG.js.map} +1 -1
  30. package/dist/{daemon-device-id-B1Af2Zmn.js → daemon-device-id-DEGf1fm6.js} +7 -6
  31. package/dist/{daemon-device-id-B1Af2Zmn.js.map → daemon-device-id-DEGf1fm6.js.map} +1 -1
  32. package/dist/{daemon-frame-transport-CSvV88PL.js → daemon-frame-transport-BMZP90f0.js} +10 -9
  33. package/dist/{daemon-frame-transport-CSvV88PL.js.map → daemon-frame-transport-BMZP90f0.js.map} +1 -1
  34. package/dist/{daemon-lifecycle-journal-ChhAF8yX.js → daemon-lifecycle-journal-NeBAn_SY.js} +27 -12
  35. package/dist/daemon-lifecycle-journal-NeBAn_SY.js.map +1 -0
  36. package/dist/{daemon-runtime-lease-1LMeZ6IS.js → daemon-runtime-lease-C1wkT4Bi.js} +2 -2
  37. package/dist/{daemon-runtime-lease-1LMeZ6IS.js.map → daemon-runtime-lease-C1wkT4Bi.js.map} +1 -1
  38. package/dist/{daemon-runtime-lease-Bz0ucJj3.js → daemon-runtime-lease-DAQyRUc5.js} +1 -1
  39. package/dist/{daemon-service-contract-GLmAxsq-.js → daemon-service-contract-DhEfbzHt.js} +4 -4
  40. package/dist/{daemon-service-contract-GLmAxsq-.js.map → daemon-service-contract-DhEfbzHt.js.map} +1 -1
  41. package/dist/{daemon-service-manager-C8RUCMDo.js → daemon-service-manager-CRnFxPKA.js} +6 -5
  42. package/dist/{daemon-service-manager-C8RUCMDo.js.map → daemon-service-manager-CRnFxPKA.js.map} +1 -1
  43. package/dist/{daemon-service-manager-CU-79a4z.js → daemon-service-manager-l0unaDGa.js} +1 -1
  44. package/dist/{daemon-service-runtime-BtqJMt8J.js → daemon-service-runtime-nIBQreis.js} +27 -153
  45. package/dist/daemon-service-runtime-nIBQreis.js.map +1 -0
  46. package/dist/{daemon-service-update-coordinator-BczvSdXA.js → daemon-service-update-coordinator-BdcEl-QC.js} +22 -20
  47. package/dist/daemon-service-update-coordinator-BdcEl-QC.js.map +1 -0
  48. package/dist/{daemon-state-Ca0WK5x0.js → daemon-state-B6G5xe7f.js} +4 -3
  49. package/dist/{daemon-state-Ca0WK5x0.js.map → daemon-state-B6G5xe7f.js.map} +1 -1
  50. package/dist/{dist-C32frPV2.js → dist-C5emSnFG.js} +1 -1
  51. package/dist/{dist-BeJcIdCZ.js → dist-DkN9tKMX.js} +127 -284
  52. package/dist/dist-DkN9tKMX.js.map +1 -0
  53. package/dist/{dist-YbTZ-Y-2.js → dist-vpxgF6Lp.js} +2 -2
  54. package/dist/{dist-YbTZ-Y-2.js.map → dist-vpxgF6Lp.js.map} +1 -1
  55. package/dist/{elapsed-time-Dvn2LxSm.js → elapsed-time-BxMWSsxC.js} +5 -5
  56. package/dist/{elapsed-time-Dvn2LxSm.js.map → elapsed-time-BxMWSsxC.js.map} +1 -1
  57. package/dist/{entry-B19Dcymp.js → entry-jvTvDBr-.js} +12 -11
  58. package/dist/{entry-B19Dcymp.js.map → entry-jvTvDBr-.js.map} +1 -1
  59. package/dist/{installation-inventory-BmZVMUzJ.js → installation-inventory-Bf1SvGVh.js} +5 -5
  60. package/dist/{installation-inventory-BmZVMUzJ.js.map → installation-inventory-Bf1SvGVh.js.map} +1 -1
  61. package/dist/{installer-DAZpeNXo.js → installer-IVAr1ZD-.js} +2 -2
  62. package/dist/{installer-DAZpeNXo.js.map → installer-IVAr1ZD-.js.map} +1 -1
  63. package/dist/{lock-iue1J2xy.js → lock-CMH9eoS7.js} +5 -270
  64. package/dist/lock-CMH9eoS7.js.map +1 -0
  65. package/dist/{meta-api-eV9exiaO.js → meta-api-BYB9vhya.js} +8 -8
  66. package/dist/{meta-api-eV9exiaO.js.map → meta-api-BYB9vhya.js.map} +1 -1
  67. package/dist/{openmeld-DEbL_TIZ.js → openmeld-0pnb6g3R.js} +63 -38
  68. package/dist/{openmeld-DEbL_TIZ.js.map → openmeld-0pnb6g3R.js.map} +1 -1
  69. package/dist/openmeld-dev.js +1 -1
  70. package/dist/{openmeld-environment-target-BBn5Ko6p.js → openmeld-environment-target-Cw3V0WnE.js} +3 -3
  71. package/dist/{openmeld-environment-target-BBn5Ko6p.js.map → openmeld-environment-target-Cw3V0WnE.js.map} +1 -1
  72. package/dist/{openmeld-maintenance-worker-Ds8LpQ1c.js → openmeld-maintenance-worker-CSes51Vp.js} +14 -14
  73. package/dist/{openmeld-maintenance-worker-Ds8LpQ1c.js.map → openmeld-maintenance-worker-CSes51Vp.js.map} +1 -1
  74. package/dist/{openmeld-tools-update-join-DV_THLes.js → openmeld-tools-update-join-BlPynw_v.js} +4 -4
  75. package/dist/{openmeld-tools-update-join-DV_THLes.js.map → openmeld-tools-update-join-BlPynw_v.js.map} +1 -1
  76. package/dist/openmeld.js +8 -4
  77. package/dist/openmeld.js.map +1 -1
  78. package/dist/paths-DSkUuEu3.js +273 -0
  79. package/dist/paths-DSkUuEu3.js.map +1 -0
  80. package/dist/{prepare-provider-runtime-CP88BnLy.js → prepare-provider-runtime-DSKQFj-R.js} +94 -28
  81. package/dist/prepare-provider-runtime-DSKQFj-R.js.map +1 -0
  82. package/dist/{prepare-session-executor-Dt5hHfsR.js → prepare-session-executor-DEJ9OaJh.js} +25 -24
  83. package/dist/{prepare-session-executor-Dt5hHfsR.js.map → prepare-session-executor-DEJ9OaJh.js.map} +1 -1
  84. package/dist/{process-channel-CgbduFCz.js → process-channel-BIumgluJ.js} +2 -2
  85. package/dist/{process-channel-CgbduFCz.js.map → process-channel-BIumgluJ.js.map} +1 -1
  86. package/dist/{process-identity-BQLdaZdB.js → process-identity-BRbhGGTM.js} +2 -2
  87. package/dist/{process-identity-BQLdaZdB.js.map → process-identity-BRbhGGTM.js.map} +1 -1
  88. package/dist/{published-production-safety-C40hKrBA.js → published-production-safety-CgXxtdMK.js} +2 -2
  89. package/dist/{published-production-safety-C40hKrBA.js.map → published-production-safety-CgXxtdMK.js.map} +1 -1
  90. package/dist/{runtime-4_VPSImW.js → runtime-Du3Az4wt.js} +18 -18
  91. package/dist/{runtime-4_VPSImW.js.map → runtime-Du3Az4wt.js.map} +1 -1
  92. package/dist/{runtime-agent-controller-reporting-submission-OpySJXCT.js → runtime-agent-controller-reporting-submission-Bl2CWQ96.js} +12 -10
  93. package/dist/runtime-agent-controller-reporting-submission-Bl2CWQ96.js.map +1 -0
  94. package/dist/{runtime-reporting-health-state-B14XCJQF.js → runtime-reporting-health-state-CKmph14R.js} +14 -13
  95. package/dist/{runtime-reporting-health-state-B14XCJQF.js.map → runtime-reporting-health-state-CKmph14R.js.map} +1 -1
  96. package/dist/{runtime-transport-YIYHSJPn.js → runtime-transport-DUR91mKK.js} +205 -5
  97. package/dist/runtime-transport-DUR91mKK.js.map +1 -0
  98. package/dist/{service-v9KNVG7t.js → service-Bh1iD84k.js} +30 -29
  99. package/dist/service-Bh1iD84k.js.map +1 -0
  100. package/dist/{service-account-authorization-DZbUOD29.js → service-account-authorization-CyV8YFAw.js} +6 -6
  101. package/dist/{service-account-authorization-DZbUOD29.js.map → service-account-authorization-CyV8YFAw.js.map} +1 -1
  102. package/dist/{service-account-control-DguBlRfW.js → service-account-control-Cc6qVa0m.js} +14 -14
  103. package/dist/{service-account-control-DguBlRfW.js.map → service-account-control-Cc6qVa0m.js.map} +1 -1
  104. package/dist/{service-control-capabilities-fFuX3GbE.js → service-control-capabilities-CdVTTNRK.js} +1 -1
  105. package/dist/{service-control-capabilities-CQb9zWvz.js → service-control-capabilities-D4W3WTHS.js} +5 -5
  106. package/dist/{service-control-capabilities-CQb9zWvz.js.map → service-control-capabilities-D4W3WTHS.js.map} +1 -1
  107. package/dist/{service-control-carrier-capability-gMk5gMKU.js → service-control-carrier-capability-SuKbNKaR.js} +2 -2
  108. package/dist/{service-control-carrier-capability-gMk5gMKU.js.map → service-control-carrier-capability-SuKbNKaR.js.map} +1 -1
  109. package/dist/{state-B7JOni3p.js → state-ClTXLNB3.js} +3 -3
  110. package/dist/{state-B7JOni3p.js.map → state-ClTXLNB3.js.map} +1 -1
  111. package/dist/{upgrade-DnWyXA1G.js → upgrade-B07Dh83M.js} +8 -8
  112. package/dist/{upgrade-DnWyXA1G.js.map → upgrade-B07Dh83M.js.map} +1 -1
  113. package/dist/upgrade-DgTfV7-m.js +4 -0
  114. package/dist/windows/openmeld-windows-process.exe +0 -0
  115. package/dist/{windows-artifact-DJ9DKjfc.js → windows-artifact-D99JU1ll.js} +3 -2
  116. package/dist/{windows-artifact-DJ9DKjfc.js.map → windows-artifact-D99JU1ll.js.map} +1 -1
  117. package/dist/windows-managed-install-BVlswqjA.js +146 -0
  118. package/dist/windows-managed-install-BVlswqjA.js.map +1 -0
  119. package/dist/windows-preview-channel-DPrYuLyY.js +32 -0
  120. package/dist/windows-preview-channel-DPrYuLyY.js.map +1 -0
  121. package/dist/{windows-user-task-Io5QuEVR.js → windows-user-task-BR-WB7hr.js} +5 -5
  122. package/dist/{windows-user-task-Io5QuEVR.js.map → windows-user-task-BR-WB7hr.js.map} +1 -1
  123. package/dist/{windows-user-task-B8NcRg_u.js → windows-user-task-m9eMEUEq.js} +1 -1
  124. package/package.json +11 -11
  125. package/skills/openmeld-cli/playbooks/plugins.md +12 -0
  126. package/dist/auth-session-BJfKu74u.js +0 -4
  127. package/dist/daemon-lifecycle-journal-ChhAF8yX.js.map +0 -1
  128. package/dist/daemon-service-runtime-BtqJMt8J.js.map +0 -1
  129. package/dist/daemon-service-update-coordinator-BczvSdXA.js.map +0 -1
  130. package/dist/dist-BeJcIdCZ.js.map +0 -1
  131. package/dist/lock-iue1J2xy.js.map +0 -1
  132. package/dist/prepare-provider-runtime-CP88BnLy.js.map +0 -1
  133. package/dist/runtime-agent-controller-reporting-submission-OpySJXCT.js.map +0 -1
  134. package/dist/runtime-transport-YIYHSJPn.js.map +0 -1
  135. package/dist/service-v9KNVG7t.js.map +0 -1
  136. package/dist/upgrade-Cy4bMox8.js +0 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"windows-managed-install-BVlswqjA.js","names":[],"sources":["../src/local-components/windows-managed-install.ts"],"sourcesContent":["import { createHash, randomUUID } from \"node:crypto\";\nimport { createReadStream } from \"node:fs\";\nimport {\n copyFile,\n lstat,\n mkdir,\n mkdtemp,\n readdir,\n readFile,\n rename,\n rm,\n writeFile,\n} from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport {\n WINDOWS_PROCESS_HELPER_FILENAME,\n windowsManagedCliInstallationSchema,\n} from \"@openmeld/schemas\";\n\nconst INSTALLATION_RECORD = \"cli-installation.json\";\nconst CLI_FILENAME = \"openmeld.exe\";\nconst RETIRED_LAUNCHER = /^\\.retired-launcher-[a-f0-9-]{36}\\.exe$/u;\nconst STAGING_VERSION = /^\\.install-[A-Za-z0-9]{6}$/u;\n\nexport async function readWindowsManagedCliVersion(\n root: string\n): Promise<string | null> {\n return (await readWindowsManagedCliInstallation(root))?.version ?? null;\n}\n\nexport async function readWindowsManagedCliInstallation(\n root: string\n): Promise<{ version: string; releaseChannel?: \"windows-preview\" } | null> {\n const serialized = await readFile(\n join(root, \"bin\", INSTALLATION_RECORD),\n \"utf8\"\n ).catch((error) => {\n if (hasCode(error, \"ENOENT\")) {\n return null;\n }\n throw error;\n });\n if (serialized === null) {\n return null;\n }\n const parsed = windowsManagedCliInstallationSchema.safeParse(\n JSON.parse(serialized)\n );\n if (!parsed.success) {\n throw new Error(\n \"The managed Windows CLI installation record is invalid. No version was selected.\"\n );\n }\n return parsed.data;\n}\n\n/** Publish the complete immutable directory, never overwrite an in-use image. */\nexport async function placeWindowsManagedVersion(input: {\n root: string;\n version: string;\n sourceBinary: string;\n}): Promise<void> {\n const { version } = windowsManagedCliInstallationSchema.parse({\n schemaVersion: 1,\n version: input.version,\n });\n const versions = join(input.root, \"versions\");\n const destination = join(versions, version);\n const sources = [\n { source: input.sourceBinary, name: CLI_FILENAME },\n {\n source: join(\n dirname(input.sourceBinary),\n WINDOWS_PROCESS_HELPER_FILENAME\n ),\n name: WINDOWS_PROCESS_HELPER_FILENAME,\n },\n ];\n if (await entryExists(destination)) {\n for (const { source, name } of sources) {\n if (!(await sameFileBytes(source, join(destination, name)))) {\n throw new Error(\n `The installed Windows CLI ${version} differs from the selected artifact. Published versions are immutable; acquire a new release instead of overwriting this installation.`\n );\n }\n }\n return;\n }\n await mkdir(versions, { recursive: true });\n // No executable is ever launched from staging. The shared install lock makes\n // these exact installer-owned leftovers from interrupted copies safe to remove.\n for (const entry of await readdir(versions, { withFileTypes: true })) {\n if (entry.isDirectory() && STAGING_VERSION.test(entry.name)) {\n await rm(join(versions, entry.name), { recursive: true });\n }\n }\n const staging = await mkdtemp(join(versions, \".install-\"));\n try {\n for (const { source, name } of sources) {\n await copyFile(source, join(staging, name));\n }\n await rename(staging, destination);\n } finally {\n await rm(staging, { recursive: true, force: true });\n }\n}\n\n/** The caller holds the shared managed-install lock. Record replacement is the commit. */\nexport async function activateWindowsManagedCli(\n root: string,\n version: string,\n releaseChannel?: \"windows-preview\"\n): Promise<void> {\n const record = windowsManagedCliInstallationSchema.parse({\n schemaVersion: 1,\n version,\n ...(releaseChannel ? { releaseChannel } : {}),\n });\n await reconcileWindowsManagedLauncher(root, version);\n const destination = join(root, \"bin\", INSTALLATION_RECORD);\n const temporary = `${destination}.${randomUUID()}.tmp`;\n try {\n await writeFile(temporary, `${JSON.stringify(record)}\\n`, {\n flag: \"wx\",\n mode: 0o600,\n });\n await rename(temporary, destination);\n } finally {\n await rm(temporary, { force: true });\n }\n}\n\n/**\n * Repair from the authoritative version record. An interrupted launcher swap\n * can leave bin/openmeld.exe absent; install/maintenance restore it from the\n * immutable version without changing account data or selecting another version.\n */\nexport async function reconcileWindowsManagedLauncher(\n root: string,\n version: string\n): Promise<void> {\n windowsManagedCliInstallationSchema.parse({ schemaVersion: 1, version });\n const source = join(\n root,\n \"versions\",\n version,\n WINDOWS_PROCESS_HELPER_FILENAME\n );\n const bin = join(root, \"bin\");\n const launcher = join(bin, CLI_FILENAME);\n await mkdir(bin, { recursive: true });\n for (const entry of await readdir(bin, { withFileTypes: true })) {\n if (entry.isFile() && RETIRED_LAUNCHER.test(entry.name)) {\n await removeRetiredLauncher(join(bin, entry.name));\n }\n }\n if (await sameFileBytes(source, launcher)) {\n return;\n }\n const temporary = join(bin, `.launcher-${randomUUID()}.tmp`);\n const retired = join(bin, `.retired-launcher-${randomUUID()}.exe`);\n await copyFile(source, temporary);\n let movedPrevious = false;\n try {\n if (await entryExists(launcher)) {\n await rename(launcher, retired);\n movedPrevious = true;\n }\n try {\n await rename(temporary, launcher);\n } catch (error) {\n if (movedPrevious) {\n await rename(retired, launcher);\n }\n throw error;\n }\n // A running launcher retains its renamed image until it exits. Only this\n // transaction's retired image is considered here; never remove by process name.\n if (movedPrevious) {\n await removeRetiredLauncher(retired);\n }\n } finally {\n await rm(temporary, { force: true });\n }\n}\n\nasync function removeRetiredLauncher(file: string): Promise<void> {\n await rm(file).catch((error) => {\n if (hasCode(error, \"EPERM\") || hasCode(error, \"EBUSY\")) {\n return;\n }\n throw error;\n });\n}\n\nasync function entryExists(file: string): Promise<boolean> {\n return await lstat(file).then(\n () => true,\n (error) => {\n if (hasCode(error, \"ENOENT\")) {\n return false;\n }\n throw error;\n }\n );\n}\n\nasync function sameFileBytes(left: string, right: string): Promise<boolean> {\n const [leftStat, rightStat] = await Promise.all([\n lstat(left),\n lstat(right).catch((error) => {\n if (hasCode(error, \"ENOENT\")) {\n return null;\n }\n throw error;\n }),\n ]);\n if (\n !(leftStat.isFile() && rightStat?.isFile()) ||\n leftStat.size !== rightStat.size\n ) {\n return false;\n }\n const hash = async (file: string) => {\n const digest = createHash(\"sha256\");\n for await (const chunk of createReadStream(file)) {\n digest.update(chunk);\n }\n return digest.digest(\"hex\");\n };\n const [leftHash, rightHash] = await Promise.all([hash(left), hash(right)]);\n return leftHash === rightHash;\n}\n\nfunction hasCode(error: unknown, code: string): boolean {\n return (\n error !== null &&\n typeof error === \"object\" &&\n \"code\" in error &&\n error.code === code\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { I as resolveOpenMeldRootDir } from "./paths-DSkUuEu3.js";
4
+ import { t as WINDOWS_INTERNAL_PREVIEW_MANIFEST_URL } from "./windows-artifact-D99JU1ll.js";
5
+ import { t as isBinaryDistribution } from "./distribution-BDQT2ilb.js";
6
+ import { r as readWindowsManagedCliInstallation } from "./windows-managed-install-BVlswqjA.js";
7
+ import { join, normalize } from "node:path";
8
+ import process from "node:process";
9
+ //#region src/local-components/windows-preview-channel.ts
10
+ /** Restore the verified install choice before loading command modules. */
11
+ async function restoreWindowsPreviewChannel(runtime = {
12
+ platform: process.platform,
13
+ execPath: process.execPath,
14
+ env: process.env,
15
+ binaryDistribution: isBinaryDistribution(),
16
+ root: resolveOpenMeldRootDir()
17
+ }) {
18
+ if (runtime.platform !== "win32" || !runtime.binaryDistribution) return;
19
+ const installation = await readWindowsManagedCliInstallation(runtime.root);
20
+ if (installation?.releaseChannel !== "windows-preview") return;
21
+ const selectedBinary = join(runtime.root, "versions", installation.version, "openmeld.exe");
22
+ if (normalize(runtime.execPath).toLowerCase() !== normalize(selectedBinary).toLowerCase()) return;
23
+ if (runtime.env.OPENMELD_ENV_PRESET && runtime.env.OPENMELD_ENV_PRESET !== "prod") return;
24
+ if (runtime.env.OPENMELD_CLI_BINARY_MANIFEST_URL) return;
25
+ runtime.env.OPENMELD_ENV_PRESET = "prod";
26
+ runtime.env.OPENMELD_CLI_BINARY_MANIFEST_URL = WINDOWS_INTERNAL_PREVIEW_MANIFEST_URL;
27
+ runtime.env.OPENMELD_WINDOWS_INTERNAL_PREVIEW = "1";
28
+ }
29
+ //#endregion
30
+ export { restoreWindowsPreviewChannel };
31
+
32
+ //# sourceMappingURL=windows-preview-channel-DPrYuLyY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"windows-preview-channel-DPrYuLyY.js","names":[],"sources":["../src/local-components/windows-preview-channel.ts"],"sourcesContent":["import { join, normalize } from \"node:path\";\nimport process from \"node:process\";\nimport { WINDOWS_INTERNAL_PREVIEW_MANIFEST_URL } from \"@openmeld/schemas\";\nimport { resolveOpenMeldRootDir } from \"../config/paths\";\nimport { isBinaryDistribution } from \"../runtime/distribution\";\nimport { readWindowsManagedCliInstallation } from \"./windows-managed-install\";\n\n/** Restore the verified install choice before loading command modules. */\nexport async function restoreWindowsPreviewChannel(\n runtime: {\n platform: string;\n execPath: string;\n env: NodeJS.ProcessEnv;\n binaryDistribution: boolean;\n root: string;\n } = {\n platform: process.platform,\n execPath: process.execPath,\n env: process.env,\n binaryDistribution: isBinaryDistribution(),\n root: resolveOpenMeldRootDir(),\n }\n): Promise<void> {\n if (runtime.platform !== \"win32\" || !runtime.binaryDistribution) {\n return;\n }\n const installation = await readWindowsManagedCliInstallation(runtime.root);\n if (installation?.releaseChannel !== \"windows-preview\") {\n return;\n }\n const selectedBinary = join(\n runtime.root,\n \"versions\",\n installation.version,\n \"openmeld.exe\"\n );\n if (\n normalize(runtime.execPath).toLowerCase() !==\n normalize(selectedBinary).toLowerCase()\n ) {\n // A downloaded bootstrap or an unrelated CLI must not inherit this account's\n // unsigned channel just because an older preview is installed.\n return;\n }\n if (\n runtime.env.OPENMELD_ENV_PRESET &&\n runtime.env.OPENMELD_ENV_PRESET !== \"prod\"\n ) {\n return;\n }\n if (runtime.env.OPENMELD_CLI_BINARY_MANIFEST_URL) {\n return;\n }\n runtime.env.OPENMELD_ENV_PRESET = \"prod\";\n runtime.env.OPENMELD_CLI_BINARY_MANIFEST_URL =\n WINDOWS_INTERNAL_PREVIEW_MANIFEST_URL;\n runtime.env.OPENMELD_WINDOWS_INTERNAL_PREVIEW = \"1\";\n}\n"],"mappings":";;;;;;;;;;AAQA,eAAsB,6BACpB,UAMI;CACF,UAAU,QAAQ;CAClB,UAAU,QAAQ;CAClB,KAAK,QAAQ;CACb,oBAAoB,qBAAqB;CACzC,MAAM,uBAAuB;AAC/B,GACe;CACf,IAAI,QAAQ,aAAa,WAAW,CAAC,QAAQ,oBAC3C;CAEF,MAAM,eAAe,MAAM,kCAAkC,QAAQ,IAAI;CACzE,IAAI,cAAc,mBAAmB,mBACnC;CAEF,MAAM,iBAAiB,KACrB,QAAQ,MACR,YACA,aAAa,SACb,cACF;CACA,IACE,UAAU,QAAQ,QAAQ,CAAC,CAAC,YAAY,MACxC,UAAU,cAAc,CAAC,CAAC,YAAY,GAItC;CAEF,IACE,QAAQ,IAAI,uBACZ,QAAQ,IAAI,wBAAwB,QAEpC;CAEF,IAAI,QAAQ,IAAI,kCACd;CAEF,QAAQ,IAAI,sBAAsB;CAClC,QAAQ,IAAI,mCACV;CACF,QAAQ,IAAI,oCAAoC;AAClD"}
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { n as attachLockProcess, s as releaseLock } from "./lock-iue1J2xy.js";
4
- import { n as WINDOWS_PROCESS_HELPER_FILENAME } from "./windows-artifact-DJ9DKjfc.js";
5
- import { l as resolveWindowsPowerShellPath, o as powerShellEncodedArguments, s as pruneWindowsBinaryBundle } from "./process-identity-BQLdaZdB.js";
3
+ import { n as WINDOWS_PROCESS_HELPER_FILENAME } from "./windows-artifact-D99JU1ll.js";
4
+ import { l as resolveWindowsPowerShellPath, o as powerShellEncodedArguments, s as pruneWindowsBinaryBundle } from "./process-identity-BRbhGGTM.js";
6
5
  import { a as windowsUserTaskRequestSchema, i as windowsUserTaskActionSchema, n as readWindowsDirectTaskAction, o as windowsUserTaskStatusSchema, s as windowsUserTaskStoredActionSchema } from "./windows-task-command-COu_6Ke3.js";
6
+ import { n as attachLockProcess, s as releaseLock } from "./lock-CMH9eoS7.js";
7
7
  import { n as normalizeCommandEnvironment } from "./process-environment-BWSFeUu6.js";
8
- import { p as daemonRuntimeBundlesPath, u as currentDaemonServiceLifecycleLock } from "./daemon-state-Ca0WK5x0.js";
8
+ import { p as daemonRuntimeBundlesPath, u as currentDaemonServiceLifecycleLock } from "./daemon-state-B6G5xe7f.js";
9
9
  import { createHash } from "node:crypto";
10
10
  import { dirname, join } from "node:path";
11
11
  import { copyFile, mkdir, mkdtemp, open, rename, rm, stat } from "node:fs/promises";
@@ -382,4 +382,4 @@ async function runWindowsUserTask(request) {
382
382
  //#endregion
383
383
  export { expectedBinaryServiceFingerprint as a, verifyWindowsServiceSubsystem as c, windowsTaskActionArguments as i, windowsMaintenanceBinaryPath as l, runWindowsUserTask as n, hashBinaryServiceBundle as o, windowsPowerShellPath as r, prepareWindowsMaintenanceBinary as s, readWindowsTaskAction as t };
384
384
 
385
- //# sourceMappingURL=windows-user-task-Io5QuEVR.js.map
385
+ //# sourceMappingURL=windows-user-task-BR-WB7hr.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"windows-user-task-Io5QuEVR.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-BR-WB7hr.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,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { n as runWindowsUserTask, t as readWindowsTaskAction } from "./windows-user-task-Io5QuEVR.js";
3
+ import { n as runWindowsUserTask, t as readWindowsTaskAction } from "./windows-user-task-BR-WB7hr.js";
4
4
  export { readWindowsTaskAction, runWindowsUserTask };
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "https://www.schemastore.org/package.json",
3
3
  "name": "openmeld",
4
- "version": "0.3.225",
5
- "openMeldReleaseDate": "2026-09-25",
4
+ "version": "0.3.227",
5
+ "openMeldReleaseDate": "2026-09-27",
6
6
  "description": "OpenMeld CLI - https://openmeld.ai",
7
7
  "license": "MIT",
8
8
  "type": "module",
@@ -49,25 +49,25 @@
49
49
  "vitest": "~3.2.0",
50
50
  "@openmeld/adapter-antigravity": "0.0.1",
51
51
  "@openmeld/adapter-claude-code": "0.0.1",
52
- "@openmeld/adapter-codex": "0.0.1",
53
52
  "@openmeld/adapter-core": "0.0.1",
53
+ "@openmeld/adapter-codex": "0.0.1",
54
54
  "@openmeld/adapter-cursor": "0.0.1",
55
+ "@openmeld/adapter-opencode": "0.0.1",
55
56
  "@openmeld/adapter-grok-build": "0.0.1",
56
57
  "@openmeld/adapter-openclaw": "0.0.1",
57
- "@openmeld/adapter-opencode": "0.0.1",
58
58
  "@openmeld/agent-runtime": "0.0.1",
59
+ "@openmeld/gateway-contract": "0.0.1",
59
60
  "@openmeld/local-execution": "0.0.1",
60
61
  "@openmeld/api-client": "0.0.1",
61
- "@openmeld/gateway-contract": "0.0.1",
62
62
  "@openmeld/local-service": "0.0.1",
63
63
  "@openmeld/projects": "0.0.1",
64
- "@openmeld/protocol": "0.0.1",
65
- "@openmeld/space-mesh": "0.0.1",
66
64
  "@openmeld/routine-schedule": "0.0.1",
67
- "@openmeld/start": "0.0.1",
68
- "@openmeld/utils": "0.0.1",
65
+ "@openmeld/space": "0.0.1",
69
66
  "@openmeld/schemas": "0.0.1",
70
- "@openmeld/space": "0.0.1"
67
+ "@openmeld/utils": "0.0.1",
68
+ "@openmeld/start": "0.0.1",
69
+ "@openmeld/space-mesh": "0.0.1",
70
+ "@openmeld/protocol": "0.0.1"
71
71
  },
72
72
  "openmeld": {
73
73
  "releaseLine": "openmeld-greenfield-2026-07",
@@ -85,5 +85,5 @@
85
85
  "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",
86
86
  "test:watch": "vitest"
87
87
  },
88
- "gitHead": "7407c3ad61fbeef946f55d79b918416f6f8cca7d"
88
+ "gitHead": "5816ed7f1ca9554e63dfe3c0c85ff5fef8acd759"
89
89
  }
@@ -6,6 +6,7 @@ During a Wake, use the assigned Profile; the CLI forwards its request context.
6
6
 
7
7
  ```sh
8
8
  openmeld plugins list --profile <agent-profile-id> --view agent
9
+ openmeld plugins connect github --account choose --profile <agent-profile-id> --view agent
9
10
  openmeld plugins actions github --account shared --profile <agent-profile-id> --view agent
10
11
  openmeld plugins call <service> <action-id> --account personal --profile <agent-profile-id> --operation <unique-operation-id> --input '<json-object>' --view agent
11
12
  ```
@@ -14,6 +15,17 @@ Choose `personal` or `shared` explicitly. Read the returned action input schema
14
15
  before invoking it. A personal account is available only for its owner's
15
16
  request; another person's Wake must use an authorized shared account.
16
17
 
18
+ When a needed connection is missing, use `plugins connect <service>`. Preserve
19
+ an explicit `--account personal` or `--account shared`; use `choose` only when
20
+ the user has not required an identity. The server returns `replyText`, a trusted
21
+ ordinary link. In a Wake, include that text unchanged at the end of your final
22
+ reply. OpenMeld enhances it into the shared connection card, and only the
23
+ original requester can explicitly continue the same task after setup. Neither
24
+ opening the page nor OAuth completion runs anything. Never put credentials in
25
+ chat or construct a provider authorization URL. Keep prior operation receipts;
26
+ continuation is remaining work, not a restart. Outside a Wake there is no bound
27
+ conversation to resume; the command truthfully returns setup guidance only.
28
+
17
29
  If the result requires confirmation, show the requester the exact action,
18
30
  account, and input. Only after their authorization, repeat the same command
19
31
  and operation ID with `--confirm <confirmation-token>`. The token expires and
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { u as getAuthSessionMetadata } from "./auth-session-uEk_Tx6T.js";
4
- export { getAuthSessionMetadata };
@@ -1 +0,0 @@
1
- {"version":3,"file":"daemon-lifecycle-journal-ChhAF8yX.js","names":["packageJson"],"sources":["../src/local-service/control-plane/client.ts","../package.json","../src/config/version-state.ts","../src/runtime/version.ts","../src/local-service/lifecycle/daemon-lifecycle-journal.ts"],"sourcesContent":["import { createConnection } from \"node:net\";\nimport type {\n OpenMeldDaemonControlPlaneRequest,\n OpenMeldDaemonConversationExecutionStatusPayload,\n OpenMeldDaemonConversationExecutionStatusRequestPayload,\n OpenMeldDaemonRequestAgentActivitySyncPayload,\n OpenMeldDaemonRequestAgentActivitySyncRequestPayload,\n OpenMeldDaemonServiceUpdateReadinessPayload,\n OpenMeldDaemonSetLocalAgentEnabledPayload,\n OpenMeldDaemonSetLocalAgentEnabledRequestPayload,\n OpenMeldDaemonShutdownRequestPayload,\n OpenMeldDaemonSyncRouteCatalogPayload,\n OpenMeldDaemonSyncRouteCatalogRequestPayload,\n} from \"@openmeld/schemas\";\nimport {\n OPENMELD_DAEMON_CONTROL_PLANE_SCHEMA_VERSION,\n openMeldDaemonControlPlaneResponseSchema,\n} from \"@openmeld/schemas\";\nimport type { OpenMeldDaemonControlPlaneResponse } from \"@openmeld/schemas/types\";\nimport {\n readDaemonControlPlaneToken,\n resolveDaemonControlPlaneEndpoint,\n} from \"../../config/daemon-state\";\n\nconst DEFAULT_LOCAL_DAEMON_CONTROL_PLANE_TIMEOUT_MS = 5000;\n\nexport class LocalDaemonControlPlaneClientError extends Error {\n code: string;\n\n constructor(code: string, message: string) {\n super(message);\n this.code = code;\n }\n}\n\nexport async function sendLocalDaemonControlPlaneRequest(input: {\n endpoint?: string;\n request: OpenMeldDaemonControlPlaneRequest;\n timeoutMs?: number;\n}): Promise<OpenMeldDaemonControlPlaneResponse> {\n const endpoint = input.endpoint ?? resolveDaemonControlPlaneEndpoint();\n const authToken = await readDaemonControlPlaneToken();\n if (!authToken) {\n throw new LocalDaemonControlPlaneClientError(\n \"daemon.control.auth_token_missing\",\n \"daemon control token is missing\"\n );\n }\n\n const request = {\n ...input.request,\n authToken,\n } satisfies OpenMeldDaemonControlPlaneRequest;\n\n const rawResponse = await writeControlPlaneRequest({\n endpoint,\n request,\n timeoutMs: input.timeoutMs ?? DEFAULT_LOCAL_DAEMON_CONTROL_PLANE_TIMEOUT_MS,\n });\n const parsed =\n openMeldDaemonControlPlaneResponseSchema.safeParse(rawResponse);\n if (!parsed.success) {\n throw new LocalDaemonControlPlaneClientError(\n \"daemon.control.invalid_response\",\n \"local daemon control returned an invalid response\"\n );\n }\n if (parsed.data.code === \"service.error\") {\n throw new LocalDaemonControlPlaneClientError(\n parsed.data.payload.errorCode,\n parsed.data.payload.errorMessage\n );\n }\n return parsed.data;\n}\n\nexport async function requestLocalConversationExecutionStatus(input: {\n endpoint?: string;\n payload: OpenMeldDaemonConversationExecutionStatusRequestPayload;\n timeoutMs?: number;\n}): Promise<OpenMeldDaemonConversationExecutionStatusPayload> {\n let response: OpenMeldDaemonControlPlaneResponse;\n try {\n response = await sendLocalDaemonControlPlaneRequest({\n endpoint: input.endpoint,\n timeoutMs: input.timeoutMs,\n request: {\n v: OPENMELD_DAEMON_CONTROL_PLANE_SCHEMA_VERSION,\n command: \"conversation_execution_status\",\n payload: input.payload,\n },\n });\n } catch (error) {\n throw rewriteDaemonControlPlaneContractMismatch(error);\n }\n if (response.code !== \"service.conversation_execution_status\") {\n throw new LocalDaemonControlPlaneClientError(\n \"daemon.control.invalid_response\",\n \"local daemon control returned an unexpected response for conversation execution status\"\n );\n }\n return response.payload;\n}\n\nexport async function requestLocalSyncRouteCatalog(input: {\n endpoint?: string;\n payload: OpenMeldDaemonSyncRouteCatalogRequestPayload;\n timeoutMs?: number;\n}): Promise<OpenMeldDaemonSyncRouteCatalogPayload> {\n let response: OpenMeldDaemonControlPlaneResponse;\n try {\n response = await sendLocalDaemonControlPlaneRequest({\n endpoint: input.endpoint,\n timeoutMs: input.timeoutMs,\n request: {\n v: OPENMELD_DAEMON_CONTROL_PLANE_SCHEMA_VERSION,\n command: \"sync_route_catalog\",\n payload: input.payload,\n },\n });\n } catch (error) {\n throw rewriteDaemonControlPlaneContractMismatch(error);\n }\n if (response.code !== \"service.sync_route_catalog\") {\n throw new LocalDaemonControlPlaneClientError(\n \"daemon.control.invalid_response\",\n \"local daemon control returned an unexpected response for route catalog sync\"\n );\n }\n return response.payload;\n}\n\nexport async function requestLocalAgentActivitySync(input: {\n endpoint?: string;\n payload: OpenMeldDaemonRequestAgentActivitySyncRequestPayload;\n timeoutMs?: number;\n}): Promise<OpenMeldDaemonRequestAgentActivitySyncPayload> {\n let response: OpenMeldDaemonControlPlaneResponse;\n try {\n response = await sendLocalDaemonControlPlaneRequest({\n endpoint: input.endpoint,\n timeoutMs: input.timeoutMs,\n request: {\n v: OPENMELD_DAEMON_CONTROL_PLANE_SCHEMA_VERSION,\n command: \"request_agent_activity_sync\",\n payload: input.payload,\n },\n });\n } catch (error) {\n throw rewriteDaemonControlPlaneContractMismatch(error);\n }\n if (response.code !== \"service.agent_activity_sync_requested\") {\n throw new LocalDaemonControlPlaneClientError(\n \"daemon.control.invalid_response\",\n \"local daemon control returned an unexpected response for Agent Activity sync\"\n );\n }\n return response.payload;\n}\n\nexport async function requestLocalSetLocalAgentEnabled(input: {\n endpoint?: string;\n payload: OpenMeldDaemonSetLocalAgentEnabledRequestPayload;\n timeoutMs?: number;\n}): Promise<OpenMeldDaemonSetLocalAgentEnabledPayload> {\n let response: OpenMeldDaemonControlPlaneResponse;\n try {\n response = await sendLocalDaemonControlPlaneRequest({\n endpoint: input.endpoint,\n timeoutMs: input.timeoutMs,\n request: {\n v: OPENMELD_DAEMON_CONTROL_PLANE_SCHEMA_VERSION,\n command: \"set_local_agent_enabled\",\n payload: input.payload,\n },\n });\n } catch (error) {\n throw rewriteDaemonControlPlaneContractMismatch(error);\n }\n if (response.code !== \"service.set_local_agent_enabled\") {\n throw new LocalDaemonControlPlaneClientError(\n \"daemon.control.invalid_response\",\n \"local daemon control returned an unexpected response for local agent enablement\"\n );\n }\n return response.payload;\n}\n\nexport async function requestLocalDaemonShutdown(input: {\n endpoint?: string;\n payload: OpenMeldDaemonShutdownRequestPayload;\n timeoutMs?: number;\n}): Promise<\n Extract<\n OpenMeldDaemonControlPlaneResponse,\n { code: \"service.shutdown\" }\n >[\"payload\"]\n> {\n let response: OpenMeldDaemonControlPlaneResponse;\n try {\n response = await sendLocalDaemonControlPlaneRequest({\n endpoint: input.endpoint,\n timeoutMs: input.timeoutMs,\n request: {\n v: OPENMELD_DAEMON_CONTROL_PLANE_SCHEMA_VERSION,\n command: \"shutdown\",\n payload: input.payload,\n },\n });\n } catch (error) {\n throw rewriteDaemonControlPlaneContractMismatch(error);\n }\n if (response.code !== \"service.shutdown\") {\n throw new LocalDaemonControlPlaneClientError(\n \"daemon.control.invalid_response\",\n \"local daemon control returned an unexpected response for shutdown\"\n );\n }\n return response.payload;\n}\n\nexport async function requestLocalDaemonServiceUpdateReadiness(\n input: { endpoint?: string; timeoutMs?: number } = {}\n): Promise<OpenMeldDaemonServiceUpdateReadinessPayload> {\n let response: OpenMeldDaemonControlPlaneResponse;\n try {\n response = await sendLocalDaemonControlPlaneRequest({\n endpoint: input.endpoint,\n timeoutMs: input.timeoutMs,\n request: {\n v: OPENMELD_DAEMON_CONTROL_PLANE_SCHEMA_VERSION,\n command: \"service_update_readiness\",\n },\n });\n } catch (error) {\n throw rewriteDaemonControlPlaneContractMismatch(error);\n }\n if (response.code !== \"service.update_readiness\") {\n throw new LocalDaemonControlPlaneClientError(\n \"daemon.control.invalid_response\",\n \"local daemon control returned an unexpected response for service update readiness\"\n );\n }\n return response.payload;\n}\n\nfunction rewriteDaemonControlPlaneContractMismatch(error: unknown): unknown {\n if (\n error instanceof LocalDaemonControlPlaneClientError &&\n error.code === \"service.invalid_request\"\n ) {\n return new LocalDaemonControlPlaneClientError(\n \"daemon.control.contract_mismatch\",\n \"local OpenMeld Service must be restarted because the daemon control-plane contract changed on this device\"\n );\n }\n return error;\n}\n\nasync function writeControlPlaneRequest(input: {\n endpoint: string;\n request: OpenMeldDaemonControlPlaneRequest;\n timeoutMs: number;\n}): Promise<unknown> {\n return await new Promise<unknown>((resolve, reject) => {\n const socket = createConnection(input.endpoint);\n let responseBuffer = \"\";\n let settled = false;\n const cleanup = () => {\n socket.setTimeout(0);\n socket.off(\"connect\", handleConnect);\n socket.off(\"data\", handleData);\n socket.off(\"end\", handleEnd);\n socket.off(\"error\", handleError);\n socket.off(\"timeout\", handleTimeout);\n };\n const settle = (action: () => void) => {\n if (settled) {\n return;\n }\n settled = true;\n cleanup();\n action();\n };\n const fail = (error: LocalDaemonControlPlaneClientError) => {\n settle(() => {\n socket.destroy();\n reject(error);\n });\n };\n\n const handleConnect = () => {\n socket.write(`${JSON.stringify(input.request)}\\n`);\n };\n const handleData = (chunk: string) => {\n if (!responseBuffer && chunk.trim().length === 0) {\n return;\n }\n responseBuffer += chunk;\n };\n const handleEnd = () => {\n settle(() => {\n const rawResponse = responseBuffer.trim();\n if (!rawResponse) {\n reject(\n new LocalDaemonControlPlaneClientError(\n \"daemon.control.empty_response\",\n \"local daemon control returned an empty response\"\n )\n );\n return;\n }\n try {\n resolve(JSON.parse(rawResponse) as unknown);\n } catch {\n reject(\n new LocalDaemonControlPlaneClientError(\n \"daemon.control.invalid_json\",\n \"local daemon control returned malformed JSON\"\n )\n );\n }\n });\n };\n const handleError = (error: Error | NodeJS.ErrnoException) => {\n const code =\n error && typeof error === \"object\" && \"code\" in error\n ? String((error as NodeJS.ErrnoException).code)\n : \"daemon.control.connection_failed\";\n fail(\n new LocalDaemonControlPlaneClientError(\n code === \"ENOENT\" || code === \"ECONNREFUSED\"\n ? \"daemon.control.endpoint_missing\"\n : code,\n error instanceof Error\n ? error.message\n : \"failed to connect to local daemon control\"\n )\n );\n };\n const handleTimeout = () => {\n fail(\n new LocalDaemonControlPlaneClientError(\n \"daemon.control.timeout\",\n `local daemon control timed out after ${String(input.timeoutMs)}ms`\n )\n );\n };\n\n socket.setEncoding(\"utf8\");\n socket.setTimeout(input.timeoutMs);\n socket.once(\"connect\", handleConnect);\n socket.on(\"data\", handleData);\n socket.once(\"end\", handleEnd);\n socket.once(\"error\", handleError);\n socket.once(\"timeout\", handleTimeout);\n });\n}\n","","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport process from \"node:process\";\nimport {\n type CliBinaryManifest,\n type CliBinaryRelease,\n cliBinaryManifestSchema,\n resolveCliBinaryPlatform,\n} from \"@openmeld/schemas\";\nimport { isBinaryDistribution } from \"../runtime/distribution\";\nimport { openMeldRootDir } from \"./paths\";\n\nconst VERSION_STATE_FILENAME = \"version.json\";\nconst NPM_REGISTRY_LATEST_TIMEOUT_MS = 5000;\nconst VERSION_CHECK_CACHE_TTL_MS = 24 * 60 * 60 * 1000;\nconst LEADING_V_PREFIX_REGEX = /^v/;\nconst SEMVER_CORE_REGEX =\n /^(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?(?:\\+.*)?$/;\nconst NUMERIC_SEMVER_IDENTIFIER_REGEX = /^\\d+$/;\nconst versionCache = new Map<\n string,\n { info: PackageLatestInfo; fetchedAt: number }\n>();\nconst versionMetadataCache = new Map<\n string,\n {\n metadata: PackageVersionMetadata;\n fetchedAt: number;\n }\n>();\nconst inFlightVersionRequests = new Map<string, Promise<PackageLatestInfo>>();\nconst inFlightVersionMetadataRequests = new Map<\n string,\n Promise<PackageVersionMetadata>\n>();\n\nexport type OpenMeldVersionStateV1 = {\n v: 1;\n last_version?: string;\n latest_version?: string;\n last_checked_at?: string;\n dismissed_version?: string | null;\n // Projection of the published \"minimum required CLI version\" floor\n // (`openmeld.minRequiredCliVersion` on the npm `latest` manifest). Cached so the\n // forced-update gate can read it without a network probe on every command.\n required_floor?: string | null;\n updated_at: string;\n};\n\nexport type PackageVersionMetadata = {\n version: string;\n deprecated: string | null;\n};\n\nexport type PackageLatestInfo = {\n version: string;\n minRequiredCliVersion: string | null;\n serviceVersion?: string;\n};\n\nexport type CliBinaryReleaseInfo = PackageLatestInfo &\n CliBinaryRelease & {\n platform: string;\n service?: CliBinaryRelease & { version: string; platform: string };\n };\n\nexport function versionStatePath(): string {\n return join(openMeldRootDir(), VERSION_STATE_FILENAME);\n}\n\nexport async function readVersionState(): Promise<OpenMeldVersionStateV1 | null> {\n const raw = await readFile(versionStatePath(), \"utf8\").catch(() => null);\n if (!raw) {\n return null;\n }\n try {\n const parsed = JSON.parse(raw) as Partial<OpenMeldVersionStateV1>;\n if (parsed.v !== 1 || typeof parsed.updated_at !== \"string\") {\n return null;\n }\n const lastVersion = toNonEmptyString(parsed.last_version);\n const latestVersion = toNonEmptyString(parsed.latest_version);\n const lastCheckedAt = toNonEmptyString(parsed.last_checked_at);\n const dismissedVersion =\n parsed.dismissed_version === null\n ? null\n : toNonEmptyString(parsed.dismissed_version);\n const requiredFloor = parseStoredRequiredFloor(parsed.required_floor);\n const next: OpenMeldVersionStateV1 = {\n v: 1,\n ...(lastVersion ? { last_version: lastVersion } : {}),\n ...(latestVersion ? { latest_version: latestVersion } : {}),\n ...(lastCheckedAt ? { last_checked_at: lastCheckedAt } : {}),\n ...(dismissedVersion === undefined\n ? {}\n : { dismissed_version: dismissedVersion }),\n ...(requiredFloor === undefined ? {} : { required_floor: requiredFloor }),\n updated_at: parsed.updated_at,\n };\n return next;\n } catch {\n return null;\n }\n}\n\nexport async function writeVersionState(\n state: OpenMeldVersionStateV1\n): Promise<void> {\n await mkdir(openMeldRootDir(), { recursive: true });\n await writeFile(versionStatePath(), `${JSON.stringify(state, null, 2)}\\n`);\n}\n\nexport function createInitialVersionState(input: {\n currentVersion: string;\n checkedAt?: string;\n}): OpenMeldVersionStateV1 {\n const checkedAt = input.checkedAt ?? new Date().toISOString();\n return {\n v: 1,\n last_version: input.currentVersion,\n latest_version: input.currentVersion,\n last_checked_at: checkedAt,\n dismissed_version: null,\n updated_at: checkedAt,\n };\n}\n\nexport function hasValidLastVersion(\n state: OpenMeldVersionStateV1 | null\n): boolean {\n return Boolean(toNonEmptyString(state?.last_version));\n}\n\nexport async function ensureVersionStateReady(input: {\n currentVersion: string;\n}): Promise<OpenMeldVersionStateV1> {\n const previousVersionState = await readVersionState();\n if (!previousVersionState) {\n const nextState = createInitialVersionState({\n currentVersion: input.currentVersion,\n });\n await writeVersionState(nextState);\n return nextState;\n }\n\n if (hasValidLastVersion(previousVersionState)) {\n return previousVersionState;\n }\n\n const nextState: OpenMeldVersionStateV1 = {\n ...previousVersionState,\n last_version: input.currentVersion,\n latest_version: previousVersionState.latest_version ?? input.currentVersion,\n };\n await writeVersionState(nextState);\n return nextState;\n}\n\nexport function buildNextVersionState(input: {\n previous: OpenMeldVersionStateV1 | null;\n currentVersion: string;\n latestVersion?: string;\n checkedAt?: string;\n dismissedVersion?: string | null;\n // When provided (including `null`), overwrites the cached floor with the\n // freshly observed value; when omitted, the previous floor is carried\n // forward so callers that do not resolve the floor leave it untouched.\n requiredFloor?: string | null;\n}): OpenMeldVersionStateV1 {\n const checkedAt = input.checkedAt ?? new Date().toISOString();\n const latestVersion =\n toNonEmptyString(input.latestVersion) ??\n toNonEmptyString(input.previous?.latest_version) ??\n input.currentVersion;\n const requiredFloor =\n input.requiredFloor === undefined\n ? (input.previous?.required_floor ?? null)\n : input.requiredFloor;\n return {\n v: 1,\n last_version: input.currentVersion,\n latest_version: latestVersion,\n last_checked_at: checkedAt,\n dismissed_version:\n input.dismissedVersion ?? input.previous?.dismissed_version ?? null,\n ...(requiredFloor ? { required_floor: requiredFloor } : {}),\n updated_at: checkedAt,\n };\n}\n\nfunction parseStoredRequiredFloor(value: unknown): string | null | undefined {\n if (value === undefined) {\n return undefined;\n }\n if (value === null) {\n return null;\n }\n return toNonEmptyString(value);\n}\n\nexport async function fetchLatestPackageInfo(\n packageName: string,\n input: { forceRefresh?: boolean } = {}\n): Promise<PackageLatestInfo> {\n const now = Date.now();\n const cached = input.forceRefresh ? undefined : versionCache.get(packageName);\n if (cached && now - cached.fetchedAt < VERSION_CHECK_CACHE_TTL_MS) {\n return cached.info;\n }\n\n const requestKey = input.forceRefresh\n ? `${packageName}:force_refresh`\n : packageName;\n const inFlight = inFlightVersionRequests.get(requestKey);\n if (inFlight) {\n return inFlight;\n }\n\n const request = requestLatestPackageInfo(packageName);\n inFlightVersionRequests.set(requestKey, request);\n\n try {\n const info = await request;\n versionCache.set(packageName, {\n info,\n fetchedAt: Date.now(),\n });\n return info;\n } finally {\n inFlightVersionRequests.delete(requestKey);\n }\n}\n\nexport async function fetchLatestPackageVersion(\n packageName: string\n): Promise<string> {\n const info = await fetchLatestPackageInfo(packageName);\n return info.version;\n}\n\nexport async function fetchLatestCliBinaryRelease(input?: {\n platform?: string;\n}): Promise<CliBinaryReleaseInfo> {\n const manifest = await requestCliBinaryManifest();\n const platform =\n toNonEmptyString(input?.platform) ??\n resolveCliBinaryPlatform(process.platform, process.arch);\n const release = manifest.platforms[platform];\n if (!release) {\n throw new Error(\n `version check failed: invalid CLI manifest response: missing platform ${platform}`\n );\n }\n const serviceRelease = manifest.service?.platforms[platform];\n return {\n version: manifest.version,\n minRequiredCliVersion: manifest.minRequiredCliVersion,\n platform,\n ...release,\n ...(manifest.service && serviceRelease\n ? {\n service: {\n ...serviceRelease,\n version: manifest.service.version,\n platform,\n },\n }\n : {}),\n };\n}\n\nexport async function fetchPackageVersionMetadata(input: {\n packageName: string;\n version: string;\n}): Promise<PackageVersionMetadata> {\n const packageName = input.packageName.trim();\n const version = input.version.trim();\n const cacheKey = `${packageName}@${version}`;\n const now = Date.now();\n const cached = versionMetadataCache.get(cacheKey);\n if (cached && now - cached.fetchedAt < VERSION_CHECK_CACHE_TTL_MS) {\n return cached.metadata;\n }\n\n const inFlight = inFlightVersionMetadataRequests.get(cacheKey);\n if (inFlight) {\n return inFlight;\n }\n\n const request = requestPackageVersionMetadata({\n packageName,\n version,\n });\n inFlightVersionMetadataRequests.set(cacheKey, request);\n\n try {\n const metadata = await request;\n versionMetadataCache.set(cacheKey, {\n metadata,\n fetchedAt: Date.now(),\n });\n return metadata;\n } finally {\n inFlightVersionMetadataRequests.delete(cacheKey);\n }\n}\n\nexport function resetVersionCheckCacheForTests(): void {\n versionCache.clear();\n versionMetadataCache.clear();\n inFlightVersionRequests.clear();\n inFlightVersionMetadataRequests.clear();\n}\n\nasync function requestLatestPackageInfo(\n packageName: string\n): Promise<PackageLatestInfo> {\n if (isBinaryDistribution()) {\n return await requestLatestPackageInfoFromCliManifest();\n }\n const response = await fetch(\n `https://registry.npmjs.org/${encodeURIComponent(packageName)}/latest`,\n {\n method: \"GET\",\n signal: AbortSignal.timeout(NPM_REGISTRY_LATEST_TIMEOUT_MS),\n }\n );\n const raw = await response.text();\n if (!response.ok) {\n throw new Error(`version check failed: HTTP ${response.status}: ${raw}`);\n }\n try {\n const parsed = JSON.parse(raw) as { version?: unknown; openmeld?: unknown };\n const version =\n typeof parsed.version === \"string\" ? parsed.version.trim() : \"\";\n if (!version) {\n throw new Error(\"missing version\");\n }\n return {\n version,\n minRequiredCliVersion: readMinRequiredCliVersion(parsed.openmeld),\n };\n } catch (error) {\n throw new Error(\n `version check failed: invalid registry response: ${toErrorMessage(error)}`\n );\n }\n}\n\n// Binary distribution reads the same version-gate inputs (latest version +\n// minRequiredCliVersion floor) from the R2 cli/manifest.json instead of the npm\n// registry. The gate logic (floorBreached) is unchanged; only the data source\n// differs. The URL is a production Web route; override with\n// OPENMELD_CLI_BINARY_MANIFEST_URL for non-prod lanes.\nconst CLI_BINARY_MANIFEST_URL =\n toNonEmptyString(process.env.OPENMELD_CLI_BINARY_MANIFEST_URL) ??\n \"https://openmeld.ai/cli/manifest.json\";\n\nasync function requestLatestPackageInfoFromCliManifest(): Promise<PackageLatestInfo> {\n const manifest = await requestCliBinaryManifest();\n return {\n version: manifest.version,\n minRequiredCliVersion: manifest.minRequiredCliVersion,\n ...(manifest.service ? { serviceVersion: manifest.service.version } : {}),\n };\n}\n\ntype ParsedCliBinaryManifest = CliBinaryManifest[\"channels\"][\"stable\"] & {\n minRequiredCliVersion: string | null;\n};\n\nasync function requestCliBinaryManifest(): Promise<ParsedCliBinaryManifest> {\n const response = await fetch(CLI_BINARY_MANIFEST_URL, {\n method: \"GET\",\n signal: AbortSignal.timeout(NPM_REGISTRY_LATEST_TIMEOUT_MS),\n });\n const raw = await response.text();\n if (!response.ok) {\n throw new Error(`version check failed: HTTP ${response.status}: ${raw}`);\n }\n try {\n return parseCliBinaryManifest(raw);\n } catch (error) {\n throw new Error(\n `version check failed: invalid CLI manifest response: ${toErrorMessage(error)}`\n );\n }\n}\n\nfunction parseCliBinaryManifest(raw: string): ParsedCliBinaryManifest {\n const parsed = cliBinaryManifestSchema.safeParse(JSON.parse(raw));\n if (!parsed.success) {\n throw new Error(parsed.error.message);\n }\n const stable = parsed.data.channels.stable;\n return {\n ...stable,\n minRequiredCliVersion: stable.minRequiredCliVersion ?? null,\n };\n}\n\nfunction readMinRequiredCliVersion(openmeld: unknown): string | null {\n if (!openmeld || typeof openmeld !== \"object\") {\n return null;\n }\n const value = (openmeld as { minRequiredCliVersion?: unknown })\n .minRequiredCliVersion;\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n // A malformed floor must be treated as \"no signal\", never a hard gate:\n // `compareSemver` falls back to lexical compare on unparseable input, which\n // could wrongly read as a floor breach. Validate before trusting it.\n return trimmed.length > 0 && isPlainReleaseVersion(trimmed) ? trimmed : null;\n}\n\nasync function requestPackageVersionMetadata(input: {\n packageName: string;\n version: string;\n}): Promise<PackageVersionMetadata> {\n if (isBinaryDistribution()) {\n // Binary distribution has no npm-style per-version deprecation metadata.\n return { version: input.version, deprecated: null };\n }\n const response = await fetch(\n `https://registry.npmjs.org/${encodeURIComponent(input.packageName)}/${encodeURIComponent(input.version)}`,\n {\n method: \"GET\",\n signal: AbortSignal.timeout(NPM_REGISTRY_LATEST_TIMEOUT_MS),\n }\n );\n const raw = await response.text();\n if (!response.ok) {\n throw new Error(`version check failed: HTTP ${response.status}: ${raw}`);\n }\n try {\n const parsed = JSON.parse(raw) as {\n version?: unknown;\n deprecated?: unknown;\n };\n const resolvedVersion =\n typeof parsed.version === \"string\" && parsed.version.trim().length > 0\n ? parsed.version.trim()\n : input.version;\n const deprecated =\n typeof parsed.deprecated === \"string\" &&\n parsed.deprecated.trim().length > 0\n ? parsed.deprecated.trim()\n : null;\n return {\n version: resolvedVersion,\n deprecated,\n };\n } catch (error) {\n throw new Error(\n `version check failed: invalid registry response: ${toErrorMessage(error)}`\n );\n }\n}\n\n// A forced-update floor must be a plain published release version — no\n// prerelease, no build metadata. This is stricter than general semver on\n// purpose: it rejects malformed values (e.g. \"9.0.0+bad meta\") so they fail\n// open instead of hard-gating, and sidesteps prerelease-precedence ambiguity\n// since a floor is always a shipped stable release. Must match the release\n// tool's plain-version check in scripts/release/local-components.mjs.\nconst PLAIN_RELEASE_VERSION_RE = /^\\d+\\.\\d+\\.\\d+$/;\n\nexport function isPlainReleaseVersion(value: string): boolean {\n return PLAIN_RELEASE_VERSION_RE.test(value.trim());\n}\n\nexport function compareSemver(a: string, b: string): number {\n const left = parseSemver(a);\n const right = parseSemver(b);\n if (!(left && right)) {\n return a.localeCompare(b);\n }\n if (left.major !== right.major) {\n return left.major > right.major ? 1 : -1;\n }\n if (left.minor !== right.minor) {\n return left.minor > right.minor ? 1 : -1;\n }\n if (left.patch !== right.patch) {\n return left.patch > right.patch ? 1 : -1;\n }\n return comparePrereleaseIdentifiers(left.prerelease, right.prerelease);\n}\n\nfunction parseSemver(value: string): {\n major: number;\n minor: number;\n patch: number;\n prerelease: string[] | null;\n} | null {\n const normalized = value.trim().replace(LEADING_V_PREFIX_REGEX, \"\");\n const match = normalized.match(SEMVER_CORE_REGEX);\n if (!match) {\n return null;\n }\n return {\n major: Number(match[1]),\n minor: Number(match[2]),\n patch: Number(match[3]),\n prerelease: match[4] ? match[4].split(\".\") : null,\n };\n}\n\nfunction comparePrereleaseIdentifiers(\n left: string[] | null,\n right: string[] | null\n): number {\n if (!(left || right)) {\n return 0;\n }\n if (!left) {\n return 1;\n }\n if (!right) {\n return -1;\n }\n\n const maxLength = Math.max(left.length, right.length);\n for (let index = 0; index < maxLength; index += 1) {\n const leftIdentifier = left[index];\n const rightIdentifier = right[index];\n const lengthComparison = comparePrereleaseLengthAtIndex(\n leftIdentifier,\n rightIdentifier\n );\n if (lengthComparison !== 0) {\n return lengthComparison;\n }\n if (!(leftIdentifier && rightIdentifier)) {\n continue;\n }\n const compared = compareSinglePrereleaseIdentifier(\n leftIdentifier,\n rightIdentifier\n );\n if (compared !== 0) {\n return compared;\n }\n }\n return 0;\n}\n\nfunction comparePrereleaseLengthAtIndex(\n leftIdentifier: string | undefined,\n rightIdentifier: string | undefined\n): number {\n if (leftIdentifier === undefined && rightIdentifier === undefined) {\n return 0;\n }\n if (leftIdentifier === undefined) {\n return -1;\n }\n if (rightIdentifier === undefined) {\n return 1;\n }\n return 0;\n}\n\nfunction compareSinglePrereleaseIdentifier(\n leftIdentifier: string,\n rightIdentifier: string\n): number {\n if (leftIdentifier === rightIdentifier) {\n return 0;\n }\n\n const leftNumber = toNumericPrereleaseIdentifier(leftIdentifier);\n const rightNumber = toNumericPrereleaseIdentifier(rightIdentifier);\n if (leftNumber !== null && rightNumber !== null) {\n if (leftNumber === rightNumber) {\n return 0;\n }\n return leftNumber > rightNumber ? 1 : -1;\n }\n if (leftNumber !== null) {\n return -1;\n }\n if (rightNumber !== null) {\n return 1;\n }\n return leftIdentifier > rightIdentifier ? 1 : -1;\n}\n\nfunction toNumericPrereleaseIdentifier(identifier: string): number | null {\n if (!NUMERIC_SEMVER_IDENTIFIER_REGEX.test(identifier)) {\n return null;\n }\n return Number(identifier);\n}\n\nfunction toNonEmptyString(value: unknown): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const normalized = value.trim();\n return normalized.length > 0 ? normalized : null;\n}\n\nfunction toErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n","import packageJson from \"../../package.json\";\n\ndeclare const __OPENMELD_VERSION__: string | undefined;\n\n/**\n * The version of the running CLI and Service bundle.\n *\n * npm builds use package.json. Binary builds may inject an isolated staging\n * prerelease so the real update lifecycle can be exercised before a production\n * version exists.\n */\nexport function resolveOpenMeldVersion(): string {\n const injected =\n typeof __OPENMELD_VERSION__ === \"string\" ? __OPENMELD_VERSION__.trim() : \"\";\n return injected || packageJson.version;\n}\n\nexport const OPENMELD_VERSION = resolveOpenMeldVersion();\n","import { appendFile, mkdir, readFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport process from \"node:process\";\nimport {\n type DaemonLifecycleIntent,\n daemonLifecycleJournalPath,\n readDaemonServiceLifecycleLockMeta,\n} from \"../../config/daemon-state\";\nimport type { OpenMeldPathResolutionInput } from \"../../config/paths\";\nimport { resolveOpenMeldEnvPreset } from \"../../config/paths\";\nimport { assertNoPublishedProductionMutationDuringTests } from \"../../config/published-production-safety\";\nimport { resolveCliContextId } from \"../../config/session-profile\";\n\nconst DAEMON_LIFECYCLE_EVENT_TYPES = [\n \"connection.state\",\n \"daemon.crash\",\n \"lifecycle.command.begin\",\n \"lifecycle.command.end\",\n \"owner.snapshot\",\n \"route_catalog.initial_load\",\n \"runtime_state.takeover\",\n \"stop.controlled_drain\",\n \"stop.strategy.selected\",\n \"service_manager.action\",\n \"service_manager.registration_reconcile\",\n \"process_stop.action\",\n \"service_contract.write\",\n \"stop.signal.observed\",\n] as const;\n\nconst DAEMON_STOP_CAUSES = [\n \"user_stop\",\n \"controlled_service_update\",\n \"service_crash\",\n \"network_disconnect\",\n \"unknown\",\n] as const;\n\nexport type DaemonLifecycleEvent = {\n schema: \"openmeld-daemon-lifecycle-event-v1\";\n v: 1;\n type: DaemonLifecycleEventType;\n timestamp: string;\n lane: string;\n intent: string;\n command: string;\n pid: number;\n sessionId: string | null;\n stopCause?: DaemonStopCause;\n result: string;\n metadata?: Record<string, unknown>;\n};\n\nexport type DaemonStopCause =\n | \"user_stop\"\n | \"controlled_service_update\"\n | \"service_crash\"\n | \"network_disconnect\"\n | \"unknown\";\n\nexport type DaemonLifecycleAttribution = {\n command: string;\n intent: DaemonLifecycleIntent | \"unknown\";\n lane: string;\n pid: number;\n sessionId: string | null;\n};\n\ntype DaemonLifecycleEventType = (typeof DAEMON_LIFECYCLE_EVENT_TYPES)[number];\n\nfunction toJournalErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction normalizeSessionId(value: string | undefined | null): string | null {\n const normalized = typeof value === \"string\" ? value.trim() : \"\";\n return normalized.length > 0 ? normalized : null;\n}\n\nfunction resolveDaemonStopCause(input: {\n explicitCause?: DaemonStopCause;\n intent: DaemonLifecycleIntent | \"unknown\";\n result: string;\n type: DaemonLifecycleEventType;\n}): DaemonStopCause {\n if (input.explicitCause) {\n return input.explicitCause;\n }\n if (input.type === \"daemon.crash\") {\n return \"service_crash\";\n }\n // A transport observation does not establish why the connection was lost,\n // and must not inherit a concurrent CLI command's stop/update attribution.\n if (input.type === \"connection.state\") {\n return \"unknown\";\n }\n if (input.intent === \"stop\") {\n return \"user_stop\";\n }\n if (\n input.intent === \"upgrade_reconcile\" ||\n input.intent === \"reinstall\" ||\n input.intent === \"startup_check\" ||\n input.intent === \"status_cleanup\"\n ) {\n return \"controlled_service_update\";\n }\n return \"unknown\";\n}\n\nfunction isDaemonLifecycleEvent(event: unknown): event is DaemonLifecycleEvent {\n if (typeof event !== \"object\" || event === null) {\n return false;\n }\n const candidate = event as Partial<DaemonLifecycleEvent>;\n return (\n candidate.schema === \"openmeld-daemon-lifecycle-event-v1\" &&\n candidate.v === 1 &&\n DAEMON_LIFECYCLE_EVENT_TYPES.includes(\n candidate.type as DaemonLifecycleEventType\n ) &&\n typeof candidate.timestamp === \"string\" &&\n candidate.timestamp.length > 0 &&\n typeof candidate.lane === \"string\" &&\n candidate.lane.length > 0 &&\n typeof candidate.intent === \"string\" &&\n candidate.intent.length > 0 &&\n typeof candidate.command === \"string\" &&\n candidate.command.length > 0 &&\n typeof candidate.pid === \"number\" &&\n Number.isInteger(candidate.pid) &&\n candidate.pid > 0 &&\n (candidate.sessionId === null ||\n (typeof candidate.sessionId === \"string\" &&\n candidate.sessionId.length > 0)) &&\n (candidate.stopCause === undefined ||\n DAEMON_STOP_CAUSES.includes(candidate.stopCause)) &&\n typeof candidate.result === \"string\" &&\n candidate.result.length > 0\n );\n}\n\nasync function resolveDaemonLifecycleAttribution(input: {\n command?: string;\n intent?: DaemonLifecycleIntent | \"unknown\";\n pathInput?: OpenMeldPathResolutionInput;\n}): Promise<DaemonLifecycleAttribution> {\n const lockMeta = await readDaemonServiceLifecycleLockMeta().catch(() => null);\n const command =\n input.command?.trim() ||\n (typeof lockMeta?.command === \"string\" ? lockMeta.command.trim() : \"\") ||\n \"unknown\";\n const intent =\n input.intent ??\n (typeof lockMeta?.intent === \"string\" ? lockMeta.intent : \"unknown\");\n return {\n command,\n intent,\n lane: resolveOpenMeldEnvPreset(input.pathInput),\n pid:\n typeof lockMeta?.pid === \"number\" && lockMeta.pid > 0\n ? lockMeta.pid\n : process.pid,\n sessionId: normalizeSessionId(lockMeta?.sessionId) ?? resolveCliContextId(),\n };\n}\n\nexport async function emitDaemonLifecycleEvent(input: {\n type: DaemonLifecycleEventType;\n result: string;\n metadata?: Record<string, unknown>;\n pathInput?: OpenMeldPathResolutionInput;\n command?: string;\n intent?: DaemonLifecycleIntent | \"unknown\";\n stopCause?: DaemonStopCause;\n}): Promise<void> {\n assertNoPublishedProductionMutationDuringTests(\n input.pathInput ?? {},\n \"OpenMeld Service lifecycle journal\"\n );\n const journalPath = daemonLifecycleJournalPath(input.pathInput);\n const timestamp = new Date().toISOString();\n const attribution =\n input.type === \"connection.state\"\n ? {\n command: \"openmeld service run\",\n intent: \"unknown\" as const,\n lane: resolveOpenMeldEnvPreset(input.pathInput),\n pid: process.pid,\n sessionId: resolveCliContextId(),\n }\n : await resolveDaemonLifecycleAttribution(input);\n const event: DaemonLifecycleEvent = {\n schema: \"openmeld-daemon-lifecycle-event-v1\",\n v: 1,\n type: input.type,\n timestamp,\n lane: attribution.lane,\n intent: attribution.intent,\n command: attribution.command,\n pid: attribution.pid,\n sessionId: attribution.sessionId,\n stopCause: resolveDaemonStopCause({\n explicitCause: input.stopCause,\n intent: attribution.intent,\n result: input.result,\n type: input.type,\n }),\n result: input.result,\n ...(input.metadata ? { metadata: input.metadata } : {}),\n };\n\n if (!isDaemonLifecycleEvent(event)) {\n console.warn(\n `[openmeld:lifecycle-journal] rejected invalid event ${input.type}`\n );\n return;\n }\n\n try {\n await mkdir(dirname(journalPath), { recursive: true });\n await appendFile(journalPath, `${JSON.stringify(event)}\\n`, \"utf8\");\n } catch (error) {\n console.warn(\n `[openmeld:lifecycle-journal] failed to append event ${input.type}: ${toJournalErrorMessage(error)}`\n );\n }\n}\n\nexport async function runWithDaemonLifecycleCommandJournal<T>(input: {\n command: string;\n intent: DaemonLifecycleIntent;\n /**\n * Stamps the begin event with `processUptimeMs`, the milliseconds this\n * process has been running when the command begins. It is opt-in because it\n * is only meaningful for the long-lived daemon run: `begin timestamp -\n * processUptimeMs` recovers the process spawn moment, which splits the gap\n * between the previous `service_manager.action start` and this begin into\n * launchd/BTM spawn-decision latency versus daemon early initialization.\n * Local diagnostic evidence only; it must never feed readiness decisions.\n */\n includeProcessUptime?: boolean;\n metadata?: Record<string, unknown>;\n pathInput?: OpenMeldPathResolutionInput;\n resolveResult?: (result: T) => {\n metadata?: Record<string, unknown>;\n result: string;\n };\n run: () => Promise<T>;\n}): Promise<T> {\n await emitDaemonLifecycleEvent({\n type: \"lifecycle.command.begin\",\n result: \"started\",\n metadata: input.includeProcessUptime\n ? {\n ...input.metadata,\n processUptimeMs: Math.round(process.uptime() * 1000),\n }\n : input.metadata,\n pathInput: input.pathInput,\n command: input.command,\n intent: input.intent,\n });\n\n try {\n const result = await input.run();\n const resolvedResult = input.resolveResult?.(result) ?? {\n result: \"completed\",\n };\n await emitDaemonLifecycleEvent({\n type: \"lifecycle.command.end\",\n result: resolvedResult.result,\n metadata: resolvedResult.metadata,\n pathInput: input.pathInput,\n command: input.command,\n intent: input.intent,\n });\n return result;\n } catch (error) {\n await emitDaemonLifecycleEvent({\n type: \"lifecycle.command.end\",\n result: \"failed\",\n metadata: {\n errorMessage: toJournalErrorMessage(error),\n },\n pathInput: input.pathInput,\n command: input.command,\n intent: input.intent,\n });\n throw error;\n }\n}\n\nexport async function runDaemonServiceManagerAction<T>(input: {\n action:\n | \"deactivate\"\n | \"install\"\n | \"start\"\n | \"stop\"\n | \"uninstall\"\n | \"wait_running\";\n command?: string;\n controller: string;\n intent?: DaemonLifecycleIntent | \"unknown\";\n metadata?: Record<string, unknown>;\n pathInput?: OpenMeldPathResolutionInput;\n /**\n * Extracts structured failure evidence from the thrown error so the\n * journal entry alone carries the diagnosis (e.g. launchd job state on a\n * wait_running timeout). Extraction failures are swallowed: journaling\n * must never change the thrown error.\n */\n resolveErrorMetadata?: (error: unknown) => Record<string, unknown> | null;\n run: () => Promise<T>;\n}): Promise<T> {\n const startedAtMs = Date.now();\n try {\n const result = await input.run();\n await emitDaemonLifecycleEvent({\n type: \"service_manager.action\",\n result: \"completed\",\n metadata: {\n action: input.action,\n controller: input.controller,\n durationMs: Date.now() - startedAtMs,\n ...(input.metadata ?? {}),\n },\n pathInput: input.pathInput,\n command: input.command,\n intent: input.intent,\n });\n return result;\n } catch (error) {\n let errorMetadata: Record<string, unknown> | null = null;\n try {\n errorMetadata = input.resolveErrorMetadata?.(error) ?? null;\n } catch {\n errorMetadata = null;\n }\n await emitDaemonLifecycleEvent({\n type: \"service_manager.action\",\n result: \"failed\",\n metadata: {\n action: input.action,\n controller: input.controller,\n durationMs: Date.now() - startedAtMs,\n errorMessage: toJournalErrorMessage(error),\n ...(errorMetadata ?? {}),\n ...(input.metadata ?? {}),\n },\n pathInput: input.pathInput,\n command: input.command,\n intent: input.intent,\n });\n throw error;\n }\n}\n\nconst DAEMON_LIFECYCLE_ORIGIN_EVENT_TYPES = new Set<DaemonLifecycleEventType>([\n \"daemon.crash\",\n \"lifecycle.command.end\",\n \"process_stop.action\",\n \"runtime_state.takeover\",\n \"service_contract.write\",\n \"service_manager.action\",\n]);\n\nexport async function readLatestDaemonLifecycleOriginEvent(\n input: { pathInput?: OpenMeldPathResolutionInput } = {}\n): Promise<DaemonLifecycleEvent | null> {\n return await readLatestDaemonLifecycleEvent({\n pathInput: input.pathInput,\n typeFilter: DAEMON_LIFECYCLE_ORIGIN_EVENT_TYPES,\n });\n}\n\nexport async function readLatestDaemonLifecycleConnectionStateEvent(\n input: { pathInput?: OpenMeldPathResolutionInput } = {}\n): Promise<DaemonLifecycleEvent | null> {\n return await readLatestDaemonLifecycleEvent({\n pathInput: input.pathInput,\n typeFilter: new Set<DaemonLifecycleEventType>([\"connection.state\"]),\n });\n}\n\nasync function readLatestDaemonLifecycleEvent(input: {\n pathInput?: OpenMeldPathResolutionInput;\n typeFilter: ReadonlySet<DaemonLifecycleEventType>;\n}): Promise<DaemonLifecycleEvent | null> {\n const journalPath = daemonLifecycleJournalPath(input.pathInput);\n let content: string;\n try {\n content = await readFile(journalPath, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return null;\n }\n throw error;\n }\n\n const lines = content\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.length > 0);\n\n for (let index = lines.length - 1; index >= 0; index -= 1) {\n const line = lines[index];\n if (!line) {\n continue;\n }\n try {\n const parsed = JSON.parse(line) as unknown;\n if (isDaemonLifecycleEvent(parsed) && input.typeFilter.has(parsed.type)) {\n return parsed;\n }\n } catch {\n // Ignore malformed journal lines and keep scanning older entries.\n }\n }\n\n return null;\n}\n\nexport async function readRecentDaemonLifecycleEvents(input: {\n maxEntries: number;\n pathInput?: OpenMeldPathResolutionInput;\n}): Promise<DaemonLifecycleEvent[]> {\n if (input.maxEntries <= 0) {\n return [];\n }\n const journalPath = daemonLifecycleJournalPath(input.pathInput);\n let content: string;\n try {\n content = await readFile(journalPath, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return [];\n }\n throw error;\n }\n\n const lines = content\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.length > 0);\n\n const recent: DaemonLifecycleEvent[] = [];\n for (let index = lines.length - 1; index >= 0; index -= 1) {\n const line = lines[index];\n if (!line) {\n continue;\n }\n try {\n const parsed = JSON.parse(line) as unknown;\n if (isDaemonLifecycleEvent(parsed)) {\n recent.push(parsed);\n if (recent.length >= input.maxEntries) {\n break;\n }\n }\n } catch {\n // Ignore malformed journal lines and keep scanning older entries.\n }\n }\n\n return recent.reverse();\n}\n\nexport async function resolveRecentDaemonSignalStopCause(\n input: { maxAgeMs?: number; pathInput?: OpenMeldPathResolutionInput } = {}\n): Promise<\n | Extract<DaemonStopCause, \"user_stop\" | \"controlled_service_update\">\n | \"unknown\"\n> {\n const nowMs = Date.now();\n const maxAgeMs = input.maxAgeMs ?? 30_000;\n const events = await readRecentDaemonLifecycleEvents({\n maxEntries: 32,\n pathInput: input.pathInput,\n });\n for (const event of events.toReversed()) {\n const eventAtMs = Date.parse(event.timestamp);\n if (\n !Number.isFinite(eventAtMs) ||\n nowMs - eventAtMs < 0 ||\n nowMs - eventAtMs > maxAgeMs\n ) {\n continue;\n }\n if (\n event.stopCause === \"user_stop\" ||\n event.stopCause === \"controlled_service_update\"\n ) {\n return event.stopCause;\n }\n }\n return \"unknown\";\n}\n\nexport function formatDaemonLifecycleOriginSummary(\n event: DaemonLifecycleEvent\n): string {\n const intent = formatDaemonLifecycleIntent(event.intent);\n return `${event.result} ${intent} from ${event.command} at ${event.timestamp} (pid ${event.pid})`;\n}\n\nfunction formatDaemonLifecycleIntent(intent: string): string {\n if (intent === \"unknown\") {\n return \"OpenMeld Service task\";\n }\n return intent.replaceAll(\"_\", \" \");\n}\n"],"mappings":";;;;;;;;;;;;;AAwBA,MAAM,gDAAgD;AAEtD,IAAa,qCAAb,cAAwD,MAAM;CAC5D;CAEA,YAAY,MAAc,SAAiB;EACzC,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF;AAEA,eAAsB,mCAAmC,OAIT;CAC9C,MAAM,WAAW,MAAM,YAAY,kCAAkC;CACrE,MAAM,YAAY,MAAM,4BAA4B;CACpD,IAAI,CAAC,WACH,MAAM,IAAI,mCACR,qCACA,iCACF;CAQF,MAAM,cAAc,MAAM,yBAAyB;EACjD;EACA,SAAA;GANA,GAAG,MAAM;GACT;EAKM;EACN,WAAW,MAAM,aAAa;CAChC,CAAC;CACD,MAAM,SACJ,yCAAyC,UAAU,WAAW;CAChE,IAAI,CAAC,OAAO,SACV,MAAM,IAAI,mCACR,mCACA,mDACF;CAEF,IAAI,OAAO,KAAK,SAAS,iBACvB,MAAM,IAAI,mCACR,OAAO,KAAK,QAAQ,WACpB,OAAO,KAAK,QAAQ,YACtB;CAEF,OAAO,OAAO;AAChB;AA8BA,eAAsB,6BAA6B,OAIA;CACjD,IAAI;CACJ,IAAI;EACF,WAAW,MAAM,mCAAmC;GAClD,UAAU,MAAM;GAChB,WAAW,MAAM;GACjB,SAAS;IACP,GAAA;IACA,SAAS;IACT,SAAS,MAAM;GACjB;EACF,CAAC;CACH,SAAS,OAAO;EACd,MAAM,0CAA0C,KAAK;CACvD;CACA,IAAI,SAAS,SAAS,8BACpB,MAAM,IAAI,mCACR,mCACA,6EACF;CAEF,OAAO,SAAS;AAClB;AAEA,eAAsB,8BAA8B,OAIO;CACzD,IAAI;CACJ,IAAI;EACF,WAAW,MAAM,mCAAmC;GAClD,UAAU,MAAM;GAChB,WAAW,MAAM;GACjB,SAAS;IACP,GAAA;IACA,SAAS;IACT,SAAS,MAAM;GACjB;EACF,CAAC;CACH,SAAS,OAAO;EACd,MAAM,0CAA0C,KAAK;CACvD;CACA,IAAI,SAAS,SAAS,yCACpB,MAAM,IAAI,mCACR,mCACA,8EACF;CAEF,OAAO,SAAS;AAClB;AA8BA,eAAsB,2BAA2B,OAS/C;CACA,IAAI;CACJ,IAAI;EACF,WAAW,MAAM,mCAAmC;GAClD,UAAU,MAAM;GAChB,WAAW,MAAM;GACjB,SAAS;IACP,GAAA;IACA,SAAS;IACT,SAAS,MAAM;GACjB;EACF,CAAC;CACH,SAAS,OAAO;EACd,MAAM,0CAA0C,KAAK;CACvD;CACA,IAAI,SAAS,SAAS,oBACpB,MAAM,IAAI,mCACR,mCACA,mEACF;CAEF,OAAO,SAAS;AAClB;AAEA,eAAsB,yCACpB,QAAmD,CAAC,GACE;CACtD,IAAI;CACJ,IAAI;EACF,WAAW,MAAM,mCAAmC;GAClD,UAAU,MAAM;GAChB,WAAW,MAAM;GACjB,SAAS;IACP,GAAA;IACA,SAAS;GACX;EACF,CAAC;CACH,SAAS,OAAO;EACd,MAAM,0CAA0C,KAAK;CACvD;CACA,IAAI,SAAS,SAAS,4BACpB,MAAM,IAAI,mCACR,mCACA,mFACF;CAEF,OAAO,SAAS;AAClB;AAEA,SAAS,0CAA0C,OAAyB;CAC1E,IACE,iBAAiB,sCACjB,MAAM,SAAS,2BAEf,OAAO,IAAI,mCACT,oCACA,2GACF;CAEF,OAAO;AACT;AAEA,eAAe,yBAAyB,OAInB;CACnB,OAAO,MAAM,IAAI,SAAkB,SAAS,WAAW;EACrD,MAAM,SAAS,iBAAiB,MAAM,QAAQ;EAC9C,IAAI,iBAAiB;EACrB,IAAI,UAAU;EACd,MAAM,gBAAgB;GACpB,OAAO,WAAW,CAAC;GACnB,OAAO,IAAI,WAAW,aAAa;GACnC,OAAO,IAAI,QAAQ,UAAU;GAC7B,OAAO,IAAI,OAAO,SAAS;GAC3B,OAAO,IAAI,SAAS,WAAW;GAC/B,OAAO,IAAI,WAAW,aAAa;EACrC;EACA,MAAM,UAAU,WAAuB;GACrC,IAAI,SACF;GAEF,UAAU;GACV,QAAQ;GACR,OAAO;EACT;EACA,MAAM,QAAQ,UAA8C;GAC1D,aAAa;IACX,OAAO,QAAQ;IACf,OAAO,KAAK;GACd,CAAC;EACH;EAEA,MAAM,sBAAsB;GAC1B,OAAO,MAAM,GAAG,KAAK,UAAU,MAAM,OAAO,EAAE,GAAG;EACnD;EACA,MAAM,cAAc,UAAkB;GACpC,IAAI,CAAC,kBAAkB,MAAM,KAAK,CAAC,CAAC,WAAW,GAC7C;GAEF,kBAAkB;EACpB;EACA,MAAM,kBAAkB;GACtB,aAAa;IACX,MAAM,cAAc,eAAe,KAAK;IACxC,IAAI,CAAC,aAAa;KAChB,OACE,IAAI,mCACF,iCACA,iDACF,CACF;KACA;IACF;IACA,IAAI;KACF,QAAQ,KAAK,MAAM,WAAW,CAAY;IAC5C,QAAQ;KACN,OACE,IAAI,mCACF,+BACA,8CACF,CACF;IACF;GACF,CAAC;EACH;EACA,MAAM,eAAe,UAAyC;GAC5D,MAAM,OACJ,SAAS,OAAO,UAAU,YAAY,UAAU,QAC5C,OAAQ,MAAgC,IAAI,IAC5C;GACN,KACE,IAAI,mCACF,SAAS,YAAY,SAAS,iBAC1B,oCACA,MACJ,iBAAiB,QACb,MAAM,UACN,2CACN,CACF;EACF;EACA,MAAM,sBAAsB;GAC1B,KACE,IAAI,mCACF,0BACA,wCAAwC,OAAO,MAAM,SAAS,EAAE,GAClE,CACF;EACF;EAEA,OAAO,YAAY,MAAM;EACzB,OAAO,WAAW,MAAM,SAAS;EACjC,OAAO,KAAK,WAAW,aAAa;EACpC,OAAO,GAAG,QAAQ,UAAU;EAC5B,OAAO,KAAK,OAAO,SAAS;EAC5B,OAAO,KAAK,SAAS,WAAW;EAChC,OAAO,KAAK,WAAW,aAAa;CACtC,CAAC;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AEzVA,MAAM,yBAAyB;AAC/B,MAAM,iCAAiC;AACvC,MAAM,6BAA6B,OAAU,KAAK;AAClD,MAAM,yBAAyB;AAC/B,MAAM,oBACJ;AACF,MAAM,kCAAkC;AACxC,MAAM,+BAAe,IAAI,IAGvB;AAQF,MAAM,0CAA0B,IAAI,IAAwC;AAoC5E,SAAgB,mBAA2B;CACzC,OAAO,KAAK,gBAAgB,GAAG,sBAAsB;AACvD;AAEA,eAAsB,mBAA2D;CAC/E,MAAM,MAAM,MAAM,SAAS,iBAAiB,GAAG,MAAM,CAAC,CAAC,YAAY,IAAI;CACvE,IAAI,CAAC,KACH,OAAO;CAET,IAAI;EACF,MAAM,SAAS,KAAK,MAAM,GAAG;EAC7B,IAAI,OAAO,MAAM,KAAK,OAAO,OAAO,eAAe,UACjD,OAAO;EAET,MAAM,cAAc,iBAAiB,OAAO,YAAY;EACxD,MAAM,gBAAgB,iBAAiB,OAAO,cAAc;EAC5D,MAAM,gBAAgB,iBAAiB,OAAO,eAAe;EAC7D,MAAM,mBACJ,OAAO,sBAAsB,OACzB,OACA,iBAAiB,OAAO,iBAAiB;EAC/C,MAAM,gBAAgB,yBAAyB,OAAO,cAAc;EAYpE,OAAO;GAVL,GAAG;GACH,GAAI,cAAc,EAAE,cAAc,YAAY,IAAI,CAAC;GACnD,GAAI,gBAAgB,EAAE,gBAAgB,cAAc,IAAI,CAAC;GACzD,GAAI,gBAAgB,EAAE,iBAAiB,cAAc,IAAI,CAAC;GAC1D,GAAI,qBAAqB,KAAA,IACrB,CAAC,IACD,EAAE,mBAAmB,iBAAiB;GAC1C,GAAI,kBAAkB,KAAA,IAAY,CAAC,IAAI,EAAE,gBAAgB,cAAc;GACvE,YAAY,OAAO;EAEX;CACZ,QAAQ;EACN,OAAO;CACT;AACF;AAEA,eAAsB,kBACpB,OACe;CACf,MAAM,MAAM,gBAAgB,GAAG,EAAE,WAAW,KAAK,CAAC;CAClD,MAAM,UAAU,iBAAiB,GAAG,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,EAAE,GAAG;AAC3E;AAEA,SAAgB,0BAA0B,OAGf;CACzB,MAAM,YAAY,MAAM,8BAAa,IAAI,KAAK,EAAA,CAAE,YAAY;CAC5D,OAAO;EACL,GAAG;EACH,cAAc,MAAM;EACpB,gBAAgB,MAAM;EACtB,iBAAiB;EACjB,mBAAmB;EACnB,YAAY;CACd;AACF;AAEA,SAAgB,oBACd,OACS;CACT,OAAO,QAAQ,iBAAiB,OAAO,YAAY,CAAC;AACtD;AAEA,eAAsB,wBAAwB,OAEV;CAClC,MAAM,uBAAuB,MAAM,iBAAiB;CACpD,IAAI,CAAC,sBAAsB;EACzB,MAAM,YAAY,0BAA0B,EAC1C,gBAAgB,MAAM,eACxB,CAAC;EACD,MAAM,kBAAkB,SAAS;EACjC,OAAO;CACT;CAEA,IAAI,oBAAoB,oBAAoB,GAC1C,OAAO;CAGT,MAAM,YAAoC;EACxC,GAAG;EACH,cAAc,MAAM;EACpB,gBAAgB,qBAAqB,kBAAkB,MAAM;CAC/D;CACA,MAAM,kBAAkB,SAAS;CACjC,OAAO;AACT;AAEA,SAAgB,sBAAsB,OAUX;CACzB,MAAM,YAAY,MAAM,8BAAa,IAAI,KAAK,EAAA,CAAE,YAAY;CAC5D,MAAM,gBACJ,iBAAiB,MAAM,aAAa,KACpC,iBAAiB,MAAM,UAAU,cAAc,KAC/C,MAAM;CACR,MAAM,gBACJ,MAAM,kBAAkB,KAAA,IACnB,MAAM,UAAU,kBAAkB,OACnC,MAAM;CACZ,OAAO;EACL,GAAG;EACH,cAAc,MAAM;EACpB,gBAAgB;EAChB,iBAAiB;EACjB,mBACE,MAAM,oBAAoB,MAAM,UAAU,qBAAqB;EACjE,GAAI,gBAAgB,EAAE,gBAAgB,cAAc,IAAI,CAAC;EACzD,YAAY;CACd;AACF;AAEA,SAAS,yBAAyB,OAA2C;CAC3E,IAAI,UAAU,KAAA,GACZ;CAEF,IAAI,UAAU,MACZ,OAAO;CAET,OAAO,iBAAiB,KAAK;AAC/B;AAEA,eAAsB,uBACpB,aACA,QAAoC,CAAC,GACT;CAC5B,MAAM,MAAM,KAAK,IAAI;CACrB,MAAM,SAAS,MAAM,eAAe,KAAA,IAAY,aAAa,IAAI,WAAW;CAC5E,IAAI,UAAU,MAAM,OAAO,YAAY,4BACrC,OAAO,OAAO;CAGhB,MAAM,aAAa,MAAM,eACrB,GAAG,YAAY,kBACf;CACJ,MAAM,WAAW,wBAAwB,IAAI,UAAU;CACvD,IAAI,UACF,OAAO;CAGT,MAAM,UAAU,yBAAyB,WAAW;CACpD,wBAAwB,IAAI,YAAY,OAAO;CAE/C,IAAI;EACF,MAAM,OAAO,MAAM;EACnB,aAAa,IAAI,aAAa;GAC5B;GACA,WAAW,KAAK,IAAI;EACtB,CAAC;EACD,OAAO;CACT,UAAU;EACR,wBAAwB,OAAO,UAAU;CAC3C;AACF;AASA,eAAsB,4BAA4B,OAEhB;CAChC,MAAM,WAAW,MAAM,yBAAyB;CAChD,MAAM,WACJ,iBAAiB,OAAO,QAAQ,KAChC,yBAAyB,QAAQ,UAAU,QAAQ,IAAI;CACzD,MAAM,UAAU,SAAS,UAAU;CACnC,IAAI,CAAC,SACH,MAAM,IAAI,MACR,yEAAyE,UAC3E;CAEF,MAAM,iBAAiB,SAAS,SAAS,UAAU;CACnD,OAAO;EACL,SAAS,SAAS;EAClB,uBAAuB,SAAS;EAChC;EACA,GAAG;EACH,GAAI,SAAS,WAAW,iBACpB,EACE,SAAS;GACP,GAAG;GACH,SAAS,SAAS,QAAQ;GAC1B;EACF,EACF,IACA,CAAC;CACP;AACF;AA6CA,eAAe,yBACb,aAC4B;CAC5B,IAAI,qBAAqB,GACvB,OAAO,MAAM,wCAAwC;CAEvD,MAAM,WAAW,MAAM,MACrB,8BAA8B,mBAAmB,WAAW,EAAE,UAC9D;EACE,QAAQ;EACR,QAAQ,YAAY,QAAQ,8BAA8B;CAC5D,CACF;CACA,MAAM,MAAM,MAAM,SAAS,KAAK;CAChC,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,MAAM,8BAA8B,SAAS,OAAO,IAAI,KAAK;CAEzE,IAAI;EACF,MAAM,SAAS,KAAK,MAAM,GAAG;EAC7B,MAAM,UACJ,OAAO,OAAO,YAAY,WAAW,OAAO,QAAQ,KAAK,IAAI;EAC/D,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,iBAAiB;EAEnC,OAAO;GACL;GACA,uBAAuB,0BAA0B,OAAO,QAAQ;EAClE;CACF,SAAS,OAAO;EACd,MAAM,IAAI,MACR,oDAAoD,eAAe,KAAK,GAC1E;CACF;AACF;AAOA,MAAM,0BACJ,iBAAiB,QAAQ,IAAI,gCAAgC,KAC7D;AAEF,eAAe,0CAAsE;CACnF,MAAM,WAAW,MAAM,yBAAyB;CAChD,OAAO;EACL,SAAS,SAAS;EAClB,uBAAuB,SAAS;EAChC,GAAI,SAAS,UAAU,EAAE,gBAAgB,SAAS,QAAQ,QAAQ,IAAI,CAAC;CACzE;AACF;AAMA,eAAe,2BAA6D;CAC1E,MAAM,WAAW,MAAM,MAAM,yBAAyB;EACpD,QAAQ;EACR,QAAQ,YAAY,QAAQ,8BAA8B;CAC5D,CAAC;CACD,MAAM,MAAM,MAAM,SAAS,KAAK;CAChC,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,MAAM,8BAA8B,SAAS,OAAO,IAAI,KAAK;CAEzE,IAAI;EACF,OAAO,uBAAuB,GAAG;CACnC,SAAS,OAAO;EACd,MAAM,IAAI,MACR,wDAAwD,eAAe,KAAK,GAC9E;CACF;AACF;AAEA,SAAS,uBAAuB,KAAsC;CACpE,MAAM,SAAS,wBAAwB,UAAU,KAAK,MAAM,GAAG,CAAC;CAChE,IAAI,CAAC,OAAO,SACV,MAAM,IAAI,MAAM,OAAO,MAAM,OAAO;CAEtC,MAAM,SAAS,OAAO,KAAK,SAAS;CACpC,OAAO;EACL,GAAG;EACH,uBAAuB,OAAO,yBAAyB;CACzD;AACF;AAEA,SAAS,0BAA0B,UAAkC;CACnE,IAAI,CAAC,YAAY,OAAO,aAAa,UACnC,OAAO;CAET,MAAM,QAAS,SACZ;CACH,IAAI,OAAO,UAAU,UACnB,OAAO;CAET,MAAM,UAAU,MAAM,KAAK;CAI3B,OAAO,QAAQ,SAAS,KAAK,sBAAsB,OAAO,IAAI,UAAU;AAC1E;AAoDA,MAAM,2BAA2B;AAEjC,SAAgB,sBAAsB,OAAwB;CAC5D,OAAO,yBAAyB,KAAK,MAAM,KAAK,CAAC;AACnD;AAEA,SAAgB,cAAc,GAAW,GAAmB;CAC1D,MAAM,OAAO,YAAY,CAAC;CAC1B,MAAM,QAAQ,YAAY,CAAC;CAC3B,IAAI,EAAE,QAAQ,QACZ,OAAO,EAAE,cAAc,CAAC;CAE1B,IAAI,KAAK,UAAU,MAAM,OACvB,OAAO,KAAK,QAAQ,MAAM,QAAQ,IAAI;CAExC,IAAI,KAAK,UAAU,MAAM,OACvB,OAAO,KAAK,QAAQ,MAAM,QAAQ,IAAI;CAExC,IAAI,KAAK,UAAU,MAAM,OACvB,OAAO,KAAK,QAAQ,MAAM,QAAQ,IAAI;CAExC,OAAO,6BAA6B,KAAK,YAAY,MAAM,UAAU;AACvE;AAEA,SAAS,YAAY,OAKZ;CAEP,MAAM,QADa,MAAM,KAAK,CAAC,CAAC,QAAQ,wBAAwB,EACzC,CAAC,CAAC,MAAM,iBAAiB;CAChD,IAAI,CAAC,OACH,OAAO;CAET,OAAO;EACL,OAAO,OAAO,MAAM,EAAE;EACtB,OAAO,OAAO,MAAM,EAAE;EACtB,OAAO,OAAO,MAAM,EAAE;EACtB,YAAY,MAAM,KAAK,MAAM,EAAE,CAAC,MAAM,GAAG,IAAI;CAC/C;AACF;AAEA,SAAS,6BACP,MACA,OACQ;CACR,IAAI,EAAE,QAAQ,QACZ,OAAO;CAET,IAAI,CAAC,MACH,OAAO;CAET,IAAI,CAAC,OACH,OAAO;CAGT,MAAM,YAAY,KAAK,IAAI,KAAK,QAAQ,MAAM,MAAM;CACpD,KAAK,IAAI,QAAQ,GAAG,QAAQ,WAAW,SAAS,GAAG;EACjD,MAAM,iBAAiB,KAAK;EAC5B,MAAM,kBAAkB,MAAM;EAC9B,MAAM,mBAAmB,+BACvB,gBACA,eACF;EACA,IAAI,qBAAqB,GACvB,OAAO;EAET,IAAI,EAAE,kBAAkB,kBACtB;EAEF,MAAM,WAAW,kCACf,gBACA,eACF;EACA,IAAI,aAAa,GACf,OAAO;CAEX;CACA,OAAO;AACT;AAEA,SAAS,+BACP,gBACA,iBACQ;CACR,IAAI,mBAAmB,KAAA,KAAa,oBAAoB,KAAA,GACtD,OAAO;CAET,IAAI,mBAAmB,KAAA,GACrB,OAAO;CAET,IAAI,oBAAoB,KAAA,GACtB,OAAO;CAET,OAAO;AACT;AAEA,SAAS,kCACP,gBACA,iBACQ;CACR,IAAI,mBAAmB,iBACrB,OAAO;CAGT,MAAM,aAAa,8BAA8B,cAAc;CAC/D,MAAM,cAAc,8BAA8B,eAAe;CACjE,IAAI,eAAe,QAAQ,gBAAgB,MAAM;EAC/C,IAAI,eAAe,aACjB,OAAO;EAET,OAAO,aAAa,cAAc,IAAI;CACxC;CACA,IAAI,eAAe,MACjB,OAAO;CAET,IAAI,gBAAgB,MAClB,OAAO;CAET,OAAO,iBAAiB,kBAAkB,IAAI;AAChD;AAEA,SAAS,8BAA8B,YAAmC;CACxE,IAAI,CAAC,gCAAgC,KAAK,UAAU,GAClD,OAAO;CAET,OAAO,OAAO,UAAU;AAC1B;AAEA,SAAS,iBAAiB,OAA+B;CACvD,IAAI,OAAO,UAAU,UACnB,OAAO;CAET,MAAM,aAAa,MAAM,KAAK;CAC9B,OAAO,WAAW,SAAS,IAAI,aAAa;AAC9C;AAEA,SAAS,eAAe,OAAwB;CAC9C,IAAI,iBAAiB,OACnB,OAAO,MAAM;CAEf,OAAO,OAAO,KAAK;AACrB;;;;;;;;;;ACvlBA,SAAgB,yBAAiC;CAG/C,QADE,OAAO,yBAAyB,WAAW,qBAAqB,KAAK,IAAI,OACxDA,gBAAY;AACjC;AAEA,MAAa,mBAAmB,uBAAuB;;;ACJvD,MAAM,+BAA+B;CACnC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,MAAM,qBAAqB;CACzB;CACA;CACA;CACA;CACA;AACF;AAkCA,SAAS,sBAAsB,OAAwB;CACrD,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;AAEA,SAAS,mBAAmB,OAAiD;CAC3E,MAAM,aAAa,OAAO,UAAU,WAAW,MAAM,KAAK,IAAI;CAC9D,OAAO,WAAW,SAAS,IAAI,aAAa;AAC9C;AAEA,SAAS,uBAAuB,OAKZ;CAClB,IAAI,MAAM,eACR,OAAO,MAAM;CAEf,IAAI,MAAM,SAAS,gBACjB,OAAO;CAIT,IAAI,MAAM,SAAS,oBACjB,OAAO;CAET,IAAI,MAAM,WAAW,QACnB,OAAO;CAET,IACE,MAAM,WAAW,uBACjB,MAAM,WAAW,eACjB,MAAM,WAAW,mBACjB,MAAM,WAAW,kBAEjB,OAAO;CAET,OAAO;AACT;AAEA,SAAS,uBAAuB,OAA+C;CAC7E,IAAI,OAAO,UAAU,YAAY,UAAU,MACzC,OAAO;CAET,MAAM,YAAY;CAClB,OACE,UAAU,WAAW,wCACrB,UAAU,MAAM,KAChB,6BAA6B,SAC3B,UAAU,IACZ,KACA,OAAO,UAAU,cAAc,YAC/B,UAAU,UAAU,SAAS,KAC7B,OAAO,UAAU,SAAS,YAC1B,UAAU,KAAK,SAAS,KACxB,OAAO,UAAU,WAAW,YAC5B,UAAU,OAAO,SAAS,KAC1B,OAAO,UAAU,YAAY,YAC7B,UAAU,QAAQ,SAAS,KAC3B,OAAO,UAAU,QAAQ,YACzB,OAAO,UAAU,UAAU,GAAG,KAC9B,UAAU,MAAM,MACf,UAAU,cAAc,QACtB,OAAO,UAAU,cAAc,YAC9B,UAAU,UAAU,SAAS,OAChC,UAAU,cAAc,KAAA,KACvB,mBAAmB,SAAS,UAAU,SAAS,MACjD,OAAO,UAAU,WAAW,YAC5B,UAAU,OAAO,SAAS;AAE9B;AAEA,eAAe,kCAAkC,OAIT;CACtC,MAAM,WAAW,MAAM,mCAAmC,CAAC,CAAC,YAAY,IAAI;CAQ5E,OAAO;EACL,SAPA,MAAM,SAAS,KAAK,MACnB,OAAO,UAAU,YAAY,WAAW,SAAS,QAAQ,KAAK,IAAI,OACnE;EAMA,QAJA,MAAM,WACL,OAAO,UAAU,WAAW,WAAW,SAAS,SAAS;EAI1D,MAAM,yBAAyB,MAAM,SAAS;EAC9C,KACE,OAAO,UAAU,QAAQ,YAAY,SAAS,MAAM,IAChD,SAAS,MACT,QAAQ;EACd,WAAW,mBAAmB,UAAU,SAAS,KAAK,oBAAoB;CAC5E;AACF;AAEA,eAAsB,yBAAyB,OAQ7B;CAChB,+CACE,MAAM,aAAa,CAAC,GACpB,oCACF;CACA,MAAM,cAAc,2BAA2B,MAAM,SAAS;CAC9D,MAAM,6BAAY,IAAI,KAAK,EAAA,CAAE,YAAY;CACzC,MAAM,cACJ,MAAM,SAAS,qBACX;EACE,SAAS;EACT,QAAQ;EACR,MAAM,yBAAyB,MAAM,SAAS;EAC9C,KAAK,QAAQ;EACb,WAAW,oBAAoB;CACjC,IACA,MAAM,kCAAkC,KAAK;CACnD,MAAM,QAA8B;EAClC,QAAQ;EACR,GAAG;EACH,MAAM,MAAM;EACZ;EACA,MAAM,YAAY;EAClB,QAAQ,YAAY;EACpB,SAAS,YAAY;EACrB,KAAK,YAAY;EACjB,WAAW,YAAY;EACvB,WAAW,uBAAuB;GAChC,eAAe,MAAM;GACrB,QAAQ,YAAY;GACpB,QAAQ,MAAM;GACd,MAAM,MAAM;EACd,CAAC;EACD,QAAQ,MAAM;EACd,GAAI,MAAM,WAAW,EAAE,UAAU,MAAM,SAAS,IAAI,CAAC;CACvD;CAEA,IAAI,CAAC,uBAAuB,KAAK,GAAG;EAClC,QAAQ,KACN,uDAAuD,MAAM,MAC/D;EACA;CACF;CAEA,IAAI;EACF,MAAM,MAAM,QAAQ,WAAW,GAAG,EAAE,WAAW,KAAK,CAAC;EACrD,MAAM,WAAW,aAAa,GAAG,KAAK,UAAU,KAAK,EAAE,KAAK,MAAM;CACpE,SAAS,OAAO;EACd,QAAQ,KACN,uDAAuD,MAAM,KAAK,IAAI,sBAAsB,KAAK,GACnG;CACF;AACF;AAEA,eAAsB,qCAAwC,OAoB/C;CACb,MAAM,yBAAyB;EAC7B,MAAM;EACN,QAAQ;EACR,UAAU,MAAM,uBACZ;GACE,GAAG,MAAM;GACT,iBAAiB,KAAK,MAAM,QAAQ,OAAO,IAAI,GAAI;EACrD,IACA,MAAM;EACV,WAAW,MAAM;EACjB,SAAS,MAAM;EACf,QAAQ,MAAM;CAChB,CAAC;CAED,IAAI;EACF,MAAM,SAAS,MAAM,MAAM,IAAI;EAC/B,MAAM,iBAAiB,MAAM,gBAAgB,MAAM,KAAK,EACtD,QAAQ,YACV;EACA,MAAM,yBAAyB;GAC7B,MAAM;GACN,QAAQ,eAAe;GACvB,UAAU,eAAe;GACzB,WAAW,MAAM;GACjB,SAAS,MAAM;GACf,QAAQ,MAAM;EAChB,CAAC;EACD,OAAO;CACT,SAAS,OAAO;EACd,MAAM,yBAAyB;GAC7B,MAAM;GACN,QAAQ;GACR,UAAU,EACR,cAAc,sBAAsB,KAAK,EAC3C;GACA,WAAW,MAAM;GACjB,SAAS,MAAM;GACf,QAAQ,MAAM;EAChB,CAAC;EACD,MAAM;CACR;AACF;AAEA,eAAsB,8BAAiC,OAqBxC;CACb,MAAM,cAAc,KAAK,IAAI;CAC7B,IAAI;EACF,MAAM,SAAS,MAAM,MAAM,IAAI;EAC/B,MAAM,yBAAyB;GAC7B,MAAM;GACN,QAAQ;GACR,UAAU;IACR,QAAQ,MAAM;IACd,YAAY,MAAM;IAClB,YAAY,KAAK,IAAI,IAAI;IACzB,GAAI,MAAM,YAAY,CAAC;GACzB;GACA,WAAW,MAAM;GACjB,SAAS,MAAM;GACf,QAAQ,MAAM;EAChB,CAAC;EACD,OAAO;CACT,SAAS,OAAO;EACd,IAAI,gBAAgD;EACpD,IAAI;GACF,gBAAgB,MAAM,uBAAuB,KAAK,KAAK;EACzD,QAAQ;GACN,gBAAgB;EAClB;EACA,MAAM,yBAAyB;GAC7B,MAAM;GACN,QAAQ;GACR,UAAU;IACR,QAAQ,MAAM;IACd,YAAY,MAAM;IAClB,YAAY,KAAK,IAAI,IAAI;IACzB,cAAc,sBAAsB,KAAK;IACzC,GAAI,iBAAiB,CAAC;IACtB,GAAI,MAAM,YAAY,CAAC;GACzB;GACA,WAAW,MAAM;GACjB,SAAS,MAAM;GACf,QAAQ,MAAM;EAChB,CAAC;EACD,MAAM;CACR;AACF;AAEA,MAAM,sDAAsC,IAAI,IAA8B;CAC5E;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,eAAsB,qCACpB,QAAqD,CAAC,GAChB;CACtC,OAAO,MAAM,+BAA+B;EAC1C,WAAW,MAAM;EACjB,YAAY;CACd,CAAC;AACH;AAEA,eAAsB,8CACpB,QAAqD,CAAC,GAChB;CACtC,OAAO,MAAM,+BAA+B;EAC1C,WAAW,MAAM;EACjB,4BAAY,IAAI,IAA8B,CAAC,kBAAkB,CAAC;CACpE,CAAC;AACH;AAEA,eAAe,+BAA+B,OAGL;CACvC,MAAM,cAAc,2BAA2B,MAAM,SAAS;CAC9D,IAAI;CACJ,IAAI;EACF,UAAU,MAAM,SAAS,aAAa,MAAM;CAC9C,SAAS,OAAO;EACd,IAAK,MAAgC,SAAS,UAC5C,OAAO;EAET,MAAM;CACR;CAEA,MAAM,QAAQ,QACX,MAAM,IAAI,CAAC,CACX,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAC1B,QAAQ,SAAS,KAAK,SAAS,CAAC;CAEnC,KAAK,IAAI,QAAQ,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG;EACzD,MAAM,OAAO,MAAM;EACnB,IAAI,CAAC,MACH;EAEF,IAAI;GACF,MAAM,SAAS,KAAK,MAAM,IAAI;GAC9B,IAAI,uBAAuB,MAAM,KAAK,MAAM,WAAW,IAAI,OAAO,IAAI,GACpE,OAAO;EAEX,QAAQ,CAER;CACF;CAEA,OAAO;AACT;AAEA,eAAsB,gCAAgC,OAGlB;CAClC,IAAI,MAAM,cAAc,GACtB,OAAO,CAAC;CAEV,MAAM,cAAc,2BAA2B,MAAM,SAAS;CAC9D,IAAI;CACJ,IAAI;EACF,UAAU,MAAM,SAAS,aAAa,MAAM;CAC9C,SAAS,OAAO;EACd,IAAK,MAAgC,SAAS,UAC5C,OAAO,CAAC;EAEV,MAAM;CACR;CAEA,MAAM,QAAQ,QACX,MAAM,IAAI,CAAC,CACX,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAC1B,QAAQ,SAAS,KAAK,SAAS,CAAC;CAEnC,MAAM,SAAiC,CAAC;CACxC,KAAK,IAAI,QAAQ,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG;EACzD,MAAM,OAAO,MAAM;EACnB,IAAI,CAAC,MACH;EAEF,IAAI;GACF,MAAM,SAAS,KAAK,MAAM,IAAI;GAC9B,IAAI,uBAAuB,MAAM,GAAG;IAClC,OAAO,KAAK,MAAM;IAClB,IAAI,OAAO,UAAU,MAAM,YACzB;GAEJ;EACF,QAAQ,CAER;CACF;CAEA,OAAO,OAAO,QAAQ;AACxB;AAEA,eAAsB,mCACpB,QAAwE,CAAC,GAIzE;CACA,MAAM,QAAQ,KAAK,IAAI;CACvB,MAAM,WAAW,MAAM,YAAY;CACnC,MAAM,SAAS,MAAM,gCAAgC;EACnD,YAAY;EACZ,WAAW,MAAM;CACnB,CAAC;CACD,KAAK,MAAM,SAAS,OAAO,WAAW,GAAG;EACvC,MAAM,YAAY,KAAK,MAAM,MAAM,SAAS;EAC5C,IACE,CAAC,OAAO,SAAS,SAAS,KAC1B,QAAQ,YAAY,KACpB,QAAQ,YAAY,UAEpB;EAEF,IACE,MAAM,cAAc,eACpB,MAAM,cAAc,6BAEpB,OAAO,MAAM;CAEjB;CACA,OAAO;AACT;AAEA,SAAgB,mCACd,OACQ;CACR,MAAM,SAAS,4BAA4B,MAAM,MAAM;CACvD,OAAO,GAAG,MAAM,OAAO,GAAG,OAAO,QAAQ,MAAM,QAAQ,MAAM,MAAM,UAAU,QAAQ,MAAM,IAAI;AACjG;AAEA,SAAS,4BAA4B,QAAwB;CAC3D,IAAI,WAAW,WACb,OAAO;CAET,OAAO,OAAO,WAAW,KAAK,GAAG;AACnC"}