11import { initWRPC } from "@webview-rpc/host" ;
2+ import * as os from "node:os" ;
3+ import * as path from "node:path" ;
24import * as vscodeApi from "vscode" ;
35import z from "zod" ;
6+ import { getProjectCode } from "@vegamo/deepcode-core" ;
47import type { SessionManager , SkillInfo , UserToolPermission , PermissionScope } from "@vegamo/deepcode-core" ;
58
69export interface RouterContext {
@@ -11,6 +14,7 @@ export interface RouterContext {
1114 getWorkspaceRoot : ( ) => string ;
1215 openSettings : ( ) => Promise < void > ;
1316 getActiveEditor : ( ) => { fileName : string ; languageId : string ; lineCount : number } | null ;
17+ openChatPanel : ( sessionId : string , viewColumn : number ) => void ;
1418}
1519
1620export const { router, procedure } = initWRPC . context < RouterContext > ( ) . create ( ) ;
@@ -38,6 +42,11 @@ function serializeProcesses(
3842 return serialized ;
3943}
4044
45+ function getSessionJsonlPath ( workspaceRoot : string , sessionId : string ) : string {
46+ const projectCode = getProjectCode ( workspaceRoot ) ;
47+ return path . join ( os . homedir ( ) , ".deepcode" , "projects" , projectCode , `${ sessionId } .jsonl` ) ;
48+ }
49+
4150const sendPromptInput = z . object ( {
4251 prompt : z . string ( ) . default ( "" ) ,
4352 skills : z
@@ -77,6 +86,9 @@ export const appRouter = router({
7786 . listSessionMessages ( activeSessionId )
7887 . filter ( ( m ) => m . visible )
7988 . map ( ( m ) => ( {
89+ ...m ,
90+ id : m . id ,
91+ sessionId : m . sessionId ,
8092 role : m . role ,
8193 content : m . content ,
8294 html :
@@ -195,6 +207,7 @@ export const appRouter = router({
195207 messages : messages
196208 . filter ( ( m ) => m . visible )
197209 . map ( ( m ) => ( {
210+ ...m ,
198211 role : m . role ,
199212 content : m . content || ( m . messageParams as { reasoning_content ?: string } | null ) ?. reasoning_content || "" ,
200213 meta : m . meta ,
@@ -264,6 +277,62 @@ export const appRouter = router({
264277 ctx . sessionManager . addSessionSystemMessage ( activeSessionId , input . content , true , input . meta ) ;
265278 return { ok : true } ;
266279 } ) ,
280+
281+ renameSession : procedure
282+ . input (
283+ z . object ( {
284+ sessionId : z . string ( ) ,
285+ summary : z . string ( ) . min ( 1 , "Summary cannot be empty" ) ,
286+ } )
287+ )
288+ . resolve ( ( { ctx, input } ) => {
289+ const ok = ctx . sessionManager . renameSession ( input . sessionId , input . summary ) ;
290+ if ( ! ok ) {
291+ return { ok : false , error : "Session not found or empty summary" } ;
292+ }
293+ return { ok : true } ;
294+ } ) ,
295+
296+ deleteSession : procedure . input ( z . object ( { sessionId : z . string ( ) } ) ) . resolve ( async ( { ctx, input } ) => {
297+ const activeSessionId = ctx . sessionManager . getActiveSessionId ( ) ;
298+ const ok = ctx . sessionManager . deleteSession ( input . sessionId ) ;
299+ if ( ! ok ) {
300+ return { ok : false , error : "Session not found" } ;
301+ }
302+ // If the deleted session was the active one, clear the active session
303+ if ( activeSessionId === input . sessionId ) {
304+ ctx . sessionManager . setActiveSessionId ( null ) ;
305+ }
306+ return { ok : true , wasActiveSession : activeSessionId === input . sessionId } ;
307+ } ) ,
308+
309+ getSessionFilePath : procedure . input ( z . object ( { sessionId : z . string ( ) } ) ) . resolve ( ( { ctx, input } ) => {
310+ const filePath = getSessionJsonlPath ( ctx . getWorkspaceRoot ( ) , input . sessionId ) ;
311+ return { filePath } ;
312+ } ) ,
313+
314+ openChatPanel : procedure
315+ . input (
316+ z . object ( {
317+ sessionId : z . string ( ) ,
318+ viewColumn : z . number ( ) . describe ( "ViewColumn: 1=Active, 2=Beside" ) ,
319+ } )
320+ )
321+ . resolve ( ( { ctx, input } ) => {
322+ ctx . openChatPanel ( input . sessionId , input . viewColumn ) ;
323+ return { ok : true } ;
324+ } ) ,
325+
326+ openChatInNewWindow : procedure . input ( z . object ( { sessionId : z . string ( ) } ) ) . resolve ( async ( { ctx, input } ) => {
327+ // Open in current window's editor area (fills it like a dedicated window)
328+ ctx . openChatPanel ( input . sessionId , vscodeApi . ViewColumn . Active ) ;
329+ return { ok : true } ;
330+ } ) ,
331+
332+ openExternal : procedure . input ( z . object ( { url : z . string ( ) } ) ) . resolve ( async ( { input } ) => {
333+ await vscodeApi . env . openExternal ( vscodeApi . Uri . parse ( input . url ) ) ;
334+ return { ok : true } ;
335+ } ) ,
267336} ) ;
268337
269338export type AppRouter = typeof appRouter ;
0 commit comments