diff --git a/.changeset/fix-import-jwt-share-url.md b/.changeset/fix-import-jwt-share-url.md new file mode 100644 index 00000000000..4f99030d17b --- /dev/null +++ b/.changeset/fix-import-jwt-share-url.md @@ -0,0 +1,6 @@ +--- +"@kilocode/cli": patch +"kilo-code": patch +--- + +Accept JWT share tokens when importing a session from a Kilo share URL. diff --git a/packages/opencode/src/cli/cmd/import.ts b/packages/opencode/src/cli/cmd/import.ts index 68bad6b3e2a..863deafbd8a 100644 --- a/packages/opencode/src/cli/cmd/import.ts +++ b/packages/opencode/src/cli/cmd/import.ts @@ -26,9 +26,9 @@ export type ShareData = | { type: "model"; data: unknown } // kilocode_change start -/** Extract share ID from a Kilo share URL like https://app.kilo.ai/s/abc123 */ +/** Extract share token from a Kilo share URL like https://app.kilo.ai/s/ */ export function parseShareUrl(url: string): string | null { - const match = url.match(/^https?:\/\/app\.kilo\.ai\/s\/([a-zA-Z0-9_-]+)$/) + const match = url.match(/^https?:\/\/app\.kilo\.ai\/s\/([A-Za-z0-9_.-]+)$/) return match ? match[1] : null } // kilocode_change end diff --git a/packages/opencode/src/kilo-sessions/kilo-sessions.ts b/packages/opencode/src/kilo-sessions/kilo-sessions.ts index d43ee120d8a..571c8ead89c 100644 --- a/packages/opencode/src/kilo-sessions/kilo-sessions.ts +++ b/packages/opencode/src/kilo-sessions/kilo-sessions.ts @@ -1068,12 +1068,12 @@ export namespace KiloSessions { throw new Error(`Unable to share session ${sessionId}: ${response.status} ${response.statusText}`) } - const result = (await response.json()) as { public_id?: string } - if (!result.public_id) { - throw new Error(`Unable to share session ${sessionId}: server did not return a public id`) + const result = (await response.json()) as { share_token?: string } + if (!result.share_token) { + throw new Error(`Unable to share session ${sessionId}: server did not return a share token`) } - const url = `https://app.kilo.ai/s/${result.public_id}` + const url = `https://app.kilo.ai/s/${result.share_token}` await save(sessionId, { ...current, diff --git a/packages/opencode/test/cli/import.test.ts b/packages/opencode/test/cli/import.test.ts index 4f1ba41671f..b06a22e775c 100644 --- a/packages/opencode/test/cli/import.test.ts +++ b/packages/opencode/test/cli/import.test.ts @@ -51,6 +51,13 @@ test("parses valid Kilo share URLs", () => { ) expect(parseShareUrl("https://app.kilo.ai/s/Jsj3hNIW")).toBe("Jsj3hNIW") expect(parseShareUrl("https://app.kilo.ai/s/test_id-123")).toBe("test_id-123") + // kilocode_change start + expect( + parseShareUrl( + "https://app.kilo.ai/s/eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJzZXNfMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMiJ9.signature", + ), + ).toBe("eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJzZXNfMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMiJ9.signature") + // kilocode_change end }) test("rejects invalid URLs", () => { diff --git a/packages/opencode/test/kilocode/session-share.test.ts b/packages/opencode/test/kilocode/session-share.test.ts index 3ed665b9ff4..171195752ce 100644 --- a/packages/opencode/test/kilocode/session-share.test.ts +++ b/packages/opencode/test/kilocode/session-share.test.ts @@ -31,7 +31,7 @@ it.instance("shares and unshares sessions through Kilo public URLs", () => { const url = String(input) urls.push(url) if (url.endsWith("/api/user")) return new Response("{}", { status: 200 }) - if (url.endsWith("/share")) return Response.json({ public_id: "public-1" }) + if (url.endsWith("/share")) return Response.json({ share_token: "public-1" }) if (url.endsWith("/unshare")) return new Response(null, { status: 200 }) return new Response("{}", { status: 200 }) },