@ai-development-environment/control-agent 0.0.57 → 0.0.58
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 +272 -0
- package/package.json +1 -1
package/dist/control-agent.js
CHANGED
|
@@ -6026,6 +6026,7 @@ function codebaseGitOperationPayload(value) {
|
|
|
6026
6026
|
// ../agent-contract/src/worktrees.ts
|
|
6027
6027
|
var WORKTREE_INSPECT_JOB_KIND = "worktree.inspect";
|
|
6028
6028
|
var WORKTREE_OPERATION_JOB_KIND = "worktree.operation";
|
|
6029
|
+
var WORKTREE_AUTO_SYNC_JOB_KIND = "worktree.auto-sync";
|
|
6029
6030
|
var WORKTREE_GIT_INSPECT_JOB_KIND = "worktree.git.inspect";
|
|
6030
6031
|
var WORKTREE_GIT_OPERATION_JOB_KIND = "worktree.git.operation";
|
|
6031
6032
|
var WORKTREE_WATCH_JOB_KIND = "worktree.watch";
|
|
@@ -6038,6 +6039,7 @@ var WORKTREE_DIFF_ASSET_JOB_KIND = "worktree.diff.asset";
|
|
|
6038
6039
|
var WORKTREE_JOB_KINDS = [
|
|
6039
6040
|
WORKTREE_INSPECT_JOB_KIND,
|
|
6040
6041
|
WORKTREE_OPERATION_JOB_KIND,
|
|
6042
|
+
WORKTREE_AUTO_SYNC_JOB_KIND,
|
|
6041
6043
|
WORKTREE_GIT_INSPECT_JOB_KIND,
|
|
6042
6044
|
WORKTREE_GIT_OPERATION_JOB_KIND,
|
|
6043
6045
|
WORKTREE_WATCH_JOB_KIND,
|
|
@@ -6422,6 +6424,51 @@ function worktreeJobPayload(value) {
|
|
|
6422
6424
|
...editorVariant === void 0 ? {} : { editorVariant }
|
|
6423
6425
|
};
|
|
6424
6426
|
}
|
|
6427
|
+
function worktreeAutoSyncJobPayload(value) {
|
|
6428
|
+
const payload = objectValue4(value, "worktree auto sync payload");
|
|
6429
|
+
const allowed = /* @__PURE__ */ new Set([
|
|
6430
|
+
"codebaseId",
|
|
6431
|
+
"folder",
|
|
6432
|
+
"gitDirectory",
|
|
6433
|
+
"expectedOrigin",
|
|
6434
|
+
"expectedBranch",
|
|
6435
|
+
"baseBranch",
|
|
6436
|
+
"phase"
|
|
6437
|
+
]);
|
|
6438
|
+
const unexpected = Object.keys(payload).find((key) => !allowed.has(key));
|
|
6439
|
+
if (unexpected) {
|
|
6440
|
+
throw new Error(
|
|
6441
|
+
`Unexpected worktree auto sync payload field: ${unexpected}`
|
|
6442
|
+
);
|
|
6443
|
+
}
|
|
6444
|
+
if (payload.phase !== "SYNC" && payload.phase !== "FINALIZE") {
|
|
6445
|
+
throw new Error("worktree auto sync payload.phase is invalid");
|
|
6446
|
+
}
|
|
6447
|
+
return {
|
|
6448
|
+
codebaseId: stringValue4(
|
|
6449
|
+
payload.codebaseId,
|
|
6450
|
+
"worktree auto sync payload.codebaseId"
|
|
6451
|
+
),
|
|
6452
|
+
folder: stringValue4(payload.folder, "worktree auto sync payload.folder"),
|
|
6453
|
+
gitDirectory: stringValue4(
|
|
6454
|
+
payload.gitDirectory,
|
|
6455
|
+
"worktree auto sync payload.gitDirectory"
|
|
6456
|
+
),
|
|
6457
|
+
expectedOrigin: stringValue4(
|
|
6458
|
+
payload.expectedOrigin,
|
|
6459
|
+
"worktree auto sync payload.expectedOrigin"
|
|
6460
|
+
),
|
|
6461
|
+
expectedBranch: stringValue4(
|
|
6462
|
+
payload.expectedBranch,
|
|
6463
|
+
"worktree auto sync payload.expectedBranch"
|
|
6464
|
+
),
|
|
6465
|
+
baseBranch: stringValue4(
|
|
6466
|
+
payload.baseBranch,
|
|
6467
|
+
"worktree auto sync payload.baseBranch"
|
|
6468
|
+
),
|
|
6469
|
+
phase: payload.phase
|
|
6470
|
+
};
|
|
6471
|
+
}
|
|
6425
6472
|
function worktreeGitInspectPayload(value) {
|
|
6426
6473
|
const payload = objectValue4(value, "worktree Git inspect payload");
|
|
6427
6474
|
const allowed = /* @__PURE__ */ new Set([
|
|
@@ -15838,6 +15885,230 @@ var operateWorktree = async (payload, timeoutMs, signal) => {
|
|
|
15838
15885
|
)
|
|
15839
15886
|
};
|
|
15840
15887
|
};
|
|
15888
|
+
var autoSyncWorktree = async (payload, timeoutMs, signal) => {
|
|
15889
|
+
const input = worktreeAutoSyncJobPayload(payload);
|
|
15890
|
+
const folder = await validateWorktree2(input, timeoutMs, signal);
|
|
15891
|
+
const runGit = async (args, fallback) => requireSuccess3(await git3(folder, args, timeoutMs, signal), fallback);
|
|
15892
|
+
const branchResult = await git3(
|
|
15893
|
+
folder,
|
|
15894
|
+
["symbolic-ref", "--short", "-q", "HEAD"],
|
|
15895
|
+
timeoutMs,
|
|
15896
|
+
signal
|
|
15897
|
+
);
|
|
15898
|
+
const symbolicBranch = branchResult.exitCode === 0 ? branchResult.stdout.trim() : null;
|
|
15899
|
+
const branch = symbolicBranch ?? (input.phase === "FINALIZE" ? await rebaseBranch(folder, timeoutMs, signal) : null);
|
|
15900
|
+
if (branch !== input.expectedBranch) {
|
|
15901
|
+
throw new Error(
|
|
15902
|
+
`Auto Sync expected branch ${input.expectedBranch}, but found ${branch ?? "detached HEAD"}`
|
|
15903
|
+
);
|
|
15904
|
+
}
|
|
15905
|
+
const upstreamResult = branch ? await git3(
|
|
15906
|
+
folder,
|
|
15907
|
+
["rev-parse", "--abbrev-ref", "@{upstream}"],
|
|
15908
|
+
timeoutMs,
|
|
15909
|
+
signal
|
|
15910
|
+
) : null;
|
|
15911
|
+
const upstream = upstreamResult?.exitCode === 0 ? upstreamResult.stdout.trim() : null;
|
|
15912
|
+
if (input.phase === "SYNC" && (!branch || !upstream)) {
|
|
15913
|
+
throw new Error("Auto Sync requires a branch with an upstream");
|
|
15914
|
+
}
|
|
15915
|
+
if (input.phase === "FINALIZE") {
|
|
15916
|
+
let status3 = await runGit(
|
|
15917
|
+
["status", "--porcelain=v1", "-z"],
|
|
15918
|
+
"Could not inspect worktree changes"
|
|
15919
|
+
);
|
|
15920
|
+
let changes = statusChangeState(status3.stdout);
|
|
15921
|
+
const continuingRebase = await rebaseInProgress(folder, timeoutMs, signal);
|
|
15922
|
+
if (changes.hasConflicts && !continuingRebase) {
|
|
15923
|
+
return {
|
|
15924
|
+
...successfulProcess7,
|
|
15925
|
+
outcome: "UNRESOLVED",
|
|
15926
|
+
worktree: await inspectWorktreeItem(
|
|
15927
|
+
folder,
|
|
15928
|
+
folder,
|
|
15929
|
+
input.baseBranch,
|
|
15930
|
+
false,
|
|
15931
|
+
Math.min(timeoutMs, 3e4),
|
|
15932
|
+
signal
|
|
15933
|
+
)
|
|
15934
|
+
};
|
|
15935
|
+
}
|
|
15936
|
+
if (continuingRebase) {
|
|
15937
|
+
await runGit(["add", "--all"], "Could not stage resolved conflicts");
|
|
15938
|
+
const continued = await command2(
|
|
15939
|
+
"git",
|
|
15940
|
+
["-C", folder, "rebase", "--continue"],
|
|
15941
|
+
timeoutMs,
|
|
15942
|
+
signal,
|
|
15943
|
+
{
|
|
15944
|
+
...process.env,
|
|
15945
|
+
GIT_EDITOR: "true",
|
|
15946
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
15947
|
+
GIT_OPTIONAL_LOCKS: "0"
|
|
15948
|
+
}
|
|
15949
|
+
);
|
|
15950
|
+
if (continued.exitCode !== 0) {
|
|
15951
|
+
return {
|
|
15952
|
+
...successfulProcess7,
|
|
15953
|
+
outcome: "UNRESOLVED",
|
|
15954
|
+
worktree: await inspectWorktreeItem(
|
|
15955
|
+
folder,
|
|
15956
|
+
folder,
|
|
15957
|
+
input.baseBranch,
|
|
15958
|
+
false,
|
|
15959
|
+
Math.min(timeoutMs, 3e4),
|
|
15960
|
+
signal
|
|
15961
|
+
)
|
|
15962
|
+
};
|
|
15963
|
+
}
|
|
15964
|
+
status3 = await runGit(
|
|
15965
|
+
["status", "--porcelain=v1", "-z"],
|
|
15966
|
+
"Could not inspect resolved worktree changes"
|
|
15967
|
+
);
|
|
15968
|
+
changes = statusChangeState(status3.stdout);
|
|
15969
|
+
}
|
|
15970
|
+
if (changes.hasConflicts || changes.hasStagedChanges || changes.hasUnstagedChanges || await rebaseInProgress(folder, timeoutMs, signal)) {
|
|
15971
|
+
return {
|
|
15972
|
+
...successfulProcess7,
|
|
15973
|
+
outcome: "UNRESOLVED",
|
|
15974
|
+
worktree: await inspectWorktreeItem(
|
|
15975
|
+
folder,
|
|
15976
|
+
folder,
|
|
15977
|
+
input.baseBranch,
|
|
15978
|
+
false,
|
|
15979
|
+
Math.min(timeoutMs, 3e4),
|
|
15980
|
+
signal
|
|
15981
|
+
)
|
|
15982
|
+
};
|
|
15983
|
+
}
|
|
15984
|
+
const finalBranch = await git3(
|
|
15985
|
+
folder,
|
|
15986
|
+
["symbolic-ref", "--short", "-q", "HEAD"],
|
|
15987
|
+
timeoutMs,
|
|
15988
|
+
signal
|
|
15989
|
+
);
|
|
15990
|
+
const finalUpstream = finalBranch.exitCode === 0 ? await git3(
|
|
15991
|
+
folder,
|
|
15992
|
+
["rev-parse", "--abbrev-ref", "@{upstream}"],
|
|
15993
|
+
timeoutMs,
|
|
15994
|
+
signal
|
|
15995
|
+
) : null;
|
|
15996
|
+
if (finalBranch.exitCode !== 0 || finalBranch.stdout.trim() !== input.expectedBranch || finalUpstream?.exitCode !== 0 || !finalUpstream.stdout.trim()) {
|
|
15997
|
+
throw new Error(
|
|
15998
|
+
`Auto Sync expected branch ${input.expectedBranch} with an upstream`
|
|
15999
|
+
);
|
|
16000
|
+
}
|
|
16001
|
+
await runGit(["push", "--force-with-lease"], "Auto Sync push failed");
|
|
16002
|
+
return {
|
|
16003
|
+
...successfulProcess7,
|
|
16004
|
+
outcome: "SYNCED",
|
|
16005
|
+
worktree: await inspectWorktreeItem(
|
|
16006
|
+
folder,
|
|
16007
|
+
folder,
|
|
16008
|
+
input.baseBranch,
|
|
16009
|
+
false,
|
|
16010
|
+
Math.min(timeoutMs, 3e4),
|
|
16011
|
+
signal
|
|
16012
|
+
)
|
|
16013
|
+
};
|
|
16014
|
+
}
|
|
16015
|
+
const status2 = await runGit(
|
|
16016
|
+
["status", "--porcelain"],
|
|
16017
|
+
"Could not inspect worktree changes"
|
|
16018
|
+
);
|
|
16019
|
+
if (status2.stdout.trim()) {
|
|
16020
|
+
throw new Error("Stash or commit changes before Auto Sync can continue");
|
|
16021
|
+
}
|
|
16022
|
+
await runGit(["fetch", "origin"], "Could not fetch origin");
|
|
16023
|
+
const remoteBase = `refs/remotes/origin/${input.baseBranch}`;
|
|
16024
|
+
const isCurrent = await git3(
|
|
16025
|
+
folder,
|
|
16026
|
+
["merge-base", "--is-ancestor", remoteBase, "HEAD"],
|
|
16027
|
+
timeoutMs,
|
|
16028
|
+
signal
|
|
16029
|
+
);
|
|
16030
|
+
if (isCurrent.exitCode === 0) {
|
|
16031
|
+
const upstreamContainsHead = await git3(
|
|
16032
|
+
folder,
|
|
16033
|
+
["merge-base", "--is-ancestor", "HEAD", "@{upstream}"],
|
|
16034
|
+
timeoutMs,
|
|
16035
|
+
signal
|
|
16036
|
+
);
|
|
16037
|
+
if (upstreamContainsHead.exitCode !== 0 && upstreamContainsHead.exitCode !== 1) {
|
|
16038
|
+
throw new Error(
|
|
16039
|
+
cleanError3(
|
|
16040
|
+
upstreamContainsHead.stderr || "Could not compare the upstream branch"
|
|
16041
|
+
)
|
|
16042
|
+
);
|
|
16043
|
+
}
|
|
16044
|
+
if (upstreamContainsHead.exitCode !== 0) {
|
|
16045
|
+
await runGit(["push", "--force-with-lease"], "Auto Sync push failed");
|
|
16046
|
+
return {
|
|
16047
|
+
...successfulProcess7,
|
|
16048
|
+
outcome: "SYNCED",
|
|
16049
|
+
worktree: await inspectWorktreeItem(
|
|
16050
|
+
folder,
|
|
16051
|
+
folder,
|
|
16052
|
+
input.baseBranch,
|
|
16053
|
+
false,
|
|
16054
|
+
Math.min(timeoutMs, 3e4),
|
|
16055
|
+
signal
|
|
16056
|
+
)
|
|
16057
|
+
};
|
|
16058
|
+
}
|
|
16059
|
+
return {
|
|
16060
|
+
...successfulProcess7,
|
|
16061
|
+
outcome: "NO_CHANGE",
|
|
16062
|
+
worktree: await inspectWorktreeItem(
|
|
16063
|
+
folder,
|
|
16064
|
+
folder,
|
|
16065
|
+
input.baseBranch,
|
|
16066
|
+
false,
|
|
16067
|
+
Math.min(timeoutMs, 3e4),
|
|
16068
|
+
signal
|
|
16069
|
+
)
|
|
16070
|
+
};
|
|
16071
|
+
}
|
|
16072
|
+
const rebase = await git3(folder, ["rebase", remoteBase], timeoutMs, signal);
|
|
16073
|
+
if (rebase.exitCode !== 0) {
|
|
16074
|
+
const conflictStatus = await git3(
|
|
16075
|
+
folder,
|
|
16076
|
+
["status", "--porcelain=v1", "-z"],
|
|
16077
|
+
timeoutMs,
|
|
16078
|
+
signal
|
|
16079
|
+
);
|
|
16080
|
+
const conflicts = conflictStatus.exitCode === 0 && statusChangeState(conflictStatus.stdout).hasConflicts;
|
|
16081
|
+
if (conflicts && await rebaseInProgress(folder, timeoutMs, signal)) {
|
|
16082
|
+
return {
|
|
16083
|
+
...successfulProcess7,
|
|
16084
|
+
outcome: "CONFLICT",
|
|
16085
|
+
worktree: await inspectWorktreeItem(
|
|
16086
|
+
folder,
|
|
16087
|
+
folder,
|
|
16088
|
+
input.baseBranch,
|
|
16089
|
+
false,
|
|
16090
|
+
Math.min(timeoutMs, 3e4),
|
|
16091
|
+
signal
|
|
16092
|
+
)
|
|
16093
|
+
};
|
|
16094
|
+
}
|
|
16095
|
+
await git3(folder, ["rebase", "--abort"], timeoutMs, signal);
|
|
16096
|
+
throw new Error(cleanError3(rebase.stderr || "Auto Sync rebase failed"));
|
|
16097
|
+
}
|
|
16098
|
+
await runGit(["push", "--force-with-lease"], "Auto Sync push failed");
|
|
16099
|
+
return {
|
|
16100
|
+
...successfulProcess7,
|
|
16101
|
+
outcome: "SYNCED",
|
|
16102
|
+
worktree: await inspectWorktreeItem(
|
|
16103
|
+
folder,
|
|
16104
|
+
folder,
|
|
16105
|
+
input.baseBranch,
|
|
16106
|
+
false,
|
|
16107
|
+
Math.min(timeoutMs, 3e4),
|
|
16108
|
+
signal
|
|
16109
|
+
)
|
|
16110
|
+
};
|
|
16111
|
+
};
|
|
15841
16112
|
|
|
15842
16113
|
// src/handlers/index.ts
|
|
15843
16114
|
var handlers = {
|
|
@@ -15853,6 +16124,7 @@ var handlers = {
|
|
|
15853
16124
|
[CODEBASE_GIT_INSPECT_JOB_KIND]: inspectCodebaseGit,
|
|
15854
16125
|
[CODEBASE_GIT_OPERATION_JOB_KIND]: operateCodebaseGit,
|
|
15855
16126
|
[WORKTREE_INSPECT_JOB_KIND]: inspectWorktree,
|
|
16127
|
+
[WORKTREE_AUTO_SYNC_JOB_KIND]: autoSyncWorktree,
|
|
15856
16128
|
[WORKTREE_BRANCH_JOB_KIND]: branchWorktree,
|
|
15857
16129
|
[WORKTREE_MOVE_PUSH_JOB_KIND]: pushMovedWorktree,
|
|
15858
16130
|
[WORKTREE_MOVE_CHECKOUT_JOB_KIND]: checkoutMovedWorktree,
|