@ai-development-environment/control-agent 0.0.79 → 0.0.80
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 +178 -3
- package/package.json +1 -1
package/dist/control-agent.js
CHANGED
|
@@ -6106,6 +6106,7 @@ function codebaseGitOperationPayload(value) {
|
|
|
6106
6106
|
// ../agent-contract/src/worktrees.ts
|
|
6107
6107
|
var WORKTREE_INSPECT_JOB_KIND = "worktree.inspect";
|
|
6108
6108
|
var WORKTREE_OPERATION_JOB_KIND = "worktree.operation";
|
|
6109
|
+
var WORKTREE_COMMIT_JOB_KIND = "worktree.commit";
|
|
6109
6110
|
var WORKTREE_AUTO_SYNC_JOB_KIND = "worktree.auto-sync";
|
|
6110
6111
|
var WORKTREE_GIT_INSPECT_JOB_KIND = "worktree.git.inspect";
|
|
6111
6112
|
var WORKTREE_GIT_OPERATION_JOB_KIND = "worktree.git.operation";
|
|
@@ -6119,6 +6120,7 @@ var WORKTREE_DIFF_ASSET_JOB_KIND = "worktree.diff.asset";
|
|
|
6119
6120
|
var WORKTREE_JOB_KINDS = [
|
|
6120
6121
|
WORKTREE_INSPECT_JOB_KIND,
|
|
6121
6122
|
WORKTREE_OPERATION_JOB_KIND,
|
|
6123
|
+
WORKTREE_COMMIT_JOB_KIND,
|
|
6122
6124
|
WORKTREE_AUTO_SYNC_JOB_KIND,
|
|
6123
6125
|
WORKTREE_GIT_INSPECT_JOB_KIND,
|
|
6124
6126
|
WORKTREE_GIT_OPERATION_JOB_KIND,
|
|
@@ -6145,6 +6147,7 @@ var WORKTREE_OPERATIONS = [
|
|
|
6145
6147
|
"SYNC",
|
|
6146
6148
|
"REBASE",
|
|
6147
6149
|
"CANCEL_REBASE",
|
|
6150
|
+
"PULL",
|
|
6148
6151
|
"PUSH",
|
|
6149
6152
|
"RESET",
|
|
6150
6153
|
"STASH_ALL",
|
|
@@ -6463,6 +6466,71 @@ function worktreeDeleteJobPayload(value) {
|
|
|
6463
6466
|
expectedHeadSha
|
|
6464
6467
|
};
|
|
6465
6468
|
}
|
|
6469
|
+
function worktreeCommitJobPayload(value) {
|
|
6470
|
+
const payload = objectValue4(value, "worktree commit payload");
|
|
6471
|
+
const allowed = /* @__PURE__ */ new Set([
|
|
6472
|
+
"codebaseId",
|
|
6473
|
+
"folder",
|
|
6474
|
+
"gitDirectory",
|
|
6475
|
+
"expectedOrigin",
|
|
6476
|
+
"baseBranch",
|
|
6477
|
+
"message",
|
|
6478
|
+
"signed",
|
|
6479
|
+
"stageAll",
|
|
6480
|
+
"paths"
|
|
6481
|
+
]);
|
|
6482
|
+
const unexpected = Object.keys(payload).find((key) => !allowed.has(key));
|
|
6483
|
+
if (unexpected) {
|
|
6484
|
+
throw new Error(`Unexpected worktree commit payload field: ${unexpected}`);
|
|
6485
|
+
}
|
|
6486
|
+
const message = stringValue4(
|
|
6487
|
+
payload.message,
|
|
6488
|
+
"worktree commit payload.message"
|
|
6489
|
+
);
|
|
6490
|
+
if (!message.trim()) throw new Error("Commit message must not be blank");
|
|
6491
|
+
if (message.length > 5e4) throw new Error("Commit message is too long");
|
|
6492
|
+
if (payload.signed !== null && typeof payload.signed !== "boolean") {
|
|
6493
|
+
throw new Error("worktree commit payload.signed must be a boolean or null");
|
|
6494
|
+
}
|
|
6495
|
+
if (typeof payload.stageAll !== "boolean") {
|
|
6496
|
+
throw new Error("worktree commit payload.stageAll must be a boolean");
|
|
6497
|
+
}
|
|
6498
|
+
if (!Array.isArray(payload.paths) || payload.paths.length > 500) {
|
|
6499
|
+
throw new Error("worktree commit payload.paths is invalid");
|
|
6500
|
+
}
|
|
6501
|
+
const paths = payload.paths.map(
|
|
6502
|
+
(path, index) => safeRelativePath(path, `worktree commit payload.paths[${index}]`)
|
|
6503
|
+
);
|
|
6504
|
+
if (new Set(paths).size !== paths.length) {
|
|
6505
|
+
throw new Error("worktree commit payload.paths must be unique");
|
|
6506
|
+
}
|
|
6507
|
+
if (!payload.stageAll && paths.length === 0) {
|
|
6508
|
+
throw new Error("A partial commit requires at least one path");
|
|
6509
|
+
}
|
|
6510
|
+
return {
|
|
6511
|
+
codebaseId: stringValue4(
|
|
6512
|
+
payload.codebaseId,
|
|
6513
|
+
"worktree commit payload.codebaseId"
|
|
6514
|
+
),
|
|
6515
|
+
folder: stringValue4(payload.folder, "worktree commit payload.folder"),
|
|
6516
|
+
gitDirectory: stringValue4(
|
|
6517
|
+
payload.gitDirectory,
|
|
6518
|
+
"worktree commit payload.gitDirectory"
|
|
6519
|
+
),
|
|
6520
|
+
expectedOrigin: stringValue4(
|
|
6521
|
+
payload.expectedOrigin,
|
|
6522
|
+
"worktree commit payload.expectedOrigin"
|
|
6523
|
+
),
|
|
6524
|
+
baseBranch: nullableString3(
|
|
6525
|
+
payload.baseBranch,
|
|
6526
|
+
"worktree commit payload.baseBranch"
|
|
6527
|
+
),
|
|
6528
|
+
message,
|
|
6529
|
+
signed: payload.signed,
|
|
6530
|
+
stageAll: payload.stageAll,
|
|
6531
|
+
paths
|
|
6532
|
+
};
|
|
6533
|
+
}
|
|
6466
6534
|
function worktreeJobPayload(value) {
|
|
6467
6535
|
const payload = objectValue4(value, "worktree payload");
|
|
6468
6536
|
const allowed = /* @__PURE__ */ new Set([
|
|
@@ -15164,10 +15232,16 @@ async function inspectCommits(folder, baseBranch, timeoutMs, signal) {
|
|
|
15164
15232
|
return { commits: commits.slice(0, 100), truncated: commits.length > 100 };
|
|
15165
15233
|
}
|
|
15166
15234
|
async function inspectWorktreeDetail(folder, baseBranch, timeoutMs, signal) {
|
|
15167
|
-
const [commitResult, changeResult, branchResult] = await Promise.all([
|
|
15235
|
+
const [commitResult, changeResult, branchResult, signingResult] = await Promise.all([
|
|
15168
15236
|
inspectCommits(folder, baseBranch, timeoutMs, signal),
|
|
15169
15237
|
inspectChanges(folder, timeoutMs, signal),
|
|
15170
|
-
inspectBranchChanges(folder, baseBranch, timeoutMs, signal)
|
|
15238
|
+
inspectBranchChanges(folder, baseBranch, timeoutMs, signal),
|
|
15239
|
+
git3(
|
|
15240
|
+
folder,
|
|
15241
|
+
["config", "--bool", "--get", "commit.gpgsign"],
|
|
15242
|
+
timeoutMs,
|
|
15243
|
+
signal
|
|
15244
|
+
)
|
|
15171
15245
|
]);
|
|
15172
15246
|
return {
|
|
15173
15247
|
commits: commitResult.commits,
|
|
@@ -15175,7 +15249,8 @@ async function inspectWorktreeDetail(folder, baseBranch, timeoutMs, signal) {
|
|
|
15175
15249
|
branchChanges: branchResult.changes,
|
|
15176
15250
|
commitsTruncated: commitResult.truncated,
|
|
15177
15251
|
changesTruncated: changeResult.truncated,
|
|
15178
|
-
branchChangesTruncated: branchResult.truncated
|
|
15252
|
+
branchChangesTruncated: branchResult.truncated,
|
|
15253
|
+
commitSigningEnabled: signingResult.exitCode === 0 && signingResult.stdout.trim() === "true"
|
|
15179
15254
|
};
|
|
15180
15255
|
}
|
|
15181
15256
|
async function baseMergeCommit(folder, baseBranch, timeoutMs, signal) {
|
|
@@ -15701,6 +15776,97 @@ var inspectWorktreeGit = async (payload, timeoutMs, signal) => {
|
|
|
15701
15776
|
)
|
|
15702
15777
|
};
|
|
15703
15778
|
};
|
|
15779
|
+
var commitWorktree = async (payload, timeoutMs, signal) => {
|
|
15780
|
+
const input = worktreeCommitJobPayload(payload);
|
|
15781
|
+
const folder = await validateWorktree2(input, timeoutMs, signal);
|
|
15782
|
+
const runGit = async (args, fallback) => requireSuccess3(await git3(folder, args, timeoutMs, signal), fallback);
|
|
15783
|
+
if (input.stageAll) {
|
|
15784
|
+
await runGit(["add", "--all"], "Could not stage worktree changes");
|
|
15785
|
+
} else {
|
|
15786
|
+
const current = await inspectChanges(folder, timeoutMs, signal);
|
|
15787
|
+
const byPath = new Map(
|
|
15788
|
+
current.changes.map((change) => [change.path, change])
|
|
15789
|
+
);
|
|
15790
|
+
const selected = input.paths.map((path) => {
|
|
15791
|
+
const change = byPath.get(path);
|
|
15792
|
+
if (!change) throw new Error(`Worktree change no longer exists: ${path}`);
|
|
15793
|
+
return change;
|
|
15794
|
+
});
|
|
15795
|
+
const head = await git3(
|
|
15796
|
+
folder,
|
|
15797
|
+
["rev-parse", "--verify", "HEAD"],
|
|
15798
|
+
timeoutMs,
|
|
15799
|
+
signal
|
|
15800
|
+
);
|
|
15801
|
+
if (head.exitCode === 0) {
|
|
15802
|
+
await runGit(
|
|
15803
|
+
["reset", "--mixed", "HEAD", "--"],
|
|
15804
|
+
"Could not reset the Git index"
|
|
15805
|
+
);
|
|
15806
|
+
} else {
|
|
15807
|
+
await runGit(
|
|
15808
|
+
["rm", "--cached", "-r", "--ignore-unmatch", "."],
|
|
15809
|
+
"Could not reset the Git index"
|
|
15810
|
+
);
|
|
15811
|
+
}
|
|
15812
|
+
const selectedPaths = [
|
|
15813
|
+
...new Set(
|
|
15814
|
+
selected.flatMap(
|
|
15815
|
+
(change) => change.previousPath ? [change.previousPath, change.path] : [change.path]
|
|
15816
|
+
)
|
|
15817
|
+
)
|
|
15818
|
+
];
|
|
15819
|
+
await runGit(
|
|
15820
|
+
["--literal-pathspecs", "add", "--all", "--", ...selectedPaths],
|
|
15821
|
+
"Could not stage selected worktree changes"
|
|
15822
|
+
);
|
|
15823
|
+
}
|
|
15824
|
+
const staged = await git3(
|
|
15825
|
+
folder,
|
|
15826
|
+
["diff", "--cached", "--quiet", "--exit-code"],
|
|
15827
|
+
timeoutMs,
|
|
15828
|
+
signal
|
|
15829
|
+
);
|
|
15830
|
+
if (staged.exitCode === 0) throw new Error("No staged changes to commit");
|
|
15831
|
+
if (staged.exitCode !== 1)
|
|
15832
|
+
requireSuccess3(staged, "Could not inspect staged changes");
|
|
15833
|
+
let signed = input.signed;
|
|
15834
|
+
if (signed === null) {
|
|
15835
|
+
const configured = await git3(
|
|
15836
|
+
folder,
|
|
15837
|
+
["config", "--bool", "--get", "commit.gpgsign"],
|
|
15838
|
+
timeoutMs,
|
|
15839
|
+
signal
|
|
15840
|
+
);
|
|
15841
|
+
signed = configured.exitCode === 0 && configured.stdout.trim() === "true";
|
|
15842
|
+
}
|
|
15843
|
+
await runGit(
|
|
15844
|
+
["commit", signed ? "--gpg-sign" : "--no-gpg-sign", "-m", input.message],
|
|
15845
|
+
"Commit failed"
|
|
15846
|
+
);
|
|
15847
|
+
const sha = runGit(["rev-parse", "HEAD"], "Could not read the new commit");
|
|
15848
|
+
const subject = runGit(
|
|
15849
|
+
["log", "-1", "--format=%s"],
|
|
15850
|
+
"Could not read the new commit subject"
|
|
15851
|
+
);
|
|
15852
|
+
const [shaResult, subjectResult] = await Promise.all([sha, subject]);
|
|
15853
|
+
return {
|
|
15854
|
+
...successfulProcess8,
|
|
15855
|
+
commit: {
|
|
15856
|
+
sha: shaResult.stdout.trim(),
|
|
15857
|
+
subject: subjectResult.stdout.trim(),
|
|
15858
|
+
signed
|
|
15859
|
+
},
|
|
15860
|
+
worktree: await inspectWorktreeItem(
|
|
15861
|
+
folder,
|
|
15862
|
+
folder,
|
|
15863
|
+
input.baseBranch,
|
|
15864
|
+
false,
|
|
15865
|
+
Math.min(timeoutMs, 3e4),
|
|
15866
|
+
signal
|
|
15867
|
+
)
|
|
15868
|
+
};
|
|
15869
|
+
};
|
|
15704
15870
|
var operateWorktreeGit = async (payload, timeoutMs, signal) => {
|
|
15705
15871
|
const input = worktreeGitOperationPayload(payload);
|
|
15706
15872
|
const folder = await validateWorktree2(input, timeoutMs, signal);
|
|
@@ -16456,6 +16622,14 @@ var operateWorktree = async (payload, timeoutMs, signal) => {
|
|
|
16456
16622
|
await runGit(["rebase", "--abort"], "Could not cancel rebase");
|
|
16457
16623
|
break;
|
|
16458
16624
|
}
|
|
16625
|
+
case "PULL": {
|
|
16626
|
+
if (!branch || !upstream)
|
|
16627
|
+
throw new Error("Pull requires a branch with an upstream");
|
|
16628
|
+
const remote = upstream.split("/")[0] || "origin";
|
|
16629
|
+
await runGit(["fetch", remote], `Could not fetch ${remote}`);
|
|
16630
|
+
await runGit(["merge", "--ff-only", "@{upstream}"], "Pull failed");
|
|
16631
|
+
break;
|
|
16632
|
+
}
|
|
16459
16633
|
case "PUSH":
|
|
16460
16634
|
if (!branch) throw new Error("Push requires a branch");
|
|
16461
16635
|
await runGit(
|
|
@@ -16735,6 +16909,7 @@ var handlers = {
|
|
|
16735
16909
|
[WORKTREE_INSPECT_JOB_KIND]: inspectWorktree,
|
|
16736
16910
|
[WORKTREE_AUTO_SYNC_JOB_KIND]: autoSyncWorktree,
|
|
16737
16911
|
[WORKTREE_BRANCH_JOB_KIND]: branchWorktree,
|
|
16912
|
+
[WORKTREE_COMMIT_JOB_KIND]: commitWorktree,
|
|
16738
16913
|
[WORKTREE_MOVE_PUSH_JOB_KIND]: pushMovedWorktree,
|
|
16739
16914
|
[WORKTREE_MOVE_CHECKOUT_JOB_KIND]: checkoutMovedWorktree,
|
|
16740
16915
|
[WORKTREE_DELETE_JOB_KIND]: deleteWorktree,
|