ai-or-die 0.1.0
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/.cursor/commands/commit-push.md +18 -0
- package/.github/agents/architect.md +26 -0
- package/.github/agents/engineer.md +29 -0
- package/.github/agents/qa-reviewer.md +31 -0
- package/.github/agents/researcher.md +30 -0
- package/.github/agents/troubleshooter.md +33 -0
- package/.github/copilot-instructions.md +55 -0
- package/.github/pull_request_template.md +21 -0
- package/.github/workflows/build-binaries.yml +76 -0
- package/.github/workflows/ci.yml +70 -0
- package/.github/workflows/release-on-main.yml +73 -0
- package/.prompts/log.md +9 -0
- package/AGENTS.md +84 -0
- package/CHANGELOG.md +25 -0
- package/CLAUDE.md +130 -0
- package/CONTRIBUTING.md +76 -0
- package/LICENSE +22 -0
- package/README.md +165 -0
- package/bin/ai-or-die.js +203 -0
- package/docs/.nojekyll +1 -0
- package/docs/README.md +37 -0
- package/docs/adrs/0000-template.md +35 -0
- package/docs/adrs/0001-bridge-base-class.md +53 -0
- package/docs/adrs/0002-devtunnels-over-ngrok.md +56 -0
- package/docs/adrs/0003-multi-tool-architecture.md +71 -0
- package/docs/adrs/0004-cross-platform-support.md +101 -0
- package/docs/adrs/0005-single-binary-distribution.md +58 -0
- package/docs/agent-instructions/00-philosophy.md +55 -0
- package/docs/agent-instructions/01-research-and-web.md +49 -0
- package/docs/agent-instructions/02-testing-and-validation.md +63 -0
- package/docs/agent-instructions/03-tooling-and-pipelines.md +59 -0
- package/docs/architecture/bridge-pattern.md +510 -0
- package/docs/architecture/overview.md +216 -0
- package/docs/architecture/websocket-protocol.md +609 -0
- package/docs/history/README.md +26 -0
- package/docs/specs/authentication.md +167 -0
- package/docs/specs/bridges.md +210 -0
- package/docs/specs/client-app.md +308 -0
- package/docs/specs/e2e-testing.md +311 -0
- package/docs/specs/server.md +334 -0
- package/docs/specs/session-store.md +170 -0
- package/docs/specs/usage-analytics.md +342 -0
- package/nul +0 -0
- package/package.json +54 -0
- package/scripts/build-sea.js +187 -0
- package/scripts/pty-sea-shim.js +21 -0
- package/scripts/publish-both.sh +21 -0
- package/scripts/release-pr.sh +73 -0
- package/scripts/smoke-test-binary.js +190 -0
- package/scripts/validate.ps1 +25 -0
- package/scripts/validate.sh +16 -0
- package/sea-bootstrap.js +54 -0
- package/site/ADVANCED_ANALYTICS.md +174 -0
- package/site/index.html +151 -0
- package/site/script.js +17 -0
- package/site/style.css +60 -0
- package/src/base-bridge.js +340 -0
- package/src/claude-bridge.js +48 -0
- package/src/codex-bridge.js +27 -0
- package/src/copilot-bridge.js +29 -0
- package/src/gemini-bridge.js +26 -0
- package/src/public/app.js +2123 -0
- package/src/public/auth.js +244 -0
- package/src/public/icon-generator.js +26 -0
- package/src/public/icons.js +36 -0
- package/src/public/index.html +397 -0
- package/src/public/manifest.json +45 -0
- package/src/public/plan-detector.js +186 -0
- package/src/public/service-worker.js +108 -0
- package/src/public/session-manager.js +1124 -0
- package/src/public/splits.js +574 -0
- package/src/public/style.css +2090 -0
- package/src/server.js +1269 -0
- package/src/terminal-bridge.js +49 -0
- package/src/usage-analytics.js +494 -0
- package/src/usage-reader.js +895 -0
- package/src/utils/auth.js +123 -0
- package/src/utils/session-store.js +181 -0
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
Claude Code Web is a web-based interface for the Claude Code CLI that enables browser-based access with multi-session support and real-time streaming capabilities. The application provides a terminal emulator interface through xterm.js with WebSocket communication for real-time interaction.
|
|
8
|
+
|
|
9
|
+
The project uses the **ai-or-die** agent infrastructure for AI-assisted development. See `AGENTS.md` for the full team roster and handoff protocol.
|
|
10
|
+
|
|
11
|
+
## Agent Infrastructure
|
|
12
|
+
|
|
13
|
+
### Agent Personas
|
|
14
|
+
Agent definitions are mirrored in two locations for tool compatibility:
|
|
15
|
+
- `.github/agents/` -- for GitHub Copilot and GitHub-native tooling
|
|
16
|
+
- `.claude/agents/` -- for Claude Code
|
|
17
|
+
|
|
18
|
+
Available agents: **Architect**, **Engineer**, **QA Reviewer**, **Troubleshooter**, **Researcher**.
|
|
19
|
+
|
|
20
|
+
### Documentation-Driven Workflow
|
|
21
|
+
Before starting any task, consult the relevant documentation:
|
|
22
|
+
- `docs/agent-instructions/` -- Philosophy, research guidelines, testing standards, tooling conventions
|
|
23
|
+
- `docs/adrs/` -- Architecture Decision Records (check before proposing new patterns)
|
|
24
|
+
- `docs/specs/` -- Component specifications (read before implementing, update after changing behavior)
|
|
25
|
+
- `docs/architecture/` -- System diagrams and component overviews
|
|
26
|
+
- `docs/history/` -- Incident post-mortems and debugging notes
|
|
27
|
+
|
|
28
|
+
### Mandatory Rules
|
|
29
|
+
1. **Spec updates with code changes**: When code behavior changes, the corresponding spec in `docs/specs/` must be updated in the same commit or PR.
|
|
30
|
+
2. **ADR compliance**: Never contradict an accepted ADR. To change direction, write a new ADR that supersedes the old one.
|
|
31
|
+
3. **Cross-platform support**: All code must work on both Windows and Linux. Use `path.join()` for file paths, provide `.sh` and `.ps1` script variants, and test on both platforms in CI.
|
|
32
|
+
4. **Test coverage**: Every feature and bug fix requires tests. No exceptions.
|
|
33
|
+
|
|
34
|
+
## Common Commands
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# Install dependencies
|
|
38
|
+
npm install
|
|
39
|
+
|
|
40
|
+
# Start development server (with extra logging)
|
|
41
|
+
npm run dev
|
|
42
|
+
|
|
43
|
+
# Start production server
|
|
44
|
+
npm start
|
|
45
|
+
|
|
46
|
+
# Start with custom port
|
|
47
|
+
npm start -- --port 8080
|
|
48
|
+
|
|
49
|
+
# Start with authentication
|
|
50
|
+
npm start -- --auth your-token
|
|
51
|
+
|
|
52
|
+
# Start with HTTPS
|
|
53
|
+
npm start -- --https --cert cert.pem --key key.pem
|
|
54
|
+
|
|
55
|
+
# Run tests
|
|
56
|
+
npm test
|
|
57
|
+
|
|
58
|
+
# Run validation (Linux/macOS)
|
|
59
|
+
bash scripts/validate.sh
|
|
60
|
+
|
|
61
|
+
# Run validation (Windows PowerShell)
|
|
62
|
+
powershell scripts/validate.ps1
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Architecture
|
|
66
|
+
|
|
67
|
+
### Core Components
|
|
68
|
+
|
|
69
|
+
**Server Layer (src/server.js)**
|
|
70
|
+
- Express server handling REST API and WebSocket connections
|
|
71
|
+
- Session persistence via SessionStore (saves to ~/.claude-code-web/sessions.json)
|
|
72
|
+
- Authentication middleware with rate limiting
|
|
73
|
+
- Folder mode for working directory selection
|
|
74
|
+
- Auto-save sessions every 30 seconds
|
|
75
|
+
|
|
76
|
+
**Claude Bridge (src/claude-bridge.js)**
|
|
77
|
+
- Manages Claude CLI process spawning using node-pty
|
|
78
|
+
- Handles multiple concurrent Claude sessions
|
|
79
|
+
- Process lifecycle management (start, stop, resize)
|
|
80
|
+
- Output buffering for reconnection support
|
|
81
|
+
- Searches for Claude CLI in multiple standard locations
|
|
82
|
+
|
|
83
|
+
**Session Management**
|
|
84
|
+
- Persistent sessions survive server restarts
|
|
85
|
+
- Multi-browser support - same session accessible from different devices
|
|
86
|
+
- Session data includes: ID, name, working directory, output buffer, creation time
|
|
87
|
+
- Sessions auto-save and can be manually deleted
|
|
88
|
+
|
|
89
|
+
**Client Architecture (src/public/)**
|
|
90
|
+
- **app.js**: Main interface controller, terminal setup, WebSocket management
|
|
91
|
+
- **session-manager.js**: Session tab UI, notifications, multi-session handling
|
|
92
|
+
- **plan-detector.js**: Detects Claude plan mode and provides approval UI
|
|
93
|
+
- **auth.js**: Client-side authentication handling
|
|
94
|
+
- **service-worker.js**: PWA support for offline capabilities
|
|
95
|
+
|
|
96
|
+
### WebSocket Protocol
|
|
97
|
+
|
|
98
|
+
The application uses WebSocket for real-time bidirectional communication:
|
|
99
|
+
- `create_session`: Initialize new Claude session
|
|
100
|
+
- `join_session`: Connect to existing session
|
|
101
|
+
- `leave_session`: Disconnect without stopping Claude
|
|
102
|
+
- `start_claude`: Launch Claude CLI in session
|
|
103
|
+
- `input`: Send user input to Claude
|
|
104
|
+
- `resize`: Adjust terminal dimensions
|
|
105
|
+
- `stop`: Terminate Claude process
|
|
106
|
+
|
|
107
|
+
### Security Features
|
|
108
|
+
- Optional token-based authentication (Bearer token or query parameter)
|
|
109
|
+
- Rate limiting (100 requests/minute per IP by default)
|
|
110
|
+
- Path validation to prevent directory traversal
|
|
111
|
+
- HTTPS support with SSL certificates
|
|
112
|
+
|
|
113
|
+
## Key Implementation Details
|
|
114
|
+
|
|
115
|
+
- Claude CLI discovery attempts multiple paths including ~/.claude/local/claude
|
|
116
|
+
- Sessions persist to disk at ~/.claude-code-web/sessions.json
|
|
117
|
+
- Output buffer maintains last 1000 lines for reconnection
|
|
118
|
+
- Terminal uses xterm-256color with full ANSI color support
|
|
119
|
+
- Folder browser restricts access to base directory and subdirectories only
|
|
120
|
+
- Mobile-responsive design with touch-optimized controls
|
|
121
|
+
|
|
122
|
+
## Coding Style
|
|
123
|
+
|
|
124
|
+
- Language: Node.js (CommonJS modules)
|
|
125
|
+
- Indentation: 2 spaces
|
|
126
|
+
- Quotes: single quotes
|
|
127
|
+
- Semicolons: required
|
|
128
|
+
- File naming: kebab-case for modules, PascalCase for classes, camelCase for functions/variables
|
|
129
|
+
- Tests: `*.test.js` in the `test/` directory
|
|
130
|
+
- Commits: Conventional Commits format (`feat:`, `fix:`, `docs:`, `test:`, `chore:`, `refactor:`)
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Contributing to ai-or-die
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in contributing! This guide covers how to set up the project, run it locally, write tests, and open quality pull requests.
|
|
4
|
+
|
|
5
|
+
## Project Structure
|
|
6
|
+
|
|
7
|
+
- `bin/ai-or-die.js`: CLI entry point; parses flags and starts the server.
|
|
8
|
+
- `src/server.js`: Express + WebSocket server, routes, session wiring.
|
|
9
|
+
- `src/base-bridge.js`: Shared bridge logic for all CLI tools.
|
|
10
|
+
- `src/claude-bridge.js`, `src/codex-bridge.js`, etc.: Tool-specific bridges extending BaseBridge.
|
|
11
|
+
- `src/copilot-bridge.js`, `src/gemini-bridge.js`, `src/terminal-bridge.js`: New tool bridges.
|
|
12
|
+
- `src/utils/*`: Helpers (auth token handling, session persistence).
|
|
13
|
+
- `src/public/*`: Browser UI assets (HTML/JS/CSS) served by the server.
|
|
14
|
+
- `test/*.test.js`: Mocha unit tests.
|
|
15
|
+
- `docs/`: Technical documentation, specs, ADRs, and agent instructions.
|
|
16
|
+
|
|
17
|
+
## Setup
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
git clone https://github.com/animeshkundu/ai-or-die.git
|
|
21
|
+
cd ai-or-die
|
|
22
|
+
npm install
|
|
23
|
+
npm run dev
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Testing
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm test
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Write tests in `test/` as `name.test.js`. Use Mocha with Node's `assert`. Mock process spawns — avoid network calls or real CLI invocations in tests.
|
|
33
|
+
|
|
34
|
+
## Coding Style
|
|
35
|
+
|
|
36
|
+
- **Language**: Node.js (CommonJS)
|
|
37
|
+
- **Indentation**: 2 spaces, semicolons, single quotes
|
|
38
|
+
- **Files**: kebab-case for modules, PascalCase for classes, camelCase for functions
|
|
39
|
+
- **Tests**: `*.test.js` in `test/`
|
|
40
|
+
- **Cross-platform**: Always use `os.homedir()`, `path.join()`, and platform-aware command discovery
|
|
41
|
+
|
|
42
|
+
## Adding a New Tool
|
|
43
|
+
|
|
44
|
+
1. Create `src/yourname-bridge.js` extending `BaseBridge`
|
|
45
|
+
2. Register it in `src/server.js` (import, instantiate, add to `getBridgeForAgent()`)
|
|
46
|
+
3. Add WebSocket handler for `start_yourtool` in `handleMessage()`
|
|
47
|
+
4. The UI generates cards dynamically from `/api/config` — no HTML changes needed
|
|
48
|
+
|
|
49
|
+
See [docs/architecture/bridge-pattern.md](docs/architecture/bridge-pattern.md) for the full guide.
|
|
50
|
+
|
|
51
|
+
## Pull Request Guidelines
|
|
52
|
+
|
|
53
|
+
- Concise description with linked issues
|
|
54
|
+
- Include tests for behavior changes
|
|
55
|
+
- Update relevant docs in `docs/specs/` when changing code
|
|
56
|
+
- Screenshots/GIFs for UI-facing changes
|
|
57
|
+
- Follow Conventional Commits (`feat:`, `fix:`, `chore:`)
|
|
58
|
+
|
|
59
|
+
## Commit Messages
|
|
60
|
+
|
|
61
|
+
Follow [Conventional Commits](https://www.conventionalcommits.org/):
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
feat: add Gemini CLI bridge support
|
|
65
|
+
fix(bridge): handle Windows path separators in command discovery
|
|
66
|
+
chore(release): v0.1.0
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Documentation
|
|
70
|
+
|
|
71
|
+
Before making code changes, check:
|
|
72
|
+
- `docs/agent-instructions/` for development protocols
|
|
73
|
+
- `docs/adrs/` for past architectural decisions
|
|
74
|
+
- `docs/specs/` for the relevant module specification
|
|
75
|
+
|
|
76
|
+
After making code changes, update the corresponding spec.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 ai-or-die contributors
|
|
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.
|
|
22
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# ai-or-die
|
|
2
|
+
|
|
3
|
+
Universal AI coding terminal — Claude, Copilot, Gemini & more in your browser.
|
|
4
|
+
|
|
5
|
+
ai-or-die is a web-based terminal aggregator that provides browser access to multiple AI CLI tools through a unified interface. Launch Claude, GitHub Copilot, Google Gemini, OpenAI Codex, or a raw terminal session — all from one place, with multi-session support and real-time streaming.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Multi-tool support** — Claude, Copilot, Gemini, Codex, and raw terminal in one interface
|
|
10
|
+
- **Dynamic tool detection** — automatically discovers which tools are installed
|
|
11
|
+
- **Real-time streaming** — full terminal emulation via xterm.js with 256-color support
|
|
12
|
+
- **Multi-session** — run multiple sessions in browser tabs, switch between them
|
|
13
|
+
- **Multi-device** — same session accessible from different browsers/devices
|
|
14
|
+
- **Session persistence** — sessions survive server restarts
|
|
15
|
+
- **Authentication** — token-based auth enabled by default
|
|
16
|
+
- **Dev Tunnels** — secure remote access via Microsoft Dev Tunnels
|
|
17
|
+
- **Cross-platform** — works on Linux and Windows (ConPTY)
|
|
18
|
+
- **PWA** — installable as a Progressive Web App
|
|
19
|
+
- **Mobile-friendly** — responsive design with touch-optimized controls
|
|
20
|
+
|
|
21
|
+
## Requirements
|
|
22
|
+
|
|
23
|
+
- Node.js >= 16
|
|
24
|
+
- At least one supported CLI tool installed:
|
|
25
|
+
- [Claude Code](https://claude.ai/code) — `claude`
|
|
26
|
+
- [GitHub Copilot CLI](https://github.com/features/copilot/cli) — `copilot`
|
|
27
|
+
- [Google Gemini CLI](https://github.com/google-gemini/gemini-cli) — `gemini`
|
|
28
|
+
- [OpenAI Codex](https://openai.com/codex) — `codex`
|
|
29
|
+
- Terminal is always available (bash/PowerShell)
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Run without installing
|
|
35
|
+
npx ai-or-die
|
|
36
|
+
|
|
37
|
+
# Or install globally
|
|
38
|
+
npm install -g ai-or-die
|
|
39
|
+
ai-or-die
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Start with default settings
|
|
46
|
+
ai-or-die
|
|
47
|
+
|
|
48
|
+
# Custom port
|
|
49
|
+
ai-or-die --port 8080
|
|
50
|
+
|
|
51
|
+
# With specific auth token
|
|
52
|
+
ai-or-die --auth your-secret-token
|
|
53
|
+
|
|
54
|
+
# Development mode (extra logging)
|
|
55
|
+
ai-or-die --dev
|
|
56
|
+
|
|
57
|
+
# HTTPS mode
|
|
58
|
+
ai-or-die --https --cert cert.pem --key key.pem
|
|
59
|
+
|
|
60
|
+
# Remote access via Dev Tunnels
|
|
61
|
+
ai-or-die --tunnel --tunnel-allow-anonymous
|
|
62
|
+
|
|
63
|
+
# Custom tool aliases
|
|
64
|
+
ai-or-die --claude-alias "AI" --copilot-alias "CP" --gemini-alias "Gem"
|
|
65
|
+
|
|
66
|
+
# Disable auth (not recommended for production)
|
|
67
|
+
ai-or-die --disable-auth
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## CLI Options
|
|
71
|
+
|
|
72
|
+
| Flag | Description | Default |
|
|
73
|
+
|------|-------------|---------|
|
|
74
|
+
| `-p, --port <number>` | Server port | `7777` |
|
|
75
|
+
| `--no-open` | Don't auto-open browser | |
|
|
76
|
+
| `--auth <token>` | Set auth token | auto-generated |
|
|
77
|
+
| `--disable-auth` | Disable authentication | |
|
|
78
|
+
| `--https` | Enable HTTPS | |
|
|
79
|
+
| `--cert <path>` | SSL certificate file | |
|
|
80
|
+
| `--key <path>` | SSL private key file | |
|
|
81
|
+
| `--dev` | Development mode | |
|
|
82
|
+
| `--plan <type>` | Subscription plan (pro, max5, max20) | `max20` |
|
|
83
|
+
| `--tunnel` | Enable Dev Tunnel | |
|
|
84
|
+
| `--tunnel-allow-anonymous` | Allow anonymous tunnel access | |
|
|
85
|
+
| `--claude-alias <name>` | Display name for Claude | `Claude` |
|
|
86
|
+
| `--codex-alias <name>` | Display name for Codex | `Codex` |
|
|
87
|
+
| `--copilot-alias <name>` | Display name for Copilot | `Copilot` |
|
|
88
|
+
| `--gemini-alias <name>` | Display name for Gemini | `Gemini` |
|
|
89
|
+
| `--terminal-alias <name>` | Display name for Terminal | `Terminal` |
|
|
90
|
+
|
|
91
|
+
## Dev Tunnels Setup
|
|
92
|
+
|
|
93
|
+
For remote access, ai-or-die uses [Microsoft Dev Tunnels](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/):
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# Install devtunnel CLI
|
|
97
|
+
# Windows:
|
|
98
|
+
winget install Microsoft.devtunnel
|
|
99
|
+
|
|
100
|
+
# Linux:
|
|
101
|
+
curl -sL https://aka.ms/DevTunnelCliInstall | bash
|
|
102
|
+
|
|
103
|
+
# First-time login (one-time)
|
|
104
|
+
devtunnel user login
|
|
105
|
+
|
|
106
|
+
# Then start ai-or-die with tunnel
|
|
107
|
+
ai-or-die --tunnel --tunnel-allow-anonymous
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Supported Tools
|
|
111
|
+
|
|
112
|
+
| Tool | Command | Install |
|
|
113
|
+
|------|---------|---------|
|
|
114
|
+
| Claude | `claude` | [claude.ai/code](https://claude.ai/code) |
|
|
115
|
+
| Copilot | `copilot` | `npm install -g @github/copilot` or `winget install GitHub.Copilot` |
|
|
116
|
+
| Gemini | `gemini` | `npm install -g @google/gemini-cli` |
|
|
117
|
+
| Codex | `codex` | [openai.com/codex](https://openai.com/codex) |
|
|
118
|
+
| Terminal | bash/PowerShell | Always available |
|
|
119
|
+
|
|
120
|
+
Tools that aren't installed appear as disabled in the UI. Install them at any time — ai-or-die detects them on next startup.
|
|
121
|
+
|
|
122
|
+
## Architecture
|
|
123
|
+
|
|
124
|
+
See [docs/](docs/README.md) for full technical documentation:
|
|
125
|
+
|
|
126
|
+
- [System Overview](docs/architecture/overview.md)
|
|
127
|
+
- [WebSocket Protocol](docs/architecture/websocket-protocol.md)
|
|
128
|
+
- [Bridge Pattern](docs/architecture/bridge-pattern.md)
|
|
129
|
+
- [Architecture Decision Records](docs/adrs/)
|
|
130
|
+
|
|
131
|
+
## Development
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
# Clone and install
|
|
135
|
+
git clone https://github.com/animeshkundu/ai-or-die.git
|
|
136
|
+
cd ai-or-die
|
|
137
|
+
npm install
|
|
138
|
+
|
|
139
|
+
# Run in dev mode
|
|
140
|
+
npm run dev
|
|
141
|
+
|
|
142
|
+
# Run tests
|
|
143
|
+
npm test
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## API
|
|
147
|
+
|
|
148
|
+
### REST Endpoints
|
|
149
|
+
|
|
150
|
+
| Method | Endpoint | Description |
|
|
151
|
+
|--------|----------|-------------|
|
|
152
|
+
| `GET` | `/api/health` | Server health check |
|
|
153
|
+
| `GET` | `/api/config` | Server config + tool availability |
|
|
154
|
+
| `GET` | `/api/sessions/list` | List all sessions |
|
|
155
|
+
| `POST` | `/api/sessions/create` | Create a new session |
|
|
156
|
+
| `DELETE` | `/api/sessions/:id` | Delete a session |
|
|
157
|
+
| `GET` | `/api/folders` | Browse directories |
|
|
158
|
+
|
|
159
|
+
### WebSocket
|
|
160
|
+
|
|
161
|
+
Connect to `ws://localhost:7777?token=<auth-token>` for real-time communication. See [WebSocket Protocol docs](docs/architecture/websocket-protocol.md) for the full message reference.
|
|
162
|
+
|
|
163
|
+
## License
|
|
164
|
+
|
|
165
|
+
MIT
|
package/bin/ai-or-die.js
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { Command } = require('commander');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const crypto = require('crypto');
|
|
6
|
+
|
|
7
|
+
// Lazy-load open — may not be available in SEA binary
|
|
8
|
+
let open;
|
|
9
|
+
try { open = require('open'); } catch { open = null; }
|
|
10
|
+
const { startServer } = require('../src/server');
|
|
11
|
+
|
|
12
|
+
const program = new Command();
|
|
13
|
+
|
|
14
|
+
program
|
|
15
|
+
.name('ai-or-die')
|
|
16
|
+
.description('ai-or-die — Universal AI coding terminal')
|
|
17
|
+
.version('0.1.0')
|
|
18
|
+
.option('-p, --port <number>', 'port to run the server on', '7777')
|
|
19
|
+
.option('--no-open', 'do not automatically open browser')
|
|
20
|
+
.option('--auth <token>', 'authentication token for secure access')
|
|
21
|
+
.option('--disable-auth', 'disable authentication (not recommended for production)')
|
|
22
|
+
.option('--https', 'enable HTTPS (requires cert files)')
|
|
23
|
+
.option('--cert <path>', 'path to SSL certificate file')
|
|
24
|
+
.option('--key <path>', 'path to SSL private key file')
|
|
25
|
+
.option('--dev', 'development mode with additional logging')
|
|
26
|
+
.option('--plan <type>', 'subscription plan (pro, max5, max20)', 'max20')
|
|
27
|
+
.option('--claude-alias <name>', 'display alias for Claude (default: env CLAUDE_ALIAS or "Claude")')
|
|
28
|
+
.option('--codex-alias <name>', 'display alias for Codex (default: env CODEX_ALIAS or "Codex")')
|
|
29
|
+
.option('--copilot-alias <name>', 'display alias for Copilot (default: env COPILOT_ALIAS or "Copilot")')
|
|
30
|
+
.option('--gemini-alias <name>', 'display alias for Gemini (default: env GEMINI_ALIAS or "Gemini")')
|
|
31
|
+
.option('--terminal-alias <name>', 'display alias for Terminal (default: env TERMINAL_ALIAS or "Terminal")')
|
|
32
|
+
.option('--tunnel', 'enable dev tunnel (requires devtunnel CLI installed)')
|
|
33
|
+
.option('--tunnel-allow-anonymous', 'allow anonymous access to dev tunnel')
|
|
34
|
+
.parse();
|
|
35
|
+
|
|
36
|
+
const options = program.opts();
|
|
37
|
+
|
|
38
|
+
function generateRandomToken(length = 10) {
|
|
39
|
+
const chars = 'ABCDEFGHJKMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789';
|
|
40
|
+
let result = '';
|
|
41
|
+
for (let i = 0; i < length; i++) {
|
|
42
|
+
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
43
|
+
}
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function main() {
|
|
48
|
+
try {
|
|
49
|
+
const port = parseInt(options.port, 10);
|
|
50
|
+
|
|
51
|
+
if (isNaN(port) || port < 1 || port > 65535) {
|
|
52
|
+
console.error('Error: Port must be a number between 1 and 65535');
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Handle authentication logic
|
|
57
|
+
let authToken = null;
|
|
58
|
+
let noAuth = options.disableAuth === true;
|
|
59
|
+
|
|
60
|
+
if (!noAuth) {
|
|
61
|
+
if (options.auth) {
|
|
62
|
+
// Use provided token
|
|
63
|
+
authToken = options.auth;
|
|
64
|
+
} else {
|
|
65
|
+
// Generate random token
|
|
66
|
+
authToken = generateRandomToken();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const serverOptions = {
|
|
71
|
+
port,
|
|
72
|
+
auth: authToken,
|
|
73
|
+
noAuth: noAuth,
|
|
74
|
+
https: options.https,
|
|
75
|
+
cert: options.cert,
|
|
76
|
+
key: options.key,
|
|
77
|
+
dev: options.dev,
|
|
78
|
+
plan: options.plan,
|
|
79
|
+
// UI aliases for assistants
|
|
80
|
+
claudeAlias: options.claudeAlias || process.env.CLAUDE_ALIAS || 'Claude',
|
|
81
|
+
codexAlias: options.codexAlias || process.env.CODEX_ALIAS || 'Codex',
|
|
82
|
+
copilotAlias: options.copilotAlias || process.env.COPILOT_ALIAS || 'Copilot',
|
|
83
|
+
geminiAlias: options.geminiAlias || process.env.GEMINI_ALIAS || 'Gemini',
|
|
84
|
+
terminalAlias: options.terminalAlias || process.env.TERMINAL_ALIAS || 'Terminal',
|
|
85
|
+
folderMode: true // Always use folder mode
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
console.log('Starting ai-or-die...');
|
|
89
|
+
console.log(`Port: ${port}`);
|
|
90
|
+
console.log('Mode: Folder selection mode');
|
|
91
|
+
console.log(`Plan: ${options.plan}`);
|
|
92
|
+
console.log(`Aliases: Claude → "${serverOptions.claudeAlias}", Codex → "${serverOptions.codexAlias}", Copilot → "${serverOptions.copilotAlias}", Gemini → "${serverOptions.geminiAlias}", Terminal → "${serverOptions.terminalAlias}"`);
|
|
93
|
+
|
|
94
|
+
// Display authentication status prominently
|
|
95
|
+
if (noAuth) {
|
|
96
|
+
console.log('\n⚠️ AUTHENTICATION DISABLED - Server is accessible without a token');
|
|
97
|
+
console.log(' (Use without --disable-auth flag for security in production)');
|
|
98
|
+
} else {
|
|
99
|
+
console.log('\n🔐 AUTHENTICATION ENABLED');
|
|
100
|
+
if (options.auth) {
|
|
101
|
+
console.log(' Using provided authentication token');
|
|
102
|
+
} else {
|
|
103
|
+
console.log(' Generated random authentication token:');
|
|
104
|
+
console.log(` \x1b[1m\x1b[33m${authToken}\x1b[0m`);
|
|
105
|
+
console.log(' \x1b[2mSave this token - you\'ll need it to access the interface\x1b[0m');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const server = await startServer(serverOptions);
|
|
110
|
+
|
|
111
|
+
const protocol = options.https ? 'https' : 'http';
|
|
112
|
+
const url = `${protocol}://localhost:${port}`;
|
|
113
|
+
|
|
114
|
+
console.log(`\n🚀 ai-or-die is running at: ${url}`);
|
|
115
|
+
|
|
116
|
+
if (!noAuth) {
|
|
117
|
+
console.log('\n📋 Authentication Required:');
|
|
118
|
+
if (options.auth) {
|
|
119
|
+
console.log(' Use your provided authentication token to access the interface');
|
|
120
|
+
} else {
|
|
121
|
+
console.log(` Enter this token when prompted: \x1b[1m\x1b[33m${authToken}\x1b[0m`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Dev tunnel setup
|
|
126
|
+
let tunnelProcess = null;
|
|
127
|
+
let publicUrl = null;
|
|
128
|
+
if (options.tunnel) {
|
|
129
|
+
console.log('\n\x1b[36m Connecting dev tunnel...\x1b[0m');
|
|
130
|
+
try {
|
|
131
|
+
const { spawn: cpSpawn, execFileSync } = require('child_process');
|
|
132
|
+
|
|
133
|
+
// Check if devtunnel CLI is available
|
|
134
|
+
const devtunnelCmd = process.platform === 'win32' ? 'where' : 'which';
|
|
135
|
+
try {
|
|
136
|
+
execFileSync(devtunnelCmd, ['devtunnel'], { stdio: 'ignore' });
|
|
137
|
+
} catch (_) {
|
|
138
|
+
const isWin = process.platform === 'win32';
|
|
139
|
+
console.error('\n\x1b[31m devtunnel CLI not found.\x1b[0m\n');
|
|
140
|
+
console.error(' Install it with a single command:');
|
|
141
|
+
if (isWin) {
|
|
142
|
+
console.error(' \x1b[1mwinget install Microsoft.devtunnel\x1b[0m');
|
|
143
|
+
} else if (process.platform === 'darwin') {
|
|
144
|
+
console.error(' \x1b[1mbrew install --cask devtunnel\x1b[0m');
|
|
145
|
+
} else {
|
|
146
|
+
console.error(' \x1b[1mcurl -sL https://aka.ms/DevTunnelCliInstall | bash\x1b[0m');
|
|
147
|
+
}
|
|
148
|
+
console.error('\n Then run: \x1b[1mdevtunnel user login\x1b[0m (one-time)\n');
|
|
149
|
+
process.exit(1);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const tunnelArgs = ['host', '-p', String(port)];
|
|
153
|
+
if (options.tunnelAllowAnonymous) tunnelArgs.push('--allow-anonymous');
|
|
154
|
+
tunnelProcess = cpSpawn('devtunnel', tunnelArgs, { stdio: ['pipe', 'pipe', 'pipe'] });
|
|
155
|
+
|
|
156
|
+
tunnelProcess.stdout.on('data', (data) => {
|
|
157
|
+
const match = data.toString().match(/https:\/\/[\w.-]+\.devtunnels\.ms\S*/);
|
|
158
|
+
if (match && !publicUrl) {
|
|
159
|
+
publicUrl = match[0].trim();
|
|
160
|
+
console.log(`\n \x1b[1m\x1b[32mTunnel ready:\x1b[0m \x1b[1m\x1b[4m${publicUrl}\x1b[0m\n`);
|
|
161
|
+
if (options.open) {
|
|
162
|
+
if (open) open(publicUrl).catch(() => {});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
tunnelProcess.stderr.on('data', (data) => {
|
|
167
|
+
const output = data.toString().trim();
|
|
168
|
+
if (output && options.dev) console.log(` [devtunnel] ${output}`);
|
|
169
|
+
});
|
|
170
|
+
tunnelProcess.on('error', () => {
|
|
171
|
+
console.error('\n \x1b[31mDev tunnel process failed to start.\x1b[0m');
|
|
172
|
+
});
|
|
173
|
+
} catch (error) {
|
|
174
|
+
console.error(' Failed to start dev tunnel:', error.message);
|
|
175
|
+
}
|
|
176
|
+
} else if (options.open) {
|
|
177
|
+
try { if (open) await open(url); } catch (error) {
|
|
178
|
+
console.warn(' Could not automatically open browser:', error.message);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
console.log('\nPress Ctrl+C to stop the server\n');
|
|
183
|
+
|
|
184
|
+
const shutdown = async () => {
|
|
185
|
+
console.log('\nShutting down server...');
|
|
186
|
+
// Close dev tunnel first if active
|
|
187
|
+
if (tunnelProcess) { try { tunnelProcess.kill(); } catch (_) {} }
|
|
188
|
+
server.close(() => {
|
|
189
|
+
console.log('Server closed');
|
|
190
|
+
process.exit(0);
|
|
191
|
+
});
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
process.on('SIGINT', () => { shutdown(); });
|
|
195
|
+
process.on('SIGTERM', () => { shutdown(); });
|
|
196
|
+
|
|
197
|
+
} catch (error) {
|
|
198
|
+
console.error('Error starting server:', error.message);
|
|
199
|
+
process.exit(1);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
main();
|
package/docs/.nojekyll
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Prevent GitHub Pages from using Jekyll so our assets serve as-is
|
package/docs/README.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# ai-or-die Documentation
|
|
2
|
+
|
|
3
|
+
Central documentation for the ai-or-die project -- a Node.js web application that provides browser-based access to AI CLI tools (Claude, Codex, Copilot, Gemini, Terminal, and more) through a shared terminal emulator interface.
|
|
4
|
+
|
|
5
|
+
## Architecture
|
|
6
|
+
|
|
7
|
+
- [System Overview](architecture/overview.md)
|
|
8
|
+
- [WebSocket Protocol](architecture/websocket-protocol.md)
|
|
9
|
+
- [Bridge Pattern](architecture/bridge-pattern.md)
|
|
10
|
+
|
|
11
|
+
## Specifications
|
|
12
|
+
|
|
13
|
+
- [Server](specs/server.md)
|
|
14
|
+
- [CLI Bridges](specs/bridges.md)
|
|
15
|
+
- [Session Store](specs/session-store.md)
|
|
16
|
+
- [Authentication](specs/authentication.md)
|
|
17
|
+
- [Client Application](specs/client-app.md)
|
|
18
|
+
- [Usage Analytics](specs/usage-analytics.md)
|
|
19
|
+
|
|
20
|
+
## Architecture Decision Records
|
|
21
|
+
|
|
22
|
+
- [ADR Template](adrs/0000-template.md)
|
|
23
|
+
- [ADR-0001: Bridge Base Class](adrs/0001-bridge-base-class.md)
|
|
24
|
+
- [ADR-0002: DevTunnels over ngrok](adrs/0002-devtunnels-over-ngrok.md)
|
|
25
|
+
- [ADR-0003: Multi-Tool Architecture](adrs/0003-multi-tool-architecture.md)
|
|
26
|
+
- [ADR-0004: Cross-Platform Support](adrs/0004-cross-platform-support.md)
|
|
27
|
+
|
|
28
|
+
## Agent Instructions
|
|
29
|
+
|
|
30
|
+
- [Philosophy](agent-instructions/00-philosophy.md)
|
|
31
|
+
- [Research & Web](agent-instructions/01-research-and-web.md)
|
|
32
|
+
- [Testing & Validation](agent-instructions/02-testing-and-validation.md)
|
|
33
|
+
- [Tooling & Pipelines](agent-instructions/03-tooling-and-pipelines.md)
|
|
34
|
+
|
|
35
|
+
## History
|
|
36
|
+
|
|
37
|
+
- [Changelog](history/README.md)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# ADR-0000: [Title]
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
**Proposed** | Accepted | Deprecated
|
|
6
|
+
|
|
7
|
+
## Date
|
|
8
|
+
|
|
9
|
+
YYYY-MM-DD
|
|
10
|
+
|
|
11
|
+
## Context
|
|
12
|
+
|
|
13
|
+
Describe the forces at play, including technical, political, social, and project-specific. What is the issue that is motivating this decision or change? What constraints exist?
|
|
14
|
+
|
|
15
|
+
## Decision
|
|
16
|
+
|
|
17
|
+
State the architecture decision clearly. Use full sentences and active voice. Explain *what* we are doing and *why*.
|
|
18
|
+
|
|
19
|
+
## Consequences
|
|
20
|
+
|
|
21
|
+
### Positive
|
|
22
|
+
|
|
23
|
+
- What becomes easier or possible as a result of this change?
|
|
24
|
+
|
|
25
|
+
### Negative
|
|
26
|
+
|
|
27
|
+
- What becomes harder or what trade-offs are introduced?
|
|
28
|
+
|
|
29
|
+
### Neutral
|
|
30
|
+
|
|
31
|
+
- What other effects does this decision have that are neither clearly positive nor negative?
|
|
32
|
+
|
|
33
|
+
## Notes
|
|
34
|
+
|
|
35
|
+
Any additional context, links to discussions, or references to related ADRs.
|