@navbook/cli 0.1.2 → 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 (167) 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/{cli/program.js → program.js} +161 -23
  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.map +0 -1
  86. package/dist/cli/prompt.d.ts +0 -22
  87. package/dist/cli/prompt.js.map +0 -1
  88. package/dist/cli/render/colors.d.ts +0 -13
  89. package/dist/cli/render/colors.js.map +0 -1
  90. package/dist/cli/render/detail.d.ts +0 -10
  91. package/dist/cli/render/detail.js +0 -105
  92. package/dist/cli/render/detail.js.map +0 -1
  93. package/dist/cli/render/table.d.ts +0 -19
  94. package/dist/cli/render/table.js.map +0 -1
  95. package/dist/cli/resolve.d.ts +0 -17
  96. package/dist/cli/resolve.js +0 -68
  97. package/dist/cli/resolve.js.map +0 -1
  98. package/dist/cli/workspace.d.ts +0 -52
  99. package/dist/cli/workspace.js +0 -178
  100. package/dist/cli/workspace.js.map +0 -1
  101. package/dist/core/comments.d.ts +0 -31
  102. package/dist/core/comments.js +0 -80
  103. package/dist/core/comments.js.map +0 -1
  104. package/dist/core/files.d.ts +0 -88
  105. package/dist/core/files.js +0 -441
  106. package/dist/core/files.js.map +0 -1
  107. package/dist/core/frontmatter.d.ts +0 -63
  108. package/dist/core/frontmatter.js +0 -149
  109. package/dist/core/frontmatter.js.map +0 -1
  110. package/dist/core/id.d.ts +0 -46
  111. package/dist/core/id.js +0 -66
  112. package/dist/core/id.js.map +0 -1
  113. package/dist/core/index.d.ts +0 -19
  114. package/dist/core/index.js +0 -20
  115. package/dist/core/index.js.map +0 -1
  116. package/dist/core/json.d.ts +0 -18
  117. package/dist/core/json.js +0 -51
  118. package/dist/core/json.js.map +0 -1
  119. package/dist/core/ops.d.ts +0 -92
  120. package/dist/core/ops.js +0 -173
  121. package/dist/core/ops.js.map +0 -1
  122. package/dist/core/person.d.ts +0 -20
  123. package/dist/core/person.js +0 -50
  124. package/dist/core/person.js.map +0 -1
  125. package/dist/core/query.d.ts +0 -30
  126. package/dist/core/query.js +0 -106
  127. package/dist/core/query.js.map +0 -1
  128. package/dist/core/refs.d.ts +0 -12
  129. package/dist/core/refs.js +0 -36
  130. package/dist/core/refs.js.map +0 -1
  131. package/dist/core/slug.d.ts +0 -22
  132. package/dist/core/slug.js +0 -40
  133. package/dist/core/slug.js.map +0 -1
  134. package/dist/core/time.d.ts +0 -14
  135. package/dist/core/time.js +0 -37
  136. package/dist/core/time.js.map +0 -1
  137. package/dist/core/tree.d.ts +0 -94
  138. package/dist/core/tree.js +0 -237
  139. package/dist/core/tree.js.map +0 -1
  140. package/dist/core/validate.d.ts +0 -55
  141. package/dist/core/validate.js +0 -312
  142. package/dist/core/validate.js.map +0 -1
  143. package/dist/git/config.d.ts +0 -12
  144. package/dist/git/config.js +0 -27
  145. package/dist/git/config.js.map +0 -1
  146. package/dist/git/exec.d.ts +0 -35
  147. package/dist/git/exec.js +0 -58
  148. package/dist/git/exec.js.map +0 -1
  149. package/dist/git/history.d.ts +0 -35
  150. package/dist/git/history.js +0 -82
  151. package/dist/git/history.js.map +0 -1
  152. package/dist/git/index-ops.d.ts +0 -20
  153. package/dist/git/index-ops.js +0 -45
  154. package/dist/git/index-ops.js.map +0 -1
  155. package/dist/git/merge.d.ts +0 -27
  156. package/dist/git/merge.js +0 -57
  157. package/dist/git/merge.js.map +0 -1
  158. package/dist/git/refscan.d.ts +0 -32
  159. package/dist/git/refscan.js +0 -82
  160. package/dist/git/refscan.js.map +0 -1
  161. package/dist/git/repo.d.ts +0 -45
  162. package/dist/git/repo.js +0 -95
  163. package/dist/git/repo.js.map +0 -1
  164. /package/dist/{cli/errors.js → errors.js} +0 -0
  165. /package/dist/{cli/install → install}/completions.js +0 -0
  166. /package/dist/{cli/render → render}/colors.js +0 -0
  167. /package/dist/{cli/render → render}/table.js +0 -0
