yeschef-cli 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. yeschef_cli-0.1.0/.claude-plugin/marketplace.json +15 -0
  2. yeschef_cli-0.1.0/.claude-plugin/plugin.json +20 -0
  3. yeschef_cli-0.1.0/.github/workflows/publish.yml +62 -0
  4. yeschef_cli-0.1.0/.gitignore +12 -0
  5. yeschef_cli-0.1.0/.mcp.json +8 -0
  6. yeschef_cli-0.1.0/CHANGELOG.md +24 -0
  7. yeschef_cli-0.1.0/CLAUDE.md +49 -0
  8. yeschef_cli-0.1.0/LICENSE +21 -0
  9. yeschef_cli-0.1.0/PKG-INFO +254 -0
  10. yeschef_cli-0.1.0/README.md +233 -0
  11. yeschef_cli-0.1.0/SPEC.md +304 -0
  12. yeschef_cli-0.1.0/agents/yeschef-expediter.md +74 -0
  13. yeschef_cli-0.1.0/commands/setup.md +34 -0
  14. yeschef_cli-0.1.0/docs/AGENTS.md +98 -0
  15. yeschef_cli-0.1.0/docs/LAUNCH.md +59 -0
  16. yeschef_cli-0.1.0/docs/claude-demo.gif +0 -0
  17. yeschef_cli-0.1.0/docs/claude-demo.tape +45 -0
  18. yeschef_cli-0.1.0/docs/demo.gif +0 -0
  19. yeschef_cli-0.1.0/docs/demo.json +63 -0
  20. yeschef_cli-0.1.0/docs/demo.tape +25 -0
  21. yeschef_cli-0.1.0/examples/agents/claude-code-worker.toml +44 -0
  22. yeschef_cli-0.1.0/examples/agents/codex-worker.toml +40 -0
  23. yeschef_cli-0.1.0/examples/agents/ollama-worker.toml +30 -0
  24. yeschef_cli-0.1.0/examples/agents/openrouter-worker.toml +42 -0
  25. yeschef_cli-0.1.0/examples/agents/vllm-worker-with-tools.toml +41 -0
  26. yeschef_cli-0.1.0/examples/deploy/dev.yeschef.hub.plist +53 -0
  27. yeschef_cli-0.1.0/examples/deploy/windows.md +48 -0
  28. yeschef_cli-0.1.0/examples/deploy/yeschef-agent@.service +33 -0
  29. yeschef_cli-0.1.0/pyproject.toml +49 -0
  30. yeschef_cli-0.1.0/skills/yeschef/SKILL.md +212 -0
  31. yeschef_cli-0.1.0/src/yeschef/__init__.py +3 -0
  32. yeschef_cli-0.1.0/src/yeschef/__main__.py +6 -0
  33. yeschef_cli-0.1.0/src/yeschef/agent/__init__.py +6 -0
  34. yeschef_cli-0.1.0/src/yeschef/agent/backends/__init__.py +53 -0
  35. yeschef_cli-0.1.0/src/yeschef/agent/backends/anthropic_compat.py +119 -0
  36. yeschef_cli-0.1.0/src/yeschef/agent/backends/base.py +50 -0
  37. yeschef_cli-0.1.0/src/yeschef/agent/backends/cli.py +99 -0
  38. yeschef_cli-0.1.0/src/yeschef/agent/backends/openai_compat.py +118 -0
  39. yeschef_cli-0.1.0/src/yeschef/agent/config.py +98 -0
  40. yeschef_cli-0.1.0/src/yeschef/agent/detect.py +98 -0
  41. yeschef_cli-0.1.0/src/yeschef/agent/harness.py +1009 -0
  42. yeschef_cli-0.1.0/src/yeschef/cli.py +1073 -0
  43. yeschef_cli-0.1.0/src/yeschef/hub/__init__.py +16 -0
  44. yeschef_cli-0.1.0/src/yeschef/hub/api.py +595 -0
  45. yeschef_cli-0.1.0/src/yeschef/hub/app.py +43 -0
  46. yeschef_cli-0.1.0/src/yeschef/hub/dashboard.html +206 -0
  47. yeschef_cli-0.1.0/src/yeschef/hub/events.py +78 -0
  48. yeschef_cli-0.1.0/src/yeschef/hub/mcp_server.py +941 -0
  49. yeschef_cli-0.1.0/src/yeschef/hub/schema.sql +106 -0
  50. yeschef_cli-0.1.0/src/yeschef/hub/store.py +1621 -0
  51. yeschef_cli-0.1.0/src/yeschef/models.py +431 -0
  52. yeschef_cli-0.1.0/src/yeschef/procs.py +109 -0
  53. yeschef_cli-0.1.0/src/yeschef/replay.py +224 -0
  54. yeschef_cli-0.1.0/src/yeschef/resources/__init__.py +0 -0
  55. yeschef_cli-0.1.0/src/yeschef/resources/agents/__init__.py +0 -0
  56. yeschef_cli-0.1.0/src/yeschef/resources/agents/yeschef-expediter.md +74 -0
  57. yeschef_cli-0.1.0/src/yeschef/resources/skill/SKILL.md +212 -0
  58. yeschef_cli-0.1.0/src/yeschef/resources/skill/__init__.py +0 -0
  59. yeschef_cli-0.1.0/src/yeschef/sdk/__init__.py +9 -0
  60. yeschef_cli-0.1.0/src/yeschef/sdk/client.py +359 -0
  61. yeschef_cli-0.1.0/src/yeschef/settings.py +100 -0
  62. yeschef_cli-0.1.0/src/yeschef/tools/__init__.py +5 -0
  63. yeschef_cli-0.1.0/src/yeschef/tools/executor.py +296 -0
  64. yeschef_cli-0.1.0/tests/__init__.py +0 -0
  65. yeschef_cli-0.1.0/tests/conftest.py +37 -0
  66. yeschef_cli-0.1.0/tests/live.py +69 -0
  67. yeschef_cli-0.1.0/tests/mock_backend.py +67 -0
  68. yeschef_cli-0.1.0/tests/test_api.py +268 -0
  69. yeschef_cli-0.1.0/tests/test_backends.py +326 -0
  70. yeschef_cli-0.1.0/tests/test_buildout.py +259 -0
  71. yeschef_cli-0.1.0/tests/test_codex.py +58 -0
  72. yeschef_cli-0.1.0/tests/test_dashboard.py +68 -0
  73. yeschef_cli-0.1.0/tests/test_guards.py +452 -0
  74. yeschef_cli-0.1.0/tests/test_integration.py +629 -0
  75. yeschef_cli-0.1.0/tests/test_mcp.py +296 -0
  76. yeschef_cli-0.1.0/tests/test_onboarding.py +112 -0
  77. yeschef_cli-0.1.0/tests/test_plugin.py +40 -0
  78. yeschef_cli-0.1.0/tests/test_races.py +233 -0
  79. yeschef_cli-0.1.0/tests/test_replay.py +154 -0
  80. yeschef_cli-0.1.0/tests/test_rooms.py +205 -0
  81. yeschef_cli-0.1.0/tests/test_tasks.py +201 -0
  82. yeschef_cli-0.1.0/tests/test_tools.py +309 -0
  83. yeschef_cli-0.1.0/tests/test_ux_fixes.py +1613 -0
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "yeschef",
3
+ "owner": {
4
+ "name": "yeschef contributors",
5
+ "url": "https://github.com/labscommunity/yeschef"
6
+ },
7
+ "plugins": [
8
+ {
9
+ "name": "yeschef",
10
+ "source": ".",
11
+ "description": "yeschef \u2014 a kitchen for Claude Code and Codex: fire work to local-model cooks (or a cloud provider) on your own hardware."
12
+ }
13
+ ],
14
+ "description": "yeschef \u2014 a kitchen for Claude Code and Codex: fire work to local-model cooks (or a cloud provider) on your own hardware."
15
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "yeschef",
3
+ "description": "Give Claude Code and Codex a kitchen: fire work to local-model cooks on your own hardware that take the grunt work, plate the files they build, and never hit a rate limit.",
4
+ "version": "0.1.0",
5
+ "author": {
6
+ "name": "yeschef contributors",
7
+ "url": "https://github.com/labscommunity/yeschef"
8
+ },
9
+ "homepage": "https://github.com/labscommunity/yeschef",
10
+ "repository": "https://github.com/labscommunity/yeschef",
11
+ "license": "MIT",
12
+ "keywords": [
13
+ "local-llm",
14
+ "ollama",
15
+ "vllm",
16
+ "agents",
17
+ "task-dispatch",
18
+ "self-hosted"
19
+ ]
20
+ }
@@ -0,0 +1,62 @@
1
+ # Publish yeschef to PyPI via Trusted Publishing (OIDC) — no API token stored.
2
+ #
3
+ # One-time PyPI setup (owner must do this in the PyPI web UI, it can't be scripted):
4
+ # Since `yeschef` isn't published yet, add a PENDING trusted publisher:
5
+ # https://pypi.org/manage/account/publishing/ → "Add a new pending publisher"
6
+ # PyPI Project Name: yeschef-cli
7
+ # Owner: labscommunity
8
+ # Repository name: yeschef
9
+ # Workflow name: publish.yml
10
+ # Environment name: pypi
11
+ # After the first successful run it converts to a normal trusted publisher.
12
+ #
13
+ # To release: bump `version` in pyproject.toml, then publish a GitHub Release whose
14
+ # tag matches (e.g. v0.1.0). This workflow builds and publishes that version.
15
+
16
+ name: publish
17
+
18
+ on:
19
+ release:
20
+ types: [published]
21
+ workflow_dispatch: {} # manual run allowed (still gated by the `pypi` environment)
22
+
23
+ jobs:
24
+ build:
25
+ name: build sdist + wheel
26
+ runs-on: ubuntu-latest
27
+ steps:
28
+ - uses: actions/checkout@v4
29
+ - uses: actions/setup-python@v5
30
+ with:
31
+ python-version: "3.12"
32
+ - name: Build
33
+ run: |
34
+ python -m pip install --upgrade build
35
+ python -m build
36
+ - name: Check the built distributions
37
+ run: |
38
+ python -m pip install --upgrade twine
39
+ python -m twine check dist/*
40
+ - uses: actions/upload-artifact@v4
41
+ with:
42
+ name: dist
43
+ path: dist/
44
+
45
+ publish:
46
+ name: publish to PyPI
47
+ needs: build
48
+ runs-on: ubuntu-latest
49
+ # A dedicated environment lets you add required reviewers / branch rules to the
50
+ # publish step, and is what the PyPI trusted-publisher config binds to.
51
+ environment:
52
+ name: pypi
53
+ url: https://pypi.org/p/yeschef-cli
54
+ permissions:
55
+ id-token: write # REQUIRED: mints the OIDC token PyPI trusts. No password needed.
56
+ steps:
57
+ - uses: actions/download-artifact@v4
58
+ with:
59
+ name: dist
60
+ path: dist/
61
+ - name: Publish to PyPI (Trusted Publishing)
62
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,12 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ .venv/
4
+ .pytest_cache/
5
+ .ruff_cache/
6
+ *.egg-info/
7
+ dist/
8
+ build/
9
+ *.db
10
+ *.db-wal
11
+ *.db-shm
12
+ .env
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "yeschef": {
4
+ "type": "http",
5
+ "url": "http://localhost:8787/mcp"
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,24 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 — 2026-08-21
4
+
5
+ Initial release.
6
+
7
+ - Hub (SQLite + REST/SSE + MCP over HTTP), Python SDK, and worker harness for
8
+ dispatching tasks to local models (Ollama, vLLM, LM Studio, any OpenAI- or
9
+ Anthropic-compatible endpoint) and holding bounded multi-agent conversations.
10
+ - Two-command onboarding (`yeschef up` / `yeschef join`), auto-detection of local
11
+ model servers, background process management, `yeschef doctor`.
12
+ - Buildout support: per-task workspaces, produced files returned through the hub
13
+ (`task_files` / `task_file`), and a `cli` backend that runs a real coding-agent CLI
14
+ as the worker's engine.
15
+ - Claude Code plugin: `/yeschef:setup` install command, the yeschef skill, the
16
+ `yeschef-expediter` subagent (dispatched tasks appear in the subagent panel and
17
+ return on their own), and MCP wiring.
18
+ - Codex support: `yeschef mcp-proxy` bridges the hub's tools to Codex over stdio,
19
+ `yeschef up` auto-wires Codex's config.toml, and a `codex exec` worker example.
20
+ - Cloud-provider workers: `yeschef join --provider openrouter|openai|groq|together|
21
+ deepseek|fireworks` (or `--base-url` + `--api-key-env` for any endpoint); keys read
22
+ from the environment. Mix cloud and local workers on one hub.
23
+ - Security defaults: per-agent bearer tokens, registration gating, scoped reads,
24
+ bounded rooms, jailed and allowlisted worker tools.
@@ -0,0 +1,49 @@
1
+ # yeschef — working agreement
2
+
3
+ ## Commits (mandatory)
4
+
5
+ - **Never add a `Co-Authored-By` trailer.** Claude does not co-author commits, PRs, or
6
+ issues in this repo. No "Generated with Claude Code" footers either.
7
+ - **Conventional Commits are mandatory** for every commit:
8
+ `<type>(<optional scope>): <description>`
9
+ - Types: `feat`, `fix`, `docs`, `refactor`, `test`, `chore`, `perf`, `build`, `ci`.
10
+ - Scopes used here: `hub`, `sdk`, `agent`, `tools`, `cli`, `spec`.
11
+ - Description in imperative mood, lower-case, no trailing period.
12
+ - Breaking changes: `!` after the scope (`feat(hub)!: …`) plus a `BREAKING CHANGE:`
13
+ footer.
14
+ - Examples: `feat(hub): add round-robin floor control`,
15
+ `fix(sdk): retry SSE reconnect on 502`, `test(agent): cover claim race`.
16
+
17
+ ## Project shape
18
+
19
+ Read [SPEC.md](SPEC.md) before changing behavior — it is the contract. Three parts of
20
+ one package:
21
+
22
+ - `src/yeschef/hub/` — the hub: SQLite store, REST + SSE agent API, FastMCP tool
23
+ surface for Claude Code. Single process, runs on the hub box.
24
+ - `src/yeschef/sdk/` — client library. **This is the protocol contract**; anything
25
+ embedding it becomes a first-class agent. Keep it dependency-light (httpx only).
26
+ - `src/yeschef/agent/` — reference harness daemon + model backends.
27
+
28
+ ## Conventions
29
+
30
+ - Python 3.11+, `async` throughout the hub and SDK. Type hints on public functions.
31
+ - Formatting and linting: `ruff format` / `ruff check` (line length 100).
32
+ - Tests: `pytest` + `pytest-asyncio`, run with `uv run pytest`. Every hub state
33
+ transition needs a test; concurrency-sensitive paths (task claim, room floor control)
34
+ need a race test.
35
+ - Store: SQLite in WAL mode, single writer. All timestamps are hub-assigned UTC epoch
36
+ seconds (`float`). Agents never write times.
37
+ - Errors cross the wire as JSON `{"error": {"code": "...", "message": "..."}}` with a
38
+ stable machine-readable `code`.
39
+ - No secrets in the repo. Tokens come from the environment or `~/.yeschef/`.
40
+
41
+ ## Guardrails
42
+
43
+ - MCP tools must return in milliseconds. Any wait is explicit and capped at 60 s to stay
44
+ clear of Claude Code's ~2-minute auto-background threshold.
45
+ - Every autonomous room must be bounded by policy (max messages, token budget, idle
46
+ timeout). Never ship a code path that lets two agents loop unbounded.
47
+ - Worker-side tools are opt-in per agent and execute only on the worker node, never on
48
+ the hub.
49
+ - The hub binds to the LAN/Tailscale only. Never expose it through a Tailscale funnel.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 yeschef contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,254 @@
1
+ Metadata-Version: 2.5
2
+ Name: yeschef-cli
3
+ Version: 0.1.0
4
+ Summary: The farm team for Claude Code and Codex: local models on your own hardware that take the grunt work, return the files they build, and never hit a rate limit
5
+ License: MIT
6
+ License-File: LICENSE
7
+ Keywords: agents,claude-code,local-llm,mcp,ollama,self-hosted,vllm
8
+ Requires-Python: >=3.11
9
+ Requires-Dist: fastapi>=0.115
10
+ Requires-Dist: fastmcp>=2.10
11
+ Requires-Dist: httpx>=0.27
12
+ Requires-Dist: rich>=13.9
13
+ Requires-Dist: typer>=0.15
14
+ Requires-Dist: uvicorn[standard]>=0.32
15
+ Provides-Extra: dev
16
+ Requires-Dist: asgi-lifespan>=2.1; extra == 'dev'
17
+ Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
18
+ Requires-Dist: pytest>=8.3; extra == 'dev'
19
+ Requires-Dist: ruff>=0.8; extra == 'dev'
20
+ Description-Content-Type: text/markdown
21
+
22
+ # 🍳 yeschef
23
+
24
+ **A kitchen for Claude Code and Codex.** Local models on your own hardware — your line
25
+ of *cooks* — that take the grunt work, talk it out in bounded rooms, and never hit a
26
+ rate limit. You call the order; a cook works the ticket; the plate comes back.
27
+
28
+ You pay per token and wait out rate limits while the GPUs you already own sit idle.
29
+ yeschef turns them into a line Claude Code can actually run: fire a ticket, keep working,
30
+ check the pass whenever — from any session, days later. You're the chef doing the
31
+ thinking; the kitchen does the reps.
32
+
33
+ ![One prompt in Claude Code: fire a ticket to a local cook, the expediter subagent appears on the rail, and the finished plates come back on their own](docs/claude-demo.gif)
34
+
35
+ *One prompt, live session: Claude shows the line — every cook's model and machine
36
+ (`grill · ollama/qwen2.5:7b-instruct @ miner`) — fires the buildout, and spawns the
37
+ `yeschef-expediter` subagent, visible in the native panel like any subagent. The session
38
+ comes straight back to you; when the cook finishes, the expediter calls it back on its
39
+ own, plates the files in `./site`, and Claude tastes the cook's work against the spec.
40
+ No hovering, no "is it up yet."*
41
+
42
+ ```
43
+ Claude Code ──MCP/HTTP──▶ ┌─────────┐ ◀──REST+SSE── cook ──▶ Ollama (office-mac)
44
+ (any session, │ hub │ ◀──REST+SSE── cook ──▶ vLLM (gpu-box)
45
+ any machine) │ SQLite │ ◀──REST+SSE── cook ──▶ any /v1 (spare-pc)
46
+ │ (pass) │
47
+ └─────────┘
48
+ ```
49
+
50
+ | | Without a kitchen | With one |
51
+ |---|---|---|
52
+ | Grunt work (summarize, classify, extract, triage) | burns your Claude tokens | cooks on your hardware, $0 marginal |
53
+ | Rate-limited or throttled | you wait | the line keeps cooking |
54
+ | Long-running work | blocks the session, dies with it | fired to the background; ticket durable in SQLite, checkable from any session |
55
+ | A second opinion | another API call | two of your machines talk it over in a bounded room while you watch — and cut in |
56
+
57
+ ## Two commands
58
+
59
+ ```bash
60
+ uv tool install yeschef-cli # or: pipx install yeschef-cli — the command is `yeschef`
61
+
62
+ # 1. On the hub machine (where you run Claude Code) — generates tokens,
63
+ # wires Claude Code, prints the clock-in line:
64
+ yeschef up
65
+
66
+ # 2. On each machine that will cook — auto-detects Ollama / vLLM / LM Studio,
67
+ # verifies the model answers, clocks the cook in. Paste the line `up` printed:
68
+ yeschef join --hub http://hub-host:8787 --token <printed-by-up>
69
+ ```
70
+
71
+ That's the whole setup. Single-box demo: run both on one machine — `join` needs no flags
72
+ at all. `yeschef doctor` diagnoses anything that's off; `--detach`/`down`/`ps` run it all
73
+ in the background from one terminal. macOS, Linux, and Windows.
74
+
75
+ `yeschef up` wires **both Claude Code and Codex** if they're installed — Claude Code over
76
+ HTTP MCP, Codex over a stdio bridge (`yeschef mcp-proxy`). Same tools, same kitchen,
77
+ either client.
78
+
79
+ **Or let Claude Code install it.** This repo is also a Claude Code plugin:
80
+
81
+ ```
82
+ /plugin marketplace add labscommunity/yeschef
83
+ /plugin install yeschef@yeschef
84
+ ```
85
+
86
+ Then say "set up yeschef" (or run `/yeschef:setup`) and Claude installs the CLI, opens
87
+ the kitchen, wires the MCP connection, and hands you the cook clock-in line. The plugin
88
+ also ships the skill and the `yeschef-expediter` subagent automatically.
89
+
90
+ ## What it feels like
91
+
92
+ From Claude Code (wired automatically by `up`) — you just talk to it: *"fire the log
93
+ triage to a fast cook,"* *"have a cook draft the release notes,"* *"send the buildout to
94
+ the line."* Under the hood:
95
+
96
+ ```
97
+ > list_agents # your line, live
98
+ > submit_task("label these 400 log lines", selector="tier:fast")
99
+ → ticket_9f3k2p # fires immediately
100
+ > task_status("ticket_9f3k2p") # any time, any session
101
+ > task_result("ticket_9f3k2p")
102
+ → … lifetime: 62 tickets · ~1.2M tokens cooked locally · 9.4h on your hardware
103
+ > start_dialogue(["saucier", "grill"], goal="agree on a cache eviction policy")
104
+ > room_transcript("room_x7c2") # watch them work it out
105
+ ```
106
+
107
+ From your terminal:
108
+
109
+ ```bash
110
+ yeschef ask saucier "what's in today's error log?" # send, wait, print the reply
111
+ yeschef submit "draft release notes from this diff" --to grill
112
+ yeschef dialogue saucier grill --goal "pick a caching strategy" # follows it live
113
+ yeschef watch room_x7c2 --record demo.json # save a transcript
114
+ yeschef replay demo.json # re-stream it, real pacing
115
+ yeschef stats # what the kitchen has cooked for you
116
+ ```
117
+
118
+ The talking-it-out is the part you have to see: two of your machines, in different
119
+ colors, working a problem — and you can cut into the middle of it. Every room is
120
+ **bounded by construction** (message caps, token budgets, idle timeouts, stop phrases —
121
+ enforced by the hub, not by hoping), so nothing loops forever.
122
+
123
+ ![Two local models plan this exact demo while the human cuts in mid-conversation](docs/demo.gif)
124
+
125
+ *Real conversation, not a script. Two cooks on one GPU box argue about what this demo
126
+ should show — until the chef cuts in and overrules them both. The transcript ships in
127
+ this repo; after install, watch the identical conversation yourself with
128
+ `yeschef replay docs/demo.json`.*
129
+
130
+ ## Fire a buildout, get the dishes back
131
+
132
+ Every ticket with a workspace returns what it plates. A cook with file tools writes into
133
+ a per-ticket jail; a cook with the **`cli` backend** hands the whole ticket to a real
134
+ coding agent — the flagship config runs the full Claude Code harness against your own
135
+ local model:
136
+
137
+ ```toml
138
+ [backend]
139
+ type = "cli"
140
+ command = ["claude", "-p", "{prompt}", "--dangerously-skip-permissions"]
141
+ [backend.env]
142
+ ANTHROPIC_BASE_URL = "http://localhost:11434" # Ollama v0.14+ speaks Anthropic
143
+ ```
144
+
145
+ Deep agentic loop, zero API tokens, and everything it plates ships back through the pass:
146
+
147
+ ```
148
+ > submit_task("build the landing page from DESIGN.md", assignee="line-cook")
149
+ > wait_task("ticket_ab12cd") # one call/min, returns early when it's up
150
+ > task_files("ticket_ab12cd") # index.html · css/styles.css
151
+ > task_file("ticket_ab12cd", "index.html") # pull it, write it into the repo
152
+ ```
153
+
154
+ **See it on the rail (the subagent panel).** `yeschef install-skill` also installs the
155
+ `yeschef-expediter` subagent: spawn it in the background after firing a ticket and the
156
+ cook's job shows up in Claude Code's native panel like any subagent — the expo watches
157
+ it efficiently, plates the returned files into the project, and calls the result back
158
+ when the cook is done.
159
+
160
+ ## Isn't this what Agent Teams does?
161
+
162
+ Complementary, not competing. Native subagents and teams are Claude-only, same billing,
163
+ same cloud — excellent at parallel *thinking*. A kitchen is the other half:
164
+ **heterogeneous cooks that are free after hardware**, that keep going when you're
165
+ throttled, and whose ticket status outlives any session. Claude Code stays the chef and
166
+ fires the verifiable grunt work down the line.
167
+
168
+ ## What a cook is
169
+
170
+ `yeschef join` clocks one in from whatever model server it finds. A TOML config (see
171
+ [`examples/agents/`](examples/agents/)) is for pinning a persona, capability tags
172
+ (`tier:fast`, `tier:reasoning` — fire by tag and the first free match takes the ticket),
173
+ or **opt-in tools**: shell (pattern-allowlisted, metacharacter-screened), file access
174
+ (jailed to one directory), web fetch (refuses internal addresses) — always executed on
175
+ the cook's machine, never the hub. Anything embedding the Python SDK
176
+ (`yeschef.sdk.AgentClient`) is a first-class cook too.
177
+
178
+ **Cloud cooks, too.** A cook is just an OpenAI- or Anthropic-compatible client, so a
179
+ hosted provider works exactly like a local one — `yeschef join` has presets:
180
+
181
+ ```bash
182
+ export OPENROUTER_API_KEY=sk-or-...
183
+ yeschef join --provider openrouter --model meta-llama/llama-3.3-70b-instruct --tier fast
184
+ ```
185
+
186
+ Presets: `openrouter`, `openai`, `groq`, `together`, `deepseek`, `fireworks`; any other
187
+ endpoint works with `--base-url` + `--api-key-env`. Mix cloud and local on one hub and
188
+ fire by tag — send bulk grunt work to a cheap cloud cook, keep the private work on your
189
+ own machines.
190
+
191
+ ## Honesty ledger
192
+
193
+ What this is, and isn't:
194
+
195
+ - **Local cooks are slower and weaker than Claude** — often 3–30× slower per token.
196
+ Firing work out wins on bounded, verifiable jobs (bulk transforms, drafts, triage,
197
+ second opinions), not on deep reasoning. That's why the design keeps the chef in charge.
198
+ - **Total cost isn't $0.** It's your electricity and your hardware. What it isn't is
199
+ metered, throttled, or revocable.
200
+ - **A cloud cook (OpenRouter etc.) is the opposite trade** — metered, and your data
201
+ leaves your network. It's supported and useful (cheap bulk work, models you can't run
202
+ locally), but it's not the "own your hardware" default. Choose per cook.
203
+ - **No TLS termination** — the hub is designed for LAN/Tailscale (which encrypts
204
+ transport). Never expose it through a public funnel or port-forward.
205
+ - **Talking-it-out is real model output, not magic.** Small models sometimes say dull
206
+ things. The `--record`/`replay` pipeline exists so demos are replays of real
207
+ conversations, not scripts.
208
+ - Windows support is tested in CI logic-paths but has had less real-world mileage than
209
+ macOS/Linux. Reports welcome.
210
+
211
+ ## Security posture
212
+
213
+ Auth is on by default (`up` generates tokens; `--open` exists for trusted LANs and says
214
+ so loudly). Cooks hold per-cook bearer tokens; a registered name can't be hijacked
215
+ without its token; reads are scoped to the caller once auth is on; cooks can't
216
+ self-register as privileged kinds; every autonomous room is bounded; cook tools are
217
+ opt-in, allowlisted, and jailed. Full details in [SPEC.md](SPEC.md).
218
+
219
+ ## Running the line
220
+
221
+ ```bash
222
+ yeschef cooks / tasks / task <id> / result <id> / rooms / watch <room> / cancel <id>
223
+ yeschef stats # lifetime: tickets cooked, tokens cooked locally, hours worked
224
+ yeschef ps / down # background processes on this machine
225
+ ```
226
+
227
+ A background sweep requeues tickets from lost cooks, times out overruns, archives idle
228
+ rooms, and un-sticks stalled conversations. Persistent-service units for launchd,
229
+ systemd, and Windows are in [`examples/deploy/`](examples/deploy/).
230
+
231
+ ## For the cooks (and Claude)
232
+
233
+ Claude Code sessions get tool docs automatically over MCP. To teach a session *when* to
234
+ fire work out (not just how), install the bundled skill: `yeschef install-skill` (or
235
+ `--user` for all projects). The full agent-facing guide is [docs/AGENTS.md](docs/AGENTS.md).
236
+
237
+ ## Standing on
238
+
239
+ yeschef is a client of the local-inference ecosystem, not a fork of it: it talks to
240
+ [Ollama](https://github.com/ollama/ollama) (and the
241
+ [llama.cpp](https://github.com/ggml-org/llama.cpp) engine underneath it),
242
+ [vLLM](https://github.com/vllm-project/vllm), LM Studio, and any OpenAI- or
243
+ Anthropic-compatible endpoint. The MCP server is built on
244
+ [FastMCP](https://github.com/jlowin/fastmcp). Those projects do the hard part.
245
+
246
+ ## Development
247
+
248
+ ```bash
249
+ uv venv && uv pip install -e ".[dev]"
250
+ uv run pytest # thread-level race regressions included
251
+ uv run ruff check src tests
252
+ ```
253
+
254
+ MIT. Formerly `farmteam` / `cascadia-tasks` — the old CLI names still work as aliases.