@puddle-code/cli 0.2.0 → 0.2.2

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 (134) hide show
  1. package/CHANGELOG.md +10 -21
  2. package/dist/host-control.mjs +43 -5
  3. package/dist/index.js +172 -87
  4. package/dist/install.sh +13 -0
  5. package/dist/public/assets/App-DYF0TQ7N.js +2 -0
  6. package/dist/public/assets/Dashboard-BLWy1kHm.js +1 -0
  7. package/dist/public/assets/{EditorTabClose-Dxz8ZjM9.js → EditorTabClose-CtInp1cT.js} +1 -1
  8. package/dist/public/assets/{LazyTerminal-CvkHRHQo.js → LazyTerminal-BrJnGoEX.js} +2 -2
  9. package/dist/public/assets/{ModelRefcount-C0ZeHnBJ.js → ModelRefcount-BNtD7p2m.js} +1 -1
  10. package/dist/public/assets/{NewProjectDialog-CHQ7EJYr.js → NewProjectDialog-BHIvFpCo.js} +1 -1
  11. package/dist/public/assets/{PaneEditorBody-Bco44A9M.js → PaneEditorBody--HKVd4ce.js} +4 -4
  12. package/dist/public/assets/{PdfViewer-Xg7NGubF.js → PdfViewer-DhO008IQ.js} +2 -2
  13. package/dist/public/assets/SettingsDialog-rfDhJoO1.js +8 -0
  14. package/dist/public/assets/Terminal-CttD7XcZ.js +60 -0
  15. package/dist/public/assets/Workspace-BB4IS8EP.js +20 -0
  16. package/dist/public/assets/Workspace-DgLBQU_0.css +1 -0
  17. package/dist/public/assets/{abnfDiagram-VCTEODGH-B9xm0g0V.js → abnfDiagram-VCTEODGH-CTMUfqGq.js} +1 -1
  18. package/dist/public/assets/architecture-7GRP2DOG-D65OB2im.js +1 -0
  19. package/dist/public/assets/{architectureDiagram-5GKGNRK7-DrrWczea.js → architectureDiagram-5GKGNRK7-B-L0EtRZ.js} +1 -1
  20. package/dist/public/assets/{blockDiagram-I7D4REHJ-CYEP6Dnn.js → blockDiagram-I7D4REHJ-CnmmDFsq.js} +1 -1
  21. package/dist/public/assets/{buffer-store-pvgusTv-.js → buffer-store-DzO77p-K.js} +2 -2
  22. package/dist/public/assets/{c4Diagram-7LVT6UL2-BAkFUfYR.js → c4Diagram-7LVT6UL2-DU4HXNd-.js} +1 -1
  23. package/dist/public/assets/channel-DDYJkwWS.js +1 -0
  24. package/dist/public/assets/{chunk-2E4U76K2-sXcn0WDZ.js → chunk-2E4U76K2-B8o6iRzd.js} +1 -1
  25. package/dist/public/assets/{chunk-4HAMMTFA-CPPsfbHS.js → chunk-4HAMMTFA-CfxkhHyC.js} +1 -1
  26. package/dist/public/assets/{chunk-75Z2AOVW-Cp3T9-mM.js → chunk-75Z2AOVW-D8v_0vko.js} +1 -1
  27. package/dist/public/assets/{chunk-CLGD4ZFX-aqUnXBfy.js → chunk-CLGD4ZFX-DPBjX4jg.js} +1 -1
  28. package/dist/public/assets/{chunk-DU6HZSFF-BKPHVNGu.js → chunk-DU6HZSFF-CuwQaNw0.js} +1 -1
  29. package/dist/public/assets/{chunk-F27PBJKO-IqOkPRK3.js → chunk-F27PBJKO-lg02cTVZ.js} +1 -1
  30. package/dist/public/assets/{chunk-GMAD6QVW-c9P8ntLy.js → chunk-GMAD6QVW-DICB0y-D.js} +1 -1
  31. package/dist/public/assets/{chunk-GVQU2GXP-DmZAhaXk.js → chunk-GVQU2GXP-9ghjwcoq.js} +1 -1
  32. package/dist/public/assets/{chunk-IMKFNOWR-CXrrJ9cb.js → chunk-IMKFNOWR-i_YIFBJX.js} +1 -1
  33. package/dist/public/assets/{chunk-L3NEJ4N5-Pn0OM8Or.js → chunk-L3NEJ4N5-gR7gj1U0.js} +1 -1
  34. package/dist/public/assets/{chunk-OSK3NFVY-CSxO-Bhw.js → chunk-OSK3NFVY-DHyaWigk.js} +1 -1
  35. package/dist/public/assets/{chunk-P2QGCYS3-DpTPoZQU.js → chunk-P2QGCYS3-ykV2meK0.js} +1 -1
  36. package/dist/public/assets/{chunk-POPQ4Y6H-V45h95Rz.js → chunk-POPQ4Y6H-BfpRTc3s.js} +1 -1
  37. package/dist/public/assets/{chunk-PWAF6VOD-aG71yphl.js → chunk-PWAF6VOD-gWIwGh8g.js} +1 -1
  38. package/dist/public/assets/{chunk-SHT3W25Y-8X6FPG54.js → chunk-SHT3W25Y-BQ_pTF0Z.js} +1 -1
  39. package/dist/public/assets/{chunk-SVP7TREG-x6ifISIm.js → chunk-SVP7TREG-SQwLD6DT.js} +1 -1
  40. package/dist/public/assets/{chunk-TICWLB2K-D9KB9pY5.js → chunk-TICWLB2K-B2zBy15L.js} +1 -1
  41. package/dist/public/assets/{chunk-TLUHSLCS-GPGNxyxD.js → chunk-TLUHSLCS-Bd2UG2tZ.js} +2 -2
  42. package/dist/public/assets/classDiagram-ZZMXUADV-DiYOyJFb.js +1 -0
  43. package/dist/public/assets/classDiagram-v2-VYDZK3BY-DiYOyJFb.js +1 -0
  44. package/dist/public/assets/{context-menu-Dt7h9y20.js → context-menu-Brk2htuk.js} +1 -1
  45. package/dist/public/assets/{cssMode-F3TrjQ2Y.js → cssMode-DqPCL8gS.js} +1 -1
  46. package/dist/public/assets/{cynefin-OW5HDTMX-BCcHZD-7.js → cynefin-OW5HDTMX-CSAZrmjo.js} +1 -1
  47. package/dist/public/assets/{cynefinDiagram-5FMLGOSQ-hEFQTinv.js → cynefinDiagram-5FMLGOSQ-CGKlzaPC.js} +1 -1
  48. package/dist/public/assets/{dagre-GXQ25YYZ-Dj7c-z9-.js → dagre-GXQ25YYZ-CgRwIpkl.js} +1 -1
  49. package/dist/public/assets/{diagram-S7CK7UJ4-i3ABTGXD.js → diagram-S7CK7UJ4-BMP1KOBu.js} +1 -1
  50. package/dist/public/assets/{diagram-UQ7AKVKN-BClHr071.js → diagram-UQ7AKVKN-DNcOIF4W.js} +1 -1
  51. package/dist/public/assets/{diagram-VSXAHHWV-_NoikNWl.js → diagram-VSXAHHWV-BGdHvK5Q.js} +1 -1
  52. package/dist/public/assets/{diagram-VX7I27RA-BxznNmgf.js → diagram-VX7I27RA-F7PfwNlr.js} +1 -1
  53. package/dist/public/assets/{diagram-Z3DM3KII-Dp_Elrik.js → diagram-Z3DM3KII-CPE4T9mi.js} +1 -1
  54. package/dist/public/assets/{dialog-GYBse2vm.js → dialog-B08M5Cgz.js} +2 -2
  55. package/dist/public/assets/disclosure-Bc6Ydabz.js +1 -0
  56. package/dist/public/assets/{dist-BB_jCiks.js → dist-CE40EiFY.js} +1 -1
  57. package/dist/public/assets/{dist-Dd_gMYta.js → dist-w0M7y9KX.js} +1 -1
  58. package/dist/public/assets/{ebnfDiagram-PWID7BFC-BrhXAUqf.js → ebnfDiagram-PWID7BFC-CqTR9kTI.js} +1 -1
  59. package/dist/public/assets/{erDiagram-RLTQ6QDP-DpvzwcpF.js → erDiagram-RLTQ6QDP-CVqix4AT.js} +1 -1
  60. package/dist/public/assets/eventmodeling-NTZA5JFV-BoPTLqKJ.js +1 -0
  61. package/dist/public/assets/flowDiagram-HODETNUW-2TNtc6rJ.js +1 -0
  62. package/dist/public/assets/{ganttDiagram-EL5Y4UJY-MwZQW2Ab.js → ganttDiagram-EL5Y4UJY-CFSX0WK6.js} +1 -1
  63. package/dist/public/assets/{gitGraph-4MIJSDKK-wD3tQrBr.js → gitGraph-4MIJSDKK-Doy-w5G0.js} +1 -1
  64. package/dist/public/assets/{gitGraphDiagram-WWUBYQGX-RZqAMYtF.js → gitGraphDiagram-WWUBYQGX-fQM29HOw.js} +1 -1
  65. package/dist/public/assets/{hotkeys-Bpeih0PX.js → hotkeys-DQNqRgOb.js} +1 -1
  66. package/dist/public/assets/{htmlMode-BQanlpBa.js → htmlMode-DE4OLLtJ.js} +1 -1
  67. package/dist/public/assets/index-CQ-7fSnd.css +2 -0
  68. package/dist/public/assets/{index-D96JjECU.js → index-CmEI98Do.js} +2 -2
  69. package/dist/public/assets/{info-A6RAGUB7-ie0E4iIr.js → info-A6RAGUB7-DPiPYEQe.js} +1 -1
  70. package/dist/public/assets/{infoDiagram-27XIBGKW-u5u8byqk.js → infoDiagram-27XIBGKW-DY5LKiBl.js} +1 -1
  71. package/dist/public/assets/{input-AzsFYZ3g.js → input-CRHttNr9.js} +1 -1
  72. package/dist/public/assets/{ishikawaDiagram-5VMMS53U-4GHMY6KJ.js → ishikawaDiagram-5VMMS53U-DwSURfQE.js} +1 -1
  73. package/dist/public/assets/{journeyDiagram-3NMN7TZE-Cwe5PRBP.js → journeyDiagram-3NMN7TZE-B0OCkFis.js} +1 -1
  74. package/dist/public/assets/{jsonMode-CRZXV6U_.js → jsonMode-F58eqVfl.js} +1 -1
  75. package/dist/public/assets/{kanban-definition-UXKFOSKX-CS-A9ZNT.js → kanban-definition-UXKFOSKX-CAQw3qWz.js} +1 -1
  76. package/dist/public/assets/{line-kZmQKU6y.js → line-Bcu_KJDQ.js} +1 -1
  77. package/dist/public/assets/{media-refresh-store-B_VyvYfl.js → media-refresh-store-B8Wdlks-.js} +1 -1
  78. package/dist/public/assets/{mermaid-parser.core-BEcx5De7.js → mermaid-parser.core-PSjhnHbq.js} +3 -3
  79. package/dist/public/assets/{mermaid.core-ZFBf3aP8.js → mermaid.core-CVDKsXhB.js} +3 -3
  80. package/dist/public/assets/{mindmap-definition-YA3MSWOX-ti5sUvQf.js → mindmap-definition-YA3MSWOX-CVAY5896.js} +1 -1
  81. package/dist/public/assets/{notification-permission-Car54v17.js → notification-permission-CbLpN3ev.js} +1 -1
  82. package/dist/public/assets/{packet-AYTQ26CC-BFLiDvUG.js → packet-AYTQ26CC-CTdFnPq7.js} +1 -1
  83. package/dist/public/assets/{pdf-CDunFg56.js → pdf-CNnH2qu8.js} +1 -1
  84. package/dist/public/assets/{pegDiagram-XKGWAZYB-L1VUrE59.js → pegDiagram-XKGWAZYB-DjAvebfq.js} +1 -1
  85. package/dist/public/assets/{pie-WAS4IAKB-BxBZGMsV.js → pie-WAS4IAKB-DGj7H0HD.js} +1 -1
  86. package/dist/public/assets/{pieDiagram-E7YTZNPT-D_z8Ah38.js → pieDiagram-E7YTZNPT-ZsMHxQiN.js} +1 -1
  87. package/dist/public/assets/{project-abbrev-B7pHIhbk.js → project-abbrev-CaGbOWtr.js} +1 -1
  88. package/dist/public/assets/{quadrantDiagram-AXDQQJYC-DEU0wyvb.js → quadrantDiagram-AXDQQJYC-DVxSJgm4.js} +1 -1
  89. package/dist/public/assets/{radar-RG4KPBEZ-C7ijJa3G.js → radar-RG4KPBEZ-D7tOXZhy.js} +1 -1
  90. package/dist/public/assets/{railroad-74A4TZTK-BR2-uhMp.js → railroad-74A4TZTK-EI9jAf_f.js} +1 -1
  91. package/dist/public/assets/railroad-abnf-HS5TGJTU-DnezvAFa.js +1 -0
  92. package/dist/public/assets/railroad-ebnf-LZEXJU2U-DHOzgi4x.js +1 -0
  93. package/dist/public/assets/railroad-peg-WCYAUIDC-C28W4OGa.js +1 -0
  94. package/dist/public/assets/{railroadDiagram-O6MQD6OU-BO2RgHB_.js → railroadDiagram-O6MQD6OU-uqpSPQV1.js} +1 -1
  95. package/dist/public/assets/{requirementDiagram-BXWQKSXE-DedAgdgA.js → requirementDiagram-BXWQKSXE-BlP0G3V7.js} +1 -1
  96. package/dist/public/assets/{sankeyDiagram-P5KCCOFB-XS4y44C-.js → sankeyDiagram-P5KCCOFB-BcxykWWD.js} +1 -1
  97. package/dist/public/assets/{sequenceDiagram-WJ2MYXX4-BgGPuhmx.js → sequenceDiagram-WJ2MYXX4-BleK5ON1.js} +1 -1
  98. package/dist/public/assets/{stateDiagram-D77RDMKH-t92luW0k.js → stateDiagram-D77RDMKH-C3Ojitqe.js} +1 -1
  99. package/dist/public/assets/stateDiagram-v2-MP3YSRHH-KLRu_NXG.js +1 -0
  100. package/dist/public/assets/{swimlanes-42K2YHIH-BTLMw_Zs.js → swimlanes-42K2YHIH-Bebu_xn2.js} +1 -1
  101. package/dist/public/assets/swimlanesDiagram-VR7AAH4N-BmvrlXmd.js +8 -0
  102. package/dist/public/assets/{switch-DFcV6j9m.js → switch-CaIM4dwn.js} +1 -1
  103. package/dist/public/assets/{timeline-definition-24CTP7MA-Buej45ei.js → timeline-definition-24CTP7MA-BKUpL8jk.js} +1 -1
  104. package/dist/public/assets/{treeView-Q6P3EWNA-CsmFV7PP.js → treeView-Q6P3EWNA-C7zCIwpV.js} +1 -1
  105. package/dist/public/assets/{treemap-WGGIJYW6-C7p2D31t.js → treemap-WGGIJYW6-6M3fRwft.js} +1 -1
  106. package/dist/public/assets/{tsMode-CkssN7v1.js → tsMode-DQRFLRMD.js} +1 -1
  107. package/dist/public/assets/{use-find-controls-o8dHk3Ai.js → use-find-controls-SI1t9mHH.js} +1 -1
  108. package/dist/public/assets/{use-ui-state-GQIbFm75.js → use-ui-state-D-3P_8P_.js} +1 -1
  109. package/dist/public/assets/{vennDiagram-4TSXK5OY-CabgcJgI.js → vennDiagram-4TSXK5OY-DxK4ozKb.js} +1 -1
  110. package/dist/public/assets/{wardley-WFR3VGLG-nDvUESM8.js → wardley-WFR3VGLG-B2zERAcS.js} +1 -1
  111. package/dist/public/assets/{wardleyDiagram-VM6X3IG4-lH7COUmu.js → wardleyDiagram-VM6X3IG4-Ctiwf9vH.js} +1 -1
  112. package/dist/public/assets/{ws-CvBEQDJB.js → ws-DK8JadaZ.js} +1 -1
  113. package/dist/public/assets/{xychartDiagram-S5SC5T6Z-c7fu3ePF.js → xychartDiagram-S5SC5T6Z-CxqvnL8v.js} +1 -1
  114. package/dist/public/index.html +2 -2
  115. package/package.json +1 -1
  116. package/dist/public/assets/App-4wHC7AhU.js +0 -2
  117. package/dist/public/assets/Dashboard-BTqiSGSr.js +0 -1
  118. package/dist/public/assets/SettingsDialog-BbqSqnMS.js +0 -8
  119. package/dist/public/assets/Terminal-DEVWotwh.js +0 -60
  120. package/dist/public/assets/Workspace-9Ke8tXhO.css +0 -1
  121. package/dist/public/assets/Workspace-D0vmiCsp.js +0 -20
  122. package/dist/public/assets/architecture-7GRP2DOG-B8geJhni.js +0 -1
  123. package/dist/public/assets/channel-B2boMkNJ.js +0 -1
  124. package/dist/public/assets/classDiagram-ZZMXUADV-D8W4ja-y.js +0 -1
  125. package/dist/public/assets/classDiagram-v2-VYDZK3BY-D8W4ja-y.js +0 -1
  126. package/dist/public/assets/eventmodeling-NTZA5JFV-DpPAlVka.js +0 -1
  127. package/dist/public/assets/flowDiagram-HODETNUW-emcn6VnU.js +0 -1
  128. package/dist/public/assets/index-BsSnxNPl.css +0 -2
  129. package/dist/public/assets/railroad-abnf-HS5TGJTU-Q_zhOWAR.js +0 -1
  130. package/dist/public/assets/railroad-ebnf-LZEXJU2U-BNV11-bx.js +0 -1
  131. package/dist/public/assets/railroad-peg-WCYAUIDC-D1whgDil.js +0 -1
  132. package/dist/public/assets/session-seed-exhI-dnY.js +0 -1
  133. package/dist/public/assets/stateDiagram-v2-MP3YSRHH-BVx0pqBn.js +0 -1
  134. package/dist/public/assets/swimlanesDiagram-VR7AAH4N-BaHPNnEm.js +0 -8
