openmeld 0.3.211 → 0.3.213

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 (78) hide show
  1. package/dist/{add-me-membership-CNgO595N.js → add-me-membership-GbaxKxz-.js} +2 -2
  2. package/dist/{add-me-membership-CNgO595N.js.map → add-me-membership-GbaxKxz-.js.map} +1 -1
  3. package/dist/agents-BNoz9DA5.js +4153 -0
  4. package/dist/agents-BNoz9DA5.js.map +1 -0
  5. package/dist/{api-client-foundation-CtQTtA4m.js → api-client-foundation-TEBOwWl1.js} +1 -1
  6. package/dist/{api-client-foundation-MJK8vWfn.js → api-client-foundation-km8Ol1P4.js} +3 -3
  7. package/dist/{api-client-foundation-MJK8vWfn.js.map → api-client-foundation-km8Ol1P4.js.map} +1 -1
  8. package/dist/auth-session-D6UDl3r3.js +4 -0
  9. package/dist/{auth-session-CB7m-csh.js → auth-session-DgHvRt5i.js} +99 -21
  10. package/dist/auth-session-DgHvRt5i.js.map +1 -0
  11. package/dist/{command-oQK6PG6b.js → command-Dsa8gaFe.js} +10 -9
  12. package/dist/{command-oQK6PG6b.js.map → command-Dsa8gaFe.js.map} +1 -1
  13. package/dist/computer-connection-D8tX14R_.js +120 -0
  14. package/dist/computer-connection-D8tX14R_.js.map +1 -0
  15. package/dist/{computer-connection-review-CiIyTeDw.js → computer-connection-review-CjOXBWiV.js} +6 -6
  16. package/dist/{computer-connection-review-CiIyTeDw.js.map → computer-connection-review-CjOXBWiV.js.map} +1 -1
  17. package/dist/computer-disconnect-k6UVCsVF.js +47 -0
  18. package/dist/computer-disconnect-k6UVCsVF.js.map +1 -0
  19. package/dist/{computer-setup-continuation-CeFPluYv.js → computer-setup-continuation-DhY_sJis.js} +4 -4
  20. package/dist/{computer-setup-continuation-CeFPluYv.js.map → computer-setup-continuation-DhY_sJis.js.map} +1 -1
  21. package/dist/{control-plane-D9jDcbMZ.js → control-plane-Bpu7g9Av.js} +3 -547
  22. package/dist/control-plane-Bpu7g9Av.js.map +1 -0
  23. package/dist/{daemon-service-runtime-D8KrOfSV.js → daemon-service-runtime-CY6wdBe1.js} +381 -54
  24. package/dist/daemon-service-runtime-CY6wdBe1.js.map +1 -0
  25. package/dist/{openmeld-tools-update-coordinator-qrZLtDMv.js → daemon-service-update-coordinator-BcbbIDzC.js} +25953 -25662
  26. package/dist/daemon-service-update-coordinator-BcbbIDzC.js.map +1 -0
  27. package/dist/{dist-DajKOXDk.js → dist-Bsz_wafH.js} +1 -1
  28. package/dist/{dist-DtykdMlN.js → dist-CAx_kxvt.js} +971 -929
  29. package/dist/dist-CAx_kxvt.js.map +1 -0
  30. package/dist/{elapsed-time-BE9NPM-x.js → elapsed-time-Do3uIV__.js} +47 -78
  31. package/dist/elapsed-time-Do3uIV__.js.map +1 -0
  32. package/dist/{installation-inventory-CLBwkIf6.js → installation-inventory-C92AkQkA.js} +3 -3
  33. package/dist/{installation-inventory-CLBwkIf6.js.map → installation-inventory-C92AkQkA.js.map} +1 -1
  34. package/dist/local-components-B6SCXZf9.js +575 -0
  35. package/dist/local-components-B6SCXZf9.js.map +1 -0
  36. package/dist/{openmeld-LADiOJ3_.js → openmeld-I4pLxQsY.js} +55 -154
  37. package/dist/openmeld-I4pLxQsY.js.map +1 -0
  38. package/dist/{openmeld-maintenance-worker-B-u1CItK.js → openmeld-maintenance-worker-D5VAO9GD.js} +5 -5
  39. package/dist/{openmeld-maintenance-worker-B-u1CItK.js.map → openmeld-maintenance-worker-D5VAO9GD.js.map} +1 -1
  40. package/dist/openmeld-tools-update-join-DsQdgYNw.js +56 -0
  41. package/dist/openmeld-tools-update-join-DsQdgYNw.js.map +1 -0
  42. package/dist/openmeld-tools-update-process-frame-0X-t0Kjv.js +93 -0
  43. package/dist/openmeld-tools-update-process-frame-0X-t0Kjv.js.map +1 -0
  44. package/dist/openmeld-tools-update-process-frame-DX1Dc8VI.js +4 -0
  45. package/dist/openmeld.js +7 -3
  46. package/dist/openmeld.js.map +1 -1
  47. package/dist/{prepare-session-executor-B5aD6Fx_.js → prepare-session-executor-BEzlM0hJ.js} +171 -16
  48. package/dist/prepare-session-executor-BEzlM0hJ.js.map +1 -0
  49. package/dist/{runtime-transport-VcPSvVY1.js → runtime-transport-DxISZdzf.js} +34 -4
  50. package/dist/runtime-transport-DxISZdzf.js.map +1 -0
  51. package/dist/{agents-CGBELT4J.js → service-Cev-7yAJ.js} +703 -4620
  52. package/dist/service-Cev-7yAJ.js.map +1 -0
  53. package/dist/{service-account-authorization-D1Wp-91j.js → service-account-authorization-AbowIr6n.js} +3 -3
  54. package/dist/{service-account-authorization-D1Wp-91j.js.map → service-account-authorization-AbowIr6n.js.map} +1 -1
  55. package/dist/service-account-control-BV_tBiio.js +145 -0
  56. package/dist/service-account-control-BV_tBiio.js.map +1 -0
  57. package/dist/{service-control-capabilities-CP1XCSVm.js → service-control-capabilities-BGXPenm1.js} +1 -1
  58. package/dist/{service-control-capabilities-COkZ1Ceh.js → service-control-capabilities-DUudAKoj.js} +2 -2
  59. package/dist/{service-control-capabilities-COkZ1Ceh.js.map → service-control-capabilities-DUudAKoj.js.map} +1 -1
  60. package/dist/{upgrade-DJLqTfBA.js → upgrade-9h70HCQP.js} +40 -18
  61. package/dist/upgrade-9h70HCQP.js.map +1 -0
  62. package/dist/upgrade-CXgHeEKK.js +4 -0
  63. package/package.json +2 -2
  64. package/dist/agents-CGBELT4J.js.map +0 -1
  65. package/dist/auth-session-CB7m-csh.js.map +0 -1
  66. package/dist/auth-session-DXJq5arz.js +0 -4
  67. package/dist/computer-connection-51dg6Tq0.js +0 -54
  68. package/dist/computer-connection-51dg6Tq0.js.map +0 -1
  69. package/dist/control-plane-D9jDcbMZ.js.map +0 -1
  70. package/dist/daemon-service-runtime-D8KrOfSV.js.map +0 -1
  71. package/dist/dist-DtykdMlN.js.map +0 -1
  72. package/dist/elapsed-time-BE9NPM-x.js.map +0 -1
  73. package/dist/openmeld-LADiOJ3_.js.map +0 -1
  74. package/dist/openmeld-tools-update-coordinator-qrZLtDMv.js.map +0 -1
  75. package/dist/prepare-session-executor-B5aD6Fx_.js.map +0 -1
  76. package/dist/runtime-transport-VcPSvVY1.js.map +0 -1
  77. package/dist/upgrade-BMh_CLJL.js +0 -4
  78. package/dist/upgrade-DJLqTfBA.js.map +0 -1
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { ft as resolveOpenMeldRootDir, pt as resolveOpenMeldServiceOwnedPathInput, rt as openMeldRootDir } from "./lock-Dxp6o_t_.js";
4
- import { A as withAuthSessionTransitionMutationLock, C as withAdmittedServiceSession, E as admitServiceAccountOperation, T as ServiceAccountAdmissionError, v as readServiceAdmissionSessionWithOwnership } from "./auth-session-CB7m-csh.js";
4
+ import { D as admitServiceAccountOperation, E as ServiceAccountAdmissionError, j as withAuthSessionTransitionMutationLock, w as withAdmittedServiceSession, y as readServiceAdmissionSessionWithOwnership } from "./auth-session-DgHvRt5i.js";
5
5
  import { r as readDaemonRuntimeLease } from "./daemon-runtime-lease-Dd4hdHNo.js";
6
- import { Bt as readDaemonServiceContract } from "./daemon-service-runtime-D8KrOfSV.js";
6
+ import { Vt as readDaemonServiceContract } from "./daemon-service-runtime-CY6wdBe1.js";
7
7
  import { t as resolveOpenMeldEnvironmentTarget } from "./openmeld-environment-target-NtJYJe1D.js";
8
8
  import { resolve } from "node:path";
9
9
  //#region src/local-service/lifecycle/service-account-authorization.ts
@@ -53,4 +53,4 @@ async function admitServiceAccountStop(input) {
53
53
  //#endregion
54
54
  export { resolveServiceAccountIdentity as n, runServiceAccountCarrier as r, admitServiceAccountStop as t };
55
55
 
56
- //# sourceMappingURL=service-account-authorization-D1Wp-91j.js.map
56
+ //# sourceMappingURL=service-account-authorization-AbowIr6n.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"service-account-authorization-D1Wp-91j.js","names":[],"sources":["../src/local-service/lifecycle/service-account-authorization.ts"],"sourcesContent":["import { resolve } from \"node:path\";\nimport type { ServiceAccountAdmissionIdentity } from \"@openmeld/schemas\";\nimport {\n readServiceAdmissionSessionWithOwnership,\n type StoredAuthSession,\n withAdmittedServiceSession,\n} from \"../../config/auth-session\";\nimport { withAuthSessionTransitionMutationLock } from \"../../config/auth-session-transition-lock\";\nimport { readDaemonRuntimeLease } from \"../../config/daemon-runtime-lease\";\nimport { readDaemonServiceContract } from \"../../config/daemon-service-contract\";\nimport { resolveOpenMeldEnvironmentTarget } from \"../../config/openmeld-environment-target\";\nimport {\n openMeldRootDir,\n resolveOpenMeldRootDir,\n resolveOpenMeldServiceOwnedPathInput,\n} from \"../../config/paths\";\nimport {\n admitServiceAccountOperation,\n ServiceAccountAdmissionError,\n} from \"../../config/service-account-admission\";\n\ntype Contract = NonNullable<\n Awaited<ReturnType<typeof readDaemonServiceContract>>\n>;\nfunction refused(reason: string, message: string): never {\n throw new ServiceAccountAdmissionError(reason, message);\n}\n\nexport async function resolveServiceAccountIdentity(\n session: StoredAuthSession,\n contract: Contract\n): Promise<ServiceAccountAdmissionIdentity> {\n const target = await resolveOpenMeldEnvironmentTarget();\n if (\n resolve(openMeldRootDir()) !==\n resolve(resolveOpenMeldRootDir(resolveOpenMeldServiceOwnedPathInput())) ||\n contract.lane !== target.preset ||\n contract.gatewayUrl !== target.gatewayUrl ||\n session.authBaseUrl !== target.authBaseUrl ||\n !contract.ownerUserId ||\n contract.ownerUserId !== session.user?.id ||\n !contract.connectedComputerId\n ) {\n refused(\n \"ownership_mismatch\",\n \"This Service does not match the signed-in account or environment. Reconnect it through OpenMeld setup before trying again.\"\n );\n }\n return {\n accountId: contract.ownerUserId,\n authBaseUrl: session.authBaseUrl,\n clientId: session.clientId,\n gatewayUrl: target.gatewayUrl,\n lane: target.preset,\n deviceId: contract.deviceId,\n contractGeneration: contract.generation,\n };\n}\n\nexport async function runServiceAccountCarrier<T>(\n id: string,\n run: () => Promise<T>\n): Promise<T> {\n const session = await withAuthSessionTransitionMutationLock(async () => {\n const local = await readServiceAdmissionSessionWithOwnership();\n const contract = await readDaemonServiceContract();\n if (!contract || contract.desiredState !== \"background\") {\n refused(\n \"cancelled\",\n \"This Service startup is no longer authorized. Start the Service again from the matching account.\"\n );\n }\n await admitServiceAccountOperation({\n id,\n operation: \"start\",\n identity: await resolveServiceAccountIdentity(local, contract),\n });\n return local;\n });\n return await withAdmittedServiceSession(session, run);\n}\n\nexport async function admitServiceAccountStop(input: {\n id: string;\n ownerUserId: string;\n deviceId: string;\n contractGeneration: number;\n commit: () => void;\n}): Promise<void> {\n await withAuthSessionTransitionMutationLock(async () => {\n const session = await readServiceAdmissionSessionWithOwnership();\n const contract = await readDaemonServiceContract();\n const lease = await readDaemonRuntimeLease();\n if (\n !(contract && lease) ||\n lease.pid !== process.pid ||\n contract.generation !== input.contractGeneration ||\n contract.ownerUserId !== input.ownerUserId ||\n contract.deviceId !== input.deviceId\n ) {\n refused(\n \"ownership_changed\",\n \"The running Service changed before this Stop was accepted. Check its status and try again.\"\n );\n }\n await admitServiceAccountOperation({\n id: input.id,\n operation: \"stop\",\n identity: await resolveServiceAccountIdentity(session, contract),\n commit: input.commit,\n });\n });\n}\n"],"mappings":";;;;;;;;;AAwBA,SAAS,QAAQ,QAAgB,SAAwB;CACvD,MAAM,IAAI,6BAA6B,QAAQ,OAAO;AACxD;AAEA,eAAsB,8BACpB,SACA,UAC0C;CAC1C,MAAM,SAAS,MAAM,iCAAiC;CACtD,IACE,QAAQ,gBAAgB,CAAC,MACvB,QAAQ,uBAAuB,qCAAqC,CAAC,CAAC,KACxE,SAAS,SAAS,OAAO,UACzB,SAAS,eAAe,OAAO,cAC/B,QAAQ,gBAAgB,OAAO,eAC/B,CAAC,SAAS,eACV,SAAS,gBAAgB,QAAQ,MAAM,MACvC,CAAC,SAAS,qBAEV,QACE,sBACA,4HACF;CAEF,OAAO;EACL,WAAW,SAAS;EACpB,aAAa,QAAQ;EACrB,UAAU,QAAQ;EAClB,YAAY,OAAO;EACnB,MAAM,OAAO;EACb,UAAU,SAAS;EACnB,oBAAoB,SAAS;CAC/B;AACF;AAEA,eAAsB,yBACpB,IACA,KACY;CAiBZ,OAAO,MAAM,2BAA2B,MAhBlB,sCAAsC,YAAY;EACtE,MAAM,QAAQ,MAAM,yCAAyC;EAC7D,MAAM,WAAW,MAAM,0BAA0B;EACjD,IAAI,CAAC,YAAY,SAAS,iBAAiB,cACzC,QACE,aACA,kGACF;EAEF,MAAM,6BAA6B;GACjC;GACA,WAAW;GACX,UAAU,MAAM,8BAA8B,OAAO,QAAQ;EAC/D,CAAC;EACD,OAAO;CACT,CAAC,GACgD,GAAG;AACtD;AAEA,eAAsB,wBAAwB,OAM5B;CAChB,MAAM,sCAAsC,YAAY;EACtD,MAAM,UAAU,MAAM,yCAAyC;EAC/D,MAAM,WAAW,MAAM,0BAA0B;EACjD,MAAM,QAAQ,MAAM,uBAAuB;EAC3C,IACE,EAAE,YAAY,UACd,MAAM,QAAQ,QAAQ,OACtB,SAAS,eAAe,MAAM,sBAC9B,SAAS,gBAAgB,MAAM,eAC/B,SAAS,aAAa,MAAM,UAE5B,QACE,qBACA,4FACF;EAEF,MAAM,6BAA6B;GACjC,IAAI,MAAM;GACV,WAAW;GACX,UAAU,MAAM,8BAA8B,SAAS,QAAQ;GAC/D,QAAQ,MAAM;EAChB,CAAC;CACH,CAAC;AACH"}
1
+ {"version":3,"file":"service-account-authorization-AbowIr6n.js","names":[],"sources":["../src/local-service/lifecycle/service-account-authorization.ts"],"sourcesContent":["import { resolve } from \"node:path\";\nimport type { ServiceAccountAdmissionIdentity } from \"@openmeld/schemas\";\nimport {\n readServiceAdmissionSessionWithOwnership,\n type StoredAuthSession,\n withAdmittedServiceSession,\n} from \"../../config/auth-session\";\nimport { withAuthSessionTransitionMutationLock } from \"../../config/auth-session-transition-lock\";\nimport { readDaemonRuntimeLease } from \"../../config/daemon-runtime-lease\";\nimport { readDaemonServiceContract } from \"../../config/daemon-service-contract\";\nimport { resolveOpenMeldEnvironmentTarget } from \"../../config/openmeld-environment-target\";\nimport {\n openMeldRootDir,\n resolveOpenMeldRootDir,\n resolveOpenMeldServiceOwnedPathInput,\n} from \"../../config/paths\";\nimport {\n admitServiceAccountOperation,\n ServiceAccountAdmissionError,\n} from \"../../config/service-account-admission\";\n\ntype Contract = NonNullable<\n Awaited<ReturnType<typeof readDaemonServiceContract>>\n>;\nfunction refused(reason: string, message: string): never {\n throw new ServiceAccountAdmissionError(reason, message);\n}\n\nexport async function resolveServiceAccountIdentity(\n session: StoredAuthSession,\n contract: Contract\n): Promise<ServiceAccountAdmissionIdentity> {\n const target = await resolveOpenMeldEnvironmentTarget();\n if (\n resolve(openMeldRootDir()) !==\n resolve(resolveOpenMeldRootDir(resolveOpenMeldServiceOwnedPathInput())) ||\n contract.lane !== target.preset ||\n contract.gatewayUrl !== target.gatewayUrl ||\n session.authBaseUrl !== target.authBaseUrl ||\n !contract.ownerUserId ||\n contract.ownerUserId !== session.user?.id ||\n !contract.connectedComputerId\n ) {\n refused(\n \"ownership_mismatch\",\n \"This Service does not match the signed-in account or environment. Reconnect it through OpenMeld setup before trying again.\"\n );\n }\n return {\n accountId: contract.ownerUserId,\n authBaseUrl: session.authBaseUrl,\n clientId: session.clientId,\n gatewayUrl: target.gatewayUrl,\n lane: target.preset,\n deviceId: contract.deviceId,\n contractGeneration: contract.generation,\n };\n}\n\nexport async function runServiceAccountCarrier<T>(\n id: string,\n run: () => Promise<T>\n): Promise<T> {\n const session = await withAuthSessionTransitionMutationLock(async () => {\n const local = await readServiceAdmissionSessionWithOwnership();\n const contract = await readDaemonServiceContract();\n if (!contract || contract.desiredState !== \"background\") {\n refused(\n \"cancelled\",\n \"This Service startup is no longer authorized. Start the Service again from the matching account.\"\n );\n }\n await admitServiceAccountOperation({\n id,\n operation: \"start\",\n identity: await resolveServiceAccountIdentity(local, contract),\n });\n return local;\n });\n return await withAdmittedServiceSession(session, run);\n}\n\nexport async function admitServiceAccountStop(input: {\n id: string;\n ownerUserId: string;\n deviceId: string;\n contractGeneration: number;\n commit: () => void;\n}): Promise<void> {\n await withAuthSessionTransitionMutationLock(async () => {\n const session = await readServiceAdmissionSessionWithOwnership();\n const contract = await readDaemonServiceContract();\n const lease = await readDaemonRuntimeLease();\n if (\n !(contract && lease) ||\n lease.pid !== process.pid ||\n contract.generation !== input.contractGeneration ||\n contract.ownerUserId !== input.ownerUserId ||\n contract.deviceId !== input.deviceId\n ) {\n refused(\n \"ownership_changed\",\n \"The running Service changed before this Stop was accepted. Check its status and try again.\"\n );\n }\n await admitServiceAccountOperation({\n id: input.id,\n operation: \"stop\",\n identity: await resolveServiceAccountIdentity(session, contract),\n commit: input.commit,\n });\n });\n}\n"],"mappings":";;;;;;;;;AAwBA,SAAS,QAAQ,QAAgB,SAAwB;CACvD,MAAM,IAAI,6BAA6B,QAAQ,OAAO;AACxD;AAEA,eAAsB,8BACpB,SACA,UAC0C;CAC1C,MAAM,SAAS,MAAM,iCAAiC;CACtD,IACE,QAAQ,gBAAgB,CAAC,MACvB,QAAQ,uBAAuB,qCAAqC,CAAC,CAAC,KACxE,SAAS,SAAS,OAAO,UACzB,SAAS,eAAe,OAAO,cAC/B,QAAQ,gBAAgB,OAAO,eAC/B,CAAC,SAAS,eACV,SAAS,gBAAgB,QAAQ,MAAM,MACvC,CAAC,SAAS,qBAEV,QACE,sBACA,4HACF;CAEF,OAAO;EACL,WAAW,SAAS;EACpB,aAAa,QAAQ;EACrB,UAAU,QAAQ;EAClB,YAAY,OAAO;EACnB,MAAM,OAAO;EACb,UAAU,SAAS;EACnB,oBAAoB,SAAS;CAC/B;AACF;AAEA,eAAsB,yBACpB,IACA,KACY;CAiBZ,OAAO,MAAM,2BAA2B,MAhBlB,sCAAsC,YAAY;EACtE,MAAM,QAAQ,MAAM,yCAAyC;EAC7D,MAAM,WAAW,MAAM,0BAA0B;EACjD,IAAI,CAAC,YAAY,SAAS,iBAAiB,cACzC,QACE,aACA,kGACF;EAEF,MAAM,6BAA6B;GACjC;GACA,WAAW;GACX,UAAU,MAAM,8BAA8B,OAAO,QAAQ;EAC/D,CAAC;EACD,OAAO;CACT,CAAC,GACgD,GAAG;AACtD;AAEA,eAAsB,wBAAwB,OAM5B;CAChB,MAAM,sCAAsC,YAAY;EACtD,MAAM,UAAU,MAAM,yCAAyC;EAC/D,MAAM,WAAW,MAAM,0BAA0B;EACjD,MAAM,QAAQ,MAAM,uBAAuB;EAC3C,IACE,EAAE,YAAY,UACd,MAAM,QAAQ,QAAQ,OACtB,SAAS,eAAe,MAAM,sBAC9B,SAAS,gBAAgB,MAAM,eAC/B,SAAS,aAAa,MAAM,UAE5B,QACE,qBACA,4FACF;EAEF,MAAM,6BAA6B;GACjC,IAAI,MAAM;GACV,WAAW;GACX,UAAU,MAAM,8BAA8B,SAAS,QAAQ;GAC/D,QAAQ,MAAM;EAChB,CAAC;CACH,CAAC;AACH"}
@@ -0,0 +1,145 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { w as readProcessStartIdentity } from "./lock-Dxp6o_t_.js";
4
+ import { va as buildDaemonSystemServiceCommandSpec, za as resolveRuntimeContext } from "./daemon-service-update-coordinator-BcbbIDzC.js";
5
+ import { A as reserveServiceAccountAdmission, E as ServiceAccountAdmissionError, O as cancelServiceAccountAdmission, d as getAuthSessionState, j as withAuthSessionTransitionMutationLock, k as readServiceAccountAdmission, o as buildStoredAuthSessionIdentity, w as withAdmittedServiceSession, y as readServiceAdmissionSessionWithOwnership } from "./auth-session-DgHvRt5i.js";
6
+ import { T as createQuietPresenter, d as runDaemonServiceDetached, m as runDaemonStop, or as fetchAuthUserSnapshot } from "./service-Cev-7yAJ.js";
7
+ import { a as serviceAccountControlRequestSchema } from "./distribution-DY2fBeSW.js";
8
+ import { r as readDaemonRuntimeLease } from "./daemon-runtime-lease-Dd4hdHNo.js";
9
+ import { Ft as requestLocalDaemonShutdown, Ht as upsertDaemonServiceContract, Mt as LocalDaemonControlPlaneClientError, Vt as readDaemonServiceContract, r as readCurrentDaemonRuntimeContext } from "./daemon-service-runtime-CY6wdBe1.js";
10
+ import { K as withDaemonServiceRunLock } from "./daemon-state-C37ZtIZK.js";
11
+ import { S as resolveDaemonServiceManager } from "./daemon-service-manager-GiMCiTmu.js";
12
+ import { n as resolveServiceAccountIdentity } from "./service-account-authorization-AbowIr6n.js";
13
+ import { setTimeout } from "node:timers/promises";
14
+ //#region src/commands/service-account-control.ts
15
+ function refused(reason, message) {
16
+ throw new ServiceAccountAdmissionError(reason, message);
17
+ }
18
+ async function runServiceAccountControl(request, expectedSessionIdentity) {
19
+ const parsed = serviceAccountControlRequestSchema.safeParse(request);
20
+ if (!parsed.success) refused("missing_account", "Choose a signed-in account before controlling this Service.");
21
+ const input = parsed.data;
22
+ if (process.platform === "win32") refused("unsupported_platform", "Account-checked Service control is not available on Windows yet.");
23
+ const auth = await getAuthSessionState();
24
+ if (auth.state !== "valid" || !auth.session) refused("authentication_required", "Sign in to the CLI with the matching account and try again.");
25
+ const preparedSession = auth.session;
26
+ if (preparedSession.user?.id !== input.expectedAccount) refused("account_mismatch", "The CLI is signed in to a different account. Sign in with the matching account and try again.");
27
+ if ((await fetchAuthUserSnapshot({
28
+ authBaseUrl: preparedSession.authBaseUrl,
29
+ accessToken: preparedSession.accessToken
30
+ })).id !== input.expectedAccount) refused("account_mismatch", "The CLI session belongs to a different account. Sign in again and retry.");
31
+ await withDaemonServiceRunLock(async () => {
32
+ const contract = await readDaemonServiceContract();
33
+ if (!contract) refused("ownership_unknown", "Connect this computer through OpenMeld setup before controlling its Service.");
34
+ const observed = await readCurrentDaemonRuntimeContext();
35
+ const lease = await readDaemonRuntimeLease();
36
+ if (input.operation === "start" && observed.effectiveRuntimeStatus !== "not_running") refused("busy", "The Service is already running or its state is uncertain. Check Service status before trying again.");
37
+ if (input.operation === "stop" && (observed.effectiveRuntimeStatus !== "running" || !lease || lease.generation !== contract.generation)) refused("ownership_unknown", "OpenMeld could not verify the running Service. Check Service status before trying again.");
38
+ let boundSession = preparedSession;
39
+ const reservation = await withAuthSessionTransitionMutationLock(async () => {
40
+ boundSession = await readServiceAdmissionSessionWithOwnership();
41
+ if (expectedSessionIdentity !== void 0 && buildStoredAuthSessionIdentity(boundSession) !== expectedSessionIdentity || boundSession.accessToken !== preparedSession.accessToken || boundSession.createdAt !== preparedSession.createdAt || boundSession.user?.id !== input.expectedAccount) refused("account_changed", "The CLI sign-in changed before this action was accepted. Check the account and try again.");
42
+ const current = await readDaemonServiceContract();
43
+ if (!current || JSON.stringify(current) !== JSON.stringify(contract)) refused("ownership_changed", "The Service changed before this action was accepted. Check its status and try again.");
44
+ const identity = await resolveServiceAccountIdentity(boundSession, contract);
45
+ if (input.operation === "start" && contract.desiredState !== "background") identity.contractGeneration += 1;
46
+ return await reserveServiceAccountAdmission({
47
+ operation: input.operation,
48
+ identity,
49
+ ...input.operation === "stop" && lease ? { target: {
50
+ ownerPid: lease.pid,
51
+ ownerProcessStartedAt: readProcessStartIdentity(lease.pid) ?? refused("ownership_unknown", "OpenMeld could not identify the Service process. Check its status and try again.")
52
+ } } : {}
53
+ });
54
+ });
55
+ try {
56
+ await withAdmittedServiceSession(boundSession, async () => {
57
+ if (input.operation === "stop") {
58
+ await stopReservedService(contract, reservation.id, lease?.pid ?? 0);
59
+ return;
60
+ }
61
+ const manager = contract.serviceController === "legacy-detached" ? null : await resolveDaemonServiceManager(contract.serviceController);
62
+ if (contract.serviceController !== "legacy-detached" && !(manager && (await manager.status()).installed)) refused("installation_required", "This Service needs setup before it can start. Run OpenMeld setup and try again.");
63
+ await upsertDaemonServiceContract({
64
+ ...contract,
65
+ desiredState: "background"
66
+ });
67
+ if (contract.serviceController === "legacy-detached") {
68
+ const runtime = await resolveRuntimeContext({ view: "agent" });
69
+ await runDaemonServiceDetached({
70
+ accountAdmissionId: reservation.id,
71
+ deviceId: contract.deviceId,
72
+ gatewayUrl: contract.gatewayUrl,
73
+ heartbeatMs: contract.heartbeatMs,
74
+ runtime,
75
+ presenter: createQuietPresenter(runtime),
76
+ mode: "background"
77
+ });
78
+ } else if (manager) {
79
+ await manager.deactivate();
80
+ await manager.install(buildDaemonSystemServiceCommandSpec({
81
+ controller: manager.controller,
82
+ accountAdmissionId: reservation.id
83
+ }));
84
+ await manager.start();
85
+ }
86
+ await waitForAdmittedService(reservation.id);
87
+ });
88
+ } finally {
89
+ await cancelServiceAccountAdmission(reservation.id);
90
+ }
91
+ });
92
+ }
93
+ async function waitForAdmittedService(id) {
94
+ const deadline = Date.now() + 15e3;
95
+ while (Date.now() < deadline) {
96
+ const current = await readServiceAccountAdmission();
97
+ const runtime = await readCurrentDaemonRuntimeContext();
98
+ if (current?.id === id && current.state === "admitted" && current.carrier?.ownerPid === runtime.runtimeStatus.pid && runtime.effectiveRuntimeStatus === "running") return;
99
+ await setTimeout(50);
100
+ }
101
+ refused("startup_unconfirmed", "OpenMeld could not confirm that this Service started. Check Service status before trying again.");
102
+ }
103
+ async function stopReservedService(contract, id, pid) {
104
+ await requestAccountCheckedServiceStop({
105
+ id,
106
+ manager: contract.serviceController === "legacy-detached" ? null : await resolveDaemonServiceManager(contract.serviceController)
107
+ });
108
+ const admitted = await readServiceAccountAdmission();
109
+ if (admitted?.id !== id || admitted.state !== "admitted" || admitted.carrier?.ownerPid !== pid) refused("admission_unconfirmed", "OpenMeld could not verify that the matching Service accepted Stop. Check Service status before trying again.");
110
+ const current = await readCurrentDaemonRuntimeContext();
111
+ if (current.runtimeStatus.pid !== null && current.runtimeStatus.pid !== pid) refused("ownership_changed", "Another Service instance is now running. Its state was left unchanged.");
112
+ await runDaemonStop({
113
+ json: true,
114
+ view: "agent"
115
+ }, { completedControlledShutdownOwnerPid: pid });
116
+ }
117
+ async function requestAccountCheckedServiceStop({ id, manager }) {
118
+ const wasEnabled = manager ? (await manager.status()).enabled : false;
119
+ if (manager) await manager.disableAutostart();
120
+ try {
121
+ if (!(await requestLocalDaemonShutdown({
122
+ payload: {
123
+ accountAdmissionId: id,
124
+ mode: "graceful",
125
+ gracePeriodMs: 2e3
126
+ },
127
+ timeoutMs: 15e3
128
+ })).accepted) throw new Error("The Service did not confirm controlled shutdown.");
129
+ } catch (error) {
130
+ if (manager && wasEnabled && error instanceof LocalDaemonControlPlaneClientError && error.code === "service.account_admission.stop_refused") try {
131
+ await manager.enableAutostart();
132
+ } catch (restoreError) {
133
+ throw new AggregateError([error, restoreError], "Stop was refused and its previous autostart setting could not be restored.");
134
+ }
135
+ if (!(error instanceof LocalDaemonControlPlaneClientError && error.code === "service.account_admission.stop_refused")) {
136
+ const detail = error instanceof Error ? error.message : String(error);
137
+ refused("stop_unconfirmed", `Stop may already be in progress. ${manager ? "Autostart remains disabled. " : ""}Check Service status before trying again. ${detail}`);
138
+ }
139
+ throw error;
140
+ }
141
+ }
142
+ //#endregion
143
+ export { runServiceAccountControl as t };
144
+
145
+ //# sourceMappingURL=service-account-control-BV_tBiio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-account-control-BV_tBiio.js","names":["delay"],"sources":["../src/commands/service-account-control.ts"],"sourcesContent":["import { setTimeout as delay } from \"node:timers/promises\";\nimport {\n SERVICE_ACCOUNT_STOP_REFUSED_CODE,\n type ServiceAccountControlRequest,\n serviceAccountControlRequestSchema,\n} from \"@openmeld/schemas\";\nimport {\n buildStoredAuthSessionIdentity,\n getAuthSessionState,\n readServiceAdmissionSessionWithOwnership,\n type StoredAuthSession,\n withAdmittedServiceSession,\n} from \"../config/auth-session\";\nimport { withAuthSessionTransitionMutationLock } from \"../config/auth-session-transition-lock\";\nimport { readDaemonRuntimeLease } from \"../config/daemon-runtime-lease\";\nimport {\n readDaemonServiceContract,\n upsertDaemonServiceContract,\n} from \"../config/daemon-service-contract\";\nimport { withDaemonServiceRunLock } from \"../config/daemon-state\";\nimport {\n cancelServiceAccountAdmission,\n readServiceAccountAdmission,\n reserveServiceAccountAdmission,\n ServiceAccountAdmissionError,\n} from \"../config/service-account-admission\";\nimport {\n LocalDaemonControlPlaneClientError,\n requestLocalDaemonShutdown,\n} from \"../local-service/control-plane/client\";\nimport { CONTROLLED_SHUTDOWN_REQUEST_TIMEOUT_MS } from \"../local-service/core/constants\";\nimport { buildDaemonSystemServiceCommandSpec } from \"../local-service/lifecycle/daemon-service-command-spec\";\nimport {\n type DaemonServiceManager,\n resolveDaemonServiceManager,\n} from \"../local-service/lifecycle/daemon-service-manager\";\nimport { readCurrentDaemonRuntimeContext } from \"../local-service/lifecycle/daemon-service-runtime\";\nimport { resolveServiceAccountIdentity } from \"../local-service/lifecycle/service-account-authorization\";\nimport { resolveRuntimeContext } from \"../runtime/context\";\nimport { readProcessStartIdentity } from \"../system/process-identity\";\nimport { fetchAuthUserSnapshot } from \"./auth-device-session-client\";\nimport { runDaemonServiceDetached, runDaemonStop } from \"./service\";\nimport { createQuietPresenter } from \"./service-output\";\n\ntype Contract = NonNullable<\n Awaited<ReturnType<typeof readDaemonServiceContract>>\n>;\n\nfunction refused(reason: string, message: string): never {\n throw new ServiceAccountAdmissionError(reason, message);\n}\n\nexport async function runServiceAccountControl(\n request: ServiceAccountControlRequest,\n expectedSessionIdentity?: string\n): Promise<void> {\n const parsed = serviceAccountControlRequestSchema.safeParse(request);\n if (!parsed.success) {\n refused(\n \"missing_account\",\n \"Choose a signed-in account before controlling this Service.\"\n );\n }\n const input = parsed.data;\n if (process.platform === \"win32\") {\n refused(\n \"unsupported_platform\",\n \"Account-checked Service control is not available on Windows yet.\"\n );\n }\n const auth = await getAuthSessionState();\n if (auth.state !== \"valid\" || !auth.session) {\n refused(\n \"authentication_required\",\n \"Sign in to the CLI with the matching account and try again.\"\n );\n }\n const preparedSession = auth.session;\n if (preparedSession.user?.id !== input.expectedAccount) {\n refused(\n \"account_mismatch\",\n \"The CLI is signed in to a different account. Sign in with the matching account and try again.\"\n );\n }\n // The shared Auth endpoint proves the principal. Local metadata alone does not.\n const user = await fetchAuthUserSnapshot({\n authBaseUrl: preparedSession.authBaseUrl,\n accessToken: preparedSession.accessToken,\n });\n if (user.id !== input.expectedAccount) {\n refused(\n \"account_mismatch\",\n \"The CLI session belongs to a different account. Sign in again and retry.\"\n );\n }\n\n await withDaemonServiceRunLock(async () => {\n const contract = await readDaemonServiceContract();\n if (!contract) {\n refused(\n \"ownership_unknown\",\n \"Connect this computer through OpenMeld setup before controlling its Service.\"\n );\n }\n const observed = await readCurrentDaemonRuntimeContext();\n const lease = await readDaemonRuntimeLease();\n if (\n input.operation === \"start\" &&\n observed.effectiveRuntimeStatus !== \"not_running\"\n ) {\n refused(\n \"busy\",\n \"The Service is already running or its state is uncertain. Check Service status before trying again.\"\n );\n }\n if (\n input.operation === \"stop\" &&\n (observed.effectiveRuntimeStatus !== \"running\" ||\n !lease ||\n lease.generation !== contract.generation)\n ) {\n refused(\n \"ownership_unknown\",\n \"OpenMeld could not verify the running Service. Check Service status before trying again.\"\n );\n }\n\n let boundSession: StoredAuthSession = preparedSession;\n const reservation = await withAuthSessionTransitionMutationLock(\n async () => {\n boundSession = await readServiceAdmissionSessionWithOwnership();\n if (\n (expectedSessionIdentity !== undefined &&\n buildStoredAuthSessionIdentity(boundSession) !==\n expectedSessionIdentity) ||\n boundSession.accessToken !== preparedSession.accessToken ||\n boundSession.createdAt !== preparedSession.createdAt ||\n boundSession.user?.id !== input.expectedAccount\n ) {\n refused(\n \"account_changed\",\n \"The CLI sign-in changed before this action was accepted. Check the account and try again.\"\n );\n }\n const current = await readDaemonServiceContract();\n if (!current || JSON.stringify(current) !== JSON.stringify(contract)) {\n refused(\n \"ownership_changed\",\n \"The Service changed before this action was accepted. Check its status and try again.\"\n );\n }\n const identity = await resolveServiceAccountIdentity(\n boundSession,\n contract\n );\n if (\n input.operation === \"start\" &&\n contract.desiredState !== \"background\"\n ) {\n identity.contractGeneration += 1;\n }\n return await reserveServiceAccountAdmission({\n operation: input.operation,\n identity,\n ...(input.operation === \"stop\" && lease\n ? {\n target: {\n ownerPid: lease.pid,\n ownerProcessStartedAt:\n readProcessStartIdentity(lease.pid) ??\n refused(\n \"ownership_unknown\",\n \"OpenMeld could not identify the Service process. Check its status and try again.\"\n ),\n },\n }\n : {}),\n });\n }\n );\n\n try {\n await withAdmittedServiceSession(boundSession, async () => {\n if (input.operation === \"stop\") {\n await stopReservedService(contract, reservation.id, lease?.pid ?? 0);\n return;\n }\n const manager =\n contract.serviceController === \"legacy-detached\"\n ? null\n : await resolveDaemonServiceManager(contract.serviceController);\n if (\n contract.serviceController !== \"legacy-detached\" &&\n !(manager && (await manager.status()).installed)\n ) {\n refused(\n \"installation_required\",\n \"This Service needs setup before it can start. Run OpenMeld setup and try again.\"\n );\n }\n await upsertDaemonServiceContract({\n ...contract,\n desiredState: \"background\",\n });\n if (contract.serviceController === \"legacy-detached\") {\n const runtime = await resolveRuntimeContext({ view: \"agent\" });\n await runDaemonServiceDetached({\n accountAdmissionId: reservation.id,\n deviceId: contract.deviceId,\n gatewayUrl: contract.gatewayUrl,\n heartbeatMs: contract.heartbeatMs,\n runtime,\n presenter: createQuietPresenter(runtime),\n mode: \"background\",\n });\n } else if (manager) {\n // Refresh the existing stopped supervisor definition with an immutable\n // generation argument. Never install a missing Service.\n await manager.deactivate();\n await manager.install(\n buildDaemonSystemServiceCommandSpec({\n controller: manager.controller,\n accountAdmissionId: reservation.id,\n })\n );\n await manager.start();\n }\n await waitForAdmittedService(reservation.id);\n });\n } finally {\n await cancelServiceAccountAdmission(reservation.id);\n }\n });\n}\n\nasync function waitForAdmittedService(id: string): Promise<void> {\n const deadline = Date.now() + 15_000;\n while (Date.now() < deadline) {\n const current = await readServiceAccountAdmission();\n const runtime = await readCurrentDaemonRuntimeContext();\n if (\n current?.id === id &&\n current.state === \"admitted\" &&\n current.carrier?.ownerPid === runtime.runtimeStatus.pid &&\n runtime.effectiveRuntimeStatus === \"running\"\n ) {\n return;\n }\n await delay(50);\n }\n refused(\n \"startup_unconfirmed\",\n \"OpenMeld could not confirm that this Service started. Check Service status before trying again.\"\n );\n}\n\nasync function stopReservedService(\n contract: Contract,\n id: string,\n pid: number\n): Promise<void> {\n const manager =\n contract.serviceController === \"legacy-detached\"\n ? null\n : await resolveDaemonServiceManager(contract.serviceController);\n await requestAccountCheckedServiceStop({ id, manager });\n const admitted = await readServiceAccountAdmission();\n if (\n admitted?.id !== id ||\n admitted.state !== \"admitted\" ||\n admitted.carrier?.ownerPid !== pid\n ) {\n refused(\n \"admission_unconfirmed\",\n \"OpenMeld could not verify that the matching Service accepted Stop. Check Service status before trying again.\"\n );\n }\n const current = await readCurrentDaemonRuntimeContext();\n if (current.runtimeStatus.pid !== null && current.runtimeStatus.pid !== pid) {\n refused(\n \"ownership_changed\",\n \"Another Service instance is now running. Its state was left unchanged.\"\n );\n }\n await runDaemonStop(\n { json: true, view: \"agent\" },\n {\n completedControlledShutdownOwnerPid: pid,\n }\n );\n}\n\nexport async function requestAccountCheckedServiceStop({\n id,\n manager,\n}: {\n id: string;\n manager: Pick<\n DaemonServiceManager,\n \"status\" | \"disableAutostart\" | \"enableAutostart\"\n > | null;\n}): Promise<void> {\n const wasEnabled = manager ? (await manager.status()).enabled : false;\n if (manager) {\n await manager.disableAutostart();\n }\n // No compatibility fallback: only the verified carrier may admit this stop.\n try {\n const shutdown = await requestLocalDaemonShutdown({\n payload: {\n accountAdmissionId: id,\n mode: \"graceful\",\n gracePeriodMs: 2000,\n },\n timeoutMs: CONTROLLED_SHUTDOWN_REQUEST_TIMEOUT_MS,\n });\n if (!shutdown.accepted) {\n throw new Error(\"The Service did not confirm controlled shutdown.\");\n }\n } catch (error) {\n if (\n manager &&\n wasEnabled &&\n error instanceof LocalDaemonControlPlaneClientError &&\n error.code === SERVICE_ACCOUNT_STOP_REFUSED_CODE\n ) {\n try {\n await manager.enableAutostart();\n } catch (restoreError) {\n throw new AggregateError(\n [error, restoreError],\n \"Stop was refused and its previous autostart setting could not be restored.\"\n );\n }\n }\n if (\n !(\n error instanceof LocalDaemonControlPlaneClientError &&\n error.code === SERVICE_ACCOUNT_STOP_REFUSED_CODE\n )\n ) {\n const detail = error instanceof Error ? error.message : String(error);\n refused(\n \"stop_unconfirmed\",\n `Stop may already be in progress. ${manager ? \"Autostart remains disabled. \" : \"\"}Check Service status before trying again. ${detail}`\n );\n }\n throw error;\n }\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { t as readServiceControlCapabilities } from "./service-control-capabilities-COkZ1Ceh.js";
3
+ import { t as readServiceControlCapabilities } from "./service-control-capabilities-DUudAKoj.js";
4
4
  export { readServiceControlCapabilities };
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { o as serviceControlCapabilitiesSchema, s as serviceControlCarrierCapabilitySchema } from "./distribution-DY2fBeSW.js";
4
- import { Bt as readDaemonServiceContract, It as sendLocalDaemonControlPlaneRequest, S as daemonServiceBinaryExecutablePath, j as readDaemonActiveBundleState, r as readCurrentDaemonRuntimeContext } from "./daemon-service-runtime-D8KrOfSV.js";
4
+ import { Lt as sendLocalDaemonControlPlaneRequest, S as daemonServiceBinaryExecutablePath, Vt as readDaemonServiceContract, j as readDaemonActiveBundleState, r as readCurrentDaemonRuntimeContext } from "./daemon-service-runtime-CY6wdBe1.js";
5
5
  import { S as resolveDaemonServiceManager } from "./daemon-service-manager-GiMCiTmu.js";
6
6
  import { realpath } from "node:fs/promises";
7
7
  import { execFile } from "node:child_process";
@@ -51,4 +51,4 @@ async function readServiceControlCapabilities() {
51
51
  //#endregion
52
52
  export { readServiceControlCapabilities as t };
53
53
 
54
- //# sourceMappingURL=service-control-capabilities-COkZ1Ceh.js.map
54
+ //# sourceMappingURL=service-control-capabilities-DUudAKoj.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"service-control-capabilities-COkZ1Ceh.js","names":[],"sources":["../src/commands/service-control-capabilities.ts"],"sourcesContent":["import { execFile } from \"node:child_process\";\nimport { realpath } from \"node:fs/promises\";\nimport { promisify } from \"node:util\";\nimport {\n serviceControlCapabilitiesSchema,\n serviceControlCarrierCapabilitySchema,\n} from \"@openmeld/schemas\";\nimport { readDaemonServiceContract } from \"../config/daemon-service-contract\";\nimport { sendLocalDaemonControlPlaneRequest } from \"../local-service/control-plane/client\";\nimport {\n daemonServiceBinaryExecutablePath,\n readDaemonActiveBundleState,\n} from \"../local-service/lifecycle/daemon-service-bundle\";\nimport { resolveDaemonServiceManager } from \"../local-service/lifecycle/daemon-service-manager\";\nimport { readCurrentDaemonRuntimeContext } from \"../local-service/lifecycle/daemon-service-runtime\";\n\n/** Read only: never invoke the repairing npm launcher or a lifecycle operation. */\nexport async function readServiceControlCapabilities() {\n const unsupported = { deviceId: null, start: false, stop: false };\n if (process.platform !== \"darwin\") {\n return unsupported;\n }\n const contract = await readDaemonServiceContract();\n const bundle = await readDaemonActiveBundleState();\n if (\n contract?.serviceController !== \"launchd\" ||\n bundle?.bundleFormat !== \"binary_v1\"\n ) {\n return unsupported;\n }\n const manager = await resolveDaemonServiceManager(\"launchd\");\n if (!(manager && (await manager.status()).installed)) {\n return unsupported;\n }\n // Guarded Start refreshes the supervisor command to this canonical executable.\n // Verify the executable that answered, so an old CLI delegating elsewhere\n // cannot advertise another binary's capability as its own.\n const executable = await realpath(daemonServiceBinaryExecutablePath());\n const { stdout } = await promisify(execFile)(\n executable,\n [\"service\", \"control-carrier-capability\", \"--json\"],\n { timeout: 5000, maxBuffer: 16_384 }\n );\n const carrier = serviceControlCarrierCapabilitySchema.safeParse(\n JSON.parse(stdout)\n );\n if (\n !carrier.success ||\n (await realpath(carrier.data.executable)) !== executable\n ) {\n return unsupported;\n }\n const runtime = await readCurrentDaemonRuntimeContext();\n if (runtime.effectiveRuntimeStatus === \"not_running\") {\n return { deviceId: contract.deviceId, start: true, stop: false };\n }\n if (runtime.effectiveRuntimeStatus !== \"running\") {\n return unsupported;\n }\n const response = await sendLocalDaemonControlPlaneRequest({\n request: { v: 1, command: \"account_control_capabilities\" },\n });\n return serviceControlCapabilitiesSchema.parse({\n deviceId: contract.deviceId,\n start: false,\n stop:\n response.code === \"service.account_control_capabilities\" &&\n response.payload.supported,\n });\n}\n"],"mappings":";;;;;;;;;;AAiBA,eAAsB,iCAAiC;CACrD,MAAM,cAAc;EAAE,UAAU;EAAM,OAAO;EAAO,MAAM;CAAM;CAChE,IAAI,QAAQ,aAAa,UACvB,OAAO;CAET,MAAM,WAAW,MAAM,0BAA0B;CACjD,MAAM,SAAS,MAAM,4BAA4B;CACjD,IACE,UAAU,sBAAsB,aAChC,QAAQ,iBAAiB,aAEzB,OAAO;CAET,MAAM,UAAU,MAAM,4BAA4B,SAAS;CAC3D,IAAI,EAAE,YAAY,MAAM,QAAQ,OAAO,EAAA,CAAG,YACxC,OAAO;CAKT,MAAM,aAAa,MAAM,SAAS,kCAAkC,CAAC;CACrE,MAAM,EAAE,WAAW,MAAM,UAAU,QAAQ,CAAC,CAC1C,YACA;EAAC;EAAW;EAA8B;CAAQ,GAClD;EAAE,SAAS;EAAM,WAAW;CAAO,CACrC;CACA,MAAM,UAAU,sCAAsC,UACpD,KAAK,MAAM,MAAM,CACnB;CACA,IACE,CAAC,QAAQ,WACR,MAAM,SAAS,QAAQ,KAAK,UAAU,MAAO,YAE9C,OAAO;CAET,MAAM,UAAU,MAAM,gCAAgC;CACtD,IAAI,QAAQ,2BAA2B,eACrC,OAAO;EAAE,UAAU,SAAS;EAAU,OAAO;EAAM,MAAM;CAAM;CAEjE,IAAI,QAAQ,2BAA2B,WACrC,OAAO;CAET,MAAM,WAAW,MAAM,mCAAmC,EACxD,SAAS;EAAE,GAAG;EAAG,SAAS;CAA+B,EAC3D,CAAC;CACD,OAAO,iCAAiC,MAAM;EAC5C,UAAU,SAAS;EACnB,OAAO;EACP,MACE,SAAS,SAAS,0CAClB,SAAS,QAAQ;CACrB,CAAC;AACH"}
1
+ {"version":3,"file":"service-control-capabilities-DUudAKoj.js","names":[],"sources":["../src/commands/service-control-capabilities.ts"],"sourcesContent":["import { execFile } from \"node:child_process\";\nimport { realpath } from \"node:fs/promises\";\nimport { promisify } from \"node:util\";\nimport {\n serviceControlCapabilitiesSchema,\n serviceControlCarrierCapabilitySchema,\n} from \"@openmeld/schemas\";\nimport { readDaemonServiceContract } from \"../config/daemon-service-contract\";\nimport { sendLocalDaemonControlPlaneRequest } from \"../local-service/control-plane/client\";\nimport {\n daemonServiceBinaryExecutablePath,\n readDaemonActiveBundleState,\n} from \"../local-service/lifecycle/daemon-service-bundle\";\nimport { resolveDaemonServiceManager } from \"../local-service/lifecycle/daemon-service-manager\";\nimport { readCurrentDaemonRuntimeContext } from \"../local-service/lifecycle/daemon-service-runtime\";\n\n/** Read only: never invoke the repairing npm launcher or a lifecycle operation. */\nexport async function readServiceControlCapabilities() {\n const unsupported = { deviceId: null, start: false, stop: false };\n if (process.platform !== \"darwin\") {\n return unsupported;\n }\n const contract = await readDaemonServiceContract();\n const bundle = await readDaemonActiveBundleState();\n if (\n contract?.serviceController !== \"launchd\" ||\n bundle?.bundleFormat !== \"binary_v1\"\n ) {\n return unsupported;\n }\n const manager = await resolveDaemonServiceManager(\"launchd\");\n if (!(manager && (await manager.status()).installed)) {\n return unsupported;\n }\n // Guarded Start refreshes the supervisor command to this canonical executable.\n // Verify the executable that answered, so an old CLI delegating elsewhere\n // cannot advertise another binary's capability as its own.\n const executable = await realpath(daemonServiceBinaryExecutablePath());\n const { stdout } = await promisify(execFile)(\n executable,\n [\"service\", \"control-carrier-capability\", \"--json\"],\n { timeout: 5000, maxBuffer: 16_384 }\n );\n const carrier = serviceControlCarrierCapabilitySchema.safeParse(\n JSON.parse(stdout)\n );\n if (\n !carrier.success ||\n (await realpath(carrier.data.executable)) !== executable\n ) {\n return unsupported;\n }\n const runtime = await readCurrentDaemonRuntimeContext();\n if (runtime.effectiveRuntimeStatus === \"not_running\") {\n return { deviceId: contract.deviceId, start: true, stop: false };\n }\n if (runtime.effectiveRuntimeStatus !== \"running\") {\n return unsupported;\n }\n const response = await sendLocalDaemonControlPlaneRequest({\n request: { v: 1, command: \"account_control_capabilities\" },\n });\n return serviceControlCapabilitiesSchema.parse({\n deviceId: contract.deviceId,\n start: false,\n stop:\n response.code === \"service.account_control_capabilities\" &&\n response.payload.supported,\n });\n}\n"],"mappings":";;;;;;;;;;AAiBA,eAAsB,iCAAiC;CACrD,MAAM,cAAc;EAAE,UAAU;EAAM,OAAO;EAAO,MAAM;CAAM;CAChE,IAAI,QAAQ,aAAa,UACvB,OAAO;CAET,MAAM,WAAW,MAAM,0BAA0B;CACjD,MAAM,SAAS,MAAM,4BAA4B;CACjD,IACE,UAAU,sBAAsB,aAChC,QAAQ,iBAAiB,aAEzB,OAAO;CAET,MAAM,UAAU,MAAM,4BAA4B,SAAS;CAC3D,IAAI,EAAE,YAAY,MAAM,QAAQ,OAAO,EAAA,CAAG,YACxC,OAAO;CAKT,MAAM,aAAa,MAAM,SAAS,kCAAkC,CAAC;CACrE,MAAM,EAAE,WAAW,MAAM,UAAU,QAAQ,CAAC,CAC1C,YACA;EAAC;EAAW;EAA8B;CAAQ,GAClD;EAAE,SAAS;EAAM,WAAW;CAAO,CACrC;CACA,MAAM,UAAU,sCAAsC,UACpD,KAAK,MAAM,MAAM,CACnB;CACA,IACE,CAAC,QAAQ,WACR,MAAM,SAAS,QAAQ,KAAK,UAAU,MAAO,YAE9C,OAAO;CAET,MAAM,UAAU,MAAM,gCAAgC;CACtD,IAAI,QAAQ,2BAA2B,eACrC,OAAO;EAAE,UAAU,SAAS;EAAU,OAAO;EAAM,MAAM;CAAM;CAEjE,IAAI,QAAQ,2BAA2B,WACrC,OAAO;CAET,MAAM,WAAW,MAAM,mCAAmC,EACxD,SAAS;EAAE,GAAG;EAAG,SAAS;CAA+B,EAC3D,CAAC;CACD,OAAO,iCAAiC,MAAM;EAC5C,UAAU,SAAS;EACnB,OAAO;EACP,MACE,SAAS,SAAS,0CAClB,SAAS,QAAQ;CACrB,CAAC;AACH"}
@@ -1,10 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { Oi as inspectDaemonServiceInventory, Vi as resolveCurrentDaemonExpectedVersion, a as resolveServiceUpdateUrgency, g as scheduleDaemonServiceUpdate, ia as resolveVersionChangeDirection, k as formatDaemonFailureContextText, m as readOpenMeldToolsUpdateContextFromEnv, na as resolveDaemonServiceAlignmentDecision, qi as resolveRuntimeContext, t as createOpenMeldToolsUpdateCoordinator, ta as buildDaemonServiceTargetSpec } from "./openmeld-tools-update-coordinator-qrZLtDMv.js";
3
+ import { $t as resolveCurrentDaemonExpectedVersion, Kt as resolveVersionChangeDirection, St as readOpenMeldToolsUpdateContextFromEnv, Ut as buildDaemonServiceTargetSpec, Wt as resolveDaemonServiceAlignmentDecision, Zi as resolveServiceUpdateUrgency, f as formatDaemonFailureContextText, jt as inspectDaemonServiceInventory, n as scheduleDaemonServiceUpdate, xt as createOpenMeldToolsUpdateCoordinator, za as resolveRuntimeContext } from "./daemon-service-update-coordinator-BcbbIDzC.js";
4
4
  import { t as isBinaryDistribution } from "./distribution-DY2fBeSW.js";
5
- import { At as verifyCliBinaryCodeSignature, Ot as downloadCliBinaryUpdateArtifact, ct as buildNextVersionState, dt as fetchLatestCliBinaryRelease, ft as fetchLatestPackageInfo, ht as writeVersionState, kt as resolveCliBinaryUpdatePlan, mt as readVersionState, nt as OPENMELD_VERSION, xt as hasIndependentMaintenanceRegistration } from "./daemon-service-runtime-D8KrOfSV.js";
6
- import { Rt as buildAgentOverviewFromContract, Ut as resolveExternalOpenMeldToolsUpdate, Zt as outJsonLine, a as formatDaemonServiceDowngradeBlockedRecommendation, c as formatDaemonServiceMissingRecommendation, m as canUseInteractivePrompts, n as resolveElapsedTimeMs, pt as getCommandEntryContract, q as createUpgradeConfirmationGuideError, qt as createPresenter, t as formatElapsedTime } from "./elapsed-time-BE9NPM-x.js";
5
+ import { At as resolveCliBinaryUpdatePlan, Ot as DEFAULT_CLI_BINARY_DOWNLOAD_POLICY, ct as buildNextVersionState, dt as fetchLatestCliBinaryRelease, ft as fetchLatestPackageInfo, ht as writeVersionState, jt as verifyCliBinaryCodeSignature, kt as downloadCliBinaryUpdateArtifact, mt as readVersionState, nt as OPENMELD_VERSION, xt as hasIndependentMaintenanceRegistration } from "./daemon-service-runtime-CY6wdBe1.js";
6
+ import { Bt as buildAgentOverviewFromContract, Gt as createPresenter, Y as createUpgradeConfirmationGuideError, Yt as outJsonLine, a as formatDaemonServiceDowngradeBlockedRecommendation, c as formatDaemonServiceMissingRecommendation, g as canUseInteractivePrompts, ht as getCommandEntryContract, n as resolveElapsedTimeMs, t as formatElapsedTime } from "./elapsed-time-Do3uIV__.js";
7
7
  import { c as formatOpenMeldCliTextBlock, i as formatInlineOpenMeldCliCommands } from "./openmeld-environment-target-NtJYJe1D.js";
8
+ import { c as withOpenMeldToolsUpdateFailure, i as OpenMeldToolsUpdateFailureError, r as parseOpenMeldToolsUpdateFailureFrame } from "./openmeld-tools-update-process-frame-0X-t0Kjv.js";
9
+ import { t as resolveExternalOpenMeldToolsUpdate } from "./openmeld-tools-update-join-DsQdgYNw.js";
8
10
  import { tmpdir } from "node:os";
9
11
  import { basename, dirname, join } from "node:path";
10
12
  import { chmod, mkdtemp, realpath, rm, stat, writeFile } from "node:fs/promises";
@@ -164,7 +166,6 @@ function resolveTopLevelEntryName(command) {
164
166
  //#endregion
165
167
  //#region src/commands/upgrade.ts
166
168
  const OPENMELD_PACKAGE_NAME = "openmeld";
167
- const CLI_BINARY_DOWNLOAD_TIMEOUT_MS = 6e4;
168
169
  const BINARY_MANUAL_OPENMELD_UPGRADE_COMMAND = "curl -fsSL 'https://openmeld.ai/setup?dist=binary' | sh";
169
170
  const STAGING_BINARY_MANIFEST_URL = "https://staging.openmeld.ai/cli/manifest.json";
170
171
  const STAGING_BINARY_SETUP_COMMAND = "curl -fsSL 'https://staging.openmeld.ai/setup?lane=canary&dist=binary' | sh";
@@ -180,7 +181,14 @@ var UpgradeOutputHandledError = class extends Error {
180
181
  }
181
182
  };
182
183
  function isUpgradeOutputHandledError(error) {
183
- return error instanceof UpgradeOutputHandledError || typeof error === "object" && error !== null && "code" in error && error.code === "openmeld.upgrade.output_handled";
184
+ const seen = /* @__PURE__ */ new Set();
185
+ let current = error;
186
+ while (current && typeof current === "object" && !seen.has(current)) {
187
+ seen.add(current);
188
+ if (current instanceof UpgradeOutputHandledError || current.code === "openmeld.upgrade.output_handled") return true;
189
+ current = current.cause;
190
+ }
191
+ return false;
184
192
  }
185
193
  async function runUpgrade(input) {
186
194
  await runUpgradeWithRuntime(input, await resolveRuntimeContext({ view: input.view }));
@@ -215,11 +223,9 @@ async function runUpgradeWithRuntime(input, runtime) {
215
223
  }
216
224
  }
217
225
  if (input.internalAlignService) {
218
- await runInternalUpgradeServiceAlignment({
226
+ await alignServiceWithCurrentCli({
219
227
  presenter,
220
- resolvedView: runtime.resolvedView,
221
- daemonVersion: await resolveCurrentDaemonExpectedVersion(),
222
- ...process.argv[1] && !isBinaryDistribution() ? { cliScriptPath: process.argv[1] } : {}
228
+ resolvedView: runtime.resolvedView
223
229
  });
224
230
  return;
225
231
  }
@@ -315,11 +321,15 @@ async function runUpgradeWithRuntime(input, runtime) {
315
321
  });
316
322
  }
317
323
  async function alignServiceWithCurrentCli(input) {
318
- await runInternalUpgradeServiceAlignment({
319
- ...input,
320
- daemonVersion: await resolveCurrentDaemonExpectedVersion(),
321
- ...process.argv[1] && !isBinaryDistribution() ? { cliScriptPath: process.argv[1] } : {}
322
- });
324
+ try {
325
+ await runInternalUpgradeServiceAlignment({
326
+ ...input,
327
+ daemonVersion: await resolveCurrentDaemonExpectedVersion(),
328
+ ...process.argv[1] && !isBinaryDistribution() ? { cliScriptPath: process.argv[1] } : {}
329
+ });
330
+ } catch (error) {
331
+ throw withOpenMeldToolsUpdateFailure(error, "cli.update.service_alignment_failed");
332
+ }
323
333
  }
324
334
  async function requestMaintainedUpgrade(input) {
325
335
  const result = await createOpenMeldToolsUpdateCoordinator({}, { executeUpdates: false }).requestUpdate({ requestSource: "cli" });
@@ -448,6 +458,7 @@ async function installAndReconcileBinaryUpgrade(input) {
448
458
  distribution: input.upgradeStatus.distribution,
449
459
  preferredTransport: updatePlan.transport
450
460
  },
461
+ failureCode: "cli.update.install_failed",
451
462
  run: async () => await installLatestCliBinary({
452
463
  release: binaryRelease,
453
464
  manualUpgradeCommand: input.manualUpgradeCommand,
@@ -468,6 +479,7 @@ async function installAndReconcileBinaryUpgrade(input) {
468
479
  code: "upgrade.service_alignment",
469
480
  startedText: SERVICE_CHECK_STARTED_TEXT,
470
481
  completedText: SERVICE_CHECK_COMPLETED_TEXT,
482
+ failureCode: "cli.update.service_alignment_failed",
471
483
  run: async () => await handoffUpgradeServiceAlignmentToLatestBinary({
472
484
  resolvedView: input.resolvedView,
473
485
  command: binaryInstall.managedBinaryPath,
@@ -497,6 +509,7 @@ async function installAndReconcileNpmUpgrade(input) {
497
509
  command: input.manualUpgradeCommand,
498
510
  distribution: input.upgradeStatus.distribution
499
511
  },
512
+ failureCode: "cli.update.install_failed",
500
513
  run: async () => await installLatestPackage({
501
514
  npmCommandSpec,
502
515
  currentGlobalInstall: input.currentGlobalInstall,
@@ -517,6 +530,7 @@ async function installAndReconcileNpmUpgrade(input) {
517
530
  code: "upgrade.service_alignment",
518
531
  startedText: SERVICE_CHECK_STARTED_TEXT,
519
532
  completedText: SERVICE_CHECK_COMPLETED_TEXT,
533
+ failureCode: "cli.update.service_alignment_failed",
520
534
  run: async () => await handoffUpgradeServiceAlignmentToLatestBinary({
521
535
  resolvedView: input.resolvedView,
522
536
  command: process.execPath,
@@ -660,7 +674,7 @@ async function installLatestCliBinary(input) {
660
674
  const tmpDir = await mkdtemp(join(tmpdir(), "openmeld-cli-upgrade-"));
661
675
  try {
662
676
  const artifactBytes = await downloadCliBinaryUpdateArtifact({
663
- downloadTimeoutMs: CLI_BINARY_DOWNLOAD_TIMEOUT_MS,
677
+ downloadPolicy: DEFAULT_CLI_BINARY_DOWNLOAD_POLICY,
664
678
  fetchImpl: fetch,
665
679
  onDeltaFallback: (error) => {
666
680
  process.stderr.write(`Small update could not be used; downloading the full update instead. (${error.message})\n`);
@@ -791,11 +805,14 @@ async function runInternalUpgradeServiceAlignment(input) {
791
805
  });
792
806
  throw new UpgradeOutputHandledError(errorMessage);
793
807
  }
808
+ const updateContext = readOpenMeldToolsUpdateContextFromEnv();
794
809
  const scheduled = await scheduleDaemonServiceUpdate({
795
810
  targetVersion: daemonVersion,
796
811
  ...binaryRelease?.version === daemonVersion ? { binaryRelease } : {},
797
812
  urgency: await resolveServiceUpdateUrgency(),
798
- ...readOpenMeldToolsUpdateContextFromEnv() ?? {},
813
+ ...updateContext ?? {},
814
+ targetCliVersion: OPENMELD_VERSION,
815
+ targetServiceVersion: daemonVersion,
799
816
  ...input.cliScriptPath ? { cliScriptPath: input.cliScriptPath } : {}
800
817
  });
801
818
  if (input.resolvedView === "human") {
@@ -824,6 +841,11 @@ async function handoffUpgradeServiceAlignmentToLatestBinary(input) {
824
841
  UPGRADE_INTERNAL_ALIGN_SERVICE_FLAG
825
842
  ], { OPENMELD_INTERNAL_SKIP_STARTUP_UPGRADE: "1" }, useInheritedOutput);
826
843
  if (handoffResult.code !== 0) {
844
+ const processFailure = parseOpenMeldToolsUpdateFailureFrame(handoffResult.stdout);
845
+ if (processFailure) throw new OpenMeldToolsUpdateFailureError({
846
+ failureCode: processFailure.failureCode,
847
+ message: processFailure.detail
848
+ });
827
849
  if (useInheritedOutput) throw new Error(formatUpgradeReconcileFailureMessage({
828
850
  errorMessage: `latest CLI handoff exited with status ${String(handoffResult.code)}`,
829
851
  backupDataPath: null,
@@ -1034,7 +1056,7 @@ async function runUpgradeStage(input) {
1034
1056
  return result;
1035
1057
  } catch (error) {
1036
1058
  stage.fail(input.failedText ?? `${input.startedText} failed.`);
1037
- throw error;
1059
+ throw input.failureCode ? withOpenMeldToolsUpdateFailure(error, input.failureCode) : error;
1038
1060
  }
1039
1061
  }
1040
1062
  function emitUpgradeCompleted(input) {
@@ -1060,4 +1082,4 @@ function toErrorMessage(error) {
1060
1082
  //#endregion
1061
1083
  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 };
1062
1084
 
1063
- //# sourceMappingURL=upgrade-DJLqTfBA.js.map
1085
+ //# sourceMappingURL=upgrade-9h70HCQP.js.map