@odla-ai/harness 0.11.10 → 0.11.12

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/node.d.cts CHANGED
@@ -596,6 +596,15 @@ interface CodeToolBrokerOptions {
596
596
  onDecision?(decision: CodeToolDecision): Promise<void> | void;
597
597
  }
598
598
 
599
+ /** A host directory (or, for build products, a file) lent into a run's workspace. */
600
+ interface LentDirectory {
601
+ /** Absolute path on the host. */
602
+ source: string;
603
+ /** Workspace-relative path it appears at. A mounted tree's last segment must be a reserved name. */
604
+ mountAs: string;
605
+ /** The workspace package it belongs to. A workspace without that directory does not receive the entry. */
606
+ within?: string;
607
+ }
599
608
  /**
600
609
  * An installed dependency tree lent to a recipe for the length of one run.
601
610
  *
@@ -608,7 +617,27 @@ interface RecipeDependencies {
608
617
  /** Where it appears inside the workspace. Must be a reserved name, so the
609
618
  * agent still cannot address it. */
610
619
  mountAs?: string;
611
- }
620
+ /** Workspace packages whose own `node_modules` the install produced (a
621
+ * version the root tree could not hoist), each lent at its own path. */
622
+ nested?: LentDirectory[];
623
+ /** The host's build output per workspace package, copied into the run's
624
+ * workspace wherever it has none, so a test can import a sibling package
625
+ * the way npm resolves it: through its `dist`. */
626
+ products?: LentDirectory[];
627
+ /** When set, every run gets its own copy-on-write clone of the tree under
628
+ * this directory and mounts it writable. vite and vitest write caches and
629
+ * bundled configs into `node_modules` and refuse a read-only one. */
630
+ runsDir?: string;
631
+ /** True only on the per-run clone `lendDependencies` makes. The shared tree
632
+ * is never mounted writable. */
633
+ writable?: boolean;
634
+ }
635
+ /** Refuse a lent path that leaves the workspace. */
636
+ declare function assertLentPath(mountAs: string): void;
637
+ /** Refuse any mounted tree the agent could address: inside the workspace, and ending in a reserved name. */
638
+ declare function assertReservedMount(mountAs: string): void;
639
+ /** Every directory a dependency set lends: the root tree first, then each nested one. */
640
+ declare function lentDirectories(dependencies: RecipeDependencies): LentDirectory[];
612
641
  /**
613
642
  * Wrap an executor so `dependencies.source` is present during each recipe run.
614
643
  *
@@ -710,8 +739,9 @@ interface TheseusRuntimeEngineOptions {
710
739
  /** Injectable agent attempt. Defaults to runAgent over the brokered surface. */
711
740
  runAgentAttempt?: (options: CodeAgentAttemptOptions) => Promise<CodeAgentAttemptResult>;
712
741
  recipeExecutor?: CodeRecipeExecutor;
713
- /** The host's installed dependency tree, lent read-only to every recipe
714
- * container so a real test runner can be a proof in an offline sandbox. */
742
+ /** The host's prepared dependency tree, lent to every recipe container (as
743
+ * the run's own writable clone when the set allows one) so a real test
744
+ * runner can be a proof in an offline sandbox. */
715
745
  recipeDependencies?: RecipeDependencies | null;
716
746
  /** Owner-visible and terminal-visible bounded runtime failures. */
717
747
  onDiagnostic?: (message: string) => void;
@@ -1616,10 +1646,10 @@ declare const DEPENDENCY_INSTALL_TIMEOUT_MS: number;
1616
1646
  /** What preparing a tree needs: the engine and pinned image, the repository, and the cache root; `run` is injectable for tests. */
1617
1647
  interface DependencyCacheInput {
1618
1648
  engine: ContainerEngine;
1619
- /** The pinned recipe image; its node and npm install the tree. */
1649
+ /** The pinned recipe image; its node installs the tree. */
1620
1650
  image: string;
1621
1651
  repoRoot: string;
1622
- /** Where trees live: `<cacheRoot>/<key>/node_modules`. */
1652
+ /** Where trees live: `<cacheRoot>/<key>/tree/node_modules`, with per-run clones under `<cacheRoot>/<key>/runs`. */
1623
1653
  cacheRoot: string;
1624
1654
  run?: (engine: ContainerEngine, args: string[], name: string, limits: {
1625
1655
  timeoutMs: number;
@@ -1627,15 +1657,24 @@ interface DependencyCacheInput {
1627
1657
  }) => Promise<CodeRecipeResult>;
1628
1658
  log?: (line: string) => void;
1629
1659
  }
1630
- /** The cache key: the lockfile's bytes, the image, and the architecture the container runs. Null without a lockfile. */
1631
- declare function dependencyCacheKey(repoRoot: string, image: string, arch?: NodeJS.Architecture): Promise<string | null>;
1660
+ /** The npm the repository generates its lockfile with: an exact `engines.npm`, or null when it pins none. */
1661
+ declare function pinnedNpmVersion(repoRoot: string): Promise<string | null>;
1662
+ /** The cache key: the lockfile's bytes, the image, the architecture the container runs, and the npm that installs. Null without a lockfile. */
1663
+ declare function dependencyCacheKey(repoRoot: string, image: string, arch?: NodeJS.Architecture, npmVersion?: string | null): Promise<string | null>;
1664
+ /** Every workspace directory the root manifest declares that has a package.json, repository-relative, in declaration order. */
1665
+ declare function workspaceDirs(repoRoot: string): Promise<string[]>;
1632
1666
  /** Copy only what npm ci needs: the root manifests and every workspace's package.json. Returns what was staged. */
1633
1667
  declare function stageManifests(repoRoot: string, stageDir: string): Promise<string[]>;
1634
- /** The helper's command: networked, writable stage, scripts disabled, nothing else of the host mounted. */
1635
- declare function dependencyInstallArgs(engine: ContainerEngine, image: string, stageDir: string, name: string): string[];
1668
+ /** The helper's command: networked, writable stage, scripts disabled, nothing else of the host mounted; the repository's npm when it pins one. */
1669
+ declare function dependencyInstallArgs(engine: ContainerEngine, image: string, stageDir: string, name: string, npmVersion?: string | null): string[];
1670
+ /** The lines of an npm failure worth reading: from `npm error code` on, never the usage boilerplate npm ends with. */
1671
+ declare function npmFailureSummary(stderr: string): string;
1636
1672
  /** The tree for this repository's lockfile, from the cache or freshly installed; null when there is no lockfile or the install failed. */
1637
1673
  declare function prepareContainerDependencies(input: DependencyCacheInput): Promise<RecipeDependencies | null>;
1638
1674
 
1675
+ /** The host checkout's build output to lend into a run's workspace: each package's `dist`, then every ignored file the policy allows. */
1676
+ declare function hostBuildProducts(repoRoot: string): Promise<LentDirectory[]>;
1677
+
1639
1678
  /** Every ordinary, policy-legal source path under `root`, sorted. */
1640
1679
  declare function registeredFiles(root: string, limit?: number): Promise<string[]>;
1641
1680
 
@@ -1653,4 +1692,17 @@ declare function runContainerCommand(engine: ContainerEngine, args: string[], na
1653
1692
  maxOutputBytes: number;
1654
1693
  }, signal?: AbortSignal): Promise<CodeRecipeResult>;