package/CHANGELOG.md CHANGED
@@ -7,33 +7,22 @@ Past releases: see docs/changelogs/.
7
7
 
8
8
  # Changelog
9
9
 
10
- ## [0.2.0] — 2026-09-21
10
+ ## [0.2.2] — 2026-09-21
11
11
 
12
12
  ### Added
13
13
 
14
- - Add Settings → Remote access in local and SSH desktop cockpits for enablement, status, QR/link pairing, browser approval/revocation, disablement and host identity recovery; add authenticated cockpit controls in protocol 18.1.
15
- - Add self-hosted mobile access with Google/GitHub login, optional authenticator MFA, independently supervised host connectors and QR/link browser pairing.
16
- - Add a single-terminal phone view, native multiline prompt composer, visible terminal keys and read-only text/change review without rewriting desktop layouts.
17
- - Add remote administration and recovery commands, deployment images and isolated relay/browser acceptance suites.
18
- - Add lightweight built-process and loopback OpenSSH authentication suites, with separate manual browser and desktop acceptance.
14
+ - Add a five-minute browser-approved account registration handoff with one-use private verifiers, origin checks and replay protection (daemon/cockpit protocol 20.0; encrypted remote protocol remains 2).
15
+ - Add confirmed registration deletion to desktop Remote access settings, with browser revocation and local/SSH-only control (daemon/cockpit protocol 19.1; remote protocol remains 2).
19
16
 
