@navbook/cli 0.4.0 → 0.5.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 (78) hide show
  1. package/dist/args.d.ts +28 -0
  2. package/dist/args.js +48 -0
  3. package/dist/args.js.map +1 -0
  4. package/dist/commands/complete.d.ts +10 -0
  5. package/dist/commands/complete.js +59 -51
  6. package/dist/commands/complete.js.map +1 -1
  7. package/dist/commands/compose.d.ts +35 -0
  8. package/dist/commands/doctor.d.ts +15 -0
  9. package/dist/commands/entity.d.ts +73 -0
  10. package/dist/commands/entity.js +59 -44
  11. package/dist/commands/entity.js.map +1 -1
  12. package/dist/commands/init.d.ts +11 -0
  13. package/dist/commands/install.d.ts +17 -0
  14. package/dist/commands/install.js +6 -3
  15. package/dist/commands/install.js.map +1 -1
  16. package/dist/commands/issue.d.ts +35 -0
  17. package/dist/commands/issue.js +4 -5
  18. package/dist/commands/issue.js.map +1 -1
  19. package/dist/commands/plugin.d.ts +36 -0
  20. package/dist/commands/plugin.js +386 -0
  21. package/dist/commands/plugin.js.map +1 -0
  22. package/dist/commands/policy.d.ts +58 -0
  23. package/dist/commands/policy.js +13 -0
  24. package/dist/commands/policy.js.map +1 -1
  25. package/dist/commands/pr-elsewhere.d.ts +40 -0
  26. package/dist/commands/pr-elsewhere.js +209 -0
  27. package/dist/commands/pr-elsewhere.js.map +1 -0
  28. package/dist/commands/pr.d.ts +69 -0
  29. package/dist/commands/pr.js +86 -60
  30. package/dist/commands/pr.js.map +1 -1
  31. package/dist/context.d.ts +42 -0
  32. package/dist/context.js +2 -0
  33. package/dist/context.js.map +1 -1
  34. package/dist/editor.d.ts +23 -0
  35. package/dist/editor.js +4 -0
  36. package/dist/editor.js.map +1 -1
  37. package/dist/errors.d.ts +17 -0
  38. package/dist/install/completions.d.ts +19 -0
  39. package/dist/install/hook.d.ts +32 -0
  40. package/dist/install/hook.js +48 -4
  41. package/dist/install/hook.js.map +1 -1
  42. package/dist/main.d.ts +21 -0
  43. package/dist/main.js +112 -8
  44. package/dist/main.js.map +1 -1
  45. package/dist/plugins/commands.d.ts +69 -0
  46. package/dist/plugins/commands.js +148 -0
  47. package/dist/plugins/commands.js.map +1 -0
  48. package/dist/plugins/hint.d.ts +23 -0
  49. package/dist/plugins/hint.js +65 -0
  50. package/dist/plugins/hint.js.map +1 -0
  51. package/dist/plugins/host.d.ts +125 -0
  52. package/dist/plugins/host.js +18 -0
  53. package/dist/plugins/host.js.map +1 -0
  54. package/dist/plugins/loader.d.ts +54 -0
  55. package/dist/plugins/loader.js +165 -0
  56. package/dist/plugins/loader.js.map +1 -0
  57. package/dist/plugins/resolve.d.ts +50 -0
  58. package/dist/plugins/resolve.js +134 -0
  59. package/dist/plugins/resolve.js.map +1 -0
  60. package/dist/plugins/runtime.d.ts +69 -0
  61. package/dist/plugins/runtime.js +256 -0
  62. package/dist/plugins/runtime.js.map +1 -0
  63. package/dist/plugins/store.d.ts +96 -0
  64. package/dist/plugins/store.js +186 -0
  65. package/dist/plugins/store.js.map +1 -0
  66. package/dist/program.d.ts +49 -0
  67. package/dist/program.js +351 -113
  68. package/dist/program.js.map +1 -1
  69. package/dist/prompt.d.ts +31 -0
  70. package/dist/render/colors.d.ts +13 -0
  71. package/dist/render/detail.d.ts +22 -0
  72. package/dist/render/table.d.ts +32 -0
  73. package/dist/render/table.js +123 -13
  74. package/dist/render/table.js.map +1 -1
  75. package/dist/sort.d.ts +27 -0
  76. package/package.json +9 -2
  77. package/dist/commands/feature.js +0 -202
  78. package/dist/commands/feature.js.map +0 -1
