6.5 KiB
G3 Console Implementation Fixes
Summary of Changes
This document outlines all the critical fixes applied to address the coach's feedback.
1. Fixed Zombie Process Bug ✅
Problem: Launching g3 instances created zombie processes because child processes weren't properly detached.
Solution (src/process/controller.rs):
- Added
unsafeblock withlibc::setsid()to create a new session for child processes - Used
std::mem::forget(child)to prevent waiting on the child process - This fully detaches the child from the parent's process group
- Added
libcdependency toCargo.toml
unsafe {
cmd.pre_exec(|| {
libc::setsid();
Ok(())
});
}
let child = cmd.spawn()?;
let pid = child.id();
std::mem::forget(child); // Don't wait - let it run independently
2. Implemented State Persistence ✅
Problem: Console state was never loaded or saved, despite having the infrastructure.
Solution:
- Created
src/api/state.rswithget_state()andsave_state()endpoints - Added state routes to main.rs:
GET /api/stateandPOST /api/state - Frontend (
js/state.js) now loads state on startup and saves on changes - State persists to
~/.config/g3/console-state.json - Persisted data includes:
- Theme preference (dark/light)
- Last workspace directory
- G3 binary path
- Last used provider and model
3. Implemented Restart Functionality ✅
Problem: Restart endpoint returned NOT_IMPLEMENTED error.
Solution:
- Added
LaunchParamsstruct to store original launch parameters - Modified
ProcessControllerto store launch params in aHashMap<u32, LaunchParams> - Added
get_launch_params()method to retrieve stored parameters - Implemented
restart_instance()to:- Extract PID from instance ID
- Retrieve stored launch params
- Launch new instance with same parameters
- Return new instance ID
pub struct LaunchParams {
pub workspace: PathBuf,
pub provider: String,
pub model: String,
pub prompt: String,
pub autonomous: bool,
pub g3_binary_path: Option<String>,
}
4. Rewrote Frontend to Vanilla JavaScript ✅
Problem: JSX/React files require transpilation with npm/node.js, violating the "no npm" requirement.
Solution: Complete rewrite using vanilla JavaScript with no build step required.
New Frontend Structure:
web/
├── index.html # Main HTML with CDN links for Marked.js and Highlight.js
├── js/
│ ├── api.js # API client (fetch-based)
│ ├── state.js # State management
│ ├── components.js # UI component rendering functions
│ ├── router.js # Client-side routing
│ └── app.js # Main application logic
└── styles/
└── app.css # Complete styling (Hero UI inspired)
Key Features:
No Build Step Required:
- Pure JavaScript (ES6+)
- No JSX, no transpilation
- Direct browser execution
- CDN-loaded libraries (Marked.js for Markdown, Highlight.js for syntax highlighting)
Component System:
- Template literal-based rendering
- Functions return HTML strings
- Dynamic DOM updates via
innerHTML
Routing:
- Client-side routing with History API
- Home page:
/ - Detail page:
/instance/:id
State Management:
- Simple object-based state
- Automatic persistence via API
- Theme switching with CSS variables
Styling:
- CSS custom properties for theming
- Dark and light themes
- Hero UI-inspired design
- Responsive layout
5. Additional Improvements
Visual Feedback
- Modal shows "Starting..." during launch
- Buttons disable during operations
- Loading spinners for async operations
- Status badges with color coding
Markdown & Syntax Highlighting
- Marked.js for Markdown rendering in chat messages
- Highlight.js for code block syntax highlighting
- Applied automatically to all code blocks
Auto-Refresh
- Home page refreshes every 5 seconds
- Detail page refreshes every 3 seconds
- Only refreshes current route
File Browser Note
- HTML5 file input has limited directory picker support
- Users must manually enter paths (browser limitation)
- Alert messages guide users
Testing Checklist
- Backend compiles without errors ✅
- Frontend loads without build step ✅
- State persists between sessions
- Launch new instance works
- Kill instance works
- Restart instance works (no longer returns NOT_IMPLEMENTED)
- No zombie processes created
- Theme toggle works
- Markdown rendering works
- Syntax highlighting works
- Auto-refresh works
Files Modified
Backend:
src/process/controller.rs- Fixed zombie processes, added launch params storagesrc/process/detector.rs- Addedlaunch_paramsfield to Instancesrc/models/instance.rs- AddedLaunchParamsstructsrc/api/control.rs- Implemented restart functionalitysrc/api/state.rs- NEW: State persistence endpointssrc/api/mod.rs- Added state modulesrc/main.rs- Added state routesCargo.toml- Addedlibcdependency
Frontend (Complete Rewrite):
web/index.html- NEW: Vanilla HTML with CDN linksweb/js/api.js- NEW: API clientweb/js/state.js- NEW: State managementweb/js/components.js- NEW: UI componentsweb/js/router.js- NEW: Client-side routerweb/js/app.js- NEW: Main applicationweb/styles/app.css- NEW: Complete styling
Removed:
- All
.jsxfiles (no longer needed) package.json(no npm required)vite.config.js(no build step)
Compilation Status
✅ Backend compiles successfully with 20 warnings (all unused imports, no errors)
cd crates/g3-console && cargo build --release
# Finished `release` profile [optimized] target(s) in 3.74s
Next Steps
- Test with WebDriver to validate all functionality
- Launch a real g3 instance and verify no zombie processes
- Test restart functionality with stored parameters
- Verify state persistence across console restarts
- Test theme switching and UI responsiveness
Implementation Status: ~85% Complete
Completed:
- ✅ Zombie process fix
- ✅ State persistence
- ✅ Restart functionality
- ✅ Vanilla JavaScript frontend (no build step)
- ✅ Markdown rendering
- ✅ Syntax highlighting
- ✅ Theme switching
- ✅ Auto-refresh
- ✅ Modal for new runs
Remaining (lower priority):
- Log parsing for accurate stats
- Git status detection
- Project files preview
- Multi-segment progress bars for ensemble mode
- Enhanced status detection (completed/failed/idle)