@nivora/matrix 0.1.1 → 0.2.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.
- package/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +4 -4
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +3 -3
- package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_global-error.html +2 -2
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +1 -1
- package/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/builder/page.js +11 -11
- package/.next/server/app/builder/page.js.nft.json +1 -1
- package/.next/server/app/builder/page_client-reference-manifest.js +1 -1
- package/.next/server/app/guide/page.js.nft.json +1 -1
- package/.next/server/app/guide/page_client-reference-manifest.js +1 -1
- package/.next/server/app/matrix/page.js.nft.json +1 -1
- package/.next/server/app/matrix/page_client-reference-manifest.js +1 -1
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/releases/[id]/page.js +16 -16
- package/.next/server/app/releases/[id]/page.js.nft.json +1 -1
- package/.next/server/app/releases/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/releases/page.js +3 -3
- package/.next/server/app/releases/page.js.nft.json +1 -1
- package/.next/server/app/releases/page_client-reference-manifest.js +1 -1
- package/.next/server/app/specs/[id]/page.js +2 -2
- package/.next/server/app/specs/[id]/page.js.nft.json +1 -1
- package/.next/server/app/specs/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +4 -4
- package/.next/server/chunks/135.js +1 -1
- package/.next/server/chunks/530.js +1 -1
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +2 -2
- package/.next/server/server-reference-manifest.js +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/app/builder/{page-e0a24ae820fa2c06.js → page-e8eb2c5950ee1495.js} +3 -3
- package/.next/static/chunks/app/releases/[id]/page-f13257c6f0e69a7c.js +1 -0
- package/.next/static/chunks/app/releases/{page-fc527101f56b36c5.js → page-050bb308276e178c.js} +1 -1
- package/.next/static/chunks/app/specs/[id]/page-a1e2672e95d4c9c6.js +1 -0
- package/bin/cli.js +82 -42
- package/bin/cli.ts +12 -12
- package/package.json +7 -2
- package/.next/diagnostics/build-diagnostics.json +0 -6
- package/.next/diagnostics/framework.json +0 -1
- package/.next/static/chunks/app/releases/[id]/page-ea66642a6a557b42.js +0 -1
- package/.next/static/chunks/app/specs/[id]/page-49293bb634997108.js +0 -1
- package/.next/trace +0 -11
- package/.next/trace-build +0 -1
- package/.next/types/app/builder/page.ts +0 -86
- package/.next/types/app/guide/page.ts +0 -86
- package/.next/types/app/layout.ts +0 -86
- package/.next/types/app/matrix/page.ts +0 -86
- package/.next/types/app/page.ts +0 -86
- package/.next/types/app/releases/[id]/page.ts +0 -86
- package/.next/types/app/releases/page.ts +0 -86
- package/.next/types/app/specs/[id]/page.ts +0 -86
- package/.next/types/package.json +0 -1
- package/.next/types/routes.d.ts +0 -63
- package/.next/types/validator.ts +0 -115
- /package/.next/static/{zmL75rl5Hq4TyiNVaXe8R → SmDoKluq2qozv2eyHXbUF}/_buildManifest.js +0 -0
- /package/.next/static/{zmL75rl5Hq4TyiNVaXe8R → SmDoKluq2qozv2eyHXbUF}/_ssgManifest.js +0 -0
package/bin/cli.js
CHANGED
|
@@ -2135,14 +2135,14 @@ __export(exports_database, {
|
|
|
2135
2135
|
closeDb: () => closeDb
|
|
2136
2136
|
});
|
|
2137
2137
|
import { Database } from "bun:sqlite";
|
|
2138
|
-
import { existsSync as existsSync3, readFileSync as
|
|
2138
|
+
import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
|
|
2139
2139
|
import { join as join3, dirname as dirname2 } from "path";
|
|
2140
2140
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2141
2141
|
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(), "
|
|
2145
|
+
return join3(process.cwd(), "matrix.db");
|
|
2146
2146
|
}
|
|
2147
2147
|
function getDb() {
|
|
2148
2148
|
if (!db) {
|
|
@@ -2156,8 +2156,8 @@ function getDb() {
|
|
|
2156
2156
|
function initDatabase() {
|
|
2157
2157
|
if (!db)
|
|
2158
2158
|
return;
|
|
2159
|
-
const schemaPath = join3(
|
|
2160
|
-
const schema =
|
|
2159
|
+
const schemaPath = join3(__dirname2, "schema.sql");
|
|
2160
|
+
const schema = readFileSync3(schemaPath, "utf-8");
|
|
2161
2161
|
db.exec(schema);
|
|
2162
2162
|
}
|
|
2163
2163
|
function closeDb() {
|
|
@@ -2192,9 +2192,9 @@ function getSpecsDir() {
|
|
|
2192
2192
|
}
|
|
2193
2193
|
return join3(process.cwd(), "specs");
|
|
2194
2194
|
}
|
|
2195
|
-
var
|
|
2195
|
+
var __dirname2, db = null;
|
|
2196
2196
|
var init_database = __esm(() => {
|
|
2197
|
-
|
|
2197
|
+
__dirname2 = dirname2(fileURLToPath2(import.meta.url));
|
|
2198
2198
|
});
|
|
2199
2199
|
|
|
2200
2200
|
// src/lib/database/fs-repo.ts
|
|
@@ -3008,7 +3008,7 @@ __export(exports_test_repo, {
|
|
|
3008
3008
|
deleteTestRun: () => deleteTestRun,
|
|
3009
3009
|
createTestRun: () => createTestRun
|
|
3010
3010
|
});
|
|
3011
|
-
import { readFileSync as
|
|
3011
|
+
import { readFileSync as readFileSync5 } from "fs";
|
|
3012
3012
|
function loadTestRuns(releaseId) {
|
|
3013
3013
|
const db2 = getDb();
|
|
3014
3014
|
return db2.query(`
|
|
@@ -3048,7 +3048,7 @@ function createTestRun(releaseId, results) {
|
|
|
3048
3048
|
return loadTestRuns(releaseId).find((r) => r.id === runId);
|
|
3049
3049
|
}
|
|
3050
3050
|
function importCucumberResults(releaseId, jsonPath) {
|
|
3051
|
-
const content =
|
|
3051
|
+
const content = readFileSync5(jsonPath, "utf-8");
|
|
3052
3052
|
const cucumberData = JSON.parse(content);
|
|
3053
3053
|
const results = [];
|
|
3054
3054
|
for (const feature of cucumberData) {
|
|
@@ -3133,13 +3133,13 @@ import { existsSync, readFileSync } from "fs";
|
|
|
3133
3133
|
import { join, resolve } from "path";
|
|
3134
3134
|
var DEFAULT_CONFIG = {
|
|
3135
3135
|
specsDir: "./specs",
|
|
3136
|
-
dbPath: "./
|
|
3136
|
+
dbPath: "./matrix.db",
|
|
3137
3137
|
port: 3000,
|
|
3138
3138
|
rootDir: process.cwd()
|
|
3139
3139
|
};
|
|
3140
3140
|
var cachedConfig = null;
|
|
3141
3141
|
async function loadConfigFile(rootDir) {
|
|
3142
|
-
const configPath = join(rootDir, "
|
|
3142
|
+
const configPath = join(rootDir, "matrix.config.ts");
|
|
3143
3143
|
if (!existsSync(configPath)) {
|
|
3144
3144
|
return {};
|
|
3145
3145
|
}
|
|
@@ -3158,7 +3158,7 @@ function loadPackageJsonConfig(rootDir) {
|
|
|
3158
3158
|
}
|
|
3159
3159
|
try {
|
|
3160
3160
|
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
3161
|
-
return pkg.
|
|
3161
|
+
return pkg.matrix || {};
|
|
3162
3162
|
} catch {
|
|
3163
3163
|
return {};
|
|
3164
3164
|
}
|
|
@@ -3184,14 +3184,38 @@ async function loadConfig(cliOptions = {}) {
|
|
|
3184
3184
|
import { spawn, spawnSync } from "child_process";
|
|
3185
3185
|
import { join as join2, dirname } from "path";
|
|
3186
3186
|
import { fileURLToPath } from "url";
|
|
3187
|
-
import { existsSync as existsSync2 } from "fs";
|
|
3188
|
-
|
|
3187
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
3188
|
+
function findPackageRoot() {
|
|
3189
|
+
const currentFile = fileURLToPath(import.meta.url);
|
|
3190
|
+
let dir = dirname(currentFile);
|
|
3191
|
+
for (let i = 0;i < 10; i++) {
|
|
3192
|
+
if (existsSync2(join2(dir, ".next", "BUILD_ID"))) {
|
|
3193
|
+
return dir;
|
|
3194
|
+
}
|
|
3195
|
+
const pkgPath = join2(dir, "package.json");
|
|
3196
|
+
if (existsSync2(pkgPath)) {
|
|
3197
|
+
try {
|
|
3198
|
+
const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
|
|
3199
|
+
if (pkg.name === "@nivora/matrix") {
|
|
3200
|
+
return dir;
|
|
3201
|
+
}
|
|
3202
|
+
} catch {}
|
|
3203
|
+
}
|
|
3204
|
+
const parent = dirname(dir);
|
|
3205
|
+
if (parent === dir)
|
|
3206
|
+
break;
|
|
3207
|
+
dir = parent;
|
|
3208
|
+
}
|
|
3209
|
+
return dirname(dirname(currentFile));
|
|
3210
|
+
}
|
|
3189
3211
|
function hasBun() {
|
|
3190
3212
|
const result = spawnSync("bun", ["--version"], { stdio: "ignore" });
|
|
3191
3213
|
return result.status === 0;
|
|
3192
3214
|
}
|
|
3193
3215
|
async function serveCommand(config) {
|
|
3194
|
-
|
|
3216
|
+
const packageRoot = findPackageRoot();
|
|
3217
|
+
console.log("\uD83D\uDE80 Starting @nivora/matrix server...");
|
|
3218
|
+
console.log(` Package: ${packageRoot}`);
|
|
3195
3219
|
console.log(` Specs: ${config.specsDir}`);
|
|
3196
3220
|
console.log(` Database: ${config.dbPath}`);
|
|
3197
3221
|
console.log(` Port: ${config.port}`);
|
|
@@ -3202,25 +3226,41 @@ async function serveCommand(config) {
|
|
|
3202
3226
|
MACHINE_DB_PATH: config.dbPath,
|
|
3203
3227
|
PORT: String(config.port)
|
|
3204
3228
|
};
|
|
3205
|
-
const packageRoot = join2(__dirname2, "..", "..");
|
|
3206
3229
|
const hasProductionBuild = existsSync2(join2(packageRoot, ".next", "BUILD_ID"));
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3230
|
+
if (hasProductionBuild) {
|
|
3231
|
+
const nextBin = join2(packageRoot, "node_modules", ".bin", "next");
|
|
3232
|
+
const useLocalNext = existsSync2(nextBin);
|
|
3233
|
+
if (useLocalNext) {
|
|
3234
|
+
spawn(nextBin, ["start", "-p", String(config.port)], {
|
|
3235
|
+
cwd: packageRoot,
|
|
3236
|
+
env,
|
|
3237
|
+
stdio: "inherit"
|
|
3238
|
+
});
|
|
3239
|
+
} else {
|
|
3240
|
+
spawn("npx", ["next", "start", "-p", String(config.port)], {
|
|
3241
|
+
cwd: packageRoot,
|
|
3242
|
+
env,
|
|
3243
|
+
stdio: "inherit"
|
|
3244
|
+
});
|
|
3245
|
+
}
|
|
3246
|
+
} else {
|
|
3247
|
+
const runtime = hasBun() ? "bun" : "npm";
|
|
3248
|
+
spawn(runtime, ["run", "dev"], {
|
|
3249
|
+
cwd: packageRoot,
|
|
3250
|
+
env,
|
|
3251
|
+
stdio: "inherit"
|
|
3252
|
+
});
|
|
3253
|
+
}
|
|
3214
3254
|
}
|
|
3215
3255
|
|
|
3216
3256
|
// src/commands/sync.ts
|
|
3217
|
-
import { existsSync as existsSync4, readFileSync as
|
|
3257
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4, readdirSync } from "fs";
|
|
3218
3258
|
import { join as join4 } from "path";
|
|
3219
3259
|
|
|
3220
3260
|
// src/config.ts
|
|
3221
3261
|
var DEFAULT_CONFIG2 = {
|
|
3222
3262
|
specsDir: "./specs",
|
|
3223
|
-
dbPath: "./
|
|
3263
|
+
dbPath: "./matrix.db",
|
|
3224
3264
|
port: 3000,
|
|
3225
3265
|
rootDir: process.cwd()
|
|
3226
3266
|
};
|
|
@@ -3248,7 +3288,7 @@ async function syncCommand(config) {
|
|
|
3248
3288
|
const fsDir = join4(config.specsDir, "fs");
|
|
3249
3289
|
if (!existsSync4(fsDir)) {
|
|
3250
3290
|
console.log(`⚠ No fs/ directory found at ${fsDir}`);
|
|
3251
|
-
console.log(" Run `
|
|
3291
|
+
console.log(" Run `matrix init` to create the specs directory structure.");
|
|
3252
3292
|
closeDb2();
|
|
3253
3293
|
return;
|
|
3254
3294
|
}
|
|
@@ -3259,7 +3299,7 @@ async function syncCommand(config) {
|
|
|
3259
3299
|
const referencedRisks = new Set;
|
|
3260
3300
|
for (const file of fsFiles) {
|
|
3261
3301
|
const filePath = join4(fsDir, file);
|
|
3262
|
-
const content =
|
|
3302
|
+
const content = readFileSync4(filePath, "utf-8");
|
|
3263
3303
|
const fsData = parseGherkinFS2(content, filePath);
|
|
3264
3304
|
syncFS2(fsData);
|
|
3265
3305
|
fsItems.push(fsData);
|
|
@@ -3365,8 +3405,8 @@ async function initCommand(config) {
|
|
|
3365
3405
|
console.log("");
|
|
3366
3406
|
console.log("Next steps:");
|
|
3367
3407
|
console.log(" 1. Edit specs/fs/*.requirement files");
|
|
3368
|
-
console.log(" 2. Run `
|
|
3369
|
-
console.log(" 3. Run `
|
|
3408
|
+
console.log(" 2. Run `matrix sync` to index files");
|
|
3409
|
+
console.log(" 3. Run `matrix serve` to start the UI");
|
|
3370
3410
|
}
|
|
3371
3411
|
|
|
3372
3412
|
// src/commands/search.ts
|
|
@@ -3412,7 +3452,7 @@ async function releaseCommand(config, action, options) {
|
|
|
3412
3452
|
case "list": {
|
|
3413
3453
|
const releases = loadAllReleases2();
|
|
3414
3454
|
if (releases.length === 0) {
|
|
3415
|
-
console.log('No releases found. Create one with:
|
|
3455
|
+
console.log('No releases found. Create one with: matrix release create -v 1.0.0 -n "My Release"');
|
|
3416
3456
|
return;
|
|
3417
3457
|
}
|
|
3418
3458
|
console.log(`\uD83D\uDCE6 Releases:
|
|
@@ -3475,7 +3515,7 @@ async function importResultsCommand(config, file, options) {
|
|
|
3475
3515
|
const { releaseId } = options;
|
|
3476
3516
|
if (!releaseId) {
|
|
3477
3517
|
console.error("❌ Error: --releaseId is required");
|
|
3478
|
-
console.log("Usage:
|
|
3518
|
+
console.log("Usage: matrix release import-results <file> --releaseId <id>");
|
|
3479
3519
|
process.exit(1);
|
|
3480
3520
|
}
|
|
3481
3521
|
const filePath = resolve2(process.cwd(), file);
|
|
@@ -3559,7 +3599,7 @@ async function testCommand(config, action, options) {
|
|
|
3559
3599
|
}
|
|
3560
3600
|
const runs = loadTestRuns2(releaseId);
|
|
3561
3601
|
if (runs.length === 0) {
|
|
3562
|
-
console.log(`No test runs for ${releaseId}. Import results with:
|
|
3602
|
+
console.log(`No test runs for ${releaseId}. Import results with: matrix test import ./results.json -r ${releaseId}`);
|
|
3563
3603
|
return;
|
|
3564
3604
|
}
|
|
3565
3605
|
console.log(`\uD83E\uDDEA Test runs for ${releaseId} v${release.version}:
|
|
@@ -3584,8 +3624,8 @@ async function testCommand(config, action, options) {
|
|
|
3584
3624
|
|
|
3585
3625
|
// bin/cli.ts
|
|
3586
3626
|
var program2 = new Command;
|
|
3587
|
-
program2.name("
|
|
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", "./
|
|
3627
|
+
program2.name("matrix").description("Requirements documentation system with semantic search").version("0.1.0");
|
|
3628
|
+
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
3629
|
const config = await loadConfig({
|
|
3590
3630
|
port: parseInt(options.port, 10),
|
|
3591
3631
|
specsDir: options.specs,
|
|
@@ -3593,7 +3633,7 @@ program2.command("serve").description("Start the documentation server").option("
|
|
|
3593
3633
|
});
|
|
3594
3634
|
await serveCommand(config);
|
|
3595
3635
|
});
|
|
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", "./
|
|
3636
|
+
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
3637
|
const config = await loadConfig({
|
|
3598
3638
|
specsDir: options.specs,
|
|
3599
3639
|
dbPath: options.db
|
|
@@ -3606,7 +3646,7 @@ program2.command("init").description("Initialize a new specs directory").option(
|
|
|
3606
3646
|
});
|
|
3607
3647
|
await initCommand(config);
|
|
3608
3648
|
});
|
|
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", "./
|
|
3649
|
+
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
3650
|
const config = await loadConfig({
|
|
3611
3651
|
specsDir: options.specs,
|
|
3612
3652
|
dbPath: options.db
|
|
@@ -3614,11 +3654,11 @@ program2.command("search <query>").description("Semantic search for steps").opti
|
|
|
3614
3654
|
await searchCommand(config, query, parseInt(options.limit, 10));
|
|
3615
3655
|
});
|
|
3616
3656
|
var release = program2.command("release").description("Manage releases");
|
|
3617
|
-
release.command("list").description("List all releases").option("-d, --db <path>", "Database path", "./
|
|
3657
|
+
release.command("list").description("List all releases").option("-d, --db <path>", "Database path", "./matrix.db").action(async (options) => {
|
|
3618
3658
|
const config = await loadConfig({ dbPath: options.db });
|
|
3619
3659
|
await releaseCommand(config, "list");
|
|
3620
3660
|
});
|
|
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", "./
|
|
3661
|
+
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
3662
|
const config = await loadConfig({ dbPath: options.db });
|
|
3623
3663
|
await releaseCommand(config, "create", {
|
|
3624
3664
|
version: options.version,
|
|
@@ -3626,24 +3666,24 @@ release.command("create").description("Create a new release").requiredOption("-v
|
|
|
3626
3666
|
notes: options.notes
|
|
3627
3667
|
});
|
|
3628
3668
|
});
|
|
3629
|
-
release.command("tag <releaseId>").description("Tag features to a release").requiredOption("--fs <fsIds...>", "FS IDs to tag").option("-d, --db <path>", "Database path", "./
|
|
3669
|
+
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
3670
|
const config = await loadConfig({ dbPath: options.db });
|
|
3631
3671
|
await releaseCommand(config, "tag", { releaseId, fsIds: options.fs });
|
|
3632
3672
|
});
|
|
3633
|
-
release.command("status <releaseId>").description("Update release status").requiredOption("--status <status>", "New status (planning|testing|released)").option("-d, --db <path>", "Database path", "./
|
|
3673
|
+
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
3674
|
const config = await loadConfig({ dbPath: options.db });
|
|
3635
3675
|
await releaseCommand(config, "status", { releaseId, status: options.status });
|
|
3636
3676
|
});
|
|
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", "./
|
|
3677
|
+
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
3678
|
const config = await loadConfig({ dbPath: options.db });
|
|
3639
3679
|
await importResultsCommand(config, file, { releaseId: options.releaseId });
|
|
3640
3680
|
});
|
|
3641
3681
|
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", "./
|
|
3682
|
+
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
3683
|
const config = await loadConfig({ dbPath: options.db });
|
|
3644
3684
|
await testCommand(config, "import", { releaseId: options.release, jsonPath });
|
|
3645
3685
|
});
|
|
3646
|
-
test.command("list <releaseId>").description("List test runs for a release").option("-d, --db <path>", "Database path", "./
|
|
3686
|
+
test.command("list <releaseId>").description("List test runs for a release").option("-d, --db <path>", "Database path", "./matrix.db").action(async (releaseId, options) => {
|
|
3647
3687
|
const config = await loadConfig({ dbPath: options.db });
|
|
3648
3688
|
await testCommand(config, "list", { releaseId });
|
|
3649
3689
|
});
|
package/bin/cli.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
/**
|
|
3
|
-
* @nivora/
|
|
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('
|
|
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', './
|
|
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', './
|
|
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', './
|
|
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', './
|
|
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', './
|
|
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', './
|
|
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', './
|
|
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', './
|
|
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', './
|
|
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', './
|
|
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.
|
|
3
|
+
"version": "0.2.1",
|
|
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
|
],
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"name":"Next.js","version":"16.1.1"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[41],{2463:(e,t,r)=>{"use strict";r.d(t,{ReleaseDetailClient:()=>h});var s=r(5155),i=r(2115),a=r(8500),l=r.n(a),n=r(9339);let o=(0,n.createServerReference)("605d227294f7347b07f597bdeb06346b065d7cb3b4",n.callServer,void 0,n.findSourceMapURL,"updateReleaseAction"),d=(0,n.createServerReference)("60349323a40d1f889ed65a65407fd61937888631f0",n.callServer,void 0,n.findSourceMapURL,"tagFSToReleaseAction"),c=(0,n.createServerReference)("600886c75927f7162206a66e82b10253be2b657f36",n.callServer,void 0,n.findSourceMapURL,"untagFSFromReleaseAction"),m=(0,n.createServerReference)("4071ca0ec8ef4365cbe46c411cf888db8018acf2ba",n.callServer,void 0,n.findSourceMapURL,"createDefectAction");function h({release:e,taggedFS:t,availableFS:r,testRuns:a,defects:n}){let[h,p]=(0,i.useState)(!1),[g,x]=(0,i.useState)(!1),[v,u]=(0,i.useState)([]),[y,j]=(0,i.useState)(null),[f,b]=(0,i.useState)({isOpen:!1}),[S,N]=(0,i.useState)({title:"",description:"",status:"open"}),[C,k]=(0,i.useState)({titleError:!1,descriptionError:!1}),[R,w]=(0,i.useTransition)(),[B,W]=(0,i.useState)({version:e.version,name:e.name,status:e.status,notes:e.notes||""}),_={planning:{bg:"rgba(168, 85, 247, 0.1)",color:"#a855f7"},testing:{bg:"rgba(59, 130, 246, 0.1)",color:"#3b82f6"},released:{bg:"rgba(34, 197, 94, 0.1)",color:"#22c55e"}}[e.status];return(0,s.jsxs)("div",{style:{maxWidth:"1200px",margin:"0 auto",padding:"2rem"},children:[(0,s.jsx)("div",{style:{marginBottom:"1.5rem"},children:(0,s.jsx)(l(),{href:"/releases",style:{color:"var(--text-secondary)",textDecoration:"none"},children:"← Back to Releases"})}),(0,s.jsxs)("header",{style:{marginBottom:"2rem"},children:[(0,s.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"1rem",marginBottom:"0.5rem"},children:[(0,s.jsxs)("code",{style:{fontSize:"1.5rem",fontWeight:700,color:_.color},children:[" ",e.id," "]}),(0,s.jsxs)("span",{style:{fontSize:"1.25rem",fontWeight:600},children:["v",e.version]}),(0,s.jsx)("span",{className:"badge",style:{background:_.bg,color:_.color,padding:"0.5rem 1rem"},children:e.status}),(0,s.jsx)("button",{onClick:()=>p(!h),className:"btn btn-primary",style:{marginLeft:"auto"},children:h?"Cancel":"✏️ Edit"})]}),(0,s.jsx)("h1",{style:{fontSize:"2rem",fontWeight:700},children:e.name}),(0,s.jsxs)("p",{style:{color:"var(--text-secondary)"},children:["Created ",e.created_at,e.released_at&&` • Released ${e.released_at}`]})]}),h&&(0,s.jsxs)("div",{className:"card",style:{marginBottom:"1.5rem"},children:[(0,s.jsx)("h2",{className:"card-title",children:"Edit Release"}),(0,s.jsxs)("div",{style:{display:"grid",gridTemplateColumns:"1fr 2fr 1fr",gap:"1rem",marginBottom:"1rem"},children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{style:{display:"block",fontWeight:500,marginBottom:"0.5rem"},children:"Version"}),(0,s.jsx)("input",{type:"text",value:B.version,onChange:e=>W({...B,version:e.target.value}),className:"input"})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{style:{display:"block",fontWeight:500,marginBottom:"0.5rem"},children:"Name"}),(0,s.jsx)("input",{type:"text",value:B.name,onChange:e=>W({...B,name:e.target.value}),className:"input"})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{style:{display:"block",fontWeight:500,marginBottom:"0.5rem"},children:"Status"}),(0,s.jsxs)("select",{value:B.status,onChange:e=>W({...B,status:e.target.value}),className:"input",children:[(0,s.jsx)("option",{value:"planning",children:"Planning"}),(0,s.jsx)("option",{value:"testing",children:"Testing"}),(0,s.jsx)("option",{value:"released",children:"Released"})]})]})]}),(0,s.jsxs)("div",{style:{marginBottom:"1rem"},children:[(0,s.jsx)("label",{style:{display:"block",fontWeight:500,marginBottom:"0.5rem"},children:"Notes"}),(0,s.jsx)("textarea",{value:B.notes,onChange:e=>W({...B,notes:e.target.value}),rows:3,className:"input",style:{resize:"vertical"}})]}),(0,s.jsx)("button",{onClick:()=>{w(async()=>{await o(e.id,B),p(!1)})},className:"btn btn-primary",disabled:R,children:R?"Saving...":"Save Changes"})]}),e.notes&&!h&&(0,s.jsxs)("div",{className:"card",style:{marginBottom:"1.5rem"},children:[(0,s.jsx)("h2",{className:"card-title",children:"\uD83D\uDCDD Notes"}),(0,s.jsx)("p",{style:{color:"var(--text-secondary)",whiteSpace:"pre-wrap"},children:e.notes})]}),(0,s.jsxs)("div",{className:"card",style:{marginBottom:"1.5rem",borderLeft:"4px solid var(--error)"},children:[(0,s.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"1rem"},children:[(0,s.jsxs)("h2",{className:"card-title",children:["\uD83D\uDEA8 Defects & Deviations (",n.length,")"]}),(0,s.jsx)("button",{className:"btn",onClick:()=>{b({isOpen:!0,testResultId:void 0,fsId:void 0,scenarioName:void 0}),N({title:"",description:"",status:"open"})},children:"+ Log Defect"})]}),0===n.length?(0,s.jsx)("p",{style:{color:"var(--text-secondary)"},children:"No defects logged. Any failed tests must be resolved or logged as a defect."}):(0,s.jsx)("div",{style:{display:"grid",gap:"0.75rem"},children:n.map(e=>(0,s.jsxs)("div",{style:{padding:"1rem",background:"var(--bg-hover)",borderRadius:"8px",borderLeft:"open"===e.status?"3px solid red":"3px solid green"},children:[(0,s.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",marginBottom:"0.5rem"},children:[(0,s.jsxs)("div",{style:{fontWeight:600},children:[e.id,": ",e.title]}),(0,s.jsx)("div",{className:"badge",style:{background:"open"===e.status?"rgba(239, 68, 68, 0.1)":"rgba(34, 197, 94, 0.1)",color:"open"===e.status?"var(--error)":"var(--success)"},children:e.status.toUpperCase()})]}),(0,s.jsx)("div",{style:{fontSize:"0.875rem",color:"var(--text-secondary)",whiteSpace:"pre-wrap"},children:e.description}),e.test_result_id&&(0,s.jsxs)("div",{style:{marginTop:"0.5rem",fontSize:"0.75rem",color:"var(--warning)"},children:["Linked to failed test result #",e.test_result_id]})]},e.id))})]}),(0,s.jsxs)("div",{className:"card",style:{marginBottom:"1.5rem"},children:[(0,s.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"1rem"},children:[(0,s.jsxs)("h2",{className:"card-title",style:{margin:0},children:["⚙️ Features (",t.length,")"]}),(0,s.jsx)("button",{onClick:()=>x(!0),className:"btn",disabled:0===r.length,children:"+ Add Features"})]}),g&&(0,s.jsxs)("div",{style:{marginBottom:"1rem",padding:"1rem",background:"var(--bg-hover)",borderRadius:"8px"},children:[(0,s.jsx)("div",{style:{marginBottom:"0.5rem",fontWeight:500},children:"Select features to add:"}),(0,s.jsx)("div",{style:{display:"flex",flexWrap:"wrap",gap:"0.5rem",marginBottom:"1rem"},children:r.map(e=>(0,s.jsxs)("label",{style:{display:"flex",alignItems:"center",gap:"0.5rem",cursor:"pointer"},children:[(0,s.jsx)("input",{type:"checkbox",checked:v.includes(e.id),onChange:t=>{t.target.checked?u([...v,e.id]):u(v.filter(t=>t!==e.id))}}),(0,s.jsx)("code",{style:{color:"var(--warning)"},children:e.id}),(0,s.jsx)("span",{children:e.title})]},e.id))}),(0,s.jsxs)("div",{style:{display:"flex",gap:"0.5rem"},children:[(0,s.jsx)("button",{onClick:()=>{x(!1),u([])},className:"btn",children:"Cancel"}),(0,s.jsx)("button",{onClick:()=>{0!==v.length&&w(async()=>{await d(e.id,v),x(!1),u([])})},className:"btn btn-primary",disabled:R||0===v.length,children:R?"Adding...":`Add ${v.length} Feature${1!==v.length?"s":""}`})]})]}),0===t.length?(0,s.jsx)("p",{style:{color:"var(--text-secondary)"},children:"No features tagged yet. Add features to track them in this release."}):(0,s.jsx)("div",{style:{display:"grid",gap:"0.5rem"},children:t.map(t=>(0,s.jsxs)("div",{style:{display:"flex",alignItems:"center",padding:"0.75rem 1rem",background:"var(--bg-hover)",borderRadius:"8px"},children:[(0,s.jsxs)(l(),{href:`/specs/${t.id}`,style:{flex:1,textDecoration:"none"},children:[(0,s.jsx)("code",{style:{fontWeight:600,color:"var(--warning)",marginRight:"0.75rem"},children:t.id}),(0,s.jsx)("span",{style:{color:"var(--text-primary)"},children:t.title}),(0,s.jsxs)("span",{style:{marginLeft:"0.75rem",color:"var(--text-secondary)",fontSize:"0.875rem"},children:[t.scenario_count," scenarios"]})]}),(0,s.jsx)("button",{onClick:()=>{var r;return r=t.id,void w(async()=>{await c(e.id,r)})},className:"btn",style:{padding:"0.25rem 0.5rem",fontSize:"0.75rem"},disabled:R,children:"\xd7"})]},t.id))})]}),(0,s.jsxs)("div",{className:"card",children:[(0,s.jsxs)("h2",{className:"card-title",children:["\uD83E\uDDEA Test Runs (",a.length,")"]}),0===a.length?(0,s.jsxs)("p",{style:{color:"var(--text-secondary)"},children:["No test runs yet. Import Cucumber results: ",(0,s.jsxs)("code",{children:["machine release import-results results.json -r ",e.id]})]}):(0,s.jsx)("div",{style:{display:"grid",gap:"0.75rem"},children:a.map(e=>{let t=e.total>0?e.passed/e.total*100:0,r=y===e.id;return(0,s.jsxs)("div",{style:{padding:"1rem",background:"var(--bg-hover)",borderRadius:"8px"},children:[(0,s.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",cursor:"pointer"},onClick:()=>j(r?null:e.id),children:[(0,s.jsxs)("div",{children:[(0,s.jsxs)("div",{style:{fontWeight:600,marginBottom:"0.25rem"},children:[e.failed>0?"❌":"✅"," Run #",e.id," ",r?"\uD83D\uDD3D":"▶"]}),(0,s.jsxs)("div",{style:{fontSize:"0.875rem",color:"var(--text-secondary)"},children:[e.run_date," • ",e.source]})]}),(0,s.jsxs)("div",{style:{display:"flex",gap:"1rem",textAlign:"center"},children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("div",{style:{fontWeight:700,color:"var(--success)"},children:e.passed}),(0,s.jsx)("div",{style:{fontSize:"0.75rem",color:"var(--text-secondary)"},children:"Passed"})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("div",{style:{fontWeight:700,color:"var(--error)"},children:e.failed}),(0,s.jsx)("div",{style:{fontSize:"0.75rem",color:"var(--text-secondary)"},children:"Failed"})]}),(0,s.jsxs)("div",{children:[(0,s.jsxs)("div",{style:{fontWeight:700,color:100===t?"var(--success)":t>=80?"var(--warning)":"var(--error)"},children:[t.toFixed(0),"%"]}),(0,s.jsx)("div",{style:{fontSize:"0.75rem",color:"var(--text-secondary)"},children:"Pass Rate"})]})]})]}),r&&(0,s.jsx)("div",{style:{marginTop:"1rem",paddingTop:"1rem",borderTop:"1px solid var(--border)"},children:(0,s.jsx)("p",{style:{fontStyle:"italic",color:"var(--text-secondary)"},children:"Detailed results view would go here. For now, check the console logs or database for failure details."})})]},e.id)})})]}),f.isOpen&&(0,s.jsx)("div",{style:{position:"fixed",top:0,left:0,right:0,bottom:0,background:"rgba(0,0,0,0.5)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:100},children:(0,s.jsxs)("div",{className:"card",style:{width:"500px",maxWidth:"90%"},children:[(0,s.jsx)("h2",{className:"card-title",children:"Log Defect / Deviation"}),(0,s.jsxs)("div",{style:{marginBottom:"1rem"},children:[(0,s.jsxs)("label",{style:{display:"block",marginBottom:"0.5rem"},children:["Title ",(0,s.jsx)("span",{style:{color:"var(--error)"},children:"*"})]}),(0,s.jsx)("input",{className:"input",value:S.title,onChange:e=>{N({...S,title:e.target.value}),e.target.value&&k(e=>({...e,titleError:!1}))},placeholder:"Defect summary",style:C.titleError?{borderColor:"var(--error)",boxShadow:"0 0 0 2px rgba(239, 68, 68, 0.2)"}:{}}),C.titleError&&(0,s.jsx)("div",{style:{color:"var(--error)",fontSize:"0.75rem",marginTop:"0.25rem"},children:"Title is required"})]}),(0,s.jsxs)("div",{style:{marginBottom:"1rem"},children:[(0,s.jsxs)("label",{style:{display:"block",marginBottom:"0.5rem"},children:["Description & Root Cause ",(0,s.jsx)("span",{style:{color:"var(--error)"},children:"*"})]}),(0,s.jsx)("textarea",{className:"input",rows:5,value:S.description,onChange:e=>{N({...S,description:e.target.value}),e.target.value&&k(e=>({...e,descriptionError:!1}))},placeholder:"Describe the failure, root cause, and why it is acceptable (if deviating) or mitigation plan.",style:C.descriptionError?{borderColor:"var(--error)",boxShadow:"0 0 0 2px rgba(239, 68, 68, 0.2)"}:{}}),C.descriptionError&&(0,s.jsx)("div",{style:{color:"var(--error)",fontSize:"0.75rem",marginTop:"0.25rem"},children:"Description is required"})]}),(0,s.jsxs)("div",{style:{marginBottom:"1rem"},children:[(0,s.jsx)("label",{style:{display:"block",marginBottom:"0.5rem"},children:"Status"}),(0,s.jsxs)("select",{className:"input",value:S.status,onChange:e=>N({...S,status:e.target.value}),children:[(0,s.jsx)("option",{value:"open",children:"Open (Needs Fix)"}),(0,s.jsx)("option",{value:"resolved",children:"Resolved (Fixed)"}),(0,s.jsx)("option",{value:"accepted",children:"Accepted (Permanent Deviation)"})]})]}),(0,s.jsxs)("div",{style:{display:"flex",gap:"0.5rem",justifyContent:"flex-end"},children:[(0,s.jsx)("button",{className:"btn",onClick:()=>{b({isOpen:!1}),k({titleError:!1,descriptionError:!1})},children:"Cancel"}),(0,s.jsx)("button",{className:"btn btn-primary",onClick:()=>{let t=!S.title.trim(),r=!S.description.trim();t||r?k({titleError:t,descriptionError:r}):w(async()=>{try{await m({releaseId:e.id,testResultId:f.testResultId,title:S.title,description:S.description,status:S.status}),b({isOpen:!1}),N({title:"",description:"",status:"open"})}catch(e){console.error("Failed to create defect:",e),alert("Failed to create defect. Check console for details.")}})},disabled:R,children:R?"Logging...":"Log Defect"})]})]})})]})}},4926:(e,t,r)=>{Promise.resolve().then(r.bind(r,2463))},9339:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var s={callServer:function(){return a.callServer},createServerReference:function(){return n.createServerReference},findSourceMapURL:function(){return l.findSourceMapURL}};for(var i in s)Object.defineProperty(t,i,{enumerable:!0,get:s[i]});let a=r(7304),l=r(4060),n=r(7197)}},e=>{e.O(0,[500,441,794,358],()=>e(e.s=4926)),_N_E=e.O()}]);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[385],{4839:(e,t,a)=>{"use strict";a.d(t,{RiskDetailClient:()=>d});var r=a(5155),i=a(2115),s=a(8500),l=a.n(s),n=a(9339);let c=(0,n.createServerReference)("605ab5a9e6bcfd5272e605b0b0bd7b2c90ce4d2856",n.callServer,void 0,n.findSourceMapURL,"updateRiskAction");function d({risk:e,linkedFS:t}){let[a,s]=(0,i.useState)(!1),[n,d]=(0,i.useTransition)(),[m,h]=(0,i.useState)({title:e.title,status:e.status,category:e.category,impact:e.impact,probability:e.probability,risk_level:e.risk_level,residual_risk:e.residual_risk}),u=e.title.includes("(Undefined)");return(0,r.jsxs)("div",{children:[(0,r.jsxs)("header",{className:"page-header",children:[(0,r.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"1rem",marginBottom:"0.5rem",flexWrap:"wrap"},children:[(0,r.jsx)("code",{style:{fontSize:"1.5rem",fontWeight:700,color:"#f97316",background:"rgba(249, 115, 22, 0.1)",padding:"0.5rem 1rem",borderRadius:"8px"},children:e.id}),a?(0,r.jsx)(({value:e,onChange:t,options:i})=>a?(0,r.jsx)("select",{value:e,onChange:e=>t(e.target.value),className:"input",children:i.map(e=>(0,r.jsx)("option",{value:e.value,children:e.label},e.value))}):(0,r.jsx)("span",{style:{textTransform:"capitalize"},children:e}),{value:m.status,onChange:e=>h({...m,status:e}),options:[{value:"draft",label:"Draft"},{value:"review",label:"Review"},{value:"approved",label:"Approved"}]}):(0,r.jsx)("span",{className:`badge ${"approved"===e.status?"badge-success":"badge-warning"}`,children:m.status}),(0,r.jsx)(p,{level:m.risk_level}),u&&!a&&(0,r.jsx)("span",{className:"badge",style:{background:"rgba(239, 68, 68, 0.2)",color:"var(--error)"},children:"Needs Definition"}),(0,r.jsx)("div",{style:{marginLeft:"auto",display:"flex",gap:"0.5rem"},children:a?(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("button",{onClick:()=>{h({title:e.title,status:e.status,category:e.category,impact:e.impact,probability:e.probability,risk_level:e.risk_level,residual_risk:e.residual_risk}),s(!1)},className:"btn",disabled:n,children:"Cancel"}),(0,r.jsx)("button",{onClick:()=>{d(async()=>{await c(e.id,m),s(!1)})},className:"btn btn-primary",disabled:n,children:n?"Saving...":"\uD83D\uDCBE Save"})]}):(0,r.jsx)("button",{onClick:()=>s(!0),className:"btn btn-primary",children:"✏️ Edit"})})]}),a?(0,r.jsx)("input",{type:"text",value:m.title,onChange:e=>h({...m,title:e.target.value}),className:"input",style:{fontSize:"1.5rem",fontWeight:700,width:"100%",marginBottom:"0.5rem"}}):(0,r.jsx)("h1",{className:"page-title",children:m.title}),(0,r.jsxs)("p",{className:"page-subtitle",children:["Risk Assessment • Category: ",a?(0,r.jsx)("input",{type:"text",value:m.category,onChange:e=>h({...m,category:e.target.value}),className:"input",style:{width:"200px",display:"inline-block"}}):m.category," • GAMP Category ",e.gamp_category]})]}),u&&!a&&(0,r.jsx)("div",{className:"card",style:{marginBottom:"1.5rem",background:"rgba(239, 68, 68, 0.1)",borderLeft:"4px solid var(--error)"},children:(0,r.jsxs)("p",{style:{margin:0,color:"var(--error)"},children:["⚠️ This Risk was auto-created from FS references. Click ",(0,r.jsx)("strong",{children:"Edit"})," to define its details."]})}),(0,r.jsx)("div",{className:"card",style:{marginBottom:"1.5rem"},children:(0,r.jsxs)("div",{style:{display:"grid",gridTemplateColumns:"repeat(4, 1fr)",gap:"1rem"},children:[(0,r.jsx)(o,{label:"Impact",value:m.impact,isEditing:a,onChange:e=>h({...m,impact:e}),options:["low","medium","high","critical"]}),(0,r.jsx)(o,{label:"Probability",value:m.probability,isEditing:a,onChange:e=>h({...m,probability:e}),options:["low","medium","high"]}),(0,r.jsx)(o,{label:"Risk Level",value:m.risk_level,isEditing:a,onChange:e=>h({...m,risk_level:e}),options:["low","medium","high","critical"]}),(0,r.jsx)(o,{label:"Residual Risk",value:m.residual_risk,isEditing:a,onChange:e=>h({...m,residual_risk:e}),options:["acceptable","unacceptable","pending"]})]})}),(0,r.jsxs)("div",{className:"card",style:{marginBottom:"1.5rem"},children:[(0,r.jsx)("h2",{className:"card-title",children:"⚙️ Linked Functional Specifications"}),(0,r.jsx)("div",{style:{display:"flex",gap:"0.5rem",flexWrap:"wrap"},children:t.map(e=>(0,r.jsx)(l(),{href:`/specs/${e.id}`,children:(0,r.jsxs)("span",{className:"badge",style:{background:"rgba(245, 158, 11, 0.15)",color:"var(--warning)",padding:"0.5rem 1rem"},children:[e.id," - ",e.title]})},e.id))})]}),(0,r.jsxs)("div",{className:"card",style:{marginBottom:"1.5rem"},children:[(0,r.jsx)("h2",{className:"card-title",children:"\uD83D\uDD34 Identified Risks"}),0===e.risks.length?(0,r.jsx)("p",{style:{color:"var(--text-secondary)",fontStyle:"italic"},children:"No risks defined yet"}):(0,r.jsx)("div",{style:{display:"grid",gap:"0.5rem"},children:e.risks.map((e,t)=>(0,r.jsxs)("div",{style:{padding:"0.75rem 1rem",background:"var(--bg-hover)",borderRadius:"6px",display:"flex",alignItems:"center",gap:"1rem"},children:[(0,r.jsx)("code",{style:{fontWeight:600,color:"#f97316"},children:e.id}),(0,r.jsx)("span",{style:{flex:1,color:"var(--text-secondary)"},children:e.description}),(0,r.jsx)(p,{level:e.impact,small:!0})]},t))})]}),(0,r.jsxs)("div",{className:"card",children:[(0,r.jsx)("h2",{className:"card-title",children:"\uD83D\uDEE1️ Mitigations"}),0===e.mitigations.length?(0,r.jsx)("p",{style:{color:"var(--text-secondary)",fontStyle:"italic"},children:"No mitigations defined yet"}):(0,r.jsxs)("table",{className:"table",children:[(0,r.jsx)("thead",{children:(0,r.jsxs)("tr",{children:[(0,r.jsx)("th",{children:"Risk"}),(0,r.jsx)("th",{children:"Control"}),(0,r.jsx)("th",{children:"Test"})]})}),(0,r.jsx)("tbody",{children:e.mitigations.map((e,t)=>(0,r.jsxs)("tr",{children:[(0,r.jsx)("td",{children:(0,r.jsx)("code",{children:e.risk_id})}),(0,r.jsx)("td",{children:e.control}),(0,r.jsx)("td",{style:{color:"var(--text-secondary)"},children:e.test})]},t))})]})]})]})}function o({label:e,value:t,isEditing:a,onChange:i,options:s}){let l=m(t);return(0,r.jsxs)("div",{style:{textAlign:"center",padding:"1rem",background:"var(--bg-hover)",borderRadius:"8px"},children:[(0,r.jsx)("div",{style:{fontSize:"0.75rem",color:"var(--text-secondary)",marginBottom:"0.25rem"},children:e}),a?(0,r.jsx)("select",{value:t,onChange:e=>i(e.target.value),className:"input",style:{width:"100%",textAlign:"center"},children:s.map(e=>(0,r.jsx)("option",{value:e,style:{textTransform:"capitalize"},children:e},e))}):(0,r.jsx)("div",{style:{fontSize:"1.25rem",fontWeight:700,color:l,textTransform:"capitalize"},children:t})]})}function p({level:e,small:t}){let a=m(e);return(0,r.jsx)("span",{className:"badge",style:{background:`${a}20`,color:a,padding:t?"0.25rem 0.5rem":"0.5rem 1rem",fontSize:t?"0.75rem":"0.875rem",textTransform:"capitalize"},children:e})}function m(e){switch(e){case"critical":case"unacceptable":return"#dc2626";case"high":return"#f97316";case"medium":case"pending":return"#eab308";case"low":case"acceptable":return"#22c55e";default:return"var(--text-secondary)"}}},6161:(e,t,a)=>{"use strict";a.d(t,{URSDetailClient:()=>d});var r=a(5155),i=a(2115),s=a(8500),l=a.n(s),n=a(9339);let c=(0,n.createServerReference)("60e0719d8381c7cf2a369b814653fb6e2b5ef7f3c2",n.callServer,void 0,n.findSourceMapURL,"updateURSAction");function d({urs:e,linkedFS:t,linkedRisks:a}){let[s,n]=(0,i.useState)(!1),[d,p]=(0,i.useTransition)(),[m,h]=(0,i.useState)({title:e.title,status:e.status,priority:e.priority,owner:e.owner,category:e.category,business_need:e.business_need,intended_use:e.intended_use,acceptance_criteria:e.acceptance_criteria}),u=e.title.includes("(Undefined)"),g=({value:e,onChange:t,multiline:a,placeholder:i})=>s?a?(0,r.jsx)("textarea",{value:e,onChange:e=>t(e.target.value),rows:4,className:"input",style:{width:"100%",resize:"vertical"}}):(0,r.jsx)("input",{type:"text",value:e,onChange:e=>t(e.target.value),className:"input",style:{width:"100%"}}):(0,r.jsx)("span",{style:{whiteSpace:"pre-wrap",color:"var(--text-secondary)",fontStyle:e?"normal":"italic"},children:e||i||"Not defined"}),x=({value:e,onChange:t,options:a})=>s?(0,r.jsx)("select",{value:e,onChange:e=>t(e.target.value),className:"input",children:a.map(e=>(0,r.jsx)("option",{value:e.value,children:e.label},e.value))}):(0,r.jsx)("span",{style:{textTransform:"capitalize"},children:e});return(0,r.jsxs)("div",{children:[(0,r.jsxs)("header",{className:"page-header",children:[(0,r.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"1rem",marginBottom:"0.5rem",flexWrap:"wrap"},children:[(0,r.jsx)("code",{style:{fontSize:"1.5rem",fontWeight:700,color:"var(--success)",background:"rgba(16, 185, 129, 0.1)",padding:"0.5rem 1rem",borderRadius:"8px"},children:e.id}),s?(0,r.jsx)(x,{value:m.status,onChange:e=>h({...m,status:e}),options:[{value:"draft",label:"Draft"},{value:"review",label:"Review"},{value:"approved",label:"Approved"}]}):(0,r.jsx)("span",{className:`badge ${"approved"===e.status?"badge-success":"badge-warning"}`,children:m.status}),s?(0,r.jsx)(x,{value:m.priority,onChange:e=>h({...m,priority:e}),options:[{value:"critical",label:"Critical"},{value:"high",label:"High"},{value:"medium",label:"Medium"},{value:"low",label:"Low"}]}):(0,r.jsx)("span",{className:"badge",style:{background:"var(--bg-hover)"},children:m.priority}),u&&!s&&(0,r.jsx)("span",{className:"badge",style:{background:"rgba(239, 68, 68, 0.2)",color:"var(--error)"},children:"Needs Definition"}),(0,r.jsx)("div",{style:{marginLeft:"auto",display:"flex",gap:"0.5rem"},children:s?(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("button",{onClick:()=>{h({title:e.title,status:e.status,priority:e.priority,owner:e.owner,category:e.category,business_need:e.business_need,intended_use:e.intended_use,acceptance_criteria:e.acceptance_criteria}),n(!1)},className:"btn",disabled:d,children:"Cancel"}),(0,r.jsx)("button",{onClick:()=>{p(async()=>{await c(e.id,m),n(!1)})},className:"btn btn-primary",disabled:d,children:d?"Saving...":"\uD83D\uDCBE Save"})]}):(0,r.jsx)("button",{onClick:()=>n(!0),className:"btn btn-primary",children:"✏️ Edit"})})]}),s?(0,r.jsx)("input",{type:"text",value:m.title,onChange:e=>h({...m,title:e.target.value}),className:"input",style:{fontSize:"1.5rem",fontWeight:700,width:"100%",marginBottom:"0.5rem"}}):(0,r.jsx)("h1",{className:"page-title",children:m.title}),(0,r.jsxs)("p",{className:"page-subtitle",children:["User Requirement Specification • Owner: ",s?(0,r.jsx)("input",{type:"text",value:m.owner,onChange:e=>h({...m,owner:e.target.value}),className:"input",style:{width:"200px",display:"inline-block"}}):m.owner]})]}),u&&!s&&(0,r.jsx)("div",{className:"card",style:{marginBottom:"1.5rem",background:"rgba(239, 68, 68, 0.1)",borderLeft:"4px solid var(--error)"},children:(0,r.jsxs)("p",{style:{margin:0,color:"var(--error)"},children:["⚠️ This URS was auto-created from FS references. Click ",(0,r.jsx)("strong",{children:"Edit"})," to define its details."]})}),(0,r.jsxs)("div",{className:"card",style:{marginBottom:"1.5rem"},children:[(0,r.jsx)("h2",{className:"card-title",children:"\uD83D\uDD17 Traceability"}),(0,r.jsxs)("div",{style:{display:"flex",gap:"2rem",flexWrap:"wrap"},children:[(0,r.jsx)(o,{label:"Functional Specs",count:t.length,color:"var(--warning)"}),(0,r.jsx)(o,{label:"Test Scenarios",count:t.reduce((e,t)=>e+t.scenarios.length,0),color:"var(--accent)"}),(0,r.jsx)(o,{label:"Risk Assessments",count:a.length,color:"#f97316"})]})]}),(0,r.jsxs)("div",{style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"1.5rem"},children:[(0,r.jsxs)("div",{className:"card",children:[(0,r.jsx)("h2",{className:"card-title",children:"\uD83D\uDCCB Business Need"}),(0,r.jsx)("div",{style:{lineHeight:1.7},children:(0,r.jsx)(g,{value:m.business_need,onChange:e=>h({...m,business_need:e}),multiline:!0,placeholder:"Not defined"})})]}),(0,r.jsxs)("div",{className:"card",children:[(0,r.jsx)("h2",{className:"card-title",children:"\uD83C\uDFAF Intended Use"}),(0,r.jsx)("div",{style:{lineHeight:1.7},children:(0,r.jsx)(g,{value:m.intended_use,onChange:e=>h({...m,intended_use:e}),multiline:!0,placeholder:"Not defined"})})]})]}),(0,r.jsxs)("div",{className:"card",style:{marginTop:"1.5rem"},children:[(0,r.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"1rem"},children:[(0,r.jsx)("h2",{className:"card-title",style:{margin:0},children:"✅ Acceptance Criteria"}),s&&(0,r.jsx)("button",{onClick:()=>h({...m,acceptance_criteria:[...m.acceptance_criteria,""]}),className:"btn",style:{padding:"0.25rem 0.75rem"},children:"+ Add"})]}),0===m.acceptance_criteria.length?(0,r.jsx)("p",{style:{color:"var(--text-secondary)",fontStyle:"italic"},children:"No acceptance criteria defined"}):s?(0,r.jsx)("div",{style:{display:"grid",gap:"0.5rem"},children:m.acceptance_criteria.map((e,t)=>(0,r.jsxs)("div",{style:{display:"flex",gap:"0.5rem"},children:[(0,r.jsx)("input",{type:"text",value:e,onChange:e=>{let a=[...m.acceptance_criteria];a[t]=e.target.value,h({...m,acceptance_criteria:a})},className:"input",style:{flex:1},placeholder:`Criterion ${t+1}`}),(0,r.jsx)("button",{onClick:()=>h({...m,acceptance_criteria:m.acceptance_criteria.filter((e,a)=>a!==t)}),className:"btn",style:{padding:"0.5rem"},children:"\xd7"})]},t))}):(0,r.jsx)("ul",{style:{margin:0,paddingLeft:"1.5rem"},children:m.acceptance_criteria.map((e,t)=>(0,r.jsx)("li",{style:{marginBottom:"0.5rem",color:"var(--text-secondary)"},children:e},t))})]}),(0,r.jsxs)("div",{className:"card",style:{marginTop:"1.5rem"},children:[(0,r.jsx)("h2",{className:"card-title",children:"⚙️ Linked Functional Specifications"}),0===t.length?(0,r.jsx)("p",{style:{color:"var(--text-secondary)"},children:"No FS linked yet"}):(0,r.jsx)("div",{style:{display:"grid",gap:"1rem"},children:t.map(e=>(0,r.jsx)(l(),{href:`/specs/${e.id}`,style:{textDecoration:"none"},children:(0,r.jsx)("div",{style:{padding:"1rem",background:"var(--bg-hover)",borderRadius:"8px",borderLeft:"4px solid var(--warning)"},children:(0,r.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"0.75rem"},children:[(0,r.jsx)("code",{style:{fontWeight:600,color:"var(--warning)"},children:e.id}),(0,r.jsx)("span",{style:{color:"var(--text-primary)"},children:e.title}),(0,r.jsxs)("span",{className:"badge badge-success",style:{marginLeft:"auto"},children:[e.scenario_count," tests"]})]})})},e.id))})]})]})}function o({label:e,count:t,color:a}){return(0,r.jsxs)("div",{children:[(0,r.jsx)("div",{style:{fontSize:"0.75rem",color:"var(--text-secondary)",marginBottom:"0.25rem"},children:e}),(0,r.jsx)("div",{style:{fontSize:"1.5rem",fontWeight:700,color:a},children:t})]})}},6164:(e,t,a)=>{Promise.resolve().then(a.t.bind(a,8500,23)),Promise.resolve().then(a.bind(a,4839)),Promise.resolve().then(a.bind(a,8169)),Promise.resolve().then(a.bind(a,6161))},8169:(e,t,a)=>{"use strict";a.d(t,{ScenarioList:()=>l});var r=a(5155),i=a(2115);function s({scenario:e,isHighlighted:t}){return(0,r.jsxs)("div",{style:{padding:"1rem",background:t?"rgba(96, 165, 250, 0.1)":"var(--bg-hover)",borderRadius:"8px",border:t?"2px solid var(--accent)":"1px solid var(--border)"},children:[(0,r.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"0.75rem",marginBottom:"0.75rem"},children:[(0,r.jsx)("span",{style:{color:"var(--accent)"},children:"\uD83E\uDDEA"}),(0,r.jsx)("span",{style:{fontWeight:600},children:e.name}),e.tags.length>0&&(0,r.jsx)("span",{style:{marginLeft:"auto",fontSize:"0.75rem",color:"var(--text-secondary)"},children:e.tags.join(" ")})]}),(0,r.jsx)("div",{style:{fontFamily:"monospace",fontSize:"0.8125rem",lineHeight:1.6},children:e.steps.map((e,t)=>{var a;return(0,r.jsx)("div",{style:{color:(a=e).startsWith("Given")?"#a78bfa":a.startsWith("When")?"#60a5fa":a.startsWith("Then")?"#34d399":"var(--text-secondary)"},children:e},t)})})]})}function l({scenarios:e,highlightScenario:t}){let a=(0,i.useRef)(null);return(0,i.useEffect)(()=>{t&&a.current&&setTimeout(()=>{a.current?.scrollIntoView({behavior:"smooth",block:"center"})},100)},[t]),(0,r.jsx)("div",{style:{display:"grid",gap:"0.75rem"},children:e.map((e,i)=>{let l=t===e.name;return(0,r.jsx)("div",{ref:l?a:void 0,children:(0,r.jsx)(s,{scenario:e,isHighlighted:l})},i)})})}a(8500)},9339:(e,t,a)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r={callServer:function(){return s.callServer},createServerReference:function(){return n.createServerReference},findSourceMapURL:function(){return l.findSourceMapURL}};for(var i in r)Object.defineProperty(t,i,{enumerable:!0,get:r[i]});let s=a(7304),l=a(4060),n=a(7197)}},e=>{e.O(0,[500,441,794,358],()=>e(e.s=6164)),_N_E=e.O()}]);
|