Skip to content

Commit c6d5d72

Browse files
committed
fixup!
1 parent cc93442 commit c6d5d72

File tree

7 files changed

+856
-39
lines changed

7 files changed

+856
-39
lines changed

.github/workflows/generate.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ jobs:
5151
BASE_SHA: ${{ github.event.pull_request.base.sha }}
5252
GH_TOKEN: ${{ github.token }}
5353
run: |
54+
# `174604400` refers to `generate.yml`'s workflow ID, available at https://api.github.com/repos/nodejs/doc-kit/actions/workflows/generate.yml
55+
# The `databaseId` is a given runs run ID (Ref: https://docs.github.com/en/enterprise-cloud@latest/graphql/reference/objects#workflowrun)
5456
ID=$(gh run list --repo $GITHUB_REPOSITORY -c $BASE_SHA -w 174604400 -L 1 --json databaseId --jq ".[].databaseId")
5557
echo "run_id=$ID" >> $GITHUB_OUTPUT
5658

.github/workflows/leave-comment.yml

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,14 @@ jobs:
2929

3030
- name: Combine results
3131
id: combine
32+
# Even if the cat fails (no files found), we don't want to fail the workflow
33+
continue-on-error: true
3234
run: |
33-
shopt -s nullglob
34-
result_files=(results/*/comparison.txt)
35-
36-
if ((${#result_files[@]})); then
37-
{
38-
echo "combined<<EOF"
39-
cat "${result_files[@]}"
40-
echo "EOF"
41-
} >> "$GITHUB_OUTPUT"
42-
fi
35+
{
36+
echo "combined<<EOF"
37+
cat results/*/comparison.txt
38+
echo "EOF"
39+
} >> "$GITHUB_OUTPUT"
4340
4441
- name: Add Comment to PR
4542
if: steps.combine.outputs.combined

