test: add rstest unit tests for doom and export packages#305
Conversation
WalkthroughThis PR adds rstest-based unit testing across the monorepo (root config, scripts, devDependency), many new test files and a remark-lint test helper, updates CI to run tests in parallel, introduces extensive developer documentation and OpenSpec command/skill specs, and minor package/tsconfig adjustments and imports maps. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
There was a problem hiding this comment.
Pull request overview
Adds @rstest/core and wires up a new unit-test setup across the monorepo, including per-package configs and new unit tests for @alauda/doom and @alauda/doom-export.
Changes:
- Add
@rstest/corewith root + per-packagerstest.config.tsand roottest/test:watchscripts. - Introduce
tsconfig.test.jsonand per-test-directorytsconfig.jsonto support TS/ESLint project service usage for tests. - Add unit tests for remark-lint rules / replace plugins in
doom, and various utilities inexport, and run tests in CI.
Reviewed changes
Copilot reviewed 31 out of 33 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| yarn.lock | Adds lock entries for @rstest/core and its dependency graph. |
| tsconfig.test.json | Adds a root test TS config with paths for package entrypoints. |
| tsconfig.json | Excludes test directories from the root TS project. |
| rstest.config.ts | Adds root rstest “projects” configuration. |
| package.json | Adds test / test:watch scripts and devDependency on @rstest/core; excludes tests from type-coverage. |
| .github/workflows/ci.yml | Runs tests in CI alongside docs/lint/typecov. |
| packages/doom/rstest.config.ts | Per-package rstest config for doom. |
| packages/doom/test/tsconfig.json | Test-directory TS config for doom. |
| packages/doom/test/utils/helpers.test.ts | Adds unit tests for baseResolve / pkgResolve. |
| packages/doom/test/remark-lint/_helper.ts | Adds shared lint helpers for remark-lint rule tests. |
| packages/doom/test/remark-lint/unit-case.test.ts | Tests unitCase remark-lint rule behavior. |
| packages/doom/test/remark-lint/table-size.test.ts | Tests tableSize remark-lint rule behavior. |
| packages/doom/test/remark-lint/no-paragraph-indent.test.ts | Tests noParagraphIndent remark-lint rule behavior. |
| packages/doom/test/remark-lint/no-multi-open-api-paths.test.ts | Tests noMultiOpenAPIPaths rule behavior with MDX. |
| packages/doom/test/remark-lint/no-heading-sup-sub.test.ts | Tests noHeadingSupSub rule behavior. |
| packages/doom/test/remark-lint/no-heading-special-characters.test.ts | Tests noHeadingSpecialCharacters rule behavior. |
| packages/doom/test/remark-lint/no-heading-punctuation.test.ts | Tests noHeadingPunctuation rule behavior. |
| packages/doom/test/remark-lint/no-empty-table-cell.test.ts | Tests noEmptyTableCell rule behavior. |
| packages/doom/test/remark-lint/no-deep-list.test.ts | Tests noDeepList rule behavior. |
| packages/doom/test/remark-lint/no-deep-heading.test.ts | Tests noDeepHeading rule behavior. |
| packages/doom/test/remark-lint/maximum-link-content-length.test.ts | Tests maximumLinkContentLength rule behavior. |
| packages/doom/test/remark-lint/list-table-introduction.test.ts | Tests listTableIntroduction rule behavior. |
| packages/doom/test/remark-lint/list-item-size.test.ts | Tests listItemSize rule behavior. |
| packages/doom/test/remark-lint/list-item-punctuation.test.ts | Tests listItemPunctuation rule behavior. |
| packages/doom/test/plugins/replace/utils.test.ts | Tests replace-plugin utilities (normalizeReferenceItems, getFrontmatterNode). |
| packages/doom/test/plugins/replace/parse-toc.test.ts | Tests replace-plugin TOC parsing behavior. |
| packages/export/rstest.config.ts | Per-package rstest config for export. |
| packages/export/test/tsconfig.json | Test-directory TS config for export. |
| packages/export/test/merge-pdfs/formatDate.test.ts | Tests PDF date formatting helper. |
| packages/export/test/html-export-pdf/utils/replaceExt.test.ts | Tests replaceExt helper behavior. |
| packages/export/test/html-export-pdf/utils/isValidUrl.test.ts | Tests isValidUrl helper behavior. |
| packages/export/test/export-pdf-core/utils/getUrlLink.test.ts | Tests getUrlLink URL+hash splitting behavior. |
| packages/export/test/export-pdf-core/utils/convertPathToPosix.test.ts | Tests convertPathToPosix helper behavior on non-Windows. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
packages/doom/test/remark-lint/no-heading-sup-sub.test.ts (1)
14-16: Prefer order-agnostic assertions for emitted messages.Line 14-Line 16 currently assume deterministic message ordering. Making this unordered reduces brittle test failures without changing coverage intent.
Suggested update
test('flags heading with sup', async () => { const messages = await lint(noHeadingSupSub, '## Title <sup>beta</sup>\n') expect(messages).toHaveLength(2) - expect(String(messages[0])).toContain('<sup>') - expect(String(messages[1])).toContain('</sup>') + const rendered = messages.map((message) => String(message)) + expect(rendered).toEqual( + expect.arrayContaining([ + expect.stringContaining('<sup>'), + expect.stringContaining('</sup>'), + ]), + ) })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/doom/test/remark-lint/no-heading-sup-sub.test.ts` around lines 14 - 16, The test currently asserts deterministic ordering by checking String(messages[0]) and String(messages[1]) contain '<sup>' and '</sup>'; change this to order-agnostic checks by converting messages to strings and asserting the array contains both expected substrings in any order (e.g., use messages.map(String) with expect.arrayContaining and expect.stringContaining for '<sup>' and '</sup>'), or assert that there exists some element matching each substring using .some; update the assertions around the messages variable accordingly.packages/export/test/export-pdf-core/utils/convertPathToPosix.test.ts (1)
6-45: Add Windows-path assertions to cover the conversion branch.These cases validate passthrough behavior, but they don’t directly exercise the
win32normalization path (backslashes/DOS device prefix). Adding 1–2 Windows-specific cases would protect the utility’s primary transformation logic.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/export/test/export-pdf-core/utils/convertPathToPosix.test.ts` around lines 6 - 45, Tests currently only cover non-Windows passthroughs; add 1–2 Windows-specific assertions to exercise the win32 conversion branch in convertPathToPosix by passing a backslash path (e.g. 'C:\\Users\\me\\file.pdf') and a DOS-device-prefixed path (e.g. '\\\\?\\C:\\path\\file.pdf') and assert they are converted to POSIX-style paths ('/c/Users/me/file.pdf' or '/c/path/file.pdf' respectively) so the normalization logic and prefix handling in convertPathToPosix are exercised.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/doom/test/plugins/replace/parse-toc.test.ts`:
- Around line 111-119: The test title "skips h1 from toc when allDepths is true"
contradicts its assertions; update the test name string in the test that calls
parseMarkdown and parseToc (the test currently using "skips h1 from toc when
allDepths is true") to reflect the actual assertion (e.g., "includes h1 in toc
when allDepths is true" or "does not skip h1 when allDepths is true") so the
test name matches the behavior verified by the expect(toc[0]?.depth).toBe(1) and
expect(toc[1]?.depth).toBe(2) assertions.
In `@packages/doom/test/plugins/replace/utils.test.ts`:
- Around line 129-149: The test currently triggers an emitted error for
duplicate source names; update the test wrapping normalizeReferenceItems so it
explicitly captures/asserts the expected emission: spy on the logger used by
normalizeReferenceItems (e.g., console.error or the module logger), run
normalizeReferenceItems(items), assert that the spy was called with a message
containing "Duplicate source name `config` will be deduplicated", then restore
the spy; keep the existing assertions on result['config'].path and .anchor. This
ensures the duplicate-source emission is asserted rather than treated as an
unexpected CI error.
---
Nitpick comments:
In `@packages/doom/test/remark-lint/no-heading-sup-sub.test.ts`:
- Around line 14-16: The test currently asserts deterministic ordering by
checking String(messages[0]) and String(messages[1]) contain '<sup>' and
'</sup>'; change this to order-agnostic checks by converting messages to strings
and asserting the array contains both expected substrings in any order (e.g.,
use messages.map(String) with expect.arrayContaining and expect.stringContaining
for '<sup>' and '</sup>'), or assert that there exists some element matching
each substring using .some; update the assertions around the messages variable
accordingly.
In `@packages/export/test/export-pdf-core/utils/convertPathToPosix.test.ts`:
- Around line 6-45: Tests currently only cover non-Windows passthroughs; add 1–2
Windows-specific assertions to exercise the win32 conversion branch in
convertPathToPosix by passing a backslash path (e.g. 'C:\\Users\\me\\file.pdf')
and a DOS-device-prefixed path (e.g. '\\\\?\\C:\\path\\file.pdf') and assert
they are converted to POSIX-style paths ('/c/Users/me/file.pdf' or
'/c/path/file.pdf' respectively) so the normalization logic and prefix handling
in convertPathToPosix are exercised.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: b6ebf20f-3043-481a-8f74-f89f9a6ec456
⛔ Files ignored due to path filters (1)
yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (32)
.github/workflows/ci.ymlpackage.jsonpackages/doom/rstest.config.tspackages/doom/test/plugins/replace/parse-toc.test.tspackages/doom/test/plugins/replace/utils.test.tspackages/doom/test/remark-lint/_helper.tspackages/doom/test/remark-lint/list-item-punctuation.test.tspackages/doom/test/remark-lint/list-item-size.test.tspackages/doom/test/remark-lint/list-table-introduction.test.tspackages/doom/test/remark-lint/maximum-link-content-length.test.tspackages/doom/test/remark-lint/no-deep-heading.test.tspackages/doom/test/remark-lint/no-deep-list.test.tspackages/doom/test/remark-lint/no-empty-table-cell.test.tspackages/doom/test/remark-lint/no-heading-punctuation.test.tspackages/doom/test/remark-lint/no-heading-special-characters.test.tspackages/doom/test/remark-lint/no-heading-sup-sub.test.tspackages/doom/test/remark-lint/no-multi-open-api-paths.test.tspackages/doom/test/remark-lint/no-paragraph-indent.test.tspackages/doom/test/remark-lint/table-size.test.tspackages/doom/test/remark-lint/unit-case.test.tspackages/doom/test/tsconfig.jsonpackages/doom/test/utils/helpers.test.tspackages/export/rstest.config.tspackages/export/test/export-pdf-core/utils/convertPathToPosix.test.tspackages/export/test/export-pdf-core/utils/getUrlLink.test.tspackages/export/test/html-export-pdf/utils/isValidUrl.test.tspackages/export/test/html-export-pdf/utils/replaceExt.test.tspackages/export/test/merge-pdfs/formatDate.test.tspackages/export/test/tsconfig.jsonrstest.config.tstsconfig.jsontsconfig.test.json
- Add @rstest/core with root + per-package configs - Add 115 tests covering remark-lint rules, plugins, and utility functions - Add tsconfig.test.json and per-test-directory tsconfigs for ESLint project service - Integrate test step into CI workflow
- Update root AGENTS.md with detailed project structure, conventions, and commands - Add per-directory AGENTS.md for doom and export packages - Add OpenSpec skills and commands for change management - Add openspec config and archived change artifacts
b78081e to
9236145
Compare
There was a problem hiding this comment.
Actionable comments posted: 10
♻️ Duplicate comments (2)
packages/doom/test/plugins/replace/parse-toc.spec.ts (1)
111-119:⚠️ Potential issue | 🟡 MinorRename this test to match what it asserts.
Line 111 says “skips h1…”, but Line 117 asserts
depth === 1(included). Please rename the case for semantic correctness.Suggested rename
- test('skips h1 from toc when allDepths is true', () => { + test('includes h1 in toc when allDepths is true', () => {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/doom/test/plugins/replace/parse-toc.spec.ts` around lines 111 - 119, The test named "skips h1 from toc when allDepths is true" is misnamed because it asserts h1 is included; update the test title string in the test that calls parseToc(tree, true) (the test block around parseToc and expect(toc[0]?.depth).toBe(1)) to accurately describe the assertion—e.g., rename it to "includes h1 in toc when allDepths is true" or similar so the description matches the asserts.packages/doom/test/plugins/replace/utils.spec.ts (1)
129-149:⚠️ Potential issue | 🟠 MajorAssert the expected duplicate-name error emission in this test.
Line 129 exercises a path that emits an error-level log in
normalizeReferenceItems; the test currently validates only result shape. Please explicitly capture/assert the expected duplicate-source emission so CI doesn’t treat it as unexpected error output.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/doom/test/plugins/replace/utils.spec.ts` around lines 129 - 149, The test "overwrites earlier entry on duplicate source name" needs to assert that normalizeReferenceItems emits the expected duplicate-source error; update that test to spy on the error logger (e.g., jest.spyOn(console, 'error') or the project's logger used by normalizeReferenceItems), call normalizeReferenceItems(items), assert the error logger was called once with a message containing the duplicate source name "config" (or the word "duplicate"), then restore the spy; keep the existing result shape assertions for path and anchor.
🧹 Nitpick comments (13)
AGENTS.md (2)
9-18: Add language identifier to fenced code block.The fenced code block should specify a language identifier for proper syntax highlighting and linting compliance.
📝 Suggested fix
-``` +```text doom/ ├── packages/doom/ # Main package: CLI, theme, runtime, plugins, remark-lint🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@AGENTS.md` around lines 9 - 18, The fenced code block in AGENTS.md is missing a language identifier; update the opening fence from ``` to a language-specific fence (e.g., ```text or ```bash) so markdown linting and syntax highlighting work correctly for the directory tree example; locate the triple-backtick block that contains the doom/ tree and change it to use a language identifier (for example, replace ``` with ```text).
55-68: Add language identifier to commands code block.The bash commands block should specify
bashas the language identifier.📝 Suggested fix
-```bash +```bash yarn install # Install deps (Yarn 4 Berry)Note: The opening fence should be
```bash(it appears to already havebashin the code, so this may be correctly specified).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@AGENTS.md` around lines 55 - 68, The commands code block in AGENTS.md is missing an explicit language fence identifier; update the opening fence for the shown commands block to include "bash" (i.e., change the opening "```" to "```bash") so the block is syntax-highlighted properly and ensure the closing fence remains "```"; locate the commands block in the file that lists yarn install / yarn build / yarn dev etc. and apply this single-line change.packages/export/AGENTS.md (1)
7-21: Add language identifier to fenced code block.The fenced code block should specify a language identifier for proper syntax highlighting and linting compliance.
📝 Suggested fix
-``` +```text src/ ├── export-pdf-core/ # Core pipeline: generatePdf, types, utils🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/export/AGENTS.md` around lines 7 - 21, In AGENTS.md update the fenced code block that shows the src/ tree to include a language identifier (e.g., change the opening ``` to ```text) so the block is recognized for syntax highlighting and linting; locate the tree block in packages/export/AGENTS.md (the triple-backtick section containing "src/" and the nested directories) and add the identifier to the opening fence only.packages/doom/src/runtime/AGENTS.md (1)
7-16: Add language identifier to fenced code block.The fenced code block should specify a language identifier for proper syntax highlighting and linting compliance.
📝 Suggested fix
-``` +```text ├── components/ # React components for docs rendering │ ├── _K8sAPIEndpoints.tsx # K8s API endpoints tables (577 lines — hotspot) │ ├── OpenAPIPath.tsx # OpenAPI path details with recursive schema resolution (359 lines — hotspot)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/doom/src/runtime/AGENTS.md` around lines 7 - 16, The fenced code block showing the directory tree in AGENTS.md lacks a language identifier; update the opening fence for that snippet (the block containing components/, hooks/, index.ts, translation.ts, utils.ts) to include a language (e.g., change the opening ``` to ```text) so markdown linters and syntax highlighters treat it correctly.packages/doom/AGENTS.md (1)
7-23: Add language identifier to fenced code block.The fenced code block should specify a language identifier for proper syntax highlighting and linting compliance.
📝 Suggested fix
-``` +```text src/ ├── cli/ # Commander CLI: build, dev, export, lint, new, translate🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/doom/AGENTS.md` around lines 7 - 23, The fenced code block showing the project tree lacks a language identifier; update the opening fence from ``` to ```text so the block becomes a "text" fenced code block for proper syntax highlighting and linting compliance and leave the closing fence unchanged; locate the block that contains the ASCII tree (the triple-backtick block in AGENTS.md) and add the "text" identifier to its opening fence.packages/doom/test/remark-lint/no-heading-sup-sub.spec.ts (1)
14-16: Avoid index-order coupling in message assertions.The two-message expectation is correct, but asserting by fixed indices is brittle. Prefer order-independent checks.
More robust assertion pattern
test('flags heading with sup', async () => { const messages = await lint(noHeadingSupSub, '## Title <sup>beta</sup>\n') expect(messages).toHaveLength(2) - expect(String(messages[0])).toContain('<sup>') - expect(String(messages[1])).toContain('</sup>') + const rendered = messages.map(String) + expect(rendered.some((m) => m.includes('<sup>'))).toBe(true) + expect(rendered.some((m) => m.includes('</sup>'))).toBe(true) })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/doom/test/remark-lint/no-heading-sup-sub.spec.ts` around lines 14 - 16, The test currently couples to message order by asserting String(messages[0]) and String(messages[1]); change the assertions to be order-independent by mapping messages to strings (e.g., texts = messages.map(String)) and then asserting texts contains both expected substrings (e.g., using expect.arrayContaining or two expect(texts).toEqual(expect.arrayContaining([...]))), keeping the existing expect(messages).toHaveLength(2) and checking for '<sup>' and '</sup>' presence without relying on indices.packages/doom/test/remark-lint/list-table-introduction.spec.ts (1)
7-23: Add table-path tests for full rule coverage.This suite currently validates only list behavior, but the rule enforces both
listandtableintroductions.Proposed test additions
describe('list-table-introduction', () => { test('allows list after paragraph', async () => { @@ test('flags list right after heading', async () => { @@ expect(String(messages[0])).toContain('introduct') }) + + test('allows table after paragraph', async () => { + const messages = await lint( + listTableIntroduction, + '# Heading\n\nIntroduction paragraph.\n\n| A |\n|---|\n| B |\n', + ) + expect(messages).toHaveLength(0) + }) + + test('flags table right after heading', async () => { + const messages = await lint( + listTableIntroduction, + '# Heading\n\n| A |\n|---|\n| B |\n', + ) + expect(messages).toHaveLength(1) + expect(String(messages[0])).toContain('introduct') + }) })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/doom/test/remark-lint/list-table-introduction.spec.ts` around lines 7 - 23, The test suite for listTableIntroduction only covers lists; add parallel tests for tables to cover the rule's table-path: create a test that lints a heading + paragraph + a simple markdown table and expects zero messages (allows table after paragraph), and a test that lints a heading immediately followed by a table and expects one message (flags table right after heading) asserting the diagnostic contains the same 'introduct' text; use the same lint helper and the listTableIntroduction rule and mirror the structure of the existing list tests..opencode/skills/openspec-archive-change/SKILL.md (3)
68-84: Consider adding source directory validation.The archive operation assumes
openspec/changes/<name>exists. While likely validated earlier by theopenspec statuscommand, adding an explicit check before themvcommand would make the workflow more robust and provide better error messages if the directory doesn't exist.🛡️ Optional validation step
Add before the
mvcommand:**Check if target already exists:** - If yes: Fail with error, suggest renaming existing archive or using different date - If no: Move the change directory to archive + + **Verify source exists:** + ```bash + test -d openspec/changes/<name> || { echo "Error: Change directory not found"; exit 1; } + ``` ```bash mv openspec/changes/<name> openspec/changes/archive/YYYY-MM-DD-<name></details> <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against the current code and only fix it if needed.
In @.opencode/skills/openspec-archive-change/SKILL.md around lines 68 - 84, The
archive step assumes the source directory openspec/changes/ exists before
running the mv command; add an explicit check (e.g., verify the directory exists
with a directory test) immediately before the mv to fail fast with a clear error
message if it does not, then only perform mv openspec/changes/
openspec/changes/archive/YYYY-MM-DD- when the check passes; reference the
existing mv operation and the source path openspec/changes/ when adding
this validation.</details> --- `54-66`: **Clarify capability resolution and missing main spec handling.** The delta spec comparison logic (line 58) references `openspec/specs/<capability>/spec.md` but doesn't explain: - How `<capability>` is determined from the delta spec path structure - What to do if the corresponding main spec doesn't exist (new capability being added) Consider adding a note about how the capability path is derived and handling the case where the main spec is missing (which would indicate all changes are additions). <details> <summary>📝 Suggested clarification</summary> Add after line 58: ```diff **If delta specs exist:** - Compare each delta spec with its corresponding main spec at `openspec/specs/<capability>/spec.md` + (capability is derived from the delta spec directory structure) + - If main spec doesn't exist, treat all delta spec content as additions (new capability) - Determine what changes would be applied (adds, modifications, removals, renames)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.opencode/skills/openspec-archive-change/SKILL.md around lines 54 - 66, Clarify how the `<capability>` is derived from a delta spec path and explicitly describe handling when the main spec is absent: state that `<capability>` is the directory name directly under openspec/changes/<name>/specs/ (e.g., openspec/changes/<name>/specs/<capability>/delta.md maps to openspec/specs/<capability>/spec.md), and if openspec/specs/<capability>/spec.md does not exist treat the delta as a new capability (all changes are additions) and include that as part of the combined summary passed into the Task tool prompt (the Task invocation remains: subagent_type: "general-purpose", prompt: "Use Skill tool to invoke openspec-sync-specs for change '<name>'. Delta spec analysis: <include the analyzed delta spec summary>").
95-106: Static analysis hint: Fenced block language is intentionally omitted.The markdownlint warning about the missing language identifier on line 97 is a false positive—this block shows example output format, not executable code. You may suppress this warning or add a comment explaining the intent.
💡 Optional: Suppress or clarify
Option 1 - Add language as
text:-``` +```text ## Archive CompleteOption 2 - Add markdownlint disable comment:
<!-- markdownlint-disable-next-line MD040 -->🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.opencode/skills/openspec-archive-change/SKILL.md around lines 95 - 106, The fenced code block under the "Output On Success" example triggers a markdownlint MD040 false positive; fix by either adding a language identifier (e.g., change the fence to ```text) or add a markdownlint disable comment immediately before the block (<!-- markdownlint-disable-next-line MD040 -->) so the example output remains unchanged while suppressing the warning; locate the fenced block shown in the SKILL.md snippet labeled "## Archive Complete" and apply one of these two small edits..opencode/skills/openspec-apply-change/SKILL.md (2)
18-25: Intentional selection behavior difference from archive workflow.This skill allows auto-selection when only one active change exists (line 22), while the archive skill explicitly forbids auto-selection (archive SKILL.md line 25). This difference appears intentional—apply is a working session where convenience is valued, while archive is a finalization step requiring explicit confirmation.
The "always announce" requirement (line 25) helps prevent confusion. Consider adding a brief note explaining this design choice to clarify why apply and archive differ in their selection strictness.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.opencode/skills/openspec-apply-change/SKILL.md around lines 18 - 25, Add a short clarifying sentence to the "Select the change" section explaining why apply allows auto-selection while archive forbids it: state that the apply workflow prioritizes convenience for an active working session (so auto-select when only one active change exists) whereas the archive workflow is a finalization step that requires explicit user confirmation, and remind users that the skill still announces "Using change: <name>" and how to override (e.g., `/opsx-apply <other>`); reference the existing behavior descriptions like the auto-select rule, the `openspec list --json` + AskUserQuestion flow, and the archive SKILL.md explicit-forbid rule when adding the note.
154-159: Static analysis hint is a false positive.The LanguageTool suggestion about a "missing subject" on line 158 is flagging the bullet point fragment "Can be invoked anytime". This is acceptable style in bulleted lists where the context is clear from the heading and list structure.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.opencode/skills/openspec-apply-change/SKILL.md around lines 154 - 159, The LanguageTool false positive flags the fragment "Can be invoked anytime" under the "Fluid Workflow Integration" heading; fix it by making the bullet a grammatically complete sentence (e.g., change the bullet text for the item referencing invocation timing to start with "It can be invoked anytime" or otherwise prepend a subject) so the list remains stylistically the same but satisfies the static analysis; update the bullet that currently reads "Can be invoked anytime" (and any similar fragments) accordingly..opencode/command/opsx-archive.md (1)
46-59: Static analysis hint appears to be a false positive.The markdownlint warning about line 59 lacking a language identifier doesn't correspond to a fenced code block. Line 59 is regular prose text. This may be a tool reporting error.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.opencode/command/opsx-archive.md around lines 46 - 59, The markdownlint warning about a fenced code block lacking a language identifier (MD040) appears to be a false positive for the "Prompt options:" / delta-specs prose block that contains inline backtick paths like `openspec/changes/<name>/specs/`; to silence the linter without changing content, wrap that section with a markdownlint rule disable/enable comment for MD040 (place a markdownlint-disable MD040 before the "Assess delta spec sync state" / "Prompt options:" block and a markdownlint-enable MD040 after it) so the linter ignores this false positive while keeping the text and inline code spans intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.opencode/command/opsx-apply.md:
- Around line 87-97: Update the Markdown fenced code blocks in the examples to
include a language identifier (e.g., text or md) so MD040 is satisfied: locate
the example blocks containing "## Implementing: <change-name> (schema:
<schema-name>)", "## Implementation Complete", and "## Implementation Paused"
and change their opening fences from ``` to ```text (or ```md) consistently;
apply the same fix to the other occurrences noted (lines around 101-114 and
118-134) so all example fences include a language tag.
In @.opencode/command/opsx-explore.md:
- Around line 59-74: The fenced ASCII diagram block currently has an unlabeled
triple-backtick; update that code fence to include a language tag (e.g., change
the opening ``` to ```text) so the block is recognized as plain text and
satisfies MD040; locate the ASCII diagram block (the triple-backtick block
containing the box diagram and the lines "Use ASCII diagrams liberally" /
"System diagrams, state machines...") and only modify the opening fence to
include the language label.
In @.opencode/skills/openspec-explore/SKILL.md:
- Around line 58-73: The markdown has multiple fenced code blocks missing
language tags (causing MD040 failures); update each fenced block in SKILL.md
(notably the ASCII diagram block and the example conversation/code blocks around
the "What We Figured Out" section and ranges ~58-73, 157-177, 181-209, 213-227,
231-257, 272-284) by adding a language tag such as text (e.g., change ``` to
```text) so every fenced block is labeled consistently; ensure you apply this to
the ASCII diagram, all user/input examples, and any other unlabeled fences to
satisfy MD040.
In `@AGENTS.md`:
- Line 46: Replace the incorrect sentence "No unit test runner exists" in
AGENTS.md with an updated statement that rstest has been introduced as the unit
test framework (covering ~115 tests) and is integrated into CI; mention how
tests are run (e.g., via rstest in the CI pipeline) and optionally point readers
to the test directory or CI workflow for details so the doc reflects the new
test infrastructure.
- Line 72: Update the CI tasks list in AGENTS.md by adding "test" to the
parallel tasks description: change the line that reads "**CI matrix**: Node [20,
22, 24] — runs `build`, `docs`, `lint`, `typecov` in parallel" so it includes
`test` among the backticked task names (i.e., `build`, `docs`, `lint`,
`typecov`, `test`) to reflect the workflow change.
- Around line 55-68: Add entries for the new test scripts to the COMMANDS
section by documenting the two new CLI targets: "yarn test" (run the test suite
once) and "yarn test:watch" (run tests in watch mode). Update the COMMANDS block
where other yarn scripts are listed to include short descriptions for yarn test
and yarn test:watch so readers know their purpose and usage, referencing the new
command names exactly.
In `@openspec/changes/archive/2026-04-09-add-rstest-unit-tests/design.md`:
- Around line 69-72: The design doc claims that rstest.config.ts uses a root
"projects" array and that package.json's typeCoverage ignore list contains
"**/test/**", but the implemented files differ; either update the implementation
to match the design by adding a root projects: ['packages/*'] to
rstest.config.ts and add "**/test/**" to the typeCoverage.ignore list in
package.json, or update the archived design text to reflect the actual configs
(remove the "projects" statement and correct the ignore list description).
Locate and update the referenced symbols rstest.config.ts (add or remove the
projects key) and the package.json typeCoverage.ignore array (add or remove the
"**/test/**" pattern) so the design and implementation are consistent.
- Line 43: The fenced code block triggering markdownlint MD040 needs a language
tag; update the opening fence from ``` to ```text (or another appropriate
language) for the block that starts with "packages/doom/test/" so the snippet is
explicitly labeled (e.g., replace the fence surrounding the tree listing in
design.md with ```text).
In `@openspec/changes/archive/2026-04-09-add-rstest-unit-tests/tasks.md`:
- Around line 5-6: Task list items reference "*.test.ts" globs but the
repository uses "*.spec.ts"; update the documented globs and file patterns in
openspec/changes/archive/2026-04-09-add-rstest-unit-tests/tasks.md so they match
the actual files (e.g. change "test/**/*.test.ts" and "*.test.ts" to
"test/**/*.spec.ts" and "*.spec.ts") for the entries that mention creating
packages/doom/rstest.config.ts and packages/export/rstest.config.ts and apply
the same replacement across sections 2–5 to keep all task items and examples
consistent.
In `@packages/export/test/merge-pdfs/formatDate.spec.ts`:
- Line 6: The test title in the call to test(...) uses double quotes; update the
test invocation in formatDate.spec.ts so the test name string uses single quotes
(replace test("formats date in D:YYYYMMDDHHmmSS±HH'mm' pattern", ...) with
test('formats date in D:YYYYMMDDHHmmSS±HH\'mm\' pattern', ...)), ensuring any
inner single quote in the title is properly escaped; leave the rest of the test
body unchanged.
---
Duplicate comments:
In `@packages/doom/test/plugins/replace/parse-toc.spec.ts`:
- Around line 111-119: The test named "skips h1 from toc when allDepths is true"
is misnamed because it asserts h1 is included; update the test title string in
the test that calls parseToc(tree, true) (the test block around parseToc and
expect(toc[0]?.depth).toBe(1)) to accurately describe the assertion—e.g., rename
it to "includes h1 in toc when allDepths is true" or similar so the description
matches the asserts.
In `@packages/doom/test/plugins/replace/utils.spec.ts`:
- Around line 129-149: The test "overwrites earlier entry on duplicate source
name" needs to assert that normalizeReferenceItems emits the expected
duplicate-source error; update that test to spy on the error logger (e.g.,
jest.spyOn(console, 'error') or the project's logger used by
normalizeReferenceItems), call normalizeReferenceItems(items), assert the error
logger was called once with a message containing the duplicate source name
"config" (or the word "duplicate"), then restore the spy; keep the existing
result shape assertions for path and anchor.
---
Nitpick comments:
In @.opencode/command/opsx-archive.md:
- Around line 46-59: The markdownlint warning about a fenced code block lacking
a language identifier (MD040) appears to be a false positive for the "Prompt
options:" / delta-specs prose block that contains inline backtick paths like
`openspec/changes/<name>/specs/`; to silence the linter without changing
content, wrap that section with a markdownlint rule disable/enable comment for
MD040 (place a markdownlint-disable MD040 before the "Assess delta spec sync
state" / "Prompt options:" block and a markdownlint-enable MD040 after it) so
the linter ignores this false positive while keeping the text and inline code
spans intact.
In @.opencode/skills/openspec-apply-change/SKILL.md:
- Around line 18-25: Add a short clarifying sentence to the "Select the change"
section explaining why apply allows auto-selection while archive forbids it:
state that the apply workflow prioritizes convenience for an active working
session (so auto-select when only one active change exists) whereas the archive
workflow is a finalization step that requires explicit user confirmation, and
remind users that the skill still announces "Using change: <name>" and how to
override (e.g., `/opsx-apply <other>`); reference the existing behavior
descriptions like the auto-select rule, the `openspec list --json` +
AskUserQuestion flow, and the archive SKILL.md explicit-forbid rule when adding
the note.
- Around line 154-159: The LanguageTool false positive flags the fragment "Can
be invoked anytime" under the "Fluid Workflow Integration" heading; fix it by
making the bullet a grammatically complete sentence (e.g., change the bullet
text for the item referencing invocation timing to start with "It can be invoked
anytime" or otherwise prepend a subject) so the list remains stylistically the
same but satisfies the static analysis; update the bullet that currently reads
"Can be invoked anytime" (and any similar fragments) accordingly.
In @.opencode/skills/openspec-archive-change/SKILL.md:
- Around line 68-84: The archive step assumes the source directory
openspec/changes/<name> exists before running the mv command; add an explicit
check (e.g., verify the directory exists with a directory test) immediately
before the mv to fail fast with a clear error message if it does not, then only
perform mv openspec/changes/<name> openspec/changes/archive/YYYY-MM-DD-<name>
when the check passes; reference the existing mv operation and the source path
openspec/changes/<name> when adding this validation.
- Around line 54-66: Clarify how the `<capability>` is derived from a delta spec
path and explicitly describe handling when the main spec is absent: state that
`<capability>` is the directory name directly under
openspec/changes/<name>/specs/ (e.g.,
openspec/changes/<name>/specs/<capability>/delta.md maps to
openspec/specs/<capability>/spec.md), and if openspec/specs/<capability>/spec.md
does not exist treat the delta as a new capability (all changes are additions)
and include that as part of the combined summary passed into the Task tool
prompt (the Task invocation remains: subagent_type: "general-purpose", prompt:
"Use Skill tool to invoke openspec-sync-specs for change '<name>'. Delta spec
analysis: <include the analyzed delta spec summary>").
- Around line 95-106: The fenced code block under the "Output On Success"
example triggers a markdownlint MD040 false positive; fix by either adding a
language identifier (e.g., change the fence to ```text) or add a markdownlint
disable comment immediately before the block (<!--
markdownlint-disable-next-line MD040 -->) so the example output remains
unchanged while suppressing the warning; locate the fenced block shown in the
SKILL.md snippet labeled "## Archive Complete" and apply one of these two small
edits.
In `@AGENTS.md`:
- Around line 9-18: The fenced code block in AGENTS.md is missing a language
identifier; update the opening fence from ``` to a language-specific fence
(e.g., ```text or ```bash) so markdown linting and syntax highlighting work
correctly for the directory tree example; locate the triple-backtick block that
contains the doom/ tree and change it to use a language identifier (for example,
replace ``` with ```text).
- Around line 55-68: The commands code block in AGENTS.md is missing an explicit
language fence identifier; update the opening fence for the shown commands block
to include "bash" (i.e., change the opening "```" to "```bash") so the block is
syntax-highlighted properly and ensure the closing fence remains "```"; locate
the commands block in the file that lists yarn install / yarn build / yarn dev
etc. and apply this single-line change.
In `@packages/doom/AGENTS.md`:
- Around line 7-23: The fenced code block showing the project tree lacks a
language identifier; update the opening fence from ``` to ```text so the block
becomes a "text" fenced code block for proper syntax highlighting and linting
compliance and leave the closing fence unchanged; locate the block that contains
the ASCII tree (the triple-backtick block in AGENTS.md) and add the "text"
identifier to its opening fence.
In `@packages/doom/src/runtime/AGENTS.md`:
- Around line 7-16: The fenced code block showing the directory tree in
AGENTS.md lacks a language identifier; update the opening fence for that snippet
(the block containing components/, hooks/, index.ts, translation.ts, utils.ts)
to include a language (e.g., change the opening ``` to ```text) so markdown
linters and syntax highlighters treat it correctly.
In `@packages/doom/test/remark-lint/list-table-introduction.spec.ts`:
- Around line 7-23: The test suite for listTableIntroduction only covers lists;
add parallel tests for tables to cover the rule's table-path: create a test that
lints a heading + paragraph + a simple markdown table and expects zero messages
(allows table after paragraph), and a test that lints a heading immediately
followed by a table and expects one message (flags table right after heading)
asserting the diagnostic contains the same 'introduct' text; use the same lint
helper and the listTableIntroduction rule and mirror the structure of the
existing list tests.
In `@packages/doom/test/remark-lint/no-heading-sup-sub.spec.ts`:
- Around line 14-16: The test currently couples to message order by asserting
String(messages[0]) and String(messages[1]); change the assertions to be
order-independent by mapping messages to strings (e.g., texts =
messages.map(String)) and then asserting texts contains both expected substrings
(e.g., using expect.arrayContaining or two
expect(texts).toEqual(expect.arrayContaining([...]))), keeping the existing
expect(messages).toHaveLength(2) and checking for '<sup>' and '</sup>' presence
without relying on indices.
In `@packages/export/AGENTS.md`:
- Around line 7-21: In AGENTS.md update the fenced code block that shows the
src/ tree to include a language identifier (e.g., change the opening ``` to
```text) so the block is recognized for syntax highlighting and linting; locate
the tree block in packages/export/AGENTS.md (the triple-backtick section
containing "src/" and the nested directories) and add the identifier to the
opening fence only.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: f0b45433-24ac-433c-a3ac-33f6e8fb5c82
⛔ Files ignored due to path filters (1)
yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (52)
.github/workflows/ci.yml.opencode/command/opsx-apply.md.opencode/command/opsx-archive.md.opencode/command/opsx-explore.md.opencode/command/opsx-propose.md.opencode/skills/openspec-apply-change/SKILL.md.opencode/skills/openspec-archive-change/SKILL.md.opencode/skills/openspec-explore/SKILL.md.opencode/skills/openspec-propose/SKILL.mdAGENTS.mdopenspec/changes/archive/2026-04-09-add-rstest-unit-tests/.openspec.yamlopenspec/changes/archive/2026-04-09-add-rstest-unit-tests/design.mdopenspec/changes/archive/2026-04-09-add-rstest-unit-tests/proposal.mdopenspec/changes/archive/2026-04-09-add-rstest-unit-tests/specs/remark-lint-tests/spec.mdopenspec/changes/archive/2026-04-09-add-rstest-unit-tests/specs/test-infrastructure/spec.mdopenspec/changes/archive/2026-04-09-add-rstest-unit-tests/specs/utility-tests/spec.mdopenspec/changes/archive/2026-04-09-add-rstest-unit-tests/tasks.mdopenspec/config.yamlpackage.jsonpackages/doom/AGENTS.mdpackages/doom/src/cli/AGENTS.mdpackages/doom/src/plugins/AGENTS.mdpackages/doom/src/remark-lint/AGENTS.mdpackages/doom/src/runtime/AGENTS.mdpackages/doom/src/theme/AGENTS.mdpackages/doom/test/plugins/replace/parse-toc.spec.tspackages/doom/test/plugins/replace/utils.spec.tspackages/doom/test/remark-lint/_helper.tspackages/doom/test/remark-lint/list-item-punctuation.spec.tspackages/doom/test/remark-lint/list-item-size.spec.tspackages/doom/test/remark-lint/list-table-introduction.spec.tspackages/doom/test/remark-lint/maximum-link-content-length.spec.tspackages/doom/test/remark-lint/no-deep-heading.spec.tspackages/doom/test/remark-lint/no-deep-list.spec.tspackages/doom/test/remark-lint/no-empty-table-cell.spec.tspackages/doom/test/remark-lint/no-heading-punctuation.spec.tspackages/doom/test/remark-lint/no-heading-special-characters.spec.tspackages/doom/test/remark-lint/no-heading-sup-sub.spec.tspackages/doom/test/remark-lint/no-multi-open-api-paths.spec.tspackages/doom/test/remark-lint/no-paragraph-indent.spec.tspackages/doom/test/remark-lint/table-size.spec.tspackages/doom/test/remark-lint/unit-case.spec.tspackages/doom/test/utils/helpers.spec.tspackages/doom/tsconfig.jsonpackages/export/AGENTS.mdpackages/export/test/export-pdf-core/utils/convertPathToPosix.spec.tspackages/export/test/export-pdf-core/utils/getUrlLink.spec.tspackages/export/test/html-export-pdf/utils/isValidUrl.spec.tspackages/export/test/html-export-pdf/utils/replaceExt.spec.tspackages/export/test/merge-pdfs/formatDate.spec.tspackages/export/tsconfig.jsonrstest.config.ts
💤 Files with no reviewable changes (2)
- packages/doom/tsconfig.json
- packages/export/tsconfig.json
✅ Files skipped from review due to trivial changes (16)
- openspec/changes/archive/2026-04-09-add-rstest-unit-tests/.openspec.yaml
- packages/doom/test/remark-lint/no-paragraph-indent.spec.ts
- packages/doom/test/remark-lint/maximum-link-content-length.spec.ts
- packages/doom/test/remark-lint/no-heading-punctuation.spec.ts
- packages/export/test/export-pdf-core/utils/convertPathToPosix.spec.ts
- packages/doom/src/theme/AGENTS.md
- packages/export/test/html-export-pdf/utils/isValidUrl.spec.ts
- openspec/changes/archive/2026-04-09-add-rstest-unit-tests/proposal.md
- packages/doom/src/cli/AGENTS.md
- packages/doom/src/remark-lint/AGENTS.md
- packages/doom/src/plugins/AGENTS.md
- openspec/config.yaml
- packages/doom/test/remark-lint/_helper.ts
- openspec/changes/archive/2026-04-09-add-rstest-unit-tests/specs/utility-tests/spec.md
- openspec/changes/archive/2026-04-09-add-rstest-unit-tests/specs/test-infrastructure/spec.md
- openspec/changes/archive/2026-04-09-add-rstest-unit-tests/specs/remark-lint-tests/spec.md
🚧 Files skipped from review as they are similar to previous changes (3)
- .github/workflows/ci.yml
- rstest.config.ts
- package.json
openspec/changes/archive/2026-04-09-add-rstest-unit-tests/tasks.md
Outdated
Show resolved
Hide resolved
commit: |
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (3)
openspec/changes/archive/2026-04-09-add-rstest-unit-tests/design.md (2)
43-43:⚠️ Potential issue | 🟡 MinorAdd a language identifier to the tree code fence.
Line [43] triggers MD040; please annotate this fence as
text.Suggested fix
-``` +```text packages/doom/test/ ├── remark-lint/ │ ├── _helper.ts # Shared lint rule test helper ... -``` +```🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@openspec/changes/archive/2026-04-09-add-rstest-unit-tests/design.md` at line 43, The code fence that begins before the tree listing (the block starting with ``` and containing "packages/doom/test/") needs a language identifier to satisfy MD040; change the opening fence from ``` to ```text so the fence is annotated as text.
69-69:⚠️ Potential issue | 🟡 MinorDesign decisions are out of sync with current config snippets.
Line [69] and Line [112]-Line [114] document concrete settings (
projects: ['packages/*'],typeCoverage.ignoreFilesincluding**/test/**) that don’t match the referenced current files (rstest.config.ts,package.json). Please align either implementation or archived design text so readers aren’t misled.Also applies to: 112-114
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@openspec/changes/archive/2026-04-09-add-rstest-unit-tests/design.md` at line 69, Update the archived design text to match the current config (or vice versa) by synchronizing the documented settings with the actual rstest.config.ts and package.json: either change the design statement that claims "Root `rstest.config.ts` with `projects: ['packages/*']`" to reflect the real `projects` value in your current rstest.config.ts, and update the documented `typeCoverage.ignoreFiles` entries (e.g., remove or alter `**/test/**`) to match the actual package.json/type-coverage config, or update the configs to match the documented design; ensure you update both the single-line decision at "Root `rstest.config.ts`..." and the later paragraph referencing `typeCoverage.ignoreFiles` so they are identical to the real `projects` and `typeCoverage` settings.AGENTS.md (1)
54-68:⚠️ Potential issue | 🟡 MinorDocument
yarn test:watchin COMMANDS for parity with scripts.Line [54]-Line [68] includes
yarn testbut missesyarn test:watch, which exists in rootpackage.jsonscripts.Suggested addition
yarn test # Unit tests (rstest) +yarn test:watch # Unit tests in watch mode yarn typecov # Type coverage check (must be 100%)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@AGENTS.md` around lines 54 - 68, Add the missing yarn test:watch entry to the COMMANDS list next to yarn test; update the AGENTS.md commands block that currently lists "yarn test" to also include "yarn test:watch" with a brief description (e.g., "Unit tests in watch mode") so it matches the root package.json scripts and provides parity for developers.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/doom/AGENTS.md`:
- Line 7: Change the opening fenced code block delimiter from ``` to include a
language tag (e.g., ```text) in the AGENTS.md file so the block is labeled and
satisfies MD040; locate the fenced block starting with ``` (the triple backticks
surrounding the src/ tree) and update the opener to ```text while leaving the
closing ``` unchanged.
In `@packages/doom/test/plugins/replace/utils.spec.ts`:
- Around line 170-210: The getFrontmatterNode utility can throw on an empty AST
because it accesses firstNode.type without a guard; update getFrontmatterNode in
packages/doom/src/plugins/replace/utils.ts to first-check that the tree/root and
root.children exist and that root.children[0] (or firstNode) is defined before
reading .type, returning undefined for empty documents, and add an extra test in
packages/doom/test/plugins/replace/utils.spec.ts that calls
parseMarkdownWithFrontmatter('') and asserts getFrontmatterNode(...) returns
undefined (and does not throw) to cover the empty-document case.
In `@packages/export/AGENTS.md`:
- Line 7: The fenced code block containing the tree listing in AGENTS.md is
missing a language tag (causing MD040); update the opening fence for that block
to include the language identifier "text" so the block starts with ```text and
the rest of the file remains unchanged.
---
Duplicate comments:
In `@AGENTS.md`:
- Around line 54-68: Add the missing yarn test:watch entry to the COMMANDS list
next to yarn test; update the AGENTS.md commands block that currently lists
"yarn test" to also include "yarn test:watch" with a brief description (e.g.,
"Unit tests in watch mode") so it matches the root package.json scripts and
provides parity for developers.
In `@openspec/changes/archive/2026-04-09-add-rstest-unit-tests/design.md`:
- Line 43: The code fence that begins before the tree listing (the block
starting with ``` and containing "packages/doom/test/") needs a language
identifier to satisfy MD040; change the opening fence from ``` to ```text so the
fence is annotated as text.
- Line 69: Update the archived design text to match the current config (or vice
versa) by synchronizing the documented settings with the actual rstest.config.ts
and package.json: either change the design statement that claims "Root
`rstest.config.ts` with `projects: ['packages/*']`" to reflect the real
`projects` value in your current rstest.config.ts, and update the documented
`typeCoverage.ignoreFiles` entries (e.g., remove or alter `**/test/**`) to match
the actual package.json/type-coverage config, or update the configs to match the
documented design; ensure you update both the single-line decision at "Root
`rstest.config.ts`..." and the later paragraph referencing
`typeCoverage.ignoreFiles` so they are identical to the real `projects` and
`typeCoverage` settings.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: def815a1-cfda-4034-bdcd-3489653a065d
📒 Files selected for processing (34)
AGENTS.mdopenspec/changes/archive/2026-04-09-add-rstest-unit-tests/design.mdopenspec/changes/archive/2026-04-09-add-rstest-unit-tests/proposal.mdopenspec/changes/archive/2026-04-09-add-rstest-unit-tests/tasks.mdpackage.jsonpackages/doom/AGENTS.mdpackages/doom/package.jsonpackages/doom/src/plugins/AGENTS.mdpackages/doom/src/remark-lint/AGENTS.mdpackages/doom/test/plugins/replace/parse-toc.spec.tspackages/doom/test/plugins/replace/utils.spec.tspackages/doom/test/remark-lint/_helper.tspackages/doom/test/remark-lint/list-item-punctuation.spec.tspackages/doom/test/remark-lint/list-item-size.spec.tspackages/doom/test/remark-lint/list-table-introduction.spec.tspackages/doom/test/remark-lint/maximum-link-content-length.spec.tspackages/doom/test/remark-lint/no-deep-heading.spec.tspackages/doom/test/remark-lint/no-deep-list.spec.tspackages/doom/test/remark-lint/no-empty-table-cell.spec.tspackages/doom/test/remark-lint/no-heading-punctuation.spec.tspackages/doom/test/remark-lint/no-heading-special-characters.spec.tspackages/doom/test/remark-lint/no-heading-sup-sub.spec.tspackages/doom/test/remark-lint/no-multi-open-api-paths.spec.tspackages/doom/test/remark-lint/no-paragraph-indent.spec.tspackages/doom/test/remark-lint/table-size.spec.tspackages/doom/test/remark-lint/unit-case.spec.tspackages/doom/test/utils/helpers.spec.tspackages/export/AGENTS.mdpackages/export/package.jsonpackages/export/test/export-pdf-core/utils/convertPathToPosix.spec.tspackages/export/test/export-pdf-core/utils/getUrlLink.spec.tspackages/export/test/html-export-pdf/utils/isValidUrl.spec.tspackages/export/test/html-export-pdf/utils/replaceExt.spec.tspackages/export/test/merge-pdfs/formatDate.spec.ts
✅ Files skipped from review due to trivial changes (22)
- packages/export/package.json
- packages/doom/test/remark-lint/list-item-size.spec.ts
- packages/doom/test/remark-lint/unit-case.spec.ts
- packages/doom/test/remark-lint/no-empty-table-cell.spec.ts
- packages/doom/test/remark-lint/maximum-link-content-length.spec.ts
- packages/doom/test/remark-lint/no-deep-heading.spec.ts
- packages/doom/test/remark-lint/no-deep-list.spec.ts
- packages/doom/test/remark-lint/list-table-introduction.spec.ts
- packages/doom/test/remark-lint/list-item-punctuation.spec.ts
- packages/doom/test/remark-lint/no-heading-punctuation.spec.ts
- packages/doom/test/remark-lint/no-multi-open-api-paths.spec.ts
- packages/doom/test/utils/helpers.spec.ts
- packages/doom/src/plugins/AGENTS.md
- packages/export/test/export-pdf-core/utils/getUrlLink.spec.ts
- packages/export/test/export-pdf-core/utils/convertPathToPosix.spec.ts
- packages/export/test/html-export-pdf/utils/isValidUrl.spec.ts
- packages/doom/src/remark-lint/AGENTS.md
- packages/doom/test/remark-lint/_helper.ts
- openspec/changes/archive/2026-04-09-add-rstest-unit-tests/proposal.md
- packages/doom/test/plugins/replace/parse-toc.spec.ts
- packages/doom/test/remark-lint/table-size.spec.ts
- packages/doom/test/remark-lint/no-paragraph-indent.spec.ts
🚧 Files skipped from review as they are similar to previous changes (4)
- packages/doom/test/remark-lint/no-heading-special-characters.spec.ts
- packages/doom/test/remark-lint/no-heading-sup-sub.spec.ts
- package.json
- packages/export/test/html-export-pdf/utils/replaceExt.spec.ts
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 54 out of 55 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Summary
@rstest/coreas the unit test framework with root + per-package rstest configs@alauda/doom: 14 remark-lint rule tests, 2 plugin tests (replace/parse-toc,replace/utils), 1 utility test (helpers)@alauda/doom-export: 5 utility tests (convertPathToPosix,getUrlLink,isValidUrl,replaceExt,formatDate)tsconfig.test.jsonand per-test-directory tsconfigs (packages/doom/test/tsconfig.json,packages/export/test/tsconfig.json) for clean ESLint project service integrationteststep into CI workflow (run-pparallel execution)Test Plan
yarn test— 115/115 tests passyarn build— cleanyarn lint— cleanyarn typecov— 100% type coverage maintainedSummary by CodeRabbit
New Features
Tests
Documentation
Chores