@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.
Files changed (73) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +4 -4
  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 +4 -4
  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-e0a24ae820fa2c06.js → page-e8eb2c5950ee1495.js} +3 -3
  49. package/.next/static/chunks/app/releases/[id]/page-f13257c6f0e69a7c.js +1 -0
  50. package/.next/static/chunks/app/releases/{page-fc527101f56b36c5.js → page-050bb308276e178c.js} +1 -1
  51. package/.next/static/chunks/app/specs/[id]/page-a1e2672e95d4c9c6.js +1 -0
  52. package/bin/cli.js +82 -42
  53. package/bin/cli.ts +12 -12
  54. package/package.json +7 -2
  55. package/.next/diagnostics/build-diagnostics.json +0 -6
  56. package/.next/diagnostics/framework.json +0 -1
  57. package/.next/static/chunks/app/releases/[id]/page-ea66642a6a557b42.js +0 -1
  58. package/.next/static/chunks/app/specs/[id]/page-49293bb634997108.js +0 -1
  59. package/.next/trace +0 -11
  60. package/.next/trace-build +0 -1
  61. package/.next/types/app/builder/page.ts +0 -86
  62. package/.next/types/app/guide/page.ts +0 -86
  63. package/.next/types/app/layout.ts +0 -86
  64. package/.next/types/app/matrix/page.ts +0 -86
  65. package/.next/types/app/page.ts +0 -86
  66. package/.next/types/app/releases/[id]/page.ts +0 -86
  67. package/.next/types/app/releases/page.ts +0 -86
  68. package/.next/types/app/specs/[id]/page.ts +0 -86
  69. package/.next/types/package.json +0 -1
  70. package/.next/types/routes.d.ts +0 -63
  71. package/.next/types/validator.ts +0 -115
  72. /package/.next/static/{zmL75rl5Hq4TyiNVaXe8R → SmDoKluq2qozv2eyHXbUF}/_buildManifest.js +0 -0
  73. /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 readFileSync2 } from "fs";
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(), "machine.db");
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(__dirname3, "schema.sql");
2160
- const schema = readFileSync2(schemaPath, "utf-8");
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 __dirname3, db = null;
2195
+ var __dirname2, db = null;
2196
2196
  var init_database = __esm(() => {
2197
- __dirname3 = dirname2(fileURLToPath2(import.meta.url));
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 readFileSync4 } from "fs";
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 = readFileSync4(jsonPath, "utf-8");
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: "./machine.db",
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, "machine.config.ts");
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.machine || {};
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
- var __dirname2 = dirname(fileURLToPath(import.meta.url));
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
- console.log("\uD83D\uDE80 Starting @nivora/machine server...");
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
- 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
- });
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 readFileSync3, readdirSync } from "fs";
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: "./machine.db",
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 `machine init` to create the specs directory structure.");
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 = readFileSync3(filePath, "utf-8");
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 `machine sync` to index files");
3369
- console.log(" 3. Run `machine serve` to start the UI");
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: machine release create -v 1.0.0 -n "My Release"');
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: machine release import-results <file> --releaseId <id>");
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: machine test import ./results.json -r ${releaseId}`);
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("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) => {
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", "./machine.db").action(async (options) => {
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", "./machine.db").action(async (query, options) => {
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", "./machine.db").action(async (options) => {
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", "./machine.db").action(async (options) => {
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", "./machine.db").action(async (releaseId, options) => {
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", "./machine.db").action(async (releaseId, options) => {
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", "./machine.db").action(async (file, options) => {
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", "./machine.db").action(async (jsonPath, options) => {
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", "./machine.db").action(async (releaseId, options) => {
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/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.1",
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,6 +0,0 @@
1
- {
2
- "buildStage": "static-generation",
3
- "buildOptions": {
4
- "useBuildWorker": "false"
5
- }
6
- }
@@ -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()}]);