featureparity 0.0.1 → 0.0.3
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.
- checksums.yaml +4 -4
- data/lib/fp/cli.rb +19 -4
- data/lib/fp/client.rb +24 -17
- data/lib/fp/commands/base.rb +7 -7
- data/lib/fp/commands/config_cmd.rb +130 -0
- data/lib/fp/commands/help.rb +40 -1
- data/lib/fp/commands/list.rb +58 -17
- data/lib/fp/commands/matrix.rb +7 -10
- data/lib/fp/commands/projects.rb +11 -5
- data/lib/fp/commands/propose.rb +45 -4
- data/lib/fp/commands/report.rb +161 -12
- data/lib/fp/commands/repos.rb +169 -0
- data/lib/fp/commands/setup.rb +11 -4
- data/lib/fp/commands/show.rb +4 -2
- data/lib/fp/commands/surfaces.rb +5 -5
- data/lib/fp/commands.rb +2 -0
- data/lib/fp/config.rb +151 -22
- data/lib/fp/junit.rb +212 -0
- data/lib/fp/output.rb +1 -1
- data/lib/fp/version.rb +1 -1
- data/lib/fp.rb +1 -0
- data/skills/fp/SKILL.md +140 -0
- data/skills/fp/references/cli.md +219 -0
- data/skills/fp/references/markers.md +149 -0
- metadata +8 -2
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# fp CLI Reference
|
|
2
|
+
|
|
3
|
+
Complete flag reference for the `fp` command-line tool.
|
|
4
|
+
|
|
5
|
+
## Global flags
|
|
6
|
+
|
|
7
|
+
These work with any command:
|
|
8
|
+
|
|
9
|
+
| Flag | Description |
|
|
10
|
+
|------|-------------|
|
|
11
|
+
| `--json` | Output JSON instead of human-readable text |
|
|
12
|
+
| `--profile NAME` | Use a named profile from `~/.config/fp/config.yml` |
|
|
13
|
+
| `--api-url URL` | Override the API URL for this invocation |
|
|
14
|
+
| `--help` | Show help for any command |
|
|
15
|
+
|
|
16
|
+
## Commands
|
|
17
|
+
|
|
18
|
+
### fp setup
|
|
19
|
+
|
|
20
|
+
Interactive first-run configuration. Validates API key and saves a profile.
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
fp setup # Interactive
|
|
24
|
+
fp setup --api-key fp_... --non-interactive # Non-interactive
|
|
25
|
+
fp setup --api-key fp_... --profile ci # Named profile
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### fp projects
|
|
29
|
+
|
|
30
|
+
List accessible projects.
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
fp projects
|
|
34
|
+
fp projects --json
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### fp surfaces
|
|
38
|
+
|
|
39
|
+
List surfaces for a project.
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
fp surfaces --project stowzilla
|
|
43
|
+
fp surfaces --project stowzilla --json
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### fp list
|
|
47
|
+
|
|
48
|
+
List requirements.
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
fp list --project stowzilla # All active requirements
|
|
52
|
+
fp list --project stowzilla --gaps # Requirements without evidence
|
|
53
|
+
fp list --project stowzilla --status draft
|
|
54
|
+
fp list --project stowzilla --json
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
| Flag | Description |
|
|
58
|
+
|------|-------------|
|
|
59
|
+
| `--project` | Project slug (required) |
|
|
60
|
+
| `--gaps` | Show only requirements without evidence |
|
|
61
|
+
| `--status` | Filter by status: active, draft, archived |
|
|
62
|
+
| `--category` | Filter by category |
|
|
63
|
+
|
|
64
|
+
### fp show
|
|
65
|
+
|
|
66
|
+
Show requirement details.
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
fp show print_container_qr --project stowzilla
|
|
70
|
+
fp show print_container_qr --project stowzilla --json
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### fp report
|
|
74
|
+
|
|
75
|
+
Report evidence linking a test to a requirement.
|
|
76
|
+
|
|
77
|
+
**Single-slug mode:**
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
fp report <slug> \
|
|
81
|
+
--project stowzilla \
|
|
82
|
+
--surface api \
|
|
83
|
+
--file spec/qr_spec.rb \
|
|
84
|
+
--repo stowzilla/marketplace \
|
|
85
|
+
[--pr URL] [--sha COMMIT] [--work-item URL] [--ci-url URL] [--title "..."] [--state present|stub]
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
| Flag | Required | Description |
|
|
89
|
+
|------|----------|-------------|
|
|
90
|
+
| `<slug>` | Yes | Requirement slug (positional) |
|
|
91
|
+
| `--project` | Yes | Project slug |
|
|
92
|
+
| `--surface` | Yes | Surface this evidence covers |
|
|
93
|
+
| `--file` | Yes | Path to test file (relative to repo root) |
|
|
94
|
+
| `--repo` | Yes | GitHub repo as `org/repo` |
|
|
95
|
+
| `--pr` | No | Pull request URL |
|
|
96
|
+
| `--sha` | No | Commit SHA |
|
|
97
|
+
| `--work-item` | No | Fizzy card or issue URL |
|
|
98
|
+
| `--ci-url` | No | CI run URL |
|
|
99
|
+
| `--title` | No | Human-readable test name for display |
|
|
100
|
+
| `--state` | No | `present` (default) or `stub`. Never `passing`/`failing` — that's CI's job. |
|
|
101
|
+
|
|
102
|
+
**JUnit batch mode:**
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
fp report --junit junit.xml \
|
|
106
|
+
--project stowzilla \
|
|
107
|
+
--surface api \
|
|
108
|
+
--repo stowzilla/marketplace \
|
|
109
|
+
[--base-dir DIR] [--pr URL] [--sha COMMIT] [--work-item URL] [--ci-url URL]
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
| Flag | Required | Description |
|
|
113
|
+
|------|----------|-------------|
|
|
114
|
+
| `--junit` | Yes | Path to JUnit XML report |
|
|
115
|
+
| `--project` | Yes | Project slug |
|
|
116
|
+
| `--surface` | Conditional | Default surface for markers without `@suffix`. Required if any matched marker pins no surface. |
|
|
117
|
+
| `--repo` | Yes | GitHub repo as `org/repo` |
|
|
118
|
+
| `--base-dir` | No | Where to resolve relative file paths (defaults to cwd) |
|
|
119
|
+
|
|
120
|
+
In JUnit mode:
|
|
121
|
+
- Slugs come from `fp:<slug>` markers in the test files referenced by the report
|
|
122
|
+
- A marker binds to the test directly below it
|
|
123
|
+
- Skipped/pending tests become `stub`; all others `present`
|
|
124
|
+
- Unknown slugs and unmarked tests are skipped with a warning
|
|
125
|
+
|
|
126
|
+
### fp propose
|
|
127
|
+
|
|
128
|
+
Propose a new requirement as draft.
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
fp propose --project stowzilla \
|
|
132
|
+
--slug print_container_qr \
|
|
133
|
+
--name "Print QR on container label" \
|
|
134
|
+
--why "Enables scanning containers" \
|
|
135
|
+
--required api,customer_android \
|
|
136
|
+
--acceptance "Label shows scannable QR code"
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
| Flag | Required | Description |
|
|
140
|
+
|------|----------|-------------|
|
|
141
|
+
| `--project` | Yes | Project slug |
|
|
142
|
+
| `--slug` | Yes | Requirement slug (immutable, choose carefully) |
|
|
143
|
+
| `--name` | Yes | Human-readable name |
|
|
144
|
+
| `--why` | No | Why this requirement matters |
|
|
145
|
+
| `--required` | No | Comma-separated surfaces that must implement this |
|
|
146
|
+
| `--acceptance` | No | How to verify completion |
|
|
147
|
+
|
|
148
|
+
**Agents always create requirements as draft.** A human must activate in the web app.
|
|
149
|
+
|
|
150
|
+
### fp matrix
|
|
151
|
+
|
|
152
|
+
Display the parity matrix.
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
fp matrix --project stowzilla # ASCII table
|
|
156
|
+
fp matrix --project stowzilla --csv # CSV export
|
|
157
|
+
fp matrix --project stowzilla --json # JSON
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### fp profile
|
|
161
|
+
|
|
162
|
+
Manage named profiles.
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
fp profile list
|
|
166
|
+
fp profile add staging --api-key fp_...
|
|
167
|
+
fp profile remove staging
|
|
168
|
+
fp profile show staging
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### fp config
|
|
172
|
+
|
|
173
|
+
Manage global settings.
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
fp config list
|
|
177
|
+
fp config get api_url
|
|
178
|
+
fp config set api_url https://api.dev.featureparity.dev
|
|
179
|
+
fp config unset api_url
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### fp repos
|
|
183
|
+
|
|
184
|
+
Map surfaces to local repo paths (stored locally, not in the web app).
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
fp repos list --project stowzilla
|
|
188
|
+
fp repos set customer_android ~/code/customer-android --project stowzilla --repo org/repo
|
|
189
|
+
fp repos get customer_android --project stowzilla
|
|
190
|
+
fp repos unset customer_android --project stowzilla
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Exit codes
|
|
194
|
+
|
|
195
|
+
| Code | Meaning |
|
|
196
|
+
|------|---------|
|
|
197
|
+
| 0 | Success |
|
|
198
|
+
| 1 | General error (invalid flags, missing required args, API error) |
|
|
199
|
+
|
|
200
|
+
## Configuration files
|
|
201
|
+
|
|
202
|
+
- `~/.config/fp/config.yml` — Profiles and global settings
|
|
203
|
+
- `FP_API_KEY` environment variable overrides all profiles
|
|
204
|
+
- `FP_API_URL` environment variable overrides API URL
|
|
205
|
+
- `FP_PROFILE` environment variable selects a profile
|
|
206
|
+
|
|
207
|
+
## API URL priority
|
|
208
|
+
|
|
209
|
+
1. `--api-url` flag
|
|
210
|
+
2. `FP_API_URL` environment variable
|
|
211
|
+
3. Profile `api_url` setting
|
|
212
|
+
4. Global `api_url` setting
|
|
213
|
+
5. Default: `https://api.featureparity.dev`
|
|
214
|
+
|
|
215
|
+
## Profile resolution priority
|
|
216
|
+
|
|
217
|
+
1. `--profile` flag
|
|
218
|
+
2. `FP_PROFILE` environment variable
|
|
219
|
+
3. `default` profile (if it exists)
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# fp Marker Syntax
|
|
2
|
+
|
|
3
|
+
The `fp:<slug>` marker binds a test to a FeatureParity requirement. Place it as a comment immediately before the test definition.
|
|
4
|
+
|
|
5
|
+
## Basic syntax
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
fp:<slug>
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Where `<slug>` is the requirement's slug (lowercase, underscores, e.g., `print_container_qr`).
|
|
12
|
+
|
|
13
|
+
## Surface pinning
|
|
14
|
+
|
|
15
|
+
Pin one or more surfaces with the `@` suffix:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
fp:<slug>@<surface>
|
|
19
|
+
fp:<slug>@<surface1>,<surface2>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Examples:
|
|
23
|
+
- `fp:print_qr` — uses `--surface` flag when reporting
|
|
24
|
+
- `fp:print_qr@api` — reports for `api` surface only
|
|
25
|
+
- `fp:print_qr@api,web` — reports for both `api` and `web`
|
|
26
|
+
|
|
27
|
+
When using `fp report --junit`, each pinned surface produces a separate evidence upload.
|
|
28
|
+
|
|
29
|
+
## Language examples
|
|
30
|
+
|
|
31
|
+
### Ruby/RSpec
|
|
32
|
+
|
|
33
|
+
```ruby
|
|
34
|
+
# fp:print_container_qr
|
|
35
|
+
it 'prints a QR code onto the container label' do
|
|
36
|
+
expect(label.qr_code).to be_present
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# fp:print_container_qr@api,web
|
|
40
|
+
it 'prints a QR code (backend test covering multiple surfaces)' do
|
|
41
|
+
expect(label.qr_code).to be_present
|
|
42
|
+
end
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Kotlin/JUnit
|
|
46
|
+
|
|
47
|
+
```kotlin
|
|
48
|
+
// fp:print_container_qr
|
|
49
|
+
@Test
|
|
50
|
+
fun `prints a QR code onto the container label`() {
|
|
51
|
+
assertNotNull(label.qrCode)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// fp:print_container_qr@customer_android
|
|
55
|
+
@Test
|
|
56
|
+
fun `prints a QR code (Android-specific)`() {
|
|
57
|
+
assertNotNull(label.qrCode)
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Swift/XCTest
|
|
62
|
+
|
|
63
|
+
```swift
|
|
64
|
+
// fp:print_container_qr
|
|
65
|
+
func testPrintsQRCodeOntoContainerLabel() {
|
|
66
|
+
XCTAssertNotNil(label.qrCode)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// fp:print_container_qr@customer_ios
|
|
70
|
+
func testPrintsQRCodeOniOS() {
|
|
71
|
+
XCTAssertNotNil(label.qrCode)
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### TypeScript/Jest
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
// fp:print_container_qr
|
|
79
|
+
it('prints a QR code onto the container label', () => {
|
|
80
|
+
expect(label.qrCode).toBeDefined();
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// fp:print_container_qr@web
|
|
84
|
+
it('prints a QR code (web-specific)', () => {
|
|
85
|
+
expect(label.qrCode).toBeDefined();
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Python/pytest
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
# fp:print_container_qr
|
|
93
|
+
def test_prints_qr_code_onto_container_label():
|
|
94
|
+
assert label.qr_code is not None
|
|
95
|
+
|
|
96
|
+
# fp:print_container_qr@api
|
|
97
|
+
def test_prints_qr_code_api():
|
|
98
|
+
assert label.qr_code is not None
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Go
|
|
102
|
+
|
|
103
|
+
```go
|
|
104
|
+
// fp:print_container_qr
|
|
105
|
+
func TestPrintsQRCodeOntoContainerLabel(t *testing.T) {
|
|
106
|
+
if label.QRCode == nil {
|
|
107
|
+
t.Fatal("expected QR code")
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// fp:print_container_qr@api
|
|
112
|
+
func TestPrintsQRCodeAPI(t *testing.T) {
|
|
113
|
+
if label.QRCode == nil {
|
|
114
|
+
t.Fatal("expected QR code")
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Rules
|
|
120
|
+
|
|
121
|
+
1. **One marker per test.** A marker binds to the test directly below it.
|
|
122
|
+
|
|
123
|
+
2. **Human-readable test names.** The marker handles binding; don't name tests after slugs.
|
|
124
|
+
- ❌ `it 'print_container_qr' do`
|
|
125
|
+
- ✅ `it 'prints a QR code onto the container label' do`
|
|
126
|
+
|
|
127
|
+
3. **Marker must be immediately before the test.** No blank lines or other code between the marker comment and the test definition.
|
|
128
|
+
|
|
129
|
+
4. **Comment style follows language conventions.** Use `#` for Ruby/Python, `//` for Kotlin/Swift/TypeScript/Go.
|
|
130
|
+
|
|
131
|
+
## Verification
|
|
132
|
+
|
|
133
|
+
After adding a marker, verify it's findable:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
grep -r "fp:print_container_qr" spec/
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## JUnit binding
|
|
140
|
+
|
|
141
|
+
When using `fp report --junit`, the CLI:
|
|
142
|
+
|
|
143
|
+
1. Parses the JUnit XML report
|
|
144
|
+
2. For each `<testcase>`, reads the `file` attribute to find the source file
|
|
145
|
+
3. Scans the source file for `fp:<slug>` markers
|
|
146
|
+
4. Binds each marker to the test directly below it
|
|
147
|
+
5. Reports evidence for each binding
|
|
148
|
+
|
|
149
|
+
Testcases without a marker are skipped with a warning. Markers with unknown slugs are also skipped.
|
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.
|
|
4
|
+
version: 0.0.3
|
|
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
|
+
date: 2026-09-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: net-http
|
|
@@ -95,6 +95,7 @@ files:
|
|
|
95
95
|
- lib/fp/client.rb
|
|
96
96
|
- lib/fp/commands.rb
|
|
97
97
|
- lib/fp/commands/base.rb
|
|
98
|
+
- lib/fp/commands/config_cmd.rb
|
|
98
99
|
- lib/fp/commands/help.rb
|
|
99
100
|
- lib/fp/commands/list.rb
|
|
100
101
|
- lib/fp/commands/matrix.rb
|
|
@@ -102,13 +103,18 @@ files:
|
|
|
102
103
|
- lib/fp/commands/projects.rb
|
|
103
104
|
- lib/fp/commands/propose.rb
|
|
104
105
|
- lib/fp/commands/report.rb
|
|
106
|
+
- lib/fp/commands/repos.rb
|
|
105
107
|
- lib/fp/commands/setup.rb
|
|
106
108
|
- lib/fp/commands/show.rb
|
|
107
109
|
- lib/fp/commands/surfaces.rb
|
|
108
110
|
- lib/fp/commands/version.rb
|
|
109
111
|
- lib/fp/config.rb
|
|
112
|
+
- lib/fp/junit.rb
|
|
110
113
|
- lib/fp/output.rb
|
|
111
114
|
- lib/fp/version.rb
|
|
115
|
+
- skills/fp/SKILL.md
|
|
116
|
+
- skills/fp/references/cli.md
|
|
117
|
+
- skills/fp/references/markers.md
|
|
112
118
|
homepage: https://featureparity.dev
|
|
113
119
|
licenses:
|
|
114
120
|
- MIT
|