docs/commands.md

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
# Creating Commands
2+
3+
## Command Structure
4+
5+
Commands in `doc-kit` are defined as modules that export a command object conforming to the `Command` interface:
6+
7+
```typescript
8+
interface Command {
9+
name: string;
10+
description: string;
11+
options: { [key: string]: Option };
12+
action: (options: any) => Promise<void>;
13+
}
14+
```
15+
16+
Each command consists of:
17+
18+
- **name**: The command name used in the CLI (e.g., `generate`, `interactive`)
19+
- **description**: A short description shown in help text
20+
- **options**: An object mapping option names to their definitions
21+
- **action**: The async function that executes when the command is run
22+
23+
## Creating a New Command
24+
25+
### Step 1: Create the Command File
26+
27+
Create a new file in `bin/commands/` with your command name:
28+
29+
```javascript
30+
// bin/commands/my-command.mjs
31+
import logger from '../../src/logger/index.mjs';
32+
33+
/**
34+
* @type {import('./types').Command}
35+
*/
36+
export default {
37+
name: 'my-command',
38+
description: 'Does something useful',
39+
40+
options: {
41+
// Define your options here (see next section)
42+
},
43+
44+
async action(opts) {
45+
logger.info('Starting my-command', opts);
46+
47+
// Your command logic here
48+
49+
logger.info('Completed my-command');
50+
},
51+
};
52+
```
53+
54+
### Step 2: Register the Command
55+
56+
Add your command to the exports in `bin/commands/index.mjs`:
57+
58+
```javascript
59+
import generate from './generate.mjs';
60+
import interactive from './interactive.mjs';
61+
import myCommand from './my-command.mjs'; // Add this
62+
63+
export default [
64+
generate,
65+
interactive,
66+
myCommand, // Add this
67+
];
68+
```
69+
70+
### Step 3: Update CLI Entry Point
71+
72+
The CLI in `bin/cli.mjs` automatically loads commands from `bin/commands/index.mjs`, so no changes are needed there if you followed step 2.
73+
74+
## Command Options
75+
76+
Options define the flags and parameters your command accepts. Each option has:
77+
78+
```typescript
79+
interface Option {
80+
flags: string[]; // CLI flags (e.g., ['-i', '--input <value>'])
81+
desc: string; // Description for help text
82+
prompt?: PromptConfig; // Interactive mode configuration
83+
}
84+
```
85+
86+
### Defining Options
87+
88+
```javascript
89+
options: {
90+
input: {
91+
flags: ['-i', '--input <patterns...>'],
92+
desc: 'Input file patterns (glob)',
93+
prompt: {
94+
type: 'text',
95+
message: 'Enter input glob patterns',
96+
variadic: true,
97+
required: true,
98+
},
99+
},
100+
101+
force: {
102+
flags: ['-f', '--force'],
103+
desc: 'Force overwrite existing files',
104+
prompt: {
105+
type: 'confirm',
106+
message: 'Overwrite existing files?',
107+
initialValue: false,
108+
},
109+
},
110+
111+
mode: {
112+
flags: ['-m', '--mode <mode>'],
113+
desc: 'Operation mode',
114+
prompt: {
115+
type: 'select',
116+
message: 'Choose operation mode',
117+
options: [
118+
{ label: 'Fast', value: 'fast' },
119+
{ label: 'Thorough', value: 'thorough' },
120+
],
121+
},
122+
},
123+
}
124+
```
125+
126+
### Flag Syntax
127+
128+
- `<value>` - Required argument
129+
- `[value]` - Optional argument
130+
- `<values...>` - Variadic (multiple values)
131+
- `[values...]` - Optional variadic
132+
133+
### Option Types
134+
135+
#### `text`
136+
Single-line text input.
137+
138+
```javascript
139+
prompt: {
140+
type: 'text',
141+
message: 'Enter a value',
142+
initialValue: 'default',
143+
required: true,
144+
}
145+
```
146+
147+
#### `confirm`
148+
Yes/no confirmation.
149+
150+
```javascript
151+
prompt: {
152+
type: 'confirm',
153+
message: 'Are you sure?',
154+
initialValue: false,
155+
}
156+
```
157+
158+
#### `select`
159+
Single choice from a list.
160+
161+
```javascript
162+
prompt: {
163+
type: 'select',
164+
message: 'Choose one',
165+
options: [
166+
{ label: 'Option 1', value: 'opt1' },
167+
{ label: 'Option 2', value: 'opt2' },
168+
],
169+
}
170+
```
171+
172+
#### `multiselect`
173+
Multiple choices from a list.
174+
175+
```javascript
176+
prompt: {
177+
type: 'multiselect',
178+
message: 'Choose multiple',
179+
options: [
180+
{ label: 'Choice A', value: 'a' },
181+
{ label: 'Choice B', value: 'b' },
182+
],
183+
}
184+
```
185+
186+
## Interactive Prompts
187+
188+
The `interactive` command automatically uses the `prompt` configuration from your options. When users run:
189+
190+
```bash
191+
doc-kit interactive
192+
```
193+
194+
They'll be prompted to select a command, then guided through all required options.
195+
196+
### Prompt Configuration
197+
198+
- **message**: Question to ask the user
199+
- **type**: Input type (`text`, `confirm`, `select`, `multiselect`)
200+
- **required**: Whether the field must have a value
201+
- **initialValue**: Default value
202+
- **variadic**: Whether multiple values can be entered (for `text` type)
203+
- **options**: Choices for `select`/`multiselect` types
204+
205+
### Making Options Interactive-Friendly
206+
207+
Always provide helpful messages and sensible defaults:
208+
209+
```javascript
210+
threads: {
211+
flags: ['-p', '--threads <number>'],
212+
desc: 'Number of threads to use (minimum: 1)',
213+
prompt: {
214+
type: 'text',
215+
message: 'How many threads to allow',
216+
initialValue: String(cpus().length), // Smart default
217+
},
218+
},
219+
```

0 commit comments

Comments
 (0)