@aion0/forge 0.2.33 → 0.2.35

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/README.md CHANGED
@@ -1,339 +1,110 @@
1
1
  <p align="center">
2
- <img src="app/icon.svg" width="80" height="80" alt="Forge - Self-hosted Vibe Coding Platform">
2
+ <img src="app/icon.svg" width="80" height="80" alt="Forge">
3
3
  </p>
4
4
 
5
5
  <h1 align="center">Forge</h1>
6
6
 
7
7
  <p align="center">
8
- <strong>Self-hosted Vibe Coding platform for Claude Code — browser terminal, AI task orchestration, remote access from any device</strong>
8
+ <strong>Self-hosted Vibe Coding platform for Claude Code</strong><br>
9
+ Browser terminal · AI tasks · Remote access · Telegram bot
9
10
  </p>
10
11
 
11
12
  <p align="center">
12
- <a href="https://www.npmjs.com/package/@aion0/forge"><img src="https://img.shields.io/npm/v/@aion0/forge" alt="npm version"></a>
13
- <a href="https://github.com/aiwatching/forge/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/@aion0/forge" alt="MIT license"></a>
14
- <a href="https://github.com/aiwatching/forge"><img src="https://img.shields.io/github/stars/aiwatching/forge?style=social" alt="GitHub stars"></a>
13
+ <a href="https://www.npmjs.com/package/@aion0/forge"><img src="https://img.shields.io/npm/v/@aion0/forge" alt="npm"></a>
14
+ <a href="https://github.com/aiwatching/forge/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/@aion0/forge" alt="MIT"></a>
15
+ <a href="https://github.com/aiwatching/forge"><img src="https://img.shields.io/github/stars/aiwatching/forge?style=social" alt="stars"></a>
15
16
  </p>
16
17
 
17
18
  <p align="center">
18
- <a href="#installation">Install</a> · <a href="#features">Features</a> · <a href="#quick-start">Quick Start</a> · <a href="#telegram-bot">Telegram</a> · <a href="#scripts">Scripts</a> · <a href="#configuration">Config</a> · <a href="#roadmap">Roadmap</a>
19
+ <a href="https://www.youtube.com/watch?v=F3fiSiP3pZY">Watch Demo →</a>
19
20
  </p>
20
21
 
21
22
  ---
22
23
 
