@nicomatt69/streamtty 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +471 -0
- package/dist/ai-sdk-adapter.d.ts +113 -0
- package/dist/ai-sdk-adapter.d.ts.map +1 -0
- package/dist/ai-sdk-adapter.js +304 -0
- package/dist/ai-sdk-adapter.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +188 -0
- package/dist/cli.js.map +1 -0
- package/dist/errors.d.ts +131 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +346 -0
- package/dist/errors.js.map +1 -0
- package/dist/events.d.ts +185 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +350 -0
- package/dist/events.js.map +1 -0
- package/dist/index.d.ts +117 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +323 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/streaming-parser.d.ts +81 -0
- package/dist/parser/streaming-parser.d.ts.map +1 -0
- package/dist/parser/streaming-parser.js +522 -0
- package/dist/parser/streaming-parser.js.map +1 -0
- package/dist/performance.d.ts +139 -0
- package/dist/performance.d.ts.map +1 -0
- package/dist/performance.js +401 -0
- package/dist/performance.js.map +1 -0
- package/dist/plugins/index.d.ts +6 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +22 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/plugin-system-inline.d.ts +116 -0
- package/dist/plugins/plugin-system-inline.d.ts.map +1 -0
- package/dist/plugins/plugin-system-inline.js +289 -0
- package/dist/plugins/plugin-system-inline.js.map +1 -0
- package/dist/plugins/plugin-system.d.ts +65 -0
- package/dist/plugins/plugin-system.d.ts.map +1 -0
- package/dist/plugins/plugin-system.js +202 -0
- package/dist/plugins/plugin-system.js.map +1 -0
- package/dist/plugins/rehype/harden.d.ts +15 -0
- package/dist/plugins/rehype/harden.d.ts.map +1 -0
- package/dist/plugins/rehype/harden.js +71 -0
- package/dist/plugins/rehype/harden.js.map +1 -0
- package/dist/plugins/rehype/index.d.ts +5 -0
- package/dist/plugins/rehype/index.d.ts.map +1 -0
- package/dist/plugins/rehype/index.js +21 -0
- package/dist/plugins/rehype/index.js.map +1 -0
- package/dist/plugins/remark/index.d.ts +6 -0
- package/dist/plugins/remark/index.d.ts.map +1 -0
- package/dist/plugins/remark/index.js +22 -0
- package/dist/plugins/remark/index.js.map +1 -0
- package/dist/plugins/remark/math.d.ts +7 -0
- package/dist/plugins/remark/math.d.ts.map +1 -0
- package/dist/plugins/remark/math.js +22 -0
- package/dist/plugins/remark/math.js.map +1 -0
- package/dist/plugins/remark/mermaid.d.ts +7 -0
- package/dist/plugins/remark/mermaid.d.ts.map +1 -0
- package/dist/plugins/remark/mermaid.js +19 -0
- package/dist/plugins/remark/mermaid.js.map +1 -0
- package/dist/plugins/types.d.ts +72 -0
- package/dist/plugins/types.d.ts.map +1 -0
- package/dist/plugins/types.js +3 -0
- package/dist/plugins/types.js.map +1 -0
- package/dist/renderer/blessed-renderer.d.ts +92 -0
- package/dist/renderer/blessed-renderer.d.ts.map +1 -0
- package/dist/renderer/blessed-renderer.js +610 -0
- package/dist/renderer/blessed-renderer.js.map +1 -0
- package/dist/renderers/index.d.ts +7 -0
- package/dist/renderers/index.d.ts.map +1 -0
- package/dist/renderers/index.js +21 -0
- package/dist/renderers/index.js.map +1 -0
- package/dist/renderers/math-renderer.d.ts +49 -0
- package/dist/renderers/math-renderer.d.ts.map +1 -0
- package/dist/renderers/math-renderer.js +193 -0
- package/dist/renderers/math-renderer.js.map +1 -0
- package/dist/renderers/mermaid-ascii.d.ts +14 -0
- package/dist/renderers/mermaid-ascii.d.ts.map +1 -0
- package/dist/renderers/mermaid-ascii.js +260 -0
- package/dist/renderers/mermaid-ascii.js.map +1 -0
- package/dist/renderers/mermaid-renderer.d.ts +79 -0
- package/dist/renderers/mermaid-renderer.d.ts.map +1 -0
- package/dist/renderers/mermaid-renderer.js +298 -0
- package/dist/renderers/mermaid-renderer.js.map +1 -0
- package/dist/renderers/shiki-ansi.d.ts +48 -0
- package/dist/renderers/shiki-ansi.d.ts.map +1 -0
- package/dist/renderers/shiki-ansi.js +206 -0
- package/dist/renderers/shiki-ansi.js.map +1 -0
- package/dist/renderers/table-ascii.d.ts +30 -0
- package/dist/renderers/table-ascii.d.ts.map +1 -0
- package/dist/renderers/table-ascii.js +243 -0
- package/dist/renderers/table-ascii.js.map +1 -0
- package/dist/renderers/table-renderer.d.ts +49 -0
- package/dist/renderers/table-renderer.d.ts.map +1 -0
- package/dist/renderers/table-renderer.js +224 -0
- package/dist/renderers/table-renderer.js.map +1 -0
- package/dist/renderers/unicode-math.d.ts +29 -0
- package/dist/renderers/unicode-math.d.ts.map +1 -0
- package/dist/renderers/unicode-math.js +181 -0
- package/dist/renderers/unicode-math.js.map +1 -0
- package/dist/security/ansi-sanitizer.d.ts +71 -0
- package/dist/security/ansi-sanitizer.d.ts.map +1 -0
- package/dist/security/ansi-sanitizer.js +275 -0
- package/dist/security/ansi-sanitizer.js.map +1 -0
- package/dist/security/chunk-processor.d.ts +81 -0
- package/dist/security/chunk-processor.d.ts.map +1 -0
- package/dist/security/chunk-processor.js +297 -0
- package/dist/security/chunk-processor.js.map +1 -0
- package/dist/security/index.d.ts +6 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +22 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/input-validator.d.ts +55 -0
- package/dist/security/input-validator.d.ts.map +1 -0
- package/dist/security/input-validator.js +201 -0
- package/dist/security/input-validator.js.map +1 -0
- package/dist/stream-protocol.d.ts +61 -0
- package/dist/stream-protocol.d.ts.map +1 -0
- package/dist/stream-protocol.js +214 -0
- package/dist/stream-protocol.js.map +1 -0
- package/dist/streamdown-compat.d.ts +74 -0
- package/dist/streamdown-compat.d.ts.map +1 -0
- package/dist/streamdown-compat.js +241 -0
- package/dist/streamdown-compat.js.map +1 -0
- package/dist/streaming/stream-stats.d.ts +97 -0
- package/dist/streaming/stream-stats.d.ts.map +1 -0
- package/dist/streaming/stream-stats.js +217 -0
- package/dist/streaming/stream-stats.js.map +1 -0
- package/dist/streaming-integration.d.ts +71 -0
- package/dist/streaming-integration.d.ts.map +1 -0
- package/dist/streaming-integration.js +194 -0
- package/dist/streaming-integration.js.map +1 -0
- package/dist/themes/index.d.ts +59 -0
- package/dist/themes/index.d.ts.map +1 -0
- package/dist/themes/index.js +122 -0
- package/dist/themes/index.js.map +1 -0
- package/dist/types/index.d.ts +222 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/plugin-types.d.ts +5 -0
- package/dist/types/plugin-types.d.ts.map +1 -0
- package/dist/types/plugin-types.js +6 -0
- package/dist/types/plugin-types.js.map +1 -0
- package/dist/types/stream-events.d.ts +71 -0
- package/dist/types/stream-events.d.ts.map +1 -0
- package/dist/types/stream-events.js +10 -0
- package/dist/types/stream-events.js.map +1 -0
- package/dist/utils/blessed-syntax-highlighter.d.ts +124 -0
- package/dist/utils/blessed-syntax-highlighter.d.ts.map +1 -0
- package/dist/utils/blessed-syntax-highlighter.js +440 -0
- package/dist/utils/blessed-syntax-highlighter.js.map +1 -0
- package/dist/utils/enhanced-table-renderer.d.ts +77 -0
- package/dist/utils/enhanced-table-renderer.d.ts.map +1 -0
- package/dist/utils/enhanced-table-renderer.js +376 -0
- package/dist/utils/enhanced-table-renderer.js.map +1 -0
- package/dist/utils/formatting.d.ts +100 -0
- package/dist/utils/formatting.d.ts.map +1 -0
- package/dist/utils/formatting.js +220 -0
- package/dist/utils/formatting.js.map +1 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +21 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/math-unicode-renderer.d.ts +38 -0
- package/dist/utils/math-unicode-renderer.d.ts.map +1 -0
- package/dist/utils/math-unicode-renderer.js +380 -0
- package/dist/utils/math-unicode-renderer.js.map +1 -0
- package/dist/utils/mermaid-ascii-renderer.d.ts +20 -0
- package/dist/utils/mermaid-ascii-renderer.d.ts.map +1 -0
- package/dist/utils/mermaid-ascii-renderer.js +325 -0
- package/dist/utils/mermaid-ascii-renderer.js.map +1 -0
- package/dist/utils/mermaid-ascii.d.ts +53 -0
- package/dist/utils/mermaid-ascii.d.ts.map +1 -0
- package/dist/utils/mermaid-ascii.js +181 -0
- package/dist/utils/mermaid-ascii.js.map +1 -0
- package/dist/utils/shiki-ansi-renderer.d.ts +29 -0
- package/dist/utils/shiki-ansi-renderer.d.ts.map +1 -0
- package/dist/utils/shiki-ansi-renderer.js +354 -0
- package/dist/utils/shiki-ansi-renderer.js.map +1 -0
- package/dist/utils/syntax-highlighter.d.ts +87 -0
- package/dist/utils/syntax-highlighter.d.ts.map +1 -0
- package/dist/utils/syntax-highlighter.js +265 -0
- package/dist/utils/syntax-highlighter.js.map +1 -0
- package/dist/utils/table-formatter-inline.d.ts +37 -0
- package/dist/utils/table-formatter-inline.d.ts.map +1 -0
- package/dist/utils/table-formatter-inline.js +337 -0
- package/dist/utils/table-formatter-inline.js.map +1 -0
- package/dist/utils/table.d.ts +35 -0
- package/dist/utils/table.d.ts.map +1 -0
- package/dist/utils/table.js +197 -0
- package/dist/utils/table.js.map +1 -0
- package/dist/widgets/stream-indicator.d.ts +130 -0
- package/dist/widgets/stream-indicator.d.ts.map +1 -0
- package/dist/widgets/stream-indicator.js +276 -0
- package/dist/widgets/stream-indicator.js.map +1 -0
- package/package.json +75 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Nicomatt69
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
# Streamtty
|
|
2
|
+
|
|
3
|
+
> A drop-in replacement for markdown rendering in TTY environments, designed for AI-powered streaming with blessed.
|
|
4
|
+
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
|
|
7
|
+
Streamtty is inspired by [Streamdown](https://github.com/vercel/streamdown) but built specifically for terminal/TTY environments using [blessed](https://github.com/chjj/blessed). It handles the unique challenges of streaming Markdown content from AI models in terminals, providing seamless formatting even with incomplete or unterminated Markdown blocks.
|
|
8
|
+
|
|
9
|
+
## ✨ Features
|
|
10
|
+
|
|
11
|
+
### Core Features
|
|
12
|
+
- 🚀 **Streaming-optimized** - Handles incomplete Markdown gracefully during real-time generation
|
|
13
|
+
- 🎨 **Unterminated block parsing** - Styles incomplete bold, italic, code, links, and headings
|
|
14
|
+
- 📊 **GitHub Flavored Markdown** - Tables, task lists, and strikethrough support
|
|
15
|
+
- 📝 **Rich formatting** - Headers, lists, blockquotes, links, and more
|
|
16
|
+
- ⚡ **Performance optimized** - Debounced rendering for efficient updates
|
|
17
|
+
- 🎮 **Interactive** - Built-in keyboard navigation and scrolling
|
|
18
|
+
|
|
19
|
+
### Enhanced Features (Streamdown Parity) ✨ NEW
|
|
20
|
+
- 📐 **Math Rendering** - LaTeX math expressions converted to Unicode (inline and block)
|
|
21
|
+
- 📊 **Mermaid Diagrams** - Flowcharts, sequence diagrams, and more rendered as ASCII art
|
|
22
|
+
- 🎨 **Shiki Syntax Highlighting** - Advanced code highlighting with multiple themes
|
|
23
|
+
- 📋 **Advanced Tables** - Full table support with alignment, borders, and navigation
|
|
24
|
+
- 🛡️ **Security Layer** - ANSI sanitization, input validation, and injection prevention
|
|
25
|
+
- ⌨️ **Interactive Controls** - Copy code, export diagrams, navigate with keyboard shortcuts
|
|
26
|
+
- 🔌 **Plugin System** - Remark/Rehype compatible plugin architecture
|
|
27
|
+
- 🎭 **Theme Support** - Light/dark themes with auto-detection
|
|
28
|
+
- 🧩 **Component Overrides** - Customize rendering for any token type
|
|
29
|
+
|
|
30
|
+
## 📦 Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install streamtty
|
|
34
|
+
# or
|
|
35
|
+
yarn add streamtty
|
|
36
|
+
# or
|
|
37
|
+
pnpm add streamtty
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
> **Note:** `blessed` is included as a dependency and will be installed automatically.
|
|
41
|
+
|
|
42
|
+
## 🚀 Quick Start
|
|
43
|
+
|
|
44
|
+
### Basic Usage
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
import { Streamtty } from 'streamtty';
|
|
48
|
+
|
|
49
|
+
const markdown = `
|
|
50
|
+
# Hello World
|
|
51
|
+
|
|
52
|
+
This is **bold** and this is *italic*.
|
|
53
|
+
|
|
54
|
+
\`\`\`typescript
|
|
55
|
+
console.log('Hello, Streamtty!');
|
|
56
|
+
\`\`\`
|
|
57
|
+
`;
|
|
58
|
+
|
|
59
|
+
const streamtty = new Streamtty();
|
|
60
|
+
streamtty.setContent(markdown);
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Streaming Usage (AI-like)
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import { Streamtty } from 'streamtty';
|
|
67
|
+
|
|
68
|
+
const streamtty = new Streamtty({
|
|
69
|
+
parseIncompleteMarkdown: true,
|
|
70
|
+
autoScroll: true,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Simulate AI streaming
|
|
74
|
+
const chunks = ['# Hello ', '**World**', '!\n\nThis is ', '`streaming`'];
|
|
75
|
+
for (const chunk of chunks) {
|
|
76
|
+
streamtty.stream(chunk);
|
|
77
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Interactive Chat Example
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import blessed from 'blessed';
|
|
85
|
+
import { Streamtty } from 'streamtty';
|
|
86
|
+
|
|
87
|
+
const screen = blessed.screen({
|
|
88
|
+
smartCSR: true,
|
|
89
|
+
title: 'AI Chat',
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
const streamtty = new Streamtty({ screen });
|
|
93
|
+
|
|
94
|
+
// Stream AI response character by character
|
|
95
|
+
function streamResponse(response: string) {
|
|
96
|
+
let index = 0;
|
|
97
|
+
const interval = setInterval(() => {
|
|
98
|
+
if (index < response.length) {
|
|
99
|
+
streamtty.stream(response[index]);
|
|
100
|
+
index++;
|
|
101
|
+
} else {
|
|
102
|
+
clearInterval(interval);
|
|
103
|
+
}
|
|
104
|
+
}, 50);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
streamResponse('# AI Response\n\nHere is some **formatted** text!');
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Enhanced Features Usage
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
import { Streamtty } from 'streamtty';
|
|
114
|
+
|
|
115
|
+
// Enable all enhanced features
|
|
116
|
+
const streamtty = new Streamtty({
|
|
117
|
+
syntaxHighlight: true,
|
|
118
|
+
theme: 'dark',
|
|
119
|
+
shikiLanguages: ['typescript', 'python', 'bash'],
|
|
120
|
+
enhancedFeatures: {
|
|
121
|
+
math: true, // LaTeX math rendering
|
|
122
|
+
mermaid: true, // Mermaid diagrams
|
|
123
|
+
shiki: true, // Advanced syntax highlighting
|
|
124
|
+
security: true, // ANSI sanitization & validation
|
|
125
|
+
interactiveControls: true, // Keyboard shortcuts
|
|
126
|
+
advancedTables: true, // Enhanced table rendering
|
|
127
|
+
},
|
|
128
|
+
controls: {
|
|
129
|
+
code: true, // Press 'c' to copy code blocks
|
|
130
|
+
table: true, // Arrow keys to navigate tables
|
|
131
|
+
mermaid: true, // Press 'e' to export diagrams
|
|
132
|
+
math: true, // Copy math expressions
|
|
133
|
+
},
|
|
134
|
+
security: {
|
|
135
|
+
enabled: true,
|
|
136
|
+
stripDangerousAnsi: true,
|
|
137
|
+
allowedLinkPrefixes: ['https://'],
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// Math rendering
|
|
142
|
+
const mathContent = `
|
|
143
|
+
Inline math: $E = mc^2$
|
|
144
|
+
|
|
145
|
+
Block math:
|
|
146
|
+
$$
|
|
147
|
+
\\int_0^\\infty e^{-x^2} dx = \\frac{\\sqrt{\\pi}}{2}
|
|
148
|
+
$$
|
|
149
|
+
`;
|
|
150
|
+
streamtty.setContent(mathContent);
|
|
151
|
+
|
|
152
|
+
// Mermaid diagrams
|
|
153
|
+
const diagramContent = `
|
|
154
|
+
\`\`\`mermaid
|
|
155
|
+
graph TD
|
|
156
|
+
A[Start] --> B{Decision}
|
|
157
|
+
B -->|Yes| C[Success]
|
|
158
|
+
B -->|No| D[Retry]
|
|
159
|
+
\`\`\`
|
|
160
|
+
`;
|
|
161
|
+
streamtty.stream(diagramContent);
|
|
162
|
+
|
|
163
|
+
// Advanced tables
|
|
164
|
+
const tableContent = `
|
|
165
|
+
| Feature | Status | Priority |
|
|
166
|
+
|---------|:------:|----------|
|
|
167
|
+
| Math | ✅ | High |
|
|
168
|
+
| Mermaid | ✅ | High |
|
|
169
|
+
| Tables | ✅ | Medium |
|
|
170
|
+
`;
|
|
171
|
+
streamtty.stream(tableContent);
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Plugin System
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
import { Streamtty, RemarkPlugin, RehypePlugin } from 'streamtty';
|
|
178
|
+
|
|
179
|
+
// Custom remark plugin (pre-parse)
|
|
180
|
+
const customRemarkPlugin: RemarkPlugin = {
|
|
181
|
+
name: 'custom-remark',
|
|
182
|
+
type: 'remark',
|
|
183
|
+
priority: 50,
|
|
184
|
+
async process(markdown, context) {
|
|
185
|
+
// Transform markdown before parsing
|
|
186
|
+
return markdown.replace(/TODO:/g, '📝 TODO:');
|
|
187
|
+
},
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
// Custom rehype plugin (post-parse)
|
|
191
|
+
const customRehypePlugin: RehypePlugin = {
|
|
192
|
+
name: 'custom-rehype',
|
|
193
|
+
type: 'rehype',
|
|
194
|
+
priority: 50,
|
|
195
|
+
async process(tokens, context) {
|
|
196
|
+
// Transform tokens after parsing
|
|
197
|
+
return tokens.map(token => {
|
|
198
|
+
if (token.type === 'text' && token.content.includes('IMPORTANT')) {
|
|
199
|
+
token.style = { fg: 'red', bold: true };
|
|
200
|
+
}
|
|
201
|
+
return token;
|
|
202
|
+
});
|
|
203
|
+
},
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
const streamtty = new Streamtty({
|
|
207
|
+
remarkPlugins: [customRemarkPlugin],
|
|
208
|
+
rehypePlugins: [customRehypePlugin],
|
|
209
|
+
});
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## 📖 API Reference
|
|
213
|
+
|
|
214
|
+
### `Streamtty`
|
|
215
|
+
|
|
216
|
+
Main class for rendering streamed markdown in TTY.
|
|
217
|
+
|
|
218
|
+
#### Constructor Options
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
interface StreamttyOptions {
|
|
222
|
+
parseIncompleteMarkdown?: boolean; // Default: true
|
|
223
|
+
styles?: Partial<MarkdownStyles>;
|
|
224
|
+
syntaxHighlight?: boolean; // Default: true
|
|
225
|
+
showLineNumbers?: boolean; // Default: false
|
|
226
|
+
maxWidth?: number; // Default: 120
|
|
227
|
+
gfm?: boolean; // Default: true
|
|
228
|
+
screen?: Widgets.Screen; // Custom blessed screen
|
|
229
|
+
autoScroll?: boolean; // Default: true
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
#### Methods
|
|
234
|
+
|
|
235
|
+
##### `stream(chunk: string): void`
|
|
236
|
+
|
|
237
|
+
Stream a chunk of markdown content. Handles incomplete markdown gracefully.
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
streamtty.stream('# Hello ');
|
|
241
|
+
streamtty.stream('**World**');
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
##### `setContent(markdown: string): void`
|
|
245
|
+
|
|
246
|
+
Set complete markdown content all at once.
|
|
247
|
+
|
|
248
|
+
```typescript
|
|
249
|
+
streamtty.setContent('# Complete Document\n\nWith **multiple** paragraphs.');
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
##### `render(): void`
|
|
253
|
+
|
|
254
|
+
Manually trigger a render. Usually not needed as rendering is automatic.
|
|
255
|
+
|
|
256
|
+
##### `clear(): void`
|
|
257
|
+
|
|
258
|
+
Clear all content from the display.
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
streamtty.clear();
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
##### `startAutoRender(intervalMs?: number): void`
|
|
265
|
+
|
|
266
|
+
Start auto-rendering at specified interval (default: 50ms).
|
|
267
|
+
|
|
268
|
+
##### `stopAutoRender(): void`
|
|
269
|
+
|
|
270
|
+
Stop auto-rendering.
|
|
271
|
+
|
|
272
|
+
##### `getScreen(): Widgets.Screen`
|
|
273
|
+
|
|
274
|
+
Get the blessed screen instance.
|
|
275
|
+
|
|
276
|
+
##### `getContainer(): Widgets.BoxElement`
|
|
277
|
+
|
|
278
|
+
Get the blessed container box.
|
|
279
|
+
|
|
280
|
+
##### `getContent(): string`
|
|
281
|
+
|
|
282
|
+
Get current buffer content.
|
|
283
|
+
|
|
284
|
+
##### `destroy(): void`
|
|
285
|
+
|
|
286
|
+
Cleanup and destroy the instance.
|
|
287
|
+
|
|
288
|
+
## 🎨 Styling
|
|
289
|
+
|
|
290
|
+
Streamtty uses blessed's styling system. You can customize styles for different markdown elements:
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
const streamtty = new Streamtty({
|
|
294
|
+
styles: {
|
|
295
|
+
h1: { fg: 'cyan', bold: true },
|
|
296
|
+
h2: { fg: 'blue', bold: true },
|
|
297
|
+
code: { fg: 'green', bold: true },
|
|
298
|
+
codeBlock: { fg: 'white', bg: 'black' },
|
|
299
|
+
blockquote: { fg: 'gray', italic: true },
|
|
300
|
+
link: { fg: 'blue', underline: true },
|
|
301
|
+
},
|
|
302
|
+
});
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
## ⌨️ Keyboard Shortcuts
|
|
306
|
+
|
|
307
|
+
Built-in keyboard navigation:
|
|
308
|
+
|
|
309
|
+
- `↑` / `k` - Scroll up
|
|
310
|
+
- `↓` / `j` - Scroll down
|
|
311
|
+
- `Page Up` - Scroll up one page
|
|
312
|
+
- `Page Down` - Scroll down one page
|
|
313
|
+
- `Home` / `g` - Go to top
|
|
314
|
+
- `End` / `G` - Go to bottom
|
|
315
|
+
- `Escape` / `q` / `Ctrl+C` - Exit
|
|
316
|
+
|
|
317
|
+
## 📚 Examples
|
|
318
|
+
|
|
319
|
+
Check out the `examples/` directory for complete examples:
|
|
320
|
+
|
|
321
|
+
### Basic Example
|
|
322
|
+
|
|
323
|
+
```bash
|
|
324
|
+
yarn tsx examples/basic.ts
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
Shows static markdown rendering with various elements.
|
|
328
|
+
|
|
329
|
+
### Streaming Example
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
yarn tsx examples/streaming.ts
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
Simulates AI-like streaming of markdown content.
|
|
336
|
+
|
|
337
|
+
### Chat Example
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
yarn tsx examples/chat.ts
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
Interactive chat interface with streaming AI responses.
|
|
344
|
+
|
|
345
|
+
## 🔧 Development
|
|
346
|
+
|
|
347
|
+
```bash
|
|
348
|
+
# Install dependencies
|
|
349
|
+
yarn install
|
|
350
|
+
|
|
351
|
+
# Build
|
|
352
|
+
yarn build
|
|
353
|
+
|
|
354
|
+
# Watch mode
|
|
355
|
+
yarn dev
|
|
356
|
+
|
|
357
|
+
# Run examples
|
|
358
|
+
yarn example:basic
|
|
359
|
+
yarn example:streaming
|
|
360
|
+
yarn example:chat
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
## 📝 Markdown Support
|
|
364
|
+
|
|
365
|
+
Streamtty supports a wide range of markdown features:
|
|
366
|
+
|
|
367
|
+
### Basic Formatting
|
|
368
|
+
|
|
369
|
+
- **Bold**: `**text**` or `__text__`
|
|
370
|
+
- *Italic*: `*text*` or `_text_`
|
|
371
|
+
- `Inline code`: `` `code` ``
|
|
372
|
+
- ~~Strikethrough~~: `~~text~~`
|
|
373
|
+
|
|
374
|
+
### Headers
|
|
375
|
+
|
|
376
|
+
```markdown
|
|
377
|
+
# H1
|
|
378
|
+
## H2
|
|
379
|
+
### H3
|
|
380
|
+
#### H4
|
|
381
|
+
##### H5
|
|
382
|
+
###### H6
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### Lists
|
|
386
|
+
|
|
387
|
+
```markdown
|
|
388
|
+
- Unordered list
|
|
389
|
+
- Items
|
|
390
|
+
|
|
391
|
+
1. Ordered list
|
|
392
|
+
2. Items
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### Code Blocks
|
|
396
|
+
|
|
397
|
+
````markdown
|
|
398
|
+
```typescript
|
|
399
|
+
function hello(): void {
|
|
400
|
+
console.log('Hello!');
|
|
401
|
+
}
|
|
402
|
+
```
|
|
403
|
+
````
|
|
404
|
+
|
|
405
|
+
### Blockquotes
|
|
406
|
+
|
|
407
|
+
```markdown
|
|
408
|
+
> This is a blockquote
|
|
409
|
+
> Multiple lines supported
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### Links
|
|
413
|
+
|
|
414
|
+
```markdown
|
|
415
|
+
[Link text](https://example.com)
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### Tables
|
|
419
|
+
|
|
420
|
+
```markdown
|
|
421
|
+
| Column 1 | Column 2 |
|
|
422
|
+
|----------|----------|
|
|
423
|
+
| Data 1 | Data 2 |
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
### Horizontal Rules
|
|
427
|
+
|
|
428
|
+
```markdown
|
|
429
|
+
---
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### Task Lists
|
|
433
|
+
|
|
434
|
+
```markdown
|
|
435
|
+
- [x] Completed task
|
|
436
|
+
- [ ] Pending task
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
## 🆚 Streamdown vs Streamtty
|
|
440
|
+
|
|
441
|
+
| Feature | Streamdown | Streamtty |
|
|
442
|
+
|---------|-----------|-----------|
|
|
443
|
+
| Environment | React / Web | TTY / Terminal |
|
|
444
|
+
| Rendering | React Components | Blessed Widgets |
|
|
445
|
+
| Output | HTML/JSX | ANSI/Terminal |
|
|
446
|
+
| Use Case | Web Apps | CLI Tools / TUIs |
|
|
447
|
+
| Dependencies | React, ReactDOM | Blessed, Marked |
|
|
448
|
+
|
|
449
|
+
## 🤝 Contributing
|
|
450
|
+
|
|
451
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
452
|
+
|
|
453
|
+
## 📄 License
|
|
454
|
+
|
|
455
|
+
MIT © [Your Name]
|
|
456
|
+
|
|
457
|
+
## 🙏 Credits
|
|
458
|
+
|
|
459
|
+
- Inspired by [Streamdown](https://github.com/vercel/streamdown) by Vercel
|
|
460
|
+
- Built with [blessed](https://github.com/chjj/blessed)
|
|
461
|
+
- Markdown parsing by [marked](https://github.com/markedjs/marked)
|
|
462
|
+
|
|
463
|
+
## 🔗 Links
|
|
464
|
+
|
|
465
|
+
- [Streamdown](https://github.com/vercel/streamdown) - The web/React version
|
|
466
|
+
- [blessed](https://github.com/chjj/blessed) - Terminal UI library
|
|
467
|
+
- [marked](https://github.com/markedjs/marked) - Markdown parser
|
|
468
|
+
|
|
469
|
+
---
|
|
470
|
+
|
|
471
|
+
Made with ❤️ for the terminal
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI SDK Stream Adapter
|
|
3
|
+
*
|
|
4
|
+
* This module provides an adapter that handles AI SDK streaming events
|
|
5
|
+
* and formats them appropriately for TTY rendering using streamtty.
|
|
6
|
+
*/
|
|
7
|
+
import { StreamEvent, StreamEventOptions } from './types/stream-events';
|
|
8
|
+
export interface AISDKStreamAdapterOptions extends StreamEventOptions {
|
|
9
|
+
maxToolResultLength?: number;
|
|
10
|
+
formatToolCalls?: boolean;
|
|
11
|
+
showThinking?: boolean;
|
|
12
|
+
renderTimestamps?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export declare class AISDKStreamAdapter {
|
|
15
|
+
private renderer;
|
|
16
|
+
private options;
|
|
17
|
+
constructor(renderer: {
|
|
18
|
+
stream: (content: string) => void;
|
|
19
|
+
}, options?: AISDKStreamAdapterOptions);
|
|
20
|
+
/**
|
|
21
|
+
* Handle a stream of AI SDK events
|
|
22
|
+
*/
|
|
23
|
+
handleAISDKStream(stream: AsyncGenerator<StreamEvent>): AsyncGenerator<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Process a single stream event
|
|
26
|
+
*/
|
|
27
|
+
processEvent(event: StreamEvent): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Render a validated stream event
|
|
30
|
+
*/
|
|
31
|
+
private renderEvent;
|
|
32
|
+
/**
|
|
33
|
+
* Render text delta events (streaming text)
|
|
34
|
+
*/
|
|
35
|
+
private renderTextDelta;
|
|
36
|
+
/**
|
|
37
|
+
* Render tool call events
|
|
38
|
+
*/
|
|
39
|
+
private renderToolCall;
|
|
40
|
+
/**
|
|
41
|
+
* Format a tool call event for display
|
|
42
|
+
*/
|
|
43
|
+
private formatToolCall;
|
|
44
|
+
/**
|
|
45
|
+
* Render tool result events
|
|
46
|
+
*/
|
|
47
|
+
private renderToolResult;
|
|
48
|
+
/**
|
|
49
|
+
* Format a tool result event for display
|
|
50
|
+
*/
|
|
51
|
+
private formatToolResult;
|
|
52
|
+
/**
|
|
53
|
+
* Format tool result content for display
|
|
54
|
+
*/
|
|
55
|
+
private formatToolResultContent;
|
|
56
|
+
/**
|
|
57
|
+
* Truncate content to specified length
|
|
58
|
+
*/
|
|
59
|
+
private truncateContent;
|
|
60
|
+
/**
|
|
61
|
+
* Render thinking/reasoning events
|
|
62
|
+
*/
|
|
63
|
+
private renderThinking;
|
|
64
|
+
/**
|
|
65
|
+
* Format thinking events for display
|
|
66
|
+
*/
|
|
67
|
+
private formatThinking;
|
|
68
|
+
/**
|
|
69
|
+
* Render status events
|
|
70
|
+
*/
|
|
71
|
+
private renderStatus;
|
|
72
|
+
/**
|
|
73
|
+
* Format status events for display
|
|
74
|
+
*/
|
|
75
|
+
private formatStatus;
|
|
76
|
+
/**
|
|
77
|
+
* Render error events
|
|
78
|
+
*/
|
|
79
|
+
private renderError;
|
|
80
|
+
/**
|
|
81
|
+
* Format error events for display
|
|
82
|
+
*/
|
|
83
|
+
private formatError;
|
|
84
|
+
/**
|
|
85
|
+
* Render start events
|
|
86
|
+
*/
|
|
87
|
+
private renderStart;
|
|
88
|
+
/**
|
|
89
|
+
* Render complete events
|
|
90
|
+
*/
|
|
91
|
+
private renderComplete;
|
|
92
|
+
/**
|
|
93
|
+
* Get appropriate icon for tool name
|
|
94
|
+
*/
|
|
95
|
+
private getToolIcon;
|
|
96
|
+
/**
|
|
97
|
+
* Get appropriate icon for status
|
|
98
|
+
*/
|
|
99
|
+
private getStatusIcon;
|
|
100
|
+
/**
|
|
101
|
+
* Format tool arguments for display
|
|
102
|
+
*/
|
|
103
|
+
private formatToolArgs;
|
|
104
|
+
/**
|
|
105
|
+
* Update adapter options
|
|
106
|
+
*/
|
|
107
|
+
updateOptions(options: Partial<AISDKStreamAdapterOptions>): void;
|
|
108
|
+
/**
|
|
109
|
+
* Get current options
|
|
110
|
+
*/
|
|
111
|
+
getOptions(): AISDKStreamAdapterOptions;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=ai-sdk-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-sdk-adapter.d.ts","sourceRoot":"","sources":["../src/ai-sdk-adapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,WAAW,EAEX,kBAAkB,EAOnB,MAAM,uBAAuB,CAAA;AAG9B,MAAM,WAAW,yBAA0B,SAAQ,kBAAkB;IACnE,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC3B;AAED,qBAAa,kBAAkB;IAI3B,OAAO,CAAC,QAAQ;IAHlB,OAAO,CAAC,OAAO,CAAqC;gBAG1C,QAAQ,EAAE;QAAE,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,EACvD,OAAO,GAAE,yBAA8B;IAazC;;OAEG;IACI,iBAAiB,CACtB,MAAM,EAAE,cAAc,CAAC,WAAW,CAAC,GAClC,cAAc,CAAC,IAAI,CAAC;IAOvB;;OAEG;IACG,YAAY,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBrD;;OAEG;YACW,WAAW;IA+BzB;;OAEG;YACW,eAAe;IAM7B;;OAEG;YACW,cAAc;IAS5B;;OAEG;IACH,OAAO,CAAC,cAAc;IAWtB;;OAEG;YACW,gBAAgB;IAK9B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAgB/B;;OAEG;IACH,OAAO,CAAC,eAAe;IAQvB;;OAEG;YACW,cAAc;IAS5B;;OAEG;IACH,OAAO,CAAC,cAAc;IAUtB;;OAEG;YACW,YAAY;IAK1B;;OAEG;IACH,OAAO,CAAC,YAAY;IAWpB;;OAEG;YACW,WAAW;IAKzB;;OAEG;IACH,OAAO,CAAC,WAAW;IAUnB;;OAEG;YACW,WAAW;IAQzB;;OAEG;YACW,cAAc;IAQ5B;;OAEG;IACH,OAAO,CAAC,WAAW;IAiCnB;;OAEG;IACH,OAAO,CAAC,aAAa;IAerB;;OAEG;IACH,OAAO,CAAC,cAAc;IAQtB;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,yBAAyB,CAAC,GAAG,IAAI;IAIhE;;OAEG;IACH,UAAU,IAAI,yBAAyB;CAGxC"}
|