@puddle-code/cli 0.2.7 → 0.2.9

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 (138) hide show
  1. package/CHANGELOG.md +7 -3
  2. package/README.md +1 -1
  3. package/dist/host-control.mjs +64 -61
  4. package/dist/index.js +134 -82
  5. package/dist/install.sh +1 -1
  6. package/dist/public/assets/App-CsZmRbS6.js +2 -0
  7. package/dist/public/assets/{Dashboard-BOK1fw_Q.js → Dashboard-DFzjlYtW.js} +1 -1
  8. package/dist/public/assets/{EditorTabClose-CzMQj4jF.js → EditorTabClose-BS7ghHjK.js} +1 -1
  9. package/dist/public/assets/FindWidget-DpVHrnVy.js +1 -0
  10. package/dist/public/assets/LazyTerminal-Pgz-4Lze.js +2 -0
  11. package/dist/public/assets/{ModelRefcount-F2Tf2V5f.js → ModelRefcount-DFwiYH-p.js} +1 -1
  12. package/dist/public/assets/{NewProjectDialog-CoI17sqS.js → NewProjectDialog-C9aSKTSk.js} +1 -1
  13. package/dist/public/assets/{PaneEditorBody-57BHgi2R.js → PaneEditorBody-DMTbgyGp.js} +4 -4
  14. package/dist/public/assets/{PdfViewer-T-uYvXEd.js → PdfViewer-CA5wELHb.js} +2 -2
  15. package/dist/public/assets/SettingsDialog-2wP0SNBO.js +8 -0
  16. package/dist/public/assets/Terminal-xHpm_bwv.js +61 -0
  17. package/dist/public/assets/Workspace-68eUOGPi.js +20 -0
  18. package/dist/public/assets/{Workspace-B6mgQyIM.css → Workspace-DdBCUbGN.css} +1 -1
  19. package/dist/public/assets/{abnfDiagram-VCTEODGH-Dl2GTGCZ.js → abnfDiagram-VCTEODGH-BMN1VDL4.js} +1 -1
  20. package/dist/public/assets/architecture-7GRP2DOG-5Ju3pdRo.js +1 -0
  21. package/dist/public/assets/{architectureDiagram-5GKGNRK7-TLkiib9Z.js → architectureDiagram-5GKGNRK7-B0YVX4zU.js} +1 -1
  22. package/dist/public/assets/{blockDiagram-I7D4REHJ-CFdDK-5H.js → blockDiagram-I7D4REHJ--GL1UNdu.js} +1 -1
  23. package/dist/public/assets/{buffer-store-Pex0dRS2.js → buffer-store-ZYgNwEDO.js} +2 -2
  24. package/dist/public/assets/{button-IwQVXqQs.js → button-BWuyGmaa.js} +1 -1
  25. package/dist/public/assets/{c4Diagram-7LVT6UL2-9M5y_7Rr.js → c4Diagram-7LVT6UL2-CrKkcxQB.js} +1 -1
  26. package/dist/public/assets/channel-BnUqvaBX.js +1 -0
  27. package/dist/public/assets/{chunk-2E4U76K2-BEq-rPTx.js → chunk-2E4U76K2-B8SWO3Xm.js} +1 -1
  28. package/dist/public/assets/{chunk-4HAMMTFA-DSsufXZj.js → chunk-4HAMMTFA-BSby2uNB.js} +1 -1
  29. package/dist/public/assets/{chunk-75Z2AOVW-CUihRphW.js → chunk-75Z2AOVW-lp4AU0nr.js} +1 -1
  30. package/dist/public/assets/{chunk-CLGD4ZFX-8FntHoH6.js → chunk-CLGD4ZFX-DhJtVYVa.js} +1 -1
  31. package/dist/public/assets/{chunk-DU6HZSFF-BhI6mdvA.js → chunk-DU6HZSFF-PTA8yYRS.js} +1 -1
  32. package/dist/public/assets/{chunk-F27PBJKO-CflkfzDR.js → chunk-F27PBJKO-BkzgbSs-.js} +1 -1
  33. package/dist/public/assets/{chunk-GMAD6QVW-C6sQnCBM.js → chunk-GMAD6QVW-Cuh7owM4.js} +1 -1
  34. package/dist/public/assets/{chunk-GVQU2GXP-BTEA9yBL.js → chunk-GVQU2GXP-iRfBGsQq.js} +1 -1
  35. package/dist/public/assets/{chunk-IMKFNOWR-BTN8pZaT.js → chunk-IMKFNOWR-B4vSM7Xn.js} +1 -1
  36. package/dist/public/assets/{chunk-L3NEJ4N5-CPMRHY2b.js → chunk-L3NEJ4N5-DBrhDuI7.js} +1 -1
  37. package/dist/public/assets/{chunk-OSK3NFVY-D62Fb29m.js → chunk-OSK3NFVY-COiVXRLk.js} +1 -1
  38. package/dist/public/assets/{chunk-P2QGCYS3-B_AAuki5.js → chunk-P2QGCYS3-CIVq3YEs.js} +1 -1
  39. package/dist/public/assets/{chunk-POPQ4Y6H-C-wGGj3u.js → chunk-POPQ4Y6H-Cl_cmH3h.js} +1 -1
  40. package/dist/public/assets/{chunk-PWAF6VOD-DElrnMgG.js → chunk-PWAF6VOD-DS_qQYSo.js} +1 -1
  41. package/dist/public/assets/{chunk-SHT3W25Y-D4tV8JU2.js → chunk-SHT3W25Y-D5NIF4fA.js} +1 -1
  42. package/dist/public/assets/{chunk-SVP7TREG-CFj2bSX9.js → chunk-SVP7TREG-C7WQVYys.js} +1 -1
  43. package/dist/public/assets/{chunk-TICWLB2K-B-5yvDQM.js → chunk-TICWLB2K-BUBKhbbM.js} +1 -1
  44. package/dist/public/assets/{chunk-TLUHSLCS-CpBFfaGS.js → chunk-TLUHSLCS-DaAUWGh9.js} +2 -2
  45. package/dist/public/assets/classDiagram-ZZMXUADV-P6ICFC70.js +1 -0
  46. package/dist/public/assets/classDiagram-v2-VYDZK3BY-P6ICFC70.js +1 -0
  47. package/dist/public/assets/{context-menu-Bh2z-xpu.js → context-menu-D-O7u4s5.js} +1 -1
  48. package/dist/public/assets/{cssMode-iZ32bnYe.js → cssMode-DXErBJEE.js} +1 -1
  49. package/dist/public/assets/{cynefin-OW5HDTMX-D5BzXyX_.js → cynefin-OW5HDTMX-BscqyxWP.js} +1 -1
  50. package/dist/public/assets/{cynefinDiagram-5FMLGOSQ-CdbgNH0t.js → cynefinDiagram-5FMLGOSQ-DYR6jijD.js} +1 -1
  51. package/dist/public/assets/{dagre-GXQ25YYZ-B7zDDwyp.js → dagre-GXQ25YYZ-D45211ER.js} +1 -1
  52. package/dist/public/assets/{diagram-S7CK7UJ4-WMtT-mtt.js → diagram-S7CK7UJ4-CLj1WRTR.js} +1 -1
  53. package/dist/public/assets/{diagram-UQ7AKVKN-DtvvWbC3.js → diagram-UQ7AKVKN-D6NOh7m9.js} +1 -1
  54. package/dist/public/assets/{diagram-VSXAHHWV-DBLLhbuk.js → diagram-VSXAHHWV-CeFz_BgE.js} +1 -1
  55. package/dist/public/assets/{diagram-VX7I27RA-6sDOwqqU.js → diagram-VX7I27RA-teDEG59v.js} +1 -1
  56. package/dist/public/assets/{diagram-Z3DM3KII-giEr0RfN.js → diagram-Z3DM3KII-BJCJhoEY.js} +1 -1
  57. package/dist/public/assets/dialog-9iVPI51D.js +41 -0
  58. package/dist/public/assets/disclosure-QzGtr4V5.js +1 -0
  59. package/dist/public/assets/{dist-ujnACQRA.js → dist-CnYnPLyF.js} +1 -1
  60. package/dist/public/assets/{dist-C1IA4PaM.js → dist-DpZlGsf_.js} +1 -1
  61. package/dist/public/assets/{ebnfDiagram-PWID7BFC-CDfLo0uv.js → ebnfDiagram-PWID7BFC-BJRvP46E.js} +1 -1
  62. package/dist/public/assets/{erDiagram-RLTQ6QDP-z5xLMSlR.js → erDiagram-RLTQ6QDP-C9g-1TKf.js} +1 -1
  63. package/dist/public/assets/eventmodeling-NTZA5JFV-Dvr2mBv2.js +1 -0
  64. package/dist/public/assets/flowDiagram-HODETNUW-DLOvfV5L.js +1 -0
  65. package/dist/public/assets/{ganttDiagram-EL5Y4UJY-C2poetEB.js → ganttDiagram-EL5Y4UJY-DZi46oV6.js} +1 -1
  66. package/dist/public/assets/{gitGraph-4MIJSDKK-D40KkO3l.js → gitGraph-4MIJSDKK-CibdMHSY.js} +1 -1
  67. package/dist/public/assets/{gitGraphDiagram-WWUBYQGX-B4839p8c.js → gitGraphDiagram-WWUBYQGX-BqOBe4tD.js} +1 -1
  68. package/dist/public/assets/{hotkeys-CY98l7MF.js → hotkeys-DbpnYjRZ.js} +1 -1
  69. package/dist/public/assets/{htmlMode-XXBiFVzW.js → htmlMode-c5xA7YRy.js} +1 -1
  70. package/dist/public/assets/{index-uKreLbru.css → index-C4dY_r6p.css} +1 -1
  71. package/dist/public/assets/index-CzOmrbzA.js +82 -0
  72. package/dist/public/assets/{info-A6RAGUB7-R6D6gcdH.js → info-A6RAGUB7-D0wGtDnd.js} +1 -1
  73. package/dist/public/assets/{infoDiagram-27XIBGKW-CQMe7eLM.js → infoDiagram-27XIBGKW-FJ20a3N_.js} +1 -1
  74. package/dist/public/assets/{ishikawaDiagram-5VMMS53U-hWJnyGf_.js → ishikawaDiagram-5VMMS53U-D3mIgaMn.js} +1 -1
  75. package/dist/public/assets/{journeyDiagram-3NMN7TZE-DRy7w8VL.js → journeyDiagram-3NMN7TZE-DSisKIqi.js} +1 -1
  76. package/dist/public/assets/{jsonMode-B4KgbobV.js → jsonMode-C8UDm-Ys.js} +1 -1
  77. package/dist/public/assets/{kanban-definition-UXKFOSKX-Dvv0eWiD.js → kanban-definition-UXKFOSKX-CzCo1cog.js} +1 -1
  78. package/dist/public/assets/{line-K2RkIT6o.js → line-DNhFIxWX.js} +1 -1
  79. package/dist/public/assets/{media-refresh-store-OAgBTFYO.js → media-refresh-store-CxdH4fIV.js} +1 -1
  80. package/dist/public/assets/{mermaid-parser.core-B36v6vc8.js → mermaid-parser.core-BIsVpVNk.js} +3 -3
  81. package/dist/public/assets/{mermaid.core-kqdkh9ua.js → mermaid.core-60pgXGV4.js} +3 -3
  82. package/dist/public/assets/{mindmap-definition-YA3MSWOX-CykDXfif.js → mindmap-definition-YA3MSWOX-_BDULKeN.js} +1 -1
  83. package/dist/public/assets/{notification-permission-B9hBLJAo.js → notification-permission-CqGfmzjr.js} +1 -1
  84. package/dist/public/assets/{packet-AYTQ26CC-BDu33u4C.js → packet-AYTQ26CC-DubEpIB-.js} +1 -1
  85. package/dist/public/assets/{pdf-BTD1hhPr.js → pdf-BWq_ZJKv.js} +1 -1
  86. package/dist/public/assets/{pegDiagram-XKGWAZYB-DWdbGFng.js → pegDiagram-XKGWAZYB-CoE18oYx.js} +1 -1
  87. package/dist/public/assets/{pie-WAS4IAKB-CeKUt-Xf.js → pie-WAS4IAKB-Dodjqs5B.js} +1 -1
  88. package/dist/public/assets/{pieDiagram-E7YTZNPT-D94ZuRp2.js → pieDiagram-E7YTZNPT-3dgoeKzj.js} +1 -1
  89. package/dist/public/assets/{project-abbrev-E6FngLNw.js → project-abbrev-5Pm98PEg.js} +1 -1
  90. package/dist/public/assets/{quadrantDiagram-AXDQQJYC-DXkTGcPo.js → quadrantDiagram-AXDQQJYC-BmkaNIIn.js} +1 -1
  91. package/dist/public/assets/{radar-RG4KPBEZ-C1wtnYrQ.js → radar-RG4KPBEZ-BYYc-wiA.js} +1 -1
  92. package/dist/public/assets/{railroad-74A4TZTK-Dx_D-zM9.js → railroad-74A4TZTK-BcZRAOQ9.js} +1 -1
  93. package/dist/public/assets/railroad-abnf-HS5TGJTU-D6pmmT2l.js +1 -0
  94. package/dist/public/assets/railroad-ebnf-LZEXJU2U-B460-0k9.js +1 -0
  95. package/dist/public/assets/railroad-peg-WCYAUIDC-CIw33RrY.js +1 -0
  96. package/dist/public/assets/{railroadDiagram-O6MQD6OU-DVuwN3bC.js → railroadDiagram-O6MQD6OU-B2LfjrEa.js} +1 -1
  97. package/dist/public/assets/{requirementDiagram-BXWQKSXE-nX3JtB1N.js → requirementDiagram-BXWQKSXE-DY8jamVI.js} +1 -1
  98. package/dist/public/assets/{sankeyDiagram-P5KCCOFB-DvErANKF.js → sankeyDiagram-P5KCCOFB-DBA4B97a.js} +1 -1
  99. package/dist/public/assets/selection-actions-d_fZEbcE.js +1 -0
  100. package/dist/public/assets/{sequenceDiagram-WJ2MYXX4-BruH0Mma.js → sequenceDiagram-WJ2MYXX4-BGw0T5v0.js} +1 -1
  101. package/dist/public/assets/{stateDiagram-D77RDMKH-BMiYrZ8Y.js → stateDiagram-D77RDMKH-Cpwdu5FR.js} +1 -1
  102. package/dist/public/assets/stateDiagram-v2-MP3YSRHH-CHpyNdbC.js +1 -0
  103. package/dist/public/assets/{swimlanes-42K2YHIH-CK3jGfyc.js → swimlanes-42K2YHIH-PQxrcHPG.js} +1 -1
  104. package/dist/public/assets/swimlanesDiagram-VR7AAH4N-zUN4_x9d.js +8 -0
  105. package/dist/public/assets/{switch-BrFrNOcn.js → switch-i3-jBrqY.js} +1 -1
  106. package/dist/public/assets/{timeline-definition-24CTP7MA-DHf_pf2_.js → timeline-definition-24CTP7MA-B-7OPl78.js} +1 -1
  107. package/dist/public/assets/{treeView-Q6P3EWNA-C5uB7_Kg.js → treeView-Q6P3EWNA-mXktY_p2.js} +1 -1
  108. package/dist/public/assets/{treemap-WGGIJYW6-BGzjaDxJ.js → treemap-WGGIJYW6-pdcutOnh.js} +1 -1
  109. package/dist/public/assets/{tsMode-C39Hmal5.js → tsMode-Bk-Av6tY.js} +1 -1
  110. package/dist/public/assets/{use-ui-state-D5kpevK-.js → use-ui-state-Dq1uo2ic.js} +1 -1
  111. package/dist/public/assets/{vennDiagram-4TSXK5OY-9mb8KINT.js → vennDiagram-4TSXK5OY-mJ8VQ8yi.js} +1 -1
  112. package/dist/public/assets/{wardley-WFR3VGLG-DW5VvBTA.js → wardley-WFR3VGLG--3zrePoQ.js} +1 -1
  113. package/dist/public/assets/{wardleyDiagram-VM6X3IG4-DCM5g6RC.js → wardleyDiagram-VM6X3IG4-BCZQVaoz.js} +1 -1
  114. package/dist/public/assets/{ws-BZ4-LssP.js → ws-Byj2wv_K.js} +1 -1
  115. package/dist/public/assets/{xychartDiagram-S5SC5T6Z-Bks8gKZc.js → xychartDiagram-S5SC5T6Z-D0DiMR0y.js} +1 -1
  116. package/dist/public/index.html +2 -2
  117. package/package.json +1 -1
  118. package/dist/public/assets/App-BkCGcO4p.js +0 -2
  119. package/dist/public/assets/FindWidget-6LifDkeS.js +0 -1
  120. package/dist/public/assets/LazyTerminal-Beep0VuJ.js +0 -2
  121. package/dist/public/assets/SettingsDialog-CkBdXZyv.js +0 -8
  122. package/dist/public/assets/Terminal-CJMmk0kO.js +0 -60
  123. package/dist/public/assets/Workspace-0P5NTRzC.js +0 -20
  124. package/dist/public/assets/architecture-7GRP2DOG-UXEF_VQt.js +0 -1
  125. package/dist/public/assets/channel-D3NmDqec.js +0 -1
  126. package/dist/public/assets/classDiagram-ZZMXUADV-8X6mwi75.js +0 -1
  127. package/dist/public/assets/classDiagram-v2-VYDZK3BY-8X6mwi75.js +0 -1
  128. package/dist/public/assets/dialog-ClHoWaGa.js +0 -41
  129. package/dist/public/assets/disclosure-Ch2qCUT3.js +0 -1
  130. package/dist/public/assets/eventmodeling-NTZA5JFV-CzmQ0jM3.js +0 -1
  131. package/dist/public/assets/flowDiagram-HODETNUW-_tJIQrw7.js +0 -1
  132. package/dist/public/assets/index-D0Lm0Z_9.js +0 -82
  133. package/dist/public/assets/input-BUZTRTzW.js +0 -1
  134. package/dist/public/assets/railroad-abnf-HS5TGJTU-CBfnoAOv.js +0 -1
  135. package/dist/public/assets/railroad-ebnf-LZEXJU2U-0kuF9A11.js +0 -1
  136. package/dist/public/assets/railroad-peg-WCYAUIDC-DCe0oM6p.js +0 -1
  137. package/dist/public/assets/stateDiagram-v2-MP3YSRHH-CF86bnO8.js +0 -1
  138. package/dist/public/assets/swimlanesDiagram-VR7AAH4N-COC62XcR.js +0 -8
package/CHANGELOG.md CHANGED
@@ -4,12 +4,16 @@ Archived release changelog. Governance lives in CLAUDE.md §"Changelog disciplin
4
4
 
5
5
  # Changelog
6
6
 
7
- ## [0.2.7] — 2026-09-23
7
+ ## [0.2.9] — 2026-09-25
8
8
 
9
9
  ### Changed
10
10
 
11
- - Allow an empty project default base branch to follow the branch currently checked out at the clone location for each new agent or terminal; retain explicit branch choices (daemon/cockpit protocol 21.3; remote protocol remains 2).
11
+ - Simplify mobile change review and show vertically stacked Before/After sections with line numbers, addition/deletion colours and changed-word highlights.
12
12
 
13
13
  ### Fixed
14
14
 
15
- - Fix CI deployment validation by creating a private temporary service environment file from the checked-in example before resolving the Compose configuration.
15
+ - Clarify browser approval instructions with the Connected browsers settings path.
16
+ - Insert a chosen mobile image's path into the composer draft when it was the last input used, instead of always into the terminal.
17
+ - Remove the spurious gap between the Connected browsers and Host identity recovery disclosures.
18
+ - Make the iOS spacebar trackpad send one arrow key per step in its direction, without exploding at line boundaries.
19
+ - Keep the mobile keyboard focused during rapid terminal key-strip taps without duplicating commands, and raise it from any tap on the strip.
package/README.md CHANGED
@@ -56,7 +56,7 @@ This connects Puddle to the remote host over SSH, bootstrapping the Puddle daemo
56
56
 
