@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 +49 -0
- package/copilot/mcp-config.json +65 -24
- package/package.json +4 -2
- package/scripts/hooks/evaluate-session.js +0 -78
- package/scripts/hooks/post-tool-use.ps1 +0 -55
- package/scripts/hooks/post-tool-use.sh +0 -68
- package/scripts/hooks/pre-compact.js +0 -48
- package/scripts/hooks/session-end.js +0 -82
- package/scripts/hooks/session-start.js +0 -61
- package/scripts/hooks/suggest-compact.js +0 -60
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:
|
package/copilot/mcp-config.json
CHANGED
|
@@ -1,103 +1,144 @@
|
|
|
1
1
|
{
|
|
2
2
|
"mcpServers": {
|
|
3
3
|
"context7": {
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"
|
|
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.
|
|
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
|
-
});
|