diff --git a/packages/cli/src/serve/server.ts b/packages/cli/src/serve/server.ts index fae3f1093fa..dbd6bd15cdb 100644 --- a/packages/cli/src/serve/server.ts +++ b/packages/cli/src/serve/server.ts @@ -282,11 +282,15 @@ function resolveDaemonTelemetryRoute( ): | { route: string; sessionId?: string; permissionRequestId?: string } | undefined { - if (req.method === 'POST' && req.path === '/session') { + const path = req.path.replace(/\/$/, '') || '/'; + if (req.method === 'POST' && path === '/session') { return { route: 'POST /session' }; } - const sessionAction = req.path.match( - /^\/session\/([^/]+)\/(load|resume|prompt|cancel)$/, + if (req.method === 'POST' && path === '/sessions/delete') { + return { route: 'POST /sessions/delete' }; + } + const sessionAction = path.match( + /^\/session\/([^/]+)\/(load|resume|prompt|cancel|recap|btw|model|shell|detach|approval-mode)$/, ); const sessionActionId = sessionAction?.[1]; const sessionActionName = sessionAction?.[2]; @@ -296,7 +300,14 @@ function resolveDaemonTelemetryRoute( sessionId: sessionActionId, }; } - const sessionPermission = req.path.match( + const sessionMetadata = path.match(/^\/session\/([^/]+)\/metadata$/); + if (sessionMetadata?.[1] && req.method === 'PATCH') { + return { + route: 'PATCH /session/:id/metadata', + sessionId: sessionMetadata[1], + }; + } + const sessionPermission = path.match( /^\/session\/([^/]+)\/permission\/([^/]+)$/, ); if ( @@ -310,21 +321,48 @@ function resolveDaemonTelemetryRoute( permissionRequestId: sessionPermission[2], }; } - const globalPermission = req.path.match(/^\/permission\/([^/]+)$/); + const globalPermission = path.match(/^\/permission\/([^/]+)$/); if (globalPermission?.[1] && req.method === 'POST') { return { route: 'POST /permission/:requestId', permissionRequestId: globalPermission[1], }; } - const deleteSession = req.path.match(/^\/session\/([^/]+)$/); + const deleteSession = path.match(/^\/session\/([^/]+)$/); const deleteSessionId = deleteSession?.[1]; if (deleteSessionId && req.method === 'DELETE') { return { route: 'DELETE /session/:id', sessionId: deleteSessionId }; } - if (req.method === 'GET' && /^\/workspace\/.+\/sessions$/.test(req.path)) { + if (req.method === 'GET' && /^\/workspace\/[^/]+\/sessions$/.test(path)) { return { route: 'GET /workspace/:id/sessions' }; } + if (req.method === 'POST' && path === '/workspace/init') { + return { route: 'POST /workspace/init' }; + } + const mcpRestart = path.match(/^\/workspace\/mcp\/([^/]+)\/restart$/); + if (mcpRestart?.[1] && req.method === 'POST') { + return { route: 'POST /workspace/mcp/:server/restart' }; + } + if (req.method === 'POST' && path === '/workspace/mcp/servers') { + return { route: 'POST /workspace/mcp/servers' }; + } + const mcpDelete = path.match(/^\/workspace\/mcp\/servers\/([^/]+)$/); + if (mcpDelete?.[1] && req.method === 'DELETE') { + return { route: 'DELETE /workspace/mcp/servers/:name' }; + } + if (req.method === 'POST' && path === '/workspace/auth/device-flow') { + return { route: 'POST /workspace/auth/device-flow' }; + } + const deviceFlowDelete = path.match( + /^\/workspace\/auth\/device-flow\/([^/]+)$/, + ); + if (deviceFlowDelete?.[1] && req.method === 'DELETE') { + return { route: 'DELETE /workspace/auth/device-flow/:id' }; + } + const toolEnable = path.match(/^\/workspace\/tools\/([^/]+)\/enable$/); + if (toolEnable?.[1] && req.method === 'POST') { + return { route: 'POST /workspace/tools/:name/enable' }; + } return undefined; } @@ -1435,10 +1473,13 @@ export function createServeApp( } if (!res.writable) { if (daemonLog) { - daemonLog.warn('session reaped (client disconnected before response)', { - sessionId: session.sessionId, - attached: session.attached, - }); + daemonLog.warn( + 'session reaped (client disconnected before response)', + { + sessionId: session.sessionId, + attached: session.attached, + }, + ); } if (!session.attached) { // `requireZeroAttaches: true` closes the BQ9tV race: if