svamp-cli 0.1.50 → 0.1.52
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/dist/cli.mjs +25 -22
- package/dist/{commands-D-nIO_Sf.mjs → commands-1tmye7o_.mjs} +7 -3
- package/dist/{commands-D1brd9fB.mjs → commands-CI_BVphs.mjs} +7 -3
- package/dist/{commands-DHnFOhQC.mjs → commands-DcFOU9nW.mjs} +7 -3
- package/dist/commands-DwY2B7KW.mjs +562 -0
- package/dist/index.mjs +1 -1
- package/dist/{package-BLDik3NY.mjs → package-BRivSAkK.mjs} +1 -1
- package/dist/{package-BYUO-39f.mjs → package-D7EUXtnk.mjs} +1 -1
- package/dist/{run-BE_AIJ7z.mjs → run-BYJX5syg.mjs} +1 -1
- package/dist/{run-CE4H8ZiN.mjs → run-BnnUavlu.mjs} +199 -65
- package/dist/{run-BG3279Kg.mjs → run-Bw6aGHLA.mjs} +1 -1
- package/dist/{run-4li60ojK.mjs → run-DOwarObi.mjs} +1 -1
- package/dist/{run-C0ecvcRP.mjs → run-DxISzP_V.mjs} +63 -8
- package/dist/{run-Bc83CRUn.mjs → run-eYBOEaWw.mjs} +22 -7
- package/dist/tunnel-C2_V6y3d.mjs +299 -0
- package/package.json +1 -1
- package/dist/commands-4_MiOQVp.mjs +0 -1217
- package/dist/commands-8UAWGJrC.mjs +0 -1208
- package/dist/commands-8Wmq0uak.mjs +0 -1407
- package/dist/commands-8Xn02pQg.mjs +0 -1217
- package/dist/commands-9DPsh6ku.mjs +0 -1217
- package/dist/commands-9rMB13FP.mjs +0 -1214
- package/dist/commands-B-XaqFDB.mjs +0 -1407
- package/dist/commands-B53zuBHB.mjs +0 -1217
- package/dist/commands-B7yLt11i.mjs +0 -1217
- package/dist/commands-BDVAO_N2.mjs +0 -1217
- package/dist/commands-BD_NjWJL.mjs +0 -1217
- package/dist/commands-BEhSQqTp.mjs +0 -507
- package/dist/commands-BIFQZZGw.mjs +0 -1375
- package/dist/commands-BImRR1Wr.mjs +0 -1217
- package/dist/commands-BLmRIMdf.mjs +0 -1217
- package/dist/commands-BOYo9cdy.mjs +0 -1741
- package/dist/commands-BQ_347V_.mjs +0 -1374
- package/dist/commands-BTEmyf2m.mjs +0 -1407
- package/dist/commands-BVjcCbWS.mjs +0 -1375
- package/dist/commands-BVsLRttq.mjs +0 -1217
- package/dist/commands-BVuE0VQU.mjs +0 -507
- package/dist/commands-BY09VTpk.mjs +0 -1375
- package/dist/commands-Bcdp0X-o.mjs +0 -1217
- package/dist/commands-BdnG1cqQ.mjs +0 -1217
- package/dist/commands-BdvvRQIo.mjs +0 -1415
- package/dist/commands-Bgg_dvDw.mjs +0 -1683
- package/dist/commands-Bi0zYJvj.mjs +0 -1407
- package/dist/commands-BmirUCVt.mjs +0 -1208
- package/dist/commands-BpSUbvmr.mjs +0 -1217
- package/dist/commands-BuJ6xTfc.mjs +0 -1217
- package/dist/commands-BzbYPx0f.mjs +0 -1208
- package/dist/commands-C-RtFjJl.mjs +0 -1217
- package/dist/commands-C20_f6oo.mjs +0 -1217
- package/dist/commands-C6KDr9Yp.mjs +0 -1407
- package/dist/commands-C9TOoTCv.mjs +0 -1395
- package/dist/commands-C9TdN_El.mjs +0 -1683
- package/dist/commands-CFv6lO0D.mjs +0 -1217
- package/dist/commands-CJ2n5jS2.mjs +0 -1375
- package/dist/commands-CKEKQ_5B.mjs +0 -1217
- package/dist/commands-CQz67Rm1.mjs +0 -1395
- package/dist/commands-CRZbJjqN.mjs +0 -1375
- package/dist/commands-CToIvBFX.mjs +0 -1375
- package/dist/commands-CWsfciHn.mjs +0 -1217
- package/dist/commands-CYMSyqYC.mjs +0 -1395
- package/dist/commands-CZ7KPLLJ.mjs +0 -1217
- package/dist/commands-Cc73uUnP.mjs +0 -1375
- package/dist/commands-CdMsAD1-.mjs +0 -1217
- package/dist/commands-CdyCWC3y.mjs +0 -1395
- package/dist/commands-ClVCprrK.mjs +0 -1217
- package/dist/commands-Cnmf8znA.mjs +0 -1196
- package/dist/commands-CorUNLRF.mjs +0 -1375
- package/dist/commands-Cq0oj5_v.mjs +0 -1217
- package/dist/commands-CrdvbXPI.mjs +0 -1395
- package/dist/commands-Cw2Od6mc.mjs +0 -1683
- package/dist/commands-CwC2aVzu.mjs +0 -1217
- package/dist/commands-CxSCUJCB.mjs +0 -1217
- package/dist/commands-D-PTwdZz.mjs +0 -1217
- package/dist/commands-D7-NHH5q.mjs +0 -1407
- package/dist/commands-D7kH-7Vn.mjs +0 -1217
- package/dist/commands-DBv6A3aJ.mjs +0 -507
- package/dist/commands-DD3HXakm.mjs +0 -1217
- package/dist/commands-DLoe6FyK.mjs +0 -1375
- package/dist/commands-DPbH8KF0.mjs +0 -1217
- package/dist/commands-DUAQ9MZM.mjs +0 -1217
- package/dist/commands-DVw-P6-0.mjs +0 -1407
- package/dist/commands-DVygnMsh.mjs +0 -1217
- package/dist/commands-DWira-Cz.mjs +0 -1741
- package/dist/commands-DYTdUlul.mjs +0 -1217
- package/dist/commands-DZfaDmsk.mjs +0 -1374
- package/dist/commands-Dd8cn8mW.mjs +0 -1217
- package/dist/commands-DsIoygTL.mjs +0 -1395
- package/dist/commands-Du-fdLLu.mjs +0 -969
- package/dist/commands-DuJGOq1y.mjs +0 -1217
- package/dist/commands-DwBr3sBn.mjs +0 -1217
- package/dist/commands-DwveR96q.mjs +0 -1683
- package/dist/commands-DypTF36z.mjs +0 -506
- package/dist/commands-EUMJqBCs.mjs +0 -1407
- package/dist/commands-HLu7P96l.mjs +0 -1214
- package/dist/commands-HrBaGV-C.mjs +0 -1683
- package/dist/commands-Jk5no-DX.mjs +0 -1407
- package/dist/commands-KH5dj9dv.mjs +0 -1214
- package/dist/commands-LaNHVHjc.mjs +0 -1217
- package/dist/commands-O1Q9g00y.mjs +0 -1395
- package/dist/commands-OwMfbBrU.mjs +0 -1395
- package/dist/commands-SQ0Wp_kD.mjs +0 -1217
- package/dist/commands-S_MFQ9n1.mjs +0 -354
- package/dist/commands-T3q8VKCY.mjs +0 -1407
- package/dist/commands-Ugz9TtRu.mjs +0 -1420
- package/dist/commands-Wng0OuNY.mjs +0 -1683
- package/dist/commands-YBW5jFpy.mjs +0 -1217
- package/dist/commands-Z-CbuF8E.mjs +0 -1217
- package/dist/commands-fSZOP80Z.mjs +0 -1217
- package/dist/commands-fqBuJe1b.mjs +0 -1217
- package/dist/commands-g-1n3_Rp.mjs +0 -1395
- package/dist/commands-mC0oe0lj.mjs +0 -1217
- package/dist/commands-od2hOku5.mjs +0 -1217
- package/dist/commands-otgzprjb.mjs +0 -1375
- package/dist/commands-rhHI6Wb2.mjs +0 -1420
- package/dist/commands-zGHnUXh5.mjs +0 -1217
- package/dist/package-BMCjXPI9.mjs +0 -58
- package/dist/package-BPMWPlS0.mjs +0 -57
- package/dist/package-BaGfG8vL.mjs +0 -58
- package/dist/package-BkBE6ZdN.mjs +0 -57
- package/dist/package-BufekbY1.mjs +0 -57
- package/dist/package-C1hpYMj4.mjs +0 -57
- package/dist/package-CmIBOZtY.mjs +0 -57
- package/dist/package-CmVt1kdw.mjs +0 -58
- package/dist/package-Cn6Ya4A0.mjs +0 -57
- package/dist/package-Csd530Ym.mjs +0 -57
- package/dist/package-D6mNQtUs.mjs +0 -57
- package/dist/package-DG0AkZdm.mjs +0 -58
- package/dist/package-DRO1LpXW.mjs +0 -58
- package/dist/package-Dav8qh6X.mjs +0 -57
- package/dist/package-DiA55dzE.mjs +0 -57
- package/dist/package-UwLIU765.mjs +0 -58
- package/dist/package-k3XsdP9k.mjs +0 -58
- package/dist/package-rasGC9_z.mjs +0 -58
- package/dist/run-4B1XZQB8.mjs +0 -5426
- package/dist/run-4eArMb_9.mjs +0 -1050
- package/dist/run-67wfoMuo.mjs +0 -5383
- package/dist/run-6N2IdEX7.mjs +0 -5410
- package/dist/run-6dwQnoBL.mjs +0 -1051
- package/dist/run-7iQKryzo.mjs +0 -5383
- package/dist/run-7s8lOXqB.mjs +0 -1050
- package/dist/run-8kKykzTs.mjs +0 -5367
- package/dist/run-8mLZV2lg.mjs +0 -1050
- package/dist/run-9x7I9Ck-.mjs +0 -5264
- package/dist/run-B-PWtXF-.mjs +0 -5894
- package/dist/run-B1ivovUl.mjs +0 -5964
- package/dist/run-B1l9Ed8k.mjs +0 -5403
- package/dist/run-B2zRMxE0.mjs +0 -5508
- package/dist/run-B31biy0V.mjs +0 -1050
- package/dist/run-B5o5fMMd.mjs +0 -5369
- package/dist/run-B7V-xXM7.mjs +0 -5775
- package/dist/run-B9ND6srh.mjs +0 -6154
- package/dist/run-BHZNzX1F.mjs +0 -5235
- package/dist/run-BKdOv7gX.mjs +0 -1050
- package/dist/run-BLySdZ1K.mjs +0 -5251
- package/dist/run-BOVkQfM-.mjs +0 -1050
- package/dist/run-BQ0lIare.mjs +0 -1050
- package/dist/run-BREPr7Yc.mjs +0 -5508
- package/dist/run-BTwshVk1.mjs +0 -5728
- package/dist/run-BUL3eAqT.mjs +0 -1050
- package/dist/run-BVcPemGr.mjs +0 -5947
- package/dist/run-BWqEmIiz.mjs +0 -5964
- package/dist/run-BWsDPiNe.mjs +0 -1050
- package/dist/run-BX4iy6k8.mjs +0 -1050
- package/dist/run-BXYfq8mK.mjs +0 -5836
- package/dist/run-BY12Ataq.mjs +0 -5732
- package/dist/run-BYDOX4yk.mjs +0 -5402
- package/dist/run-Bd-t6s63.mjs +0 -5373
- package/dist/run-BenYqfwQ.mjs +0 -5273
- package/dist/run-BfF4bgA3.mjs +0 -5403
- package/dist/run-Bhh05yic.mjs +0 -5369
- package/dist/run-BicITYWX.mjs +0 -6138
- package/dist/run-BieEN0Pg.mjs +0 -5761
- package/dist/run-BjEQi6PN.mjs +0 -1050
- package/dist/run-BjZ6SyFy.mjs +0 -1051
- package/dist/run-Bl8OkKyC.mjs +0 -5969
- package/dist/run-BlEFlhfn.mjs +0 -5510
- package/dist/run-BmL1m0Bk.mjs +0 -1050
- package/dist/run-Bmx5wEBF.mjs +0 -1051
- package/dist/run-BnX5Rw8x.mjs +0 -5403
- package/dist/run-BpjmHeht.mjs +0 -1050
- package/dist/run-BxTdRjCG.mjs +0 -1051
- package/dist/run-ByOVDgvx.mjs +0 -6115
- package/dist/run-BzRP6Q5t.mjs +0 -1051
- package/dist/run-C0dyMP62.mjs +0 -1051
- package/dist/run-C1lS3SwN.mjs +0 -5733
- package/dist/run-C3PAp02X.mjs +0 -5252
- package/dist/run-C3eaYQub.mjs +0 -1050
- package/dist/run-C4pdX4sY.mjs +0 -1051
- package/dist/run-C676pHe-.mjs +0 -5423
- package/dist/run-C8GkzcfP.mjs +0 -1050
- package/dist/run-C9Hrqjy_.mjs +0 -1050
- package/dist/run-CC2C8P-U.mjs +0 -6031
- package/dist/run-CCcW4asS.mjs +0 -1050
- package/dist/run-CDBKhQ1Z.mjs +0 -1051
- package/dist/run-CEB6sYzn.mjs +0 -5962
- package/dist/run-CF6aXLmA.mjs +0 -5445
- package/dist/run-CHyN5U0t.mjs +0 -1050
- package/dist/run-CIFezmkC.mjs +0 -5949
- package/dist/run-CLA9zw7J.mjs +0 -5907
- package/dist/run-COWb9ovq.mjs +0 -1050
- package/dist/run-CSUAy5T5.mjs +0 -1051
- package/dist/run-CSk7i0Hq.mjs +0 -1050
- package/dist/run-CUtqSGWJ.mjs +0 -1050
- package/dist/run-CXrEt0TM.mjs +0 -5008
- package/dist/run-CY8Y0JPW.mjs +0 -5287
- package/dist/run-CZCKBcQ-.mjs +0 -5244
- package/dist/run-CZj0sRCs.mjs +0 -1050
- package/dist/run-C_1x2cNU.mjs +0 -5381
- package/dist/run-C_8iOjO1.mjs +0 -5892
- package/dist/run-C_KIew8H.mjs +0 -1051
- package/dist/run-CajRcN3C.mjs +0 -1050
- package/dist/run-CbzXO7fw.mjs +0 -1050
- package/dist/run-CcSr4x2f.mjs +0 -1050
- package/dist/run-CcYaXgCy.mjs +0 -6091
- package/dist/run-CdihMx0V.mjs +0 -1051
- package/dist/run-Cf2Dl_ck.mjs +0 -1051
- package/dist/run-CjH1H4vq.mjs +0 -1050
- package/dist/run-CkbDK6jA.mjs +0 -1051
- package/dist/run-Ckh6JE9F.mjs +0 -1050
- package/dist/run-Ckyg9-fm.mjs +0 -6079
- package/dist/run-CqL3ZWdr.mjs +0 -5381
- package/dist/run-Csj7sJAh.mjs +0 -1050
- package/dist/run-Ct--DWF1.mjs +0 -1051
- package/dist/run-CtJRxaFC.mjs +0 -1051
- package/dist/run-CuIMdkKF.mjs +0 -6099
- package/dist/run-CuckJGM-.mjs +0 -1050
- package/dist/run-CxGAa9MH.mjs +0 -1050
- package/dist/run-CyU4-O-e.mjs +0 -5411
- package/dist/run-CymDyu2b.mjs +0 -5389
- package/dist/run-CzIY4_RE.mjs +0 -6093
- package/dist/run-D0Ha4aWt.mjs +0 -1050
- package/dist/run-D0ow-xms.mjs +0 -5905
- package/dist/run-D1PFrNZB.mjs +0 -6273
- package/dist/run-D2X3jEqg.mjs +0 -1051
- package/dist/run-D39C7Ta3.mjs +0 -1050
- package/dist/run-D3Lqxasl.mjs +0 -1051
- package/dist/run-D3bhRCCb.mjs +0 -1051
- package/dist/run-D5N42sVA.mjs +0 -1050
- package/dist/run-D691XPXy.mjs +0 -6031
- package/dist/run-D7dLDpq3.mjs +0 -5403
- package/dist/run-D8mQ_fL5.mjs +0 -1050
- package/dist/run-DA-YBjNw.mjs +0 -6018
- package/dist/run-DByI8mI0.mjs +0 -1051
- package/dist/run-DCINWip4.mjs +0 -1050
- package/dist/run-DCrZ3vke.mjs +0 -5406
- package/dist/run-DDF-tRbn.mjs +0 -5954
- package/dist/run-DGSgljJE.mjs +0 -5421
- package/dist/run-DGsXW19O.mjs +0 -5541
- package/dist/run-DHrF2xpW.mjs +0 -5776
- package/dist/run-DIB0W42M.mjs +0 -1050
- package/dist/run-DJ4k0WzZ.mjs +0 -1051
- package/dist/run-DMI83W7i.mjs +0 -5434
- package/dist/run-DNX3djCI.mjs +0 -1050
- package/dist/run-DOPaGRT2.mjs +0 -6027
- package/dist/run-DP7KSZqR.mjs +0 -1051
- package/dist/run-DQ0yljWr.mjs +0 -1050
- package/dist/run-DTkldU6a.mjs +0 -1050
- package/dist/run-DU10B3gK.mjs +0 -5728
- package/dist/run-DV86VJNG.mjs +0 -5386
- package/dist/run-DVZGKdKO.mjs +0 -1050
- package/dist/run-DWdtp6VD.mjs +0 -6136
- package/dist/run-DWzA1gZ-.mjs +0 -1050
- package/dist/run-DXJ2M19k.mjs +0 -1050
- package/dist/run-DZOeccNu.mjs +0 -5484
- package/dist/run-D_W5YF0D.mjs +0 -6046
- package/dist/run-DaReJPf8.mjs +0 -1051
- package/dist/run-DaYrEeQ9.mjs +0 -5400
- package/dist/run-DbC9-WM4.mjs +0 -1050
- package/dist/run-Dd9XkswU.mjs +0 -1051
- package/dist/run-De-wkVl3.mjs +0 -5487
- package/dist/run-DfU2luyX.mjs +0 -1050
- package/dist/run-Dfl3Ze2L.mjs +0 -5541
- package/dist/run-DfuHUDIJ.mjs +0 -1051
- package/dist/run-DfwfyFqj.mjs +0 -5975
- package/dist/run-DgUDGHZy.mjs +0 -1051
- package/dist/run-Dge2K7h1.mjs +0 -1050
- package/dist/run-Di3I0USw.mjs +0 -1050
- package/dist/run-Dm3U4FB5.mjs +0 -6018
- package/dist/run-Du0YOs48.mjs +0 -5446
- package/dist/run-DuaIQAE4.mjs +0 -5392
- package/dist/run-Dwm19YhI.mjs +0 -1050
- package/dist/run-DxM7xaBa.mjs +0 -1050
- package/dist/run-DysN-cGm.mjs +0 -1050
- package/dist/run-DzXohf8-.mjs +0 -1051
- package/dist/run-E_MwVOtN.mjs +0 -5272
- package/dist/run-FPoL2-FD.mjs +0 -5381
- package/dist/run-HU4XjZfs.mjs +0 -6023
- package/dist/run-HhiYlJuS.mjs +0 -5414
- package/dist/run-JXLlRLFb.mjs +0 -1050
- package/dist/run-K-_jahIg.mjs +0 -1051
- package/dist/run-K_S7pfZ-.mjs +0 -1050
- package/dist/run-LDiT4WF-.mjs +0 -1050
- package/dist/run-NToLJWx-.mjs +0 -5442
- package/dist/run-RBufRqbs.mjs +0 -1050
- package/dist/run-YFYpyThQ.mjs +0 -1051
- package/dist/run-YG1Pb9dY.mjs +0 -5385
- package/dist/run-ZDa17iLg.mjs +0 -6060
- package/dist/run-ZN0qMdS_.mjs +0 -1051
- package/dist/run-azpFWM6w.mjs +0 -1050
- package/dist/run-coIDvBK_.mjs +0 -6127
- package/dist/run-jLp4pbTE.mjs +0 -1050
- package/dist/run-m3oAuSg0.mjs +0 -1050
- package/dist/run-r9CAcL_U.mjs +0 -5403
- package/dist/run-v32uF2bP.mjs +0 -5378
- package/dist/run-vTsskoZc.mjs +0 -5340
- package/dist/run-vt26p5D7.mjs +0 -1050
- package/dist/run-vvQiCHpi.mjs +0 -5427
- package/dist/run-w-HVv5py.mjs +0 -5410
- package/dist/run-wpUutZ9C.mjs +0 -1051
- package/dist/run-yTjJ7noq.mjs +0 -1051
- package/dist/run-zo5GSoVC.mjs +0 -1050
|
@@ -3872,7 +3872,9 @@ function createSvampConfigChecker(directory, sessionId, getMetadata, setMetadata
|
|
|
3872
3872
|
maxIterations: state.max_iterations,
|
|
3873
3873
|
currentIteration: state.iteration,
|
|
3874
3874
|
startedAt: state.started_at,
|
|
3875
|
-
cooldownSeconds: state.cooldown_seconds
|
|
3875
|
+
cooldownSeconds: state.cooldown_seconds,
|
|
3876
|
+
contextMode: state.context_mode || "fresh",
|
|
3877
|
+
lastIterationStartedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3876
3878
|
};
|
|
3877
3879
|
if (!prevRalph?.active) {
|
|
3878
3880
|
const progressRelPath = `.svamp/${sessionId}/ralph-progress.md`;
|
|
@@ -3897,7 +3899,7 @@ function createSvampConfigChecker(directory, sessionId, getMetadata, setMetadata
|
|
|
3897
3899
|
);
|
|
3898
3900
|
logger.log(`[svampConfig] Ralph loop started: "${state.task.slice(0, 50)}..."`);
|
|
3899
3901
|
onRalphLoopActivated?.();
|
|
3900
|
-
} else if (prevRalph.currentIteration !== ralphLoop.currentIteration) {
|
|
3902
|
+
} else if (prevRalph.currentIteration !== ralphLoop.currentIteration || prevRalph.task !== ralphLoop.task) {
|
|
3901
3903
|
setMetadata((m) => ({ ...m, ralphLoop }));
|
|
3902
3904
|
sessionService.updateMetadata(getMetadata());
|
|
3903
3905
|
}
|
|
@@ -3947,12 +3949,14 @@ function createSvampConfigChecker(directory, sessionId, getMetadata, setMetadata
|
|
|
3947
3949
|
if ("ralph_loop" in patch) {
|
|
3948
3950
|
const rl = patch.ralph_loop;
|
|
3949
3951
|
if (rl && typeof rl === "object" && typeof rl.task === "string") {
|
|
3952
|
+
const contextMode = rl.context_mode === "fresh" || rl.context_mode === "continue" ? rl.context_mode : void 0;
|
|
3950
3953
|
writeRalphState(ralphStatePath, {
|
|
3951
3954
|
iteration: rl.current_iteration || 1,
|
|
3952
3955
|
max_iterations: typeof rl.max_iterations === "number" ? rl.max_iterations : 0,
|
|
3953
3956
|
completion_promise: rl.completion_promise || "DONE",
|
|
3954
3957
|
cooldown_seconds: typeof rl.cooldown_seconds === "number" ? rl.cooldown_seconds : 1,
|
|
3955
3958
|
started_at: rl.started_at || (/* @__PURE__ */ new Date()).toISOString(),
|
|
3959
|
+
context_mode: contextMode,
|
|
3956
3960
|
task: rl.task.trim()
|
|
3957
3961
|
});
|
|
3958
3962
|
ralphChecker();
|
|
@@ -4085,9 +4089,16 @@ function buildRalphPrompt(task, state) {
|
|
|
4085
4089
|
return task;
|
|
4086
4090
|
}
|
|
4087
4091
|
const iterStr = state.max_iterations > 0 ? `${state.iteration}/${state.max_iterations}` : `${state.iteration}`;
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4092
|
+
const reminder = [
|
|
4093
|
+
"<system-reminder>",
|
|
4094
|
+
`Ralph Loop \u2014 Iteration ${iterStr} (Continue Mode)`,
|
|
4095
|
+
"Your conversation history persists. Continue from where you left off.",
|
|
4096
|
+
`To signal completion, output EXACTLY: <promise>${state.completion_promise}</promise>`,
|
|
4097
|
+
"Only output the promise when the task is FULLY and PERMANENTLY complete.",
|
|
4098
|
+
"Do NOT output a false promise to exit the loop.",
|
|
4099
|
+
"</system-reminder>"
|
|
4100
|
+
].join("\n");
|
|
4101
|
+
return task + "\n\n" + reminder;
|
|
4091
4102
|
}
|
|
4092
4103
|
function getRalphProgressFilePath(directory, sessionId) {
|
|
4093
4104
|
return join(getSessionDir(directory, sessionId), "ralph-progress.md");
|
|
@@ -4902,7 +4913,9 @@ The automated loop has finished. Review the progress above and let me know if yo
|
|
|
4902
4913
|
maxIterations: rlState.max_iterations,
|
|
4903
4914
|
currentIteration: nextIteration,
|
|
4904
4915
|
startedAt: rlState.started_at,
|
|
4905
|
-
cooldownSeconds: rlState.cooldown_seconds
|
|
4916
|
+
cooldownSeconds: rlState.cooldown_seconds,
|
|
4917
|
+
contextMode: rlState.context_mode || "fresh",
|
|
4918
|
+
lastIterationStartedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4906
4919
|
};
|
|
4907
4920
|
sessionMetadata = { ...sessionMetadata, ralphLoop };
|
|
4908
4921
|
sessionService.updateMetadata(sessionMetadata);
|
|
@@ -5782,7 +5795,9 @@ The automated loop has finished. Review the progress above and let me know if yo
|
|
|
5782
5795
|
maxIterations: rlState.max_iterations,
|
|
5783
5796
|
currentIteration: nextIteration,
|
|
5784
5797
|
startedAt: rlState.started_at,
|
|
5785
|
-
cooldownSeconds: rlState.cooldown_seconds
|
|
5798
|
+
cooldownSeconds: rlState.cooldown_seconds,
|
|
5799
|
+
contextMode: rlState.context_mode || "fresh",
|
|
5800
|
+
lastIterationStartedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
5786
5801
|
};
|
|
5787
5802
|
sessionMetadata = { ...sessionMetadata, ralphLoop };
|
|
5788
5803
|
sessionService.updateMetadata(sessionMetadata);
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import * as os from 'os';
|
|
2
|
+
import { r as requireSandboxApiEnv } from './commands-DwY2B7KW.mjs';
|
|
3
|
+
import { WebSocket } from 'ws';
|
|
4
|
+
|
|
5
|
+
class TunnelClient {
|
|
6
|
+
ws = null;
|
|
7
|
+
options;
|
|
8
|
+
env;
|
|
9
|
+
sandboxId;
|
|
10
|
+
reconnectAttempts = 0;
|
|
11
|
+
maxReconnectAttempts = 20;
|
|
12
|
+
destroyed = false;
|
|
13
|
+
pingInterval = null;
|
|
14
|
+
requestCount = 0;
|
|
15
|
+
localWebSockets = /* @__PURE__ */ new Map();
|
|
16
|
+
// request_id → local WS connection
|
|
17
|
+
constructor(options) {
|
|
18
|
+
this.options = {
|
|
19
|
+
localHost: "localhost",
|
|
20
|
+
requestTimeout: 3e4,
|
|
21
|
+
...options
|
|
22
|
+
};
|
|
23
|
+
this.env = options.env || requireSandboxApiEnv();
|
|
24
|
+
this.sandboxId = options.sandboxId || this.env.sandboxId || `local-${os.hostname()}-${process.pid}`;
|
|
25
|
+
}
|
|
26
|
+
/** Build the WebSocket URL for the tunnel endpoint. */
|
|
27
|
+
buildWsUrl() {
|
|
28
|
+
const baseUrl = this.env.apiUrl.replace(/\/+$/, "");
|
|
29
|
+
const wsBase = baseUrl.replace(/^http/, "ws");
|
|
30
|
+
const ns = this.env.namespace || "_tunnel";
|
|
31
|
+
const params = new URLSearchParams({
|
|
32
|
+
token: this.env.apiKey,
|
|
33
|
+
sandbox_id: this.sandboxId
|
|
34
|
+
});
|
|
35
|
+
return `${wsBase}/services/${ns}/${this.options.name}/tunnel?${params}`;
|
|
36
|
+
}
|
|
37
|
+
/** Connect to the tunnel endpoint. */
|
|
38
|
+
async connect() {
|
|
39
|
+
if (this.destroyed) return;
|
|
40
|
+
const url = this.buildWsUrl();
|
|
41
|
+
return new Promise((resolve, reject) => {
|
|
42
|
+
try {
|
|
43
|
+
this.ws = new WebSocket(url);
|
|
44
|
+
} catch (err) {
|
|
45
|
+
reject(new Error(`Failed to create WebSocket: ${err.message}`));
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
this.ws.on("open", () => {
|
|
49
|
+
this.reconnectAttempts = 0;
|
|
50
|
+
this.startPingInterval();
|
|
51
|
+
this.options.onConnect?.();
|
|
52
|
+
resolve();
|
|
53
|
+
});
|
|
54
|
+
this.ws.on("message", (data) => {
|
|
55
|
+
const raw = typeof data === "string" ? data : data.toString("utf8");
|
|
56
|
+
this.handleMessage(raw);
|
|
57
|
+
});
|
|
58
|
+
this.ws.on("close", () => {
|
|
59
|
+
this.stopPingInterval();
|
|
60
|
+
this.cleanupLocalWebSockets();
|
|
61
|
+
this.options.onDisconnect?.();
|
|
62
|
+
if (!this.destroyed) {
|
|
63
|
+
this.scheduleReconnect();
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
this.ws.on("error", (err) => {
|
|
67
|
+
this.options.onError?.(err);
|
|
68
|
+
if (this.reconnectAttempts === 0) {
|
|
69
|
+
reject(err);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
/** Disconnect and stop reconnecting. */
|
|
75
|
+
destroy() {
|
|
76
|
+
this.destroyed = true;
|
|
77
|
+
this.stopPingInterval();
|
|
78
|
+
this.cleanupLocalWebSockets();
|
|
79
|
+
if (this.ws) {
|
|
80
|
+
this.ws.close();
|
|
81
|
+
this.ws = null;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/** Number of HTTP requests proxied. */
|
|
85
|
+
get totalRequests() {
|
|
86
|
+
return this.requestCount;
|
|
87
|
+
}
|
|
88
|
+
/** Number of active WebSocket connections being proxied. */
|
|
89
|
+
get activeWebSockets() {
|
|
90
|
+
return this.localWebSockets.size;
|
|
91
|
+
}
|
|
92
|
+
// ── Message handling ────────────────────────────────────────────────
|
|
93
|
+
handleMessage(raw) {
|
|
94
|
+
let msg;
|
|
95
|
+
try {
|
|
96
|
+
msg = JSON.parse(raw);
|
|
97
|
+
} catch {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
switch (msg.type) {
|
|
101
|
+
case "ping":
|
|
102
|
+
this.send({ type: "pong" });
|
|
103
|
+
break;
|
|
104
|
+
case "request":
|
|
105
|
+
this.options.onRequest?.(msg);
|
|
106
|
+
this.proxyRequest(msg).catch((err) => {
|
|
107
|
+
this.options.onError?.(err);
|
|
108
|
+
});
|
|
109
|
+
break;
|
|
110
|
+
case "ws_open":
|
|
111
|
+
this.handleWsOpen(msg).catch((err) => {
|
|
112
|
+
this.options.onError?.(err);
|
|
113
|
+
});
|
|
114
|
+
break;
|
|
115
|
+
case "ws_data":
|
|
116
|
+
this.handleWsData(msg);
|
|
117
|
+
break;
|
|
118
|
+
case "ws_close":
|
|
119
|
+
this.handleWsClose(msg);
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async proxyRequest(req) {
|
|
124
|
+
this.requestCount++;
|
|
125
|
+
const port = req.port || this.options.ports[0];
|
|
126
|
+
const url = `http://${this.options.localHost}:${port}${req.path}`;
|
|
127
|
+
const controller = new AbortController();
|
|
128
|
+
const timeout = setTimeout(() => controller.abort(), this.options.requestTimeout);
|
|
129
|
+
const init = {
|
|
130
|
+
method: req.method,
|
|
131
|
+
headers: req.headers,
|
|
132
|
+
signal: controller.signal
|
|
133
|
+
};
|
|
134
|
+
if (req.body && !["GET", "HEAD"].includes(req.method.toUpperCase())) {
|
|
135
|
+
init.body = Buffer.from(req.body, "base64");
|
|
136
|
+
}
|
|
137
|
+
try {
|
|
138
|
+
const res = await fetch(url, init);
|
|
139
|
+
clearTimeout(timeout);
|
|
140
|
+
const bodyBuffer = await res.arrayBuffer();
|
|
141
|
+
const bodyBase64 = bodyBuffer.byteLength > 0 ? Buffer.from(bodyBuffer).toString("base64") : void 0;
|
|
142
|
+
const headers = {};
|
|
143
|
+
res.headers.forEach((value, key) => {
|
|
144
|
+
headers[key] = value;
|
|
145
|
+
});
|
|
146
|
+
this.send({
|
|
147
|
+
type: "response",
|
|
148
|
+
id: req.id,
|
|
149
|
+
status: res.status,
|
|
150
|
+
headers,
|
|
151
|
+
body: bodyBase64
|
|
152
|
+
});
|
|
153
|
+
} catch (err) {
|
|
154
|
+
clearTimeout(timeout);
|
|
155
|
+
if (err.name === "AbortError") {
|
|
156
|
+
this.send({
|
|
157
|
+
type: "response",
|
|
158
|
+
id: req.id,
|
|
159
|
+
status: 504,
|
|
160
|
+
headers: { "content-type": "text/plain" },
|
|
161
|
+
body: Buffer.from("Tunnel: request timeout").toString("base64")
|
|
162
|
+
});
|
|
163
|
+
} else {
|
|
164
|
+
this.send({
|
|
165
|
+
type: "response",
|
|
166
|
+
id: req.id,
|
|
167
|
+
status: 502,
|
|
168
|
+
headers: { "content-type": "text/plain" },
|
|
169
|
+
body: Buffer.from(`Tunnel: local service error: ${err.message}`).toString("base64")
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
// ── WebSocket proxying ───────────────────────────────────────────────
|
|
175
|
+
async handleWsOpen(msg) {
|
|
176
|
+
const port = msg.port || this.options.ports[0];
|
|
177
|
+
const localUrl = `ws://${this.options.localHost}:${port}${msg.path}`;
|
|
178
|
+
try {
|
|
179
|
+
const localWs = new WebSocket(localUrl, {
|
|
180
|
+
headers: msg.headers
|
|
181
|
+
});
|
|
182
|
+
this.localWebSockets.set(msg.id, localWs);
|
|
183
|
+
localWs.on("message", (data, isBinary) => {
|
|
184
|
+
const encoded = typeof data === "string" ? Buffer.from(data).toString("base64") : (data instanceof Buffer ? data : Buffer.from(data)).toString("base64");
|
|
185
|
+
this.send({
|
|
186
|
+
type: "ws_data",
|
|
187
|
+
id: msg.id,
|
|
188
|
+
data: encoded,
|
|
189
|
+
is_text: !isBinary
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
localWs.on("close", (code) => {
|
|
193
|
+
this.localWebSockets.delete(msg.id);
|
|
194
|
+
this.send({ type: "ws_close", id: msg.id, code: code || 1e3 });
|
|
195
|
+
});
|
|
196
|
+
localWs.on("error", () => {
|
|
197
|
+
this.localWebSockets.delete(msg.id);
|
|
198
|
+
this.send({ type: "ws_close", id: msg.id, code: 1011 });
|
|
199
|
+
});
|
|
200
|
+
} catch {
|
|
201
|
+
this.send({ type: "ws_close", id: msg.id, code: 1011 });
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
handleWsData(msg) {
|
|
205
|
+
const localWs = this.localWebSockets.get(msg.id);
|
|
206
|
+
if (!localWs || localWs.readyState !== WebSocket.OPEN) return;
|
|
207
|
+
const buf = Buffer.from(msg.data, "base64");
|
|
208
|
+
if (msg.is_text) {
|
|
209
|
+
localWs.send(buf.toString("utf8"));
|
|
210
|
+
} else {
|
|
211
|
+
localWs.send(buf);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
handleWsClose(msg) {
|
|
215
|
+
const localWs = this.localWebSockets.get(msg.id);
|
|
216
|
+
if (localWs) {
|
|
217
|
+
this.localWebSockets.delete(msg.id);
|
|
218
|
+
localWs.close(msg.code || 1e3);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
cleanupLocalWebSockets() {
|
|
222
|
+
for (const [id, ws] of this.localWebSockets) {
|
|
223
|
+
ws.close(1001);
|
|
224
|
+
}
|
|
225
|
+
this.localWebSockets.clear();
|
|
226
|
+
}
|
|
227
|
+
// ── WebSocket helpers ───────────────────────────────────────────────
|
|
228
|
+
send(msg) {
|
|
229
|
+
if (this.ws?.readyState === WebSocket.OPEN) {
|
|
230
|
+
this.ws.send(JSON.stringify(msg));
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
startPingInterval() {
|
|
234
|
+
this.stopPingInterval();
|
|
235
|
+
this.pingInterval = setInterval(() => {
|
|
236
|
+
this.send({ type: "ping" });
|
|
237
|
+
}, 3e4);
|
|
238
|
+
}
|
|
239
|
+
stopPingInterval() {
|
|
240
|
+
if (this.pingInterval) {
|
|
241
|
+
clearInterval(this.pingInterval);
|
|
242
|
+
this.pingInterval = null;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
scheduleReconnect() {
|
|
246
|
+
if (this.reconnectAttempts >= this.maxReconnectAttempts) {
|
|
247
|
+
this.options.onError?.(new Error(
|
|
248
|
+
`Tunnel disconnected: max reconnect attempts (${this.maxReconnectAttempts}) reached`
|
|
249
|
+
));
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
this.reconnectAttempts++;
|
|
253
|
+
const delay = Math.min(1e3 * Math.pow(2, this.reconnectAttempts - 1), 3e4);
|
|
254
|
+
setTimeout(() => {
|
|
255
|
+
if (!this.destroyed) {
|
|
256
|
+
this.connect().catch((err) => {
|
|
257
|
+
this.options.onError?.(err);
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
}, delay);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
async function runTunnel(name, ports) {
|
|
264
|
+
const portList = ports.join(", ");
|
|
265
|
+
const client = new TunnelClient({
|
|
266
|
+
name,
|
|
267
|
+
ports,
|
|
268
|
+
onConnect: () => {
|
|
269
|
+
console.log(`Tunnel connected: ${name} \u2192 localhost:[${portList}]`);
|
|
270
|
+
},
|
|
271
|
+
onDisconnect: () => {
|
|
272
|
+
console.log("Tunnel disconnected, reconnecting...");
|
|
273
|
+
},
|
|
274
|
+
onRequest: (req) => {
|
|
275
|
+
console.log(` ${req.method} :${req.port || ports[0]}${req.path}`);
|
|
276
|
+
},
|
|
277
|
+
onError: (err) => {
|
|
278
|
+
console.error(`Tunnel error: ${err.message}`);
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
const cleanup = () => {
|
|
282
|
+
console.log("\nTunnel shutting down...");
|
|
283
|
+
client.destroy();
|
|
284
|
+
process.exit(0);
|
|
285
|
+
};
|
|
286
|
+
process.on("SIGINT", cleanup);
|
|
287
|
+
process.on("SIGTERM", cleanup);
|
|
288
|
+
try {
|
|
289
|
+
await client.connect();
|
|
290
|
+
console.log(`Tunnel is active. Press Ctrl+C to stop.`);
|
|
291
|
+
await new Promise(() => {
|
|
292
|
+
});
|
|
293
|
+
} catch (err) {
|
|
294
|
+
console.error(`Failed to establish tunnel: ${err.message}`);
|
|
295
|
+
process.exit(1);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
export { TunnelClient, runTunnel };
|