Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
6f687b5
package `express` app in cli
NiloCK Jul 3, 2025
2dcfa91
add expressManager helper
NiloCK Jul 3, 2025
f8f7667
add working docs re: express integration w/ studio
NiloCK Jul 3, 2025
3bdeba9
run & shutdown of studio express server
NiloCK Jul 3, 2025
b9c907b
add pack_course endpoint to express server
NiloCK Jul 3, 2025
80ae695
add check for studio-mode coursedb
NiloCK Jul 3, 2025
4c66c6a
add hook to express pack-course
NiloCK Jul 3, 2025
d507930
add linting, lint
NiloCK Jul 3, 2025
88e45ab
lockfile
NiloCK Jul 3, 2025
284be0d
flush course changes
NiloCK Jul 3, 2025
ba396d3
update todo
NiloCK Jul 3, 2025
147a7ec
fcn signature fixes
NiloCK Jul 3, 2025
b09e823
add backticks
NiloCK Jul 4, 2025
f89682d
use pouchdb rather than pouchdb-http
NiloCK Jul 4, 2025
8bf8fbc
set version var for express server
NiloCK Jul 4, 2025
01cb844
copy express assets during embedding
NiloCK Jul 4, 2025
8a0da1f
fix stdout text lookup detecting express server
NiloCK Jul 4, 2025
ccdeea9
skip auth in studio-mode...
NiloCK Jul 4, 2025
565d7b5
construct qualified db path for packing operation
NiloCK Jul 4, 2025
d9ba1b8
add missing type
NiloCK Jul 4, 2025
cdd4091
fix indexed view query
NiloCK Jul 4, 2025
2322a3e
add fallback path for packed course outputs
NiloCK Jul 4, 2025
8c0d559
expand fsAdapter interface
NiloCK Jul 4, 2025
0b03c1c
expose 'packCourseToFiles' fcn
NiloCK Jul 4, 2025
f84e3dd
lockfile
NiloCK Jul 4, 2025
efb3bb3
refactor: move pack logic to own file
NiloCK Jul 4, 2025
5f097d6
add project_path env var
NiloCK Jul 4, 2025
d0dffc6
write packed course back to original location
NiloCK Jul 4, 2025
2d86eec
reject non-studio-mode calls to pack-course
NiloCK Jul 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 18 additions & 15 deletions agent/791/a.todo.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@
- [x] CourseInformation component rendering successfully with admin authentication
- [x] Clean UI without debug elements

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

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

## Phase 10: Testing & Validation
- [ ] Test studio mode with various sui course structures
Expand Down
211 changes: 211 additions & 0 deletions agent/a.1.assessment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
# Assessment: CLI Studio Express Integration

## Current State Analysis

### How CLI Currently Handles Studio-UI

The CLI's `studio` command currently:

1. **Bundled Static Assets**: Studio-UI is built as a static Vue.js app and bundled into the CLI package
- Built via `npm run build:studio-ui` in CLI build process
- Assets copied to `dist/studio-ui-assets/` via `embed:studio-ui` script
- Served via Node.js `serve-static` middleware with dynamic config injection

2. **Process Management**: CLI manages processes directly in Node.js
- **CouchDB**: Uses `CouchDBManager` class to spawn Docker containers
- **Studio-UI Server**: Creates HTTP server using Node.js `http` module
- **Process Lifecycle**: Handles graceful shutdown via SIGINT/SIGTERM handlers

3. **Configuration Injection**: Dynamic config injection for studio-ui
- Injects CouchDB connection details into `window.STUDIO_CONFIG`
- Modifies `index.html` at runtime with database connection info
- Uses SPA fallback routing for client-side routing

### Express Backend Architecture

The Express backend (`@vue-skuilder/express`) is:

1. **Standalone Service**: Designed as independent Node.js/Express application
- Main entry: `src/app.ts`
- Hardcoded port: 3000
- Manages own CouchDB connections via `nano` client
- Handles authentication, course management, classroom operations

2. **External Dependencies**: Requires external CouchDB instance
- Connects to CouchDB via environment configuration
- Manages multiple databases (courses, classrooms, users)
- Includes its own initialization and setup logic

3. **Heavyweight Service**: Full-featured API server
- Authentication middleware
- File upload processing
- Complex business logic for course/classroom management
- Logging and error handling

## Integration Options Analysis

### Option A: Bundle Express and Run as Subprocess

**Approach**: Bundle express into CLI and spawn it as a child process

**Pros**:
- Clean separation of concerns
- Express runs in its own process space
- Can leverage existing Express configuration
- Easy to manage process lifecycle (start/stop)
- Familiar process management pattern (similar to CouchDB)

**Cons**:
- Requires bundling entire Express app with CLI
- Multiple Node.js processes running
- More complex communication between CLI and Express
- Harder to pass configuration dynamically
- Potential port conflicts

**Technical Implementation**:
```typescript
// Similar to how CLI spawns CouchDB
const expressProcess = spawn('node', [expressDistPath], {
env: { ...process.env, COUCHDB_URL: couchUrl }
});
```

### Option B: Import Express Directly (Same Process)

**Approach**: Import Express app and run it in the same Node.js process as CLI

