Developer Guide
This document covers local development, testing, and release operations for @selfagency/llm-stream-parser.
Prerequisites
- Node.js 20+ (18+ minimum, but 20+ recommended for tooling compatibility)
- pnpm (version pinned in
package.json) taskCLI (optional, recommended)
Quick Start
1. Install dependencies
pnpm installpnpm install is the only required direct package-manager command for normal development.
2. Build and verify
task compile
task check-types
task unit-tests
task lint
task check-formattingOr run all checks at once:
task check-allDevelopment Workflow
Running tasks
We use Taskfile.yaml for consistent workflows:
task <task-name>View all available tasks:
task --listCommon tasks
| Task | Purpose |
|---|---|
check-types | Run TypeScript type checker |
lint | Run linter (oxlint) |
lint-fix | Auto-fix linting issues |
check-formatting | Check code formatting |
formatting | Auto-format code |
compile | Build distribution (tsup) |
unit-tests | Run all tests |
unit-test-coverage | Run tests with coverage report |
precommit | Run pre-commit checks (lint-fix + format) |
watch | Watch for changes and recompile |
Development mode
Watch for changes and automatically rebuild:
task watchThis runs tsup in watch mode.
Testing Strategy
Structure
Tests are colocated with source modules in src/**/*.test.ts:
src/
├── thinking/
│ ├── index.ts
│ └── thinking.test.ts
├── xml-filter/
│ ├── index.ts
│ └── xml-filter.test.ts
└── ...Best practices
- Keep parser behavior deterministic across chunk boundaries
- Test streaming edge cases (partial chunks, large inputs)
- Assert safety rails explicitly:
- Privacy scrub defaults
- Tool-call count/size limits
- JSON depth/key limits
- Add targeted unit tests for bug fixes
Run tests
# Run all tests
task unit-tests
# Run tests with coverage
task unit-test-coverage
# Run specific test file
task unit-tests src/thinking/thinking.test.ts
# Watch mode
pnpm vitest srcBuilding and Releases
Build outputs
The package uses tsup for building:
task compileThis generates:
dist/- Compiled JavaScript and TypeScript declarationsdist/package.json- Package metadata (auto-generated)
Distribution files
dist/index.js- ES modules (primary)dist/index.cjs- CommonJS (for Node.jsrequire)dist/index.d.ts- TypeScript declarations
Each subpath export also gets compiled:
dist/thinking/index.js,.cjs,.d.tsdist/structured/index.js,.cjs,.d.ts- etc.
Release process
The package uses scripted release automation:
Create feature branch and make changes
Commit and push changes
Create pull request on GitHub
After merge to main:
bashtask release -- <version>
The release script:
- Builds with
pnpm run build - Publishes
./distto npm registry - Tags commit on GitHub
Version scheme
- Stable versions → published to
latesttag on npm - Prerelease versions → published to
nexttag
Example:
task release -- 0.2.0 # Stable release
task release -- 0.2.0-alpha.1 # PrereleaseCI/CD
See .github/workflows/:
- Test & Build - Runs tests and builds on all branches
- Release - Publishes to npm after merge to main
Code Quality
Check all code quality rules
task check-allThis runs:
- Type checking (TypeScript)
- Linting (oxlint)
- Formatting checks (oxfmt)
Auto-fix issues
task precommitThis runs:
- Lint with auto-fix
- Format code
Git hooks
Pre-commit hooks are configured via husky:
# Install git hooks
pnpm husky installDebugging
TypeScript errors
task check-types
# Or directly:
pnpm tsc --noEmitLinting errors
task lint-fixTest failures
pnpm vitest src <path-to-test>Debug specific tests:
node --inspect-brk ./node_modules/vitest/vitest.mjs run src/path/to/test.tsDocumentation
Documentation is built with VitePress:
pnpm docs:dev # Start dev server
pnpm docs:build # Build static site
pnpm docs:preview # Preview built siteDocumentation sources:
docs/- Markdown documentation.vitepress/config.ts- VitePress configuration
Project Structure
@selfagency/llm-stream-parser/
├── src/
│ ├── thinking/ # Thinking tag extraction
│ ├── xml-filter/ # XML context filtering
│ ├── tool-calls/ # Tool call extraction
│ ├── context/ # Context block processing
│ ├── structured/ # JSON parsing & schema validation
│ ├── formatting/ # Output formatting
│ ├── processor/ # Stream processor orchestration
│ ├── markdown/ # Markdown parsing
│ ├── adapters/ # Pre-built adapters
│ └── index.ts # Main entry point
├── dist/ # Compiled output (tsup)
├── docs/ # Documentation (VitePress)
├── .vitepress/ # VitePress config
├── scripts/ # Build and release scripts
├── Taskfile.yaml # Task definitions
├── tsconfig.json # TypeScript config
├── tsup.config.ts # Build config
└── package.json # Package metadataContributing Guidelines
- Create a feature branch from
main - Make changes and add tests
- Run
task check-allandtask unit-testslocally - Commit with clear messages
- Push and create pull request
- Address review feedback
- After merge, maintainer runs release workflow
Troubleshooting
pnpm install fails
- Clear pnpm cache:
pnpm store prune - Delete pnpm-lock.yaml and reinstall
- Ensure Node.js version matches
Type errors after changes
task check-types --forceTests pass locally but fail in CI
- Check Node.js version in CI matches local
- Check environment variables
- Run
task check-alllocally
Build artifacts missing
rm -rf dist pnpm-lock.yaml
pnpm install
task compileAdditional Resources
- API Reference - Complete API documentation
- Getting Started - Usage examples
- Integration Guide - Integration patterns