Add documentation site and Homebrew installation
- Add Fumadocs-based docs site (docs-site/) - Document all features: tabs, notifications, splits, socket API, CLI - Add Claude Code hooks guide with cmuxterm detection - Update README with native macOS emphasis and brew install - Add homebrew-cmuxterm to .gitignore (has its own repo)
This commit is contained in:
parent
70e00b5b00
commit
f36525f5f1
31 changed files with 8262 additions and 2 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -16,6 +16,7 @@ xcuserdata/
|
|||
|
||||
# GhosttyKit binary (rebuild from /tmp/ghostty with zig build)
|
||||
GhosttyKit.xcframework/
|
||||
GhosttyKit.xcframework.bak-*/
|
||||
|
||||
# Release artifacts
|
||||
GhosttyTabs-*.zip
|
||||
|
|
@ -25,3 +26,4 @@ __pycache__/
|
|||
*.pyc
|
||||
*.pyo
|
||||
.pytest_cache/
|
||||
homebrew-cmuxterm/
|
||||
|
|
|
|||
19
README.md
19
README.md
|
|
@ -1,5 +1,5 @@
|
|||
<h1 align="center">cmuxterm</h1>
|
||||
<p align="center">A Ghostty-based terminal with vertical tabs and a notification panel for macOS</p>
|
||||
<p align="center">A lightweight native macOS terminal with vertical tabs and notifications for AI coding agents</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/manaflow-ai/cmuxterm/releases/latest/download/cmuxterm-macos.dmg">
|
||||
|
|
@ -9,10 +9,25 @@
|
|||
|
||||
## Features
|
||||
|
||||
- **Native macOS app** — Built with Swift and AppKit, not Electron. Fast startup, low memory.
|
||||
- **Vertical tabs** — See all your terminals at a glance in a sidebar
|
||||
- **Notification panel** — Tabs flash when AI agents (Claude Code, Codex) need your attention
|
||||
- **Built on libghostty** — Native macOS performance with Ghostty's GPU-accelerated rendering
|
||||
- **Lightweight** — Small binary, minimal resource footprint. No bundled browser engine.
|
||||
- **GPU-accelerated** — Powered by libghostty for smooth rendering
|
||||
|
||||
## Install
|
||||
|
||||
**Homebrew:**
|
||||
|
||||
```bash
|
||||
brew tap manaflow-ai/cmuxterm
|
||||
brew install --cask cmuxterm
|
||||
```
|
||||
|
||||
Or [download the DMG](https://github.com/manaflow-ai/cmuxterm/releases/latest/download/cmuxterm-macos.dmg) directly.
|
||||
|
||||
## Why cmuxterm?
|
||||
|
||||
Running multiple AI coding agents? cmuxterm helps you manage them. Instead of losing track of which terminal needs input, the notification panel shows you exactly where to look.
|
||||
|
||||
A native macOS app means it launches instantly, uses minimal RAM, and feels right at home on your Mac.
|
||||
|
|
|
|||
35
docs-site/.gitignore
vendored
Normal file
35
docs-site/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
# dependencies
|
||||
node_modules
|
||||
.pnpm-store
|
||||
|
||||
# next.js
|
||||
.next/
|
||||
out/
|
||||
|
||||
# production
|
||||
build
|
||||
dist
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# local env files
|
||||
.env*.local
|
||||
.env
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
next-env.d.ts
|
||||
|
||||
# fumadocs
|
||||
.source/
|
||||
58
docs-site/README.md
Normal file
58
docs-site/README.md
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
# cmuxterm Documentation
|
||||
|
||||
Documentation website for [cmuxterm](https://github.com/manaflow-ai/cmuxterm), built with [Fumadocs](https://fumadocs.vercel.app) and Next.js.
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
npm install
|
||||
|
||||
# Start dev server
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) to view the docs.
|
||||
|
||||
## Deployment
|
||||
|
||||
This site is deployed to Vercel. Push to main to trigger a deployment.
|
||||
|
||||
### Manual Deploy
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
npx vercel --prod
|
||||
```
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
docs-site/
|
||||
├── app/ # Next.js app router
|
||||
│ ├── docs/ # Documentation pages
|
||||
│ └── page.tsx # Landing page
|
||||
├── content/
|
||||
│ └── docs/ # MDX documentation files
|
||||
└── lib/
|
||||
└── source.ts # Fumadocs source configuration
|
||||
```
|
||||
|
||||
## Adding Documentation
|
||||
|
||||
1. Create a new `.mdx` file in `content/docs/`
|
||||
2. Add frontmatter with title and description
|
||||
3. Add the page to `content/docs/meta.json`
|
||||
|
||||
Example:
|
||||
|
||||
```mdx
|
||||
---
|
||||
title: My Page
|
||||
description: Description of my page
|
||||
---
|
||||
|
||||
# My Page
|
||||
|
||||
Content here...
|
||||
```
|
||||
46
docs-site/app/(docs)/[[...slug]]/page.tsx
Normal file
46
docs-site/app/(docs)/[[...slug]]/page.tsx
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
import { source } from '@/lib/source';
|
||||
import {
|
||||
DocsPage,
|
||||
DocsBody,
|
||||
DocsDescription,
|
||||
DocsTitle,
|
||||
} from 'fumadocs-ui/page';
|
||||
import { notFound } from 'next/navigation';
|
||||
import defaultMdxComponents from 'fumadocs-ui/mdx';
|
||||
|
||||
export default async function Page(props: {
|
||||
params: Promise<{ slug?: string[] }>;
|
||||
}) {
|
||||
const params = await props.params;
|
||||
const page = source.getPage(params.slug);
|
||||
if (!page) notFound();
|
||||
|
||||
const MDX = page.data.body;
|
||||
|
||||
return (
|
||||
<DocsPage toc={page.data.toc} full={page.data.full}>
|
||||
<DocsTitle>{page.data.title}</DocsTitle>
|
||||
<DocsDescription>{page.data.description}</DocsDescription>
|
||||
<DocsBody>
|
||||
<MDX components={{ ...defaultMdxComponents }} />
|
||||
</DocsBody>
|
||||
</DocsPage>
|
||||
);
|
||||
}
|
||||
|
||||
export async function generateStaticParams() {
|
||||
return source.generateParams();
|
||||
}
|
||||
|
||||
export async function generateMetadata(props: {
|
||||
params: Promise<{ slug?: string[] }>;
|
||||
}) {
|
||||
const params = await props.params;
|
||||
const page = source.getPage(params.slug);
|
||||
if (!page) notFound();
|
||||
|
||||
return {
|
||||
title: page.data.title,
|
||||
description: page.data.description,
|
||||
};
|
||||
}
|
||||
20
docs-site/app/(docs)/layout.tsx
Normal file
20
docs-site/app/(docs)/layout.tsx
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
|
||||
import type { ReactNode } from 'react';
|
||||
import { source } from '@/lib/source';
|
||||
|
||||
export default function Layout({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<DocsLayout
|
||||
tree={source.pageTree}
|
||||
nav={{
|
||||
title: 'cmuxterm',
|
||||
url: '/',
|
||||
}}
|
||||
sidebar={{
|
||||
defaultOpenLevel: 1,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</DocsLayout>
|
||||
);
|
||||
}
|
||||
11
docs-site/app/global.css
Normal file
11
docs-site/app/global.css
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
:root {
|
||||
--fd-background-card: theme(colors.zinc.50);
|
||||
}
|
||||
|
||||
.dark {
|
||||
--fd-background-card: theme(colors.zinc.900);
|
||||
}
|
||||
23
docs-site/app/layout.tsx
Normal file
23
docs-site/app/layout.tsx
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import './global.css';
|
||||
import { RootProvider } from 'fumadocs-ui/provider';
|
||||
import { Inter } from 'next/font/google';
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
const inter = Inter({
|
||||
subsets: ['latin'],
|
||||
});
|
||||
|
||||
export const metadata = {
|
||||
title: 'cmuxterm Documentation',
|
||||
description: 'Documentation for cmuxterm - A Ghostty-based terminal for AI agents',
|
||||
};
|
||||
|
||||
export default function Layout({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<html lang="en" className={inter.className} suppressHydrationWarning>
|
||||
<body className="flex flex-col min-h-screen">
|
||||
<RootProvider>{children}</RootProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
266
docs-site/content/docs/claude-code-hooks.mdx
Normal file
266
docs-site/content/docs/claude-code-hooks.mdx
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
---
|
||||
title: Claude Code Hooks
|
||||
description: Set up notifications for Claude Code using cmuxterm hooks
|
||||
---
|
||||
|
||||
# Claude Code Hooks
|
||||
|
||||
cmuxterm integrates with [Claude Code](https://docs.anthropic.com/en/docs/claude-code) via hooks to notify you when tasks complete or when Claude needs attention.
|
||||
|
||||
## Detecting cmuxterm
|
||||
|
||||
Before sending notifications, you should detect if you're running inside cmuxterm to avoid conflicts with other terminals.
|
||||
|
||||
### Detection Methods
|
||||
|
||||
**1. Check for the socket:**
|
||||
|
||||
```bash
|
||||
[ -S /tmp/cmuxterm.sock ] && echo "In cmuxterm"
|
||||
```
|
||||
|
||||
**2. Check for the CLI:**
|
||||
|
||||
```bash
|
||||
command -v cmuxterm &>/dev/null && echo "cmuxterm available"
|
||||
```
|
||||
|
||||
**3. Check the TERM_PROGRAM environment variable:**
|
||||
|
||||
```bash
|
||||
[ "$TERM_PROGRAM" = "ghostty" ] && [ -S /tmp/cmuxterm.sock ] && echo "In cmuxterm"
|
||||
```
|
||||
|
||||
<Callout type="info">
|
||||
cmuxterm sets `TERM_PROGRAM=ghostty` since it's built on Ghostty. Use the socket check to distinguish from regular Ghostty.
|
||||
</Callout>
|
||||
|
||||
## Setting Up Hooks
|
||||
|
||||
Claude Code supports hooks that run on specific events. Add these to your `~/.claude/settings.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"PostToolUse": [
|
||||
{
|
||||
"matcher": "Task",
|
||||
"hooks": [
|
||||
"/path/to/cmuxterm-notify.sh"
|
||||
]
|
||||
}
|
||||
],
|
||||
"Stop": [
|
||||
"/path/to/cmuxterm-notify.sh"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Notification Hook Script
|
||||
|
||||
Create a script that checks for cmuxterm and sends notifications:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# ~/.claude/hooks/cmuxterm-notify.sh
|
||||
|
||||
# Only proceed if we're in cmuxterm
|
||||
if [ ! -S /tmp/cmuxterm.sock ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Parse the hook event from stdin (Claude Code passes JSON)
|
||||
EVENT=$(cat)
|
||||
|
||||
# Extract event type and details
|
||||
EVENT_TYPE=$(echo "$EVENT" | jq -r '.event // "unknown"')
|
||||
TOOL_NAME=$(echo "$EVENT" | jq -r '.tool_name // ""')
|
||||
SESSION=$(echo "$EVENT" | jq -r '.session_id // ""' | cut -c1-8)
|
||||
|
||||
case "$EVENT_TYPE" in
|
||||
"Stop")
|
||||
cmuxterm notify \
|
||||
--title "Claude Code" \
|
||||
--subtitle "Task Complete" \
|
||||
--body "Session $SESSION finished"
|
||||
;;
|
||||
"PostToolUse")
|
||||
if [ "$TOOL_NAME" = "Task" ]; then
|
||||
cmuxterm notify \
|
||||
--title "Claude Code" \
|
||||
--subtitle "Agent Finished" \
|
||||
--body "Task agent completed in session $SESSION"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
```
|
||||
|
||||
Make it executable:
|
||||
|
||||
```bash
|
||||
chmod +x ~/.claude/hooks/cmuxterm-notify.sh
|
||||
```
|
||||
|
||||
## Example Configurations
|
||||
|
||||
### Notify on All Completions
|
||||
|
||||
Get notified whenever Claude Code finishes a task:
|
||||
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"Stop": [
|
||||
"~/.claude/hooks/cmuxterm-notify.sh"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Notify on Long-Running Tasks
|
||||
|
||||
Only notify for Task tool completions (agent subprocesses):
|
||||
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"PostToolUse": [
|
||||
{
|
||||
"matcher": "Task",
|
||||
"hooks": ["~/.claude/hooks/cmuxterm-notify.sh"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Notify on Errors
|
||||
|
||||
Add error notifications:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# cmuxterm-notify.sh with error handling
|
||||
|
||||
if [ ! -S /tmp/cmuxterm.sock ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
EVENT=$(cat)
|
||||
EVENT_TYPE=$(echo "$EVENT" | jq -r '.event // "unknown"')
|
||||
ERROR=$(echo "$EVENT" | jq -r '.error // ""')
|
||||
|
||||
if [ -n "$ERROR" ] && [ "$ERROR" != "null" ]; then
|
||||
cmuxterm notify \
|
||||
--title "Claude Code Error" \
|
||||
--body "$ERROR"
|
||||
elif [ "$EVENT_TYPE" = "Stop" ]; then
|
||||
cmuxterm notify \
|
||||
--title "Claude Code" \
|
||||
--body "Task complete"
|
||||
fi
|
||||
```
|
||||
|
||||
## Advanced: Conditional Notifications
|
||||
|
||||
Only notify if the terminal is not focused:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# cmuxterm-notify.sh with focus detection
|
||||
|
||||
if [ ! -S /tmp/cmuxterm.sock ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# cmuxterm automatically suppresses notifications for focused tabs,
|
||||
# so we can always send - it will handle suppression for us
|
||||
|
||||
EVENT=$(cat)
|
||||
EVENT_TYPE=$(echo "$EVENT" | jq -r '.event // "unknown"')
|
||||
|
||||
if [ "$EVENT_TYPE" = "Stop" ]; then
|
||||
cmuxterm notify \
|
||||
--title "Claude Code" \
|
||||
--subtitle "Ready" \
|
||||
--body "Waiting for your input"
|
||||
fi
|
||||
```
|
||||
|
||||
## Using OSC Sequences Directly
|
||||
|
||||
If you prefer not to use the CLI, you can emit OSC sequences directly:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Direct OSC notification (no CLI needed)
|
||||
|
||||
if [ ! -S /tmp/cmuxterm.sock ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
EVENT=$(cat)
|
||||
EVENT_TYPE=$(echo "$EVENT" | jq -r '.event // "unknown"')
|
||||
|
||||
if [ "$EVENT_TYPE" = "Stop" ]; then
|
||||
# OSC 777 notification
|
||||
printf '\e]777;notify;Claude Code;Task complete\a'
|
||||
fi
|
||||
```
|
||||
|
||||
## Full Example Setup
|
||||
|
||||
1. Create the hooks directory:
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.claude/hooks
|
||||
```
|
||||
|
||||
2. Create the notification script:
|
||||
|
||||
```bash
|
||||
cat > ~/.claude/hooks/cmuxterm-notify.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
# cmuxterm notification hook for Claude Code
|
||||
|
||||
# Skip if not in cmuxterm
|
||||
[ -S /tmp/cmuxterm.sock ] || exit 0
|
||||
|
||||
EVENT=$(cat)
|
||||
EVENT_TYPE=$(echo "$EVENT" | jq -r '.event // "unknown"')
|
||||
TOOL=$(echo "$EVENT" | jq -r '.tool_name // ""')
|
||||
|
||||
case "$EVENT_TYPE" in
|
||||
"Stop")
|
||||
cmuxterm notify --title "Claude Code" --body "Session complete"
|
||||
;;
|
||||
"PostToolUse")
|
||||
[ "$TOOL" = "Task" ] && cmuxterm notify --title "Claude Code" --body "Agent finished"
|
||||
;;
|
||||
esac
|
||||
EOF
|
||||
chmod +x ~/.claude/hooks/cmuxterm-notify.sh
|
||||
```
|
||||
|
||||
3. Configure Claude Code:
|
||||
|
||||
```bash
|
||||
cat > ~/.claude/settings.json << 'EOF'
|
||||
{
|
||||
"hooks": {
|
||||
"Stop": ["~/.claude/hooks/cmuxterm-notify.sh"],
|
||||
"PostToolUse": [
|
||||
{
|
||||
"matcher": "Task",
|
||||
"hooks": ["~/.claude/hooks/cmuxterm-notify.sh"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
4. Restart Claude Code to apply the hooks.
|
||||
|
||||
Now you'll receive desktop notifications in cmuxterm whenever Claude Code finishes a task or needs attention.
|
||||
222
docs-site/content/docs/cli.mdx
Normal file
222
docs-site/content/docs/cli.mdx
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
---
|
||||
title: CLI Reference
|
||||
description: Command-line interface for cmuxterm
|
||||
---
|
||||
|
||||
# CLI Reference
|
||||
|
||||
cmuxterm includes a command-line tool for controlling the terminal from scripts and other tools.
|
||||
|
||||
## Installation
|
||||
|
||||
The CLI is bundled with cmuxterm. Inside cmuxterm terminals, it's available automatically. For external use:
|
||||
|
||||
```bash
|
||||
# Create symlink to CLI
|
||||
sudo ln -sf "/Applications/cmuxterm.app/Contents/MacOS/cmuxterm" /usr/local/bin/cmuxterm
|
||||
```
|
||||
|
||||
## Global Options
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--socket PATH` | Use a custom socket path |
|
||||
| `--json` | Output in JSON format |
|
||||
| `--tab ID` | Target a specific tab |
|
||||
| `--panel ID` | Target a specific panel |
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| `CMUX_SOCKET_PATH` | Default socket path |
|
||||
| `CMUX_TAB_ID` | Default tab ID |
|
||||
| `CMUX_PANEL_ID` | Default panel ID |
|
||||
|
||||
## Commands
|
||||
|
||||
### Tab Management
|
||||
|
||||
#### list-tabs
|
||||
|
||||
List all open tabs.
|
||||
|
||||
```bash
|
||||
cmuxterm list-tabs
|
||||
cmuxterm list-tabs --json
|
||||
```
|
||||
|
||||
#### new-tab
|
||||
|
||||
Create a new tab.
|
||||
|
||||
```bash
|
||||
cmuxterm new-tab
|
||||
```
|
||||
|
||||
#### select-tab
|
||||
|
||||
Switch to a specific tab.
|
||||
|
||||
```bash
|
||||
cmuxterm select-tab --tab <tab-id>
|
||||
```
|
||||
|
||||
#### current-tab
|
||||
|
||||
Get the current tab info.
|
||||
|
||||
```bash
|
||||
cmuxterm current-tab
|
||||
cmuxterm current-tab --json
|
||||
```
|
||||
|
||||
#### close-tab
|
||||
|
||||
Close a tab.
|
||||
|
||||
```bash
|
||||
cmuxterm close-tab --tab <tab-id>
|
||||
```
|
||||
|
||||
### Split Management
|
||||
|
||||
#### new-split
|
||||
|
||||
Create a new split pane.
|
||||
|
||||
```bash
|
||||
cmuxterm new-split right
|
||||
cmuxterm new-split down
|
||||
cmuxterm new-split left
|
||||
cmuxterm new-split up
|
||||
```
|
||||
|
||||
#### list-panels
|
||||
|
||||
List panels in the current tab.
|
||||
|
||||
```bash
|
||||
cmuxterm list-panels
|
||||
cmuxterm list-panels --json
|
||||
```
|
||||
|
||||
#### focus-panel
|
||||
|
||||
Focus a specific panel.
|
||||
|
||||
```bash
|
||||
cmuxterm focus-panel --panel <panel-id>
|
||||
```
|
||||
|
||||
### Input Commands
|
||||
|
||||
#### send
|
||||
|
||||
Send text to the terminal.
|
||||
|
||||
```bash
|
||||
cmuxterm send "echo hello"
|
||||
cmuxterm send "ls -la\n" # Include newline to execute
|
||||
```
|
||||
|
||||
#### send-key
|
||||
|
||||
Send a key press.
|
||||
|
||||
```bash
|
||||
cmuxterm send-key enter
|
||||
cmuxterm send-key tab
|
||||
cmuxterm send-key escape
|
||||
```
|
||||
|
||||
#### send-panel
|
||||
|
||||
Send text to a specific panel.
|
||||
|
||||
```bash
|
||||
cmuxterm send-panel --panel <panel-id> "command"
|
||||
```
|
||||
|
||||
#### send-key-panel
|
||||
|
||||
Send a key press to a specific panel.
|
||||
|
||||
```bash
|
||||
cmuxterm send-key-panel --panel <panel-id> enter
|
||||
```
|
||||
|
||||
### Notifications
|
||||
|
||||
#### notify
|
||||
|
||||
Send a notification.
|
||||
|
||||
```bash
|
||||
cmuxterm notify --title "Title" --body "Message body"
|
||||
cmuxterm notify --title "Title" --subtitle "Subtitle" --body "Body"
|
||||
```
|
||||
|
||||
#### list-notifications
|
||||
|
||||
List all notifications.
|
||||
|
||||
```bash
|
||||
cmuxterm list-notifications
|
||||
cmuxterm list-notifications --json
|
||||
```
|
||||
|
||||
#### clear-notifications
|
||||
|
||||
Clear all notifications.
|
||||
|
||||
```bash
|
||||
cmuxterm clear-notifications
|
||||
```
|
||||
|
||||
### Utility
|
||||
|
||||
#### ping
|
||||
|
||||
Check if cmuxterm is running and responsive.
|
||||
|
||||
```bash
|
||||
cmuxterm ping
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Build Script with Notification
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
npm run build
|
||||
if [ $? -eq 0 ]; then
|
||||
cmuxterm notify --title "✓ Build Success" --body "Ready to deploy"
|
||||
else
|
||||
cmuxterm notify --title "✗ Build Failed" --body "Check the logs"
|
||||
fi
|
||||
```
|
||||
|
||||
### Create Tab and Run Command
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Create a new tab
|
||||
result=$(cmuxterm new-tab --json)
|
||||
tab_id=$(echo "$result" | jq -r '.id')
|
||||
|
||||
# Select the new tab
|
||||
cmuxterm select-tab --tab "$tab_id"
|
||||
|
||||
# Send a command
|
||||
cmuxterm send "npm run dev\n"
|
||||
```
|
||||
|
||||
### Monitor Multiple Tabs
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# List all tabs and their directories
|
||||
cmuxterm list-tabs --json | jq -r '.tabs[] | "\(.title): \(.directory)"'
|
||||
```
|
||||
121
docs-site/content/docs/configuration.mdx
Normal file
121
docs-site/content/docs/configuration.mdx
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
---
|
||||
title: Configuration
|
||||
description: Configure cmuxterm appearance and behavior
|
||||
---
|
||||
|
||||
# Configuration
|
||||
|
||||
cmuxterm reads configuration from Ghostty config files, giving you familiar options if you're coming from Ghostty.
|
||||
|
||||
## Config File Locations
|
||||
|
||||
cmuxterm looks for configuration in these locations (in order):
|
||||
|
||||
1. `~/.config/ghostty/config`
|
||||
2. `~/Library/Application Support/com.mitchellh.ghostty/config`
|
||||
|
||||
Create the config file if it doesn't exist:
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.config/ghostty
|
||||
touch ~/.config/ghostty/config
|
||||
```
|
||||
|
||||
## Appearance Options
|
||||
|
||||
### Font
|
||||
|
||||
```ini
|
||||
font-family = JetBrains Mono
|
||||
font-size = 14
|
||||
```
|
||||
|
||||
### Colors
|
||||
|
||||
```ini
|
||||
# Theme (or use individual colors below)
|
||||
theme = Dracula
|
||||
|
||||
# Custom colors
|
||||
background = #1e1e2e
|
||||
foreground = #cdd6f4
|
||||
cursor-color = #f5e0dc
|
||||
cursor-text = #1e1e2e
|
||||
selection-background = #585b70
|
||||
selection-foreground = #cdd6f4
|
||||
```
|
||||
|
||||
### Split Panes
|
||||
|
||||
```ini
|
||||
# Opacity for unfocused splits (0.0 to 1.0)
|
||||
unfocused-split-opacity = 0.7
|
||||
|
||||
# Fill color for unfocused splits
|
||||
unfocused-split-fill = #1e1e2e
|
||||
|
||||
# Divider color between splits
|
||||
split-divider-color = #45475a
|
||||
```
|
||||
|
||||
## Behavior Options
|
||||
|
||||
### Scrollback
|
||||
|
||||
```ini
|
||||
# Number of lines to keep in scrollback buffer
|
||||
scrollback-limit = 10000
|
||||
```
|
||||
|
||||
### Working Directory
|
||||
|
||||
```ini
|
||||
# Default directory for new terminals
|
||||
working-directory = ~/Projects
|
||||
```
|
||||
|
||||
## App Settings
|
||||
|
||||
In-app settings are available via **cmuxterm → Settings** (⌘,):
|
||||
|
||||
### Theme Mode
|
||||
|
||||
Choose between:
|
||||
- **System** - Follow macOS appearance
|
||||
- **Light** - Always light mode
|
||||
- **Dark** - Always dark mode
|
||||
|
||||
### Automation Mode
|
||||
|
||||
Control socket access level:
|
||||
|
||||
- **Off** - No socket control (most secure)
|
||||
- **Notifications only** - Only allow notification commands
|
||||
- **Full control** - Allow all socket commands
|
||||
|
||||
<Callout type="warn">
|
||||
On shared machines, consider using "Notifications only" mode to prevent other processes from controlling your terminals.
|
||||
</Callout>
|
||||
|
||||
## Example Config
|
||||
|
||||
Here's a complete example configuration:
|
||||
|
||||
```ini
|
||||
# Font
|
||||
font-family = SF Mono
|
||||
font-size = 13
|
||||
|
||||
# Colors
|
||||
theme = One Dark
|
||||
|
||||
# Scrollback
|
||||
scrollback-limit = 50000
|
||||
|
||||
# Splits
|
||||
unfocused-split-opacity = 0.85
|
||||
split-divider-color = #3e4451
|
||||
|
||||
# Working directory
|
||||
working-directory = ~/code
|
||||
```
|
||||
179
docs-site/content/docs/environment-variables.mdx
Normal file
179
docs-site/content/docs/environment-variables.mdx
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
---
|
||||
title: Environment Variables
|
||||
description: Environment variables for configuring cmuxterm
|
||||
---
|
||||
|
||||
# Environment Variables
|
||||
|
||||
cmuxterm uses environment variables for configuration and integration.
|
||||
|
||||
## Socket Control
|
||||
|
||||
### CMUX_SOCKET_PATH
|
||||
|
||||
Override the default socket path.
|
||||
|
||||
```bash
|
||||
export CMUX_SOCKET_PATH=/custom/path/cmuxterm.sock
|
||||
```
|
||||
|
||||
Default: `/tmp/cmuxterm.sock` (release) or `/tmp/cmuxterm-debug.sock` (debug)
|
||||
|
||||
### CMUX_SOCKET_ENABLE
|
||||
|
||||
Enable or disable the control socket.
|
||||
|
||||
```bash
|
||||
export CMUX_SOCKET_ENABLE=1 # Enable
|
||||
export CMUX_SOCKET_ENABLE=0 # Disable
|
||||
```
|
||||
|
||||
Values: `1`, `0`, `true`, `false`, `yes`, `no`
|
||||
|
||||
### CMUX_SOCKET_MODE
|
||||
|
||||
Override the socket access mode.
|
||||
|
||||
```bash
|
||||
export CMUX_SOCKET_MODE=notifications # Notifications only
|
||||
export CMUX_SOCKET_MODE=full # Full control
|
||||
export CMUX_SOCKET_MODE=off # Disabled
|
||||
```
|
||||
|
||||
## CLI Context
|
||||
|
||||
### CMUX_TAB_ID
|
||||
|
||||
Default tab ID for CLI commands.
|
||||
|
||||
```bash
|
||||
export CMUX_TAB_ID=abc123
|
||||
cmuxterm send "hello" # Sends to tab abc123
|
||||
```
|
||||
|
||||
cmuxterm automatically sets this in each terminal session.
|
||||
|
||||
### CMUX_PANEL_ID
|
||||
|
||||
Default panel ID for CLI commands.
|
||||
|
||||
```bash
|
||||
export CMUX_PANEL_ID=xyz789
|
||||
cmuxterm send-panel "hello" # Sends to panel xyz789
|
||||
```
|
||||
|
||||
cmuxterm automatically sets this for each split pane.
|
||||
|
||||
## Terminal Environment
|
||||
|
||||
cmuxterm sets these variables in terminal sessions:
|
||||
|
||||
### TERM
|
||||
|
||||
Terminal type for compatibility.
|
||||
|
||||
```bash
|
||||
TERM=xterm-ghostty
|
||||
```
|
||||
|
||||
### TERM_PROGRAM
|
||||
|
||||
Identifies the terminal application.
|
||||
|
||||
```bash
|
||||
TERM_PROGRAM=ghostty
|
||||
```
|
||||
|
||||
<Callout type="info">
|
||||
cmuxterm sets this to `ghostty` since it's built on Ghostty. Use the socket check to distinguish from regular Ghostty.
|
||||
</Callout>
|
||||
|
||||
### GHOSTTY_RESOURCES_DIR
|
||||
|
||||
Path to Ghostty resources.
|
||||
|
||||
```bash
|
||||
GHOSTTY_RESOURCES_DIR=/path/to/resources
|
||||
```
|
||||
|
||||
## Testing & Debug
|
||||
|
||||
### CMUX_UI_TEST_SHOW_SETTINGS
|
||||
|
||||
Show the settings window on app launch (for UI testing).
|
||||
|
||||
```bash
|
||||
export CMUX_UI_TEST_SHOW_SETTINGS=1
|
||||
```
|
||||
|
||||
### CMUX_UI_TEST_TRIGGER_UPDATE_CHECK
|
||||
|
||||
Trigger an update check on app launch (for testing).
|
||||
|
||||
```bash
|
||||
export CMUX_UI_TEST_TRIGGER_UPDATE_CHECK=1
|
||||
```
|
||||
|
||||
### CMUX_COMMIT
|
||||
|
||||
Override the commit hash displayed in the About window.
|
||||
|
||||
```bash
|
||||
export CMUX_COMMIT=abc1234
|
||||
```
|
||||
|
||||
## Detection Script
|
||||
|
||||
Check if running inside cmuxterm:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
is_cmuxterm() {
|
||||
# Check for cmuxterm socket
|
||||
if [ -S "${CMUX_SOCKET_PATH:-/tmp/cmuxterm.sock}" ]; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
if is_cmuxterm; then
|
||||
echo "Running in cmuxterm"
|
||||
echo "Tab ID: ${CMUX_TAB_ID:-unknown}"
|
||||
echo "Panel ID: ${CMUX_PANEL_ID:-unknown}"
|
||||
else
|
||||
echo "Not in cmuxterm"
|
||||
fi
|
||||
```
|
||||
|
||||
## Shell Configuration
|
||||
|
||||
Add to your `~/.bashrc` or `~/.zshrc`:
|
||||
|
||||
```bash
|
||||
# cmuxterm integration
|
||||
if [ -S "${CMUX_SOCKET_PATH:-/tmp/cmuxterm.sock}" ]; then
|
||||
# We're in cmuxterm
|
||||
|
||||
# Function to notify on long commands
|
||||
notify_done() {
|
||||
"$@"
|
||||
local exit_code=$?
|
||||
cmuxterm notify --title "Command Complete" --body "$1"
|
||||
return $exit_code
|
||||
}
|
||||
|
||||
# Alias for builds
|
||||
alias build='notify_done npm run build'
|
||||
fi
|
||||
```
|
||||
|
||||
## Precedence
|
||||
|
||||
Environment variables override app settings:
|
||||
|
||||
1. Environment variable (if set)
|
||||
2. App settings (Settings window)
|
||||
3. Default value
|
||||
|
||||
For example, if `CMUX_SOCKET_MODE=full` is set, it overrides the app's Automation Mode setting.
|
||||
57
docs-site/content/docs/index.mdx
Normal file
57
docs-site/content/docs/index.mdx
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
---
|
||||
title: Introduction
|
||||
description: cmuxterm - A lightweight native macOS terminal with vertical tabs and notifications for AI coding agents
|
||||
---
|
||||
|
||||
# cmuxterm
|
||||
|
||||
cmuxterm is a lightweight, native macOS terminal built on Ghostty for managing multiple AI coding agents. It features vertical tabs, a notification panel, and a socket-based control API.
|
||||
|
||||
## Why cmuxterm?
|
||||
|
||||
- **Native macOS app** - Built with Swift and AppKit, not Electron. Fast startup, low memory usage, and native look and feel.
|
||||
- **Lightweight** - Small binary, minimal resource footprint. No bundled browser engine.
|
||||
- **GPU-accelerated** - Powered by libghostty for buttery smooth rendering.
|
||||
|
||||
When running AI coding agents like Claude Code, Codex, or similar tools, you need to:
|
||||
|
||||
- **Manage multiple terminal sessions** - Each agent runs in its own terminal
|
||||
- **Know when agents need attention** - Agents waiting for input should notify you
|
||||
- **Automate terminal control** - Programmatically create tabs, send input, and more
|
||||
|
||||
cmuxterm solves these with:
|
||||
|
||||
- **Vertical sidebar tabs** - All terminals visible at a glance
|
||||
- **OSC 99/777 notifications** - Desktop alerts when agents need you
|
||||
- **Unix socket API** - Full programmatic control for automation
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
brew tap manaflow-ai/cmuxterm
|
||||
brew install --cask cmuxterm
|
||||
```
|
||||
|
||||
Or [download the DMG](https://github.com/manaflow-ai/cmuxterm/releases/latest/download/cmuxterm-macos.dmg) directly.
|
||||
|
||||
## Key Features
|
||||
|
||||
<Cards>
|
||||
<Card title="Vertical Tabs" href="/tabs">
|
||||
All terminals in a resizable sidebar with keyboard navigation
|
||||
</Card>
|
||||
<Card title="Notifications" href="/notifications">
|
||||
Desktop alerts via OSC 99/777 sequences when agents need attention
|
||||
</Card>
|
||||
<Card title="Socket API" href="/socket-api">
|
||||
Unix socket for programmatic control - create tabs, send input, and more
|
||||
</Card>
|
||||
<Card title="Claude Code Hooks" href="/claude-code-hooks">
|
||||
Send notifications from Claude Code when tasks complete
|
||||
</Card>
|
||||
</Cards>
|
||||
|
||||
## Requirements
|
||||
|
||||
- macOS 13.0 or later
|
||||
- Apple Silicon or Intel Mac
|
||||
70
docs-site/content/docs/installation.mdx
Normal file
70
docs-site/content/docs/installation.mdx
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
---
|
||||
title: Installation
|
||||
description: How to install cmuxterm on macOS
|
||||
---
|
||||
|
||||
# Installation
|
||||
|
||||
## Homebrew (Recommended)
|
||||
|
||||
Install via Homebrew:
|
||||
|
||||
```bash
|
||||
brew tap manaflow-ai/cmuxterm
|
||||
brew install --cask cmuxterm
|
||||
```
|
||||
|
||||
To update later:
|
||||
|
||||
```bash
|
||||
brew upgrade --cask cmuxterm
|
||||
```
|
||||
|
||||
## Manual Download
|
||||
|
||||
Download the latest release from GitHub:
|
||||
|
||||
<a href="https://github.com/manaflow-ai/cmuxterm/releases/latest/download/cmuxterm-macos.dmg">
|
||||
<img src="/macos-badge.png" alt="Download cmuxterm for macOS" width="180" />
|
||||
</a>
|
||||
|
||||
Then:
|
||||
|
||||
1. Open the downloaded `.dmg` file
|
||||
2. Drag **cmuxterm** to your **Applications** folder
|
||||
3. Open cmuxterm from Applications
|
||||
|
||||
<Callout type="info">
|
||||
On first launch, macOS may ask you to confirm opening an app from an identified developer. Click **Open** to proceed.
|
||||
</Callout>
|
||||
|
||||
## Verify Installation
|
||||
|
||||
Open cmuxterm and you should see:
|
||||
|
||||
- A terminal window with a vertical tab sidebar on the left
|
||||
- One initial tab already open
|
||||
- The Ghostty-powered terminal ready for input
|
||||
|
||||
## CLI Tool
|
||||
|
||||
cmuxterm includes a command-line tool for automation. It's bundled inside the app and works automatically when you run commands inside cmuxterm.
|
||||
|
||||
To use the CLI from outside cmuxterm, you can create a symlink:
|
||||
|
||||
```bash
|
||||
sudo ln -sf "/Applications/cmuxterm.app/Contents/MacOS/cmuxterm" /usr/local/bin/cmuxterm
|
||||
```
|
||||
|
||||
Then you can run commands like:
|
||||
|
||||
```bash
|
||||
cmuxterm list-tabs
|
||||
cmuxterm notify --title "Build Complete" --body "Your build finished successfully"
|
||||
```
|
||||
|
||||
## Updates
|
||||
|
||||
cmuxterm checks for updates automatically using Sparkle. When an update is available, you'll see an update pill in the titlebar. Click it to install the latest version.
|
||||
|
||||
You can also check for updates manually via **cmuxterm → Check for Updates** in the menu bar.
|
||||
74
docs-site/content/docs/keyboard-shortcuts.mdx
Normal file
74
docs-site/content/docs/keyboard-shortcuts.mdx
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
---
|
||||
title: Keyboard Shortcuts
|
||||
description: Complete list of cmuxterm keyboard shortcuts
|
||||
---
|
||||
|
||||
# Keyboard Shortcuts
|
||||
|
||||
## Tab Management
|
||||
|
||||
| Shortcut | Action |
|
||||
|----------|--------|
|
||||
| **⌘T** | New tab |
|
||||
| **⌘N** | New tab |
|
||||
| **⌘W** | Close pane (or tab if single pane) |
|
||||
| **⌘⇧W** | Close tab |
|
||||
| **⌘B** | Toggle sidebar |
|
||||
|
||||
## Tab Navigation
|
||||
|
||||
| Shortcut | Action |
|
||||
|----------|--------|
|
||||
| **⌘1** - **⌘9** | Jump to tab 1-9 |
|
||||
| **⌘]** | Next tab |
|
||||
| **⌘[** | Previous tab |
|
||||
| **⌃Tab** | Next tab |
|
||||
| **⌃⇧Tab** | Previous tab |
|
||||
|
||||
## Notifications
|
||||
|
||||
| Shortcut | Action |
|
||||
|----------|--------|
|
||||
| **⌘⇧U** | Jump to latest unread notification |
|
||||
| **⌘⇧I** | Show notifications panel |
|
||||
|
||||
## Split Panes
|
||||
|
||||
| Shortcut | Action |
|
||||
|----------|--------|
|
||||
| **⌘D** | Split right |
|
||||
| **⌘⇧D** | Split down |
|
||||
| **⌘⌥←** | Focus left pane |
|
||||
| **⌘⌥→** | Focus right pane |
|
||||
| **⌘⌥↑** | Focus pane above |
|
||||
| **⌘⌥↓** | Focus pane below |
|
||||
|
||||
## Window
|
||||
|
||||
| Shortcut | Action |
|
||||
|----------|--------|
|
||||
| **⌘,** | Settings |
|
||||
| **⌘Q** | Quit |
|
||||
| **⌘M** | Minimize |
|
||||
| **⌘H** | Hide |
|
||||
|
||||
## Terminal
|
||||
|
||||
| Shortcut | Action |
|
||||
|----------|--------|
|
||||
| **⌘K** | Clear scrollback |
|
||||
| **⌘C** | Copy (when text selected) |
|
||||
| **⌘V** | Paste |
|
||||
| **⌘+** | Increase font size |
|
||||
| **⌘-** | Decrease font size |
|
||||
| **⌘0** | Reset font size |
|
||||
|
||||
## Symbol Key
|
||||
|
||||
| Symbol | Key |
|
||||
|--------|-----|
|
||||
| ⌘ | Command |
|
||||
| ⌥ | Option/Alt |
|
||||
| ⌃ | Control |
|
||||
| ⇧ | Shift |
|
||||
| ← → ↑ ↓ | Arrow keys |
|
||||
21
docs-site/content/docs/meta.json
Normal file
21
docs-site/content/docs/meta.json
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"title": "Documentation",
|
||||
"pages": [
|
||||
"index",
|
||||
"---Getting Started---",
|
||||
"installation",
|
||||
"configuration",
|
||||
"---Features---",
|
||||
"tabs",
|
||||
"notifications",
|
||||
"splits",
|
||||
"keyboard-shortcuts",
|
||||
"---Automation---",
|
||||
"socket-api",
|
||||
"cli",
|
||||
"claude-code-hooks",
|
||||
"---Reference---",
|
||||
"osc-sequences",
|
||||
"environment-variables"
|
||||
]
|
||||
}
|
||||
127
docs-site/content/docs/notifications.mdx
Normal file
127
docs-site/content/docs/notifications.mdx
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
---
|
||||
title: Notifications
|
||||
description: Desktop notifications in cmuxterm for AI agents
|
||||
---
|
||||
|
||||
# Notifications
|
||||
|
||||
cmuxterm supports desktop notifications, allowing AI agents and scripts to alert you when they need attention.
|
||||
|
||||
## How It Works
|
||||
|
||||
1. A process in the terminal sends an OSC escape sequence
|
||||
2. cmuxterm parses the notification title and body
|
||||
3. If the terminal isn't focused, a desktop notification appears
|
||||
4. The tab shows an unread badge
|
||||
|
||||
## Sending Notifications
|
||||
|
||||
### Using the CLI
|
||||
|
||||
The simplest way to send a notification:
|
||||
|
||||
```bash
|
||||
cmuxterm notify --title "Task Complete" --body "Your build finished"
|
||||
```
|
||||
|
||||
With a subtitle:
|
||||
|
||||
```bash
|
||||
cmuxterm notify --title "Claude Code" --subtitle "Waiting" --body "Agent needs input"
|
||||
```
|
||||
|
||||
### Using OSC Sequences
|
||||
|
||||
You can send notifications directly using escape sequences:
|
||||
|
||||
#### OSC 99 (Kitty Protocol)
|
||||
|
||||
```bash
|
||||
# Basic notification
|
||||
printf '\e]99;i=1;e=1;d=0:Hello World\e\\'
|
||||
|
||||
# With title and body
|
||||
printf '\e]99;i=1;e=1;d=0;p=title:My Title\e\\'
|
||||
printf '\e]99;i=1;e=1;d=0;p=body:Message body here\e\\'
|
||||
```
|
||||
|
||||
#### OSC 777 (RXVT Protocol)
|
||||
|
||||
```bash
|
||||
printf '\e]777;notify;My Title;Message body here\a'
|
||||
```
|
||||
|
||||
See [OSC Sequences](/docs/osc-sequences) for full format documentation.
|
||||
|
||||
## Notification Behavior
|
||||
|
||||
### Suppression
|
||||
|
||||
Notifications are suppressed (no desktop alert) when:
|
||||
|
||||
- The cmuxterm window is focused
|
||||
- The specific tab sending the notification is active
|
||||
- The notification panel is open
|
||||
|
||||
This prevents duplicate alerts when you're already looking at the terminal.
|
||||
|
||||
### Notification Panel
|
||||
|
||||
Press **⌘⇧I** to open the notification panel, showing all notifications:
|
||||
|
||||
- Click a notification to jump to that tab
|
||||
- Notifications are marked as read when viewed
|
||||
- Clear all with the clear button
|
||||
|
||||
### Quick Jump
|
||||
|
||||
Press **⌘⇧U** to jump directly to the tab with the most recent unread notification.
|
||||
|
||||
## Notification Lifecycle
|
||||
|
||||
1. **Received** - Notification appears in panel, desktop alert fires (if not suppressed)
|
||||
2. **Unread** - Badge shown on tab
|
||||
3. **Read** - Cleared when you view that tab
|
||||
4. **Cleared** - Removed from panel
|
||||
|
||||
## Integration Examples
|
||||
|
||||
### Notify After Long Command
|
||||
|
||||
```bash
|
||||
# Add to your shell config
|
||||
notify-after() {
|
||||
"$@"
|
||||
local exit_code=$?
|
||||
if [ $exit_code -eq 0 ]; then
|
||||
cmuxterm notify --title "✓ Command Complete" --body "$1"
|
||||
else
|
||||
cmuxterm notify --title "✗ Command Failed" --body "$1 (exit $exit_code)"
|
||||
fi
|
||||
return $exit_code
|
||||
}
|
||||
|
||||
# Usage
|
||||
notify-after npm run build
|
||||
```
|
||||
|
||||
### Notify When Build Finishes
|
||||
|
||||
```bash
|
||||
npm run build && cmuxterm notify --title "Build Success" --body "Ready to deploy"
|
||||
```
|
||||
|
||||
### Watch Script Completion
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# long-running-task.sh
|
||||
|
||||
do_work() {
|
||||
# ... your task
|
||||
sleep 10
|
||||
}
|
||||
|
||||
do_work
|
||||
cmuxterm notify --title "Task Complete" --body "long-running-task.sh finished"
|
||||
```
|
||||
204
docs-site/content/docs/osc-sequences.mdx
Normal file
204
docs-site/content/docs/osc-sequences.mdx
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
---
|
||||
title: OSC Sequences
|
||||
description: OSC escape sequence reference for cmuxterm notifications
|
||||
---
|
||||
|
||||
# OSC Sequences
|
||||
|
||||
cmuxterm supports two OSC (Operating System Command) escape sequence standards for sending notifications from terminal programs.
|
||||
|
||||
## OSC 99 (Kitty Protocol)
|
||||
|
||||
The Kitty notification protocol provides rich notification support with multiple parameters.
|
||||
|
||||
### Format
|
||||
|
||||
```
|
||||
ESC ] 99 ; <params> ; <payload> ESC \
|
||||
```
|
||||
|
||||
Or using BEL terminator:
|
||||
|
||||
```
|
||||
ESC ] 99 ; <params> ; <payload> BEL
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
Parameters are semicolon-separated key=value pairs:
|
||||
|
||||
| Parameter | Description | Values |
|
||||
|-----------|-------------|--------|
|
||||
| `i` | Notification ID | Any string |
|
||||
| `e` | Event type | `1` = new notification |
|
||||
| `d` | Done flag | `0` = more data coming, `1` = complete |
|
||||
| `p` | Payload type | `title`, `body`, `subtitle` |
|
||||
|
||||
### Payload
|
||||
|
||||
After the final semicolon, the payload contains the notification content. If `p=` is specified, the payload is interpreted as that type.
|
||||
|
||||
### Examples
|
||||
|
||||
**Simple notification:**
|
||||
|
||||
```bash
|
||||
printf '\e]99;i=1;e=1;d=0:Hello World\e\\'
|
||||
```
|
||||
|
||||
**Notification with title and body:**
|
||||
|
||||
```bash
|
||||
# Set title
|
||||
printf '\e]99;i=1;e=1;d=0;p=title:Build Complete\e\\'
|
||||
# Set body
|
||||
printf '\e]99;i=1;e=1;d=1;p=body:All tests passed\e\\'
|
||||
```
|
||||
|
||||
**With subtitle:**
|
||||
|
||||
```bash
|
||||
printf '\e]99;i=1;e=1;d=0;p=title:Claude Code\e\\'
|
||||
printf '\e]99;i=1;e=1;d=0;p=subtitle:Session abc123\e\\'
|
||||
printf '\e]99;i=1;e=1;d=1;p=body:Waiting for input\e\\'
|
||||
```
|
||||
|
||||
### Shell Function
|
||||
|
||||
```bash
|
||||
notify_osc99() {
|
||||
local title="$1"
|
||||
local body="$2"
|
||||
local id="${3:-1}"
|
||||
|
||||
printf '\e]99;i=%s;e=1;d=0;p=title:%s\e\\' "$id" "$title"
|
||||
printf '\e]99;i=%s;e=1;d=1;p=body:%s\e\\' "$id" "$body"
|
||||
}
|
||||
|
||||
# Usage
|
||||
notify_osc99 "Build Done" "Your project compiled successfully"
|
||||
```
|
||||
|
||||
## OSC 777 (RXVT Protocol)
|
||||
|
||||
The RXVT/urxvt protocol is simpler, with a fixed format for title and body.
|
||||
|
||||
### Format
|
||||
|
||||
```
|
||||
ESC ] 777 ; notify ; <title> ; <body> BEL
|
||||
```
|
||||
|
||||
Or with ST terminator:
|
||||
|
||||
```
|
||||
ESC ] 777 ; notify ; <title> ; <body> ESC \
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
**Basic notification:**
|
||||
|
||||
```bash
|
||||
printf '\e]777;notify;Hello;World\a'
|
||||
```
|
||||
|
||||
**Build completion:**
|
||||
|
||||
```bash
|
||||
printf '\e]777;notify;Build Complete;All 42 tests passed\a'
|
||||
```
|
||||
|
||||
**With ST terminator:**
|
||||
|
||||
```bash
|
||||
printf '\e]777;notify;Task Done;Ready for review\e\\'
|
||||
```
|
||||
|
||||
### Shell Function
|
||||
|
||||
```bash
|
||||
notify_osc777() {
|
||||
local title="$1"
|
||||
local body="$2"
|
||||
printf '\e]777;notify;%s;%s\a' "$title" "$body"
|
||||
}
|
||||
|
||||
# Usage
|
||||
notify_osc777 "Download Complete" "File saved to ~/Downloads"
|
||||
```
|
||||
|
||||
## Comparison
|
||||
|
||||
| Feature | OSC 99 | OSC 777 |
|
||||
|---------|--------|---------|
|
||||
| Title | ✓ | ✓ |
|
||||
| Body | ✓ | ✓ |
|
||||
| Subtitle | ✓ | ✗ |
|
||||
| Notification ID | ✓ | ✗ |
|
||||
| Complexity | Higher | Lower |
|
||||
| Compatibility | Kitty, cmuxterm | RXVT, cmuxterm |
|
||||
|
||||
## Recommendations
|
||||
|
||||
- **Use OSC 777** for simple title + body notifications
|
||||
- **Use OSC 99** when you need subtitles or notification IDs
|
||||
- **Use the CLI** (`cmuxterm notify`) for the easiest integration
|
||||
|
||||
## Testing
|
||||
|
||||
Test notifications in your terminal:
|
||||
|
||||
```bash
|
||||
# OSC 777 (simpler)
|
||||
printf '\e]777;notify;Test;This is a test notification\a'
|
||||
|
||||
# OSC 99 (with subtitle)
|
||||
printf '\e]99;i=test;e=1;d=0;p=title:Test Notification\e\\'
|
||||
printf '\e]99;i=test;e=1;d=0;p=subtitle:Subtitle here\e\\'
|
||||
printf '\e]99;i=test;e=1;d=1;p=body:This is the body text\e\\'
|
||||
```
|
||||
|
||||
## Integration with Other Tools
|
||||
|
||||
### tmux
|
||||
|
||||
If using tmux inside cmuxterm, enable passthrough:
|
||||
|
||||
```bash
|
||||
# In .tmux.conf
|
||||
set -g allow-passthrough on
|
||||
```
|
||||
|
||||
Then wrap sequences:
|
||||
|
||||
```bash
|
||||
printf '\ePtmux;\e\e]777;notify;Title;Body\a\e\\'
|
||||
```
|
||||
|
||||
### SSH
|
||||
|
||||
Notifications work over SSH if your SSH client supports OSC passthrough. Most modern terminals do.
|
||||
|
||||
### Python
|
||||
|
||||
```python
|
||||
import sys
|
||||
|
||||
def notify(title: str, body: str):
|
||||
"""Send OSC 777 notification."""
|
||||
sys.stdout.write(f'\x1b]777;notify;{title};{body}\x07')
|
||||
sys.stdout.flush()
|
||||
|
||||
notify("Script Complete", "Processing finished")
|
||||
```
|
||||
|
||||
### Node.js
|
||||
|
||||
```javascript
|
||||
function notify(title, body) {
|
||||
process.stdout.write(`\x1b]777;notify;${title};${body}\x07`);
|
||||
}
|
||||
|
||||
notify('Build Done', 'webpack finished');
|
||||
```
|
||||
263
docs-site/content/docs/socket-api.mdx
Normal file
263
docs-site/content/docs/socket-api.mdx
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
---
|
||||
title: Socket API
|
||||
description: Unix socket API for programmatic control of cmuxterm
|
||||
---
|
||||
|
||||
# Socket API
|
||||
|
||||
cmuxterm exposes a Unix socket for programmatic control, enabling automation and integration with tools like Claude Code.
|
||||
|
||||
## Socket Location
|
||||
|
||||
| Build | Socket Path |
|
||||
|-------|-------------|
|
||||
| Release | `/tmp/cmuxterm.sock` |
|
||||
| Debug | `/tmp/cmuxterm-debug.sock` |
|
||||
|
||||
You can override the path with the `CMUX_SOCKET_PATH` environment variable.
|
||||
|
||||
## Access Modes
|
||||
|
||||
cmuxterm has three access modes, configurable in Settings:
|
||||
|
||||
| Mode | Description |
|
||||
|------|-------------|
|
||||
| **Off** | Socket disabled |
|
||||
| **Notifications only** | Only notification commands allowed |
|
||||
| **Full control** | All commands enabled |
|
||||
|
||||
<Callout type="warn">
|
||||
On shared machines, use "Notifications only" mode to prevent other users from controlling your terminals.
|
||||
</Callout>
|
||||
|
||||
## Protocol
|
||||
|
||||
Commands are sent as newline-terminated JSON:
|
||||
|
||||
```json
|
||||
{"command": "command-name", "arg1": "value1"}
|
||||
```
|
||||
|
||||
Responses are newline-terminated JSON:
|
||||
|
||||
```json
|
||||
{"success": true, "data": {...}}
|
||||
{"success": false, "error": "Error message"}
|
||||
```
|
||||
|
||||
## Commands Reference
|
||||
|
||||
### Tab Management
|
||||
|
||||
#### list-tabs
|
||||
|
||||
List all open tabs.
|
||||
|
||||
```json
|
||||
{"command": "list-tabs"}
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"tabs": [
|
||||
{"id": "uuid", "title": "Tab 1", "directory": "/Users/..."}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### new-tab
|
||||
|
||||
Create a new tab.
|
||||
|
||||
```json
|
||||
{"command": "new-tab"}
|
||||
```
|
||||
|
||||
#### select-tab
|
||||
|
||||
Switch to a specific tab.
|
||||
|
||||
```json
|
||||
{"command": "select-tab", "id": "tab-uuid"}
|
||||
```
|
||||
|
||||
#### current-tab
|
||||
|
||||
Get the currently active tab.
|
||||
|
||||
```json
|
||||
{"command": "current-tab"}
|
||||
```
|
||||
|
||||
#### close-tab
|
||||
|
||||
Close a specific tab.
|
||||
|
||||
```json
|
||||
{"command": "close-tab", "id": "tab-uuid"}
|
||||
```
|
||||
|
||||
### Split Management
|
||||
|
||||
#### new-split
|
||||
|
||||
Create a new split pane.
|
||||
|
||||
```json
|
||||
{"command": "new-split", "direction": "right"}
|
||||
```
|
||||
|
||||
Direction options: `left`, `right`, `up`, `down`
|
||||
|
||||
#### list-panels
|
||||
|
||||
List all panes in the current tab.
|
||||
|
||||
```json
|
||||
{"command": "list-panels"}
|
||||
```
|
||||
|
||||
#### focus-panel
|
||||
|
||||
Focus a specific pane.
|
||||
|
||||
```json
|
||||
{"command": "focus-panel", "id": "panel-uuid"}
|
||||
```
|
||||
|
||||
### Input Control
|
||||
|
||||
#### send
|
||||
|
||||
Send text input to a terminal.
|
||||
|
||||
```json
|
||||
{"command": "send", "text": "echo hello\n"}
|
||||
```
|
||||
|
||||
#### send-key
|
||||
|
||||
Send a key press.
|
||||
|
||||
```json
|
||||
{"command": "send-key", "key": "enter"}
|
||||
```
|
||||
|
||||
Key options: `enter`, `tab`, `escape`, `backspace`, `delete`, `up`, `down`, `left`, `right`
|
||||
|
||||
#### send-panel
|
||||
|
||||
Send text to a specific panel.
|
||||
|
||||
```json
|
||||
{"command": "send-panel", "id": "panel-uuid", "text": "ls -la\n"}
|
||||
```
|
||||
|
||||
#### send-key-panel
|
||||
|
||||
Send a key press to a specific panel.
|
||||
|
||||
```json
|
||||
{"command": "send-key-panel", "id": "panel-uuid", "key": "enter"}
|
||||
```
|
||||
|
||||
### Notifications
|
||||
|
||||
#### notify
|
||||
|
||||
Send a notification.
|
||||
|
||||
```json
|
||||
{
|
||||
"command": "notify",
|
||||
"title": "Build Complete",
|
||||
"subtitle": "Project X",
|
||||
"body": "Build finished successfully"
|
||||
}
|
||||
```
|
||||
|
||||
#### list-notifications
|
||||
|
||||
List all notifications.
|
||||
|
||||
```json
|
||||
{"command": "list-notifications"}
|
||||
```
|
||||
|
||||
#### clear-notifications
|
||||
|
||||
Clear all notifications.
|
||||
|
||||
```json
|
||||
{"command": "clear-notifications"}
|
||||
```
|
||||
|
||||
### App Control
|
||||
|
||||
#### ping
|
||||
|
||||
Check if the socket is responsive.
|
||||
|
||||
```json
|
||||
{"command": "ping"}
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```json
|
||||
{"success": true, "pong": true}
|
||||
```
|
||||
|
||||
#### set-app-focus
|
||||
|
||||
Simulate app focus/unfocus (for testing).
|
||||
|
||||
```json
|
||||
{"command": "set-app-focus", "focused": true}
|
||||
```
|
||||
|
||||
## Example: Python Client
|
||||
|
||||
```python
|
||||
import socket
|
||||
import json
|
||||
|
||||
def send_command(cmd):
|
||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
sock.connect('/tmp/cmuxterm.sock')
|
||||
sock.send(json.dumps(cmd).encode() + b'\n')
|
||||
response = sock.recv(4096).decode()
|
||||
sock.close()
|
||||
return json.loads(response)
|
||||
|
||||
# List tabs
|
||||
tabs = send_command({"command": "list-tabs"})
|
||||
print(tabs)
|
||||
|
||||
# Send notification
|
||||
send_command({
|
||||
"command": "notify",
|
||||
"title": "Hello",
|
||||
"body": "From Python!"
|
||||
})
|
||||
```
|
||||
|
||||
## Example: Shell Script
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
# Function to send commands
|
||||
cmux_cmd() {
|
||||
echo "$1" | nc -U /tmp/cmuxterm.sock
|
||||
}
|
||||
|
||||
# List tabs
|
||||
cmux_cmd '{"command": "list-tabs"}'
|
||||
|
||||
# Send notification
|
||||
cmux_cmd '{"command": "notify", "title": "Done", "body": "Task complete"}'
|
||||
```
|
||||
111
docs-site/content/docs/splits.mdx
Normal file
111
docs-site/content/docs/splits.mdx
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
---
|
||||
title: Split Panes
|
||||
description: Working with split panes in cmuxterm
|
||||
---
|
||||
|
||||
# Split Panes
|
||||
|
||||
cmuxterm supports splitting terminal panes within a tab, allowing you to view multiple terminals side by side.
|
||||
|
||||
## Creating Splits
|
||||
|
||||
### Keyboard Shortcuts
|
||||
|
||||
| Shortcut | Action |
|
||||
|----------|--------|
|
||||
| **⌘D** | Split right |
|
||||
| **⌘⇧D** | Split down |
|
||||
|
||||
### Using the CLI
|
||||
|
||||
```bash
|
||||
# Split in a specific direction
|
||||
cmuxterm new-split right
|
||||
cmuxterm new-split down
|
||||
cmuxterm new-split left
|
||||
cmuxterm new-split up
|
||||
```
|
||||
|
||||
## Navigating Splits
|
||||
|
||||
### Keyboard
|
||||
|
||||
Use **⌘⌥** + arrow keys to move between splits:
|
||||
|
||||
| Shortcut | Action |
|
||||
|----------|--------|
|
||||
| **⌘⌥←** | Focus left pane |
|
||||
| **⌘⌥→** | Focus right pane |
|
||||
| **⌘⌥↑** | Focus pane above |
|
||||
| **⌘⌥↓** | Focus pane below |
|
||||
|
||||
### CLI
|
||||
|
||||
```bash
|
||||
# List all panes in current tab
|
||||
cmuxterm list-panels
|
||||
|
||||
# Focus a specific pane
|
||||
cmuxterm focus-panel --panel <panel-id>
|
||||
```
|
||||
|
||||
## Closing Splits
|
||||
|
||||
- **⌘W** - Close the focused pane
|
||||
- If only one pane remains, **⌘W** closes the tab
|
||||
|
||||
## Visual Styling
|
||||
|
||||
Unfocused panes are visually distinguished to help you identify the active pane.
|
||||
|
||||
### Configuration
|
||||
|
||||
In your Ghostty config:
|
||||
|
||||
```ini
|
||||
# Dim unfocused panes (0.0 = fully dimmed, 1.0 = no dimming)
|
||||
unfocused-split-opacity = 0.7
|
||||
|
||||
# Background fill for unfocused panes
|
||||
unfocused-split-fill = #1e1e2e
|
||||
|
||||
# Color of the divider between panes
|
||||
split-divider-color = #45475a
|
||||
```
|
||||
|
||||
## Split Layout
|
||||
|
||||
cmuxterm uses a binary split tree structure:
|
||||
|
||||
- Each split creates two child panes
|
||||
- Nested splits create a tree of panes
|
||||
- Each pane has a unique `panel-id` for CLI access
|
||||
|
||||
### Example Layout
|
||||
|
||||
```
|
||||
┌────────────────────────────────┐
|
||||
│ Tab 1 │
|
||||
├──────────────┬─────────────────┤
|
||||
│ │ Pane 2 │
|
||||
│ Pane 1 ├─────────────────┤
|
||||
│ │ Pane 3 │
|
||||
└──────────────┴─────────────────┘
|
||||
```
|
||||
|
||||
This layout is created by:
|
||||
1. Split right → Pane 1 | Pane 2
|
||||
2. Focus Pane 2
|
||||
3. Split down → Pane 2 | Pane 3
|
||||
|
||||
## Sending Input to Specific Panes
|
||||
|
||||
With the CLI, you can send input to specific panes:
|
||||
|
||||
```bash
|
||||
# Send text to a specific pane
|
||||
cmuxterm send-panel --panel <panel-id> "echo hello"
|
||||
|
||||
# Send a keypress to a specific pane
|
||||
cmuxterm send-key-panel --panel <panel-id> enter
|
||||
```
|
||||
74
docs-site/content/docs/tabs.mdx
Normal file
74
docs-site/content/docs/tabs.mdx
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
---
|
||||
title: Vertical Tabs
|
||||
description: Managing terminal tabs in cmuxterm
|
||||
---
|
||||
|
||||
# Vertical Tabs
|
||||
|
||||
cmuxterm displays all your terminal tabs in a vertical sidebar on the left side of the window, making it easy to see and switch between multiple terminals at a glance.
|
||||
|
||||
## Sidebar Features
|
||||
|
||||
- **Always visible** - All tabs shown at once, no hidden tabs
|
||||
- **Resizable** - Drag the sidebar edge to resize (140-360pt)
|
||||
- **Current directory** - Each tab shows its working directory
|
||||
- **Notification badges** - Unread notification indicators
|
||||
- **Keyboard navigation** - Quick switching without mouse
|
||||
|
||||
## Tab Operations
|
||||
|
||||
### Create New Tab
|
||||
|
||||
- **⌘T** or **⌘N** - Create a new tab
|
||||
|
||||
### Close Tab
|
||||
|
||||
- **⌘⇧W** - Close the current tab
|
||||
- **⌘W** - Close the current pane (closes tab if only one pane)
|
||||
|
||||
### Switch Tabs
|
||||
|
||||
| Shortcut | Action |
|
||||
|----------|--------|
|
||||
| **⌘1** - **⌘9** | Jump to tab 1-9 |
|
||||
| **⌘]** | Next tab |
|
||||
| **⌘[** | Previous tab |
|
||||
| **⌃Tab** | Next tab |
|
||||
| **⌃⇧Tab** | Previous tab |
|
||||
|
||||
### Jump to Notifications
|
||||
|
||||
- **⌘⇧U** - Jump to the tab with the latest unread notification
|
||||
- **⌘⇧I** - Show the notifications panel
|
||||
|
||||
## Tab Titles
|
||||
|
||||
Tab titles are determined by:
|
||||
|
||||
1. **Terminal title** - Set via OSC escape sequence
|
||||
2. **Current directory** - Shown if no title is set
|
||||
3. **Tab number** - Fallback display
|
||||
|
||||
You can set a custom tab title from within the terminal:
|
||||
|
||||
```bash
|
||||
# Set tab title
|
||||
echo -e "\033]0;My Custom Title\007"
|
||||
|
||||
# Or using printf
|
||||
printf "\033]0;Build Server\007"
|
||||
```
|
||||
|
||||
## Toggle Sidebar
|
||||
|
||||
- **⌘B** - Toggle the sidebar visibility
|
||||
|
||||
When the sidebar is hidden, you can still use keyboard shortcuts to navigate between tabs.
|
||||
|
||||
## Tab Indicators
|
||||
|
||||
Tabs display visual indicators:
|
||||
|
||||
- **Blue dot** - Unread notification in this tab
|
||||
- **Bold title** - Currently selected tab
|
||||
- **Directory path** - Current working directory for the tab
|
||||
8
docs-site/lib/source.ts
Normal file
8
docs-site/lib/source.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import { docs, meta } from '@/.source';
|
||||
import { createMDXSource } from 'fumadocs-mdx';
|
||||
import { loader } from 'fumadocs-core/source';
|
||||
|
||||
export const source = loader({
|
||||
baseUrl: '/',
|
||||
source: createMDXSource(docs, meta),
|
||||
});
|
||||
10
docs-site/next.config.mjs
Normal file
10
docs-site/next.config.mjs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { createMDX } from 'fumadocs-mdx/next';
|
||||
|
||||
const withMDX = createMDX();
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
const config = {
|
||||
reactStrictMode: true,
|
||||
};
|
||||
|
||||
export default withMDX(config);
|
||||
6122
docs-site/package-lock.json
generated
Normal file
6122
docs-site/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
28
docs-site/package.json
Normal file
28
docs-site/package.json
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"name": "cmuxterm-docs",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"fumadocs-core": "^14.0.0",
|
||||
"fumadocs-mdx": "^11.0.0",
|
||||
"fumadocs-ui": "^14.0.0",
|
||||
"next": "^15.0.0",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.0.0",
|
||||
"@types/react": "^19.0.0",
|
||||
"@types/react-dom": "^19.0.0",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"postcss": "^8.4.49",
|
||||
"tailwindcss": "^3.4.16",
|
||||
"typescript": "^5.7.0"
|
||||
}
|
||||
}
|
||||
9
docs-site/postcss.config.mjs
Normal file
9
docs-site/postcss.config.mjs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/** @type {import('postcss-load-config').Config} */
|
||||
const config = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
BIN
docs-site/public/macos-badge.png
Normal file
BIN
docs-site/public/macos-badge.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
7
docs-site/source.config.ts
Normal file
7
docs-site/source.config.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import { defineConfig, defineDocs } from 'fumadocs-mdx/config';
|
||||
|
||||
export const { docs, meta } = defineDocs({
|
||||
dir: 'content/docs',
|
||||
});
|
||||
|
||||
export default defineConfig();
|
||||
33
docs-site/tailwind.config.ts
Normal file
33
docs-site/tailwind.config.ts
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import { createPreset } from 'fumadocs-ui/tailwind-plugin';
|
||||
import type { Config } from 'tailwindcss';
|
||||
|
||||
const config: Config = {
|
||||
content: [
|
||||
'./components/**/*.{ts,tsx}',
|
||||
'./app/**/*.{ts,tsx}',
|
||||
'./content/**/*.{md,mdx}',
|
||||
'./node_modules/fumadocs-ui/dist/**/*.js',
|
||||
],
|
||||
presets: [createPreset()],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: {
|
||||
50: '#f0f9ff',
|
||||
100: '#e0f2fe',
|
||||
200: '#bae6fd',
|
||||
300: '#7dd3fc',
|
||||
400: '#38bdf8',
|
||||
500: '#0ea5e9',
|
||||
600: '#0284c7',
|
||||
700: '#0369a1',
|
||||
800: '#075985',
|
||||
900: '#0c4a6e',
|
||||
950: '#082f49',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
40
docs-site/tsconfig.json
Normal file
40
docs-site/tsconfig.json
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"plugins": [
|
||||
{
|
||||
"name": "next"
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"target": "ES2017"
|
||||
},
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
".next/types/**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
4
docs-site/vercel.json
Normal file
4
docs-site/vercel.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"$schema": "https://openapi.vercel.sh/vercel.json",
|
||||
"framework": "nextjs"
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue