@navbook/cli 0.1.1 → 0.2.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.
Files changed (168) hide show
  1. package/dist/commands/complete.js +124 -0
  2. package/dist/commands/complete.js.map +1 -0
  3. package/dist/{cli/commands → commands}/compose.js +5 -3
  4. package/dist/commands/compose.js.map +1 -0
  5. package/dist/commands/doctor.js +56 -0
  6. package/dist/commands/doctor.js.map +1 -0
  7. package/dist/commands/entity.js +235 -0
  8. package/dist/commands/entity.js.map +1 -0
  9. package/dist/commands/feature.js +202 -0
  10. package/dist/commands/feature.js.map +1 -0
  11. package/dist/commands/init.js +23 -0
  12. package/dist/commands/init.js.map +1 -0
  13. package/dist/{cli/commands → commands}/install.js +1 -2
  14. package/dist/commands/install.js.map +1 -0
  15. package/dist/commands/issue.js +89 -0
  16. package/dist/commands/issue.js.map +1 -0
  17. package/dist/commands/policy.js +49 -0
  18. package/dist/commands/policy.js.map +1 -0
  19. package/dist/commands/pr.js +262 -0
  20. package/dist/commands/pr.js.map +1 -0
  21. package/dist/context.js +21 -0
  22. package/dist/context.js.map +1 -0
  23. package/dist/{cli/editor.js → editor.js} +1 -1
  24. package/dist/editor.js.map +1 -0
  25. package/dist/errors.js.map +1 -0
  26. package/dist/install/completions.js.map +1 -0
  27. package/dist/{cli/install → install}/hook.js +1 -1
  28. package/dist/install/hook.js.map +1 -0
  29. package/dist/{cli/main.js → main.js} +10 -0
  30. package/dist/main.js.map +1 -0
  31. package/dist/program.js +356 -0
  32. package/dist/program.js.map +1 -0
  33. package/dist/{cli/prompt.js → prompt.js} +11 -0
  34. package/dist/prompt.js.map +1 -0
  35. package/dist/render/colors.js.map +1 -0
  36. package/dist/render/detail.js +197 -0
  37. package/dist/render/detail.js.map +1 -0
  38. package/dist/render/table.js.map +1 -0
  39. package/dist/sort.js +77 -0
  40. package/dist/sort.js.map +1 -0
  41. package/package.json +15 -21
  42. package/README.md +0 -165
  43. package/dist/cli/commands/complete.d.ts +0 -9
  44. package/dist/cli/commands/complete.js +0 -72
  45. package/dist/cli/commands/complete.js.map +0 -1
  46. package/dist/cli/commands/compose.d.ts +0 -27
  47. package/dist/cli/commands/compose.js.map +0 -1
  48. package/dist/cli/commands/doctor.d.ts +0 -14
  49. package/dist/cli/commands/doctor.js +0 -127
  50. package/dist/cli/commands/doctor.js.map +0 -1
  51. package/dist/cli/commands/entity.d.ts +0 -55
  52. package/dist/cli/commands/entity.js +0 -209
  53. package/dist/cli/commands/entity.js.map +0 -1
  54. package/dist/cli/commands/init.d.ts +0 -11
  55. package/dist/cli/commands/init.js +0 -39
  56. package/dist/cli/commands/init.js.map +0 -1
  57. package/dist/cli/commands/install.d.ts +0 -17
  58. package/dist/cli/commands/install.js.map +0 -1
  59. package/dist/cli/commands/issue.d.ts +0 -12
  60. package/dist/cli/commands/issue.js +0 -42
  61. package/dist/cli/commands/issue.js.map +0 -1
  62. package/dist/cli/commands/pr.d.ts +0 -64
  63. package/dist/cli/commands/pr.js +0 -466
  64. package/dist/cli/commands/pr.js.map +0 -1
  65. package/dist/cli/commit-flow.d.ts +0 -27
  66. package/dist/cli/commit-flow.js +0 -47
  67. package/dist/cli/commit-flow.js.map +0 -1
  68. package/dist/cli/context.d.ts +0 -39
  69. package/dist/cli/context.js +0 -93
  70. package/dist/cli/context.js.map +0 -1
  71. package/dist/cli/editor.d.ts +0 -23
  72. package/dist/cli/editor.js.map +0 -1
  73. package/dist/cli/errors.d.ts +0 -17
  74. package/dist/cli/errors.js.map +0 -1
  75. package/dist/cli/history-checks.d.ts +0 -21
  76. package/dist/cli/history-checks.js +0 -134
  77. package/dist/cli/history-checks.js.map +0 -1
  78. package/dist/cli/install/completions.d.ts +0 -19
  79. package/dist/cli/install/completions.js.map +0 -1
  80. package/dist/cli/install/hook.d.ts +0 -20
  81. package/dist/cli/install/hook.js.map +0 -1
  82. package/dist/cli/main.d.ts +0 -14
  83. package/dist/cli/main.js.map +0 -1
  84. package/dist/cli/program.d.ts +0 -23
  85. package/dist/cli/program.js +0 -204
  86. package/dist/cli/program.js.map +0 -1
  87. package/dist/cli/prompt.d.ts +0 -22
  88. package/dist/cli/prompt.js.map +0 -1
  89. package/dist/cli/render/colors.d.ts +0 -13
  90. package/dist/cli/render/colors.js.map +0 -1
  91. package/dist/cli/render/detail.d.ts +0 -10
  92. package/dist/cli/render/detail.js +0 -105
  93. package/dist/cli/render/detail.js.map +0 -1
  94. package/dist/cli/render/table.d.ts +0 -19
  95. package/dist/cli/render/table.js.map +0 -1
  96. package/dist/cli/resolve.d.ts +0 -17
  97. package/dist/cli/resolve.js +0 -68
  98. package/dist/cli/resolve.js.map +0 -1
  99. package/dist/cli/workspace.d.ts +0 -52
  100. package/dist/cli/workspace.js +0 -178
  101. package/dist/cli/workspace.js.map +0 -1
  102. package/dist/core/comments.d.ts +0 -31
  103. package/dist/core/comments.js +0 -80
  104. package/dist/core/comments.js.map +0 -1
  105. package/dist/core/files.d.ts +0 -88
  106. package/dist/core/files.js +0 -441
  107. package/dist/core/files.js.map +0 -1
  108. package/dist/core/frontmatter.d.ts +0 -63
  109. package/dist/core/frontmatter.js +0 -149
  110. package/dist/core/frontmatter.js.map +0 -1
  111. package/dist/core/id.d.ts +0 -46
  112. package/dist/core/id.js +0 -66
  113. package/dist/core/id.js.map +0 -1
  114. package/dist/core/index.d.ts +0 -19
  115. package/dist/core/index.js +0 -20
  116. package/dist/core/index.js.map +0 -1
  117. package/dist/core/json.d.ts +0 -18
  118. package/dist/core/json.js +0 -51
  119. package/dist/core/json.js.map +0 -1
  120. package/dist/core/ops.d.ts +0 -92
  121. package/dist/core/ops.js +0 -173
  122. package/dist/core/ops.js.map +0 -1
  123. package/dist/core/person.d.ts +0 -20
  124. package/dist/core/person.js +0 -50
  125. package/dist/core/person.js.map +0 -1
  126. package/dist/core/query.d.ts +0 -30
  127. package/dist/core/query.js +0 -106
  128. package/dist/core/query.js.map +0 -1
  129. package/dist/core/refs.d.ts +0 -12
  130. package/dist/core/refs.js +0 -36
  131. package/dist/core/refs.js.map +0 -1
  132. package/dist/core/slug.d.ts +0 -22
  133. package/dist/core/slug.js +0 -40
  134. package/dist/core/slug.js.map +0 -1
  135. package/dist/core/time.d.ts +0 -14
  136. package/dist/core/time.js +0 -37
  137. package/dist/core/time.js.map +0 -1
  138. package/dist/core/tree.d.ts +0 -94
  139. package/dist/core/tree.js +0 -237
  140. package/dist/core/tree.js.map +0 -1
  141. package/dist/core/validate.d.ts +0 -55
  142. package/dist/core/validate.js +0 -312
  143. package/dist/core/validate.js.map +0 -1
  144. package/dist/git/config.d.ts +0 -12
  145. package/dist/git/config.js +0 -27
  146. package/dist/git/config.js.map +0 -1
  147. package/dist/git/exec.d.ts +0 -35
  148. package/dist/git/exec.js +0 -58
  149. package/dist/git/exec.js.map +0 -1
  150. package/dist/git/history.d.ts +0 -35
  151. package/dist/git/history.js +0 -82
  152. package/dist/git/history.js.map +0 -1
  153. package/dist/git/index-ops.d.ts +0 -20
  154. package/dist/git/index-ops.js +0 -45
  155. package/dist/git/index-ops.js.map +0 -1
  156. package/dist/git/merge.d.ts +0 -27
  157. package/dist/git/merge.js +0 -57
  158. package/dist/git/merge.js.map +0 -1
  159. package/dist/git/refscan.d.ts +0 -32
  160. package/dist/git/refscan.js +0 -82
  161. package/dist/git/refscan.js.map +0 -1
  162. package/dist/git/repo.d.ts +0 -45
  163. package/dist/git/repo.js +0 -95
  164. package/dist/git/repo.js.map +0 -1
  165. /package/dist/{cli/errors.js → errors.js} +0 -0
  166. /package/dist/{cli/install → install}/completions.js +0 -0
  167. /package/dist/{cli/render → render}/colors.js +0 -0
  168. /package/dist/{cli/render → render}/table.js +0 -0
@@ -1,93 +0,0 @@
1
- /**
2
- * Per-invocation context: where the repository is, what time it is, where IDs
3
- * come from, and how output is styled.
4
- *
5
- * This is the one place the conformance hooks `NAV_NOW` and `NAV_IDS` are
6
- * honored (see `doc/spec/fixtures/README.md`). Keeping them here means `core`
7
- * has no notion of testing and every command is deterministic under fixtures.
8
- */
9
- import { webcrypto } from "node:crypto";
10
- import { mintId as coreMintId, isId } from "../core/id.js";
11
- import { toIsoSeconds } from "../core/time.js";
12
- import { findRepo, userIdentity } from "../git/repo.js";
13
- import { NavError } from "./errors.js";
14
- import { makeColors } from "./render/colors.js";
15
- export const NAV_NOW_ENV = "NAV_NOW";
16
- export const NAV_IDS_ENV = "NAV_IDS";
17
- const defaultRandomBytes = (n) => webcrypto.getRandomValues(new Uint8Array(n));
18
- export function makeContext(opts = {}) {
19
- const cwd = opts.cwd ?? process.cwd();
20
- const env = opts.env ?? process.env;
21
- const stdout = opts.stdout ?? process.stdout;
22
- const stderr = opts.stderr ?? process.stderr;
23
- let paths;
24
- try {
25
- paths = findRepo(cwd);
26
- }
27
- catch (error) {
28
- if (opts.requireRepo === false) {
29
- paths = { repoRoot: cwd, navRoot: "", hasNavbook: false };
30
- }
31
- else {
32
- throw new NavError(error instanceof Error ? error.message : String(error));
33
- }
34
- }
35
- const fixedNow = parseFixedNow(env[NAV_NOW_ENV]);
36
- const scriptedIds = parseScriptedIds(env[NAV_IDS_ENV]);
37
- let idCursor = 0;
38
- return {
39
- cwd,
40
- env,
41
- repoRoot: paths.repoRoot,
42
- navRoot: paths.navRoot,
43
- hasNavbook: paths.hasNavbook,
44
- colors: makeColors(stdout, env),
45
- stdout,
46
- stderr,
47
- now: () => (fixedNow ? new Date(fixedNow) : new Date()),
48
- mintId(taken) {
49
- if (scriptedIds) {
50
- const next = scriptedIds[idCursor++];
51
- if (next === undefined) {
52
- throw new NavError(`${NAV_IDS_ENV} is exhausted after ${scriptedIds.length} id(s)`);
53
- }
54
- return next;
55
- }
56
- for (let attempt = 0; attempt < 100; attempt++) {
57
- const id = coreMintId(defaultRandomBytes);
58
- if (!taken?.has(id))
59
- return id;
60
- }
61
- /* c8 ignore next */
62
- throw new NavError("could not mint a collision-free id");
63
- },
64
- identity: () => userIdentity(paths.repoRoot),
65
- };
66
- }
67
- function parseFixedNow(value) {
68
- if (!value)
69
- return null;
70
- const date = new Date(value);
71
- if (Number.isNaN(date.getTime())) {
72
- throw new NavError(`${NAV_NOW_ENV} is not a valid timestamp: ${value}`);
73
- }
74
- return date;
75
- }
76
- function parseScriptedIds(value) {
77
- if (value === undefined)
78
- return null;
79
- const ids = value
80
- .split(",")
81
- .map((id) => id.trim())
82
- .filter((id) => id !== "");
83
- for (const id of ids) {
84
- if (!isId(id))
85
- throw new NavError(`${NAV_IDS_ENV} contains an invalid id: ${id}`);
86
- }
87
- return ids;
88
- }
89
- /** The current instant as an ISO 8601 string with second precision. */
90
- export function nowIso(ctx) {
91
- return toIsoSeconds(ctx.now());
92
- }
93
- //# sourceMappingURL=context.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/cli/context.ts"],"names":[],"mappings":"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"}
@@ -1,23 +0,0 @@
1
- /**
2
- * `$EDITOR` integration for the `--edit` flows.
3
- *
4
- * The editor is always opened on the real Navbook file, exactly as spec 04 §4.3
5
- * describes, so nothing has to be parsed back out of a scratch buffer.
6
- */
7
- import type { Ctx } from "./context.ts";
8
- /** Single-quote a path for a POSIX shell, escaping any embedded quotes. */
9
- export declare function shellQuote(value: string): string;
10
- /** The editor command to use, or null when none can be determined. */
11
- export declare function editorCommand(env: NodeJS.ProcessEnv): string | null;
12
- /** Open `absolutePath` in the user's editor, failing if it exits non-zero. */
13
- export declare function openInEditor(ctx: Ctx, absolutePath: string): void;
14
- /**
15
- * Edit a Navbook file before it exists.
16
- *
17
- * The buffer is a real `.md` file (so editors highlight it) held next to
18
- * `COMMIT_EDITMSG` in the git directory, and it is prefilled with the exact
19
- * frontmatter the file will carry — the author can adjust the title, labels and
20
- * body in one pass. Nothing is created in `.navbook/` until the text is valid,
21
- * so an abort leaves no partial entity behind.
22
- */
23
- export declare function editBuffer(ctx: Ctx, name: string, initial: string): string;
@@ -1 +0,0 @@
1
- {"version":3,"file":"editor.js","sourceRoot":"","sources":["../../src/cli/editor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAExC,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAEnC,2EAA2E;AAC3E,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,OAAO,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC;AAC/C,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,aAAa,CAAC,GAAsB;IAClD,KAAK,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACvB,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;IACxD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,YAAY,CAAC,GAAQ,EAAE,YAAoB;IACzD,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,IAAI,CAAC,sBAAsB,EAAE;YAC3B,0EAA0E;SAC3E,CAAC,CAAC;IACL,CAAC;IACD,yEAAyE;IACzE,yEAAyE;IACzE,uEAAuE;IACvE,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,EAAE;QAChE,KAAK,EAAE,SAAS;QAChB,KAAK,EAAE,IAAI;QACX,GAAG,EAAE,GAAG,CAAC,QAAQ;QACjB,GAAG,EAAE,GAAG,CAAC,GAAG;KACb,CAAC,CAAC;IACH,IAAI,MAAM,CAAC,KAAK;QAAE,IAAI,CAAC,2BAA2B,MAAM,MAAM,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACtF,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC;QAAE,IAAI,CAAC,WAAW,MAAM,wBAAwB,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;AACjG,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAC,GAAQ,EAAE,IAAY,EAAE,OAAe;IAChE,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;IAC9C,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACrC,IAAI,CAAC;QACH,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACxB,OAAO,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACpC,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAChC,CAAC;AACH,CAAC"}
@@ -1,17 +0,0 @@
1
- /**
2
- * Exit codes — spec 04 §4.2: 0 success, 1 operational error, 2 format violation.
3
- */
4
- export type ExitCode = 0 | 1 | 2;
5
- export declare class NavError extends Error {
6
- readonly exitCode: ExitCode;
7
- /** Extra lines printed under the message, e.g. candidate IDs. */
8
- readonly details: string[];
9
- constructor(message: string, opts?: {
10
- exitCode?: ExitCode;
11
- details?: string[];
12
- });
13
- }
14
- /** An operational error: not found, ambiguous, malformed input (exit 1). */
15
- export declare function fail(message: string, details?: string[]): never;
16
- /** A format violation detected by `doctor` (exit 2). */
17
- export declare function failFormat(message: string, details?: string[]): never;
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/cli/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,OAAO,QAAS,SAAQ,KAAK;IACxB,QAAQ,CAAW;IAC5B,iEAAiE;IACxD,OAAO,CAAW;IAE3B,YAAY,OAAe,EAAE,OAAoD,EAAE;QACjF,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;IACpC,CAAC;CACF;AAED,4EAA4E;AAC5E,MAAM,UAAU,IAAI,CAAC,OAAe,EAAE,UAAoB,EAAE;IAC1D,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;AACxD,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,UAAU,CAAC,OAAe,EAAE,UAAoB,EAAE;IAChE,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;AACxD,CAAC"}
@@ -1,21 +0,0 @@
1
- /**
2
- * The doctor checks that need git archaeology — spec 04 §4.3, D7, D9 and D10.
3
- *
4
- * Their decision logic lives in `core/validate.ts`; this module supplies the
5
- * history those pure functions judge. Every check degrades to silence when the
6
- * history is unavailable (a shallow clone, an unfetched commit), because an
7
- * absent object is not evidence of a fault.
8
- */
9
- import { type Repo } from "../core/tree.ts";
10
- import { type Diagnostic } from "../core/validate.ts";
11
- import type { Ctx } from "./context.ts";
12
- /**
13
- * How far a frontmatter timestamp may sit from the commit that introduced it
14
- * before D10 calls it inconsistent.
15
- *
16
- * The specification says "wildly inconsistent" without a number. Two days
17
- * absorbs offline work, a delayed push and any timezone confusion, while still
18
- * catching a timestamp that was copied or typed from the wrong year.
19
- */
20
- export declare const TIMESTAMP_SKEW_HOURS = 48;
21
- export declare function runHistoryChecks(ctx: Ctx, repo: Repo): Diagnostic[];
@@ -1,134 +0,0 @@
1
- /**
2
- * The doctor checks that need git archaeology — spec 04 §4.3, D7, D9 and D10.
3
- *
4
- * Their decision logic lives in `core/validate.ts`; this module supplies the
5
- * history those pure functions judge. Every check degrades to silence when the
6
- * history is unavailable (a shallow clone, an unfetched commit), because an
7
- * absent object is not evidence of a fault.
8
- */
9
- import { parseFile, readRevisions } from "../core/files.js";
10
- import { parseIso } from "../core/time.js";
11
- import { allEntities } from "../core/tree.js";
12
- import { checkRevisionsAppendOnly, checkTimestampSkew, planD9Fix, } from "../core/validate.js";
13
- import { addedAt, blobAt, fileVersions, isAncestor, objectExists } from "../git/history.js";
14
- import { currentBranch, resolveSha } from "../git/repo.js";
15
- import { repoPath } from "./workspace.js";
16
- /**
17
- * How far a frontmatter timestamp may sit from the commit that introduced it
18
- * before D10 calls it inconsistent.
19
- *
20
- * The specification says "wildly inconsistent" without a number. Two days
21
- * absorbs offline work, a delayed push and any timezone confusion, while still
22
- * catching a timestamp that was copied or typed from the wrong year.
23
- */
24
- export const TIMESTAMP_SKEW_HOURS = 48;
25
- export function runHistoryChecks(ctx, repo) {
26
- return [
27
- ...checkAppendOnly(ctx, repo),
28
- ...checkMergedButOpen(ctx, repo),
29
- ...checkTimestamps(ctx, repo),
30
- ];
31
- }
32
- /* ------------------------------------------- D7: revisions are append-only */
33
- function checkAppendOnly(ctx, repo) {
34
- const out = [];
35
- for (const pr of repo.prs) {
36
- const versions = fileVersions(ctx.repoRoot, repoPath(pr.filePath));
37
- if (versions.length < 2)
38
- continue;
39
- const lists = [];
40
- for (const version of versions) {
41
- const text = blobAt(ctx.repoRoot, version.sha, version.path);
42
- if (text === null)
43
- continue;
44
- try {
45
- lists.push(readRevisions(parseFile(text).fm));
46
- }
47
- catch {
48
- // A malformed historical version is D2's business, not D7's.
49
- }
50
- }
51
- const result = checkRevisionsAppendOnly(lists);
52
- if (result.ok)
53
- continue;
54
- out.push({
55
- check: "D7",
56
- level: "error",
57
- path: pr.filePath,
58
- message: `revisions must only be appended to (§2.7): ${result.message}`,
59
- });
60
- }
61
- return out;
62
- }
63
- /* ------------------------------------ D9: merged but not archived (03 §3.5) */
64
- function checkMergedButOpen(ctx, repo) {
65
- const head = resolveSha(ctx.repoRoot, "HEAD");
66
- if (!head)
67
- return [];
68
- // "Merged" only means anything on the branch the PR asked to merge into. On
69
- // its own source branch the head is trivially an ancestor of HEAD, and on an
70
- // unrelated branch containing it the fact is not actionable.
71
- const branch = currentBranch(ctx.repoRoot);
72
- if (!branch)
73
- return [];
74
- const out = [];
75
- for (const pr of repo.prs) {
76
- if (pr.status !== "open")
77
- continue;
78
- if (pr.fm.target !== branch)
79
- continue;
80
- const revisions = readRevisions(pr.fm);
81
- const latest = revisions[revisions.length - 1];
82
- // An unfetched head is not evidence of anything.
83
- if (!latest || !objectExists(ctx.repoRoot, latest.head))
84
- continue;
85
- if (!isAncestor(ctx.repoRoot, latest.head, head))
86
- continue;
87
- out.push({
88
- check: "D9",
89
- level: "warning",
90
- path: pr.dirPath,
91
- message: `#${pr.id} is merged into this branch but still filed under prs/open/; move it to prs/merged/`,
92
- fix: planD9Fix(pr),
93
- });
94
- }
95
- return out;
96
- }
97
- /* --------------------------------- D10: timestamps versus the commit record */
98
- function checkTimestamps(ctx, repo) {
99
- const out = [];
100
- for (const entity of allEntities(repo)) {
101
- // An entity whose timestamps legitimately predate the commit that carries
102
- // them: bulk-imported from a forge (§2.4), or archived from an era the
103
- // visible history may no longer reach (03 §3.6).
104
- if (entity.archived || entity.fm["imported-from"] !== undefined)
105
- continue;
106
- const created = typeof entity.fm.created === "string" ? parseIso(entity.fm.created) : null;
107
- if (created) {
108
- const added = addedAt(ctx.repoRoot, repoPath(entity.filePath));
109
- if (added && !checkTimestampSkew(created, added.authored, TIMESTAMP_SKEW_HOURS)) {
110
- out.push({
111
- check: "D10",
112
- level: "warning",
113
- path: entity.filePath,
114
- message: `'created: ${entity.fm.created}' is more than ${TIMESTAMP_SKEW_HOURS}h from the commit that added it (${added.authored.toISOString().slice(0, 10)})`,
115
- });
116
- }
117
- }
118
- for (const comment of entity.comments) {
119
- const added = addedAt(ctx.repoRoot, repoPath(comment.path));
120
- if (!added)
121
- continue;
122
- if (checkTimestampSkew(comment.date, added.authored, TIMESTAMP_SKEW_HOURS))
123
- continue;
124
- out.push({
125
- check: "D10",
126
- level: "warning",
127
- path: comment.path,
128
- message: `the filename timestamp is more than ${TIMESTAMP_SKEW_HOURS}h from the commit that added it (${added.authored.toISOString().slice(0, 10)})`,
129
- });
130
- }
131
- }
132
- return out;
133
- }
134
- //# sourceMappingURL=history-checks.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"history-checks.js","sourceRoot":"","sources":["../../src/cli/history-checks.ts"],"names":[],"mappings":"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"}
@@ -1,19 +0,0 @@
1
- /**
2
- * Shell completions.
3
- *
4
- * The scripts stay deliberately thin: anything that needs to know about the
5
- * repository calls back into `nav __complete`, so completion behavior lives in
6
- * one implementation rather than three shell dialects.
7
- */
8
- export declare const SHELLS: readonly ["bash", "zsh", "fish"];
9
- export type Shell = (typeof SHELLS)[number];
10
- export declare function isShell(value: string): value is Shell;
11
- /** Guess the user's shell from `$SHELL`, defaulting to bash. */
12
- export declare function detectShell(env: NodeJS.ProcessEnv): Shell;
13
- /** Where a shell looks for per-user completion scripts. */
14
- export declare function completionPath(shell: Shell, env: NodeJS.ProcessEnv): string;
15
- /** Extra advice printed after installing, where a shell needs configuration. */
16
- export declare function completionNote(shell: Shell, path: string): string | null;
17
- export declare function completionScript(shell: Shell): string;
18
- export declare function installCompletions(shell: Shell, env: NodeJS.ProcessEnv): string;
19
- export declare function uninstallCompletions(shell: Shell, env: NodeJS.ProcessEnv): string | null;
@@ -1 +0,0 @@
1
- {"version":3,"file":"completions.js","sourceRoot":"","sources":["../../../src/cli/install/completions.ts"],"names":[],"mappings":"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"}
@@ -1,20 +0,0 @@
1
- /**
2
- * The `pre-commit` hook — spec 04 §4.5.
3
- *
4
- * The hook is a thin shell script that calls the binary, so `--no-verify` and
5
- * manual hook removal behave exactly as users expect. It is written as a marked
6
- * block appended to any existing hook, and `nav uninstall --hooks` removes
7
- * precisely that block and nothing else.
8
- */
9
- export declare const MARKER_BEGIN = "# >>> navbook >>>";
10
- export declare const MARKER_END = "# <<< navbook <<<";
11
- export declare const HOOK_NAME = "pre-commit";
12
- export declare function hookPath(repoRoot: string): string;
13
- export declare function isInstalled(repoRoot: string): boolean;
14
- /** Append the marked block, creating the hook file if there is none. */
15
- export declare function installHook(repoRoot: string): void;
16
- /**
17
- * Remove exactly the marked block. A hook that contained nothing else is
18
- * deleted; a hook the user also wrote by hand keeps everything they wrote.
19
- */
20
- export declare function uninstallHook(repoRoot: string): void;
@@ -1 +0,0 @@
1
- {"version":3,"file":"hook.js","sourceRoot":"","sources":["../../../src/cli/install/hook.ts"],"names":[],"mappings":"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"}
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * `nav` entry point.
4
- */
5
- import { type ExitCode } from "./errors.ts";
6
- export interface RunOptions {
7
- argv?: string[];
8
- cwd?: string;
9
- env?: NodeJS.ProcessEnv;
10
- stdout?: NodeJS.WriteStream;
11
- stderr?: NodeJS.WriteStream;
12
- }
13
- /** Run the CLI and return its exit code. Never throws for expected failures. */
14
- export declare function run(opts?: RunOptions): ExitCode;
@@ -1 +0,0 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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"}
@@ -1,23 +0,0 @@
1
- /**
2
- * Command tree — spec 04 §4.3: noun-verb, with one verb vocabulary shared by
3
- * both entity kinds, plus root-level utilities.
4
- */
5
- import { Command, Option } from "commander";
6
- import type { EntityKind } from "../core/tree.ts";
7
- import { type CloseOptions, type ExtraColumn } from "./commands/entity.ts";
8
- import type { Ctx } from "./context.ts";
9
- export declare const VERSION = "0.1.0";
10
- export declare function buildProgram(getCtx: () => Ctx): Command;
11
- export interface SharedVerbOptions {
12
- extraColumns: ExtraColumn[];
13
- /** Extra options the noun's `list` accepts, e.g. `--all-refs` for PRs. */
14
- configureList?: (command: Command) => void;
15
- /** Listing implementation, when the noun needs more than the shared one. */
16
- runList?: (ctx: Ctx, terms: string[], options: Record<string, unknown>) => void;
17
- /** Close implementation, when the noun needs more than the shared one. */
18
- runClose?: (ctx: Ctx, id: string, options: CloseOptions) => void;
19
- }
20
- /** Register the verbs both nouns share, so their behavior can never drift. */
21
- export declare function addSharedVerbs(parent: Command, kind: EntityKind, getCtx: () => Ctx, shared: SharedVerbOptions): void;
22
- export declare function collect(value: string, previous: string[]): string[];
23
- export { Option };
@@ -1,204 +0,0 @@
1
- /**
2
- * Command tree — spec 04 §4.3: noun-verb, with one verb vocabulary shared by
3
- * both entity kinds, plus root-level utilities.
4
- */
5
- import { Command, Option } from "commander";
6
- import { cmdComplete } from "./commands/complete.js";
7
- import { cmdDoctor } from "./commands/doctor.js";
8
- import { cmdClose, cmdComment, cmdEdit, cmdList, cmdReopen, cmdShow, } from "./commands/entity.js";
9
- import { cmdId, cmdInit } from "./commands/init.js";
10
- import { cmdInstall, cmdUninstall } from "./commands/install.js";
11
- import { cmdIssueOpen } from "./commands/issue.js";
12
- import { cmdPrClose, cmdPrList, cmdPrMerge, cmdPrOpen, cmdPrReview, cmdPrUpdate, } from "./commands/pr.js";
13
- export const VERSION = "0.1.0";
14
- const QUERY_HELP = `Query terms AND together. Terms:
15
- status:open|closed|merged entity status (path); 'merged' is PR-only
16
- label:L L is among the entity's labels (repeatable, ANDs)
17
- assignee:EMAIL assignee address, or a fragment of its domain
18
- author:EMAIL author address, same matching
19
- milestone:M exact milestone
20
- WORD or "some phrase" case-insensitive substring of the title,
21
- description, or any comment body
22
- Same-key terms OR for single-valued fields (status, author, milestone) and AND
23
- for multi-valued ones (label, assignee). The default query is status:open.`;
24
- /** Help for `--commit`, naming the subject the verb commits under (spec 03 §3.2). */
25
- function commitHelp(kind) {
26
- return `wrap the change in a 'docs${kind ? `(${kind})` : ""}:' commit`;
27
- }
28
- export function buildProgram(getCtx) {
29
- const program = new Command();
30
- program
31
- .name("nav")
32
- .description("Git-native issue and pull-request tracking, stored as files in your repository")
33
- .version(VERSION, "-V, --version")
34
- .showHelpAfterError()
35
- .enablePositionalOptions();
36
- program
37
- .command("init")
38
- .description("create the .navbook/ skeleton at the repository root")
39
- .option("--commit", commitHelp())
40
- .action((opts) => cmdInit(getCtx(), opts));
41
- program
42
- .command("id")
43
- .description("mint and print a fresh Navbook ID")
44
- .option("-n, --count <n>", "how many IDs to print", (value) => Number.parseInt(value, 10), 1)
45
- .action((opts) => cmdId(getCtx(), opts));
46
- program
47
- .command("doctor")
48
- .description("check the tree against the specification")
49
- .option("--staged", "check only what is staged in the index (used by the pre-commit hook)")
50
- .option("--fix", "apply the mechanical repairs offered by the diagnostics")
51
- .option("--json", "one JSON object per diagnostic, newline-delimited")
52
- .action((opts) => cmdDoctor(getCtx(), opts));
53
- program
54
- .command("install")
55
- .description("set up the git alias, merge config, pre-commit hook and completions")
56
- .addOption(new Option("--alias [name]", "git alias name (default: nav)"))
57
- .option("--hooks", "install the pre-commit hook")
58
- .addOption(new Option("--completions [shell]", "bash, zsh or fish (default: $SHELL)"))
59
- .option("--merge-config", "set merge.directoryRenames=true in this repository")
60
- .option("-y, --yes", "do not ask for confirmation")
61
- .action((opts) => cmdInstall(getCtx(), opts));
62
- program
63
- .command("uninstall")
64
- .description("remove what nav install set up")
65
- .addOption(new Option("--alias [name]", "git alias name (default: nav)"))
66
- .option("--hooks", "remove the pre-commit hook block")
67
- .addOption(new Option("--completions [shell]", "bash, zsh or fish (default: $SHELL)"))
68
- .option("--merge-config", "unset merge.directoryRenames")
69
- .option("-y, --yes", "do not ask for confirmation")
70
- .action((opts) => cmdUninstall(getCtx(), opts));
71
- program
72
- .command("__complete", { hidden: true })
73
- .description("internal: print completion candidates for the words typed so far")
74
- .argument("[words...]")
75
- .action((words) => cmdComplete(getCtx(), words));
76
- program.addCommand(buildIssueCommand(getCtx));
77
- program.addCommand(buildPrCommand(getCtx));
78
- return program;
79
- }
80
- function buildPrCommand(getCtx) {
81
- const pr = new Command("pr").description("work with pull requests");
82
- pr.command("open")
83
- .description("open a pull request from the current branch")
84
- .option("--target <branch>", "branch to merge into (default: the repository's default branch)")
85
- .option("--title <text>", "one-line summary (default: the last commit's subject)")
86
- .option("-m, --message <text>", "description text; without it $EDITOR is opened")
87
- .option("--draft", "not yet requesting review")
88
- .option("--label <label>", "add a label (repeatable)", collect, [])
89
- .option("--assignee <email>", "assign to a person (repeatable)", collect, [])
90
- .option("--milestone <name>", "milestone")
91
- .option("--commit", commitHelp("pr"))
92
- .action((opts) => cmdPrOpen(getCtx(), opts));
93
- pr.command("update")
94
- .argument("<id>", "ID or unambiguous prefix")
95
- .description("append a revision pinning the current HEAD")
96
- .option("--commit", commitHelp("pr"))
97
- .action((id, opts) => cmdPrUpdate(getCtx(), id, opts));
98
- pr.command("review")
99
- .argument("<id>", "ID or unambiguous prefix")
100
- .description("review a pull request, bound to a specific revision")
101
- .option("--approve", "record an approving verdict")
102
- .option("--request-changes", "record a request-changes verdict")
103
- .option("-m, --message <text>", "review text; without it $EDITOR is opened")
104
- .option("--revision <sha>", "bind to this revision instead of the latest")
105
- .option("--file <path>", "anchor the comment to a file")
106
- .option("--line <n|start-end>", "anchor the comment to a line or range")
107
- .option("--commit", commitHelp("pr"))
108
- .action((id, opts) => cmdPrReview(getCtx(), id, opts));
109
- pr.command("merge")
110
- .argument("[id]", "ID or unambiguous prefix")
111
- .description("merge a pull request into the checked-out target branch")
112
- .option("--no-ff", "always create a merge commit")
113
- .option("--continue", "finish a merge that stopped for conflict resolution")
114
- // Commander models `--no-ff` as the negation of an implicit `--ff`.
115
- .action((id, opts) => cmdPrMerge(getCtx(), id, { ...opts, noFf: opts.ff === false }));
116
- addSharedVerbs(pr, "pr", getCtx, {
117
- extraColumns: [{ header: "target", value: (entity) => stringOf(entity, "target") }],
118
- runClose: (ctx, id, options) => cmdPrClose(ctx, id, options),
119
- configureList: (command) => {
120
- command.option("--all-refs", "scan all local and fetched remote branches, not just this one");
121
- },
122
- runList: (ctx, terms, options) => cmdPrList(ctx, terms, options),
123
- });
124
- return pr;
125
- }
126
- function stringOf(entity, key) {
127
- const value = entity.fm[key];
128
- return typeof value === "string" ? value : "";
129
- }
130
- function buildIssueCommand(getCtx) {
131
- const issue = new Command("issue").description("work with issues");
132
- issue
133
- .command("open")
134
- .argument("<title>", "one-line summary")
135
- .description("file a new issue")
136
- .option("-m, --message <text>", "description text; without it $EDITOR is opened")
137
- .option("--label <label>", "add a label (repeatable)", collect, [])
138
- .option("--assignee <email>", "assign to a person (repeatable)", collect, [])
139
- .option("--milestone <name>", "milestone")
140
- .option("--commit", commitHelp("issue"))
141
- .action((title, opts) => cmdIssueOpen(getCtx(), title, opts));
142
- addSharedVerbs(issue, "issue", getCtx, { extraColumns: [] });
143
- return issue;
144
- }
145
- /** Register the verbs both nouns share, so their behavior can never drift. */
146
- export function addSharedVerbs(parent, kind, getCtx, shared) {
147
- const noun = kind === "issue" ? "issue" : "pull request";
148
- const { extraColumns } = shared;
149
- const list = parent
150
- .command("list")
151
- .argument("[query...]", "query terms; default status:open")
152
- .description(`list ${kind === "issue" ? "issues" : "pull requests"} matching a query`)
153
- .addHelpText("after", `\n${QUERY_HELP}`)
154
- .option("--json", "one JSON object per entity, newline-delimited");
155
- shared.configureList?.(list);
156
- list.action((terms, opts) => shared.runList
157
- ? shared.runList(getCtx(), terms, { ...opts, extraColumns })
158
- : cmdList(getCtx(), kind, terms, { ...opts, extraColumns }));
159
- parent
160
- .command("show")
161
- .argument("<id>", "ID or unambiguous prefix")
162
- .description(`render one ${noun} and its comments`)
163
- .option("--json", "emit a single JSON object including comments")
164
- .action((id, opts) => cmdShow(getCtx(), kind, id, opts));
165
- parent
166
- .command("edit")
167
- .argument("<id>", "ID or unambiguous prefix")
168
- .description(`open the ${noun}'s file in $EDITOR`)
169
- .option("--commit", commitHelp(kind))
170
- .action((id, opts) => cmdEdit(getCtx(), kind, id, opts));
171
- parent
172
- .command("comment")
173
- .argument("<id>", "ID or unambiguous prefix")
174
- .description(`add a comment to a ${noun}`)
175
- .option("-m, --message <text>", "comment text; without it $EDITOR is opened")
176
- .option("--reply-to <comment-id>", "comment this one replies to")
177
- .option("--commit", commitHelp(kind))
178
- .action((id, opts) => cmdComment(getCtx(), kind, id, opts));
179
- parent
180
- .command("close")
181
- .argument("<id>", "ID or unambiguous prefix")
182
- .description(`move the ${noun} to closed/`)
183
- .option("--resolution <value>", "why it was closed, e.g. fixed, wontfix, duplicate")
184
- .option("--duplicate-of <id>", "the entity this duplicates (implies duplicate)")
185
- .option("--commit", commitHelp(kind))
186
- .action((id, opts) => {
187
- const options = { ...opts, duplicateOf: opts.duplicateOf };
188
- if (shared.runClose)
189
- shared.runClose(getCtx(), id, options);
190
- else
191
- cmdClose(getCtx(), kind, id, options);
192
- });
193
- parent
194
- .command("reopen")
195
- .argument("<id>", "ID or unambiguous prefix")
196
- .description(`move the ${noun} back to open/ and clear its resolution`)
197
- .option("--commit", commitHelp(kind))
198
- .action((id, opts) => cmdReopen(getCtx(), kind, id, opts));
199
- }
200
- export function collect(value, previous) {
201
- return [...previous, value];
202
- }
203
- export { Option };
204
- //# sourceMappingURL=program.js.map