Skip to content

test: add rstest unit tests for doom and export packages#305

Merged
JounQin merged 7 commits intomainfrom
test/add-rstest-unit-tests
Apr 13, 2026
Merged

test: add rstest unit tests for doom and export packages#305
JounQin merged 7 commits intomainfrom
test/add-rstest-unit-tests

Conversation

@JounQin
Copy link
Copy Markdown
Member

@JounQin JounQin commented Apr 9, 2026

Summary

  • Add @rstest/core as the unit test framework with root + per-package rstest configs
  • Add 115 tests across both packages:
    • @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)
  • Add tsconfig.test.json and per-test-directory tsconfigs (packages/doom/test/tsconfig.json, packages/export/test/tsconfig.json) for clean ESLint project service integration
  • Integrate test step into CI workflow (run-p parallel execution)

Test Plan

  • yarn test — 115/115 tests pass
  • yarn build — clean
  • yarn lint — clean
  • yarn typecov — 100% type coverage maintained

Summary by CodeRabbit

  • New Features

    • Added a monorepo-wide unit testing setup and runner.
  • Tests

    • Added extensive unit and lint-rule tests covering utilities, plugins, and remark-lint rules plus a shared test helper.
  • Documentation

    • Added many developer-facing guides, skills, and OpenSpec docs describing project structure, workflows, and test/spec proposals.
  • Chores

    • Updated CI and package scripts to run tests alongside build/lint/typecov; added testing dev-dependency and minor tsconfig/package maps tweaks.

Copilot AI review requested due to automatic review settings April 9, 2026 08:30
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 9, 2026

Walkthrough

This 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

Cohort / File(s) Summary
CI & package scripts
/.github/workflows/ci.yml, package.json
CI “Build and Lint” now runs docs lint test typecov in parallel; added test/test:watch scripts and @rstest/core devDependency; adjusted lint script to use run-p 'lint:*'.
Root rstest config
rstest.config.ts
Added root rstest config with testEnvironment: 'node' and project discovery for packages.
Test helper
packages/doom/test/remark-lint/_helper.ts
New reusable remark test helper exporting lint() and lintMdx() to run rules against markdown/MDX and return vfile messages.
Remark-lint tests
packages/doom/test/remark-lint/*.spec.ts
Added ~16 rule test suites (no-deep-heading, maximum-link-content-length, list-item-punctuation, list-item-size, list-table-introduction, no-deep-list, no-empty-table-cell, no-heading-punctuation, no-heading-special-characters, no-heading-sup-sub, no-multi-open-api-paths, no-paragraph-indent, table-size, unit-case, etc.).
Utility & export tests
packages/doom/test/plugins/replace/*.spec.ts, packages/doom/test/utils/helpers.spec.ts, packages/export/test/**/*.spec.ts
Added parseToc, normalizeReferenceItems, getFrontmatterNode, baseResolve/pkgResolve tests and multiple export utilities tests (isValidUrl, getUrlLink, convertPathToPosix, replaceExt, formatDate).
Documentation / AGENTS
AGENTS.md, packages/*/AGENTS.md, packages/doom/src/*/AGENTS.md, packages/export/AGENTS.md
Large additions of developer-facing docs mapping repo structure, conventions, commands, and hotspots across root and package subtrees.
OpenSpec command & skills
.opencode/command/opsx-*.md, .opencode/skills/openspec-*/SKILL.md
Added command specs and skill documents for propose/apply/archive/explore OpenSpec workflows with detailed flows and guardrails.
OpenSpec change & specs
openspec/changes/archive/2026-04-09-add-rstest-unit-tests/..., openspec/config.yaml
Added archived change with proposal/design/specs/tasks for adding rstest tests and a root OpenSpec config describing conventions and validation rules.
TypeScript configs
packages/doom/tsconfig.json, packages/export/tsconfig.json
Removed explicit compilerOptions.noEmit: false from package tsconfigs (defer to base).
Package imports maps
packages/doom/package.json, packages/export/package.json
Added Node "imports": { "#*": "./src/*" } mappings to enable #-prefixed internal imports.
Opencode command docs
.opencode/command/opsx-apply.md, .opencode/command/opsx-archive.md, .opencode/command/opsx-explore.md, .opencode/command/opsx-propose.md
New long-form command procedure docs covering apply, archive, explore, and propose flows.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

ci, internal, documentation

Poem

🐇 In a burrow of code I nibble and test,

