@odla-ai/harness 0.10.4 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,7 @@ import {
7
7
  createCodeRuntimeControlClient,
8
8
  createCodeRuntimeSessionSkillLoader,
9
9
  runCodeRuntimeHeartbeatLoop
10
- } from "./chunk-IV3VMKDV.js";
10
+ } from "./chunk-DP6LOGBF.js";
11
11
  import "./chunk-KXFI3WM2.js";
12
12
  import {
13
13
  assertPinnedImage,
package/dist/node.cjs CHANGED
@@ -27,6 +27,7 @@ __export(node_exports, {
27
27
  DecompositionError: () => DecompositionError,
28
28
  MAX_MEMORY_BODY: () => MAX_MEMORY_BODY,
29
29
  MEASURED_PREMIUM: () => MEASURED_PREMIUM,
30
+ REPOSITORY_RECIPES_FILE: () => REPOSITORY_RECIPES_FILE,
30
31
  SYSTEM_PROMPT_FOR: () => SYSTEM_PROMPT_FOR,
31
32
  TheseusRuntimeEngine: () => TheseusRuntimeEngine,
32
33
  V1_SYSTEM_PROMPT: () => V1_SYSTEM_PROMPT,
@@ -48,6 +49,7 @@ __export(node_exports, {
48
49
  createCodeToolBroker: () => createCodeToolBroker,
49
50
  createCodeWorkspaceCheckpoint: () => createCodeWorkspaceCheckpoint,
50
51
  createContainerRecipeExecutor: () => createContainerRecipeExecutor,
52
+ describeCodeRecipes: () => describeCodeRecipes,
51
53
  describePatchFailure: () => describePatchFailure,
52
54
  digestStagedWorkspace: () => digestStagedWorkspace,
53
55
  feedbackIsActionable: () => feedbackIsActionable,
@@ -62,16 +64,19 @@ __export(node_exports, {
62
64
  materializeGitTree: () => materializeGitTree,
63
65
  outcomeCloses: () => outcomeCloses,
64
66
  outcomeMemory: () => outcomeMemory,
67
+ parseRepositoryRecipes: () => parseRepositoryRecipes,
65
68
  patchPaths: () => patchPaths,
66
69
  planReachCollisions: () => planReachCollisions,
67
70
  prepareRuntimeCheckpoint: () => prepareRuntimeCheckpoint,
68
71
  racedAttempt: () => racedAttempt,
69
72
  readOnlyNotice: () => readOnlyNotice,
73
+ readRepositoryRecipes: () => readRepositoryRecipes,
70
74
  recallAbout: () => recallAbout,
71
75
  registeredFiles: () => registeredFiles,
72
76
  renderMemories: () => renderMemories,
73
77
  renderOutcome: () => renderOutcome,
74
78
  resolveCodePath: () => resolveCodePath,
79
+ resolveCodeRecipes: () => resolveCodeRecipes,
75
80
  restoreCodeWorkspaceCheckpoint: () => restoreCodeWorkspaceCheckpoint,
76
81
  runCodeAgent: () => runCodeAgent,
77
82
  runCodeAgentAttempt: () => runCodeAgentAttempt,
@@ -84,6 +89,7 @@ __export(node_exports, {
84
89
  safeWorkspaceLabel: () => safeWorkspaceLabel,
85
90
  selectContainerEngine: () => selectContainerEngine,
86
91
  selectWinner: () => selectWinner,
92
+ sessionRecipesFor: () => sessionRecipesFor,
87
93
  sessionSkillsFor: () => sessionSkillsFor,
88
94
  stageWorkspace: () => stageWorkspace,
89
95
  stageWorkspacePair: () => stageWorkspacePair,
@@ -1315,40 +1321,40 @@ async function readBoundedResponse(body, maximum) {
1315
1321
  return result;
1316
1322
  }
1317
1323
 
1318
- // src/code-runtime.ts
1319
- var CODE_RUNTIME_PROTOCOL_VERSION = 3;
1320
- async function runCodeRuntimeHeartbeatLoop(options) {
1321
- const heartbeatMs = options.heartbeatMs ?? 15e3;
1322
- if (!Number.isSafeInteger(heartbeatMs) || heartbeatMs < 1e3 || heartbeatMs > 3e5) {
1323
- throw new TypeError("heartbeatMs must be an integer from 1000 to 300000");
1324
- }
1325
- let retryMs = 1e3;
1326
- do {
1327
- if (options.signal?.aborted) return;
1324
+ // src/code-runtime-overload.ts
1325
+ var OVERLOAD_RETRY_DELAYS_MS = [2e3, 4e3, 8e3, 16e3];
1326
+ var RETRYABLE_CODES = /* @__PURE__ */ new Set(["control_plane_overloaded", "registry_overloaded", "transport_unavailable"]);
1327
+ function overloadedControlFailure(cause) {
1328
+ if (!cause || typeof cause !== "object") return false;
1329
+ const failure = cause;
1330
+ return failure.status === 503 && typeof failure.code === "string" && RETRYABLE_CODES.has(failure.code);
1331
+ }
1332
+ async function withOverloadRetry(call, wait2, onRetry = () => void 0) {
1333
+ for (let attempt = 0; ; attempt += 1) {
1328
1334
  try {
1329
- const snapshot = await options.control.heartbeat(options.runtimeVersion, options.capabilities);
1330
- await options.onSnapshot?.(snapshot);
1331
- retryMs = 1e3;
1332
- if (options.once) return;
1333
- await wait(heartbeatMs, options.signal);
1334
- } catch (error) {
1335
- if (options.signal?.aborted) return;
1336
- if (options.once || !retryableControlFailure(error)) throw error;
1337
- await options.onRetry?.(error, retryMs);
1338
- await wait(retryMs, options.signal);
1339
- retryMs = Math.min(retryMs * 2, 3e4);
1335
+ return await call();
1336
+ } catch (cause) {
1337
+ const delayMs = OVERLOAD_RETRY_DELAYS_MS[attempt];
1338
+ if (delayMs === void 0 || !overloadedControlFailure(cause)) throw cause;
1339
+ await onRetry(cause, delayMs);
1340
+ await wait2(delayMs);
1340
1341
  }
1341
- } while (!options.signal?.aborted);
1342
+ }
1342
1343
  }
1344
+
1345
+ // src/code-runtime-reconciler.ts
1346
+ var sleep = (ms) => new Promise((resolve8) => setTimeout(resolve8, ms));
1343
1347
  var CodeRuntimeReconciler = class {
1344
- constructor(control, engine, onDiagnostic) {
1348
+ constructor(control, engine, onDiagnostic, options = {}) {
1345
1349
  this.control = control;
1346
1350
  this.engine = engine;
1347
1351
  this.onDiagnostic = onDiagnostic;
1352
+ this.options = options;
1348
1353
  }
1349
1354
  control;
1350
1355
  engine;
1351
1356
  onDiagnostic;
1357
+ options;
1352
1358
  results = /* @__PURE__ */ new Map();
1353
1359
  async reconcile(snapshot) {
1354
1360
  for (const command of snapshot.commands) {
@@ -1367,7 +1373,15 @@ var CodeRuntimeReconciler = class {
1367
1373
  await this.control.acknowledge(command.commandId, completed.result);
1368
1374
  if (!completed.notified) {
1369
1375
  try {
1370
- await this.engine.acknowledged?.(command, completed.result);
1376
+ await withOverloadRetry(
1377
+ async () => {
1378
+ await this.engine.acknowledged?.(command, completed.result);
1379
+ },
1380
+ (ms) => (this.options.wait ?? sleep)(ms),
1381
+ (cause, delayMs) => this.onDiagnostic?.(
1382
+ `command ${command.commandId} acknowledged handling waits ${delayMs}ms for an overloaded control plane \xB7 ${cause instanceof Error ? cause.message : String(cause)}`
1383
+ )
1384
+ );
1371
1385
  } catch (error) {
1372
1386
  this.onDiagnostic?.(
1373
1387
  `command ${command.commandId} acknowledged handling failed \xB7 ${error instanceof Error ? error.message : String(error)}`
@@ -1378,6 +1392,32 @@ var CodeRuntimeReconciler = class {
1378
1392
  }
1379
1393
  }
1380
1394
  };
1395
+
1396
+ // src/code-runtime.ts
1397
+ var CODE_RUNTIME_PROTOCOL_VERSION = 3;
1398
+ async function runCodeRuntimeHeartbeatLoop(options) {
1399
+ const heartbeatMs = options.heartbeatMs ?? 15e3;
1400
+ if (!Number.isSafeInteger(heartbeatMs) || heartbeatMs < 1e3 || heartbeatMs > 3e5) {
1401
+ throw new TypeError("heartbeatMs must be an integer from 1000 to 300000");
1402
+ }
1403
+ let retryMs = 1e3;
1404
+ do {
1405
+ if (options.signal?.aborted) return;
1406
+ try {
1407
+ const snapshot = await options.control.heartbeat(options.runtimeVersion, options.capabilities);
1408
+ await options.onSnapshot?.(snapshot);
1409
+ retryMs = 1e3;
1410
+ if (options.once) return;
1411
+ await wait(heartbeatMs, options.signal);
1412
+ } catch (error) {
1413
+ if (options.signal?.aborted) return;
1414
+ if (options.once || !retryableControlFailure(error)) throw error;
1415
+ await options.onRetry?.(error, retryMs);
1416
+ await wait(retryMs, options.signal);
1417
+ retryMs = Math.min(retryMs * 2, 3e4);
1418
+ }
1419
+ } while (!options.signal?.aborted);
1420
+ }
1381
1421
  function retryableControlFailure(value) {
1382
1422
  if (!value || typeof value !== "object") return false;
1383
1423
  const failure = value;
@@ -2000,8 +2040,8 @@ var CodeRuntimeCheckpointManager = class {
2000
2040
  trustedBaseDigest: active.trustedBaseDigest,
2001
2041
  planningInputDigest: active.planningInputDigest,
2002
2042
  conversationRefs: active.conversationRefs,
2003
- fallbackPolicyDigest: this.options.fallbackPolicyDigest,
2004
- recipes: this.options.recipes,
2043
+ fallbackPolicyDigest: active.buildPolicyDigest ?? this.options.fallbackPolicyDigest,
2044
+ recipes: active.recipes ?? this.options.recipes,
2005
2045
  recipeExecutor: this.options.recipeExecutor,
2006
2046
  review: (patch2, verification) => this.options.control.review(command.sessionId, { patch: patch2, verification })
2007
2047
  });
@@ -2942,13 +2982,19 @@ function createCodeRuntimeSessionSkillLoader(control) {
2942
2982
  ...tool.acceptsTaint === void 0 ? {} : { acceptsTaint: tool.acceptsTaint },
2943
2983
  handler: async (input, context) => {
2944
2984
  if (!context.toolCallId) throw new TypeError("collaboration tool call identity is required");
2945
- return execute2(command.sessionId, {
2946
- commandId: command.commandId,
2947
- toolCallId: context.toolCallId,
2948
- skill: manifest.name,
2949
- tool: tool.name,
2950
- input
2951
- }, context.signal);
2985
+ try {
2986
+ return await execute2(command.sessionId, {
2987
+ commandId: command.commandId,
2988
+ toolCallId: context.toolCallId,
2989
+ skill: manifest.name,
2990
+ tool: tool.name,
2991
+ input
2992
+ }, context.signal);
2993
+ } catch (cause) {
2994
+ if (context.signal?.aborted) throw cause;
2995
+ const detail = (cause instanceof Error ? cause.message : String(cause)).slice(0, 500);
2996
+ return { content: `Tool "${tool.name}" failed: ${detail}`, isError: true };
2997
+ }
2952
2998
  }
2953
2999
  }))
2954
3000
  }));
@@ -2966,23 +3012,7 @@ async function sessionSkillsFor(options, command) {
2966
3012
  }
2967
3013
 
2968
3014
  // src/code-runtime-inference.ts
2969
- var OVERLOAD_RETRY_DELAYS_MS = [2e3, 4e3, 8e3, 16e3];
2970
- var RETRYABLE_CODES = /* @__PURE__ */ new Set(["control_plane_overloaded", "registry_overloaded", "transport_unavailable"]);
2971
- function overloadedControlFailure(cause) {
2972
- return cause instanceof CodeRuntimeControlError && cause.status === 503 && RETRYABLE_CODES.has(cause.code);
2973
- }
2974
- async function inferWithBackoff(infer, wait2, onRetry) {
2975
- for (let attempt = 0; ; attempt += 1) {
2976
- try {
2977
- return await infer();
2978
- } catch (cause) {
2979
- const delayMs = OVERLOAD_RETRY_DELAYS_MS[attempt];
2980
- if (delayMs === void 0 || !overloadedControlFailure(cause)) throw cause;
2981
- await onRetry(cause, delayMs);
2982
- await wait2(delayMs);
2983
- }
2984
- }
2985
- }
3015
+ var inferWithBackoff = (infer, wait2, onRetry) => withOverloadRetry(infer, wait2, (cause, delayMs) => onRetry(cause, delayMs));
2986
3016
  async function handleCodeRuntimeInference(input) {
2987
3017
  const { command, request, state } = input;
2988
3018
  const startedAt = Date.now();
@@ -4417,6 +4447,96 @@ function observeCodeRuntimeSessionSkills(command, skills, emit) {
4417
4447
  }));
4418
4448
  }
4419
4449
 
4450
+ // src/code-repository-recipes.ts
4451
+ var import_promises15 = require("fs/promises");
4452
+ var import_node_path13 = require("path");
4453
+ var REPOSITORY_RECIPES_FILE = "odla.recipes.json";
4454
+ var MAX_RECIPES = 16;
4455
+ var DEFAULT_TIMEOUT_MS = 12e4;
4456
+ var MAX_TIMEOUT_MS = 15 * 6e4;
4457
+ var ID2 = /^[A-Za-z0-9._:-]{1,120}$/;
4458
+ var RECIPE_FIELDS = /* @__PURE__ */ new Set(["id", "command", "timeoutMs"]);
4459
+ var fault = (detail) => new TypeError(`${REPOSITORY_RECIPES_FILE} is malformed: ${detail}`);
4460
+ function parseRepositoryRecipes(text2, envelope) {
4461
+ let parsed;
4462
+ try {
4463
+ parsed = JSON.parse(text2);
4464
+ } catch {
4465
+ throw fault("not valid JSON");
4466
+ }
4467
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw fault("the document must be an object");
4468
+ const document = parsed;
4469
+ if (document.version !== 1) throw fault("version must be 1");
4470
+ const entries = document.recipes;
4471
+ if (!Array.isArray(entries) || entries.length < 1) throw fault("recipes must be a non-empty array");
4472
+ if (entries.length > MAX_RECIPES) throw fault(`at most ${MAX_RECIPES} recipes may be declared`);
4473
+ const recipes = [];
4474
+ const seen = /* @__PURE__ */ new Set();
4475
+ entries.forEach((entry, index) => {
4476
+ const label = `recipe ${index + 1}`;
4477
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) throw fault(`${label} must be an object`);
4478
+ const row = entry;
4479
+ const unknown = Object.keys(row).filter((key) => !RECIPE_FIELDS.has(key));
4480
+ if (unknown.length) throw fault(`${label} has unsupported field ${unknown[0]}; the host owns image and resource limits`);
4481
+ if (typeof row.id !== "string" || !ID2.test(row.id)) throw fault(`${label} needs an id of 1 to 120 letters, digits, . _ : or -`);
4482
+ if (seen.has(row.id)) throw fault(`${label} repeats id ${row.id}`);
4483
+ seen.add(row.id);
4484
+ if (!Array.isArray(row.command) || row.command.length < 1 || row.command.some((part) => typeof part !== "string" || !part)) {
4485
+ throw fault(`${label} (${row.id}) needs command as a non-empty array of non-empty strings`);
4486
+ }
4487
+ const timeoutMs = row.timeoutMs ?? DEFAULT_TIMEOUT_MS;
4488
+ if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > MAX_TIMEOUT_MS) {
4489
+ throw fault(`${label} (${row.id}) timeoutMs must be an integer from 1 to ${MAX_TIMEOUT_MS}`);
4490
+ }
4491
+ const recipe2 = {
4492
+ id: row.id,
4493
+ command: [...row.command],
4494
+ timeoutMs,
4495
+ image: envelope.image,
4496
+ maxOutputBytes: envelope.maxOutputBytes,
4497
+ cpus: envelope.cpus,
4498
+ memory: envelope.memory,
4499
+ pids: envelope.pids
4500
+ };
4501
+ try {
4502
+ assertCodeBuildRecipe(recipe2);
4503
+ } catch (cause) {
4504
+ throw fault(`${label} (${row.id}) is not a runnable recipe: ${cause instanceof Error ? cause.message : String(cause)}`);
4505
+ }
4506
+ recipes.push(recipe2);
4507
+ });
4508
+ return recipes;
4509
+ }
4510
+ async function readRepositoryRecipes(baselineDir, envelope) {
4511
+ let text2;
4512
+ try {
4513
+ text2 = await (0, import_promises15.readFile)((0, import_node_path13.join)(baselineDir, REPOSITORY_RECIPES_FILE), "utf8");
4514
+ } catch (cause) {
4515
+ if (cause.code === "ENOENT") return null;
4516
+ throw cause;
4517
+ }
4518
+ return parseRepositoryRecipes(text2, envelope);
4519
+ }
4520
+ async function resolveCodeRecipes(baselineDir, release, envelope) {
4521
+ const declared = envelope ? await readRepositoryRecipes(baselineDir, envelope) : null;
4522
+ return declared ? { recipes: declared, source: "repository" } : { recipes: release, source: "release" };
4523
+ }
4524
+ function describeCodeRecipes(resolved) {
4525
+ const ids = resolved.recipes.map((recipe2) => recipe2.id).join(", ");
4526
+ return resolved.source === "repository" ? `Verification recipes: declared by the repository in ${REPOSITORY_RECIPES_FILE} \xB7 ${ids}` : `Verification recipes: release-owned (the repository declares none in ${REPOSITORY_RECIPES_FILE}) \xB7 ${ids}`;
4527
+ }
4528
+ async function sessionRecipesFor(workspace, options, resume) {
4529
+ const resolved = await resolveCodeRecipes(workspace.baselineDir, options.recipes, options.repositoryRecipes ?? null).catch(async (cause) => {
4530
+ await workspace.cleanup();
4531
+ throw cause;
4532
+ });
4533
+ return {
4534
+ ...resolved,
4535
+ buildPolicyDigest: digestRuntimeValue(JSON.stringify(resolved.recipes)),
4536
+ note: !resume && resolved.source === "repository" ? describeCodeRecipes(resolved) : null
4537
+ };
4538
+ }
4539
+
4420
4540
  // src/code-runtime-engine.ts
4421
4541
  var TheseusRuntimeEngine = class {
4422
4542
  constructor(options) {
@@ -4468,6 +4588,7 @@ var TheseusRuntimeEngine = class {
4468
4588
  control: this.options.control,
4469
4589
  ...this.options.localSource ? { localSource: this.options.localSource } : {}
4470
4590
  });
4591
+ const resolvedRecipes = await sessionRecipesFor(workspace, this.options, resume);
4471
4592
  const abort = new AbortController(), startGate = codeRuntimeAcknowledgementGate(abort.signal);
4472
4593
  const conversationRefs = [];
4473
4594
  const active = {
@@ -4476,6 +4597,8 @@ var TheseusRuntimeEngine = class {
4476
4597
  conversationRefs,
4477
4598
  acknowledged: false,
4478
4599
  startGate,
4600
+ recipes: resolvedRecipes.recipes,
4601
+ buildPolicyDigest: resolvedRecipes.buildPolicyDigest,
4479
4602
  role: metadata.role,
4480
4603
  readOnly: metadata.readOnly,
4481
4604
  title: metadata.title,
@@ -4493,6 +4616,7 @@ var TheseusRuntimeEngine = class {
4493
4616
  done: Promise.resolve(null)
4494
4617
  };
4495
4618
  this.#active.set(command.sessionId, active);
4619
+ if (resolvedRecipes.note) await this.#event(command, { type: "message", actor: "system", body: resolvedRecipes.note }, conversationRefs);
4496
4620
  if (requestedLocal) {
4497
4621
  await this.#event(command, {
4498
4622
  type: "message",
@@ -4528,7 +4652,7 @@ var TheseusRuntimeEngine = class {
4528
4652
  const active = await this.#takeOver(command, "pursue requires an active Code session");
4529
4653
  active.done = startGoalPursuit({
4530
4654
  spec,
4531
- recipes: this.options.recipes,
4655
+ recipes: active.recipes,
4532
4656
  recipeExecutor: this.options.recipeExecutor ?? createContainerRecipeExecutor(this.options.engine),
4533
4657
  workspace: active.workspace,
4534
4658
  baseCommitSha: active.baseCommitSha,
@@ -4607,7 +4731,7 @@ var TheseusRuntimeEngine = class {
4607
4731
  async #runAttempt(command, metadata, active) {
4608
4732
  const lease = fakeCodeLease(command, metadata);
4609
4733
  const broker = this.#observed(command, active, createCodeRuntimeToolBroker({
4610
- recipes: this.options.recipes,
4734
+ recipes: active.recipes,
4611
4735
  engine: this.options.engine,
4612
4736
  recipeAuthorization: this.options.recipeAuthorization
4613
4737
  }, lease, metadata.role));
@@ -4633,7 +4757,7 @@ var TheseusRuntimeEngine = class {
4633
4757
  // A review-role session is read-only and still runs the proof; a planner
4634
4758
  // marked read-only by its payload runs nothing.
4635
4759
  recipes: metadata.role === "review" || !metadata.readOnly,
4636
- recipeIds: this.options.recipes.map((recipe2) => recipe2.id),
4760
+ recipeIds: active.recipes.map((recipe2) => recipe2.id),
4637
4761
  ...extraSkills.length ? { extraSkills } : {}
4638
4762
  });
4639
4763
  const closing = result.finalText.trim();
@@ -4964,12 +5088,12 @@ function chooseStrategy(signals = {}) {
4964
5088
  var feedbackIsActionable = actionable;
4965
5089
 
4966
5090
  // src/code-recipe-dependencies.ts
4967
- var import_promises15 = require("fs/promises");
4968
- var import_node_path13 = require("path");
5091
+ var import_promises16 = require("fs/promises");
5092
+ var import_node_path14 = require("path");
4969
5093
  var RESERVED_MOUNTS = /* @__PURE__ */ new Set(["node_modules", "dist", "coverage"]);
4970
5094
  function withRecipeDependencies(executor, dependencies) {
4971
5095
  const mountAs = dependencies.mountAs ?? "node_modules";
4972
- if (!(0, import_node_path13.isAbsolute)(dependencies.source)) {
5096
+ if (!(0, import_node_path14.isAbsolute)(dependencies.source)) {
4973
5097
  throw new TypeError("recipe dependency source must be an absolute path");
4974
5098
  }
4975
5099
  if (!RESERVED_MOUNTS.has(mountAs)) {
@@ -4977,24 +5101,24 @@ function withRecipeDependencies(executor, dependencies) {
4977
5101
  }
4978
5102
  return {
4979
5103
  run: async (input) => {
4980
- const target = (0, import_node_path13.join)(input.workspaceDir, mountAs);
5104
+ const target = (0, import_node_path14.join)(input.workspaceDir, mountAs);
4981
5105
  let linked = false;
4982
5106
  try {
4983
- const existing = await (0, import_promises15.lstat)(target).catch(() => null);
5107
+ const existing = await (0, import_promises16.lstat)(target).catch(() => null);
4984
5108
  if (!existing) {
4985
- await (0, import_promises15.symlink)(dependencies.source, target, "dir");
5109
+ await (0, import_promises16.symlink)(dependencies.source, target, "dir");
4986
5110
  linked = true;
4987
5111
  }
4988
5112
  return await executor.run(input);
4989
5113
  } finally {
4990
- if (linked) await (0, import_promises15.rm)(target, { force: true, recursive: false }).catch(() => void 0);
5114
+ if (linked) await (0, import_promises16.rm)(target, { force: true, recursive: false }).catch(() => void 0);
4991
5115
  }
4992
5116
  }
4993
5117
  };
4994
5118
  }
4995
5119
  async function installedDependencies(repoRoot) {
4996
- const source = (0, import_node_path13.join)(repoRoot, "node_modules");
4997
- const info = await (0, import_promises15.lstat)(source).catch(() => null);
5120
+ const source = (0, import_node_path14.join)(repoRoot, "node_modules");
5121
+ const info = await (0, import_promises16.lstat)(source).catch(() => null);
4998
5122
  return info?.isDirectory() ? { source } : null;
4999
5123
  }
5000
5124
  // Annotate the CommonJS export names for ESM import in node:
@@ -5006,6 +5130,7 @@ async function installedDependencies(repoRoot) {
5006
5130
  DecompositionError,
5007
5131
  MAX_MEMORY_BODY,
5008
5132
  MEASURED_PREMIUM,
5133
+ REPOSITORY_RECIPES_FILE,
5009
5134
  SYSTEM_PROMPT_FOR,
5010
5135
  TheseusRuntimeEngine,
5011
5136
  V1_SYSTEM_PROMPT,
@@ -5027,6 +5152,7 @@ async function installedDependencies(repoRoot) {
5027
5152
  createCodeToolBroker,
5028
5153
  createCodeWorkspaceCheckpoint,
5029
5154
  createContainerRecipeExecutor,
5155
+ describeCodeRecipes,
5030
5156
  describePatchFailure,
5031
5157
  digestStagedWorkspace,
5032
5158
  feedbackIsActionable,
@@ -5041,16 +5167,19 @@ async function installedDependencies(repoRoot) {
5041
5167
  materializeGitTree,
5042
5168
  outcomeCloses,
5043
5169
  outcomeMemory,
5170
+ parseRepositoryRecipes,
5044
5171
  patchPaths,
5045
5172
  planReachCollisions,
5046
5173
  prepareRuntimeCheckpoint,
5047
5174
  racedAttempt,
5048
5175
  readOnlyNotice,
5176
+ readRepositoryRecipes,
5049
5177
  recallAbout,
5050
5178
  registeredFiles,
5051
5179
  renderMemories,
5052
5180
  renderOutcome,
5053
5181
  resolveCodePath,
5182
+ resolveCodeRecipes,
5054
5183
  restoreCodeWorkspaceCheckpoint,
5055
5184
  runCodeAgent,
5056
5185
  runCodeAgentAttempt,
@@ -5063,6 +5192,7 @@ async function installedDependencies(repoRoot) {
5063
5192
  safeWorkspaceLabel,
5064
5193
  selectContainerEngine,
5065
5194
  selectWinner,
5195
+ sessionRecipesFor,
5066
5196
  sessionSkillsFor,
5067
5197
  stageWorkspace,
5068
5198
  stageWorkspacePair,