fm-bench 0.5.0 → 0.5.1

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 (2) hide show
  1. package/README.md +165 -174
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,41 +1,34 @@
1
1
  # fm-bench
2
2
 
3
- `fm-bench` is a dynamic benchmark CLI for Apple's `fm` command on macOS 27 and newer.
3
+ Benchmark Apple's `fm` command on macOS 27+.
4
4
 
5
- It discovers the models reported by `fm --help`, checks availability with `fm available`, runs repeatable prompt suites through `fm respond`, counts tokens with `fm token-count`, shows live progress while it works, and prints terminal tables with latency, throughput, stability, goodput, and streaming-quality stats.
5
+ Measure latency, throughput, streaming smoothness, stability, and goodput across Apple Foundation Models — with repeatable prompt suites and JSON/CSV reports for automation.
6
6
 
7
- Apple introduced the preinstalled `fm` command for macOS 27 as part of the Foundation Models tooling. `fm-bench` intentionally shells out to the system `fm` binary instead of linking private APIs, so it can adapt as Apple adds models or changes availability.
7
+ ## Why fm-bench exists
8
8
 
9
- ## Install
9
+ Apple's Foundation Models can run on-device, through Private Cloud Compute, and through model adapters. That makes raw model quality only half the story.
10
10
 
11
- ```sh
12
- npm install -g fm-bench
13
- ```
14
-
15
- You can also install directly from GitHub:
16
-
17
- ```sh
18
- npm install -g --install-links git+https://github.com/devinoldenburg/fm-bench.git
19
- ```
11
+ For real apps, the important questions are:
20
12
 
21
- For local development from this repository:
13
+ - How fast does the first token arrive?
14
+ - Does streaming stay smooth?
15
+ - How stable is latency over repeated runs?
16
+ - What happens under concurrency?
17
+ - Which model/hardware pair meets an interactive SLO?
22
18
 
23
- ```sh
24
- npm install
25
- npm link
26
- fm-bench doctor
27
- ```
19
+ `fm-bench` answers those questions with repeatable local benchmarks. Think of it as GeekBench for Apple Foundation Models — run it, get numbers, compare across hardware, models, and macOS updates.
28
20
 
29
21
  ## Quick Start
30
22
 
31
23
  ```sh
24
+ npm install -g fm-bench
32
25
  fm-bench
33
26
  ```
34
27
 
35
- Example output:
28
+ One command discovers your models, runs the standard prompt suite, and prints a full benchmark report:
36
29
 
37
30
  ```text
38
- fm-bench 0.4.0 | darwin/arm64 | fm
31
+ fm-bench 0.5.0 | darwin/arm64 | fm
39
32
  prompts 5 | runs 3 | concurrency 1,2 | stream on | measured 30 | failed 0 | skipped 0 | elapsed 42.10s | SLO TTFT<=750ms,E2E<=4.00s
40
33
 
41
34
  ┌───┬────────┬────────┬─────────┬──────┬──────┬──────────┬──────┬──────────┬─────┬─────┐
@@ -46,132 +39,173 @@ prompts 5 | runs 3 | concurrency 1,2 | stream on | measured 30 | failed 0 | skip
46
39
  └───┴────────┴────────┴─────────┴──────┴──────┴──────────┴──────┴──────────┴─────┴─────┘
47
40
  ```
48
41
 
49
- ## Commands
42
+ Wide terminals add TTFT P95, TPOT, decode/prefill throughput, chunk-gap smoothness, and 95% CI columns. Narrow terminals switch to compact model cards automatically.
43
+
44
+ ## Install
50
45
 
51
46
  ```sh
52
- fm-bench [run] [options]
53
- fm-bench models [options]
54
- fm-bench compare <before.json> <after.json> [options]
55
- fm-bench history [dir] [options]
56
- fm-bench legend [options]
57
- fm-bench doctor [options]
47
+ npm install -g fm-bench
58
48
  ```
59
49
 
60
- `run` is the default command. It benchmarks all models discovered from `fm` and skips models that are currently unavailable.
50
+ Install directly from GitHub (always latest):
61
51
 
62
- `models` lists discovered models, availability, descriptions, and quota output.
52
+ ```sh
53
+ npm install -g --install-links git+https://github.com/devinoldenburg/fm-bench.git
54
+ ```
63
55
 
