























@@ -1,4 +1,3 @@
1-import fsSync from "node:fs";
21import fs from "node:fs/promises";
32import path from "node:path";
43import { expect, test, vi } from "vitest";
@@ -456,65 +455,100 @@ test("lists and patches session store via sessions.* RPC", async () => {
456455);
457456});
458457459-test("sessions.list configuredAgentsOnly hides disk-discovered unregistered agent stores", async () => {
458+test("sessions.list configuredAgentsOnly keeps configured-agent children and hides unrelated stores", async () => {
460459const stateDir = process.env.OPENCLAW_STATE_DIR;
461460if (!stateDir) {
462461throw new Error("OPENCLAW_STATE_DIR is required for gateway session tests");
463462}
464463testState.agentsConfig = { list: [{ id: "main", default: true }] };
464+const configPath = process.env.OPENCLAW_CONFIG_PATH;
465+if (!configPath) {
466+throw new Error("OPENCLAW_CONFIG_PATH is required for gateway session tests");
467+}
468+await fs.writeFile(
469+configPath,
470+JSON.stringify({ acp: { defaultAgent: "claude", allowedAgents: ["gemini"] } }, null, 2),
471+"utf-8",
472+);
465473testState.sessionConfig = {
466474store: path.join(stateDir, "agents", "{agentId}", "sessions", "sessions.json"),
467475};
468476469477const mainStorePath = path.join(stateDir, "agents", "main", "sessions", "sessions.json");
478+const acpStorePath = path.join(stateDir, "agents", "claude", "sessions", "sessions.json");
479+const childStorePath = path.join(stateDir, "agents", "codex", "sessions", "sessions.json");
470480const diskOnlyStorePath = path.join(stateDir, "agents", "local", "sessions", "sessions.json");
471481await fs.mkdir(path.dirname(mainStorePath), { recursive: true });
482+await fs.mkdir(path.dirname(acpStorePath), { recursive: true });
483+await fs.mkdir(path.dirname(childStorePath), { recursive: true });
472484await fs.mkdir(path.dirname(diskOnlyStorePath), { recursive: true });
473485await fs.writeFile(
474486mainStorePath,
475487JSON.stringify({ main: { sessionId: "sess-main", updatedAt: 20 } }, null, 2),
476488"utf-8",
477489);
490+await fs.writeFile(
491+acpStorePath,
492+JSON.stringify(
493+{
494+"agent:claude:acp:25f77580-de30-4d80-9bc3-7cbc6374bce7": {
495+sessionId: "sess-claude-acp",
496+updatedAt: 30,
497+acp: {
498+backend: "acpx",
499+agent: "claude",
500+runtimeSessionName: "agent:claude:acp:25f77580-de30-4d80-9bc3-7cbc6374bce7",
501+mode: "oneshot",
502+state: "idle",
503+lastActivityAt: 30,
504+},
505+},
506+},
507+null,
508+2,
509+),
510+"utf-8",
511+);
512+await fs.writeFile(
513+childStorePath,
514+JSON.stringify(
515+{
516+"agent:codex:subagent:app-server-child": {
517+sessionId: "sess-codex-child",
518+updatedAt: 25,
519+spawnedBy: "agent:main:main",
520+},
521+},
522+null,
523+2,
524+),
525+"utf-8",
526+);
478527await fs.writeFile(
479528diskOnlyStorePath,
480529JSON.stringify({ main: { sessionId: "sess-local", updatedAt: 10 } }, null, 2),
481530"utf-8",
482531);
483532484-const readFileSyncSpy = vi.spyOn(fsSync, "readFileSync");
485-const realDiskOnlyStorePath = await fs.realpath(diskOnlyStorePath);
486-487-try {
488-const configuredOnly = await directSessionHandlerReq<{ sessions: Array<{ key: string }> }>(
489-"sessions.list",
490-{ includeGlobal: false, includeUnknown: false, configuredAgentsOnly: true },
491-);
492-expect(configuredOnly.ok).toBe(true);
493-expect(configuredOnly.payload?.sessions.map((session) => session.key)).toEqual([
494-"agent:main:main",
495-]);
496-expect(
497-readFileSyncSpy.mock.calls.some(([file]) => {
498-if (typeof file !== "string") {
499-return false;
500-}
501-try {
502-return fsSync.realpathSync.native(file) === realDiskOnlyStorePath;
503-} catch {
504-return false;
505-}
506-}),
507-).toBe(false);
508-} finally {
509-readFileSyncSpy.mockRestore();
510-}
533+const configuredOnly = await directSessionHandlerReq<{ sessions: Array<{ key: string }> }>(
534+"sessions.list",
535+{ includeGlobal: false, includeUnknown: false, configuredAgentsOnly: true },
536+);
537+expect(configuredOnly.ok).toBe(true);
538+expect(configuredOnly.payload?.sessions.map((session) => session.key)).toEqual([
539+"agent:claude:acp:25f77580-de30-4d80-9bc3-7cbc6374bce7",
540+"agent:codex:subagent:app-server-child",
541+"agent:main:main",
542+]);
511543512544const broad = await directSessionHandlerReq<{ sessions: Array<{ key: string }> }>(
513545"sessions.list",
514546{ includeGlobal: false, includeUnknown: false },
515547);
516548expect(broad.ok).toBe(true);
517549expect(broad.payload?.sessions.map((session) => session.key)).toEqual([
550+"agent:claude:acp:25f77580-de30-4d80-9bc3-7cbc6374bce7",
551+"agent:codex:subagent:app-server-child",
518552"agent:main:main",
519553"agent:local:main",
520554]);
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。