clay-terminal
Version:
A beautiful, modern terminal for the web - Perfect for ChromeOS users without terminal access
479 lines (380 loc) • 10.6 kB
Markdown
# Clay Terminal - Integration Guide
This guide shows you how to integrate Clay Terminal into your existing project as an NPM package.
## 📦 Installation
```bash
npm install clay-terminal
```
### Install Peer Dependencies
```bash
npm install xterm xterm-addon-fit xterm-addon-web-links xterm-addon-canvas
```
## 🚀 Quick Integration
### 1. HTML Setup
```html
<html>
<head>
<title>My App with Terminal</title>
<!-- Include xterm.css -->
<link rel="stylesheet" href="node_modules/xterm/css/xterm.css" />
<style>
#terminal-container {
width: 100%;
height: 100vh;
background: #1e1e2e;
}
</style>
</head>
<body>
<div id="terminal-container"></div>
<script type="module">
import { createClayTerminal } from 'clay-terminal';
const terminal = await createClayTerminal({
container: document.getElementById('terminal-container')
});
</script>
</body>
</html>
```
### 2. React Integration
```bash
npm install clay-terminal xterm xterm-addon-fit xterm-addon-web-links xterm-addon-canvas
```
```tsx
// Terminal.tsx
import React, { useEffect, useRef } from 'react';
import { createClayTerminal, ClayTerminal } from 'clay-terminal';
import 'xterm/css/xterm.css';
import './Terminal.css';
interface TerminalProps {
bridgeUrl?: string;
onCommand?: (command: string) => void;
}
export default function Terminal({ bridgeUrl, onCommand }: TerminalProps) {
const containerRef = useRef<HTMLDivElement>(null);
const terminalRef = useRef<ClayTerminal | null>(null);
useEffect(() => {
if (!containerRef.current || terminalRef.current) return;
createClayTerminal({
container: containerRef.current,
bridgeUrl: bridgeUrl,
onOutput: (data) => {
// Handle output
},
onError: (error) => {
console.error('Terminal error:', error);
},
onStatusChange: (status) => {
console.log('Status:', status);
}
}).then(terminal => {
terminalRef.current = terminal;
// Execute initial command if needed
// terminal.executeCommand('ls -la');
});
return () => {
if (terminalRef.current) {
terminalRef.current.dispose();
}
};
}, [bridgeUrl]);
return (
<div className="terminal-wrapper">
<div ref={containerRef} className="terminal-container" />
</div>
);
}
```
```css
/* Terminal.css */
.terminal-wrapper {
width: 100%;
height: 100%;
}
.terminal-container {
width: 100%;
height: 100%;
padding: 16px;
}
```
### 3. Vue 3 Integration
```bash
npm install clay-terminal xterm xterm-addon-fit xterm-addon-web-links xterm-addon-canvas
```
```vue
<template>
<div ref="terminalContainer" class="terminal-container"></div>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { createClayTerminal, type ClayTerminal } from 'clay-terminal';
import 'xterm/css/xterm.css';
interface Props {
bridgeUrl?: string;
}
const props = defineProps<Props>();
const terminalContainer = ref<HTMLDivElement | null>(null);
let terminal: ClayTerminal | null = null;
onMounted(async () => {
if (terminalContainer.value) {
terminal = await createClayTerminal({
container: terminalContainer.value,
bridgeUrl: props.bridgeUrl,
onOutput: (data) => {
// Handle output
},
onError: (error) => {
console.error('Terminal error:', error);
}
});
}
});
onUnmounted(() => {
if (terminal) {
terminal.dispose();
}
});
</script>
<style scoped>
.terminal-container {
width: 100%;
height: 100vh;
background: #1e1e2e;
}
</style>
```
### 4. Next.js Integration
```bash
npm install clay-terminal xterm xterm-addon-fit xterm-addon-web-links xterm-addon-canvas
```
```tsx
// app/terminal/page.tsx (Next.js 13+ App Router)
'use client';
import { useEffect, useRef } from 'react';
import { createClayTerminal, type ClayTerminal } from 'clay-terminal';
import 'xterm/css/xterm.css';
export default function TerminalPage() {
const containerRef = useRef<HTMLDivElement>(null);
const terminalRef = useRef<ClayTerminal | null>(null);
useEffect(() => {
if (!containerRef.current || terminalRef.current) return;
createClayTerminal({
container: containerRef.current
}).then(terminal => {
terminalRef.current = terminal;
});
return () => {
if (terminalRef.current) {
terminalRef.current.dispose();
}
};
}, []);
return (
<div className="w-full h-screen bg-[#1e1e2e]">
<div ref={containerRef} className="w-full h-full p-4" />
</div>
);
}
```
### 5. Svelte Integration
```bash
npm install clay-terminal xterm xterm-addon-fit xterm-addon-web-links xterm-addon-canvas
```
```svelte
<script lang="ts">
import { onMount, onDestroy } from 'svelte';
import { createClayTerminal, type ClayTerminal } from 'clay-terminal';
import 'xterm/css/xterm.css';
let terminalContainer: HTMLDivElement;
let terminal: ClayTerminal | null = null;
onMount(async () => {
if (terminalContainer) {
terminal = await createClayTerminal({
container: terminalContainer
});
}
});
onDestroy(() => {
if (terminal) {
terminal.dispose();
}
});
</script>
<div class="terminal-wrapper">
<div bind:this={terminalContainer} class="terminal-container"></div>
</div>
<style>
.terminal-wrapper {
width: 100%;
height: 100vh;
}
.terminal-container {
width: 100%;
height: 100%;
padding: 16px;
}
</style>
```
## 🔧 Advanced Configuration
### Custom Theme
```typescript
import { createClayTerminal } from 'clay-terminal';
const terminal = await createClayTerminal({
container: document.getElementById('terminal'),
theme: {
background: '#0a0a0a',
foreground: '#ffffff',
cursor: '#00ff00',
// ... customize colors
},
fontSize: 14,
fontFamily: 'Monaco, monospace'
});
```
### With Bridge Server (Real System Access)
```typescript
import { createClayTerminal } from 'clay-terminal';
// Start bridge server first:
// cd bridge && npm install && npm start
const terminal = await createClayTerminal({
container: document.getElementById('terminal'),
bridgeUrl: 'ws://127.0.0.1:8765/ws',
autoConnectBridge: true,
onStatusChange: (status) => {
if (status.backend === 'connected') {
console.log('✅ Real system access enabled!');
}
}
});
```
### Programmatic Command Execution
```typescript
import { createClayTerminal } from 'clay-terminal';
const terminal = await createClayTerminal({
container: document.getElementById('terminal')
});
// Execute commands programmatically
await terminal.executeCommand('ls -la');
await terminal.executeCommand('cd ~/Documents');
await terminal.executeCommand('cat file.txt');
// Get command history
const history = terminal.getHistory();
// Get session commands for sharing
const sessionCommands = terminal.getSessionCommands();
```
### Event Handling
```typescript
import { createClayTerminal } from 'clay-terminal';
const terminal = await createClayTerminal({
container: document.getElementById('terminal'),
onOutput: (data) => {
// Handle all terminal output
console.log('Output:', data);
// You can filter or process output here
if (data.includes('error')) {
// Handle errors
}
},
onError: (error) => {
// Handle terminal errors
console.error('Terminal error:', error);
showErrorNotification(error);
},
onStatusChange: (status) => {
// Update UI based on status
updateStatusIndicator(status.backend, status.ai);
if (status.backend === 'connected') {
showSuccessMessage('Terminal connected!');
} else if (status.backend === 'error') {
showErrorMessage('Connection failed');
}
}
});
// You can also register callbacks later
terminal.onOutput((data) => {
// Additional output handler
});
```
## 📦 Building for Production
### Webpack Configuration
```javascript
// webpack.config.js
module.exports = {
// ... other config
resolve: {
alias: {
'xterm': require.resolve('xterm'),
'xterm-addon-fit': require.resolve('xterm-addon-fit'),
'xterm-addon-web-links': require.resolve('xterm-addon-web-links'),
'xterm-addon-canvas': require.resolve('xterm-addon-canvas')
}
}
};
```
### Vite Configuration
```typescript
// vite.config.ts
import { defineConfig } from 'vite';
export default defineConfig({
// ... other config
optimizeDeps: {
include: ['xterm', 'xterm-addon-fit', 'xterm-addon-web-links', 'xterm-addon-canvas']
}
});
```
## 🎯 Use Cases
### 1. ChromeOS Development Environment
Perfect for ChromeOS users who need terminal access but don't have Linux container enabled:
```typescript
// Works in browser, no Linux container needed
const terminal = await createClayTerminal({
container: document.getElementById('terminal')
});
// For real system access, start bridge server
// Terminal will auto-connect when bridge is available
```
### 2. Web-based IDE
Integrate terminal into your code editor:
```typescript
// In your IDE component
const terminal = await createClayTerminal({
container: editorRef.current,
bridgeUrl: 'ws://localhost:8765/ws',
onOutput: (data) => {
// Sync output with editor
}
});
```
### 3. Educational Platform
Teach terminal commands interactively:
```typescript
const terminal = await createClayTerminal({
container: document.getElementById('terminal'),
showWelcome: true
});
// Pre-populate with tutorial commands
await terminal.executeCommand('echo "Welcome to Terminal Basics!"');
```
### 4. Documentation Site
Interactive terminal examples:
```typescript
// In your docs site
const terminal = await createClayTerminal({
container: document.getElementById('terminal-example')
});
// Show example commands
await terminal.executeCommand('git clone https://github.com/user/repo.git');
```
## 🔐 Security Considerations
- **Bridge Server**: Only connect to trusted bridge servers (localhost by default)
- **Command Execution**: Be careful with user input - validate commands before execution
- **CORS**: Ensure proper CORS configuration if using remote bridge servers
## 📚 Additional Resources
- [Full API Documentation](./README-PACKAGE.md)
- [Bridge Server Setup](../bridge/README.md)
- [Web App Usage](../README.md)
## 💬 Support
For integration help:
- Check [examples](./README-PACKAGE.md#examples)
- Open an issue on GitHub
- Read the [full documentation](./README-PACKAGE.md)