featureparity 0.0.27 → 0.0.29

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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/lib/fp/cli.rb +14 -2
  3. data/lib/fp/client.rb +79 -2
  4. data/lib/fp/commands/analyze.rb +17 -0
  5. data/lib/fp/commands/base.rb +16 -0
  6. data/lib/fp/commands/check.rb +38 -4
  7. data/lib/fp/commands/ci_report.rb +2 -2
  8. data/lib/fp/commands/comment.rb +1 -1
  9. data/lib/fp/commands/comments.rb +146 -0
  10. data/lib/fp/commands/coverage.rb +149 -0
  11. data/lib/fp/commands/doctor.rb +228 -0
  12. data/lib/fp/commands/help.rb +41 -1
  13. data/lib/fp/commands/history.rb +16 -1
  14. data/lib/fp/commands/init.rb +181 -117
  15. data/lib/fp/commands/list.rb +58 -4
  16. data/lib/fp/commands/mark.rb +167 -0
  17. data/lib/fp/commands/projects.rb +6 -1
  18. data/lib/fp/commands/propose.rb +435 -53
  19. data/lib/fp/commands/propose_change.rb +13 -7
  20. data/lib/fp/commands/question.rb +137 -0
  21. data/lib/fp/commands/report.rb +40 -4
  22. data/lib/fp/commands/run.rb +147 -0
  23. data/lib/fp/commands/show.rb +41 -3
  24. data/lib/fp/commands/spot_check.rb +458 -0
  25. data/lib/fp/commands/tutorial.rb +95 -0
  26. data/lib/fp/commands/whoami.rb +2 -0
  27. data/lib/fp/commands.rb +8 -0
  28. data/lib/fp/config.rb +12 -0
  29. data/lib/fp/junit.rb +74 -11
  30. data/lib/fp/repo_detector.rb +488 -0
  31. data/lib/fp/requirement_lint.rb +105 -0
  32. data/lib/fp/rspec_json.rb +54 -0
  33. data/lib/fp/tutorial/hexhaven/AGENTS.md +5 -0
  34. data/lib/fp/tutorial/hexhaven/README.md +29 -0
  35. data/lib/fp/tutorial/hexhaven/lib/hexhaven.rb +36 -0
  36. data/lib/fp/tutorial/hexhaven/test/junit_reporter.rb +134 -0
  37. data/lib/fp/tutorial/hexhaven/test/rules_test.rb +36 -0
  38. data/lib/fp/tutorial/hexhaven/test/test_helper.rb +6 -0
  39. data/lib/fp/version.rb +1 -1
  40. data/lib/fp.rb +1 -0
  41. data/skills/fp/SKILL.md +244 -105
  42. data/skills/fp/references/cli.md +304 -3
  43. metadata +19 -2
@@ -210,17 +210,74 @@ fp report --junit junit.xml \
210
210
 
211
211
  | Flag | Required | Description |
212
212
  |------|----------|-------------|
213
- | `--junit` | Yes | Path to JUnit XML report |
213
+ | `--junit` | Yes | Path to a JUnit XML report, or RSpec's own `--format json` report |
214
214
  | `--project` | Yes | Project slug |
215
215
  | `--surface` | Conditional | Default surface for markers without `@suffix`. Required if any matched marker pins no surface. |
216
216
  | `--repo` | Yes | GitHub repo as `org/repo` |
217
217
  | `--base-dir` | No | Where to resolve relative file paths (defaults to cwd) |
