diff --git a/.claude-ejecutor/settings.json b/.claude-ejecutor/settings.json index cb7be00..744506d 100644 --- a/.claude-ejecutor/settings.json +++ b/.claude-ejecutor/settings.json @@ -26,7 +26,7 @@ "hooks": [ { "type": "command", - "command": "powershell -NoProfile -Command \"try{$b=[Console]::In.ReadToEnd();Invoke-RestMethod -Uri 'http://localhost:4101/api/claude-hook?agent=ejecutor' -Method POST -Body $b -ContentType 'application/json' -TimeoutSec 3|Out-Null}catch{}\"", + "command": "powershell -NoProfile -File hooks/forward-hook.ps1 ejecutor", "timeout": 5000 } ] @@ -38,7 +38,7 @@ "hooks": [ { "type": "command", - "command": "powershell -NoProfile -Command \"try{$b=[Console]::In.ReadToEnd();Invoke-RestMethod -Uri 'http://localhost:4101/api/claude-hook?agent=ejecutor' -Method POST -Body $b -ContentType 'application/json' -TimeoutSec 3|Out-Null}catch{}\"", + "command": "powershell -NoProfile -File hooks/forward-hook.ps1 ejecutor", "timeout": 5000 } ] @@ -50,7 +50,7 @@ "hooks": [ { "type": "command", - "command": "powershell -NoProfile -Command \"try{$b=[Console]::In.ReadToEnd();Invoke-RestMethod -Uri 'http://localhost:4101/api/claude-hook?agent=ejecutor' -Method POST -Body $b -ContentType 'application/json' -TimeoutSec 3|Out-Null}catch{}\"", + "command": "powershell -NoProfile -File hooks/forward-hook.ps1 ejecutor", "timeout": 5000 } ] @@ -61,7 +61,7 @@ "hooks": [ { "type": "command", - "command": "powershell -NoProfile -Command \"try{$b=[Console]::In.ReadToEnd();Invoke-RestMethod -Uri 'http://localhost:4101/api/claude-hook?agent=ejecutor' -Method POST -Body $b -ContentType 'application/json' -TimeoutSec 3|Out-Null}catch{}\"", + "command": "powershell -NoProfile -File hooks/forward-hook.ps1 ejecutor", "timeout": 5000 } ] @@ -73,7 +73,7 @@ "hooks": [ { "type": "command", - "command": "powershell -NoProfile -Command \"try{$b=[Console]::In.ReadToEnd();Invoke-RestMethod -Uri 'http://localhost:4101/api/claude-hook?agent=ejecutor' -Method POST -Body $b -ContentType 'application/json' -TimeoutSec 3|Out-Null}catch{}\"", + "command": "powershell -NoProfile -File hooks/forward-hook.ps1 ejecutor", "timeout": 5000 } ] @@ -85,10 +85,20 @@ "hooks": [ { "type": "command", - "command": "powershell -NoProfile -Command \"try{$b=[Console]::In.ReadToEnd();Invoke-RestMethod -Uri 'http://localhost:4101/api/claude-hook?agent=ejecutor' -Method POST -Body $b -ContentType 'application/json' -TimeoutSec 3|Out-Null}catch{}\"", + "command": "powershell -NoProfile -File hooks/forward-hook.ps1 ejecutor", "timeout": 5000 } ] + }, + { + "matcher": ".*", + "hooks": [ + { + "type": "command", + "command": "powershell -NoProfile -File hooks/approval-permission.ps1 ejecutor", + "timeout": 130000 + } + ] } ], "Stop": [ @@ -96,10 +106,19 @@ "hooks": [ { "type": "command", - "command": "powershell -NoProfile -Command \"try{$b=[Console]::In.ReadToEnd();Invoke-RestMethod -Uri 'http://localhost:4101/api/claude-hook?agent=ejecutor' -Method POST -Body $b -ContentType 'application/json' -TimeoutSec 3|Out-Null}catch{}\"", + "command": "powershell -NoProfile -File hooks/forward-hook.ps1 ejecutor", "timeout": 10000 } ] + }, + { + "hooks": [ + { + "type": "command", + "command": "powershell -NoProfile -File hooks/approval-plan.ps1 ejecutor", + "timeout": 130000 + } + ] } ] } diff --git a/.claude-isolated/.gitignore b/.claude-isolated/.gitignore deleted file mode 100644 index ca50cc4..0000000 --- a/.claude-isolated/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -# No versionar credenciales -.credentials.json -*.backup - -# Estado de sesión (regenerable) -.claude.json -.claude.json.backup - -# Archivos temporales -tmp/ diff --git a/.claude-isolated/settings.json b/.claude-isolated/settings.json deleted file mode 100644 index c9c0a74..0000000 --- a/.claude-isolated/settings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "permissions": { - "allow": [], - "deny": [] - }, - "env": { - "DISABLE_TELEMETRY": "1" - } -} diff --git a/.claude-nucleo000/settings.json b/.claude-nucleo000/settings.json index c9c0a74..07e342b 100644 --- a/.claude-nucleo000/settings.json +++ b/.claude-nucleo000/settings.json @@ -1,9 +1,111 @@ { + "env": { + "DISABLE_TELEMETRY": "1" + }, "permissions": { "allow": [], "deny": [] }, - "env": { - "DISABLE_TELEMETRY": "1" + "hooks": { + "UserPromptSubmit": [ + { + "hooks": [ + { + "type": "command", + "command": "powershell -NoProfile -File hooks/forward-hook.ps1 nucleo000", + "timeout": 5000 + } + ] + } + ], + "PreToolUse": [ + { + "matcher": ".*", + "hooks": [ + { + "type": "command", + "command": "powershell -NoProfile -File hooks/forward-hook.ps1 nucleo000", + "timeout": 5000 + } + ] + } + ], + "PostToolUse": [ + { + "matcher": ".*", + "hooks": [ + { + "type": "command", + "command": "powershell -NoProfile -File hooks/forward-hook.ps1 nucleo000", + "timeout": 5000 + } + ] + } + ], + "SessionStart": [ + { + "hooks": [ + { + "type": "command", + "command": "powershell -NoProfile -File hooks/forward-hook.ps1 nucleo000", + "timeout": 5000 + } + ] + } + ], + "Notification": [ + { + "matcher": ".*", + "hooks": [ + { + "type": "command", + "command": "powershell -NoProfile -File hooks/forward-hook.ps1 nucleo000", + "timeout": 5000 + } + ] + } + ], + "PermissionRequest": [ + { + "matcher": ".*", + "hooks": [ + { + "type": "command", + "command": "powershell -NoProfile -File hooks/forward-hook.ps1 nucleo000", + "timeout": 5000 + } + ] + }, + { + "matcher": ".*", + "hooks": [ + { + "type": "command", + "command": "powershell -NoProfile -File hooks/approval-permission.ps1 nucleo000", + "timeout": 130000 + } + ] + } + ], + "Stop": [ + { + "hooks": [ + { + "type": "command", + "command": "powershell -NoProfile -File hooks/forward-hook.ps1 nucleo000", + "timeout": 10000 + } + ] + }, + { + "hooks": [ + { + "type": "command", + "command": "powershell -NoProfile -File hooks/approval-plan.ps1 nucleo000", + "timeout": 130000 + } + ] + } + ] } } diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 332295e..e8d1bb7 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -8,6 +8,8 @@ import FloatingResponse from './components/FloatingResponse.vue' import FloatingVoice from './components/FloatingVoice.vue' import AgentBar from './components/AgentBar.vue' import PwaInstallBanner from './components/PwaInstallBanner.vue' +import HooksApprovalModal from './components/HooksApprovalModal.vue' +import { useGlobalApproval } from './composables/useGlobalApproval' import { initWebMCP, getWebMCP } from './services/webmcp' import { initTorch, destroyTorch } from './services/torch' import { endpoints } from './config/endpoints' @@ -68,6 +70,7 @@ const responseRef = ref | null>(null) const voiceRef = ref | null>(null) const canvasStore = useCanvasStore() const projectCanvasStore = useProjectCanvasStore() +const { totalPending, modalVisible, connect: connectApproval, disconnect: disconnectApproval, fetchPending: fetchApprovalPending } = useGlobalApproval() // Voice FAB push-to-talk state const voicePTTActive = ref(false) let voiceTouchStarted = false @@ -264,6 +267,10 @@ onMounted(async () => { // Connect to WebSocket for Claude status updates connectStatusWs() + // Connect global hooks approval WS + connectApproval() + fetchApprovalPending() + // Fire torch connection early (don't await yet) const torchReady = initTorch() @@ -349,6 +356,7 @@ onMounted(async () => { onUnmounted(() => { destroyTorch() + disconnectApproval() if (statusReconnectTimeout) clearTimeout(statusReconnectTimeout) if (processingTimeout) clearTimeout(processingTimeout) if (sessionStartTimeout) clearTimeout(sessionStartTimeout) @@ -398,6 +406,18 @@ watch(() => route.name, (newPage) => {
+ +
+ +
+ + +
+ + + + No pending approvals +
+
+ + + + + + + diff --git a/frontend/src/components/Toolbar.vue b/frontend/src/components/Toolbar.vue index 0fff2ea..b46ee8f 100644 --- a/frontend/src/components/Toolbar.vue +++ b/frontend/src/components/Toolbar.vue @@ -131,6 +131,15 @@ onMounted(() => { + + + + + + + + +
diff --git a/frontend/src/components/transcript-debug/AssistantMessageBubble.vue b/frontend/src/components/transcript-debug/AssistantMessageBubble.vue new file mode 100644 index 0000000..c71d2d3 --- /dev/null +++ b/frontend/src/components/transcript-debug/AssistantMessageBubble.vue @@ -0,0 +1,189 @@ + + + + + diff --git a/frontend/src/components/transcript-debug/ChatContainer.vue b/frontend/src/components/transcript-debug/ChatContainer.vue new file mode 100644 index 0000000..d65c9db --- /dev/null +++ b/frontend/src/components/transcript-debug/ChatContainer.vue @@ -0,0 +1,583 @@ + + + + + diff --git a/frontend/src/components/transcript-debug/PermissionApproval.vue b/frontend/src/components/transcript-debug/PermissionApproval.vue new file mode 100644 index 0000000..dbf9dca --- /dev/null +++ b/frontend/src/components/transcript-debug/PermissionApproval.vue @@ -0,0 +1,213 @@ + + + + + diff --git a/frontend/src/components/transcript-debug/PlanApproval.vue b/frontend/src/components/transcript-debug/PlanApproval.vue new file mode 100644 index 0000000..b699397 --- /dev/null +++ b/frontend/src/components/transcript-debug/PlanApproval.vue @@ -0,0 +1,253 @@ + + + + + diff --git a/frontend/src/components/transcript-debug/ProgressEvent.vue b/frontend/src/components/transcript-debug/ProgressEvent.vue new file mode 100644 index 0000000..99aa971 --- /dev/null +++ b/frontend/src/components/transcript-debug/ProgressEvent.vue @@ -0,0 +1,279 @@ + + + + + diff --git a/frontend/src/components/transcript-debug/RawJsonViewer.vue b/frontend/src/components/transcript-debug/RawJsonViewer.vue new file mode 100644 index 0000000..44972d2 --- /dev/null +++ b/frontend/src/components/transcript-debug/RawJsonViewer.vue @@ -0,0 +1,216 @@ + + + + + diff --git a/frontend/src/components/transcript-debug/SessionSelector.vue b/frontend/src/components/transcript-debug/SessionSelector.vue new file mode 100644 index 0000000..461e28f --- /dev/null +++ b/frontend/src/components/transcript-debug/SessionSelector.vue @@ -0,0 +1,110 @@ + + + + + diff --git a/frontend/src/components/transcript-debug/SystemMessage.vue b/frontend/src/components/transcript-debug/SystemMessage.vue new file mode 100644 index 0000000..f781a92 --- /dev/null +++ b/frontend/src/components/transcript-debug/SystemMessage.vue @@ -0,0 +1,90 @@ + + + + + diff --git a/frontend/src/components/transcript-debug/ThinkingBlock.vue b/frontend/src/components/transcript-debug/ThinkingBlock.vue new file mode 100644 index 0000000..289ccce --- /dev/null +++ b/frontend/src/components/transcript-debug/ThinkingBlock.vue @@ -0,0 +1,87 @@ + + + + + diff --git a/frontend/src/components/transcript-debug/ToolCallBlock.vue b/frontend/src/components/transcript-debug/ToolCallBlock.vue new file mode 100644 index 0000000..d123cef --- /dev/null +++ b/frontend/src/components/transcript-debug/ToolCallBlock.vue @@ -0,0 +1,390 @@ + + + + + diff --git a/frontend/src/components/transcript-debug/ToolResultBlock.vue b/frontend/src/components/transcript-debug/ToolResultBlock.vue new file mode 100644 index 0000000..f1b3ffa --- /dev/null +++ b/frontend/src/components/transcript-debug/ToolResultBlock.vue @@ -0,0 +1,102 @@ + + + + + diff --git a/frontend/src/components/transcript-debug/UserInput.vue b/frontend/src/components/transcript-debug/UserInput.vue new file mode 100644 index 0000000..6d7cf31 --- /dev/null +++ b/frontend/src/components/transcript-debug/UserInput.vue @@ -0,0 +1,166 @@ + + +