kiro-spec-engine 1.28.0 → 1.29.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 +15 -0
- package/lib/commands/scene.js +181 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.29.0] - 2026-02-10
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **Scene Registry Query**: List and search scene packages in local registry
|
|
14
|
+
- `kse scene list` list all packages in registry
|
|
15
|
+
- `--registry <dir>` custom registry directory
|
|
16
|
+
- `--json` structured JSON output
|
|
17
|
+
- `kse scene search --query <term>` search packages by keyword
|
|
18
|
+
- Case-insensitive substring matching on name, description, and group
|
|
19
|
+
- `--registry <dir>` custom registry directory
|
|
20
|
+
- `--json` structured JSON output
|
|
21
|
+
- Shared helpers: `buildRegistryPackageList`, `filterRegistryPackages`
|
|
22
|
+
- Follows normalize → validate → run → print pattern
|
|
23
|
+
- Implements Spec 79-00-scene-registry-query
|
|
24
|
+
|
|
10
25
|
## [1.28.0] - 2026-02-10
|
|
11
26
|
|
|
12
27
|
### Added
|
package/lib/commands/scene.js
CHANGED
|
@@ -517,6 +517,25 @@ function registerSceneCommands(program) {
|
|
|
517
517
|
.action(async (options) => {
|
|
518
518
|
await runSceneInstallCommand(options);
|
|
519
519
|
});
|
|
520
|
+
|
|
521
|
+
sceneCmd
|
|
522
|
+
.command('list')
|
|
523
|
+
.description('List all packages in the local scene registry')
|
|
524
|
+
.option('-r, --registry <path>', 'Registry root directory', '.kiro/registry')
|
|
525
|
+
.option('--json', 'Print result as JSON')
|
|
526
|
+
.action(async (options) => {
|
|
527
|
+
await runSceneListCommand(options);
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
sceneCmd
|
|
531
|
+
.command('search')
|
|
532
|
+
.description('Search packages in the local scene registry')
|
|
533
|
+
.requiredOption('-q, --query <term>', 'Search term (substring match on name, description, group)')
|
|
534
|
+
.option('-r, --registry <path>', 'Registry root directory', '.kiro/registry')
|
|
535
|
+
.option('--json', 'Print result as JSON')
|
|
536
|
+
.action(async (options) => {
|
|
537
|
+
await runSceneSearchCommand(options);
|
|
538
|
+
});
|
|
520
539
|
}
|
|
521
540
|
|
|
522
541
|
function normalizeSourceOptions(options = {}) {
|
|
@@ -10062,6 +10081,157 @@ async function runSceneInstallCommand(rawOptions = {}, dependencies = {}) {
|
|
|
10062
10081
|
}
|
|
10063
10082
|
}
|
|
10064
10083
|
|
|
10084
|
+
// --- Scene Registry Query Helpers ---
|
|
10085
|
+
|
|
10086
|
+
function buildRegistryPackageList(registryPackages) {
|
|
10087
|
+
return Object.values(registryPackages || {})
|
|
10088
|
+
.map(pkg => ({
|
|
10089
|
+
name: pkg.name || '',
|
|
10090
|
+
group: pkg.group || '',
|
|
10091
|
+
description: pkg.description || '',
|
|
10092
|
+
latest: pkg.latest || '',
|
|
10093
|
+
version_count: Object.keys(pkg.versions || {}).length
|
|
10094
|
+
}))
|
|
10095
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
10096
|
+
}
|
|
10097
|
+
|
|
10098
|
+
function filterRegistryPackages(packageList, query) {
|
|
10099
|
+
if (!query) return packageList;
|
|
10100
|
+
const lowerQuery = query.toLowerCase();
|
|
10101
|
+
return packageList.filter(pkg =>
|
|
10102
|
+
pkg.name.toLowerCase().includes(lowerQuery) ||
|
|
10103
|
+
pkg.description.toLowerCase().includes(lowerQuery) ||
|
|
10104
|
+
pkg.group.toLowerCase().includes(lowerQuery)
|
|
10105
|
+
);
|
|
10106
|
+
}
|
|
10107
|
+
|
|
10108
|
+
// --- Scene List Command ---
|
|
10109
|
+
|
|
10110
|
+
function normalizeSceneListOptions(options = {}) {
|
|
10111
|
+
return {
|
|
10112
|
+
registry: options.registry ? String(options.registry).trim() : '.kiro/registry',
|
|
10113
|
+
json: options.json === true
|
|
10114
|
+
};
|
|
10115
|
+
}
|
|
10116
|
+
|
|
10117
|
+
function validateSceneListOptions(options) {
|
|
10118
|
+
return null;
|
|
10119
|
+
}
|
|
10120
|
+
|
|
10121
|
+
async function runSceneListCommand(rawOptions = {}, dependencies = {}) {
|
|
10122
|
+
const projectRoot = dependencies.projectRoot || process.cwd();
|
|
10123
|
+
const fileSystem = dependencies.fileSystem || fs;
|
|
10124
|
+
|
|
10125
|
+
const options = normalizeSceneListOptions(rawOptions);
|
|
10126
|
+
const validationError = validateSceneListOptions(options);
|
|
10127
|
+
|
|
10128
|
+
if (validationError) {
|
|
10129
|
+
console.error(chalk.red(`Scene list failed: ${validationError}`));
|
|
10130
|
+
process.exitCode = 1;
|
|
10131
|
+
return null;
|
|
10132
|
+
}
|
|
10133
|
+
|
|
10134
|
+
try {
|
|
10135
|
+
const registryRoot = path.isAbsolute(options.registry)
|
|
10136
|
+
? options.registry
|
|
10137
|
+
: path.join(projectRoot, options.registry);
|
|
10138
|
+
|
|
10139
|
+
const index = await loadRegistryIndex(registryRoot, fileSystem);
|
|
10140
|
+
const packages = buildRegistryPackageList(index.packages);
|
|
10141
|
+
const payload = { packages, total: packages.length };
|
|
10142
|
+
|
|
10143
|
+
printSceneListSummary(options, payload, projectRoot);
|
|
10144
|
+
return payload;
|
|
10145
|
+
} catch (error) {
|
|
10146
|
+
console.error(chalk.red('Scene list failed:'), error.message);
|
|
10147
|
+
process.exitCode = 1;
|
|
10148
|
+
return null;
|
|
10149
|
+
}
|
|
10150
|
+
}
|
|
10151
|
+
|
|
10152
|
+
function printSceneListSummary(options, payload, projectRoot = process.cwd()) {
|
|
10153
|
+
if (options.json) {
|
|
10154
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
10155
|
+
return;
|
|
10156
|
+
}
|
|
10157
|
+
|
|
10158
|
+
if (payload.total === 0) {
|
|
10159
|
+
console.log('No packages found');
|
|
10160
|
+
return;
|
|
10161
|
+
}
|
|
10162
|
+
|
|
10163
|
+
console.log(chalk.blue(`Scene Registry (${payload.total} package${payload.total !== 1 ? 's' : ''})`));
|
|
10164
|
+
for (const pkg of payload.packages) {
|
|
10165
|
+
console.log(` ${pkg.name.padEnd(20)} ${pkg.latest.padEnd(10)} ${String(pkg.version_count).padEnd(10)} ${pkg.description}`);
|
|
10166
|
+
}
|
|
10167
|
+
}
|
|
10168
|
+
|
|
10169
|
+
function normalizeSceneSearchOptions(options = {}) {
|
|
10170
|
+
return {
|
|
10171
|
+
query: options.query ? String(options.query).trim() : '',
|
|
10172
|
+
registry: options.registry ? String(options.registry).trim() : '.kiro/registry',
|
|
10173
|
+
json: options.json === true
|
|
10174
|
+
};
|
|
10175
|
+
}
|
|
10176
|
+
|
|
10177
|
+
function validateSceneSearchOptions(options) {
|
|
10178
|
+
return null; // Empty query is valid (returns all)
|
|
10179
|
+
}
|
|
10180
|
+
|
|
10181
|
+
async function runSceneSearchCommand(rawOptions = {}, dependencies = {}) {
|
|
10182
|
+
const projectRoot = dependencies.projectRoot || process.cwd();
|
|
10183
|
+
const fileSystem = dependencies.fileSystem || fs;
|
|
10184
|
+
|
|
10185
|
+
const options = normalizeSceneSearchOptions(rawOptions);
|
|
10186
|
+
const validationError = validateSceneSearchOptions(options);
|
|
10187
|
+
|
|
10188
|
+
if (validationError) {
|
|
10189
|
+
console.error(chalk.red(`Scene search failed: ${validationError}`));
|
|
10190
|
+
process.exitCode = 1;
|
|
10191
|
+
return null;
|
|
10192
|
+
}
|
|
10193
|
+
|
|
10194
|
+
try {
|
|
10195
|
+
const registryRoot = path.isAbsolute(options.registry)
|
|
10196
|
+
? options.registry
|
|
10197
|
+
: path.join(projectRoot, options.registry);
|
|
10198
|
+
|
|
10199
|
+
const index = await loadRegistryIndex(registryRoot, fileSystem);
|
|
10200
|
+
const allPackages = buildRegistryPackageList(index.packages);
|
|
10201
|
+
const packages = filterRegistryPackages(allPackages, options.query);
|
|
10202
|
+
const payload = { query: options.query, packages, total: packages.length };
|
|
10203
|
+
|
|
10204
|
+
printSceneSearchSummary(options, payload, projectRoot);
|
|
10205
|
+
return payload;
|
|
10206
|
+
} catch (error) {
|
|
10207
|
+
console.error(chalk.red('Scene search failed:'), error.message);
|
|
10208
|
+
process.exitCode = 1;
|
|
10209
|
+
return null;
|
|
10210
|
+
}
|
|
10211
|
+
}
|
|
10212
|
+
|
|
10213
|
+
function printSceneSearchSummary(options, payload, projectRoot = process.cwd()) {
|
|
10214
|
+
if (options.json) {
|
|
10215
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
10216
|
+
return;
|
|
10217
|
+
}
|
|
10218
|
+
|
|
10219
|
+
if (payload.total === 0) {
|
|
10220
|
+
if (payload.query) {
|
|
10221
|
+
console.log(`No packages matching '${payload.query}'`);
|
|
10222
|
+
} else {
|
|
10223
|
+
console.log('No packages found');
|
|
10224
|
+
}
|
|
10225
|
+
return;
|
|
10226
|
+
}
|
|
10227
|
+
|
|
10228
|
+
const matchLabel = payload.total === 1 ? 'match' : 'matches';
|
|
10229
|
+
console.log(chalk.blue(`Scene Search: "${payload.query}" (${payload.total} ${matchLabel})`));
|
|
10230
|
+
for (const pkg of payload.packages) {
|
|
10231
|
+
console.log(` ${pkg.name.padEnd(20)} ${pkg.latest.padEnd(10)} ${String(pkg.version_count).padEnd(10)} ${pkg.description}`);
|
|
10232
|
+
}
|
|
10233
|
+
}
|
|
10234
|
+
|
|
10065
10235
|
function printSceneUnpublishSummary(options, payload, projectRoot = process.cwd()) {
|
|
10066
10236
|
if (options.json) {
|
|
10067
10237
|
console.log(JSON.stringify(payload, null, 2));
|
|
@@ -10290,5 +10460,15 @@ module.exports = {
|
|
|
10290
10460
|
normalizeSceneInstallOptions,
|
|
10291
10461
|
printSceneInstallSummary,
|
|
10292
10462
|
runSceneInstallCommand,
|
|
10293
|
-
validateSceneInstallOptions
|
|
10463
|
+
validateSceneInstallOptions,
|
|
10464
|
+
buildRegistryPackageList,
|
|
10465
|
+
filterRegistryPackages,
|
|
10466
|
+
normalizeSceneListOptions,
|
|
10467
|
+
validateSceneListOptions,
|
|
10468
|
+
runSceneListCommand,
|
|
10469
|
+
printSceneListSummary,
|
|
10470
|
+
normalizeSceneSearchOptions,
|
|
10471
|
+
validateSceneSearchOptions,
|
|
10472
|
+
runSceneSearchCommand,
|
|
10473
|
+
printSceneSearchSummary
|
|
10294
10474
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kiro-spec-engine",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.29.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": {
|