1655
1694
 
1656
- export { CODE_PATCH_PATH, CODE_RUNTIME_PROTOCOL_VERSION, type CodeAgentAttemptOptions, type CodeAgentAttemptResult, type CodeAgentRun, type CodeBuildRecipe, type CodeExpectedArtifact, type CodeLocalSourceDescriptor, type CodeMemory, type CodeMemoryEvidence, type CodeMemoryKind, type CodeMemoryStore, type CodeRecipeExecutor, type CodeRecipeResult, type CodeRuntimeAgentControlPlane, type CodeRuntimeBinding, type CodeRuntimeCandidateResponse, type CodeRuntimeCapabilities, CodeRuntimeCheckpointManager, type CodeRuntimeClientOptions, type CodeRuntimeCollaborationSkillManifest, type CodeRuntimeCollaborationToolManifest, type CodeRuntimeCollaborationToolRequest, type CodeRuntimeCommand, type CodeRuntimeCommandEngine, type CodeRuntimeCommandKind, type CodeRuntimeCommandResult, CodeRuntimeControlError, type CodeRuntimeControlPlane, type CodeRuntimeInferenceOptions, type CodeRuntimeLoopOptions, type CodeRuntimeMemory, type CodeRuntimeNewMemory, CodeRuntimeReconciler, type CodeRuntimeReviewRequest, type CodeRuntimeReviewResponse, type CodeRuntimeSnapshot, type CodeRuntimeSourceArchive, type CodeRuntimeSourceSnapshot, type CodeSkillOpts, type CodeSurface, type CodeToolBrokerOptions, type CodeToolCallRecord, type CodeToolDecision, type CodeVerificationEvidence, type CodeVerificationLog, type CodeVerificationPolicy, type ContainerEngine, type ContainerEngineSelectionOptions, type ContainerEngineVerificationOptions, type ContainerLimits, type ContainerRunOptions, type ContainerRunResult, type CreateCodeWorkspaceCheckpointInput, DEPENDENCY_INSTALL_TIMEOUT_MS, type DecomposedRun, DecompositionError, type DependencyCacheInput, type GoalAttempt, type GoalAttemptInput, type GoalAttemptOutcome, type GoalAttemptRecord, type GoalBudget, type GoalEvent, type GoalOutcome, type GoalRun, type GoalRunSpec, type GoalStoppedReason, type GoalStrategy, type HarnessRunnerOptions, type IntegrateOptions, type IntegrationStep, MAX_MEMORY_BODY, MEASURED_PREMIUM, type MaterializedCodeSource, type MaterializedGitTree, type NewCodeMemory, PROOF_RECIPE_PREFIX, type PrepareRuntimeCheckpointInput, type PreparedRuntimeCheckpoint, REPOSITORY_RECIPES_FILE, type RacedAttemptOptions, type RacedOutcome, type RecallOptions, type RecipeDependencies, type RepositoryRecipeEnvelope, type ResolvedCodeRecipes, type RestoreCodeWorkspaceCheckpointInput, type RestoredCodeWorkspaceCheckpoint, type RunCodeAgentOptions, type RuntimeCheckpointSession, SYSTEM_PROMPT_FOR, type StageWorkspaceOptions, type StagedWorkspace, type StrategyChoice, type StrategySignals, type SubGoal, type SubGoalResult, TheseusRuntimeEngine, type TheseusRuntimeEngineOptions, V1_SYSTEM_PROMPT, V2_SYSTEM_PROMPT, V3_SYSTEM_PROMPT, type VerifyCodeCandidateInput, applyCodePatch, applyPatchDialectToDiff, assertCodeBuildRecipe, assertDisjointPlan, assertPinnedImage, attachCodeRuntimeReferences, buildContainerRunArgs, buildRecipeContainerArgs, chooseStrategy, codeSkill, createCodeRuntimeControlClient, createCodeRuntimeInference, createCodeRuntimeSessionSkillLoader, createCodeToolBroker, createCodeWorkspaceCheckpoint, createContainerRecipeExecutor, dependencyCacheKey, dependencyInstallArgs, describeCodeRecipes, describeGateFailure, describePatchFailure, digestStagedWorkspace, feedbackIsActionable, hasContextFreeHunk, hazardFromAttempt, installedDependencies, integrateSubGoals, isCheckpointEffectCompleted, materializeCodeRuntimeArchive, materializeCodeRuntimeSource, materializeCommandWorkspace, materializeGitTree, outcomeCloses, outcomeMemory, parseRepositoryRecipes, patchPaths, planReachCollisions, prepareContainerDependencies, prepareRuntimeCheckpoint, racedAttempt, readOnlyNotice, readRepositoryRecipes, recallAbout, registeredFiles, renderMemories, renderOutcome, resolveCodePath, resolveCodeRecipes, restoreCodeWorkspaceCheckpoint, runCodeAgent, runCodeAgentAttempt, runCodeRuntimeHeartbeatLoop, runContainerAttempt, runContainerCommand, runGoal, runHarnessRunner, runLeasedAttempt, runtimeMemoryStore, safeWorkspaceLabel, selectContainerEngine, selectWinner, sessionRecipesFor, sessionSkillsFor, stageManifests, stageWorkspace, stageWorkspacePair, straySubGoalFiles, stripPatchEnvelope, validateCodePatch, validateMemory, validateRelativePath, verifyCodeCandidate, verifyContainerEngineBoundary, withProofRecipes, withRecipeDependencies };
1695
+ /** A dependency set lent to one run, and how to give it back. */
1696
+ interface LentDependencies {
1697
+ dependencies: RecipeDependencies | null;
1698
+ /** Remove the run's clone. A no-op when nothing was cloned. */
1699
+ release(): Promise<void>;
1700
+ }
1701
+ /** Clone a directory tree, sharing blocks with the original where the filesystem can and copying otherwise. */
1702
+ declare function cloneTree(source: string, target: string, platform?: NodeJS.Platform): Promise<void>;
1703
+ /** Give one run its own writable clone of the tree when the set allows it; otherwise lend the set as it is, read-only. */
1704
+ declare function lendDependencies(dependencies: RecipeDependencies | null, runId: string): Promise<LentDependencies>;
1705
+ /** Copy the host's build output into the workspace wherever its package exists there and it has no copy of its own. Returns what was lent. */
1706
+ declare function lendBuildProducts(products: readonly LentDirectory[], workspaceDir: string): Promise<string[]>;
1707
+
1708
+ export { CODE_PATCH_PATH, CODE_RUNTIME_PROTOCOL_VERSION, type CodeAgentAttemptOptions, type CodeAgentAttemptResult, type CodeAgentRun, type CodeBuildRecipe, type CodeExpectedArtifact, type CodeLocalSourceDescriptor, type CodeMemory, type CodeMemoryEvidence, type CodeMemoryKind, type CodeMemoryStore, type CodeRecipeExecutor, type CodeRecipeResult, type CodeRuntimeAgentControlPlane, type CodeRuntimeBinding, type CodeRuntimeCandidateResponse, type CodeRuntimeCapabilities, CodeRuntimeCheckpointManager, type CodeRuntimeClientOptions, type CodeRuntimeCollaborationSkillManifest, type CodeRuntimeCollaborationToolManifest, type CodeRuntimeCollaborationToolRequest, type CodeRuntimeCommand, type CodeRuntimeCommandEngine, type CodeRuntimeCommandKind, type CodeRuntimeCommandResult, CodeRuntimeControlError, type CodeRuntimeControlPlane, type CodeRuntimeInferenceOptions, type CodeRuntimeLoopOptions, type CodeRuntimeMemory, type CodeRuntimeNewMemory, CodeRuntimeReconciler, type CodeRuntimeReviewRequest, type CodeRuntimeReviewResponse, type CodeRuntimeSnapshot, type CodeRuntimeSourceArchive, type CodeRuntimeSourceSnapshot, type CodeSkillOpts, type CodeSurface, type CodeToolBrokerOptions, type CodeToolCallRecord, type CodeToolDecision, type CodeVerificationEvidence, type CodeVerificationLog, type CodeVerificationPolicy, type ContainerEngine, type ContainerEngineSelectionOptions, type ContainerEngineVerificationOptions, type ContainerLimits, type ContainerRunOptions, type ContainerRunResult, type CreateCodeWorkspaceCheckpointInput, DEPENDENCY_INSTALL_TIMEOUT_MS, type DecomposedRun, DecompositionError, type DependencyCacheInput, type GoalAttempt, type GoalAttemptInput, type GoalAttemptOutcome, type GoalAttemptRecord, type GoalBudget, type GoalEvent, type GoalOutcome, type GoalRun, type GoalRunSpec, type GoalStoppedReason, type GoalStrategy, type HarnessRunnerOptions, type IntegrateOptions, type IntegrationStep, type LentDependencies, type LentDirectory, MAX_MEMORY_BODY, MEASURED_PREMIUM, type MaterializedCodeSource, type MaterializedGitTree, type NewCodeMemory, PROOF_RECIPE_PREFIX, type PrepareRuntimeCheckpointInput, type PreparedRuntimeCheckpoint, REPOSITORY_RECIPES_FILE, type RacedAttemptOptions, type RacedOutcome, type RecallOptions, type RecipeDependencies, type RepositoryRecipeEnvelope, type ResolvedCodeRecipes, type RestoreCodeWorkspaceCheckpointInput, type RestoredCodeWorkspaceCheckpoint, type RunCodeAgentOptions, type RuntimeCheckpointSession, SYSTEM_PROMPT_FOR, type StageWorkspaceOptions, type StagedWorkspace, type StrategyChoice, type StrategySignals, type SubGoal, type SubGoalResult, TheseusRuntimeEngine, type TheseusRuntimeEngineOptions, V1_SYSTEM_PROMPT, V2_SYSTEM_PROMPT, V3_SYSTEM_PROMPT, type VerifyCodeCandidateInput, applyCodePatch, applyPatchDialectToDiff, assertCodeBuildRecipe, assertDisjointPlan, assertLentPath, assertPinnedImage, assertReservedMount, attachCodeRuntimeReferences, buildContainerRunArgs, buildRecipeContainerArgs, chooseStrategy, cloneTree, codeSkill, createCodeRuntimeControlClient, createCodeRuntimeInference, createCodeRuntimeSessionSkillLoader, createCodeToolBroker, createCodeWorkspaceCheckpoint, createContainerRecipeExecutor, dependencyCacheKey, dependencyInstallArgs, describeCodeRecipes, describeGateFailure, describePatchFailure, digestStagedWorkspace, feedbackIsActionable, hasContextFreeHunk, hazardFromAttempt, hostBuildProducts, installedDependencies, integrateSubGoals, isCheckpointEffectCompleted, lendBuildProducts, lendDependencies, lentDirectories, materializeCodeRuntimeArchive, materializeCodeRuntimeSource, materializeCommandWorkspace, materializeGitTree, npmFailureSummary, outcomeCloses, outcomeMemory, parseRepositoryRecipes, patchPaths, pinnedNpmVersion, planReachCollisions, prepareContainerDependencies, prepareRuntimeCheckpoint, racedAttempt, readOnlyNotice, readRepositoryRecipes, recallAbout, registeredFiles, renderMemories, renderOutcome, resolveCodePath, resolveCodeRecipes, restoreCodeWorkspaceCheckpoint, runCodeAgent, runCodeAgentAttempt, runCodeRuntimeHeartbeatLoop, runContainerAttempt, runContainerCommand, runGoal, runHarnessRunner, runLeasedAttempt, runtimeMemoryStore, safeWorkspaceLabel, selectContainerEngine, selectWinner, sessionRecipesFor, sessionSkillsFor, stageManifests, stageWorkspace, stageWorkspacePair, straySubGoalFiles, stripPatchEnvelope, validateCodePatch, validateMemory, validateRelativePath, verifyCodeCandidate, verifyContainerEngineBoundary, withProofRecipes, withRecipeDependencies, workspaceDirs };
package/dist/node.d.ts CHANGED
@@ -596,6 +596,15 @@ interface CodeToolBrokerOptions {
596
596
  onDecision?(decision: CodeToolDecision): Promise<void> | void;
597
597
  }
