内容
# 为什么线上 — 公司记忆引擎
<div align="center">
### 您的公司忘记了为什么做出的每个决定。
三月份的 Slack 线程没人能找到。
没人能解释清楚的定价规则。
您拒绝的供应商 — 因为 Sarah 离开了而原因也随之消失。
**每个季度,都会有人问 "为什么我们要这样做?"**
**每个季度,您都要花两周的时间让六个人重新发现您已经做出的决定。**
这不是文档问题。这是 **机构失忆**。
---
**为什么线上是实际交付的 why 层。**
服务器端 SQLite,您的整个团队共享 — 而不是一个浏览器标签页的内存。
BM25 检索 — 而不是将您的整个语料库塞进每个提示。
每个答案都有凭证 — Slack永久链接,文档链接,Jira 密钥。
询问: *"为什么我们不支持在德国进行年度计费?"*
获取线索。不是关键词汤。 **实际的推理。**
从 **Slack** (📌 或 `/whyline`),**电子邮件** (`decisions@`),**会议记录**,**Notion/Confluence/GDocs**,**GitHub PRs**,**Teams**,**Linear**,**Jira** — 或直接通过 **MCP** 在 Cursor 中与其交谈。
克隆它。插入您的 API 密钥。 60 秒即可运行。
**免费。本地。属于您。**
[询问原因](#quick-start) · [捕获](#features) · [MCP + Cursor](#mcp--cursor)
</div>
---
## v2 更新内容
我们不再假装 IndexedDB 是 "公司记忆"。v2 是可用的底层基础设施:
| 层 | 功能 |
|-------|----------------|
| **SQLite** (`data/whyline.db`) | 共享决策存储 — 浏览器清除后仍存在,适用于整个团队 |
| **BM25 检索** | 每个问题的 top-k 决策 — 扩展到数百条记录之外 |
| **凭证** | 每个决策都链接回去 — Slack,电子邮件,文档 URL,Jira 密钥 |
| **线程级捕获** | 完整的 Slack 线程,而不是每个消息的垃圾 |
| **MCP** | `whyline_ask` / `whyline_extract` / `whyline_search` — Cursor 成为客户端 |
`.env` 永不被提供。默认绑定:`127.0.0.1`。需要 Webhook 机密,而不是可选。
---
## 快速开始
```bash
git clone https://github.com/Sunradiance/whyline.git
cd whyline
cp .env.example .env
# 编辑 .env — 添加 LLM_API_KEY
npm run setup
npm run dev
```
打开 **http://127.0.0.1:8793**
`npm run dev` 使用 Flask 的内置服务器 — 适用于本地使用。对于共享团队部署,请使用生产 WSGI 服务器(原子捕获声明使多工作进程安全):
```bash
pip install gunicorn
gunicorn -w 4 -b 127.0.0.1:8793 'app:create_app()' --chdir backend
```
在 Windows 上:`pip install waitress` 然后 `waitress-serve --listen=127.0.0.1:8793 --call app:create_app` 从 `backend/`。
### 最小 `.env`
```env
LLM_API_KEY=gsk_...
LLM_BASE_URL=https://api.groq.com/openai/v1
LLM_MODEL_NAME=qwen/qwen3-32b
WHYLINE_HOST=127.0.0.1
```
---
## MCP + Cursor
为什么线上是一个 MCP 服务器。您的 IDE 中的每个 AI 助手都可以查询机构记忆 — 并写入其中。
**工具:** `whyline_ask` · `whyline_extract` · `whyline_search`
### 一次性设置
```bash
npm run setup # 如果您尚未设置
```
复制 `.cursor/mcp.json.example` → `.cursor/mcp.json` (或使用包含的项目配置)并调整路径。
重启 Cursor → **设置 → MCP** → 启用 **whyline**。
现在在聊天中询问: *"Whyline:为什么我们拒绝 Acme CDN?"* — 它会命中您的本地 SQLite 语料库,并附上凭证。
详情: [`integrations/mcp/README.md`](integrations/mcp/README.md)
---
## 功能
- **询问原因** — 带有验证的 `decisionIds` 和可点击凭证的检索支持答案
- **决策注册表** — 搜索,过滤,生命周期更新
- **捕获** — 会议记录,电子邮件,文档(Notion/Confluence/GDocs),Slack/Teams 线程
- **Slack** — `/whyline` 斜杠命令 + 📌 反应 → 完整线程捕获
- **decisions@** — CC 电子邮件别名 → 提取 + 持久化 ([设置](integrations/email/README.md))
- **Jira / GitHub / Linear / Teams / Salesforce** — Webhook 抓取凭证
- **记忆摘要** — 为领导层导出
演示种子数据:DACH 计费,Acme CDN,Teams 功能删除。
---
## 集成(实时)
| 来源 | 端点 | 认证 |
|--------|----------|------|
| **电子邮件** `decisions@` | `POST /api/integrations/email/ingest` | `X-Whyline-Secret` |
| **Slack** `/whyline` + 📌 | `/api/integrations/slack/commands` + `/events` | Slack 签名 |
| **会议记录** | `POST /api/integrations/transcript/ingest` | 会话 / API 密钥 |
| **Notion / Confluence / GDocs** | `POST /api/integrations/doc/ingest` | 会话 / API 密钥 |
| **GitHub / GitLab** | `POST /api/integrations/github/webhook` | `X-Hub-Signature-256` |
| **MS Teams** | `POST /api/integrations/teams/ingest` | `X-Whyline-Secret` |
| **Linear** | `POST /api/integrations/linear/webhook` | `X-Whyline-Secret` |
| **Jira** | `POST /api/integrations/atlassian/jira` | `X-Whyline-Secret` |
| **Salesforce** | `POST /api/integrations/salesforce/webhook` | `X-Whyline-Secret` |
| **MCP** | `npm run mcp` | 本地标准输入输出 |
文档: [`integrations/email`](integrations/email/README.md) · [`integrations/slack`](integrations/slack/README.md) · [`integrations/mcp`](integrations/mcp/README.md) · [`integrations/github`](integrations/github/README.md)
---
## 团队模式和访问控制
设置 `WHYLINE_AUTH_MODE=team` (或 `open`)用于多租户部署。 Solo 保留为零配置默认值。
| 角色 | 读取 | 创建决策 | 管理决策 | 邀请/删除成员,铸造/撤销令牌 | 工作区设置 |
|------|------|------------------|------------------|-------------------------------------------|-------------------|
| 查看者 | ✓ | | | | |
| 成员 | ✓ | ✓ | | | |
| 管理员 | ✓ | ✓ | ✓ | ✓ | |
| 所有者 | ✓ | ✓ | ✓ | ✓ | ✓ |
**取消配置:** 删除离职用户的成员资格 (`DELETE /api/workspaces/<id>/members/<user_id>`) 并审计工作区令牌 (`GET /api/workspaces/<id>/tokens`),撤销他们可能看到的任何令牌 (`DELETE /api/workspaces/<id>/tokens/<token_id>`).
**服务令牌是基础设施凭证** — 工作区范围,而不是用户范围。MCP、CI 和集成密钥在明确撤销之前保持有效。这是故意的:令牌的生命周期长于任何单个用户帐户。注销时,所有者通过列表端点旋转令牌;成员删除不会影响他们铸造的令牌。
身份验证模式棘轮:已启动 `team`/`open` 的数据库如果未设置 `WHYLINE_AUTH_MODE`,则拒绝静默降级为 `solo`。仅当 `WHYLINE_ALLOW_SOLO_DOWNGRADE=1` 时才可覆盖。
---
## 测试
```bash
npm run test
```
97 个测试 · 主分支推送时 CI
---
## 支持(自愿)
MIT 许可。无付费墙。永远。
如果您喜欢这个项目,请使用 **SOL** 在 Solana 上支持我们:
```
B4ZFerkb7DctTLabgzh3F8aGhJF7EVDxcnLz6e2zqZwb
```
在本地运行?在 `.env` 中设置 `SOL_DONATION_ADDRESS` (或在配置完成后使用 **◎ 使用 SOL 支持**)。仅自愿提示 — Solana 链,SOL 代币。
---
<div align="center">
**为什么线上** — 记得的决策。
*您公司从未有的 why 层 — 现附凭证。*
</div>