@@ -0,0 +1,124 @@
1
+ /**
2
+ * `nav __complete` — the completion backend the shell scripts call.
3
+ *
4
+ * Given the words typed so far (without the leading `nav`), it prints one
5
+ * candidate per line. Keeping the logic here rather than in three shell
6
+ * dialects is what makes ID and slug completion possible at all.
7
+ */
8
+ import { allEntities, loadRepo } from "@navbook/core";
9
+ import { featureSlugs } from "./feature.js";
10
+ const ROOT_COMMANDS = ["issue", "pr", "feature", "init", "id", "doctor", "install", "uninstall"];
11
+ const SHARED_VERBS = ["open", "list", "show", "edit", "comment", "close", "reopen", "delete"];
12
+ const ISSUE_VERBS = [...SHARED_VERBS, "link", "unlink"];
13
+ const PR_VERBS = [...SHARED_VERBS, "update", "request", "review", "merge"];
14
+ const FEATURE_VERBS = ["open", "list", "show", "edit", "spec"];
15
+ const SPEC_VERBS = ["add", "edit", "list"];
16
+ const QUERY_KEYS = ["status:", "label:", "assignee:", "author:", "milestone:", "feature:"];
17
+ /** Terms only a pull request has (spec 04 §4.3), offered only where they work. */
18
+ const PR_QUERY_KEYS = ["reviewer:", "review:", "awaiting:"];
19
+ /** And the one only an issue has (spec 02 §2.5). */
20
+ const ISSUE_QUERY_KEYS = ["deadline:"];
21
+ export function cmdComplete(ctx, words) {
22
+ for (const candidate of completionsFor(ctx, words))
23
+ ctx.stdout.write(`${candidate}\n`);
24
+ }
25
+ function completionsFor(ctx, words) {
26
+ const [noun, verb] = words;
27
+ if (noun === undefined)
28
+ return ROOT_COMMANDS;
29
+ if (noun === "feature")
30
+ return featureCompletions(ctx, words);
31
+ if (noun !== "issue" && noun !== "pr") {
32
+ return words.length === 1 ? ROOT_COMMANDS : [];
33
+ }
34
+ const kind = noun === "issue" ? "issue" : "pr";
35
+ const verbs = kind === "issue" ? ISSUE_VERBS : PR_VERBS;
36
+ if (verb === undefined)
37
+ return verbs;
38
+ if (!verbs.includes(verb))
39
+ return [];
40
+ if (verb === "list") {
41
+ const keys = kind === "pr" ? [...QUERY_KEYS, ...PR_QUERY_KEYS] : [...QUERY_KEYS, ...ISSUE_QUERY_KEYS];
42
+ return [...keys, ...labels(ctx), ...features(ctx)];
43
+ }
44
+ if (verb === "open")
45
+ return [];
46
+ // Every other verb takes an ID as its first argument.
47
+ return words.length === 2 ? entityCandidates(ctx, kind) : [];
48
+ }
49
+ /**
50
+ * `nav feature …`, whose second word may be a verb or the `spec` group.
51
+ *
52
+ * Slugs are offered wherever one is expected, and document names once the
53
+ * feature is known — which is the whole reason completion is written here
54
+ * rather than in three shell dialects.
55
+ */
56
+ function featureCompletions(ctx, words) {
57
+ const [, verb, third] = words;
58
+ if (verb === undefined)
59
+ return FEATURE_VERBS;
60
+ if (verb === "spec") {
61
+ if (third === undefined)
62
+ return SPEC_VERBS;
63
+ if (!SPEC_VERBS.includes(third))
64
+ return [];
65
+ if (words.length === 3)
66
+ return featureSlugs(ctx);
67
+ // `spec edit <slug> <file>` is the one place a document name is wanted.
68
+ if (third === "edit" && words.length === 4)
69
+ return specNames(ctx, words[3]);
70
+ return [];
71
+ }
72
+ if (!FEATURE_VERBS.includes(verb))
73
+ return [];
74
+ if (verb === "list" || verb === "open")
75
+ return [];
76
+ return words.length === 2 ? featureSlugs(ctx) : [];
77
+ }
78
+ function specNames(ctx, slug) {
79
+ try {
80
+ const feature = loadRepo(ctx, { comments: "none" }).featureBySlug.get(slug);
81
+ return feature ? feature.specs.map((spec) => spec.fileName) : [];
82
+ }
83
+ catch {
84
+ return [];
85
+ }
86
+ }
87
+ function features(ctx) {
88
+ return featureSlugs(ctx).map((slug) => `feature:${slug}`);
89
+ }
90
+ /**
91
+ * Bare IDs and full directory names, so a user can complete either the short
92
+ * form they would type or the readable name they would recognize.
93
+ */
94
+ function entityCandidates(ctx, kind) {
95
+ try {
96
+ const repo = loadRepo(ctx, { comments: "none" });
97
+ return allEntities(repo)
98
+ .filter((entity) => entity.kind === kind)
99
+ .flatMap((entity) => [entity.id, entity.dirName])
100
+ .sort();
101
+ }
102
+ catch {
103
+ return [];
104
+ }
105
+ }
106
+ function labels(ctx) {
107
+ try {
108
+ const repo = loadRepo(ctx, { comments: "none" });
109
+ const found = new Set();
110
+ for (const entity of allEntities(repo)) {
111
+ const values = entity.fm.labels;
112
+ if (!Array.isArray(values))
113
+ continue;
114
+ for (const value of values)
115
+ if (typeof value === "string")
116
+ found.add(`label:${value}`);
117
+ }
118
+ return [...found].sort();
119
+ }
120
+ catch {
121
+ return [];
122
+ }
123
+ }
124
+ //# sourceMappingURL=complete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"complete.js","sourceRoot":"","sources":["../../src/commands/complete.ts"],"names":[],"mappings":"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"}
@@ -6,13 +6,14 @@
6
6
  * the whole file — frontmatter included — so an author can set the title,
