@codeyam/codeyam-cli 0.1.17 → 0.1.18
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/analyzer-template/.build-info.json +6 -6
- package/analyzer-template/log.txt +3 -3
- package/codeyam-cli/src/commands/editor.js +123 -5
- package/codeyam-cli/src/commands/editor.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/editorAudit.test.js +160 -0
- package/codeyam-cli/src/utils/__tests__/editorAudit.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/editorEntityHelpers.test.js +66 -0
- package/codeyam-cli/src/utils/__tests__/editorEntityHelpers.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/entityChangeStatus.test.js +213 -0
- package/codeyam-cli/src/utils/__tests__/entityChangeStatus.test.js.map +1 -1
- package/codeyam-cli/src/utils/editorAudit.js +44 -14
- package/codeyam-cli/src/utils/editorAudit.js.map +1 -1
- package/codeyam-cli/src/utils/editorRecapture.js +109 -0
- package/codeyam-cli/src/utils/editorRecapture.js.map +1 -0
- package/codeyam-cli/src/utils/entityChangeStatus.js +30 -2
- package/codeyam-cli/src/utils/entityChangeStatus.js.map +1 -1
- package/codeyam-cli/src/utils/scenariosManifest.js +22 -0
- package/codeyam-cli/src/utils/scenariosManifest.js.map +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/api.editor-recapture-stale-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/manifest-b9d4d267.js +1 -0
- package/codeyam-cli/src/webserver/build/server/assets/{analysisRunner-BMmkgAkg.js → analysisRunner-CGwTN3V2.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/{index-DxB0pOSt.js → index-D4meMKy3.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/{init-DLYLaqqP.js → init-odGJ_c2-.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/{server-build-CcyitQLQ.js → server-build-TmPfF7pT.js} +123 -122
- package/codeyam-cli/src/webserver/build/server/index.js +1 -1
- package/codeyam-cli/src/webserver/build-info.json +5 -5
- package/package.json +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/manifest-3157d6b8.js +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
"buildTimestamp": "2026-03-
|
|
3
|
-
"buildTime":
|
|
4
|
-
"gitCommit": "
|
|
2
|
+
"buildTimestamp": "2026-03-19T21:52:47.836Z",
|
|
3
|
+
"buildTime": 1773957167836,
|
|
4
|
+
"gitCommit": "40b059fe8e0f00686186b501bf7ad39e8cdbc22c",
|
|
5
5
|
"nodeVersion": "v20.20.1",
|
|
6
6
|
"contentHash": "b046e014847d5b02d10d6795839ccd0d5117627cbd0be413260824610596a63d",
|
|
7
|
-
"buildNumber":
|
|
8
|
-
"semanticVersion": "0.1.
|
|
9
|
-
"version": "0.1.
|
|
7
|
+
"buildNumber": 1110,
|
|
8
|
+
"semanticVersion": "0.1.1110",
|
|
9
|
+
"version": "0.1.1110 (2026-03-19T21:52+b046e01)"
|
|
10
10
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
|
-
[3/19/2026,
|
|
3
|
-
[3/19/2026,
|
|
2
|
+
[3/19/2026, 9:52:47 PM] > codeyam-combo@1.0.0 mergeDependencies
|
|
3
|
+
[3/19/2026, 9:52:47 PM] > node ./scripts/mergePackageJsonFiles.cjs
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
[3/19/2026,
|
|
6
|
+
[3/19/2026, 9:52:47 PM] Merged dependencies into root package.json
|
|
7
7
|
|
|
@@ -1449,6 +1449,7 @@ function printStep12(root, feature) {
|
|
|
1449
1449
|
checkbox('If `hasErrors` is true, fix them and re-capture affected scenarios');
|
|
1450
1450
|
checkbox('Run `codeyam editor verify-images \'{"paths":["/"], "imageUrls":["url1"]}\'` with all page paths and image URLs');
|
|
1451
1451
|
checkbox('Fix or remove any broken images before continuing');
|
|
1452
|
+
checkbox('Recapture stale scenarios: `codeyam editor recapture-stale`');
|
|
1452
1453
|
checkbox('Run `codeyam editor audit` to verify completeness of scenarios and tests');
|
|
1453
1454
|
checkbox('Do not proceed until all checks pass');
|
|
1454
1455
|
stopGate(12);
|
|
@@ -2122,6 +2123,7 @@ function printStep14(root, feature) {
|
|
|
2122
2123
|
console.log('Commit all changes for this feature.');
|
|
2123
2124
|
console.log();
|
|
2124
2125
|
console.log(chalk.bold('Checklist:'));
|
|
2126
|
+
checkbox('Ensure all screenshots are fresh: `codeyam editor recapture-stale`');
|
|
2125
2127
|
checkbox(`Hide the results panel: \`codeyam editor hide-results\``);
|
|
2126
2128
|
checkbox(`Git commit using the journal description: \`codeyam editor commit '{"message":"feat: <title>\\n\\n<journal description>"}'\``);
|
|
2127
2129
|
console.log(chalk.dim(' The commit message body MUST match the journal description exactly'));
|
|
@@ -2951,6 +2953,7 @@ function handleChange(feature) {
|
|
|
2951
2953
|
checkbox(`Navigate to key pages to verify changes: \`codeyam editor preview '{"path":"/your-route","dimension":"${dim}"}'\``);
|
|
2952
2954
|
printDimensionGuidance(dim, dimNames);
|
|
2953
2955
|
checkbox('Run `codeyam editor scenario-coverage` — all affected scenarios must be fresh');
|
|
2956
|
+
checkbox('Recapture stale scenarios: `codeyam editor recapture-stale`');
|
|
2954
2957
|
checkbox('Run `codeyam editor audit` — all checks must pass');
|
|
2955
2958
|
checkbox(`Check for client-side errors: \`codeyam editor client-errors\``);
|
|
2956
2959
|
console.log(chalk.dim(' If `hasContent=false`, the preview is blank — fix the code before proceeding.'));
|
|
@@ -3186,11 +3189,18 @@ async function handleAudit() {
|
|
|
3186
3189
|
}
|
|
3187
3190
|
console.log(chalk.bold('Components (scenarios):'));
|
|
3188
3191
|
for (const c of components) {
|
|
3189
|
-
const icon = c.status === 'ok'
|
|
3192
|
+
const icon = c.status === 'ok'
|
|
3193
|
+
? chalk.green('✓')
|
|
3194
|
+
: c.status === 'needs_recapture'
|
|
3195
|
+
? chalk.yellow('↻')
|
|
3196
|
+
: chalk.red('✗');
|
|
3190
3197
|
let detail;
|
|
3191
3198
|
if (c.status === 'has_errors') {
|
|
3192
3199
|
detail = chalk.red(` — ${c.scenarioCount} scenario${c.scenarioCount !== 1 ? 's' : ''} but has client errors`);
|
|
3193
3200
|
}
|
|
3201
|
+
else if (c.status === 'needs_recapture') {
|
|
3202
|
+
detail = chalk.yellow(` — ${c.scenarioCount} scenario${c.scenarioCount !== 1 ? 's' : ''}, needs recapture`);
|
|
3203
|
+
}
|
|
3194
3204
|
else if (c.status === 'ok') {
|
|
3195
3205
|
detail = chalk.dim(` (${c.scenarioCount} scenario${c.scenarioCount !== 1 ? 's' : ''})`);
|
|
3196
3206
|
}
|
|
@@ -3199,7 +3209,7 @@ async function handleAudit() {
|
|
|
3199
3209
|
}
|
|
3200
3210
|
// Show file path for failing components always, for OK only when name is ambiguous
|
|
3201
3211
|
const isDuplicate = (componentNameCounts.get(c.name) || 0) > 1;
|
|
3202
|
-
const showPath = c.status !== 'ok' || isDuplicate;
|
|
3212
|
+
const showPath = (c.status !== 'ok' && c.status !== 'needs_recapture') || isDuplicate;
|
|
3203
3213
|
const pathSuffix = showPath && c.filePath ? chalk.dim(` (${c.filePath})`) : '';
|
|
3204
3214
|
console.log(` ${icon} ${c.name}${pathSuffix}${detail}`);
|
|
3205
3215
|
if (c.clientErrors && c.clientErrors.length > 0) {
|
|
@@ -3313,7 +3323,7 @@ async function handleAudit() {
|
|
|
3313
3323
|
: `${s.status.status}`;
|
|
3314
3324
|
console.log(` ${chalk.red('✗')} ${s.scenarioName} ${chalk.dim(`(${s.entityName} — ${reason})`)}`);
|
|
3315
3325
|
}
|
|
3316
|
-
console.log(chalk.yellow('
|
|
3326
|
+
console.log(chalk.yellow(' Run: codeyam editor recapture-stale'));
|
|
3317
3327
|
console.log();
|
|
3318
3328
|
}
|
|
3319
3329
|
// Duplicate glossary names (warning, not a failure)
|
|
@@ -3385,6 +3395,109 @@ async function handleAudit() {
|
|
|
3385
3395
|
console.log(chalk.yellow('Warning: Could not build import graph. Run `codeyam editor analyze-imports` manually.'));
|
|
3386
3396
|
}
|
|
3387
3397
|
}
|
|
3398
|
+
// ─── Recapture-stale subcommand ────────────────────────────────────────
|
|
3399
|
+
/**
|
|
3400
|
+
* `codeyam editor recapture-stale`
|
|
3401
|
+
*
|
|
3402
|
+
* Identifies all scenarios whose entity (or dependency) has changed but
|
|
3403
|
+
* whose screenshot hasn't been recaptured this session, then recaptures
|
|
3404
|
+
* them in batch.
|
|
3405
|
+
*/
|
|
3406
|
+
async function handleRecaptureStale() {
|
|
3407
|
+
const port = getServerPort();
|
|
3408
|
+
const url = `http://localhost:${port}/api/editor-recapture-stale`;
|
|
3409
|
+
console.log();
|
|
3410
|
+
console.log(chalk.bold.cyan('━━━ Recapture Stale Scenarios ━━━'));
|
|
3411
|
+
console.log();
|
|
3412
|
+
let res;
|
|
3413
|
+
try {
|
|
3414
|
+
res = await fetch(url, { method: 'POST' });
|
|
3415
|
+
}
|
|
3416
|
+
catch (err) {
|
|
3417
|
+
console.error(chalk.red('Error: Could not reach the CodeYam server. Is it running?'));
|
|
3418
|
+
console.error(chalk.dim(` ${err.message}`));
|
|
3419
|
+
process.exit(1);
|
|
3420
|
+
}
|
|
3421
|
+
if (!res.ok) {
|
|
3422
|
+
const body = await res.json().catch(() => null);
|
|
3423
|
+
console.error(chalk.red(`Error: Recapture endpoint returned ${res.status}`));
|
|
3424
|
+
if (body?.error)
|
|
3425
|
+
console.error(chalk.red(` ${body.error}`));
|
|
3426
|
+
process.exit(1);
|
|
3427
|
+
}
|
|
3428
|
+
// Handle JSON response (early returns like "no changes" / "all up to date")
|
|
3429
|
+
const contentType = res.headers.get('content-type') || '';
|
|
3430
|
+
if (contentType.includes('application/json')) {
|
|
3431
|
+
const data = await res.json();
|
|
3432
|
+
if (data.note) {
|
|
3433
|
+
console.log(chalk.dim(data.note));
|
|
3434
|
+
}
|
|
3435
|
+
else if (data.total === 0) {
|
|
3436
|
+
console.log(chalk.green('All scenarios are up to date.'));
|
|
3437
|
+
}
|
|
3438
|
+
console.log();
|
|
3439
|
+
return;
|
|
3440
|
+
}
|
|
3441
|
+
// Stream NDJSON progress events
|
|
3442
|
+
let total = 0;
|
|
3443
|
+
let recapturedCount = 0;
|
|
3444
|
+
let failedCount = 0;
|
|
3445
|
+
const reader = res.body?.getReader();
|
|
3446
|
+
if (!reader) {
|
|
3447
|
+
console.error(chalk.red('Error: No response body'));
|
|
3448
|
+
process.exit(1);
|
|
3449
|
+
}
|
|
3450
|
+
const decoder = new TextDecoder();
|
|
3451
|
+
let buffer = '';
|
|
3452
|
+
while (true) {
|
|
3453
|
+
const { done, value } = await reader.read();
|
|
3454
|
+
if (done)
|
|
3455
|
+
break;
|
|
3456
|
+
buffer += decoder.decode(value, { stream: true });
|
|
3457
|
+
const lines = buffer.split('\n');
|
|
3458
|
+
buffer = lines.pop() || ''; // Keep incomplete last line in buffer
|
|
3459
|
+
for (const line of lines) {
|
|
3460
|
+
if (!line.trim())
|
|
3461
|
+
continue;
|
|
3462
|
+
try {
|
|
3463
|
+
const event = JSON.parse(line);
|
|
3464
|
+
switch (event.type) {
|
|
3465
|
+
case 'start':
|
|
3466
|
+
total = event.total;
|
|
3467
|
+
console.log(`Found ${total} stale scenario(s). Recapturing...\n`);
|
|
3468
|
+
break;
|
|
3469
|
+
case 'capturing':
|
|
3470
|
+
process.stdout.write(chalk.dim(` … ${event.name}`));
|
|
3471
|
+
break;
|
|
3472
|
+
case 'success':
|
|
3473
|
+
// Clear the "capturing" line and print success
|
|
3474
|
+
process.stdout.write('\r\x1b[K');
|
|
3475
|
+
console.log(` ${chalk.green('✓')} ${event.name}`);
|
|
3476
|
+
recapturedCount++;
|
|
3477
|
+
break;
|
|
3478
|
+
case 'failure':
|
|
3479
|
+
process.stdout.write('\r\x1b[K');
|
|
3480
|
+
console.log(` ${chalk.red('✗')} ${event.name} — ${chalk.dim(event.error)}`);
|
|
3481
|
+
failedCount++;
|
|
3482
|
+
break;
|
|
3483
|
+
case 'done':
|
|
3484
|
+
// Final summary
|
|
3485
|
+
console.log();
|
|
3486
|
+
const color = failedCount > 0 ? chalk.yellow : chalk.green;
|
|
3487
|
+
console.log(color(`Recaptured ${recapturedCount}/${total} scenario(s).`));
|
|
3488
|
+
console.log();
|
|
3489
|
+
break;
|
|
3490
|
+
}
|
|
3491
|
+
}
|
|
3492
|
+
catch {
|
|
3493
|
+
// Skip unparseable lines
|
|
3494
|
+
}
|
|
3495
|
+
}
|
|
3496
|
+
}
|
|
3497
|
+
if (failedCount > 0) {
|
|
3498
|
+
process.exit(1);
|
|
3499
|
+
}
|
|
3500
|
+
}
|
|
3388
3501
|
// ─── Scenarios subcommand ─────────────────────────────────────────────
|
|
3389
3502
|
async function handleScenarios() {
|
|
3390
3503
|
const port = getServerPort();
|
|
@@ -3995,8 +4108,8 @@ const editorCommand = {
|
|
|
3995
4108
|
describe: 'Editor mode guided workflow',
|
|
3996
4109
|
builder: (yargs) => {
|
|
3997
4110
|
const stepDescription = IS_INTERNAL_BUILD
|
|
3998
|
-
? 'Step number (1-16) or subcommand (template, register, isolate, analyze-imports, dependents, audit, scenarios, scenario-coverage, change, sync, debug, preview, show-results, hide-results, commit, journal, journal-list, journal-update, dev-server, client-errors)'
|
|
3999
|
-
: 'Step number (1-16) or subcommand (template, register, isolate, analyze-imports, dependents, audit, scenarios, scenario-coverage, change, sync, preview, show-results, hide-results, commit, journal, journal-list, journal-update, dev-server, client-errors)';
|
|
4111
|
+
? 'Step number (1-16) or subcommand (template, register, isolate, analyze-imports, dependents, audit, scenarios, scenario-coverage, recapture-stale, change, sync, debug, preview, show-results, hide-results, commit, journal, journal-list, journal-update, dev-server, client-errors)'
|
|
4112
|
+
: 'Step number (1-16) or subcommand (template, register, isolate, analyze-imports, dependents, audit, scenarios, scenario-coverage, recapture-stale, change, sync, preview, show-results, hide-results, commit, journal, journal-list, journal-update, dev-server, client-errors)';
|
|
4000
4113
|
let builder = yargs
|
|
4001
4114
|
.positional('step', {
|
|
4002
4115
|
type: 'string',
|
|
@@ -4119,6 +4232,11 @@ const editorCommand = {
|
|
|
4119
4232
|
await handleScenarioCoverage();
|
|
4120
4233
|
return;
|
|
4121
4234
|
}
|
|
4235
|
+
// Subcommand: codeyam editor recapture-stale
|
|
4236
|
+
if (argv.step === 'recapture-stale') {
|
|
4237
|
+
await handleRecaptureStale();
|
|
4238
|
+
return;
|
|
4239
|
+
}
|
|
4122
4240
|
// Subcommand: codeyam editor change <feature>
|
|
4123
4241
|
if (argv.step === 'change') {
|
|
4124
4242
|
handleChange(argv.json || '');
|