makecindy / makecindy/cindy

Pi 一轮只有一条用户消息时,灵动岛会因工具/权限状态连弹多次

Open
#3,127 3 comments 0 reactions 0 assignees View on GitHub
bug pi
Dominant language
TypeScript
Stars
2.7k
Forks
395
Avg merge
21h 48m
Merged PRs (30d)
776

Description

**客户端版本**: 0.1.57
**反馈类型**: bug

---

## 现象

本机 macOS 灵动岛在短时间内连续展开/弹出 10 次以上,但用户只给对应任务发了 **1 条消息**。岛上看到的也是同一个 session,不像多任务并发。

## 复现步骤

用户未提供稳定复现脚本。本机观察到的近似路径:

1. 用 Pi 任务发一条消息。
2. 该轮连续调用大量工具(本次还伴随第一方 iOS 模拟器 MCP;lease 过期后代理会反复拿新 lease)。
3. 用户可能不在看该任务主界面(例如在看模拟器,或另开了一个任务)。
4. 灵动岛短时间内连续弹出 10 次以上。

弹出卡片刷底是权限确认还是完成卡:**用户未知**。
当时任务权限档(完全访问 / Auto / 询问):**用户未知**。

## 期望行为

一条用户消息对应一个产品轮次时:

- 开始音 / 展开至多一次
- 跑着的工具调用只更新收起 pill 文案,不要每次 `tool_use` / 旁白都把岛弹开
- 正在看该任务时,权限卡不要每次都把岛撑开;Pi 若选「本任务总是允许」应真正记住

## 实际行为

岛连续展开 10 次以上,但 session / 用户消息仍只有一个。

## 复现频率

本机观察到 1 次。是否必现:**用户未知**。

## 已尝试

**用户未知**。

## 代码侧分析(用户同意公开)

灵动岛跟的是任务状态变化,不是用户消息条数。Pi 一轮会连续发 `text` / `tool_use` / `tool_result`,岛会跟着 publish。

**1. 权限卡从不智能抑制**

`shouldSmartSuppressSession()` 对 `permission` 直接 `return false`。正在看该任务时,权限卡仍会 blocking 展开。这是单测写死的现状。

**2. Pi 没有「本任务总是允许」记忆**

`prompt` 与 `prompt-each-time` 在 Pi 里收敛成每次都问。`cindy_ios_simulator` 不在 `TRUSTED_MCP_SERVERS`;截屏/点按等内层动作按设计 auto-approve,但 `create_instance` / `attach_device` / 带设备路由的 `build_app` 是每次确认。lease 过期后反复 attach 会一张张往岛上顶。

**3. 原生 helper 对每次 publish 都走展开弹簧**

`macos-agent-island-helper.swift` 里 `withAnimation(agentIslandOpenAnimation) { model.state = state }`。只要岛当时已展开,或宽度变了(例如运行中任务 1→2,徽章 `1` 变 `1/2`),每次工具状态都会再弹一下。`start` 音冷却只有 800ms。

**4. 背景任务不被抑制**

用户若在看模拟器或另一个任务,运行中的 Pi session 不算 visible-session,完成/权限都会真展开。

已排除:

- 同一条用户消息被重复投递
- 调度任务的静默完成卡
- helper 崩溃重启

建议修法:

- 正在看的 session,权限卡不要每次把岛撑开;Pi 「本任务总是允许」要真正持久化
- native helper 只在 `compact ↔ expanded` 时走展开弹簧,不要对每次 `tool_use` / 文案刷新动画
---
**版本区域**: CN
**OS**: darwin arm64 (25.4.0)
**界面语言**: zh-CN

Contributor guide

Open the contributing guide

Research direction

Start with macos-agent-island-helper.swift and shouldSmartSuppressSession(), then trace the Pi permission flow and TRUSTED_MCP_SERVERS handling described in the report. Verify the existing permission suppression test and the state-publish path before changing behavior. Done means one user message does not repeatedly trigger island expansion, tool updates refresh the pill without replaying the expansion animation, and the task-level allow choice persists.

Written by the indexing model from the issue text.

Assessment

Tech stack
macos, swift, typescript
Domain
ai, desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.