Skip to content

Latest commit

 

History

23 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

semantic-terminal

Claude Code terminal output parser - detect states, parse confirmations, extract tool outputs.

Rust-powered performance with Node.js bindings via napi-rs.

Features

  • State Detection: Detect terminal states (Idle, Thinking, ToolRunning, Confirming, Error)
  • Confirmation Parsing: Parse tool approval dialogs with options and tool info
  • Status Bar Parsing: Extract spinner, status text, and phase information
  • Tool Output Parsing: Parse tool execution output with parameters and duration
  • Fingerprint Registry: Fast pattern matching with 22+ pre-defined patterns

Installation

Rust

[dependencies]
semantic-terminal = "0.1"

Node.js

npm install @anthropic/semantic-terminal

Pre-built binaries available for:

  • macOS (ARM64, x64)
  • Linux (x64 glibc, x64 musl)
  • Windows (x64)

Quick Start

Rust

use semantic_terminal::{
    ClaudeCodeStateParser, StateParser,
    ClaudeCodeConfirmParser, ConfirmParser,
    ParserContext,
};

// Detect terminal state
let parser = ClaudeCodeStateParser::new();
let context = ParserContext::new(vec!["❯ ".to_string()]);
if let Some(result) = parser.detect_state(&context) {
    println!("State: {:?}, Confidence: {}", result.state, result.confidence);
}

Node.js

import { detectState, detectConfirm, parseToolOutput, State } from '@anthropic/semantic-terminal'

// Detect terminal state
const state = detectState(['❯ '])
console.log(state.state) // 'Idle'

// Parse confirmation dialog
const confirm = detectConfirm([
  'xjp-mcp - xjp_secret_get(key: "test")',
  '❯ 1. Yes, allow this action',
  '  2. Yes, allow for this session',
  '  3. No, deny this action',
  'Esc to cancel',
])
console.log(confirm.tool.name) // 'xjp_secret_get'

// Parse tool output
const tool = parseToolOutput([
  '⏺ Bash',
  '  │ command: "git status"',
])
console.log(tool.toolName) // 'Bash'

API

State Detection

import { StateParser, detectState, State } from '@anthropic/semantic-terminal'

// Using class
const parser = new StateParser()
const result = parser.detect(['❯ '])

// Using convenience function
const result = detectState(['❯ '])

// Result type
interface StateResult {
  state: State  // 'Starting' | 'Idle' | 'Thinking' | 'ToolRunning' | 'Confirming' | 'Error'
  confidence: number
  needsTrustConfirm?: boolean
  confirmType?: ConfirmType
}

Confirmation Parsing

import { ConfirmParser, detectConfirm, ConfirmType } from '@anthropic/semantic-terminal'

const parser = new ConfirmParser()
const info = parser.detect(lines)

// Format responses for PTY
parser.formatConfirm()     // "\r" (Enter)
parser.formatDeny('Options') // "\x1b[B\x1b[B\r" (Down Down Enter)
parser.formatSelect(2)     // "\x1b[B\r" (Down Enter)

Status Bar Parsing

import { StatusParser, parseStatus } from '@anthropic/semantic-terminal'

const status = parseStatus(['· Precipitating… (esc to interrupt · thinking)'])
// { spinner: '·', statusText: 'Precipitating…', phase: 'Thinking', interruptible: true }

Tool Output Parsing

import { ToolOutputParser, parseToolOutput } from '@anthropic/semantic-terminal'

const tool = parseToolOutput([
  '⏺ Bash (completed in 0.5s)',
  '  │ command: "git status"',
])
// { toolName: 'Bash', params: { command: 'git status' }, durationMs: 500, status: 'Completed' }

Fingerprint Registry

Fast pattern matching with 22 pre-defined Claude Code fingerprints:

import { Registry, extractFingerprints } from '@anthropic/semantic-terminal'

const registry = new Registry()

// Quick checks
registry.hasSpinner(lines)  // true/false
registry.hasPrompt(lines)   // true/false
registry.hasError(lines)    // true/false

// Full extraction
const result = registry.extract(lines)
console.log(result.hints)  // { hasSpinner, hasPrompt, hasToolOutput, hasConfirmDialog, hasError }

Constants

import { knownTools, spinnerChars } from '@anthropic/semantic-terminal'

knownTools()   // ['Bash', 'Read', 'Edit', 'Write', 'Glob', 'Grep', ...]
spinnerChars() // ['·', '✻', '✽', '✶', '✳', '✢']

Use Cases

  • PTY Automation: Detect when Claude Code is waiting for input or confirmation
  • Task Monitoring: Track tool execution and state changes
  • Custom UIs: Build terminal UIs that react to Claude Code state
  • Testing: Validate Claude Code output in automated tests

Project Structure

semantic-terminal/
├── crates/
│   ├── semantic-terminal/      # Core Rust library
│   └── semantic-terminal-napi/ # Node.js bindings
├── packages/
│   ├── semantic-terminal/      # Main npm package
│   └── semantic-terminal-*/    # Platform-specific packages
└── Cargo.toml                  # Rust workspace

Building

Rust

cargo build --release

Node.js

cd packages/semantic-terminal
npm install
npm run build
npm test

License

MIT

About

The missing Semantic Layer for AI Agents to understand Terminal output

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages