@fyow/copilot-everything 1.0.11 → 1.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -91,6 +91,8 @@ copilot-everything <command> [options]
91
91
  |--------|-------------|
92
92
  | --ai type | Target AI platform: copilot (default), claude, or all |
93
93
  | --force | Overwrite existing files |
94
+ | --force-mcp | Overwrite ~/.copilot/mcp-config.json (contains API keys) |
95
+ | -y, --yes | Skip confirmation prompts for --force flags |
94
96
  | --skip-agents | Skip agent installation |
95
97
  | --skip-skills | Skip skills installation |
96
98
  | --skip-hooks | Skip hooks installation |
@@ -106,6 +108,12 @@ copilot-everything init
106
108
  # Initialize with force overwrite
107
109
  copilot-everything init --force
108
110
 
111
+ # Overwrite MCP config (API keys will be auto-filled from environment)
112
+ copilot-everything init --force-mcp
113
+
114
+ # Skip confirmation prompts (for CI/scripts)
115
+ copilot-everything init --force-mcp -y
116
+
109
117
  # Skip certain components
110
118
  copilot-everything init --skip-hooks --skip-skills
111
119
 
@@ -166,6 +174,47 @@ VS Code uses its own built-in tools (`read_file`, `run_in_terminal`, etc.) which
166
174
 
167
175
  ---
168
176
 
177
+ ## MCP Server Configuration
178
+
179
+ The init command installs a comprehensive MCP config template to `~/.copilot/mcp-config.json` with 20+ servers:
180
+
181
+ - **AI/Docs**: context7, next-devtools, cloudflare-docs
182
+ - **Browser**: playwright, chrome-devtools, puppeteer
183
+ - **DevOps**: github, vercel, railway, docker, sentry
184
+ - **Database**: postgres, sqlite, redis, supabase
185
+ - **Utilities**: memory, firecrawl, fetch, filesystem, git, sequential-thinking
186
+
187
+ ### Auto-fill Environment Variables
188
+
189
+ When installing MCP config, the CLI automatically detects and substitutes environment variables:
190
+
191
+ ```bash
192
+ # Set your API keys in environment
193
+ export GITHUB_TOKEN=ghp_xxx
194
+ export FIRECRAWL_API_KEY=fc_xxx
195
+ export CONTEXT7_API_KEY=xxx
196
+
197
+ # Install with auto-fill
198
+ copilot-everything init --force-mcp
199
+
200
+ # Output:
201
+ # ✅ MCP config: installed to ~/.copilot/mcp-config.json
202
+ # 🔑 Auto-filled from environment: GITHUB_TOKEN, FIRECRAWL_API_KEY, CONTEXT7_API_KEY
203
+ # 📝 Need to configure: SUPABASE_PROJECT_REF, POSTGRES_CONNECTION_STRING, ...
204
+ ```
205
+
206
+ Supported environment variables:
207
+ - `GITHUB_TOKEN` - GitHub Personal Access Token
208
+ - `CONTEXT7_API_KEY` - Context7 API key
209
+ - `FIRECRAWL_API_KEY` - Firecrawl API key
210
+ - `SUPABASE_PROJECT_REF` - Supabase project reference
211
+ - `POSTGRES_CONNECTION_STRING` - PostgreSQL connection string
212
+ - `SQLITE_DB_PATH` - SQLite database path
213
+ - `REDIS_URL` - Redis connection URL
214
+ - `WORKSPACE_PATH` - Filesystem workspace path
215
+
216
+ ---
217
+
169
218
  ## Customization
170
219
 
171
220
  After installation, customize the configs for your project:
@@ -1,103 +1,144 @@
1
1
  {
2
2
  "mcpServers": {
3
3
  "context7": {
4
- "command": "npx",
5
- "args": ["-y", "@upstash/context7-mcp@latest"],
6
- "env": {
4
+ "type": "http",
5
+ "url": "https://mcp.context7.com/mcp",
6
+ "headers": {
7
7
  "CONTEXT7_API_KEY": "${CONTEXT7_API_KEY}"
8
- }
8
+ },
9
+ "tools": ["*"]
9
10
  },
10
11
  "playwright": {
12
+ "type": "stdio",
11
13
  "command": "npx",
12
- "args": ["-y", "@playwright/mcp@latest"]
14
+ "args": ["-y", "@playwright/mcp@latest"],
15
+ "tools": ["*"]
13
16
  },
14
17
  "sequential-thinking": {
18
+ "type": "stdio",
15
19
  "command": "npx",
16
- "args": ["-y", "@modelcontextprotocol/server-sequential-thinking"]
20
+ "args": ["-y", "@modelcontextprotocol/server-sequential-thinking"],
21
+ "tools": ["*"]
17
22
  },
18
23
  "chrome-devtools": {
24
+ "type": "stdio",
19
25
  "command": "npx",
20
- "args": ["-y", "chrome-devtools-mcp"]
26
+ "args": ["-y", "chrome-devtools-mcp@latest"],
27
+ "tools": ["*"]
21
28
  },
22
29
  "next-devtools": {
30
+ "type": "stdio",
23
31
  "command": "npx",
24
- "args": ["-y", "next-devtools-mcp@latest"]
32
+ "args": ["-y", "next-devtools-mcp@latest"],
33
+ "tools": ["*"]
25
34
  },
26
35
  "github": {
36
+ "type": "stdio",
27
37
  "command": "npx",
28
38
  "args": ["-y", "@modelcontextprotocol/server-github"],
29
39
  "env": {
30
40
  "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
31
- }
41
+ },
42
+ "tools": ["*"]
32
43
  },
33
44
  "memory": {
45
+ "type": "stdio",
34
46
  "command": "npx",
35
- "args": ["-y", "@modelcontextprotocol/server-memory"]
47
+ "args": ["-y", "@modelcontextprotocol/server-memory"],
48
+ "tools": ["*"]
36
49
  },
37
50
  "firecrawl": {
51
+ "type": "stdio",
38
52
  "command": "npx",
39
53
  "args": ["-y", "firecrawl-mcp"],
40
54
  "env": {
41
55
  "FIRECRAWL_API_KEY": "${FIRECRAWL_API_KEY}"
42
- }
56
+ },
57
+ "tools": ["*"]
43
58
  },
44
59
  "supabase": {
60
+ "type": "stdio",
45
61
  "command": "npx",
46
- "args": ["-y", "@supabase/mcp-server-supabase@latest", "--project-ref=${SUPABASE_PROJECT_REF}"]
62
+ "args": ["-y", "@supabase/mcp-server-supabase@latest", "--project-ref=${SUPABASE_PROJECT_REF}"],
63
+ "tools": ["*"]
47
64
  },
48
65
  "vercel": {
49
66
  "type": "http",
50
- "url": "https://mcp.vercel.com"
67
+ "url": "https://mcp.vercel.com",
68
+ "headers": {},
69
+ "tools": ["*"]
51
70
  },
52
71
  "railway": {
72
+ "type": "stdio",
53
73
  "command": "npx",
54
- "args": ["-y", "@railway/mcp-server"]
74
+ "args": ["-y", "@railway/mcp-server"],
75
+ "tools": ["*"]
55
76
  },
56
77
  "cloudflare-docs": {
57
78
  "type": "http",
58
- "url": "https://docs.mcp.cloudflare.com/mcp"
79
+ "url": "https://docs.mcp.cloudflare.com/mcp",
80
+ "headers": {},
81
+ "tools": ["*"]
59
82
  },
60
83
  "filesystem": {
84
+ "type": "stdio",
61
85
  "command": "npx",
62
- "args": ["-y", "@modelcontextprotocol/server-filesystem", "${WORKSPACE_PATH}"]
86
+ "args": ["-y", "@modelcontextprotocol/server-filesystem", "${WORKSPACE_PATH}"],
87
+ "tools": ["*"]
63
88
  },