57
57
  **To connect from a phone or another browser over the internet:** deploy your own
58
58
  [mobile access service and trusted web application](docs/mobile-access.md), then
59
- use `puddle remote enable` and `puddle remote pair`. The host connects outward;
59
+ use `puddle remote enable --profile <profile-id>` and `puddle remote pair --profile <profile-id>`. Each profile registers independently. The host connects outward;
60
60
  there is no public daemon port or VPN requirement. Each browser needs explicit
61
61
  host approval. The phone view provides live terminals, prompt input and read-only
62
62
  text/diff review over a pinned Noise connection through the relay.
@@ -15775,7 +15775,7 @@ var wsServerMessageSchema = external_exports.discriminatedUnion("t", [
15775
15775
  ]);
15776
15776
 
15777
15777
  // ../shared/src/remote/protocol.ts
15778
- var REMOTE_PROTOCOL_VERSION = 2;
15778
+ var REMOTE_PROTOCOL_VERSION = 3;
15779
15779
  var REMOTE_POLICY = {
15780
15780
  chunkBytes: 32 * 1024,
15781
15781
  frameBytes: 48 * 1024,
@@ -15896,6 +15896,65 @@ var remoteChunkSchema = external_exports.object({
15896
15896
  data: external_exports.string().max(REMOTE_POLICY.chunkBytes)
15897
15897
  }).strict();
15898
15898
 
15899
+ // ../shared/src/remote/service.ts
15900
+ var remoteHostSchema = external_exports.object({
15901
+ id: remoteIdSchema,
15902
+ label: remoteLabelSchema,
15903
+ online: external_exports.boolean()
15904
+ });
15905
+ var remoteHostsSchema = external_exports.array(remoteHostSchema);
15906
+ var remoteServiceInfoSchema = external_exports.object({
15907
+ providers: external_exports.array(external_exports.enum(["google", "github"])),
15908
+ protocol: external_exports.literal(REMOTE_PROTOCOL_VERSION)
15909
+ });
15910
+ var remoteLoginStateSchema = external_exports.object({
15911
+ user: external_exports.object({
15912
+ id: remoteAccountSchema,
15913
+ name: external_exports.string(),
15914
+ email: external_exports.string(),
15915
+ emailVerified: external_exports.boolean(),
15916
+ twoFactorEnabled: external_exports.boolean()
15917
+ }).nullable(),
15918
+ mfaRequired: external_exports.boolean()
15919
+ });
15920
+ var registerHostRequestSchema = external_exports.object({ label: remoteLabelSchema }).strict();
15921
+ var registrationResponseSchema = external_exports.object({ host: remoteIdSchema, code: remoteSecretSchema, expires: external_exports.number() }).strict();
15922
+ var redeemRegistrationSchema = external_exports.object({ code: remoteSecretSchema }).strict();
15923
+ var unregisterHostRequestSchema = external_exports.object({ credential: remoteSecretSchema }).strict();
15924
+ var desktopRegistrationSchema = external_exports.object({
15925
+ challenge: remoteSecretSchema,
15926
+ label: remoteLabelSchema,
15927
+ service: remoteOriginSchema,
15928
+ app: remoteOriginSchema,
15929
+ expires: external_exports.number().int().positive()
15930
+ }).strict();
15931
+ var registrationStatusSchema = external_exports.object({ ready: external_exports.boolean() }).strict();
15932
+ var connectorRegistrationSchema = external_exports.object({
15933
+ host: remoteIdSchema,
15934
+ account: remoteAccountSchema,
15935
+ credential: remoteSecretSchema
15936
+ }).strict();
15937
+ var connectorConfigSchema = connectorRegistrationSchema.extend({
15938
+ service: remoteOriginSchema,
15939
+ app: remoteOriginSchema,
15940
+ enabled: external_exports.boolean()
15941
+ }).strict();
15942
+ var connectorSetupSchema = external_exports.object({
15943
+ service: remoteOriginSchema.optional(),
15944
+ app: remoteOriginSchema.optional(),
15945
+ code: remoteSecretSchema.optional(),
15946
+ managed: external_exports.boolean().default(true)
15947
+ }).strict();
15948
+ var remoteIdentitySchema = external_exports.array(external_exports.number().int().min(0).max(255)).min(32).max(256);
15949
+ var remoteBrowserHostSchema = external_exports.object({
15950
+ host: remoteIdSchema,
15951
+ peer: remotePeerSchema,
15952
+ account: remoteAccountSchema,
15953
+ service: remoteOriginSchema,
15954
+ label: external_exports.string(),
15955
+ privateKey: remoteIdentitySchema
15956
+ }).strict();
15957
+
15899
15958
  // ../shared/src/api/cockpit-remote.ts
15900
15959
  var connectorLocalRequestSchema = external_exports.union([
15901
15960
  remoteAdminRequestSchema,
@@ -15923,6 +15982,9 @@ var cockpitRemoteStatusSchema = external_exports.object({
15923
15982
  app: remoteOriginSchema.optional(),
15924
15983
  devices: external_exports.array(remoteDeviceSchema)
15925
15984
  });
15985
+ var connectorProfileSchema = external_exports.object({ profile: profileId }).strict();
15986
+ var connectorAdminSchema = external_exports.object({ profile: profileId, request: connectorLocalRequestSchema }).strict();
15987
+ var connectorConfigureSchema = external_exports.object({ profile: profileId, setup: connectorSetupSchema }).strict();
15926
15988
 
15927
15989
  // ../shared/src/api/connection-auth.ts
15928
15990
  var CONNECTION_POLICY = {
@@ -15945,7 +16007,7 @@ var authErrorCodeSchema = external_exports.enum([
15945
16007
  "protocol_mismatch"
15946
16008
  ]);
15947
16009
  var controlRequestSchema = external_exports.discriminatedUnion("t", [
15948
- external_exports.object({ t: external_exports.literal("open") }).strict(),
16010
+ external_exports.object({ t: external_exports.literal("open"), profile: profileId.optional() }).strict(),
15949
16011
  external_exports.object({ t: external_exports.literal("renew"), resources: external_exports.array(resourceIdSchema).max(2048) }).strict(),
15950
16012
  external_exports.object({ t: external_exports.literal("close") }).strict()
15951
16013
  ]);
@@ -16034,65 +16096,6 @@ var imageUploadProgressSchema = external_exports.object({
16034
16096
  received: external_exports.number().int().nonnegative().max(IMAGE_UPLOAD_POLICY.imageBytes)
16035
16097
  });
16036
16098
 
16037
- // ../shared/src/remote/service.ts
16038
- var remoteHostSchema = external_exports.object({
16039
- id: remoteIdSchema,
16040
- label: remoteLabelSchema,
16041
- online: external_exports.boolean()
16042
- });
16043
- var remoteHostsSchema = external_exports.array(remoteHostSchema);
16044
- var remoteServiceInfoSchema = external_exports.object({
16045
- providers: external_exports.array(external_exports.enum(["google", "github"])),
16046
- protocol: external_exports.literal(REMOTE_PROTOCOL_VERSION)
16047
- });
16048
- var remoteLoginStateSchema = external_exports.object({
16049
- user: external_exports.object({
16050
- id: remoteAccountSchema,
16051
- name: external_exports.string(),
16052
- email: external_exports.string(),
16053
- emailVerified: external_exports.boolean(),
16054
- twoFactorEnabled: external_exports.boolean()
16055
- }).nullable(),
16056
- mfaRequired: external_exports.boolean()
16057
- });
16058
- var registerHostRequestSchema = external_exports.object({ label: remoteLabelSchema }).strict();
16059
- var registrationResponseSchema = external_exports.object({ host: remoteIdSchema, code: remoteSecretSchema, expires: external_exports.number() }).strict();
16060
- var redeemRegistrationSchema = external_exports.object({ code: remoteSecretSchema }).strict();
16061
- var unregisterHostRequestSchema = external_exports.object({ credential: remoteSecretSchema }).strict();
16062
- var desktopRegistrationSchema = external_exports.object({
16063
- challenge: remoteSecretSchema,
16064
- label: remoteLabelSchema,
16065
- service: remoteOriginSchema,
16066
- app: remoteOriginSchema,
16067
- expires: external_exports.number().int().positive()
16068
- }).strict();
16069
- var registrationStatusSchema = external_exports.object({ ready: external_exports.boolean() }).strict();
16070
- var connectorRegistrationSchema = external_exports.object({
16071
- host: remoteIdSchema,
16072
- account: remoteAccountSchema,
16073
- credential: remoteSecretSchema
16074
- }).strict();
16075
- var connectorConfigSchema = connectorRegistrationSchema.extend({
16076
- service: remoteOriginSchema,
16077
- app: remoteOriginSchema,
16078
- enabled: external_exports.boolean()
16079
- }).strict();
16080
- var connectorSetupSchema = external_exports.object({
16081
- service: remoteOriginSchema.optional(),
16082
- app: remoteOriginSchema.optional(),
16083
- code: remoteSecretSchema.optional(),
16084
- managed: external_exports.boolean().default(true)
16085
- }).strict();
16086
- var remoteIdentitySchema = external_exports.array(external_exports.number().int().min(0).max(255)).min(32).max(256);
16087
- var remoteBrowserHostSchema = external_exports.object({
16088
- host: remoteIdSchema,
16089
- peer: remotePeerSchema,
16090
- account: remoteAccountSchema,
16091
- service: remoteOriginSchema,
16092
- label: external_exports.string(),
16093
- privateKey: remoteIdentitySchema
16094
- }).strict();
16095
-
16096
16099
  // ../shared/src/node/security.ts
16097
16100
  import { createHash, randomBytes } from "node:crypto";
16098
16101
  import {
package/dist/index.js CHANGED
@@ -3925,7 +3925,7 @@ import { createInterface } from "node:readline";
3925
3925
  import { Writable } from "node:stream";
3926
3926
 
3927
3927
  // ../shared/src/protocol.ts
3928
- var PROTOCOL_VERSION = { major: 21, minor: 3 };
3928
+ var PROTOCOL_VERSION = { major: 22, minor: 0 };
3929
3929
 
3930
3930
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
3931
3931
  var external_exports = {};
@@ -19695,7 +19695,7 @@ var wsServerMessageSchema = external_exports.discriminatedUnion("t", [
19695
19695
  ]);
19696
19696
 
19697
19697
  // ../shared/src/remote/protocol.ts
19698
- var REMOTE_PROTOCOL_VERSION = 2;
19698
+ var REMOTE_PROTOCOL_VERSION = 3;
19699
19699
  var REMOTE_POLICY = {
19700
19700
  chunkBytes: 32 * 1024,
19701
19701
  frameBytes: 48 * 1024,
@@ -19816,6 +19816,65 @@ var remoteChunkSchema = external_exports.object({
19816
19816
  data: external_exports.string().max(REMOTE_POLICY.chunkBytes)
19817
19817
  }).strict();
19818
19818
 
19819
+ // ../shared/src/remote/service.ts
19820
+ var remoteHostSchema = external_exports.object({
19821
+ id: remoteIdSchema,
19822
+ label: remoteLabelSchema,
19823
+ online: external_exports.boolean()
19824
+ });
19825
+ var remoteHostsSchema = external_exports.array(remoteHostSchema);
19826
+ var remoteServiceInfoSchema = external_exports.object({
19827
+ providers: external_exports.array(external_exports.enum(["google", "github"])),
19828
+ protocol: external_exports.literal(REMOTE_PROTOCOL_VERSION)
19829
+ });
19830
+ var remoteLoginStateSchema = external_exports.object({
19831
+ user: external_exports.object({
19832
+ id: remoteAccountSchema,
19833
+ name: external_exports.string(),
19834
+ email: external_exports.string(),
19835
+ emailVerified: external_exports.boolean(),
19836
+ twoFactorEnabled: external_exports.boolean()
19837
+ }).nullable(),
19838
+ mfaRequired: external_exports.boolean()
19839
+ });
19840
+ var registerHostRequestSchema = external_exports.object({ label: remoteLabelSchema }).strict();
19841
+ var registrationResponseSchema = external_exports.object({ host: remoteIdSchema, code: remoteSecretSchema, expires: external_exports.number() }).strict();
19842
+ var redeemRegistrationSchema = external_exports.object({ code: remoteSecretSchema }).strict();
19843
+ var unregisterHostRequestSchema = external_exports.object({ credential: remoteSecretSchema }).strict();
19844
+ var desktopRegistrationSchema = external_exports.object({
19845
+ challenge: remoteSecretSchema,
19846
+ label: remoteLabelSchema,
19847
+ service: remoteOriginSchema,
19848
+ app: remoteOriginSchema,
19849
+ expires: external_exports.number().int().positive()
19850
+ }).strict();
19851
+ var registrationStatusSchema = external_exports.object({ ready: external_exports.boolean() }).strict();
19852
+ var connectorRegistrationSchema = external_exports.object({
19853
+ host: remoteIdSchema,
19854
+ account: remoteAccountSchema,
19855
+ credential: remoteSecretSchema
19856
+ }).strict();
19857
+ var connectorConfigSchema = connectorRegistrationSchema.extend({
19858
+ service: remoteOriginSchema,
19859
+ app: remoteOriginSchema,
19860
+ enabled: external_exports.boolean()
19861
+ }).strict();
19862
+ var connectorSetupSchema = external_exports.object({
19863
+ service: remoteOriginSchema.optional(),
19864
+ app: remoteOriginSchema.optional(),
19865
+ code: remoteSecretSchema.optional(),
19866
+ managed: external_exports.boolean().default(true)
19867
+ }).strict();
19868
+ var remoteIdentitySchema = external_exports.array(external_exports.number().int().min(0).max(255)).min(32).max(256);
19869
+ var remoteBrowserHostSchema = external_exports.object({
19870
+ host: remoteIdSchema,
19871
+ peer: remotePeerSchema,
19872
+ account: remoteAccountSchema,
19873
+ service: remoteOriginSchema,
19874
+ label: external_exports.string(),
19875
+ privateKey: remoteIdentitySchema
19876
+ }).strict();
19877
+
19819
19878
  // ../shared/src/api/cockpit-remote.ts
19820
19879
  var connectorLocalRequestSchema = external_exports.union([
19821
19880
  remoteAdminRequestSchema,
@@ -19843,6 +19902,9 @@ var cockpitRemoteStatusSchema = external_exports.object({
19843
19902
  app: remoteOriginSchema.optional(),
19844
19903
  devices: external_exports.array(remoteDeviceSchema)
19845
19904
  });
19905
+ var connectorProfileSchema = external_exports.object({ profile: profileId }).strict();
19906
+ var connectorAdminSchema = external_exports.object({ profile: profileId, request: connectorLocalRequestSchema }).strict();
19907
+ var connectorConfigureSchema = external_exports.object({ profile: profileId, setup: connectorSetupSchema }).strict();
19846
19908
 
19847
19909
  // ../shared/src/api/connection-auth.ts
19848
19910
  var CONNECTION_POLICY = {
@@ -19865,7 +19927,7 @@ var authErrorCodeSchema = external_exports.enum([
19865
19927
  "protocol_mismatch"
19866
19928
  ]);
19867
19929
  var controlRequestSchema = external_exports.discriminatedUnion("t", [
19868
- external_exports.object({ t: external_exports.literal("open") }).strict(),
19930
+ external_exports.object({ t: external_exports.literal("open"), profile: profileId.optional() }).strict(),
19869
19931
  external_exports.object({ t: external_exports.literal("renew"), resources: external_exports.array(resourceIdSchema).max(2048) }).strict(),
19870
19932
  external_exports.object({ t: external_exports.literal("close") }).strict()
19871
19933
  ]);
@@ -19954,65 +20016,6 @@ var imageUploadProgressSchema = external_exports.object({
19954
20016
  received: external_exports.number().int().nonnegative().max(IMAGE_UPLOAD_POLICY.imageBytes)
19955
20017
  });
19956
20018
 
19957
- // ../shared/src/remote/service.ts
19958
- var remoteHostSchema = external_exports.object({
19959
- id: remoteIdSchema,
19960
- label: remoteLabelSchema,
19961
- online: external_exports.boolean()
19962
- });
19963
- var remoteHostsSchema = external_exports.array(remoteHostSchema);
19964
- var remoteServiceInfoSchema = external_exports.object({
19965
- providers: external_exports.array(external_exports.enum(["google", "github"])),
19966
- protocol: external_exports.literal(REMOTE_PROTOCOL_VERSION)
19967
- });
19968
- var remoteLoginStateSchema = external_exports.object({
19969
- user: external_exports.object({
19970
- id: remoteAccountSchema,
19971
- name: external_exports.string(),
19972
- email: external_exports.string(),
19973
- emailVerified: external_exports.boolean(),
19974
- twoFactorEnabled: external_exports.boolean()
19975
- }).nullable(),
19976
- mfaRequired: external_exports.boolean()
19977
- });
19978
- var registerHostRequestSchema = external_exports.object({ label: remoteLabelSchema }).strict();
19979
- var registrationResponseSchema = external_exports.object({ host: remoteIdSchema, code: remoteSecretSchema, expires: external_exports.number() }).strict();
19980
- var redeemRegistrationSchema = external_exports.object({ code: remoteSecretSchema }).strict();
19981
- var unregisterHostRequestSchema = external_exports.object({ credential: remoteSecretSchema }).strict();
19982
- var desktopRegistrationSchema = external_exports.object({
19983
- challenge: remoteSecretSchema,
19984
- label: remoteLabelSchema,
19985
- service: remoteOriginSchema,
19986
- app: remoteOriginSchema,
19987
- expires: external_exports.number().int().positive()
19988
- }).strict();
19989
- var registrationStatusSchema = external_exports.object({ ready: external_exports.boolean() }).strict();
19990
- var connectorRegistrationSchema = external_exports.object({
19991
- host: remoteIdSchema,
19992
- account: remoteAccountSchema,
19993
- credential: remoteSecretSchema
19994
- }).strict();
19995
- var connectorConfigSchema = connectorRegistrationSchema.extend({
19996
- service: remoteOriginSchema,
19997
- app: remoteOriginSchema,
19998
- enabled: external_exports.boolean()
19999
- }).strict();
20000
- var connectorSetupSchema = external_exports.object({
20001
- service: remoteOriginSchema.optional(),
20002
- app: remoteOriginSchema.optional(),
20003
- code: remoteSecretSchema.optional(),
20004
- managed: external_exports.boolean().default(true)
20005
- }).strict();
20006
- var remoteIdentitySchema = external_exports.array(external_exports.number().int().min(0).max(255)).min(32).max(256);
20007
- var remoteBrowserHostSchema = external_exports.object({
20008
- host: remoteIdSchema,
20009
- peer: remotePeerSchema,
20010
- account: remoteAccountSchema,
20011
- service: remoteOriginSchema,
20012
- label: external_exports.string(),
20013
- privateKey: remoteIdentitySchema
20014
- }).strict();
20015
-
20016
20019
  // src/lib/transport/local.ts
20017
20020
  import { spawn } from "node:child_process";
20018
20021
  import { copyFileSync, mkdirSync, readFileSync } from "node:fs";
@@ -20341,7 +20344,12 @@ function parseRemoteArgs(args) {
20341
20344
  for (let i = 0; i < rest.length; i++) {
20342
20345
  const arg = rest[i];
20343
20346
  if (arg === "--foreground") command.foreground = true;
20344
- else if (arg === "--service" || arg === "--app-origin") {
20347
+ else if (arg === "--profile") {
20348
+ const parsed = profileId.safeParse(rest[++i]);
20349
+ if (!parsed.success)
20350
+ throw new CliError("bad_arguments", "--profile requires an exact profile id");
20351
+ command.profile = parsed.data;
20352
+ } else if (arg === "--service" || arg === "--app-origin") {
20345
20353
  const value = remoteOriginSchema.safeParse(rest[++i]);
20346
20354
  if (!value.success) throw new CliError("bad_arguments", `${arg} needs an exact HTTPS origin`);
20347
20355
  if (arg === "--service") command.service = value.data;
@@ -20366,6 +20374,10 @@ function parseRemoteArgs(args) {
20366
20374
  throw new CliError("bad_arguments", "Configuration options apply only to remote enable");
20367
20375
  if (!!command.service !== !!command.app)
20368
20376
  throw new CliError("bad_arguments", "Specify both --service and --app-origin");
20377
+ if (action !== "run" && !command.profile)
20378
+ throw new CliError("bad_arguments", "Select a profile with --profile <profile-id>");
20379
+ if (action === "run" && command.profile)
20380
+ throw new CliError("bad_arguments", "remote run supervises all registered profiles");
20369
20381
  return command;
20370
20382
  }
20371
20383
  async function registrationCode() {
@@ -20405,12 +20417,21 @@ async function runRemote(command) {
20405
20417
  "The installed daemon does not include mobile access",
20406
20418
  `puddle upgrade daemon${command.host ? ` ${command.host}` : ""}`
20407
20419
  );
20420
+ const capabilities = await transport.exec(`${base} --version`, { timeoutMs: 1e4 });
20421
+ if (capabilities.code !== 0 || !capabilities.stdout.includes("cockpit controls 2"))
20422
+ throw new CliError(
20423
+ "protocol_mismatch",
20424
+ "Upgrade the host daemon before managing profile registrations."
20425
+ );
20408
20426
  if (command.action === "run") {
20409
20427
  const result2 = await transport.exec(base, { onStdout: (text) => process.stdout.write(text) });
20410
20428
  return result2.code;
20411
20429
  }
20412
20430
  if (command.action === "reset") {
20413
- const result2 = await transport.exec(`${base} --reset`, { timeoutMs: 3e4 });
20431
+ const result2 = await transport.exec(`${base} --reset`, {
20432
+ timeoutMs: 3e4,
20433
+ stdin: JSON.stringify({ profile: command.profile }) + "\n"
20434
+ });
20414
20435
  if (result2.code !== 0)
20415
20436
  throw new CliError("bad_arguments", result2.stderr.trim() || "Reset failed");
20416
20437
  process.stdout.write(
@@ -20427,7 +20448,9 @@ async function runRemote(command) {
20427
20448
  const result = await transport.exec(
20428
20449
  `${base} ${command.action === "enable" ? "--configure" : "--admin"}`,
20429
20450
  {
20430
- stdin: JSON.stringify(payload) + "\n",
20451
+ stdin: JSON.stringify(
20452
+ command.action === "enable" ? { profile: command.profile, setup: payload } : { profile: command.profile, request: payload }
20453
+ ) + "\n",
20431
20454
  timeoutMs: 3e4
20432
20455
  }
20433
20456
  );
@@ -20494,14 +20517,15 @@ usage:
20494
20517
  puddle install <daemon|desktop>[@version] [user@host] [--tarball <path>]
20495
20518
  puddle upgrade [cli|daemon|desktop][@version] [user@host] [--tarball <path>]
20496
20519
  puddle remove <cli|daemon|desktop> [user@host] [--yes] [--purge]
20497
- puddle remote enable [user@host] --service <https-origin> --app-origin <https-origin>
20520
+ puddle remote enable --profile <profile-id> [user@host] --service <https-origin> --app-origin <https-origin>
20498
20521
  [--foreground]
20499
- puddle remote status|pair|devices|disable|reset|run [user@host]
20500
- puddle remote approve|revoke <device-id> [user@host]
20522
+ puddle remote status|pair|devices|disable|reset --profile <profile-id> [user@host]
20523
+ puddle remote run [user@host]
20524
+ puddle remote approve|revoke <device-id> --profile <profile-id> [user@host]
20501
20525
  puddle --version | --help
20502
20526
 
20503
20527
  --version lists the installed CLI, daemon, and desktop app with the protocol
20504
- each speaks; absent local components are reported as not installed.
20528
+ each speaks (daemon -cN reports the connector\u2019s remote protocol); absent local components are reported as not installed.
20505
20529
 
20506
20530
  launch serves the cockpit at http://localhost:7433 against the daemon on this
20507
20531
  machine when no host (or 'local') is given \u2014 installing it under ~/.puddle if
@@ -21108,10 +21132,11 @@ function jsonLines(stream, receive, fail2) {
21108
21132
 
21109
21133
  // ../shared/src/node/host-control.ts
21110
21134
  var HostControlClient = class {
21111
- constructor(openChannel, automatic = true, error51 = (_code, message) => new Error(message)) {
21135
+ constructor(openChannel, automatic = true, error51 = (_code, message) => new Error(message), profile) {
21112
21136
  this.openChannel = openChannel;
21113
21137
  this.automatic = automatic;
21114
21138
  this.error = error51;
21139
+ this.profile = profile;
21115
21140
  this.timer = setInterval(() => {
21116
21141
  if (this.channel && performance.now() >= this.until)
21117
21142
  this.lose(this.channel, "upstream_expired");
@@ -21254,7 +21279,7 @@ var HostControlClient = class {
21254
21279
  channel.once("error", closed);
21255
21280
  channel.once("close", closed);
21256
21281
  channel.once("end", closed);
21257
- send({ t: "open" });
21282
+ send({ t: "open", ...this.profile ? { profile: this.profile } : {} });
21258
21283
  });
21259
21284
  } finally {
21260
21285
  this.connecting = false;
@@ -21528,7 +21553,7 @@ import { readFileSync as readFileSync4 } from "node:fs";
21528
21553
  import { dirname as dirname4, join as join5 } from "node:path";
21529
21554
  import { fileURLToPath as fileURLToPath2 } from "node:url";
21530
21555
  function cliVersion() {
21531
- if (true) return "0.2.7";
21556
+ if (true) return "0.2.9";
21532
21557
  const here = dirname4(fileURLToPath2(import.meta.url));
21533
21558
  for (const candidate of [
21534
21559
  join5(here, "..", "..", "package.json"),
@@ -21908,7 +21933,9 @@ var RELEASE_PROTOCOLS = {
21908
21933
  "0.2.4": { major: 21, minor: 2 },
21909
21934
  "0.2.5": { major: 21, minor: 2 },
21910
21935
  "0.2.6": { major: 21, minor: 2 },
21911
- "0.2.7": { major: 21, minor: 3 }
21936
+ "0.2.7": { major: 21, minor: 3 },
21937
+ "0.2.8": { major: 22, minor: 0 },
21938
+ "0.2.9": { major: 22, minor: 0 }
21912
21939
  };
21913
21940
  function validProtocol(value) {
21914
21941
  if (typeof value !== "object" || value === null) return false;
@@ -21967,6 +21994,15 @@ function daemonProtocol(home, version2) {
21967
21994
  }
21968
21995
  return releasedProtocol(version2);
21969
21996
  }
21997
+ function daemonConnectorProtocol(home, version2) {
21998
+ try {
21999
+ const raw = readFileSync5(join7(home, "bin", "current", "CONNECTOR_PROTOCOL"), "utf8").trim();
22000
+ if (/^[1-9][0-9]*$/.test(raw) && Number.isSafeInteger(Number(raw))) return Number(raw);
22001
+ return void 0;
22002
+ } catch {
22003
+ return /^0\.2\.[0-7]$/.test(version2) ? 2 : void 0;
22004
+ }
22005
+ }
21970
22006
  async function installedComponentVersions(opts = {}) {
21971
22007
  const home = opts.home ?? clientHome();
21972
22008
  const cli = {
@@ -21977,10 +22013,12 @@ async function installedComponentVersions(opts = {}) {
21977
22013
  };
21978
22014
  const installedDaemon = daemonVersion(home);
21979
22015
  const installedDaemonProtocol = installedDaemon === void 0 ? void 0 : daemonProtocol(home, installedDaemon);
22016
+ const connectorProtocol = installedDaemon === void 0 ? void 0 : daemonConnectorProtocol(home, installedDaemon);
21980
22017
  const daemon = installedDaemon === void 0 ? { component: "daemon", installed: false } : {
21981
22018
  component: "daemon",
21982
22019
  installed: true,
21983
22020
  version: installedDaemon,
22021
+ ...connectorProtocol !== void 0 ? { connectorProtocol } : {},
21984
22022
  ...installedDaemonProtocol ? { protocol: installedDaemonProtocol } : {}
21985
22023
  };
21986
22024
  const recordedDesktop = readDesktopInstallation(desktopRecordFile(home));
@@ -22012,7 +22050,7 @@ function formatComponentVersions(components) {
22012
22050
  const name = component.component.padEnd(7);
22013
22051
  if (!component.installed) return `${name} not installed`;
22014
22052
  const version2 = component.version ?? "unknown version";
22015
- const protocol = component.protocol ? `protocol ${component.protocol.major}.${component.protocol.minor}` : "protocol unknown";
22053
+ const protocol = component.protocol ? `protocol ${component.protocol.major}.${component.protocol.minor}${component.component === "daemon" && component.connectorProtocol !== void 0 ? `-c${component.connectorProtocol}` : ""}` : "protocol unknown";
22016
22054
  return `${name} ${version2} (${protocol})`;
22017
22055
  }).join("\n");
22018
22056
  }
@@ -23281,13 +23319,18 @@ function remoteAccessHandler(control) {
23281
23319
  return async (req, res, authorised) => {
23282
23320
  if (!control) return fail(res, 404, "remote_controls_unavailable");
23283
23321
  if (req.method !== "GET" && req.method !== "POST") return fail(res, 405, "method_not_allowed");
23322
+ const url2 = new URL(req.url, "http://localhost");
23323
+ const scope = connectorProfileSchema.safeParse(Object.fromEntries(url2.searchParams));
23324
+ if (!scope.success || url2.searchParams.getAll("profile").length !== 1)
23325
+ return fail(res, 400, "invalid_profile", "Select the profile to manage remote access.");
23326
+ const { profile } = scope.data;
23284
23327
  const request = req.method === "POST" ? cockpitRemoteRequestSchema.parse(await readJson(req)) : null;
23285
23328
  if (!authorised()) return fail(res, 401, "browser_rejected");
23286
23329
  if (busy)
23287
23330
  return fail(res, 409, "remote_control_busy", "A host operation is already in progress.");
23288
23331
  busy = true;
23289
23332
  try {
23290
- const response = request ? await control.request(request, authorised) : await control.status();
23333
+ const response = request ? await control.request(request, authorised, profile) : await control.status(profile);
23291
23334
  if (!authorised()) return fail(res, 401, "browser_rejected");
23292
23335
  json2(res, 200, response);
23293
23336
  } catch (error51) {
@@ -23540,11 +23583,12 @@ var RemoteAccessControl = class {
23540
23583
  if (result.code !== 0)
23541
23584
  throw new Error("Host control is unavailable. Check the host connection.");
23542
23585
  return {
23543
- availability: result.stdout.includes("cockpit controls 1") ? "ready" : "upgrade_required",
23586
+ availability: result.stdout.includes("cockpit controls 2") ? "ready" : "upgrade_required",
23544
23587
  canDeleteRegistration: result.stdout.includes("delete registration 1")
23545
23588
  };
23546
23589
  }
23547
- async status() {
23590
+ async status(profile) {
23591
+ profileId.parse(profile);
23548
23592
  const capabilities = await this.capabilities();
23549
23593
  if (capabilities.availability !== "ready")
23550
23594
  return {
@@ -23555,12 +23599,16 @@ var RemoteAccessControl = class {
23555
23599
  supervisor: null,
23556
23600
  devices: []
23557
23601
  };
23558
- const result = await this.transport.exec(`${binary} --inspect`, { timeoutMs: 1e4 });
23602
+ const result = await this.transport.exec(`${binary} --inspect`, {
23603
+ timeoutMs: 1e4,
23604
+ stdin: JSON.stringify({ profile }) + "\n"
23605
+ });
23559
23606
  if (result.code !== 0) throw new Error("Could not read remote access status on this host.");
23560
23607
  return cockpitRemoteStatusSchema.parse({ ...JSON.parse(result.stdout), ...capabilities });
23561
23608
  }
23562
- async request(value, authorised) {
23609
+ async request(value, authorised, profile) {
23563
23610
  const request = cockpitRemoteRequestSchema.parse(value);
23611
+ profileId.parse(profile);
23564
23612
  const capabilities = await this.capabilities();
23565
23613
  if (capabilities.availability !== "ready")
23566
23614
  throw new Error("Upgrade the daemon on this host to manage remote access here.");
@@ -23568,7 +23616,7 @@ var RemoteAccessControl = class {
23568
23616
  throw new Error("Upgrade the daemon on this host to delete its remote registration.");
23569
23617
  if (!authorised()) throw new Error("Browser authorisation expired before dispatch.");
23570
23618
  const flag = request.t === "enable" ? "--configure" : request.t === "reset" ? "--reset" : "--admin";
23571
- const payload = request.t === "enable" ? { ...request.registration, managed: true } : request;
23619
+ const payload = request.t === "enable" ? { profile, setup: { ...request.registration, managed: true } } : request.t === "reset" ? { profile } : { profile, request };
23572
23620
  const result = await this.transport.exec(`${binary} ${flag}`, {
23573
23621
  stdin: JSON.stringify(payload) + "\n",
23574
23622
  timeoutMs: 3e4
@@ -24357,8 +24405,12 @@ HOME_DIR="\${PUDDLE_HOME:-$HOME/.puddle}"
24357
24405
  say() { printf 'puddled remove: %s\\n' "$1"; }
24358
24406
 
24359
24407
  # Persist remote disable before unregistering either supervisor.
24360
- if [ -f "$HOME_DIR/bin/current/daemon/connector.mjs" ] && [ -f "$HOME_DIR/remote/config.json" ]; then
24361
- printf '%s\\n' '{"t":"disable"}' | "$HOME_DIR/bin/current/bin/node" "$HOME_DIR/bin/current/daemon/connector.mjs" --admin >/dev/null 2>&1 || exit 1
24408
+ if [ -f "$HOME_DIR/bin/current/daemon/connector.mjs" ] && [ -d "$HOME_DIR/remote" ]; then
24409
+ if [ -f "$HOME_DIR/bin/current/CONNECTOR_PROTOCOL" ]; then
24410
+ "$HOME_DIR/bin/current/bin/node" "$HOME_DIR/bin/current/daemon/connector.mjs" --disable-all >/dev/null 2>&1 || exit 1
24411
+ elif [ -f "$HOME_DIR/remote/config.json" ]; then
24412
+ printf '%s\\n' '{"t":"disable"}' | "$HOME_DIR/bin/current/bin/node" "$HOME_DIR/bin/current/daemon/connector.mjs" --admin >/dev/null 2>&1 || exit 1
24413
+ fi
24362
24414
  fi
24363
24415
 
24364
24416
  # systemd user unit
package/dist/install.sh CHANGED
@@ -254,7 +254,7 @@ fi
254
254
 
255
255
  printf '%s\n' "$KIND" > "$HOME_DIR/supervisor"
256
256
  # An upgrade replaces the supervised connector too. Never opt a new host in.
257
- if [ "$START" = 1 ] && [ -f "$HOME_DIR/remote/config.json" ]; then
257
+ if [ "$START" = 1 ] && [ -d "$HOME_DIR/remote" ]; then
258
258
  if [ "$KIND" = systemd ] && [ -f "$HOME/.config/systemd/user/puddle-connector.service" ]; then
259
259
  systemctl --user restart puddle-connector || die "connector restart failed"
260
260
  elif [ "$KIND" = launchd ] && [ -f "$HOME/Library/LaunchAgents/dev.puddle.connector.plist" ]; then