64
- `compare` reads two saved JSON reports and prints a side-by-side regression table showing absolute and percent change for every latency, throughput, and reliability metric. Green/yellow/red coloring applies lower-is-better logic for latency and CV and higher-is-better for throughput. Use `--json` to get the diff as structured data.
56
+ Local development:
65
57
 
66
- `history` scans a directory for fm-bench JSON report files and prints a chronological trend table. Pairs with `--output-dir` to build a persistent benchmark archive.
58
+ ```sh
59
+ npm install && npm link
60
+ fm-bench doctor # verify your setup
61
+ ```
62
+
63
+ **Requirements:** macOS 27+, Node.js 20+, Apple Intelligence enabled.
67
64
 
68
- `legend` explains every terminal table column, compact-card field, model-list column, and color rule. It does not run `fm`.
65
+ ## Commands
69
66
 
70
- `doctor` checks Node, macOS, `fm`, model availability, CPU, memory, thermal throttle state, and battery status.
67
+ | Command | What it does |
68
+ |---------|-------------|
69
+ | `fm-bench` | Run the full benchmark (default) |
70
+ | `fm-bench models` | List discovered models, availability, and quota |
71
+ | `fm-bench compare <a.json> <b.json>` | Regression diff: before/after metrics with color-coded deltas |
72
+ | `fm-bench history [dir]` | Chronological trend table from a directory of saved reports |
73
+ | `fm-bench legend` | Definitions for every table column and color rule |
74
+ | `fm-bench doctor` | Environment check: Node, macOS, `fm`, CPU, memory, thermals, battery |
71
75
 
72
- ## Benchmark Options
76
+ ## Common Recipes
73
77
 
74
78
  ```sh
79
+ # Quick smoke test
80
+ fm-bench --profile quick
81
+
82
+ # Standard 5-run benchmark with SLO budgets
83
+ fm-bench --runs 5 --slo-ttft-ms 750 --slo-e2e-ms 4000
84
+
85
+ # Sweep concurrency to find your throughput ceiling
86
+ fm-bench --sweep-concurrency 1,2,4 --runs 3
87
+
88
+ # Stress both on-device and PCC models
75
89
  fm-bench --models system,pcc --runs 3 --profile stress
76
- fm-bench --models system --runs 5 --profile interactive
77
- fm-bench --models system --runs 3 --profile throughput --warmup 1
78
- fm-bench --models system --profile interactive --sweep-concurrency 1,2,4
79
- fm-bench --profile client --sweep-concurrency 1,2 --request-rate 0.5 --ramp-up-ms 2000
80
- fm-bench --models system --runs 5 --slo-ttft-ms 750 --slo-e2e-ms 4000
81
- fm-bench --profile reasoning --runs 5 --retry 2
82
- fm-bench --profile coding --runs 3 --tag pre-update --output-dir reports/
83
- fm-bench --prompt "Reply with exactly: ok" --runs 5
84
- fm-bench --prompt-file prompts.json --format json --out reports/bench.json
85
- fm-bench --format csv --out reports/bench.csv
86
- fm-bench --histogram
87
- fm-bench --ci --slo-ttft-ms 750 --slo-e2e-ms 4000
88
- fm-bench compare reports/before.json reports/after.json
89
- fm-bench history reports/
90
- fm-bench legend
91
- fm-bench legend --json
90
+
91
+ # Reasoning and coding workloads
92
+ fm-bench --profile reasoning --runs 5
93
+ fm-bench --profile coding --runs 3 --histogram
94
+
95
+ # Archive runs and compare before/after a macOS update
96
+ fm-bench --output-dir reports/ --tag before-update
97
+ fm-bench --output-dir reports/ --tag after-update
98
+ fm-bench compare reports/fm-bench_*before*.json reports/fm-bench_*after*.json
99
+
100
+ # Fail CI when SLOs regress
101
+ fm-bench --ci --slo-ttft-ms 750 --slo-e2e-ms 4000 --runs 5
102
+
103
+ # Save JSON for automation
104
+ fm-bench --json --out bench.json
105
+ fm-bench --format csv --out bench.csv
92
106
  ```
93
107
 