20
17
  ### Changed
21
18
 
22
- - Open remote account registration to every verified Google/GitHub identity; remove the signup allowlist and registration switch while retaining account isolation and explicit host approval.
23
-
24
- ### Removed
25
-
26
- - Remove the TLS contact email setting from the Caddy deployment and environment example.
27
- - Remove email/password login, verification/reset email delivery, SMTP configuration and Nodemailer; require Google and/or GitHub OAuth, retain verified-email admission and optional authenticator MFA, and retire legacy passwords/sessions. Bump remote protocol to 2 and daemon/cockpit protocol to 19.0 for the changed pairing contract.
19
+ - Distil remote access into Puddle’s shared project cards and dialogues, with host-grouped projects, host disconnection in settings, a compact session rail, Files/Terminals views, custom-path browsing and direct terminal typing with touch keys.
20
+ - Render pairing QR codes as sharp SVGs with rounded white surfaces and Puddle foreground ink, and match pairing links to the theme's text colour.
21
+ - Start remote registration from desktop browser sign-in, with editable default origins and in-place connection settings instead of a second form or copied registration code.
22
+ - Combine remote access and settings sync under Remote & Sync, preserving existing settings links.
23
+ - Replace native disclosure triangles throughout the UI with Puddle chevrons.
28
24
 
