本文件定义技能包所有生成文件的目录规则。任何工具、脚本或 Skill 生成文件时必须遵循本标准,并通过 mcp/src/core/output-paths.js 模块解析路径,禁止直接拼 process.cwd() + 'outputs'。
claude-code-qiwei-assistant/
├── bin/ # CLI 入口,不生成文件
├── mcp/ # MCP 服务源码与接口清单(catalog 为构建产物,由 scripts/build-catalog.py 生成)
├── skills/ # SKILL.md 定义,只读
├── scripts/ # 构建 / 安装 / 冒烟脚本
├── docs/ # 人工与生成文档(见第 4 节)
└── outputs/ # 所有运行期生成文件(见第 2 节,git 忽略)
统一根目录:<包根>/outputs,可用环境变量 QIWEI_OUTPUTS_DIR 覆盖。目录不存在时由 output-paths.js 自动创建。
第一层为固定类别,禁止在 outputs 根目录直接放文件:
| 类别 | 用途 |
|---|---|
login/ |
扫码登录二维码与预览页(保持固定文件名,最新一次覆盖) |
api-calls/ |
qiwei_api_call 落盘的请求/响应样本 |
subscription/ |
订阅、席位、余额查询快照 |
meetings/ |
官方 CLI 会议相关导出 |
docs/ |
官方 CLI 文档能力导出 |
messages/ |
消息发送记录与回执 |
knowledge/ |
持续知识库与知识沉淀(当前注册 meetings/) |
goals/ |
目标、里程碑与行动项状态 |
groups/ |
外部群同步结果与确认/导入映射 |
portraits/ |
客户画像 JSON |
broker-playbooks/ |
顾问 playbook JSON |
tags/ |
本地客户标签 |
transfers/ |
客户交接包 |
voice/ |
语音消息本地文件与转写结果 |
webhook/ |
Relay / 本地 webhook 回调事件(按 run 目录归档) |
relay/ |
Relay 客户端运行日志与状态 |
customers/ |
客户档案(customerId 为主键) |
brokers/ |
经纪人/顾问档案(brokerId 为主键) |
devices/ |
设备 guid → wecomUserId / brokerId 映射 |
smoke/ |
冒烟测试产物 |
tmp/ |
临时文件,可随时清理 |
dashboard/ |
Dashboard 本地状态与账号级投影 |
runtime/ |
Callback Runtime 等本地守护进程状态 |
outputs/<类别>/<固定文件名>,通过 latestPath(category, filename) 获取。run 模式(按次归档):适用于每次运行都要保留的产物。
路径:outputs/<类别>/<YYYY-MM-DD>/<HHmmss>-<slug>/,通过 createRunDir(category, slug) 创建。
每个 run 目录必须包含 manifest.json(用 writeRunManifest(runDir, meta) 生成),至少含:
{
"createdAt": "2026-07-12T09:00:00.000Z",
"tool": "qiwei_official_call",
"summary": {},
"files": ["meeting-list.json"]
}
persistent-store 模式(持续知识库):适用于需要跨次同步、增量更新和稳定索引的知识沉淀。
路径:outputs/<类别>/<已注册库名>/。库名必须在 OUTPUT_PERSISTENT_STORES 中注册;当前仅允许 outputs/knowledge/meetings/。
此模式可包含索引、按业务键组织的记录目录和说明文件,不按单次 run 生成 manifest。
account-scoped 模式(账号隔离):适用于客户、画像、标签、群、消息归档和 Dashboard 状态。
路径:outputs/<类别>/<account-key>/...。account-key 只能是企微 userId 的 16 位十六进制摘要,或迁移兼容用的 legacy-<slug>;原始 userId、昵称和企业名不得进入目录名。
允许类别由 OUTPUT_ACCOUNT_SCOPED_CATEGORIES 注册。账号目录内保存该账号的 latest/persistent 数据,不要求每个子目录生成 run manifest。
slugify() 生成,最长 60 字符。YYYY-MM-DD,时间用 HHmmss(UTC)。tmp/ 可随时删除;其余类别按日期目录归档,建议保留最近 30 天。outputs/ 整体在 .gitignore 中,不入库。mcp/src/core/output-paths.js 暴露:
outputsRoot() // outputs 根目录(含 QIWEI_OUTPUTS_DIR 覆盖)
categoryDir(category) // 确保并返回类别目录
latestPath(category, filename) // latest 模式路径
createRunDir(category, slug, date?) // run 模式目录
writeRunManifest(runDir, manifest) // 写 manifest.json
slugify(value) / dateStamp() / timeStamp()
OUTPUT_CATEGORIES // 允许的类别列表
OUTPUT_ACCOUNT_SCOPED_CATEGORIES // 允许账号隔离目录的类别
OUTPUT_PERSISTENT_STORES // 允许的持续知识库目录
新增输出类别时:先在 OUTPUT_CATEGORIES 注册,再更新本文件第 2 节表格。
docs/
├── OUTPUT-STANDARD.md # 本标准
├── specs/ # 设计与需求规格(人工撰写,kebab-case.md)
├── guides/ # 使用指南、课程讲义
├── research/ # 可复现的研究、基线与评测说明
└── generated/ # 脚本生成的文档,文件头必须注明生成脚本与时间,不手工编辑
docs/generated/,并以 <主题>-<YYYY-MM-DD>.md 命名;outputs/,不得写入 docs/;docs/ 入库(git 跟踪),outputs/ 不入库。运行 npm run outputs:validate(scripts/validate-output-standard.js)检查:
manifest.json;npm run check 已包含上述脚本的语法检查。