@nivora/matrix 0.1.0 → 0.2.0

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 (74) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +3 -3
  3. package/.next/build-manifest.json +2 -2
  4. package/.next/prerender-manifest.json +3 -3
  5. package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  6. package/.next/server/app/_global-error.html +2 -2
  7. package/.next/server/app/_global-error.rsc +1 -1
  8. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  9. package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  10. package/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  12. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  13. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  14. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  15. package/.next/server/app/_not-found.html +1 -1
  16. package/.next/server/app/_not-found.rsc +1 -1
  17. package/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  18. package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  19. package/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  20. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  21. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  22. package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  23. package/.next/server/app/builder/page.js +11 -11
  24. package/.next/server/app/builder/page.js.nft.json +1 -1
  25. package/.next/server/app/builder/page_client-reference-manifest.js +1 -1
  26. package/.next/server/app/guide/page.js.nft.json +1 -1
  27. package/.next/server/app/guide/page_client-reference-manifest.js +1 -1
  28. package/.next/server/app/matrix/page.js.nft.json +1 -1
  29. package/.next/server/app/matrix/page_client-reference-manifest.js +1 -1
  30. package/.next/server/app/page.js.nft.json +1 -1
  31. package/.next/server/app/page_client-reference-manifest.js +1 -1
  32. package/.next/server/app/releases/[id]/page.js +16 -16
  33. package/.next/server/app/releases/[id]/page.js.nft.json +1 -1
  34. package/.next/server/app/releases/[id]/page_client-reference-manifest.js +1 -1
  35. package/.next/server/app/releases/page.js +3 -3
  36. package/.next/server/app/releases/page.js.nft.json +1 -1
  37. package/.next/server/app/releases/page_client-reference-manifest.js +1 -1
  38. package/.next/server/app/specs/[id]/page.js +2 -2
  39. package/.next/server/app/specs/[id]/page.js.nft.json +1 -1
  40. package/.next/server/app/specs/[id]/page_client-reference-manifest.js +1 -1
  41. package/.next/server/app-paths-manifest.json +3 -3
  42. package/.next/server/chunks/135.js +1 -1
  43. package/.next/server/chunks/530.js +1 -1
  44. package/.next/server/pages/404.html +1 -1
  45. package/.next/server/pages/500.html +2 -2
  46. package/.next/server/server-reference-manifest.js +1 -1
  47. package/.next/server/server-reference-manifest.json +1 -1
  48. package/.next/static/chunks/app/builder/{page-e10754eb65a4f784.js → page-29ef0d9ec753466c.js} +3 -3
  49. package/.next/static/chunks/app/releases/[id]/page-467d1893a4442eed.js +1 -0
  50. package/.next/static/chunks/app/releases/page-6fc2e948b934fbb5.js +1 -0
  51. package/.next/static/chunks/app/specs/[id]/page-b5f2c99269d194c4.js +1 -0
  52. package/README.md +220 -134
  53. package/bin/cli.js +37 -20
  54. package/bin/cli.ts +12 -12
  55. package/package.json +7 -2
  56. package/.next/diagnostics/build-diagnostics.json +0 -6
  57. package/.next/diagnostics/framework.json +0 -1
  58. package/.next/static/chunks/app/releases/[id]/page-d8069a1802686478.js +0 -1
  59. package/.next/static/chunks/app/releases/page-26a520d9789e69f5.js +0 -1
  60. package/.next/static/chunks/app/specs/[id]/page-7065af5d4d103f16.js +0 -1
  61. package/.next/trace-build +0 -1
  62. package/.next/types/app/builder/page.ts +0 -86
  63. package/.next/types/app/guide/page.ts +0 -86
  64. package/.next/types/app/layout.ts +0 -86
  65. package/.next/types/app/matrix/page.ts +0 -86
  66. package/.next/types/app/page.ts +0 -86
  67. package/.next/types/app/releases/[id]/page.ts +0 -86
  68. package/.next/types/app/releases/page.ts +0 -86
  69. package/.next/types/app/specs/[id]/page.ts +0 -86
  70. package/.next/types/package.json +0 -1
  71. package/.next/types/routes.d.ts +0 -63
  72. package/.next/types/validator.ts +0 -115
  73. /package/.next/static/{8ZUFcYHRSRlY1FYWZ33gH → p01ytei1EF9z6WCg6Sbk1}/_buildManifest.js +0 -0
  74. /package/.next/static/{8ZUFcYHRSRlY1FYWZ33gH → p01ytei1EF9z6WCg6Sbk1}/_ssgManifest.js +0 -0
package/README.md CHANGED
@@ -1,35 +1,78 @@
1
- # GAMP 5 V-Model Traceability System
1
+ # Matrix - GAMP 5 Traceability System
2
2
 