@@ -0,0 +1,186 @@
1
+ /**
2
+ * The per-user plugin store — spec 04 §4.3.
3
+ *
4
+ * Plugins live in a directory `nav` owns rather than beside `nav` itself,
5
+ * because where `nav` itself lives is not knowable: it may have arrived by
6
+ * `npm -g`, by pnpm, through a version manager, or not be installed at all
7
+ * under `npx`. A directory of our own works the same way in every one of those.
8
+ *
9
+ * The store is an ordinary npm project — a `package.json` and a `node_modules`
10
+ * — so resolution, transitive dependencies and updates are npm's problem and
11
+ * not ours. What we add on top is `plugins.json`: an index of what is
12
+ * installed, with each plugin's manifest copied into it. That file is why
13
+ * startup costs one read. Scanning `node_modules` to find out what is there
14
+ * would cost a directory walk and a `package.json` parse per plugin on every
15
+ * single `nav` invocation, which is the cost spec 05 §5.2 says we cannot pay —
16
+ * and is exactly the mistake Prettier removed its plugin search for.
17
+ */
18
+ import { spawnSync } from "node:child_process";
19
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
20
+ import { join } from "node:path";
21
+ import { parsePluginPackage } from "@navbook/core";
22
+ /** Where the store lives, honouring `$XDG_DATA_HOME` (spec 04 §4.3). */
23
+ export function storeDir(env) {
24
+ const xdg = env.XDG_DATA_HOME;
25
+ if (xdg !== undefined && xdg.trim() !== "")
26
+ return join(xdg, "navbook", "plugins");
27
+ const home = env.HOME ?? env.USERPROFILE ?? "";
28
+ return join(home, ".local", "share", "navbook", "plugins");
29
+ }
30
+ const INDEX_FILE = "plugins.json";
31
+ const STORE_PACKAGE = {
32
+ name: "navbook-plugins",
33
+ private: true,
34
+ description: "Plugins installed for the nav CLI. Managed by `nav plugin`.",
35
+ version: "1.0.0",
36
+ };
37
+ export function indexPath(env) {
38
+ return join(storeDir(env), INDEX_FILE);
39
+ }
40
+ /**
41
+ * Read the index, or null when there is none.
42
+ *
43
+ * Null for every fault — no store, no file, unreadable, not JSON, a version
44
+ * from some future `nav`. A store this `nav` cannot read is a store with no
45
+ * plugins in it as far as this run is concerned, and refusing to list issues
46
+ * because of a file in the user's data directory would be absurd. The repair
47
+ * is `nav plugin install`, which rewrites it.
48
+ */
49
+ export function readIndex(env) {
50
+ const path = indexPath(env);
51
+ if (!existsSync(path))
52
+ return null;
53
+ try {
54
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
55
+ if (parsed.version !== 1 || typeof parsed.plugins !== "object" || parsed.plugins === null) {
56
+ return null;
57
+ }
58
+ return parsed;
59
+ }
60
+ catch {
61
+ return null;
62
+ }
63
+ }
64
+ export function writeIndex(env, index) {
65
+ const dir = storeDir(env);
66
+ mkdirSync(dir, { recursive: true });
67
+ writeFileSync(join(dir, INDEX_FILE), `${JSON.stringify(index, null, 2)}\n`);
68
+ }
69
+ /** Create the store's own `package.json` if it is not there yet. */
70
+ export function ensureStore(env) {
71
+ const dir = storeDir(env);
72
+ mkdirSync(dir, { recursive: true });
73
+ const manifest = join(dir, "package.json");
74
+ if (!existsSync(manifest)) {
75
+ writeFileSync(manifest, `${JSON.stringify(STORE_PACKAGE, null, 2)}\n`);
76
+ }
77
+ return dir;
78
+ }
79
+ /**
80
+ * The npm command a given install would run, as a string to print.
81
+ *
82
+ * Printed before it runs (spec 04 §4.3), so that what the user agrees to is
83
+ * the command rather than a summary of it.
84
+ */
85
+ export function installCommand(specs) {
86
+ return `npm ${installArgs(specs).join(" ")}`;
87
+ }
88
+ function installArgs(specs) {
89
+ return [
90
+ "install",
91
+ // A plugin is code somebody chose to install, but its *dependencies* are
92
+ // not, and a postinstall script is the classic way a package does
93
+ // something nobody asked for. npm runs none of them here.
94
+ "--ignore-scripts",
95
+ // The pair that keeps a second `@navbook/core` out of the store. A plugin
96
+ // declares core as a peer for its types; installing peers would give it a
97
+ // copy of its own, and then `instanceof WorkspaceError` would be false
98
+ // across the boundary and the YAML parser would be loaded twice.
99
+ // `--omit=peer` alone only leaves peers off the disk: npm still resolves
100
+ // them, from the registry, and refuses the install when a web half's
101
+ // optional framework peers do not reconcile. `--legacy-peer-deps` stops it
102
+ // resolving them at all — the host provides every one.
103
+ "--omit=peer",
104
+ "--legacy-peer-deps",
105
+ "--no-audit",
106
+ "--no-fund",
107
+ "--save-exact",
108
+ ...specs,
109
+ ];
110
+ }
111
+ /** Run npm in the store. Its output is captured rather than streamed. */
112
+ export function npmInstall(env, specs) {
113
+ return runNpm(env, installArgs(specs));
114
+ }
115
+ export function npmRemove(env, names) {
116
+ return runNpm(env, ["uninstall", "--no-audit", "--no-fund", ...names]);
117
+ }
118
+ function runNpm(env, args) {
119
+ const dir = ensureStore(env);
120
+ const result = spawnSync("npm", [...args], {
121
+ cwd: dir,
122
+ encoding: "utf8",
123
+ // npm is a shell script on Windows; everywhere Navbook supports it is not.
124
+ shell: false,
125
+ env: { ...env },
126
+ });
127
+ if (result.error)
128
+ return { ok: false, output: result.error.message };
129
+ return {
130
+ ok: result.status === 0,
131
+ output: `${result.stdout ?? ""}${result.stderr ?? ""}`.trim(),
132
+ };
133
+ }
134
+ /**
135
+ * Read an installed package directory as a plugin.
136
+ *
137
+ * Used at install time to check what npm actually fetched, and by
138
+ * `NAVBOOK_PLUGIN_PATH` to read a plugin nobody installed. Faults come back as
139
+ * a message so the caller can name the directory alongside them.
140
+ */
141
+ export function readPluginAt(dir) {
142
+ const manifestPath = join(dir, "package.json");
143
+ let raw;
144
+ try {
145
+ raw = JSON.parse(readFileSync(manifestPath, "utf8"));
146
+ }
147
+ catch (error) {
148
+ return { error: `${manifestPath}: ${error instanceof Error ? error.message : String(error)}` };
149
+ }
150
+ const read = parsePluginPackage(raw);
151
+ if (!read.ok)
152
+ return { error: read.error };
153
+ return {
154
+ name: read.plugin.name,
155
+ version: read.plugin.version,
156
+ dir,
157
+ engines: read.plugin.engines,
158
+ manifest: read.plugin.manifest,
159
+ };
160
+ }
161
+ /** Where npm put a package inside the store. */
162
+ export function packageDir(env, name) {
163
+ return join(storeDir(env), "node_modules", ...name.split("/"));
164
+ }
165
+ /**
166
+ * The packages the store depends on, as npm recorded them: each real package
167
+ * name, and the specifier npm saved for it.
168
+ *
169
+ * What was *asked* for and what was *installed* are not the same string: a
170
+ * tarball path, a git URL and a short name all resolve to a package whose real
171
+ * name is inside it, and looking in `node_modules/<what-was-typed>` finds
172
+ * nothing. npm writes the real name into the store's own `package.json`, so
173
+ * reading it back — before an install and again after — is how an install
174
+ * learns what it actually got. The specifier is kept too, because a new
175
+ * version of a plugin already installed changes it without adding a name.
176
+ */
177
+ export function storeDependencies(env) {
178
+ try {
179
+ const pkg = JSON.parse(readFileSync(join(storeDir(env), "package.json"), "utf8"));
180
+ return { ...(pkg.dependencies ?? {}) };
181
+ }
182
+ catch {
183
+ return {};
184
+ }
185
+ }
186
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/plugins/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
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 { type EntityKind } from "@navbook/core";
6
+ import { Command, Option } from "commander";
7
+ import { type CloseOptions, type ExtraColumn } from "./commands/entity.ts";
8
+ import type { Ctx, GetCtx } from "./context.ts";
9
+ import type { PluginRuntime } from "./plugins/runtime.ts";
10
+ export declare const VERSION: string;
11
+ /**
12
+ * A plugin's declared `help` line as rows of the table above.
13
+ *
14
+ * The manifest writes it as the built-in rows read, syntax then a gap then
15
+ * the hint; it is re-aligned here so a plugin need not know the column this
16
+ * help happens to use. A line with no gap is all syntax, and a syntax too wide
17
+ * for its column puts the hint on the next line rather than against it.
18
+ */
19
+ export declare function pluginHelpRow(help: string): string[];
20
+ /**
21
+ * The nouns and utilities this CLI defines, which a plugin may not take.
22
+ *
23
+ * Kept as data because two things read it: the collision check that refuses a
24
+ * plugin claiming one of these (spec 04 §4.3), and completion, which offers
25
+ * them alongside whatever plugins added.
26
+ */
27
+ export declare const BUILTIN_NOUNS: readonly ["issue", "pr", "plugin", "init", "id", "doctor", "install", "uninstall"];
28
+ export declare function buildProgram(getCtx: GetCtx, plugins?: PluginRuntime): Command;
29
+ export interface SharedVerbOptions {
30
+ extraColumns: ExtraColumn[];
31
+ /** The plugin runtime, when this invocation has one. */
32
+ plugins?: PluginRuntime;
33
+ /** The noun these verbs hang off, for looking a contribution up by name. */
34
+ verbPrefix?: string;
35
+ /** Extra options the noun's `list` accepts, e.g. `--all-refs` for PRs. */
36
+ configureList?: (command: Command) => void;
37
+ /** Extra options the noun's `show` accepts, e.g. `--depth` for issues. */
38
+ configureShow?: (command: Command) => void;
39
+ /** Extra options the noun's `delete` accepts, e.g. `--recursive` for issues. */
40
+ configureDelete?: (command: Command) => void;
41
+ /** Listing implementation, when the noun needs more than the shared one. */
42
+ runList?: (ctx: Ctx, terms: string[], options: Record<string, unknown>) => void;
43
+ /** Close implementation, when the noun needs more than the shared one. */
44
+ runClose?: (ctx: Ctx, id: string, options: CloseOptions) => void;
45
+ }
46
+ /** Register the verbs both nouns share, so their behavior can never drift. */
47
+ export declare function addSharedVerbs(parent: Command, kind: EntityKind, getCtx: () => Ctx, shared: SharedVerbOptions): void;
48
+ export declare function collect(value: string, previous: string[]): string[];
49
+ export { Option };