@zedtech/zedkit-ai 0.0.0 → 0.2.0

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.
package/dist/bin.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=bin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":""}
package/dist/bin.js ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ // Original work by the same author.
3
+ import { main } from "./cli.js";
4
+ process.exitCode = main(process.argv.slice(2), {
5
+ out: (line) => console.log(line),
6
+ err: (line) => console.error(line),
7
+ });
8
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,oCAAoC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAEhC,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;IAC7C,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;IAChC,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;CACnC,CAAC,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ /** Where the CLI writes: normal lines and error lines. */
2
+ export type Sinks = {
3
+ out: (line: string) => void;
4
+ err: (line: string) => void;
5
+ };
6
+ /** Run the CLI. Returns the process exit code (0 ok, 1 validation problems, 2 usage or runtime error). */
7
+ export declare function main(argv: string[], sinks: Sinks): number;
8
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAyBA,0DAA0D;AAC1D,MAAM,MAAM,KAAK,GAAG;IAAE,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,CAAC;AAqFjF,0GAA0G;AAC1G,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,CAQzD"}
package/dist/cli.js ADDED
@@ -0,0 +1,123 @@
1
+ // Original work by the same author.
2
+ import { existsSync } from "node:fs";
3
+ import { dirname, join, resolve } from "node:path";
4
+ import { parseArgs } from "node:util";
5
+ import { err, ok, tryCatch } from "@zedtech/zedkit-core";
6
+ import { installKit } from "./install.js";
7
+ import { readManifest } from "./kit.js";
8
+ import { checkDrift, validateKit } from "./validate.js";
9
+ const USAGE = `zedkit-ai <command>
10
+
11
+ init [dir] [--preset core|full] [--provider ...] [--dry-run]
12
+ Copy skills, subagents, commands and an AGENTS.md template into dir
13
+ (default .), then wire the providers (default all). Never overwrites
14
+ existing files (an existing AGENTS.md without the ladder gets the
15
+ ladder section appended). --provider takes cursor,claude,codex,muse,all;
16
+ --target is an alias of --provider.
17
+ validate [dir]
18
+ Check skills, subagents and commands, plus provider-copy drift
19
+ (default dir: .agents; a project root is accepted too). Exit 1
20
+ on problems.
21
+ list
22
+ Show presets, subagents and commands.
23
+ `;
24
+ const OPTIONS = {
25
+ preset: { type: "string" },
26
+ provider: { type: "string" },
27
+ target: { type: "string" },
28
+ "dry-run": { type: "boolean" },
29
+ };
30
+ function parse(args, options, maxPositionals) {
31
+ const parsed = tryCatch(() => parseArgs({ args, allowPositionals: true, options }));
32
+ if (!parsed.ok)
33
+ return err(parsed.error);
34
+ if (parsed.value.positionals.length > maxPositionals) {
35
+ return err(new Error(`unexpected argument "${parsed.value.positionals[maxPositionals]}"`));
36
+ }
37
+ return ok(parsed.value);
38
+ }
39
+ function parseProviders(value) {
40
+ if (value === undefined)
41
+ return ok(undefined);
42
+ const names = String(value).split(",").map((s) => s.trim());
43
+ if (names.includes("all"))
44
+ return ok(undefined);
45
+ const bad = names.find((n) => n !== "claude" && n !== "cursor" && n !== "codex" && n !== "muse");
46
+ if (bad !== undefined)
47
+ return err(new Error(`unknown provider "${bad}" (cursor, claude, codex, muse, all)`));
48
+ return ok(names);
49
+ }
50
+ function fail(message, sinks) {
51
+ sinks.err(`error: ${message}`);
52
+ return 2;
53
+ }
54
+ function runInit(args, sinks) {
55
+ const parsed = parse(args, OPTIONS, 1);
56
+ if (!parsed.ok)
57
+ return fail(parsed.error.message, sinks);
58
+ const { values, positionals } = parsed.value;
59
+ const providers = parseProviders(values.provider ?? values.target);
60
+ if (!providers.ok)
61
+ return fail(providers.error.message, sinks);
62
+ const dryRun = values["dry-run"] === true;
63
+ const preset = typeof values.preset === "string" ? values.preset : undefined;
64
+ const result = installKit({
65
+ dest: resolve(positionals[0] ?? "."),
66
+ ...(preset !== undefined && { preset }),
67
+ ...(providers.value !== undefined && { providers: providers.value }),
68
+ dryRun,
69
+ });
70
+ if (!result.ok)
71
+ return fail(result.error.message, sinks);
72
+ for (const action of result.value) {
73
+ sinks.out(`${action.kind.padEnd(5)} ${action.path}${action.note ? ` (${action.note})` : ""}`);
74
+ }
75
+ sinks.out(dryRun ? "dry run: nothing written" : "next: ask your agent to run the `setup-ai` skill, then `zedkit-ai validate`");
76
+ return 0;
77
+ }
78
+ function runValidate(args, sinks) {
79
+ const parsed = parse(args, {}, 1);
80
+ if (!parsed.ok)
81
+ return fail(parsed.error.message, sinks);
82
+ const dir = resolve(parsed.value.positionals[0] ?? ".agents");
83
+ if (!existsSync(dir))
84
+ return fail(`no such directory: ${dir}`, sinks);
85
+ // A project root points at its .agents/; an .agents/ dir drifts against
86
+ // its own parent. Any other dir just has nothing to drift against.
87
+ const nested = join(dir, ".agents");
88
+ const agentsDir = existsSync(nested) ? nested : dir;
89
+ const projectRoot = agentsDir === dir ? dirname(dir) : dir;
90
+ const issues = [...validateKit(agentsDir), ...checkDrift(projectRoot, agentsDir)];
91
+ for (const issue of issues)
92
+ sinks.out(`${issue.path}: ${issue.message}`);
93
+ sinks.out(issues.length === 0 ? "ok" : `${issues.length} problem(s)`);
94
+ return issues.length === 0 ? 0 : 1;
95
+ }
96
+ function runList(args, sinks) {
97
+ const parsed = parse(args, {}, 0);
98
+ if (!parsed.ok)
99
+ return fail(parsed.error.message, sinks);
100
+ const manifest = readManifest();
101
+ if (!manifest.ok)
102
+ return fail(manifest.error.message, sinks);
103
+ for (const [name, skills] of Object.entries(manifest.value.presets)) {
104
+ sinks.out(`preset ${name}: ${skills === "*" ? "every skill" : skills.join(", ")}`);
105
+ }
106
+ sinks.out(`agents: ${manifest.value.agents.join(", ")}`);
107
+ sinks.out(`commands: ${(manifest.value.commands ?? []).join(", ") || "(none)"}`);
108
+ return 0;
109
+ }
110
+ /** Run the CLI. Returns the process exit code (0 ok, 1 validation problems, 2 usage or runtime error). */
111
+ export function main(argv, sinks) {
112
+ const [command, ...rest] = argv;
113
+ if (command === "init")
114
+ return runInit(rest, sinks);
115
+ if (command === "validate")
116
+ return runValidate(rest, sinks);
117
+ if (command === "list")
118
+ return runList(rest, sinks);
119
+ const help = command === undefined || command === "--help" || command === "-h";
120
+ (help ? sinks.out : sinks.err)(USAGE.trimEnd());
121
+ return help ? 0 : 2;
122
+ }
123
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { type Result } from "@zedtech/zedkit-core";
2
+ export type Frontmatter = {
3
+ /** Parsed YAML mapping. */
4
+ data: Record<string, unknown>;
5
+ /** Frontmatter source text, without the `---` fences. */
6
+ raw: string;
7
+ };
8
+ export declare function parseFrontmatter(text: string): Result<Frontmatter>;
9
+ //# sourceMappingURL=frontmatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../src/frontmatter.ts"],"names":[],"mappings":"AACA,OAAO,EAAqB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAGtE,MAAM,MAAM,WAAW,GAAG;IACxB,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,yDAAyD;IACzD,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAKF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,CAelE"}
@@ -0,0 +1,22 @@
1
+ // Original work by the same author.
2
+ import { err, ok, tryCatch } from "@zedtech/zedkit-core";
3
+ import { parse } from "yaml";
4
+ // Optional BOM, opening fence, body (may be empty), closing fence.
5
+ const FENCE = /^\uFEFF?---[ \t]*\n(?:([\s\S]*?)\n)?---[ \t]*(?:\n|$)/;
6
+ export function parseFrontmatter(text) {
7
+ const match = FENCE.exec(text.replace(/\r\n/g, "\n"));
8
+ if (!match) {
9
+ return err(new Error("missing frontmatter (file must start with a --- block)"));
10
+ }
11
+ const raw = match[1] ?? "";
12
+ const parsed = tryCatch(() => parse(raw));
13
+ if (!parsed.ok) {
14
+ return err(new Error(`invalid YAML frontmatter: ${parsed.error.message}`));
15
+ }
16
+ const value = parsed.value ?? {};
17
+ if (typeof value !== "object" || Array.isArray(value)) {
18
+ return err(new Error("frontmatter must be a YAML mapping"));
19
+ }
20
+ return ok({ data: value, raw });
21
+ }
22
+ //# sourceMappingURL=frontmatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../src/frontmatter.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,QAAQ,EAAe,MAAM,sBAAsB,CAAC;AACtE,OAAO,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAS7B,mEAAmE;AACnE,MAAM,KAAK,GAAG,uDAAuD,CAAC;AAEtE,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;IACtD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,GAAG,CAAC,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC,CAAC;IAClF,CAAC;IACD,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3B,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC,CAAC;IACrD,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO,GAAG,CAAC,IAAI,KAAK,CAAC,6BAA6B,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC7E,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;IACjC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACtD,OAAO,GAAG,CAAC,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,KAAgC,EAAE,GAAG,EAAE,CAAC,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { type Action, type InstallOptions, type Provider, type Target, installKit } from "./install.js";
2
+ export { type Issue, checkDrift, validateKit } from "./validate.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,cAAc,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACxG,OAAO,EAAE,KAAK,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { installKit } from "./install.js";
2
+ export { checkDrift, validateKit } from "./validate.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgE,UAAU,EAAE,MAAM,cAAc,CAAC;AACxG,OAAO,EAAc,UAAU,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,36 @@
1
+ import { type Result } from "@zedtech/zedkit-core";
2
+ export type Provider = "claude" | "cursor" | "codex" | "muse";
3
+ /** @deprecated Use {@link Provider}. Kept so `--target` and old callers keep working. */
4
+ export type Target = Provider;
5
+ export type InstallOptions = {
6
+ /** Project directory to install into. */
7
+ dest: string;
8
+ /** Preset name from kit.json. Default `core`. */
9
+ preset?: string;
10
+ /** Providers to wire. Default: all. */
11
+ providers?: Provider[];
12
+ /** @deprecated Use `providers`. */
13
+ targets?: Target[];
14
+ /** Report what would happen without touching the disk. */
15
+ dryRun?: boolean;
16
+ /** Custom kit directory (default: the bundled kit). */
17
+ kit?: string;
18
+ };
19
+ export type Action = {
20
+ kind: "copy" | "link" | "write" | "append" | "skip";
21
+ path: string;
22
+ /** Why it was skipped, what was appended, or what a link points to. */
23
+ note?: string;
24
+ };
25
+ /**
26
+ * Install the kit into a project. The shared source (skills, subagents,
27
+ * commands, AGENTS.md) is copied into `.agents/` (the project owns it from
28
+ * then on); each chosen provider then gets its thin layer, links where the
29
+ * provider follows them, real files where it does not. Existing files are
30
+ * never overwritten: they are reported as skipped, except an existing
31
+ * AGENTS.md missing the ladder, which gets the ladder section appended
32
+ * (reported as `append`). A bad preset or kit fails before anything is
33
+ * written.
34
+ */
35
+ export declare function installKit(options: InstallOptions): Result<Action[]>;
36
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAeA,OAAO,EAAqB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAItE,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;AAE9D,yFAAyF;AACzF,MAAM,MAAM,MAAM,GAAG,QAAQ,CAAC;AAE9B,MAAM,MAAM,cAAc,GAAG;IAC3B,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,mCAAmC;IACnC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,uDAAuD;IACvD,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IACnB,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AA0NF;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAapE"}
@@ -0,0 +1,242 @@
1
+ // Original work by the same author.
2
+ import { copyFileSync, cpSync, existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, readlinkSync, statSync, symlinkSync, writeFileSync, } from "node:fs";
3
+ import { dirname, join, sep } from "node:path";
4
+ import { err, ok, tryCatch } from "@zedtech/zedkit-core";
5
+ import { parseFrontmatter } from "./frontmatter.js";
6
+ import { kitDir, readManifest } from "./kit.js";
7
+ const ALL_PROVIDERS = ["claude", "cursor", "codex", "muse"];
8
+ const CURSOR_RULE = `---
9
+ description: Project rules
10
+ alwaysApply: true
11
+ ---
12
+
13
+ Read and follow /AGENTS.md at the repo root, and use the skills in .agents/skills.
14
+ `;
15
+ function lstatOf(path) {
16
+ const stat = tryCatch(() => lstatSync(path));
17
+ return stat.ok ? stat.value : undefined;
18
+ }
19
+ function isDirectory(path) {
20
+ const stat = tryCatch(() => statSync(path));
21
+ return stat.ok && stat.value.isDirectory();
22
+ }
23
+ // Why `rel` cannot be created, or undefined when the way is free. The path
24
+ // itself is taken if anything (even a dangling symlink) is there; a parent
25
+ // that is not a directory would make the write fail halfway.
26
+ function obstacle(ctx, rel) {
27
+ const parts = rel.split(sep);
28
+ for (let i = 1; i < parts.length; i++) {
29
+ const parent = join(ctx.dest, ...parts.slice(0, i));
30
+ if (lstatOf(parent) && !isDirectory(parent)) {
31
+ return `${parts.slice(0, i).join(sep)} is not a directory`;
32
+ }
33
+ }
34
+ return lstatOf(join(ctx.dest, rel)) ? "already exists, left untouched" : undefined;
35
+ }
36
+ function place(ctx, kind, rel, make, note) {
37
+ const blocked = obstacle(ctx, rel);
38
+ if (blocked) {
39
+ const current = tryCatch(() => readlinkSync(join(ctx.dest, rel)));
40
+ const same = kind === "link" && current.ok && current.value === note;
41
+ ctx.actions.push({ kind: "skip", path: rel, note: same ? "already linked" : blocked });
42
+ return;
43
+ }
44
+ ctx.actions.push({ kind, path: rel, ...(note !== undefined && { note }) });
45
+ if (ctx.dryRun)
46
+ return;
47
+ mkdirSync(dirname(join(ctx.dest, rel)), { recursive: true });
48
+ make();
49
+ }
50
+ function copyFile(ctx, from, rel) {
51
+ place(ctx, "copy", rel, () => copyFileSync(from, join(ctx.dest, rel)));
52
+ }
53
+ function link(ctx, rel, target) {
54
+ place(ctx, "link", rel, () => symlinkSync(target, join(ctx.dest, rel)), target);
55
+ }
56
+ function skillNames(manifest, kit, preset) {
57
+ const entry = Object.hasOwn(manifest.presets, preset) ? manifest.presets[preset] : undefined;
58
+ if (entry === undefined) {
59
+ throw new Error(`unknown preset "${preset}" (have: ${Object.keys(manifest.presets).join(", ")})`);
60
+ }
61
+ if (entry !== "*")
62
+ return entry;
63
+ return readdirSync(join(kit, "skills"), { withFileTypes: true })
64
+ .filter((e) => e.isDirectory())
65
+ .map((e) => e.name);
66
+ }
67
+ // Resolve everything the install needs from the kit before the first write,
68
+ // so a bad preset or manifest never leaves a half install behind.
69
+ function plan(kit, manifest, preset) {
70
+ const skills = skillNames(manifest, kit, preset);
71
+ for (const name of skills) {
72
+ if (!existsSync(join(kit, "skills", name, "SKILL.md")))
73
+ throw new Error(`kit has no skill "${name}"`);
74
+ }
75
+ for (const name of manifest.agents) {
76
+ if (!existsSync(join(kit, "agents", `${name}.md`)))
77
+ throw new Error(`kit has no agent "${name}"`);
78
+ }
79
+ const commands = manifest.commands ?? [];
80
+ for (const name of commands) {
81
+ if (!existsSync(join(kit, "commands", `${name}.md`)))
82
+ throw new Error(`kit has no command "${name}"`);
83
+ }
84
+ const licences = readdirSync(join(kit, "skills")).filter((f) => f.startsWith("LICENSE-"));
85
+ return { skills, licences, agents: manifest.agents, commands };
86
+ }
87
+ // The ladder section every AGENTS.md must carry, lifted from the bundled
88
+ // template so the wording has a single home. Undefined when the kit has
89
+ // no template or no ladder section (foreign kits keep working).
90
+ function ladderSection(kit) {
91
+ const template = tryCatch(() => readFileSync(join(kit, "AGENTS.template.md"), "utf8"));
92
+ if (!template.ok)
93
+ return undefined;
94
+ const start = template.value.indexOf("## Before writing any code");
95
+ if (start < 0)
96
+ return undefined;
97
+ const rest = template.value.slice(start);
98
+ const next = rest.indexOf("\n## ", 1);
99
+ return `${(next < 0 ? rest : rest.slice(0, next)).trimEnd()}\n`;
100
+ }
101
+ // Fresh projects get the whole template; an existing AGENTS.md is never
102
+ // overwritten, but when it lacks the ladder the section is appended (and
103
+ // reported as `append`, so dry runs agree with real ones).
104
+ function installAgentsMd(ctx) {
105
+ const blocked = obstacle(ctx, "AGENTS.md");
106
+ if (blocked === undefined) {
107
+ copyFile(ctx, join(ctx.kit, "AGENTS.template.md"), "AGENTS.md");
108
+ return;
109
+ }
110
+ const current = tryCatch(() => readFileSync(join(ctx.dest, "AGENTS.md"), "utf8"));
111
+ if (!current.ok || current.value.toLowerCase().includes("ladder")) {
112
+ ctx.actions.push({ kind: "skip", path: "AGENTS.md", note: blocked });
113
+ return;
114
+ }
115
+ const section = ladderSection(ctx.kit);
116
+ if (section === undefined) {
117
+ ctx.actions.push({ kind: "skip", path: "AGENTS.md", note: blocked });
118
+ return;
119
+ }
120
+ ctx.actions.push({ kind: "append", path: "AGENTS.md", note: "ladder section" });
121
+ if (ctx.dryRun)
122
+ return;
123
+ const gap = current.value === "" ? "" : current.value.endsWith("\n") ? "\n" : "\n\n";
124
+ writeFileSync(join(ctx.dest, "AGENTS.md"), `${current.value}${gap}${section}`);
125
+ }
126
+ function installContent(ctx, content) {
127
+ for (const name of content.skills) {
128
+ const rel = join(".agents", "skills", name);
129
+ // dereference: a symlink inside a skill must not be copied as a dangling one
130
+ place(ctx, "copy", rel, () => cpSync(join(ctx.kit, "skills", name), join(ctx.dest, rel), { recursive: true, dereference: true }));
131
+ }
132
+ // Licence texts of vendored skills travel with them.
133
+ for (const file of content.licences) {
134
+ copyFile(ctx, join(ctx.kit, "skills", file), join(".agents", "skills", file));
135
+ }
136
+ copyFile(ctx, join(ctx.kit, "THIRD_PARTY_NOTICES.md"), join(".agents", "THIRD_PARTY_NOTICES.md"));
137
+ // Project personas for persona-review; an existing file is left untouched.
138
+ if (existsSync(join(ctx.kit, "personas.template.md"))) {
139
+ copyFile(ctx, join(ctx.kit, "personas.template.md"), join(".agents", "personas.md"));
140
+ }
141
+ for (const name of content.agents) {
142
+ copyFile(ctx, join(ctx.kit, "agents", `${name}.md`), join(".agents", "agents", `${name}.md`));
143
+ }
144
+ for (const name of content.commands) {
145
+ copyFile(ctx, join(ctx.kit, "commands", `${name}.md`), join(".agents", "commands", `${name}.md`));
146
+ }
147
+ installAgentsMd(ctx);
148
+ }
149
+ function agentsMdReady(ctx) {
150
+ if (ctx.actions.some((a) => a.kind === "copy" && a.path === "AGENTS.md"))
151
+ return true;
152
+ const stat = tryCatch(() => statSync(join(ctx.dest, "AGENTS.md")));
153
+ return stat.ok && stat.value.isFile();
154
+ }
155
+ // Name of another rule in .cursor/rules/ that is already always on, if any.
156
+ // A second always-on rule would only duplicate (or fight) it, so the
157
+ // installer skips project.mdc then. Reads the disk only, so dry runs agree.
158
+ function existingAlwaysOnRule(ctx) {
159
+ const dir = join(ctx.dest, ".cursor", "rules");
160
+ const entries = tryCatch(() => readdirSync(dir, { withFileTypes: true }));
161
+ if (!entries.ok)
162
+ return undefined;
163
+ for (const entry of entries.value) {
164
+ if (!entry.isFile() || !entry.name.endsWith(".mdc") || entry.name === "project.mdc")
165
+ continue;
166
+ const read = tryCatch(() => readFileSync(join(dir, entry.name), "utf8"));
167
+ if (!read.ok)
168
+ continue;
169
+ const front = parseFrontmatter(read.value);
170
+ if (front.ok && front.value.data.alwaysApply === true)
171
+ return entry.name;
172
+ }
173
+ return undefined;
174
+ }
175
+ function writeCursorRule(ctx) {
176
+ const rel = join(".cursor", "rules", "project.mdc");
177
+ if (obstacle(ctx, rel) === undefined) {
178
+ const existing = existingAlwaysOnRule(ctx);
179
+ if (existing !== undefined) {
180
+ ctx.actions.push({ kind: "skip", path: rel, note: `always-on rule ${existing} already exists` });
181
+ return;
182
+ }
183
+ }
184
+ place(ctx, "write", rel, () => writeFileSync(join(ctx.dest, rel), CURSOR_RULE));
185
+ }
186
+ function wireClaude(ctx) {
187
+ link(ctx, join(".claude", "skills"), "../.agents/skills");
188
+ link(ctx, join(".claude", "agents"), "../.agents/agents");
189
+ link(ctx, join(".claude", "commands"), "../.agents/commands");
190
+ // Only when AGENTS.md is (or will be) a real file: never a dangling link.
191
+ if (agentsMdReady(ctx))
192
+ link(ctx, "CLAUDE.md", "AGENTS.md");
193
+ else
194
+ ctx.actions.push({ kind: "skip", path: "CLAUDE.md", note: "AGENTS.md is not a file" });
195
+ }
196
+ function wireCursor(ctx, content) {
197
+ link(ctx, join(".cursor", "skills"), "../.agents/skills");
198
+ // Real files, not links: a symlinked folder shows up empty here, so the
199
+ // copies are authoritative for Cursor. They can drift from .agents/;
200
+ // checkDrift reports that, and init never overwrites them.
201
+ for (const name of content.agents) {
202
+ copyFile(ctx, join(ctx.kit, "agents", `${name}.md`), join(".cursor", "agents", `${name}.md`));
203
+ }
204
+ for (const name of content.commands) {
205
+ copyFile(ctx, join(ctx.kit, "commands", `${name}.md`), join(".cursor", "commands", `${name}.md`));
206
+ }
207
+ writeCursorRule(ctx);
208
+ }
209
+ function wireProvider(ctx, provider, content) {
210
+ if (provider === "claude")
211
+ wireClaude(ctx);
212
+ else if (provider === "cursor")
213
+ wireCursor(ctx, content);
214
+ // codex and muse read the shared source directly (AGENTS.md plus
215
+ // .agents/): no per-provider layer to generate.
216
+ }
217
+ /**
218
+ * Install the kit into a project. The shared source (skills, subagents,
219
+ * commands, AGENTS.md) is copied into `.agents/` (the project owns it from
220
+ * then on); each chosen provider then gets its thin layer, links where the
221
+ * provider follows them, real files where it does not. Existing files are
222
+ * never overwritten: they are reported as skipped, except an existing
223
+ * AGENTS.md missing the ladder, which gets the ladder section appended
224
+ * (reported as `append`). A bad preset or kit fails before anything is
225
+ * written.
226
+ */
227
+ export function installKit(options) {
228
+ const kit = options.kit ?? kitDir();
229
+ const manifest = readManifest(kit);
230
+ if (!manifest.ok)
231
+ return err(manifest.error);
232
+ const ctx = { dest: options.dest, kit, dryRun: options.dryRun ?? false, actions: [] };
233
+ const run = tryCatch(() => {
234
+ const content = plan(kit, manifest.value, options.preset ?? "core");
235
+ installContent(ctx, content);
236
+ for (const provider of options.providers ?? options.targets ?? ALL_PROVIDERS) {
237
+ wireProvider(ctx, provider, content);
238
+ }
239
+ });
240
+ return run.ok ? ok(ctx.actions) : err(run.error);
241
+ }
242
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"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"}
package/dist/kit.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ import { type Result } from "@zedtech/zedkit-core";
2
+ export type KitManifest = {
3
+ /** Preset name -> skill names, or "*" for every skill in the kit. */
4
+ presets: Record<string, string[] | "*">;
5
+ /** Subagent names (files in `agents/`). */
6
+ agents: string[];
7
+ /** Command names (files in `commands/`). Absent means none. */
8
+ commands?: string[];
9
+ };
10
+ /** Absolute path of the bundled kit (same relative spot from `src/` and `dist/`). */
11
+ export declare function kitDir(): string;
12
+ export declare function readManifest(dir?: string): Result<KitManifest>;
13
+ //# sourceMappingURL=kit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kit.d.ts","sourceRoot":"","sources":["../src/kit.ts"],"names":[],"mappings":"AAGA,OAAO,EAAqB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEtE,MAAM,MAAM,WAAW,GAAG;IACxB,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC;IACxC,2CAA2C;IAC3C,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB,CAAC;AAEF,qFAAqF;AACrF,wBAAgB,MAAM,IAAI,MAAM,CAE/B;AAMD,wBAAgB,YAAY,CAAC,GAAG,GAAE,MAAiB,GAAG,MAAM,CAAC,WAAW,CAAC,CAuBxE"}
package/dist/kit.js ADDED
@@ -0,0 +1,36 @@
1
+ // Original work by the same author.
2
+ import { readFileSync } from "node:fs";
3
+ import { fileURLToPath } from "node:url";
4
+ import { err, ok, tryCatch } from "@zedtech/zedkit-core";
5
+ /** Absolute path of the bundled kit (same relative spot from `src/` and `dist/`). */
6
+ export function kitDir() {
7
+ return fileURLToPath(new URL("../kit/", import.meta.url));
8
+ }
9
+ function isStringList(value) {
10
+ return Array.isArray(value) && value.every((item) => typeof item === "string");
11
+ }
12
+ export function readManifest(dir = kitDir()) {
13
+ const read = tryCatch(() => JSON.parse(readFileSync(`${dir}/kit.json`, "utf8")));
14
+ if (!read.ok) {
15
+ return err(new Error(`cannot read kit.json in ${dir}: ${read.error.message}`));
16
+ }
17
+ const data = read.value;
18
+ const presets = data?.presets;
19
+ if (!presets || typeof presets !== "object" || !isStringList(data?.agents)) {
20
+ return err(new Error("kit.json needs `presets` (object) and `agents` (string list)"));
21
+ }
22
+ if (data.commands !== undefined && !isStringList(data.commands)) {
23
+ return err(new Error("kit.json `commands` must be a string list"));
24
+ }
25
+ for (const [name, value] of Object.entries(presets)) {
26
+ if (value !== "*" && !isStringList(value)) {
27
+ return err(new Error(`kit.json preset "${name}" must be a string list or "*"`));
28
+ }
29
+ }
30
+ return ok({
31
+ presets: presets,
32
+ agents: data.agents,
33
+ ...(data.commands !== undefined && { commands: data.commands }),
34
+ });
35
+ }
36
+ //# sourceMappingURL=kit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kit.js","sourceRoot":"","sources":["../src/kit.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,QAAQ,EAAe,MAAM,sBAAsB,CAAC;AAWtE,qFAAqF;AACrF,MAAM,UAAU,MAAM;IACpB,OAAO,aAAa,CAAC,IAAI,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,SAAS,YAAY,CAAC,KAAc;IAClC,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAc,MAAM,EAAE;IACjD,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,GAAG,WAAW,EAAE,MAAM,CAAC,CAAY,CAAC,CAAC;IAC5F,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QACb,OAAO,GAAG,CAAC,IAAI,KAAK,CAAC,2BAA2B,GAAG,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACjF,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAA2F,CAAC;IAC9G,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,CAAC;IAC9B,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;QAC3E,OAAO,GAAG,CAAC,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC,CAAC;IACxF,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAChE,OAAO,GAAG,CAAC,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC,CAAC;IACrE,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACpD,IAAI,KAAK,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1C,OAAO,GAAG,CAAC,IAAI,KAAK,CAAC,oBAAoB,IAAI,gCAAgC,CAAC,CAAC,CAAC;QAClF,CAAC;IACH,CAAC;IACD,OAAO,EAAE,CAAC;QACR,OAAO,EAAE,OAAiC;QAC1C,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,GAAG,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAoB,EAAE,CAAC;KAC5E,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,22 @@
1
+ export type Issue = {
2
+ path: string;
3
+ message: string;
4
+ };
5
+ /**
6
+ * Check a directory laid out as `skills/<name>/SKILL.md`, `agents/<name>.md`,
7
+ * `commands/<name>.md` and optionally `kit.json`. Returns every problem
8
+ * found; empty means valid. An unreadable entry (dangling symlink,
9
+ * permissions) is reported as a problem instead of throwing.
10
+ */
11
+ export declare function validateKit(root: string): Issue[];
12
+ /**
13
+ * Compare the provider copies (`.cursor/agents`, `.cursor/commands`) against
14
+ * the shared `source` (usually the project's `.agents/`). Copies are real
15
+ * files because that provider does not follow a symlinked folder here; when
16
+ * the source changes they go stale, and init never overwrites them. Reports
17
+ * each missing or drifted copy. Links and missing folders cannot drift and
18
+ * are skipped silently, as are extra files on the provider side (the user's
19
+ * own). Paths are relative to `projectRoot`.
20
+ */
21
+ export declare function checkDrift(projectRoot: string, source: string): Issue[];
22
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,KAAK,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAoMtD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,EAAE,CAMjD;AAOD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK,EAAE,CAoBvE"}
@@ -0,0 +1,240 @@
1
+ // Original work by the same author.
2
+ import { existsSync, lstatSync, readdirSync, readFileSync, statSync } from "node:fs";
3
+ import { join, relative } from "node:path";
4
+ import { tryCatch } from "@zedtech/zedkit-core";
5
+ import { readManifest } from "./kit.js";
6
+ import { parseFrontmatter } from "./frontmatter.js";
7
+ const NAME = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
8
+ const MAX_NAME = 64;
9
+ const MAX_DESCRIPTION = 1024;
10
+ function read(path) {
11
+ return readFileSync(path, "utf8");
12
+ }
13
+ function dirsIn(path) {
14
+ if (!existsSync(path))
15
+ return [];
16
+ return readdirSync(path).filter((entry) => statSync(join(path, entry)).isDirectory());
17
+ }
18
+ function checkName(name, expected, path, issues) {
19
+ if (name !== expected) {
20
+ issues.push({ path, message: `name must equal "${expected}" (got ${JSON.stringify(name)})` });
21
+ }
22
+ if (!NAME.test(expected) || expected.length > MAX_NAME) {
23
+ issues.push({ path, message: `name must be lowercase-hyphen, at most ${MAX_NAME} characters` });
24
+ }
25
+ }
26
+ // True when `description:` is a plain or quoted scalar that fits on one line.
27
+ // A block scalar (`>`, `|`) can be shown literally in an agent list, and a
28
+ // continuation line is just as invisible to simple parsers.
29
+ function isSingleLineDescription(raw) {
30
+ const lines = raw.split("\n");
31
+ const at = lines.findIndex((line) => /^description:/.test(line));
32
+ if (at < 0)
33
+ return true;
34
+ const value = (lines[at] ?? "").slice("description:".length).trim();
35
+ const next = lines[at + 1];
36
+ return value !== "" && !/^[>|]/.test(value) && !(next !== undefined && /^[ \t]+\S/.test(next));
37
+ }
38
+ function checkDescription(value, path, issues) {
39
+ if (typeof value !== "string" || value.trim() === "") {
40
+ issues.push({ path, message: "description is required and must be a non-empty string" });
41
+ }
42
+ else if (value.length > MAX_DESCRIPTION) {
43
+ issues.push({ path, message: `description is ${value.length} characters (max ${MAX_DESCRIPTION})` });
44
+ }
45
+ }
46
+ function checkSkill(root, name, issues) {
47
+ const file = join(root, "skills", name, "SKILL.md");
48
+ const path = relative(root, file);
49
+ if (!existsSync(file)) {
50
+ issues.push({ path: relative(root, join(root, "skills", name)), message: "skill folder has no SKILL.md" });
51
+ return;
52
+ }
53
+ const parsed = parseFrontmatter(read(file));
54
+ if (!parsed.ok) {
55
+ issues.push({ path, message: parsed.error.message });
56
+ return;
57
+ }
58
+ checkName(parsed.value.data.name, name, path, issues);
59
+ checkDescription(parsed.value.data.description, path, issues);
60
+ }
61
+ function checkAgent(root, file, issues) {
62
+ const path = join("agents", file);
63
+ const parsed = parseFrontmatter(read(join(root, path)));
64
+ if (!parsed.ok) {
65
+ issues.push({ path, message: parsed.error.message });
66
+ return;
67
+ }
68
+ const { data, raw } = parsed.value;
69
+ checkName(data.name, file.replace(/\.md$/, ""), path, issues);
70
+ checkDescription(data.description, path, issues);
71
+ if (!isSingleLineDescription(raw)) {
72
+ issues.push({ path, message: "description must be a single line (no `>` or `|` block, no continuation lines)" });
73
+ }
74
+ // An id the tool does not know falls back silently, and the kit is
75
+ // tool-agnostic: only `inherit` is portable.
76
+ if (data.model !== undefined && data.model !== "inherit") {
77
+ issues.push({ path, message: 'model must be omitted or "inherit" (pin a model in your project, after listing what your tool accepts)' });
78
+ }
79
+ // `readonly` is a single-tool field, and at least one tool drops the
80
+ // whole definition when it sees an unknown key. Read-only stays in the
81
+ // prompt body plus `disallowedTools`, which every tool tolerates.
82
+ if (data.readonly !== undefined) {
83
+ issues.push({ path, message: "readonly is not portable: some tools skip agent files that set it (use disallowedTools instead)" });
84
+ }
85
+ }
86
+ function checkCommand(root, file, skills, issues) {
87
+ const path = join("commands", file);
88
+ const base = file.replace(/\.md$/, "");
89
+ if (!NAME.test(base) || base.length > MAX_NAME) {
90
+ issues.push({ path, message: `name must be lowercase-hyphen, at most ${MAX_NAME} characters` });
91
+ }
92
+ const text = read(join(root, path));
93
+ const parsed = parseFrontmatter(text);
94
+ if (!parsed.ok) {
95
+ issues.push({ path, message: parsed.error.message });
96
+ return;
97
+ }
98
+ checkDescription(parsed.value.data.description, path, issues);
99
+ if (!isSingleLineDescription(parsed.value.raw)) {
100
+ issues.push({ path, message: "description must be a single line (no `>` or `|` block, no continuation lines)" });
101
+ }
102
+ // A command runs a skill by name: it must name at least one installed one.
103
+ const names = [...skills].filter((name) => text.includes(`\`${name}\``));
104
+ if (names.length === 0) {
105
+ issues.push({ path, message: "names no installed skill (a command runs a `skill` by name)" });
106
+ }
107
+ }
108
+ function checkLineEndings(root, issues) {
109
+ const entries = readdirSync(root, { recursive: true, encoding: "utf8" });
110
+ for (const entry of entries) {
111
+ const full = join(root, entry);
112
+ if (entry.endsWith(".md") && statSync(full).isFile() && read(full).includes("\r")) {
113
+ issues.push({ path: entry, message: "CR found: use LF line endings" });
114
+ }
115
+ }
116
+ }
117
+ const LADDER_SKILLS = ["plan", "implement", "review", "ponytail-review"];
118
+ // The ponytail ladder must survive in the skills that ask it and in the
119
+ // template every setup inherits. Only checked where the file exists, so
120
+ // minimal or foreign layouts are unaffected.
121
+ function checkLadder(root, issues) {
122
+ for (const name of LADDER_SKILLS) {
123
+ const file = join(root, "skills", name, "SKILL.md");
124
+ if (existsSync(file) && !read(file).toLowerCase().includes("ladder")) {
125
+ issues.push({
126
+ path: relative(root, file),
127
+ message: "must state the ponytail ladder (regression: the 7 questions vanished)",
128
+ });
129
+ }
130
+ }
131
+ const template = join(root, "AGENTS.template.md");
132
+ if (existsSync(template) && !read(template).toLowerCase().includes("ladder")) {
133
+ issues.push({
134
+ path: "AGENTS.template.md",
135
+ message: "must state the ponytail ladder (every setup inherits this file)",
136
+ });
137
+ }
138
+ }
139
+ function checkManifest(root, issues) {
140
+ if (!existsSync(join(root, "kit.json")))
141
+ return;
142
+ const manifest = readManifest(root);
143
+ if (!manifest.ok) {
144
+ issues.push({ path: "kit.json", message: manifest.error.message });
145
+ return;
146
+ }
147
+ const skills = new Set(dirsIn(join(root, "skills")));
148
+ const agents = new Set(existsSync(join(root, "agents"))
149
+ ? readdirSync(join(root, "agents")).map((f) => f.replace(/\.md$/, ""))
150
+ : []);
151
+ for (const [preset, names] of Object.entries(manifest.value.presets)) {
152
+ for (const name of names === "*" ? [] : names) {
153
+ if (!skills.has(name))
154
+ issues.push({ path: "kit.json", message: `preset "${preset}" lists missing skill "${name}"` });
155
+ }
156
+ }
157
+ for (const name of manifest.value.agents) {
158
+ if (!agents.has(name))
159
+ issues.push({ path: "kit.json", message: `lists missing agent "${name}"` });
160
+ }
161
+ const commands = new Set(existsSync(join(root, "commands"))
162
+ ? readdirSync(join(root, "commands")).map((f) => f.replace(/\.md$/, ""))
163
+ : []);
164
+ for (const name of manifest.value.commands ?? []) {
165
+ if (!commands.has(name))
166
+ issues.push({ path: "kit.json", message: `lists missing command "${name}"` });
167
+ }
168
+ }
169
+ function collect(root) {
170
+ const issues = [];
171
+ const skills = new Set(dirsIn(join(root, "skills")));
172
+ for (const name of skills)
173
+ checkSkill(root, name, issues);
174
+ const agentsDir = join(root, "agents");
175
+ if (existsSync(agentsDir)) {
176
+ for (const file of readdirSync(agentsDir).filter((f) => f.endsWith(".md"))) {
177
+ checkAgent(root, file, issues);
178
+ }
179
+ }
180
+ const commandsDir = join(root, "commands");
181
+ if (existsSync(commandsDir)) {
182
+ for (const file of readdirSync(commandsDir).filter((f) => f.endsWith(".md"))) {
183
+ checkCommand(root, file, skills, issues);
184
+ }
185
+ }
186
+ checkManifest(root, issues);
187
+ checkLadder(root, issues);
188
+ checkLineEndings(root, issues);
189
+ return issues;
190
+ }
191
+ /**
192
+ * Check a directory laid out as `skills/<name>/SKILL.md`, `agents/<name>.md`,
193
+ * `commands/<name>.md` and optionally `kit.json`. Returns every problem
194
+ * found; empty means valid. An unreadable entry (dangling symlink,
195
+ * permissions) is reported as a problem instead of throwing.
196
+ */
197
+ export function validateKit(root) {
198
+ if (!existsSync(root)) {
199
+ return [{ path: root, message: "directory does not exist" }];
200
+ }
201
+ const result = tryCatch(() => collect(root));
202
+ return result.ok ? result.value : [{ path: root, message: `cannot read: ${result.error.message}` }];
203
+ }
204
+ function isRealDir(path) {
205
+ const stat = tryCatch(() => lstatSync(path));
206
+ return stat.ok && stat.value.isDirectory();
207
+ }
208
+ /**
209
+ * Compare the provider copies (`.cursor/agents`, `.cursor/commands`) against
210
+ * the shared `source` (usually the project's `.agents/`). Copies are real
211
+ * files because that provider does not follow a symlinked folder here; when
212
+ * the source changes they go stale, and init never overwrites them. Reports
213
+ * each missing or drifted copy. Links and missing folders cannot drift and
214
+ * are skipped silently, as are extra files on the provider side (the user's
215
+ * own). Paths are relative to `projectRoot`.
216
+ */
217
+ export function checkDrift(projectRoot, source) {
218
+ const run = tryCatch(() => {
219
+ const issues = [];
220
+ for (const kind of ["agents", "commands"]) {
221
+ const from = join(source, kind);
222
+ const to = join(projectRoot, ".cursor", kind);
223
+ if (!isRealDir(from) || !isRealDir(to))
224
+ continue;
225
+ for (const file of readdirSync(from).filter((f) => f.endsWith(".md"))) {
226
+ const target = join(to, file);
227
+ const want = relative(projectRoot, join(from, file));
228
+ if (!existsSync(target)) {
229
+ issues.push({ path: relative(projectRoot, target), message: `copy missing: copy it from ${want} or re-run init` });
230
+ }
231
+ else if (read(target) !== read(join(from, file))) {
232
+ issues.push({ path: relative(projectRoot, target), message: `drifted from ${want}: copy it over (init never overwrites)` });
233
+ }
234
+ }
235
+ }
236
+ return issues;
237
+ });
238
+ return run.ok ? run.value : [{ path: projectRoot, message: `cannot check drift: ${run.error.message}` }];
239
+ }
240
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACrF,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAIpD,MAAM,IAAI,GAAG,4BAA4B,CAAC;AAC1C,MAAM,QAAQ,GAAG,EAAE,CAAC;AACpB,MAAM,eAAe,GAAG,IAAI,CAAC;AAE7B,SAAS,IAAI,CAAC,IAAY;IACxB,OAAO,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,MAAM,CAAC,IAAY;IAC1B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;AACxF,CAAC;AAED,SAAS,SAAS,CAAC,IAAa,EAAE,QAAgB,EAAE,IAAY,EAAE,MAAe;IAC/E,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,oBAAoB,QAAQ,UAAU,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAChG,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,MAAM,GAAG,QAAQ,EAAE,CAAC;QACvD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,0CAA0C,QAAQ,aAAa,EAAE,CAAC,CAAC;IAClG,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,2EAA2E;AAC3E,4DAA4D;AAC5D,SAAS,uBAAuB,CAAC,GAAW;IAC1C,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACjE,IAAI,EAAE,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACxB,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IACpE,MAAM,IAAI,GAAG,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAC3B,OAAO,KAAK,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AACjG,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc,EAAE,IAAY,EAAE,MAAe;IACrE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,wDAAwD,EAAE,CAAC,CAAC;IAC3F,CAAC;SAAM,IAAI,KAAK,CAAC,MAAM,GAAG,eAAe,EAAE,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,kBAAkB,KAAK,CAAC,MAAM,oBAAoB,eAAe,GAAG,EAAE,CAAC,CAAC;IACvG,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,IAAY,EAAE,IAAY,EAAE,MAAe;IAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAClC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,8BAA8B,EAAE,CAAC,CAAC;QAC3G,OAAO;IACT,CAAC;IACD,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACrD,OAAO;IACT,CAAC;IACD,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACtD,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,UAAU,CAAC,IAAY,EAAE,IAAY,EAAE,MAAe;IAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAClC,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IACxD,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACrD,OAAO;IACT,CAAC;IACD,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC;IACnC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAC9D,gBAAgB,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACjD,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,gFAAgF,EAAE,CAAC,CAAC;IACnH,CAAC;IACD,mEAAmE;IACnE,6CAA6C;IAC7C,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QACzD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,wGAAwG,EAAE,CAAC,CAAC;IAC3I,CAAC;IACD,qEAAqE;IACrE,uEAAuE;IACvE,kEAAkE;IAClE,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,iGAAiG,EAAE,CAAC,CAAC;IACpI,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,IAAY,EAAE,IAAY,EAAE,MAAmB,EAAE,MAAe;IACpF,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACvC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,QAAQ,EAAE,CAAC;QAC/C,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,0CAA0C,QAAQ,aAAa,EAAE,CAAC,CAAC;IAClG,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACrD,OAAO;IACT,CAAC;IACD,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAC9D,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,gFAAgF,EAAE,CAAC,CAAC;IACnH,CAAC;IACD,2EAA2E;IAC3E,MAAM,KAAK,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC;IACzE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,6DAA6D,EAAE,CAAC,CAAC;IAChG,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAY,EAAE,MAAe;IACrD,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IACzE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC/B,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAClF,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,+BAA+B,EAAE,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,iBAAiB,CAAC,CAAC;AAEzE,wEAAwE;AACxE,wEAAwE;AACxE,6CAA6C;AAC7C,SAAS,WAAW,CAAC,IAAY,EAAE,MAAe;IAChD,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;QACpD,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACrE,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;gBAC1B,OAAO,EAAE,uEAAuE;aACjF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC;IAClD,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7E,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,oBAAoB;YAC1B,OAAO,EAAE,iEAAiE;SAC3E,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,IAAY,EAAE,MAAe;IAClD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAAE,OAAO;IAChD,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACnE,OAAO;IACT,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,IAAI,GAAG,CACpB,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC9B,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACtE,CAAC,CAAC,EAAE,CACP,CAAC;IACF,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACrE,KAAK,MAAM,IAAI,IAAI,KAAK,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;YAC9C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,MAAM,0BAA0B,IAAI,GAAG,EAAE,CAAC,CAAC;QACxH,CAAC;IACH,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QACzC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,wBAAwB,IAAI,GAAG,EAAE,CAAC,CAAC;IACrG,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,GAAG,CACtB,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAChC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACxE,CAAC,CAAC,EAAE,CACP,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;QACjD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,0BAA0B,IAAI,GAAG,EAAE,CAAC,CAAC;IACzG,CAAC;AACH,CAAC;AAED,SAAS,OAAO,CAAC,IAAY;IAC3B,MAAM,MAAM,GAAY,EAAE,CAAC;IAC3B,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IACrD,KAAK,MAAM,IAAI,IAAI,MAAM;QAAE,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAC1D,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACvC,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1B,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YAC3E,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IACD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAC3C,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5B,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YAC7E,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IACD,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC5B,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC1B,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC/B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,0BAA0B,EAAE,CAAC,CAAC;IAC/D,CAAC;IACD,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7C,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,gBAAgB,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AACtG,CAAC;AAED,SAAS,SAAS,CAAC,IAAY;IAC7B,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7C,OAAO,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;AAC7C,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAC,WAAmB,EAAE,MAAc;IAC5D,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE;QACxB,MAAM,MAAM,GAAY,EAAE,CAAC;QAC3B,KAAK,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,CAAC;YAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAChC,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;YAC9C,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;gBAAE,SAAS;YACjD,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;gBACtE,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;gBAC9B,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;gBACrD,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;oBACxB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,8BAA8B,IAAI,iBAAiB,EAAE,CAAC,CAAC;gBACrH,CAAC;qBAAM,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;oBACnD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,gBAAgB,IAAI,wCAAwC,EAAE,CAAC,CAAC;gBAC9H,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,uBAAuB,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAC3G,CAAC"}
@@ -1,50 +1,10 @@
1
1
  ---
