mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-17 22:05: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>
408 lines
8.1 KiB
Markdown
408 lines
8.1 KiB
Markdown
# Chapter 9: Hooks Reference
|
|
|
|
Complete API reference for all hooks exported by `@anthropic/ink`.
|
|
|
|
---
|
|
|
|
## Application Hooks
|
|
|
|
### `useApp()`
|
|
|
|
Access app-level operations.
|
|
|
|
```ts
|
|
function useApp(): {
|
|
exit: (error?: Error) => void
|
|
}
|
|
```
|
|
|
|
Example:
|
|
```tsx
|
|
const { exit } = useApp()
|
|
// Gracefully unmount and exit
|
|
exit()
|
|
```
|
|
|
|
### `useStdin()`
|
|
|
|
Access the stdin stream and raw mode control.
|
|
|
|
```ts
|
|
function useStdin(): {
|
|
stdin: NodeJS.ReadStream
|
|
isRawModeSupported: boolean
|
|
setRawMode: (enabled: boolean) => void
|
|
internal_exitOnCtrlC: boolean
|
|
internal_eventEmitter: EventEmitter | undefined
|
|
internal_querier: TerminalQuerier | null
|
|
}
|
|
```
|
|
|
|
> Prefer `useInput` for keyboard handling.
|
|
|
|
---
|
|
|
|
## Input Hooks
|
|
|
|
### `useInput(handler, options?)`
|
|
|
|
Handle keyboard input. See [Chapter 7](./07-user-input.md) for full details.
|
|
|
|
```ts
|
|
function useInput(
|
|
handler: (input: string, key: Key, event: InputEvent) => void,
|
|
options?: { isActive?: boolean }
|
|
): void
|
|
```
|
|
|
|
---
|
|
|
|
## Terminal Hooks
|
|
|
|
### `useTerminalSize()`
|
|
|
|
Get current terminal dimensions.
|
|
|
|
```ts
|
|
function useTerminalSize(): {
|
|
columns: number
|
|
rows: number
|
|
}
|
|
```
|
|
|
|
Throws if used outside `<App>`.
|
|
|
|
### `useTerminalFocus()`
|
|
|
|
Track whether the terminal window is focused.
|
|
|
|
```ts
|
|
function useTerminalFocus(): boolean
|
|
```
|
|
|
|
Uses DECSET 1004 focus reporting. Returns `true` when focused.
|
|
|
|
### `useTerminalTitle(title)`
|
|
|
|
Set the terminal window title.
|
|
|
|
```ts
|
|
function useTerminalTitle(title: string | null): void
|
|
```
|
|
|
|
Pass `null` to clear the title.
|
|
|
|
### `useTerminalViewport()`
|
|
|
|
Track element visibility in the terminal viewport.
|
|
|
|
```ts
|
|
function useTerminalViewport(): [
|
|
ref: (element: DOMElement | null) => void,
|
|
entry: { isVisible: boolean }
|
|
]
|
|
```
|
|
|
|
Example:
|
|
```tsx
|
|
const [viewportRef, { isVisible }] = useTerminalViewport()
|
|
|
|
<Box ref={viewportRef}>
|
|
<Text>{isVisible ? 'Visible' : 'Scrolled off'}</Text>
|
|
</Box>
|
|
```
|
|
|
|
### `useTabStatus(kind)`
|
|
|
|
Set tab status indicator in terminal tab bar (OSC 21337).
|
|
|
|
```ts
|
|
type TabStatusKind = 'idle' | 'busy' | 'waiting'
|
|
function useTabStatus(kind: TabStatusKind | null): void
|
|
```
|
|
|
|
### `useTerminalNotification()`
|
|
|
|
Send terminal notifications (iTerm2, Kitty, Ghostty, bell).
|
|
|
|
```ts
|
|
function useTerminalNotification(): {
|
|
notifyITerm2: (opts: { message: string; title?: string }) => void
|
|
notifyKitty: (opts: { message: string; title: string; id: number }) => void
|
|
notifyGhostty: (opts: { message: string; title: string }) => void
|
|
notifyBell: () => void
|
|
progress: (state: Progress['state'] | null, percentage?: number) => void
|
|
}
|
|
```
|
|
|
|
Requires `TerminalWriteProvider` in the tree.
|
|
|
|
Progress states: `'running'`, `'completed'`, `'error'`, `'indeterminate'`, `null` (clear).
|
|
|
|
---
|
|
|
|
## Animation & Timing Hooks
|
|
|
|
### `useInterval(callback, intervalMs)`
|
|
|
|
Clock-backed interval timer.
|
|
|
|
```ts
|
|
function useInterval(callback: () => void, intervalMs: number | null): void
|
|
```
|
|
|
|
Pass `null` to pause. Shares the application clock for efficient batching.
|
|
|
|
### `useAnimationTimer(intervalMs)`
|
|
|
|
Returns the current clock time, updating at the given interval.
|
|
|
|
```ts
|
|
function useAnimationTimer(intervalMs: number): number
|
|
```
|
|
|
|
Subscribes as non-keepAlive -- won't keep the clock running on its own.
|
|
|
|
### `useAnimationFrame(intervalMs?)`
|
|
|
|
Synchronized animation hook that pauses when offscreen.
|
|
|
|
```ts
|
|
function useAnimationFrame(
|
|
intervalMs?: number | null, // default 16
|
|
): [ref: (element: DOMElement | null) => void, time: number]
|
|
```
|
|
|
|
Returns a ref callback (attach to animated element) and the current animation time. All instances share the same clock. Pass `null` to pause.
|
|
|
|
```tsx
|
|
const [ref, time] = useAnimationFrame(120)
|
|
const frame = Math.floor(time / 120) % FRAMES.length
|
|
return <Box ref={ref}>{FRAMES[frame]}</Box>
|
|
```
|
|
|
|
### `useTimeout(delayMs, resetTrigger?)`
|
|
|
|
One-shot timer.
|
|
|
|
```ts
|
|
function useTimeout(delay: number, resetTrigger?: number): boolean
|
|
```
|
|
|
|
Returns `true` when the timeout has elapsed. Change `resetTrigger` to restart.
|
|
|
|
### `useMinDisplayTime(value, minMs)`
|
|
|
|
Ensure a value is displayed for at least `minMs` milliseconds.
|
|
|
|
```ts
|
|
function useMinDisplayTime<T>(value: T, minMs: number): T
|
|
```
|
|
|
|
Holds the previous value until `minMs` has elapsed, then switches to the new value.
|
|
|
|
Example:
|
|
```tsx
|
|
// Keep showing "Loading" for at least 300ms to prevent flash
|
|
const displayValue = useMinDisplayTime(isLoading ? 'loading' : 'done', 300)
|
|
```
|
|
|
|
---
|
|
|
|
## Interaction Hooks
|
|
|
|
### `useDoublePress(setPending, onDoublePress, onFirstPress?)`
|
|
|
|
Detect double-press (double-click equivalent for keyboard).
|
|
|
|
```ts
|
|
export const DOUBLE_PRESS_TIMEOUT_MS = 800
|
|
|
|
function useDoublePress(
|
|
setPending: (pending: boolean) => void,
|
|
onDoublePress: () => void,
|
|
onFirstPress?: () => void
|
|
): () => void // Returns the press handler
|
|
```
|
|
|
|
Example:
|
|
```tsx
|
|
const [pendingExit, setPendingExit] = useState(false)
|
|
const handlePress = useDoublePress(
|
|
setPendingExit,
|
|
() => exit(), // Double press
|
|
() => {}, // First press
|
|
)
|
|
|
|
useInput((input, key) => {
|
|
if (key.escape) handlePress()
|
|
})
|
|
```
|
|
|
|
### `useExitOnCtrlCD(options?)`
|
|
|
|
Handle Ctrl+C / Ctrl+D with double-press confirmation.
|
|
|
|
```ts
|
|
type ExitState = {
|
|
pending: boolean
|
|
keyName: 'Ctrl-C' | 'Ctrl-D' | null
|
|
}
|
|
|
|
function useExitOnCtrlCDWithKeybindings(
|
|
onExit?: () => void,
|
|
onInterrupt?: () => boolean,
|
|
isActive?: boolean
|
|
): ExitState
|
|
```
|
|
|
|
Example:
|
|
```tsx
|
|
const exitState = useExitOnCtrlCDWithKeybindings(
|
|
() => exit(),
|
|
() => { /* return true to prevent exit */ }
|
|
)
|
|
|
|
if (exitState.pending) {
|
|
return <Text>Press {exitState.keyName} again to exit</Text>
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Selection Hooks (Alt-Screen Only)
|
|
|
|
### `useSelection()`
|
|
|
|
Text selection operations.
|
|
|
|
```ts
|
|
function useSelection(): {
|
|
copySelection: () => string
|
|
copySelectionNoClear: () => string
|
|
clearSelection: () => void
|
|
hasSelection: () => boolean
|
|
getState: () => SelectionState | null
|
|
subscribe: (cb: () => void) => () => void
|
|
shiftAnchor: (dRow: number, minRow: number, maxRow: number) => void
|
|
shiftSelection: (dRow: number, minRow: number, maxRow: number) => void
|
|
moveFocus: (move: FocusMove) => void
|
|
captureScrolledRows: (firstRow: number, lastRow: number, side: 'above' | 'below') => void
|
|
setSelectionBgColor: (color: string) => void
|
|
}
|
|
```
|
|
|
|
### `useHasSelection()`
|
|
|
|
Reactive boolean for selection state.
|
|
|
|
```ts
|
|
function useHasSelection(): boolean
|
|
```
|
|
|
|
Re-renders when selection is created or cleared.
|
|
|
|
---
|
|
|
|
## Search Hooks
|
|
|
|
### `useSearchHighlight()`
|
|
|
|
Set and manage search highlighting.
|
|
|
|
```ts
|
|
function useSearchHighlight(): {
|
|
setQuery: (query: string) => void
|
|
scanElement: (el: DOMElement) => MatchPosition[]
|
|
setPositions: (state: { positions: MatchPosition[]; rowOffset: number; currentIdx: number } | null) => void
|
|
}
|
|
```
|
|
|
|
### `useSearchInput(options)`
|
|
|
|
Search input handler with cursor management.
|
|
|
|
```ts
|
|
type UseSearchInputOptions = {
|
|
isActive: boolean
|
|
onExit: () => void
|
|
onCancel?: () => void
|
|
onExitUp?: () => void
|
|
columns?: number
|
|
passthroughCtrlKeys?: string[]
|
|
initialQuery?: string
|
|
backspaceExitsOnEmpty?: boolean
|
|
}
|
|
|
|
type UseSearchInputReturn = {
|
|
query: string
|
|
setQuery: (q: string) => void
|
|
cursorOffset: number
|
|
handleKeyDown: (e: KeyboardEvent) => void
|
|
}
|
|
|
|
function useSearchInput(options: UseSearchInputOptions): UseSearchInputReturn
|
|
```
|
|
|
|
---
|
|
|
|
## Cursor Hooks
|
|
|
|
### `useDeclaredCursor(options)`
|
|
|
|
Park the terminal cursor at a specific position for IME and accessibility.
|
|
|
|
```ts
|
|
function useDeclaredCursor({
|
|
line: number,
|
|
column: number,
|
|
active: boolean
|
|
}): (element: DOMElement | null) => void
|
|
```
|
|
|
|
Returns a ref callback. Position is relative to the ref'd element.
|
|
|
|
Example:
|
|
```tsx
|
|
const cursorRef = useDeclaredCursor({
|
|
line: 0,
|
|
column: cursorPosition,
|
|
active: isFocused,
|
|
})
|
|
|
|
return <Box ref={cursorRef}>...</Box>
|
|
```
|
|
|
|
---
|
|
|
|
## Tab Status Hooks
|
|
|
|
### `useTabStatus(kind)`
|
|
|
|
Set tab status indicator (OSC 21337) for terminal tab bars.
|
|
|
|
```ts
|
|
type TabStatusKind = 'idle' | 'busy' | 'waiting'
|
|
|
|
function useTabStatus(kind: TabStatusKind | null): void
|
|
```
|
|
|
|
Pass `null` to clear.
|
|
|
|
---
|
|
|
|
## Viewport Hooks
|
|
|
|
### `useTerminalViewport()`
|
|
|
|
Track element visibility within the terminal viewport.
|
|
|
|
```ts
|
|
function useTerminalViewport(): [
|
|
ref: (element: DOMElement | null) => void,
|
|
entry: { isVisible: boolean }
|
|
]
|
|
```
|
|
|
|
Returns a ref callback and visibility state.
|