47 lines
3.0 KiB
JavaScript
47 lines
3.0 KiB
JavaScript
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
import { readIndexedTask, verifyTaskIndex, root } from './task-context-lib.mjs';
|
|
|
|
const taskArg = process.argv.indexOf('--task');
|
|
const task = taskArg >= 0 ? process.argv[taskArg + 1] : undefined;
|
|
if (!task) throw new Error('usage: node tools/web/generate-task-card.mjs --task <task-id>');
|
|
verifyTaskIndex();
|
|
const entry = readIndexedTask(task);
|
|
if (!entry) throw new Error('unknown indexed task: ' + task);
|
|
const cardPath = path.join(root, 'docs/tasks', task + '.md');
|
|
if (fs.existsSync(cardPath) && !process.argv.includes('--force')) {
|
|
process.stdout.write('task-card-exists task=' + task + ' path=' + path.relative(root, cardPath) + '\n');
|
|
process.exit(0);
|
|
}
|
|
if (!entry.previous) throw new Error('task ' + task + ' has no indexed parent');
|
|
const safeName = entry.gapId.replace(/[^A-Za-z0-9_.-]+/g, '-').replace(/^-+|-+$/g, '') || 'gap';
|
|
const fixture = 'tests/files/web/generated/' + task + '-' + safeName + '.blend';
|
|
const source = [
|
|
'# ' + task + ': ' + entry.gapId + ' LOCAL_EXACT slice', '',
|
|
'- task: ' + task, '- parent: ' + entry.previous, '- status: in_progress',
|
|
'- gap: ' + entry.gapId, '- ownerFamily: ' + entry.ownerFamily,
|
|
'- targetImplementationClass: ' + entry.targetImplementationClass, '',
|
|
'## 目标', '',
|
|
'Make the same minimal fixture produce observable ' + entry.gapId + ' data in Blender desktop and WASM/Main, with save/reopen stability. Change only this gap; do not expand to other data-blocks, editors, or browsers.', '',
|
|
'## 输入与范围', '',
|
|
'- Fixture: `' + fixture + '`',
|
|
'- Generator: `tools/web/generated/' + task + '.py`',
|
|
'- Production: `blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp`',
|
|
'- Checker: `tools/web/check-generated-gap.mjs`',
|
|
'- Do: field read, desktop/WASM comparison, save/reopen, structured report.',
|
|
'- Do not: other gaps, Firefox/WebKit, or full editor behavior.', '',
|
|
'## 验收', '',
|
|
'build_blender_5.2.0/bin/blender -b --factory-startup --python tools/web/generated/' + task + '.py -- ' + fixture,
|
|
'npm --prefix web run test:generated-gap -- --task ' + task,
|
|
'node tools/web/check-generated-gap.mjs --task ' + task, '',
|
|
'Malformed/unsupported, cancellation, duplicate, over-budget, or hash-drift cases must keep in_progress; they must not change Main revision or advance nextTask.', '',
|
|
'## 交付与回滚', '',
|
|
'- Reports: `tests/golden/' + task + '/`', '- Status: `docs/status/' + task + '.md`',
|
|
'- Manifest: `tests/golden/' + task + '/manifest.json`',
|
|
'- Handoff: `node tools/web/check-task-context.mjs --task ' + task + ' --write`',
|
|
'- Rollback: remove this task production entry, fixture, tests, reports, manifest, status, and context; restore the parent as queue tail without rewriting parent evidence.',
|
|
].join('\n') + '\n';
|
|
fs.mkdirSync(path.dirname(cardPath), { recursive: true });
|
|
fs.writeFileSync(cardPath, source);
|
|
process.stdout.write('task-card-generated task=' + task + ' bytes=' + Buffer.byteLength(source) + ' path=' + path.relative(root, cardPath) + '\n');
|