2
2
  name: plan-challenger
3
- description: "Pre-mortem for a plan, run before any code is written: is each part needed, is each claim verified, what fails in production. Use after the architect's plan or on any non-trivial design. Reports ranked objections; never writes code."
3
+ description: "Deprecated alias of the skeptic agent (angle: plan). Kept for one release so existing briefs keep working; new briefs must name skeptic with an angle."
4
4
  model: inherit
5
5
  disallowedTools: Write, Edit, NotebookEdit
6
6
  ---
7
7
 
8
- You are the skeptic in the room. Your job is to find what is wrong with a plan while it is still cheap to change. You do not write code and you do not redesign: you object, with evidence, and name the simpler alternative.
9
-
10
- If you are given a loose idea instead of a plan, first state it as a plan (what changes, where) so there is something concrete to attack.
11
-
12
- ## Three questions for every part of the plan
13
-
14
- Search the repository before claiming something is missing or duplicated. Cite `file:line`.
15
-
16
- 1. **Is it needed?** Could the requirement be met by something that already exists, by an extra argument on an existing function, or by deleting code? Is any file, option, interface or dependency there for a future nobody asked for?
17
- 2. **Is it true?** Every shape, contract, path and behavior the plan assumes: did the author read it in source? List each assumption as VERIFIED (you opened it) or UNVERIFIED. An UNVERIFIED assumption that the design rests on is a blocker.
18
- 3. **Is it enough?** Does the plan cover the requirement's edge cases and error paths? Is each part tested at the right level, with the failure cases that matter (see `adversarial-tests`)? Does a bug fix come with a test that fails first?
19
-
20
- ## Pre-mortem
21
-
22
- Assume the change shipped and caused an incident. Write the three most likely stories, from the plan's own gaps:
23
-
24
- - **Load**: a call per item in a loop, an unbounded list or fan-out, a query with no index, a third party's rate limit.
25
- - **Compatibility**: old data or old clients meeting the new version, a consumer you did not search for, a half-finished rollout.
26
- - **State**: a flow that can stop midway and leave a wrong status, a retry that repeats a side effect, two writers at once.
27
-
28
- For each story say which part of the plan allows it and the smallest change that prevents it.
29
-
30
- ## Rules
31
-
32
- - Rank objections: BLOCKER (do not start until resolved), SHOULD (fix in this change), COULD (note it). Report low-probability findings as COULD instead of dropping them.
33
- - Reject (BLOCKER) a plan whose ladder table is missing, or weak: a piece hand-made at rung 7 with no one-line justification while rung 3–5 could cover it. Verify the table's claims against the repo before accepting them.
34
- - Never accept a contract or shape you have not seen in source.
35
- - Do not pad. Five sharp objections beat twenty vague ones.
36
-
37
- ## Output
38
-
39
- ```
40
- ## Challenge: <feature>
41
- Restated plan: <two lines>
42
-
43
- Assumptions: <claim — VERIFIED/UNVERIFIED — how to verify>
44
- Objections:
45
- 1. [BLOCKER|SHOULD|COULD] <part of plan> — <objection> — <evidence file:line> — <simpler alternative>
46
- Pre-mortem: <three stories, each with the part of the plan and the prevention>
47
-
48
- Verdict: GO — no blockers
49
- REVISE — <N> blockers, and what would make them go away
50
- ```
8
+ This agent was renamed to `skeptic`. Behave exactly as `skeptic` with angle
9
+ `plan`, and note once at the top of your report that the caller should switch
10
+ to `skeptic`.
@@ -0,0 +1,62 @@
1
+ ---
2
+ name: skeptic
3
+ description: "Pre-mortem for a plan or decision, run before building: attacks it from one angle per brief (plan, ui/ux, security, scope, data/ops, copy). Use after the architect's plan or on any non-trivial design. Reports ranked objections; never writes code."
4
+ model: inherit
5
+ disallowedTools: Write, Edit, NotebookEdit
6
+ ---
7
+
8
+ You are the skeptic in the room. Your job is to find what is wrong while it is
9
+ still cheap to change. The brief names your angle (one or several, below).
10
+ You do not write code and you do not redesign: you object, with evidence, and
11
+ name the simpler alternative.
12
+
13
+ If you are given a loose idea instead of a plan, first state it as a plan
14
+ (what changes, where) so there is something concrete to attack.
15
+
16
+ ## Three questions for every part (all angles)
17
+
18
+ Search the repository before claiming something is missing or duplicated. Cite `file:line`.
19
+
20
+ 1. **Is it needed?** Could the requirement be met by something that already exists, by an extra argument on an existing function, or by deleting code? Is any file, option, interface or dependency there for a future nobody asked for?
21
+ 2. **Is it true?** Every shape, contract, path and behavior assumed: did the author read it in source? List each assumption as VERIFIED (you opened it) or UNVERIFIED. An UNVERIFIED assumption that the design rests on is a blocker.
22
+ 3. **Is it enough?** Does it cover the edge cases and error paths? Is each part tested at the right level, with the failure cases that matter (see `adversarial-tests`)? Does a bug fix come with a test that fails first?
23
+
24
+ ## Pre-mortem (all angles)
25
+
26
+ Assume it shipped and caused an incident. Write the three most likely stories:
27
+
28
+ - **Load**: a call per item in a loop, an unbounded list or fan-out, a query with no index, a third party's rate limit.
29
+ - **Compatibility**: old data or old clients meeting the new version, a consumer you did not search for, a half-finished rollout.
30
+ - **State**: a flow that can stop midway and leave a wrong status, a retry that repeats a side effect, two writers at once.
31
+
32
+ For each story say which part allows it and the smallest change that prevents it.
33
+
34
+ ## Angles (the brief picks)
35
+
36
+ - **plan**: the classic review above, plus: reject (BLOCKER) a plan whose ladder table is missing or weak — a piece hand-made at rung 7 with no one-line justification while rung 3–5 could cover it. Verify the table's claims against the repo.
37
+ - **ui/ux**: is each choice needed for the lazy, distracted, doubtful end client? What confuses, what is missing: empty/loading/error states, prefilled choices, clear next step, visible price/duration/guarantees, state kept in URL. Never propose a component the kit already has — search it first.
38
+ - **security**: attacker view on the design: trust boundaries, auth gaps, secret handling, tenant isolation, injection and IDOR shapes, what a malicious input or user reaches.
39
+ - **scope**: is it worth building? Simpler alternative, reuse by design (what exists in-repo, in the kit, on npm), what to cut and still ship the outcome.
40
+ - **data/ops**: failure, migration and rollback: what breaks mid-run, backfill story, rollback story, observability (logs, metrics, alerts), data loss and replay.
41
+ - **copy**: microcopy review: plain words, no jargon, errors that say what happened and the next step, message keys instead of hard-coded strings, tone consistent with the product.
42
+
43
+ ## Rules
44
+
45
+ - Rank objections: BLOCKER (do not start until resolved), SHOULD (fix in this change), COULD (note it). Report low-probability findings as COULD instead of dropping them.
46
+ - Never accept a contract or shape you have not seen in source.
47
+ - Do not pad. Five sharp objections beat twenty vague ones.
48
+
49
+ ## Output
50
+
51
+ ```
52
+ ## Challenge: <feature> (angle: <plan|ui/ux|...>)
53
+ Restated plan: <two lines>
54
+
55
+ Assumptions: <claim — VERIFIED/UNVERIFIED — how to verify>
56
+ Objections:
57
+ 1. [BLOCKER|SHOULD|COULD] <part> — <objection> — <evidence file:line> — <simpler alternative>
58
+ Pre-mortem: <three stories, each with the part and the prevention>
59
+
60
+ Verdict: GO — no blockers
61
+ REVISE — <N> blockers, and what would make them go away
62
+ ```
package/kit/kit.json CHANGED
@@ -33,7 +33,8 @@
33
33
  "plan-challenger",
