mcpField
K
kk-migrate

kk-migrate

github.com/e0ipso数据与数据库3339 次安装1 周前更新
代码仓库

关于 kk-migrate

kk-migrate 是用于跨越已注册模式版本迁移 Kenkeep 知识库的交互式技能。需要整理内容时由 LLM 在当前会话中判断,文件变更则交给确定性的命令行原语,最终留待人工审查。

主要功能

  1. 01检测待执行的模式迁移
  2. 02将扁平知识库条目归入主题文件夹
  3. 03保留节点 ID 和关系
  4. 04通过确定性的命令行原语修改文件
  5. 05重建索引并交付未提交的差异

适用场景

  1. 01将扁平知识库整理成主题文件夹
  2. 02将主题树转换为 v3 OKF 格式
  3. 03提交前审查迁移变更

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/e0ipso/kenkeep --skill kk-migrate

安装后在 Claude Code 中输入/kk-migrate确认已加载。

详细介绍

kk-migrate

你是迁移执行者,负责任何待处理的知识库迁移,而非某个特定版本跃迁。知识库会将其磁盘布局记录在编号的 schema_version 中,每个已注册的迁移步骤都会将目录树从一个版本升级到下一个版本。无论某个步骤需要作出何种判断,都由你在本次会话中完成:没有子 Agent、没有运行器,也不会通过 -p 启动子进程——你就是负责判断的大模型。所有文件写入都委托给该步骤的确定性 CLI 基元,以确保 ID 和字节由经过测试的代码保留,而非由你来保留。

确定项目根目录

使用随附的检测器解析仓库根目录(包含 .ai/kenkeep 的目录),然后将其输出的路径作为以下所有命令的工作目录:

KK_REPO_ROOT=$(node .ai/kenkeep/scripts/kk-detect-root.mjs) || exit $?
cd "$KK_REPO_ROOT" || exit $?
pwd

分派

首先,让 CLI 查询有哪些待处理的迁移:

npx --yes kenkeep@latest migrate status
  • 如果它输出类似 Knowledge base is already at schema_version 3; nothing to do.(或 No knowledge base found under nodes/; nothing to do.)的一行,则无需迁移。停止并将该行报告给用户。不要做其他操作。

  • 否则,stdout 将严格输出一行 JSON,即待处理步骤的有序链:

    {"current":2,"target":3,"steps":[{"id":"okf-v3","from":2,"to":3,"primitives":["migrate okf-v3"]}]}
    

    current 是检测到的磁盘上架构版本,target 是此 CLI 随附的版本,steps 是衔接这两个版本所需的全部步骤,按执行顺序排列。每个条目都包含步骤的稳定 id、该步骤衔接的 from/to 版本,以及它驱动的确定性 CLI primitives。

对于每个 steps[] 条目,按顺序查找下方标题中包含完全匹配的 id 的操作流程章节,并执行该章节。如果本文档中没有与某个步骤的 id 匹配的章节,停止并报告给用户:此技能副本早于已注册的步骤;CLI 识别出此技能副本尚无法执行的迁移,因此必须先升级技能(重新运行 init --upgrade)再进行迁移。绝不要为未知的步骤 ID 临时编造操作流程。

flat-to-tree(1 -> 2)

将 v1 知识库(叶节点存放在扁平的 nodes/practice/ 和 nodes/map/ 布局中)迁移到 v2 嵌套的主题文件夹树中。唯一需要判断的是如何将扁平叶节点归类到主题文件夹;所有写入操作都通过 place apply 基元完成。

1. 获取清单

运行确定性清单基元并捕获 stdout:

npx --yes kenkeep@latest place inventory

分派阶段已确认需要执行此步骤,因此预期恰好输出一行 JSON。(如果该基元提前结束或拒绝执行——说明目录树在分派后发生了变化——请停止并将其输出报告给用户。)

{"leaves":[{"id":"<id>","title":"...","kind":"practice|map","tags":["..."],"summary":"...","relates_to":["..."],"sourcePath":"..."}, ...]}

这是你的输入。该基元已为你读取并验证 frontmatter——对这份 JSON 进行归类;不要自行打开或解析叶节点文件。

2. 在当前会话中为叶节点分组

将清单中的叶节点归入少量主题文件夹。请遵循以下规则:

  • 主题文件夹,数量精简。 将相关叶节点归入少量主题文件夹。文件夹名称使用小写字母并以连字符分隔,可使用 / 嵌套(例如 cli、knowledge-base/index)。不要为每个叶节点单独创建文件夹;要进行归类。
  • 让相互引用的节点彼此靠近。 通过 relates_to 相互引用的叶节点通常应放在相近的位置。
  • 完整保留每个 id。 清单中的每个叶节点必须且只能有一个存放位置,并且必须放在其确切的 id 下——绝不可编造、重命名、丢弃或合并 id。id 是节点的身份标识;文件夹仅用于展示。
  • 为创建的每个文件夹编写一条 summary。 为你使用的每个不同文件夹编写一行 summary:使用名词短语或不完整句,能够接在「for more information on <summary>」之后(以小写字母开头,不以句号结尾,长度不超过约 140 个字符)。先说明文件夹中包含的内容,再附上简短的 ; read when <task pattern> 子句,说明哪些任务应触发深入查看——Agent 会通过将任务与这些摘要匹配来决定查看路径,因此触发条件有助于确保准确路由。

组装存放位置与文件夹文档。格式必须与 place apply 解析的格式完全一致:

{
  "placements": [{ "id": "<leaf-id>", "targetFolder": "<folder>" }],
  "folders": [{ "folder": "<folder>", "summary": "<fragment>" }]
}

