openmeld 0.3.222 → 0.3.224

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 (177) hide show
  1. package/dist/{add-me-membership-Wc69O6rA.js → add-me-membership-CGISMRPF.js} +2 -2
  2. package/dist/{add-me-membership-Wc69O6rA.js.map → add-me-membership-CGISMRPF.js.map} +1 -1
  3. package/dist/{agents-B8zhQnGw.js → agents-CR7BebgO.js} +12 -12
  4. package/dist/{agents-B8zhQnGw.js.map → agents-CR7BebgO.js.map} +1 -1
  5. package/dist/{api-client-foundation-DTiFoGpI.js → api-client-foundation-CqbIn_de.js} +1 -1
  6. package/dist/{api-client-foundation-DnJ_JYli.js → api-client-foundation-DpVwrgh-.js} +3 -3
  7. package/dist/{api-client-foundation-DnJ_JYli.js.map → api-client-foundation-DpVwrgh-.js.map} +1 -1
  8. package/dist/auth-session-BJfKu74u.js +4 -0
  9. package/dist/{auth-session-nhS8jyux.js → auth-session-uEk_Tx6T.js} +8 -8
  10. package/dist/auth-session-uEk_Tx6T.js.map +1 -0
  11. package/dist/{base-url-CMBApK1J.js → base-url-DXrUiSMI.js} +1 -1
  12. package/dist/{base-url-D7uE_xTo.js → base-url-DvjOkKPs.js} +2 -2
  13. package/dist/{base-url-D7uE_xTo.js.map → base-url-DvjOkKPs.js.map} +1 -1
  14. package/dist/{channel-ggx0o_aG.js → channel-B2fD2_be.js} +4 -4
  15. package/dist/{channel-ggx0o_aG.js.map → channel-B2fD2_be.js.map} +1 -1
  16. package/dist/{cli-binary-manifest-DiUulkp0.js → cli-binary-manifest-CT5X05lk.js} +30 -4
  17. package/dist/cli-binary-manifest-CT5X05lk.js.map +1 -0
  18. package/dist/{command-Bz9x7V2T.js → command-CQ9XRwqf.js} +22 -165
  19. package/dist/command-CQ9XRwqf.js.map +1 -0
  20. package/dist/{computer-connection-M3N6plkj.js → computer-connection-Dm7iTnRK.js} +2 -2
  21. package/dist/{computer-connection-M3N6plkj.js.map → computer-connection-Dm7iTnRK.js.map} +1 -1
  22. package/dist/{computer-connection-review-DY5BK_27.js → computer-connection-review-RHAoddSS.js} +6 -6
  23. package/dist/{computer-connection-review-DY5BK_27.js.map → computer-connection-review-RHAoddSS.js.map} +1 -1
  24. package/dist/{computer-disconnect-DR1WDSPK.js → computer-disconnect-BWRsge_2.js} +10 -10
  25. package/dist/{computer-disconnect-DR1WDSPK.js.map → computer-disconnect-BWRsge_2.js.map} +1 -1
  26. package/dist/{computer-setup-continuation-2gs8z-nB.js → computer-setup-continuation-BOCRH0qq.js} +4 -4
  27. package/dist/{computer-setup-continuation-2gs8z-nB.js.map → computer-setup-continuation-BOCRH0qq.js.map} +1 -1
  28. package/dist/context-Bdh3nAzw.js +162 -0
  29. package/dist/context-Bdh3nAzw.js.map +1 -0
  30. package/dist/{control-plane-e3W6PD2M.js → control-plane-rTE2rHZ5.js} +2 -2
  31. package/dist/{control-plane-e3W6PD2M.js.map → control-plane-rTE2rHZ5.js.map} +1 -1
  32. package/dist/{daemon-device-id-DWO9_QW6.js → daemon-device-id-B1Af2Zmn.js} +344 -36
  33. package/dist/daemon-device-id-B1Af2Zmn.js.map +1 -0
  34. package/dist/{daemon-frame-transport-D2-tazuK.js → daemon-frame-transport-WiB73yhT.js} +519 -12
  35. package/dist/daemon-frame-transport-WiB73yhT.js.map +1 -0
  36. package/dist/{daemon-lifecycle-journal-DyKx1xzm.js → daemon-lifecycle-journal-CDZLWgMj.js} +11 -11
  37. package/dist/daemon-lifecycle-journal-CDZLWgMj.js.map +1 -0
  38. package/dist/{daemon-runtime-lease-BUr4qsLo.js → daemon-runtime-lease-1LMeZ6IS.js} +2 -2
  39. package/dist/{daemon-runtime-lease-BUr4qsLo.js.map → daemon-runtime-lease-1LMeZ6IS.js.map} +1 -1
  40. package/dist/{daemon-runtime-lease-C9X8xV_F.js → daemon-runtime-lease-Bz0ucJj3.js} +1 -1
  41. package/dist/{daemon-service-contract-BpOBMGX0.js → daemon-service-contract-GLmAxsq-.js} +4 -4
  42. package/dist/{daemon-service-contract-BpOBMGX0.js.map → daemon-service-contract-GLmAxsq-.js.map} +1 -1
  43. package/dist/{daemon-service-manager-HL4VKbIU.js → daemon-service-manager-C8RUCMDo.js} +9 -7
  44. package/dist/daemon-service-manager-C8RUCMDo.js.map +1 -0
  45. package/dist/{daemon-service-manager-B-QrDe5p.js → daemon-service-manager-CU-79a4z.js} +1 -1
  46. package/dist/{daemon-service-runtime-bKt0YjC7.js → daemon-service-runtime-CBJtgM4P.js} +397 -51
  47. package/dist/daemon-service-runtime-CBJtgM4P.js.map +1 -0
  48. package/dist/{daemon-service-update-coordinator-D8O1uTtu.js → daemon-service-update-coordinator-0LB_XGVZ.js} +48 -33
  49. package/dist/daemon-service-update-coordinator-0LB_XGVZ.js.map +1 -0
  50. package/dist/{daemon-state-B44aq2nm.js → daemon-state-Ca0WK5x0.js} +3 -3
  51. package/dist/{daemon-state-B44aq2nm.js.map → daemon-state-Ca0WK5x0.js.map} +1 -1
  52. package/dist/{dist-B07ziN_u.js → dist-BeJcIdCZ.js} +25 -17
  53. package/dist/dist-BeJcIdCZ.js.map +1 -0
  54. package/dist/dist-C32frPV2.js +4 -0
  55. package/dist/{dist-B2EauBG6.js → dist-YbTZ-Y-2.js} +16 -12
  56. package/dist/dist-YbTZ-Y-2.js.map +1 -0
  57. package/dist/{elapsed-time-Ooo4IC25.js → elapsed-time-q8lSPcfm.js} +6 -6
  58. package/dist/{elapsed-time-Ooo4IC25.js.map → elapsed-time-q8lSPcfm.js.map} +1 -1
  59. package/dist/{entry-DeIRMCiW.js → entry-CpS6tnIk.js} +12 -12
  60. package/dist/{entry-DeIRMCiW.js.map → entry-CpS6tnIk.js.map} +1 -1
  61. package/dist/{installation-inventory-DThnBEhV.js → installation-inventory-C5FsAvrf.js} +5 -5
  62. package/dist/{installation-inventory-DThnBEhV.js.map → installation-inventory-C5FsAvrf.js.map} +1 -1
  63. package/dist/{installer-D2bWZT88.js → installer-054NLJg6.js} +2 -2
  64. package/dist/{installer-D2bWZT88.js.map → installer-054NLJg6.js.map} +1 -1
  65. package/dist/io-DT66typ4.js +16 -0
  66. package/dist/io-DT66typ4.js.map +1 -0
  67. package/dist/{local-components-B6SCXZf9.js → local-components-DleLEzSU.js} +2 -1
  68. package/dist/local-components-DleLEzSU.js.map +1 -0
  69. package/dist/{lock-Bsl_ElWy.js → lock-iue1J2xy.js} +8 -5
  70. package/dist/lock-iue1J2xy.js.map +1 -0
  71. package/dist/{cli-space-api-CQtKu9Zt.js → meta-api-B1k3mwHN.js} +203 -19
  72. package/dist/meta-api-B1k3mwHN.js.map +1 -0
  73. package/dist/{openmeld-BQy0nMox.js → openmeld-BFO3sfC_.js} +93 -1027
  74. package/dist/openmeld-BFO3sfC_.js.map +1 -0
  75. package/dist/openmeld-dev.js +1 -1
  76. package/dist/{openmeld-environment-target-B6HqY0_a.js → openmeld-environment-target-BBn5Ko6p.js} +3 -3
  77. package/dist/{openmeld-environment-target-B6HqY0_a.js.map → openmeld-environment-target-BBn5Ko6p.js.map} +1 -1
  78. package/dist/{openmeld-maintenance-worker-BSODPHbn.js → openmeld-maintenance-worker-Ce4ehQ-c.js} +15 -14
  79. package/dist/openmeld-maintenance-worker-Ce4ehQ-c.js.map +1 -0
  80. package/dist/{openmeld-tools-update-join-BfY0GnDs.js → openmeld-tools-update-join-D24llJ9L.js} +4 -4
  81. package/dist/{openmeld-tools-update-join-BfY0GnDs.js.map → openmeld-tools-update-join-D24llJ9L.js.map} +1 -1
  82. package/dist/{openmeld-tools-update-process-frame-B-XB4dmO.js → openmeld-tools-update-process-frame-BtFKp70p.js} +2 -2
  83. package/dist/{openmeld-tools-update-process-frame-B-XB4dmO.js.map → openmeld-tools-update-process-frame-BtFKp70p.js.map} +1 -1
  84. package/dist/{openmeld-tools-update-process-frame-j-RXwFsK.js → openmeld-tools-update-process-frame-DbEZ3fEh.js} +1 -1
  85. package/dist/openmeld.js +9 -5
  86. package/dist/openmeld.js.map +1 -1
  87. package/dist/{prepare-provider-runtime-CWZcuMF6.js → prepare-provider-runtime-MB-BxOgt.js} +3342 -1327
  88. package/dist/prepare-provider-runtime-MB-BxOgt.js.map +1 -0
  89. package/dist/{prepare-session-executor-CkDxstsf.js → prepare-session-executor-zvSZ6jqy.js} +29 -28
  90. package/dist/prepare-session-executor-zvSZ6jqy.js.map +1 -0
  91. package/dist/{presenter-BcxiQyJg.js → presenter-MJ5YgsOT.js} +3 -13
  92. package/dist/presenter-MJ5YgsOT.js.map +1 -0
  93. package/dist/{process-channel-BQwtOlRc.js → process-channel-CgbduFCz.js} +2 -2
  94. package/dist/{process-channel-BQwtOlRc.js.map → process-channel-CgbduFCz.js.map} +1 -1
  95. package/dist/process-environment-BWSFeUu6.js +49 -0
  96. package/dist/process-environment-BWSFeUu6.js.map +1 -0
  97. package/dist/process-identity-BQLdaZdB.js +190 -0
  98. package/dist/process-identity-BQLdaZdB.js.map +1 -0
  99. package/dist/process-launch-B0pHlkV_.js +173 -0
  100. package/dist/process-launch-B0pHlkV_.js.map +1 -0
  101. package/dist/{published-production-safety-dp-fOmmB.js → published-production-safety-C40hKrBA.js} +2 -2
  102. package/dist/{published-production-safety-dp-fOmmB.js.map → published-production-safety-C40hKrBA.js.map} +1 -1
  103. package/dist/{runtime-BYaFkkLK.js → runtime-D6jItuQ-.js} +155 -702
  104. package/dist/runtime-D6jItuQ-.js.map +1 -0
  105. package/dist/{runtime-agent-controller-reporting-submission-BUUub9_1.js → runtime-agent-controller-reporting-submission-D9ysbi7R.js} +9 -9
  106. package/dist/{runtime-agent-controller-reporting-submission-BUUub9_1.js.map → runtime-agent-controller-reporting-submission-D9ysbi7R.js.map} +1 -1
  107. package/dist/{runtime-reporting-health-state-BgwfrH7f.js → runtime-reporting-health-state-DA-_vW-n.js} +2210 -60
  108. package/dist/runtime-reporting-health-state-DA-_vW-n.js.map +1 -0
  109. package/dist/{runtime-transport-Cc_RN-PL.js → runtime-transport-YIYHSJPn.js} +99 -14
  110. package/dist/runtime-transport-YIYHSJPn.js.map +1 -0
  111. package/dist/{service-CfO38_a-.js → service-Dz2MsvGr.js} +126 -550
  112. package/dist/service-Dz2MsvGr.js.map +1 -0
  113. package/dist/{service-account-admission-Dy2W3n3_.js → service-account-admission-BfdJ-kKR.js} +18 -10
  114. package/dist/service-account-admission-BfdJ-kKR.js.map +1 -0
  115. package/dist/{service-account-authorization-DKpIpxXo.js → service-account-authorization-DZbUOD29.js} +6 -6
  116. package/dist/{service-account-authorization-DKpIpxXo.js.map → service-account-authorization-DZbUOD29.js.map} +1 -1
  117. package/dist/{service-account-control-CCPQAZzn.js → service-account-control-DCMOKXDT.js} +16 -16
  118. package/dist/service-account-control-DCMOKXDT.js.map +1 -0
  119. package/dist/{service-control-capabilities-C9UHSMPz.js → service-control-capabilities-3_bdeHXu.js} +1 -1
  120. package/dist/{service-control-capabilities-xGylBNoH.js → service-control-capabilities-Bb738e_d.js} +19 -15
  121. package/dist/service-control-capabilities-Bb738e_d.js.map +1 -0
  122. package/dist/{service-control-carrier-capability-DDNyE5cB.js → service-control-carrier-capability-gMk5gMKU.js} +11 -4
  123. package/dist/service-control-carrier-capability-gMk5gMKU.js.map +1 -0
  124. package/dist/{state-CQG3k9eh.js → state-GxF_KAM1.js} +4 -4
  125. package/dist/{state-CQG3k9eh.js.map → state-GxF_KAM1.js.map} +1 -1
  126. package/dist/{upgrade-D5FxGbh1.js → upgrade-DfJwCD5H.js} +52 -32
  127. package/dist/upgrade-DfJwCD5H.js.map +1 -0
  128. package/dist/upgrade-DgmYWeNu.js +4 -0
  129. package/dist/windows/openmeld-windows-process.exe +0 -0
  130. package/dist/windows-artifact-DJ9DKjfc.js +16 -0
  131. package/dist/windows-artifact-DJ9DKjfc.js.map +1 -0
  132. package/dist/windows-task-command-COu_6Ke3.js +74 -0
  133. package/dist/windows-task-command-COu_6Ke3.js.map +1 -0
  134. package/dist/windows-task-entry-CtRpUbiK.js +50 -0
  135. package/dist/windows-task-entry-CtRpUbiK.js.map +1 -0
  136. package/dist/{windows-user-task-Bx2yYnOM.js → windows-user-task-B8NcRg_u.js} +1 -1
  137. package/dist/{windows-user-task-CRGbKggi.js → windows-user-task-Io5QuEVR.js} +108 -51
  138. package/dist/windows-user-task-Io5QuEVR.js.map +1 -0
  139. package/package.json +12 -12
  140. package/skills/openmeld-cli/playbooks/space-ops.md +9 -3
  141. package/skills/openmeld-cli/references/commands.md +0 -1
  142. package/dist/auth-session-D8dbMpaK.js +0 -4
  143. package/dist/auth-session-nhS8jyux.js.map +0 -1
  144. package/dist/cli-binary-manifest-DiUulkp0.js.map +0 -1
  145. package/dist/cli-space-api-CQtKu9Zt.js.map +0 -1
  146. package/dist/command-Bz9x7V2T.js.map +0 -1
  147. package/dist/context-l_31Mn4X.js +0 -473
  148. package/dist/context-l_31Mn4X.js.map +0 -1
  149. package/dist/daemon-device-id-DWO9_QW6.js.map +0 -1
  150. package/dist/daemon-frame-transport-D2-tazuK.js.map +0 -1
  151. package/dist/daemon-lifecycle-journal-DyKx1xzm.js.map +0 -1
  152. package/dist/daemon-service-manager-HL4VKbIU.js.map +0 -1
  153. package/dist/daemon-service-runtime-bKt0YjC7.js.map +0 -1
  154. package/dist/daemon-service-update-coordinator-D8O1uTtu.js.map +0 -1
  155. package/dist/dist-B07ziN_u.js.map +0 -1
  156. package/dist/dist-B2EauBG6.js.map +0 -1
  157. package/dist/dist-DhWI1iyi.js +0 -4
  158. package/dist/local-components-B6SCXZf9.js.map +0 -1
  159. package/dist/lock-Bsl_ElWy.js.map +0 -1
  160. package/dist/openmeld-BQy0nMox.js.map +0 -1
  161. package/dist/openmeld-maintenance-worker-BSODPHbn.js.map +0 -1
  162. package/dist/prepare-provider-runtime-CWZcuMF6.js.map +0 -1
  163. package/dist/prepare-session-executor-CkDxstsf.js.map +0 -1
  164. package/dist/presenter-BcxiQyJg.js.map +0 -1
  165. package/dist/process-identity-CNus0e6E.js +0 -146
  166. package/dist/process-identity-CNus0e6E.js.map +0 -1
  167. package/dist/runtime-BYaFkkLK.js.map +0 -1
  168. package/dist/runtime-reporting-health-state-BgwfrH7f.js.map +0 -1
  169. package/dist/runtime-transport-Cc_RN-PL.js.map +0 -1
  170. package/dist/service-CfO38_a-.js.map +0 -1
  171. package/dist/service-account-admission-Dy2W3n3_.js.map +0 -1
  172. package/dist/service-account-control-CCPQAZzn.js.map +0 -1
  173. package/dist/service-control-capabilities-xGylBNoH.js.map +0 -1
  174. package/dist/service-control-carrier-capability-DDNyE5cB.js.map +0 -1
  175. package/dist/upgrade-D5FxGbh1.js.map +0 -1
  176. package/dist/upgrade-DhFEu0k6.js +0 -4
  177. package/dist/windows-user-task-CRGbKggi.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"state-CQG3k9eh.js","names":["getErrorCode"],"sources":["../../../packages/schemas/dist/official-cli-skill.js","../src/skills/bundled.ts","../src/skills/bundled-assets-fs.ts","../src/skills/bundled-assets.ts","../src/skills/content-hash.ts","../src/skills/install-lock.ts","../src/skills/official-release.ts","../src/skills/replace-directory.ts","../src/skills/store.ts","../src/skills/state.ts"],"sourcesContent":["import * as z$1 from \"zod/v4\";\n//#region src/official-cli-skill.ts\nconst OFFICIAL_CLI_SKILL_CONTRACT = \"openmeld-skills-contract-2026-09-explicit-space-recipients-v1\";\nconst OFFICIAL_CLI_SKILL_URL = \"https://openmeld.ai/skills/openmeld-cli/SKILL.md\";\nconst OFFICIAL_CLI_SKILL_MAX_BYTES = 1048576;\nconst OFFICIAL_CLI_SKILL_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAFZjFHrQ/QLsJQpHkAbKBRG57fEazhm7zc0dMa54ilWQ=\n-----END PUBLIC KEY-----\n`;\nconst officialCliSkillPayloadSchema = z$1.object({\n\tschemaVersion: z$1.literal(1),\n\trevision: z$1.number().int().positive(),\n\tminimumCliVersion: z$1.string().regex(/^\\d+\\.\\d+\\.\\d+$/),\n\tcontractVersion: z$1.string().min(1).max(128),\n\tfiles: z$1.array(z$1.object({\n\t\tpath: z$1.string().regex(/^(?:SKILL\\.md|(?:playbooks|references)\\/[a-z0-9-]+\\.md)$/),\n\t\tcontent: z$1.string().min(1).max(131072)\n\t}).strict()).min(1).max(32)\n}).strict().superRefine((value, context) => {\n\tconst paths = value.files.map((file) => file.path);\n\tif (!paths.includes(\"SKILL.md\") || new Set(paths).size !== paths.length) context.addIssue({\n\t\tcode: \"custom\",\n\t\tmessage: \"Skill entry is required and paths must be unique\"\n\t});\n});\nconst officialCliSkillReleaseSchema = z$1.object({\n\tpayload: z$1.string().min(1).max(524288),\n\tsignature: z$1.string().regex(/^[A-Za-z0-9+/]{86}==$/)\n}).strict();\nconst officialCliSkillChannelSchema = z$1.object({\n\tschemaVersion: z$1.literal(1),\n\treleases: z$1.array(officialCliSkillReleaseSchema).min(1).max(16)\n}).strict();\n//#endregion\nexport { OFFICIAL_CLI_SKILL_CONTRACT, OFFICIAL_CLI_SKILL_MAX_BYTES, OFFICIAL_CLI_SKILL_PUBLIC_KEY, OFFICIAL_CLI_SKILL_URL, officialCliSkillChannelSchema, officialCliSkillPayloadSchema, officialCliSkillReleaseSchema };\n\n//# sourceMappingURL=official-cli-skill.js.map","import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst CLI_PACKAGE_JSON = \"package.json\";\n\nexport type BundledSkillsLocation = {\n cliRootDir: string;\n skillsRootDir: string;\n};\n\n/**\n * Locate the on-disk bundled skills directory for the npm distribution by\n * walking up from this module to the CLI package root (a directory that has\n * both package.json and skills/). Returns null under the binary distribution,\n * where import.meta.url is a virtual path and the skills are embedded instead —\n * callers in that mode go through bundled-assets.ts, not this function.\n */\nexport function resolveBundledSkillsLocation(): BundledSkillsLocation | null {\n const moduleDir = path.dirname(fileURLToPath(import.meta.url));\n const cliRootDir = resolveCliRootDir(moduleDir);\n if (!cliRootDir) {\n return null;\n }\n return {\n cliRootDir,\n skillsRootDir: path.join(cliRootDir, \"skills\"),\n };\n}\n\nfunction resolveCliRootDir(fromDir: string): string | null {\n let current = fromDir;\n for (;;) {\n const packageJsonPath = path.join(current, CLI_PACKAGE_JSON);\n const hasPackageJson = existsSync(packageJsonPath);\n const hasSkillsDir = existsSync(path.join(current, \"skills\"));\n if (hasPackageJson && hasSkillsDir) {\n return current;\n }\n const parent = path.dirname(current);\n if (parent === current) {\n return null;\n }\n current = parent;\n }\n}\n","import { readdir, readFile } from \"node:fs/promises\";\nimport { join, relative } from \"node:path\";\nimport { resolveBundledSkillsLocation } from \"./bundled\";\nimport type { BundledSkillAsset } from \"./bundled-assets\";\n\n/**\n * npm-distribution source: read the bundled skills from the on-disk `skills/`\n * directory next to the CLI package. Assets are sorted by relative path so the\n * order (and therefore any content hash computed from them) is stable and\n * matches the embedded distribution.\n */\nexport async function loadFsBundledSkillAssets(): Promise<BundledSkillAsset[]> {\n const location = resolveBundledSkillsLocation();\n if (!location) {\n throw new Error(\"unable to resolve bundled OpenMeld skills directory\");\n }\n const assets = await collectSkillAssets(\n location.skillsRootDir,\n location.skillsRootDir\n );\n return sortBundledSkillAssets(assets);\n}\n\nexport function sortBundledSkillAssets(\n assets: BundledSkillAsset[]\n): BundledSkillAsset[] {\n return [...assets].sort((left, right) =>\n left.relativePath.localeCompare(right.relativePath)\n );\n}\n\nasync function collectSkillAssets(\n dir: string,\n rootDir: string\n): Promise<BundledSkillAsset[]> {\n const entries = await readdir(dir, { withFileTypes: true });\n const assets: BundledSkillAsset[] = [];\n for (const entry of entries) {\n const absolutePath = join(dir, entry.name);\n if (entry.isDirectory()) {\n assets.push(...(await collectSkillAssets(absolutePath, rootDir)));\n continue;\n }\n if (!entry.isFile()) {\n continue;\n }\n assets.push({\n relativePath: toPosixRelativePath(relative(rootDir, absolutePath)),\n content: await readFile(absolutePath),\n });\n }\n return assets;\n}\n\nfunction toPosixRelativePath(value: string): string {\n return value.split(\"\\\\\").join(\"/\");\n}\n","import { createHash } from \"node:crypto\";\nimport { isBinaryDistribution } from \"../runtime/distribution\";\nimport { loadFsBundledSkillAssets } from \"./bundled-assets-fs\";\n\n/**\n * One bundled skill file, addressed by its POSIX path relative to the skills/\n * root (e.g. \"README.md\", \"openmeld-cli/SKILL.md\"). This is the single shape\n * both distribution forms produce, so downstream skill install and bundle-hash\n * logic never branches on how the files were sourced.\n */\nexport type BundledSkillAsset = {\n relativePath: string;\n content: Buffer;\n};\n\n/**\n * Load the OpenMeld-managed skill files that ship with this CLI build.\n *\n * - npm distribution: read from the on-disk `skills/` directory.\n * - binary distribution: read from files embedded into the single binary at\n * compile time. The embedded module is a Bun-only island resolved only by\n * `bun build --compile`; the npm build never reaches this branch and marks\n * the module external, so its `with { type: \"file\" }` imports are never\n * parsed by tsdown.\n */\nexport async function loadBundledSkillAssets(): Promise<BundledSkillAsset[]> {\n if (isBinaryDistribution()) {\n const embedded = await import(\"./bundled-assets-embedded\");\n return embedded.loadEmbeddedBundledSkillAssets();\n }\n return loadFsBundledSkillAssets();\n}\n\n/**\n * Content hash over an ordered list of skill assets. Byte-for-byte compatible\n * with `computeDirectoryContentHash` (same `file:<relativePath>\\n<content>\\n`\n * framing) so the embedded and on-disk sources produce identical hashes as long\n * as `assets` is sorted by relative path (as `loadBundledSkillAssets` returns\n * it). This is the single skills-hash algorithm for both distribution forms.\n */\nexport function hashBundledSkillAssets(assets: BundledSkillAsset[]): string {\n const hash = createHash(\"sha256\");\n for (const asset of assets) {\n hash.update(`file:${asset.relativePath}\\n`);\n hash.update(asset.content);\n hash.update(\"\\n\");\n }\n return hash.digest(\"hex\");\n}\n\nconst OPENMELD_CLI_SKILL_ID = \"openmeld-cli\";\nconst OPENMELD_CLI_SKILL_FILE = \"SKILL.md\";\n\n/**\n * Read one OpenMeld CLI skill document by its path relative to the skill root\n * (e.g. \"SKILL.md\", \"references/commands.md\"). Works in both distribution forms\n * via loadBundledSkillAssets, so `openmeld prompt --raw` renders the bundled\n * markdown from the embedded binary too.\n */\nexport async function readBundledOpenMeldCliSkillDocumentByPath(\n skillRelativePath: string\n): Promise<string> {\n const targetPath = `${OPENMELD_CLI_SKILL_ID}/${skillRelativePath}`;\n const assets = await loadBundledSkillAssets();\n const asset = assets.find((item) => item.relativePath === targetPath);\n if (!asset) {\n throw new Error(\n `bundled OpenMeld CLI skill document is missing: ${skillRelativePath}`\n );\n }\n return asset.content.toString(\"utf8\");\n}\n\nexport function readBundledOpenMeldCliSkillDocument(): Promise<string> {\n return readBundledOpenMeldCliSkillDocumentByPath(OPENMELD_CLI_SKILL_FILE);\n}\n","import { createHash } from \"node:crypto\";\nimport { readdir, readFile } from \"node:fs/promises\";\nimport { join, relative } from \"node:path\";\n\nexport async function computeDirectoryContentHash(input: {\n rootDir: string;\n ignoredNames?: string[];\n}): Promise<string> {\n const ignoredNames = new Set(input.ignoredNames ?? []);\n const files = await collectFiles({\n dir: input.rootDir,\n rootDir: input.rootDir,\n ignoredNames,\n });\n const hash = createHash(\"sha256\");\n for (const file of files) {\n hash.update(`file:${file.relativePath}\\n`);\n hash.update(file.content);\n hash.update(\"\\n\");\n }\n return hash.digest(\"hex\");\n}\n\nasync function collectFiles(input: {\n dir: string;\n rootDir: string;\n ignoredNames: Set<string>;\n}): Promise<Array<{ relativePath: string; content: Buffer }>> {\n const entries = await readdir(input.dir, { withFileTypes: true }).catch(\n (error: unknown) => {\n if (getErrorCode(error) === \"ENOENT\") {\n return [];\n }\n warnDirectoryReadError(input.dir, error);\n throw error;\n }\n );\n entries.sort((a, b) => a.name.localeCompare(b.name));\n\n const files: Array<{ relativePath: string; content: Buffer }> = [];\n for (const entry of entries) {\n if (input.ignoredNames.has(entry.name)) {\n continue;\n }\n const absolutePath = join(input.dir, entry.name);\n if (entry.isDirectory()) {\n files.push(\n ...(await collectFiles({\n dir: absolutePath,\n rootDir: input.rootDir,\n ignoredNames: input.ignoredNames,\n }))\n );\n continue;\n }\n if (!entry.isFile()) {\n continue;\n }\n const content = await readFile(absolutePath);\n files.push({\n relativePath: normalizeRelativePath(\n relative(input.rootDir, absolutePath)\n ),\n content,\n });\n }\n return files;\n}\n\nfunction normalizeRelativePath(value: string): string {\n return value.split(\"\\\\\").join(\"/\");\n}\n\nfunction getErrorCode(error: unknown): string | undefined {\n if (!error || typeof error !== \"object\") {\n return undefined;\n }\n const code = (error as { code?: unknown }).code;\n return typeof code === \"string\" ? code : undefined;\n}\n\nfunction warnDirectoryReadError(dir: string, error: unknown): void {\n const reason = error instanceof Error ? error.message : String(error);\n process.stderr.write(\n `[openmeld] failed to read directory while hashing skills content (${dir}): ${reason}\\n`\n );\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { mkdir, readFile, rm, stat, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { runtimeLogsDir } from \"../config/paths\";\n\nconst heldLock = new AsyncLocalStorage<boolean>();\nconst pendingLocks = new Map<string, Promise<unknown>>();\nexport function withSkillsInstallLock<T>(run: () => Promise<T>): Promise<T> {\n if (heldLock.getStore()) {\n return run();\n }\n const key = runtimeLogsDir();\n const previous = pendingLocks.get(key) ?? Promise.resolve();\n const current = previous\n .catch(() => undefined)\n .then(() => acquireSkillsInstallLock(() => heldLock.run(true, run)));\n pendingLocks.set(key, current);\n return current.finally(() => {\n if (pendingLocks.get(key) === current) {\n pendingLocks.delete(key);\n }\n });\n}\n\nconst LOCK_FILE_NAME = \"skills-install.lock\";\nconst LOCK_ACQUIRE_MAX_ATTEMPTS = 3;\n\nasync function acquireSkillsInstallLock<T>(run: () => Promise<T>): Promise<T> {\n const logsDir = runtimeLogsDir();\n await mkdir(logsDir, { recursive: true });\n const lockPath = join(logsDir, LOCK_FILE_NAME);\n\n let acquired = false;\n const lockContents = `${JSON.stringify({\n pid: process.pid,\n createdAt: new Date().toISOString(),\n })}\\n`;\n for (let attempt = 0; attempt < LOCK_ACQUIRE_MAX_ATTEMPTS; attempt += 1) {\n try {\n await writeFile(lockPath, lockContents, {\n encoding: \"utf8\",\n flag: \"wx\",\n });\n acquired = true;\n break;\n } catch (error) {\n if (getErrorCode(error) !== \"EEXIST\") {\n throw error;\n }\n\n const recovered = await recoverStaleSkillsInstallLock(lockPath);\n if (!recovered) {\n throw new Error(\n \"another skills installation is already running; retry after it finishes\"\n );\n }\n\n try {\n await writeFile(lockPath, lockContents, {\n encoding: \"utf8\",\n flag: \"wx\",\n });\n acquired = true;\n break;\n } catch (retryError) {\n if (getErrorCode(retryError) !== \"EEXIST\") {\n throw retryError;\n }\n }\n }\n }\n\n if (!acquired) {\n throw new Error(\n \"another skills installation is already running; retry after it finishes\"\n );\n }\n\n try {\n return await run();\n } finally {\n await rm(lockPath, { force: true }).catch(() => undefined);\n }\n}\n\nasync function recoverStaleSkillsInstallLock(\n lockPath: string\n): Promise<boolean> {\n const lockRaw = await readFile(lockPath, \"utf8\").catch((error: unknown) => {\n if (getErrorCode(error) === \"ENOENT\") {\n return \"\";\n }\n throw error;\n });\n if (!lockRaw) {\n return true;\n }\n\n const parsed = parseLockMeta(lockRaw);\n const pid = resolveLockPid(parsed);\n if (!pid) {\n const metadata = await stat(lockPath).catch(() => null);\n if (metadata && Date.now() - metadata.mtimeMs < 30_000) {\n return false;\n }\n }\n if (pid && isPidAlive(pid)) {\n return false;\n }\n\n const latestLockRaw = await readFile(lockPath, \"utf8\").catch(\n (error: unknown) => {\n if (getErrorCode(error) === \"ENOENT\") {\n return \"\";\n }\n throw error;\n }\n );\n if (!latestLockRaw) {\n return true;\n }\n const latestParsed = parseLockMeta(latestLockRaw);\n const latestPid = resolveLockPid(latestParsed);\n if (\n !isSameLockSnapshot({\n beforeRaw: lockRaw,\n beforePid: pid,\n afterRaw: latestLockRaw,\n afterPid: latestPid,\n })\n ) {\n return false;\n }\n\n await rm(lockPath, { force: true }).catch((error: unknown) => {\n if (getErrorCode(error) === \"ENOENT\") {\n return undefined;\n }\n throw error;\n });\n return true;\n}\n\nfunction parseLockMeta(value: string): unknown {\n try {\n return JSON.parse(value);\n } catch {\n return null;\n }\n}\n\nfunction resolveLockPid(meta: unknown): number | null {\n if (!meta || typeof meta !== \"object\") {\n return null;\n }\n const pid = (meta as Record<string, unknown>).pid;\n return typeof pid === \"number\" && Number.isInteger(pid) && pid > 0\n ? pid\n : null;\n}\n\nfunction isPidAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n return getErrorCode(error) !== \"ESRCH\";\n }\n}\n\nfunction getErrorCode(error: unknown): string | undefined {\n if (!error || typeof error !== \"object\") {\n return undefined;\n }\n const code = (error as { code?: unknown }).code;\n return typeof code === \"string\" ? code : undefined;\n}\n\nfunction isSameLockSnapshot(input: {\n beforeRaw: string;\n beforePid: number | null;\n afterRaw: string;\n afterPid: number | null;\n}): boolean {\n if (input.beforeRaw !== input.afterRaw) {\n return false;\n }\n return input.beforePid === input.afterPid;\n}\n","import { randomUUID, verify } from \"node:crypto\";\nimport { mkdir, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport {\n OFFICIAL_CLI_SKILL_CONTRACT,\n OFFICIAL_CLI_SKILL_MAX_BYTES,\n OFFICIAL_CLI_SKILL_PUBLIC_KEY,\n type OfficialCliSkillPayload,\n type OfficialCliSkillRelease,\n officialCliSkillChannelSchema,\n officialCliSkillPayloadSchema,\n officialCliSkillReleaseSchema,\n} from \"@openmeld/schemas\";\nimport { openMeldRootDir, resolveOpenMeldEnvPreset } from \"../config/paths\";\nimport { compareSemver } from \"../config/version-state\";\nimport { OPENMELD_VERSION } from \"../runtime/version\";\nimport { loadBundledSkillAssets } from \"./bundled-assets\";\nimport { withSkillsInstallLock } from \"./install-lock\";\n\nconst CACHE_FILE = \"official-cli-skill.json\";\n\nexport function verifyOfficialSkillRelease(value: unknown): {\n release: OfficialCliSkillRelease;\n payload: OfficialCliSkillPayload;\n} {\n const envelope = officialCliSkillReleaseSchema.safeParse(value);\n if (\n !(\n envelope.success &&\n verify(\n null,\n Buffer.from(envelope.data.payload),\n OFFICIAL_CLI_SKILL_PUBLIC_KEY,\n Buffer.from(envelope.data.signature, \"base64\")\n )\n )\n ) {\n throw new Error(\"OpenMeld Skill signature is invalid\");\n }\n const payload = officialCliSkillPayloadSchema.safeParse(\n JSON.parse(envelope.data.payload)\n );\n if (!payload.success) {\n throw new Error(\"OpenMeld Skill content is invalid\");\n }\n return { release: envelope.data, payload: payload.data };\n}\n\nfunction isCompatible(\n payload: OfficialCliSkillPayload,\n cliVersion = OPENMELD_VERSION\n): boolean {\n return (\n payload.contractVersion === OFFICIAL_CLI_SKILL_CONTRACT &&\n compareSemver(cliVersion, payload.minimumCliVersion) >= 0\n );\n}\n\nexport function selectOfficialSkillRelease(\n value: unknown,\n cliVersion = OPENMELD_VERSION\n) {\n const channel = officialCliSkillChannelSchema.safeParse(value);\n if (!channel.success) {\n throw new Error(\"OpenMeld Skill channel is invalid\");\n }\n return (\n channel.data.releases\n .map(verifyOfficialSkillRelease)\n .filter(({ payload }) => isCompatible(payload, cliVersion))\n .sort((a, b) => b.payload.revision - a.payload.revision)[0] ?? null\n );\n}\n\nasync function readCachedRelease() {\n const raw = await readFile(join(openMeldRootDir(), CACHE_FILE), \"utf8\").catch(\n (error: NodeJS.ErrnoException) => {\n if (error.code === \"ENOENT\") {\n return null;\n }\n throw error;\n }\n );\n if (!raw) {\n return null;\n }\n try {\n return verifyOfficialSkillRelease(JSON.parse(raw));\n } catch (error) {\n process.stderr.write(\n `[openmeld] cached Skill rejected: ${error instanceof Error ? error.message : String(error)}\\n`\n );\n return null;\n }\n}\n\n// Local-only selection is shared by install, prompt, and component status.\nexport async function loadSelectedSkillAssets() {\n const cached = await readCachedRelease();\n if (!(cached && isCompatible(cached.payload))) {\n return {\n assets: await loadBundledSkillAssets(),\n version: OPENMELD_VERSION,\n };\n }\n return {\n assets: [\n ...cached.payload.files.map((file) => ({\n relativePath: `openmeld-cli/${file.path}`,\n content: Buffer.from(file.content),\n })),\n ].sort((a, b) => a.relativePath.localeCompare(b.relativePath)),\n version: `skill-r${cached.payload.revision}`,\n contentRelease: {\n revision: cached.payload.revision,\n minimumCliVersion: cached.payload.minimumCliVersion,\n },\n };\n}\n\nexport async function readSelectedSkillDocument(path: string): Promise<string> {\n const { assets } = await loadSelectedSkillAssets();\n const asset = assets.find(\n (file) => file.relativePath === `openmeld-cli/${path}`\n );\n if (!asset) {\n throw new Error(`OpenMeld Skill document is missing: ${path}`);\n }\n return asset.content.toString(\"utf8\");\n}\n\nexport function resolveOfficialSkillChannelUrl(): string | null {\n if (resolveOpenMeldEnvPreset() === \"prod\") {\n return \"https://openmeld.ai/skills/openmeld-cli/channel.json\";\n }\n const override = process.env.OPENMELD_CLI_SKILL_CHANNEL_URL;\n if (!(override && process.env.OPENMELD_HOME)) {\n return null;\n }\n const url = new URL(override);\n if (\n url.protocol !== \"http:\" ||\n ![\"localhost\", \"127.0.0.1\", \"[::1]\"].includes(url.hostname) ||\n url.username ||\n url.password\n ) {\n throw new Error(\"Isolated Skill updates require an explicit localhost URL\");\n }\n return url.href;\n}\n\nexport async function downloadOfficialSkillUpdate(): Promise<\n \"updated\" | \"current\" | \"incompatible\" | \"lane_isolated\"\n> {\n const url = resolveOfficialSkillChannelUrl();\n if (!url) {\n return \"lane_isolated\";\n }\n const response = await fetch(url, {\n signal: AbortSignal.timeout(5000),\n redirect: \"error\",\n });\n if (!(response.ok && response.body)) {\n throw new Error(`OpenMeld Skill download failed (HTTP ${response.status})`);\n }\n const chunks: Uint8Array[] = [];\n let size = 0;\n for await (const chunk of response.body) {\n size += chunk.byteLength;\n if (size > OFFICIAL_CLI_SKILL_MAX_BYTES) {\n throw new Error(\"OpenMeld Skill download exceeds the size limit\");\n }\n chunks.push(chunk);\n }\n const selected = selectOfficialSkillRelease(\n JSON.parse(Buffer.concat(chunks).toString(\"utf8\"))\n );\n if (!selected) {\n return \"incompatible\";\n }\n return withSkillsInstallLock(async () => {\n const cached = await readCachedRelease();\n if (cached && cached.payload.revision >= selected.payload.revision) {\n return \"current\";\n }\n await mkdir(openMeldRootDir(), { recursive: true });\n const cache = join(openMeldRootDir(), CACHE_FILE);\n const staged = `${cache}.${randomUUID()}.tmp`;\n try {\n await writeFile(staged, JSON.stringify(selected.release), {\n flag: \"wx\",\n mode: 0o600,\n });\n await rename(staged, cache);\n } finally {\n await rm(staged, { force: true });\n }\n return \"updated\";\n });\n}\n","import { randomUUID } from \"node:crypto\";\nimport { lstat, readFile, readlink, rename, rm } from \"node:fs/promises\";\nimport { basename, dirname, join, resolve } from \"node:path\";\n\n// Callers hold the skills install lock. Recover a process exit between renames.\nexport async function recoverSkillReplacement(target: string): Promise<void> {\n const previous = join(\n dirname(target),\n `.${basename(target)}.openmeld-previous`\n );\n if (!(await exists(previous))) {\n return;\n }\n if (!(await isManagedReplacement(previous, basename(target)))) {\n throw new Error(\"OpenMeld Skill backup conflicts with an unmanaged path\");\n }\n if (await exists(target)) {\n if (!(await isManagedReplacement(target, basename(target)))) {\n throw new Error(\"OpenMeld Skill recovery would affect an unmanaged path\");\n }\n await rm(previous, { recursive: true, force: true });\n } else {\n await rename(previous, target);\n }\n}\n\nexport async function replaceSkillDirectory(\n target: string,\n prepare: (staged: string) => Promise<void>\n): Promise<void> {\n await recoverSkillReplacement(target);\n const staged = join(\n dirname(target),\n `.${basename(target)}.openmeld-staged-${randomUUID()}`\n );\n const previous = join(\n dirname(target),\n `.${basename(target)}.openmeld-previous`\n );\n try {\n await prepare(staged);\n const hadPrevious = await exists(target);\n if (hadPrevious) {\n await rename(target, previous);\n }\n try {\n await rename(staged, target);\n } catch (error) {\n if (hadPrevious) {\n await rename(previous, target);\n }\n throw error;\n }\n // A cleanup failure must not roll back a committed replacement.\n await rm(previous, { recursive: true, force: true }).catch(() => undefined);\n } finally {\n await rm(staged, { recursive: true, force: true }).catch(() => undefined);\n }\n}\n\nasync function isManagedReplacement(\n path: string,\n skillId: string\n): Promise<boolean> {\n const raw = await readFile(join(path, \".openmeld-skill.json\"), \"utf8\").catch(\n () => null\n );\n if (raw) {\n try {\n const marker = JSON.parse(raw);\n return marker.managedBy === \"openmeld\" && marker.skillId === skillId;\n } catch {\n return false;\n }\n }\n // Legacy dangling links have no readable marker and carry no directory data.\n if ((await lstat(path)).isSymbolicLink()) {\n const destination = resolve(dirname(path), await readlink(path));\n return basename(destination) === skillId && !(await exists(destination));\n }\n return false;\n}\n\nfunction exists(path: string): Promise<boolean> {\n return lstat(path).then(\n () => true,\n (error: NodeJS.ErrnoException) => {\n if (error.code === \"ENOENT\") {\n return false;\n }\n throw error;\n }\n );\n}\n","import { lstat, mkdir, readdir, readFile, writeFile } from \"node:fs/promises\";\nimport path, { dirname, join, relative } from \"node:path\";\nimport { skillsDir } from \"../config/paths\";\nimport {\n type BundledSkillAsset,\n hashBundledSkillAssets,\n} from \"./bundled-assets\";\nimport { sortBundledSkillAssets } from \"./bundled-assets-fs\";\nimport { computeDirectoryContentHash } from \"./content-hash\";\nimport { withSkillsInstallLock } from \"./install-lock\";\nimport { loadSelectedSkillAssets } from \"./official-release\";\nimport {\n recoverSkillReplacement,\n replaceSkillDirectory,\n} from \"./replace-directory\";\n\nexport const OPENMELD_SKILL_MARKER_FILE = \".openmeld-skill.json\";\n\nexport type OpenMeldSkillMarker = {\n managedBy: \"openmeld\";\n skillId: string;\n mode: \"source\" | \"symlink\" | \"copy\";\n contentHash?: string;\n version?: string;\n updatedAt: string;\n};\n\nexport type LocalSkill = {\n id: string;\n name: string;\n absolutePath: string;\n relativePath: string;\n contentHash?: string;\n version?: string;\n};\n\nconst OPENMELD_CLI_SKILL_FILE = \"SKILL.md\";\nconst SKILL_NAME_REGEX = /^name:\\s*(.+)$/m;\n\nexport function ensureLocalSkills(): Promise<LocalSkill[]> {\n return withSkillsInstallLock(ensureLocalSkillsLocked);\n}\n\nasync function ensureLocalSkillsLocked(): Promise<LocalSkill[]> {\n const storePath = skillsDir();\n await mkdir(storePath, { recursive: true });\n\n const { assets, version: bundledVersion } = await loadSelectedSkillAssets();\n if (assets.length === 0) {\n return listLocalSkills();\n }\n const skillGroups = groupAssetsBySkill(assets);\n\n for (const [skillId, skillAssets] of skillGroups) {\n const targetDir = join(storePath, skillId);\n await recoverSkillReplacement(targetDir);\n const sourceContentHash = hashBundledSkillAssets(skillAssets);\n const existingMarker = await readOpenMeldSkillMarker(targetDir);\n const existing = await lstat(targetDir).catch(\n (error: NodeJS.ErrnoException) => {\n if (error.code === \"ENOENT\") {\n return null;\n }\n throw error;\n }\n );\n if (existing && (!existingMarker || existing.isSymbolicLink())) {\n throw new Error(\n `OpenMeld Skill source conflicts with an unmanaged path: ${targetDir}`\n );\n }\n const isUpToDate =\n existingMarker?.managedBy === \"openmeld\" &&\n existingMarker.skillId === skillId &&\n existingMarker.mode === \"source\" &&\n existingMarker.contentHash === sourceContentHash &&\n existingMarker.version === bundledVersion &&\n (await computeDirectoryContentHash({\n rootDir: targetDir,\n ignoredNames: [OPENMELD_SKILL_MARKER_FILE],\n })) === sourceContentHash;\n if (isUpToDate) {\n continue;\n }\n\n await replaceSkillDirectory(targetDir, async (stagedDir) => {\n for (const asset of skillAssets) {\n const filePath = join(stagedDir, asset.relativePath);\n await mkdir(dirname(filePath), { recursive: true });\n await writeFile(filePath, asset.content);\n }\n await writeOpenMeldSkillMarker({\n skillDir: stagedDir,\n skillId,\n mode: \"source\",\n contentHash: sourceContentHash,\n version: bundledVersion,\n });\n });\n }\n\n return listLocalSkills();\n}\n\n// Group loaded assets by their first path segment (the skill id). Top-level\n// files (e.g. skills/README.md) belong to no skill and are dropped, and a group\n// without a SKILL.md is dropped too — matching the previous \"only install skill\n// directories that contain SKILL.md\" behavior. Each group's paths are made\n// skill-relative and sorted so the per-skill hash matches the source tree.\nfunction groupAssetsBySkill(\n assets: BundledSkillAsset[]\n): Map<string, BundledSkillAsset[]> {\n const groups = new Map<string, BundledSkillAsset[]>();\n for (const asset of assets) {\n const slashIndex = asset.relativePath.indexOf(\"/\");\n if (slashIndex < 0) {\n continue;\n }\n const skillId = asset.relativePath.slice(0, slashIndex);\n const skillRelativePath = asset.relativePath.slice(slashIndex + 1);\n const group = groups.get(skillId) ?? [];\n group.push({ relativePath: skillRelativePath, content: asset.content });\n groups.set(skillId, group);\n }\n for (const [skillId, group] of [...groups.entries()]) {\n if (group.some((asset) => asset.relativePath === OPENMELD_CLI_SKILL_FILE)) {\n groups.set(skillId, sortBundledSkillAssets(group));\n } else {\n groups.delete(skillId);\n }\n }\n return groups;\n}\n\nexport async function listLocalSkills(): Promise<LocalSkill[]> {\n const storePath = skillsDir();\n const skillDirs = await discoverSkillDirs(storePath, 0, 6);\n const skills: LocalSkill[] = [];\n\n for (const skillDir of skillDirs) {\n const skillFile = join(skillDir, \"SKILL.md\");\n const raw = await readFile(skillFile, \"utf8\").catch(() => \"\");\n if (!raw) {\n continue;\n }\n const skillId = path.basename(skillDir);\n const skillName = readSkillName(raw) ?? skillId;\n const marker = await readOpenMeldSkillMarker(skillDir);\n skills.push({\n id: skillId,\n name: skillName,\n absolutePath: skillDir,\n relativePath: relative(storePath, skillDir) || skillId,\n ...(marker?.contentHash ? { contentHash: marker.contentHash } : {}),\n ...(marker?.version ? { version: marker.version } : {}),\n });\n }\n\n skills.sort((a, b) => a.relativePath.localeCompare(b.relativePath));\n return skills;\n}\n\nexport async function writeOpenMeldSkillMarker(input: {\n skillDir: string;\n skillId: string;\n mode: \"source\" | \"symlink\" | \"copy\";\n contentHash?: string;\n version?: string;\n}): Promise<void> {\n const markerPath = join(input.skillDir, OPENMELD_SKILL_MARKER_FILE);\n const marker: OpenMeldSkillMarker = {\n managedBy: \"openmeld\",\n skillId: input.skillId,\n mode: input.mode,\n ...(input.contentHash ? { contentHash: input.contentHash } : {}),\n ...(input.version ? { version: input.version } : {}),\n updatedAt: new Date().toISOString(),\n };\n await writeFile(markerPath, `${JSON.stringify(marker, null, 2)}\\n`, \"utf8\");\n}\n\nexport async function isOpenMeldManagedSkillDir(\n skillDir: string\n): Promise<boolean> {\n const marker = await readOpenMeldSkillMarker(skillDir);\n return marker?.managedBy === \"openmeld\";\n}\n\nexport async function readOpenMeldSkillMarker(\n skillDir: string\n): Promise<OpenMeldSkillMarker | null> {\n const markerPath = join(skillDir, OPENMELD_SKILL_MARKER_FILE);\n const raw = await readFile(markerPath, \"utf8\").catch(() => null);\n if (!raw) {\n return null;\n }\n try {\n const parsed = JSON.parse(raw) as Partial<OpenMeldSkillMarker>;\n if (parsed.managedBy !== \"openmeld\") {\n return null;\n }\n if (\n typeof parsed.skillId !== \"string\" ||\n parsed.skillId.trim().length === 0\n ) {\n return null;\n }\n if (\n parsed.mode !== \"source\" &&\n parsed.mode !== \"symlink\" &&\n parsed.mode !== \"copy\"\n ) {\n return null;\n }\n return {\n managedBy: \"openmeld\",\n skillId: parsed.skillId.trim(),\n mode: parsed.mode,\n ...(typeof parsed.contentHash === \"string\" &&\n parsed.contentHash.trim().length > 0\n ? { contentHash: parsed.contentHash.trim() }\n : {}),\n ...(typeof parsed.version === \"string\" && parsed.version.trim().length > 0\n ? { version: parsed.version.trim() }\n : {}),\n updatedAt:\n typeof parsed.updatedAt === \"string\" &&\n parsed.updatedAt.trim().length > 0\n ? parsed.updatedAt\n : new Date().toISOString(),\n };\n } catch {\n return null;\n }\n}\n\nasync function discoverSkillDirs(\n dir: string,\n depth: number,\n maxDepth: number\n): Promise<string[]> {\n if (depth > maxDepth) {\n return [];\n }\n\n const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);\n if (entries.length === 0) {\n return [];\n }\n\n const hasSkill = entries.some(\n (entry) => entry.isFile() && entry.name === \"SKILL.md\"\n );\n if (hasSkill) {\n return [dir];\n }\n\n const nested = await Promise.all(\n entries\n .filter(\n (entry) => entry.isDirectory() && !entry.name.includes(\".openmeld-\")\n )\n .map((entry) =>\n discoverSkillDirs(join(dir, entry.name), depth + 1, maxDepth)\n )\n );\n\n return nested.flat();\n}\n\nfunction readSkillName(rawSkillFile: string): string | undefined {\n const match = rawSkillFile.match(SKILL_NAME_REGEX);\n if (!match) {\n return undefined;\n }\n const candidate = match[1]?.trim();\n return candidate && candidate.length > 0 ? candidate : undefined;\n}\n","import { lstat, readlink } from \"node:fs/promises\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport { computeDirectoryContentHash } from \"./content-hash\";\nimport type { SkillsInstallTarget } from \"./installer\";\nimport {\n type LocalSkill,\n type OpenMeldSkillMarker,\n readOpenMeldSkillMarker,\n} from \"./store\";\n\nexport type SkillInstallState =\n | \"missing\"\n | \"outdated\"\n | \"up_to_date\"\n | \"external_conflict\";\n\nexport type SkillInstallStateResult = {\n targetId: string;\n targetDir: string;\n targetType: \"agent\" | \"custom\";\n skillId: string;\n skillDir: string;\n state: SkillInstallState;\n targetMode?: OpenMeldSkillMarker[\"mode\"];\n sourceHash?: string;\n targetHash?: string;\n sourceVersion?: string;\n targetVersion?: string;\n reason?: string;\n};\n\ntype SourceSnapshot = {\n hash?: string;\n version?: string;\n};\n\ntype TargetSnapshot =\n | {\n exists: false;\n }\n | {\n exists: true;\n isSymlink: boolean;\n marker: OpenMeldSkillMarker | null;\n symlinkTargetPath: string;\n destinationExists: boolean;\n };\n\nexport async function resolveSkillsInstallStates(input: {\n skills: LocalSkill[];\n targets: SkillsInstallTarget[];\n}): Promise<SkillInstallStateResult[]> {\n const states: SkillInstallStateResult[] = [];\n for (const target of input.targets) {\n for (const skill of input.skills) {\n states.push(\n await resolveSkillInstallStateForTarget({\n skill,\n target,\n })\n );\n }\n }\n return states;\n}\n\nexport async function resolveSkillInstallStateForTarget(input: {\n skill: LocalSkill;\n target: SkillsInstallTarget;\n}): Promise<SkillInstallStateResult> {\n const base = createBaseResult(input);\n const source = await resolveSourceSnapshot(input.skill);\n const target = await resolveTargetSnapshot(base.skillDir);\n\n if (!target.exists) {\n return createStateResult({\n base,\n source,\n state: \"missing\",\n });\n }\n\n if (target.marker?.managedBy !== \"openmeld\") {\n if (\n isLegacyOpenMeldSkillSymlink({\n skillId: input.skill.id,\n target,\n })\n ) {\n return createStateResult({\n base,\n source,\n state: \"outdated\",\n targetMode: \"symlink\",\n reason: \"legacy OpenMeld skill link found; update required\",\n });\n }\n\n return createStateResult({\n base,\n source,\n state: \"external_conflict\",\n reason:\n \"existing non-OpenMeld skill detected; skipped to avoid overwrite\",\n });\n }\n\n if (!target.isSymlink && target.marker.contentHash) {\n const entry = await lstat(join(base.skillDir, \"SKILL.md\")).catch(\n () => null\n );\n if (!entry?.isFile()) {\n return createStateResult({\n base,\n source,\n state: \"outdated\",\n targetMarker: target.marker,\n reason: \"OpenMeld Skill entry is missing\",\n });\n }\n const actualHash = await computeDirectoryContentHash({\n rootDir: base.skillDir,\n ignoredNames: [\".openmeld-skill.json\"],\n });\n if (actualHash !== target.marker.contentHash) {\n return createStateResult({\n base,\n source,\n state: \"external_conflict\",\n targetMarker: target.marker,\n reason: \"OpenMeld Skill files were modified locally; kept your changes\",\n });\n }\n }\n\n const upToDate = isUpToDate({\n source,\n targetMarker: target.marker,\n isSymlink: target.isSymlink,\n symlinkTargetPath: target.symlinkTargetPath,\n sourceSkillDir: input.skill.absolutePath,\n });\n if (upToDate) {\n return createStateResult({\n base,\n source,\n targetMarker: target.marker,\n state: \"up_to_date\",\n reason: \"already up-to-date\",\n });\n }\n\n return createStateResult({\n base,\n source,\n targetMarker: target.marker,\n state: \"outdated\",\n reason: target.isSymlink\n ? \"OpenMeld skill link points to a different OpenMeld skills store; update required\"\n : \"OpenMeld skill content changed; update required\",\n });\n}\n\nfunction createBaseResult(input: {\n skill: LocalSkill;\n target: SkillsInstallTarget;\n}): Omit<SkillInstallStateResult, \"state\"> {\n const skillDir = join(input.target.dir, input.skill.id);\n return {\n targetId: input.target.id,\n targetDir: input.target.dir,\n targetType: input.target.type,\n skillId: input.skill.id,\n skillDir,\n };\n}\n\nasync function resolveSourceSnapshot(\n skill: LocalSkill\n): Promise<SourceSnapshot> {\n const sourceMarker = await readOpenMeldSkillMarker(skill.absolutePath);\n return {\n ...((skill.contentHash ?? sourceMarker?.contentHash)\n ? { hash: skill.contentHash ?? sourceMarker?.contentHash }\n : {}),\n ...((skill.version ?? sourceMarker?.version)\n ? { version: skill.version ?? sourceMarker?.version }\n : {}),\n };\n}\n\nasync function resolveTargetSnapshot(\n skillDir: string\n): Promise<TargetSnapshot> {\n const stats = await lstat(skillDir).catch(() => null);\n if (!stats) {\n return { exists: false };\n }\n\n let marker = await readOpenMeldSkillMarker(skillDir);\n let symlinkTargetPath = \"\";\n if (stats.isSymbolicLink()) {\n symlinkTargetPath = await resolveSymlinkTarget(skillDir).catch(() => \"\");\n if (!marker && symlinkTargetPath) {\n marker = await readOpenMeldSkillMarker(symlinkTargetPath);\n }\n }\n\n return {\n exists: true,\n isSymlink: stats.isSymbolicLink(),\n marker,\n symlinkTargetPath,\n destinationExists: symlinkTargetPath\n ? Boolean(await lstat(symlinkTargetPath).catch(() => null))\n : true,\n };\n}\n\nfunction isLegacyOpenMeldSkillSymlink(input: {\n skillId: string;\n target: Extract<TargetSnapshot, { exists: true }>;\n}): boolean {\n if (\n !(input.target.isSymlink && input.target.symlinkTargetPath) ||\n input.target.destinationExists\n ) {\n return false;\n }\n\n return basename(input.target.symlinkTargetPath) === input.skillId;\n}\n\nfunction isUpToDate(input: {\n source: SourceSnapshot;\n targetMarker: OpenMeldSkillMarker;\n isSymlink: boolean;\n symlinkTargetPath: string;\n sourceSkillDir: string;\n}): boolean {\n if (input.isSymlink) {\n // A symlinked target mirrors whatever store it points at, and its marker is\n // read through the link, so a matching hash/version only proves that other\n // store's state. The link is current only when it resolves to this store's\n // skill directory; anything else must be reinstalled before the foreign\n // store drifts or disappears.\n return (\n input.symlinkTargetPath.length > 0 &&\n pathsEqual(input.symlinkTargetPath, input.sourceSkillDir)\n );\n }\n return hasMatchingHashAndVersion(input.source, input.targetMarker);\n}\n\nfunction hasMatchingHashAndVersion(\n source: SourceSnapshot,\n targetMarker: OpenMeldSkillMarker\n): boolean {\n if (\n !(\n source.hash &&\n targetMarker.contentHash &&\n source.hash === targetMarker.contentHash\n )\n ) {\n return false;\n }\n return (\n !(source.version && targetMarker.version) ||\n source.version === targetMarker.version\n );\n}\n\nfunction createStateResult(input: {\n base: Omit<SkillInstallStateResult, \"state\">;\n source: SourceSnapshot;\n state: SkillInstallState;\n targetMode?: OpenMeldSkillMarker[\"mode\"];\n targetMarker?: OpenMeldSkillMarker;\n reason?: string;\n}): SkillInstallStateResult {\n return {\n ...input.base,\n state: input.state,\n ...(input.source.hash ? { sourceHash: input.source.hash } : {}),\n ...(input.source.version ? { sourceVersion: input.source.version } : {}),\n ...(input.targetMarker?.contentHash\n ? { targetHash: input.targetMarker.contentHash }\n : {}),\n ...(input.targetMarker?.mode\n ? { targetMode: input.targetMarker.mode }\n : {}),\n ...(input.targetMode ? { targetMode: input.targetMode } : {}),\n ...(input.targetMarker?.version\n ? { targetVersion: input.targetMarker.version }\n : {}),\n ...(input.reason ? { reason: input.reason } : {}),\n };\n}\n\nasync function resolveSymlinkTarget(linkPath: string): Promise<string> {\n const target = await readlink(linkPath);\n return resolve(dirname(linkPath), target);\n}\n\nfunction pathsEqual(left: string, right: string): boolean {\n return resolve(left) === resolve(right);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"state-GxF_KAM1.js","names":["getErrorCode"],"sources":["../../../packages/schemas/dist/official-cli-skill.js","../src/skills/bundled.ts","../src/skills/bundled-assets-fs.ts","../src/skills/bundled-assets.ts","../src/skills/content-hash.ts","../src/skills/install-lock.ts","../src/skills/official-release.ts","../src/skills/replace-directory.ts","../src/skills/store.ts","../src/skills/state.ts"],"sourcesContent":["import * as z$1 from \"zod/v4\";\n//#region src/official-cli-skill.ts\nconst OFFICIAL_CLI_SKILL_CONTRACT = \"openmeld-skills-contract-2026-09-explicit-space-recipients-v1\";\nconst OFFICIAL_CLI_SKILL_URL = \"https://openmeld.ai/skills/openmeld-cli/SKILL.md\";\nconst OFFICIAL_CLI_SKILL_MAX_BYTES = 1048576;\nconst OFFICIAL_CLI_SKILL_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAFZjFHrQ/QLsJQpHkAbKBRG57fEazhm7zc0dMa54ilWQ=\n-----END PUBLIC KEY-----\n`;\nconst officialCliSkillPayloadSchema = z$1.object({\n\tschemaVersion: z$1.literal(1),\n\trevision: z$1.number().int().positive(),\n\tminimumCliVersion: z$1.string().regex(/^\\d+\\.\\d+\\.\\d+$/),\n\tcontractVersion: z$1.string().min(1).max(128),\n\tfiles: z$1.array(z$1.object({\n\t\tpath: z$1.string().regex(/^(?:SKILL\\.md|(?:playbooks|references)\\/[a-z0-9-]+\\.md)$/),\n\t\tcontent: z$1.string().min(1).max(131072)\n\t}).strict()).min(1).max(32)\n}).strict().superRefine((value, context) => {\n\tconst paths = value.files.map((file) => file.path);\n\tif (!paths.includes(\"SKILL.md\") || new Set(paths).size !== paths.length) context.addIssue({\n\t\tcode: \"custom\",\n\t\tmessage: \"Skill entry is required and paths must be unique\"\n\t});\n});\nconst officialCliSkillReleaseSchema = z$1.object({\n\tpayload: z$1.string().min(1).max(524288),\n\tsignature: z$1.string().regex(/^[A-Za-z0-9+/]{86}==$/)\n}).strict();\nconst officialCliSkillChannelSchema = z$1.object({\n\tschemaVersion: z$1.literal(1),\n\treleases: z$1.array(officialCliSkillReleaseSchema).min(1).max(16)\n}).strict();\n//#endregion\nexport { OFFICIAL_CLI_SKILL_CONTRACT, OFFICIAL_CLI_SKILL_MAX_BYTES, OFFICIAL_CLI_SKILL_PUBLIC_KEY, OFFICIAL_CLI_SKILL_URL, officialCliSkillChannelSchema, officialCliSkillPayloadSchema, officialCliSkillReleaseSchema };\n\n//# sourceMappingURL=official-cli-skill.js.map","import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst CLI_PACKAGE_JSON = \"package.json\";\n\nexport type BundledSkillsLocation = {\n cliRootDir: string;\n skillsRootDir: string;\n};\n\n/**\n * Locate the on-disk bundled skills directory for the npm distribution by\n * walking up from this module to the CLI package root (a directory that has\n * both package.json and skills/). Returns null under the binary distribution,\n * where import.meta.url is a virtual path and the skills are embedded instead —\n * callers in that mode go through bundled-assets.ts, not this function.\n */\nexport function resolveBundledSkillsLocation(): BundledSkillsLocation | null {\n const moduleDir = path.dirname(fileURLToPath(import.meta.url));\n const cliRootDir = resolveCliRootDir(moduleDir);\n if (!cliRootDir) {\n return null;\n }\n return {\n cliRootDir,\n skillsRootDir: path.join(cliRootDir, \"skills\"),\n };\n}\n\nfunction resolveCliRootDir(fromDir: string): string | null {\n let current = fromDir;\n for (;;) {\n const packageJsonPath = path.join(current, CLI_PACKAGE_JSON);\n const hasPackageJson = existsSync(packageJsonPath);\n const hasSkillsDir = existsSync(path.join(current, \"skills\"));\n if (hasPackageJson && hasSkillsDir) {\n return current;\n }\n const parent = path.dirname(current);\n if (parent === current) {\n return null;\n }\n current = parent;\n }\n}\n","import { readdir, readFile } from \"node:fs/promises\";\nimport { join, relative } from \"node:path\";\nimport { resolveBundledSkillsLocation } from \"./bundled\";\nimport type { BundledSkillAsset } from \"./bundled-assets\";\n\n/**\n * npm-distribution source: read the bundled skills from the on-disk `skills/`\n * directory next to the CLI package. Assets are sorted by relative path so the\n * order (and therefore any content hash computed from them) is stable and\n * matches the embedded distribution.\n */\nexport async function loadFsBundledSkillAssets(): Promise<BundledSkillAsset[]> {\n const location = resolveBundledSkillsLocation();\n if (!location) {\n throw new Error(\"unable to resolve bundled OpenMeld skills directory\");\n }\n const assets = await collectSkillAssets(\n location.skillsRootDir,\n location.skillsRootDir\n );\n return sortBundledSkillAssets(assets);\n}\n\nexport function sortBundledSkillAssets(\n assets: BundledSkillAsset[]\n): BundledSkillAsset[] {\n return [...assets].sort((left, right) =>\n left.relativePath.localeCompare(right.relativePath)\n );\n}\n\nasync function collectSkillAssets(\n dir: string,\n rootDir: string\n): Promise<BundledSkillAsset[]> {\n const entries = await readdir(dir, { withFileTypes: true });\n const assets: BundledSkillAsset[] = [];\n for (const entry of entries) {\n const absolutePath = join(dir, entry.name);\n if (entry.isDirectory()) {\n assets.push(...(await collectSkillAssets(absolutePath, rootDir)));\n continue;\n }\n if (!entry.isFile()) {\n continue;\n }\n assets.push({\n relativePath: toPosixRelativePath(relative(rootDir, absolutePath)),\n content: await readFile(absolutePath),\n });\n }\n return assets;\n}\n\nfunction toPosixRelativePath(value: string): string {\n return value.split(\"\\\\\").join(\"/\");\n}\n","import { createHash } from \"node:crypto\";\nimport { isBinaryDistribution } from \"../runtime/distribution\";\nimport { loadFsBundledSkillAssets } from \"./bundled-assets-fs\";\n\n/**\n * One bundled skill file, addressed by its POSIX path relative to the skills/\n * root (e.g. \"README.md\", \"openmeld-cli/SKILL.md\"). This is the single shape\n * both distribution forms produce, so downstream skill install and bundle-hash\n * logic never branches on how the files were sourced.\n */\nexport type BundledSkillAsset = {\n relativePath: string;\n content: Buffer;\n};\n\n/**\n * Load the OpenMeld-managed skill files that ship with this CLI build.\n *\n * - npm distribution: read from the on-disk `skills/` directory.\n * - binary distribution: read from files embedded into the single binary at\n * compile time. The embedded module is a Bun-only island resolved only by\n * `bun build --compile`; the npm build never reaches this branch and marks\n * the module external, so its `with { type: \"file\" }` imports are never\n * parsed by tsdown.\n */\nexport async function loadBundledSkillAssets(): Promise<BundledSkillAsset[]> {\n if (isBinaryDistribution()) {\n const embedded = await import(\"./bundled-assets-embedded\");\n return embedded.loadEmbeddedBundledSkillAssets();\n }\n return loadFsBundledSkillAssets();\n}\n\n/**\n * Content hash over an ordered list of skill assets. Byte-for-byte compatible\n * with `computeDirectoryContentHash` (same `file:<relativePath>\\n<content>\\n`\n * framing) so the embedded and on-disk sources produce identical hashes as long\n * as `assets` is sorted by relative path (as `loadBundledSkillAssets` returns\n * it). This is the single skills-hash algorithm for both distribution forms.\n */\nexport function hashBundledSkillAssets(assets: BundledSkillAsset[]): string {\n const hash = createHash(\"sha256\");\n for (const asset of assets) {\n hash.update(`file:${asset.relativePath}\\n`);\n hash.update(asset.content);\n hash.update(\"\\n\");\n }\n return hash.digest(\"hex\");\n}\n\nconst OPENMELD_CLI_SKILL_ID = \"openmeld-cli\";\nconst OPENMELD_CLI_SKILL_FILE = \"SKILL.md\";\n\n/**\n * Read one OpenMeld CLI skill document by its path relative to the skill root\n * (e.g. \"SKILL.md\", \"references/commands.md\"). Works in both distribution forms\n * via loadBundledSkillAssets, so `openmeld prompt --raw` renders the bundled\n * markdown from the embedded binary too.\n */\nexport async function readBundledOpenMeldCliSkillDocumentByPath(\n skillRelativePath: string\n): Promise<string> {\n const targetPath = `${OPENMELD_CLI_SKILL_ID}/${skillRelativePath}`;\n const assets = await loadBundledSkillAssets();\n const asset = assets.find((item) => item.relativePath === targetPath);\n if (!asset) {\n throw new Error(\n `bundled OpenMeld CLI skill document is missing: ${skillRelativePath}`\n );\n }\n return asset.content.toString(\"utf8\");\n}\n\nexport function readBundledOpenMeldCliSkillDocument(): Promise<string> {\n return readBundledOpenMeldCliSkillDocumentByPath(OPENMELD_CLI_SKILL_FILE);\n}\n","import { createHash } from \"node:crypto\";\nimport { readdir, readFile } from \"node:fs/promises\";\nimport { join, relative } from \"node:path\";\n\nexport async function computeDirectoryContentHash(input: {\n rootDir: string;\n ignoredNames?: string[];\n}): Promise<string> {\n const ignoredNames = new Set(input.ignoredNames ?? []);\n const files = await collectFiles({\n dir: input.rootDir,\n rootDir: input.rootDir,\n ignoredNames,\n });\n const hash = createHash(\"sha256\");\n for (const file of files) {\n hash.update(`file:${file.relativePath}\\n`);\n hash.update(file.content);\n hash.update(\"\\n\");\n }\n return hash.digest(\"hex\");\n}\n\nasync function collectFiles(input: {\n dir: string;\n rootDir: string;\n ignoredNames: Set<string>;\n}): Promise<Array<{ relativePath: string; content: Buffer }>> {\n const entries = await readdir(input.dir, { withFileTypes: true }).catch(\n (error: unknown) => {\n if (getErrorCode(error) === \"ENOENT\") {\n return [];\n }\n warnDirectoryReadError(input.dir, error);\n throw error;\n }\n );\n entries.sort((a, b) => a.name.localeCompare(b.name));\n\n const files: Array<{ relativePath: string; content: Buffer }> = [];\n for (const entry of entries) {\n if (input.ignoredNames.has(entry.name)) {\n continue;\n }\n const absolutePath = join(input.dir, entry.name);\n if (entry.isDirectory()) {\n files.push(\n ...(await collectFiles({\n dir: absolutePath,\n rootDir: input.rootDir,\n ignoredNames: input.ignoredNames,\n }))\n );\n continue;\n }\n if (!entry.isFile()) {\n continue;\n }\n const content = await readFile(absolutePath);\n files.push({\n relativePath: normalizeRelativePath(\n relative(input.rootDir, absolutePath)\n ),\n content,\n });\n }\n return files;\n}\n\nfunction normalizeRelativePath(value: string): string {\n return value.split(\"\\\\\").join(\"/\");\n}\n\nfunction getErrorCode(error: unknown): string | undefined {\n if (!error || typeof error !== \"object\") {\n return undefined;\n }\n const code = (error as { code?: unknown }).code;\n return typeof code === \"string\" ? code : undefined;\n}\n\nfunction warnDirectoryReadError(dir: string, error: unknown): void {\n const reason = error instanceof Error ? error.message : String(error);\n process.stderr.write(\n `[openmeld] failed to read directory while hashing skills content (${dir}): ${reason}\\n`\n );\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { mkdir, readFile, rm, stat, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { runtimeLogsDir } from \"../config/paths\";\n\nconst heldLock = new AsyncLocalStorage<boolean>();\nconst pendingLocks = new Map<string, Promise<unknown>>();\nexport function withSkillsInstallLock<T>(run: () => Promise<T>): Promise<T> {\n if (heldLock.getStore()) {\n return run();\n }\n const key = runtimeLogsDir();\n const previous = pendingLocks.get(key) ?? Promise.resolve();\n const current = previous\n .catch(() => undefined)\n .then(() => acquireSkillsInstallLock(() => heldLock.run(true, run)));\n pendingLocks.set(key, current);\n return current.finally(() => {\n if (pendingLocks.get(key) === current) {\n pendingLocks.delete(key);\n }\n });\n}\n\nconst LOCK_FILE_NAME = \"skills-install.lock\";\nconst LOCK_ACQUIRE_MAX_ATTEMPTS = 3;\n\nasync function acquireSkillsInstallLock<T>(run: () => Promise<T>): Promise<T> {\n const logsDir = runtimeLogsDir();\n await mkdir(logsDir, { recursive: true });\n const lockPath = join(logsDir, LOCK_FILE_NAME);\n\n let acquired = false;\n const lockContents = `${JSON.stringify({\n pid: process.pid,\n createdAt: new Date().toISOString(),\n })}\\n`;\n for (let attempt = 0; attempt < LOCK_ACQUIRE_MAX_ATTEMPTS; attempt += 1) {\n try {\n await writeFile(lockPath, lockContents, {\n encoding: \"utf8\",\n flag: \"wx\",\n });\n acquired = true;\n break;\n } catch (error) {\n if (getErrorCode(error) !== \"EEXIST\") {\n throw error;\n }\n\n const recovered = await recoverStaleSkillsInstallLock(lockPath);\n if (!recovered) {\n throw new Error(\n \"another skills installation is already running; retry after it finishes\"\n );\n }\n\n try {\n await writeFile(lockPath, lockContents, {\n encoding: \"utf8\",\n flag: \"wx\",\n });\n acquired = true;\n break;\n } catch (retryError) {\n if (getErrorCode(retryError) !== \"EEXIST\") {\n throw retryError;\n }\n }\n }\n }\n\n if (!acquired) {\n throw new Error(\n \"another skills installation is already running; retry after it finishes\"\n );\n }\n\n try {\n return await run();\n } finally {\n await rm(lockPath, { force: true }).catch(() => undefined);\n }\n}\n\nasync function recoverStaleSkillsInstallLock(\n lockPath: string\n): Promise<boolean> {\n const lockRaw = await readFile(lockPath, \"utf8\").catch((error: unknown) => {\n if (getErrorCode(error) === \"ENOENT\") {\n return \"\";\n }\n throw error;\n });\n if (!lockRaw) {\n return true;\n }\n\n const parsed = parseLockMeta(lockRaw);\n const pid = resolveLockPid(parsed);\n if (!pid) {\n const metadata = await stat(lockPath).catch(() => null);\n if (metadata && Date.now() - metadata.mtimeMs < 30_000) {\n return false;\n }\n }\n if (pid && isPidAlive(pid)) {\n return false;\n }\n\n const latestLockRaw = await readFile(lockPath, \"utf8\").catch(\n (error: unknown) => {\n if (getErrorCode(error) === \"ENOENT\") {\n return \"\";\n }\n throw error;\n }\n );\n if (!latestLockRaw) {\n return true;\n }\n const latestParsed = parseLockMeta(latestLockRaw);\n const latestPid = resolveLockPid(latestParsed);\n if (\n !isSameLockSnapshot({\n beforeRaw: lockRaw,\n beforePid: pid,\n afterRaw: latestLockRaw,\n afterPid: latestPid,\n })\n ) {\n return false;\n }\n\n await rm(lockPath, { force: true }).catch((error: unknown) => {\n if (getErrorCode(error) === \"ENOENT\") {\n return undefined;\n }\n throw error;\n });\n return true;\n}\n\nfunction parseLockMeta(value: string): unknown {\n try {\n return JSON.parse(value);\n } catch {\n return null;\n }\n}\n\nfunction resolveLockPid(meta: unknown): number | null {\n if (!meta || typeof meta !== \"object\") {\n return null;\n }\n const pid = (meta as Record<string, unknown>).pid;\n return typeof pid === \"number\" && Number.isInteger(pid) && pid > 0\n ? pid\n : null;\n}\n\nfunction isPidAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n return getErrorCode(error) !== \"ESRCH\";\n }\n}\n\nfunction getErrorCode(error: unknown): string | undefined {\n if (!error || typeof error !== \"object\") {\n return undefined;\n }\n const code = (error as { code?: unknown }).code;\n return typeof code === \"string\" ? code : undefined;\n}\n\nfunction isSameLockSnapshot(input: {\n beforeRaw: string;\n beforePid: number | null;\n afterRaw: string;\n afterPid: number | null;\n}): boolean {\n if (input.beforeRaw !== input.afterRaw) {\n return false;\n }\n return input.beforePid === input.afterPid;\n}\n","import { randomUUID, verify } from \"node:crypto\";\nimport { mkdir, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport {\n OFFICIAL_CLI_SKILL_CONTRACT,\n OFFICIAL_CLI_SKILL_MAX_BYTES,\n OFFICIAL_CLI_SKILL_PUBLIC_KEY,\n type OfficialCliSkillPayload,\n type OfficialCliSkillRelease,\n officialCliSkillChannelSchema,\n officialCliSkillPayloadSchema,\n officialCliSkillReleaseSchema,\n} from \"@openmeld/schemas\";\nimport { openMeldRootDir, resolveOpenMeldEnvPreset } from \"../config/paths\";\nimport { compareSemver } from \"../config/version-state\";\nimport { OPENMELD_VERSION } from \"../runtime/version\";\nimport { loadBundledSkillAssets } from \"./bundled-assets\";\nimport { withSkillsInstallLock } from \"./install-lock\";\n\nconst CACHE_FILE = \"official-cli-skill.json\";\n\nexport function verifyOfficialSkillRelease(value: unknown): {\n release: OfficialCliSkillRelease;\n payload: OfficialCliSkillPayload;\n} {\n const envelope = officialCliSkillReleaseSchema.safeParse(value);\n if (\n !(\n envelope.success &&\n verify(\n null,\n Buffer.from(envelope.data.payload),\n OFFICIAL_CLI_SKILL_PUBLIC_KEY,\n Buffer.from(envelope.data.signature, \"base64\")\n )\n )\n ) {\n throw new Error(\"OpenMeld Skill signature is invalid\");\n }\n const payload = officialCliSkillPayloadSchema.safeParse(\n JSON.parse(envelope.data.payload)\n );\n if (!payload.success) {\n throw new Error(\"OpenMeld Skill content is invalid\");\n }\n return { release: envelope.data, payload: payload.data };\n}\n\nfunction isCompatible(\n payload: OfficialCliSkillPayload,\n cliVersion = OPENMELD_VERSION\n): boolean {\n return (\n payload.contractVersion === OFFICIAL_CLI_SKILL_CONTRACT &&\n compareSemver(cliVersion, payload.minimumCliVersion) >= 0\n );\n}\n\nexport function selectOfficialSkillRelease(\n value: unknown,\n cliVersion = OPENMELD_VERSION\n) {\n const channel = officialCliSkillChannelSchema.safeParse(value);\n if (!channel.success) {\n throw new Error(\"OpenMeld Skill channel is invalid\");\n }\n return (\n channel.data.releases\n .map(verifyOfficialSkillRelease)\n .filter(({ payload }) => isCompatible(payload, cliVersion))\n .sort((a, b) => b.payload.revision - a.payload.revision)[0] ?? null\n );\n}\n\nasync function readCachedRelease() {\n const raw = await readFile(join(openMeldRootDir(), CACHE_FILE), \"utf8\").catch(\n (error: NodeJS.ErrnoException) => {\n if (error.code === \"ENOENT\") {\n return null;\n }\n throw error;\n }\n );\n if (!raw) {\n return null;\n }\n try {\n return verifyOfficialSkillRelease(JSON.parse(raw));\n } catch (error) {\n process.stderr.write(\n `[openmeld] cached Skill rejected: ${error instanceof Error ? error.message : String(error)}\\n`\n );\n return null;\n }\n}\n\n// Local-only selection is shared by install, prompt, and component status.\nexport async function loadSelectedSkillAssets() {\n const cached = await readCachedRelease();\n if (!(cached && isCompatible(cached.payload))) {\n return {\n assets: await loadBundledSkillAssets(),\n version: OPENMELD_VERSION,\n };\n }\n return {\n assets: [\n ...cached.payload.files.map((file) => ({\n relativePath: `openmeld-cli/${file.path}`,\n content: Buffer.from(file.content),\n })),\n ].sort((a, b) => a.relativePath.localeCompare(b.relativePath)),\n version: `skill-r${cached.payload.revision}`,\n contentRelease: {\n revision: cached.payload.revision,\n minimumCliVersion: cached.payload.minimumCliVersion,\n },\n };\n}\n\nexport async function readSelectedSkillDocument(path: string): Promise<string> {\n const { assets } = await loadSelectedSkillAssets();\n const asset = assets.find(\n (file) => file.relativePath === `openmeld-cli/${path}`\n );\n if (!asset) {\n throw new Error(`OpenMeld Skill document is missing: ${path}`);\n }\n return asset.content.toString(\"utf8\");\n}\n\nexport function resolveOfficialSkillChannelUrl(): string | null {\n if (resolveOpenMeldEnvPreset() === \"prod\") {\n return \"https://openmeld.ai/skills/openmeld-cli/channel.json\";\n }\n const override = process.env.OPENMELD_CLI_SKILL_CHANNEL_URL;\n if (!(override && process.env.OPENMELD_HOME)) {\n return null;\n }\n const url = new URL(override);\n if (\n url.protocol !== \"http:\" ||\n ![\"localhost\", \"127.0.0.1\", \"[::1]\"].includes(url.hostname) ||\n url.username ||\n url.password\n ) {\n throw new Error(\"Isolated Skill updates require an explicit localhost URL\");\n }\n return url.href;\n}\n\nexport async function downloadOfficialSkillUpdate(): Promise<\n \"updated\" | \"current\" | \"incompatible\" | \"lane_isolated\"\n> {\n const url = resolveOfficialSkillChannelUrl();\n if (!url) {\n return \"lane_isolated\";\n }\n const response = await fetch(url, {\n signal: AbortSignal.timeout(5000),\n redirect: \"error\",\n });\n if (!(response.ok && response.body)) {\n throw new Error(`OpenMeld Skill download failed (HTTP ${response.status})`);\n }\n const chunks: Uint8Array[] = [];\n let size = 0;\n for await (const chunk of response.body) {\n size += chunk.byteLength;\n if (size > OFFICIAL_CLI_SKILL_MAX_BYTES) {\n throw new Error(\"OpenMeld Skill download exceeds the size limit\");\n }\n chunks.push(chunk);\n }\n const selected = selectOfficialSkillRelease(\n JSON.parse(Buffer.concat(chunks).toString(\"utf8\"))\n );\n if (!selected) {\n return \"incompatible\";\n }\n return withSkillsInstallLock(async () => {\n const cached = await readCachedRelease();\n if (cached && cached.payload.revision >= selected.payload.revision) {\n return \"current\";\n }\n await mkdir(openMeldRootDir(), { recursive: true });\n const cache = join(openMeldRootDir(), CACHE_FILE);\n const staged = `${cache}.${randomUUID()}.tmp`;\n try {\n await writeFile(staged, JSON.stringify(selected.release), {\n flag: \"wx\",\n mode: 0o600,\n });\n await rename(staged, cache);\n } finally {\n await rm(staged, { force: true });\n }\n return \"updated\";\n });\n}\n","import { randomUUID } from \"node:crypto\";\nimport { lstat, readFile, readlink, rename, rm } from \"node:fs/promises\";\nimport { basename, dirname, join, resolve } from \"node:path\";\n\n// Callers hold the skills install lock. Recover a process exit between renames.\nexport async function recoverSkillReplacement(target: string): Promise<void> {\n const previous = join(\n dirname(target),\n `.${basename(target)}.openmeld-previous`\n );\n if (!(await exists(previous))) {\n return;\n }\n if (!(await isManagedReplacement(previous, basename(target)))) {\n throw new Error(\"OpenMeld Skill backup conflicts with an unmanaged path\");\n }\n if (await exists(target)) {\n if (!(await isManagedReplacement(target, basename(target)))) {\n throw new Error(\"OpenMeld Skill recovery would affect an unmanaged path\");\n }\n await rm(previous, { recursive: true, force: true });\n } else {\n await rename(previous, target);\n }\n}\n\nexport async function replaceSkillDirectory(\n target: string,\n prepare: (staged: string) => Promise<void>\n): Promise<void> {\n await recoverSkillReplacement(target);\n const staged = join(\n dirname(target),\n `.${basename(target)}.openmeld-staged-${randomUUID()}`\n );\n const previous = join(\n dirname(target),\n `.${basename(target)}.openmeld-previous`\n );\n try {\n await prepare(staged);\n const hadPrevious = await exists(target);\n if (hadPrevious) {\n await rename(target, previous);\n }\n try {\n await rename(staged, target);\n } catch (error) {\n if (hadPrevious) {\n await rename(previous, target);\n }\n throw error;\n }\n // A cleanup failure must not roll back a committed replacement.\n await rm(previous, { recursive: true, force: true }).catch(() => undefined);\n } finally {\n await rm(staged, { recursive: true, force: true }).catch(() => undefined);\n }\n}\n\nasync function isManagedReplacement(\n path: string,\n skillId: string\n): Promise<boolean> {\n const raw = await readFile(join(path, \".openmeld-skill.json\"), \"utf8\").catch(\n () => null\n );\n if (raw) {\n try {\n const marker = JSON.parse(raw);\n return marker.managedBy === \"openmeld\" && marker.skillId === skillId;\n } catch {\n return false;\n }\n }\n // Legacy dangling links have no readable marker and carry no directory data.\n if ((await lstat(path)).isSymbolicLink()) {\n const destination = resolve(dirname(path), await readlink(path));\n return basename(destination) === skillId && !(await exists(destination));\n }\n return false;\n}\n\nfunction exists(path: string): Promise<boolean> {\n return lstat(path).then(\n () => true,\n (error: NodeJS.ErrnoException) => {\n if (error.code === \"ENOENT\") {\n return false;\n }\n throw error;\n }\n );\n}\n","import { lstat, mkdir, readdir, readFile, writeFile } from \"node:fs/promises\";\nimport path, { dirname, join, relative } from \"node:path\";\nimport { skillsDir } from \"../config/paths\";\nimport {\n type BundledSkillAsset,\n hashBundledSkillAssets,\n} from \"./bundled-assets\";\nimport { sortBundledSkillAssets } from \"./bundled-assets-fs\";\nimport { computeDirectoryContentHash } from \"./content-hash\";\nimport { withSkillsInstallLock } from \"./install-lock\";\nimport { loadSelectedSkillAssets } from \"./official-release\";\nimport {\n recoverSkillReplacement,\n replaceSkillDirectory,\n} from \"./replace-directory\";\n\nexport const OPENMELD_SKILL_MARKER_FILE = \".openmeld-skill.json\";\n\nexport type OpenMeldSkillMarker = {\n managedBy: \"openmeld\";\n skillId: string;\n mode: \"source\" | \"symlink\" | \"copy\";\n contentHash?: string;\n version?: string;\n updatedAt: string;\n};\n\nexport type LocalSkill = {\n id: string;\n name: string;\n absolutePath: string;\n relativePath: string;\n contentHash?: string;\n version?: string;\n};\n\nconst OPENMELD_CLI_SKILL_FILE = \"SKILL.md\";\nconst SKILL_NAME_REGEX = /^name:\\s*(.+)$/m;\n\nexport function ensureLocalSkills(): Promise<LocalSkill[]> {\n return withSkillsInstallLock(ensureLocalSkillsLocked);\n}\n\nasync function ensureLocalSkillsLocked(): Promise<LocalSkill[]> {\n const storePath = skillsDir();\n await mkdir(storePath, { recursive: true });\n\n const { assets, version: bundledVersion } = await loadSelectedSkillAssets();\n if (assets.length === 0) {\n return listLocalSkills();\n }\n const skillGroups = groupAssetsBySkill(assets);\n\n for (const [skillId, skillAssets] of skillGroups) {\n const targetDir = join(storePath, skillId);\n await recoverSkillReplacement(targetDir);\n const sourceContentHash = hashBundledSkillAssets(skillAssets);\n const existingMarker = await readOpenMeldSkillMarker(targetDir);\n const existing = await lstat(targetDir).catch(\n (error: NodeJS.ErrnoException) => {\n if (error.code === \"ENOENT\") {\n return null;\n }\n throw error;\n }\n );\n if (existing && (!existingMarker || existing.isSymbolicLink())) {\n throw new Error(\n `OpenMeld Skill source conflicts with an unmanaged path: ${targetDir}`\n );\n }\n const isUpToDate =\n existingMarker?.managedBy === \"openmeld\" &&\n existingMarker.skillId === skillId &&\n existingMarker.mode === \"source\" &&\n existingMarker.contentHash === sourceContentHash &&\n existingMarker.version === bundledVersion &&\n (await computeDirectoryContentHash({\n rootDir: targetDir,\n ignoredNames: [OPENMELD_SKILL_MARKER_FILE],\n })) === sourceContentHash;\n if (isUpToDate) {\n continue;\n }\n\n await replaceSkillDirectory(targetDir, async (stagedDir) => {\n for (const asset of skillAssets) {\n const filePath = join(stagedDir, asset.relativePath);\n await mkdir(dirname(filePath), { recursive: true });\n await writeFile(filePath, asset.content);\n }\n await writeOpenMeldSkillMarker({\n skillDir: stagedDir,\n skillId,\n mode: \"source\",\n contentHash: sourceContentHash,\n version: bundledVersion,\n });\n });\n }\n\n return listLocalSkills();\n}\n\n// Group loaded assets by their first path segment (the skill id). Top-level\n// files (e.g. skills/README.md) belong to no skill and are dropped, and a group\n// without a SKILL.md is dropped too — matching the previous \"only install skill\n// directories that contain SKILL.md\" behavior. Each group's paths are made\n// skill-relative and sorted so the per-skill hash matches the source tree.\nfunction groupAssetsBySkill(\n assets: BundledSkillAsset[]\n): Map<string, BundledSkillAsset[]> {\n const groups = new Map<string, BundledSkillAsset[]>();\n for (const asset of assets) {\n const slashIndex = asset.relativePath.indexOf(\"/\");\n if (slashIndex < 0) {\n continue;\n }\n const skillId = asset.relativePath.slice(0, slashIndex);\n const skillRelativePath = asset.relativePath.slice(slashIndex + 1);\n const group = groups.get(skillId) ?? [];\n group.push({ relativePath: skillRelativePath, content: asset.content });\n groups.set(skillId, group);\n }\n for (const [skillId, group] of [...groups.entries()]) {\n if (group.some((asset) => asset.relativePath === OPENMELD_CLI_SKILL_FILE)) {\n groups.set(skillId, sortBundledSkillAssets(group));\n } else {\n groups.delete(skillId);\n }\n }\n return groups;\n}\n\nexport async function listLocalSkills(): Promise<LocalSkill[]> {\n const storePath = skillsDir();\n const skillDirs = await discoverSkillDirs(storePath, 0, 6);\n const skills: LocalSkill[] = [];\n\n for (const skillDir of skillDirs) {\n const skillFile = join(skillDir, \"SKILL.md\");\n const raw = await readFile(skillFile, \"utf8\").catch(() => \"\");\n if (!raw) {\n continue;\n }\n const skillId = path.basename(skillDir);\n const skillName = readSkillName(raw) ?? skillId;\n const marker = await readOpenMeldSkillMarker(skillDir);\n skills.push({\n id: skillId,\n name: skillName,\n absolutePath: skillDir,\n relativePath: relative(storePath, skillDir) || skillId,\n ...(marker?.contentHash ? { contentHash: marker.contentHash } : {}),\n ...(marker?.version ? { version: marker.version } : {}),\n });\n }\n\n skills.sort((a, b) => a.relativePath.localeCompare(b.relativePath));\n return skills;\n}\n\nexport async function writeOpenMeldSkillMarker(input: {\n skillDir: string;\n skillId: string;\n mode: \"source\" | \"symlink\" | \"copy\";\n contentHash?: string;\n version?: string;\n}): Promise<void> {\n const markerPath = join(input.skillDir, OPENMELD_SKILL_MARKER_FILE);\n const marker: OpenMeldSkillMarker = {\n managedBy: \"openmeld\",\n skillId: input.skillId,\n mode: input.mode,\n ...(input.contentHash ? { contentHash: input.contentHash } : {}),\n ...(input.version ? { version: input.version } : {}),\n updatedAt: new Date().toISOString(),\n };\n await writeFile(markerPath, `${JSON.stringify(marker, null, 2)}\\n`, \"utf8\");\n}\n\nexport async function isOpenMeldManagedSkillDir(\n skillDir: string\n): Promise<boolean> {\n const marker = await readOpenMeldSkillMarker(skillDir);\n return marker?.managedBy === \"openmeld\";\n}\n\nexport async function readOpenMeldSkillMarker(\n skillDir: string\n): Promise<OpenMeldSkillMarker | null> {\n const markerPath = join(skillDir, OPENMELD_SKILL_MARKER_FILE);\n const raw = await readFile(markerPath, \"utf8\").catch(() => null);\n if (!raw) {\n return null;\n }\n try {\n const parsed = JSON.parse(raw) as Partial<OpenMeldSkillMarker>;\n if (parsed.managedBy !== \"openmeld\") {\n return null;\n }\n if (\n typeof parsed.skillId !== \"string\" ||\n parsed.skillId.trim().length === 0\n ) {\n return null;\n }\n if (\n parsed.mode !== \"source\" &&\n parsed.mode !== \"symlink\" &&\n parsed.mode !== \"copy\"\n ) {\n return null;\n }\n return {\n managedBy: \"openmeld\",\n skillId: parsed.skillId.trim(),\n mode: parsed.mode,\n ...(typeof parsed.contentHash === \"string\" &&\n parsed.contentHash.trim().length > 0\n ? { contentHash: parsed.contentHash.trim() }\n : {}),\n ...(typeof parsed.version === \"string\" && parsed.version.trim().length > 0\n ? { version: parsed.version.trim() }\n : {}),\n updatedAt:\n typeof parsed.updatedAt === \"string\" &&\n parsed.updatedAt.trim().length > 0\n ? parsed.updatedAt\n : new Date().toISOString(),\n };\n } catch {\n return null;\n }\n}\n\nasync function discoverSkillDirs(\n dir: string,\n depth: number,\n maxDepth: number\n): Promise<string[]> {\n if (depth > maxDepth) {\n return [];\n }\n\n const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);\n if (entries.length === 0) {\n return [];\n }\n\n const hasSkill = entries.some(\n (entry) => entry.isFile() && entry.name === \"SKILL.md\"\n );\n if (hasSkill) {\n return [dir];\n }\n\n const nested = await Promise.all(\n entries\n .filter(\n (entry) => entry.isDirectory() && !entry.name.includes(\".openmeld-\")\n )\n .map((entry) =>\n discoverSkillDirs(join(dir, entry.name), depth + 1, maxDepth)\n )\n );\n\n return nested.flat();\n}\n\nfunction readSkillName(rawSkillFile: string): string | undefined {\n const match = rawSkillFile.match(SKILL_NAME_REGEX);\n if (!match) {\n return undefined;\n }\n const candidate = match[1]?.trim();\n return candidate && candidate.length > 0 ? candidate : undefined;\n}\n","import { lstat, readlink } from \"node:fs/promises\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport { computeDirectoryContentHash } from \"./content-hash\";\nimport type { SkillsInstallTarget } from \"./installer\";\nimport {\n type LocalSkill,\n type OpenMeldSkillMarker,\n readOpenMeldSkillMarker,\n} from \"./store\";\n\nexport type SkillInstallState =\n | \"missing\"\n | \"outdated\"\n | \"up_to_date\"\n | \"external_conflict\";\n\nexport type SkillInstallStateResult = {\n targetId: string;\n targetDir: string;\n targetType: \"agent\" | \"custom\";\n skillId: string;\n skillDir: string;\n state: SkillInstallState;\n targetMode?: OpenMeldSkillMarker[\"mode\"];\n sourceHash?: string;\n targetHash?: string;\n sourceVersion?: string;\n targetVersion?: string;\n reason?: string;\n};\n\ntype SourceSnapshot = {\n hash?: string;\n version?: string;\n};\n\ntype TargetSnapshot =\n | {\n exists: false;\n }\n | {\n exists: true;\n isSymlink: boolean;\n marker: OpenMeldSkillMarker | null;\n symlinkTargetPath: string;\n destinationExists: boolean;\n };\n\nexport async function resolveSkillsInstallStates(input: {\n skills: LocalSkill[];\n targets: SkillsInstallTarget[];\n}): Promise<SkillInstallStateResult[]> {\n const states: SkillInstallStateResult[] = [];\n for (const target of input.targets) {\n for (const skill of input.skills) {\n states.push(\n await resolveSkillInstallStateForTarget({\n skill,\n target,\n })\n );\n }\n }\n return states;\n}\n\nexport async function resolveSkillInstallStateForTarget(input: {\n skill: LocalSkill;\n target: SkillsInstallTarget;\n}): Promise<SkillInstallStateResult> {\n const base = createBaseResult(input);\n const source = await resolveSourceSnapshot(input.skill);\n const target = await resolveTargetSnapshot(base.skillDir);\n\n if (!target.exists) {\n return createStateResult({\n base,\n source,\n state: \"missing\",\n });\n }\n\n if (target.marker?.managedBy !== \"openmeld\") {\n if (\n isLegacyOpenMeldSkillSymlink({\n skillId: input.skill.id,\n target,\n })\n ) {\n return createStateResult({\n base,\n source,\n state: \"outdated\",\n targetMode: \"symlink\",\n reason: \"legacy OpenMeld skill link found; update required\",\n });\n }\n\n return createStateResult({\n base,\n source,\n state: \"external_conflict\",\n reason:\n \"existing non-OpenMeld skill detected; skipped to avoid overwrite\",\n });\n }\n\n if (!target.isSymlink && target.marker.contentHash) {\n const entry = await lstat(join(base.skillDir, \"SKILL.md\")).catch(\n () => null\n );\n if (!entry?.isFile()) {\n return createStateResult({\n base,\n source,\n state: \"outdated\",\n targetMarker: target.marker,\n reason: \"OpenMeld Skill entry is missing\",\n });\n }\n const actualHash = await computeDirectoryContentHash({\n rootDir: base.skillDir,\n ignoredNames: [\".openmeld-skill.json\"],\n });\n if (actualHash !== target.marker.contentHash) {\n return createStateResult({\n base,\n source,\n state: \"external_conflict\",\n targetMarker: target.marker,\n reason: \"OpenMeld Skill files were modified locally; kept your changes\",\n });\n }\n }\n\n const upToDate = isUpToDate({\n source,\n targetMarker: target.marker,\n isSymlink: target.isSymlink,\n symlinkTargetPath: target.symlinkTargetPath,\n sourceSkillDir: input.skill.absolutePath,\n });\n if (upToDate) {\n return createStateResult({\n base,\n source,\n targetMarker: target.marker,\n state: \"up_to_date\",\n reason: \"already up-to-date\",\n });\n }\n\n return createStateResult({\n base,\n source,\n targetMarker: target.marker,\n state: \"outdated\",\n reason: target.isSymlink\n ? \"OpenMeld skill link points to a different OpenMeld skills store; update required\"\n : \"OpenMeld skill content changed; update required\",\n });\n}\n\nfunction createBaseResult(input: {\n skill: LocalSkill;\n target: SkillsInstallTarget;\n}): Omit<SkillInstallStateResult, \"state\"> {\n const skillDir = join(input.target.dir, input.skill.id);\n return {\n targetId: input.target.id,\n targetDir: input.target.dir,\n targetType: input.target.type,\n skillId: input.skill.id,\n skillDir,\n };\n}\n\nasync function resolveSourceSnapshot(\n skill: LocalSkill\n): Promise<SourceSnapshot> {\n const sourceMarker = await readOpenMeldSkillMarker(skill.absolutePath);\n return {\n ...((skill.contentHash ?? sourceMarker?.contentHash)\n ? { hash: skill.contentHash ?? sourceMarker?.contentHash }\n : {}),\n ...((skill.version ?? sourceMarker?.version)\n ? { version: skill.version ?? sourceMarker?.version }\n : {}),\n };\n}\n\nasync function resolveTargetSnapshot(\n skillDir: string\n): Promise<TargetSnapshot> {\n const stats = await lstat(skillDir).catch(() => null);\n if (!stats) {\n return { exists: false };\n }\n\n let marker = await readOpenMeldSkillMarker(skillDir);\n let symlinkTargetPath = \"\";\n if (stats.isSymbolicLink()) {\n symlinkTargetPath = await resolveSymlinkTarget(skillDir).catch(() => \"\");\n if (!marker && symlinkTargetPath) {\n marker = await readOpenMeldSkillMarker(symlinkTargetPath);\n }\n }\n\n return {\n exists: true,\n isSymlink: stats.isSymbolicLink(),\n marker,\n symlinkTargetPath,\n destinationExists: symlinkTargetPath\n ? Boolean(await lstat(symlinkTargetPath).catch(() => null))\n : true,\n };\n}\n\nfunction isLegacyOpenMeldSkillSymlink(input: {\n skillId: string;\n target: Extract<TargetSnapshot, { exists: true }>;\n}): boolean {\n if (\n !(input.target.isSymlink && input.target.symlinkTargetPath) ||\n input.target.destinationExists\n ) {\n return false;\n }\n\n return basename(input.target.symlinkTargetPath) === input.skillId;\n}\n\nfunction isUpToDate(input: {\n source: SourceSnapshot;\n targetMarker: OpenMeldSkillMarker;\n isSymlink: boolean;\n symlinkTargetPath: string;\n sourceSkillDir: string;\n}): boolean {\n if (input.isSymlink) {\n // A symlinked target mirrors whatever store it points at, and its marker is\n // read through the link, so a matching hash/version only proves that other\n // store's state. The link is current only when it resolves to this store's\n // skill directory; anything else must be reinstalled before the foreign\n // store drifts or disappears.\n return (\n input.symlinkTargetPath.length > 0 &&\n pathsEqual(input.symlinkTargetPath, input.sourceSkillDir)\n );\n }\n return hasMatchingHashAndVersion(input.source, input.targetMarker);\n}\n\nfunction hasMatchingHashAndVersion(\n source: SourceSnapshot,\n targetMarker: OpenMeldSkillMarker\n): boolean {\n if (\n !(\n source.hash &&\n targetMarker.contentHash &&\n source.hash === targetMarker.contentHash\n )\n ) {\n return false;\n }\n return (\n !(source.version && targetMarker.version) ||\n source.version === targetMarker.version\n );\n}\n\nfunction createStateResult(input: {\n base: Omit<SkillInstallStateResult, \"state\">;\n source: SourceSnapshot;\n state: SkillInstallState;\n targetMode?: OpenMeldSkillMarker[\"mode\"];\n targetMarker?: OpenMeldSkillMarker;\n reason?: string;\n}): SkillInstallStateResult {\n return {\n ...input.base,\n state: input.state,\n ...(input.source.hash ? { sourceHash: input.source.hash } : {}),\n ...(input.source.version ? { sourceVersion: input.source.version } : {}),\n ...(input.targetMarker?.contentHash\n ? { targetHash: input.targetMarker.contentHash }\n : {}),\n ...(input.targetMarker?.mode\n ? { targetMode: input.targetMarker.mode }\n : {}),\n ...(input.targetMode ? { targetMode: input.targetMode } : {}),\n ...(input.targetMarker?.version\n ? { targetVersion: input.targetMarker.version }\n : {}),\n ...(input.reason ? { reason: input.reason } : {}),\n };\n}\n\nasync function resolveSymlinkTarget(linkPath: string): Promise<string> {\n const target = await readlink(linkPath);\n return resolve(dirname(linkPath), target);\n}\n\nfunction pathsEqual(left: string, right: string): boolean {\n return resolve(left) === resolve(right);\n}\n"],"mappings":"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"}
@@ -1,15 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { dt as downloadCliBinaryUpdateArtifact, ft as resolveCliBinaryUpdatePlan, pt as verifyCliBinaryCodeSignature, rt as hasIndependentMaintenanceRegistration, ut as DEFAULT_CLI_BINARY_DOWNLOAD_POLICY } from "./daemon-service-runtime-bKt0YjC7.js";
4
- import { Dt as resolveVersionChangeDirection, Ft as resolveServiceUpdateUrgency, Pt as resolveCurrentDaemonExpectedVersion, Tt as resolveDaemonServiceAlignmentDecision, f as formatDaemonFailureContextText, ft as inspectDaemonServiceInventory, n as scheduleDaemonServiceUpdate, nt as createOpenMeldToolsUpdateCoordinator, rt as readOpenMeldToolsUpdateContextFromEnv, wt as buildDaemonServiceTargetSpec } from "./daemon-service-update-coordinator-D8O1uTtu.js";
3
+ import { lt as resolveOpenMeldEnvPreset } from "./lock-iue1J2xy.js";
4
+ import { dt as DEFAULT_CLI_BINARY_DOWNLOAD_POLICY, ft as allowUnsignedWindowsInternalPreview, gt as verifyCliBinaryCodeSignature, ht as resolveCliBinaryUpdatePlan, it as hasIndependentMaintenanceRegistration, mt as prepareCliBinaryProcessHelper, pt as downloadCliBinaryUpdateArtifact } from "./daemon-service-runtime-CBJtgM4P.js";
5
+ import { Dt as resolveVersionChangeDirection, Ft as resolveServiceUpdateUrgency, Pt as resolveCurrentDaemonExpectedVersion, Tt as resolveDaemonServiceAlignmentDecision, f as formatDaemonFailureContextText, ft as inspectDaemonServiceInventory, n as scheduleDaemonServiceUpdate, nt as createOpenMeldToolsUpdateCoordinator, rt as readOpenMeldToolsUpdateContextFromEnv, wt as buildDaemonServiceTargetSpec } from "./daemon-service-update-coordinator-0LB_XGVZ.js";
5
6
  import { t as isBinaryDistribution } from "./distribution-BDQT2ilb.js";
