本页目录
Runtime —— loader 与 resolver
@skill-wiki/runtime 读磁盘上的编译产物,把 metadata 加投影路径喂给 MCP server。
它从来不读 chunk 正文。
模块
| 模块 | 角色 |
|---|---|
atom-loader.ts | 按原子读 atom.yaml 与 graph.yaml,不读 chunks。 |
index-loader.ts | 解析 _index.xml,构建内存里的 atom map。 |
projection-resolver.ts | 给一对 (atom, level),返回磁盘路径。 |
domain-config.ts | 递归发现 domain.yaml,再加上 DomainRegistry。 |
edge-walker.ts | 在内存边图上做 BFS / DFS。 |
启动时序
async function boot(primeDir: string) {
// 1. Discover domain plugins.
const domains = await discoverDomains(primeDir);
for (const d of domains) DomainRegistry.register(d);
// 2. Parse the index.
const index = await loadIndex(`${primeDir}/_index.xml`);
// 3. Build the in-memory graph.
// Atoms map id → metadata; no chunk content read here.
const graph = buildGraph(index);
return { domains, index, graph };
} "永不读 chunk 内容"这条规矩
运行时契约把 chunks/{summary,core,full}.md 划在运行时之外。原因有三:
- 跟 agent 的工作方式一致。agent 自带
Read工具。在运行时再造一份只会引来格式漂移和缓存 bug。 - 内存有界。chunk 内容随 corpus 大小膨胀,metadata 加 index 不会(哪怕 1k 个原子也才约 50 KB)。
- 热重载。运行时可以热重载 index,又不必动 agent 已经看到的具体原子。
// packages/runtime/src/atom-loader.ts
//
// IMPORTANT: This module NEVER reads chunks/*.md content.
// It only reads _index.xml and atom.yaml (metadata).
// Chunk content is exclusively for the agent to pull via the Read tool. 边遍历器
MCP server 用它来满足 contract 解析、走 requires 链:
function walkRequires(seed: AtomMeta, depth = 5): AtomMeta[] {
const out: AtomMeta[] = [];
const seen = new Set<string>([seed.id]);
const queue: [AtomMeta, number][] = [[seed, 0]];
while (queue.length > 0) {
const [atom, d] = queue.shift()!;
if (d >= depth) continue;
for (const edge of atom.edges) {
if (edge.verb !== 'requires' || seen.has(edge.target)) continue;
const target = byId.get(edge.target);
if (!target) continue;
seen.add(target.id);
out.push(target);
queue.push([target, d + 1]);
}
}
return out;
} 对外 API
import { Runtime } from "@skill-wiki/runtime";
const rt = await Runtime.boot({ primeDir: "/path/to/compiled" });
// Lookup
const atom = rt.lookup("@recipes/method-pan-sauce");
// Resolve a projection (returns a path, NOT content)
const path = rt.resolveProjection(atom.id, "core");
// Walk
const deps = rt.walkRequires(atom);
// Domains
console.log(rt.domains); // [DomainConfig, ...]