Skip to content

Commit 6d6c3fa

Browse files
authored
feat: add Mimir workspace packages
Move the core package into packages/mimir, add the Mimir TTS workspace package, and update CI/release automation for publishing both packages.
1 parent 82fd9d8 commit 6d6c3fa

202 files changed

Lines changed: 5055 additions & 1311 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ jobs:
5151
run: pnpm smoke
5252

5353
- name: Verify generated dist is committed
54-
run: git diff --exit-code -- dist
54+
run: git diff --exit-code -- packages/mimir/dist packages/mimir-tts/dist
5555

5656
- name: Verify npm package metadata
5757
run: pnpm package:check

.github/workflows/npm-publish.yml

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ jobs:
4747
4848
- name: Verify version input
4949
run: |
50-
test "$(node -p "require('./package.json').version")" = "${{ inputs.version }}"
50+
test "$(node -p "require('./packages/mimir/package.json').version")" = "${{ inputs.version }}"
51+
test "$(node -p "require('./packages/mimir-tts/package.json').version")" = "${{ inputs.version }}"
5152
5253
- name: Install dependencies
5354
run: pnpm install --frozen-lockfile
@@ -68,7 +69,7 @@ jobs:
6869
run: pnpm smoke
6970

7071
- name: Verify generated dist is committed
71-
run: git diff --exit-code -- dist
72+
run: git diff --exit-code -- packages/mimir/dist packages/mimir-tts/dist
7273

7374
- name: Verify npm package metadata
7475
run: pnpm package:check
@@ -82,7 +83,12 @@ jobs:
8283
name: mimir-release-${{ inputs.version }}
8384
path: release-artifacts/
8485

85-
- name: Publish
86-
run: npm publish --access public --provenance
86+
- name: Publish Mimir TTS
87+
run: pnpm --dir packages/mimir-tts publish --access public --provenance --no-git-checks
88+
env:
89+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
90+
91+
- name: Publish Mimir
92+
run: pnpm --dir packages/mimir publish --access public --provenance --no-git-checks
8793
env:
8894
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
11
node_modules/
22
coverage/
33
.env
4+
.env.*
45
.DS_Store
56
private/**
67
.kb/
78
.mimir/
89
*.tgz
910
release-artifacts/
11+
12+
# Tracked synthetic examples. Keep generated example runtime state ignored.
13+
!packages/mimir/examples/
14+
!packages/mimir/examples/**/
15+
!packages/mimir/examples/**/.kb/
16+
!packages/mimir/examples/**/.kb/config.json
17+
!packages/mimir/examples/**/.kb/sources.txt
18+
packages/mimir/examples/**/.kb/storage/
19+
packages/mimir/examples/**/.kb/access.log
20+
packages/mimir/examples/**/.mimir/

AGENTS.md

