lean-spec 0.2.4 → 0.2.5-dev.20251118134144

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.
@@ -4278,14 +4278,15 @@ Validating ${specs.length} specs...
4278
4278
 
4279
4279
  // src/commands/validate.ts
4280
4280
  function validateCommand() {
4281
- return new Command("validate").description("Validate specs for quality issues").argument("[specs...]", "Specific specs to validate (optional)").option("--max-lines <number>", "Custom line limit (default: 400)", parseInt).option("--verbose", "Show passing specs").option("--quiet", "Suppress warnings, only show errors").option("--format <format>", "Output format: default, json, compact", "default").option("--rule <rule>", "Filter by specific rule name (e.g., max-lines, frontmatter)").action(async (specs, options) => {
4281
+ return new Command("validate").description("Validate specs for quality issues").argument("[specs...]", "Specific specs to validate (optional)").option("--max-lines <number>", "Custom line limit (default: 400)", parseInt).option("--verbose", "Show passing specs").option("--quiet", "Suppress warnings, only show errors").option("--format <format>", "Output format: default, json, compact", "default").option("--rule <rule>", "Filter by specific rule name (e.g., max-lines, frontmatter)").option("--warnings-only", "Treat all issues as warnings, never fail (useful for CI pre-release checks)").action(async (specs, options) => {
4282
4282
  const passed = await validateSpecs({
4283
4283
  maxLines: options.maxLines,
4284
4284
  specs: specs && specs.length > 0 ? specs : void 0,
4285
4285
  verbose: options.verbose,
4286
4286
  quiet: options.quiet,
4287
4287
  format: options.format,
4288
- rule: options.rule
4288
+ rule: options.rule,
4289
+ warningsOnly: options.warningsOnly
4289
4290
  });
4290
4291
  process.exit(passed ? 0 : 1);
4291
4292
  });
@@ -4356,6 +4357,9 @@ async function validateSpecs(options = {}) {
4356
4357
  };
4357
4358
  const output = formatValidationResults(results, specs, config.specsDir, formatOptions);
4358
4359
  console.log(output);
4360
+ if (options.warningsOnly) {
4361
+ return true;
4362
+ }
4359
4363
  const hasErrors = results.some((r) => !r.result.passed);
4360
4364
  return !hasErrors;
4361
4365
  }
@@ -7009,31 +7013,31 @@ async function startUi(options) {
7009
7013
  console.log(chalk18.dim("Remove --dev flag to use production mode"));
7010
7014
  throw new Error("Not in LeanSpec monorepo");
7011
7015
  }
7012
- const localWebDir = join(cwd, "packages/web");
7013
- return runLocalWeb(localWebDir, specsDir, options);
7016
+ const localUiDir = join(cwd, "packages/ui");
7017
+ return runLocalWeb(localUiDir, specsDir, options);
7014
7018
  }
7015
7019
  return runPublishedUI(cwd, specsDir, options);
7016
7020
  }
