diff --git a/gene.md b/gene.md new file mode 100644 index 0000000..5dcea19 --- /dev/null +++ b/gene.md @@ -0,0 +1,901 @@ +# Gene 方案 + +## 这份文档针对什么 + +这个项目里,`Skill` 已经不是一个抽象概念,而是完整的业务实体: + +* 后端有 `project_skill` 持久化模型 +* Git 同步会扫描仓库里的 `SKILL.md` +* 聊天构建会把启用的技能注入上下文 +* 前端有技能列表、详情、编辑、删除、扫描 +* 内建技能模板也已经存在 + +所以这里不应该“用 Gene 替换 Skill”,而应该是: + +* `Skill` 继续负责执行和交付能力 +* `Gene` 作为新增元层,负责让技能可演化、可比较、可追踪、可继承 + +--- + +## 设计结论 + +`Gene` 的正确位置不是新的执行系统,也不是 `Skill` 的替代品,而是 `Skill` 的生命周期治理层。 + +```text +Skill = 可执行内容 + 上下文注入 + 业务交付 +Gene = 演化族 + 版本谱系 + 评估记录 + 选择记录 +``` + +更准确地说: + +```text +Skill 是可执行的技能内容,负责被扫描、编辑、启用、注入和交付能力。 + +Gene 是 Skill 的演化族,负责组织一个 Skill 在项目内的版本、来源、谱系、评估和选择记录。 + +GeneRevision 是 Gene 下的不可变版本节点,绑定到某个 Skill 内容快照。 + +GeneEvaluation 是对某个 GeneRevision 的评估结果。 + +GeneSelection 是对当前有效 GeneRevision 的显式选择记录。 +``` + +--- + +## 项目现状 + +### Skill 已经落在这些地方 + +* `libs/models/projects/project_skill.rs` + + * 定义了 `project_skill` 实体 + * 已包含 `source` + * 已包含 `repo_id` + * 已包含 `commit_sha` + * 已包含 `blob_hash` + * 已包含 `content` + * 已包含 `metadata` + * 已包含 `enabled` + +* `libs/git/hook/sync/mod.rs` + + * 扫描仓库中的 `SKILL.md` + * 从 frontmatter 解析 `name`、`description`、`license`、`compatibility` + * 用 `commit_sha` 和 `blob_hash` 做增量同步 + +* `libs/agent/skills/templates.rs` + + * 内建技能模板已经编译进程序 + * 这些模板本质上是“系统内置 Skill” + +* `libs/agent/chat/message_builder.rs` + + * 读取项目中启用的技能 + * 把技能注入对话上下文 + * 和 embedding / perception 一起影响模型行为 + +* `src/app/project/skills/*` + + * 已有技能管理 UI + * 能查看、编辑、删除、扫描技能 + +--- + +## 现有 Skill 的问题 + +当前 `Skill` 已经能用,但还不够“可进化”: + +* 只有内容,没有明确的演化关系 +* 只有当前状态,没有谱系 +* 只有启用/禁用,没有版本选择 +* 只有来源信息,没有变体比较 +* 只有同步时间和 blob hash,没有“为什么变成这样”的记录 +* 有评估空间,但没有评估结果和版本绑定 +* 有扫描和编辑能力,但没有可审计的回滚与选择记录 + +换句话说,现在的 `Skill` 更像“静态资产”,还不是“进化单元”。 + +--- + +## 设计原则 + +### 1. Skill 仍然是唯一执行实体 + +`Skill` 继续负责: + +* 被扫描 +* 被编辑 +* 被启用或禁用 +* 被注入聊天上下文 +* 交付实际能力 + +`Gene` 不直接执行任务,不直接调用工具,不直接参与上下文拼装。 + +--- + +### 2. Gene 只管理 Skill 的演化元数据 + +`Gene` 管理的是: + +* 版本 +* 来源 +* 父子关系 +* 变体 +* 评估 +* 选择 +* 淘汰 +* 回滚 + +它不应该成为第二套 `Skill` 系统。 + +--- + +### 3. GeneRevision 必须不可变 + +`Skill` 可以是当前可编辑对象。 + +`GeneRevision` 是不可变演化节点。一旦创建,不应再修改: + +* 内容快照 +* 父代关系 +* 来源信息 +* `commit_sha` +* `blob_hash` +* `content_hash` +* `mutation_reason` +* `mutation_diff` + +后续任何内容变化、prompt 变化、工具权限变化、上下文注入规则变化,都应该产生新的 `GeneRevision`。 + +--- + +### 4. Evaluation 必须绑定到具体 Revision + +评估不是评价一个抽象的 `Gene`,而是评价某个具体版本。 + +因此: + +```text +GeneEvaluation 必须绑定 revision_id。 +``` + +否则同一个 `Gene` 下存在多个版本时,评估结果无法精确归因。 + +--- + +### 5. Selection 必须显式记录 + +如果系统选择了某个版本作为当前有效版本,必须记录: + +* 选中了哪个 revision +* 为什么选它 +* 谁选的 +* 依据什么策略选的 +* 什么时候选的 +* 是否仍然 active + +这能支持审计、回滚和后续自动选择。 + +--- + +### 6. SKILL.md 仍然是仓库内 Skill 的事实来源 + +仓库里的 `SKILL.md` 仍然是 Git 同步的事实来源。 + +`Gene` 只记录它如何演化,不改变仓库同步的基本语义。 + +--- + +## 核心概念 + +### Skill + +`Skill` 是现有业务实体。 + +它负责: + +```text +可执行内容 +上下文注入 +用户可见编辑 +Git 扫描 +启用 / 禁用 +业务交付 +``` + +### Gene + +`Gene` 是某个 Skill 的演化族。 + +它负责组织这个 Skill 的生命周期: + +```text +这个能力从哪里来 +经历过哪些版本 +有哪些变体 +评估结果如何 +当前选择哪个版本 +哪些版本被淘汰 +``` + +### GeneRevision + +`GeneRevision` 是 `Gene` 下的一个不可变版本节点。 + +它绑定某个 `Skill` 的内容状态,例如: + +```text +skill_id +skill_slug +commit_sha +blob_hash +content_hash +content_snapshot_ref +``` + +### GeneEvaluation + +`GeneEvaluation` 是对某个 `GeneRevision` 的评估结果。 + +它回答: + +```text +这个版本好不好? +在哪个数据集上测的? +指标是什么? +是否通过? +成本和延迟如何? +失败样本是什么? +``` + +### GeneSelection + +`GeneSelection` 是对当前有效版本的显式选择记录。 + +它回答: + +```text +当前选中哪个 revision? +为什么选它? +谁选的? +依据什么策略? +是否还在生效? +``` + +--- + +## Gene 和 Skill 的关系 + +可以把关系理解为: + +```text +Gene 1 ── has many ── GeneRevision +GeneRevision ── references ── Skill snapshot +GeneRevision ── has many ── GeneEvaluation +Gene ── has one active ── GeneSelection +GeneSelection ── selects ── GeneRevision +Skill ── executes ── actual capability +``` + +也就是说: + +* `Skill` 解决“能不能做” +* `Gene` 解决“该保留哪个版本、为什么保留、怎么变体、怎么传播” +* `GeneRevision` 解决“这个能力在某一刻具体长什么样” +* `GeneEvaluation` 解决“这个版本是否足够好” +* `GeneSelection` 解决“当前应该用哪个版本” + +--- + +## 数据模型 + +### ProjectGene + +```text +ProjectGene + - gene_id + - project_uuid + - skill_id + - skill_slug + - name + - description + - owner + - status + - created_at + - updated_at +``` + +说明: + +* `gene_id` 是 Gene 的唯一标识 +* `project_uuid` 绑定项目 +* `skill_id` / `skill_slug` 绑定现有 Skill +* `status` 可为 `active`、`archived`、`deprecated` +* `owner` 用于责任归属 + +--- + +### ProjectGeneRevision + +```text +ProjectGeneRevision + - revision_id + - gene_id + - version + - parent_revision_id + - origin + - source + - skill_id + - skill_slug + - commit_sha + - blob_hash + - content_hash + - content_snapshot_ref + - mutation_reason + - mutation_diff + - created_by + - created_at +``` + +说明: + +* `revision_id` 是内部唯一版本节点 +* `version` 是用户可见版本号,不承担唯一性职责 +* `parent_revision_id` 表示单父版本关系 +* `origin` 表示来源,例如 `git_sync`、`manual_edit`、`builtin_template`、`migration` +* `source` 复用现有 `Skill.source` +* `commit_sha` / `blob_hash` 记录 Git 来源 +* `content_hash` 记录内容稳定标识 +* `content_snapshot_ref` 用于指向当时的内容快照 +* `mutation_reason` 记录为什么产生这个版本 +* `mutation_diff` 记录相对父版本的变化 + +--- + +### ProjectGeneEvaluation + +```text +ProjectGeneEvaluation + - evaluation_id + - gene_id + - revision_id + - eval_name + - evaluator + - dataset_ref + - dataset_version + - metric_name + - score + - threshold + - passed + - sample_count + - failure_count + - latency_ms_avg + - cost + - result_summary + - result_json + - evaluated_at +``` + +说明: + +* `revision_id` 必填 +* `score` 不应脱离 `metric_name` 单独解释 +* `threshold` 用于判断是否通过 +* `sample_count` 和 `failure_count` 用于判断评估可信度 +* `result_json` 存放详细结果、失败样本、分项指标等 + +--- + +### ProjectGeneSelection + +```text +ProjectGeneSelection + - selection_id + - gene_id + - selected_revision_id + - project_uuid + - policy + - reason + - selected_by + - selected_at + - active +``` + +说明: + +* 同一个 `gene_id` 同一时间只能有一个 active selection +* `policy` 可以是 `manual`、`latest_passed`、`best_score`、`stable_low_cost` +* `reason` 用于审计和回滚 +* `selected_by` 可以是用户、系统或自动策略 + +--- + +## 关于 GeneLineage + +MVP 阶段不单独引入 `GeneLineage` 表。 + +原因是:如果每个版本只有一个父版本,`ProjectGeneRevision.parent_revision_id` 已经足够表达谱系。 + +```text +MVP:单父版本树 +Future:多父 DAG / merge / cross-skill inheritance +``` + +未来如果需要支持合并、交叉继承或复杂谱系,再引入: + +```text +ProjectGeneEdge + - parent_revision_id + - child_revision_id + - edge_type + - mutation_reason + - mutation_diff +``` + +--- + +## 关于 Variant + +`Variant` 是 Gene 的重要能力,但不一定是 MVP 的独立表。 + +这些变化都可以先作为新的 `GeneRevision` 表达: + +* 更严格的 prompt +* 更短的 prompt +* 不同工具权限 +* 不同上下文注入规则 +* 不同评估阈值 + +MVP 中: + +```text +不单独引入 ProjectGeneVariant。 +所有变体先作为 GeneRevision 表达。 +``` + +当系统需要以下能力时,再引入 `GeneExperiment` / `GeneVariant`: + +* A/B 实验 +* 并行流量分配 +* 实验分组 +* 统计显著性 +* 多候选版本同时比较 + +--- + +## Git 同步流程 + +当前 Git 同步已经会扫描仓库中的 `SKILL.md`,并使用 `commit_sha` 和 `blob_hash` 做增量同步。 + +引入 Gene 后,Git 同步流程建议变成: + +```text +当 Git 同步发现 SKILL.md 的 blob_hash 变化时: + +1. 正常创建或更新 project_skill。 +2. 查找该 skill 对应的 project_gene。 +3. 如果不存在 project_gene,则创建一个。 +4. 查找该 gene 下最新的 project_gene_revision。 +5. 如果新的 blob_hash / content_hash 不同,则创建新的 GeneRevision。 +6. 将上一 revision 设为 parent_revision_id。 +7. mutation_reason 默认记录为 git_sync。 +8. mutation_diff 记录上一个 SKILL.md 与当前 SKILL.md 的 diff。 +9. 不自动改变 selected_revision,除非选择策略明确允许。 +``` + +关键约束: + +```text +Git sync 可以产生新的 GeneRevision。 +Git sync 不应默认切换当前线上选中版本。 +``` + +这样可以避免仓库变更自动导致线上行为漂移。 + +--- + +## 手动编辑流程 + +当用户在 UI 中编辑 `Skill` 内容时: + +```text +1. 更新 project_skill。 +2. 计算新的 content_hash。 +3. 查找对应 project_gene。 +4. 创建新的 project_gene_revision。 +5. parent_revision_id 指向编辑前的 revision。 +6. mutation_reason 记录为 manual_edit。 +7. mutation_diff 记录编辑前后的差异。 +8. 可选择是否自动把新 revision 标记为 selected。 +``` + +建议 MVP 默认: + +```text +手动编辑后创建新 revision,但不自动覆盖 active selection。 +由用户显式选择是否启用该 revision。 +``` + +如果产品希望“编辑即生效”,也可以让 selection 同步更新,但必须记录: + +```text +policy = manual_edit_auto_select +reason = "User edited skill content" +``` + +--- + +## 聊天上下文注入流程 + +现有流程中,`libs/agent/chat/message_builder.rs` 读取项目中启用的 `Skill`,并把技能注入对话上下文。 + +引入 Gene 后,这个原则不变: + +```text +message_builder 不直接读取 Gene 内容。 +message_builder 仍然读取启用的 Skill。 +Gene 只影响哪个 Skill revision 被视为推荐版本或当前选中版本。 +``` + +如果未来要让 `GeneSelection` 影响上下文注入,推荐路径是: + +```text +GeneSelection + -> resolve selected GeneRevision + -> materialize / update project_skill + -> message_builder reads project_skill +``` + +不建议: + +```text +message_builder + -> read Gene + -> assemble prompt +``` + +因为这会让 `Gene` 偷偷变成新的执行层。 + +--- + +## API 设计 + +MVP API 可以包括: + +```text +GET /projects/:project_uuid/skills/:skill_id/gene +POST /projects/:project_uuid/skills/:skill_id/gene + +GET /projects/:project_uuid/genes/:gene_id/revisions +POST /projects/:project_uuid/genes/:gene_id/revisions + +GET /projects/:project_uuid/genes/:gene_id/evaluations +POST /projects/:project_uuid/genes/:gene_id/evaluations + +GET /projects/:project_uuid/genes/:gene_id/selection +POST /projects/:project_uuid/genes/:gene_id/select +``` + +选择接口示例: + +```json +{ + "selected_revision_id": "rev_123", + "policy": "manual", + "reason": "Higher pass rate on regression eval" +} +``` + +评估写入接口示例: + +```json +{ + "revision_id": "rev_123", + "eval_name": "skill_regression_eval", + "dataset_ref": "datasets/skill-regression-v1", + "dataset_version": "2026-01-01", + "metric_name": "task_success_rate", + "score": 0.92, + "threshold": 0.85, + "passed": true, + "sample_count": 100, + "failure_count": 8, + "latency_ms_avg": 1200, + "cost": 0.34 +} +``` + +--- + +## UI 设计 + +`Gene` 不替代现有技能管理 UI。 + +推荐把它放在 `Skill Detail` 页面中的一个“演化”标签页。 + +```text +Skill Detail + - 基本信息 + - 内容编辑 + - 启用状态 + - Evolution / Gene + - 当前选中 revision + - 版本列表 + - 父子关系 + - 每个版本的 diff + - 每个版本的评估结果 + - 选择按钮 + - 回滚按钮 +``` + +MVP UI 可以先做只读: + +```text +1. 显示 Gene 信息 +2. 显示 Revision 列表 +3. 显示每个 Revision 的来源、时间、commit_sha、blob_hash +4. 显示相邻 Revision 的 diff +``` + +第二阶段再加入: + +```text +1. 手动选择 revision +2. 回滚 revision +3. 展示评估结果 +4. 根据评估结果推荐版本 +``` + +--- + +## 评估指标 + +Gene 的核心不是“更像生物学”,而是“更像可验证的演化对象”。 + +每个 `GeneRevision` 都应该支持评估,例如: + +* 任务成功率 +* 失败率 +* 平均耗时 +* 误触发率 +* 人工接受率 +* 回滚率 +* 成本 +* 稳定性 +* 安全失败数 +* 用户满意度 + +没有评估的 Gene,只是重命名后的 Skill 管理。 + +--- + +## 选择策略 + +如果存在多个 GeneRevision,系统应该能选择更优版本。 + +MVP 阶段不做自动选择,只做人工选择和可审计回滚。 + +后续选择规则可以逐步加入: + +```text +1. 先看是否通过基础测试 +2. 再看近期成功率 +3. 再看失败率 +4. 再看成本 +5. 再看延迟 +6. 再看稳定性 +7. 再看人工接受率 +``` + +可选策略: + +```text +manual +latest_passed +best_score +stable_low_cost +lowest_latency +highest_acceptance_rate +``` + +自动选择必须满足: + +```text +有评估数据 +有样本量 +有失败分类 +有回滚机制 +有选择审计记录 +``` + +--- + +## Migration 策略 + +对于已有的 `project_skill`,可以执行一次初始化迁移: + +```text +对每个 project_skill: + +1. 创建 project_gene。 +2. 创建初始 project_gene_revision。 +3. revision.origin = migration。 +4. revision.skill_id = project_skill.id。 +5. revision.skill_slug = project_skill.slug。 +6. revision.commit_sha = project_skill.commit_sha。 +7. revision.blob_hash = project_skill.blob_hash。 +8. revision.content_hash = hash(project_skill.content)。 +9. revision.content_snapshot_ref = 当前 Skill 内容快照。 +10. 创建 active project_gene_selection。 +11. selected_revision_id = 初始 revision。 +12. policy = migration。 +13. reason = "Initial gene selection from existing project_skill"。 +``` + +这样现有 Skill 都可以无损进入 Gene 生命周期模型。 + +--- + +## 推荐实现顺序 + +```text +1. 保持 Skill 执行、扫描、编辑、注入流程不变。 +2. 增加 project_gene 和 project_gene_revision 表。 +3. 为现有 project_skill 执行一次 migration:每个 Skill 创建一个 Gene 和初始 Revision。 +4. 在 Git sync 发现 blob_hash 变化时,自动创建新的 GeneRevision。 +5. 在 Skill 详情页增加只读版本历史和 diff 展示。 +6. 增加 ProjectGeneEvaluation 表和手动写入 API。 +7. 增加 ProjectGeneSelection 表和人工选择 / 回滚能力。 +8. 当评估数据稳定后,再做自动选择策略。 +9. 最后再考虑 Variant / Experiment / A-B 测试。 +``` + +--- + +## 落地判断标准 + +一个能力如果只是: + +* 能被扫描 +* 能被编辑 +* 能被启用或禁用 +* 能被注入上下文 +* 能交付业务能力 + +它还是 `Skill`。 + +一个能力如果还能: + +* 被追踪来源 +* 被比较版本 +* 被记录变体 +* 被评估好坏 +* 被继承和淘汰 +* 被审计选择 +* 被安全回滚 + +它才进入 `Gene` 管理范畴。 + +--- + +## 非目标 + +Gene MVP 不做以下事情: + +```text +1. 不替换 project_skill。 +2. 不改变 SKILL.md 作为仓库技能事实来源的地位。 +3. 不直接参与聊天上下文构建。 +4. 不直接执行工具调用。 +5. 不自动改写 Skill 内容。 +6. 不在没有评估和回滚机制的情况下自动切换线上版本。 +7. 不一开始支持复杂遗传算法、交叉、随机变异或自动进化。 +8. 不新增一套和 Skill 并列的执行 UI。 +``` + +--- + +## 风险与约束 + +### 1. Gene 变成另一个 Skill + +风险: + +```text +Gene 中也开始存 prompt、工具权限、上下文注入规则,并且聊天时直接读取 Gene。 +``` + +规避: + +```text +Gene 不存放执行主内容。 +执行内容仍然归 Skill 所有。 +GeneRevision 只引用或快照 Skill 的某个状态。 +``` + +--- + +### 2. 评估绑定到可变 Skill + +风险: + +```text +评估结果只挂在 skill_id 上,Skill 内容变化后,评估记录失真。 +``` + +规避: + +```text +评估必须绑定 revision_id + content_hash / blob_hash。 +``` + +--- + +### 3. 自动选择过早上线 + +风险: + +```text +没有足够评估数据时自动切换版本,导致线上行为漂移。 +``` + +规避: + +```text +MVP 只做人工选择和可审计回滚。 +自动选择必须依赖稳定评估和回滚机制。 +``` + +--- + +### 4. mutation_diff 膨胀 + +风险: + +```text +每个版本都保存完整 diff,长期可能膨胀。 +``` + +规避: + +```text +MVP 可直接存 mutation_diff。 +后续引入 mutation_diff_ref 或对象存储引用。 +``` + +--- + +### 5. version 语义不清 + +风险: + +```text +version 同时承担用户展示、唯一标识、Git 版本等多种含义。 +``` + +规避: + +```text +revision_id = 系统内部唯一版本节点 +version = 用户可见版本号 +commit_sha / blob_hash = Git 来源版本标识 +content_hash = 内容稳定标识 +``` + +--- + +## 最终结论 + +这个项目已经具备 `Skill` 的完整工程闭环。 + +`Gene` 的正确位置不是替换它,而是补上它缺失的演化层: + +```text +Skill 负责落地执行 +Gene 负责生命周期治理 +GeneRevision 负责不可变版本节点 +GeneEvaluation 负责版本质量判断 +GeneSelection 负责显式选择和回滚 +``` + +两者结合后,技能系统才从“可配置”变成“可进化”。 diff --git a/public/fonts/JetBrainsMono-Bold.woff2 b/public/fonts/JetBrainsMono-Bold.woff2 new file mode 100644 index 0000000..4917f43 Binary files /dev/null and b/public/fonts/JetBrainsMono-Bold.woff2 differ diff --git a/public/fonts/JetBrainsMono-BoldItalic.woff2 b/public/fonts/JetBrainsMono-BoldItalic.woff2 new file mode 100644 index 0000000..536d3f7 Binary files /dev/null and b/public/fonts/JetBrainsMono-BoldItalic.woff2 differ diff --git a/public/fonts/JetBrainsMono-ExtraBold.woff2 b/public/fonts/JetBrainsMono-ExtraBold.woff2 new file mode 100644 index 0000000..8f88c54 Binary files /dev/null and b/public/fonts/JetBrainsMono-ExtraBold.woff2 differ diff --git a/public/fonts/JetBrainsMono-ExtraBoldItalic.woff2 b/public/fonts/JetBrainsMono-ExtraBoldItalic.woff2 new file mode 100644 index 0000000..d1478ba Binary files /dev/null and b/public/fonts/JetBrainsMono-ExtraBoldItalic.woff2 differ diff --git a/public/fonts/JetBrainsMono-ExtraLight.woff2 b/public/fonts/JetBrainsMono-ExtraLight.woff2 new file mode 100644 index 0000000..b97239f Binary files /dev/null and b/public/fonts/JetBrainsMono-ExtraLight.woff2 differ diff --git a/public/fonts/JetBrainsMono-ExtraLightItalic.woff2 b/public/fonts/JetBrainsMono-ExtraLightItalic.woff2 new file mode 100644 index 0000000..be01aac Binary files /dev/null and b/public/fonts/JetBrainsMono-ExtraLightItalic.woff2 differ diff --git a/public/fonts/JetBrainsMono-Italic.woff2 b/public/fonts/JetBrainsMono-Italic.woff2 new file mode 100644 index 0000000..d60c270 Binary files /dev/null and b/public/fonts/JetBrainsMono-Italic.woff2 differ diff --git a/public/fonts/JetBrainsMono-Light.woff2 b/public/fonts/JetBrainsMono-Light.woff2 new file mode 100644 index 0000000..6538498 Binary files /dev/null and b/public/fonts/JetBrainsMono-Light.woff2 differ diff --git a/public/fonts/JetBrainsMono-LightItalic.woff2 b/public/fonts/JetBrainsMono-LightItalic.woff2 new file mode 100644 index 0000000..66ca3d2 Binary files /dev/null and b/public/fonts/JetBrainsMono-LightItalic.woff2 differ diff --git a/public/fonts/JetBrainsMono-Medium.woff2 b/public/fonts/JetBrainsMono-Medium.woff2 new file mode 100644 index 0000000..669d04c Binary files /dev/null and b/public/fonts/JetBrainsMono-Medium.woff2 differ diff --git a/public/fonts/JetBrainsMono-MediumItalic.woff2 b/public/fonts/JetBrainsMono-MediumItalic.woff2 new file mode 100644 index 0000000..80cfd15 Binary files /dev/null and b/public/fonts/JetBrainsMono-MediumItalic.woff2 differ diff --git a/public/fonts/JetBrainsMono-Regular.woff2 b/public/fonts/JetBrainsMono-Regular.woff2 new file mode 100644 index 0000000..40da427 Binary files /dev/null and b/public/fonts/JetBrainsMono-Regular.woff2 differ diff --git a/public/fonts/JetBrainsMono-SemiBold.woff2 b/public/fonts/JetBrainsMono-SemiBold.woff2 new file mode 100644 index 0000000..5ead7b0 Binary files /dev/null and b/public/fonts/JetBrainsMono-SemiBold.woff2 differ diff --git a/public/fonts/JetBrainsMono-SemiBoldItalic.woff2 b/public/fonts/JetBrainsMono-SemiBoldItalic.woff2 new file mode 100644 index 0000000..c5dd294 Binary files /dev/null and b/public/fonts/JetBrainsMono-SemiBoldItalic.woff2 differ diff --git a/public/fonts/JetBrainsMono-Thin.woff2 b/public/fonts/JetBrainsMono-Thin.woff2 new file mode 100644 index 0000000..17270e4 Binary files /dev/null and b/public/fonts/JetBrainsMono-Thin.woff2 differ diff --git a/public/fonts/JetBrainsMono-ThinItalic.woff2 b/public/fonts/JetBrainsMono-ThinItalic.woff2 new file mode 100644 index 0000000..a643215 Binary files /dev/null and b/public/fonts/JetBrainsMono-ThinItalic.woff2 differ