rstest carrots lined up in a nest;
Rules are checked, helpers hop through,
Docs and specs stitched neat as new,
Cheers — the repo sleeps better tonight.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding rstest unit tests across the doom and export packages, which is the primary focus of this comprehensive PR.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test/add-rstest-unit-tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 9, 2026

⚠️ No Changeset found

Latest commit: 4e7ee58

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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/core with root + per-package rstest.config.ts and root test/test:watch scripts.
  • Introduce tsconfig.test.json and per-test-directory tsconfig.json to support TS/ESLint project service usage for tests.
  • Add unit tests for remark-lint rules / replace plugins in doom, and various utilities in export, 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.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 win32 normalization 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

📥 Commits

Reviewing files that changed from the base of the PR and between 62d6f03 and b78081e.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (32)
  • .github/workflows/ci.yml
  • package.json
  • packages/doom/rstest.config.ts
  • packages/doom/test/plugins/replace/parse-toc.test.ts
  • packages/doom/test/plugins/replace/utils.test.ts
  • packages/doom/test/remark-lint/_helper.ts
  • packages/doom/test/remark-lint/list-item-punctuation.test.ts
  • packages/doom/test/remark-lint/list-item-size.test.ts
  • packages/doom/test/remark-lint/list-table-introduction.test.ts
  • packages/doom/test/remark-lint/maximum-link-content-length.test.ts
  • packages/doom/test/remark-lint/no-deep-heading.test.ts
  • packages/doom/test/remark-lint/no-deep-list.test.ts
  • packages/doom/test/remark-lint/no-empty-table-cell.test.ts
  • packages/doom/test/remark-lint/no-heading-punctuation.test.ts
  • packages/doom/test/remark-lint/no-heading-special-characters.test.ts
  • packages/doom/test/remark-lint/no-heading-sup-sub.test.ts
  • packages/doom/test/remark-lint/no-multi-open-api-paths.test.ts
  • packages/doom/test/remark-lint/no-paragraph-indent.test.ts
  • packages/doom/test/remark-lint/table-size.test.ts
  • packages/doom/test/remark-lint/unit-case.test.ts
  • packages/doom/test/tsconfig.json
  • packages/doom/test/utils/helpers.test.ts
  • packages/export/rstest.config.ts
  • packages/export/test/export-pdf-core/utils/convertPathToPosix.test.ts
  • packages/export/test/export-pdf-core/utils/getUrlLink.test.ts
  • packages/export/test/html-export-pdf/utils/isValidUrl.test.ts
  • packages/export/test/html-export-pdf/utils/replaceExt.test.ts
  • packages/export/test/merge-pdfs/formatDate.test.ts
  • packages/export/test/tsconfig.json
  • rstest.config.ts
  • tsconfig.json
  • tsconfig.test.json

JounQin added 4 commits April 13, 2026 12:34
- 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
@JounQin JounQin force-pushed the test/add-rstest-unit-tests branch from b78081e to 9236145 Compare April 13, 2026 05:14
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

♻️ Duplicate comments (2)
packages/doom/test/plugins/replace/parse-toc.spec.ts (1)

111-119: ⚠️ Potential issue | 🟡 Minor

Rename 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 | 🟠 Major

Assert 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 bash as 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 have bash in 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 list and table introductions.

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 the openspec status command, adding an explicit check before the mv command would make the workflow more robust and provide better error messages if the directory doesn't exist.

🛡️ Optional validation step

Add before the mv command:

   **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 Complete

Option 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

📥 Commits

Reviewing files that changed from the base of the PR and between b78081e and 9236145.

