Two bugs caught by the live end-to-end test: 1. Tool dispatch mismatch. Gemini tool name "dev_server_list" runs through executeMcpTool's _-to-. converter (toolName.replace(/_/g, '.')) and arrives as "dev.server.list". The dispatcher only had cases for "dev_server.list", so all four dev_server.* tools 404'd as "Unknown tool". The AI gracefully fell back to shell.exec + nohup, so Express still ran — but the dev_servers table never got populated and the preview URL machinery was bypassed. Add aliases for both underscore and fully-dotted forms. 2. State machine never transitioned. ensureDevContainer wrote state='provisioning'; nothing ever flipped it to 'running'. As a result the idle-sweep (which filters by state='running') never saw a candidate to suspend. Use the first successful exec as the authoritative liveness signal: touchActivity() now also flips provisioning|suspended → running and clears suspended_at. Surfaced by the live trace: AI tried dev_server_list, got 404, fell back to manually grepping the process table. Made-with: Cursor
24 KiB
24 KiB