diff --git a/cli/src/commands/client/agent.ts b/cli/src/commands/client/agent.ts index c98ca158..36eb04e6 100644 --- a/cli/src/commands/client/agent.ts +++ b/cli/src/commands/client/agent.ts @@ -197,10 +197,16 @@ export function registerAgentCommands(program: Command): void { const agentRow = await ctx.api.get( `/api/agents/${encodeURIComponent(agentRef)}?${query.toString()}`, ); + if (!agentRow) { + throw new Error(`Agent not found: ${agentRef}`); + } const now = new Date().toISOString().replaceAll(":", "-"); const keyName = opts.keyName?.trim() ? opts.keyName.trim() : `local-cli-${now}`; const key = await ctx.api.post(`/api/agents/${agentRow.id}/keys`, { name: keyName }); + if (!key) { + throw new Error("Failed to create API key"); + } const installSummaries: SkillsInstallSummary[] = []; if (opts.installSkills !== false) { diff --git a/packages/adapters/cursor-local/package.json b/packages/adapters/cursor-local/package.json index 575f9e1b..4ef66052 100644 --- a/packages/adapters/cursor-local/package.json +++ b/packages/adapters/cursor-local/package.json @@ -45,6 +45,7 @@ "picocolors": "^1.1.1" }, "devDependencies": { + "@types/node": "^24.6.0", "typescript": "^5.7.3" } } diff --git a/packages/adapters/cursor-local/tsconfig.json b/packages/adapters/cursor-local/tsconfig.json index 2f355cfe..90314411 100644 --- a/packages/adapters/cursor-local/tsconfig.json +++ b/packages/adapters/cursor-local/tsconfig.json @@ -2,7 +2,8 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "dist", - "rootDir": "src" + "rootDir": "src", + "types": ["node"] }, "include": ["src"] } diff --git a/packages/adapters/openclaw-gateway/README.md b/packages/adapters/openclaw-gateway/README.md index cadc8198..ba3edde2 100644 --- a/packages/adapters/openclaw-gateway/README.md +++ b/packages/adapters/openclaw-gateway/README.md @@ -38,7 +38,7 @@ By default the adapter sends a signed `device` payload in `connect` params. The adapter supports the same session routing model as HTTP OpenClaw mode: -- `sessionKeyStrategy=fixed|issue|run` +- `sessionKeyStrategy=issue|fixed|run` - `sessionKey` is used when strategy is `fixed` Resolved session key is sent as `agent.sessionKey`. diff --git a/packages/adapters/openclaw-gateway/doc/ONBOARDING_AND_TEST_PLAN.md b/packages/adapters/openclaw-gateway/doc/ONBOARDING_AND_TEST_PLAN.md index f8cacedb..61c9b331 100644 --- a/packages/adapters/openclaw-gateway/doc/ONBOARDING_AND_TEST_PLAN.md +++ b/packages/adapters/openclaw-gateway/doc/ONBOARDING_AND_TEST_PLAN.md @@ -250,8 +250,7 @@ POST /api/companies/$CLA_COMPANY_ID/invites "headers": { "x-openclaw-token": "" }, "role": "operator", "scopes": ["operator.admin"], - "sessionKeyStrategy": "fixed", - "sessionKey": "paperclip", + "sessionKeyStrategy": "issue", "waitTimeoutMs": 120000 } } diff --git a/packages/adapters/openclaw-gateway/src/index.ts b/packages/adapters/openclaw-gateway/src/index.ts index 34f7201d..e15ca45c 100644 --- a/packages/adapters/openclaw-gateway/src/index.ts +++ b/packages/adapters/openclaw-gateway/src/index.ts @@ -37,6 +37,6 @@ Request behavior fields: - paperclipApiUrl (string, optional): absolute Paperclip base URL advertised in wake text Session routing fields: -- sessionKeyStrategy (string, optional): fixed (default), issue, or run +- sessionKeyStrategy (string, optional): issue (default), fixed, or run - sessionKey (string, optional): fixed session key when strategy=fixed (default paperclip) `; diff --git a/packages/adapters/openclaw-gateway/src/server/execute.ts b/packages/adapters/openclaw-gateway/src/server/execute.ts index b92dccfa..c8de510d 100644 --- a/packages/adapters/openclaw-gateway/src/server/execute.ts +++ b/packages/adapters/openclaw-gateway/src/server/execute.ts @@ -117,9 +117,9 @@ function parseBoolean(value: unknown, fallback = false): boolean { } function normalizeSessionKeyStrategy(value: unknown): SessionKeyStrategy { - const normalized = asString(value, "fixed").trim().toLowerCase(); - if (normalized === "issue" || normalized === "run") return normalized; - return "fixed"; + const normalized = asString(value, "issue").trim().toLowerCase(); + if (normalized === "fixed" || normalized === "run") return normalized; + return "issue"; } function resolveSessionKey(input: { diff --git a/packages/adapters/openclaw-gateway/src/ui/build-config.ts b/packages/adapters/openclaw-gateway/src/ui/build-config.ts index fcbbbf4e..6a749f84 100644 --- a/packages/adapters/openclaw-gateway/src/ui/build-config.ts +++ b/packages/adapters/openclaw-gateway/src/ui/build-config.ts @@ -5,8 +5,7 @@ export function buildOpenClawGatewayConfig(v: CreateConfigValues): Record { const body = JSON.parse(String(fetchMock.mock.calls[0]?.[1]?.body ?? "{}")) as Record; expect(body.foo).toBe("bar"); expect(body.stream).toBe(true); - expect(body.sessionKey).toBe("paperclip"); + expect(body.sessionKey).toBe("paperclip:issue:issue-123"); expect((body.paperclip as Record).streamTransport).toBe("sse"); expect((body.paperclip as Record).runId).toBe("run-123"); - expect((body.paperclip as Record).sessionKey).toBe("paperclip"); + expect((body.paperclip as Record).sessionKey).toBe("paperclip:issue:issue-123"); expect( ((body.paperclip as Record).env as Record).PAPERCLIP_RUN_ID, ).toBe("run-123"); @@ -414,7 +414,7 @@ describe("openclaw adapter execute", () => { expect(body.sessionKey).toBeUndefined(); const headers = (fetchMock.mock.calls[0]?.[1]?.headers ?? {}) as Record; - expect(headers["x-openclaw-session-key"]).toBe("paperclip"); + expect(headers["x-openclaw-session-key"]).toBe("paperclip:issue:issue-123"); }); it("does not treat response.output_text.done as a terminal OpenResponses event", async () => { @@ -584,7 +584,7 @@ describe("openclaw adapter execute", () => { const body = JSON.parse(String(fetchMock.mock.calls[0]?.[1]?.body ?? "{}")) as Record; expect(body.foo).toBe("bar"); expect(body.stream).toBe(false); - expect(body.sessionKey).toBe("paperclip"); + expect(body.sessionKey).toBe("paperclip:issue:issue-123"); expect(String(body.text ?? "")).toContain("PAPERCLIP_RUN_ID=run-123"); expect((body.paperclip as Record).streamTransport).toBe("webhook"); }); @@ -668,7 +668,7 @@ describe("openclaw adapter execute", () => { expect(String(secondBody.input ?? "")).toContain("PAPERCLIP_RUN_ID=run-123"); const secondHeaders = (fetchMock.mock.calls[1]?.[1]?.headers ?? {}) as Record; - expect(secondHeaders["x-openclaw-session-key"]).toBe("paperclip"); + expect(secondHeaders["x-openclaw-session-key"]).toBe("paperclip:issue:issue-123"); expect(result.resultJson).toEqual( expect.objectContaining({ usedLegacyResponsesFallback: true, @@ -766,7 +766,7 @@ describe("openclaw adapter execute", () => { expect(result.exitCode).toBe(0); expect(fetchMock).toHaveBeenCalledTimes(1); const body = JSON.parse(String(fetchMock.mock.calls[0]?.[1]?.body ?? "{}")) as Record; - expect(body.sessionKey).toBe("paperclip"); + expect(body.sessionKey).toBe("paperclip:issue:issue-123"); }); it("retries webhook payloads with wake compatibility format on text-required errors", async () => { diff --git a/server/src/__tests__/openclaw-gateway-adapter.test.ts b/server/src/__tests__/openclaw-gateway-adapter.test.ts index 3a4ac10e..364f5a97 100644 --- a/server/src/__tests__/openclaw-gateway-adapter.test.ts +++ b/server/src/__tests__/openclaw-gateway-adapter.test.ts @@ -424,7 +424,7 @@ describe("openclaw gateway adapter execute", () => { const payload = gateway.getAgentPayload(); expect(payload).toBeTruthy(); expect(payload?.idempotencyKey).toBe("run-123"); - expect(payload?.sessionKey).toBe("paperclip"); + expect(payload?.sessionKey).toBe("paperclip:issue:issue-123"); expect(String(payload?.message ?? "")).toContain("wake now"); expect(String(payload?.message ?? "")).toContain("PAPERCLIP_RUN_ID=run-123"); expect(String(payload?.message ?? "")).toContain("PAPERCLIP_TASK_ID=task-123"); diff --git a/server/src/routes/access.ts b/server/src/routes/access.ts index 3e2ba527..9eaacf71 100644 --- a/server/src/routes/access.ts +++ b/server/src/routes/access.ts @@ -1484,8 +1484,7 @@ export function buildInviteOnboardingTextDocument( paperclipApiUrl: "http://host.docker.internal:3100", headers: { "x-openclaw-token": token }, waitTimeoutMs: 120000, - sessionKeyStrategy: "fixed", - sessionKey: "paperclip", + sessionKeyStrategy: "issue", role: "operator", scopes: ["operator.admin"] } @@ -1518,8 +1517,7 @@ export function buildInviteOnboardingTextDocument( "paperclipApiUrl": "https://paperclip-hostname-your-agent-can-reach:3100", "headers": { "x-openclaw-token": "replace-me" }, "waitTimeoutMs": 120000, - "sessionKeyStrategy": "fixed", - "sessionKey": "paperclip", + "sessionKeyStrategy": "issue", "role": "operator", "scopes": ["operator.admin"] }