| 1 | import { |
| 2 | ProviderDriverKind, |
| 3 | ProviderInstanceId, |
| 4 | type RepositoryIdentity, |
| 5 | type ThreadPullRequestLink, |
| 6 | } from "@t3tools/contracts"; |
| 7 | import { describe, expect, it } from "vite-plus/test"; |
| 8 | |
| 9 | import { |
| 10 | findPromptLinkProject, |
| 11 | findPromptLinkPullRequestThread, |
| 12 | resolvePromptLinkModelSelection, |
| 13 | } from "./promptLinks.ts"; |
| 14 | |
| 15 | const identity = (canonicalKey: string, origin?: string): RepositoryIdentity => ({ |
| 16 | canonicalKey, |
| 17 | locator: { source: "git-remote", remoteName: "origin", remoteUrl: `https://${canonicalKey}` }, |
| 18 | ...(origin ? { origin: { canonicalKey: origin } } : {}), |
| 19 | }); |
| 20 | |
| 21 | describe("findPromptLinkProject", () => { |
| 22 | it("takes the first exact match and never a fork of the repository", () => { |
| 23 | const projects = [ |
| 24 | { |
| 25 | id: "fork", |
| 26 | repositoryIdentity: identity("github.com/pingdotgg/t3code", "github.com/me/t3code"), |
| 27 | }, |
| 28 | { id: "none", repositoryIdentity: null }, |
| 29 | { id: "recent", repositoryIdentity: identity("github.com/PingDotGG/T3Code") }, |
| 30 | { id: "older", repositoryIdentity: identity("github.com/pingdotgg/t3code") }, |
| 31 | ]; |
| 32 | expect(findPromptLinkProject(projects, { owner: "pingdotgg", name: "t3code" })?.id).toBe( |
| 33 | "recent", |
| 34 | ); |
| 35 | expect(findPromptLinkProject(projects, { owner: "me", name: "t3code" })?.id).toBe("fork"); |
| 36 | expect(findPromptLinkProject(projects, { owner: "gitlab", name: "x" })).toBeUndefined(); |
| 37 | }); |
| 38 | }); |
| 39 | |
| 40 | describe("findPromptLinkPullRequestThread", () => { |
| 41 | const link = (number: number, source: ThreadPullRequestLink["source"] = "created") => |
| 42 | ({ |
| 43 | host: "github.com", |
| 44 | repository: "pingdotgg/t3code", |
| 45 | number, |
| 46 | url: `https://github.com/pingdotgg/t3code/pull/${number}`, |
| 47 | source, |
| 48 | linkedAt: "2026-01-01T00:00:00.000Z", |
| 49 | snapshot: null, |
| 50 | stack: null, |
| 51 | }) satisfies ThreadPullRequestLink; |
| 52 | |
| 53 | it("finds the most recently updated thread linked to the pull request", () => { |
| 54 | const threads = [ |
| 55 | { id: "old", updatedAt: "2026-01-01T00:00:00.000Z", pullRequests: [link(7)] }, |
| 56 | { id: "new", updatedAt: "2026-02-01T00:00:00.000Z", pullRequests: [link(7)] }, |
| 57 | { id: "other", updatedAt: "2026-03-01T00:00:00.000Z", pullRequests: [link(8)] }, |
| 58 | { |
| 59 | id: "dismissed", |
| 60 | updatedAt: "2026-04-01T00:00:00.000Z", |
| 61 | pullRequests: [link(7, "stack-dismissed")], |
| 62 | }, |
| 63 | ]; |
| 64 | const pullRequest = { owner: "PingDotGG", name: "t3code", number: 7 }; |
| 65 | expect(findPromptLinkPullRequestThread(threads, pullRequest)?.id).toBe("new"); |
| 66 | expect(findPromptLinkPullRequestThread(threads, { ...pullRequest, number: 9 })).toBeUndefined(); |
| 67 | }); |
| 68 | }); |
| 69 | |
| 70 | describe("resolvePromptLinkModelSelection", () => { |
| 71 | const provider = ( |
| 72 | instanceId: string, |
| 73 | driver: string, |
| 74 | status: "ready" | "warning" | "error" | "disabled" = "ready", |
| 75 | ) => ({ |
| 76 | instanceId: ProviderInstanceId.make(instanceId), |
| 77 | driver: ProviderDriverKind.make(driver), |
| 78 | enabled: true, |
| 79 | status, |
| 80 | models: [ |
| 81 | { slug: "small", name: "Small" }, |
| 82 | { slug: "big", name: "Big", aliases: ["opus"], isDefault: true }, |
| 83 | ], |
| 84 | }); |
| 85 | |
| 86 | it("maps the requested provider and model onto a usable instance", () => { |
| 87 | const providers = [provider("broken", "claudeAgent", "error"), provider("work", "claudeAgent")]; |
| 88 | expect( |
| 89 | resolvePromptLinkModelSelection(providers, { provider: "claude", model: "small" }), |
| 90 | ).toEqual({ |
| 91 | selection: { instanceId: "work", model: "small" }, |
| 92 | exact: true, |
| 93 | }); |
| 94 | expect( |
| 95 | resolvePromptLinkModelSelection(providers, { provider: "claudeagent", model: "opus" }), |
| 96 | ).toEqual({ |
| 97 | selection: { instanceId: "work", model: "big" }, |
| 98 | exact: true, |
| 99 | }); |
| 100 | }); |
| 101 | |
| 102 | it("uses the instance default for an unknown model, and nothing for a missing provider", () => { |
| 103 | const providers = [provider("codex", "codex")]; |
| 104 | expect( |
| 105 | resolvePromptLinkModelSelection(providers, { provider: "codex", model: "nope" }), |
| 106 | ).toEqual({ |
| 107 | selection: { instanceId: "codex", model: "big" }, |
| 108 | exact: false, |
| 109 | }); |
| 110 | expect( |
| 111 | resolvePromptLinkModelSelection(providers, { provider: "cursor", model: null }), |
| 112 | ).toBeNull(); |
| 113 | }); |
| 114 | }); |