Tags: bor799/CodePilot
Tags
feat: QQ bridge channel + SDK crash resilience fixes QQ Bridge Adapter (new): - qq-api.ts: AppAccessToken, WebSocket Gateway, heartbeat, passive reply, msg_seq auto-increment — pure QQ protocol layer - qq-adapter.ts: BaseChannelAdapter impl with WebSocket lifecycle, C2C_MESSAGE_CREATE handling, image download (base64), dedup, reconnect - Settings UI (QqBridgeSection.tsx) + API routes (/api/settings/qq) - i18n keys for en/zh, PLATFORM_LIMITS qq: 2000 replyToMessageId threading: - bridge-manager.ts: thread msg.messageId through all deliver/command/ permission paths — required for QQ passive reply (msg_id mandatory) - permission-broker.ts: accept and forward replyToMessageId SDK crash resilience (bug fix): - bridge-manager.ts: check hasError BEFORE saving sdkSessionId — the SDK may emit a session_id before crashing, and saving that broken ID caused ALL subsequent messages to fail by repeatedly resuming a corrupted session - claude-client.ts: always clear sdk_session_id on crash, even for fresh sessions (SDK can persist a new ID via status event before dying) - conversation-engine.ts: attach filePath to file objects after disk write so streamClaude() reuses on-disk copies (prevents duplicate writes, matches desktop route behavior) QQ permission handling (P1 fix): - permission-broker.ts: for channels without inline button support (QQ), render text-based /perm allow|deny|allow_session commands instead of invisible inlineButtons that would deadlock the stream QQ passive reply budget (P2 fix): - bridge-manager.ts: QQ-specific delivery limits chunks to 3 max, truncates with notice to avoid exhausting passive reply quota - delivery-layer.ts: export chunkText for reuse Error message improvement: - claude-client.ts: when exit code 1 with image files, hint "Provider may not support image/vision input" instead of generic auth/network message Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
feat: integrate Claude Agent SDK capabilities — model/command discove… …ry, effort/thinking, MCP runtime, file rewind, structured output Systematically integrate high-value SDK capabilities while preserving the multi-provider architecture: SDK capability discovery (per-provider cache): - agent-sdk-capabilities.ts: cache models, commands, account info, MCP status per provider via Map<providerId, cache> to prevent cross-provider pollution - claude-client.ts: fire-and-forget captureCapabilities() after query() init - providers/models: merge SDK models with static defaults - skills: merge SDK slash commands with filesystem skills Query options passthrough: - thinking (adaptive/enabled/disabled), effort (low/medium/high/max), outputFormat, agents, enableFileCheckpointing - /chat page.tsx: first-message path now includes effort/thinking (was missing) - stream-session-manager: passes effort/thinking in POST body Graceful interrupt: - /api/chat/interrupt: conversation.interrupt() before abort fallback - stream-session-manager: tries interrupt first, aborts after 2s timeout MCP runtime management: - /api/plugins/mcp/status: live status from active Query, auto-resolves providerId from session DB record (prevents wrong-provider cache writes) - /api/plugins/mcp/reconnect + toggle: reconnect/enable/disable servers - McpManager + McpServerList: runtime status indicators with action buttons File checkpointing & rewind: - enableFileCheckpointing=true for code mode by default - rewind_point SSE: only emitted for prompt-level user messages (parent_tool_use_id===null) and skips autoTrigger turns - /api/chat/rewind: dry-run preview + actual rewind via rewindFiles() - MessageList: RewindButton with dry-run preview Structured output: - /api/chat/structured: reads SDKResultSuccess.structured_output as primary path, text fallback only when absent Account info & thinking config: - /api/sdk/account: cached account info display - Settings: thinking_mode in ALLOWED_KEYS, thinking mode selector in UI - Effort selector in MessageInput with lifted state pattern New files: 11 route handlers + 2 lib modules + 1 test file Modified files: 18 (types, client, manager, UI components, i18n) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
feat: assistant workspace V2 — indexing, retrieval, security hardenin… …g & workspace switching Assistant Workspace V2: - Markdown indexing engine (incremental manifest + chunks JSONL) - Keyword retrieval with CJK bigram support and hotset boosting - Directory taxonomy inference and evolution suggestions - Workspace config management (.assistant/config.json) - Organize API: capture, classify, move, archive, suggest-evolution Workspace switching: - Inspect API (GET /api/workspace/inspect) for pre-switch validation - Two-phase switching with confirmation dialogs (5 workspace statuses) - Atomic save: init/reset runs before setSetting(), rollback on failure - Auto-navigate to new/reused session after switch - Mismatch banner in ChatView (only for former assistant sessions) - Debounced path validation with visual indicators Security hardening: - Completion fence (onboarding-complete/checkin-complete) only processes when session.workingDirectory === assistant_workspace_path (frontend) AND session.working_directory === workspacePath (backend double-check) - assertContained() in workspace-organizer: rejects absolute paths, ~/, ../ traversal, and symlink escapes for captureNote/moveFile - organize API validates all path params at entry (validateRelativePath) - captureDefault sanitized to relative path on onboarding write - R_OK + W_OK validation on GET settings, session creation, and PUT Bug fixes: - hookTriggeredSessionId now read before auto-trigger; allows retry if session has no messages (previous trigger failed silently) - workspace-switched event listener matches oldPath (not just != newPath) so normal project chats never show the mismatch banner - Daily check-in card hidden when onboarding not complete - Refresh docs now calls generateRootDocs() + generateDirectoryDocs() - Banner "Open" button reuses latest session (checkin mode) instead of always creating new onboarding session Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
feat: Discord bridge adapter — 完整实现 Discord 作为第三个桥接渠道 新增文件: - discord-adapter.ts: 基于 discord.js v14 的适配器,支持 DM/频道消息、 按钮交互、流式预览(edit-based)、@提及过滤(兼容角色 mention)、 图片附件下载、!→/ 命令归一化、消息去重、typing indicator - markdown/discord.ts: Discord 2000 字符分段,代码块围栏自动平衡 - API routes: settings CRUD(Token 掩码)+ verify(Discord REST 验证) - DiscordBridgeSection.tsx: 设置 UI(凭据、授权、服务器策略、配置指南含 ID 获取方法) - discord-bridge.test.ts: 22 项单元测试(chunking/auth/command/HTML 转换) 修改文件: - bridge-manager.ts: Discord 分段投递 + channel-aware stream config (Discord 默认 1500ms/40chars/1900max vs Telegram 700ms/20/3900) - BridgeLayout/BridgeSection: Discord 渠道开关和侧栏入口 - bridge/settings/route.ts: 新增 14 个 Discord 设置键 - next.config.ts: serverExternalPackages 添加 discord.js/zlib-sync - i18n: 中英文完整翻译(30+ keys) - docs/handover/bridge-system.md: Discord 架构文档 依赖:discord.js ^14.18.0, zlib-sync ^0.1.9 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
feat: 飞书(Feishu/Lark)Bridge 适配器 + 发布 v0.25.0 新增飞书 IM 通道,通过 @larksuiteoapi/node-sdk WSClient 接收消息、REST Client 发送回复。 适配器核心 (feishu-adapter.ts): - WSClient 长连接接收 im.message.receive_v1 事件 - 消息去重 (message_id LRU 1000)、授权校验、群聊策略 (open/allowlist/disabled) - @提及检测 (bot open_id/user_id/union_id 匹配) - 图片/文件/音频/视频/富文本(post) 下载 → base64 FileAttachment - Typing 指示器 (Openclaw 方案: emoji reaction) - /perm 文本命令处理权限审批 渲染策略 (markdown/feishu.ts): - 代码块/表格 → schema 2.0 interactive card (markdown 元素) - 纯文本 → post (md tag), 支持粗体/斜体/行内代码/链接 - 权限卡片 → schema 2.0 card + /perm 文本命令 (无按钮, 见下方决策) - 每层降级: card → post → text 关键决策 — 权限交互无按钮: - 飞书 card.action.trigger 回调需 HTTP webhook, WSClient 不支持 - schema 2.0 不支持 action 标签 (错误码 200861) - schema 1.0 按钮可渲染但点击报 200340 (无 webhook 端点) - Openclaw 用 http.createServer + Lark.adaptDefault 解决, CodePilot 桌面端无公网端点 - 最终方案: 格式化卡片 + /perm 文本命令, 用户复制发送即可审批 其他变更: - permission-broker.ts: permissionRequestId 去重 (30s TTL) - telegram-bot.ts: bridge 模式互斥 (globalThis 标志) - bridge-manager.ts: 飞书渲染分发 (deliverResponse feishu 分支) - UI: FeishuBridgeSection 设置页 + 侧边栏入口 + 通道开关 - i18n: 中英文飞书配置文案 - 交接文档: bridge-system.md 更新飞书架构、数据流、6 项设计决策 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
feat: Telegram 流式预览(sendMessageDraft)+ 出站渲染解耦 + 投递容错 Bridge 新增"边生成边显示"能力,利用 Telegram Bot API 9.5 的 sendMessageDraft 在私聊中以草稿形式流式展示 Claude 生成进度。 架构上抽象为通道级可选能力,便于后续扩展到其他 IM。 types.ts - 新增 PreviewCapabilities、StreamingPreviewState 接口 channel-adapter.ts - BaseChannelAdapter 新增三个可选方法: getPreviewCapabilities / sendPreview / endPreview - sendPreview 返回 'sent'|'skip'|'degrade' 三态, 区分瞬时失败(跳过)和永久失败(降级) telegram-utils.ts - 新增 sendMessageDraft() API 封装(plain text,截断到 4096) telegram-adapter.ts - 实现 getPreviewCapabilities: 开关检查 + 私聊/群聊检测 + 降级状态 - 实现 sendPreview: 调 sendMessageDraft,400/404 永久降级,429 仅跳过 - 实现 endPreview: 空操作 - stop() 清空 previewDegraded Set conversation-engine.ts - 新增 OnPartialText 回调类型 - processMessage / consumeStream 透传 onPartialText 参数 - 使用独立 previewText 变量(只累积、不因 tool_use 清零), 避免预览文本在工具调用后回退/抖动 bridge-manager.ts - 流式预览状态机:generateDraftId / getStreamConfig / flushPreview 节流闭包(间隔+最小增量+trailing-edge timer),finally 清理 - flushPreview 仅在 'degrade' 时降级,'skip'/网络错误不降级 - 新增 deliverResponse() 按 channelType 分发渲染: Telegram → markdownToTelegramChunks + deliverRendered 其他 IM → deliver() 纯文本(内部自动分块) 解除 handleMessage 对 Telegram 渲染的硬编码依赖 delivery-layer.ts - deliverRendered: chunk 失败后继续投递剩余 chunk(不中断), 追发截断提示通知用户,返回 ok:false 标识不完整投递 - deliver: 保持原有 fail-fast 行为(短消息无需跳过) route.ts (bridge/settings) - BRIDGE_SETTING_KEYS 白名单追加 5 个流式配置项 docs/handover/bridge-system.md - 更新目录结构、数据流、设计决策(op7418#12 流式预览)、设置项表 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
refactor: 简化 macOS 构建 — 只签名不公证,禁用原生热更新 CI (.github/workflows/build.yml): - 删除 mac_notarize 输入、notarization strategy/credentials 步骤 - 双架构回归单步构建,统一 -c.mac.notarize=false - 证书缺失时硬失败,不 fallback ad-hoc - 上传产物移除 blockmap / latest-mac.yml - release 收集资产移除 blockmap / yml 元数据 electron-builder.yml: - mac.notarize 固定为 false Electron 主进程 (main.ts): - 移除 initAutoUpdater / setUpdaterWindow 调用和 import Preload (preload.ts): - 移除 updater bridge,不再暴露 electronAPI.updater Updater (updater.ts): - 恢复为 no-op stub 前端 AppShell 无需改动 — isNativeUpdater 运行时检测 updater 不存在, 自动走 /api/app/updates 浏览器模式(全量下载链接)。 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
PreviousNext