3
- A streamlined requirements traceability and test management system designed for regulated environments, using **Gherkin as the source of truth** for Functional Specifications.
3
+ A **spec-as-code** requirements traceability system for regulated environments. Write Gherkin specs, run them as tests, and maintain automatic audit-ready traceability.
4
4
 
5
- 📚 **Documentation**:
6
- - [**User Guide**](./USER_GUIDE.md): How to use the dashboard and CLI.
7
- - [**Developer Guide**](./DEVELOPER_GUIDE.md): Architecture, setup, and development workflow.
8
- - [**Philosophy & Approach**](./GAMP_AND_V_MODEL.md): GAMP 5 principles, V-Model, and "Spec-as-Code" reasoning.
5
+ ## Quickstart
9
6
 
7
+ ```bash
8
+ bun add @nivora/matrix
9
+ bunx matrix init
10
+ bunx matrix serve
11
+ ```
12
+
13
+ Dashboard available at: http://localhost:3000
10
14
 
11
- ## Data Model
15
+ ---
12
16
 
13
- This system uses a **relational model** with 3 artifact types and no duplicate data:
17
+ ## Core Concepts
14
18
 
15
- | Artifact | Format | Location | Purpose |
16
- |----------|--------|----------|---------|
17
- | **URS** | Database | SQLite Table `urs` | High-level business requirements |
18
- | **FS** | Gherkin | `specs/fs/*.requirement` | Functional specs + embedded test scenarios |
19
- | **RISK** | Database | SQLite Table `risks` | Risk assessments linked to FS |
19
+ This system implements **GAMP 5** and **V-Model** compliance by making specifications executable:
20
20
 
21
- ### Key Insight: Gherkin IS the Functional Specification
21
+ | Artifact | Storage | Purpose |
22
+ |----------|---------|---------|
23
+ | **URS** | SQLite DB | High-level business requirements |
24
+ | **FS** | Gherkin `.requirement` files | Functional specs + test scenarios |
25
+ | **Risk** | SQLite DB | Risk assessments & mitigations |
26
+ | **Release** | SQLite DB | Version management & test results |
22
27
 
23
- Instead of maintaining separate FS documents and test files, we use Gherkin Feature files AS the functional specification:
28
+ **Key Insight**: The Gherkin Feature file IS the Functional Spec AND the test. No duplication.
24
29
 
25
30
  ```gherkin
26
31
  @URS-001 @RISK-001
27
- Feature: FS-001 User Login Authentication
28
- The system shall provide a login interface that authenticates users
29
- against stored credentials and establishes a secure session.
32
+ Feature: FS-001 User Login
33
+ The system shall authenticate users against stored credentials.
34
+
35
+ Scenario: Successful login
36
+ Given I am on the login page
37
+ When I enter valid credentials
38
+ Then I should see my dashboard
39
+ ```
40
+
41
+ ---
42
+
43
+ ## Workflow
44
+
45
+ ### 1. Create User Requirements (URS)
46
+
47
+ **Option A: Dashboard UI**
48
+ 1. Navigate to http://localhost:3000/specs
49
+ 2. Click "New Specification"
50
+ 3. Fill in Title, Business Need, Acceptance Criteria
51
+ 4. Save
52
+
53
+ **Option B: Stub Generation (Recommended)**
54
+
55
+ Reference URS IDs in your Gherkin files before they exist:
56
+
57
+ ```gherkin
58
+ @URS-011
59
+ Feature: FS-009 Password Reset
60
+ ```
61
+
62
+ Run `matrix sync` and the system creates a placeholder `URS-011` record. Fill in details via the dashboard later.
63
+
64
+ ### 2. Write Functional Specs (FS)
65
+
66
+ Create `.requirement` files in `specs/fs/`:
67
+
68
+ ```gherkin
69
+ @URS-001 @URS-002 @RISK-005
70
+ Feature: FS-001 User Authentication
71
+ The system shall authenticate users against stored credentials
72
+ and establish a secure session.
30
73
 
31
74
  Requirements:
32
- - FR-001.1: Display login form with email and password fields
75
+ - FR-001.1: Display login form with email and password
33
76
  - FR-001.2: Validate credentials against stored hash
34
77
  - FR-001.3: Rate limit after 5 failed attempts
35
78
 
@@ -37,149 +80,192 @@ Feature: FS-001 User Login Authentication
37
80
  Given I am on the login page
38
81
  When I enter valid credentials
39
82
  Then I should be redirected to my dashboard
83
+
84
+ Scenario: Failed login locks account after 5 attempts
85
+ Given I have failed login 4 times
86
+ When I enter invalid credentials
87
+ Then I should see "Account locked"
40
88
  ```