**Pros**:
- Single process - more efficient resource usage
- Direct communication between CLI and Express
- Easy to pass configuration objects
- Simpler deployment (single Node.js process)
- Can share CouchDB connection instances

**Cons**:
- Tight coupling between CLI and Express
- Harder to isolate Express errors from CLI
- Express initialization could block CLI startup
- More complex to handle Express-specific configuration
- Potential conflicts with CLI's HTTP server

**Technical Implementation**:
```typescript
// Import Express app and configure it
import { createExpressApp } from '@vue-skuilder/express';
const expressApp = createExpressApp(couchConfig);
expressApp.listen(3000);
```

### Option C: Expect Express Running Separately

**Approach**: CLI expects Express to be running as separate service

**Pros**:
- Complete separation of concerns
- Express can be managed independently
- No changes needed to CLI architecture
- Easy to scale Express separately
- Clear service boundaries

**Cons**:
- Additional setup complexity for users
- Need to coordinate between multiple services
- User must manage Express lifecycle manually
- Harder to provide "one-command" studio experience
- Complex error handling when Express is down

**Technical Implementation**:
```typescript
// CLI just checks if Express is available
const expressHealthCheck = await fetch('http://localhost:3000/health');
if (!expressHealthCheck.ok) {
throw new Error('Express server not running');
}
```

### Option D: Hybrid Approach - Express Module

**Approach**: Refactor Express into a configurable module that CLI can import and control

**Pros**:
- Best of both worlds - modularity with integration
- CLI maintains control over process lifecycle
- Express can be configured per CLI session
- Clean API boundaries
- Reusable Express module

**Cons**:
- Requires significant refactoring of Express package
- Breaking changes to Express architecture
- More complex implementation
- Need to maintain backward compatibility

**Technical Implementation**:
```typescript
// Express as configurable module
import { ExpressService } from '@vue-skuilder/express';
const expressService = new ExpressService({
port: 3001,
couchdb: couchConfig,
logger: cliLogger
});
await expressService.start();
```

## Key Considerations

### 1. **Process Management Consistency**
- CLI already manages CouchDB via subprocess (Docker)
- Studio-UI runs as HTTP server within CLI process
- Express subprocess would follow CouchDB pattern

### 2. **Configuration Management**
- CLI injects config into Studio-UI at runtime
- Express needs CouchDB connection details
- Studio-UI needs to know Express endpoint

### 3. **Port Management**
- CLI finds available ports dynamically (Studio-UI: 7174+)
- Express hardcoded to port 3000
- Need to avoid port conflicts

### 4. **Error Handling & Lifecycle**
- CLI handles graceful shutdown for all services
- Express needs to integrate with CLI's process management
- Studio-UI depends on both CouchDB and Express

### 5. **User Experience**
- Current: Single `skuilder studio` command starts everything
- Goal: Maintain single-command simplicity
- Express adds complexity but provides powerful features

## Recommendation

**Option A: Bundle Express and Run as Subprocess** is the best approach because:

1. **Architectural Consistency**: Matches existing CouchDB subprocess pattern
2. **Clean Separation**: Express runs independently but managed by CLI
3. **Minimal Changes**: Can reuse existing Express code with minimal refactoring
4. **Process Management**: Leverages CLI's existing process lifecycle handling
5. **Configuration**: Can pass config via environment variables (established pattern)

### Implementation Plan

1. **Express Modifications**:
- Make port configurable via environment variable
- Add health check endpoint
- Ensure clean shutdown on SIGTERM/SIGINT

2. **CLI Integration**:
- Add Express process management (similar to CouchDB)
- Bundle Express dist in CLI build process
- Dynamic port allocation for Express
- Update Studio-UI config injection to include Express endpoint

3. **Process Orchestration**:
- Start CouchDB first (as currently done)
- Start Express with CouchDB connection details
- Start Studio-UI with both CouchDB and Express endpoints
- Coordinate shutdown of all services

This approach maintains the current architecture's clarity while adding the powerful Express backend capabilities that users need for full studio functionality.
5 changes: 4 additions & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
}
},
"scripts": {
"build": "rm -rf dist && npm run build:studio-ui && tsc && npm run embed:studio-ui",
"build": "rm -rf dist && npm run build:studio-ui && npm run build:express && tsc && npm run embed:studio-ui && npm run embed:express",
"build:studio-ui": "cd ../studio-ui && npm run build",
"build:express": "cd ../express && npm run build",
"embed:studio-ui": "mkdir -p dist/studio-ui-assets && cp -r ../studio-ui/dist/* dist/studio-ui-assets/",
"embed:express": "mkdir -p dist/express-assets && cp -r ../express/dist/* dist/express-assets/ && cp -r ../express/assets dist/express-assets/",
"dev": "tsc --watch",
"lint": "npx eslint .",
"lint:fix": "npx eslint . --fix",
Expand Down Expand Up @@ -50,6 +52,7 @@
"@types/inquirer": "^9.0.0",
"@types/node": "^20.0.0",
"@types/serve-static": "^1.15.0",
"@vue-skuilder/express": "workspace:*",
"@vue-skuilder/studio-ui": "workspace:*",
"typescript": "~5.7.2"
},
Expand Down
Loading