From 5fbda2535ce2e1bb4a929464a00c99576166ff30 Mon Sep 17 00:00:00 2001 From: Adrian Elton-Browning Date: Tue, 6 Oct 2026 12:10:53 +0100 Subject: [PATCH 1/2] docs(bumpy): spell out the transformWithFunction -> update migration --- .bumpy/library-cli-boundary.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bumpy/library-cli-boundary.md b/.bumpy/library-cli-boundary.md index 1b6bdd7..92ce1be 100644 --- a/.bumpy/library-cli-boundary.md +++ b/.bumpy/library-cli-boundary.md @@ -2,4 +2,4 @@ mdcode-ts: minor --- -Removed `transform()` and `transformWithFunction()`, which printed every block to the console and `transform()` read stdin; use `update({ source, transformer, filter })` instead. Added `update({ onBlock })` to report each block as it finishes, and `extract()` now throws an `invalid_usage` error for `updateSource` with `ignoreAnonymous`. +Removed `transform()` and `transformWithFunction()`, which printed every block to the console and `transform()` read stdin. `update({ source, transformer, filter })` replaces `transformWithFunction()` but reads each `file=` first, so a missing file is a `read_failed` error (thrown, or collected with `continueOnError`); use `walk()` to transform without reading files. Added `update({ onBlock })` to report each block as it finishes, and `extract()` now throws an `invalid_usage` error for `updateSource` with `ignoreAnonymous`. From b562ebc73b6c5be0a351328fcd4a56e9547a2d45 Mon Sep 17 00:00:00 2001 From: Adrian Elton-Browning Date: Tue, 6 Oct 2026 12:19:10 +0100 Subject: [PATCH 2/2] chore: lint library code for console/process I/O, dot test reporter, recompile Abide rubric, re-check blocked issues on close --- .abide/rubric.json | 197 ++++++++++++++++++--------------- TESTING.md | 5 +- docs/agents/issue-tracker.md | 1 + packages/mdcode/.eslintrc.json | 36 +++++- packages/mdcode/package.json | 2 +- packages/usage/package.json | 2 +- 6 files changed, 147 insertions(+), 96 deletions(-) diff --git a/.abide/rubric.json b/.abide/rubric.json index 5f882f2..16b92e8 100644 --- a/.abide/rubric.json +++ b/.abide/rubric.json @@ -1,191 +1,206 @@ { "version": 1, - "compiledAt": "2026-09-26T00:00:00.000Z", + "compiledAt": "2026-10-06T12:30:00.000Z", "compiledBy": "claude", "sources": [ { "path": "CLAUDE.md", - "sha": "555a20d66f1b750123f05622c861eca3704c4246e29622ff32a81a3abbd34027", - "scope": "**/*" + "scope": "**/*", + "sha": "afb77c5e8ffc502330baa870089e75bc042b19b79dca1bd839176051baf1076d" } ], "rules": [ { - "id": "run-both-test-packages", - "text": "Testing (ALWAYS RUN BOTH)", + "id": "node-test-runner-only", + "text": "Tests use `node:test`.", "source": { "path": "CLAUDE.md", - "line": 16 + "line": 14 }, + "scope": [ + "**/*.ts", + "**/*.mts", + "**/package.json" + ], "check": { - "type": "unenforceable", - "reason": "about which commands the agent runs, not the code" + "type": "lint", + "how": "no-restricted-imports for vitest, jest, @jest/*, mocha; grep package.json for those dependencies", + "pattern": "(from\\s+['\"](vitest|jest|@jest/[\\w-]+|mocha)['\"]|\"(vitest|jest|mocha)\"\\s*:)" }, "status": "active" }, { - "id": "no-unified-remark", - "text": "Custom line-by-line state machine for parsing markdown (no unified/remark)", + "id": "zshy-bundler-only", + "text": "The build uses `zshy`, not tsc.", "source": { "path": "CLAUDE.md", - "line": 54 + "line": 14 }, "scope": [ - "packages/mdcode/**/*.ts", - "packages/mdcode/package.json" + "**/package.json" ], "check": { "type": "lint", - "how": "no-restricted-imports for unified, remark, remark-* and mdast packages; grep package.json dependencies", - "pattern": "(from\\s+['\"](unified|remark[\\w-]*|mdast[\\w-]*)['\"]|\"(unified|remark[\\w-]*)\"\\s*:)" + "how": "grep package.json build scripts for a tsc emit build or rollup", + "pattern": "\"(build|dev)\"\\s*:\\s*\"[^\"]*\\b(tsc(?![^\"]*--noEmit)|rollup)\\b" }, "status": "active" }, { - "id": "use-define-transform", - "text": "Use `defineTransform()` helper for type safety.", + "id": "ts-extension-imports", + "text": "Relative imports keep their `.ts` extension: `import { parse } from \"./parser.ts\"`.", "source": { "path": "CLAUDE.md", - "line": 92 + "line": 15 }, "scope": [ - "packages/usage/**/*.ts", - "packages/example/**/*.ts", - "packages/mdcode/src/**/*.test.ts", - "**/*transform*.ts", - "**/*transform*.mts" + "**/*.ts", + "**/*.mts" ], - "when": "edit", "check": { - "type": "model", - "question": { - "type": "boolean", - "instructions": "Among the added lines, is there `export default`, `const transformer =` or `transformer:` followed directly by an arrow function or `function` taking `{ tag, meta, code }`, with no `defineTransform(` around it? Answer false if no transformer is added.", - "criteria": { - "true": "export default ({ tag, code }) => tag === 'sql' ? code.toUpperCase() : code;", - "false": "export default defineTransform(({tag, code}) => {\n if (tag === 'sql') return code.toUpperCase();\n return code;\n});" - } - } - }, - "status": "active", - "calibration": { - "at": "2026-09-26T15:12:04.977Z", - "hunks": 3, - "median": 0.8683, - "min": 0.8596, - "max": 0.9016, - "fired": 3, - "verdict": "skipped" - } + "type": "lint", + "how": "node/file-extension-in-import (set to always in shared/.eslintrc.json)", + "pattern": "from\\s+['\"]\\.{1,2}/[^'\"]*(? --body "..."` - **Apply / remove labels**: `gh issue edit --add-label "..."` / `--remove-label "..."` - **Close**: `gh issue close --comment "..."` +- **After closing an issue**: list the open issues it blocked with `gh api 'repos/{owner}/{repo}/issues//dependencies/blocking' --jq '.[] | select(.state=="open") | .number'`, plus any open issue whose body says `Blocked by` it (`gh search issues --repo / --state open '"#" in:body'`). Check each one's Agent Brief against `main` and comment with whatever the close made outdated: criteria now met, a stale "Verification status", names that have changed. Infer the repo from `git remote -v` — `gh` does this automatically when run inside a clone. diff --git a/packages/mdcode/.eslintrc.json b/packages/mdcode/.eslintrc.json index c2b5ec6..1ac48b6 100644 --- a/packages/mdcode/.eslintrc.json +++ b/packages/mdcode/.eslintrc.json @@ -7,5 +7,39 @@ "node": { "version": ">=20.*" } - } + }, + // Library code returns results; only the CLI adapter (cli.ts, main.ts) prints, reads stdin or exits. + "rules": { + "no-console": "error", + "no-restricted-properties": [ + "error", + { "object": "process", "property": "stdin", "message": "Library code takes its input as an argument; only cli.ts reads stdin." }, + { "object": "process", "property": "stdout", "message": "Library code returns results; only cli.ts and main.ts write output." }, + { "object": "process", "property": "stderr", "message": "Library code returns results; only cli.ts and main.ts write output." }, + { "object": "process", "property": "exit", "message": "Only main.ts ends the process, through exitCode." }, + { "object": "process", "property": "exitCode", "message": "Only main.ts sets the exit code." } + ], + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "node:process", + "importNames": [ "stdin", "stdout", "stderr", "exit", "exitCode" ], + "message": "Library code returns results; only cli.ts and main.ts touch process I/O." + } + ] + } + ] + }, + "overrides": [ + { + "files": [ "src/cli.ts", "src/main.ts", "src/**/*.test.ts" ], + "rules": { + "no-console": "off", + "no-restricted-properties": "off", + "no-restricted-imports": "off" + } + } + ] } diff --git a/packages/mdcode/package.json b/packages/mdcode/package.json index b1af33a..2ebdb23 100644 --- a/packages/mdcode/package.json +++ b/packages/mdcode/package.json @@ -11,7 +11,7 @@ "bp": "pnpm version prerelease --no-git-tag-version && pnpm --filter mdcode-ts build && pnpm pack", "build": "zshy", "dev": "zshy --watch", - "test": "node --test-reporter=spec --test './{tests,src}/**/*.test.ts'", + "test": "node --test-reporter=dot --test './{tests,src}/**/*.test.ts'", "test:watch": "node --watch --test-reporter=spec --test './{tests,src}/**/*.test.ts'", "prepublishOnly": "pnpm build", "lint:ts": "tsc --noEmit", diff --git a/packages/usage/package.json b/packages/usage/package.json index 6f29ecf..01e88fa 100644 --- a/packages/usage/package.json +++ b/packages/usage/package.json @@ -6,7 +6,7 @@ "private": true, "scripts": { "pretest": "pnpm --filter mdcode-ts build", - "test": "node --test-reporter=spec --test tests/**/*.test.ts", + "test": "node --test-reporter=dot --test tests/**/*.test.ts", "test:watch": "pnpm test -w", "lint:ts": "tsc --noEmit", "lint": "tsc --noEmit && eslint \"{tests,fixtures,examples}/**/*.{j,t}s{,x}\" --cache --max-warnings=0",