@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.
- package/CHANGELOG.md +7 -3
- package/README.md +4 -0
- package/dist/host-control.mjs +147 -0
- package/dist/index.js +165 -7
- package/dist/install-cli.sh +13 -2
- package/dist/public/assets/{App-BYidYCu7.js → App-XpQccO6u.js} +2 -2
- package/dist/public/assets/{Dashboard-Dzjf0zET.js → Dashboard-DMEBtYwv.js} +1 -1
- package/dist/public/assets/{EditorTabClose-DKA1_wod.js → EditorTabClose-PbgNs_rN.js} +1 -1
- package/dist/public/assets/{FindWidget-AH805XK9.js → FindWidget-ZDHywlX4.js} +1 -1
- package/dist/public/assets/{LazyTerminal-Bqg0V2V8.js → LazyTerminal-DRgaFViU.js} +2 -2
- package/dist/public/assets/{ModelRefcount-5wOQD9So.js → ModelRefcount-CI3cYeQp.js} +1 -1
- package/dist/public/assets/{NewProjectDialog-B6E4_Y_p.js → NewProjectDialog-Bhfj_sYl.js} +1 -1
- package/dist/public/assets/{PaneEditorBody-LVZ3_6WO.js → PaneEditorBody-Bz74yrKU.js} +3 -3
- package/dist/public/assets/{PdfViewer-BGVCeFGN.js → PdfViewer-73_UlYnM.js} +2 -2
- package/dist/public/assets/{SettingsDialog-DKCK1la1.js → SettingsDialog-DJmvzJHQ.js} +1 -1
- package/dist/public/assets/{Terminal-BSDLWpgK.js → Terminal-BwuoWKED.js} +3 -3
- package/dist/public/assets/{Workspace-CR8tLiD8.js → Workspace-DPL1IKA6.js} +4 -4
- package/dist/public/assets/{abnfDiagram-VCTEODGH-FgX2dXui.js → abnfDiagram-VCTEODGH-AawOhIcj.js} +1 -1
- package/dist/public/assets/architecture-7GRP2DOG-BbAArV9u.js +1 -0
- package/dist/public/assets/{architectureDiagram-5GKGNRK7-CdJkD_Pz.js → architectureDiagram-5GKGNRK7-D9vP5DO8.js} +1 -1
- package/dist/public/assets/{blockDiagram-I7D4REHJ-DNbmvisu.js → blockDiagram-I7D4REHJ-Cm9i3cTT.js} +1 -1
- package/dist/public/assets/{buffer-store-BvXwuYnu.js → buffer-store-BIpSx_-b.js} +2 -2
- package/dist/public/assets/{button-CHEvj8hX.js → button-CgZcwDne.js} +1 -1
- package/dist/public/assets/{c4Diagram-7LVT6UL2-CjD9lD8i.js → c4Diagram-7LVT6UL2-BiN1-NKB.js} +1 -1
- package/dist/public/assets/channel-CUWW1WRo.js +1 -0
- package/dist/public/assets/{chunk-2E4U76K2-SJhD4HB_.js → chunk-2E4U76K2-BxAMvG2q.js} +1 -1
- package/dist/public/assets/{chunk-4HAMMTFA-C_eKRFh0.js → chunk-4HAMMTFA-D4UgoMR5.js} +1 -1
- package/dist/public/assets/{chunk-75Z2AOVW-DRIbOeZi.js → chunk-75Z2AOVW-ViSC5KeO.js} +1 -1
- package/dist/public/assets/{chunk-CLGD4ZFX-CMf2IZk2.js → chunk-CLGD4ZFX-C1obqh7u.js} +1 -1
- package/dist/public/assets/{chunk-DU6HZSFF-PwbPwYnk.js → chunk-DU6HZSFF-Dd9xUi9L.js} +1 -1
- package/dist/public/assets/{chunk-F27PBJKO-Oq_sdoh3.js → chunk-F27PBJKO-S5xJlLKg.js} +1 -1
- package/dist/public/assets/{chunk-GMAD6QVW-Ck8EGVZC.js → chunk-GMAD6QVW-DXbO7ojE.js} +1 -1
- package/dist/public/assets/{chunk-GVQU2GXP-Ny1aeY0A.js → chunk-GVQU2GXP-vZ5Z6XwC.js} +1 -1
- package/dist/public/assets/{chunk-IMKFNOWR-fHImnlSZ.js → chunk-IMKFNOWR-BGcGac3f.js} +1 -1
- package/dist/public/assets/{chunk-L3NEJ4N5-BbUIctlf.js → chunk-L3NEJ4N5-BfxBma0T.js} +1 -1
- package/dist/public/assets/{chunk-OSK3NFVY-hqM-ZrkL.js → chunk-OSK3NFVY-BaWjSKfn.js} +1 -1
- package/dist/public/assets/{chunk-P2QGCYS3-B23zjSSj.js → chunk-P2QGCYS3-Ce8Ukv1J.js} +1 -1
- package/dist/public/assets/{chunk-POPQ4Y6H-GEEn3V5D.js → chunk-POPQ4Y6H-lrRlaehc.js} +1 -1
- package/dist/public/assets/{chunk-PWAF6VOD-DW1kCowt.js → chunk-PWAF6VOD-DcoK5-E2.js} +1 -1
- package/dist/public/assets/{chunk-SHT3W25Y-DmDCmUrG.js → chunk-SHT3W25Y-BWdHabuP.js} +1 -1
- package/dist/public/assets/{chunk-SVP7TREG-DwlrYDnP.js → chunk-SVP7TREG-CfpAvBiO.js} +1 -1
- package/dist/public/assets/{chunk-TICWLB2K-C5NBrDW2.js → chunk-TICWLB2K-BnqQqZIp.js} +1 -1
- package/dist/public/assets/{chunk-TLUHSLCS-COQ_6Xv5.js → chunk-TLUHSLCS-Cd6EShzW.js} +2 -2
- package/dist/public/assets/classDiagram-ZZMXUADV-Cve4a5Gc.js +1 -0
- package/dist/public/assets/classDiagram-v2-VYDZK3BY-Cve4a5Gc.js +1 -0
- package/dist/public/assets/{context-menu-DofF0Gza.js → context-menu-CtKnUzHa.js} +1 -1
- package/dist/public/assets/{copy-BW2fd4uA.js → copy-Xz4fK2YI.js} +1 -1
- package/dist/public/assets/{cssMode-B4htuRa7.js → cssMode-CNBJ-DrN.js} +1 -1
- package/dist/public/assets/{cynefin-OW5HDTMX-DypMTjQw.js → cynefin-OW5HDTMX-C1-MjjCZ.js} +1 -1
- package/dist/public/assets/{cynefinDiagram-5FMLGOSQ-WLacyiJj.js → cynefinDiagram-5FMLGOSQ-xt5hQJ88.js} +1 -1
- package/dist/public/assets/{dagre-GXQ25YYZ-DaKOhMFv.js → dagre-GXQ25YYZ-Bgahh86t.js} +1 -1
- package/dist/public/assets/{diagram-S7CK7UJ4-DIwi33o4.js → diagram-S7CK7UJ4-Djip7YHP.js} +1 -1
- package/dist/public/assets/{diagram-UQ7AKVKN-x_QCuDjf.js → diagram-UQ7AKVKN-StD7DYFa.js} +1 -1
- package/dist/public/assets/{diagram-VSXAHHWV-Bjr6LKcx.js → diagram-VSXAHHWV-C6W2XMTF.js} +1 -1
- package/dist/public/assets/{diagram-VX7I27RA-BQ1d8ghu.js → diagram-VX7I27RA-C5rBIjxM.js} +1 -1
- package/dist/public/assets/{diagram-Z3DM3KII-CN1JdLeI.js → diagram-Z3DM3KII-DDzmZnRU.js} +1 -1
- package/dist/public/assets/{dialog-DPE0j1Ok.js → dialog-_JRACgt4.js} +1 -1
- package/dist/public/assets/{disclosure-BmYZGR3p.js → disclosure-DBXM9uBm.js} +1 -1
- package/dist/public/assets/{dist-BROMyZLV.js → dist-Bl7vUoam.js} +1 -1
- package/dist/public/assets/{dist-B1jh4y60.js → dist-CzEdee3K.js} +1 -1
- package/dist/public/assets/{ebnfDiagram-PWID7BFC-BWTV2Lw8.js → ebnfDiagram-PWID7BFC-TJlh5Fea.js} +1 -1
- package/dist/public/assets/{erDiagram-RLTQ6QDP-DiYZY7fZ.js → erDiagram-RLTQ6QDP-BSNVCw_x.js} +1 -1
- package/dist/public/assets/{errors-CZ1Lhnki.js → errors-BzfxU_Kw.js} +1 -1
- package/dist/public/assets/eventmodeling-NTZA5JFV-DZ8G1RJ1.js +1 -0
- package/dist/public/assets/flowDiagram-HODETNUW-Dd9WpTU6.js +1 -0
- package/dist/public/assets/{ganttDiagram-EL5Y4UJY-ChyMBO-e.js → ganttDiagram-EL5Y4UJY-BGFNgCoM.js} +1 -1
- package/dist/public/assets/{gitGraph-4MIJSDKK-qX2_zEiU.js → gitGraph-4MIJSDKK-Du3WBCxU.js} +1 -1
- package/dist/public/assets/{gitGraphDiagram-WWUBYQGX-DJb4bV4o.js → gitGraphDiagram-WWUBYQGX-Dq_yAVmM.js} +1 -1
- package/dist/public/assets/{htmlMode-BaQBKHvn.js → htmlMode-BWm5ayBQ.js} +1 -1
- package/dist/public/assets/index-BP-EF5G2.js +82 -0
- package/dist/public/assets/{info-A6RAGUB7-t5cYX1fg.js → info-A6RAGUB7-V0hlAV3d.js} +1 -1
- package/dist/public/assets/{infoDiagram-27XIBGKW-CoS-Nsq6.js → infoDiagram-27XIBGKW-DZM1jHkq.js} +1 -1
- package/dist/public/assets/{ishikawaDiagram-5VMMS53U-DaKttTut.js → ishikawaDiagram-5VMMS53U-CZlO72MU.js} +1 -1
- package/dist/public/assets/{journeyDiagram-3NMN7TZE-kLaNVwdB.js → journeyDiagram-3NMN7TZE-DZZieltZ.js} +1 -1
- package/dist/public/assets/{jsonMode-DhacIbdT.js → jsonMode-DA3Di61-.js} +1 -1
- package/dist/public/assets/{kanban-definition-UXKFOSKX-sBx71npp.js → kanban-definition-UXKFOSKX-BAFfgDCD.js} +1 -1
- package/dist/public/assets/{line-B6tFaQMh.js → line-DNRJuk5l.js} +1 -1
- package/dist/public/assets/{markdown-mermaid-C56AFLzi.js → markdown-mermaid-zldCuMow.js} +2 -2
- package/dist/public/assets/{math-S65D25xf.js → math-Bl0zHVK2.js} +1 -1
- package/dist/public/assets/{media-refresh-store-BhfM9D0i.js → media-refresh-store-BemN_6sc.js} +1 -1
- package/dist/public/assets/{mermaid-parser.core-D4kJBS6w.js → mermaid-parser.core-DpOHgT8D.js} +3 -3
- package/dist/public/assets/{mermaid.core-Cne_RySy.js → mermaid.core-DuO1Atct.js} +3 -3
- package/dist/public/assets/{mindmap-definition-YA3MSWOX-BEhzKX0Z.js → mindmap-definition-YA3MSWOX-Bbgshnhk.js} +1 -1
- package/dist/public/assets/{notification-delivery-BNxj08z5.js → notification-delivery-DehaYHWS.js} +1 -1
- package/dist/public/assets/{packet-AYTQ26CC-BzfZcYUP.js → packet-AYTQ26CC-H2b8zBMM.js} +1 -1
- package/dist/public/assets/{pdf-Cg-HiUjy.js → pdf-DTc2umrm.js} +1 -1
- package/dist/public/assets/{pegDiagram-XKGWAZYB-DzpbUJ7d.js → pegDiagram-XKGWAZYB-BKdl5Qrn.js} +1 -1
- package/dist/public/assets/{pie-WAS4IAKB-DNKuxanW.js → pie-WAS4IAKB-SB8x1Dpp.js} +1 -1
- package/dist/public/assets/{pieDiagram-E7YTZNPT-BeOnYivs.js → pieDiagram-E7YTZNPT-YXMNp-5O.js} +1 -1
- package/dist/public/assets/{project-abbrev-CKBTuDt5.js → project-abbrev-D7aa-LGS.js} +1 -1
- package/dist/public/assets/{protocol-support-B-0f1eJ3.js → protocol-support-Dm8bEo7Y.js} +1 -1
- package/dist/public/assets/{quadrantDiagram-AXDQQJYC-D5RU0BZ9.js → quadrantDiagram-AXDQQJYC-B2TAChhA.js} +1 -1
- package/dist/public/assets/{radar-RG4KPBEZ-C-7t5hsN.js → radar-RG4KPBEZ-D2xzXNL8.js} +1 -1
- package/dist/public/assets/{railroad-74A4TZTK-CaVM2B69.js → railroad-74A4TZTK-CKug6hj8.js} +1 -1
- package/dist/public/assets/railroad-abnf-HS5TGJTU-cj9XZHow.js +1 -0
- package/dist/public/assets/railroad-ebnf-LZEXJU2U-CCIfyLjg.js +1 -0
- package/dist/public/assets/railroad-peg-WCYAUIDC-DkxYDi7O.js +1 -0
- package/dist/public/assets/{railroadDiagram-O6MQD6OU-DxkTp-H6.js → railroadDiagram-O6MQD6OU-Bft2oh-d.js} +1 -1
- package/dist/public/assets/{requirementDiagram-BXWQKSXE-DXsUjGlL.js → requirementDiagram-BXWQKSXE-e0GCEfhM.js} +1 -1
- package/dist/public/assets/{sankeyDiagram-P5KCCOFB-CjlMAu4N.js → sankeyDiagram-P5KCCOFB-Csb70YNA.js} +1 -1
- package/dist/public/assets/{scroll-restoration-BMX0q1d6.js → scroll-restoration-D7f4DDsJ.js} +1 -1
- package/dist/public/assets/{selection-actions-BnvTzlOF.js → selection-actions-D5wKfiBu.js} +1 -1
- package/dist/public/assets/{sequenceDiagram-WJ2MYXX4-B8pW_U2s.js → sequenceDiagram-WJ2MYXX4-DcnD8T30.js} +1 -1
- package/dist/public/assets/{stateDiagram-D77RDMKH-C4649vJ_.js → stateDiagram-D77RDMKH-GnwFUlNg.js} +1 -1
- package/dist/public/assets/stateDiagram-v2-MP3YSRHH-Bktkoy9c.js +1 -0
- package/dist/public/assets/{swimlanes-42K2YHIH-D2bi0IkJ.js → swimlanes-42K2YHIH-CPq_eKyi.js} +1 -1
- package/dist/public/assets/swimlanesDiagram-VR7AAH4N-BmjIwfwd.js +8 -0
- package/dist/public/assets/{switch-CEs7mmdu.js → switch-DZbOKnZ0.js} +1 -1
- package/dist/public/assets/{timeline-definition-24CTP7MA-D55uisDI.js → timeline-definition-24CTP7MA-DjUPAJJx.js} +1 -1
- package/dist/public/assets/{treeView-Q6P3EWNA-BTfpSxF_.js → treeView-Q6P3EWNA-DBuhlxaq.js} +1 -1
- package/dist/public/assets/{treemap-WGGIJYW6-Ck20fjtW.js → treemap-WGGIJYW6-3TKwSIeh.js} +1 -1
- package/dist/public/assets/{tsMode-BiJ1tmbK.js → tsMode-BYwFH3pC.js} +1 -1
- package/dist/public/assets/{use-ui-state-DMXseT3q.js → use-ui-state-BXROVbIw.js} +1 -1
- package/dist/public/assets/{vennDiagram-4TSXK5OY-BKNs6Vhx.js → vennDiagram-4TSXK5OY-oDrGN_Dh.js} +1 -1
- package/dist/public/assets/{view-state-store-B64Y8syO.js → view-state-store-vUrDt7wu.js} +1 -1
- package/dist/public/assets/{wardley-WFR3VGLG-sC7irUb3.js → wardley-WFR3VGLG-Br5CacuJ.js} +1 -1
- package/dist/public/assets/{wardleyDiagram-VM6X3IG4-BwmBuIAi.js → wardleyDiagram-VM6X3IG4-Cw_uOLXA.js} +1 -1
- package/dist/public/assets/{ws-Djpdj45w.js → ws-Ug1Tr2sh.js} +1 -1
- package/dist/public/assets/{xychartDiagram-S5SC5T6Z-IfkSgCyl.js → xychartDiagram-S5SC5T6Z-Cl8gNx_J.js} +1 -1
- package/dist/public/index.html +1 -1
- package/dist/puddlang.js +17578 -0
- package/package.json +3 -2
- package/dist/public/assets/architecture-7GRP2DOG-BtJFkJAN.js +0 -1
- package/dist/public/assets/channel-Cdoqj1v0.js +0 -1
- package/dist/public/assets/classDiagram-ZZMXUADV-BgnwaWPy.js +0 -1
- package/dist/public/assets/classDiagram-v2-VYDZK3BY-BgnwaWPy.js +0 -1
- package/dist/public/assets/eventmodeling-NTZA5JFV-RcT3PESX.js +0 -1
- package/dist/public/assets/flowDiagram-HODETNUW-DwQ7P0aM.js +0 -1
- package/dist/public/assets/index-yGQSODPf.js +0 -82
- package/dist/public/assets/railroad-abnf-HS5TGJTU-BU_CVJO3.js +0 -1
- package/dist/public/assets/railroad-ebnf-LZEXJU2U-DfYF2tn-.js +0 -1
- package/dist/public/assets/railroad-peg-WCYAUIDC-DjlDlAsc.js +0 -1
- package/dist/public/assets/stateDiagram-v2-MP3YSRHH-z1utsNYA.js +0 -1
- 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.
|
|
7
|
+
## [0.3.0] — 2026-10-14
|
|
8
8
|
|
|
9
|
-
###
|
|
9
|
+
### Added
|
|
10
10
|
|
|
11
|
-
-
|
|
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
|
package/dist/host-control.mjs
CHANGED
|
@@ -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:
|
|
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.
|
|
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 {
|
|
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,
|
|
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 {
|
package/dist/install-cli.sh
CHANGED
|
@@ -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.
|