spawnfile 0.1.17 → 0.1.18
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/README.md +1 -1
- package/dist/auth/importers.js +21 -5
- package/dist/auth/index.d.ts +1 -0
- package/dist/auth/index.js +1 -0
- package/dist/auth/profileStore.js +4 -1
- package/dist/auth/trainingGrokWriteback.d.ts +4 -0
- package/dist/auth/trainingGrokWriteback.js +119 -0
- package/dist/auth/trainingGrokWritebackLock.d.ts +5 -0
- package/dist/auth/trainingGrokWritebackLock.js +56 -0
- package/dist/cli/authCommands.js +9 -5
- package/dist/cli/compileBuildCommands.js +4 -0
- package/dist/cli/devCommands.js +4 -2
- package/dist/cli/downCommand.d.ts +2 -0
- package/dist/cli/downCommand.js +3 -0
- package/dist/cli/envFileOption.d.ts +18 -0
- package/dist/cli/envFileOption.js +20 -0
- package/dist/cli/lifecycleCommands.d.ts +1 -1
- package/dist/cli/lifecycleCommands.js +3 -1
- package/dist/cli/lifecyclePlan.d.ts +1 -0
- package/dist/cli/lifecyclePlan.js +2 -0
- package/dist/cli/paideiaDelegation.d.ts +2 -1
- package/dist/cli/paideiaDelegation.js +5 -4
- package/dist/cli/recordCommands.d.ts +17 -0
- package/dist/cli/recordCommands.js +43 -0
- package/dist/cli/releaseCommand.d.ts +6 -0
- package/dist/cli/releaseCommand.js +91 -0
- package/dist/cli/runCli.d.ts +7 -1
- package/dist/cli/runCli.js +11 -6
- package/dist/cli/runPublishCommands.js +5 -3
- package/dist/cli/trainCommand.js +73 -20
- package/dist/cli/upCommand.js +5 -1
- package/dist/cli/volumeCommands.d.ts +8 -0
- package/dist/cli/volumeCommands.js +53 -0
- package/dist/compiler/agentNodeMerge.js +3 -2
- package/dist/compiler/buildCompilePlan.js +4 -0
- package/dist/compiler/buildCompilePlanAgent.js +3 -1
- package/dist/compiler/buildCompilePlanTraversal.js +2 -0
- package/dist/compiler/buildCompilePlanTraversalHelpers.d.ts +2 -2
- package/dist/compiler/buildCompilePlanTraversalHelpers.js +4 -3
- package/dist/compiler/buildProject.d.ts +10 -0
- package/dist/compiler/buildProject.js +14 -2
- package/dist/compiler/cleanCompileOutput.d.ts +2 -0
- package/dist/compiler/cleanCompileOutput.js +14 -0
- package/dist/compiler/compilePlanHelpers.js +2 -0
- package/dist/compiler/compileProject.d.ts +10 -0
- package/dist/compiler/compileProject.js +29 -3
- package/dist/compiler/containerArtifactSummaries.js +1 -0
- package/dist/compiler/containerArtifacts.d.ts +4 -4
- package/dist/compiler/containerArtifacts.js +18 -34
- package/dist/compiler/containerArtifactsPlans.js +7 -0
- package/dist/compiler/containerArtifactsTypes.d.ts +7 -0
- package/dist/compiler/containerDaimonBrokerRender.d.ts +3 -1
- package/dist/compiler/containerDaimonBrokerRender.js +6 -3
- package/dist/compiler/containerDaimonGrokTaskClock.d.ts +5 -0
- package/dist/compiler/containerDaimonGrokTaskClock.js +29 -0
- package/dist/compiler/containerDaimonGrokWorkerProvisioning.d.ts +1 -1
- package/dist/compiler/containerDaimonGrokWorkerProvisioning.js +38 -16
- package/dist/compiler/containerDaimonGrokWorkerRender.d.ts +33 -8
- package/dist/compiler/containerDaimonGrokWorkerRender.js +18 -5
- package/dist/compiler/containerDaimonOwnershipGuardRender.d.ts +14 -1
- package/dist/compiler/containerDaimonOwnershipGuardRender.js +15 -2
- package/dist/compiler/containerDaimonUidEntrypointRender.js +6 -12
- package/dist/compiler/containerTargetResources.d.ts +10 -0
- package/dist/compiler/containerTargetResources.js +21 -13
- package/dist/compiler/containerWorkspaceResourceRender.js +4 -1
- package/dist/compiler/index.d.ts +2 -0
- package/dist/compiler/index.js +2 -0
- package/dist/compiler/mcpPlaceholders.d.ts +11 -0
- package/dist/compiler/mcpPlaceholders.js +58 -0
- package/dist/compiler/mcpServerInheritance.d.ts +18 -0
- package/dist/compiler/mcpServerInheritance.js +43 -0
- package/dist/compiler/moltnetArtifactTypes.d.ts +1 -0
- package/dist/compiler/moltnetArtifacts.js +1 -0
- package/dist/compiler/preflightCompilePlan.d.ts +9 -0
- package/dist/compiler/preflightCompilePlan.js +38 -0
- package/dist/compiler/recordingAgentFacts.d.ts +4 -0
- package/dist/compiler/recordingAgentFacts.js +35 -0
- package/dist/compiler/recordingCapability.d.ts +4 -0
- package/dist/compiler/recordingCapability.js +22 -0
- package/dist/compiler/recordingReport.d.ts +4 -0
- package/dist/compiler/recordingReport.js +18 -0
- package/dist/compiler/runProject.d.ts +2 -1
- package/dist/compiler/runProject.js +2 -0
- package/dist/compiler/surfaces.d.ts +1 -2
- package/dist/compiler/surfaces.js +0 -1
- package/dist/compiler/syncProjectAuth.js +2 -1
- package/dist/compiler/training/broker/clockProbe.d.ts +6 -0
- package/dist/compiler/training/broker/clockProbe.js +27 -0
- package/dist/compiler/training/broker/declaration.d.ts +4 -2
- package/dist/compiler/training/broker/declaration.js +4 -2
- package/dist/compiler/training/broker/entrypoint.js +33 -18
- package/dist/compiler/training/broker/evaluatorSecrets.d.ts +2 -0
- package/dist/compiler/training/broker/evaluatorSecrets.js +60 -0
- package/dist/compiler/training/broker/index.d.ts +3 -2
- package/dist/compiler/training/broker/index.js +3 -2
- package/dist/compiler/training/broker/main.js +1 -1
- package/dist/compiler/training/broker/paths.d.ts +96 -56
- package/dist/compiler/training/broker/paths.js +97 -89
- package/dist/compiler/training/broker/processes.d.ts +9 -0
- package/dist/compiler/training/broker/processes.js +4 -1
- package/dist/compiler/training/broker/projection.d.ts +3 -2
- package/dist/compiler/training/broker/projection.js +21 -9
- package/dist/compiler/training/broker/provisioning.d.ts +6 -15
- package/dist/compiler/training/broker/provisioning.js +71 -53
- package/dist/compiler/training/broker/registration.d.ts +3 -1
- package/dist/compiler/training/broker/registration.js +29 -21
- package/dist/compiler/training/broker/reset.d.ts +9 -0
- package/dist/compiler/training/broker/reset.js +71 -0
- package/dist/compiler/training/broker/runtime.d.ts +10 -13
- package/dist/compiler/training/broker/runtime.js +69 -115
- package/dist/compiler/training/broker/supervisor.d.ts +10 -11
- package/dist/compiler/training/broker/supervisor.js +22 -23
- package/dist/compiler/training/broker/taskClock.d.ts +5 -0
- package/dist/compiler/training/broker/taskClock.js +41 -0
- package/dist/compiler/training/compiledAgent.d.ts +21 -0
- package/dist/compiler/training/compiledAgent.js +62 -0
- package/dist/compiler/training/container/contract.d.ts +23 -0
- package/dist/compiler/training/container/contract.js +23 -5
- package/dist/compiler/training/container/evaluators.d.ts +48 -0
- package/dist/compiler/training/container/evaluators.js +50 -0
- package/dist/compiler/training/container/grokWriteback.d.ts +8 -0
- package/dist/compiler/training/container/grokWriteback.js +26 -0
- package/dist/compiler/training/container/index.d.ts +2 -1
- package/dist/compiler/training/container/index.js +2 -1
- package/dist/compiler/training/container/launch.d.ts +3 -0
- package/dist/compiler/training/container/launch.js +119 -28
- package/dist/compiler/training/container/nativeSlots.d.ts +14 -0
- package/dist/compiler/training/container/nativeSlots.js +13 -0
- package/dist/compiler/training/container/outputCopy.d.ts +2 -0
- package/dist/compiler/training/container/outputCopy.js +72 -0
- package/dist/compiler/training/container/outputVolume.d.ts +27 -0
- package/dist/compiler/training/container/outputVolume.js +161 -0
- package/dist/compiler/training/container/prepare.d.ts +3 -1
- package/dist/compiler/training/container/prepare.js +57 -12
- package/dist/compiler/training/container/security.d.ts +5 -3
- package/dist/compiler/training/container/security.js +15 -5
- package/dist/compiler/training/container/subjectIsolation.d.ts +5 -0
- package/dist/compiler/training/container/subjectIsolation.js +15 -0
- package/dist/compiler/training/context.d.ts +8 -0
- package/dist/compiler/training/context.js +12 -12
- package/dist/compiler/training/contract.d.ts +2 -0
- package/dist/compiler/training/contract.js +2 -0
- package/dist/compiler/training/execution.d.ts +417 -0
- package/dist/compiler/training/execution.js +160 -0
- package/dist/compiler/training/index.d.ts +8 -0
- package/dist/compiler/training/index.js +7 -0
- package/dist/compiler/training/moments.d.ts +80 -0
- package/dist/compiler/training/moments.js +118 -0
- package/dist/compiler/training/output.d.ts +2 -0
- package/dist/compiler/training/output.js +20 -0
- package/dist/compiler/training/plan/contract.d.ts +287 -0
- package/dist/compiler/training/plan/contract.js +49 -0
- package/dist/compiler/training/plan/index.d.ts +5 -0
- package/dist/compiler/training/plan/index.js +4 -0
- package/dist/compiler/training/plan/load.d.ts +9 -0
- package/dist/compiler/training/plan/load.js +153 -0
- package/dist/compiler/training/plan/references.d.ts +19 -0
- package/dist/compiler/training/plan/references.js +57 -0
- package/dist/compiler/training/plan/resolve.d.ts +4 -0
- package/dist/compiler/training/plan/resolve.js +73 -0
- package/dist/compiler/training/plan/targets.d.ts +11 -0
- package/dist/compiler/training/plan/targets.js +71 -0
- package/dist/compiler/training/plan/types.d.ts +36 -0
- package/dist/compiler/training/plan/types.js +1 -0
- package/dist/compiler/training/preparation/assets/Dockerfile +13 -2
- package/dist/compiler/training/preparation/assets/package-lock.json +2 -2
- package/dist/compiler/training/preparation/broker.d.ts +3 -3
- package/dist/compiler/training/preparation/broker.js +6 -4
- package/dist/compiler/training/preparation/contract.d.ts +27 -2
- package/dist/compiler/training/preparation/contract.js +23 -4
- package/dist/compiler/training/preparation/files.d.ts +5 -1
- package/dist/compiler/training/preparation/files.js +76 -15
- package/dist/compiler/training/preparation/image.js +9 -4
- package/dist/compiler/training/preparation/inputs.d.ts +1 -0
- package/dist/compiler/training/preparation/inputs.js +18 -10
- package/dist/compiler/training/preparation/prepare.d.ts +5 -0
- package/dist/compiler/training/preparation/prepare.js +66 -29
- package/dist/compiler/training/preparation/scratch.d.ts +6 -17
- package/dist/compiler/training/preparation/scratch.js +89 -23
- package/dist/compiler/training/repair/contract.d.ts +338 -4
- package/dist/compiler/training/repair/contract.js +2 -0
- package/dist/compiler/training/repair/index.d.ts +1 -1
- package/dist/compiler/training/repair/index.js +1 -1
- package/dist/compiler/training/repair/prepare.d.ts +155 -3
- package/dist/compiler/training/repair/prepare.js +6 -2
- package/dist/compiler/training/repair/witness.d.ts +152 -3
- package/dist/compiler/training/repair/witness.js +8 -2
- package/dist/compiler/training/resolution.d.ts +25 -0
- package/dist/compiler/training/resolution.js +69 -0
- package/dist/compiler/training/rewind/contract.d.ts +321 -0
- package/dist/compiler/training/rewind/contract.js +39 -0
- package/dist/compiler/training/rewind/deployedResource.d.ts +22 -0
- package/dist/compiler/training/rewind/deployedResource.js +19 -0
- package/dist/compiler/training/rewind/feed.d.ts +12 -0
- package/dist/compiler/training/rewind/feed.js +182 -0
- package/dist/compiler/training/rewind/feedContent.d.ts +6 -0
- package/dist/compiler/training/rewind/feedContent.js +38 -0
- package/dist/compiler/training/rewind/git.d.ts +8 -0
- package/dist/compiler/training/rewind/git.js +159 -0
- package/dist/compiler/training/rewind/gitArchive.d.ts +2 -0
- package/dist/compiler/training/rewind/gitArchive.js +7 -0
- package/dist/compiler/training/rewind/gitHistory.d.ts +3 -0
- package/dist/compiler/training/rewind/gitHistory.js +55 -0
- package/dist/compiler/training/rewind/gitProcess.d.ts +19 -0
- package/dist/compiler/training/rewind/gitProcess.js +81 -0
- package/dist/compiler/training/rewind/gitTree.d.ts +14 -0
- package/dist/compiler/training/rewind/gitTree.js +90 -0
- package/dist/compiler/training/rewind/history.d.ts +28 -0
- package/dist/compiler/training/rewind/history.js +239 -0
- package/dist/compiler/training/rewind/index.d.ts +18 -0
- package/dist/compiler/training/rewind/index.js +15 -0
- package/dist/compiler/training/rewind/inputs.d.ts +9 -0
- package/dist/compiler/training/rewind/inputs.js +67 -0
- package/dist/compiler/training/rewind/instant.d.ts +4 -0
- package/dist/compiler/training/rewind/instant.js +24 -0
- package/dist/compiler/training/rewind/leakCheck.d.ts +10 -0
- package/dist/compiler/training/rewind/leakCheck.js +56 -0
- package/dist/compiler/training/rewind/leakFeed.d.ts +5 -0
- package/dist/compiler/training/rewind/leakFeed.js +25 -0
- package/dist/compiler/training/rewind/leakFiles.d.ts +10 -0
- package/dist/compiler/training/rewind/leakFiles.js +106 -0
- package/dist/compiler/training/rewind/leakGit.d.ts +3 -0
- package/dist/compiler/training/rewind/leakGit.js +78 -0
- package/dist/compiler/training/rewind/leakGitPayload.d.ts +4 -0
- package/dist/compiler/training/rewind/leakGitPayload.js +57 -0
- package/dist/compiler/training/rewind/leakInputs.d.ts +7 -0
- package/dist/compiler/training/rewind/leakInputs.js +135 -0
- package/dist/compiler/training/rewind/leakLayout.d.ts +2 -0
- package/dist/compiler/training/rewind/leakLayout.js +17 -0
- package/dist/compiler/training/rewind/leakProvenance.d.ts +3 -0
- package/dist/compiler/training/rewind/leakProvenance.js +88 -0
- package/dist/compiler/training/rewind/materialize.d.ts +136 -0
- package/dist/compiler/training/rewind/materialize.js +212 -0
- package/dist/compiler/training/rewind/memory.d.ts +10 -0
- package/dist/compiler/training/rewind/memory.js +84 -0
- package/dist/compiler/training/rewind/memorySchemas.d.ts +87 -0
- package/dist/compiler/training/rewind/memorySchemas.js +50 -0
- package/dist/compiler/training/rewind/moltnet.d.ts +2 -0
- package/dist/compiler/training/rewind/moltnet.js +54 -0
- package/dist/compiler/training/rewind/moltnetJson.d.ts +13 -0
- package/dist/compiler/training/rewind/moltnetJson.js +180 -0
- package/dist/compiler/training/rewind/moltnetSchemas.d.ts +1226 -0
- package/dist/compiler/training/rewind/moltnetSchemas.js +75 -0
- package/dist/compiler/training/rewind/moltnetSqlite.d.ts +31 -0
- package/dist/compiler/training/rewind/moltnetSqlite.js +192 -0
- package/dist/compiler/training/rewind/moltnetSqliteData.d.ts +10 -0
- package/dist/compiler/training/rewind/moltnetSqliteData.js +113 -0
- package/dist/compiler/training/rewind/recordInput.d.ts +40 -0
- package/dist/compiler/training/rewind/recordInput.js +49 -0
- package/dist/compiler/training/rewind/recordedBundle.d.ts +4 -0
- package/dist/compiler/training/rewind/recordedBundle.js +58 -0
- package/dist/compiler/training/rewind/recordedCommit.d.ts +2 -0
- package/dist/compiler/training/rewind/recordedCommit.js +10 -0
- package/dist/compiler/training/rewind/select.d.ts +18 -0
- package/dist/compiler/training/rewind/select.js +64 -0
- package/dist/compiler/training/rewind/snapshotManifest.d.ts +42 -0
- package/dist/compiler/training/rewind/snapshotManifest.js +134 -0
- package/dist/compiler/training/rewind/taskClock.d.ts +12 -0
- package/dist/compiler/training/rewind/taskClock.js +40 -0
- package/dist/compiler/training/rewind/timestamps.d.ts +4 -0
- package/dist/compiler/training/rewind/timestamps.js +26 -0
- package/dist/compiler/training/rewind/types.d.ts +43 -0
- package/dist/compiler/training/rewind/types.js +1 -0
- package/dist/compiler/training/rewind/volumes.d.ts +12 -0
- package/dist/compiler/training/rewind/volumes.js +58 -0
- package/dist/compiler/training/selection.d.ts +7 -0
- package/dist/compiler/training/selection.js +15 -0
- package/dist/compiler/types.d.ts +6 -3
- package/dist/compiler/upProject.d.ts +1 -0
- package/dist/compiler/upProject.js +21 -5
- package/dist/compiler/workspaceBundleArtifacts.d.ts +16 -1
- package/dist/compiler/workspaceBundleArtifacts.js +69 -20
- package/dist/compiler/workspaceBundleCache.d.ts +23 -0
- package/dist/compiler/workspaceBundleCache.js +79 -0
- package/dist/compiler/workspaceBundleDependencies.d.ts +21 -0
- package/dist/compiler/workspaceBundleDependencies.js +122 -0
- package/dist/compiler/workspaceBundleFiles.d.ts +51 -0
- package/dist/compiler/workspaceBundleFiles.js +251 -0
- package/dist/compiler/workspaceBundleGenerated.d.ts +25 -0
- package/dist/compiler/workspaceBundleGenerated.js +103 -0
- package/dist/compiler/workspaceBundleGit.d.ts +64 -0
- package/dist/compiler/workspaceBundleGit.js +154 -0
- package/dist/compiler/workspaceBundleKey.d.ts +34 -0
- package/dist/compiler/workspaceBundleKey.js +17 -0
- package/dist/compiler/workspaceBundleResolve.d.ts +56 -0
- package/dist/compiler/workspaceBundleResolve.js +144 -0
- package/dist/compiler/workspaceBundleRun.d.ts +41 -0
- package/dist/compiler/workspaceBundleRun.js +79 -0
- package/dist/compiler/workspaceBundleTar.d.ts +47 -0
- package/dist/compiler/workspaceBundleTar.js +140 -0
- package/dist/compiler/workspaceBundleTree.d.ts +15 -0
- package/dist/compiler/workspaceBundleTree.js +58 -0
- package/dist/compiler/workspaceGitFetch.d.ts +41 -0
- package/dist/compiler/workspaceGitFetch.js +155 -0
- package/dist/compiler/workspaceGitPins.d.ts +33 -0
- package/dist/compiler/workspaceGitPins.js +127 -0
- package/dist/compiler/workspaceResources.d.ts +5 -1
- package/dist/compiler/workspaceResources.js +32 -5
- package/dist/deployment/activation.d.ts +3 -0
- package/dist/deployment/activation.js +12 -0
- package/dist/deployment/canaryCutover.d.ts +1 -1
- package/dist/deployment/candidateRecording.d.ts +8 -0
- package/dist/deployment/candidateRecording.js +22 -0
- package/dist/deployment/dockerManager.d.ts +5 -3
- package/dist/deployment/dockerManager.js +12 -2
- package/dist/deployment/downDeployment.d.ts +2 -0
- package/dist/deployment/downDeployment.js +6 -2
- package/dist/deployment/homeStore.d.ts +9 -1
- package/dist/deployment/homeStore.js +16 -53
- package/dist/deployment/index.d.ts +6 -0
- package/dist/deployment/index.js +6 -0
- package/dist/deployment/pidLock.d.ts +25 -0
- package/dist/deployment/pidLock.js +81 -0
- package/dist/deployment/record.d.ts +85 -1
- package/dist/deployment/record.js +11 -5
- package/dist/deployment/recordPublication.d.ts +15 -0
- package/dist/deployment/recordPublication.js +76 -0
- package/dist/deployment/recordedMemoryRetention.d.ts +18 -0
- package/dist/deployment/recordedMemoryRetention.js +27 -0
- package/dist/deployment/resourceLog.d.ts +140 -0
- package/dist/deployment/resourceLog.js +78 -0
- package/dist/distribution/buildDistributionReport.d.ts +3 -0
- package/dist/distribution/buildDistributionReport.js +5 -0
- package/dist/distribution/consumeImage.d.ts +3 -0
- package/dist/distribution/consumeImage.js +23 -31
- package/dist/distribution/consumeImageLifecycle.d.ts +4 -1
- package/dist/distribution/consumeImageLifecycle.js +14 -3
- package/dist/distribution/consumeImageSupport.d.ts +7 -0
- package/dist/distribution/consumeImageSupport.js +25 -0
- package/dist/distribution/distributionReportSchema.d.ts +47 -0
- package/dist/distribution/distributionReportSchema.js +20 -0
- package/dist/distribution/renderImageInterface.js +1 -1
- package/dist/distribution/types.d.ts +15 -0
- package/dist/filesystem/durableWrite.d.ts +10 -0
- package/dist/filesystem/durableWrite.js +87 -0
- package/dist/filesystem/index.d.ts +2 -0
- package/dist/filesystem/index.js +2 -0
- package/dist/filesystem/retainedJsonl.d.ts +23 -0
- package/dist/filesystem/retainedJsonl.js +123 -0
- package/dist/manifest/commandSchemas.d.ts +5 -0
- package/dist/manifest/commandSchemas.js +5 -0
- package/dist/manifest/executionSchemas.d.ts +20 -0
- package/dist/manifest/executionSchemas.js +13 -3
- package/dist/manifest/index.d.ts +2 -0
- package/dist/manifest/index.js +2 -0
- package/dist/manifest/loadManifest.js +3 -26
- package/dist/manifest/mcpSchemas.d.ts +61 -0
- package/dist/manifest/mcpSchemas.js +57 -11
- package/dist/manifest/memorySchemas.d.ts +1 -1
- package/dist/manifest/memorySchemas.js +1 -1
- package/dist/manifest/parseManifest.d.ts +7 -0
- package/dist/manifest/parseManifest.js +65 -0
- package/dist/manifest/renderSpawnfile.js +4 -1
- package/dist/manifest/renderSpawnfileWorkspace.js +6 -2
- package/dist/manifest/schemas.d.ts +1206 -132
- package/dist/manifest/schemas.js +14 -4
- package/dist/manifest/teamNetworkSchemas.d.ts +1 -1
- package/dist/manifest/trainingDataSchemas.d.ts +357 -0
- package/dist/manifest/trainingDataSchemas.js +31 -0
- package/dist/manifest/trainingSchemas.d.ts +49 -0
- package/dist/manifest/trainingSchemas.js +44 -0
- package/dist/manifest/volumeFeedSchemas.d.ts +52 -0
- package/dist/manifest/volumeFeedSchemas.js +104 -0
- package/dist/manifest/workspaceSchemas.d.ts +182 -5
- package/dist/manifest/workspaceSchemas.js +111 -7
- package/dist/recording/compose.d.ts +3 -0
- package/dist/recording/compose.js +93 -0
- package/dist/recording/deployment.d.ts +15 -0
- package/dist/recording/deployment.js +38 -0
- package/dist/recording/history.d.ts +16 -0
- package/dist/recording/history.js +47 -0
- package/dist/recording/index.d.ts +9 -0
- package/dist/recording/index.js +9 -0
- package/dist/recording/moment.d.ts +61 -0
- package/dist/recording/moment.js +36 -0
- package/dist/recording/parse.d.ts +15 -0
- package/dist/recording/parse.js +74 -0
- package/dist/recording/read.d.ts +8 -0
- package/dist/recording/read.js +61 -0
- package/dist/recording/store.d.ts +10 -0
- package/dist/recording/store.js +94 -0
- package/dist/recording/sync.d.ts +24 -0
- package/dist/recording/sync.js +126 -0
- package/dist/recording/types.d.ts +45 -0
- package/dist/recording/types.js +2 -0
- package/dist/release/drainControl.d.ts +54 -0
- package/dist/release/drainControl.js +137 -0
- package/dist/release/drainPhase.d.ts +37 -0
- package/dist/release/drainPhase.js +161 -0
- package/dist/release/index.d.ts +11 -0
- package/dist/release/index.js +11 -0
- package/dist/release/ledger.d.ts +75 -0
- package/dist/release/ledger.js +111 -0
- package/dist/release/notify.d.ts +58 -0
- package/dist/release/notify.js +126 -0
- package/dist/release/pending.d.ts +35 -0
- package/dist/release/pending.js +60 -0
- package/dist/release/postDeploy.d.ts +32 -0
- package/dist/release/postDeploy.js +62 -0
- package/dist/release/releaseDefaults.d.ts +9 -0
- package/dist/release/releaseDefaults.js +115 -0
- package/dist/release/releaseDocker.d.ts +38 -0
- package/dist/release/releaseDocker.js +94 -0
- package/dist/release/releaseTypes.d.ts +94 -0
- package/dist/release/releaseTypes.js +1 -0
- package/dist/release/runRelease.d.ts +9 -0
- package/dist/release/runRelease.js +218 -0
- package/dist/release/swap.d.ts +23 -0
- package/dist/release/swap.js +55 -0
- package/dist/release/types.d.ts +50 -0
- package/dist/release/types.js +29 -0
- package/dist/report/index.d.ts +1 -0
- package/dist/report/index.js +1 -0
- package/dist/report/recording.d.ts +57 -0
- package/dist/report/recording.js +26 -0
- package/dist/report/types.d.ts +58 -0
- package/dist/runtime/container.js +8 -13
- package/dist/runtime/daimon/adapter.js +15 -4
- package/dist/runtime/daimon/config.d.ts +4 -0
- package/dist/runtime/daimon/config.js +53 -4
- package/dist/runtime/daimon/contract-manifest.json +1 -0
- package/dist/runtime/daimon/contract-manifest.sha256 +1 -0
- package/dist/runtime/daimon/contractManifest.d.ts +59 -8
- package/dist/runtime/daimon/contractManifest.js +26 -10
- package/dist/runtime/daimon/grokTurnLimits.d.ts +25 -0
- package/dist/runtime/daimon/grokTurnLimits.js +51 -0
- package/dist/runtime/daimon/grokWorkerConfigBytes.d.ts +17 -0
- package/dist/runtime/daimon/grokWorkerConfigBytes.js +17 -0
- package/dist/runtime/daimon/grokWorkerContract.d.ts +5 -0
- package/dist/runtime/daimon/grokWorkerContract.js +13 -1
- package/dist/runtime/daimon/recording.d.ts +19 -0
- package/dist/runtime/daimon/recording.js +50 -0
- package/dist/runtime/daimon/scheduleAuthority.d.ts +8 -0
- package/dist/runtime/daimon/scheduleAuthority.js +19 -5
- package/dist/runtime/daimon/wakeMoments.d.ts +15 -0
- package/dist/runtime/daimon/wakeMoments.js +17 -0
- package/dist/runtime/daimonInstall.d.ts +3 -0
- package/dist/runtime/daimonInstall.js +25 -0
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/install.d.ts +2 -0
- package/dist/runtime/install.js +1 -0
- package/dist/runtime/openclaw/adapter.js +3 -0
- package/dist/runtime/pi/adapter.js +3 -0
- package/dist/runtime/pi/containerTargets.js +6 -0
- package/dist/runtime/picoclaw/adapter.js +3 -0
- package/dist/runtime/registry.d.ts +3 -0
- package/dist/runtime/registry.js +13 -1
- package/dist/runtime/types.d.ts +15 -0
- package/dist/runtime/usageLedgerRead.d.ts +6 -0
- package/dist/runtime/usageLedgerRead.js +3 -3
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.js +1 -0
- package/dist/shared/recording.d.ts +8 -0
- package/dist/shared/recording.js +25 -0
- package/dist/target/dockerCommandExecutorCore.js +1 -1
- package/dist/target/dockerTargetBinding.js +2 -1
- package/dist/volume/feedLand.d.ts +31 -0
- package/dist/volume/feedLand.js +174 -0
- package/dist/volume/feedLandings.d.ts +45 -0
- package/dist/volume/feedLandings.js +111 -0
- package/dist/volume/feedLayout.d.ts +61 -0
- package/dist/volume/feedLayout.js +234 -0
- package/dist/volume/feedLock.d.ts +7 -0
- package/dist/volume/feedLock.js +131 -0
- package/dist/volume/feedManifest.d.ts +27 -0
- package/dist/volume/feedManifest.js +123 -0
- package/dist/volume/feedPrepare.d.ts +16 -0
- package/dist/volume/feedPrepare.js +228 -0
- package/dist/volume/feedProject.d.ts +39 -0
- package/dist/volume/feedProject.js +92 -0
- package/dist/volume/feedRecord.d.ts +55 -0
- package/dist/volume/feedRecord.js +148 -0
- package/dist/volume/feedRef.d.ts +43 -0
- package/dist/volume/feedRef.js +117 -0
- package/dist/volume/feedRefresh.d.ts +15 -0
- package/dist/volume/feedRefresh.js +187 -0
- package/dist/volume/feedSource.d.ts +66 -0
- package/dist/volume/feedSource.js +104 -0
- package/dist/volume/feedTarget.d.ts +70 -0
- package/dist/volume/feedTarget.js +9 -0
- package/dist/volume/feedTestKit.d.ts +11 -0
- package/dist/volume/feedTestKit.js +45 -0
- package/dist/volume/feedVerify.d.ts +18 -0
- package/dist/volume/feedVerify.js +104 -0
- package/dist/volume/index.d.ts +13 -0
- package/dist/volume/index.js +13 -0
- package/package.json +3 -3
- package/runtimes.yaml +8 -6
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import {
|
|
2
|
+
import { constants } from "node:fs";
|
|
3
|
+
import { copyFile, link, mkdir, readFile, rm, stat, writeFile } from "node:fs/promises";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import { SpawnfileError } from "../shared/index.js";
|
|
5
6
|
// Sanity bound for an operator-declared local tar; integrity comes from its digest, not its size.
|
|
@@ -75,32 +76,80 @@ export const validateWorkspaceBundleTar = (bytes) => {
|
|
|
75
76
|
if (entries === 0)
|
|
76
77
|
fail("Workspace bundle is empty");
|
|
77
78
|
};
|
|
78
|
-
export const
|
|
79
|
-
|
|
79
|
+
export const workspaceBundleContextPath = (outputDirectory, identity) => path.join(outputDirectory, "container/workspace-bundles", `${identity.slice(7)}.tar`);
|
|
80
|
+
/**
|
|
81
|
+
* Hard-links a read-only cached archive into the Docker context (cloning or
|
|
82
|
+
* copying across filesystems). Never writes through an existing name: with
|
|
83
|
+
* `clean: false` it may already be a link into the cache. Returns the staged
|
|
84
|
+
* path, or undefined when the cached archive no longer exists.
|
|
85
|
+
*/
|
|
86
|
+
export const linkBuiltBundle = async (archive, outputDirectory, identity) => {
|
|
87
|
+
const target = workspaceBundleContextPath(outputDirectory, identity);
|
|
88
|
+
await mkdir(path.dirname(target), { recursive: true });
|
|
89
|
+
await rm(target, { force: true });
|
|
90
|
+
try {
|
|
91
|
+
await link(archive, target);
|
|
92
|
+
return target;
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
if (error.code === "ENOENT")
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
try {
|
|
99
|
+
await copyFile(archive, target, constants.COPYFILE_FICLONE);
|
|
100
|
+
return target;
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
if (error.code === "ENOENT")
|
|
104
|
+
return undefined;
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* Completes the bundle archives in the Docker context. Built bundles were
|
|
110
|
+
* already linked by `resolveWorkspaceBundles` (`built` maps their digests to
|
|
111
|
+
* the staged path). Every `source` tar is hashed, validated and staged from
|
|
112
|
+
* the exact bytes that were verified, even when a built bundle shares its
|
|
113
|
+
* digest; distinct source paths with identical bytes stage once.
|
|
114
|
+
*/
|
|
115
|
+
export const stageWorkspaceBundles = async (outputDirectory, plan, built = new Map()) => {
|
|
116
|
+
const sources = new Map();
|
|
117
|
+
let any = false;
|
|
80
118
|
for (const node of plan.nodes)
|
|
81
119
|
if (node.kind === "agent")
|
|
82
120
|
for (const resource of node.value.workspaceResources ?? []) {
|
|
83
121
|
if (resource.kind !== "bundle")
|
|
84
122
|
continue;
|
|
85
|
-
|
|
86
|
-
if (
|
|
87
|
-
throw new SpawnfileError("
|
|
88
|
-
|
|
123
|
+
any = true;
|
|
124
|
+
if (resource.sha256 === undefined || (resource.source === undefined && !built.has(resource.sha256))) {
|
|
125
|
+
throw new SpawnfileError("compile_error", `Workspace bundle ${resource.id} has not been built`);
|
|
126
|
+
}
|
|
127
|
+
if (resource.source === undefined)
|
|
128
|
+
continue;
|
|
129
|
+
const paths = sources.get(resource.sha256) ?? new Set();
|
|
130
|
+
paths.add(path.resolve(path.dirname(resource.scope.key), resource.source));
|
|
131
|
+
sources.set(resource.sha256, paths);
|
|
89
132
|
}
|
|
90
|
-
if (
|
|
133
|
+
if (!any)
|
|
91
134
|
return false;
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
135
|
+
await mkdir(path.join(outputDirectory, "container/workspace-bundles"), { recursive: true });
|
|
136
|
+
for (const [identity, paths] of sources) {
|
|
137
|
+
let verified;
|
|
138
|
+
for (const source of paths) {
|
|
139
|
+
const info = await stat(source);
|
|
140
|
+
if (!info.isFile() || info.size < 1 || info.size > CAP)
|
|
141
|
+
throw new SpawnfileError("validation_error", "Workspace bundle must be a bounded regular tar file");
|
|
142
|
+
const bytes = await readFile(source);
|
|
143
|
+
const actual = `sha256:${createHash("sha256").update(bytes).digest("hex")}`;
|
|
144
|
+
if (actual !== identity)
|
|
145
|
+
throw new SpawnfileError("validation_error", "Workspace bundle checksum mismatch");
|
|
146
|
+
validateWorkspaceBundleTar(bytes);
|
|
147
|
+
verified ??= bytes;
|
|
148
|
+
}
|
|
149
|
+
// Replace by unlinking first: the name may be a hard link into the bundle cache.
|
|
150
|
+
const target = workspaceBundleContextPath(outputDirectory, identity);
|
|
151
|
+
await rm(target, { force: true });
|
|
152
|
+
await writeFile(target, verified);
|
|
104
153
|
}
|
|
105
154
|
return true;
|
|
106
155
|
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { BundleTarSummary } from "./workspaceBundleTar.js";
|
|
2
|
+
/** Built archives kept per cache directory; the least recently used beyond this are pruned. */
|
|
3
|
+
export declare const WORKSPACE_BUNDLE_CACHE_LIMIT = 24;
|
|
4
|
+
export interface CachedBundle extends BundleTarSummary {
|
|
5
|
+
key: string;
|
|
6
|
+
tarPath: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const resolveWorkspaceBundleCacheDirectory: (override?: string) => string;
|
|
9
|
+
/**
|
|
10
|
+
* A hit is a record whose archive still has the size, inode and mtime it had
|
|
11
|
+
* when it was written. Anything else — a missing, replaced or edited archive,
|
|
12
|
+
* an unreadable record — is a miss and the archive is rebuilt.
|
|
13
|
+
*/
|
|
14
|
+
export declare const lookupCachedBundle: (directory: string, key: string) => Promise<CachedBundle | undefined>;
|
|
15
|
+
/** Builds into a private temporary file, validates it, then publishes archive and record by atomic rename. */
|
|
16
|
+
export declare const storeBuiltBundle: (directory: string, key: string, build: (temporaryPath: string) => Promise<BundleTarSummary>) => Promise<CachedBundle>;
|
|
17
|
+
/** An archive used this recently may belong to a concurrent compile that has not staged it yet. */
|
|
18
|
+
export declare const WORKSPACE_BUNDLE_CACHE_GRACE_MS = 3600000;
|
|
19
|
+
/**
|
|
20
|
+
* Removes the least recently used archives beyond the limit. Never removes
|
|
21
|
+
* one this compile uses, nor one any compile used within the grace period.
|
|
22
|
+
*/
|
|
23
|
+
export declare const pruneBundleCache: (directory: string, keep: ReadonlySet<string>, limit?: number, now?: number) => Promise<void>;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { chmod, mkdir, readdir, readFile, rename, rm, stat, utimes, writeFile } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { resolveSpawnfileHome } from "../auth/paths.js";
|
|
5
|
+
import { validateWorkspaceBundleTar } from "./workspaceBundleArtifacts.js";
|
|
6
|
+
const RECORD_VERSION = "spawnfile.workspace-bundle-cache.v1";
|
|
7
|
+
/** Built archives kept per cache directory; the least recently used beyond this are pruned. */
|
|
8
|
+
export const WORKSPACE_BUNDLE_CACHE_LIMIT = 24;
|
|
9
|
+
export const resolveWorkspaceBundleCacheDirectory = (override) => override ?? path.join(resolveSpawnfileHome(), "cache", "workspace-bundles");
|
|
10
|
+
const paths = (directory, key) => ({ record: path.join(directory, `${key}.json`), tar: path.join(directory, `${key}.tar`) });
|
|
11
|
+
/**
|
|
12
|
+
* Archives are named by key AND digest: two concurrent builds of one key that
|
|
13
|
+
* produce different bytes publish two files, and each record names the file
|
|
14
|
+
* its digest describes, so a record can never pair one digest with another's bytes.
|
|
15
|
+
*/
|
|
16
|
+
const archiveName = (key, sha256) => `${key}.${sha256.slice(7)}.tar`;
|
|
17
|
+
/**
|
|
18
|
+
* A hit is a record whose archive still has the size, inode and mtime it had
|
|
19
|
+
* when it was written. Anything else — a missing, replaced or edited archive,
|
|
20
|
+
* an unreadable record — is a miss and the archive is rebuilt.
|
|
21
|
+
*/
|
|
22
|
+
export const lookupCachedBundle = async (directory, key) => {
|
|
23
|
+
const location = paths(directory, key);
|
|
24
|
+
try {
|
|
25
|
+
const record = JSON.parse(await readFile(location.record, "utf8"));
|
|
26
|
+
if (typeof record.sha256 !== "string" || !/^sha256:[a-f0-9]{64}$/u.test(record.sha256))
|
|
27
|
+
return undefined;
|
|
28
|
+
const tarPath = path.join(directory, archiveName(key, record.sha256));
|
|
29
|
+
const info = await stat(tarPath);
|
|
30
|
+
if (record.version !== RECORD_VERSION || record.key !== key || !info.isFile() || (info.mode & 0o222) !== 0 || info.size !== record.size || info.ino !== record.ino || info.mtimeMs !== record.mtimeMs)
|
|
31
|
+
return undefined;
|
|
32
|
+
const now = new Date();
|
|
33
|
+
await utimes(location.record, now, now).catch(() => undefined);
|
|
34
|
+
return { contentBytes: record.contentBytes, fileCount: record.fileCount, key, sha256: record.sha256, size: record.size, tarPath };
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
/** Builds into a private temporary file, validates it, then publishes archive and record by atomic rename. */
|
|
41
|
+
export const storeBuiltBundle = async (directory, key, build) => {
|
|
42
|
+
await mkdir(directory, { mode: 0o700, recursive: true });
|
|
43
|
+
const location = paths(directory, key), suffix = `${process.pid}.${randomBytes(6).toString("hex")}.tmp`;
|
|
44
|
+
const temporaryTar = `${location.tar}.${suffix}`, temporaryRecord = `${location.record}.${suffix}`;
|
|
45
|
+
try {
|
|
46
|
+
const summary = await build(temporaryTar);
|
|
47
|
+
validateWorkspaceBundleTar(await readFile(temporaryTar));
|
|
48
|
+
// Read-only: staging hard-links this inode into build contexts, which must never write through to it.
|
|
49
|
+
await chmod(temporaryTar, 0o444);
|
|
50
|
+
const tarPath = path.join(directory, archiveName(key, summary.sha256));
|
|
51
|
+
await rename(temporaryTar, tarPath);
|
|
52
|
+
const info = await stat(tarPath);
|
|
53
|
+
const record = { ...summary, ino: info.ino, key, mtimeMs: info.mtimeMs, version: RECORD_VERSION };
|
|
54
|
+
await writeFile(temporaryRecord, `${JSON.stringify(record)}\n`, { mode: 0o600 });
|
|
55
|
+
await rename(temporaryRecord, location.record);
|
|
56
|
+
return { ...summary, key, tarPath };
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
await rm(temporaryTar, { force: true });
|
|
60
|
+
await rm(temporaryRecord, { force: true });
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
/** An archive used this recently may belong to a concurrent compile that has not staged it yet. */
|
|
64
|
+
export const WORKSPACE_BUNDLE_CACHE_GRACE_MS = 3_600_000;
|
|
65
|
+
/**
|
|
66
|
+
* Removes the least recently used archives beyond the limit. Never removes
|
|
67
|
+
* one this compile uses, nor one any compile used within the grace period.
|
|
68
|
+
*/
|
|
69
|
+
export const pruneBundleCache = async (directory, keep, limit = WORKSPACE_BUNDLE_CACHE_LIMIT, now = Date.now()) => {
|
|
70
|
+
const names = await readdir(directory).catch(() => []);
|
|
71
|
+
const records = await Promise.all(names.filter((name) => /^[a-f0-9]{64}\.json$/u.test(name)).map(async (name) => ({
|
|
72
|
+
key: name.slice(0, 64), used: (await stat(path.join(directory, name)).catch(() => undefined))?.mtimeMs ?? 0
|
|
73
|
+
})));
|
|
74
|
+
const stale = records.sort((left, right) => right.used - left.used).slice(limit).filter((record) => !keep.has(record.key) && now - record.used > WORKSPACE_BUNDLE_CACHE_GRACE_MS);
|
|
75
|
+
await Promise.all(stale.flatMap((record) => [
|
|
76
|
+
rm(path.join(directory, `${record.key}.json`), { force: true }),
|
|
77
|
+
...names.filter((name) => name.startsWith(`${record.key}.`) && name.endsWith(".tar")).map((name) => rm(path.join(directory, name), { force: true }))
|
|
78
|
+
]));
|
|
79
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { WorkspaceBundleBuild } from "../manifest/index.js";
|
|
2
|
+
import { type BundleBuildContext, type BundleBuildPlan } from "./workspaceBundleKey.js";
|
|
3
|
+
type DependenciesSpec = NonNullable<WorkspaceBundleBuild["dependencies"]>;
|
|
4
|
+
/**
|
|
5
|
+
* The lockfile is the whole dependency identity, so it must describe exactly
|
|
6
|
+
* what package.json asks for: a modern npm lock (v2+) whose root entry
|
|
7
|
+
* declares the same dependency sets, with no linked (workspace or file:)
|
|
8
|
+
* packages that would reach outside the install directory.
|
|
9
|
+
*/
|
|
10
|
+
export declare const assertNpmLockMatchesManifest: (manifestBytes: Buffer, lockBytes: Buffer, directory: string) => void;
|
|
11
|
+
/**
|
|
12
|
+
* `dependencies`: package.json + package-lock.json installed with `npm ci` in
|
|
13
|
+
* a digest-pinned image on the TARGET platform, so native packages and
|
|
14
|
+
* platform-specific optional dependencies match the container, never the host.
|
|
15
|
+
* The key is the lockfile, the manifest, the install recipe (manager, flags,
|
|
16
|
+
* check command, pinned image = tool versions) and the platform; installs run
|
|
17
|
+
* only on a cache miss. The archive holds the installed `node_modules` tree;
|
|
18
|
+
* `.bin` symlinks and npm's hidden lockfile are left out.
|
|
19
|
+
*/
|
|
20
|
+
export declare const planDependenciesBundle: (spec: DependenciesSpec, context: BundleBuildContext) => Promise<BundleBuildPlan>;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { copyFile, lstat, mkdir, mkdtemp, readFile, rm } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { SpawnfileError } from "../shared/index.js";
|
|
5
|
+
import { assertCommittedInputs, resolveBundleRoot, writeBundleFiles } from "./workspaceBundleFiles.js";
|
|
6
|
+
import { computeRecipeBundleKey } from "./workspaceBundleKey.js";
|
|
7
|
+
import { bundleContainerName, runContainerStep } from "./workspaceBundleRun.js";
|
|
8
|
+
import { walkBuiltTree } from "./workspaceBundleTree.js";
|
|
9
|
+
const MANIFEST_LIMIT = 67_108_864;
|
|
10
|
+
const INSTALL_TIMEOUT_MS = 1_800_000;
|
|
11
|
+
const DEPENDENCY_FIELDS = ["dependencies", "devDependencies", "optionalDependencies"];
|
|
12
|
+
const fail = (message) => {
|
|
13
|
+
throw new SpawnfileError("validation_error", message);
|
|
14
|
+
};
|
|
15
|
+
const sha256 = (bytes) => `sha256:${createHash("sha256").update(bytes).digest("hex")}`;
|
|
16
|
+
const stable = (value) => JSON.stringify(value, (_key, item) => item && typeof item === "object" && !Array.isArray(item) ? Object.fromEntries(Object.entries(item).sort(([left], [right]) => left.localeCompare(right))) : item);
|
|
17
|
+
const readManifest = async (directory, name) => {
|
|
18
|
+
const file = path.join(directory, name), info = await lstat(file).catch(() => undefined);
|
|
19
|
+
if (!info?.isFile() || info.size > MANIFEST_LIMIT)
|
|
20
|
+
fail(`Dependency bundle needs a regular ${name} in ${directory}`);
|
|
21
|
+
return readFile(file);
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* The lockfile is the whole dependency identity, so it must describe exactly
|
|
25
|
+
* what package.json asks for: a modern npm lock (v2+) whose root entry
|
|
26
|
+
* declares the same dependency sets, with no linked (workspace or file:)
|
|
27
|
+
* packages that would reach outside the install directory.
|
|
28
|
+
*/
|
|
29
|
+
export const assertNpmLockMatchesManifest = (manifestBytes, lockBytes, directory) => {
|
|
30
|
+
const parse = (bytes, name) => {
|
|
31
|
+
try {
|
|
32
|
+
return JSON.parse(bytes.toString("utf8"));
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return fail(`Dependency bundle ${name} is not valid JSON in ${directory}`);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const manifest = parse(manifestBytes, "package.json"), lock = parse(lockBytes, "package-lock.json");
|
|
39
|
+
const packages = lock.packages;
|
|
40
|
+
if (typeof lock.lockfileVersion !== "number" || lock.lockfileVersion < 2 || !packages?.[""])
|
|
41
|
+
fail(`Dependency bundle needs an npm lockfile v2 or later in ${directory}`);
|
|
42
|
+
for (const field of DEPENDENCY_FIELDS) {
|
|
43
|
+
if (stable(manifest[field] ?? {}) !== stable(packages[""][field] ?? {}))
|
|
44
|
+
fail(`Dependency bundle package.json ${field} differs from package-lock.json in ${directory}; run npm install`);
|
|
45
|
+
}
|
|
46
|
+
for (const [location, entry] of Object.entries(packages)) {
|
|
47
|
+
if (!location)
|
|
48
|
+
continue;
|
|
49
|
+
if (entry.link === true || !location.startsWith("node_modules/") || location.split("/").includes("..")) {
|
|
50
|
+
fail(`Dependency bundle lock entry ${location} is linked or outside node_modules; only registry installs are archived`);
|
|
51
|
+
}
|
|
52
|
+
// A cold install must fetch exactly what the key names: every fetched package needs content
|
|
53
|
+
// integrity, or a git source pinned to a full commit. Bundled packages ship inside their parent.
|
|
54
|
+
if (entry.inBundle === true)
|
|
55
|
+
continue;
|
|
56
|
+
const resolved = typeof entry.resolved === "string" ? entry.resolved : "";
|
|
57
|
+
const pinnedGit = /^git\+.+#[a-f0-9]{40}$/u.test(resolved);
|
|
58
|
+
if (!pinnedGit && !validIntegrity(entry.integrity)) {
|
|
59
|
+
fail(`Dependency bundle lock entry ${location} has no content integrity; its download is not pinned by the lockfile`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
// Base64 lengths of each SRI algorithm npm verifies; a token npm would parse as empty is not integrity.
|
|
64
|
+
const SRI_LENGTHS = { sha1: 28, sha256: 44, sha384: 64, sha512: 88 };
|
|
65
|
+
const validIntegrity = (value) => typeof value === "string" && value.trim() !== "" &&
|
|
66
|
+
value.trim().split(/\s+/u).every((token) => {
|
|
67
|
+
const match = /^(sha1|sha256|sha384|sha512)-([A-Za-z0-9+/]+={0,2})$/u.exec(token);
|
|
68
|
+
return match !== null && match[2].length === SRI_LENGTHS[match[1]];
|
|
69
|
+
});
|
|
70
|
+
const inNodeModules = (relativePath) => relativePath === "node_modules" || relativePath.startsWith("node_modules/");
|
|
71
|
+
/**
|
|
72
|
+
* `dependencies`: package.json + package-lock.json installed with `npm ci` in
|
|
73
|
+
* a digest-pinned image on the TARGET platform, so native packages and
|
|
74
|
+
* platform-specific optional dependencies match the container, never the host.
|
|
75
|
+
* The key is the lockfile, the manifest, the install recipe (manager, flags,
|
|
76
|
+
* check command, pinned image = tool versions) and the platform; installs run
|
|
77
|
+
* only on a cache miss. The archive holds the installed `node_modules` tree;
|
|
78
|
+
* `.bin` symlinks and npm's hidden lockfile are left out.
|
|
79
|
+
*/
|
|
80
|
+
export const planDependenciesBundle = async (spec, context) => {
|
|
81
|
+
const directory = await resolveBundleRoot(spec.directory);
|
|
82
|
+
// A release build installs exactly the committed manifests.
|
|
83
|
+
if (context.identity === "release")
|
|
84
|
+
await assertCommittedInputs(directory, ["package.json", "package-lock.json"]);
|
|
85
|
+
const [manifestBytes, lockBytes] = await Promise.all([readManifest(directory, "package.json"), readManifest(directory, "package-lock.json")]);
|
|
86
|
+
assertNpmLockMatchesManifest(manifestBytes, lockBytes, directory);
|
|
87
|
+
const dev = spec.dev ?? false, scripts = spec.scripts ?? true;
|
|
88
|
+
const recipe = {
|
|
89
|
+
check: spec.check ?? null, dev, image: spec.image, lock: sha256(lockBytes), manager: "npm", manifest: sha256(manifestBytes), scripts
|
|
90
|
+
};
|
|
91
|
+
return {
|
|
92
|
+
input: "dependencies",
|
|
93
|
+
key: computeRecipeBundleKey("dependencies", recipe, context.platform),
|
|
94
|
+
write: async (temporaryTar) => {
|
|
95
|
+
await mkdir(context.workRoot, { mode: 0o700, recursive: true });
|
|
96
|
+
const work = await mkdtemp(path.join(context.workRoot, "dependencies-"));
|
|
97
|
+
try {
|
|
98
|
+
await copyFile(path.join(directory, "package.json"), path.join(work, "package.json"));
|
|
99
|
+
await copyFile(path.join(directory, "package-lock.json"), path.join(work, "package-lock.json"));
|
|
100
|
+
if (sha256(await readFile(path.join(work, "package-lock.json"))) !== recipe.lock || sha256(await readFile(path.join(work, "package.json"))) !== recipe.manifest) {
|
|
101
|
+
fail(`Dependency bundle manifests changed while the bundle was built: ${directory}`);
|
|
102
|
+
}
|
|
103
|
+
const step = (argv, label) => runContainerStep({
|
|
104
|
+
argv, dockerCommand: context.dockerCommand, env: { npm_config_cache: "/tmp/spawnfile-home/.npm", npm_config_update_notifier: "false" },
|
|
105
|
+
image: spec.image, mounts: [[work, "/spawnfile/install"]], name: bundleContainerName(), platform: context.platform, workdir: "/spawnfile/install"
|
|
106
|
+
}, INSTALL_TIMEOUT_MS, label, work);
|
|
107
|
+
const install = ["npm", "ci", "--no-audit", "--no-fund", dev ? "--include=dev" : "--omit=dev", ...(scripts ? [] : ["--ignore-scripts"])];
|
|
108
|
+
await step(install, `Dependency install for ${directory}`);
|
|
109
|
+
if (spec.check)
|
|
110
|
+
await step(spec.check, `Dependency check for ${directory}`);
|
|
111
|
+
const input = await walkBuiltTree(work, {
|
|
112
|
+
dropSymlink: (relativePath) => /(^|\/)\.bin\/[^/]+$/u.test(relativePath),
|
|
113
|
+
skip: (relativePath) => !inNodeModules(relativePath) || relativePath === "node_modules/.package-lock.json"
|
|
114
|
+
});
|
|
115
|
+
return await writeBundleFiles(input, temporaryTar);
|
|
116
|
+
}
|
|
117
|
+
finally {
|
|
118
|
+
await rm(work, { force: true, recursive: true });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { type BundleFileMode, type BundleTarSummary } from "./workspaceBundleTar.js";
|
|
2
|
+
export type BundleIdentityMode = "dev" | "release";
|
|
3
|
+
/** One archived file. `identity` is a git object id (`git:`, content read from the object store) or a content digest (`sha256:`, read from disk). */
|
|
4
|
+
export interface BundleFileEntry {
|
|
5
|
+
identity: string;
|
|
6
|
+
mode: BundleFileMode;
|
|
7
|
+
objectId?: string;
|
|
8
|
+
path: string;
|
|
9
|
+
}
|
|
10
|
+
export interface BundleFilesInput {
|
|
11
|
+
directory: string;
|
|
12
|
+
entries: BundleFileEntry[];
|
|
13
|
+
mode: BundleIdentityMode;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Exclude patterns match the path relative to the bundle root: `*` and `?`
|
|
17
|
+
* stay inside one segment, `**` crosses segments, and a pattern that matches
|
|
18
|
+
* a directory excludes everything beneath it.
|
|
19
|
+
*/
|
|
20
|
+
export declare const compileExcludePatterns: (patterns?: readonly string[]) => ((relativePath: string) => boolean);
|
|
21
|
+
export declare const resolveBundleRoot: (directory: string) => Promise<string>;
|
|
22
|
+
/**
|
|
23
|
+
* Release identity: the root must be clean against HEAD (ignoring excluded
|
|
24
|
+
* paths), and the identity is the committed tree's blob ids and modes. No
|
|
25
|
+
* input file is read.
|
|
26
|
+
*/
|
|
27
|
+
export declare const resolveReleaseFiles: (directory: string, exclude?: readonly string[]) => Promise<BundleFilesInput>;
|
|
28
|
+
/**
|
|
29
|
+
* Release rule for recipe inputs that are named files rather than a tree:
|
|
30
|
+
* each must be tracked at HEAD with no staged, unstaged or untracked change.
|
|
31
|
+
*/
|
|
32
|
+
export declare const assertCommittedInputs: (directory: string, names: readonly string[]) => Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* A pinned revision: identity and bytes come from the tree of `ref` (resolved
|
|
35
|
+
* to a commit once), so the work tree's state is irrelevant and no clean
|
|
36
|
+
* checkout is needed. The same in dev and release compiles.
|
|
37
|
+
*/
|
|
38
|
+
export declare const resolveCommittedFiles: (directory: string, ref: string, exclude?: readonly string[]) => Promise<BundleFilesInput>;
|
|
39
|
+
/**
|
|
40
|
+
* Dev identity: the working tree as it is now. Files git reports as unchanged
|
|
41
|
+
* keep their index blob id; modified and untracked (not ignored) files are
|
|
42
|
+
* hashed from disk, so an uncommitted edit or a new file always moves the key.
|
|
43
|
+
*/
|
|
44
|
+
export declare const resolveDevFiles: (directory: string, exclude?: readonly string[]) => Promise<BundleFilesInput>;
|
|
45
|
+
/**
|
|
46
|
+
* Writes the archive for a resolved input set. Every `git:` entry is read from
|
|
47
|
+
* the object store, so its bytes are exactly the blob its identity names;
|
|
48
|
+
* every `sha256:` entry is read from disk and re-checked against its digest.
|
|
49
|
+
* The archive is therefore a pure function of the cache key.
|
|
50
|
+
*/
|
|
51
|
+
export declare const writeBundleFiles: (input: BundleFilesInput, outputPath: string) => Promise<BundleTarSummary>;
|