From 8c5fd91d0570841557f6a898a41fd736ab5869e0 Mon Sep 17 00:00:00 2001 From: AI Briefing Date: Mon, 16 Mar 2026 18:55:10 +0800 Subject: [PATCH 1/2] fix: route auto-approve through CodePilot Handle permission prompts in CodePilot instead of relying on Claude Code bypass mode so auto-approve still works in environments where bypassPermissions is rejected. --- src/hooks/useSSEStream.ts | 2 ++ src/lib/bridge/permission-broker.ts | 10 ++++++- src/lib/claude-client.ts | 46 +++++++++++++++++++++-------- src/types/index.ts | 1 + 4 files changed, 45 insertions(+), 14 deletions(-) diff --git a/src/hooks/useSSEStream.ts b/src/hooks/useSSEStream.ts index 14c39fc3..c4bb33e4 100644 --- a/src/hooks/useSSEStream.ts +++ b/src/hooks/useSSEStream.ts @@ -10,6 +10,7 @@ interface ToolUseInfo { interface ToolResultInfo { tool_use_id: string; content: string; + is_error?: boolean; } export interface SSECallbacks { @@ -73,6 +74,7 @@ function handleSSEEvent( callbacks.onToolResult({ tool_use_id: resultData.tool_use_id, content: resultData.content, + is_error: resultData.is_error, }); } catch { // skip malformed tool_result data diff --git a/src/lib/bridge/permission-broker.ts b/src/lib/bridge/permission-broker.ts index 395a1245..bf2056c7 100644 --- a/src/lib/bridge/permission-broker.ts +++ b/src/lib/bridge/permission-broker.ts @@ -13,7 +13,7 @@ import type { PermissionUpdate } from '@anthropic-ai/claude-agent-sdk'; import type { ChannelAddress, OutboundMessage } from './types'; import type { BaseChannelAdapter } from './channel-adapter'; import { deliver } from './delivery-layer'; -import { insertPermissionLink, getPermissionLink, markPermissionLinkResolved, getSession, getDb } from '../db'; +import { insertPermissionLink, getPermissionLink, markPermissionLinkResolved, getSession, getDb, getSetting } from '../db'; import { resolvePendingPermission } from '../permission-registry'; import { escapeHtml } from './adapters/telegram-utils'; @@ -36,6 +36,14 @@ export async function forwardPermissionRequest( suggestions?: unknown[], replyToMessageId?: string, ): Promise { + // Check if auto-approval is enabled globally — auto-approve without IM notification + const globalAutoApprove = getSetting('dangerously_skip_permissions') === 'true'; + if (globalAutoApprove) { + console.log(`[bridge] Auto-approved permission ${permissionRequestId} (tool=${toolName}) due to global auto-approval setting`); + resolvePendingPermission(permissionRequestId, { behavior: 'allow' }); + return; + } + // Check if this session uses full_access permission profile — auto-approve without IM notification if (sessionId) { const session = getSession(sessionId); diff --git a/src/lib/claude-client.ts b/src/lib/claude-client.ts index a0c21db4..d8089497 100644 --- a/src/lib/claude-client.ts +++ b/src/lib/claude-client.ts @@ -19,6 +19,7 @@ import { registerPendingPermission } from './permission-registry'; import { registerConversation, unregisterConversation } from './conversation-registry'; import { captureCapabilities, setCachedPlugins } from './agent-sdk-capabilities'; import { getSetting, updateSdkSessionId, createPermissionRequest } from './db'; +// Auto-approval is now handled at the CodePilot level, not via SDK bypassPermissions import { resolveForClaudeCode, toClaudeCodeEnv } from './provider-resolver'; import { findClaudeBinary, findGitBash, getExpandedPath, invalidateClaudePathCache } from './platform'; import { notifyPermissionRequest, notifyGeneric } from './telegram-bot'; @@ -315,14 +316,26 @@ export async function generateTextViaSdk(params: { const queryOptions: Options = { cwd: os.homedir(), abortController, - permissionMode: 'bypassPermissions', - allowDangerouslySkipPermissions: true, + permissionMode: 'acceptEdits', env: sanitizeEnv(sdkEnv), settingSources: resolved.settingSources as Options['settingSources'], systemPrompt: params.system, maxTurns: 1, }; + // Add auto-approval handler for this simple query + const globalAutoApprove = getSetting('dangerously_skip_permissions') === 'true'; + if (globalAutoApprove) { + queryOptions.canUseTool = async (toolName, _input, opts) => { + console.log(`[claude-client] Auto-approved ${toolName} (auto-approval enabled)`); + return { + behavior: 'allow', + updatedInput: _input, + ...(opts.suggestions ? { updatedPermissions: opts.suggestions } : {}), + }; + }; + } + if (params.model) { queryOptions.model = params.model; } @@ -443,17 +456,15 @@ export function streamClaude(options: ClaudeStreamOptions): ReadableStream { const permissionRequestId = `perm-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`; + // If auto-approval is enabled, approve immediately without user interaction + if (shouldAutoApprove) { + console.log(`[claude-client] Auto-approved ${toolName} (auto-approval enabled)`); + return { + behavior: 'allow', + updatedInput: input, + ...(opts.suggestions ? { updatedPermissions: opts.suggestions } : {}), + }; + } + const permEvent: PermissionRequestEvent = { permissionRequestId, toolName, @@ -856,6 +873,9 @@ export function streamClaude(options: ClaudeStreamOptions): ReadableStream Date: Tue, 17 Mar 2026 17:09:46 +0800 Subject: [PATCH 2/2] chore: improve stop script to kill port 3000 processes --- start.sh | 183 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100755 start.sh diff --git a/start.sh b/start.sh new file mode 100755 index 00000000..441ce0ea --- /dev/null +++ b/start.sh @@ -0,0 +1,183 @@ +#!/bin/bash + +# CodePilot 后台启动脚本 + +APP_DIR="$(cd "$(dirname "$0")" && pwd)" +LOG_FILE="$APP_DIR/app.log" +PID_FILE="$APP_DIR/app.pid" + +# 显示菜单 +show_menu() { + clear + echo "========================================" + echo " CodePilot 管理菜单" + echo "========================================" + echo "" + + # 检查状态 + if [ -f "$PID_FILE" ] && kill -0 "$(cat "$PID_FILE")" 2>/dev/null; then + echo " 当前状态: 运行中 (PID: $(cat "$PID_FILE"))" + else + echo " 当前状态: 未运行" + fi + + echo "" + echo " [1] 启动服务" + echo " [2] 停止服务" + echo " [3] 重启服务" + echo " [4] 查看实时日志" + echo " [5] 查看状态" + echo " [6] 查看日志 (最后50行)" + echo " [0] 退出" + echo "" + echo "========================================" +} + +# 启动服务 +do_start() { + if [ -f "$PID_FILE" ] && kill -0 "$(cat "$PID_FILE")" 2>/dev/null; then + echo "服务已在运行 (PID: $(cat "$PID_FILE"))" + return + fi + + cd "$APP_DIR" || exit 1 + nohup npm run start > "$LOG_FILE" 2>&1 & + echo $! > "$PID_FILE" + echo "启动成功,PID: $!" +} + +# 停止服务 +do_stop() { + # 先尝试停止 PID 文件中的进程 + if [ -f "$PID_FILE" ]; then + PID=$(cat "$PID_FILE") + if kill -0 "$PID" 2>/dev/null; then + kill "$PID" 2>/dev/null + sleep 1 + # 如果进程还在,强制杀掉 + if kill -0 "$PID" 2>/dev/null; then + kill -9 "$PID" 2>/dev/null + fi + echo "已停止 (PID: $PID)" + else + echo "进程不存在" + fi + rm -f "$PID_FILE" + else + echo "服务未运行" + fi + + # 强制清理占用端口 3000 的进程 + if ss -tlnp 2>/dev/null | grep -q ":3000 "; then + echo "清理残留进程..." + fuser -k 3000/tcp 2>/dev/null + sleep 1 + # 再次强制清理 + lsof -ti:3000 | xargs -r kill -9 2>/dev/null + fi +} + +# 查看状态 +do_status() { + if [ -f "$PID_FILE" ] && kill -0 "$(cat "$PID_FILE")" 2>/dev/null; then + echo "运行中 (PID: $(cat "$PID_FILE"))" + else + echo "未运行" + fi +} + +# 查看日志 +do_log() { + tail -f "$LOG_FILE" +} + +# 菜单模式 +menu_mode() { + while true; do + show_menu + read -p "请选择操作 [0-6]: " choice + + case $choice in + 1) + echo "" + do_start + read -p "按回车键继续..." + ;; + 2) + echo "" + do_stop + read -p "按回车键继续..." + ;; + 3) + echo "" + do_stop + sleep 1 + do_start + read -p "按回车键继续..." + ;; + 4) + echo "" + echo "按 Ctrl+C 退出日志查看" + do_log + ;; + 5) + echo "" + do_status + read -p "按回车键继续..." + ;; + 6) + echo "" + if [ -f "$LOG_FILE" ]; then + tail -n 50 "$LOG_FILE" + else + echo "暂无日志文件" + fi + read -p "按回车键继续..." + ;; + 0) + echo "" + echo "再见!" + exit 0 + ;; + *) + echo "" + echo "无效选项" + read -p "按回车键继续..." + ;; + esac + done +} + +# 命令行模式 +case "${1:-menu}" in + start) + do_start + ;; + stop) + do_stop + ;; + restart) + do_stop + sleep 1 + do_start + ;; + status) + do_status + ;; + log) + do_log + ;; + menu) + menu_mode + ;; + *) + echo "用法: $0 {start|stop|restart|status|log|menu}" + echo "" + echo " start - 后台启动服务" + echo " stop - 停止服务" + echo " restart- 重启服务" + echo " status - 查看运行状态" + echo " log - 查看实时日志" + echo " menu - 显示交互菜单(默认)" + ;; +esac