23
- ## What is Forge?
24
-
25
- Forge is a self-hosted web platform that turns [Claude Code](https://docs.anthropic.com/en/docs/claude-code) into a remote-accessible vibe coding environment. It provides a persistent browser-based terminal (powered by tmux), background AI task orchestration, one-click Cloudflare Tunnel for remote access, and a Telegram bot for mobile control.
26
-
27
- **Use cases:**
28
- - Vibe code from your iPad, phone, or any browser — Claude Code runs on your machine, you access it from anywhere
29
- - Submit AI coding tasks that run in the background while you sleep
30
- - Chain multiple Claude Code instances into automated pipelines (design → implement → review → deploy)
31
- - Browse and search your Obsidian notes with an AI assistant
32
-
33
- **No API keys required.** Forge uses your existing Claude Code CLI subscription. Your code never leaves your machine.
34
-
35
- ## Features
24
+ ## Demo & Install Guide
36
25
 
37
- | Feature | What it does |
38
- |---------|-------------|
39
- | **Vibe Coding** | Browser-based tmux terminal with multiple tabs. Sessions persist across page refresh, browser close, and server restart. Access from any device via Cloudflare Tunnel. |
40
- | **AI Task Queue** | Submit prompts to Claude Code that run in the background. Live streaming output, cost tracking, session continuity across tasks. Supports `--dangerously-skip-permissions` for fully autonomous operation. |
41
- | **Pipeline Engine** | Define multi-step DAG workflows in YAML. Chain Claude Code tasks with dependencies, output passing between steps, conditional routing, and parallel execution. Visual drag-and-drop editor included. |
42
- | **Remote Access** | One-click Cloudflare Tunnel generates a secure public URL. Zero config, no Cloudflare account needed. Auto-health-check with reconnection. |
43
- | **Docs Viewer** | Render Obsidian vaults and markdown directories in the browser. Built-in Claude Console for AI-assisted note-taking and research. Image support. |
44
- | **Project Manager** | Browse project files, view code with syntax highlighting, git status/commit/push/pull, commit history — all from the browser. Multi-repo support. |
45
- | **Demo Preview** | Preview local dev servers (Vite, Next.js, etc.) through dedicated Cloudflare Tunnel URLs. Multiple simultaneous previews supported. |
46
- | **Telegram Bot** | Create tasks, check status, control tunnel, take notes, get AI session summaries — all from your phone. Whitelist-protected. |
47
- | **CLI** | Full command-line interface: `forge task`, `forge watch`, `forge status`, `forge password`, and more. |
48
- | **Monitor** | Real-time dashboard showing process status (Next.js, Terminal, Telegram, Tunnel), tmux sessions, and system uptime. |
26
+ [![Forge Install Guide](https://img.youtube.com/vi/F3fiSiP3pZY/maxresdefault.jpg)](https://www.youtube.com/watch?v=F3fiSiP3pZY)
49
27
 
50
- ## Installation
28
+ ## Install
51
29
 
52
30
  ```bash
53
31
  npm install -g @aion0/forge
54
32
  forge server start
55
33
  ```
56
34
 
57
- Open `http://localhost:3000` a login password is printed in the console.
58
-
59
- ### From source
60
-
61
- ```bash
62
- git clone https://github.com/aiwatching/forge.git
63
- cd forge
64
- pnpm install
65
- ./start.sh # production
66
- ./start.sh dev # development with hot-reload
67
- ```
68
-
69
- ### Prerequisites
70
-
71
- - **Node.js** >= 20
72
- - **tmux** — `brew install tmux` (macOS) / `apt install tmux` (Linux)
73
- - **Claude Code CLI** — `npm install -g @anthropic-ai/claude-code`
74
-
75
- ## Quick Start
76
-
77
- 1. **Start Forge** — `forge server start` or `./start.sh`
78
- 2. **Open browser** — `http://localhost:3000`
79
- 3. **Log in** — set an admin password in Settings. Run `forge password` for info.
80
- 4. **Configure** — Settings → add project directories and (optionally) Telegram bot token
81
- 5. **Start coding** — Open a terminal tab, run `claude`, and vibe
82
-
83
- ## Remote Access
84
-
85
- Access Forge from anywhere — iPad, phone, coffee shop:
86
-
87
- 1. Click the **tunnel button** in the header
88
- 2. A temporary Cloudflare URL is generated (no account needed)
89
- 3. Open it on any device — requires admin password + session code (2FA)
90
-
91
- Health checks run every 60 seconds. If the tunnel drops, it auto-restarts and notifies you via Telegram.
92
-
93
- ## Telegram Bot
94
-
95
- Mobile-first control for Forge. Create a bot via [@BotFather](https://t.me/botfather), add the token in Settings.
96
-
97
- | Command | Description |
98
- |---------|-------------|
99
- | `/task` | Create a task (interactive project picker) |
100
- | `/tasks` | List tasks with quick-action numbers |
101
- | `/sessions` | AI summary of Claude Code sessions |
102
- | `/docs` | Docs session summary or file search |
103
- | `/note` | Quick note — sent to Docs Claude for filing |
104
- | `/tunnel_start <admin_pw>` | Start Cloudflare Tunnel |
105
- | `/tunnel_stop` | Stop tunnel |
106
- | `/tunnel_code <admin_pw>` | Get session code for remote login |
107
- | `/watch` | Monitor session / list watchers |
108
-
109
- Whitelist-protected — only configured Chat IDs can interact. Supports multiple users (comma-separated IDs).
110
-
111
- ## Pipeline Engine
112
-
113
- Define multi-step AI workflows in YAML. Each step runs Claude Code autonomously, with outputs passed to downstream steps.
114
-
115
- ```yaml
116
- name: feature-build
117
- description: "Design → Implement → Review"
118
- input:
119
- requirement: "Feature description"
120
- vars:
121
- project: my-app
122
- nodes:
123
- architect:
124
- project: "{{vars.project}}"
125
- prompt: "Analyze: {{input.requirement}}. Output a design doc."
126
- outputs:
127
- - name: design
128
- extract: result
129
- implement:
130
- project: "{{vars.project}}"
131
- depends_on: [architect]
132
- prompt: "Implement: {{nodes.architect.outputs.design}}"
133
- outputs:
134
- - name: diff
135
- extract: git_diff
136
- review:
137
- depends_on: [implement]
138
- project: "{{vars.project}}"
139
- prompt: "Review: {{nodes.implement.outputs.diff}}"
140
- ```
141
-
142
- Features: DAG execution, parallel nodes, conditional routing, loop protection, Telegram notifications per step, visual editor.
143
-
144
- ## CLI
145
-
146
- All commands are unified under `forge`:
147
-
148
- ```bash
149
- # Server management
150
- forge server start # Start server (foreground)
151
- forge server start --background # Start in background
152
- forge server start --dev # Development mode with hot-reload
153
- forge server start --port 4000 # Custom port
154
- forge server stop # Stop server
155
- forge server restart # Restart (safe for remote use)
156
- forge server rebuild # Force rebuild
157
-
158
- # Tasks
159
- forge task <project> <prompt> # Submit a task
160
- forge tasks [status] # List tasks (running|queued|done|failed)
161
- forge watch <id> # Live stream task output
162
- forge cancel <id> # Cancel a task
163
- forge retry <id> # Retry a failed task
164
-
165
- # Workflows
166
- forge run <flow-name> # Run a YAML workflow
167
- forge flows # List available workflows
168
-
169
- # Status & Info
170
- forge status # Show process status + tmux sessions
171
- forge status <id> # Show task details
172
- forge password # Show login password
173
- forge projects # List configured projects
174
- forge -v # Show version
175
-
176
- # Package management
177
- forge upgrade # Update to latest npm version
178
- forge uninstall # Stop server + uninstall (data preserved in ~/.forge)
179
- ```
180
-
181
- Shortcuts: `t`=task, `ls`=tasks, `w`=watch, `s`=status, `l`=log, `f`=flows, `p`=projects, `pw`=password
182
-
183
- ### Server start options
184
-
185
- ```bash
186
- forge server start --port 4000 # Custom web port (default: 3000)
187
- forge server start --terminal-port 4001 # Custom terminal port (default: 3001)
188
- forge server start --dir ~/.forge-test # Custom data directory
189
- forge server start --background # Run in background
190
- forge server start --reset-terminal # Kill terminal server on start
191
- ```
192
-
193
- ### Development scripts
194
-
195
- ```bash
196
- ./start.sh # kill old processes → build → start (production)
197
- ./start.sh dev # development with hot-reload
198
- ./dev-test.sh # test instance on port 4000 (separate data dir)
199
- ./install.sh # install from npm
200
- ./install.sh --local # install from local source
201
- ./publish.sh # bump version → commit → tag → ready to publish
202
- ./check-forge-status.sh # show all forge processes + tmux sessions
203
- ```
204
-
205
- ## Configuration
206
-
207
- All data lives in `~/.forge/`:
208
-
209
- ```
210
- ~/.forge/
211
- ├── .env.local # Environment variables (AUTH_SECRET, API keys)
212
- ├── settings.yaml # Main configuration
213
- ├── session-code.json # Session code for remote login 2FA
214
- ├── data.db # SQLite database (tasks, sessions)
215
- ├── terminal-state.json # Terminal tab layout
216
- ├── tunnel-state.json # Tunnel process state
217
- ├── preview.json # Demo preview config
218
- ├── pipelines/ # Pipeline execution state
219
- ├── flows/ # YAML workflow definitions
220
- └── bin/ # Auto-downloaded binaries (cloudflared)
221
- ```
222
-
223
- <details>
224
- <summary><strong>settings.yaml</strong></summary>
225
-
226
- ```yaml
227
- projectRoots:
228
- - ~/Projects
229
- docRoots:
230
- - ~/Documents/obsidian-vault
231
- claudePath: claude
232
- tunnelAutoStart: false
233
- telegramBotToken: ""
234
- telegramChatId: "" # Comma-separated for multiple users
235
- telegramTunnelPassword: "" # Admin password (encrypted)
236
- notifyOnComplete: true
237
- notifyOnFailure: true
238
- taskModel: default # default / sonnet / opus / haiku
239
- pipelineModel: default
240
- telegramModel: sonnet
241
- skipPermissions: false # Add --dangerously-skip-permissions to terminal claude invocations
242
- ```
243
-
244
- </details>
245
-
246
- <details>
247
- <summary><strong>.env.local</strong> (optional)</summary>
248
-
249
- ```env
250
- # Fixed auth secret (auto-generated if not set)
251
- AUTH_SECRET=<random-string>
252
-
253
- # Optional: AI provider API keys for multi-model chat
254
- # ANTHROPIC_API_KEY=sk-ant-...
255
- # OPENAI_API_KEY=sk-...
256
- ```
35
+ Open `http://localhost:3000`. First launch prompts you to set an admin password.
257
36
 
258
- </details>
37
+ **Requirements:** Node.js ≥ 20, tmux, [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code)
259
38
 
260
- ## Architecture
39
+ ## What is Forge?
261
40
 
262
- ```
263
- forge-server.mjs (single process)
264
- ├── Next.js (web dashboard + API)
265
- │ ├── Vibe Coding (xterm.js + tmux)
266
- │ ├── Docs Viewer (markdown + Claude Console)
267
- │ ├── Project Manager (files + git)
268
- │ ├── Task Queue (background Claude Code)
269
- │ ├── Pipeline Engine (DAG workflows)
270
- │ ├── Demo Preview (tunnel proxy)
271
- │ └── Monitor (process status)
272
- ├── terminal-standalone.ts (WebSocket → tmux)
273
- ├── telegram-standalone.ts (Telegram Bot API polling)
274
- └── cloudflared (Cloudflare Tunnel, on demand)
275
- ```
41
+ Forge turns Claude Code into a remote-accessible coding platform. Run it on your machine, access from any device.
276
42
 
277
- ## Tech Stack
43
+ - **Vibe Code anywhere** — iPad, phone, any browser. Persistent tmux sessions survive refresh/restart
44
+ - **Background AI tasks** — Submit prompts that run while you sleep. Live output, cost tracking
45
+ - **Pipeline workflows** — Chain Claude Code steps in YAML (design → implement → review)
46
+ - **Remote access** — One-click Cloudflare Tunnel, no account needed
47
+ - **Telegram bot** — Create tasks, check status, take notes from your phone
48
+ - **Skills marketplace** — Browse & install Claude Code slash commands
278
49
 
279
- | Layer | Technology |
280
- |-------|-----------|
281
- | Frontend | Next.js 16, React 19, Tailwind CSS 4, xterm.js, ReactFlow |
282
- | Backend | Next.js Route Handlers, SQLite (better-sqlite3) |
283
- | Terminal | node-pty, tmux, WebSocket |
284
- | Auth | NextAuth v5 (admin password + session code 2FA + OAuth) |
285
- | Tunnel | Cloudflare cloudflared (zero-config) |
286
- | Bot | Telegram Bot API |
287
- | Pipeline | YAML-based DAG engine with visual editor |
50
+ No API keys required. Uses your existing Claude Code subscription. Code never leaves your machine.
288
51
 
289
- ## Troubleshooting
52
+ ## Features
290
53
 
291
- <details>
292
- <summary><strong>macOS: "fork failed: Device not configured"</strong></summary>
54
+ | | |
55
+ |---|---|
56
+ | **Vibe Coding** | Browser tmux terminal, multi-tab, split panes, persistent sessions |
57
+ | **AI Tasks** | Background Claude Code execution with live streaming output |
58
+ | **Pipelines** | YAML DAG workflows with parallel execution & visual editor |
59
+ | **Remote Access** | Cloudflare Tunnel with 2FA (password + session code) |
60
+ | **Docs Viewer** | Obsidian / markdown rendering with AI assistant |
61
+ | **Projects** | File browser, git operations, code viewer |
62
+ | **Skills** | Browse & install Claude Code skills from registry |
63
+ | **Telegram** | Tasks, sessions, notes, tunnel control from mobile |
64
+ | **CLI** | `forge task`, `forge watch`, `forge status`, and more |
293
65
 
294
- PTY device limit exhausted:
66
+ ## Quick Start
295
67
 
296
68
  ```bash
297
- sudo sysctl kern.tty.ptmx_max=2048
298
- echo 'kern.tty.ptmx_max=2048' | sudo tee -a /etc/sysctl.conf
69
+ forge server start # start
70
+ forge server start --dev # dev mode with hot-reload
71
+ forge server start --background # run in background
72
+ forge server stop # stop
73
+ forge server restart # restart
299
74
  ```
300
75
 
301
- </details>
302
-
303
- <details>
304
- <summary><strong>Session cookie invalid after restart</strong></summary>
305
-
306
- Fix AUTH_SECRET so it persists across restarts:
76
+ ### From source
307
77
 
308
78
  ```bash
309
- echo "AUTH_SECRET=$(openssl rand -hex 32)" >> ~/.forge/.env.local
79
+ git clone https://github.com/aiwatching/forge.git
80
+ cd forge && pnpm install
81
+ ./start.sh # production
82
+ ./start.sh dev # development
310
83
  ```
311
84
 
312
- </details>
313
-
314
- <details>
315
- <summary><strong>Orphan processes after Ctrl+C</strong></summary>
316
-
317
- Use `./start.sh` or `forge server start` which clean up old processes on start. Or manually:
85
+ ## CLI
318
86
 
319
87
  ```bash
320
- ./check-forge-status.sh # see what's running
321
- pkill -f 'telegram-standalone|terminal-standalone|next-server|cloudflared'
88
+ forge task <project> <prompt> # submit a task
89
+ forge tasks # list tasks
90
+ forge watch <id> # live stream output
91
+ forge status # process status
92
+ forge password # show login password
93
+ forge projects # list projects
94
+ forge flows # list workflows
95
+ forge run <flow> # run a workflow
96
+ forge server start --reset-password # reset admin password
322
97
  ```
323
98
 
324
- </details>
99
+ ## Telegram Bot
325
100
 
326
- ## Roadmap
101
+ Create a bot via [@BotFather](https://t.me/botfather), add the token in Settings.
327
102
 
328
- - [ ] **Multi-Agent Collaboration**Real-time message channels between concurrent Claude Code instances ([design doc](docs/roadmap-multi-agent-workflow.md))
329
- - [ ] Additional bot platforms — Discord, Slack
330
- - [ ] Excalidraw rendering in Docs viewer
331
- - [ ] Multi-model chat with API keys (Anthropic, OpenAI, Google, xAI)
332
- - [ ] Plugin system for custom integrations
103
+ `/task` create task · `/tasks` list · `/sessions` AI summary · `/note` quick note · `/tunnel_start` — start tunnel · `/watch` — monitor session
333
104
 
334
- ## Contributing
105
+ ## Data
335
106
 
336
- Contributions welcome! Please open an issue first to discuss what you'd like to change.
107
+ All data in `~/.forge/` settings, database, terminal state, workflows, logs. Configurable via `--dir` flag.
337
108
 
338
109
  ## License
339
110
 
@@ -782,6 +782,34 @@ export default function SettingsModal({ onClose }: { onClose: () => void }) {
782
782
 
783
783
  </div>
784
784
 
785
+ {/* Display Name */}
786
+ <div className="space-y-2">
787
+ <label className="text-xs text-[var(--text-secondary)] font-semibold uppercase">
788
+ Display Name
789
+ </label>
790
+ <input
791
+ type="text"
792
+ value={(settings as any).displayName || ''}
793
+ onChange={e => setSettings({ ...settings, displayName: e.target.value } as any)}
794
+ placeholder="Forge"
795
+ className="w-full px-2 py-1 bg-[var(--bg-tertiary)] border border-[var(--border)] rounded text-xs text-[var(--text-primary)]"
796
+ />
797
+ </div>
798
+
799
+ {/* Email */}
800
+ <div className="space-y-2">
801
+ <label className="text-xs text-[var(--text-secondary)] font-semibold uppercase">
802
+ Email
803
+ </label>
804
+ <input
805
+ type="email"
806
+ value={(settings as any).displayEmail || ''}
807
+ onChange={e => setSettings({ ...settings, displayEmail: e.target.value } as any)}
808
+ placeholder="local@forge"
809
+ className="w-full px-2 py-1 bg-[var(--bg-tertiary)] border border-[var(--border)] rounded text-xs text-[var(--text-primary)]"
810
+ />
811
+ </div>
812
+
785
813
  {/* Admin Password */}
786
814
  <div className="space-y-2">
787
815
  <label className="text-xs text-[var(--text-secondary)] font-semibold uppercase">
package/lib/auth.ts CHANGED
@@ -35,7 +35,9 @@ export const { handlers, signIn, signOut, auth } = NextAuth({
35
35
  const isRemote = String(credentials?.isRemote) === 'true';
36
36
 
37
37
  if (verifyLogin(password, sessionCode, isRemote)) {
38
- return { id: 'local', name: 'zliu', email: 'local@forge' };
38
+ const { loadSettings } = await import('./settings');
39
+ const settings = loadSettings();
40
+ return { id: 'local', name: settings.displayName || 'Forge', email: settings.displayEmail || 'local@forge' };
39
41
  }
40
42
  return null;
41
43
  },
package/lib/init.ts CHANGED
@@ -128,6 +128,12 @@ export function ensureInitialized() {
128
128
  export function restartTelegramBot() {
129
129
  stopTelegramBot();
130
130
  startTelegramBot();
131
+ // Kill existing telegram process and restart if configured
132
+ if (telegramChild) {
133
+ try { telegramChild.kill('SIGTERM'); } catch {}
134
+ telegramChild = null;
135
+ }
136
+ startTelegramProcess();
131
137
  }
132
138
 
133
139
  let telegramChild: ReturnType<typeof spawn> | null = null;
package/lib/settings.ts CHANGED
@@ -23,6 +23,8 @@ export interface Settings {
23
23
  skipPermissions: boolean; // Add --dangerously-skip-permissions to all claude invocations
24
24
  notificationRetentionDays: number; // Auto-cleanup notifications older than N days
25
25
  skillsRepoUrl: string; // GitHub raw URL for skills registry
26
+ displayName: string; // User display name (shown in header)
27
+ displayEmail: string; // User email (for session/future integrations)
26
28
  }
27
29
 
28
30
  const defaults: Settings = {
@@ -41,6 +43,8 @@ const defaults: Settings = {
41
43
  skipPermissions: false,
42
44
  notificationRetentionDays: 30,
43
45
  skillsRepoUrl: 'https://raw.githubusercontent.com/aiwatching/forge-skills/main',
46
+ displayName: 'Forge',
47
+ displayEmail: '',
44
48
  };
45
49
 
46
50
  /** Load settings with secrets decrypted (for internal use) */
@@ -53,17 +53,7 @@ function loadTerminalState(): unknown {
53
53
  function saveTerminalState(data: unknown): void {
54
54
  try {
55
55
  mkdirSync(STATE_DIR, { recursive: true });
56
- const json = JSON.stringify(data, null, 2);
57
- writeFileSync(STATE_FILE, json);
58
- // Debug: check if projectPath is being saved
59
- const parsed = JSON.parse(json);
60
- if (parsed.tabs) {
61
- for (const t of parsed.tabs) {
62
- if (t.projectPath || t.tree?.projectPath) {
63
- console.log(`[terminal] Saved tab "${t.label}" with projectPath: tab=${t.projectPath} tree=${t.tree?.projectPath}`);
64
- }
65
- }
66
- }
56
+ writeFileSync(STATE_FILE, JSON.stringify(data, null, 2));
67
57
  } catch (e) {
68
58
  console.error('[terminal] Failed to save state:', e);
69
59
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aion0/forge",
3
- "version": "0.2.33",
3
+ "version": "0.2.35",
4
4
  "description": "Unified AI workflow platform — multi-model task orchestration, persistent sessions, web terminal, remote access",
5
5
  "type": "module",
6
6
  "scripts": {