抄写员
AI代理的工作图。Scribe是一个具有原生DAG支持的结构化工件存储,它允许AI编码助手跨会话规划、跟踪和调用工作,超越了单个上下文窗口的限制。
快速开始
容器(推荐)
# podman or docker
podman run -d --name scribe \
-p 8080:8080 \
-v scribe-data:/data \
quay.io/dpopsuev/scribe:v1.5.2二进制
go install github.com/dpopsuev/scribe/cmd/scribe@latest
scribe serve # stdio (Cursor, Claude Desktop)
scribe serve --transport http # Streamable HTTP on :8080MCP配置
光标/克劳德桌面(stdio--本地二进制):
{
"mcpServers": {
"scribe": {
"command": "scribe",
"args": ["serve"]
}
}
}光标/克劳德桌面(HTTP--容器):
{
"mcpServers": {
"scribe": {
"url": "http://localhost:8080/?workspace=origami"
}
}
}工作流程
Scribe是为自然语言而设计的。你和你的代理交谈,它会在幕后构建工作图。
你: 我想要v1.0的身份验证和速率限制。 代理人: 已经有了限速规范。我为auth创建了一个规范。你今天的目标是什么?
你: 我需要加强安全性——我们发现了一个令牌泄漏漏洞。 代理人: 我已经进行了一次审计,并为安全强化创建了一个目标。提交 BUG-1: Token leak你也想要一场竞选吗?你: 对。 代理人: 活动准备就绪。这是审计和简报——3个任务,认证修复的规范,泄漏的bug,topo-sort显示执行顺序。先认证修复,然后限速,然后泄漏补丁。
你: 执行活动。 代理人: *(完成任务)* 安全强化行动完成。3个任务已关闭,代码已提交,所有测试均为绿色。
问题
LLM上下文窗口是有限的。一个编码代理可以在工作内存中保存大约10万个令牌。当一个会话结束时,它学到的一切——目标、决策、依赖关系、进度——都会消失。
这会产生三种故障模式:
- 失忆症。 代理在每个会话中从头开始重新发现相同的代码库。
- 漂移。 多届会议的工作失去了连贯性,因为没有关于决定内容和原因的共同记录。
- 碎片化。 分散在聊天记录、markdown文件和问题跟踪器中的计划无法以图形形式查询或遍历。
Scribe通过为代理提供一个结构化的、持久的内存来解决这个问题,他们可以通过MCP工具进行读写——一个在可查询的DAG中存储活动、目标、规格、任务、错误及其关系的地方。
核心概念
| 概念 | 它是什么 |
|---|---|
| 人工制品 | 世界纪录。一切都是一个具有种类、状态、范围和自动生成ID的工件(例如。 TASK-2026-042). |
| 亲切的 | 人工制品的类型。标准类型: goal, task, spec, bug, campaign, template, need, ref, doc, decision, config, mirror。通过模式验证强制执行。 |
| 任务 | 主要工作单位。任务包含目标陈述、设计部分和依赖边。任务 实施 规格和错误。 |
| 规格 | A规格: *什么* 和 *为什么*.定义验收标准。任务执行规范。 |
| 程序错误 | 缺陷记录。与规范一样,bug由实现它的任务来解决 |
| 目标 | 瞄准镜的北极星人工制品。设置目标会自动创建根交付工件并存档任何先前的目标。 |
| 状态 | 生命周期状态: draft → active → complete / dismissed此外: current (目标), retired, archived. |
| 范围 | 工件所属的项目或存储库(例如。 locus, origami).从单个Scribe实例启用多项目规划。 |
| 部分 | 附加到工件的命名文本块。用于设计说明、美人鱼图、验收标准或任何结构化内容。 |
| 运动 | 跨项目任务容器。将目标、规格和任务分组到一个主题下(例如“v1稳定”)。 |
| 模板 | 元工件(关于工件的工件)。定义一种所需的部分和指导。工件通过以下方式链接到模板 satisfies. |
| 需要 | 需求或能力差距。证明目标和规格的合理性。 |
| 配置 | 运行时配置工件。部分是具有级联分辨率(范围>全局)的键值对。 |
| 边缘 | 定向关系: parent_of, depends_on, follows, justifies, implements, documents, satisfies。边形成代理可以遍历的DAG。 |
人工制品关系
graph LR
subgraph "Organizes Work"
CAMPAIGN["campaign"]
GOAL["goal"]
end
subgraph "Defines Work"
SPEC["spec"]
BUG["bug"]
NEED["need"]
end
subgraph "Does Work"
TASK["task"]
end
TEMPLATE["template"]
CAMPAIGN -- parent_of --> GOAL
GOAL -- parent_of --> TASK
GOAL -- parent_of --> SPEC
GOAL -- parent_of --> BUG
TASK -- implements --> SPEC
TASK -- implements --> BUG
TASK -- depends_on --> TASK
TASK -. follows .-> TASK
NEED -. justifies .-> SPEC
CAMPAIGN -. satisfies .-> TEMPLATE
GOAL -. satisfies .-> TEMPLATE
TASK -. satisfies .-> TEMPLATE
SPEC -. satisfies .-> TEMPLATE
BUG -. satisfies .-> TEMPLATE活动 是将目标分组的任务容器。 目标 是北极星伪影,是规范、任务和bug的母体。 规格 和 漏洞 定义 *什么* 必须发生。 任务 实现规范并解决错误。 depends_on 边缘强制执行顺序; follows 边缘表示ROI顺序。这 detect 当任务没有spec/bug链接,或者spec/bug没有实现任务时,管理工具会发出警告。
工件图示例
graph TD
CMP["SCR-CMP-1\nv1.0 Campaign\n(active)"]
GOAL["SCR-GOL-1\nv1.0 Release\n(current)"]
CMP -->|parent_of| GOAL
SPEC["SCR-SPC-1\nAuth Spec\n(complete)"]
GOAL -->|parent_of| SPEC
BUG["SCR-BUG-1\nToken Leak\n(open)"]
GOAL -->|parent_of| BUG
TSK1["SCR-TSK-1\nImplement Auth\n(complete)"]
TSK1 -.->|implements| SPEC
GOAL -->|parent_of| TSK1
TSK2["SCR-TSK-2\nRate Limiting\n(active)"]
TSK2 -.->|depends_on| TSK1
GOAL -->|parent_of| TSK2
TSK3["SCR-TSK-3\nFix Token Leak\n(draft)"]
TSK3 -.->|implements| BUG
GOAL -->|parent_of| TSK3实心箭头是 parent_of 边缘(树形结构)。虚线箭头是 implements, depends_on,或 follows 边缘(语义)。代理人使用 graph next 找到依赖项都已完成的最高优先级未阻塞任务。
建筑
生成的图表 轨迹 (locus diagram --theme natural).按健康状况着色的组件:绿色=健康,黄色=生病(粉丝人数>=3,流失人数>=8),红色=致命。依赖图
locus diagram /path/to/scribe --type dependency --theme natural%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#F7FAFC', 'primaryTextColor': '#2D3748', 'primaryBorderColor': '#4A90D9', 'lineColor': '#4A90D9', 'background': '#FFFFFF', 'fontSize': '14px'}}}%%
graph TD
classDef boundary fill:#FFFFFF,stroke:#718096,color:#2D3748
classDef component fill:#F7FAFC,stroke:#4A90D9,color:#2D3748
classDef edge stroke:#4A90D9
classDef entry fill:#4A90D9,stroke:#4A90D9,color:#FFFFFF
classDef fatal fill:#E53E3E,stroke:#E53E3E,color:#FFFFFF
classDef healthy fill:#38A169,stroke:#38A169,color:#FFFFFF
classDef sick fill:#D69E2E,stroke:#D69E2E,color:#FFFFFF
classDef violation_edge stroke:#E53E3E
cmd_scribe["cmd/scribe [churn:12]"]:::entry
config["config [churn:6]"]:::healthy
directive["directive [churn:6]"]:::healthy
keygen["keygen [churn:2]"]:::healthy
lifecycle["lifecycle [churn:7]"]:::healthy
mcp["mcp [churn:20]"]:::healthy
mcpclient["mcpclient [churn:1]"]:::healthy
model["model [churn:9]"]:::sick
protocol["protocol [churn:14]"]:::sick
render["render [churn:1]"]:::healthy
store["store [churn:13]"]:::sick
web["web [churn:6]"]:::healthy
cmd_scribe -->|"13"| config
cmd_scribe -->|"7"| directive
cmd_scribe -->|"2"| mcp
cmd_scribe -->|"6"| mcpclient
cmd_scribe -->|"18"| model
cmd_scribe -->|"90"| protocol
cmd_scribe -->|"3"| render
cmd_scribe -->|"6"| store
cmd_scribe -->|"1"| web
config -->|"2"| model
config -->|"5"| protocol
config -->|"1"| store
lifecycle -->|"6"| model
lifecycle -->|"6"| store
mcp -->|"8"| directive
mcp -->|"6"| mcpclient
mcp -->|"9"| model
mcp -->|"88"| protocol
mcp -->|"3"| render
mcp -->|"1"| store
protocol -->|"1"| keygen
protocol -->|"5"| lifecycle
protocol -->|"57"| model
protocol -->|"21"| store
render -->|"24"| model
store -->|"40"| model
web -->|"2"| model
web -->|"12"| protocol层次图
locus diagram /path/to/scribe --type layers --theme natural%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#F7FAFC', 'primaryTextColor': '#2D3748', 'primaryBorderColor': '#4A90D9', 'lineColor': '#4A90D9', 'background': '#FFFFFF', 'fontSize': '14px'}}}%%
block-beta
columns 1
block:layer_0["Layer 0"]
cmd_scribe["cmd/scribe"]
end
columns 3
block:layer_1["Layer 1"]
config["config"]
mcp["mcp"]
web["web"]
end
columns 4
block:layer_2["Layer 2"]
directive["directive"]
mcpclient["mcpclient"]
protocol["protocol"]
render["render"]
end
columns 2
block:layer_3["Layer 3"]
keygen["keygen"]
lifecycle["lifecycle"]
end
columns 1
block:layer_4["Layer 4"]
store["store"]
end
columns 1
block:layer_5["Layer 5"]
model["model"]
end包裹
| 套餐 | LOC | 流失 | 角色 |
|---|---|---|---|
cmd/scribe | 1880 | 19 | CLI入口点。每个MCP工具都有一个等效的CLI。Capsule和seed dir命令。 |
mcp | 3215 | 44 | MCP服务器。工件、图形和管理工具的处理程序。批量操作,差异,top-N,影响。 |
protocol | 4939 | 38 | 所有业务逻辑。胶囊导出/导入、种子、配置解析、模板一致性。 |
model | 1048 | 25 | 数据模型: Artifact, Section, Edge, Filter, Schema, IDConfig. |
store | 2656 | 30 | 持久化接口+SQLite。带有可插拔后端的快照。 |
render | 281 | 2 | 用于CLI和MCP输出的Markdown和表格式化程序。 |
config | 281 | 12 | 配置加载、工作区定义、seed_dir |
directive | 119 | 6 | MCP工具注册表和输入验证。 |
keygen | 214 | 2 | 按工件类型自动生成ID序列。 |
web | 371 | 7 | 用于工件浏览和冲刺板的Web UI。 |
存储
单一SQLite数据库(CGo免费通过 modernc.org/sqlite).桌子:
- 人工制品 --UID主键(加密/随机十六进制),人类可读的ID作为唯一索引,碰撞时自动重命名。JSON用于数组/映射。
- 边缘 --有向图:
(from, to, relation)具有独特的约束。 - 序列 / scoped_sequences --带有碰撞检查的自动递增计数器。
快照:使用可插拔后端(本地文件系统,未来的S3)进行自动定期备份。通过预还原备份进行还原 admin snapshot restore.
默认位置: ~/.scribe/scribe.sqlite (二进制)或 /data/scribe.sqlite (集装箱)。
数据模型
每件艺术品都带有:
- 身份: 自动生成的ID(
PREFIX-YYYY-SEQ)、种类、范围 - 内容: 标题、目标陈述、命名部分(任意文本块)
- 图表: 父级、依赖边、类型化链接(证明、实现、文档)
- 生命周期: 状态、优先级、冲刺分配、标签、时间戳
- 扩展名:
extra域特定键值对的映射(提醒、自定义字段)
词汇表被强制执行:未知类型被拒绝,并提示通过以下方式注册它们 scribe vocab add.未知字段进入 extra.
MCP工具
| 工具 | 说明 |
|---|---|
artifact | 创建、读取、更新和管理工作工件。行动: create, batch_create, clone, get (批量通过id、section_filter), list (紧凑字段、计数、group_by、前N名排名), set, update (补丁图), archive, attach_section, get_section, detach_section, diff.具有级联分辨率的模板自动链接。 |
graph | 导航和修改工件关系。行动: tree, briefing, topo_sort, link, unlink, bulk_link, bulk_unlink, move (重新父母), replace (交换目标), impact (下游分析)。关系:parent_of、depends_on、follows、justice、implementation、documents、conference。 |
admin | 系统管理和监控。行动: motd, changelog, dashboard, snapshot (创建/列表/差异/恢复), set_goal, vacuum, detect, lint, check, seed, transfer_scope (使用dry_run), set_scope_labels, list_scope_labels. |
配置
Scribe使用零配置。要进行自定义,请创建 scribe.yaml:
# scribe.yaml
db: ~/.scribe/scribe.sqlite
transport: stdio
addr: ":8080"
scopes:
- myproject
vocabulary:
kinds:
- goal
- sprint
- task
- spec
- bug
# add your own via: scribe vocab add
schema:
kinds:
goal: { prefix: GOAL }
sprint: { prefix: SPR }
task: { prefix: TASK }
spec: { prefix: SPE }
bug: { prefix: BUG }
campaign: { prefix: CON }
template: { prefix: TPL }
need: { prefix: NED }
statuses:
- draft
- active
- current
- complete
- dismissed
- archived
guards:
archived_readonly: true
completion_requires_children_complete: true
auto_archive_goal_on_justify_complete: true
delete_requires_archived: true
auto_complete_parent_on_children_terminal: true
auto_activate_next_draft_sprint: true
workspaces:
origami: [origami, asterisk, achilles]
sidecar: [scribe, locus, lex, limes]解决顺序: --config 旗帜> $SCRIBE_CONFIG > ./scribe.yaml > $SCRIBE_ROOT/scribe.yaml > ~/.scribe/scribe.yaml >内置默认值。
超控链: CLI标志>环境变量>配置文件>默认值。
工作区连接(HTTP): 添加 ?workspace=origami 指向MCP URL以限定到特定范围的连接。
对于容器,请在以下位置挂载配置文件 /data/scribe.yaml:
podman run -d --name scribe \
-p 8080:8080 \
-v scribe-data:/data \
-v ./scribe.yaml:/data/scribe.yaml \
quay.io/dpopsuev/scribe:v1.5.2环境变量
| 变量 | 默认值 | 描述 |
|---|---|---|
SCRIBE_ROOT | ~/.scribe | 储存根;设置默认数据库和配置路径 |
SCRIBE_DB | $SCRIBE_ROOT/scribe.sqlite | 数据库路径(覆盖 SCRIBE_ROOT) |
SCRIBE_TRANSPORT | stdio | 运输: stdio 或 http |
SCRIBE_ADDR | :8080 | 监听地址(仅限HTTP传输) |
SCRIBE_CONFIG | ./scribe.yaml 或 $SCRIBE_ROOT/scribe.yaml | 配置文件的路径(首先找到的获胜) |
SCRIBE_LOG_LEVEL | info | 日志级别: debug, info, warn, error.JSON转换为stderr。 |
SCRIBE_WORKSPACE | -- | stdio传输的工作区名称(从配置解析作用域)。 |
许可证
麻省理工学院
