@puddle-code/cli 0.2.24 → 0.3.0

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 +7 -3
  2. package/README.md +4 -0
  3. package/dist/host-control.mjs +147 -0
  4. package/dist/index.js +165 -7
  5. package/dist/install-cli.sh +13 -2
  6. package/dist/public/assets/{App-BYidYCu7.js → App-XpQccO6u.js} +2 -2
  7. package/dist/public/assets/{Dashboard-Dzjf0zET.js → Dashboard-DMEBtYwv.js} +1 -1
  8. package/dist/public/assets/{EditorTabClose-DKA1_wod.js → EditorTabClose-PbgNs_rN.js} +1 -1
  9. package/dist/public/assets/{FindWidget-AH805XK9.js → FindWidget-ZDHywlX4.js} +1 -1
  10. package/dist/public/assets/{LazyTerminal-Bqg0V2V8.js → LazyTerminal-DRgaFViU.js} +2 -2
  11. package/dist/public/assets/{ModelRefcount-5wOQD9So.js → ModelRefcount-CI3cYeQp.js} +1 -1
  12. package/dist/public/assets/{NewProjectDialog-B6E4_Y_p.js → NewProjectDialog-Bhfj_sYl.js} +1 -1
  13. package/dist/public/assets/{PaneEditorBody-LVZ3_6WO.js → PaneEditorBody-Bz74yrKU.js} +3 -3
  14. package/dist/public/assets/{PdfViewer-BGVCeFGN.js → PdfViewer-73_UlYnM.js} +2 -2
  15. package/dist/public/assets/{SettingsDialog-DKCK1la1.js → SettingsDialog-DJmvzJHQ.js} +1 -1
  16. package/dist/public/assets/{Terminal-BSDLWpgK.js → Terminal-BwuoWKED.js} +3 -3
  17. package/dist/public/assets/{Workspace-CR8tLiD8.js → Workspace-DPL1IKA6.js} +4 -4
  18. package/dist/public/assets/{abnfDiagram-VCTEODGH-FgX2dXui.js → abnfDiagram-VCTEODGH-AawOhIcj.js} +1 -1
  19. package/dist/public/assets/architecture-7GRP2DOG-BbAArV9u.js +1 -0
  20. package/dist/public/assets/{architectureDiagram-5GKGNRK7-CdJkD_Pz.js → architectureDiagram-5GKGNRK7-D9vP5DO8.js} +1 -1
  21. package/dist/public/assets/{blockDiagram-I7D4REHJ-DNbmvisu.js → blockDiagram-I7D4REHJ-Cm9i3cTT.js} +1 -1
  22. package/dist/public/assets/{buffer-store-BvXwuYnu.js → buffer-store-BIpSx_-b.js} +2 -2
  23. package/dist/public/assets/{button-CHEvj8hX.js → button-CgZcwDne.js} +1 -1
  24. package/dist/public/assets/{c4Diagram-7LVT6UL2-CjD9lD8i.js → c4Diagram-7LVT6UL2-BiN1-NKB.js} +1 -1
  25. package/dist/public/assets/channel-CUWW1WRo.js +1 -0
  26. package/dist/public/assets/{chunk-2E4U76K2-SJhD4HB_.js → chunk-2E4U76K2-BxAMvG2q.js} +1 -1
  27. package/dist/public/assets/{chunk-4HAMMTFA-C_eKRFh0.js → chunk-4HAMMTFA-D4UgoMR5.js} +1 -1
  28. package/dist/public/assets/{chunk-75Z2AOVW-DRIbOeZi.js → chunk-75Z2AOVW-ViSC5KeO.js} +1 -1
  29. package/dist/public/assets/{chunk-CLGD4ZFX-CMf2IZk2.js → chunk-CLGD4ZFX-C1obqh7u.js} +1 -1
  30. package/dist/public/assets/{chunk-DU6HZSFF-PwbPwYnk.js → chunk-DU6HZSFF-Dd9xUi9L.js} +1 -1
  31. package/dist/public/assets/{chunk-F27PBJKO-Oq_sdoh3.js → chunk-F27PBJKO-S5xJlLKg.js} +1 -1
  32. package/dist/public/assets/{chunk-GMAD6QVW-Ck8EGVZC.js → chunk-GMAD6QVW-DXbO7ojE.js} +1 -1
  33. package/dist/public/assets/{chunk-GVQU2GXP-Ny1aeY0A.js → chunk-GVQU2GXP-vZ5Z6XwC.js} +1 -1
  34. package/dist/public/assets/{chunk-IMKFNOWR-fHImnlSZ.js → chunk-IMKFNOWR-BGcGac3f.js} +1 -1
  35. package/dist/public/assets/{chunk-L3NEJ4N5-BbUIctlf.js → chunk-L3NEJ4N5-BfxBma0T.js} +1 -1
  36. package/dist/public/assets/{chunk-OSK3NFVY-hqM-ZrkL.js → chunk-OSK3NFVY-BaWjSKfn.js} +1 -1
  37. package/dist/public/assets/{chunk-P2QGCYS3-B23zjSSj.js → chunk-P2QGCYS3-Ce8Ukv1J.js} +1 -1
  38. package/dist/public/assets/{chunk-POPQ4Y6H-GEEn3V5D.js → chunk-POPQ4Y6H-lrRlaehc.js} +1 -1
  39. package/dist/public/assets/{chunk-PWAF6VOD-DW1kCowt.js → chunk-PWAF6VOD-DcoK5-E2.js} +1 -1
  40. package/dist/public/assets/{chunk-SHT3W25Y-DmDCmUrG.js → chunk-SHT3W25Y-BWdHabuP.js} +1 -1
  41. package/dist/public/assets/{chunk-SVP7TREG-DwlrYDnP.js → chunk-SVP7TREG-CfpAvBiO.js} +1 -1
  42. package/dist/public/assets/{chunk-TICWLB2K-C5NBrDW2.js → chunk-TICWLB2K-BnqQqZIp.js} +1 -1
  43. package/dist/public/assets/{chunk-TLUHSLCS-COQ_6Xv5.js → chunk-TLUHSLCS-Cd6EShzW.js} +2 -2
  44. package/dist/public/assets/classDiagram-ZZMXUADV-Cve4a5Gc.js +1 -0
  45. package/dist/public/assets/classDiagram-v2-VYDZK3BY-Cve4a5Gc.js +1 -0
  46. package/dist/public/assets/{context-menu-DofF0Gza.js → context-menu-CtKnUzHa.js} +1 -1
  47. package/dist/public/assets/{copy-BW2fd4uA.js → copy-Xz4fK2YI.js} +1 -1
  48. package/dist/public/assets/{cssMode-B4htuRa7.js → cssMode-CNBJ-DrN.js} +1 -1
  49. package/dist/public/assets/{cynefin-OW5HDTMX-DypMTjQw.js → cynefin-OW5HDTMX-C1-MjjCZ.js} +1 -1
  50. package/dist/public/assets/{cynefinDiagram-5FMLGOSQ-WLacyiJj.js → cynefinDiagram-5FMLGOSQ-xt5hQJ88.js} +1 -1
  51. package/dist/public/assets/{dagre-GXQ25YYZ-DaKOhMFv.js → dagre-GXQ25YYZ-Bgahh86t.js} +1 -1
  52. package/dist/public/assets/{diagram-S7CK7UJ4-DIwi33o4.js → diagram-S7CK7UJ4-Djip7YHP.js} +1 -1
  53. package/dist/public/assets/{diagram-UQ7AKVKN-x_QCuDjf.js → diagram-UQ7AKVKN-StD7DYFa.js} +1 -1
  54. package/dist/public/assets/{diagram-VSXAHHWV-Bjr6LKcx.js → diagram-VSXAHHWV-C6W2XMTF.js} +1 -1
  55. package/dist/public/assets/{diagram-VX7I27RA-BQ1d8ghu.js → diagram-VX7I27RA-C5rBIjxM.js} +1 -1
  56. package/dist/public/assets/{diagram-Z3DM3KII-CN1JdLeI.js → diagram-Z3DM3KII-DDzmZnRU.js} +1 -1
  57. package/dist/public/assets/{dialog-DPE0j1Ok.js → dialog-_JRACgt4.js} +1 -1
  58. package/dist/public/assets/{disclosure-BmYZGR3p.js → disclosure-DBXM9uBm.js} +1 -1
  59. package/dist/public/assets/{dist-BROMyZLV.js → dist-Bl7vUoam.js} +1 -1
  60. package/dist/public/assets/{dist-B1jh4y60.js → dist-CzEdee3K.js} +1 -1
  61. package/dist/public/assets/{ebnfDiagram-PWID7BFC-BWTV2Lw8.js → ebnfDiagram-PWID7BFC-TJlh5Fea.js} +1 -1
  62. package/dist/public/assets/{erDiagram-RLTQ6QDP-DiYZY7fZ.js → erDiagram-RLTQ6QDP-BSNVCw_x.js} +1 -1
  63. package/dist/public/assets/{errors-CZ1Lhnki.js → errors-BzfxU_Kw.js} +1 -1
  64. package/dist/public/assets/eventmodeling-NTZA5JFV-DZ8G1RJ1.js +1 -0
  65. package/dist/public/assets/flowDiagram-HODETNUW-Dd9WpTU6.js +1 -0
  66. package/dist/public/assets/{ganttDiagram-EL5Y4UJY-ChyMBO-e.js → ganttDiagram-EL5Y4UJY-BGFNgCoM.js} +1 -1
  67. package/dist/public/assets/{gitGraph-4MIJSDKK-qX2_zEiU.js → gitGraph-4MIJSDKK-Du3WBCxU.js} +1 -1
  68. package/dist/public/assets/{gitGraphDiagram-WWUBYQGX-DJb4bV4o.js → gitGraphDiagram-WWUBYQGX-Dq_yAVmM.js} +1 -1
  69. package/dist/public/assets/{htmlMode-BaQBKHvn.js → htmlMode-BWm5ayBQ.js} +1 -1
  70. package/dist/public/assets/index-BP-EF5G2.js +82 -0
  71. package/dist/public/assets/{info-A6RAGUB7-t5cYX1fg.js → info-A6RAGUB7-V0hlAV3d.js} +1 -1
  72. package/dist/public/assets/{infoDiagram-27XIBGKW-CoS-Nsq6.js → infoDiagram-27XIBGKW-DZM1jHkq.js} +1 -1
  73. package/dist/public/assets/{ishikawaDiagram-5VMMS53U-DaKttTut.js → ishikawaDiagram-5VMMS53U-CZlO72MU.js} +1 -1
  74. package/dist/public/assets/{journeyDiagram-3NMN7TZE-kLaNVwdB.js → journeyDiagram-3NMN7TZE-DZZieltZ.js} +1 -1
  75. package/dist/public/assets/{jsonMode-DhacIbdT.js → jsonMode-DA3Di61-.js} +1 -1
  76. package/dist/public/assets/{kanban-definition-UXKFOSKX-sBx71npp.js → kanban-definition-UXKFOSKX-BAFfgDCD.js} +1 -1
  77. package/dist/public/assets/{line-B6tFaQMh.js → line-DNRJuk5l.js} +1 -1
  78. package/dist/public/assets/{markdown-mermaid-C56AFLzi.js → markdown-mermaid-zldCuMow.js} +2 -2
  79. package/dist/public/assets/{math-S65D25xf.js → math-Bl0zHVK2.js} +1 -1
  80. package/dist/public/assets/{media-refresh-store-BhfM9D0i.js → media-refresh-store-BemN_6sc.js} +1 -1
  81. package/dist/public/assets/{mermaid-parser.core-D4kJBS6w.js → mermaid-parser.core-DpOHgT8D.js} +3 -3
  82. package/dist/public/assets/{mermaid.core-Cne_RySy.js → mermaid.core-DuO1Atct.js} +3 -3
  83. package/dist/public/assets/{mindmap-definition-YA3MSWOX-BEhzKX0Z.js → mindmap-definition-YA3MSWOX-Bbgshnhk.js} +1 -1
  84. package/dist/public/assets/{notification-delivery-BNxj08z5.js → notification-delivery-DehaYHWS.js} +1 -1
  85. package/dist/public/assets/{packet-AYTQ26CC-BzfZcYUP.js → packet-AYTQ26CC-H2b8zBMM.js} +1 -1
  86. package/dist/public/assets/{pdf-Cg-HiUjy.js → pdf-DTc2umrm.js} +1 -1
  87. package/dist/public/assets/{pegDiagram-XKGWAZYB-DzpbUJ7d.js → pegDiagram-XKGWAZYB-BKdl5Qrn.js} +1 -1
  88. package/dist/public/assets/{pie-WAS4IAKB-DNKuxanW.js → pie-WAS4IAKB-SB8x1Dpp.js} +1 -1
  89. package/dist/public/assets/{pieDiagram-E7YTZNPT-BeOnYivs.js → pieDiagram-E7YTZNPT-YXMNp-5O.js} +1 -1
  90. package/dist/public/assets/{project-abbrev-CKBTuDt5.js → project-abbrev-D7aa-LGS.js} +1 -1
  91. package/dist/public/assets/{protocol-support-B-0f1eJ3.js → protocol-support-Dm8bEo7Y.js} +1 -1
  92. package/dist/public/assets/{quadrantDiagram-AXDQQJYC-D5RU0BZ9.js → quadrantDiagram-AXDQQJYC-B2TAChhA.js} +1 -1
  93. package/dist/public/assets/{radar-RG4KPBEZ-C-7t5hsN.js → radar-RG4KPBEZ-D2xzXNL8.js} +1 -1
  94. package/dist/public/assets/{railroad-74A4TZTK-CaVM2B69.js → railroad-74A4TZTK-CKug6hj8.js} +1 -1
  95. package/dist/public/assets/railroad-abnf-HS5TGJTU-cj9XZHow.js +1 -0
  96. package/dist/public/assets/railroad-ebnf-LZEXJU2U-CCIfyLjg.js +1 -0
  97. package/dist/public/assets/railroad-peg-WCYAUIDC-DkxYDi7O.js +1 -0
  98. package/dist/public/assets/{railroadDiagram-O6MQD6OU-DxkTp-H6.js → railroadDiagram-O6MQD6OU-Bft2oh-d.js} +1 -1
  99. package/dist/public/assets/{requirementDiagram-BXWQKSXE-DXsUjGlL.js → requirementDiagram-BXWQKSXE-e0GCEfhM.js} +1 -1
  100. package/dist/public/assets/{sankeyDiagram-P5KCCOFB-CjlMAu4N.js → sankeyDiagram-P5KCCOFB-Csb70YNA.js} +1 -1
  101. package/dist/public/assets/{scroll-restoration-BMX0q1d6.js → scroll-restoration-D7f4DDsJ.js} +1 -1
  102. package/dist/public/assets/{selection-actions-BnvTzlOF.js → selection-actions-D5wKfiBu.js} +1 -1
  103. package/dist/public/assets/{sequenceDiagram-WJ2MYXX4-B8pW_U2s.js → sequenceDiagram-WJ2MYXX4-DcnD8T30.js} +1 -1
  104. package/dist/public/assets/{stateDiagram-D77RDMKH-C4649vJ_.js → stateDiagram-D77RDMKH-GnwFUlNg.js} +1 -1
  105. package/dist/public/assets/stateDiagram-v2-MP3YSRHH-Bktkoy9c.js +1 -0
  106. package/dist/public/assets/{swimlanes-42K2YHIH-D2bi0IkJ.js → swimlanes-42K2YHIH-CPq_eKyi.js} +1 -1
  107. package/dist/public/assets/swimlanesDiagram-VR7AAH4N-BmjIwfwd.js +8 -0
  108. package/dist/public/assets/{switch-CEs7mmdu.js → switch-DZbOKnZ0.js} +1 -1
  109. package/dist/public/assets/{timeline-definition-24CTP7MA-D55uisDI.js → timeline-definition-24CTP7MA-DjUPAJJx.js} +1 -1
  110. package/dist/public/assets/{treeView-Q6P3EWNA-BTfpSxF_.js → treeView-Q6P3EWNA-DBuhlxaq.js} +1 -1
  111. package/dist/public/assets/{treemap-WGGIJYW6-Ck20fjtW.js → treemap-WGGIJYW6-3TKwSIeh.js} +1 -1
  112. package/dist/public/assets/{tsMode-BiJ1tmbK.js → tsMode-BYwFH3pC.js} +1 -1
  113. package/dist/public/assets/{use-ui-state-DMXseT3q.js → use-ui-state-BXROVbIw.js} +1 -1
  114. package/dist/public/assets/{vennDiagram-4TSXK5OY-BKNs6Vhx.js → vennDiagram-4TSXK5OY-oDrGN_Dh.js} +1 -1
  115. package/dist/public/assets/{view-state-store-B64Y8syO.js → view-state-store-vUrDt7wu.js} +1 -1
  116. package/dist/public/assets/{wardley-WFR3VGLG-sC7irUb3.js → wardley-WFR3VGLG-Br5CacuJ.js} +1 -1
  117. package/dist/public/assets/{wardleyDiagram-VM6X3IG4-BwmBuIAi.js → wardleyDiagram-VM6X3IG4-Cw_uOLXA.js} +1 -1
  118. package/dist/public/assets/{ws-Djpdj45w.js → ws-Ug1Tr2sh.js} +1 -1
  119. package/dist/public/assets/{xychartDiagram-S5SC5T6Z-IfkSgCyl.js → xychartDiagram-S5SC5T6Z-Cl8gNx_J.js} +1 -1
  120. package/dist/public/index.html +1 -1
  121. package/dist/puddlang.js +17578 -0
  122. package/package.json +3 -2
  123. package/dist/public/assets/architecture-7GRP2DOG-BtJFkJAN.js +0 -1
  124. package/dist/public/assets/channel-Cdoqj1v0.js +0 -1
  125. package/dist/public/assets/classDiagram-ZZMXUADV-BgnwaWPy.js +0 -1
  126. package/dist/public/assets/classDiagram-v2-VYDZK3BY-BgnwaWPy.js +0 -1
  127. package/dist/public/assets/eventmodeling-NTZA5JFV-RcT3PESX.js +0 -1
  128. package/dist/public/assets/flowDiagram-HODETNUW-DwQ7P0aM.js +0 -1
  129. package/dist/public/assets/index-yGQSODPf.js +0 -82
  130. package/dist/public/assets/railroad-abnf-HS5TGJTU-BU_CVJO3.js +0 -1
  131. package/dist/public/assets/railroad-ebnf-LZEXJU2U-DfYF2tn-.js +0 -1
  132. package/dist/public/assets/railroad-peg-WCYAUIDC-DjlDlAsc.js +0 -1
  133. package/dist/public/assets/stateDiagram-v2-MP3YSRHH-z1utsNYA.js +0 -1
  134. package/dist/public/assets/swimlanesDiagram-VR7AAH4N-RcujV43_.js +0 -8
