@shipers-dev/multi 0.15.0 → 0.16.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 +59 -27
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -16073,10 +16073,10 @@ var StreamEventInputSchema = exports_external.object({
|
|
|
16073
16073
|
});
|
|
16074
16074
|
// src/worktree.ts
|
|
16075
16075
|
import { spawn } from "child_process";
|
|
16076
|
-
import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
16077
|
-
import { join as join3 } from "path";
|
|
16076
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, symlinkSync } from "fs";
|
|
16077
|
+
import { dirname as dirname2, join as join3, resolve } from "path";
|
|
16078
16078
|
async function run(cwd, cmd, args) {
|
|
16079
|
-
return await new Promise((
|
|
16079
|
+
return await new Promise((resolve2) => {
|
|
16080
16080
|
const p = spawn(cmd, args, { cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
16081
16081
|
let stdout = "";
|
|
16082
16082
|
let stderr = "";
|
|
@@ -16086,8 +16086,8 @@ async function run(cwd, cmd, args) {
|
|
|
16086
16086
|
p.stderr.on("data", (d) => {
|
|
16087
16087
|
stderr += d.toString();
|
|
16088
16088
|
});
|
|
16089
|
-
p.on("close", (code) =>
|
|
16090
|
-
p.on("error", (e) =>
|
|
16089
|
+
p.on("close", (code) => resolve2({ code: code ?? 0, stdout: stdout.trim(), stderr: stderr.trim() }));
|
|
16090
|
+
p.on("error", (e) => resolve2({ code: 1, stdout: "", stderr: String(e) }));
|
|
16091
16091
|
});
|
|
16092
16092
|
}
|
|
16093
16093
|
async function isGitRepo(dir) {
|
|
@@ -16144,12 +16144,43 @@ async function ensureWorktree(workingDir, issueKey) {
|
|
|
16144
16144
|
if (r.code !== 0) {
|
|
16145
16145
|
throw new Error(`git worktree add failed: ${r.stderr || r.stdout}`);
|
|
16146
16146
|
}
|
|
16147
|
+
await linkIgnoredFiles(workingDir, wtPath);
|
|
16147
16148
|
return { path: wtPath, branch, created: true };
|
|
16148
16149
|
}
|
|
16150
|
+
async function linkIgnoredFiles(workingDir, wtPath) {
|
|
16151
|
+
const r = await run(workingDir, "git", [
|
|
16152
|
+
"ls-files",
|
|
16153
|
+
"--others",
|
|
16154
|
+
"--ignored",
|
|
16155
|
+
"--exclude-standard",
|
|
16156
|
+
"--directory"
|
|
16157
|
+
]);
|
|
16158
|
+
if (r.code !== 0)
|
|
16159
|
+
return;
|
|
16160
|
+
const entries = r.stdout.split(`
|
|
16161
|
+
`).map((l) => l.trim()).filter(Boolean);
|
|
16162
|
+
for (const raw of entries) {
|
|
16163
|
+
const rel = raw.endsWith("/") ? raw.slice(0, -1) : raw;
|
|
16164
|
+
if (!rel || rel === ".multi" || rel.startsWith(".multi/"))
|
|
16165
|
+
continue;
|
|
16166
|
+
if (rel === ".git" || rel.startsWith(".git/"))
|
|
16167
|
+
continue;
|
|
16168
|
+
const src = resolve(workingDir, rel);
|
|
16169
|
+
const dst = join3(wtPath, rel);
|
|
16170
|
+
if (existsSync2(dst))
|
|
16171
|
+
continue;
|
|
16172
|
+
try {
|
|
16173
|
+
mkdirSync2(dirname2(dst), { recursive: true });
|
|
16174
|
+
} catch {}
|
|
16175
|
+
try {
|
|
16176
|
+
symlinkSync(src, dst);
|
|
16177
|
+
} catch {}
|
|
16178
|
+
}
|
|
16179
|
+
}
|
|
16149
16180
|
|
|
16150
16181
|
// src/materializer.ts
|
|
16151
|
-
import { mkdirSync as mkdirSync3, existsSync as existsSync3, writeFileSync as writeFileSync3, readFileSync as readFileSync3, rmSync, symlinkSync, lstatSync } from "fs";
|
|
16152
|
-
import { join as join4, dirname as
|
|
16182
|
+
import { mkdirSync as mkdirSync3, existsSync as existsSync3, writeFileSync as writeFileSync3, readFileSync as readFileSync3, rmSync, symlinkSync as symlinkSync2, lstatSync } from "fs";
|
|
16183
|
+
import { join as join4, dirname as dirname3 } from "path";
|
|
16153
16184
|
var HOME2 = process.env.HOME || process.env.USERPROFILE || ".";
|
|
16154
16185
|
var MULTI_DIR = join4(HOME2, ".multi");
|
|
16155
16186
|
var MULTI_SKILLS = join4(MULTI_DIR, "skills");
|
|
@@ -16207,7 +16238,7 @@ revision=${Date.now()}
|
|
|
16207
16238
|
if (f.path === MARKER)
|
|
16208
16239
|
continue;
|
|
16209
16240
|
const out = join4(dir, f.path);
|
|
16210
|
-
mkdirSync3(
|
|
16241
|
+
mkdirSync3(dirname3(out), { recursive: true });
|
|
16211
16242
|
writeFileSync3(out, f.content);
|
|
16212
16243
|
}
|
|
16213
16244
|
mkdirSync3(CLAUDE_SKILLS, { recursive: true });
|
|
@@ -16215,7 +16246,7 @@ revision=${Date.now()}
|
|
|
16215
16246
|
safeRmManaged(link);
|
|
16216
16247
|
if (!existsSync3(link)) {
|
|
16217
16248
|
try {
|
|
16218
|
-
|
|
16249
|
+
symlinkSync2(dir, link, "dir");
|
|
16219
16250
|
} catch {}
|
|
16220
16251
|
}
|
|
16221
16252
|
}
|
|
@@ -16289,11 +16320,11 @@ function lastMaterializedRevision() {
|
|
|
16289
16320
|
// src/index.ts
|
|
16290
16321
|
import { parseArgs } from "util";
|
|
16291
16322
|
import { mkdirSync as mkdirSync4, existsSync as existsSync4, writeFileSync as writeFileSync4, readFileSync as readFileSync4, appendFileSync as appendFileSync2, unlinkSync, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
|
|
16292
|
-
import { join as join5, dirname as
|
|
16323
|
+
import { join as join5, dirname as dirname4 } from "path";
|
|
16293
16324
|
// package.json
|
|
16294
16325
|
var package_default = {
|
|
16295
16326
|
name: "@shipers-dev/multi",
|
|
16296
|
-
version: "0.
|
|
16327
|
+
version: "0.16.0",
|
|
16297
16328
|
type: "module",
|
|
16298
16329
|
bin: {
|
|
16299
16330
|
"multi-agent": "./dist/index.js"
|
|
@@ -16303,7 +16334,8 @@ var package_default = {
|
|
|
16303
16334
|
],
|
|
16304
16335
|
scripts: {
|
|
16305
16336
|
dev: "bun run src/index.ts",
|
|
16306
|
-
build: "bun build src/index.ts --outdir=dist --target=bun"
|
|
16337
|
+
build: "bun build src/index.ts --outdir=dist --target=bun",
|
|
16338
|
+
prepublishOnly: "bun run build"
|
|
16307
16339
|
},
|
|
16308
16340
|
dependencies: {
|
|
16309
16341
|
"@agentclientprotocol/sdk": "^0.20.0",
|
|
@@ -17016,9 +17048,12 @@ async function parseTunnelUrl(stream2) {
|
|
|
17016
17048
|
}
|
|
17017
17049
|
return { url: null, tail: buf };
|
|
17018
17050
|
}
|
|
17051
|
+
async function patchIssueStatus(apiUrl, issueId, status) {
|
|
17052
|
+
return apiClient.post(`${apiUrl}/api/issues/agent/mutate`, { action: "update", id: issueId, status });
|
|
17053
|
+
}
|
|
17019
17054
|
async function markStopped(apiUrl, issueId, reason) {
|
|
17020
17055
|
try {
|
|
17021
|
-
await
|
|
17056
|
+
await patchIssueStatus(apiUrl, issueId, "stopped");
|
|
17022
17057
|
} catch {}
|
|
17023
17058
|
try {
|
|
17024
17059
|
await apiClient.post(`${apiUrl}/api/issues/${issueId}/comments`, {
|
|
@@ -17047,7 +17082,7 @@ async function handleRunTask(apiUrl, deviceId, task, detected, ctx) {
|
|
|
17047
17082
|
}
|
|
17048
17083
|
}
|
|
17049
17084
|
log(`\u25B6 run_task ${task.key}: ${isFollowup ? "(follow-up) " : ""}${task.title}${workingDir ? ` [cwd: ${workingDir}${worktreeBranch ? ` @${worktreeBranch}` : ""}]` : ""}`);
|
|
17050
|
-
await
|
|
17085
|
+
await patchIssueStatus(apiUrl, issueId, "in_progress");
|
|
17051
17086
|
await postStream(apiUrl, issueId, "progress", { message: `Device ${deviceId} picked up ${isFollowup ? "follow-up" : "task"}` });
|
|
17052
17087
|
let attachmentRefs = [];
|
|
17053
17088
|
if (task.from_comment_id) {
|
|
@@ -17276,12 +17311,14 @@ _${bits.join(" \xB7 ")}_`);
|
|
|
17276
17311
|
}
|
|
17277
17312
|
}
|
|
17278
17313
|
};
|
|
17279
|
-
let preferType;
|
|
17280
|
-
|
|
17281
|
-
|
|
17282
|
-
|
|
17283
|
-
|
|
17284
|
-
|
|
17314
|
+
let preferType = task.agent_runtime || undefined;
|
|
17315
|
+
if (!preferType) {
|
|
17316
|
+
try {
|
|
17317
|
+
const a = await apiClient.get(`${apiUrl}/api/agents/${task.agent_id}`);
|
|
17318
|
+
if (a.data?.type)
|
|
17319
|
+
preferType = a.data.type;
|
|
17320
|
+
} catch {}
|
|
17321
|
+
}
|
|
17285
17322
|
const acpCapable = detected.filter((d) => d.type === "claude-code");
|
|
17286
17323
|
const useAcp = preferType !== "pi" && acpCapable.length > 0 && process.env.MULTI_LEGACY !== "1";
|
|
17287
17324
|
const useAcpx = !useAcp && preferType && ["pi", "codex", "openclaw"].includes(preferType) && process.env.MULTI_LEGACY !== "1";
|
|
@@ -17354,12 +17391,7 @@ ${body}
|
|
|
17354
17391
|
---
|
|
17355
17392
|
|
|
17356
17393
|
${userPart}` : userPart;
|
|
17357
|
-
let preferredType = "claude-code";
|
|
17358
|
-
try {
|
|
17359
|
-
const a = await apiClient.get(`${apiUrl}/api/agents/${task.agent_id}`);
|
|
17360
|
-
if (a.data?.type)
|
|
17361
|
-
preferredType = a.data.type;
|
|
17362
|
-
} catch {}
|
|
17394
|
+
let preferredType = preferType || "claude-code";
|
|
17363
17395
|
const chosen = acpCapable.find((d) => d.type === preferredType) || acpCapable[0];
|
|
17364
17396
|
const adapterBin = await resolveAcpAdapter(chosen.type, chosen.path);
|
|
17365
17397
|
if (!adapterBin)
|
|
@@ -17792,7 +17824,7 @@ async function resolveAcpAdapter(agentType, detectedPath) {
|
|
|
17792
17824
|
const here = new URL(import.meta.url).pathname;
|
|
17793
17825
|
let dir = here;
|
|
17794
17826
|
for (let i = 0;i < 8; i++) {
|
|
17795
|
-
dir =
|
|
17827
|
+
dir = dirname4(dir);
|
|
17796
17828
|
const bin = join5(dir, "node_modules", ".bin", name);
|
|
17797
17829
|
if (existsSync4(bin))
|
|
17798
17830
|
return [bin];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shipers-dev/multi",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"multi-agent": "./dist/index.js"
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
],
|
|
11
11
|
"scripts": {
|
|
12
12
|
"dev": "bun run src/index.ts",
|
|
13
|
-
"build": "bun build src/index.ts --outdir=dist --target=bun"
|
|
13
|
+
"build": "bun build src/index.ts --outdir=dist --target=bun",
|
|
14
|
+
"prepublishOnly": "bun run build"
|
|
14
15
|
},
|
|
15
16
|
"dependencies": {
|
|
16
17
|
"@agentclientprotocol/sdk": "^0.20.0",
|