@ai-development-environment/control-agent 0.0.80 → 0.0.82
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 +168 -41
- package/package.json +1 -1
package/dist/control-agent.js
CHANGED
|
@@ -4184,7 +4184,7 @@ var require_cross_spawn = __commonJS({
|
|
|
4184
4184
|
var cp3 = __require("child_process");
|
|
4185
4185
|
var parse2 = require_parse();
|
|
4186
4186
|
var enoent = require_enoent();
|
|
4187
|
-
function
|
|
4187
|
+
function spawn9(command3, args, options) {
|
|
4188
4188
|
const parsed = parse2(command3, args, options);
|
|
4189
4189
|
const spawned = cp3.spawn(parsed.command, parsed.args, parsed.options);
|
|
4190
4190
|
enoent.hookChildProcess(spawned, parsed);
|
|
@@ -4196,8 +4196,8 @@ var require_cross_spawn = __commonJS({
|
|
|
4196
4196
|
result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
|
|
4197
4197
|
return result;
|
|
4198
4198
|
}
|
|
4199
|
-
module.exports =
|
|
4200
|
-
module.exports.spawn =
|
|
4199
|
+
module.exports = spawn9;
|
|
4200
|
+
module.exports.spawn = spawn9;
|
|
4201
4201
|
module.exports.sync = spawnSync2;
|
|
4202
4202
|
module.exports._parse = parse2;
|
|
4203
4203
|
module.exports._enoent = enoent;
|
|
@@ -5031,6 +5031,26 @@ var AgentGraphQLClient = class {
|
|
|
5031
5031
|
})
|
|
5032
5032
|
};
|
|
5033
5033
|
}
|
|
5034
|
+
async ready() {
|
|
5035
|
+
const response = await fetch(`${this.server}/api/auth/config`, {
|
|
5036
|
+
headers: { ...this.headers },
|
|
5037
|
+
signal: AbortSignal.timeout(this.requestTimeoutMs)
|
|
5038
|
+
});
|
|
5039
|
+
const raw = await response.text();
|
|
5040
|
+
let body;
|
|
5041
|
+
try {
|
|
5042
|
+
body = raw ? JSON.parse(raw) : void 0;
|
|
5043
|
+
} catch {
|
|
5044
|
+
body = void 0;
|
|
5045
|
+
}
|
|
5046
|
+
if (!response.ok || typeof body?.mode !== "string") {
|
|
5047
|
+
const detail = `HTTP ${response.status} ${response.statusText}`.trim();
|
|
5048
|
+
throw new Error(
|
|
5049
|
+
!body && raw ? `${detail}: ${raw.slice(0, 500)}` : detail
|
|
5050
|
+
);
|
|
5051
|
+
}
|
|
5052
|
+
return { mode: body.mode };
|
|
5053
|
+
}
|
|
5034
5054
|
async request(query, variables) {
|
|
5035
5055
|
const response = await fetch(`${this.server}/api/graphql`, {
|
|
5036
5056
|
method: "POST",
|
|
@@ -14286,12 +14306,16 @@ import { tmpdir as tmpdir5 } from "node:os";
|
|
|
14286
14306
|
import { join as join12 } from "node:path";
|
|
14287
14307
|
|
|
14288
14308
|
// src/runs/git-checkpoint.ts
|
|
14289
|
-
import { execFile as execFile2 } from "node:child_process";
|
|
14309
|
+
import { execFile as execFile2, spawn as spawn6 } from "node:child_process";
|
|
14290
14310
|
import { copyFile, mkdtemp as mkdtemp4, rm as rm7 } from "node:fs/promises";
|
|
14291
14311
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
14292
14312
|
import { join as join11 } from "node:path";
|
|
14293
14313
|
import { promisify as promisify2 } from "node:util";
|
|
14294
14314
|
var execFileAsync = promisify2(execFile2);
|
|
14315
|
+
var PATCH_LIMIT = 2e6;
|
|
14316
|
+
var SUMMARY_LIMIT = 24e4;
|
|
14317
|
+
var MANIFEST_LIMIT = 2e6;
|
|
14318
|
+
var TRUNCATION_RESERVE = 200;
|
|
14295
14319
|
async function git2(cwd, args, env) {
|
|
14296
14320
|
const result = await execFileAsync("git", args, {
|
|
14297
14321
|
cwd,
|
|
@@ -14308,24 +14332,111 @@ async function optionalGit(cwd, args) {
|
|
|
14308
14332
|
return null;
|
|
14309
14333
|
}
|
|
14310
14334
|
}
|
|
14335
|
+
function cappedGit(cwd, args, limit) {
|
|
14336
|
+
const budget = limit - TRUNCATION_RESERVE;
|
|
14337
|
+
return new Promise((resolve8, reject) => {
|
|
14338
|
+
const child = spawn6("git", args, {
|
|
14339
|
+
cwd,
|
|
14340
|
+
env: {
|
|
14341
|
+
...process.env,
|
|
14342
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
14343
|
+
GIT_OPTIONAL_LOCKS: "0"
|
|
14344
|
+
},
|
|
14345
|
+
shell: false,
|
|
14346
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
14347
|
+
});
|
|
14348
|
+
const chunks = [];
|
|
14349
|
+
const errorChunks = [];
|
|
14350
|
+
let collected = 0;
|
|
14351
|
+
let errorCollected = 0;
|
|
14352
|
+
let truncated = false;
|
|
14353
|
+
let settled = false;
|
|
14354
|
+
child.stdout.on("data", (chunk) => {
|
|
14355
|
+
if (truncated) return;
|
|
14356
|
+
const remaining = budget - collected;
|
|
14357
|
+
if (chunk.length >= remaining) {
|
|
14358
|
+
chunks.push(chunk.subarray(0, remaining));
|
|
14359
|
+
collected = budget;
|
|
14360
|
+
truncated = true;
|
|
14361
|
+
child.stdout.destroy();
|
|
14362
|
+
if (child.exitCode === null && !child.killed) child.kill("SIGTERM");
|
|
14363
|
+
return;
|
|
14364
|
+
}
|
|
14365
|
+
chunks.push(chunk);
|
|
14366
|
+
collected += chunk.length;
|
|
14367
|
+
});
|
|
14368
|
+
child.stderr.on("data", (chunk) => {
|
|
14369
|
+
if (errorCollected >= 8192) return;
|
|
14370
|
+
errorChunks.push(chunk);
|
|
14371
|
+
errorCollected += chunk.length;
|
|
14372
|
+
});
|
|
14373
|
+
child.once("error", (error) => {
|
|
14374
|
+
if (settled) return;
|
|
14375
|
+
settled = true;
|
|
14376
|
+
reject(error);
|
|
14377
|
+
});
|
|
14378
|
+
child.once("close", (exitCode) => {
|
|
14379
|
+
if (settled) return;
|
|
14380
|
+
settled = true;
|
|
14381
|
+
if (!truncated && exitCode !== 0) {
|
|
14382
|
+
const message = Buffer.concat(errorChunks).toString("utf8").trim() || `git ${args[0]} exited with code ${exitCode}`;
|
|
14383
|
+
reject(new Error(message));
|
|
14384
|
+
return;
|
|
14385
|
+
}
|
|
14386
|
+
const output = Buffer.concat(chunks).toString("utf8");
|
|
14387
|
+
resolve8(
|
|
14388
|
+
truncated ? `${output.trimEnd()}
|
|
14389
|
+
|
|
14390
|
+
[Truncated after ${budget} bytes]` : output.trim()
|
|
14391
|
+
);
|
|
14392
|
+
});
|
|
14393
|
+
});
|
|
14394
|
+
}
|
|
14395
|
+
async function optionalCappedGit(cwd, args, limit) {
|
|
14396
|
+
try {
|
|
14397
|
+
return await cappedGit(cwd, args, limit) || null;
|
|
14398
|
+
} catch {
|
|
14399
|
+
return null;
|
|
14400
|
+
}
|
|
14401
|
+
}
|
|
14402
|
+
function manifestPayload(manifest) {
|
|
14403
|
+
let value = manifest;
|
|
14404
|
+
let json = JSON.stringify({ porcelainV2: value });
|
|
14405
|
+
while (json.length > MANIFEST_LIMIT && value.length > 0) {
|
|
14406
|
+
value = value.slice(
|
|
14407
|
+
0,
|
|
14408
|
+
Math.floor(value.length * MANIFEST_LIMIT / json.length) - 1
|
|
14409
|
+
);
|
|
14410
|
+
json = JSON.stringify({ porcelainV2: value });
|
|
14411
|
+
}
|
|
14412
|
+
return json;
|
|
14413
|
+
}
|
|
14311
14414
|
async function compareGitCheckpoint(cwd, target2, current) {
|
|
14312
14415
|
if (!target2.worktreeTree || !current.worktreeTree) {
|
|
14313
14416
|
throw new Error("The worktree checkpoint is incomplete");
|
|
14314
14417
|
}
|
|
14315
|
-
const worktreePatch = await
|
|
14316
|
-
|
|
14317
|
-
|
|
14318
|
-
|
|
14319
|
-
|
|
14320
|
-
|
|
14321
|
-
|
|
14322
|
-
|
|
14323
|
-
|
|
14324
|
-
|
|
14325
|
-
|
|
14326
|
-
|
|
14327
|
-
|
|
14328
|
-
|
|
14418
|
+
const worktreePatch = await cappedGit(
|
|
14419
|
+
cwd,
|
|
14420
|
+
[
|
|
14421
|
+
"diff",
|
|
14422
|
+
"--binary",
|
|
14423
|
+
"--find-renames",
|
|
14424
|
+
target2.worktreeTree,
|
|
14425
|
+
current.worktreeTree
|
|
14426
|
+
],
|
|
14427
|
+
PATCH_LIMIT
|
|
14428
|
+
);
|
|
14429
|
+
const indexPatch = target2.indexTree && current.indexTree ? await cappedGit(
|
|
14430
|
+
cwd,
|
|
14431
|
+
[
|
|
14432
|
+
"diff",
|
|
14433
|
+
"--binary",
|
|
14434
|
+
"--find-renames",
|
|
14435
|
+
target2.indexTree,
|
|
14436
|
+
current.indexTree
|
|
14437
|
+
],
|
|
14438
|
+
PATCH_LIMIT
|
|
14439
|
+
) : "";
|
|
14329
14440
|
const upstream = await optionalGit(cwd, ["rev-parse", "@{upstream}"]);
|
|
14330
14441
|
const pushedCount = target2.headSha && upstream ? Number(
|
|
14331
14442
|
await optionalGit(cwd, [
|
|
@@ -14342,7 +14453,7 @@ ${worktreePatch}`,
|
|
|
14342
14453
|
indexPatch && `Index changes that will be undone:
|
|
14343
14454
|
|
|
14344
14455
|
${indexPatch}`
|
|
14345
|
-
].filter(Boolean).join("\n\n").slice(0,
|
|
14456
|
+
].filter(Boolean).join("\n\n").slice(0, PATCH_LIMIT),
|
|
14346
14457
|
pushedCommitWarning: pushedCount > 0 ? `${pushedCount} commit${pushedCount === 1 ? "" : "s"} after this question appear on the upstream branch. Remote refs will not be changed.` : null
|
|
14347
14458
|
};
|
|
14348
14459
|
}
|
|
@@ -14401,9 +14512,21 @@ async function captureGitCheckpoint(cwd, runId, kind) {
|
|
|
14401
14512
|
]);
|
|
14402
14513
|
const upstreamSha = await optionalGit(cwd, ["rev-parse", "@{upstream}"]);
|
|
14403
14514
|
const indexTree = await optionalGit(cwd, ["write-tree"]);
|
|
14404
|
-
const manifest = await
|
|
14405
|
-
|
|
14406
|
-
|
|
14515
|
+
const manifest = await optionalCappedGit(
|
|
14516
|
+
cwd,
|
|
14517
|
+
["status", "--porcelain=v2", "-z"],
|
|
14518
|
+
MANIFEST_LIMIT
|
|
14519
|
+
);
|
|
14520
|
+
const staged = await optionalCappedGit(
|
|
14521
|
+
cwd,
|
|
14522
|
+
["diff", "--cached", "--stat", "HEAD"],
|
|
14523
|
+
SUMMARY_LIMIT
|
|
14524
|
+
);
|
|
14525
|
+
const unstaged = await optionalCappedGit(
|
|
14526
|
+
cwd,
|
|
14527
|
+
["diff", "--stat", "HEAD"],
|
|
14528
|
+
SUMMARY_LIMIT
|
|
14529
|
+
);
|
|
14407
14530
|
const directory = await mkdtemp4(join11(tmpdir4(), "aide-run-index-"));
|
|
14408
14531
|
let worktreeTree = null;
|
|
14409
14532
|
let refName = null;
|
|
@@ -14451,17 +14574,15 @@ async function captureGitCheckpoint(cwd, runId, kind) {
|
|
|
14451
14574
|
indexTree,
|
|
14452
14575
|
worktreeTree,
|
|
14453
14576
|
refName,
|
|
14454
|
-
manifestJson:
|
|
14577
|
+
manifestJson: manifestPayload(manifest ?? ""),
|
|
14455
14578
|
diffSummary: [staged && `Staged:
|
|
14456
14579
|
${staged}`, unstaged && `Working tree:
|
|
14457
14580
|
${unstaged}`].filter(Boolean).join("\n\n") || null,
|
|
14458
|
-
diffPatch: headSha && worktreeTree ?
|
|
14459
|
-
|
|
14460
|
-
"--binary",
|
|
14461
|
-
|
|
14462
|
-
|
|
14463
|
-
worktreeTree
|
|
14464
|
-
])).slice(0, 2e6) || null : null
|
|
14581
|
+
diffPatch: headSha && worktreeTree ? await cappedGit(
|
|
14582
|
+
cwd,
|
|
14583
|
+
["diff", "--binary", "--find-renames", headSha, worktreeTree],
|
|
14584
|
+
PATCH_LIMIT
|
|
14585
|
+
) || null : null
|
|
14465
14586
|
};
|
|
14466
14587
|
}
|
|
14467
14588
|
|
|
@@ -14576,7 +14697,7 @@ import { createWriteStream as createWriteStream2, watch } from "node:fs";
|
|
|
14576
14697
|
import { mkdtemp as mkdtemp6, open as open2, readFile as readFile8, realpath as realpath8, rm as rm9, stat as stat10 } from "node:fs/promises";
|
|
14577
14698
|
import { tmpdir as tmpdir6 } from "node:os";
|
|
14578
14699
|
import { basename as basename5, dirname as dirname7, isAbsolute as isAbsolute6, join as join13, relative as relative7 } from "node:path";
|
|
14579
|
-
import { spawn as
|
|
14700
|
+
import { spawn as spawn7 } from "node:child_process";
|
|
14580
14701
|
var successfulProcess8 = {
|
|
14581
14702
|
exitCode: 0,
|
|
14582
14703
|
signal: null,
|
|
@@ -15576,7 +15697,7 @@ function imageContentType(path) {
|
|
|
15576
15697
|
}
|
|
15577
15698
|
async function writeGitObject(folder, specification, destination, timeoutMs, signal) {
|
|
15578
15699
|
await new Promise((resolvePromise, rejectPromise) => {
|
|
15579
|
-
const child =
|
|
15700
|
+
const child = spawn7(
|
|
15580
15701
|
"git",
|
|
15581
15702
|
["-C", folder, "cat-file", "blob", specification],
|
|
15582
15703
|
{ stdio: ["ignore", "pipe", "pipe"] }
|
|
@@ -43515,7 +43636,7 @@ var ClaudeAdapter = class {
|
|
|
43515
43636
|
// src/runs/codex-adapter.ts
|
|
43516
43637
|
import {
|
|
43517
43638
|
execFile as execFile3,
|
|
43518
|
-
spawn as
|
|
43639
|
+
spawn as spawn8
|
|
43519
43640
|
} from "node:child_process";
|
|
43520
43641
|
import { mkdtemp as mkdtemp7, rm as rm12, writeFile as writeFile8 } from "node:fs/promises";
|
|
43521
43642
|
import { tmpdir as tmpdir7 } from "node:os";
|
|
@@ -43604,7 +43725,7 @@ var CodexAppServer = class {
|
|
|
43604
43725
|
const executable = this.executable();
|
|
43605
43726
|
const modelCatalogPath = await this.createBundledModelCatalog(executable);
|
|
43606
43727
|
const modelCatalogDirectory = this.modelCatalogDirectory;
|
|
43607
|
-
const child =
|
|
43728
|
+
const child = spawn8(executable, codexAppServerArgs(modelCatalogPath), {
|
|
43608
43729
|
stdio: ["pipe", "pipe", "pipe"],
|
|
43609
43730
|
env: process.env
|
|
43610
43731
|
});
|
|
@@ -51304,7 +51425,7 @@ async function waitForServer(client2, timeoutMs, signal, dependencies) {
|
|
|
51304
51425
|
let lastError;
|
|
51305
51426
|
while (!signal.aborted && Date.now() < deadline) {
|
|
51306
51427
|
try {
|
|
51307
|
-
await client2.
|
|
51428
|
+
await client2.ready();
|
|
51308
51429
|
return;
|
|
51309
51430
|
} catch (error) {
|
|
51310
51431
|
lastError = error;
|
|
@@ -51346,10 +51467,15 @@ async function prepareDevelopmentAgent(options, signal, dependencies = defaultDe
|
|
|
51346
51467
|
}
|
|
51347
51468
|
} catch {
|
|
51348
51469
|
}
|
|
51349
|
-
const
|
|
51470
|
+
const enrollmentToken = options.enrollmentToken?.trim();
|
|
51471
|
+
if (!enrollmentToken) {
|
|
51472
|
+
throw new Error(
|
|
51473
|
+
"The development agent needs a one-time enrollment token. Create one on the Agents page and set CONTROL_AGENT_DEV_ENROLLMENT_TOKEN."
|
|
51474
|
+
);
|
|
51475
|
+
}
|
|
51350
51476
|
const response = await anonymousClient.enroll({
|
|
51351
51477
|
...inventory,
|
|
51352
|
-
enrollmentToken
|
|
51478
|
+
enrollmentToken,
|
|
51353
51479
|
name
|
|
51354
51480
|
});
|
|
51355
51481
|
const config = {
|
|
@@ -51583,10 +51709,10 @@ async function doctor() {
|
|
|
51583
51709
|
null,
|
|
51584
51710
|
1e4,
|
|
51585
51711
|
config?.headers
|
|
51586
|
-
).
|
|
51712
|
+
).ready();
|
|
51587
51713
|
return {
|
|
51588
|
-
ok:
|
|
51589
|
-
detail: `${endpoint.kind} ${endpoint.server}: ${health.
|
|
51714
|
+
ok: true,
|
|
51715
|
+
detail: `${endpoint.kind} ${endpoint.server}: ready (${health.mode})`
|
|
51590
51716
|
};
|
|
51591
51717
|
} catch (error) {
|
|
51592
51718
|
return {
|
|
@@ -51633,7 +51759,8 @@ async function main() {
|
|
|
51633
51759
|
{
|
|
51634
51760
|
server,
|
|
51635
51761
|
websocketServer: options["websocket-server"] ?? process.env.CONTROL_AGENT_DEV_WEBSOCKET_SERVER ?? process.env.NEXT_PUBLIC_AGENT_WS_URL,
|
|
51636
|
-
name: options.name
|
|
51762
|
+
name: options.name,
|
|
51763
|
+
enrollmentToken: options["enrollment-token"] ?? process.env.CONTROL_AGENT_DEV_ENROLLMENT_TOKEN
|
|
51637
51764
|
},
|
|
51638
51765
|
controller.signal
|
|
51639
51766
|
);
|