Contributing
Contributions are welcome! This page covers the development setup, project layout, and how to add new features.
Changesets required
Every PR must include a changeset file generated by running pnpm changeset. See CONTRIBUTING.md for the full guide.
Development setup
bash
pnpm install
pnpm typecheck # strict TypeScript check
pnpm test # vitest unit + golden tests
pnpm test:golden # retrieval recall@k per strategy
pnpm test:bench # hot-path latency benchmarks
pnpm lint # eslint
pnpm fmt # prettier
pnpm build # tsc + copy migrations + copy dashboard → dist/Reinstalling the global binary from local build
After making source changes:
bash
pnpm build
npm install -g . # run from project rootThis replaces the globally installed copy with your local dist/.
Project layout
src/
cli/
index.ts # commander CLI entry point
init.ts # somtum init — installs hooks + MCP config
serve.ts # somtum serve — local dashboard server
stats.ts # somtum stats
doctor.ts # somtum doctor — health checks
hook.ts # internal: dispatches hook events by name
search.ts / show.ts / forget.ts / edit.ts
list.ts # somtum list
reset.ts # somtum reset — wipe project DB
export.ts / import.ts / purge.ts / sync.ts / rebuild.ts / reindex.ts
config_cmd.ts
suggest_claude_md.ts
core/
db.ts # SQLite setup, migration runner
store.ts # MemoryStore — CRUD for observations
cache.ts # PromptCache — exact + fuzzy lookup
retriever/ # bm25, embeddings, hybrid, index, factory
extractor.ts # session transcript → observations (Claude Haiku)
index_gen.ts # renders index.md (incremental past 1k obs)
memory_files.ts # writes memories/<YYYY-MM>/<ulid>.md
retrieval_stats.ts
embeddings.ts # Embedder interface + encode/decode utils
privacy.ts # redact() — runs on every capture
tokens.ts # gpt-tokenizer wrapper
hooks/
post_session.ts # SessionEnd/PreCompact: extract → store → index → warm-start
pre_prompt.ts # UserPromptSubmit: cache lookup + auto-inject + false-hit detection
pre_read.ts # PreToolUse: file gating
mcp/ # MCP server + tool implementations
dashboard/
index.html # single-page dashboard (served by somtum serve)
config.ts # global + project config merge
index.ts # public API for embedding Somtum
src/db/migrations/ # NNN_name.sql migration files
test/
golden/ # per-strategy retrieval golden sets
bench/ # hot-path latency benchmarks
fixtures/ # synthetic session transcriptsAdding a new observation kind
- Extend the zod enum in
src/core/schema.ts - Update the extractor prompt in
src/core/extractor.ts - Add a fixture in
test/fixtures/and an assertion - Update
src/core/index_gen.tsto render the new section
Adding a new MCP tool
- Define args + response with zod in
src/mcp/tools.ts - Register it in
src/mcp/server.ts - Response must include a
tokensfield - Add an integration test in
src/mcp/server.test.ts
Adding a new CLI command
- Add the command in
src/cli/index.ts(commander) - Implement the handler in a new file under
src/cli/ - Add a test in
test/
Adding a new retrieval strategy
- Implement the
Retrieverinterface insrc/core/retriever/ - Register it in
src/core/retriever/factory.ts - Add a golden test set in
test/golden/
Database migrations
Migrations live in src/db/migrations/ as numbered SQL files (NNN_name.sql). The migration runner in src/core/db.ts applies them in order on startup.
To add a migration:
- Create
src/db/migrations/<next-number>_description.sql - Write the SQL (must be idempotent where possible)
- Test with a fresh DB and an existing DB
Release process
Somtum uses changesets for versioning:
bash
pnpm changeset # describe your change
pnpm changeset version # bump versions (CI does this)
pnpm release # publish to npm (CI does this)