mdspec Development Roadmap
In Progress
None - ready for next high priority items
Planned
High Priority
Test Coverage Gaps
- [ ] Add tests for stderr redirection (
2>&1) - Currently no tests verify this works - [ ] Add tests for pipes (
cmd1 | cmd2) - Basic pipe functionality not tested - [ ] Add tests for combined pipes + redirection (
cmd1 | cmd2 2>&1) - Complex shell patterns not tested - [ ] Add tests for
!stderr matching - Multi-line stderr assertions not tested
Medium Priority
Scrut-Inspired Features
Scrut (Facebook's Rust-based Cram successor) provides a roadmap for mdspec enhancements:
[ ] Detached processes -
console detachedfor server/daemon testing- Track PIDs, auto-cleanup on test completion
- Essential for testing servers, watch mode, etc.
[ ] Wait-for-file/port -
console wait=file:/tmp/ready timeout=5s- Block until file exists or port responds
- Critical for async startup sequences
[ ] Per-block config - YAML frontmatter or extended attributes
console timeout=5s cwd=subdir env=PORT=3000- More granular control than current global options
[ ] Pattern quantifiers - Multi-line pattern matching
(glob+)- match one or more lines with glob(regex*)- match zero or more lines with regex- More powerful than current
...ellipsis
[ ] Shell function/alias capture - Expand state serialization
- Currently captures env vars and cwd
- Could capture functions, aliases, shell options
NOT adopting from Scrut (intentional decisions):
- Shell-per-block isolation (destroys speed, complicates debugging)
- State file serialization (persistent session is simpler)
(esc)emoji escaping (keep full Unicode)- Rust binary requirement (zero-dependency philosophy)
Runtime Portability (when needed for wider adoption)
[ ] Node.js runtime support -
src/integrations/node.ts- Implement
shell()usingchild_process.spawn() - Same interface as Bun integration
- Enables mdspec without Bun dependency
- ~50 LOC (copy Bun integration, swap spawn method)
- Implement
[ ] Deno runtime support -
src/integrations/deno.ts- Implement
shell()usingDeno.Command() - Same interface as Bun integration
- Completes cross-runtime story
- Implement
Test Framework Integration (when needed for wider adoption)
[ ] Jest integration -
src/integrations/jest.ts- Transform
.spec.mdfiles via Jest transformer - Uses Node.js integration under the hood
- Larger user base than Bun
- Transform
[x] Vitest integration -
src/integrations/vitest.ts(DONE)- Plugin for Vitest (similar to Bun integration)
- Popular in Vue/React ecosystems
Quality of Life (when limitations hit)
- [ ] Better error messages - Show line numbers, context, suggestions
- [ ] Multi-file test suites - Share helper files across test files
- [ ] Custom matchers - User-defined pattern matching functions
- [ ] Custom normalization filters - Timestamps, paths, PIDs, etc.
- [ ] Parallel file execution - Run independent test files in parallel (preserve serial within file)
- [ ] Watch mode improvements - Better integration with framework watch modes
- [ ] Coverage reporting - Track which commands were tested
Low Priority
- [ ] CLI enhancements
- [ ] Add useful CLI flags (e.g.,
--bail,--timeout,--filter) - [ ] Interactive
--updatemode (selective snapshot updates) - Note: Bun reporters require
bun testintegration - no programmatic API (bun#5411)
- [ ] Add useful CLI flags (e.g.,
- [ ] Add edge case test coverage (empty fences, nested ellipsis, hook order)
- [ ] Create Cram migration guide (syntax differences, conversion examples)
- [ ] Performance optimizations for large test suites
Backlog
Known Issues (not blocking)
- [ ] Fix Bun test runner subprocess regression (was working, now broken)
- Tracked: Bun issue #24690
- Issue:
Bun.spawn()returns empty stdout/stderr when run insidebun test - Status: Bug confirmed and reported to Bun maintainers (Nov 13, 2025)
- Minimal reproduction:
tests/bun-bugs.test.ts- expects failure, will alert when Bun fixes it - Workaround: Use mdspec CLI instead of Bun test runner (documented in package.json scripts)
- Next steps: Wait for Bun fix, then re-enable bun test integration
Rejected
External Tool Adoption
After evaluating Cram, Scrut, trycmd, byexample, and mdsh:
- Cram/byexample rejected due to Python dependency, isolation issues, no named captures
- Scrut is best external tool but lacks named captures, requires Rust binary
- trycmd excellent for Rust but not applicable to Bun/TypeScript
- Decision: Build mdspec as Bun-native solution, learn from Scrut's feature set
Smart Bash Parsing
- Why rejected: Bash wrapper is unavoidable for state persistence
- Bun
$can't capture state changes (need bashexport -p,pwd,declare -f) - Bun
$can't source files (need bashsourcefor hooks) - Even with perfect bash parser, still need bash wrapper
- Parser libraries (340KB-25MB) add unnecessary dependencies
- Decision: Accept bash wrapper, use custom shell adapter for portability
Other Rejected Approaches:
- Parallel execution within files - Conflicts with session state persistence
- Direct
bun test file.spec.md- Bun doesn't support custom file extensions yet - Using Bun $ directly - Can't persist state, can't source files
Completed
v0.1 - Core Functionality
Test Execution:
- [x] Core markdown parsing with
remark - [x] Pattern matching (wildcards, ellipsis, regex, named captures)
- [x] Persistent shell context (env, cwd, functions via
declare -f) - [x] Lifecycle hooks (beforeAll, afterAll, beforeEach, afterEach)
- [x] Bun test integration with direct registration
- [x] Standalone CLI with
--updateflag - [x] Step-based parsing (1:1 cmd→expected mapping)
- [x] Serial file suites (prevent parallel state corruption)
- [x] Hook persistence (state saved after hook execution)
- [x] Markdown-structured output format (heading hierarchy, inline check marks)
- [x] File creation from fences (
file=filenamefor all languages) - [x] Temp directory isolation
- [x] Exit code and stderr testing
Architecture:
- [x] Custom shell adapter (
src/integrations/bun.ts) - [x] Runtime-portable design (Bun-specific code isolated)
- [x] Bash wrapper strategy (unavoidable, optimized)
- [x] Function persistence using
declare -f - [x] Removed Bun
$dependency
Code Quality:
- [x] Standardize path imports to
node:path - [x] Fix dynamic import in hot path
- [x] Extract magic constants
- [x] Consolidate test files
- [x] Timeout configuration per block
- [x] Duplicate test ID validation
- [x] Delete unused TestExecutor class
- [x] Use commander.js for CLI argument parsing
- [x] Consolidate markdown parsing to remark
- [x] DRY refactoring - extracted shared shell helpers
- [x] Remove prototype parser code