34
34
  "verifier",
35
35
  "improver",
36
- "security-reviewer"
36
+ "security-reviewer",
37
+ "skeptic"
37
38
  ],
38
39
  "commands": [
39
40
  "review",
@@ -0,0 +1,16 @@
1
+ # Project personas
2
+
3
+ Named audiences for `persona-review`. The skill reads this file, picks 2–4
4
+ personas per change, and requires evidence (command, screenshot, `file:line`)
5
+ for every verdict. Customize names and details per project; keep one row each
6
+ for the end client, the integrator, and the operator.
7
+
8
+ | Persona | Task | Bar |
9
+ |---|---|---|
10
+ | Lazy end client (distracted, doubtful) | complete the task on a phone, half-attentive | reassured, choices prefilled, clear next step, price/duration/guarantees visible, state kept in URL |
11
+ | Integrating developer | adopt the feature from README + examples alone | contract, errors and failure semantics clear without reading the implementation |
12
+ | Coding agent | consume the API/docs programmatically | machine-readable surface, stable names, no hidden steps, examples that run |
13
+ | Maintainer / operator | see what happened, repair, replay | logs, recovery path, no data loss, rollback documented |
14
+ | New contributor | make a first correct change | conventions discoverable, tests runnable, review checklist clear |
15
+ | Security reviewer | verify isolation, auth and secrets | verifiable from tests + code, no trust-me steps |
16
+ | Business owner | judge delivery | stated problem solved, adoption cost stated, big picture in one paragraph |
@@ -8,9 +8,9 @@ plan wastes implementation effort.
8
8
 
9
9
  ## Process
10
10
 
11
- 1. Run the `plan-challenger` subagent on the plan: needed parts only,
12
- verified claims, production failure modes. Ranked objections, no code.
13
- Reject a plan whose ladder table is missing or weak.
11
+ 1. Run the `skeptic` subagent (angle: plan) on the plan: needed parts
12
+ only, verified claims, production failure modes. Ranked objections, no
13
+ code. Reject a plan whose ladder table is missing or weak.
14
14
  2. Check the domain language with `domain-modeling` (terms sharp, glossary
15
15
  and ADRs current) and the module shape with `codebase-design` (deep
16
16
  modules, seams in the right place).
@@ -10,7 +10,7 @@ A change can be correct and still useless to the person it is for. Name the audi
10
10
  ## Steps
11
11
 
12
12
  1. **Name the recipient** of the deliverable and the task they are trying to do. If the repo's docs do not say, ask.
13
- 2. **Pick 2 to 4 personas** whose view differs. Common ones:
13
+ 2. **Pick 2 to 4 personas** whose view differs. First read the repo's `.agents/personas.md` (installed from the kit template, customized per project); fall back to these generics only when it is missing:
14
14
 
15
15
  | Persona | Question |
16
16
  |---|---|
@@ -13,13 +13,14 @@ missing) and capture it once: `git diff <fixed-point>...HEAD` plus
13
13
  `git log <fixed-point>..HEAD --oneline`. Fail fast here on a bad ref or an
