@dansyuqri/spark-joy 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -7
- package/dist/app/assets/index-CX9CpO88.js +8 -0
- package/dist/app/assets/index-ChCdW9F8.css +1 -0
- package/dist/app/index.html +2 -2
- package/dist/cli.js +339 -41
- package/dist/cli.js.map +1 -1
- package/package.json +8 -8
- package/{skill → plugin/skills/spark-joy}/SKILL.md +41 -2
- package/dist/app/assets/index-1qEXDj-s.js +0 -40
- package/dist/app/assets/index-DyYm7_iM.css +0 -1
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../cli/index.ts","../shared/schema.ts","../shared/derive.ts","../shared/validate.ts","../cli/lib/extract.ts","../cli/lib/diff.ts","../cli/lib/classify.ts","../cli/lib/split.ts","../cli/lib/symbols.ts","../cli/lib/git.ts","../cli/lib/runs.ts","../cli/lib/export.ts","../cli/lib/format.ts","../cli/lib/server.ts"],"sourcesContent":["import { copyFile, mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { parseArgs } from \"node:util\";\nimport { validatePlan } from \"../shared/validate\";\nimport { extract } from \"./lib/extract\";\nimport { exportMarkdown } from \"./lib/export\";\nimport { describeMeta, expandIds, formatLinks, outline, showFile, showHunks } from \"./lib/format\";\nimport * as g from \"./lib/git\";\nimport { readHunks, readLinks, readMeta, readPlanRaw, readState, resolveRun } from \"./lib/runs\";\nimport { serve } from \"./lib/server\";\n\nconst PKG_ROOT = fileURLToPath(new URL(\"..\", import.meta.url));\n\nconst HELP = `spark-joy: break a huge PR into reviewable chunks\n\nUsage: spark-joy <command> [options]\n\nCommands:\n extract [base] Diff merge-base(base, HEAD)..HEAD into hunks (base defaults to origin's default branch)\n --working Diff against the working tree (uncommitted changes) instead of HEAD\n --split-at <n> Split hunks longer than n lines (default 150)\n outline Compact per-file, per-hunk overview of the diff\n show <ids...> Print hunks in full; accepts h003, h003..h010, or a parent id like h012\n --file <path> Print every hunk of a file\n links Cross-file links: which hunk uses a name another hunk defines\n validate Check plan.json against the hunks\n --json Machine-readable output\n serve Open the review app\n --port <n> Port to listen on (default 4848)\n export Write review.md with progress, notes and the feature summary\n --stdout Print instead of writing the file\n install-skill Install the Claude Code skill into ~/.claude/skills/spark-joy\n --project Install into ./.claude/skills/spark-joy instead\n\nCommon options:\n --run <name> Run to use (default: the current branch's run)\n -v, --version Print the installed version\n -h, --help Show this help\n`;\n\nasync function run(cwd: string, name: string | undefined) {\n const root = await g.repoRoot(cwd);\n const branch = await g.currentBranch(root);\n return resolveRun(root, name, branch);\n}\n\nexport async function main(argv: string[], cwd = process.cwd()): Promise<number> {\n const { values, positionals } = parseArgs({\n args: argv,\n allowPositionals: true,\n options: {\n run: { type: \"string\" },\n working: { type: \"boolean\" },\n \"split-at\": { type: \"string\" },\n file: { type: \"string\" },\n json: { type: \"boolean\" },\n port: { type: \"string\" },\n stdout: { type: \"boolean\" },\n project: { type: \"boolean\" },\n help: { type: \"boolean\", short: \"h\" },\n version: { type: \"boolean\", short: \"v\" },\n },\n });\n const [cmd, ...rest] = positionals;\n if (values.version) {\n const pkg = JSON.parse(await readFile(join(PKG_ROOT, \"package.json\"), \"utf8\"));\n console.log(pkg.version);\n return 0;\n }\n if (!cmd || values.help) {\n console.log(HELP);\n return cmd || values.help ? 0 : 1;\n }\n\n switch (cmd) {\n case \"extract\": {\n const splitAt = values[\"split-at\"] ? Number(values[\"split-at\"]) : undefined;\n if (splitAt !== undefined && !(splitAt >= 40)) throw new Error(\"--split-at must be a number ≥ 40\");\n const r = await extract({ cwd, base: rest[0], working: values.working, run: values.run, splitAt });\n console.log(describeMeta(r.meta));\n console.log(`wrote ${r.paths.dir}`);\n if (r.hunks.length === 0) console.log(\"the diff is empty; nothing to review\");\n if (r.untracked.length)\n console.log(`note: ${r.untracked.length} untracked file(s) are not included; \\`git add -N <file>\\` to include them`);\n if (await readPlanRaw(r.paths)) console.log(\"note: plan.json already exists and may be stale; run `spark-joy validate`\");\n return 0;\n }\n\n case \"outline\": {\n const p = await run(cwd, values.run);\n console.log(outline(await readMeta(p), await readHunks(p)));\n return 0;\n }\n\n case \"show\": {\n const p = await run(cwd, values.run);\n const hunks = await readHunks(p);\n const ids = values.file ? showFile(hunks, values.file) : expandIds(rest, hunks);\n if (!ids.length) throw new Error(values.file ? `no hunks in ${values.file}` : \"pass hunk ids, e.g. `show h001 h004..h009`\");\n console.log(showHunks(hunks, ids));\n return 0;\n }\n\n case \"links\": {\n const p = await run(cwd, values.run);\n console.log(formatLinks(await readHunks(p), await readLinks(p)));\n return 0;\n }\n\n case \"validate\": {\n const p = await run(cwd, values.run);\n const raw = await readPlanRaw(p);\n if (raw === undefined) throw new Error(`no plan yet; write ${p.plan}`);\n const result = validatePlan(raw, await readHunks(p));\n if (values.json) {\n console.log(JSON.stringify({ ok: result.ok, issues: result.issues }, null, 2));\n } else {\n for (const i of result.issues) console.log(`${i.level === \"error\" ? \"error\" : \"warn \"} ${i.where}: ${i.message}`);\n const errors = result.issues.filter((i) => i.level === \"error\").length;\n const warnings = result.issues.length - errors;\n console.log(result.ok ? `plan ok (${warnings} warning${warnings === 1 ? \"\" : \"s\"})` : `${errors} error(s), ${warnings} warning(s)`);\n }\n return result.ok ? 0 : 1;\n }\n\n case \"serve\": {\n const p = await run(cwd, values.run);\n const port = values.port ? Number(values.port) : 4848;\n const s = await serve({ paths: p, appDir: join(PKG_ROOT, \"dist\", \"app\"), port });\n console.log(`spark-joy reviewing ${p.name} at ${s.url} (Ctrl+C to stop)`);\n await new Promise<void>((resolve) => process.once(\"SIGINT\", resolve));\n await s.close();\n return 0;\n }\n\n case \"export\": {\n const p = await run(cwd, values.run);\n const raw = await readPlanRaw(p);\n const hunks = await readHunks(p);\n const result = raw === undefined ? undefined : validatePlan(raw, hunks);\n if (!result?.plan) throw new Error(\"no valid plan to export; run `spark-joy validate`\");\n const md = exportMarkdown(await readMeta(p), hunks, result.plan, await readState(p));\n if (values.stdout) process.stdout.write(md);\n else {\n await writeFile(p.review, md);\n console.log(`wrote ${p.review}`);\n }\n return 0;\n }\n\n case \"install-skill\": {\n const dir = values.project\n ? join(await g.repoRoot(cwd), \".claude\", \"skills\", \"spark-joy\")\n : join(homedir(), \".claude\", \"skills\", \"spark-joy\");\n await mkdir(dir, { recursive: true });\n await copyFile(join(PKG_ROOT, \"skill\", \"SKILL.md\"), join(dir, \"SKILL.md\"));\n console.log(`installed skill to ${dir}; use /spark-joy in Claude Code`);\n return 0;\n }\n\n default:\n console.error(`unknown command: ${cmd}\\n`);\n console.log(HELP);\n return 1;\n }\n}\n","import { z } from \"zod\";\n\n// Flags that mark a hunk as mechanical. Hunks carrying any of these may be left\n// out of a plan; they are treated as part of the skim bucket automatically.\nexport const IGNORABLE_FLAGS = [\"lockfile\", \"generated\", \"binary\", \"whitespace-only\", \"rename\", \"mode\"] as const;\n\nexport const HunkFlag = z.enum([\n ...IGNORABLE_FLAGS,\n \"test\",\n \"docs\",\n]);\nexport type HunkFlag = z.infer<typeof HunkFlag>;\n\nexport const FileStatus = z.enum([\"added\", \"deleted\", \"modified\", \"renamed\", \"copied\"]);\nexport type FileStatus = z.infer<typeof FileStatus>;\n\nexport const Hunk = z.object({\n id: z.string(),\n file: z.string(),\n oldFile: z.string().optional(),\n status: FileStatus,\n header: z.string(),\n oldStart: z.number().int(),\n oldLines: z.number().int(),\n newStart: z.number().int(),\n newLines: z.number().int(),\n // Raw diff lines including their one-character prefix (\" \", \"+\", \"-\", \"\\\").\n lines: z.array(z.string()),\n added: z.number().int(),\n removed: z.number().int(),\n // Content hash that ignores line numbers, so review progress survives rebases\n // that only shift code around.\n hash: z.string(),\n flags: z.array(HunkFlag),\n // Set when a large hunk was split into pieces; points at the original id.\n parent: z.string().optional(),\n});\nexport type Hunk = z.infer<typeof Hunk>;\n\nexport const Meta = z.object({\n run: z.string(),\n repoRoot: z.string(),\n branch: z.string(),\n base: z.string(),\n baseSha: z.string(),\n mergeBase: z.string(),\n headSha: z.string(),\n working: z.boolean(),\n createdAt: z.string(),\n stats: z.object({\n files: z.number().int(),\n hunks: z.number().int(),\n added: z.number().int(),\n removed: z.number().int(),\n }),\n});\nexport type Meta = z.infer<typeof Meta>;\n\nexport const ChunkKind = z.enum([\"core\", \"test\", \"mechanical\"]);\nexport const Risk = z.enum([\"low\", \"med\", \"high\"]);\n\nexport const Chunk = z.object({\n id: z.string().min(1),\n title: z.string().min(1),\n intent: z.string().min(1),\n kind: ChunkKind.default(\"core\"),\n hunks: z.array(z.string()),\n dependsOn: z.array(z.string()).default([]),\n reviewFocus: z.array(z.string()).default([]),\n risk: Risk.default(\"low\"),\n});\nexport type Chunk = z.infer<typeof Chunk>;\n\nexport const Strategy = z.object({\n id: z.string().min(1),\n // Optional: the app names \"layers\" and \"features\" itself.\n label: z.string().optional(),\n chunks: z.array(Chunk),\n});\nexport type Strategy = z.infer<typeof Strategy>;\n\nexport const Feature = z.object({\n title: z.string().min(1),\n description: z.string().min(1),\n hunks: z.array(z.string()),\n});\nexport type Feature = z.infer<typeof Feature>;\n\n// Found by the CLI: hunk `from` uses a name that hunk `to` defines.\nexport const AutoLink = z.object({\n from: z.string(),\n to: z.string(),\n symbols: z.array(z.string()),\n});\nexport type AutoLink = z.infer<typeof AutoLink>;\n\n// Written by Claude to name the relationships a reviewer must understand.\nexport const PlanLink = z.object({\n from: z.string(),\n to: z.string(),\n label: z.string().min(1),\n});\nexport type PlanLink = z.infer<typeof PlanLink>;\n\nexport const Plan = z.object({\n title: z.string().optional(),\n overview: z.string().optional(),\n strategies: z.array(Strategy).min(1),\n features: z.array(Feature).default([]),\n skim: z.array(z.string()).default([]),\n links: z.array(PlanLink).default([]),\n});\nexport type Plan = z.infer<typeof Plan>;\n\nexport const LineNote = z.object({\n id: z.string(),\n file: z.string(),\n side: z.enum([\"old\", \"new\"]),\n line: z.number().int(),\n text: z.string(),\n at: z.string(),\n});\nexport type LineNote = z.infer<typeof LineNote>;\n\nexport const ReviewState = z.object({\n strategy: z.string().optional(),\n // Hashes of hunks the reviewer has signed off. Stored by content hash rather\n // than by id so that progress carries over when the diff is re-extracted.\n reviewed: z.array(z.string()).default([]),\n // Keyed by \"<strategyId>/<chunkId>\".\n chunkNotes: z.record(z.string()).default({}),\n lineNotes: z.array(LineNote).default([]),\n updatedAt: z.string().optional(),\n});\nexport type ReviewState = z.infer<typeof ReviewState>;\n\nexport const emptyState = (): ReviewState => ReviewState.parse({});\n","import { IGNORABLE_FLAGS, type Chunk, type Feature, type Hunk, type LineNote, type Plan, type ReviewState, type Strategy } from \"./schema\";\n\nexport type ChunkStatus = \"done\" | \"partial\" | \"todo\";\n\nexport const isIgnorable = (h: Hunk): boolean =>\n h.flags.some((f) => (IGNORABLE_FLAGS as readonly string[]).includes(f));\n\nexport const changedLines = (hs: readonly Hunk[]): number =>\n hs.reduce((n, h) => n + h.added + h.removed, 0);\n\nconst LABELS: Record<string, string> = { layers: \"Foundations first\", features: \"By feature\" };\nexport const strategyLabel = (s: Strategy): string => LABELS[s.id] ?? s.label ?? s.id;\n\nexport const chunkNoteKey = (strategyId: string, chunkId: string): string => `${strategyId}/${chunkId}`;\n\nexport interface ChunkView {\n chunk: Chunk;\n index: number;\n hunks: Hunk[];\n size: number;\n}\n\nexport interface StrategyView {\n strategy: Strategy;\n chunks: ChunkView[];\n // Explicit skim hunks plus ignorable hunks the plan left out.\n skim: Hunk[];\n}\n\nexport function strategyView(plan: Plan, hunks: readonly Hunk[], strategyId: string | undefined): StrategyView | undefined {\n const strategy = plan.strategies.find((s) => s.id === strategyId) ?? plan.strategies[0];\n if (!strategy) return undefined;\n const byId = new Map(hunks.map((h) => [h.id, h]));\n const placed = new Set<string>();\n const chunks = strategy.chunks.map((chunk, index) => {\n const hs = chunk.hunks.map((id) => byId.get(id)).filter((h): h is Hunk => !!h);\n hs.forEach((h) => placed.add(h.id));\n return { chunk, index, hunks: hs, size: changedLines(hs) };\n });\n const skimIds = new Set(plan.skim);\n const skim = hunks.filter((h) => !placed.has(h.id) && (skimIds.has(h.id) || isIgnorable(h)));\n return { strategy, chunks, skim };\n}\n\nexport function hunkStatus(hs: readonly Hunk[], reviewed: ReadonlySet<string>): ChunkStatus {\n if (hs.length === 0) return \"done\";\n const n = hs.filter((h) => reviewed.has(h.hash)).length;\n return n === hs.length ? \"done\" : n === 0 ? \"todo\" : \"partial\";\n}\n\nexport function setReviewed(state: ReviewState, hs: readonly Hunk[], on: boolean): ReviewState {\n const set = new Set(state.reviewed);\n for (const h of hs) on ? set.add(h.hash) : set.delete(h.hash);\n return { ...state, reviewed: [...set] };\n}\n\n// Chunks (in the given strategy) that hold at least one hunk of the feature.\nexport function featureChunks(feature: Feature, view: StrategyView): ChunkView[] {\n const ids = new Set(feature.hunks);\n return view.chunks.filter((c) => c.chunk.hunks.some((id) => ids.has(id)));\n}\n\nexport function featureHunks(feature: Feature, hunks: readonly Hunk[]): Hunk[] {\n const ids = new Set(feature.hunks);\n return hunks.filter((h) => ids.has(h.id));\n}\n\nexport interface Progress {\n done: number;\n total: number;\n linesDone: number;\n linesTotal: number;\n}\n\nexport function progress(view: StrategyView, reviewed: ReadonlySet<string>): Progress {\n let done = 0;\n let linesDone = 0;\n let linesTotal = 0;\n for (const c of view.chunks) {\n if (hunkStatus(c.hunks, reviewed) === \"done\") done++;\n linesTotal += c.size;\n linesDone += changedLines(c.hunks.filter((h) => reviewed.has(h.hash)));\n }\n return { done, total: view.chunks.length, linesDone, linesTotal };\n}\n\n// Old/new line numbers for every line of a hunk, for rendering gutters and\n// anchoring line notes. \"\\\" lines get neither.\nexport interface NumberedLine {\n text: string;\n kind: \"context\" | \"add\" | \"del\" | \"meta\";\n oldNo?: number;\n newNo?: number;\n}\n\nexport function numberLines(h: Hunk): NumberedLine[] {\n let o = h.oldStart;\n let n = h.newStart;\n return h.lines.map((raw) => {\n const p = raw[0];\n const text = raw.slice(1).replace(/\\r$/, \"\");\n if (p === \"+\") return { text, kind: \"add\", newNo: n++ };\n if (p === \"-\") return { text, kind: \"del\", oldNo: o++ };\n if (p === \"\\\\\") return { text: raw, kind: \"meta\" };\n return { text, kind: \"context\", oldNo: o++, newNo: n++ };\n });\n}\n\n// Line notes that fall inside any of the given hunks.\nexport function notesInHunks(hs: readonly Hunk[], notes: readonly LineNote[]): LineNote[] {\n return notes.filter((n) =>\n hs.some((h) => {\n if (h.file !== n.file) return false;\n const [start, len] = n.side === \"new\" ? [h.newStart, h.newLines] : [h.oldStart, h.oldLines];\n return n.line >= start && n.line < start + len;\n }),\n );\n}\n","import { isIgnorable, changedLines } from \"./derive\";\nimport { Plan, type Hunk } from \"./schema\";\n\nexport const CHUNK_LINE_BUDGET = 400;\n// Non-mechanical hunks larger than this in the skim bucket get a warning, since\n// skimmed code is code nobody reads closely.\nconst SKIM_WARN_LINES = 30;\n\n// Word budgets for plan text. Every word here is one more thing a reviewer\n// reads before the code, so going over is an error, not a warning.\nexport const BUDGET = {\n planTitle: 5,\n overview: 15,\n chunkTitle: 5,\n intent: 10,\n focusItems: 2,\n focusWords: 8,\n featureTitle: 4,\n featureDescription: 8,\n linkLabel: 3,\n} as const;\n\n// Phrases that add words without adding meaning: contrasts with what the code\n// doesn't do (\"by count, not prefix\"), and filler openers.\nconst PADDING: [RegExp, string][] = [\n [/,\\s*not\\b|\\bnot just\\b|\\brather than\\b|\\binstead of\\b/i, \"drop the contrast; say only what it does\"],\n [/^(this|the) (chunk|pr|change|code)\\b/i, \"drop the opener\"],\n [/^(introduces|adds support for|implements)\\b/i, \"drop the opener\"],\n [/\\b(various|several|some|basically|simply|just|really|very)\\b/i, \"drop the filler word\"],\n];\n\nexport const words = (s: string): number => s.trim().split(/\\s+/).filter(Boolean).length;\n\nexport interface Issue {\n level: \"error\" | \"warning\";\n where: string;\n message: string;\n}\n\nexport interface ValidationResult {\n ok: boolean;\n issues: Issue[];\n plan?: Plan;\n}\n\nexport function validatePlan(raw: unknown, hunks: readonly Hunk[], budget = CHUNK_LINE_BUDGET): ValidationResult {\n const parsed = Plan.safeParse(raw);\n if (!parsed.success) {\n return {\n ok: false,\n issues: parsed.error.issues.map((i) => ({\n level: \"error\" as const,\n where: i.path.length ? i.path.join(\".\") : \"plan\",\n message: i.message,\n })),\n };\n }\n const plan = parsed.data;\n const issues: Issue[] = [];\n const error = (where: string, message: string) => issues.push({ level: \"error\", where, message });\n const warn = (where: string, message: string) => issues.push({ level: \"warning\", where, message });\n\n const tooLong = (where: string, what: string, text: string | undefined, max: number) => {\n if (text === undefined) return;\n if (words(text) > max) error(where, `${what} is ${words(text)} words; max ${max}`);\n for (const [re, fix] of PADDING) {\n const m = re.exec(text);\n if (m) error(where, `${what} \"${m[0].trim()}\": ${fix}`);\n }\n };\n tooLong(\"plan\", \"title\", plan.title, BUDGET.planTitle);\n tooLong(\"plan\", \"overview\", plan.overview, BUDGET.overview);\n\n const byId = new Map(hunks.map((h) => [h.id, h]));\n const describe = (h: Hunk) => `${h.id} (${h.file} +${h.added} -${h.removed})`;\n\n const skim = new Set<string>();\n for (const id of plan.skim) {\n const h = byId.get(id);\n if (!h) error(\"skim\", `unknown hunk id ${id}`);\n else if (skim.has(id)) error(\"skim\", `hunk ${id} listed twice`);\n else {\n skim.add(id);\n if (!isIgnorable(h) && h.added + h.removed > SKIM_WARN_LINES)\n warn(\"skim\", `${describe(h)} is not flagged mechanical; make sure it really only needs a skim`);\n }\n }\n\n if (plan.strategies.length < 2)\n warn(\"strategies\", \"only one strategy; the reviewer is meant to choose between a foundations-first and a by-feature order\");\n\n const strategyIds = new Set<string>();\n for (const s of plan.strategies) {\n const where = `strategy ${s.id}`;\n if (strategyIds.has(s.id)) error(where, \"duplicate strategy id\");\n strategyIds.add(s.id);\n\n const seen = new Map<string, string>();\n const chunkIndex = new Map<string, number>();\n s.chunks.forEach((c, i) => {\n const cw = `${where} / chunk ${c.id}`;\n if (chunkIndex.has(c.id)) error(cw, \"duplicate chunk id\");\n chunkIndex.set(c.id, i);\n if (c.hunks.length === 0) error(cw, \"chunk has no hunks\");\n tooLong(cw, \"title\", c.title, BUDGET.chunkTitle);\n tooLong(cw, \"intent\", c.intent, BUDGET.intent);\n if (c.reviewFocus.length > BUDGET.focusItems)\n error(cw, `${c.reviewFocus.length} reviewFocus items; max ${BUDGET.focusItems}`);\n c.reviewFocus.forEach((q, n) => tooLong(cw, `reviewFocus ${n + 1}`, q, BUDGET.focusWords));\n\n const hs: Hunk[] = [];\n for (const id of c.hunks) {\n const h = byId.get(id);\n if (!h) {\n error(cw, `unknown hunk id ${id}`);\n continue;\n }\n if (seen.has(id)) error(cw, `hunk ${id} is already in chunk ${seen.get(id)}`);\n else if (skim.has(id)) error(cw, `hunk ${id} is also in skim`);\n seen.set(id, c.id);\n hs.push(h);\n }\n const size = changedLines(hs);\n if (size > budget) warn(cw, `${size} changed lines exceeds the ${budget}-line budget; consider splitting`);\n\n for (const dep of c.dependsOn) {\n const at = chunkIndex.get(dep);\n if (dep === c.id) error(cw, \"depends on itself\");\n else if (at === undefined) {\n if (s.chunks.some((o) => o.id === dep)) error(cw, `depends on ${dep}, which comes later; reorder the chunks`);\n else error(cw, `depends on unknown chunk ${dep}`);\n }\n }\n });\n\n const missing = hunks.filter((h) => !seen.has(h.id) && !skim.has(h.id) && !isIgnorable(h));\n if (missing.length)\n error(where, `hunks not in any chunk or skim: ${missing.map(describe).join(\", \")}`);\n }\n\n plan.links.forEach((l, i) => {\n const lw = `link ${i + 1} (${l.from}→${l.to})`;\n for (const id of [l.from, l.to]) if (!byId.has(id)) error(lw, `unknown hunk id ${id}`);\n if (l.from === l.to) error(lw, \"links a hunk to itself\");\n tooLong(lw, \"label\", l.label, BUDGET.linkLabel);\n });\n\n if (plan.features.length === 0) warn(\"features\", \"no features; the summary page will be empty\");\n const inFeature = new Set<string>();\n plan.features.forEach((f, i) => {\n const fw = `feature ${i + 1} (${f.title})`;\n if (f.hunks.length === 0) error(fw, \"feature has no hunks\");\n tooLong(fw, \"title\", f.title, BUDGET.featureTitle);\n tooLong(fw, \"description\", f.description, BUDGET.featureDescription);\n for (const id of f.hunks) {\n if (!byId.has(id)) error(fw, `unknown hunk id ${id}`);\n inFeature.add(id);\n }\n });\n if (plan.features.length) {\n const orphans = hunks.filter((h) => !inFeature.has(h.id) && !skim.has(h.id) && !isIgnorable(h));\n if (orphans.length)\n warn(\"features\", `hunks not linked to any feature: ${orphans.map((h) => h.id).join(\", \")}`);\n }\n\n return { ok: !issues.some((i) => i.level === \"error\"), issues, plan };\n}\n","import { createHash } from \"node:crypto\";\nimport { mkdir } from \"node:fs/promises\";\nimport type { Hunk, HunkFlag, Meta } from \"../../shared/schema\";\nimport { parseDiff, type FileDiff, type RawHunk } from \"./diff\";\nimport { fileFlags, hasGeneratedMarker, whitespaceOnly } from \"./classify\";\nimport { splitHunk } from \"./split\";\nimport { computeLinks } from \"./symbols\";\nimport * as g from \"./git\";\nimport { ensureRunsDir, runPaths, slug, writeJson, type RunPaths } from \"./runs\";\n\nconst hashOf = (...parts: string[]) => createHash(\"sha1\").update(parts.join(\"\\0\")).digest(\"hex\").slice(0, 16);\n\n// Files with no textual hunks (binary, pure rename, mode change, empty file)\n// still get one placeholder hunk so every change is accounted for.\nfunction placeholder(f: FileDiff): { raw: RawHunk; flag?: HunkFlag } {\n const raw = (header: string): RawHunk => ({ header, oldStart: 0, oldLines: 0, newStart: 0, newLines: 0, lines: [] });\n if (f.binary) return { raw: raw(`Binary file ${f.status}`), flag: \"binary\" };\n if (f.status === \"renamed\") return { raw: raw(`Renamed from ${f.oldFile}`), flag: \"rename\" };\n if (f.status === \"copied\") return { raw: raw(`Copied from ${f.oldFile}`), flag: \"rename\" };\n if (f.modeChange) return { raw: raw(\"File mode changed\"), flag: \"mode\" };\n return { raw: raw(`Empty file ${f.status}`) };\n}\n\nexport function buildHunks(files: FileDiff[], attrGenerated: ReadonlySet<string> = new Set(), splitAt?: number): Hunk[] {\n type Pending = Omit<Hunk, \"id\"> & { pieces: number };\n const pending: Pending[] = [];\n for (const f of files) {\n const flags = fileFlags(f, attrGenerated);\n if (!flags.includes(\"generated\") && hasGeneratedMarker(f)) flags.push(\"generated\");\n const raws = f.hunks.length ? f.hunks.map((h) => ({ raw: h, flag: undefined as HunkFlag | undefined })) : [placeholder(f)];\n for (const { raw, flag } of raws) {\n const hunkFlags = [...flags];\n if (flag && !hunkFlags.includes(flag)) hunkFlags.push(flag);\n if (whitespaceOnly(raw)) hunkFlags.push(\"whitespace-only\");\n // Nobody reads lockfiles or generated code line by line, so don't cut them up.\n const pieces = flags.includes(\"lockfile\") || flags.includes(\"generated\") ? [raw] : splitHunk(raw, splitAt);\n for (const p of pieces) {\n pending.push({\n file: f.file,\n ...(f.oldFile ? { oldFile: f.oldFile } : {}),\n status: f.status,\n header: p.header,\n oldStart: p.oldStart,\n oldLines: p.oldLines,\n newStart: p.newStart,\n newLines: p.newLines,\n lines: p.lines,\n added: p.lines.filter((l) => l[0] === \"+\").length,\n removed: p.lines.filter((l) => l[0] === \"-\").length,\n hash: hashOf(f.file, f.oldFile ?? \"\", f.status, p.header.startsWith(\"@@\") ? \"\" : p.header, ...p.lines),\n flags: hunkFlags,\n pieces: pieces.length,\n });\n }\n }\n }\n\n let n = 0;\n let piece = 0;\n const hunks: Hunk[] = [];\n // Number the original hunks, then suffix pieces of split ones (h012.1, h012.2).\n for (let i = 0; i < pending.length; i++) {\n const { pieces, ...h } = pending[i]!;\n if (piece === 0) n++;\n const base = `h${String(n).padStart(3, \"0\")}`;\n if (pieces > 1) {\n piece++;\n hunks.push({ ...h, id: `${base}.${piece}`, parent: base });\n if (piece === pieces) piece = 0;\n } else hunks.push({ ...h, id: base });\n }\n return hunks;\n}\n\nexport interface ExtractOptions {\n cwd: string;\n base?: string;\n working?: boolean;\n run?: string;\n splitAt?: number;\n}\n\nexport interface ExtractResult {\n paths: RunPaths;\n meta: Meta;\n hunks: Hunk[];\n untracked: string[];\n}\n\nexport async function extract(opts: ExtractOptions): Promise<ExtractResult> {\n const root = await g.repoRoot(opts.cwd);\n const branch = await g.currentBranch(root);\n const base = opts.base ?? (await g.defaultBase(root));\n const baseSha = await g.revParse(root, base);\n const headSha = await g.revParse(root, \"HEAD\");\n const mb = await g.mergeBase(root, baseSha, headSha);\n\n const text = await g.diff(root, mb, opts.working ? undefined : headSha);\n const files = parseDiff(text);\n const attr = await g.generatedByAttr(root, files.map((f) => f.file));\n const hunks = buildHunks(files, attr, opts.splitAt);\n\n const name = slug(opts.run ?? branch);\n const meta: Meta = {\n run: name,\n repoRoot: root,\n branch,\n base,\n baseSha,\n mergeBase: mb,\n headSha,\n working: !!opts.working,\n createdAt: new Date().toISOString(),\n stats: {\n files: files.length,\n hunks: hunks.length,\n added: hunks.reduce((s, h) => s + h.added, 0),\n removed: hunks.reduce((s, h) => s + h.removed, 0),\n },\n };\n\n await ensureRunsDir(root);\n const paths = runPaths(root, name);\n await mkdir(paths.dir, { recursive: true });\n await writeJson(paths.hunks, hunks);\n await writeJson(paths.meta, meta);\n await writeJson(paths.links, computeLinks(hunks));\n const untracked = opts.working ? await g.untracked(root) : [];\n return { paths, meta, hunks, untracked };\n}\n","import type { FileStatus } from \"../../shared/schema\";\n\nexport interface RawHunk {\n header: string;\n oldStart: number;\n oldLines: number;\n newStart: number;\n newLines: number;\n lines: string[];\n}\n\nexport interface FileDiff {\n file: string;\n oldFile?: string;\n status: FileStatus;\n binary: boolean;\n modeChange: boolean;\n hunks: RawHunk[];\n}\n\nconst HUNK_RE = /^@@ -(\\d+)(?:,(\\d+))? \\+(\\d+)(?:,(\\d+))? @@/;\n\n// Undo git's C-style quoting of paths (\"a/caf\\303\\251 file\").\nexport function unquotePath(s: string): string {\n if (!s.startsWith('\"')) return s;\n const bytes: number[] = [];\n const esc: Record<string, number> = { n: 10, t: 9, r: 13, '\"': 34, \"\\\\\": 92, a: 7, b: 8, f: 12, v: 11 };\n for (let i = 1; i < s.length - 1; i++) {\n const ch = s[i]!;\n if (ch !== \"\\\\\") {\n bytes.push(...Buffer.from(ch, \"utf8\"));\n continue;\n }\n const next = s[++i]!;\n if (/[0-7]/.test(next)) {\n bytes.push(parseInt(s.slice(i, i + 3), 8));\n i += 2;\n } else bytes.push(esc[next] ?? next.charCodeAt(0));\n }\n return Buffer.from(bytes).toString(\"utf8\");\n}\n\nconst stripPrefix = (p: string, prefix: string) => (p.startsWith(prefix) ? p.slice(prefix.length) : p);\n\n// \"--- a/foo\" / \"+++ b/foo\" path, or undefined for /dev/null.\nfunction markerPath(line: string): string | undefined {\n let p = line.slice(4).replace(/\\t$/, \"\");\n p = unquotePath(p);\n if (p === \"/dev/null\") return undefined;\n return p.replace(/^[ab]\\//, \"\");\n}\n\n// Paths from \"diff --git a/X b/Y\". Ambiguous when names contain \" b/\", so this\n// is only a fallback for binary and mode-only changes that have no ---/+++ lines.\nfunction gitHeaderPaths(rest: string): [string, string] {\n if (rest.startsWith('\"')) {\n let end = 1;\n while (end < rest.length && !(rest[end] === '\"' && rest[end - 1] !== \"\\\\\")) end++;\n const a = unquotePath(rest.slice(0, end + 1));\n const b = unquotePath(rest.slice(end + 2));\n return [stripPrefix(a, \"a/\"), stripPrefix(b, \"b/\")];\n }\n // Same path on both sides: \"a/P b/P\" has length 2 * len(P) + 5.\n const len = (rest.length - 5) / 2;\n if (Number.isInteger(len) && len > 0) {\n const p = rest.slice(2, 2 + len);\n if (rest === `a/${p} b/${p}`) return [p, p];\n }\n const at = rest.indexOf(\" b/\");\n const b = rest.slice(at + 1);\n return [stripPrefix(rest.slice(0, at), \"a/\"), stripPrefix(unquotePath(b), \"b/\")];\n}\n\nexport function parseDiff(text: string): FileDiff[] {\n const lines = text.split(\"\\n\");\n const files: FileDiff[] = [];\n let cur: FileDiff | undefined;\n let i = 0;\n\n while (i < lines.length) {\n const line = lines[i]!;\n if (line.startsWith(\"diff --git \")) {\n const [a, b] = gitHeaderPaths(line.slice(\"diff --git \".length));\n cur = { file: b, oldFile: a !== b ? a : undefined, status: \"modified\", binary: false, modeChange: false, hunks: [] };\n files.push(cur);\n i++;\n continue;\n }\n if (!cur) {\n i++;\n continue;\n }\n\n if (line.startsWith(\"new file mode\")) cur.status = \"added\";\n else if (line.startsWith(\"deleted file mode\")) cur.status = \"deleted\";\n else if (line.startsWith(\"old mode\") || line.startsWith(\"new mode\")) cur.modeChange = true;\n else if (line.startsWith(\"rename from \")) {\n cur.status = \"renamed\";\n cur.oldFile = unquotePath(line.slice(\"rename from \".length));\n } else if (line.startsWith(\"rename to \")) cur.file = unquotePath(line.slice(\"rename to \".length));\n else if (line.startsWith(\"copy from \")) {\n cur.status = \"copied\";\n cur.oldFile = unquotePath(line.slice(\"copy from \".length));\n } else if (line.startsWith(\"copy to \")) cur.file = unquotePath(line.slice(\"copy to \".length));\n else if (line.startsWith(\"Binary files \") || line === \"GIT binary patch\") cur.binary = true;\n else if (line.startsWith(\"--- \")) {\n const p = markerPath(line);\n if (p && p !== cur.file && cur.status !== \"deleted\") cur.oldFile = p;\n } else if (line.startsWith(\"+++ \")) {\n const p = markerPath(line);\n if (p) cur.file = p;\n } else if (line.startsWith(\"@@\")) {\n const m = HUNK_RE.exec(line);\n if (!m) throw new Error(`malformed hunk header: ${line}`);\n const h: RawHunk = {\n header: line,\n oldStart: Number(m[1]),\n oldLines: m[2] === undefined ? 1 : Number(m[2]),\n newStart: Number(m[3]),\n newLines: m[4] === undefined ? 1 : Number(m[4]),\n lines: [],\n };\n i++;\n // Consume by count rather than by prefix, so content that happens to look\n // like a header (\"@@\" in a removed line) can't end the hunk early.\n let oldLeft = h.oldLines;\n let newLeft = h.newLines;\n while (i < lines.length && (oldLeft > 0 || newLeft > 0 || lines[i]!.startsWith(\"\\\\\"))) {\n let l = lines[i]!;\n if (l === \"\" && (oldLeft > 0 && newLeft > 0)) l = \" \"; // tools that strip trailing spaces\n const p = l[0];\n if (p === \"+\") newLeft--;\n else if (p === \"-\") oldLeft--;\n else if (p === \" \") {\n oldLeft--;\n newLeft--;\n } else if (p !== \"\\\\\") break;\n h.lines.push(l);\n i++;\n }\n cur.hunks.push(h);\n continue;\n }\n i++;\n }\n\n return files;\n}\n","import { basename } from \"node:path\";\nimport type { HunkFlag } from \"../../shared/schema\";\nimport type { FileDiff, RawHunk } from \"./diff\";\n\nconst LOCKFILES = new Set([\n \"package-lock.json\",\n \"npm-shrinkwrap.json\",\n \"pnpm-lock.yaml\",\n \"yarn.lock\",\n \"bun.lockb\",\n \"bun.lock\",\n \"Cargo.lock\",\n \"poetry.lock\",\n \"Pipfile.lock\",\n \"uv.lock\",\n \"composer.lock\",\n \"Gemfile.lock\",\n \"go.sum\",\n \"flake.lock\",\n \"mix.lock\",\n \"pubspec.lock\",\n \"Podfile.lock\",\n \"packages.lock.json\",\n \"gradle.lockfile\",\n]);\n\nconst GENERATED_PATH = [\n /(^|\\/)(dist|build|out|vendor|node_modules|__generated__|generated)\\//,\n /\\.min\\.(js|css)$/,\n /\\.map$/,\n /\\.pb\\.go$/,\n /_pb2(_grpc)?\\.pyi?$/,\n /\\.g\\.dart$/,\n /\\.generated\\.\\w+$/,\n /\\.snap$/,\n];\nconst GENERATED_MARKER = /@generated|Code generated .* DO NOT EDIT|auto-?generated file/i;\n\nconst TEST_PATH = [\n /(^|\\/)(tests?|__tests__|spec|e2e|testdata|fixtures)\\//,\n /\\.(test|spec)\\.\\w+$/,\n /_test\\.(go|py|rb|exs?)$/,\n /(^|\\/)test_[^/]+\\.py$/,\n /Tests?\\.(java|kt|cs|swift)$/,\n];\nconst DOCS_PATH = [/\\.(md|mdx|rst|adoc|txt)$/i, /(^|\\/)docs?\\//];\n\nexport function fileFlags(f: FileDiff, attrGenerated: ReadonlySet<string>): HunkFlag[] {\n const flags: HunkFlag[] = [];\n if (LOCKFILES.has(basename(f.file))) flags.push(\"lockfile\");\n if (attrGenerated.has(f.file) || GENERATED_PATH.some((r) => r.test(f.file))) flags.push(\"generated\");\n if (f.binary) flags.push(\"binary\");\n if (TEST_PATH.some((r) => r.test(f.file))) flags.push(\"test\");\n if (DOCS_PATH.some((r) => r.test(f.file))) flags.push(\"docs\");\n return flags;\n}\n\n// True when the hunk only changes whitespace: the removed and added lines are\n// the same multiset once all whitespace is stripped.\nexport function whitespaceOnly(h: RawHunk): boolean {\n const norm = (l: string) => l.slice(1).replace(/\\s+/g, \"\");\n const del = h.lines.filter((l) => l[0] === \"-\").map(norm).sort();\n const add = h.lines.filter((l) => l[0] === \"+\").map(norm).sort();\n if (del.length === 0 && add.length === 0) return false;\n const a = del.filter((l) => l !== \"\");\n const b = add.filter((l) => l !== \"\");\n return a.length === b.length && a.every((l, i) => l === b[i]);\n}\n\n// Generated-code markers usually sit in the first lines of a new file.\nexport function hasGeneratedMarker(f: FileDiff): boolean {\n const first = f.hunks[0];\n if (!first || first.oldStart > 1 || first.newStart > 1) return false;\n return first.lines.slice(0, 5).some((l) => GENERATED_MARKER.test(l));\n}\n","import type { RawHunk } from \"./diff\";\n\nexport const SPLIT_THRESHOLD = 150;\nconst TARGET = 80;\nconst MIN_PIECE = 30;\n\nconst isBlank = (l: string) => /^[ +-]\\s*$/.test(l);\nconst indent = (l: string) => /^[ +-](\\s*)/.exec(l)?.[1]?.length ?? 0;\n\n// Score how good a place it is to start a new piece at line i (0 = can't).\nfunction cutScore(lines: string[], i: number): number {\n const line = lines[i];\n if (line === undefined || line.startsWith(\"\\\\\")) return 0;\n if (isBlank(line)) return 0;\n let s = 1;\n if (isBlank(lines[i - 1] ?? \"\")) s += 2;\n if (indent(line) === 0) s += 2;\n return s;\n}\n\n// Split a hunk longer than `threshold` lines into consecutive pieces, preferring\n// to cut after blank lines in front of top-level code. Pieces concatenate back\n// to exactly the original lines.\nexport function splitHunk(h: RawHunk, threshold = SPLIT_THRESHOLD): RawHunk[] {\n if (h.lines.length <= threshold) return [h];\n const max = Math.max(threshold, TARGET * 2);\n const cuts: number[] = [];\n let start = 0;\n while (h.lines.length - start > threshold) {\n let best = -1;\n let bestScore = 0;\n for (let i = start + MIN_PIECE; i <= Math.min(start + max, h.lines.length - MIN_PIECE); i++) {\n const s = cutScore(h.lines, i);\n // Prefer higher scores, then whichever is closest to the target size.\n const dist = Math.abs(i - start - TARGET);\n const bestDist = Math.abs(best - start - TARGET);\n if (s > bestScore || (s === bestScore && s > 0 && dist < bestDist)) {\n best = i;\n bestScore = s;\n }\n }\n if (best < 0) {\n best = start + TARGET;\n while (h.lines[best]?.startsWith(\"\\\\\")) best++;\n }\n cuts.push(best);\n start = best;\n }\n\n const pieces: RawHunk[] = [];\n const section = h.header.replace(/^@@ [^@]* @@ ?/, \"\");\n // Next line number on each side. An empty side's start points at the line\n // before the change, following git's convention.\n let o = h.oldLines === 0 ? h.oldStart + 1 : h.oldStart;\n let n = h.newLines === 0 ? h.newStart + 1 : h.newStart;\n let from = 0;\n for (const to of [...cuts, h.lines.length]) {\n const lines = h.lines.slice(from, to);\n let ol = 0;\n let nl = 0;\n for (const l of lines) {\n if (l[0] === \"+\") nl++;\n else if (l[0] === \"-\") ol++;\n else if (l[0] === \" \") {\n ol++;\n nl++;\n }\n }\n const os = ol === 0 ? o - 1 : o;\n const ns = nl === 0 ? n - 1 : n;\n pieces.push({\n header: `@@ -${os},${ol} +${ns},${nl} @@${section ? ` ${section}` : \"\"}`,\n oldStart: os,\n oldLines: ol,\n newStart: ns,\n newLines: nl,\n lines,\n });\n o += ol;\n n += nl;\n from = to;\n }\n return pieces;\n}\n","import { basename, dirname, extname } from \"node:path\";\nimport { isIgnorable } from \"../../shared/derive\";\nimport type { AutoLink, Hunk } from \"../../shared/schema\";\n\n// Declarations that name something another file could use. Deliberately\n// loose and language-agnostic: a missed link costs less than a wrong one.\nconst DECLS = [\n /\\b(?:function\\*?|class|interface|type|enum|def|fn|struct|trait|func|module|object|record)\\s+([A-Za-z_$][\\w$]*)/g,\n /\\bfunc\\s+\\([^)]*\\)\\s*([A-Za-z_]\\w*)/g, // Go methods\n];\n// Top-level bindings only; indented consts are locals.\nconst TOP_BINDING = /^(?:export\\s+(?:default\\s+)?)?(?:const|let|var|val)\\s+([A-Za-z_$][\\w$]*)/;\nconst IDENT = /[A-Za-z_$][\\w$]*/g;\n\nconst KEYWORDS = new Set(\n (\n \"and any as async await bool boolean break case catch char class const continue def default del do else enum \" +\n \"export extends false final finally float fn for from func function get if impl import in int interface is let \" +\n \"match mod module new nil none not null number object or package private protected pub public return self set \" +\n \"static str string struct super switch this throw true try type typeof undefined use val var void while with yield \" +\n \"main init test index value data result error props state\"\n ).split(\" \"),\n);\n\nconst usable = (name: string) => name.length >= 3 && !KEYWORDS.has(name.toLowerCase());\n\nconst CODE = new Set(\n \"ts tsx js jsx mjs cjs mts cts py go rs java kt kts swift rb cs php scala c cc cpp h hpp vue svelte ex exs dart\".split(\" \"),\n);\nconst isCode = (file: string) => CODE.has(extname(file).slice(1).toLowerCase());\n\n// Strings and comments mention names without using them.\nconst stripNoise = (line: string) =>\n line\n .replace(/([\"'`])(?:\\\\.|(?!\\1).)*\\1/g, \" \")\n .replace(/\\/\\/.*$|#.*$|\\/\\*.*?\\*\\//g, \" \");\n\nconst IMPORT_LINE = /\\b(import|from|require|use|include|using)\\b/;\n\n// The name a module is imported by: its file stem, or its folder for index files.\nfunction moduleName(file: string): string {\n const stem = basename(file, extname(file));\n return [\"index\", \"mod\", \"__init__\", \"main\"].includes(stem) ? basename(dirname(file)) : stem;\n}\n\nfunction declared(line: string): string[] {\n if (IMPORT_LINE.test(line)) return []; // `import { type X }` mentions a declaration; it doesn't make one.\n const names: string[] = [];\n for (const re of DECLS) for (const m of line.matchAll(re)) names.push(m[1]!);\n const top = TOP_BINDING.exec(line);\n if (top) names.push(top[1]!);\n return names;\n}\n\n// Names a hunk defines or changes the body of: declarations on added lines,\n// plus the declaration enclosing the first change (the last one in the\n// leading context, else the one git puts in the hunk header).\nexport function definitions(h: Hunk): string[] {\n const names = new Set<string>();\n const firstChange = h.lines.findIndex((l) => l[0] === \"+\" || l[0] === \"-\");\n let enclosing = declared(/^@@ [^@]* @@ ?(.*)$/.exec(h.header)?.[1] ?? \"\");\n h.lines.forEach((raw, i) => {\n if (raw[0] === \"+\") declared(raw.slice(1)).forEach((n) => names.add(n));\n else if (raw[0] === \" \" && i < firstChange) {\n const d = declared(raw.slice(1));\n if (d.length) enclosing = d;\n }\n });\n if (firstChange >= 0) enclosing.forEach((n) => names.add(n));\n return [...names].filter(usable);\n}\n\nfunction uses(h: Hunk): Set<string> {\n const names = new Set<string>();\n for (const raw of h.lines) if (raw[0] === \"+\") for (const m of stripNoise(raw.slice(1)).matchAll(IDENT)) names.add(m[0]);\n return names;\n}\n\n// Tokens on a file's import lines, so a use only counts when the user file\n// actually imports the module that defines the name.\nfunction importTokens(hunks: readonly Hunk[]): Map<string, Set<string>> {\n const out = new Map<string, Set<string>>();\n for (const h of hunks) {\n const set = out.get(h.file) ?? new Set<string>();\n for (const raw of h.lines) {\n if (raw[0] === \"-\" || !IMPORT_LINE.test(raw)) continue;\n for (const t of raw.slice(1).split(/[^A-Za-z0-9_$-]+/)) if (t) set.add(t);\n }\n out.set(h.file, set);\n }\n return out;\n}\n\nfunction connected(user: string, definer: string, imports: Map<string, Set<string>>): boolean {\n if (imports.get(user)?.has(moduleName(definer))) return true;\n // Go files in one package share names without imports.\n return extname(user) === \".go\" && extname(definer) === \".go\" && dirname(user) === dirname(definer);\n}\n\n// Links between hunks in different files: `from` uses a name `to` defines.\nexport function computeLinks(hunks: readonly Hunk[]): AutoLink[] {\n const live = hunks.filter((h) => !isIgnorable(h) && isCode(h.file));\n const imports = importTokens(live);\n const definedIn = new Map<string, Hunk[]>();\n for (const h of live) for (const name of definitions(h)) definedIn.set(name, [...(definedIn.get(name) ?? []), h]);\n // Names defined in many files are too generic to say anything.\n for (const [name, hs] of definedIn) if (new Set(hs.map((h) => h.file)).size > 2) definedIn.delete(name);\n\n const links = new Map<string, AutoLink>();\n for (const from of live) {\n for (const name of uses(from)) {\n for (const to of definedIn.get(name) ?? []) {\n if (to.file === from.file || !connected(from.file, to.file, imports)) continue;\n const key = `${from.id}>${to.id}`;\n const link = links.get(key) ?? { from: from.id, to: to.id, symbols: [] };\n link.symbols.push(name);\n links.set(key, link);\n }\n }\n }\n return [...links.values()].map((l) => ({ ...l, symbols: l.symbols.sort() }));\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst exec = promisify(execFile);\n\nexport async function git(cwd: string, args: string[], input?: string): Promise<string> {\n const child = exec(\"git\", [\"-c\", \"core.quotePath=false\", ...args], {\n cwd,\n maxBuffer: 1024 * 1024 * 1024,\n encoding: \"utf8\",\n });\n if (input !== undefined) {\n child.child.stdin?.end(input);\n }\n const { stdout } = await child;\n return stdout;\n}\n\nconst tryGit = (cwd: string, args: string[]) => git(cwd, args).then((s) => s.trim(), () => undefined);\n\nexport const repoRoot = async (cwd: string) => (await git(cwd, [\"rev-parse\", \"--show-toplevel\"])).trim();\n\nexport async function currentBranch(cwd: string): Promise<string> {\n return (await tryGit(cwd, [\"symbolic-ref\", \"--short\", \"-q\", \"HEAD\"])) || \"HEAD\";\n}\n\nexport async function revParse(cwd: string, rev: string): Promise<string> {\n const sha = await tryGit(cwd, [\"rev-parse\", \"--verify\", \"--quiet\", `${rev}^{commit}`]);\n if (!sha) throw new Error(`unknown revision: ${rev}`);\n return sha;\n}\n\n// The branch PRs/MRs usually target: origin/HEAD, else the first common default\n// branch name that exists (remote first, then local).\nexport async function defaultBase(cwd: string): Promise<string> {\n const originHead = await tryGit(cwd, [\"symbolic-ref\", \"--short\", \"-q\", \"refs/remotes/origin/HEAD\"]);\n if (originHead) return originHead;\n for (const name of [\"origin/main\", \"origin/master\", \"origin/develop\", \"main\", \"master\", \"develop\"]) {\n if (await tryGit(cwd, [\"rev-parse\", \"--verify\", \"--quiet\", `${name}^{commit}`])) return name;\n }\n throw new Error(\"could not find a base branch; pass one explicitly, e.g. `spark-joy extract origin/main`\");\n}\n\nexport async function mergeBase(cwd: string, a: string, b: string): Promise<string> {\n const sha = await tryGit(cwd, [\"merge-base\", a, b]);\n if (!sha) throw new Error(`${a} and ${b} have no common history`);\n return sha;\n}\n\nexport function diff(cwd: string, from: string, to: string | undefined): Promise<string> {\n const args = [\n \"diff\",\n \"--no-color\",\n \"--no-ext-diff\",\n \"--no-textconv\",\n \"-M\",\n \"--src-prefix=a/\",\n \"--dst-prefix=b/\",\n from,\n ];\n if (to) args.push(to);\n return git(cwd, args);\n}\n\nexport async function untracked(cwd: string): Promise<string[]> {\n const out = await git(cwd, [\"ls-files\", \"--others\", \"--exclude-standard\", \"-z\"]);\n return out.split(\"\\0\").filter(Boolean);\n}\n\n// Files marked linguist-generated in .gitattributes.\nexport async function generatedByAttr(cwd: string, files: string[]): Promise<Set<string>> {\n if (files.length === 0) return new Set();\n const out = await git(cwd, [\"check-attr\", \"-z\", \"--stdin\", \"linguist-generated\"], files.join(\"\\0\") + \"\\0\").catch(() => \"\");\n const parts = out.split(\"\\0\");\n const result = new Set<string>();\n for (let i = 0; i + 2 < parts.length; i += 3) {\n if (parts[i + 2] === \"set\" || parts[i + 2] === \"true\") result.add(parts[i]!);\n }\n return result;\n}\n","import { mkdir, readFile, readdir, rename, stat, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { AutoLink, Hunk, Meta, ReviewState, emptyState } from \"../../shared/schema\";\nimport { z } from \"zod\";\n\nexport const RUNS_DIR = \".spark-joy\";\n\nexport const slug = (s: string) => s.replace(/[^A-Za-z0-9._-]+/g, \"-\").replace(/^-+|-+$/g, \"\") || \"run\";\n\nexport interface RunPaths {\n name: string;\n dir: string;\n hunks: string;\n meta: string;\n plan: string;\n state: string;\n review: string;\n links: string;\n}\n\nexport function runPaths(root: string, name: string): RunPaths {\n const dir = join(root, RUNS_DIR, name);\n return {\n name,\n dir,\n hunks: join(dir, \"hunks.json\"),\n meta: join(dir, \"meta.json\"),\n plan: join(dir, \"plan.json\"),\n state: join(dir, \"review-state.json\"),\n review: join(dir, \"review.md\"),\n links: join(dir, \"links.json\"),\n };\n}\n\nexport async function ensureRunsDir(root: string): Promise<void> {\n const dir = join(root, RUNS_DIR);\n await mkdir(dir, { recursive: true });\n // Keep runs out of the user's commits without touching their .gitignore.\n await writeFile(join(dir, \".gitignore\"), \"*\\n\");\n}\n\nconst exists = (p: string) => stat(p).then(() => true, () => false);\n\n// An explicit name wins; otherwise the run for the current branch, falling back\n// to the most recently extracted run.\nexport async function resolveRun(root: string, name: string | undefined, branch: string): Promise<RunPaths> {\n if (name) {\n const p = runPaths(root, name);\n if (!(await exists(p.hunks))) throw new Error(`no run named \"${name}\"; run \\`spark-joy extract\\` first`);\n return p;\n }\n const mine = runPaths(root, slug(branch));\n if (await exists(mine.hunks)) return mine;\n const runs = await listRuns(root);\n if (!runs[0]) throw new Error(\"no runs yet; run `spark-joy extract` first\");\n return runPaths(root, runs[0].name);\n}\n\nexport async function listRuns(root: string): Promise<{ name: string; mtime: number }[]> {\n const dir = join(root, RUNS_DIR);\n const names = await readdir(dir).catch(() => [] as string[]);\n const runs = [];\n for (const name of names) {\n const s = await stat(join(dir, name, \"hunks.json\")).catch(() => undefined);\n if (s) runs.push({ name, mtime: s.mtimeMs });\n }\n return runs.sort((a, b) => b.mtime - a.mtime);\n}\n\nexport async function writeJson(path: string, data: unknown): Promise<void> {\n const tmp = `${path}.${process.pid}.tmp`;\n await writeFile(tmp, JSON.stringify(data, null, 2) + \"\\n\");\n await rename(tmp, path);\n}\n\nexport async function readJson(path: string): Promise<unknown> {\n return JSON.parse(await readFile(path, \"utf8\"));\n}\n\nexport const readHunks = async (p: RunPaths) => z.array(Hunk).parse(await readJson(p.hunks));\nexport const readMeta = async (p: RunPaths) => Meta.parse(await readJson(p.meta));\n\nexport async function readPlanRaw(p: RunPaths): Promise<unknown | undefined> {\n if (!(await exists(p.plan))) return undefined;\n try {\n return await readJson(p.plan);\n } catch (e) {\n throw new Error(`plan.json is not valid JSON: ${(e as Error).message}`);\n }\n}\n\n// Runs extracted before links existed have no file; treat that as no links.\nexport async function readLinks(p: RunPaths): Promise<AutoLink[]> {\n if (!(await exists(p.links))) return [];\n return z.array(AutoLink).parse(await readJson(p.links));\n}\n\nexport async function readState(p: RunPaths): Promise<ReviewState> {\n if (!(await exists(p.state))) return emptyState();\n return ReviewState.parse(await readJson(p.state));\n}\n","import {\n chunkNoteKey,\n featureChunks,\n featureHunks,\n hunkStatus,\n notesInHunks,\n progress,\n strategyView,\n type ChunkStatus,\n} from \"../../shared/derive\";\nimport type { Hunk, Meta, Plan, ReviewState } from \"../../shared/schema\";\n\nconst MARK: Record<ChunkStatus, string> = {\n done: \"[x]\",\n partial: \"[~]\",\n todo: \"[ ]\",\n};\n\n// Markdown review summary that pastes cleanly into a GitHub or GitLab comment.\nexport function exportMarkdown(meta: Meta, hunks: readonly Hunk[], plan: Plan, state: ReviewState): string {\n const view = strategyView(plan, hunks, state.strategy);\n if (!view) return \"\";\n const reviewed = new Set(state.reviewed);\n const p = progress(view, reviewed);\n const head = meta.working ? \"working tree\" : meta.headSha.slice(0, 8);\n const pct = p.linesTotal ? Math.round((100 * p.linesDone) / p.linesTotal) : 100;\n const out: string[] = [];\n\n out.push(`# Review: ${plan.title ?? meta.branch}`, \"\");\n out.push(`${p.done}/${p.total} chunks · ${pct}% lines · \\`${meta.base}\\` → ${head}`, \"\");\n\n if (plan.features.length) {\n out.push(\"## Features\", \"\");\n for (const f of plan.features) {\n const status = hunkStatus(featureHunks(f, hunks), reviewed);\n const chunks = featureChunks(f, view).map((c) => c.index + 1);\n out.push(`- ${MARK[status]} ${f.title}${chunks.length ? ` (${chunks.join(\", \")})` : \"\"}`);\n }\n out.push(\"\");\n }\n\n out.push(\"## Chunks\", \"\");\n for (const c of view.chunks) {\n const status = hunkStatus(c.hunks, reviewed);\n const changed = status === \"partial\" ? \" · changed since review\" : \"\";\n out.push(`- ${MARK[status]} ${c.index + 1}. ${c.chunk.title} (${c.size})${changed}`);\n const note = state.chunkNotes[chunkNoteKey(view.strategy.id, c.chunk.id)]?.trim();\n if (note) out.push(...note.split(\"\\n\").map((l) => ` > ${l}`));\n for (const n of notesInHunks(c.hunks, state.lineNotes))\n out.push(` - \\`${n.file}:${n.line}\\`${n.side === \"old\" ? \" (old)\" : \"\"} ${n.text.trim()}`);\n }\n if (view.skim.length) out.push(`- ${MARK[hunkStatus(view.skim, reviewed)]} Skim (${view.skim.length} hunks)`);\n out.push(\"\");\n\n const placed = new Set([...view.chunks.flatMap((c) => c.hunks), ...view.skim].map((h) => h.file));\n const stray = state.lineNotes.filter((n) => !placed.has(n.file));\n if (stray.length) {\n out.push(\"## Other notes\", \"\");\n for (const n of stray) out.push(`- \\`${n.file}:${n.line}\\` ${n.text.trim()}`);\n out.push(\"\");\n }\n return out.join(\"\\n\").replace(/\\n{3,}/g, \"\\n\\n\").trimEnd() + \"\\n\";\n}\n\n","import { isIgnorable } from \"../../shared/derive\";\nimport type { AutoLink, Hunk, Meta } from \"../../shared/schema\";\n\nconst short = (sha: string) => sha.slice(0, 8);\nconst clip = (s: string, n: number) => (s.length > n ? `${s.slice(0, n - 1)}…` : s);\n\nexport function describeMeta(meta: Meta): string {\n const head = meta.working ? \"working tree\" : `HEAD ${short(meta.headSha)}`;\n const { files, hunks, added, removed } = meta.stats;\n return `run ${meta.run}: ${meta.base} (${short(meta.mergeBase)}) → ${head} on ${meta.branch}\\n${files} files, ${hunks} hunks, +${added} −${removed}`;\n}\n\n// First changed line that says something, to hint at what a hunk does.\nfunction gist(h: Hunk): string {\n const line =\n h.lines.find((l) => (l[0] === \"+\" || l[0] === \"-\") && /[A-Za-z0-9]/.test(l) && l.slice(1).trim().length > 3) ?? \"\";\n return clip(line.replace(/\\s+/g, \" \").trim(), 90);\n}\n\nconst section = (h: Hunk) => /^@@ [^@]* @@ ?(.*)$/.exec(h.header)?.[1]?.trim() ?? \"\";\n\nexport function outline(meta: Meta, hunks: readonly Hunk[]): string {\n const out = [describeMeta(meta)];\n const ignorable = hunks.filter(isIgnorable);\n if (ignorable.length) {\n const a = ignorable.reduce((s, h) => s + h.added, 0);\n const r = ignorable.reduce((s, h) => s + h.removed, 0);\n out.push(`${ignorable.length} mechanical hunks (lockfile/generated/binary/whitespace/rename), +${a} −${r}: may be left out of the plan`);\n }\n let file = \"\";\n for (const h of hunks) {\n if (h.file !== file) {\n file = h.file;\n const fh = hunks.filter((x) => x.file === file);\n const a = fh.reduce((s, x) => s + x.added, 0);\n const r = fh.reduce((s, x) => s + x.removed, 0);\n const from = h.oldFile && h.oldFile !== h.file ? ` (from ${h.oldFile})` : \"\";\n out.push(\"\", `${file}${from} [${h.status}] +${a} −${r}`);\n }\n const flags = h.flags.length ? ` {${h.flags.join(\",\")}}` : \"\";\n const sec = section(h);\n const where = /^@@ (.*?) @@/.exec(h.header)?.[1] ?? h.header;\n out.push(` ${h.id.padEnd(9)} ${where.padEnd(22)} +${h.added} −${h.removed}${flags}${sec ? ` in ${clip(sec, 40)}` : \"\"}`);\n const g = gist(h);\n if (g) out.push(` ${g}`);\n }\n return out.join(\"\\n\");\n}\n\n// Expand \"h003..h007\" style ranges against the hunk order.\nexport function expandIds(args: string[], hunks: readonly Hunk[]): string[] {\n const order = hunks.map((h) => h.id);\n const ids: string[] = [];\n for (const arg of args.flatMap((a) => a.split(\",\"))) {\n if (!arg) continue;\n const m = /^(.+)\\.\\.(.+)$/.exec(arg);\n if (m) {\n const from = order.findIndex((id) => id === m[1] || id.startsWith(`${m[1]}.`));\n const toIdx = order.findLastIndex((id) => id === m[2] || id.startsWith(`${m[2]}.`));\n if (from < 0 || toIdx < 0) throw new Error(`unknown range ${arg}`);\n ids.push(...order.slice(from, toIdx + 1));\n } else {\n // A bare parent id selects all of its pieces.\n const match = order.filter((id) => id === arg || id.startsWith(`${arg}.`));\n if (!match.length) throw new Error(`unknown hunk id ${arg}`);\n ids.push(...match);\n }\n }\n return [...new Set(ids)];\n}\n\nexport function showHunks(hunks: readonly Hunk[], ids: readonly string[]): string {\n const byId = new Map(hunks.map((h) => [h.id, h]));\n return ids\n .map((id) => {\n const h = byId.get(id)!;\n const flags = h.flags.length ? ` {${h.flags.join(\",\")}}` : \"\";\n const head = `=== ${h.id} ${h.file} [${h.status}] +${h.added} −${h.removed}${flags}`;\n return [head, h.header, ...h.lines].join(\"\\n\");\n })\n .join(\"\\n\\n\");\n}\n\nexport function showFile(hunks: readonly Hunk[], file: string): string[] {\n return hunks.filter((h) => h.file === file || h.oldFile === file).map((h) => h.id);\n}\n\n// Links grouped by file pair, definer first, for Claude to pick which to label.\nexport function formatLinks(hunks: readonly Hunk[], links: readonly AutoLink[]): string {\n const file = new Map(hunks.map((h) => [h.id, h.file]));\n const pairs = new Map<string, string[]>();\n for (const l of links) {\n const key = `${file.get(l.to)} → ${file.get(l.from)}`;\n pairs.set(key, [...(pairs.get(key) ?? []), `${clip(l.symbols.join(\", \"), 60)} (${l.to}→${l.from})`]);\n }\n if (!pairs.size) return \"no cross-file links found\";\n return [...pairs]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([pair, items]) => [pair, ...items.map((i) => ` ${i}`)].join(\"\\n\"))\n .join(\"\\n\");\n}\n","import { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { extname, join, normalize, sep } from \"node:path\";\nimport { ReviewState } from \"../../shared/schema\";\nimport { validatePlan } from \"../../shared/validate\";\nimport { exportMarkdown } from \"./export\";\nimport { readHunks, readLinks, readMeta, readPlanRaw, readState, writeJson, type RunPaths } from \"./runs\";\n\nconst TYPES: Record<string, string> = {\n \".html\": \"text/html; charset=utf-8\",\n \".js\": \"text/javascript; charset=utf-8\",\n \".css\": \"text/css; charset=utf-8\",\n \".svg\": \"image/svg+xml\",\n \".json\": \"application/json\",\n \".map\": \"application/json\",\n};\n\nconst MAX_BODY = 20 * 1024 * 1024;\n\nasync function body(req: IncomingMessage): Promise<unknown> {\n const chunks: Buffer[] = [];\n let size = 0;\n for await (const c of req) {\n size += (c as Buffer).length;\n if (size > MAX_BODY) throw new Error(\"request too large\");\n chunks.push(c as Buffer);\n }\n return JSON.parse(Buffer.concat(chunks).toString(\"utf8\") || \"{}\");\n}\n\nfunction send(res: ServerResponse, status: number, data: unknown) {\n res.writeHead(status, { \"content-type\": \"application/json\", \"cache-control\": \"no-store\" });\n res.end(JSON.stringify(data));\n}\n\n// Everything the app needs, read fresh from disk on each request so a plan\n// rewritten by Claude shows up on the next reload.\nasync function loadRun(paths: RunPaths) {\n const [meta, hunks, raw, state, links] = await Promise.all([\n readMeta(paths),\n readHunks(paths),\n readPlanRaw(paths),\n readState(paths),\n readLinks(paths),\n ]);\n const validation = raw === undefined ? undefined : validatePlan(raw, hunks);\n return {\n meta,\n hunks,\n plan: validation?.plan,\n issues: validation?.issues ?? [],\n hasPlan: raw !== undefined,\n links,\n state,\n };\n}\n\nexport interface ServeOptions {\n paths: RunPaths;\n appDir: string;\n port: number;\n host?: string;\n}\n\nexport async function serve(opts: ServeOptions): Promise<{ url: string; close: () => Promise<void> }> {\n const { paths, appDir } = opts;\n const host = opts.host ?? \"127.0.0.1\";\n\n let port = opts.port;\n const server = createServer(async (req, res) => {\n try {\n // Refuse other Host names so a DNS-rebinding page can't read the diff.\n const allowed = [`${host}:${port}`, `localhost:${port}`, `127.0.0.1:${port}`];\n if (!allowed.includes(req.headers.host ?? \"\")) return send(res, 403, { error: \"unexpected host\" });\n const url = new URL(req.url ?? \"/\", \"http://localhost\");\n // Requests from other sites can't read responses, but could still write;\n // only accept writes that come from this origin.\n if (req.method !== \"GET\" && req.headers.origin && new URL(req.headers.origin).host !== req.headers.host) {\n return send(res, 403, { error: \"cross-origin request refused\" });\n }\n\n if (url.pathname === \"/api/run\" && req.method === \"GET\") return send(res, 200, await loadRun(paths));\n\n if (url.pathname === \"/api/state\" && req.method === \"PUT\") {\n const state = ReviewState.parse(await body(req));\n state.updatedAt = new Date().toISOString();\n await writeJson(paths.state, state);\n return send(res, 200, state);\n }\n\n if (url.pathname === \"/api/export\" && req.method === \"POST\") {\n const run = await loadRun(paths);\n if (!run.plan) return send(res, 409, { error: \"no valid plan to export\" });\n const markdown = exportMarkdown(run.meta, run.hunks, run.plan, run.state);\n await writeFile(paths.review, markdown);\n return send(res, 200, { path: paths.review, markdown });\n }\n\n if (url.pathname.startsWith(\"/api/\")) return send(res, 404, { error: \"not found\" });\n if (req.method !== \"GET\") return send(res, 405, { error: \"method not allowed\" });\n\n // Static app files, falling back to index.html for client-side routes.\n const rel = normalize(decodeURIComponent(url.pathname)).replace(/^([/\\\\])+/, \"\");\n let file = join(appDir, rel);\n if (!file.startsWith(appDir + sep) && file !== appDir) return send(res, 403, { error: \"forbidden\" });\n let data: Buffer;\n try {\n data = await readFile(file);\n } catch {\n file = join(appDir, \"index.html\");\n data = await readFile(file);\n }\n res.writeHead(200, { \"content-type\": TYPES[extname(file)] ?? \"application/octet-stream\" });\n res.end(data);\n } catch (e) {\n send(res, 400, { error: (e as Error).message });\n }\n });\n\n for (let attempt = 0; ; attempt++) {\n try {\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(port, host, () => {\n server.off(\"error\", reject);\n resolve();\n });\n });\n break;\n } catch (e) {\n if ((e as NodeJS.ErrnoException).code !== \"EADDRINUSE\" || attempt >= 20) throw e;\n port++;\n }\n }\n const address = server.address();\n if (address && typeof address === \"object\") port = address.port;\n return {\n url: `http://${host}:${port}`,\n close: () => new Promise((r) => server.close(() => r())),\n };\n}\n"],"mappings":"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","names":["mkdir","readFile","writeFile","join","mkdir","b","section","basename","basename","z","mkdir","untracked","readFile","writeFile","extname","join","run","writeFile","join","readFile","extname","readFile","join","writeFile","mkdir"]}
|
|
1
|
+
{"version":3,"sources":["../cli/index.ts","../shared/schema.ts","../shared/derive.ts","../shared/validate.ts","../cli/lib/extract.ts","../cli/lib/diff.ts","../cli/lib/classify.ts","../cli/lib/split.ts","../cli/lib/symbols.ts","../cli/lib/git.ts","../cli/lib/runs.ts","../cli/lib/export.ts","../cli/lib/format.ts","../cli/lib/server.ts","../cli/lib/stack.ts"],"sourcesContent":["import { copyFile, mkdir, mkdtemp, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { homedir, tmpdir } from \"node:os\";\nimport { join, relative } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { parseArgs } from \"node:util\";\nimport { defaultPrefix } from \"../shared/derive\";\nimport { validatePlan } from \"../shared/validate\";\nimport { extract } from \"./lib/extract\";\nimport { exportMarkdown } from \"./lib/export\";\nimport { describeMeta, expandIds, formatLinks, outline, showFile, showHunks } from \"./lib/format\";\nimport * as g from \"./lib/git\";\nimport { readHunks, readLinks, readMeta, readPlanRaw, readState, resolveRun } from \"./lib/runs\";\nimport { serve } from \"./lib/server\";\nimport { buildStack, checkStack, createBranches, prsMarkdown } from \"./lib/stack\";\n\nconst PKG_ROOT = fileURLToPath(new URL(\"..\", import.meta.url));\n\nconst HELP = `spark-joy: break a huge PR into reviewable chunks\n\nUsage: spark-joy <command> [options]\n\nCommands:\n extract [base] Diff merge-base(base, HEAD)..HEAD into hunks (base defaults to origin's default branch)\n --working Diff against the working tree (uncommitted changes) instead of HEAD\n --staged Only staged changes (HEAD → index); for split\n --uncommitted Only uncommitted changes (HEAD → working tree); for split\n --split-at <n> Split hunks longer than n lines (default 150)\n outline Compact per-file, per-hunk overview of the diff\n show <ids...> Print hunks in full; accepts h003, h003..h010, or a parent id like h012\n --file <path> Print every hunk of a file\n links Cross-file links: which hunk uses a name another hunk defines\n validate Check plan.json against the hunks\n --json Machine-readable output\n serve Open the review app\n --port <n> Port to listen on (default 4848)\n export Write review.md with progress, notes and the feature summary\n --stdout Print instead of writing the file\n split Dry run of a split plan: build the stacked PRs and check they add up\n --check <cmd> Run cmd on each PR in a temporary worktree, e.g. \"npm ci && npm test\"\n --apply Create the branches (never pushes)\n --prefix <name> Branch prefix (default <branch>-split)\n --force Move branches that already exist\n install-skill Install the Claude Code skill into ~/.claude/skills/spark-joy\n --project Install into ./.claude/skills/spark-joy instead\n\nCommon options:\n --run <name> Run to use (default: the current branch's run)\n -v, --version Print the installed version\n -h, --help Show this help\n`;\n\nasync function run(cwd: string, name: string | undefined) {\n const root = await g.repoRoot(cwd);\n const branch = await g.currentBranch(root);\n return resolveRun(root, name, branch);\n}\n\nexport async function main(argv: string[], cwd = process.cwd()): Promise<number> {\n const { values, positionals } = parseArgs({\n args: argv,\n allowPositionals: true,\n options: {\n run: { type: \"string\" },\n working: { type: \"boolean\" },\n staged: { type: \"boolean\" },\n uncommitted: { type: \"boolean\" },\n apply: { type: \"boolean\" },\n prefix: { type: \"string\" },\n force: { type: \"boolean\" },\n check: { type: \"string\" },\n \"split-at\": { type: \"string\" },\n file: { type: \"string\" },\n json: { type: \"boolean\" },\n port: { type: \"string\" },\n stdout: { type: \"boolean\" },\n project: { type: \"boolean\" },\n help: { type: \"boolean\", short: \"h\" },\n version: { type: \"boolean\", short: \"v\" },\n },\n });\n const [cmd, ...rest] = positionals;\n if (values.version) {\n const pkg = JSON.parse(await readFile(join(PKG_ROOT, \"package.json\"), \"utf8\"));\n console.log(pkg.version);\n return 0;\n }\n if (!cmd || values.help) {\n console.log(HELP);\n return cmd || values.help ? 0 : 1;\n }\n\n switch (cmd) {\n case \"extract\": {\n const splitAt = values[\"split-at\"] ? Number(values[\"split-at\"]) : undefined;\n if (splitAt !== undefined && !(splitAt >= 40)) throw new Error(\"--split-at must be a number ≥ 40\");\n const flags = ([\"working\", \"staged\", \"uncommitted\"] as const).filter((f) => values[f]);\n if (flags.length > 1) throw new Error(`pick one of ${flags.map((f) => `--${f}`).join(\", \")}`);\n const r = await extract({ cwd, base: rest[0], source: flags[0], run: values.run, splitAt });\n console.log(describeMeta(r.meta));\n console.log(`wrote ${relative(cwd, r.paths.dir)}`);\n if (r.hunks.length === 0) console.log(\"the diff is empty; nothing to review\");\n if (r.untracked.length)\n console.log(`note: ${r.untracked.length} untracked file(s) are not included; \\`git add -N <file>\\` to include them`);\n if (await readPlanRaw(r.paths)) console.log(\"note: plan.json already exists and may be stale; run `spark-joy validate`\");\n return 0;\n }\n\n case \"outline\": {\n const p = await run(cwd, values.run);\n console.log(outline(await readMeta(p), await readHunks(p)));\n return 0;\n }\n\n case \"show\": {\n const p = await run(cwd, values.run);\n const hunks = await readHunks(p);\n const ids = values.file ? showFile(hunks, values.file) : expandIds(rest, hunks);\n if (!ids.length) throw new Error(values.file ? `no hunks in ${values.file}` : \"pass hunk ids, e.g. `show h001 h004..h009`\");\n console.log(showHunks(hunks, ids));\n return 0;\n }\n\n case \"links\": {\n const p = await run(cwd, values.run);\n console.log(formatLinks(await readHunks(p), await readLinks(p)));\n return 0;\n }\n\n case \"validate\": {\n const p = await run(cwd, values.run);\n const raw = await readPlanRaw(p);\n if (raw === undefined) throw new Error(`no plan yet; write ${p.plan}`);\n const result = validatePlan(raw, await readHunks(p));\n if (values.json) {\n console.log(JSON.stringify({ ok: result.ok, issues: result.issues }, null, 2));\n } else {\n for (const i of result.issues) console.log(`${i.level === \"error\" ? \"error\" : \"warn \"} ${i.where}: ${i.message}`);\n const errors = result.issues.filter((i) => i.level === \"error\").length;\n const warnings = result.issues.length - errors;\n console.log(result.ok ? `plan ok (${warnings} warning${warnings === 1 ? \"\" : \"s\"})` : `${errors} error(s), ${warnings} warning(s)`);\n }\n return result.ok ? 0 : 1;\n }\n\n case \"serve\": {\n const p = await run(cwd, values.run);\n const port = values.port ? Number(values.port) : 4848;\n const s = await serve({ paths: p, appDir: join(PKG_ROOT, \"dist\", \"app\"), port });\n console.log(`spark-joy reviewing ${p.name} at ${s.url} (Ctrl+C to stop)`);\n await new Promise<void>((resolve) => process.once(\"SIGINT\", resolve));\n await s.close();\n return 0;\n }\n\n case \"export\": {\n const p = await run(cwd, values.run);\n const raw = await readPlanRaw(p);\n const hunks = await readHunks(p);\n const result = raw === undefined ? undefined : validatePlan(raw, hunks);\n if (!result?.plan) throw new Error(\"no valid plan to export; run `spark-joy validate`\");\n const md = exportMarkdown(await readMeta(p), hunks, result.plan, await readState(p));\n if (values.stdout) process.stdout.write(md);\n else {\n await writeFile(p.review, md);\n console.log(`wrote ${relative(cwd, p.review)}`);\n }\n return 0;\n }\n\n case \"split\": {\n const p = await run(cwd, values.run);\n const raw = await readPlanRaw(p);\n if (raw === undefined) throw new Error(`no plan yet; write ${p.plan}`);\n const hunks = await readHunks(p);\n const result = validatePlan(raw, hunks);\n if (!result.ok || !result.plan) throw new Error(\"the plan has errors; run `spark-joy validate`\");\n const meta = await readMeta(p);\n const prefix = values.prefix ?? defaultPrefix(meta.branch);\n const stack = await buildStack({\n root: meta.repoRoot,\n meta,\n hunks,\n plan: result.plan,\n prefix,\n indexFile: join(p.dir, \"split.index\"),\n });\n for (const pr of stack.prs)\n console.log(`${String(pr.n).padStart(2)} ${pr.branch} ${pr.lines} lines, ${pr.files} files ${pr.chunk.title}`);\n console.log(`${stack.prs.length} PRs; the last one matches your changes exactly`);\n\n if (values.check !== undefined) {\n const tmp = await mkdtemp(join(tmpdir(), \"spark-joy-check-\"));\n try {\n const results = await checkStack(meta.repoRoot, stack, values.check, tmp);\n for (const r of results) {\n console.log(`PR ${r.n}: ${r.ok ? \"passed\" : \"failed\"}`);\n if (!r.ok) console.log(r.output.trimEnd().split(\"\\n\").slice(-20).map((l) => ` ${l}`).join(\"\\n\"));\n }\n if (results.some((r) => !r.ok)) return 1;\n } finally {\n await rm(tmp, { recursive: true, force: true });\n }\n }\n\n await writeFile(p.prs, prsMarkdown(meta, stack));\n if (!values.apply) {\n console.log(`wrote ${relative(cwd, p.prs)}\\nnothing created; add --apply to create the branches`);\n return 0;\n }\n await createBranches(meta.repoRoot, stack, !!values.force);\n console.log(`created ${stack.prs.length} branches; your working tree is unchanged. To publish:`);\n for (const pr of stack.prs) console.log(` git push -u origin ${pr.branch}`);\n console.log(`PR titles and descriptions: ${relative(cwd, p.prs)}`);\n return 0;\n }\n\n case \"install-skill\": {\n const dir = values.project\n ? join(await g.repoRoot(cwd), \".claude\", \"skills\", \"spark-joy\")\n : join(homedir(), \".claude\", \"skills\", \"spark-joy\");\n await mkdir(dir, { recursive: true });\n await copyFile(join(PKG_ROOT, \"plugin\", \"skills\", \"spark-joy\", \"SKILL.md\"), join(dir, \"SKILL.md\"));\n console.log(`installed skill to ${dir}; use /spark-joy in Claude Code`);\n return 0;\n }\n\n default:\n console.error(`unknown command: ${cmd}\\n`);\n console.log(HELP);\n return 1;\n }\n}\n","import { z } from \"zod\";\n\n// Flags that mark a hunk as mechanical. Hunks carrying any of these may be left\n// out of a plan; they are treated as part of the skim bucket automatically.\nexport const IGNORABLE_FLAGS = [\"lockfile\", \"generated\", \"binary\", \"whitespace-only\", \"rename\", \"mode\"] as const;\n\nexport const HunkFlag = z.enum([\n ...IGNORABLE_FLAGS,\n \"test\",\n \"docs\",\n]);\nexport type HunkFlag = z.infer<typeof HunkFlag>;\n\nexport const FileStatus = z.enum([\"added\", \"deleted\", \"modified\", \"renamed\", \"copied\"]);\nexport type FileStatus = z.infer<typeof FileStatus>;\n\nexport const Hunk = z.object({\n id: z.string(),\n file: z.string(),\n oldFile: z.string().optional(),\n status: FileStatus,\n header: z.string(),\n oldStart: z.number().int(),\n oldLines: z.number().int(),\n newStart: z.number().int(),\n newLines: z.number().int(),\n // Raw diff lines including their one-character prefix (\" \", \"+\", \"-\", \"\\\").\n lines: z.array(z.string()),\n added: z.number().int(),\n removed: z.number().int(),\n // Content hash that ignores line numbers, so review progress survives rebases\n // that only shift code around.\n hash: z.string(),\n flags: z.array(HunkFlag),\n // Set when a large hunk was split into pieces; points at the original id.\n parent: z.string().optional(),\n});\nexport type Hunk = z.infer<typeof Hunk>;\n\nexport const Meta = z.object({\n run: z.string(),\n repoRoot: z.string(),\n branch: z.string(),\n base: z.string(),\n baseSha: z.string(),\n mergeBase: z.string(),\n headSha: z.string(),\n working: z.boolean(),\n // What the diff covers. `mergeBase` is the commit it starts from: the\n // merge-base for \"pr\" and \"working\", HEAD for \"staged\" and \"uncommitted\".\n source: z.enum([\"pr\", \"working\", \"staged\", \"uncommitted\"]).optional(),\n createdAt: z.string(),\n stats: z.object({\n files: z.number().int(),\n hunks: z.number().int(),\n added: z.number().int(),\n removed: z.number().int(),\n }),\n});\nexport type Meta = z.infer<typeof Meta>;\n\nexport const ChunkKind = z.enum([\"core\", \"test\", \"mechanical\"]);\nexport const Risk = z.enum([\"low\", \"med\", \"high\"]);\n\nexport const Chunk = z.object({\n id: z.string().min(1),\n title: z.string().min(1),\n intent: z.string().min(1),\n kind: ChunkKind.default(\"core\"),\n hunks: z.array(z.string()),\n dependsOn: z.array(z.string()).default([]),\n reviewFocus: z.array(z.string()).default([]),\n risk: Risk.default(\"low\"),\n // Split mode: the branch this chunk becomes.\n branch: z.string().min(1).optional(),\n});\nexport type Chunk = z.infer<typeof Chunk>;\n\nexport const Strategy = z.object({\n id: z.string().min(1),\n // Optional: the app names \"layers\" and \"features\" itself.\n label: z.string().optional(),\n chunks: z.array(Chunk),\n});\nexport type Strategy = z.infer<typeof Strategy>;\n\nexport const Feature = z.object({\n title: z.string().min(1),\n description: z.string().min(1),\n hunks: z.array(z.string()),\n});\nexport type Feature = z.infer<typeof Feature>;\n\n// Found by the CLI: hunk `from` uses a name that hunk `to` defines.\nexport const AutoLink = z.object({\n from: z.string(),\n to: z.string(),\n symbols: z.array(z.string()),\n});\nexport type AutoLink = z.infer<typeof AutoLink>;\n\n// Written by Claude to name the relationships a reviewer must understand.\nexport const PlanLink = z.object({\n from: z.string(),\n to: z.string(),\n label: z.string().min(1),\n});\nexport type PlanLink = z.infer<typeof PlanLink>;\n\nexport const Plan = z.object({\n // \"split\" turns the plan into stacked PRs for the author instead of a review.\n mode: z.enum([\"review\", \"split\"]).default(\"review\"),\n title: z.string().optional(),\n overview: z.string().optional(),\n strategies: z.array(Strategy).min(1),\n features: z.array(Feature).default([]),\n skim: z.array(z.string()).default([]),\n links: z.array(PlanLink).default([]),\n});\nexport type Plan = z.infer<typeof Plan>;\n\nexport const LineNote = z.object({\n id: z.string(),\n file: z.string(),\n side: z.enum([\"old\", \"new\"]),\n line: z.number().int(),\n text: z.string(),\n at: z.string(),\n});\nexport type LineNote = z.infer<typeof LineNote>;\n\nexport const ReviewState = z.object({\n strategy: z.string().optional(),\n // Hashes of hunks the reviewer has signed off. Stored by content hash rather\n // than by id so that progress carries over when the diff is re-extracted.\n reviewed: z.array(z.string()).default([]),\n // Keyed by \"<strategyId>/<chunkId>\".\n chunkNotes: z.record(z.string()).default({}),\n lineNotes: z.array(LineNote).default([]),\n updatedAt: z.string().optional(),\n});\nexport type ReviewState = z.infer<typeof ReviewState>;\n\nexport const emptyState = (): ReviewState => ReviewState.parse({});\n","import { IGNORABLE_FLAGS, type Chunk, type Feature, type Hunk, type LineNote, type Meta, type Plan, type ReviewState, type Strategy } from \"./schema\";\n\nexport type ChunkStatus = \"done\" | \"partial\" | \"todo\";\n\nexport const isIgnorable = (h: Hunk): boolean =>\n h.flags.some((f) => (IGNORABLE_FLAGS as readonly string[]).includes(f));\n\nexport const changedLines = (hs: readonly Hunk[]): number =>\n hs.reduce((n, h) => n + h.added + h.removed, 0);\n\n// What the diff ends at.\nexport const headLabel = (meta: Meta): string =>\n meta.source === \"staged\" ? \"index\" : meta.working ? \"working tree\" : `HEAD ${meta.headSha.slice(0, 8)}`;\n\nconst branchSlug = (s: string) =>\n s.toLowerCase().replace(/[^a-z0-9]+/g, \"-\").replace(/^-+|-+$/g, \"\").slice(0, 40).replace(/-+$/, \"\") || \"pr\";\n\n// Split mode: `<branch>-split/`, so the stack never collides with the branch it came from.\nexport const defaultPrefix = (branch: string) => (branch === \"HEAD\" ? \"split\" : `${branch}-split`);\n\nexport const branchName = (prefix: string, n: number, c: Chunk) => c.branch ?? `${prefix}/${n}-${branchSlug(c.title)}`;\n\nconst LABELS: Record<string, string> = { layers: \"Foundations first\", features: \"By feature\", split: \"Stacked PRs\" };\nexport const strategyLabel = (s: Strategy): string => LABELS[s.id] ?? s.label ?? s.id;\n\nexport const chunkNoteKey = (strategyId: string, chunkId: string): string => `${strategyId}/${chunkId}`;\n\nexport interface ChunkView {\n chunk: Chunk;\n index: number;\n hunks: Hunk[];\n size: number;\n}\n\nexport interface StrategyView {\n strategy: Strategy;\n chunks: ChunkView[];\n // Explicit skim hunks plus ignorable hunks the plan left out.\n skim: Hunk[];\n}\n\nexport function strategyView(plan: Plan, hunks: readonly Hunk[], strategyId: string | undefined): StrategyView | undefined {\n const strategy = plan.strategies.find((s) => s.id === strategyId) ?? plan.strategies[0];\n if (!strategy) return undefined;\n const byId = new Map(hunks.map((h) => [h.id, h]));\n const placed = new Set<string>();\n const chunks = strategy.chunks.map((chunk, index) => {\n const hs = chunk.hunks.map((id) => byId.get(id)).filter((h): h is Hunk => !!h);\n hs.forEach((h) => placed.add(h.id));\n return { chunk, index, hunks: hs, size: changedLines(hs) };\n });\n const skimIds = new Set(plan.skim);\n const skim = hunks.filter((h) => !placed.has(h.id) && (skimIds.has(h.id) || isIgnorable(h)));\n return { strategy, chunks, skim };\n}\n\nexport function hunkStatus(hs: readonly Hunk[], reviewed: ReadonlySet<string>): ChunkStatus {\n if (hs.length === 0) return \"done\";\n const n = hs.filter((h) => reviewed.has(h.hash)).length;\n return n === hs.length ? \"done\" : n === 0 ? \"todo\" : \"partial\";\n}\n\nexport function setReviewed(state: ReviewState, hs: readonly Hunk[], on: boolean): ReviewState {\n const set = new Set(state.reviewed);\n for (const h of hs) on ? set.add(h.hash) : set.delete(h.hash);\n return { ...state, reviewed: [...set] };\n}\n\n// Chunks (in the given strategy) that hold at least one hunk of the feature.\nexport function featureChunks(feature: Feature, view: StrategyView): ChunkView[] {\n const ids = new Set(feature.hunks);\n return view.chunks.filter((c) => c.chunk.hunks.some((id) => ids.has(id)));\n}\n\nexport function featureHunks(feature: Feature, hunks: readonly Hunk[]): Hunk[] {\n const ids = new Set(feature.hunks);\n return hunks.filter((h) => ids.has(h.id));\n}\n\nexport interface Progress {\n done: number;\n total: number;\n linesDone: number;\n linesTotal: number;\n}\n\nexport function progress(view: StrategyView, reviewed: ReadonlySet<string>): Progress {\n let done = 0;\n let linesDone = 0;\n let linesTotal = 0;\n for (const c of view.chunks) {\n if (hunkStatus(c.hunks, reviewed) === \"done\") done++;\n linesTotal += c.size;\n linesDone += changedLines(c.hunks.filter((h) => reviewed.has(h.hash)));\n }\n return { done, total: view.chunks.length, linesDone, linesTotal };\n}\n\n// Old/new line numbers for every line of a hunk, for rendering gutters and\n// anchoring line notes. \"\\\" lines get neither.\nexport interface NumberedLine {\n text: string;\n kind: \"context\" | \"add\" | \"del\" | \"meta\";\n oldNo?: number;\n newNo?: number;\n}\n\nexport function numberLines(h: Hunk): NumberedLine[] {\n let o = h.oldStart;\n let n = h.newStart;\n return h.lines.map((raw) => {\n const p = raw[0];\n const text = raw.slice(1).replace(/\\r$/, \"\");\n if (p === \"+\") return { text, kind: \"add\", newNo: n++ };\n if (p === \"-\") return { text, kind: \"del\", oldNo: o++ };\n if (p === \"\\\\\") return { text: raw, kind: \"meta\" };\n return { text, kind: \"context\", oldNo: o++, newNo: n++ };\n });\n}\n\n// Line notes that fall inside any of the given hunks.\nexport function notesInHunks(hs: readonly Hunk[], notes: readonly LineNote[]): LineNote[] {\n return notes.filter((n) =>\n hs.some((h) => {\n if (h.file !== n.file) return false;\n const [start, len] = n.side === \"new\" ? [h.newStart, h.newLines] : [h.oldStart, h.oldLines];\n return n.line >= start && n.line < start + len;\n }),\n );\n}\n","import { isIgnorable, changedLines } from \"./derive\";\nimport { Plan, type Hunk } from \"./schema\";\n\nexport const CHUNK_LINE_BUDGET = 400;\n// Non-mechanical hunks larger than this in the skim bucket get a warning, since\n// skimmed code is code nobody reads closely.\nconst SKIM_WARN_LINES = 30;\n\n// Word budgets for plan text. Every word here is one more thing a reviewer\n// reads before the code, so going over is an error, not a warning.\nexport const BUDGET = {\n planTitle: 5,\n overview: 15,\n chunkTitle: 5,\n intent: 10,\n focusItems: 2,\n focusWords: 8,\n featureTitle: 4,\n featureDescription: 8,\n linkLabel: 3,\n} as const;\n\n// Phrases that add words without adding meaning: contrasts with what the code\n// doesn't do (\"by count, not prefix\"), and filler openers.\nconst PADDING: [RegExp, string][] = [\n [/,\\s*not\\b|\\bnot just\\b|\\brather than\\b|\\binstead of\\b/i, \"drop the contrast; say only what it does\"],\n [/^(this|the) (chunk|pr|change|code)\\b/i, \"drop the opener\"],\n [/^(introduces|adds support for|implements)\\b/i, \"drop the opener\"],\n [/\\b(various|several|some|basically|simply|just|really|very)\\b/i, \"drop the filler word\"],\n];\n\n// A loose `git check-ref-format`: catches typos before `split --apply` does.\nexport const validBranch = (b: string): boolean =>\n !/[\\s~^:?*[\\\\]|\\.\\.|@\\{|\\/\\/|^[/.-]|[/.]$|\\.lock$|\\/\\./.test(b) && b !== \"@\";\n\nexport const words = (s: string): number => s.trim().split(/\\s+/).filter(Boolean).length;\n\nexport interface Issue {\n level: \"error\" | \"warning\";\n where: string;\n message: string;\n}\n\nexport interface ValidationResult {\n ok: boolean;\n issues: Issue[];\n plan?: Plan;\n}\n\nexport function validatePlan(raw: unknown, hunks: readonly Hunk[], budget = CHUNK_LINE_BUDGET): ValidationResult {\n const parsed = Plan.safeParse(raw);\n if (!parsed.success) {\n return {\n ok: false,\n issues: parsed.error.issues.map((i) => ({\n level: \"error\" as const,\n where: i.path.length ? i.path.join(\".\") : \"plan\",\n message: i.message,\n })),\n };\n }\n const plan = parsed.data;\n const issues: Issue[] = [];\n const error = (where: string, message: string) => issues.push({ level: \"error\", where, message });\n const warn = (where: string, message: string) => issues.push({ level: \"warning\", where, message });\n\n const tooLong = (where: string, what: string, text: string | undefined, max: number) => {\n if (text === undefined) return;\n if (words(text) > max) error(where, `${what} is ${words(text)} words; max ${max}`);\n for (const [re, fix] of PADDING) {\n const m = re.exec(text);\n if (m) error(where, `${what} \"${m[0].trim()}\": ${fix}`);\n }\n };\n tooLong(\"plan\", \"title\", plan.title, BUDGET.planTitle);\n tooLong(\"plan\", \"overview\", plan.overview, BUDGET.overview);\n\n const byId = new Map(hunks.map((h) => [h.id, h]));\n const describe = (h: Hunk) => `${h.id} (${h.file} +${h.added} -${h.removed})`;\n\n const skim = new Set<string>();\n for (const id of plan.skim) {\n const h = byId.get(id);\n if (!h) error(\"skim\", `unknown hunk id ${id}`);\n else if (skim.has(id)) error(\"skim\", `hunk ${id} listed twice`);\n else {\n skim.add(id);\n if (!isIgnorable(h) && h.added + h.removed > SKIM_WARN_LINES)\n warn(\"skim\", `${describe(h)} is not flagged mechanical; make sure it really only needs a skim`);\n }\n }\n\n const split = plan.mode === \"split\";\n if (split) {\n if (plan.strategies.length !== 1 || plan.strategies[0]!.id !== \"split\")\n error(\"strategies\", 'split mode takes exactly one strategy, with id \"split\"');\n if (plan.skim.length) error(\"skim\", \"split mode has no skim; put every hunk in a PR\");\n } else if (plan.strategies.length < 2)\n warn(\"strategies\", \"only one strategy; the reviewer is meant to choose between a foundations-first and a by-feature order\");\n\n const strategyIds = new Set<string>();\n for (const s of plan.strategies) {\n const where = `strategy ${s.id}`;\n if (strategyIds.has(s.id)) error(where, \"duplicate strategy id\");\n strategyIds.add(s.id);\n\n const seen = new Map<string, string>();\n const chunkIndex = new Map<string, number>();\n const branches = new Set<string>();\n s.chunks.forEach((c, i) => {\n const cw = `${where} / chunk ${c.id}`;\n if (c.branch !== undefined) {\n if (!validBranch(c.branch)) error(cw, `invalid branch name \"${c.branch}\"`);\n else if (branches.has(c.branch)) error(cw, `branch ${c.branch} is used twice`);\n branches.add(c.branch);\n }\n if (chunkIndex.has(c.id)) error(cw, \"duplicate chunk id\");\n chunkIndex.set(c.id, i);\n if (c.hunks.length === 0) error(cw, \"chunk has no hunks\");\n tooLong(cw, \"title\", c.title, BUDGET.chunkTitle);\n tooLong(cw, \"intent\", c.intent, BUDGET.intent);\n if (c.reviewFocus.length > BUDGET.focusItems)\n error(cw, `${c.reviewFocus.length} reviewFocus items; max ${BUDGET.focusItems}`);\n c.reviewFocus.forEach((q, n) => tooLong(cw, `reviewFocus ${n + 1}`, q, BUDGET.focusWords));\n\n const hs: Hunk[] = [];\n for (const id of c.hunks) {\n const h = byId.get(id);\n if (!h) {\n error(cw, `unknown hunk id ${id}`);\n continue;\n }\n if (seen.has(id)) error(cw, `hunk ${id} is already in chunk ${seen.get(id)}`);\n else if (skim.has(id)) error(cw, `hunk ${id} is also in skim`);\n seen.set(id, c.id);\n hs.push(h);\n }\n const size = changedLines(hs);\n if (size > budget) warn(cw, `${size} changed lines exceeds the ${budget}-line budget; consider splitting`);\n\n for (const dep of c.dependsOn) {\n const at = chunkIndex.get(dep);\n if (dep === c.id) error(cw, \"depends on itself\");\n else if (at === undefined) {\n if (s.chunks.some((o) => o.id === dep)) error(cw, `depends on ${dep}, which comes later; reorder the chunks`);\n else error(cw, `depends on unknown chunk ${dep}`);\n }\n }\n });\n\n // A split must carry every change, lockfiles included, or it would be lost.\n const missing = hunks.filter((h) => !seen.has(h.id) && !skim.has(h.id) && (split || !isIgnorable(h)));\n if (missing.length)\n error(where, `hunks not in any ${split ? \"PR\" : \"chunk or skim\"}: ${missing.map(describe).join(\", \")}`);\n }\n\n plan.links.forEach((l, i) => {\n const lw = `link ${i + 1} (${l.from}→${l.to})`;\n for (const id of [l.from, l.to]) if (!byId.has(id)) error(lw, `unknown hunk id ${id}`);\n if (l.from === l.to) error(lw, \"links a hunk to itself\");\n tooLong(lw, \"label\", l.label, BUDGET.linkLabel);\n });\n\n if (plan.features.length === 0 && !split) warn(\"features\", \"no features; the summary page will be empty\");\n const inFeature = new Set<string>();\n plan.features.forEach((f, i) => {\n const fw = `feature ${i + 1} (${f.title})`;\n if (f.hunks.length === 0) error(fw, \"feature has no hunks\");\n tooLong(fw, \"title\", f.title, BUDGET.featureTitle);\n tooLong(fw, \"description\", f.description, BUDGET.featureDescription);\n for (const id of f.hunks) {\n if (!byId.has(id)) error(fw, `unknown hunk id ${id}`);\n inFeature.add(id);\n }\n });\n if (plan.features.length) {\n const orphans = hunks.filter((h) => !inFeature.has(h.id) && !skim.has(h.id) && !isIgnorable(h));\n if (orphans.length)\n warn(\"features\", `hunks not linked to any feature: ${orphans.map((h) => h.id).join(\", \")}`);\n }\n\n return { ok: !issues.some((i) => i.level === \"error\"), issues, plan };\n}\n","import { createHash } from \"node:crypto\";\nimport { mkdir } from \"node:fs/promises\";\nimport type { Hunk, HunkFlag, Meta } from \"../../shared/schema\";\nimport { parseDiff, type FileDiff, type RawHunk } from \"./diff\";\nimport { fileFlags, hasGeneratedMarker, whitespaceOnly } from \"./classify\";\nimport { splitHunk } from \"./split\";\nimport { computeLinks } from \"./symbols\";\nimport * as g from \"./git\";\nimport { ensureRunsDir, runPaths, slug, writeJson, type RunPaths } from \"./runs\";\n\nconst hashOf = (...parts: string[]) => createHash(\"sha1\").update(parts.join(\"\\0\")).digest(\"hex\").slice(0, 16);\n\n// Files with no textual hunks (binary, pure rename, mode change, empty file)\n// still get one placeholder hunk so every change is accounted for.\nfunction placeholder(f: FileDiff): { raw: RawHunk; flag?: HunkFlag } {\n const raw = (header: string): RawHunk => ({ header, oldStart: 0, oldLines: 0, newStart: 0, newLines: 0, lines: [] });\n if (f.binary) return { raw: raw(`Binary file ${f.status}`), flag: \"binary\" };\n if (f.status === \"renamed\") return { raw: raw(`Renamed from ${f.oldFile}`), flag: \"rename\" };\n if (f.status === \"copied\") return { raw: raw(`Copied from ${f.oldFile}`), flag: \"rename\" };\n if (f.modeChange) return { raw: raw(\"File mode changed\"), flag: \"mode\" };\n return { raw: raw(`Empty file ${f.status}`) };\n}\n\nexport function buildHunks(files: FileDiff[], attrGenerated: ReadonlySet<string> = new Set(), splitAt?: number): Hunk[] {\n type Pending = Omit<Hunk, \"id\"> & { pieces: number };\n const pending: Pending[] = [];\n for (const f of files) {\n const flags = fileFlags(f, attrGenerated);\n if (!flags.includes(\"generated\") && hasGeneratedMarker(f)) flags.push(\"generated\");\n const raws = f.hunks.length ? f.hunks.map((h) => ({ raw: h, flag: undefined as HunkFlag | undefined })) : [placeholder(f)];\n for (const { raw, flag } of raws) {\n const hunkFlags = [...flags];\n if (flag && !hunkFlags.includes(flag)) hunkFlags.push(flag);\n if (whitespaceOnly(raw)) hunkFlags.push(\"whitespace-only\");\n // Nobody reads lockfiles or generated code line by line, so don't cut them up.\n const pieces = flags.includes(\"lockfile\") || flags.includes(\"generated\") ? [raw] : splitHunk(raw, splitAt);\n for (const p of pieces) {\n pending.push({\n file: f.file,\n ...(f.oldFile ? { oldFile: f.oldFile } : {}),\n status: f.status,\n header: p.header,\n oldStart: p.oldStart,\n oldLines: p.oldLines,\n newStart: p.newStart,\n newLines: p.newLines,\n lines: p.lines,\n added: p.lines.filter((l) => l[0] === \"+\").length,\n removed: p.lines.filter((l) => l[0] === \"-\").length,\n hash: hashOf(f.file, f.oldFile ?? \"\", f.status, p.header.startsWith(\"@@\") ? \"\" : p.header, ...p.lines),\n flags: hunkFlags,\n pieces: pieces.length,\n });\n }\n }\n }\n\n let n = 0;\n let piece = 0;\n const hunks: Hunk[] = [];\n // Number the original hunks, then suffix pieces of split ones (h012.1, h012.2).\n for (let i = 0; i < pending.length; i++) {\n const { pieces, ...h } = pending[i]!;\n if (piece === 0) n++;\n const base = `h${String(n).padStart(3, \"0\")}`;\n if (pieces > 1) {\n piece++;\n hunks.push({ ...h, id: `${base}.${piece}`, parent: base });\n if (piece === pieces) piece = 0;\n } else hunks.push({ ...h, id: base });\n }\n return hunks;\n}\n\nexport type Source = NonNullable<Meta[\"source\"]>;\n\nexport interface ExtractOptions {\n cwd: string;\n base?: string;\n // Defaults to \"pr\". `working` is the older spelling of source \"working\".\n source?: Source;\n working?: boolean;\n run?: string;\n splitAt?: number;\n}\n\nexport interface ExtractResult {\n paths: RunPaths;\n meta: Meta;\n hunks: Hunk[];\n untracked: string[];\n}\n\nexport async function extract(opts: ExtractOptions): Promise<ExtractResult> {\n const root = await g.repoRoot(opts.cwd);\n const branch = await g.currentBranch(root);\n const source: Source = opts.source ?? (opts.working ? \"working\" : \"pr\");\n const local = source === \"staged\" || source === \"uncommitted\";\n if (local && opts.base) throw new Error(`--${source} always diffs against HEAD; drop the base`);\n const headSha = await g.revParse(root, \"HEAD\");\n const base = local ? \"HEAD\" : (opts.base ?? (await g.defaultBase(root)));\n const baseSha = local ? headSha : await g.revParse(root, base);\n const mb = local ? headSha : await g.mergeBase(root, baseSha, headSha);\n const working = source === \"working\" || source === \"uncommitted\";\n\n const text = await g.diff(root, mb, source === \"staged\" ? \"index\" : working ? undefined : headSha);\n const files = parseDiff(text);\n const attr = await g.generatedByAttr(root, files.map((f) => f.file));\n const hunks = buildHunks(files, attr, opts.splitAt);\n\n const name = slug(opts.run ?? branch);\n const meta: Meta = {\n run: name,\n repoRoot: root,\n branch,\n base,\n baseSha,\n mergeBase: mb,\n headSha,\n working,\n source,\n createdAt: new Date().toISOString(),\n stats: {\n files: files.length,\n hunks: hunks.length,\n added: hunks.reduce((s, h) => s + h.added, 0),\n removed: hunks.reduce((s, h) => s + h.removed, 0),\n },\n };\n\n await ensureRunsDir(root);\n const paths = runPaths(root, name);\n await mkdir(paths.dir, { recursive: true });\n await writeJson(paths.hunks, hunks);\n await writeJson(paths.meta, meta);\n await writeJson(paths.links, computeLinks(hunks));\n const untracked = working ? await g.untracked(root) : [];\n return { paths, meta, hunks, untracked };\n}\n","import type { FileStatus } from \"../../shared/schema\";\n\nexport interface RawHunk {\n header: string;\n oldStart: number;\n oldLines: number;\n newStart: number;\n newLines: number;\n lines: string[];\n}\n\nexport interface FileDiff {\n file: string;\n oldFile?: string;\n status: FileStatus;\n binary: boolean;\n modeChange: boolean;\n hunks: RawHunk[];\n}\n\nconst HUNK_RE = /^@@ -(\\d+)(?:,(\\d+))? \\+(\\d+)(?:,(\\d+))? @@/;\n\n// Undo git's C-style quoting of paths (\"a/caf\\303\\251 file\").\nexport function unquotePath(s: string): string {\n if (!s.startsWith('\"')) return s;\n const bytes: number[] = [];\n const esc: Record<string, number> = { n: 10, t: 9, r: 13, '\"': 34, \"\\\\\": 92, a: 7, b: 8, f: 12, v: 11 };\n for (let i = 1; i < s.length - 1; i++) {\n const ch = s[i]!;\n if (ch !== \"\\\\\") {\n bytes.push(...Buffer.from(ch, \"utf8\"));\n continue;\n }\n const next = s[++i]!;\n if (/[0-7]/.test(next)) {\n bytes.push(parseInt(s.slice(i, i + 3), 8));\n i += 2;\n } else bytes.push(esc[next] ?? next.charCodeAt(0));\n }\n return Buffer.from(bytes).toString(\"utf8\");\n}\n\nconst stripPrefix = (p: string, prefix: string) => (p.startsWith(prefix) ? p.slice(prefix.length) : p);\n\n// \"--- a/foo\" / \"+++ b/foo\" path, or undefined for /dev/null.\nfunction markerPath(line: string): string | undefined {\n let p = line.slice(4).replace(/\\t$/, \"\");\n p = unquotePath(p);\n if (p === \"/dev/null\") return undefined;\n return p.replace(/^[ab]\\//, \"\");\n}\n\n// Paths from \"diff --git a/X b/Y\". Ambiguous when names contain \" b/\", so this\n// is only a fallback for binary and mode-only changes that have no ---/+++ lines.\nfunction gitHeaderPaths(rest: string): [string, string] {\n if (rest.startsWith('\"')) {\n let end = 1;\n while (end < rest.length && !(rest[end] === '\"' && rest[end - 1] !== \"\\\\\")) end++;\n const a = unquotePath(rest.slice(0, end + 1));\n const b = unquotePath(rest.slice(end + 2));\n return [stripPrefix(a, \"a/\"), stripPrefix(b, \"b/\")];\n }\n // Same path on both sides: \"a/P b/P\" has length 2 * len(P) + 5.\n const len = (rest.length - 5) / 2;\n if (Number.isInteger(len) && len > 0) {\n const p = rest.slice(2, 2 + len);\n if (rest === `a/${p} b/${p}`) return [p, p];\n }\n const at = rest.indexOf(\" b/\");\n const b = rest.slice(at + 1);\n return [stripPrefix(rest.slice(0, at), \"a/\"), stripPrefix(unquotePath(b), \"b/\")];\n}\n\nexport function parseDiff(text: string): FileDiff[] {\n const lines = text.split(\"\\n\");\n const files: FileDiff[] = [];\n let cur: FileDiff | undefined;\n let i = 0;\n\n while (i < lines.length) {\n const line = lines[i]!;\n if (line.startsWith(\"diff --git \")) {\n const [a, b] = gitHeaderPaths(line.slice(\"diff --git \".length));\n cur = { file: b, oldFile: a !== b ? a : undefined, status: \"modified\", binary: false, modeChange: false, hunks: [] };\n files.push(cur);\n i++;\n continue;\n }\n if (!cur) {\n i++;\n continue;\n }\n\n if (line.startsWith(\"new file mode\")) cur.status = \"added\";\n else if (line.startsWith(\"deleted file mode\")) cur.status = \"deleted\";\n else if (line.startsWith(\"old mode\") || line.startsWith(\"new mode\")) cur.modeChange = true;\n else if (line.startsWith(\"rename from \")) {\n cur.status = \"renamed\";\n cur.oldFile = unquotePath(line.slice(\"rename from \".length));\n } else if (line.startsWith(\"rename to \")) cur.file = unquotePath(line.slice(\"rename to \".length));\n else if (line.startsWith(\"copy from \")) {\n cur.status = \"copied\";\n cur.oldFile = unquotePath(line.slice(\"copy from \".length));\n } else if (line.startsWith(\"copy to \")) cur.file = unquotePath(line.slice(\"copy to \".length));\n else if (line.startsWith(\"Binary files \") || line === \"GIT binary patch\") cur.binary = true;\n else if (line.startsWith(\"--- \")) {\n const p = markerPath(line);\n if (p && p !== cur.file && cur.status !== \"deleted\") cur.oldFile = p;\n } else if (line.startsWith(\"+++ \")) {\n const p = markerPath(line);\n if (p) cur.file = p;\n } else if (line.startsWith(\"@@\")) {\n const m = HUNK_RE.exec(line);\n if (!m) throw new Error(`malformed hunk header: ${line}`);\n const h: RawHunk = {\n header: line,\n oldStart: Number(m[1]),\n oldLines: m[2] === undefined ? 1 : Number(m[2]),\n newStart: Number(m[3]),\n newLines: m[4] === undefined ? 1 : Number(m[4]),\n lines: [],\n };\n i++;\n // Consume by count rather than by prefix, so content that happens to look\n // like a header (\"@@\" in a removed line) can't end the hunk early.\n let oldLeft = h.oldLines;\n let newLeft = h.newLines;\n while (i < lines.length && (oldLeft > 0 || newLeft > 0 || lines[i]!.startsWith(\"\\\\\"))) {\n let l = lines[i]!;\n if (l === \"\" && (oldLeft > 0 && newLeft > 0)) l = \" \"; // tools that strip trailing spaces\n const p = l[0];\n if (p === \"+\") newLeft--;\n else if (p === \"-\") oldLeft--;\n else if (p === \" \") {\n oldLeft--;\n newLeft--;\n } else if (p !== \"\\\\\") break;\n h.lines.push(l);\n i++;\n }\n cur.hunks.push(h);\n continue;\n }\n i++;\n }\n\n return files;\n}\n","import { basename } from \"node:path\";\nimport type { HunkFlag } from \"../../shared/schema\";\nimport type { FileDiff, RawHunk } from \"./diff\";\n\nconst LOCKFILES = new Set([\n \"package-lock.json\",\n \"npm-shrinkwrap.json\",\n \"pnpm-lock.yaml\",\n \"yarn.lock\",\n \"bun.lockb\",\n \"bun.lock\",\n \"Cargo.lock\",\n \"poetry.lock\",\n \"Pipfile.lock\",\n \"uv.lock\",\n \"composer.lock\",\n \"Gemfile.lock\",\n \"go.sum\",\n \"flake.lock\",\n \"mix.lock\",\n \"pubspec.lock\",\n \"Podfile.lock\",\n \"packages.lock.json\",\n \"gradle.lockfile\",\n]);\n\nconst GENERATED_PATH = [\n /(^|\\/)(dist|build|out|vendor|node_modules|__generated__|generated)\\//,\n /\\.min\\.(js|css)$/,\n /\\.map$/,\n /\\.pb\\.go$/,\n /_pb2(_grpc)?\\.pyi?$/,\n /\\.g\\.dart$/,\n /\\.generated\\.\\w+$/,\n /\\.snap$/,\n];\nconst GENERATED_MARKER = /@generated|Code generated .* DO NOT EDIT|auto-?generated file/i;\n\nconst TEST_PATH = [\n /(^|\\/)(tests?|__tests__|spec|e2e|testdata|fixtures)\\//,\n /\\.(test|spec)\\.\\w+$/,\n /_test\\.(go|py|rb|exs?)$/,\n /(^|\\/)test_[^/]+\\.py$/,\n /Tests?\\.(java|kt|cs|swift)$/,\n];\nconst DOCS_PATH = [/\\.(md|mdx|rst|adoc|txt)$/i, /(^|\\/)docs?\\//];\n\nexport function fileFlags(f: FileDiff, attrGenerated: ReadonlySet<string>): HunkFlag[] {\n const flags: HunkFlag[] = [];\n if (LOCKFILES.has(basename(f.file))) flags.push(\"lockfile\");\n if (attrGenerated.has(f.file) || GENERATED_PATH.some((r) => r.test(f.file))) flags.push(\"generated\");\n if (f.binary) flags.push(\"binary\");\n if (TEST_PATH.some((r) => r.test(f.file))) flags.push(\"test\");\n if (DOCS_PATH.some((r) => r.test(f.file))) flags.push(\"docs\");\n return flags;\n}\n\n// True when the hunk only changes whitespace: the removed and added lines are\n// the same multiset once all whitespace is stripped.\nexport function whitespaceOnly(h: RawHunk): boolean {\n const norm = (l: string) => l.slice(1).replace(/\\s+/g, \"\");\n const del = h.lines.filter((l) => l[0] === \"-\").map(norm).sort();\n const add = h.lines.filter((l) => l[0] === \"+\").map(norm).sort();\n if (del.length === 0 && add.length === 0) return false;\n const a = del.filter((l) => l !== \"\");\n const b = add.filter((l) => l !== \"\");\n return a.length === b.length && a.every((l, i) => l === b[i]);\n}\n\n// Generated-code markers usually sit in the first lines of a new file.\nexport function hasGeneratedMarker(f: FileDiff): boolean {\n const first = f.hunks[0];\n if (!first || first.oldStart > 1 || first.newStart > 1) return false;\n return first.lines.slice(0, 5).some((l) => GENERATED_MARKER.test(l));\n}\n","import type { RawHunk } from \"./diff\";\n\nexport const SPLIT_THRESHOLD = 150;\nconst TARGET = 80;\nconst MIN_PIECE = 30;\n\nconst isBlank = (l: string) => /^[ +-]\\s*$/.test(l);\nconst indent = (l: string) => /^[ +-](\\s*)/.exec(l)?.[1]?.length ?? 0;\n\n// Score how good a place it is to start a new piece at line i (0 = can't).\nfunction cutScore(lines: string[], i: number): number {\n const line = lines[i];\n if (line === undefined || line.startsWith(\"\\\\\")) return 0;\n if (isBlank(line)) return 0;\n let s = 1;\n if (isBlank(lines[i - 1] ?? \"\")) s += 2;\n if (indent(line) === 0) s += 2;\n return s;\n}\n\n// Split a hunk longer than `threshold` lines into consecutive pieces, preferring\n// to cut after blank lines in front of top-level code. Pieces concatenate back\n// to exactly the original lines.\nexport function splitHunk(h: RawHunk, threshold = SPLIT_THRESHOLD): RawHunk[] {\n if (h.lines.length <= threshold) return [h];\n const max = Math.max(threshold, TARGET * 2);\n const cuts: number[] = [];\n let start = 0;\n while (h.lines.length - start > threshold) {\n let best = -1;\n let bestScore = 0;\n for (let i = start + MIN_PIECE; i <= Math.min(start + max, h.lines.length - MIN_PIECE); i++) {\n const s = cutScore(h.lines, i);\n // Prefer higher scores, then whichever is closest to the target size.\n const dist = Math.abs(i - start - TARGET);\n const bestDist = Math.abs(best - start - TARGET);\n if (s > bestScore || (s === bestScore && s > 0 && dist < bestDist)) {\n best = i;\n bestScore = s;\n }\n }\n if (best < 0) {\n best = start + TARGET;\n while (h.lines[best]?.startsWith(\"\\\\\")) best++;\n }\n cuts.push(best);\n start = best;\n }\n\n const pieces: RawHunk[] = [];\n const section = h.header.replace(/^@@ [^@]* @@ ?/, \"\");\n // Next line number on each side. An empty side's start points at the line\n // before the change, following git's convention.\n let o = h.oldLines === 0 ? h.oldStart + 1 : h.oldStart;\n let n = h.newLines === 0 ? h.newStart + 1 : h.newStart;\n let from = 0;\n for (const to of [...cuts, h.lines.length]) {\n const lines = h.lines.slice(from, to);\n let ol = 0;\n let nl = 0;\n for (const l of lines) {\n if (l[0] === \"+\") nl++;\n else if (l[0] === \"-\") ol++;\n else if (l[0] === \" \") {\n ol++;\n nl++;\n }\n }\n const os = ol === 0 ? o - 1 : o;\n const ns = nl === 0 ? n - 1 : n;\n pieces.push({\n header: `@@ -${os},${ol} +${ns},${nl} @@${section ? ` ${section}` : \"\"}`,\n oldStart: os,\n oldLines: ol,\n newStart: ns,\n newLines: nl,\n lines,\n });\n o += ol;\n n += nl;\n from = to;\n }\n return pieces;\n}\n","import { basename, dirname, extname } from \"node:path\";\nimport { isIgnorable } from \"../../shared/derive\";\nimport type { AutoLink, Hunk } from \"../../shared/schema\";\n\n// Declarations that name something another file could use. Deliberately\n// loose and language-agnostic: a missed link costs less than a wrong one.\nconst DECLS = [\n /\\b(?:function\\*?|class|interface|type|enum|def|fn|struct|trait|func|module|object|record)\\s+([A-Za-z_$][\\w$]*)/g,\n /\\bfunc\\s+\\([^)]*\\)\\s*([A-Za-z_]\\w*)/g, // Go methods\n];\n// Top-level bindings only; indented consts are locals.\nconst TOP_BINDING = /^(?:export\\s+(?:default\\s+)?)?(?:const|let|var|val)\\s+([A-Za-z_$][\\w$]*)/;\nconst IDENT = /[A-Za-z_$][\\w$]*/g;\n\nconst KEYWORDS = new Set(\n (\n \"and any as async await bool boolean break case catch char class const continue def default del do else enum \" +\n \"export extends false final finally float fn for from func function get if impl import in int interface is let \" +\n \"match mod module new nil none not null number object or package private protected pub public return self set \" +\n \"static str string struct super switch this throw true try type typeof undefined use val var void while with yield \" +\n \"main init test index value data result error props state\"\n ).split(\" \"),\n);\n\nconst usable = (name: string) => name.length >= 3 && !KEYWORDS.has(name.toLowerCase());\n\nconst CODE = new Set(\n \"ts tsx js jsx mjs cjs mts cts py go rs java kt kts swift rb cs php scala c cc cpp h hpp vue svelte ex exs dart\".split(\" \"),\n);\nconst isCode = (file: string) => CODE.has(extname(file).slice(1).toLowerCase());\n\n// Strings and comments mention names without using them.\nconst stripNoise = (line: string) =>\n line\n .replace(/([\"'`])(?:\\\\.|(?!\\1).)*\\1/g, \" \")\n .replace(/\\/\\/.*$|#.*$|\\/\\*.*?\\*\\//g, \" \");\n\nconst IMPORT_LINE = /\\b(import|from|require|use|include|using)\\b/;\n\n// The name a module is imported by: its file stem, or its folder for index files.\nfunction moduleName(file: string): string {\n const stem = basename(file, extname(file));\n return [\"index\", \"mod\", \"__init__\", \"main\"].includes(stem) ? basename(dirname(file)) : stem;\n}\n\nfunction declared(line: string): string[] {\n if (IMPORT_LINE.test(line)) return []; // `import { type X }` mentions a declaration; it doesn't make one.\n const names: string[] = [];\n for (const re of DECLS) for (const m of line.matchAll(re)) names.push(m[1]!);\n const top = TOP_BINDING.exec(line);\n if (top) names.push(top[1]!);\n return names;\n}\n\n// Names a hunk defines or changes the body of: declarations on added lines,\n// plus the declaration enclosing the first change (the last one in the\n// leading context, else the one git puts in the hunk header).\nexport function definitions(h: Hunk): string[] {\n const names = new Set<string>();\n const firstChange = h.lines.findIndex((l) => l[0] === \"+\" || l[0] === \"-\");\n let enclosing = declared(/^@@ [^@]* @@ ?(.*)$/.exec(h.header)?.[1] ?? \"\");\n h.lines.forEach((raw, i) => {\n if (raw[0] === \"+\") declared(raw.slice(1)).forEach((n) => names.add(n));\n else if (raw[0] === \" \" && i < firstChange) {\n const d = declared(raw.slice(1));\n if (d.length) enclosing = d;\n }\n });\n if (firstChange >= 0) enclosing.forEach((n) => names.add(n));\n return [...names].filter(usable);\n}\n\nfunction uses(h: Hunk): Set<string> {\n const names = new Set<string>();\n for (const raw of h.lines) if (raw[0] === \"+\") for (const m of stripNoise(raw.slice(1)).matchAll(IDENT)) names.add(m[0]);\n return names;\n}\n\n// Tokens on a file's import lines, so a use only counts when the user file\n// actually imports the module that defines the name.\nfunction importTokens(hunks: readonly Hunk[]): Map<string, Set<string>> {\n const out = new Map<string, Set<string>>();\n for (const h of hunks) {\n const set = out.get(h.file) ?? new Set<string>();\n for (const raw of h.lines) {\n if (raw[0] === \"-\" || !IMPORT_LINE.test(raw)) continue;\n for (const t of raw.slice(1).split(/[^A-Za-z0-9_$-]+/)) if (t) set.add(t);\n }\n out.set(h.file, set);\n }\n return out;\n}\n\nfunction connected(user: string, definer: string, imports: Map<string, Set<string>>): boolean {\n if (imports.get(user)?.has(moduleName(definer))) return true;\n // Go files in one package share names without imports.\n return extname(user) === \".go\" && extname(definer) === \".go\" && dirname(user) === dirname(definer);\n}\n\n// Links between hunks in different files: `from` uses a name `to` defines.\nexport function computeLinks(hunks: readonly Hunk[]): AutoLink[] {\n const live = hunks.filter((h) => !isIgnorable(h) && isCode(h.file));\n const imports = importTokens(live);\n const definedIn = new Map<string, Hunk[]>();\n for (const h of live) for (const name of definitions(h)) definedIn.set(name, [...(definedIn.get(name) ?? []), h]);\n // Names defined in many files are too generic to say anything.\n for (const [name, hs] of definedIn) if (new Set(hs.map((h) => h.file)).size > 2) definedIn.delete(name);\n\n const links = new Map<string, AutoLink>();\n for (const from of live) {\n for (const name of uses(from)) {\n for (const to of definedIn.get(name) ?? []) {\n if (to.file === from.file || !connected(from.file, to.file, imports)) continue;\n const key = `${from.id}>${to.id}`;\n const link = links.get(key) ?? { from: from.id, to: to.id, symbols: [] };\n link.symbols.push(name);\n links.set(key, link);\n }\n }\n }\n return [...links.values()].map((l) => ({ ...l, symbols: l.symbols.sort() }));\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst exec = promisify(execFile);\n\nexport async function git(cwd: string, args: string[], input?: string, env?: NodeJS.ProcessEnv): Promise<string> {\n const child = exec(\"git\", [\"-c\", \"core.quotePath=false\", ...args], {\n cwd,\n ...(env ? { env: { ...process.env, ...env } } : {}),\n maxBuffer: 1024 * 1024 * 1024,\n encoding: \"utf8\",\n });\n if (input !== undefined) {\n child.child.stdin?.end(input);\n }\n const { stdout } = await child;\n return stdout;\n}\n\nconst tryGit = (cwd: string, args: string[]) => git(cwd, args).then((s) => s.trim(), () => undefined);\n\nexport const repoRoot = async (cwd: string) => (await git(cwd, [\"rev-parse\", \"--show-toplevel\"])).trim();\n\nexport async function currentBranch(cwd: string): Promise<string> {\n return (await tryGit(cwd, [\"symbolic-ref\", \"--short\", \"-q\", \"HEAD\"])) || \"HEAD\";\n}\n\nexport async function revParse(cwd: string, rev: string): Promise<string> {\n const sha = await tryGit(cwd, [\"rev-parse\", \"--verify\", \"--quiet\", `${rev}^{commit}`]);\n if (!sha) throw new Error(`unknown revision: ${rev}`);\n return sha;\n}\n\n// The branch PRs/MRs usually target: origin/HEAD, else the first common default\n// branch name that exists (remote first, then local).\nexport async function defaultBase(cwd: string): Promise<string> {\n const originHead = await tryGit(cwd, [\"symbolic-ref\", \"--short\", \"-q\", \"refs/remotes/origin/HEAD\"]);\n if (originHead) return originHead;\n for (const name of [\"origin/main\", \"origin/master\", \"origin/develop\", \"main\", \"master\", \"develop\"]) {\n if (await tryGit(cwd, [\"rev-parse\", \"--verify\", \"--quiet\", `${name}^{commit}`])) return name;\n }\n throw new Error(\"could not find a base branch; pass one explicitly, e.g. `spark-joy extract origin/main`\");\n}\n\nexport async function mergeBase(cwd: string, a: string, b: string): Promise<string> {\n const sha = await tryGit(cwd, [\"merge-base\", a, b]);\n if (!sha) throw new Error(`${a} and ${b} have no common history`);\n return sha;\n}\n\n// `to` undefined diffs against the working tree; \"index\" against the index.\nexport function diff(cwd: string, from: string, to: string | undefined): Promise<string> {\n const args = [\n \"diff\",\n \"--no-color\",\n \"--no-ext-diff\",\n \"--no-textconv\",\n \"-M\",\n \"--src-prefix=a/\",\n \"--dst-prefix=b/\",\n from,\n ];\n if (to === \"index\") args.splice(1, 0, \"--cached\");\n else if (to) args.push(to);\n return git(cwd, args);\n}\n\nexport async function untracked(cwd: string): Promise<string[]> {\n const out = await git(cwd, [\"ls-files\", \"--others\", \"--exclude-standard\", \"-z\"]);\n return out.split(\"\\0\").filter(Boolean);\n}\n\n// Files marked linguist-generated in .gitattributes.\nexport async function generatedByAttr(cwd: string, files: string[]): Promise<Set<string>> {\n if (files.length === 0) return new Set();\n const out = await git(cwd, [\"check-attr\", \"-z\", \"--stdin\", \"linguist-generated\"], files.join(\"\\0\") + \"\\0\").catch(() => \"\");\n const parts = out.split(\"\\0\");\n const result = new Set<string>();\n for (let i = 0; i + 2 < parts.length; i += 3) {\n if (parts[i + 2] === \"set\" || parts[i + 2] === \"true\") result.add(parts[i]!);\n }\n return result;\n}\n","import { mkdir, readFile, readdir, rename, stat, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { AutoLink, Hunk, Meta, ReviewState, emptyState } from \"../../shared/schema\";\nimport { z } from \"zod\";\n\nexport const RUNS_DIR = \".spark-joy\";\n\nexport const slug = (s: string) => s.replace(/[^A-Za-z0-9._-]+/g, \"-\").replace(/^-+|-+$/g, \"\") || \"run\";\n\nexport interface RunPaths {\n name: string;\n dir: string;\n hunks: string;\n meta: string;\n plan: string;\n state: string;\n review: string;\n links: string;\n prs: string;\n}\n\nexport function runPaths(root: string, name: string): RunPaths {\n const dir = join(root, RUNS_DIR, name);\n return {\n name,\n dir,\n hunks: join(dir, \"hunks.json\"),\n meta: join(dir, \"meta.json\"),\n plan: join(dir, \"plan.json\"),\n state: join(dir, \"review-state.json\"),\n review: join(dir, \"review.md\"),\n links: join(dir, \"links.json\"),\n prs: join(dir, \"prs.md\"),\n };\n}\n\nexport async function ensureRunsDir(root: string): Promise<void> {\n const dir = join(root, RUNS_DIR);\n await mkdir(dir, { recursive: true });\n // Keep runs out of the user's commits without touching their .gitignore.\n await writeFile(join(dir, \".gitignore\"), \"*\\n\");\n}\n\nconst exists = (p: string) => stat(p).then(() => true, () => false);\n\n// An explicit name wins; otherwise the run for the current branch, falling back\n// to the most recently extracted run.\nexport async function resolveRun(root: string, name: string | undefined, branch: string): Promise<RunPaths> {\n if (name) {\n const p = runPaths(root, name);\n if (!(await exists(p.hunks))) throw new Error(`no run named \"${name}\"; run \\`spark-joy extract\\` first`);\n return p;\n }\n const mine = runPaths(root, slug(branch));\n if (await exists(mine.hunks)) return mine;\n const runs = await listRuns(root);\n if (!runs[0]) throw new Error(\"no runs yet; run `spark-joy extract` first\");\n return runPaths(root, runs[0].name);\n}\n\nexport async function listRuns(root: string): Promise<{ name: string; mtime: number }[]> {\n const dir = join(root, RUNS_DIR);\n const names = await readdir(dir).catch(() => [] as string[]);\n const runs = [];\n for (const name of names) {\n const s = await stat(join(dir, name, \"hunks.json\")).catch(() => undefined);\n if (s) runs.push({ name, mtime: s.mtimeMs });\n }\n return runs.sort((a, b) => b.mtime - a.mtime);\n}\n\nexport async function writeJson(path: string, data: unknown): Promise<void> {\n const tmp = `${path}.${process.pid}.tmp`;\n await writeFile(tmp, JSON.stringify(data, null, 2) + \"\\n\");\n await rename(tmp, path);\n}\n\nexport async function readJson(path: string): Promise<unknown> {\n return JSON.parse(await readFile(path, \"utf8\"));\n}\n\nexport const readHunks = async (p: RunPaths) => z.array(Hunk).parse(await readJson(p.hunks));\nexport const readMeta = async (p: RunPaths) => Meta.parse(await readJson(p.meta));\n\nexport async function readPlanRaw(p: RunPaths): Promise<unknown | undefined> {\n if (!(await exists(p.plan))) return undefined;\n try {\n return await readJson(p.plan);\n } catch (e) {\n throw new Error(`plan.json is not valid JSON: ${(e as Error).message}`);\n }\n}\n\n// Runs extracted before links existed have no file; treat that as no links.\nexport async function readLinks(p: RunPaths): Promise<AutoLink[]> {\n if (!(await exists(p.links))) return [];\n return z.array(AutoLink).parse(await readJson(p.links));\n}\n\nexport async function readState(p: RunPaths): Promise<ReviewState> {\n if (!(await exists(p.state))) return emptyState();\n return ReviewState.parse(await readJson(p.state));\n}\n","import {\n chunkNoteKey,\n featureChunks,\n featureHunks,\n headLabel,\n hunkStatus,\n notesInHunks,\n progress,\n strategyView,\n type ChunkStatus,\n} from \"../../shared/derive\";\nimport type { Hunk, Meta, Plan, ReviewState } from \"../../shared/schema\";\n\nconst MARK: Record<ChunkStatus, string> = {\n done: \"[x]\",\n partial: \"[~]\",\n todo: \"[ ]\",\n};\n\n// Markdown review summary that pastes cleanly into a GitHub or GitLab comment.\nexport function exportMarkdown(meta: Meta, hunks: readonly Hunk[], plan: Plan, state: ReviewState): string {\n const view = strategyView(plan, hunks, state.strategy);\n if (!view) return \"\";\n const reviewed = new Set(state.reviewed);\n const p = progress(view, reviewed);\n const pct = p.linesTotal ? Math.round((100 * p.linesDone) / p.linesTotal) : 100;\n const out: string[] = [];\n\n out.push(`# Review: ${plan.title ?? meta.branch}`, \"\");\n out.push(`${p.done}/${p.total} chunks · ${pct}% lines · \\`${meta.base}\\` → ${headLabel(meta)}`, \"\");\n\n if (plan.features.length) {\n out.push(\"## Features\", \"\");\n for (const f of plan.features) {\n const status = hunkStatus(featureHunks(f, hunks), reviewed);\n const chunks = featureChunks(f, view).map((c) => c.index + 1);\n out.push(`- ${MARK[status]} ${f.title}${chunks.length ? ` (${chunks.join(\", \")})` : \"\"}`);\n }\n out.push(\"\");\n }\n\n out.push(\"## Chunks\", \"\");\n for (const c of view.chunks) {\n const status = hunkStatus(c.hunks, reviewed);\n const changed = status === \"partial\" ? \" · changed since review\" : \"\";\n out.push(`- ${MARK[status]} ${c.index + 1}. ${c.chunk.title} (${c.size})${changed}`);\n const note = state.chunkNotes[chunkNoteKey(view.strategy.id, c.chunk.id)]?.trim();\n if (note) out.push(...note.split(\"\\n\").map((l) => ` > ${l}`));\n for (const n of notesInHunks(c.hunks, state.lineNotes))\n out.push(` - \\`${n.file}:${n.line}\\`${n.side === \"old\" ? \" (old)\" : \"\"} ${n.text.trim()}`);\n }\n if (view.skim.length) out.push(`- ${MARK[hunkStatus(view.skim, reviewed)]} Skim (${view.skim.length} hunks)`);\n out.push(\"\");\n\n const placed = new Set([...view.chunks.flatMap((c) => c.hunks), ...view.skim].map((h) => h.file));\n const stray = state.lineNotes.filter((n) => !placed.has(n.file));\n if (stray.length) {\n out.push(\"## Other notes\", \"\");\n for (const n of stray) out.push(`- \\`${n.file}:${n.line}\\` ${n.text.trim()}`);\n out.push(\"\");\n }\n return out.join(\"\\n\").replace(/\\n{3,}/g, \"\\n\\n\").trimEnd() + \"\\n\";\n}\n\n","import { headLabel, isIgnorable } from \"../../shared/derive\";\nimport type { AutoLink, Hunk, Meta } from \"../../shared/schema\";\n\nconst short = (sha: string) => sha.slice(0, 8);\nconst clip = (s: string, n: number) => (s.length > n ? `${s.slice(0, n - 1)}…` : s);\n\nexport function describeMeta(meta: Meta): string {\n const { files, hunks, added, removed } = meta.stats;\n return `run ${meta.run}: ${meta.base} (${short(meta.mergeBase)}) → ${headLabel(meta)} on ${meta.branch}\\n${files} files, ${hunks} hunks, +${added} −${removed}`;\n}\n\n// First changed line that says something, to hint at what a hunk does.\nfunction gist(h: Hunk): string {\n const line =\n h.lines.find((l) => (l[0] === \"+\" || l[0] === \"-\") && /[A-Za-z0-9]/.test(l) && l.slice(1).trim().length > 3) ?? \"\";\n return clip(line.replace(/\\s+/g, \" \").trim(), 90);\n}\n\nconst section = (h: Hunk) => /^@@ [^@]* @@ ?(.*)$/.exec(h.header)?.[1]?.trim() ?? \"\";\n\nexport function outline(meta: Meta, hunks: readonly Hunk[]): string {\n const out = [describeMeta(meta)];\n const ignorable = hunks.filter(isIgnorable);\n if (ignorable.length) {\n const a = ignorable.reduce((s, h) => s + h.added, 0);\n const r = ignorable.reduce((s, h) => s + h.removed, 0);\n out.push(`${ignorable.length} mechanical hunks (lockfile/generated/binary/whitespace/rename), +${a} −${r}: may be left out of the plan`);\n }\n let file = \"\";\n for (const h of hunks) {\n if (h.file !== file) {\n file = h.file;\n const fh = hunks.filter((x) => x.file === file);\n const a = fh.reduce((s, x) => s + x.added, 0);\n const r = fh.reduce((s, x) => s + x.removed, 0);\n const from = h.oldFile && h.oldFile !== h.file ? ` (from ${h.oldFile})` : \"\";\n out.push(\"\", `${file}${from} [${h.status}] +${a} −${r}`);\n }\n const flags = h.flags.length ? ` {${h.flags.join(\",\")}}` : \"\";\n const sec = section(h);\n const where = /^@@ (.*?) @@/.exec(h.header)?.[1] ?? h.header;\n out.push(` ${h.id.padEnd(9)} ${where.padEnd(22)} +${h.added} −${h.removed}${flags}${sec ? ` in ${clip(sec, 40)}` : \"\"}`);\n const g = gist(h);\n if (g) out.push(` ${g}`);\n }\n return out.join(\"\\n\");\n}\n\n// Expand \"h003..h007\" style ranges against the hunk order.\nexport function expandIds(args: string[], hunks: readonly Hunk[]): string[] {\n const order = hunks.map((h) => h.id);\n const ids: string[] = [];\n for (const arg of args.flatMap((a) => a.split(\",\"))) {\n if (!arg) continue;\n const m = /^(.+)\\.\\.(.+)$/.exec(arg);\n if (m) {\n const from = order.findIndex((id) => id === m[1] || id.startsWith(`${m[1]}.`));\n const toIdx = order.findLastIndex((id) => id === m[2] || id.startsWith(`${m[2]}.`));\n if (from < 0 || toIdx < 0) throw new Error(`unknown range ${arg}`);\n ids.push(...order.slice(from, toIdx + 1));\n } else {\n // A bare parent id selects all of its pieces.\n const match = order.filter((id) => id === arg || id.startsWith(`${arg}.`));\n if (!match.length) throw new Error(`unknown hunk id ${arg}`);\n ids.push(...match);\n }\n }\n return [...new Set(ids)];\n}\n\nexport function showHunks(hunks: readonly Hunk[], ids: readonly string[]): string {\n const byId = new Map(hunks.map((h) => [h.id, h]));\n return ids\n .map((id) => {\n const h = byId.get(id)!;\n const flags = h.flags.length ? ` {${h.flags.join(\",\")}}` : \"\";\n const head = `=== ${h.id} ${h.file} [${h.status}] +${h.added} −${h.removed}${flags}`;\n return [head, h.header, ...h.lines].join(\"\\n\");\n })\n .join(\"\\n\\n\");\n}\n\nexport function showFile(hunks: readonly Hunk[], file: string): string[] {\n return hunks.filter((h) => h.file === file || h.oldFile === file).map((h) => h.id);\n}\n\n// Links grouped by file pair, definer first, for Claude to pick which to label.\nexport function formatLinks(hunks: readonly Hunk[], links: readonly AutoLink[]): string {\n const file = new Map(hunks.map((h) => [h.id, h.file]));\n const pairs = new Map<string, string[]>();\n for (const l of links) {\n const key = `${file.get(l.to)} → ${file.get(l.from)}`;\n pairs.set(key, [...(pairs.get(key) ?? []), `${clip(l.symbols.join(\", \"), 60)} (${l.to}→${l.from})`]);\n }\n if (!pairs.size) return \"no cross-file links found\";\n return [...pairs]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([pair, items]) => [pair, ...items.map((i) => ` ${i}`)].join(\"\\n\"))\n .join(\"\\n\");\n}\n","import { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { extname, join, normalize, sep } from \"node:path\";\nimport { ReviewState } from \"../../shared/schema\";\nimport { validatePlan } from \"../../shared/validate\";\nimport { exportMarkdown } from \"./export\";\nimport { readHunks, readLinks, readMeta, readPlanRaw, readState, writeJson, type RunPaths } from \"./runs\";\n\nconst TYPES: Record<string, string> = {\n \".html\": \"text/html; charset=utf-8\",\n \".js\": \"text/javascript; charset=utf-8\",\n \".css\": \"text/css; charset=utf-8\",\n \".svg\": \"image/svg+xml\",\n \".json\": \"application/json\",\n \".map\": \"application/json\",\n};\n\nconst MAX_BODY = 20 * 1024 * 1024;\n\nasync function body(req: IncomingMessage): Promise<unknown> {\n const chunks: Buffer[] = [];\n let size = 0;\n for await (const c of req) {\n size += (c as Buffer).length;\n if (size > MAX_BODY) throw new Error(\"request too large\");\n chunks.push(c as Buffer);\n }\n return JSON.parse(Buffer.concat(chunks).toString(\"utf8\") || \"{}\");\n}\n\nfunction send(res: ServerResponse, status: number, data: unknown) {\n res.writeHead(status, { \"content-type\": \"application/json\", \"cache-control\": \"no-store\" });\n res.end(JSON.stringify(data));\n}\n\n// Everything the app needs, read fresh from disk on each request so a plan\n// rewritten by Claude shows up on the next reload.\nasync function loadRun(paths: RunPaths) {\n const [meta, hunks, raw, state, links] = await Promise.all([\n readMeta(paths),\n readHunks(paths),\n readPlanRaw(paths),\n readState(paths),\n readLinks(paths),\n ]);\n const validation = raw === undefined ? undefined : validatePlan(raw, hunks);\n return {\n meta,\n hunks,\n plan: validation?.plan,\n issues: validation?.issues ?? [],\n hasPlan: raw !== undefined,\n links,\n state,\n };\n}\n\nexport interface ServeOptions {\n paths: RunPaths;\n appDir: string;\n port: number;\n host?: string;\n}\n\nexport async function serve(opts: ServeOptions): Promise<{ url: string; close: () => Promise<void> }> {\n const { paths, appDir } = opts;\n const host = opts.host ?? \"127.0.0.1\";\n\n let port = opts.port;\n const server = createServer(async (req, res) => {\n try {\n // Refuse other Host names so a DNS-rebinding page can't read the diff.\n const allowed = [`${host}:${port}`, `localhost:${port}`, `127.0.0.1:${port}`];\n if (!allowed.includes(req.headers.host ?? \"\")) return send(res, 403, { error: \"unexpected host\" });\n const url = new URL(req.url ?? \"/\", \"http://localhost\");\n // Requests from other sites can't read responses, but could still write;\n // only accept writes that come from this origin.\n if (req.method !== \"GET\" && req.headers.origin && new URL(req.headers.origin).host !== req.headers.host) {\n return send(res, 403, { error: \"cross-origin request refused\" });\n }\n\n if (url.pathname === \"/api/run\" && req.method === \"GET\") return send(res, 200, await loadRun(paths));\n\n if (url.pathname === \"/api/state\" && req.method === \"PUT\") {\n const state = ReviewState.parse(await body(req));\n state.updatedAt = new Date().toISOString();\n await writeJson(paths.state, state);\n return send(res, 200, state);\n }\n\n if (url.pathname === \"/api/export\" && req.method === \"POST\") {\n const run = await loadRun(paths);\n if (!run.plan) return send(res, 409, { error: \"no valid plan to export\" });\n const markdown = exportMarkdown(run.meta, run.hunks, run.plan, run.state);\n await writeFile(paths.review, markdown);\n return send(res, 200, { path: paths.review, markdown });\n }\n\n if (url.pathname.startsWith(\"/api/\")) return send(res, 404, { error: \"not found\" });\n if (req.method !== \"GET\") return send(res, 405, { error: \"method not allowed\" });\n\n // Static app files, falling back to index.html for client-side routes.\n const rel = normalize(decodeURIComponent(url.pathname)).replace(/^([/\\\\])+/, \"\");\n let file = join(appDir, rel);\n if (!file.startsWith(appDir + sep) && file !== appDir) return send(res, 403, { error: \"forbidden\" });\n let data: Buffer;\n try {\n data = await readFile(file);\n } catch {\n file = join(appDir, \"index.html\");\n data = await readFile(file);\n }\n res.writeHead(200, { \"content-type\": TYPES[extname(file)] ?? \"application/octet-stream\" });\n res.end(data);\n } catch (e) {\n send(res, 400, { error: (e as Error).message });\n }\n });\n\n for (let attempt = 0; ; attempt++) {\n try {\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(port, host, () => {\n server.off(\"error\", reject);\n resolve();\n });\n });\n break;\n } catch (e) {\n if ((e as NodeJS.ErrnoException).code !== \"EADDRINUSE\" || attempt >= 20) throw e;\n port++;\n }\n }\n const address = server.address();\n if (address && typeof address === \"object\") port = address.port;\n return {\n url: `http://${host}:${port}`,\n close: () => new Promise((r) => server.close(() => r())),\n };\n}\n","import { execFile } from \"node:child_process\";\nimport { lstat, readFile, readlink, rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { branchName, changedLines } from \"../../shared/derive\";\nimport type { Chunk, Hunk, Meta, Plan } from \"../../shared/schema\";\nimport * as g from \"./git\";\n\nconst execP = promisify(execFile);\nconst ZERO = \"0\".repeat(40);\n\nexport interface StackPR {\n n: number;\n chunk: Chunk;\n branch: string;\n commit: string;\n lines: number;\n files: number;\n}\n\nexport interface Stack {\n base: string;\n prs: StackPR[];\n}\n\ninterface FileGroup {\n file: string;\n oldFile?: string;\n status: Hunk[\"status\"];\n hunks: Hunk[];\n}\n\ninterface Entry {\n mode: string;\n sha: string;\n}\n\n// Lines with their endings kept, so a missing final newline survives.\nfunction toLines(text: string): string[] {\n const out: string[] = [];\n let i = 0;\n while (i < text.length) {\n const j = text.indexOf(\"\\n\", i);\n if (j < 0) {\n out.push(text.slice(i));\n break;\n }\n out.push(text.slice(i, j + 1));\n i = j + 1;\n }\n return out;\n}\n\nfunction sides(h: Hunk): { old: string[]; new: string[] } {\n const old: string[] = [];\n const neu: string[] = [];\n h.lines.forEach((l, i) => {\n const p = l[0];\n if (p === \"\\\\\") return;\n const text = l.slice(1) + (h.lines[i + 1]?.startsWith(\"\\\\\") ? \"\" : \"\\n\");\n if (p !== \"+\") old.push(text);\n if (p !== \"-\") neu.push(text);\n });\n return { old, new: neu };\n}\n\n// Apply any subset of a file's hunks to its old content. Hunks never overlap\n// and carry exact line numbers, so this needs no fuzz.\nexport function applyHunks(oldText: string, hunks: readonly Hunk[]): string {\n const old = toLines(oldText);\n const out: string[] = [];\n let pos = 0;\n for (const h of [...hunks].sort((a, b) => a.oldStart - b.oldStart)) {\n const start = h.oldLines === 0 ? h.oldStart : h.oldStart - 1;\n const s = sides(h);\n if (start < pos || old.slice(start, start + h.oldLines).join(\"\") !== s.old.join(\"\"))\n throw new Error(`hunk ${h.id} doesn't match ${h.file}; re-run \\`spark-joy extract\\``);\n out.push(...old.slice(pos, start), ...s.new);\n pos = start + h.oldLines;\n }\n out.push(...old.slice(pos));\n return out.join(\"\");\n}\n\nfunction groupByFile(hunks: readonly Hunk[]): FileGroup[] {\n const groups = new Map<string, FileGroup>();\n for (const h of hunks) {\n const key = `${h.oldFile ?? \"\"}\\0${h.file}`;\n let f = groups.get(key);\n if (!f) groups.set(key, (f = { file: h.file, oldFile: h.oldFile, status: h.status, hunks: [] }));\n f.hunks.push(h);\n }\n return [...groups.values()];\n}\n\nasync function treeEntry(root: string, rev: string, path: string): Promise<Entry | undefined> {\n const out = await g.git(root, [\"ls-tree\", \"-z\", rev, \"--\", path]);\n const m = /^(\\d+) \\w+ ([0-9a-f]+)\\t/.exec(out);\n return m ? { mode: m[1]!, sha: m[2]! } : undefined;\n}\n\n// Where the file ends up: HEAD, the index, or the working tree.\nasync function targetEntry(root: string, meta: Meta, path: string): Promise<Entry> {\n const source = meta.source ?? (meta.working ? \"working\" : \"pr\");\n let e: Entry | undefined;\n if (source === \"pr\") e = await treeEntry(root, meta.headSha, path);\n else if (source === \"staged\") {\n const m = /^(\\d+) ([0-9a-f]+) 0\\t/.exec(await g.git(root, [\"ls-files\", \"-s\", \"-z\", \"--\", path]));\n if (m) e = { mode: m[1]!, sha: m[2]! };\n } else {\n const full = join(root, path);\n const st = await lstat(full);\n const content = st.isSymbolicLink() ? await readlink(full) : await readFile(full);\n const mode = st.isSymbolicLink() ? \"120000\" : st.mode & 0o111 ? \"100755\" : \"100644\";\n // hash-object takes stdin as text through git(); binary content goes via the path.\n const sha = st.isSymbolicLink()\n ? (await g.git(root, [\"hash-object\", \"-w\", \"--stdin\"], content as string)).trim()\n : (await g.git(root, [\"hash-object\", \"-w\", \"--\", path])).trim();\n e = { mode, sha };\n }\n if (!e) throw new Error(`${path} is missing from the ${source} source; re-run \\`spark-joy extract\\``);\n return e;\n}\n\nconst blob = async (root: string, text: string) => (await g.git(root, [\"hash-object\", \"-w\", \"--stdin\"], text)).trim();\n\n// Index lines that bring one file to its state once `done` hunks are applied.\nasync function fileUpdate(root: string, meta: Meta, f: FileGroup, done: ReadonlySet<string>): Promise<string[]> {\n const applied = f.hunks.filter((h) => done.has(h.id));\n const all = applied.length === f.hunks.length;\n const textual = applied.filter((h) => h.lines.length > 0);\n const oldPath = f.oldFile ?? f.file;\n const remove = (p: string) => `0 ${ZERO}\\t${p}`;\n const lines: string[] = [];\n if (f.status === \"renamed\") lines.push(remove(oldPath));\n if (f.status === \"deleted\" && all) return [remove(f.file)];\n\n const old = f.status === \"added\" ? undefined : await treeEntry(root, meta.mergeBase, oldPath);\n // Binary files and mode changes have no text to apply: take the final file.\n const binary = f.hunks.some((h) => h.flags.includes(\"binary\"));\n const target = f.status === \"deleted\" ? undefined : await targetEntry(root, meta, f.file);\n if (binary || (all && f.hunks.every((h) => h.lines.length === 0))) {\n lines.push(`${target!.mode} ${target!.sha}\\t${f.file}`);\n return lines;\n }\n const oldText = old ? await g.git(root, [\"cat-file\", \"blob\", old.sha]) : \"\";\n const sha = await blob(root, applyHunks(oldText, textual));\n const mode = all && target ? target.mode : (old?.mode ?? target!.mode);\n lines.push(`${mode} ${sha}\\t${f.file}`);\n return lines;\n}\n\nexport interface BuildOptions {\n root: string;\n meta: Meta;\n hunks: readonly Hunk[];\n plan: Plan;\n prefix: string;\n indexFile: string;\n}\n\n// Commit each PR on top of the last through a temporary index. The working\n// tree, the real index and every branch stay untouched.\nexport async function buildStack(o: BuildOptions): Promise<Stack> {\n const { root, meta, hunks } = o;\n const strategy = o.plan.strategies.find((s) => s.id === \"split\");\n if (o.plan.mode !== \"split\" || !strategy) throw new Error('not a split plan; set \"mode\": \"split\"');\n const head = await g.revParse(root, \"HEAD\");\n if (head !== meta.headSha) throw new Error(\"HEAD moved since extract; re-run `spark-joy extract`\");\n\n const byId = new Map(hunks.map((h) => [h.id, h]));\n const files = groupByFile(hunks);\n const env = { GIT_INDEX_FILE: o.indexFile };\n await rm(o.indexFile, { force: true });\n await g.git(root, [\"read-tree\", meta.mergeBase], undefined, env);\n\n const done = new Set<string>();\n const prs: StackPR[] = [];\n let parent = meta.mergeBase;\n try {\n for (const [i, chunk] of strategy.chunks.entries()) {\n for (const id of chunk.hunks) done.add(id);\n const ids = new Set(chunk.hunks);\n const touched = files.filter((f) => f.hunks.some((h) => ids.has(h.id)));\n const updates = (await Promise.all(touched.map((f) => fileUpdate(root, meta, f, done)))).flat();\n await g.git(root, [\"update-index\", \"-z\", \"--index-info\"], updates.map((u) => `${u}\\0`).join(\"\"), env);\n const tree = (await g.git(root, [\"write-tree\"], undefined, env)).trim();\n const message = `${chunk.title}\\n\\n${chunk.intent}\\n`;\n const commit = (await g.git(root, [\"commit-tree\", tree, \"-p\", parent], message)).trim();\n prs.push({\n n: i + 1,\n chunk,\n branch: branchName(o.prefix, i + 1, chunk),\n commit,\n lines: changedLines(chunk.hunks.map((id) => byId.get(id)!).filter(Boolean)),\n files: touched.length,\n });\n parent = commit;\n }\n } finally {\n await rm(o.indexFile, { force: true });\n }\n await verify(root, meta, parent);\n return { base: meta.mergeBase, prs };\n}\n\n// The top of the stack must hold exactly the changes that were split.\nasync function verify(root: string, meta: Meta, top: string): Promise<void> {\n const source = meta.source ?? (meta.working ? \"working\" : \"pr\");\n let differ: string;\n if (source === \"pr\" || source === \"staged\") {\n const want = source === \"pr\" ? `${meta.headSha}^{tree}` : (await g.git(root, [\"write-tree\"])).trim();\n differ = await g.git(root, [\"diff\", \"--name-only\", \"--no-ext-diff\", \"--no-textconv\", `${top}^{tree}`, want]);\n } else differ = await g.git(root, [\"diff\", \"--name-only\", \"--no-ext-diff\", \"--no-textconv\", top]);\n const files = differ.split(\"\\n\").filter(Boolean);\n if (files.length)\n throw new Error(\n `the stack doesn't reproduce your changes in ${files.join(\", \")}; re-run \\`spark-joy extract\\`. No branches were created`,\n );\n}\n\n// All or nothing: check every branch first, then create them.\nexport async function createBranches(root: string, stack: Stack, force: boolean): Promise<void> {\n const current = await g.currentBranch(root);\n const taken: string[] = [];\n for (const pr of stack.prs) {\n const ok = await g.git(root, [\"check-ref-format\", \"--branch\", pr.branch]).then(() => true, () => false);\n if (!ok) throw new Error(`invalid branch name ${pr.branch}`);\n if (pr.branch === current) throw new Error(`${pr.branch} is checked out; pick another --prefix`);\n const exists = await g.git(root, [\"rev-parse\", \"--verify\", \"--quiet\", `refs/heads/${pr.branch}`]).then(() => true, () => false);\n if (exists) taken.push(pr.branch);\n }\n if (taken.length && !force) throw new Error(`branches already exist: ${taken.join(\", \")}; pass --force to move them`);\n for (const pr of stack.prs) {\n const args = [\"update-ref\", \"-m\", \"spark-joy split\", `refs/heads/${pr.branch}`, pr.commit];\n await g.git(root, force ? args : [...args, ZERO]);\n }\n}\n\nexport interface CheckResult {\n n: number;\n ok: boolean;\n output: string;\n}\n\n// Run `cmd` on each PR in a throwaway worktree.\nexport async function checkStack(root: string, stack: Stack, cmd: string, tmp: string): Promise<CheckResult[]> {\n const results: CheckResult[] = [];\n for (const pr of stack.prs) {\n const dir = join(tmp, `pr-${pr.n}`);\n await g.git(root, [\"worktree\", \"add\", \"--detach\", \"--quiet\", dir, pr.commit]);\n try {\n const r = await execP(cmd, { cwd: dir, shell: true, maxBuffer: 64 * 1024 * 1024 }).then(\n (out) => ({ ok: true, out }),\n (e: { stdout?: string; stderr?: string }) => ({ ok: false, out: { stdout: e.stdout ?? \"\", stderr: e.stderr ?? \"\" } }),\n );\n results.push({ n: pr.n, ok: r.ok, output: `${r.out.stdout}${r.out.stderr}` });\n } finally {\n await g.git(root, [\"worktree\", \"remove\", \"--force\", dir]).catch(() => undefined);\n }\n }\n return results;\n}\n\nexport function prsMarkdown(meta: Meta, stack: Stack): string {\n const target = meta.source === \"staged\" || meta.source === \"uncommitted\" ? meta.branch : meta.base.replace(/^origin\\//, \"\");\n const out: string[] = [];\n stack.prs.forEach((pr, i) => {\n const c = pr.chunk;\n out.push(`## ${pr.n}. ${c.title}`, \"\");\n out.push(`\\`${pr.branch}\\` → \\`${i === 0 ? target : stack.prs[i - 1]!.branch}\\` · ${pr.lines} lines`, \"\");\n out.push(c.intent, \"\");\n for (const q of c.reviewFocus) out.push(`- ${q}`);\n if (c.reviewFocus.length) out.push(\"\");\n // The PR below is implied by the stack; name only the ones further down.\n const deps = c.dependsOn.map((d) => stack.prs.find((p) => p.chunk.id === d)?.n).filter((n) => n && n < pr.n - 1);\n if (deps.length) out.push(`Depends on ${deps.map((n) => `PR ${n}`).join(\", \")}.`, \"\");\n });\n return out.join(\"\\n\");\n}\n"],"mappings":"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","names":["mkdir","readFile","rm","writeFile","join","mkdir","b","section","basename","basename","z","mkdir","untracked","readFile","writeFile","extname","join","run","writeFile","join","readFile","extname","execFile","readFile","join","promisify","promisify","execFile","join","readFile","exists","readFile","join","writeFile","rm","mkdir"]}
|