@shipers-dev/multi 0.41.0 → 0.44.0
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/index.js +186 -10
- package/package.json +1 -1
- package/dist/fsevents-hj42pnne.node +0 -0
- package/dist/loro_wasm_bg-2zffq6w4.wasm +0 -0
- package/dist/wa-sqlite.node.wasm +0 -0
package/dist/index.js
CHANGED
|
@@ -17109,7 +17109,7 @@ function setWorktreeIndexEntry(workingDir, key, issueId) {
|
|
|
17109
17109
|
idx[key] = issueId;
|
|
17110
17110
|
writeIndex(workingDir, idx);
|
|
17111
17111
|
}
|
|
17112
|
-
async function ensureWorktree(workingDir, issueKey, issueId) {
|
|
17112
|
+
async function ensureWorktree(workingDir, issueKey, issueId, opts) {
|
|
17113
17113
|
if (!await isGitRepo(workingDir)) {
|
|
17114
17114
|
return { path: workingDir, branch: "", created: false };
|
|
17115
17115
|
}
|
|
@@ -17126,8 +17126,19 @@ async function ensureWorktree(workingDir, issueKey, issueId) {
|
|
|
17126
17126
|
try {
|
|
17127
17127
|
mkdirSync3(wtDir, { recursive: true });
|
|
17128
17128
|
} catch {}
|
|
17129
|
+
let baseRef = "HEAD";
|
|
17130
|
+
if (opts?.parentBranch) {
|
|
17131
|
+
const localOk = await branchExists(workingDir, opts.parentBranch);
|
|
17132
|
+
if (localOk) {
|
|
17133
|
+
baseRef = opts.parentBranch;
|
|
17134
|
+
} else {
|
|
17135
|
+
const fetched = await run3(workingDir, "git", ["fetch", "origin", `${opts.parentBranch}:${opts.parentBranch}`]);
|
|
17136
|
+
if (fetched.code === 0)
|
|
17137
|
+
baseRef = opts.parentBranch;
|
|
17138
|
+
}
|
|
17139
|
+
}
|
|
17129
17140
|
const exists4 = await branchExists(workingDir, branch);
|
|
17130
|
-
const args2 = exists4 ? ["worktree", "add", wtPath, branch] : ["worktree", "add", "-b", branch, wtPath,
|
|
17141
|
+
const args2 = exists4 ? ["worktree", "add", wtPath, branch] : ["worktree", "add", "-b", branch, wtPath, baseRef];
|
|
17131
17142
|
const r = await run3(workingDir, "git", args2);
|
|
17132
17143
|
if (r.code !== 0) {
|
|
17133
17144
|
throw new Error(`git worktree add failed: ${r.stderr || r.stdout}`);
|
|
@@ -17219,6 +17230,48 @@ async function removeWorktree(workingDir, issueKey, opts = {}) {
|
|
|
17219
17230
|
removeWorktreeIndexEntry(workingDir, key);
|
|
17220
17231
|
return result;
|
|
17221
17232
|
}
|
|
17233
|
+
async function squashMergeChild(wtPath, childBranch, childKey) {
|
|
17234
|
+
const result = { childKey, branch: childBranch, ok: false, empty: false, conflicts: [], message: "" };
|
|
17235
|
+
await run3(wtPath, "git", ["fetch", "origin", `${childBranch}:${childBranch}`]).catch(() => null);
|
|
17236
|
+
const haveLocal = await branchExists(wtPath, childBranch);
|
|
17237
|
+
if (!haveLocal) {
|
|
17238
|
+
result.message = `branch ${childBranch} not resolvable locally or via origin`;
|
|
17239
|
+
return result;
|
|
17240
|
+
}
|
|
17241
|
+
const ahead = await run3(wtPath, "git", ["rev-list", "--count", `HEAD..${childBranch}`]);
|
|
17242
|
+
if (ahead.code === 0 && Number((ahead.stdout || "0").trim()) === 0) {
|
|
17243
|
+
result.ok = true;
|
|
17244
|
+
result.empty = true;
|
|
17245
|
+
result.message = `${childKey} had no commits ahead of parent — nothing to merge`;
|
|
17246
|
+
return result;
|
|
17247
|
+
}
|
|
17248
|
+
const merge9 = await run3(wtPath, "git", ["merge", "--squash", "--no-commit", childBranch]);
|
|
17249
|
+
const conflicted = await run3(wtPath, "git", ["diff", "--name-only", "--diff-filter=U"]);
|
|
17250
|
+
const conflictPaths = (conflicted.stdout || "").split(`
|
|
17251
|
+
`).map((l) => l.trim()).filter(Boolean);
|
|
17252
|
+
if (merge9.code !== 0 || conflictPaths.length > 0) {
|
|
17253
|
+
result.conflicts = conflictPaths;
|
|
17254
|
+
result.message = `${childKey} had ${conflictPaths.length} conflicting path(s); worktree left dirty for parent to resolve`;
|
|
17255
|
+
return result;
|
|
17256
|
+
}
|
|
17257
|
+
const staged = await run3(wtPath, "git", ["diff", "--cached", "--name-only"]);
|
|
17258
|
+
const stagedFiles = (staged.stdout || "").split(`
|
|
17259
|
+
`).map((l) => l.trim()).filter(Boolean);
|
|
17260
|
+
if (stagedFiles.length === 0) {
|
|
17261
|
+
result.ok = true;
|
|
17262
|
+
result.empty = true;
|
|
17263
|
+
result.message = `${childKey} produced no staged changes — nothing to commit`;
|
|
17264
|
+
return result;
|
|
17265
|
+
}
|
|
17266
|
+
const commit = await run3(wtPath, "git", ["commit", "-m", `squash: ${childKey} (${childBranch})`]);
|
|
17267
|
+
if (commit.code !== 0) {
|
|
17268
|
+
result.message = `${childKey} commit failed: ${commit.stderr || commit.stdout}`;
|
|
17269
|
+
return result;
|
|
17270
|
+
}
|
|
17271
|
+
result.ok = true;
|
|
17272
|
+
result.message = `${childKey} squash-merged (${stagedFiles.length} file${stagedFiles.length === 1 ? "" : "s"})`;
|
|
17273
|
+
return result;
|
|
17274
|
+
}
|
|
17222
17275
|
var init_worktree = () => {};
|
|
17223
17276
|
|
|
17224
17277
|
// ../../node_modules/zod/v4/core/core.js
|
|
@@ -34357,7 +34410,7 @@ async function handleRunTask(apiUrl, deviceId, task, detected, ctx) {
|
|
|
34357
34410
|
let worktreeBranch = "";
|
|
34358
34411
|
if (baseWorkingDir) {
|
|
34359
34412
|
try {
|
|
34360
|
-
const wt = await ensureWorktree(baseWorkingDir, task.key || issueId, issueId);
|
|
34413
|
+
const wt = await ensureWorktree(baseWorkingDir, task.key || issueId, issueId, { parentBranch: task.parent_branch ?? undefined });
|
|
34361
34414
|
workingDir = wt.path;
|
|
34362
34415
|
worktreeBranch = wt.branch;
|
|
34363
34416
|
await postStream(apiUrl, issueId, "worktree_created", { path: wt.path, branch: wt.branch, reused: !wt.created });
|
|
@@ -34372,6 +34425,44 @@ async function handleRunTask(apiUrl, deviceId, task, detected, ctx) {
|
|
|
34372
34425
|
await postStream(apiUrl, issueId, "worktree_error", { message: fmtError(e) });
|
|
34373
34426
|
}
|
|
34374
34427
|
}
|
|
34428
|
+
let mergeReportLines = [];
|
|
34429
|
+
let mergeHadConflicts = false;
|
|
34430
|
+
const mergeTargets = Array.isArray(task.merge_targets) ? task.merge_targets : [];
|
|
34431
|
+
if (workingDir && mergeTargets.length) {
|
|
34432
|
+
for (const t of mergeTargets) {
|
|
34433
|
+
if (!t?.branch || !t?.child_key)
|
|
34434
|
+
continue;
|
|
34435
|
+
try {
|
|
34436
|
+
const r = await squashMergeChild(workingDir, String(t.branch), String(t.child_key));
|
|
34437
|
+
if (r.ok && r.empty) {
|
|
34438
|
+
mergeReportLines.push(`- _empty_ ${t.child_key} → no changes`);
|
|
34439
|
+
} else if (r.ok) {
|
|
34440
|
+
mergeReportLines.push(`- ✅ ${t.child_key} squashed into ${worktreeBranch || "(parent)"}`);
|
|
34441
|
+
} else if (r.conflicts.length) {
|
|
34442
|
+
mergeHadConflicts = true;
|
|
34443
|
+
mergeReportLines.push(`- ⚠ ${t.child_key} CONFLICT in: ${r.conflicts.join(", ")}`);
|
|
34444
|
+
} else {
|
|
34445
|
+
mergeReportLines.push(`- ✗ ${t.child_key} ${r.message}`);
|
|
34446
|
+
}
|
|
34447
|
+
await postStream(apiUrl, issueId, "child_merge", {
|
|
34448
|
+
child_key: t.child_key,
|
|
34449
|
+
branch: t.branch,
|
|
34450
|
+
ok: r.ok,
|
|
34451
|
+
empty: r.empty,
|
|
34452
|
+
conflicts: r.conflicts,
|
|
34453
|
+
message: r.message
|
|
34454
|
+
});
|
|
34455
|
+
} catch (e) {
|
|
34456
|
+
mergeReportLines.push(`- ✗ ${t.child_key} merge threw: ${fmtError(e)}`);
|
|
34457
|
+
}
|
|
34458
|
+
}
|
|
34459
|
+
if (mergeReportLines.length) {
|
|
34460
|
+
const header = mergeHadConflicts ? "## ⚠ Squash-merge results — conflicts to resolve in your worktree" : "## Squash-merge results";
|
|
34461
|
+
const block = [header, ...mergeReportLines, "", "---", ""].join(`
|
|
34462
|
+
`);
|
|
34463
|
+
task.followup = block + (task.followup || "");
|
|
34464
|
+
}
|
|
34465
|
+
}
|
|
34375
34466
|
log3(`▶ run_task ${task.key}: ${isFollowup ? "(follow-up) " : ""}${task.title}${workingDir ? ` [cwd: ${workingDir}${worktreeBranch ? ` @${worktreeBranch}` : ""}]` : ""}`);
|
|
34376
34467
|
if (tenantWsId)
|
|
34377
34468
|
await patchIssueStatus(apiUrl, tenantWsId, issueId, "in_progress");
|
|
@@ -35030,7 +35121,8 @@ async function executePlanActions(apiUrl, parentTask, actions, ctx, parseErrors
|
|
|
35030
35121
|
priority: a.priority,
|
|
35031
35122
|
assignee_type: a.assignee_type,
|
|
35032
35123
|
assignee_id: a.assignee_id,
|
|
35033
|
-
parent_id: a.parent_id || parentId
|
|
35124
|
+
parent_id: a.parent_id || parentId,
|
|
35125
|
+
await_children: a.await_children
|
|
35034
35126
|
};
|
|
35035
35127
|
const res = await apiClient.post(mutateUrl, body, { headers });
|
|
35036
35128
|
if (!res.success) {
|
|
@@ -36197,7 +36289,8 @@ async function executeChatPlanActions(actionsIn, parseErrors, ctx) {
|
|
|
36197
36289
|
priority: a.priority,
|
|
36198
36290
|
assignee_type: a.assignee_type,
|
|
36199
36291
|
assignee_id: a.assignee_id,
|
|
36200
|
-
parent_id: a.parent_id
|
|
36292
|
+
parent_id: a.parent_id,
|
|
36293
|
+
await_children: a.await_children
|
|
36201
36294
|
};
|
|
36202
36295
|
const res = await apiClient.post(mutateUrl, body, { headers });
|
|
36203
36296
|
if (!res.success) {
|
|
@@ -36841,6 +36934,63 @@ var init_chat_supervisor = __esm(() => {
|
|
|
36841
36934
|
init_lib();
|
|
36842
36935
|
});
|
|
36843
36936
|
|
|
36937
|
+
// src/_impl/supervisor-tick.ts
|
|
36938
|
+
var exports_supervisor_tick = {};
|
|
36939
|
+
__export(exports_supervisor_tick, {
|
|
36940
|
+
runSupervisorTick: () => runSupervisorTick
|
|
36941
|
+
});
|
|
36942
|
+
async function runSupervisorTick(opts) {
|
|
36943
|
+
const { apiUrl, tickId, system, user, callbackUrl, callbackToken, log: log4 } = opts;
|
|
36944
|
+
let collected = "";
|
|
36945
|
+
await new Promise((resolve2) => {
|
|
36946
|
+
handleChatTurn({
|
|
36947
|
+
chatId: `sup-${tickId}`,
|
|
36948
|
+
prompt: user + `
|
|
36949
|
+
|
|
36950
|
+
Respond with ONLY a JSON object matching the schema. No prose, no fences.`,
|
|
36951
|
+
systemPreamble: system,
|
|
36952
|
+
preferredRuntime: "claude-code",
|
|
36953
|
+
log: log4,
|
|
36954
|
+
onChunk: (text) => {
|
|
36955
|
+
collected += text;
|
|
36956
|
+
},
|
|
36957
|
+
onDone: () => resolve2()
|
|
36958
|
+
});
|
|
36959
|
+
});
|
|
36960
|
+
let reflection = undefined;
|
|
36961
|
+
let error48;
|
|
36962
|
+
try {
|
|
36963
|
+
const start3 = collected.indexOf("{");
|
|
36964
|
+
const end3 = collected.lastIndexOf("}");
|
|
36965
|
+
if (start3 < 0 || end3 <= start3)
|
|
36966
|
+
throw new Error("no JSON object in agent reply");
|
|
36967
|
+
reflection = JSON.parse(collected.slice(start3, end3 + 1));
|
|
36968
|
+
} catch (e) {
|
|
36969
|
+
error48 = String(e?.message || e);
|
|
36970
|
+
log4(`[sup ${tickId}] parse failed: ${error48}`);
|
|
36971
|
+
}
|
|
36972
|
+
try {
|
|
36973
|
+
const r = await fetch(callbackUrl, {
|
|
36974
|
+
method: "POST",
|
|
36975
|
+
headers: { "content-type": "application/json" },
|
|
36976
|
+
body: JSON.stringify({
|
|
36977
|
+
tick_id: tickId,
|
|
36978
|
+
callback_token: callbackToken,
|
|
36979
|
+
reflection,
|
|
36980
|
+
error: error48
|
|
36981
|
+
})
|
|
36982
|
+
});
|
|
36983
|
+
if (!r.ok) {
|
|
36984
|
+
log4(`[sup ${tickId}] callback failed: HTTP ${r.status}`);
|
|
36985
|
+
}
|
|
36986
|
+
} catch (e) {
|
|
36987
|
+
log4(`[sup ${tickId}] callback error: ${e.message}`);
|
|
36988
|
+
}
|
|
36989
|
+
}
|
|
36990
|
+
var init_supervisor_tick = __esm(() => {
|
|
36991
|
+
init_chat_turn();
|
|
36992
|
+
});
|
|
36993
|
+
|
|
36844
36994
|
// ../../node_modules/effect/dist/esm/index.js
|
|
36845
36995
|
init_Cause();
|
|
36846
36996
|
init_Effect();
|
|
@@ -37403,7 +37553,7 @@ import { parseArgs } from "util";
|
|
|
37403
37553
|
// package.json
|
|
37404
37554
|
var package_default = {
|
|
37405
37555
|
name: "@shipers-dev/multi",
|
|
37406
|
-
version: "0.
|
|
37556
|
+
version: "0.44.0",
|
|
37407
37557
|
type: "module",
|
|
37408
37558
|
bin: {
|
|
37409
37559
|
"multi-agent": "./dist/index.js"
|
|
@@ -37688,8 +37838,8 @@ init_errors();
|
|
|
37688
37838
|
|
|
37689
37839
|
class Worktree extends exports_Effect.Service()("cli/Worktree", {
|
|
37690
37840
|
succeed: {
|
|
37691
|
-
ensure: (workingDir, issueKey, issueId) => exports_Effect.tryPromise({
|
|
37692
|
-
try: () => ensureWorktree(workingDir, issueKey, issueId),
|
|
37841
|
+
ensure: (workingDir, issueKey, issueId, opts) => exports_Effect.tryPromise({
|
|
37842
|
+
try: () => ensureWorktree(workingDir, issueKey, issueId, opts),
|
|
37693
37843
|
catch: (cause3) => new WorktreeError({ message: `ensureWorktree failed`, cause: cause3 })
|
|
37694
37844
|
}),
|
|
37695
37845
|
isGitRepo: (dir) => exports_Effect.tryPromise({
|
|
@@ -38415,8 +38565,8 @@ init_errors();
|
|
|
38415
38565
|
|
|
38416
38566
|
class Worktree2 extends exports_Effect.Service()("cli/Worktree", {
|
|
38417
38567
|
succeed: {
|
|
38418
|
-
ensure: (workingDir, issueKey, issueId) => exports_Effect.tryPromise({
|
|
38419
|
-
try: () => ensureWorktree(workingDir, issueKey, issueId),
|
|
38568
|
+
ensure: (workingDir, issueKey, issueId, opts) => exports_Effect.tryPromise({
|
|
38569
|
+
try: () => ensureWorktree(workingDir, issueKey, issueId, opts),
|
|
38420
38570
|
catch: (cause3) => new WorktreeError({ message: `ensureWorktree failed`, cause: cause3 })
|
|
38421
38571
|
}),
|
|
38422
38572
|
isGitRepo: (dir) => exports_Effect.tryPromise({
|
|
@@ -38862,6 +39012,32 @@ var daemonProgram = ({ cfg, apiUrl }) => exports_Effect.gen(function* () {
|
|
|
38862
39012
|
}
|
|
38863
39013
|
})();
|
|
38864
39014
|
}
|
|
39015
|
+
if (url2.pathname === "/run-supervisor-tick" && req.method === "POST") {
|
|
39016
|
+
if (req.headers.get("authorization") !== expectedAuth)
|
|
39017
|
+
return new Response("unauthorized", { status: 401 });
|
|
39018
|
+
return (async () => {
|
|
39019
|
+
try {
|
|
39020
|
+
const body = await req.json();
|
|
39021
|
+
if (!body?.tick_id || !body?.callback_url || !body?.callback_token) {
|
|
39022
|
+
return Response.json({ error: "tick_id, callback_url, callback_token required" }, { status: 400 });
|
|
39023
|
+
}
|
|
39024
|
+
const { runSupervisorTick: runSupervisorTick2 } = await Promise.resolve().then(() => (init_supervisor_tick(), exports_supervisor_tick));
|
|
39025
|
+
runSupervisorTick2({
|
|
39026
|
+
apiUrl,
|
|
39027
|
+
tickId: body.tick_id,
|
|
39028
|
+
projectId: body.project_id,
|
|
39029
|
+
system: body.system,
|
|
39030
|
+
user: body.user,
|
|
39031
|
+
callbackUrl: body.callback_url,
|
|
39032
|
+
callbackToken: body.callback_token,
|
|
39033
|
+
log: log3
|
|
39034
|
+
}).catch((e) => log3(`[sup ${body.tick_id}] runSupervisorTick error: ${e.message}`));
|
|
39035
|
+
return Response.json({ accepted: true }, { status: 202 });
|
|
39036
|
+
} catch (e) {
|
|
39037
|
+
return Response.json({ error: String(e) }, { status: 400 });
|
|
39038
|
+
}
|
|
39039
|
+
})();
|
|
39040
|
+
}
|
|
38865
39041
|
if (url2.pathname === "/stop" && req.method === "POST") {
|
|
38866
39042
|
if (req.headers.get("authorization") !== expectedAuth)
|
|
38867
39043
|
return new Response("unauthorized", { status: 401 });
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
package/dist/wa-sqlite.node.wasm
DELETED
|
Binary file
|