@ganglion/xacpx 0.15.0 → 0.15.2
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/README.md +2 -2
- package/dist/bridge/bridge-main.js +156 -11
- package/dist/cli.js +238 -65
- package/dist/transport/types.d.ts +2 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# xacpx
|
|
2
2
|
|
|
3
|
+

|
|
4
|
+
|
|
3
5
|
> Remotely drive Codex, Claude Code, and other acpx sessions from WeChat, Feishu, or Yuanbao.
|
|
4
6
|
|
|
5
7
|
[](https://www.npmjs.com/package/@ganglion/xacpx)
|
|
@@ -13,8 +15,6 @@ English · **[中文](./docs/zh/README_zh.md)**
|
|
|
13
15
|
|
|
14
16
|
`xacpx` is a tool that lets you control ACP agents such as Codex / Claude Code / Gemini / OpenCode directly from WeChat, Feishu, or Yuanbao. It connects chat messages to your agent CLI sessions through `acpx`, so you can, right from your phone:
|
|
15
17
|
|
|
16
|
-
[](https://imgchr.com/i/pmZXIv6)
|
|
17
|
-
|
|
18
18
|
- Create and switch between sessions
|
|
19
19
|
- Have the agent keep working in a specific project directory
|
|
20
20
|
- View streaming replies, final results, and tool-call summaries
|
|
@@ -3470,6 +3470,143 @@ var init_path = __esm(() => {
|
|
|
3470
3470
|
ROOT_PATH_RE = /^(\/|[a-zA-Z]:\/?)$/;
|
|
3471
3471
|
});
|
|
3472
3472
|
|
|
3473
|
+
// src/transport/codex-subagent-filter.ts
|
|
3474
|
+
import { closeSync, openSync, readdirSync, readSync, statSync } from "node:fs";
|
|
3475
|
+
import { homedir as homedir4 } from "node:os";
|
|
3476
|
+
import { join as join3 } from "node:path";
|
|
3477
|
+
function resolveCodexHome(env = process.env) {
|
|
3478
|
+
const fromEnv = env.CODEX_HOME?.trim();
|
|
3479
|
+
return fromEnv ? fromEnv : join3(homedir4(), ".codex");
|
|
3480
|
+
}
|
|
3481
|
+
function isPlainObject(value) {
|
|
3482
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
3483
|
+
}
|
|
3484
|
+
function isSubagentSource(source) {
|
|
3485
|
+
if (!isPlainObject(source) || !Object.hasOwn(source, "subagent"))
|
|
3486
|
+
return false;
|
|
3487
|
+
const subagent = source.subagent;
|
|
3488
|
+
if (!isPlainObject(subagent))
|
|
3489
|
+
return false;
|
|
3490
|
+
return Object.values(subagent).some((variant) => isPlainObject(variant) && typeof variant.parent_thread_id === "string");
|
|
3491
|
+
}
|
|
3492
|
+
function sessionMetaLineIsSubagent(line) {
|
|
3493
|
+
if (!line)
|
|
3494
|
+
return false;
|
|
3495
|
+
let parsed;
|
|
3496
|
+
try {
|
|
3497
|
+
parsed = JSON.parse(line);
|
|
3498
|
+
} catch {
|
|
3499
|
+
return false;
|
|
3500
|
+
}
|
|
3501
|
+
const payload = parsed?.payload;
|
|
3502
|
+
return isSubagentSource(payload?.source);
|
|
3503
|
+
}
|
|
3504
|
+
function createSubagentPredicate(reader) {
|
|
3505
|
+
let index = null;
|
|
3506
|
+
const cache = new Map;
|
|
3507
|
+
return (sessionId) => {
|
|
3508
|
+
const cached = cache.get(sessionId);
|
|
3509
|
+
if (cached !== undefined)
|
|
3510
|
+
return cached;
|
|
3511
|
+
let result = false;
|
|
3512
|
+
try {
|
|
3513
|
+
if (!index) {
|
|
3514
|
+
index = new Map;
|
|
3515
|
+
for (const path4 of reader.listRolloutPaths()) {
|
|
3516
|
+
const id = path4.match(ROLLOUT_RE)?.[1];
|
|
3517
|
+
if (id)
|
|
3518
|
+
index.set(id.toLowerCase(), path4);
|
|
3519
|
+
}
|
|
3520
|
+
}
|
|
3521
|
+
const path3 = index.get(sessionId.toLowerCase());
|
|
3522
|
+
if (path3)
|
|
3523
|
+
result = sessionMetaLineIsSubagent(reader.readFirstLine(path3));
|
|
3524
|
+
} catch {
|
|
3525
|
+
result = false;
|
|
3526
|
+
}
|
|
3527
|
+
cache.set(sessionId, result);
|
|
3528
|
+
return result;
|
|
3529
|
+
};
|
|
3530
|
+
}
|
|
3531
|
+
function filterSubagentSessions(result, isSubagent) {
|
|
3532
|
+
return {
|
|
3533
|
+
...result,
|
|
3534
|
+
sessions: result.sessions.filter((session3) => {
|
|
3535
|
+
try {
|
|
3536
|
+
return !isSubagent(session3.sessionId);
|
|
3537
|
+
} catch {
|
|
3538
|
+
return true;
|
|
3539
|
+
}
|
|
3540
|
+
})
|
|
3541
|
+
};
|
|
3542
|
+
}
|
|
3543
|
+
function nodeRolloutReader(home) {
|
|
3544
|
+
const root = join3(home, "sessions");
|
|
3545
|
+
return {
|
|
3546
|
+
listRolloutPaths() {
|
|
3547
|
+
const out = [];
|
|
3548
|
+
const walk = (dir) => {
|
|
3549
|
+
let entries;
|
|
3550
|
+
try {
|
|
3551
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
3552
|
+
} catch {
|
|
3553
|
+
return;
|
|
3554
|
+
}
|
|
3555
|
+
for (const entry of entries) {
|
|
3556
|
+
const full = join3(dir, entry.name);
|
|
3557
|
+
if (entry.isDirectory())
|
|
3558
|
+
walk(full);
|
|
3559
|
+
else if (entry.isFile() && entry.name.startsWith("rollout-") && entry.name.endsWith(".jsonl"))
|
|
3560
|
+
out.push(full);
|
|
3561
|
+
}
|
|
3562
|
+
};
|
|
3563
|
+
walk(root);
|
|
3564
|
+
return out;
|
|
3565
|
+
},
|
|
3566
|
+
readFirstLine(path3) {
|
|
3567
|
+
let fd;
|
|
3568
|
+
try {
|
|
3569
|
+
statSync(path3);
|
|
3570
|
+
fd = openSync(path3, "r");
|
|
3571
|
+
const buf = Buffer.alloc(READ_CHUNK);
|
|
3572
|
+
let acc = "";
|
|
3573
|
+
let total = 0;
|
|
3574
|
+
for (;; ) {
|
|
3575
|
+
const bytes = readSync(fd, buf, 0, READ_CHUNK, total);
|
|
3576
|
+
if (bytes <= 0)
|
|
3577
|
+
break;
|
|
3578
|
+
acc += buf.toString("utf8", 0, bytes);
|
|
3579
|
+
total += bytes;
|
|
3580
|
+
const nl = acc.indexOf(`
|
|
3581
|
+
`);
|
|
3582
|
+
if (nl !== -1)
|
|
3583
|
+
return acc.slice(0, nl);
|
|
3584
|
+
if (total >= FIRST_LINE_READ_CAP)
|
|
3585
|
+
return;
|
|
3586
|
+
}
|
|
3587
|
+
return acc.length ? acc : undefined;
|
|
3588
|
+
} catch {
|
|
3589
|
+
return;
|
|
3590
|
+
} finally {
|
|
3591
|
+
if (fd !== undefined) {
|
|
3592
|
+
try {
|
|
3593
|
+
closeSync(fd);
|
|
3594
|
+
} catch {}
|
|
3595
|
+
}
|
|
3596
|
+
}
|
|
3597
|
+
}
|
|
3598
|
+
};
|
|
3599
|
+
}
|
|
3600
|
+
function codexSubagentPredicate(env) {
|
|
3601
|
+
return createSubagentPredicate(nodeRolloutReader(resolveCodexHome(env)));
|
|
3602
|
+
}
|
|
3603
|
+
var CODEX_AGENT_NAME = "codex", FIRST_LINE_READ_CAP, READ_CHUNK, ROLLOUT_RE;
|
|
3604
|
+
var init_codex_subagent_filter = __esm(() => {
|
|
3605
|
+
FIRST_LINE_READ_CAP = 1024 * 1024;
|
|
3606
|
+
READ_CHUNK = 64 * 1024;
|
|
3607
|
+
ROLLOUT_RE = /rollout-.*-([0-9a-fA-F-]{36})\.jsonl$/;
|
|
3608
|
+
});
|
|
3609
|
+
|
|
3473
3610
|
// src/transport/agent-session-list.ts
|
|
3474
3611
|
function isUnknownFilterCwdOption(output) {
|
|
3475
3612
|
return /(?:unknown|unrecognized) option/i.test(output) && output.includes("--filter-cwd");
|
|
@@ -3487,7 +3624,11 @@ async function runAgentSessionList(options) {
|
|
|
3487
3624
|
}
|
|
3488
3625
|
throw new Error(options.formatError(result));
|
|
3489
3626
|
}
|
|
3490
|
-
|
|
3627
|
+
const parsed = parseAgentSessionListOutput(result.stdout, filterLocally ? options.filterCwd : undefined);
|
|
3628
|
+
if (parsed && options.isSubagentSession) {
|
|
3629
|
+
return filterSubagentSessions(parsed, options.isSubagentSession);
|
|
3630
|
+
}
|
|
3631
|
+
return parsed;
|
|
3491
3632
|
}
|
|
3492
3633
|
function parseAgentSessionListOutput(stdout, filterCwd) {
|
|
3493
3634
|
let parsed;
|
|
@@ -3522,16 +3663,17 @@ function filterAgentSessionListByCwd(result, cwd) {
|
|
|
3522
3663
|
}
|
|
3523
3664
|
var init_agent_session_list = __esm(() => {
|
|
3524
3665
|
init_path();
|
|
3666
|
+
init_codex_subagent_filter();
|
|
3525
3667
|
});
|
|
3526
3668
|
|
|
3527
3669
|
// src/transport/acpx-session-files.ts
|
|
3528
3670
|
import { readdir, unlink as unlink2 } from "node:fs/promises";
|
|
3529
|
-
import { homedir as
|
|
3530
|
-
import { join as
|
|
3671
|
+
import { homedir as homedir5 } from "node:os";
|
|
3672
|
+
import { join as join4 } from "node:path";
|
|
3531
3673
|
async function deleteAcpxSessionFiles(options) {
|
|
3532
|
-
const dir = options.sessionsDir ??
|
|
3674
|
+
const dir = options.sessionsDir ?? join4(homedir5(), ".acpx", "sessions");
|
|
3533
3675
|
const safeId = encodeURIComponent(options.acpxRecordId);
|
|
3534
|
-
await unlink2(
|
|
3676
|
+
await unlink2(join4(dir, `${safeId}.json`)).catch(() => {
|
|
3535
3677
|
return;
|
|
3536
3678
|
});
|
|
3537
3679
|
let entries;
|
|
@@ -3542,7 +3684,7 @@ async function deleteAcpxSessionFiles(options) {
|
|
|
3542
3684
|
}
|
|
3543
3685
|
const streamFiles = entries.filter((name) => name.startsWith(`${safeId}.stream.`));
|
|
3544
3686
|
for (const name of streamFiles) {
|
|
3545
|
-
await unlink2(
|
|
3687
|
+
await unlink2(join4(dir, name)).catch(() => {
|
|
3546
3688
|
return;
|
|
3547
3689
|
});
|
|
3548
3690
|
}
|
|
@@ -3622,8 +3764,8 @@ init_prompt_output();
|
|
|
3622
3764
|
init_prompt_media();
|
|
3623
3765
|
init_streaming_prompt();
|
|
3624
3766
|
import { copyFile, readdir as readdir2 } from "node:fs/promises";
|
|
3625
|
-
import { homedir as
|
|
3626
|
-
import { dirname as dirname2, join as
|
|
3767
|
+
import { homedir as homedir6 } from "node:os";
|
|
3768
|
+
import { dirname as dirname2, join as join5, win32 } from "node:path";
|
|
3627
3769
|
import { spawn as spawn4 } from "node:child_process";
|
|
3628
3770
|
|
|
3629
3771
|
// src/bridge/parse-missing-optional-dep.ts
|
|
@@ -3643,6 +3785,7 @@ function parseMissingOptionalDep(text) {
|
|
|
3643
3785
|
init_discover_parent_package_paths();
|
|
3644
3786
|
init_acpx_queue_owner_launcher();
|
|
3645
3787
|
init_agent_session_list();
|
|
3788
|
+
init_codex_subagent_filter();
|
|
3646
3789
|
init_acpx_session_files();
|
|
3647
3790
|
class EnsureSessionFailedError extends Error {
|
|
3648
3791
|
kind;
|
|
@@ -3708,7 +3851,8 @@ class BridgeRuntime {
|
|
|
3708
3851
|
], { format: "json" }));
|
|
3709
3852
|
return await this.run(spec.command, spec.args);
|
|
3710
3853
|
},
|
|
3711
|
-
formatError: (result) => result.stderr || result.stdout || `sessions list failed with exit code ${result.code}
|
|
3854
|
+
formatError: (result) => result.stderr || result.stdout || `sessions list failed with exit code ${result.code}`,
|
|
3855
|
+
isSubagentSession: (input.driver ?? input.agent) === CODEX_AGENT_NAME ? codexSubagentPredicate() : undefined
|
|
3712
3856
|
});
|
|
3713
3857
|
}
|
|
3714
3858
|
async resumeAgentSession(input) {
|
|
@@ -4218,11 +4362,11 @@ async function tryRepairAcpxSessionIndex(deps = {}) {
|
|
|
4218
4362
|
if (platform !== "win32") {
|
|
4219
4363
|
return false;
|
|
4220
4364
|
}
|
|
4221
|
-
const home = deps.home ?? process.env.HOME ?? process.env.USERPROFILE ??
|
|
4365
|
+
const home = deps.home ?? process.env.HOME ?? process.env.USERPROFILE ?? homedir6();
|
|
4222
4366
|
if (!home) {
|
|
4223
4367
|
return false;
|
|
4224
4368
|
}
|
|
4225
|
-
const pathJoin = platform === "win32" ? win32.join :
|
|
4369
|
+
const pathJoin = platform === "win32" ? win32.join : join5;
|
|
4226
4370
|
const sessionsDir = pathJoin(home, ".acpx", "sessions");
|
|
4227
4371
|
const indexPath = pathJoin(sessionsDir, "index.json");
|
|
4228
4372
|
const readdirFn = deps.readdirFn ?? readdir2;
|
|
@@ -4372,6 +4516,7 @@ class BridgeServer {
|
|
|
4372
4516
|
return await this.runtime.listAgentSessions({
|
|
4373
4517
|
agent: requireString(params, "agent"),
|
|
4374
4518
|
agentCommand: asOptionalString(params.agentCommand),
|
|
4519
|
+
driver: asOptionalString(params.driver),
|
|
4375
4520
|
cwd: requireString(params, "cwd"),
|
|
4376
4521
|
cursor: asOptionalString(params.cursor),
|
|
4377
4522
|
filterCwd: asOptionalString(params.filterCwd)
|
package/dist/cli.js
CHANGED
|
@@ -23806,6 +23806,15 @@ var init_session_shortcut_handler = __esm(() => {
|
|
|
23806
23806
|
});
|
|
23807
23807
|
|
|
23808
23808
|
// src/commands/handlers/native-session-handler.ts
|
|
23809
|
+
async function listFirstNonEmptyPage(listAgentSessions, query) {
|
|
23810
|
+
let result = await listAgentSessions(query);
|
|
23811
|
+
let guard = 0;
|
|
23812
|
+
while (result && result.sessions.length === 0 && result.nextCursor && guard < MAX_EMPTY_PAGE_ADVANCE) {
|
|
23813
|
+
guard++;
|
|
23814
|
+
result = await listAgentSessions({ ...query, cursor: result.nextCursor });
|
|
23815
|
+
}
|
|
23816
|
+
return result;
|
|
23817
|
+
}
|
|
23809
23818
|
async function handleNativeSessionList(context, chatKey, input) {
|
|
23810
23819
|
const target = await resolveNativeTarget(context, chatKey, input);
|
|
23811
23820
|
if (isRouterResponse(target)) {
|
|
@@ -23818,13 +23827,14 @@ async function handleNativeSessionList(context, chatKey, input) {
|
|
|
23818
23827
|
const query = {
|
|
23819
23828
|
agent: target.agent,
|
|
23820
23829
|
agentCommand: target.agentCommand,
|
|
23830
|
+
...target.driver ? { driver: target.driver } : {},
|
|
23821
23831
|
cwd: target.cwd,
|
|
23822
23832
|
...input.cursor ? { cursor: input.cursor } : {},
|
|
23823
23833
|
...input.all ? {} : { filterCwd: target.cwd }
|
|
23824
23834
|
};
|
|
23825
23835
|
let result;
|
|
23826
23836
|
try {
|
|
23827
|
-
result = await listAgentSessions
|
|
23837
|
+
result = await listFirstNonEmptyPage(listAgentSessions, query);
|
|
23828
23838
|
} catch (error2) {
|
|
23829
23839
|
return { text: renderNativeListError(target, error2) };
|
|
23830
23840
|
}
|
|
@@ -23950,6 +23960,7 @@ async function resolveNativeTarget(context, chatKey, input) {
|
|
|
23950
23960
|
agent: agent3,
|
|
23951
23961
|
agentDisplayName: displayAgentName(agent3),
|
|
23952
23962
|
agentCommand: resolveRuntimeAgentCommand(agentConfig.driver, agentConfig.command, context.config?.transport.preferLocalAgents !== false),
|
|
23963
|
+
driver: agentConfig.driver,
|
|
23953
23964
|
workspace: workspaceResolution.workspace,
|
|
23954
23965
|
workspaceLabel: workspaceResolution.workspaceLabel,
|
|
23955
23966
|
cwd: workspaceResolution.cwd,
|
|
@@ -24185,7 +24196,7 @@ function displayAgentName(agent3) {
|
|
|
24185
24196
|
}
|
|
24186
24197
|
return agent3.charAt(0).toUpperCase() + agent3.slice(1);
|
|
24187
24198
|
}
|
|
24188
|
-
var NATIVE_SESSION_CACHE_TTL_MS;
|
|
24199
|
+
var NATIVE_SESSION_CACHE_TTL_MS, MAX_EMPTY_PAGE_ADVANCE = 25;
|
|
24189
24200
|
var init_native_session_handler = __esm(() => {
|
|
24190
24201
|
init_resolve_agent_command();
|
|
24191
24202
|
init_channel_scope();
|
|
@@ -25054,6 +25065,7 @@ class CommandRouter {
|
|
|
25054
25065
|
const result = await listAgentSessions({
|
|
25055
25066
|
agent: agent3,
|
|
25056
25067
|
...agentCommand ? { agentCommand } : {},
|
|
25068
|
+
...agentConfig.driver ? { driver: agentConfig.driver } : {},
|
|
25057
25069
|
cwd: workspaceConfig.cwd,
|
|
25058
25070
|
filterCwd: workspaceConfig.cwd
|
|
25059
25071
|
});
|
|
@@ -32150,6 +32162,143 @@ function permissionModeToFlag(permissionMode) {
|
|
|
32150
32162
|
}
|
|
32151
32163
|
}
|
|
32152
32164
|
|
|
32165
|
+
// src/transport/codex-subagent-filter.ts
|
|
32166
|
+
import { closeSync, openSync, readdirSync, readSync, statSync as statSync2 } from "node:fs";
|
|
32167
|
+
import { homedir as homedir9 } from "node:os";
|
|
32168
|
+
import { join as join19 } from "node:path";
|
|
32169
|
+
function resolveCodexHome(env = process.env) {
|
|
32170
|
+
const fromEnv = env.CODEX_HOME?.trim();
|
|
32171
|
+
return fromEnv ? fromEnv : join19(homedir9(), ".codex");
|
|
32172
|
+
}
|
|
32173
|
+
function isPlainObject3(value) {
|
|
32174
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
32175
|
+
}
|
|
32176
|
+
function isSubagentSource(source) {
|
|
32177
|
+
if (!isPlainObject3(source) || !Object.hasOwn(source, "subagent"))
|
|
32178
|
+
return false;
|
|
32179
|
+
const subagent = source.subagent;
|
|
32180
|
+
if (!isPlainObject3(subagent))
|
|
32181
|
+
return false;
|
|
32182
|
+
return Object.values(subagent).some((variant) => isPlainObject3(variant) && typeof variant.parent_thread_id === "string");
|
|
32183
|
+
}
|
|
32184
|
+
function sessionMetaLineIsSubagent(line) {
|
|
32185
|
+
if (!line)
|
|
32186
|
+
return false;
|
|
32187
|
+
let parsed;
|
|
32188
|
+
try {
|
|
32189
|
+
parsed = JSON.parse(line);
|
|
32190
|
+
} catch {
|
|
32191
|
+
return false;
|
|
32192
|
+
}
|
|
32193
|
+
const payload = parsed?.payload;
|
|
32194
|
+
return isSubagentSource(payload?.source);
|
|
32195
|
+
}
|
|
32196
|
+
function createSubagentPredicate(reader) {
|
|
32197
|
+
let index = null;
|
|
32198
|
+
const cache = new Map;
|
|
32199
|
+
return (sessionId) => {
|
|
32200
|
+
const cached2 = cache.get(sessionId);
|
|
32201
|
+
if (cached2 !== undefined)
|
|
32202
|
+
return cached2;
|
|
32203
|
+
let result = false;
|
|
32204
|
+
try {
|
|
32205
|
+
if (!index) {
|
|
32206
|
+
index = new Map;
|
|
32207
|
+
for (const path16 of reader.listRolloutPaths()) {
|
|
32208
|
+
const id = path16.match(ROLLOUT_RE)?.[1];
|
|
32209
|
+
if (id)
|
|
32210
|
+
index.set(id.toLowerCase(), path16);
|
|
32211
|
+
}
|
|
32212
|
+
}
|
|
32213
|
+
const path15 = index.get(sessionId.toLowerCase());
|
|
32214
|
+
if (path15)
|
|
32215
|
+
result = sessionMetaLineIsSubagent(reader.readFirstLine(path15));
|
|
32216
|
+
} catch {
|
|
32217
|
+
result = false;
|
|
32218
|
+
}
|
|
32219
|
+
cache.set(sessionId, result);
|
|
32220
|
+
return result;
|
|
32221
|
+
};
|
|
32222
|
+
}
|
|
32223
|
+
function filterSubagentSessions(result, isSubagent) {
|
|
32224
|
+
return {
|
|
32225
|
+
...result,
|
|
32226
|
+
sessions: result.sessions.filter((session3) => {
|
|
32227
|
+
try {
|
|
32228
|
+
return !isSubagent(session3.sessionId);
|
|
32229
|
+
} catch {
|
|
32230
|
+
return true;
|
|
32231
|
+
}
|
|
32232
|
+
})
|
|
32233
|
+
};
|
|
32234
|
+
}
|
|
32235
|
+
function nodeRolloutReader(home) {
|
|
32236
|
+
const root = join19(home, "sessions");
|
|
32237
|
+
return {
|
|
32238
|
+
listRolloutPaths() {
|
|
32239
|
+
const out = [];
|
|
32240
|
+
const walk = (dir) => {
|
|
32241
|
+
let entries;
|
|
32242
|
+
try {
|
|
32243
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
32244
|
+
} catch {
|
|
32245
|
+
return;
|
|
32246
|
+
}
|
|
32247
|
+
for (const entry of entries) {
|
|
32248
|
+
const full = join19(dir, entry.name);
|
|
32249
|
+
if (entry.isDirectory())
|
|
32250
|
+
walk(full);
|
|
32251
|
+
else if (entry.isFile() && entry.name.startsWith("rollout-") && entry.name.endsWith(".jsonl"))
|
|
32252
|
+
out.push(full);
|
|
32253
|
+
}
|
|
32254
|
+
};
|
|
32255
|
+
walk(root);
|
|
32256
|
+
return out;
|
|
32257
|
+
},
|
|
32258
|
+
readFirstLine(path15) {
|
|
32259
|
+
let fd;
|
|
32260
|
+
try {
|
|
32261
|
+
statSync2(path15);
|
|
32262
|
+
fd = openSync(path15, "r");
|
|
32263
|
+
const buf = Buffer.alloc(READ_CHUNK);
|
|
32264
|
+
let acc = "";
|
|
32265
|
+
let total = 0;
|
|
32266
|
+
for (;; ) {
|
|
32267
|
+
const bytes = readSync(fd, buf, 0, READ_CHUNK, total);
|
|
32268
|
+
if (bytes <= 0)
|
|
32269
|
+
break;
|
|
32270
|
+
acc += buf.toString("utf8", 0, bytes);
|
|
32271
|
+
total += bytes;
|
|
32272
|
+
const nl = acc.indexOf(`
|
|
32273
|
+
`);
|
|
32274
|
+
if (nl !== -1)
|
|
32275
|
+
return acc.slice(0, nl);
|
|
32276
|
+
if (total >= FIRST_LINE_READ_CAP)
|
|
32277
|
+
return;
|
|
32278
|
+
}
|
|
32279
|
+
return acc.length ? acc : undefined;
|
|
32280
|
+
} catch {
|
|
32281
|
+
return;
|
|
32282
|
+
} finally {
|
|
32283
|
+
if (fd !== undefined) {
|
|
32284
|
+
try {
|
|
32285
|
+
closeSync(fd);
|
|
32286
|
+
} catch {}
|
|
32287
|
+
}
|
|
32288
|
+
}
|
|
32289
|
+
}
|
|
32290
|
+
};
|
|
32291
|
+
}
|
|
32292
|
+
function codexSubagentPredicate(env) {
|
|
32293
|
+
return createSubagentPredicate(nodeRolloutReader(resolveCodexHome(env)));
|
|
32294
|
+
}
|
|
32295
|
+
var CODEX_AGENT_NAME = "codex", FIRST_LINE_READ_CAP, READ_CHUNK, ROLLOUT_RE;
|
|
32296
|
+
var init_codex_subagent_filter = __esm(() => {
|
|
32297
|
+
FIRST_LINE_READ_CAP = 1024 * 1024;
|
|
32298
|
+
READ_CHUNK = 64 * 1024;
|
|
32299
|
+
ROLLOUT_RE = /rollout-.*-([0-9a-fA-F-]{36})\.jsonl$/;
|
|
32300
|
+
});
|
|
32301
|
+
|
|
32153
32302
|
// src/transport/agent-session-list.ts
|
|
32154
32303
|
function isUnknownFilterCwdOption(output) {
|
|
32155
32304
|
return /(?:unknown|unrecognized) option/i.test(output) && output.includes("--filter-cwd");
|
|
@@ -32167,7 +32316,11 @@ async function runAgentSessionList(options) {
|
|
|
32167
32316
|
}
|
|
32168
32317
|
throw new Error(options.formatError(result));
|
|
32169
32318
|
}
|
|
32170
|
-
|
|
32319
|
+
const parsed = parseAgentSessionListOutput(result.stdout, filterLocally ? options.filterCwd : undefined);
|
|
32320
|
+
if (parsed && options.isSubagentSession) {
|
|
32321
|
+
return filterSubagentSessions(parsed, options.isSubagentSession);
|
|
32322
|
+
}
|
|
32323
|
+
return parsed;
|
|
32171
32324
|
}
|
|
32172
32325
|
function parseAgentSessionListOutput(stdout2, filterCwd) {
|
|
32173
32326
|
let parsed;
|
|
@@ -32202,16 +32355,17 @@ function filterAgentSessionListByCwd(result, cwd) {
|
|
|
32202
32355
|
}
|
|
32203
32356
|
var init_agent_session_list = __esm(() => {
|
|
32204
32357
|
init_path();
|
|
32358
|
+
init_codex_subagent_filter();
|
|
32205
32359
|
});
|
|
32206
32360
|
|
|
32207
32361
|
// src/transport/acpx-session-files.ts
|
|
32208
32362
|
import { readdir as readdir3, unlink as unlink2 } from "node:fs/promises";
|
|
32209
|
-
import { homedir as
|
|
32210
|
-
import { join as
|
|
32363
|
+
import { homedir as homedir10 } from "node:os";
|
|
32364
|
+
import { join as join20 } from "node:path";
|
|
32211
32365
|
async function deleteAcpxSessionFiles(options) {
|
|
32212
|
-
const dir = options.sessionsDir ??
|
|
32366
|
+
const dir = options.sessionsDir ?? join20(homedir10(), ".acpx", "sessions");
|
|
32213
32367
|
const safeId = encodeURIComponent(options.acpxRecordId);
|
|
32214
|
-
await unlink2(
|
|
32368
|
+
await unlink2(join20(dir, `${safeId}.json`)).catch(() => {
|
|
32215
32369
|
return;
|
|
32216
32370
|
});
|
|
32217
32371
|
let entries;
|
|
@@ -32222,7 +32376,7 @@ async function deleteAcpxSessionFiles(options) {
|
|
|
32222
32376
|
}
|
|
32223
32377
|
const streamFiles = entries.filter((name) => name.startsWith(`${safeId}.stream.`));
|
|
32224
32378
|
for (const name of streamFiles) {
|
|
32225
|
-
await unlink2(
|
|
32379
|
+
await unlink2(join20(dir, name)).catch(() => {
|
|
32226
32380
|
return;
|
|
32227
32381
|
});
|
|
32228
32382
|
}
|
|
@@ -32352,7 +32506,8 @@ class AcpxCliTransport {
|
|
|
32352
32506
|
timeoutMs: this.sessionInitTimeoutMs
|
|
32353
32507
|
});
|
|
32354
32508
|
},
|
|
32355
|
-
formatError: (result) => normalizeCommandError(result) ?? `command failed with exit code ${result.code}
|
|
32509
|
+
formatError: (result) => normalizeCommandError(result) ?? `command failed with exit code ${result.code}`,
|
|
32510
|
+
isSubagentSession: (query.driver ?? query.agent) === CODEX_AGENT_NAME ? codexSubagentPredicate() : undefined
|
|
32356
32511
|
});
|
|
32357
32512
|
}
|
|
32358
32513
|
async tailSessionHistory(session3, lines) {
|
|
@@ -32812,6 +32967,7 @@ var init_acpx_cli_transport = __esm(() => {
|
|
|
32812
32967
|
init_terminate_process_tree();
|
|
32813
32968
|
init_acpx_queue_owner_launcher();
|
|
32814
32969
|
init_agent_session_list();
|
|
32970
|
+
init_codex_subagent_filter();
|
|
32815
32971
|
init_acpx_session_files();
|
|
32816
32972
|
require4 = createRequire5(import.meta.url);
|
|
32817
32973
|
});
|
|
@@ -33284,8 +33440,8 @@ function createControlEventBus(logger2) {
|
|
|
33284
33440
|
|
|
33285
33441
|
// src/transport/native-session-history.ts
|
|
33286
33442
|
import { readFile as readFile14 } from "node:fs/promises";
|
|
33287
|
-
import { homedir as
|
|
33288
|
-
import { join as
|
|
33443
|
+
import { homedir as homedir11 } from "node:os";
|
|
33444
|
+
import { join as join21 } from "node:path";
|
|
33289
33445
|
function classifyToolKind(name) {
|
|
33290
33446
|
const n = name.toLowerCase();
|
|
33291
33447
|
if (/(^|[^a-z])(read|cat|view|open)([^a-z]|$)/.test(n))
|
|
@@ -33397,8 +33553,8 @@ function mapAcpxMessagesToHistory(raw) {
|
|
|
33397
33553
|
}
|
|
33398
33554
|
async function readNativeSessionHistory(opts) {
|
|
33399
33555
|
try {
|
|
33400
|
-
const dir = opts.sessionsDir ??
|
|
33401
|
-
const indexRaw = await readFile14(
|
|
33556
|
+
const dir = opts.sessionsDir ?? join21(opts.homeDir ?? homedir11(), ".acpx", "sessions");
|
|
33557
|
+
const indexRaw = await readFile14(join21(dir, "index.json"), "utf8").catch(() => null);
|
|
33402
33558
|
if (!indexRaw)
|
|
33403
33559
|
return [];
|
|
33404
33560
|
const index = JSON.parse(indexRaw);
|
|
@@ -33407,7 +33563,7 @@ async function readNativeSessionHistory(opts) {
|
|
|
33407
33563
|
for (const entry of candidates) {
|
|
33408
33564
|
if (!entry.file)
|
|
33409
33565
|
continue;
|
|
33410
|
-
const recRaw = await readFile14(
|
|
33566
|
+
const recRaw = await readFile14(join21(dir, entry.file), "utf8").catch(() => null);
|
|
33411
33567
|
if (!recRaw)
|
|
33412
33568
|
continue;
|
|
33413
33569
|
const record3 = JSON.parse(recRaw);
|
|
@@ -33425,14 +33581,14 @@ var init_native_session_history = () => {};
|
|
|
33425
33581
|
// src/control/workspace-fs.ts
|
|
33426
33582
|
import { execFile } from "node:child_process";
|
|
33427
33583
|
import { promisify } from "node:util";
|
|
33428
|
-
import { homedir as
|
|
33584
|
+
import { homedir as homedir12 } from "node:os";
|
|
33429
33585
|
import { readdir as readdir4, realpath, stat as stat3, open as open5 } from "node:fs/promises";
|
|
33430
33586
|
import { isAbsolute as isAbsolute3, relative, resolve as resolve3, sep } from "node:path";
|
|
33431
33587
|
function expandHome2(p) {
|
|
33432
33588
|
if (p === "~")
|
|
33433
|
-
return
|
|
33589
|
+
return homedir12();
|
|
33434
33590
|
if (p.startsWith("~/") || p.startsWith("~" + sep))
|
|
33435
|
-
return resolve3(
|
|
33591
|
+
return resolve3(homedir12(), p.slice(2));
|
|
33436
33592
|
return p;
|
|
33437
33593
|
}
|
|
33438
33594
|
|
|
@@ -33561,16 +33717,16 @@ class WorkspaceFs {
|
|
|
33561
33717
|
}
|
|
33562
33718
|
const files = [];
|
|
33563
33719
|
try {
|
|
33564
|
-
const { stdout: stdout2 } = await execFileAsync("git", ["-C", root, "status", "--porcelain"], { maxBuffer: GIT_MAX_BUFFER });
|
|
33565
|
-
|
|
33566
|
-
|
|
33567
|
-
|
|
33720
|
+
const { stdout: stdout2 } = await execFileAsync("git", ["-C", root, "-c", "core.quotePath=false", "status", "--porcelain", "-z"], { maxBuffer: GIT_MAX_BUFFER });
|
|
33721
|
+
const fields = stdout2.split("\x00");
|
|
33722
|
+
for (let i = 0;i < fields.length; i++) {
|
|
33723
|
+
const field = fields[i];
|
|
33724
|
+
if (!field)
|
|
33568
33725
|
continue;
|
|
33569
|
-
const status =
|
|
33570
|
-
|
|
33571
|
-
|
|
33572
|
-
|
|
33573
|
-
path15 = path15.slice(arrow + 4);
|
|
33726
|
+
const status = field.slice(0, 2);
|
|
33727
|
+
const path15 = field.slice(3);
|
|
33728
|
+
if (status[0] === "R" || status[0] === "C")
|
|
33729
|
+
i++;
|
|
33574
33730
|
files.push({ path: path15, status });
|
|
33575
33731
|
}
|
|
33576
33732
|
} catch {}
|
|
@@ -33585,6 +33741,15 @@ class WorkspaceFs {
|
|
|
33585
33741
|
diff = "";
|
|
33586
33742
|
}
|
|
33587
33743
|
}
|
|
33744
|
+
if (rel && !diff) {
|
|
33745
|
+
try {
|
|
33746
|
+
diff = (await execFileAsync("git", ["-C", root, "-c", "core.quotePath=false", "diff", "--no-index", "--", "/dev/null", rel], { maxBuffer: GIT_MAX_BUFFER })).stdout;
|
|
33747
|
+
} catch (e) {
|
|
33748
|
+
const out = e.stdout;
|
|
33749
|
+
if (typeof out === "string")
|
|
33750
|
+
diff = out;
|
|
33751
|
+
}
|
|
33752
|
+
}
|
|
33588
33753
|
const truncated = diff.length > DIFF_CAP;
|
|
33589
33754
|
return { workspace: workspace3, files, diff: truncated ? diff.slice(0, DIFF_CAP) : diff, truncated, ...await this.gitContext(root) };
|
|
33590
33755
|
}
|
|
@@ -33827,6 +33992,11 @@ class ControlService {
|
|
|
33827
33992
|
resolveSettled = resolve4;
|
|
33828
33993
|
});
|
|
33829
33994
|
this.inFlight.set(key, { controller, settled });
|
|
33995
|
+
let wasArchived = false;
|
|
33996
|
+
try {
|
|
33997
|
+
const internalAlias = await this.deps.sessions.resolveAliasForChat(params.chatKey, params.sessionAlias);
|
|
33998
|
+
wasArchived = (await this.deps.sessions.getSession(internalAlias))?.archived === true;
|
|
33999
|
+
} catch {}
|
|
33830
34000
|
try {
|
|
33831
34001
|
await this.deps.sessions.useSession(params.chatKey, params.sessionAlias);
|
|
33832
34002
|
} catch (error2) {
|
|
@@ -33834,6 +34004,9 @@ class ControlService {
|
|
|
33834
34004
|
resolveSettled();
|
|
33835
34005
|
return { ok: false, errorMessage: toErrorMessage(error2) };
|
|
33836
34006
|
}
|
|
34007
|
+
if (wasArchived) {
|
|
34008
|
+
this.deps.events.emit({ type: "sessions-changed" });
|
|
34009
|
+
}
|
|
33837
34010
|
this.deps.events.emit({
|
|
33838
34011
|
type: "turn-started",
|
|
33839
34012
|
chatKey: params.chatKey,
|
|
@@ -34028,10 +34201,10 @@ var init_control_service = __esm(() => {
|
|
|
34028
34201
|
|
|
34029
34202
|
// src/control/upload-store.ts
|
|
34030
34203
|
import { mkdtemp as mkdtemp2, readdir as readdir5, rm as rm10, stat as stat4, writeFile as writeFile8 } from "node:fs/promises";
|
|
34031
|
-
import { homedir as
|
|
34204
|
+
import { homedir as homedir13 } from "node:os";
|
|
34032
34205
|
import path16 from "node:path";
|
|
34033
34206
|
function defaultRootDir() {
|
|
34034
|
-
const home = process.env.HOME ??
|
|
34207
|
+
const home = process.env.HOME ?? homedir13();
|
|
34035
34208
|
return path16.join(coreHomeDir(home), "runtime", "uploads");
|
|
34036
34209
|
}
|
|
34037
34210
|
function sanitizeUploadFilename(raw) {
|
|
@@ -34107,7 +34280,7 @@ var init_upload_store = __esm(() => {
|
|
|
34107
34280
|
|
|
34108
34281
|
// src/config/agent-catalog.ts
|
|
34109
34282
|
import { existsSync as existsSync3 } from "node:fs";
|
|
34110
|
-
import { delimiter as delimiter2, join as
|
|
34283
|
+
import { delimiter as delimiter2, join as join22 } from "node:path";
|
|
34111
34284
|
function isBinaryOnPath(binary) {
|
|
34112
34285
|
const path17 = process.env.PATH ?? "";
|
|
34113
34286
|
const exts = process.platform === "win32" ? ["", ".exe", ".cmd", ".bat"] : [""];
|
|
@@ -34116,7 +34289,7 @@ function isBinaryOnPath(binary) {
|
|
|
34116
34289
|
continue;
|
|
34117
34290
|
for (const ext of exts) {
|
|
34118
34291
|
try {
|
|
34119
|
-
if (existsSync3(
|
|
34292
|
+
if (existsSync3(join22(dir, binary + ext)))
|
|
34120
34293
|
return true;
|
|
34121
34294
|
} catch {}
|
|
34122
34295
|
}
|
|
@@ -34207,8 +34380,8 @@ __export(exports_main, {
|
|
|
34207
34380
|
buildApp: () => buildApp
|
|
34208
34381
|
});
|
|
34209
34382
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
34210
|
-
import { homedir as
|
|
34211
|
-
import { dirname as dirname13, join as
|
|
34383
|
+
import { homedir as homedir14 } from "node:os";
|
|
34384
|
+
import { dirname as dirname13, join as join23 } from "node:path";
|
|
34212
34385
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
34213
34386
|
function startProgressHeartbeat(orchestration3, config4, logger2, channel) {
|
|
34214
34387
|
const thresholdSeconds = config4.orchestration.progressHeartbeatSeconds;
|
|
@@ -34899,8 +35072,8 @@ async function main() {
|
|
|
34899
35072
|
}
|
|
34900
35073
|
}
|
|
34901
35074
|
async function prepareChannelMedia(configPath, config4) {
|
|
34902
|
-
const runtimeDir =
|
|
34903
|
-
const mediaRootDir =
|
|
35075
|
+
const runtimeDir = join23(dirname13(configPath), "runtime");
|
|
35076
|
+
const mediaRootDir = join23(runtimeDir, "media");
|
|
34904
35077
|
const mediaStore = new RuntimeMediaStore({ rootDir: mediaRootDir });
|
|
34905
35078
|
await mediaStore.cleanupExpired().catch((error2) => {
|
|
34906
35079
|
console.error("[xacpx] media cleanup failed:", error2 instanceof Error ? error2.message : String(error2));
|
|
@@ -34909,16 +35082,16 @@ async function prepareChannelMedia(configPath, config4) {
|
|
|
34909
35082
|
return { mediaStore, channelDeps: { mediaStore, allowedMediaRoots } };
|
|
34910
35083
|
}
|
|
34911
35084
|
function resolveRuntimePaths() {
|
|
34912
|
-
const home = process.env.HOME ??
|
|
35085
|
+
const home = process.env.HOME ?? homedir14();
|
|
34913
35086
|
if (!home) {
|
|
34914
35087
|
throw new Error("Unable to resolve the current user home directory");
|
|
34915
35088
|
}
|
|
34916
|
-
const configPath = coreEnv("CONFIG") ??
|
|
34917
|
-
const runtimeDir =
|
|
35089
|
+
const configPath = coreEnv("CONFIG") ?? join23(coreHomeDir(home), "config.json");
|
|
35090
|
+
const runtimeDir = join23(dirname13(configPath), "runtime");
|
|
34918
35091
|
return {
|
|
34919
35092
|
configPath,
|
|
34920
|
-
statePath: coreEnv("STATE") ??
|
|
34921
|
-
perfLogPath:
|
|
35093
|
+
statePath: coreEnv("STATE") ?? join23(coreHomeDir(home), "state.json"),
|
|
35094
|
+
perfLogPath: join23(runtimeDir, "perf.log"),
|
|
34922
35095
|
orchestrationSocketPath: coreEnv("ORCHESTRATION_SOCKET") ?? resolveDaemonOrchestrationSocketPath(runtimeDir)
|
|
34923
35096
|
};
|
|
34924
35097
|
}
|
|
@@ -34930,13 +35103,13 @@ function resolveBridgeEntryPath() {
|
|
|
34930
35103
|
}
|
|
34931
35104
|
function resolveAppLogPath(configPath) {
|
|
34932
35105
|
const rootDir = dirname13(configPath);
|
|
34933
|
-
const runtimeDir =
|
|
34934
|
-
return
|
|
35106
|
+
const runtimeDir = join23(rootDir, "runtime");
|
|
35107
|
+
return join23(runtimeDir, "app.log");
|
|
34935
35108
|
}
|
|
34936
35109
|
function resolvePerfLogPath(configPath) {
|
|
34937
35110
|
const rootDir = dirname13(configPath);
|
|
34938
|
-
const runtimeDir =
|
|
34939
|
-
return
|
|
35111
|
+
const runtimeDir = join23(rootDir, "runtime");
|
|
35112
|
+
return join23(runtimeDir, "perf.log");
|
|
34940
35113
|
}
|
|
34941
35114
|
function resolveOrchestrationSocketPathFromConfigPath(configPath) {
|
|
34942
35115
|
const runtimeDir = resolveRuntimeDirFromConfigPath(configPath);
|
|
@@ -35178,10 +35351,10 @@ var init_config_check = __esm(async () => {
|
|
|
35178
35351
|
// src/doctor/checks/daemon-check.ts
|
|
35179
35352
|
import { readdir as readdir6, readFile as readFile15, rm as rm11 } from "node:fs/promises";
|
|
35180
35353
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
35181
|
-
import { homedir as
|
|
35182
|
-
import { join as
|
|
35354
|
+
import { homedir as homedir15 } from "node:os";
|
|
35355
|
+
import { join as join24 } from "node:path";
|
|
35183
35356
|
async function checkDaemon(options = {}) {
|
|
35184
|
-
const home = options.home ?? process.env.HOME ??
|
|
35357
|
+
const home = options.home ?? process.env.HOME ?? homedir15();
|
|
35185
35358
|
const runtimeDir = options.configPath ? resolveRuntimeDirFromConfigPath(options.configPath) : undefined;
|
|
35186
35359
|
const paths = (options.resolveDaemonPaths ?? resolveDaemonPaths)({
|
|
35187
35360
|
home,
|
|
@@ -35281,7 +35454,7 @@ async function detectStaleConsumerLockFix(runtimeDir, deps) {
|
|
|
35281
35454
|
if (!fileName.endsWith(CONSUMER_LOCK_SUFFIX)) {
|
|
35282
35455
|
continue;
|
|
35283
35456
|
}
|
|
35284
|
-
const lockPath =
|
|
35457
|
+
const lockPath = join24(runtimeDir, fileName);
|
|
35285
35458
|
const lock2 = await deps.readConsumerLock(lockPath);
|
|
35286
35459
|
if (lock2 && !deps.isProcessRunning(lock2.pid)) {
|
|
35287
35460
|
stalePaths.push(lockPath);
|
|
@@ -35346,10 +35519,10 @@ var init_daemon_check = __esm(() => {
|
|
|
35346
35519
|
|
|
35347
35520
|
// src/doctor/checks/logs-check.ts
|
|
35348
35521
|
import { stat as stat5, readdir as readdir7 } from "node:fs/promises";
|
|
35349
|
-
import { basename as basename4, join as
|
|
35350
|
-
import { homedir as
|
|
35522
|
+
import { basename as basename4, join as join25 } from "node:path";
|
|
35523
|
+
import { homedir as homedir16 } from "node:os";
|
|
35351
35524
|
async function checkLogs(options = {}) {
|
|
35352
|
-
const home = options.home ?? process.env.HOME ??
|
|
35525
|
+
const home = options.home ?? process.env.HOME ?? homedir16();
|
|
35353
35526
|
const runtimeDir = options.configPath ? resolveRuntimeDirFromConfigPath(options.configPath) : undefined;
|
|
35354
35527
|
const paths = (options.resolveDaemonPaths ?? resolveDaemonPaths)({
|
|
35355
35528
|
home,
|
|
@@ -35381,7 +35554,7 @@ async function checkLogs(options = {}) {
|
|
|
35381
35554
|
const matched = entries.filter((entry) => isTrackedLogName(entry, tracked));
|
|
35382
35555
|
const files = [];
|
|
35383
35556
|
for (const name of matched) {
|
|
35384
|
-
const path17 =
|
|
35557
|
+
const path17 = join25(paths.runtimeDir, name);
|
|
35385
35558
|
try {
|
|
35386
35559
|
const fileStat = await probe.stat(path17);
|
|
35387
35560
|
if (fileStat.isDirectory()) {
|
|
@@ -35531,9 +35704,9 @@ var init_orchestration_health = __esm(() => {
|
|
|
35531
35704
|
});
|
|
35532
35705
|
|
|
35533
35706
|
// src/doctor/checks/orchestration-socket-check.ts
|
|
35534
|
-
import { homedir as
|
|
35707
|
+
import { homedir as homedir17 } from "node:os";
|
|
35535
35708
|
async function checkOrchestrationSocket(options = {}) {
|
|
35536
|
-
const home = options.home ?? process.env.HOME ??
|
|
35709
|
+
const home = options.home ?? process.env.HOME ?? homedir17();
|
|
35537
35710
|
const runtimeDir = options.configPath ? resolveRuntimeDirFromConfigPath(options.configPath) : undefined;
|
|
35538
35711
|
const paths = (options.resolveDaemonPaths ?? resolveDaemonPaths)({
|
|
35539
35712
|
home,
|
|
@@ -35708,9 +35881,9 @@ var init_plugin_check = __esm(async () => {
|
|
|
35708
35881
|
import { constants } from "node:fs";
|
|
35709
35882
|
import { access as access4, stat as stat6 } from "node:fs/promises";
|
|
35710
35883
|
import { dirname as dirname14 } from "node:path";
|
|
35711
|
-
import { homedir as
|
|
35884
|
+
import { homedir as homedir18 } from "node:os";
|
|
35712
35885
|
async function checkRuntime(options = {}) {
|
|
35713
|
-
const home = options.home ?? process.env.HOME ??
|
|
35886
|
+
const home = options.home ?? process.env.HOME ?? homedir18();
|
|
35714
35887
|
const runtimeDir = options.configPath ? resolveRuntimeDirFromConfigPath(options.configPath) : undefined;
|
|
35715
35888
|
const paths = (options.resolveDaemonPaths ?? resolveDaemonPaths)({
|
|
35716
35889
|
home,
|
|
@@ -36343,10 +36516,10 @@ var init_render_doctor = __esm(() => {
|
|
|
36343
36516
|
});
|
|
36344
36517
|
|
|
36345
36518
|
// src/doctor/doctor.ts
|
|
36346
|
-
import { homedir as
|
|
36347
|
-
import { join as
|
|
36519
|
+
import { homedir as homedir19 } from "node:os";
|
|
36520
|
+
import { join as join26 } from "node:path";
|
|
36348
36521
|
async function runDoctor(options = {}, deps = {}) {
|
|
36349
|
-
const home = deps.home ?? process.env.HOME ??
|
|
36522
|
+
const home = deps.home ?? process.env.HOME ?? homedir19();
|
|
36350
36523
|
const runtimePaths = resolveDoctorRuntimePaths(home, deps.resolveRuntimePaths);
|
|
36351
36524
|
const sharedLoadConfig = createSharedLoadConfig(runtimePaths, deps.loadConfig ?? loadConfig);
|
|
36352
36525
|
const runners = [
|
|
@@ -36499,8 +36672,8 @@ function resolveDoctorRuntimePaths(home, resolver) {
|
|
|
36499
36672
|
return resolveRuntimePaths();
|
|
36500
36673
|
}
|
|
36501
36674
|
return {
|
|
36502
|
-
configPath:
|
|
36503
|
-
statePath:
|
|
36675
|
+
configPath: join26(coreHomeDir(home), "config.json"),
|
|
36676
|
+
statePath: join26(coreHomeDir(home), "state.json")
|
|
36504
36677
|
};
|
|
36505
36678
|
}
|
|
36506
36679
|
function depsUseExplicitRuntimeOverrides() {
|
|
@@ -36683,8 +36856,8 @@ var init_doctor2 = __esm(async () => {
|
|
|
36683
36856
|
// src/cli.ts
|
|
36684
36857
|
init_core_home();
|
|
36685
36858
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
36686
|
-
import { homedir as
|
|
36687
|
-
import { dirname as dirname15, join as
|
|
36859
|
+
import { homedir as homedir20 } from "node:os";
|
|
36860
|
+
import { dirname as dirname15, join as join27, sep as sep2 } from "node:path";
|
|
36688
36861
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
36689
36862
|
|
|
36690
36863
|
// src/runtime/migrate-core-home.ts
|
|
@@ -52938,7 +53111,7 @@ async function createCliScheduledTaskService() {
|
|
|
52938
53111
|
return new ScheduledTaskService(state, stateStore);
|
|
52939
53112
|
}
|
|
52940
53113
|
function resolveConfigPathForCurrentEnv() {
|
|
52941
|
-
return coreEnv("CONFIG") ??
|
|
53114
|
+
return coreEnv("CONFIG") ?? join27(coreHomeDir(requireHome2()), "config.json");
|
|
52942
53115
|
}
|
|
52943
53116
|
function resolveDaemonPathsForCurrentConfig() {
|
|
52944
53117
|
const configPath = resolveConfigPathForCurrentEnv();
|
|
@@ -53289,7 +53462,7 @@ function decodeFirstRunOnboarding(raw) {
|
|
|
53289
53462
|
return null;
|
|
53290
53463
|
}
|
|
53291
53464
|
function requireHome2() {
|
|
53292
|
-
const home = process.env.HOME ??
|
|
53465
|
+
const home = process.env.HOME ?? homedir20();
|
|
53293
53466
|
if (!home) {
|
|
53294
53467
|
throw new Error("Unable to resolve the current user home directory");
|
|
53295
53468
|
}
|
|
@@ -53313,7 +53486,7 @@ function safeDaemonLogPaths() {
|
|
|
53313
53486
|
const configPath = resolveConfigPathForCurrentEnv();
|
|
53314
53487
|
const paths = resolveDaemonPathsForCurrentConfig();
|
|
53315
53488
|
return {
|
|
53316
|
-
appLog:
|
|
53489
|
+
appLog: join27(dirname15(configPath), "runtime", "app.log"),
|
|
53317
53490
|
stderrLog: paths.stderrLog
|
|
53318
53491
|
};
|
|
53319
53492
|
} catch {
|
|
@@ -102,6 +102,8 @@ export interface AgentSession {
|
|
|
102
102
|
export interface AgentSessionListQuery {
|
|
103
103
|
agent: string;
|
|
104
104
|
agentCommand?: string;
|
|
105
|
+
/** Resolved acpx driver for `agent` (e.g. a custom `my-codex` agent has driver `codex`). Used to gate driver-specific list filtering. */
|
|
106
|
+
driver?: string;
|
|
105
107
|
cwd: string;
|
|
106
108
|
cursor?: string;
|
|
107
109
|
filterCwd?: string;
|