deepline 0.3.461 → 0.3.463
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/bundling-sources/sdk/src/client-core.ts +7593 -0
- package/dist/bundling-sources/sdk/src/client.ts +8 -7366
- package/dist/bundling-sources/sdk/src/http-core.ts +1239 -0
- package/dist/bundling-sources/sdk/src/http.ts +6 -1231
- package/dist/bundling-sources/sdk/src/index.ts +4 -1
- package/dist/bundling-sources/sdk/src/play.ts +5 -5
- package/dist/bundling-sources/sdk/src/plays/client-core.ts +437 -0
- package/dist/bundling-sources/sdk/src/plays/client.ts +4 -421
- package/dist/bundling-sources/sdk/src/plays/input-example.ts +3 -4
- package/dist/bundling-sources/sdk/src/plays/play-description.ts +1 -1
- package/dist/bundling-sources/sdk/src/plays/run-request.ts +1 -1
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/server.ts +43 -0
- package/dist/bundling-sources/sdk/src/types.ts +15 -5
- package/dist/bundling-sources/shared_libs/integration-contracts/billing-entitlements.ts +15 -0
- package/dist/bundling-sources/shared_libs/monitors/billing/tamradar.ts +17 -17
- package/dist/bundling-sources/shared_libs/monitors/callback-security.ts +0 -307
- package/dist/bundling-sources/shared_libs/monitors/http-error-response.ts +3 -0
- package/dist/bundling-sources/shared_libs/monitors/lifecycle-notifications.ts +3 -2
- package/dist/bundling-sources/shared_libs/monitors/package.json +2 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-callback-verification.ts +34 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-batch-operation.ts +61 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-upstream-identity.ts +122 -2
- package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-dead-letter.ts +11 -1
- package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-failure-codes.ts +24 -0
- package/dist/bundling-sources/shared_libs/observability/dlq.ts +32 -0
- package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +57 -3
- package/dist/bundling-sources/shared_libs/observability/scheduled-work.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-data-plane/r2.ts +66 -1
- package/dist/bundling-sources/shared_libs/play-data-plane/sheet-column-storage.ts +36 -7
- package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +250 -11
- package/dist/bundling-sources/shared_libs/play-runtime/array-input-store.ts +319 -0
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +991 -359
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +17 -0
- package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-janitor.ts +13 -0
- package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-reaper.ts +110 -0
- package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-machines.ts +155 -6
- package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-registry.ts +110 -6
- package/dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts +127 -13
- package/dist/bundling-sources/shared_libs/play-runtime/execution-capabilities.ts +14 -1
- package/dist/bundling-sources/shared_libs/play-runtime/fixture-behavior.ts +57 -1
- package/dist/bundling-sources/shared_libs/play-runtime/free-company-lookup-batching.ts +218 -0
- package/dist/bundling-sources/shared_libs/play-runtime/gateway-postgres-admission.ts +42 -5
- package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-budget-state-backend.ts +6 -1
- package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-rate-state-backend.ts +92 -31
- package/dist/bundling-sources/shared_libs/play-runtime/governor/block-reserving-budget-state-backend.ts +69 -14
- package/dist/bundling-sources/shared_libs/play-runtime/governor/governor.ts +93 -23
- package/dist/bundling-sources/shared_libs/play-runtime/governor/in-memory-rate-state-backend.ts +15 -4
- package/dist/bundling-sources/shared_libs/play-runtime/governor/policy.ts +22 -18
- package/dist/bundling-sources/shared_libs/play-runtime/governor/rate-state-backend.ts +5 -0
- package/dist/bundling-sources/shared_libs/play-runtime/launch-identity.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/map-memory-limits.ts +190 -14
- package/dist/bundling-sources/shared_libs/play-runtime/memory-ledger.ts +131 -0
- package/dist/bundling-sources/shared_libs/play-runtime/modal-runtime-config.ts +77 -2
- package/dist/bundling-sources/shared_libs/play-runtime/output-size-limits.ts +271 -2
- package/dist/bundling-sources/shared_libs/play-runtime/play-run-recovery-policy.ts +51 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/contracts.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/job.ts +27 -1
- package/dist/bundling-sources/shared_libs/play-runtime/play-runtime-batching-registry.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-runtime/provider-text-for-log.ts +63 -0
- package/dist/bundling-sources/shared_libs/play-runtime/resource-governor.ts +19 -0
- package/dist/bundling-sources/shared_libs/play-runtime/run-ledger-event-transport.ts +112 -16
- package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +104 -2
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +265 -151
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-gateway-transport.ts +17 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-progress-push.ts +35 -14
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-sheet-persistence-retry.ts +12 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-control-transport.ts +4 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-labels.ts +36 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-launch-transport.ts +136 -70
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +237 -36
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-runtime-watchdog.ts +148 -4
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-session-execution.ts +6 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +285 -32
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/modal.ts +251 -56
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/runtime-sandbox-reconciliation.ts +29 -4
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/sandbox-create-outcome.ts +27 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/types.ts +22 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +1397 -382
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-array-input-receipts.ts +920 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-constants.ts +16 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-environment.ts +38 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-flow.ts +6 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-incident-drills.ts +26 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-operation-contract.ts +30 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-receipt-store-adapter.ts +14 -3
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-receipt-writer.ts +31 -4
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-sheet-row-transition.ts +47 -0
- package/dist/bundling-sources/shared_libs/play-runtime/sandbox-compute-usage.ts +20 -7
- package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/contract.ts +12 -0
- package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/index.ts +9 -0
- package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/runner-backend-adapter.ts +10 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +4 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +1496 -320
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-worker-required-env.ts +31 -1
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +1389 -129
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/receipt-gateway.ts +36 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-dispatch-authority.ts +4 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +162 -23
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-event-search.ts +499 -115
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-capacity.ts +377 -9
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-ledger-reconciliation.ts +117 -8
- package/dist/bundling-sources/shared_libs/play-runtime/secret-resolution-retry-policy.ts +25 -0
- package/dist/bundling-sources/shared_libs/play-runtime/terminal-runtime-performance.ts +391 -0
- package/dist/bundling-sources/shared_libs/play-runtime/test-runtime-seams.ts +40 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-call/index.ts +6 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-call/mapped-calls.ts +171 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-call/receipt-cohort.ts +16 -1
- package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +38 -12
- package/dist/bundling-sources/shared_libs/play-runtime/tool-result.ts +33 -9
- package/dist/bundling-sources/shared_libs/play-runtime/transport-error-diagnostics.ts +28 -0
- package/dist/bundling-sources/shared_libs/play-runtime/work-receipt-storage-contract.ts +55 -5
- package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +41 -1
- package/dist/bundling-sources/shared_libs/plays/contracts.ts +4 -0
- package/dist/bundling-sources/shared_libs/plays/dataset.ts +9 -3
- package/dist/bundling-sources/shared_libs/plays/deploy/manifest-contract.ts +2 -0
- package/dist/bundling-sources/shared_libs/plays/deploy/manifest.ts +3 -2
- package/dist/bundling-sources/shared_libs/plays/deploy/project-serializer.ts +2 -2
- package/dist/bundling-sources/shared_libs/plays/run-output-summary.ts +66 -0
- package/dist/bundling-sources/shared_libs/plays/script-entry.ts +1 -1
- package/dist/bundling-sources/shared_libs/product-notifications/catalog.ts +43 -1
- package/dist/bundling-sources/shared_libs/product-notifications/content.ts +9 -0
- package/dist/bundling-sources/shared_libs/product-notifications/email.ts +91 -13
- package/dist/bundling-sources/shared_libs/product-notifications/events.ts +3 -0
- package/dist/bundling-sources/shared_libs/product-notifications/slack-delivery.ts +41 -24
- package/dist/bundling-sources/shared_libs/security/attested-client-ip.ts +91 -0
- package/dist/bundling-sources/shared_libs/security/internal-actor.ts +0 -11
- package/dist/cli/{auth-6HJXNWUG.mjs → auth-LZLBR4C3.mjs} +5 -4
- package/dist/cli/auth-XPGKBJKB.js +41 -0
- package/dist/cli/{billing-6P5HO6QG.js → billing-6TJPNJQD.js} +152 -78
- package/dist/cli/{billing-MJ42N7YF.mjs → billing-OTOP5RE4.mjs} +84 -10
- package/dist/cli/{chunk-FCAZQ7WV.js → chunk-2NISBXMN.js} +52 -50
- package/dist/cli/{chunk-PNATXKLP.js → chunk-2ZIRCBYG.js} +6 -6
- package/dist/cli/{chunk-5FDKJQZE.js → chunk-3BOIOCNX.js} +1 -1
- package/dist/cli/chunk-3BVLLJ3H.mjs +1038 -0
- package/dist/cli/{chunk-FJZILBL7.mjs → chunk-3U5EAP6E.mjs} +5 -5
- package/dist/cli/{describe-FRAVCY5F.mjs → chunk-4YZKBBLZ.mjs} +19 -36
- package/dist/cli/{chunk-QWRHGGUH.js → chunk-5DRNNC72.js} +20 -2
- package/dist/cli/{chunk-Z2GUFYT6.js → chunk-5LEAXRHV.js} +11 -11
- package/dist/cli/{chunk-5MDIZX7M.js → chunk-5LHXOIPT.js} +8 -6
- package/dist/cli/{chunk-NMJ4D2WO.js → chunk-6PMCRYDA.js} +216 -91
- package/dist/cli/{chunk-EBU7LQ64.js → chunk-6V7KVRR5.js} +3 -3
- package/dist/cli/{chunk-MGXEUZHL.mjs → chunk-7D6X7IXW.mjs} +7 -5
- package/dist/cli/{chunk-SAZFZQRI.js → chunk-7FCYPAPP.js} +2 -2
- package/dist/cli/{chunk-ACCR7POB.js → chunk-7XYDDCQ2.js} +27 -27
- package/dist/cli/{chunk-5IYOUBFZ.js → chunk-ALZBANZI.js} +28 -54
- package/dist/cli/{chunk-3DNKFH2G.mjs → chunk-BAPTQDLF.mjs} +19 -1
- package/dist/cli/chunk-BGNWI3KH.js +827 -0
- package/dist/cli/{chunk-V7REJRDZ.mjs → chunk-C25QE4CH.mjs} +1 -1
- package/dist/cli/{chunk-FGMX4HUZ.js → chunk-CBZP6J3V.js} +29 -27
- package/dist/cli/{chunk-QEYHTIV4.mjs → chunk-CTQ56DXP.mjs} +10 -1
- package/dist/cli/{chunk-IHHLTHE7.mjs → chunk-CVQ7N5CV.mjs} +267 -38
- package/dist/cli/{chunk-7DH2FD7Y.mjs → chunk-D464JW3N.mjs} +5 -85
- package/dist/cli/{chunk-MEAIOXJL.mjs → chunk-DHXCBITQ.mjs} +7 -5
- package/dist/cli/chunk-F2RHUPVH.mjs +827 -0
- package/dist/cli/chunk-F6QV42MC.mjs +91 -0
- package/dist/cli/{chunk-OZBWRICM.js → chunk-FK2HNDCN.js} +2 -2
- package/dist/cli/{chunk-BGY2PLP7.mjs → chunk-GUT7CLOL.mjs} +23 -49
- package/dist/cli/{chunk-RY4IVOU3.mjs → chunk-I624J4H5.mjs} +16 -806
- package/dist/cli/{chunk-Z2XUZC34.js → chunk-IAYSWZDJ.js} +188 -76
- package/dist/cli/{chunk-FGLKOWSC.mjs → chunk-IKWRUNAP.mjs} +1 -1
- package/dist/cli/{chunk-KCCOQ5G5.js → chunk-JVDKZJUH.js} +511 -282
- package/dist/cli/{chunk-HDFRJ4IT.mjs → chunk-JVHOS3K3.mjs} +177 -65
- package/dist/cli/chunk-LYFKBLJI.mjs +1039 -0
- package/dist/cli/{chunk-SLEUWLJE.mjs → chunk-MSY22NQW.mjs} +5 -5
- package/dist/cli/{chunk-5FY72YOV.js → chunk-NAPTMYTY.js} +8 -8
- package/dist/cli/{chunk-O6QOMHCH.js → chunk-NDHJR2WZ.js} +37 -35
- package/dist/cli/{chunk-KXMNM4AQ.js → chunk-NMU3VR5U.js} +4 -5
- package/dist/cli/chunk-NTLI6P6Y.mjs +19 -0
- package/dist/cli/{chunk-RFONC4WJ.mjs → chunk-O3BJYD6D.mjs} +3 -3
- package/dist/cli/{describe-2WQY7ZCY.js → chunk-PVY4DPPF.js} +27 -44
- package/dist/cli/{chunk-WIYWSYDS.mjs → chunk-Q2EIZKVX.mjs} +3 -3
- package/dist/cli/{chunk-VZBCEA5S.mjs → chunk-RD6IQ2JY.mjs} +223 -92
- package/dist/cli/chunk-RGOUCIIZ.js +1039 -0
- package/dist/cli/{chunk-EIMG75BT.mjs → chunk-S3A4IXBQ.mjs} +4 -5
- package/dist/cli/{chunk-QIW7TVV6.mjs → chunk-S4XQCFES.mjs} +14 -12
- package/dist/cli/chunk-SKU6ECIY.js +19 -0
- package/dist/cli/{chunk-CRYOUPEB.js → chunk-TIRBDQ3W.js} +16 -16
- package/dist/cli/{chunk-G7L27KZB.mjs → chunk-TKAQR3IB.mjs} +31 -21
- package/dist/cli/{chunk-MDJPEGVN.js → chunk-UC4SFYNU.js} +392 -261
- package/dist/cli/{chunk-3BMLICF7.mjs → chunk-UIURR26V.mjs} +13 -8
- package/dist/cli/{chunk-TNMBPMMC.js → chunk-UROQDCVW.js} +13 -4
- package/dist/cli/{chunk-R64BGGRQ.mjs → chunk-VDGTTH7K.mjs} +2 -2
- package/dist/cli/chunk-VLEVVDWG.js +91 -0
- package/dist/cli/{chunk-R2GLGLDR.mjs → chunk-VPHN2HAL.mjs} +216 -91
- package/dist/cli/chunk-VY2GBNTX.js +1038 -0
- package/dist/cli/{chunk-CFUTOWE4.js → chunk-WG3KGAII.js} +8 -88
- package/dist/cli/{chunk-QAJAJPKK.mjs → chunk-WUMIYOXQ.mjs} +4 -2
- package/dist/cli/{chunk-SCIR5JXW.js → chunk-WUZS2HK6.js} +56 -51
- package/dist/cli/{chunk-T3MVIPHG.mjs → chunk-XDWS2JJT.mjs} +1 -1
- package/dist/cli/{chunk-KGQNIA37.js → chunk-XQCTG5OO.js} +44 -34
- package/dist/cli/{chunk-KVJ5VHW5.mjs → chunk-XW2JIYG7.mjs} +2 -2
- package/dist/cli/chunk-YGGIZ3VT.js +920 -0
- package/dist/cli/command-docs.d.mts +5 -0
- package/dist/cli/command-docs.d.ts +5 -0
- package/dist/cli/command-docs.js +2 -2
- package/dist/cli/command-docs.mjs +1 -1
- package/dist/cli/{csv-NX7NO3O6.js → csv-EH5QWR4O.js} +13 -12
- package/dist/cli/{csv-DQ6GW5B5.mjs → csv-OK45Z5XQ.mjs} +4 -3
- package/dist/cli/{db-R72DFMP6.js → db-3ESJKETS.js} +30 -27
- package/dist/cli/{db-2YP33M4K.mjs → db-6Z5E4HKN.mjs} +10 -7
- package/dist/cli/describe-PNDQB7YS.mjs +48 -0
- package/dist/cli/describe-QUF7VTTR.js +48 -0
- package/dist/cli/describe-core.d.mts +153 -5
- package/dist/cli/describe-core.d.ts +153 -5
- package/dist/cli/describe-core.js +9 -5
- package/dist/cli/describe-core.mjs +10 -6
- package/dist/cli/{executions-WFBU7L2Q.mjs → executions-2NTWQFEG.mjs} +7 -5
- package/dist/cli/{executions-ZLHD4QIT.js → executions-KUOBRX5V.js} +9 -7
- package/dist/cli/{feedback-CN3HJFVF.mjs → feedback-7RPRMSGY.mjs} +6 -5
- package/dist/cli/{feedback-NDV6TPHG.js → feedback-UPHAZJ4C.js} +10 -9
- package/dist/cli/getting-started.d.mts +6 -6
- package/dist/cli/getting-started.d.ts +6 -6
- package/dist/cli/getting-started.js +2 -2
- package/dist/cli/getting-started.mjs +1 -1
- package/dist/cli/{git-QAD6E3HW.mjs → git-SCYP6WSZ.mjs} +5 -4
- package/dist/cli/git-UH653WHV.js +25 -0
- package/dist/cli/index.js +152 -142
- package/dist/cli/index.mjs +56 -46
- package/dist/cli/{legacy-noops-KVC5QJ74.js → legacy-noops-7XMFCVRG.js} +8 -7
- package/dist/cli/{legacy-noops-TPTKNBI2.mjs → legacy-noops-A4KYAGI6.mjs} +5 -4
- package/dist/cli/{monitors-SV57JFLO.mjs → monitors-FLC5J7RI.mjs} +19 -6
- package/dist/cli/{monitors-KCROV6PJ.js → monitors-NZV6IX5H.js} +103 -90
- package/dist/cli/{org-NJYX5743.js → org-IZ7UP3XF.js} +70 -67
- package/dist/cli/{org-KX6QIR7A.mjs → org-LUETJ7Z5.mjs} +9 -6
- package/dist/cli/pages-22ML3O7O.js +252 -0
- package/dist/cli/pages-EUX5EAGF.mjs +252 -0
- package/dist/cli/{play-IQQ57L7Z.mjs → play-CDHPAKKM.mjs} +512 -1508
- package/dist/cli/{play-32L7EQN4.js → play-USJBQADG.js} +1090 -2086
- package/dist/cli/{providers-4WEC2EQN.mjs → providers-CCXZ3SQF.mjs} +7 -5
- package/dist/cli/{providers-ZQV6QLVQ.js → providers-WFEUNPGC.js} +10 -8
- package/dist/cli/{quickstart-HKUSFADF.js → quickstart-O4JSUORZ.js} +13 -12
- package/dist/cli/{quickstart-RQ76RIUE.mjs → quickstart-ZUULI635.mjs} +5 -4
- package/dist/cli/run-ISDJYJMU.js +443 -0
- package/dist/cli/run-QJ4NX5F5.mjs +443 -0
- package/dist/cli/{search-ZRAVFBZC.mjs → search-IX3XKZJ3.mjs} +8 -6
- package/dist/cli/search-TIFNLRPM.js +32 -0
- package/dist/cli/{secrets-CMJOVNVH.mjs → secrets-7VUDXTUZ.mjs} +7 -5
- package/dist/cli/{secrets-J3G5Y43U.js → secrets-ELQSNCTR.js} +16 -14
- package/dist/cli/{sessions-WY7VN4AE.js → sessions-A3FG3AZX.js} +6 -5
- package/dist/cli/{sessions-MDQYY5CB.mjs → sessions-VOIQ62GB.mjs} +5 -4
- package/dist/cli/{settings-4RWZPCT5.mjs → settings-S6N6EFBG.mjs} +14 -11
- package/dist/cli/{settings-HTNTFKCE.js → settings-ZTXQEMZI.js} +80 -77
- package/dist/cli/{setup-P3GYYZWG.mjs → setup-AYPIK4JE.mjs} +12 -10
- package/dist/cli/{setup-QGCAP62X.js → setup-Y3WOIFLS.js} +53 -51
- package/dist/cli/{skills-7NAE4ICL.mjs → skills-5SF5QWNI.mjs} +7 -6
- package/dist/cli/skills-MWFRMG3H.js +31 -0
- package/dist/cli/tools-3XNZ4J64.mjs +55 -0
- package/dist/cli/tools-XEC4OD3R.js +55 -0
- package/dist/cli/{update-GODLRKNB.mjs → update-3U4OVX5R.mjs} +9 -8
- package/dist/cli/update-DWYEYTZE.js +33 -0
- package/dist/cli/{workflow-4BXOUVEO.mjs → workflow-2M5JP7SA.mjs} +10 -8
- package/dist/cli/{workflow-AO3A6LXN.js → workflow-RM7H7555.js} +20 -18
- package/dist/client-DS2IWYZF.d.ts +10 -0
- package/dist/client-DTwnz_AW.d.mts +10 -0
- package/dist/{client-CYqG23K1.d.ts → client-core-B_6HAIBy.d.ts} +385 -12
- package/dist/{client-BbU5_j7n.d.mts → client-core-DzBSlY1U.d.mts} +385 -12
- package/dist/{compiler-manifest-CWz_sNOQ.d.ts → compiler-manifest-Dcyd3-Zd.d.mts} +43 -1
- package/dist/{compiler-manifest-CWz_sNOQ.d.mts → compiler-manifest-Dcyd3-Zd.d.ts} +43 -1
- package/dist/errors-d-sTrZhe.d.mts +142 -0
- package/dist/errors-yQwfgrcX.d.ts +142 -0
- package/dist/{index-BF2JB_Ug.d.mts → index-C6oXchjN.d.mts} +1 -1
- package/dist/{index-4NPXDzlD.d.ts → index-P56zy_z5.d.ts} +1 -1
- package/dist/index.d.mts +11 -147
- package/dist/index.d.ts +11 -147
- package/dist/index.js +16 -12
- package/dist/index.mjs +15 -11
- package/dist/install-integrity.json +141 -104
- package/dist/plays/bundle-play-file.d.mts +3 -3
- package/dist/plays/bundle-play-file.d.ts +3 -3
- package/dist/plays/bundle-play-file.mjs +2 -1
- package/dist/plays/play-description.d.mts +2 -2
- package/dist/plays/play-description.d.ts +2 -2
- package/dist/plays/play-description.js +2 -2
- package/dist/plays/play-description.mjs +1 -1
- package/dist/plays/run-request.d.mts +2 -2
- package/dist/plays/run-request.d.ts +2 -2
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +2 -2
- package/dist/release.mjs +1 -1
- package/dist/server.d.mts +17 -0
- package/dist/server.d.ts +17 -0
- package/dist/server.js +76 -0
- package/dist/server.mjs +76 -0
- package/package.json +6 -1
- package/dist/cli/auth-IACERYQH.js +0 -40
- package/dist/cli/chunk-PQUUWFXY.js +0 -95
- package/dist/cli/chunk-YBWAG72P.mjs +0 -95
- package/dist/cli/chunk-YQDUODZW.js +0 -1710
- package/dist/cli/git-JVI36ZFV.js +0 -24
- package/dist/cli/search-75X5LTDE.js +0 -30
- package/dist/cli/skills-BKJ53JOQ.js +0 -30
- package/dist/cli/tools-COWMIEJ6.mjs +0 -45
- package/dist/cli/tools-TASOCE7I.js +0 -45
- package/dist/cli/update-SJIKVME6.js +0 -32
|
@@ -525,6 +525,8 @@ export interface MapExecutionFrame {
|
|
|
525
525
|
/** Digest of the authored input before Runtime Sheet outputs were merged. */
|
|
526
526
|
authoredInputDigest?: string;
|
|
527
527
|
}>;
|
|
528
|
+
/** A sealed, bounded array source is readable by page after a wake. */
|
|
529
|
+
arrayInput?: { hasSourceIdentities: boolean };
|
|
528
530
|
/** Successful inputs, including reused inputs with no distinct stored key. */
|
|
529
531
|
completedRowsCount?: number;
|
|
530
532
|
pendingRowsCount?: number;
|
|
@@ -982,6 +984,10 @@ export interface ContextOptions {
|
|
|
982
984
|
columnTypes?: PlayDatasetColumnTypes;
|
|
983
985
|
},
|
|
984
986
|
) => Promise<MapStartResult>;
|
|
987
|
+
/** Internal transport pages; each yielded value is one actual admission response. */
|
|
988
|
+
onMapStartPages?: (
|
|
989
|
+
...args: Parameters<NonNullable<ContextOptions['onMapStart']>>
|
|
990
|
+
) => AsyncIterable<MapStartResult>;
|
|
985
991
|
/**
|
|
986
992
|
* Called as ctx.dataset() rows complete — persists executed rows (data +
|
|
987
993
|
* cell meta) into the tenant runtime sheet so the sheet, not an in-memory
|
|
@@ -1082,6 +1088,10 @@ export interface ContextOptions {
|
|
|
1082
1088
|
* in-memory callback tests can omit it and keep local result resolvers.
|
|
1083
1089
|
*/
|
|
1084
1090
|
runtimeSheetBackedMapDatasets?: boolean;
|
|
1091
|
+
/** Runner-owned durable source pages for arrays that cannot fit a second resident copy. */
|
|
1092
|
+
runtimeArrayInputStore?: import('./array-input-store').RuntimeArrayInputStore;
|
|
1093
|
+
/** Internal rollout switch for new array snapshots; existing snapshots always replay. */
|
|
1094
|
+
runtimeArrayInputStagingEnabled?: boolean;
|
|
1085
1095
|
resolvePlay?: (playRef: string) => Promise<ResolvedPlayExecution | null>;
|
|
1086
1096
|
/** Admit an independently scheduled scalar/HITL Play Run. */
|
|
1087
1097
|
launchPlayAsync?: (
|
|
@@ -1284,6 +1294,13 @@ export interface ProviderRetryCursor {
|
|
|
1284
1294
|
}
|
|
1285
1295
|
|
|
1286
1296
|
export interface PlayCheckpoint {
|
|
1297
|
+
/** Scheduler silence proof for one exact detached-runner heartbeat. Older
|
|
1298
|
+
* checkpoints acquire a fresh proof through the existing durable park. */
|
|
1299
|
+
detachedRunnerSilenceConfirmation?: {
|
|
1300
|
+
boundaryId: string;
|
|
1301
|
+
runnerAttempt: number;
|
|
1302
|
+
heartbeatIdentity: string | null;
|
|
1303
|
+
};
|
|
1287
1304
|
/** Last completed runner invocation within the current scheduler attempt. */
|
|
1288
1305
|
workCounterInvocationAttempt?: number;
|
|
1289
1306
|
workCounterInvocationSeq?: number;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createRateLimitedRuntimeLogger } from '../observability/runtime-console';
|
|
1
2
|
import { withRuntimeSchedulerClient } from './/scheduler-backends/postgres-pool';
|
|
2
3
|
import { RUNTIME_CAPACITY_POLICY } from './/runtime-capacity-policy';
|
|
3
4
|
import { isIsolatedRuntimeSchedulerSchema } from './/runtime-scheduler-topology';
|
|
@@ -6,6 +7,12 @@ import { isIsolatedRuntimeSchedulerSchema } from './/runtime-scheduler-topology'
|
|
|
6
7
|
* their own attempts; they do not each enumerate the shared Daytona account. */
|
|
7
8
|
export const DAYTONA_JANITOR_INTERVAL_MS = 5 * 60 * 1_000;
|
|
8
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Spacing of the `[daytona-janitor.stale_list]` line. The page does not depend
|
|
12
|
+
* on it: the monitor reads every pass summary and holds one open incident.
|
|
13
|
+
*/
|
|
14
|
+
export const DAYTONA_STALE_LIST_ALERT_INTERVAL_MS = 30 * 60 * 1_000;
|
|
15
|
+
|
|
9
16
|
export type DaytonaSandboxJanitorOptions = {
|
|
10
17
|
url: string;
|
|
11
18
|
schema: string;
|
|
@@ -36,6 +43,11 @@ export function startDaytonaSandboxJanitor(
|
|
|
36
43
|
}
|
|
37
44
|
|
|
38
45
|
let running = false;
|
|
46
|
+
// Spans passes, so it cannot live in the per-pass reaper.
|
|
47
|
+
const reportStaleList = createRateLimitedRuntimeLogger({
|
|
48
|
+
log: (...args) => console.warn(...args),
|
|
49
|
+
intervalMs: DAYTONA_STALE_LIST_ALERT_INTERVAL_MS,
|
|
50
|
+
});
|
|
39
51
|
const runPass = async (): Promise<void> => {
|
|
40
52
|
if (running) {
|
|
41
53
|
console.info('[daytona-janitor.controller] skip (previous pass running)');
|
|
@@ -80,6 +92,7 @@ export function startDaytonaSandboxJanitor(
|
|
|
80
92
|
},
|
|
81
93
|
schema: options.schema,
|
|
82
94
|
}),
|
|
95
|
+
options: { reportStaleList },
|
|
83
96
|
});
|
|
84
97
|
} catch (error) {
|
|
85
98
|
// This is a best-effort resource backstop. A failed sweep must never
|
|
@@ -38,6 +38,12 @@
|
|
|
38
38
|
* authorization failure is logged and the sweep continues — one wedged sandbox
|
|
39
39
|
* must never abort the fleet-wide pass. The only hard failure is an inability
|
|
40
40
|
* to enumerate at all.
|
|
41
|
+
*
|
|
42
|
+
* A successful list can still be wrong. From Oct 29 23:00 to Oct 30 06:00 UTC it
|
|
43
|
+
* returned about 75 sandboxes from other lanes and none of the 1 to 3 live
|
|
44
|
+
* production ones, so `scanned` never reached zero and every pass reported
|
|
45
|
+
* errors=0. Each pass therefore compares the list with the durable ledger. A
|
|
46
|
+
* mismatch only alerts: absence from a list never proves a sandbox is gone.
|
|
41
47
|
*/
|
|
42
48
|
import { PLAY_RUNNER_TERMINAL_GRACE_SECONDS } from './/runtime-constants';
|
|
43
49
|
import { DAYTONA_PLAY_RUNNER_LABEL_SOURCE } from './/runner-backends/backends/daytona-labels';
|
|
@@ -52,6 +58,15 @@ export { DAYTONA_PLAY_RUNNER_LABEL_SOURCE };
|
|
|
52
58
|
*/
|
|
53
59
|
export const REAP_AGE_GRACE_MS = 5 * 60 * 1000;
|
|
54
60
|
|
|
61
|
+
/**
|
|
62
|
+
* A sandbox must be this old when the list begins before the list missing it
|
|
63
|
+
* means anything, which leaves room for clock skew and Daytona's own lag.
|
|
64
|
+
*/
|
|
65
|
+
export const DAYTONA_DURABLE_LIVE_SETTLE_MS = 60 * 1000;
|
|
66
|
+
/** A live sandbox whose runner has been silent this long may be lost, so one
|
|
67
|
+
* such sandbox missing from the list is not evidence of a blind list. */
|
|
68
|
+
export const DAYTONA_DURABLE_LIVE_HEARTBEAT_STALE_MS = 5 * 60 * 1000;
|
|
69
|
+
|
|
55
70
|
/**
|
|
56
71
|
* A single sandbox as seen by the janitor. Structurally a subset of the Daytona
|
|
57
72
|
* SDK `Sandbox`, so a real `Sandbox` satisfies it directly.
|
|
@@ -133,6 +148,11 @@ export type DaytonaJanitorOwnershipPort = {
|
|
|
133
148
|
runId: string;
|
|
134
149
|
attempt: number;
|
|
135
150
|
}): Promise<DaytonaJanitorCleanupAuthorization>;
|
|
151
|
+
/** One statement per pass; its cost never scales with the provider list. */
|
|
152
|
+
countDurableLive(input: {
|
|
153
|
+
createdBeforeMs: number;
|
|
154
|
+
heartbeatStaleMs: number;
|
|
155
|
+
}): Promise<{ live: number; heartbeating: number }>;
|
|
136
156
|
};
|
|
137
157
|
|
|
138
158
|
export type ReapOptions = {
|
|
@@ -142,6 +162,8 @@ export type ReapOptions = {
|
|
|
142
162
|
dryRun?: boolean;
|
|
143
163
|
/** Structured logger; defaults to console. */
|
|
144
164
|
logger?: Pick<Console, 'info' | 'warn'>;
|
|
165
|
+
/** Rate limited by the long-lived controller; defaults to `logger.warn`. */
|
|
166
|
+
reportStaleList?: (message: string, detail: Record<string, unknown>) => void;
|
|
145
167
|
};
|
|
146
168
|
|
|
147
169
|
export type ReapSummary = {
|
|
@@ -152,6 +174,14 @@ export type ReapSummary = {
|
|
|
152
174
|
spared: number;
|
|
153
175
|
alerts: number;
|
|
154
176
|
errors: number;
|
|
177
|
+
/** Sandboxes the ledger held live throughout this list; null if unreadable. */
|
|
178
|
+
durableLive: number | null;
|
|
179
|
+
/** Of `durableLive`, those whose runner heartbeat is recent or not started. */
|
|
180
|
+
durableLiveHeartbeating: number | null;
|
|
181
|
+
/** Listed sandboxes that the ledger holds live. */
|
|
182
|
+
listedDurableLive: number;
|
|
183
|
+
/** The list succeeded but showed none of `durableLive`. */
|
|
184
|
+
listStale: boolean;
|
|
155
185
|
};
|
|
156
186
|
|
|
157
187
|
type ReapDecision =
|
|
@@ -232,8 +262,14 @@ export async function reapOrphanDaytonaSandboxes(input: {
|
|
|
232
262
|
spared: 0,
|
|
233
263
|
alerts: 0,
|
|
234
264
|
errors: 0,
|
|
265
|
+
durableLive: null,
|
|
266
|
+
durableLiveHeartbeating: null,
|
|
267
|
+
listedDurableLive: 0,
|
|
268
|
+
listStale: false,
|
|
235
269
|
};
|
|
270
|
+
let ownershipReadFailed = false;
|
|
236
271
|
|
|
272
|
+
const listStartedAtMs = now();
|
|
237
273
|
const iterator = input.daytona.list({
|
|
238
274
|
labels: { source: DAYTONA_PLAY_RUNNER_LABEL_SOURCE },
|
|
239
275
|
});
|
|
@@ -253,6 +289,7 @@ export async function reapOrphanDaytonaSandboxes(input: {
|
|
|
253
289
|
routingDomain,
|
|
254
290
|
});
|
|
255
291
|
} catch (error) {
|
|
292
|
+
ownershipReadFailed = true;
|
|
256
293
|
summary.errors += 1;
|
|
257
294
|
summary.spared += 1;
|
|
258
295
|
logger.warn('[daytona-janitor.ownership_read_failed]', {
|
|
@@ -279,6 +316,8 @@ export async function reapOrphanDaytonaSandboxes(input: {
|
|
|
279
316
|
continue;
|
|
280
317
|
}
|
|
281
318
|
|
|
319
|
+
if (ownership.operationState === 'live') summary.listedDurableLive += 1;
|
|
320
|
+
|
|
282
321
|
if (labelRunId && labelRunId !== ownership.runId) {
|
|
283
322
|
logger.info('[daytona-janitor.label_correlation_mismatch]', {
|
|
284
323
|
sandboxId: sandbox.id,
|
|
@@ -388,6 +427,42 @@ export async function reapOrphanDaytonaSandboxes(input: {
|
|
|
388
427
|
}
|
|
389
428
|
}
|
|
390
429
|
|
|
430
|
+
// Read after the list ends: a row still live now, and created before the list
|
|
431
|
+
// began, was live for the whole list, so a miss cannot be a race.
|
|
432
|
+
try {
|
|
433
|
+
const durable = await input.ownership.countDurableLive({
|
|
434
|
+
createdBeforeMs: listStartedAtMs - DAYTONA_DURABLE_LIVE_SETTLE_MS,
|
|
435
|
+
heartbeatStaleMs: DAYTONA_DURABLE_LIVE_HEARTBEAT_STALE_MS,
|
|
436
|
+
});
|
|
437
|
+
summary.durableLive = durable.live;
|
|
438
|
+
summary.durableLiveHeartbeating = durable.heartbeating;
|
|
439
|
+
} catch (error) {
|
|
440
|
+
summary.errors += 1;
|
|
441
|
+
logger.warn('[daytona-janitor.durable_live_read_failed]', {
|
|
442
|
+
error: error instanceof Error ? error.message : String(error),
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
// One missing sandbox whose runner went silent is likely a loss whose run
|
|
446
|
+
// has not settled. A missing runner that still heartbeats, or several
|
|
447
|
+
// missing at once (a gateway outage silences them all), is a blind list.
|
|
448
|
+
summary.listStale =
|
|
449
|
+
summary.durableLive !== null &&
|
|
450
|
+
summary.durableLiveHeartbeating !== null &&
|
|
451
|
+
summary.listedDurableLive === 0 &&
|
|
452
|
+
(summary.durableLiveHeartbeating > 0 || summary.durableLive >= 2) &&
|
|
453
|
+
!ownershipReadFailed;
|
|
454
|
+
if (summary.listStale) {
|
|
455
|
+
const reportStaleList =
|
|
456
|
+
input.options?.reportStaleList ??
|
|
457
|
+
((message, detail) => logger.warn(message, detail));
|
|
458
|
+
reportStaleList('[daytona-janitor.stale_list]', {
|
|
459
|
+
provider: 'daytona',
|
|
460
|
+
durableLive: summary.durableLive,
|
|
461
|
+
scanned: summary.scanned,
|
|
462
|
+
dryRun,
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
|
|
391
466
|
logger.info('[daytona-janitor.summary]', { ...summary, dryRun });
|
|
392
467
|
return summary;
|
|
393
468
|
}
|
|
@@ -453,6 +528,7 @@ export function createPostgresDaytonaJanitorOwnershipPort(input: {
|
|
|
453
528
|
schema: string;
|
|
454
529
|
}): DaytonaJanitorOwnershipPort {
|
|
455
530
|
const runs = `${quoteIdent(input.schema)}.${quoteIdent('runs')}`;
|
|
531
|
+
const attempts = `${quoteIdent(input.schema)}.${quoteIdent('attempts')}`;
|
|
456
532
|
const operations = `${quoteIdent(input.schema)}.${quoteIdent(
|
|
457
533
|
'runtime_sandbox_operations',
|
|
458
534
|
)}`;
|
|
@@ -652,6 +728,40 @@ export function createPostgresDaytonaJanitorOwnershipPort(input: {
|
|
|
652
728
|
}
|
|
653
729
|
return row.inserted ? 'scheduled' : 'already_authorized';
|
|
654
730
|
},
|
|
731
|
+
async countDurableLive({ createdBeforeMs, heartbeatStaleMs }) {
|
|
732
|
+
// The schema already scopes this to one lane. Listing both environments
|
|
733
|
+
// keeps the reconcile index usable. A finished run's sandbox is cleanup's
|
|
734
|
+
// to settle, so it says nothing about whether the list is current.
|
|
735
|
+
const result = await input.client.query<{
|
|
736
|
+
live: string;
|
|
737
|
+
heartbeating: string;
|
|
738
|
+
}>(
|
|
739
|
+
`
|
|
740
|
+
SELECT count(*)::text AS live,
|
|
741
|
+
count(*) FILTER (
|
|
742
|
+
WHERE attempt.heartbeat_at IS NULL
|
|
743
|
+
OR attempt.heartbeat_at > clock_timestamp()
|
|
744
|
+
- make_interval(secs => $2::double precision / 1000.0)
|
|
745
|
+
)::text AS heartbeating
|
|
746
|
+
FROM ${operations} AS operation
|
|
747
|
+
JOIN ${runs} AS run ON run.run_id = operation.run_id
|
|
748
|
+
LEFT JOIN ${attempts} AS attempt
|
|
749
|
+
ON attempt.run_id = operation.run_id
|
|
750
|
+
AND attempt.attempt = operation.attempt
|
|
751
|
+
WHERE operation.provider = 'daytona'
|
|
752
|
+
AND operation.environment IN ('production', 'preview')
|
|
753
|
+
AND operation.state = 'live'
|
|
754
|
+
AND operation.provider_created_at
|
|
755
|
+
<= to_timestamp($1::double precision / 1000.0)
|
|
756
|
+
AND run.status IN ('queued', 'running', 'waiting')
|
|
757
|
+
`,
|
|
758
|
+
[createdBeforeMs, heartbeatStaleMs],
|
|
759
|
+
);
|
|
760
|
+
return {
|
|
761
|
+
live: Number(result.rows[0]?.live ?? 0),
|
|
762
|
+
heartbeating: Number(result.rows[0]?.heartbeating ?? 0),
|
|
763
|
+
};
|
|
764
|
+
},
|
|
655
765
|
};
|
|
656
766
|
}
|
|
657
767
|
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
* secret and correctly lives in the environment.
|
|
28
28
|
*/
|
|
29
29
|
import { spawnSync } from 'node:child_process';
|
|
30
|
+
import { randomBytes } from 'node:crypto';
|
|
30
31
|
import { appendFileSync } from 'node:fs';
|
|
31
32
|
import { RUNTIME_CAPACITY_POLICY } from '../runtime-capacity-policy';
|
|
32
33
|
import { ABSURD_RELEASE_ID_RE } from '../runtime-scheduler-topology';
|
|
@@ -228,6 +229,13 @@ export type FlyMachine = {
|
|
|
228
229
|
* routing event as an explicit legacy-drain fence. */
|
|
229
230
|
events?: Array<{ type?: string; timestamp?: number }>;
|
|
230
231
|
region?: string;
|
|
232
|
+
/** Native resolved identity; config.image can omit its immutable digest. */
|
|
233
|
+
image_ref?: {
|
|
234
|
+
registry?: string;
|
|
235
|
+
repository?: string;
|
|
236
|
+
tag?: string;
|
|
237
|
+
digest?: string;
|
|
238
|
+
} | null;
|
|
231
239
|
config?: {
|
|
232
240
|
image?: string;
|
|
233
241
|
metadata?: Record<string, string>;
|
|
@@ -279,6 +287,12 @@ export function parseArgs(argv: readonly string[]): ParsedArgs {
|
|
|
279
287
|
index += 1;
|
|
280
288
|
}
|
|
281
289
|
}
|
|
290
|
+
if (
|
|
291
|
+
'image-ref' in flags &&
|
|
292
|
+
!['boot', 'replace', 'plan-image'].includes(command)
|
|
293
|
+
) {
|
|
294
|
+
throw new Error(`--image-ref is unsupported for ${command}.`);
|
|
295
|
+
}
|
|
282
296
|
return { command, flags };
|
|
283
297
|
}
|
|
284
298
|
|
|
@@ -346,6 +360,58 @@ export function laneImageRef(app: string, sha: string): string {
|
|
|
346
360
|
return `${FLY_REGISTRY_HOST}/${app}:git-${sha}`;
|
|
347
361
|
}
|
|
348
362
|
|
|
363
|
+
/** Preserve the registered image identity instead of deriving a tag in the target app.
|
|
364
|
+
* Shared Preview images must retain both their exact source tag and native digest.
|
|
365
|
+
*/
|
|
366
|
+
export function resolveWorkerLaneImage(input: {
|
|
367
|
+
app: string;
|
|
368
|
+
sha?: string;
|
|
369
|
+
imageRef: string;
|
|
370
|
+
}): { sha: string; imageRef: string } {
|
|
371
|
+
const prefix = `${FLY_REGISTRY_HOST}/${input.app}:git-`;
|
|
372
|
+
const legacySha = input.imageRef.startsWith(prefix)
|
|
373
|
+
? input.imageRef.slice(prefix.length)
|
|
374
|
+
: null;
|
|
375
|
+
const sharedSha =
|
|
376
|
+
/^registry\.fly\.io\/deepline-absurd-worker-preview-cache:git-([a-f0-9]{40})-worker-[a-f0-9]{64}@sha256:[a-f0-9]{64}$/.exec(
|
|
377
|
+
input.imageRef,
|
|
378
|
+
)?.[1];
|
|
379
|
+
const sha =
|
|
380
|
+
sharedSha ?? (legacySha && GIT_SHA_RE.test(legacySha) ? legacySha : null);
|
|
381
|
+
if (!sha)
|
|
382
|
+
throw new Error(`Invalid worker image reference: ${input.imageRef}`);
|
|
383
|
+
if (input.sha !== undefined && sha !== input.sha) {
|
|
384
|
+
throw new Error(
|
|
385
|
+
`Worker image source ${sha} disagrees with requested source ${input.sha}.`,
|
|
386
|
+
);
|
|
387
|
+
}
|
|
388
|
+
return { sha, imageRef: input.imageRef };
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/** Exact native immutable identity, shared semantically with the release gate's
|
|
392
|
+
* jq predicates. Config equality alone proves a requested tag, not its digest. */
|
|
393
|
+
export function flyMachineMatchesImage(
|
|
394
|
+
machine: FlyMachine,
|
|
395
|
+
image: string,
|
|
396
|
+
): boolean {
|
|
397
|
+
if (!image.includes('@')) return machine.config?.image === image;
|
|
398
|
+
const requested =
|
|
399
|
+
/^([A-Za-z0-9.-]+(?::[0-9]+)?)\/([A-Za-z0-9._-]+(?:\/[A-Za-z0-9._-]+)*):([A-Za-z0-9_][A-Za-z0-9_.-]*)@(sha256:[a-f0-9]{64})$/.exec(
|
|
400
|
+
image,
|
|
401
|
+
);
|
|
402
|
+
const resolved = machine.image_ref;
|
|
403
|
+
if (!requested || !resolved || typeof resolved !== 'object') return false;
|
|
404
|
+
const [, registry, repository, imageTag, digest] = requested;
|
|
405
|
+
const tag = `${registry}/${repository}:${imageTag}`;
|
|
406
|
+
return (
|
|
407
|
+
(machine.config?.image === image || machine.config?.image === tag) &&
|
|
408
|
+
resolved.registry === registry &&
|
|
409
|
+
resolved.repository === repository &&
|
|
410
|
+
resolved.tag === imageTag &&
|
|
411
|
+
resolved.digest === digest
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
|
|
349
415
|
export function laneQueueName(releaseId: string): string {
|
|
350
416
|
return `runs_${releaseId}`;
|
|
351
417
|
}
|
|
@@ -366,16 +432,32 @@ export function buildBootMachineConfig(input: {
|
|
|
366
432
|
app: string;
|
|
367
433
|
releaseId: string;
|
|
368
434
|
sha: string;
|
|
435
|
+
imageRef?: string;
|
|
369
436
|
runtimeSurfaceHash?: string;
|
|
370
437
|
componentInputHash?: string;
|
|
371
438
|
region?: string;
|
|
372
439
|
rollbackHoldUntilMs?: number;
|
|
373
440
|
draining?: boolean;
|
|
441
|
+
/** Provider secrets propagation fence; never a runtime schema or wire floor. */
|
|
442
|
+
secretsPropagationFence?: number;
|
|
374
443
|
}): Record<string, unknown> {
|
|
444
|
+
if (input.secretsPropagationFence !== undefined) {
|
|
445
|
+
assertMinSecretsVersion(input.secretsPropagationFence);
|
|
446
|
+
}
|
|
375
447
|
return {
|
|
376
448
|
region: input.region ?? DEFAULT_ABSURD_FLY_REGION,
|
|
449
|
+
...(input.secretsPropagationFence === undefined
|
|
450
|
+
? {}
|
|
451
|
+
: { min_secrets_version: input.secretsPropagationFence }),
|
|
377
452
|
config: {
|
|
378
|
-
image:
|
|
453
|
+
image:
|
|
454
|
+
input.imageRef === undefined
|
|
455
|
+
? laneImageRef(input.app, input.sha)
|
|
456
|
+
: resolveWorkerLaneImage({
|
|
457
|
+
app: input.app,
|
|
458
|
+
sha: input.sha,
|
|
459
|
+
imageRef: input.imageRef,
|
|
460
|
+
}).imageRef,
|
|
379
461
|
metadata: {
|
|
380
462
|
[RELEASE_METADATA_KEY]: input.releaseId,
|
|
381
463
|
...(input.runtimeSurfaceHash
|
|
@@ -569,6 +651,12 @@ export function requireFlyToken(
|
|
|
569
651
|
return token;
|
|
570
652
|
}
|
|
571
653
|
|
|
654
|
+
function assertMinSecretsVersion(value: unknown): asserts value is number {
|
|
655
|
+
if (typeof value !== 'number' || !Number.isSafeInteger(value) || value <= 0) {
|
|
656
|
+
throw new Error('Fly secrets version must be a positive safe integer.');
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
|
|
572
660
|
export class FlyMachinesClient {
|
|
573
661
|
constructor(
|
|
574
662
|
private readonly app: string,
|
|
@@ -681,6 +769,22 @@ export class FlyMachinesClient {
|
|
|
681
769
|
return (await this.request('POST', '/machines', config)) as FlyMachine;
|
|
682
770
|
}
|
|
683
771
|
|
|
772
|
+
/**
|
|
773
|
+
* Match native `flyctl secrets sync` without consulting its local config.
|
|
774
|
+
* The native protocol unsets a random nonexistent name to obtain a version;
|
|
775
|
+
* GET /secrets returns metadata only and cannot establish this fence.
|
|
776
|
+
* https://github.com/superfly/flyctl/blob/b3263736a487b5c713fc7733633cfbb2e2976dd6/internal/appsecrets/secrets.go#L48-L57
|
|
777
|
+
*/
|
|
778
|
+
async syncAppSecretsVersion(): Promise<number> {
|
|
779
|
+
const name = `BogusDummySecret_${randomBytes(8).toString('hex')}`;
|
|
780
|
+
const result = await this.request('POST', '/secrets', {
|
|
781
|
+
values: { [name]: null },
|
|
782
|
+
});
|
|
783
|
+
const version = (result as { version?: unknown } | null)?.version;
|
|
784
|
+
assertMinSecretsVersion(version);
|
|
785
|
+
return version;
|
|
786
|
+
}
|
|
787
|
+
|
|
684
788
|
async updateMachine(
|
|
685
789
|
id: string,
|
|
686
790
|
config: Record<string, unknown>,
|
|
@@ -1063,8 +1167,11 @@ export async function bootLane(input: {
|
|
|
1063
1167
|
app: string;
|
|
1064
1168
|
releaseId: string;
|
|
1065
1169
|
sha: string;
|
|
1170
|
+
imageRef?: string;
|
|
1066
1171
|
runtimeSurfaceHash?: string;
|
|
1067
1172
|
componentInputHash?: string;
|
|
1173
|
+
/** Provider secrets propagation fence; never a runtime schema or wire floor. */
|
|
1174
|
+
secretsPropagationFence?: number;
|
|
1068
1175
|
count: number;
|
|
1069
1176
|
region?: string;
|
|
1070
1177
|
timeoutMs?: number;
|
|
@@ -1078,6 +1185,9 @@ export async function bootLane(input: {
|
|
|
1078
1185
|
rollbackHoldUntilMs?: number;
|
|
1079
1186
|
rollbackHoldScalerQuiescenceMs?: number;
|
|
1080
1187
|
}): Promise<FlyMachine[]> {
|
|
1188
|
+
if (input.secretsPropagationFence !== undefined) {
|
|
1189
|
+
assertMinSecretsVersion(input.secretsPropagationFence);
|
|
1190
|
+
}
|
|
1081
1191
|
const now = input.now ?? (() => Date.now());
|
|
1082
1192
|
const wait = input.wait ?? sleep;
|
|
1083
1193
|
const timeoutMs = input.timeoutMs ?? DEFAULT_BOOT_TIMEOUT_MS;
|
|
@@ -1086,7 +1196,14 @@ export async function bootLane(input: {
|
|
|
1086
1196
|
input.imagePropagationRetryDelaysMs ??
|
|
1087
1197
|
DEFAULT_IMAGE_PROPAGATION_RETRY_DELAYS_MS;
|
|
1088
1198
|
|
|
1089
|
-
const expectedImage =
|
|
1199
|
+
const expectedImage =
|
|
1200
|
+
input.imageRef === undefined
|
|
1201
|
+
? laneImageRef(input.app, input.sha)
|
|
1202
|
+
: resolveWorkerLaneImage({
|
|
1203
|
+
app: input.app,
|
|
1204
|
+
sha: input.sha,
|
|
1205
|
+
imageRef: input.imageRef,
|
|
1206
|
+
}).imageRef;
|
|
1090
1207
|
const reusableStates = new Set([
|
|
1091
1208
|
'started',
|
|
1092
1209
|
'created',
|
|
@@ -1105,7 +1222,7 @@ export async function bootLane(input: {
|
|
|
1105
1222
|
? (await input.client.machinesInLane(input.releaseId))
|
|
1106
1223
|
.filter(
|
|
1107
1224
|
(machine) =>
|
|
1108
|
-
machine
|
|
1225
|
+
flyMachineMatchesImage(machine, expectedImage) &&
|
|
1109
1226
|
(!input.runtimeSurfaceHash ||
|
|
1110
1227
|
machine.config?.metadata?.[RUNTIME_SURFACE_METADATA_KEY] ===
|
|
1111
1228
|
input.runtimeSurfaceHash) &&
|
|
@@ -1113,7 +1230,7 @@ export async function bootLane(input: {
|
|
|
1113
1230
|
machine.config?.metadata?.[COMPONENT_INPUT_METADATA_KEY] ===
|
|
1114
1231
|
input.componentInputHash) &&
|
|
1115
1232
|
(input.rollbackHoldUntilMs !== undefined ||
|
|
1116
|
-
machine.config
|
|
1233
|
+
machine.config?.env?.[DRAIN_EXIT_ENV] !== '1') &&
|
|
1117
1234
|
reusableStates.has(machine.state ?? ''),
|
|
1118
1235
|
)
|
|
1119
1236
|
.sort((left, right) => statePriority(left) - statePriority(right))
|
|
@@ -1151,8 +1268,10 @@ export async function bootLane(input: {
|
|
|
1151
1268
|
app: input.app,
|
|
1152
1269
|
releaseId: input.releaseId,
|
|
1153
1270
|
sha: input.sha,
|
|
1271
|
+
imageRef: input.imageRef,
|
|
1154
1272
|
runtimeSurfaceHash: input.runtimeSurfaceHash,
|
|
1155
1273
|
componentInputHash: input.componentInputHash,
|
|
1274
|
+
secretsPropagationFence: input.secretsPropagationFence,
|
|
1156
1275
|
region: input.region,
|
|
1157
1276
|
rollbackHoldUntilMs: input.rollbackHoldUntilMs,
|
|
1158
1277
|
}),
|
|
@@ -1243,8 +1362,11 @@ export async function replaceLane(input: {
|
|
|
1243
1362
|
app: string;
|
|
1244
1363
|
releaseId: string;
|
|
1245
1364
|
sha: string;
|
|
1365
|
+
imageRef?: string;
|
|
1246
1366
|
runtimeSurfaceHash?: string;
|
|
1247
1367
|
componentInputHash?: string;
|
|
1368
|
+
/** Provider secrets propagation fence; never a runtime schema or wire floor. */
|
|
1369
|
+
secretsPropagationFence?: number;
|
|
1248
1370
|
count: number;
|
|
1249
1371
|
region?: string;
|
|
1250
1372
|
stopTimeoutMs?: number;
|
|
@@ -1253,12 +1375,21 @@ export async function replaceLane(input: {
|
|
|
1253
1375
|
wait?: (ms: number) => Promise<void>;
|
|
1254
1376
|
machineLogs?: (machineId: string) => string;
|
|
1255
1377
|
}): Promise<FlyMachine[]> {
|
|
1378
|
+
if (input.secretsPropagationFence !== undefined) {
|
|
1379
|
+
assertMinSecretsVersion(input.secretsPropagationFence);
|
|
1380
|
+
}
|
|
1256
1381
|
const now = input.now ?? (() => Date.now());
|
|
1257
1382
|
const wait = input.wait ?? sleep;
|
|
1258
1383
|
const stopTimeoutMs =
|
|
1259
1384
|
input.stopTimeoutMs ?? DEFAULT_LANE_REPLACEMENT_STOP_WAIT_MS;
|
|
1260
1385
|
const stopPollIntervalMs =
|
|
1261
1386
|
input.stopPollIntervalMs ?? DEFAULT_LANE_REPLACEMENT_STOP_POLL_INTERVAL_MS;
|
|
1387
|
+
if (input.imageRef !== undefined)
|
|
1388
|
+
resolveWorkerLaneImage({
|
|
1389
|
+
app: input.app,
|
|
1390
|
+
sha: input.sha,
|
|
1391
|
+
imageRef: input.imageRef,
|
|
1392
|
+
});
|
|
1262
1393
|
const predecessors = await input.client.machinesInLane(input.releaseId);
|
|
1263
1394
|
const predecessorIds = new Set(predecessors.map((machine) => machine.id));
|
|
1264
1395
|
|
|
@@ -1303,8 +1434,10 @@ export async function replaceLane(input: {
|
|
|
1303
1434
|
app: input.app,
|
|
1304
1435
|
releaseId: input.releaseId,
|
|
1305
1436
|
sha: input.sha,
|
|
1437
|
+
imageRef: input.imageRef,
|
|
1306
1438
|
runtimeSurfaceHash: input.runtimeSurfaceHash,
|
|
1307
1439
|
componentInputHash: input.componentInputHash,
|
|
1440
|
+
secretsPropagationFence: input.secretsPropagationFence,
|
|
1308
1441
|
count: input.count,
|
|
1309
1442
|
region: input.region,
|
|
1310
1443
|
now,
|
|
@@ -1329,6 +1462,10 @@ async function cmdBoot(flags: Record<string, string | boolean>): Promise<void> {
|
|
|
1329
1462
|
const app = resolveApp(flags);
|
|
1330
1463
|
const releaseId = requireReleaseId(flags);
|
|
1331
1464
|
const sha = requireSha(flags);
|
|
1465
|
+
const imageRef =
|
|
1466
|
+
flags['image-ref'] === undefined
|
|
1467
|
+
? undefined
|
|
1468
|
+
: requireStringFlag(flags, 'image-ref');
|
|
1332
1469
|
const count = requireCount(flags);
|
|
1333
1470
|
const region = typeof flags.region === 'string' ? flags.region : undefined;
|
|
1334
1471
|
const reuseExisting = flags['reuse-existing'] === true;
|
|
@@ -1374,12 +1511,16 @@ async function cmdBoot(flags: Record<string, string | boolean>): Promise<void> {
|
|
|
1374
1511
|
app,
|
|
1375
1512
|
releaseId,
|
|
1376
1513
|
sha,
|
|
1514
|
+
imageRef,
|
|
1377
1515
|
runtimeSurfaceHash,
|
|
1378
1516
|
componentInputHash,
|
|
1379
1517
|
count,
|
|
1380
1518
|
region,
|
|
1381
1519
|
reuseExisting,
|
|
1382
1520
|
rollbackHoldUntilMs,
|
|
1521
|
+
...(flags.environment === 'preview'
|
|
1522
|
+
? { secretsPropagationFence: await client.syncAppSecretsVersion() }
|
|
1523
|
+
: {}),
|
|
1383
1524
|
});
|
|
1384
1525
|
}
|
|
1385
1526
|
|
|
@@ -1389,6 +1530,10 @@ async function cmdReplace(
|
|
|
1389
1530
|
const app = resolveApp(flags);
|
|
1390
1531
|
const releaseId = requireReleaseId(flags);
|
|
1391
1532
|
const sha = requireSha(flags);
|
|
1533
|
+
const imageRef =
|
|
1534
|
+
flags['image-ref'] === undefined
|
|
1535
|
+
? undefined
|
|
1536
|
+
: requireStringFlag(flags, 'image-ref');
|
|
1392
1537
|
const count = requireCount(flags);
|
|
1393
1538
|
const region = typeof flags.region === 'string' ? flags.region : undefined;
|
|
1394
1539
|
const componentInputHash =
|
|
@@ -1410,9 +1555,13 @@ async function cmdReplace(
|
|
|
1410
1555
|
app,
|
|
1411
1556
|
releaseId,
|
|
1412
1557
|
sha,
|
|
1558
|
+
imageRef,
|
|
1413
1559
|
componentInputHash,
|
|
1414
1560
|
count,
|
|
1415
1561
|
region,
|
|
1562
|
+
...(flags.environment === 'preview'
|
|
1563
|
+
? { secretsPropagationFence: await client.syncAppSecretsVersion() }
|
|
1564
|
+
: {}),
|
|
1416
1565
|
});
|
|
1417
1566
|
}
|
|
1418
1567
|
|
|
@@ -2065,8 +2214,8 @@ const USAGE = `fly-absurd-lane <command> [flags]
|
|
|
2065
2214
|
Commands:
|
|
2066
2215
|
push-image --sha <sha> --release <id> [--app <app>]
|
|
2067
2216
|
plan-image --release <id> [--image-ref <ref>] [--app <app>]
|
|
2068
|
-
boot --release <id> --sha <sha> --count <K> [--reuse-existing] [--component-input-hash <sha256>] [--rollback-hold-until-ms <ms>] [--app <app>] [--region <r>]
|
|
2069
|
-
replace --release <id> --sha <sha> --count <K> --environment preview [--component-input-hash <sha256>] [--app <app>] [--region <r>]
|
|
2217
|
+
boot --release <id> --sha <sha> --count <K> [--image-ref <ref>] [--reuse-existing] [--component-input-hash <sha256>] [--rollback-hold-until-ms <ms>] [--app <app>] [--region <r>]
|
|
2218
|
+
replace --release <id> --sha <sha> --count <K> [--image-ref <ref>] --environment preview [--component-input-hash <sha256>] [--app <app>] [--region <r>]
|
|
2070
2219
|
list [--release <id>] [--json] [--app <app>]
|
|
2071
2220
|
drain --release <id> [--if-present] [--app <app>]
|
|
2072
2221
|
stop-claiming --release <id> [--environment production|preview]
|