Skip to content

Commit adc0e10

Browse files
authored
Add express server to studio mode, add Flush method (#810)
Toward #791 PR - ads a running `packages/express` backend to the cli studio mode, enabling attachment processing hooks - adds database `pack` command to express server, and exposes it as a server_request - connects studio-ui to this server command Pending testing & documentation updates, this probably achieves basic goals of #791. - **package `express` app in cli** - **add expressManager helper** - **add working docs re: express integration w/ studio** - **run & shutdown of studio express server** - **add pack_course endpoint to express server**
2 parents 15336e8 + 2d86eec commit adc0e10

File tree

25 files changed

+1176
-60
lines changed

25 files changed

+1176
-60
lines changed

agent/791/a.todo.md

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@
3535
- [x] CourseInformation component rendering successfully with admin authentication
3636
- [x] Clean UI without debug elements
3737

38-
## Phase 6: Studio-UI Features ⚠️ BLOCKED (Requires Express Integration)
38+
## Phase 6: Studio-UI Features ✅ COMPLETED
3939
- [x] Add StudioFlush component with "Flush to Static" functionality
40-
- [ ] **BLOCKED**: Update StudioFlush.vue to use Express HTTP API instead of CLI exec
41-
- [ ] **BLOCKED**: Add progress reporting via HTTP streaming or polling
42-
- [ ] **BLOCKED**: Implement proper error handling for HTTP flush operations
40+
- [x] Update StudioFlush.vue to use Express HTTP API instead of CLI exec
41+
- [x] Add progress reporting via HTTP streaming or polling
42+
- [x] Implement proper error handling for HTTP flush operations
4343
- [x] Add flush status/progress feedback in studio-ui (UI complete)
4444
- [x] Handle flush errors gracefully with user feedback (UI complete)
4545
- [x] Integrate StudioFlush into studio-ui App.vue
@@ -71,17 +71,20 @@
7171
- [ ] Create basic studio mode documentation
7272
- [x] Add studio-ui package to monorepo build system
7373

74-
## Phase 9.5: Express Backend Integration **CURRENT PRIORITY**
75-
- [ ] **CURRENT**: Add mandatory express backend service to `skuilder studio` command
76-
- [ ] Configure express environment variables to connect to studio CouchDB instance
77-
- [ ] Enable audio normalization processing for studio content (FFMPEG pipeline)
78-
- [ ] Add express service shutdown handling for graceful studio exit
79-
- [ ] Extend wire-format.ts with `FLUSH_COURSE` ServerRequestType
80-
- [ ] Create `FlushCourse` interface in wire-format.ts
81-
- [ ] Add express route for flush operations using `CouchDBToStaticPacker` directly
82-
- [ ] Implement automatic content monitoring and processing for studio sessions
83-
- [ ] Create MCP integration points for content authoring and browsing
84-
- [ ] Document express integration benefits (audio processing, API endpoints, MCP)
74+
## Phase 9.5: Express Backend Integration ✅ COMPLETED (Option A: Bundle Express Subprocess)
75+
- [x] Add express build integration to CLI package.json (similar to studio-ui pattern)
76+
- [x] Create express bundling/embedding process in CLI build scripts
77+
- [x] Create `ExpressManager` class for subprocess management (similar to `CouchDBManager`)
78+
- [x] Add express startup to `launchStudio()` function with dynamic port assignment
79+
- [x] Configure express environment variables to connect to studio CouchDB instance
80+
- [x] Add express to cleanup process in CLI signal handlers (SIGINT/SIGTERM)
81+
- [x] Extend wire-format.ts with `PACK_COURSE` ServerRequestType (renamed from FLUSH_COURSE)
82+
- [x] Create `PackCourse` interface in wire-format.ts (renamed from FlushCourse)
83+
- [x] Add express route for pack operations using `CouchDBToStaticPacker` directly
84+
- [x] Enable audio normalization processing for studio content (FFMPEG pipeline)
85+
- [x] Implement automatic content monitoring and processing for studio sessions
86+
- [ ] **DEFERRED** Create MCP integration points for content authoring and browsing
87+
- [ ] **DEFERRED** Document express integration benefits (audio processing, API endpoints, MCP)
8588

8689
## Phase 10: Testing & Validation
8790
- [ ] Test studio mode with various sui course structures

agent/a.1.assessment.md

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
# Assessment: CLI Studio Express Integration
2+
3+
## Current State Analysis
4+
5+
### How CLI Currently Handles Studio-UI
6+
7+
The CLI's `studio` command currently:
8+
9+
1. **Bundled Static Assets**: Studio-UI is built as a static Vue.js app and bundled into the CLI package
10+
- Built via `npm run build:studio-ui` in CLI build process
11+
- Assets copied to `dist/studio-ui-assets/` via `embed:studio-ui` script
12+
- Served via Node.js `serve-static` middleware with dynamic config injection
13+
14+
2. **Process Management**: CLI manages processes directly in Node.js
15+
- **CouchDB**: Uses `CouchDBManager` class to spawn Docker containers
16+
- **Studio-UI Server**: Creates HTTP server using Node.js `http` module
17+
- **Process Lifecycle**: Handles graceful shutdown via SIGINT/SIGTERM handlers
18+
19+
3. **Configuration Injection**: Dynamic config injection for studio-ui
20+
- Injects CouchDB connection details into `window.STUDIO_CONFIG`
21+
- Modifies `index.html` at runtime with database connection info
22+
- Uses SPA fallback routing for client-side routing
23+
24+
### Express Backend Architecture
25+
26+
The Express backend (`@vue-skuilder/express`) is:
27+
28+
1. **Standalone Service**: Designed as independent Node.js/Express application
29+
- Main entry: `src/app.ts`
30+
- Hardcoded port: 3000
31+
- Manages own CouchDB connections via `nano` client
32+
- Handles authentication, course management, classroom operations
33+
34+
2. **External Dependencies**: Requires external CouchDB instance
35+
- Connects to CouchDB via environment configuration
36+
- Manages multiple databases (courses, classrooms, users)
37+
- Includes its own initialization and setup logic
38+
39+
3. **Heavyweight Service**: Full-featured API server
40+
- Authentication middleware
41+
- File upload processing
42+
- Complex business logic for course/classroom management
43+
- Logging and error handling
44+
45+
## Integration Options Analysis
46+
47+
### Option A: Bundle Express and Run as Subprocess
48+
49+
**Approach**: Bundle express into CLI and spawn it as a child process
50+
51+
**Pros**:
52+
- Clean separation of concerns
53+
- Express runs in its own process space
54+
- Can leverage existing Express configuration
55+
- Easy to manage process lifecycle (start/stop)
56+
- Familiar process management pattern (similar to CouchDB)
57+
58+
**Cons**:
59+
- Requires bundling entire Express app with CLI
60+
- Multiple Node.js processes running
61+
- More complex communication between CLI and Express
62+
- Harder to pass configuration dynamically
63+
- Potential port conflicts
64+
65+
**Technical Implementation**:
66+
```typescript
67+
// Similar to how CLI spawns CouchDB
68+
const expressProcess = spawn('node', [expressDistPath], {
69+
env: { ...process.env, COUCHDB_URL: couchUrl }
70+
});
71+
```
72+
73+
### Option B: Import Express Directly (Same Process)
74+
75+
**Approach**: Import Express app and run it in the same Node.js process as CLI
76+
77+
**Pros**:
78+
- Single process - more efficient resource usage
79+
- Direct communication between CLI and Express
80+
- Easy to pass configuration objects
81+
- Simpler deployment (single Node.js process)
82+
- Can share CouchDB connection instances
83+
84+
**Cons**:
85+
- Tight coupling between CLI and Express
86+
- Harder to isolate Express errors from CLI
87+
- Express initialization could block CLI startup
88+
- More complex to handle Express-specific configuration
89+
- Potential conflicts with CLI's HTTP server
90+
91+
**Technical Implementation**:
92+
```typescript
93+
// Import Express app and configure it
94+
import { createExpressApp } from '@vue-skuilder/express';
95+
const expressApp = createExpressApp(couchConfig);
96+
expressApp.listen(3000);
97+
```
98+
99+
### Option C: Expect Express Running Separately
100+
101+
**Approach**: CLI expects Express to be running as separate service
102+
103+
**Pros**:
104+
- Complete separation of concerns
105+
- Express can be managed independently
106+
- No changes needed to CLI architecture
107+
- Easy to scale Express separately
108+
- Clear service boundaries
109+
110+
**Cons**:
111+
- Additional setup complexity for users
112+
- Need to coordinate between multiple services
113+
- User must manage Express lifecycle manually
114+
- Harder to provide "one-command" studio experience
115+
- Complex error handling when Express is down
116+
117+
**Technical Implementation**:
118+
```typescript
119+
// CLI just checks if Express is available
120+
const expressHealthCheck = await fetch('http://localhost:3000/health');
121+
if (!expressHealthCheck.ok) {
122+
throw new Error('Express server not running');
123+
}
124+
```
125+
126+
### Option D: Hybrid Approach - Express Module
127+
128+
**Approach**: Refactor Express into a configurable module that CLI can import and control
129+
130+
**Pros**:
131+
- Best of both worlds - modularity with integration
132+
- CLI maintains control over process lifecycle
133+
- Express can be configured per CLI session
134+
- Clean API boundaries
135+
- Reusable Express module
136+
137+
**Cons**:
138+
- Requires significant refactoring of Express package
139+
- Breaking changes to Express architecture
140+
- More complex implementation
141+
- Need to maintain backward compatibility
142+
143+
**Technical Implementation**:
144+
```typescript
145+
// Express as configurable module
146+
import { ExpressService } from '@vue-skuilder/express';
147+
const expressService = new ExpressService({
148+
port: 3001,
149+
couchdb: couchConfig,
150+
logger: cliLogger
151+
});
152+
await expressService.start();
153+
```
154+
155+
## Key Considerations
156+
157+
### 1. **Process Management Consistency**
158+
- CLI already manages CouchDB via subprocess (Docker)
159+
- Studio-UI runs as HTTP server within CLI process
160+
- Express subprocess would follow CouchDB pattern
161+
162+
### 2. **Configuration Management**
163+
- CLI injects config into Studio-UI at runtime
164+
- Express needs CouchDB connection details
165+
- Studio-UI needs to know Express endpoint
166+
167+
### 3. **Port Management**
168+
- CLI finds available ports dynamically (Studio-UI: 7174+)
169+
- Express hardcoded to port 3000
170+
- Need to avoid port conflicts
171+
172+
### 4. **Error Handling & Lifecycle**
173+
- CLI handles graceful shutdown for all services
174+
- Express needs to integrate with CLI's process management
175+
- Studio-UI depends on both CouchDB and Express
176+
177+
### 5. **User Experience**
178+
- Current: Single `skuilder studio` command starts everything
179+
- Goal: Maintain single-command simplicity
180+
- Express adds complexity but provides powerful features
181+
182+
## Recommendation
183+
184+
**Option A: Bundle Express and Run as Subprocess** is the best approach because:
185+
186+
1. **Architectural Consistency**: Matches existing CouchDB subprocess pattern
187+
2. **Clean Separation**: Express runs independently but managed by CLI
188+
3. **Minimal Changes**: Can reuse existing Express code with minimal refactoring
189+
4. **Process Management**: Leverages CLI's existing process lifecycle handling
190+
5. **Configuration**: Can pass config via environment variables (established pattern)
191+
192+
### Implementation Plan
193+
194+
1. **Express Modifications**:
195+
- Make port configurable via environment variable
196+
- Add health check endpoint
197+
- Ensure clean shutdown on SIGTERM/SIGINT
198+
199+
2. **CLI Integration**:
200+
- Add Express process management (similar to CouchDB)
201+
- Bundle Express dist in CLI build process
202+
- Dynamic port allocation for Express
203+
- Update Studio-UI config injection to include Express endpoint
204+
205+
3. **Process Orchestration**:
206+
- Start CouchDB first (as currently done)
207+
- Start Express with CouchDB connection details
208+
- Start Studio-UI with both CouchDB and Express endpoints
209+
- Coordinate shutdown of all services
210+
211+
This approach maintains the current architecture's clarity while adding the powerful Express backend capabilities that users need for full studio functionality.

packages/cli/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@
1818
}
1919
},
2020
"scripts": {
21-
"build": "rm -rf dist && npm run build:studio-ui && tsc && npm run embed:studio-ui",
21+
"build": "rm -rf dist && npm run build:studio-ui && npm run build:express && tsc && npm run embed:studio-ui && npm run embed:express",
2222
"build:studio-ui": "cd ../studio-ui && npm run build",
23+
"build:express": "cd ../express && npm run build",
2324
"embed:studio-ui": "mkdir -p dist/studio-ui-assets && cp -r ../studio-ui/dist/* dist/studio-ui-assets/",
25+
"embed:express": "mkdir -p dist/express-assets && cp -r ../express/dist/* dist/express-assets/ && cp -r ../express/assets dist/express-assets/",
2426
"dev": "tsc --watch",
2527
"lint": "npx eslint .",
2628
"lint:fix": "npx eslint . --fix",
@@ -50,6 +52,7 @@
5052
"@types/inquirer": "^9.0.0",
5153
"@types/node": "^20.0.0",
5254
"@types/serve-static": "^1.15.0",
55+
"@vue-skuilder/express": "workspace:*",
5356
"@vue-skuilder/studio-ui": "workspace:*",
5457
"typescript": "~5.7.2"
5558
},

0 commit comments

Comments
 (0)