makecindy / makecindy/cindy

[Feature] 支持在 Slack 新会话中持续关闭内置工具

Open
#78 1 comment 0 reactions 0 assignees View on GitHub
feature
Dominant language
TypeScript
Stars
2.7k
Forks
395
Avg merge
21h 48m
Merged PRs (30d)
776

Description

## 背景

用户通过 Slack Robot 与 Cindy 对话时,通常会进入新的 Cindy 会话。当前在“设置 → 内置工具”中关闭 Slack 工具后,后续 Slack 新会话仍会重新显示为开启,导致该工具在实际使用中逻辑上无法持续关闭。

本问题与 makecindy/cindy#36 描述的“普通内置工具缺少用户级默认开关”属于同一配置作用域问题。

Related: makecindy/cindy#36

## 当前现象

1. 用户通过 Slack Robot 发起对话,Cindy 创建一个新的会话。
2. 用户在该会话的“设置 → 内置工具”中关闭 Slack。
3. 再次通过 Slack Robot 进入新的 Cindy 会话。
4. Slack 工具重新回到默认开启状态。
5. 用户需要在每个新会话中重复关闭,无法形成稳定的用户偏好。

在没有有效项目工作目录的场景下,设置页的开关还可能直接处于不可操作状态。

## 源码分析

当前普通内置工具的 toggle 只写入项目级配置:

```ts
maker.plugins.setProjectEnabled(effectiveWorkingDir, id, next)
```

对应配置保存在:

```text
/.claude/settings.json
→ xdtMaker.builtinTools..enabled
```

普通插件的最终启用状态只依次读取:

1. 当前工作目录的项目 override;
2. 产品默认值。

目前不存在可供普通插件读取的用户级默认 override。只有 machine-wide 插件会读取全局配置。

Slack/无项目对话的工作目录按 session 创建:

```text
/dialogues//
```

因此,在会话 A 中关闭 Slack 时,配置只写入会话 A 的 dialogue 目录;会话 B 使用新的目录,无法读取会话 A 的配置,最终重新回落为产品默认开启。

当前 Slack 内置工具的 plugin id 为 `slack`,默认启用,且不属于 machine-wide 插件,所以能够稳定复现该问题。

## 期望行为

参考 makecindy/cindy#36,为普通内置工具补充用户级默认开关,并采用明确的配置优先级:

1. Essential 工具始终开启;
2. Machine-wide 工具沿用全局设置;
3. 项目 override;
4. 用户级默认值;
5. 产品默认值。

用户在无项目对话或 Slack 新会话中关闭 Slack 工具后,后续新建的无项目/Slack 对话都应继续遵循该用户级默认值。

项目仍然可以单独覆盖用户级默认值;清除项目 override 后,应重新跟随用户级默认值,而不是写入一份静态默认值快照。

## 建议验收标准

- [ ] 用户可以在没有项目工作目录时修改普通内置工具的用户级默认值。
- [ ] 将 Slack 内置工具的用户级默认值设为关闭后,连续创建多个 Slack 新会话,Slack 工具均保持关闭。
- [ ] 连续创建多个普通无项目对话时,同样遵循用户级默认值。
- [ ] 项目可以覆盖用户级默认值。
- [ ] 清除项目 override 后,重新跟随当前用户级默认值。
- [ ] 修改用户级默认值只影响新启动的 agent runtime,不改变正在运行的会话。
- [ ] 设置页能够区分“项目 override”“用户默认值”和“产品默认值”。
- [ ] Claude Code 与 Codex 使用相同的最终启用结果。
- [ ] 相关 UI 文案同步覆盖 zh-CN、en、ja、ko。

## 与 makecindy/cindy#36 的关系

本问题是 makecindy/cindy#36 在 Slack Robot 新会话场景中的直接表现,建议复用 makecindy/cindy#36 提出的用户级默认配置方案,不为 Slack 单独实现一套特殊的持久化逻辑。

Slack 消息是否应复用同一个 Cindy session,由 Slack Hook 的 `externalKey → sessionId` 绑定链路决定,不属于本 issue 已确认的根因;如后续确认同一 Slack thread 仍不断产生不同 session,应另行记录运行时的 `connectionId`、`externalKey` 和 archive 事件后再处理。

Contributor guide

Open the contributing guide

Research direction

Start by tracing maker.plugins.setProjectEnabled and the /.claude/settings.json path, then inspect how xdtMaker.builtinTools..enabled is resolved for new sessions. Review the settings UI and Slack Hook entry points around externalKey → sessionId. Done means user defaults, project overrides, new-session behavior, runtime boundaries, UI labels, and zh-CN/en/ja/ko coverage match the acceptance criteria.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
full-stack
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.