@@ -22,7 +22,6 @@ import { execSync } from 'child_process';
2222const CLAUDE_DIR = join ( homedir ( ) , '.claude' ) ;
2323const CLAUDE_CONFIG_FILE = join ( CLAUDE_DIR , 'config.json' ) ;
2424const MCP_CONFIG_FILE = join ( CLAUDE_DIR , 'stackmemory-mcp.json' ) ;
25- const HOOKS_JSON = join ( CLAUDE_DIR , 'hooks.json' ) ;
2625
2726interface DiagnosticResult {
2827 name : string ;
@@ -264,39 +263,41 @@ export function createDoctorCommand(): Command {
264263 } ) ;
265264 }
266265
267- // 4. Check Claude hooks
268- if ( existsSync ( HOOKS_JSON ) ) {
269- try {
270- const hooks = JSON . parse ( readFileSync ( HOOKS_JSON , 'utf8' ) ) ;
271- const hasTraceHook = ! ! hooks [ 'tool-use-approval' ] ;
272- if ( hasTraceHook ) {
273- results . push ( {
274- name : 'Claude Hooks' ,
275- status : 'ok' ,
276- message : 'Tool tracing hook installed' ,
277- } ) ;
278- } else {
279- results . push ( {
280- name : 'Claude Hooks' ,
281- status : 'warn' ,
282- message : 'Hooks file exists but tracing not configured' ,
283- fix : 'Run: stackmemory hooks install' ,
284- } ) ;
266+ // 4. Check Claude hooks (settings.json)
267+ {
268+ const settingsFile = join ( homedir ( ) , '.claude' , 'settings.json' ) ;
269+ let hookCount = 0 ;
270+ if ( existsSync ( settingsFile ) ) {
271+ try {
272+ const settings = JSON . parse ( readFileSync ( settingsFile , 'utf8' ) ) ;
273+ if ( settings . hooks ) {
274+ for ( const groups of Object . values ( settings . hooks ) as Array <
275+ Array < { hooks : Array < { command : string } > } >
276+ > ) {
277+ for ( const group of groups ) {
278+ hookCount += group . hooks . length ;
279+ }
280+ }
281+ }
282+ } catch {
283+ // Cannot parse settings.json
285284 }
286- } catch {
285+ }
286+
287+ if ( hookCount > 0 ) {
288+ results . push ( {
289+ name : 'Claude Hooks' ,
290+ status : 'ok' ,
291+ message : `${ hookCount } hooks registered in settings.json` ,
292+ } ) ;
293+ } else {
287294 results . push ( {
288295 name : 'Claude Hooks' ,
289296 status : 'warn' ,
290- message : 'Could not read hooks.json' ,
297+ message : 'No hooks registered in settings.json' ,
298+ fix : 'Run: stackmemory hooks install' ,
291299 } ) ;
292300 }
293- } else {
294- results . push ( {
295- name : 'Claude Hooks' ,
296- status : 'warn' ,
297- message : 'Claude hooks not installed (optional)' ,
298- fix : 'Run: stackmemory hooks install' ,
299- } ) ;
300301 }
301302
302303 // 5. Check MCP tool definitions
@@ -659,7 +660,44 @@ export function createDoctorCommand(): Command {
659660 }
660661 }
661662
662- // 12. Check file permissions
663+ // 12. Check daemon health
664+ {
665+ try {
666+ const { readDaemonStatus } =
667+ await import ( '../../daemon/daemon-config.js' ) ;
668+ const status = readDaemonStatus ( ) ;
669+ if ( status . running ) {
670+ const uptime = status . startedAt
671+ ? Math . round ( ( Date . now ( ) - status . startedAt ) / 1000 / 60 )
672+ : 0 ;
673+ const svcCount = Object . values ( status . services || { } ) . filter (
674+ ( s : { enabled ?: boolean } ) => s . enabled
675+ ) . length ;
676+ results . push ( {
677+ name : 'Background Daemon' ,
678+ status : 'ok' ,
679+ message : `Running (PID: ${ status . pid } , ${ svcCount } services, ${ uptime } min uptime)` ,
680+ } ) ;
681+ } else {
682+ results . push ( {
683+ name : 'Background Daemon' ,
684+ status : 'warn' ,
685+ message :
686+ 'Daemon not running — context auto-save and maintenance disabled' ,
687+ fix : 'Run: stackmemory daemon start' ,
688+ } ) ;
689+ }
690+ } catch {
691+ results . push ( {
692+ name : 'Background Daemon' ,
693+ status : 'warn' ,
694+ message : 'Could not check daemon status' ,
695+ fix : 'Run: stackmemory daemon start' ,
696+ } ) ;
697+ }
698+ }
699+
700+ // 13. Check file permissions
663701 const homeStackmemory = join ( homedir ( ) , '.stackmemory' ) ;
664702 if ( existsSync ( homeStackmemory ) ) {
665703 try {
@@ -701,13 +739,23 @@ export function createDoctorCommand(): Command {
701739 console . log ( chalk . cyan ( ` Fix: ${ result . fix } ` ) ) ;
702740
703741 if ( options . fix && result . status !== 'ok' ) {
704- // Auto-fix logic for specific issues
705- if ( result . fix . includes ( 'stackmemory setup-mcp' ) ) {
706- console . log ( chalk . gray ( ' Attempting auto-fix...' ) ) ;
707- try {
708- execSync ( 'stackmemory setup-mcp' , { stdio : 'inherit' } ) ;
709- } catch {
710- console . log ( chalk . red ( ' Auto-fix failed' ) ) ;
742+ const fixCmds = [
743+ 'stackmemory setup-mcp' ,
744+ 'stackmemory hooks install' ,
745+ 'stackmemory daemon start' ,
746+ ] ;
747+ for ( const cmd of fixCmds ) {
748+ if ( result . fix . includes ( cmd ) ) {
749+ console . log ( chalk . gray ( ` Attempting: ${ cmd } ...` ) ) ;
750+ try {
751+ execSync ( cmd , {
752+ stdio : 'inherit' ,
753+ timeout : 15000 ,
754+ } ) ;
755+ } catch {
756+ console . log ( chalk . red ( ' Auto-fix failed' ) ) ;
757+ }
758+ break ;
711759 }
712760 }
713761 }
0 commit comments