pickem 1.0.0 → 1.0.2
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/README.md +68 -69
- package/package.json +1 -9
package/README.md
CHANGED
|
@@ -1,39 +1,40 @@
|
|
|
1
1
|
# pickem
|
|
2
2
|
|
|
3
|
-
Usage-sorted searchable autocomplete for CLI tools
|
|
3
|
+
**Usage-sorted, searchable autocomplete for CLI tools.** Give every command-line tool the same fast, interactive picker: type to filter, arrow to choose — and the options you reach for most float to the top on their own.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
  
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
npm install pickem
|
|
11
|
-
```
|
|
7
|
+

|
|
12
8
|
|
|
13
|
-
|
|
9
|
+
- **Search as you type** — filter on labels, descriptions, or any field you name
|
|
10
|
+
- **Usage-aware ordering** — frequently chosen items sort to the top automatically
|
|
11
|
+
- **Single- and multi-select** — with optional free-text entry for ad-hoc values
|
|
12
|
+
- **Wizard flows** — chain prompts with branching and conditional steps
|
|
13
|
+
- **Light and fully typed** — one runtime dependency, ESM, ships with types
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
## Install
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
|
|
19
|
-
cd pickem && npm install && npm run demo
|
|
18
|
+
npm install pickem
|
|
20
19
|
```
|
|
21
20
|
|
|
22
|
-
## Quick
|
|
21
|
+
## Quick start
|
|
23
22
|
|
|
24
23
|
```typescript
|
|
25
24
|
import { pickem } from 'pickem'
|
|
26
25
|
|
|
27
26
|
const choice = await pickem([
|
|
28
27
|
{ label: 'Deploy', value: 'deploy', description: 'Push to production' },
|
|
29
|
-
{ label: 'Test',
|
|
30
|
-
{ label: 'Lint',
|
|
28
|
+
{ label: 'Test', value: 'test', description: 'Run test suite' },
|
|
29
|
+
{ label: 'Lint', value: 'lint', description: 'Check formatting' },
|
|
31
30
|
])
|
|
32
31
|
```
|
|
33
32
|
|
|
34
|
-
|
|
33
|
+
Type to filter, arrow keys to move, Enter to choose. The selected value is returned.
|
|
35
34
|
|
|
36
|
-
|
|
35
|
+
## Multi-select
|
|
36
|
+
|
|
37
|
+
`pickem.checkbox(items, opts)` returns the values of every checked item.
|
|
37
38
|
|
|
38
39
|
```typescript
|
|
39
40
|
import { pickem } from 'pickem'
|
|
@@ -46,35 +47,37 @@ const choices = await pickem.checkbox([
|
|
|
46
47
|
// => ['deploy', 'test']
|
|
47
48
|
```
|
|
48
49
|
|
|
49
|
-
|
|
50
|
+
Space toggles a selection, Enter submits, type to filter, Esc clears the filter, Backspace removes filter characters.
|
|
50
51
|
|
|
51
|
-
Pass `searchable: false` to fall back to
|
|
52
|
+
Pass `searchable: false` to fall back to a plain checkbox list with no search bar:
|
|
52
53
|
|
|
53
54
|
```typescript
|
|
54
55
|
const choices = await pickem.checkbox(items, { searchable: false })
|
|
55
56
|
```
|
|
56
57
|
|
|
57
|
-
Pass `
|
|
58
|
+
Pass `allowFreeText: true` to let users add ad-hoc entries: type text that matches nothing, press Enter, and it's appended to the list as a checked item — the filter clears and the picker stays open so they can keep going.
|
|
58
59
|
|
|
59
60
|
```typescript
|
|
60
61
|
const tags = await pickem.checkbox(KNOWN_TAGS, { allowFreeText: true })
|
|
61
62
|
```
|
|
62
63
|
|
|
63
|
-
## Usage
|
|
64
|
+
## Usage-aware ordering
|
|
64
65
|
|
|
65
|
-
Items sort by how often they'
|
|
66
|
+
Items sort by how often they've been chosen, so the picker adapts to how each user actually works. Enable it with `track: true`:
|
|
66
67
|
|
|
67
68
|
```typescript
|
|
68
69
|
const choice = await pickem(items, {
|
|
69
|
-
track: true,
|
|
70
|
-
// or:
|
|
70
|
+
track: true, // stored in ~/.pickem/usage.json
|
|
71
|
+
// or point it somewhere of your own:
|
|
71
72
|
track: { storePath: '~/.myapp/usage.json' },
|
|
72
73
|
})
|
|
73
74
|
```
|
|
74
75
|
|
|
75
|
-
3-tier sort: count
|
|
76
|
+
Ordering is a 3-tier sort: usage count, then most-recently-used, then alphabetical.
|
|
77
|
+
|
|
78
|
+
## Multiple sources
|
|
76
79
|
|
|
77
|
-
|
|
80
|
+
Pull items from several places at once — they load in parallel and merge into one picker.
|
|
78
81
|
|
|
79
82
|
```typescript
|
|
80
83
|
import { pickem, defineSource } from 'pickem'
|
|
@@ -86,45 +89,45 @@ const scripts = defineSource('scripts', async () => [
|
|
|
86
89
|
|
|
87
90
|
const npm = defineSource('npm', async () => [
|
|
88
91
|
{ label: 'build', value: 'npm run build' },
|
|
89
|
-
{ label: 'test',
|
|
92
|
+
{ label: 'test', value: 'npm test' },
|
|
90
93
|
])
|
|
91
94
|
|
|
92
95
|
const choice = await pickem.from([scripts, npm], { track: true })
|
|
93
|
-
//
|
|
96
|
+
// Set badgeStyle to label each item by source, e.g. [scripts], [npm]
|
|
94
97
|
```
|
|
95
98
|
|
|
96
|
-
## Wizard
|
|
99
|
+
## Wizard flows
|
|
97
100
|
|
|
98
|
-
Chain multiple prompts with branching
|
|
101
|
+
Chain multiple prompts together, with branching and conditional steps.
|
|
99
102
|
|
|
100
103
|
```typescript
|
|
101
104
|
import { wizard } from 'pickem'
|
|
102
105
|
|
|
103
106
|
const result = await wizard([
|
|
104
|
-
{ id: 'action', type: 'pick',
|
|
105
|
-
{ id: 'env',
|
|
107
|
+
{ id: 'action', type: 'pick', message: 'What to do?', items: allScripts },
|
|
108
|
+
{ id: 'env', type: 'select', message: 'Environment:', choices: [
|
|
106
109
|
{ label: 'Production', value: 'prod' },
|
|
107
|
-
{ label: 'Staging',
|
|
110
|
+
{ label: 'Staging', value: 'staging' },
|
|
108
111
|
], when: ctx => ctx.action === 'deploy' },
|
|
109
112
|
{ id: 'confirm', type: 'confirm', message: 'Are you sure?' },
|
|
110
|
-
{ id: 'route',
|
|
113
|
+
{ id: 'route', type: 'branch', on: ctx => ctx.confirm ? 'done' : 'action' },
|
|
111
114
|
])
|
|
112
115
|
```
|
|
113
116
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
|
117
|
-
|------|---------|
|
|
118
|
-
| `pick` | Searchable usage-sorted selection |
|
|
117
|
+
| Step type | Purpose |
|
|
118
|
+
|------------|---------|
|
|
119
|
+
| `pick` | Searchable, usage-sorted selection |
|
|
119
120
|
| `checkbox` | Searchable multi-select, returns an array |
|
|
120
|
-
| `select`
|
|
121
|
-
| `input`
|
|
122
|
-
| `confirm`
|
|
123
|
-
| `branch`
|
|
121
|
+
| `select` | Simple choice list |
|
|
122
|
+
| `input` | Free text entry |
|
|
123
|
+
| `confirm` | Yes / no |
|
|
124
|
+
| `branch` | Route to a step ID or inject steps dynamically |
|
|
125
|
+
|
|
126
|
+
Every step supports `when` (run conditionally) and `before` (a pre-step hook).
|
|
124
127
|
|
|
125
|
-
|
|
128
|
+
## Standalone usage tracker
|
|
126
129
|
|
|
127
|
-
|
|
130
|
+
The usage tracker works on its own, too — handy for ranking anything by frequency.
|
|
128
131
|
|
|
129
132
|
```typescript
|
|
130
133
|
import { UsageTracker } from 'pickem'
|
|
@@ -134,26 +137,26 @@ await tracker.track('deploy')
|
|
|
134
137
|
await tracker.track('deploy')
|
|
135
138
|
|
|
136
139
|
const sorted = await tracker.sortItems(items)
|
|
137
|
-
const top
|
|
138
|
-
const stats
|
|
140
|
+
const top = await tracker.getTop(10)
|
|
141
|
+
const stats = await tracker.getStats('deploy') // { count: 2, lastUsed: ... }
|
|
139
142
|
```
|
|
140
143
|
|
|
141
144
|
## Options
|
|
142
145
|
|
|
143
146
|
```typescript
|
|
144
147
|
await pickem(items, {
|
|
145
|
-
message: 'Pick one:',
|
|
146
|
-
pageSize: 15,
|
|
147
|
-
track: true
|
|
148
|
-
searchable: true,
|
|
149
|
-
searchFields: ['label', 'description'], // Fields to search (dot-notation for meta)
|
|
150
|
-
search: (item, term) => boolean, // Custom
|
|
151
|
-
format: (item, stats) => string, // Custom
|
|
152
|
-
badgeStyle: 'none' | 'bracket' | 'dot' | fn
|
|
153
|
-
badgeColors: { npm: 'red' },
|
|
154
|
-
sort: (a, b) => number,
|
|
155
|
-
onSelect: (item) => {},
|
|
156
|
-
allowFreeText:
|
|
148
|
+
message: 'Pick one:', // Prompt message
|
|
149
|
+
pageSize: 15, // Visible items per page
|
|
150
|
+
track: true, // Enable usage tracking (true | TrackOptions)
|
|
151
|
+
searchable: true, // false skips the search bar
|
|
152
|
+
searchFields: ['label', 'description'], // Fields to search (dot-notation for nested meta)
|
|
153
|
+
search: (item, term) => boolean, // Custom match function
|
|
154
|
+
format: (item, stats) => string, // Custom row formatter
|
|
155
|
+
badgeStyle: 'none', // Group badge style: 'none' | 'bracket' | 'dot' | fn
|
|
156
|
+
badgeColors: { npm: 'red' }, // Per-group badge colors
|
|
157
|
+
sort: (a, b) => number, // Tiebreaker applied after usage sort
|
|
158
|
+
onSelect: (item) => {}, // Callback fired on selection
|
|
159
|
+
allowFreeText: false, // Surface unmatched input as a selectable option
|
|
157
160
|
})
|
|
158
161
|
```
|
|
159
162
|
|
|
@@ -162,20 +165,16 @@ await pickem(items, {
|
|
|
162
165
|
```typescript
|
|
163
166
|
await pickem.checkbox(items, {
|
|
164
167
|
required: false, // Require at least one selection before Enter submits
|
|
165
|
-
defaultChecked: ['test'], //
|
|
166
|
-
allowFreeText: true, // Type unmatched text + Enter to add as a checked item
|
|
168
|
+
defaultChecked: ['test'], // Values checked on open
|
|
169
|
+
allowFreeText: true, // Type unmatched text + Enter to add it as a checked item
|
|
167
170
|
})
|
|
168
171
|
```
|
|
169
172
|
|
|
170
|
-
### `badgeStyle` default changed in v0.2.0
|
|
171
|
-
|
|
172
|
-
The default `badgeStyle` is now `'none'` — group labels are hidden unless you opt in. This is a breaking change if your code relied on the old default of `'bracket'`. To restore the previous behavior:
|
|
173
|
-
|
|
174
|
-
```typescript
|
|
175
|
-
await pickem(items, { badgeStyle: 'bracket' })
|
|
176
|
-
```
|
|
177
|
-
|
|
178
173
|
## Requirements
|
|
179
174
|
|
|
180
|
-
- Node >= 18
|
|
175
|
+
- Node.js >= 18
|
|
181
176
|
- ESM only
|
|
177
|
+
|
|
178
|
+
## License
|
|
179
|
+
|
|
180
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pickem",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Usage-sorted searchable autocomplete for CLI tools",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.js",
|
|
@@ -21,14 +21,6 @@
|
|
|
21
21
|
"picker",
|
|
22
22
|
"wizard"
|
|
23
23
|
],
|
|
24
|
-
"repository": {
|
|
25
|
-
"type": "git",
|
|
26
|
-
"url": "git+https://github.com/calebogden/pickem.git"
|
|
27
|
-
},
|
|
28
|
-
"bugs": {
|
|
29
|
-
"url": "https://github.com/calebogden/pickem/issues"
|
|
30
|
-
},
|
|
31
|
-
"homepage": "https://github.com/calebogden/pickem#readme",
|
|
32
24
|
"author": "Caleb Ogden <co@ogden.co>",
|
|
33
25
|
"license": "MIT",
|
|
34
26
|
"engines": {
|