kiro-spec-engine 1.29.0 → 1.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.30.0] - 2026-02-10
11
+
12
+ ### Added
13
+ - **Scene Version Bump**: Bump version in scene-package.json following semver
14
+ - `kse scene version --bump <major|minor|patch|x.y.z>` bump scene package version
15
+ - `--package <dir>` scene package directory (default: current directory)
16
+ - `--dry-run` preview without writing
17
+ - `--json` structured JSON output
18
+ - Supports major, minor, patch increments and explicit semver strings
19
+ - Validates explicit version is greater than current version
20
+ - Follows normalize → validate → run → print pattern
21
+ - Implements Spec 80-00-scene-version-bump
22
+
10
23
  ## [1.29.0] - 2026-02-10
11
24
 
12
25
  ### Added
@@ -536,6 +536,17 @@ function registerSceneCommands(program) {
536
536
  .action(async (options) => {
537
537
  await runSceneSearchCommand(options);
538
538
  });
539
+
540
+ sceneCmd
541
+ .command('version')
542
+ .description('Bump the version in a scene-package.json file')
543
+ .option('-p, --package <dir>', 'Scene package directory', '.')
544
+ .requiredOption('-b, --bump <type>', 'Bump type: major, minor, patch, or explicit semver')
545
+ .option('--json', 'Print result as JSON')
546
+ .option('--dry-run', 'Show what would change without writing')
547
+ .action(async (options) => {
548
+ await runSceneVersionCommand(options);
549
+ });
539
550
  }
540
551
 
541
552
  function normalizeSourceOptions(options = {}) {
@@ -10318,6 +10329,112 @@ async function runSceneUnpublishCommand(rawOptions = {}, dependencies = {}) {
10318
10329
  }
10319
10330
  }
10320
10331
 
10332
+ function normalizeSceneVersionOptions(options = {}) {
10333
+ return {
10334
+ package: options.package ? String(options.package).trim() : '.',
10335
+ bump: options.bump ? String(options.bump).trim().toLowerCase() : undefined,
10336
+ dryRun: options.dryRun === true,
10337
+ json: options.json === true
10338
+ };
10339
+ }
10340
+
10341
+ function validateSceneVersionOptions(options) {
10342
+ if (!options.bump) {
10343
+ return '--bump is required (major, minor, patch, or explicit semver)';
10344
+ }
10345
+ const validTypes = ['major', 'minor', 'patch'];
10346
+ if (!validTypes.includes(options.bump) && !semver.valid(options.bump)) {
10347
+ return `--bump "${options.bump}" is not a valid bump type or semver version`;
10348
+ }
10349
+ return null;
10350
+ }
10351
+
10352
+ function printSceneVersionSummary(options, payload, projectRoot = process.cwd()) {
10353
+ if (options.json) {
10354
+ console.log(JSON.stringify(payload, null, 2));
10355
+ return;
10356
+ }
10357
+ const dryRunLabel = payload.dryRun ? chalk.yellow(' [dry-run]') : '';
10358
+ console.log(chalk.blue('Scene Version Bump') + dryRunLabel);
10359
+ console.log(` Package: ${payload.name}`);
10360
+ console.log(` Version: ${payload.oldVersion} → ${payload.newVersion}`);
10361
+ console.log(` Directory: ${chalk.gray(payload.packageDir)}`);
10362
+ }
10363
+
10364
+ async function runSceneVersionCommand(rawOptions = {}, dependencies = {}) {
10365
+ const projectRoot = dependencies.projectRoot || process.cwd();
10366
+ const fileSystem = dependencies.fileSystem || fs;
10367
+
10368
+ const options = normalizeSceneVersionOptions(rawOptions);
10369
+ const validationError = validateSceneVersionOptions(options);
10370
+ if (validationError) {
10371
+ console.error(chalk.red(`Scene version bump failed: ${validationError}`));
10372
+ process.exitCode = 1;
10373
+ return null;
10374
+ }
10375
+
10376
+ try {
10377
+ const packageDir = path.isAbsolute(options.package)
10378
+ ? options.package
10379
+ : path.join(projectRoot, options.package);
10380
+
10381
+ const packageJsonPath = path.join(packageDir, 'scene-package.json');
10382
+ const readJson = typeof fileSystem.readJson === 'function'
10383
+ ? fileSystem.readJson.bind(fileSystem) : fs.readJson.bind(fs);
10384
+
10385
+ let packageData;
10386
+ try {
10387
+ packageData = await readJson(packageJsonPath);
10388
+ } catch (err) {
10389
+ throw new Error(`failed to read scene-package.json: ${err.message}`);
10390
+ }
10391
+
10392
+ const metadata = packageData && typeof packageData.metadata === 'object'
10393
+ ? packageData.metadata : null;
10394
+ const currentVersion = metadata ? String(metadata.version || '').trim() : '';
10395
+ if (!currentVersion || !semver.valid(currentVersion)) {
10396
+ throw new Error(`invalid or missing metadata.version: "${currentVersion}"`);
10397
+ }
10398
+
10399
+ const validTypes = ['major', 'minor', 'patch'];
10400
+ let newVersion;
10401
+ if (validTypes.includes(options.bump)) {
10402
+ newVersion = semver.inc(currentVersion, options.bump);
10403
+ } else {
10404
+ if (!semver.gt(options.bump, currentVersion)) {
10405
+ throw new Error(
10406
+ `explicit version "${options.bump}" must be greater than current "${currentVersion}"`
10407
+ );
10408
+ }
10409
+ newVersion = options.bump;
10410
+ }
10411
+
10412
+ if (!options.dryRun) {
10413
+ const writeJson = typeof fileSystem.writeJson === 'function'
10414
+ ? fileSystem.writeJson.bind(fileSystem) : fs.writeJson.bind(fs);
10415
+ packageData.metadata.version = newVersion;
10416
+ await writeJson(packageJsonPath, packageData, { spaces: 2 });
10417
+ }
10418
+
10419
+ const name = (metadata && metadata.name) || '';
10420
+ const payload = {
10421
+ success: true,
10422
+ name,
10423
+ oldVersion: currentVersion,
10424
+ newVersion,
10425
+ packageDir: formatScenePackagePath(projectRoot, packageDir),
10426
+ dryRun: options.dryRun
10427
+ };
10428
+
10429
+ printSceneVersionSummary(options, payload, projectRoot);
10430
+ return payload;
10431
+ } catch (error) {
10432
+ console.error(chalk.red('Scene version bump failed:'), error.message);
10433
+ process.exitCode = 1;
10434
+ return null;
10435
+ }
10436
+ }
10437
+
10321
10438
  module.exports = {
10322
10439
  RUN_MODES,
10323
10440
  SCAFFOLD_TYPES,
@@ -10470,5 +10587,9 @@ module.exports = {
10470
10587
  normalizeSceneSearchOptions,
10471
10588
  validateSceneSearchOptions,
10472
10589
  runSceneSearchCommand,
10473
- printSceneSearchSummary
10590
+ printSceneSearchSummary,
10591
+ normalizeSceneVersionOptions,
10592
+ validateSceneVersionOptions,
10593
+ runSceneVersionCommand,
10594
+ printSceneVersionSummary
10474
10595
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kiro-spec-engine",
3
- "version": "1.29.0",
3
+ "version": "1.30.0",
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": {