critique 0.1.103 → 0.1.104
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/AGENTS.md +3 -6
- package/CHANGELOG.md +9 -0
- package/package.json +4 -4
- package/scripts/preview-review.tsx +2 -2
- package/src/ansi-html.ts +2 -2
- package/src/ansi-output.test.ts +2 -2
- package/src/ansi-output.ts +2 -2
- package/src/cli-scroll.test.tsx +1 -1
- package/src/cli.tsx +7 -3
- package/src/components/diff-view.test.tsx +1 -1
- package/src/components/diff-view.tsx +1 -1
- package/src/diff-utils.ts +1 -1
- package/src/directory-tree.test.tsx +1 -1
- package/src/dropdown.test.tsx +1 -1
- package/src/dropdown.tsx +2 -2
- package/src/hooks/use-copy-selection.ts +1 -1
- package/src/image.ts +1 -1
- package/src/opentui-image.ts +2 -2
- package/src/patch-terminal-dimensions.ts +51 -0
- package/src/review/review-app.test.tsx +1 -1
- package/src/review/review-app.tsx +2 -2
- package/src/review/stream-display.test.tsx +1 -1
- package/src/review/stream-display.tsx +1 -1
- package/src/stdin-pager.test.ts +86 -0
- package/src/themes.ts +1 -1
- package/src/web-utils.test.ts +3 -3
- package/src/web-utils.tsx +7 -7
- package/tsconfig.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -17,8 +17,8 @@ gh pr view 536 -R anomalyco/opentui --json commits --jq '.commits[-1].oid[:40]'
|
|
|
17
17
|
then use it in package.json:
|
|
18
18
|
|
|
19
19
|
```
|
|
20
|
-
https://pkg.pr.new/anomalyco/opentui/@
|
|
21
|
-
https://pkg.pr.new/anomalyco/opentui/@
|
|
20
|
+
https://pkg.pr.new/anomalyco/opentui/@opentuah/core@<hash>
|
|
21
|
+
https://pkg.pr.new/anomalyco/opentui/@opentuah/react@<hash>
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
YOU MUST ALWAYS use the commit hash 40 characters long when changing the pkg.pr.new url! not the pr number!
|
|
@@ -134,10 +134,7 @@ npx opensrc <owner>/<repo> # GitHub repo (e.g., npx opensrc vercel/ai)
|
|
|
134
134
|
|
|
135
135
|
## opentui fork
|
|
136
136
|
|
|
137
|
-
we are using an opentui fork
|
|
138
|
-
|
|
139
|
-
"@opentui/core": "npm:@opentuah/core@^0.1.80",
|
|
140
|
-
"@opentui/react": "npm:@opentuah/react@^0.1.80",
|
|
137
|
+
we are using an opentui fork published as `@opentuah`. imports use `@opentuah/core` and `@opentuah/react` directly (no npm alias remapping).
|
|
141
138
|
|
|
142
139
|
To find my opentui folder with that fork see kimaki projects via kimaki cli, the one named opentui.
|
|
143
140
|
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
# 0.1.104
|
|
2
|
+
|
|
3
|
+
- `critique --stdin` (pager mode):
|
|
4
|
+
- Force scrollback mode for `--stdin` pager usage to fix lazygit integration (#25)
|
|
5
|
+
- When used as a pager (e.g. `critique --stdin` in lazygit), critique now correctly outputs static colored text instead of interactive TUI escape sequences
|
|
6
|
+
- `critique`:
|
|
7
|
+
- Fix crash in Bun compiled binaries where terminal TTY `columns`/`rows` report as 0, causing NaN framebuffer dimensions
|
|
8
|
+
- Replace `@opentui/*` npm alias remapping with direct `@opentuah/*` imports
|
|
9
|
+
|
|
1
10
|
# 0.1.103
|
|
2
11
|
|
|
3
12
|
- Syntax highlighting:
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "critique",
|
|
3
3
|
"module": "src/diff.tsx",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.104",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"private": false,
|
|
8
8
|
"bin": "./src/cli.tsx",
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@agentclientprotocol/sdk": "^0.13.1",
|
|
30
30
|
"@clack/prompts": "1.0.0-alpha.9",
|
|
31
|
-
"@
|
|
32
|
-
"@
|
|
31
|
+
"@opentuah/core": "0.1.95",
|
|
32
|
+
"@opentuah/react": "0.1.95",
|
|
33
33
|
"@parcel/watcher": "^2.5.6",
|
|
34
|
-
"goke": "^6.1.3",
|
|
35
34
|
"diff": "^8.0.2",
|
|
35
|
+
"goke": "^6.1.3",
|
|
36
36
|
"js-yaml": "^4.1.1",
|
|
37
37
|
"marked": "^17.0.1",
|
|
38
38
|
"picocolors": "^1.1.1",
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
// Renders example hunks and review data to preview TUI appearance.
|
|
4
4
|
// Run with: bun run scripts/preview-review.tsx (TUI) or --web (HTML upload).
|
|
5
5
|
|
|
6
|
-
import { createCliRenderer, addDefaultParsers } from "@
|
|
6
|
+
import { createCliRenderer, addDefaultParsers } from "@opentuah/core"
|
|
7
7
|
import parsersConfig from "../parsers-config.ts"
|
|
8
8
|
|
|
9
9
|
// Register custom syntax highlighting parsers
|
|
10
10
|
addDefaultParsers(parsersConfig.parsers)
|
|
11
|
-
import { createRoot } from "@
|
|
11
|
+
import { createRoot } from "@opentuah/react"
|
|
12
12
|
import * as React from "react"
|
|
13
13
|
import { ReviewApp, ReviewAppView } from "../src/review/review-app.tsx"
|
|
14
14
|
import { createHunk } from "../src/review/hunk-parser.ts"
|
package/src/ansi-html.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// Uses opentui's test renderer to capture structured span data and generates responsive HTML documents
|
|
3
3
|
// with proper font scaling to fit terminal content within viewport width.
|
|
4
4
|
|
|
5
|
-
import { TextAttributes, rgbToHex, type RGBA } from "@
|
|
6
|
-
import type { CapturedFrame, CapturedLine, CapturedSpan } from "@
|
|
5
|
+
import { TextAttributes, rgbToHex, type RGBA } from "@opentuah/core"
|
|
6
|
+
import type { CapturedFrame, CapturedLine, CapturedSpan } from "@opentuah/core"
|
|
7
7
|
|
|
8
8
|
export interface ToHtmlOptions {
|
|
9
9
|
/** Background color for the container */
|
package/src/ansi-output.test.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, test, expect } from "bun:test"
|
|
2
2
|
import { spanToAnsi, frameToAnsi } from "./ansi-output.ts"
|
|
3
|
-
import { RGBA } from "@
|
|
4
|
-
import type { CapturedFrame, CapturedSpan, CapturedLine } from "@
|
|
3
|
+
import { RGBA } from "@opentuah/core"
|
|
4
|
+
import type { CapturedFrame, CapturedSpan, CapturedLine } from "@opentuah/core"
|
|
5
5
|
|
|
6
6
|
const themeBg = RGBA.fromValues(0, 0, 0, 1) // Black background
|
|
7
7
|
|
package/src/ansi-output.ts
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
// Falls back gracefully: truecolor → 256 → 16 → plain text.
|
|
4
4
|
|
|
5
5
|
import supportsColor from "supports-color"
|
|
6
|
-
import { TextAttributes, type RGBA } from "@
|
|
7
|
-
import type { CapturedFrame, CapturedSpan, CapturedLine } from "@
|
|
6
|
+
import { TextAttributes, type RGBA } from "@opentuah/core"
|
|
7
|
+
import type { CapturedFrame, CapturedSpan, CapturedLine } from "@opentuah/core"
|
|
8
8
|
|
|
9
9
|
// Color support levels: 0=none, 1=16 colors, 2=256 colors, 3=truecolor
|
|
10
10
|
type ColorLevel = 0 | 1 | 2 | 3
|
package/src/cli-scroll.test.tsx
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import * as React from "react"
|
|
4
4
|
import { afterEach, describe, expect, it } from "bun:test"
|
|
5
5
|
import { act } from "react"
|
|
6
|
-
import { testRender } from "@
|
|
6
|
+
import { testRender } from "@opentuah/react/test-utils"
|
|
7
7
|
import { App } from "./cli.tsx"
|
|
8
8
|
import type { ParsedFile } from "./diff-utils.ts"
|
|
9
9
|
|
package/src/cli.tsx
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
// Provides TUI diff viewing, AI-powered review generation, and web preview upload.
|
|
4
4
|
// Commands: default (diff), review (AI analysis), web (HTML upload), pick (cherry-pick files).
|
|
5
5
|
|
|
6
|
+
// Must be first import: patches process.stdout.columns/rows for Bun compiled binaries
|
|
7
|
+
// where they incorrectly return 0 instead of actual terminal dimensions.
|
|
8
|
+
import "./patch-terminal-dimensions.ts";
|
|
9
|
+
|
|
6
10
|
import { goke, wrapJsonSchema } from "goke";
|
|
7
11
|
import {
|
|
8
12
|
createRoot,
|
|
@@ -11,7 +15,7 @@ import {
|
|
|
11
15
|
useOnResize,
|
|
12
16
|
useRenderer,
|
|
13
17
|
useTerminalDimensions,
|
|
14
|
-
} from "@
|
|
18
|
+
} from "@opentuah/react";
|
|
15
19
|
import { useCopySelection } from "./hooks/use-copy-selection.ts";
|
|
16
20
|
import * as React from "react";
|
|
17
21
|
import { exec, execSync } from "child_process";
|
|
@@ -22,7 +26,7 @@ import {
|
|
|
22
26
|
ScrollBoxRenderable,
|
|
23
27
|
BoxRenderable,
|
|
24
28
|
addDefaultParsers,
|
|
25
|
-
} from "@
|
|
29
|
+
} from "@opentuah/core";
|
|
26
30
|
import parsersConfig from "../parsers-config.ts";
|
|
27
31
|
|
|
28
32
|
// Register custom syntax highlighting parsers
|
|
@@ -1826,7 +1830,7 @@ cli
|
|
|
1826
1830
|
return;
|
|
1827
1831
|
}
|
|
1828
1832
|
|
|
1829
|
-
if (options.scrollback || !process.stdout.isTTY) {
|
|
1833
|
+
if (options.scrollback || options.stdin || !process.stdout.isTTY) {
|
|
1830
1834
|
// For scrollback, prefer terminal width over --cols default (240 is for web)
|
|
1831
1835
|
const scrollbackCols = process.stdout.columns || parseInt(options.cols) || 120;
|
|
1832
1836
|
await runScrollbackMode(cleanedDiff, {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import * as React from "react"
|
|
4
4
|
import { afterEach, describe, expect, it } from "bun:test"
|
|
5
5
|
import { act } from "react"
|
|
6
|
-
import { testRender } from "@
|
|
6
|
+
import { testRender } from "@opentuah/react/test-utils"
|
|
7
7
|
import { DiffView } from "./diff-view.tsx"
|
|
8
8
|
import { useAppStore } from "../store.ts"
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Supports split and unified view modes with line numbers.
|
|
4
4
|
|
|
5
5
|
import * as React from "react"
|
|
6
|
-
import { SyntaxStyle } from "@
|
|
6
|
+
import { SyntaxStyle } from "@opentuah/core"
|
|
7
7
|
import { getSyntaxTheme, getResolvedTheme, rgbaToHex } from "../themes.ts"
|
|
8
8
|
|
|
9
9
|
export interface DiffViewProps {
|
package/src/diff-utils.ts
CHANGED
|
@@ -459,7 +459,7 @@ export function processFiles<T extends ParsedFile>(
|
|
|
459
459
|
|
|
460
460
|
/**
|
|
461
461
|
* Detect filetype from filename for syntax highlighting
|
|
462
|
-
* Maps to tree-sitter parsers available in @
|
|
462
|
+
* Maps to tree-sitter parsers available in @opentuah/core and parsers-config.ts
|
|
463
463
|
*/
|
|
464
464
|
export function detectFiletype(filePath: string): string | undefined {
|
|
465
465
|
const ext = filePath.split(".").pop()?.toLowerCase();
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Uses opentui test renderer with captureCharFrame() for visual testing
|
|
3
3
|
|
|
4
4
|
import { afterEach, describe, expect, it } from "bun:test"
|
|
5
|
-
import { testRender } from "@
|
|
5
|
+
import { testRender } from "@opentuah/react/test-utils"
|
|
6
6
|
import { buildDirectoryTree, type TreeFileInfo, type TreeNode } from "./directory-tree.ts"
|
|
7
7
|
import { DirectoryTreeView } from "./components/directory-tree-view.tsx"
|
|
8
8
|
|
package/src/dropdown.test.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from "react"
|
|
2
2
|
import { afterEach, describe, expect, it } from "bun:test"
|
|
3
3
|
import { act } from "react"
|
|
4
|
-
import { testRender } from "@
|
|
4
|
+
import { testRender } from "@opentuah/react/test-utils"
|
|
5
5
|
import Dropdown, { filterDropdownOptions } from "./dropdown.tsx"
|
|
6
6
|
import { getResolvedTheme } from "./themes.ts"
|
|
7
7
|
|
package/src/dropdown.tsx
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
// Used by main diff view for file picker and theme picker overlays.
|
|
4
4
|
|
|
5
5
|
import React, { useCallback, useEffect, useRef, useState, type ReactNode } from "react";
|
|
6
|
-
import { useKeyboard } from "@
|
|
7
|
-
import { TextAttributes, TextareaRenderable } from "@
|
|
6
|
+
import { useKeyboard } from "@opentuah/react";
|
|
7
|
+
import { TextAttributes, TextareaRenderable } from "@opentuah/core";
|
|
8
8
|
import { type ResolvedTheme, rgbaToHex } from "./themes";
|
|
9
9
|
|
|
10
10
|
export interface DropdownOption {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Automatically copies selected text to clipboard when user releases mouse button.
|
|
3
3
|
// Uses native clipboard commands (pbcopy, xclip, etc.) with OSC52 fallback.
|
|
4
4
|
|
|
5
|
-
import { useRenderer } from "@
|
|
5
|
+
import { useRenderer } from "@opentuah/react"
|
|
6
6
|
import { spawn } from "child_process"
|
|
7
7
|
|
|
8
8
|
/**
|
package/src/image.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Uses opentui-image.ts for generic frame-to-image conversion.
|
|
3
3
|
// Adds theme resolution and diff/review-specific rendering.
|
|
4
4
|
|
|
5
|
-
import type { CapturedFrame } from "@
|
|
5
|
+
import type { CapturedFrame } from "@opentuah/core"
|
|
6
6
|
import { getResolvedTheme, rgbaToHex } from "./themes.ts"
|
|
7
7
|
import {
|
|
8
8
|
renderFrameToImage,
|
package/src/opentui-image.ts
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
import { tmpdir } from "os"
|
|
5
5
|
import { join } from "path"
|
|
6
6
|
import fs from "fs"
|
|
7
|
-
import { TextAttributes, rgbToHex, type RGBA } from "@
|
|
8
|
-
import type { CapturedFrame, CapturedLine, CapturedSpan } from "@
|
|
7
|
+
import { TextAttributes, rgbToHex, type RGBA } from "@opentuah/core"
|
|
8
|
+
import type { CapturedFrame, CapturedLine, CapturedSpan } from "@opentuah/core"
|
|
9
9
|
|
|
10
10
|
// ─────────────────────────────────────────────────────────────
|
|
11
11
|
// Types
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// Polyfill for terminal dimensions in Bun compiled binaries.
|
|
2
|
+
// Bun's `--compile` produces binaries where process.stdout.columns/rows are 0
|
|
3
|
+
// instead of the actual terminal size (even when isTTY is true).
|
|
4
|
+
// This must be imported before any opentui imports, since opentui reads
|
|
5
|
+
// stdout.columns at init time and uses `?? fallback` which doesn't catch 0.
|
|
6
|
+
|
|
7
|
+
import { execSync } from "child_process"
|
|
8
|
+
|
|
9
|
+
function getTerminalSize(): { cols: number; rows: number } | null {
|
|
10
|
+
try {
|
|
11
|
+
const cols = parseInt(
|
|
12
|
+
execSync("tput cols", {
|
|
13
|
+
encoding: "utf-8",
|
|
14
|
+
stdio: ["inherit", "pipe", "pipe"],
|
|
15
|
+
}).trim(),
|
|
16
|
+
)
|
|
17
|
+
const rows = parseInt(
|
|
18
|
+
execSync("tput lines", {
|
|
19
|
+
encoding: "utf-8",
|
|
20
|
+
stdio: ["inherit", "pipe", "pipe"],
|
|
21
|
+
}).trim(),
|
|
22
|
+
)
|
|
23
|
+
if (cols > 0 && rows > 0) return { cols, rows }
|
|
24
|
+
} catch {}
|
|
25
|
+
return null
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (process.stdout.isTTY && process.stdout.columns === 0) {
|
|
29
|
+
const size = getTerminalSize()
|
|
30
|
+
if (size) {
|
|
31
|
+
Object.defineProperty(process.stdout, "columns", {
|
|
32
|
+
value: size.cols,
|
|
33
|
+
writable: true,
|
|
34
|
+
configurable: true,
|
|
35
|
+
})
|
|
36
|
+
Object.defineProperty(process.stdout, "rows", {
|
|
37
|
+
value: size.rows,
|
|
38
|
+
writable: true,
|
|
39
|
+
configurable: true,
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
// Keep patched values updated on terminal resize
|
|
43
|
+
process.on("SIGWINCH", () => {
|
|
44
|
+
const newSize = getTerminalSize()
|
|
45
|
+
if (newSize) {
|
|
46
|
+
process.stdout.columns = newSize.cols
|
|
47
|
+
process.stdout.rows = newSize.rows
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Test for ReviewAppView rendering with example YAML data
|
|
2
2
|
|
|
3
3
|
import { afterEach, describe, expect, it } from "bun:test"
|
|
4
|
-
import { testRender } from "@
|
|
4
|
+
import { testRender } from "@opentuah/react/test-utils"
|
|
5
5
|
import { ReviewAppView } from "./review-app.tsx"
|
|
6
6
|
import { createHunk } from "./hunk-parser.ts"
|
|
7
7
|
import type { ReviewYaml } from "./types.ts"
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
// Supports live generation updates, theme switching, and resume from saved reviews.
|
|
4
4
|
|
|
5
5
|
import * as React from "react"
|
|
6
|
-
import { useKeyboard, useRenderer, useTerminalDimensions } from "@
|
|
7
|
-
import { MacOSScrollAccel, SyntaxStyle, BoxRenderable, CodeRenderable, TextRenderable, ScrollBoxRenderable } from "@
|
|
6
|
+
import { useKeyboard, useRenderer, useTerminalDimensions } from "@opentuah/react"
|
|
7
|
+
import { MacOSScrollAccel, SyntaxStyle, BoxRenderable, CodeRenderable, TextRenderable, ScrollBoxRenderable } from "@opentuah/core"
|
|
8
8
|
import { useCopySelection } from "../hooks/use-copy-selection.ts"
|
|
9
9
|
import type { Token } from "marked"
|
|
10
10
|
import { getResolvedTheme, getSyntaxTheme, defaultThemeName, themeNames, rgbaToHex } from "../themes.ts"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Tests for StreamDisplay component
|
|
2
2
|
|
|
3
3
|
import { afterEach, describe, expect, it } from "bun:test"
|
|
4
|
-
import { testRender } from "@
|
|
4
|
+
import { testRender } from "@opentuah/react/test-utils"
|
|
5
5
|
import type { SessionNotification } from "@agentclientprotocol/sdk"
|
|
6
6
|
import { StreamDisplay } from "./stream-display.tsx"
|
|
7
7
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Shows formatted tool operations with file names and edit statistics.
|
|
4
4
|
|
|
5
5
|
import * as React from "react"
|
|
6
|
-
import { SyntaxStyle } from "@
|
|
6
|
+
import { SyntaxStyle } from "@opentuah/core"
|
|
7
7
|
import type { SessionNotification } from "@agentclientprotocol/sdk"
|
|
8
8
|
import { formatNotifications, SYMBOLS, COLORS, isEditTool, type StreamLine } from "./acp-stream-display.ts"
|
|
9
9
|
import { getSyntaxTheme, getResolvedTheme, rgbaToHex } from "../themes.ts"
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// Tests for --stdin pager mode (lazygit integration).
|
|
2
|
+
// Reproduces https://github.com/remorses/critique/issues/25
|
|
3
|
+
//
|
|
4
|
+
// Problem: When critique is used as a pager in lazygit:
|
|
5
|
+
// git.paging.pager: critique --stdin
|
|
6
|
+
//
|
|
7
|
+
// Lazygit runs the pager using a PTY (github.com/creack/pty), so from critique's
|
|
8
|
+
// perspective process.stdout.isTTY is true. The current mode selection logic:
|
|
9
|
+
//
|
|
10
|
+
// if (options.scrollback || !process.stdout.isTTY) → scrollback mode
|
|
11
|
+
// else → TUI mode (interactive, cursor positioning, mouse tracking)
|
|
12
|
+
//
|
|
13
|
+
// Since stdout IS a TTY (PTY), critique enters TUI mode and outputs raw escape
|
|
14
|
+
// sequences like [?1000h (mouse tracking), [row;col;H (cursor positioning) etc.
|
|
15
|
+
// Lazygit's pager panel can't interpret these → shows garbled text.
|
|
16
|
+
//
|
|
17
|
+
// Fix: --stdin should always force scrollback mode. A pager consumer never
|
|
18
|
+
// expects interactive TUI — it expects static colored text output.
|
|
19
|
+
|
|
20
|
+
import { describe, test, expect } from "bun:test"
|
|
21
|
+
|
|
22
|
+
describe("--stdin pager mode selection (lazygit issue #25)", () => {
|
|
23
|
+
// This test validates the decision logic that determines whether to use
|
|
24
|
+
// scrollback mode or TUI mode. It tests the condition directly.
|
|
25
|
+
test("--stdin should force scrollback mode regardless of TTY status", () => {
|
|
26
|
+
// Current buggy condition (cli.tsx:1829):
|
|
27
|
+
const buggyCondition = (options: { scrollback?: boolean; stdin?: boolean }, isTTY: boolean) =>
|
|
28
|
+
options.scrollback || !isTTY
|
|
29
|
+
|
|
30
|
+
// Fixed condition:
|
|
31
|
+
const fixedCondition = (options: { scrollback?: boolean; stdin?: boolean }, isTTY: boolean) =>
|
|
32
|
+
options.scrollback || options.stdin || !isTTY
|
|
33
|
+
|
|
34
|
+
// Scenario 1: lazygit PTY - stdout IS a TTY, --stdin flag set
|
|
35
|
+
const lazygitOptions = { stdin: true }
|
|
36
|
+
|
|
37
|
+
// BUG: current logic sends lazygit to TUI mode
|
|
38
|
+
expect(buggyCondition(lazygitOptions, true)).toBe(false) // false = TUI mode (wrong!)
|
|
39
|
+
|
|
40
|
+
// FIX: stdin flag should force scrollback
|
|
41
|
+
expect(fixedCondition(lazygitOptions, true)).toBe(true) // true = scrollback mode (correct!)
|
|
42
|
+
|
|
43
|
+
// Scenario 2: piped stdout (non-TTY) - both conditions work
|
|
44
|
+
expect(buggyCondition(lazygitOptions, false)).toBe(true)
|
|
45
|
+
expect(fixedCondition(lazygitOptions, false)).toBe(true)
|
|
46
|
+
|
|
47
|
+
// Scenario 3: normal TUI usage (no --stdin, real TTY)
|
|
48
|
+
const normalOptions = {}
|
|
49
|
+
expect(buggyCondition(normalOptions, true)).toBe(false) // TUI mode
|
|
50
|
+
expect(fixedCondition(normalOptions, true)).toBe(false) // TUI mode (unchanged)
|
|
51
|
+
|
|
52
|
+
// Scenario 4: explicit --scrollback
|
|
53
|
+
const scrollbackOptions = { scrollback: true }
|
|
54
|
+
expect(buggyCondition(scrollbackOptions, true)).toBe(true)
|
|
55
|
+
expect(fixedCondition(scrollbackOptions, true)).toBe(true)
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
// Verify the exact line in cli.tsx has the bug
|
|
59
|
+
test("cli.tsx line 1829 should include options.stdin in the condition", async () => {
|
|
60
|
+
const fs = await import("fs")
|
|
61
|
+
const path = await import("path")
|
|
62
|
+
const cliSource = fs.readFileSync(path.join(import.meta.dir, "cli.tsx"), "utf-8")
|
|
63
|
+
|
|
64
|
+
// The current buggy condition
|
|
65
|
+
const hasBuggyCondition = cliSource.includes("options.scrollback || !process.stdout.isTTY")
|
|
66
|
+
|
|
67
|
+
// The fixed condition should include options.stdin
|
|
68
|
+
const hasFixedCondition = cliSource.includes("options.stdin") &&
|
|
69
|
+
/options\.scrollback\s*\|\|\s*options\.stdin\s*\|\|\s*!process\.stdout\.isTTY/.test(cliSource)
|
|
70
|
+
|
|
71
|
+
// This test will fail until the fix is applied, documenting the bug
|
|
72
|
+
if (hasBuggyCondition && !hasFixedCondition) {
|
|
73
|
+
// Bug is present — document it
|
|
74
|
+
expect(hasBuggyCondition).toBe(true)
|
|
75
|
+
// After fix, this assertion should change
|
|
76
|
+
console.log(
|
|
77
|
+
"BUG CONFIRMED: cli.tsx:1829 does not include options.stdin in scrollback condition.\n" +
|
|
78
|
+
"Fix: Change 'options.scrollback || !process.stdout.isTTY'\n" +
|
|
79
|
+
" to: 'options.scrollback || options.stdin || !process.stdout.isTTY'"
|
|
80
|
+
)
|
|
81
|
+
} else {
|
|
82
|
+
// Fix has been applied
|
|
83
|
+
expect(hasFixedCondition).toBe(true)
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
})
|
package/src/themes.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Loads JSON theme files lazily on demand, resolves color references,
|
|
3
3
|
// and provides both UI colors and Tree-sitter compatible syntax styles.
|
|
4
4
|
|
|
5
|
-
import { parseColor, RGBA } from "@
|
|
5
|
+
import { parseColor, RGBA } from "@opentuah/core";
|
|
6
6
|
import { fileURLToPath } from "url";
|
|
7
7
|
|
|
8
8
|
// Only import the default theme statically for fast startup
|
package/src/web-utils.test.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { describe, test, expect, afterEach } from "bun:test"
|
|
2
|
-
import { createTestRenderer } from "@
|
|
3
|
-
import { createRoot } from "@
|
|
2
|
+
import { createTestRenderer } from "@opentuah/core/testing"
|
|
3
|
+
import { createRoot } from "@opentuah/react"
|
|
4
4
|
import React from "react"
|
|
5
|
-
import { RGBA } from "@
|
|
5
|
+
import { RGBA } from "@opentuah/core"
|
|
6
6
|
|
|
7
7
|
describe("getSpanLines rendering", () => {
|
|
8
8
|
let renderer: Awaited<ReturnType<typeof createTestRenderer>>["renderer"] | null = null
|
package/src/web-utils.tsx
CHANGED
|
@@ -8,7 +8,7 @@ import fs from "fs"
|
|
|
8
8
|
import { tmpdir } from "os"
|
|
9
9
|
import { join } from "path"
|
|
10
10
|
import { getResolvedTheme, rgbaToHex } from "./themes.ts"
|
|
11
|
-
import type { CapturedFrame, RootRenderable, CliRenderer } from "@
|
|
11
|
+
import type { CapturedFrame, RootRenderable, CliRenderer } from "@opentuah/core"
|
|
12
12
|
import type { IndexedHunk, ReviewYaml } from "./review/types.ts"
|
|
13
13
|
import { loadStoredLicenseKey, loadOrCreateOwnerSecret } from "./license.ts"
|
|
14
14
|
|
|
@@ -118,9 +118,9 @@ export async function renderDiffToFrame(
|
|
|
118
118
|
diffContent: string,
|
|
119
119
|
options: CaptureOptions
|
|
120
120
|
): Promise<CapturedFrame> {
|
|
121
|
-
const { createTestRenderer } = await import("@
|
|
122
|
-
const { createRoot } = await import("@
|
|
123
|
-
const { getTreeSitterClient } = await import("@
|
|
121
|
+
const { createTestRenderer } = await import("@opentuah/core/testing")
|
|
122
|
+
const { createRoot } = await import("@opentuah/react")
|
|
123
|
+
const { getTreeSitterClient } = await import("@opentuah/core")
|
|
124
124
|
const React = await import("react")
|
|
125
125
|
const { parsePatch, formatPatch } = await import("diff")
|
|
126
126
|
|
|
@@ -375,9 +375,9 @@ export interface ReviewRenderOptions extends CaptureOptions {
|
|
|
375
375
|
export async function renderReviewToFrame(
|
|
376
376
|
options: ReviewRenderOptions
|
|
377
377
|
): Promise<CapturedFrame> {
|
|
378
|
-
const { createTestRenderer } = await import("@
|
|
379
|
-
const { createRoot } = await import("@
|
|
380
|
-
const { getTreeSitterClient } = await import("@
|
|
378
|
+
const { createTestRenderer } = await import("@opentuah/core/testing")
|
|
379
|
+
const { createRoot } = await import("@opentuah/react")
|
|
380
|
+
const { getTreeSitterClient } = await import("@opentuah/core")
|
|
381
381
|
const React = await import("react")
|
|
382
382
|
|
|
383
383
|
// Pre-initialize TreeSitter client to ensure syntax highlighting works
|