598
598
 
599
+ /** A host directory (or, for build products, a file) lent into a run's workspace. */
600
+ interface LentDirectory {
601
+ /** Absolute path on the host. */
602
+ source: string;
603
+ /** Workspace-relative path it appears at. A mounted tree's last segment must be a reserved name. */
604
+ mountAs: string;
605
+ /** The workspace package it belongs to. A workspace without that directory does not receive the entry. */
606
+ within?: string;
607
+ }
599
608
  /**
600
609
  * An installed dependency tree lent to a recipe for the length of one run.
601
610
  *
@@ -608,7 +617,27 @@ interface RecipeDependencies {
608
617
  /** Where it appears inside the workspace. Must be a reserved name, so the
609
618
  * agent still cannot address it. */
610
619
  mountAs?: string;
611
- }
620
+ /** Workspace packages whose own `node_modules` the install produced (a
621
+ * version the root tree could not hoist), each lent at its own path. */
622
+ nested?: LentDirectory[];
623
+ /** The host's build output per workspace package, copied into the run's
624
+ * workspace wherever it has none, so a test can import a sibling package
625
+ * the way npm resolves it: through its `dist`. */
626
+ products?: LentDirectory[];
627
+ /** When set, every run gets its own copy-on-write clone of the tree under
628
+ * this directory and mounts it writable. vite and vitest write caches and
629
+ * bundled configs into `node_modules` and refuse a read-only one. */
630
+ runsDir?: string;
631
+ /** True only on the per-run clone `lendDependencies` makes. The shared tree
632
+ * is never mounted writable. */
633
+ writable?: boolean;
634
+ }
635
+ /** Refuse a lent path that leaves the workspace. */
636
+ declare function assertLentPath(mountAs: string): void;
637
+ /** Refuse any mounted tree the agent could address: inside the workspace, and ending in a reserved name. */
638
+ declare function assertReservedMount(mountAs: string): void;
639
+ /** Every directory a dependency set lends: the root tree first, then each nested one. */
640
+ declare function lentDirectories(dependencies: RecipeDependencies): LentDirectory[];
612
641
  /**
613
642
  * Wrap an executor so `dependencies.source` is present during each recipe run.
614
643
  *
@@ -710,8 +739,9 @@ interface TheseusRuntimeEngineOptions {
710
739
  /** Injectable agent attempt. Defaults to runAgent over the brokered surface. */
