@rathnasgala/cli 1.1.8 → 1.1.9
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/package.json +1 -1
- package/src/cli/invocation.js +9 -0
- package/src/commands/doctor.js +5 -4
- package/src/commands/domain.js +6 -5
- package/src/commands/init.js +2 -5
- package/src/commands/new.js +2 -1
- package/src/commands/prism.js +17 -13
- package/src/commands/upgrade.js +4 -2
- package/src/commands-manifest.js +6 -5
- package/src/index.js +4 -2
package/package.json
CHANGED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const CLI_INVOCATION = 'npx --yes @rathnasgala/cli@latest';
|
|
2
|
+
|
|
3
|
+
export function cliCommand(argumentsText = '') {
|
|
4
|
+
return argumentsText === '' ? CLI_INVOCATION : `${CLI_INVOCATION} ${argumentsText}`;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function shellArgument(value) {
|
|
8
|
+
return /^[A-Za-z0-9_./-]+$/.test(value) ? value : `'${value.replaceAll("'", "'\\''")}'`;
|
|
9
|
+
}
|
package/src/commands/doctor.js
CHANGED
|
@@ -4,6 +4,7 @@ import path from 'node:path';
|
|
|
4
4
|
import { galaApi } from '../api/gala.js';
|
|
5
5
|
import { galaCredential } from '../auth/gala.js';
|
|
6
6
|
import { githubCredential } from '../auth/github.js';
|
|
7
|
+
import { cliCommand } from '../cli/invocation.js';
|
|
7
8
|
import { createGit } from '../git.js';
|
|
8
9
|
|
|
9
10
|
/**
|
|
@@ -23,7 +24,7 @@ export async function doctor({ terminal, options, cwd = process.cwd() }) {
|
|
|
23
24
|
const accepted = await galaApi({ baseUrl: gala.apiBaseUrl, token: gala.accessToken }).accepted();
|
|
24
25
|
return accepted
|
|
25
26
|
? ok(`valid until ${new Date(gala.expiresAt).toLocaleString()}`)
|
|
26
|
-
: wrong('the API no longer accepts it', '
|
|
27
|
+
: wrong('the API no longer accepts it', cliCommand('auth'));
|
|
27
28
|
}));
|
|
28
29
|
|
|
29
30
|
checks.push(await checkCredential('GitHub sign-in', async () => {
|
|
@@ -45,7 +46,7 @@ export async function doctor({ terminal, options, cwd = process.cwd() }) {
|
|
|
45
46
|
const source = await readFile(workflow, 'utf8');
|
|
46
47
|
const siteId = /site-id:\s*([0-9A-Z]{26})/.exec(source)?.[1];
|
|
47
48
|
return siteId == null
|
|
48
|
-
? wrong('no site id — this publication may not be registered', '
|
|
49
|
+
? wrong('no site id — this publication may not be registered', cliCommand('init'))
|
|
49
50
|
: ok(siteId);
|
|
50
51
|
}, 'the workflow is missing; registration writes it'));
|
|
51
52
|
|
|
@@ -53,8 +54,8 @@ export async function doctor({ terminal, options, cwd = process.cwd() }) {
|
|
|
53
54
|
const git = createGit({ root });
|
|
54
55
|
const dirty = await git.run(['status', '--porcelain'], { capture: true });
|
|
55
56
|
const ahead = await git.run(['rev-list', '--count', '@{upstream}..HEAD'], { capture: true, allow: [0, 128] });
|
|
56
|
-
if (dirty !== '') return wrong(`${dirty.split('\n').length} file(s) not recorded`, '
|
|
57
|
-
if (ahead !== '' && ahead !== '0') return wrong(`${ahead} commit(s) not sent`, '
|
|
57
|
+
if (dirty !== '') return wrong(`${dirty.split('\n').length} file(s) not recorded`, cliCommand('publish'));
|
|
58
|
+
if (ahead !== '' && ahead !== '0') return wrong(`${ahead} commit(s) not sent`, cliCommand('publish'));
|
|
58
59
|
return ok('everything is on GitHub');
|
|
59
60
|
}, 'this folder is not a git checkout'));
|
|
60
61
|
|
package/src/commands/domain.js
CHANGED
|
@@ -3,6 +3,7 @@ import path from 'node:path';
|
|
|
3
3
|
import { galaApi } from '../api/gala.js';
|
|
4
4
|
import { galaCredential } from '../auth/gala.js';
|
|
5
5
|
import { UsageError } from '../cli/args.js';
|
|
6
|
+
import { cliCommand } from '../cli/invocation.js';
|
|
6
7
|
import { customDomain } from '../domain.js';
|
|
7
8
|
import { readPublication } from '../publication.js';
|
|
8
9
|
|
|
@@ -16,7 +17,7 @@ export async function domain({ terminal, options, cwd = process.cwd() }) {
|
|
|
16
17
|
}
|
|
17
18
|
const [action = 'status', value, ...extra] = options.positional;
|
|
18
19
|
if (extra.length > 0 || !['status', 'set', 'check', 'cancel', 'remove'].includes(action)) {
|
|
19
|
-
throw new UsageError(
|
|
20
|
+
throw new UsageError(`Use: ${cliCommand('domain [status|set <hostname>|check|cancel|remove]')}`);
|
|
20
21
|
}
|
|
21
22
|
if (action === 'set' && value == null) throw new UsageError('domain set needs a hostname');
|
|
22
23
|
if (action !== 'set' && value != null) throw new UsageError(`domain ${action} takes no hostname`);
|
|
@@ -45,7 +46,7 @@ export async function domain({ terminal, options, cwd = process.cwd() }) {
|
|
|
45
46
|
pathPrefix: '/',
|
|
46
47
|
});
|
|
47
48
|
terminal.done(`Reserved ${checked.host}`);
|
|
48
|
-
terminal.note(
|
|
49
|
+
terminal.note(`Verify it in the repository owner’s GitHub account, then run: ${cliCommand('domain check')}`);
|
|
49
50
|
terminal.openUrl('https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site/verifying-your-custom-domain-for-github-pages');
|
|
50
51
|
return change;
|
|
51
52
|
}
|
|
@@ -83,7 +84,7 @@ export async function domain({ terminal, options, cwd = process.cwd() }) {
|
|
|
83
84
|
const configured = await api.configureTopologyChange(publication.siteId, pending.changeId);
|
|
84
85
|
terminal.done(`GitHub verified ${configured.cname}`);
|
|
85
86
|
terminal.note(dnsInstruction(configured.cname, await providerHost(api, publication.siteId)));
|
|
86
|
-
terminal.note(
|
|
87
|
+
terminal.note(`After DNS propagates, run: ${cliCommand('domain check')}`);
|
|
87
88
|
return configured;
|
|
88
89
|
}
|
|
89
90
|
const committed = await api.commitTopologyChange(publication.siteId, pending.changeId);
|
|
@@ -119,6 +120,6 @@ function dnsInstruction(host, target) {
|
|
|
119
120
|
function showPending(terminal, pending) {
|
|
120
121
|
terminal.result(`${pending.canonicalBaseUrl}${pending.pathPrefix}`);
|
|
121
122
|
terminal.note(`State: ${pending.state}`);
|
|
122
|
-
if (pending.state === 'PREPARED') terminal.note(
|
|
123
|
-
else terminal.note(
|
|
123
|
+
if (pending.state === 'PREPARED') terminal.note(`Next: verify ownership, then run ${cliCommand('domain check')}.`);
|
|
124
|
+
else terminal.note(`Next: configure DNS, then run ${cliCommand('domain check')}.`);
|
|
124
125
|
}
|
package/src/commands/init.js
CHANGED
|
@@ -7,6 +7,7 @@ import { galaCredential } from '../auth/gala.js';
|
|
|
7
7
|
import { githubCredential } from '../auth/github.js';
|
|
8
8
|
import { cloneRepository, createGit, populateEmptyRepository } from '../git.js';
|
|
9
9
|
import { UsageError } from '../cli/args.js';
|
|
10
|
+
import { CLI_INVOCATION, shellArgument } from '../cli/invocation.js';
|
|
10
11
|
import { customDomain } from '../domain.js';
|
|
11
12
|
|
|
12
13
|
/**
|
|
@@ -291,7 +292,7 @@ export function reportCreatedPublication({
|
|
|
291
292
|
directoryLabel,
|
|
292
293
|
hasDomainChange = false
|
|
293
294
|
}) {
|
|
294
|
-
const run =
|
|
295
|
+
const run = CLI_INVOCATION;
|
|
295
296
|
terminal.done(`Created ${owner}/${name}`);
|
|
296
297
|
terminal.note('The first deployment is running in GitHub Actions. The public site is not live yet.');
|
|
297
298
|
terminal.note(`track it at https://github.com/${owner}/${name}/actions`);
|
|
@@ -313,10 +314,6 @@ export function reportCreatedPublication({
|
|
|
313
314
|
terminal.note('lists every available command');
|
|
314
315
|
}
|
|
315
316
|
|
|
316
|
-
function shellArgument(value) {
|
|
317
|
-
return /^[A-Za-z0-9_./-]+$/.test(value) ? value : `'${value.replaceAll("'", "'\\''")}'`;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
317
|
function idempotencyKey(owner, name) {
|
|
321
318
|
return `init-${createHash('sha256').update(`${owner.toLowerCase()}/${name.toLowerCase()}`).digest('hex')}`;
|
|
322
319
|
}
|
package/src/commands/new.js
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
import { stringify } from 'yaml';
|
|
12
12
|
|
|
13
13
|
import { UsageError } from '../cli/args.js';
|
|
14
|
+
import { cliCommand } from '../cli/invocation.js';
|
|
14
15
|
import { postUrl, readPublication } from '../publication.js';
|
|
15
16
|
|
|
16
17
|
/**
|
|
@@ -54,7 +55,7 @@ export async function createPost({ terminal, options, cwd = process.cwd(), now =
|
|
|
54
55
|
if (address != null) terminal.note(`will appear at ${address}`);
|
|
55
56
|
|
|
56
57
|
terminal.blank();
|
|
57
|
-
terminal.note(
|
|
58
|
+
terminal.note(`write below the second --- line, then: ${cliCommand('preview')}`);
|
|
58
59
|
return { file, metadata };
|
|
59
60
|
}
|
|
60
61
|
|
package/src/commands/prism.js
CHANGED
|
@@ -4,6 +4,7 @@ import path from 'node:path';
|
|
|
4
4
|
import { galaApi } from '../api/gala.js';
|
|
5
5
|
import { galaCredential } from '../auth/gala.js';
|
|
6
6
|
import { UsageError } from '../cli/args.js';
|
|
7
|
+
import { cliCommand } from '../cli/invocation.js';
|
|
7
8
|
import { createGit } from '../git.js';
|
|
8
9
|
import { readPublication } from '../publication.js';
|
|
9
10
|
|
|
@@ -25,7 +26,7 @@ export async function prism({ terminal, options, cwd = process.cwd() }) {
|
|
|
25
26
|
const [action = 'status', ...args] = options.positional;
|
|
26
27
|
|
|
27
28
|
if (action === 'status') {
|
|
28
|
-
requireArgs(args, 0, '
|
|
29
|
+
requireArgs(args, 0, cliCommand('prism status'));
|
|
29
30
|
const state = await api.json(`/v1/sites/${publication.siteId}/prism`, { action: 'Prism status' });
|
|
30
31
|
terminal.result(`Prism ${state.publishedMode}`);
|
|
31
32
|
terminal.note(`Mode: requested ${state.requestedMode}; published ${state.publishedMode}`);
|
|
@@ -39,7 +40,7 @@ export async function prism({ terminal, options, cwd = process.cwd() }) {
|
|
|
39
40
|
const expectedRepositoryHeadSha = inventory.headSha;
|
|
40
41
|
|
|
41
42
|
if (action === 'mode') {
|
|
42
|
-
requireArgs(args, 1, '
|
|
43
|
+
requireArgs(args, 1, cliCommand('prism mode <off|presentation-only|manual|assisted>'));
|
|
43
44
|
const mode = MODES.get(args[0]);
|
|
44
45
|
if (!mode) throw new UsageError('Prism mode must be off, presentation-only, manual, or assisted.');
|
|
45
46
|
if (mode === 'OFF' || mode === 'PRESENTATION_ONLY') await confirm(terminal, options, `Change Prism mode to ${args[0]}?`);
|
|
@@ -52,7 +53,7 @@ export async function prism({ terminal, options, cwd = process.cwd() }) {
|
|
|
52
53
|
if (action === 'link-policy') {
|
|
53
54
|
const [scope, target, value] = args;
|
|
54
55
|
if (scope === 'site') {
|
|
55
|
-
requireArgs(args, 2, '
|
|
56
|
+
requireArgs(args, 2, cliCommand('prism link-policy site <nofollow|follow>'));
|
|
56
57
|
const policy = policyValue(target);
|
|
57
58
|
const result = await mutate(api, `/v1/sites/${publication.siteId}/prism`, 'PUT', {
|
|
58
59
|
configurationLinkPolicy: policy, expectedRepositoryHeadSha,
|
|
@@ -60,7 +61,7 @@ export async function prism({ terminal, options, cwd = process.cwd() }) {
|
|
|
60
61
|
return settleMutation(api, terminal, publication, result);
|
|
61
62
|
}
|
|
62
63
|
if (scope === 'work') {
|
|
63
|
-
requireArgs(args, 3, '
|
|
64
|
+
requireArgs(args, 3, cliCommand('prism link-policy work <slug> <inherit|nofollow|follow>'));
|
|
64
65
|
const post = resolvePost(inventory, target, options.value('language'), publication.defaultLanguage);
|
|
65
66
|
if (value === 'inherit') {
|
|
66
67
|
const result = await mutate(api,
|
|
@@ -76,11 +77,14 @@ export async function prism({ terminal, options, cwd = process.cwd() }) {
|
|
|
76
77
|
}, 'Prism work link policy');
|
|
77
78
|
return settleMutation(api, terminal, publication, result);
|
|
78
79
|
}
|
|
79
|
-
throw new UsageError(
|
|
80
|
+
throw new UsageError(
|
|
81
|
+
`Use: ${cliCommand('prism link-policy site <nofollow|follow>')} or `
|
|
82
|
+
+ cliCommand('prism link-policy work <slug> <inherit|nofollow|follow>')
|
|
83
|
+
);
|
|
80
84
|
}
|
|
81
85
|
|
|
82
86
|
if (action === 'list') {
|
|
83
|
-
requireArgs(args, 1, '
|
|
87
|
+
requireArgs(args, 1, cliCommand('prism list <slug> [--language en]'));
|
|
84
88
|
const post = resolvePost(inventory, args[0], options.value('language'), publication.defaultLanguage);
|
|
85
89
|
const result = await configurations(api, publication.siteId, post);
|
|
86
90
|
terminal.result(`${result.configurations.length} configuration${result.configurations.length === 1 ? '' : 's'}`);
|
|
@@ -91,7 +95,7 @@ export async function prism({ terminal, options, cwd = process.cwd() }) {
|
|
|
91
95
|
}
|
|
92
96
|
|
|
93
97
|
if (action === 'create') {
|
|
94
|
-
requireArgs(args, 1, '
|
|
98
|
+
requireArgs(args, 1, cliCommand('prism create <slug> --language en --depth brief --intent orientation'));
|
|
95
99
|
const post = resolvePost(inventory, args[0], options.value('language'), publication.defaultLanguage);
|
|
96
100
|
const current = await configurations(api, publication.siteId, post);
|
|
97
101
|
const result = await mutate(api,
|
|
@@ -108,7 +112,7 @@ export async function prism({ terminal, options, cwd = process.cwd() }) {
|
|
|
108
112
|
}
|
|
109
113
|
|
|
110
114
|
if (!['edit', 'generate', 'submit', 'approve', 'reject', 'revoke'].includes(action)) {
|
|
111
|
-
throw new UsageError(
|
|
115
|
+
throw new UsageError(`Unknown Prism action. Run ${cliCommand('prism --help')}.`);
|
|
112
116
|
}
|
|
113
117
|
|
|
114
118
|
const configurationId = args[0];
|
|
@@ -119,7 +123,7 @@ export async function prism({ terminal, options, cwd = process.cwd() }) {
|
|
|
119
123
|
const base = `/v1/sites/${publication.siteId}/articles/${post.articleId}/configurations/${configurationId}`;
|
|
120
124
|
|
|
121
125
|
if (action === 'edit') {
|
|
122
|
-
requireArgs(args, 1, '
|
|
126
|
+
requireArgs(args, 1, cliCommand('prism edit <configuration-id> --file proposal.md'));
|
|
123
127
|
const filename = options.value('file');
|
|
124
128
|
if (!filename) throw new UsageError('Prism edit needs --file proposal.md.');
|
|
125
129
|
const markdown = await readFile(path.resolve(root, filename), 'utf8');
|
|
@@ -132,7 +136,7 @@ export async function prism({ terminal, options, cwd = process.cwd() }) {
|
|
|
132
136
|
}
|
|
133
137
|
|
|
134
138
|
if (action === 'generate') {
|
|
135
|
-
requireArgs(args, 1, '
|
|
139
|
+
requireArgs(args, 1, cliCommand('prism generate <configuration-id>'));
|
|
136
140
|
const result = await mutate(api, `${base}/generation-jobs`, 'POST', {
|
|
137
141
|
expectedSourceContentHash: collection.sourceRevisionHash,
|
|
138
142
|
hashContract: collection.hashContract,
|
|
@@ -146,7 +150,7 @@ export async function prism({ terminal, options, cwd = process.cwd() }) {
|
|
|
146
150
|
throw new UsageError(`${action} needs a revision ID when there is no working revision.`);
|
|
147
151
|
}
|
|
148
152
|
if (action === 'submit') {
|
|
149
|
-
if (args.length > 2) throw new UsageError(
|
|
153
|
+
if (args.length > 2) throw new UsageError(`Use: ${cliCommand('prism submit <configuration-id> [revision-id]')}`);
|
|
150
154
|
if (revisionId !== configuration.workingRevision?.revisionId) {
|
|
151
155
|
throw new UsageError('Only the current working revision can be submitted. Refresh the configuration and try again.');
|
|
152
156
|
}
|
|
@@ -165,7 +169,7 @@ export async function prism({ terminal, options, cwd = process.cwd() }) {
|
|
|
165
169
|
|
|
166
170
|
const reason = options.value('reason');
|
|
167
171
|
if (action === 'approve') {
|
|
168
|
-
if (args.length > 2) throw new UsageError(
|
|
172
|
+
if (args.length > 2) throw new UsageError(`Use: ${cliCommand('prism approve <configuration-id> [revision-id] [--yes]')}`);
|
|
169
173
|
if (revisionId !== configuration.workingRevision?.revisionId) {
|
|
170
174
|
throw new UsageError('Only the current working revision can be approved. Refresh the configuration and try again.');
|
|
171
175
|
}
|
|
@@ -292,7 +296,7 @@ async function settleMutation(api, terminal, publication, result) {
|
|
|
292
296
|
throw new UsageError(`Repository update failed (${state.errorCode ?? 'unknown error'}). Run the command again after correcting the cause.`);
|
|
293
297
|
}
|
|
294
298
|
if (state.status !== 'COMMITTED') {
|
|
295
|
-
throw new UsageError(
|
|
299
|
+
throw new UsageError(`Repository update did not finish before the 31-minute tracking deadline. Check ${cliCommand('prism status')} before retrying.`);
|
|
296
300
|
}
|
|
297
301
|
if (!state.publicationAttemptSha) {
|
|
298
302
|
terminal.result('Repository updated. No publication attempt was returned.');
|
package/src/commands/upgrade.js
CHANGED
|
@@ -4,6 +4,8 @@ import { tmpdir } from 'node:os';
|
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { x as extractTar } from 'tar';
|
|
6
6
|
|
|
7
|
+
import { cliCommand } from '../cli/invocation.js';
|
|
8
|
+
|
|
7
9
|
const PACKAGE = '@rathnasgala/theme';
|
|
8
10
|
const REGISTRY = 'https://registry.npmjs.org';
|
|
9
11
|
const PROTECTED = ['.git/', 'content/', 'custom.css', 'site.config.yml'];
|
|
@@ -81,7 +83,7 @@ async function assertNoManagedDrift(root, installed) {
|
|
|
81
83
|
for (const [managed, expected] of Object.entries(installed.files)) {
|
|
82
84
|
const file = path.join(root, managed);
|
|
83
85
|
if (!await exists(file) || (await lstat(file)).isSymbolicLink() || sha256(await readFile(file)) !== expected) {
|
|
84
|
-
throw new Error(`${managed} has local changes; restore it with
|
|
86
|
+
throw new Error(`${managed} has local changes; restore it with ${cliCommand('doctor')} before upgrading`);
|
|
85
87
|
}
|
|
86
88
|
}
|
|
87
89
|
}
|
|
@@ -168,6 +170,6 @@ export async function upgrade({ terminal, options, cwd = process.cwd(), fetchImp
|
|
|
168
170
|
await rm(unpacked.temporary, { recursive: true, force: true });
|
|
169
171
|
}
|
|
170
172
|
terminal.done(`Upgraded managed theme to ${release.version}`);
|
|
171
|
-
terminal.note(
|
|
173
|
+
terminal.note(`Run ${cliCommand('preview')}, then ${cliCommand('publish')} when the result is approved.`);
|
|
172
174
|
return { changed: true, version: release.version };
|
|
173
175
|
}
|
package/src/commands-manifest.js
CHANGED
|
@@ -7,6 +7,7 @@ import { preview } from './commands/preview.js';
|
|
|
7
7
|
import { publish } from './commands/publish.js';
|
|
8
8
|
import { prism } from './commands/prism.js';
|
|
9
9
|
import { upgrade } from './commands/upgrade.js';
|
|
10
|
+
import { cliCommand } from './cli/invocation.js';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Commands in the order a writer meets them.
|
|
@@ -31,19 +32,19 @@ export const COMMANDS = {
|
|
|
31
32
|
},
|
|
32
33
|
init: {
|
|
33
34
|
summary: 'Create a publication in an empty directory',
|
|
34
|
-
usage: '
|
|
35
|
+
usage: cliCommand('init [directory] [--name my-notes] [--domain blog.example.com]'),
|
|
35
36
|
flags: ['name', 'domain', 'api-base-url'],
|
|
36
37
|
run: init
|
|
37
38
|
},
|
|
38
39
|
domain: {
|
|
39
40
|
summary: 'Inspect or change this publication’s custom domain',
|
|
40
|
-
usage: '
|
|
41
|
+
usage: cliCommand('domain [status|set <hostname>|check|cancel|remove] [--root path]'),
|
|
41
42
|
flags: ['root', 'api-base-url'],
|
|
42
43
|
run: domain
|
|
43
44
|
},
|
|
44
45
|
new: {
|
|
45
46
|
summary: 'Start a post',
|
|
46
|
-
usage: '
|
|
47
|
+
usage: cliCommand('new "A durable idea" [--language en]'),
|
|
47
48
|
flags: ['root', 'language', 'today'],
|
|
48
49
|
run: createPost
|
|
49
50
|
},
|
|
@@ -60,14 +61,14 @@ export const COMMANDS = {
|
|
|
60
61
|
},
|
|
61
62
|
prism: {
|
|
62
63
|
summary: 'Manage author-approved Prism configurations',
|
|
63
|
-
usage: '
|
|
64
|
+
usage: cliCommand('prism <status|mode|link-policy|list|create|edit|generate|submit|approve|reject|revoke> [arguments]'),
|
|
64
65
|
flags: ['root', 'api-base-url', 'language', 'depth', 'intent', 'modality', 'file', 'reason'],
|
|
65
66
|
switches: ['yes'],
|
|
66
67
|
run: prism
|
|
67
68
|
},
|
|
68
69
|
upgrade: {
|
|
69
70
|
summary: 'Inspect and apply a verified managed-theme update',
|
|
70
|
-
usage: '
|
|
71
|
+
usage: cliCommand('upgrade [--channel latest|next] [--yes]'),
|
|
71
72
|
flags: ['root', 'channel'],
|
|
72
73
|
switches: ['yes'],
|
|
73
74
|
run: upgrade
|
package/src/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { UsageError, parseArguments } from './cli/args.js';
|
|
3
|
+
import { CLI_INVOCATION, cliCommand } from './cli/invocation.js';
|
|
3
4
|
import { createTerminal } from './cli/terminal.js';
|
|
4
5
|
import { COMMANDS } from './commands-manifest.js';
|
|
5
6
|
|
|
@@ -20,7 +21,7 @@ if (command == null) {
|
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
if (argv.includes('--help') || argv.includes('-h')) {
|
|
23
|
-
process.stdout.write(`\n ${command.usage ??
|
|
24
|
+
process.stdout.write(`\n ${command.usage ?? cliCommand(name)}\n ${command.summary}\n\n`);
|
|
24
25
|
process.exit(0);
|
|
25
26
|
}
|
|
26
27
|
|
|
@@ -56,5 +57,6 @@ function usage() {
|
|
|
56
57
|
const lines = Object.entries(COMMANDS)
|
|
57
58
|
.map(([key, { summary }]) => ` ${key.padEnd(9)} ${summary}`)
|
|
58
59
|
.join('\n');
|
|
59
|
-
process.stdout.write(`\n
|
|
60
|
+
process.stdout.write(`\n ${CLI_INVOCATION} <command>\n\n${lines}\n\n`
|
|
61
|
+
+ ` Run ${CLI_INVOCATION} <command> --help for details.\n\n`);
|
|
60
62
|
}
|