First off — thank you for taking the time to contribute! 🎉
This document describes how to set up the project, the conventions we follow, and how to submit changes. It is short on purpose; when in doubt, open an issue and ask.
promptkit is a non-commercial, community-maintained TypeScript toolkit for prompt engineering. Our north star: make prompts as testable and versionable as the rest of your code, without locking you into any model provider.
If your contribution advances that mission and keeps the runtime surface small, it is probably welcome.
By participating you agree to abide by the Code of Conduct. Be kind. Be patient. Assume good intent.
git clone https://github.com/Cryptoteep/promptkit
cd promptkit
npm install
npm test # run the vitest suite
npm run build # build dist/ with tsup
npm run typecheck # tsc --noEmit
npm run lint # eslintRequirements: Node 18+, npm/pnpm/bun.
src/ library source (the published package)
index.ts public entrypoint
test.ts promptkit/test entrypoint
cli/ the `promptkit` CLI
tests/ vitest suite
examples/ runnable examples (also used as smoke tests)
docs/ longer-form documentation
- Open an issue first for anything beyond a typo or obvious bug fix. A short discussion up front saves everyone time.
- Fork the repo and create a branch off
main. - Make your change. Keep commits focused; we favour small, reviewable PRs.
- Add or update tests in
tests/. We aim to keep coverage of the core modules high. - Run
npm run typecheck && npm test && npm run lintlocally. - Open a PR against
mainand fill in the template.
We use Conventional Commits:
feat(eval): add parallel case execution
fix(loader): handle missing directory gracefully
docs: clarify LLMCall contract
- TypeScript throughout, strict mode.
- No runtime dependencies in the published package. Dev dependencies are fine.
- Prefer pure functions in
src/. Side effects belong in the CLI or the user'scallfunction. - Format with Prettier (config is committed). Lint with ESLint.
We use Vitest. Tests live in tests/ and mirror the src/ layout. A test
file for src/foo.ts is tests/foo.test.ts. Aim for behaviour, not
implementation: assert on outputs and error messages, not internal state.
Matchers live in src/expect.ts. To add one:
- Add the method to the
Expect<T>interface. - Implement it in
createExpect. - Add a test in
tests/expect.test.ts. - Document it in
README.mdanddocs/api.md.
- Create
src/cli/commands/<name>.tsexporting an async<name>Command. - Wire it into the
switchinsrc/cli/index.ts. - Add a section to the
printHelpoutput anddocs/cli.md. - Add a smoke test if feasible.
Releases are cut by maintainers. We use semantic versioning:
patch: bug fixes, docsminor: backwards-compatible featuresmajor: breaking changes (rare; coordinated in an issue first)
- Open a discussion for questions.
- Open an issue for bugs.
- Ping a maintainer on your PR if it goes quiet for > 1 week.
Thanks again — and happy prompting! 💬