29
25
  ### Fixed
30
26
 
31
- - Reject incomplete remote-origin input without throwing during registration form rendering.
32
- - Preserve browser login, terminal snapshots and refresh correlation across cockpit replacement and upstream recovery; retain desktop routes when the origin moves.
33
-
34
- ### Security
35
-
36
- - Require exact browser approval at the host, pinned Noise XX transport, bounded forwarding and fresh browser participation in the existing host leases; keep remote protocol 2 independent of the protocol-18 host lease foundation.
37
- - Persist device revocation and offline remote disable, isolate application delivery from the relay origin, and deny unreviewed remote routes and executable previews.
38
- - Replace distributed master credentials with private host control, short-lived renewable connection leases and single-use browser invitations; migrate to protocol 18.0 and require existing tabs to run `puddle launch` once.
39
- - Isolate forwarded applications on a separate loopback origin, bind proxy grants to browser authorisation and revoke active streams when their authority expires.
27
+ - Keep remote status polling quiet so controls, registration fields and button labels no longer blink during background refreshes.
28
+ - Initialise remote service volumes with private directory permissions to prevent startup failures and ingress 502 responses.
@@ -15887,19 +15887,25 @@ var remoteChunkSchema = external_exports.object({
15887
15887
  }).strict();
15888
15888
 
