{"id":51856284,"url":"https://github.com/ellmos-ai/gardener","last_synced_at":"2026-07-24T01:03:50.271Z","repository":{"id":349849399,"uuid":"1182075695","full_name":"ellmos-ai/gardener","owner":"ellmos-ai","description":"Gardener -- LLM-native operating system. Everything lives in a searchable SQLite database. Four functions, two databases, one search.","archived":false,"fork":false,"pushed_at":"2026-07-03T21:55:51.000Z","size":362,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-07-03T23:26:57.917Z","etag":null,"topics":["agent-framework","ai-agent","automation","cli","database-os","fts5","knowledge-management","llm","llm-agents","llm-native","llm-operating-system","local-first","memory-system","open-source","operating-system","python","searchable-memory","sqlite","sqlite-agent-memory","task-management"],"latest_commit_sha":null,"homepage":"https://github.com/ellmos-ai/gardener#readme","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ellmos-ai.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"custom":["https://paypal.me/lukasgeiger2507"]}},"created_at":"2026-03-15T02:14:44.000Z","updated_at":"2026-07-03T21:55:54.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ellmos-ai/gardener","commit_stats":null,"previous_names":["ellmos-ai/gardener"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ellmos-ai/gardener","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ellmos-ai%2Fgardener","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ellmos-ai%2Fgardener/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ellmos-ai%2Fgardener/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ellmos-ai%2Fgardener/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ellmos-ai","download_url":"https://codeload.github.com/ellmos-ai/gardener/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ellmos-ai%2Fgardener/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35822076,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-07-23T02:00:06.683Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-framework","ai-agent","automation","cli","database-os","fts5","knowledge-management","llm","llm-agents","llm-native","llm-operating-system","local-first","memory-system","open-source","operating-system","python","searchable-memory","sqlite","sqlite-agent-memory","task-management"],"created_at":"2026-07-24T01:03:48.108Z","updated_at":"2026-07-24T01:03:50.263Z","avatar_url":"https://github.com/ellmos-ai.png","language":"Python","funding_links":["https://paypal.me/lukasgeiger2507"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"logo.jpg\" alt=\"gardener logo\" width=\"300\"\u003e\n\u003c/p\u003e\n\n# gardener — Database-Based OS for LLMs\n\n[![Gardener tests](https://github.com/ellmos-ai/gardener/actions/workflows/tests.yml/badge.svg)](https://github.com/ellmos-ai/gardener/actions/workflows/tests.yml)\n\n**🇩🇪 [Deutsche Version](README_de.md)**\n\n\u003e Status: Prototype | Author: Lukas Geiger + Claude | 2026-03-12\n\n## What is Gardener?\n\nAn operating system built for LLMs. Everything lives in a searchable\ndatabase. Four functions are all you need.\n\n## Discovery Context\n\nUse the canonical search phrase `ellmos-ai/gardener` when you need this\nrepository. The short name `gardener` collides with gardening sites, Sesame\nStreet results, and unrelated database-operating-system research. This project\nis specifically the ellmos SQLite memory substrate for LLM agents: one\n`everything` table, FTS5 search, and the four primitives `find`, `get`, `put`,\nand `run`.\n\n## Quickstart\n\n```python\nfrom gardener import Gardener\naf = Gardener()\n\n# Search\naf.find(\"taxes\")\n\n# Read\naf.get(\"receipt-scanner\")\n\n# Write\naf.put(\"note\", content=\"Important!\", type=\"memory\", tags=\"todo\")\n\n# Execute\naf.run(\"file-info\", input={\"path\": \"/path/to/file\"})\n```\n\n## CLI\n\n```bash\npython gardener.py find \u003cquery\u003e\npython gardener.py get \u003cname\u003e\npython gardener.py put \u003cname\u003e \u003ctext\u003e\npython gardener.py run \u003cname\u003e\npython gardener.py absorb \u003cfile\u003e\npython gardener.py materialize \u003cname\u003e\npython gardener.py sync\npython gardener.py observe\npython gardener.py observe-source add \u003cid\u003e \u003ckind\u003e [key=value ...]\npython gardener.py observe-source list\npython gardener.py observe-source remove \u003cid\u003e\npython gardener.py observe-source refresh [id]\npython gardener.py status\n```\n\nThe CLI help defaults to German. Set `GARDENER_LANG=en` for English help\ntext; unsupported languages fall back to German and English.\n\n## Architecture\n\n```\nGardener/\n  gardener.py          # Core: Gardener class + CLI\n  seed.py              # Initial system knowledge\n  KONZEPT.md           # Design documentation (German)\n  README.md            # This file\n  workspace/           # Materialized code for execution\n  blobs/               # Storage for large files (\u003e50MB)\n\nLocal (not in cloud, override with GARDENER_DATA):\n  ~/.gardener/\n    gardener.db        # System: Knowledge, tools, blueprints\n    user.db            # User: Memory, tasks, personal data\n    blobs/             # Large files\n\nUser directory (cloud ok, override with GARDENER_HOME):\n  ~/gardener/\n    .absorber/         # Files here → automatically absorbed into DB\n    .output/           # Materialized files appear here\n    documents/         # Observed files (LLM reads along)\n```\n\n## Data Model\n\nOne table for (almost) everything:\n\n| Type | Description | Target DB |\n|------|-------------|-----------|\n| knowledge | Knowledge, docs, rules | gardener.db |\n| tool | Executable code | gardener.db |\n| memory | Memories, notes | user.db |\n| task | Tasks | user.db |\n| document | Absorbed files | user.db |\n| observed | Observed files | user.db |\n| config | Configuration | user.db |\n| export | Marked for materialization | user.db |\n\n## Memory (No Separate Memory System!)\n\nInstead of 5 tables: everything in `everything` with types and meta fields.\nThe FTS5 search IS the associative memory.\n\n```python\naf.memo(\"Quick note\")                    # Working memory (decays fast)\naf.lesson(\"Title\", \"Insight\")            # Best practice (barely decays)\naf.session_end(\"Summary\")               # Session report\naf.recall(\"taxes\")                       # Remember (searches + boosts weight)\naf.consolidate()                         # Sleep: Decay + Forget\n```\n\n```bash\ngardener memo \u003ctext\u003e            # Note\ngardener lesson \u003ctitle\u003e [text]  # Lesson\ngardener recall \u003cquery\u003e         # Remember\ngardener consolidate            # Consolidate\ngardener session-end \u003ctext\u003e     # End session\n```\n\nDetails: [KONZEPT.md#memory](KONZEPT.md#memory-kein-separates-gedächtnis-system-design-entscheidung)\n\n## Tasks (No Separate System!)\n\nTasks are entries of type `task` in the `everything` table. **No separate\ntask system needed.** `find(\"taxes\")` finds knowledge AND tasks simultaneously.\n\n```python\naf.task(\"taxes-2025\", content=\"File return\", priority=\"high\", due=\"2026-05-31\")\naf.tasks()                     # All tasks\naf.tasks(status=\"open\")        # Open only\naf.task_done(\"taxes-2025\")     # Mark done\n```\n\n```bash\ngardener task \u003cname\u003e [text]     # Create\ngardener tasks [status]         # List\ngardener done \u003cname\u003e            # Mark done\n```\n\nDetails: [KONZEPT.md#tasks](KONZEPT.md#tasks-kein-separates-system-design-entscheidung)\n\n## Three Relationships with Files\n\n1. **Observe:** File stays in folder, LLM reads along (looking out the window)\n2. **Absorb:** File gets pulled into the DB (now lives in the house)\n3. **Direct edit:** LLM edits file in folder (working in front of the house)\n\n## Transporter\n\n```python\naf.absorb(\"/path/to/file.pdf\")     # File → DB (dematerialize)\naf.materialize(\"file.pdf\")          # DB → File (rematerialize)\n```\n\n## Cross-Source Federated Index\n\n`observe()` watches Gardener's own home folder. **Observe-sources** extend\nthe same read-only principle to knowledge that lives in *other* tools:\ntheir originals are never touched, moved, or copied in — only their text\nis added to Gardener's FTS index, and every indexed entry carries a\n`source_ref` in its `meta` so a search hit can be traced back to exactly\nwhere it came from (file path, DB table + row, or transcript line).\n`find()` already searches `gardener.db` + `user.db` in one query, so\nobserved cross-source hits show up right alongside your own entries —\nno separate search call needed.\n\nFour source kinds:\n\n| Kind | What it indexes | Key config |\n|------|------------------|------------|\n| `markdown_dir` | A directory of markdown files, one entry per file. The `path` may itself be a glob spanning several directories (e.g. a per-project memory convention). `patterns` widens this to other file kinds (e.g. `.txt` notes). | `path`, `patterns` (list, default `[\"*.md\"]`), `glob` (single-pattern legacy alias) |\n| `remember_files` | Small note files anywhere below a root, found via a recursive glob. | `path`, `glob` (default `**/.remember`) |\n| `sqlite_table` | A single table in a foreign SQLite database, opened strictly read-only (`mode=ro`). Column names are whitelisted against the live schema before use. | `db_path`, `table`, `columns` (`content` required; `id`/`name`/`tags` optional) |\n| `agent_transcripts` | JSONL chat transcripts, indexed line by line, **text turns only** (tool calls/results and internal \"thinking\" blocks are skipped). Ships a built-in field mapping for Claude Code's own transcript format; any other line-based JSON transcript can be indexed via a generic dotted-path role/text mapping. Large, growing files are tailed from a saved byte offset — a refresh never re-reads what it already indexed. | `path` (glob, `**` recurses), `format` (`claude_code` default, or `generic` with `role_field`/`text_field`) |\n\n```bash\n# Index this machine's Claude Code project memories\ngardener observe-source add claude-memories markdown_dir path=\"~/.claude/projects/*/memory\"\n\n# Index .remember notes anywhere below a root\ngardener observe-source add notes remember_files path=\"~/notes\"\n\n# Index a table in a foreign, read-only SQLite database\ngardener observe-source add tasks-db sqlite_table db_path=\"~/.some-tool/tool.db\" table=tasks\n\n# Index Claude Code transcripts (main conversation, text turns only)\ngardener observe-source add claude-transcripts agent_transcripts path=\"~/.claude/projects/*/**/*.jsonl\"\n\ngardener observe-source list\ngardener observe-source refresh              # all sources\ngardener observe-source refresh claude-memories\ngardener observe-source remove claude-memories\n```\n\n```python\naf.observe_source_add(\"claude-memories\", \"markdown_dir\",\n                       path=\"~/.claude/projects/*/memory\")\naf.observe_sources()                          # refresh all configured sources\naf.find(\"taxes\")                              # own entries + observed hits, one query\n\n# List-valued config like `patterns` needs the Python API -- the CLI's\n# plain key=value form only accepts strings, not JSON.\naf.observe_source_add(\"mixed-notes\", \"markdown_dir\",\n                       path=\"~/notes\", patterns=[\"*.md\", \"*.txt\"])\n```\n\nThe `sqlite_table` adapter's `columns` mapping lets it point at any\nforeign table without Gardener knowing its schema in advance — e.g. a\ntask or notes table kept by a different local tool. Configuration lives\nin `config.json` under `observe_sources`; nothing here is hardcoded to a\nspecific machine or tool.\n\n## Seeding\n\n```bash\npython seed.py    # Populates gardener.db with base knowledge and example tools\n```\n\n## Comparison: Gardener vs Rinnsal\n\nGardener and [Rinnsal](https://github.com/ellmos-ai/rinnsal) are both lightweight\nLLM operating systems from the ellmos ecosystem. Here are the differences:\n\n| Feature | Detail | **Gardener** | **Rinnsal** |\n|---|---|---|---|\n| **Core API** | Style | 4 functions (find/get/put/run) | ~20 CLI commands, module-based |\n| **Data Model** | Tables | 1 (`everything` + type field) | 4+ (facts, notes, lessons, sessions) |\n| | FTS5 Search | Yes (core feature, IS the memory) | No (structured queries) |\n| **Memory** | Working | memo() with decay | notes (session-scoped) |\n| | Long-term | lesson() + weighting | facts (confidence score) |\n| | Consolidation | consolidate() (decay+forget) | No |\n| | Recall/Boost | recall() boosts weight | No |\n| | Context Export | No | api.context() (LLM-ready) |\n| **Tasks** | Priorities | Yes (meta field) | critical/high/medium/low |\n| | Agent Assignment | No | Yes |\n| | Deadlines | Yes (due field) | No |\n| **Files** | Absorb (file→DB) | Yes | No |\n| | Materialize (DB→file) | Yes | No |\n| | Observe (watch) | Yes | No |\n| | Blob Storage (\u003e50MB) | Yes | No |\n| **Automation** | Chains | No | Marble-run model |\n| | Ollama | No | Yes (REST client) |\n| **Connectors** | Telegram/Discord/HA | No (planned) | Yes |\n| **Architecture** | Dependencies | Zero | Zero |\n| | Event Bus | No | Yes |\n| | Multi-Agent | No | Yes (event bus + USMC) |\n\n**In short:** Gardener = radical minimalism (1 table, search = everything).\nRinnsal = more structure, but connectors and chains out of the box.\n\n## Extensibility\n\nGardener is designed as a core that can be extended with ellmos modules:\n\n| Module | Function | Status |\n|--------|----------|--------|\n| [connectors](https://github.com/ellmos-ai/connectors) | Telegram, Discord, Webhook, etc. | Planned |\n| [USMC](https://github.com/ellmos-ai/usmc) | Cross-Agent Shared Memory | Integrable |\n| [clutch](https://github.com/ellmos-ai/clutch) | Smart Model Routing | Integrable |\n| [swarm-ai](https://github.com/ellmos-ai/swarm-ai) | Parallel LLM Patterns | Integrable |\n\nThe vision: The LLM serves itself from a library of modules.\nGardener provides search, memory, and the execution environment —\neverything else is added as a plugin when needed.\n\n## Security Model (Read This)\n\nGardener is a **local, single-user tool with no sandbox — by design**. Be\naware of what that means before feeding it untrusted content:\n\n- `run(name)` executes the Python code stored in an entry's content **with\n  the full permissions of your user account**. There is no isolation, no\n  restricted builtins, no network or filesystem limits.\n- The seeded `shell` tool executes arbitrary shell commands\n  (`subprocess.run(..., shell=True)`).\n- Anything that can call `put()` can therefore achieve code execution via\n  `run()`. If you expose Gardener through another layer (e.g. an MCP server\n  or a chat agent), that layer inherits this power — add your own\n  authorization there.\n\n**Rule of thumb:** only absorb, put, and run content you trust as much as\ncode you would execute yourself.\n\n## Design Document\n\nDetailed design documentation: [KONZEPT.md](KONZEPT.md) (German)\n\n---\n\n## Haftung / Liability\n\nDieses Projekt ist eine **unentgeltliche Open-Source-Schenkung** im Sinne der §§ 516 ff. BGB. Die Haftung des Urhebers ist gemäß **§ 521 BGB** auf **Vorsatz und grobe Fahrlässigkeit** beschränkt. Ergänzend gelten die Haftungsausschlüsse aus GPL-3.0 / MIT / Apache-2.0 §§ 15–16 (je nach gewählter Lizenz).\n\nNutzung auf eigenes Risiko. Keine Wartungszusage, keine Verfügbarkeitsgarantie, keine Gewähr für Fehlerfreiheit oder Eignung für einen bestimmten Zweck.\n\nThis project is an unpaid open-source donation. Liability is limited to intent and gross negligence (§ 521 German Civil Code). Use at your own risk. No warranty, no maintenance guarantee, no fitness-for-purpose assumed.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fellmos-ai%2Fgardener","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fellmos-ai%2Fgardener","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fellmos-ai%2Fgardener/lists"}