@nebutra/play-loader 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
- {"at":"2026-05-18T05:13:34.179Z","type":"reload","plays":0}
2
- {"at":"2026-05-18T05:13:34.233Z","type":"reload","plays":1}
3
- {"at":"2026-05-18T05:13:34.236Z","type":"write","play":"launch_page"}
4
- {"at":"2026-05-18T05:13:34.271Z","type":"load","play":"launch_page"}
5
- {"at":"2026-05-18T05:13:34.370Z","type":"reload","plays":2}
6
- {"at":"2026-05-18T05:13:34.376Z","type":"write","play":"launch_page_copy"}
7
- {"at":"2026-05-18T05:13:34.406Z","type":"load","play":"launch_page_copy"}
1
+ {"at":"2026-05-19T08:15:22.732Z","type":"reload","plays":0}
2
+ {"at":"2026-05-19T08:15:22.765Z","type":"reload","plays":1}
3
+ {"at":"2026-05-19T08:15:22.768Z","type":"write","play":"launch_page"}
4
+ {"at":"2026-05-19T08:15:22.780Z","type":"load","play":"launch_page"}
5
+ {"at":"2026-05-19T08:15:22.825Z","type":"reload","plays":2}
6
+ {"at":"2026-05-19T08:15:22.825Z","type":"write","play":"launch_page_copy"}
7
+ {"at":"2026-05-19T08:15:22.844Z","type":"load","play":"launch_page_copy"}
@@ -1,5 +1,5 @@
1
1
 
2
- > @nebutra/play-loader@0.1.0 build /home/runner/work/Nebutra-Sailor/Nebutra-Sailor/packages/ai/play-loader
2
+ > @nebutra/play-loader@0.1.1 build /home/runner/work/Nebutra-Sailor/Nebutra-Sailor/packages/ai/play-loader
3
3
  > tsup
4
4
 
5
5
  CLI Building entry: src/cli.ts, src/index.ts
@@ -11,12 +11,12 @@
11
11
  ESM Build start
12
12
  ESM dist/cli.js 2.28 KB
13
13
  ESM dist/index.js 226.00 B
14
- ESM dist/chunk-7JPGPQKB.js 7.89 KB
14
+ ESM dist/chunk-TVBZH43E.js 7.56 KB
15
15
  ESM dist/cli.js.map 4.29 KB
16
16
  ESM dist/index.js.map 71.00 B
17
- ESM dist/chunk-7JPGPQKB.js.map 15.87 KB
18
- ESM ⚡️ Build success in 126ms
17
+ ESM dist/chunk-TVBZH43E.js.map 15.16 KB
18
+ ESM ⚡️ Build success in 81ms
19
19
  DTS Build start
20
- DTS ⚡️ Build success in 8990ms
20
+ DTS ⚡️ Build success in 6327ms
21
21
  DTS dist/cli.d.ts 13.00 B
22
- DTS dist/index.d.ts 1.85 KB
22
+ DTS dist/index.d.ts 1.91 KB
@@ -1,14 +1,14 @@
1
1
 
2
- > @nebutra/play-loader@0.1.0 test /home/runner/work/Nebutra-Sailor/Nebutra-Sailor/packages/ai/play-loader
2
+ > @nebutra/play-loader@0.1.1 test /home/runner/work/Nebutra-Sailor/Nebutra-Sailor/packages/ai/play-loader
3
3
  > vitest run
4
4
 
5
5
 
6
6
   RUN  v4.1.4 /home/runner/work/Nebutra-Sailor/Nebutra-Sailor/packages/ai/play-loader
7
7
 
8
- ✓ src/index.test.ts (4 tests) 449ms
8
+ ✓ src/index.test.ts (5 tests) 309ms
9
9
 
10
10
   Test Files  1 passed (1)
11
-  Tests  4 passed (4)
12
-  Start at  05:13:32
13
-  Duration  2.33s (transform 888ms, setup 0ms, import 1.17s, tests 449ms, environment 0ms)
11
+  Tests  5 passed (5)
12
+  Start at  08:15:20
13
+  Duration  2.26s (transform 925ms, setup 0ms, import 1.18s, tests 309ms, environment 0ms)
14
14
 
@@ -1,4 +1,4 @@
1
1
 
2
- > @nebutra/play-loader@0.1.0 typecheck /home/runner/work/Nebutra-Sailor/Nebutra-Sailor/packages/ai/play-loader
2
+ > @nebutra/play-loader@0.1.1 typecheck /home/runner/work/Nebutra-Sailor/Nebutra-Sailor/packages/ai/play-loader
3
3
  > tsc --noEmit
4
4
 
package/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
1
+ # @nebutra/play-loader
2
+
3
+ ## 0.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Publish registry package metadata under the MIT license.
8
+
9
+ - Updated dependencies []:
10
+ - @nebutra/capability-kit@0.2.1
11
+ - @nebutra/errors@0.1.1
12
+ - @nebutra/tool-registry@0.1.1
@@ -1,8 +1,9 @@
1
1
  // src/index.ts
2
2
  import { mkdir, readdir, readFile, writeFile } from "fs/promises";
3
3
  import { dirname, join, relative } from "path";
4
+ import { appendCapabilityDebug, readCapabilityDebug } from "@nebutra/capability-kit/debug";
4
5
  import { CapabilityError } from "@nebutra/errors";
5
- import { parseSkillFrontmatter, parseSkillMarkdown } from "@nebutra/tool-registry";
6
+ import { parseSkillMarkdown } from "@nebutra/tool-registry";
6
7
  async function walk(dir) {
7
8
  const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);
8
9
  const files = [];
@@ -25,24 +26,11 @@ function asRecord(value) {
25
26
  function normalizePlayName(name) {
26
27
  return name.trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "_").replace(/^_+|_+$/g, "");
27
28
  }