6
7
  import { a as formatOpenMeldCliTextBlock, t as formatInlineOpenMeldCliCommands } from "./cli-entry-command-CR_9QU1i.js";
7
- import { _ as writeVersionState, g as readVersionState, l as OPENMELD_VERSION, m as fetchLatestPackageInfo, p as fetchLatestCliBinaryRelease, u as buildNextVersionState } from "./daemon-lifecycle-journal-DyKx1xzm.js";
8
- import { n as resolveRuntimeContext } from "./context-l_31Mn4X.js";
9
- import { a as outJsonLine, t as createPresenter } from "./presenter-BcxiQyJg.js";
10
- import { X as getCommandEntryContract, Y as createUpgradeConfirmationGuideError, a as formatDaemonServiceDowngradeBlockedRecommendation, c as formatDaemonServiceMissingRecommendation, g as canUseInteractivePrompts, n as resolveElapsedTimeMs, t as formatElapsedTime, xt as buildAgentOverviewFromContract } from "./elapsed-time-Ooo4IC25.js";
11
- import { c as withOpenMeldToolsUpdateFailure, i as OpenMeldToolsUpdateFailureError, r as parseOpenMeldToolsUpdateFailureFrame } from "./openmeld-tools-update-process-frame-B-XB4dmO.js";
12
- import { t as resolveExternalOpenMeldToolsUpdate } from "./openmeld-tools-update-join-BfY0GnDs.js";
8
+ import { _ as writeVersionState, g as readVersionState, l as OPENMELD_VERSION, m as fetchLatestPackageInfo, p as fetchLatestCliBinaryRelease, u as buildNextVersionState } from "./daemon-lifecycle-journal-CDZLWgMj.js";
9
+ import { n as resolveRuntimeContext } from "./context-Bdh3nAzw.js";
10
+ import { n as outJsonLine } from "./io-DT66typ4.js";
11
+ import { t as createPresenter } from "./presenter-MJ5YgsOT.js";
12
+ import { X as getCommandEntryContract, Y as createUpgradeConfirmationGuideError, a as formatDaemonServiceDowngradeBlockedRecommendation, c as formatDaemonServiceMissingRecommendation, g as canUseInteractivePrompts, n as resolveElapsedTimeMs, t as formatElapsedTime, xt as buildAgentOverviewFromContract } from "./elapsed-time-q8lSPcfm.js";
13
+ import { c as withOpenMeldToolsUpdateFailure, i as OpenMeldToolsUpdateFailureError, r as parseOpenMeldToolsUpdateFailureFrame } from "./openmeld-tools-update-process-frame-BtFKp70p.js";
14
+ import { t as resolveExternalOpenMeldToolsUpdate } from "./openmeld-tools-update-join-D24llJ9L.js";
13
15
  import { tmpdir } from "node:os";
