Last updated: v2.1.0
The public contract lives at plugins/dotbabel/src/index.mjs — import from
the package root, not deep paths:
import {
createHarnessContext,
validateSpecs,
validateManifest,
refreshChecksums,
checkSpecCoverage,
checkInstructionDrift,
scaffoldHarness,
ValidationError,
ERROR_CODES,
formatError,
EXIT_CODES,
version,
// spec-harness helpers
readJson,
readText,
pathExists,
git,
loadFacts,
listSpecDirs,
listRepoPaths,
escapeRegex,
globToRegExp,
matchesGlob,
anyPathMatches,
toPosix,
extractTemplateSection,
isMeaningfulSection,
getPullRequestContext,
isBotActor,
getChangedFiles,
} from "@dotbabel/dotbabel";
Every symbol is documented with JSDoc in-source. Run
node scripts/check-jsdoc-coverage.mjs plugins/dotbabel/src in the repo to
assert coverage is complete.
import { createHarnessContext, validateSpecs, formatError } from "@dotbabel/dotbabel";
const ctx = createHarnessContext(); // resolves repo root via git or DOTBABEL_REPO_ROOT
const { ok, errors } = validateSpecs(ctx);
if (!ok) {
for (const err of errors) {
console.error(formatError(err, { verbose: true }));
// err.code — stable enum (see ERROR_CODES)
// err.file — repo-relative path
// err.pointer — JSON pointer for structured files
// err.hint — actionable remediation
}
process.exit(1);
}
@typedefs)HarnessContext — { repoRoot, specsRoot, manifestPath, factsPath },
the context threaded through every validator.ValidationResult — { ok: boolean, errors: ValidationError[] }.StructuredError — the ValidationError object shape with
code, message, optional file, pointer, line, expected, got,
hint, category.PullRequestContext — { isPullRequest, body, actor }, the shape
getPullRequestContext() returns.See ERROR_CODES for the full list (it’s Object.freezed). Renames are
breaking changes; additions are not. Enumerated families:
SPEC_JSON_INVALID, SPEC_STATUS_INVALID,
SPEC_MISSING_REQUIRED_FIELD, SPEC_ID_MISMATCH,
SPEC_LINKED_PATH_MISSING, SPEC_ACCEPTANCE_EMPTY,
SPEC_DEPENDENCY_UNKNOWN.SKILL_FRONTMATTER_MISSING, SKILL_NAME_MISMATCH.MANIFEST_ENTRY_MISSING, MANIFEST_CHECKSUM_MISMATCH,
MANIFEST_ORPHAN_FILE, MANIFEST_DEPENDENCY_CYCLE.COVERAGE_UNCOVERED, COVERAGE_NO_SPEC_RATIONALE,
COVERAGE_UNKNOWN_SPEC_ID.DRIFT_TEAM_COUNT, DRIFT_PROTECTED_PATH,
DRIFT_INSTRUCTION_FILES, DRIFT_INSTRUCTION_FILE_MISSING.SCAFFOLD_CONFLICT, SCAFFOLD_USAGE.SETTINGS_SEC_1..SETTINGS_SEC_4,
SETTINGS_OPS_1, SETTINGS_OPS_2.ENV_REPO_ROOT_UNKNOWN, ENV_FACTS_MISSING,
USAGE_UNKNOWN_FLAG, USAGE_MISSING_POSITIONAL.EXIT_CODES = { OK:0, VALIDATION:1, ENV:2, USAGE:64 }. Use these instead
of string-matching error messages.
A few commonly-reached-for modules are also exposed as sub-paths in
package.json.exports:
import { ValidationError, ERROR_CODES } from "@dotbabel/dotbabel/errors";
import { EXIT_CODES } from "@dotbabel/dotbabel/exit-codes";
Deep imports beyond these three subpaths are not part of the public
contract; any reshuffle inside src/ can happen in a minor bump.
version is the package version at import time (read from the installed
package.json). Consumers can gate on it:
import { version } from "@dotbabel/dotbabel";
if (!version.startsWith("0.2.")) throw new Error(`unsupported harness: ${version}`);
Semver: minor bumps add new codes/bins. Major bumps can rename codes or
remove bins. ValidationError.prototype.toString() keeps the
"<file>: <message>" format across minor bumps so stderr-grep pipelines
don’t break.