trace-mcp 1.4.1 → 1.5.3
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 +132 -12
- package/dist/cli.js +23119 -20778
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +388 -167
- package/dist/index.js +23786 -21715
- package/dist/index.js.map +1 -1
- package/hooks/trace-mcp-guard.cmd +20 -2
- package/hooks/trace-mcp-guard.sh +41 -2
- package/hooks/trace-mcp-precompact.cmd +33 -0
- package/hooks/trace-mcp-precompact.sh +57 -0
- package/hooks/trace-mcp-worktree.cmd +33 -0
- package/hooks/trace-mcp-worktree.sh +57 -0
- package/package.json +2 -2
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
@echo off
|
|
2
|
-
REM trace-mcp-guard v0.
|
|
2
|
+
REM trace-mcp-guard v0.4.0
|
|
3
3
|
REM trace-mcp PreToolUse guard (Windows)
|
|
4
4
|
REM Blocks Read/Grep/Glob/Bash on source code files - redirects to trace-mcp tools.
|
|
5
5
|
REM Allows: non-code files, Read before Edit, safe Bash commands (git, npm, build, test).
|
|
6
6
|
REM
|
|
7
|
+
REM Consultation markers: trace-mcp server writes markers when tools access files.
|
|
8
|
+
REM If a marker exists, Read is allowed immediately.
|
|
9
|
+
REM
|
|
7
10
|
REM Install: add to ~\.claude\settings.json or .claude\settings.local.json
|
|
8
11
|
REM See README.md for setup instructions.
|
|
9
12
|
|
|
@@ -47,6 +50,14 @@ REM Block code file reads - redirect to trace-mcp
|
|
|
47
50
|
echo "%FILE_PATH%" | findstr /i /r "\.ts$ \.tsx$ \.js$ \.jsx$ \.mjs$ \.cjs$ \.py$ \.pyi$ \.go$ \.rs$ \.java$ \.kt$ \.kts$ \.rb$ \.php$ \.cs$ \.cpp$ \.c$ \.h$ \.hpp$ \.swift$ \.scala$ \.vue$ \.svelte$ \.astro$" >nul 2>&1
|
|
48
51
|
if not %errorlevel%==0 goto :allow
|
|
49
52
|
|
|
53
|
+
REM Check consultation markers (trace-mcp server writes these when get_outline/get_symbol called)
|
|
54
|
+
for /f "usebackq delims=" %%h in (`powershell -NoProfile -Command "[System.BitConverter]::ToString([System.Security.Cryptography.SHA256]::Create().ComputeHash([System.Text.Encoding]::UTF8.GetBytes('%CD%'))).Replace('-','').Substring(0,12).ToLower()"`) do set "PROJ_HASH=%%h"
|
|
55
|
+
set "REL_FOR_HASH=%FILE_PATH%"
|
|
56
|
+
set "REL_FOR_HASH=!REL_FOR_HASH:%CD%\=!"
|
|
57
|
+
set "REL_FOR_HASH=!REL_FOR_HASH:\=/!"
|
|
58
|
+
for /f "usebackq delims=" %%h in (`powershell -NoProfile -Command "[System.BitConverter]::ToString([System.Security.Cryptography.SHA256]::Create().ComputeHash([System.Text.Encoding]::UTF8.GetBytes('!REL_FOR_HASH!'))).Replace('-','').ToLower()"`) do set "FILE_HASH=%%h"
|
|
59
|
+
if exist "%TEMP%\trace-mcp-consulted-!PROJ_HASH!\!FILE_HASH!" goto :allow
|
|
60
|
+
|
|
50
61
|
REM Allow on second attempt (agent needs full content for Edit)
|
|
51
62
|
set "SESSION_ID=default"
|
|
52
63
|
for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "try { (Get-Content '%TMPINPUT%' -Raw | ConvertFrom-Json).session_id } catch { 'default' }"`) do set "SESSION_ID=%%i"
|
|
@@ -54,7 +65,7 @@ set "DENY_DIR=%TEMP%\trace-mcp-guard-%SESSION_ID%"
|
|
|
54
65
|
if not exist "%DENY_DIR%" mkdir "%DENY_DIR%" 2>nul
|
|
55
66
|
|
|
56
67
|
REM Create a hash of the file path for the marker
|
|
57
|
-
for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "[System.BitConverter]::ToString([System.Security.Cryptography.
|
|
68
|
+
for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "[System.BitConverter]::ToString([System.Security.Cryptography.SHA256]::Create().ComputeHash([System.Text.Encoding]::UTF8.GetBytes('%FILE_PATH%'))).Replace('-','').ToLower()"`) do set "MARKER_HASH=%%i"
|
|
58
69
|
set "DENY_MARKER=%DENY_DIR%\%MARKER_HASH%"
|
|
59
70
|
|
|
60
71
|
if exist "%DENY_MARKER%" (
|
|
@@ -137,6 +148,13 @@ REM Allow safe commands
|
|
|
137
148
|
echo "%COMMAND%" | findstr /i /r /c:"^git " /c:"^npm " /c:"^npx " /c:"^pnpm " /c:"^yarn " /c:"^bun " /c:"^node " /c:"^deno " /c:"^cargo " /c:"^go " /c:"^make " /c:"^mvn " /c:"^gradle " /c:"^docker " /c:"^kubectl " /c:"^helm " /c:"^terraform " /c:"^pip " /c:"^poetry " /c:"^uv " /c:"^pytest " /c:"^vitest " /c:"^jest " /c:"^phpunit " /c:"^composer " /c:"^artisan " /c:"^rails " /c:"^bundle " /c:"^mix " /c:"^dotnet " /c:"^cmake " >nul 2>&1
|
|
138
149
|
if %errorlevel%==0 goto :allow
|
|
139
150
|
|
|
151
|
+
REM Block bash commands targeting .env files - prevent secret leakage
|
|
152
|
+
echo "%COMMAND%" | findstr /i /r "\.env" >nul 2>&1
|
|
153
|
+
if %errorlevel%==0 (
|
|
154
|
+
call :deny "Use get_env_vars for .env files - it masks sensitive values (passwords, API keys, tokens)." "trace-mcp alternatives: get_env_vars to list keys + types without exposing secrets. Never access .env files via shell."
|
|
155
|
+
goto :cleanup
|
|
156
|
+
)
|
|
157
|
+
|
|
140
158
|
REM Block code exploration via bash
|
|
141
159
|
set "HAS_EXPLORE=0"
|
|
142
160
|
echo "%COMMAND%" | findstr /i /r "grep rg find cat head tail less more awk sed" >nul 2>&1
|
package/hooks/trace-mcp-guard.sh
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# trace-mcp-guard v0.
|
|
2
|
+
# trace-mcp-guard v0.4.0
|
|
3
3
|
# trace-mcp PreToolUse guard
|
|
4
4
|
# Blocks Read/Grep/Glob/Bash on source code files → redirects to trace-mcp tools.
|
|
5
5
|
# Allows: non-code files, Read before Edit, safe Bash commands (git, npm, build, test).
|
|
6
6
|
#
|
|
7
|
+
# Consultation markers: trace-mcp server writes markers when tools access files
|
|
8
|
+
# (get_outline, get_symbol, etc.). If a marker exists for a file, Read is allowed
|
|
9
|
+
# immediately — the agent already consulted trace-mcp for this file.
|
|
10
|
+
#
|
|
7
11
|
# Install: add to ~/.claude/settings.json or .claude/settings.local.json
|
|
8
12
|
# See README.md for setup instructions.
|
|
9
13
|
|
|
@@ -24,6 +28,11 @@ ENV_FILE_RE='\.env(\.[a-zA-Z0-9._-]+)?$'
|
|
|
24
28
|
# Safe bash command prefixes — never block
|
|
25
29
|
SAFE_BASH_RE='^(git |npm |npx |pnpm |yarn |bun |node |deno |cargo |go |make |mvn |gradle |docker |kubectl |helm |terraform |pip |poetry |uv |pytest |vitest |jest |phpunit |composer |artisan |rails |bundle |mix |dotnet |cmake |ninja |meson )'
|
|
26
30
|
|
|
31
|
+
# Cross-platform sha256 hash (Linux: sha256sum, macOS: shasum)
|
|
32
|
+
file_sha256() {
|
|
33
|
+
echo -n "$1" | sha256sum 2>/dev/null | cut -d' ' -f1 || echo -n "$1" | shasum -a 256 2>/dev/null | cut -d' ' -f1
|
|
34
|
+
}
|
|
35
|
+
|
|
27
36
|
deny() {
|
|
28
37
|
local reason="$1"
|
|
29
38
|
local context="$2"
|
|
@@ -45,6 +54,19 @@ SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // "default"')
|
|
|
45
54
|
DENY_DIR="/tmp/trace-mcp-guard-${SESSION_ID}"
|
|
46
55
|
mkdir -p "$DENY_DIR" 2>/dev/null
|
|
47
56
|
|
|
57
|
+
# Consultation markers: trace-mcp server writes these when get_outline/get_symbol/etc. are called.
|
|
58
|
+
# If a file was already consulted via trace-mcp, allow Read immediately (agent needs full content for Edit).
|
|
59
|
+
# Dir format: $TMPDIR/trace-mcp-consulted-{sha256(projectRoot)[:12]}/{sha256(relPath)}
|
|
60
|
+
PROJECT_ROOT="$(pwd)"
|
|
61
|
+
if command -v sha256sum >/dev/null 2>&1; then
|
|
62
|
+
PROJECT_HASH=$(echo -n "$PROJECT_ROOT" | sha256sum | cut -c1-12)
|
|
63
|
+
elif command -v shasum >/dev/null 2>&1; then
|
|
64
|
+
PROJECT_HASH=$(echo -n "$PROJECT_ROOT" | shasum -a 256 | cut -c1-12)
|
|
65
|
+
else
|
|
66
|
+
PROJECT_HASH=""
|
|
67
|
+
fi
|
|
68
|
+
CONSULTED_DIR="${TMPDIR:-/tmp}/trace-mcp-consulted-${PROJECT_HASH}"
|
|
69
|
+
|
|
48
70
|
# --- Read ---
|
|
49
71
|
if [[ "$TOOL_NAME" == "Read" ]]; then
|
|
50
72
|
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
|
|
@@ -70,8 +92,18 @@ if [[ "$TOOL_NAME" == "Read" ]]; then
|
|
|
70
92
|
|
|
71
93
|
# Block code file reads → redirect to trace-mcp
|
|
72
94
|
if echo "$FILE_PATH" | grep -qiE "$CODE_EXT_RE"; then
|
|
95
|
+
# Compute relative path for consultation marker check (server writes markers keyed by relative path)
|
|
96
|
+
REL_PATH_FOR_HASH=$(echo "$FILE_PATH" | sed "s|^${PROJECT_ROOT}/||")
|
|
97
|
+
CONSULTED_HASH=$(file_sha256 "$REL_PATH_FOR_HASH")
|
|
98
|
+
|
|
99
|
+
# Check if file was already consulted via trace-mcp (get_outline, get_symbol, etc.)
|
|
100
|
+
if [[ -n "$PROJECT_HASH" && -f "$CONSULTED_DIR/$CONSULTED_HASH" ]]; then
|
|
101
|
+
# File was consulted via trace-mcp → allow Read (agent needs full content for Edit)
|
|
102
|
+
exit 0
|
|
103
|
+
fi
|
|
104
|
+
|
|
73
105
|
# Allow on second attempt — agent needs full content for Edit
|
|
74
|
-
DENY_MARKER="$DENY_DIR/$(
|
|
106
|
+
DENY_MARKER="$DENY_DIR/$(file_sha256 "$FILE_PATH")"
|
|
75
107
|
if [[ -f "$DENY_MARKER" ]]; then
|
|
76
108
|
rm -f "$DENY_MARKER"
|
|
77
109
|
exit 0
|
|
@@ -153,6 +185,13 @@ if [[ "$TOOL_NAME" == "Bash" ]]; then
|
|
|
153
185
|
exit 0
|
|
154
186
|
fi
|
|
155
187
|
|
|
188
|
+
# Block bash commands targeting .env files — prevent secret leakage
|
|
189
|
+
if echo "$COMMAND" | grep -qiE "$ENV_FILE_RE"; then
|
|
190
|
+
deny \
|
|
191
|
+
"Use get_env_vars for .env files — it masks sensitive values (passwords, API keys, tokens)." \
|
|
192
|
+
"trace-mcp alternatives:\\n- get_env_vars {} — list all env vars across all .env files\\n- get_env_vars { \\\"pattern\\\": \\\"DB_\\\" } — filter by key prefix\\nNever access .env files via shell — secrets will leak into AI model context."
|
|
193
|
+
fi
|
|
194
|
+
|
|
156
195
|
# Block code exploration via bash (grep, find, cat, head, tail on code files)
|
|
157
196
|
if echo "$COMMAND" | grep -qE '(^|\|)\s*(grep|rg|find|cat|head|tail|less|more|awk|sed)\s' && echo "$COMMAND" | grep -qiE "$CODE_EXT_RE"; then
|
|
158
197
|
deny \
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
@echo off
|
|
2
|
+
REM trace-mcp-precompact v0.1.0
|
|
3
|
+
REM trace-mcp PreCompact hook (Windows)
|
|
4
|
+
REM Injects session snapshot into compacted context to prevent "compaction amnesia".
|
|
5
|
+
REM Reads the live snapshot file written by the running trace-mcp MCP server and
|
|
6
|
+
REM returns it via the systemMessage field in Claude Code's hook output schema.
|
|
7
|
+
REM
|
|
8
|
+
REM Install: add to ~\.claude\settings.json or .claude\settings.local.json under PreCompact
|
|
9
|
+
REM See README.md for setup instructions.
|
|
10
|
+
|
|
11
|
+
setlocal enabledelayedexpansion
|
|
12
|
+
|
|
13
|
+
REM Determine project root from working directory
|
|
14
|
+
set "PROJECT_ROOT=%CD%"
|
|
15
|
+
|
|
16
|
+
REM Compute project hash using PowerShell (sha256, first 12 hex chars)
|
|
17
|
+
for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "[System.BitConverter]::ToString([System.Security.Cryptography.SHA256]::Create().ComputeHash([System.Text.Encoding]::UTF8.GetBytes('%PROJECT_ROOT%'))).Replace('-','').Substring(0,12).ToLower()"`) do set "PROJECT_HASH=%%i"
|
|
18
|
+
|
|
19
|
+
if "%PROJECT_HASH%"=="" goto :done
|
|
20
|
+
|
|
21
|
+
set "SNAPSHOT_FILE=%USERPROFILE%\.trace-mcp\sessions\%PROJECT_HASH%-snapshot.json"
|
|
22
|
+
|
|
23
|
+
if not exist "%SNAPSHOT_FILE%" goto :done
|
|
24
|
+
|
|
25
|
+
REM Read markdown from snapshot file and output as systemMessage
|
|
26
|
+
for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "$j = Get-Content '%SNAPSHOT_FILE%' -Raw | ConvertFrom-Json; if ($j.markdown) { $j.markdown }"`) do set "MARKDOWN=%%i"
|
|
27
|
+
|
|
28
|
+
if "%MARKDOWN%"=="" goto :done
|
|
29
|
+
|
|
30
|
+
powershell -NoProfile -Command "$m = (Get-Content '%SNAPSHOT_FILE%' -Raw | ConvertFrom-Json).markdown; @{systemMessage=$m} | ConvertTo-Json -Compress"
|
|
31
|
+
|
|
32
|
+
:done
|
|
33
|
+
exit /b 0
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# trace-mcp-precompact v0.1.0
|
|
3
|
+
# trace-mcp PreCompact hook
|
|
4
|
+
# Injects session snapshot into compacted context to prevent "compaction amnesia".
|
|
5
|
+
# Reads the live snapshot file written by the running trace-mcp MCP server and
|
|
6
|
+
# returns it via the systemMessage field in Claude Code's hook output schema.
|
|
7
|
+
#
|
|
8
|
+
# Install: add to ~/.claude/settings.json or .claude/settings.local.json under PreCompact
|
|
9
|
+
# See README.md for setup instructions.
|
|
10
|
+
|
|
11
|
+
set -euo pipefail
|
|
12
|
+
|
|
13
|
+
# Determine project root from working directory
|
|
14
|
+
PROJECT_ROOT="$(pwd)"
|
|
15
|
+
|
|
16
|
+
# Compute project hash (same algorithm as trace-mcp: sha256, first 12 hex chars)
|
|
17
|
+
if command -v sha256sum >/dev/null 2>&1; then
|
|
18
|
+
PROJECT_HASH=$(echo -n "$PROJECT_ROOT" | sha256sum | cut -c1-12)
|
|
19
|
+
elif command -v shasum >/dev/null 2>&1; then
|
|
20
|
+
PROJECT_HASH=$(echo -n "$PROJECT_ROOT" | shasum -a 256 | cut -c1-12)
|
|
21
|
+
else
|
|
22
|
+
# Fallback: no hash available, exit silently
|
|
23
|
+
exit 0
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
SNAPSHOT_FILE="$HOME/.trace-mcp/sessions/${PROJECT_HASH}-snapshot.json"
|
|
27
|
+
|
|
28
|
+
# If no snapshot file exists, exit silently (no session data yet)
|
|
29
|
+
if [[ ! -f "$SNAPSHOT_FILE" ]]; then
|
|
30
|
+
exit 0
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# Check file freshness — skip if older than 10 minutes (stale session)
|
|
34
|
+
if command -v stat >/dev/null 2>&1; then
|
|
35
|
+
if [[ "$(uname)" == "Darwin" ]]; then
|
|
36
|
+
FILE_MTIME=$(stat -f %m "$SNAPSHOT_FILE" 2>/dev/null || echo 0)
|
|
37
|
+
else
|
|
38
|
+
FILE_MTIME=$(stat -c %Y "$SNAPSHOT_FILE" 2>/dev/null || echo 0)
|
|
39
|
+
fi
|
|
40
|
+
NOW=$(date +%s)
|
|
41
|
+
AGE=$(( NOW - FILE_MTIME ))
|
|
42
|
+
if [[ $AGE -gt 600 ]]; then
|
|
43
|
+
exit 0
|
|
44
|
+
fi
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
# Read the markdown snapshot from the JSON file
|
|
48
|
+
MARKDOWN=$(jq -r '.markdown // empty' "$SNAPSHOT_FILE" 2>/dev/null)
|
|
49
|
+
|
|
50
|
+
if [[ -z "$MARKDOWN" ]]; then
|
|
51
|
+
exit 0
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
# Output systemMessage for Claude Code to inject into compacted context
|
|
55
|
+
jq -n --arg msg "$MARKDOWN" '{ "systemMessage": $msg }'
|
|
56
|
+
|
|
57
|
+
exit 0
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
@echo off
|
|
2
|
+
REM trace-mcp-worktree v0.1.0
|
|
3
|
+
REM trace-mcp WorktreeCreate / WorktreeRemove hook
|
|
4
|
+
REM On WorktreeCreate: registers and indexes the new worktree.
|
|
5
|
+
REM On WorktreeRemove: deregisters the worktree project.
|
|
6
|
+
|
|
7
|
+
setlocal enabledelayedexpansion
|
|
8
|
+
|
|
9
|
+
set "INPUT="
|
|
10
|
+
for /f "delims=" %%i in ('more') do set "INPUT=!INPUT!%%i"
|
|
11
|
+
|
|
12
|
+
REM Extract event type
|
|
13
|
+
for /f "delims=" %%e in ('echo !INPUT! ^| jq -r ".hook_event_name // .event // empty" 2^>nul') do set "EVENT=%%e"
|
|
14
|
+
if not defined CLAUDE_HOOK_EVENT set "CLAUDE_HOOK_EVENT=%EVENT%"
|
|
15
|
+
if defined CLAUDE_HOOK_EVENT set "EVENT=%CLAUDE_HOOK_EVENT%"
|
|
16
|
+
|
|
17
|
+
REM Extract worktree path
|
|
18
|
+
for /f "delims=" %%p in ('echo !INPUT! ^| jq -r ".tool_input.path // .worktree_path // .path // .cwd // empty" 2^>nul') do set "WPATH=%%p"
|
|
19
|
+
|
|
20
|
+
if "%WPATH%"=="" exit /b 0
|
|
21
|
+
|
|
22
|
+
if "%EVENT%"=="WorktreeCreate" (
|
|
23
|
+
start /b trace-mcp add "%WPATH%" --force --json >nul 2>&1
|
|
24
|
+
) else if "%EVENT%"=="WorktreeRemove" (
|
|
25
|
+
REM Clean up worktree DB file if it exists
|
|
26
|
+
for /f "delims=" %%h in ('echo %WPATH%^| certutil -hashfile - SHA256 2^>nul ^| findstr /v "hash"') do set "PHASH=%%h"
|
|
27
|
+
if defined PHASH (
|
|
28
|
+
set "PHASH=!PHASH:~0,12!"
|
|
29
|
+
del /q "%USERPROFILE%\.trace-mcp\db\!PHASH!.db" "%USERPROFILE%\.trace-mcp\db\!PHASH!.db-shm" "%USERPROFILE%\.trace-mcp\db\!PHASH!.db-wal" 2>nul
|
|
30
|
+
)
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
exit /b 0
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# trace-mcp-worktree v0.1.0
|
|
3
|
+
# trace-mcp WorktreeCreate / WorktreeRemove hook
|
|
4
|
+
# On WorktreeCreate: registers and indexes the new worktree so trace-mcp tools work immediately.
|
|
5
|
+
# On WorktreeRemove: deregisters the worktree project from the registry.
|
|
6
|
+
#
|
|
7
|
+
# Install: add to ~/.claude/settings.json or .claude/settings.local.json
|
|
8
|
+
# See README.md for setup instructions.
|
|
9
|
+
|
|
10
|
+
set -euo pipefail
|
|
11
|
+
|
|
12
|
+
INPUT=$(cat)
|
|
13
|
+
|
|
14
|
+
# Claude Code passes the event type via CLAUDE_HOOK_EVENT or hook_event_name
|
|
15
|
+
EVENT="${CLAUDE_HOOK_EVENT:-}"
|
|
16
|
+
if [[ -z "$EVENT" ]]; then
|
|
17
|
+
EVENT=$(echo "$INPUT" | jq -r '.hook_event_name // .event // empty' 2>/dev/null)
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
# Extract worktree path from hook input
|
|
21
|
+
WORKTREE_PATH=$(echo "$INPUT" | jq -r '.tool_input.path // .worktree_path // .path // empty' 2>/dev/null)
|
|
22
|
+
|
|
23
|
+
if [[ -z "$WORKTREE_PATH" ]]; then
|
|
24
|
+
# Fallback: use working directory from input
|
|
25
|
+
WORKTREE_PATH=$(echo "$INPUT" | jq -r '.cwd // empty' 2>/dev/null)
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
if [[ -z "$WORKTREE_PATH" ]]; then
|
|
29
|
+
exit 0
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
# Resolve to absolute path
|
|
33
|
+
WORKTREE_PATH=$(cd "$WORKTREE_PATH" 2>/dev/null && pwd || echo "$WORKTREE_PATH")
|
|
34
|
+
|
|
35
|
+
case "$EVENT" in
|
|
36
|
+
WorktreeCreate|worktree_create|create)
|
|
37
|
+
# Register and index the new worktree in the background
|
|
38
|
+
# --force: re-register even if parent repo is already known (worktree is a different root)
|
|
39
|
+
nohup trace-mcp add "$WORKTREE_PATH" --force --json >/dev/null 2>&1 &
|
|
40
|
+
;;
|
|
41
|
+
WorktreeRemove|worktree_remove|remove)
|
|
42
|
+
# Clean up the worktree DB file if it exists.
|
|
43
|
+
# The global registry entry becomes stale but is harmless — next `trace-mcp add` overwrites it.
|
|
44
|
+
PROJECT_HASH=""
|
|
45
|
+
if command -v sha256sum >/dev/null 2>&1; then
|
|
46
|
+
PROJECT_HASH=$(echo -n "$WORKTREE_PATH" | sha256sum | cut -c1-12)
|
|
47
|
+
elif command -v shasum >/dev/null 2>&1; then
|
|
48
|
+
PROJECT_HASH=$(echo -n "$WORKTREE_PATH" | shasum -a 256 | cut -c1-12)
|
|
49
|
+
fi
|
|
50
|
+
if [[ -n "$PROJECT_HASH" ]]; then
|
|
51
|
+
DB_FILE="$HOME/.trace-mcp/db/${PROJECT_HASH}.db"
|
|
52
|
+
rm -f "$DB_FILE" "$DB_FILE-shm" "$DB_FILE-wal" 2>/dev/null
|
|
53
|
+
fi
|
|
54
|
+
;;
|
|
55
|
+
esac
|
|
56
|
+
|
|
57
|
+
exit 0
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "trace-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.3",
|
|
4
4
|
"description": "Framework-aware code intelligence MCP server — 48+ frameworks, 68 languages",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"prepublishOnly": "npm run build"
|
|
19
19
|
},
|
|
20
20
|
"engines": {
|
|
21
|
-
"node": ">=
|
|
21
|
+
"node": ">=18.0.0"
|
|
22
22
|
},
|
|
23
23
|
"license": "ELv2",
|
|
24
24
|
"author": "Nikolai Vysotskyi",
|