41
89
 
42
- **Benefits:**
43
- - **No duplication**: The Feature description IS the spec, scenarios ARE the tests
44
- - **Single source of truth**: Edit one file, both spec and tests are updated
45
- - **Clear traceability**: `@URS-xxx` and `@RISK-xxx` tags create automatic links
46
- - **Executable specs**: The `.requirement` files can be run by Cucumber
90
+ **Linking Tags:**
91
+ - `@URS-xxx` Links to User Requirement
92
+ - `@RISK-xxx` Links to Risk Assessment
47
93
 
48
- ## Directory Structure
94
+ ### 3. Create Risk Assessments
49
95
 
50
- ```
51
- docs/
52
- ├── specs/
53
- │ └── fs/ # Functional Specs (Gherkin)
54
- │ ├── FS-001-login.requirement
55
- │ ├── FS-002-session.requirement
56
- │ ├── FS-003-registration.requirement
57
- │ ├── FS-004-booking.requirement
58
- │ ├── FS-005-waitlist.requirement
59
- │ ├── FS-006-schedule.requirement
60
- │ └── FS-007-instructor.requirement
61
- └── src/ # Next.js Dashboard
62
- ```
96
+ **Option A: Dashboard UI** — Same flow as URS
63
97
 
64
- ## Linking Artifacts
98
+ **Option B: Stub Generation** — Reference `@RISK-xxx` in Gherkin, run sync, fill in details later
65
99
 
66
- ### URS to FS
67
- Use `@URS-xxx` tag in the Gherkin Feature:
68
- ```gherkin
69
- @URS-001
70
- Feature: FS-001 User Login
100
+ ### 4. Sync to Database
101
+
102
+ ```bash
103
+ matrix sync
71
104
  ```
72
105
 
73
- ### FS to Risk
74
- Use `@RISK-xxx` tag in the Gherkin Feature:
75
- ```gherkin
76
- @URS-001 @RISK-001
77
- Feature: FS-001 User Login
106
+ **What sync does:**
107
+ 1. Parses all `.requirement` files in `specs/fs/`
108
+ 2. Updates database with Feature titles, descriptions, and scenarios
109
+ 3. Extracts `@URS` and `@RISK` tags
110
+ 4. Auto-creates stub records for any referenced IDs that don't exist
111
+
112
+ > **Tip:** Write Gherkin first with new IDs, run sync, then fill in URS/Risk details via the dashboard.
113
+
114
+ ---
115
+
116
+ ## Release Management
117
+
118
+ ### 1. Create a Release
119
+
120
+ ```bash
121
+ matrix release create -v 1.0.0 -n "MVP Launch" --notes "Initial release"
78
122
  ```
79
123
 
80
- ### Verification Levels (V-Model)
81
- - **URS** Verified by **PQ** (Performance Qualification)
82
- - **FS** Verified by **OQ** (Operational Qualification)
83
- - **Scenarios** Verified by **IQ** (Installation Qualification)
124
+ Creates a release with:
125
+ - **Version**: Semantic version (e.g., 1.0.0)
126
+ - **Name**: Human-readable name
127
+ - **Status**: Defaults to "planning"
128
+ - **Notes**: Optional release notes
84
129
 
85
- ## Running the Dashboard
130
+ ### 2. Tag Features to Release
86
131
 
87
132
  ```bash
88
- cd docs
89
- bun install
90
- bun run dev
133
+ matrix release tag REL-001 --fs FS-001 FS-002 FS-003
91
134
  ```
92
135
 
93
- Access at: http://localhost:3000
136
+ ### 3. Run Tests
94
137
 
95
- ## Dashboard Pages
138
+ Execute Cucumber tests and export results:
96
139
 