7017
7021
  function checkIsLeanSpecMonorepo(cwd) {
7018
- const localWebDir = join(cwd, "packages/web");
7019
- const webPackageJson = join(localWebDir, "package.json");
7020
- if (!existsSync(webPackageJson)) {
7022
+ const localUiDir = join(cwd, "packages/ui");
7023
+ const uiPackageJson = join(localUiDir, "package.json");
7024
+ if (!existsSync(uiPackageJson)) {
7021
7025
  return false;
7022
7026
  }
7023
7027
  try {
7024
- const packageJson2 = JSON.parse(readFileSync(webPackageJson, "utf-8"));
7025
- return packageJson2.name === "@leanspec/web";
7028
+ const packageJson2 = JSON.parse(readFileSync(uiPackageJson, "utf-8"));
7029
+ return packageJson2.name === "@leanspec/ui";
7026
7030
  } catch {
7027
7031
  return false;
7028
7032
  }
7029
7033
  }
7030
- async function runLocalWeb(webDir, specsDir, options) {
7031
- console.log(chalk18.dim("\u2192 Detected LeanSpec monorepo, using local web package\n"));
7032
- const repoRoot = resolve(webDir, "..", "..");
7034
+ async function runLocalWeb(uiDir, specsDir, options) {
7035
+ console.log(chalk18.dim("\u2192 Detected LeanSpec monorepo, using local ui package\n"));
7036
+ const repoRoot = resolve(uiDir, "..", "..");
7033
7037
  const packageManager = detectPackageManager(repoRoot);
7034
7038
  if (options.dryRun) {
7035
7039
  console.log(chalk18.cyan("Would run:"));
7036
- console.log(chalk18.dim(` cd ${webDir}`));
7040
+ console.log(chalk18.dim(` cd ${uiDir}`));
7037
7041
  console.log(chalk18.dim(` SPECS_MODE=filesystem SPECS_DIR=${specsDir} PORT=${options.port} ${packageManager} run dev`));
7038
7042
  if (options.open) {
7039
7043
  console.log(chalk18.dim(` open http://localhost:${options.port}`));
@@ -7048,9 +7052,10 @@ async function runLocalWeb(webDir, specsDir, options) {
7048
7052
  PORT: options.port
7049
7053
  };
7050
7054
  const child = spawn(packageManager, ["run", "dev"], {
7051
- cwd: webDir,
7055
+ cwd: uiDir,
7052
7056
  stdio: "inherit",
7053
- env
7057
+ env,
7058
+ detached: true
7054
7059
  });
7055
7060
  const readyTimeout = setTimeout(async () => {
7056
7061
  spinner.succeed("Web UI running");
@@ -7070,14 +7075,28 @@ async function runLocalWeb(webDir, specsDir, options) {
7070
7075
  }
7071
7076
  }
7072
7077
  }, 3e3);
7073
- const sigintHandler = () => {
7078
+ const shutdown = (signal) => {
7074
7079
  clearTimeout(readyTimeout);
7075
7080
  spinner.stop();
7076
- child.kill("SIGTERM");
7081
+ try {
7082
+ if (child && child.pid) {
7083
+ try {
7084
+ process.kill(-child.pid, signal ?? "SIGTERM");
7085
+ } catch (err) {
7086
+ child.kill(signal ?? "SIGTERM");
7087
+ }
7088
+ }
7089
+ } catch (err) {
7090
+ }
7077
7091
  console.log(chalk18.dim("\n\u2713 Web UI stopped"));
7078
7092
  process.exit(0);
7079
7093
  };
7080
- process.once("SIGINT", sigintHandler);
7094
+ process.once("SIGINT", () => shutdown("SIGINT"));
7095
+ process.once("SIGTERM", () => shutdown("SIGTERM"));
7096
+ process.once("SIGHUP", () => shutdown("SIGHUP"));
7097
+ if (process.stdin && !process.stdin.destroyed) {
7098
+ process.stdin.once("end", () => shutdown("SIGTERM"));
7099
+ }
7081
7100
  child.on("exit", (code) => {
7082
7101
  clearTimeout(readyTimeout);
7083
7102
  spinner.stop();
@@ -7087,6 +7106,7 @@ async function runLocalWeb(webDir, specsDir, options) {
7087
7106
  Process exited with code ${code}`));
7088
7107
  process.exit(code);
7089
7108
  }
7109
+ process.exit(0);
7090
7110
  });
7091
7111
  }
7092
7112
  async function runPublishedUI(cwd, specsDir, options) {
@@ -7100,16 +7120,32 @@ async function runPublishedUI(cwd, specsDir, options) {
7100
7120
  }
7101
7121
  const child = spawn(command, args, {
7102
7122
  stdio: "inherit",
7103
- env: process.env
7123
+ env: process.env,
7124
+ detached: true
7104
7125
  });
7105
- const shutdown = () => {
7106
- child.kill("SIGINT");
7126
+ const shutdownPublished = (signal) => {
7127
+ try {
7128
+ if (child && child.pid) {
7129
+ try {
7130
+ process.kill(-child.pid, signal ?? "SIGINT");
7131
+ } catch (err) {
7132
+ child.kill(signal ?? "SIGINT");
7133
+ }
7134
+ }
7135
+ } catch (err) {
7136
+ }
7107
7137
  console.log(chalk18.dim("\n\u2713 Web UI stopped"));
7108
7138
  process.exit(0);
7109
7139
  };
7110
- process.once("SIGINT", shutdown);
7140
+ process.once("SIGINT", () => shutdownPublished("SIGINT"));
7141
+ process.once("SIGTERM", () => shutdownPublished("SIGTERM"));
7142
+ process.once("SIGHUP", () => shutdownPublished("SIGHUP"));
7143
+ if (process.stdin && !process.stdin.destroyed) {
7144
+ process.stdin.once("end", () => shutdownPublished("SIGTERM"));
7145
+ }
7111
7146
  child.on("exit", (code) => {
7112
7147
  if (code === 0 || code === null) {
7148
+ process.exit(0);
7113
7149
  return;
7114
7150
  }
7115
7151
  console.error(chalk18.red(`
@@ -8423,5 +8459,5 @@ if (import.meta.url === `file://${process.argv[1]}`) {
8423
8459
  }
8424
8460
 
8425
8461
  export { analyzeCommand, archiveCommand, backfillCommand, boardCommand, checkCommand, compactCommand, createCommand, createMcpServer, depsCommand, filesCommand, ganttCommand, initCommand, linkCommand, listCommand, mcpCommand, migrateCommand, openCommand, searchCommand, splitCommand, statsCommand, templatesCommand, timelineCommand, tokensCommand, uiCommand, unlinkCommand, updateCommand, validateCommand, viewCommand };
8426
- //# sourceMappingURL=chunk-UHMYFCXJ.js.map
8427
- //# sourceMappingURL=chunk-UHMYFCXJ.js.map
8462
+ //# sourceMappingURL=chunk-7WXYOHZU.js.map
8463
+ //# sourceMappingURL=chunk-7WXYOHZU.js.map