Tencent / Tencent/teamai-cli

[bug] UserPromptSubmit 钩子把 prompt 原文明文落盘:~/.teamai/debug.log 与 dashboard/events.jsonl(字段名 promptSummary,实际存全文)

Open
#664 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
4.8k
Forks
342
Avg merge
13h 48m
Merged PRs (30d)
211

Description

English summary — teamai's UserPromptSubmit hook persists the full text of the user's
prompt
to two plaintext files on disk:
~/.teamai/debug.log ([prompt=<full text>]) and
~/.teamai/dashboard/events.jsonl ("promptSummary":"<full text>").
The field is named promptSummary, but it stores the complete prompt, not a summary.
Consequence: any credential or token a user pastes into an AI tool prompt is written to disk in
clear text and kept indefinitely — debug.log has no rotation. Verified blast radius: this does
not reach the team repo (stats/*.yaml holds only aggregate counters, no prompt text), but the
two local files are enough. Suggested fix: stop persisting prompt content (store length, a hash, or
a redacted form), or make it opt-in; and rename/truncate the field so it matches its name.

Description

teamai 的 UserPromptSubmit 钩子会把用户 prompt 的完整原文写进两个本地明文文件。

~/.teamai/debug.log

2026-09-19T11:28:26.798Z [DEBUG] dashboard: recorded prompt_submit for session <session-id> [prompt=<prompt 全文>]

~/.teamai/dashboard/events.jsonl

{"type":"prompt_submit","timestamp":"...","sessionId":"...","tool":"workbuddy","cwd":"...","promptSummary":"<prompt 全文>"}

注意 events.jsonl 里的字段名是 promptSummary,但它存的不是摘要,而是一字不差的全文(本次实测:prompt 只有一句话,落盘内容与该句完全一致)。这个命名会误导使用者以为记录的是脱敏摘要,从而低估风险。

为什么这是个问题

用户把敏感信息粘进 AI 工具的对话框是很常见的操作——「这是我的私人令牌」「这是数据库密码」「帮我改一下这个连接串」。而在装了 teamai 的机器上,这个动作会把凭据永久留在磁盘上

  • 用户不会有任何提示,也不会预期"提问内容被落盘";
  • ~/.teamai/debug.log 是持续追加的调试日志,没有轮转,历史越积越长;
  • 这两个文件默认就是普通用户可读,任何能读用户目录的进程/备份/同步工具都能拿到;
  • 用户发现后能做的事只有一件——吊销凭据。因为日志、会话记录、各类 trace 里已经散落了多份副本,逐个清理既不完整也不现实。

本次的真实触发场景:用户为了让我通过 API 关闭一个 PR,在对话里贴了 Gitee 私人令牌。该令牌随即出现在上述两个文件中。排查时还有一层困扰——无法从落盘内容判断是谁写的,因为钩子记录的是 prompt 本身,看起来就像"某段代码把令牌写进了日志"。

已核实的爆炸半径(供维护者参考)

好消息是它没有扩散到团队仓库

# team-repo 工作区、全部历史、远端 master 均无命中
git grep -I "<token>" $(git rev-list --all)   # 空
git grep -I "<token>" origin/master           # 空

stats/<user>.yaml 只存聚合计数,不含 prompt 文本:

username: C
updatedAt: 2026-09-19T11:03:31.693Z
skills: {}
interventions:
  sessions: 5
  interrupt: 0
  toolReject: 0
  correction: 0
prompts: 11
tokens:
  input: 0
  output: 0
  cacheRead: 0
  cacheCreation: 0

也就是说:聚合成 prompts: 11 是对的、也是有用的,问题在于把内容也一起写进了本地文件。

Reproduction

  1. 在已安装 teamai 的环境里,通过任意受管工具(本机为 WorkBuddy)提交一条包含唯一字符串的 prompt,例如 MY_UNIQUE_MARKER_9f3c
  2. 检索:
grep -rl "MY_UNIQUE_MARKER_9f3c" ~/.teamai/
  1. 命中结果:
~/.teamai/debug.log
~/.teamai/dashboard/events.jsonl
  1. 查看命中行:两者都包含该标记的完整 prompt 文本events.jsonl 里字段名为 promptSummary

Environment

  • OS: Windows 11 25H2 (10.0.26200)
  • Node.js: v22.22.2
  • teamai: 0.24.0
  • Provider: Gitee
  • AI tool(s): WorkBuddy(钩子对所有 UserPromptSubmit 启用工具都生效)

Logs

落盘内容(敏感串已打码)

~/.teamai/debug.log

2026-09-19T11:28:26.798Z [DEBUG] dashboard: recorded prompt_submit for session <sid> [prompt=<REDACTED-TOKEN> 这是我的私人令牌。]

~/.teamai/dashboard/events.jsonl

{"type":"prompt_submit","timestamp":"2026-09-19T11:28:26.777Z","sessionId":"<sid>","tool":"workbuddy","cwd":"d:\\workbuddyworkspace","promptSummary":"<REDACTED-TOKEN> 这是我的私人令牌。"}

注意 promptSummary 与原始 prompt 逐字相同。

Suggested fix

按破坏性从小到大:

  1. 字段改名 + 截断。 若确实要留 prompt,promptSummary 就应当真的是摘要(例如前 N 个字符 + 省略标记),不要存全文。命名与行为不一致是最容易误导的一环。
  2. 降级为可度量信号。 仪表盘真正需要的似乎只是计数(prompts: 11 这类聚合已经足够且有价值)。可以只记录长度 + 哈希,既能统计、又能对同一 prompt 去重,还不落内容。
  3. 默认不落内容,需要时显式开启。 例如 sharing.dashboard.capturePromptText: false 作为默认,让需要排查问题的用户自己打开。
  4. 加轮转与权限收紧。 debug.log 目前只增不减,且包含 prompt 原文。给它加大小上限/轮转,并在创建时收紧文件权限,至少能限制窗口期。
  5. 文档里写明这一点。 无论最终选哪个方案,"提问内容会被写到哪里"都应当让用户能查到——本次排查里这层信息完全缺失。

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Trace the UserPromptSubmit hook and the writers for ~/.teamai/debug.log and ~/.teamai/dashboard/events.jsonl, then reproduce the issue with a unique marker and grep. Determine which prompt data is required by the dashboard; done means prompt text is no longer persisted, aggregate prompt counts still work, and the marker is absent from both files.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
observability, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.