97
- | Page | Description |
98
- |------|-------------|
99
- | `/` | Dashboard with stats, coverage, and traceability summary |
100
- | `/specs` | Browse URS (YAML), FS (Gherkin), and Risk (YAML) |
101
- | `/matrix` | Full traceability matrix: URS → FS → Scenarios → Risks |
102
- | `/builder` | Visual editor for creating new FS .requirement files |
103
- | `/search` | Search across all artifacts |
104
-
105
- ## Creating New Artifacts
106
-
107
- ### New URS (via Dashboard or manually)
108
- Create `specs/urs/URS-xxx.yaml`:
109
- ```yaml
110
- id: URS-004
111
- type: urs
112
- title: New Business Requirement
113
- status: draft
114
- priority: high
115
- owner: Product Team
116
- category: Core
117
- business_need: |
118
- Description of the business need...
119
- intended_use: |
120
- How the system will be used...
121
- acceptance_criteria:
122
- - Criterion 1
123
- - Criterion 2
124
- regulatory_refs:
125
- - GAMP 5
140
+ ```bash
141
+ npx cucumber-js specs/fs/**/*.requirement --format json:results.json
126
142
  ```
127
143
 
128
- ### New FS (via Builder or manually)
129
- Create `specs/fs/FS-xxx-name.requirement`:
130
- ```gherkin
131
- @URS-xxx @RISK-xxx
132
- Feature: FS-xxx Feature Title
133
- The system shall...
134
-
135
- Requirements:
136
- - FR-xxx.1: First requirement
137
- - FR-xxx.2: Second requirement
144
+ ### 4. Import Test Results
145
+
146
+ ```bash
147
+ matrix release import-results results.json --releaseId REL-001
148
+ ```
149
+
150
+ Or use the test command:
138
151
 
139
- Scenario: Test case 1
140
- Given ...
141
- When ...
142
- Then ...
152
+ ```bash
153
+ matrix test import results.json -r REL-001
143
154
  ```
144
155
 
145
- ### New Risk (manually)
146
- Create `specs/risk/RISK-xxx.yaml`:
147
- ```yaml
148
- id: RISK-004
149
- type: risk
150
- title: Risk Title
151
- status: draft
152
- category: Security
153
- gamp_category: 4
154
- fs_ids:
155
- - FS-001
156
- impact: high
157
- probability: medium
158
- risk_level: high
159
- risks:
160
- - id: R-004.1
161
- description: Risk description
162
- impact: high
163
- probability: medium
164
- mitigations:
165
- - risk_id: R-004.1
166
- control: Control measure
167
- test: How to test
168
- residual_risk: acceptable
156
+ The import process:
157
+ - Creates a test run record
158
+ - Stores individual scenario results (pass/fail)
159
+ - Warns if any tests failed
160
+ - Updates release status to "testing"
161
+
162
+ ### 5. View Test Results
163
+
164
+ ```bash
165
+ matrix test list REL-001
169
166
  ```
170
167
 
171
- ## Running Tests
168
+ ### 6. Handle Test Failures
169
+
170
+ If tests fail, you have two GAMP-compliant options:
171
+
172
+ **Option A: Fix the Code**
173
+ 1. Fix the failing functionality
174
+ 2. Re-run tests
175
+ 3. Import the new results
176
+
177
+ **Option B: Log a Defect/Deviation**
178
+ 1. Go to Release Detail page: `http://localhost:3000/releases/REL-001`
179
+ 2. Find the **Defects & Deviations** section
180
+ 3. Click **Log Defect** for the failing scenario
181
+ 4. Provide:
182
+ - **Description**: What failed and why
183
+ - **Justification**: Why it's acceptable (workaround exists, low impact, etc.)
184
+ - **Status**: Open, Investigating, Resolved, or Accepted
172
185
 
173
- The `.requirement` files are standard Gherkin and can be executed with Cucumber:
186
+ > [!IMPORTANT]
187
+ > You cannot mark a release as "Released" if it has failing tests without corresponding Defect records.
188
+
189
+ ### 7. Update Release Status
174
190
 
175
191
  ```bash
176
- # Configure cucumber to find .requirement files
177
- npx cucumber-js specs/fs/**/*.requirement
192
+ # Move to testing phase
193
+ matrix release status REL-001 --status testing
194
+
195
+ # Mark as released (requires all tests pass or defects logged)
196
+ matrix release status REL-001 --status released
178
197
  ```
179
198
 