Lines changed: 62 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,28 +14,78 @@
1414
- `kb init` and `kb install-skill` must keep generated local Mimir state ignored in target
1515
repositories. By default, add `.kb/`, `.mimir/`, and private raw-document paths to the
1616
target repository `.gitignore`.
17-
- Keep confidentiality features low-friction: local-only network policy, redaction before
18-
indexing, metadata-only access logs, bounded MCP retrieval, and `security-audit` should work
19-
from default config.
17+
- Keep confidentiality features low-friction: local-hash retrieval by default, optional
18+
Transformers.js embeddings with remote model loading disabled by default, redaction before
19+
indexing, metadata-only access logs, bounded MCP retrieval, configurable text-extension ingestion,
20+
and `security-audit` should work from default config.
21+
- Keep public positioning focused on sovereign local RAG for confidential datasets and AI agents.
22+
Avoid claiming universal binary-file support; unsupported proprietary formats need extraction or
23+
dedicated parsers.
24+
- Keep optional audio summaries separate from core ingestion/query behavior. The
25+
`mimir-audio-summary` skill must prefer `kb audio` / `@jcode.labs/mimir-tts`, support offline
26+
model loading, and keep generated audio under ignored local Mimir state.
27+
- Keep the repository as a simple pnpm workspace monorepo. Add Turbo only if multiple packages or
28+
apps start needing task caching/orchestration beyond `pnpm --filter`.
29+
- Keep Mimir core free of Ollama. `embeddingProvider: "local-hash"` supports ingestion, search, MCP,
30+
and cited retrieval without a model server, but it must not be described as equivalent to semantic
31+
retrieval. `embeddingProvider: "transformers"` is the optional semantic embedding path.
32+
- Keep `packages/mimir/examples/sovereign-rag-demo` synthetic and safe to commit. It exists for
33+
package/user testing only; never place real confidential documents there.
2034
- Use Context7 before changing dependencies or public APIs that rely on external libraries.
2135
- Run `pnpm validate` before opening a release pull request or publishing. It covers
2236
Biome, TypeScript, Vitest, build output, production CLI/MCP smoke tests, and npm package
2337
metadata.
2438
- Do not publish from a local machine or direct push to `main`. npm releases must go through
25-
the protected manual `Publish npm` GitHub Actions workflow after `main` has green CI.
39+
the protected manual `Publish npm` GitHub Actions workflow after `main` has green CI. The workflow
40+
publishes `@jcode.labs/mimir-tts` first, then `@jcode.labs/mimir`.
41+
42+
## Coding Conventions
43+
44+
General principles (KISS, DRY, YAGNI, SOLID) as applied in this codebase. Match the surrounding style.
45+
46+
- One responsibility per module. The ingest pipeline is split on purpose: `files` discovers,
47+
`parsing` extracts, `redaction` strips, `chunking` splits, `embeddings` vectorizes, `store`
48+
persists, `query` retrieves. Add logic to the module that owns the concern, or a new small module.
49+
- No duplicated logic. Reuse existing helpers (`loadConfig`, `embedText`/`embedTexts`,
50+
`openRowsTable`, `redactText`, `supportedExtensions`, `recordAccess`); extract instead of copying.
51+
`embedText` delegating to `embedTexts` is the reference pattern.
52+
- No dead or obsolete code. Delete replaced code, unused exports, and commented-out blocks in the
53+
same change; a deletion must cover both source and the regenerated package `dist/`.
54+
- No magic strings or numbers. Name meaningful literals as constants, and put shared paths, provider
55+
defaults, and ignore constants in `packages/mimir/src/defaults.ts` rather than copying them across
56+
modules.
57+
- Validate at the boundary, narrow inside. Use Zod at external edges (config in `config.ts`, MCP
58+
inputs in `mcp.ts`) and CLI parsers (`parsePositiveInt`); trust the types past that point.
59+
- Type-guard instead of casting. Prefer runtime guards over `as`/`!` (`hasToList`, `isNumberArray`,
60+
`isNumberMatrix`); LanceDB row casts at the `store`/`query` driver boundary are the only exception.
61+
- Named exports only; keep the public surface explicit in `index.ts`. Functions stay small and pure;
62+
private helpers sit below the exported function in the same file.
63+
- Comments explain why, not what; the codebase is near comment-free. Only the CLI (`cli.ts`) writes
64+
to stdout/stderr — library, MCP, and pipeline code return data, never log.
65+
- YAGNI: no options, providers, or abstractions ahead of a real need.
2666

2767
## Architecture
2868

29-
- `src/cli.ts` exposes the `kb` CLI.
30-
- `src/config.ts` resolves `.kb/config.json` from the target repository.
31-
- `src/ingest.ts` parses supported files, chunks text, embeds chunks, and rebuilds the
69+
- `packages/mimir` is the core package published as `@jcode.labs/mimir`.
70+
- `packages/mimir/src/cli.ts` exposes the `kb` CLI.
71+
- `packages/mimir/src/config.ts` resolves `.kb/config.json` from the target repository.
72+
- `packages/mimir/src/defaults.ts` owns shared default paths, provider defaults, and generated-state ignore
73+
constants. Keep config/init/security/gitignore aligned through this module instead of copying
74+
literals.
75+
- `packages/mimir/src/ingest.ts` parses supported files, chunks text, embeds chunks, and rebuilds the
3276
local LanceDB table.
33-
- `src/query.ts` performs vector search and local Ollama answer synthesis.
34-
- `src/mcp.ts` exposes Mimir as an MCP stdio server for agents.
35-
- `src/gitignore.ts` owns target-repository `.gitignore` entries for local generated Mimir
77+
- `packages/mimir/src/query.ts` performs vector search and returns cited retrieval context; LLM synthesis belongs
78+
outside Mimir core.
79+
- `packages/mimir/src/mcp.ts` exposes Mimir as an MCP stdio server for agents.
80+
- `packages/mimir-tts` is the standalone JS/ONNX TTS package used by `kb audio`.
81+
- `packages/mimir/src/gitignore.ts` owns target-repository `.gitignore` entries for local generated Mimir
3682
state.
37-
- `src/security.ts`, `src/network.ts`, `src/redaction.ts`, and `src/access-log.ts` own the
83+
- `packages/mimir/src/security.ts`, `packages/mimir/src/redaction.ts`, and
84+
`packages/mimir/src/access-log.ts` own the
3885
privacy and confidentiality hardening layer.
39-
- `skills/mimir/SKILL.md` is the bundled portable agent skill.
86+
- `packages/mimir/skills/mimir/SKILL.md` is the bundled portable agent skill.
87+
- `packages/mimir/skills/mimir-audio-summary/SKILL.md` is the optional bundled audio-summary skill.
88+
- `packages/mimir/examples/sovereign-rag-demo` is the tracked synthetic test workspace for manual
89+
and package validation.
4090
- `.kb/`, `.mimir/`, and project `private/` folders are local user data or generated agent
4191
state in target repositories and must not be committed.

