@puddle-code/cli 0.2.24 → 0.3.1
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 -2
- package/README.md +4 -0
- package/dist/host-control.mjs +147 -0
- package/dist/index.js +171 -8
- package/dist/install-cli.sh +24 -2
- package/dist/public/assets/App-CNmIJjl_.js +2 -0
- package/dist/public/assets/{Dashboard-Dzjf0zET.js → Dashboard-CXo8Im5Y.js} +1 -1
- package/dist/public/assets/{EditorTabClose-DKA1_wod.js → EditorTabClose--kyKHSwZ.js} +1 -1
- package/dist/public/assets/{FindWidget-AH805XK9.js → FindWidget-PycvFKIo.js} +1 -1
- package/dist/public/assets/{LazyTerminal-Bqg0V2V8.js → LazyTerminal-CAhb0T8p.js} +2 -2
- package/dist/public/assets/{ModelRefcount-5wOQD9So.js → ModelRefcount-DaHZ2vpK.js} +1 -1
- package/dist/public/assets/{NewProjectDialog-B6E4_Y_p.js → NewProjectDialog-BWkhYVKJ.js} +1 -1
- package/dist/public/assets/{PaneEditorBody-LVZ3_6WO.js → PaneEditorBody-DKpaey4n.js} +3 -3
- package/dist/public/assets/{PdfViewer-BGVCeFGN.js → PdfViewer-B-O3C5Fb.js} +2 -2
- package/dist/public/assets/{SettingsDialog-DKCK1la1.js → SettingsDialog-DxI5UQty.js} +1 -1
- package/dist/public/assets/{Terminal-BSDLWpgK.js → Terminal-DE7QO3Lv.js} +4 -4
- package/dist/public/assets/Workspace-CcPBZYc6.js +20 -0
- package/dist/public/assets/{abnfDiagram-VCTEODGH-FgX2dXui.js → abnfDiagram-VCTEODGH-Bn8NH7EO.js} +1 -1
- package/dist/public/assets/architecture-7GRP2DOG-Di8Z0gNN.js +1 -0
- package/dist/public/assets/{architectureDiagram-5GKGNRK7-CdJkD_Pz.js → architectureDiagram-5GKGNRK7-rXpMU6RM.js} +1 -1
- package/dist/public/assets/{blockDiagram-I7D4REHJ-DNbmvisu.js → blockDiagram-I7D4REHJ-BnnIsbDF.js} +1 -1
- package/dist/public/assets/{buffer-store-BvXwuYnu.js → buffer-store-B24QspY2.js} +2 -2
- package/dist/public/assets/{button-CHEvj8hX.js → button-CcKBhdZO.js} +1 -1
- package/dist/public/assets/{c4Diagram-7LVT6UL2-CjD9lD8i.js → c4Diagram-7LVT6UL2-CSC_Hbql.js} +1 -1
- package/dist/public/assets/channel-BpgRfG_m.js +1 -0
- package/dist/public/assets/{chunk-2E4U76K2-SJhD4HB_.js → chunk-2E4U76K2-BBFx22L7.js} +1 -1
- package/dist/public/assets/{chunk-4HAMMTFA-C_eKRFh0.js → chunk-4HAMMTFA-CFf6LTHp.js} +1 -1
- package/dist/public/assets/{chunk-75Z2AOVW-DRIbOeZi.js → chunk-75Z2AOVW-DmsoAjw5.js} +1 -1
- package/dist/public/assets/{chunk-CLGD4ZFX-CMf2IZk2.js → chunk-CLGD4ZFX-Dx1fE4HX.js} +1 -1
- package/dist/public/assets/{chunk-DU6HZSFF-PwbPwYnk.js → chunk-DU6HZSFF-p5k9qXhh.js} +1 -1
- package/dist/public/assets/{chunk-F27PBJKO-Oq_sdoh3.js → chunk-F27PBJKO-BSaAmHi0.js} +1 -1
- package/dist/public/assets/{chunk-GMAD6QVW-Ck8EGVZC.js → chunk-GMAD6QVW-Dna8BJJq.js} +1 -1
- package/dist/public/assets/{chunk-GVQU2GXP-Ny1aeY0A.js → chunk-GVQU2GXP-DOhlGSDl.js} +1 -1
- package/dist/public/assets/{chunk-IMKFNOWR-fHImnlSZ.js → chunk-IMKFNOWR-D65oIwAv.js} +1 -1
- package/dist/public/assets/{chunk-L3NEJ4N5-BbUIctlf.js → chunk-L3NEJ4N5-BwcBPm7M.js} +1 -1
- package/dist/public/assets/{chunk-OSK3NFVY-hqM-ZrkL.js → chunk-OSK3NFVY-82MNmgWe.js} +1 -1
- package/dist/public/assets/{chunk-P2QGCYS3-B23zjSSj.js → chunk-P2QGCYS3-CfrZ7JB4.js} +1 -1
- package/dist/public/assets/{chunk-POPQ4Y6H-GEEn3V5D.js → chunk-POPQ4Y6H-CHs8yAQU.js} +1 -1
- package/dist/public/assets/{chunk-PWAF6VOD-DW1kCowt.js → chunk-PWAF6VOD-BXxrEmLT.js} +1 -1
- package/dist/public/assets/{chunk-SHT3W25Y-DmDCmUrG.js → chunk-SHT3W25Y-DMUmvTem.js} +1 -1
- package/dist/public/assets/{chunk-SVP7TREG-DwlrYDnP.js → chunk-SVP7TREG-CPru3m3o.js} +1 -1
- package/dist/public/assets/{chunk-TICWLB2K-C5NBrDW2.js → chunk-TICWLB2K-zN8e4oYt.js} +1 -1
- package/dist/public/assets/{chunk-TLUHSLCS-COQ_6Xv5.js → chunk-TLUHSLCS-D9SadBk_.js} +2 -2
- package/dist/public/assets/classDiagram-ZZMXUADV-Cvjt82YE.js +1 -0
- package/dist/public/assets/classDiagram-v2-VYDZK3BY-Cvjt82YE.js +1 -0
- package/dist/public/assets/{context-menu-DofF0Gza.js → context-menu-DeidX0Pi.js} +1 -1
- package/dist/public/assets/{copy-BW2fd4uA.js → copy-DWjBcRsB.js} +1 -1
- package/dist/public/assets/{cssMode-B4htuRa7.js → cssMode-CZGyU_SG.js} +1 -1
- package/dist/public/assets/{cynefin-OW5HDTMX-DypMTjQw.js → cynefin-OW5HDTMX-DWHI9hMS.js} +1 -1
- package/dist/public/assets/{cynefinDiagram-5FMLGOSQ-WLacyiJj.js → cynefinDiagram-5FMLGOSQ-D6ufz00C.js} +1 -1
- package/dist/public/assets/{dagre-GXQ25YYZ-DaKOhMFv.js → dagre-GXQ25YYZ-t9AbgVhY.js} +1 -1
- package/dist/public/assets/{diagram-S7CK7UJ4-DIwi33o4.js → diagram-S7CK7UJ4-BldMPLHQ.js} +1 -1
- package/dist/public/assets/{diagram-UQ7AKVKN-x_QCuDjf.js → diagram-UQ7AKVKN-D9T4tJbc.js} +1 -1
- package/dist/public/assets/{diagram-VSXAHHWV-Bjr6LKcx.js → diagram-VSXAHHWV-Dh7CRewi.js} +1 -1
- package/dist/public/assets/{diagram-VX7I27RA-BQ1d8ghu.js → diagram-VX7I27RA-DtaAnFuF.js} +1 -1
- package/dist/public/assets/{diagram-Z3DM3KII-CN1JdLeI.js → diagram-Z3DM3KII-Bu1-SbmM.js} +1 -1
- package/dist/public/assets/{dialog-DPE0j1Ok.js → dialog-CxBgPsab.js} +1 -1
- package/dist/public/assets/{disclosure-BmYZGR3p.js → disclosure-BH-wuD_D.js} +1 -1
- package/dist/public/assets/{dist-BROMyZLV.js → dist-D5t_kbYW.js} +1 -1
- package/dist/public/assets/{dist-B1jh4y60.js → dist-qyIRFVt1.js} +1 -1
- package/dist/public/assets/{ebnfDiagram-PWID7BFC-BWTV2Lw8.js → ebnfDiagram-PWID7BFC-DInnl0wx.js} +1 -1
- package/dist/public/assets/{erDiagram-RLTQ6QDP-DiYZY7fZ.js → erDiagram-RLTQ6QDP-C359QLoG.js} +1 -1
- package/dist/public/assets/{errors-CZ1Lhnki.js → errors-1cUzcK5v.js} +1 -1
- package/dist/public/assets/eventmodeling-NTZA5JFV-BQVYxt7A.js +1 -0
- package/dist/public/assets/flowDiagram-HODETNUW--HTl_4V1.js +1 -0
- package/dist/public/assets/{ganttDiagram-EL5Y4UJY-ChyMBO-e.js → ganttDiagram-EL5Y4UJY-xq_Yuf1R.js} +1 -1
- package/dist/public/assets/{gitGraph-4MIJSDKK-qX2_zEiU.js → gitGraph-4MIJSDKK-U5qKRzrG.js} +1 -1
- package/dist/public/assets/{gitGraphDiagram-WWUBYQGX-DJb4bV4o.js → gitGraphDiagram-WWUBYQGX-BcXQM8eP.js} +1 -1
- package/dist/public/assets/{htmlMode-BaQBKHvn.js → htmlMode-23yFfFGb.js} +1 -1
- package/dist/public/assets/index-CPDXsNn7.js +82 -0
- package/dist/public/assets/{info-A6RAGUB7-t5cYX1fg.js → info-A6RAGUB7-BXjSF_iH.js} +1 -1
- package/dist/public/assets/{infoDiagram-27XIBGKW-CoS-Nsq6.js → infoDiagram-27XIBGKW-BIJ52Gpm.js} +1 -1
- package/dist/public/assets/{ishikawaDiagram-5VMMS53U-DaKttTut.js → ishikawaDiagram-5VMMS53U-Bob975Xt.js} +1 -1
- package/dist/public/assets/{journeyDiagram-3NMN7TZE-kLaNVwdB.js → journeyDiagram-3NMN7TZE-x9ssExSV.js} +1 -1
- package/dist/public/assets/{jsonMode-DhacIbdT.js → jsonMode-CmlPrpF1.js} +1 -1
- package/dist/public/assets/{kanban-definition-UXKFOSKX-sBx71npp.js → kanban-definition-UXKFOSKX-Cy8SkNND.js} +1 -1
- package/dist/public/assets/{line-B6tFaQMh.js → line-C0YxHEKk.js} +1 -1
- package/dist/public/assets/{markdown-mermaid-C56AFLzi.js → markdown-mermaid-wVNP7t8F.js} +2 -2
- package/dist/public/assets/{math-S65D25xf.js → math-B4Pf1FaR.js} +1 -1
- package/dist/public/assets/{media-refresh-store-BhfM9D0i.js → media-refresh-store-CcMOJ-U-.js} +1 -1
- package/dist/public/assets/{mermaid-parser.core-D4kJBS6w.js → mermaid-parser.core-Cy8AG-qQ.js} +3 -3
- package/dist/public/assets/{mermaid.core-Cne_RySy.js → mermaid.core-DoDuR-5f.js} +3 -3
- package/dist/public/assets/{mindmap-definition-YA3MSWOX-BEhzKX0Z.js → mindmap-definition-YA3MSWOX-B6ghAwaT.js} +1 -1
- package/dist/public/assets/{notification-delivery-BNxj08z5.js → notification-delivery-0LhR-ShC.js} +1 -1
- package/dist/public/assets/{packet-AYTQ26CC-BzfZcYUP.js → packet-AYTQ26CC-BpWwI2oX.js} +1 -1
- package/dist/public/assets/{pdf-Cg-HiUjy.js → pdf-C7rjnygQ.js} +1 -1
- package/dist/public/assets/{pegDiagram-XKGWAZYB-DzpbUJ7d.js → pegDiagram-XKGWAZYB-yj3GPtMG.js} +1 -1
- package/dist/public/assets/{pie-WAS4IAKB-DNKuxanW.js → pie-WAS4IAKB-DvE_icUX.js} +1 -1
- package/dist/public/assets/{pieDiagram-E7YTZNPT-BeOnYivs.js → pieDiagram-E7YTZNPT-DdwpR7qt.js} +1 -1
- package/dist/public/assets/{project-abbrev-CKBTuDt5.js → project-abbrev-DUQCetLc.js} +1 -1
- package/dist/public/assets/{protocol-support-B-0f1eJ3.js → protocol-support-DWTHwckn.js} +1 -1
- package/dist/public/assets/{quadrantDiagram-AXDQQJYC-D5RU0BZ9.js → quadrantDiagram-AXDQQJYC-DRGzxdVf.js} +1 -1
- package/dist/public/assets/{radar-RG4KPBEZ-C-7t5hsN.js → radar-RG4KPBEZ-BMUoktqq.js} +1 -1
- package/dist/public/assets/{railroad-74A4TZTK-CaVM2B69.js → railroad-74A4TZTK-CRCU-hfz.js} +1 -1
- package/dist/public/assets/railroad-abnf-HS5TGJTU-DgF_7Rby.js +1 -0
- package/dist/public/assets/railroad-ebnf-LZEXJU2U-yoQjOTe4.js +1 -0
- package/dist/public/assets/railroad-peg-WCYAUIDC-Bi2UnAcg.js +1 -0
- package/dist/public/assets/{railroadDiagram-O6MQD6OU-DxkTp-H6.js → railroadDiagram-O6MQD6OU-DoYXFCYn.js} +1 -1
- package/dist/public/assets/{requirementDiagram-BXWQKSXE-DXsUjGlL.js → requirementDiagram-BXWQKSXE-CSioB-S4.js} +1 -1
- package/dist/public/assets/{sankeyDiagram-P5KCCOFB-CjlMAu4N.js → sankeyDiagram-P5KCCOFB-Be_RNG6h.js} +1 -1
- package/dist/public/assets/{scroll-restoration-BMX0q1d6.js → scroll-restoration-C6CrXFrx.js} +1 -1
- package/dist/public/assets/{selection-actions-BnvTzlOF.js → selection-actions-BuV-nTRE.js} +1 -1
- package/dist/public/assets/{sequenceDiagram-WJ2MYXX4-B8pW_U2s.js → sequenceDiagram-WJ2MYXX4-QO7Ba1BQ.js} +1 -1
- package/dist/public/assets/{stateDiagram-D77RDMKH-C4649vJ_.js → stateDiagram-D77RDMKH-B52l08Ki.js} +1 -1
- package/dist/public/assets/stateDiagram-v2-MP3YSRHH-DyfZNcXp.js +1 -0
- package/dist/public/assets/{swimlanes-42K2YHIH-D2bi0IkJ.js → swimlanes-42K2YHIH-CEkCp-cn.js} +1 -1
- package/dist/public/assets/swimlanesDiagram-VR7AAH4N-9I9MU74C.js +8 -0
- package/dist/public/assets/{switch-CEs7mmdu.js → switch-B5sIV745.js} +1 -1
- package/dist/public/assets/{timeline-definition-24CTP7MA-D55uisDI.js → timeline-definition-24CTP7MA-0rICk4bz.js} +1 -1
- package/dist/public/assets/{treeView-Q6P3EWNA-BTfpSxF_.js → treeView-Q6P3EWNA-UwjA1jwm.js} +1 -1
- package/dist/public/assets/{treemap-WGGIJYW6-Ck20fjtW.js → treemap-WGGIJYW6-BWpfnhSW.js} +1 -1
- package/dist/public/assets/{tsMode-BiJ1tmbK.js → tsMode-iBk8vwDB.js} +1 -1
- package/dist/public/assets/{use-ui-state-DMXseT3q.js → use-ui-state-Bxj6PnLE.js} +1 -1
- package/dist/public/assets/{vennDiagram-4TSXK5OY-BKNs6Vhx.js → vennDiagram-4TSXK5OY-B1JUHS0H.js} +1 -1
- package/dist/public/assets/{view-state-store-B64Y8syO.js → view-state-store-B5KgrWCh.js} +1 -1
- package/dist/public/assets/{wardley-WFR3VGLG-sC7irUb3.js → wardley-WFR3VGLG-DGkljHJE.js} +1 -1
- package/dist/public/assets/{wardleyDiagram-VM6X3IG4-BwmBuIAi.js → wardleyDiagram-VM6X3IG4-WNi3mtNy.js} +1 -1
- package/dist/public/assets/{ws-Djpdj45w.js → ws-D9g0r8Jb.js} +1 -1
- package/dist/public/assets/{xychartDiagram-S5SC5T6Z-IfkSgCyl.js → xychartDiagram-S5SC5T6Z-CbKt4_V3.js} +1 -1
- package/dist/public/index.html +1 -1
- package/dist/pudl.js +17578 -0
- package/package.json +3 -2
- package/dist/public/assets/App-BYidYCu7.js +0 -2
- package/dist/public/assets/Workspace-CR8tLiD8.js +0 -20
- 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,13 @@ Archived release changelog. Governance lives in CLAUDE.md §"Changelog disciplin
|
|
|
4
4
|
|
|
5
5
|
# Changelog
|
|
6
6
|
|
|
7
|
-
## [0.
|
|
7
|
+
## [0.3.1] — 2026-10-14
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Rename the puddlang executable to `pudl` across npm, standalone installers and command examples; retain the puddlang language/API name.
|
|
12
|
+
- Suppress desktop notifications only during recent typing, pasting or clicking in the notifying session when focused delivery is disabled; idle windows and other sessions no longer silence alerts.
|
|
8
13
|
|
|
9
14
|
### Fixed
|
|
10
15
|
|
|
11
|
-
-
|
|
16
|
+
- Activate the exact session tab on desktop notification clicks, including when a file hides its terminal under the same URL, and open sessions without an existing tab.
|
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 `pudl`, which runs puddlang programmes for coder/reviewer
|
|
33
|
+
loops and other agent workflows 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.1";
|
|
21650
21797
|
const here = dirname4(fileURLToPath2(import.meta.url));
|
|
21651
21798
|
for (const candidate of [
|
|
21652
21799
|
join5(here, "..", "..", "package.json"),
|
|
@@ -22043,7 +22190,9 @@ 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 },
|
|
22195
|
+
"0.3.1": { major: 23, minor: 0 }
|
|
22047
22196
|
};
|
|
22048
22197
|
function validProtocol(value) {
|
|
22049
22198
|
if (typeof value !== "object" || value === null) return false;
|
|
@@ -24305,7 +24454,7 @@ init_types();
|
|
|
24305
24454
|
import { spawn as spawn6 } from "node:child_process";
|
|
24306
24455
|
import { existsSync as existsSync5, lstatSync as lstatSync2, readFileSync as readFileSync9, realpathSync as realpathSync2 } from "node:fs";
|
|
24307
24456
|
import { mkdir as mkdir2, readFile as readFile2, rm as rm2, unlink } from "node:fs/promises";
|
|
24308
|
-
import { dirname as dirname9, isAbsolute, join as join15, resolve as resolve5 } from "node:path";
|
|
24457
|
+
import { basename, dirname as dirname9, isAbsolute, join as join15, resolve as resolve5 } from "node:path";
|
|
24309
24458
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
24310
24459
|
function standaloneInstallation(entryFile = fileURLToPath4(import.meta.url), execPath = process.execPath) {
|
|
24311
24460
|
const release = resolve5(dirname9(entryFile), "..");
|
|
@@ -24313,9 +24462,14 @@ function standaloneInstallation(entryFile = fileURLToPath4(import.meta.url), exe
|
|
|
24313
24462
|
try {
|
|
24314
24463
|
const root = resolve5(release, "..", "..");
|
|
24315
24464
|
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))
|
|
24465
|
+
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), "pudl") && record2.scriptLauncher !== join15(dirname9(record2.launcher), "puddlang"))
|
|
24317
24466
|
throw new Error("Installation metadata does not match this CLI");
|
|
24318
|
-
return {
|
|
24467
|
+
return {
|
|
24468
|
+
root,
|
|
24469
|
+
release,
|
|
24470
|
+
launcher: record2.launcher,
|
|
24471
|
+
...typeof record2.scriptLauncher === "string" ? { scriptLauncher: record2.scriptLauncher } : {}
|
|
24472
|
+
};
|
|
24319
24473
|
} catch {
|
|
24320
24474
|
throw new CliError(
|
|
24321
24475
|
"not_installed",
|
|
@@ -24349,8 +24503,8 @@ function upgradeStandaloneCli(installation, version2, repo) {
|
|
|
24349
24503
|
});
|
|
24350
24504
|
});
|
|
24351
24505
|
}
|
|
24352
|
-
function standaloneLauncher(root) {
|
|
24353
|
-
const quoted = `'${join15(root,
|
|
24506
|
+
function standaloneLauncher(root, command = "puddle") {
|
|
24507
|
+
const quoted = `'${join15(root, `current/${command}`).replaceAll("'", "'\\''")}'`;
|
|
24354
24508
|
return `#!/bin/sh
|
|
24355
24509
|
# puddle standalone launcher
|
|
24356
24510
|
exec ${quoted} "$@"
|
|
@@ -24366,6 +24520,15 @@ async function removeStandaloneCli(installation) {
|
|
|
24366
24520
|
try {
|
|
24367
24521
|
if (lstatSync2(installation.launcher).isSymbolicLink() || await readFile2(installation.launcher, "utf8") !== standaloneLauncher(installation.root))
|
|
24368
24522
|
throw new CliError("not_installed", "the CLI launcher was replaced; refusing removal");
|
|
24523
|
+
if (installation.scriptLauncher && existsSync5(installation.scriptLauncher)) {
|
|
24524
|
+
const command = basename(installation.scriptLauncher);
|
|
24525
|
+
if (command !== "pudl" && command !== "puddlang" || !lstatSync2(installation.scriptLauncher).isFile() || await readFile2(installation.scriptLauncher, "utf8") !== standaloneLauncher(installation.root, command))
|
|
24526
|
+
throw new CliError(
|
|
24527
|
+
"not_installed",
|
|
24528
|
+
`the ${command} launcher was replaced; refusing removal`
|
|
24529
|
+
);
|
|
24530
|
+
await unlink(installation.scriptLauncher);
|
|
24531
|
+
}
|
|
24369
24532
|
await unlink(installation.launcher);
|
|
24370
24533
|
await rm2(installation.root, { recursive: true, force: true });
|
|
24371
24534
|
} finally {
|
package/dist/install-cli.sh
CHANGED
|
@@ -125,16 +125,29 @@ 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/pudl" ]; then
|
|
129
|
+
"$STAGE/pudl" --help >/dev/null || die "pudl smoke test failed"
|
|
130
|
+
elif [ -f "$STAGE/puddlang" ]; then
|
|
131
|
+
"$STAGE/puddlang" --help >/dev/null || die "puddlang smoke test failed"
|
|
132
|
+
fi
|
|
128
133
|
"$STAGE/bin/node" --input-type=commonjs - "$PREFIX" "$BIN_DIR" "$STAGE" <<'NODE'
|
|
129
134
|
const fs = require('node:fs'), path = require('node:path');
|
|
130
135
|
const [root, binDir, stage] = process.argv.slice(2);
|
|
131
136
|
const launcher = path.join(binDir, 'puddle');
|
|
132
137
|
const quote = (s) => "'" + s.replaceAll("'", "'\\''") + "'";
|
|
133
138
|
const wrapper = '#!/bin/sh\n# puddle standalone launcher\nexec ' + quote(path.join(root, 'current/puddle')) + ' "$@"\n';
|
|
139
|
+
// Older archives remain installable; current releases provide only pudl.
|
|
140
|
+
const scriptCommand = ['pudl', 'puddlang'].find((name) => fs.existsSync(path.join(stage, name)));
|
|
141
|
+
const scriptLauncher = path.join(binDir, scriptCommand || 'pudl');
|
|
142
|
+
const scriptWrapperFor = (name) => '#!/bin/sh\n# puddle standalone launcher\nexec ' + quote(path.join(root, 'current', name)) + ' "$@"\n';
|
|
143
|
+
const scriptWrapper = scriptWrapperFor(scriptCommand || 'pudl');
|
|
144
|
+
const hasScript = scriptCommand !== undefined;
|
|
134
145
|
const stat = (p) => { try { return fs.lstatSync(p); } catch (e) { if (e.code === 'ENOENT') return null; throw e; } };
|
|
135
146
|
if (stat(launcher) && (!stat(launcher).isFile() || fs.readFileSync(launcher, 'utf8') !== wrapper)) {
|
|
136
147
|
throw Error('Refusing to replace an unrelated launcher: ' + launcher + '; choose --bin-dir');
|
|
137
148
|
}
|
|
149
|
+
const ownsScript = stat(scriptLauncher)?.isFile() && fs.readFileSync(scriptLauncher, 'utf8') === scriptWrapper;
|
|
150
|
+
if (hasScript && stat(scriptLauncher) && !ownsScript) throw Error('Refusing to replace an unrelated launcher: ' + scriptLauncher + '; choose --bin-dir');
|
|
138
151
|
const current = path.join(root, 'current');
|
|
139
152
|
if (stat(current) && !stat(current).isSymbolicLink()) throw Error('current must be a symlink');
|
|
140
153
|
const record = path.join(root, 'installation.json');
|
|
@@ -144,14 +157,23 @@ if (stat(record)) {
|
|
|
144
157
|
}
|
|
145
158
|
const tmp = '.new-' + process.pid;
|
|
146
159
|
try {
|
|
147
|
-
fs.writeFileSync(record + tmp, JSON.stringify({ kind: 'puddle-cli', launcher }) + '\n', { flag: 'wx', mode: 0o600 });
|
|
160
|
+
fs.writeFileSync(record + tmp, JSON.stringify({ kind: 'puddle-cli', launcher, ...(hasScript ? { scriptLauncher } : {}) }) + '\n', { flag: 'wx', mode: 0o600 });
|
|
148
161
|
fs.writeFileSync(launcher + tmp, wrapper, { flag: 'wx', mode: 0o755 });
|
|
162
|
+
if (hasScript) fs.writeFileSync(scriptLauncher + tmp, scriptWrapper, { flag: 'wx', mode: 0o755 });
|
|
149
163
|
fs.symlinkSync(path.relative(root, stage), current + tmp);
|
|
150
164
|
fs.renameSync(record + tmp, record);
|
|
151
165
|
fs.renameSync(launcher + tmp, launcher);
|
|
166
|
+
if (hasScript) fs.renameSync(scriptLauncher + tmp, scriptLauncher);
|
|
152
167
|
fs.renameSync(current + tmp, current); // Activate only after every other write succeeds.
|
|
168
|
+
// Remove only exact wrappers owned by this installation when the command
|
|
169
|
+
// changes or a named older release does not contain a scripting command.
|
|
170
|
+
for (const name of ['pudl', 'puddlang']) {
|
|
171
|
+
if (name === scriptCommand) continue;
|
|
172
|
+
const obsolete = path.join(binDir, name);
|
|
173
|
+
if (stat(obsolete)?.isFile() && fs.readFileSync(obsolete, 'utf8') === scriptWrapperFor(name)) fs.unlinkSync(obsolete);
|
|
174
|
+
}
|
|
153
175
|
} finally {
|
|
154
|
-
for (const file of [record + tmp, launcher + tmp, current + tmp]) fs.rmSync(file, { force: true });
|
|
176
|
+
for (const file of [record + tmp, launcher + tmp, scriptLauncher + tmp, current + tmp]) fs.rmSync(file, { force: true });
|
|
155
177
|
}
|
|
156
178
|
NODE
|
|
157
179
|
STAGE="" # Published releases stay intact, including those serving live cockpits.
|