711
740
  runAgentAttempt?: (options: CodeAgentAttemptOptions) => Promise<CodeAgentAttemptResult>;
712
741
  recipeExecutor?: CodeRecipeExecutor;
713
- /** The host's installed dependency tree, lent read-only to every recipe
714
- * container so a real test runner can be a proof in an offline sandbox. */
742
+ /** The host's prepared dependency tree, lent to every recipe container (as
743
+ * the run's own writable clone when the set allows one) so a real test
744
+ * runner can be a proof in an offline sandbox. */
715
745
  recipeDependencies?: RecipeDependencies | null;
716
746
  /** Owner-visible and terminal-visible bounded runtime failures. */
717
747
  onDiagnostic?: (message: string) => void;
@@ -1616,10 +1646,10 @@ declare const DEPENDENCY_INSTALL_TIMEOUT_MS: number;
1616
1646
  /** What preparing a tree needs: the engine and pinned image, the repository, and the cache root; `run` is injectable for tests. */
1617
1647
  interface DependencyCacheInput {
1618
1648
  engine: ContainerEngine;
1619
- /** The pinned recipe image; its node and npm install the tree. */
1649
+ /** The pinned recipe image; its node installs the tree. */
1620
1650
  image: string;
1621
1651
  repoRoot: string;
1622
- /** Where trees live: `<cacheRoot>/<key>/node_modules`. */
1652
+ /** Where trees live: `<cacheRoot>/<key>/tree/node_modules`, with per-run clones under `<cacheRoot>/<key>/runs`. */
1623
1653
  cacheRoot: string;
1624
1654
  run?: (engine: ContainerEngine, args: string[], name: string, limits: {
1625
1655
  timeoutMs: number;
@@ -1627,15 +1657,24 @@ interface DependencyCacheInput {
1627
1657
  }) => Promise<CodeRecipeResult>;
1628
1658
  log?: (line: string) => void;
1629
1659
  }
1630
- /** The cache key: the lockfile's bytes, the image, and the architecture the container runs. Null without a lockfile. */
1631
- declare function dependencyCacheKey(repoRoot: string, image: string, arch?: NodeJS.Architecture): Promise<string | null>;
1660
+ /** The npm the repository generates its lockfile with: an exact `engines.npm`, or null when it pins none. */
1661
+ declare function pinnedNpmVersion(repoRoot: string): Promise<string | null>;
1662
+ /** The cache key: the lockfile's bytes, the image, the architecture the container runs, and the npm that installs. Null without a lockfile. */
1663
+ declare function dependencyCacheKey(repoRoot: string, image: string, arch?: NodeJS.Architecture, npmVersion?: string | null): Promise<string | null>;
1664
+ /** Every workspace directory the root manifest declares that has a package.json, repository-relative, in declaration order. */
1665
+ declare function workspaceDirs(repoRoot: string): Promise<string[]>;
1632
1666
  /** Copy only what npm ci needs: the root manifests and every workspace's package.json. Returns what was staged. */
1633
1667
  declare function stageManifests(repoRoot: string, stageDir: string): Promise<string[]>;
1634
- /** The helper's command: networked, writable stage, scripts disabled, nothing else of the host mounted. */
1635
- declare function dependencyInstallArgs(engine: ContainerEngine, image: string, stageDir: string, name: string): string[];
1668
+ /** The helper's command: networked, writable stage, scripts disabled, nothing else of the host mounted; the repository's npm when it pins one. */
1669
+ declare function dependencyInstallArgs(engine: ContainerEngine, image: string, stageDir: string, name: string, npmVersion?: string | null): string[];
1670
+ /** The lines of an npm failure worth reading: from `npm error code` on, never the usage boilerplate npm ends with. */
1671
+ declare function npmFailureSummary(stderr: string): string;
1636
1672
  /** The tree for this repository's lockfile, from the cache or freshly installed; null when there is no lockfile or the install failed. */
1637
1673
  declare function prepareContainerDependencies(input: DependencyCacheInput): Promise<RecipeDependencies | null>;
1638
1674
 
1675
+ /** The host checkout's build output to lend into a run's workspace: each package's `dist`, then every ignored file the policy allows. */
1676
+ declare function hostBuildProducts(repoRoot: string): Promise<LentDirectory[]>;
1677
+
1639
1678
  /** Every ordinary, policy-legal source path under `root`, sorted. */
1640
1679
  declare function registeredFiles(root: string, limit?: number): Promise<string[]>;
1641
1680
 
@@ -1653,4 +1692,17 @@ declare function runContainerCommand(engine: ContainerEngine, args: string[], na
1653
1692
  maxOutputBytes: number;
1654
1693
  }, signal?: AbortSignal): Promise<CodeRecipeResult>;
1655
1694
 
