refactor(shared): group worktree, github, and linear modules into folders (#14437)

`src/shared` is a flat directory of ~1,150 entries. The worktree, github, and
linear domains accounted for 71 of them, so finding the module you wanted meant
scanning a wall of same-prefixed filenames.

Move each domain into its own folder and drop the now-redundant prefix:

    src/shared/github-pr-types.ts    -> src/shared/github/pull-request-types.ts
    src/shared/worktree-id.ts        -> src/shared/worktree/id.ts
    src/shared/linear-links.ts       -> src/shared/linear/links.ts

This follows the existing `network/` and `new-workspace/` convention in the
same directory, which also drop the prefix inside the folder.

Whole clusters move, including tests. Foldering only part of a domain would be
worse than flat: a reader would have to check both `github/` and the flat
directory, and `github-auth-types.ts` / `github-project-types.ts` are type
modules that belong with the rest. No files with these prefixes remain flat.

Import specifiers were rewritten by resolving each one to an absolute path and
recomputing it, not by string substitution, so the `@/../../shared/...` alias
forms are handled correctly. 501 specifiers across 298 files.

Two things `tsc` cannot catch, handled explicitly:

- `github-project-types.ts` carries its own `max-lines` bypass, so its baseline
  entry is REPOINTED to the new path rather than pruned. Pruning would drop the
  bypass and then flag the new path as a fresh violation. Ratchet stays at 345.
- `mobile/` is outside `pnpm typecheck` and cannot be typechecked here
  (`mobile/node_modules` is empty). Instead every relative specifier in the repo
  was resolved against the filesystem: 174 unresolved before this change and 174
  after — identical, so nothing broke in mobile either.

The pinned `tests/e2e/.cross-version-checkouts` fixtures are deliberately NOT
rewritten; they are a snapshot of an older release and still reference the old
paths.

Verified: cold `tsc --noEmit` green on node, cli, and web (buildinfo deleted
first — these projects are `composite: true` and reuse stale caches).
This commit is contained in:
Neil
2026-08-13 20:44:16 -07:00
committed by GitHub
parent 070572bfd7
commit 583ab1601b
318 changed files with 526 additions and 509 deletions
+110
View File
@@ -0,0 +1,110 @@
// Why shared: main's terminal side-effect tracker emits pr-link facts
// (terminal-side-effect-authority.md, slice 3) and needs the same GitHub URL
// parsing core the renderer link picker uses.
const GH_ITEM_PATH_RE = /^\/([^/]+)\/([^/]+)\/(issues|pull)\/(\d+)(?:\/.*)?$/i
export type RepoSlug = {
owner: string
repo: string
host?: string
}
export type GitHubIssueOrPRLink = {
slug: RepoSlug
number: number
type: 'issue' | 'pr'
}
export function buildGitHubRepoUrl(slug: RepoSlug | null | undefined): string | null {
if (!slug?.owner || !slug.repo) {
return null
}
// Why: hosted identities carry the GHES host; links must point at that
// server, not github.com.
const host = slug.host ?? 'github.com'
return `https://${host}/${encodeURIComponent(slug.owner)}/${encodeURIComponent(slug.repo)}`
}
function matchGitHubItemPath(url: URL): RegExpExecArray | null {
return GH_ITEM_PATH_RE.exec(url.pathname.replace(/\/+$/, ''))
}
function parseGitHubItemNumber(value: string): number | null {
const parsed = Number.parseInt(value, 10)
return parsed > 0 ? parsed : null
}
/**
* Parses a GitHub issue/PR reference from plain input.
* Supports issue/PR numbers (e.g. "42"), "#42", and full GitHub URLs.
*/
export function parseGitHubIssueOrPRNumber(input: string): number | null {
const trimmed = input.trim()
if (!trimmed) {
return null
}
const numeric = trimmed.startsWith('#') ? trimmed.slice(1) : trimmed
if (/^\d+$/.test(numeric)) {
return parseGitHubItemNumber(numeric)
}
let url: URL
try {
url = new URL(trimmed)
} catch {
return null
}
if (url.protocol !== 'https:' && url.protocol !== 'http:') {
return null
}
const match = matchGitHubItemPath(url)
if (!match) {
return null
}
return parseGitHubItemNumber(match[4])
}
/**
* Parses an owner/repo slug plus issue/PR number from a GitHub URL. Returns
* null for anything that isn't a recognizable GitHub-shaped issue or pull URL.
*/
export function parseGitHubIssueOrPRLink(input: string): GitHubIssueOrPRLink | null {
const trimmed = input.trim()
if (!trimmed) {
return null
}
let url: URL
try {
url = new URL(trimmed)
} catch {
return null
}
if (url.protocol !== 'https:' && url.protocol !== 'http:') {
return null
}
const match = matchGitHubItemPath(url)
if (!match) {
return null
}
const number = parseGitHubItemNumber(match[4])
if (number === null) {
return null
}
return {
// Why: the URL proves the host — GHES links must keep their server identity
// instead of being treated as github.com slugs.
// Why: GHES installations on non-default ports require the full URL host;
// `hostname` would silently redirect later API calls to port 443.
slug: { owner: match[1], repo: match[2], host: url.host },
type: match[3].toLowerCase() === 'pull' ? 'pr' : 'issue',
number
}
}