Workbench
Gurki Markdown is canonical. JSON is a generated interchange surface. Optional AI analysis lives in a separate sidecar and never replaces source text.
Other projects use the gurki package: a CLI, a TypeScript library, keywords.json, and an agent mixin skill. The language page is the human introduction; the specification is the contract.
Install
npm install gurkiNode 20 or later. The package is ESM only.
npx gurki lint path/to/specs
npx gurki encode file.spec.md
npx gurki decode file.json --analysis analysis.jsonCLI
| Command | Role |
|---|---|
lint | Syntax, frontmatter, continuation, order, Activates warnings |
encode | Gurki → validated GurkiDocument JSON IR |
decode | JSON IR → canonical Gurki Markdown, plus net sections with --analysis |
analysis check | Validate an AI sidecar + optional source digest and ledger units |
compare | Side-by-side structural comparison by step kind |
skill | Install the mixin skill into Cursor, Claude Code, or Pi |
gurki lint examples
gurki encode file.spec.md --out doc.json
gurki decode doc.json --out file.spec.md --analysis analysis.json
gurki analysis check analysis.json file.spec.md
gurki compare a.spec.md b.spec.md
gurki skill --harness allFree-text steps are not declared equivalent by compare. That is deliberate. Attach validated analysis sidecars with --analysis when an agent has normalised measures.
Library
Most projects need three calls: parse, lint, format.
import { parseGurki, lintDocument, formatDocument } from 'gurki'
const parsed = parseGurki(source, { path: 'policy.spec.md' })
const lint = lintDocument(parsed.document, parsed.diagnostics)
if (lint.errors.length > 0) {
throw new Error(lint.errors.map((d) => d.message).join('\n'))
}
const canonical = formatDocument(parsed.document)parseFile(path) reads from disk. parseGurki(source) takes a string and does not need the filesystem.
| Export | Role |
|---|---|
parseGurki, parseFile | Source → GurkiDocument IR + diagnostics |
lintDocument, buildScenarioIndex | Cross-file Activates and lifecycle checks |
formatDocument | IR → canonical Markdown (decode) |
compareDocuments, formatCompareResult | Structural side-by-side by step kind |
checkAnalysis, parseDocumentJson | Sidecar + JSON IR validation |
valueReport, netReport | Derived listings and ledger rollups |
GurkiDocumentZ, GurkiAnalysisZ, LedgerEntryZ | Zod schemas for the IR and sidecar |
keywords, STEP_KINDS, SCHEMA_VERSION | Closed tables and version |
import { GurkiDocumentZ, keywords } from 'gurki'
import table from 'gurki/keywords.json' with { type: 'json' }The CLI is a thin wrapper over these functions. Do not import gurki/dist/... internals; they are not a contract.
Mixin skill
The skill names the language and points at the CLI and schemas. Compose it with other skills; it does not lock you into a workflow. There is no embedded model runtime — the host harness supplies the model when normalising text into analysis sidecars.
npx gurki skill # project-scoped Cursor install
npx gurki skill --harness all # Cursor + Claude Code + Pi
npx gurki skill --scope global --forceInside this repository, pnpm install-skill is the same command.
What the package does not include
The published tarball is the language workbench. It does not include:
- Policy Bias (NZ 2026 policy cards and corpus)
- the example specs (they live in the repository and on the examples page)