64
89
  "git": {
90
+ "type": "stdio",
65
91
  "command": "uvx",
66
- "args": ["mcp-server-git"]
92
+ "args": ["mcp-server-git"],
93
+ "tools": ["*"]
67
94
  },
68
95
  "postgres": {
96
+ "type": "stdio",
69
97
  "command": "npx",
70
- "args": ["-y", "@modelcontextprotocol/server-postgres", "${POSTGRES_CONNECTION_STRING}"]
98
+ "args": ["-y", "@modelcontextprotocol/server-postgres", "${POSTGRES_CONNECTION_STRING}"],
99
+ "tools": ["*"]
71
100
  },
72
101
  "sqlite": {
102
+ "type": "stdio",
73
103
  "command": "npx",
74
- "args": ["-y", "@modelcontextprotocol/server-sqlite", "--db-path", "${SQLITE_DB_PATH}"]
104
+ "args": ["-y", "@modelcontextprotocol/server-sqlite", "--db-path", "${SQLITE_DB_PATH}"],
105
+ "tools": ["*"]
75
106
  },
76
107
  "redis": {
108
+ "type": "stdio",
77
109
  "command": "npx",
78
110
  "args": ["-y", "@modelcontextprotocol/server-redis"],
79
111
  "env": {
80
112
  "REDIS_URL": "${REDIS_URL}"
81
- }
113
+ },
114
+ "tools": ["*"]
82
115
  },
83
116
  "puppeteer": {
117
+ "type": "stdio",
84
118
  "command": "npx",
85
- "args": ["-y", "@modelcontextprotocol/server-puppeteer"]
119
+ "args": ["-y", "@modelcontextprotocol/server-puppeteer"],
120
+ "tools": ["*"]
86
121
  },
87
122
  "fetch": {
123
+ "type": "stdio",
88
124
  "command": "npx",
89
- "args": ["-y", "@modelcontextprotocol/server-fetch"]
125
+ "args": ["-y", "@modelcontextprotocol/server-fetch"],
126
+ "tools": ["*"]
90
127
  },
91
128
  "docker": {
129
+ "type": "stdio",
92
130
  "command": "npx",
93
- "args": ["-y", "mcp-server-docker"]
131
+ "args": ["-y", "mcp-server-docker"],
132
+ "tools": ["*"]
94
133
  },
95
134
  "sentry": {
135
+ "type": "stdio",
96
136
  "command": "npx",
97
137
  "args": ["-y", "@modelcontextprotocol/server-sentry"],
98
138
  "env": {
99
139
  "SENTRY_AUTH_TOKEN": "${SENTRY_AUTH_TOKEN}"
100
- }
140
+ },
141
+ "tools": ["*"]
101
142
  }
102
143
  }
103
144
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fyow/copilot-everything",
3
- "version": "1.0.11",
3
+ "version": "1.0.13",
4
4
  "description": "Everything you need for GitHub Copilot CLI - agents, skills, instructions, and hooks configurations",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -12,7 +12,9 @@
12
12
  "files": [
13
13
  "src/",
14
14
  ".github/",
15
- "scripts/",
15
+ "scripts/lib/",
16
+ "scripts/migrate-to-copilot.js",
17
+ "scripts/setup-package-manager.js",
16
18
  "AGENTS.md",
17
19
  "copilot/"
18
20
  ],
