@ai-development-environment/control-agent 0.0.103 → 0.0.105

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.
Files changed (2) hide show
  1. package/dist/control-agent.js +103 -23
  2. package/package.json +1 -1
@@ -14455,8 +14455,22 @@ async function updateBaseBranchAfterFetch(folder, baseBranch, timeoutMs, signal)
14455
14455
  return false;
14456
14456
  }
14457
14457
  }
14458
- var fetchCodebase = async (payload, timeoutMs, signal) => {
14458
+ var fetchCodebase = async (payload, timeoutMs, signal, onLog, context) => {
14459
14459
  const input = codebaseJobPayload(payload);
14460
+ let sequence = 0;
14461
+ const log = async (message) => {
14462
+ try {
14463
+ await onLog({
14464
+ sequence: sequence++,
14465
+ stream: "SYSTEM",
14466
+ message,
14467
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
14468
+ });
14469
+ } catch (error) {
14470
+ console.error("Could not report fetch progress:", cleanError2(error));
14471
+ }
14472
+ };
14473
+ await log("Checking repository before fetching");
14460
14474
  const beforeResult = await inspectCodebaseProcess(
14461
14475
  input.folder,
14462
14476
  Math.min(timeoutMs, 3e4),
@@ -14469,6 +14483,8 @@ var fetchCodebase = async (payload, timeoutMs, signal) => {
14469
14483
  return { ...successfulProcess5, exitCode: 1, snapshot: before };
14470
14484
  }
14471
14485
  let result;
14486
+ const fetchAttemptedAt = (/* @__PURE__ */ new Date()).toISOString();
14487
+ await log("Fetching remote branches from origin");
14472
14488
  try {
14473
14489
  result = await git(input.folder, ["fetch", "origin"], timeoutMs, signal);
14474
14490
  } catch (error) {
@@ -14476,12 +14492,16 @@ var fetchCodebase = async (payload, timeoutMs, signal) => {
14476
14492
  throw error;
14477
14493
  }
14478
14494
  if (result.exitCode === 0 && input.keepBaseBranchUpToDate && input.baseBranch) {
14479
- await updateBaseBranchAfterFetch(
14495
+ await log("Updating the base branch where it can be fast-forwarded");
14496
+ const updated = await updateBaseBranchAfterFetch(
14480
14497
  input.folder,
14481
14498
  input.baseBranch,
14482
14499
  timeoutMs,
14483
14500
  signal
14484
14501
  );
14502
+ await log(
14503
+ updated ? "Base branch updated" : "Base branch left unchanged because it could not be safely fast-forwarded"
14504
+ );
14485
14505
  }
14486
14506
  const afterResult = await inspectCodebaseProcess(
14487
14507
  input.folder,
@@ -14496,12 +14516,34 @@ var fetchCodebase = async (payload, timeoutMs, signal) => {
14496
14516
  } else if (!snapshot.fetchedAt) {
14497
14517
  snapshot.fetchedAt = (/* @__PURE__ */ new Date()).toISOString();
14498
14518
  }
14519
+ if (result.exitCode !== 0) {
14520
+ await log(snapshot.error || "Git fetch failed");
14521
+ }
14522
+ let worktreesRefreshedAt;
14523
+ let worktreeRefreshError;
14524
+ if (input.codebaseId && context?.refreshFetchedCodebase) {
14525
+ await log("Refreshing worktree branches and status");
14526
+ try {
14527
+ worktreesRefreshedAt = await context.refreshFetchedCodebase({
14528
+ codebaseId: input.codebaseId,
14529
+ snapshot,
14530
+ fetchAttemptedAt,
14531
+ fetchError: result.exitCode === 0 ? null : snapshot.error
14532
+ });
14533
+ await log("Worktree branches and status refreshed");
14534
+ } catch (error) {
14535
+ worktreeRefreshError = cleanError2(error);
14536
+ await log(`Could not refresh worktrees: ${worktreeRefreshError}`);
14537
+ }
14538
+ }
14499
14539
  return {
14500
14540
  exitCode: result.exitCode,
14501
14541
  signal: result.signal,
14502
14542
  timedOut: result.timedOut,
14503
- cancelled: result.cancelled,
14504
- snapshot
14543
+ cancelled: result.cancelled || signal.aborted,
14544
+ snapshot,
14545
+ ...worktreesRefreshedAt ? { worktreesRefreshedAt } : {},
14546
+ ...worktreeRefreshError ? { worktreeRefreshError } : {}
14505
14547
  };
14506
14548
  };
14507
14549
  async function validateGitCodebase(folder, expectedOrigin, timeoutMs, signal) {
@@ -19415,6 +19457,50 @@ var handlers = {
19415
19457
  [TAILSCALE_SERVE_REMOVE_JOB_KIND]: removeTailscaleServe
19416
19458
  };
19417
19459
 
19460
+ // src/refresh-fetched-codebase.ts
19461
+ async function refreshFetchedCodebase(client2, input, timeoutMs, signal) {
19462
+ signal.throwIfAborted();
19463
+ const registration = (await client2.agentCodebases()).find(
19464
+ (codebase) => codebase.id === input.codebaseId
19465
+ );
19466
+ if (!registration) throw new Error("Codebase is no longer registered");
19467
+ if (input.snapshot.availability !== "AVAILABLE") {
19468
+ throw new Error(input.snapshot.error || "Codebase is unavailable");
19469
+ }
19470
+ signal.throwIfAborted();
19471
+ const inventory = await discoverWorktrees(
19472
+ input.snapshot.folder,
19473
+ new Map(
19474
+ registration.worktrees.map((worktree) => [
19475
+ worktree.gitDirectory,
19476
+ worktree.baseBranchOverride
19477
+ ])
19478
+ ),
19479
+ registration.defaultBranch,
19480
+ Math.min(timeoutMs, 3e4),
19481
+ signal
19482
+ );
19483
+ if (!inventory.complete) {
19484
+ throw new Error("Worktree inventory refresh was incomplete");
19485
+ }
19486
+ signal.throwIfAborted();
19487
+ await client2.reportCodebaseStatuses([
19488
+ { codebaseId: input.codebaseId, snapshot: input.snapshot }
19489
+ ]);
19490
+ signal.throwIfAborted();
19491
+ await client2.reportWorktrees([
19492
+ {
19493
+ codebaseId: input.codebaseId,
19494
+ ...inventory,
19495
+ fetchedAt: input.snapshot.fetchedAt,
19496
+ fetchAttemptedAt: input.fetchAttemptedAt,
19497
+ fetchError: input.fetchError
19498
+ }
19499
+ ]);
19500
+ signal.throwIfAborted();
19501
+ return (/* @__PURE__ */ new Date()).toISOString();
19502
+ }
19503
+
19418
19504
  // src/repository-coordinator.ts
19419
19505
  var RepositoryCoordinator = class {
19420
19506
  tails = /* @__PURE__ */ new Map();
@@ -19492,6 +19578,12 @@ var JobExecutor = class {
19492
19578
  {
19493
19579
  agentId: claimed.agentId,
19494
19580
  reportWorktreeActivity: (input) => this.client.reportWorktreeActivity(input),
19581
+ refreshFetchedCodebase: (input) => refreshFetchedCodebase(
19582
+ this.client,
19583
+ input,
19584
+ claimed.timeoutSeconds * 1e3,
19585
+ controller.signal
19586
+ ),
19495
19587
  reportBuildProgress: (input) => this.client.reportBuildProgress(input),
19496
19588
  appendBuildLogChunks: (buildId, chunks) => this.client.appendBuildLogChunks(buildId, chunks),
19497
19589
  uploadBuildArtifact: (input) => this.client.uploadBuildArtifact(input),
@@ -19558,11 +19650,9 @@ var CodebaseMonitor = class {
19558
19650
  this.intervalMs = configuration.refreshIntervalSeconds * 1e3;
19559
19651
  }
19560
19652
  const codebases = configuration.codebases;
19561
- const reports = [];
19562
- const worktreeReports = [];
19563
19653
  for (let index = 0; index < codebases.length; index += CONCURRENCY2) {
19564
19654
  const batch = codebases.slice(index, index + CONCURRENCY2);
19565
- const results = await Promise.all(
19655
+ await Promise.all(
19566
19656
  batch.map(
19567
19657
  (codebase) => this.repositoryCoordinator.run(codebase.id, async () => {
19568
19658
  let snapshot = await inspectCodebase(
@@ -19634,31 +19724,21 @@ var CodebaseMonitor = class {
19634
19724
  };
19635
19725
  fetchError ??= error instanceof Error ? error.message.slice(0, 2e3) : String(error);
19636
19726
  }
19637
- return {
19638
- codebaseReport: { codebaseId: codebase.id, snapshot },
19639
- worktreeReport: {
19727
+ await this.client.reportCodebaseStatuses([
19728
+ { codebaseId: codebase.id, snapshot }
19729
+ ]);
19730
+ await this.client.reportWorktrees([
19731
+ {
19640
19732
  codebaseId: codebase.id,
19641
19733
  ...inventory,
19642
19734
  fetchedAt: snapshot.fetchedAt,
19643
19735
  fetchAttemptedAt,
19644
19736
  fetchError
19645
19737
  }
19646
- };
19738
+ ]);
19647
19739
  })
19648
19740
  )
19649
19741
  );
19650
- reports.push(...results.map((result) => result.codebaseReport));
19651
- worktreeReports.push(...results.map((result) => result.worktreeReport));
19652
- }
19653
- for (let index = 0; index < reports.length; index += 500) {
19654
- await this.client.reportCodebaseStatuses(
19655
- reports.slice(index, index + 500)
19656
- );
19657
- }
19658
- for (let index = 0; index < worktreeReports.length; index += 100) {
19659
- await this.client.reportWorktrees(
19660
- worktreeReports.slice(index, index + 100)
19661
- );
19662
19742
  }
19663
19743
  } catch (error) {
19664
19744
  if (!signal.aborted) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-development-environment/control-agent",
3
- "version": "0.0.103",
3
+ "version": "0.0.105",
4
4
  "description": "Control agent for the AI Development Environment",
5
5
  "license": "MIT",
6
6
  "repository": {