@openacp/cli 2026.408.2 → 2026.408.4
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/cli.js +310 -145
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +257 -118
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -199,11 +199,11 @@ async function shutdownLogger() {
|
|
|
199
199
|
logDir = void 0;
|
|
200
200
|
initialized = false;
|
|
201
201
|
if (transport) {
|
|
202
|
-
await new Promise((
|
|
203
|
-
const timeout = setTimeout(
|
|
202
|
+
await new Promise((resolve9) => {
|
|
203
|
+
const timeout = setTimeout(resolve9, 3e3);
|
|
204
204
|
transport.on("close", () => {
|
|
205
205
|
clearTimeout(timeout);
|
|
206
|
-
|
|
206
|
+
resolve9();
|
|
207
207
|
});
|
|
208
208
|
transport.end();
|
|
209
209
|
});
|
|
@@ -343,21 +343,21 @@ function compareVersions(current, latest) {
|
|
|
343
343
|
}
|
|
344
344
|
async function runUpdate() {
|
|
345
345
|
const { spawn: spawn9 } = await import("child_process");
|
|
346
|
-
return new Promise((
|
|
346
|
+
return new Promise((resolve9) => {
|
|
347
347
|
const child = spawn9("npm", ["install", "-g", `${NPM_PACKAGE}@latest`], {
|
|
348
348
|
stdio: "inherit",
|
|
349
349
|
shell: true
|
|
350
350
|
});
|
|
351
351
|
const onSignal = () => {
|
|
352
352
|
child.kill("SIGTERM");
|
|
353
|
-
|
|
353
|
+
resolve9(false);
|
|
354
354
|
};
|
|
355
355
|
process.on("SIGINT", onSignal);
|
|
356
356
|
process.on("SIGTERM", onSignal);
|
|
357
357
|
child.on("close", (code) => {
|
|
358
358
|
process.off("SIGINT", onSignal);
|
|
359
359
|
process.off("SIGTERM", onSignal);
|
|
360
|
-
|
|
360
|
+
resolve9(code === 0);
|
|
361
361
|
});
|
|
362
362
|
});
|
|
363
363
|
}
|
|
@@ -5040,7 +5040,7 @@ import https from "https";
|
|
|
5040
5040
|
import os8 from "os";
|
|
5041
5041
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
5042
5042
|
function downloadFile(url, dest, maxRedirects = 10) {
|
|
5043
|
-
return new Promise((
|
|
5043
|
+
return new Promise((resolve9, reject) => {
|
|
5044
5044
|
const file = fs13.createWriteStream(dest);
|
|
5045
5045
|
const cleanup = () => {
|
|
5046
5046
|
try {
|
|
@@ -5059,7 +5059,7 @@ function downloadFile(url, dest, maxRedirects = 10) {
|
|
|
5059
5059
|
}
|
|
5060
5060
|
file.close(() => {
|
|
5061
5061
|
cleanup();
|
|
5062
|
-
downloadFile(response.headers.location, dest, maxRedirects - 1).then(
|
|
5062
|
+
downloadFile(response.headers.location, dest, maxRedirects - 1).then(resolve9).catch(reject);
|
|
5063
5063
|
});
|
|
5064
5064
|
return;
|
|
5065
5065
|
}
|
|
@@ -5083,7 +5083,7 @@ function downloadFile(url, dest, maxRedirects = 10) {
|
|
|
5083
5083
|
}
|
|
5084
5084
|
});
|
|
5085
5085
|
response.pipe(file);
|
|
5086
|
-
file.on("finish", () => file.close(() =>
|
|
5086
|
+
file.on("finish", () => file.close(() => resolve9(dest)));
|
|
5087
5087
|
file.on("error", (err) => {
|
|
5088
5088
|
file.close(() => {
|
|
5089
5089
|
cleanup();
|
|
@@ -5233,7 +5233,7 @@ var init_cloudflare = __esm({
|
|
|
5233
5233
|
if (this.options.domain) {
|
|
5234
5234
|
args2.push("--hostname", String(this.options.domain));
|
|
5235
5235
|
}
|
|
5236
|
-
return new Promise((
|
|
5236
|
+
return new Promise((resolve9, reject) => {
|
|
5237
5237
|
let settled = false;
|
|
5238
5238
|
const settle = (fn) => {
|
|
5239
5239
|
if (!settled) {
|
|
@@ -5261,7 +5261,7 @@ var init_cloudflare = __esm({
|
|
|
5261
5261
|
clearTimeout(timeout);
|
|
5262
5262
|
this.publicUrl = match[0];
|
|
5263
5263
|
log4.info({ url: this.publicUrl }, "Cloudflare tunnel ready");
|
|
5264
|
-
settle(() =>
|
|
5264
|
+
settle(() => resolve9(this.publicUrl));
|
|
5265
5265
|
}
|
|
5266
5266
|
};
|
|
5267
5267
|
this.child.stdout?.on("data", onData);
|
|
@@ -5294,8 +5294,8 @@ var init_cloudflare = __esm({
|
|
|
5294
5294
|
}
|
|
5295
5295
|
child.kill("SIGTERM");
|
|
5296
5296
|
const exited = await Promise.race([
|
|
5297
|
-
new Promise((
|
|
5298
|
-
new Promise((
|
|
5297
|
+
new Promise((resolve9) => child.on("exit", () => resolve9(true))),
|
|
5298
|
+
new Promise((resolve9) => setTimeout(() => resolve9(false), SIGKILL_TIMEOUT_MS))
|
|
5299
5299
|
]);
|
|
5300
5300
|
if (!exited) {
|
|
5301
5301
|
log4.warn("cloudflared did not exit after SIGTERM, sending SIGKILL");
|
|
@@ -5348,7 +5348,7 @@ var init_ngrok = __esm({
|
|
|
5348
5348
|
if (this.options.region) {
|
|
5349
5349
|
args2.push("--region", String(this.options.region));
|
|
5350
5350
|
}
|
|
5351
|
-
return new Promise((
|
|
5351
|
+
return new Promise((resolve9, reject) => {
|
|
5352
5352
|
let settled = false;
|
|
5353
5353
|
const settle = (fn) => {
|
|
5354
5354
|
if (!settled) {
|
|
@@ -5378,7 +5378,7 @@ var init_ngrok = __esm({
|
|
|
5378
5378
|
clearTimeout(timeout);
|
|
5379
5379
|
this.publicUrl = match[0];
|
|
5380
5380
|
log5.info({ url: this.publicUrl }, "ngrok tunnel ready");
|
|
5381
|
-
settle(() =>
|
|
5381
|
+
settle(() => resolve9(this.publicUrl));
|
|
5382
5382
|
}
|
|
5383
5383
|
};
|
|
5384
5384
|
this.child.stdout?.on("data", onData);
|
|
@@ -5413,8 +5413,8 @@ var init_ngrok = __esm({
|
|
|
5413
5413
|
}
|
|
5414
5414
|
child.kill("SIGTERM");
|
|
5415
5415
|
const exited = await Promise.race([
|
|
5416
|
-
new Promise((
|
|
5417
|
-
new Promise((
|
|
5416
|
+
new Promise((resolve9) => child.on("exit", () => resolve9(true))),
|
|
5417
|
+
new Promise((resolve9) => setTimeout(() => resolve9(false), SIGKILL_TIMEOUT_MS2))
|
|
5418
5418
|
]);
|
|
5419
5419
|
if (!exited) {
|
|
5420
5420
|
log5.warn("ngrok did not exit after SIGTERM, sending SIGKILL");
|
|
@@ -5458,7 +5458,7 @@ var init_bore = __esm({
|
|
|
5458
5458
|
if (this.options.secret) {
|
|
5459
5459
|
args2.push("--secret", String(this.options.secret));
|
|
5460
5460
|
}
|
|
5461
|
-
return new Promise((
|
|
5461
|
+
return new Promise((resolve9, reject) => {
|
|
5462
5462
|
let settled = false;
|
|
5463
5463
|
const settle = (fn) => {
|
|
5464
5464
|
if (!settled) {
|
|
@@ -5488,7 +5488,7 @@ var init_bore = __esm({
|
|
|
5488
5488
|
clearTimeout(timeout);
|
|
5489
5489
|
this.publicUrl = `http://${match[1]}:${match[2]}`;
|
|
5490
5490
|
log6.info({ url: this.publicUrl }, "Bore tunnel ready");
|
|
5491
|
-
settle(() =>
|
|
5491
|
+
settle(() => resolve9(this.publicUrl));
|
|
5492
5492
|
}
|
|
5493
5493
|
};
|
|
5494
5494
|
this.child.stdout?.on("data", onData);
|
|
@@ -5523,8 +5523,8 @@ var init_bore = __esm({
|
|
|
5523
5523
|
}
|
|
5524
5524
|
child.kill("SIGTERM");
|
|
5525
5525
|
const exited = await Promise.race([
|
|
5526
|
-
new Promise((
|
|
5527
|
-
new Promise((
|
|
5526
|
+
new Promise((resolve9) => child.on("exit", () => resolve9(true))),
|
|
5527
|
+
new Promise((resolve9) => setTimeout(() => resolve9(false), SIGKILL_TIMEOUT_MS3))
|
|
5528
5528
|
]);
|
|
5529
5529
|
if (!exited) {
|
|
5530
5530
|
log6.warn("bore did not exit after SIGTERM, sending SIGKILL");
|
|
@@ -5573,7 +5573,7 @@ var init_tailscale = __esm({
|
|
|
5573
5573
|
if (this.options.bg) {
|
|
5574
5574
|
args2.push("--bg");
|
|
5575
5575
|
}
|
|
5576
|
-
return new Promise((
|
|
5576
|
+
return new Promise((resolve9, reject) => {
|
|
5577
5577
|
let settled = false;
|
|
5578
5578
|
const settle = (fn) => {
|
|
5579
5579
|
if (!settled) {
|
|
@@ -5603,7 +5603,7 @@ var init_tailscale = __esm({
|
|
|
5603
5603
|
clearTimeout(timeout);
|
|
5604
5604
|
this.publicUrl = match[0];
|
|
5605
5605
|
log7.info({ url: this.publicUrl }, "Tailscale funnel ready");
|
|
5606
|
-
settle(() =>
|
|
5606
|
+
settle(() => resolve9(this.publicUrl));
|
|
5607
5607
|
}
|
|
5608
5608
|
};
|
|
5609
5609
|
this.child.stdout?.on("data", onData);
|
|
@@ -5621,7 +5621,7 @@ var init_tailscale = __esm({
|
|
|
5621
5621
|
this.publicUrl = `https://${hostname}:${localPort}`;
|
|
5622
5622
|
this.child = null;
|
|
5623
5623
|
log7.info({ url: this.publicUrl }, "Tailscale funnel ready (constructed from hostname)");
|
|
5624
|
-
settle(() =>
|
|
5624
|
+
settle(() => resolve9(this.publicUrl));
|
|
5625
5625
|
} else {
|
|
5626
5626
|
settle(() => reject(new Error(`tailscale exited with code ${code} before establishing funnel`)));
|
|
5627
5627
|
}
|
|
@@ -5645,8 +5645,8 @@ var init_tailscale = __esm({
|
|
|
5645
5645
|
}
|
|
5646
5646
|
child.kill("SIGTERM");
|
|
5647
5647
|
const exited = await Promise.race([
|
|
5648
|
-
new Promise((
|
|
5649
|
-
new Promise((
|
|
5648
|
+
new Promise((resolve9) => child.on("exit", () => resolve9(true))),
|
|
5649
|
+
new Promise((resolve9) => setTimeout(() => resolve9(false), SIGKILL_TIMEOUT_MS4))
|
|
5650
5650
|
]);
|
|
5651
5651
|
if (!exited) {
|
|
5652
5652
|
log7.warn("tailscale did not exit after SIGTERM, sending SIGKILL");
|
|
@@ -5762,7 +5762,7 @@ var init_openacp = __esm({
|
|
|
5762
5762
|
}
|
|
5763
5763
|
async spawnCloudflared(binaryPath, token, port) {
|
|
5764
5764
|
const args2 = ["tunnel", "run", "--url", `http://localhost:${port}`, "--token", token];
|
|
5765
|
-
return new Promise((
|
|
5765
|
+
return new Promise((resolve9, reject) => {
|
|
5766
5766
|
let settled = false;
|
|
5767
5767
|
const settle = (fn) => {
|
|
5768
5768
|
if (!settled) {
|
|
@@ -5772,7 +5772,7 @@ var init_openacp = __esm({
|
|
|
5772
5772
|
};
|
|
5773
5773
|
const timeout = setTimeout(() => {
|
|
5774
5774
|
log8.info({ port }, "cloudflared still running after startup window \u2014 assuming tunnel active");
|
|
5775
|
-
settle(
|
|
5775
|
+
settle(resolve9);
|
|
5776
5776
|
}, STARTUP_TIMEOUT_MS);
|
|
5777
5777
|
let child;
|
|
5778
5778
|
try {
|
|
@@ -5788,7 +5788,7 @@ var init_openacp = __esm({
|
|
|
5788
5788
|
if (/Registered tunnel connection/.test(line)) {
|
|
5789
5789
|
clearTimeout(timeout);
|
|
5790
5790
|
log8.info({ port }, "cloudflared connection registered");
|
|
5791
|
-
settle(
|
|
5791
|
+
settle(resolve9);
|
|
5792
5792
|
}
|
|
5793
5793
|
};
|
|
5794
5794
|
child.stdout?.on("data", onData);
|
|
@@ -7430,7 +7430,8 @@ __export(instance_context_exports, {
|
|
|
7430
7430
|
createInstanceContext: () => createInstanceContext,
|
|
7431
7431
|
generateSlug: () => generateSlug,
|
|
7432
7432
|
getGlobalRoot: () => getGlobalRoot,
|
|
7433
|
-
resolveInstanceRoot: () => resolveInstanceRoot
|
|
7433
|
+
resolveInstanceRoot: () => resolveInstanceRoot,
|
|
7434
|
+
resolveRunningInstance: () => resolveRunningInstance
|
|
7434
7435
|
});
|
|
7435
7436
|
import path23 from "path";
|
|
7436
7437
|
import fs18 from "fs";
|
|
@@ -7482,6 +7483,38 @@ function resolveInstanceRoot(opts) {
|
|
|
7482
7483
|
function getGlobalRoot() {
|
|
7483
7484
|
return path23.join(os11.homedir(), ".openacp");
|
|
7484
7485
|
}
|
|
7486
|
+
async function resolveRunningInstance(cwd) {
|
|
7487
|
+
const globalRoot = getGlobalRoot();
|
|
7488
|
+
let dir = path23.resolve(cwd);
|
|
7489
|
+
while (true) {
|
|
7490
|
+
const candidate = path23.join(dir, ".openacp");
|
|
7491
|
+
if (candidate !== globalRoot && fs18.existsSync(candidate)) {
|
|
7492
|
+
if (await isInstanceRunning(candidate)) return candidate;
|
|
7493
|
+
}
|
|
7494
|
+
const parent = path23.dirname(dir);
|
|
7495
|
+
if (parent === dir) break;
|
|
7496
|
+
dir = parent;
|
|
7497
|
+
}
|
|
7498
|
+
if (fs18.existsSync(globalRoot) && await isInstanceRunning(globalRoot)) return globalRoot;
|
|
7499
|
+
return null;
|
|
7500
|
+
}
|
|
7501
|
+
async function isInstanceRunning(instanceRoot) {
|
|
7502
|
+
const portFile = path23.join(instanceRoot, "api.port");
|
|
7503
|
+
try {
|
|
7504
|
+
const content = fs18.readFileSync(portFile, "utf-8").trim();
|
|
7505
|
+
const port = parseInt(content, 10);
|
|
7506
|
+
if (isNaN(port)) return false;
|
|
7507
|
+
const controller = new AbortController();
|
|
7508
|
+
const timeout = setTimeout(() => controller.abort(), 2e3);
|
|
7509
|
+
const res = await fetch(`http://127.0.0.1:${port}/api/v1/system/health`, {
|
|
7510
|
+
signal: controller.signal
|
|
7511
|
+
});
|
|
7512
|
+
clearTimeout(timeout);
|
|
7513
|
+
return res.ok;
|
|
7514
|
+
} catch {
|
|
7515
|
+
return false;
|
|
7516
|
+
}
|
|
7517
|
+
}
|
|
7485
7518
|
var init_instance_context = __esm({
|
|
7486
7519
|
"src/core/instance/instance-context.ts"() {
|
|
7487
7520
|
"use strict";
|
|
@@ -14017,12 +14050,12 @@ function isProcessAlive(pid) {
|
|
|
14017
14050
|
}
|
|
14018
14051
|
}
|
|
14019
14052
|
function checkPortInUse(port) {
|
|
14020
|
-
return new Promise((
|
|
14053
|
+
return new Promise((resolve9) => {
|
|
14021
14054
|
const server = net.createServer();
|
|
14022
|
-
server.once("error", () =>
|
|
14055
|
+
server.once("error", () => resolve9(true));
|
|
14023
14056
|
server.once("listening", () => {
|
|
14024
14057
|
server.close();
|
|
14025
|
-
|
|
14058
|
+
resolve9(false);
|
|
14026
14059
|
});
|
|
14027
14060
|
server.listen(port, "127.0.0.1");
|
|
14028
14061
|
});
|
|
@@ -15175,8 +15208,27 @@ var init_stream_accumulator = __esm({
|
|
|
15175
15208
|
}
|
|
15176
15209
|
});
|
|
15177
15210
|
|
|
15178
|
-
// src/core/
|
|
15211
|
+
// src/core/utils/apply-patch-detection.ts
|
|
15179
15212
|
function asRecord(value) {
|
|
15213
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
15214
|
+
}
|
|
15215
|
+
function hasApplyPatchPatchText(rawInput) {
|
|
15216
|
+
const input2 = asRecord(rawInput);
|
|
15217
|
+
return !!input2 && (typeof input2.patchText === "string" || typeof input2.patch_text === "string");
|
|
15218
|
+
}
|
|
15219
|
+
function isApplyPatchOtherTool(kind, name, rawInput) {
|
|
15220
|
+
if (kind !== "other") return false;
|
|
15221
|
+
if (name.toLowerCase() === "apply_patch") return true;
|
|
15222
|
+
return hasApplyPatchPatchText(rawInput);
|
|
15223
|
+
}
|
|
15224
|
+
var init_apply_patch_detection = __esm({
|
|
15225
|
+
"src/core/utils/apply-patch-detection.ts"() {
|
|
15226
|
+
"use strict";
|
|
15227
|
+
}
|
|
15228
|
+
});
|
|
15229
|
+
|
|
15230
|
+
// src/core/adapter-primitives/display-spec-builder.ts
|
|
15231
|
+
function asRecord2(value) {
|
|
15180
15232
|
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
15181
15233
|
return value;
|
|
15182
15234
|
}
|
|
@@ -15209,8 +15261,21 @@ function parseApplyPatchTargets(patchText) {
|
|
|
15209
15261
|
function buildTitle(entry, kind) {
|
|
15210
15262
|
if (entry.displayTitle) return entry.displayTitle;
|
|
15211
15263
|
if (entry.displaySummary) return entry.displaySummary;
|
|
15212
|
-
const input2 =
|
|
15264
|
+
const input2 = asRecord2(entry.rawInput);
|
|
15213
15265
|
const nameLower = entry.name.toLowerCase();
|
|
15266
|
+
if (isApplyPatchOtherTool(entry.kind, entry.name, entry.rawInput)) {
|
|
15267
|
+
const patchText = getStringField(input2, ["patchText", "patch_text"]);
|
|
15268
|
+
if (patchText) {
|
|
15269
|
+
const targets = parseApplyPatchTargets(patchText);
|
|
15270
|
+
if (targets.length === 1) return targets[0];
|
|
15271
|
+
if (targets.length > 1) {
|
|
15272
|
+
const shown = targets.slice(0, 2).join(", ");
|
|
15273
|
+
const rest = targets.length - 2;
|
|
15274
|
+
return rest > 0 ? `${shown} (+${rest} more)` : shown;
|
|
15275
|
+
}
|
|
15276
|
+
}
|
|
15277
|
+
return "apply_patch";
|
|
15278
|
+
}
|
|
15214
15279
|
if (kind === "read") {
|
|
15215
15280
|
const filePath = getStringField(input2, ["file_path", "filePath", "path"]);
|
|
15216
15281
|
if (filePath) {
|
|
@@ -15259,36 +15324,6 @@ function buildTitle(entry, kind) {
|
|
|
15259
15324
|
}
|
|
15260
15325
|
return capitalize(entry.name);
|
|
15261
15326
|
}
|
|
15262
|
-
if (nameLower === "apply_patch") {
|
|
15263
|
-
const patchText = getStringField(input2, ["patchText", "patch_text"]);
|
|
15264
|
-
if (patchText) {
|
|
15265
|
-
const targets = parseApplyPatchTargets(patchText);
|
|
15266
|
-
if (targets.length === 1) return targets[0];
|
|
15267
|
-
if (targets.length > 1) {
|
|
15268
|
-
const shown = targets.slice(0, 2).join(", ");
|
|
15269
|
-
const remaining2 = targets.length - 2;
|
|
15270
|
-
return remaining2 > 0 ? `${shown} (+${remaining2} more)` : shown;
|
|
15271
|
-
}
|
|
15272
|
-
}
|
|
15273
|
-
return "apply_patch";
|
|
15274
|
-
}
|
|
15275
|
-
if (nameLower === "todowrite") {
|
|
15276
|
-
const todos = Array.isArray(input2.todos) ? input2.todos : [];
|
|
15277
|
-
if (todos.length > 0) {
|
|
15278
|
-
const inProgress = todos.filter((t) => {
|
|
15279
|
-
if (!t || typeof t !== "object") return false;
|
|
15280
|
-
const status = t.status;
|
|
15281
|
-
return status === "in_progress";
|
|
15282
|
-
}).length;
|
|
15283
|
-
const completed = todos.filter((t) => {
|
|
15284
|
-
if (!t || typeof t !== "object") return false;
|
|
15285
|
-
const status = t.status;
|
|
15286
|
-
return status === "completed";
|
|
15287
|
-
}).length;
|
|
15288
|
-
return `Todo list (${completed}/${todos.length} done${inProgress > 0 ? `, ${inProgress} active` : ""})`;
|
|
15289
|
-
}
|
|
15290
|
-
return "Todo list";
|
|
15291
|
-
}
|
|
15292
15327
|
if (kind === "fetch" || kind === "web") {
|
|
15293
15328
|
const url = typeof input2.url === "string" ? input2.url : null;
|
|
15294
15329
|
if (url && url !== "undefined") return url.length > 60 ? url.slice(0, 57) + "..." : url;
|
|
@@ -15299,19 +15334,6 @@ function buildTitle(entry, kind) {
|
|
|
15299
15334
|
if (nameLower === "skill" && typeof input2.skill === "string" && input2.skill) {
|
|
15300
15335
|
return input2.skill;
|
|
15301
15336
|
}
|
|
15302
|
-
if (nameLower === "apply_patch") {
|
|
15303
|
-
const patchText = getStringField(input2, ["patchText", "patch_text"]);
|
|
15304
|
-
if (patchText) {
|
|
15305
|
-
const targets = parseApplyPatchTargets(patchText);
|
|
15306
|
-
if (targets.length === 1) return targets[0];
|
|
15307
|
-
if (targets.length > 1) {
|
|
15308
|
-
const shown = targets.slice(0, 2).join(", ");
|
|
15309
|
-
const rest = targets.length - 2;
|
|
15310
|
-
return rest > 0 ? `${shown} (+${rest} more)` : shown;
|
|
15311
|
-
}
|
|
15312
|
-
}
|
|
15313
|
-
return "apply_patch";
|
|
15314
|
-
}
|
|
15315
15337
|
if (nameLower === "todowrite") {
|
|
15316
15338
|
const todos = Array.isArray(input2.todos) ? input2.todos : [];
|
|
15317
15339
|
if (todos.length > 0) {
|
|
@@ -15341,6 +15363,7 @@ var init_display_spec_builder = __esm({
|
|
|
15341
15363
|
"src/core/adapter-primitives/display-spec-builder.ts"() {
|
|
15342
15364
|
"use strict";
|
|
15343
15365
|
init_format_types();
|
|
15366
|
+
init_apply_patch_detection();
|
|
15344
15367
|
EXECUTE_KINDS = /* @__PURE__ */ new Set(["execute", "bash", "command", "terminal"]);
|
|
15345
15368
|
INLINE_MAX_LINES = 15;
|
|
15346
15369
|
INLINE_MAX_CHARS = 800;
|
|
@@ -15349,12 +15372,12 @@ var init_display_spec_builder = __esm({
|
|
|
15349
15372
|
this.tunnelService = tunnelService;
|
|
15350
15373
|
}
|
|
15351
15374
|
buildToolSpec(entry, mode, sessionContext) {
|
|
15352
|
-
const effectiveKind = entry.displayKind ?? entry.kind;
|
|
15375
|
+
const effectiveKind = entry.displayKind ?? (isApplyPatchOtherTool(entry.kind, entry.name, entry.rawInput) ? "edit" : entry.kind);
|
|
15353
15376
|
const icon = KIND_ICONS[effectiveKind] ?? KIND_ICONS["other"] ?? "\u{1F6E0}\uFE0F";
|
|
15354
15377
|
const title = buildTitle(entry, effectiveKind);
|
|
15355
15378
|
const isHidden = entry.isNoise && mode !== "high";
|
|
15356
15379
|
const includeMeta = mode !== "low";
|
|
15357
|
-
const input2 =
|
|
15380
|
+
const input2 = asRecord2(entry.rawInput);
|
|
15358
15381
|
const rawDescription = typeof input2.description === "string" ? input2.description : null;
|
|
15359
15382
|
const descLower = rawDescription?.toLowerCase();
|
|
15360
15383
|
const description = includeMeta && rawDescription && rawDescription !== title && descLower !== effectiveKind && descLower !== entry.name.toLowerCase() ? rawDescription : null;
|
|
@@ -15800,10 +15823,10 @@ var init_send_queue = __esm({
|
|
|
15800
15823
|
const type = opts?.type ?? "other";
|
|
15801
15824
|
const key = opts?.key;
|
|
15802
15825
|
const category = opts?.category;
|
|
15803
|
-
let
|
|
15826
|
+
let resolve9;
|
|
15804
15827
|
let reject;
|
|
15805
15828
|
const promise = new Promise((res, rej) => {
|
|
15806
|
-
|
|
15829
|
+
resolve9 = res;
|
|
15807
15830
|
reject = rej;
|
|
15808
15831
|
});
|
|
15809
15832
|
promise.catch(() => {
|
|
@@ -15814,12 +15837,12 @@ var init_send_queue = __esm({
|
|
|
15814
15837
|
);
|
|
15815
15838
|
if (idx !== -1) {
|
|
15816
15839
|
this.items[idx].resolve(void 0);
|
|
15817
|
-
this.items[idx] = { fn, type, key, category, resolve:
|
|
15840
|
+
this.items[idx] = { fn, type, key, category, resolve: resolve9, reject, promise };
|
|
15818
15841
|
this.scheduleProcess();
|
|
15819
15842
|
return promise;
|
|
15820
15843
|
}
|
|
15821
15844
|
}
|
|
15822
|
-
this.items.push({ fn, type, key, category, resolve:
|
|
15845
|
+
this.items.push({ fn, type, key, category, resolve: resolve9, reject, promise });
|
|
15823
15846
|
this.scheduleProcess();
|
|
15824
15847
|
return promise;
|
|
15825
15848
|
}
|
|
@@ -18566,7 +18589,7 @@ function startDaemon(pidPath = getPidPath(), logDir2, instanceRoot) {
|
|
|
18566
18589
|
return { pid: child.pid };
|
|
18567
18590
|
}
|
|
18568
18591
|
function sleep(ms) {
|
|
18569
|
-
return new Promise((
|
|
18592
|
+
return new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
18570
18593
|
}
|
|
18571
18594
|
function isProcessAlive2(pid) {
|
|
18572
18595
|
try {
|
|
@@ -18848,15 +18871,15 @@ var init_env_filter = __esm({
|
|
|
18848
18871
|
function nodeToWebWritable(nodeStream) {
|
|
18849
18872
|
return new WritableStream({
|
|
18850
18873
|
write(chunk) {
|
|
18851
|
-
return new Promise((
|
|
18874
|
+
return new Promise((resolve9, reject) => {
|
|
18852
18875
|
const ok3 = nodeStream.write(chunk);
|
|
18853
18876
|
if (ok3) {
|
|
18854
|
-
|
|
18877
|
+
resolve9();
|
|
18855
18878
|
return;
|
|
18856
18879
|
}
|
|
18857
18880
|
const onDrain = () => {
|
|
18858
18881
|
nodeStream.removeListener("error", onError);
|
|
18859
|
-
|
|
18882
|
+
resolve9();
|
|
18860
18883
|
};
|
|
18861
18884
|
const onError = (err) => {
|
|
18862
18885
|
nodeStream.removeListener("drain", onDrain);
|
|
@@ -19166,12 +19189,12 @@ var init_terminal_manager = __esm({
|
|
|
19166
19189
|
signal: state.exitStatus.signal
|
|
19167
19190
|
};
|
|
19168
19191
|
}
|
|
19169
|
-
return new Promise((
|
|
19192
|
+
return new Promise((resolve9) => {
|
|
19170
19193
|
state.process.on("exit", (code, signal) => {
|
|
19171
|
-
|
|
19194
|
+
resolve9({ exitCode: code, signal });
|
|
19172
19195
|
});
|
|
19173
19196
|
if (state.exitStatus !== null) {
|
|
19174
|
-
|
|
19197
|
+
resolve9({
|
|
19175
19198
|
exitCode: state.exitStatus.exitCode,
|
|
19176
19199
|
signal: state.exitStatus.signal
|
|
19177
19200
|
});
|
|
@@ -19319,18 +19342,41 @@ function resolveAgentCommand(cmd) {
|
|
|
19319
19342
|
try {
|
|
19320
19343
|
const fullPath = execFileSync6("which", [cmd], { encoding: "utf-8" }).trim();
|
|
19321
19344
|
if (fullPath) {
|
|
19322
|
-
|
|
19323
|
-
|
|
19324
|
-
|
|
19345
|
+
try {
|
|
19346
|
+
const content = fs40.readFileSync(fullPath, "utf-8");
|
|
19347
|
+
if (content.startsWith("#!/usr/bin/env node")) {
|
|
19348
|
+
return { command: process.execPath, args: [fullPath] };
|
|
19349
|
+
}
|
|
19350
|
+
} catch {
|
|
19325
19351
|
}
|
|
19352
|
+
return { command: fullPath, args: [] };
|
|
19326
19353
|
}
|
|
19327
19354
|
} catch {
|
|
19328
19355
|
}
|
|
19329
19356
|
if (cmd === "npx" || cmd === "uvx") {
|
|
19330
|
-
const
|
|
19331
|
-
|
|
19332
|
-
|
|
19357
|
+
const seen = /* @__PURE__ */ new Set();
|
|
19358
|
+
const candidates = [];
|
|
19359
|
+
const addCandidate = (dir) => {
|
|
19360
|
+
if (!seen.has(dir)) {
|
|
19361
|
+
seen.add(dir);
|
|
19362
|
+
candidates.push(dir);
|
|
19363
|
+
}
|
|
19364
|
+
};
|
|
19365
|
+
addCandidate(path44.dirname(process.execPath));
|
|
19366
|
+
try {
|
|
19367
|
+
addCandidate(path44.dirname(fs40.realpathSync(process.execPath)));
|
|
19368
|
+
} catch {
|
|
19333
19369
|
}
|
|
19370
|
+
addCandidate("/opt/homebrew/bin");
|
|
19371
|
+
addCandidate("/usr/local/bin");
|
|
19372
|
+
for (const dir of candidates) {
|
|
19373
|
+
const candidate = path44.join(dir, cmd);
|
|
19374
|
+
if (fs40.existsSync(candidate)) {
|
|
19375
|
+
log31.info({ cmd, resolved: candidate }, "Resolved package runner from fallback search");
|
|
19376
|
+
return { command: candidate, args: [] };
|
|
19377
|
+
}
|
|
19378
|
+
}
|
|
19379
|
+
log31.warn({ cmd, execPath: process.execPath, candidates }, "Could not find package runner");
|
|
19334
19380
|
}
|
|
19335
19381
|
return { command: cmd, args: [] };
|
|
19336
19382
|
}
|
|
@@ -19405,7 +19451,7 @@ var init_agent_instance = __esm({
|
|
|
19405
19451
|
env: filterEnv(process.env, agentDef.env)
|
|
19406
19452
|
}
|
|
19407
19453
|
);
|
|
19408
|
-
await new Promise((
|
|
19454
|
+
await new Promise((resolve9, reject) => {
|
|
19409
19455
|
instance.child.on("error", (err) => {
|
|
19410
19456
|
reject(
|
|
19411
19457
|
new Error(
|
|
@@ -19413,7 +19459,7 @@ var init_agent_instance = __esm({
|
|
|
19413
19459
|
)
|
|
19414
19460
|
);
|
|
19415
19461
|
});
|
|
19416
|
-
instance.child.on("spawn", () =>
|
|
19462
|
+
instance.child.on("spawn", () => resolve9());
|
|
19417
19463
|
});
|
|
19418
19464
|
instance.stderrCapture = new StderrCapture(50);
|
|
19419
19465
|
instance.child.stderr.on("data", (chunk) => {
|
|
@@ -19919,15 +19965,15 @@ ${skipNote}`;
|
|
|
19919
19965
|
this._destroying = true;
|
|
19920
19966
|
this.terminalManager.destroyAll();
|
|
19921
19967
|
if (this.child.exitCode !== null) return;
|
|
19922
|
-
await new Promise((
|
|
19968
|
+
await new Promise((resolve9) => {
|
|
19923
19969
|
this.child.on("exit", () => {
|
|
19924
19970
|
clearTimeout(forceKillTimer);
|
|
19925
|
-
|
|
19971
|
+
resolve9();
|
|
19926
19972
|
});
|
|
19927
19973
|
this.child.kill("SIGTERM");
|
|
19928
19974
|
const forceKillTimer = setTimeout(() => {
|
|
19929
19975
|
if (this.child.exitCode === null) this.child.kill("SIGKILL");
|
|
19930
|
-
|
|
19976
|
+
resolve9();
|
|
19931
19977
|
}, 1e4);
|
|
19932
19978
|
if (typeof forceKillTimer === "object" && forceKillTimer !== null && "unref" in forceKillTimer) {
|
|
19933
19979
|
forceKillTimer.unref();
|
|
@@ -19991,8 +20037,8 @@ var init_prompt_queue = __esm({
|
|
|
19991
20037
|
processorSettled = null;
|
|
19992
20038
|
async enqueue(text6, attachments, routing, turnId) {
|
|
19993
20039
|
if (this.processing) {
|
|
19994
|
-
return new Promise((
|
|
19995
|
-
this.queue.push({ text: text6, attachments, routing, turnId, resolve:
|
|
20040
|
+
return new Promise((resolve9) => {
|
|
20041
|
+
this.queue.push({ text: text6, attachments, routing, turnId, resolve: resolve9 });
|
|
19996
20042
|
});
|
|
19997
20043
|
}
|
|
19998
20044
|
await this.process(text6, attachments, routing, turnId);
|
|
@@ -20072,8 +20118,8 @@ var init_permission_gate = __esm({
|
|
|
20072
20118
|
this.request = request;
|
|
20073
20119
|
this.settled = false;
|
|
20074
20120
|
this.clearTimeout();
|
|
20075
|
-
return new Promise((
|
|
20076
|
-
this.resolveFn =
|
|
20121
|
+
return new Promise((resolve9, reject) => {
|
|
20122
|
+
this.resolveFn = resolve9;
|
|
20077
20123
|
this.rejectFn = reject;
|
|
20078
20124
|
this.timeoutTimer = setTimeout(() => {
|
|
20079
20125
|
this.reject("Permission request timed out (no response received)");
|
|
@@ -21321,7 +21367,10 @@ var init_session_bridge = __esm({
|
|
|
21321
21367
|
});
|
|
21322
21368
|
|
|
21323
21369
|
// src/core/utils/extract-file-info.ts
|
|
21324
|
-
function extractFileInfo(name, kind, content, rawInput, meta) {
|
|
21370
|
+
function extractFileInfo(name, kind, content, rawInput, meta, rawOutput) {
|
|
21371
|
+
if (isApplyPatchOtherTool(kind, name, rawInput)) {
|
|
21372
|
+
return parseApplyPatchRawOutput(rawOutput);
|
|
21373
|
+
}
|
|
21325
21374
|
if (kind && !["read", "edit", "write"].includes(kind)) return null;
|
|
21326
21375
|
let info = null;
|
|
21327
21376
|
if (meta) {
|
|
@@ -21376,6 +21425,37 @@ function extractFileInfo(name, kind, content, rawInput, meta) {
|
|
|
21376
21425
|
if (!info.filePath || !info.content) return null;
|
|
21377
21426
|
return info;
|
|
21378
21427
|
}
|
|
21428
|
+
function parseApplyPatchRawOutput(rawOutput) {
|
|
21429
|
+
if (!rawOutput || typeof rawOutput !== "object" || Array.isArray(rawOutput)) return null;
|
|
21430
|
+
const output = rawOutput;
|
|
21431
|
+
const metadata = output.metadata;
|
|
21432
|
+
if (!metadata || typeof metadata !== "object" || Array.isArray(metadata)) return null;
|
|
21433
|
+
const files = metadata.files;
|
|
21434
|
+
if (!Array.isArray(files)) return null;
|
|
21435
|
+
const sortedFiles = [...files].sort((a, b) => getApplyPatchFileScore(b) - getApplyPatchFileScore(a));
|
|
21436
|
+
for (const file of sortedFiles) {
|
|
21437
|
+
if (!file || typeof file !== "object" || Array.isArray(file)) continue;
|
|
21438
|
+
const f = file;
|
|
21439
|
+
const filePath = typeof f.filePath === "string" ? f.filePath : typeof f.relativePath === "string" ? f.relativePath : null;
|
|
21440
|
+
if (!filePath) continue;
|
|
21441
|
+
const after = typeof f.after === "string" ? f.after : null;
|
|
21442
|
+
if (!after) continue;
|
|
21443
|
+
const before = typeof f.before === "string" ? f.before : void 0;
|
|
21444
|
+
return {
|
|
21445
|
+
filePath,
|
|
21446
|
+
content: after,
|
|
21447
|
+
oldContent: before
|
|
21448
|
+
};
|
|
21449
|
+
}
|
|
21450
|
+
return null;
|
|
21451
|
+
}
|
|
21452
|
+
function getApplyPatchFileScore(file) {
|
|
21453
|
+
if (!file || typeof file !== "object" || Array.isArray(file)) return 0;
|
|
21454
|
+
const f = file;
|
|
21455
|
+
const additions = typeof f.additions === "number" && Number.isFinite(f.additions) && f.additions >= 0 ? f.additions : 0;
|
|
21456
|
+
const deletions = typeof f.deletions === "number" && Number.isFinite(f.deletions) && f.deletions >= 0 ? f.deletions : 0;
|
|
21457
|
+
return additions + deletions;
|
|
21458
|
+
}
|
|
21379
21459
|
function resolveToolResponse(meta) {
|
|
21380
21460
|
const claudeCode = meta.claudeCode;
|
|
21381
21461
|
if (claudeCode?.toolResponse && typeof claudeCode.toolResponse === "object") {
|
|
@@ -21444,6 +21524,7 @@ function parseContent(content) {
|
|
|
21444
21524
|
var init_extract_file_info = __esm({
|
|
21445
21525
|
"src/core/utils/extract-file-info.ts"() {
|
|
21446
21526
|
"use strict";
|
|
21527
|
+
init_apply_patch_detection();
|
|
21447
21528
|
}
|
|
21448
21529
|
});
|
|
21449
21530
|
|
|
@@ -21467,11 +21548,69 @@ function computeLineDiff(oldStr, newStr) {
|
|
|
21467
21548
|
removed: Math.max(0, oldLines.length - prefixLen - suffixLen)
|
|
21468
21549
|
};
|
|
21469
21550
|
}
|
|
21551
|
+
function asRecord3(value) {
|
|
21552
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
21553
|
+
}
|
|
21554
|
+
function asNonNegativeNumber(value) {
|
|
21555
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : null;
|
|
21556
|
+
}
|
|
21557
|
+
function extractDiffStatsFromRawOutput(rawOutput) {
|
|
21558
|
+
const output = asRecord3(rawOutput);
|
|
21559
|
+
const metadata = asRecord3(output?.metadata);
|
|
21560
|
+
if (!metadata) return null;
|
|
21561
|
+
const files = Array.isArray(metadata.files) ? metadata.files : null;
|
|
21562
|
+
if (files && files.length > 0) {
|
|
21563
|
+
let added2 = 0;
|
|
21564
|
+
let removed2 = 0;
|
|
21565
|
+
let hasAny = false;
|
|
21566
|
+
for (const file of files) {
|
|
21567
|
+
const fileMeta = asRecord3(file);
|
|
21568
|
+
if (!fileMeta) continue;
|
|
21569
|
+
const fileAdded = asNonNegativeNumber(fileMeta.additions);
|
|
21570
|
+
const fileRemoved = asNonNegativeNumber(fileMeta.deletions);
|
|
21571
|
+
if (fileAdded === null && fileRemoved === null) continue;
|
|
21572
|
+
added2 += fileAdded ?? 0;
|
|
21573
|
+
removed2 += fileRemoved ?? 0;
|
|
21574
|
+
hasAny = true;
|
|
21575
|
+
}
|
|
21576
|
+
if (hasAny && (added2 > 0 || removed2 > 0)) return { added: added2, removed: removed2 };
|
|
21577
|
+
}
|
|
21578
|
+
const added = asNonNegativeNumber(metadata.additions);
|
|
21579
|
+
const removed = asNonNegativeNumber(metadata.deletions);
|
|
21580
|
+
if (added === null && removed === null) return null;
|
|
21581
|
+
if ((added ?? 0) === 0 && (removed ?? 0) === 0) return null;
|
|
21582
|
+
return {
|
|
21583
|
+
added: added ?? 0,
|
|
21584
|
+
removed: removed ?? 0
|
|
21585
|
+
};
|
|
21586
|
+
}
|
|
21587
|
+
function extractDiffStatsFromToolPayload(name, kind, rawInput, rawOutput) {
|
|
21588
|
+
if (kind === "edit" || kind === "write") {
|
|
21589
|
+
const ri = asRecord3(rawInput);
|
|
21590
|
+
if (!ri) return null;
|
|
21591
|
+
const oldStr = typeof ri.old_string === "string" ? ri.old_string : typeof ri.oldText === "string" ? ri.oldText : null;
|
|
21592
|
+
const newStr = typeof ri.new_string === "string" ? ri.new_string : typeof ri.newText === "string" ? ri.newText : typeof ri.content === "string" ? ri.content : null;
|
|
21593
|
+
if (oldStr !== null && newStr !== null) {
|
|
21594
|
+
const stats = computeLineDiff(oldStr, newStr);
|
|
21595
|
+
return stats.added > 0 || stats.removed > 0 ? stats : null;
|
|
21596
|
+
}
|
|
21597
|
+
if (oldStr === null && newStr !== null && kind === "write") {
|
|
21598
|
+
const added = newStr.split("\n").length;
|
|
21599
|
+
return added > 0 ? { added, removed: 0 } : null;
|
|
21600
|
+
}
|
|
21601
|
+
return null;
|
|
21602
|
+
}
|
|
21603
|
+
if (isApplyPatchOtherTool(kind, name, rawInput)) {
|
|
21604
|
+
return extractDiffStatsFromRawOutput(rawOutput);
|
|
21605
|
+
}
|
|
21606
|
+
return null;
|
|
21607
|
+
}
|
|
21470
21608
|
var log33, BINARY_VIEWER_EXTENSIONS, MessageTransformer;
|
|
21471
21609
|
var init_message_transformer = __esm({
|
|
21472
21610
|
"src/core/message-transformer.ts"() {
|
|
21473
21611
|
"use strict";
|
|
21474
21612
|
init_extract_file_info();
|
|
21613
|
+
init_apply_patch_detection();
|
|
21475
21614
|
init_log();
|
|
21476
21615
|
log33 = createChildLogger({ module: "message-transformer" });
|
|
21477
21616
|
BINARY_VIEWER_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
@@ -21658,22 +21797,11 @@ var init_message_transformer = __esm({
|
|
|
21658
21797
|
return input2 !== null && input2 !== void 0 && typeof input2 === "object" && !Array.isArray(input2) && Object.keys(input2).length > 0;
|
|
21659
21798
|
}
|
|
21660
21799
|
enrichWithViewerLinks(event, metadata, sessionContext) {
|
|
21800
|
+
const name = "name" in event ? event.name || "" : "";
|
|
21661
21801
|
const kind = "kind" in event ? event.kind : void 0;
|
|
21662
|
-
if (!metadata.diffStats
|
|
21663
|
-
const
|
|
21664
|
-
if (
|
|
21665
|
-
const oldStr = typeof ri.old_string === "string" ? ri.old_string : typeof ri.oldText === "string" ? ri.oldText : null;
|
|
21666
|
-
const newStr = typeof ri.new_string === "string" ? ri.new_string : typeof ri.newText === "string" ? ri.newText : typeof ri.content === "string" ? ri.content : null;
|
|
21667
|
-
if (oldStr !== null && newStr !== null) {
|
|
21668
|
-
const stats = computeLineDiff(oldStr, newStr);
|
|
21669
|
-
if (stats.added > 0 || stats.removed > 0) {
|
|
21670
|
-
metadata.diffStats = stats;
|
|
21671
|
-
}
|
|
21672
|
-
} else if (oldStr === null && newStr !== null && kind === "write") {
|
|
21673
|
-
const added = newStr.split("\n").length;
|
|
21674
|
-
if (added > 0) metadata.diffStats = { added, removed: 0 };
|
|
21675
|
-
}
|
|
21676
|
-
}
|
|
21802
|
+
if (!metadata.diffStats) {
|
|
21803
|
+
const stats = extractDiffStatsFromToolPayload(name, kind, event.rawInput, event.rawOutput);
|
|
21804
|
+
if (stats) metadata.diffStats = stats;
|
|
21677
21805
|
}
|
|
21678
21806
|
if (!this.tunnelService || !sessionContext) {
|
|
21679
21807
|
log33.debug(
|
|
@@ -21682,7 +21810,6 @@ var init_message_transformer = __esm({
|
|
|
21682
21810
|
);
|
|
21683
21811
|
return;
|
|
21684
21812
|
}
|
|
21685
|
-
const name = "name" in event ? event.name || "" : "";
|
|
21686
21813
|
log33.debug(
|
|
21687
21814
|
{ name, kind, status: event.status, hasContent: !!event.content, hasRawInput: !!event.rawInput },
|
|
21688
21815
|
"enrichWithViewerLinks: inspecting event"
|
|
@@ -21692,7 +21819,8 @@ var init_message_transformer = __esm({
|
|
|
21692
21819
|
kind,
|
|
21693
21820
|
event.content,
|
|
21694
21821
|
event.rawInput,
|
|
21695
|
-
event.meta
|
|
21822
|
+
event.meta,
|
|
21823
|
+
event.rawOutput
|
|
21696
21824
|
);
|
|
21697
21825
|
if (!fileInfo) {
|
|
21698
21826
|
log33.debug(
|
|
@@ -22650,6 +22778,7 @@ var init_agent_catalog = __esm({
|
|
|
22650
22778
|
DEFAULT_TTL_HOURS = 24;
|
|
22651
22779
|
AgentCatalog = class {
|
|
22652
22780
|
store;
|
|
22781
|
+
globalStore = null;
|
|
22653
22782
|
registryAgents = [];
|
|
22654
22783
|
cachePath;
|
|
22655
22784
|
agentsDir;
|
|
@@ -22657,9 +22786,15 @@ var init_agent_catalog = __esm({
|
|
|
22657
22786
|
this.store = store ?? new AgentStore();
|
|
22658
22787
|
this.cachePath = cachePath ?? path48.join(os21.homedir(), ".openacp", "registry-cache.json");
|
|
22659
22788
|
this.agentsDir = agentsDir;
|
|
22789
|
+
const globalPath = path48.join(os21.homedir(), ".openacp", "agents.json");
|
|
22790
|
+
const storePath = this.store.filePath;
|
|
22791
|
+
if (path48.resolve(storePath) !== path48.resolve(globalPath)) {
|
|
22792
|
+
this.globalStore = new AgentStore(globalPath);
|
|
22793
|
+
}
|
|
22660
22794
|
}
|
|
22661
22795
|
load() {
|
|
22662
22796
|
this.store.load();
|
|
22797
|
+
this.globalStore?.load();
|
|
22663
22798
|
this.loadRegistryFromCacheOrSnapshot();
|
|
22664
22799
|
this.enrichInstalledFromRegistry();
|
|
22665
22800
|
}
|
|
@@ -22699,19 +22834,20 @@ var init_agent_catalog = __esm({
|
|
|
22699
22834
|
if (byId) return byId;
|
|
22700
22835
|
return this.registryAgents.find((a) => getAgentAlias(a.id) === keyOrId);
|
|
22701
22836
|
}
|
|
22702
|
-
// --- Installed ---
|
|
22837
|
+
// --- Installed (instance-first, global-fallback) ---
|
|
22703
22838
|
getInstalled() {
|
|
22704
|
-
|
|
22839
|
+
const merged = { ...this.globalStore?.getInstalled(), ...this.store.getInstalled() };
|
|
22840
|
+
return Object.values(merged);
|
|
22705
22841
|
}
|
|
22706
22842
|
getInstalledEntries() {
|
|
22707
|
-
return this.store.getInstalled();
|
|
22843
|
+
return { ...this.globalStore?.getInstalled(), ...this.store.getInstalled() };
|
|
22708
22844
|
}
|
|
22709
22845
|
getInstalledAgent(key) {
|
|
22710
|
-
return this.store.getAgent(key);
|
|
22846
|
+
return this.store.getAgent(key) ?? this.globalStore?.getAgent(key);
|
|
22711
22847
|
}
|
|
22712
22848
|
// --- Discovery ---
|
|
22713
22849
|
getAvailable() {
|
|
22714
|
-
const installed = this.
|
|
22850
|
+
const installed = this.getInstalledEntries();
|
|
22715
22851
|
const items = [];
|
|
22716
22852
|
const seenKeys = /* @__PURE__ */ new Set();
|
|
22717
22853
|
for (const [key, agent] of Object.entries(installed)) {
|
|
@@ -22785,15 +22921,18 @@ var init_agent_catalog = __esm({
|
|
|
22785
22921
|
this.store.addAgent(key, data);
|
|
22786
22922
|
}
|
|
22787
22923
|
async uninstall(key) {
|
|
22788
|
-
if (
|
|
22789
|
-
|
|
22924
|
+
if (this.store.hasAgent(key)) {
|
|
22925
|
+
await uninstallAgent(key, this.store);
|
|
22926
|
+
return { ok: true };
|
|
22790
22927
|
}
|
|
22791
|
-
|
|
22792
|
-
|
|
22928
|
+
if (this.globalStore?.getAgent(key)) {
|
|
22929
|
+
return { ok: false, error: `"${key}" is installed globally. Uninstall it from the global instance instead.` };
|
|
22930
|
+
}
|
|
22931
|
+
return { ok: false, error: `"${key}" is not installed.` };
|
|
22793
22932
|
}
|
|
22794
22933
|
// --- Resolution (for AgentManager) ---
|
|
22795
22934
|
resolve(key) {
|
|
22796
|
-
const agent = this.store.getAgent(key);
|
|
22935
|
+
const agent = this.store.getAgent(key) ?? this.globalStore?.getAgent(key);
|
|
22797
22936
|
if (!agent) return void 0;
|
|
22798
22937
|
return {
|
|
22799
22938
|
name: key,
|
|
@@ -23434,13 +23573,13 @@ var init_plugin_context = __esm({
|
|
|
23434
23573
|
|
|
23435
23574
|
// src/core/plugin/lifecycle-manager.ts
|
|
23436
23575
|
function withTimeout(promise, ms, label) {
|
|
23437
|
-
return new Promise((
|
|
23576
|
+
return new Promise((resolve9, reject) => {
|
|
23438
23577
|
const timer = setTimeout(() => reject(new Error(`Timeout: ${label} exceeded ${ms}ms`)), ms);
|
|
23439
23578
|
if (typeof timer === "object" && timer !== null && "unref" in timer) {
|
|
23440
23579
|
;
|
|
23441
23580
|
timer.unref();
|
|
23442
23581
|
}
|
|
23443
|
-
promise.then(
|
|
23582
|
+
promise.then(resolve9, reject).finally(() => clearTimeout(timer));
|
|
23444
23583
|
});
|
|
23445
23584
|
}
|
|
23446
23585
|
function resolvePluginConfig(pluginName, configManager) {
|
|
@@ -28789,7 +28928,7 @@ function showInteractiveMenu(options) {
|
|
|
28789
28928
|
}
|
|
28790
28929
|
}
|
|
28791
28930
|
console.log("");
|
|
28792
|
-
return new Promise((
|
|
28931
|
+
return new Promise((resolve9) => {
|
|
28793
28932
|
process.stdin.setRawMode(true);
|
|
28794
28933
|
process.stdin.resume();
|
|
28795
28934
|
const onData = async (buf) => {
|
|
@@ -28808,7 +28947,7 @@ function showInteractiveMenu(options) {
|
|
|
28808
28947
|
console.error(err);
|
|
28809
28948
|
process.exit(1);
|
|
28810
28949
|
}
|
|
28811
|
-
|
|
28950
|
+
resolve9(true);
|
|
28812
28951
|
}
|
|
28813
28952
|
};
|
|
28814
28953
|
const cleanup = () => {
|
|
@@ -28828,6 +28967,7 @@ var init_interactive_menu = __esm({
|
|
|
28828
28967
|
// src/cli/instance-prompt.ts
|
|
28829
28968
|
var instance_prompt_exports = {};
|
|
28830
28969
|
__export(instance_prompt_exports, {
|
|
28970
|
+
findParentInstance: () => findParentInstance,
|
|
28831
28971
|
promptForInstance: () => promptForInstance
|
|
28832
28972
|
});
|
|
28833
28973
|
import fs57 from "fs";
|
|
@@ -28838,14 +28978,15 @@ async function promptForInstance(opts) {
|
|
|
28838
28978
|
const globalConfigExists = fs57.existsSync(path69.join(globalRoot, "config.json"));
|
|
28839
28979
|
const cwd = process.cwd();
|
|
28840
28980
|
const localRoot = path69.join(cwd, ".openacp");
|
|
28841
|
-
|
|
28981
|
+
const detectedParent = findParentInstance(cwd, globalRoot);
|
|
28982
|
+
if (!globalConfigExists) return detectedParent ?? globalRoot;
|
|
28842
28983
|
const isTTY = process.stdin.isTTY && process.stdout.isTTY;
|
|
28843
|
-
if (!isTTY) return globalRoot;
|
|
28984
|
+
if (!isTTY) return detectedParent ?? globalRoot;
|
|
28844
28985
|
const registryPath = path69.join(globalRoot, "instances.json");
|
|
28845
28986
|
const registry = new InstanceRegistry(registryPath);
|
|
28846
28987
|
registry.load();
|
|
28847
28988
|
const instances = registry.list().filter((e) => fs57.existsSync(e.root));
|
|
28848
|
-
const instanceOptions = instances.map((e) => {
|
|
28989
|
+
const instanceOptions = instances.filter((e) => !detectedParent || e.root !== detectedParent).map((e) => {
|
|
28849
28990
|
let name = e.id;
|
|
28850
28991
|
try {
|
|
28851
28992
|
const raw = fs57.readFileSync(path69.join(e.root, "config.json"), "utf-8");
|
|
@@ -28858,6 +28999,17 @@ async function promptForInstance(opts) {
|
|
|
28858
28999
|
const type = isGlobal ? "global" : "local";
|
|
28859
29000
|
return { value: e.root, label: `${name} workspace (${type} \u2014 ${displayPath})` };
|
|
28860
29001
|
});
|
|
29002
|
+
if (detectedParent) {
|
|
29003
|
+
let name = path69.basename(path69.dirname(detectedParent));
|
|
29004
|
+
try {
|
|
29005
|
+
const raw = fs57.readFileSync(path69.join(detectedParent, "config.json"), "utf-8");
|
|
29006
|
+
const parsed = JSON.parse(raw);
|
|
29007
|
+
if (parsed.instanceName) name = parsed.instanceName;
|
|
29008
|
+
} catch {
|
|
29009
|
+
}
|
|
29010
|
+
const displayPath = detectedParent.replace(os32.homedir(), "~");
|
|
29011
|
+
instanceOptions.unshift({ value: detectedParent, label: `${name} workspace (detected \u2014 ${displayPath})` });
|
|
29012
|
+
}
|
|
28861
29013
|
if (instanceOptions.length === 0) {
|
|
28862
29014
|
const globalDisplay = globalRoot.replace(os32.homedir(), "~");
|
|
28863
29015
|
instanceOptions.push({ value: globalRoot, label: `Global workspace (${globalDisplay})` });
|
|
@@ -28886,6 +29038,17 @@ async function promptForInstance(opts) {
|
|
|
28886
29038
|
}
|
|
28887
29039
|
return choice;
|
|
28888
29040
|
}
|
|
29041
|
+
function findParentInstance(cwd, globalRoot) {
|
|
29042
|
+
let dir = path69.dirname(cwd);
|
|
29043
|
+
while (true) {
|
|
29044
|
+
const candidate = path69.join(dir, ".openacp");
|
|
29045
|
+
if (candidate !== globalRoot && fs57.existsSync(candidate)) return candidate;
|
|
29046
|
+
const parent = path69.dirname(dir);
|
|
29047
|
+
if (parent === dir) break;
|
|
29048
|
+
dir = parent;
|
|
29049
|
+
}
|
|
29050
|
+
return null;
|
|
29051
|
+
}
|
|
28889
29052
|
var init_instance_prompt = __esm({
|
|
28890
29053
|
"src/cli/instance-prompt.ts"() {
|
|
28891
29054
|
"use strict";
|
|
@@ -30633,6 +30796,7 @@ installs it globally if an update is available.
|
|
|
30633
30796
|
init_api_client();
|
|
30634
30797
|
init_helpers();
|
|
30635
30798
|
init_output();
|
|
30799
|
+
init_instance_context();
|
|
30636
30800
|
async function cmdAdopt(args2) {
|
|
30637
30801
|
if (wantsHelp(args2)) {
|
|
30638
30802
|
console.log(`
|
|
@@ -30686,10 +30850,11 @@ as a messaging thread. Requires a running daemon.
|
|
|
30686
30850
|
const cwd = cwdIdx !== -1 && args2[cwdIdx + 1] ? args2[cwdIdx + 1] : process.cwd();
|
|
30687
30851
|
const channelIdx = args2.indexOf("--channel");
|
|
30688
30852
|
const channel = channelIdx !== -1 && args2[channelIdx + 1] ? args2[channelIdx + 1] : void 0;
|
|
30689
|
-
const
|
|
30853
|
+
const instanceRoot = await resolveRunningInstance(cwd);
|
|
30854
|
+
const port = instanceRoot ? readApiPort(void 0, instanceRoot) : null;
|
|
30690
30855
|
if (!port) {
|
|
30691
|
-
if (json) jsonError(ErrorCodes.DAEMON_NOT_RUNNING, "OpenACP
|
|
30692
|
-
console.log("OpenACP
|
|
30856
|
+
if (json) jsonError(ErrorCodes.DAEMON_NOT_RUNNING, "No running OpenACP instance found. Start one with: openacp start");
|
|
30857
|
+
console.log("No running OpenACP instance found. Start one with: openacp start");
|
|
30693
30858
|
process.exit(1);
|
|
30694
30859
|
}
|
|
30695
30860
|
try {
|
|
@@ -30698,7 +30863,7 @@ as a messaging thread. Requires a running daemon.
|
|
|
30698
30863
|
method: "POST",
|
|
30699
30864
|
headers: { "Content-Type": "application/json" },
|
|
30700
30865
|
body: JSON.stringify({ agent, agentSessionId: sessionId, cwd, channel })
|
|
30701
|
-
});
|
|
30866
|
+
}, instanceRoot ?? void 0);
|
|
30702
30867
|
const data = await res.json();
|
|
30703
30868
|
if (data.ok) {
|
|
30704
30869
|
if (json) jsonSuccess({ sessionId: data.sessionId, threadId: data.threadId, agent, status: data.status ?? "new" });
|