Jul 3 03:48 feat: add inline terminal image rendering with Kitty protocol support chenbhao +1: Claude Big Pickle Introduce InlineImage component, ImageShow tool, and image caching/detection
utilities for rendering images directly in the terminal via the Kitty graphics
protocol. Falls back to clickable hyperlinks when protocol is unavailable.
Co-Authored-By: Claude Big Pickle <noreply@anthropic.com> Jul 1 15:57 chore: env map config 15:39 docs: add LocationTool unlimited search news and pagination docs chenbhao +1: Claude Big Pickle Co-Authored-By: Claude Big Pickle <noreply@anthropic.com> 15:34 feat: remove result limits on LocationTool place searches (Amap/Google) chenbhao +1: Claude Big Pickle - Amap (高德): offset 25 → 1000 per page with pagination loop (≤20 pages)
- Google Places: remove .slice(0,20), add next_page_token pagination (≤3 pages)
- Photos list: remove .slice(0,3) limit
Co-Authored-By: Claude Big Pickle <noreply@anthropic.com> 14:02 feat: add LocationTool — geographic search with Amap/Google Maps chenbhao +1: Claude Big Pickle Add a new LocationTool supporting geocoding, POI search, directions,
and trip planning. Automatically selects Amap (China) or Google Maps
(international) based on region detection.
Co-Authored-By: Claude Big Pickle <noreply@anthropic.com> Jun 30 13:22 chore: docs — add Computer Use Python runtime documentation chenbhao +1: Claude Big Pickle Co-Authored-By: Claude Big Pickle <noreply@anthropic.com> 03:01 fix: /friend motion — interrupt hold on new action, drain queue, fix emotion mapping chenbhao +1: Claude Big Pickle - MotionController: interrupt hold when new playAction arrives instead of
queueing, so LLM text-message actions are not blocked by stale 10s hold
- MotionController: drain action queue in hold timer callback to prevent
silent drop of queued actions
- App.tsx: remove hold=true from emotion-only messages — action plays once,
emotion timer handles duration independently
- App.tsx: remove awkward emotion→action mappings (neutral→salute,
relaxed→salute, sad→shy) that caused unnatural gestures
Co-Authored-By: Claude Big Pickle <noreply@anthropic.com> 02:08 feat: /friend aliveness system, motion controller fix, VAD tuning, high-pass filter chenbhao +1: Claude Big Pickle - Remove redundant files (HistoryPanel, MoodIndicator, vmd-loader, vrm-ik-handler, web-file-picker, FriendScreenObserveTool)
- Add action parameter to friend_emotion for VRM animation playback
- Fix motion-controller: replace broken 'finished' event with frame-accurate completion detection and action queue
- Add aliveness system: breathing, postural sway, speech micro-movements, listening response, micro-expressions, enhanced blink
- Add Silero VAD threshold tuning and high-pass filter for low-frequency noise rejection
- Fix build scripts (vite build instead of tauri build)
- Add LipSync.isActive() for speech-driven animation blending
Co-Authored-By: Claude Big Pickle <noreply@anthropic.com> Jun 29 17:39 chore: docs v1.2 — add debug system, feishu integration; update swarm, tavily, provider auth chenbhao +1: Claude Big Pickle New docs:
- docs/cli/debug-system.md — /debug v2.0 DEBUG PROBE workflow, session debug logging
- docs/services/feishu.md — Feishu/Lark bot architecture, access control, TTS
Updated docs:
- docs/coordinator/multi-agent.md — Agent Teams (Swarm topology), Fork Subagent
- docs/tools/overview.md — WebSearch dual-backend (Tavily vs SearXNG)
- docs/architecture/provider-auth.md — OpenCode Zen free models, NVIDIA sidecar
- docs/friend/voice-vad.md — noise suppression, FriendService stricter threshold
- docs/services/overview.md — condensed feishu section to point to new doc
- docs/README.md — index updated with all new entries
Co-Authored-By: Claude Big Pickle <noreply@anthropic.com> 16:58 fix: prevent TTS replay of historical messages on session resume chenbhao +1: Claude Big Pickle useAutoTTS now detects session switches (resume) via UUID discontinuity
and treats all loaded messages as history to skip TTS. Only subsequent
real-time assistant replies will trigger speech.
Co-Authored-By: Claude Big Pickle <noreply@anthropic.com> 14:15 chore: remove obsolete test and vendor source, add CLI SDK docs chenbhao +1: Claude Big Pickle - Remove test_feishu_ws.ts (contained secrets)
- Remove vendor/audio-capture-src/index.ts (replaced by
packages/audio-capture-napi)
- Add docs/cli/ build system documentation
- Add src/cli/ SDK transport and handler modules
Co-Authored-By: Claude Big Pickle <noreply@anthropic.com> 13:53 feat: unify build output paths and extract shared feature flags chenbhao +1: Claude Big Pickle - Always build to dist/VersperClaw with symlink at project root
- Always enable all experimental features (dev mode, no release builds)
- Extract feature flag list to scripts/features.ts, shared by build & dev
- Create scripts/dev.ts to run source with --feature and --define flags
- Copy vendor/ to dist/vendor/ at build time for runtime resolution
- Remove redundant build:dev, build:dev:full, compile scripts
Co-Authored-By: Claude Big Pickle <noreply@anthropic.com> 12:44 feat: /debug v2.0 已将 VersperClaw 的 /debug 从被动日志阅读技能完全替换为 Openclaude /debug-mode 的主动插桩调试工作流。
改动文件
┌───────────────────────────────┬──────┬──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 文件 │ 操作 │ 说明 │
├───────────────────────────────┼──────┼──────────────────────────────────────────────────────────────────────────────────────────────────┤
│ src/tools/DebugSessionTool.ts │ 新建 │ 移植自 Openclaude,管理 .versperclaw-debug/ 目录(init/begin_run/begin_verify/read_log/cleanup) │
├───────────────────────────────┼──────┼──────────────────────────────────────────────────────────────────────────────────────────────────┤
│ src/tools.ts │ 修改 │ 导入并注册 DebugSessionTool 到工具列表 │
├───────────────────────────────┼──────┼─────────────────────────────────────────────────────… Jun 28 12:49 feat: Filter TTS rules based on language 09:21 fix: FriendEmotionTool.call() 08:59 feat: /friend cosplay 07:58 feat: Friend 消息 → 仅使用人设提示词 修改的文件 (5个)
核心流程:Friend 消息 → 仅使用人设提示词
1. src/types/textInputTypes.ts
- 在 QueuedCommand 中添加 overrideSystemPrompt?: string 字段,用于存储替代系统提示词
2. src/skills/bundled/friendPrompt.ts
- 导出 loadPersona() 和 buildVrmSystemPrompt(),供 FriendService 调用
3. src/friend/FriendService.ts
- 在 sendText() 中构建 VRM 人设提示词,作为 overrideSystemPrompt 随消息入队
4. src/utils/handlePromptSubmit.ts
- 在 onQuery 类型中添加 overrideSystemPrompt 参数
- 从 commands[0] 提取并传递给 onQuery
5. src/screens/REPL.tsx
- onQuery 和 onQueryImpl 均接收 overrideSystemPrompt 参数
- 传入 buildEffectiveSystemPrompt(),当该值存在时完全替代默认系统提示词
数据流
FriendService.sendText()
→ buildVrmSystemPrompt() ← 只构建 VRM 人设提示词
→ enqueue({ overrideSystemPrompt, ... })
→ processQueueIfReady()
→ handlePromptSubmit()
→ executeUserInput()
→ onQuery(..., overrideSystemPrompt)
→ onQueryImpl(..., overrideSystemPrompt)
→ buildEffectiveSystemPrompt({ overrideSystemPrompt })
→ 返回 [overrideSystemPrompt] ← 完全绕过 ~900 行 … 07:57 fix: tts not read tool message 06:20 chore: script bun run friend:build Jun 22 14:41 chore: update readme 13:20 chore: docs v1.1 12:38 chore: docs v1.0 11:24 chore: questionnaire rename 11:05 feat: VAD Noise Suppression 代码正确。运行现有测试确保没有破坏。
● Bash(npx vitest run src/friend/__tests__/ 2>&1 | tail -30)
⎿ FAIL src/friend/__tests__/e2e-http-flow.test.ts [ src/friend/__tests__/e2e-http-flow.test.ts ]
Error: Cannot find package 'bun:test' imported from /home/yuki/Code/Agent/VersperClaw/src/friend/__tests__/e2e-http-flow.test.ts
❯ src/friend/__tests__/e2e-http-flow.test.ts:10:1
… +26 lines (ctrl+o to expand)
⎿ (timeout 30s)
● 测试使用 bun,需要 bun test。
● Bash(bun test src/friend/__tests__/ 2>&1 | tail -30)
⎿ bun test v1.3.14-canary.1 (0d9b296a)
src/friend/__tests__/e2e-http-flow.test.ts:
… +15 lines (ctrl+o to expand)
● 4 测试全部通过,15 个 expect() 均无失败。
修改总结
vad-service.ts — 核心 VAD 检测逻辑
阈值调整(减少假阳性):
┌─────────────────────────┬───────────┬────────────┬─────────────────────────────────────┐
│ 参数 │ 旧值 │ 新值 │ 作用 │
├─────────────────────────┼───────────┼────────────┼─────────────────────────────────────┤
│… 10:54 chore: friend and how to use prompt 10:33 chore: no appimage 10:23 fix: tools call or think voice play will stop receive audio 用户说话 → VAD检测说话结束 → _flushVadSegment()
→ sendText(transcript) → 进入CLI对话
→ startAiTurnMute()
├─ muted = true
├─ VAD pause()
└─ 30秒超时(安全网,覆盖AI处理、工具调用、思考等)
AI处理中(WebSearch / 深度思考 / 等) → 音频静音,不收不送
AI回复就绪 → broadcastResponse()
→ TTS生成成功
→ extendMuteForTts(audioId)
├─ 清除30秒安全网
├─ 解析MP3算出精确音频时长
└─ 新定时器 = 精确时长
TTS播放中 → 音频静音
TTS播放完毕 → unmute()
├─ muted = false
├─ VAD start() → 恢复收音
└─ 下一轮对话开始
30 秒兜底防止 AI 不回复(错误等)导致永久静音,extendMuteForTts 在 TTS 生成后会精确定时到音频实际长度 10:12 fix: TTS voice play will stop receive audio 现在 muteForTts 不再靠估算,而是实际解析 MP3 文件头算出精确时长:
1. 找到前两个帧同步(0xFFE0),测量出实际帧间距(144 字节)
2. 用这个帧间距作为步长遍历文件统计帧数
3. 从第一帧头部解析出采样率和每帧采样数
4. duration = frameCount × samplesPerFrame / sampleRate
短句 "你好,这是一段测试语音。" → 2880ms ✓
中等 "你好,这是一段...voice message." → 6024ms ✓
长句 "你好!我是Claude..." → 14400ms ✓
全部精确匹配 ffprobe
静音时长不含推测余量,纯按实际 TTS 音频长度来,用户话音一落地就恢复收音 09:45 fix: echo in VAD STT TTS 回声问题修复
新增静音机制 — 在 AI 通过 TTS 回答期间,暂时阻断麦克风音频进入 STT 和 VAD:
1. muted 标志 + muteTimer — 控制音频采集的静音状态
2. muteForTts(text) — 根据回复文本长度估算 TTS 播放时长,自动管理静音期:
- 估算公式:max(3000ms, text.length × 100ms + 1500ms)
- 中文字符约 125ms/字,英文约 83ms/字符,+1s 生成/网络开销 + 0.5s 余量
- 最短 3 秒
3. clearMute() — 用户按 F2 结束通话时立即清除静音状态
4. arecord 回调中的 feedAudio(c) — 静音时直接 return,音频不进入 STT 也不进入 VAD
完整流程:
用户说话 → 音频 → STT → 转录 → AI → broadcastResponse()
↓ TTS生成成功 + 采集进行中
muteForTts(text)
↓
静音期间所有音频丢弃
↓ (TTS播放完毕)
setTimeout → unmute
↓
恢复音频采集 09:37 feat: VAD 08:51 feat: polling voice create stt 5s 架构变更:浏览器 VAD → 服务器端定时分段
根本问题
onnxruntime-web WASM 后端在 Tauri 的 WebKitGTK
中无法运行(即使所有文件都在本地提供)。这是 WebKitGTK 的一个已知限制。
解决方案
不再尝试在浏览器中运行 VAD。改为服务器端的定时音频分段:
F2 开始 → 服务器用 cpal/arecord 录制音频 → 每 5 秒:
├─ 结束当前 STT 连接 → Groq 转写 → sendText() → CLI 对话
└─ 创建新的 STT 连接,继续录制
F2 结束 → 清理
变更文件
┌──────────────────┬────────────────────────────────────────────────────────────┐
│ 文件 │ 变更 │
├──────────────────┼────────────────────────────────────────────────────────────┤
│ FriendService.ts │ 新增定时分段:_flushSegment() + captureTimer,将音频分段为 │
│ │ 5 秒窗口,自动发送到 CLI │
├──────────────────┼────────────────────────────────────────────────────────────┤
│ useServerStt.ts │ 完全重写:移除浏览器 VAD(@ricky0123/vad-web / │
│ │ onnxruntime-web),新增基于轮询的服务器端语音通话 │
├──────────────────┼─────────────────────────────────────────────────────────… 07:40 feat: VAD but just case choose 00:45 feat: cycle time activate check friend Jun 21 16:31 chore: update news 16:28 feat: /voice use best grop whisper provider free and fast 15:30 feat: grop free stt 14:31 feat: /friend tts add websearch 14:11 feat: friend text tts ok but websearch tts not ok 13:28 fix: Microphone access denied 12:07 feat: inter-process 架构对比
之前: 之后:
CLI TUI CLI TUI (单一进程)
└── /friend start ├── FriendService (in-process, cpal)
├── 服务器子进程 :3456 │ ├── STT via cpal
│ ├── chat-service.ts │ ├── enqueue() → 主 CLI
│ │ └── CLI SDK 子进程│ └── SSE → Tauri
│ ├── arecord 子进程 ├── 轻量 Bun.serve (in-process)
│ └── SSE └── Tauri (thin display only)
└── Tauri (getUserMedia) 08:11 feat: csp null 00:30 feat: full screen friend Jun 20 19:28 fix: friend render 18:20 chore: cancel exc /friend (no content) 17:50 fix: /friend start stop (no content) 17:32 fix: auto esc /friend start stop 17:20 fix: after /friend stop can esc 17:16 fix: esc in /friend start 1. 启动 Tauri 窗口(异步,后台运行)
2. 渲染 FriendStartView 组件,显示状态信息
3. 按 Esc 或 Enter 关闭 TUI 面板,Tauri 窗口继续在后台运行
launchTauri 之前用了 await 会阻塞 UI,现在改成了直接调用让它在后台异步运行。试试 /friend start 看看效果 16:45 fix: just friend desktop no browser 16:34 feat: /friend start tauri app