AI-native operating system for managing a high-complexity life and multi-business portfolio. Pronounced like "gecko." Phase 1 is a CLI vertical slice — multiple isolated contexts, an agent loop with memory, and the data model + migration discipline to expand.
- A Supabase Postgres database with
pgvector, HNSW indexes, and migration-first schema discipline - Multiple contexts (business / personal), each with fully isolated memory, actions, and artifacts
- A
geckCLI: an interactive agent loop plus commands to manage actions, artifacts, and contexts - The agent loop, per turn: retrieve memory → build system prompt → call Claude → classify new actions and resolutions → log everything with embeddings
- A Vitest suite (real local DB, mocked AI)
- Strict TypeScript, zod-validated env, no heavyweight frameworks
- Automatic context routing — the agent inferring which context a message belongs to (in Phase 1 you switch contexts explicitly with
geck context use) - Proactive jobs — cron-driven check-ins, accountability nudges, weekly review generation
- Synergy / cross-context detection — e.g. "this personal goal is blocked by a business bottleneck"
- Reviews automation — the
reviewstable exists but is unwritten - Any web UI
- macOS with Homebrew
- Node.js ≥ 20 (this repo is on 22)
- Docker Desktop running (Supabase local needs it)
- Xcode ≥ 26.3 installed (required by the
supabasebrew formula) - API keys: Anthropic + Google AI Studio
# 1. Install the Supabase CLI
brew install supabase/tap/supabase
# 2. Initialize the Supabase project structure (creates config.toml)
supabase init
# 3. Start the local Supabase stack (Postgres + Studio + auth, all in Docker)
supabase start
# 4. Apply migrations + seed the Personal context
supabase db reset
# 5. Install Node dependencies
npm install
# 6. Configure env
cp .env.example .env
# Fill in SUPABASE_URL + SUPABASE_SERVICE_ROLE_KEY from `supabase status`,
# plus your ANTHROPIC_API_KEY and GOOGLE_API_KEY.
# 7. Type check
npm run typecheck
# 8. (Optional) Regenerate src/db/types.ts from the live schema
npm run gen-typesEvery command runs via npm run geck -- <command> and operates on the current context (see Contexts).
| Command | Description |
|---|---|
geck chat |
Interactive agent session in the current context |
geck status |
Open actions in the current context |
geck overview |
Open actions across all contexts, grouped by context |
| Command | Description |
|---|---|
geck add "<title>" --horizon <h> [--score <1-10>] |
Manually add an action. <h> = pulse | sprint | review | vision |
geck done <id> |
Mark an open action complete |
geck drop <id> |
Mark an open action dropped |
geck reopen <id> |
Return a done/dropped action to open |
<id> accepts a unique prefix of at least 4 characters — use the 8-char prefix shown by status / overview.
Actions are also created and resolved automatically by the chat classifier: each turn it extracts new commitments, and resolves existing ones it's confident were finished (and asks a clarifying question when it's unsure).
Long-lived knowledge — sop, goal, value, or note.
| Command | Description |
|---|---|
geck artifact add --kind <k> --title "<t>" [--body "<b>" | --body-file <path>] |
Add an artifact. With no body flag, opens $EDITOR |
geck artifact list [--kind <k>] |
List artifacts in the current context |
geck artifact show <id> |
Show an artifact's full body (id or ≥4-char prefix) |
| Command | Description |
|---|---|
geck context create --name "<n>" --type <business|personal> |
Create a new context |
geck context list |
List all contexts (the current one is marked *) |
geck context use "<n>" |
Switch the active context |
geck context show |
Current context's name, type, summary, and values |
geck context edit [--summary "<s>" | --summary-file <path>] |
Edit the summary. With no flag, opens $EDITOR |
geck context edit-values [--file <path>] |
Replace the values list, one per line. With no flag, opens $EDITOR |
A context is a bounded domain — a business, or personal life. Every action, interaction, and artifact belongs to exactly one context, and contexts are fully isolated from each other.
The current context — which every command operates on — is stored in .geck/state.json (gitignored). Switch it with geck context use. First run with no state file falls back to the seeded "Personal" context.
geck chat is single-context: the agent reasons only within the current context. geck overview is the panoramic cross-context dashboard.
npm test # run the Vitest suite once
npm run test:watchTests run against your local Supabase — real queries, RPCs, constraints, and cascades are exercised — with the Anthropic and Gemini SDKs mocked, so no API credits are spent. They isolate via throwaway __test__… contexts that are cascade-deleted afterward, so your real data is never touched. supabase start must be running.
Phase 1 uses Gemini Embedding 2 (gemini-embedding-2, GA April 22, 2026) at outputDimensionality: 1536. Notes:
- V2 is multimodal-capable (text/image/video/audio/PDF), but Phase 1 only embeds text.
- V2 replaces the V1
taskTypeenum with inline task prefixes liketask: search result | query: …. Theembed()wrapper hides this — call sites still use"RETRIEVAL_QUERY"/"RETRIEVAL_DOCUMENT". - V2 auto-normalizes sub-3072 dimensional outputs, so we don't manually L2-normalize.
- 1536 is one of Google's three recommended MRL dimensions (768 / 1536 / 3072). It's a 50% storage saving vs the default 3072 with minimal quality loss.
Why this matters: switching embedding models later requires re-embedding every row in interactions and artifacts — the vector space is model-specific. Don't switch without a backfill plan.
| Table | Purpose | Embedded? |
|---|---|---|
contexts |
Top-level "stage" (business / personal). | no |
actions |
Discrete work items, classified by horizon. | no |
interactions |
Conversational turns; retrieved by similarity. | yes |
artifacts |
Long-lived knowledge (SOPs, goals, values, notes). | yes |
reviews |
Periodic retrospectives. Empty in Phase 1. | no |
Vector search runs via two SQL functions (match_interactions, match_artifacts) in the migration — supabase-js doesn't expose pgvector operators directly, so we wrap them in RPCs.
Every schema change must be a new migration file under supabase/migrations/. Never edit existing migrations once they've been applied. Never use Studio's UI for schema work. supabase db reset is the source of truth for what the schema actually is.