Skip to content

Commit 91ec4d6

Browse files
committed
feat: initial open source release
- Browser-based desktop environment with AI Agent integration - Built-in apps: Music, Chess, Gomoku, FreeCell, Email, Diary, Twitter, Album, CyberNews - Vibe workflow for AI-powered app generation via Claude Code - IndexedDB-based local file system, no backend required - iframe communication SDK (@gui/vibe-container) - i18n support (English, Chinese, Japanese, Spanish, Portuguese) - Design token system with CSS variables - CI pipeline with GitHub Actions
0 parents  commit 91ec4d6

225 files changed

Lines changed: 42100 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/commands/vibe.md

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
# VibeApp Workflow Orchestrator
2+
3+
Single-entry workflow orchestrator. Automatically advances stages based on workflow state, supporting creation, resume from breakpoint, and requirement changes.
4+
5+
## Parameter Parsing
6+
7+
- `$ARGUMENTS` format: `{AppName} [Description]`
8+
- **Has Description + App does not exist** -> New workflow (creation mode)
9+
- **Has Description + App already exists (workflow completed)** -> Change workflow (change mode)
10+
- **AppName only** -> Resume existing workflow (continue from last interruption point)
11+
- **AppName --from=XX** -> Re-run from specified stage (e.g., `--from=04-codegen`)
12+
13+
## Mode Determination Logic
14+
15+
```
16+
Read .claude/thinking/{AppName}/workflow.json
17+
├── File does not exist ──────────────────────> Creation mode
18+
├── File exists + No Description ─────────────> Resume mode
19+
└── File exists + Has Description
20+
├── Workflow all completed ─────────────> Change mode
21+
└── Workflow not completed ─────────────> Resume mode (ignore new Description, prompt user to complete current workflow first)
22+
```
23+
24+
## Creation Mode: Stage Definitions
25+
26+
```
27+
01-analysis -> Requirement Analysis
28+
02-architecture -> Architecture Design
29+
03-planning -> Task Planning
30+
04-codegen -> Code Generation
31+
05-assets -> Asset Generation (auto-detected, skipped if no requirements)
32+
06-integration -> Project Integration
33+
```
34+
35+
## Change Mode: Stage Definitions
36+
37+
```
38+
01-change-analysis -> Change Impact Analysis
39+
02-change-planning -> Change Task Planning
40+
03-change-codegen -> Change Code Implementation
41+
04-change-verification -> Change Verification
42+
```
43+
44+
## Execution Protocol
45+
46+
### 1. Initialize Workflow State
47+
48+
Read `.claude/thinking/{AppName}/workflow.json`:
49+
50+
- **File does not exist** (creation mode):
51+
1. Create directory `.claude/thinking/{AppName}/outputs/`
52+
2. Create `workflow.json` with mode set to `create`, all stages set to `pending`, `currentStage` set to `01-analysis`
53+
3. Record user Description in the `description` field of `workflow.json`
54+
55+
- **File exists + Has Description + All completed** (change mode):
56+
1. Update `workflow.json`, change mode to `change`
57+
2. Replace stages with the 4 change mode stages, all stages set to `pending`
58+
3. Set `currentStage` to `01-change-analysis`
59+
4. Record new Description in the `changeDescription` field (keep original `description` unchanged)
60+
61+
- **File exists + No Description** (resume mode):
62+
1. Read `currentStage`, continue from that stage
63+
2. If `--from=XX` is passed, reset the target stage and all subsequent stages to `pending`, update `currentStage`
64+
65+
### workflow.json Structure
66+
67+
Creation mode:
68+
```json
69+
{
70+
"appName": "{AppName}",
71+
"mode": "create",
72+
"description": "User's original requirement description",
73+
"currentStage": "01-analysis",
74+
"stages": {
75+
"01-analysis": { "status": "pending", "outputFile": "outputs/requirement-breakdown.json" },
76+
"02-architecture": { "status": "pending", "outputFile": "outputs/solution-design.json" },
77+
"03-planning": { "status": "pending", "outputFile": "outputs/workflow-todolist.json" },
78+
"04-codegen": { "status": "pending", "outputFile": null },
79+
"05-assets": { "status": "pending", "outputFile": "outputs/asset-manifest.json" },
80+
"06-integration": { "status": "pending", "outputFile": null }
81+
},
82+
"createdAt": "",
83+
"updatedAt": ""
84+
}
85+
```
86+
87+
Change mode:
88+
```json
89+
{
90+
"appName": "{AppName}",
91+
"mode": "change",
92+
"description": "User's original requirement description (from creation)",
93+
"changeDescription": "Current change requirement description",
94+
"currentStage": "01-change-analysis",
95+
"stages": {
96+
"01-change-analysis": { "status": "pending", "outputFile": "outputs/change-analysis.json" },
97+
"02-change-planning": { "status": "pending", "outputFile": "outputs/change-todolist.json" },
98+
"03-change-codegen": { "status": "pending", "outputFile": null },
99+
"04-change-verification": { "status": "pending", "outputFile": null }
100+
},
101+
"createdAt": "",
102+
"updatedAt": ""
103+
}
104+
```
105+
106+
### 2. Stage Execution Loop
107+
108+
Execute the following steps for `currentStage`, advance to the next stage upon completion, until all stages are completed:
109+
110+
#### 2a. Load Stage Definition
111+
112+
Read `.claude/workflow/stages/{currentStage}.md`, parse from frontmatter:
113+
- `requires_rules`: List of rule files to read
114+
- `requires_outputs`: List of preceding artifacts to read
115+
- `produces`: Artifact filename produced by this stage
116+
117+
#### 2b. Load Dependencies
118+
119+
- Read each file in `requires_rules`: `.claude/workflow/rules/{rule}`
120+
- Read each file in `requires_outputs`: `.claude/thinking/{AppName}/outputs/{output}`
121+
- These contents serve as input context for the current stage
122+
123+
#### 2c. Execute Stage Instructions
124+
125+
Execute according to the workflow defined in the stage definition file.
126+
127+
#### 2d. Save Artifacts & Advance State
128+
129+
- If `produces` is non-empty, confirm artifacts have been written to `.claude/thinking/{AppName}/outputs/`
130+
- Update `workflow.json`:
131+
- Current stage `status` -> `completed`
132+
- Next stage `status` -> `in_progress`
133+
- `currentStage` -> next stage ID
134+
- `updatedAt` -> current time
135+
- If this is the last stage, mark as `completed` and output completion report
136+
137+
### 3. Completion Report
138+
139+
#### Creation Mode Completion Report
140+
141+
```
142+
Workflow completed: {AppName}
143+
Access URL: http://localhost:3000/{app-name}
144+
Artifacts directory: .claude/thinking/{AppName}/outputs/
145+
Stage duration: (list status of each stage)
146+
```
147+
148+
#### Change Mode Completion Report
149+
150+
```
151+
Change completed: {AppName}
152+
Change type: {changeType}
153+
Change summary: {summary}
154+
Access URL: http://localhost:3000/{app-name}
155+
Build status: pnpm build passed
156+
Changed files: Added {N} / Modified {M} / Deleted {K}
157+
```
158+
159+
After the change is completed, restore the `workflow.json` mode to `create` and restore stages to the 5 creation mode stages (all `completed`), so that the next change can be correctly identified.
160+
161+
## Error Handling
162+
163+
- If any stage execution fails: record the error in the thinking file, keep the current stage as `in_progress` in `workflow.json`
164+
- User can resume the failed stage via `/vibe {AppName}`
165+
- User can re-run from a specified stage via `/vibe {AppName} --from=XX`
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# Concurrent Execution Rules
2+
3+
All multi-file async operations must be executed concurrently; serial `await` is prohibited. **Concurrency limit is 6**; exceeding this requires batching.
4+
5+
---
6+
7+
## 1. Core Tool: `batchConcurrent`
8+
9+
```typescript
10+
import { batchConcurrent } from '@/lib';
11+
12+
// Basic usage: automatically batches 6 at a time
13+
const results = await batchConcurrent(items, (item) => api.readFile(item.path));
14+
15+
// With progressive callback
16+
await batchConcurrent(jsonFiles, (file) => api.readFile(file.path), {
17+
onBatch: (batchResults, startIndex) => { /* parse and append to UI */ },
18+
});
19+
```
20+
21+
**Signature**: `batchConcurrent<T, R>(items, fn, options?: { batchSize?: number; onBatch?: callback })`
22+
- Uses `Promise.allSettled` internally, a single failure does not block | Default batchSize=6
23+
24+
---
25+
26+
## 2. Two-Layer Concurrent Loading (initialization loadData)
27+
28+
```typescript
29+
// Layer 1: Concurrent directory listing (≤ 6, use Promise.all directly)
30+
const [songFiles, playlistFiles] = await Promise.all([
31+
api.listFiles(SONGS_DIR), api.listFiles(PLAYLISTS_DIR),
32+
]);
33+
34+
// Merge → Layer 2: Batch read, progressively update UI per batch
35+
const allFiles = [
36+
...songJsonFiles.map(f => ({ file: f, collection: 'song' as const })),
37+
...playlistJsonFiles.map(f => ({ file: f, collection: 'playlist' as const })),
38+
];
39+
await batchConcurrent(allFiles, (item) => api.readFile(item.file.path), {
40+
onBatch: (batchResults, startIndex) => {
41+
// Parse and categorize → setSongs([...loaded]) / setPlaylists([...loaded])
42+
},
43+
});
44+
```
45+
46+
---
47+
48+
## 3. Single Collection Refresh / Batch Write
49+
50+
```typescript
51+
// Single collection refresh: batchConcurrent + onBatch progressive display
52+
const refreshSongs = async () => {
53+
const loaded: Song[] = [];
54+
await batchConcurrent(jsonFiles, (file) => api.readFile(file.path), {
55+
onBatch: (batchResults) => { /* parse and append to loaded → setSongs([...loaded]) */ },
56+
});
57+
return loaded;
58+
};
59+
60+
// Batch write: batchConcurrent rate limiting (prefer putTextFiles)
61+
await batchConcurrent(SEED_SONGS, (song) => api.writeFile(`${SONGS_DIR}/${song.id}.json`, song));
62+
```
63+
64+
---
65+
66+
## 4. Selection Strategy
67+
68+
| Scenario | API |
69+
|------|-----|
70+
| Directory listing (≤ 6) | `Promise.all` |
71+
| Multi-file read (possibly > 6) | `batchConcurrent` + `onBatch` |
72+
| Batch write (no batch API) | `batchConcurrent` |
73+
| Batch write (has batch API) | `putTextFiles` |
74+
75+
---
76+
77+
## 5. Progressive Loading (all Apps must implement)
78+
79+
**Exit loading immediately** after the first batch of data arrives; subsequent batches append and render.
80+
81+
```typescript
82+
const [isLoading, setIsLoading] = useState(true);
83+
let firstBatchRendered = false;
84+
85+
await batchConcurrent(allFiles, (item) => api.readFile(item.file.path), {
86+
onBatch: (batchResults, startIndex) => {
87+
// Parse and append → setState
88+
if (!firstBatchRendered && hasData) {
89+
firstBatchRendered = true;
90+
setIsLoading(false); // ★ Exit loading on first batch
91+
}
92+
},
93+
});
94+
if (!firstBatchRendered) setIsLoading(false); // Fall back to seed data when no data exists
95+
```
96+
97+
**Rules**:
98+
- `loadData` controls `isLoading` internally; outer layer should not set it redundantly
99+
- refresh functions should also `setState` in each `onBatch` callback
100+
101+
---
102+
103+
## Prohibited Practices
104+
105+
```typescript
106+
// ❌ Serial directory listing / file reading
107+
const songs = await api.listFiles(SONGS_DIR);
108+
const playlists = await api.listFiles(PLAYLISTS_DIR);
109+
for (const file of files) { await api.readFile(file.path); }
110+
111+
// ❌ Unlimited concurrency (when > 6 files)
112+
await Promise.all(files.map(f => api.readFile(f.path)));
113+
114+
// ✅ Correct
115+
const results = await batchConcurrent(files, (f) => api.readFile(f.path));
116+
```

0 commit comments

Comments
 (0)