* fix(#4489): make capability-registry.test.cjs's extractShellBlocks CRLF-safe Second, independent copy of the #4409 CRLF-fragile line-splitting bug, explicitly flagged as out of scope there ("other duplicated helper in file sibling test files not part of the shadowing chain, tracked separately if divergent"). Same fix: content.split('\n') -> content.split(/\r?\n/), matching src/text-lines.cts's splitLines() and the already-fixed sibling copy in tests/runtime-launcher-parity.test.cjs. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * chore(#4488): regenerate INVENTORY-MANIFEST.json for tdd-red-evidence.cjs's ADR-457 untracking Discovered while validating #4489's push: #4488's merge (untracking gsd-core/bin/lib/tdd-red-evidence.cjs per ADR-457) left docs/INVENTORY- MANIFEST.json stale, since that file was previously listed as a tracked shipped artifact. Removed via node scripts/gen-inventory-manifest.cjs --write. docs/INVENTORY.md already described this file as gitignored (no update needed there -- it already documented the intended state). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * revert: undo incorrect INVENTORY-MANIFEST.json edit from 57f1457a27 The prior commit removed tdd-red-evidence.cjs's manifest entry based on a false premise: a stale tsconfig.build.tsbuildinfo (gitignored, untouched by git checkout/rebase) told tsc the file's compilation was already current even though git's own checkout had deleted the actual output file during this branch's rebase onto #4488's merge (a tracked-in-old-tree, untracked-in-new-tree transition deletes the working-tree file regardless of the new .gitignore entry). tsc's incremental cache doesn't verify its recorded output still exists on disk, so it silently skipped re-emitting it. Confirmed real root cause: deleting tsconfig.build.tsbuildinfo and rebuilding fresh correctly re-emits gsd-core/bin/lib/tdd-red-evidence.cjs (it is gitignored now, not deleted -- src/tdd-red-evidence.cts is unaffected by ADR-457's tracked-vs-gitignored distinction and always compiles). The manifest's own purpose (per its docstring) is 'every shipped surface derived entirely from the filesystem' -- this file still ships via the normal build, so it belongs in the manifest regardless of git-tracking status. Net result matches next's own INVENTORY-MANIFEST.json byte-for-byte; this correction should not have been needed at all had the build cache been fresh when the prior commit was made. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: sim <sim@local> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -6286,7 +6286,11 @@ const WORKFLOWS_DIR = path.join(__dirname, '..', 'gsd-core', 'workflows');
|
|||||||
* between the ```bash / ```sh / ```shell fence markers.
|
* between the ```bash / ```sh / ```shell fence markers.
|
||||||
*/
|
*/
|
||||||
function extractShellBlocks(content) {
|
function extractShellBlocks(content) {
|
||||||
const allLines = content.split('\n');
|
// #4489: CRLF-safe split (mirrors src/text-lines.cts's splitLines() and the
|
||||||
|
// fixed sibling copy in tests/runtime-launcher-parity.test.cjs:221) — a bare
|
||||||
|
// '\n' split leaves a trailing \r on every line on a CRLF checkout, which
|
||||||
|
// reaches lineHasBareGsdTools' whitespace tokenizer below.
|
||||||
|
const allLines = content.split(/\r?\n/);
|
||||||
const blocks = [];
|
const blocks = [];
|
||||||
let inBlock = false;
|
let inBlock = false;
|
||||||
let blockLang = null;
|
let blockLang = null;
|
||||||
@@ -6369,6 +6373,41 @@ function lineHasBareGsdTools(line) {
|
|||||||
|
|
||||||
const AGENTS_DIR = path.join(__dirname, '..', 'agents');
|
const AGENTS_DIR = path.join(__dirname, '..', 'agents');
|
||||||
|
|
||||||
|
describe('bug #4489: extractShellBlocks is CRLF-safe (sibling of #4409)', () => {
|
||||||
|
test('a CRLF-line-ending fenced block yields lines with no trailing \\r', () => {
|
||||||
|
const content = [
|
||||||
|
'# doc',
|
||||||
|
'',
|
||||||
|
'```bash',
|
||||||
|
'echo one',
|
||||||
|
'echo two',
|
||||||
|
'```',
|
||||||
|
'',
|
||||||
|
].join('\r\n');
|
||||||
|
const blocks = extractShellBlocks(content);
|
||||||
|
assert.strictEqual(blocks.length, 1, 'expected exactly one extracted block');
|
||||||
|
assert.deepStrictEqual(blocks[0].lines, ['echo one', 'echo two']);
|
||||||
|
for (const line of blocks[0].lines) {
|
||||||
|
assert.ok(!line.includes('\r'), `line carried a trailing/embedded \\r: ${JSON.stringify(line)}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('LF-only input is unaffected (pre-existing behavior unchanged)', () => {
|
||||||
|
const content = [
|
||||||
|
'# doc',
|
||||||
|
'',
|
||||||
|
'```sh',
|
||||||
|
'echo one',
|
||||||
|
'echo two',
|
||||||
|
'```',
|
||||||
|
'',
|
||||||
|
].join('\n');
|
||||||
|
const blocks = extractShellBlocks(content);
|
||||||
|
assert.strictEqual(blocks.length, 1);
|
||||||
|
assert.deepStrictEqual(blocks[0].lines, ['echo one', 'echo two']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('bug #1041: agent files must not call bare gsd-tools (all-runtime resolver)', () => {
|
describe('bug #1041: agent files must not call bare gsd-tools (all-runtime resolver)', () => {
|
||||||
test('no agents/gsd-*.md file contains a bare gsd-tools command', () => {
|
test('no agents/gsd-*.md file contains a bare gsd-tools command', () => {
|
||||||
const files = fs.readdirSync(AGENTS_DIR).filter((f) => f.startsWith('gsd-') && f.endsWith('.md'));
|
const files = fs.readdirSync(AGENTS_DIR).filter((f) => f.startsWith('gsd-') && f.endsWith('.md'));
|
||||||
|
|||||||
Reference in New Issue
Block a user