@vaubaan/harness 0.0.0-stage → 1.3.2

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.
Files changed (53) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +5 -0
  3. package/README.md +307 -2
  4. package/dist/agents/coding.agent.md +182 -0
  5. package/dist/agents/merge.agent.md +139 -0
  6. package/dist/agents/planning.agent.md +194 -0
  7. package/dist/agents/review.agent.md +176 -0
  8. package/dist/cli/index.d.ts +1 -0
  9. package/dist/cli/index.js +2924 -0
  10. package/dist/cli/index.js.map +1 -0
  11. package/dist/commands/clean-code.cmd.md +26 -0
  12. package/dist/commands/decision.cmd.md +19 -0
  13. package/dist/commands/doc-audit.cmd.md +24 -0
  14. package/dist/commands/drift.cmd.md +18 -0
  15. package/dist/commands/handbook.cmd.md +21 -0
  16. package/dist/commands/readme.cmd.md +19 -0
  17. package/dist/commands/spec.cmd.md +20 -0
  18. package/dist/commands/test-plan.cmd.md +22 -0
  19. package/dist/commands/workflow.cmd.md +19 -0
  20. package/dist/index.d.ts +36 -0
  21. package/dist/index.js +1706 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/init.d.ts +42 -0
  24. package/dist/init.js +1088 -0
  25. package/dist/init.js.map +1 -0
  26. package/dist/linters/index.d.ts +43 -0
  27. package/dist/linters/index.js +727 -0
  28. package/dist/linters/index.js.map +1 -0
  29. package/dist/parser/index.d.ts +247 -0
  30. package/dist/parser/index.js +114 -0
  31. package/dist/parser/index.js.map +1 -0
  32. package/dist/render-B9_kNtQc.d.ts +50 -0
  33. package/dist/render.d.ts +3 -0
  34. package/dist/render.js +572 -0
  35. package/dist/render.js.map +1 -0
  36. package/dist/skills/clean-code-guardian.skill.md +391 -0
  37. package/dist/skills/decision-record-writer.skill.md +166 -0
  38. package/dist/skills/doc-audit.skill.md +257 -0
  39. package/dist/skills/drift-detector.skill.md +173 -0
  40. package/dist/skills/handbook-writer.skill.md +185 -0
  41. package/dist/skills/readme-writer.skill.md +131 -0
  42. package/dist/skills/spec-writer.skill.md +165 -0
  43. package/dist/skills/test-plan-writer.skill.md +179 -0
  44. package/dist/skills/workflow-writer.skill.md +168 -0
  45. package/dist/templates/code-quality.md.tmpl +57 -0
  46. package/dist/templates/coding-workflow.md.tmpl +88 -0
  47. package/dist/templates/decision.md.tmpl +60 -0
  48. package/dist/templates/e2e-tests.md.tmpl +62 -0
  49. package/dist/templates/handbook.md.tmpl +58 -0
  50. package/dist/templates/integration-tests.md.tmpl +50 -0
  51. package/dist/templates/readme.md.tmpl +51 -0
  52. package/dist/templates/spec.md.tmpl +64 -0
  53. package/package.json +82 -4
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/linters/util.ts","../../src/linters/adr-no-tracks.ts","../../src/linters/cardinal-files.ts","../../src/linters/config.ts","../../src/linters/cross-links.ts","../../src/linters/decision-schema.ts","../../src/linters/doc-layout.ts","../../src/linters/frontmatter-tracks.ts","../../src/linters/gitignore-harness.ts","../../src/linters/orphan-decisions.ts","../../src/linters/quality-schema.ts","../../src/linters/readme-presence.ts","../../src/linters/readme-sections.ts","../../src/linters/spec-has-content.ts","../../src/linters/spec-tech-agnostic.ts","../../src/linters/tracks-drift.ts","../../src/linters/index.ts"],"sourcesContent":["import { execFileSync } from \"node:child_process\";\nimport { existsSync, readFileSync, statSync } from \"node:fs\";\nimport { join, relative } from \"node:path\";\nimport fg from \"fast-glob\";\nimport matter from \"gray-matter\";\n\nexport function fileExists(repoRoot: string, relativePath: string): boolean {\n return existsSync(join(repoRoot, relativePath));\n}\n\nexport function readText(repoRoot: string, relativePath: string): string {\n return readFileSync(join(repoRoot, relativePath), \"utf8\");\n}\n\nexport function listMarkdown(repoRoot: string, dir: string): string[] {\n const cwd = join(repoRoot, dir);\n if (!existsSync(cwd)) return [];\n return fg\n .sync(\"**/*.md\", { cwd, absolute: false, ignore: [\"**/node_modules/**\", \"**/dist/**\"] })\n .filter((f) => !f.endsWith(\"README.md\"))\n .map((f) => join(dir, f));\n}\n\nexport function listAllMarkdown(repoRoot: string, dir: string): string[] {\n const cwd = join(repoRoot, dir);\n if (!existsSync(cwd)) return [];\n return fg\n .sync(\"**/*.md\", { cwd, absolute: false, ignore: [\"**/node_modules/**\", \"**/dist/**\"] })\n .map((f) => join(dir, f));\n}\n\nexport function dirExists(repoRoot: string, relativePath: string): boolean {\n const full = join(repoRoot, relativePath);\n if (!existsSync(full)) return false;\n return statSync(full).isDirectory();\n}\n\nexport function parseFrontmatter(text: string): { data: Record<string, unknown>; body: string } {\n const m = matter(text);\n return { data: m.data, body: m.content };\n}\n\nexport interface GitLogEntry {\n hash: string;\n timestamp: number;\n}\n\nexport function gitLastCommitForPath(\n repoRoot: string,\n relativePath: string,\n): GitLogEntry | undefined {\n try {\n const out = execFileSync(\"git\", [\"log\", \"-1\", \"--format=%H:%ct\", \"--\", relativePath], {\n cwd: repoRoot,\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim();\n if (!out) return undefined;\n const idx = out.indexOf(\":\");\n if (idx < 0) return undefined;\n const hash = out.slice(0, idx);\n const ts = Number.parseInt(out.slice(idx + 1), 10);\n return { hash, timestamp: ts };\n } catch {\n return undefined;\n }\n}\n\nexport function gitCommitsSince(\n repoRoot: string,\n relativePath: string,\n sinceCommit: string,\n): number {\n try {\n const out = execFileSync(\n \"git\",\n [\"log\", `${sinceCommit}..HEAD`, \"--format=%H\", \"--\", relativePath],\n {\n cwd: repoRoot,\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n },\n ).trim();\n if (!out) return 0;\n return out.split(\"\\n\").filter(Boolean).length;\n } catch {\n return 0;\n }\n}\n\nexport function relPath(repoRoot: string, abs: string): string {\n return relative(repoRoot, abs);\n}\n\nexport function findLineNumber(text: string, needle: string | RegExp): number | undefined {\n const lines = text.split(\"\\n\");\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n if (typeof needle === \"string\" ? line.includes(needle) : needle.test(line)) {\n return i + 1;\n }\n }\n return undefined;\n}\n","import type { LintIssue, Linter } from \"./types.js\";\nimport { listMarkdown, parseFrontmatter, readText } from \"./util.js\";\n\nconst ADR_DIR = \"docs/decisions\";\n\nexport const adrNoTracks: Linter = {\n id: \"lint:adr-no-tracks\",\n pillars: [\"decisions\"],\n defaultSeverity: \"error\",\n suggestedSkills: [\"/decision\"],\n run(repoRoot: string): LintIssue[] {\n const issues: LintIssue[] = [];\n const files = listMarkdown(repoRoot, ADR_DIR);\n for (const f of files) {\n const text = readText(repoRoot, f);\n const { data } = parseFrontmatter(text);\n if (!(\"tracks\" in data)) continue;\n const value = data.tracks;\n if (Array.isArray(value) && value.length === 0) continue;\n issues.push({\n linter: this.id,\n severity: \"error\",\n file: f,\n message:\n \"ADRs must not declare `tracks:` (or must set it to []). ADRs document a decision frozen in time, not the current state of code — use status: superseded to mark them obsolete instead.\",\n });\n }\n return issues;\n },\n};\n","import type { LintIssue, Linter } from \"./types.js\";\nimport { fileExists } from \"./util.js\";\n\nconst REQUIRED_FILES = [\n \"docs/tests/integration-tests.md\",\n \"docs/tests/e2e-tests.md\",\n \"docs/workflow/coding-workflow.md\",\n];\n\nexport const cardinalFiles: Linter = {\n id: \"lint:cardinal-files\",\n pillars: [\"tests\", \"workflow\"],\n defaultSeverity: \"error\",\n suggestedSkills: [\"/test-plan\", \"/workflow\"],\n run(repoRoot: string): LintIssue[] {\n const issues: LintIssue[] = [];\n for (const f of REQUIRED_FILES) {\n if (!fileExists(repoRoot, f)) {\n issues.push({\n linter: this.id,\n severity: \"error\",\n file: f,\n message: `missing required cardinal file: ${f}`,\n });\n }\n }\n return issues;\n },\n};\n","import { cosmiconfigSync } from \"cosmiconfig\";\n\nexport interface HarnessLintConfig {\n ignore: ReadonlyArray<string>;\n}\n\nconst DEFAULT_CONFIG: HarnessLintConfig = { ignore: [] };\n\nexport function loadLintConfig(repoRoot: string): HarnessLintConfig {\n const explorer = cosmiconfigSync(\"harness\", {\n searchPlaces: [\n \"package.json\",\n \".harnessrc\",\n \".harnessrc.json\",\n \".harnessrc.yaml\",\n \".harnessrc.yml\",\n \"harness.config.js\",\n \"harness.config.cjs\",\n ],\n });\n const result = explorer.search(repoRoot);\n if (!result || result.isEmpty) return DEFAULT_CONFIG;\n\n const raw = result.config as Record<string, unknown> | undefined;\n if (!raw) return DEFAULT_CONFIG;\n\n const lint = raw.lint as Record<string, unknown> | undefined;\n if (!lint) return DEFAULT_CONFIG;\n\n const ignore = lint.ignore;\n if (!Array.isArray(ignore)) return DEFAULT_CONFIG;\n\n return { ignore: ignore.filter((x): x is string => typeof x === \"string\") };\n}\n","import { existsSync } from \"node:fs\";\nimport { dirname, isAbsolute, join, resolve } from \"node:path\";\nimport fg from \"fast-glob\";\nimport type { LintContext, LintIssue, Linter } from \"./types.js\";\nimport { readText } from \"./util.js\";\n\nconst LINK_REGEX = /\\[([^\\]]+)\\]\\(([^)]+)\\)/g;\n\nfunction maskCodeSpans(text: string): string {\n return text\n .replace(/```[\\s\\S]*?```/g, (m) => m.replace(/[^\\n]/g, \" \"))\n .replace(/`[^`\\n]*`/g, (m) => \" \".repeat(m.length));\n}\n\nfunction isExternalOrAnchor(url: string): boolean {\n if (url.startsWith(\"http://\") || url.startsWith(\"https://\")) return true;\n if (url.startsWith(\"mailto:\")) return true;\n if (url.startsWith(\"#\")) return true;\n return false;\n}\n\nfunction stripFragment(url: string): string {\n const i = url.indexOf(\"#\");\n return i < 0 ? url : url.slice(0, i);\n}\n\nfunction resolveLink(repoRoot: string, sourceFile: string, link: string): string {\n const noFrag = stripFragment(link);\n if (isAbsolute(noFrag)) return join(repoRoot, noFrag);\n return resolve(dirname(join(repoRoot, sourceFile)), noFrag);\n}\n\nexport const crossLinks: Linter = {\n id: \"lint:cross-links\",\n pillars: [\"all\"],\n defaultSeverity: \"error\",\n run(repoRoot: string, ctx?: LintContext): LintIssue[] {\n const extra = ctx?.config.ignore ?? [];\n const issues: LintIssue[] = [];\n const allDocs = fg.sync(\"**/*.md\", {\n cwd: repoRoot,\n absolute: false,\n ignore: [\n \"**/node_modules/**\",\n \"**/dist/**\",\n \".harness-overrides/**\",\n \"skills/**\",\n \"agents/**\",\n \"commands/**\",\n \"templates/**\",\n \"**/*.skill.md\",\n \"**/*.cmd.md\",\n \"**/*.agent.md\",\n ...extra,\n ],\n });\n for (const f of allDocs) {\n const text = maskCodeSpans(readText(repoRoot, f));\n const lines = text.split(\"\\n\");\n for (let lineNo = 0; lineNo < lines.length; lineNo++) {\n const line = lines[lineNo] ?? \"\";\n LINK_REGEX.lastIndex = 0;\n let match: RegExpExecArray | null;\n match = LINK_REGEX.exec(line);\n while (match !== null) {\n const url = match[2];\n if (url && !isExternalOrAnchor(url)) {\n const noFrag = stripFragment(url);\n if (noFrag !== \"\" && !noFrag.startsWith(\"data:\")) {\n const target = resolveLink(repoRoot, f, url);\n if (!existsSync(target)) {\n issues.push({\n linter: this.id,\n severity: \"error\",\n file: f,\n line: lineNo + 1,\n message: `broken link: ${url}`,\n });\n }\n }\n }\n match = LINK_REGEX.exec(line);\n }\n }\n }\n return issues;\n },\n};\n","import type { LintIssue, Linter } from \"./types.js\";\nimport { listMarkdown, readText } from \"./util.js\";\n\n// English headings are canonical; the French ones are still accepted so\n// projects written before the switch to English keep passing.\nconst REQUIRED_SECTIONS: Array<{ label: string; pattern: RegExp }> = [\n { label: \"Context\", pattern: /^##\\s+(Context|Contexte)\\b/m },\n { label: \"Decision\", pattern: /^##\\s+(Decision|D[ée]cision)\\b/m },\n { label: \"Consequences\", pattern: /^##\\s+(Consequences|Cons[ée]quences)\\b/m },\n {\n label: \"Rejected alternatives\",\n pattern: /^##\\s+(Rejected\\s+alternatives|Alternatives(\\s+rejet[ée]es)?)\\b/im,\n },\n];\n\nexport const decisionSchema: Linter = {\n id: \"lint:decision-schema\",\n pillars: [\"decisions\"],\n defaultSeverity: \"error\",\n suggestedSkills: [\"/decision\"],\n run(repoRoot: string): LintIssue[] {\n const issues: LintIssue[] = [];\n const files = listMarkdown(repoRoot, \"docs/decisions\");\n for (const f of files) {\n const text = readText(repoRoot, f);\n for (const { label, pattern } of REQUIRED_SECTIONS) {\n if (!pattern.test(text)) {\n issues.push({\n linter: this.id,\n severity: \"error\",\n file: f,\n message: `missing required section: \"${label}\"`,\n });\n }\n }\n }\n return issues;\n },\n};\n","import type { LintIssue, Linter } from \"./types.js\";\nimport { dirExists } from \"./util.js\";\n\nconst REQUIRED_DIRS = [\n \"docs/spec\",\n \"docs/decisions\",\n \"docs/handbook\",\n \"docs/tests\",\n \"docs/workflow\",\n];\n\nexport const docLayout: Linter = {\n id: \"lint:doc-layout\",\n pillars: [\"all\"],\n defaultSeverity: \"error\",\n run(repoRoot: string): LintIssue[] {\n const issues: LintIssue[] = [];\n for (const dir of REQUIRED_DIRS) {\n if (!dirExists(repoRoot, dir)) {\n issues.push({\n linter: this.id,\n severity: \"error\",\n file: dir,\n message: `missing required directory: ${dir}/`,\n });\n }\n }\n return issues;\n },\n};\n","import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport fg from \"fast-glob\";\nimport type { LintIssue, Linter } from \"./types.js\";\nimport { listMarkdown, parseFrontmatter, readText } from \"./util.js\";\n\nconst TRACKED_DIRS = [\"docs/handbook\", \"docs/tests\", \"docs/workflow\"];\n\nfunction trackedPathExists(repoRoot: string, pattern: string): boolean {\n if (pattern.includes(\"*\")) {\n return fg.sync(pattern, { cwd: repoRoot, absolute: false }).length > 0;\n }\n return existsSync(join(repoRoot, pattern));\n}\n\nexport const frontmatterTracks: Linter = {\n id: \"lint:frontmatter-tracks\",\n pillars: [\"handbook\", \"tests\", \"workflow\"],\n defaultSeverity: \"error\",\n suggestedSkills: [\"/handbook\", \"/test-plan\", \"/workflow\"],\n run(repoRoot: string): LintIssue[] {\n const issues: LintIssue[] = [];\n for (const dir of TRACKED_DIRS) {\n const files = listMarkdown(repoRoot, dir);\n for (const f of files) {\n const text = readText(repoRoot, f);\n const { data } = parseFrontmatter(text);\n if (!Array.isArray(data.tracks)) {\n issues.push({\n linter: this.id,\n severity: \"error\",\n file: f,\n message: \"missing frontmatter `tracks:` array\",\n });\n continue;\n }\n for (const tracked of data.tracks as unknown[]) {\n if (typeof tracked !== \"string\") {\n issues.push({\n linter: this.id,\n severity: \"error\",\n file: f,\n message: \"`tracks` entries must be strings\",\n });\n continue;\n }\n if (!trackedPathExists(repoRoot, tracked)) {\n issues.push({\n linter: this.id,\n severity: \"error\",\n file: f,\n message: `tracked path does not exist: ${tracked}`,\n });\n }\n }\n }\n }\n return issues;\n },\n};\n","import type { LintIssue, Linter } from \"./types.js\";\nimport { fileExists, readText } from \"./util.js\";\n\n/** Paths the harness generates or writes at runtime; none belongs in Git. */\nexport const REQUIRED_GITIGNORE_ENTRIES: ReadonlyArray<string> = [\n \".harness-overrides/\",\n \".harness-manifest.json\",\n \".harness/\",\n \".claude/\",\n \".codex/\",\n \".opencode/\",\n \".agents/\",\n \".vaubaan/\",\n \"AGENTS.md\",\n \"CLAUDE.md\",\n \".mcp.json\",\n];\n\nexport const gitignoreHarness: Linter = {\n id: \"lint:gitignore-harness\",\n pillars: [\"repo-root\"],\n defaultSeverity: \"error\",\n run(repoRoot: string): LintIssue[] {\n const issues: LintIssue[] = [];\n if (!fileExists(repoRoot, \".gitignore\")) {\n issues.push({\n linter: this.id,\n severity: \"error\",\n file: \".gitignore\",\n message: \".gitignore is missing at repo root\",\n });\n return issues;\n }\n const text = readText(repoRoot, \".gitignore\");\n const lines = new Set(\n text\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter(Boolean),\n );\n for (const entry of REQUIRED_GITIGNORE_ENTRIES) {\n const variants = [entry, entry.replace(/\\/$/, \"\")];\n if (!variants.some((v) => lines.has(v))) {\n issues.push({\n linter: this.id,\n severity: \"error\",\n file: \".gitignore\",\n message: `.gitignore must contain \"${entry}\"`,\n });\n }\n }\n return issues;\n },\n};\n","import { basename } from \"node:path\";\nimport fg from \"fast-glob\";\nimport type { LintContext, LintIssue, Linter } from \"./types.js\";\nimport { listMarkdown, readText } from \"./util.js\";\n\nexport const orphanDecisions: Linter = {\n id: \"lint:orphan-decisions\",\n pillars: [\"decisions\"],\n defaultSeverity: \"warning\",\n suggestedSkills: [\"/handbook\"],\n run(repoRoot: string, ctx?: LintContext): LintIssue[] {\n const extra = ctx?.config.ignore ?? [];\n const issues: LintIssue[] = [];\n const adrs = listMarkdown(repoRoot, \"docs/decisions\");\n if (adrs.length === 0) return issues;\n\n const otherDocs = fg.sync(\"**/*.md\", {\n cwd: repoRoot,\n absolute: false,\n ignore: [\n \"**/node_modules/**\",\n \"**/dist/**\",\n \".harness-overrides/**\",\n \"docs/decisions/**\",\n \"skills/**\",\n \"agents/**\",\n \"commands/**\",\n \"templates/**\",\n ...extra,\n ],\n });\n\n const referenceCorpus = otherDocs.map((f) => readText(repoRoot, f)).join(\"\\n\");\n\n for (const adr of adrs) {\n const filename = basename(adr);\n const stem = filename.replace(/\\.md$/, \"\");\n const referenced = referenceCorpus.includes(filename) || referenceCorpus.includes(stem);\n if (!referenced) {\n issues.push({\n linter: this.id,\n severity: \"warning\",\n file: adr,\n message: \"ADR is not referenced by any other doc file (orphan)\",\n });\n }\n }\n return issues;\n },\n};\n","import type { LintIssue, Linter } from \"./types.js\";\nimport { dirExists, fileExists, readText } from \"./util.js\";\n\nconst QUALITY_DIR = \"docs/quality\";\nconst CARDINAL_FILE = `${QUALITY_DIR}/code-quality.md`;\n\n// English headings are canonical; the French ones are still accepted so\n// projects written before the switch to English keep passing.\nconst REQUIRED_SECTIONS: ReadonlyArray<{ label: string; pattern: RegExp }> = [\n {\n label: \"Mechanical checks\",\n pattern: /^##\\s+(Mechanical\\s+checks|V[ée]rifications\\s+m[ée]caniques)\\s*$/im,\n },\n { label: \"Project rules\", pattern: /^##\\s+(Project\\s+rules|R[èe]gles\\s+du\\s+projet)\\s*$/im },\n {\n label: \"Accepted deviations\",\n pattern: /^##\\s+(Accepted\\s+deviations|[ÉE]carts\\s+assum[ée]s)\\s*$/im,\n },\n];\n\n/**\n * `docs/quality/` is an optional pillar: absent directory = nothing to\n * report. Once the directory exists, its cardinal file and sections are\n * required.\n */\nexport const qualitySchema: Linter = {\n id: \"lint:quality-schema\",\n pillars: [\"quality\"],\n defaultSeverity: \"error\",\n run(repoRoot: string): LintIssue[] {\n if (!dirExists(repoRoot, QUALITY_DIR)) return [];\n if (!fileExists(repoRoot, CARDINAL_FILE)) {\n return [\n {\n linter: this.id,\n severity: \"error\",\n file: CARDINAL_FILE,\n message: `missing required cardinal file: ${CARDINAL_FILE}`,\n },\n ];\n }\n const text = readText(repoRoot, CARDINAL_FILE);\n return REQUIRED_SECTIONS.filter(({ pattern }) => !pattern.test(text)).map(({ label }) => ({\n linter: this.id,\n severity: \"error\" as const,\n file: CARDINAL_FILE,\n message: `missing required section: \"${label}\"`,\n }));\n },\n};\n","import type { LintIssue, Linter } from \"./types.js\";\nimport { fileExists } from \"./util.js\";\n\nexport const readmePresence: Linter = {\n id: \"lint:readme-presence\",\n pillars: [\"readme\"],\n defaultSeverity: \"error\",\n suggestedSkills: [\"/readme\"],\n run(repoRoot: string): LintIssue[] {\n if (fileExists(repoRoot, \"README.md\")) return [];\n return [\n {\n linter: this.id,\n severity: \"error\",\n file: \"README.md\",\n message: \"README.md is missing at repo root\",\n },\n ];\n },\n};\n","import type { LintIssue, Linter } from \"./types.js\";\nimport { fileExists, readText } from \"./util.js\";\n\nconst REQUIRED_SECTIONS = [\n /^#\\s+\\S/m,\n /^##?\\s+(What is this|Quick start)/im,\n /^##?\\s+(Quick start|Install|Getting started)/im,\n];\n\nconst REQUIRED_LABELS = [\"title (# H1)\", \"What is this / intro\", \"Quick start / Install\"];\n\nexport const readmeSections: Linter = {\n id: \"lint:readme-sections\",\n pillars: [\"readme\"],\n defaultSeverity: \"error\",\n suggestedSkills: [\"/readme\"],\n run(repoRoot: string): LintIssue[] {\n if (!fileExists(repoRoot, \"README.md\")) return [];\n const text = readText(repoRoot, \"README.md\");\n const issues: LintIssue[] = [];\n for (let i = 0; i < REQUIRED_SECTIONS.length; i++) {\n const pattern = REQUIRED_SECTIONS[i];\n const label = REQUIRED_LABELS[i];\n if (pattern && !pattern.test(text)) {\n issues.push({\n linter: this.id,\n severity: \"error\",\n file: \"README.md\",\n message: `missing required section: ${label}`,\n });\n }\n }\n return issues;\n },\n};\n","import type { LintIssue, Linter } from \"./types.js\";\nimport { dirExists, listMarkdown } from \"./util.js\";\n\nexport const specHasContent: Linter = {\n id: \"lint:spec-has-content\",\n pillars: [\"spec\"],\n defaultSeverity: \"warning\",\n suggestedSkills: [\"/spec\"],\n run(repoRoot: string): LintIssue[] {\n if (!dirExists(repoRoot, \"docs/spec\")) return [];\n const files = listMarkdown(repoRoot, \"docs/spec\");\n if (files.length > 0) return [];\n return [\n {\n linter: this.id,\n severity: \"warning\",\n file: \"docs/spec\",\n message: \"docs/spec/ has no markdown files — write at least one spec document\",\n },\n ];\n },\n};\n","import type { LintIssue, Linter } from \"./types.js\";\nimport { findLineNumber, listMarkdown, readText } from \"./util.js\";\n\nfunction maskFencedBlocks(text: string): string {\n return text.replace(/```[\\s\\S]*?```/g, (m) => m.replace(/[^\\n]/g, \" \"));\n}\n\nconst TECH_BLOCKLIST: Array<{ pattern: RegExp; keyword: string }> = [\n { pattern: /\\bNext\\.?js\\b/i, keyword: \"Next.js\" },\n { pattern: /\\bSupabase\\b/i, keyword: \"Supabase\" },\n { pattern: /\\bVercel\\b/i, keyword: \"Vercel\" },\n { pattern: /\\bReact\\b/, keyword: \"React\" },\n { pattern: /\\bTypeScript\\b/, keyword: \"TypeScript\" },\n { pattern: /\\bDocker\\b/, keyword: \"Docker\" },\n { pattern: /\\bKubernetes\\b/i, keyword: \"Kubernetes\" },\n { pattern: /\\bPostgres(QL)?\\b/i, keyword: \"Postgres\" },\n { pattern: /\\bMySQL\\b/i, keyword: \"MySQL\" },\n { pattern: /\\bRedis\\b/i, keyword: \"Redis\" },\n { pattern: /\\bnpm\\b/, keyword: \"npm\" },\n { pattern: /\\bpnpm\\b/, keyword: \"pnpm\" },\n { pattern: /\\byarn\\b/, keyword: \"yarn\" },\n];\n\nexport const specTechAgnostic: Linter = {\n id: \"lint:spec-tech-agnostic\",\n pillars: [\"spec\"],\n defaultSeverity: \"error\",\n suggestedSkills: [\"/spec\"],\n run(repoRoot: string): LintIssue[] {\n const issues: LintIssue[] = [];\n const files = listMarkdown(repoRoot, \"docs/spec\");\n for (const f of files) {\n const text = maskFencedBlocks(readText(repoRoot, f));\n for (const { pattern, keyword } of TECH_BLOCKLIST) {\n if (pattern.test(text)) {\n const issue: LintIssue = {\n linter: this.id,\n severity: \"error\",\n file: f,\n message: `forbidden tech keyword \"${keyword}\" — should be in handbook/ or decisions/`,\n };\n const line = findLineNumber(text, pattern);\n if (line !== undefined) issue.line = line;\n issues.push(issue);\n }\n }\n }\n return issues;\n },\n};\n","import fg from \"fast-glob\";\nimport type { LintIssue, Linter } from \"./types.js\";\nimport {\n gitCommitsSince,\n gitLastCommitForPath,\n listMarkdown,\n parseFrontmatter,\n readText,\n} from \"./util.js\";\n\nconst TRACKED_DIRS = [\"docs/handbook\", \"docs/tests\", \"docs/workflow\"];\nconst DEFAULT_DRIFT_THRESHOLD = 10;\n\nfunction expandGlob(repoRoot: string, pattern: string): string[] {\n if (pattern.includes(\"*\")) {\n return fg.sync(pattern, { cwd: repoRoot, absolute: false });\n }\n return [pattern];\n}\n\nexport const tracksDrift: Linter = {\n id: \"lint:tracks-drift\",\n pillars: [\"handbook\", \"tests\", \"workflow\"],\n defaultSeverity: \"warning\",\n suggestedSkills: [\"/drift\", \"/handbook\"],\n run(repoRoot: string): LintIssue[] {\n const issues: LintIssue[] = [];\n for (const dir of TRACKED_DIRS) {\n const files = listMarkdown(repoRoot, dir);\n for (const f of files) {\n const text = readText(repoRoot, f);\n const { data } = parseFrontmatter(text);\n if (!Array.isArray(data.tracks)) continue;\n const docCommit = gitLastCommitForPath(repoRoot, f);\n if (!docCommit) continue;\n const threshold =\n typeof data.driftThreshold === \"number\" && data.driftThreshold > 0\n ? data.driftThreshold\n : DEFAULT_DRIFT_THRESHOLD;\n let driftCount = 0;\n for (const tracked of data.tracks) {\n if (typeof tracked !== \"string\") continue;\n const targets = expandGlob(repoRoot, tracked);\n for (const t of targets.length > 0 ? targets : [tracked]) {\n driftCount += gitCommitsSince(repoRoot, t, docCommit.hash);\n }\n }\n if (driftCount > threshold) {\n issues.push({\n linter: this.id,\n severity: \"warning\",\n file: f,\n message: `tracked files changed in ${driftCount} commits since doc last edit (threshold ${threshold})`,\n });\n }\n }\n }\n return issues;\n },\n};\n","import { adrNoTracks } from \"./adr-no-tracks.js\";\nimport { cardinalFiles } from \"./cardinal-files.js\";\nimport { loadLintConfig } from \"./config.js\";\nimport { crossLinks } from \"./cross-links.js\";\nimport { decisionSchema } from \"./decision-schema.js\";\nimport { docLayout } from \"./doc-layout.js\";\nimport { frontmatterTracks } from \"./frontmatter-tracks.js\";\nimport { gitignoreHarness } from \"./gitignore-harness.js\";\nimport { orphanDecisions } from \"./orphan-decisions.js\";\nimport { qualitySchema } from \"./quality-schema.js\";\nimport { readmePresence } from \"./readme-presence.js\";\nimport { readmeSections } from \"./readme-sections.js\";\nimport { specHasContent } from \"./spec-has-content.js\";\nimport { specTechAgnostic } from \"./spec-tech-agnostic.js\";\nimport { tracksDrift } from \"./tracks-drift.js\";\nimport type { LintContext, LintIssue, LintReport, Linter } from \"./types.js\";\n\nexport const ALL_LINTERS: ReadonlyArray<Linter> = [\n readmePresence,\n readmeSections,\n docLayout,\n cardinalFiles,\n decisionSchema,\n adrNoTracks,\n frontmatterTracks,\n tracksDrift,\n specTechAgnostic,\n specHasContent,\n crossLinks,\n orphanDecisions,\n gitignoreHarness,\n qualitySchema,\n];\n\nexport interface RunOptions {\n pillar?: string;\n only?: ReadonlyArray<string>;\n}\n\nexport function runLinters(repoRoot: string, opts: RunOptions = {}): LintReport {\n const config = loadLintConfig(repoRoot);\n const ctx: LintContext = { repoRoot, config };\n const filtered = ALL_LINTERS.filter((l) => {\n if (opts.only && !opts.only.includes(l.id)) return false;\n if (opts.pillar && !l.pillars.includes(opts.pillar) && !l.pillars.includes(\"all\")) return false;\n return true;\n });\n const issues: LintIssue[] = [];\n for (const linter of filtered) {\n try {\n issues.push(...linter.run(repoRoot, ctx));\n } catch (err) {\n issues.push({\n linter: linter.id,\n severity: \"error\",\n file: \"<internal>\",\n message: `linter crashed: ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n }\n const errors = issues.filter((i) => i.severity === \"error\").length;\n const warnings = issues.filter((i) => i.severity === \"warning\").length;\n return {\n version: 1,\n summary: { errors, warnings, pass: errors === 0 },\n issues,\n };\n}\n\nfunction suggestedSkillsFor(linterId: string): ReadonlyArray<string> {\n const linter = ALL_LINTERS.find((l) => l.id === linterId);\n return linter?.suggestedSkills ?? [];\n}\n\nexport function formatReportText(report: LintReport): string {\n const lines: string[] = [];\n for (const issue of report.issues) {\n const location = issue.line !== undefined ? `:${issue.line}` : \"\";\n lines.push(`${issue.file}${location}: ${issue.severity}[${issue.linter}]\\n ${issue.message}`);\n const hints = suggestedSkillsFor(issue.linter);\n if (hints.length > 0) {\n lines.push(` → Try: ${hints.join(\", \")}`);\n }\n }\n const { errors, warnings, pass } = report.summary;\n lines.push(\"\");\n lines.push(\n `${errors} ${errors === 1 ? \"error\" : \"errors\"}, ${warnings} ${warnings === 1 ? \"warning\" : \"warnings\"}. ${pass ? \"✔ CI passes.\" : \"✘ CI fails.\"}`,\n );\n return lines.join(\"\\n\");\n}\n\nexport type { HarnessLintConfig } from \"./config.js\";\nexport { loadLintConfig } from \"./config.js\";\nexport type { LintContext, Linter, LintIssue, LintReport, Severity } from \"./types.js\";\n"],"mappings":"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","names":["existsSync","join","fg","join","fg","existsSync","existsSync","join","fg","fg","existsSync","join","fg","fg","REQUIRED_SECTIONS","REQUIRED_SECTIONS","fg","TRACKED_DIRS","fg"]}
@@ -0,0 +1,247 @@
1
+ import { z } from 'zod';
2
+
3
+ interface ParsedFile<T> {
4
+ meta: T;
5
+ body: string;
6
+ sourcePath: string;
7
+ }
8
+
9
+ declare const SkillFrontmatterSchema: z.ZodObject<{
10
+ id: z.ZodString;
11
+ description: z.ZodString;
12
+ engines: z.ZodOptional<z.ZodArray<z.ZodEnum<["claude-code", "codex-cli", "opencode"]>, "many">>;
13
+ requires: z.ZodOptional<z.ZodArray<z.ZodEnum<["multi-step", "slash-command", "inline-exec"]>, "many">>;
14
+ tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
15
+ }, "strict", z.ZodTypeAny, {
16
+ id: string;
17
+ description: string;
18
+ engines?: ("claude-code" | "codex-cli" | "opencode")[] | undefined;
19
+ requires?: ("multi-step" | "slash-command" | "inline-exec")[] | undefined;
20
+ tags?: string[] | undefined;
21
+ }, {
22
+ id: string;
23
+ description: string;
24
+ engines?: ("claude-code" | "codex-cli" | "opencode")[] | undefined;
25
+ requires?: ("multi-step" | "slash-command" | "inline-exec")[] | undefined;
26
+ tags?: string[] | undefined;
27
+ }>;
28
+ type SkillFrontmatter = z.infer<typeof SkillFrontmatterSchema>;
29
+ declare const CmdArgSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
30
+ name: z.ZodString;
31
+ type: z.ZodLiteral<"enum">;
32
+ values: z.ZodArray<z.ZodString, "many">;
33
+ default: z.ZodOptional<z.ZodString>;
34
+ }, "strict", z.ZodTypeAny, {
35
+ values: string[];
36
+ type: "enum";
37
+ name: string;
38
+ default?: string | undefined;
39
+ }, {
40
+ values: string[];
41
+ type: "enum";
42
+ name: string;
43
+ default?: string | undefined;
44
+ }>, z.ZodObject<{
45
+ name: z.ZodString;
46
+ type: z.ZodLiteral<"string">;
47
+ default: z.ZodOptional<z.ZodString>;
48
+ }, "strict", z.ZodTypeAny, {
49
+ type: "string";
50
+ name: string;
51
+ default?: string | undefined;
52
+ }, {
53
+ type: "string";
54
+ name: string;
55
+ default?: string | undefined;
56
+ }>]>;
57
+ type CmdArg = z.infer<typeof CmdArgSchema>;
58
+ declare const CmdFrontmatterSchema: z.ZodObject<{
59
+ id: z.ZodString;
60
+ trigger: z.ZodString;
61
+ invokes_skill: z.ZodString;
62
+ args: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
63
+ name: z.ZodString;
64
+ type: z.ZodLiteral<"enum">;
65
+ values: z.ZodArray<z.ZodString, "many">;
66
+ default: z.ZodOptional<z.ZodString>;
67
+ }, "strict", z.ZodTypeAny, {
68
+ values: string[];
69
+ type: "enum";
70
+ name: string;
71
+ default?: string | undefined;
72
+ }, {
73
+ values: string[];
74
+ type: "enum";
75
+ name: string;
76
+ default?: string | undefined;
77
+ }>, z.ZodObject<{
78
+ name: z.ZodString;
79
+ type: z.ZodLiteral<"string">;
80
+ default: z.ZodOptional<z.ZodString>;
81
+ }, "strict", z.ZodTypeAny, {
82
+ type: "string";
83
+ name: string;
84
+ default?: string | undefined;
85
+ }, {
86
+ type: "string";
87
+ name: string;
88
+ default?: string | undefined;
89
+ }>]>, "many">>;
90
+ description: z.ZodString;
91
+ }, "strict", z.ZodTypeAny, {
92
+ id: string;
93
+ description: string;
94
+ trigger: string;
95
+ invokes_skill: string;
96
+ args?: ({
97
+ values: string[];
98
+ type: "enum";
99
+ name: string;
100
+ default?: string | undefined;
101
+ } | {
102
+ type: "string";
103
+ name: string;
104
+ default?: string | undefined;
105
+ })[] | undefined;
106
+ }, {
107
+ id: string;
108
+ description: string;
109
+ trigger: string;
110
+ invokes_skill: string;
111
+ args?: ({
112
+ values: string[];
113
+ type: "enum";
114
+ name: string;
115
+ default?: string | undefined;
116
+ } | {
117
+ type: "string";
118
+ name: string;
119
+ default?: string | undefined;
120
+ })[] | undefined;
121
+ }>;
122
+ type CmdFrontmatter = z.infer<typeof CmdFrontmatterSchema>;
123
+ declare const AgentFrontmatterSchema: z.ZodObject<{
124
+ id: z.ZodEnum<["coding", "review", "merge", "planning"]>;
125
+ description: z.ZodString;
126
+ }, "strict", z.ZodTypeAny, {
127
+ id: "coding" | "review" | "merge" | "planning";
128
+ description: string;
129
+ }, {
130
+ id: "coding" | "review" | "merge" | "planning";
131
+ description: string;
132
+ }>;
133
+ type AgentFrontmatter = z.infer<typeof AgentFrontmatterSchema>;
134
+ declare const Schemas: {
135
+ readonly Skill: z.ZodObject<{
136
+ id: z.ZodString;
137
+ description: z.ZodString;
138
+ engines: z.ZodOptional<z.ZodArray<z.ZodEnum<["claude-code", "codex-cli", "opencode"]>, "many">>;
139
+ requires: z.ZodOptional<z.ZodArray<z.ZodEnum<["multi-step", "slash-command", "inline-exec"]>, "many">>;
140
+ tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
141
+ }, "strict", z.ZodTypeAny, {
142
+ id: string;
143
+ description: string;
144
+ engines?: ("claude-code" | "codex-cli" | "opencode")[] | undefined;
145
+ requires?: ("multi-step" | "slash-command" | "inline-exec")[] | undefined;
146
+ tags?: string[] | undefined;
147
+ }, {
148
+ id: string;
149
+ description: string;
150
+ engines?: ("claude-code" | "codex-cli" | "opencode")[] | undefined;
151
+ requires?: ("multi-step" | "slash-command" | "inline-exec")[] | undefined;
152
+ tags?: string[] | undefined;
153
+ }>;
154
+ readonly Cmd: z.ZodObject<{
155
+ id: z.ZodString;
156
+ trigger: z.ZodString;
157
+ invokes_skill: z.ZodString;
158
+ args: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
159
+ name: z.ZodString;
160
+ type: z.ZodLiteral<"enum">;
161
+ values: z.ZodArray<z.ZodString, "many">;
162
+ default: z.ZodOptional<z.ZodString>;
163
+ }, "strict", z.ZodTypeAny, {
164
+ values: string[];
165
+ type: "enum";
166
+ name: string;
167
+ default?: string | undefined;
168
+ }, {
169
+ values: string[];
170
+ type: "enum";
171
+ name: string;
172
+ default?: string | undefined;
173
+ }>, z.ZodObject<{
174
+ name: z.ZodString;
175
+ type: z.ZodLiteral<"string">;
176
+ default: z.ZodOptional<z.ZodString>;
177
+ }, "strict", z.ZodTypeAny, {
178
+ type: "string";
179
+ name: string;
180
+ default?: string | undefined;
181
+ }, {
182
+ type: "string";
183
+ name: string;
184
+ default?: string | undefined;
185
+ }>]>, "many">>;
186
+ description: z.ZodString;
187
+ }, "strict", z.ZodTypeAny, {
188
+ id: string;
189
+ description: string;
190
+ trigger: string;
191
+ invokes_skill: string;
192
+ args?: ({
193
+ values: string[];
194
+ type: "enum";
195
+ name: string;
196
+ default?: string | undefined;
197
+ } | {
198
+ type: "string";
199
+ name: string;
200
+ default?: string | undefined;
201
+ })[] | undefined;
202
+ }, {
203
+ id: string;
204
+ description: string;
205
+ trigger: string;
206
+ invokes_skill: string;
207
+ args?: ({
208
+ values: string[];
209
+ type: "enum";
210
+ name: string;
211
+ default?: string | undefined;
212
+ } | {
213
+ type: "string";
214
+ name: string;
215
+ default?: string | undefined;
216
+ })[] | undefined;
217
+ }>;
218
+ readonly Agent: z.ZodObject<{
219
+ id: z.ZodEnum<["coding", "review", "merge", "planning"]>;
220
+ description: z.ZodString;
221
+ }, "strict", z.ZodTypeAny, {
222
+ id: "coding" | "review" | "merge" | "planning";
223
+ description: string;
224
+ }, {
225
+ id: "coding" | "review" | "merge" | "planning";
226
+ description: string;
227
+ }>;
228
+ };
229
+ declare class ParseError extends Error {
230
+ readonly file: string;
231
+ readonly issues: z.ZodIssue[];
232
+ constructor(file: string, issues: z.ZodIssue[]);
233
+ }
234
+
235
+ type Agent = ParsedFile<AgentFrontmatter>;
236
+ declare function parseAgent(filePath: string, source: string): Agent;
237
+ declare function parseAgentFile(filePath: string): Agent;
238
+
239
+ type Cmd = ParsedFile<CmdFrontmatter>;
240
+ declare function parseCmd(filePath: string, source: string): Cmd;
241
+ declare function parseCmdFile(filePath: string): Cmd;
242
+
243
+ type Skill = ParsedFile<SkillFrontmatter>;
244
+ declare function parseSkill(filePath: string, source: string): Skill;
245
+ declare function parseSkillFile(filePath: string): Skill;
246
+
247
+ export { type Agent, type AgentFrontmatter, type Cmd, type CmdArg, type CmdFrontmatter, ParseError, type ParsedFile, Schemas, type Skill, type SkillFrontmatter, parseAgent, parseAgentFile, parseCmd, parseCmdFile, parseSkill, parseSkillFile };
@@ -0,0 +1,114 @@
1
+ // src/parser/common.ts
2
+ import { readFileSync } from "fs";
3
+ import matter from "gray-matter";
4
+
5
+ // src/parser/schemas.ts
6
+ import { z } from "zod";
7
+
8
+ // src/types.ts
9
+ var AGENT_IDS = ["coding", "review", "merge", "planning"];
10
+ var ENGINES = ["claude-code", "codex-cli", "opencode"];
11
+ var CAPABILITIES = ["multi-step", "slash-command", "inline-exec"];
12
+
13
+ // src/parser/schemas.ts
14
+ var IdSchema = z.string().min(1).regex(/^[a-z][a-z0-9-]*$/, "id must be kebab-case (lowercase + digits + hyphens)");
15
+ var SkillFrontmatterSchema = z.object({
16
+ id: IdSchema,
17
+ description: z.string().min(1),
18
+ engines: z.array(z.enum(ENGINES)).min(1).optional(),
19
+ requires: z.array(z.enum(CAPABILITIES)).optional(),
20
+ tags: z.array(z.string()).optional()
21
+ }).strict();
22
+ var CmdArgEnumSchema = z.object({
23
+ name: z.string().min(1),
24
+ type: z.literal("enum"),
25
+ values: z.array(z.string()).min(1),
26
+ default: z.string().optional()
27
+ }).strict();
28
+ var CmdArgStringSchema = z.object({
29
+ name: z.string().min(1),
30
+ type: z.literal("string"),
31
+ default: z.string().optional()
32
+ }).strict();
33
+ var CmdArgSchema = z.discriminatedUnion("type", [CmdArgEnumSchema, CmdArgStringSchema]);
34
+ var CmdFrontmatterSchema = z.object({
35
+ id: IdSchema,
36
+ trigger: z.string().regex(/^\/[a-z][a-z0-9-]*$/, "trigger must be /kebab-case"),
37
+ invokes_skill: IdSchema,
38
+ args: z.array(CmdArgSchema).optional(),
39
+ description: z.string().min(1)
40
+ }).strict();
41
+ var AgentFrontmatterSchema = z.object({
42
+ id: z.enum(AGENT_IDS),
43
+ description: z.string().min(1)
44
+ }).strict();
45
+ var Schemas = {
46
+ Skill: SkillFrontmatterSchema,
47
+ Cmd: CmdFrontmatterSchema,
48
+ Agent: AgentFrontmatterSchema
49
+ };
50
+ var ParseError = class extends Error {
51
+ constructor(file, issues) {
52
+ const messages = issues.map((i) => ` - ${i.path.join(".") || "<root>"}: ${i.message}`).join("\n");
53
+ super(`Frontmatter validation failed for ${file}:
54
+ ${messages}`);
55
+ this.file = file;
56
+ this.issues = issues;
57
+ this.name = "ParseError";
58
+ }
59
+ file;
60
+ issues;
61
+ };
62
+
63
+ // src/parser/common.ts
64
+ function parseWithSchema(filePath, source, schema) {
65
+ const parsed = matter(source);
66
+ const result = schema.safeParse(parsed.data);
67
+ if (!result.success) {
68
+ throw new ParseError(filePath, result.error.issues);
69
+ }
70
+ return {
71
+ meta: result.data,
72
+ body: parsed.content.trim(),
73
+ sourcePath: filePath
74
+ };
75
+ }
76
+ function parseFileWithSchema(filePath, schema) {
77
+ const source = readFileSync(filePath, "utf8");
78
+ return parseWithSchema(filePath, source, schema);
79
+ }
80
+
81
+ // src/parser/agent.ts
82
+ function parseAgent(filePath, source) {
83
+ return parseWithSchema(filePath, source, Schemas.Agent);
84
+ }
85
+ function parseAgentFile(filePath) {
86
+ return parseFileWithSchema(filePath, Schemas.Agent);
87
+ }
88
+
89
+ // src/parser/cmd.ts
90
+ function parseCmd(filePath, source) {
91
+ return parseWithSchema(filePath, source, Schemas.Cmd);
92
+ }
93
+ function parseCmdFile(filePath) {
94
+ return parseFileWithSchema(filePath, Schemas.Cmd);
95
+ }
96
+
97
+ // src/parser/skill.ts
98
+ function parseSkill(filePath, source) {
99
+ return parseWithSchema(filePath, source, Schemas.Skill);
100
+ }
101
+ function parseSkillFile(filePath) {
102
+ return parseFileWithSchema(filePath, Schemas.Skill);
103
+ }
104
+ export {
105
+ ParseError,
106
+ Schemas,
107
+ parseAgent,
108
+ parseAgentFile,
109
+ parseCmd,
110
+ parseCmdFile,
111
+ parseSkill,
112
+ parseSkillFile
113
+ };
114
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/parser/common.ts","../../src/parser/schemas.ts","../../src/types.ts","../../src/parser/agent.ts","../../src/parser/cmd.ts","../../src/parser/skill.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport matter from \"gray-matter\";\nimport type { z } from \"zod\";\nimport { ParseError } from \"./schemas.js\";\n\nexport interface ParsedFile<T> {\n meta: T;\n body: string;\n sourcePath: string;\n}\n\nexport function parseWithSchema<T extends z.ZodTypeAny>(\n filePath: string,\n source: string,\n schema: T,\n): ParsedFile<z.infer<T>> {\n const parsed = matter(source);\n const result = schema.safeParse(parsed.data);\n if (!result.success) {\n throw new ParseError(filePath, result.error.issues);\n }\n return {\n meta: result.data,\n body: parsed.content.trim(),\n sourcePath: filePath,\n };\n}\n\nexport function parseFileWithSchema<T extends z.ZodTypeAny>(\n filePath: string,\n schema: T,\n): ParsedFile<z.infer<T>> {\n const source = readFileSync(filePath, \"utf8\");\n return parseWithSchema(filePath, source, schema);\n}\n","import { z } from \"zod\";\nimport { AGENT_IDS, CAPABILITIES, ENGINES } from \"../types.js\";\n\nconst IdSchema = z\n .string()\n .min(1)\n .regex(/^[a-z][a-z0-9-]*$/, \"id must be kebab-case (lowercase + digits + hyphens)\");\n\nconst SkillFrontmatterSchema = z\n .object({\n id: IdSchema,\n description: z.string().min(1),\n engines: z.array(z.enum(ENGINES)).min(1).optional(),\n requires: z.array(z.enum(CAPABILITIES)).optional(),\n tags: z.array(z.string()).optional(),\n })\n .strict();\n\nexport type SkillFrontmatter = z.infer<typeof SkillFrontmatterSchema>;\n\nconst CmdArgEnumSchema = z\n .object({\n name: z.string().min(1),\n type: z.literal(\"enum\"),\n values: z.array(z.string()).min(1),\n default: z.string().optional(),\n })\n .strict();\n\nconst CmdArgStringSchema = z\n .object({\n name: z.string().min(1),\n type: z.literal(\"string\"),\n default: z.string().optional(),\n })\n .strict();\n\nconst CmdArgSchema = z.discriminatedUnion(\"type\", [CmdArgEnumSchema, CmdArgStringSchema]);\n\nexport type CmdArg = z.infer<typeof CmdArgSchema>;\n\nconst CmdFrontmatterSchema = z\n .object({\n id: IdSchema,\n trigger: z.string().regex(/^\\/[a-z][a-z0-9-]*$/, \"trigger must be /kebab-case\"),\n invokes_skill: IdSchema,\n args: z.array(CmdArgSchema).optional(),\n description: z.string().min(1),\n })\n .strict();\n\nexport type CmdFrontmatter = z.infer<typeof CmdFrontmatterSchema>;\n\nconst AgentFrontmatterSchema = z\n .object({\n id: z.enum(AGENT_IDS),\n description: z.string().min(1),\n })\n .strict();\n\nexport type AgentFrontmatter = z.infer<typeof AgentFrontmatterSchema>;\n\nexport const Schemas = {\n Skill: SkillFrontmatterSchema,\n Cmd: CmdFrontmatterSchema,\n Agent: AgentFrontmatterSchema,\n} as const;\n\nexport class ParseError extends Error {\n constructor(\n public readonly file: string,\n public readonly issues: z.ZodIssue[],\n ) {\n const messages = issues\n .map((i) => ` - ${i.path.join(\".\") || \"<root>\"}: ${i.message}`)\n .join(\"\\n\");\n super(`Frontmatter validation failed for ${file}:\\n${messages}`);\n this.name = \"ParseError\";\n }\n}\n","export const AGENT_IDS = [\"coding\", \"review\", \"merge\", \"planning\"] as const;\nexport type AgentId = (typeof AGENT_IDS)[number];\n\nexport const ENGINES = [\"claude-code\", \"codex-cli\", \"opencode\"] as const;\nexport type Engine = (typeof ENGINES)[number];\n\nexport const ENGINE_ROOT_DIR: Record<Engine, string> = {\n \"claude-code\": \".claude\",\n \"codex-cli\": \".codex\",\n opencode: \".opencode\",\n};\n\nexport const CAPABILITIES = [\"multi-step\", \"slash-command\", \"inline-exec\"] as const;\nexport type Capability = (typeof CAPABILITIES)[number];\n\nexport interface RenderedFile {\n path: string;\n content: string;\n}\n\nexport interface CapabilitiesMatrix {\n [engine: string]: ReadonlyArray<Capability>;\n}\n\nexport const CAPABILITIES_MATRIX: Record<Engine, ReadonlyArray<Capability>> = {\n \"claude-code\": [\"multi-step\", \"slash-command\", \"inline-exec\"],\n \"codex-cli\": [\"multi-step\", \"slash-command\", \"inline-exec\"],\n opencode: [\"multi-step\", \"slash-command\", \"inline-exec\"],\n};\n\nexport const DEGRADED_CAPABILITIES: Partial<Record<Engine, ReadonlyArray<Capability>>> = {\n \"codex-cli\": [\"multi-step\"],\n};\n\nexport function engineSupports(engine: Engine, capability: Capability): boolean {\n return CAPABILITIES_MATRIX[engine].includes(capability);\n}\n","import { parseFileWithSchema, parseWithSchema } from \"./common.js\";\nimport type { ParsedFile } from \"./common.js\";\nimport { type AgentFrontmatter, Schemas } from \"./schemas.js\";\n\nexport type Agent = ParsedFile<AgentFrontmatter>;\n\nexport function parseAgent(filePath: string, source: string): Agent {\n return parseWithSchema(filePath, source, Schemas.Agent);\n}\n\nexport function parseAgentFile(filePath: string): Agent {\n return parseFileWithSchema(filePath, Schemas.Agent);\n}\n","import { parseFileWithSchema, parseWithSchema } from \"./common.js\";\nimport type { ParsedFile } from \"./common.js\";\nimport { type CmdFrontmatter, Schemas } from \"./schemas.js\";\n\nexport type Cmd = ParsedFile<CmdFrontmatter>;\n\nexport function parseCmd(filePath: string, source: string): Cmd {\n return parseWithSchema(filePath, source, Schemas.Cmd);\n}\n\nexport function parseCmdFile(filePath: string): Cmd {\n return parseFileWithSchema(filePath, Schemas.Cmd);\n}\n","import { parseFileWithSchema, parseWithSchema } from \"./common.js\";\nimport type { ParsedFile } from \"./common.js\";\nimport { Schemas, type SkillFrontmatter } from \"./schemas.js\";\n\nexport type Skill = ParsedFile<SkillFrontmatter>;\n\nexport function parseSkill(filePath: string, source: string): Skill {\n return parseWithSchema(filePath, source, Schemas.Skill);\n}\n\nexport function parseSkillFile(filePath: string): Skill {\n return parseFileWithSchema(filePath, Schemas.Skill);\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,50 @@
1
+ import { Agent, Skill, Cmd } from './parser/index.js';
2
+
3
+ declare const MCP_SERVER_IDS: readonly ["context7"];
4
+ type McpServerId = (typeof MCP_SERVER_IDS)[number];
5
+
6
+ declare const ENGINES: readonly ["claude-code", "codex-cli", "opencode"];
7
+ type Engine = (typeof ENGINES)[number];
8
+ interface RenderedFile {
9
+ path: string;
10
+ content: string;
11
+ }
12
+
13
+ interface Harness {
14
+ agents: ReadonlyArray<Agent>;
15
+ skills: ReadonlyArray<Skill>;
16
+ cmds: ReadonlyArray<Cmd>;
17
+ }
18
+ interface HarnessOverrides {
19
+ add?: Partial<Harness>;
20
+ disable?: ReadonlyArray<string>;
21
+ }
22
+ interface RenderInput {
23
+ harness: Harness;
24
+ engines: ReadonlyArray<Engine>;
25
+ overrides?: HarnessOverrides;
26
+ projectSkills?: ReadonlyArray<Skill>;
27
+ /** True when the target project ships `docs/quality/code-quality.md` (optional pillar). */
28
+ hasQualityDoc?: boolean;
29
+ mcpServers?: ReadonlyArray<McpServerId>;
30
+ /**
31
+ * When true (default), each engine's renderer emits a Stop-hook config
32
+ * that calls `vaubaan-harness stop-hook --engine <engine>` and injects
33
+ * the lint report (with skill suggestions) into the running session
34
+ * whenever the worktree is dirty and lint fails. Pass `false` to skip
35
+ * the hook configs entirely (kill-switch at install time; runtime
36
+ * kill-switch is `HARNESS_LINT_DISABLE=1`).
37
+ */
38
+ withStopHook?: boolean;
39
+ }
40
+ interface RenderOutput {
41
+ files: RenderedFile[];
42
+ warnings: string[];
43
+ }
44
+ declare class RenderError extends Error {
45
+ constructor(message: string);
46
+ }
47
+ declare function applyOverrides(harness: Harness, overrides: HarnessOverrides | undefined): Harness;
48
+ declare function render(input: RenderInput): RenderOutput;
49
+
50
+ export { type Engine as E, type Harness as H, RenderError as R, type HarnessOverrides as a, type RenderInput as b, type RenderOutput as c, type RenderedFile as d, applyOverrides as e, render as r };
@@ -0,0 +1,3 @@
1
+ export { H as Harness, a as HarnessOverrides, R as RenderError, b as RenderInput, c as RenderOutput, e as applyOverrides, r as render } from './render-B9_kNtQc.js';
2
+ import './parser/index.js';
3
+ import 'zod';