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.
Files changed (78) hide show
  1. package/.cursor/commands/commit-push.md +18 -0
  2. package/.github/agents/architect.md +26 -0
  3. package/.github/agents/engineer.md +29 -0
  4. package/.github/agents/qa-reviewer.md +31 -0
  5. package/.github/agents/researcher.md +30 -0
  6. package/.github/agents/troubleshooter.md +33 -0
  7. package/.github/copilot-instructions.md +55 -0
  8. package/.github/pull_request_template.md +21 -0
  9. package/.github/workflows/build-binaries.yml +76 -0
  10. package/.github/workflows/ci.yml +70 -0
  11. package/.github/workflows/release-on-main.yml +73 -0
  12. package/.prompts/log.md +9 -0
  13. package/AGENTS.md +84 -0
  14. package/CHANGELOG.md +25 -0
  15. package/CLAUDE.md +130 -0
  16. package/CONTRIBUTING.md +76 -0
  17. package/LICENSE +22 -0
  18. package/README.md +165 -0
  19. package/bin/ai-or-die.js +203 -0
  20. package/docs/.nojekyll +1 -0
  21. package/docs/README.md +37 -0
  22. package/docs/adrs/0000-template.md +35 -0
  23. package/docs/adrs/0001-bridge-base-class.md +53 -0
  24. package/docs/adrs/0002-devtunnels-over-ngrok.md +56 -0
  25. package/docs/adrs/0003-multi-tool-architecture.md +71 -0
  26. package/docs/adrs/0004-cross-platform-support.md +101 -0
  27. package/docs/adrs/0005-single-binary-distribution.md +58 -0
  28. package/docs/agent-instructions/00-philosophy.md +55 -0
  29. package/docs/agent-instructions/01-research-and-web.md +49 -0
  30. package/docs/agent-instructions/02-testing-and-validation.md +63 -0
  31. package/docs/agent-instructions/03-tooling-and-pipelines.md +59 -0
  32. package/docs/architecture/bridge-pattern.md +510 -0
  33. package/docs/architecture/overview.md +216 -0
  34. package/docs/architecture/websocket-protocol.md +609 -0
  35. package/docs/history/README.md +26 -0
  36. package/docs/specs/authentication.md +167 -0
  37. package/docs/specs/bridges.md +210 -0
  38. package/docs/specs/client-app.md +308 -0
  39. package/docs/specs/e2e-testing.md +311 -0
  40. package/docs/specs/server.md +334 -0
  41. package/docs/specs/session-store.md +170 -0
  42. package/docs/specs/usage-analytics.md +342 -0
  43. package/nul +0 -0
  44. package/package.json +54 -0
  45. package/scripts/build-sea.js +187 -0
  46. package/scripts/pty-sea-shim.js +21 -0
  47. package/scripts/publish-both.sh +21 -0
  48. package/scripts/release-pr.sh +73 -0
  49. package/scripts/smoke-test-binary.js +190 -0
  50. package/scripts/validate.ps1 +25 -0
  51. package/scripts/validate.sh +16 -0
  52. package/sea-bootstrap.js +54 -0
  53. package/site/ADVANCED_ANALYTICS.md +174 -0
  54. package/site/index.html +151 -0
  55. package/site/script.js +17 -0
  56. package/site/style.css +60 -0
  57. package/src/base-bridge.js +340 -0
  58. package/src/claude-bridge.js +48 -0
  59. package/src/codex-bridge.js +27 -0
  60. package/src/copilot-bridge.js +29 -0
  61. package/src/gemini-bridge.js +26 -0
  62. package/src/public/app.js +2123 -0
  63. package/src/public/auth.js +244 -0
  64. package/src/public/icon-generator.js +26 -0
  65. package/src/public/icons.js +36 -0
  66. package/src/public/index.html +397 -0
  67. package/src/public/manifest.json +45 -0
  68. package/src/public/plan-detector.js +186 -0
  69. package/src/public/service-worker.js +108 -0
  70. package/src/public/session-manager.js +1124 -0
  71. package/src/public/splits.js +574 -0
  72. package/src/public/style.css +2090 -0
  73. package/src/server.js +1269 -0
  74. package/src/terminal-bridge.js +49 -0
  75. package/src/usage-analytics.js +494 -0
  76. package/src/usage-reader.js +895 -0
  77. package/src/utils/auth.js +123 -0
  78. package/src/utils/session-store.js +181 -0
