453 Commits

Author SHA1 Message Date
Yunfei He 0209d5b5aa test: port Ink text tests (13 passing, 4 skipped)
Adds 17 text tests from Ink: color (standard/hex/rgb/ansi256),
background color, dim, bold, inversion, reactive remeasure, and
edge cases. 4 tests skipped due to null-children yoga crash and
constructor text lookup bug.

Also fixes lastFrame() treating empty-string frames as undefined
(Codex review feedback) and adds strip-ansi dev dependency.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 21:39:10 +08:00
Yunfei He 22ecbe0f80 test: port Ink layout tests (157 passing, 21 known failures)
Translates flex, direction, wrap, align, justify, gap, padding,
margin, width-height, position, display, and overflow tests from
Ink. Adds trimLines mode and trailing-newline strip to test helper.
Fixes Box type for alignContent (space-between/around/evenly) and
alignSelf (stretch/baseline).

21 tests fail due to behavioral differences (overflow clipping,
percentage dimensions, relative position offsets, align-content
space-* variants). These represent real gaps to investigate.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 21:24:31 +08:00
Yunfei He ffb5d69b0b feat(runtime): add per-side border dim and background color props
Adds borderTopDimColor/borderBottomDimColor/borderLeftDimColor/
borderRightDimColor and borderBackgroundColor with per-side variants.
Refactors drawBorder to use per-edge colorizers that respect
edge-specific color, dim, and background overrides.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 20:50:22 +08:00
Yunfei He 1503c18a66 feat(runtime): add wrap='hard' mode to Text component
Hard wrap breaks text at exact width boundaries without respecting
word boundaries. Uses wrap-ansi with { hard: true, trim: false }.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 20:45:21 +08:00
Yunfei He f4ef12f484 feat(runtime): add maxWidth, maxHeight, aspectRatio, alignContent, position props
Adds 9 new Box props backed by yoga-layout: maxWidth, maxHeight,
aspectRatio, alignContent, position, top, right, bottom, left.
Also adds baseline alignment support. Includes reset semantics
for props that Ink tests exercise clearing on rerender.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 20:42:49 +08:00
Yunfei He b78d65789d feat(paint): support ansi256() color format
Ink uses 'ansi256(N)' while vue-tui only parsed 'ansi(N)'.
Both now work. Needed for Ink test migration.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 20:40:03 +08:00
Yunfei He d976ab5f90 chore(test): bump FORCE_COLOR to 3 for truecolor support
Ink tests use chalk level 3 (24-bit) for hex/rgb/ansi256 colors.
Level 1 (basic 16-color) caused different ANSI codes than expected.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 20:39:57 +08:00
Yunfei He 5a3de85079 feat(testing): add raw frame access via lastFrame({ raw: true })
Stores raw (untrimmed) frames internally. lastFrame() still trims
by default for backward compat. lastFrame({ raw: true }) returns
the untrimmed output for layout tests asserting exact widths.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 20:37:01 +08:00
Yunfei He ff75506371 chore: add chalk to workspace catalog, update deps
Adds chalk to pnpm-workspace catalog (runtime-tests referenced
catalog:chalk but it was missing). Also updates vite-plus deps
to fix vitest JSX transform regression.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 20:33:24 +08:00
Yunfei He 53206292ce refactor(paint): preserve trailing spaces in Output.get()
Removes trimEnd() from the paint grid output. The test helper's
trimFrame() still handles cosmetic trimming for lastFrame(), so
existing tests are unaffected. This enables layout tests to assert
exact widths via lastFrame({ raw: true }).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 20:33:17 +08:00
Yunfei He 0bf3bf32ef chore: set FORCE_COLOR=1 in test env for realistic ANSI output
Tests must exercise the same ANSI code paths users see. Without
FORCE_COLOR, chalk disables all color in non-TTY test environments,
making style bugs invisible to the test suite.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 17:47:26 +08:00
Yunfei He 5b399e0844 feat(runtime): enable raw mode by default on mount
TUI apps should suppress terminal echo to prevent keystroke pollution
in the rendered UI. Raw mode is now on by default (matching Bubbletea,
Textual, Ratatui), with exitOnCtrlC also defaulting to true.