94
- Useful flags:
95
-
96
- - `--models <list>`: comma-separated or repeated model names.
97
- - `--runs <n>`: measured runs per prompt/model.
98
- - `--warmup <n>`: warmup runs per model before measurement.
99
- - `--concurrency <n>`: parallel `fm` processes.
100
- - `--sweep-concurrency <list>`: run separate measured operating points, such as `1,2,4`.
101
- - `--request-rate <rps>`: pace request starts at a target requests-per-second rate.
102
- - `--ramp-up-ms <n>`: gradually ramp request pacing over `n` milliseconds.
103
- - `--timeout-ms <n>`: timeout per `fm` call.
104
- - `--retry <n>`: retry failed `fm` calls up to `n` times with exponential backoff (500ms–4s). Useful for handling transient model busy errors.
105
- - `--slo-ttft-ms <n>`, `--slo-e2e-ms <n>`, `--slo-tpot-ms <n>`: count goodput against latency budgets.
106
- - `--ci`: exit with code 1 if any run fails or any SLO budget is violated. Disables color and progress. Designed for GitHub Actions and CI pipelines.
107
- - `--profile quick|standard|interactive|throughput|client|stress|reasoning|coding|creative`: built-in prompt suite.
108
- - `--prompt <text>`: custom prompt, repeatable.
109
- - `--prompt-file <file>`: JSON, JSONL, or blank-line separated text prompts.
110
- - `--instructions <text>`: passed to `fm respond`.
111
- - `--tag <name>`: tag this run (repeatable). Tags appear in the JSON payload and report header.
112
- - `--note <text>`: freeform note attached to the JSON payload and report header.
113
- - `--available-only`: hide unavailable discovered models.
114
- - `--capture-output`: include raw model output in JSON reports.
115
- - `--json`, `--csv`, `--format table|json|csv`: choose output format.
116
- - `--ascii`: use plain ASCII table borders.
117
- - `--color`, `--no-color`: force or disable semantic ANSI colors. Colors are automatic on TTYs.
118
- - `--progress`, `--no-progress`: force or disable the live progress status line on stderr.
119
- - `--compact`: force the narrow terminal layout.
120
- - `--width <n>`: render as if the terminal has `n` columns.
121
- - `--histogram`: print an ASCII latency distribution bar chart after the report.
122
- - `--out <file>`: save a report.
123
- - `--output-dir <dir>`: auto-save a timestamped JSON report to a directory on every run.
108
+ ## Options Reference
109
+
110
+ **Workload**
111
+
112
+ | Flag | Default | Description |
113
+ |------|---------|-------------|
114
+ | `-m, --models <list>` | all | Comma-separated or repeated model names |
115
+ | `-r, --runs <n>` | 1 | Measured runs per prompt/model |
116
+ | `--warmup <n>` | 0 | Warmup runs per model before measurement |
117
+ | `-c, --concurrency <n>` | 1 | Parallel `fm` processes |
118
+ | `--sweep-concurrency <list>` | — | Separate operating points, e.g. `1,2,4` |
119
+ | `--request-rate <rps>` | — | Pace request starts at a target rate |
120
+ | `--ramp-up-ms <n>` | 0 | Gradually ramp pacing over `n` ms |
121
+ | `--timeout-ms <n>` | 60000 | Timeout per `fm` call |
122
+ | `--retry <n>` | 0 | Retry failed calls with exponential backoff (500ms–4s) |
123
+ | `--profile <name>` | standard | Built-in prompt suite (see Profiles) |
124
+ | `-p, --prompt <text>` | — | Custom prompt, repeatable |
125
+ | `--prompt-file <file>` | — | JSON, JSONL, or blank-line separated prompts |
126
+ | `-i, --instructions <text>` | — | Passed to `fm respond` |
127
+
128
+ **Quality Gates**
129
+
130
+ | Flag | Description |
131
+ |------|-------------|
132
+ | `--slo-ttft-ms <n>` | Count a run as good only if TTFT ≤ n ms |
133
+ | `--slo-e2e-ms <n>` | Count a run as good only if E2E latency ≤ n ms |
134
+ | `--slo-tpot-ms <n>` | Count a run as good only if TPOT ≤ n ms |
135
+ | `--ci` | Exit 1 if any run fails or any SLO is violated (for pipelines) |
136
+ | `--fail-fast` | Stop after the first failed run |
137
+
138
+ **Output**
139
+
140
+ | Flag | Description |
141
+ |------|-------------|
142
+ | `--json` / `--csv` | Output format (also `--format table\|json\|csv`) |
143
+ | `-o, --out <file>` | Save a report to a file |
144
+ | `--output-dir <dir>` | Auto-save a timestamped JSON report to a directory |
145
+ | `--tag <name>` | Label this run; repeatable; appears in payload and header |
146
+ | `--note <text>` | Freeform annotation in payload and header |
147
+ | `--histogram` | Print ASCII latency distribution chart after the report |
148
+ | `--capture-output` | Include raw model output in JSON reports |
149
+ | `-v, --verbose` | Append per-run CSV after the summary table |
150
+
151
+ **Display**
152
+
153
+ | Flag | Description |
154
+ |------|-------------|
155
+ | `--color` / `--no-color` | Force or disable ANSI colors (auto on TTYs) |
156
+ | `--ascii` | Plain ASCII table borders instead of Unicode |
157
+ | `--compact` | Force narrow terminal layout |
158
+ | `--width <n>` | Render as if the terminal is `n` columns wide |
159
+ | `--progress` / `--no-progress` | Force or disable the live progress line |
124
160
 