@@ -0,0 +1,216 @@
1
+ # Architecture Overview
2
+
3
+ ai-or-die is a Node.js web application that provides browser-based access to multiple AI CLI tools through a unified terminal interface. It wraps CLI processes (Claude, Codex, Copilot, Gemini, Terminal, and others) in pseudo-terminals and streams their I/O over WebSockets to xterm.js terminals running in the browser.
4
+
5
+ ## System Architecture
6
+
7
+ ```mermaid
8
+ graph TB
9
+ subgraph Browser["Browser Client"]
10
+ UI["app.js<br/>Main Interface Controller"]
11
+ SM["session-manager.js<br/>Tab Management & Notifications"]
12
+ PD["plan-detector.js<br/>Plan Mode Approval UI"]
13
+ XT["xterm.js<br/>Terminal Emulator"]
14
+ AUTH["auth.js<br/>Token Authentication"]
15
+ SW["service-worker.js<br/>PWA / Offline Support"]
16
+ end
17
+
18
+ subgraph Transport["Transport Layer"]
19
+ WS["WebSocket (ws)"]
20
+ HTTP["Express HTTP API"]
21
+ end
22
+
23
+ subgraph Server["Server Layer"]
24
+ SRV["ClaudeCodeWebServer<br/>src/server.js"]
25
+ SS["SessionStore<br/>~/.claude-code-web/sessions.json"]
26
+ UR["UsageReader<br/>~/.claude/projects/.../*.jsonl"]
27
+ UA["UsageAnalytics<br/>Burn Rate & Predictions"]
28
+ end
29
+
30
+ subgraph Bridges["Bridge Layer"]
31
+ CB["ClaudeBridge<br/>src/claude-bridge.js"]
32
+ XB["CodexBridge<br/>src/codex-bridge.js"]
33
+ CPB["CopilotBridge<br/>src/copilot-bridge.js"]
34
+ GB["GeminiBridge<br/>src/gemini-bridge.js"]
35
+ TB["TerminalBridge<br/>src/terminal-bridge.js"]
36
+ end
37
+
38
+ subgraph CLIs["CLI Processes (node-pty)"]
39
+ CLAUDE["claude CLI"]
40
+ CODEX["codex CLI"]
41
+ COPILOT["copilot CLI"]
42
+ GEMINI["gemini CLI"]
43
+ TERMINAL["terminal CLI"]
44
+ end
45
+
46
+ UI <--> WS
47
+ SM <--> UI
48
+ PD <--> UI
49
+ XT <--> UI
50
+ AUTH --> HTTP
51
+ AUTH --> WS
52
+
53
+ WS <--> SRV
54
+ HTTP <--> SRV
55
+
56
+ SRV --> SS
57
+ SRV --> UR
58
+ SRV --> UA
59
+ SRV --> CB
60
+ SRV --> XB
61
+ SRV --> CPB
62
+ SRV --> GB
63
+ SRV --> TB
64
+
65
+ CB <--> CLAUDE
66
+ XB <--> CODEX
67
+ CPB <--> COPILOT
68
+ GB <--> GEMINI
69
+ TB <--> TERMINAL
70
+ ```
71
+
72
+ ## Component Relationships
73
+
74
+ ```mermaid
75
+ graph LR
76
+ subgraph Entry["Entry Point"]
77
+ BIN["bin/ai-or-die.js<br/>Commander.js CLI"]
78
+ end
79
+
80
+ subgraph Core["Core Server"]
81
+ SRV["ClaudeCodeWebServer"]
82
+ end
83
+
84
+ subgraph Persistence["Persistence"]
85
+ SS["SessionStore"]
86
+ end
87
+
88
+ subgraph Analytics["Usage Analytics"]
89
+ UR["UsageReader"]
90
+ UA["UsageAnalytics"]
91
+ end
92
+
93
+ subgraph Bridges["Bridges"]
94
+ CB["ClaudeBridge"]
95
+ XB["CodexBridge"]
96
+ CPB["CopilotBridge"]
97
+ GB["GeminiBridge"]
98
+ TB["TerminalBridge"]
99
+ end
100
+
101
+ BIN -->|"startServer(options)"| SRV
102
+ SRV -->|"saves/loads sessions"| SS
103
+ SRV -->|"reads JSONL logs"| UR
104
+ SRV -->|"burn rate, predictions"| UA
105
+ SRV -->|"spawns claude"| CB
106
+ SRV -->|"spawns codex"| XB
107
+ SRV -->|"spawns copilot"| CPB
108
+ SRV -->|"spawns gemini"| GB
109
+ SRV -->|"spawns terminal"| TB
110
+ ```
111
+
112
+ ## Data Flow
113
+
114
+ ### User Input Flow
115
+
116
+ ```mermaid
117
+ sequenceDiagram
118
+ participant User as Browser User
119
+ participant XT as xterm.js
120
+ participant WS as WebSocket
121
+ participant SRV as Server
122
+ participant Bridge as Bridge (Claude/Codex/Copilot/Gemini/Terminal)
123
+ participant PTY as node-pty Process
124
+
125
+ User->>XT: Types in terminal
126
+ XT->>WS: {type: "input", data: keystrokes}
127
+ WS->>SRV: handleMessage()
128
+ SRV->>SRV: Validate session membership
129
+ SRV->>Bridge: sendInput(sessionId, data)
130
+ Bridge->>PTY: process.write(data)
131
+ ```
132
+
133
+ ### Output Broadcast Flow
134
+
135
+ ```mermaid
136
+ sequenceDiagram
137
+ participant PTY as node-pty Process
138
+ participant Bridge as Bridge
139
+ participant SRV as Server
140
+ participant WS1 as WebSocket Client A
141
+ participant WS2 as WebSocket Client B
142
+
143
+ PTY->>Bridge: onData(output)
144
+ Bridge->>SRV: onOutput callback
145
+ SRV->>SRV: Append to session outputBuffer
146
+ SRV->>SRV: broadcastToSession()
147
+ par Broadcast to all connected clients
148
+ SRV->>WS1: {type: "output", data: output}
149
+ SRV->>WS2: {type: "output", data: output}
150
+ end
151
+ ```
152
+
153
+ ### Session Lifecycle
154
+
155
+ ```mermaid
156
+ stateDiagram-v2
157
+ [*] --> Created: create_session
158
+ Created --> Joined: join_session
159
+ Joined --> AgentRunning: start_claude / start_codex / start_copilot / start_gemini / start_terminal
160
+ AgentRunning --> AgentRunning: input / output
161
+ AgentRunning --> Stopped: stop / exit
162
+ Stopped --> AgentRunning: start_claude / start_codex / start_copilot / start_gemini / start_terminal
163
+ Joined --> Left: leave_session
164
+ Left --> Joined: join_session
165
+ Joined --> Deleted: DELETE /api/sessions/:id
166
+ Stopped --> Deleted: DELETE /api/sessions/:id
167
+ Deleted --> [*]
168
+ ```
169
+
170
+ ## Technology Stack
171
+
172
+ | Layer | Technology | Purpose |
173
+ |-------|-----------|---------|
174
+ | **CLI Entry** | Commander.js | Parse command-line arguments (`--port`, `--auth`, `--https`, etc.) |
175
+ | **HTTP Server** | Express 4.x | REST API, static file serving, authentication middleware |
176
+ | **WebSocket** | ws 8.x | Bidirectional real-time communication between browser and server |
177
+ | **PTY** | node-pty 1.x | Spawn CLI tools in pseudo-terminals with full ANSI/256-color support |
178
+ | **Terminal UI** | xterm.js | Browser-based terminal emulator with fit addon and web links |
179
+ | **Session IDs** | uuid v4 | Unique identifiers for sessions and WebSocket connections |
180
+ | **Tunneling** | devtunnel CLI | Optional public tunnel for remote access |
181
+ | **CORS** | cors | Cross-origin request handling |
182
+ | **PWA** | Service Worker | Progressive Web App support for offline/installable experience |
183
+
184
+ ## Key Design Decisions
185
+
186
+ ### 1. Bridge-per-CLI Architecture
187
+
188
+ Each supported CLI tool has its own bridge class that extends `BaseBridge` (`ClaudeBridge`, `CodexBridge`, `CopilotBridge`, `GeminiBridge`, `TerminalBridge`). All bridges share an identical interface (`startSession`, `sendInput`, `resize`, `stopSession`, `cleanup`), making it straightforward to add new tools. The server routes messages to the correct bridge based on the `session.agent` field.
189
+
190
+ ### 2. Session-Centric Model
191
+
192
+ Sessions are the central organizing concept. A session represents a working directory plus an optional running CLI process. Multiple WebSocket connections can join the same session simultaneously, enabling multi-device access to the same terminal. Sessions persist to disk (`~/.claude-code-web/sessions.json`) and survive server restarts, though the CLI processes themselves do not persist.
193
+
194
+ ### 3. Output Buffering for Reconnection
195
+
196
+ Each session maintains a rolling output buffer (last 1000 lines). When a client joins an existing session, the server replays the last 200 lines from the buffer, allowing the user to see recent context without needing the CLI process to re-emit output.
197
+
198
+ ### 4. node-pty over child_process
199
+
200
+ The application uses `node-pty` instead of `child_process.spawn` because CLI tools like Claude Code produce rich terminal output (ANSI escape codes, 256-color sequences, cursor movement). A real pseudo-terminal is required to faithfully capture and replay this output. The PTY is configured with `xterm-256color` TERM and `truecolor` COLORTERM.
201
+
202
+ ### 5. Authentication by Default
203
+
204
+ The server generates a random authentication token on startup if none is provided. All HTTP endpoints (except `/auth-status`) and WebSocket connections require this token. This prevents accidental exposure of the terminal interface, which has full access to the underlying CLI tools.
205
+
206
+ ### 6. Path Validation and Sandboxing
207
+
208
+ The folder browser and working directory selection enforce that all paths remain within the base directory where the server was started (`process.cwd()`). Directory traversal attempts are rejected at both the API and session creation levels.
209
+
210
+ ### 7. Graceful Shutdown with Escalation
211
+
212
+ When stopping a CLI process, the server sends `SIGTERM` first, then escalates to `SIGKILL` after a 5-second timeout if the process has not exited. This matches standard Unix process management and gives CLI tools a chance to clean up.
213
+
214
+ ### 8. Auto-Save with Atomic Writes
215
+
216
+ Sessions are automatically saved to disk every 30 seconds. The save operation writes to a temporary file first, then renames it atomically to prevent corruption from interrupted writes. Sessions older than 7 days are discarded on load.