@@ -3,11 +3,13 @@ import { readFileSync, writeFileSync, existsSync, mkdirSync, appendFileSync, cop
33import { homedir } from 'os' ;
44import { join } from 'path' ;
55import { createInterface } from 'readline' ;
6+ import { getDefaultIgnoreContent } from '../core/ignore.js' ;
67
78const CLAUDE_DIR = join ( homedir ( ) , '.claude' ) ;
89const SETTINGS_PATH = join ( CLAUDE_DIR , 'settings.json' ) ;
910const MCP_JSON_PATH = join ( CLAUDE_DIR , 'mcp.json' ) ;
1011const CLAUDE_MD_PATH = join ( CLAUDE_DIR , 'CLAUDE.md' ) ;
12+ const GLOBAL_IGNORE_PATH = join ( homedir ( ) , '.threadlinkingignore' ) ;
1113
1214const POST_TOOL_USE_HOOK_CONFIG = {
1315 matcher : 'Edit|Write' ,
@@ -86,6 +88,7 @@ interface SetupStatus {
8688 sessionStartHookInstalled : boolean ;
8789 mcpConfigured : boolean ;
8890 claudeMdPresent : boolean ;
91+ ignoreFilePresent : boolean ;
8992 settingsJsonValid : boolean ;
9093 mcpJsonValid : boolean ;
9194}
@@ -175,13 +178,17 @@ function checkStatus(): SetupStatus {
175178 claudeMdPresent = content . toLowerCase ( ) . includes ( 'threadlinking' ) ;
176179 }
177180
181+ // Check ignore file
182+ const ignoreFilePresent = existsSync ( GLOBAL_IGNORE_PATH ) ;
183+
178184 return {
179185 claudeCodeDetected,
180186 claudeDirExists,
181187 postToolUseHookInstalled,
182188 sessionStartHookInstalled,
183189 mcpConfigured,
184190 claudeMdPresent,
191+ ignoreFilePresent,
185192 settingsJsonValid,
186193 mcpJsonValid,
187194 } ;
@@ -309,6 +316,7 @@ function printStatus(status: SetupStatus): void {
309316 console . log ( ` SessionStart hook: ${ status . sessionStartHookInstalled ? '\u2713 Installed' : '\u2717 Not installed' } ` ) ;
310317 console . log ( ` MCP server: ${ status . mcpConfigured ? '\u2713 Configured (mcp.json)' : '\u2717 Not configured' } ` ) ;
311318 console . log ( ` CLAUDE.md: ${ status . claudeMdPresent ? '\u2713 Present' : '\u2717 Not present' } ` ) ;
319+ console . log ( ` Ignore file: ${ status . ignoreFilePresent ? '\u2713 Present' : '\u2717 Not present' } ` ) ;
312320
313321 if ( ! status . settingsJsonValid && existsSync ( SETTINGS_PATH ) ) {
314322 console . log ( ` settings.json: \u2717 Invalid JSON` ) ;
@@ -371,7 +379,7 @@ export const initCommand = new Command('init')
371379 }
372380
373381 // Step 1: PostToolUse hook
374- console . log ( '[1/4 ] PostToolUse hook (auto-tracks files you create)' ) ;
382+ console . log ( '[1/5 ] PostToolUse hook (auto-tracks files you create)' ) ;
375383 if ( status . postToolUseHookInstalled ) {
376384 console . log ( ' Status: Already installed' ) ;
377385 console . log ( ' \u2713 Skipping\n' ) ;
@@ -398,7 +406,7 @@ export const initCommand = new Command('init')
398406 }
399407
400408 // Step 2: SessionStart hook
401- console . log ( '[2/4 ] SessionStart hook (shows context at session start)' ) ;
409+ console . log ( '[2/5 ] SessionStart hook (shows context at session start)' ) ;
402410 if ( status . sessionStartHookInstalled ) {
403411 console . log ( ' Status: Already installed' ) ;
404412 console . log ( ' \u2713 Skipping\n' ) ;
@@ -419,7 +427,7 @@ export const initCommand = new Command('init')
419427 }
420428
421429 // Step 3: MCP Server (uses separate mcp.json file)
422- console . log ( '[3/4 ] MCP Server (gives Claude direct access to threadlinking tools)' ) ;
430+ console . log ( '[3/5 ] MCP Server (gives Claude direct access to threadlinking tools)' ) ;
423431 let { mcpJson, valid : mcpJsonValid } = loadMcpJson ( ) ;
424432
425433 // Handle invalid mcp.json
@@ -475,7 +483,7 @@ export const initCommand = new Command('init')
475483 }
476484
477485 // Step 4: CLAUDE.md
478- console . log ( '[4/4 ] CLAUDE.md instructions (teaches Claude when/how to use threadlinking)' ) ;
486+ console . log ( '[4/5 ] CLAUDE.md instructions (teaches Claude when/how to use threadlinking)' ) ;
479487 if ( status . claudeMdPresent ) {
480488 console . log ( ' Status: Already present' ) ;
481489 console . log ( ' \u2713 Skipping\n' ) ;
@@ -494,6 +502,26 @@ export const initCommand = new Command('init')
494502 }
495503 }
496504
505+ // Step 5: Ignore file
506+ console . log ( '[5/5] Ignore file (filters noise from pending files list)' ) ;
507+ if ( status . ignoreFilePresent ) {
508+ console . log ( ' Status: Already present' ) ;
509+ console . log ( ' \u2713 Skipping\n' ) ;
510+ } else {
511+ console . log ( ' Status: Not present' ) ;
512+ let shouldInstall = true ;
513+ if ( options . interactive !== false ) {
514+ const answer = await ask ( ' Create ~/.threadlinkingignore? (Y/n) ' ) ;
515+ shouldInstall = answer !== 'n' && answer !== 'no' ;
516+ }
517+ if ( shouldInstall ) {
518+ writeFileSync ( GLOBAL_IGNORE_PATH , getDefaultIgnoreContent ( ) , 'utf-8' ) ;
519+ console . log ( ' \u2713 Ignore file created\n' ) ;
520+ } else {
521+ console . log ( ' Skipped\n' ) ;
522+ }
523+ }
524+
497525 // Done
498526 console . log ( 'Done! Threadlinking is fully configured.\n' ) ;
499527 console . log ( 'Start a new Claude Code session to begin.' ) ;
0 commit comments