14
16
  import { basename, dirname, join } from "node:path";
15
17
  import { chmod, mkdtemp, realpath, rm, stat, writeFile } from "node:fs/promises";
@@ -175,9 +177,9 @@ function resolveTopLevelEntryName(command) {
175
177
  //#endregion
176
178
  //#region src/commands/upgrade.ts
177
179
  const OPENMELD_PACKAGE_NAME = "openmeld";
178
- const BINARY_MANUAL_OPENMELD_UPGRADE_COMMAND = "curl -fsSL 'https://openmeld.ai/setup?dist=binary' | sh";
180
+ const BINARY_UPGRADE_RECOVERY_URL = "https://openmeld.ai";
179
181
  const STAGING_BINARY_MANIFEST_URL = "https://staging.openmeld.ai/cli/manifest.json";
180
- const STAGING_BINARY_SETUP_COMMAND = "curl -fsSL 'https://staging.openmeld.ai/setup?lane=canary&dist=binary' | sh";
182
+ const STAGING_BINARY_UPGRADE_RECOVERY_URL = "https://staging.openmeld.ai";
181
183
  const INSTALL_SELF_JSON_LINE_SPLIT_RE = /\r?\n/u;
182
184
  const SERVICE_CHECK_STARTED_TEXT = "Checking OpenMeld Service";
183
185
  const SERVICE_CHECK_COMPLETED_TEXT = "OpenMeld Service check finished.";
@@ -240,12 +242,12 @@ async function runUpgradeWithRuntime(input, runtime) {
240
242
  }
241
243
  const allowPrompt = canUseInteractivePrompts(runtime);
242
244
  const currentVersion = OPENMELD_VERSION;
243
- const { currentGlobalInstall, manualUpgradeCommand } = await resolveUpgradeInstallContext();
245
+ const { currentGlobalInstall, manualUpgradeRecovery } = await resolveUpgradeInstallContext();
244
246
  const previousVersionState = await readVersionState();
245
247
  if (!previousVersionState) handleMissingVersionMetadata({
246
248
  presenter,
247
249
  resolvedView: runtime.resolvedView,
248
- manualUpgradeCommand
250
+ manualUpgradeRecovery
249
251
  });
250
252
  const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
251
253
  const checkingStage = startUpgradeStage({
@@ -298,7 +300,7 @@ async function runUpgradeWithRuntime(input, runtime) {
298
300
  presenter,
299
301
  resolvedView: runtime.resolvedView,
300
302
  upgradeStatus,
301
- manualUpgradeCommand
303
+ manualUpgradeRecovery
302
304
  });
303
305
  const installableUpgradeStatus = requireInstallableUpgradeStatus(upgradeStatus);
304
306
  if (!currentUpdate && await hasIndependentMaintenanceRegistration()) {
@@ -312,7 +314,7 @@ async function runUpgradeWithRuntime(input, runtime) {
312
314
  await installAndReconcileBinaryUpgrade({
313
315
  upgradeStatus: installableUpgradeStatus,
314
316
  previousVersionState,
315
- manualUpgradeCommand,
317
+ manualUpgradeRecovery,
316
318
  resolvedView: runtime.resolvedView,
317
319
  currentVersion,
318
320
  presenter
@@ -323,7 +325,7 @@ async function runUpgradeWithRuntime(input, runtime) {
323
325
  upgradeStatus: installableUpgradeStatus,
324
326
  previousVersionState,
325
327
  currentGlobalInstall,
326
- manualUpgradeCommand,
328
+ manualUpgradeRecovery,
327
329
  resolvedView: runtime.resolvedView,
328
330
  currentVersion,
329
331
  presenter
@@ -462,7 +464,7 @@ async function installAndReconcileBinaryUpgrade(input) {
462
464
  startedText: `Downloading and installing OpenMeld CLI (about ${bytesToRoundedMb(updatePlan.downloadSizeBytes)} MB)`,
463
465
  completedText: `OpenMeld CLI ${input.upgradeStatus.latestVersion} installed.`,
464
466
  data: {
465
- command: input.manualUpgradeCommand,
467
+ recoveryUrl: input.manualUpgradeRecovery.value,
466
468
  downloadSizeBytes: updatePlan.downloadSizeBytes,
467
469
  distribution: input.upgradeStatus.distribution,
468
470
  preferredTransport: updatePlan.transport
@@ -470,7 +472,7 @@ async function installAndReconcileBinaryUpgrade(input) {
470
472
  failureCode: "cli.update.install_failed",
471
473
  run: async () => await installLatestCliBinary({
472
474
  release: binaryRelease,
473
- manualUpgradeCommand: input.manualUpgradeCommand,
475
+ manualUpgradeRecovery: input.manualUpgradeRecovery,
474
476
  updatePlan
475
477
  })
476
478
  });
@@ -515,14 +517,14 @@ async function installAndReconcileNpmUpgrade(input) {
515
517
  startedText: "Downloading and installing OpenMeld CLI with npm",
516
518
  completedText: `OpenMeld CLI ${input.upgradeStatus.latestVersion} installed.`,
517
519
  data: {
518
- command: input.manualUpgradeCommand,
520
+ command: input.manualUpgradeRecovery.value,
519
521
  distribution: input.upgradeStatus.distribution
520
522
  },
521
523
  failureCode: "cli.update.install_failed",
522
524
  run: async () => await installLatestPackage({
523
525
  npmCommandSpec,
524
526
  currentGlobalInstall: input.currentGlobalInstall,
525
- manualUpgradeCommand: input.manualUpgradeCommand
527
+ manualUpgradeCommand: input.manualUpgradeRecovery.value
526
528
  })
527
529
  });
528
530
  const latestVersion = input.upgradeStatus.latestVersion;
@@ -556,7 +558,10 @@ async function installAndReconcileNpmUpgrade(input) {
556
558
  async function resolveUpgradeInstallContext() {
557
559
  if (isBinaryDistribution()) return {
558
560
  currentGlobalInstall: null,
559
- manualUpgradeCommand: resolveBinaryManualOpenMeldUpgradeCommand()
561
+ manualUpgradeRecovery: {
562
+ kind: "web",
563
+ value: resolveBinaryUpgradeRecoveryUrl()
564
+ }
560
565
  };
561
566
  const currentGlobalInstall = await resolveCurrentNpmGlobalPackageInstall({
562
567
  packageName: OPENMELD_PACKAGE_NAME,
@@ -565,26 +570,32 @@ async function resolveUpgradeInstallContext() {
565
570
  if (process.env.OPENMELD_INTERNAL_MAINTENANCE_WORKER === "1" && !currentGlobalInstall) throw new Error("OpenMeld could not identify the original npm installation. Automatic update stopped to preserve the current installation.");
566
571
  return {
567
572
  currentGlobalInstall,
568
- manualUpgradeCommand: buildManualOpenMeldUpgradeCommand({ globalPrefixPath: currentGlobalInstall?.globalPrefixPath ?? null })
573
+ manualUpgradeRecovery: {
574
+ kind: "command",
575
+ value: buildManualOpenMeldUpgradeCommand({ globalPrefixPath: currentGlobalInstall?.globalPrefixPath ?? null })
576
+ }
569
577
  };
570
578
  }
571
- function resolveBinaryManualOpenMeldUpgradeCommand(env = process.env) {
572
- return env.OPENMELD_ENV_PRESET === "canary" && env.OPENMELD_CLI_BINARY_MANIFEST_URL === STAGING_BINARY_MANIFEST_URL ? STAGING_BINARY_SETUP_COMMAND : BINARY_MANUAL_OPENMELD_UPGRADE_COMMAND;
579
+ function resolveBinaryUpgradeRecoveryUrl(env = process.env) {
580
+ return env.OPENMELD_ENV_PRESET === "canary" && env.OPENMELD_CLI_BINARY_MANIFEST_URL === STAGING_BINARY_MANIFEST_URL ? STAGING_BINARY_UPGRADE_RECOVERY_URL : BINARY_UPGRADE_RECOVERY_URL;
581
+ }
582
+ function formatManualUpgradeRecovery(recovery) {
583
+ return recovery.kind === "web" ? `Open ${recovery.value}, go to Computers, and use Update manually or Connect Computer to get a fresh setup command. Run that command on this Mac.` : `Run \`${recovery.value}\`.`;
573
584
  }
574
585
  function handleMissingVersionMetadata(input) {
575
- const errorMessage = formatOpenMeldCliTextBlock(`OpenMeld version metadata is missing, so automatic upgrade cannot continue.\nManual fallback: \`${input.manualUpgradeCommand}\`\nIf you want to repair local OpenMeld state first, run \`openmeld reset --yes\` before \`openmeld upgrade\`.`);
586
+ const errorMessage = formatOpenMeldCliTextBlock(`OpenMeld version metadata is missing, so automatic upgrade cannot continue.\nManual fallback: ${formatManualUpgradeRecovery(input.manualUpgradeRecovery)}\nIf you want to repair local OpenMeld state first, run \`openmeld reset --yes\` before \`openmeld upgrade\`.`);
576
587
  if (input.resolvedView === "agent") {
577
588
  input.presenter.data({
578
589
  code: "upgrade.metadata.missing",
579
590
  payload: {
580
591
  summary: "Local OpenMeld version metadata is missing, so automatic upgrade cannot verify downgrade safety.",
581
592
  nextSteps: [
582
- input.manualUpgradeCommand,
593
+ formatManualUpgradeRecovery(input.manualUpgradeRecovery),
583
594
  "openmeld-dev reset --yes --view agent",
584
595
  "openmeld-dev start",
585
596
  "openmeld-dev upgrade --check --view agent"
586
597
  ],
587
- humanActionRequired: false
598
+ humanActionRequired: input.manualUpgradeRecovery.kind === "web"
588
599
  }
589
600
  });
590
601
  throw new UpgradeOutputHandledError(errorMessage);
@@ -592,18 +603,18 @@ function handleMissingVersionMetadata(input) {
592
603
  throw new Error(errorMessage);
593
604
  }
594
605
  function handleUpgradeCheckFailure(input) {
595
- const errorMessage = formatOpenMeldCliTextBlock(`Version check failed (${input.upgradeStatus.error}). Upgrade stopped because downgrade protection requires confirming that ${formatUpgradeLatestSource(input.upgradeStatus.distribution)} is newer than the current CLI.\nManual fallback: \`${input.manualUpgradeCommand}\``);
606
+ const errorMessage = formatOpenMeldCliTextBlock(`Version check failed (${input.upgradeStatus.error}). Upgrade stopped because downgrade protection requires confirming that ${formatUpgradeLatestSource(input.upgradeStatus.distribution)} is newer than the current CLI.\nManual fallback: ${formatManualUpgradeRecovery(input.manualUpgradeRecovery)}`);
596
607
  if (input.resolvedView === "agent") {
597
608
  input.presenter.data({
598
609
  code: "upgrade.check_failed",
599
610
  payload: {
600
611
  ...input.upgradeStatus,
601
612
  nextSteps: [
602
- input.manualUpgradeCommand,
613
+ formatManualUpgradeRecovery(input.manualUpgradeRecovery),
603
614
  "openmeld-dev upgrade --check --view agent",
604
615
  "openmeld-dev upgrade --yes --view agent"
605
616
  ],
606
- humanActionRequired: false
617
+ humanActionRequired: input.manualUpgradeRecovery.kind === "web"
607
618
  }
608
619
  });
609
620
  throw new UpgradeOutputHandledError(errorMessage);
@@ -695,10 +706,19 @@ async function installLatestCliBinary(input) {
695
706
  await writeFile(artifactPath, artifactBytes);
696
707
  await chmod(artifactPath, 493);
697
708
  await verifyCliBinaryCodeSignature({
709
+ allowUnsignedPreview: allowUnsignedWindowsInternalPreview(),
698
710
  artifactPath,
711
+ allowUnsignedForDevelopment: resolveOpenMeldEnvPreset() === "dev-local",
699
712
  release: input.release,
700
713
  runCommand
701
714
  });
715
+ await prepareCliBinaryProcessHelper({
716
+ allowUnsignedPreview: allowUnsignedWindowsInternalPreview(),
717
+ artifactPath,
718
+ release: input.release,
719
+ downloadPolicy: DEFAULT_CLI_BINARY_DOWNLOAD_POLICY,
720
+ fetchImpl: fetch
721
+ });
702
722
  const installResult = await runCommand(artifactPath, [
703
723
  "install-self",
704
724
  "--force",
@@ -706,7 +726,7 @@ async function installLatestCliBinary(input) {
706
726
  ]);
707
727
  if (installResult.code !== 0) {
708
728
  const details = installResult.stderr.trim() || installResult.stdout.trim();
709
- throw new Error(formatOpenMeldCliTextBlock(`binary install-self failed (exit ${installResult.code})${details ? `: ${details}` : ""}\nManual fallback: \`${input.manualUpgradeCommand}\``));
729
+ throw new Error(formatOpenMeldCliTextBlock(`binary install-self failed (exit ${installResult.code})${details ? `: ${details}` : ""}\nManual fallback: ${formatManualUpgradeRecovery(input.manualUpgradeRecovery)}`));
710
730
  }
711
731
  const installed = parseInstallSelfJsonOutput(installResult.stdout);
712
732
  if (installed.version !== input.release.version) throw new Error(`binary install-self returned version ${installed.version}, expected ${input.release.version}`);
@@ -1090,6 +1110,6 @@ function toErrorMessage(error) {
1090
1110
  return String(error);
1091
1111
  }
1092
1112
  //#endregion
1093
- export { runUpgrade as a, OPENMELD_UPGRADE_FAILURE_HINTS as c, runMaintenanceUpgrade as i, OPENMELD_UPGRADE_METADATA_RECOVERY_HINTS as l, isUpgradeOutputHandledError as n, emitTopLevelAgentOverview as o, resolveBinaryManualOpenMeldUpgradeCommand as r, emitTopLevelCliAgentOverview as s, UPGRADE_INTERNAL_ALIGN_SERVICE_FLAG as t };
1113
+ export { runUpgrade as a, OPENMELD_UPGRADE_FAILURE_HINTS as c, runMaintenanceUpgrade as i, OPENMELD_UPGRADE_METADATA_RECOVERY_HINTS as l, isUpgradeOutputHandledError as n, emitTopLevelAgentOverview as o, resolveBinaryUpgradeRecoveryUrl as r, emitTopLevelCliAgentOverview as s, UPGRADE_INTERNAL_ALIGN_SERVICE_FLAG as t };
1094
1114
 
1095
- //# sourceMappingURL=upgrade-D5FxGbh1.js.map
1115
+ //# sourceMappingURL=upgrade-DfJwCD5H.js.map