@navbook/cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +9 -0
- package/README.md +165 -0
- package/dist/cli/commands/complete.d.ts +9 -0
- package/dist/cli/commands/complete.js +72 -0
- package/dist/cli/commands/complete.js.map +1 -0
- package/dist/cli/commands/compose.d.ts +27 -0
- package/dist/cli/commands/compose.js +44 -0
- package/dist/cli/commands/compose.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +14 -0
- package/dist/cli/commands/doctor.js +127 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/entity.d.ts +55 -0
- package/dist/cli/commands/entity.js +209 -0
- package/dist/cli/commands/entity.js.map +1 -0
- package/dist/cli/commands/init.d.ts +11 -0
- package/dist/cli/commands/init.js +39 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/install.d.ts +17 -0
- package/dist/cli/commands/install.js +137 -0
- package/dist/cli/commands/install.js.map +1 -0
- package/dist/cli/commands/issue.d.ts +12 -0
- package/dist/cli/commands/issue.js +42 -0
- package/dist/cli/commands/issue.js.map +1 -0
- package/dist/cli/commands/pr.d.ts +64 -0
- package/dist/cli/commands/pr.js +466 -0
- package/dist/cli/commands/pr.js.map +1 -0
- package/dist/cli/commit-flow.d.ts +27 -0
- package/dist/cli/commit-flow.js +47 -0
- package/dist/cli/commit-flow.js.map +1 -0
- package/dist/cli/context.d.ts +39 -0
- package/dist/cli/context.js +93 -0
- package/dist/cli/context.js.map +1 -0
- package/dist/cli/editor.d.ts +23 -0
- package/dist/cli/editor.js +67 -0
- package/dist/cli/editor.js.map +1 -0
- package/dist/cli/errors.d.ts +17 -0
- package/dist/cli/errors.js +23 -0
- package/dist/cli/errors.js.map +1 -0
- package/dist/cli/history-checks.d.ts +21 -0
- package/dist/cli/history-checks.js +134 -0
- package/dist/cli/history-checks.js.map +1 -0
- package/dist/cli/install/completions.d.ts +19 -0
- package/dist/cli/install/completions.js +94 -0
- package/dist/cli/install/completions.js.map +1 -0
- package/dist/cli/install/hook.d.ts +20 -0
- package/dist/cli/install/hook.js +78 -0
- package/dist/cli/install/hook.js.map +1 -0
- package/dist/cli/main.d.ts +14 -0
- package/dist/cli/main.js +88 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/program.d.ts +23 -0
- package/dist/cli/program.js +204 -0
- package/dist/cli/program.js.map +1 -0
- package/dist/cli/prompt.d.ts +22 -0
- package/dist/cli/prompt.js +51 -0
- package/dist/cli/prompt.js.map +1 -0
- package/dist/cli/render/colors.d.ts +13 -0
- package/dist/cli/render/colors.js +19 -0
- package/dist/cli/render/colors.js.map +1 -0
- package/dist/cli/render/detail.d.ts +10 -0
- package/dist/cli/render/detail.js +105 -0
- package/dist/cli/render/detail.js.map +1 -0
- package/dist/cli/render/table.d.ts +19 -0
- package/dist/cli/render/table.js +58 -0
- package/dist/cli/render/table.js.map +1 -0
- package/dist/cli/resolve.d.ts +17 -0
- package/dist/cli/resolve.js +68 -0
- package/dist/cli/resolve.js.map +1 -0
- package/dist/cli/workspace.d.ts +52 -0
- package/dist/cli/workspace.js +178 -0
- package/dist/cli/workspace.js.map +1 -0
- package/dist/core/comments.d.ts +31 -0
- package/dist/core/comments.js +80 -0
- package/dist/core/comments.js.map +1 -0
- package/dist/core/files.d.ts +88 -0
- package/dist/core/files.js +441 -0
- package/dist/core/files.js.map +1 -0
- package/dist/core/frontmatter.d.ts +63 -0
- package/dist/core/frontmatter.js +149 -0
- package/dist/core/frontmatter.js.map +1 -0
- package/dist/core/id.d.ts +46 -0
- package/dist/core/id.js +66 -0
- package/dist/core/id.js.map +1 -0
- package/dist/core/index.d.ts +19 -0
- package/dist/core/index.js +20 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/json.d.ts +18 -0
- package/dist/core/json.js +51 -0
- package/dist/core/json.js.map +1 -0
- package/dist/core/ops.d.ts +92 -0
- package/dist/core/ops.js +173 -0
- package/dist/core/ops.js.map +1 -0
- package/dist/core/person.d.ts +20 -0
- package/dist/core/person.js +50 -0
- package/dist/core/person.js.map +1 -0
- package/dist/core/query.d.ts +30 -0
- package/dist/core/query.js +106 -0
- package/dist/core/query.js.map +1 -0
- package/dist/core/refs.d.ts +12 -0
- package/dist/core/refs.js +36 -0
- package/dist/core/refs.js.map +1 -0
- package/dist/core/slug.d.ts +22 -0
- package/dist/core/slug.js +40 -0
- package/dist/core/slug.js.map +1 -0
- package/dist/core/time.d.ts +14 -0
- package/dist/core/time.js +37 -0
- package/dist/core/time.js.map +1 -0
- package/dist/core/tree.d.ts +94 -0
- package/dist/core/tree.js +237 -0
- package/dist/core/tree.js.map +1 -0
- package/dist/core/validate.d.ts +55 -0
- package/dist/core/validate.js +312 -0
- package/dist/core/validate.js.map +1 -0
- package/dist/git/config.d.ts +12 -0
- package/dist/git/config.js +27 -0
- package/dist/git/config.js.map +1 -0
- package/dist/git/exec.d.ts +35 -0
- package/dist/git/exec.js +58 -0
- package/dist/git/exec.js.map +1 -0
- package/dist/git/history.d.ts +35 -0
- package/dist/git/history.js +82 -0
- package/dist/git/history.js.map +1 -0
- package/dist/git/index-ops.d.ts +20 -0
- package/dist/git/index-ops.js +45 -0
- package/dist/git/index-ops.js.map +1 -0
- package/dist/git/merge.d.ts +27 -0
- package/dist/git/merge.js +57 -0
- package/dist/git/merge.js.map +1 -0
- package/dist/git/refscan.d.ts +32 -0
- package/dist/git/refscan.js +82 -0
- package/dist/git/refscan.js.map +1 -0
- package/dist/git/repo.d.ts +45 -0
- package/dist/git/repo.js +95 -0
- package/dist/git/repo.js.map +1 -0
- package/package.json +51 -0
package/dist/cli/main.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* `nav` entry point.
|
|
4
|
+
*/
|
|
5
|
+
import { realpathSync } from "node:fs";
|
|
6
|
+
import { CommanderError } from "commander";
|
|
7
|
+
import { makeContext } from "./context.js";
|
|
8
|
+
import { NavError } from "./errors.js";
|
|
9
|
+
import { buildProgram } from "./program.js";
|
|
10
|
+
/** Run the CLI and return its exit code. Never throws for expected failures. */
|
|
11
|
+
export function run(opts = {}) {
|
|
12
|
+
const argv = opts.argv ?? process.argv.slice(2);
|
|
13
|
+
const stdout = opts.stdout ?? process.stdout;
|
|
14
|
+
const stderr = opts.stderr ?? process.stderr;
|
|
15
|
+
let ctx = null;
|
|
16
|
+
const getCtx = () => {
|
|
17
|
+
ctx ??= makeContext({ cwd: opts.cwd, env: opts.env, stdout, stderr });
|
|
18
|
+
return ctx;
|
|
19
|
+
};
|
|
20
|
+
const program = buildProgram(getCtx);
|
|
21
|
+
program.exitOverride();
|
|
22
|
+
program.configureOutput({
|
|
23
|
+
writeOut: (text) => stdout.write(text),
|
|
24
|
+
writeErr: (text) => stderr.write(text),
|
|
25
|
+
});
|
|
26
|
+
try {
|
|
27
|
+
program.parse(argv, { from: "user" });
|
|
28
|
+
return 0;
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
return report(error, stderr);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function report(error, stderr) {
|
|
35
|
+
if (error instanceof CommanderError) {
|
|
36
|
+
// Commander already wrote help or the version string.
|
|
37
|
+
if (error.code === "commander.helpDisplayed" || error.code === "commander.version")
|
|
38
|
+
return 0;
|
|
39
|
+
if (error.code === "commander.help")
|
|
40
|
+
return 0;
|
|
41
|
+
return error.exitCode === 0 ? 0 : 1;
|
|
42
|
+
}
|
|
43
|
+
if (error instanceof NavError) {
|
|
44
|
+
stderr.write(`nav: ${error.message}\n`);
|
|
45
|
+
for (const line of error.details)
|
|
46
|
+
stderr.write(`${line}\n`);
|
|
47
|
+
return error.exitCode;
|
|
48
|
+
}
|
|
49
|
+
stderr.write(`nav: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
50
|
+
return 1;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* A closed pipe is a normal way for a command to end — `nav issue list | head`
|
|
54
|
+
* closes stdout as soon as it has enough. Without this, node turns that into an
|
|
55
|
+
* unhandled EPIPE and a stack trace.
|
|
56
|
+
*/
|
|
57
|
+
function exitQuietlyOnClosedPipe(stream) {
|
|
58
|
+
stream.on("error", (error) => {
|
|
59
|
+
if (error.code === "EPIPE")
|
|
60
|
+
process.exit(0);
|
|
61
|
+
throw error;
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* True when this file is the program being run.
|
|
66
|
+
*
|
|
67
|
+
* The paths are resolved through symlinks first: npm installs the binary as a
|
|
68
|
+
* link in `node_modules/.bin`, so `process.argv[1]` is the link while
|
|
69
|
+
* `import.meta.filename` is its target. Comparing them raw makes the installed
|
|
70
|
+
* CLI silently do nothing.
|
|
71
|
+
*/
|
|
72
|
+
function invokedDirectly() {
|
|
73
|
+
const entry = process.argv[1];
|
|
74
|
+
if (entry === undefined)
|
|
75
|
+
return false;
|
|
76
|
+
try {
|
|
77
|
+
return realpathSync(entry) === realpathSync(import.meta.filename);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (invokedDirectly()) {
|
|
84
|
+
exitQuietlyOnClosedPipe(process.stdout);
|
|
85
|
+
exitQuietlyOnClosedPipe(process.stderr);
|
|
86
|
+
process.exitCode = run();
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
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 };
|
|
@@ -0,0 +1,204 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"program.js","sourceRoot":"","sources":["../../src/cli/program.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Confirmation for commands that change files or configuration.
|
|
3
|
+
*
|
|
4
|
+
* Following `apt`: print the exact actions first, then ask. `--yes` skips the
|
|
5
|
+
* question but never the printing, so a scripted run still leaves a record of
|
|
6
|
+
* what it did.
|
|
7
|
+
*/
|
|
8
|
+
import type { Ctx } from "./context.ts";
|
|
9
|
+
export interface Action {
|
|
10
|
+
/** One line describing what will happen, e.g. the exact command to be run. */
|
|
11
|
+
description: string;
|
|
12
|
+
perform: () => void;
|
|
13
|
+
}
|
|
14
|
+
export interface ConfirmOptions {
|
|
15
|
+
title: string;
|
|
16
|
+
actions: readonly Action[];
|
|
17
|
+
assumeYes?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/** Print the planned actions, ask once, then perform them. */
|
|
20
|
+
export declare function confirmAndPerform(ctx: Ctx, opts: ConfirmOptions): boolean;
|
|
21
|
+
/** Ask a yes/no question; anything but `y`/`yes` — including EOF — is a no. */
|
|
22
|
+
export declare function askYesNo(ctx: Ctx, question: string): boolean;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Confirmation for commands that change files or configuration.
|
|
3
|
+
*
|
|
4
|
+
* Following `apt`: print the exact actions first, then ask. `--yes` skips the
|
|
5
|
+
* question but never the printing, so a scripted run still leaves a record of
|
|
6
|
+
* what it did.
|
|
7
|
+
*/
|
|
8
|
+
import { readSync } from "node:fs";
|
|
9
|
+
/** Print the planned actions, ask once, then perform them. */
|
|
10
|
+
export function confirmAndPerform(ctx, opts) {
|
|
11
|
+
if (opts.actions.length === 0) {
|
|
12
|
+
ctx.stdout.write("Nothing to do.\n");
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
ctx.stdout.write(`${opts.title}\n`);
|
|
16
|
+
for (const action of opts.actions)
|
|
17
|
+
ctx.stdout.write(` ${action.description}\n`);
|
|
18
|
+
if (!opts.assumeYes && !askYesNo(ctx, "Continue? [y/N] ")) {
|
|
19
|
+
ctx.stdout.write("Aborted.\n");
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
for (const action of opts.actions)
|
|
23
|
+
action.perform();
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
/** Ask a yes/no question; anything but `y`/`yes` — including EOF — is a no. */
|
|
27
|
+
export function askYesNo(ctx, question) {
|
|
28
|
+
ctx.stdout.write(question);
|
|
29
|
+
const answer = readLineFromStdin();
|
|
30
|
+
if (!ctx.stdout.isTTY)
|
|
31
|
+
ctx.stdout.write("\n");
|
|
32
|
+
return /^y(es)?$/i.test(answer.trim());
|
|
33
|
+
}
|
|
34
|
+
function readLineFromStdin() {
|
|
35
|
+
const chunk = Buffer.alloc(256);
|
|
36
|
+
let text = "";
|
|
37
|
+
while (!text.includes("\n")) {
|
|
38
|
+
let read;
|
|
39
|
+
try {
|
|
40
|
+
read = readSync(0, chunk, 0, chunk.length, null);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
if (read === 0)
|
|
46
|
+
break;
|
|
47
|
+
text += chunk.subarray(0, read).toString("utf8");
|
|
48
|
+
}
|
|
49
|
+
return text.split("\n")[0] ?? "";
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/cli/prompt.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAenC,8DAA8D;AAC9D,MAAM,UAAU,iBAAiB,CAAC,GAAQ,EAAE,IAAoB;IAC9D,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;IACpC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO;QAAE,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,MAAM,CAAC,WAAW,IAAI,CAAC,CAAC;IAEjF,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,kBAAkB,CAAC,EAAE,CAAC;QAC1D,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO;QAAE,MAAM,CAAC,OAAO,EAAE,CAAC;IACpD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,QAAQ,CAAC,GAAQ,EAAE,QAAgB;IACjD,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC3B,MAAM,MAAM,GAAG,iBAAiB,EAAE,CAAC;IACnC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK;QAAE,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9C,OAAO,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,iBAAiB;IACxB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5B,IAAI,IAAY,CAAC;QACjB,IAAI,CAAC;YACH,IAAI,GAAG,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACnD,CAAC;QAAC,MAAM,CAAC;YACP,MAAM;QACR,CAAC;QACD,IAAI,IAAI,KAAK,CAAC;YAAE,MAAM;QACtB,IAAI,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal color, enabled only for a TTY that has not opted out.
|
|
3
|
+
*
|
|
4
|
+
* `--json` output and every fixture comparison therefore run uncolored.
|
|
5
|
+
*/
|
|
6
|
+
import pc from "picocolors";
|
|
7
|
+
export type Colors = ReturnType<typeof pc.createColors>;
|
|
8
|
+
export declare function colorEnabled(stream: {
|
|
9
|
+
isTTY?: boolean;
|
|
10
|
+
}, env: NodeJS.ProcessEnv): boolean;
|
|
11
|
+
export declare function makeColors(stream: {
|
|
12
|
+
isTTY?: boolean;
|
|
13
|
+
}, env: NodeJS.ProcessEnv): Colors;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal color, enabled only for a TTY that has not opted out.
|
|
3
|
+
*
|
|
4
|
+
* `--json` output and every fixture comparison therefore run uncolored.
|
|
5
|
+
*/
|
|
6
|
+
import pc from "picocolors";
|
|
7
|
+
export function colorEnabled(stream, env) {
|
|
8
|
+
if (env.NO_COLOR !== undefined && env.NO_COLOR !== "")
|
|
9
|
+
return false;
|
|
10
|
+
if (env.FORCE_COLOR !== undefined && env.FORCE_COLOR !== "" && env.FORCE_COLOR !== "0")
|
|
11
|
+
return true;
|
|
12
|
+
if (env.TERM === "dumb")
|
|
13
|
+
return false;
|
|
14
|
+
return stream.isTTY === true;
|
|
15
|
+
}
|
|
16
|
+
export function makeColors(stream, env) {
|
|
17
|
+
return pc.createColors(colorEnabled(stream, env));
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=colors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colors.js","sourceRoot":"","sources":["../../../src/cli/render/colors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAI5B,MAAM,UAAU,YAAY,CAAC,MAA2B,EAAE,GAAsB;IAC9E,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,GAAG,CAAC,QAAQ,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IACpE,IAAI,GAAG,CAAC,WAAW,KAAK,SAAS,IAAI,GAAG,CAAC,WAAW,KAAK,EAAE,IAAI,GAAG,CAAC,WAAW,KAAK,GAAG;QACpF,OAAO,IAAI,CAAC;IACd,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IACtC,OAAO,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAA2B,EAAE,GAAsB;IAC5E,OAAO,EAAE,CAAC,YAAY,CAAC,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `show` rendering: an entity's metadata, description and comment thread.
|
|
3
|
+
*/
|
|
4
|
+
import type { EntityRecord } from "../../core/tree.ts";
|
|
5
|
+
import type { Colors } from "./colors.ts";
|
|
6
|
+
export interface DetailOptions {
|
|
7
|
+
colors: Colors;
|
|
8
|
+
}
|
|
9
|
+
/** Render one entity with its full comment thread. */
|
|
10
|
+
export declare function renderDetail(entity: EntityRecord, opts: DetailOptions): string;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `show` rendering: an entity's metadata, description and comment thread.
|
|
3
|
+
*/
|
|
4
|
+
import { threadOrder } from "../../core/comments.js";
|
|
5
|
+
import { readAssignees, readLabels, readMerged, readRevisions } from "../../core/files.js";
|
|
6
|
+
import { NAVBOOK_ROOT } from "../../core/json.js";
|
|
7
|
+
import { toIsoSeconds } from "../../core/time.js";
|
|
8
|
+
/** Render one entity with its full comment thread. */
|
|
9
|
+
export function renderDetail(entity, opts) {
|
|
10
|
+
const c = opts.colors;
|
|
11
|
+
const lines = [];
|
|
12
|
+
lines.push(`${c.bold(`#${entity.id}`)} ${entity.title}`);
|
|
13
|
+
const labelWidth = 11;
|
|
14
|
+
for (const [label, value] of metadataRows(entity)) {
|
|
15
|
+
// A continuation row (empty label) is indented to line up under the value.
|
|
16
|
+
const cell = label === "" ? " ".repeat(labelWidth) : c.dim(`${label}:`.padEnd(labelWidth));
|
|
17
|
+
lines.push(`${cell}${value}`);
|
|
18
|
+
}
|
|
19
|
+
const body = entity.body.trim();
|
|
20
|
+
if (body !== "") {
|
|
21
|
+
lines.push("");
|
|
22
|
+
lines.push(body);
|
|
23
|
+
}
|
|
24
|
+
lines.push("");
|
|
25
|
+
lines.push(c.dim(`comments (${entity.comments.length}):`));
|
|
26
|
+
if (entity.comments.length === 0) {
|
|
27
|
+
lines.push(c.dim(" none"));
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
for (const { comment, depth } of threadOrder(entity.comments)) {
|
|
31
|
+
lines.push("");
|
|
32
|
+
lines.push(...renderComment(comment, depth, c));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return lines.join("\n");
|
|
36
|
+
}
|
|
37
|
+
function metadataRows(entity) {
|
|
38
|
+
const rows = [];
|
|
39
|
+
rows.push(["status", entity.archived ? `${entity.status} (archived)` : entity.status]);
|
|
40
|
+
rows.push(["author", stringField(entity, "author")]);
|
|
41
|
+
rows.push(["created", stringField(entity, "created")]);
|
|
42
|
+
if (entity.kind === "pr") {
|
|
43
|
+
rows.push(["target", stringField(entity, "target")]);
|
|
44
|
+
const source = stringField(entity, "source");
|
|
45
|
+
if (source !== "")
|
|
46
|
+
rows.push(["source", source]);
|
|
47
|
+
if (entity.fm.draft === true)
|
|
48
|
+
rows.push(["draft", "yes"]);
|
|
49
|
+
const revisions = readRevisions(entity.fm);
|
|
50
|
+
revisions.forEach((revision, index) => {
|
|
51
|
+
rows.push([
|
|
52
|
+
index === 0 ? "revisions" : "",
|
|
53
|
+
`${index + 1}. head ${revision.head.slice(0, 12)} base ${revision.base.slice(0, 12)} ${revision.date}`,
|
|
54
|
+
]);
|
|
55
|
+
});
|
|
56
|
+
const merged = readMerged(entity.fm);
|
|
57
|
+
if (merged) {
|
|
58
|
+
rows.push(["merged", `${merged.date ?? "?"} by ${merged.by ?? "?"}`]);
|
|
59
|
+
if (typeof merged.commit === "string")
|
|
60
|
+
rows.push(["", `commit ${merged.commit.slice(0, 12)}`]);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const labels = readLabels(entity.fm);
|
|
64
|
+
if (labels.length > 0)
|
|
65
|
+
rows.push(["labels", labels.join(", ")]);
|
|
66
|
+
const assignees = readAssignees(entity.fm);
|
|
67
|
+
if (assignees.length > 0)
|
|
68
|
+
rows.push(["assignee", assignees.join(", ")]);
|
|
69
|
+
for (const key of ["milestone", "resolution", "duplicate-of", "superseded-by"]) {
|
|
70
|
+
const value = stringField(entity, key);
|
|
71
|
+
if (value !== "")
|
|
72
|
+
rows.push([key, value]);
|
|
73
|
+
}
|
|
74
|
+
rows.push(["path", `${NAVBOOK_ROOT}/${entity.dirPath}/`]);
|
|
75
|
+
return rows;
|
|
76
|
+
}
|
|
77
|
+
function stringField(entity, key) {
|
|
78
|
+
const value = entity.fm[key];
|
|
79
|
+
return typeof value === "string" ? value : "";
|
|
80
|
+
}
|
|
81
|
+
function renderComment(comment, depth, c) {
|
|
82
|
+
const indent = " ".repeat(depth + 1);
|
|
83
|
+
const head = [c.bold(`#${comment.id}`), comment.author, toIsoSeconds(comment.date)];
|
|
84
|
+
const verdict = comment.parsed.fm.verdict;
|
|
85
|
+
if (typeof verdict === "string") {
|
|
86
|
+
const paint = verdict === "approve" ? c.green : c.yellow;
|
|
87
|
+
head.push(paint(`[${verdict}]`));
|
|
88
|
+
}
|
|
89
|
+
const revision = comment.parsed.fm.revision;
|
|
90
|
+
if (typeof revision === "string")
|
|
91
|
+
head.push(c.dim(`@${revision.slice(0, 12)}`));
|
|
92
|
+
const file = comment.parsed.fm.file;
|
|
93
|
+
if (typeof file === "string") {
|
|
94
|
+
const line = comment.parsed.fm.line;
|
|
95
|
+
head.push(c.dim(`${file}${line === undefined ? "" : `:${line}`}`));
|
|
96
|
+
}
|
|
97
|
+
if (comment.replyTo)
|
|
98
|
+
head.push(c.dim(`reply to #${comment.replyTo}`));
|
|
99
|
+
const lines = [`${indent}${head.join(" ")}`];
|
|
100
|
+
for (const line of comment.body.trim().split("\n")) {
|
|
101
|
+
lines.push(line === "" ? "" : `${indent} ${line}`);
|
|
102
|
+
}
|
|
103
|
+
return lines;
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=detail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detail.js","sourceRoot":"","sources":["../../../src/cli/render/detail.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Column-aligned listings for `nav issue list` / `nav pr list`.
|
|
3
|
+
*/
|
|
4
|
+
import type { Colors } from "./colors.ts";
|
|
5
|
+
export interface Column {
|
|
6
|
+
header: string;
|
|
7
|
+
/** Cells are truncated to this width when the terminal is narrow. */
|
|
8
|
+
flexible?: boolean;
|
|
9
|
+
minWidth?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface TableOptions {
|
|
12
|
+
colors: Colors;
|
|
13
|
+
/** Total width available; unlimited when undefined. */
|
|
14
|
+
width?: number;
|
|
15
|
+
}
|
|
16
|
+
/** Render a table, shrinking flexible columns to fit the terminal width. */
|
|
17
|
+
export declare function renderTable(columns: readonly Column[], rows: readonly string[][], opts: TableOptions): string;
|
|
18
|
+
/** Truncate to `width`, marking the cut with a single ellipsis character. */
|
|
19
|
+
export declare function truncate(text: string, width: number): string;
|