diff --git a/docs/api-versioning.md b/docs/api-versioning.md index 1a0a687..1eb1f55 100644 --- a/docs/api-versioning.md +++ b/docs/api-versioning.md @@ -4,9 +4,9 @@ The primary "API surface" of this site is the `/open` URL scheme bridge. External consumers (GitHub Action comments, CI scripts, integrations) construct `/open?...` URLs. Breaking changes to accepted parameters must not invalidate old links. -## Current version: v1 (unversioned) +## Current version: v1 -All existing `/open` URLs are treated as **v1**. The `v` query parameter is optional and defaults to `1`. +The current URL scheme lives at `/open`. It is treated as v1. ### v1 parameter sets @@ -27,21 +27,23 @@ All existing `/open` URLs are treated as **v1**. The `v` query parameter is opti ## Versioning convention -| Version | Path | Status | -| ------- | ---------------- | ------- | -| v1 | `/open` | Current | -| v2+ | `/open?v=2&...` | Future | +New versions live at a new path prefix — not as a query parameter. + +| Version | Path | Status | +| ------- | ----------- | ------- | +| v1 | `/open` | Current | +| v2+ | `/v2/open` | Future | ### Rules 1. **Never remove or rename params from an existing version.** Old links must keep working. -2. **Introduce a new version for breaking changes.** Add `v=2` (or higher) when dropping, renaming, or reinterpreting existing params. +2. **Introduce a new path for breaking changes.** Use `/v2/open` (or `/v3/open`, etc.) when dropping, renaming, or reinterpreting existing params. 3. **New optional params are non-breaking.** They may be added to an existing version without a version bump. -4. **The `v` param must be a positive integer string.** Unknown values return an error state with a clear message. +4. **Old version routes stay alive indefinitely.** Do not delete `/open` when `/v2/open` ships. ## Adding a new version -1. Extend the `resolveParams` function in `src/app/open/page.tsx` with a branch for the new version. +1. Create `src/app/v2/open/` with its own `page.tsx` that implements the new param set. 2. Add the new param set to this document under a new `## v parameter sets` section. -3. Keep the old version branch intact — do not delete it. -4. Update the version table above. +3. Update the version table above. +4. Keep the old route untouched — do not modify it. diff --git a/src/app/open/page.tsx b/src/app/open/page.tsx index 4011a14..9dd3d01 100644 --- a/src/app/open/page.tsx +++ b/src/app/open/page.tsx @@ -3,18 +3,16 @@ import { useEffect, useRef, useState } from "react"; import { type IssueParams, buildWorktreeUrl } from "./issue-card"; import { NoParamsView } from "./no-params-view"; -import { UnknownVersionView } from "./unknown-version-view"; import { OpeningView } from "./opening-view"; import { InstallView } from "./install-view"; import { OpenNav, OpenFooter } from "./open-layout"; type Phase = - | "loading" // reading URL params - | "opening" // scheme triggered, awaiting user confirmation - | "success" // user confirmed it opened - | "install" // user says it didn't open → show install guide - | "no-params" // no valid params in URL - | "unknown-version"; // unrecognized v= param + | "loading" // reading URL params + | "opening" // scheme triggered, awaiting user confirmation + | "success" // user confirmed it opened + | "install" // user says it didn't open → show install guide + | "no-params"; // no valid params in URL function get(sp: URLSearchParams, key: string): string { const val = sp.get(key); @@ -44,23 +42,13 @@ function resolveParams(sp: URLSearchParams): IssueParams | null { return { kind: "github", owner, repo, issue }; } -const SUPPORTED_VERSIONS: string[] = ["1"]; - export default function OpenPage() { const [phase, setPhase] = useState("loading"); const [params, setParams] = useState(null); - const [urlVersion, setUrlVersion] = useState("1"); const schemeTriggered = useRef(false); useEffect(() => { const sp = new URLSearchParams(window.location.search); - const raw = sp.get("v"); - const v = raw !== null ? raw : "1"; - setUrlVersion(v); - if (!SUPPORTED_VERSIONS.includes(v)) { - setPhase("unknown-version"); - return; - } const p = resolveParams(sp); if (!p) { setPhase("no-params"); return; } setParams(p); @@ -83,7 +71,6 @@ export default function OpenPage() {
{phase === "no-params" && } - {phase === "unknown-version" && } {phase === "loading" && (
diff --git a/src/app/open/unknown-version-view.tsx b/src/app/open/unknown-version-view.tsx deleted file mode 100644 index 92d2e17..0000000 --- a/src/app/open/unknown-version-view.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import Link from "next/link"; -import { AlertTriangle } from "lucide-react"; - -export function UnknownVersionView({ version }: { version: string }) { - return ( -
-
- -
-

Unsupported link version

-

- This link uses{" "} - v={version}, which is not - supported by this version of the site. The link may have been - generated by a newer version of the Worktree runner. Please update - your runner to open this workspace. -

- - ← Back to home - -
- ); -}