- Keep **markers as plain text through reflowText to prevent ANSI code splitting
- Strip \x1b[0m full-reset codes that override Ink's <Text color> context
- Replace * bullets with · in post-processing
- Convert **text** to ANSI bold after reflow is complete
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- WARM_ACCENT: #c88a56 → #d4a070 (warmer highlight for ◆ and accents)
- WARM_REPLY: #f0e6d8 → #c0a480 (warm sand tone for AI response body)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use marked + marked-terminal to render markdown in assistant replies,
supporting bold, italic, inline code, tables, and lists in the terminal.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Revert the isSimpleGreeting LLM bypass in runtime.ts chat handler to
preserve existing behavior where tools.chat is always called. Adapt the
nl-router test to pass hasFailed: true when testing explain_failure
routing, matching the new guard condition.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove hardcoded maxTokens cap (240/700) from chat and developBookDraft
tools so thinking models like kimi-k2.5 are not truncated mid-response
- Add resolveProjectRoot() to launchTui so running `inkos` from inside a
book directory auto-resolves to the correct project root
- Pass projectRoot through loadConfig in createInteractionTools instead of
falling back to process.cwd()
- Skip LLM call for simple greetings (你好/hi/hello) that already have
built-in fallback responses, preventing empty-response errors
- Add try-catch around chat tool LLM call to gracefully degrade when
thinking models return empty content
- Guard "为什么/why" routing to explain_failure behind hasFailed context
flag so normal questions containing "为什么" route to chat instead
- Use columnGap={1} for conversation row spacing in Ink v7
- Remove statusSecondaryLine and mode label from status bar
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Guard browser.unref() call in studio command — mock spawn objects
in test environment don't have unref, causing TypeError
- Fix cli-integration test isolation: clean up harbor book and session
file after interact tests so book list/status tests find empty state
- Change interact --book test to use /books intent instead of
explain status which requires LLM connectivity
- Update v1 sections to v1.2 in README.md, README.en.md, README.ja.md
covering: shared interaction runtime, Ink TUI dashboard, Studio
assistant panel, conversational book creation, entity rename,
inkos interact endpoint, thinking model temperature clamp
- Add v1.2.0 changelog with full feature list, improvements, and fixes
- Bump all package versions from 1.1.1 to 1.2.0
The agent endpoint was returning `session.messages.at(-1)?.content` as
the response, but the last session message is the user's input — the
actual assistant reply is in `result.responseText`. This caused the
ChatBar to echo the user's own message back as the "assistant response".
The agent endpoint returns the response text in `data.response` and
the full session history in `data.session.messages`. The ChatBar was
replacing its entire message list with session history on every call,
but session messages don't include the latest assistant response —
so the reply was silently dropped every time.
Fix: always append `data.response` as an assistant message instead
of replacing with session history. Session restore only happens on
first panel open when ChatBar is empty.
The fadeIn animation's transform creates a stacking context on each
book card, trapping the dropdown's z-50 inside. When the BookMenu
opens, the parent card now gets z-50 to sit above sibling cards,
allowing the full dropdown (including delete) to render unclipped.
The paper-sheet hover effect used `transform: translateY(-4px)` which
creates a new stacking context, trapping the BookMenu dropdown's z-50
inside the card. Subsequent cards in DOM order rendered above it.
Remove transform and transform-style from paper-sheet, keep the
shadow-based hover effect. Dropdown menus now render above all cards.
The BookMenu dropdown (three-dot menu) was clipped by the parent
card's overflow-hidden. The progress bar already has its own
overflow-hidden, so the card-level clip was unnecessary.
54 commits from dev branch introducing:
- Shared interaction runtime (NL router, session management, edit controller)
- Ink-based TUI dashboard with themed animations and i18n
- Studio ChatBar shared session integration and book draft conversation flow
- CLI interact command for OpenClaw/agent interop
- Studio server endpoints for interaction session and agent routing
Core 585/585, Studio 70/70 tests pass.
- Fix SSE effect stale `loading` closure: use loadingRef to read
current loading state inside the SSE effect instead of capturing
a stale value from the dependency array
- Deduplicate handleSubmit/handleQuickCommand: extract shared
executeCommand() function, eliminating ~80 lines of copy-pasted
logic that would inevitably diverge
- Fix curly quote encoding issue causing esbuild parse failures
- Add semantic status colors and role colors to theme palette
- Improve conversation rows with distinct icons per role
- Upgrade ExecutionBadge with per-status icons
- Add visual separators between dashboard sections
- Improve composer with separated status/helper text
- Enhance startup animation with project info reveal
- Move hardcoded i18n strings into TuiCopy stageLabels
- Fix non-null assertions in effects.ts
- Remove cursor lift/settle — content flows top-to-bottom naturally
- Spinner + response appear above next input (like Claude Code)
- Input box: top border + hint drawn before prompt, bottom border
printed after submit, then response, then new input box
- Simplify InputChrome to drawInputTop/drawInputBottom
- Show configured model + provider in startup header
- Yellow warning if no model configured, directs to /config
- Tab completion for all slash commands (/write, /books, etc.)
- /config command launches interactive LLM setup wizard inline
- detectModelInfo reads provider/model/baseUrl from env files
- Filter ExperimentalWarning from stderr during TUI session
- Replace bordered input box with single gray separator line
- Gray ❯ prompt with proper spacing above and below
- Input line spans full terminal width
- Input prompt wrapped in ╭─ inkos ───╮ / ╰────╯ box
- Prompt shows │ ❯ inside the box frame
- Box closes after each input, reopens for next prompt
- Clean separation between output and input areas
- Auto-detect inkos.json on launch, auto-init if missing
- Interactive LLM config wizard when no API key found
- Persistent REPL loop with colored output and box-drawn header
- Spinner animation during async operations
- /help, /status, /quit, /clear built-in commands
- Natural language and slash commands delegated to interaction layer
- Zero new dependencies (pure ANSI escape codes)