diff --git a/.env.example b/.env.example index 5ccd61a..fb3eff7 100644 --- a/.env.example +++ b/.env.example @@ -10,7 +10,20 @@ # your shell profile, the shell value takes precedence. # Database -DATABASE_URL=postgresql://smriti:smriti@localhost:5432/smriti +# +# Solo/local mode is the low-friction default. It uses a local SQLite +# database file and does not require Docker or Postgres. +SMRITI_DB_MODE=local + +# Optional: override the local SQLite database path. +# Default: ~/.smriti/smriti.db +# SMRITI_LOCAL_DB_PATH=~/.smriti/smriti.db + +# Shared/team mode: uncomment for Postgres-backed operation. +# If DATABASE_URL is explicitly set to a Postgres URL, Smriti preserves +# Postgres behavior. +# SMRITI_DB_MODE=postgres +# DATABASE_URL=postgresql://smriti:smriti@localhost:5432/smriti # Provider API keys — uncomment and set the ones you want to use. # If unset, the backend falls back to config/providers.yaml, then to diff --git a/AGENTS.md b/AGENTS.md index 9fe1a1b..db1f740 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -224,8 +224,8 @@ are a client of it. You do not own it. That is your reachability check — no separate health probe needed. - **If the backend is unreachable, stop and tell the human.** Say: "The Smriti backend is not reachable at http://localhost:8000. - Please start it with `make dev` and ensure Postgres is running - via `docker compose up -d postgres`." + Please start it with `make dev-local` for solo/local mode, or + `make dev-postgres` for Postgres/shared-team mode." - **Do not attempt to start, restart, or manage the backend or Docker yourself.** Starting the server from inside an agent's tool loop creates environment-variable inheritance issues that diff --git a/Makefile b/Makefile index d42c7f3..740af7d 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: help dev up down test test-unit test-int lint format migrate +.PHONY: help dev dev-local dev-postgres up down test test-unit test-int lint format migrate setup setup-local setup-postgres VENV := cd backend && source .venv/bin/activate && @@ -21,9 +21,15 @@ logs: ## Follow logs # ── Backend ────────────────────────────────────────────────────────────────── -dev: ## Run backend dev server locally (requires venv) +dev: ## Run backend dev server with configured DB mode (requires venv) $(VENV) uvicorn app.main:app --reload --port 8000 +dev-local: ## Run backend in local-first SQLite mode + $(VENV) SMRITI_DB_MODE=local uvicorn app.main:app --reload --port 8000 + +dev-postgres: ## Run backend in Postgres mode + $(VENV) SMRITI_DB_MODE=postgres uvicorn app.main:app --reload --port 8000 + test: ## Run all backend tests $(VENV) python -m pytest -v @@ -44,8 +50,8 @@ format: ## Format backend code # ── Database ───────────────────────────────────────────────────────────────── -migrate: ## Run database migrations - $(VENV) alembic upgrade head +migrate: ## Run database migrations for Postgres/shared mode + $(VENV) SMRITI_DB_MODE=postgres alembic upgrade head migration: ## Create a new migration (usage: make migration msg="add users table") $(VENV) alembic revision --autogenerate -m "$(msg)" @@ -71,11 +77,25 @@ install: ## Install all dependencies (creates venv, installs CLI + MCP server) cd cli && ../backend/.venv/bin/pip install -e . cd frontend && npm install -setup: ## Full local setup (venv + deps + migrations) +setup: setup-local ## Default solo setup (local-first SQLite) + +setup-local: ## Solo setup: venv + deps + local SQLite path, no Docker + cp -n .env.example .env || true + mkdir -p "$$HOME/.smriti" + $(MAKE) install + @echo "\n✅ Setup complete!" + @echo " Mode: local SQLite" + @echo " Local DB path: $${SMRITI_LOCAL_DB_PATH:-$$HOME/.smriti/smriti.db}" + @echo " Activate the CLI: source backend/.venv/bin/activate" + @echo " Start backend: make dev-local" + @echo " Start frontend: make dev-frontend" + +setup-postgres: ## Shared/team setup: venv + deps + Docker Postgres + migrations cp -n .env.example .env || true $(MAKE) install + docker compose up -d postgres $(MAKE) migrate - @echo "\n✅ Setup complete!" + @echo "\n✅ Postgres setup complete!" @echo " Activate the CLI: source backend/.venv/bin/activate" - @echo " Start backend: make dev" + @echo " Start backend: make dev-postgres" @echo " Start frontend: make dev-frontend" diff --git a/README.md b/README.md index 24b978c..6e8543d 100644 --- a/README.md +++ b/README.md @@ -72,9 +72,10 @@ One project, one Smriti Space, multiple agents. Each reads the state, declares i ## Getting started -You will need: Python 3.11+, Node 18+, Docker (for Postgres). +You will need: Python 3.11+ and Node 18+. Docker is only needed for +Postgres/shared-team mode. -### 1. Clone and set up +### 1. Clone and set up for solo/local mode ```bash git clone https://github.com/himanshudongre/smriti @@ -89,11 +90,14 @@ cp .env.example .env # SMRITI_GENERIC_MODEL=llama3.1:8b # See .env.example for details. -docker compose up -d postgres # start the database -make setup # backend venv + deps + migrations + CLI + frontend +make setup-local # backend venv + CLI + frontend, no Docker ``` -`make setup` installs the backend, the CLI (`smriti` + `smriti-mcp`), and the frontend. The CLI binaries are installed into the backend venv at `backend/.venv/bin/`. To use them from your shell: +Local mode uses SQLite at `~/.smriti/smriti.db` by default. Override it +with `SMRITI_LOCAL_DB_PATH=/path/to/smriti.db` if you want the database +somewhere else. + +`make setup-local` installs the backend, the CLI (`smriti` + `smriti-mcp`), and the frontend. The CLI binaries are installed into the backend venv at `backend/.venv/bin/`. To use them from your shell: ```bash source backend/.venv/bin/activate @@ -102,12 +106,32 @@ source backend/.venv/bin/activate ### 2. Start the backend and frontend ```bash -make dev # backend on http://localhost:8000 (keep running) +make dev-local # backend on http://localhost:8000 (keep running) make dev-frontend # frontend on http://localhost:5173 (separate terminal) ``` **For the chat UI only, you're done.** Open http://localhost:5173. +### Shared/team mode with Postgres + +Postgres remains the stronger shared/team mode. Use it when you want an +explicit database service, Docker-backed state, or a closer path toward a +hosted deployment. + +```bash +cp .env.example .env +# In .env, set: +# SMRITI_DB_MODE=postgres +# DATABASE_URL=postgresql://smriti:smriti@localhost:5432/smriti + +make setup-postgres # starts Docker Postgres and runs migrations +make dev-postgres # backend on http://localhost:8000 +make dev-frontend # frontend on http://localhost:5173 +``` + +If `DATABASE_URL` is explicitly set to a Postgres URL, Smriti preserves +Postgres behavior. + ### 3. For coding agents **Quick path:** @@ -139,7 +163,11 @@ smriti skills install claude-code # → .claude/skills/smriti/SKILL.md smriti skills install codex # → AGENTS.md (commit it) ``` -**Runtime model.** Postgres runs in Docker. The backend runs locally via `make dev`. The human starts both. Agents are clients of `http://localhost:8000` — they do not manage the backend. +**Runtime model.** In solo/local mode, Smriti stores state in a SQLite +file and the backend runs locally via `make dev-local`. In shared/team +mode, Postgres runs in Docker and the backend runs via `make dev-postgres`. +Agents are clients of `http://localhost:8000` — they do not manage the +backend. ### 4. Auto-inject state at session start (Claude Code) @@ -152,7 +180,7 @@ smriti skills install codex # → AGENTS.md (commit it) "hooks": [ { "type": "command", - "command": "smriti state my-project --compact 2>/dev/null || echo 'Smriti backend not reachable. Start it with: make dev'" + "command": "smriti state my-project --compact 2>/dev/null || echo 'Smriti backend not reachable. Start it with: make dev-local'" } ] } diff --git a/cli/README.md b/cli/README.md index ca126ae..d6d2abf 100644 --- a/cli/README.md +++ b/cli/README.md @@ -23,6 +23,11 @@ export SMRITI_API_URL=http://localhost:8000 Or pass `--api-url` on any command. +Local-first vs Postgres storage is configured on the backend, not in the +CLI. For solo use, start the backend with `make dev-local`; for +Postgres/shared-team use, start it with `make dev-postgres`. The CLI and +MCP server keep talking to the same HTTP API either way. + ## MCP server Run Smriti as a local MCP server so agents inside Claude Code, Cursor, or Windsurf can read and write reasoning state natively — no subprocess-shelling to the `smriti` binary. diff --git a/cli/smriti_cli/main.py b/cli/smriti_cli/main.py index 60bf57e..387f87d 100644 --- a/cli/smriti_cli/main.py +++ b/cli/smriti_cli/main.py @@ -937,8 +937,8 @@ def cmd_init(client: SmritiClient, args: argparse.Namespace) -> None: except Exception: _fail( f"error: Cannot reach Smriti backend at {client.base_url}.\n" - "Start the backend with `make dev` and ensure Postgres is running " - "via `docker compose up -d postgres`." + "Start the backend with `make dev-local` for solo/local mode, " + "or `make dev-postgres` for Postgres/shared-team mode." ) return @@ -999,7 +999,7 @@ def cmd_init(client: SmritiClient, args: argparse.Namespace) -> None: settings_path = Path(".claude/settings.json") hook_command = ( f"backend/.venv/bin/smriti state {space_name} --preview 2>/dev/null " - f"|| echo 'Smriti backend not reachable. Start with: make dev'" + f"|| echo 'Smriti backend not reachable. Start with: make dev-local'" ) hook_entry = { "type": "command", diff --git a/cli/smriti_cli/skill_pack/template.md b/cli/smriti_cli/skill_pack/template.md index b382404..26070f1 100644 --- a/cli/smriti_cli/skill_pack/template.md +++ b/cli/smriti_cli/skill_pack/template.md @@ -1,5 +1,5 @@ --- -smriti_skill_pack_version: 2.2 +smriti_skill_pack_version: 2.3 title: Smriti — how to use it well target: {{display_name}} --- @@ -241,8 +241,8 @@ are a client of it. You do not own it. That is your reachability check — no separate health probe needed. - **If the backend is unreachable, stop and tell the human.** Say: "The Smriti backend is not reachable at http://localhost:8000. - Please start it with `make dev` and ensure Postgres is running - via `docker compose up -d postgres`." + Please start it with `make dev-local` for solo/local mode, or + `make dev-postgres` for Postgres/shared-team mode." - **Do not attempt to start, restart, or manage the backend or Docker yourself.** Starting the server from inside an agent's tool loop creates environment-variable inheritance issues that @@ -257,7 +257,8 @@ are a client of it. You do not own it. the backend is running stale code. Tell the human: "The backend at localhost:8000 does not support [feature]. Its git_sha is [sha] but the current repo is at [repo sha]. Please restart - the backend with `make dev` to pick up recent changes." + the backend with the same mode you are using (`make dev-local` + or `make dev-postgres`) to pick up recent changes." For worktree-aware coordination, the capabilities list should include both `worktrees` and `worktree_binding`. - **When to check capabilities:** You do NOT need to check on every diff --git a/cli/tests/test_skill_pack.py b/cli/tests/test_skill_pack.py index abda752..76499ef 100644 --- a/cli/tests/test_skill_pack.py +++ b/cli/tests/test_skill_pack.py @@ -43,7 +43,7 @@ def test_load_template_nonempty(): def test_get_version_parses_frontmatter(): version = get_version() - assert version == "2.2" + assert version == "2.3" def test_get_version_raises_when_frontmatter_missing():