Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/clean-box-drawing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"opencode-drive": patch
---

Render light box-drawing borders as continuous geometric primitives.
10 changes: 5 additions & 5 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/drive/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
"@effect/platform-node": "4.0.0-beta.101",
"@effect/platform-node-shared": "4.0.0-beta.101",
"@napi-rs/canvas": "1.0.2",
"@opencode-ai/client": "0.0.0-next-16543",
"@opencode-ai/client": "0.0.0-next-17010",
"@opentui/core": "0.4.5",
"@types/bun": "1.3.13",
"@typescript/native-preview": "7.0.0-dev.20251207.1",
Expand Down
41 changes: 41 additions & 0 deletions packages/drive/src/frame/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,27 @@ export const BlockGlyphs: Record<string, GlyphRect> = {
"╹": { x: CellWidth / 2 - 1, y: 0, width: 2, height: CellHeight / 2, stretch: false },
}

const lightBoxGlyphs: Record<
string,
readonly [up: boolean, right: boolean, down: boolean, left: boolean]
> = {
"─": [false, true, false, true],
"│": [true, false, true, false],
"┌": [false, true, true, false],
"┐": [false, false, true, true],
"└": [true, true, false, false],
"┘": [true, false, false, true],
"├": [true, true, true, false],
"┤": [true, false, true, true],
"┬": [false, true, true, true],
"┴": [true, true, false, true],
"┼": [true, true, true, true],
"╭": [false, true, true, false],
"╮": [false, false, true, true],
"╰": [true, true, false, false],
"╯": [true, false, false, true],
}

const diagonalBlockGlyphs: Record<string, ReadonlyArray<Omit<GlyphRect, "stretch">>> = {
"▚": [
{ x: 0, y: 0, width: CellWidth / 2, height: CellHeight / 2 },
Expand Down Expand Up @@ -94,6 +115,26 @@ export const drawBlockGlyph = (
context.fillRect(x + glyph.x, y + glyph.y, width, glyph.height)
return true
}
const box = lightBoxGlyphs[char]
if (box !== undefined) {
const lineX = CellWidth / 2 - 1
const lineY = CellHeight / 2 - 1
const vertical = box[0] || box[2]
if (vertical) {
const top = box[0] ? 0 : lineY
const bottom = box[2] ? CellHeight : lineY + 1
context.fillRect(x + lineX, y + top, 1, bottom - top)
}
if (!vertical && (box[1] || box[3])) {
const left = box[3] ? 0 : lineX
const right = box[1] ? CellWidth : lineX + 1
context.fillRect(x + left, y + lineY, right - left, 1)
} else {
if (box[3]) context.fillRect(x, y + lineY, lineX, 1)
if (box[1]) context.fillRect(x + lineX + 1, y + lineY, CellWidth - lineX - 1, 1)
}
return true
}
const quadrants = diagonalBlockGlyphs[char]
if (quadrants === undefined) return false
for (const quadrant of quadrants)
Expand Down
28 changes: 28 additions & 0 deletions packages/drive/test/frame.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,34 @@ describe("frame geometry", () => {
])
})

it("draws light box borders as connected pixel geometry", () => {
const rects: Array<readonly [number, number, number, number]> = []
const context = {
fillRect: (x: number, y: number, width: number, height: number) =>
void rects.push([x, y, width, height]),
}
expect(drawBlockGlyph(context, "│", 0, 0)).toBe(true)
expect(drawBlockGlyph(context, "─", CellWidth, 0)).toBe(true)
expect(drawBlockGlyph(context, "╭", CellWidth * 2, 0)).toBe(true)
expect(drawBlockGlyph(context, "┼", CellWidth * 3, 0)).toBe(true)
expect(rects.length).toBe(7)
expect(
rects.every(
([x, y, width, height]) =>
Number.isInteger(x) &&
Number.isInteger(y) &&
Number.isInteger(width) &&
Number.isInteger(height),
),
).toBe(true)
const pixels = rects.flatMap(([x, y, width, height]) =>
Array.from({ length: width * height }, (_, index) =>
`${x + (index % width)},${y + Math.floor(index / width)}`,
),
)
expect(new Set(pixels).size).toBe(pixels.length)
})

it("draws diagonal quadrant blocks edge-to-edge", () => {
const rects: Array<readonly [number, number, number, number]> = []
const context = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default defineScript({
yield* opencode.event.subscribe().pipe(
Stream.runForEach((event) => {
if (event.type === "session.tool.success" || event.type === "session.tool.failed")
toolSettlements.push(`${event.type}:${event.data.callID}`)
toolSettlements.push(`${event.type}:${event.data.id}`)
if (event.type === "session.execution.interrupted")
return Deferred.succeed(executionInterrupted, undefined).pipe(Effect.asVoid)
return Effect.void
Expand Down Expand Up @@ -92,13 +92,13 @@ export default defineScript({
opencode.permission.list({ sessionID }).pipe(
Effect.map((items) => {
const questionPermission = items.find(
(item) => item.source?.type === "tool" && item.source.callID === questionCallID,
(item) => item.source?.type === "tool" && item.source.id === questionCallID,
)
const readPermission = items.find(
(item) => item.source?.type === "tool" && item.source.callID === readCallID,
(item) => item.source?.type === "tool" && item.source.id === readCallID,
)
const globPermission = items.find(
(item) => item.source?.type === "tool" && item.source.callID === globCallID,
(item) => item.source?.type === "tool" && item.source.id === globCallID,
)
return questionPermission && readPermission && globPermission
? { question: questionPermission, read: readPermission, glob: globPermission }
Expand Down