⛔ Files ignored due to path filters (1)
  • yarn.lock is 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.md
  • AGENTS.md
  • openspec/changes/archive/2026-04-09-add-rstest-unit-tests/.openspec.yaml
  • openspec/changes/archive/2026-04-09-add-rstest-unit-tests/design.md
  • openspec/changes/archive/2026-04-09-add-rstest-unit-tests/proposal.md
  • openspec/changes/archive/2026-04-09-add-rstest-unit-tests/specs/remark-lint-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/utility-tests/spec.md
  • openspec/changes/archive/2026-04-09-add-rstest-unit-tests/tasks.md
  • openspec/config.yaml
  • package.json
  • packages/doom/AGENTS.md
  • packages/doom/src/cli/AGENTS.md
  • packages/doom/src/plugins/AGENTS.md
  • packages/doom/src/remark-lint/AGENTS.md
  • packages/doom/src/runtime/AGENTS.md
  • packages/doom/src/theme/AGENTS.md
  • packages/doom/test/plugins/replace/parse-toc.spec.ts
  • packages/doom/test/plugins/replace/utils.spec.ts
  • packages/doom/test/remark-lint/_helper.ts
  • packages/doom/test/remark-lint/list-item-punctuation.spec.ts
  • packages/doom/test/remark-lint/list-item-size.spec.ts
  • packages/doom/test/remark-lint/list-table-introduction.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/no-empty-table-cell.spec.ts
  • packages/doom/test/remark-lint/no-heading-punctuation.spec.ts
  • packages/doom/test/remark-lint/no-heading-special-characters.spec.ts
  • packages/doom/test/remark-lint/no-heading-sup-sub.spec.ts
  • packages/doom/test/remark-lint/no-multi-open-api-paths.spec.ts
  • packages/doom/test/remark-lint/no-paragraph-indent.spec.ts
  • packages/doom/test/remark-lint/table-size.spec.ts
  • packages/doom/test/remark-lint/unit-case.spec.ts
  • packages/doom/test/utils/helpers.spec.ts
  • packages/doom/tsconfig.json
  • packages/export/AGENTS.md
  • packages/export/test/export-pdf-core/utils/convertPathToPosix.spec.ts
  • packages/export/test/export-pdf-core/utils/getUrlLink.spec.ts
  • packages/export/test/html-export-pdf/utils/isValidUrl.spec.ts
  • packages/export/test/html-export-pdf/utils/replaceExt.spec.ts
  • packages/export/test/merge-pdfs/formatDate.spec.ts
  • packages/export/tsconfig.json
  • rstest.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

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Apr 13, 2026

Open in StackBlitz

yarn add https://pkg.pr.new/@alauda/doom@305.tgz
yarn add https://pkg.pr.new/@alauda/doom-export@305.tgz

commit: 4e7ee58

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (3)
openspec/changes/archive/2026-04-09-add-rstest-unit-tests/design.md (2)

43-43: ⚠️ Potential issue | 🟡 Minor

Add 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 | 🟡 Minor

Design decisions are out of sync with current config snippets.

Line [69] and Line [112]-Line [114] document concrete settings (projects: ['packages/*'], typeCoverage.ignoreFiles including **/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 | 🟡 Minor

Document yarn test:watch in COMMANDS for parity with scripts.

Line [54]-Line [68] includes yarn test but misses yarn test:watch, which exists in root package.json scripts.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9236145 and 4e7ee58.

📒 Files selected for processing (34)
  • AGENTS.md
  • openspec/changes/archive/2026-04-09-add-rstest-unit-tests/design.md
  • openspec/changes/archive/2026-04-09-add-rstest-unit-tests/proposal.md
  • openspec/changes/archive/2026-04-09-add-rstest-unit-tests/tasks.md
  • package.json
  • packages/doom/AGENTS.md
  • packages/doom/package.json
  • packages/doom/src/plugins/AGENTS.md
  • packages/doom/src/remark-lint/AGENTS.md
  • packages/doom/test/plugins/replace/parse-toc.spec.ts
  • packages/doom/test/plugins/replace/utils.spec.ts
  • packages/doom/test/remark-lint/_helper.ts
  • packages/doom/test/remark-lint/list-item-punctuation.spec.ts
  • packages/doom/test/remark-lint/list-item-size.spec.ts
  • packages/doom/test/remark-lint/list-table-introduction.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/no-empty-table-cell.spec.ts
  • packages/doom/test/remark-lint/no-heading-punctuation.spec.ts
  • packages/doom/test/remark-lint/no-heading-special-characters.spec.ts
  • packages/doom/test/remark-lint/no-heading-sup-sub.spec.ts
  • packages/doom/test/remark-lint/no-multi-open-api-paths.spec.ts
  • packages/doom/test/remark-lint/no-paragraph-indent.spec.ts
  • packages/doom/test/remark-lint/table-size.spec.ts
  • packages/doom/test/remark-lint/unit-case.spec.ts
  • packages/doom/test/utils/helpers.spec.ts
  • packages/export/AGENTS.md
  • packages/export/package.json
  • packages/export/test/export-pdf-core/utils/convertPathToPosix.spec.ts
  • packages/export/test/export-pdf-core/utils/getUrlLink.spec.ts
  • packages/export/test/html-export-pdf/utils/isValidUrl.spec.ts
  • packages/export/test/html-export-pdf/utils/replaceExt.spec.ts
  • packages/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

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@JounQin JounQin merged commit 7d05730 into main Apr 13, 2026
18 checks passed
@JounQin JounQin deleted the test/add-rstest-unit-tests branch April 13, 2026 06:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants