@fyow/copilot-everything 1.0.0 → 1.0.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fyow/copilot-everything",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
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,6 +12,7 @@
12
12
  "files": [
13
13
  "src/",
14
14
  ".github/",
15
+ "scripts/",
15
16
  "AGENTS.md",
16
17
  "copilot/"
17
18
  ],
@@ -0,0 +1,78 @@
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
+ });
@@ -0,0 +1,55 @@
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
@@ -0,0 +1,68 @@
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"
@@ -0,0 +1,48 @@
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
+ });
@@ -0,0 +1,82 @@
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
+ });
@@ -0,0 +1,61 @@
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
+ });
@@ -0,0 +1,60 @@
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
+ });