@miraland-labs/conduit-bridge 0.16.160 → 0.16.161

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.
@@ -40,19 +40,19 @@ export async function ensureLandCommit(input) {
40
40
  const listPending = input.listUncommittedPaths ?? ((workspace) => uncommittedPaths(workspace));
41
41
  const commitPaths = input.commitPaths ?? commitScopedPaths;
42
42
  const ahead = await countAhead(input.workspace, base);
43
- if (ahead !== null && ahead > 0) {
44
- return { kind: "already_landed", headCommit: await readHead(input.workspace) };
45
- }
46
43
  const pending = filterPathsInScope(await listPending(input.workspace), input.spec.change_scope ?? []);
47
- if (!pending.length) {
48
- throw new AgentNoLandCommitError(base);
44
+ if (pending.length) {
45
+ await commitPaths(input.workspace, pending);
46
+ const afterAhead = await countAhead(input.workspace, base);
47
+ if (afterAhead === 0) {
48
+ throw new AgentNoLandCommitError(base);
49
+ }
50
+ return { kind: "committed", headCommit: await readHead(input.workspace), paths: pending };
49
51
  }
50
- await commitPaths(input.workspace, pending);
51
- const afterAhead = await countAhead(input.workspace, base);
52
- if (afterAhead === 0) {
53
- throw new AgentNoLandCommitError(base);
52
+ if (ahead !== null && ahead > 0) {
53
+ return { kind: "already_landed", headCommit: await readHead(input.workspace) };
54
54
  }
55
- return { kind: "committed", headCommit: await readHead(input.workspace), paths: pending };
55
+ throw new AgentNoLandCommitError(base);
56
56
  }
57
57
  async function currentBranch(workspace) {
58
58
  const { stdout } = await execFileAsync("git", ["-C", workspace, "branch", "--show-current"], {
@@ -11,6 +11,7 @@ import { boundedTail, runBoundedVerificationCommand } from "./ensure-test-eviden
11
11
  import { createAttemptWorktree, removeAttemptWorktree } from "./attempt-worktree.js";
12
12
  import { buildWorkspaceBrief, ensureCommitAvailable, normalizeRepositoryUrl } from "./brief.js";
13
13
  import { headCommitOrNull } from "./git.js";
14
+ import { ConduitRequestError } from "./client.js";
14
15
  import { learnDriverFuel, resolveAssignmentModel, changedPathsSince, runDeliveryVerificationGates, discardWorktreeWrites } from "./execution.js";
15
16
  import { DRIVERS, execute, extractAgentReportJsonText, parseJsonObjectCandidate } from "./driver.js";
16
17
  import { pickDriverForClaim, resolveDriverFuel, supportsReadOnlyDiagnosis } from "./drivers.js";
@@ -773,13 +774,24 @@ export async function executeNextInvestigation(client, config, workspace, brief,
773
774
  const fingerprintBefore = await workspaceFingerprint(workspace);
774
775
  let attemptWorkspace = null;
775
776
  const runId = investigationRunId(assignment.id);
776
- // Renew inside the lease for as long as the driver runs; a renewal the control plane refuses
777
- // means the run is already over for it, and the settle below reports that honestly.
777
+ // Renew inside the lease for as long as the driver runs. A terminal refusal (`invalid_lease`)
778
+ // means the control plane already took the run back — abort the driver and do not settle.
779
+ const runAbort = new AbortController();
780
+ let leaseTakenBack = false;
778
781
  const renewTimer = setInterval(() => {
779
782
  void client.request(`/runner/v1/investigations/${assignment.id}/renew`, {
780
783
  method: "POST",
781
784
  body: JSON.stringify({ lease_token: leaseToken }),
782
- }).catch((error) => console.error(`Investigation ${assignment.id} lease renewal failed: ${redactSecrets(error instanceof Error ? error.message : "unknown")}`));
785
+ }).catch((error) => {
786
+ if (error instanceof ConduitRequestError && error.code === "invalid_lease") {
787
+ leaseTakenBack = true;
788
+ clearInterval(renewTimer);
789
+ runAbort.abort();
790
+ console.error(`Investigation ${assignment.id} stopped: lease is no longer valid`);
791
+ return;
792
+ }
793
+ console.error(`Investigation ${assignment.id} lease renewal failed: ${redactSecrets(error instanceof Error ? error.message : "unknown")}`);
794
+ });
783
795
  }, options.renewIntervalMs ?? INVESTIGATION_RENEW_INTERVAL_MS);
784
796
  renewTimer.unref?.();
785
797
  let heartbeatRunning = false;
@@ -853,7 +865,10 @@ export async function executeNextInvestigation(client, config, workspace, brief,
853
865
  fuel,
854
866
  timeoutMs: Math.min(timeoutMs ?? assignment.budget.max_duration_ms, assignment.budget.max_duration_ms),
855
867
  maxTurns: config.maxTurns,
868
+ signal: runAbort.signal,
856
869
  });
870
+ if (leaseTakenBack || runAbort.signal.aborted)
871
+ return true;
857
872
  await learnDriverFuel(config, driver.name, investigationFuel, result);
858
873
  if (result.status === "failed") {
859
874
  const message = result.error ?? "Investigation run failed";
@@ -927,6 +942,9 @@ export async function executeNextInvestigation(client, config, workspace, brief,
927
942
  console.log(`Investigation ${assignment.id} settled with a bounded brief.`);
928
943
  }
929
944
  catch (error) {
945
+ if (leaseTakenBack || runAbort.signal.aborted) {
946
+ return true;
947
+ }
930
948
  const message = error instanceof Error ? error.message : "investigation_failed";
931
949
  await settle(client, assignment.id, {
932
950
  lease_token: leaseToken,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miraland-labs/conduit-bridge",
3
- "version": "0.16.160",
3
+ "version": "0.16.161",
4
4
  "description": "Conduit Bridge CLI \u2014 join, connect, disconnect, multi-driver lanes, and run Claude Code / Codex / Cursor / OpenCode / Pi / Kiro / Antigravity / Grok Build agents for a Conduit organization",
5
5
  "type": "module",
6
6
  "bin": {