15889
15889
  // ../shared/src/api/cockpit-remote.ts
15890
- var cockpitRemoteRequestSchema = external_exports.union([
15890
+ var connectorLocalRequestSchema = external_exports.union([
15891
15891
  remoteAdminRequestSchema,
15892
+ external_exports.object({ t: external_exports.literal("delete_registration") }).strict()
15893
+ ]);
15894
+ var cockpitRemoteRequestSchema = external_exports.union([
15895
+ connectorLocalRequestSchema,
15892
15896
  external_exports.object({
15893
15897
  t: external_exports.literal("enable"),
15894
15898
  registration: external_exports.object({ service: remoteOriginSchema, app: remoteOriginSchema, code: remoteSecretSchema }).strict().optional()
15895
15899
  }).strict(),
15896
15900
  external_exports.object({ t: external_exports.literal("reset") }).strict()
15897
15901
  ]);
15902
+ var cockpitRegistrationCheckSchema = external_exports.object({ service: remoteOriginSchema, code: remoteSecretSchema }).strict();
15898
15903
  var cockpitRemoteStatusSchema = external_exports.object({
15899
15904
  availability: external_exports.enum(["ready", "not_installed", "upgrade_required"]),
15900
15905
  configured: external_exports.boolean(),
15901
15906
  enabled: external_exports.boolean(),
15902
15907
  connected: external_exports.boolean(),
15908
+ canDeleteRegistration: external_exports.boolean().optional(),
15903
15909
  supervisor: external_exports.enum(["systemd", "launchd"]).nullable(),
15904
15910
  host: remoteIdSchema.optional(),
15905
15911
  peer: remotePeerSchema.optional(),
@@ -16012,6 +16018,14 @@ var remoteLoginStateSchema = external_exports.object({
16012
16018
  var registerHostRequestSchema = external_exports.object({ label: remoteLabelSchema }).strict();
16013
16019
  var registrationResponseSchema = external_exports.object({ host: remoteIdSchema, code: remoteSecretSchema, expires: external_exports.number() }).strict();
16014
16020
  var redeemRegistrationSchema = external_exports.object({ code: remoteSecretSchema }).strict();
16021
+ var desktopRegistrationSchema = external_exports.object({
16022
+ challenge: remoteSecretSchema,
16023
+ label: remoteLabelSchema,
16024
+ service: remoteOriginSchema,
16025
+ app: remoteOriginSchema,
16026
+ expires: external_exports.number().int().positive()
16027
+ }).strict();
16028
+ var registrationStatusSchema = external_exports.object({ ready: external_exports.boolean() }).strict();
16015
16029
  var connectorRegistrationSchema = external_exports.object({
16016
16030
  host: remoteIdSchema,
16017
16031
  account: remoteAccountSchema,
@@ -16043,6 +16057,9 @@ import { createHash, randomBytes } from "node:crypto";
16043
16057
  import {
16044
16058
  chmodSync,
16045
16059
  closeSync,
16060
+ constants,
16061
+ fchmodSync,
16062
+ fstatSync,
16046
16063
  fsyncSync,
16047
16064
  lstatSync,
16048
16065
  mkdirSync,
@@ -16053,7 +16070,7 @@ import {
16053
16070
  rmSync,
16054
16071
  writeFileSync
16055
16072
  } from "node:fs";
16056
- import { dirname, join } from "node:path";
16073
+ import { dirname, join, resolve } from "node:path";
16057
16074
  var digest = (value) => createHash("sha256").update(value).digest("hex");
16058
16075
  function privatePath(path, directory = false) {
16059
16076
  const st = lstatSync(path);
@@ -16065,8 +16082,29 @@ function privateDirectory(path) {
16065
16082
  mkdirSync(path, { recursive: true, mode: 448 });
16066
16083
  privatePath(path, true);
16067
16084
  }
16085
+ function initialisePrivateHome(home) {
16086
+ const path = resolve(home);
16087
+ mkdirSync(path, { recursive: true, mode: 448 });
16088
+ if (process.platform === "win32") {
16089
+ privatePath(path, true);
16090
+ return;
16091
+ }
16092
+ const fd = openSync(path, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
16093
+ try {
16094
+ const st = fstatSync(fd);
16095
+ if (!st.isDirectory() || st.uid !== process.getuid() || (st.mode & 18) !== 0) {
16096
+ throw new Error(
16097
+ `Puddle home must be owned by the current user and not writable by other users: ${path}`
16098
+ );
16099
+ }
16100
+ if ((st.mode & 63) !== 0) fchmodSync(fd, 448);
16101
+ } finally {
16102
+ closeSync(fd);
16103
+ }
16104
+ privatePath(path, true);
16105
+ }
16068
16106
  function ipcPath(home, scope) {
16069
- privateDirectory(home);
16107
+ initialisePrivateHome(home);
16070
16108
  const key = digest(`${realpathSync(home)}\0${scope}`).slice(0, 24);
16071
16109
  if (process.platform === "win32") return `\\\\.\\pipe\\puddle-${key}`;
16072
16110
  const dir = join("/tmp", `puddle-${process.getuid()}-${key}`);
@@ -16189,7 +16227,7 @@ async function inspectHostLocally(home) {
16189
16227
  }
16190
16228
  const socket = connect(path);
16191
16229
  try {
16192
- const grant = await new Promise((resolve, reject) => {
16230
+ const grant = await new Promise((resolve2, reject) => {
16193
16231
  socket.setTimeout(5e3, () => socket.destroy(new Error("Host inspection timed out")));
16194
16232
  socket.once("error", reject);
16195
16233
  socket.once("close", () => reject(new Error("Host control closed")));
@@ -16199,7 +16237,7 @@ async function inspectHostLocally(home) {
16199
16237
  const message = controlResponseSchema.parse(value);
16200
16238
  if (message.t !== "authority" || !message.token)
16201
16239
  throw new Error("Host authority unavailable");
16202
- resolve(message);
16240
+ resolve2(message);
16203
16241
  },
16204
16242
  () => socket.destroy(new Error("Invalid host control response"))
16205
16243
  );