CHANGELOG.md

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,29 @@
11
# Changelog
22

3+
## 0.4.0 - 2026-06-28
4+
5+
- Reposition Mimir as sovereign local RAG for confidential datasets and AI agents.
6+
- Expand default ingestion to common text, Office/OpenDocument, data, config, log, and source-code
7+
file types.
8+
- Add `includeExtensions` / `KB_INCLUDE_EXTENSIONS` for custom UTF-8 text file extensions.
9+
- Add the optional `mimir-audio-summary` bundled skill for confidential audio summaries.
10+
- Install both the main Mimir skill and optional audio-summary skill with `kb install-skill`.
11+
- Improve agent guidance for deep multi-query retrieval before synthesis.
12+
- Make Mimir core retrieval-only: `kb ask` now returns cited context for external agents or LLMs
13+
instead of generating answers internally.
14+
- Add optional Transformers.js semantic embeddings through `embeddingProvider: "transformers"`.
15+
- Remove Ollama providers and keep `embeddingProvider: "local-hash"` as the no-model default.
16+
- Move the repository to a simple pnpm workspace monorepo without adding Turbo.
17+
- Move the core `@jcode.labs/mimir` package into `packages/mimir`.
18+
- Add `@jcode.labs/mimir-tts` for plug-and-play JS/ONNX WAV rendering without Python or ffmpeg.
19+
- Add `kb audio` and update the audio-summary skill to use Mimir TTS before advanced fallback
20+
engines.
21+
322
## 0.3.0 - 2026-06-28
423

5-
- Add confidentiality hardening defaults: local-only Ollama network policy, built-in
6-
redaction before indexing, metadata-only access logs, and bounded MCP retrieval.
7-
- Add `kb security-audit` for zero-telemetry, network, redaction, gitignore, storage, and
24+
- Add confidentiality hardening defaults: built-in redaction before indexing, metadata-only access
25+
logs, and bounded MCP retrieval.
26+
- Add `kb security-audit` for zero-telemetry, provider, redaction, gitignore, storage, and
827
MCP posture checks.
928
- Add `kb destroy-index --yes` to remove generated vector indexes.
1029
- Add release verification artifacts: npm tarball, SHA256 checksums, SBOM, and manifest.