package/CHANGELOG.md CHANGED
@@ -4,8 +4,12 @@ Archived release changelog. Governance lives in CLAUDE.md §"Changelog disciplin
4
4
 
5
5
  # Changelog
6
6
 
7
- ## [0.2.24] — 2026-10-14
7
+ ## [0.3.0] — 2026-10-14
8
8
 
9
- ### Fixed
9
+ ### Added
10
10
 
11
- - macOS releases without signing secrets unset the empty certificate environment before ad-hoc packaging, preventing electron-builder from treating the desktop directory as a certificate file. Desktop packaging leaves publication to the release job.
11
+ - Add puddlang: host-executed TypeScript agent workflows, Codex exact turns and structured replies, profile/account selection, durable run records, cancellation, CLI and stdio MCP access; bundle `puddlang` with existing CLI installers (daemon protocol 23.0, remote protocol unchanged).
12
+
13
+ ### Changed
14
+
15
+ - Bump daemon/cockpit protocol to 23.0 for the puddlang rollout; require matching clients and hosts through the existing approved upgrade flow, while retaining remote transport protocol 3.
package/README.md CHANGED
@@ -29,6 +29,10 @@ installer (replace the example host):
29
29
  curl -fsSL https://app.example.com/install.sh | sh
30
30
  ```
31
31
 
32
+ The CLI also includes `puddlang`, a TypeScript interface for coder/reviewer loops
33
+ and other agent workflows, available through the shell or stdio MCP. See the
34
+ [puddlang guide](docs/puddlang.md) for setup, examples and initial limitations.
35
+
32
36
  This installs the CLI under `~/.local/share/puddle/cli` and its launcher at
33
37
  `~/.local/bin/puddle`. Add `~/.local/bin` to your `PATH` if the installer asks.
34
38
  The standalone releases support Linux x64/arm64 and macOS arm64. The script and
@@ -16188,6 +16188,153 @@ var connectorNotificationSchema = external_exports.object({
16188
16188
  var pushDispatchResultSchema = external_exports.object({ accepted: external_exports.number().int().nonnegative(), failed: external_exports.number().int().nonnegative() }).strict();
16189
16189
  var pushPreferenceResultSchema = external_exports.object({ enabled: external_exports.boolean() }).strict();
16190
16190
 
16191
+ // ../shared/src/api/puddlang.ts
16192
+ var PUDDLANG_MAX_SOURCE = 256 * 1024;
16193
+ var sourceSchema = external_exports.string().min(1).max(PUDDLANG_MAX_SOURCE).refine(
16194
+ (source) => new TextEncoder().encode(source).length <= PUDDLANG_MAX_SOURCE,
16195
+ "Source exceeds 256 KiB"
16196
+ );
16197
+ var puddlangSpawnSchema = external_exports.object({
16198
+ agent: external_exports.string().min(1).max(100),
16199
+ account: external_exports.union([external_exports.string().min(1).max(100), external_exports.number().int().positive()]).optional(),
16200
+ project: external_exports.string().min(1).max(200).optional(),
16201
+ worktree: external_exports.string().min(1).max(4096).optional(),
16202
+ path: external_exports.string().min(1).max(4096).optional(),
16203
+ title: external_exports.string().min(1).max(200).optional()
16204
+ }).refine((v) => Boolean(v.path) !== Boolean(v.project), "Choose path or project").refine((v) => !v.path || !v.worktree, "worktree requires project");
16205
+ var puddlangHandleSchema = external_exports.object({ runtime_id: external_exports.uuid(), session_id: sessionId });
16206
+ var puddlangAskSchema = external_exports.object({
16207
+ prompt: external_exports.string().min(1).max(128 * 1024),
16208
+ output_schema: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
16209
+ });
16210
+ var puddlangStartSchema = external_exports.object({
16211
+ id: external_exports.uuid(),
16212
+ source: sourceSchema,
16213
+ input: external_exports.unknown().optional(),
16214
+ accounts: external_exports.record(external_exports.string(), external_exports.union([external_exports.string(), external_exports.number().int().positive()])).default({}),
16215
+ max_turns: external_exports.number().int().min(1).max(1e3).default(50),
16216
+ max_agents: external_exports.number().int().min(1).max(32).default(8),
16217
+ timeout_ms: external_exports.number().int().min(1e3).max(24 * 60 * 60 * 1e3).default(60 * 60 * 1e3)
16218
+ });
16219
+ var puddlangRunSchema = external_exports.object({
16220
+ id: external_exports.uuid(),
16221
+ profile_id: profileId,
16222
+ source_hash: external_exports.string(),
16223
+ status: external_exports.enum(["running", "completed", "failed", "cancelled", "interrupted"]),
16224
+ result: external_exports.unknown().nullable(),
16225
+ error: external_exports.string().nullable(),
16226
+ created_at: external_exports.string(),
16227
+ updated_at: external_exports.string()
16228
+ });
16229
+ var puddlangEventSchema = external_exports.object({
16230
+ sequence: external_exports.number().int(),
16231
+ run_id: external_exports.uuid(),
16232
+ type: external_exports.string(),
16233
+ data: external_exports.unknown(),
16234
+ created_at: external_exports.string()
16235
+ });
16236
+ var puddlangEventsSchema = external_exports.object({ events: external_exports.array(puddlangEventSchema) });
16237
+ var puddlangOperationSchema = external_exports.discriminatedUnion("op", [
16238
+ external_exports.object({ op: external_exports.literal("spawn"), options: puddlangSpawnSchema }),
16239
+ external_exports.object({ op: external_exports.literal("attach"), reference: external_exports.string().min(1).max(100) }),
16240
+ external_exports.object({ op: external_exports.literal("ask"), handle: puddlangHandleSchema, request: puddlangAskSchema }),
16241
+ external_exports.object({ op: external_exports.literal("stop"), handle: puddlangHandleSchema })
16242
+ ]);
16243
+ var puddlangRunnerMessageSchema = external_exports.discriminatedUnion("type", [
16244
+ external_exports.object({
16245
+ type: external_exports.literal("operation"),
16246
+ id: external_exports.number().int(),
16247
+ operation: puddlangOperationSchema
16248
+ }),
16249
+ external_exports.object({
16250
+ type: external_exports.literal("finished"),
16251
+ result: external_exports.unknown().optional(),
16252
+ error: external_exports.string().max(8192).optional()
16253
+ })
16254
+ ]);
16255
+ var puddlangRunnerInputSchema = external_exports.discriminatedUnion("type", [
16256
+ external_exports.object({
16257
+ type: external_exports.literal("start"),
16258
+ source: sourceSchema,
16259
+ input: external_exports.unknown().optional()
16260
+ }),
16261
+ external_exports.object({
16262
+ type: external_exports.literal("reply"),
16263
+ id: external_exports.number().int(),
16264
+ value: external_exports.unknown().optional(),
16265
+ error: external_exports.string().optional()
16266
+ })
16267
+ ]);
16268
+ var puddlangContextSchema = external_exports.object({
16269
+ profile: external_exports.object({ id: profileId, name: external_exports.string() }),
16270
+ projects: external_exports.array(external_exports.object({ id: external_exports.string(), name: external_exports.string(), path: external_exports.string() })),
16271
+ accounts: external_exports.array(
16272
+ external_exports.object({ id: external_exports.number(), label: external_exports.string(), agent: external_exports.string(), logged_in: external_exports.boolean() })
16273
+ ),
16274
+ agents: external_exports.array(external_exports.object({ id: external_exports.string(), scripted_turns: external_exports.boolean() }))
16275
+ });
16276
+
16277
+ // ../shared/src/api/puddlang-mcp.ts
16278
+ var puddlangMcpRequestSchema = external_exports.object({
16279
+ jsonrpc: external_exports.literal("2.0"),
16280
+ id: external_exports.union([external_exports.string(), external_exports.number()]).optional(),
16281
+ method: external_exports.string(),
16282
+ params: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
16283
+ });
16284
+ var puddlangMcpCallSchema = external_exports.object({
16285
+ name: external_exports.string(),
16286
+ arguments: external_exports.unknown().optional()
16287
+ });
16288
+ var puddlangMcpRunSchema = puddlangStartSchema;
16289
+ var puddlangMcpIdSchema = external_exports.object({ id: external_exports.uuid() });
16290
+ var puddlangMcpEventsSchema = puddlangMcpIdSchema.extend({
16291
+ after: external_exports.number().int().nonnegative().default(0)
16292
+ });
16293
+ var puddlangMcpEmptySchema = external_exports.object({}).strict();
16294
+ var definitions = [
16295
+ [
16296
+ "puddlang_context",
16297
+ "List this host profile, projects, accounts and supported agents.",
16298
+ puddlangMcpEmptySchema,
16299
+ true
16300
+ ],
16301
+ [
16302
+ "puddlang_run",
16303
+ 'Execute a trusted single-file TypeScript programme on the host. Imports: puddlang (spawn, attach, input, z), zod, node: built-ins. Returns immediately with a durable run id; use status/events. Supply a fresh UUID id, or reuse it with identical input to recover an uncertain submission. spawn({agent:"codex",project:"name",account:"label"}); await agent.ask("task"); export default result. Supports structured ask({prompt,input,schema:z.object(...)}) and agent.stop().',
16304
+ puddlangMcpRunSchema,
16305
+ false
16306
+ ],
16307
+ [
16308
+ "puddlang_status",
16309
+ "Read a run and its final default export, if finished.",
16310
+ puddlangMcpIdSchema,
16311
+ true
16312
+ ],
16313
+ [
16314
+ "puddlang_events",
16315
+ "Read up to 100 events after a sequence; paginate until empty.",
16316
+ puddlangMcpEventsSchema,
16317
+ true
16318
+ ],
16319
+ [
16320
+ "puddlang_cancel",
16321
+ "Cancel a run, interrupt its pending asks, and stop agents it created. Attached agents are retained.",
16322
+ puddlangMcpIdSchema,
16323
+ false
16324
+ ]
16325
+ ];
16326
+ var puddlangMcpTools = definitions.map(([name, description, schema, readOnlyHint]) => ({
16327
+ name,
16328
+ description,
16329
+ inputSchema: external_exports.toJSONSchema(schema, { io: "input" }),
16330
+ annotations: {
16331
+ readOnlyHint,
16332
+ destructiveHint: !readOnlyHint,
16333
+ idempotentHint: true,
16334
+ openWorldHint: !readOnlyHint
16335
+ }
16336
+ }));
16337
+
16191
16338
  // ../shared/src/node/security.ts
16192
16339
  import { createHash, randomBytes } from "node:crypto";
16193
16340
  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: 22, minor: 5 };
3928
+ var PROTOCOL_VERSION = { major: 23, 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 = {};
@@ -20108,6 +20108,153 @@ var connectorNotificationSchema = external_exports.object({
20108
20108
  var pushDispatchResultSchema = external_exports.object({ accepted: external_exports.number().int().nonnegative(), failed: external_exports.number().int().nonnegative() }).strict();
20109
20109
  var pushPreferenceResultSchema = external_exports.object({ enabled: external_exports.boolean() }).strict();
20110
20110
 
20111
+ // ../shared/src/api/puddlang.ts
20112
+ var PUDDLANG_MAX_SOURCE = 256 * 1024;
20113
+ var sourceSchema = external_exports.string().min(1).max(PUDDLANG_MAX_SOURCE).refine(
20114
+ (source) => new TextEncoder().encode(source).length <= PUDDLANG_MAX_SOURCE,
20115
+ "Source exceeds 256 KiB"
20116
+ );
20117
+ var puddlangSpawnSchema = external_exports.object({
20118
+ agent: external_exports.string().min(1).max(100),
20119
+ account: external_exports.union([external_exports.string().min(1).max(100), external_exports.number().int().positive()]).optional(),
20120
+ project: external_exports.string().min(1).max(200).optional(),
20121
+ worktree: external_exports.string().min(1).max(4096).optional(),
20122
+ path: external_exports.string().min(1).max(4096).optional(),
20123
+ title: external_exports.string().min(1).max(200).optional()
20124
+ }).refine((v) => Boolean(v.path) !== Boolean(v.project), "Choose path or project").refine((v) => !v.path || !v.worktree, "worktree requires project");
20125
+ var puddlangHandleSchema = external_exports.object({ runtime_id: external_exports.uuid(), session_id: sessionId });
20126
+ var puddlangAskSchema = external_exports.object({
20127
+ prompt: external_exports.string().min(1).max(128 * 1024),
20128
+ output_schema: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
20129
+ });
20130
+ var puddlangStartSchema = external_exports.object({
20131
+ id: external_exports.uuid(),
20132
+ source: sourceSchema,
20133
+ input: external_exports.unknown().optional(),
20134
+ accounts: external_exports.record(external_exports.string(), external_exports.union([external_exports.string(), external_exports.number().int().positive()])).default({}),
20135
+ max_turns: external_exports.number().int().min(1).max(1e3).default(50),
20136
+ max_agents: external_exports.number().int().min(1).max(32).default(8),
20137
+ timeout_ms: external_exports.number().int().min(1e3).max(24 * 60 * 60 * 1e3).default(60 * 60 * 1e3)
20138
+ });
20139
+ var puddlangRunSchema = external_exports.object({
20140
+ id: external_exports.uuid(),
20141
+ profile_id: profileId,
20142
+ source_hash: external_exports.string(),
20143
+ status: external_exports.enum(["running", "completed", "failed", "cancelled", "interrupted"]),
20144
+ result: external_exports.unknown().nullable(),
20145
+ error: external_exports.string().nullable(),
20146
+ created_at: external_exports.string(),
20147
+ updated_at: external_exports.string()
20148
+ });
20149
+ var puddlangEventSchema = external_exports.object({
20150
+ sequence: external_exports.number().int(),
20151
+ run_id: external_exports.uuid(),
20152
+ type: external_exports.string(),
20153
+ data: external_exports.unknown(),
20154
+ created_at: external_exports.string()
20155
+ });
20156
+ var puddlangEventsSchema = external_exports.object({ events: external_exports.array(puddlangEventSchema) });
20157
+ var puddlangOperationSchema = external_exports.discriminatedUnion("op", [
20158
+ external_exports.object({ op: external_exports.literal("spawn"), options: puddlangSpawnSchema }),
20159
+ external_exports.object({ op: external_exports.literal("attach"), reference: external_exports.string().min(1).max(100) }),
20160
+ external_exports.object({ op: external_exports.literal("ask"), handle: puddlangHandleSchema, request: puddlangAskSchema }),
20161
+ external_exports.object({ op: external_exports.literal("stop"), handle: puddlangHandleSchema })
20162
+ ]);
20163
+ var puddlangRunnerMessageSchema = external_exports.discriminatedUnion("type", [
20164
+ external_exports.object({
20165
+ type: external_exports.literal("operation"),
20166
+ id: external_exports.number().int(),
20167
+ operation: puddlangOperationSchema
20168
+ }),
20169
+ external_exports.object({
20170
+ type: external_exports.literal("finished"),
20171
+ result: external_exports.unknown().optional(),
20172
+ error: external_exports.string().max(8192).optional()
20173
+ })
20174
+ ]);
20175
+ var puddlangRunnerInputSchema = external_exports.discriminatedUnion("type", [
20176
+ external_exports.object({
20177
+ type: external_exports.literal("start"),
20178
+ source: sourceSchema,
20179
+ input: external_exports.unknown().optional()
20180
+ }),
20181
+ external_exports.object({
20182
+ type: external_exports.literal("reply"),
20183
+ id: external_exports.number().int(),
20184
+ value: external_exports.unknown().optional(),
20185
+ error: external_exports.string().optional()
20186
+ })
20187
+ ]);
20188
+ var puddlangContextSchema = external_exports.object({
20189
+ profile: external_exports.object({ id: profileId, name: external_exports.string() }),
20190
+ projects: external_exports.array(external_exports.object({ id: external_exports.string(), name: external_exports.string(), path: external_exports.string() })),
20191
+ accounts: external_exports.array(
20192
+ external_exports.object({ id: external_exports.number(), label: external_exports.string(), agent: external_exports.string(), logged_in: external_exports.boolean() })
20193
+ ),
20194
+ agents: external_exports.array(external_exports.object({ id: external_exports.string(), scripted_turns: external_exports.boolean() }))
20195
+ });
20196
+
20197
+ // ../shared/src/api/puddlang-mcp.ts
20198
+ var puddlangMcpRequestSchema = external_exports.object({
20199
+ jsonrpc: external_exports.literal("2.0"),
20200
+ id: external_exports.union([external_exports.string(), external_exports.number()]).optional(),
20201
+ method: external_exports.string(),
20202
+ params: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
20203
+ });
20204
+ var puddlangMcpCallSchema = external_exports.object({
20205
+ name: external_exports.string(),
20206
+ arguments: external_exports.unknown().optional()
20207
+ });
20208
+ var puddlangMcpRunSchema = puddlangStartSchema;
20209
+ var puddlangMcpIdSchema = external_exports.object({ id: external_exports.uuid() });
20210
+ var puddlangMcpEventsSchema = puddlangMcpIdSchema.extend({
20211
+ after: external_exports.number().int().nonnegative().default(0)
20212
+ });
20213
+ var puddlangMcpEmptySchema = external_exports.object({}).strict();
20214
+ var definitions = [
20215
+ [
20216
+ "puddlang_context",
20217
+ "List this host profile, projects, accounts and supported agents.",
20218
+ puddlangMcpEmptySchema,
20219
+ true
20220
+ ],
20221
+ [
20222
+ "puddlang_run",
20223
+ 'Execute a trusted single-file TypeScript programme on the host. Imports: puddlang (spawn, attach, input, z), zod, node: built-ins. Returns immediately with a durable run id; use status/events. Supply a fresh UUID id, or reuse it with identical input to recover an uncertain submission. spawn({agent:"codex",project:"name",account:"label"}); await agent.ask("task"); export default result. Supports structured ask({prompt,input,schema:z.object(...)}) and agent.stop().',
20224
+ puddlangMcpRunSchema,
20225
+ false
20226
+ ],
20227
+ [
20228
+ "puddlang_status",
20229
+ "Read a run and its final default export, if finished.",
20230
+ puddlangMcpIdSchema,
20231
+ true
20232
+ ],
20233
+ [
20234
+ "puddlang_events",
20235
+ "Read up to 100 events after a sequence; paginate until empty.",
20236
+ puddlangMcpEventsSchema,
20237
+ true
20238
+ ],
20239
+ [
20240
+ "puddlang_cancel",
20241
+ "Cancel a run, interrupt its pending asks, and stop agents it created. Attached agents are retained.",
20242
+ puddlangMcpIdSchema,
20243
+ false
20244
+ ]
20245
+ ];
20246
+ var puddlangMcpTools = definitions.map(([name, description, schema, readOnlyHint]) => ({
20247
+ name,
20248
+ description,
20249
+ inputSchema: external_exports.toJSONSchema(schema, { io: "input" }),
20250
+ annotations: {
20251
+ readOnlyHint,
20252
+ destructiveHint: !readOnlyHint,
20253
+ idempotentHint: true,
20254
+ openWorldHint: !readOnlyHint
20255
+ }
20256
+ }));
20257
+
20111
20258
  // src/lib/transport/local.ts
20112
20259
  import { spawn } from "node:child_process";
20113
20260
  import { copyFileSync, mkdirSync, readFileSync } from "node:fs";
@@ -21646,7 +21793,7 @@ import { readFileSync as readFileSync4 } from "node:fs";
21646
21793
  import { dirname as dirname4, join as join5 } from "node:path";
21647
21794
  import { fileURLToPath as fileURLToPath2 } from "node:url";
21648
21795
  function cliVersion() {
21649
- if (true) return "0.2.24";
21796
+ if (true) return "0.3.0";
21650
21797
  const here = dirname4(fileURLToPath2(import.meta.url));
21651
21798
  for (const candidate of [
21652
21799
  join5(here, "..", "..", "package.json"),
@@ -22043,7 +22190,8 @@ var RELEASE_PROTOCOLS = {
22043
22190
  "0.2.21": { major: 22, minor: 4 },
22044
22191
  "0.2.22": { major: 22, minor: 4 },
22045
22192
  "0.2.23": { major: 22, minor: 5 },
22046
- "0.2.24": { major: 22, minor: 5 }
22193
+ "0.2.24": { major: 22, minor: 5 },
22194
+ "0.3.0": { major: 23, minor: 0 }
22047
22195
  };
22048
22196
  function validProtocol(value) {
22049
22197
  if (typeof value !== "object" || value === null) return false;
@@ -24313,9 +24461,14 @@ function standaloneInstallation(entryFile = fileURLToPath4(import.meta.url), exe
24313
24461
  try {
24314
24462
  const root = resolve5(release, "..", "..");
24315
24463
  const record2 = JSON.parse(readFileSync9(join15(root, "installation.json"), "utf8"));
24316
- if (readFileSync9(join15(release, "STANDALONE"), "utf8").trim() !== "puddle-cli" || readFileSync9(join15(root, "INSTALLATION"), "utf8").trim() !== "puddle-cli" || dirname9(release) !== join15(root, "versions") || realpathSync2(release) !== release || realpathSync2(execPath) !== join15(release, "bin/node") || record2.kind !== "puddle-cli" || typeof record2.launcher !== "string" || !isAbsolute(record2.launcher))
24464
+ if (readFileSync9(join15(release, "STANDALONE"), "utf8").trim() !== "puddle-cli" || readFileSync9(join15(root, "INSTALLATION"), "utf8").trim() !== "puddle-cli" || dirname9(release) !== join15(root, "versions") || realpathSync2(release) !== release || realpathSync2(execPath) !== join15(release, "bin/node") || record2.kind !== "puddle-cli" || typeof record2.launcher !== "string" || !isAbsolute(record2.launcher) || record2.scriptLauncher !== void 0 && record2.scriptLauncher !== join15(dirname9(record2.launcher), "puddlang"))
24317
24465
  throw new Error("Installation metadata does not match this CLI");
24318
- return { root, release, launcher: record2.launcher };
24466
+ return {
24467
+ root,
24468
+ release,
24469
+ launcher: record2.launcher,
24470
+ ...typeof record2.scriptLauncher === "string" ? { scriptLauncher: record2.scriptLauncher } : {}
24471
+ };
24319
24472
  } catch {
24320
24473
  throw new CliError(
24321
24474
  "not_installed",
@@ -24349,8 +24502,8 @@ function upgradeStandaloneCli(installation, version2, repo) {
24349
24502
  });
24350
24503
  });
24351
24504
  }
24352
- function standaloneLauncher(root) {
24353
- const quoted = `'${join15(root, "current/puddle").replaceAll("'", "'\\''")}'`;
24505
+ function standaloneLauncher(root, command = "puddle") {
24506
+ const quoted = `'${join15(root, `current/${command}`).replaceAll("'", "'\\''")}'`;
24354
24507
  return `#!/bin/sh
