@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/index.js
CHANGED
|
@@ -198,11 +198,11 @@ async function shutdownLogger() {
|
|
|
198
198
|
logDir = void 0;
|
|
199
199
|
initialized = false;
|
|
200
200
|
if (transport) {
|
|
201
|
-
await new Promise((
|
|
202
|
-
const timeout = setTimeout(
|
|
201
|
+
await new Promise((resolve7) => {
|
|
202
|
+
const timeout = setTimeout(resolve7, 3e3);
|
|
203
203
|
transport.on("close", () => {
|
|
204
204
|
clearTimeout(timeout);
|
|
205
|
-
|
|
205
|
+
resolve7();
|
|
206
206
|
});
|
|
207
207
|
transport.end();
|
|
208
208
|
});
|
|
@@ -289,7 +289,8 @@ __export(instance_context_exports, {
|
|
|
289
289
|
createInstanceContext: () => createInstanceContext,
|
|
290
290
|
generateSlug: () => generateSlug,
|
|
291
291
|
getGlobalRoot: () => getGlobalRoot,
|
|
292
|
-
resolveInstanceRoot: () => resolveInstanceRoot
|
|
292
|
+
resolveInstanceRoot: () => resolveInstanceRoot,
|
|
293
|
+
resolveRunningInstance: () => resolveRunningInstance
|
|
293
294
|
});
|
|
294
295
|
import path2 from "path";
|
|
295
296
|
import fs2 from "fs";
|
|
@@ -341,6 +342,38 @@ function resolveInstanceRoot(opts) {
|
|
|
341
342
|
function getGlobalRoot() {
|
|
342
343
|
return path2.join(os2.homedir(), ".openacp");
|
|
343
344
|
}
|
|
345
|
+
async function resolveRunningInstance(cwd) {
|
|
346
|
+
const globalRoot = getGlobalRoot();
|
|
347
|
+
let dir = path2.resolve(cwd);
|
|
348
|
+
while (true) {
|
|
349
|
+
const candidate = path2.join(dir, ".openacp");
|
|
350
|
+
if (candidate !== globalRoot && fs2.existsSync(candidate)) {
|
|
351
|
+
if (await isInstanceRunning(candidate)) return candidate;
|
|
352
|
+
}
|
|
353
|
+
const parent = path2.dirname(dir);
|
|
354
|
+
if (parent === dir) break;
|
|
355
|
+
dir = parent;
|
|
356
|
+
}
|
|
357
|
+
if (fs2.existsSync(globalRoot) && await isInstanceRunning(globalRoot)) return globalRoot;
|
|
358
|
+
return null;
|
|
359
|
+
}
|
|
360
|
+
async function isInstanceRunning(instanceRoot) {
|
|
361
|
+
const portFile = path2.join(instanceRoot, "api.port");
|
|
362
|
+
try {
|
|
363
|
+
const content = fs2.readFileSync(portFile, "utf-8").trim();
|
|
364
|
+
const port = parseInt(content, 10);
|
|
365
|
+
if (isNaN(port)) return false;
|
|
366
|
+
const controller = new AbortController();
|
|
367
|
+
const timeout = setTimeout(() => controller.abort(), 2e3);
|
|
368
|
+
const res = await fetch(`http://127.0.0.1:${port}/api/v1/system/health`, {
|
|
369
|
+
signal: controller.signal
|
|
370
|
+
});
|
|
371
|
+
clearTimeout(timeout);
|
|
372
|
+
return res.ok;
|
|
373
|
+
} catch {
|
|
374
|
+
return false;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
344
377
|
var init_instance_context = __esm({
|
|
345
378
|
"src/core/instance/instance-context.ts"() {
|
|
346
379
|
"use strict";
|
|
@@ -875,6 +908,25 @@ var init_events = __esm({
|
|
|
875
908
|
}
|
|
876
909
|
});
|
|
877
910
|
|
|
911
|
+
// src/core/utils/apply-patch-detection.ts
|
|
912
|
+
function asRecord(value) {
|
|
913
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
914
|
+
}
|
|
915
|
+
function hasApplyPatchPatchText(rawInput) {
|
|
916
|
+
const input2 = asRecord(rawInput);
|
|
917
|
+
return !!input2 && (typeof input2.patchText === "string" || typeof input2.patch_text === "string");
|
|
918
|
+
}
|
|
919
|
+
function isApplyPatchOtherTool(kind, name, rawInput) {
|
|
920
|
+
if (kind !== "other") return false;
|
|
921
|
+
if (name.toLowerCase() === "apply_patch") return true;
|
|
922
|
+
return hasApplyPatchPatchText(rawInput);
|
|
923
|
+
}
|
|
924
|
+
var init_apply_patch_detection = __esm({
|
|
925
|
+
"src/core/utils/apply-patch-detection.ts"() {
|
|
926
|
+
"use strict";
|
|
927
|
+
}
|
|
928
|
+
});
|
|
929
|
+
|
|
878
930
|
// src/core/utils/bypass-detection.ts
|
|
879
931
|
function isPermissionBypass(value) {
|
|
880
932
|
const lower = value.toLowerCase();
|
|
@@ -2013,12 +2065,12 @@ function isProcessAlive(pid) {
|
|
|
2013
2065
|
}
|
|
2014
2066
|
}
|
|
2015
2067
|
function checkPortInUse(port) {
|
|
2016
|
-
return new Promise((
|
|
2068
|
+
return new Promise((resolve7) => {
|
|
2017
2069
|
const server = net.createServer();
|
|
2018
|
-
server.once("error", () =>
|
|
2070
|
+
server.once("error", () => resolve7(true));
|
|
2019
2071
|
server.once("listening", () => {
|
|
2020
2072
|
server.close();
|
|
2021
|
-
|
|
2073
|
+
resolve7(false);
|
|
2022
2074
|
});
|
|
2023
2075
|
server.listen(port, "127.0.0.1");
|
|
2024
2076
|
});
|
|
@@ -2110,7 +2162,7 @@ import https from "https";
|
|
|
2110
2162
|
import os9 from "os";
|
|
2111
2163
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
2112
2164
|
function downloadFile(url, dest, maxRedirects = 10) {
|
|
2113
|
-
return new Promise((
|
|
2165
|
+
return new Promise((resolve7, reject) => {
|
|
2114
2166
|
const file = fs23.createWriteStream(dest);
|
|
2115
2167
|
const cleanup = () => {
|
|
2116
2168
|
try {
|
|
@@ -2129,7 +2181,7 @@ function downloadFile(url, dest, maxRedirects = 10) {
|
|
|
2129
2181
|
}
|
|
2130
2182
|
file.close(() => {
|
|
2131
2183
|
cleanup();
|
|
2132
|
-
downloadFile(response.headers.location, dest, maxRedirects - 1).then(
|
|
2184
|
+
downloadFile(response.headers.location, dest, maxRedirects - 1).then(resolve7).catch(reject);
|
|
2133
2185
|
});
|
|
2134
2186
|
return;
|
|
2135
2187
|
}
|
|
@@ -2153,7 +2205,7 @@ function downloadFile(url, dest, maxRedirects = 10) {
|
|
|
2153
2205
|
}
|
|
2154
2206
|
});
|
|
2155
2207
|
response.pipe(file);
|
|
2156
|
-
file.on("finish", () => file.close(() =>
|
|
2208
|
+
file.on("finish", () => file.close(() => resolve7(dest)));
|
|
2157
2209
|
file.on("error", (err) => {
|
|
2158
2210
|
file.close(() => {
|
|
2159
2211
|
cleanup();
|
|
@@ -4975,10 +5027,10 @@ var init_send_queue = __esm({
|
|
|
4975
5027
|
const type = opts?.type ?? "other";
|
|
4976
5028
|
const key = opts?.key;
|
|
4977
5029
|
const category = opts?.category;
|
|
4978
|
-
let
|
|
5030
|
+
let resolve7;
|
|
4979
5031
|
let reject;
|
|
4980
5032
|
const promise = new Promise((res, rej) => {
|
|
4981
|
-
|
|
5033
|
+
resolve7 = res;
|
|
4982
5034
|
reject = rej;
|
|
4983
5035
|
});
|
|
4984
5036
|
promise.catch(() => {
|
|
@@ -4989,12 +5041,12 @@ var init_send_queue = __esm({
|
|
|
4989
5041
|
);
|
|
4990
5042
|
if (idx !== -1) {
|
|
4991
5043
|
this.items[idx].resolve(void 0);
|
|
4992
|
-
this.items[idx] = { fn, type, key, category, resolve:
|
|
5044
|
+
this.items[idx] = { fn, type, key, category, resolve: resolve7, reject, promise };
|
|
4993
5045
|
this.scheduleProcess();
|
|
4994
5046
|
return promise;
|
|
4995
5047
|
}
|
|
4996
5048
|
}
|
|
4997
|
-
this.items.push({ fn, type, key, category, resolve:
|
|
5049
|
+
this.items.push({ fn, type, key, category, resolve: resolve7, reject, promise });
|
|
4998
5050
|
this.scheduleProcess();
|
|
4999
5051
|
return promise;
|
|
5000
5052
|
}
|
|
@@ -5256,7 +5308,7 @@ var init_stream_accumulator = __esm({
|
|
|
5256
5308
|
});
|
|
5257
5309
|
|
|
5258
5310
|
// src/core/adapter-primitives/display-spec-builder.ts
|
|
5259
|
-
function
|
|
5311
|
+
function asRecord3(value) {
|
|
5260
5312
|
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
5261
5313
|
return value;
|
|
5262
5314
|
}
|
|
@@ -5289,8 +5341,21 @@ function parseApplyPatchTargets(patchText) {
|
|
|
5289
5341
|
function buildTitle(entry, kind) {
|
|
5290
5342
|
if (entry.displayTitle) return entry.displayTitle;
|
|
5291
5343
|
if (entry.displaySummary) return entry.displaySummary;
|
|
5292
|
-
const input2 =
|
|
5344
|
+
const input2 = asRecord3(entry.rawInput);
|
|
5293
5345
|
const nameLower = entry.name.toLowerCase();
|
|
5346
|
+
if (isApplyPatchOtherTool(entry.kind, entry.name, entry.rawInput)) {
|
|
5347
|
+
const patchText = getStringField(input2, ["patchText", "patch_text"]);
|
|
5348
|
+
if (patchText) {
|
|
5349
|
+
const targets = parseApplyPatchTargets(patchText);
|
|
5350
|
+
if (targets.length === 1) return targets[0];
|
|
5351
|
+
if (targets.length > 1) {
|
|
5352
|
+
const shown = targets.slice(0, 2).join(", ");
|
|
5353
|
+
const rest = targets.length - 2;
|
|
5354
|
+
return rest > 0 ? `${shown} (+${rest} more)` : shown;
|
|
5355
|
+
}
|
|
5356
|
+
}
|
|
5357
|
+
return "apply_patch";
|
|
5358
|
+
}
|
|
5294
5359
|
if (kind === "read") {
|
|
5295
5360
|
const filePath = getStringField(input2, ["file_path", "filePath", "path"]);
|
|
5296
5361
|
if (filePath) {
|
|
@@ -5339,36 +5404,6 @@ function buildTitle(entry, kind) {
|
|
|
5339
5404
|
}
|
|
5340
5405
|
return capitalize(entry.name);
|
|
5341
5406
|
}
|
|
5342
|
-
if (nameLower === "apply_patch") {
|
|
5343
|
-
const patchText = getStringField(input2, ["patchText", "patch_text"]);
|
|
5344
|
-
if (patchText) {
|
|
5345
|
-
const targets = parseApplyPatchTargets(patchText);
|
|
5346
|
-
if (targets.length === 1) return targets[0];
|
|
5347
|
-
if (targets.length > 1) {
|
|
5348
|
-
const shown = targets.slice(0, 2).join(", ");
|
|
5349
|
-
const remaining = targets.length - 2;
|
|
5350
|
-
return remaining > 0 ? `${shown} (+${remaining} more)` : shown;
|
|
5351
|
-
}
|
|
5352
|
-
}
|
|
5353
|
-
return "apply_patch";
|
|
5354
|
-
}
|
|
5355
|
-
if (nameLower === "todowrite") {
|
|
5356
|
-
const todos = Array.isArray(input2.todos) ? input2.todos : [];
|
|
5357
|
-
if (todos.length > 0) {
|
|
5358
|
-
const inProgress = todos.filter((t) => {
|
|
5359
|
-
if (!t || typeof t !== "object") return false;
|
|
5360
|
-
const status = t.status;
|
|
5361
|
-
return status === "in_progress";
|
|
5362
|
-
}).length;
|
|
5363
|
-
const completed = todos.filter((t) => {
|
|
5364
|
-
if (!t || typeof t !== "object") return false;
|
|
5365
|
-
const status = t.status;
|
|
5366
|
-
return status === "completed";
|
|
5367
|
-
}).length;
|
|
5368
|
-
return `Todo list (${completed}/${todos.length} done${inProgress > 0 ? `, ${inProgress} active` : ""})`;
|
|
5369
|
-
}
|
|
5370
|
-
return "Todo list";
|
|
5371
|
-
}
|
|
5372
5407
|
if (kind === "fetch" || kind === "web") {
|
|
5373
5408
|
const url = typeof input2.url === "string" ? input2.url : null;
|
|
5374
5409
|
if (url && url !== "undefined") return url.length > 60 ? url.slice(0, 57) + "..." : url;
|
|
@@ -5379,19 +5414,6 @@ function buildTitle(entry, kind) {
|
|
|
5379
5414
|
if (nameLower === "skill" && typeof input2.skill === "string" && input2.skill) {
|
|
5380
5415
|
return input2.skill;
|
|
5381
5416
|
}
|
|
5382
|
-
if (nameLower === "apply_patch") {
|
|
5383
|
-
const patchText = getStringField(input2, ["patchText", "patch_text"]);
|
|
5384
|
-
if (patchText) {
|
|
5385
|
-
const targets = parseApplyPatchTargets(patchText);
|
|
5386
|
-
if (targets.length === 1) return targets[0];
|
|
5387
|
-
if (targets.length > 1) {
|
|
5388
|
-
const shown = targets.slice(0, 2).join(", ");
|
|
5389
|
-
const rest = targets.length - 2;
|
|
5390
|
-
return rest > 0 ? `${shown} (+${rest} more)` : shown;
|
|
5391
|
-
}
|
|
5392
|
-
}
|
|
5393
|
-
return "apply_patch";
|
|
5394
|
-
}
|
|
5395
5417
|
if (nameLower === "todowrite") {
|
|
5396
5418
|
const todos = Array.isArray(input2.todos) ? input2.todos : [];
|
|
5397
5419
|
if (todos.length > 0) {
|
|
@@ -5421,6 +5443,7 @@ var init_display_spec_builder = __esm({
|
|
|
5421
5443
|
"src/core/adapter-primitives/display-spec-builder.ts"() {
|
|
5422
5444
|
"use strict";
|
|
5423
5445
|
init_format_types();
|
|
5446
|
+
init_apply_patch_detection();
|
|
5424
5447
|
EXECUTE_KINDS = /* @__PURE__ */ new Set(["execute", "bash", "command", "terminal"]);
|
|
5425
5448
|
INLINE_MAX_LINES = 15;
|
|
5426
5449
|
INLINE_MAX_CHARS = 800;
|
|
@@ -5429,12 +5452,12 @@ var init_display_spec_builder = __esm({
|
|
|
5429
5452
|
this.tunnelService = tunnelService;
|
|
5430
5453
|
}
|
|
5431
5454
|
buildToolSpec(entry, mode, sessionContext) {
|
|
5432
|
-
const effectiveKind = entry.displayKind ?? entry.kind;
|
|
5455
|
+
const effectiveKind = entry.displayKind ?? (isApplyPatchOtherTool(entry.kind, entry.name, entry.rawInput) ? "edit" : entry.kind);
|
|
5433
5456
|
const icon = KIND_ICONS[effectiveKind] ?? KIND_ICONS["other"] ?? "\u{1F6E0}\uFE0F";
|
|
5434
5457
|
const title = buildTitle(entry, effectiveKind);
|
|
5435
5458
|
const isHidden = entry.isNoise && mode !== "high";
|
|
5436
5459
|
const includeMeta = mode !== "low";
|
|
5437
|
-
const input2 =
|
|
5460
|
+
const input2 = asRecord3(entry.rawInput);
|
|
5438
5461
|
const rawDescription = typeof input2.description === "string" ? input2.description : null;
|
|
5439
5462
|
const descLower = rawDescription?.toLowerCase();
|
|
5440
5463
|
const description = includeMeta && rawDescription && rawDescription !== title && descLower !== effectiveKind && descLower !== entry.name.toLowerCase() ? rawDescription : null;
|
|
@@ -5819,14 +5842,14 @@ __export(version_exports, {
|
|
|
5819
5842
|
runUpdate: () => runUpdate
|
|
5820
5843
|
});
|
|
5821
5844
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
5822
|
-
import { dirname as dirname10, join as join20, resolve as
|
|
5845
|
+
import { dirname as dirname10, join as join20, resolve as resolve6 } from "path";
|
|
5823
5846
|
import { existsSync as existsSync17, readFileSync as readFileSync15 } from "fs";
|
|
5824
5847
|
function findPackageJson() {
|
|
5825
5848
|
let dir = dirname10(fileURLToPath2(import.meta.url));
|
|
5826
5849
|
for (let i = 0; i < 5; i++) {
|
|
5827
5850
|
const candidate = join20(dir, "package.json");
|
|
5828
5851
|
if (existsSync17(candidate)) return candidate;
|
|
5829
|
-
const parent =
|
|
5852
|
+
const parent = resolve6(dir, "..");
|
|
5830
5853
|
if (parent === dir) break;
|
|
5831
5854
|
dir = parent;
|
|
5832
5855
|
}
|
|
@@ -5865,21 +5888,21 @@ function compareVersions(current, latest) {
|
|
|
5865
5888
|
}
|
|
5866
5889
|
async function runUpdate() {
|
|
5867
5890
|
const { spawn: spawn4 } = await import("child_process");
|
|
5868
|
-
return new Promise((
|
|
5891
|
+
return new Promise((resolve7) => {
|
|
5869
5892
|
const child = spawn4("npm", ["install", "-g", `${NPM_PACKAGE}@latest`], {
|
|
5870
5893
|
stdio: "inherit",
|
|
5871
5894
|
shell: true
|
|
5872
5895
|
});
|
|
5873
5896
|
const onSignal = () => {
|
|
5874
5897
|
child.kill("SIGTERM");
|
|
5875
|
-
|
|
5898
|
+
resolve7(false);
|
|
5876
5899
|
};
|
|
5877
5900
|
process.on("SIGINT", onSignal);
|
|
5878
5901
|
process.on("SIGTERM", onSignal);
|
|
5879
5902
|
child.on("close", (code) => {
|
|
5880
5903
|
process.off("SIGINT", onSignal);
|
|
5881
5904
|
process.off("SIGTERM", onSignal);
|
|
5882
|
-
|
|
5905
|
+
resolve7(code === 0);
|
|
5883
5906
|
});
|
|
5884
5907
|
});
|
|
5885
5908
|
}
|
|
@@ -10778,15 +10801,15 @@ var ChannelAdapter = class {
|
|
|
10778
10801
|
function nodeToWebWritable(nodeStream) {
|
|
10779
10802
|
return new WritableStream({
|
|
10780
10803
|
write(chunk) {
|
|
10781
|
-
return new Promise((
|
|
10804
|
+
return new Promise((resolve7, reject) => {
|
|
10782
10805
|
const ok2 = nodeStream.write(chunk);
|
|
10783
10806
|
if (ok2) {
|
|
10784
|
-
|
|
10807
|
+
resolve7();
|
|
10785
10808
|
return;
|
|
10786
10809
|
}
|
|
10787
10810
|
const onDrain = () => {
|
|
10788
10811
|
nodeStream.removeListener("error", onError);
|
|
10789
|
-
|
|
10812
|
+
resolve7();
|
|
10790
10813
|
};
|
|
10791
10814
|
const onError = (err) => {
|
|
10792
10815
|
nodeStream.removeListener("drain", onDrain);
|
|
@@ -11222,12 +11245,12 @@ var TerminalManager = class {
|
|
|
11222
11245
|
signal: state.exitStatus.signal
|
|
11223
11246
|
};
|
|
11224
11247
|
}
|
|
11225
|
-
return new Promise((
|
|
11248
|
+
return new Promise((resolve7) => {
|
|
11226
11249
|
state.process.on("exit", (code, signal) => {
|
|
11227
|
-
|
|
11250
|
+
resolve7({ exitCode: code, signal });
|
|
11228
11251
|
});
|
|
11229
11252
|
if (state.exitStatus !== null) {
|
|
11230
|
-
|
|
11253
|
+
resolve7({
|
|
11231
11254
|
exitCode: state.exitStatus.exitCode,
|
|
11232
11255
|
signal: state.exitStatus.signal
|
|
11233
11256
|
});
|
|
@@ -11358,18 +11381,41 @@ function resolveAgentCommand(cmd) {
|
|
|
11358
11381
|
try {
|
|
11359
11382
|
const fullPath = execFileSync("which", [cmd], { encoding: "utf-8" }).trim();
|
|
11360
11383
|
if (fullPath) {
|
|
11361
|
-
|
|
11362
|
-
|
|
11363
|
-
|
|
11384
|
+
try {
|
|
11385
|
+
const content = fs8.readFileSync(fullPath, "utf-8");
|
|
11386
|
+
if (content.startsWith("#!/usr/bin/env node")) {
|
|
11387
|
+
return { command: process.execPath, args: [fullPath] };
|
|
11388
|
+
}
|
|
11389
|
+
} catch {
|
|
11364
11390
|
}
|
|
11391
|
+
return { command: fullPath, args: [] };
|
|
11365
11392
|
}
|
|
11366
11393
|
} catch {
|
|
11367
11394
|
}
|
|
11368
11395
|
if (cmd === "npx" || cmd === "uvx") {
|
|
11369
|
-
const
|
|
11370
|
-
|
|
11371
|
-
|
|
11396
|
+
const seen = /* @__PURE__ */ new Set();
|
|
11397
|
+
const candidates = [];
|
|
11398
|
+
const addCandidate = (dir) => {
|
|
11399
|
+
if (!seen.has(dir)) {
|
|
11400
|
+
seen.add(dir);
|
|
11401
|
+
candidates.push(dir);
|
|
11402
|
+
}
|
|
11403
|
+
};
|
|
11404
|
+
addCandidate(path7.dirname(process.execPath));
|
|
11405
|
+
try {
|
|
11406
|
+
addCandidate(path7.dirname(fs8.realpathSync(process.execPath)));
|
|
11407
|
+
} catch {
|
|
11408
|
+
}
|
|
11409
|
+
addCandidate("/opt/homebrew/bin");
|
|
11410
|
+
addCandidate("/usr/local/bin");
|
|
11411
|
+
for (const dir of candidates) {
|
|
11412
|
+
const candidate = path7.join(dir, cmd);
|
|
11413
|
+
if (fs8.existsSync(candidate)) {
|
|
11414
|
+
log4.info({ cmd, resolved: candidate }, "Resolved package runner from fallback search");
|
|
11415
|
+
return { command: candidate, args: [] };
|
|
11416
|
+
}
|
|
11372
11417
|
}
|
|
11418
|
+
log4.warn({ cmd, execPath: process.execPath, candidates }, "Could not find package runner");
|
|
11373
11419
|
}
|
|
11374
11420
|
return { command: cmd, args: [] };
|
|
11375
11421
|
}
|
|
@@ -11427,7 +11473,7 @@ var AgentInstance = class _AgentInstance extends TypedEmitter {
|
|
|
11427
11473
|
env: filterEnv(process.env, agentDef.env)
|
|
11428
11474
|
}
|
|
11429
11475
|
);
|
|
11430
|
-
await new Promise((
|
|
11476
|
+
await new Promise((resolve7, reject) => {
|
|
11431
11477
|
instance.child.on("error", (err) => {
|
|
11432
11478
|
reject(
|
|
11433
11479
|
new Error(
|
|
@@ -11435,7 +11481,7 @@ var AgentInstance = class _AgentInstance extends TypedEmitter {
|
|
|
11435
11481
|
)
|
|
11436
11482
|
);
|
|
11437
11483
|
});
|
|
11438
|
-
instance.child.on("spawn", () =>
|
|
11484
|
+
instance.child.on("spawn", () => resolve7());
|
|
11439
11485
|
});
|
|
11440
11486
|
instance.stderrCapture = new StderrCapture(50);
|
|
11441
11487
|
instance.child.stderr.on("data", (chunk) => {
|
|
@@ -11941,15 +11987,15 @@ ${skipNote}`;
|
|
|
11941
11987
|
this._destroying = true;
|
|
11942
11988
|
this.terminalManager.destroyAll();
|
|
11943
11989
|
if (this.child.exitCode !== null) return;
|
|
11944
|
-
await new Promise((
|
|
11990
|
+
await new Promise((resolve7) => {
|
|
11945
11991
|
this.child.on("exit", () => {
|
|
11946
11992
|
clearTimeout(forceKillTimer);
|
|
11947
|
-
|
|
11993
|
+
resolve7();
|
|
11948
11994
|
});
|
|
11949
11995
|
this.child.kill("SIGTERM");
|
|
11950
11996
|
const forceKillTimer = setTimeout(() => {
|
|
11951
11997
|
if (this.child.exitCode === null) this.child.kill("SIGKILL");
|
|
11952
|
-
|
|
11998
|
+
resolve7();
|
|
11953
11999
|
}, 1e4);
|
|
11954
12000
|
if (typeof forceKillTimer === "object" && forceKillTimer !== null && "unref" in forceKillTimer) {
|
|
11955
12001
|
forceKillTimer.unref();
|
|
@@ -12003,8 +12049,8 @@ var PromptQueue = class {
|
|
|
12003
12049
|
processorSettled = null;
|
|
12004
12050
|
async enqueue(text3, attachments, routing, turnId) {
|
|
12005
12051
|
if (this.processing) {
|
|
12006
|
-
return new Promise((
|
|
12007
|
-
this.queue.push({ text: text3, attachments, routing, turnId, resolve:
|
|
12052
|
+
return new Promise((resolve7) => {
|
|
12053
|
+
this.queue.push({ text: text3, attachments, routing, turnId, resolve: resolve7 });
|
|
12008
12054
|
});
|
|
12009
12055
|
}
|
|
12010
12056
|
await this.process(text3, attachments, routing, turnId);
|
|
@@ -12078,8 +12124,8 @@ var PermissionGate = class {
|
|
|
12078
12124
|
this.request = request;
|
|
12079
12125
|
this.settled = false;
|
|
12080
12126
|
this.clearTimeout();
|
|
12081
|
-
return new Promise((
|
|
12082
|
-
this.resolveFn =
|
|
12127
|
+
return new Promise((resolve7, reject) => {
|
|
12128
|
+
this.resolveFn = resolve7;
|
|
12083
12129
|
this.rejectFn = reject;
|
|
12084
12130
|
this.timeoutTimer = setTimeout(() => {
|
|
12085
12131
|
this.reject("Permission request timed out (no response received)");
|
|
@@ -12688,7 +12734,11 @@ ${result.text}` : result.text;
|
|
|
12688
12734
|
import * as path8 from "path";
|
|
12689
12735
|
|
|
12690
12736
|
// src/core/utils/extract-file-info.ts
|
|
12691
|
-
|
|
12737
|
+
init_apply_patch_detection();
|
|
12738
|
+
function extractFileInfo(name, kind, content, rawInput, meta, rawOutput) {
|
|
12739
|
+
if (isApplyPatchOtherTool(kind, name, rawInput)) {
|
|
12740
|
+
return parseApplyPatchRawOutput(rawOutput);
|
|
12741
|
+
}
|
|
12692
12742
|
if (kind && !["read", "edit", "write"].includes(kind)) return null;
|
|
12693
12743
|
let info = null;
|
|
12694
12744
|
if (meta) {
|
|
@@ -12743,6 +12793,37 @@ function extractFileInfo(name, kind, content, rawInput, meta) {
|
|
|
12743
12793
|
if (!info.filePath || !info.content) return null;
|
|
12744
12794
|
return info;
|
|
12745
12795
|
}
|
|
12796
|
+
function parseApplyPatchRawOutput(rawOutput) {
|
|
12797
|
+
if (!rawOutput || typeof rawOutput !== "object" || Array.isArray(rawOutput)) return null;
|
|
12798
|
+
const output = rawOutput;
|
|
12799
|
+
const metadata = output.metadata;
|
|
12800
|
+
if (!metadata || typeof metadata !== "object" || Array.isArray(metadata)) return null;
|
|
12801
|
+
const files = metadata.files;
|
|
12802
|
+
if (!Array.isArray(files)) return null;
|
|
12803
|
+
const sortedFiles = [...files].sort((a, b) => getApplyPatchFileScore(b) - getApplyPatchFileScore(a));
|
|
12804
|
+
for (const file of sortedFiles) {
|
|
12805
|
+
if (!file || typeof file !== "object" || Array.isArray(file)) continue;
|
|
12806
|
+
const f = file;
|
|
12807
|
+
const filePath = typeof f.filePath === "string" ? f.filePath : typeof f.relativePath === "string" ? f.relativePath : null;
|
|
12808
|
+
if (!filePath) continue;
|
|
12809
|
+
const after = typeof f.after === "string" ? f.after : null;
|
|
12810
|
+
if (!after) continue;
|
|
12811
|
+
const before = typeof f.before === "string" ? f.before : void 0;
|
|
12812
|
+
return {
|
|
12813
|
+
filePath,
|
|
12814
|
+
content: after,
|
|
12815
|
+
oldContent: before
|
|
12816
|
+
};
|
|
12817
|
+
}
|
|
12818
|
+
return null;
|
|
12819
|
+
}
|
|
12820
|
+
function getApplyPatchFileScore(file) {
|
|
12821
|
+
if (!file || typeof file !== "object" || Array.isArray(file)) return 0;
|
|
12822
|
+
const f = file;
|
|
12823
|
+
const additions = typeof f.additions === "number" && Number.isFinite(f.additions) && f.additions >= 0 ? f.additions : 0;
|
|
12824
|
+
const deletions = typeof f.deletions === "number" && Number.isFinite(f.deletions) && f.deletions >= 0 ? f.deletions : 0;
|
|
12825
|
+
return additions + deletions;
|
|
12826
|
+
}
|
|
12746
12827
|
function resolveToolResponse(meta) {
|
|
12747
12828
|
const claudeCode = meta.claudeCode;
|
|
12748
12829
|
if (claudeCode?.toolResponse && typeof claudeCode.toolResponse === "object") {
|
|
@@ -12810,6 +12891,7 @@ function parseContent(content) {
|
|
|
12810
12891
|
}
|
|
12811
12892
|
|
|
12812
12893
|
// src/core/message-transformer.ts
|
|
12894
|
+
init_apply_patch_detection();
|
|
12813
12895
|
init_log();
|
|
12814
12896
|
var log5 = createChildLogger({ module: "message-transformer" });
|
|
12815
12897
|
var BINARY_VIEWER_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
@@ -12865,6 +12947,63 @@ function computeLineDiff(oldStr, newStr) {
|
|
|
12865
12947
|
removed: Math.max(0, oldLines.length - prefixLen - suffixLen)
|
|
12866
12948
|
};
|
|
12867
12949
|
}
|
|
12950
|
+
function asRecord2(value) {
|
|
12951
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
12952
|
+
}
|
|
12953
|
+
function asNonNegativeNumber(value) {
|
|
12954
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : null;
|
|
12955
|
+
}
|
|
12956
|
+
function extractDiffStatsFromRawOutput(rawOutput) {
|
|
12957
|
+
const output = asRecord2(rawOutput);
|
|
12958
|
+
const metadata = asRecord2(output?.metadata);
|
|
12959
|
+
if (!metadata) return null;
|
|
12960
|
+
const files = Array.isArray(metadata.files) ? metadata.files : null;
|
|
12961
|
+
if (files && files.length > 0) {
|
|
12962
|
+
let added2 = 0;
|
|
12963
|
+
let removed2 = 0;
|
|
12964
|
+
let hasAny = false;
|
|
12965
|
+
for (const file of files) {
|
|
12966
|
+
const fileMeta = asRecord2(file);
|
|
12967
|
+
if (!fileMeta) continue;
|
|
12968
|
+
const fileAdded = asNonNegativeNumber(fileMeta.additions);
|
|
12969
|
+
const fileRemoved = asNonNegativeNumber(fileMeta.deletions);
|
|
12970
|
+
if (fileAdded === null && fileRemoved === null) continue;
|
|
12971
|
+
added2 += fileAdded ?? 0;
|
|
12972
|
+
removed2 += fileRemoved ?? 0;
|
|
12973
|
+
hasAny = true;
|
|
12974
|
+
}
|
|
12975
|
+
if (hasAny && (added2 > 0 || removed2 > 0)) return { added: added2, removed: removed2 };
|
|
12976
|
+
}
|
|
12977
|
+
const added = asNonNegativeNumber(metadata.additions);
|
|
12978
|
+
const removed = asNonNegativeNumber(metadata.deletions);
|
|
12979
|
+
if (added === null && removed === null) return null;
|
|
12980
|
+
if ((added ?? 0) === 0 && (removed ?? 0) === 0) return null;
|
|
12981
|
+
return {
|
|
12982
|
+
added: added ?? 0,
|
|
12983
|
+
removed: removed ?? 0
|
|
12984
|
+
};
|
|
12985
|
+
}
|
|
12986
|
+
function extractDiffStatsFromToolPayload(name, kind, rawInput, rawOutput) {
|
|
12987
|
+
if (kind === "edit" || kind === "write") {
|
|
12988
|
+
const ri = asRecord2(rawInput);
|
|
12989
|
+
if (!ri) return null;
|
|
12990
|
+
const oldStr = typeof ri.old_string === "string" ? ri.old_string : typeof ri.oldText === "string" ? ri.oldText : null;
|
|
12991
|
+
const newStr = typeof ri.new_string === "string" ? ri.new_string : typeof ri.newText === "string" ? ri.newText : typeof ri.content === "string" ? ri.content : null;
|
|
12992
|
+
if (oldStr !== null && newStr !== null) {
|
|
12993
|
+
const stats = computeLineDiff(oldStr, newStr);
|
|
12994
|
+
return stats.added > 0 || stats.removed > 0 ? stats : null;
|
|
12995
|
+
}
|
|
12996
|
+
if (oldStr === null && newStr !== null && kind === "write") {
|
|
12997
|
+
const added = newStr.split("\n").length;
|
|
12998
|
+
return added > 0 ? { added, removed: 0 } : null;
|
|
12999
|
+
}
|
|
13000
|
+
return null;
|
|
13001
|
+
}
|
|
13002
|
+
if (isApplyPatchOtherTool(kind, name, rawInput)) {
|
|
13003
|
+
return extractDiffStatsFromRawOutput(rawOutput);
|
|
13004
|
+
}
|
|
13005
|
+
return null;
|
|
13006
|
+
}
|
|
12868
13007
|
var MessageTransformer = class {
|
|
12869
13008
|
tunnelService;
|
|
12870
13009
|
/** Cache rawInput from tool_call so it's available in tool_update (which often lacks it) */
|
|
@@ -13014,22 +13153,11 @@ var MessageTransformer = class {
|
|
|
13014
13153
|
return input2 !== null && input2 !== void 0 && typeof input2 === "object" && !Array.isArray(input2) && Object.keys(input2).length > 0;
|
|
13015
13154
|
}
|
|
13016
13155
|
enrichWithViewerLinks(event, metadata, sessionContext) {
|
|
13156
|
+
const name = "name" in event ? event.name || "" : "";
|
|
13017
13157
|
const kind = "kind" in event ? event.kind : void 0;
|
|
13018
|
-
if (!metadata.diffStats
|
|
13019
|
-
const
|
|
13020
|
-
if (
|
|
13021
|
-
const oldStr = typeof ri.old_string === "string" ? ri.old_string : typeof ri.oldText === "string" ? ri.oldText : null;
|
|
13022
|
-
const newStr = typeof ri.new_string === "string" ? ri.new_string : typeof ri.newText === "string" ? ri.newText : typeof ri.content === "string" ? ri.content : null;
|
|
13023
|
-
if (oldStr !== null && newStr !== null) {
|
|
13024
|
-
const stats = computeLineDiff(oldStr, newStr);
|
|
13025
|
-
if (stats.added > 0 || stats.removed > 0) {
|
|
13026
|
-
metadata.diffStats = stats;
|
|
13027
|
-
}
|
|
13028
|
-
} else if (oldStr === null && newStr !== null && kind === "write") {
|
|
13029
|
-
const added = newStr.split("\n").length;
|
|
13030
|
-
if (added > 0) metadata.diffStats = { added, removed: 0 };
|
|
13031
|
-
}
|
|
13032
|
-
}
|
|
13158
|
+
if (!metadata.diffStats) {
|
|
13159
|
+
const stats = extractDiffStatsFromToolPayload(name, kind, event.rawInput, event.rawOutput);
|
|
13160
|
+
if (stats) metadata.diffStats = stats;
|
|
13033
13161
|
}
|
|
13034
13162
|
if (!this.tunnelService || !sessionContext) {
|
|
13035
13163
|
log5.debug(
|
|
@@ -13038,7 +13166,6 @@ var MessageTransformer = class {
|
|
|
13038
13166
|
);
|
|
13039
13167
|
return;
|
|
13040
13168
|
}
|
|
13041
|
-
const name = "name" in event ? event.name || "" : "";
|
|
13042
13169
|
log5.debug(
|
|
13043
13170
|
{ name, kind, status: event.status, hasContent: !!event.content, hasRawInput: !!event.rawInput },
|
|
13044
13171
|
"enrichWithViewerLinks: inspecting event"
|
|
@@ -13048,7 +13175,8 @@ var MessageTransformer = class {
|
|
|
13048
13175
|
kind,
|
|
13049
13176
|
event.content,
|
|
13050
13177
|
event.rawInput,
|
|
13051
|
-
event.meta
|
|
13178
|
+
event.meta,
|
|
13179
|
+
event.rawOutput
|
|
13052
13180
|
);
|
|
13053
13181
|
if (!fileInfo) {
|
|
13054
13182
|
log5.debug(
|
|
@@ -14587,6 +14715,7 @@ var REGISTRY_URL = "https://cdn.agentclientprotocol.com/registry/v1/latest/regis
|
|
|
14587
14715
|
var DEFAULT_TTL_HOURS = 24;
|
|
14588
14716
|
var AgentCatalog = class {
|
|
14589
14717
|
store;
|
|
14718
|
+
globalStore = null;
|
|
14590
14719
|
registryAgents = [];
|
|
14591
14720
|
cachePath;
|
|
14592
14721
|
agentsDir;
|
|
@@ -14594,9 +14723,15 @@ var AgentCatalog = class {
|
|
|
14594
14723
|
this.store = store ?? new AgentStore();
|
|
14595
14724
|
this.cachePath = cachePath ?? path13.join(os6.homedir(), ".openacp", "registry-cache.json");
|
|
14596
14725
|
this.agentsDir = agentsDir;
|
|
14726
|
+
const globalPath = path13.join(os6.homedir(), ".openacp", "agents.json");
|
|
14727
|
+
const storePath = this.store.filePath;
|
|
14728
|
+
if (path13.resolve(storePath) !== path13.resolve(globalPath)) {
|
|
14729
|
+
this.globalStore = new AgentStore(globalPath);
|
|
14730
|
+
}
|
|
14597
14731
|
}
|
|
14598
14732
|
load() {
|
|
14599
14733
|
this.store.load();
|
|
14734
|
+
this.globalStore?.load();
|
|
14600
14735
|
this.loadRegistryFromCacheOrSnapshot();
|
|
14601
14736
|
this.enrichInstalledFromRegistry();
|
|
14602
14737
|
}
|
|
@@ -14636,19 +14771,20 @@ var AgentCatalog = class {
|
|
|
14636
14771
|
if (byId) return byId;
|
|
14637
14772
|
return this.registryAgents.find((a) => getAgentAlias(a.id) === keyOrId);
|
|
14638
14773
|
}
|
|
14639
|
-
// --- Installed ---
|
|
14774
|
+
// --- Installed (instance-first, global-fallback) ---
|
|
14640
14775
|
getInstalled() {
|
|
14641
|
-
|
|
14776
|
+
const merged = { ...this.globalStore?.getInstalled(), ...this.store.getInstalled() };
|
|
14777
|
+
return Object.values(merged);
|
|
14642
14778
|
}
|
|
14643
14779
|
getInstalledEntries() {
|
|
14644
|
-
return this.store.getInstalled();
|
|
14780
|
+
return { ...this.globalStore?.getInstalled(), ...this.store.getInstalled() };
|
|
14645
14781
|
}
|
|
14646
14782
|
getInstalledAgent(key) {
|
|
14647
|
-
return this.store.getAgent(key);
|
|
14783
|
+
return this.store.getAgent(key) ?? this.globalStore?.getAgent(key);
|
|
14648
14784
|
}
|
|
14649
14785
|
// --- Discovery ---
|
|
14650
14786
|
getAvailable() {
|
|
14651
|
-
const installed = this.
|
|
14787
|
+
const installed = this.getInstalledEntries();
|
|
14652
14788
|
const items = [];
|
|
14653
14789
|
const seenKeys = /* @__PURE__ */ new Set();
|
|
14654
14790
|
for (const [key, agent] of Object.entries(installed)) {
|
|
@@ -14722,15 +14858,18 @@ var AgentCatalog = class {
|
|
|
14722
14858
|
this.store.addAgent(key, data);
|
|
14723
14859
|
}
|
|
14724
14860
|
async uninstall(key) {
|
|
14725
|
-
if (
|
|
14726
|
-
|
|
14861
|
+
if (this.store.hasAgent(key)) {
|
|
14862
|
+
await uninstallAgent(key, this.store);
|
|
14863
|
+
return { ok: true };
|
|
14864
|
+
}
|
|
14865
|
+
if (this.globalStore?.getAgent(key)) {
|
|
14866
|
+
return { ok: false, error: `"${key}" is installed globally. Uninstall it from the global instance instead.` };
|
|
14727
14867
|
}
|
|
14728
|
-
|
|
14729
|
-
return { ok: true };
|
|
14868
|
+
return { ok: false, error: `"${key}" is not installed.` };
|
|
14730
14869
|
}
|
|
14731
14870
|
// --- Resolution (for AgentManager) ---
|
|
14732
14871
|
resolve(key) {
|
|
14733
|
-
const agent = this.store.getAgent(key);
|
|
14872
|
+
const agent = this.store.getAgent(key) ?? this.globalStore?.getAgent(key);
|
|
14734
14873
|
if (!agent) return void 0;
|
|
14735
14874
|
return {
|
|
14736
14875
|
name: key,
|
|
@@ -15332,13 +15471,13 @@ init_events();
|
|
|
15332
15471
|
var SETUP_TIMEOUT_MS = 3e4;
|
|
15333
15472
|
var TEARDOWN_TIMEOUT_MS = 1e4;
|
|
15334
15473
|
function withTimeout(promise, ms, label) {
|
|
15335
|
-
return new Promise((
|
|
15474
|
+
return new Promise((resolve7, reject) => {
|
|
15336
15475
|
const timer = setTimeout(() => reject(new Error(`Timeout: ${label} exceeded ${ms}ms`)), ms);
|
|
15337
15476
|
if (typeof timer === "object" && timer !== null && "unref" in timer) {
|
|
15338
15477
|
;
|
|
15339
15478
|
timer.unref();
|
|
15340
15479
|
}
|
|
15341
|
-
promise.then(
|
|
15480
|
+
promise.then(resolve7, reject).finally(() => clearTimeout(timer));
|
|
15342
15481
|
});
|
|
15343
15482
|
}
|
|
15344
15483
|
function resolvePluginConfig(pluginName, configManager) {
|
|
@@ -17665,7 +17804,7 @@ function startDaemon(pidPath = getPidPath(), logDir2, instanceRoot) {
|
|
|
17665
17804
|
return { pid: child.pid };
|
|
17666
17805
|
}
|
|
17667
17806
|
function sleep(ms) {
|
|
17668
|
-
return new Promise((
|
|
17807
|
+
return new Promise((resolve7) => setTimeout(resolve7, ms));
|
|
17669
17808
|
}
|
|
17670
17809
|
function isProcessAlive2(pid) {
|
|
17671
17810
|
try {
|