28
- function playDebugPath() {
29
- return join(process.cwd(), ".nebutra", "debug", "play-loader.jsonl");
30
- }
31
29
  async function appendPlayDebug(entry) {
32
- const path = playDebugPath();
33
- await mkdir(dirname(path), { recursive: true });
34
- await writeFile(path, `${JSON.stringify({ at: (/* @__PURE__ */ new Date()).toISOString(), ...entry })}
35
- `, {
36
- flag: "a"
37
- });
30
+ await appendCapabilityDebug("play-loader", entry);
38
31
  }
39
32
  async function readPlayDebug(limit = 10) {
40
- try {
41
- const raw = await readFile(playDebugPath(), "utf8");
42
- return raw.trim().split("\n").filter(Boolean).slice(-limit).map((line) => JSON.parse(line));
43
- } catch {
44
- return [];
45
- }
33
+ return readCapabilityDebug("play-loader", { limit });
46
34
  }
47
35
  function parseSubagents(value) {
48
36
  if (!Array.isArray(value)) return [];
@@ -65,7 +53,7 @@ function parsePlayDependencies(value) {
65
53
  }
66
54
  function parsePlayMarkdown(markdown) {
67
55
  const loaded = parseSkillMarkdown(markdown);
68
- const { frontmatter } = parseSkillFrontmatter(markdown);
56
+ const { frontmatter } = loaded;
69
57
  if (frontmatter.kind !== "play") {
70
58
  throw new CapabilityError("play-loader", "Play SKILL.md must set kind: play", {
71
59
  suggestion: "Set `kind: play` in frontmatter or keep this document in tool-registry only.",
@@ -76,6 +64,7 @@ function parsePlayMarkdown(markdown) {
76
64
  return {
77
65
  meta: { ...loaded.meta, kind: "play" },
78
66
  body: loaded.body,
67
+ frontmatter,
79
68
  requiredSkills: asStringArray(frontmatter.required_skills),
80
69
  subAgents: parseSubagents(frontmatter.sub_agents),
81
70
  dependsOnPlays: parsePlayDependencies(frontmatter.depends_on_plays)
@@ -230,4 +219,4 @@ export {
230
219
  resolvePlayChain,
231
220
  PlayLoader
232
221
  };
233
- //# sourceMappingURL=chunk-7JPGPQKB.js.map
222
+ //# sourceMappingURL=chunk-TVBZH43E.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { mkdir, readdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname, join, relative } from \"node:path\";\nimport { appendCapabilityDebug, readCapabilityDebug } from \"@nebutra/capability-kit/debug\";\nimport { CapabilityError } from \"@nebutra/errors\";\nimport { type ParsedFrontmatter, parseSkillMarkdown, type SkillMeta } from \"@nebutra/tool-registry\";\n\nexport interface PlayDependency {\n readonly play: string;\n readonly outputs: readonly string[];\n}\n\nexport interface PlaySubagent {\n readonly role: string;\n readonly allowedSkills: readonly string[];\n}\n\nexport interface PlayMeta extends SkillMeta {\n readonly kind: \"play\";\n}\n\nexport interface LoadedPlay {\n readonly meta: PlayMeta;\n readonly body: string;\n readonly frontmatter: ParsedFrontmatter;\n readonly requiredSkills: readonly string[];\n readonly subAgents: readonly PlaySubagent[];\n readonly dependsOnPlays: readonly PlayDependency[];\n}\n\nexport interface PlayNode {\n readonly name: string;\n readonly dependsOn: readonly string[];\n}\n\nexport interface PlayTestReport {\n readonly name: string;\n readonly ok: boolean;\n readonly checks: readonly string[];\n readonly suggestion?: string;\n}\n\nexport interface PlayLoaderDoctorReport {\n readonly ok: boolean;\n readonly plays: number;\n readonly root: string;\n readonly suggestion?: string;\n}\n\nasync function walk(dir: string): Promise<string[]> {\n const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);\n const files: string[] = [];\n for (const entry of entries) {\n const full = join(dir, entry.name);\n if (entry.isDirectory()) files.push(...(await walk(full)));\n else files.push(full);\n }\n return files;\n}\n\nfunction asString(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction asStringArray(value: unknown): string[] {\n return Array.isArray(value)\n ? value.filter((item): item is string => typeof item === \"string\")\n : [];\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nfunction normalizePlayName(name: string): string {\n return name\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9_-]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\");\n}\n\nasync function appendPlayDebug(entry: Record<string, unknown>): Promise<void> {\n await appendCapabilityDebug(\"play-loader\", entry);\n}\n\nexport async function readPlayDebug(limit = 10): Promise<unknown[]> {\n return readCapabilityDebug(\"play-loader\", { limit });\n}\n\nfunction parseSubagents(value: unknown): PlaySubagent[] {\n if (!Array.isArray(value)) return [];\n return value.flatMap((item): PlaySubagent[] => {\n const record = asRecord(item);\n const role = asString(record?.role);\n if (!record || !role) return [];\n return [{ role, allowedSkills: asStringArray(record.allowed_skills) }];\n });\n}\n\nfunction parsePlayDependencies(value: unknown): PlayDependency[] {\n if (!Array.isArray(value)) return [];\n return value.flatMap((item): PlayDependency[] => {\n if (typeof item === \"string\") return [{ play: item, outputs: [] }];\n const record = asRecord(item);\n const play = asString(record?.play);\n if (!record || !play) return [];\n return [{ play, outputs: asStringArray(record.outputs) }];\n });\n}\n\nexport function parsePlayMarkdown(markdown: string): LoadedPlay {\n const loaded = parseSkillMarkdown(markdown);\n const { frontmatter } = loaded;\n if (frontmatter.kind !== \"play\") {\n throw new CapabilityError(\"play-loader\", \"Play SKILL.md must set kind: play\", {\n suggestion: \"Set `kind: play` in frontmatter or keep this document in tool-registry only.\",\n statusCode: 400,\n metadata: { name: loaded.meta.name, kind: frontmatter.kind },\n });\n }\n\n return {\n meta: { ...loaded.meta, kind: \"play\" },\n body: loaded.body,\n frontmatter,\n requiredSkills: asStringArray(frontmatter.required_skills),\n subAgents: parseSubagents(frontmatter.sub_agents),\n dependsOnPlays: parsePlayDependencies(frontmatter.depends_on_plays),\n };\n}\n\nexport function resolvePlayChain(nodes: readonly PlayNode[]): readonly string[] {\n const byName = new Map(nodes.map((node) => [node.name, node]));\n const visited = new Set<string>();\n const visiting = new Set<string>();\n const ordered: string[] = [];\n\n const visit = (name: string): void => {\n if (visited.has(name)) return;\n if (visiting.has(name)) {\n throw new CapabilityError(\"play-loader\", \"Play dependency cycle detected\", {\n suggestion: \"Remove the cycle or merge mutually dependent plays into one declaration.\",\n statusCode: 400,\n metadata: { name },\n });\n }\n visiting.add(name);\n const node = byName.get(name);\n for (const dependency of node?.dependsOn ?? []) visit(dependency);\n visiting.delete(name);\n visited.add(name);\n ordered.push(name);\n };\n\n for (const node of nodes) visit(node.name);\n return ordered;\n}\n\nexport class PlayLoader {\n readonly #root: string;\n readonly #plays = new Map<string, { readonly meta: PlayMeta; readonly path: string }>();\n\n private constructor(root: string) {\n this.#root = root;\n }\n\n static async open(root: string): Promise<PlayLoader> {\n const loader = new PlayLoader(root);\n await mkdir(loader.playsRoot(), { recursive: true });\n await loader.reload();\n return loader;\n }\n\n playsRoot(): string {\n return join(this.#root, \"plays\");\n }\n\n async writePlay(name: string, markdown: string): Promise<void> {\n const normalized = normalizePlayName(name);\n const parsed = parsePlayMarkdown(markdown);\n if (parsed.meta.name !== normalized) {\n throw new CapabilityError(\"play-loader\", \"Play name does not match path\", {\n suggestion: \"Use the same lowercase codename in the path and SKILL.md frontmatter.\",\n metadata: { pathName: normalized, playName: parsed.meta.name },\n statusCode: 400,\n });\n }\n const path = join(this.playsRoot(), normalized, \"SKILL.md\");\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, markdown, \"utf8\");\n await this.reload();\n await appendPlayDebug({ type: \"write\", play: normalized });\n }\n\n async newPlay(name: string): Promise<LoadedPlay> {\n const normalized = normalizePlayName(name);\n const markdown = [\n \"---\",\n `name: ${normalized}`,\n \"kind: play\",\n \"version: 1.0.0\",\n `description: ${normalized.replaceAll(\"_\", \" \")} play`,\n \"required_skills: []\",\n \"sub_agents: []\",\n \"depends_on_plays: []\",\n \"---\",\n \"\",\n \"## What this play does\",\n \"\",\n \"Describe the user story and expected output.\",\n ].join(\"\\n\");\n await this.writePlay(normalized, markdown);\n return this.load(normalized);\n }\n\n async reload(): Promise<void> {\n this.#plays.clear();\n for (const file of await walk(this.playsRoot())) {\n if (!file.endsWith(\"SKILL.md\")) continue;\n const raw = await readFile(file, \"utf8\");\n const play = parsePlayMarkdown(raw);\n this.#plays.set(play.meta.name, { meta: play.meta, path: relative(this.#root, file) });\n }\n await appendPlayDebug({ type: \"reload\", plays: this.#plays.size });\n }\n\n async list(): Promise<PlayMeta[]> {\n return [...this.#plays.values()]\n .map((entry) => entry.meta)\n .sort((left, right) => left.name.localeCompare(right.name));\n }\n\n async load(name: string): Promise<LoadedPlay> {\n const play = this.#plays.get(normalizePlayName(name));\n if (!play) {\n throw new CapabilityError(\"play-loader\", \"Play not found\", {\n suggestion: \"Run `pnpm play:list` or create it with `pnpm play:new <name>`.\",\n metadata: { name },\n statusCode: 404,\n });\n }\n const loaded = parsePlayMarkdown(await readFile(join(this.#root, play.path), \"utf8\"));\n await appendPlayDebug({ type: \"load\", play: loaded.meta.name });\n return loaded;\n }\n\n async install(source: string): Promise<LoadedPlay> {\n if (!source.startsWith(\"file:\")) {\n throw new CapabilityError(\"play-loader\", \"Only file installs are enabled locally\", {\n suggestion:\n \"Download remote plays through a reviewed distribution workflow, then install with file:<path>.\",\n metadata: { source },\n statusCode: 400,\n });\n }\n const raw = await readFile(source.slice(\"file:\".length), \"utf8\");\n const play = parsePlayMarkdown(raw);\n await this.writePlay(play.meta.name, raw);\n return this.load(play.meta.name);\n }\n\n async test(name: string): Promise<PlayTestReport> {\n try {\n const play = await this.load(name);\n return {\n name: play.meta.name,\n ok: play.body.length > 0,\n checks: [\"frontmatter\", \"kind:play\", \"body\", \"dependency-dag\"],\n ...(!play.body ? { suggestion: \"Add a markdown body after the frontmatter.\" } : {}),\n };\n } catch (error) {\n return {\n name,\n ok: false,\n checks: [],\n suggestion:\n error instanceof CapabilityError\n ? \"Create the play with `pnpm play:new <name>` or fix its SKILL.md metadata.\"\n : \"Run `pnpm play:list` and verify the play directory exists.\",\n };\n }\n }\n\n async doctor(): Promise<PlayLoaderDoctorReport> {\n const plays = this.#plays.size;\n return {\n ok: plays > 0,\n plays,\n root: this.#root,\n ...(plays === 0 ? { suggestion: \"Create a play with `pnpm play:new <name>`.\" } : {}),\n };\n }\n}\n"],"mappings":";AAAA,SAAS,OAAO,SAAS,UAAU,iBAAiB;AACpD,SAAS,SAAS,MAAM,gBAAgB;AACxC,SAAS,uBAAuB,2BAA2B;AAC3D,SAAS,uBAAuB;AAChC,SAAiC,0BAA0C;AA4C3E,eAAe,KAAK,KAAgC;AAClD,QAAM,UAAU,MAAM,QAAQ,KAAK,EAAE,eAAe,KAAK,CAAC,EAAE,MAAM,MAAM,CAAC,CAAC;AAC1E,QAAM,QAAkB,CAAC;AACzB,aAAW,SAAS,SAAS;AAC3B,UAAM,OAAO,KAAK,KAAK,MAAM,IAAI;AACjC,QAAI,MAAM,YAAY,EAAG,OAAM,KAAK,GAAI,MAAM,KAAK,IAAI,CAAE;AAAA,QACpD,OAAM,KAAK,IAAI;AAAA,EACtB;AACA,SAAO;AACT;AAEA,SAAS,SAAS,OAAoC;AACpD,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAEA,SAAS,cAAc,OAA0B;AAC/C,SAAO,MAAM,QAAQ,KAAK,IACtB,MAAM,OAAO,CAAC,SAAyB,OAAO,SAAS,QAAQ,IAC/D,CAAC;AACP;AAEA,SAAS,SAAS,OAAqD;AACrE,SAAO,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IAC5D,QACD;AACN;AAEA,SAAS,kBAAkB,MAAsB;AAC/C,SAAO,KACJ,KAAK,EACL,YAAY,EACZ,QAAQ,iBAAiB,GAAG,EAC5B,QAAQ,YAAY,EAAE;AAC3B;AAEA,eAAe,gBAAgB,OAA+C;AAC5E,QAAM,sBAAsB,eAAe,KAAK;AAClD;AAEA,eAAsB,cAAc,QAAQ,IAAwB;AAClE,SAAO,oBAAoB,eAAe,EAAE,MAAM,CAAC;AACrD;AAEA,SAAS,eAAe,OAAgC;AACtD,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO,CAAC;AACnC,SAAO,MAAM,QAAQ,CAAC,SAAyB;AAC7C,UAAM,SAAS,SAAS,IAAI;AAC5B,UAAM,OAAO,SAAS,QAAQ,IAAI;AAClC,QAAI,CAAC,UAAU,CAAC,KAAM,QAAO,CAAC;AAC9B,WAAO,CAAC,EAAE,MAAM,eAAe,cAAc,OAAO,cAAc,EAAE,CAAC;AAAA,EACvE,CAAC;AACH;AAEA,SAAS,sBAAsB,OAAkC;AAC/D,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO,CAAC;AACnC,SAAO,MAAM,QAAQ,CAAC,SAA2B;AAC/C,QAAI,OAAO,SAAS,SAAU,QAAO,CAAC,EAAE,MAAM,MAAM,SAAS,CAAC,EAAE,CAAC;AACjE,UAAM,SAAS,SAAS,IAAI;AAC5B,UAAM,OAAO,SAAS,QAAQ,IAAI;AAClC,QAAI,CAAC,UAAU,CAAC,KAAM,QAAO,CAAC;AAC9B,WAAO,CAAC,EAAE,MAAM,SAAS,cAAc,OAAO,OAAO,EAAE,CAAC;AAAA,EAC1D,CAAC;AACH;AAEO,SAAS,kBAAkB,UAA8B;AAC9D,QAAM,SAAS,mBAAmB,QAAQ;AAC1C,QAAM,EAAE,YAAY,IAAI;AACxB,MAAI,YAAY,SAAS,QAAQ;AAC/B,UAAM,IAAI,gBAAgB,eAAe,qCAAqC;AAAA,MAC5E,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,UAAU,EAAE,MAAM,OAAO,KAAK,MAAM,MAAM,YAAY,KAAK;AAAA,IAC7D,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL,MAAM,EAAE,GAAG,OAAO,MAAM,MAAM,OAAO;AAAA,IACrC,MAAM,OAAO;AAAA,IACb;AAAA,IACA,gBAAgB,cAAc,YAAY,eAAe;AAAA,IACzD,WAAW,eAAe,YAAY,UAAU;AAAA,IAChD,gBAAgB,sBAAsB,YAAY,gBAAgB;AAAA,EACpE;AACF;AAEO,SAAS,iBAAiB,OAA+C;AAC9E,QAAM,SAAS,IAAI,IAAI,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,MAAM,IAAI,CAAC,CAAC;AAC7D,QAAM,UAAU,oBAAI,IAAY;AAChC,QAAM,WAAW,oBAAI,IAAY;AACjC,QAAM,UAAoB,CAAC;AAE3B,QAAM,QAAQ,CAAC,SAAuB;AACpC,QAAI,QAAQ,IAAI,IAAI,EAAG;AACvB,QAAI,SAAS,IAAI,IAAI,GAAG;AACtB,YAAM,IAAI,gBAAgB,eAAe,kCAAkC;AAAA,QACzE,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,UAAU,EAAE,KAAK;AAAA,MACnB,CAAC;AAAA,IACH;AACA,aAAS,IAAI,IAAI;AACjB,UAAM,OAAO,OAAO,IAAI,IAAI;AAC5B,eAAW,cAAc,MAAM,aAAa,CAAC,EAAG,OAAM,UAAU;AAChE,aAAS,OAAO,IAAI;AACpB,YAAQ,IAAI,IAAI;AAChB,YAAQ,KAAK,IAAI;AAAA,EACnB;AAEA,aAAW,QAAQ,MAAO,OAAM,KAAK,IAAI;AACzC,SAAO;AACT;AAEO,IAAM,aAAN,MAAM,YAAW;AAAA,EACb;AAAA,EACA,SAAS,oBAAI,IAAgE;AAAA,EAE9E,YAAY,MAAc;AAChC,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,aAAa,KAAK,MAAmC;AACnD,UAAM,SAAS,IAAI,YAAW,IAAI;AAClC,UAAM,MAAM,OAAO,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AACnD,UAAM,OAAO,OAAO;AACpB,WAAO;AAAA,EACT;AAAA,EAEA,YAAoB;AAClB,WAAO,KAAK,KAAK,OAAO,OAAO;AAAA,EACjC;AAAA,EAEA,MAAM,UAAU,MAAc,UAAiC;AAC7D,UAAM,aAAa,kBAAkB,IAAI;AACzC,UAAM,SAAS,kBAAkB,QAAQ;AACzC,QAAI,OAAO,KAAK,SAAS,YAAY;AACnC,YAAM,IAAI,gBAAgB,eAAe,iCAAiC;AAAA,QACxE,YAAY;AAAA,QACZ,UAAU,EAAE,UAAU,YAAY,UAAU,OAAO,KAAK,KAAK;AAAA,QAC7D,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AACA,UAAM,OAAO,KAAK,KAAK,UAAU,GAAG,YAAY,UAAU;AAC1D,UAAM,MAAM,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC9C,UAAM,UAAU,MAAM,UAAU,MAAM;AACtC,UAAM,KAAK,OAAO;AAClB,UAAM,gBAAgB,EAAE,MAAM,SAAS,MAAM,WAAW,CAAC;AAAA,EAC3D;AAAA,EAEA,MAAM,QAAQ,MAAmC;AAC/C,UAAM,aAAa,kBAAkB,IAAI;AACzC,UAAM,WAAW;AAAA,MACf;AAAA,MACA,SAAS,UAAU;AAAA,MACnB;AAAA,MACA;AAAA,MACA,gBAAgB,WAAW,WAAW,KAAK,GAAG,CAAC;AAAA,MAC/C;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AACX,UAAM,KAAK,UAAU,YAAY,QAAQ;AACzC,WAAO,KAAK,KAAK,UAAU;AAAA,EAC7B;AAAA,EAEA,MAAM,SAAwB;AAC5B,SAAK,OAAO,MAAM;AAClB,eAAW,QAAQ,MAAM,KAAK,KAAK,UAAU,CAAC,GAAG;AAC/C,UAAI,CAAC,KAAK,SAAS,UAAU,EAAG;AAChC,YAAM,MAAM,MAAM,SAAS,MAAM,MAAM;AACvC,YAAM,OAAO,kBAAkB,GAAG;AAClC,WAAK,OAAO,IAAI,KAAK,KAAK,MAAM,EAAE,MAAM,KAAK,MAAM,MAAM,SAAS,KAAK,OAAO,IAAI,EAAE,CAAC;AAAA,IACvF;AACA,UAAM,gBAAgB,EAAE,MAAM,UAAU,OAAO,KAAK,OAAO,KAAK,CAAC;AAAA,EACnE;AAAA,EAEA,MAAM,OAA4B;AAChC,WAAO,CAAC,GAAG,KAAK,OAAO,OAAO,CAAC,EAC5B,IAAI,CAAC,UAAU,MAAM,IAAI,EACzB,KAAK,CAAC,MAAM,UAAU,KAAK,KAAK,cAAc,MAAM,IAAI,CAAC;AAAA,EAC9D;AAAA,EAEA,MAAM,KAAK,MAAmC;AAC5C,UAAM,OAAO,KAAK,OAAO,IAAI,kBAAkB,IAAI,CAAC;AACpD,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,gBAAgB,eAAe,kBAAkB;AAAA,QACzD,YAAY;AAAA,QACZ,UAAU,EAAE,KAAK;AAAA,QACjB,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AACA,UAAM,SAAS,kBAAkB,MAAM,SAAS,KAAK,KAAK,OAAO,KAAK,IAAI,GAAG,MAAM,CAAC;AACpF,UAAM,gBAAgB,EAAE,MAAM,QAAQ,MAAM,OAAO,KAAK,KAAK,CAAC;AAC9D,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,QAAQ,QAAqC;AACjD,QAAI,CAAC,OAAO,WAAW,OAAO,GAAG;AAC/B,YAAM,IAAI,gBAAgB,eAAe,0CAA0C;AAAA,QACjF,YACE;AAAA,QACF,UAAU,EAAE,OAAO;AAAA,QACnB,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AACA,UAAM,MAAM,MAAM,SAAS,OAAO,MAAM,QAAQ,MAAM,GAAG,MAAM;AAC/D,UAAM,OAAO,kBAAkB,GAAG;AAClC,UAAM,KAAK,UAAU,KAAK,KAAK,MAAM,GAAG;AACxC,WAAO,KAAK,KAAK,KAAK,KAAK,IAAI;AAAA,EACjC;AAAA,EAEA,MAAM,KAAK,MAAuC;AAChD,QAAI;AACF,YAAM,OAAO,MAAM,KAAK,KAAK,IAAI;AACjC,aAAO;AAAA,QACL,MAAM,KAAK,KAAK;AAAA,QAChB,IAAI,KAAK,KAAK,SAAS;AAAA,QACvB,QAAQ,CAAC,eAAe,aAAa,QAAQ,gBAAgB;AAAA,QAC7D,GAAI,CAAC,KAAK,OAAO,EAAE,YAAY,6CAA6C,IAAI,CAAC;AAAA,MACnF;AAAA,IACF,SAAS,OAAO;AACd,aAAO;AAAA,QACL;AAAA,QACA,IAAI;AAAA,QACJ,QAAQ,CAAC;AAAA,QACT,YACE,iBAAiB,kBACb,8EACA;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,SAA0C;AAC9C,UAAM,QAAQ,KAAK,OAAO;AAC1B,WAAO;AAAA,MACL,IAAI,QAAQ;AAAA,MACZ;AAAA,MACA,MAAM,KAAK;AAAA,MACX,GAAI,UAAU,IAAI,EAAE,YAAY,6CAA6C,IAAI,CAAC;AAAA,IACpF;AAAA,EACF;AACF;","names":[]}
package/dist/cli.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  parsePlayMarkdown,
4
4
  readPlayDebug,
5
5
  resolvePlayChain
6
- } from "./chunk-7JPGPQKB.js";
6
+ } from "./chunk-TVBZH43E.js";
7
7
 
8
8
  // src/cli.ts
9
9
  import { readFile } from "fs/promises";
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { SkillMeta } from '@nebutra/tool-registry';
1
+ import { SkillMeta, ParsedFrontmatter } from '@nebutra/tool-registry';
2
2
 
3
3
  interface PlayDependency {
4
4
  readonly play: string;
@@ -14,6 +14,7 @@ interface PlayMeta extends SkillMeta {
14
14
  interface LoadedPlay {
15
15
  readonly meta: PlayMeta;
16
16
  readonly body: string;
17
+ readonly frontmatter: ParsedFrontmatter;
17
18
  readonly requiredSkills: readonly string[];
18
19
  readonly subAgents: readonly PlaySubagent[];
19
20
  readonly dependsOnPlays: readonly PlayDependency[];
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  parsePlayMarkdown,
4
4
  readPlayDebug,
5
5
  resolvePlayChain
6
- } from "./chunk-7JPGPQKB.js";
6
+ } from "./chunk-TVBZH43E.js";
7
7
  export {
8
8
  PlayLoader,
9
9
  parsePlayMarkdown,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nebutra/play-loader",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Declarative SKILL.md play loader and dependency planner",
5
5
  "private": false,
6
6
  "license": "MIT",
@@ -18,6 +18,7 @@
18
18
  ],
19
19
  "featureId": "play-loader",
20
20
  "category": "ai",
21
+ "surface": "product-orchestration",
21
22
  "summary": "SKILL.md play parser, dependency-chain planner, and agent-runtime runner seam"
22
23
  },
23
24
  "main": "./src/index.ts",
@@ -26,8 +27,9 @@
26
27
  ".": "./src/index.ts"
27
28
  },
28
29
  "dependencies": {
29
- "@nebutra/errors": "0.1.0",
30
- "@nebutra/tool-registry": "0.1.0"
30
+ "@nebutra/capability-kit": "0.2.1",
31
+ "@nebutra/errors": "0.1.1",
32
+ "@nebutra/tool-registry": "0.1.1"
31
33
  },
32
34
  "devDependencies": {
33
35
  "@types/node": "^22.19.15",
package/src/index.test.ts CHANGED
@@ -56,6 +56,15 @@ describe("play-loader", () => {
56
56
  expect(play.body).toContain("Create a launch page");
57
57
  });
58
58
 
59
+ it("keeps raw play frontmatter on the shared SKILL parser contract", () => {
60
+ const play = parsePlayMarkdown(playMarkdown);
61
+
62
+ expect(play.frontmatter).toMatchObject({
63
+ kind: "play",
64
+ required_skills: ["content_store.write", "tool_protocol.call"],
65
+ });
66
+ });
67
+
59
68
  it("rejects non-play SKILL.md documents with a fix suggestion", () => {
60
69
  const markdown = playMarkdown.replace("kind: play", "kind: skill");
61
70
  expect(() => parsePlayMarkdown(markdown)).toThrow(/kind: play/i);
package/src/index.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import { mkdir, readdir, readFile, writeFile } from "node:fs/promises";
2
2
  import { dirname, join, relative } from "node:path";
3
+ import { appendCapabilityDebug, readCapabilityDebug } from "@nebutra/capability-kit/debug";
3
4
  import { CapabilityError } from "@nebutra/errors";
4
- import { parseSkillFrontmatter, parseSkillMarkdown, type SkillMeta } from "@nebutra/tool-registry";
5
+ import { type ParsedFrontmatter, parseSkillMarkdown, type SkillMeta } from "@nebutra/tool-registry";
5
6
 
6
7
  export interface PlayDependency {
7
8
  readonly play: string;
@@ -20,6 +21,7 @@ export interface PlayMeta extends SkillMeta {
20
21
  export interface LoadedPlay {
21
22
  readonly meta: PlayMeta;
22
23
  readonly body: string;
24
+ readonly frontmatter: ParsedFrontmatter;
23
25
  readonly requiredSkills: readonly string[];
24
26
  readonly subAgents: readonly PlaySubagent[];
25
27
  readonly dependsOnPlays: readonly PlayDependency[];
@@ -79,30 +81,12 @@ function normalizePlayName(name: string): string {
79
81
  .replace(/^_+|_+$/g, "");
80
82
  }
81
83
 
82
- function playDebugPath(): string {
83
- return join(process.cwd(), ".nebutra", "debug", "play-loader.jsonl");
84
- }
85
-
86
84
  async function appendPlayDebug(entry: Record<string, unknown>): Promise<void> {
87
- const path = playDebugPath();
88
- await mkdir(dirname(path), { recursive: true });
89
- await writeFile(path, `${JSON.stringify({ at: new Date().toISOString(), ...entry })}\n`, {
90
- flag: "a",
91
- });
85
+ await appendCapabilityDebug("play-loader", entry);
92
86
  }
93
87
 
94
88
  export async function readPlayDebug(limit = 10): Promise<unknown[]> {
95
- try {
96
- const raw = await readFile(playDebugPath(), "utf8");
97
- return raw
98
- .trim()
99
- .split("\n")
100
- .filter(Boolean)
101
- .slice(-limit)
102
- .map((line) => JSON.parse(line) as unknown);
103
- } catch {
104
- return [];
105
- }
89
+ return readCapabilityDebug("play-loader", { limit });
106
90
  }
107
91
 
108
92
  function parseSubagents(value: unknown): PlaySubagent[] {
@@ -128,7 +112,7 @@ function parsePlayDependencies(value: unknown): PlayDependency[] {
128
112
 
129
113
  export function parsePlayMarkdown(markdown: string): LoadedPlay {
130
114
  const loaded = parseSkillMarkdown(markdown);
131
- const { frontmatter } = parseSkillFrontmatter(markdown);
115
+ const { frontmatter } = loaded;
132
116
  if (frontmatter.kind !== "play") {
133
117
  throw new CapabilityError("play-loader", "Play SKILL.md must set kind: play", {
134
118
  suggestion: "Set `kind: play` in frontmatter or keep this document in tool-registry only.",
@@ -140,6 +124,7 @@ export function parsePlayMarkdown(markdown: string): LoadedPlay {
140
124
  return {
141
125
  meta: { ...loaded.meta, kind: "play" },
142
126
  body: loaded.body,
127
+ frontmatter,
143
128
  requiredSkills: asStringArray(frontmatter.required_skills),
144
129
  subAgents: parseSubagents(frontmatter.sub_agents),
145
130
  dependsOnPlays: parsePlayDependencies(frontmatter.depends_on_plays),
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { mkdir, readdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname, join, relative } from \"node:path\";\nimport { CapabilityError } from \"@nebutra/errors\";\nimport { parseSkillFrontmatter, parseSkillMarkdown, type SkillMeta } from \"@nebutra/tool-registry\";\n\nexport interface PlayDependency {\n readonly play: string;\n readonly outputs: readonly string[];\n}\n\nexport interface PlaySubagent {\n readonly role: string;\n readonly allowedSkills: readonly string[];\n}\n\nexport interface PlayMeta extends SkillMeta {\n readonly kind: \"play\";\n}\n\nexport interface LoadedPlay {\n readonly meta: PlayMeta;\n readonly body: string;\n readonly requiredSkills: readonly string[];\n readonly subAgents: readonly PlaySubagent[];\n readonly dependsOnPlays: readonly PlayDependency[];\n}\n\nexport interface PlayNode {\n readonly name: string;\n readonly dependsOn: readonly string[];\n}\n\nexport interface PlayTestReport {\n readonly name: string;\n readonly ok: boolean;\n readonly checks: readonly string[];\n readonly suggestion?: string;\n}\n\nexport interface PlayLoaderDoctorReport {\n readonly ok: boolean;\n readonly plays: number;\n readonly root: string;\n readonly suggestion?: string;\n}\n\nasync function walk(dir: string): Promise<string[]> {\n const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);\n const files: string[] = [];\n for (const entry of entries) {\n const full = join(dir, entry.name);\n if (entry.isDirectory()) files.push(...(await walk(full)));\n else files.push(full);\n }\n return files;\n}\n\nfunction asString(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction asStringArray(value: unknown): string[] {\n return Array.isArray(value)\n ? value.filter((item): item is string => typeof item === \"string\")\n : [];\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nfunction normalizePlayName(name: string): string {\n return name\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9_-]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\");\n}\n\nfunction playDebugPath(): string {\n return join(process.cwd(), \".nebutra\", \"debug\", \"play-loader.jsonl\");\n}\n\nasync function appendPlayDebug(entry: Record<string, unknown>): Promise<void> {\n const path = playDebugPath();\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, `${JSON.stringify({ at: new Date().toISOString(), ...entry })}\\n`, {\n flag: \"a\",\n });\n}\n\nexport async function readPlayDebug(limit = 10): Promise<unknown[]> {\n try {\n const raw = await readFile(playDebugPath(), \"utf8\");\n return raw\n .trim()\n .split(\"\\n\")\n .filter(Boolean)\n .slice(-limit)\n .map((line) => JSON.parse(line) as unknown);\n } catch {\n return [];\n }\n}\n\nfunction parseSubagents(value: unknown): PlaySubagent[] {\n if (!Array.isArray(value)) return [];\n return value.flatMap((item): PlaySubagent[] => {\n const record = asRecord(item);\n const role = asString(record?.role);\n if (!record || !role) return [];\n return [{ role, allowedSkills: asStringArray(record.allowed_skills) }];\n });\n}\n\nfunction parsePlayDependencies(value: unknown): PlayDependency[] {\n if (!Array.isArray(value)) return [];\n return value.flatMap((item): PlayDependency[] => {\n if (typeof item === \"string\") return [{ play: item, outputs: [] }];\n const record = asRecord(item);\n const play = asString(record?.play);\n if (!record || !play) return [];\n return [{ play, outputs: asStringArray(record.outputs) }];\n });\n}\n\nexport function parsePlayMarkdown(markdown: string): LoadedPlay {\n const loaded = parseSkillMarkdown(markdown);\n const { frontmatter } = parseSkillFrontmatter(markdown);\n if (frontmatter.kind !== \"play\") {\n throw new CapabilityError(\"play-loader\", \"Play SKILL.md must set kind: play\", {\n suggestion: \"Set `kind: play` in frontmatter or keep this document in tool-registry only.\",\n statusCode: 400,\n metadata: { name: loaded.meta.name, kind: frontmatter.kind },\n });\n }\n\n return {\n meta: { ...loaded.meta, kind: \"play\" },\n body: loaded.body,\n requiredSkills: asStringArray(frontmatter.required_skills),\n subAgents: parseSubagents(frontmatter.sub_agents),\n dependsOnPlays: parsePlayDependencies(frontmatter.depends_on_plays),\n };\n}\n\nexport function resolvePlayChain(nodes: readonly PlayNode[]): readonly string[] {\n const byName = new Map(nodes.map((node) => [node.name, node]));\n const visited = new Set<string>();\n const visiting = new Set<string>();\n const ordered: string[] = [];\n\n const visit = (name: string): void => {\n if (visited.has(name)) return;\n if (visiting.has(name)) {\n throw new CapabilityError(\"play-loader\", \"Play dependency cycle detected\", {\n suggestion: \"Remove the cycle or merge mutually dependent plays into one declaration.\",\n statusCode: 400,\n metadata: { name },\n });\n }\n visiting.add(name);\n const node = byName.get(name);\n for (const dependency of node?.dependsOn ?? []) visit(dependency);\n visiting.delete(name);\n visited.add(name);\n ordered.push(name);\n };\n\n for (const node of nodes) visit(node.name);\n return ordered;\n}\n\nexport class PlayLoader {\n readonly #root: string;\n readonly #plays = new Map<string, { readonly meta: PlayMeta; readonly path: string }>();\n\n private constructor(root: string) {\n this.#root = root;\n }\n\n static async open(root: string): Promise<PlayLoader> {\n const loader = new PlayLoader(root);\n await mkdir(loader.playsRoot(), { recursive: true });\n await loader.reload();\n return loader;\n }\n\n playsRoot(): string {\n return join(this.#root, \"plays\");\n }\n\n async writePlay(name: string, markdown: string): Promise<void> {\n const normalized = normalizePlayName(name);\n const parsed = parsePlayMarkdown(markdown);\n if (parsed.meta.name !== normalized) {\n throw new CapabilityError(\"play-loader\", \"Play name does not match path\", {\n suggestion: \"Use the same lowercase codename in the path and SKILL.md frontmatter.\",\n metadata: { pathName: normalized, playName: parsed.meta.name },\n statusCode: 400,\n });\n }\n const path = join(this.playsRoot(), normalized, \"SKILL.md\");\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, markdown, \"utf8\");\n await this.reload();\n await appendPlayDebug({ type: \"write\", play: normalized });\n }\n\n async newPlay(name: string): Promise<LoadedPlay> {\n const normalized = normalizePlayName(name);\n const markdown = [\n \"---\",\n `name: ${normalized}`,\n \"kind: play\",\n \"version: 1.0.0\",\n `description: ${normalized.replaceAll(\"_\", \" \")} play`,\n \"required_skills: []\",\n \"sub_agents: []\",\n \"depends_on_plays: []\",\n \"---\",\n \"\",\n \"## What this play does\",\n \"\",\n \"Describe the user story and expected output.\",\n ].join(\"\\n\");\n await this.writePlay(normalized, markdown);\n return this.load(normalized);\n }\n\n async reload(): Promise<void> {\n this.#plays.clear();\n for (const file of await walk(this.playsRoot())) {\n if (!file.endsWith(\"SKILL.md\")) continue;\n const raw = await readFile(file, \"utf8\");\n const play = parsePlayMarkdown(raw);\n this.#plays.set(play.meta.name, { meta: play.meta, path: relative(this.#root, file) });\n }\n await appendPlayDebug({ type: \"reload\", plays: this.#plays.size });\n }\n\n async list(): Promise<PlayMeta[]> {\n return [...this.#plays.values()]\n .map((entry) => entry.meta)\n .sort((left, right) => left.name.localeCompare(right.name));\n }\n\n async load(name: string): Promise<LoadedPlay> {\n const play = this.#plays.get(normalizePlayName(name));\n if (!play) {\n throw new CapabilityError(\"play-loader\", \"Play not found\", {\n suggestion: \"Run `pnpm play:list` or create it with `pnpm play:new <name>`.\",\n metadata: { name },\n statusCode: 404,\n });\n }\n const loaded = parsePlayMarkdown(await readFile(join(this.#root, play.path), \"utf8\"));\n await appendPlayDebug({ type: \"load\", play: loaded.meta.name });\n return loaded;\n }\n\n async install(source: string): Promise<LoadedPlay> {\n if (!source.startsWith(\"file:\")) {\n throw new CapabilityError(\"play-loader\", \"Only file installs are enabled locally\", {\n suggestion:\n \"Download remote plays through a reviewed distribution workflow, then install with file:<path>.\",\n metadata: { source },\n statusCode: 400,\n });\n }\n const raw = await readFile(source.slice(\"file:\".length), \"utf8\");\n const play = parsePlayMarkdown(raw);\n await this.writePlay(play.meta.name, raw);\n return this.load(play.meta.name);\n }\n\n async test(name: string): Promise<PlayTestReport> {\n try {\n const play = await this.load(name);\n return {\n name: play.meta.name,\n ok: play.body.length > 0,\n checks: [\"frontmatter\", \"kind:play\", \"body\", \"dependency-dag\"],\n ...(!play.body ? { suggestion: \"Add a markdown body after the frontmatter.\" } : {}),\n };\n } catch (error) {\n return {\n name,\n ok: false,\n checks: [],\n suggestion:\n error instanceof CapabilityError\n ? \"Create the play with `pnpm play:new <name>` or fix its SKILL.md metadata.\"\n : \"Run `pnpm play:list` and verify the play directory exists.\",\n };\n }\n }\n\n async doctor(): Promise<PlayLoaderDoctorReport> {\n const plays = this.#plays.size;\n return {\n ok: plays > 0,\n plays,\n root: this.#root,\n ...(plays === 0 ? { suggestion: \"Create a play with `pnpm play:new <name>`.\" } : {}),\n };\n }\n}\n"],"mappings":"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","names":[]}