24355
24508
  # puddle standalone launcher
24356
24509
  exec ${quoted} "$@"
@@ -24366,6 +24519,11 @@ async function removeStandaloneCli(installation) {
24366
24519
  try {
24367
24520
  if (lstatSync2(installation.launcher).isSymbolicLink() || await readFile2(installation.launcher, "utf8") !== standaloneLauncher(installation.root))
24368
24521
  throw new CliError("not_installed", "the CLI launcher was replaced; refusing removal");
24522
+ if (installation.scriptLauncher && existsSync5(installation.scriptLauncher)) {
24523
+ if (!lstatSync2(installation.scriptLauncher).isFile() || await readFile2(installation.scriptLauncher, "utf8") !== standaloneLauncher(installation.root, "puddlang"))
24524
+ throw new CliError("not_installed", "the puddlang launcher was replaced; refusing removal");
24525
+ await unlink(installation.scriptLauncher);
24526
+ }
24369
24527
  await unlink(installation.launcher);
24370
24528
  await rm2(installation.root, { recursive: true, force: true });
24371
24529
  } finally {
@@ -125,16 +125,24 @@ main() {
125
125
  done
126
126
  # Help loads the bundle without touching a daemon or user state.
127
127
  "$STAGE/puddle" --help >/dev/null || die "CLI smoke test failed"
128
+ if [ -f "$STAGE/puddlang" ]; then
129
+ "$STAGE/puddlang" --help >/dev/null || die "puddlang smoke test failed"
130
+ fi
128
131
  "$STAGE/bin/node" --input-type=commonjs - "$PREFIX" "$BIN_DIR" "$STAGE" <<'NODE'
129
132
  const fs = require('node:fs'), path = require('node:path');
130
133
  const [root, binDir, stage] = process.argv.slice(2);
131
134
  const launcher = path.join(binDir, 'puddle');
132
135
  const quote = (s) => "'" + s.replaceAll("'", "'\\''") + "'";
133
136
  const wrapper = '#!/bin/sh\n# puddle standalone launcher\nexec ' + quote(path.join(root, 'current/puddle')) + ' "$@"\n';
137
+ const scriptLauncher = path.join(binDir, 'puddlang');
138
+ const scriptWrapper = '#!/bin/sh\n# puddle standalone launcher\nexec ' + quote(path.join(root, 'current/puddlang')) + ' "$@"\n';
139
+ const hasScript = fs.existsSync(path.join(stage, 'puddlang'));
134
140
  const stat = (p) => { try { return fs.lstatSync(p); } catch (e) { if (e.code === 'ENOENT') return null; throw e; } };
135
141
  if (stat(launcher) && (!stat(launcher).isFile() || fs.readFileSync(launcher, 'utf8') !== wrapper)) {
136
142
  throw Error('Refusing to replace an unrelated launcher: ' + launcher + '; choose --bin-dir');
137
143
  }
144
+ const ownsScript = stat(scriptLauncher)?.isFile() && fs.readFileSync(scriptLauncher, 'utf8') === scriptWrapper;
145
+ if (hasScript && stat(scriptLauncher) && !ownsScript) throw Error('Refusing to replace an unrelated launcher: ' + scriptLauncher + '; choose --bin-dir');
138
146
  const current = path.join(root, 'current');
139
147
  if (stat(current) && !stat(current).isSymbolicLink()) throw Error('current must be a symlink');
140
148
  const record = path.join(root, 'installation.json');
@@ -144,14 +152,17 @@ if (stat(record)) {
144
152
  }
145
153
  const tmp = '.new-' + process.pid;
146
154
  try {
147
- fs.writeFileSync(record + tmp, JSON.stringify({ kind: 'puddle-cli', launcher }) + '\n', { flag: 'wx', mode: 0o600 });
155
+ fs.writeFileSync(record + tmp, JSON.stringify({ kind: 'puddle-cli', launcher, ...(hasScript ? { scriptLauncher } : {}) }) + '\n', { flag: 'wx', mode: 0o600 });
148
156
  fs.writeFileSync(launcher + tmp, wrapper, { flag: 'wx', mode: 0o755 });
157
+ if (hasScript) fs.writeFileSync(scriptLauncher + tmp, scriptWrapper, { flag: 'wx', mode: 0o755 });
149
158
  fs.symlinkSync(path.relative(root, stage), current + tmp);
150
159
  fs.renameSync(record + tmp, record);
151
160
  fs.renameSync(launcher + tmp, launcher);
161
+ if (hasScript) fs.renameSync(scriptLauncher + tmp, scriptLauncher);
152
162
  fs.renameSync(current + tmp, current); // Activate only after every other write succeeds.
163
+ if (!hasScript && ownsScript) fs.unlinkSync(scriptLauncher); // Named older releases remain installable.
153
164
  } finally {
154
- for (const file of [record + tmp, launcher + tmp, current + tmp]) fs.rmSync(file, { force: true });
165
+ for (const file of [record + tmp, launcher + tmp, scriptLauncher + tmp, current + tmp]) fs.rmSync(file, { force: true });
155
166
  }
156
167
  NODE
157
168
  STAGE="" # Published releases stay intact, including those serving live cockpits.