kiro-spec-engine 1.47.30 → 1.47.31

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.
@@ -893,14 +893,17 @@ kse scene package-ontology-backfill-batch --from-331 --dry-run --out-report .kir
893
893
  ### Moqui Template Baseline Scorecard
894
894
 
895
895
  ```bash
896
- # Score Moqui/ERP templates in the local template library (default filter: moqui|erp)
896
+ # Preferred CLI entry: score Moqui/ERP templates in the local template library (default filter: moqui|erp)
897
+ kse scene moqui-baseline --json
898
+
899
+ # Script alias (same behavior)
897
900
  npm run report:moqui-baseline
898
901
 
899
902
  # Score all scene templates instead of Moqui/ERP subset
900
- node scripts/moqui-template-baseline-report.js --include-all --json
903
+ kse scene moqui-baseline --include-all --json
901
904
 
902
905
  # Customize score thresholds and output paths
903
- node scripts/moqui-template-baseline-report.js \
906
+ kse scene moqui-baseline \
904
907
  --min-score 75 \
905
908
  --min-valid-rate 100 \
906
909
  --out .kiro/reports/moqui-template-baseline.json \
@@ -908,7 +911,7 @@ node scripts/moqui-template-baseline-report.js \
908
911
  --json
909
912
 
910
913
  # Compare with a previous baseline and fail CI on portfolio gate fail
911
- node scripts/moqui-template-baseline-report.js \
914
+ kse scene moqui-baseline \
912
915
  --compare-with .kiro/reports/release-evidence/moqui-template-baseline-prev.json \
913
916
  --fail-on-portfolio-fail \
914
917
  --json
@@ -27,10 +27,10 @@ Emergency bypass exists but is not recommended:
27
27
 
28
28
  ```bash
29
29
  # 0) Generate template baseline scoreboard (Moqui/ERP templates by default)
30
- node scripts/moqui-template-baseline-report.js --json
30
+ kse scene moqui-baseline --json
31
31
 
32
32
  # 0.1) CI/release mode: compare against previous baseline and enforce portfolio gate
33
- node scripts/moqui-template-baseline-report.js \
33
+ kse scene moqui-baseline \
34
34
  --compare-with .kiro/reports/release-evidence/moqui-template-baseline-prev.json \
35
35
  --fail-on-portfolio-fail \
36
36
  --json
@@ -1,6 +1,7 @@
1
1
  const path = require('path');
2
2
  const zlib = require('zlib');
3
3
  const crypto = require('crypto');
4
+ const { spawnSync } = require('child_process');
4
5
  const fs = require('fs-extra');
5
6
  const chalk = require('chalk');
6
7
  const yaml = require('js-yaml');