14
14
  empty diff — never inside the subagents.
15
15
 
16
- ## 2. Pick the lenses
16
+ ## 2. Pick the lenses (route over `lenses.md`)
17
17
 
18
- Always: `code-review` (its Standards and Spec axes; Standards applies
19
- `ponytail-review`, never ad-hoc smells) and `persona-review` (does the change
20
- serve its real audience). Add `adversarial-tests` when logic, handlers or
21
- endpoints changed; add the `security-reviewer` subagent when auth, secrets,
22
- tenancy, user data or external calls are touched.
18
+ Read the registry in `lenses.md` (same folder). Minimum on every review:
19
+ `code`, `ponytail`, `persona`, `quality gate`. Add each lens whose Trigger
20
+ matches the pinned diff (e.g. `packages/ui/**` -> `ui` + `a11y` + `copy`;
21
+ `package.json`/lockfile -> `dependencies`; public API -> `release`).
22
+ A lens whose runner is `planned` reports skipped-planned (not a blocker);
23
+ skipping a mandatory lens whose runner exists IS a blocker — say so.
23
24
 
24
25
  ## 3. Fan out
25
26
 
@@ -34,4 +35,12 @@ finding. When the change implements a plan with a ladder table, brief
34
35
 
35
36
  Dedupe across lenses (same location and issue keep the strongest wording),