1656
- export { CODE_PATCH_PATH, CODE_RUNTIME_PROTOCOL_VERSION, type CodeAgentAttemptOptions, type CodeAgentAttemptResult, type CodeAgentRun, type CodeBuildRecipe, type CodeExpectedArtifact, type CodeLocalSourceDescriptor, type CodeMemory, type CodeMemoryEvidence, type CodeMemoryKind, type CodeMemoryStore, type CodeRecipeExecutor, type CodeRecipeResult, type CodeRuntimeAgentControlPlane, type CodeRuntimeBinding, type CodeRuntimeCandidateResponse, type CodeRuntimeCapabilities, CodeRuntimeCheckpointManager, type CodeRuntimeClientOptions, type CodeRuntimeCollaborationSkillManifest, type CodeRuntimeCollaborationToolManifest, type CodeRuntimeCollaborationToolRequest, type CodeRuntimeCommand, type CodeRuntimeCommandEngine, type CodeRuntimeCommandKind, type CodeRuntimeCommandResult, CodeRuntimeControlError, type CodeRuntimeControlPlane, type CodeRuntimeInferenceOptions, type CodeRuntimeLoopOptions, type CodeRuntimeMemory, type CodeRuntimeNewMemory, CodeRuntimeReconciler, type CodeRuntimeReviewRequest, type CodeRuntimeReviewResponse, type CodeRuntimeSnapshot, type CodeRuntimeSourceArchive, type CodeRuntimeSourceSnapshot, type CodeSkillOpts, type CodeSurface, type CodeToolBrokerOptions, type CodeToolCallRecord, type CodeToolDecision, type CodeVerificationEvidence, type CodeVerificationLog, type CodeVerificationPolicy, type ContainerEngine, type ContainerEngineSelectionOptions, type ContainerEngineVerificationOptions, type ContainerLimits, type ContainerRunOptions, type ContainerRunResult, type CreateCodeWorkspaceCheckpointInput, DEPENDENCY_INSTALL_TIMEOUT_MS, type DecomposedRun, DecompositionError, type DependencyCacheInput, type GoalAttempt, type GoalAttemptInput, type GoalAttemptOutcome, type GoalAttemptRecord, type GoalBudget, type GoalEvent, type GoalOutcome, type GoalRun, type GoalRunSpec, type GoalStoppedReason, type GoalStrategy, type HarnessRunnerOptions, type IntegrateOptions, type IntegrationStep, MAX_MEMORY_BODY, MEASURED_PREMIUM, type MaterializedCodeSource, type MaterializedGitTree, type NewCodeMemory, PROOF_RECIPE_PREFIX, type PrepareRuntimeCheckpointInput, type PreparedRuntimeCheckpoint, REPOSITORY_RECIPES_FILE, type RacedAttemptOptions, type RacedOutcome, type RecallOptions, type RecipeDependencies, type RepositoryRecipeEnvelope, type ResolvedCodeRecipes, type RestoreCodeWorkspaceCheckpointInput, type RestoredCodeWorkspaceCheckpoint, type RunCodeAgentOptions, type RuntimeCheckpointSession, SYSTEM_PROMPT_FOR, type StageWorkspaceOptions, type StagedWorkspace, type StrategyChoice, type StrategySignals, type SubGoal, type SubGoalResult, TheseusRuntimeEngine, type TheseusRuntimeEngineOptions, V1_SYSTEM_PROMPT, V2_SYSTEM_PROMPT, V3_SYSTEM_PROMPT, type VerifyCodeCandidateInput, applyCodePatch, applyPatchDialectToDiff, assertCodeBuildRecipe, assertDisjointPlan, assertPinnedImage, attachCodeRuntimeReferences, buildContainerRunArgs, buildRecipeContainerArgs, chooseStrategy, codeSkill, createCodeRuntimeControlClient, createCodeRuntimeInference, createCodeRuntimeSessionSkillLoader, createCodeToolBroker, createCodeWorkspaceCheckpoint, createContainerRecipeExecutor, dependencyCacheKey, dependencyInstallArgs, describeCodeRecipes, describeGateFailure, describePatchFailure, digestStagedWorkspace, feedbackIsActionable, hasContextFreeHunk, hazardFromAttempt, installedDependencies, integrateSubGoals, isCheckpointEffectCompleted, materializeCodeRuntimeArchive, materializeCodeRuntimeSource, materializeCommandWorkspace, materializeGitTree, outcomeCloses, outcomeMemory, parseRepositoryRecipes, patchPaths, planReachCollisions, prepareContainerDependencies, prepareRuntimeCheckpoint, racedAttempt, readOnlyNotice, readRepositoryRecipes, recallAbout, registeredFiles, renderMemories, renderOutcome, resolveCodePath, resolveCodeRecipes, restoreCodeWorkspaceCheckpoint, runCodeAgent, runCodeAgentAttempt, runCodeRuntimeHeartbeatLoop, runContainerAttempt, runContainerCommand, runGoal, runHarnessRunner, runLeasedAttempt, runtimeMemoryStore, safeWorkspaceLabel, selectContainerEngine, selectWinner, sessionRecipesFor, sessionSkillsFor, stageManifests, stageWorkspace, stageWorkspacePair, straySubGoalFiles, stripPatchEnvelope, validateCodePatch, validateMemory, validateRelativePath, verifyCodeCandidate, verifyContainerEngineBoundary, withProofRecipes, withRecipeDependencies };
1695
+ /** A dependency set lent to one run, and how to give it back. */
1696
+ interface LentDependencies {
1697
+ dependencies: RecipeDependencies | null;
1698
+ /** Remove the run's clone. A no-op when nothing was cloned. */
1699
+ release(): Promise<void>;
1700
+ }
1701
+ /** Clone a directory tree, sharing blocks with the original where the filesystem can and copying otherwise. */
1702
+ declare function cloneTree(source: string, target: string, platform?: NodeJS.Platform): Promise<void>;
1703
+ /** Give one run its own writable clone of the tree when the set allows it; otherwise lend the set as it is, read-only. */
1704
+ declare function lendDependencies(dependencies: RecipeDependencies | null, runId: string): Promise<LentDependencies>;
1705
+ /** Copy the host's build output into the workspace wherever its package exists there and it has no copy of its own. Returns what was lent. */
1706
+ declare function lendBuildProducts(products: readonly LentDirectory[], workspaceDir: string): Promise<string[]>;
1707
+
1708
+ export { CODE_PATCH_PATH, CODE_RUNTIME_PROTOCOL_VERSION, type CodeAgentAttemptOptions, type CodeAgentAttemptResult, type CodeAgentRun, type CodeBuildRecipe, type CodeExpectedArtifact, type CodeLocalSourceDescriptor, type CodeMemory, type CodeMemoryEvidence, type CodeMemoryKind, type CodeMemoryStore, type CodeRecipeExecutor, type CodeRecipeResult, type CodeRuntimeAgentControlPlane, type CodeRuntimeBinding, type CodeRuntimeCandidateResponse, type CodeRuntimeCapabilities, CodeRuntimeCheckpointManager, type CodeRuntimeClientOptions, type CodeRuntimeCollaborationSkillManifest, type CodeRuntimeCollaborationToolManifest, type CodeRuntimeCollaborationToolRequest, type CodeRuntimeCommand, type CodeRuntimeCommandEngine, type CodeRuntimeCommandKind, type CodeRuntimeCommandResult, CodeRuntimeControlError, type CodeRuntimeControlPlane, type CodeRuntimeInferenceOptions, type CodeRuntimeLoopOptions, type CodeRuntimeMemory, type CodeRuntimeNewMemory, CodeRuntimeReconciler, type CodeRuntimeReviewRequest, type CodeRuntimeReviewResponse, type CodeRuntimeSnapshot, type CodeRuntimeSourceArchive, type CodeRuntimeSourceSnapshot, type CodeSkillOpts, type CodeSurface, type CodeToolBrokerOptions, type CodeToolCallRecord, type CodeToolDecision, type CodeVerificationEvidence, type CodeVerificationLog, type CodeVerificationPolicy, type ContainerEngine, type ContainerEngineSelectionOptions, type ContainerEngineVerificationOptions, type ContainerLimits, type ContainerRunOptions, type ContainerRunResult, type CreateCodeWorkspaceCheckpointInput, DEPENDENCY_INSTALL_TIMEOUT_MS, type DecomposedRun, DecompositionError, type DependencyCacheInput, type GoalAttempt, type GoalAttemptInput, type GoalAttemptOutcome, type GoalAttemptRecord, type GoalBudget, type GoalEvent, type GoalOutcome, type GoalRun, type GoalRunSpec, type GoalStoppedReason, type GoalStrategy, type HarnessRunnerOptions, type IntegrateOptions, type IntegrationStep, type LentDependencies, type LentDirectory, MAX_MEMORY_BODY, MEASURED_PREMIUM, type MaterializedCodeSource, type MaterializedGitTree, type NewCodeMemory, PROOF_RECIPE_PREFIX, type PrepareRuntimeCheckpointInput, type PreparedRuntimeCheckpoint, REPOSITORY_RECIPES_FILE, type RacedAttemptOptions, type RacedOutcome, type RecallOptions, type RecipeDependencies, type RepositoryRecipeEnvelope, type ResolvedCodeRecipes, type RestoreCodeWorkspaceCheckpointInput, type RestoredCodeWorkspaceCheckpoint, type RunCodeAgentOptions, type RuntimeCheckpointSession, SYSTEM_PROMPT_FOR, type StageWorkspaceOptions, type StagedWorkspace, type StrategyChoice, type StrategySignals, type SubGoal, type SubGoalResult, TheseusRuntimeEngine, type TheseusRuntimeEngineOptions, V1_SYSTEM_PROMPT, V2_SYSTEM_PROMPT, V3_SYSTEM_PROMPT, type VerifyCodeCandidateInput, applyCodePatch, applyPatchDialectToDiff, assertCodeBuildRecipe, assertDisjointPlan, assertLentPath, assertPinnedImage, assertReservedMount, attachCodeRuntimeReferences, buildContainerRunArgs, buildRecipeContainerArgs, chooseStrategy, cloneTree, codeSkill, createCodeRuntimeControlClient, createCodeRuntimeInference, createCodeRuntimeSessionSkillLoader, createCodeToolBroker, createCodeWorkspaceCheckpoint, createContainerRecipeExecutor, dependencyCacheKey, dependencyInstallArgs, describeCodeRecipes, describeGateFailure, describePatchFailure, digestStagedWorkspace, feedbackIsActionable, hasContextFreeHunk, hazardFromAttempt, hostBuildProducts, installedDependencies, integrateSubGoals, isCheckpointEffectCompleted, lendBuildProducts, lendDependencies, lentDirectories, materializeCodeRuntimeArchive, materializeCodeRuntimeSource, materializeCommandWorkspace, materializeGitTree, npmFailureSummary, outcomeCloses, outcomeMemory, parseRepositoryRecipes, patchPaths, pinnedNpmVersion, planReachCollisions, prepareContainerDependencies, prepareRuntimeCheckpoint, racedAttempt, readOnlyNotice, readRepositoryRecipes, recallAbout, registeredFiles, renderMemories, renderOutcome, resolveCodePath, resolveCodeRecipes, restoreCodeWorkspaceCheckpoint, runCodeAgent, runCodeAgentAttempt, runCodeRuntimeHeartbeatLoop, runContainerAttempt, runContainerCommand, runGoal, runHarnessRunner, runLeasedAttempt, runtimeMemoryStore, safeWorkspaceLabel, selectContainerEngine, selectWinner, sessionRecipesFor, sessionSkillsFor, stageManifests, stageWorkspace, stageWorkspacePair, straySubGoalFiles, stripPatchEnvelope, validateCodePatch, validateMemory, validateRelativePath, verifyCodeCandidate, verifyContainerEngineBoundary, withProofRecipes, withRecipeDependencies, workspaceDirs };
package/dist/node.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  runHarnessRunner,
3
3
  runLeasedAttempt