125
161
  ## Prompt Profiles
126
162
 
127
- Nine built-in profiles cover a range of workloads:
128
-
129
- | Profile | Prompts | Focus |
130
- |---------|---------|-------|
131
- | `quick` | 1 | Single-prompt smoke test |
132
- | `standard` | 3 | Short chat, structured JSON, medium generation |
133
- | `interactive` | 3 | Short conversational turns |
134
- | `throughput` | 3 | Longer generation and transformation tasks |
135
- | `client` | 5 | Broad real-world mix: chat, content, extraction, summarization, code review |
136
- | `stress` | 5 | Diverse stress mix with math and reasoning |
137
- | `reasoning` | 5 | Multi-step math, logic, causal chains, estimation, debugging |
138
- | `coding` | 5 | Code review, refactoring, algorithms, code explanation, system design |
139
- | `creative` | 5 | Product copy, error messages, analogies, commit messages, doc writing |
163
+ Nine built-in suites, choose the one that matches your use case:
140
164
 
141
- Use `--profile reasoning` or `--profile coding` for richer signal when evaluating a model's capability alongside raw speed.
165
+ | Profile | Prompts | Best for |
166
+ |---------|---------|----------|
167
+ | `quick` | 1 | Smoke test, fast health check |
168
+ | `standard` | 3 | Default — short chat, JSON generation, medium output |
169
+ | `interactive` | 3 | Conversational latency (TTFT-heavy) |
170
+ | `throughput` | 3 | Longer generation, token throughput signal |
171
+ | `client` | 5 | Real-world mix: chat, content, extraction, summarization, code |
172
+ | `stress` | 5 | High-load mix with math and reasoning |
173
+ | `reasoning` | 5 | Multi-step logic, estimation, debugging — capability + speed |
174
+ | `coding` | 5 | Code review, refactoring, algorithms, system design |
175
+ | `creative` | 5 | Product copy, analogies, commit messages, docs |
142
176
 
143
- ## Compare Reports
177
+ ## Regression Tracking
144
178
 
145
- Save two runs to JSON and diff them:
179
+ Track performance across macOS updates, model changes, or hardware swaps:
146
180
 
147
181
  ```sh
148
- fm-bench --runs 5 --json --out before.json
149
- # ... update your system, wait, or run again ...
150
- fm-bench --runs 5 --json --out after.json
151
- fm-bench compare before.json after.json
152
- ```
182
+ # Before
183
+ fm-bench --profile coding --runs 5 --output-dir reports/ --tag before
153
184
 
154
- Output shows each model/concurrency row with before value, delta percentage (color-coded green/yellow/red), and after value for TTFT, E2E, TPOT, tokens/s, RPS, success rate, and CV.
185
+ # After the change
186
+ fm-bench --profile coding --runs 5 --output-dir reports/ --tag after
155
187
 
156
- ## Benchmark History
188
+ # See what changed
189
+ fm-bench compare reports/fm-bench_*before*.json reports/fm-bench_*after*.json
190
+ ```
157
191
 
158
- Use `--output-dir` to build an archive, then view trends with `history`:
192
+ The compare output shows each model/concurrency row with the before value, a color-coded percent delta (green = improvement, red = regression), and the after value — for TTFT, E2E, TPOT, tokens/s, RPS, success rate, and CV.
159
193
 
160
194
  ```sh