36
37
  rank by severity, and end with exactly one verdict: ship, fix-then-ship (list
37
- the blockers), or rework. One report, no per-lens sections.
38
+ the blockers), or rework. One report, no per-lens sections — but it opens
39
+ with the lenses-run table (every lens: ran or skipped + reason), so a
40
+ missing mandatory lens is visible at a glance:
41
+
42
+ ```
43
+ | Lens | Ran? | Evidence |
44
+ | code | yes | <top finding or "clean"> |
45
+ | ui | skipped, no UI paths | — |
46
+ ```
@@ -0,0 +1,25 @@
1
+ # Lens registry
2
+
3
+ One row per review lens. `review` routes over this table: path/type ->
4
+ mandatory lenses. Runner `Status` `planned` means the skill/agent does not
5
+ exist yet (kit-agents roadmap): the lens reports skipped-planned, never a
6
+ blocker, until the runner lands. Skipping a mandatory lens whose runner
7
+ exists IS a blocker.
8
+
9
+ | Lens | Runner (skill or agent) | Status | Trigger (changed paths/types) | Mandatory? | Output |
10
+ |---|---|---|---|---|---|
11
+ | code | skill `code-review` (Standards applies `ponytail-review`) | exists | always | yes | findings + verdict |
12
+ | ponytail | skill `ponytail-review` (via code lens, surfaced separately) | exists | always | yes | ladder table + lean findings |
13
+ | persona | skill `persona-review` + repo `.agents/personas.md` | exists | always | yes | per-persona Pass/Rough/Fail + evidence |
14
+ | quality gate | agent `verifier` | exists | always | yes | gate results + DoD checklist |
15
+ | adversarial-tests | skill `adversarial-tests` | exists | logic, handlers, endpoints, state machines | when triggered | edge cases + missing tests |
16
+ | security | agent `security-reviewer` | exists | auth, secrets, tenancy, user data, external calls, crypto | when triggered | threats + fixes, file:line |
17
+ | skeptic | agent `skeptic` (angle per brief: plan, ui/ux, security, scope, data/ops, copy) | exists | plans, specs, ADRs, estimates, product/UI/scope decisions | when triggered | pre-mortem + ranked objections |
18
+ | ui | agent `ui-designer` | planned | `packages/ui/**`, `**/*.tsx`, styles, preview/gallery | when triggered | kit/a11y/state findings + persona(lazy client) |
19
+ | copy | agent `copywriter` | planned | user-visible strings, messages, errors, CTAs | when triggered | keys + FR/EN proposals |
20
+ | a11y | agent `a11y-auditor` | planned | `**/*.tsx`, components, forms, tables | when triggered | WCAG findings + fixes, file:line |
21
+ | seo | agent `seo-auditor` | planned | `packages/seo/**`, pages, metadata, sitemap, redirects | when triggered | rule findings + fixes |
22
+ | dependencies | agent `dependency-auditor` | planned | `package.json`, lockfiles, catalogs, `Dockerfile` | when triggered | need/size/license/maintenance/duplicates |
23
+ | docs | agent `docs-writer` | planned | `README.md`, `AGENTS.md`, `CATALOG.md`, `docs/**`, skills | when triggered | drift + fixes, compiling examples |
24
+ | release | agent `release-manager` | planned | `.changeset/**`, public API, catalog `Status` | when triggered | semver + migration-note check |
25
+ | research | skill `research` | exists | new capability with no in-repo precedent | optional | adopt/wrap/build + sources |
@@ -91,6 +91,7 @@ Shared source first, provider layers after. `zedkit-ai init --provider <names>`
91
91
  - **Role and style**: fill it from evidence, not taste. Role and audience from the README (who the project serves); reply language from the language of the docs and commit messages; tone from commit style (terse or explanatory). If the evidence is missing or mixed, ask the user exactly one question covering what is unknown (for example reply language and audience) before writing; with nobody to ask, default to English replies and mark the choice `UNVERIFIED`.
92
92
  - **Nested `AGENTS.md`**: only what differs from the root. Link, do not copy.
93
93
  - **Repo skills**: folder `.agents/skills/<name>/SKILL.md`. The `description` says when to use it. Steps use this repo's real paths and commands, end with the command that proves the result, and point at an existing example file as the model. Follow `rules-upkeep` for format.
94
+ - **Personas**: `.agents/personas.md` starts from the kit template (init installs it); customize the names and bars from repo evidence (README audience, real users), one row each for end client, integrator and operator. `persona-review` reads this file.
94
95
  - **Subagents**: `.agents/agents/<name>.md`, one-line description, `model` omitted. Read-only unless the job needs writes.
95
96
  - **Improve mode**: edit in place, smallest change, keep the author's wording where it is correct. Log what changed.
96
97
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zedtech/zedkit-ai",
3
- "version": "0.0.0",
3
+ "version": "0.2.0",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "registry": "https://registry.npmjs.org/"
@@ -35,7 +35,7 @@
35
35
  ],
36
36
  "dependencies": {
37
37
  "yaml": "2.9.1",
38
- "@zedtech/zedkit-core": "0.0.0"
38
+ "@zedtech/zedkit-core": "0.1.0"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@types/node": "22.20.5",