mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-17 13:55:50 +00:00
* feat: 第一版大重构 * fix: 修复类型问题 * chore: 更新版本到 1.3.2 * Add brave as alternative WebSearchTool * fix: 修正顺序 * fix: 修复对穷鬼模式的 auto dream 和 session memory 越过 * feat: 穷鬼模式去除 session-summary * feat: 创建 builtin-tools 包,搬运所有工具实现 将 src/tools/ 下的全部 60 个工具目录迁移至 packages/builtin-tools/src/tools/, 内部导入路径已更新为 src/ alias 模式。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: 更新 src/ 中所有工具引用至 builtin-tools 包,删除 src/tools/ - src/tools.ts 及 178 个 src/ 文件的 import 路径从 ./tools/ 改为 builtin-tools/tools/ - 删除 src/tools/ 整个目录(已迁移至 packages/builtin-tools/) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: 添加 builtin-tools 路径别名至 tsconfig,更新 bun.lock - tsconfig.json 新增 builtin-tools/* 和 builtin-tools 路径映射 - 新增 packages/builtin-tools/src 至 include Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: 为 builtin-tools、mcp-client、agent-tools 添加 @claude-code-best 作用域前缀 所有包名及 import 路径统一添加 @claude-code-best/ 前缀: - builtin-tools → @claude-code-best/builtin-tools - mcp-client → @claude-code-best/mcp-client - agent-tools → @claude-code-best/agent-tools Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: 修复 node 环境没有 bun 的问题 --------- Co-authored-by: Eric-Guo <eric.guocz@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
382 lines
8.0 KiB
Markdown
382 lines
8.0 KiB
Markdown
# Chapter 12: Terminal Integration
|
|
|
|
This chapter covers terminal-specific features: alternate screen, mouse tracking, clipboard, notifications, and terminal querying.
|
|
|
|
## Alternate Screen
|
|
|
|
Enter a fullscreen alternate screen buffer (like vim, less, htop).
|
|
|
|
```tsx
|
|
import { AlternateScreen } from '@anthropic/ink'
|
|
|
|
<AlternateScreen mouseTracking={true}>
|
|
<Box flexDirection="column" height="100%">
|
|
<Text>Fullscreen content</Text>
|
|
</Box>
|
|
</AlternateScreen>
|
|
```
|
|
|
|
### Props
|
|
|
|
| Prop | Type | Default | Description |
|
|
|------|------|---------|-------------|
|
|
| `children` | `ReactNode` | - | Content |
|
|
| `mouseTracking` | `boolean` | `true` | Enable SGR mouse tracking |
|
|
|
|
### Behavior
|
|
|
|
On mount:
|
|
1. Enters DEC 1049 alternate screen buffer
|
|
2. Hides cursor
|
|
3. Enables mouse tracking (if `mouseTracking=true`)
|
|
4. Constrains rendering height to terminal rows
|
|
|
|
On unmount:
|
|
1. Exits alternate screen buffer
|
|
2. Shows cursor
|
|
3. Disables mouse tracking
|
|
4. Restores original terminal content
|
|
|
|
### Mouse Tracking Modes
|
|
|
|
When enabled:
|
|
- **Mode 1003** -- Button press/release + motion (hover)
|
|
- **Mode 1006** -- SGR extended mouse format (coordinates > 223)
|
|
- **Wheel events** -- Scroll up/down
|
|
|
|
### External Editor Handoff
|
|
|
|
The Ink instance supports pausing for an external editor:
|
|
|
|
```ts
|
|
// Pause Ink, run external command, resume
|
|
ink.enterAlternateScreen() // Save state
|
|
// ... external editor runs ...
|
|
ink.reassertTerminalModes() // Restore on resume
|
|
```
|
|
|
|
This is triggered by Ctrl+Z (SIGTSTP) and SIGCONT.
|
|
|
|
## Mouse Events
|
|
|
|
### Click Events
|
|
|
|
```tsx
|
|
<Box onClick={(event) => {
|
|
console.log(`Clicked at col=${event.x}, row=${event.y}`)
|
|
event.stopImmediatePropagation()
|
|
}}>
|
|
<Text>Clickable area</Text>
|
|
</Box>
|
|
```
|
|
|
|
### Multi-Click
|
|
|
|
Double-click selects a word, triple-click selects a line. Handled by the App component:
|
|
|
|
```ts
|
|
// App prop
|
|
onMultiClick: (col: number, row: number, count: 2 | 3) => void
|
|
```
|
|
|
|
### Hover Events
|
|
|
|
```tsx
|
|
<Box
|
|
onMouseEnter={() => setHovered(true)}
|
|
onMouseLeave={() => setHovered(false)}
|
|
>
|
|
<Text>{hovered ? 'Hovered!' : 'Hover me'}</Text>
|
|
</Box>
|
|
```
|
|
|
|
Hover uses `mouseenter`/`mouseleave` semantics (no bubbling between children).
|
|
|
|
### Drag-to-Select
|
|
|
|
In alt-screen mode, click-drag creates a text selection:
|
|
|
|
```ts
|
|
// App prop
|
|
onSelectionDrag: (col: number, row: number) => void
|
|
```
|
|
|
|
## Clipboard
|
|
|
|
### OSC 52 Clipboard
|
|
|
|
```tsx
|
|
import { setClipboard } from '@anthropic/ink'
|
|
|
|
await setClipboard('Copied text')
|
|
```
|
|
|
|
### Copy Selection
|
|
|
|
```tsx
|
|
const { copySelection } = useSelection()
|
|
const text = copySelection() // Copies to clipboard and clears highlight
|
|
```
|
|
|
|
### Copy Without Clear
|
|
|
|
```tsx
|
|
const { copySelectionNoClear } = useSelection()
|
|
const text = copySelectionNoClear() // Copies but keeps highlight
|
|
```
|
|
|
|
## Terminal Notifications
|
|
|
|
Send desktop notifications from the terminal.
|
|
|
|
```tsx
|
|
import { useTerminalNotification } from '@anthropic/ink'
|
|
|
|
function MyComponent() {
|
|
const { notifyBell, progress } = useTerminalNotification()
|
|
|
|
// Terminal bell (audible/system notification)
|
|
notifyBell()
|
|
|
|
// Progress bar in terminal title/tab
|
|
progress('running', 65) // 65% complete
|
|
progress('completed') // Done
|
|
progress('error') // Error state
|
|
progress('indeterminate') // Unknown progress
|
|
progress(null) // Clear
|
|
}
|
|
```
|
|
|
|
### Terminal-Specific Notifications
|
|
|
|
```tsx
|
|
const { notifyITerm2, notifyKitty, notifyGhostty } = useTerminalNotification()
|
|
|
|
// iTerm2
|
|
notifyITerm2({ message: 'Build complete', title: 'My App' })
|
|
|
|
// Kitty
|
|
notifyKitty({ message: 'Build complete', title: 'My App', id: 1 })
|
|
|
|
// Ghostty
|
|
notifyGhostty({ message: 'Build complete', title: 'My App' })
|
|
```
|
|
|
|
## Terminal Queries
|
|
|
|
### Background Color (OSC 11)
|
|
|
|
Used for auto-theme detection:
|
|
|
|
```ts
|
|
import { getTerminalBackground } from '@anthropic/ink'
|
|
const bg = await getTerminalBackground()
|
|
// e.g., 'rgb:0000/0000/0000' (dark) or 'rgb:ffff/ffff/ffff' (light)
|
|
```
|
|
|
|
### Terminal Version (XTVERSION)
|
|
|
|
```ts
|
|
import { isXtermJs, setXtversionName, getXtversionName } from '@anthropic/ink'
|
|
```
|
|
|
|
### Feature Detection
|
|
|
|
```ts
|
|
import { supportsHyperlinks } from '@anthropic/ink'
|
|
|
|
if (supportsHyperlinks()) {
|
|
// OSC 8 hyperlinks supported
|
|
}
|
|
|
|
import { supportsExtendedKeys } from '@anthropic/ink'
|
|
|
|
if (supportsExtendedKeys()) {
|
|
// Kitty keyboard protocol / modifyOtherKeys available
|
|
}
|
|
```
|
|
|
|
## Terminal Focus
|
|
|
|
Track terminal window focus/unfocus:
|
|
|
|
```tsx
|
|
import { useTerminalFocus } from '@anthropic/ink'
|
|
|
|
const isFocused = useTerminalFocus()
|
|
```
|
|
|
|
Low-level API:
|
|
|
|
```ts
|
|
import { getTerminalFocused, subscribeTerminalFocus } from '@anthropic/ink'
|
|
|
|
getTerminalFocused() // boolean
|
|
subscribeTerminalFocus((focused: boolean) => {
|
|
// Called on focus change
|
|
})
|
|
```
|
|
|
|
Uses DECSET 1004 focus reporting.
|
|
|
|
## Terminal Title
|
|
|
|
Set the terminal window title:
|
|
|
|
```tsx
|
|
import { useTerminalTitle } from '@anthropic/ink'
|
|
|
|
useTerminalTitle('My App - Dashboard')
|
|
```
|
|
|
|
Clear:
|
|
|
|
```tsx
|
|
useTerminalTitle(null)
|
|
```
|
|
|
|
## Terminal I/O Sequences
|
|
|
|
Low-level ANSI sequence constants for advanced use.
|
|
|
|
### Cursor Control
|
|
|
|
```ts
|
|
import {
|
|
SHOW_CURSOR,
|
|
HIDE_CURSOR,
|
|
CURSOR_HOME,
|
|
} from '@anthropic/ink'
|
|
|
|
// cursorPosition(row, col) -- Move cursor to absolute position
|
|
// cursorMove(dx, dy) -- Move cursor relative
|
|
```
|
|
|
|
### Screen Control
|
|
|
|
```ts
|
|
import {
|
|
ENTER_ALT_SCREEN,
|
|
EXIT_ALT_SCREEN,
|
|
ERASE_SCREEN,
|
|
} from '@anthropic/ink'
|
|
```
|
|
|
|
### Mouse Control
|
|
|
|
```ts
|
|
import {
|
|
ENABLE_MOUSE_TRACKING,
|
|
DISABLE_MOUSE_TRACKING,
|
|
} from '@anthropic/ink'
|
|
```
|
|
|
|
### Keyboard Protocols
|
|
|
|
```ts
|
|
import {
|
|
ENABLE_KITTY_KEYBOARD,
|
|
DISABLE_KITTY_KEYBOARD,
|
|
ENABLE_MODIFY_OTHER_KEYS,
|
|
DISABLE_MODIFY_OTHER_KEYS,
|
|
} from '@anthropic/ink'
|
|
```
|
|
|
|
### Clipboard & Tab Status
|
|
|
|
```ts
|
|
import {
|
|
CLEAR_ITERM2_PROGRESS,
|
|
CLEAR_TAB_STATUS,
|
|
CLEAR_TERMINAL_TITLE,
|
|
wrapForMultiplexer,
|
|
} from '@anthropic/ink'
|
|
```
|
|
|
|
`wrapForMultiplexer` wraps OSC sequences for tmux compatibility.
|
|
|
|
## Terminal Compatibility
|
|
|
|
### Supported Terminals
|
|
|
|
| Terminal | Features |
|
|
|----------|----------|
|
|
| iTerm2 | Full support (hyperlinks, notifications, progress) |
|
|
| Kitty | Full support (keyboard protocol, notifications) |
|
|
| Ghostty | Full support |
|
|
| WezTerm | Full support |
|
|
| Alacritty | Most features |
|
|
| Windows Terminal | Most features |
|
|
| Apple Terminal | 256-color fallback |
|
|
| xterm.js (VS Code) | Detected and special-cased |
|
|
| tmux | Wrapped sequences via `wrapForMultiplexer` |
|
|
| Screen | Basic support |
|
|
|
|
### Feature Degradation
|
|
|
|
The framework gracefully degrades:
|
|
- No true color → Falls back to ANSI 16-color themes
|
|
- No OSC 52 → Clipboard operations silently fail
|
|
- No mouse tracking → Click/hover events are no-ops
|
|
- No extended keys → Standard escape sequences used
|
|
- No bracketed paste → Paste detected by timing heuristic
|
|
|
|
### Synchronized Output
|
|
|
|
```ts
|
|
import { isSynchronizedOutputSupported } from '@anthropic/ink'
|
|
|
|
if (isSynchronizedOutputSupported()) {
|
|
// BSU/ESU for tear-free rendering
|
|
}
|
|
```
|
|
|
|
Uses DECSET 2026 synchronized output to prevent partial frame display.
|
|
|
|
### Bracketed Paste
|
|
|
|
Uses DECSET 2004 to distinguish paste events from rapid typing. Automatically enabled by the App component.
|
|
|
|
## Text Selection (Alt-Screen)
|
|
|
|
### Selection State
|
|
|
|
```ts
|
|
type SelectionState = {
|
|
anchor: Point | null // Drag start
|
|
focus: Point | null // Current position
|
|
isDragging: boolean
|
|
anchorSpan: { lo: Point; hi: Point; kind: 'word' | 'line' } | null
|
|
scrolledOffAbove: string[] // Text scrolled out above
|
|
scrolledOffBelow: string[] // Text scrolled out below
|
|
}
|
|
```
|
|
|
|
### Selection Operations
|
|
|
|
- **Click-drag** -- Free-form selection
|
|
- **Double-click** -- Word selection
|
|
- **Triple-click** -- Line selection
|
|
- **Shift+Arrow** -- Extend selection from keyboard
|
|
- **Drag-to-scroll** -- Auto-scroll when dragging near edges
|
|
|
|
### noSelect Regions
|
|
|
|
Exclude areas from selection (gutters, line numbers):
|
|
|
|
```tsx
|
|
<Box noSelect={true}>
|
|
<Text>1 │</Text>
|
|
</Box>
|
|
<Box>
|
|
<Text>code here</Text> {/* Only this is selectable */}
|
|
</Box>
|
|
```
|
|
|
|
### Soft-Wrap Awareness
|
|
|
|
Selection correctly handles text that was wrapped across multiple rows:
|
|
- Wrapped lines are joined when copied
|
|
- Trailing whitespace is trimmed
|
|
- The `softWrap` bitmap tracks which rows are continuations
|