{"id":40292201,"url":"https://github.com/frumu-ai/tandem","last_synced_at":"2026-03-11T15:13:57.755Z","repository":{"id":333358108,"uuid":"1136405944","full_name":"frumu-ai/tandem","owner":"frumu-ai","description":"Your AI coworker for any folder: local-first, secure by design, cross-platform, and built for supervised automation.","archived":false,"fork":false,"pushed_at":"2026-03-08T23:05:04.000Z","size":37370,"stargazers_count":71,"open_issues_count":1,"forks_count":7,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-03-09T04:42:52.090Z","etag":null,"topics":["anthropic","docs","help-wanted","human-in-the-loop","local-first","ollama","openai","opencode","openrouter"],"latest_commit_sha":null,"homepage":"https://tandem.frumu.ai/","language":"Rust","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/frumu-ai.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","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":{"github":"frumu-ai"}},"created_at":"2026-01-17T16:27:57.000Z","updated_at":"2026-03-08T23:05:08.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/frumu-ai/tandem","commit_stats":null,"previous_names":["frumu-ai/tandem"],"tags_count":81,"template":false,"template_full_name":null,"purl":"pkg:github/frumu-ai/tandem","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frumu-ai%2Ftandem","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frumu-ai%2Ftandem/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frumu-ai%2Ftandem/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frumu-ai%2Ftandem/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/frumu-ai","download_url":"https://codeload.github.com/frumu-ai/tandem/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frumu-ai%2Ftandem/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30292239,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-09T11:12:22.024Z","status":"ssl_error","status_checked_at":"2026-03-09T11:10:54.577Z","response_time":61,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["anthropic","docs","help-wanted","human-in-the-loop","local-first","ollama","openai","opencode","openrouter"],"created_at":"2026-01-20T05:00:15.702Z","updated_at":"2026-03-11T15:13:57.748Z","avatar_url":"https://github.com/frumu-ai.png","language":"Rust","readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\".github/assets/logo.png\" alt=\"Tandem Logo\" width=\"500\"\u003e\n  \n  \u003cp\u003e\n    \u003ca href=\"https://tandem.frumu.ai/\"\u003e\u003cimg src=\"https://img.shields.io/website?url=https%3A%2F%2Ftandem.frumu.ai%2F\u0026label=tandem.frumu.ai\u0026logo=firefox\u0026style=for-the-badge\" alt=\"Website\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/frumu-ai/tandem/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://img.shields.io/github/actions/workflow/status/frumu-ai/tandem/ci.yml?branch=main\u0026label=CI\u0026style=for-the-badge\" alt=\"CI\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/frumu-ai/tandem/actions/workflows/publish-registries.yml\"\u003e\u003cimg src=\"https://img.shields.io/github/actions/workflow/status/frumu-ai/tandem/publish-registries.yml?branch=main\u0026label=Publish%20Registries\u0026style=for-the-badge\" alt=\"Registry Publish\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/frumu-ai/tandem/releases\"\u003e\u003cimg src=\"https://img.shields.io/github/v/release/frumu-ai/tandem?label=release\u0026style=for-the-badge\" alt=\"Latest Release\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://www.npmjs.com/package/@frumu/tandem-client\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/%40frumu%2Ftandem-client?label=npm%20client\u0026style=for-the-badge\" alt=\"npm client\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://pypi.org/project/tandem-client/\"\u003e\u003cimg src=\"https://img.shields.io/pypi/v/tandem-client?label=PyPI%20client\u0026style=for-the-badge\" alt=\"PyPI client\"\u003e\u003c/a\u003e\n    \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-MIT-yellow.svg?style=for-the-badge\" alt=\"License: MIT\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/sponsors/frumu-ai\"\u003e\u003cimg src=\"https://img.shields.io/badge/sponsor-30363D?logo=GitHub-Sponsors\u0026logoColor=%23EA4AAA\u0026style=for-the-badge\" alt=\"Sponsor\"\u003e\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n\n## Tandem\n\nTandem is an **engine-owned workflow runtime** for coordinated autonomous work.\n\nWhile the current landscape of AI agents is flooded with \"chat-first assistants,\" these conversational routing models inevitably fail at scale due to context bloat and concurrency blindness. **Chat is fine as an interface, but it is weak as an authoritative coordination substrate for parallel, durable engineering workflows.**\n\nTandem takes a fundamentally different approach to tackle the complex realities of agentic engineering. **We treat autonomous execution as a distributed systems problem**, prioritizing robust engine state over fragile chat transcripts.\n\nIt provides durable coordination primitives—blackboards, workboards, explicit task claiming, operational memory accumulation, and checkpoints—allowing multiple agents to work concurrently on complex, long-running software engineering and automation tasks without colliding.\n\n- **Multiple clients, one engine:** The desktop app, TUI, and headless APIs all operate on the exact same materialized state truth.\n- **Engine-owned orchestration:** Shared task state, replay, approvals, and deterministic workflow projections natively solve coordination failures.\n- **Provider agnostic:** Use OpenRouter, Anthropic, OpenAI, OpenCode Zen, or local Ollama endpoints effortlessly.\n\n`Durable State → Workboards → Agent Swarm → Artifacts`\n\n**→ [Download desktop app](https://tandem.frumu.ai/) · [Deploy on a VPS (5 min)](examples/agent-quickstart/) · [Read the docs](https://tandem.docs.frumu.ai/)**\n\n## Language options\n\n- English: [README.md](README.md)\n- 简体中文: [README.zh-CN.md](README.zh-CN.md)\n- Translations (contribution guide): [docs/README_TRANSLATIONS.md](docs/README_TRANSLATIONS.md)\n\n## 30-second quickstart\n\n### Desktop\n\n1. Download and launch Tandem: [tandem.frumu.ai](https://tandem.frumu.ai/)\n2. Open **Settings** and add a provider API key.\n3. Select a workspace folder.\n4. Start with a task prompt and choose **Immediate** or **Plan Mode**.\n\n### Headless (server/VPS)\n\n**Option 1: Quick Start (Run instantly)**\nRun the pre-built control panel directly (it automatically downloads and starts the engine):\n\n```bash\nnpx @frumu/tandem-panel\n```\n\n**Option 2: Hackable / Service Install (Modifiable source)**\nClone the repo to get the control panel source code, which allows you to modify it and install it as a background systemd service:\n\n```bash\ngit clone https://github.com/frumu-ai/tandem.git\ncd tandem/examples/agent-quickstart\nsudo bash setup-agent.sh\n```\n\nOpen the printed URL and sign in with the generated key!\n\n## Architecture\n\n```mermaid\ngraph TD\n    %% Clients\n    Desktop[Desktop App]\n    ControlPanel[Web Control Panel]\n    TUI[Terminal UI]\n    API[SDKs \u0026 API Clients]\n\n    subgraph \"Tandem Engine (Source of Truth)\"\n        Orchestrator[Orchestration \u0026 Approvals]\n        Blackboard[(Blackboard \u0026 Shared State)]\n        Memory[(Vector Memory \u0026 Checkpoints)]\n        Worktrees[Git Worktree Isolation]\n    end\n\n    subgraph \"Agent Swarm\"\n        Planner[Planner Agent]\n        Builder[Builder Agent]\n        Validator[Verifier Agent]\n    end\n\n    Desktop -.-\u003e Orchestrator\n    ControlPanel -.-\u003e Orchestrator\n    TUI -.-\u003e Orchestrator\n    API -.-\u003e Orchestrator\n\n    Orchestrator --\u003e Blackboard\n    Orchestrator --\u003e Memory\n    Orchestrator --\u003e Worktrees\n\n    Blackboard \u003c--\u003e Planner\n    Blackboard \u003c--\u003e Builder\n    Blackboard \u003c--\u003e Validator\n```\n\n## Common workflows\n\n| Task                               | What Tandem does                                                               |\n| ---------------------------------- | ------------------------------------------------------------------------------ |\n| Refactor a codebase safely         | Scans files, proposes a staged plan, shows diffs, and applies approved changes |\n| Research and summarize sources     | Reads multiple references and outputs structured summaries                     |\n| Generate recurring reports         | Runs scheduled automations and produces markdown/dashboard artifacts           |\n| Connect external tools through MCP | Uses configured MCP connectors with approval-aware execution                   |\n| Operate AI workflows via API       | Run sessions through local/headless HTTP + SSE endpoints                       |\n\n## Features\n\n### Engine-Owned Workflow Runtime\n\n- **Coordinated autonomous work:** Explicit blackboards over conversational thread dumping.\n- **Multi-simultaneous agents:** Manage parallel execution through Git Worktree Isolation and patch streams.\n- **State survival:** Checkpoints, replayable event history, and materialized run states.\n- **Approval gates:** Keep humans in control with supervised tool flows for destructive actions.\n\n### Multi-Agent Orchestration\n\n- **Kanban-driven execution:** Agents claim tasks, report blockers, and hand off work through deterministic state.\n- **Memory-aware swarms:** Agents learn from prior runs, extracting fixes and failure patterns automatically.\n- **Revisioned coordination:** Engine-enforced locks prevent agents from trampling the same codebase simultaneously.\n\n### Integrations and automation\n\n- MCP tool connectors\n- Scheduled automations and routines\n- Headless runtime with HTTP + SSE APIs\n- Desktop runtime for Windows, macOS, and Linux\n\n### Security and local-first controls\n\n- API keys encrypted in local SecureKeyStore (AES-256-GCM)\n- Workspace access is scoped to folders you explicitly grant\n- Write/delete operations require approval via supervised tool flow\n- Sensitive paths denied by default (`.env`, `.ssh/*`, `*.pem`, `*.key`, secrets folders)\n- No analytics or call-home telemetry from Tandem itself\n\n### Outputs and artifacts\n\n- Markdown reports\n- HTML dashboards\n- PowerPoint (`.pptx`) generation\n\n## Programmatic API\n\nThe SDKs are API clients. They do **not** bundle `tandem-engine`.  \nYou need a running Tandem runtime (desktop sidecar or headless engine) and then use the SDKs to create sessions, trigger runs, and stream events.\n\nRuntime options:\n\n- Desktop app running locally (starts the sidecar runtime)\n- Headless engine via npm:\n\n  ```bash\n  npm install -g @frumu/tandem\n  tandem-engine serve --hostname 127.0.0.1 --port 39731\n  ```\n\n- TypeScript SDK: [@frumu/tandem-client](https://www.npmjs.com/package/@frumu/tandem-client)\n- Python SDK: [tandem-client](https://pypi.org/project/tandem-client/)\n- Engine package: [@frumu/tandem](https://www.npmjs.com/package/@frumu/tandem)\n\n```typescript\n// npm install @frumu/tandem-client\nimport { TandemClient } from \"@frumu/tandem-client\";\n\nconst client = new TandemClient({ baseUrl: \"http://localhost:39731\", token: \"...\" });\nconst sessionId = await client.sessions.create({ title: \"My agent\" });\nconst { runId } = await client.sessions.promptAsync(sessionId, \"Summarize README.md\");\n\nfor await (const event of client.stream(sessionId, runId)) {\n  if (event.type === \"session.response\") process.stdout.write(event.properties.delta ?? \"\");\n}\n```\n\n```python\n# pip install tandem-client\nfrom tandem_client import TandemClient\n\nasync with TandemClient(base_url=\"http://localhost:39731\", token=\"...\") as client:\n    session_id = await client.sessions.create(title=\"My agent\")\n    run = await client.sessions.prompt_async(session_id, \"Summarize README.md\")\n    async for event in client.stream(session_id, run.run_id):\n        if event.type == \"session.response\":\n            print(event.properties.get(\"delta\", \"\"), end=\"\", flush=True)\n```\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\".github/assets/app.png\" alt=\"Tandem AI Workspace\" width=\"90%\"\u003e\n\u003c/div\u003e\n\n## Provider setup\n\nConfigure providers in **Settings**.\n\n| Provider          | Description                                      | Get API key                                                          |\n| ----------------- | ------------------------------------------------ | -------------------------------------------------------------------- |\n| **OpenRouter** ⭐ | Access many models through one API               | [openrouter.ai/keys](https://openrouter.ai/keys)                     |\n| **OpenCode Zen**  | Fast, cost-effective models optimized for coding | [opencode.ai/zen](https://opencode.ai/zen)                           |\n| **Anthropic**     | Anthropic models (Sonnet, Opus, Haiku)           | [console.anthropic.com](https://console.anthropic.com/settings/keys) |\n| **OpenAI**        | GPT models and OpenAI endpoints                  | [platform.openai.com](https://platform.openai.com/api-keys)          |\n| **Ollama**        | Local models (no remote API key required)        | [Setup Guide](docs/OLLAMA_GUIDE.md)                                  |\n| **Custom**        | OpenAI-compatible API endpoint                   | Configure endpoint URL                                               |\n\n## Design principles\n\n- **Local-first runtime**: Data and state stay on your machine unless you send prompts/tools to configured providers.\n- **Supervised execution**: AI runs through controlled tools with explicit approvals for write/delete operations.\n- **Provider agnostic**: Route through the model providers you choose.\n- **Open source and auditable**: MIT repo license and `MIT OR Apache-2.0` for Rust crates.\n\n## Security and privacy\n\n- **Telemetry**: Tandem does not include analytics/tracking or call-home telemetry.\n- **Provider traffic**: AI request content is sent only to endpoints you configure (cloud providers or local Ollama/custom endpoints).\n- **Network scope**: Desktop runtime communicates with the local sidecar (`127.0.0.1`) and configured endpoints.\n- **Updater/release checks**: App update and release metadata flows can contact GitHub endpoints.\n- **Credential storage**: Provider keys are stored encrypted (AES-256-GCM).\n- **Filesystem safety**: Access is scoped to granted folders; sensitive paths are denied by default.\n\nFor the full threat model and reporting process, see [SECURITY.md](SECURITY.md).\n\n## Learn more\n\n- Architecture overview: [ARCHITECTURE.md](ARCHITECTURE.md)\n- Engine runtime + CLI reference: [docs/ENGINE_CLI.md](docs/ENGINE_CLI.md)\n- Desktop/runtime communication contract: [docs/ENGINE_COMMUNICATION.md](docs/ENGINE_COMMUNICATION.md)\n- Engine testing and smoke checks: [docs/ENGINE_TESTING.md](docs/ENGINE_TESTING.md)\n- Docs portal: [tandem.docs.frumu.ai](https://tandem.docs.frumu.ai/)\n\nAdvanced MCP behavior (including OAuth/auth-required flows and retries) is documented in [docs/ENGINE_CLI.md](docs/ENGINE_CLI.md).\n\n## Advanced setup (build from source)\n\n### Prerequisites\n\n- [Node.js](https://nodejs.org/) 20+\n- [Rust](https://rustup.rs/) 1.75+ (includes `cargo`)\n- [pnpm](https://pnpm.io/) (recommended) or npm\n\n| Platform | Additional requirements                                                                          |\n| -------- | ------------------------------------------------------------------------------------------------ |\n| Windows  | [Build Tools for Visual Studio](https://visualstudio.microsoft.com/downloads/)                   |\n| macOS    | Xcode Command Line Tools: `xcode-select --install`                                               |\n| Linux    | `libwebkit2gtk-4.1-dev`, `libappindicator3-dev`, `librsvg2-dev`, `build-essential`, `pkg-config` |\n\n### Local development\n\n```bash\ngit clone https://github.com/frumu-ai/tandem.git\ncd tandem\npnpm install\ncargo build -p tandem-ai\npnpm tauri dev\n```\n\n### Production build and signing notes\n\n```bash\npnpm tauri build\n```\n\nFor local self-built updater artifacts, generate your own signing keys and configure:\n\n1. `pnpm tauri signer generate -w ./src-tauri/tandem.key`\n2. `TAURI_SIGNING_PRIVATE_KEY`\n3. `TAURI_SIGNING_PASSWORD`\n4. `pubkey` in `src-tauri/tauri.conf.json`\n\nReference: [Tauri signing documentation](https://tauri.app/v1/guides/distribution/updater/#signing-updates)\n\nOutput paths:\n\n```bash\n# Windows: src-tauri/target/release/bundle/msi/\n# macOS:   src-tauri/target/release/bundle/dmg/\n# Linux:   src-tauri/target/release/bundle/appimage/\n```\n\n### macOS install troubleshooting\n\nIf a downloaded `.dmg` shows \"damaged\" or \"corrupted\", Gatekeeper is usually rejecting an app bundle/DMG that is not Developer ID signed and notarized.\n\n1. Confirm the correct architecture (`aarch64/arm64` vs `x86_64/x64`).\n2. Try opening via Finder (`Right click -\u003e Open` or `System Settings -\u003e Privacy \u0026 Security -\u003e Open Anyway`).\n3. For non-technical distribution, ship signed + notarized artifacts from release automation.\n\n## Contributing\n\nContributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md).\n\n```bash\n# Run lints\npnpm lint\n\n# Run tests\npnpm test\ncargo test\n\n# Format code\npnpm format\ncargo fmt\n```\n\nEngine-specific build/run/smoke instructions: `docs/ENGINE_TESTING.md`  \nEngine CLI usage reference: `docs/ENGINE_CLI.md`  \nEngine runtime communication contract: `docs/ENGINE_COMMUNICATION.md`\n\n### Maintainer release note\n\n- Desktop binary/app release: `.github/workflows/release.yml` (tag pattern `v*`)\n- Registry publish (crates.io + npm wrappers): `.github/workflows/publish-registries.yml` (manual trigger or `publish-v*`)\n- The workflows are intentionally separate\n\n## Project structure\n\n```text\ntandem/\n├── src/                    # React frontend\n│   ├── components/         # UI components\n│   ├── hooks/              # React hooks\n│   └── lib/                # Utilities\n├── src-tauri/              # Rust backend\n│   ├── src/                # Rust source\n│   ├── capabilities/       # Permission config\n│   └── binaries/           # Sidecar (gitignored)\n├── scripts/                # Build scripts\n└── docs/                   # Documentation\n```\n\n## Roadmap\n\n- [x] **Phase 1: Security Foundation** - Encrypted vault, permission system\n- [x] **Phase 2: Sidecar Integration** - Tandem agent runtime\n- [x] **Phase 3: Glass UI** - Modern, polished interface\n- [x] **Phase 4: Provider Routing** - Multi-provider support\n- [x] **Phase 5: Agent Capabilities** - Multi-mode agents, execution planning\n- [x] **Phase 6: Project Management** - Multi-workspace support\n- [x] **Phase 7: Advanced Presentations** - PPTX export engine, theme mapping, explicit positioning\n- [x] **Phase 8: Brand Evolution** - Rubik 900 typography, polished boot sequence\n- [x] **Phase 9: Memory \u0026 Context** - Vector database integration (`sqlite-vec`)\n- [x] **Phase 10: Skills System** - Importable agent skills and custom instructions\n- [ ] **Phase 11: Browser Integration** - Web content access\n- [ ] **Phase 12: Team Features** - Collaboration tools\n- [ ] **Phase 13: Mobile Companion** - iOS/Android apps\n\n## Support this project\n\nIf Tandem saves you time, consider [sponsoring development](https://github.com/sponsors/frumu-ai).\n\n[❤️ Become a Sponsor](https://github.com/sponsors/frumu-ai)\n\n## Star history\n\n[![Star History Chart](https://api.star-history.com/svg?repos=frumu-ai/tandem\u0026type=date\u0026logscale\u0026legend=top-left)](https://www.star-history.com/#frumu-ai/tandem\u0026type=date\u0026logscale\u0026legend=top-left)\n\n## License\n\n- Repository license text: [MIT](LICENSE)\n- Rust crates (`crates/*`): `MIT OR Apache-2.0` (see [LICENSE](LICENSE) and [LICENSE-APACHE](LICENSE-APACHE))\n\n## Acknowledgments\n\n- [Anthropic](https://anthropic.com) for the Cowork inspiration\n- [Tauri](https://tauri.app) for the secure desktop framework\n- The open source community\n","funding_links":["https://github.com/sponsors/frumu-ai"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrumu-ai%2Ftandem","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffrumu-ai%2Ftandem","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrumu-ai%2Ftandem/lists"}