紫檀
人工智能辅助小说写作的叙事智能引擎。
  
Narra是一个用于虚构世界的结构化数据库——人物、地点、事件、场景、关系、知识、感知、事实和笔记——所有这些都可以通过局部嵌入按意义查询。
它超越了CRUD。Narra检测戏剧性的讽刺,通过嵌入漂移跟踪角色的演变,测量角色之间的感知差距,揭示未解决的紧张关系,聚类新出现的主题,发现知识冲突,通过关系网络跟踪影响传播,并预览假设场景-所有这些都不需要外部API调用。
一切都在本地运行:具有RocksDB持久性的嵌入式SurrealDB,通过快速嵌入的BGE-small-en-v1.5嵌入,单二进制,零运行时依赖关系。将其用作 CLI工具 或作为 MCP服务器 用于人工智能辅助写作工作流程。
目录
特性
世界建筑
- 角色 --具有结构化密钥(伤口、欲望、矛盾、秘密)和任意自定义密钥的灵活配置文件系统
- 位置 --具有类型的层次父子结构
- 事件 --具有可选日期和日期精度的顺序时间线
- 场景 --锚定到活动+地点,并键入参与者
- 关系 --7种内置类型(家庭、浪漫、专业、社交、对抗、导师、定制),带有子类型和标签
- 知识 --只附加7个确定性级别(知道、怀疑、相信、不确定、假设、否认、遗忘)和8种学习方法(告知、无意中听到、目睹、发现、推断、阅读、记住、初始)的分类账,完整来源(源字符、事件)
- 感知 --不对称:A对B的看法独立于B对A的看法,有感情、紧张程度和历史
- 宇宙事实 --具有执行级别的世界规则:信息性(仅上下文)、警告性(标记违规)、严格性(阻止突变)
- 备注 --可附加到任何实体的自由文本
- 导入/导出 --具有依赖顺序处理的往返YAML(字符→ 位置→ 事件→ 场景→ 关系→ 知识→ 笔记→ 事实)
叙事智能
| 能力 | 它做什么 |
|---|---|
| 语义搜索 | 按意义而不是关键字(“难以履行职责的角色”)查找实体 |
| 混合搜索 | 将关键字匹配与语义相似性相结合(“与Bob的背叛场景”) |
| 戏剧反讽 | 检测知识不对称——一些角色知道而另一些角色不知道的东西 |
| 感知差距 | 测量观察者对目标的错误程度(余弦距离:感知与现实) |
| 感知矩阵 | 多个观察者如何通过成对协议看到同一目标 |
| 电弧径迹 | 随时间嵌入快照:漂移排名、弧比较、矩检索 |
| 主题聚类 | K-means对实体嵌入进行聚类,以揭示涌现的故事主题 |
| 语义连接 | 跨领域查询,如“欲望与爱丽丝的伤口相冲突的角色” |
| 假设分析 | 预览嵌入从角色学习事实的转变——无需承诺 |
| 未解决的紧张局势 | 感知不对称性高、共享场景少的角色对——有待书写的场景 |
| 知识冲突 | 相信矛盾事实的角色(相信_强烈检测) |
| 影响传播 | 追踪信息如何在关系网络中传播 |
| 图形分析 | 中心度指标(度、介数、亲密度),用于寻找结构性主角和桥梁人物 |
| 一致性检查 | 根据宇宙事实、时间线顺序和引用完整性验证实体一致性 |
| 影响分析 | 预览哪些实体将受到更改的影响,以及严重程度 |
双接口
命令行界面:30多个命令,包括高级工作流(explore, ask, find),图形操作(path, references),实体管理(create, update, delete, protect),并组织了子命令: analyze (20+分析), world (状态、健康状况、导入/导出、回填、验证、图表), session (上下文,固定/取消固定)。
MCP服务器:5个工具,总共有70个操作——查询(40个操作)、变异(25个操作),会话(3个操作)。加上资源(narra:// URI)和工作流提示。
技术的
- 嵌入式SurrealDB+RocksDB——无需安装或管理外部数据库
- 本地BGE-small-en-v1.5嵌入件(384维,通过fastembed完全离线)
- graphers用于图分析,linfa用于K-means聚类
- 跨平台:macOS(英特尔+苹果硅)、Linux(x86_64+aarch64)
- 单个静态链接二进制文件,使用LTO发布版本
- JSON输出模式(
--json)用于脚本编写和集成
快速开始
# Install (macOS Apple Silicon — see Installation for other platforms)
curl -sL https://github.com/florinutz/narra/releases/latest/download/narra-aarch64-apple-darwin.tar.gz | tar xz
sudo mv narra /usr/local/bin/
# Create a character
narra create character --name "Alice Voss" --role "Detective" \
--description "Homicide detective haunted by her partner's unsolved murder" \
--profile '{"wound": ["partner murdered 3 years ago"], "secret": ["knows who did it"]}'
# Generate embeddings, then search by meaning
narra world backfill
narra find --semantic-only "characters hiding dark secrets"安装
来自GitHub发布
下载适用于您平台的最新二进制文件:
# macOS (Apple Silicon)
curl -sL https://github.com/florinutz/narra/releases/latest/download/narra-aarch64-apple-darwin.tar.gz | tar xz
sudo mv narra /usr/local/bin/
# macOS (Intel)
curl -sL https://github.com/florinutz/narra/releases/latest/download/narra-x86_64-apple-darwin.tar.gz | tar xz
sudo mv narra /usr/local/bin/
# Linux (x86_64)
curl -sL https://github.com/florinutz/narra/releases/latest/download/narra-x86_64-unknown-linux-gnu.tar.gz | tar xz
sudo mv narra /usr/local/bin/
# Linux (aarch64)
curl -sL https://github.com/florinutz/narra/releases/latest/download/narra-aarch64-unknown-linux-gnu.tar.gz | tar xz
sudo mv narra /usr/local/bin/来源
cargo install --git https://github.com/florinutz/narra.gitCLI命令参考
Narra的CLI为所有操作提供了直观的分层命令。命令支持 --json 脚本输出和 --brief/--full 用于详细控制的标志。
高级工作流
narra explore
对关系、知识、感知和语义相似的实体进行深入的实体探索。
narra explore alice # Full exploration
narra explore alice --no-similar # Skip similarity search
narra explore alice --depth 3 # Extend graph traversal depthnarra ask
关于你的叙事世界的自然语言查询。
narra ask "What secrets does Alice know that Gray doesn't?"
narra ask "Which characters are connected to the murder event?" --limit 20
narra ask "Show me all locations in the city" --context false # Skip contextual summariesnarra find [query]
使用自动混合搜索(关键字+语义)跨实体搜索。
# Basic search (hybrid by default)
narra find "Gray murder"
narra find "betrayal" --type scene --limit 10
# Semantic-only (find by meaning)
narra find --semantic-only "characters struggling with duty"
# Keyword-only (exact text matching)
narra find --keyword-only "Commissioner"
# Advanced search subcommands
narra find join "characters whose desires conflict with Alice's wounds"
narra find knowledge "the royal succession" --character alice
narra find graph alice "betrayal and deception" --hops 2
narra find perspectives "threatening and dangerous" --observer bob
narra find similar alice gray --bias "with more tension"查找子命令:
join--按意义进行跨类型语义搜索knowledge--在角色知识中搜索graph--图形接近度+语义相似性perspectives--按意义搜索感知/观点similar--查找与参考对相似的关系
narra path
查找实体之间的最短连接路径。
narra path alice eddie # Shortest paths
narra path alice eddie --max-hops 5 # Extend search depth
narra path alice eddie --include-events # Include event co-participationnarra references
发现什么引用了目标实体。
narra references alice # All references
narra references alice --types scene,event # Filter by type
narra references location:castle --limit 50实体管理
narra create
创建新实体: character, location, event, scene, knowledge, relationship, perception, fact, note.
# Character
narra create character --name "Alice Voss" --role "Detective" \
--description "Homicide detective haunted by her partner's murder" \
--profile '{"wound": ["partner murdered 3 years ago"], "secret": ["knows who did it"]}'
# Location
narra create location --name "Precinct 13" --loc-type "building" \
--description "Aging police station" --parent location:downtown
# Event
narra create event --title "The Confrontation" --sequence 10 \
--description "Alice confronts Gray with evidence" \
--date "2024-06-15" --date-precision day
# Scene
narra create scene --title "Gray's Office" --event event:confrontation \
--location location:city_hall --summary "The truth comes out"
# Knowledge
narra create knowledge --character alice --fact "Gray ordered the hit" \
--certainty knows --method discovered --event event:investigation
# Relationship
narra create relationship --from alice --to gray --type antagonistic \
--label "Hunter and prey — neither knows who is which"
# Perception
narra create perception --observer bob --target alice \
--perception "Sees her as relentless and dangerous" \
--feelings "fear, respect" --tension 8
# Fact (universe rules)
narra create fact --title "Magic requires sacrifice" \
--description "All magic extracts a personal cost" \
--categories physics_magic --enforcement strict
# Note
narra create note --title "Plot thread" --body "Revisit Eddie's backstory" \
--attach-to character:eddie,event:tipnarra get
按ID或名称检索任何实体(自动解析)。
narra get alice # By name (auto-resolves)
narra get character:alice # By full ID
narra get event:confrontationnarra list
列出具有可选筛选器的实体。
narra list character
narra list event --limit 50
narra list knowledge --character alice
narra list fact --category physics_magic --enforcement strict
narra list note --entity character:alicenarra update
更新实体字段。
# Update with JSON object
narra update character:alice --fields '{"role": "Lead Detective"}'
# Update individual fields
narra update character:alice --set role="Lead Detective" --set description="..."
# Link/unlink facts
narra update character:alice --link fact:magic_rules
narra update character:alice --unlink fact:old_rulenarra delete
删除实体(带影响分析提示)。
narra delete character:bob # Soft delete (respects protection)
narra delete character:bob --hard # Hard delete (bypass protection)实体保护
narra protect
将实体标记为受保护。受保护实体在影响分析中触发严重性临界,并要求 --hard 删除标志。
narra protect alice # Protect protagonist
narra protect event:climax # Protect key plot point
narra protect location:headquarters # Protect central location使用案例:
- 主角:防止意外删除主要角色
- 绘图锚点:保护故事所依赖的关键事件
- 世界基金会:保护核心位置或宇宙事实
narra unprotect
从实体中删除保护。
narra unprotect character:minor_npc分析命令
全部在 narra analyze :
# Network analysis
narra analyze centrality # Network centrality metrics
narra analyze centrality --scope character:alice --limit 20
narra analyze influence alice --depth 3 # Influence propagation
# Knowledge analysis
narra analyze irony # Dramatic irony report
narra analyze irony --character alice --threshold 5
narra analyze asymmetries alice gray # Pairwise knowledge gaps
narra analyze conflicts # Knowledge conflicts (believes_wrongly)
narra analyze conflicts --character alice
# Perception analysis
narra analyze perception-gap alice bob # How wrong is alice about bob?
narra analyze perception-matrix bob # How do all observers see bob?
narra analyze perception-shift alice bob # How has alice's view evolved?
narra analyze tensions # Unresolved perception tensions
# Arc tracking (requires baseline snapshots)
narra analyze arc-drift # Most-changed entities
narra analyze arc-drift --type character --limit 20
narra analyze arc-history alice # Entity evolution timeline
narra analyze arc-compare alice bob --window "recent:10"
narra analyze arc-moment alice --event event:betrayal
# Thematic analysis
narra analyze themes # K-means clustering
narra analyze themes --types character,event --clusters 5
narra analyze thematic-gaps --min-size 3
# Temporal & consistency
narra analyze temporal alice --event event:confrontation
narra analyze contradictions alice --depth 3
narra analyze impact alice --description "major personality shift"
# Composite reports
narra analyze situation-report # High-level narrative overview
narra analyze dossier alice # Comprehensive character report
narra analyze scene-prep alice,bob,gray # Scene planning for character meeting
narra analyze what-if alice --fact knowledge:secret --certainty suspects会话管理
会话状态在CLI调用和MCP服务器使用之间持续存在。
narra session context
查看当前会话状态:热实体(最近访问)、固定实体、待定决策和世界概览。
narra session context
narra session context --json # Machine-readable output会话上下文包括:
- 热门实体:最近查看或修改(最近50次)
- 固定实体:手动固定以进行持久引用
- 待定决定:带有验证警告的实体
- 世界概况:实体计数,嵌入覆盖范围
narra session pin
将实体固定到持久会话上下文。
narra session pin alice # Keep protagonist in context
narra session pin event:climax # Pin pivotal event
narra session pin location:headquarters使用案例:
- 积极写作:固定您当前正在书写的字符/位置
- 连续性:固定需要经常引用的实体
- 交叉会议:维护MCP和CLI使用的上下文
narra session unpin
从固定上下文中删除实体。
narra session unpin character:minor_npc世界管理
全部在 narra world :
narra world status
带有实体计数和嵌入覆盖率的世界概览仪表板。
narra world statusnarra world health
嵌入健康报告:覆盖范围、陈旧性、缺失嵌入。
narra world healthnarra world backfill
为所有实体生成嵌入(在初始数据输入后运行)。
narra world backfill # All entity types
narra world backfill --type character # Single type onlynarra world baseline-arcs
为电弧跟踪创建基线电弧快照(回填后运行一次)。
narra world baseline-arcs # All types with embeddings
narra world baseline-arcs --type characternarra world import
从YAML文件导入世界数据。
narra world import story-world.yaml
narra world import story-world.yaml --on-conflict update # Merge with existing
narra world import story-world.yaml --dry-run # Preview without writing冲突模式: error (默认情况下,跳过冲突), skip (无声), update (合并字段)。
narra world export
将世界数据导出到YAML。
narra world export # Auto-named export
narra world export -o backup.yaml # Custom filenamenarra world validate
根据宇宙事实和时间线验证实体的一致性。
narra world validate # General check
narra world validate character:alice # Single entitynarra world graph
生成美人鱼关系图。
narra world graph --scope full # All characters
narra world graph --scope character:alice --depth 2
narra world graph -o graph.mmd # Save to file批量操作
narra batch
从YAML(stdin或文件)批量创建实体。
# From file
narra batch character --file characters.yaml
# From stdin
cat characters.yaml | narra batch character输出控制
所有命令上都有全局标志:
--json # JSON output for scripting
--md # Markdown output
--brief # Less detail
--full # Maximum detail
--no-semantic # Disable semantic search (use keyword only)壳牌完井
为您的shell生成shell补全:
narra completions bash > /etc/bash_completion.d/narra
narra completions zsh > ~/.zsh/completion/_narra
narra completions fish > ~/.config/fish/completions/narra.fishClaude代码插件
Claude Code与斜线命令、技能和钩子集成,用于小说写作工作流程:
https://github.com/florinutz/flo-market/tree/main/plugins/narra该插件自动下载二进制文件,提供会话管理,并将Narra操作作为会话命令公开。
CLI演练
黑色悬疑漫游:侦探爱丽丝·沃斯、腐败专员格雷和街头线人埃迪——从头开始构建一个故事世界。
1.引导世界
设置故事世界的最快方法是通过YAML导入,它允许您指定自己的ID:
narra world import noir-world.yamlnoir-world.yaml
characters:
- id: alice
name: "Alice Voss"
role: "Detective"
description: "Homicide detective, 15 years on the force. Methodical, relentless."
profile:
wound: ["partner murdered 3 years ago"]
desire: ["justice for her partner"]
secret: ["knows Commissioner Gray ordered the hit"]
contradiction: ["upholds the law while planning extralegal revenge"]
- id: gray
name: "Commissioner Gray"
role: "Antagonist"
description: "Police commissioner with a public image of reform. Privately runs a protection racket."
profile:
wound: ["grew up in poverty, fears losing power"]
desire: ["absolute control of the city"]
secret: ["ordered the murder of Alice's partner"]
contradiction: ["champion of justice who is the biggest criminal"]
- id: eddie
name: "Eddie Malone"
role: "Informant"
description: "Street-level informant who plays all sides. Knows more than he lets on."
profile:
wound: ["abandoned by family at 14"]
desire: ["enough money to disappear"]
secret: ["suspects Gray is dirty but has no proof"]
contradiction: ["sells information to survive while hating betrayal"]
locations:
- id: precinct
name: "Precinct 13"
loc_type: "building"
description: "Aging police station in the warehouse district. Alice's home base."
- id: blind_pig
name: "The Blind Pig"
loc_type: "bar"
description: "Dive bar where Eddie brokers information. Back booth, cash only."
- id: city_hall
name: "City Hall"
loc_type: "building"
description: "Commissioner Gray's seat of power. Marble corridors, closed doors."
events:
- id: murder
title: "Partner's Murder"
sequence: 1
description: "Alice's partner killed in an apparent robbery. Case goes cold."
- id: promotion
title: "Gray's Promotion"
sequence: 2
description: "Gray becomes commissioner, promising to clean up the city."
- id: tip
title: "Eddie's Tip"
sequence: 3
description: "Eddie approaches Alice with a rumor about Gray's protection racket."
- id: confrontation
title: "The Confrontation"
sequence: 4
description: "Alice confronts Gray with evidence. The truth comes out."
relationships:
- from_character_id: "character:alice"
to_character_id: "character:gray"
rel_type: "antagonistic"
label: "Hunter and prey — neither knows who is which"
- from_character_id: "character:eddie"
to_character_id: "character:alice"
rel_type: "professional"
subtype: "informant"
label: "Eddie feeds Alice information for cash"
- from_character_id: "character:gray"
to_character_id: "character:eddie"
rel_type: "professional"
subtype: "asset"
label: "Gray uses Eddie as eyes on the street"
knowledge:
- character_id: "character:alice"
target_id: "character:gray"
fact: "Commissioner Gray ordered the murder of Alice's partner"
certainty: "knows"
method: "discovered"
- character_id: "character:eddie"
target_id: "character:gray"
fact: "Commissioner Gray is connected to organized crime"
certainty: "suspects"
method: "deduced"
- character_id: "character:gray"
target_id: "character:alice"
fact: "No one suspects my involvement in the partner's murder"
certainty: "believes_wrongly"
method: "deduced"三个秘密交织的角色。轮廓键(伤口、欲望、秘密、矛盾)成为每个角色嵌入的一部分,实现了跨心理维度的语义搜索。爱丽丝 *知道* 什么灰色 *相信没人知道*埃迪 *嫌疑人* 但无法证明这一点。
所有实体创建都使用统一 narra create 界面。看 CLI命令参考 下面是完整的命令文档。
2.生成嵌入
narra world backfill计算所有实体的BGE-small-en-v1.5嵌入。这实现了语义搜索、电弧跟踪和感知分析。
3.探索和搜索
# Deep exploration: relationships, knowledge, perceptions, similar entities
narra explore alice
# Natural language questions
narra ask "What secrets does Alice know that Gray doesn't?"
# Simple search (hybrid by default - combines keyword + semantic)
narra find "Gray murder"
# Semantic-only search (find by meaning, not keywords)
narra find --semantic-only "characters hiding dark secrets"
# Advanced searches
narra find join "characters whose desires conflict with Alice's wounds"
narra find knowledge "the royal succession" --character alice
narra find graph alice "betrayal and deception" --hops 2
narra find perspectives "threatening and dangerous" --observer bob
narra find similar alice gray # Find relationships similar to Alice-Gray dynamic
# Connection analysis
narra path alice eddie # Shortest connection paths
narra references alice # What mentions/references Alice?高级命令(explore,ask,find)提供对纳拉情报的直观访问。语义搜索通过心理特征而不仅仅是关键字来查找实体。混合搜索结合了这两种方法。
4.分析网络
# Who are the most connected characters?
narra analyze centrality
# How would information spread from Eddie?
narra analyze influence eddie
# What knowledge asymmetries exist?
narra analyze irony
# What does Alice know that Gray doesn't, and vice versa?
narra analyze asymmetries alice gray
# Who believes things that are wrong?
narra analyze conflicts
# Where are the unresolved tensions?
narra analyze tensions
# Which characters have changed the most?
narra analyze arc-drift5.可视化
narra world graph --scope full生成关系网络的美人鱼图。
6.出口
narra world export -o noir-export.yaml将整个世界导出到YAML。可重新导入 narra world import noir-export.yaml.有了MCP服务器,人工智能助手可以运行所有这些操作以及更多操作,包括感知差距、感知矩阵、弧比较、主题聚类、假设分析和语义图搜索。
MCP服务器
启动MCP服务器(stdio传输,专为Claude Code和其他MCP客户端设计):
narra mcp工具概述
| 工具 | 操作 | 目的 |
|---|---|---|
| 怎么翻译 | 40 | 只读:搜索、分析、弧线跟踪、感知分析、验证、影响预览 |
| 突变 | 25 | 写入:创建/更新/删除实体、记录知识、批量操作、导入、保护实体 |
| 会话 | 3 | 上下文管理:热门实体、固定项目、待定决策 |
| 出口_世界 | 1 | 将世界导出到YAML(兼容NarraImport,可重新导入) |
| 发电机图形 | 1 | 生成美人鱼关系图 .planning/exports/ |
突出显示的操作
| 操作 | 它做什么 |
|---|---|
DramaticIronyReport | 自不对称产生以来,知识不对称与场景数量 |
KnowledgeAsymmetries | 紧张语境下两个角色之间的成对知识差距 |
PerceptionGap | 观察者视角与目标现实之间的余弦距离 |
PerceptionMatrix | 多个观察者如何通过成对协议看到一个目标 |
PerceptionShift | 通过弧形快照跟踪观察者的视图随时间的变化 |
ArcDrift | 按总嵌入漂移对实体进行排名——谁变化最大 |
ArcHistory | 查看实体演变的嵌入快照时间线 |
ArcComparison | 比较两个实体的收敛/发散轨迹 |
ArcMoment | 获取特定事件的实体状态(最近的快照) |
SemanticJoin | 跨实体类型的跨字段语义查询 |
SemanticKnowledge | 按含义搜索字符知识,可选按字符搜索 |
SemanticGraphSearch | 图+向量:查找与概念匹配的连通实体 |
PerspectiveSearch | 语义搜索透视图嵌入 |
SimilarRelationships | 查找与参考对相似的关系 |
WhatIf | 预览角色学习事实的影响——无需承诺 |
UnresolvedTensions | 高度不对称的配对,共享场景很少——等待书写的场景 |
ThematicClustering | K-means在嵌入中发现新兴的故事主题 |
ThematicGaps | 查找缺少预期实体类型的群集 |
InfluencePropagation | 追踪信息如何在网络中传播 |
KnowledgeConflicts | 找出相信矛盾事实的角色 |
SituationReport | 高层次叙事概述:讽刺、冲突、紧张、主题 |
CharacterDossier | 综合性格报告:网络、知识、影响力、感知 |
ScenePlanning | 角色会议的场景准备:动态、讽刺、紧张 |
AnalyzeImpact | 在突变前预览变更影响,并显示受影响实体的严重程度 |
ValidateEntity | 根据事实、时间线和关系检查实体的一致性 |
InvestigateContradictions | 图遍历以找出与实体相矛盾的内容 |
资源和提示
资源 (narra:// URI):
narra://session/context--热门实体、固定项目、待定决定narra://entity/{type}:{id}--具有属性和关系的完整实体视图narra://consistency/issues--按严重程度列出的当前违规行为narra://schema/import-template--用于全球导入的YAML模板narra://schema/import-schema--用于导入验证的JSON模式
提示:
check_consistency--带有修复建议的指导性验证dramatic_irony--人物之间的知识不对称分析
Claude代码插件
对于集成的Claude Code工作流,请安装 发现插件。它提供斜线命令、技能、钩子和自动二进制管理。
数据存储
默认情况下,Narra将数据存储在 ~/.narra/。您可以按项目或全局覆盖此选项:
# Per-project: create a .narra directory in your project root
mkdir .narra
narra list character # uses ./.narra/ automatically
# Environment variable
export NARRA_DATA_PATH=/path/to/data
# CLI flag (highest priority)
narra --data-path /path/to/data list character解决顺序: --data-path 旗帜> NARRA_DATA_PATH 环境> ./.narra (如果存在)> ~/.narra
建筑
CLI (clap) ──┐
├─→ AppContext ──→ Services ──→ Repositories ──→ SurrealDB (RocksDB)
MCP (rmcp) ──┘- 应用上下文 (
init.rs)--中央依赖连接。CLI和MCP共享相同的服务 - 特质对象 --所有服务使用
Arc可测试性 - 标记为枚举调度 --MCP工具接收
#[serde(tag = "operation")]别联合 - 嵌入服务特性 —
EmbeddingService随着LocalEmbeddingService(紧固)用于生产和NoopEmbeddingService用于测试 - 缓存 --用于上下文和摘要服务的moka异步缓存
- 数据提供者 --IronyService、InfluenceService、GraphAnalyticsService等服务使用数据提供者特征,支持使用模拟数据进行单元测试
发展
git clone https://github.com/florinutz/narra.git
cd narra
cargo build # Debug build
cargo test # All tests
cargo test --lib # Unit tests only
cargo test --test '*' # Integration tests only
cargo clippy -- -D warnings # Lint (CI enforces warnings-as-errors)
cargo fmt -- --check # Format check关键制造目标:
make build # Debug build
make lint # Clippy + fmt check
make test # All tests
make quick-check # Lint + build (no tests)
make test-embedding # Embedding-specific tests测试为每个测试使用一个隔离的SurrealDB实例(临时目录),并为测试数据提供流畅的构建器(CharacterBuilder, LocationBuilder等等) tests/common/.