@@ -1,78 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Continuous Learning - Session Evaluator
4
- *
5
- * Cross-platform (Windows, macOS, Linux)
6
- *
7
- * Runs on Stop hook to extract reusable patterns from Claude Code sessions
8
- *
9
- * Why Stop hook instead of UserPromptSubmit:
10
- * - Stop runs once at session end (lightweight)
11
- * - UserPromptSubmit runs every message (heavy, adds latency)
12
- */
13
-
14
- const path = require('path');
15
- const fs = require('fs');
16
- const {
17
- getLearnedSkillsDir,
18
- ensureDir,
19
- readFile,
20
- countInFile,
21
- log
22
- } = require('../lib/utils');
23
-
24
- async function main() {
25
- // Get script directory to find config
26
- const scriptDir = __dirname;
27
- const configFile = path.join(scriptDir, '..', '..', 'skills', 'continuous-learning', 'config.json');
28
-
29
- // Default configuration
30
- let minSessionLength = 10;
31
- let learnedSkillsPath = getLearnedSkillsDir();
32
-
33
- // Load config if exists
34
- const configContent = readFile(configFile);
35
- if (configContent) {
36
- try {
37
- const config = JSON.parse(configContent);
38
- minSessionLength = config.min_session_length || 10;
39
-
40
- if (config.learned_skills_path) {
41
- // Handle ~ in path
42
- learnedSkillsPath = config.learned_skills_path.replace(/^~/, require('os').homedir());
43
- }
44
- } catch {
45
- // Invalid config, use defaults
46
- }
47
- }
48
-
49
- // Ensure learned skills directory exists
50
- ensureDir(learnedSkillsPath);
51
-
52
- // Get transcript path from environment (set by Claude Code)
53
- const transcriptPath = process.env.CLAUDE_TRANSCRIPT_PATH;
54
-
55
- if (!transcriptPath || !fs.existsSync(transcriptPath)) {
56
- process.exit(0);
57
- }
58
-
59
- // Count user messages in session
60
- const messageCount = countInFile(transcriptPath, /"type":"user"/g);
61
-
62
- // Skip short sessions
63
- if (messageCount < minSessionLength) {
64
- log(`[ContinuousLearning] Session too short (${messageCount} messages), skipping`);
65
- process.exit(0);
66
- }
67
-
68
- // Signal to Claude that session should be evaluated for extractable patterns
69
- log(`[ContinuousLearning] Session has ${messageCount} messages - evaluate for extractable patterns`);
70
- log(`[ContinuousLearning] Save learned skills to: ${learnedSkillsPath}`);
71
-
72
- process.exit(0);
73
- }
74
-
75
- main().catch(err => {
76
- console.error('[ContinuousLearning] Error:', err.message);
77
- process.exit(0);
78
- });
@@ -1,55 +0,0 @@
1
- # Post tool use hook for Copilot CLI (PowerShell version)
2
- # Handles formatting, type checking, and warnings after tool execution
3
-
4
- param()
5
-
6
- $input = $input | Out-String
7
-
8
- try {
9
- $data = $input | ConvertFrom-Json
10
- $toolName = $data.tool_name
11
- $filePath = $data.tool_input.file_path
12
- } catch {
13
- $toolName = ""
14
- $filePath = ""
15
- }
16
-
17
- # If editing JS/TS file, run prettier
18
- if ($filePath -match '\.(ts|tsx|js|jsx)$' -and (Test-Path $filePath)) {
19
- try {
20
- npx prettier --write $filePath 2>$null
21
- } catch {
22
- # Ignore prettier errors
23
- }
24
- }
25
-
26
- # If editing TS file, run type check
27
- if ($filePath -match '\.(ts|tsx)$' -and (Test-Path $filePath)) {
28
- $dir = Split-Path $filePath -Parent
29
- while ($dir -ne "" -and -not (Test-Path "$dir\tsconfig.json")) {
30
- $dir = Split-Path $dir -Parent
31
- }
32
-
33
- if (Test-Path "$dir\tsconfig.json") {
34
- try {
35
- $errors = npx tsc --noEmit --pretty false 2>&1 | Select-String $filePath | Select-Object -First 5
36
- if ($errors) {
37
- Write-Host "[Hook] TypeScript errors in $filePath`:" -ForegroundColor Yellow
38
- $errors | ForEach-Object { Write-Host $_.Line -ForegroundColor Yellow }
39
- }
40
- } catch {
41
- # Ignore tsc errors
42
- }
43
- }
44
- }
45
-
46
- # Check for console.log in modified files
47
- if ($filePath -match '\.(ts|tsx|js|jsx)$' -and (Test-Path $filePath)) {
48
- $consoleLogLines = Select-String -Path $filePath -Pattern "console\.log" | Select-Object -First 3
49
- if ($consoleLogLines) {
50
- Write-Host "[Hook] WARNING: console.log found in $filePath - remove before commit" -ForegroundColor Yellow
51
- }
52
- }
53
-
54
- # Output original input unchanged
55
- Write-Output $input
@@ -1,68 +0,0 @@
1
- #!/bin/bash
2
- # Post tool use hook for Copilot CLI
3
- # Handles formatting, type checking, and warnings after tool execution
4
-
5
- set -e
6
-
7
- # Read JSON input from stdin
8
- input=$(cat)
9
-
10
- # Extract tool information
11
- tool_name=$(echo "$input" | node -e "
12
- let d='';
13
- process.stdin.on('data',c=>d+=c);
14
- process.stdin.on('end',()=>{
15
- try {
16
- const data = JSON.parse(d);
17
- console.log(data.tool_name || data.tool || '');
18
- } catch(e) {
19
- console.log('');
20
- }
21
- });
22
- " <<< "$input" 2>/dev/null || echo "")
23
-
24
- file_path=$(echo "$input" | node -e "
25
- let d='';
26
- process.stdin.on('data',c=>d+=c);
27
- process.stdin.on('end',()=>{
28
- try {
29
- const data = JSON.parse(d);
30
- console.log(data.tool_input?.file_path || data.file_path || '');
31
- } catch(e) {
32
- console.log('');
33
- }
34
- });
35
- " <<< "$input" 2>/dev/null || echo "")
36
-
37
- # If editing JS/TS file, run prettier
38
- if [[ "$file_path" =~ \.(ts|tsx|js|jsx)$ ]] && [ -f "$file_path" ]; then
39
- if command -v npx &> /dev/null; then
40
- npx prettier --write "$file_path" 2>/dev/null || true
41
- fi
42
- fi
43
-
44
- # If editing TS file, run type check
45
- if [[ "$file_path" =~ \.(ts|tsx)$ ]] && [ -f "$file_path" ]; then
46
- dir=$(dirname "$file_path")
47
- while [ "$dir" != "/" ] && [ ! -f "$dir/tsconfig.json" ]; do
48
- dir=$(dirname "$dir")
49
- done
50
-
51
- if [ -f "$dir/tsconfig.json" ]; then
52
- errors=$(npx tsc --noEmit --pretty false 2>&1 | grep "$file_path" | head -5 || true)
53
- if [ -n "$errors" ]; then
54
- echo "[Hook] TypeScript errors in $file_path:" >&2
55
- echo "$errors" >&2
56
- fi
57
- fi
58
- fi
59
-
60
- # Check for console.log in modified files
61
- if [[ "$file_path" =~ \.(ts|tsx|js|jsx)$ ]] && [ -f "$file_path" ]; then
62
- if grep -n "console.log" "$file_path" 2>/dev/null | head -3; then
63
- echo "[Hook] WARNING: console.log found in $file_path - remove before commit" >&2
64
- fi
65
- fi
66
-
67
- # Output original input unchanged
68
- echo "$input"
@@ -1,48 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * PreCompact Hook - Save state before context compaction
4
- *
5
- * Cross-platform (Windows, macOS, Linux)
6
- *
7
- * Runs before Claude compacts context, giving you a chance to
8
- * preserve important state that might get lost in summarization.
9
- */
10
-
11
- const path = require('path');
12
- const {
13
- getSessionsDir,
14
- getDateTimeString,
15
- getTimeString,
16
- findFiles,
17
- ensureDir,
18
- appendFile,
19
- log
20
- } = require('../lib/utils');
21
-
22
- async function main() {
23
- const sessionsDir = getSessionsDir();
24
- const compactionLog = path.join(sessionsDir, 'compaction-log.txt');
25
-
26
- ensureDir(sessionsDir);
27
-
28
- // Log compaction event with timestamp
29
- const timestamp = getDateTimeString();
30
- appendFile(compactionLog, `[${timestamp}] Context compaction triggered\n`);
31
-
32
- // If there's an active session file, note the compaction
33
- const sessions = findFiles(sessionsDir, '*.tmp');
34
-
35
- if (sessions.length > 0) {
36
- const activeSession = sessions[0].path;
37
- const timeStr = getTimeString();
38
- appendFile(activeSession, `\n---\n**[Compaction occurred at ${timeStr}]** - Context was summarized\n`);
39
- }
40
-
41
- log('[PreCompact] State saved before compaction');
42
- process.exit(0);
43
- }
44
-
45
- main().catch(err => {
46
- console.error('[PreCompact] Error:', err.message);
47
- process.exit(0);
48
- });
@@ -1,82 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Stop Hook (Session End) - Persist learnings when session ends
4
- *
5
- * Cross-platform (Windows, macOS, Linux)
6
- *
7
- * Runs when Claude session ends. Creates/updates session log file
8
- * with timestamp for continuity tracking.
9
- */
10
-
11
- const path = require('path');
12
- const fs = require('fs');
13
- const {
14
- getSessionsDir,
15
- getDateString,
16
- getTimeString,
17
- ensureDir,
18
- readFile,
19
- writeFile,
20
- replaceInFile,
21
- log
22
- } = require('../lib/utils');
23
-
24
- async function main() {
25
- const sessionsDir = getSessionsDir();
26
- const today = getDateString();
27
- const sessionFile = path.join(sessionsDir, `${today}-session.tmp`);
28
-
29
- ensureDir(sessionsDir);
30
-
31
- const currentTime = getTimeString();
32
-
33
- // If session file exists for today, update the end time
34
- if (fs.existsSync(sessionFile)) {
35
- const success = replaceInFile(
36
- sessionFile,
37
- /\*\*Last Updated:\*\*.*/,
38
- `**Last Updated:** ${currentTime}`
39
- );
40
-
41
- if (success) {
42
- log(`[SessionEnd] Updated session file: ${sessionFile}`);
43
- }
44
- } else {
45
- // Create new session file with template
46
- const template = `# Session: ${today}
47
- **Date:** ${today}
48
- **Started:** ${currentTime}
49
- **Last Updated:** ${currentTime}
50
-
51
- ---
52
-
53
- ## Current State
54
-
55
- [Session context goes here]
56
-
57
- ### Completed
58
- - [ ]
59
-
60
- ### In Progress
61
- - [ ]
62
-
63
- ### Notes for Next Session
64
- -
65
-
66
- ### Context to Load
67
- \`\`\`
68
- [relevant files]
69
- \`\`\`
70
- `;
71
-
72
- writeFile(sessionFile, template);
73
- log(`[SessionEnd] Created session file: ${sessionFile}`);
74
- }
75
-
76
- process.exit(0);
77
- }
78
-
79
- main().catch(err => {
80
- console.error('[SessionEnd] Error:', err.message);
81
- process.exit(0);
82
- });
@@ -1,61 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * SessionStart Hook - Load previous context on new session
4
- *
5
- * Cross-platform (Windows, macOS, Linux)
6
- *
7
- * Runs when a new Claude session starts. Checks for recent session
8
- * files and notifies Claude of available context to load.
9
- */
10
-
11
- const path = require('path');
12
- const {
13
- getSessionsDir,
14
- getLearnedSkillsDir,
15
- findFiles,
16
- ensureDir,
17
- log
18
- } = require('../lib/utils');
19
- const { getPackageManager, getSelectionPrompt } = require('../lib/package-manager');
20
-
21
- async function main() {
22
- const sessionsDir = getSessionsDir();
23
- const learnedDir = getLearnedSkillsDir();
24
-
25
- // Ensure directories exist
26
- ensureDir(sessionsDir);
27
- ensureDir(learnedDir);
28
-
29
- // Check for recent session files (last 7 days)
30
- const recentSessions = findFiles(sessionsDir, '*.tmp', { maxAge: 7 });
31
-
32
- if (recentSessions.length > 0) {
33
- const latest = recentSessions[0];
34
- log(`[SessionStart] Found ${recentSessions.length} recent session(s)`);
35
- log(`[SessionStart] Latest: ${latest.path}`);
36
- }
37
-
38
- // Check for learned skills
39
- const learnedSkills = findFiles(learnedDir, '*.md');
40
-
41
- if (learnedSkills.length > 0) {
42
- log(`[SessionStart] ${learnedSkills.length} learned skill(s) available in ${learnedDir}`);
43
- }
44
-
45
- // Detect and report package manager
46
- const pm = getPackageManager();
47
- log(`[SessionStart] Package manager: ${pm.name} (${pm.source})`);
48
-
49
- // If package manager was detected via fallback, show selection prompt
50
- if (pm.source === 'fallback' || pm.source === 'default') {
51
- log('[SessionStart] No package manager preference found.');
52
- log(getSelectionPrompt());
53
- }
54
-
55
- process.exit(0);
56
- }
57
-
58
- main().catch(err => {
59
- console.error('[SessionStart] Error:', err.message);
60
- process.exit(0); // Don't block on errors
61
- });
@@ -1,60 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Strategic Compact Suggester
4
- *
5
- * Cross-platform (Windows, macOS, Linux)
6
- *
7
- * Runs on PreToolUse or periodically to suggest manual compaction at logical intervals
8
- *
9
- * Why manual over auto-compact:
10
- * - Auto-compact happens at arbitrary points, often mid-task
11
- * - Strategic compacting preserves context through logical phases
12
- * - Compact after exploration, before execution
13
- * - Compact after completing a milestone, before starting next
14
- */
15
-
16
- const path = require('path');
17
- const fs = require('fs');
18
- const {
19
- getTempDir,
20
- readFile,
21
- writeFile,
22
- log
23
- } = require('../lib/utils');
24
-
25
- async function main() {
26
- // Track tool call count (increment in a temp file)
27
- // Use a session-specific counter file based on PID from parent process
28
- // or session ID from environment
29
- const sessionId = process.env.CLAUDE_SESSION_ID || process.ppid || 'default';
30
- const counterFile = path.join(getTempDir(), `claude-tool-count-${sessionId}`);
31
- const threshold = parseInt(process.env.COMPACT_THRESHOLD || '50', 10);
32
-
33
- let count = 1;
34
-
35
- // Read existing count or start at 1
36
- const existing = readFile(counterFile);
37
- if (existing) {
38
- count = parseInt(existing.trim(), 10) + 1;
39
- }
40
-
41
- // Save updated count
42
- writeFile(counterFile, String(count));
43
-
44
- // Suggest compact after threshold tool calls
45
- if (count === threshold) {
46
- log(`[StrategicCompact] ${threshold} tool calls reached - consider /compact if transitioning phases`);
47
- }
48
-
49
- // Suggest at regular intervals after threshold
50
- if (count > threshold && count % 25 === 0) {
51
- log(`[StrategicCompact] ${count} tool calls - good checkpoint for /compact if context is stale`);
52
- }
53
-
54
- process.exit(0);
55
- }
56
-
57
- main().catch(err => {
58
- console.error('[StrategicCompact] Error:', err.message);
59
- process.exit(0);
60
- });