Pass rawMode: false to mount() for pure-output CLI tools that don't
need input suppression.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 17:43:21 +08:00
Yunfei He ca25ccd96e fix(paint): continuous backgroundColor across wrapped text lines
- Wrap each text line with applyChalk(bgProps) after wrapText so
  background color is reapplied on every wrapped line (wrap-ansi
  doesn't carry ANSI state across line breaks)
- Add wrapped-text backgroundColor regression test
- Fix typo: color=" cyan" → color="cyan" in example
- Add FORCE_COLOR=3 debugging tip to AGENTS.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 11:31:00 +08:00
Yunfei He e62c802829 fix(paint): continuous backgroundColor with borders
- Fill background inside border area only (not under border chars)
  so border placeLine doesn't overwrite background ANSI codes
- Pad text lines to full layout width when inheritedBg is set
  so background extends past text content to fill the row

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 11:24:36 +08:00
Yunfei He ecad937af9 docs: add test-first bug fix rule to AGENTS.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 11:16:06 +08:00
Yunfei He 8e6c4c5c2b fix(paint): backgroundColor now visible with borders and text
Root causes:
- drawBorder wrote plain characters, overwriting fillBackground's ANSI codes
- renderTextWithInlineStyles spread node.props over inherited bg, but
  undefined props from Vue clobbered the inherited backgroundColor
- Child text nodes did not inherit backgroundColor from parent Box

Fixes:
- drawBorder applies backgroundColor (and borderColor) to border chars
- Filter out undefined props before merging in renderTextWithInlineStyles
- Pass inheritedBg through the paint tree to text nodes

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 11:11:54 +08:00
Yunfei He e850cb15ee docs: update Examples section and move below Quick Example
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 00:03:45 +08:00
Yunfei He ddac248d26 fix(runtime): set Static yoga node to display:none in dynamic layout
Static content is rendered via paintIsolated (separate channel), but its
yoga node was still participating in the dynamic frame layout calculation,
adding blank lines equal to the Static content height between the last
Static item and the dynamic content below.

Setting display:none on the Static yoga node removes it from the dynamic
layout. paintIsolated is unaffected — it reparents children into a
temporary yoga tree.
2026-05-24 23:16:58 +08:00
Yunfei He 15cf216291 fix(cli): add prepublishOnly to ensure build before publish
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 23:04:56 +08:00
Yunfei He 0854ef4828 fix(coding-agent): fix user message layout and add Agent prefix
- Use nested Text instead of sibling Text nodes to keep 'You: ' and
  content on the same line (avoids yoga row layout splitting them)
- Add 'Agent: ' prefix (cyan, bold) to assistant messages
2026-05-24 23:03:13 +08:00
Yunfei He b834a87529 fix(runtime): clear dynamic frame before flushing static content
flushStatic() writes directly to stdout, but log-update tracks cursor
position for in-place re-rendering. Without clearing log-update first,
the static content gets overwritten when the dynamic frame re-renders.

Adds a regression test that verifies the clear sequence appears before
static content in non-debug mode.
2026-05-24 23:00:05 +08:00
Yunfei He ae33947c37 chore: prepare v0.0.1 release
- Bump all packages to 0.0.1
- Add publishConfig.access: public to @vue-tui/cli
- Disable tsgo for dts generation (missing native-preview dep)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 22:58:29 +08:00
Yunfei He 6b504d2a36 docs: add early-stage disclaimer to README
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 22:52:09 +08:00
Yunfei He 638dd9fbc7 fix(coding-agent): harden edge cases from codex review
- Guard JSON.parse of tool arguments with try-catch
- Robust tool-call accumulation via Map (handles out-of-order deltas)
- Pass real ToolCall to onToolCall/onToolResult (correct ids in scrollback)
- Persist skipped tool calls to Static scrollback
- Flush partial streaming text on network errors
- Ensure empty assistant messages have content: "" (valid schema)
2026-05-24 22:49:57 +08:00
Yunfei He 4ac8a87507 fix(coding-agent): persist user messages and tool results to Static scrollback 2026-05-24 22:40:57 +08:00
Yunfei He 20b412ace1 refactor: convert all SFCs to script setup
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 22:39:11 +08:00
Yunfei He 9f9edcf991 fix(coding-agent): lazy-init OpenAI client to avoid top-level throw 2026-05-24 22:36:38 +08:00
Yunfei He 253fa8bfc6 feat(coding-agent): add API key validation in entry point
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 22:32:55 +08:00
Yunfei He 6a8a365d24 feat(coding-agent): implement App with state machine and Static/Dynamic split
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 22:32:07 +08:00
Yunfei He b1da92e63c feat(coding-agent): add MessageList component
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 22:30:48 +08:00
Yunfei He 242fc74b9c feat(coding-agent): add streaming agent loop with DeepSeek
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 22:29:32 +08:00
Yunfei He 6aec92e16d feat(coding-agent): add types and bash execution
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 22:27:27 +08:00
Yunfei He 795251a080 feat(examples): scaffold coding-agent example
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 22:26:21 +08:00
Yunfei He f0443ef90e docs: move Packages section up and expand descriptions
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 22:20:35 +08:00
Yunfei He e87274fcda docs: replace manual install with tiged starter in Getting Started
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 22:13:59 +08:00
Yunfei He 8bda124b9a docs: polish README with install, examples, API overview, and testing
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 22:07:37 +08:00
Yunfei He 34a73c1b5f fix: rename start to preview in remaining examples
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 21:48:09 +08:00
Yunfei He 48ff01a0f9 fix: rename flappy-bird package and use preview instead of start
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 21:47:26 +08:00
Yunfei He abfdf89e3e docs: update README tagline
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 21:45:29 +08:00
Yunfei He d98bbb6369 chore: remove unused apps/website and packages/utils
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 21:41:13 +08:00
Yunfei He 625aa138f1 fix(cli): clean terminal output for TUI apps
- Silence Vite server logs (logLevel: 'silent')
- Intercept console.log/info/warn/error/debug in child process to
  suppress [vite] and [Vue warn] noise from HMR client
- Add 3s startup grace period to ignore initial reload requests
  (prevents double-spawn on first WS connection)
- Clear screen before spawning child process

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 21:39:28 +08:00
Yunfei He d31e8b7a65 fix(cli): clear screen before spawning child process
Prevents Vite startup logs and connection messages from mixing
with the TUI app's output.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 21:23:26 +08:00
Yunfei He 020fd0d85a feat: add basic-jsx and basic-template examples
- basic-jsx: Counter + Clock with defineComponent() + JSX
- basic-template: Counter + Clock with .vue SFC + <template>
- Both demonstrate HMR via vue-tui dev
- Fix vite-plugin: strip build.lib and external config for bundledDev,
  add node builtins resolveId to prevent browser-external shimming
- Remove old hmr-demo example (superseded by basic-template)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 21:21:08 +08:00
Yunfei He e8ef31814a feat: add hmr-demo example with Vue SFC HMR
- Counter + Clock components demonstrating component-level HMR
- Fix hmr-loader: use project-root file:// URL prefix so Node's
  bare specifier resolution finds node_modules
- Fix hmr-loader: export hooks directly instead of inline data URL
- Fix process-manager: register loader via data URL + register()
  pointing to the file (matches spike pattern)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 20:48:52 +08:00
Yunfei He 81a640f3ba feat(runtime): add HMR event bridge, DevOverlay, and dev mode wiring
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 20:01:07 +08:00
Yunfei He d319e77540 feat(cli): add orchestrator and CLI entry point
Create dev.ts orchestrator wiring Vite dev server, bundle extractor, and
process manager together with HMR reload and crash-recovery logic.
Replace index.ts placeholder with full CLI entry supporting `vue-tui dev [entry]`.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 19:57:47 +08:00
Yunfei He 2b7d1250f4 feat(cli): scaffold @vue-tui/cli package with all modules
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 19:55:46 +08:00
Yunfei He fda19b926d docs: README with Ink credits, project website
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 18:14:06 +08:00
Yunfei He 544a826670 feat: flappy-bird and basic examples
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 18:13:57 +08:00
Yunfei He a7f7d9957d feat(runtime-tests): integration test suite
21 test files covering components, composables, focus, lifecycle,
and scheduler through the public render() API.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 18:13:53 +08:00