199
+ ### 8. List All Releases
200
+
201
+ ```bash
202
+ matrix release list
203
+ ```
204
+
205
+ ---
206
+
207
+ ## CLI Reference
208
+
209
+ ### Core Commands
210
+
211
+ | Command | Description |
212
+ |---------|-------------|
213
+ | `matrix init` | Initialize a new specs directory |
214
+ | `matrix serve` | Start the dashboard server |
215
+ | `matrix sync` | Parse `.requirement` files and update database |
216
+ | `matrix search <query>` | Semantic search across specs |
217
+
218
+ ### Release Commands
219
+
220
+ | Command | Description |
221
+ |---------|-------------|
222
+ | `matrix release list` | List all releases |
223
+ | `matrix release create` | Create a new release |
224
+ | `matrix release tag <id>` | Tag FS records to a release |
225
+ | `matrix release status <id>` | Update release status |
226
+ | `matrix release import-results <file>` | Import Cucumber JSON results |
227
+
228
+ ### Test Commands
229
+
230
+ | Command | Description |
231
+ |---------|-------------|
232
+ | `matrix test import <file> -r <releaseId>` | Import Cucumber JSON results |
233
+ | `matrix test list <releaseId>` | List test runs for a release |
234
+
235
+ ### Common Options
236
+
237
+ | Option | Description |
238
+ |--------|-------------|
239
+ | `-p, --port <port>` | Port for serve (default: 3000) |
240
+ | `-s, --specs <dir>` | Specs directory (default: ./specs) |
241
+ | `-d, --db <path>` | Database path (default: ./matrix.db) |
242
+
243
+ ---
244
+
245
+ ## Dashboard Pages
246
+
247
+ | Page | URL | Description |
248
+ |------|-----|-------------|
249
+ | Home | `/` | Stats, coverage, and traceability overview |
250
+ | Specs | `/specs` | Browse and edit URS, FS, and Risks |
251
+ | Matrix | `/matrix` | Full traceability matrix: URS → FS → Scenarios → Risks |
252
+ | Releases | `/releases` | Release management and test results |
253
+ | Builder | `/builder` | Visual editor for creating FS files |
254
+ | Search | `/search` | Search across all artifacts |
255
+
256
+ ---
257
+
180
258
  ## GAMP 5 Compliance
181
259
 
182
- - **Category 4**: Configured products (authentication, session management)
183
- - **Category 5**: Custom applications (booking transactions)
184
- - **21 CFR Part 11**: Electronic records and signatures ready
185
- - **ALCOA+**: Data integrity principles for booking records
260
+ - **V-Model Integration**: FS files serve as both specification (FS) and test protocol (OQ)
261
+ - **Risk-Based Testing**: `@RISK-xxx` tags prioritize validation effort
262
+ - **Automatic Traceability**: Tag-based linking generates audit-ready matrices
263
+ - **Defect Management**: Failed tests require formal deviation records before release
264
+ - **21 CFR Part 11 Ready**: Full audit trail of changes and test results
265
+
266
+ ---
267
+
268
+ ## Additional Documentation
269
+
270
+ - [Developer Guide](./DEVELOPER_GUIDE.md) - Architecture and development setup
271
+ - [GAMP & V-Model Philosophy](./GAMP_AND_V_MODEL.md) - Design rationale
package/bin/cli.js CHANGED
@@ -2142,7 +2142,7 @@ function getDbPath() {
2142
2142
  if (process.env.MACHINE_DB_PATH) {
2143
2143
  return process.env.MACHINE_DB_PATH;
2144
2144
  }
2145
- return join3(process.cwd(), "machine.db");
2145
+ return join3(process.cwd(), "matrix.db");
2146
2146
  }
