@ai-development-environment/control-agent 0.0.137 → 0.0.138
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/control-agent.js +382 -186
- package/package.json +1 -1
package/dist/control-agent.js
CHANGED
|
@@ -7130,25 +7130,38 @@ var AgentGraphQLClient = class {
|
|
|
7130
7130
|
);
|
|
7131
7131
|
}
|
|
7132
7132
|
async uploadBuildArtifact(input) {
|
|
7133
|
+
const timeoutMs = input.timeoutMs ?? this.requestTimeoutMs;
|
|
7134
|
+
if (timeoutMs <= 0)
|
|
7135
|
+
throw new DOMException("Artifact upload timed out", "TimeoutError");
|
|
7136
|
+
const timeout = AbortSignal.timeout(timeoutMs);
|
|
7137
|
+
const signal2 = input.signal ? AbortSignal.any([input.signal, timeout]) : timeout;
|
|
7138
|
+
signal2.throwIfAborted();
|
|
7133
7139
|
const information = await stat(input.path);
|
|
7134
|
-
|
|
7135
|
-
|
|
7136
|
-
|
|
7137
|
-
|
|
7138
|
-
|
|
7139
|
-
|
|
7140
|
-
"
|
|
7141
|
-
|
|
7142
|
-
|
|
7143
|
-
|
|
7144
|
-
|
|
7145
|
-
|
|
7146
|
-
|
|
7147
|
-
|
|
7148
|
-
|
|
7149
|
-
|
|
7150
|
-
|
|
7140
|
+
signal2.throwIfAborted();
|
|
7141
|
+
const source = createReadStream(input.path);
|
|
7142
|
+
try {
|
|
7143
|
+
const response = await fetch(
|
|
7144
|
+
`${this.server}/api/build-artifact-uploads/${encodeURIComponent(input.uploadId)}`,
|
|
7145
|
+
{
|
|
7146
|
+
method: "POST",
|
|
7147
|
+
headers: mergeHeaders(this.headers, {
|
|
7148
|
+
...this.credential ? { authorization: `Bearer ${this.credential}` } : {},
|
|
7149
|
+
"content-length": String(information.size),
|
|
7150
|
+
"content-type": input.contentType,
|
|
7151
|
+
"x-artifact-filename": encodeURIComponent(input.filename)
|
|
7152
|
+
}),
|
|
7153
|
+
body: Readable.toWeb(source),
|
|
7154
|
+
duplex: "half",
|
|
7155
|
+
signal: signal2
|
|
7156
|
+
}
|
|
7151
7157
|
);
|
|
7158
|
+
if (!response.ok) {
|
|
7159
|
+
throw new Error(
|
|
7160
|
+
`Artifact upload failed: HTTP ${response.status} ${await response.text()}`
|
|
7161
|
+
);
|
|
7162
|
+
}
|
|
7163
|
+
} finally {
|
|
7164
|
+
source.destroy();
|
|
7152
7165
|
}
|
|
7153
7166
|
}
|
|
7154
7167
|
artifactTransferHeaders(values = {}) {
|
|
@@ -7471,12 +7484,12 @@ var AgentGraphQLClient = class {
|
|
|
7471
7484
|
);
|
|
7472
7485
|
return data.beginRunAttempt;
|
|
7473
7486
|
}
|
|
7474
|
-
updateRunAttemptNativeId(attemptId, nativeId, providerVersion) {
|
|
7487
|
+
updateRunAttemptNativeId(attemptId, nativeId, providerVersion, sessionInfo) {
|
|
7475
7488
|
return this.request(
|
|
7476
|
-
`mutation UpdateRunAttemptNativeId($attemptId: ID!, $nativeId: String!, $providerVersion: String) {
|
|
7477
|
-
updateRunAttemptNativeId(attemptId: $attemptId, nativeId: $nativeId, providerVersion: $providerVersion) { id nativeId }
|
|
7489
|
+
`mutation UpdateRunAttemptNativeId($attemptId: ID!, $nativeId: String!, $providerVersion: String, $sessionInfo: RunSessionInfoInput) {
|
|
7490
|
+
updateRunAttemptNativeId(attemptId: $attemptId, nativeId: $nativeId, providerVersion: $providerVersion, sessionInfo: $sessionInfo) { id nativeId }
|
|
7478
7491
|
}`,
|
|
7479
|
-
{ attemptId, nativeId, providerVersion }
|
|
7492
|
+
{ attemptId, nativeId, providerVersion, sessionInfo }
|
|
7480
7493
|
);
|
|
7481
7494
|
}
|
|
7482
7495
|
appendRunEvents(runId, attemptId, events) {
|
|
@@ -11552,7 +11565,7 @@ function tailscaleServeRemovePayload(value) {
|
|
|
11552
11565
|
// package.json
|
|
11553
11566
|
var package_default = {
|
|
11554
11567
|
name: "@ai-development-environment/control-agent",
|
|
11555
|
-
version: "0.0.
|
|
11568
|
+
version: "0.0.138",
|
|
11556
11569
|
description: "Control agent for the AI Development Environment",
|
|
11557
11570
|
license: "MIT",
|
|
11558
11571
|
repository: {
|
|
@@ -12060,6 +12073,17 @@ function repairToolPath(options = {}) {
|
|
|
12060
12073
|
|
|
12061
12074
|
// src/runs/codex-adapter.ts
|
|
12062
12075
|
var execFileAsync = promisify(execFile);
|
|
12076
|
+
async function codexSessionInfo(thread, cwd) {
|
|
12077
|
+
const path = typeof thread.path === "string" && thread.path ? thread.path : await findCodexSessionFile(
|
|
12078
|
+
String(thread.id),
|
|
12079
|
+
homedir4(),
|
|
12080
|
+
process.env.CODEX_HOME
|
|
12081
|
+
).catch(() => null);
|
|
12082
|
+
return {
|
|
12083
|
+
workingDirectory: typeof thread.cwd === "string" && thread.cwd ? thread.cwd : cwd,
|
|
12084
|
+
...path ? { nativeTranscriptPath: path } : {}
|
|
12085
|
+
};
|
|
12086
|
+
}
|
|
12063
12087
|
function codexAppServerArgs(modelCatalogPath) {
|
|
12064
12088
|
return [
|
|
12065
12089
|
"app-server",
|
|
@@ -12453,7 +12477,8 @@ var CodexAdapter = class {
|
|
|
12453
12477
|
throw new Error("Codex did not return a thread ID");
|
|
12454
12478
|
await callbacks.onNativeId(
|
|
12455
12479
|
nativeId,
|
|
12456
|
-
typeof thread.cliVersion === "string" ? thread.cliVersion : void 0
|
|
12480
|
+
typeof thread.cliVersion === "string" ? thread.cliVersion : void 0,
|
|
12481
|
+
await codexSessionInfo(thread, cwd)
|
|
12457
12482
|
);
|
|
12458
12483
|
let turnId = "";
|
|
12459
12484
|
let stopReason = null;
|
|
@@ -12618,6 +12643,7 @@ var CodexAdapter = class {
|
|
|
12618
12643
|
const thread = asRecord(value);
|
|
12619
12644
|
const updatedAtKey = String(thread.updatedAt ?? "");
|
|
12620
12645
|
const cached = this.hydrationCache.get(String(thread.id));
|
|
12646
|
+
const sessionInfo = await codexSessionInfo(thread, worktree.folder);
|
|
12621
12647
|
let history = {};
|
|
12622
12648
|
const active = asRecord(thread.status).type === "active";
|
|
12623
12649
|
if (active) this.hydrationCache.delete(String(thread.id));
|
|
@@ -12640,11 +12666,7 @@ var CodexAdapter = class {
|
|
|
12640
12666
|
} catch {
|
|
12641
12667
|
}
|
|
12642
12668
|
try {
|
|
12643
|
-
const path =
|
|
12644
|
-
String(thread.id),
|
|
12645
|
-
homedir4(),
|
|
12646
|
-
process.env.CODEX_HOME
|
|
12647
|
-
);
|
|
12669
|
+
const path = sessionInfo.nativeTranscriptPath;
|
|
12648
12670
|
if (path)
|
|
12649
12671
|
Object.assign(
|
|
12650
12672
|
history,
|
|
@@ -12671,7 +12693,8 @@ var CodexAdapter = class {
|
|
|
12671
12693
|
branch: firstString(asRecord(thread.gitInfo).branch) || worktree.branch || void 0,
|
|
12672
12694
|
createdAt: thread.createdAt ? new Date(Number(thread.createdAt) * 1e3).toISOString() : void 0,
|
|
12673
12695
|
updatedAt: thread.updatedAt ? new Date(Number(thread.updatedAt) * 1e3).toISOString() : void 0,
|
|
12674
|
-
rawMetadata: thread
|
|
12696
|
+
rawMetadata: thread,
|
|
12697
|
+
sessionInfo
|
|
12675
12698
|
});
|
|
12676
12699
|
}
|
|
12677
12700
|
cursor = typeof page.nextCursor === "string" ? page.nextCursor : null;
|
|
@@ -42895,7 +42918,15 @@ var ClaudeAdapter = class {
|
|
|
42895
42918
|
if (sessionId && sessionId !== nativeId) {
|
|
42896
42919
|
nativeId = sessionId;
|
|
42897
42920
|
const version = record.subtype === "init" && typeof record.claude_code_version === "string" ? record.claude_code_version : void 0;
|
|
42898
|
-
await
|
|
42921
|
+
const path = await findClaudeSessionFile(
|
|
42922
|
+
sessionId,
|
|
42923
|
+
homedir5(),
|
|
42924
|
+
process.env.CLAUDE_CONFIG_DIR
|
|
42925
|
+
).catch(() => null);
|
|
42926
|
+
await callbacks.onNativeId(sessionId, version, {
|
|
42927
|
+
workingDirectory: typeof record.cwd === "string" && record.cwd ? record.cwd : input.run.worktree.folder,
|
|
42928
|
+
...path ? { nativeTranscriptPath: path } : {}
|
|
42929
|
+
});
|
|
42899
42930
|
}
|
|
42900
42931
|
const messageText = firstString(
|
|
42901
42932
|
record.message ?? record.result ?? record.summary
|
|
@@ -42976,16 +43007,20 @@ var ClaudeAdapter = class {
|
|
|
42976
43007
|
const lastModifiedKey = `${session.lastModified ?? ""}:${session.fileSize ?? ""}`;
|
|
42977
43008
|
const cached = this.hydrationCache.get(session.sessionId);
|
|
42978
43009
|
let history = {};
|
|
43010
|
+
const path = await findClaudeSessionFile(
|
|
43011
|
+
session.sessionId,
|
|
43012
|
+
homedir5(),
|
|
43013
|
+
process.env.CLAUDE_CONFIG_DIR
|
|
43014
|
+
).catch(() => null);
|
|
43015
|
+
const sessionInfo = {
|
|
43016
|
+
workingDirectory: session.cwd || worktree.folder,
|
|
43017
|
+
...path ? { nativeTranscriptPath: path } : {}
|
|
43018
|
+
};
|
|
42979
43019
|
if (cached && cached.lastModified === lastModifiedKey) {
|
|
42980
43020
|
history = cached.history;
|
|
42981
43021
|
} else {
|
|
42982
43022
|
let transcript = [];
|
|
42983
43023
|
try {
|
|
42984
|
-
const path = await findClaudeSessionFile(
|
|
42985
|
-
session.sessionId,
|
|
42986
|
-
homedir5(),
|
|
42987
|
-
process.env.CLAUDE_CONFIG_DIR
|
|
42988
|
-
);
|
|
42989
43024
|
if (path) transcript = await readClaudeTranscript(path);
|
|
42990
43025
|
history = claudeTranscriptMetadata(transcript);
|
|
42991
43026
|
} catch {
|
|
@@ -43016,7 +43051,8 @@ var ClaudeAdapter = class {
|
|
|
43016
43051
|
branch: session.gitBranch || worktree.branch || void 0,
|
|
43017
43052
|
createdAt: session.createdAt ? new Date(session.createdAt).toISOString() : void 0,
|
|
43018
43053
|
updatedAt: new Date(session.lastModified).toISOString(),
|
|
43019
|
-
rawMetadata: session
|
|
43054
|
+
rawMetadata: session,
|
|
43055
|
+
sessionInfo
|
|
43020
43056
|
});
|
|
43021
43057
|
}
|
|
43022
43058
|
}
|
|
@@ -43788,6 +43824,7 @@ function captureCommand(options) {
|
|
|
43788
43824
|
let timedOut = false;
|
|
43789
43825
|
let cancelled = false;
|
|
43790
43826
|
let settled = false;
|
|
43827
|
+
let terminating = false;
|
|
43791
43828
|
let killTimer = null;
|
|
43792
43829
|
const detached = process.platform !== "win32";
|
|
43793
43830
|
const child = spawn3(options.command, options.args, {
|
|
@@ -43842,10 +43879,11 @@ function captureCommand(options) {
|
|
|
43842
43879
|
}
|
|
43843
43880
|
};
|
|
43844
43881
|
const terminate2 = () => {
|
|
43845
|
-
if (
|
|
43882
|
+
if (settled || terminating) return;
|
|
43883
|
+
terminating = true;
|
|
43846
43884
|
sendSignal("SIGTERM");
|
|
43847
43885
|
killTimer = setTimeout(() => {
|
|
43848
|
-
if (
|
|
43886
|
+
if (!settled) sendSignal("SIGKILL");
|
|
43849
43887
|
}, 5e3);
|
|
43850
43888
|
killTimer.unref();
|
|
43851
43889
|
};
|
|
@@ -45298,21 +45336,129 @@ import {
|
|
|
45298
45336
|
|
|
45299
45337
|
// src/repository-coordinator.ts
|
|
45300
45338
|
var RepositoryCoordinator = class {
|
|
45301
|
-
|
|
45302
|
-
|
|
45303
|
-
|
|
45304
|
-
|
|
45305
|
-
|
|
45306
|
-
|
|
45339
|
+
queues = /* @__PURE__ */ new Map();
|
|
45340
|
+
run(key, task, signal2) {
|
|
45341
|
+
return this.enqueue(key, "exclusive", () => task(), signal2);
|
|
45342
|
+
}
|
|
45343
|
+
/** Only read-only worktree inspection jobs may overlap reconciliation. */
|
|
45344
|
+
runInspection(key, task, signal2) {
|
|
45345
|
+
return this.enqueue(key, "inspection", () => task(), signal2);
|
|
45346
|
+
}
|
|
45347
|
+
/** Keep reconciliation and its reports ordered with all user mutations. */
|
|
45348
|
+
runReconciliation(key, task, signal2) {
|
|
45349
|
+
return this.enqueue(
|
|
45350
|
+
key,
|
|
45351
|
+
"reconciliation",
|
|
45352
|
+
(queue) => task({
|
|
45353
|
+
runExclusive: (exclusiveTask) => this.runReconciliationExclusive(key, queue, exclusiveTask)
|
|
45354
|
+
}),
|
|
45355
|
+
signal2
|
|
45356
|
+
);
|
|
45357
|
+
}
|
|
45358
|
+
runReconciliationExclusive(key, queue, task) {
|
|
45359
|
+
if (!queue.reconciliation || queue.exclusiveReconciliationPhase) {
|
|
45360
|
+
return Promise.reject(new Error("Invalid reconciliation phase"));
|
|
45361
|
+
}
|
|
45362
|
+
return new Promise((resolve11, reject) => {
|
|
45363
|
+
const complete = () => {
|
|
45364
|
+
queue.exclusiveReconciliationPhase = null;
|
|
45365
|
+
queue.exclusive = false;
|
|
45366
|
+
this.drain(key, queue);
|
|
45367
|
+
};
|
|
45368
|
+
queue.exclusiveReconciliationPhase = () => {
|
|
45369
|
+
void Promise.resolve().then(task).then(
|
|
45370
|
+
(result) => {
|
|
45371
|
+
complete();
|
|
45372
|
+
resolve11(result);
|
|
45373
|
+
},
|
|
45374
|
+
(error) => {
|
|
45375
|
+
complete();
|
|
45376
|
+
reject(error);
|
|
45377
|
+
}
|
|
45378
|
+
);
|
|
45379
|
+
};
|
|
45380
|
+
this.drain(key, queue);
|
|
45307
45381
|
});
|
|
45308
|
-
|
|
45309
|
-
|
|
45310
|
-
|
|
45311
|
-
|
|
45312
|
-
|
|
45313
|
-
|
|
45314
|
-
|
|
45315
|
-
|
|
45382
|
+
}
|
|
45383
|
+
enqueue(key, kind, task, signal2) {
|
|
45384
|
+
if (signal2?.aborted) return Promise.reject(signal2.reason);
|
|
45385
|
+
let queue = this.queues.get(key);
|
|
45386
|
+
if (!queue) {
|
|
45387
|
+
queue = {
|
|
45388
|
+
inspections: 0,
|
|
45389
|
+
reconciliation: false,
|
|
45390
|
+
exclusive: false,
|
|
45391
|
+
exclusiveReconciliationPhase: null,
|
|
45392
|
+
pending: []
|
|
45393
|
+
};
|
|
45394
|
+
this.queues.set(key, queue);
|
|
45395
|
+
}
|
|
45396
|
+
const repositoryQueue = queue;
|
|
45397
|
+
return new Promise((resolve11, reject) => {
|
|
45398
|
+
let pending = true;
|
|
45399
|
+
const complete = () => {
|
|
45400
|
+
if (kind === "inspection") repositoryQueue.inspections -= 1;
|
|
45401
|
+
else if (kind === "reconciliation")
|
|
45402
|
+
repositoryQueue.reconciliation = false;
|
|
45403
|
+
else repositoryQueue.exclusive = false;
|
|
45404
|
+
this.drain(key, repositoryQueue);
|
|
45405
|
+
};
|
|
45406
|
+
const abort = () => {
|
|
45407
|
+
if (!pending) return;
|
|
45408
|
+
pending = false;
|
|
45409
|
+
const index = repositoryQueue.pending.indexOf(operation);
|
|
45410
|
+
if (index !== -1) repositoryQueue.pending.splice(index, 1);
|
|
45411
|
+
signal2?.removeEventListener("abort", abort);
|
|
45412
|
+
reject(signal2?.reason);
|
|
45413
|
+
this.drain(key, repositoryQueue);
|
|
45414
|
+
};
|
|
45415
|
+
const operation = {
|
|
45416
|
+
kind,
|
|
45417
|
+
start: () => {
|
|
45418
|
+
pending = false;
|
|
45419
|
+
signal2?.removeEventListener("abort", abort);
|
|
45420
|
+
void Promise.resolve().then(() => {
|
|
45421
|
+
signal2?.throwIfAborted();
|
|
45422
|
+
return task(repositoryQueue);
|
|
45423
|
+
}).then(
|
|
45424
|
+
(result) => {
|
|
45425
|
+
complete();
|
|
45426
|
+
resolve11(result);
|
|
45427
|
+
},
|
|
45428
|
+
(error) => {
|
|
45429
|
+
complete();
|
|
45430
|
+
reject(error);
|
|
45431
|
+
}
|
|
45432
|
+
);
|
|
45433
|
+
}
|
|
45434
|
+
};
|
|
45435
|
+
repositoryQueue.pending.push(operation);
|
|
45436
|
+
signal2?.addEventListener("abort", abort, { once: true });
|
|
45437
|
+
if (signal2?.aborted) abort();
|
|
45438
|
+
else this.drain(key, repositoryQueue);
|
|
45439
|
+
});
|
|
45440
|
+
}
|
|
45441
|
+
drain(key, queue) {
|
|
45442
|
+
if (queue.exclusiveReconciliationPhase) {
|
|
45443
|
+
if (!queue.exclusive && queue.inspections === 0) {
|
|
45444
|
+
queue.exclusive = true;
|
|
45445
|
+
queue.exclusiveReconciliationPhase();
|
|
45446
|
+
}
|
|
45447
|
+
return;
|
|
45448
|
+
}
|
|
45449
|
+
while (!queue.exclusive && queue.pending.length) {
|
|
45450
|
+
const next = queue.pending[0];
|
|
45451
|
+
if (next.kind === "exclusive" && (queue.inspections > 0 || queue.reconciliation) || next.kind === "reconciliation" && queue.reconciliation) {
|
|
45452
|
+
return;
|
|
45453
|
+
}
|
|
45454
|
+
queue.pending.shift();
|
|
45455
|
+
if (next.kind === "inspection") queue.inspections += 1;
|
|
45456
|
+
else if (next.kind === "reconciliation") queue.reconciliation = true;
|
|
45457
|
+
else queue.exclusive = true;
|
|
45458
|
+
next.start();
|
|
45459
|
+
}
|
|
45460
|
+
if (!queue.exclusive && !queue.reconciliation && queue.inspections === 0 && queue.pending.length === 0) {
|
|
45461
|
+
this.queues.delete(key);
|
|
45316
45462
|
}
|
|
45317
45463
|
}
|
|
45318
45464
|
};
|
|
@@ -48322,7 +48468,9 @@ var downloadIosBuildArtifact = async (payload, timeoutMs, signal2, onLog, contex
|
|
|
48322
48468
|
uploadId: input.uploadId,
|
|
48323
48469
|
path: uploadPath,
|
|
48324
48470
|
filename,
|
|
48325
|
-
contentType
|
|
48471
|
+
contentType,
|
|
48472
|
+
signal: signal2,
|
|
48473
|
+
timeoutMs
|
|
48326
48474
|
});
|
|
48327
48475
|
return successfulProcess3;
|
|
48328
48476
|
} finally {
|
|
@@ -51028,6 +51176,17 @@ async function compareGitCheckpoint(cwd, target2, current) {
|
|
|
51028
51176
|
],
|
|
51029
51177
|
PATCH_LIMIT
|
|
51030
51178
|
);
|
|
51179
|
+
const worktreeSummary = await cappedGit(
|
|
51180
|
+
cwd,
|
|
51181
|
+
[
|
|
51182
|
+
"diff",
|
|
51183
|
+
"--stat",
|
|
51184
|
+
"--find-renames",
|
|
51185
|
+
target2.worktreeTree,
|
|
51186
|
+
current.worktreeTree
|
|
51187
|
+
],
|
|
51188
|
+
SUMMARY_LIMIT
|
|
51189
|
+
);
|
|
51031
51190
|
const indexPatch = target2.indexTree && current.indexTree ? await cappedGit(
|
|
51032
51191
|
cwd,
|
|
51033
51192
|
[
|
|
@@ -51048,6 +51207,8 @@ async function compareGitCheckpoint(cwd, target2, current) {
|
|
|
51048
51207
|
])
|
|
51049
51208
|
) : 0;
|
|
51050
51209
|
return {
|
|
51210
|
+
worktreePatch,
|
|
51211
|
+
worktreeSummary,
|
|
51051
51212
|
rollbackPatch: [
|
|
51052
51213
|
worktreePatch && `Worktree changes that will be undone:
|
|
51053
51214
|
|
|
@@ -52900,7 +53061,9 @@ var downloadWorktreeDiffAsset = async (payload, timeoutMs, signal2, _onLog, cont
|
|
|
52900
53061
|
uploadId: input.uploadId,
|
|
52901
53062
|
path: uploadPath,
|
|
52902
53063
|
filename: basename5(input.path),
|
|
52903
|
-
contentType: imageContentType(input.path)
|
|
53064
|
+
contentType: imageContentType(input.path),
|
|
53065
|
+
signal: signal2,
|
|
53066
|
+
timeoutMs
|
|
52904
53067
|
});
|
|
52905
53068
|
return successfulProcess9;
|
|
52906
53069
|
} finally {
|
|
@@ -55146,39 +55309,55 @@ var JobExecutor = class {
|
|
|
55146
55309
|
const handler = handlers[claimed.kind];
|
|
55147
55310
|
if (!handler)
|
|
55148
55311
|
throw new Error(`No local handler is registered for ${claimed.kind}`);
|
|
55149
|
-
const runHandler = () =>
|
|
55150
|
-
|
|
55151
|
-
|
|
55152
|
-
|
|
55153
|
-
|
|
55154
|
-
|
|
55155
|
-
|
|
55156
|
-
|
|
55157
|
-
|
|
55158
|
-
|
|
55159
|
-
this.client,
|
|
55160
|
-
input
|
|
55161
|
-
|
|
55162
|
-
|
|
55163
|
-
|
|
55164
|
-
|
|
55165
|
-
|
|
55166
|
-
|
|
55167
|
-
deploymentId,
|
|
55168
|
-
|
|
55169
|
-
|
|
55170
|
-
|
|
55171
|
-
|
|
55172
|
-
|
|
55173
|
-
|
|
55174
|
-
|
|
55175
|
-
|
|
55176
|
-
|
|
55177
|
-
|
|
55178
|
-
|
|
55179
|
-
|
|
55312
|
+
const runHandler = () => {
|
|
55313
|
+
controller.signal.throwIfAborted();
|
|
55314
|
+
return handler(
|
|
55315
|
+
claimed.payload,
|
|
55316
|
+
claimed.timeoutSeconds * 1e3,
|
|
55317
|
+
controller.signal,
|
|
55318
|
+
(log2) => this.client.appendLog(claimed.id, log2).then(() => void 0),
|
|
55319
|
+
{
|
|
55320
|
+
agentId: claimed.agentId,
|
|
55321
|
+
reportBranchDeletionResult: (result2) => this.client.reportBranchDeletionResult(claimed.id, result2),
|
|
55322
|
+
reportWorktreeActivity: (input) => this.client.reportWorktreeActivity(input),
|
|
55323
|
+
refreshFetchedCodebase: (input) => refreshFetchedCodebase(
|
|
55324
|
+
this.client,
|
|
55325
|
+
input,
|
|
55326
|
+
claimed.timeoutSeconds * 1e3,
|
|
55327
|
+
controller.signal
|
|
55328
|
+
),
|
|
55329
|
+
reportBuildProgress: (input) => this.client.reportBuildProgress(input),
|
|
55330
|
+
reportBuildDeploymentLaunched: (deploymentId, launchedAt) => this.client.reportBuildDeploymentLaunched(
|
|
55331
|
+
claimed.id,
|
|
55332
|
+
deploymentId,
|
|
55333
|
+
launchedAt
|
|
55334
|
+
),
|
|
55335
|
+
appendBuildLogChunks: (buildId, chunks) => this.client.appendBuildLogChunks(buildId, chunks),
|
|
55336
|
+
uploadBuildArtifact: (input) => this.client.uploadBuildArtifact(input),
|
|
55337
|
+
uploadBuildArtifactTransfer: (input) => this.client.uploadBuildArtifactTransfer(input),
|
|
55338
|
+
downloadBuildArtifactTransfer: (input) => this.client.downloadBuildArtifactTransfer(input),
|
|
55339
|
+
downloadDsymDwarf: (input) => this.client.downloadDsymDwarf(input),
|
|
55340
|
+
claimSigningSecretTransfer: (transferId) => this.client.claimSigningSecretTransfer(transferId),
|
|
55341
|
+
claimWorkflowJobSecrets: () => this.client.claimWorkflowJobSecrets(claimed.id),
|
|
55342
|
+
appendCommandOutput: (attemptId, chunks) => this.client.appendCommandOutput(claimed.id, attemptId, chunks)
|
|
55343
|
+
}
|
|
55344
|
+
);
|
|
55345
|
+
};
|
|
55180
55346
|
const codebaseId = claimed.payload && typeof claimed.payload === "object" && !Array.isArray(claimed.payload) && typeof claimed.payload.codebaseId === "string" ? String(claimed.payload.codebaseId) : null;
|
|
55181
|
-
|
|
55347
|
+
if (!codebaseId) result = await runHandler();
|
|
55348
|
+
else if (claimed.kind === WORKTREE_INSPECT_JOB_KIND || claimed.kind === WORKTREE_DIFF_JOB_KIND || claimed.kind === WORKTREE_DIFF_ASSET_JOB_KIND || claimed.kind === WORKTREE_GIT_INSPECT_JOB_KIND || claimed.kind === CODEBASE_GIT_INSPECT_JOB_KIND) {
|
|
55349
|
+
result = await this.repositoryCoordinator.runInspection(
|
|
55350
|
+
codebaseId,
|
|
55351
|
+
runHandler,
|
|
55352
|
+
controller.signal
|
|
55353
|
+
);
|
|
55354
|
+
} else {
|
|
55355
|
+
result = await this.repositoryCoordinator.run(
|
|
55356
|
+
codebaseId,
|
|
55357
|
+
runHandler,
|
|
55358
|
+
controller.signal
|
|
55359
|
+
);
|
|
55360
|
+
}
|
|
55182
55361
|
status2 = result.cancelled ? "CANCELLED" : result.timedOut ? "TIMED_OUT" : result.exitCode === 0 ? "SUCCEEDED" : "FAILED";
|
|
55183
55362
|
completionError = status2 === "FAILED" ? `Process exited with code ${result.exitCode}` : void 0;
|
|
55184
55363
|
} catch (error) {
|
|
@@ -55244,110 +55423,118 @@ var CodebaseMonitor = class {
|
|
|
55244
55423
|
const batch = codebases.slice(index, index + CONCURRENCY2);
|
|
55245
55424
|
await Promise.all(
|
|
55246
55425
|
batch.map(
|
|
55247
|
-
(codebase) => this.repositoryCoordinator.
|
|
55248
|
-
|
|
55249
|
-
|
|
55250
|
-
|
|
55251
|
-
|
|
55252
|
-
|
|
55253
|
-
|
|
55254
|
-
|
|
55255
|
-
|
|
55256
|
-
|
|
55257
|
-
|
|
55258
|
-
|
|
55259
|
-
|
|
55260
|
-
|
|
55261
|
-
|
|
55262
|
-
|
|
55263
|
-
|
|
55264
|
-
|
|
55265
|
-
|
|
55266
|
-
|
|
55267
|
-
|
|
55268
|
-
|
|
55269
|
-
|
|
55270
|
-
|
|
55271
|
-
|
|
55272
|
-
|
|
55273
|
-
|
|
55274
|
-
|
|
55275
|
-
|
|
55276
|
-
|
|
55426
|
+
(codebase) => this.repositoryCoordinator.runReconciliation(
|
|
55427
|
+
codebase.id,
|
|
55428
|
+
async ({ runExclusive }) => {
|
|
55429
|
+
let snapshot = await inspectCodebase(
|
|
55430
|
+
codebase.folder,
|
|
55431
|
+
INSPECTION_TIMEOUT_MS,
|
|
55432
|
+
signal2,
|
|
55433
|
+
codebase.canonicalOrigin
|
|
55434
|
+
);
|
|
55435
|
+
let fetchAttemptedAt = null;
|
|
55436
|
+
let fetchError = null;
|
|
55437
|
+
const fetchedAt2 = Math.max(
|
|
55438
|
+
snapshot.fetchedAt ? new Date(snapshot.fetchedAt).getTime() : 0,
|
|
55439
|
+
codebase.lastFetchAttemptAt ? new Date(codebase.lastFetchAttemptAt).getTime() : 0
|
|
55440
|
+
);
|
|
55441
|
+
const fetchDue = snapshot.availability === "AVAILABLE" && Date.now() - fetchedAt2 >= configuration.fetchIntervalSeconds * 1e3;
|
|
55442
|
+
if (fetchDue && !signal2.aborted) {
|
|
55443
|
+
fetchAttemptedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
55444
|
+
const fetchResult = await captureCommand({
|
|
55445
|
+
command: "git",
|
|
55446
|
+
args: ["-C", codebase.folder, "fetch", "origin"],
|
|
55447
|
+
timeoutMs: 3e5,
|
|
55448
|
+
signal: signal2,
|
|
55449
|
+
env: {
|
|
55450
|
+
...process.env,
|
|
55451
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
55452
|
+
GIT_OPTIONAL_LOCKS: "0"
|
|
55453
|
+
}
|
|
55454
|
+
});
|
|
55455
|
+
if (fetchResult.exitCode === 0) {
|
|
55456
|
+
if (codebase.keepBaseBranchUpToDate && codebase.defaultBranch) {
|
|
55457
|
+
const baseBranch = codebase.defaultBranch;
|
|
55458
|
+
await runExclusive(
|
|
55459
|
+
() => updateBaseBranchAfterFetch(
|
|
55460
|
+
codebase.folder,
|
|
55461
|
+
baseBranch,
|
|
55462
|
+
INSPECTION_TIMEOUT_MS,
|
|
55463
|
+
signal2
|
|
55464
|
+
)
|
|
55465
|
+
);
|
|
55466
|
+
}
|
|
55467
|
+
snapshot = await inspectCodebase(
|
|
55277
55468
|
codebase.folder,
|
|
55278
|
-
codebase.defaultBranch,
|
|
55279
55469
|
INSPECTION_TIMEOUT_MS,
|
|
55280
|
-
signal2
|
|
55470
|
+
signal2,
|
|
55471
|
+
codebase.canonicalOrigin
|
|
55281
55472
|
);
|
|
55473
|
+
} else {
|
|
55474
|
+
fetchError = (fetchResult.stderr || "Git fetch failed").replace(/([a-z][a-z0-9+.-]*:\/\/)[^\s/@]+@/gi, "$1").slice(0, 2e3);
|
|
55282
55475
|
}
|
|
55283
|
-
|
|
55476
|
+
}
|
|
55477
|
+
let inventory;
|
|
55478
|
+
try {
|
|
55479
|
+
inventory = await discoverWorktrees(
|
|
55284
55480
|
codebase.folder,
|
|
55481
|
+
new Map(
|
|
55482
|
+
codebase.worktrees.map((worktree) => [
|
|
55483
|
+
worktree.gitDirectory,
|
|
55484
|
+
worktree.baseBranchOverride
|
|
55485
|
+
])
|
|
55486
|
+
),
|
|
55487
|
+
codebase.defaultBranch,
|
|
55285
55488
|
INSPECTION_TIMEOUT_MS,
|
|
55286
|
-
signal2
|
|
55287
|
-
codebase.canonicalOrigin
|
|
55489
|
+
signal2
|
|
55288
55490
|
);
|
|
55289
|
-
}
|
|
55290
|
-
|
|
55291
|
-
|
|
55292
|
-
|
|
55293
|
-
|
|
55294
|
-
|
|
55295
|
-
|
|
55296
|
-
|
|
55297
|
-
|
|
55298
|
-
codebase.worktrees.map((worktree) => [
|
|
55299
|
-
worktree.gitDirectory,
|
|
55300
|
-
worktree.baseBranchOverride
|
|
55301
|
-
])
|
|
55302
|
-
),
|
|
55303
|
-
codebase.defaultBranch,
|
|
55304
|
-
INSPECTION_TIMEOUT_MS,
|
|
55305
|
-
signal2
|
|
55306
|
-
);
|
|
55307
|
-
} catch (error) {
|
|
55308
|
-
inventory = {
|
|
55309
|
-
complete: false,
|
|
55310
|
-
defaultBranch: null,
|
|
55311
|
-
localBranches: [],
|
|
55312
|
-
remoteBranches: [],
|
|
55313
|
-
worktrees: []
|
|
55314
|
-
};
|
|
55315
|
-
fetchError ??= error instanceof Error ? error.message.slice(0, 2e3) : String(error);
|
|
55316
|
-
}
|
|
55317
|
-
const localBranchInventoryAttemptedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
55318
|
-
let localBranchInventory = null;
|
|
55319
|
-
let localBranchInventoryError = null;
|
|
55320
|
-
try {
|
|
55321
|
-
if (snapshot.availability !== "AVAILABLE")
|
|
55322
|
-
throw new Error(snapshot.error || "Codebase is unavailable");
|
|
55323
|
-
localBranchInventory = await scanLocalBranches(
|
|
55324
|
-
codebase.folder,
|
|
55325
|
-
INSPECTION_TIMEOUT_MS,
|
|
55326
|
-
signal2
|
|
55327
|
-
);
|
|
55328
|
-
} catch (error) {
|
|
55329
|
-
localBranchInventoryError = error instanceof Error ? error.message.slice(0, 2e3) : String(error).slice(0, 2e3);
|
|
55330
|
-
}
|
|
55331
|
-
if (signal2.aborted) return;
|
|
55332
|
-
await this.client.reportCodebaseStatuses([
|
|
55333
|
-
{
|
|
55334
|
-
codebaseId: codebase.id,
|
|
55335
|
-
snapshot,
|
|
55336
|
-
localBranchInventory,
|
|
55337
|
-
localBranchInventoryError,
|
|
55338
|
-
localBranchInventoryAttemptedAt
|
|
55491
|
+
} catch (error) {
|
|
55492
|
+
inventory = {
|
|
55493
|
+
complete: false,
|
|
55494
|
+
defaultBranch: null,
|
|
55495
|
+
localBranches: [],
|
|
55496
|
+
remoteBranches: [],
|
|
55497
|
+
worktrees: []
|
|
55498
|
+
};
|
|
55499
|
+
fetchError ??= error instanceof Error ? error.message.slice(0, 2e3) : String(error);
|
|
55339
55500
|
}
|
|
55340
|
-
|
|
55341
|
-
|
|
55342
|
-
|
|
55343
|
-
|
|
55344
|
-
|
|
55345
|
-
|
|
55346
|
-
|
|
55347
|
-
|
|
55501
|
+
const localBranchInventoryAttemptedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
55502
|
+
let localBranchInventory = null;
|
|
55503
|
+
let localBranchInventoryError = null;
|
|
55504
|
+
try {
|
|
55505
|
+
if (snapshot.availability !== "AVAILABLE")
|
|
55506
|
+
throw new Error(
|
|
55507
|
+
snapshot.error || "Codebase is unavailable"
|
|
55508
|
+
);
|
|
55509
|
+
localBranchInventory = await scanLocalBranches(
|
|
55510
|
+
codebase.folder,
|
|
55511
|
+
INSPECTION_TIMEOUT_MS,
|
|
55512
|
+
signal2
|
|
55513
|
+
);
|
|
55514
|
+
} catch (error) {
|
|
55515
|
+
localBranchInventoryError = error instanceof Error ? error.message.slice(0, 2e3) : String(error).slice(0, 2e3);
|
|
55348
55516
|
}
|
|
55349
|
-
|
|
55350
|
-
|
|
55517
|
+
if (signal2.aborted) return;
|
|
55518
|
+
await this.client.reportCodebaseStatuses([
|
|
55519
|
+
{
|
|
55520
|
+
codebaseId: codebase.id,
|
|
55521
|
+
snapshot,
|
|
55522
|
+
localBranchInventory,
|
|
55523
|
+
localBranchInventoryError,
|
|
55524
|
+
localBranchInventoryAttemptedAt
|
|
55525
|
+
}
|
|
55526
|
+
]);
|
|
55527
|
+
await this.client.reportWorktrees([
|
|
55528
|
+
{
|
|
55529
|
+
codebaseId: codebase.id,
|
|
55530
|
+
...inventory,
|
|
55531
|
+
fetchedAt: snapshot.fetchedAt,
|
|
55532
|
+
fetchAttemptedAt,
|
|
55533
|
+
fetchError
|
|
55534
|
+
}
|
|
55535
|
+
]);
|
|
55536
|
+
}
|
|
55537
|
+
)
|
|
55351
55538
|
)
|
|
55352
55539
|
);
|
|
55353
55540
|
}
|
|
@@ -56200,7 +56387,9 @@ var OpenCodeAdapter = class {
|
|
|
56200
56387
|
initial = new Set(
|
|
56201
56388
|
(await openCodeMessages(client, nativeId)).map((entry) => entry.id)
|
|
56202
56389
|
);
|
|
56203
|
-
await callbacks.onNativeId(nativeId, runtime.version
|
|
56390
|
+
await callbacks.onNativeId(nativeId, runtime.version, {
|
|
56391
|
+
workingDirectory: cwd
|
|
56392
|
+
});
|
|
56204
56393
|
} catch (error) {
|
|
56205
56394
|
await cleanup();
|
|
56206
56395
|
throw error;
|
|
@@ -56645,7 +56834,8 @@ var OpenCodeAdapter = class {
|
|
|
56645
56834
|
pricingSource: "opencode-history",
|
|
56646
56835
|
createdAt: opencodeTimestamp(session.time.created),
|
|
56647
56836
|
updatedAt: opencodeTimestamp(session.time.updated),
|
|
56648
|
-
rawMetadata: session
|
|
56837
|
+
rawMetadata: session,
|
|
56838
|
+
sessionInfo: { workingDirectory: session.location.directory }
|
|
56649
56839
|
});
|
|
56650
56840
|
}
|
|
56651
56841
|
}
|
|
@@ -56945,12 +57135,17 @@ var RunManager = class {
|
|
|
56945
57135
|
return;
|
|
56946
57136
|
}
|
|
56947
57137
|
const callbacks = {
|
|
56948
|
-
onNativeId: async (nativeId, providerVersion) => {
|
|
57138
|
+
onNativeId: async (nativeId, providerVersion, sessionInfo) => {
|
|
56949
57139
|
await this.retry(
|
|
56950
57140
|
() => this.client.updateRunAttemptNativeId(
|
|
56951
57141
|
attempt.id,
|
|
56952
57142
|
nativeId,
|
|
56953
|
-
providerVersion
|
|
57143
|
+
providerVersion,
|
|
57144
|
+
{
|
|
57145
|
+
workingDirectory: run.worktree.folder,
|
|
57146
|
+
...sessionInfo,
|
|
57147
|
+
activityLogPath: journal.eventsPath
|
|
57148
|
+
}
|
|
56954
57149
|
)
|
|
56955
57150
|
);
|
|
56956
57151
|
},
|
|
@@ -57091,7 +57286,8 @@ var RunManager = class {
|
|
|
57091
57286
|
await this.retryFinalization(
|
|
57092
57287
|
() => this.client.reportRunCheckpoint(run.id, attemptId, {
|
|
57093
57288
|
...finalCheckpoint,
|
|
57094
|
-
diffPatch: comparison.
|
|
57289
|
+
diffPatch: comparison.worktreePatch || null,
|
|
57290
|
+
diffSummary: comparison.worktreeSummary || null
|
|
57095
57291
|
})
|
|
57096
57292
|
);
|
|
57097
57293
|
}
|