4
- } from "./chunk-GNNAQ2JX.js";
4
+ } from "./chunk-EXSEQEZ6.js";
5
5
  import {
6
6
  CODE_PATCH_PATH,
7
7
  CODE_RUNTIME_PROTOCOL_VERSION,
@@ -19,8 +19,11 @@ import {
19
19
  applyCodePatch,
20
20
  applyPatchDialectToDiff,
21
21
  assertCodeBuildRecipe,
22
+ assertLentPath,
23
+ assertReservedMount,
22
24
  attachCodeRuntimeReferences,
23
25
  buildRecipeContainerArgs,
26
+ cloneTree,
24
27
  codeSkill,
25
28
  createCodeRuntimeControlClient,
26
29
  createCodeRuntimeInference,
@@ -34,7 +37,11 @@ import {
34
37
  digestStagedWorkspace,
35
38
  hasContextFreeHunk,
36
39
  hazardFromAttempt,
40
+ installedDependencies,
37
41
  isCheckpointEffectCompleted,
42
+ lendBuildProducts,
43
+ lendDependencies,
44
+ lentDirectories,
38
45
  materializeCodeRuntimeArchive,
39
46
  materializeCodeRuntimeSource,
40
47
  materializeCommandWorkspace,
@@ -60,10 +67,12 @@ import {
60
67
  validateMemory,
61
68
  validateRelativePath,
62
69
  verifyCodeCandidate,
63
- withProofRecipes
64
- } from "./chunk-4IGSN53G.js";
70
+ withProofRecipes,
71
+ withRecipeDependencies
72
+ } from "./chunk-6QILNLBY.js";
65
73
  import "./chunk-INL642J5.js";
66
74
  import {
75
+ allowedWorkspacePath,
67
76
  assertPinnedImage,
68
77
  buildContainerRunArgs,
69
78
  materializeGitTree,
@@ -73,7 +82,7 @@ import {
73
82
  stageWorkspace,
74
83
  stageWorkspacePair,
75
84
  verifyContainerEngineBoundary
76
- } from "./chunk-ZM6AITC2.js";
85
+ } from "./chunk-3ON6UAOV.js";
77
86
  import "./chunk-T2IW7MYQ.js";
78
87
  import "./chunk-ONYW2VSB.js";
79
88
 
@@ -343,82 +352,58 @@ function chooseStrategy(signals = {}) {
343
352
  }
344
353
  var feedbackIsActionable = actionable;
345
354
 
346
- // src/code-recipe-dependencies.ts
347
- import { lstat, rm, symlink } from "fs/promises";
348
- import { isAbsolute, join } from "path";
349
- var RESERVED_MOUNTS = /* @__PURE__ */ new Set(["node_modules", "dist", "coverage"]);
350
- function withRecipeDependencies(executor, dependencies) {
351
- const mountAs = dependencies.mountAs ?? "node_modules";
352
- if (!isAbsolute(dependencies.source)) {
353
- throw new TypeError("recipe dependency source must be an absolute path");
354
- }
355
- if (!RESERVED_MOUNTS.has(mountAs)) {
356
- throw new TypeError(`recipe dependencies must mount at a reserved name, not "${mountAs}"`);
357
- }
358
- return {
359
- run: async (input) => {
360
- const target = join(input.workspaceDir, mountAs);
361
- let linked = false;
362
- try {
363
- const existing = await lstat(target).catch(() => null);
364
- if (!existing) {
365
- await symlink(dependencies.source, target, "dir");
366
- linked = true;
367
- }
368
- return await executor.run(input);
369
- } finally {
370
- if (linked) await rm(target, { force: true, recursive: false }).catch(() => void 0);
371
- }
372
- }
373
- };
374
- }
375
- async function installedDependencies(repoRoot) {
376
- const source = join(repoRoot, "node_modules");
377
- const info = await lstat(source).catch(() => null);
378
- return info?.isDirectory() ? { source } : null;
379
- }
380
-
381
355
  // src/code-recipe-dependency-cache.ts
382
356
  import { createHash } from "crypto";
383
- import { copyFile, mkdir, readFile, readdir, rename, rm as rm2, stat, writeFile } from "fs/promises";
357
+ import { copyFile, mkdir, readFile, readdir, rename, rm, stat, writeFile } from "fs/promises";
384
358
  import { getgid, getuid } from "process";
385
- import { join as join2 } from "path";
359
+ import { join } from "path";
386
360
  var DEPENDENCY_INSTALL_TIMEOUT_MS = 20 * 6e4;
387
361
  var OUTPUT_CAP = 4 * 1024 * 1024;
362
+ var EXACT_VERSION = /^\d+\.\d+\.\d+$/;
388
363
  var exists = async (path) => Boolean(await stat(path).catch(() => null));
389
- async function dependencyCacheKey(repoRoot, image, arch = process.arch) {
390
- const lock = await readFile(join2(repoRoot, "package-lock.json")).catch(() => null);
364
+ async function pinnedNpmVersion(repoRoot) {
365
+ const manifest = await readFile(join(repoRoot, "package.json"), "utf8").catch(() => null);
366
+ if (!manifest) return null;
367
+ const engines = JSON.parse(manifest).engines;
368
+ return typeof engines?.npm === "string" && EXACT_VERSION.test(engines.npm) ? engines.npm : null;
369
+ }
370
+ async function dependencyCacheKey(repoRoot, image, arch = process.arch, npmVersion = null) {
371
+ const lock = await readFile(join(repoRoot, "package-lock.json")).catch(() => null);
391
372
  if (!lock) return null;
392
- return createHash("sha256").update(lock).update("\n").update(image).update("\n").update(arch).digest("hex").slice(0, 32);
373
+ return createHash("sha256").update(lock).update("\n").update(image).update("\n").update(arch).update("\n").update(npmVersion ?? "image").digest("hex").slice(0, 32);
374
+ }
375
+ async function workspaceDirs(repoRoot) {
376
+ const root = JSON.parse(await readFile(join(repoRoot, "package.json"), "utf8"));
377
+ const globs = Array.isArray(root.workspaces) ? root.workspaces : root.workspaces?.packages ?? [];
378
+ const dirs = [];
379
+ for (const glob of globs) {
380
+ const found = glob.endsWith("/*") ? (await readdir(join(repoRoot, glob.slice(0, -2)), { withFileTypes: true }).catch(() => [])).filter((entry) => entry.isDirectory()).map((entry) => `${glob.slice(0, -2)}/${entry.name}`) : [glob];
381
+ for (const dir of found) if (await exists(join(repoRoot, dir, "package.json"))) dirs.push(dir);
382
+ }
383
+ return dirs;
393
384
  }
394
385
  async function stageManifests(repoRoot, stageDir) {
395
386
  await mkdir(stageDir, { recursive: true });
396
387
  const staged = [];
397
388
  for (const name of ["package.json", "package-lock.json", ".npmrc"]) {
398
- if (!await exists(join2(repoRoot, name))) continue;
399
- await copyFile(join2(repoRoot, name), join2(stageDir, name));
389
+ if (!await exists(join(repoRoot, name))) continue;
390
+ await copyFile(join(repoRoot, name), join(stageDir, name));
400
391
  staged.push(name);
401
392
  }
402
- const root = JSON.parse(await readFile(join2(repoRoot, "package.json"), "utf8"));
403
- const globs = Array.isArray(root.workspaces) ? root.workspaces : root.workspaces?.packages ?? [];
404
- for (const glob of globs) {
405
- const dirs = glob.endsWith("/*") ? (await readdir(join2(repoRoot, glob.slice(0, -2)), { withFileTypes: true }).catch(() => [])).filter((entry) => entry.isDirectory()).map((entry) => `${glob.slice(0, -2)}/${entry.name}`) : [glob];
406
- for (const dir of dirs) {
407
- const manifest = join2(repoRoot, dir, "package.json");
408
- if (!await exists(manifest)) continue;
409
- await mkdir(join2(stageDir, dir), { recursive: true });
410
- await copyFile(manifest, join2(stageDir, dir, "package.json"));
411
- staged.push(`${dir}/package.json`);
412
- }
393
+ for (const dir of await workspaceDirs(repoRoot)) {
394
+ await mkdir(join(stageDir, dir), { recursive: true });
395
+ await copyFile(join(repoRoot, dir, "package.json"), join(stageDir, dir, "package.json"));
396
+ staged.push(`${dir}/package.json`);
413
397
  }
414
398
  return staged;
415
399
  }
416
- function dependencyInstallArgs(engine, image, stageDir, name) {
400
+ function dependencyInstallArgs(engine, image, stageDir, name, npmVersion = null) {
417
401
  if (/[,\r\n]/.test(stageDir)) throw new TypeError("stage path contains unsupported mount characters");
418
402
  const uid = typeof getuid === "function" ? getuid() : 1e3;
419
403
  const gid = typeof getgid === "function" ? getgid() : 1e3;
420
404
  const mount = engine === "container" ? `--mount=type=bind,source=${stageDir},target=/workspace` : `--mount=type=bind,src=${stageDir},dst=/workspace`;
421
- const npm = ["npm", "ci", "--no-audit", "--no-fund", "--ignore-scripts"];
405
+ const install = ["ci", "--no-audit", "--no-fund", "--ignore-scripts", "--engine-strict=false"];
406
+ const npm = npmVersion ? ["npx", "--yes", `npm@${npmVersion}`, ...install] : ["npm", ...install];
422
407
  return [
423
408
  "run",
424
409
  "--rm",
@@ -437,34 +422,79 @@ function dependencyInstallArgs(engine, image, stageDir, name) {
437
422
  ...npm
438
423
  ];
439
424
  }
425
+ function npmFailureSummary(stderr) {
426
+ const lines = stderr.split("\n").map((line) => line.trim()).filter((line) => line && line !== "npm error");
427
+ const at = lines.findIndex((line) => /^npm error code /.test(line));
428
+ return (at >= 0 ? lines.slice(at, at + 3) : lines.slice(-3)).join(" | ").slice(0, 400);
429
+ }
430
+ async function nestedTrees(treeRoot, dirs) {
431
+ const nested = [];
432
+ for (const dir of dirs) {
433
+ if (await exists(join(treeRoot, dir, "node_modules"))) nested.push({ source: join(treeRoot, dir, "node_modules"), mountAs: `${dir}/node_modules` });
434
+ }
435
+ return nested;
436
+ }
440
437
  async function prepareContainerDependencies(input) {
441
- const key = await dependencyCacheKey(input.repoRoot, input.image);
438
+ const npmVersion = await pinnedNpmVersion(input.repoRoot);
439
+ const key = await dependencyCacheKey(input.repoRoot, input.image, process.arch, npmVersion);
442
440
  if (!key) return null;
443
- const dir = join2(input.cacheRoot, key);
444
- const tree = join2(dir, "node_modules");
445
- const stage = join2(dir, "stage");
446
- if (await exists(tree)) return { source: tree };
441
+ const dir = join(input.cacheRoot, key);
442
+ const tree = join(dir, "tree");
443
+ const stage = join(dir, "stage");
444
+ const runsDir = join(dir, "runs");
445
+ await rm(runsDir, { recursive: true, force: true });
446
+ const dirs = await workspaceDirs(input.repoRoot);
447
+ const lend = async () => ({ source: join(tree, "node_modules"), nested: await nestedTrees(tree, dirs), runsDir });
448
+ if (await exists(join(tree, "node_modules"))) return lend();
447
449
  const run = input.run ?? runContainerCommand;
448
- await rm2(stage, { recursive: true, force: true });
450
+ await rm(stage, { recursive: true, force: true });
449
451
  const staged = await stageManifests(input.repoRoot, stage);
450
- input.log?.(`installing ${key.slice(0, 12)}: ${staged.length} manifests, npm ci in ${input.image}`);
452
+ input.log?.(`installing ${key.slice(0, 12)}: ${staged.length} manifests, npm${npmVersion ? `@${npmVersion}` : ""} ci in ${input.image}`);
451
453
  const name = `odla-deps-${key.slice(0, 12)}`;
452
454
  const result = await run(
453
455
  input.engine,
454
- dependencyInstallArgs(input.engine, input.image, stage, name),
456
+ dependencyInstallArgs(input.engine, input.image, stage, name, npmVersion),
455
457
  name,
456
458
  { timeoutMs: DEPENDENCY_INSTALL_TIMEOUT_MS, maxOutputBytes: OUTPUT_CAP }
457
459
  );
458
- if (result.exitCode !== 0 || result.timedOut || !await exists(join2(stage, "node_modules"))) {
459
- input.log?.(`install failed (exit ${result.exitCode}${result.timedOut ? ", timed out" : ""}): ${result.stderr.trim().split("\n").slice(-3).join(" | ").slice(0, 400)}`);
460
- await rm2(stage, { recursive: true, force: true });
460
+ if (result.exitCode !== 0 || result.timedOut || !await exists(join(stage, "node_modules"))) {
461
+ input.log?.(`install failed (exit ${result.exitCode}${result.timedOut ? ", timed out" : ""}): ${npmFailureSummary(result.stderr)}`);
462
+ await rm(stage, { recursive: true, force: true });
461
463
  return null;
462
464
  }
463
- await rename(join2(stage, "node_modules"), tree);
464
- await rm2(stage, { recursive: true, force: true });
465
- await writeFile(join2(dir, "manifest.json"), JSON.stringify({ image: input.image, key, createdAt: Date.now() }, null, 2));
466
- input.log?.(`installed ${key.slice(0, 12)} in ${Math.round(result.durationMs / 1e3)}s`);
467
- return { source: tree };
465
+ await rm(tree, { recursive: true, force: true });
466
+ await rename(stage, tree);
467
+ await writeFile(join(dir, "manifest.json"), JSON.stringify({ image: input.image, key, npmVersion, createdAt: Date.now() }, null, 2));
468
+ const lent = await lend();
469
+ input.log?.(`installed ${key.slice(0, 12)} in ${Math.round(result.durationMs / 1e3)}s, ${lent.nested?.length ?? 0} nested tree(s)`);
470
+ return lent;
471
+ }
472
+
473
+ // src/code-recipe-build-products.ts
474
+ import { spawn } from "child_process";
475
+ import { stat as stat2 } from "fs/promises";
476
+ import { join as join2 } from "path";
477
+ function gitIgnoredFiles(repoRoot) {
478
+ return new Promise((accept) => {
479
+ const child = spawn("git", ["-C", repoRoot, "ls-files", "--others", "--ignored", "--exclude-standard", "-z"], { shell: false, stdio: ["ignore", "pipe", "ignore"] });
480
+ const chunks = [];
481
+ child.stdout.on("data", (chunk) => chunks.push(chunk));
482
+ child.once("error", () => accept([]));
483
+ child.once("exit", (code) => accept(code === 0 ? Buffer.concat(chunks).toString("utf8").split("\0").filter(Boolean) : []));
484
+ });
485
+ }
486
+ async function hostBuildProducts(repoRoot) {
487
+ const dirs = await workspaceDirs(repoRoot);
488
+ const within = (path) => dirs.find((dir) => path.startsWith(`${dir}/`)) ?? ".";
489
+ const products = [];
490
+ for (const dir of dirs) {
491
+ const source = join2(repoRoot, dir, "dist");
492
+ if ((await stat2(source).catch(() => null))?.isDirectory()) products.push({ source, mountAs: `${dir}/dist`, within: dir });
493
+ }
494
+ for (const path of await gitIgnoredFiles(repoRoot)) {
495
+ if (allowedWorkspacePath(path)) products.push({ source: join2(repoRoot, path), mountAs: path, within: within(path) });
496
+ }
497
+ return products;
468
498
  }
469
499
  export {
470
500
  CODE_PATCH_PATH,
@@ -487,11 +517,14 @@ export {
487
517
  applyPatchDialectToDiff,
488
518
  assertCodeBuildRecipe,
489
519
  assertDisjointPlan,
520
+ assertLentPath,
490
521
  assertPinnedImage,
522
+ assertReservedMount,
491
523
  attachCodeRuntimeReferences,
492
524
  buildContainerRunArgs,
493
525
  buildRecipeContainerArgs,
494
526
  chooseStrategy,
527
+ cloneTree,
495
528
  codeSkill,
496
529
  createCodeRuntimeControlClient,
497
530
  createCodeRuntimeInference,
@@ -508,17 +541,23 @@ export {
508
541
  feedbackIsActionable,
509
542
  hasContextFreeHunk,
510
543
  hazardFromAttempt,
544
+ hostBuildProducts,
511
545
  installedDependencies,
512
546
  integrateSubGoals,
513
547
  isCheckpointEffectCompleted,
548
+ lendBuildProducts,
549
+ lendDependencies,
550
+ lentDirectories,
514
551
  materializeCodeRuntimeArchive,
515
552
  materializeCodeRuntimeSource,
516
553
  materializeCommandWorkspace,
517
554
  materializeGitTree,
555
+ npmFailureSummary,
518
556
  outcomeCloses,
519
557
  outcomeMemory,
520
558
  parseRepositoryRecipes,
521
559
  patchPaths,
560
+ pinnedNpmVersion,
522
561
  planReachCollisions,
523
562
  prepareContainerDependencies,
524
563
  prepareRuntimeCheckpoint,
@@ -557,6 +596,7 @@ export {
557
596
  verifyCodeCandidate,
558
597
  verifyContainerEngineBoundary,
559
598
  withProofRecipes,
560
- withRecipeDependencies
599
+ withRecipeDependencies,
600
+ workspaceDirs
561
601
  };
562
602
  //# sourceMappingURL=node.js.map