218
+ | `--attach-media` | No | Upload the screenshots and videos the run recorded (Playwright's `[[ATTACHMENT|…]]` entries) as visual evidence, one set per bound test, titled with the test's name. Unknown slugs and unsupported or oversized files are skipped with a reason |
218
219
 
219
220
  In JUnit mode:
220
221
  - Slugs come from `fp:<slug>` markers in the test files referenced by the report
221
222
  - A marker binds to the test directly below it
222
223
  - Skipped/pending tests become `stub`; all others `present`
223
224
  - Unknown slugs and unmarked tests are skipped with a warning
225
+ - A JSON report from `rspec --format json --out rspec.json` works as-is (recognised by its
226
+ content, no extra flag), so an RSpec suite needs no `rspec_junit_formatter`. `fp ci-report`
227
+ and `fp check --junit` take it the same way.
228
+
229
+ ### fp run
230
+
231
+ Run a test command with a report formatter fp adds itself, then report the results exactly
232
+ as `fp report --junit` would. Nothing is added to the project under test.
233
+
234
+ ```bash
235
+ fp run --surface api --repo stowzilla/marketplace -- bundle exec rspec
236
+ fp run --surface api --repo stowzilla/marketplace -- pytest tests/
237
+ (cd frontend && fp run --surface web --repo stowzilla/marketplace -- npx vitest run)
238
+ fp run --surface web --repo stowzilla/marketplace -- npx playwright test
239
+ ```
240
+
241
+ | Runner | What fp adds |
242
+ |--------|--------------|
243
+ | rspec | `--format json --out <tmp>`, plus `--format progress` when the command names no formatter |
244
+ | pytest | `-o junit_family=xunit1 --junitxml=<tmp>` (xunit1 carries each test's file and line) |
245
+ | vitest | `--reporter=default --reporter=junit --outputFile.junit=<tmp>` |
246
+ | playwright | `--reporter=list,junit`, with `PLAYWRIGHT_JUNIT_OUTPUT_NAME=<tmp>` |
247
+
248
+ Everything before `--` is an `fp report` flag (`--surface`, `--repo`, `--project`,
249
+ `--test-type`, `--work-item`, `--pr`, `--base-dir`, ...); everything after it is the test
250
+ command, left alone (global flags like `--json` or `-p` there belong to the runner). Agents
251
+ still report `present`/`stub` only. When the tests fail, fp reports first and then exits with
252
+ the test command's status. Any other runner errors with the supported list: make it write
253
+ JUnit XML and use `fp report --junit <file>`.
254
+
255
+ ### fp attach / fp attachments
256
+
257
+ Attach a screenshot, video or file to a requirement as evidence. Visual captures sit under the
258
+ receipt of the test they prove on the requirement page, and the team can copy one into the
259
+ client showroom. This is optional and stores the file in FeatureParity, so an agent uploads
260
+ only with permission from the person it works for, and never captures someone's own screen.
261
+
262
+ ```bash
263
+ fp attach checkout_flow e2e/results/checkout.webm --project stowzilla --surface web \
264
+ --example-title "pays by card" --sha $(git rev-parse HEAD)
265
+ fp attachments checkout_flow --project stowzilla # list
266
+ fp attachments checkout_flow <id> --project stowzilla # download URL
267
+ fp attach rm checkout_flow <id> --project stowzilla # delete
268
+ ```
269
+
270
+ | Flag | Required | Description |
271
+ |------|----------|-------------|
272
+ | `--surface` | For images/videos | Surface the capture is for |
273
+ | `--example-title` | No | Name of the test this capture proves (nests it under that receipt) |
274
+ | `--evidence-key` | No | Bind to a specific receipt (`surface:repo:test_type`) |
275
+ | `--deployment-url` / `--deployed-at` | No | The deployment the capture observed |
276
+ | `--captured-at` / `--sha` / `--test-run-url` | No | When, at which commit, and in which run |
277
+
278
+ Images and video: png, jpg, gif, webp, mp4, webm, mov. Files: txt, md, json, svg, pdf. Up to
279
+ 100 MB each, and several files per call. For a Playwright run, `fp report --junit ... --attach-media`
280
+ does this for every bound test at once (with the same permission). A capture never changes a cell's state.
224
281
 
225
282
  ### fp propose
226
283
 
@@ -265,6 +322,20 @@ fp propose --project stowzilla \
265
322
  | `--why` | No | User need, problem or risk, and valuable outcome |
266
323
  | `--required` | No | Comma-separated surfaces that must implement this |
267
324
  | `--acceptance` | No | Observable behaviour and material boundaries |
325
+ | `--required-types` | No | Comma-separated kinds of test each surface needs |
326
+ | `--parent` | No | Parent requirement's slug (nests one level) |
327
+ | `--category` | No | `functional`, `non-functional`, `ux`, `performance`, `security`, `compliance` |
328
+ | `--tags` | No | Comma-separated labels |
329
+ | `--source-type` / `--source-url` / `--source-context` | No | Where it came from |
330
+ | `--source-ref` | No | A repository place it was read from, e.g. `app/models/order.rb:42`. Repeatable |
331
+ | `--dry-run` | No | Validate and lint the wording, and check the catalog for a taken slug or missing parent. Writes nothing |
332
+ | `--file` | No | YAML or JSON batch (below). Other flags become defaults for every entry |
333
+
334
+ After creating the draft, `fp propose` prints its quality feedback — a verdict, the issues
335
+ found, and suggestions — in the same run (`analysis` in `--json`). Act on it: revise a weak
336
+ draft with `fp propose-change`, or withdraw one that shouldn't be a requirement. When analysis
337
+ is unavailable the draft is still created, and the output says the feedback couldn't be
338
+ produced (`analysis_error`).
268
339
 
269
340
  **Write for a decision-maker, not an implementer.** The result should sound natural and be
270
341
  ready for management review without someone translating AI boilerplate or reverse-engineering
@@ -300,6 +371,53 @@ earn its place?
300
371
 
301
372
  **Agents always create requirements as draft.** A human must activate them in the web app.
302
373
 
374
+ #### Checking wording first: `--dry-run`
375
+
376
+ `fp propose ... --dry-run` prints what would be created and a list of wording notes. These
377
+ cover a title that names the work (`Implement…`), commentary openings (`This feature…`,
378
+ `Users should be able to…`), filler (`seamless`, `robust`), a missing why or acceptance, an
379
+ acceptance with no `Example:`, several sentences of rule that may be separate promises, and a
380
+ number in the rule that a source has to have decided. Notes are advice, not errors. A taken
381
+ slug or a missing parent is an error, and it exits 1. Without `--dry-run`, the notes go to
382
+ stderr and the draft is still created.
383
+
384
+ #### A batch: `--file`
385
+
386
+ ```yaml
387
+ defaults: # optional; merged into every entry
388
+ required: [api, web]
389
+ source_type: repo_scan
390
+ requirements:
391
+ - slug: profile_editing
392
+ name: People keep their profile current
393
+ why: ...
394
+ acceptance: "... Example: ..."
395
+ - slug: profile_required_fields
396
+ parent: profile_editing # another entry, or a requirement already in the project
397
+ name: A profile can't be saved without a school
398
+ source_refs: [app/models/academic_experience.rb:12]
399
+ ```
400
+
401
+ Every entry is checked before anything is written: an unknown field (a typo like
402
+ `acceptence`), a bad category or source type, a slug that appears twice or already exists, and
403
+ a parent that isn't found or is itself a child. If any of these fails, nothing is created.
404
+ Parents in the file are created before their children, and the created drafts are printed as
405
+ one table. Run with `--dry-run` first to hand a human the batch for review.
406
+
407
+ ### fp mark
408
+
409
+ ```bash
410
+ fp mark academic_experience_required_fields spec/models/academic_experience_spec.rb:52
411
+ fp mark checkout_flow e2e/checkout.spec.ts:10 --surface web --type e2e
412
+ ```
413
+
414
+ Inserts `fp:<slug>` (with `@surfaces` and `:type` when given) directly above the test on that
415
+ line, using the file's own comment syntax (`#`, `//` or `--`) and indentation, then names the
416
+ test it binds to. Running it again on the same marker changes nothing. `--comment` sets the
417
+ prefix for an extension fp doesn't know, and `--dry-run` shows the line without writing it.
418
+ This is purely local and needs no API key. Never mark a failing test to make a requirement
419
+ look covered.
420
+
303
421
  ### fp propose-change
304
422
 
305
423
  Propose a change to a requirement that already exists — or propose deleting it.
@@ -332,9 +450,10 @@ fp propose-change print_container_qr --project stowzilla \
332
450
  | `--parent` | No | Proposed parent requirement, by slug |
333
451
  | `--slug` | No | Proposed new key; evidence follows it, but existing `fp:<slug>` markers must be updated |
334
452
  | `--reason` | No | Why the change is needed |
335
- | `--source-type` | No | `fizzy`, `discord`, `github_issue`, `jira`, `notion`, `manual`, `ai_chat` |
453
+ | `--source-type` | No | `fizzy`, `discord`, `github_issue`, `jira`, `notion`, `manual`, `ai_chat`, `repo_scan` (an agent derived it from the code) |
336
454
  | `--source-url` | No | Link to the card/message/issue that prompted it |
337
455
  | `--source-context` | No | Free-text context |
456
+ | `--source-ref` | No | A repository place that prompted it, e.g. `app/models/order.rb:42`. Repeatable |
338
457
 
339
458
  At least one proposed value (or `--removal`) is required — a bare invocation would knock a
340
459
  live requirement back to draft for nothing, so it errors instead.
@@ -370,6 +489,54 @@ the review decision where one was made. An open proposal is called out at the en
370
489
 
371
490
  `--project` is optional when the repo has a `.featureparity.yml`.
372
491
 
492
+ ### fp question / fp questions
493
+
494
+ Attach an open question for a human to the requirement it concerns, and read the answers.
495
+ Use it for the decisions a draft can't settle by itself, instead of leaving them in chat.
496
+
497
+ ```bash
498
+ fp question upload_limits "Is the 5 MB cap per file or per upload?"
499
+ fp question upload_limits --body "Does the cap apply to admins?" --project stowzilla
500
+ fp questions upload_limits # every question, open and resolved, with answers
501
+ fp questions upload_limits --open --json # only the open ones
502
+ ```
503
+
504
+ Asking never changes the requirement's status or wording. The human reviewing it sees the
505
+ question in Quick Review and on the requirement page, and answers it (the answer is kept
506
+ with the question) or dismisses it. `fp show <slug>` lists the open questions, and `fp
507
+ history` shows each question and its answer in the timeline. Agents can ask but cannot
508
+ answer or dismiss; there is no CLI command for that.
509
+
510
+ Draft and active requirements take questions, including a draft awaiting review of a
511
+ proposed change. Refusals, printed verbatim:
512
+
513
+ | Situation | Status |
514
+ |-----------|--------|
515
+ | No question text, or more than 2000 characters | 422 |
516
+ | Requirement is archived or rejected | 422 |
517
+
518
+ `--project` is optional when the repo has a `.featureparity.yml`.
519
+ ### fp comments
520
+
521
+ Read or join the team's conversation on a requirement, and tag people or agents in it.
522
+
523
+ ```bash
524
+ fp comments print_container_qr --project stowzilla # comments + who can be tagged
525
+ fp comments print_container_qr --body "The label redesign dropped this — retire it?" \
526
+ --tag andy@example.com
527
+ fp comments print_container_qr --body "Can you re-check this against the new label?" --tag claude
528
+ ```
529
+
530
+ A comment never changes the requirement. `--tag` takes a teammate's email or name, or one of
531
+ the team's agents by name or key name; an unknown or ambiguous tag stops the command and
532
+ posts nothing. Tagged people get an email; each tagged agent fires the project's
533
+ `requirement.agent_mentioned` webhook, whose payload names the agent, the requirement and
534
+ the comment, plus the `fp` commands to read and answer it. If a human tagged you, answer
535
+ with `fp comments <slug> --body "..."` — and if the question means the requirement is
536
+ wrong, propose the change with `fp propose-change` rather than settling it in a comment.
537
+
538
+ `fp comment` (singular) is different: it threads a comment onto an open change proposal.
539
+
373
540
  ### fp analyze
374
541
 
375
542
  Triage requirement quality: duplicates, fragments of a broader promise, vague wording,
@@ -459,6 +626,52 @@ classifications remain open for a human product decision. A stale candidate is r
459
626
  later fingerprint always requires a new assessment. Assessing never changes the requirement
460
627
  wording or CI outcome.
461
628
 
629
+ ### fp spot-check
630
+
631
+ A random drug test for evidence. A green receipt proves a marked test ran and passed, not
632
+ that it checks what the requirement promises. `fp spot-check` picks one active requirement
633
+ that has evidence on record, at random, and prints its why and acceptance, its receipts, and
634
+ the source of every `fp:<slug>` test it finds in the checkout, then a brief.
635
+
636
+ ```bash
637
+ fp spot-check # random pick; prints the seed
638
+ fp spot-check --seed 4821 # repeat that pick
639
+ fp spot-check --surface cli --json # narrow to one surface; machine-readable
640
+ fp spot-check print_container_qr print_label # chosen requirements, any status
641
+ fp spot-check --count 5 # five distinct requirements at random
642
+ fp spot-check --all # every active requirement with evidence
643
+ fp spot-check --test test/qr_test.rb # every marked test in the file
644
+ fp spot-check --test test/qr_test.rb:42 # only the test spanning that line
645
+ fp spot-check --path ../android # look for the tests in another checkout
646
+ ```
647
+
648
+ Use one way of choosing per run: slugs, `--count`, `--all`, or `--test` (which may be
649
+ repeated). The seed is printed only for the random picks. In `--json` the result is
650
+ `checks` (one entry per requirement, each with `requirement`, `evidence` and `tests`), plus
651
+ a single `brief` that applies to every check.
652
+
653
+ `--prompt` prints the whole spot check as instructions for an agent, so a person or a
654
+ schedule can hand it over as is (`fp spot-check --count 3 --prompt | claude -p`). It ends
655
+ with what to report for each requirement: `proves`, `does_not_prove` or `uncertain`, the
656
+ clauses no assertion checks, the probe made and the tests that failed, and a clean
657
+ `git status`. It can't be combined with `--json`.
658
+
659
+ `--jev` first sends each requirement's marked tests (up to 10) to Jev and adds its read:
660
+ `agree`, `gaps` or `uncertain`, how likely the tests are to cover the acceptance, the
661
+ likeliest gap (`unasserted_clause`, `asserts_other_behaviour`, `cannot_fail`,
662
+ `tests_a_double`), and a per-test likelihood. Treat it as a hint about where to aim the
663
+ probe. It doesn't replace the probe. Jev is for paid plans: a person on Pro or Lifetime,
664
+ or a project whose owner is (that is what lets an agent use it). Otherwise the spot check
665
+ prints a note and carries on without it. Nothing Jev reads is stored.
666
+
667
+ The brief: list each result and boundary the acceptance promises; name the clause each
668
+ test's assertions actually check; make one small change to the *product code* that breaks
669
+ the promise, run only those tests, and confirm one fails; revert and confirm `git status` is
670
+ clean. A test that stays green under the probe, or checks something the acceptance doesn't
671
+ say, doesn't prove the requirement. Report that to a human with what you tried. Don't
672
+ rewrite the test or the requirement as part of a spot check. The command itself is
673
+ read-only.
674
+
462
675
  #### Upgrading an existing project
463
676
 
464
677
  Changed-test auditing requires fp 0.0.17 or newer and the corresponding backend deployment.
@@ -506,6 +719,45 @@ A slug suffixed with `✎` has a proposed change awaiting review — it is still
506
719
  the gate, and its evidence is `suspect` until someone reviews the change. `--csv` writes
507
720
  `<slug> (under review)` instead of the glyph.
508
721
 
722
+ `--status draft --gaps` lists *drafts* with a required surface lacking real evidence
723
+ (missing, stubbed, or failing). Plain `--gaps` reads the gate, which never measures a
724
+ never-approved draft, so on a freshly onboarded project it says "No gaps found". See
725
+ `fp coverage` for the full drafts × surfaces table.
726
+
727
+ ### fp coverage
728
+
729
+ Draft coverage: which draft requirements have marked tests or evidence on which surfaces,
730
+ and which have none. The gate measures only active requirements (plus ones an open
731
+ proposal demoted), so on a new project where every requirement is still a draft `fp check`
732
+ says "Nothing to enforce yet". This is how an onboarding agent confirms its work before a
733
+ human activates anything.
734
+
735
+ ```bash
736
+ fp coverage # drafts × surfaces, then the drafts with no evidence
737
+ fp coverage --surface api
738
+ fp coverage --all # also the measured (active / under review) rows
739
+ fp coverage --json # drafts, untested, and with --all, measured
740
+ ```
741
+
742
+ | Flag | Description |
743
+ |------|-------------|
744
+ | `--project` | Project slug (optional if `.featureparity.yml` declares one) |
745
+ | `--surface` | Restrict to one surface |
746
+ | `--all` | Also list the requirements the gate measures |
747
+
748
+ Each cell is resolved from evidence exactly as the matrix will resolve it once the draft is
749
+ active. The command ends with a plain list — the "requirements with no test" section to hand
750
+ the human:
751
+
752
+ ```
753
+ 2 draft(s) with no evidence on a required surface:
754
+ export_csv — no evidence on: web
755
+ bulk_delete — no evidence on: api, web
756
+ ```
757
+
758
+ "No evidence" means `missing`: nothing at all is filed, not even a stub. Drafts are
759
+ reported, never gated — this command exits 0 on a successful read, whatever it shows.
760
+
509
761
  ### fp check
510
762
 
511
763
  The enforcement gate. Exits **1** when the project violates its enforcement level, so it
@@ -528,6 +780,7 @@ fp check --surface api --junit junit.xml # gate on this run's results (preview)
528
780
  | `--junit` | Evaluate this run's JUnit results without saving them (repeatable) |
529
781
  | `--pr [url]` | With `--junit`: this run is a pull request — fail only on parity it makes worse |
530
782
  | `--warn-only` | Report violations but exit 0 |
783
+ | `--include-drafts` | After the verdict, print draft coverage (as `fp coverage`); never changes the exit code. `--json` adds `drafts` |
531
784
 
532
785
  **Enforcement levels** (the level is configured on the project; don't hardcode one):
533
786
 
@@ -616,6 +869,8 @@ Onboard a repo onto FeatureParity. Writes three files and makes no API calls (so
616
869
  before a key is configured).
617
870
 
618
871
  ```bash
872
+ fp init --detect # suggest slug, surfaces, test commands; writes nothing
873
+ fp init --detect --json
619
874
  fp init --project stowzilla --surface api
620
875
  fp init --project stowzilla --no-workflow # skip the CI workflow
621
876
  fp init --project stowzilla --no-agents # skip the AGENTS.md section
@@ -635,7 +890,53 @@ marker comments and recognised on re-run, so it is never duplicated.
635
890
  The `AGENTS.md` section tells agents to bind a test to a requirement with `fp:<slug>`, to
636
891
  propose a new requirement when none covers the work, and to use `fp propose-change`
637
892
  instead of editing or ignoring a requirement that no longer says the right thing — plus
638
- the guards they would otherwise learn from a 403.
893
+ the guards they would otherwise learn from a 403. It opens with the fp version that wrote
894
+ it (`Written by fp X.Y.Z`), has an *Onboarding a repo* first-run path and a
895
+ *Troubleshooting* list, and copies its modeling, writing, onboarding and troubleshooting
896
+ blocks from the skill's `SKILL.md` (between `fp-shared` comments) rather than keeping a
897
+ second copy.
898
+
899
+ `--detect` reads the checkout (Gemfile, package.json, Podfile and Xcode projects, Android
900
+ manifests, pyproject/requirements, Rails routes and `config/database.yml`, docker-compose),
901
+ in the root and one directory down, and prints:
902
+
903
+ - a suggested slug (the git remote's repo name, else the directory name);
904
+ - suggested surfaces with the reason for each, and the rubric to judge them by: a surface is
905
+ somewhere a user interacts with the product, and an internal API with no separate client
906
+ isn't one;
907
+ - each test runner (rspec, minitest, jest, vitest, playwright, pytest, xctest, gradle), the
908
+ command that makes it write a report fp reads, the dependency that needs adding (or none),
909
+ and the `fp run` form where there is one;
910
+ - whether the tests need a database server, and whether there's a `.devcontainer`.
911
+
912
+ A plain `fp init` prints the detected test command and the database note in its closing
913
+ guidance. When the tests need a database server, the generated workflow's report recipe gets
914
+ a TODO and a commented-out service block. Committing the workflow before the `FP_API_KEY`
915
+ secret exists is fine: the gate skips with an explanation and stays green.
916
+
917
+ ### fp doctor
918
+
919
+ Check that fp works here, with no API key and no API calls.
920
+
921
+ ```bash
922
+ fp doctor
923
+ fp doctor --dir path/to/repo
924
+ fp doctor --json
925
+ ```
926
+
927
+ - **Ruby:** the Ruby running fp, the gem's version and path, the `fp` on `PATH` (and whether
928
+ it's a version-manager shim), and whether this directory pins a different Ruby in
929
+ `.ruby-version`, `.tool-versions`, `mise.toml` or `.mise.toml`. On a mismatch it prints
930
+ the fix: install the gem under the pinned Ruby (`mise exec ruby@<pinned> -- gem install
931
+ featureparity`, or `gem install featureparity` in the repo), or put the running Ruby's bin
932
+ directory first on `PATH`.
933
+ - **Config:** the API environment (warning when it isn't production), whether a key is
934
+ present, which `.featureparity.yml` applies, and which fp wrote the `AGENTS.md` section.
935
+ - **Repo:** the same summary as `fp init --detect`.
936
+
937
+ `mise ERROR No version is set for shim: fp` comes from the shim, before fp runs, so doctor
938
+ can't catch it from inside that repo. Run it from somewhere fp works (another directory, or
939
+ with the other Ruby's bin directory on `PATH`) to get the commands.
639
940
 
640
941
  ### fp profile
641
942
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: featureparity
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.27
4
+ version: 0.0.29
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stowzilla
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-11-02 00:00:00.000000000 Z
11
+ date: 2026-11-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-http
@@ -103,25 +103,33 @@ files:
103
103
  - lib/fp/commands/check.rb
104
104
  - lib/fp/commands/ci_report.rb
105
105
  - lib/fp/commands/comment.rb
106
+ - lib/fp/commands/comments.rb
106
107
  - lib/fp/commands/config_cmd.rb
107
108
  - lib/fp/commands/conversation.rb
109
+ - lib/fp/commands/coverage.rb
110
+ - lib/fp/commands/doctor.rb
108
111
  - lib/fp/commands/export.rb
109
112
  - lib/fp/commands/help.rb
110
113
  - lib/fp/commands/history.rb
111
114
  - lib/fp/commands/init.rb
112
115
  - lib/fp/commands/list.rb
116
+ - lib/fp/commands/mark.rb
113
117
  - lib/fp/commands/matrix.rb
114
118
  - lib/fp/commands/profile.rb
115
119
  - lib/fp/commands/projects.rb
116
120
  - lib/fp/commands/propose.rb
117
121
  - lib/fp/commands/propose_change.rb
122
+ - lib/fp/commands/question.rb
118
123
  - lib/fp/commands/report.rb
119
124
  - lib/fp/commands/repos.rb
125
+ - lib/fp/commands/run.rb
120
126
  - lib/fp/commands/setup.rb
121
127
  - lib/fp/commands/show.rb
122
128
  - lib/fp/commands/showroom.rb
123
129
  - lib/fp/commands/showroom_media.rb
130
+ - lib/fp/commands/spot_check.rb
124
131
  - lib/fp/commands/surfaces.rb
132
+ - lib/fp/commands/tutorial.rb
125
133
  - lib/fp/commands/version.rb
126
134
  - lib/fp/commands/whoami.rb
127
135
  - lib/fp/config.rb
@@ -129,7 +137,16 @@ files:
129
137
  - lib/fp/output.rb
130
138
  - lib/fp/parity.rb
131
139
  - lib/fp/project_config.rb
140
+ - lib/fp/repo_detector.rb
141
+ - lib/fp/requirement_lint.rb
142
+ - lib/fp/rspec_json.rb
132
143
  - lib/fp/source_fingerprint.rb
144
+ - lib/fp/tutorial/hexhaven/AGENTS.md
145
+ - lib/fp/tutorial/hexhaven/README.md
146
+ - lib/fp/tutorial/hexhaven/lib/hexhaven.rb
147
+ - lib/fp/tutorial/hexhaven/test/junit_reporter.rb
148
+ - lib/fp/tutorial/hexhaven/test/rules_test.rb
149
+ - lib/fp/tutorial/hexhaven/test/test_helper.rb
133
150
  - lib/fp/version.rb
134
151
  - skills/fp/SKILL.md
135
152
  - skills/fp/references/cli.md