2147
2147
  function getDb() {
2148
2148
  if (!db) {
@@ -3133,7 +3133,7 @@ import { existsSync, readFileSync } from "fs";
3133
3133
  import { join, resolve } from "path";
3134
3134
  var DEFAULT_CONFIG = {
3135
3135
  specsDir: "./specs",
3136
- dbPath: "./machine.db",
3136
+ dbPath: "./matrix.db",
3137
3137
  port: 3000,
3138
3138
  rootDir: process.cwd()
3139
3139
  };
@@ -3204,13 +3204,30 @@ async function serveCommand(config) {
3204
3204
  };
3205
3205
  const packageRoot = join2(__dirname2, "..", "..");
3206
3206
  const hasProductionBuild = existsSync2(join2(packageRoot, ".next", "BUILD_ID"));
3207
- const script = hasProductionBuild ? "start" : "dev";
3208
- const runtime = hasBun() ? "bun" : "npm";
3209
- spawn(runtime, ["run", script], {
3210
- cwd: packageRoot,
3211
- env,
3212
- stdio: "inherit"
3213
- });
3207
+ if (hasProductionBuild) {
3208
+ const nextBin = join2(packageRoot, "node_modules", ".bin", "next");
3209
+ const useLocalNext = existsSync2(nextBin);
3210
+ if (useLocalNext) {
3211
+ spawn(nextBin, ["start", "-p", String(config.port)], {
3212
+ cwd: packageRoot,
3213
+ env,
3214
+ stdio: "inherit"
3215
+ });
3216
+ } else {
3217
+ spawn("npx", ["next", "start", "-p", String(config.port)], {
3218
+ cwd: packageRoot,
3219
+ env,
3220
+ stdio: "inherit"
3221
+ });
3222
+ }
3223
+ } else {
3224
+ const runtime = hasBun() ? "bun" : "npm";
3225
+ spawn(runtime, ["run", "dev"], {
3226
+ cwd: packageRoot,
3227
+ env,
3228
+ stdio: "inherit"
3229
+ });
3230
+ }
3214
3231
  }
3215
3232
 
3216
3233
  // src/commands/sync.ts
@@ -3220,7 +3237,7 @@ import { join as join4 } from "path";
3220
3237
  // src/config.ts
3221
3238
  var DEFAULT_CONFIG2 = {
3222
3239
  specsDir: "./specs",
3223
- dbPath: "./machine.db",
3240
+ dbPath: "./matrix.db",
3224
3241
  port: 3000,
3225
3242
  rootDir: process.cwd()
3226
3243
  };
@@ -3585,7 +3602,7 @@ async function testCommand(config, action, options) {
3585
3602
  // bin/cli.ts
3586
3603
  var program2 = new Command;
3587
3604
  program2.name("machine").description("Requirements documentation system with semantic search").version("0.1.0");
3588
- program2.command("serve").description("Start the documentation server").option("-p, --port <port>", "Port to run server on", "3000").option("-s, --specs <dir>", "Specs directory", "./specs").option("-d, --db <path>", "Database path", "./machine.db").action(async (options) => {
3605
+ program2.command("serve").description("Start the documentation server").option("-p, --port <port>", "Port to run server on", "3000").option("-s, --specs <dir>", "Specs directory", "./specs").option("-d, --db <path>", "Database path", "./matrix.db").action(async (options) => {
3589
3606
  const config = await loadConfig({
3590
3607
  port: parseInt(options.port, 10),
3591
3608
  specsDir: options.specs,
@@ -3593,7 +3610,7 @@ program2.command("serve").description("Start the documentation server").option("
3593
3610
  });
3594
3611
  await serveCommand(config);
3595
3612
  });
3596
- program2.command("sync").description("Sync FS files to database and index steps").option("-s, --specs <dir>", "Specs directory", "./specs").option("-d, --db <path>", "Database path", "./machine.db").action(async (options) => {
3613
+ program2.command("sync").description("Sync FS files to database and index steps").option("-s, --specs <dir>", "Specs directory", "./specs").option("-d, --db <path>", "Database path", "./matrix.db").action(async (options) => {
3597
3614
  const config = await loadConfig({
3598
3615
  specsDir: options.specs,
3599
3616
  dbPath: options.db
@@ -3606,7 +3623,7 @@ program2.command("init").description("Initialize a new specs directory").option(
3606
3623
  });
3607
3624
  await initCommand(config);
3608
3625
  });
3609
- program2.command("search <query>").description("Semantic search for steps").option("-n, --limit <n>", "Number of results", "10").option("-s, --specs <dir>", "Specs directory", "./specs").option("-d, --db <path>", "Database path", "./machine.db").action(async (query, options) => {
3626
+ program2.command("search <query>").description("Semantic search for steps").option("-n, --limit <n>", "Number of results", "10").option("-s, --specs <dir>", "Specs directory", "./specs").option("-d, --db <path>", "Database path", "./matrix.db").action(async (query, options) => {
3610
3627
  const config = await loadConfig({
3611
3628
  specsDir: options.specs,
3612
3629
  dbPath: options.db
@@ -3614,11 +3631,11 @@ program2.command("search <query>").description("Semantic search for steps").opti
3614
3631
  await searchCommand(config, query, parseInt(options.limit, 10));
3615
3632
  });
3616
3633
  var release = program2.command("release").description("Manage releases");
3617
- release.command("list").description("List all releases").option("-d, --db <path>", "Database path", "./machine.db").action(async (options) => {
3634
+ release.command("list").description("List all releases").option("-d, --db <path>", "Database path", "./matrix.db").action(async (options) => {
3618
3635
  const config = await loadConfig({ dbPath: options.db });
3619
3636
  await releaseCommand(config, "list");
3620
3637
  });
3621
- release.command("create").description("Create a new release").requiredOption("-v, --version <version>", "Release version (e.g., 1.0.0)").requiredOption("-n, --name <name>", "Release name").option("--notes <notes>", "Release notes").option("-d, --db <path>", "Database path", "./machine.db").action(async (options) => {
3638
+ release.command("create").description("Create a new release").requiredOption("-v, --version <version>", "Release version (e.g., 1.0.0)").requiredOption("-n, --name <name>", "Release name").option("--notes <notes>", "Release notes").option("-d, --db <path>", "Database path", "./matrix.db").action(async (options) => {
3622
3639
  const config = await loadConfig({ dbPath: options.db });
3623
3640
  await releaseCommand(config, "create", {
3624
3641
  version: options.version,
@@ -3626,24 +3643,24 @@ release.command("create").description("Create a new release").requiredOption("-v
3626
3643
  notes: options.notes
3627
3644
  });
3628
3645
  });
3629
- release.command("tag <releaseId>").description("Tag features to a release").requiredOption("--fs <fsIds...>", "FS IDs to tag").option("-d, --db <path>", "Database path", "./machine.db").action(async (releaseId, options) => {
3646
+ release.command("tag <releaseId>").description("Tag features to a release").requiredOption("--fs <fsIds...>", "FS IDs to tag").option("-d, --db <path>", "Database path", "./matrix.db").action(async (releaseId, options) => {
3630
3647
  const config = await loadConfig({ dbPath: options.db });
3631
3648
  await releaseCommand(config, "tag", { releaseId, fsIds: options.fs });
3632
3649
  });
3633
- release.command("status <releaseId>").description("Update release status").requiredOption("--status <status>", "New status (planning|testing|released)").option("-d, --db <path>", "Database path", "./machine.db").action(async (releaseId, options) => {
3650
+ release.command("status <releaseId>").description("Update release status").requiredOption("--status <status>", "New status (planning|testing|released)").option("-d, --db <path>", "Database path", "./matrix.db").action(async (releaseId, options) => {
3634
3651
  const config = await loadConfig({ dbPath: options.db });
3635
3652
  await releaseCommand(config, "status", { releaseId, status: options.status });
3636
3653
  });
3637
- release.command("import-results <file>").description("Import Cucumber JSON results into a release").requiredOption("--releaseId <id>", "Release ID").option("-d, --db <path>", "Database path", "./machine.db").action(async (file, options) => {
3654
+ release.command("import-results <file>").description("Import Cucumber JSON results into a release").requiredOption("--releaseId <id>", "Release ID").option("-d, --db <path>", "Database path", "./matrix.db").action(async (file, options) => {
3638
3655
  const config = await loadConfig({ dbPath: options.db });
3639
3656
  await importResultsCommand(config, file, { releaseId: options.releaseId });
3640
3657
  });
3641
3658
  var test = program2.command("test").description("Manage test results");
3642
- test.command("import <jsonPath>").description("Import Cucumber JSON test results").requiredOption("-r, --release <releaseId>", "Release ID").option("-d, --db <path>", "Database path", "./machine.db").action(async (jsonPath, options) => {
3659
+ test.command("import <jsonPath>").description("Import Cucumber JSON test results").requiredOption("-r, --release <releaseId>", "Release ID").option("-d, --db <path>", "Database path", "./matrix.db").action(async (jsonPath, options) => {
3643
3660
  const config = await loadConfig({ dbPath: options.db });
3644
3661
  await testCommand(config, "import", { releaseId: options.release, jsonPath });
3645
3662
  });
3646
- test.command("list <releaseId>").description("List test runs for a release").option("-d, --db <path>", "Database path", "./machine.db").action(async (releaseId, options) => {
3663
+ test.command("list <releaseId>").description("List test runs for a release").option("-d, --db <path>", "Database path", "./matrix.db").action(async (releaseId, options) => {
3647
3664
  const config = await loadConfig({ dbPath: options.db });
3648
3665
  await testCommand(config, "list", { releaseId });
3649
3666
  });
package/bin/cli.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env bun
2
2
  /**
3
- * @nivora/machine CLI
3
+ * @nivora/matrix CLI
4
4
  *
5
5
  * Commands:
6
6
  * serve - Start the documentation server
@@ -25,7 +25,7 @@ import { testCommand } from '../src/commands/test';
25
25
  const program = new Command();
26
26
 
27
27
  program
28
- .name('machine')
28
+ .name('matrix')
29
29
  .description('Requirements documentation system with semantic search')
30
30
  .version('0.1.0');
31
31
 
@@ -34,7 +34,7 @@ program
34
34
  .description('Start the documentation server')
35
35
  .option('-p, --port <port>', 'Port to run server on', '3000')
36
36
  .option('-s, --specs <dir>', 'Specs directory', './specs')
37
- .option('-d, --db <path>', 'Database path', './machine.db')
37
+ .option('-d, --db <path>', 'Database path', './matrix.db')
38
38
  .action(async (options) => {
39
39
  const config = await loadConfig({
40
40
  port: parseInt(options.port, 10),
@@ -48,7 +48,7 @@ program
48
48
  .command('sync')
49
49
  .description('Sync FS files to database and index steps')
50
50
  .option('-s, --specs <dir>', 'Specs directory', './specs')
51
- .option('-d, --db <path>', 'Database path', './machine.db')
51
+ .option('-d, --db <path>', 'Database path', './matrix.db')
52
52
  .action(async (options) => {
53
53
  const config = await loadConfig({
54
54
  specsDir: options.specs,
@@ -73,7 +73,7 @@ program
73
73
  .description('Semantic search for steps')
74
74
  .option('-n, --limit <n>', 'Number of results', '10')
75
75
  .option('-s, --specs <dir>', 'Specs directory', './specs')
76
- .option('-d, --db <path>', 'Database path', './machine.db')
76
+ .option('-d, --db <path>', 'Database path', './matrix.db')
77
77
  .action(async (query, options) => {
78
78
  const config = await loadConfig({
79
79
  specsDir: options.specs,
@@ -90,7 +90,7 @@ const release = program
90
90
  release
91
91
  .command('list')
92
92
  .description('List all releases')
93
- .option('-d, --db <path>', 'Database path', './machine.db')
93
+ .option('-d, --db <path>', 'Database path', './matrix.db')
94
94
  .action(async (options) => {
95
95
  const config = await loadConfig({ dbPath: options.db });
96
96
  await releaseCommand(config, 'list');
@@ -102,7 +102,7 @@ release
102
102
  .requiredOption('-v, --version <version>', 'Release version (e.g., 1.0.0)')
103
103
  .requiredOption('-n, --name <name>', 'Release name')
104
104
  .option('--notes <notes>', 'Release notes')
105
- .option('-d, --db <path>', 'Database path', './machine.db')
105
+ .option('-d, --db <path>', 'Database path', './matrix.db')
106
106
  .action(async (options) => {
107
107
  const config = await loadConfig({ dbPath: options.db });
108
108
  await releaseCommand(config, 'create', {
@@ -116,7 +116,7 @@ release
116
116
  .command('tag <releaseId>')
117
117
  .description('Tag features to a release')
118
118
  .requiredOption('--fs <fsIds...>', 'FS IDs to tag')
119
- .option('-d, --db <path>', 'Database path', './machine.db')
119
+ .option('-d, --db <path>', 'Database path', './matrix.db')
120
120
  .action(async (releaseId, options) => {
121
121
  const config = await loadConfig({ dbPath: options.db });
122
122
  await releaseCommand(config, 'tag', { releaseId, fsIds: options.fs });
@@ -126,7 +126,7 @@ release
126
126
  .command('status <releaseId>')
127
127
  .description('Update release status')
128
128
  .requiredOption('--status <status>', 'New status (planning|testing|released)')
129
- .option('-d, --db <path>', 'Database path', './machine.db')
129
+ .option('-d, --db <path>', 'Database path', './matrix.db')
130
130
  .action(async (releaseId, options) => {
131
131
  const config = await loadConfig({ dbPath: options.db });
132
132
  await releaseCommand(config, 'status', { releaseId, status: options.status });
@@ -136,7 +136,7 @@ release
136
136
  .command('import-results <file>')
137
137
  .description('Import Cucumber JSON results into a release')
138
138
  .requiredOption('--releaseId <id>', 'Release ID')
139
- .option('-d, --db <path>', 'Database path', './machine.db')
139
+ .option('-d, --db <path>', 'Database path', './matrix.db')
140
140
  .action(async (file, options) => {
141
141
  const config = await loadConfig({ dbPath: options.db });
142
142
  await importResultsCommand(config, file, { releaseId: options.releaseId });
@@ -152,7 +152,7 @@ test
152
152
  .command('import <jsonPath>')
153
153
  .description('Import Cucumber JSON test results')
154
154
  .requiredOption('-r, --release <releaseId>', 'Release ID')
155
- .option('-d, --db <path>', 'Database path', './machine.db')
155
+ .option('-d, --db <path>', 'Database path', './matrix.db')
156
156
  .action(async (jsonPath, options) => {
157
157
  const config = await loadConfig({ dbPath: options.db });
158
158
  await testCommand(config, 'import', { releaseId: options.release, jsonPath });
@@ -161,7 +161,7 @@ test
161
161
  test
162
162
  .command('list <releaseId>')
163
163
  .description('List test runs for a release')
164
- .option('-d, --db <path>', 'Database path', './machine.db')
164
+ .option('-d, --db <path>', 'Database path', './matrix.db')
165
165
  .action(async (releaseId, options) => {
166
166
  const config = await loadConfig({ dbPath: options.db });
167
167
  await testCommand(config, 'list', { releaseId });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nivora/matrix",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Requirements documentation system with semantic search",
5
5
  "type": "module",
6
6
  "bin": {
@@ -12,7 +12,12 @@
12
12
  "files": [
13
13
  "bin",
14
14
  "dist",
15
- ".next",
15
+ ".next/*.json",
16
+ ".next/*.js",
17
+ ".next/BUILD_ID",
18
+ ".next/package.json",
19
+ ".next/server",
20
+ ".next/static",
16
21
  "public",
17
22
  "next.config.ts"
18
23
  ],