@@ -42,11 +42,18 @@ try {
4242 exit 0
4343 }
4444
45+ # DEBUG: Log raw stdin length and first 100 chars
46+ Write-Log " DEBUG: stdin length=$ ( $input_json.Length ) , preview=$ ( $input_json.Substring (0 , [Math ]::Min(100 , $input_json.Length ))) "
47+
4548 $data = $input_json | ConvertFrom-Json
4649 $toolName = $data.tool_name
4750
4851 Write-Log " Tool: $toolName "
4952
53+ # Write JSON to temp file to avoid command-line length limits
54+ $tempFile = [System.IO.Path ]::Combine([System.IO.Path ]::GetTempPath(), " hook-input-$ ( [guid ]::NewGuid().ToString()) .json" )
55+ [System.IO.File ]::WriteAllText($tempFile , $input_json , [System.Text.Encoding ]::UTF8)
56+
5057 # ============================================================
5158 # PHASE: PreToolUse
5259 # ============================================================
5663 # This replaces plain Read with intelligent caching, diffing, and truncation
5764 # Must run BEFORE user enforcers to ensure caching takes priority
5865 if ($toolName -eq " Read" ) {
59- $input_json | & powershell - NoProfile - ExecutionPolicy Bypass - File $ORCHESTRATOR - Phase " PreToolUse" - Action " smart-read"
66+ & powershell - NoProfile - ExecutionPolicy Bypass - File $ORCHESTRATOR - Phase " PreToolUse" - Action " smart-read" - InputJsonFile $tempFile
6067 if ($LASTEXITCODE -eq 2 ) {
6168 # smart_read succeeded - blocks plain Read and returns cached/optimized content
6269 exit 2
@@ -65,13 +72,13 @@ try {
6572 }
6673
6774 # 2. Context Guard - Check if we're approaching token limit
68- $input_json | & powershell - NoProfile - ExecutionPolicy Bypass - File $ORCHESTRATOR - Phase " PreToolUse" - Action " context-guard"
75+ & powershell - NoProfile - ExecutionPolicy Bypass - File $ORCHESTRATOR - Phase " PreToolUse" - Action " context-guard" - InputJsonFile $tempFile
6976 if ($LASTEXITCODE -eq 2 ) {
7077 Block-Tool - Reason " Context budget exhausted - session optimization required"
7178 }
7279
7380 # 3. Track operation
74- $input_json | & powershell - NoProfile - ExecutionPolicy Bypass - File $ORCHESTRATOR - Phase " PreToolUse" - Action " session-track"
81+ & powershell - NoProfile - ExecutionPolicy Bypass - File $ORCHESTRATOR - Phase " PreToolUse" - Action " session-track" - InputJsonFile $tempFile
7582
7683 # 4. MCP Enforcers - Force usage of MCP tools over Bash/Read/Grep
7784
@@ -113,7 +120,10 @@ try {
113120 }
114121
115122 # Block GitHub operations - require MCP
116- Block-Tool - Reason " Use GitHub MCP (mcp__github__*) for GitHub operations (pr, issue, etc.)"
123+ # DISABLED: MCP tools not available, allow gh CLI
124+ # Block-Tool -Reason "Use GitHub MCP (mcp__github__*) for GitHub operations (pr, issue, etc.)"
125+ Write-Log " [ALLOW] GitHub operation via gh CLI: $ ( $data.tool_input.command ) "
126+ exit 0
117127 }
118128
119129 # Gemini CLI Enforcer - Now safe to enable because smart_read runs first
@@ -127,20 +137,48 @@ try {
127137 # }
128138
129139 Write-Log " [ALLOW] $toolName "
140+
141+ # Cleanup temp file before exit
142+ if (Test-Path $tempFile ) {
143+ Remove-Item - Path $tempFile - Force - ErrorAction SilentlyContinue
144+ }
145+
130146 exit 0
131147 }
132148
133149 # ============================================================
134150 # PHASE: PostToolUse
135151 # ============================================================
136152 if ($Phase -eq " PostToolUse" ) {
153+ $phaseStart = Get-Date
137154
138155 # 1. Log ALL tool operations to operations-{sessionId}.csv
139156 # This is CRITICAL for session-level optimization
140- $input_json | & powershell - NoProfile - ExecutionPolicy Bypass - File $ORCHESTRATOR - Phase " PostToolUse" - Action " log-operation"
141-
142- # 2. Track operation count
143- $input_json | & powershell - NoProfile - ExecutionPolicy Bypass - File $ORCHESTRATOR - Phase " PostToolUse" - Action " session-track"
157+ $actionStart = Get-Date
158+ & powershell - NoProfile - ExecutionPolicy Bypass - File $ORCHESTRATOR - Phase " PostToolUse" - Action " log-operation" - InputJsonFile $tempFile
159+ $actionDuration = ((Get-Date ) - $actionStart ).TotalMilliseconds
160+ Write-Log " TIMING: log-operation took ${actionDuration} ms"
161+
162+ # 2. Optimize tool output for token savings (BACKGROUND MODE - NON-BLOCKING)
163+ # Run in background process to avoid blocking the main thread
164+ # This allows hooks to return immediately while optimization runs async
165+ $actionStart = Get-Date
166+ Write-Log " BACKGROUND: Starting optimize-tool-output in background process"
167+ Start-Process - FilePath " powershell" - ArgumentList " -NoProfile" , " -ExecutionPolicy" , " Bypass" , " -File" , $ORCHESTRATOR , " -Phase" , " PostToolUse" , " -Action" , " optimize-tool-output" , " -InputJsonFile" , $tempFile - WindowStyle Hidden - NoNewWindow
168+ $actionDuration = ((Get-Date ) - $actionStart ).TotalMilliseconds
169+ Write-Log " TIMING: optimize-tool-output background spawn took ${actionDuration} ms"
170+
171+ # 3. Track operation count
172+ $actionStart = Get-Date
173+ & powershell - NoProfile - ExecutionPolicy Bypass - File $ORCHESTRATOR - Phase " PostToolUse" - Action " session-track" - InputJsonFile $tempFile
174+ $actionDuration = ((Get-Date ) - $actionStart ).TotalMilliseconds
175+ Write-Log " TIMING: session-track took ${actionDuration} ms"
176+
177+ $phaseDuration = ((Get-Date ) - $phaseStart ).TotalMilliseconds
178+ Write-Log " TIMING: PostToolUse total took ${phaseDuration} ms"
179+
180+ # NOTE: Do NOT cleanup temp file here - background process needs it
181+ # Background process will clean up when done
144182
145183 exit 0
146184 }
@@ -153,7 +191,12 @@ try {
153191 Write-Log " Session starting - warming cache"
154192
155193 # Pre-warm cache using predictive patterns
156- $input_json | & powershell - NoProfile - ExecutionPolicy Bypass - File $ORCHESTRATOR - Phase " SessionStart" - Action " cache-warmup"
194+ & powershell - NoProfile - ExecutionPolicy Bypass - File $ORCHESTRATOR - Phase " SessionStart" - Action " cache-warmup" - InputJsonFile $tempFile
195+
196+ # Cleanup temp file
197+ if (Test-Path $tempFile ) {
198+ Remove-Item - Path $tempFile - Force - ErrorAction SilentlyContinue
199+ }
157200
158201 exit 0
159202 }
@@ -166,7 +209,12 @@ try {
166209 Write-Log " Session ending - generating final report"
167210
168211 # Generate comprehensive session analytics
169- $input_json | & powershell - NoProfile - ExecutionPolicy Bypass - File $ORCHESTRATOR - Phase " PreCompact" - Action " session-report"
212+ & powershell - NoProfile - ExecutionPolicy Bypass - File $ORCHESTRATOR - Phase " PreCompact" - Action " session-report" - InputJsonFile $tempFile
213+
214+ # Cleanup temp file
215+ if (Test-Path $tempFile ) {
216+ Remove-Item - Path $tempFile - Force - ErrorAction SilentlyContinue
217+ }
170218
171219 exit 0
172220 }
@@ -176,20 +224,37 @@ try {
176224 # ============================================================
177225 if ($Phase -eq " UserPromptSubmit" ) {
178226 # Track user prompts for analytics
179- $input_json | & powershell - NoProfile - ExecutionPolicy Bypass - File $ORCHESTRATOR - Phase " UserPromptSubmit" - Action " session-track"
227+ & powershell - NoProfile - ExecutionPolicy Bypass - File $ORCHESTRATOR - Phase " UserPromptSubmit" - Action " session-track" - InputJsonFile $tempFile
180228
181229 # CRITICAL: Run session-level optimization at end of user turn
182230 # This batch-optimizes ALL file operations from the previous turn
183- $input_json | & powershell - NoProfile - ExecutionPolicy Bypass - File $ORCHESTRATOR - Phase " UserPromptSubmit" - Action " optimize-session"
231+ & powershell - NoProfile - ExecutionPolicy Bypass - File $ORCHESTRATOR - Phase " UserPromptSubmit" - Action " optimize-session" - InputJsonFile $tempFile
232+
233+ # Cleanup temp file
234+ if (Test-Path $tempFile ) {
235+ Remove-Item - Path $tempFile - Force - ErrorAction SilentlyContinue
236+ }
184237
185238 exit 0
186239 }
187240
188241 # Unknown phase
189242 Write-Log " Unknown phase: $Phase "
243+
244+ # Cleanup temp file
245+ if (Test-Path $tempFile ) {
246+ Remove-Item - Path $tempFile - Force - ErrorAction SilentlyContinue
247+ }
248+
190249 exit 0
191250
192251} catch {
193252 Write-Log " [ERROR] Dispatcher failed: $ ( $_.Exception.Message ) "
253+
254+ # Cleanup temp file on error
255+ if ($tempFile -and (Test-Path $tempFile )) {
256+ Remove-Item - Path $tempFile - Force - ErrorAction SilentlyContinue
257+ }
258+
194259 exit 0 # Never block on error
195260}
0 commit comments