7
7
  * labels and body in one pass, and an abort leaves nothing behind.
8
8
  */
9
- import { parseFile } from "../../core/files.js";
9
+ import { parseFile } from "@navbook/core";
10
10
  import { editBuffer } from "../editor.js";
11
11
  import { fail } from "../errors.js";
12
12
  export function composeFile(ctx, opts) {
13
13
  if (opts.message !== undefined) {
14
- if (opts.message.trim() === "")
14
+ if (opts.message.trim() === "" && !opts.allowEmptyBody) {
15
15
  fail(`empty ${opts.noun} text; aborting`);
16
+ }
16
17
  return check(opts, opts.render(opts.message));
17
18
  }
18
19
  const edited = editBuffer(ctx, opts.bufferName, opts.render(""));
@@ -23,8 +24,9 @@ export function composeFile(ctx, opts) {
23
24
  catch (error) {
24
25
  fail(`aborting: ${error instanceof Error ? error.message : String(error)}`);
25
26
  }
26
- if (parsed.body.trim() === "")
27
+ if (parsed.body.trim() === "" && !opts.allowEmptyBody) {
27
28
  fail(`aborting ${opts.noun} due to empty body`);
29
+ }
28
30
  return check(opts, edited);
29
31
  }
30
32
  function check(opts, content) {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compose.js","sourceRoot":"","sources":["../../src/commands/compose.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAiC,SAAS,EAAE,MAAM,eAAe,CAAC;AAEzE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AA4BpC,MAAM,UAAU,WAAW,CAAC,GAAQ,EAAE,IAAoB;IACxD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAC/B,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACvD,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,iBAAiB,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAChD,CAAC;IACD,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IACjE,IAAI,MAAkB,CAAC;IACvB,IAAI,CAAC;QACH,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,aAAa,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC9E,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;QACtD,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,oBAAoB,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,KAAK,CAAC,IAAoB,EAAE,OAAe;IAClD,IAAI,MAAkB,CAAC;IACvB,IAAI,CAAC;QACH,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,aAAa,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC9E,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACvC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,IAAI,CACF,OAAO,IAAI,CAAC,IAAI,mCAAmC,EACnD,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,CAClD,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * `nav doctor` — spec 04 §4.3.
3
+ *
4
+ * Doctor enforces the specification, not a house style: hand edits that are
5
+ * unusual but valid must pass. Errors (exit 2) are format violations; warnings
6
+ * (exit 0) are things worth a look that may be perfectly deliberate. Deciding
7
+ * which is which is `core`'s job; deciding what an exit code is, is this file's.
8
+ */
9
+ import { hasErrors, runDoctor } from "@navbook/core";
10
+ import { failFormat } from "../errors.js";
11
+ export function cmdDoctor(ctx, opts) {
12
+ const { diagnostics, applied } = runDoctor(ctx, { staged: opts.staged, fix: opts.fix });
13
+ if (opts.json) {
14
+ for (const diagnostic of diagnostics) {
15
+ ctx.stdout.write(`${JSON.stringify(toJson(ctx.navDir, diagnostic))}\n`);
16
+ }
17
+ }
18
+ else {
19
+ report(ctx, diagnostics, applied);
20
+ }
21
+ if (hasErrors(diagnostics)) {
22
+ failFormat(`${countErrors(diagnostics)} format violation(s) found`);
23
+ }
24
+ }
25
+ function toJson(navDir, diagnostic) {
26
+ return {
27
+ check: diagnostic.check,
28
+ level: diagnostic.level,
29
+ path: diagnostic.path === "" ? "" : `${navDir}/${diagnostic.path}`,
30
+ message: diagnostic.message,
31
+ };
32
+ }
33
+ function report(ctx, diagnostics, applied) {
34
+ const c = ctx.colors;
35
+ for (const line of applied)
36
+ ctx.stdout.write(`${c.green("fixed")} ${line}\n`);
37
+ for (const diagnostic of diagnostics) {
38
+ const level = diagnostic.level === "error" ? c.red("error") : c.yellow("warning");
39
+ const where = diagnostic.path === "" ? "" : `${ctx.navDir}/${diagnostic.path}: `;
40
+ ctx.stdout.write(`${level} ${c.dim(diagnostic.check)} ${where}${diagnostic.message}\n`);
41
+ }
42
+ const errors = countErrors(diagnostics);
43
+ const warnings = diagnostics.length - errors;
44
+ if (errors === 0 && warnings === 0) {
45
+ ctx.stdout.write(applied.length > 0 ? "No problems remain.\n" : "No problems found.\n");
46
+ return;
47
+ }
48
+ ctx.stdout.write(`${plural(errors, "error")}, ${plural(warnings, "warning")}\n`);
49
+ }
50
+ function plural(count, noun) {
51
+ return `${count} ${noun}${count === 1 ? "" : "s"}`;
52
+ }
53
+ function countErrors(diagnostics) {
54
+ return diagnostics.filter((d) => d.level === "error").length;
55
+ }
56
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,235 @@
1
+ /**
2
+ * The verbs issues and pull requests share — spec 04 §4.3.
3
+ *
4
+ * One implementation serves both nouns; the entity kind only selects which
5
+ * collection is searched, which file name is edited, and which words appear in
6
+ * the report. The work itself is in `ops/entity.ts` — what is left here is
7
+ * gathering what the user typed and phrasing what came back.
8
+ */
9
+ import { applyComment, applyEntityEdit, closeEntity, commentJson, commitReport, currentAuthor, entityJson, executeEntityDelete, findEntity, listEntities, loadRepo, newCommentFile, parentNode, parseListQuery, planEntityDelete, readAssignees, readDeadline, readLabels, readRank, reopenEntity, resolveComment, resolveEntity, resolveEntityForEdit, revalidateEntityFile, reviewSummary, subtaskTree, toNdjson, uncommittedUnder, validateComment, } from "@navbook/core";
10
+ import { openInEditor } from "../editor.js";
11
+ import { fail } from "../errors.js";
12
+ import { askYesNo } from "../prompt.js";
13
+ import { renderDetail } from "../render/detail.js";
14
+ import { renderTable } from "../render/table.js";
15
+ import { parseSortOrder, sortListing } from "../sort.js";
16
+ import { composeFile } from "./compose.js";
17
+ import { warnPolicyProblems } from "./policy.js";
18
+ const PLURAL = { issue: "issues", pr: "pull requests" };
19
+ export function cmdList(ctx, kind, terms, opts) {
20
+ const query = parseListQuery(ctx, terms, kind);
21
+ const matched = listEntities(ctx, kind, query, {
22
+ ...(opts.entities ? { entities: opts.entities } : {}),
23
+ });
24
+ reportList(ctx, kind, matched, opts);
25
+ }
26
+ /**
27
+ * Order a listing the way `--sort` asked, refusing an order that is not one.
28
+ *
29
+ * Applied here rather than in `core`, and to the JSON as well as the table: a
30
+ * caller that pipes a listing asked for the order it asked for, and `--json`
31
+ * that ignored `--sort` would be a second answer to the same question.
32
+ */
33
+ function ordered(matched, opts) {
34
+ return sortListing(matched, parseSortOrder(opts.sort));
35
+ }
36
+ /** Render a listing whose entities have already been collected. */
37
+ export function reportList(ctx, kind, matched, opts) {
38
+ const listing = ordered(matched, opts);
39
+ if (opts.json) {
40
+ if (listing.length === 0)
41
+ return;
42
+ const objects = listing.map((entity) => entityJson(ctx.navDir, entity, opts.jsonExtra?.(entity) ?? {}));
43
+ ctx.stdout.write(`${toNdjson(objects)}\n`);
44
+ return;
45
+ }
46
+ if (listing.length === 0) {
47
+ ctx.stdout.write(`No ${PLURAL[kind]} match this query.\n`);
48
+ return;
49
+ }
50
+ ctx.stdout.write(`${renderList(ctx, listing, opts.extraColumns ?? [])}\n`);
51
+ }
52
+ function renderList(ctx, entities, extra) {
53
+ const columns = [{ header: "id" }, { header: "status" }];
54
+ const values = [(e) => `#${e.id}`, (e) => e.status];
55
+ for (const column of extra) {
56
+ if (column.when && !column.when(entities))
57
+ continue;
58
+ columns.push({
59
+ header: column.header,
60
+ ...(column.flexible ? { flexible: true, minWidth: 6 } : {}),
61
+ });
62
+ values.push(column.value);
63
+ }
64
+ columns.push({ header: "title", flexible: true, minWidth: 20 });
65
+ values.push((e) => e.title);
66
+ if (entities.some((e) => readLabels(e.fm).length > 0)) {
67
+ columns.push({ header: "labels", flexible: true, minWidth: 6 });
68
+ values.push((e) => readLabels(e.fm).join(","));
69
+ }
70
+ if (entities.some((e) => readAssignees(e.fm).length > 0)) {
71
+ columns.push({ header: "assignee", flexible: true, minWidth: 6 });
72
+ values.push((e) => readAssignees(e.fm).join(","));
73
+ }
74
+ // As with labels and assignees: a column nothing in this listing carries is
75
+ // a column of blanks, and the terminal is narrow enough already.
76
+ if (entities.some((e) => readRank(e.fm) !== null)) {
77
+ columns.push({ header: "rank" });
78
+ values.push((e) => {
79
+ const rank = readRank(e.fm);
80
+ return rank === null ? "" : String(rank);
81
+ });
82
+ }
83
+ if (entities.some((e) => readDeadline(e.fm) !== null)) {
84
+ columns.push({ header: "deadline" });
85
+ values.push((e) => readDeadline(e.fm) ?? "");
86
+ }
87
+ const rows = entities.map((entity) => values.map((value) => value(entity)));
88
+ return renderTable(columns, rows, { colors: ctx.colors, width: terminalWidth(ctx) });
89
+ }
90
+ function terminalWidth(ctx) {
91
+ const columns = ctx.stdout.columns;
92
+ return typeof columns === "number" && columns > 20 ? columns : undefined;
93
+ }
94
+ export function cmdShow(ctx, kind, prefix, opts) {
95
+ const repo = loadRepo(ctx);
96
+ const entity = resolveEntity(repo, prefix, kind);
97
+ const reading = repo.reviewPolicy;
98
+ if (kind === "pr")
99
+ warnPolicyProblems(ctx, reading);
100
+ if (opts.json) {
101
+ // `parent` and `subtasks` are frontmatter, so they are already in the
102
+ // object; resolving them would be a second, differently-shaped answer.
103
+ // `review` is not frontmatter at all — it is the derived state of spec 02
104
+ // §2.7, and it is here rather than in `list` because `show` is the command
105
+ // that has already read every comment it is computed from.
106
+ ctx.stdout.write(`${JSON.stringify(entityJson(ctx.navDir, entity, {
107
+ ...(kind === "pr"
108
+ ? {
109
+ review: reviewSummary(entity, reading.policy),
110
+ reviewPolicy: {
111
+ selfReview: reading.policy.selfReview,
112
+ minApprovals: reading.policy.minApprovals,
113
+ declared: reading.declared,
114
+ },
115
+ }
116
+ : {}),
117
+ comments: entity.comments.map((comment) => commentJson(ctx.navDir, comment)),
118
+ }))}\n`);
119
+ return;
120
+ }
121
+ const depth = opts.depth ?? 1;
122
+ if (!Number.isInteger(depth) || depth < 0)
123
+ fail("--depth takes a whole number of levels");
124
+ ctx.stdout.write(`${renderDetail(entity, {
125
+ colors: ctx.colors,
126
+ navDir: ctx.navDir,
127
+ ...(kind === "issue"
128
+ ? {
129
+ links: { parent: parentNode(repo, entity), subtasks: subtaskTree(repo, entity, depth) },
130
+ }
131
+ : { reviewPolicy: reading }),
132
+ })}\n`);
133
+ }
134
+ /* --------------------------------------------------------------------- edit */
135
+ export function cmdEdit(ctx, kind, prefix, opts) {
136
+ const { entity, path } = resolveEntityForEdit(ctx, kind, prefix);
137
+ openInEditor(ctx, path);
138
+ for (const problem of revalidateEntityFile(path, kind)) {
139
+ ctx.stderr.write(`${ctx.colors.yellow("warning:")} ${entity.filePath}: ${problem}\n`);
140
+ }
141
+ const result = applyEntityEdit(ctx, entity, { commit: opts.commit });
142
+ ctx.stdout.write(`Edited #${entity.id} ${ctx.navDir}/${entity.filePath}\n`);
143
+ if (opts.commit)
144
+ ctx.stdout.write(`${commitReport(result)}\n`);
145
+ }
146
+ export function cmdComment(ctx, kind, prefix, opts) {
147
+ const entity = findEntity(ctx, kind, prefix);
148
+ const replyTo = opts.replyTo ? resolveComment(entity, opts.replyTo) : undefined;
149
+ const isReview = opts.review?.verdict !== undefined;
150
+ const noun = isReview ? "review" : "comment";
151
+ const base = {
152
+ author: currentAuthor(ctx),
153
+ body: "",
154
+ ...(replyTo ? { replyTo } : {}),
155
+ ...(opts.review ?? {}),
156
+ };
157
+ const composed = composeFile(ctx, {
158
+ message: opts.message,
159
+ bufferName: "NAVBOOK_COMMENT.md",
160
+ noun,
161
+ render: (body) => newCommentFile({ ...base, body }),
162
+ validate: (parsed) => validateComment(parsed, { onPr: kind === "pr" }),
163
+ });
164
+ const { id, path, run } = applyComment(ctx, entity, { content: composed.content, review: isReview }, { commit: opts.commit });
165
+ ctx.stdout.write(`${isReview ? "Reviewed" : "Commented on"} #${entity.id} ${ctx.navDir}/${path} (#${id})\n`);
166
+ if (opts.commit)
167
+ ctx.stdout.write(`${commitReport(run)}\n`);
168
+ }
169
+ export function cmdClose(ctx, kind, prefix, opts) {
170
+ const { entity, destination, run } = closeEntity(ctx, kind, prefix, opts, {
171
+ commit: opts.commit,
172
+ });
173
+ ctx.stdout.write(`Closed #${entity.id} ${ctx.navDir}/${destination}/\n`);
174
+ if (opts.commit)
175
+ ctx.stdout.write(`${commitReport(run)}\n`);
176
+ }
177
+ export function cmdReopen(ctx, kind, prefix, opts) {
178
+ const { entity, destination, run } = reopenEntity(ctx, kind, prefix, { commit: opts.commit });
179
+ ctx.stdout.write(`Reopened #${entity.id} ${ctx.navDir}/${destination}/\n`);
180
+ if (opts.commit)
181
+ ctx.stdout.write(`${commitReport(run)}\n`);
182
+ }
183
+ /**
184
+ * Remove an entity's directory — spec 04 §4.3.
185
+ *
186
+ * Closing records how work ended; deleting says it should never have been
187
+ * filed. Whatever git already holds can be recovered from history, so the
188
+ * command only stops to ask when it would destroy something git could not give
189
+ * back.
190
+ */
191
+ export function cmdDelete(ctx, kind, prefix, opts) {
192
+ const deletion = planEntityDelete(ctx, kind, prefix, {
193
+ commit: opts.commit,
194
+ recursive: opts.recursive,
195
+ });
196
+ const { entity, alsoRemoved, detached } = deletion;
197
+ // Only look for work git could not give back when there is a question to
198
+ // ask: the scan is a full `git status`, and --force says not to ask.
199
+ if (!opts.force)
200
+ confirmLoss(ctx, deletion, uncommittedUnder(ctx, deletion));
201
+ const result = executeEntityDelete(ctx, deletion, { commit: opts.commit });
202
+ ctx.stdout.write(`Deleted #${entity.id} ${ctx.navDir}/${entity.dirPath}/\n`);
203
+ for (const target of alsoRemoved) {
204
+ ctx.stdout.write(`Deleted #${target.id} ${ctx.navDir}/${target.dirPath}/\n`);
205
+ }
206
+ // Subtasks kept are now top-level, which is easy to miss and hard to undo
207
+ // from memory, so they are named rather than merely implied.
208
+ if (detached.length > 0) {
209
+ ctx.stdout.write(`${detached.length} subtask(s) are now top-level issues:\n`);
210
+ for (const child of detached)
211
+ ctx.stdout.write(` #${child.id} ${child.title}\n`);
212
+ }
213
+ if (opts.commit)
214
+ ctx.stdout.write(`${commitReport(result)}\n`);
215
+ }
216
+ /** Ask before destroying content that is not in git yet. */
217
+ function confirmLoss(ctx, deletion, uncommitted) {
218
+ if (uncommitted.length === 0)
219
+ return;
220
+ const { entity, alsoRemoved } = deletion;
221
+ const what = alsoRemoved.length === 0
222
+ ? `#${entity.id}`
223
+ : `#${entity.id} and its ${alsoRemoved.length} subtask(s)`;
224
+ ctx.stdout.write(`${what} ${alsoRemoved.length === 0 ? "has" : "have"} changes that are not committed:\n`);
225
+ for (const entry of uncommitted)
226
+ ctx.stdout.write(` ${entry}\n`);
227
+ ctx.stdout.write("Deleting it loses them; everything else can be recovered from history.\n");
228
+ const target = alsoRemoved.length === 0
229
+ ? `${ctx.navDir}/${entity.dirPath}/`
230
+ : `${ctx.navDir}/${entity.dirPath}/ and ${alsoRemoved.length} more`;
231
+ if (!askYesNo(ctx, `Delete ${target} anyway? [y/N] `)) {
232
+ fail(`#${entity.id} was not deleted`);
233
+ }
234
+ }
235
+ //# sourceMappingURL=entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity.js","sourceRoot":"","sources":["../../src/commands/entity.ts"],"names":[],"mappings":"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"}