@openacp/cli 2026.408.3 → 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 +281 -139
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +228 -112
- 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
|
});
|
|
@@ -19428,7 +19451,7 @@ var init_agent_instance = __esm({
|
|
|
19428
19451
|
env: filterEnv(process.env, agentDef.env)
|
|
19429
19452
|
}
|
|
19430
19453
|
);
|
|
19431
|
-
await new Promise((
|
|
19454
|
+
await new Promise((resolve9, reject) => {
|
|
19432
19455
|
instance.child.on("error", (err) => {
|
|
19433
19456
|
reject(
|
|
19434
19457
|
new Error(
|
|
@@ -19436,7 +19459,7 @@ var init_agent_instance = __esm({
|
|
|
19436
19459
|
)
|
|
19437
19460
|
);
|
|
19438
19461
|
});
|
|
19439
|
-
instance.child.on("spawn", () =>
|
|
19462
|
+
instance.child.on("spawn", () => resolve9());
|
|
19440
19463
|
});
|
|
19441
19464
|
instance.stderrCapture = new StderrCapture(50);
|
|
19442
19465
|
instance.child.stderr.on("data", (chunk) => {
|
|
@@ -19942,15 +19965,15 @@ ${skipNote}`;
|
|
|
19942
19965
|
this._destroying = true;
|
|
19943
19966
|
this.terminalManager.destroyAll();
|
|
19944
19967
|
if (this.child.exitCode !== null) return;
|
|
19945
|
-
await new Promise((
|
|
19968
|
+
await new Promise((resolve9) => {
|
|
19946
19969
|
this.child.on("exit", () => {
|
|
19947
19970
|
clearTimeout(forceKillTimer);
|
|
19948
|
-
|
|
19971
|
+
resolve9();
|
|
19949
19972
|
});
|
|
19950
19973
|
this.child.kill("SIGTERM");
|
|
19951
19974
|
const forceKillTimer = setTimeout(() => {
|
|
19952
19975
|
if (this.child.exitCode === null) this.child.kill("SIGKILL");
|
|
19953
|
-
|
|
19976
|
+
resolve9();
|
|
19954
19977
|
}, 1e4);
|
|
19955
19978
|
if (typeof forceKillTimer === "object" && forceKillTimer !== null && "unref" in forceKillTimer) {
|
|
19956
19979
|
forceKillTimer.unref();
|
|
@@ -20014,8 +20037,8 @@ var init_prompt_queue = __esm({
|
|
|
20014
20037
|
processorSettled = null;
|
|
20015
20038
|
async enqueue(text6, attachments, routing, turnId) {
|
|
20016
20039
|
if (this.processing) {
|
|
20017
|
-
return new Promise((
|
|
20018
|
-
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 });
|
|
20019
20042
|
});
|
|
20020
20043
|
}
|
|
20021
20044
|
await this.process(text6, attachments, routing, turnId);
|
|
@@ -20095,8 +20118,8 @@ var init_permission_gate = __esm({
|
|
|
20095
20118
|
this.request = request;
|
|
20096
20119
|
this.settled = false;
|
|
20097
20120
|
this.clearTimeout();
|
|
20098
|
-
return new Promise((
|
|
20099
|
-
this.resolveFn =
|
|
20121
|
+
return new Promise((resolve9, reject) => {
|
|
20122
|
+
this.resolveFn = resolve9;
|
|
20100
20123
|
this.rejectFn = reject;
|
|
20101
20124
|
this.timeoutTimer = setTimeout(() => {
|
|
20102
20125
|
this.reject("Permission request timed out (no response received)");
|
|
@@ -21344,7 +21367,10 @@ var init_session_bridge = __esm({
|
|
|
21344
21367
|
});
|
|
21345
21368
|
|
|
21346
21369
|
// src/core/utils/extract-file-info.ts
|
|
21347
|
-
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
|
+
}
|
|
21348
21374
|
if (kind && !["read", "edit", "write"].includes(kind)) return null;
|
|
21349
21375
|
let info = null;
|
|
21350
21376
|
if (meta) {
|
|
@@ -21399,6 +21425,37 @@ function extractFileInfo(name, kind, content, rawInput, meta) {
|
|
|
21399
21425
|
if (!info.filePath || !info.content) return null;
|
|
21400
21426
|
return info;
|
|
21401
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
|
+
}
|
|
21402
21459
|
function resolveToolResponse(meta) {
|
|
21403
21460
|
const claudeCode = meta.claudeCode;
|
|
21404
21461
|
if (claudeCode?.toolResponse && typeof claudeCode.toolResponse === "object") {
|
|
@@ -21467,6 +21524,7 @@ function parseContent(content) {
|
|
|
21467
21524
|
var init_extract_file_info = __esm({
|
|
21468
21525
|
"src/core/utils/extract-file-info.ts"() {
|
|
21469
21526
|
"use strict";
|
|
21527
|
+
init_apply_patch_detection();
|
|
21470
21528
|
}
|
|
21471
21529
|
});
|
|
21472
21530
|
|
|
@@ -21490,11 +21548,69 @@ function computeLineDiff(oldStr, newStr) {
|
|
|
21490
21548
|
removed: Math.max(0, oldLines.length - prefixLen - suffixLen)
|
|
21491
21549
|
};
|
|
21492
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
|
+
}
|
|
21493
21608
|
var log33, BINARY_VIEWER_EXTENSIONS, MessageTransformer;
|
|
21494
21609
|
var init_message_transformer = __esm({
|
|
21495
21610
|
"src/core/message-transformer.ts"() {
|
|
21496
21611
|
"use strict";
|
|
21497
21612
|
init_extract_file_info();
|
|
21613
|
+
init_apply_patch_detection();
|
|
21498
21614
|
init_log();
|
|
21499
21615
|
log33 = createChildLogger({ module: "message-transformer" });
|
|
21500
21616
|
BINARY_VIEWER_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
@@ -21681,22 +21797,11 @@ var init_message_transformer = __esm({
|
|
|
21681
21797
|
return input2 !== null && input2 !== void 0 && typeof input2 === "object" && !Array.isArray(input2) && Object.keys(input2).length > 0;
|
|
21682
21798
|
}
|
|
21683
21799
|
enrichWithViewerLinks(event, metadata, sessionContext) {
|
|
21800
|
+
const name = "name" in event ? event.name || "" : "";
|
|
21684
21801
|
const kind = "kind" in event ? event.kind : void 0;
|
|
21685
|
-
if (!metadata.diffStats
|
|
21686
|
-
const
|
|
21687
|
-
if (
|
|
21688
|
-
const oldStr = typeof ri.old_string === "string" ? ri.old_string : typeof ri.oldText === "string" ? ri.oldText : null;
|
|
21689
|
-
const newStr = typeof ri.new_string === "string" ? ri.new_string : typeof ri.newText === "string" ? ri.newText : typeof ri.content === "string" ? ri.content : null;
|
|
21690
|
-
if (oldStr !== null && newStr !== null) {
|
|
21691
|
-
const stats = computeLineDiff(oldStr, newStr);
|
|
21692
|
-
if (stats.added > 0 || stats.removed > 0) {
|
|
21693
|
-
metadata.diffStats = stats;
|
|
21694
|
-
}
|
|
21695
|
-
} else if (oldStr === null && newStr !== null && kind === "write") {
|
|
21696
|
-
const added = newStr.split("\n").length;
|
|
21697
|
-
if (added > 0) metadata.diffStats = { added, removed: 0 };
|
|
21698
|
-
}
|
|
21699
|
-
}
|
|
21802
|
+
if (!metadata.diffStats) {
|
|
21803
|
+
const stats = extractDiffStatsFromToolPayload(name, kind, event.rawInput, event.rawOutput);
|
|
21804
|
+
if (stats) metadata.diffStats = stats;
|
|
21700
21805
|
}
|
|
21701
21806
|
if (!this.tunnelService || !sessionContext) {
|
|
21702
21807
|
log33.debug(
|
|
@@ -21705,7 +21810,6 @@ var init_message_transformer = __esm({
|
|
|
21705
21810
|
);
|
|
21706
21811
|
return;
|
|
21707
21812
|
}
|
|
21708
|
-
const name = "name" in event ? event.name || "" : "";
|
|
21709
21813
|
log33.debug(
|
|
21710
21814
|
{ name, kind, status: event.status, hasContent: !!event.content, hasRawInput: !!event.rawInput },
|
|
21711
21815
|
"enrichWithViewerLinks: inspecting event"
|
|
@@ -21715,7 +21819,8 @@ var init_message_transformer = __esm({
|
|
|
21715
21819
|
kind,
|
|
21716
21820
|
event.content,
|
|
21717
21821
|
event.rawInput,
|
|
21718
|
-
event.meta
|
|
21822
|
+
event.meta,
|
|
21823
|
+
event.rawOutput
|
|
21719
21824
|
);
|
|
21720
21825
|
if (!fileInfo) {
|
|
21721
21826
|
log33.debug(
|
|
@@ -22673,6 +22778,7 @@ var init_agent_catalog = __esm({
|
|
|
22673
22778
|
DEFAULT_TTL_HOURS = 24;
|
|
22674
22779
|
AgentCatalog = class {
|
|
22675
22780
|
store;
|
|
22781
|
+
globalStore = null;
|
|
22676
22782
|
registryAgents = [];
|
|
22677
22783
|
cachePath;
|
|
22678
22784
|
agentsDir;
|
|
@@ -22680,9 +22786,15 @@ var init_agent_catalog = __esm({
|
|
|
22680
22786
|
this.store = store ?? new AgentStore();
|
|
22681
22787
|
this.cachePath = cachePath ?? path48.join(os21.homedir(), ".openacp", "registry-cache.json");
|
|
22682
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
|
+
}
|
|
22683
22794
|
}
|
|
22684
22795
|
load() {
|
|
22685
22796
|
this.store.load();
|
|
22797
|
+
this.globalStore?.load();
|
|
22686
22798
|
this.loadRegistryFromCacheOrSnapshot();
|
|
22687
22799
|
this.enrichInstalledFromRegistry();
|
|
22688
22800
|
}
|
|
@@ -22722,19 +22834,20 @@ var init_agent_catalog = __esm({
|
|
|
22722
22834
|
if (byId) return byId;
|
|
22723
22835
|
return this.registryAgents.find((a) => getAgentAlias(a.id) === keyOrId);
|
|
22724
22836
|
}
|
|
22725
|
-
// --- Installed ---
|
|
22837
|
+
// --- Installed (instance-first, global-fallback) ---
|
|
22726
22838
|
getInstalled() {
|
|
22727
|
-
|
|
22839
|
+
const merged = { ...this.globalStore?.getInstalled(), ...this.store.getInstalled() };
|
|
22840
|
+
return Object.values(merged);
|
|
22728
22841
|
}
|
|
22729
22842
|
getInstalledEntries() {
|
|
22730
|
-
return this.store.getInstalled();
|
|
22843
|
+
return { ...this.globalStore?.getInstalled(), ...this.store.getInstalled() };
|
|
22731
22844
|
}
|
|
22732
22845
|
getInstalledAgent(key) {
|
|
22733
|
-
return this.store.getAgent(key);
|
|
22846
|
+
return this.store.getAgent(key) ?? this.globalStore?.getAgent(key);
|
|
22734
22847
|
}
|
|
22735
22848
|
// --- Discovery ---
|
|
22736
22849
|
getAvailable() {
|
|
22737
|
-
const installed = this.
|
|
22850
|
+
const installed = this.getInstalledEntries();
|
|
22738
22851
|
const items = [];
|
|
22739
22852
|
const seenKeys = /* @__PURE__ */ new Set();
|
|
22740
22853
|
for (const [key, agent] of Object.entries(installed)) {
|
|
@@ -22808,15 +22921,18 @@ var init_agent_catalog = __esm({
|
|
|
22808
22921
|
this.store.addAgent(key, data);
|
|
22809
22922
|
}
|
|
22810
22923
|
async uninstall(key) {
|
|
22811
|
-
if (
|
|
22812
|
-
|
|
22924
|
+
if (this.store.hasAgent(key)) {
|
|
22925
|
+
await uninstallAgent(key, this.store);
|
|
22926
|
+
return { ok: true };
|
|
22813
22927
|
}
|
|
22814
|
-
|
|
22815
|
-
|
|
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.` };
|
|
22816
22932
|
}
|
|
22817
22933
|
// --- Resolution (for AgentManager) ---
|
|
22818
22934
|
resolve(key) {
|
|
22819
|
-
const agent = this.store.getAgent(key);
|
|
22935
|
+
const agent = this.store.getAgent(key) ?? this.globalStore?.getAgent(key);
|
|
22820
22936
|
if (!agent) return void 0;
|
|
22821
22937
|
return {
|
|
22822
22938
|
name: key,
|
|
@@ -23457,13 +23573,13 @@ var init_plugin_context = __esm({
|
|
|
23457
23573
|
|
|
23458
23574
|
// src/core/plugin/lifecycle-manager.ts
|
|
23459
23575
|
function withTimeout(promise, ms, label) {
|
|
23460
|
-
return new Promise((
|
|
23576
|
+
return new Promise((resolve9, reject) => {
|
|
23461
23577
|
const timer = setTimeout(() => reject(new Error(`Timeout: ${label} exceeded ${ms}ms`)), ms);
|
|
23462
23578
|
if (typeof timer === "object" && timer !== null && "unref" in timer) {
|
|
23463
23579
|
;
|
|
23464
23580
|
timer.unref();
|
|
23465
23581
|
}
|
|
23466
|
-
promise.then(
|
|
23582
|
+
promise.then(resolve9, reject).finally(() => clearTimeout(timer));
|
|
23467
23583
|
});
|
|
23468
23584
|
}
|
|
23469
23585
|
function resolvePluginConfig(pluginName, configManager) {
|
|
@@ -28812,7 +28928,7 @@ function showInteractiveMenu(options) {
|
|
|
28812
28928
|
}
|
|
28813
28929
|
}
|
|
28814
28930
|
console.log("");
|
|
28815
|
-
return new Promise((
|
|
28931
|
+
return new Promise((resolve9) => {
|
|
28816
28932
|
process.stdin.setRawMode(true);
|
|
28817
28933
|
process.stdin.resume();
|
|
28818
28934
|
const onData = async (buf) => {
|
|
@@ -28831,7 +28947,7 @@ function showInteractiveMenu(options) {
|
|
|
28831
28947
|
console.error(err);
|
|
28832
28948
|
process.exit(1);
|
|
28833
28949
|
}
|
|
28834
|
-
|
|
28950
|
+
resolve9(true);
|
|
28835
28951
|
}
|
|
28836
28952
|
};
|
|
28837
28953
|
const cleanup = () => {
|
|
@@ -28851,6 +28967,7 @@ var init_interactive_menu = __esm({
|
|
|
28851
28967
|
// src/cli/instance-prompt.ts
|
|
28852
28968
|
var instance_prompt_exports = {};
|
|
28853
28969
|
__export(instance_prompt_exports, {
|
|
28970
|
+
findParentInstance: () => findParentInstance,
|
|
28854
28971
|
promptForInstance: () => promptForInstance
|
|
28855
28972
|
});
|
|
28856
28973
|
import fs57 from "fs";
|
|
@@ -28861,14 +28978,15 @@ async function promptForInstance(opts) {
|
|
|
28861
28978
|
const globalConfigExists = fs57.existsSync(path69.join(globalRoot, "config.json"));
|
|
28862
28979
|
const cwd = process.cwd();
|
|
28863
28980
|
const localRoot = path69.join(cwd, ".openacp");
|
|
28864
|
-
|
|
28981
|
+
const detectedParent = findParentInstance(cwd, globalRoot);
|
|
28982
|
+
if (!globalConfigExists) return detectedParent ?? globalRoot;
|
|
28865
28983
|
const isTTY = process.stdin.isTTY && process.stdout.isTTY;
|
|
28866
|
-
if (!isTTY) return globalRoot;
|
|
28984
|
+
if (!isTTY) return detectedParent ?? globalRoot;
|
|
28867
28985
|
const registryPath = path69.join(globalRoot, "instances.json");
|
|
28868
28986
|
const registry = new InstanceRegistry(registryPath);
|
|
28869
28987
|
registry.load();
|
|
28870
28988
|
const instances = registry.list().filter((e) => fs57.existsSync(e.root));
|
|
28871
|
-
const instanceOptions = instances.map((e) => {
|
|
28989
|
+
const instanceOptions = instances.filter((e) => !detectedParent || e.root !== detectedParent).map((e) => {
|
|
28872
28990
|
let name = e.id;
|
|
28873
28991
|
try {
|
|
28874
28992
|
const raw = fs57.readFileSync(path69.join(e.root, "config.json"), "utf-8");
|
|
@@ -28881,6 +28999,17 @@ async function promptForInstance(opts) {
|
|
|
28881
28999
|
const type = isGlobal ? "global" : "local";
|
|
28882
29000
|
return { value: e.root, label: `${name} workspace (${type} \u2014 ${displayPath})` };
|
|
28883
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
|
+
}
|
|
28884
29013
|
if (instanceOptions.length === 0) {
|
|
28885
29014
|
const globalDisplay = globalRoot.replace(os32.homedir(), "~");
|
|
28886
29015
|
instanceOptions.push({ value: globalRoot, label: `Global workspace (${globalDisplay})` });
|
|
@@ -28909,6 +29038,17 @@ async function promptForInstance(opts) {
|
|
|
28909
29038
|
}
|
|
28910
29039
|
return choice;
|
|
28911
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
|
+
}
|
|
28912
29052
|
var init_instance_prompt = __esm({
|
|
28913
29053
|
"src/cli/instance-prompt.ts"() {
|
|
28914
29054
|
"use strict";
|
|
@@ -30656,6 +30796,7 @@ installs it globally if an update is available.
|
|
|
30656
30796
|
init_api_client();
|
|
30657
30797
|
init_helpers();
|
|
30658
30798
|
init_output();
|
|
30799
|
+
init_instance_context();
|
|
30659
30800
|
async function cmdAdopt(args2) {
|
|
30660
30801
|
if (wantsHelp(args2)) {
|
|
30661
30802
|
console.log(`
|
|
@@ -30709,10 +30850,11 @@ as a messaging thread. Requires a running daemon.
|
|
|
30709
30850
|
const cwd = cwdIdx !== -1 && args2[cwdIdx + 1] ? args2[cwdIdx + 1] : process.cwd();
|
|
30710
30851
|
const channelIdx = args2.indexOf("--channel");
|
|
30711
30852
|
const channel = channelIdx !== -1 && args2[channelIdx + 1] ? args2[channelIdx + 1] : void 0;
|
|
30712
|
-
const
|
|
30853
|
+
const instanceRoot = await resolveRunningInstance(cwd);
|
|
30854
|
+
const port = instanceRoot ? readApiPort(void 0, instanceRoot) : null;
|
|
30713
30855
|
if (!port) {
|
|
30714
|
-
if (json) jsonError(ErrorCodes.DAEMON_NOT_RUNNING, "OpenACP
|
|
30715
|
-
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");
|
|
30716
30858
|
process.exit(1);
|
|
30717
30859
|
}
|
|
30718
30860
|
try {
|
|
@@ -30721,7 +30863,7 @@ as a messaging thread. Requires a running daemon.
|
|
|
30721
30863
|
method: "POST",
|
|
30722
30864
|
headers: { "Content-Type": "application/json" },
|
|
30723
30865
|
body: JSON.stringify({ agent, agentSessionId: sessionId, cwd, channel })
|
|
30724
|
-
});
|
|
30866
|
+
}, instanceRoot ?? void 0);
|
|
30725
30867
|
const data = await res.json();
|
|
30726
30868
|
if (data.ok) {
|
|
30727
30869
|
if (json) jsonSuccess({ sessionId: data.sessionId, threadId: data.threadId, agent, status: data.status ?? "new" });
|