A text-first, persistent AI Dungeon Master for long-running fantasy campaigns.
Loreweaver is not a generic fantasy chatbot and not a virtual tabletop. It is a campaign engine that preserves canon across many play sessions: it remembers prior events, tracks structured game state, adjudicates rules through deterministic tools, and sustains a tabletop-like solo or small-group experience entirely through text.
It is built for two overlapping kinds of player:
- Tabletop-seeking solo adventurers who want D&D/TTRPG-style play when friends are unavailable or nobody wants to DM.
- Living text-world nostalgists who loved text adventures, MUDs, and BBS door games but wanted worlds that could understand actions the designer never pre-authored.
The promise: open-ended text adventure plus tabletop rules and consequences plus persistent campaign memory. It should feel like a real DM inhabiting a living world, not a video game missing its graphics.
Project status: local CLI MVP. The repository now contains the provider-neutral core, SQLite persistence, module/world loading, multi-system rules packs (bundled D&D 5e SRD and Pathfinder 2e Remaster fixtures) with provider-neutral
lookup_rules, deterministic tools, model orchestration, session launch/resume, graceful session close, and optional Dolt checkpoints. The CLI can create or resume a local campaign and run interactive model-backed turns, and manages campaigns through a per-user data root and registry (LOREWEAVER_DB_PATHstill works as an explicit-path override). The project is still pre-distribution: packaging and release workflow are being planned.
- Text-first. The MVP is pure text: narration, player input, dice/results, state tracking, campaign memory, summaries, checkpoints, and theater-of-the-mind combat. Structured UI panels, tactical abstractions, and VTT export come later; native VTT and native mobile are explicit non-goals for early scope.
- CLI now, web later. The current surface is CLI/local-friendly because it is the fastest route to the core game loop, local campaign state, and bring-your-own-key use. The likely public product is a hosted, mobile-friendly web app / PWA. The CLI remains supported as the local and power-user surface.
- Provider-neutral core. Model access is isolated behind provider adapters
and capability-based model profiles such as
premium_dm,state_extractor, andsummarizer. The Claude Agent SDK is the initial adapter, not a hardcoded core assumption. - Premium quality floor. The primary DM targets frontier-model quality (Opus 4.6+ / GPT-5.5-class or a future equivalent). Cheaper models are only for bounded auxiliary tasks that cannot corrupt canon. Loreweaver targets a capability floor, not a price floor.
- Separated knowledge. Rules/mechanics, campaign/module content, live campaign state, user-private content, and generated memory are kept separate. Bundled/public content must be open-licensed, public domain, original, or publisher-licensed; fair use is not the permission model.
See docs/architecture-report.md for the full strategy, docs/adr/0001-product-model-deployment-content-strategy.md for the product/model/content decision record, and docs/adr/0002-hosted-web-pwa-byok-deployment-path.md for the CLI-to-hosted deployment path, and docs/adr/0004-config-file-and-campaign-registry.md for the managed local storage decision. The local CLI release plan is in docs/cli-distribution.md.
Monorepo using npm workspaces:
| Package | Path | Role |
|---|---|---|
@loreweaver/core |
packages/core |
UI-agnostic engine: config, models, tools, persistence |
@loreweaver/cli |
packages/cli |
Thin CLI front end for local play and development |
- Node.js 24 LTS is the supported runtime. The package engines intentionally
use
>=24 <25, and the nativebetter-sqlite3dependency is on 12.x for Node 24 prebuilt binary support. See ADR 0008. - Anthropic API key. The only concrete model adapter today is the Claude Agent SDK adapter.
- Dolt optional. Dolt is used only for local campaign checkpoints on graceful session close. Play still works without Dolt; the CLI reports that the session was closed without a checkpoint.
After the CLI packages are published, install the command with npm:
npm install -g @loreweaver/cli
loreweaverThat command prints the core version and resolved config. If required
configuration is missing, it prints the missing setting instead of requiring a
repository checkout or a direct node packages/cli/dist/index.js invocation.
npm install # local install
npm run build # tsc --build (incremental)
npm run typecheck # tsc --build --force (full deterministic build)
npm run test # vitest runUse npm ci for clean CI-style installs and npm run clean before any proof
that needs fresh build output. Incremental TypeScript builds can otherwise
report "up to date" after dist/ was deleted if .tsbuildinfo remains.
The CLI reads provider credentials and model overrides from environment
variables. Campaigns normally live under Loreweaver's per-user data root and
are selected through the managed registry. .env.example is a template, but
the CLI does not currently load .env files by itself.
Provider authentication: set exactly one before running model-backed play. If
both are present, ANTHROPIC_API_KEY wins, mirroring Claude Code's credential
precedence. See
docs/agent-sdk-auth.md:
ANTHROPIC_API_KEY- an Anthropic Console API key.CLAUDE_CODE_OAUTH_TOKEN- a Claude Pro/Max subscription token, generated byclaude setup-token. Lets the CLI run on a subscription instead of an API key.
Optional:
LOREWEAVER_HOME- explicit data-root directory for config, the campaign registry, managed campaign databases, rules packs, and the managed Dolt cache.LOREWEAVER_MODEL- legacy flat override for the primary-DM model id. When set it still takes precedence over the profile registry.LOREWEAVER_PROFILE_*_PROVIDER/LOREWEAVER_PROFILE_*_MODEL- per-profile provider/model overrides for the provider-neutral profile registry. The CLI runtime resolves its primary-DM model from thepremium_dmprofile entry, soLOREWEAVER_PROFILE_PREMIUM_DM_MODELselects the DM model whenLOREWEAVER_MODELis unset. The resolvedpremium_dmprovider must beanthropic— the only adapter the CLI ships today.LOREWEAVER_DOLT_BIN- explicit path to a Dolt binary for checkpoints.LOREWEAVER_DOLT_HOME- managed Dolt cache directory used byloreweaver dolt install; defaults to<data-root>/dolt.LOREWEAVER_DB_PATH- advanced override for an explicit, unmanaged SQLite campaign database. When set,loreweaver playopens that file directly and bypasses the managed campaign registry.
Installed CLI PowerShell example:
$env:ANTHROPIC_API_KEY = "sk-ant-..."
loreweaver new "Emberfall Hollow"
loreweaver campaigns list
loreweaver playAfter install, run the CLI with:
loreweaverThis prints the core version and resolved config.
Start or resume a campaign:
loreweaver new "Emberfall Hollow"
loreweaver campaigns list
loreweaver playnew creates a managed SQLite campaign database under the data root, forks the
bundled EMBERFALL_HOLLOW module into it, and records it in the registry.
campaigns list shows registered campaigns. play opens the only registered
campaign, prompts you to choose when several exist, or offers to create the
first one when the registry is empty. You can also pass a campaign id:
loreweaver play <id>.
During play, each player input goes through the core turn orchestrator. Type
/quit or /exit to close and recap the session.
For scripted, CI, synced-folder, or other explicit-path workflows, set
LOREWEAVER_DB_PATH. In that mode play opens exactly that SQLite file as an
unmanaged campaign and bypasses the registry.
Install Dolt into the managed cache when you want local checkpoints and Dolt is
not already on PATH:
loreweaver dolt installManaged Dolt install is consent-based. Non-interactive shells decline automatically so CI and automation cannot trigger an unattended binary download.
When working directly from a repository checkout before package publication,
run npm run build and invoke the built entrypoint with
node packages/cli/dist/index.js.
Local CLI storage is managed through a per-user data root and campaign registry. See docs/storage.md and ADR 0004 for the full user-facing storage boundary.
- Static bundled content lives in the package source/build output,
including
EMBERFALL_HOLLOWsample module data, SRD catalog data, and bundled rules packs (DND5E_SRD_RULES_PACK,PATHFINDER2E_REMASTER_RULES_PACK). - Managed user data lives under the data root:
LOREWEAVER_HOMEwhen set, otherwise%LOCALAPPDATA%\Loreweaveron Windows and~/.loreweaveron macOS/Linux. The registry isregistry.json; managed campaign databases live undercampaigns/. - Live campaign state lives in the SQLite file selected by the registry.
loreweaver newcreates managed databases under<root>/campaigns/, whileloreweaver campaigns add <path>registers an existing external database. SQLite sidecar files such as-wal,-shm, or-journalmay appear beside the database while it is open. - Explicit unmanaged campaigns use
LOREWEAVER_DB_PATH. When set, the CLI opens exactly that SQLite file and does not consult or update the registry. - Dolt checkpoints live beside the selected database in
<dbPath>.checkpointswhen Dolt is available. Restore/fork commands materialize checkpoints into a new SQLite database path chosen by the caller. - Beads tracker data is separate from campaign checkpoints. Checkpoint code guards against reusing the beads Dolt ref/remote.
- Provider secrets come from the local environment in the CLI release. They
must not be written to campaign SQLite databases, Dolt checkpoints,
turn_trace, exports, or logs. Hosted BYOK secret handling is governed by ADR 0002.
The managed Dolt binary cache defaults inside the data root, and bundled static content lives in the npm package build output.
- Issue tracking uses bd (beads), not GitHub issues or markdown TODO lists.
Run
bd readyto find available work andbd primefor the full workflow. - Operational guidance for both humans and AI agents lives in
AGENTS.md.
CLAUDE.mdsimply imports it. - Dependency updates use the conservative policy in
docs/dependencies.md, including special handling for
Node runtime and
better-sqlite3compatibility. - Bundled or publicly shared campaign/rules content must be open-licensed, public domain, original, or publisher-licensed.
The Loreweaver source-code license is not finalized. Until a repository-level LICENSE file and package license metadata are added, the root workspace and both npm workspaces are marked private/unpublished and are not intended for npm publication.
That source-code decision is separate from bundled content licensing. Any bundled or publicly shared rules/campaign content must be open-licensed, public domain, original, or publisher-licensed, with license and provenance recorded in pack metadata.
Third-party adventure or module source legality is also separate from the
repository license. That review remains tracked by bead loreweaver-9s6; this
repository must not bundle or publish third-party adventure text until that
source is confirmed open, public domain, original, or publisher-licensed.