CLAUDE.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
`AGENTS.md` is the authoritative source for shared rules — working rules, coding conventions, and
6+
high-level architecture. Read it first. This file adds only the Claude Code operational details and
7+
non-obvious traps that matter when editing here, without duplicating `AGENTS.md`.
8+
9+
## Commands
10+
11+
```bash
12+
pnpm build # builds packages/mimir-tts, then packages/mimir; package dist is committed
13+
pnpm check # typecheck only (tsc --noEmit)
14+
pnpm lint # Biome CI (format + lint check, no writes)
15+
pnpm lint:fix # Biome auto-fix
16+
pnpm format # Biome format --write
17+
pnpm test # vitest run for packages/mimir-tts, then packages/mimir
18+
pnpm smoke # build production CLI + MCP smoke test (scripts/smoke.mjs)
19+
pnpm validate # full release gate: lint + check + test + build + smoke + package:check + release:artifacts
20+
```
21+
22+
Run a single core test file: `pnpm --filter @jcode.labs/mimir exec vitest run src/config.test.ts`
23+
Run a single core test by name: `pnpm --filter @jcode.labs/mimir exec vitest run -t "applies env overrides"`
24+
Run only the TTS package tests: `pnpm --filter @jcode.labs/mimir-tts test`
25+
26+
Tests are colocated as `packages/*/src/*.test.ts` and run on the TypeScript sources.
27+
28+
## Committed `dist/` — critical
29+
30+
`packages/mimir/dist/` and `packages/mimir-tts/dist/` are checked into Git. CI enforces
31+
`git diff --exit-code -- packages/mimir/dist packages/mimir-tts/dist`. After any change under
32+
`packages/mimir/src/` or `packages/mimir-tts/src/`, run `pnpm build` and commit the regenerated
33+
output in the same commit, or CI fails. This is the single easiest mistake to make in this repo.
34+
35+
## Naming map (the package has several names on purpose)
36+
37+
- Product / core package: **Mimir**, published as `@jcode.labs/mimir` from `packages/mimir`.
38+
- TTS package: **Mimir TTS**, published as `@jcode.labs/mimir-tts`.
39+
- CLI binary: **`kb`** (`packages/mimir/bin.kb` -> `packages/mimir/dist/cli.js`). Commands: `init`,
40+
`ingest`, `search`, `ask`, `audit`, `status`, `security-audit`, `destroy-index`, `audio`,
41+
`serve-mcp`, `skill-path`, `install-skill`.
42+
- TTS CLI binary: **`mimir-tts`** (`packages/mimir-tts/dist/cli.js`). Commands: `doctor`, `render`.
43+
- Project config/state in the target repo: **`.kb/`** (`config.json`, `sources.txt`, `access.log`,
44+
`storage/`), raw documents in **`private/`**, agent kit in **`.mimir/`**.
45+
- Environment overrides: **`KB_*`** (e.g. `KB_EMBEDDING_PROVIDER`, `KB_CHUNK_SIZE`).
46+
- MCP tools exposed to agents: **`mimir_*`** (`mimir_status`, `mimir_search`, `mimir_ask`,
47+
`mimir_audit`, `mimir_security_audit`).
48+
49+
## Architecture and data flow
50+
51+
This is a pnpm workspace monorepo with the core package in `packages/mimir` and TTS in
52+
`packages/mimir-tts`. Do not add Turbo unless `pnpm --filter` stops being enough.
53+
54+
The core package is an ESM-only TypeScript library + CLI + MCP server. Same core, three entry
55+
points: `packages/mimir/src/cli.ts` (commander), `packages/mimir/src/index.ts` (public library
56+
exports), `packages/mimir/src/mcp.ts` (stdio MCP server).
57+
58+
The ingest pipeline (`packages/mimir/src/ingest.ts`) chains single-responsibility modules:
59+
`files.ts` (discover supported files via fast-glob, with sha256 checksums) →
60+
`parsing.ts` (extract text per format: PDF/Office/HTML/etc.) →
61+
`redaction.ts` (strip secrets/PII *before* anything is embedded) →
62+
`chunking.ts` (split into overlapping chunks) →
63+
`embeddings.ts` (vectorize) → `store.ts` (LanceDB). `query.ts` embeds the query and runs vector
64+
search; `ask` returns cited passages only (no LLM synthesis in core).
65+
66+
`packages/mimir-tts` is a separate ESM package that uses Transformers.js text-to-speech to render
67+
WAV files without Python or ffmpeg. Core `kb audio` imports it dynamically.
68+
69+
Key behaviors to keep in mind before editing:
70+
71+
- **Config resolution is caller-relative.** `loadConfig` walks up from `cwd` looking for
72+
`.kb/config.json` (`findProjectRoot`). The package must resolve project data from the caller's
73+
working directory, never from its own install path. Zod validates config; `KB_*` env vars override.
74+
- **Two embedding providers, not interchangeable at runtime.** `local-hash` (default) is a 384-dim
75+
sha256 lexical embedding — fully offline, no model, *not semantic*. `transformers` lazily
76+
`import()`s `@huggingface/transformers` with `allowRemoteModels` off by default. The two produce
77+
different vectors, so **switching providers requires a full re-ingest**.
78+
- **Ingest always full-rebuilds** the LanceDB table (`mode: "overwrite"`). The `--rebuild` flag is a
79+
no-op kept for compatibility. There is no incremental indexing; `audit` only *reports* missing/stale
80+
files against the current index.
81+
- **Privacy is a feature, not a side effect.** Redaction runs before embedding, the access log stores
82+
query hashes/metadata only (`access-log.ts`), MCP top-K is clamped to `mcpMaxTopK`, and
83+
`gitignore.ts` keeps `.kb/`, `.mimir/`, `private/**` ignored in target repos. `security-audit`
84+
reports this posture and `--strict` exits non-zero on warnings. Preserve these guarantees.
85+
86+
Coding conventions (KISS, DRY, YAGNI, SOLID as applied here) live in `AGENTS.md`.
87+
88+
## Toolchain constraints
89+
90+
- Strict TypeScript with `noUncheckedIndexedAccess` and `exactOptionalPropertyTypes`; module mode is
91+
`NodeNext`, so relative imports use `.js` extensions even from `.ts` sources.
92+
- Biome is the formatter and linter (not ESLint/Prettier): 2-space indent, width 100, double quotes,
93+
semicolons as-needed, trailing commas all.
94+
- Conventional Commits are enforced by commitlint in CI.
95+
96+
Release policy (no local publish, no direct push to `main`, protected `Publish npm` workflow) lives
97+
in `AGENTS.md`. The workflow publishes `@jcode.labs/mimir-tts` before `@jcode.labs/mimir`.

0 commit comments

Comments
 (0)