@@ -60,6 +61,9 @@ const SCENE_PACKAGE_KINDS = new Set([
60
61
  const SCENE_PACKAGE_RISK_LEVELS = new Set(['low', 'medium', 'high', 'critical']);
61
62
  const SCENE_PACKAGE_TEMPLATE_API_VERSION = 'kse.scene.template/v0.1';
62
63
  const SCENE_PACKAGE_TEMPLATE_DEFAULT_DIR = '.kiro/templates/scene-packages';
64
+ const SCENE_MOQUI_BASELINE_DEFAULT_MATCH = '(moqui|erp)';
65
+ const SCENE_MOQUI_BASELINE_DEFAULT_MIN_SCORE = 70;
66
+ const SCENE_MOQUI_BASELINE_DEFAULT_MIN_VALID_RATE = 100;
63
67
  const SCENE_PACKAGE_BATCH_DEFAULT_ONTOLOGY_MIN_AVERAGE_SCORE = 70;
64
68
  const SCENE_PACKAGE_BATCH_DEFAULT_ONTOLOGY_MIN_VALID_RATE = 100;
65
69
  const SCENE_PACKAGE_GATE_API_VERSION = 'kse.scene.package-gate/v0.1';
@@ -536,6 +540,23 @@ function registerSceneCommands(program) {
536
540
  await runSceneTemplateRenderCommand(options);
537
541
  });
538
542
 
543
+ sceneCmd
544
+ .command('moqui-baseline')
545
+ .description('Generate Moqui template baseline scorecard from scene package library')
546
+ .option('--template-dir <path>', 'Template root directory', SCENE_PACKAGE_TEMPLATE_DEFAULT_DIR)
547
+ .option('--out <path>', 'JSON report output path', '.kiro/reports/moqui-template-baseline.json')
548
+ .option('--markdown-out <path>', 'Markdown report output path', '.kiro/reports/moqui-template-baseline.md')
549
+ .option('--match <regex>', 'Template selector regex', SCENE_MOQUI_BASELINE_DEFAULT_MATCH)
550
+ .option('--include-all', 'Disable selector filter and score all templates')
551
+ .option('--min-score <number>', 'Baseline minimum semantic score (0-100)', String(SCENE_MOQUI_BASELINE_DEFAULT_MIN_SCORE))
552
+ .option('--min-valid-rate <number>', 'Baseline minimum ontology valid-rate percent (0-100)', String(SCENE_MOQUI_BASELINE_DEFAULT_MIN_VALID_RATE))
553
+ .option('--compare-with <path>', 'Compare with previous baseline JSON report')
554
+ .option('--fail-on-portfolio-fail', 'Exit non-zero when portfolio baseline gate fails')
555
+ .option('--json', 'Print payload as JSON')
556
+ .action(async (options) => {
557
+ await runSceneMoquiBaselineCommand(options);
558
+ });
559
+
539
560
  sceneCmd
540
561
  .command('instantiate')
541
562
  .description('Instantiate scene template package with full pipeline (resolve, validate, render, manifest, log, hook)')
@@ -10960,6 +10981,48 @@ function validateSceneTemplateResolveOptions(options) {
10960
10981
  return null;
10961
10982
  }
10962
10983
 
10984
+ function normalizeSceneMoquiBaselineOptions(options = {}) {
10985
+ const minScore = Number(options.minScore);
10986
+ const minValidRate = Number(options.minValidRate);
10987
+ return {
10988
+ templateDir: options.templateDir ? String(options.templateDir).trim() : SCENE_PACKAGE_TEMPLATE_DEFAULT_DIR,
10989
+ out: options.out ? String(options.out).trim() : '.kiro/reports/moqui-template-baseline.json',
10990
+ markdownOut: options.markdownOut ? String(options.markdownOut).trim() : '.kiro/reports/moqui-template-baseline.md',
10991
+ match: options.match ? String(options.match).trim() : SCENE_MOQUI_BASELINE_DEFAULT_MATCH,
10992
+ includeAll: options.includeAll === true,
10993
+ minScore: Number.isFinite(minScore) ? minScore : SCENE_MOQUI_BASELINE_DEFAULT_MIN_SCORE,
10994
+ minValidRate: Number.isFinite(minValidRate) ? minValidRate : SCENE_MOQUI_BASELINE_DEFAULT_MIN_VALID_RATE,
10995
+ compareWith: options.compareWith ? String(options.compareWith).trim() : undefined,
10996
+ failOnPortfolioFail: options.failOnPortfolioFail === true,
10997
+ json: options.json === true
10998
+ };
10999
+ }
11000
+
11001
+ function validateSceneMoquiBaselineOptions(options) {
11002
+ if (!options.templateDir || typeof options.templateDir !== 'string' || options.templateDir.trim().length === 0) {
11003
+ return '--template-dir is required';
11004
+ }
11005
+ if (!options.out || typeof options.out !== 'string' || options.out.trim().length === 0) {
11006
+ return '--out is required';
11007
+ }
11008
+ if (!options.markdownOut || typeof options.markdownOut !== 'string' || options.markdownOut.trim().length === 0) {
11009
+ return '--markdown-out is required';
11010
+ }
11011
+ if (!options.match || typeof options.match !== 'string' || options.match.trim().length === 0) {
11012
+ return '--match is required';
11013
+ }
11014
+ if (!Number.isFinite(Number(options.minScore)) || Number(options.minScore) < 0 || Number(options.minScore) > 100) {
11015
+ return '--min-score must be a number between 0 and 100';
11016
+ }
11017
+ if (!Number.isFinite(Number(options.minValidRate)) || Number(options.minValidRate) < 0 || Number(options.minValidRate) > 100) {
11018
+ return '--min-valid-rate must be a number between 0 and 100';
11019
+ }
11020
+ if (options.compareWith !== undefined && (!options.compareWith || options.compareWith.length === 0)) {
11021
+ return '--compare-with cannot be empty';
11022
+ }
11023
+ return null;
11024
+ }
11025
+
10963
11026
  // --- Print functions for template commands ---
10964
11027
 
10965
11028
  function printSceneTemplateValidateSummary(options, payload, projectRoot = process.cwd()) {
@@ -11076,6 +11139,80 @@ function printSceneTemplateRenderSummary(options, payload, projectRoot = process
11076
11139
 
11077
11140
  // --- Command runners for template commands ---
11078
11141
 
11142
+ async function runSceneMoquiBaselineCommand(rawOptions = {}, dependencies = {}) {
11143
+ const projectRoot = dependencies.projectRoot || process.cwd();
11144
+ const fileSystem = dependencies.fileSystem || fs;
11145
+
11146
+ const options = normalizeSceneMoquiBaselineOptions(rawOptions);
11147
+ const validationError = validateSceneMoquiBaselineOptions(options);
11148
+ if (validationError) {
11149
+ console.error(chalk.red(`Scene moqui-baseline failed: ${validationError}`));
11150
+ process.exitCode = 1;
11151
+ return null;
11152
+ }
11153
+
11154
+ const scriptPath = path.join(projectRoot, 'scripts', 'moqui-template-baseline-report.js');
11155
+ const scriptExists = await fileSystem.pathExists(scriptPath);
11156
+ if (!scriptExists) {
11157
+ console.error(chalk.red(`Scene moqui-baseline failed: script not found at ${scriptPath}`));
11158
+ process.exitCode = 1;
11159
+ return null;
11160
+ }
11161
+
11162
+ const args = [scriptPath];
11163
+ args.push('--template-dir', options.templateDir);
11164
+ args.push('--out', options.out);
11165
+ args.push('--markdown-out', options.markdownOut);
11166
+ args.push('--match', options.match);
11167
+ args.push('--min-score', String(options.minScore));
11168
+ args.push('--min-valid-rate', String(options.minValidRate));
11169
+ if (options.includeAll) {
11170
+ args.push('--include-all');
11171
+ }
11172
+ if (options.compareWith) {
11173
+ args.push('--compare-with', options.compareWith);
11174
+ }
11175
+ if (options.failOnPortfolioFail) {
11176
+ args.push('--fail-on-portfolio-fail');
11177
+ }
11178
+ if (options.json) {
11179
+ args.push('--json');
11180
+ }
11181
+
11182
+ const result = spawnSync(process.execPath, args, {
11183
+ cwd: projectRoot,
11184
+ encoding: 'utf8'
11185
+ });
11186
+
11187
+ if (typeof result.stdout === 'string' && result.stdout.length > 0) {
11188
+ process.stdout.write(result.stdout);
11189
+ }
11190
+ if (typeof result.stderr === 'string' && result.stderr.length > 0) {
11191
+ process.stderr.write(result.stderr);
11192
+ }
11193
+
11194
+ if (result.error) {
11195
+ console.error(chalk.red(`Scene moqui-baseline failed: ${result.error.message}`));
11196
+ process.exitCode = 1;
11197
+ return null;
11198
+ }
11199
+
11200
+ const exitCode = Number.isInteger(result.status) ? result.status : 1;
11201
+ if (exitCode !== 0) {
11202
+ process.exitCode = exitCode;
11203
+ }
11204
+
11205
+ if (options.json && typeof result.stdout === 'string' && result.stdout.trim().length > 0) {
11206
+ try {
11207
+ return JSON.parse(result.stdout);
11208
+ } catch (_error) {
11209
+ return null;
11210
+ }
11211
+ }
11212
+
11213
+ return null;
11214
+ }
11215
+
11079
11216
  async function runSceneTemplateValidateCommand(rawOptions = {}, dependencies = {}) {
11080
11217
  const projectRoot = dependencies.projectRoot || process.cwd();
11081
11218
  const fileSystem = dependencies.fileSystem || fs;
@@ -15266,6 +15403,9 @@ module.exports = {
15266
15403
  validateSceneTemplateValidateOptions,
15267
15404
  normalizeSceneTemplateResolveOptions,
15268
15405
  validateSceneTemplateResolveOptions,
15406
+ normalizeSceneMoquiBaselineOptions,
15407
+ validateSceneMoquiBaselineOptions,
15408
+ runSceneMoquiBaselineCommand,
15269
15409
  runSceneTemplateValidateCommand,
15270
15410
  runSceneTemplateResolveCommand,
15271
15411
  runSceneTemplateRenderCommand,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kiro-spec-engine",
3
- "version": "1.47.30",
3
+ "version": "1.47.31",
4
4
  "description": "kiro-spec-engine (kse) - A CLI tool and npm package for spec-driven development with AI coding assistants. NOT the Kiro IDE desktop application.",
5
5
  "main": "index.js",
6
6
  "bin": {