@spader/spall-tui 1.0.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/dist/App.js +3636 -0
- package/dist/App.js.map +39 -0
- package/dist/bash-nbhfht5r.scm +56 -0
- package/dist/c-4zy7d3fw.scm +81 -0
- package/dist/c_sharp-tb7n62t2.scm +212 -0
- package/dist/cpp-stxr9ffp.scm +77 -0
- package/dist/css-b1p1h6ys.scm +76 -0
- package/dist/dart-t89b32ej.scm +13 -0
- package/dist/elisp-ax9wx1b9.scm +72 -0
- package/dist/elixir-77300bss.scm +223 -0
- package/dist/elm-k2q5knqb.scm +76 -0
- package/dist/embedded_template-k7ypjkba.scm +12 -0
- package/dist/go-9wx8m64k.scm +123 -0
- package/dist/html-g95aq3vw.scm +13 -0
- package/dist/index.js +3635 -0
- package/dist/index.js.map +39 -0
- package/dist/java-wasz6t7a.scm +149 -0
- package/dist/javascript-cswtymww.scm +204 -0
- package/dist/json-pf4aw8w1.scm +16 -0
- package/dist/kotlin-m6cj2y7m.scm +380 -0
- package/dist/lib/git.js +117 -0
- package/dist/lib/git.js.map +10 -0
- package/dist/lua-7h6jk3pd.scm +204 -0
- package/dist/objc-6yjdwy1z.scm +216 -0
- package/dist/ocaml-jfj520qk.scm +148 -0
- package/dist/parsers/index.d.ts +8 -0
- package/dist/parsers/index.d.ts.map +1 -0
- package/dist/php-bds7v5h1.scm +203 -0
- package/dist/python-k2cbtg72.scm +137 -0
- package/dist/ql-qs2vxbeq.scm +154 -0
- package/dist/ruby-3ybh5bp2.scm +154 -0
- package/dist/rust-edtnatpk.scm +161 -0
- package/dist/scala-91f2sb1z.scm +260 -0
- package/dist/src/App.d.ts +6 -0
- package/dist/src/App.d.ts.map +1 -0
- package/dist/src/Review.d.ts +6 -0
- package/dist/src/Review.d.ts.map +1 -0
- package/dist/src/components/CommandPalette.d.ts +2 -0
- package/dist/src/components/CommandPalette.d.ts.map +1 -0
- package/dist/src/components/DiffPanel.d.ts +16 -0
- package/dist/src/components/DiffPanel.d.ts.map +1 -0
- package/dist/src/components/EditorPanel.d.ts +9 -0
- package/dist/src/components/EditorPanel.d.ts.map +1 -0
- package/dist/src/components/ErrorFallback.d.ts +6 -0
- package/dist/src/components/ErrorFallback.d.ts.map +1 -0
- package/dist/src/components/HalfLineShadow.d.ts +18 -0
- package/dist/src/components/HalfLineShadow.d.ts.map +1 -0
- package/dist/src/components/index.d.ts +7 -0
- package/dist/src/components/index.d.ts.map +1 -0
- package/dist/src/components/sidebar/CommentList.d.ts +10 -0
- package/dist/src/components/sidebar/CommentList.d.ts.map +1 -0
- package/dist/src/components/sidebar/FileList.d.ts +13 -0
- package/dist/src/components/sidebar/FileList.d.ts.map +1 -0
- package/dist/src/components/sidebar/PatchList.d.ts +14 -0
- package/dist/src/components/sidebar/PatchList.d.ts.map +1 -0
- package/dist/src/components/sidebar/ProjectStatus.d.ts +7 -0
- package/dist/src/components/sidebar/ProjectStatus.d.ts.map +1 -0
- package/dist/src/components/sidebar/Section.d.ts +12 -0
- package/dist/src/components/sidebar/Section.d.ts.map +1 -0
- package/dist/src/components/sidebar/ServerStatus.d.ts +2 -0
- package/dist/src/components/sidebar/ServerStatus.d.ts.map +1 -0
- package/dist/src/components/sidebar/index.d.ts +7 -0
- package/dist/src/components/sidebar/index.d.ts.map +1 -0
- package/dist/src/context/command.d.ts +10 -0
- package/dist/src/context/command.d.ts.map +1 -0
- package/dist/src/context/dialog.d.ts +11 -0
- package/dist/src/context/dialog.d.ts.map +1 -0
- package/dist/src/context/exit.d.ts +10 -0
- package/dist/src/context/exit.d.ts.map +1 -0
- package/dist/src/context/review.d.ts +47 -0
- package/dist/src/context/review.d.ts.map +1 -0
- package/dist/src/context/server.d.ts +10 -0
- package/dist/src/context/server.d.ts.map +1 -0
- package/dist/src/context/sidebar.d.ts +13 -0
- package/dist/src/context/sidebar.d.ts.map +1 -0
- package/dist/src/context/theme.d.ts +47 -0
- package/dist/src/context/theme.d.ts.map +1 -0
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/lib/diff.d.ts +24 -0
- package/dist/src/lib/diff.d.ts.map +1 -0
- package/dist/src/lib/git.d.ts +15 -0
- package/dist/src/lib/git.d.ts.map +1 -0
- package/dist/src/lib/keybind.d.ts +23 -0
- package/dist/src/lib/keybind.d.ts.map +1 -0
- package/dist/src/lib/tree.d.ts +39 -0
- package/dist/src/lib/tree.d.ts.map +1 -0
- package/dist/src/store/comment.d.ts +20 -0
- package/dist/src/store/comment.d.ts.map +1 -0
- package/dist/src/store/db.d.ts +6 -0
- package/dist/src/store/db.d.ts.map +1 -0
- package/dist/src/store/index.d.ts +7 -0
- package/dist/src/store/index.d.ts.map +1 -0
- package/dist/src/store/patch.d.ts +22 -0
- package/dist/src/store/patch.d.ts.map +1 -0
- package/dist/src/store/repo.d.ts +8 -0
- package/dist/src/store/repo.d.ts.map +1 -0
- package/dist/src/store/review.d.ts +18 -0
- package/dist/src/store/review.d.ts.map +1 -0
- package/dist/store/index.js +303 -0
- package/dist/store/index.js.map +14 -0
- package/dist/swift-a4tt704b.scm +336 -0
- package/dist/toml-hcqfz0bg.scm +53 -0
- package/dist/tsx-c3k3mmc9.scm +239 -0
- package/dist/typescript-hz4pg6ze.scm +239 -0
- package/dist/vue-xbeea1aj.scm +9 -0
- package/dist/yaml-mbfb25g0.scm +79 -0
- package/dist/zig-ds3q8m26.scm +283 -0
- package/package.json +74 -0
package/dist/App.js.map
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/lib/git.ts", "../src/store/db.ts", "../src/store/repo.ts", "../src/store/review.ts", "../src/store/patch.ts", "../src/store/comment.ts", "../src/App.tsx", "../src/Review.tsx", "../src/components/DiffPanel.tsx", "../src/lib/diff.ts", "../src/context/theme.tsx", "../src/components/HalfLineShadow.tsx", "../src/components/EditorPanel.tsx", "../src/context/review.tsx", "../src/context/server.tsx", "../src/components/ErrorFallback.tsx", "../src/components/CommandPalette.tsx", "../src/context/command.tsx", "../src/context/dialog.tsx", "../src/lib/keybind.ts", "../src/components/sidebar/FileList.tsx", "../src/context/sidebar.tsx", "../src/components/sidebar/Section.tsx", "../src/components/sidebar/CommentList.tsx", "../src/components/sidebar/PatchList.tsx", "../src/components/sidebar/ServerStatus.tsx", "../src/components/sidebar/ProjectStatus.tsx", "../src/lib/tree.ts", "../src/context/exit.tsx", "../parsers/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import { $ } from \"bun\";\n\nexport namespace Git {\n export interface Entry {\n file: string;\n content: string;\n isNew: boolean;\n isDeleted: boolean;\n }\n\n export async function root(startPath: string): Promise<string | null> {\n try {\n const result =\n await $`git -C ${startPath} rev-parse --show-toplevel`.quiet();\n return result.stdout.toString().trim() || null;\n } catch {\n return null;\n }\n }\n\n export async function head(repoPath: string): Promise<string | null> {\n try {\n const result = await $`git -C ${repoPath} rev-parse HEAD`.quiet();\n return result.stdout.toString().trim() || null;\n } catch {\n return null;\n }\n }\n\n export async function diff(repoPath: string): Promise<string> {\n const e = await entries(repoPath);\n return e.map((x) => x.content).join(\"\\n\");\n }\n\n export async function hash(repoPath: string): Promise<number> {\n const trackedResult =\n await $`git -C ${repoPath} diff HEAD --name-only --relative`.quiet();\n const untrackedResult =\n await $`git -C ${repoPath} ls-files --others --exclude-standard`.quiet();\n const combined =\n trackedResult.stdout.toString() +\n \"\\0\" +\n untrackedResult.stdout.toString();\n return Number(Bun.hash(combined));\n }\n\n export async function entries(repoPath: string): Promise<Entry[]> {\n const context = 0\n const result: Entry[] = [];\n const filesResult =\n await $`git -C ${repoPath} diff -U${context} HEAD --name-only --relative`.quiet();\n const filesOutput = filesResult.stdout.toString().trim();\n const trackedFiles = filesOutput\n ? filesOutput.split(\"\\n\").filter(Boolean)\n : [];\n\n const deletedResult =\n await $`git -C ${repoPath} diff -U${context} HEAD --name-only --diff-filter=D --relative`.quiet();\n const deletedOutput = deletedResult.stdout.toString().trim();\n const deletedFiles = new Set(\n deletedOutput ? deletedOutput.split(\"\\n\").filter(Boolean) : [],\n );\n\n for (const file of trackedFiles) {\n const diffResult =\n await $`git -C ${repoPath} diff -U${context} HEAD -- ${file}`.quiet();\n const content = diffResult.stdout.toString();\n const isDeleted = deletedFiles.has(file);\n result.push({ file, content, isNew: false, isDeleted });\n }\n\n const untrackedResult =\n await $`git -C ${repoPath} ls-files --others --exclude-standard`.quiet();\n const untrackedOutput = untrackedResult.stdout.toString().trim();\n const untrackedFiles = untrackedOutput\n ? untrackedOutput.split(\"\\n\").filter(Boolean)\n : [];\n\n for (const file of untrackedFiles) {\n const fileContent = await Bun.file(`${repoPath}/${file}`).text();\n const lines = fileContent.split(\"\\n\");\n const diffLines = lines.map((line) => `+${line}`);\n const content = `diff --git a/${file} b/${file}\nnew file mode 100644\n--- /dev/null\n+++ b/${file}\n@@ -0,0 +1,${lines.length} @@\n${diffLines.join(\"\\n\")}`;\n result.push({ file, content, isNew: true, isDeleted: false });\n }\n\n return result;\n }\n\n export function lines(diffContent: string): number {\n if (!diffContent) return 0;\n const allLines = diffContent.split(\"\\n\");\n let count = 0;\n let inHunk = false;\n for (const line of allLines) {\n if (line.startsWith(\"@@\")) {\n inHunk = true;\n continue;\n }\n if (!inHunk) continue;\n const firstChar = line[0];\n if (firstChar === \" \" || firstChar === \"+\" || firstChar === \"-\") {\n count++;\n }\n }\n return count;\n }\n}\n",
|
|
6
|
+
"import { Database } from \"bun:sqlite\";\nimport { mkdirSync, existsSync } from \"fs\";\nimport { dirname, join } from \"path\";\nimport { Config } from \"@spader/spall-core/config\";\n\nconst DB_PATH = join(Config.get().dirs.data, \"tui.db\");\n\nconst CREATE_REPOS_TABLE = `\n CREATE TABLE IF NOT EXISTS repos (\n id INTEGER PRIMARY KEY,\n path TEXT NOT NULL UNIQUE\n )\n`;\n\nconst CREATE_REVIEWS_TABLE = `\n CREATE TABLE IF NOT EXISTS reviews (\n id INTEGER PRIMARY KEY,\n repo INTEGER NOT NULL,\n commit_sha TEXT NOT NULL,\n name TEXT,\n created_at INTEGER NOT NULL,\n FOREIGN KEY (repo) REFERENCES repos(id)\n )\n`;\n\nconst CREATE_PATCHES_TABLE = `\n CREATE TABLE IF NOT EXISTS patches (\n id INTEGER PRIMARY KEY,\n review INTEGER NOT NULL,\n seq INTEGER NOT NULL,\n hash TEXT NOT NULL,\n content TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n FOREIGN KEY (review) REFERENCES reviews(id),\n UNIQUE (review, seq)\n )\n`;\n\nconst CREATE_REVIEW_COMMENTS_TABLE = `\n CREATE TABLE IF NOT EXISTS review_comments (\n id INTEGER PRIMARY KEY,\n review INTEGER NOT NULL,\n note_id INTEGER NOT NULL,\n file TEXT NOT NULL,\n patch_id INTEGER NOT NULL,\n start_row INTEGER NOT NULL,\n end_row INTEGER NOT NULL,\n created_at INTEGER NOT NULL,\n FOREIGN KEY (review) REFERENCES reviews(id)\n )\n`;\n\nlet db: Database | null = null;\n\nexport function path(): string {\n return DB_PATH;\n}\n\nexport function init(): Database {\n if (db) return db;\n\n const dir = dirname(DB_PATH);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n db = new Database(DB_PATH);\n db.exec(CREATE_REPOS_TABLE);\n db.exec(CREATE_REVIEWS_TABLE);\n db.exec(CREATE_PATCHES_TABLE);\n db.exec(CREATE_REVIEW_COMMENTS_TABLE);\n\n return db;\n}\n\nexport function get(): Database {\n if (!db) {\n throw new Error(\"Store not initialized. Call init() first.\");\n }\n return db;\n}\n\nexport function close(): void {\n if (db) {\n db.close();\n db = null;\n }\n}\n",
|
|
7
|
+
"import * as db from \"./db\";\n\ntype Row = {\n id: number;\n path: string;\n};\n\nexport type Info = {\n id: number;\n path: string;\n};\n\nexport function create(path: string): Info {\n const row = db\n .get()\n .prepare(`INSERT INTO repos (path) VALUES (?) RETURNING id`)\n .get(path) as { id: number };\n return { id: row.id, path };\n}\n\nexport function getByPath(path: string): Info | null {\n const row = db\n .get()\n .prepare(`SELECT * FROM repos WHERE path = ?`)\n .get(path) as Row | null;\n if (!row) return null;\n return { id: row.id, path: row.path };\n}\n\nexport function getOrCreate(path: string): Info {\n const existing = getByPath(path);\n if (existing) return existing;\n return create(path);\n}\n",
|
|
8
|
+
"import * as db from \"./db\";\n\ntype Row = {\n id: number;\n repo: number;\n commit_sha: string;\n name: string | null;\n created_at: number;\n};\n\nexport type Info = {\n id: number;\n repo: number;\n commitSha: string;\n name: string | null;\n createdAt: number;\n};\n\nfunction rowToInfo(row: Row): Info {\n return {\n id: row.id,\n repo: row.repo,\n commitSha: row.commit_sha,\n name: row.name,\n createdAt: row.created_at,\n };\n}\n\nexport function create(input: {\n repo: number;\n commitSha: string;\n name?: string;\n}): Info {\n const createdAt = Date.now();\n\n const row = db\n .get()\n .prepare(\n `INSERT INTO reviews (repo, commit_sha, name, created_at) \n VALUES (?, ?, ?, ?) RETURNING *`,\n )\n .get(input.repo, input.commitSha, input.name ?? null, createdAt) as Row;\n\n return rowToInfo(row);\n}\n\nexport function list(repo: number): Info[] {\n const rows = db\n .get()\n .prepare(`SELECT * FROM reviews WHERE repo = ? ORDER BY created_at DESC`)\n .all(repo) as Row[];\n\n return rows.map(rowToInfo);\n}\n\nexport function get(id: number): Info | null {\n const row = db\n .get()\n .prepare(`SELECT * FROM reviews WHERE id = ?`)\n .get(id) as Row | null;\n\n if (!row) return null;\n return rowToInfo(row);\n}\n\nexport function latest(repo: number): Info | null {\n const row = db\n .get()\n .prepare(\n `SELECT * FROM reviews WHERE repo = ? ORDER BY created_at DESC LIMIT 1`,\n )\n .get(repo) as Row | null;\n\n if (!row) return null;\n return rowToInfo(row);\n}\n\nexport function getByRepoAndCommit(\n repo: number,\n commitSha: string,\n): Info | null {\n const row = db\n .get()\n .prepare(`SELECT * FROM reviews WHERE repo = ? AND commit_sha = ?`)\n .get(repo, commitSha) as Row | null;\n\n if (!row) return null;\n return rowToInfo(row);\n}\n\nexport function getOrCreate(repo: number, commitSha: string): Info {\n const existing = getByRepoAndCommit(repo, commitSha);\n if (existing) return existing;\n return create({ repo, commitSha });\n}\n",
|
|
9
|
+
"import * as db from \"./db\";\n\ntype Row = {\n id: number;\n review: number;\n seq: number;\n hash: string;\n content: string;\n created_at: number;\n};\n\nexport type Info = {\n id: number;\n review: number;\n seq: number;\n hash: string;\n content: string;\n createdAt: number;\n};\n\nfunction rowToInfo(row: Row): Info {\n return {\n id: row.id,\n review: row.review,\n seq: row.seq,\n hash: row.hash,\n content: row.content,\n createdAt: row.created_at,\n };\n}\n\nexport function create(input: {\n review: number;\n seq: number;\n hash: string;\n content: string;\n}): Info {\n const row = db\n .get()\n .prepare(\n `INSERT INTO patches (review, seq, hash, content, created_at)\n VALUES (?, ?, ?, ?, ?) RETURNING *`,\n )\n .get(input.review, input.seq, input.hash, input.content, Date.now()) as Row;\n\n return rowToInfo(row);\n}\n\nexport function get(id: number): Info | null {\n const row = db\n .get()\n .prepare(`SELECT * FROM patches WHERE id = ?`)\n .get(id) as Row | null;\n\n if (!row) return null;\n return rowToInfo(row);\n}\n\nexport function getByHash(review: number, hash: string): Info | null {\n const row = db\n .get()\n .prepare(`SELECT * FROM patches WHERE review = ? AND hash = ?`)\n .get(review, hash) as Row | null;\n\n if (!row) return null;\n return rowToInfo(row);\n}\n\nexport function latest(review: number): Info | null {\n const row = db\n .get()\n .prepare(`SELECT * FROM patches WHERE review = ? ORDER BY seq DESC LIMIT 1`)\n .get(review) as Row | null;\n\n if (!row) return null;\n return rowToInfo(row);\n}\n\nexport function list(review: number): Info[] {\n const rows = db\n .get()\n .prepare(`SELECT * FROM patches WHERE review = ? ORDER BY seq ASC`)\n .all(review) as Row[];\n\n return rows.map(rowToInfo);\n}\n\nexport function pruneUnreferenced(\n review: number,\n keepPatchIds: number[] = [],\n): number {\n const keep = keepPatchIds.filter((x) => Number.isFinite(x));\n const keepSql =\n keep.length > 0 ? ` AND id NOT IN (${keep.map(() => \"?\").join(\",\")})` : \"\";\n\n const stmt = db.get().prepare(\n `DELETE FROM patches\n WHERE review = ?\n AND id NOT IN (\n SELECT DISTINCT patch_id FROM review_comments WHERE review = ?\n )${keepSql}`,\n );\n\n const result = stmt.run(review, review, ...keep);\n return Number(result.changes ?? 0);\n}\n\nexport function nextSeq(review: number): number {\n const last = latest(review);\n return last ? last.seq + 1 : 0;\n}\n\nexport function getOrCreate(review: number, content: string): Info {\n const hash = String(Bun.hash(content));\n const existing = getByHash(review, hash);\n if (existing) return existing;\n const seq = nextSeq(review);\n return create({ review, seq, hash, content });\n}\n",
|
|
10
|
+
"import * as db from \"./db\";\n\ntype Row = {\n id: number;\n review: number;\n note_id: number;\n file: string;\n patch_id: number;\n start_row: number;\n end_row: number;\n created_at: number;\n};\n\nexport type Info = {\n id: number;\n review: number;\n noteId: number;\n file: string;\n patchId: number;\n startRow: number;\n endRow: number;\n createdAt: number;\n};\n\nexport function create(input: {\n review: number;\n noteId: number;\n file: string;\n patchId: number;\n startRow: number;\n endRow: number;\n}): Info {\n const now = Date.now();\n\n const row = db\n .get()\n .prepare(\n `INSERT INTO review_comments (\n review,\n note_id,\n file,\n patch_id,\n start_row,\n end_row,\n created_at\n )\n VALUES (?, ?, ?, ?, ?, ?, ?) RETURNING id`,\n )\n .get(\n input.review,\n input.noteId,\n input.file,\n input.patchId,\n input.startRow,\n input.endRow,\n now,\n ) as {\n id: number;\n };\n\n return {\n id: row.id,\n review: input.review,\n noteId: input.noteId,\n file: input.file,\n patchId: input.patchId,\n startRow: input.startRow,\n endRow: input.endRow,\n createdAt: now,\n };\n}\n\nexport function list(review: number): Info[] {\n const rows = db\n .get()\n .prepare(\n `SELECT * FROM review_comments WHERE review = ? ORDER BY created_at ASC`,\n )\n .all(review) as Row[];\n\n return rows.map((row) => ({\n id: row.id,\n review: row.review,\n noteId: row.note_id,\n file: row.file,\n patchId: row.patch_id,\n startRow: row.start_row,\n endRow: row.end_row,\n createdAt: row.created_at,\n }));\n}\n",
|
|
11
|
+
"#!/usr/bin/env bun\nimport { render } from \"@opentui/solid\";\nimport { SliderRenderable, addDefaultParsers } from \"@opentui/core\";\nimport { ErrorBoundary } from \"solid-js\";\nimport { Review } from \"./Review\";\nimport { ErrorFallback } from \"./components\";\nimport { mkdirSync, writeFileSync } from \"fs\";\nimport { parsers } from \"../parsers\";\nimport { db } from \"./store\";\n\n// Initialize TUI local database\ndb.init();\n\n// Register tree-sitter parsers for syntax highlighting\naddDefaultParsers(parsers);\n\n// Monkey patch Slider to prevent rendering with invalid layout\n// Fixes flash when scrollbar appears (layout not yet calculated by yoga)\nconst originalSliderRenderSelf = (SliderRenderable.prototype as any).renderSelf;\n(SliderRenderable.prototype as any).renderSelf = function (buffer: any) {\n // Skip if dimensions invalid - vertical sliders should have height > 1, horizontal width > 1\n if (this.width <= 0 || this.height <= 0) return;\n if (this.orientation === \"vertical\" && this.height <= 1) return;\n if (this.orientation === \"horizontal\" && this.width <= 1) return;\n originalSliderRenderSelf.call(this, buffer);\n};\n\nconst RECORD_FRAMES = process.env.RECORD_FRAMES === \"1\";\nlet frameNumber = 0;\nconst decoder = new TextDecoder();\n\nexport interface TuiOptions {\n repoPath?: string;\n}\n\nexport async function tui(options: TuiOptions = {}): Promise<void> {\n const repoPath = options.repoPath ?? process.cwd();\n\n await render(\n () => (\n <ErrorBoundary\n fallback={(err: Error, reset: () => void) => (\n <ErrorFallback error={err} reset={reset} />\n )}\n >\n <Review repoPath={repoPath} />\n </ErrorBoundary>\n ),\n {\n exitOnCtrlC: false,\n useKittyKeyboard: {},\n postProcessFns: RECORD_FRAMES\n ? [\n (buffer) => {\n const frameBytes = buffer.getRealCharBytes(true);\n const frame = decoder.decode(frameBytes);\n\n mkdirSync(\"frames\", { recursive: true });\n writeFileSync(\n `frames/frame-${String(frameNumber++).padStart(5, \"0\")}.txt`,\n frame,\n );\n },\n ]\n : undefined,\n },\n );\n}\n\n// Run if executed directly\nif (import.meta.main) {\n tui();\n}\n",
|
|
12
|
+
"import { useKeyboard, useTerminalDimensions } from \"@opentui/solid\";\nimport { createSignal, createEffect, createMemo, Show } from \"solid-js\";\nimport {\n FileList,\n CommentList,\n PatchList,\n DiffPanel,\n EditorPanel,\n CommandPalette,\n ServerStatus,\n ProjectStatus,\n} from \"./components\";\nimport {\n buildFileTree,\n flattenTree,\n getFileIndices,\n type DisplayItem,\n} from \"./lib/tree\";\nimport { getHunkIndexForRow, parseFileDiff } from \"./lib/diff\";\nimport { DialogProvider, useDialog } from \"./context/dialog\";\nimport { CommandProvider, useCommand } from \"./context/command\";\nimport { ThemeProvider, useTheme } from \"./context/theme\";\nimport { ExitProvider, useExit } from \"./context/exit\";\nimport { ServerProvider } from \"./context/server\";\nimport { ReviewProvider, useReview } from \"./context/review\";\nimport { SidebarProvider } from \"./context/sidebar\";\nimport { type Command, matchAny } from \"./lib/keybind\";\nimport { EmptyBorder } from \"./components/HalfLineShadow\";\n\ntype FocusPanel = \"sidebar\" | \"diff\" | \"editor\";\ntype SidebarMode = \"files\" | \"patches\" | \"comments\";\ntype SelectionMode = \"hunk\" | \"line\";\n\ntype EditorAnchor = {\n file: string;\n startRow: number;\n endRow: number;\n commentId?: number;\n};\n\nexport interface ReviewProps {\n /** Path to the git repository. Defaults to process.argv[2] or \".\" */\n repoPath?: string;\n}\n\nexport function Review(props: ReviewProps = {}) {\n const repoPath = props.repoPath ?? process.argv[2] ?? \".\";\n return (\n <ThemeProvider>\n <ExitProvider>\n <ServerProvider>\n <ReviewProvider repoPath={repoPath}>\n <DialogProvider>\n <CommandProvider>\n <App repoPath={repoPath} />\n </CommandProvider>\n </DialogProvider>\n </ReviewProvider>\n </ServerProvider>\n </ExitProvider>\n </ThemeProvider>\n );\n}\n\ninterface AppProps {\n repoPath: string;\n}\n\nfunction App(props: AppProps) {\n const dims = useTerminalDimensions();\n const dialog = useDialog();\n const command = useCommand();\n const { theme } = useTheme();\n const { exit } = useExit();\n const review = useReview();\n\n // Derived tree state\n const displayItems = createMemo<DisplayItem[]>(() => {\n const e = review.entries();\n if (e.length === 0) return [];\n const tree = buildFileTree(e);\n return flattenTree(tree);\n });\n\n const fileIndices = createMemo(() => getFileIndices(displayItems()));\n\n createEffect(() => {\n const indices = fileIndices();\n const entries = review.entries();\n const current = review.selectedFilePath();\n\n if (indices.length === 0) {\n review.setSelectedFilePath(null);\n return;\n }\n\n if (!current || !entries.some((e) => e.file === current)) {\n const firstEntryIndex = indices[0]!;\n review.setSelectedFilePath(entries[firstEntryIndex]?.file ?? null);\n }\n });\n\n // Navigation state\n const [focusPanel, setFocusPanel] = createSignal<FocusPanel>(\"sidebar\");\n const [sidebarMode, setSidebarMode] = createSignal<SidebarMode>(\"files\");\n const [selectedHunkIndex, setSelectedHunkIndex] = createSignal(0);\n const [selectionMode, setSelectionMode] = createSignal<SelectionMode>(\"hunk\");\n const [selectedRange, setSelectedRange] = createSignal<{\n startRow: number;\n endRow: number;\n } | null>(null);\n const [cursorRow, setCursorRow] = createSignal(1);\n const [editorAnchor, setEditorAnchor] = createSignal<EditorAnchor | null>(\n null,\n );\n\n // Comment list state\n const [selectedCommentIndex, setSelectedCommentIndex] = createSignal(0);\n\n // Patch list state\n const [selectedPatchIndex, setSelectedPatchIndex] = createSignal(0);\n\n const selectedFileNavIndex = createMemo(() => {\n const indices = fileIndices();\n if (indices.length === 0) return 0;\n\n const entries = review.entries();\n const path = review.selectedFilePath();\n if (!path) return 0;\n\n const entryIndex = entries.findIndex((e) => e.file === path);\n if (entryIndex === -1) return 0;\n\n const navIndex = indices.indexOf(entryIndex);\n return navIndex === -1 ? 0 : navIndex;\n });\n\n const selectedEntry = () => {\n const entries = review.entries();\n if (entries.length === 0) return undefined;\n\n const path = review.selectedFilePath();\n if (path) {\n const found = entries.find((e) => e.file === path);\n if (found) return found;\n }\n\n const firstEntryIndex = fileIndices()[0];\n if (firstEntryIndex !== undefined) return entries[firstEntryIndex];\n return entries[0];\n };\n\n // Hunk count for the selected entry (computed from diff content)\n const diffModel = createMemo(() => {\n const entry = selectedEntry();\n if (!entry) return { hunks: [], totalRows: 0 };\n return parseFileDiff(entry.content, entry.file);\n });\n\n const hunkCount = createMemo(() => diffModel().hunks.length);\n const totalRows = createMemo(() => diffModel().totalRows);\n\n const selectedHunkRange = createMemo(() => {\n const entry = selectedEntry();\n if (!entry) return null;\n const hunk = diffModel().hunks[selectedHunkIndex()];\n if (!hunk) return null;\n return { startRow: hunk.startRow, endRow: hunk.endRow };\n });\n\n // Track previous file to detect actual file changes vs patch switches\n const [previousFile, setPreviousFile] = createSignal<string | null>(null);\n\n // Reset or clip hunk selection when file changes\n createEffect(() => {\n review.selectedFilePath();\n review.activePatchId();\n const currentFile = selectedEntry()?.file ?? null;\n const prevFile = previousFile();\n\n // Only reset if we actually changed to a different file\n if (currentFile !== prevFile) {\n setSelectedHunkIndex(0);\n setSelectionMode(\"hunk\");\n setSelectedRange(null);\n setCursorRow(1);\n } else if (currentFile !== null) {\n // Same file, patch changed - clip to valid bounds\n const maxHunk = Math.max(0, hunkCount() - 1);\n setSelectedHunkIndex((i) => Math.min(i, maxHunk));\n\n const maxRow = totalRows();\n if (maxRow > 0) {\n setSelectedRange((range) => {\n if (!range) return null;\n // Clip range to valid bounds\n const clippedStart = Math.min(range.startRow, maxRow);\n const clippedEnd = Math.min(range.endRow, maxRow);\n if (\n clippedStart === clippedEnd &&\n clippedStart === maxRow &&\n maxRow > 1\n ) {\n // If everything got clipped to the end, select last line\n return { startRow: maxRow - 1, endRow: maxRow };\n }\n return { startRow: clippedStart, endRow: clippedEnd };\n });\n setCursorRow((r) => Math.min(Math.max(1, r), maxRow));\n }\n }\n\n setPreviousFile(currentFile);\n });\n\n const clampRow = (row: number) => {\n const max = Math.max(1, totalRows());\n return Math.min(Math.max(1, row), max);\n };\n\n const setSelectedNavIndex = (navIndex: number) => {\n const entryIndex = fileIndices()[navIndex];\n const entry =\n entryIndex !== undefined ? review.entries()[entryIndex] : null;\n review.setSelectedFilePath(entry?.file ?? null);\n };\n\n // Helper functions for commands\n const navigateUp = () => {\n const panel = focusPanel();\n if (panel === \"sidebar\") {\n if (sidebarMode() === \"files\") {\n setSelectedNavIndex(Math.max(0, selectedFileNavIndex() - 1));\n } else if (sidebarMode() === \"patches\") {\n setSelectedPatchIndex((i) => Math.max(0, i - 1));\n } else {\n setSelectedCommentIndex((i) => Math.max(0, i - 1));\n }\n return;\n }\n\n if (panel === \"diff\" && selectionMode() === \"line\") {\n const next = clampRow(cursorRow() - 1);\n setCursorRow(next);\n setSelectedRange({ startRow: next, endRow: next });\n return;\n }\n\n if (panel === \"diff\") {\n setSelectedHunkIndex((i: number) => Math.max(0, i - 1));\n }\n };\n\n const navigateDown = () => {\n const panel = focusPanel();\n if (panel === \"sidebar\") {\n if (sidebarMode() === \"files\") {\n setSelectedNavIndex(\n Math.min(fileIndices().length - 1, selectedFileNavIndex() + 1),\n );\n } else if (sidebarMode() === \"patches\") {\n const wt = review.workingTreePatchId();\n const patchCount =\n (wt === null\n ? review.patches().length\n : review.patches().filter((p) => p.id !== wt).length) + 1; // +1 for working tree\n setSelectedPatchIndex((i) => Math.min(patchCount - 1, i + 1));\n } else {\n const maxIndex = review.comments().length - 1;\n setSelectedCommentIndex((i) => Math.min(maxIndex, i + 1));\n }\n return;\n }\n\n if (panel === \"diff\" && selectionMode() === \"line\") {\n const next = clampRow(cursorRow() + 1);\n setCursorRow(next);\n setSelectedRange({ startRow: next, endRow: next });\n return;\n }\n\n if (panel === \"diff\") {\n setSelectedHunkIndex((i: number) => Math.min(hunkCount() - 1, i + 1));\n }\n };\n\n const openCommentEditor = () => {\n const entry = selectedEntry();\n const range =\n selectionMode() === \"line\" ? selectedRange() : selectedHunkRange();\n if (!entry || !range) return;\n\n const existing = review.getCommentForRange(\n entry.file,\n range.startRow,\n range.endRow,\n );\n\n setEditorAnchor({\n file: entry.file,\n startRow: range.startRow,\n endRow: range.endRow,\n commentId: existing?.id,\n });\n setFocusPanel(\"editor\");\n };\n\n const toggleSidebarMode = () => {\n setSidebarMode((m) => {\n if (m === \"files\") return \"patches\";\n if (m === \"patches\") return \"comments\";\n return \"files\";\n });\n };\n\n const toggleHunkSelection = () => {\n const range = selectedHunkRange();\n if (!range) return;\n if (selectedRange()) {\n setSelectedRange(null);\n return;\n }\n setSelectionMode(\"hunk\");\n setSelectedRange(range);\n };\n\n const toggleLineMode = () => {\n if (totalRows() === 0) return;\n if (selectionMode() === \"hunk\") {\n const range = selectedRange() ?? selectedHunkRange();\n const row = clampRow(range?.startRow ?? 1);\n setSelectionMode(\"line\");\n setCursorRow(row);\n setSelectedRange({ startRow: row, endRow: row });\n return;\n }\n const entry = selectedEntry();\n const range = selectedRange();\n if (entry && range) {\n const hunkIndex =\n getHunkIndexForRow(entry.content, entry.file, range.startRow) ?? 0;\n setSelectedHunkIndex(hunkIndex);\n }\n setSelectionMode(\"hunk\");\n setSelectedRange(null);\n };\n\n const extendSelectionDown = () => {\n if (selectionMode() !== \"line\") return;\n const range = selectedRange() ?? {\n startRow: cursorRow(),\n endRow: cursorRow(),\n };\n const next = clampRow(range.endRow + 1);\n setSelectedRange({ startRow: range.startRow, endRow: next });\n setCursorRow(next);\n };\n\n const extendSelectionUp = () => {\n if (selectionMode() !== \"line\") return;\n const range = selectedRange() ?? {\n startRow: cursorRow(),\n endRow: cursorRow(),\n };\n const next = clampRow(range.startRow - 1);\n setSelectedRange({ startRow: next, endRow: range.endRow });\n setCursorRow(next);\n };\n\n // Define all commands with structured keybinds\n const commands = (): Command[] => [\n // Movement\n {\n id: \"up\",\n title: \"up\",\n category: \"movement\",\n keybinds: [{ name: \"up\" }, { name: \"k\" }],\n isActive: () => focusPanel() !== \"editor\",\n onExecute: navigateUp,\n },\n {\n id: \"down\",\n title: \"down\",\n category: \"movement\",\n keybinds: [{ name: \"down\" }, { name: \"j\" }],\n isActive: () => focusPanel() !== \"editor\",\n onExecute: navigateDown,\n },\n {\n id: \"back-from-diff\",\n title: \"back\",\n category: \"movement\",\n keybinds: [{ name: \"escape\" }],\n isActive: () => focusPanel() === \"diff\",\n onExecute: () => {\n setFocusPanel(\"sidebar\");\n setSelectedHunkIndex(0);\n },\n },\n\n {\n id: \"quit\",\n title: \"quit\",\n category: \"movement\",\n keybinds: [\n { name: \"c\", ctrl: true },\n { name: \"d\", ctrl: true },\n { name: \"q\", ctrl: true },\n ],\n isActive: () => focusPanel() !== \"editor\",\n onExecute: () => exit(),\n },\n\n {\n id: \"refresh-working-tree\",\n title: \"refresh working tree\",\n category: \"movement\",\n keybinds: [{ name: \"r\", ctrl: true }],\n isActive: () => focusPanel() !== \"editor\",\n onExecute: () => {\n const preserve = selectedEntry()?.file ?? review.selectedFilePath();\n void review.refreshWorkingTree(preserve ?? undefined);\n },\n },\n\n {\n id: \"cycle-forward\",\n title: \"cycle forward\",\n category: \"movement\",\n keybinds: [{ name: \"tab\" }],\n isActive: () => focusPanel() !== \"editor\",\n onExecute: () => {\n // Cycle: files -> patches -> comments -> diff -> files\n if (focusPanel() === \"sidebar\") {\n if (sidebarMode() === \"files\") {\n setSidebarMode(\"patches\");\n } else if (sidebarMode() === \"patches\") {\n setSidebarMode(\"comments\");\n } else {\n setFocusPanel(\"diff\");\n setSelectedHunkIndex(0);\n }\n } else if (focusPanel() === \"diff\") {\n setFocusPanel(\"sidebar\");\n setSidebarMode(\"files\");\n }\n },\n },\n {\n id: \"cycle-backward\",\n title: \"cycle backward\",\n category: \"movement\",\n keybinds: [{ name: \"tab\", shift: true }],\n isActive: () => focusPanel() !== \"editor\",\n onExecute: () => {\n // Cycle: files <- patches <- comments <- diff <- files\n if (focusPanel() === \"sidebar\") {\n if (sidebarMode() === \"files\") {\n setFocusPanel(\"diff\");\n setSelectedHunkIndex(0);\n } else if (sidebarMode() === \"patches\") {\n setSidebarMode(\"files\");\n } else {\n setSidebarMode(\"patches\");\n }\n } else if (focusPanel() === \"diff\") {\n setFocusPanel(\"sidebar\");\n setSidebarMode(\"comments\");\n }\n },\n },\n\n {\n id: \"select-hunks\",\n title: \"select hunks\",\n category: \"selection\",\n keybinds: [{ name: \"return\" }],\n isActive: () =>\n focusPanel() === \"sidebar\" &&\n sidebarMode() === \"files\" &&\n !!selectedEntry() &&\n hunkCount() > 0,\n onExecute: () => {\n setFocusPanel(\"diff\");\n setSelectedHunkIndex(0);\n setSelectionMode(\"hunk\");\n setSelectedRange(null);\n },\n },\n {\n id: \"select-lines\",\n title: \"select by lines\",\n category: \"selection\",\n keybinds: [{ name: \"a\" }],\n isActive: () => focusPanel() === \"diff\" && totalRows() > 0,\n onExecute: toggleLineMode,\n },\n {\n id: \"toggle-hunk-selection\",\n title: \"toggle hunk selection\",\n category: \"selection\",\n keybinds: [{ name: \"space\" }],\n isActive: () =>\n focusPanel() === \"diff\" &&\n selectionMode() === \"hunk\" &&\n selectedHunkRange() !== null,\n onExecute: toggleHunkSelection,\n },\n {\n id: \"extend-down\",\n title: \"extend selection down\",\n category: \"selection\",\n keybinds: [\n { name: \"j\", shift: true },\n { name: \"down\", shift: true },\n ],\n isActive: () => focusPanel() === \"diff\" && selectionMode() === \"line\",\n onExecute: extendSelectionDown,\n },\n {\n id: \"extend-up\",\n title: \"extend selection up\",\n category: \"selection\",\n keybinds: [\n { name: \"k\", shift: true },\n { name: \"up\", shift: true },\n ],\n isActive: () => focusPanel() === \"diff\" && selectionMode() === \"line\",\n onExecute: extendSelectionUp,\n },\n {\n id: \"open-comment\",\n title: \"open comment\",\n category: \"selection\",\n keybinds: [{ name: \"return\" }],\n isActive: () =>\n focusPanel() === \"sidebar\" &&\n sidebarMode() === \"comments\" &&\n review.comments().length > 0,\n onExecute: () => {\n // Navigate to the comment's file+range and open editor\n const comments = review.comments();\n const idx = selectedCommentIndex();\n const comment = comments[idx];\n if (!comment) return;\n\n review.setActivePatch(comment.patchId, comment.file);\n\n // Navigate to the file and hunk (best-effort). Even if the file isn't\n // present in the current patch diff (eg stale comment), still open the\n // editor so the user can view/edit the note content.\n review.setSelectedFilePath(comment.file);\n\n const entry = review.entries().find((e) => e.file === comment.file);\n const hunkIndex = entry\n ? (getHunkIndexForRow(entry.content, entry.file, comment.startRow) ??\n 0)\n : 0;\n setSelectedHunkIndex(hunkIndex);\n setEditorAnchor({\n file: comment.file,\n startRow: comment.startRow,\n endRow: comment.endRow,\n commentId: comment.id,\n });\n setFocusPanel(\"editor\");\n },\n },\n {\n id: \"select-patch\",\n title: \"select patch\",\n category: \"selection\",\n keybinds: [{ name: \"return\" }],\n isActive: () =>\n focusPanel() === \"sidebar\" &&\n sidebarMode() === \"patches\" &&\n review.patches().length > 0,\n onExecute: () => {\n const wt = review.workingTreePatchId();\n const patches = review\n .patches()\n .slice()\n .filter((p) => (wt === null ? true : p.id !== wt))\n .sort((a, b) => b.seq - a.seq);\n const idx = selectedPatchIndex();\n // Get current file to preserve selection if possible\n const currentEntry = selectedEntry();\n const currentFile = currentEntry?.file;\n // Index 0 is working tree, then patches start at index 1\n if (idx === 0) {\n if (wt !== null) review.setActivePatch(wt, currentFile);\n } else {\n const patch = patches[idx - 1];\n if (patch) {\n review.setActivePatch(patch.id, currentFile);\n }\n }\n },\n },\n // Actions\n {\n id: \"comment\",\n title: \"comment\",\n category: \"actions\",\n keybinds: [{ name: \"c\" }],\n isActive: () =>\n focusPanel() === \"diff\" &&\n ((selectionMode() === \"hunk\" && selectedHunkRange() !== null) ||\n (selectionMode() === \"line\" && selectedRange() !== null)),\n onExecute: openCommentEditor,\n },\n ];\n\n // Register commands for palette\n command.register(commands);\n\n useKeyboard((key) => {\n if (key.ctrl && key.name === \"p\") {\n dialog.show(() => <CommandPalette />);\n return;\n }\n\n // Skip if dialog is open (CommandPalette handles its own keys)\n if (dialog.isOpen()) return;\n\n // Find and execute first matching active command\n for (const cmd of commands()) {\n if (cmd.isActive() && matchAny(key, cmd.keybinds)) {\n cmd.onExecute();\n return;\n }\n }\n });\n\n const Footer = () => (\n <box height={1} paddingLeft={1} flexDirection=\"row\" gap={2}>\n <box flexDirection=\"row\">\n <text>j/k </text>\n <text fg=\"brightBlack\">navigate</text>\n </box>\n <Show when={focusPanel() === \"sidebar\"}>\n <box flexDirection=\"row\">\n <text>tab </text>\n <text fg=\"brightBlack\">switch</text>\n </box>\n </Show>\n <Show\n when={\n focusPanel() === \"diff\" &&\n ((selectionMode() === \"hunk\" && selectedHunkRange() !== null) ||\n (selectionMode() === \"line\" && selectedRange()))\n }\n >\n <box flexDirection=\"row\">\n <text>c </text>\n <text fg=\"brightBlack\">comment</text>\n </box>\n </Show>\n <Show when={focusPanel() === \"editor\"}>\n <box flexDirection=\"row\">\n <text>enter </text>\n <text fg=\"brightBlack\">submit</text>\n </box>\n <box flexDirection=\"row\">\n <text>C-j </text>\n <text fg=\"brightBlack\">newline</text>\n </box>\n <box flexDirection=\"row\">\n <text>C-e </text>\n <text fg=\"brightBlack\">editor</text>\n </box>\n <box flexDirection=\"row\">\n <text>esc </text>\n <text fg=\"brightBlack\">cancel</text>\n </box>\n </Show>\n <Show when={focusPanel() !== \"editor\"}>\n <box flexDirection=\"row\">\n <text>esc </text>\n <text fg=\"brightBlack\">back</text>\n </box>\n </Show>\n <Show when={focusPanel() !== \"editor\"}>\n <box flexDirection=\"row\">\n <text>C-r </text>\n <text fg=\"brightBlack\">refresh</text>\n </box>\n </Show>\n <Show when={focusPanel() !== \"editor\"}>\n <box flexDirection=\"row\">\n <text>C-q </text>\n <text fg=\"brightBlack\">quit</text>\n </box>\n </Show>\n </box>\n );\n\n return (\n <box\n flexDirection=\"column\"\n width={dims().width}\n height={dims().height}\n backgroundColor={theme.background}\n >\n <box flexGrow={1} flexDirection=\"row\" gap={1}>\n <box\n width={40}\n flexDirection=\"column\"\n gap={1}\n paddingTop={1}\n paddingBottom={1}\n paddingLeft={2}\n paddingRight={2}\n backgroundColor={theme.backgroundPanel}\n >\n <ServerStatus />\n <ProjectStatus\n repoRoot={review.repoRoot}\n commentCount={() => review.comments().length}\n />\n\n <SidebarProvider\n activeSection={sidebarMode}\n isFocused={() => focusPanel() === \"sidebar\"}\n >\n <box flexGrow={1} flexDirection=\"column\" overflow=\"hidden\" gap={1}>\n <box\n flexGrow={1}\n >\n <FileList\n displayItems={displayItems}\n selectedFileIndex={selectedFileNavIndex}\n fileIndices={fileIndices}\n entries={review.entries}\n loading={review.loading}\n focused={() =>\n focusPanel() === \"sidebar\" && sidebarMode() === \"files\"\n }\n />\n </box>\n\n <box flexGrow={1} flexDirection=\"column\">\n <PatchList\n patches={review.patches}\n activePatchId={review.activePatchId}\n workingTreePatchId={review.workingTreePatchId}\n workspaceEntries={review.workspaceEntries}\n loading={review.patchesLoading}\n selectedIndex={selectedPatchIndex}\n focused={() =>\n focusPanel() === \"sidebar\" && sidebarMode() === \"patches\"\n }\n />\n </box>\n\n <box flexGrow={1} flexDirection=\"column\">\n <CommentList\n comments={review.comments}\n loading={review.commentsLoading}\n selectedIndex={selectedCommentIndex}\n focused={() =>\n focusPanel() === \"sidebar\" && sidebarMode() === \"comments\"\n }\n />\n </box>\n </box>\n </SidebarProvider>\n </box>\n\n <box flexGrow={1} flexDirection=\"column\" gap={1}>\n <DiffPanel\n entry={selectedEntry}\n hunkCount={hunkCount}\n selectedHunkIndex={selectedHunkIndex}\n selectionMode={selectionMode}\n selectedRange={selectedRange}\n cursorRow={cursorRow}\n focused={() => focusPanel() === \"diff\"}\n />\n\n <Show when={focusPanel() === \"editor\" && editorAnchor()}>\n <EditorPanel\n file={editorAnchor()!.file}\n startRow={editorAnchor()!.startRow}\n endRow={editorAnchor()!.endRow}\n commentId={editorAnchor()!.commentId}\n onClose={() => {\n setFocusPanel(\"diff\");\n setEditorAnchor(null);\n }}\n />\n </Show>\n </box>\n </box>\n\n {/* Footer */}\n <Footer />\n\n {/* Dialog overlay */}\n <Show when={dialog.isOpen()}>{dialog.content()}</Show>\n </box>\n );\n}\n",
|
|
13
|
+
"import { Show, For, createMemo, createEffect, Index } from \"solid-js\";\nimport type { Accessor } from \"solid-js\";\nimport type { ScrollBoxRenderable } from \"@opentui/core\";\nimport { Git } from \"../lib/git\";\nimport { getHunkIndexForRow, parseFileDiff } from \"../lib/diff\";\nimport { useTheme } from \"../context/theme\";\nimport { EmptyBorder } from \"./HalfLineShadow\";\n\n/** Number of diff rows to keep visible above/below cursor (line mode). */\nconst LINE_SCROLL_BUFFER = 8;\n\nfunction getFiletype(filename: string): string {\n const ext = filename.split(\".\").pop()?.toLowerCase() ?? \"\";\n const extMap: Record<string, string> = {\n ts: \"typescript\",\n tsx: \"tsx\",\n js: \"javascript\",\n jsx: \"javascript\",\n mjs: \"javascript\",\n cjs: \"javascript\",\n html: \"html\",\n htm: \"html\",\n css: \"css\",\n scss: \"css\",\n vue: \"vue\",\n json: \"json\",\n yaml: \"yaml\",\n yml: \"yaml\",\n toml: \"toml\",\n c: \"c\",\n h: \"c\",\n cpp: \"cpp\",\n cc: \"cpp\",\n cxx: \"cpp\",\n hpp: \"cpp\",\n hxx: \"cpp\",\n rs: \"rust\",\n go: \"go\",\n zig: \"zig\",\n py: \"python\",\n rb: \"ruby\",\n lua: \"lua\",\n sh: \"bash\",\n bash: \"bash\",\n zsh: \"bash\",\n php: \"php\",\n java: \"java\",\n kt: \"kotlin\",\n kts: \"kotlin\",\n scala: \"scala\",\n cs: \"c_sharp\",\n swift: \"swift\",\n m: \"objc\",\n mm: \"objc\",\n dart: \"dart\",\n ex: \"elixir\",\n exs: \"elixir\",\n elm: \"elm\",\n ml: \"ocaml\",\n mli: \"ocaml\",\n el: \"elisp\",\n sql: \"ql\",\n erb: \"embedded_template\",\n ejs: \"embedded_template\",\n md: \"markdown\",\n mdx: \"markdown\",\n };\n return extMap[ext] ?? \"text\";\n}\n\nexport interface DiffPanelProps {\n entry: Accessor<Git.Entry | undefined>;\n hunkCount: Accessor<number>;\n selectedHunkIndex: Accessor<number>;\n selectionMode: Accessor<\"hunk\" | \"line\">;\n selectedRange: Accessor<{ startRow: number; endRow: number } | null>;\n cursorRow: Accessor<number>;\n focused: Accessor<boolean>;\n}\n\nexport function DiffPanel(props: DiffPanelProps) {\n const { theme, syntax } = useTheme();\n\n const title = () => {\n const entry = props.entry();\n if (!entry) return \"Diff\";\n const hunkCount = props.hunkCount();\n\n if (hunkCount === 0) return entry.file;\n if (props.selectionMode() === \"line\") {\n const range = props.selectedRange();\n if (range && range.startRow !== range.endRow) {\n return `[lines ${range.startRow}-${range.endRow}]`;\n }\n const row = range?.startRow ?? props.cursorRow();\n return `[line ${row}]`;\n }\n if (props.focused()) {\n return `[hunk ${props.selectedHunkIndex() + 1}/${hunkCount}]`;\n }\n return `[${hunkCount} hunk${hunkCount === 1 ? \"\" : \"s\"}]`;\n };\n\n return (\n <box\n flexGrow={1}\n flexDirection=\"column\"\n backgroundColor={theme.backgroundPanel}\n paddingTop={1}\n paddingBottom={1}\n paddingLeft={2}\n paddingRight={2}\n >\n {/* Title bar */}\n <box\n height={1}\n flexDirection=\"row\"\n justifyContent=\"flex-start\"\n gap={1}\n backgroundColor={\n props.focused() ? theme.primaryDark : theme.backgroundPanel\n }\n border={[\"left\"]}\n borderColor={props.focused() ? theme.primary : theme.indicatorDefault}\n customBorderChars={{\n ...EmptyBorder,\n vertical: \"\\u258C\",\n }}\n >\n <box paddingLeft={1} flexDirection=\"row\" gap={1}>\n <text>\n <span style={{ italic: true }}>\n {props.entry() ? props.entry()!.file : \"none\"}\n </span>\n </text>\n <text>\n <span style={{ bold: true }}>{title()}</span>\n </text>\n </box>\n </box>\n\n <Show when={props.entry()}>\n {(() => {\n const entry = props.entry()!;\n const model = createMemo(() =>\n parseFileDiff(entry.content, entry.file),\n );\n const hunks = createMemo(() => model().hunks);\n const filetype = getFiletype(entry.file);\n\n let scrollbox: ScrollBoxRenderable | null = null;\n\n // Scroll to selected hunk when it changes\n createEffect(() => {\n const hunkIdx = props.selectedHunkIndex();\n const hunkList = hunks();\n if (!scrollbox || hunkList.length === 0) return;\n\n let scrollLine = 0;\n if (props.selectionMode() === \"line\") {\n const row = props.cursorRow();\n const rowHunkIndex = getHunkIndexForRow(\n entry.content,\n entry.file,\n row,\n );\n const separatorOffset = rowHunkIndex ? rowHunkIndex : 0;\n scrollLine = Math.max(0, row - 1 + separatorOffset);\n const scrollTop = scrollbox.scrollTop;\n const viewportHeight = scrollbox.viewport.height;\n\n const topBound = scrollTop + LINE_SCROLL_BUFFER;\n const bottomBound =\n scrollTop + viewportHeight - 1 - LINE_SCROLL_BUFFER;\n\n if (scrollLine < topBound) {\n scrollbox.scrollTo(\n Math.max(0, scrollLine - LINE_SCROLL_BUFFER),\n );\n } else if (scrollLine > bottomBound) {\n scrollbox.scrollTo(\n Math.max(\n 0,\n scrollLine + LINE_SCROLL_BUFFER - viewportHeight + 1,\n ),\n );\n }\n return;\n }\n\n if (hunkIdx > 0) {\n const prev = hunkList[Math.min(hunkIdx - 1, hunkList.length - 1)];\n if (prev) scrollLine = prev.endRow + hunkIdx;\n }\n\n const activeHunk = hunkList[hunkIdx];\n if (!activeHunk) return;\n const scrollTop = scrollbox.scrollTop;\n const viewportHeight = scrollbox.viewport.height;\n const separatorOffset = hunkIdx;\n const hunkTop = Math.max(\n 0,\n activeHunk.startRow - 1 + separatorOffset,\n );\n const hunkBottom = Math.max(\n 0,\n activeHunk.endRow - 1 + separatorOffset,\n );\n const viewportBottom = scrollTop + viewportHeight - 1;\n\n if (hunkTop < scrollTop) {\n scrollbox.scrollTo(hunkTop);\n } else if (hunkBottom > viewportBottom) {\n scrollbox.scrollTo(scrollLine);\n }\n });\n\n return (\n <scrollbox\n ref={(r) => {\n scrollbox = r;\n }}\n focused={false}\n flexGrow={1}\n >\n <box flexDirection=\"column\" backgroundColor={theme.background}>\n <Index each={hunks()}>\n {(hunk, i) => {\n const isFocused = () =>\n props.focused() && props.selectedHunkIndex() === i;\n const indicatorColor = (row: number) => {\n if (props.selectionMode() === \"line\") {\n const range = props.selectedRange();\n if (\n range &&\n row >= range.startRow &&\n row <= range.endRow\n ) {\n return theme.primary;\n }\n return theme.indicatorDefault;\n }\n if (isFocused()) return theme.primary;\n return theme.indicatorDefault;\n };\n\n return (\n <>\n <Show when={i > 0}>\n <box\n height={1}\n backgroundColor={theme.backgroundPanel}\n />\n </Show>\n <box flexDirection=\"row\">\n {/* Indicator column */}\n <box flexDirection=\"column\" width={1} flexShrink={0}>\n {/* <text height={1} fg={indicatorColor()}> */}\n {/* {\"\\u2582\"} */}\n {/* </text> */}\n <For\n each={Array.from(\n { length: hunk().lineCount },\n (_, j) => j,\n )}\n >\n {(j) => {\n const row = hunk().startRow + j;\n return (\n <text height={1} fg={indicatorColor(row)}>\n ▌\n </text>\n );\n }}\n </For>\n {/* <text height={1} fg={indicatorColor()}> */}\n {/* {\"\\u2594\"} */}\n {/* </text> */}\n {/**/}\n </box>\n <diff\n diff={hunk().diffString}\n view=\"unified\"\n filetype={filetype}\n syntaxStyle={syntax()}\n showLineNumbers={true}\n flexGrow={0}\n fg={theme.text}\n addedBg={theme.diffAddedBg}\n removedBg={theme.diffRemovedBg}\n contextBg={theme.diffContextBg}\n addedSignColor={theme.diffSignAdded}\n removedSignColor={theme.diffSignRemoved}\n lineNumberFg={theme.diffLineNumberFg}\n lineNumberBg={theme.diffContextBg}\n addedLineNumberBg={theme.diffAddedLineNumberBg}\n removedLineNumberBg={theme.diffRemovedLineNumberBg}\n />\n </box>\n </>\n );\n }}\n </Index>\n </box>\n </scrollbox>\n );\n })()}\n </Show>\n <Show when={!props.entry()}>\n <box padding={1} flexGrow={1}>\n <text>Select a file to view diff</text>\n </box>\n </Show>\n </box>\n );\n}\n",
|
|
14
|
+
"import { parsePatch } from \"diff\";\nimport { Git } from \"./git\";\n\nexport interface DiffHunk {\n diffString: string;\n oldStart: number;\n oldLines: number;\n newStart: number;\n newLines: number;\n skipBefore: number;\n lineCount: number;\n startRow: number;\n endRow: number;\n}\n\nexport interface DiffFileModel {\n hunks: DiffHunk[];\n totalRows: number;\n}\n\nexport function parseFileDiff(content: string, file: string): DiffFileModel {\n if (!content) return { hunks: [], totalRows: 0 };\n\n try {\n const patches = parsePatch(content);\n if (patches.length === 0 && !content.endsWith(\"\\n\")) {\n patches.push(...parsePatch(`${content}\\n`));\n }\n if (patches.length === 0) return { hunks: [], totalRows: 0 };\n\n const rawHunks = patches[0]?.hunks ?? [];\n const hunks: DiffHunk[] = [];\n\n const header = `diff --git a/${file} b/${file}\\n--- a/${file}\\n+++ b/${file}`;\n\n let currentRow = 1;\n\n for (let i = 0; i < rawHunks.length; i++) {\n const hunk = rawHunks[i]!;\n\n let skipBefore = 0;\n if (i > 0) {\n const prev = rawHunks[i - 1]!;\n const prevEnd = prev.oldStart + prev.oldLines;\n skipBefore = hunk.oldStart - prevEnd;\n }\n\n const hunkHeader = `@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`;\n const diffString = `${header}\\n${hunkHeader}\\n${hunk.lines.join(\"\\n\")}`;\n\n let lineCount = 0;\n for (const line of hunk.lines) {\n const c = line[0];\n if (c === \" \" || c === \"+\" || c === \"-\") lineCount++;\n }\n\n const startRow = currentRow;\n const endRow = currentRow + lineCount - 1;\n currentRow = endRow + 1;\n\n hunks.push({\n diffString,\n oldStart: hunk.oldStart,\n oldLines: hunk.oldLines,\n newStart: hunk.newStart,\n newLines: hunk.newLines,\n skipBefore,\n lineCount,\n startRow,\n endRow,\n });\n }\n\n return { hunks, totalRows: Math.max(0, currentRow - 1) };\n } catch {\n return { hunks: [], totalRows: 0 };\n }\n}\n\nexport function getHunkIndexForRow(\n content: string,\n file: string,\n row: number,\n): number | null {\n const { hunks } = parseFileDiff(content, file);\n for (let i = 0; i < hunks.length; i++) {\n const hunk = hunks[i]!;\n if (row >= hunk.startRow && row <= hunk.endRow) return i;\n }\n return null;\n}\n\nfunction stripPrefix(path: string | undefined | null): string {\n if (!path) return \"\";\n return path.replace(/^a\\//, \"\").replace(/^b\\//, \"\");\n}\n\nexport function parsePatchEntries(content: string): Git.Entry[] {\n if (!content.trim()) return [];\n\n const chunks = content.trimEnd().split(/\\n(?=diff --git )/);\n const entries: Git.Entry[] = [];\n\n for (const chunk of chunks) {\n if (!chunk.trim()) continue;\n const parsed = parsePatch(chunk);\n const patch = parsed[0];\n\n let file = \"\";\n if (patch) {\n const newName = stripPrefix(patch.newFileName);\n const oldName = stripPrefix(patch.oldFileName);\n file = newName !== \"/dev/null\" ? newName : oldName;\n }\n\n if (!file) {\n const first = chunk.split(\"\\n\")[0] ?? \"\";\n const match = first.match(/^diff --git a\\/(.+?) b\\/(.+)$/);\n if (match) file = match[2] ?? match[1] ?? \"\";\n }\n\n if (!file) continue;\n\n const isNew =\n patch?.oldFileName === \"/dev/null\" || chunk.includes(\"\\nnew file mode\");\n const isDeleted =\n patch?.newFileName === \"/dev/null\" ||\n chunk.includes(\"\\ndeleted file mode\");\n\n entries.push({ file, content: chunk, isNew, isDeleted });\n }\n\n return entries;\n}\n\nexport function getHunkRowRange(\n content: string,\n file: string,\n hunkIndex: number,\n): { startRow: number; endRow: number } | null {\n const { hunks } = parseFileDiff(content, file);\n const hunk = hunks[hunkIndex];\n if (!hunk) return null;\n return { startRow: hunk.startRow, endRow: hunk.endRow };\n}\n",
|
|
15
|
+
"import {\n createContext,\n useContext,\n createSignal,\n createMemo,\n type ParentProps,\n type Accessor,\n} from \"solid-js\";\nimport { SyntaxStyle, type ThemeTokenStyle } from \"@opentui/core\";\n\nexport interface ThemeColors {\n // Backgrounds\n background: string; // Main app background\n backgroundPanel: string; // Panel backgrounds (slightly lighter)\n backgroundElement: string; // Interactive elements, hover states\n\n // Text\n text: string; // Primary text\n textMuted: string; // Secondary/gray text\n\n // Accents\n primary: string; // Focused elements, highlights\n primaryDark: string; // Focused elements, highlights\n secondary: string;\n secondaryDark: string;\n\n // Status\n added: string; // Green for additions\n removed: string; // Red for removals\n modified: string; // Yellow for modifications\n\n // Indicators\n indicatorDefault: string; // Default state for hunk indicators (not hovered, not selected)\n\n // Connection status\n connected: string; // Bright green for connected\n disconnected: string; // Bright red for disconnected\n\n // Diff backgrounds (for syntax-highlighted diff view)\n diffAddedBg: string; // Background for added lines\n diffRemovedBg: string; // Background for removed lines\n diffContextBg: string; // Background for unchanged context lines\n\n // Diff sign colors (the \"+\" and \"-\" indicators)\n diffSignAdded: string; // Color for \"+\" sign\n diffSignRemoved: string; // Color for \"-\" sign\n\n // Diff line number styling\n diffAddedLineNumberBg: string;\n diffRemovedLineNumberBg: string;\n diffLineNumberFg: string;\n\n // Syntax highlighting colors\n syntaxComment: string;\n syntaxKeyword: string;\n syntaxFunction: string;\n syntaxVariable: string;\n syntaxString: string;\n syntaxNumber: string;\n syntaxType: string;\n syntaxOperator: string;\n syntaxPunctuation: string;\n}\n\nexport type ThemeName = \"default\" | \"system\";\n\ninterface ThemeContextValue {\n theme: ThemeColors;\n themeName: Accessor<ThemeName>;\n setTheme: (name: ThemeName) => void;\n syntax: Accessor<SyntaxStyle>;\n}\n\nconst ThemeContext = createContext<ThemeContextValue>();\n\n// Default theme (opencode dark) - hardcoded values from opencode.json\nconst defaultTheme: ThemeColors = {\n background: \"#0a0a0a\", // darkStep1\n backgroundPanel: \"#141414\", // darkStep2\n backgroundElement: \"#1e1e1e\", // darkStep3\n text: \"#eeeeee\", // darkStep12\n textMuted: \"#808080\", // darkStep11\n primary: \"#63a088\", // zomp (teal-green)\n primaryDark: \"#1d2f28\",\n secondary: \"#608999\", // orange accent\n secondaryDark: \"#182226\", // orange accent\n added: \"#284036\", // dark green\n removed: \"#e06c75\", // darkRed\n modified: \"#e5c07b\", // darkYellow\n indicatorDefault: \"#4a4a4a\", // medium-dark gray for unselected hunks\n connected: \"#73d936\", // bright green\n disconnected: \"#ff5555\", // bright red\n\n // Diff styling (ayu-inspired colors)\n diffAddedBg: \"#20303b\", // dark blue-green tint\n diffRemovedBg: \"#37222c\", // dark red tint\n diffContextBg: \"111111\",\n diffSignAdded: \"#b8db87\", // bright green for \"+\"\n diffSignRemoved: \"#e26a75\", // bright red for \"-\"\n diffAddedLineNumberBg: \"#1a2a30\",\n diffRemovedLineNumberBg: \"#2d1a22\",\n diffLineNumberFg: \"#888888\",\n\n // Syntax highlighting (ayu-inspired)\n syntaxComment: \"#5c6773\",\n syntaxKeyword: \"#ff7733\",\n syntaxFunction: \"#ffb454\",\n syntaxVariable: \"#cbccc6\",\n syntaxString: \"#bae67e\",\n syntaxNumber: \"#ffcc66\",\n syntaxType: \"#73d0ff\",\n syntaxOperator: \"#f29e74\",\n syntaxPunctuation: \"#cbccc6\",\n};\n\n// System theme - uses terminal colors via ANSI names\nconst systemTheme: ThemeColors = {\n background: \"transparent\",\n backgroundPanel: \"brightBlack\",\n backgroundElement: \"gray\",\n text: \"white\",\n textMuted: \"brightBlack\",\n primary: \"cyan\",\n primaryDark: \"blue\",\n secondary: \"red\",\n secondaryDark: \"magenta\",\n added: \"green\",\n removed: \"red\",\n modified: \"yellow\",\n indicatorDefault: \"gray\",\n connected: \"brightGreen\",\n disconnected: \"brightRed\",\n\n // Diff styling (ANSI-based)\n diffAddedBg: \"green\",\n diffRemovedBg: \"red\",\n diffContextBg: \"transparent\",\n diffSignAdded: \"brightGreen\",\n diffSignRemoved: \"brightRed\",\n diffAddedLineNumberBg: \"green\",\n diffRemovedLineNumberBg: \"red\",\n diffLineNumberFg: \"brightBlack\",\n\n // Syntax highlighting (ANSI-based)\n syntaxComment: \"brightBlack\",\n syntaxKeyword: \"magenta\",\n syntaxFunction: \"blue\",\n syntaxVariable: \"white\",\n syntaxString: \"green\",\n syntaxNumber: \"yellow\",\n syntaxType: \"cyan\",\n syntaxOperator: \"white\",\n syntaxPunctuation: \"white\",\n};\n\nconst themes: Record<ThemeName, ThemeColors> = {\n default: defaultTheme,\n system: systemTheme,\n};\n\n// Map tree-sitter scopes to theme colors\nfunction getSyntaxRules(theme: ThemeColors): ThemeTokenStyle[] {\n return [\n {\n scope: [\"comment\", \"comment.documentation\"],\n style: { foreground: theme.syntaxComment, italic: true },\n },\n {\n scope: [\"string\", \"string.special\", \"character\"],\n style: { foreground: theme.syntaxString },\n },\n {\n scope: [\"number\", \"boolean\", \"constant\"],\n style: { foreground: theme.syntaxNumber },\n },\n {\n scope: [\n \"keyword\",\n \"keyword.return\",\n \"keyword.conditional\",\n \"keyword.repeat\",\n ],\n style: { foreground: theme.syntaxKeyword, italic: true },\n },\n {\n scope: [\"keyword.function\", \"keyword.import\"],\n style: { foreground: theme.syntaxKeyword },\n },\n {\n scope: [\"function\", \"function.call\", \"function.method\", \"constructor\"],\n style: { foreground: theme.syntaxFunction },\n },\n {\n scope: [\"variable\", \"variable.parameter\", \"variable.member\"],\n style: { foreground: theme.syntaxVariable },\n },\n {\n scope: [\"type\", \"type.builtin\", \"module\"],\n style: { foreground: theme.syntaxType },\n },\n {\n scope: [\"operator\", \"keyword.operator\"],\n style: { foreground: theme.syntaxOperator },\n },\n {\n scope: [\"punctuation\", \"punctuation.delimiter\", \"punctuation.bracket\"],\n style: { foreground: theme.syntaxPunctuation },\n },\n {\n scope: [\"property\"],\n style: { foreground: theme.syntaxVariable },\n },\n {\n scope: [\"tag\", \"tag.attribute\"],\n style: { foreground: theme.syntaxKeyword },\n },\n ];\n}\n\nexport function ThemeProvider(props: ParentProps) {\n const [themeName, setThemeName] = createSignal<ThemeName>(\"default\");\n\n // Create syntax style that updates when theme changes\n const syntax = createMemo(() => {\n const theme = themes[themeName()];\n return SyntaxStyle.fromTheme(getSyntaxRules(theme));\n });\n\n const value: ThemeContextValue = {\n get theme() {\n return themes[themeName()];\n },\n themeName,\n setTheme: setThemeName,\n syntax,\n };\n\n return (\n <ThemeContext.Provider value={value}>\n {props.children}\n </ThemeContext.Provider>\n );\n}\n\nexport function useTheme(): ThemeContextValue {\n const ctx = useContext(ThemeContext);\n if (!ctx) throw new Error(\"useTheme must be used within ThemeProvider\");\n return ctx;\n}\n",
|
|
16
|
+
"import { useTheme } from \"../context/theme\"\n\nexport const EmptyBorder = {\n topLeft: \"\",\n bottomLeft: \"\",\n vertical: \"\",\n topRight: \"\",\n bottomRight: \"\",\n horizontal: \" \",\n bottomT: \"\",\n topT: \"\",\n cross: \"\",\n leftT: \"\",\n rightT: \"\",\n}\n\nexport interface HalfLineShadowProps {\n color?: string\n}\n\nexport function HalfLineShadow(props: HalfLineShadowProps) {\n const { theme } = useTheme()\n const color = () => props.color ?? theme.backgroundPanel\n\n return (\n <box\n height={1}\n backgroundColor={theme.background}\n border={[\"top\"]}\n borderColor={color()}\n customBorderChars={{\n ...EmptyBorder,\n horizontal: \"\\u2580\",\n }}\n />\n )\n}\n",
|
|
17
|
+
"import { onMount } from \"solid-js\";\nimport { spawn } from \"child_process\";\nimport { writeFileSync, readFileSync } from \"fs\";\nimport type { TextareaRenderable, KeyEvent } from \"@opentui/core\";\nimport { useRenderer } from \"@opentui/solid\";\nimport { useTheme } from \"../context/theme\";\nimport { useReview } from \"../context/review\";\n\nexport interface EditorPanelProps {\n file: string;\n startRow: number;\n endRow: number;\n commentId?: number;\n onClose: () => void;\n}\n\nexport function EditorPanel(props: EditorPanelProps) {\n const { theme } = useTheme();\n const review = useReview();\n const renderer = useRenderer();\n\n let textareaRef: TextareaRenderable | null = null;\n let initialized = false;\n\n // Get existing comment for this file+range (if any)\n const existingComment = props.commentId\n ? review.getCommentById(props.commentId)\n : review.getCommentForRange(props.file, props.startRow, props.endRow);\n const initialContent = existingComment?.noteContent ?? \"\";\n\n // Filename is file_range (e.g., \"CommentList.tsx_rows-3-5.md\")\n const shortFile = props.file.split(\"/\").pop() ?? props.file;\n const rangeLabel = `rows-${props.startRow}-${props.endRow}`;\n const filename = `${shortFile}_${rangeLabel}.md`;\n\n // Mark as initialized after first render to ignore the trigger key\n onMount(() => {\n setTimeout(() => {\n initialized = true;\n }, 0);\n });\n\n const submit = async () => {\n if (!textareaRef) return;\n\n const content = textareaRef.editBuffer.getText();\n\n // Don't save empty comments\n if (!content.trim()) {\n props.onClose();\n return;\n }\n\n if (existingComment) {\n // Update existing comment\n await review.updateComment(existingComment.id, content);\n } else {\n // Create new comment\n await review.createComment(\n props.file,\n props.startRow,\n props.endRow,\n content,\n );\n }\n\n props.onClose();\n };\n\n const openInEditor = async () => {\n if (!textareaRef) return;\n\n const tmpFile = `/tmp/spall-${filename}`;\n writeFileSync(tmpFile, textareaRef.editBuffer.getText());\n\n renderer.suspend();\n\n await new Promise<void>((resolve, reject) => {\n const editor = process.env.EDITOR || \"nvim\";\n const child = spawn(editor, [tmpFile], { stdio: \"inherit\" });\n child.on(\"close\", (code) =>\n code === 0 ? resolve() : reject(new Error(`exit ${code}`)),\n );\n child.on(\"error\", reject);\n });\n\n const content = readFileSync(tmpFile, \"utf-8\");\n renderer.resume();\n\n // If empty, treat as cancel\n if (!content.trim()) {\n props.onClose();\n return;\n }\n\n // Update textarea with edited content, let user manually submit\n if (textareaRef) {\n textareaRef.editBuffer.setText(content);\n // Move cursor to end of content\n textareaRef.cursorOffset = content.length;\n }\n };\n\n const handleKeyDown = (e: KeyEvent) => {\n // Ignore the trigger key that opened this editor\n if (!initialized && (e.name === \"c\" || e.name === \"return\")) {\n e.preventDefault();\n return;\n }\n\n // Escape: close without saving\n if (e.name === \"escape\") {\n e.preventDefault();\n props.onClose();\n return;\n }\n\n // Enter: submit\n if (e.name === \"return\") {\n e.preventDefault();\n submit();\n return;\n }\n\n if (e.name === \"j\" && e.ctrl) {\n e.preventDefault();\n textareaRef?.editBuffer.newLine();\n return;\n }\n\n if (e.name === \"e\" && e.ctrl) {\n e.preventDefault();\n void openInEditor();\n return;\n }\n };\n\n return (\n <box\n flexDirection=\"column\"\n backgroundColor={theme.backgroundPanel}\n flexShrink={0}\n >\n {/* Textarea with padding */}\n <box paddingLeft={1} paddingRight={1} paddingTop={1} paddingBottom={1}>\n <textarea\n ref={(r: TextareaRenderable) => {\n textareaRef = r;\n }}\n initialValue={initialContent || undefined}\n focused={true}\n showCursor\n wrapMode=\"word\"\n minHeight={1}\n maxHeight={6}\n width=\"100%\"\n onKeyDown={handleKeyDown}\n />\n </box>\n\n {/* Footer with filename */}\n <box height={1} paddingLeft={1}>\n <text fg={theme.textMuted}>{filename}</text>\n </box>\n </box>\n );\n}\n",
|
|
18
|
+
"import {\n createContext,\n useContext,\n createSignal,\n createEffect,\n onMount,\n type ParentProps,\n type Accessor,\n} from \"solid-js\";\nimport { Git } from \"../lib/git\";\nimport { parsePatchEntries } from \"../lib/diff\";\nimport { Repo, Review as ReviewStore, Patch, ReviewComment } from \"../store\";\nimport { useServer } from \"./server\";\n\n// Comment with hydrated note details\nexport interface CommentWithNote {\n id: number;\n reviewId: number;\n noteId: number;\n file: string;\n patchId: number;\n startRow: number;\n endRow: number;\n createdAt: number;\n // Hydrated from server\n notePath: string | null;\n noteContent: string | null;\n}\n\nexport function pickCommentForRange(\n list: CommentWithNote[],\n preferredPatchId: number | null,\n file: string,\n startRow: number,\n endRow: number,\n): CommentWithNote | null {\n if (preferredPatchId !== null) {\n const exact =\n list.find(\n (c) =>\n c.patchId === preferredPatchId &&\n c.file === file &&\n c.startRow === startRow &&\n c.endRow === endRow,\n ) ?? null;\n if (exact) return exact;\n }\n\n const matches = list.filter(\n (c) => c.file === file && c.startRow === startRow && c.endRow === endRow,\n );\n if (matches.length === 0) return null;\n return matches.reduce((best, c) => (c.createdAt > best.createdAt ? c : best));\n}\n\nexport interface ReviewContextValue {\n // Corpus state\n corpusId: Accessor<number | null>;\n corpusName: Accessor<string>;\n\n // Current working tree snapshot (stored as a patch)\n workingTreePatchId: Accessor<number | null>;\n\n // Repo state\n repoRoot: Accessor<string | null>;\n repoPath: Accessor<string>;\n\n // Review state\n reviewId: Accessor<number | null>;\n commitSha: Accessor<string | null>;\n activePatchId: Accessor<number | null>;\n\n // Diff state\n workspaceEntries: Accessor<Git.Entry[]>;\n entries: Accessor<Git.Entry[]>;\n loading: Accessor<boolean>;\n\n // Patches state\n patches: Accessor<Patch.Info[]>;\n patchesLoading: Accessor<boolean>;\n\n // Comments state\n comments: Accessor<CommentWithNote[]>;\n commentsLoading: Accessor<boolean>;\n\n // File selection state\n selectedFilePath: Accessor<string | null>;\n setSelectedFilePath: (path: string | null) => void;\n\n // Actions\n setActivePatch: (patchId: number | null, preserveFilePath?: string) => void;\n refreshWorkingTree: (preserveFilePath?: string) => Promise<void>;\n getCommentById: (commentId: number) => CommentWithNote | null;\n getCommentForRange: (\n file: string,\n startRow: number,\n endRow: number,\n ) => CommentWithNote | null;\n createComment: (\n file: string,\n startRow: number,\n endRow: number,\n content: string,\n ) => Promise<CommentWithNote | null>;\n updateComment: (commentId: number, content: string) => Promise<void>;\n}\n\nconst ReviewContext = createContext<ReviewContextValue>();\n\nexport interface ReviewProviderProps extends ParentProps {\n repoPath: string;\n}\n\n// Get repo name from path (last segment)\nfunction repoName(path: string): string {\n const segments = path.split(\"/\").filter(Boolean);\n return segments[segments.length - 1] || \"unknown\";\n}\n\nconst REVIEW_CORPUS_NAME = \"spall-review\";\n\nfunction repoKey(root: string): string {\n const base = repoName(root).replace(/[^a-zA-Z0-9._-]+/g, \"-\");\n const h = Bun.hash(root);\n const n = typeof h === \"bigint\" ? Number(h % 0xffffffffn) : h;\n const suffix = Math.abs(n).toString(36).slice(0, 6);\n return `${base}-${suffix}`;\n}\n\nfunction reviewNotePath(input: {\n root: string;\n commitSha: string;\n patchSeq: number;\n file: string;\n startRow: number;\n endRow: number;\n}): string {\n const filePath = input.file.replace(/\\\\/g, \"/\");\n return `review/${repoKey(input.root)}/${input.commitSha}/p${input.patchSeq}/${filePath}__${input.startRow}-${input.endRow}.md`;\n}\n\nexport function ReviewProvider(props: ReviewProviderProps) {\n const server = useServer();\n\n const [corpusId, setCorpusId] = createSignal<number | null>(null);\n const corpusName = () => REVIEW_CORPUS_NAME;\n\n // Repo state\n const [repoRoot, setRepoRoot] = createSignal<string | null>(null);\n\n // Review state\n const [reviewId, setReviewId] = createSignal<number | null>(null);\n const [commitSha, setCommitSha] = createSignal<string | null>(null);\n const [activePatchId, setActivePatchIdState] = createSignal<number | null>(\n null,\n );\n\n const [workingTreePatchId, setWorkingTreePatchId] = createSignal<\n number | null\n >(null);\n\n // Diff state\n const [workspaceEntries, setWorkspaceEntries] = createSignal<Git.Entry[]>([]);\n const [workspaceDiff, setWorkspaceDiff] = createSignal<string>(\"\");\n const [entries, setEntries] = createSignal<Git.Entry[]>([]);\n const [loading, setLoading] = createSignal(true);\n\n const ensureReviewId = (root: string, head: string): number => {\n const current = reviewId();\n if (current !== null) return current;\n const repo = Repo.getOrCreate(root);\n const review = ReviewStore.getOrCreate(repo.id, head);\n setReviewId(review.id);\n return review.id;\n };\n\n // Patches state\n const [patches, setPatches] = createSignal<Patch.Info[]>([]);\n const [patchesLoading, setPatchesLoading] = createSignal(false);\n\n // Comments state\n const [comments, setComments] = createSignal<CommentWithNote[]>([]);\n const [commentsLoading, setCommentsLoading] = createSignal(false);\n\n // File selection state (stable across entry ordering)\n const [selectedFilePath, setSelectedFilePath] = createSignal<string | null>(\n null,\n );\n\n const preserveSelectedFilePath = (\n list: Git.Entry[],\n preferred?: string | null,\n ) => {\n if (!preferred) return null;\n return list.some((e) => e.file === preferred) ? preferred : null;\n };\n\n const setActivePatch = (\n patchId: number | null,\n preserveFilePath?: string,\n ) => {\n if (patchId === null) {\n const wt = workingTreePatchId();\n if (wt !== null) {\n setActivePatch(wt, preserveFilePath);\n return;\n }\n\n setActivePatchIdState(null);\n const ws = parsePatchEntries(workspaceDiff());\n setEntries(ws);\n setSelectedFilePath(\n preserveSelectedFilePath(ws, preserveFilePath ?? selectedFilePath()),\n );\n return;\n }\n\n const patch = Patch.get(patchId);\n if (!patch) return;\n\n setActivePatchIdState(patchId);\n const newEntries = parsePatchEntries(patch.content);\n setEntries(newEntries);\n\n setSelectedFilePath(\n preserveSelectedFilePath(\n newEntries,\n preserveFilePath ?? selectedFilePath(),\n ),\n );\n };\n\n const refreshWorkingTree = async (preserveFilePath?: string) => {\n const newEntries = await Git.entries(props.repoPath);\n setWorkspaceEntries(newEntries);\n const fullDiff = newEntries.map((x) => x.content).join(\"\\n\");\n setWorkspaceDiff(fullDiff);\n\n const root = repoRoot();\n const head = commitSha();\n\n // If we can't associate this with a review yet, still update the view.\n if (!root || !head) {\n if (activePatchId() === null) {\n const ws = parsePatchEntries(fullDiff);\n setEntries(ws);\n setSelectedFilePath(\n preserveSelectedFilePath(ws, preserveFilePath ?? selectedFilePath()),\n );\n }\n setWorkingTreePatchId(null);\n return;\n }\n\n const revId = ensureReviewId(root, head);\n const patch = Patch.getOrCreate(revId, fullDiff);\n\n const prevWt = workingTreePatchId();\n setWorkingTreePatchId(patch.id);\n\n setPatches((prev) => {\n if (prev.some((p) => p.id === patch.id)) return prev;\n return [...prev, patch].sort((a, b) => a.seq - b.seq);\n });\n\n // If we were viewing the working tree snapshot, advance it.\n const active = activePatchId();\n if (active === null || (prevWt !== null && active === prevWt)) {\n setActivePatch(patch.id, preserveFilePath);\n }\n };\n\n // Gate hydration work that touches either database with:\n // - a signal, to ensure local review/comments are loaded\n // - some booleans, to keep it one-shot\n const [initialized, setInitialized] = createSignal(false);\n let corpusInitInFlight = false;\n let commentsHydrated = false;\n\n createEffect(() => {\n const client = server.client();\n if (!client || !initialized()) return;\n\n if (corpusId() === null && !corpusInitInFlight) {\n corpusInitInFlight = true;\n void (async () => {\n try {\n const result = await client.corpus.create({\n name: REVIEW_CORPUS_NAME,\n });\n if (result.data) {\n setCorpusId(result.data.id);\n }\n } catch {\n // no-op: we'll try again if the client reconnects\n } finally {\n corpusInitInFlight = false;\n }\n })();\n }\n\n if (commentsHydrated) return;\n const pending = comments().filter(\n (c) => c.notePath === null || c.noteContent === null,\n );\n if (pending.length === 0) {\n commentsHydrated = true;\n return;\n }\n\n commentsHydrated = true;\n setCommentsLoading(true);\n void (async () => {\n try {\n const results = await Promise.all(\n pending.map(async (comment) => {\n try {\n const result = await client.note.getById({\n id: comment.noteId.toString(),\n });\n if (!result.data) return null;\n return {\n id: comment.id,\n notePath: result.data.path,\n noteContent: result.data.content,\n };\n } catch {\n return null;\n }\n }),\n );\n\n const byId = new Map(\n results.filter(Boolean).map((r) => [r!.id, r!] as const),\n );\n\n setComments((prev) =>\n prev.map((c) => {\n const upd = byId.get(c.id);\n return upd\n ? { ...c, notePath: upd.notePath, noteContent: upd.noteContent }\n : c;\n }),\n );\n } finally {\n setCommentsLoading(false);\n }\n })();\n });\n\n onMount(async () => {\n // load everything from the tui db\n const root = await Git.root(props.repoPath);\n setRepoRoot(root);\n\n const head = await Git.head(props.repoPath);\n setCommitSha(head);\n\n // Ensure a review exists for this (repo, commit) so the working tree\n // snapshot can be treated as a normal patch.\n if (root && head) {\n ensureReviewId(root, head);\n }\n\n const revId = reviewId();\n if (revId) {\n // Load comments from local DB\n const local = ReviewComment.list(revId);\n setComments(\n local.map((c) => ({\n id: c.id,\n reviewId: c.review,\n noteId: c.noteId,\n file: c.file,\n patchId: c.patchId,\n startRow: c.startRow,\n endRow: c.endRow,\n createdAt: c.createdAt,\n notePath: null,\n noteContent: null,\n })),\n );\n\n // Load patches\n setPatchesLoading(true);\n setPatches(Patch.list(revId));\n setPatchesLoading(false);\n }\n\n // Capture the working tree snapshot and select it.\n await refreshWorkingTree(selectedFilePath() ?? undefined);\n\n // Prune unreferenced patches; keep the current working tree snapshot.\n if (revId) {\n const wt = workingTreePatchId();\n Patch.pruneUnreferenced(revId, wt !== null ? [wt] : []);\n setPatches(Patch.list(revId));\n }\n\n setLoading(false);\n\n setInitialized(true);\n\n // No automatic polling; user refreshes explicitly.\n });\n\n const getCommentById = (commentId: number): CommentWithNote | null => {\n return comments().find((c) => c.id === commentId) ?? null;\n };\n\n const getCommentForRange = (\n file: string,\n startRow: number,\n endRow: number,\n ): CommentWithNote | null => {\n const patchId = activePatchId();\n return pickCommentForRange(comments(), patchId, file, startRow, endRow);\n };\n\n const createComment = async (\n file: string,\n startRow: number,\n endRow: number,\n content: string,\n ): Promise<CommentWithNote | null> => {\n const root = repoRoot();\n const head = commitSha();\n const c = server.client();\n let cid = corpusId();\n\n if (!root || !head) return null;\n if (!content.trim()) return null;\n\n // ensure an entry in the reviews table\n const repo = Repo.getOrCreate(root);\n\n let revId = reviewId();\n if (!revId) {\n const review = ReviewStore.getOrCreate(repo.id, head);\n revId = review.id;\n setReviewId(revId);\n }\n\n // ensure the current changeset exists in the patches table\n let patch = activePatchId() ? Patch.get(activePatchId()!) : null;\n if (!patch) {\n const wt = workingTreePatchId();\n patch = wt !== null ? Patch.get(wt) : null;\n\n // As a fallback (shouldn't happen), persist the current working tree diff.\n if (!patch) {\n const fullDiff = workspaceDiff();\n patch = Patch.getOrCreate(revId, fullDiff);\n setWorkingTreePatchId(patch.id);\n setPatches((prev) => {\n if (prev.some((p) => p.id === patch!.id)) return prev;\n return [...prev, patch!].sort((a, b) => a.seq - b.seq);\n });\n if (activePatchId() === null) setActivePatch(patch.id);\n }\n }\n\n if (!patch) return null;\n\n // If we have a server connection, upsert the note via SDK\n if (c) {\n if (cid === null) {\n try {\n const ensured = await c.corpus.create({ name: REVIEW_CORPUS_NAME });\n if (ensured.data) {\n cid = ensured.data.id;\n setCorpusId(cid);\n }\n } catch {\n // ignore\n }\n }\n if (cid === null) return null;\n\n const path = reviewNotePath({\n root,\n commitSha: head,\n patchSeq: patch.seq,\n file,\n startRow,\n endRow,\n });\n\n const result = await c.note.upsert({\n id: cid.toString(),\n path,\n content,\n dupe: true,\n });\n\n if (result.error || !result.data) {\n return null;\n }\n const noteId = result.data.id;\n\n // Create review comment linking to the note\n const localComment = ReviewComment.create({\n review: revId,\n noteId,\n file,\n patchId: patch.id,\n startRow,\n endRow,\n });\n\n // Build the hydrated comment\n const newComment: CommentWithNote = {\n id: localComment.id,\n reviewId: revId,\n noteId,\n file,\n patchId: localComment.patchId,\n startRow: localComment.startRow,\n endRow: localComment.endRow,\n createdAt: localComment.createdAt,\n notePath: path,\n noteContent: content,\n };\n\n // Add to comments list\n setComments((prev) => [...prev, newComment]);\n\n return newComment;\n }\n\n // No server connection - can't save note\n return null;\n };\n\n const updateComment = async (\n commentId: number,\n content: string,\n ): Promise<void> => {\n const c = server.client();\n\n if (!c) return;\n if (!content.trim()) return;\n\n // Find the comment to get its noteId\n const comment = comments().find((c) => c.id === commentId);\n if (!comment) return;\n\n // Update the note via SDK\n const result = await c.note.update({\n id: comment.noteId.toString(),\n content,\n dupe: true,\n });\n\n if (result.error) return;\n\n // Update local state\n setComments((prev) =>\n prev.map((c) =>\n c.id === commentId ? { ...c, noteContent: content } : c,\n ),\n );\n };\n\n const value: ReviewContextValue = {\n // Corpus\n corpusId,\n corpusName,\n // Working tree snapshot\n workingTreePatchId,\n // Repo\n repoRoot,\n repoPath: () => props.repoPath,\n // Review\n reviewId,\n commitSha,\n activePatchId,\n // Diff\n workspaceEntries,\n entries,\n loading,\n // Patches\n patches,\n patchesLoading,\n // Comments\n comments,\n commentsLoading,\n // File selection\n selectedFilePath,\n setSelectedFilePath,\n // Actions\n setActivePatch,\n refreshWorkingTree,\n getCommentById,\n getCommentForRange,\n createComment,\n updateComment,\n };\n\n return (\n <ReviewContext.Provider value={value}>\n {props.children}\n </ReviewContext.Provider>\n );\n}\n\nexport function useReview(): ReviewContextValue {\n const ctx = useContext(ReviewContext);\n if (!ctx) throw new Error(\"useReview must be used within ReviewProvider\");\n return ctx;\n}\n",
|
|
19
|
+
"import {\n createContext,\n useContext,\n createSignal,\n onMount,\n onCleanup,\n type ParentProps,\n type Accessor,\n} from \"solid-js\";\nimport { Client, SpallClient } from \"@spader/spall-sdk/client\";\n\nexport interface ServerContextValue {\n url: Accessor<string | null>;\n connected: Accessor<boolean>;\n client: Accessor<SpallClient | null>;\n}\n\nconst ServerContext = createContext<ServerContextValue>();\n\nexport function ServerProvider(props: ParentProps) {\n const [url, setUrl] = createSignal<string | null>(null);\n const [connected, setConnected] = createSignal(false);\n const [client, setClient] = createSignal<SpallClient | null>(null);\n\n let shutdown = false;\n const controller = new AbortController()\n\n onMount(() => {\n const connect = async () => {\n while (!shutdown) {\n try {\n const c = await Client.connect(controller.signal);\n const health = await c.health();\n\n if (!health?.response?.ok) {\n throw new Error(\"Health check failed\");\n }\n\n setUrl(health.response.url.replace(\"/health\", \"\"));\n setConnected(true);\n setClient(c);\n\n const { stream } = await c.events({\n onSseError: () => {\n setConnected(false);\n setClient(null);\n },\n sseMaxRetryAttempts: 0,\n });\n\n for await (const event of stream) {\n\n }\n } catch {\n setConnected(false);\n setClient(null);\n setUrl(null);\n await Bun.sleep(100);\n }\n }\n };\n\n connect();\n });\n\n onCleanup(() => {\n shutdown = true;\n controller.abort();\n });\n\n const value: ServerContextValue = {\n url,\n connected,\n client,\n };\n\n return (\n <ServerContext.Provider value={value}>\n {props.children}\n </ServerContext.Provider>\n );\n}\n\nexport function useServer(): ServerContextValue {\n const ctx = useContext(ServerContext);\n if (!ctx) throw new Error(\"useServer must be used within ServerProvider\");\n return ctx;\n}\n",
|
|
20
|
+
"import { useKeyboard, useRenderer } from \"@opentui/solid\"\n\nexport interface ErrorFallbackProps {\n error: Error\n reset: () => void\n}\n\nexport function ErrorFallback(props: ErrorFallbackProps) {\n const renderer = useRenderer()\n\n useKeyboard((key) => {\n if (key.name === \"r\") {\n props.reset()\n }\n if (key.name === \"q\" || key.raw === \"\\u0003\") {\n renderer.destroy()\n }\n })\n\n return (\n <box flexDirection=\"column\" padding={2}>\n <text fg=\"red\">Error: {props.error.message}</text>\n <text></text>\n <text fg=\"gray\">Press 'r' to retry or 'q' to quit</text>\n </box>\n )\n}\n",
|
|
21
|
+
"import { For, createSignal, createMemo, Show } from \"solid-js\"\nimport { useKeyboard, useRenderer, useTerminalDimensions } from \"@opentui/solid\"\nimport { RGBA } from \"@opentui/core\"\nimport { useCommand } from \"../context/command\"\nimport { useDialog } from \"../context/dialog\"\nimport { useTheme } from \"../context/theme\"\nimport { formatKeybind, type Command, type CommandCategory } from \"../lib/keybind\"\n\n// Category display order\nconst CATEGORY_ORDER: CommandCategory[] = [\"movement\", \"selection\", \"actions\"]\n\nexport function CommandPalette() {\n const dims = useTerminalDimensions()\n const renderer = useRenderer()\n const command = useCommand()\n const dialog = useDialog()\n const { theme } = useTheme()\n const [selectedIndex, setSelectedIndex] = createSignal(0)\n\n // Only show active commands, deduplicated by title\n const entries = createMemo(() => {\n const active = command.entries().filter((cmd) => cmd.isActive())\n // Deduplicate by title (e.g., multiple \"back\" commands)\n const seen = new Set<string>()\n return active.filter((cmd) => {\n if (seen.has(cmd.title)) return false\n seen.add(cmd.title)\n return true\n })\n })\n\n // Group entries by category\n const groupedEntries = createMemo(() => {\n const groups: { category: CommandCategory; commands: Command[] }[] = []\n const byCategory = new Map<CommandCategory, Command[]>()\n\n for (const cmd of entries()) {\n const list = byCategory.get(cmd.category) ?? []\n list.push(cmd)\n byCategory.set(cmd.category, list)\n }\n\n // Build groups in display order\n for (const cat of CATEGORY_ORDER) {\n const cmds = byCategory.get(cat)\n if (cmds && cmds.length > 0) {\n groups.push({ category: cat, commands: cmds })\n }\n }\n\n return groups\n })\n\n // Flat list of commands for navigation (ignoring category headers)\n const flatEntries = createMemo(() => {\n return groupedEntries().flatMap((g) => g.commands)\n })\n\n useKeyboard((key) => {\n // Quit app on Ctrl+C or Ctrl+D\n if (key.ctrl && (key.name === \"c\" || key.name === \"d\")) {\n renderer.destroy()\n return\n }\n\n // Close palette on Escape\n if (key.name === \"escape\") {\n dialog.clear()\n return\n }\n\n if (key.name === \"up\" || key.name === \"k\") {\n setSelectedIndex((i) => Math.max(0, i - 1))\n return\n }\n\n if (key.name === \"down\" || key.name === \"j\") {\n setSelectedIndex((i) => Math.min(flatEntries().length - 1, i + 1))\n return\n }\n\n if (key.name === \"return\") {\n const entry = flatEntries()[selectedIndex()]\n if (entry) {\n dialog.clear()\n entry.onExecute()\n }\n return\n }\n })\n\n const width = () => Math.min(40, dims().width - 4)\n\n // Track current index across all commands for selection highlighting\n let currentIndex = 0\n\n return (\n <box\n position=\"absolute\"\n left={0}\n top={0}\n width={dims().width}\n height={dims().height}\n justifyContent=\"center\"\n alignItems=\"center\"\n backgroundColor={RGBA.fromInts(0, 0, 0, 150)}\n >\n <box\n width={width()}\n flexDirection=\"column\"\n backgroundColor={theme.backgroundPanel}\n paddingTop={1}\n paddingBottom={1}\n >\n {/* Title bar */}\n <box height={1} justifyContent=\"center\" paddingLeft={2} paddingRight={2}>\n <text>\n <span style={{ bold: true }}>Commands</span>\n </text>\n </box>\n\n {/* Separator */}\n <box height={1} />\n\n {/* Command list grouped by category */}\n <For each={groupedEntries()}>\n {(group, groupIndex) => {\n const startIndex = createMemo(() => {\n let idx = 0\n const groups = groupedEntries()\n for (let i = 0; i < groupIndex(); i++) {\n idx += groups[i]!.commands.length\n }\n return idx\n })\n\n return (\n <>\n {/* Category header */}\n <Show when={groupIndex() > 0}>\n <box height={1} />\n </Show>\n <box paddingLeft={2} paddingRight={2}>\n <text fg={theme.secondary}>\n <span style={{ bold: true }}>{group.category}</span>\n </text>\n </box>\n\n {/* Commands in this category */}\n <For each={group.commands}>\n {(entry, cmdIndex) => {\n const globalIndex = () => startIndex() + cmdIndex()\n return (\n <box flexDirection=\"row\" justifyContent=\"space-between\" paddingLeft={2} paddingRight={2}>\n <text fg={globalIndex() === selectedIndex() ? theme.primary : undefined}>\n {entry.title}\n </text>\n <box flexDirection=\"row\" gap={1}>\n <For each={entry.keybinds}>\n {(bind) => (\n <box>\n <text fg={theme.textMuted}>{formatKeybind(bind)}</text>\n </box>\n )}\n </For>\n </box>\n </box>\n )\n }}\n </For>\n </>\n )\n }}\n </For>\n </box>\n </box>\n )\n}\n",
|
|
22
|
+
"import { createContext, useContext, createSignal, type ParentProps, type Accessor } from \"solid-js\"\nimport type { Command } from \"../lib/keybind\"\n\ninterface CommandContextValue {\n register: (commands: Accessor<Command[]>) => void\n entries: Accessor<Command[]>\n}\n\nconst CommandContext = createContext<CommandContextValue>()\n\nexport function CommandProvider(props: ParentProps) {\n const [registrations, setRegistrations] = createSignal<Accessor<Command[]>[]>([])\n\n const value: CommandContextValue = {\n register: (commands) => {\n setRegistrations((prev) => [...prev, commands])\n },\n entries: () => registrations().flatMap((r) => r()),\n }\n\n return (\n <CommandContext.Provider value={value}>\n {props.children}\n </CommandContext.Provider>\n )\n}\n\nexport function useCommand(): CommandContextValue {\n const ctx = useContext(CommandContext)\n if (!ctx) throw new Error(\"useCommand must be used within CommandProvider\")\n return ctx\n}\n",
|
|
23
|
+
"import { createContext, useContext, createSignal, type JSX, type ParentProps } from \"solid-js\"\n\ninterface DialogContextValue {\n show: (element: () => JSX.Element) => void\n clear: () => void\n isOpen: () => boolean\n content: () => JSX.Element | null\n}\n\nconst DialogContext = createContext<DialogContextValue>()\n\nexport function DialogProvider(props: ParentProps) {\n const [content, setContent] = createSignal<(() => JSX.Element) | null>(null)\n\n const value: DialogContextValue = {\n show: (element) => setContent(() => element),\n clear: () => setContent(null),\n isOpen: () => content() !== null,\n content: () => {\n const c = content()\n return c ? c() : null\n },\n }\n\n return (\n <DialogContext.Provider value={value}>\n {props.children}\n </DialogContext.Provider>\n )\n}\n\nexport function useDialog(): DialogContextValue {\n const ctx = useContext(DialogContext)\n if (!ctx) throw new Error(\"useDialog must be used within DialogProvider\")\n return ctx\n}\n",
|
|
24
|
+
"import type { ParsedKey } from \"@opentui/core\"\n\nexport interface KeybindInfo {\n name: string\n ctrl?: boolean\n meta?: boolean\n shift?: boolean\n}\n\nexport type CommandCategory = \"movement\" | \"selection\" | \"actions\"\n\nexport interface Command {\n id: string\n title: string\n category: CommandCategory\n keybinds: KeybindInfo[]\n isActive: () => boolean\n onExecute: () => void\n}\n\n/** Check if a ParsedKey matches a KeybindInfo */\nexport function matchKey(key: ParsedKey, bind: KeybindInfo): boolean {\n if (key.name !== bind.name) return false\n if ((bind.ctrl ?? false) !== key.ctrl) return false\n if ((bind.meta ?? false) !== key.meta) return false\n if ((bind.shift ?? false) !== key.shift) return false\n return true\n}\n\n/** Check if a ParsedKey matches any of the bindings */\nexport function matchAny(key: ParsedKey, binds: KeybindInfo[]): boolean {\n return binds.some((bind) => matchKey(key, bind))\n}\n\n/** Format a keybind for display (e.g., \"C-c\", \"return\", \"a\") */\nexport function formatKeybind(bind: KeybindInfo): string {\n const parts: string[] = []\n if (bind.ctrl) parts.push(\"C\")\n if (bind.meta) parts.push(\"M\")\n if (bind.shift) parts.push(\"S\")\n parts.push(bind.name)\n return parts.join(\"-\")\n}\n",
|
|
25
|
+
"import { For, Show, createEffect } from \"solid-js\";\nimport type { Accessor } from \"solid-js\";\nimport type { ScrollBoxRenderable } from \"@opentui/core\";\nimport type { DisplayItem } from \"../../lib/tree\";\nimport { useTheme } from \"../../context/theme\";\nimport { Title } from \"./Section\";\nimport type { Git } from \"../../lib/git\";\n\nexport interface FileListProps {\n displayItems: Accessor<DisplayItem[]>;\n selectedFileIndex: Accessor<number>;\n fileIndices: Accessor<number[]>;\n entries: Accessor<Git.Entry[]>;\n loading: Accessor<boolean>;\n focused: Accessor<boolean>;\n}\n\nconst SCROLL_BUFFER = 2;\n\nfunction fileDiffStats(content: string): { added: number; removed: number } {\n let added = 0;\n let removed = 0;\n for (const line of content.split(\"\\n\")) {\n if (line.startsWith(\"+++\") || line.startsWith(\"---\")) continue;\n if (line.startsWith(\"+\")) added++;\n else if (line.startsWith(\"-\")) removed++;\n }\n return { added, removed };\n}\n\nexport function FileList(props: FileListProps) {\n const { theme } = useTheme();\n let scrollbox: ScrollBoxRenderable | null = null;\n\n const isSelected = (item: DisplayItem): boolean => {\n if (item.node.type !== \"file\") return false;\n const selectedEntryIndex = props.fileIndices()[props.selectedFileIndex()];\n return item.node.entryIndex === selectedEntryIndex;\n };\n\n // Find the display index for the currently selected file\n const getSelectedDisplayIndex = (): number => {\n const selectedEntryIndex = props.fileIndices()[props.selectedFileIndex()];\n return props\n .displayItems()\n .findIndex(\n (item) =>\n item.node.type === \"file\" &&\n item.node.entryIndex === selectedEntryIndex,\n );\n };\n\n // Scroll to keep selection visible with buffer\n createEffect(() => {\n const displayIndex = getSelectedDisplayIndex();\n if (displayIndex < 0 || !scrollbox) return;\n\n const viewportHeight = scrollbox.viewport.height;\n const scrollTop = scrollbox.scrollTop;\n const itemTop = displayIndex;\n const itemBottom = displayIndex + 1;\n\n // Scroll up if item is above viewport (with buffer at top)\n if (itemTop < scrollTop + SCROLL_BUFFER) {\n scrollbox.scrollTo(Math.max(0, itemTop - SCROLL_BUFFER));\n }\n // Scroll down if item is below viewport (with buffer at bottom)\n else if (itemBottom > scrollTop + viewportHeight - SCROLL_BUFFER) {\n scrollbox.scrollTo(itemBottom - viewportHeight + SCROLL_BUFFER);\n }\n });\n\n return (\n <box\n flexGrow={1}\n flexDirection=\"column\"\n backgroundColor={theme.backgroundPanel}\n >\n <Title section=\"files\" />\n\n <Show when={props.loading()}>\n <box>\n <text>Loading...</text>\n </box>\n </Show>\n\n <Show when={!props.loading() && props.displayItems().length === 0}>\n <box>\n <text>No changes found</text>\n </box>\n </Show>\n\n <Show when={!props.loading() && props.displayItems().length > 0}>\n <scrollbox ref={(r) => (scrollbox = r)} flexGrow={1}>\n <For each={props.displayItems()}>\n {(item) => {\n if (item.node.type === \"dir\") {\n return (\n <box flexDirection=\"row\">\n <Show when={item.depth > 0}>\n <text>{\" \".repeat(item.depth)}</text>\n </Show>\n <text>{\"\\u25BE \"}</text>\n <text>{item.node.name}</text>\n </box>\n );\n }\n\n const textColor = () =>\n isSelected(item) ? theme.primary : undefined;\n\n const bgColor = () =>\n isSelected(item) ? theme.backgroundElement : theme.backgroundPanel;\n\n const entryIndex = item.node.entryIndex;\n const entry =\n typeof entryIndex === \"number\"\n ? props.entries()[entryIndex]\n : undefined;\n const stats = entry ? fileDiffStats(entry.content) : null;\n\n return (\n <box flexDirection=\"row\" gap={1} backgroundColor={bgColor()}>\n <Show when={item.depth > 0}>\n <text>{\" \".repeat(item.depth)}</text>\n </Show>\n <text fg={theme.textMuted}>{item.node.status}</text>\n <text fg={textColor()}>{item.node.name}</text>\n <Show when={!!stats && (stats.added > 0)}>\n <text fg={theme.diffSignAdded}>{`+${stats!.added}`}</text>\n </Show>\n <Show when={!!stats && (stats.removed > 0)}>\n <text fg={theme.diffSignRemoved}>{`-${stats!.removed}`}</text>\n </Show>\n\n </box>\n );\n }}\n </For>\n </scrollbox>\n </Show>\n </box>\n );\n}\n",
|
|
26
|
+
"import {\n createContext,\n useContext,\n type ParentProps,\n type Accessor,\n} from \"solid-js\";\n\nexport type SidebarSection = \"files\" | \"comments\" | \"patches\";\n\ninterface SidebarContextValue {\n activeSection: Accessor<SidebarSection>;\n isFocused: Accessor<boolean>;\n}\n\nconst SidebarContext = createContext<SidebarContextValue>();\n\nexport function SidebarProvider(\n props: ParentProps<{\n activeSection: Accessor<SidebarSection>;\n isFocused: Accessor<boolean>;\n }>,\n) {\n const value: SidebarContextValue = {\n activeSection: props.activeSection,\n isFocused: props.isFocused,\n };\n\n return (\n <SidebarContext.Provider value={value}>\n {props.children}\n </SidebarContext.Provider>\n );\n}\n\nexport function useSidebar(): SidebarContextValue {\n const ctx = useContext(SidebarContext);\n if (!ctx) throw new Error(\"useSidebar must be used within SidebarProvider\");\n return ctx;\n}\n",
|
|
27
|
+
"import type { JSXElement } from \"solid-js\";\nimport { useTheme } from \"../../context/theme\";\nimport { useSidebar, type SidebarSection } from \"../../context/sidebar\";\nimport { EmptyBorder } from \"../HalfLineShadow\";\n\n/** Static section title (for Server, Project, etc.) */\nfunction SectionTitle(props: { title: string }) {\n return (\n <box flexShrink={0}>\n <text>\n <span style={{ bold: true }}>{props.title}</span>\n </text>\n </box>\n );\n}\n\n/** Selectable sidebar section title (for Files, Comments) */\nexport function Title(props: { section: SidebarSection }) {\n const { theme } = useTheme();\n const sidebar = useSidebar();\n\n const isActive = () =>\n sidebar.activeSection() === props.section && sidebar.isFocused();\n const title = () =>\n props.section.charAt(0).toUpperCase() + props.section.slice(1);\n\n return (\n <box\n flexShrink={0}\n border={[\"left\"]}\n borderColor={isActive() ? theme.primary : theme.indicatorDefault}\n backgroundColor={isActive() ? theme.backgroundElement : theme.backgroundPanel}\n customBorderChars={{\n ...EmptyBorder,\n vertical: \"\\u258C\",\n }}\n >\n <text>\n <span style={{ bold: true }}>{title()}</span>\n </text>\n </box>\n );\n}\n\n/** Container for static sidebar sections */\nexport function Section(props: { title: string; children: JSXElement }) {\n const { theme } = useTheme();\n\n return (\n <box\n flexDirection=\"column\"\n backgroundColor={theme.backgroundPanel}\n flexShrink={0}\n >\n <SectionTitle title={props.title} />\n {props.children}\n </box>\n );\n}\n",
|
|
28
|
+
"import { For, Show, createEffect } from \"solid-js\";\nimport type { Accessor } from \"solid-js\";\nimport type { ScrollBoxRenderable } from \"@opentui/core\";\nimport { useTheme } from \"../../context/theme\";\nimport { useReview } from \"../../context/review\";\nimport { Title } from \"./Section\";\nimport type { CommentWithNote } from \"../../context/review\";\nimport type { Patch } from \"../../store\";\n\nexport interface CommentListProps {\n comments: Accessor<CommentWithNote[]>;\n loading: Accessor<boolean>;\n selectedIndex: Accessor<number>;\n focused: Accessor<boolean>;\n}\n\nconst SCROLL_BUFFER = 2;\n\nfunction getShortFile(file: string): string {\n const segments = file.split(\"/\");\n return segments[segments.length - 1] || file;\n}\n\nfunction getPatchDisplay(\n patchId: number | null,\n patches: Patch.Info[],\n workingTreePatchId: number | null,\n): string {\n if (patchId === null) return \"?\";\n if (workingTreePatchId !== null && patchId === workingTreePatchId)\n return \"WT\";\n const patch = patches.find((p) => p.id === patchId);\n if (!patch) return \"?\";\n return `P${patch.seq}`;\n}\n\nexport function CommentList(props: CommentListProps) {\n const { theme } = useTheme();\n const review = useReview();\n let scrollbox: ScrollBoxRenderable | null = null;\n\n // Scroll to keep selection visible\n createEffect(() => {\n const idx = props.selectedIndex();\n if (idx < 0 || !scrollbox) return;\n\n const viewportHeight = scrollbox.viewport.height;\n const scrollTop = scrollbox.scrollTop;\n\n if (idx < scrollTop + SCROLL_BUFFER) {\n scrollbox.scrollTo(Math.max(0, idx - SCROLL_BUFFER));\n } else if (idx + 1 > scrollTop + viewportHeight - SCROLL_BUFFER) {\n scrollbox.scrollTo(idx - viewportHeight + SCROLL_BUFFER + 1);\n }\n });\n\n const commentCount = () => props.comments().length;\n\n return (\n <box flexDirection=\"column\">\n <Title section=\"comments\" />\n\n <Show when={!props.loading() && commentCount() === 0}>\n <box>\n <text fg={theme.textMuted}>No comments</text>\n </box>\n </Show>\n\n <Show when={!props.loading() && commentCount() > 0}>\n <scrollbox ref={(r) => (scrollbox = r)} flexGrow={1}>\n <For each={props.comments()}>\n {(comment, index) => {\n const isSelected = () => index() === props.selectedIndex();\n const textColor = () =>\n isSelected() && props.focused() ? theme.primary : undefined;\n const bgColor = () =>\n isSelected() && props.focused()\n ? theme.backgroundElement\n : theme.backgroundPanel;\n\n return (\n <box\n flexDirection=\"row\"\n justifyContent=\"space-between\"\n backgroundColor={bgColor()}\n >\n <box flexDirection=\"row\" gap={1}>\n <text fg={textColor()}>{getShortFile(comment.file)}</text>\n <text fg={theme.textMuted}>\n {`${comment.startRow}:${comment.endRow}`}\n </text>\n </box>\n <text fg={theme.textMuted}>\n {getPatchDisplay(\n comment.patchId,\n review.patches(),\n review.workingTreePatchId(),\n )}\n </text>\n </box>\n );\n }}\n </For>\n </scrollbox>\n </Show>\n </box>\n );\n}\n",
|
|
29
|
+
"import {\n For,\n Show,\n createEffect,\n createSignal,\n onCleanup,\n onMount,\n} from \"solid-js\";\nimport type { Accessor } from \"solid-js\";\nimport type { ScrollBoxRenderable } from \"@opentui/core\";\nimport type { Patch } from \"../../store\";\nimport { useTheme } from \"../../context/theme\";\nimport { Title } from \"./Section\";\nimport type { Git } from \"../../lib/git\";\n\nexport interface PatchListProps {\n patches: Accessor<Patch.Info[]>;\n activePatchId: Accessor<number | null>;\n workingTreePatchId: Accessor<number | null>;\n workspaceEntries: Accessor<Git.Entry[]>;\n loading: Accessor<boolean>;\n selectedIndex: Accessor<number>;\n focused: Accessor<boolean>;\n}\n\n/** Number of items to keep visible below the cursor */\nconst SCROLL_BUFFER = 2;\n\n// Format timestamp to readable time\nfunction formatTime(timestamp: number): string {\n const date = new Date(timestamp);\n return date.toLocaleTimeString([], { hour: \"numeric\", minute: \"2-digit\" });\n}\n\nfunction diffStats(content: string): { added: number; removed: number } {\n let added = 0;\n let removed = 0;\n\n for (const line of content.split(\"\\n\")) {\n if (line.startsWith(\"+++\") || line.startsWith(\"---\")) continue;\n if (line.startsWith(\"+\")) added++;\n else if (line.startsWith(\"-\")) removed++;\n }\n\n return { added, removed };\n}\n\nfunction sumEntryStats(entries: Git.Entry[]): {\n added: number;\n removed: number;\n} {\n let added = 0;\n let removed = 0;\n for (const e of entries) {\n const s = diffStats(e.content);\n added += s.added;\n removed += s.removed;\n }\n return { added, removed };\n}\n\nexport function PatchList(props: PatchListProps) {\n const { theme } = useTheme();\n let scrollbox: ScrollBoxRenderable | null = null;\n\n const [now, setNow] = createSignal(Date.now());\n\n onMount(() => {\n let interval: ReturnType<typeof setInterval> | null = null;\n const start = () => {\n // Align to minute boundary so the display flips on :00.\n const ms = Date.now();\n const nextMinute = Math.ceil(ms / 60000) * 60000;\n const delay = Math.max(0, nextMinute - ms);\n const timeout = setTimeout(() => {\n setNow(Date.now());\n interval = setInterval(() => setNow(Date.now()), 60000);\n }, delay);\n onCleanup(() => clearTimeout(timeout));\n };\n start();\n onCleanup(() => {\n if (interval) clearInterval(interval);\n });\n });\n\n // Scroll to keep selection visible\n createEffect(() => {\n const idx = props.selectedIndex();\n if (idx < 0 || !scrollbox) return;\n\n const viewportHeight = scrollbox.viewport.height;\n const scrollTop = scrollbox.scrollTop;\n\n if (idx < scrollTop + SCROLL_BUFFER) {\n scrollbox.scrollTo(Math.max(0, idx - SCROLL_BUFFER));\n } else if (idx + 1 > scrollTop + viewportHeight - SCROLL_BUFFER) {\n scrollbox.scrollTo(idx - viewportHeight + SCROLL_BUFFER + 1);\n }\n });\n\n // Include workspace as item 0, then patches\n const items = () => {\n const patchList = props.patches();\n const wt = props.workingTreePatchId();\n // Workspace entry at index 0, then patches sorted by seq descending (newest first)\n // Use current time for workspace timestamp\n return [\n { type: \"workspace\" as const, id: wt, seq: -1, createdAt: now() },\n ...patchList\n .slice()\n .filter((p) => (wt === null ? true : p.id !== wt))\n .sort((a, b) => b.seq - a.seq)\n .map((p) => ({ type: \"patch\" as const, ...p })),\n ];\n };\n\n const patchCount = () => {\n const wt = props.workingTreePatchId();\n const list = props.patches();\n return wt === null ? list.length : list.filter((p) => p.id !== wt).length;\n };\n\n return (\n <box flexDirection=\"column\">\n <Title section=\"patches\" />\n <Show when={props.loading()}>\n <box>\n <text fg={theme.textMuted}>Loading...</text>\n </box>\n </Show>\n\n <Show when={!props.loading() && patchCount() === 0}>\n <box>\n <box flexDirection=\"row\" justifyContent=\"space-between\">\n <box flexDirection=\"row\" gap={1}>\n <Show\n when={\n props.workingTreePatchId() !== null &&\n props.activePatchId() === props.workingTreePatchId()\n }\n >\n <text fg={theme.primary}>▸</text>\n </Show>\n <Show\n when={\n props.workingTreePatchId() === null ||\n props.activePatchId() !== props.workingTreePatchId()\n }\n >\n <text fg={theme.textMuted}> </text>\n </Show>\n <text fg={props.focused() ? theme.primary : undefined}>\n Working tree\n </text>\n\n {(() => {\n const s = sumEntryStats(props.workspaceEntries());\n if (s.added === 0 && s.removed === 0) return null;\n return (\n <>\n <text fg={theme.diffSignAdded}>+</text>\n <text fg={theme.textMuted}>{s.added}</text>\n <text fg={theme.diffSignRemoved}>-</text>\n <text fg={theme.textMuted}>{s.removed}</text>\n </>\n );\n })()}\n </box>\n <text fg={theme.textMuted}>{formatTime(now())}</text>\n </box>\n </box>\n </Show>\n\n <Show when={!props.loading() && patchCount() > 0}>\n <scrollbox ref={(r) => (scrollbox = r)} flexGrow={1}>\n <For each={items()}>\n {(item, index) => {\n const isSelected = () => index() === props.selectedIndex();\n const isActive = () => {\n if (item.type === \"workspace\")\n return item.id !== null && props.activePatchId() === item.id;\n return props.activePatchId() === item.id;\n };\n const textColor = () => (isActive() ? theme.primary : undefined);\n const bgColor = () =>\n isSelected() && props.focused()\n ? theme.backgroundElement\n : theme.backgroundPanel;\n\n const label = () =>\n item.type === \"workspace\" ? \"Working tree\" : `P${item.seq}`;\n\n const delta = () =>\n item.type === \"workspace\"\n ? sumEntryStats(props.workspaceEntries())\n : diffStats(item.content);\n\n return (\n <box\n flexDirection=\"row\"\n justifyContent=\"space-between\"\n backgroundColor={bgColor()}\n >\n <box flexDirection=\"row\" gap={1}>\n <text fg={textColor()}>{label()}</text>\n <Show\n when={\n delta() && (delta().added > 0 || delta().removed > 0)\n }\n >\n <text fg={theme.diffSignAdded}>+{delta().added}</text>\n <text fg={theme.diffSignRemoved}>-{delta().removed}</text>\n </Show>\n </box>\n\n <text fg={theme.textMuted}>{formatTime(item.createdAt)}</text>\n </box>\n );\n }}\n </For>\n </scrollbox>\n </Show>\n </box>\n );\n}\n",
|
|
30
|
+
"import { useTheme } from \"../../context/theme\";\nimport { useServer } from \"../../context/server\";\nimport { Section } from \"./Section\";\n\nexport function ServerStatus() {\n const { theme } = useTheme();\n const server = useServer();\n\n return (\n <Section title=\"Server\">\n <box\n flexDirection=\"row\"\n gap={1}\n backgroundColor={theme.backgroundPanel}\n height={1}\n >\n <text fg={server.connected() ? theme.connected : theme.disconnected}>\n •\n </text>\n <text fg={server.connected() ? theme.text : theme.textMuted}>\n {server.url() ?? \"disconnected\"}\n </text>\n </box>\n </Section>\n );\n}\n",
|
|
31
|
+
"import type { Accessor } from \"solid-js\";\nimport { Show } from \"solid-js\";\nimport { useTheme } from \"../../context/theme\";\nimport { Section } from \"./Section\";\nimport { basename, dirname } from \"path\";\n\nexport interface ProjectStatusProps {\n repoRoot: Accessor<string | null>;\n commentCount: Accessor<number>;\n}\n\nexport function ProjectStatus(props: ProjectStatusProps) {\n const { theme } = useTheme();\n\n const displayName = () => {\n const root = props.repoRoot();\n return root ? basename(root) : null;\n };\n\n return (\n <Section title=\"Review\">\n <Show when={displayName()}>\n <box flexDirection=\"row\" flexShrink={0}>\n <text fg={theme.text}>{displayName()}</text>\n <text fg={theme.textMuted}> ({props.commentCount()} comments)</text>\n </box>\n </Show>\n <Show when={props.repoRoot()}>\n <box flexDirection=\"row\" flexShrink={0}>\n <text fg={theme.textMuted}>{dirname(props.repoRoot()!)}/</text>\n <text fg={theme.text}>{basename(props.repoRoot()!)}</text>\n </box>\n </Show>\n </Section>\n );\n}\n",
|
|
32
|
+
"import type { Git } from \"../lib/git\";\n\n/**\n * A node in the file tree - either a directory or a file\n */\nexport interface FileTreeNode {\n name: string; // Just the segment name (\"cli\", \"index.ts\")\n path: string; // Full path (\"packages/cli/src/index.ts\")\n type: \"file\" | \"dir\";\n status?: \"M\" | \"A\" | \"D\"; // Only for files\n children: FileTreeNode[]; // Empty for files\n entryIndex?: number; // Only for files - index into original Git.Entry[] array\n}\n\n/**\n * A flattened item for display/rendering\n */\nexport interface DisplayItem {\n node: FileTreeNode;\n depth: number; // Indentation level\n}\n\n/**\n * Build a file tree from a list of diff entries.\n * Directories are sorted before files, then alphabetically within each group.\n */\nexport function buildFileTree(entries: Git.Entry[]): FileTreeNode[] {\n const root: FileTreeNode[] = [];\n\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i]!;\n const parts = entry.file.split(\"/\");\n insertPath(root, parts, 0, entry, i);\n }\n\n // Sort the tree recursively\n sortTree(root);\n\n return root;\n}\n\n/**\n * Insert a file path into the tree, creating directory nodes as needed\n */\nfunction insertPath(\n nodes: FileTreeNode[],\n parts: string[],\n partIndex: number,\n entry: Git.Entry,\n entryIndex: number,\n): void {\n if (partIndex >= parts.length) return;\n\n const name = parts[partIndex]!;\n const isLastPart = partIndex === parts.length - 1;\n const fullPath = parts.slice(0, partIndex + 1).join(\"/\");\n\n // Find existing node with this name\n let node = nodes.find((n) => n.name === name);\n\n if (!node) {\n // Create new node\n node = {\n name,\n path: fullPath,\n type: isLastPart ? \"file\" : \"dir\",\n children: [],\n };\n\n if (isLastPart) {\n // It's a file\n node.status = entry.isDeleted ? \"D\" : entry.isNew ? \"A\" : \"M\";\n node.entryIndex = entryIndex;\n }\n\n nodes.push(node);\n }\n\n // If not the last part, recurse into children\n if (!isLastPart && node) {\n insertPath(node.children, parts, partIndex + 1, entry, entryIndex);\n }\n}\n\n/**\n * Sort tree: directories first, then files, alphabetically within each group\n */\nfunction sortTree(nodes: FileTreeNode[]): void {\n nodes.sort((a, b) => {\n // Directories before files\n if (a.type !== b.type) {\n return a.type === \"dir\" ? -1 : 1;\n }\n // Alphabetical within same type\n return a.name.localeCompare(b.name);\n });\n\n // Recursively sort children\n for (const node of nodes) {\n if (node.children.length > 0) {\n sortTree(node.children);\n }\n }\n}\n\n/**\n * Flatten the tree into a display list with depth information.\n * Collapses single-child directory chains (e.g., \"packages/cli/src\" instead of nested).\n */\nexport function flattenTree(nodes: FileTreeNode[]): DisplayItem[] {\n const items: DisplayItem[] = [];\n flattenNodes(nodes, 0, items);\n return items;\n}\n\nfunction flattenNodes(\n nodes: FileTreeNode[],\n depth: number,\n items: DisplayItem[],\n): void {\n for (const node of nodes) {\n if (node.type === \"dir\") {\n // Collapse single-child directory chains\n const collapsed = collapseDir(node);\n items.push({ node: collapsed, depth });\n flattenNodes(collapsed.children, depth + 1, items);\n } else {\n items.push({ node, depth });\n }\n }\n}\n\n/**\n * Collapse a chain of single-child directories into one node.\n * e.g., packages -> cli -> src with one file becomes \"packages/cli/src\"\n */\nfunction collapseDir(node: FileTreeNode): FileTreeNode {\n let current = node;\n const nameParts = [current.name];\n\n // Keep collapsing while we have exactly one child that is a directory\n while (current.children.length === 1 && current.children[0]!.type === \"dir\") {\n current = current.children[0]!;\n nameParts.push(current.name);\n }\n\n if (nameParts.length === 1) {\n // No collapsing needed\n return node;\n }\n\n // Return a new node with the collapsed name\n return {\n name: nameParts.join(\"/\"),\n path: current.path,\n type: \"dir\",\n children: current.children,\n };\n}\n\n/**\n * Get the list of file entry indices from display items (for navigation).\n * Returns indices in display order.\n */\nexport function getFileIndices(items: DisplayItem[]): number[] {\n const indices: number[] = [];\n for (const item of items) {\n if (item.node.type === \"file\" && item.node.entryIndex !== undefined) {\n indices.push(item.node.entryIndex);\n }\n }\n return indices;\n}\n\n/**\n * Find the display index for a given file entry index\n */\nexport function findDisplayIndex(\n items: DisplayItem[],\n entryIndex: number,\n): number {\n return items.findIndex(\n (item) => item.node.type === \"file\" && item.node.entryIndex === entryIndex,\n );\n}\n",
|
|
33
|
+
"import { createContext, useContext, type ParentProps } from \"solid-js\";\nimport { useRenderer } from \"@opentui/solid\";\n\ntype CleanupFn = () => void | Promise<void>;\n\ninterface ExitContextValue {\n exit: (reason?: unknown) => Promise<void>;\n registerCleanup: (fn: CleanupFn) => void;\n}\n\nconst ExitContext = createContext<ExitContextValue>();\n\nexport function ExitProvider(props: ParentProps) {\n const renderer = useRenderer();\n const cleanupFns: CleanupFn[] = [];\n\n const registerCleanup = (fn: CleanupFn) => {\n cleanupFns.push(fn);\n };\n\n const exit = async (reason?: unknown) => {\n // Run all cleanup functions\n for (const fn of cleanupFns) {\n try {\n await fn();\n } catch {\n // Ignore cleanup errors\n }\n }\n\n renderer.destroy();\n\n if (reason) {\n const message = reason instanceof Error ? reason.message : String(reason);\n process.stderr.write(message + \"\\n\");\n }\n process.exit(0);\n };\n\n return (\n <ExitContext.Provider value={{ exit, registerCleanup }}>\n {props.children}\n </ExitContext.Provider>\n );\n}\n\nexport function useExit(): ExitContextValue {\n const ctx = useContext(ExitContext);\n if (!ctx) throw new Error(\"useExit must be used within ExitProvider\");\n return ctx;\n}\n",
|
|
34
|
+
"// Tree-sitter parser configuration\n// WASM binaries from tree-sitter-wasms package\n// Highlight queries bundled locally\n\n// WASM imports\nimport bash_wasm from \"tree-sitter-wasms/out/tree-sitter-bash.wasm\" with { type: \"file\" };\nimport c_wasm from \"tree-sitter-wasms/out/tree-sitter-c.wasm\" with { type: \"file\" };\nimport cpp_wasm from \"tree-sitter-wasms/out/tree-sitter-cpp.wasm\" with { type: \"file\" };\nimport c_sharp_wasm from \"tree-sitter-wasms/out/tree-sitter-c_sharp.wasm\" with { type: \"file\" };\nimport css_wasm from \"tree-sitter-wasms/out/tree-sitter-css.wasm\" with { type: \"file\" };\nimport dart_wasm from \"tree-sitter-wasms/out/tree-sitter-dart.wasm\" with { type: \"file\" };\nimport elisp_wasm from \"tree-sitter-wasms/out/tree-sitter-elisp.wasm\" with { type: \"file\" };\nimport elixir_wasm from \"tree-sitter-wasms/out/tree-sitter-elixir.wasm\" with { type: \"file\" };\nimport elm_wasm from \"tree-sitter-wasms/out/tree-sitter-elm.wasm\" with { type: \"file\" };\nimport embedded_template_wasm from \"tree-sitter-wasms/out/tree-sitter-embedded_template.wasm\" with { type: \"file\" };\nimport go_wasm from \"tree-sitter-wasms/out/tree-sitter-go.wasm\" with { type: \"file\" };\nimport html_wasm from \"tree-sitter-wasms/out/tree-sitter-html.wasm\" with { type: \"file\" };\nimport java_wasm from \"tree-sitter-wasms/out/tree-sitter-java.wasm\" with { type: \"file\" };\nimport javascript_wasm from \"tree-sitter-wasms/out/tree-sitter-javascript.wasm\" with { type: \"file\" };\nimport json_wasm from \"tree-sitter-wasms/out/tree-sitter-json.wasm\" with { type: \"file\" };\nimport kotlin_wasm from \"tree-sitter-wasms/out/tree-sitter-kotlin.wasm\" with { type: \"file\" };\nimport lua_wasm from \"tree-sitter-wasms/out/tree-sitter-lua.wasm\" with { type: \"file\" };\nimport objc_wasm from \"tree-sitter-wasms/out/tree-sitter-objc.wasm\" with { type: \"file\" };\nimport ocaml_wasm from \"tree-sitter-wasms/out/tree-sitter-ocaml.wasm\" with { type: \"file\" };\nimport php_wasm from \"tree-sitter-wasms/out/tree-sitter-php.wasm\" with { type: \"file\" };\nimport python_wasm from \"tree-sitter-wasms/out/tree-sitter-python.wasm\" with { type: \"file\" };\nimport ql_wasm from \"tree-sitter-wasms/out/tree-sitter-ql.wasm\" with { type: \"file\" };\nimport ruby_wasm from \"tree-sitter-wasms/out/tree-sitter-ruby.wasm\" with { type: \"file\" };\nimport rust_wasm from \"tree-sitter-wasms/out/tree-sitter-rust.wasm\" with { type: \"file\" };\nimport scala_wasm from \"tree-sitter-wasms/out/tree-sitter-scala.wasm\" with { type: \"file\" };\nimport swift_wasm from \"tree-sitter-wasms/out/tree-sitter-swift.wasm\" with { type: \"file\" };\nimport toml_wasm from \"tree-sitter-wasms/out/tree-sitter-toml.wasm\" with { type: \"file\" };\nimport tsx_wasm from \"tree-sitter-wasms/out/tree-sitter-tsx.wasm\" with { type: \"file\" };\nimport typescript_wasm from \"tree-sitter-wasms/out/tree-sitter-typescript.wasm\" with { type: \"file\" };\nimport vue_wasm from \"tree-sitter-wasms/out/tree-sitter-vue.wasm\" with { type: \"file\" };\nimport yaml_wasm from \"tree-sitter-wasms/out/tree-sitter-yaml.wasm\" with { type: \"file\" };\nimport zig_wasm from \"tree-sitter-wasms/out/tree-sitter-zig.wasm\" with { type: \"file\" };\n\n// Query imports\nimport bash_highlights from \"./queries/bash.scm\" with { type: \"file\" };\nimport c_highlights from \"./queries/c.scm\" with { type: \"file\" };\nimport cpp_highlights from \"./queries/cpp.scm\" with { type: \"file\" };\nimport c_sharp_highlights from \"./queries/c_sharp.scm\" with { type: \"file\" };\nimport css_highlights from \"./queries/css.scm\" with { type: \"file\" };\nimport dart_highlights from \"./queries/dart.scm\" with { type: \"file\" };\nimport elisp_highlights from \"./queries/elisp.scm\" with { type: \"file\" };\nimport elixir_highlights from \"./queries/elixir.scm\" with { type: \"file\" };\nimport elm_highlights from \"./queries/elm.scm\" with { type: \"file\" };\nimport embedded_template_highlights from \"./queries/embedded_template.scm\" with { type: \"file\" };\nimport go_highlights from \"./queries/go.scm\" with { type: \"file\" };\nimport html_highlights from \"./queries/html.scm\" with { type: \"file\" };\nimport java_highlights from \"./queries/java.scm\" with { type: \"file\" };\nimport javascript_highlights from \"./queries/javascript.scm\" with { type: \"file\" };\nimport json_highlights from \"./queries/json.scm\" with { type: \"file\" };\nimport kotlin_highlights from \"./queries/kotlin.scm\" with { type: \"file\" };\nimport lua_highlights from \"./queries/lua.scm\" with { type: \"file\" };\nimport objc_highlights from \"./queries/objc.scm\" with { type: \"file\" };\nimport ocaml_highlights from \"./queries/ocaml.scm\" with { type: \"file\" };\nimport php_highlights from \"./queries/php.scm\" with { type: \"file\" };\nimport python_highlights from \"./queries/python.scm\" with { type: \"file\" };\nimport ql_highlights from \"./queries/ql.scm\" with { type: \"file\" };\nimport ruby_highlights from \"./queries/ruby.scm\" with { type: \"file\" };\nimport rust_highlights from \"./queries/rust.scm\" with { type: \"file\" };\nimport scala_highlights from \"./queries/scala.scm\" with { type: \"file\" };\nimport swift_highlights from \"./queries/swift.scm\" with { type: \"file\" };\nimport toml_highlights from \"./queries/toml.scm\" with { type: \"file\" };\nimport tsx_highlights from \"./queries/tsx.scm\" with { type: \"file\" };\nimport typescript_highlights from \"./queries/typescript.scm\" with { type: \"file\" };\nimport vue_highlights from \"./queries/vue.scm\" with { type: \"file\" };\nimport yaml_highlights from \"./queries/yaml.scm\" with { type: \"file\" };\nimport zig_highlights from \"./queries/zig.scm\" with { type: \"file\" };\n\nexport const parsers = [\n {\n filetype: \"bash\",\n wasm: bash_wasm,\n queries: { highlights: [bash_highlights] },\n },\n { filetype: \"c\", wasm: c_wasm, queries: { highlights: [c_highlights] } },\n {\n filetype: \"cpp\",\n wasm: cpp_wasm,\n queries: { highlights: [cpp_highlights] },\n },\n {\n filetype: \"c_sharp\",\n wasm: c_sharp_wasm,\n queries: { highlights: [c_sharp_highlights] },\n },\n {\n filetype: \"css\",\n wasm: css_wasm,\n queries: { highlights: [css_highlights] },\n },\n {\n filetype: \"dart\",\n wasm: dart_wasm,\n queries: { highlights: [dart_highlights] },\n },\n {\n filetype: \"elisp\",\n wasm: elisp_wasm,\n queries: { highlights: [elisp_highlights] },\n },\n {\n filetype: \"elixir\",\n wasm: elixir_wasm,\n queries: { highlights: [elixir_highlights] },\n },\n {\n filetype: \"elm\",\n wasm: elm_wasm,\n queries: { highlights: [elm_highlights] },\n },\n {\n filetype: \"embedded_template\",\n wasm: embedded_template_wasm,\n queries: { highlights: [embedded_template_highlights] },\n },\n { filetype: \"go\", wasm: go_wasm, queries: { highlights: [go_highlights] } },\n {\n filetype: \"html\",\n wasm: html_wasm,\n queries: { highlights: [html_highlights] },\n },\n {\n filetype: \"java\",\n wasm: java_wasm,\n queries: { highlights: [java_highlights] },\n },\n {\n filetype: \"javascript\",\n wasm: javascript_wasm,\n queries: { highlights: [javascript_highlights] },\n },\n {\n filetype: \"json\",\n wasm: json_wasm,\n queries: { highlights: [json_highlights] },\n },\n {\n filetype: \"kotlin\",\n wasm: kotlin_wasm,\n queries: { highlights: [kotlin_highlights] },\n },\n {\n filetype: \"lua\",\n wasm: lua_wasm,\n queries: { highlights: [lua_highlights] },\n },\n {\n filetype: \"objc\",\n wasm: objc_wasm,\n queries: { highlights: [objc_highlights] },\n },\n {\n filetype: \"ocaml\",\n wasm: ocaml_wasm,\n queries: { highlights: [ocaml_highlights] },\n },\n {\n filetype: \"php\",\n wasm: php_wasm,\n queries: { highlights: [php_highlights] },\n },\n {\n filetype: \"python\",\n wasm: python_wasm,\n queries: { highlights: [python_highlights] },\n },\n { filetype: \"ql\", wasm: ql_wasm, queries: { highlights: [ql_highlights] } },\n {\n filetype: \"ruby\",\n wasm: ruby_wasm,\n queries: { highlights: [ruby_highlights] },\n },\n {\n filetype: \"rust\",\n wasm: rust_wasm,\n queries: { highlights: [rust_highlights] },\n },\n {\n filetype: \"scala\",\n wasm: scala_wasm,\n queries: { highlights: [scala_highlights] },\n },\n {\n filetype: \"swift\",\n wasm: swift_wasm,\n queries: { highlights: [swift_highlights] },\n },\n {\n filetype: \"toml\",\n wasm: toml_wasm,\n queries: { highlights: [toml_highlights] },\n },\n {\n filetype: \"tsx\",\n wasm: tsx_wasm,\n queries: { highlights: [tsx_highlights] },\n },\n {\n filetype: \"typescript\",\n wasm: typescript_wasm,\n queries: { highlights: [typescript_highlights] },\n },\n {\n filetype: \"vue\",\n wasm: vue_wasm,\n queries: { highlights: [vue_highlights] },\n },\n {\n filetype: \"yaml\",\n wasm: yaml_wasm,\n queries: { highlights: [yaml_highlights] },\n },\n {\n filetype: \"zig\",\n wasm: zig_wasm,\n queries: { highlights: [zig_highlights] },\n },\n];\n"
|
|
35
|
+
],
|
|
36
|
+
"mappings": "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",
|
|
37
|
+
"debugId": "D41DC668FD4D6FC664756E2164756E21",
|
|
38
|
+
"names": []
|
|
39
|
+
}
|