161
- fm-bench --output-dir reports/ --runs 3
162
- fm-bench --output-dir reports/ --runs 3
195
+ # View the full trend over time
163
196
  fm-bench history reports/
164
197
  ```
165
198
 
166
199
  ## CI Integration
167
200
 
168
- Use `--ci` to fail the pipeline when quality regresses:
201
+ Gate deployments or model updates on benchmark quality:
169
202
 
170
203
  ```sh
204
+ # Fails with exit code 1 if TTFT > 750ms or E2E > 4s on any run
171
205
  fm-bench --ci --slo-ttft-ms 750 --slo-e2e-ms 4000 --runs 5
172
206
  ```
173
207
 
174
- Exit code is 0 on pass, 1 on any failure or SLO violation. Prints `fm-bench ci: PASS` or `fm-bench ci: FAIL — <reasons>` to stderr.
208
+ Prints `fm-bench ci: PASS` or `fm-bench ci: FAIL — <reason>` to stderr. Designed for GitHub Actions, Buildkite, or any shell-based pipeline.
175
209
 
176
210
  ## Prompt Files
177
211
 
@@ -195,95 +229,52 @@ Plain text files are split on blank lines.
195
229
 
196
230
  ## Metrics
197
231
 
198
- `fm-bench` reports:
199
-
200
- - TTFT, or time to first streamed output.
201
- - E2E latency, or full response wall-clock latency.
202
- - TPOT, or decode time per output token after the first output token.
203
- - second-chunk delay and chunk-gap p95 as terminal-side streaming smoothness signals.
204
- - prefill tokens per second, or prompt tokens divided by TTFT.
205
- - output tokens per second per request.
206
- - total output token throughput across the measured window.
207
- - total token throughput, including prompt and output tokens.
208
- - requests per second across the measured window.
209
- - goodput percentage and goodput RPS when SLO flags are set.
210
- - coefficient of variation (CV) and confidence interval context for stability.
211
- - prompt and output token counts.
212
- - p50, p95, and p99 tail latency views.
213
- - repeatability across repeated runs of the same prompt.
214
- - success and failure counts.
215
- - unavailable model notes.
216
-
217
- Token counts come from `fm token-count --quiet`. If `fm` cannot count a response, token fields are left blank while character throughput is still reported.
232
+ **Latency** — TTFT (p50/p95), E2E (p50/p95/p99), TPOT (p50/p95), 95% confidence interval, coefficient of variation (CV).
218
233
 
219
- Measured runs stream by default so `fm-bench` can capture TTFT and streaming smoothness. Use `--no-stream` if you need buffered `fm respond` behavior; TTFT, TPOT, second-chunk, and chunk-gap fields that depend on streaming will be blank.
234
+ **Throughput** — prefill tokens/s, decode tokens/s, output tokens/s per request, aggregate system tokens/s, requests per second.
220
235
 
221
- Terminal output is responsive. Wide terminals show full scoreboard and detail tables, medium terminals show a tighter operating-point table, and narrow terminals switch to compact model cards. Long `NOTE`, `DESCRIPTION`, and model quota cells wrap so error context stays visible instead of being hidden behind ellipses. Use `--width` to preview a layout and `--ascii` for log systems that do not render Unicode borders well.
236
+ **Streaming quality** — second-chunk delay, chunk-gap p95. Captured from `stdout` chunks during streaming runs.
222
237
 
223
- ## Table Legend
238
+ **Reliability** — success rate, goodput rate and RPS against SLO budgets, repeatability (most common output hash frequency across repeated runs).
224
239
 
225
- Benchmark output stays focused on results and does not print the metric legend footer. Use `fm-bench legend` when you want definitions for every table column and color rule:
226
-
227
- ```sh
228
- fm-bench legend
229
- fm-bench legend --json
230
- fm-bench legend --csv
231
- ```
240
+ **Stability** — CV (stddev/mean for E2E latency); green ≤10%, yellow ≤25%, red >25%.
232
241
 
233
- The legend wraps long definitions and rules to fit the terminal width instead of hiding text behind ellipses.
242
+ Token counts come from `fm token-count --quiet`. If `fm` cannot count tokens, those fields are blank while character throughput is still reported.
234
243
 
235
- ## Live Progress
244
+ Terminal layout is responsive: wide → full scoreboard + detail tables, medium → tighter single table, narrow → compact model cards. Use `--width` to preview any layout and `--ascii` for log-friendly output.
236
245
 
237
- Interactive terminal runs show a single-line status indicator on stderr while prompts are loaded, models are inspected, tokens are counted, warmups run, and benchmark jobs complete. The final report still prints to stdout, so `--json`, `--csv`, and `--out` remain automation-friendly.
246
+ ## Colors and Legend
238
247
 
239
- Progress is automatic for table output on TTYs. Use `--progress` to force it or `--no-progress` to keep the terminal completely quiet until the report is ready.
248
+ Table output is color-coded on interactive terminals — **green** is better/passing, **yellow** is marginal/partial, **red** is failing/unstable. Fixed thresholds apply to success rate, goodput, CV, and repeatability. Latency uses SLO thresholds when set, otherwise lower-is-better relative ranking. Throughput uses higher-is-better relative ranking.
240
249
 
241
- ## Terminal Colors
242
-
243
- Table output uses semantic ANSI color on interactive terminals:
244
-
245
- - green: passing, steadier, or better than the current comparison set.
246
- - yellow: marginal, partial, or near a budget.
247
- - red: failing a budget, unstable, or slower/lower than peers.
248
-
249
- Success rate, goodput, repeatability, and CV use fixed benchmark thresholds. CV is green at `<=10%`, yellow at `<=25%`, and red above `25%` because higher CV means less steady latency. Throughput columns use relative ranking within the current run because “good” depends on the machine, model, prompt mix, and concurrency. TTFT, E2E, and TPOT use SLO thresholds when you pass `--slo-ttft-ms`, `--slo-e2e-ms`, or `--slo-tpot-ms`; otherwise they use lower-is-better relative ranking across the models and operating points in the report.
250
+ ```sh
251
+ fm-bench legend # full column definitions and color rules
252
+ fm-bench legend --json # machine-readable
253
+ ```
250
254
 
251
- Use `--color` to force ANSI colors in captured logs, or `--no-color` for plain output. `NO_COLOR=1` disables automatic color and `FORCE_COLOR=1` enables it.
255
+ `NO_COLOR=1` disables color; `FORCE_COLOR=1` or `--color` enables it. `--ascii` switches to plain ASCII borders for log systems.
252
256
 
253
- See [docs/methodology.md](docs/methodology.md) for the benchmark methodology and source references.
257
+ A live single-line progress indicator runs on stderr during interactive sessions. The final report always goes to stdout — `--json`, `--csv`, and `--out` stay automation-friendly.
254
258
 
255
259
  ## Requirements
256
260
 
257
- - macOS 27 or newer for Apple's `fm` CLI.
261
+ - macOS 27 or newer (Apple's `fm` CLI is preinstalled).
258
262
  - Node.js 20 or newer.
259
- - Apple Intelligence and model availability configured for the machine.
263
+ - Apple Intelligence enabled on the device.
264
+
265
+ `pcc` (Private Cloud Compute) availability depends on Apple's current eligibility. `fm-bench` shows it as skipped if `fm available --model pcc` reports unavailable.
260
266
 
261
- Private Cloud Compute (`pcc`) availability depends on Apple's current eligibility and context. If `fm available --model pcc` reports unavailable, `fm-bench` will show it as skipped.
267
+ See [docs/methodology.md](docs/methodology.md) for benchmark methodology and metric references.
262
268
 
263
269
  ## Development
264
270
 
265
271
  ```sh
266
272
  npm install
267
- npm test
273
+ npm test # node --test
268
274
  npm run lint
269
- npm pack
270
275
  ```
271
276
 
272
- The package has no runtime npm dependencies.
273
-
274
- ## Releases
275
-
276
- Releases are tag-driven:
277
-
278
- ```sh
279
- npm run release:patch
280
- npm run release:minor
281
- npm run release:major
282
- ```
283
-
284
- Pushing a `v*.*.*` tag runs the GitHub Release workflow, publishes to npm using the repository `NPM_TOKEN` secret, and creates a GitHub Release with generated notes.
285
-
286
- Maintainers can also run the **Version** workflow manually from GitHub Actions to bump the version and push the tag.
277
+ No runtime npm dependencies.
287
278
 
288
279
  ## License
289
280
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fm-bench",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "Dynamic benchmark CLI for Apple's fm command on macOS 27+.",
5
5
  "type": "module",
6
6
  "bin": {