为清单中的每个叶节点指定一个存放位置,并为你使用的每个不同 targetFolder 添加一项 folders 条目。(如果要将叶节点保留在 nodes/ 根目录下,请将 "targetFolder": "",空根目录无需添加 folders 条目。)

**应用前,先向用户展示拟定的分组供其审阅:**展示文件夹树、每个文件夹包含的 id,以及各文件夹编写的摘要。这是一次性且影响重大的整个知识库重组操作——在进行任何写入前,让用户决定是否调整。

3. 确定性地应用存放位置

将文档写入临时文件,并交给确定性应用原语处理:

PLACE_PLAN=$(mktemp -t kk-place-plan.XXXXXX.json)
# Write your {"placements":[...],"folders":[...]} document to $PLACE_PLAN.
npx --yes kenkeep@latest place apply --input "$PLACE_PLAN"

该原语会在进行任何写入前,验证每个 id 是否与磁盘上的叶节点相符,以及每条编写的文件夹摘要是否对应由存放位置创建的文件夹——随后按原样迁移每个叶节点,保留其 id 和字节内容(仅更新 schema_version),并将每条文件夹摘要写入文件夹摘要旁置文件。若计划有误(包含未知或遗漏的 id,或摘要对应的文件夹中没有放置任何叶节点),操作将中止并给出明确提示,且不会进行任何文件系统更改;请修正文档后重新运行。不要自行迁移文件或写入摘要。

成功时,会输出一行 JSON,即存放位置摘要:

{"placed":[{"id":"<id>","targetFolder":"<folder>"}, ...]}
4. 重建索引

根据迁移后的目录树重新生成 ENTRY.md、GRAPH.md 和每个文件夹的 index.md:

npx --yes kenkeep@latest index rebuild

重建操作会保留你在第 3 步写入的文件夹摘要。未编写摘要的文件夹会显示标题式大小写的文件夹名称作为回退值;index rebuild 会发出警告并以状态码 0 退出(只警告,不会阻止操作)。

5. 交接

告知用户迁移已暂存于工作树中,且未运行任何 git 命令。用户可通过以下方式审阅结果:

git diff

移入主题文件夹的叶节点会显示为重命名(id 和字节内容保持不变);每个新建文件夹的摘要都会记录在 .ai/kenkeep/FOLDER_SUMMARIES.md 中;ENTRY.md / GRAPH.md 已刷新。用户可用 git commit 接受迁移,用 git restore(指定路径或整个工作树)拒绝迁移。不要自行暂存、提交或还原任何内容。

okf-v3(2 -> 3)

将 v2 主题目录树迁移为 v3 OKF 原生节点格式。此步骤完全确定性:不进行分组,也不需要 LLM 判断。你的职责是调用原语、检查其摘要,并将生成的差异交给用户审阅。

1. 运行确定性重写

运行 dispatch 报告的原语:

npx --yes kenkeep@latest migrate okf-v3

除非检测到的磁盘版本恰好为 2,否则它会拒绝执行。成功后,它会以机械方式:

  • 将叶节点 frontmatter 中的 kind 重命名为 type,将 summary 重命名为 description;
  • 将 kenkeep 所有的字段移至 kk_ 扩展键(kk_schema_version、kk_id、kk_relates_to、kk_depends_on、kk_derived_from、kk_confidence);
  • 根据 v3 frontmatter 中的事实生成 Related 和 # Citations 正文部分;
  • 将旧版 nodes/**/index.md frontmatter 中的文件夹摘要迁移至 .ai/kenkeep/FOLDER_SUMMARIES.md;
  • 重建 nodes/**/index.md、ENTRY.md 和 GRAPH.md。

它会输出一行 JSON:

{"converted":2,"folder_summaries":1,"collisions":[]}

如果 collisions 非空,请明确指出:这些叶节点在追加生成的部分之前,已经有未标记的 # Related 或 # Citations 标题。不要尝试自行合并这些标题;由用户检查正文差异。

2. 验证并交接

运行常规确定性检查:

npx --yes kenkeep@latest lint --verbose
npx --yes kenkeep@latest doctor --verbose

然后报告:v3 OKF 迁移已暂存在工作树中,且未运行任何 git 命令。告知用户检查:

git diff

叶节点会原地重写,文件夹摘要现存放在 .ai/kenkeep/FOLDER_SUMMARIES.md,普通的 nodes/**/index.md 文件是 OKF 保留文件,且 ENTRY.md / GRAPH.md 已刷新。用户可用 git commit 接受变更,用 git restore 拒绝变更。不要替用户暂存、提交或还原任何内容。

约束

  • 仅在宿主环境内操作。 判断工作在本会话中进行。没有子 Agent,也不使用 -p 派生进程;不要派生子 Agent。
  • 绝不直接写入节点文件。 每次文件变更都必须通过某一步的确定性原语完成——在 flat-to-tree 中,每次叶节点迁移和每次文件夹摘要写入都必须通过 place apply 完成。你只负责编写原语所使用的 JSON 文档。
  • 绝不调用 git。 不运行 add、commit 或 restore。迁移结果应作为未提交差异留给人工接受或拒绝。
  • ID 和边不可更改。 每个叶节点必须保留其确切 ID 和所有边;如果计划会丢弃、重命名或遗漏任何 ID 或边,原语的验证会在写入前中止。
  • 完整迁移需要本交互会话。 不支持无头或无人值守迁移;判断步骤需要你,也就是会话中的 Agent。

评论

支持 Markdown