fix: surface upstream gateway timeout for remote OpenClaw/Tailscale connections (#94)

* surface gateway timeout for tailscale

* talescale fix #2 - attempt 1

* luke findings fix#1

* add narrow log for clientId

* prod safe proxy log

* fix log visibility

* LAN connection & subagent SOUL|IDENTITY fixes

* Initialize missing files for subagent SOUL|IDENTITY

* surface missing files in UI

* capturing agent - runtime,identity,session

* plugin-install fix

* fix: recover agent workspace for marketplace installs

* fix: recover agent workspace and identity name from file provenance

* fix: tolerate webchat session patch blocks during permission updates
This commit is contained in:
gsknnft
2026-04-03 18:57:36 -04:00
committed by GitHub
parent 4be98d7080
commit a18c8c630c
28 changed files with 1174 additions and 76 deletions
+67
View File
@@ -20,6 +20,73 @@ describe("skills gateway client", () => {
expect(result).toBe(report);
});
it("repairs root workspace reports using agent file provenance", async () => {
const client = {
call: vi.fn(async (method: string, params?: Record<string, unknown>) => {
if (method === "skills.status") {
return {
workspaceDir: "/home/pi/.openclaw/workspace",
managedSkillsDir: "/home/pi/.openclaw/skills",
skills: [],
};
}
if (method === "agents.files.get") {
expect(params).toEqual({
agentId: "main",
name: "IDENTITY.md",
});
return {
workspace: "/home/pi/.openclaw/workspace-main",
file: {
missing: false,
content: "# IDENTITY",
path: "/home/pi/.openclaw/workspace-main/IDENTITY.md",
},
};
}
throw new Error(`Unexpected method: ${method}`);
}),
} as unknown as GatewayClient;
const result = await loadAgentSkillStatus(client, "main");
expect(result.workspaceDir).toBe("/home/pi/.openclaw/workspace-main");
expect(client.call).toHaveBeenNthCalledWith(1, "skills.status", { agentId: "main" });
expect(client.call).toHaveBeenNthCalledWith(2, "agents.files.get", {
agentId: "main",
name: "IDENTITY.md",
});
});
it("derives workspace from file path when agents.files.get reports the root workspace", async () => {
const client = {
call: vi.fn(async (method: string) => {
if (method === "skills.status") {
return {
workspaceDir: "/home/pi/.openclaw/workspace",
managedSkillsDir: "/home/pi/.openclaw/skills",
skills: [],
};
}
if (method === "agents.files.get") {
return {
workspace: "/home/pi/.openclaw/workspace",
file: {
missing: false,
content: "# IDENTITY",
path: "/home/pi/.openclaw/workspace-main/IDENTITY.md",
},
};
}
throw new Error(`Unexpected method: ${method}`);
}),
} as unknown as GatewayClient;
const result = await loadAgentSkillStatus(client, "main");
expect(result.workspaceDir).toBe("/home/pi/.openclaw/workspace-main");
});
it("fails fast when agent id is empty", async () => {
const client = {
call: vi.fn(),