@nikovirtala/adr 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -9
- package/dist/cli.js +195 -22
- package/dist/cli.js.map +1 -1
- package/dist/index.js +3 -3
- package/dist/{kind-BcHjCHvi.js → kind-DjvA3dyA.js} +2 -6
- package/dist/{kind-BcHjCHvi.js.map → kind-DjvA3dyA.js.map} +1 -1
- package/dist/kind.js +1 -1
- package/dist/{write-9IaqHRrY.js → scope-CLqH-q1y.js} +1439 -552
- package/dist/scope-CLqH-q1y.js.map +1 -0
- package/dist/types/cli/hooks.d.ts +6 -0
- package/dist/types/cli/index-command.d.ts +3 -0
- package/dist/types/cli/list.d.ts +1 -1
- package/dist/types/cli/open.d.ts +2 -0
- package/dist/types/cli/text.d.ts +6 -0
- package/dist/types/commit-actions.d.ts +72 -0
- package/dist/types/config.d.ts +7 -1
- package/dist/types/hooks.d.ts +59 -0
- package/dist/types/index.d.ts +3 -1
- package/dist/types/init.d.ts +7 -1
- package/dist/types/log-index.d.ts +117 -0
- package/dist/types/log.d.ts +34 -1
- package/dist/types/verify.d.ts +6 -4
- package/dist/types/views.d.ts +7 -3
- package/dist/types/write.d.ts +28 -10
- package/package.json +2 -2
- package/dist/write-9IaqHRrY.js.map +0 -1
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `{action}` of a commit that writes one event of each type (design §4.3), and what the title slot
|
|
3
|
+
* names: the decision's title for the events that change whether it is decided, else its display.
|
|
4
|
+
*/
|
|
5
|
+
export declare const ACTIONS: {
|
|
6
|
+
readonly proposed: {
|
|
7
|
+
readonly action: "propose to";
|
|
8
|
+
readonly names: "title";
|
|
9
|
+
};
|
|
10
|
+
readonly accepted: {
|
|
11
|
+
readonly action: "decide to";
|
|
12
|
+
readonly names: "title";
|
|
13
|
+
};
|
|
14
|
+
readonly rejected: {
|
|
15
|
+
readonly action: "decide not to";
|
|
16
|
+
readonly names: "title";
|
|
17
|
+
};
|
|
18
|
+
readonly withdrawn: {
|
|
19
|
+
readonly action: "withdraw the proposal to";
|
|
20
|
+
readonly names: "title";
|
|
21
|
+
};
|
|
22
|
+
readonly deprecated: {
|
|
23
|
+
readonly action: "deprecate";
|
|
24
|
+
readonly names: "display";
|
|
25
|
+
};
|
|
26
|
+
readonly superseded: {
|
|
27
|
+
readonly action: "supersede";
|
|
28
|
+
readonly names: "display";
|
|
29
|
+
};
|
|
30
|
+
readonly noted: {
|
|
31
|
+
readonly action: "add a note to";
|
|
32
|
+
readonly names: "display";
|
|
33
|
+
};
|
|
34
|
+
readonly linked: {
|
|
35
|
+
readonly action: "link";
|
|
36
|
+
readonly names: "display";
|
|
37
|
+
};
|
|
38
|
+
readonly scoped: {
|
|
39
|
+
readonly action: "set the scope of";
|
|
40
|
+
readonly names: "display";
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
/** `{action}` of `adr index --commit`, whose title slot holds `the decision index`. */
|
|
44
|
+
export declare const INDEX_ACTION = "regenerate";
|
|
45
|
+
/** What `adr index --commit`'s title slot holds. */
|
|
46
|
+
export declare const INDEX_TITLE = "the decision index";
|
|
47
|
+
/** The longest `{action}`, which `[commit] subject` must leave room for. */
|
|
48
|
+
export declare const LONGEST_ACTION: number;
|
|
49
|
+
/** The longest display: `ADR-` and up to 9 digits (`formatDecisionNumber`, kind/project.ts). */
|
|
50
|
+
export declare const DISPLAY_LENGTH = 13;
|
|
51
|
+
/** What a link's title slot names after the display when the target is in another log. */
|
|
52
|
+
export declare const CROSS_LOG_LINK = "to a decision in another log";
|
|
53
|
+
/** adr's commit-subject placeholders, each with its longest value (design §4.2). */
|
|
54
|
+
export declare const COMMIT_VARS: Readonly<{
|
|
55
|
+
action: number;
|
|
56
|
+
id: 8;
|
|
57
|
+
display: 13;
|
|
58
|
+
command: 9;
|
|
59
|
+
}>;
|
|
60
|
+
/**
|
|
61
|
+
* The names the title placeholder holds instead of a title, which are never shortened, each with
|
|
62
|
+
* its action: supersede's `<display> with <display>` and a link's `<display> to <display>` or
|
|
63
|
+
* `<display> to a decision in another log` (`planLink` in write.ts), and `adr index`'s
|
|
64
|
+
* `the decision index`. The shorter names (a display, at most 13 characters) always fit in the
|
|
65
|
+
* room a title gets.
|
|
66
|
+
*/
|
|
67
|
+
export declare const COMMIT_NAMES: readonly {
|
|
68
|
+
length: number;
|
|
69
|
+
vars: {
|
|
70
|
+
action: number;
|
|
71
|
+
};
|
|
72
|
+
}[];
|
package/dist/types/config.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export interface AdrConfig {
|
|
|
7
7
|
readonly defaultTemplate: string;
|
|
8
8
|
/** `[log] main_branch`: the ref numbers come from; `null` resolves it automatically. */
|
|
9
9
|
readonly mainBranch: string | null;
|
|
10
|
-
/** `[log] index`:
|
|
10
|
+
/** `[log] index`: `committed` keeps a generated `<root>/index.md` fresh and verified. */
|
|
11
11
|
readonly index: "committed" | "none";
|
|
12
12
|
/** `[policy] accept_requires_human`. */
|
|
13
13
|
readonly acceptRequiresHuman: boolean;
|
|
@@ -17,6 +17,12 @@ export interface AdrConfig {
|
|
|
17
17
|
readonly mcpCanDecide: boolean;
|
|
18
18
|
/** `[verify] fail_on`. */
|
|
19
19
|
readonly failOn: Severity;
|
|
20
|
+
/** `[verify] governed_by_inactive`: the severity of `decision/governed-by-inactive`. */
|
|
21
|
+
readonly governedByInactive: Severity;
|
|
22
|
+
/** `[hooks] scope_follow_renames`: what the pre-commit hook does with renames of covered files. */
|
|
23
|
+
readonly scopeFollowRenames: "stage" | "warn" | "off";
|
|
24
|
+
/** `[hooks] index`: whether the pre-commit hook only checks `index.md` or regenerates it. */
|
|
25
|
+
readonly hookIndex: "check" | "stage";
|
|
20
26
|
/** `[commit] subject`: the template of `--commit` subjects. */
|
|
21
27
|
readonly commitSubject: CommitTemplate;
|
|
22
28
|
/** `[scope] anchor_keyword`: the code-anchor keyword, `adr` in `// adr:<id>`. */
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { type Finding, type HookManager, type HookName, type Severity } from "@nikovirtala/ledger";
|
|
2
|
+
import type { DecisionLog } from "./log.js";
|
|
3
|
+
/** `adr hooks … --json` (design 2b §4.3); `hooks run` prints `ledger-findings/v1` instead. */
|
|
4
|
+
export interface HooksResultJson {
|
|
5
|
+
readonly format: "adr-hooks/v1";
|
|
6
|
+
readonly action: "install" | "uninstall" | "print" | "trailers";
|
|
7
|
+
/** Repo-relative shim paths written or removed. */
|
|
8
|
+
readonly written: readonly string[];
|
|
9
|
+
readonly unchanged: readonly string[];
|
|
10
|
+
readonly registrations: readonly {
|
|
11
|
+
readonly hook: HookName;
|
|
12
|
+
readonly argv: readonly string[];
|
|
13
|
+
}[];
|
|
14
|
+
/** `print` only. */
|
|
15
|
+
readonly snippet: string | null;
|
|
16
|
+
/** `trailers` only: the trailers added, in order. */
|
|
17
|
+
readonly trailers: readonly (readonly [string, string])[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* adr's command per hook (design 2b D4), after `adr`. `--root <root>` comes first only when the
|
|
21
|
+
* root can't be found without it: no `<repo>/adr.toml` names it and it isn't `docs/adr`. So the
|
|
22
|
+
* hooks see the same config as a plain `adr` run, and never print the root-override note.
|
|
23
|
+
*/
|
|
24
|
+
export declare function decisionHookCommands(log: DecisionLog): Partial<Record<HookName, readonly string[]>>;
|
|
25
|
+
/**
|
|
26
|
+
* Registers adr's four commands in ledger's shims, one per hook and shared with other ark tools
|
|
27
|
+
* (design 2b D4). With `core.hooksPath` set or a foreign hook file present, it writes the rest and
|
|
28
|
+
* then throws `HookConflictError` (exit 2), naming each conflict and the `print` command.
|
|
29
|
+
*/
|
|
30
|
+
export declare function installDecisionHooks(log: DecisionLog): Promise<HooksResultJson>;
|
|
31
|
+
/** Removes adr from every shim; a shim left with no tool is deleted. */
|
|
32
|
+
export declare function uninstallDecisionHooks(log: DecisionLog): Promise<HooksResultJson>;
|
|
33
|
+
/** The config to paste into a hook manager instead of installing shims. */
|
|
34
|
+
export declare function printDecisionHooks(log: DecisionLog, manager: HookManager): HooksResultJson;
|
|
35
|
+
/**
|
|
36
|
+
* The `commit-msg` step (P1 §7.1): appends one `ADR`/`ADR-Event` pair per staged added event file
|
|
37
|
+
* of the log, by path, keeping repeats (`ifExists: "add"`). It does nothing for a message that
|
|
38
|
+
* already has an `ADR-Event:` trailer (an `adr … --commit` message), or during a merge, whose
|
|
39
|
+
* events came with their own commits' trailers. Throws `UsageError` when the file is missing.
|
|
40
|
+
*/
|
|
41
|
+
export declare function addHookTrailers(log: DecisionLog, messageFile: string): Promise<HooksResultJson>;
|
|
42
|
+
/**
|
|
43
|
+
* `adr hooks run pre-commit` (design 2b D8): rename following, then the index, then `verify
|
|
44
|
+
* --staged`, stopping at the first step that fails. `worktree` must be opened with the work-tree
|
|
45
|
+
* reader, because rename following writes through `write()`; `index` with the index reader, for
|
|
46
|
+
* the config as staged, the index render and verify. Only the index step stages `index.md`, and
|
|
47
|
+
* only with `[hooks] index = "stage"`; rename following passes `index: "skip"`. Neither stages
|
|
48
|
+
* into a temporary index (`stagingSafe`). A step that can't run throws (exit 2).
|
|
49
|
+
*/
|
|
50
|
+
export declare function runPreCommitHook(o: {
|
|
51
|
+
readonly worktree: DecisionLog;
|
|
52
|
+
readonly index: DecisionLog;
|
|
53
|
+
readonly env: NodeJS.ProcessEnv;
|
|
54
|
+
}): Promise<{
|
|
55
|
+
readonly exit: 0 | 1;
|
|
56
|
+
readonly findings: readonly Finding[];
|
|
57
|
+
readonly notes: readonly string[];
|
|
58
|
+
readonly failOn: Severity;
|
|
59
|
+
}>;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export { type AdrConfig, DEFAULT_ADR_CONFIG, parseAdrConfig } from "./config.js";
|
|
2
|
+
export { addHookTrailers, decisionHookCommands, type HooksResultJson, installDecisionHooks, printDecisionHooks, runPreCommitHook, uninstallDecisionHooks, } from "./hooks.js";
|
|
2
3
|
export { type InitResultJson, initDecisionLog } from "./init.js";
|
|
3
4
|
export { type AdrOptions, adrKind, DECISION_STATUSES, type DecisionEvents, type DecisionState, type DecisionStatus, type DecisionView, formatDecisionNumber, type LinkRel, parseDecisionNumber, REF, } from "./kind.js";
|
|
4
|
-
export { type DecisionLog, type DecisionsRead, openDecisionLog, readDecisions, readDecisionsFrom, resolveDecision, } from "./log.js";
|
|
5
|
+
export { type ChangedSince, changedSince, type DecisionLog, type DecisionsRead, openDecisionLog, readDecisions, readDecisionsFrom, resolveDecision, } from "./log.js";
|
|
6
|
+
export { type IndexResultJson, indexDecisionLog, renderDecisionIndex } from "./log-index.js";
|
|
5
7
|
export { type DecisionForJson, type DecisionsForJson, decisionsFor, type UnresolvedAnchorJson, } from "./scope.js";
|
|
6
8
|
export { adrChecks, verifyDecisions } from "./verify.js";
|
|
7
9
|
export { type DecisionListJson, type DecisionShowJson, listDecisions, type NumberingJson, showDecision, stateHeader, } from "./views.js";
|
package/dist/types/init.d.ts
CHANGED
|
@@ -12,12 +12,18 @@ export interface InitResultJson {
|
|
|
12
12
|
readonly commit: string | null;
|
|
13
13
|
readonly notes: readonly string[];
|
|
14
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* What the recovery hint says about rerunning `adr init` after `git commit` failed (design 2b D5):
|
|
17
|
+
* init keeps existing files, so it would commit nothing.
|
|
18
|
+
*/
|
|
19
|
+
export declare const INIT_RERUN = "Running adr init again won't commit them: the files exist now, so it keeps them and commits nothing.";
|
|
15
20
|
/**
|
|
16
21
|
* `adr init` (design §6.2): writes a config for the log, unless one is found, and each built-in
|
|
17
22
|
* template in `o.templates` (default `nygard`) to `<root>/templates/`, never overwriting a file.
|
|
18
23
|
* A `--root` other than `docs/adr` gets a repo-level `adr.toml` naming it, so later commands find
|
|
19
24
|
* the log without `--root`; when that file exists for another log, the config goes in the root.
|
|
20
|
-
* With `
|
|
25
|
+
* With `[log] index = "committed"` it also writes `<root>/index.md` unless one exists. With
|
|
26
|
+
* `commit` (default `[policy] auto_commit`) the written files are committed on their own;
|
|
21
27
|
* nothing written means nothing committed. No events are written.
|
|
22
28
|
*/
|
|
23
29
|
export declare function initDecisionLog(log: DecisionLog, o?: {
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { type Check, type Finding, type Git, type IndexSpec, type LogLayout, type TreeReader } from "@nikovirtala/ledger";
|
|
2
|
+
import type { AdrConfig } from "./config.js";
|
|
3
|
+
import { type DecisionView } from "./kind.js";
|
|
4
|
+
import { type DecisionLog } from "./log.js";
|
|
5
|
+
import type { WriteOptions } from "./write.js";
|
|
6
|
+
/** `adr index --json` (design 2b §4.5). */
|
|
7
|
+
export interface IndexResultJson {
|
|
8
|
+
readonly format: "adr-index/v1";
|
|
9
|
+
/** The index file, repo-relative: `<root>/index.md`. */
|
|
10
|
+
readonly path: string;
|
|
11
|
+
readonly check: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* `--check`: no finding. Otherwise: the copies the command compares (the work tree and the
|
|
14
|
+
* index, or HEAD's when committing) already held the render.
|
|
15
|
+
*/
|
|
16
|
+
readonly fresh: boolean;
|
|
17
|
+
/** Repo-relative paths this command wrote. */
|
|
18
|
+
readonly written: readonly string[];
|
|
19
|
+
readonly commit: string | null;
|
|
20
|
+
/** `--check`'s findings; `[]` otherwise. */
|
|
21
|
+
readonly findings: readonly Finding[];
|
|
22
|
+
readonly notes: readonly string[];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* What the recovery hint says about rerunning `adr index --commit` after `git commit` failed
|
|
26
|
+
* (design 2b D5). It names the file, not the path, which the hint lists above it.
|
|
27
|
+
*/
|
|
28
|
+
export declare const INDEX_RERUN = "You can also run adr index --commit again once git accepts the commit; it commits index.md while it differs from HEAD's.";
|
|
29
|
+
/**
|
|
30
|
+
* The step before the manual commit when a write's second index render failed after staging
|
|
31
|
+
* (design 2b §4.5 step 4).
|
|
32
|
+
*/
|
|
33
|
+
export declare const INDEX_BEFORE: (root: string) => string;
|
|
34
|
+
/**
|
|
35
|
+
* The step after the manual commit when the commit carried the index: the commit's render leaves
|
|
36
|
+
* out other decisions' uncommitted entries (design 2b D5, §4.5 step 5).
|
|
37
|
+
*/
|
|
38
|
+
export declare const INDEX_AFTER: (root: string) => string;
|
|
39
|
+
/** The repo-relative path of a log's generated index. */
|
|
40
|
+
export declare const indexPath: (layout: LogLayout) => string;
|
|
41
|
+
/**
|
|
42
|
+
* adr's index spec (01:209: active decisions first), built per render so that a superseded
|
|
43
|
+
* decision's status can name its successor's display from `views`.
|
|
44
|
+
*/
|
|
45
|
+
export declare const DECISION_INDEX: (root: string, views: ReadonlyMap<string, DecisionView>) => IndexSpec<DecisionView>;
|
|
46
|
+
/**
|
|
47
|
+
* The index `tree` must hold: its decisions, numbered as they will be once the commit holding
|
|
48
|
+
* `tree` (which builds on `history`: HEAD, a commit, or null on an unborn HEAD) is on main
|
|
49
|
+
* (design 2b D2), with `[log] main_branch`'s numbers first. A tree that isn't a commit's (the work
|
|
50
|
+
* tree, the index) also merges `MERGE_HEAD` while a merge is in progress. In a shallow clone the
|
|
51
|
+
* numbers continue from those `history`'s index recorded; `null` when there are none, so the
|
|
52
|
+
* numbers can't be projected.
|
|
53
|
+
*/
|
|
54
|
+
export declare function renderDecisionIndex(git: Git, o: {
|
|
55
|
+
readonly layout: LogLayout;
|
|
56
|
+
readonly adr: AdrConfig;
|
|
57
|
+
readonly tree: TreeReader;
|
|
58
|
+
readonly history: string | null;
|
|
59
|
+
}): Promise<string | null>;
|
|
60
|
+
/**
|
|
61
|
+
* What the unstaged-files `index/stale` finding and the matching write note both start with:
|
|
62
|
+
* `path` lists `files` (some of them), which aren't staged.
|
|
63
|
+
*/
|
|
64
|
+
export declare function unstagedIndexText(path: string, files: readonly string[]): string;
|
|
65
|
+
/**
|
|
66
|
+
* The log's event and body files whose work-tree content isn't staged (untracked or modified),
|
|
67
|
+
* sorted: the cause of a staged `index.md` that only the work tree's render matches.
|
|
68
|
+
*/
|
|
69
|
+
export declare function unstagedLogFiles(git: Git, layout: LogLayout): Promise<string[]>;
|
|
70
|
+
/**
|
|
71
|
+
* The verify check that `<root>/index.md` is current (design 2b §4.5, "Freshness in verify"). In
|
|
72
|
+
* staged mode (the pre-commit hook), a stale staged copy that equals the work tree's render
|
|
73
|
+
* means another decision's files aren't staged: writes stage the work tree's render (D2), and
|
|
74
|
+
* `adr index` would change nothing. The finding then names those files and says to stage them.
|
|
75
|
+
*/
|
|
76
|
+
export declare function decisionIndexCheck(log: DecisionLog): Check;
|
|
77
|
+
/** Whether `bytes` (null: absent) hold exactly `text`. */
|
|
78
|
+
export declare function holdsText(bytes: Uint8Array | null, text: string): boolean;
|
|
79
|
+
/** HEAD's copy of `path`; `null` when it is absent or HEAD is unborn. */
|
|
80
|
+
export declare function headBytes(git: Git, path: string): Promise<Uint8Array | null>;
|
|
81
|
+
/** HEAD's tree, or an empty tree on an unborn HEAD. */
|
|
82
|
+
export declare function headTree(git: Git, head: string | null): Promise<TreeReader>;
|
|
83
|
+
/**
|
|
84
|
+
* Brings the work-tree copy of `path` to `text` (atomically, when it differs) and reports whether
|
|
85
|
+
* the staged copy differs, so the caller stages it. `old` is the work-tree copy before the write
|
|
86
|
+
* (`null` when absent), for rollback.
|
|
87
|
+
*/
|
|
88
|
+
export declare function writeIndexCopy(git: Git, path: string, text: string): Promise<{
|
|
89
|
+
readonly wrote: boolean;
|
|
90
|
+
readonly old: Uint8Array | null;
|
|
91
|
+
readonly stage: boolean;
|
|
92
|
+
}>;
|
|
93
|
+
/** The first line of an error's message, for notes and headlines. */
|
|
94
|
+
export declare const firstLine: (err: unknown) => string;
|
|
95
|
+
/** `adr index`'s result and whether the work-tree refresh after a commit changed a copy. */
|
|
96
|
+
export interface IndexRun {
|
|
97
|
+
readonly doc: IndexResultJson;
|
|
98
|
+
/** With a commit requested: step 5 wrote or staged the work tree's render. */
|
|
99
|
+
readonly refreshed: boolean;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* `adr index` (design 2b §4.5) with what the text output needs; `indexDecisionLog` is the
|
|
103
|
+
* library entry.
|
|
104
|
+
*/
|
|
105
|
+
export declare function runDecisionIndex(log: DecisionLog, o?: WriteOptions & {
|
|
106
|
+
readonly check?: boolean;
|
|
107
|
+
}): Promise<IndexRun>;
|
|
108
|
+
/**
|
|
109
|
+
* `adr index [--check] [--commit | --no-commit] [-m <message>]` (design 2b §4.5): renders
|
|
110
|
+
* `<root>/index.md` and writes and stages it where the work tree or the index differ. With
|
|
111
|
+
* `commit` (default `[policy] auto_commit`) it renders HEAD's tree and commits the file alone when
|
|
112
|
+
* HEAD's copy differs, then refreshes the work tree's copy, which may include other decisions'
|
|
113
|
+
* uncommitted entries. `check` writes nothing and reports `index/*` findings.
|
|
114
|
+
*/
|
|
115
|
+
export declare function indexDecisionLog(log: DecisionLog, o?: WriteOptions & {
|
|
116
|
+
readonly check?: boolean;
|
|
117
|
+
}): Promise<IndexResultJson>;
|
package/dist/types/log.d.ts
CHANGED
|
@@ -33,8 +33,15 @@ export interface DecisionsRead {
|
|
|
33
33
|
/** How the log was located (`ToolLog.notes`); `[]` for a MemoryTree read. */
|
|
34
34
|
readonly notes: readonly string[];
|
|
35
35
|
}
|
|
36
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* `numberLog` on the repository, then `readDecisionsFrom(log.tree, …)`. In a shallow clone of a
|
|
38
|
+
* log with `[log] index = "committed"`, the numbers come from `<root>/index.md` in the commit
|
|
39
|
+
* being read (`--ref`, else HEAD, resolved when the numbers are needed), never from the work tree's
|
|
40
|
+
* copy, which may number acceptances that exist only there (design 2b D1, §4.6).
|
|
41
|
+
*/
|
|
37
42
|
export declare function readDecisions(log: DecisionLog): Promise<DecisionsRead>;
|
|
43
|
+
/** The display numbers `readDecisions` uses, with its shallow-clone fallback to `index.md`. */
|
|
44
|
+
export declare function numberDecisions(log: DecisionLog): Promise<Numbering>;
|
|
38
45
|
/** The git-free core of `readDecisions`; tests pass a MemoryTree and a hand-made `Numbering`. */
|
|
39
46
|
export declare function readDecisionsFrom(tree: TreeReader, o: {
|
|
40
47
|
readonly layout: LogLayout;
|
|
@@ -44,6 +51,13 @@ export declare function readDecisionsFrom(tree: TreeReader, o: {
|
|
|
44
51
|
readonly commit?: string | null;
|
|
45
52
|
readonly notes?: readonly string[];
|
|
46
53
|
}): Promise<DecisionsRead>;
|
|
54
|
+
/**
|
|
55
|
+
* The note a read command adds about where numbers come from: the shallow-clone index, or why
|
|
56
|
+
* they are unavailable (`unavailable: false` leaves that one out); `null` for none.
|
|
57
|
+
*/
|
|
58
|
+
export declare function numberingNote(read: DecisionsRead, o: {
|
|
59
|
+
readonly unavailable: boolean;
|
|
60
|
+
}): string | null;
|
|
47
61
|
/** Why numbers are unavailable, in words: `shallow clone` or `no main branch`. */
|
|
48
62
|
export declare function unavailableReason(n: Numbering): string;
|
|
49
63
|
/**
|
|
@@ -51,3 +65,22 @@ export declare function unavailableReason(n: Numbering): string;
|
|
|
51
65
|
* Throws `UsageError` (exit 2) naming the reason when it names nothing.
|
|
52
66
|
*/
|
|
53
67
|
export declare function resolveDecision(read: DecisionsRead, input: string): string;
|
|
68
|
+
/** The `since` key of `adr list --since <rev>` (design 2b D7). */
|
|
69
|
+
export interface ChangedSince {
|
|
70
|
+
/** The revision as given, such as `ORIG_HEAD`. */
|
|
71
|
+
readonly rev: string;
|
|
72
|
+
readonly commit: string;
|
|
73
|
+
/** Event files added since `rev`, sorted by path. */
|
|
74
|
+
readonly events: readonly {
|
|
75
|
+
readonly subject: string;
|
|
76
|
+
readonly type: string;
|
|
77
|
+
readonly path: string;
|
|
78
|
+
}[];
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* The event files in `--ref`'s tree (else HEAD's) that `rev`'s tree lacks (design 2b D7). Diffing
|
|
82
|
+
* trees answers "what did this pull bring" for fast-forwards and merges (`ORIG_HEAD` is the tip
|
|
83
|
+
* before them), and lists nothing for a rebase of your own work, whose events are in both trees.
|
|
84
|
+
* Throws `RefNotFoundError` when either revision doesn't resolve.
|
|
85
|
+
*/
|
|
86
|
+
export declare function changedSince(log: DecisionLog, rev: string): Promise<ChangedSince>;
|
package/dist/types/verify.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { type Check, type Finding, type VerifyMode } from "@nikovirtala/ledger";
|
|
2
|
-
import type
|
|
2
|
+
import { type DecisionLog } from "./log.js";
|
|
3
3
|
/**
|
|
4
|
-
* Every
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Every check for the log: ledger's mechanical and fold checks with adr's actor policy, template
|
|
5
|
+
* lint against the templates in the head tree and, for older versions, the history of
|
|
6
|
+
* `historyRef`, the scope-glob and anchor checks, and the decision checks over code
|
|
7
|
+
* (`decision/governed-by-inactive`, `decision/scope-narrowed`). With `[log] index = "committed"`,
|
|
8
|
+
* also the freshness of `<root>/index.md`.
|
|
7
9
|
*/
|
|
8
10
|
export declare function adrChecks(log: DecisionLog, historyRef: string | null): readonly Check[];
|
|
9
11
|
/** Verifies the decision log in `mode` (staged, range or full) with `adrChecks`. */
|
package/dist/types/views.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { type EventEnvelope, type Finding, type StateHeader } from "@nikovirtala/ledger";
|
|
2
2
|
import type { DecisionStatus, DecisionView } from "./kind.js";
|
|
3
|
-
import type { DecisionsRead } from "./log.js";
|
|
3
|
+
import type { ChangedSince, DecisionsRead } from "./log.js";
|
|
4
4
|
/** The `numbering` key of the read documents. */
|
|
5
5
|
export interface NumberingJson {
|
|
6
6
|
readonly available: boolean;
|
|
7
|
-
readonly reason: "shallow" | "no-main-ref" | null;
|
|
7
|
+
readonly reason: "shallow" | "no-main-ref" | "index" | null;
|
|
8
8
|
readonly ref: string | null;
|
|
9
9
|
}
|
|
10
10
|
/** `adr list --json` (design §5.5). */
|
|
@@ -15,6 +15,8 @@ export interface DecisionListJson {
|
|
|
15
15
|
readonly commit: string | null;
|
|
16
16
|
readonly numbering: NumberingJson;
|
|
17
17
|
readonly decisions: readonly DecisionView[];
|
|
18
|
+
/** With `--since <rev>`: the event files added since `rev`; `null` without it. */
|
|
19
|
+
readonly since: ChangedSince | null;
|
|
18
20
|
/** Newer envelope or schema versions; upgrade adr. */
|
|
19
21
|
readonly unreadable: readonly string[];
|
|
20
22
|
/** First event not `proposed`, or a body with no events; run adr verify. */
|
|
@@ -40,11 +42,13 @@ export interface DecisionShowJson {
|
|
|
40
42
|
/** The `numbering` key of `adr-list/v1`, `adr-show/v1` and `adr-for/v1`. */
|
|
41
43
|
export declare const numberingJson: (read: DecisionsRead) => NumberingJson;
|
|
42
44
|
/**
|
|
43
|
-
* The `adr-list/v1` document: decisions in list order, filtered by `status` and
|
|
45
|
+
* The `adr-list/v1` document: decisions in list order, filtered by `status` and by `since` (only
|
|
46
|
+
* the decisions with event files added since its revision, from `changedSince`), and truncated to
|
|
44
47
|
* `limit` after ordering. `findings` are those of the listed decisions and of the log as a whole.
|
|
45
48
|
*/
|
|
46
49
|
export declare function listDecisions(read: DecisionsRead, o?: {
|
|
47
50
|
readonly status?: readonly DecisionStatus[];
|
|
51
|
+
readonly since?: ChangedSince | null;
|
|
48
52
|
readonly limit?: number;
|
|
49
53
|
}): DecisionListJson;
|
|
50
54
|
/**
|
package/dist/types/write.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Actor, type EventEnvelope, type Finding, type SetOp, type Template, type TemplateSource, type Trailer } from "@nikovirtala/ledger";
|
|
1
|
+
import { type Actor, type EventEnvelope, type Finding, type SetOp, type Template, type TemplateSource, type Trailer, type TreeReader } from "@nikovirtala/ledger";
|
|
2
2
|
import { type DecisionView } from "./kind.js";
|
|
3
3
|
import { type DecisionLog, type DecisionsRead } from "./log.js";
|
|
4
4
|
/** `adr <write command> --json` (design §5.5, §6.1). */
|
|
@@ -9,7 +9,9 @@ export interface WriteResultJson {
|
|
|
9
9
|
/**
|
|
10
10
|
* The decision after the write; before it when `ok` is false (`null` for a refused `new`).
|
|
11
11
|
* After a commit it is read again from the log, so an acceptance committed on the main ref
|
|
12
|
-
* carries its number; otherwise `number` is `null` until the acceptance lands on main.
|
|
12
|
+
* carries its number; otherwise `number` is `null` until the acceptance lands on main. In a
|
|
13
|
+
* shallow clone with a committed index, the number comes from HEAD's `index.md`, which on a
|
|
14
|
+
* branch is the number the decision will get once the branch merges.
|
|
13
15
|
*/
|
|
14
16
|
readonly decision: DecisionView | null;
|
|
15
17
|
/** Each decision superseded by this write, after it (read again after a commit, like `decision`). */
|
|
@@ -33,6 +35,11 @@ export interface WriteOptions {
|
|
|
33
35
|
readonly message?: string | null;
|
|
34
36
|
/** Notes to report before the write's own, such as the attribution notes. */
|
|
35
37
|
readonly notes?: readonly string[];
|
|
38
|
+
/**
|
|
39
|
+
* With `[log] index = "committed"`: `"refresh"` (the default) keeps `<root>/index.md` fresh;
|
|
40
|
+
* `"skip"` leaves it alone (the pre-commit hook's rename following, design 2b D8).
|
|
41
|
+
*/
|
|
42
|
+
readonly index?: "refresh" | "skip";
|
|
36
43
|
}
|
|
37
44
|
export interface ProposeInput {
|
|
38
45
|
readonly title: string;
|
|
@@ -229,11 +236,20 @@ export interface AfterStage {
|
|
|
229
236
|
/** `false` skips the commit: the files stay written and staged, and `commit` is `null`. */
|
|
230
237
|
readonly commit: boolean;
|
|
231
238
|
}
|
|
239
|
+
/** What `applyPlan` did. */
|
|
240
|
+
export interface AppliedPlan {
|
|
241
|
+
/** Repo-relative paths written: the plan's files, then `<root>/index.md` when it was written. */
|
|
242
|
+
readonly written: string[];
|
|
243
|
+
readonly commit: string | null;
|
|
244
|
+
readonly findings: readonly Finding[];
|
|
245
|
+
/** Notes about the index ("not updated", "may be stale"); `[]` when none. */
|
|
246
|
+
readonly notes: readonly string[];
|
|
247
|
+
}
|
|
232
248
|
/**
|
|
233
|
-
*
|
|
234
|
-
*
|
|
235
|
-
* commits `plan.stage` plus the involved subjects' already-staged files with exact trailers.
|
|
249
|
+
* What the recovery hint says about rerunning a write command after `git commit` failed (design
|
|
250
|
+
* 2b D5): the batch is already in the log, so a rerun is refused, writes nothing or duplicates it.
|
|
236
251
|
*/
|
|
252
|
+
export declare const WRITE_RERUN = "Don't run the command again: the log already holds the change, so a rerun would be refused, do nothing, or write it a second time.";
|
|
237
253
|
export declare function applyPlan(log: DecisionLog, plan: WritePlan, o: {
|
|
238
254
|
readonly commit: boolean;
|
|
239
255
|
/** The commit message, without trailers; required when committing. */
|
|
@@ -241,11 +257,13 @@ export declare function applyPlan(log: DecisionLog, plan: WritePlan, o: {
|
|
|
241
257
|
/** `message` is the user's own: append the trailers to its own trailer block, if it ends in one. */
|
|
242
258
|
readonly mergeTrailers?: boolean;
|
|
243
259
|
readonly afterStage?: () => Promise<AfterStage>;
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
260
|
+
/**
|
|
261
|
+
* Renders the log's index for `tree`, which builds on `history` (HEAD, the new commit, or
|
|
262
|
+
* null on an unborn HEAD); `null` when the numbers can't be projected. Given only when the log
|
|
263
|
+
* keeps a committed index (design 2b D2, §4.5).
|
|
264
|
+
*/
|
|
265
|
+
readonly index?: (tree: TreeReader, history: string | null) => Promise<string | null>;
|
|
266
|
+
}): Promise<AppliedPlan>;
|
|
249
267
|
/**
|
|
250
268
|
* The clock, the randomness and `applyPlan` the write functions use. Only tests pass their own
|
|
251
269
|
* (for example an `apply` that fails once); the default is the real ones.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nikovirtala/adr",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Architecture decision records kept as event logs in git: frozen bodies, computed status and supersession chains. CLI and library.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"adr",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"provenance": true
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@nikovirtala/ledger": "^0.
|
|
48
|
+
"@nikovirtala/ledger": "^0.5.0"
|
|
49
49
|
},
|
|
50
50
|
"scripts": {
|
|
51
51
|
"build": "tsdown",
|