@nikovirtala/adr 0.0.0 → 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","names":[],"sources":["../src/cli/open.ts","../src/cli/text.ts","../src/cli/accept.ts","../src/cli/list.ts","../src/cli/editor.ts","../src/cli/new.ts","../src/cli/show.ts","../src/cli/supersede.ts","../src/cli/commands.ts","../src/cli.ts"],"sourcesContent":["import type { CliIO, GlobalFlags } from \"@nikovirtala/ledger/cli\";\nimport { type DecisionLog, openDecisionLog, readDecisions } from \"../log.js\";\nimport type { Display } from \"./text.js\";\n\n/**\n * The decision log a command works on: `--root` and `--ref` from the globals, git run with the\n * CLI's environment.\n */\nexport function openForCli(\n io: CliIO,\n flags: GlobalFlags,\n o: { readonly reader?: \"worktree\" | \"index\" } = {},\n): Promise<DecisionLog> {\n return openDecisionLog({\n cwd: io.cwd,\n root: flags.root,\n ref: flags.ref,\n ...(o.reader === undefined ? {} : { reader: o.reader }),\n gitOptions: { env: io.env },\n });\n}\n\n/**\n * How other decisions display in a write's text, read again from the work tree, like the write\n * result's own views: a commit on the main ref has numbered the decisions it accepted.\n */\nexport async function displayAfterWrite(log: DecisionLog): Promise<{ readonly display: Display }> {\n const read = await readDecisions(log);\n return { display: (id) => read.projection.views.get(id)?.display ?? id };\n}\n\n/** `--commit`/`--no-commit` when given, else `[policy] auto_commit`. */\nexport function commitRequested(log: DecisionLog, values: Readonly<Record<string, unknown>>) {\n return typeof values.commit === \"boolean\" ? values.commit : log.adr.autoCommit;\n}\n","import { type EventEnvelope, type Finding, renderStateHeader } from \"@nikovirtala/ledger\";\nimport type { DecisionView } from \"../kind.js\";\nimport type { DecisionListJson, DecisionShowJson } from \"../views.js\";\nimport type { WriteResultJson } from \"../write.js\";\n\n/** How a decision id is shown: its display (`ADR-0007`), or the id when it has no number. */\nexport type Display = (id: string) => string;\n\n/** A table: each column padded to its widest value, trailing spaces removed. */\nfunction columns(rows: readonly (readonly string[])[]): string {\n const widths: number[] = [];\n for (const row of rows) {\n row.forEach((cell, i) => {\n widths[i] = Math.max(widths[i] ?? 0, cell.length);\n });\n }\n return rows\n .map((row) =>\n row\n .map((cell, i) => (i === row.length - 1 ? cell : cell.padEnd(widths[i] ?? 0)))\n .join(\" \")\n .trimEnd(),\n )\n .join(\"\\n\");\n}\n\n/** `adr list`: one row per decision, `→ <effective>` when it differs from the decision. */\nexport function listText(doc: DecisionListJson, display: Display): string {\n if (doc.decisions.length === 0) return \"No decisions.\";\n return columns(\n doc.decisions.map((v) => {\n const arrow =\n v.effective === null\n ? \"→ (cycle)\"\n : v.effective === v.id\n ? \"\"\n : `→ ${display(v.effective)}`;\n return [v.number === null ? \"-\" : v.display, v.id, v.status, v.title, arrow];\n }),\n );\n}\n\n/** `ADR-0003 (m2x7p4d2)`, or the id alone when it has no number. */\nfunction named(id: string, display: Display): string {\n const shown = display(id);\n return shown === id ? id : `${shown} (${id})`;\n}\n\nconst day = (at: string | null) => (at ?? \"\").slice(0, 10);\nconst list = (ids: readonly string[], display: Display) =>\n ids.length === 0 ? \"none\" : ids.map((id) => named(id, display)).join(\", \");\n\nfunction bodyLine(v: DecisionView): string {\n if (v.body_path === null) return \"missing\";\n if (v.body_intact === null) return v.body_path;\n return `${v.body_path} (${v.body_intact ? \"intact\" : \"changed after acceptance\"})`;\n}\n\nfunction actorText(e: EventEnvelope): string {\n const a = e.actor;\n return a.kind === \"agent\" ? `${a.name} (agent ${a.agent} for ${a.on_behalf_of})` : a.name;\n}\n\n/** The second line of an event in `show --history`: its reason, else a summary of its data. */\nfunction eventDetail(e: EventEnvelope): string | null {\n if (typeof e.reason === \"string\") return `reason: ${e.reason}`;\n const entries = Object.entries(e.data);\n if (entries.length === 0) return null;\n return entries\n .map(([k, v]) => `${k}: ${typeof v === \"string\" ? v : JSON.stringify(v)}`)\n .join(\", \");\n}\n\nfunction historyLines(events: readonly EventEnvelope[]): string[] {\n const width = Math.max(...events.map((e) => e.type.length));\n return events.flatMap((e) => {\n const detail = eventDetail(e);\n return [\n ` ${e.at} ${e.type.padEnd(width)} ${actorText(e)}`,\n ...(detail === null ? [] : [` ${detail}`]),\n ];\n });\n}\n\nconst SECTION_FINDING =\n /^(?:required )?section (.+?) (is missing|is empty|still contains its guidance text)$/;\nconst REASONS: Readonly<Record<string, string>> = {\n \"is missing\": \"missing\",\n \"is empty\": \"empty\",\n \"still contains its guidance text\": \"guidance text left\",\n};\n\n/**\n * The draft lint of `new` as advice: `Fill in N sections before accepting: A, B (why)` for the\n * section findings, and one line per other finding.\n */\nfunction draftAdvice(findings: readonly Finding[]): string[] {\n const headings: string[] = [];\n const reasons: string[] = [];\n const other: string[] = [];\n for (const f of findings) {\n const m = SECTION_FINDING.exec(f.message);\n if (m === null) {\n other.push(`Draft: ${f.message} [${f.rule}]`);\n continue;\n }\n const [, heading = \"\", what = \"\"] = m;\n const reason = REASONS[what] ?? what;\n if (!headings.includes(heading)) headings.push(heading);\n if (!reasons.includes(reason)) reasons.push(reason);\n }\n const n = headings.length;\n return [\n ...(n === 0\n ? []\n : [\n `Fill in ${n === 1 ? \"1 section\" : `${n} sections`} before accepting: ${headings.join(\", \")} (${reasons.join(\", \")})`,\n ]),\n ...other,\n ];\n}\n\nfunction findingLines(findings: readonly Finding[]): string[] {\n return findings.map((f) => ` ${f.file === null ? \"\" : `${f.file}: `}${f.message} [${f.rule}]`);\n}\n\nconst short = (sha: string) => sha.slice(0, 7);\n\n/**\n * The text of `adr new|accept|supersede` (design §5.6). `subject` names what a refused command\n * was about; `number` is the decision's number in the write result, if it has one now.\n */\nexport function writeText(\n doc: WriteResultJson,\n display: Display,\n o: { readonly subject: string; readonly number: string | null },\n): string {\n const verb = { new: \"proposed\", accept: \"accepted\", supersede: \"superseded\" }[doc.command];\n if (!doc.ok) return [`Not ${verb}: ${o.subject}`, ...findingLines(doc.findings)].join(\"\\n\");\n const v = doc.decision;\n if (v === null) return \"\";\n const committed = doc.commit === null ? null : `Committed ${short(doc.commit)}`;\n switch (doc.command) {\n case \"new\":\n return [\n `Proposed ${v.id}: ${v.title}`,\n ...doc.written.map((p) => ` ${p}`),\n ...draftAdvice(doc.findings),\n ...(committed === null ? [] : [`${committed}.`]),\n `Next: adr accept ${v.id}`,\n ].join(\"\\n\");\n case \"accept\":\n return [\n `Accepted ${v.id}: ${v.title}`,\n ...doc.affected.map((a) => `Superseded ${named(a.id, display)}: ${a.title}`),\n committed === null\n ? \"Staged; commit to record it.\"\n : o.number === null\n ? `${committed}. The number is assigned when this commit lands on main.`\n : `${committed} as ${o.number}.`,\n ].join(\"\\n\");\n case \"supersede\":\n return [\n `Superseded ${named(v.id, display)}: ${v.title}`,\n ` by ${named(v.superseded_by ?? \"\", display)}`,\n committed === null ? \"Staged; commit to record it.\" : `${committed}.`,\n ].join(\"\\n\");\n }\n}\n\n/** `adr show`: the state header, the decision's fields and its body. */\nexport function showText(doc: DecisionShowJson, display: Display): string {\n const v = doc.decision;\n const supersedes =\n v.supersedes.length === 0 && v.declared_supersedes.length > 0\n ? `none (declared: ${list(v.declared_supersedes, display)})`\n : list(v.supersedes, display);\n const fields: [string, string][] = [\n [\"Title\", v.title],\n [\"Status\", `${v.status} (${day(v.status_at)})`],\n [\"Effective\", v.effective === null ? \"none (supersession cycle)\" : named(v.effective, display)],\n [\"Chain\", v.chain.map(display).join(\" → \")],\n [\"Supersedes\", supersedes],\n [\"Applies to\", v.applies_to.length === 0 ? \"none\" : v.applies_to.join(\", \")],\n [\"Body\", bodyLine(v)],\n ];\n if (doc.events === null) fields.push([\"History\", v.history.join(\" · \")]);\n const width = Math.max(...fields.map(([k]) => k.length)) + 2;\n const lines = fields.map(([k, value]) => `${`${k}:`.padEnd(width)}${value}`);\n if (doc.events !== null) lines.push(\"History:\", ...historyLines(doc.events));\n const body = doc.body === null ? \"\" : `\\n${doc.body.endsWith(\"\\n\") ? doc.body : `${doc.body}\\n`}`;\n return `${renderStateHeader(doc.header)}\\n${lines.join(\"\\n\")}\\n${body}`;\n}\n","import { type JsonValue, resolveActor } from \"@nikovirtala/ledger\";\nimport type { CommandSpec } from \"@nikovirtala/ledger/cli\";\nimport { acceptDecision } from \"../write.js\";\nimport { commitRequested, displayAfterWrite, openForCli } from \"./open.js\";\nimport { writeText } from \"./text.js\";\n\n/** `adr accept <decision> [--commit | --no-commit]` (design §5.6). */\nexport const acceptCommand: CommandSpec = {\n name: \"accept\",\n summary: \"accept a proposed decision, superseding the decisions it declares\",\n usage: \"accept <decision> [--commit | --no-commit]\",\n options: { commit: { type: \"boolean\" } },\n positionals: { min: 1, max: 1, names: [\"decision\"] },\n ref: \"reject\",\n async run({ io, flags, values, positionals }) {\n const input = positionals[0] ?? \"\";\n const log = await openForCli(io, flags);\n const actor = await resolveActor(log.git, { env: io.env });\n const doc = await acceptDecision(\n log,\n { id: input, actor },\n { commit: commitRequested(log, values) },\n );\n const { display } = await displayAfterWrite(log);\n const v = doc.decision;\n return {\n exit: doc.ok ? 0 : 1,\n json: doc as unknown as JsonValue,\n text: writeText(doc, display, {\n subject: v === null ? input.trim() : `${display(v.id)}: ${v.title}`,\n number: v === null || doc.commit === null || v.number === null ? null : v.display,\n }),\n notes: doc.notes,\n };\n },\n};\n","import { type JsonValue, UsageError } from \"@nikovirtala/ledger\";\nimport type { CommandSpec } from \"@nikovirtala/ledger/cli\";\nimport { DECISION_STATUSES, type DecisionStatus } from \"../kind.js\";\nimport { readDecisions, unavailableReason } from \"../log.js\";\nimport { listDecisions } from \"../views.js\";\nimport { openForCli } from \"./open.js\";\nimport { listText } from \"./text.js\";\n\nconst plural = (n: number, one: string, many: string) => (n === 1 ? `1 ${one}` : `${n} ${many}`);\n\nfunction statuses(values: Readonly<Record<string, unknown>>): DecisionStatus[] {\n const given = Array.isArray(values.status) ? (values.status as string[]) : [];\n return given.map((s) => {\n if (!(DECISION_STATUSES as readonly string[]).includes(s)) {\n throw new UsageError(\n `unknown status ${JSON.stringify(s)}; use one of ${DECISION_STATUSES.join(\", \")}`,\n );\n }\n return s as DecisionStatus;\n });\n}\n\n/** `adr list [--status <status>]…` (design §5.6). */\nexport const listCommand: CommandSpec = {\n name: \"list\",\n summary: \"list decisions with their computed status\",\n usage: \"list [--status <status>]…\",\n options: { status: { type: \"string\", multiple: true } },\n positionals: { min: 0, max: 0, names: [] },\n ref: \"read\",\n async run({ io, flags, values }) {\n const status = statuses(values);\n const read = await readDecisions(await openForCli(io, flags));\n const doc = listDecisions(read, { status });\n const notes = [...doc.notes];\n if (!read.numbering.available && doc.decisions.length > 0) {\n notes.push(\n `numbers are unavailable (${unavailableReason(read.numbering)}); decisions display by id`,\n );\n }\n if (doc.findings.length > 0) {\n notes.push(\n `the decision log has ${plural(doc.findings.length, \"problem\", \"problems\")}; run adr verify`,\n );\n }\n if (doc.unreadable.length > 0) {\n notes.push(\n `${plural(doc.unreadable.length, \"decision uses\", \"decisions use\")} a newer format; upgrade adr`,\n );\n }\n if (doc.unfoldable.length > 0) {\n notes.push(\n `${plural(doc.unfoldable.length, \"decision\", \"decisions\")} can't be read; run adr verify`,\n );\n }\n const display = (id: string) => read.projection.views.get(id)?.display ?? id;\n return { exit: 0, json: doc as unknown as JsonValue, text: listText(doc, display), notes };\n },\n};\n","import { spawn } from \"node:child_process\";\n\n/** The `edit` callback of `proposeDecision`: `null` when the editor exited 0, else a note. */\nexport type Edit = (absPath: string) => Promise<string | null>;\n\n/**\n * The user's editor as an `edit` callback (design §5.7), or `null` when neither `VISUAL` nor\n * `EDITOR` is set. The editor string is run by `sh -c` the way git runs `core.editor`, with the\n * path as the positional parameter `$1`, never interpolated. When stdout isn't a TTY (piped\n * `--json`, say), the editor's stdout goes to stderr so the CLI's stdout stays one document.\n * The callback never throws: a spawn error or a non-zero exit becomes the note.\n */\nexport function editorFor(\n env: NodeJS.ProcessEnv,\n o: { readonly stdoutIsTTY: boolean },\n): Edit | null {\n const editor = [env.VISUAL, env.EDITOR].map((v) => v?.trim() ?? \"\").find((v) => v !== \"\");\n if (editor === undefined) return null;\n return (absPath) =>\n new Promise((resolve) => {\n const fail = (e: unknown) =>\n resolve(`could not start the editor: ${e instanceof Error ? e.message : String(e)}`);\n try {\n const child = spawn(\"sh\", [\"-c\", `${editor} \"$1\"`, \"sh\", absPath], {\n env,\n stdio: o.stdoutIsTTY ? \"inherit\" : [\"inherit\", 2, \"inherit\"],\n });\n child.on(\"error\", fail);\n child.on(\"close\", (code, signal) => {\n if (code === 0) resolve(null);\n else {\n const how =\n code === null\n ? `was killed by ${signal ?? \"a signal\"}`\n : `exited with status ${code}`;\n resolve(`the editor ${how}; the draft is staged as rendered`);\n }\n });\n } catch (e) {\n fail(e);\n }\n });\n}\n","import { type JsonValue, resolveActor, UsageError } from \"@nikovirtala/ledger\";\nimport type { CommandSpec } from \"@nikovirtala/ledger/cli\";\nimport { proposeDecision } from \"../write.js\";\nimport { editorFor } from \"./editor.js\";\nimport { commitRequested, displayAfterWrite, openForCli } from \"./open.js\";\nimport { writeText } from \"./text.js\";\n\nconst strings = (v: unknown): string[] => (Array.isArray(v) ? (v as string[]) : []);\n\n/** `--section <id>=<markdown>` values, split at the first `=`; each id at most once. */\nfunction sections(values: readonly string[]): Record<string, string> {\n const out: Record<string, string> = {};\n for (const value of values) {\n const at = value.indexOf(\"=\");\n const id = at < 0 ? \"\" : value.slice(0, at).trim();\n if (id === \"\") {\n throw new UsageError(`--section needs <id>=<markdown>, not ${JSON.stringify(value)}`);\n }\n if (Object.hasOwn(out, id)) throw new UsageError(`--section ${id} is given twice`);\n out[id] = value.slice(at + 1);\n }\n return out;\n}\n\n/**\n * `adr new <title> …` (design §5.6). The editor runs with `--edit`, or without `--no-edit` when\n * the terminal is interactive and an editor is set.\n */\nexport const newCommand: CommandSpec = {\n name: \"new\",\n summary: \"propose a decision from a template and stage it\",\n usage:\n \"new <title> [--template <name>] [--supersedes <decision>]… [--section <id>=<markdown>]… [--edit | --no-edit] [--commit | --no-commit]\",\n options: {\n template: { type: \"string\" },\n supersedes: { type: \"string\", multiple: true },\n section: { type: \"string\", multiple: true },\n edit: { type: \"boolean\" },\n commit: { type: \"boolean\" },\n },\n positionals: { min: 1, max: 1, names: [\"title\"] },\n ref: \"reject\",\n async run({ io, flags, values, positionals }) {\n const title = positionals[0] ?? \"\";\n const given = sections(strings(values.section));\n const log = await openForCli(io, flags);\n const actor = await resolveActor(log.git, { env: io.env });\n // Design review NIT 1: the skip notes say \"not committed\" only when a commit was asked for.\n const requested = commitRequested(log, values);\n const notes: string[] = [];\n const editor = editorFor(io.env, { stdoutIsTTY: io.stdoutIsTTY });\n const wantsEdit = values.edit === true || (values.edit === undefined && io.interactive);\n if (values.edit === true && editor === null) notes.push(\"no editor: set VISUAL or EDITOR\");\n const edit =\n wantsEdit && editor !== null\n ? async (abs: string) => {\n const note = await editor(abs);\n if (note !== null) notes.push(note);\n return note;\n }\n : undefined;\n const doc = await proposeDecision(\n log,\n {\n title,\n sections: given,\n supersedes: strings(values.supersedes),\n actor,\n ...(typeof values.template === \"string\" ? { template: values.template } : {}),\n },\n {\n commit: requested,\n ...(edit === undefined ? {} : { edit }),\n onNote: (note) => notes.push(requested ? `not committed: ${note}` : note),\n },\n );\n const { display } = await displayAfterWrite(log);\n const v = doc.decision;\n return {\n exit: doc.ok ? 0 : 1,\n json: doc as unknown as JsonValue,\n text: writeText(doc, display, {\n subject: title.trim(),\n number: v === null || v.number === null ? null : v.display,\n }),\n notes: [...doc.notes, ...notes],\n };\n },\n};\n","import type { JsonValue } from \"@nikovirtala/ledger\";\nimport type { CommandSpec } from \"@nikovirtala/ledger/cli\";\nimport { readDecisions, resolveDecision } from \"../log.js\";\nimport { showDecision } from \"../views.js\";\nimport { openForCli } from \"./open.js\";\nimport { showText } from \"./text.js\";\n\n/** `adr show <decision> [--history]` (design §5.6). */\nexport const showCommand: CommandSpec = {\n name: \"show\",\n summary: \"show a decision with its state header, chain, history and body\",\n usage: \"show <decision> [--history]\",\n options: { history: { type: \"boolean\" } },\n positionals: { min: 1, max: 1, names: [\"decision\"] },\n ref: \"read\",\n async run({ io, flags, values, positionals }) {\n const read = await readDecisions(await openForCli(io, flags));\n const id = resolveDecision(read, positionals[0] ?? \"\");\n const doc = await showDecision(read, id, { history: values.history === true });\n const display = (s: string) => read.projection.views.get(s)?.display ?? s;\n return {\n exit: 0,\n json: doc as unknown as JsonValue,\n text: showText(doc, display),\n notes: doc.notes,\n };\n },\n};\n","import { type JsonValue, resolveActor, UsageError } from \"@nikovirtala/ledger\";\nimport type { CommandSpec } from \"@nikovirtala/ledger/cli\";\nimport { supersedeDecision } from \"../write.js\";\nimport { commitRequested, displayAfterWrite, openForCli } from \"./open.js\";\nimport { writeText } from \"./text.js\";\n\nconst USAGE = \"supersede <decision> --by <decision> [--reason <text>] [--commit | --no-commit]\";\n\n/** `adr supersede <decision> --by <decision> …` (design §5.6). */\nexport const supersedeCommand: CommandSpec = {\n name: \"supersede\",\n summary: \"mark an accepted decision as superseded by another accepted one\",\n usage: USAGE,\n options: { by: { type: \"string\" }, reason: { type: \"string\" }, commit: { type: \"boolean\" } },\n positionals: { min: 1, max: 1, names: [\"decision\"] },\n ref: \"reject\",\n async run({ io, flags, values, positionals }) {\n const input = positionals[0] ?? \"\";\n if (typeof values.by !== \"string\") {\n throw new UsageError(`missing --by <decision>; usage: adr ${USAGE}`);\n }\n const log = await openForCli(io, flags);\n const actor = await resolveActor(log.git, { env: io.env });\n const doc = await supersedeDecision(\n log,\n {\n id: input,\n by: values.by,\n actor,\n ...(typeof values.reason === \"string\" ? { reason: values.reason } : {}),\n },\n { commit: commitRequested(log, values) },\n );\n const { display } = await displayAfterWrite(log);\n const v = doc.decision;\n return {\n exit: doc.ok ? 0 : 1,\n json: doc as unknown as JsonValue,\n text: writeText(doc, display, {\n subject: v === null ? input.trim() : `${display(v.id)}: ${v.title}`,\n number: null,\n }),\n notes: doc.notes,\n };\n },\n};\n","import { templateHistoryRef } from \"@nikovirtala/ledger\";\nimport { type ToolCli, verifyCommand } from \"@nikovirtala/ledger/cli\";\nimport { adrKind } from \"../kind.js\";\nimport { adrChecks } from \"../verify.js\";\nimport { acceptCommand } from \"./accept.js\";\nimport { listCommand } from \"./list.js\";\nimport { newCommand } from \"./new.js\";\nimport { openForCli } from \"./open.js\";\nimport { showCommand } from \"./show.js\";\nimport { supersedeCommand } from \"./supersede.js\";\n\n/**\n * ledger's shared `verify`: the log as the mode reads it (the index for `--staged`, else the\n * `--ref` tree or the work tree), every phase-1 check, and `[verify] fail_on`.\n */\nconst verify = verifyCommand({\n async open({ io, flags, mode }) {\n const log = await openForCli(io, flags, {\n reader: mode.type === \"staged\" ? \"index\" : \"worktree\",\n });\n return {\n git: log.git,\n kind: adrKind,\n layout: log.layout,\n checks: adrChecks(log, await templateHistoryRef(log.git, mode)),\n failOn: log.adr.failOn,\n notes: log.notes,\n };\n },\n});\n\n/** The `adr` tool: its commands, for ledger's `runCli`. */\nexport function adrCli(version: string): ToolCli {\n return {\n name: \"adr\",\n version,\n summary: \"Architecture decision records kept as event logs in git.\",\n commands: [newCommand, acceptCommand, supersedeCommand, listCommand, showCommand, verify],\n };\n}\n","#!/usr/bin/env node\nimport { createRequire } from \"node:module\";\nimport { processIO, runCli } from \"@nikovirtala/ledger/cli\";\nimport { adrCli } from \"./cli/commands.js\";\n\n// Read at run time, relative to dist/cli.js (or src/cli.ts): both sit next to ../package.json.\nconst { version } = createRequire(import.meta.url)(\"../package.json\") as { version: string };\n\nprocess.exitCode = await runCli(adrCli(version), processIO());\n"],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ import { a as showDecision, c as verifyDecisions, d as readDecisionsFrom, f as resolveDecision, h as parseAdrConfig, i as listDecisions, l as openDecisionLog, m as DEFAULT_ADR_CONFIG, n as proposeDecision, o as stateHeader, r as supersedeDecision, s as adrChecks, t as acceptDecision, u as readDecisions } from "./write-C3IW5WrA.js";
2
+ import { a as parseDecisionNumber, i as formatDecisionNumber, n as DECISION_STATUSES, r as REF, t as adrKind } from "./kind-DqFhApu7.js";
3
+ export { DECISION_STATUSES, DEFAULT_ADR_CONFIG, REF, acceptDecision, adrChecks, adrKind, formatDecisionNumber, listDecisions, openDecisionLog, parseAdrConfig, parseDecisionNumber, proposeDecision, readDecisions, readDecisionsFrom, resolveDecision, showDecision, stateHeader, supersedeDecision, verifyDecisions };
@@ -0,0 +1,424 @@
1
+ import { defineKind, eventType } from "@nikovirtala/ledger";
2
+ // src/kind/project.ts
3
+ const NUMBER = /^(?:adr-?)?0*([1-9][0-9]{0,8})$/i;
4
+ /** `ADR-0007`: at least 4 digits, growing past 9999. */
5
+ function formatDecisionNumber(n) {
6
+ return `ADR-${String(n).padStart(4, "0")}`;
7
+ }
8
+ /** `7`, `0007`, `ADR-7`, `adr-0007` → 7; `null` for anything else. */
9
+ function parseDecisionNumber(s) {
10
+ const m = NUMBER.exec(s.trim());
11
+ return m === null ? null : Number(m[1]);
12
+ }
13
+ /**
14
+ * Follows `superseded_by` from `id`. A visited set stops on a cycle (`effective: null`); a
15
+ * reference to a subject that isn't folded ends the chain there.
16
+ */
17
+ function chainOf(id, ctx) {
18
+ const chain = [id];
19
+ let cur = id;
20
+ for (;;) {
21
+ const next = ctx.log.subjects.get(cur)?.state?.supersededBy ?? null;
22
+ if (next === null) return {
23
+ chain,
24
+ effective: cur
25
+ };
26
+ if (chain.includes(next)) return {
27
+ chain,
28
+ effective: null
29
+ };
30
+ chain.push(next);
31
+ cur = next;
32
+ }
33
+ }
34
+ /** Pure: the view of one folded decision. */
35
+ function project(subject, ctx) {
36
+ const { id } = subject;
37
+ const s = subject.state;
38
+ if (s === null || subject.status === null) throw new Error(`decision ${id} is not folded`);
39
+ const supersedes = [...ctx.log.subjects.values()].filter((o) => o.id !== id && o.state?.supersededBy === id).map((o) => o.id).sort();
40
+ const { chain, effective } = chainOf(id, ctx);
41
+ const current = ctx.bodySha256(id);
42
+ return {
43
+ id,
44
+ number: ctx.number(id),
45
+ display: ctx.display(id),
46
+ title: s.title,
47
+ status: subject.status,
48
+ superseded_by: s.supersededBy,
49
+ supersedes,
50
+ declared_supersedes: s.declaredSupersedes,
51
+ effective,
52
+ chain,
53
+ template: s.template,
54
+ body_path: subject.loaded.body?.path ?? subject.loaded.bodyPaths[0] ?? null,
55
+ body_sha256: s.bodySha256,
56
+ body_intact: s.bodySha256 === null ? null : current === s.bodySha256,
57
+ links: s.links,
58
+ applies_to: s.appliesTo,
59
+ notes: s.notes,
60
+ proposed_at: s.proposedAt,
61
+ decided_at: s.decidedAt,
62
+ status_at: s.statusAt,
63
+ history: s.history.map((h) => `${h.type} ${h.at.slice(0, 10)}`)
64
+ };
65
+ }
66
+ // src/kind/reduce.ts
67
+ const EMPTY = {
68
+ title: "",
69
+ template: {
70
+ name: "",
71
+ version: 0
72
+ },
73
+ declaredSupersedes: [],
74
+ bodySha256: null,
75
+ acceptedBy: null,
76
+ supersededBy: null,
77
+ links: [],
78
+ appliesTo: [],
79
+ notes: 0,
80
+ history: [],
81
+ proposedAt: "",
82
+ decidedAt: null,
83
+ statusAt: ""
84
+ };
85
+ /** Pure: the state after one applied event. The fold only passes events the machine allows. */
86
+ function reduce(state, e) {
87
+ const s = state ?? EMPTY;
88
+ const changed = (extra = {}) => ({
89
+ ...s,
90
+ ...extra,
91
+ history: [...s.history, {
92
+ type: e.type,
93
+ at: e.at
94
+ }],
95
+ statusAt: e.at
96
+ });
97
+ switch (e.type) {
98
+ case "proposed": return changed({
99
+ title: e.data.title,
100
+ template: {
101
+ name: e.data.template,
102
+ version: e.data.template_version
103
+ },
104
+ declaredSupersedes: [...e.data.supersedes ?? []],
105
+ proposedAt: e.at
106
+ });
107
+ case "accepted": return changed({
108
+ bodySha256: e.data.body_sha256,
109
+ acceptedBy: e.actor,
110
+ decidedAt: e.at
111
+ });
112
+ case "rejected":
113
+ case "withdrawn": return changed({ decidedAt: e.at });
114
+ case "deprecated": return changed();
115
+ case "superseded": return changed({ supersededBy: e.data.by });
116
+ case "noted": return {
117
+ ...s,
118
+ notes: s.notes + 1
119
+ };
120
+ case "linked": {
121
+ const { to, rel } = e.data;
122
+ return s.links.some((l) => l.to === to && l.rel === rel) ? s : {
123
+ ...s,
124
+ links: [...s.links, {
125
+ to,
126
+ rel
127
+ }]
128
+ };
129
+ }
130
+ case "scoped": return {
131
+ ...s,
132
+ appliesTo: [...e.data.set]
133
+ };
134
+ }
135
+ }
136
+ // src/kind/rules.ts
137
+ /** `decision/agent-accepted`: an applied `accepted` event written by an agent under the human policy. */
138
+ function invariants(subject, options) {
139
+ if (!options.acceptRequiresHuman) return [];
140
+ return subject.applied.flatMap(({ event }) => event.type === "accepted" && event.actor.kind === "agent" ? [{
141
+ severity: "error",
142
+ rule: "decision/agent-accepted",
143
+ message: `accepted by agent ${event.actor.name}; accept_requires_human needs a human`,
144
+ subject: subject.id,
145
+ event: event.id
146
+ }] : []);
147
+ }
148
+ /**
149
+ * Qualified ids (`<source>:<id>`) name decisions in other logs. Phase 1 checks local references
150
+ * only and skips qualified ones, which only hand-written events can hold; CI checks them at the
151
+ * pinned ref in phase 2 (design §E).
152
+ */
153
+ const isQualified = (ref) => ref.includes(":");
154
+ /**
155
+ * Cross-subject rules: `decision/reference-missing` for a local `supersedes`, `superseded.by` or
156
+ * `linked.to` naming no subject in the log; `decision/superseded-by-unaccepted` when the target of
157
+ * an applied `superseded.by` has no applied `accepted` event in this tree; and
158
+ * `decision/supersession-cycle`, once per cycle on its smallest id.
159
+ */
160
+ function relate(log) {
161
+ const out = [];
162
+ const isAccepted = (id) => log.subjects.get(id)?.applied.some((a) => a.event.type === "accepted") ?? false;
163
+ const missing = (subject, event, ref, what) => {
164
+ if (isQualified(ref) || log.subjects.has(ref)) return false;
165
+ out.push({
166
+ severity: "error",
167
+ rule: "decision/reference-missing",
168
+ message: `${what} ${ref}, which is not in the log`,
169
+ subject,
170
+ event,
171
+ related: [ref]
172
+ });
173
+ return true;
174
+ };
175
+ for (const [id, s] of log.subjects) for (const { event } of s.applied) switch (event.type) {
176
+ case "proposed":
177
+ for (const ref of event.data.supersedes ?? []) missing(id, event.id, ref, "supersedes");
178
+ break;
179
+ case "superseded": {
180
+ const by = event.data.by;
181
+ if (missing(id, event.id, by, "superseded by") || isQualified(by)) break;
182
+ if (!isAccepted(by)) out.push({
183
+ severity: "error",
184
+ rule: "decision/superseded-by-unaccepted",
185
+ message: `superseded by ${by}, which is not accepted`,
186
+ subject: id,
187
+ event: event.id,
188
+ related: [by]
189
+ });
190
+ break;
191
+ }
192
+ case "linked": missing(id, event.id, event.data.to, "links to");
193
+ }
194
+ const next = (id) => log.subjects.get(id)?.state?.supersededBy ?? null;
195
+ const reported = /* @__PURE__ */ new Set();
196
+ for (const start of log.subjects.keys()) {
197
+ const path = [];
198
+ let cur = start;
199
+ while (cur !== null && !path.includes(cur)) {
200
+ path.push(cur);
201
+ cur = next(cur);
202
+ }
203
+ if (cur === null) continue;
204
+ const cycle = path.slice(path.indexOf(cur));
205
+ const smallest = [...cycle].sort()[0];
206
+ if (smallest === void 0 || reported.has(smallest)) continue;
207
+ reported.add(smallest);
208
+ const from = cycle.indexOf(smallest);
209
+ const ordered = [
210
+ ...cycle.slice(from),
211
+ ...cycle.slice(0, from),
212
+ smallest
213
+ ];
214
+ const event = log.subjects.get(smallest)?.applied.find((a) => a.event.type === "superseded")?.event.id;
215
+ out.push({
216
+ severity: "error",
217
+ rule: "decision/supersession-cycle",
218
+ message: `supersession cycle: ${ordered.join(" → ")}`,
219
+ subject: smallest,
220
+ ...event === void 0 ? {} : { event },
221
+ related: [...cycle].sort()
222
+ });
223
+ }
224
+ return out;
225
+ }
226
+ // src/kind/schemas.ts
227
+ /** Every status, in lifecycle order. */
228
+ const DECISION_STATUSES = Object.freeze([
229
+ "proposed",
230
+ "accepted",
231
+ "rejected",
232
+ "withdrawn",
233
+ "deprecated",
234
+ "superseded"
235
+ ]);
236
+ /** A local subject id, or a qualified `<source>:<id>` one. */
237
+ const REF = "^(?:[a-z][a-z0-9-]*:)?[0-9a-hjkmnp-tv-z]{8}$";
238
+ const ref = {
239
+ type: "string",
240
+ pattern: REF
241
+ };
242
+ /** The decision kind's event types (01:128–136): data schemas, allowed states and targets. */
243
+ const decisionEvents = {
244
+ proposed: eventType()({
245
+ data: {
246
+ type: "object",
247
+ required: [
248
+ "title",
249
+ "template",
250
+ "template_version"
251
+ ],
252
+ properties: {
253
+ title: {
254
+ type: "string",
255
+ minLength: 1,
256
+ maxLength: 200,
257
+ pattern: "^[^\\r\\n]*$"
258
+ },
259
+ template: {
260
+ type: "string",
261
+ pattern: "^[a-z][a-z0-9-]*$"
262
+ },
263
+ template_version: {
264
+ type: "integer",
265
+ minimum: 1
266
+ },
267
+ supersedes: {
268
+ type: "array",
269
+ items: ref,
270
+ uniqueItems: true,
271
+ maxItems: 20
272
+ }
273
+ }
274
+ },
275
+ allowedIn: [],
276
+ to: "proposed"
277
+ }),
278
+ accepted: eventType()({
279
+ data: {
280
+ type: "object",
281
+ required: ["body_sha256"],
282
+ properties: { body_sha256: {
283
+ type: "string",
284
+ pattern: "^[0-9a-f]{64}$"
285
+ } }
286
+ },
287
+ allowedIn: ["proposed"],
288
+ to: "accepted"
289
+ }),
290
+ rejected: eventType()({
291
+ data: { type: "object" },
292
+ allowedIn: ["proposed"],
293
+ to: "rejected",
294
+ reason: "required"
295
+ }),
296
+ withdrawn: eventType()({
297
+ data: { type: "object" },
298
+ allowedIn: ["proposed"],
299
+ to: "withdrawn"
300
+ }),
301
+ deprecated: eventType()({
302
+ data: { type: "object" },
303
+ allowedIn: ["accepted"],
304
+ to: "deprecated",
305
+ reason: "required"
306
+ }),
307
+ superseded: eventType()({
308
+ data: {
309
+ type: "object",
310
+ required: ["by"],
311
+ properties: { by: ref }
312
+ },
313
+ allowedIn: ["accepted", "deprecated"],
314
+ to: "superseded"
315
+ }),
316
+ noted: eventType()({
317
+ data: {
318
+ type: "object",
319
+ required: ["text"],
320
+ properties: { text: {
321
+ type: "string",
322
+ minLength: 1
323
+ } }
324
+ },
325
+ allowedIn: "any",
326
+ to: null
327
+ }),
328
+ linked: eventType()({
329
+ data: {
330
+ type: "object",
331
+ required: ["to", "rel"],
332
+ properties: {
333
+ to: ref,
334
+ rel: { enum: [
335
+ "relates-to",
336
+ "refines",
337
+ "depends-on"
338
+ ] }
339
+ }
340
+ },
341
+ allowedIn: "any",
342
+ to: null
343
+ }),
344
+ scoped: eventType()({
345
+ data: {
346
+ type: "object",
347
+ required: ["set"],
348
+ properties: { set: {
349
+ type: "array",
350
+ items: {
351
+ type: "string",
352
+ minLength: 1,
353
+ maxLength: 500
354
+ },
355
+ uniqueItems: true,
356
+ maxItems: 200
357
+ } }
358
+ },
359
+ allowedIn: [
360
+ "proposed",
361
+ "accepted",
362
+ "deprecated"
363
+ ],
364
+ to: null
365
+ })
366
+ };
367
+ // src/kind.ts
368
+ /**
369
+ * The decision kind (01:128–194), as imported by other tools through `@nikovirtala/adr/kind`.
370
+ *
371
+ * Decisions are proposed, then accepted (which freezes the body and earns a number on main),
372
+ * rejected or withdrawn; accepted ones can be deprecated or superseded. This module imports only
373
+ * `@nikovirtala/ledger` and `./kind/*`, so importing the kind never loads CLI or MCP code.
374
+ */
375
+ const adrKind = defineKind({
376
+ name: "decision",
377
+ schema: "decision/v1",
378
+ states: [
379
+ "proposed",
380
+ "accepted",
381
+ "rejected",
382
+ "withdrawn",
383
+ "deprecated",
384
+ "superseded"
385
+ ],
386
+ events: decisionEvents,
387
+ initial: "proposed",
388
+ reduce,
389
+ invariants,
390
+ relate,
391
+ project,
392
+ body: { freezeOn: "accepted" },
393
+ layout: {
394
+ bodies: "decisions",
395
+ events: "events"
396
+ },
397
+ defaultRoot: "docs/adr",
398
+ sourceName: "adr",
399
+ numbering: {
400
+ on: "accepted",
401
+ format: formatDecisionNumber,
402
+ parse: parseDecisionNumber
403
+ },
404
+ templates: {
405
+ dir: "templates",
406
+ nameField: "template",
407
+ versionField: "template_version",
408
+ lintIn: ["proposed"],
409
+ lintOn: "accepted",
410
+ requireSections: ["scope"]
411
+ },
412
+ scope: {
413
+ event: "scoped",
414
+ activeIn: [
415
+ "proposed",
416
+ "accepted",
417
+ "deprecated"
418
+ ]
419
+ },
420
+ options: Object.freeze({ acceptRequiresHuman: true })
421
+ });
422
+ export { parseDecisionNumber as a, formatDecisionNumber as i, DECISION_STATUSES as n, REF as r, adrKind as t };
423
+
424
+ //# sourceMappingURL=kind-DqFhApu7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kind-DqFhApu7.js","names":[],"sources":["../src/kind/project.ts","../src/kind/reduce.ts","../src/kind/rules.ts","../src/kind/schemas.ts","../src/kind.ts"],"sourcesContent":["import type { FoldedSubject, ProjectContext } from \"@nikovirtala/ledger\";\nimport type { DecisionState } from \"./reduce.js\";\nimport type { DecisionEvents, DecisionStatus } from \"./schemas.js\";\n\n/** One decision as the CLI, the library and MCP show it (01:173–192, plus the added fields). */\nexport interface DecisionView {\n readonly id: string;\n readonly number: number | null;\n /** `ADR-0007`, or the id when unnumbered. */\n readonly display: string;\n readonly title: string;\n readonly status: DecisionStatus;\n readonly superseded_by: string | null;\n /** Ids whose applied `superseded.by` is this id, sorted. */\n readonly supersedes: readonly string[];\n /** The proposal's intent (01:164). */\n readonly declared_supersedes: readonly string[];\n /** Head of the `superseded_by` chain; `null` only on a cycle. */\n readonly effective: string | null;\n /** `[id, …, effective]`, following `superseded_by` forward. */\n readonly chain: readonly string[];\n readonly template: { readonly name: string; readonly version: number };\n readonly body_path: string | null;\n /** Recorded at acceptance. */\n readonly body_sha256: string | null;\n /** `null` until accepted; whether the current body hash equals the recorded one. */\n readonly body_intact: boolean | null;\n readonly links: readonly { readonly to: string; readonly rel: string }[];\n readonly applies_to: readonly string[];\n readonly notes: number;\n readonly proposed_at: string;\n readonly decided_at: string | null;\n readonly status_at: string;\n /** `proposed 2026-03-12`: state-changing events, in fold order. */\n readonly history: readonly string[];\n}\n\ntype Subject = FoldedSubject<DecisionStatus, DecisionState, DecisionEvents>;\ntype Context = ProjectContext<DecisionStatus, DecisionState, DecisionEvents>;\n\nconst NUMBER = /^(?:adr-?)?0*([1-9][0-9]{0,8})$/i;\n\n/** `ADR-0007`: at least 4 digits, growing past 9999. */\nexport function formatDecisionNumber(n: number): string {\n return `ADR-${String(n).padStart(4, \"0\")}`;\n}\n\n/** `7`, `0007`, `ADR-7`, `adr-0007` → 7; `null` for anything else. */\nexport function parseDecisionNumber(s: string): number | null {\n const m = NUMBER.exec(s.trim());\n return m === null ? null : Number(m[1]);\n}\n\n/**\n * Follows `superseded_by` from `id`. A visited set stops on a cycle (`effective: null`); a\n * reference to a subject that isn't folded ends the chain there.\n */\nfunction chainOf(id: string, ctx: Context): { chain: string[]; effective: string | null } {\n const chain = [id];\n let cur = id;\n for (;;) {\n const next = ctx.log.subjects.get(cur)?.state?.supersededBy ?? null;\n if (next === null) return { chain, effective: cur };\n if (chain.includes(next)) return { chain, effective: null };\n chain.push(next);\n cur = next;\n }\n}\n\n/** Pure: the view of one folded decision. */\nexport function project(subject: Subject, ctx: Context): DecisionView {\n const { id } = subject;\n const s = subject.state;\n if (s === null || subject.status === null) {\n throw new Error(`decision ${id} is not folded`);\n }\n const supersedes = [...ctx.log.subjects.values()]\n .filter((o) => o.id !== id && o.state?.supersededBy === id)\n .map((o) => o.id)\n .sort();\n const { chain, effective } = chainOf(id, ctx);\n const current = ctx.bodySha256(id);\n return {\n id,\n number: ctx.number(id),\n display: ctx.display(id),\n title: s.title,\n status: subject.status,\n superseded_by: s.supersededBy,\n supersedes,\n declared_supersedes: s.declaredSupersedes,\n effective,\n chain,\n template: s.template,\n body_path: subject.loaded.body?.path ?? subject.loaded.bodyPaths[0] ?? null,\n body_sha256: s.bodySha256,\n body_intact: s.bodySha256 === null ? null : current === s.bodySha256,\n links: s.links,\n applies_to: s.appliesTo,\n notes: s.notes,\n proposed_at: s.proposedAt,\n decided_at: s.decidedAt,\n status_at: s.statusAt,\n history: s.history.map((h) => `${h.type} ${h.at.slice(0, 10)}`),\n };\n}\n","import type { Actor, FoldEvent } from \"@nikovirtala/ledger\";\nimport type { DecisionEvents } from \"./schemas.js\";\n\n/** A decision's own state, maintained by `reduce` over its applied events. */\nexport interface DecisionState {\n readonly title: string;\n readonly template: { readonly name: string; readonly version: number };\n readonly declaredSupersedes: readonly string[];\n /** From the applied `accepted` event. */\n readonly bodySha256: string | null;\n readonly acceptedBy: Actor | null;\n readonly supersededBy: string | null;\n /** In fold order, duplicates kept once. */\n readonly links: readonly { readonly to: string; readonly rel: string }[];\n /** The latest `scoped` set (latest wins). */\n readonly appliesTo: readonly string[];\n readonly notes: number;\n /** State-changing events only, in fold order. */\n readonly history: readonly { readonly type: string; readonly at: string }[];\n readonly proposedAt: string;\n /** `at` of `accepted`, `rejected` or `withdrawn`. */\n readonly decidedAt: string | null;\n /** `at` of the latest state-changing event. */\n readonly statusAt: string;\n}\n\nconst EMPTY: DecisionState = {\n title: \"\",\n template: { name: \"\", version: 0 },\n declaredSupersedes: [],\n bodySha256: null,\n acceptedBy: null,\n supersededBy: null,\n links: [],\n appliesTo: [],\n notes: 0,\n history: [],\n proposedAt: \"\",\n decidedAt: null,\n statusAt: \"\",\n};\n\n/** Pure: the state after one applied event. The fold only passes events the machine allows. */\nexport function reduce(state: DecisionState | null, e: FoldEvent<DecisionEvents>): DecisionState {\n const s = state ?? EMPTY;\n const changed = (extra: Partial<DecisionState> = {}): DecisionState => ({\n ...s,\n ...extra,\n history: [...s.history, { type: e.type, at: e.at }],\n statusAt: e.at,\n });\n switch (e.type) {\n case \"proposed\":\n return changed({\n title: e.data.title,\n template: { name: e.data.template, version: e.data.template_version },\n declaredSupersedes: [...(e.data.supersedes ?? [])],\n proposedAt: e.at,\n });\n case \"accepted\":\n return changed({ bodySha256: e.data.body_sha256, acceptedBy: e.actor, decidedAt: e.at });\n case \"rejected\":\n case \"withdrawn\":\n return changed({ decidedAt: e.at });\n case \"deprecated\":\n return changed();\n case \"superseded\":\n return changed({ supersededBy: e.data.by });\n case \"noted\":\n return { ...s, notes: s.notes + 1 };\n case \"linked\": {\n const { to, rel } = e.data;\n const known = s.links.some((l) => l.to === to && l.rel === rel);\n return known ? s : { ...s, links: [...s.links, { to, rel }] };\n }\n case \"scoped\":\n return { ...s, appliesTo: [...e.data.set] };\n }\n}\n","import type { FoldedLog, FoldedSubject, KindFinding } from \"@nikovirtala/ledger\";\nimport type { DecisionState } from \"./reduce.js\";\nimport type { DecisionEvents, DecisionStatus } from \"./schemas.js\";\n\n/** Options of the decision kind's `invariants` and `relate`. */\nexport interface AdrOptions {\n /** Default `true`: an agent may propose, but only a human may accept (01:98). */\n readonly acceptRequiresHuman: boolean;\n}\n\ntype Subject = FoldedSubject<DecisionStatus, DecisionState, DecisionEvents>;\ntype Log = FoldedLog<DecisionStatus, DecisionState, DecisionEvents>;\n\n/** `decision/agent-accepted`: an applied `accepted` event written by an agent under the human policy. */\nexport function invariants(subject: Subject, options: AdrOptions): readonly KindFinding[] {\n if (!options.acceptRequiresHuman) return [];\n return subject.applied.flatMap(({ event }) =>\n event.type === \"accepted\" && event.actor.kind === \"agent\"\n ? [\n {\n severity: \"error\" as const,\n rule: \"decision/agent-accepted\",\n message: `accepted by agent ${event.actor.name}; accept_requires_human needs a human`,\n subject: subject.id,\n event: event.id,\n },\n ]\n : [],\n );\n}\n\n/**\n * Qualified ids (`<source>:<id>`) name decisions in other logs. Phase 1 checks local references\n * only and skips qualified ones, which only hand-written events can hold; CI checks them at the\n * pinned ref in phase 2 (design §E).\n */\nconst isQualified = (ref: string) => ref.includes(\":\");\n\n/**\n * Cross-subject rules: `decision/reference-missing` for a local `supersedes`, `superseded.by` or\n * `linked.to` naming no subject in the log; `decision/superseded-by-unaccepted` when the target of\n * an applied `superseded.by` has no applied `accepted` event in this tree; and\n * `decision/supersession-cycle`, once per cycle on its smallest id.\n */\nexport function relate(log: Log): readonly KindFinding[] {\n const out: KindFinding[] = [];\n const isAccepted = (id: string) =>\n log.subjects.get(id)?.applied.some((a) => a.event.type === \"accepted\") ?? false;\n const missing = (subject: string, event: string, ref: string, what: string) => {\n if (isQualified(ref) || log.subjects.has(ref)) return false;\n out.push({\n severity: \"error\",\n rule: \"decision/reference-missing\",\n message: `${what} ${ref}, which is not in the log`,\n subject,\n event,\n related: [ref],\n });\n return true;\n };\n\n for (const [id, s] of log.subjects) {\n for (const { event } of s.applied) {\n switch (event.type) {\n case \"proposed\":\n for (const ref of event.data.supersedes ?? []) missing(id, event.id, ref, \"supersedes\");\n break;\n case \"superseded\": {\n const by = event.data.by;\n if (missing(id, event.id, by, \"superseded by\") || isQualified(by)) break;\n if (!isAccepted(by)) {\n out.push({\n severity: \"error\",\n rule: \"decision/superseded-by-unaccepted\",\n message: `superseded by ${by}, which is not accepted`,\n subject: id,\n event: event.id,\n related: [by],\n });\n }\n break;\n }\n case \"linked\":\n missing(id, event.id, event.data.to, \"links to\");\n break;\n default:\n break;\n }\n }\n }\n\n const next = (id: string) => log.subjects.get(id)?.state?.supersededBy ?? null;\n const reported = new Set<string>();\n for (const start of log.subjects.keys()) {\n const path: string[] = [];\n let cur: string | null = start;\n while (cur !== null && !path.includes(cur)) {\n path.push(cur);\n cur = next(cur);\n }\n if (cur === null) continue;\n const cycle = path.slice(path.indexOf(cur));\n const smallest = [...cycle].sort()[0];\n if (smallest === undefined || reported.has(smallest)) continue;\n reported.add(smallest);\n const from = cycle.indexOf(smallest);\n const ordered = [...cycle.slice(from), ...cycle.slice(0, from), smallest];\n const event = log.subjects.get(smallest)?.applied.find((a) => a.event.type === \"superseded\")\n ?.event.id;\n out.push({\n severity: \"error\",\n rule: \"decision/supersession-cycle\",\n message: `supersession cycle: ${ordered.join(\" → \")}`,\n subject: smallest,\n ...(event === undefined ? {} : { event }),\n related: [...cycle].sort(),\n });\n }\n return out;\n}\n","import { eventType } from \"@nikovirtala/ledger\";\n\n/** A decision's computed status. */\nexport type DecisionStatus =\n | \"proposed\"\n | \"accepted\"\n | \"rejected\"\n | \"withdrawn\"\n | \"deprecated\"\n | \"superseded\";\n\n/** Every status, in lifecycle order. */\nexport const DECISION_STATUSES: readonly DecisionStatus[] = Object.freeze([\n \"proposed\",\n \"accepted\",\n \"rejected\",\n \"withdrawn\",\n \"deprecated\",\n \"superseded\",\n]);\n\n/** A local subject id, or a qualified `<source>:<id>` one. */\nexport const REF = \"^(?:[a-z][a-z0-9-]*:)?[0-9a-hjkmnp-tv-z]{8}$\";\n\nconst ref = { type: \"string\", pattern: REF } as const;\nconst SINGLE_LINE = \"^[^\\\\r\\\\n]*$\";\n\n/** How a `linked` decision relates to its target. */\nexport type LinkRel = \"relates-to\" | \"refines\" | \"depends-on\";\n\n/** The decision kind's event types (01:128–136): data schemas, allowed states and targets. */\nexport const decisionEvents = {\n proposed: eventType<{\n title: string;\n template: string;\n template_version: number;\n supersedes?: string[];\n }>()({\n data: {\n type: \"object\",\n required: [\"title\", \"template\", \"template_version\"],\n properties: {\n title: { type: \"string\", minLength: 1, maxLength: 200, pattern: SINGLE_LINE },\n template: { type: \"string\", pattern: \"^[a-z][a-z0-9-]*$\" },\n template_version: { type: \"integer\", minimum: 1 },\n supersedes: { type: \"array\", items: ref, uniqueItems: true, maxItems: 20 },\n },\n },\n allowedIn: [],\n to: \"proposed\",\n }),\n accepted: eventType<{ body_sha256: string }>()({\n data: {\n type: \"object\",\n required: [\"body_sha256\"],\n properties: { body_sha256: { type: \"string\", pattern: \"^[0-9a-f]{64}$\" } },\n },\n allowedIn: [\"proposed\"],\n to: \"accepted\",\n }),\n rejected: eventType()({\n data: { type: \"object\" },\n allowedIn: [\"proposed\"],\n to: \"rejected\",\n reason: \"required\",\n }),\n withdrawn: eventType()({ data: { type: \"object\" }, allowedIn: [\"proposed\"], to: \"withdrawn\" }),\n deprecated: eventType()({\n data: { type: \"object\" },\n allowedIn: [\"accepted\"],\n to: \"deprecated\",\n reason: \"required\",\n }),\n superseded: eventType<{ by: string }>()({\n data: { type: \"object\", required: [\"by\"], properties: { by: ref } },\n allowedIn: [\"accepted\", \"deprecated\"],\n to: \"superseded\",\n }),\n noted: eventType<{ text: string }>()({\n data: {\n type: \"object\",\n required: [\"text\"],\n properties: { text: { type: \"string\", minLength: 1 } },\n },\n allowedIn: \"any\",\n to: null,\n }),\n linked: eventType<{ to: string; rel: LinkRel }>()({\n data: {\n type: \"object\",\n required: [\"to\", \"rel\"],\n properties: { to: ref, rel: { enum: [\"relates-to\", \"refines\", \"depends-on\"] } },\n },\n allowedIn: \"any\",\n to: null,\n }),\n scoped: eventType<{ set: string[] }>()({\n data: {\n type: \"object\",\n required: [\"set\"],\n properties: {\n set: {\n type: \"array\",\n items: { type: \"string\", minLength: 1, maxLength: 500 },\n uniqueItems: true,\n maxItems: 200,\n },\n },\n },\n allowedIn: [\"proposed\", \"accepted\", \"deprecated\"],\n to: null,\n }),\n} as const;\n\nexport type DecisionEvents = typeof decisionEvents;\n","import { defineKind, type Kind } from \"@nikovirtala/ledger\";\nimport {\n type DecisionView,\n formatDecisionNumber,\n parseDecisionNumber,\n project,\n} from \"./kind/project.js\";\nimport { type DecisionState, reduce } from \"./kind/reduce.js\";\nimport { type AdrOptions, invariants, relate } from \"./kind/rules.js\";\nimport { type DecisionEvents, type DecisionStatus, decisionEvents } from \"./kind/schemas.js\";\n\nexport type { DecisionView } from \"./kind/project.js\";\nexport { formatDecisionNumber, parseDecisionNumber } from \"./kind/project.js\";\nexport type { DecisionState } from \"./kind/reduce.js\";\nexport type { AdrOptions } from \"./kind/rules.js\";\nexport {\n DECISION_STATUSES,\n type DecisionEvents,\n type DecisionStatus,\n type LinkRel,\n REF,\n} from \"./kind/schemas.js\";\n\n/**\n * The decision kind (01:128–194), as imported by other tools through `@nikovirtala/adr/kind`.\n *\n * Decisions are proposed, then accepted (which freezes the body and earns a number on main),\n * rejected or withdrawn; accepted ones can be deprecated or superseded. This module imports only\n * `@nikovirtala/ledger` and `./kind/*`, so importing the kind never loads CLI or MCP code.\n */\nexport const adrKind: Kind<\n DecisionStatus,\n DecisionEvents,\n DecisionState,\n DecisionView,\n AdrOptions\n> = defineKind<DecisionStatus, DecisionEvents, DecisionState, DecisionView, AdrOptions>({\n name: \"decision\",\n schema: \"decision/v1\",\n states: [\"proposed\", \"accepted\", \"rejected\", \"withdrawn\", \"deprecated\", \"superseded\"],\n events: decisionEvents,\n initial: \"proposed\",\n reduce,\n invariants,\n relate,\n project,\n body: { freezeOn: \"accepted\" },\n layout: { bodies: \"decisions\", events: \"events\" },\n defaultRoot: \"docs/adr\",\n sourceName: \"adr\",\n numbering: { on: \"accepted\", format: formatDecisionNumber, parse: parseDecisionNumber },\n templates: {\n dir: \"templates\",\n nameField: \"template\",\n versionField: \"template_version\",\n lintIn: [\"proposed\"],\n lintOn: \"accepted\",\n requireSections: [\"scope\"],\n },\n scope: { event: \"scoped\", activeIn: [\"proposed\", \"accepted\", \"deprecated\"] },\n options: Object.freeze({ acceptRequiresHuman: true }),\n});\n"],"mappings":"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"}
package/dist/kind.js ADDED
@@ -0,0 +1 @@
1
+ export { n as DECISION_STATUSES, r as REF, t as adrKind, i as formatDecisionNumber, a as parseDecisionNumber } from "./kind-DqFhApu7.js";
@@ -0,0 +1,3 @@
1
+ import type { CommandSpec } from "@nikovirtala/ledger/cli";
2
+ /** `adr accept <decision> [--commit | --no-commit]` (design §5.6). */
3
+ export declare const acceptCommand: CommandSpec;
@@ -0,0 +1,3 @@
1
+ import { type ToolCli } from "@nikovirtala/ledger/cli";
2
+ /** The `adr` tool: its commands, for ledger's `runCli`. */
3
+ export declare function adrCli(version: string): ToolCli;
@@ -0,0 +1,12 @@
1
+ /** The `edit` callback of `proposeDecision`: `null` when the editor exited 0, else a note. */
2
+ export type Edit = (absPath: string) => Promise<string | null>;
3
+ /**
4
+ * The user's editor as an `edit` callback (design §5.7), or `null` when neither `VISUAL` nor
5
+ * `EDITOR` is set. The editor string is run by `sh -c` the way git runs `core.editor`, with the
6
+ * path as the positional parameter `$1`, never interpolated. When stdout isn't a TTY (piped
7
+ * `--json`, say), the editor's stdout goes to stderr so the CLI's stdout stays one document.
8
+ * The callback never throws: a spawn error or a non-zero exit becomes the note.
9
+ */
10
+ export declare function editorFor(env: NodeJS.ProcessEnv, o: {
11
+ readonly stdoutIsTTY: boolean;
12
+ }): Edit | null;
@@ -0,0 +1,3 @@
1
+ import type { CommandSpec } from "@nikovirtala/ledger/cli";
2
+ /** `adr list [--status <status>]…` (design §5.6). */
3
+ export declare const listCommand: CommandSpec;
@@ -0,0 +1,6 @@
1
+ import type { CommandSpec } from "@nikovirtala/ledger/cli";
2
+ /**
3
+ * `adr new <title> …` (design §5.6). The editor runs with `--edit`, or without `--no-edit` when
4
+ * the terminal is interactive and an editor is set.
5
+ */
6
+ export declare const newCommand: CommandSpec;
@@ -0,0 +1,19 @@
1
+ import type { CliIO, GlobalFlags } from "@nikovirtala/ledger/cli";
2
+ import { type DecisionLog } from "../log.js";
3
+ import type { Display } from "./text.js";
4
+ /**
5
+ * The decision log a command works on: `--root` and `--ref` from the globals, git run with the
6
+ * CLI's environment.
7
+ */
8
+ export declare function openForCli(io: CliIO, flags: GlobalFlags, o?: {
9
+ readonly reader?: "worktree" | "index";
10
+ }): Promise<DecisionLog>;
11
+ /**
12
+ * How other decisions display in a write's text, read again from the work tree, like the write
13
+ * result's own views: a commit on the main ref has numbered the decisions it accepted.
14
+ */
15
+ export declare function displayAfterWrite(log: DecisionLog): Promise<{
16
+ readonly display: Display;
17
+ }>;
18
+ /** `--commit`/`--no-commit` when given, else `[policy] auto_commit`. */
19
+ export declare function commitRequested(log: DecisionLog, values: Readonly<Record<string, unknown>>): boolean;
@@ -0,0 +1,3 @@
1
+ import type { CommandSpec } from "@nikovirtala/ledger/cli";
2
+ /** `adr show <decision> [--history]` (design §5.6). */
3
+ export declare const showCommand: CommandSpec;
@@ -0,0 +1,3 @@
1
+ import type { CommandSpec } from "@nikovirtala/ledger/cli";
2
+ /** `adr supersede <decision> --by <decision> …` (design §5.6). */
3
+ export declare const supersedeCommand: CommandSpec;
@@ -0,0 +1,16 @@
1
+ import type { DecisionListJson, DecisionShowJson } from "../views.js";
2
+ import type { WriteResultJson } from "../write.js";
3
+ /** How a decision id is shown: its display (`ADR-0007`), or the id when it has no number. */
4
+ export type Display = (id: string) => string;
5
+ /** `adr list`: one row per decision, `→ <effective>` when it differs from the decision. */
6
+ export declare function listText(doc: DecisionListJson, display: Display): string;
7
+ /**
8
+ * The text of `adr new|accept|supersede` (design §5.6). `subject` names what a refused command
9
+ * was about; `number` is the decision's number in the write result, if it has one now.
10
+ */
11
+ export declare function writeText(doc: WriteResultJson, display: Display, o: {
12
+ readonly subject: string;
13
+ readonly number: string | null;
14
+ }): string;
15
+ /** `adr show`: the state header, the decision's fields and its body. */
16
+ export declare function showText(doc: DecisionShowJson, display: Display): string;