@@ -76,8 +76,27 @@ function scanClaudeFiles(projectPath: string): ClaudeFileEntry[] {
7676
7777 addFiles ( path . join ( claudeDir , 'commands' ) , 'commands' , entries )
7878
79+ addFiles ( path . join ( claudeDir , 'scripts' ) , 'hooks' , entries )
80+
81+ const keybindingsJson = path . join ( claudeDir , 'keybindings.json' )
82+ if ( fs . existsSync ( keybindingsJson ) ) {
83+ entries . push ( { name : 'keybindings.json' , path : keybindingsJson , section : 'global' } )
84+ }
85+
7986 const projectKey = projectPath . replace ( / \/ / g, '-' )
80- const projectMemDir = path . join ( claudeDir , 'projects' , projectKey , 'memory' )
87+ const projectConfigDir = path . join ( claudeDir , 'projects' , projectKey )
88+
89+ const projectSettingsJson = path . join ( projectConfigDir , 'settings.json' )
90+ if ( fs . existsSync ( projectSettingsJson ) ) {
91+ entries . push ( { name : 'settings.json (project)' , path : projectSettingsJson , section : 'project' } )
92+ }
93+
94+ const projectClaudeMdGlobal = path . join ( projectConfigDir , 'CLAUDE.md' )
95+ if ( fs . existsSync ( projectClaudeMdGlobal ) ) {
96+ entries . push ( { name : 'CLAUDE.md (project config)' , path : projectClaudeMdGlobal , section : 'project' } )
97+ }
98+
99+ const projectMemDir = path . join ( projectConfigDir , 'memory' )
81100 addFiles ( projectMemDir , 'project' , entries )
82101
83102 const projectClaudeDir = path . join ( projectPath , '.claude' )
@@ -103,8 +122,38 @@ function scanClaudeFiles(projectPath: string): ClaudeFileEntry[] {
103122 return entries
104123}
105124
125+ function isAllowedClaudePath ( filePath : string , projectPath ?: string ) : boolean {
126+ const resolved = path . resolve ( filePath )
127+ const claudeDir = path . join ( os . homedir ( ) , '.claude' )
128+ if ( resolved . startsWith ( claudeDir + path . sep ) ) return true
129+ if ( projectPath ) {
130+ const projectClaudeDir = path . join ( path . resolve ( projectPath ) , '.claude' )
131+ if ( resolved . startsWith ( projectClaudeDir + path . sep ) ) return true
132+ if ( resolved === path . join ( path . resolve ( projectPath ) , 'CLAUDE.md' ) ) return true
133+ }
134+ return false
135+ }
136+
106137export function registerClaudeConfigHandlers ( ) : void {
107138 ipcMain . handle ( 'claude:scan-files' , ( _event , projectPath : string ) : ClaudeFileEntry [ ] => {
108139 return scanClaudeFiles ( projectPath )
109140 } )
141+
142+ ipcMain . handle ( 'claude:read-file' , ( _event , filePath : string , projectPath : string ) : string => {
143+ const resolved = path . resolve ( filePath )
144+ if ( ! isAllowedClaudePath ( resolved , projectPath ) ) throw new Error ( 'Path not allowed' )
145+ return fs . readFileSync ( resolved , 'utf-8' )
146+ } )
147+
148+ ipcMain . handle ( 'claude:write-file' , ( _event , filePath : string , content : string , projectPath : string ) : void => {
149+ const resolved = path . resolve ( filePath )
150+ if ( ! isAllowedClaudePath ( resolved , projectPath ) ) throw new Error ( 'Path not allowed' )
151+ fs . writeFileSync ( resolved , content , 'utf-8' )
152+ } )
153+
154+ ipcMain . handle ( 'claude:delete-file' , ( _event , filePath : string , projectPath : string ) : void => {
155+ const resolved = path . resolve ( filePath )
156+ if ( ! isAllowedClaudePath ( resolved , projectPath ) ) throw new Error ( 'Path not allowed' )
157+ fs . unlinkSync ( resolved )
158+ } )
110159}
0 commit comments