diff --git a/AGENTS.md b/AGENTS.md index 7c19b779..54f4fda9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -31,6 +31,7 @@ - 测试目标:测试应优先覆盖用户数据安全、数据库迁移、导入解析、权限/认证、AI 工具权限、配置/API key 迁移、跨端共享逻辑和已发生过的回归;不要为了提高数量给低风险 getter、常量、样式或纯展示细节机械补测 - 必须加测试:修复会影响用户数据、业务逻辑、异步任务、缓存状态、跨端共享 service、公开 API 契约、导入解析、去重逻辑、权限认证、AI 工具 allowlist、配置/API key 迁移或数据库 schema/迁移的行为 bug 时,必须先加能失败的回归测试;修改上述高风险模块时也必须加或更新测试 - 可以不加测试:只改 UI 文案、i18n key/翻译、样式、类型声明、日志、注释、无行为变化的小重构,或修复低风险展示细节时,可以不新增测试,但仍需运行相关类型检查、lint 和 format;不要为了低价值页面文案或源码字符串扫描新增脆弱测试 +- 低风险文档、示例、README、SKILL.md、`.docs`、package `files` 列表等说明/分发类改动,不要新增测试,也不要为了锁定文案、示例命令或文件存在性写脆弱测试;只做格式化、相关构建或必要静态检查。只有涉及用户数据、业务逻辑、导入解析、跨端 service、公开 API、权限/auth、数据库迁移、AI 工具 allowlist 或异步任务时,才新增或更新回归测试。 - 测试分层:纯函数、解析/格式化、权限判断、参数规范化、错误分支优先写单元测试;SQL 行为、数据库迁移、文件迁移、导入写库、Fastify route、跨包 service 优先写集成测试;Electron、真实浏览器、真实 LLM、真实网络仅用于少量关键 E2E/Smoke,并默认通过环境变量显式启用 - 避免重复测试:新增测试前先搜索同类断言;如果下层单测已覆盖算法,上层只测调用链是否接通,不重复枚举算法细节;如果测试只锁定实现写法、失败后不指向用户可见风险,应合并、改写或删除;优先写能覆盖全量场景的通用断言,而非针对单个条目的专项断言——若通用断言已完整覆盖,单个断言是冗余的 - 测试替身选择:涉及 SQL、数据库迁移、Fastify route 或跨包 service 时,优先使用轻量内存 SQLite / 临时文件 fixture 验证真实行为;只有在测试纯适配边界时才使用 mock/fake。避免用大量 `sql.includes(...)` 一类字符串匹配来模拟数据库行为 diff --git a/apps/cli/SKILL.md b/apps/cli/SKILL.md deleted file mode 100644 index c7416d03..00000000 --- a/apps/cli/SKILL.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -name: chatlab-cli -description: Query local chat history (WeChat/QQ/Telegram/WhatsApp and more) through the chatlab CLI. Use when the user asks what a chat group talked about, who said something first, conversation stats, topics, or keyword evidence from imported chat records. ---- - -# ChatLab CLI for AI Agents - -`chatlab` queries locally imported chat history. Read-only for agents: search, list, stats, topics, SQL fallback. Run `chatlab manifest` once to get the full machine-readable command tree (commands, options, exit codes, examples). - -## Contract - -- Always pass `--format` explicitly: `agent` for message bodies (preprocessed, token-friendly text), `json` for structural data (`--no-content`, `--fields`, stats). -- stdout carries exactly one JSON envelope per call; logs go to stderr. -- Success: `{ ok: true, command, data, meta }`. Failure: `{ ok: false, command, error: { code, message, hint, candidates? } }`. -- Exit codes: 0 ok, 2 bad argument/disabled capability, 3 not found, 4 ambiguous (retry with an id from `error.candidates`), 5 SQL error. -- Pagination: when `meta.hasMore` is true, re-run the same query with `--cursor `. -- Time: ISO dates (`2026-06-01`, `"2026-06-01 08:30"`), `today`, `yesterday`, or `--last 30d` (h/d/w). Date-only `--until` includes the whole day; resolved bounds are echoed in `meta.timeRange`. -- Members: pass an id, exact name, or `me` (the data owner). Ambiguity returns candidates with ids. -- Privacy preprocessing (desensitization, blacklist) is always on. Do not use `--raw`; it is disabled unless the user opts in. -- `[#1021]` markers in agent text are message ids; `[#1021*]` marks search hits; `[#1021-1024]` is a merged block. Use these ids as evidence citations. - -## Task recipes - -```bash -# Discover sessions (skip --session everywhere if there is only one) -chatlab sessions list --format json - -# "What did this group talk about today?" -chatlab messages list --session --since today --limit 100 --max-tokens 2000 --format agent - -# "Main topics this month?" (AI summaries; falls back to keywords if empty) -chatlab topics list --session --since 2026-07-01 --format agent -chatlab stats keywords --session --last 30d --top 20 --format json - -# "Who mentioned X first? Give evidence." -chatlab messages search "服务器迁移" --session --sort asc --limit 5 --context 3 --format agent - -# Follow up an evidence id from [#1021*] -chatlab messages context --id 1021 --session --window 10 --format agent - -# "What did I talk about with 小红 last month?" -chatlab messages between --member me --member 小红 --session --last 30d --format agent - -# "Who is most active?" -chatlab stats activity --session --top 10 --format json - -# Scout hit distribution before pulling bodies (json is correct here) -chatlab messages search "旅游" "旅行" --session --since 2026-01-01 --no-content --limit 100 --format json - -# Next page of results -chatlab messages search "报销" --session --cursor --format agent - -# Advanced fallback: read-only SQL (string cells are desensitized) -chatlab schema --session --format json -chatlab sql "SELECT strftime('%Y-%m', ts, 'unixepoch') AS m, COUNT(*) AS n FROM message GROUP BY m" --session --format json -``` - -## Token budget - -`--limit` caps primary hits, `--max-messages` caps context expansion, `--max-tokens` caps agent text (default 4000), `--max-chars` caps per-message length. Prefer narrowing time ranges and paginating over raising limits. diff --git a/apps/cli/package.json b/apps/cli/package.json index d4c9071d..3c01d8c2 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -12,7 +12,6 @@ "bin/", "dist/", "dist-web/", - "SKILL.md", "LICENSE" ], "engines": { diff --git a/docs/cn/usage/cli-query.md b/docs/cn/usage/cli-query.md index ff30ea38..7908458d 100644 --- a/docs/cn/usage/cli-query.md +++ b/docs/cn/usage/cli-query.md @@ -79,7 +79,19 @@ agent/json 模式下 stdout 只包含一个 JSON 响应信封,日志一律走 ## 给 Agent 的使用指南 -npm 包内附带 `SKILL.md`(Agent 使用指南:命令速查 + 任务配方),可放入项目的 `AGENTS.md`、Claude Code skill 或 Cursor rules。也可以让 Agent 直接执行 `chatlab manifest` 获取机读命令清单。 +推荐通过通用 Agent Skills CLI 安装官方 `chatlab-analyze` 技能: + +```bash +npx skills add ChatLab/ChatLab --skill chatlab-analyze -g +``` + +安装后,可以在 Codex、Claude Code、Cursor 等外部 Agent 中直接说: + +```text +chatlab-analyze 帮我分析我和小红的聊天记录 +``` + +这个技能会引导 Agent 先执行 `chatlab manifest` 获取机读命令清单,再用安全的 `--format agent/json` 查询聊天记录。 典型配方——"谁最早提到某个问题?给出证据": diff --git a/docs/en/usage/cli-query.md b/docs/en/usage/cli-query.md index 9440c824..92348127 100644 --- a/docs/en/usage/cli-query.md +++ b/docs/en/usage/cli-query.md @@ -79,7 +79,19 @@ Failures return `{ "ok": false, "error": { "code", "message", "hint", "candidate ## Agent usage guide -The npm package ships a `SKILL.md` (command quick reference + task recipes) you can drop into your project's `AGENTS.md`, a Claude Code skill, or Cursor rules. Agents can also run `chatlab manifest` to fetch the machine-readable command tree in one call. +Install the official `chatlab-analyze` skill through the general Agent Skills CLI: + +```bash +npx skills add ChatLab/ChatLab --skill chatlab-analyze -g +``` + +After installation, ask Codex, Claude Code, Cursor, or another external agent: + +```text +chatlab-analyze help me analyze my chat history with Alice +``` + +The skill tells the agent to run `chatlab manifest` first, then query chat records safely with explicit `--format agent/json` commands. A typical recipe — "who mentioned this first? give evidence": diff --git a/skills/chatlab-analyze/SKILL.md b/skills/chatlab-analyze/SKILL.md new file mode 100644 index 00000000..cc01eb8f --- /dev/null +++ b/skills/chatlab-analyze/SKILL.md @@ -0,0 +1,127 @@ +--- +name: chatlab-analyze +description: Analyze local ChatLab chat records through the chatlab CLI. Use when the user asks an external agent to inspect conversations, find evidence, summarize topics, compare members, or analyze a named relationship from imported ChatLab data. +--- + +# ChatLab Analyze + +Use this skill when the user asks you to analyze local ChatLab chat records, especially when they explicitly write `chatlab-analyze`, ask about a person or group in their chat history, or want evidence from imported conversations. + +Example user request: + +```text +chatlab-analyze 帮我分析我和小红的聊天记录 +``` + +Install this skill with: + +```bash +npx skills add ChatLab/ChatLab --skill chatlab-analyze -g +``` + +## What ChatLab Provides + +`chatlab` is a local CLI for querying chat records imported into ChatLab. Treat it as the source of truth for sessions, members, messages, statistics, topics, and read-only SQL fallback. + +The CLI is read-only for this skill. Do not modify ChatLab data, import files, change config, or start long-running services unless the user explicitly asks. + +## First Steps + +1. Check that the CLI is available: + +```bash +chatlab --help +``` + +2. Load the command contract before deeper work: + +```bash +chatlab manifest +``` + +3. List sessions. If exactly one session is relevant, use it. If multiple sessions may match the user's wording, ask a short clarification or show the likely candidates. + +```bash +chatlab sessions list --format json +``` + +## Privacy Rules + +- Always pass `--format` explicitly. +- Use `--format agent` when reading message bodies. +- Use `--format json` for structural scouting such as session lists, member lists, counts, fields, and `--no-content` searches. +- Do not use `--raw`. ChatLab disables raw output by default because the safe path applies the user's desensitization and blacklist rules. +- Do not reveal full chat dumps. Retrieve only the context needed for the user's question. +- Cite evidence with ChatLab message markers such as `[#1021]`, `[#1021*]`, or merged ranges like `[#1021-1024]` when available. + +## Common Workflows + +### Analyze a One-To-One Relationship + +Use this when the user asks about themselves and another person, for example "我和小红". + +```bash +chatlab members list --session --format json +chatlab messages between --member me --member --session --last 90d --format agent +chatlab stats keywords --session --member me --last 90d --top 20 --format json +chatlab stats keywords --session --member --last 90d --top 20 --format json +``` + +Then answer with patterns, concrete examples, and limits. If the retrieved time range is narrow, say so and offer the next query you would run. + +### Find Who Mentioned Something First + +```bash +chatlab messages search "" --session --sort asc --limit 5 --context 3 --format agent +chatlab messages context --id 1021 --session --window 10 --format agent +``` + +Use the earliest hit and its surrounding context as evidence. The `[#1021*]` marker identifies the matching message. + +### Summarize Recent Topics + +```bash +chatlab topics list --session --last 30d --format agent +chatlab stats keywords --session --last 30d --top 20 --format json +chatlab messages list --session --last 7d --limit 80 --max-tokens 3000 --format agent +``` + +Prefer topic summaries first. Use keywords and recent messages to verify or fill gaps. + +### Scout Before Pulling Message Bodies + +Use JSON scouting before retrieving many message bodies. + +```bash +chatlab messages search "" --session --since 2026-01-01 --no-content --limit 100 --format json +chatlab messages search "" --session --cursor --format agent +``` + +When `meta.hasMore` is true, continue with `--cursor ` using the same query conditions. + +### Read-Only SQL Fallback + +Only use SQL when dedicated commands cannot answer the question. + +```bash +chatlab schema --session --format json +chatlab sql "SELECT COUNT(*) AS n FROM message" --session --format json +``` + +SQL output still goes through ChatLab's privacy preprocessing for string values. + +## Answering Style + +- Start with the direct answer, then give evidence and caveats. +- Name the session and time range you actually queried. +- Separate observed facts from interpretation. +- For relationship analysis, avoid overclaiming emotional intent. Use language like "从这些记录看..." and ground claims in message evidence. +- If member names are ambiguous, stop and ask the user to choose from the candidate ids. +- If ChatLab returns an error envelope, follow `error.hint` and retry only when the correction is clear. + +## Useful Command Hints + +- Time supports ISO dates, `today`, `yesterday`, and `--last 30d`. +- Members can be ids, exact display names, aliases, or `me`. +- Pagination uses `meta.hasMore` and `meta.nextCursor`. +- Token controls: `--limit`, `--max-messages`, `--max-tokens`, and `--max-chars`.